diff --git a/.circleci/config.yml b/.circleci/config.yml index 3d14b5489c..0133c5d6b9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,10 +1,13 @@ # NOTE: Current plan gives 1500 build minutes per month. version: 2 +# https://circleci.com/blog/circleci-hacks-reuse-yaml-in-your-circleci-config-with-yaml/ +defaults: &defaults + docker: + # Built by Thanos make docker-ci + - image: quay.io/thanos/thanos-ci:go1.14.2-node jobs: test: - docker: - # Build by Thanos make docker-ci - - image: quay.io/thanos/thanos-ci:v0.3.0 + <<: *defaults working_directory: /go/src/github.com/thanos-io/thanos environment: GO111MODULE: 'on' @@ -18,7 +21,7 @@ jobs: steps: - checkout - setup_remote_docker: - version: 17.07.0-ce + version: 17.07.0-ce - run: name: Create Secret if PR is not forked # GCS integration tests are run only for author's PR that have write access, because these tests @@ -31,6 +34,7 @@ jobs: - run: make deps - run: make lint - run: make check-docs + - run: make check-examples - run: make format - run: name: "Run unit tests." @@ -49,17 +53,15 @@ jobs: environment: GOBIN: "/home/circleci/.go_workspace/go/bin" steps: - - checkout - - run: make crossbuild - - persist_to_workspace: - root: . - paths: - - .build + - checkout + - run: make crossbuild + - persist_to_workspace: + root: . + paths: + - .build publish_master: - docker: - # Build by Thanos make docker-ci - - image: quay.io/thanos/thanos-ci:v0.2.0 + <<: *defaults working_directory: /go/src/github.com/thanos-io/thanos steps: - checkout @@ -77,9 +79,7 @@ jobs: - run: make docker-push publish_release: - docker: - # Build by Thanos make docker-ci - - image: quay.io/thanos/thanos-ci:v0.2.0 + <<: *defaults working_directory: /go/src/github.com/thanos-io/thanos environment: GOBIN: "/go/bin" @@ -106,30 +106,30 @@ workflows: version: 2 thanos: jobs: - - test: - filters: - tags: - only: /.*/ - - publish_master: - requires: - - test - filters: - branches: - only: master - - cross_build: - requires: - - test - filters: - tags: - only: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/ - branches: - ignore: /.*/ - - publish_release: - requires: - - test - - cross_build - filters: - tags: - only: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/ - branches: - ignore: /.*/ + - test: + filters: + tags: + only: /.*/ + - publish_master: + requires: + - test + filters: + branches: + only: master + - cross_build: + requires: + - test + filters: + tags: + only: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/ + branches: + ignore: /.*/ + - publish_release: + requires: + - test + - cross_build + filters: + tags: + only: /^v[0-9]+(\.[0-9]+){2}(-.+|[^-.]*)$/ + branches: + ignore: /.*/ diff --git a/.github/stale.yml b/.github/stale.yml index ab344e9349..6f22060c83 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -1,60 +1,52 @@ # Configuration for probot-stale - https://github.com/probot/stale -# Number of days of inactivity before an Issue or Pull Request becomes stale -daysUntilStale: 30 - -# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. -# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. -daysUntilClose: 7 - # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) onlyLabels: [] # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable. # We want stale bot to notify us that something is stale so we can revisit it. -exemptLabels: [] +# If one issue is marked as 'reminder' by the reminder bot, we don't mark it as 'stale' again. +exemptLabels: + # This label is hardcoded on remind bot (https://probot.github.io/apps/reminders/) and is used by remind bot when + # issue is being reminded. + - reminder # Set to true to ignore issues in a project (defaults to false) exemptProjects: false - # Set to true to ignore issues in a milestone (defaults to false) exemptMilestones: false - # Set to true to ignore issues with an assignee (defaults to false) exemptAssignees: false - # Label to use when marking as stale staleLabel: stale -# Comment to post when marking as stale. Set to `false` to disable -markComment: > - This issue/PR has been automatically marked as stale because it has not had - recent activity. Please comment on status otherwise the issue will be closed in a week. Thank you - for your contributions. +pull: + daysUntilClose: 7 + daysUntilStale: 30 + markComment: > + Hello 👋 Looks like there was no activity on this amazing PR for last 30 days. -# Comment to post when removing the stale label. -# unmarkComment: > -# Your comment here. + **Do you mind updating us on the status?** Is there anything we can help with? If you plan to still work on it, just comment on this PR or push a commit. Thanks! 🤗 -# Comment to post when closing a stale Issue or Pull Request. -# closeComment: > -# Your comment here. + If there will be no activity for next week, this issue will be closed (we can always reopen a PR if you get back to this!). + Alternatively, use [`remind` command](https://probot.github.io/apps/reminders/) if you wish to be reminded at some point in future. + #unmarkComment: No need for unmark comment. + closeComment: > + Closing for now as promised, let us know if you need this to be reopened! 🤗 -# Limit the number of actions per hour, from 1-30. Default is 30 -limitPerRun: 30 - -# Limit to only `issues` or `pulls` -# only: issues +issues: + daysUntilClose: 7 + daysUntilStale: 30 + markComment: > + Hello 👋 Looks like there was no activity on this issue for last 30 days. -# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': -# pulls: -# daysUntilStale: 30 -# markComment: > -# This pull request has been automatically marked as stale because it has not had -# recent activity. It will be closed if no further activity occurs. Thank you -# for your contributions. + **Do you mind updating us on the status?** Is this still reproducible or needed? If yes, just comment on this PR or push a commit. Thanks! 🤗 -# issues: -# exemptLabels: -# - confirmed + If there will be no activity for next week, this issue will be closed (we can always reopen an issue if we need!). + Alternatively, use [`remind` command](https://probot.github.io/apps/reminders/) if you wish to be reminded at some point in future. + #unmarkComment: No need for unmark comment. + closeComment: > + Closing for now as promised, let us know if you need this to be reopened! 🤗 +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 diff --git a/.github/workflows/cross-build.yaml b/.github/workflows/cross-build.yaml index 832ffa8fad..853f8ddd26 100644 --- a/.github/workflows/cross-build.yaml +++ b/.github/workflows/cross-build.yaml @@ -13,7 +13,7 @@ jobs: - name: Install Go. uses: actions/setup-go@v1 with: - go-version: 1.13.6 + go-version: 1.14.2 - name: Check out code into the Go module directory uses: actions/checkout@v1 diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 1cc20d0dc2..17934a5e9b 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -14,7 +14,7 @@ jobs: - name: Install Go. uses: actions/setup-go@v1 with: - go-version: 1.13.6 + go-version: 1.14.2 - name: Check out code into the Go module directory. uses: actions/checkout@v2 diff --git a/.github/workflows/react-test.yml b/.github/workflows/react-test.yml new file mode 100644 index 0000000000..fc3c4fa0b4 --- /dev/null +++ b/.github/workflows/react-test.yml @@ -0,0 +1,33 @@ +name: react-test + +on: + push: + branches: + - master + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + node: [ '10', '12' ] + name: React UI test on Node ${{ matrix.node }} + steps: + - uses: actions/checkout@v2 + - name: Setup node + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node }} + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + + - uses: actions/cache@v1 + id: yarn-cache + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('pkg/ui/react-app/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - run: make react-app-test diff --git a/.gitignore b/.gitignore index 15bdae29c7..4e1783a9b8 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ kube/.minikube # Ignore e2e working dirs. data/ +test/e2e/e2e_integration_test* # Ignore promu artifacts. /.build @@ -25,5 +26,11 @@ website/public/ website/docs-pre-processed/ !website/data +# React build assets +pkg/ui/static/react + tmp/bin examples/tmp/ + +# Ignore the MacOS Trash (DS-Store) +.DS_Store diff --git a/.golangci.yml b/.golangci.yml index e6fb2b4d39..3afa8e8707 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -32,6 +32,7 @@ linters: - deadcode - errcheck - goconst + - gofmt - goimports - gosimple - govet diff --git a/.promu.yml b/.promu.yml index 7139c31d39..be5e09cbd5 100644 --- a/.promu.yml +++ b/.promu.yml @@ -1,5 +1,5 @@ go: - version: 1.13.6 + version: 1.14.2 repository: path: github.com/thanos-io/thanos build: diff --git a/CHANGELOG.md b/CHANGELOG.md index 26ccc79e8b..b9ad0f628b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,26 +13,132 @@ We use *breaking* word for marking changes that are not backward compatible (rel ### Fixed -- [#2033](https://github.com/thanos-io/thanos/pull/2033) minio-go: Fixed Issue #1494 support Web Identity providers for IAM credentials for AWS EKS -- [#1985](https://github.com/thanos-io/thanos/pull/1985) store gateway: Fixed case where series entry is larger than 64KB in index. -- [#2051](https://github.com/thanos-io/thanos/pull/2051) ruler: Fixed issue where ruler does not expose shipper metrics. -- [#2101](https://github.com/thanos-io/thanos/pull/2101) ruler: Fixed bug where thanos_alert_sender_errors_total was not registered. +- [#2536](https://github.com/thanos-io/thanos/pull/2536) minio-go: Fixed AWS STS endpoint url to https for Web Identity providers on AWS EKS +- [#2501](https://github.com/thanos-io/thanos/pull/2501) Query: Gracefully handle additional fields in `SeriesResponse` protobuf message that may be added in the future. +- [#2568](https://github.com/thanos-io/thanos/pull/2568) Query: Does not close the connection of strict, static nodes if establishing a connection had succeeded but Info() call failed +- [#2615](https://github.com/thanos-io/thanos/pull/2615) Rule: Fix bugs where rules were out of sync. +- [#2548](https://github.com/thanos-io/thanos/pull/2548) Query: Fixed rare cases of double counter reset accounting when querying `rate` with deduplication enabled. ### Added -- [#1969](https://github.com/thanos-io/thanos/pull/1969) Sidecar: allow setting http connection pool size via flags -- [#1967](https://github.com/thanos-io/thanos/issues/1967) Receive: Allow local TSDB compaction -- [#1970](https://github.com/thanos-io/thanos/issues/1970) *breaking* Receive: Use gRPC for forwarding requests between peers. Note that existing values for the `--receive.local-endpoint` flag and the endpoints in the hashring configuration file must now specify the receive gRPC port and must be updated to be a simple `host:port` combination, e.g. `127.0.0.1:10901`, rather than a full HTTP URL, e.g. `http://127.0.0.1:10902/api/v1/receive`. +- [#2502](https://github.com/thanos-io/thanos/pull/2502) Added `hints` field to `SeriesResponse`. Hints in an opaque data structure that can be used to carry additional information from the store and its content is implementation specific. +- [#2521](https://github.com/thanos-io/thanos/pull/2521) Sidecar: add `thanos_sidecar_reloader_reloads_failed_total`, `thanos_sidecar_reloader_reloads_total`, `thanos_sidecar_reloader_watch_errors_total`, `thanos_sidecar_reloader_watch_events_total` and `thanos_sidecar_reloader_watches` metrics. +- [#2412](https://github.com/thanos-io/thanos/pull/2412) ui: add React UI from Prometheus upstream. Currently only accessible from Query component as only `/graph` endpoint is migrated. +- [#2532](https://github.com/thanos-io/thanos/pull/2532) Store: Added hidden option `--store.caching-bucket.config=` (or `--store.caching-bucket.config-file=`) for experimental caching bucket, that can cache chunks into shared memcached. This can speed up querying and reduce number of requests to object storage. +- [#2579](https://github.com/thanos-io/thanos/pull/2579) Store: Experimental caching bucket can now cache metadata as well. Config has changed from #2532. + +### Changed + +- [#2194](https://github.com/thanos-io/thanos/pull/2194) Updated to golang v1.14.2 +- [#2505](https://github.com/thanos.io/thanos/pull/2505) Store: remove obsolete `thanos_store_node_info` metric. +- [2513](https://github.com/thanos-io/thanos/pull/2513) Tools: Moved `thanos bucket` commands to `thanos tools bucket`, also +moved `thanos check rules` to `thanos tools rules-check`. `thanos tools rules-check` also takes rules by `--rules` repeated flag not argument +anymore. +- [#2548](https://github.com/thanos-io/thanos/pull/2548/commits/53e69bd89b2b08c18df298eed7d90cb7179cc0ec) Store, Querier: remove duplicated chunks on StoreAPI. + +## [v0.12.2](https://github.com/thanos-io/thanos/releases/tag/v0.12.2) - 2020.04.30 + +### Fixed + +- [#2459](https://github.com/thanos-io/thanos/issues/2459) Compact: Fixed issue with old blocks being marked and deleted in a (slow) loop. +- [#2533](https://github.com/thanos-io/thanos/pull/2515) Rule: do not wrap reload endpoint with `/`. Makes `/-/reload` accessible again when no prefix has been specified. + +## [v0.12.1](https://github.com/thanos-io/thanos/releases/tag/v0.12.1) - 2020.04.20 + +### Fixed + +- [#2411](https://github.com/thanos-io/thanos/pull/2411) Query: fix a bug where queries might not time out sometimes due to issues with one or more StoreAPIs. +- [#2474](https://github.com/thanos-io/thanos/pull/2474) Store: fix a panic caused by concurrent memory access during block filtering. +- [#2472](https://github.com/thanos-io/thanos/pull/2472) Compact: fix a bug where partial blocks were never deleted, causing spam of warnings. +- [#2484](https://github.com/thanos-io/thanos/pull/2484) Query/Ruler: fix issue #2483, when web.route-prefix is set, it is added twice in HTTP router prefix. +- [#2416](https://github.com/thanos-io/thanos/pull/2416) Bucket: fixes issue #2416 bug in `inspect --sort-by` doesn't work correctly in all cases +- [#2411](https://github.com/thanos-io/thanos/pull/2411) Query: fix a bug where queries might not time out sometimes due to issues with one or more StoreAPIs + +### Added + +### Changed +- [#2450](https://github.com/thanos-io/thanos/pull/2450) Store: regex-set optimization for `label=~"a|b|c"` matchers. +- [#2475](https://github.com/thanos-io/thanos/pull/2475) Store: remove incorrect optimizations for queries with `=~".*"` and `!=~".*"` matchers. + +## [v0.12.0](https://github.com/thanos-io/thanos/releases/tag/v0.12.0) - 2020.04.15 + +### Fixed + +- [#2288](https://github.com/thanos-io/thanos/pull/2288) Ruler: fixes issue #2281, a bug causing incorrect parsing of query address with path prefix. +- [#2238](https://github.com/thanos-io/thanos/pull/2238) Ruler: fixed issue #2204, where a bug in alert queue signaling filled up the queue and alerts were dropped. +- [#2231](https://github.com/thanos-io/thanos/pull/2231) Bucket Web: sort chunks by thanos.downsample.resolution for better grouping. +- [#2254](https://github.com/thanos-io/thanos/pull/2254) Bucket: fix issue where metrics were registered multiple times in bucket replicate. +- [#2271](https://github.com/thanos-io/thanos/pull/2271) Bucket Web: fixed issue #2260, where the bucket passes null when storage is empty. +- [#2339](https://github.com/thanos-io/thanos/pull/2339) Query: fix a bug where `--store.unhealthy-timeout` was never respected. +- [#2208](https://github.com/thanos-io/thanos/pull/2208) Query and Rule: fix handling of `web.route-prefix` to correctly handle `/` and prefixes that do not begin with a `/`. +- [#2311](https://github.com/thanos-io/thanos/pull/2311) Receive: ensure receive component serves TLS when TLS configuration is provided. +- [#2319](https://github.com/thanos-io/thanos/pull/2319) Query: fixed inconsistent naming of metrics. +- [#2390](https://github.com/thanos-io/thanos/pull/2390) Store: fixed bug that was causing all posting offsets to be used instead of only 1/32 as intended; added hidden flag to control this behavior. +- [#2393](https://github.com/thanos-io/thanos/pull/2393) Store: fixed bug causing certain not-existing label values queried to fail with "invalid-size" error from binary header. +- [#2382](https://github.com/thanos-io/thanos/pull/2382) Store: fixed bug causing partial writes of index-header. +- [#2383](https://github.com/thanos-io/thanos/pull/2383) Store: handle expected errors correctly, e.g. do not increment failure counters. + + +### Added + +- [#2252](https://github.com/thanos-io/thanos/pull/2252) Query: add new `--store-strict` flag. More information available [here](/docs/proposals/202001_thanos_query_health_handling.md). +- [#2265](https://github.com/thanos-io/thanos/pull/2265) Compact: add `--wait-interval` to specify compaction wait interval between consecutive compact runs when `--wait` is enabled. +- [#2250](https://github.com/thanos-io/thanos/pull/2250) Compact: enable vertical compaction for offline deduplication (experimental). Uses `--deduplication.replica-label` flag to specify the replica label on which to deduplicate (hidden). Please note that this uses a NAIVE algorithm for merging (no smart replica deduplication, just chaining samples together). This works well for deduplication of blocks with **precisely the same samples** like those produced by Receiver replication. We plan to add a smarter algorithm in the following weeks. +- [#1714](https://github.com/thanos-io/thanos/pull/1714) Compact: the compact component now exposes the bucket web UI when it is run as a long-lived process. +- [#2304](https://github.com/thanos-io/thanos/pull/2304) Store: added `max_item_size` configuration option to memcached-based index cache. This should be set to the max item size configured in memcached (`-I` flag) in order to not waste network round-trips to cache items larger than the limit configured in memcached. +- [#2297](https://github.com/thanos-io/thanos/pull/2297) Store: add `--experimental.enable-index-cache-postings-compression` flag to enable re-encoding and compressing postings before storing them into the cache. Compressed postings take about 10% of the original size. +- [#2357](https://github.com/thanos-io/thanos/pull/2357) Compact and Store: the compact and store components now serve the bucket UI on `:/loaded`, which shows exactly the blocks that are currently seen by compactor and the store gateway. The compactor also serves a different bucket UI on `:/global`, which shows the status of object storage without any filters. +- [#2166](https://github.com/thanos-io/thanos/pull/2166) Bucket Web: improve the tooltip for the bucket UI; it was reconstructed and now exposes much more information about blocks. +- [#2172](https://github.com/thanos-io/thanos/pull/2172) Store: add support for sharding the store component based on the label hash. +- [#2113](https://github.com/thanos-io/thanos/pull/2113) Bucket: added `thanos bucket replicate` command to replicate blocks from one bucket to another. +- [#1922](https://github.com/thanos-io/thanos/pull/1922) Docs: create a new document to explain sharding in Thanos. +- [#2230](https://github.com/thanos-io/thanos/pull/2230) Store: optimize conversion of labels. + +### Changed + +- [#2136](https://github.com/thanos-io/thanos/pull/2136) *breaking* Store, Compact, Bucket: schedule block deletion by adding deletion-mark.json. This adds a consistent way for multiple readers and writers to access object storage. +Since there are no consistency guarantees provided by some Object Storage providers, this PR adds a consistent lock-free way of dealing with Object Storage irrespective of the choice of object storage. In order to achieve this co-ordination, blocks are not deleted directly. Instead, blocks are marked for deletion by uploading the `deletion-mark.json` file for the block that was chosen to be deleted. This file contains Unix time of when the block was marked for deletion. If you want to keep existing behavior, you should add `--delete-delay=0s` as a flag. +- [#2090](https://github.com/thanos-io/thanos/issues/2090) *breaking* Downsample command: the `downsample` command has moved and is now a sub-command of the `thanos bucket` sub-command; it cannot be called via `thanos downsample` any more. +- [#2294](https://github.com/thanos-io/thanos/pull/2294) Store: optimizations for fetching postings. Queries using `=~".*"` matchers or negation matchers (`!=...` or `!~...`) benefit the most. +- [#2301](https://github.com/thanos-io/thanos/pull/2301) Ruler: exit with an error when initialization fails. +- [#2310](https://github.com/thanos-io/thanos/pull/2310) Query: report timespan 0 to 0 when discovering no stores. +- [#2330](https://github.com/thanos-io/thanos/pull/2330) Store: index-header is no longer experimental. It is enabled by default for store Gateway. You can disable it with new hidden flag: `--store.disable-index-header`. The `--experimental.enable-index-header` flag was removed. +- [#1848](https://github.com/thanos-io/thanos/pull/1848) Ruler: allow returning error messages when a reload is triggered via HTTP. +- [#2270](https://github.com/thanos-io/thanos/pull/2277) All: Thanos components will now print stack traces when they error out. + +## [v0.11.0](https://github.com/thanos-io/thanos/releases/tag/v0.11.0) - 2020.03.02 + +### Fixed + +- [#2033](https://github.com/thanos-io/thanos/pull/2033) Minio-go: Fixed Issue #1494 support Web Identity providers for IAM credentials for AWS EKS. +- [#1985](https://github.com/thanos-io/thanos/pull/1985) Store Gateway: Fixed case where series entry is larger than 64KB in index. +- [#2051](https://github.com/thanos-io/thanos/pull/2051) Ruler: Fixed issue where ruler does not expose shipper metrics. +- [#2101](https://github.com/thanos-io/thanos/pull/2101) Ruler: Fixed bug where thanos_alert_sender_errors_total was not registered. +- [#1789](https://github.com/thanos-io/thanos/pull/1789) Store Gateway: Improve timeouts. +- [#2139](https://github.com/thanos-io/thanos/pull/2139) Properly handle SIGHUP for reloading. +- [#2040](https://github.com/thanos-io/thanos/pull/2040) UI: Fix URL of alerts in Ruler +- [#2033](https://github.com/thanos-io/thanos/pull/1978) Ruler: Fix tracing in Thanos Ruler + +### Added + +- [#2003](https://github.com/thanos-io/thanos/pull/2003) Query: Support downsampling for /series. +- [#1952](https://github.com/thanos-io/thanos/pull/1952) Store Gateway: Implemented [binary index header](https://thanos.io/proposals/201912_thanos_binary_index_header.md/). This significantly reduces resource consumption (memory, CPU, net bandwidth) for startup and data loading processes as well as baseline memory. This means that adding more blocks into object storage, without querying them will use almost no resources. This, however, **still means that querying large amounts of data** will result in high spikes of memory and CPU use as before, due to simply fetching large amounts of metrics data. Since we fixed baseline, we are now focusing on query performance optimizations in separate initiatives. To enable experimental `index-header` mode run store with hidden `experimental.enable-index-header` flag. +- [#2009](https://github.com/thanos-io/thanos/pull/2009) Store Gateway: Minimum age of all blocks before they are being read. Set it to a safe value (e.g 30m) if your object storage is eventually consistent. GCS and S3 are (roughly) strongly consistent. +- [#1963](https://github.com/thanos-io/thanos/pull/1963) Mixin: Add Thanos Ruler alerts. +- [#1984](https://github.com/thanos-io/thanos/pull/1984) Query: Add cache-control header to not cache on error. +- [#1870](https://github.com/thanos-io/thanos/pull/1870) UI: Persist settings in query. +- [#1969](https://github.com/thanos-io/thanos/pull/1969) Sidecar: allow setting http connection pool size via flags. +- [#1967](https://github.com/thanos-io/thanos/issues/1967) Receive: Allow local TSDB compaction. - [#1939](https://github.com/thanos-io/thanos/pull/1939) Ruler: Add TLS and authentication support for query endpoints with the `--query.config` and `--query.config-file` CLI flags. See [documentation](docs/components/rule.md/#configuration) for further information. - [#1982](https://github.com/thanos-io/thanos/pull/1982) Ruler: Add support for Alertmanager v2 API endpoints. - [#2030](https://github.com/thanos-io/thanos/pull/2030) Query: Add `thanos_proxy_store_empty_stream_responses_total` metric for number of empty responses from stores. - [#2049](https://github.com/thanos-io/thanos/pull/2049) Tracing: Support sampling on Elastic APM with new sample_rate setting. - [#2008](https://github.com/thanos-io/thanos/pull/2008) Querier, Receiver, Sidecar, Store: Add gRPC [health check](https://github.com/grpc/grpc/blob/master/doc/health-checking.md) endpoints. - [#2145](https://github.com/thanos-io/thanos/pull/2145) Tracing: track query sent to prometheus via remote read api. -- [#2113](https://github.com/thanos-io/thanos/pull/2113) Bucket: Added `thanos bucket replicate`. ### Changed +- [#1970](https://github.com/thanos-io/thanos/issues/1970) *breaking* Receive: Use gRPC for forwarding requests between peers. Note that existing values for the `--receive.local-endpoint` flag and the endpoints in the hashring configuration file must now specify the receive gRPC port and must be updated to be a simple `host:port` combination, e.g. `127.0.0.1:10901`, rather than a full HTTP URL, e.g. `http://127.0.0.1:10902/api/v1/receive`. - [#1933](https://github.com/thanos-io/thanos/pull/1933) Add a flag `--tsdb.wal-compression` to configure whether to enable tsdb wal compression in ruler and receiver. - [#2021](https://github.com/thanos-io/thanos/pull/2021) Rename metric `thanos_query_duplicated_store_address` to `thanos_query_duplicated_store_addresses_total` and `thanos_rule_duplicated_query_address` to `thanos_rule_duplicated_query_addresses_total`. - [#2166](https://github.com/thanos-io/thanos/pull/2166) Improve tooltip for bucket web UI. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a595ef4513..fa2b1c04db 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,23 @@ This document explain the process of contributing to the Thanos project. First of all please follow the [code of conduct](CODE_OF_CONDUCT.md) in all your interactions with the project. +## TOC + +- [Contributing](#contributing) + * [TOC](#toc) + * [Thanos Philosophy](#thanos-philosophy) + * [Feedback / Issues](#feedback---issues) + * [Adding New Features / Components](#adding-new-features---components) + * [Components Naming](#components-naming) + * [Development](#development) + + [Prerequisites](#prerequisites) + + [First steps](#first-steps) + + [Pull Request Process](#pull-request-process) + + [Dependency management](#dependency-management) + + [Advanced testing](#advanced-testing) + +Table of contents generated with markdown-toc + ## Thanos Philosophy The philosophy of Thanos and our community is borrowing much from UNIX philosophy and the golang programming language. @@ -36,10 +53,6 @@ method with the owners of this repository before making a change. Adding a large new feature or/and component to Thanos should be done by first creating a [proposal](docs/proposals) document outlining the design decisions of the change, motivations for the change, and any alternatives that might have been considered. -## Prerequisites - -* It is strongly recommended that you use OSX or popular Linux distributions systems e.g. Ubuntu, Redhat, or OpenSUSE for development. - ## Components Naming Thanos is a distributed system composed with several services and CLI tools as listed [here](cmd/thanos). @@ -61,12 +74,29 @@ However, when speaking about those or explaining we use `actor` noun form: `stor * Documentation * Code comments -## Pull Request Process +## Development + +The following section explains various suggestions and procedures to note during development of Thanos. + +### Prerequisites + +* It is strongly recommended that you use Linux distributions systems or OSX for development. +* Go 1.13.9 or newer installed. +* For React UI, you will need a working NodeJS environment and the Yarn package manager to compile the Web UI assets + +### First Steps -1. Read [getting started docs](docs/getting-started.md) and prepare Thanos. -2. Familiarize yourself with Go standard style guides Thanos follows: [this](https://golang.org/doc/effective_go.html) and [this](https://github.com/golang/go/wiki/CodeReviewComments). -3. Familiarize yourself with [Makefile](Makefile) commands like `format`, `build`, `proto` and `test`. -4. Fork thanos-io/thanos.git and start development from your own fork. Here are sample steps to setup your development environment: +It's key to get familiarized with style guide and mechanics of Thanos, especially if your contribution touches more than one +component of the Thanos distributed system. We recommend: + +* Reading the [getting started docs](docs/getting-started.md) and working through them, or alternatively working through the [Thanos tutorial](https://katacoda.com/thanos). +* Familiarizing yourself with our [coding style guidelines.](docs/contributing/coding-style-guide.md). +* Familiarizing yourself with the [Makefile](Makefile) commands, for example `format`, `build`, `proto`, `docker` and `test`. +`make help` will print most of available commands with details. + +### Pull Request Process + +1. Fork thanos-io/thanos.git and start development from your own fork. Here are sample steps to setup your development environment: ```console $ mkdir -p $GOPATH/src/github.com/thanos-io @@ -80,7 +110,21 @@ $ make build $ ./thanos -h ``` -5. Keep PRs as small as possible. For each of your PR, you create one branch based on the latest master. Chain them if needed (base PR on other PRs). Here are sample steps you can follow. You can get more details about the workflow from [here](https://gist.github.com/Chaser324/ce0505fbed06b947d962). +1. Signing your work: DCO (Developer Certificate of Origin) Process. + +By contributing to this project you agree to the [Developer Certificate of Origin](https://developercertificate.org/)(DCO). This document was created by the Linux Kernel community and is a simple statement that you, as a contributor, have the legal right to make the contribution. + +To signoff, you need to add `Signed-off-by: Your Name ` at the end of your commit messages. You can do this using [`git commit -s`](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt--s). For example: +``` +$ git commit -s -m 'This is my commit message' +``` + +You can also alias ``commit`` as `commit -s` in your `~/.gitconfig` to signoff all your future commits. + +If you have authored an unsigned commit, you can update it using ``git commit --amend --signoff``. If you've pushed your changes to GitHub already you'll need to force push your branch after this with ``git push -f``. + +1. Keep PRs as small as possible. For each of your PRs, you create a new branch based on the latest master. +Chain them if needed (base one PR on other PRs). You can read more details about the workflow from [here](https://gist.github.com/Chaser324/ce0505fbed06b947d962). ```console $ git checkout master @@ -92,19 +136,21 @@ $ $ git push origin ``` -6. Add unit tests for new functionalities. Add e2e tests if functionality is major. -7. If you don't have a live object store ready add this envvar to skip tests for these: -- THANOS_TEST_OBJSTORE_SKIP=GCS,S3,AZURE,SWIFT,COS,ALIYUNOSS +1. Add unit tests for new functionality. Add e2e tests for major changes to functionality. +1. If you don't have a live object store ready, you can use the `make test-local` command. -If you skip all of these, the store specific tests will be run against memory object storage only. -CI runs GCS and inmem tests only for now. Not having these variables will produce auth errors against GCS, AWS, Azure or COS tests. +NOTE: this command skips tests against live object storage systems by specifying environment variables; this causes the +store-specific tests to be run against memory and filesystem object storages only. The CI tests run `make test-ci` instead +(uses GCS, AWS). -8. If your change affects users (adds or removes feature) consider adding the item to [CHANGELOG](CHANGELOG.md) -9. You may merge the Pull Request in once you have the sign-off of at least one developers with write access, or if you +Not specifying these variables will result in auth errors against GCS, AWS, Azure, COS etc. + +1. If your change affects users (adds or removes feature) consider adding the item to the [CHANGELOG](CHANGELOG.md). +1. You may merge the Pull Request once you have the sign-off of at least one developer with write access, or if you do not have permission to do that, you may request the second reviewer to merge it for you. -10. If you feel like your PR waits too long for a review, feel free to ping [`#thanos-prs`](https://slack.cncf.io/) channel on our slack for review! +1. If you feel like your PR is waiting too long for a review, feel free to ping the [`#thanos-prs`](https://slack.cncf.io/) channel on our slack for a review! -## Dependency management +### Dependency management The Thanos project uses [Go modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) to manage dependencies on external packages. This requires a working Go environment with version 1.11 or greater and git installed. @@ -127,3 +173,26 @@ git commit ``` You have to commit the changes to `go.mod` and `go.sum` before submitting the pull request. + +### Advanced testing + +At some point during development it is useful, in addition to running unit or e2e tests, to run and play with Thanos components manually. While you +can run any component manually by crafting specific flags for a test setup, there are already some nice tools and scripts available. +Consider the following methods: + +* [quickstart.sh](https://github.com/thanos-io/thanos/blob/b08c0ea62abfe4dcf1400da0e37598f0cd8fa8cf/scripts/quickstart.sh): this script spins +up a simple example setup. Do `make build` before running the script to build the `thanos` binary first. +* `make test-e2e`: the e2e tests cover most of the setups and functionality Thanos offers. It's extremely easy to add `time.Sleep(10* time.Minutes)` +at certain points in the tests (e.g for compactor [here](https://github.com/thanos-io/thanos/blob/8f492a9f073f819019dd9f044e346a1e1fa730bc/test/e2e/compact_test.go#L379)). +This way when you run `make test-e2e`, the test will sleep for some time, allowing you to connect to the setup manually using the port printed in the logs. For example: + +```bash +querier-1: level=info name=querier-1 ts=2020-04-01T12:53:56.101029491Z caller=http.go:56 service=http/server component=query msg="listening for requests and metrics" address=:80 +querier-1: level=info name=querier-1 ts=2020-04-01T12:53:56.101106805Z caller=intrumentation.go:48 msg="changing probe status" status=ready +querier-1: level=info name=querier-1 ts=2020-04-01T12:53:56.101290229Z caller=grpc.go:106 service=gRPC/server component=query msg="listening for StoreAPI gRPC" address=:9091 +Ports for container: e2e_test_store_gateway-querier-1 Mapping: map[80:32825 9091:32824] +``` + +This output indicates that the HTTP (`80`) endpoint will be available on `http://localhost:32825`. You can quickly craft your own test case with our framework as well! + +NOTE: `make docker` has to work in order for `make test-e2e` to run. This currently might not work properly on macOS. diff --git a/Dockerfile b/Dockerfile index bf71a154f3..51cf401fb0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM quay.io/prometheus/busybox:latest LABEL maintainer="The Thanos Authors" -COPY thanos /bin/thanos +COPY /thanos_tmp_for_docker /bin/thanos ENTRYPOINT [ "/bin/thanos" ] diff --git a/Dockerfile.multi-stage b/Dockerfile.multi-stage index dbcc5aa3f0..031a2deea5 100644 --- a/Dockerfile.multi-stage +++ b/Dockerfile.multi-stage @@ -1,9 +1,14 @@ -FROM golang:1.13.6-alpine3.11 as builder +FROM golang:1.14.2-alpine3.11 as builder -ADD . $GOPATH/src/github.com/thanos-io/thanos WORKDIR $GOPATH/src/github.com/thanos-io/thanos - +# Change in the docker context invalidates the cache so to leverage docker +# layer caching, moving update and installing apk packages above COPY cmd +# More info https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache RUN apk update && apk upgrade && apk add --no-cache alpine-sdk +# Replaced ADD with COPY as add is generally to download content form link or tar files +# while COPY supports the basic copying of local files into the container. +# https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#add-or-copy +COPY . $GOPATH/src/github.com/thanos-io/thanos RUN git update-index --refresh; make build diff --git a/Dockerfile.thanos-ci b/Dockerfile.thanos-ci index 4c12365193..4a96a3538d 100644 --- a/Dockerfile.thanos-ci +++ b/Dockerfile.thanos-ci @@ -1,5 +1,5 @@ # Available from https://hub.docker.com/r/circleci/golang/ -FROM circleci/golang:1.13.6 +FROM circleci/golang:1.14.2-node ENV GOBIN=/go/bin diff --git a/MAINTAINERS.md b/MAINTAINERS.md index c36e87defa..346b668580 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -5,12 +5,13 @@ | Bartłomiej Płotka | bwplotka@gmail.com | `@bwplotka` | [@bwplotka](https://github.com/bwplotka) | Red Hat | | Frederic Branczyk | fbranczyk@gmail.com | `@brancz` | [@brancz](https://github.com/brancz) | Red Hat | | Giedrius Statkevičius | giedriuswork@gmail.com | `@Giedrius Statkevičius` | [@GiedriusS](https://github.com/GiedriusS) | AdForm | +| Lucas Servén Marín | lserven@gmail.com | `@squat` | [@squat](https://github.com/squat) | Red Hat | | Povilas Versockas | p.versockas@gmail.com | `@povilasv` | [@povilasv](https://github.com/povilasv) | Utility Warehouse | +| Marco Pracucci | marco@pracucci.com | `@pracucci` | [@pracucci](https://github.com/pracucci) | Grafana Labs | | Matthias Loibl | mail@matthiasloibl.com | `@metalmatze` | [@metalmatze](https://github.com/metalmatze)| Red Hat | -| Lucas Servén Marín | lserven@gmail.com | `@squat` | [@squat](https://github.com/squat) | Red Hat | We are bunch of people from different companies with various interests and skills. -We are from different parts of Europe: Germany, Lithuania, Poland and UK. +We are from different parts of Europe: Germany, Italy, Lithuania, Poland and UK. We have something in common though: We all share the love for OpenSource, Go, Prometheus, :coffee: and Observability topics. As either Software Developers or SRE (or both!) we've chosen to maintain (mostly in our free time) Thanos, the de facto way to scale awesome [Prometheus](https://prometheus.io) project. @@ -32,6 +33,8 @@ Full list of triage persons is displayed below: | Ben Ye | `@yeya24` | [@yeya24](https://github.com/yeya24) | | Martin Chodur | `@FUSAKLA` | [@fusakla](https://github.com/fusakla) | | Michael Dai | `@jojohappy` | [@jojohappy](https://github.com/jojohappy) | +| Kemal Akkoyun | `@kakkoyun` | [@kakkoyun](https://github.com/kakkoyun) | +| Xiang Dai | `@daixiang0` | [@daixiang0](https://github.com/daixiang0) | Please reach any of the maintainer on slack or email if you want to help as well. diff --git a/Makefile b/Makefile index 95382bb177..a9deed3041 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ -PREFIX ?= $(shell pwd) FILES_TO_FMT ?= $(shell find . -path ./vendor -prune -o -name '*.go' -print) DOCKER_IMAGE_REPO ?= quay.io/thanos/thanos @@ -16,6 +15,8 @@ export GO111MODULE GOPROXY ?= https://proxy.golang.org export GOPROXY +GOTEST_OPTS ?= -failfast -timeout 10m -v + # Tools. EMBEDMD ?= $(GOBIN)/embedmd-$(EMBEDMD_VERSION) # v2.0.0 @@ -44,8 +45,9 @@ MISSPELL ?= $(GOBIN)/misspell-$(MISSPELL_VERSION) GOJSONTOYAML_VERSION ?= e8bd32d46b3d764bef60f12b3bada1c132c4be55 GOJSONTOYAML ?= $(GOBIN)/gojsontoyaml-$(GOJSONTOYAML_VERSION) # v0.14.0 -JSONNET_VERSION ?= fbde25be2182caa4345b03f1532450911ac7d1f3 +JSONNET_VERSION ?= 724650d358b67909a7bea00ea443e23afc3d2a17 JSONNET ?= $(GOBIN)/jsonnet-$(JSONNET_VERSION) +JSONNETFMT ?= $(GOBIN)/jsonnetfmt-$(JSONNET_VERSION) JSONNET_BUNDLER_VERSION ?= efe0c9e864431e93d5c3376bd5931d0fb9b2a296 JSONNET_BUNDLER ?= $(GOBIN)/jb-$(JSONNET_BUNDLER_VERSION) # Prometheus v2.14.0 @@ -56,8 +58,7 @@ PROMTOOL ?= $(GOBIN)/promtool-$(PROMTOOL_VERSION) # systems gsed won't be installed, so will use sed as expected. SED ?= $(shell which gsed 2>/dev/null || which sed) -MIXIN_ROOT ?= mixin -THANOS_MIXIN ?= mixin/thanos +THANOS_MIXIN ?= mixin JSONNET_VENDOR_DIR ?= mixin/vendor WEB_DIR ?= website @@ -78,9 +79,13 @@ ALERTMANAGER ?= $(GOBIN)/alertmanager-$(ALERTMANAGER_VERSION) MINIO_SERVER_VERSION ?= RELEASE.2018-10-06T00-15-16Z MINIO_SERVER ?=$(GOBIN)/minio-$(MINIO_SERVER_VERSION) -FAILLINT_VERSION ?= v1.0.1 +FAILLINT_VERSION ?= v1.2.0 FAILLINT ?=$(GOBIN)/faillint-$(FAILLINT_VERSION) -MODULES_TO_AVOID ?=errors,github.com/prometheus/tsdb,github.com/prometheus/prometheus/pkg/testutils + +REACT_APP_PATH = pkg/ui/react-app +REACT_APP_SOURCE_FILES = $(wildcard $(REACT_APP_PATH)/public/* $(REACT_APP_PATH)/src/* $(REACT_APP_PATH)/tsconfig.json) +REACT_APP_OUTPUT_DIR = pkg/ui/static/react +REACT_APP_NODE_MODULES_PATH = $(REACT_APP_PATH)/node_modules # fetch_go_bin_version downloads (go gets) the binary from specific version and installs it in $(GOBIN)/- # arguments: @@ -93,9 +98,9 @@ define fetch_go_bin_version @echo ">> fetching $(1)@$(2) revision/version" @if [ ! -d '$(TMP_GOPATH)/src/$(1)' ]; then \ - GOPATH='$(TMP_GOPATH)' GO111MODULE='off' go get -d -u '$(1)/...'; \ + GOPATH='$(TMP_GOPATH)' GO111MODULE='off' go get -d -u '$(1)/...'; \ else \ - CDPATH='' cd -- '$(TMP_GOPATH)/src/$(1)' && git fetch; \ + CDPATH='' cd -- '$(TMP_GOPATH)/src/$(1)' && git fetch; \ fi @CDPATH='' cd -- '$(TMP_GOPATH)/src/$(1)' && git checkout -f -q '$(2)' @echo ">> installing $(1)@$(2)" @@ -108,43 +113,69 @@ endef define require_clean_work_tree @git update-index -q --ignore-submodules --refresh - @if ! git diff-files --quiet --ignore-submodules --; then \ - echo >&2 "cannot $1: you have unstaged changes."; \ - git diff-files --name-status -r --ignore-submodules -- >&2; \ - echo >&2 "Please commit or stash them."; \ - exit 1; \ - fi + @if ! git diff-files --quiet --ignore-submodules --; then \ + echo >&2 "cannot $1: you have unstaged changes."; \ + git diff-files --name-status -r --ignore-submodules -- >&2; \ + echo >&2 "Please commit or stash them."; \ + exit 1; \ + fi - @if ! git diff-index --cached --quiet HEAD --ignore-submodules --; then \ - echo >&2 "cannot $1: your index contains uncommitted changes."; \ - git diff-index --cached --name-status -r --ignore-submodules HEAD -- >&2; \ - echo >&2 "Please commit or stash them."; \ - exit 1; \ - fi + @if ! git diff-index --cached --quiet HEAD --ignore-submodules --; then \ + echo >&2 "cannot $1: your index contains uncommitted changes."; \ + git diff-index --cached --name-status -r --ignore-submodules HEAD -- >&2; \ + echo >&2 "Please commit or stash them."; \ + exit 1; \ + fi endef help: ## Displays help. - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST) + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n\nTargets:\n"} /^[a-z0-9A-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST) .PHONY: all all: format build +$(REACT_APP_NODE_MODULES_PATH): $(REACT_APP_PATH)/package.json $(REACT_APP_PATH)/yarn.lock + cd $(REACT_APP_PATH) && yarn --frozen-lockfile + +$(REACT_APP_OUTPUT_DIR): $(REACT_APP_NODE_MODULES_PATH) $(REACT_APP_SOURCE_FILES) + @echo ">> building React app" + @./scripts/build-react-app.sh + .PHONY: assets assets: # Repacks all static assets into go file for easier deploy. -assets: $(GOBINDATA) +assets: $(GOBINDATA) $(REACT_APP_OUTPUT_DIR) @echo ">> deleting asset file" @rm pkg/ui/bindata.go || true @echo ">> writing assets" @$(GOBINDATA) $(bindata_flags) -pkg ui -o pkg/ui/bindata.go -ignore '(.*\.map|bootstrap\.js|bootstrap-theme\.css|bootstrap\.css)' pkg/ui/templates/... pkg/ui/static/... @go fmt ./pkg/ui +.PHONY: react-app-lint +react-app-lint: $(REACT_APP_NODE_MODULES_PATH) + @echo ">> running React app linting" + cd $(REACT_APP_PATH) && yarn lint:ci + +.PHONY: react-app-lint-fix +react-app-lint-fix: + @echo ">> running React app linting and fixing errors where possible" + cd $(REACT_APP_PATH) && yarn lint + +.PHONY: react-app-test +react-app-test: | $(REACT_APP_NODE_MODULES_PATH) react-app-lint + @echo ">> running React app tests" + cd $(REACT_APP_PATH) && export CI=true && yarn test --no-watch + +.PHONY: react-app-start +react-app-start: $(REACT_APP_NODE_MODULES_PATH) + @echo ">> running React app" + cd $(REACT_APP_PATH) && yarn start .PHONY: build build: ## Builds Thanos binary using `promu`. build: check-git deps $(PROMU) - @echo ">> building binaries $(GOBIN)" - @$(PROMU) build --prefix $(PREFIX) + @echo ">> building Thanos binary in $(GOBIN)" + @$(PROMU) build --prefix $(GOBIN) .PHONY: crossbuild crossbuild: ## Builds all binaries for all platforms. @@ -160,8 +191,11 @@ deps: ## Ensures fresh go.mod and go.sum. .PHONY: docker docker: ## Builds 'thanos' docker with no tag. docker: build + @echo ">> copying Thanos from $(GOBIN) to ./thanos_tmp_for_docker" + @cp $(GOBIN)/thanos ./thanos_tmp_for_docker @echo ">> building docker image 'thanos'" @docker build -t "thanos" . + @rm ./thanos_tmp_for_docker .PHONY: docker-multi-stage docker-multi-stage: ## Builds 'thanos' docker image using multi-stage. @@ -179,14 +213,14 @@ docker-push: .PHONY: docs docs: ## Regenerates flags in docs for all thanos commands. docs: $(EMBEDMD) build - @EMBEDMD_BIN="$(EMBEDMD)" SED_BIN="$(SED)" scripts/genflagdocs.sh + @EMBEDMD_BIN="$(EMBEDMD)" SED_BIN="$(SED)" THANOS_BIN="$(GOBIN)/thanos" scripts/genflagdocs.sh @find . -type f -name "*.md" | SED_BIN="$(SED)" xargs scripts/cleanup-white-noise.sh .PHONY: check-docs check-docs: ## checks docs against discrepancy with flags, links, white noise. check-docs: $(EMBEDMD) $(LICHE) build - @EMBEDMD_BIN="$(EMBEDMD)" SED_BIN="$(SED)" scripts/genflagdocs.sh check - @$(LICHE) --recursive docs --exclude "(couchdb.apache.org/bylaws.html|cloud.tencent.com|alibabacloud.com)" --document-root . + @EMBEDMD_BIN="$(EMBEDMD)" SED_BIN="$(SED)" THANOS_BIN="$(GOBIN)/thanos" scripts/genflagdocs.sh check + @$(LICHE) --recursive docs --exclude "(couchdb.apache.org/bylaws.html|cloud.tencent.com|alibabacloud.com|zoom.us)" --document-root . @$(LICHE) --exclude "goreportcard.com" --document-root . *.md @find . -type f -name "*.md" | SED_BIN="$(SED)" xargs scripts/cleanup-white-noise.sh $(call require_clean_work_tree,"check documentation") @@ -200,6 +234,7 @@ check-comments: ## Checks Go code comments if they have trailing period (exclude format: ## Formats Go code including imports and cleans up white noise. format: $(GOIMPORTS) check-comments @echo ">> formatting code" + @gofmt -s -w $(FILES_TO_FMT) @$(GOIMPORTS) -w $(FILES_TO_FMT) @SED_BIN="$(SED)" scripts/cleanup-white-noise.sh $(FILES_TO_FMT) @@ -246,8 +281,14 @@ test-local: .PHONY: test-e2e test-e2e: ## Runs all Thanos e2e docker-based e2e tests from test/e2e. Required access to docker daemon. test-e2e: docker + @echo ">> cleaning docker environment." + @docker system prune -f --volumes + @echo ">> cleaning e2e test garbage." + @rm -rf ./test/e2e/e2e_integration_test* @echo ">> running /test/e2e tests." - @go test -v ./test/e2e/... + # NOTE(bwplotka): + # * If you see errors on CI (timeouts), but not locally, try to add -parallel 1 to limit to single CPU to reproduce small 1CPU machine. + @go test $(GOTEST_OPTS) ./test/e2e/... .PHONY: install-deps install-deps: ## Installs dependencies for integration tests. It installs supported versions of Prometheus and alertmanager to test against in integration tests. @@ -286,22 +327,34 @@ web: web-pre-process $(HUGO) # TODO(bwplotka): Make it --gc @cd $(WEB_DIR) && HUGO_ENV=production $(HUGO) --config hugo.yaml --minify -v -b $(WEBSITE_BASE_URL) +.PHONY:lint +lint: ## Runs various static analysis against our code. +lint: go-lint react-app-lint + # PROTIP: # Add # --cpu-profile-path string Path to CPU profile output file # --mem-profile-path string Path to memory profile output file # to debug big allocations during linting. -lint: ## Runs various static analysis against our code. -lint: check-git deps $(GOLANGCILINT) $(MISSPELL) $(FAILLINT) +.PHONY: go-lint +go-lint: check-git deps $(GOLANGCILINT) $(MISSPELL) $(FAILLINT) $(call require_clean_work_tree,"detected not clean master before running lint") @echo ">> verifying modules being imported" - @$(FAILLINT) -paths $(MODULES_TO_AVOID) ./... + @# TODO(bwplotka): Add, Printf, DefaultRegisterer, NewGaugeFunc and MustRegister once exception are accepted. Add fmt.{Errorf}=github.com/pkg/errors.{Errorf} once https://github.com/fatih/faillint/issues/10 is addressed. + @$(FAILLINT) -paths "errors=github.com/pkg/errors,\ +github.com/prometheus/tsdb=github.com/prometheus/prometheus/tsdb,\ +github.com/prometheus/prometheus/pkg/testutils=github.com/thanos-io/thanos/pkg/testutil,\ +github.com/prometheus/client_golang/prometheus.{DefaultGatherer,DefBuckets,NewUntypedFunc,UntypedFunc},\ +github.com/prometheus/client_golang/prometheus.{NewCounter,NewCounterVec,NewCounterVec,NewGauge,NewGaugeVec,NewGaugeFunc,\ +NewHistorgram,NewHistogramVec,NewSummary,NewSummaryVec}=github.com/prometheus/client_golang/prometheus/promauto.{NewCounter,\ +NewCounterVec,NewCounterVec,NewGauge,NewGaugeVec,NewGaugeFunc,NewHistorgram,NewHistogramVec,NewSummary,NewSummaryVec}" ./... + @$(FAILLINT) -paths "fmt.{Print,Println,Sprint}" -ignore-tests ./... @echo ">> examining all of the Go files" @go vet -stdmethods=false ./pkg/... ./cmd/... && go vet doc.go @echo ">> linting all of the Go files GOGC=${GOGC}" @$(GOLANGCILINT) run @echo ">> detecting misspells" - @find . -type f | grep -v vendor/ | grep -vE '\./\..*' | xargs $(MISSPELL) -error + @find . -type f | grep -v vendor/ | grep -v pkg/ui/react-app/node_modules | grep -v pkg/ui/static | grep -vE '\./\..*' | xargs $(MISSPELL) -error @echo ">> detecting white noise" @find . -type f \( -name "*.md" -o -name "*.go" \) | SED_BIN="$(SED)" xargs scripts/cleanup-white-noise.sh $(call require_clean_work_tree,"detected white noise") @@ -339,7 +392,7 @@ examples-in-container: examples .PHONY: examples -examples: jsonnet-format $(EMBEDMD) ${THANOS_MIXIN}/README.md examples/alerts/alerts.md examples/alerts/alerts.yaml examples/alerts/rules.yaml examples/dashboards examples/tmp +examples: jsonnet-vendor jsonnet-format $(EMBEDMD) ${THANOS_MIXIN}/README.md examples/alerts/alerts.md examples/alerts/alerts.yaml examples/alerts/rules.yaml examples/dashboards examples/tmp $(EMBEDMD) -w examples/alerts/alerts.md $(EMBEDMD) -w ${THANOS_MIXIN}/README.md @@ -350,40 +403,42 @@ examples/tmp: $(JSONNET) -J ${JSONNET_VENDOR_DIR} -m examples/tmp/ ${THANOS_MIXIN}/separated_alerts.jsonnet | xargs -I{} sh -c 'cat {} | $(GOJSONTOYAML) > {}.yaml; rm -f {}' -- {} .PHONY: examples/dashboards # to keep examples/dashboards/dashboards.md. -examples/dashboards: $(JSONNET) ${THANOS_MIXIN}/mixin.libsonnet ${THANOS_MIXIN}/defaults.libsonnet ${THANOS_MIXIN}/dashboards/* +examples/dashboards: $(JSONNET) ${THANOS_MIXIN}/mixin.libsonnet ${THANOS_MIXIN}/config.libsonnet ${THANOS_MIXIN}/dashboards/* -rm -rf examples/dashboards/*.json $(JSONNET) -J ${JSONNET_VENDOR_DIR} -m examples/dashboards ${THANOS_MIXIN}/dashboards.jsonnet -examples/alerts/alerts.yaml: $(JSONNET) $(GOJSONTOYAML) ${THANOS_MIXIN}/mixin.libsonnet ${THANOS_MIXIN}/defaults.libsonnet ${THANOS_MIXIN}/alerts/* +examples/alerts/alerts.yaml: $(JSONNET) $(GOJSONTOYAML) ${THANOS_MIXIN}/mixin.libsonnet ${THANOS_MIXIN}/config.libsonnet ${THANOS_MIXIN}/alerts/* $(JSONNET) ${THANOS_MIXIN}/alerts.jsonnet | $(GOJSONTOYAML) > $@ -examples/alerts/rules.yaml: $(JSONNET) $(GOJSONTOYAML) ${THANOS_MIXIN}/mixin.libsonnet ${THANOS_MIXIN}/defaults.libsonnet ${THANOS_MIXIN}/rules/* +examples/alerts/rules.yaml: $(JSONNET) $(GOJSONTOYAML) ${THANOS_MIXIN}/mixin.libsonnet ${THANOS_MIXIN}/config.libsonnet ${THANOS_MIXIN}/rules/* $(JSONNET) ${THANOS_MIXIN}/rules.jsonnet | $(GOJSONTOYAML) > $@ .PHONY: jsonnet-vendor -jsonnet-vendor: $(JSONNET_BUNDLER) $(MIXIN_ROOT)/jsonnetfile.json $(MIXIN_ROOT)/jsonnetfile.lock.json +jsonnet-vendor: $(JSONNET_BUNDLER) $(THANOS_MIXIN)/jsonnetfile.json $(THANOS_MIXIN)/jsonnetfile.lock.json rm -rf ${JSONNET_VENDOR_DIR} - cd ${MIXIN_ROOT} && $(JSONNET_BUNDLER) install + cd ${THANOS_MIXIN} && $(JSONNET_BUNDLER) install -JSONNET_FMT := jsonnetfmt -n 2 --max-blank-lines 2 --string-style s --comment-style s +JSONNETFMT_CMD := $(JSONNETFMT) -n 2 --max-blank-lines 2 --string-style s --comment-style s .PHONY: jsonnet-format -jsonnet-format: - @which jsonnetfmt 2>&1 >/dev/null || ( \ - echo "Cannot find jsonnetfmt command, please install from https://github.com/google/jsonnet/releases.\nIf your C++ does not support GLIBCXX_3.4.20, please use xxx-in-container target like jsonnet-format-in-container." \ - && exit 1) +jsonnet-format: $(JSONNETFMT) find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ - xargs -n 1 -- $(JSONNET_FMT) -i + xargs -n 1 -- $(JSONNETFMT_CMD) -i .PHONY: jsonnet-format-in-container jsonnet-format-in-container: - $(JSONNET_CONTAINER_CMD) make $(MFLAGS) jsonnet-format + $(JSONNET_CONTAINER_CMD) find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ + xargs -n 1 -- jsonnetfmt -n 2 --max-blank-lines 2 --string-style s --comment-style s -i .PHONY: example-rules-lint example-rules-lint: $(PROMTOOL) examples/alerts/alerts.yaml examples/alerts/rules.yaml $(PROMTOOL) check rules examples/alerts/alerts.yaml examples/alerts/rules.yaml $(PROMTOOL) test rules examples/alerts/tests.yaml +.PHONY: check-examples +check-examples: examples example-rules-lint + $(call require_clean_work_tree,'all generated files should be committed,check examples') + .PHONY: examples-clean examples-clean: rm -f examples/alerts/alerts.yaml @@ -441,6 +496,9 @@ $(PROTOC): $(JSONNET): $(call fetch_go_bin_version,github.com/google/go-jsonnet/cmd/jsonnet,$(JSONNET_VERSION)) +$(JSONNETFMT): + $(call fetch_go_bin_version,github.com/google/go-jsonnet/cmd/jsonnetfmt,$(JSONNET_VERSION)) + $(GOJSONTOYAML): $(call fetch_go_bin_version,github.com/brancz/gojsontoyaml,$(GOJSONTOYAML_VERSION)) diff --git a/README.md b/README.md index 2f4240bcca..e163a9cc97 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@

Thanos Logo

+[![Latest Release](https://img.shields.io/github/release/thanos-io/thanos.svg?style=flat-square)](https://github.com/thanos-io/thanos/releases/latest) [![CI](https://circleci.com/gh/thanos-io/thanos.svg?style=svg)](https://circleci.com/gh/thanos-io/thanos) [![Cross Build](https://github.com/thanos-io/thanos/workflows/cross-build/badge.svg)](https://github.com/thanos-io/thanos/actions?query=workflow%3Across-build) [![End-to-End Tests](https://github.com/thanos-io/thanos/workflows/e2e/badge.svg)](https://github.com/thanos-io/thanos/actions?query=workflow%3Ae2e) @@ -66,7 +67,7 @@ The philosophy of Thanos and our community is borrowing much from UNIX philosoph ## Releases -Master should be stable and usable. Every commit to master builds docker image named `master--` in [quay.io/thanos/thanos](https://quay.io/repository/thanos/thanos) and [thanosio/thanos dockerhub (mirror)](https://hub.docker.com/r/thanosio/thanos) +Master should be stable and usable. Every commit to master builds docker image named `master--` in [quay.io/thanos/thanos](https://quay.io/repository/thanos/thanos) and [thanosio/thanos dockerhub (mirror)](https://hub.docker.com/r/thanosio/thanos) We also perform minor releases every 6 weeks. diff --git a/VERSION b/VERSION index 539f9fc668..26acbf080b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.10.1-dev +0.12.2 diff --git a/cmd/thanos/compact.go b/cmd/thanos/compact.go index b0ea2f346c..60dc702b29 100644 --- a/cmd/thanos/compact.go +++ b/cmd/thanos/compact.go @@ -16,9 +16,12 @@ import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "github.com/oklog/run" + "github.com/oklog/ulid" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/common/route" "github.com/prometheus/prometheus/tsdb" "github.com/thanos-io/thanos/pkg/block" "github.com/thanos-io/thanos/pkg/block/indexheader" @@ -28,11 +31,13 @@ import ( "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/extflag" "github.com/thanos-io/thanos/pkg/extprom" + extpromhttp "github.com/thanos-io/thanos/pkg/extprom/http" "github.com/thanos-io/thanos/pkg/objstore" "github.com/thanos-io/thanos/pkg/objstore/client" "github.com/thanos-io/thanos/pkg/prober" "github.com/thanos-io/thanos/pkg/runutil" httpserver "github.com/thanos-io/thanos/pkg/server/http" + "github.com/thanos-io/thanos/pkg/ui" "gopkg.in/alecthomas/kingpin.v2" ) @@ -102,10 +107,14 @@ func registerCompact(m map[string]setupFunc, app *kingpin.Application) { retention5m := modelDuration(cmd.Flag("retention.resolution-5m", "How long to retain samples of resolution 1 (5 minutes) in bucket. Setting this to 0d will retain samples of this resolution forever").Default("0d")) retention1h := modelDuration(cmd.Flag("retention.resolution-1h", "How long to retain samples of resolution 2 (1 hour) in bucket. Setting this to 0d will retain samples of this resolution forever").Default("0d")) + // TODO(kakkoyun): https://github.com/thanos-io/thanos/issues/2266. wait := cmd.Flag("wait", "Do not exit after all compactions have been processed and wait for new work."). Short('w').Bool() - generateMissingIndexCacheFiles := cmd.Flag("index.generate-missing-cache-file", "If enabled, on startup compactor runs an on-off job that scans all the blocks to find all blocks with missing index cache file. It generates those if needed and upload."). + waitInterval := cmd.Flag("wait-interval", "Wait interval between consecutive compaction runs and bucket refreshes. Only works when --wait flag specified."). + Default("5m").Duration() + + generateMissingIndexCacheFiles := cmd.Flag("index.generate-missing-cache-file", "DEPRECATED flag. Will be removed in next release. If enabled, on startup compactor runs an on-off job that scans all the blocks to find all blocks with missing index cache file. It generates those if needed and upload."). Hidden().Default("false").Bool() disableDownsampling := cmd.Flag("downsampling.disable", "Disables downsampling. This is not recommended "+ @@ -121,8 +130,25 @@ func registerCompact(m map[string]setupFunc, app *kingpin.Application) { compactionConcurrency := cmd.Flag("compact.concurrency", "Number of goroutines to use when compacting groups."). Default("1").Int() + deleteDelay := modelDuration(cmd.Flag("delete-delay", "Time before a block marked for deletion is deleted from bucket. "+ + "If delete-delay is non zero, blocks will be marked for deletion and compactor component will delete blocks marked for deletion from the bucket. "+ + "If delete-delay is 0, blocks will be deleted straight away. "+ + "Note that deleting blocks immediately can cause query failures, if store gateway still has the block loaded, "+ + "or compactor is ignoring the deletion because it's compacting the block at the same time."). + Default("48h")) + + dedupReplicaLabels := cmd.Flag("deduplication.replica-label", "Label to treat as a replica indicator of blocks that can be deduplicated (repeated flag). This will merge multiple replica blocks into one. This process is irreversible."+ + "Experimental. When it is set to true, compactor will ignore the given labels so that vertical compaction can merge the blocks."+ + "Please note that this uses a NAIVE algorithm for merging (no smart replica deduplication, just chaining samples together)."+ + "This works well for deduplication of blocks with **precisely the same samples** like produced by Receiver replication."). + Hidden().Strings() + selectorRelabelConf := regSelectorRelabelFlags(cmd) + webExternalPrefix := cmd.Flag("web.external-prefix", "Static prefix for all HTML links and redirect URLs in the bucket web UI interface. Actual endpoints are still served on / or the web.route-prefix. This allows thanos bucket web UI to be served behind a reverse proxy that strips a URL sub-path.").Default("").String() + webPrefixHeaderName := cmd.Flag("web.prefix-header", "Name of HTTP request header used for dynamic prefixing of UI links and redirects. This option is ignored if web.external-prefix argument is set. Security risk: enable this option only if a reverse proxy in front of thanos is resetting the header. The --web.prefix-header=X-Forwarded-Prefix option can be useful, for example, if Thanos UI is served via Traefik reverse proxy with PathPrefixStrip option enabled, which sends the stripped prefix value in X-Forwarded-Prefix header. This allows thanos UI to be served on a sub-path.").Default("").String() + label := cmd.Flag("bucket-web-label", "Prometheus label to use as timeline title in the bucket web UI").String() + m[component.Compact.String()] = func(g *run.Group, logger log.Logger, reg *prometheus.Registry, tracer opentracing.Tracer, _ <-chan struct{}, _ bool) error { return runCompact(g, logger, reg, *httpAddr, @@ -130,6 +156,7 @@ func registerCompact(m map[string]setupFunc, app *kingpin.Application) { *dataDir, objStoreConfig, time.Duration(*consistencyDelay), + time.Duration(*deleteDelay), *haltOnError, *acceptMalformedIndex, *wait, @@ -144,7 +171,12 @@ func registerCompact(m map[string]setupFunc, app *kingpin.Application) { *maxCompactionLevel, *blockSyncConcurrency, *compactionConcurrency, + *dedupReplicaLabels, selectorRelabelConf, + *waitInterval, + *label, + *webExternalPrefix, + *webPrefixHeaderName, ) } } @@ -158,43 +190,61 @@ func runCompact( dataDir string, objStoreConfig *extflag.PathOrContent, consistencyDelay time.Duration, - haltOnError bool, - acceptMalformedIndex bool, - wait bool, - generateMissingIndexCacheFiles bool, + deleteDelay time.Duration, + haltOnError, acceptMalformedIndex, wait, generateMissingIndexCacheFiles bool, retentionByResolution map[compact.ResolutionLevel]time.Duration, component component.Component, disableDownsampling bool, - maxCompactionLevel int, - blockSyncConcurrency int, + maxCompactionLevel, blockSyncConcurrency int, concurrency int, + dedupReplicaLabels []string, selectorRelabelConf *extflag.PathOrContent, + waitInterval time.Duration, + label string, + externalPrefix, prefixHeader string, ) error { - halted := prometheus.NewGauge(prometheus.GaugeOpts{ + halted := promauto.With(reg).NewGauge(prometheus.GaugeOpts{ Name: "thanos_compactor_halted", Help: "Set to 1 if the compactor halted due to an unexpected error.", }) halted.Set(0) - retried := prometheus.NewCounter(prometheus.CounterOpts{ + retried := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_compactor_retries_total", Help: "Total number of retries after retriable compactor error.", }) - iterations := prometheus.NewCounter(prometheus.CounterOpts{ + iterations := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_compactor_iterations_total", Help: "Total number of iterations that were executed successfully.", }) - partialUploadDeleteAttempts := prometheus.NewCounter(prometheus.CounterOpts{ + partialUploadDeleteAttempts := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_compactor_aborted_partial_uploads_deletion_attempts_total", Help: "Total number of started deletions of blocks that are assumed aborted and only partially uploaded.", }) - reg.MustRegister(halted, retried, iterations, partialUploadDeleteAttempts) + blocksCleaned := promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "thanos_compactor_blocks_cleaned_total", + Help: "Total number of blocks deleted in compactor.", + }) + blockCleanupFailures := promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "thanos_compactor_block_cleanup_failures_total", + Help: "Failures encountered while deleting blocks in compactor.", + }) + blocksMarkedForDeletion := promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "thanos_compactor_blocks_marked_for_deletion_total", + Help: "Total number of blocks marked for deletion in compactor.", + }) + _ = promauto.With(reg).NewGaugeFunc(prometheus.GaugeOpts{ + Name: "thanos_delete_delay_seconds", + Help: "Configured delete delay in seconds.", + }, func() float64 { + return deleteDelay.Seconds() + }) downsampleMetrics := newDownsampleMetrics(reg) httpProbe := prober.NewHTTP() statusProber := prober.Combine( httpProbe, - prober.NewInstrumentation(component, logger, prometheus.WrapRegistererWithPrefix("thanos_", reg)), + prober.NewInstrumentation(component, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)), ) srv := httpserver.New(logger, reg, component, httpProbe, @@ -240,20 +290,49 @@ func runCompact( } }() + // While fetching blocks, we filter out blocks that were marked for deletion by using IgnoreDeletionMarkFilter. + // The delay of deleteDelay/2 is added to ensure we fetch blocks that are meant to be deleted but do not have a replacement yet. + // This is to make sure compactor will not accidentally perform compactions with gap instead. + ignoreDeletionMarkFilter := block.NewIgnoreDeletionMarkFilter(logger, bkt, deleteDelay/2) duplicateBlocksFilter := block.NewDeduplicateFilter() - prometheusRegisterer := extprom.WrapRegistererWithPrefix("thanos_", reg) - metaFetcher, err := block.NewMetaFetcher(logger, 32, bkt, "", prometheusRegisterer, - block.NewLabelShardedMetaFilter(relabelConfig).Filter, - block.NewConsistencyDelayMetaFilter(logger, consistencyDelay, prometheusRegisterer).Filter, - duplicateBlocksFilter.Filter, - ) + + baseMetaFetcher, err := block.NewBaseFetcher(logger, 32, bkt, "", extprom.WrapRegistererWithPrefix("thanos_", reg)) if err != nil { return errors.Wrap(err, "create meta fetcher") } - sy, err := compact.NewSyncer(logger, reg, bkt, metaFetcher, duplicateBlocksFilter, blockSyncConcurrency, acceptMalformedIndex, false) - if err != nil { - return errors.Wrap(err, "create syncer") + enableVerticalCompaction := false + if len(dedupReplicaLabels) > 0 { + enableVerticalCompaction = true + level.Info(logger).Log("msg", "deduplication.replica-label specified, vertical compaction is enabled", "dedupReplicaLabels", strings.Join(dedupReplicaLabels, ",")) + } + + compactorView := ui.NewBucketUI(logger, label, path.Join(externalPrefix, "/loaded"), prefixHeader) + var sy *compact.Syncer + { + // Make sure all compactor meta syncs are done through Syncer.SyncMeta for readability. + cf := baseMetaFetcher.NewMetaFetcher( + extprom.WrapRegistererWithPrefix("thanos_", reg), []block.MetadataFilter{ + block.NewLabelShardedMetaFilter(relabelConfig), + block.NewConsistencyDelayMetaFilter(logger, consistencyDelay, extprom.WrapRegistererWithPrefix("thanos_", reg)), + ignoreDeletionMarkFilter, + duplicateBlocksFilter, + }, []block.MetadataModifier{block.NewReplicaLabelRemover(logger, dedupReplicaLabels)}, + ) + cf.UpdateOnChange(compactorView.Set) + sy, err = compact.NewSyncer( + logger, + reg, + bkt, + cf, + duplicateBlocksFilter, + ignoreDeletionMarkFilter, + blocksMarkedForDeletion, + blockSyncConcurrency, + acceptMalformedIndex, enableVerticalCompaction) + if err != nil { + return errors.Wrap(err, "create syncer") + } } levels, err := compactions.levels(maxCompactionLevel) @@ -285,6 +364,7 @@ func runCompact( return errors.Wrap(err, "clean working downsample directory") } + blocksCleaner := compact.NewBlocksCleaner(logger, bkt, ignoreDeletionMarkFilter, deleteDelay, blocksCleaned, blockCleanupFailures) compactor, err := compact.NewBucketCompactor(logger, sy, comp, compactDir, bkt, concurrency) if err != nil { cancel() @@ -303,7 +383,7 @@ func runCompact( compactMainFn := func() error { if err := compactor.Compact(ctx); err != nil { - return errors.Wrap(err, "compaction failed") + return errors.Wrap(err, "compaction") } if !disableDownsampling { @@ -311,35 +391,52 @@ func runCompact( // We run two passes of this to ensure that the 1h downsampling is generated // for 5m downsamplings created in the first run. level.Info(logger).Log("msg", "start first pass of downsampling") - - if err := downsampleBucket(ctx, logger, downsampleMetrics, bkt, metaFetcher, downsamplingDir); err != nil { + if err := sy.SyncMetas(ctx); err != nil { + return errors.Wrap(err, "sync before first pass of downsampling") + } + if err := downsampleBucket(ctx, logger, downsampleMetrics, bkt, sy.Metas(), downsamplingDir); err != nil { return errors.Wrap(err, "first pass of downsampling failed") } level.Info(logger).Log("msg", "start second pass of downsampling") - - if err := downsampleBucket(ctx, logger, downsampleMetrics, bkt, metaFetcher, downsamplingDir); err != nil { + if err := sy.SyncMetas(ctx); err != nil { + return errors.Wrap(err, "sync before second pass of downsampling") + } + if err := downsampleBucket(ctx, logger, downsampleMetrics, bkt, sy.Metas(), downsamplingDir); err != nil { return errors.Wrap(err, "second pass of downsampling failed") } level.Info(logger).Log("msg", "downsampling iterations done") } else { - level.Warn(logger).Log("msg", "downsampling was explicitly disabled") + level.Info(logger).Log("msg", "downsampling was explicitly disabled") } - if err := compact.ApplyRetentionPolicyByResolution(ctx, logger, bkt, metaFetcher, retentionByResolution); err != nil { - return errors.Wrap(err, fmt.Sprintf("retention failed")) + // TODO(bwplotka): Find a way to avoid syncing if no op was done. + if err := sy.SyncMetas(ctx); err != nil { + return errors.Wrap(err, "sync before first pass of downsampling") } - compact.BestEffortCleanAbortedPartialUploads(ctx, logger, metaFetcher, bkt, partialUploadDeleteAttempts) + if err := compact.ApplyRetentionPolicyByResolution(ctx, logger, bkt, sy.Metas(), retentionByResolution, blocksMarkedForDeletion); err != nil { + return errors.Wrap(err, "retention failed") + } + + // No need to resync before partial uploads and delete marked blocks. Last sync should be valid. + compact.BestEffortCleanAbortedPartialUploads(ctx, logger, sy.Partial(), bkt, partialUploadDeleteAttempts, blocksCleaned, blockCleanupFailures) + if err := blocksCleaner.DeleteMarkedBlocks(ctx); err != nil { + return errors.Wrap(err, "error cleaning blocks") + } return nil } g.Add(func() error { defer runutil.CloseWithLogOnErr(logger, bkt, "bucket client") - // Generate index file. + // Generate index files. + // TODO(bwplotka): Remove this in next release. if generateMissingIndexCacheFiles { - if err := genMissingIndexCacheFiles(ctx, logger, reg, bkt, metaFetcher, indexCacheDir); err != nil { + if err := sy.SyncMetas(ctx); err != nil { + return err + } + if err := genMissingIndexCacheFiles(ctx, logger, reg, bkt, sy.Metas(), indexCacheDir); err != nil { return err } } @@ -349,7 +446,7 @@ func runCompact( } // --wait=true is specified. - return runutil.Repeat(5*time.Minute, ctx.Done(), func() error { + return runutil.Repeat(waitInterval, ctx.Done(), func() error { err := compactMainFn() if err == nil { iterations.Inc() @@ -383,18 +480,56 @@ func runCompact( cancel() }) + if wait { + r := route.New() + + ins := extpromhttp.NewInstrumentationMiddleware(reg) + compactorView.Register(r, ins) + + global := ui.NewBucketUI(logger, label, path.Join(externalPrefix, "/global"), prefixHeader) + global.Register(r, ins) + + // Separate fetcher for global view. + // TODO(bwplotka): Allow Bucket UI to visualize the state of the block as well. + f := baseMetaFetcher.NewMetaFetcher(extprom.WrapRegistererWithPrefix("thanos_bucket_ui", reg), nil, nil, "component", "globalBucketUI") + f.UpdateOnChange(global.Set) + + srv.Handle("/", r) + + g.Add(func() error { + iterCtx, iterCancel := context.WithTimeout(ctx, waitInterval) + _, _, _ = f.Fetch(iterCtx) + iterCancel() + + // For /global state make sure to fetch periodically. + return runutil.Repeat(time.Minute, ctx.Done(), func() error { + return runutil.RetryWithLog(logger, time.Minute, ctx.Done(), func() error { + iterCtx, iterCancel := context.WithTimeout(ctx, waitInterval) + defer iterCancel() + + _, _, err := f.Fetch(iterCtx) + if err != nil { + return err + } + return nil + }) + }) + }, func(error) { + cancel() + }) + } + level.Info(logger).Log("msg", "starting compact node") statusProber.Ready() return nil } // genMissingIndexCacheFiles scans over all blocks, generates missing index cache files and uploads them to object storage. -func genMissingIndexCacheFiles(ctx context.Context, logger log.Logger, reg *prometheus.Registry, bkt objstore.Bucket, fetcher block.MetadataFetcher, dir string) error { - genIndex := prometheus.NewCounter(prometheus.CounterOpts{ +func genMissingIndexCacheFiles(ctx context.Context, logger log.Logger, reg *prometheus.Registry, bkt objstore.Bucket, metas map[ulid.ULID]*metadata.Meta, dir string) error { + genIndex := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: metricIndexGenerateName, Help: metricIndexGenerateHelp, }) - reg.MustRegister(genIndex) if err := os.RemoveAll(dir); err != nil { return errors.Wrap(err, "clean index cache directory") @@ -411,11 +546,6 @@ func genMissingIndexCacheFiles(ctx context.Context, logger log.Logger, reg *prom level.Info(logger).Log("msg", "start index cache processing") - metas, _, err := fetcher.Fetch(ctx) - if err != nil { - return errors.Wrap(err, "fetch metas") - } - for _, meta := range metas { // New version of compactor pushes index cache along with data block. // Skip uncompacted blocks. @@ -456,7 +586,7 @@ func generateIndexCacheFile( cachePath := filepath.Join(bdir, block.IndexCacheFilename) cache := path.Join(meta.ULID.String(), block.IndexCacheFilename) - ok, err := objstore.Exists(ctx, bkt, cache) + ok, err := bkt.Exists(ctx, cache) if ok { return nil } diff --git a/cmd/thanos/config.go b/cmd/thanos/config.go new file mode 100644 index 0000000000..da80f24cde --- /dev/null +++ b/cmd/thanos/config.go @@ -0,0 +1,127 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package main + +import ( + "net/url" + "time" + + "github.com/prometheus/common/model" + "gopkg.in/alecthomas/kingpin.v2" +) + +type grpcConfig struct { + bindAddress string + gracePeriod model.Duration + tlsSrvCert string + tlsSrvKey string + tlsSrvClientCA string +} + +func (gc *grpcConfig) registerFlag(cmd *kingpin.CmdClause) *grpcConfig { + cmd.Flag("grpc-address", + "Listen ip:port address for gRPC endpoints (StoreAPI). Make sure this address is routable from other components."). + Default("0.0.0.0:10901").StringVar(&gc.bindAddress) + cmd.Flag("grpc-grace-period", + "Time to wait after an interrupt received for GRPC Server."). + Default("2m").SetValue(&gc.gracePeriod) + cmd.Flag("grpc-server-tls-cert", + "TLS Certificate for gRPC server, leave blank to disable TLS"). + Default("").StringVar(&gc.tlsSrvCert) + cmd.Flag("grpc-server-tls-key", + "TLS Key for the gRPC server, leave blank to disable TLS"). + Default("").StringVar(&gc.tlsSrvKey) + cmd.Flag("grpc-server-tls-client-ca", + "TLS CA to verify clients against. If no client CA is specified, there is no client verification on server side. (tls.NoClientCert)"). + Default("").StringVar(&gc.tlsSrvClientCA) + return gc +} + +type httpConfig struct { + bindAddress string + gracePeriod model.Duration +} + +func (hc *httpConfig) registerFlag(cmd *kingpin.CmdClause) *httpConfig { + cmd.Flag("http-address", + "Listen host:port for HTTP endpoints."). + Default("0.0.0.0:10902").StringVar(&hc.bindAddress) + cmd.Flag("http-grace-period", + "Time to wait after an interrupt received for HTTP Server."). + Default("2m").SetValue(&hc.gracePeriod) + return hc +} + +type prometheusConfig struct { + url *url.URL + readyTimeout time.Duration +} + +func (pc *prometheusConfig) registerFlag(cmd *kingpin.CmdClause) *prometheusConfig { + cmd.Flag("prometheus.url", + "URL at which to reach Prometheus's API. For better performance use local network."). + Default("http://localhost:9090").URLVar(&pc.url) + cmd.Flag("prometheus.ready_timeout", + "Maximum time to wait for the Prometheus instance to start up"). + Default("10m").DurationVar(&pc.readyTimeout) + return pc +} + +type connConfig struct { + maxIdleConns int + maxIdleConnsPerHost int +} + +func (cc *connConfig) registerFlag(cmd *kingpin.CmdClause) *connConfig { + cmd.Flag("receive.connection-pool-size", + "Controls the http MaxIdleConns. Default is 0, which is unlimited"). + IntVar(&cc.maxIdleConns) + cmd.Flag("receive.connection-pool-size-per-host", + "Controls the http MaxIdleConnsPerHost"). + Default("100").IntVar(&cc.maxIdleConnsPerHost) + return cc +} + +type tsdbConfig struct { + path string +} + +func (tc *tsdbConfig) registerFlag(cmd *kingpin.CmdClause) *tsdbConfig { + cmd.Flag("tsdb.path", "Data directory of TSDB.").Default("./data").StringVar(&tc.path) + return tc +} + +type reloaderConfig struct { + confFile string + envVarConfFile string + ruleDirectories []string +} + +func (rc *reloaderConfig) registerFlag(cmd *kingpin.CmdClause) *reloaderConfig { + cmd.Flag("reloader.config-file", + "Config file watched by the reloader."). + Default("").StringVar(&rc.confFile) + cmd.Flag("reloader.config-envsubst-file", + "Output file for environment variable substituted config file."). + Default("").StringVar(&rc.envVarConfFile) + cmd.Flag("reloader.rule-dir", + "Rule directories for the reloader to refresh (repeated field)."). + StringsVar(&rc.ruleDirectories) + return rc +} + +type shipperConfig struct { + uploadCompacted bool + ignoreBlockSize bool +} + +func (sc *shipperConfig) registerFlag(cmd *kingpin.CmdClause) *shipperConfig { + cmd.Flag("shipper.upload-compacted", + "If true sidecar will try to upload compacted blocks as well. Useful for migration purposes. Works only if compaction is disabled on Prometheus. Do it once and then disable the flag when done."). + Default("false").BoolVar(&sc.uploadCompacted) + cmd.Flag("shipper.ignore-unequal-block-size", + "If true sidecar will not require prometheus min and max block size flags to be set to the same value. Only use this if you want to keep long retention and compaction enabled on your Prometheus instance, as in the worst case it can result in ~2h data loss for your Thanos bucket storage."). + Default("false").Hidden().BoolVar(&sc.ignoreBlockSize) + return sc +} diff --git a/cmd/thanos/downsample.go b/cmd/thanos/downsample.go index d38ea26273..13e1aa8a68 100644 --- a/cmd/thanos/downsample.go +++ b/cmd/thanos/downsample.go @@ -13,9 +13,9 @@ import ( "github.com/go-kit/kit/log/level" "github.com/oklog/run" "github.com/oklog/ulid" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/tsdb" "github.com/prometheus/prometheus/tsdb/chunkenc" "github.com/thanos-io/thanos/pkg/block" @@ -30,25 +30,8 @@ import ( "github.com/thanos-io/thanos/pkg/prober" "github.com/thanos-io/thanos/pkg/runutil" httpserver "github.com/thanos-io/thanos/pkg/server/http" - kingpin "gopkg.in/alecthomas/kingpin.v2" ) -func registerDownsample(m map[string]setupFunc, app *kingpin.Application) { - comp := component.Downsample - cmd := app.Command(comp.String(), "continuously downsamples blocks in an object store bucket") - - httpAddr, httpGracePeriod := regHTTPFlags(cmd) - - dataDir := cmd.Flag("data-dir", "Data directory in which to cache blocks and process downsamplings."). - Default("./data").String() - - objStoreConfig := regCommonObjStoreFlags(cmd, "", true) - - m[comp.String()] = func(g *run.Group, logger log.Logger, reg *prometheus.Registry, tracer opentracing.Tracer, _ <-chan struct{}, _ bool) error { - return runDownsample(g, logger, reg, *httpAddr, time.Duration(*httpGracePeriod), *dataDir, objStoreConfig, comp) - } -} - type DownsampleMetrics struct { downsamples *prometheus.CounterVec downsampleFailures *prometheus.CounterVec @@ -57,22 +40,19 @@ type DownsampleMetrics struct { func newDownsampleMetrics(reg *prometheus.Registry) *DownsampleMetrics { m := new(DownsampleMetrics) - m.downsamples = prometheus.NewCounterVec(prometheus.CounterOpts{ + m.downsamples = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_compact_downsample_total", Help: "Total number of downsampling attempts.", }, []string{"group"}) - m.downsampleFailures = prometheus.NewCounterVec(prometheus.CounterOpts{ + m.downsampleFailures = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_compact_downsample_failures_total", Help: "Total number of failed downsampling attempts.", }, []string{"group"}) - reg.MustRegister(m.downsamples) - reg.MustRegister(m.downsampleFailures) - return m } -func runDownsample( +func RunDownsample( g *run.Group, logger log.Logger, reg *prometheus.Registry, @@ -92,7 +72,9 @@ func runDownsample( return err } - metaFetcher, err := block.NewMetaFetcher(logger, 32, bkt, "", extprom.WrapRegistererWithPrefix("thanos_", reg)) + metaFetcher, err := block.NewMetaFetcher(logger, 32, bkt, "", extprom.WrapRegistererWithPrefix("thanos_", reg), []block.MetadataFilter{ + block.NewDeduplicateFilter(), + }, nil) if err != nil { return errors.Wrap(err, "create meta fetcher") } @@ -107,7 +89,7 @@ func runDownsample( httpProbe := prober.NewHTTP() statusProber := prober.Combine( httpProbe, - prober.NewInstrumentation(comp, logger, prometheus.WrapRegistererWithPrefix("thanos_", reg)), + prober.NewInstrumentation(comp, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)), ) metrics := newDownsampleMetrics(reg) @@ -120,14 +102,20 @@ func runDownsample( statusProber.Ready() level.Info(logger).Log("msg", "start first pass of downsampling") - - if err := downsampleBucket(ctx, logger, metrics, bkt, metaFetcher, dataDir); err != nil { + metas, _, err := metaFetcher.Fetch(ctx) + if err != nil { + return errors.Wrap(err, "sync before first pass of downsampling") + } + if err := downsampleBucket(ctx, logger, metrics, bkt, metas, dataDir); err != nil { return errors.Wrap(err, "downsampling failed") } level.Info(logger).Log("msg", "start second pass of downsampling") - - if err := downsampleBucket(ctx, logger, metrics, bkt, metaFetcher, dataDir); err != nil { + metas, _, err = metaFetcher.Fetch(ctx) + if err != nil { + return errors.Wrap(err, "sync before second pass of downsampling") + } + if err := downsampleBucket(ctx, logger, metrics, bkt, metas, dataDir); err != nil { return errors.Wrap(err, "downsampling failed") } @@ -162,7 +150,7 @@ func downsampleBucket( logger log.Logger, metrics *DownsampleMetrics, bkt objstore.Bucket, - fetcher block.MetadataFetcher, + metas map[ulid.ULID]*metadata.Meta, dir string, ) error { if err := os.RemoveAll(dir); err != nil { @@ -178,11 +166,6 @@ func downsampleBucket( } }() - metas, _, err := fetcher.Fetch(ctx) - if err != nil { - return errors.Wrap(err, "downsampling meta fetch") - } - // mapping from a hash over all source IDs to blocks. We don't need to downsample a block // if a downsampled version with the same hash already exists. sources5m := map[ulid.ULID]struct{}{} diff --git a/cmd/thanos/flags.go b/cmd/thanos/flags.go index fac85c125a..d5f9ddf12a 100644 --- a/cmd/thanos/flags.go +++ b/cmd/thanos/flags.go @@ -7,9 +7,8 @@ import ( "fmt" "strings" - "github.com/thanos-io/thanos/pkg/extflag" - "github.com/prometheus/common/model" + "github.com/thanos-io/thanos/pkg/extflag" "gopkg.in/alecthomas/kingpin.v2" ) @@ -60,7 +59,7 @@ func regCommonTracingFlags(app *kingpin.Application) *extflag.PathOrContent { return extflag.RegisterPathOrContent( app, "tracing.config", - fmt.Sprintf("YAML file with tracing configuration. See format details: https://thanos.io/tracing.md/#configuration "), + "YAML file with tracing configuration. See format details: https://thanos.io/tracing.md/#configuration ", false, ) } diff --git a/cmd/thanos/main.go b/cmd/thanos/main.go index f77424d8ce..c5b22d74d7 100644 --- a/cmd/thanos/main.go +++ b/cmd/thanos/main.go @@ -60,10 +60,8 @@ func main() { registerQuery(cmds, app) registerRule(cmds, app) registerCompact(cmds, app) - registerBucket(cmds, app, "bucket") - registerDownsample(cmds, app) + registerTools(cmds, app) registerReceive(cmds, app) - registerChecks(cmds, app, "check") cmd, err := app.Parse(os.Args[1:]) if err != nil { @@ -119,6 +117,7 @@ func main() { prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}), ) + // Some packages still use default Register. Replace to have those metrics. prometheus.DefaultRegisterer = metrics // Memberlist uses go-metrics. sink, err := gprom.NewPrometheusSink() @@ -182,7 +181,8 @@ func main() { reloadCh := make(chan struct{}, 1) if err := cmds[cmd](&g, logger, metrics, tracer, reloadCh, *logLevel == "debug"); err != nil { - level.Error(logger).Log("err", errors.Wrapf(err, "%s command failed", cmd)) + // Use %+v for github.com/pkg/errors error to print with stack. + level.Error(logger).Log("err", fmt.Sprintf("%+v", errors.Wrapf(err, "preparing %s command failed", cmd))) os.Exit(1) } @@ -207,7 +207,8 @@ func main() { } if err := g.Run(); err != nil { - level.Error(logger).Log("msg", "running command failed", "err", err) + // Use %+v for github.com/pkg/errors error to print with stack. + level.Error(logger).Log("err", fmt.Sprintf("%+v", errors.Wrapf(err, "%s command failed", cmd))) os.Exit(1) } level.Info(logger).Log("msg", "exiting") @@ -234,7 +235,7 @@ func reload(logger log.Logger, cancel <-chan struct{}, r chan<- struct{}) error level.Info(logger).Log("msg", "caught signal. Reloading.", "signal", s) select { case r <- struct{}{}: - level.Info(logger).Log("msg", "relaod dispatched.") + level.Info(logger).Log("msg", "reload dispatched.") default: } case <-cancel: diff --git a/cmd/thanos/main_test.go b/cmd/thanos/main_test.go index 1917a79f20..ffd6598bd8 100644 --- a/cmd/thanos/main_test.go +++ b/cmd/thanos/main_test.go @@ -15,13 +15,14 @@ import ( "github.com/go-kit/kit/log" "github.com/oklog/ulid" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/prometheus/prometheus/pkg/labels" "github.com/thanos-io/thanos/pkg/block" "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/compact" "github.com/thanos-io/thanos/pkg/compact/downsample" - "github.com/thanos-io/thanos/pkg/objstore/inmem" + "github.com/thanos-io/thanos/pkg/objstore" "github.com/thanos-io/thanos/pkg/testutil" "github.com/thanos-io/thanos/pkg/testutil/e2eutil" ) @@ -35,7 +36,7 @@ func TestCleanupIndexCacheFolder(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - bkt := inmem.NewBucket() + bkt := objstore.WithNoopInstr(objstore.NewInMemBucket()) // Upload one compaction lvl = 2 block, one compaction lvl = 1. // We generate index cache files only for lvl > 1 blocks. @@ -71,16 +72,16 @@ func TestCleanupIndexCacheFolder(t *testing.T) { reg := prometheus.NewRegistry() expReg := prometheus.NewRegistry() - genIndexExp := prometheus.NewCounter(prometheus.CounterOpts{ + genIndexExp := promauto.With(expReg).NewCounter(prometheus.CounterOpts{ Name: metricIndexGenerateName, Help: metricIndexGenerateHelp, }) - expReg.MustRegister(genIndexExp) - - metaFetcher, err := block.NewMetaFetcher(nil, 32, bkt, "", nil) + metaFetcher, err := block.NewMetaFetcher(nil, 32, bkt, "", nil, nil, nil) testutil.Ok(t, err) - testutil.Ok(t, genMissingIndexCacheFiles(ctx, logger, reg, bkt, metaFetcher, dir)) + metas, _, err := metaFetcher.Fetch(ctx) + testutil.Ok(t, err) + testutil.Ok(t, genMissingIndexCacheFiles(ctx, logger, reg, bkt, metas, dir)) genIndexExp.Inc() testutil.GatherAndCompare(t, expReg, reg, metricIndexGenerateName) @@ -98,7 +99,7 @@ func TestCleanupDownsampleCacheFolder(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - bkt := inmem.NewBucket() + bkt := objstore.WithNoopInstr(objstore.NewInMemBucket()) var id ulid.ULID { id, err = e2eutil.CreateBlock( @@ -117,10 +118,12 @@ func TestCleanupDownsampleCacheFolder(t *testing.T) { metrics := newDownsampleMetrics(prometheus.NewRegistry()) testutil.Equals(t, 0.0, promtest.ToFloat64(metrics.downsamples.WithLabelValues(compact.GroupKey(meta.Thanos)))) - metaFetcher, err := block.NewMetaFetcher(nil, 32, bkt, "", nil) + metaFetcher, err := block.NewMetaFetcher(nil, 32, bkt, "", nil, nil, nil) testutil.Ok(t, err) - testutil.Ok(t, downsampleBucket(ctx, logger, metrics, bkt, metaFetcher, dir)) + metas, _, err := metaFetcher.Fetch(ctx) + testutil.Ok(t, err) + testutil.Ok(t, downsampleBucket(ctx, logger, metrics, bkt, metas, dir)) testutil.Equals(t, 1.0, promtest.ToFloat64(metrics.downsamples.WithLabelValues(compact.GroupKey(meta.Thanos)))) _, err = os.Stat(dir) diff --git a/cmd/thanos/query.go b/cmd/thanos/query.go index f0dfafa7a5..66a23e36d8 100644 --- a/cmd/thanos/query.go +++ b/cmd/thanos/query.go @@ -8,7 +8,7 @@ import ( "fmt" "math" "net/http" - "path" + "strings" "time" "github.com/go-kit/kit/log" @@ -17,6 +17,7 @@ import ( opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/common/route" "github.com/prometheus/prometheus/discovery/file" "github.com/prometheus/prometheus/discovery/targetgroup" @@ -79,6 +80,9 @@ func registerQuery(m map[string]setupFunc, app *kingpin.Application) { rules := cmd.Flag("rule", "Addresses of statically configured rules API servers (repeatable). The scheme may be prefixed with 'dns+' or 'dnssrv+' to detect rule API servers through respective DNS lookups."). PlaceHolder("").Strings() + strictStores := cmd.Flag("store-strict", "Addresses of only statically configured store API servers that are always used, even if the health check fails. Useful if you have a caching layer on top."). + PlaceHolder("").Strings() + fileSDFiles := cmd.Flag("store.sd-files", "Path to files that contain addresses of store API servers. The path can be a glob pattern (repeatable)."). PlaceHolder("").Strings() @@ -163,6 +167,7 @@ func registerQuery(m map[string]setupFunc, app *kingpin.Application) { *dnsSDResolver, time.Duration(*unhealthyStoreTimeout), time.Duration(*instantDefaultMaxSourceResolution), + *strictStores, component.Query, ) } @@ -204,14 +209,14 @@ func runQuery( dnsSDResolver string, unhealthyStoreTimeout time.Duration, instantDefaultMaxSourceResolution time.Duration, + strictStores []string, comp component.Component, ) error { // TODO(bplotka in PR #513 review): Move arguments into struct. - duplicatedStores := prometheus.NewCounter(prometheus.CounterOpts{ + duplicatedStores := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_query_duplicated_store_addresses_total", Help: "The number of times a duplicated store addresses is detected from the different configs in query", }) - reg.MustRegister(duplicatedStores) dialOpts, err := extgrpc.StoreClientGRPCOpts(logger, reg, tracer, secure, cert, key, caCert, serverName) if err != nil { @@ -231,14 +236,24 @@ func runQuery( dns.ResolverType(dnsSDResolver), ) + for _, store := range strictStores { + if dns.IsDynamicNode(store) { + return errors.Errorf("%s is a dynamically specified store i.e. it uses SD and that is not permitted under strict mode. Use --store for this", store) + } + } + var ( stores = query.NewStoreSet( logger, reg, func() (specs []query.StoreSpec) { - // Add DNS resolved addresses from static flags and file SD. + // Add DNS resolved addresses. for _, addr := range dnsStoreProvider.Addresses() { - specs = append(specs, query.NewGRPCStoreSpec(addr)) + specs = append(specs, query.NewGRPCStoreSpec(addr, false)) + } + // Add strict & static nodes. + for _, addr := range strictStores { + specs = append(specs, query.NewGRPCStoreSpec(addr, true)) } specs = removeDuplicateStoreSpecs(logger, duplicatedStores, specs) @@ -247,7 +262,7 @@ func runQuery( }, func() (specs []query.RuleSpec) { for _, addr := range dnsRuleProvider.Addresses() { - specs = append(specs, query.NewGRPCStoreSpec(addr)) + specs = append(specs, query.NewGRPCStoreSpec(addr, false)) } // NOTE(s-urbaniak): No need to remove duplicates, as rule apis are a subset of store apis. @@ -339,32 +354,31 @@ func runQuery( statusProber := prober.Combine( httpProbe, grpcProbe, - prober.NewInstrumentation(comp, logger, reg), + prober.NewInstrumentation(comp, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)), ) // Start query API + UI HTTP server. { router := route.New() + // RoutePrefix must always start with '/'. + webRoutePrefix = "/" + strings.Trim(webRoutePrefix, "/") + // Redirect from / to /webRoutePrefix. - if webRoutePrefix != "" { + if webRoutePrefix != "/" { router.Get("/", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, webRoutePrefix, http.StatusFound) }) - } - - flagsMap := map[string]string{ - // TODO(bplotka in PR #513 review): pass all flags, not only the flags needed by prefix rewriting. - "web.external-prefix": webExternalPrefix, - "web.prefix-header": webPrefixHeaderName, + router = router.WithPrefix(webRoutePrefix) } ins := extpromhttp.NewInstrumentationMiddleware(reg) - ui.NewQueryUI(logger, reg, stores, flagsMap).Register(router.WithPrefix(webRoutePrefix), ins) + // TODO(bplotka in PR #513 review): pass all flags, not only the flags needed by prefix rewriting. + ui.NewQueryUI(logger, reg, stores, webExternalPrefix, webPrefixHeaderName).Register(router, ins) - api := v1.NewAPI(logger, reg, engine, queryableCreator, enableAutodownsampling, enablePartialResponse, queryReplicaLabels, instantDefaultMaxSourceResolution, query.NewRulesRetriever(proxy)) + api := v1.NewAPI(logger, reg, stores, engine, queryableCreator, enableAutodownsampling, enablePartialResponse, queryReplicaLabels, instantDefaultMaxSourceResolution, query.NewRulesRetriever(proxy)) - api.Register(router.WithPrefix(path.Join(webRoutePrefix, "/api/v1")), tracer, logger, ins) + api.Register(router.WithPrefix("/api/v1"), tracer, logger, ins) srv := httpserver.New(logger, reg, comp, httpProbe, httpserver.WithListen(httpBindAddr), diff --git a/cmd/thanos/receive.go b/cmd/thanos/receive.go index 25b11ada64..98638b8bb1 100644 --- a/cmd/thanos/receive.go +++ b/cmd/thanos/receive.go @@ -6,7 +6,9 @@ package main import ( "context" "fmt" + "io/ioutil" "os" + "path" "strings" "time" @@ -20,17 +22,17 @@ import ( "github.com/prometheus/prometheus/storage/tsdb" kingpin "gopkg.in/alecthomas/kingpin.v2" - "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/extflag" "github.com/thanos-io/thanos/pkg/extgrpc" + "github.com/thanos-io/thanos/pkg/extprom" + "github.com/thanos-io/thanos/pkg/objstore" "github.com/thanos-io/thanos/pkg/objstore/client" "github.com/thanos-io/thanos/pkg/prober" "github.com/thanos-io/thanos/pkg/receive" "github.com/thanos-io/thanos/pkg/runutil" grpcserver "github.com/thanos-io/thanos/pkg/server/grpc" httpserver "github.com/thanos-io/thanos/pkg/server/http" - "github.com/thanos-io/thanos/pkg/shipper" "github.com/thanos-io/thanos/pkg/store" "github.com/thanos-io/thanos/pkg/tls" ) @@ -71,6 +73,10 @@ func registerReceive(m map[string]setupFunc, app *kingpin.Application) { tenantHeader := cmd.Flag("receive.tenant-header", "HTTP header to determine tenant for write requests.").Default(receive.DefaultTenantHeader).String() + defaultTenantID := cmd.Flag("receive.default-tenant-id", "Default tenant ID to use when none is provided via a header.").Default(receive.DefaultTenant).String() + + tenantLabelName := cmd.Flag("receive.tenant-label-name", "Label name through which the tenant will be announced.").Default(receive.DefaultTenantLabel).String() + replicaHeader := cmd.Flag("receive.replica-header", "HTTP header specifying the replica number of a write request.").Default(receive.DefaultReplicaHeader).String() replicationFactor := cmd.Flag("receive.replication-factor", "How many times to replicate incoming write requests.").Default("1").Uint64() @@ -143,6 +149,8 @@ func registerReceive(m map[string]setupFunc, app *kingpin.Application) { cw, *local, *tenantHeader, + *defaultTenantID, + *tenantLabelName, *replicaHeader, *replicationFactor, comp, @@ -178,6 +186,8 @@ func runReceive( cw *receive.ConfigWatcher, endpoint string, tenantHeader string, + defaultTenantID string, + tenantLabelName string, replicaHeader string, replicationFactor uint64, comp component.SourceStoreAPI, @@ -185,30 +195,66 @@ func runReceive( logger = log.With(logger, "component", "receive") level.Warn(logger).Log("msg", "setting up receive; the Thanos receive component is EXPERIMENTAL, it may break significantly without notice") - localStorage := &tsdb.ReadyStorage{} rwTLSConfig, err := tls.NewServerConfig(log.With(logger, "protocol", "HTTP"), rwServerCert, rwServerKey, rwServerClientCA) if err != nil { return err } - rwTLSClientConfig, err := tls.NewClientConfig(logger, rwClientCert, rwClientKey, rwClientServerCA, rwClientServerName) + dialOpts, err := extgrpc.StoreClientGRPCOpts(logger, reg, tracer, rwServerCert != "", rwClientCert, rwClientKey, rwClientServerCA, rwClientServerName) if err != nil { return err } - dialOpts, err := extgrpc.StoreClientGRPCOpts(logger, reg, tracer, rwServerCert != "", rwClientCert, rwClientKey, rwClientServerCA, rwClientServerName) + + var bkt objstore.Bucket + confContentYaml, err := objStoreConfig.Content() if err != nil { return err } + upload := len(confContentYaml) > 0 + if upload { + if tsdbOpts.MinBlockDuration != tsdbOpts.MaxBlockDuration { + if !ignoreBlockSize { + return errors.Errorf("found that TSDB Max time is %s and Min time is %s. "+ + "Compaction needs to be disabled (tsdb.min-block-duration = tsdb.max-block-duration)", tsdbOpts.MaxBlockDuration, tsdbOpts.MinBlockDuration) + } + level.Warn(logger).Log("msg", "flag to ignore min/max block duration flags differing is being used. If the upload of a 2h block fails and a tsdb compaction happens that block may be missing from your Thanos bucket storage.") + } + // The background shipper continuously scans the data directory and uploads + // new blocks to object storage service. + bkt, err = client.NewBucket(logger, confContentYaml, reg, comp.String()) + if err != nil { + return err + } + } else { + level.Info(logger).Log("msg", "no supported bucket was configured, uploads will be disabled") + } + // TODO(brancz): remove after a couple of versions + // Migrate non-multi-tsdb capable storage to multi-tsdb disk layout. + if err := migrateLegacyStorage(logger, dataDir, defaultTenantID); err != nil { + return errors.Wrapf(err, "migrate legacy storage in %v to default tenant %v", dataDir, defaultTenantID) + } + + dbs := receive.NewMultiTSDB( + dataDir, + logger, + reg, + tsdbOpts, + lset, + tenantLabelName, + bkt, + ) + writer := receive.NewWriter(log.With(logger, "component", "receive-writer"), dbs) webHandler := receive.NewHandler(log.With(logger, "component", "receive-handler"), &receive.Options{ + Writer: writer, ListenAddress: rwAddress, Registry: reg, Endpoint: endpoint, TenantHeader: tenantHeader, + DefaultTenantID: defaultTenantID, ReplicaHeader: replicaHeader, ReplicationFactor: replicationFactor, Tracer: tracer, TLSConfig: rwTLSConfig, - TLSClientConfig: rwTLSClientConfig, DialOpts: dialOpts, }) @@ -217,27 +263,9 @@ func runReceive( statusProber := prober.Combine( httpProbe, grpcProbe, - prober.NewInstrumentation(comp, logger, prometheus.WrapRegistererWithPrefix("thanos_", reg)), + prober.NewInstrumentation(comp, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)), ) - confContentYaml, err := objStoreConfig.Content() - if err != nil { - return err - } - upload := true - if len(confContentYaml) == 0 { - level.Info(logger).Log("msg", "No supported bucket was configured, uploads will be disabled") - upload = false - } - - if upload && tsdbOpts.MinBlockDuration != tsdbOpts.MaxBlockDuration { - if !ignoreBlockSize { - return errors.Errorf("found that TSDB Max time is %s and Min time is %s. "+ - "Compaction needs to be disabled (tsdb.min-block-duration = tsdb.max-block-duration)", tsdbOpts.MaxBlockDuration, tsdbOpts.MinBlockDuration) - } - level.Warn(logger).Log("msg", "flag to ignore min/max block duration flags differing is being used. If the upload of a 2h block fails and a tsdb compaction happens that block may be missing from your Thanos bucket storage.") - } - // Start all components while we wait for TSDB to open but only load // initial config and mark ourselves as ready after it completed. @@ -254,24 +282,13 @@ func runReceive( { // TSDB. cancel := make(chan struct{}) - startTimeMargin := int64(2 * time.Duration(tsdbOpts.MinBlockDuration).Seconds() * 1000) g.Add(func() error { defer close(dbReady) defer close(uploadC) - // Before actually starting, we need to make sure the - // WAL is flushed. The WAL is flushed after the - // hashring is loaded. - db := receive.NewFlushableStorage( - dataDir, - log.With(logger, "component", "tsdb"), - reg, - tsdbOpts, - ) - // Before quitting, ensure the WAL is flushed and the DB is closed. defer func() { - if err := db.Flush(); err != nil { + if err := dbs.Flush(); err != nil { level.Warn(logger).Log("err", err, "msg", "failed to flush storage") } }() @@ -287,28 +304,24 @@ func runReceive( level.Info(logger).Log("msg", "updating DB") - if err := db.Flush(); err != nil { + if err := dbs.Flush(); err != nil { return errors.Wrap(err, "flushing storage") } - if err := db.Open(); err != nil { + if err := dbs.Open(); err != nil { return errors.Wrap(err, "opening storage") } if upload { uploadC <- struct{}{} <-uploadDone } - level.Info(logger).Log("msg", "tsdb started") - localStorage.Set(db.Get(), startTimeMargin) - webHandler.SetWriter(receive.NewWriter(log.With(logger, "component", "receive-writer"), localStorage)) statusProber.Ready() - level.Info(logger).Log("msg", "server is ready to receive web requests") + level.Info(logger).Log("msg", "tsdb started, and server is ready to receive web requests") dbReady <- struct{}{} } } }, func(err error) { close(cancel) - }, - ) + }) } level.Debug(logger).Log("msg", "setting up hashring") @@ -353,7 +366,6 @@ func runReceive( if !ok { return nil } - webHandler.SetWriter(nil) webHandler.Hashring(h) msg := "hashring has changed; server is not ready to receive web requests." statusProber.NotReady(errors.New(msg)) @@ -401,9 +413,14 @@ func runReceive( if s != nil { s.Shutdown(errors.New("reload hashrings")) } - tsdbStore := store.NewTSDBStore(log.With(logger, "component", "thanos-tsdb-store"), nil, localStorage.Get(), comp, lset) + rw := store.ReadWriteTSDBStore{ - StoreServer: tsdbStore, + StoreServer: store.NewMultiTSDBStore( + logger, + reg, + comp, + dbs.TSDBStores, + ), WriteableStoreServer: webHandler, } @@ -423,6 +440,7 @@ func runReceive( // whenever the DB changes, thus it needs its own run group. g.Add(func() error { for range startGRPC { + level.Info(logger).Log("msg", "listening for StoreAPI and WritableStoreAPI gRPC", "address", grpcBindAddr) if err := s.ListenAndServe(); err != nil { return errors.Wrap(err, "serve gRPC") } @@ -444,18 +462,9 @@ func runReceive( } if upload { - // The background shipper continuously scans the data directory and uploads - // new blocks to Google Cloud Storage or an S3-compatible storage service. - bkt, err := client.NewBucket(logger, confContentYaml, reg, comp.String()) - if err != nil { - return err - } - - s := shipper.New(logger, reg, dataDir, bkt, func() labels.Labels { return lset }, metadata.ReceiveSource) - - // Before starting, ensure any old blocks are uploaded. - if uploaded, err := s.Sync(context.Background()); err != nil { - level.Warn(logger).Log("err", err, "failed to upload", uploaded) + level.Debug(logger).Log("msg", "upload enabled") + if err := dbs.Sync(context.Background()); err != nil { + level.Warn(logger).Log("msg", "initial upload failed", "err", err) } { @@ -463,8 +472,8 @@ func runReceive( ctx, cancel := context.WithCancel(context.Background()) g.Add(func() error { return runutil.Repeat(30*time.Second, ctx.Done(), func() error { - if uploaded, err := s.Sync(ctx); err != nil { - level.Warn(logger).Log("err", err, "uploaded", uploaded) + if err := dbs.Sync(ctx); err != nil { + level.Warn(logger).Log("msg", "interval upload failed", "err", err) } return nil @@ -485,8 +494,8 @@ func runReceive( // Before quitting, ensure all blocks are uploaded. defer func() { <-uploadC - if uploaded, err := s.Sync(context.Background()); err != nil { - level.Warn(logger).Log("err", err, "failed to upload", uploaded) + if err := dbs.Sync(context.Background()); err != nil { + level.Warn(logger).Log("msg", "on demnad upload failed", "err", err) } }() defer close(uploadDone) @@ -500,8 +509,8 @@ func runReceive( case <-ctx.Done(): return nil case <-uploadC: - if uploaded, err := s.Sync(ctx); err != nil { - level.Warn(logger).Log("err", err, "failed to upload", uploaded) + if err := dbs.Sync(ctx); err != nil { + level.Warn(logger).Log("err", err) } uploadDone <- struct{}{} } @@ -515,3 +524,38 @@ func runReceive( level.Info(logger).Log("msg", "starting receiver") return nil } + +func migrateLegacyStorage(logger log.Logger, dataDir, defaultTenantID string) error { + defaultTenantDataDir := path.Join(dataDir, defaultTenantID) + + if _, err := os.Stat(defaultTenantDataDir); !os.IsNotExist(err) { + level.Info(logger).Log("msg", "default tenant data dir already present, not attempting to migrate storage") + return nil + } + + if _, err := os.Stat(dataDir); os.IsNotExist(err) { + level.Info(logger).Log("msg", "no existing storage found, no data migration attempted") + return nil + } + + level.Info(logger).Log("msg", "found legacy storage, migrating to multi-tsdb layout with default tenant", "defaultTenantID", defaultTenantID) + + files, err := ioutil.ReadDir(dataDir) + if err != nil { + return errors.Wrapf(err, "read legacy data dir: %v", dataDir) + } + + if err := os.MkdirAll(defaultTenantDataDir, 0777); err != nil { + return errors.Wrapf(err, "create default tenant data dir: %v", defaultTenantDataDir) + } + + for _, f := range files { + from := path.Join(dataDir, f.Name()) + to := path.Join(defaultTenantDataDir, f.Name()) + if err := os.Rename(from, to); err != nil { + return errors.Wrapf(err, "migrate file from %v to %v", from, to) + } + } + + return nil +} diff --git a/cmd/thanos/rule.go b/cmd/thanos/rule.go index 5ff5c55d39..e39d62402b 100644 --- a/cmd/thanos/rule.go +++ b/cmd/thanos/rule.go @@ -8,7 +8,6 @@ import ( "math/rand" "net/http" "net/url" - "path" "path/filepath" "strconv" "strings" @@ -20,12 +19,14 @@ import ( "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/common/model" "github.com/prometheus/common/route" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/promql" "github.com/prometheus/prometheus/rules" "github.com/prometheus/prometheus/storage/tsdb" + tsdberrors "github.com/prometheus/prometheus/tsdb/errors" "github.com/prometheus/prometheus/util/strutil" "github.com/thanos-io/thanos/pkg/alert" "github.com/thanos-io/thanos/pkg/block/metadata" @@ -200,6 +201,50 @@ func registerRule(m map[string]setupFunc, app *kingpin.Application) { } } +// RuleMetrics defines thanos rule metrics. +type RuleMetrics struct { + configSuccess prometheus.Gauge + configSuccessTime prometheus.Gauge + duplicatedQuery prometheus.Counter + rulesLoaded *prometheus.GaugeVec + ruleEvalWarnings *prometheus.CounterVec +} + +func newRuleMetrics(reg *prometheus.Registry) *RuleMetrics { + m := new(RuleMetrics) + + factory := promauto.With(reg) + m.configSuccess = factory.NewGauge(prometheus.GaugeOpts{ + Name: "thanos_rule_config_last_reload_successful", + Help: "Whether the last configuration reload attempt was successful.", + }) + m.configSuccessTime = factory.NewGauge(prometheus.GaugeOpts{ + Name: "thanos_rule_config_last_reload_success_timestamp_seconds", + Help: "Timestamp of the last successful configuration reload.", + }) + m.duplicatedQuery = factory.NewCounter(prometheus.CounterOpts{ + Name: "thanos_rule_duplicated_query_addresses_total", + Help: "The number of times a duplicated query addresses is detected from the different configs in rule.", + }) + m.rulesLoaded = factory.NewGaugeVec( + prometheus.GaugeOpts{ + Name: "thanos_rule_loaded_rules", + Help: "Loaded rules partitioned by file and group.", + }, + []string{"strategy", "file", "group"}, + ) + m.ruleEvalWarnings = factory.NewCounterVec( + prometheus.CounterOpts{ + Name: "thanos_rule_evaluation_with_warnings_total", + Help: "The total number of rule evaluation that were successful but had warnings which can indicate partial error.", + }, []string{"strategy"}, + ) + m.ruleEvalWarnings.WithLabelValues(strings.ToLower(storepb.PartialResponseStrategy_ABORT.String())) + m.ruleEvalWarnings.WithLabelValues(strings.ToLower(storepb.PartialResponseStrategy_WARN.String())) + + return m +} + // runRule runs a rule evaluation component that continuously evaluates alerting and recording // rules. It sends alert notifications and writes TSDB data for results like a regular Prometheus server. func runRule( @@ -239,52 +284,19 @@ func runRule( dnsSDResolver string, comp component.Component, ) error { - configSuccess := prometheus.NewGauge(prometheus.GaugeOpts{ - Name: "thanos_rule_config_last_reload_successful", - Help: "Whether the last configuration reload attempt was successful.", - }) - configSuccessTime := prometheus.NewGauge(prometheus.GaugeOpts{ - Name: "thanos_rule_config_last_reload_success_timestamp_seconds", - Help: "Timestamp of the last successful configuration reload.", - }) - duplicatedQuery := prometheus.NewCounter(prometheus.CounterOpts{ - Name: "thanos_rule_duplicated_query_addresses_total", - Help: "The number of times a duplicated query addresses is detected from the different configs in rule", - }) - rulesLoaded := prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "thanos_rule_loaded_rules", - Help: "Loaded rules partitioned by file and group", - }, - []string{"strategy", "file", "group"}, - ) - ruleEvalWarnings := prometheus.NewCounterVec( - prometheus.CounterOpts{ - Name: "thanos_rule_evaluation_with_warnings_total", - Help: "The total number of rule evaluation that were successful but had warnings which can indicate partial error.", - }, []string{"strategy"}, - ) - ruleEvalWarnings.WithLabelValues(strings.ToLower(storepb.PartialResponseStrategy_ABORT.String())) - ruleEvalWarnings.WithLabelValues(strings.ToLower(storepb.PartialResponseStrategy_WARN.String())) - - reg.MustRegister(configSuccess) - reg.MustRegister(configSuccessTime) - reg.MustRegister(duplicatedQuery) - reg.MustRegister(rulesLoaded) - reg.MustRegister(ruleEvalWarnings) + metrics := newRuleMetrics(reg) var queryCfg []query.Config + var err error if len(queryConfigYAML) > 0 { - var err error queryCfg, err = query.LoadConfigs(queryConfigYAML) if err != nil { return err } } else { - for _, addr := range queryAddrs { - if addr == "" { - return errors.New("static querier address cannot be empty") - } + queryCfg, err = query.BuildQueryConfig(queryAddrs) + if err != nil { + return err } // Build the query configuration from the legacy query flags. @@ -294,16 +306,15 @@ func runRule( Files: querySDFiles, RefreshInterval: model.Duration(querySDInterval), }) - } - queryCfg = append(queryCfg, - query.Config{ - EndpointsConfig: http_util.EndpointsConfig{ - Scheme: "http", - StaticAddresses: queryAddrs, - FileSDConfigs: fileSDConfigs, + queryCfg = append(queryCfg, + query.Config{ + EndpointsConfig: http_util.EndpointsConfig{ + Scheme: "http", + FileSDConfigs: fileSDConfigs, + }, }, - }, - ) + ) + } } queryProvider := dns.NewProvider( @@ -435,7 +446,7 @@ func runRule( opts := opts opts.Registerer = extprom.WrapRegistererWith(prometheus.Labels{"strategy": strings.ToLower(s.String())}, reg) opts.Context = ctx - opts.QueryFunc = queryFunc(logger, queryClients, duplicatedQuery, ruleEvalWarnings, s) + opts.QueryFunc = queryFunc(logger, queryClients, metrics.duplicatedQuery, metrics.ruleEvalWarnings, s) mgr := rules.NewManager(&opts) ruleMgr.SetRuleManager(s, mgr) @@ -458,7 +469,9 @@ func runRule( g.Add(func() error { for { - sdr.Send(ctx, alertQ.Pop(ctx.Done())) + tracing.DoInSpan(ctx, "/send_alerts", func(ctx context.Context) { + sdr.Send(ctx, alertQ.Pop(ctx.Done())) + }) select { case <-ctx.Done(): @@ -472,52 +485,33 @@ func runRule( } // Handle reload and termination interrupts. - reload := make(chan struct{}, 1) + reloadWebhandler := make(chan chan error) { - cancel := make(chan struct{}) - reload <- struct{}{} // Initial reload. - + ctx, cancel := context.WithCancel(context.Background()) g.Add(func() error { + // Initialize rules. + if err := reloadRules(logger, ruleFiles, ruleMgr, evalInterval, metrics); err != nil { + level.Error(logger).Log("msg", "initialize rules failed", "err", err) + return err + } for { select { - case <-cancel: - return errors.New("canceled") - case <-reload: case <-reloadSignal: - } - - level.Debug(logger).Log("msg", "configured rule files", "files", strings.Join(ruleFiles, ",")) - var files []string - for _, pat := range ruleFiles { - fs, err := filepath.Glob(pat) + if err := reloadRules(logger, ruleFiles, ruleMgr, evalInterval, metrics); err != nil { + level.Error(logger).Log("msg", "reload rules by sighup failed", "err", err) + } + case reloadMsg := <-reloadWebhandler: + err := reloadRules(logger, ruleFiles, ruleMgr, evalInterval, metrics) if err != nil { - // The only error can be a bad pattern. - level.Error(logger).Log("msg", "retrieving rule files failed. Ignoring file.", "pattern", pat, "err", err) - continue + level.Error(logger).Log("msg", "reload rules by webhandler failed", "err", err) } - - files = append(files, fs...) - } - - level.Info(logger).Log("msg", "reload rule files", "numFiles", len(files)) - - if err := ruleMgr.Update(evalInterval, files); err != nil { - configSuccess.Set(0) - level.Error(logger).Log("msg", "reloading rules failed", "err", err) - continue - } - - configSuccess.Set(1) - configSuccessTime.SetToCurrentTime() - - rulesLoaded.Reset() - for _, group := range ruleMgr.RuleGroups() { - rulesLoaded.WithLabelValues(group.PartialResponseStrategy.String(), group.File(), group.Name()).Set(float64(len(group.Rules()))) + reloadMsg <- err + case <-ctx.Done(): + return ctx.Err() } - } }, func(error) { - close(cancel) + cancel() }) } @@ -526,7 +520,7 @@ func runRule( statusProber := prober.Combine( httpProbe, grpcProbe, - prober.NewInstrumentation(comp, logger, prometheus.WrapRegistererWithPrefix("thanos_", reg)), + prober.NewInstrumentation(comp, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)), ) // Start gRPC server. @@ -557,29 +551,32 @@ func runRule( { router := route.New() + // RoutePrefix must always start with '/'. + webRoutePrefix = "/" + strings.Trim(webRoutePrefix, "/") + // Redirect from / to /webRoutePrefix. - if webRoutePrefix != "" { + if webRoutePrefix != "/" { router.Get("/", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, webRoutePrefix, http.StatusFound) }) + router = router.WithPrefix(webRoutePrefix) } - router.WithPrefix(webRoutePrefix).Post("/-/reload", func(w http.ResponseWriter, r *http.Request) { - reload <- struct{}{} + router.Post("/-/reload", func(w http.ResponseWriter, r *http.Request) { + reloadMsg := make(chan error) + reloadWebhandler <- reloadMsg + if err := <-reloadMsg; err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } }) - flagsMap := map[string]string{ - // TODO(bplotka in PR #513 review): pass all flags, not only the flags needed by prefix rewriting. - "web.external-prefix": webExternalPrefix, - "web.prefix-header": webPrefixHeaderName, - } - ins := extpromhttp.NewInstrumentationMiddleware(reg) - ui.NewRuleUI(logger, reg, ruleMgr, alertQueryURL.String(), flagsMap).Register(router.WithPrefix(webRoutePrefix), ins) + // TODO(bplotka in PR #513 review): pass all flags, not only the flags needed by prefix rewriting. + ui.NewRuleUI(logger, reg, ruleMgr, alertQueryURL.String(), webExternalPrefix, webPrefixHeaderName).Register(router, ins) api := v1.NewAPI(logger, reg, ruleMgr) - api.Register(router.WithPrefix(path.Join(webRoutePrefix, "/api/v1")), tracer, logger, ins) + api.Register(router.WithPrefix("/api/v1"), tracer, logger, ins) srv := httpserver.New(logger, reg, comp, httpProbe, httpserver.WithListen(httpBindAddr), @@ -713,18 +710,18 @@ func queryFunc( promClients = append(promClients, promclient.NewClient(q, logger, "thanos-rule")) } - return func(ctx context.Context, q string, t time.Time) (promql.Vector, error) { + return func(ctx context.Context, q string, t time.Time) (v promql.Vector, err error) { for _, i := range rand.Perm(len(queriers)) { promClient := promClients[i] endpoints := removeDuplicateQueryEndpoints(logger, duplicatedQuery, queriers[i].Endpoints()) for _, i := range rand.Perm(len(endpoints)) { - span, ctx := tracing.StartSpan(ctx, spanID) - v, warns, err := promClient.PromqlQueryInstant(ctx, endpoints[i], q, t, promclient.QueryOptions{ - Deduplicate: true, - PartialResponseStrategy: partialResponseStrategy, + var warns []string + tracing.DoInSpan(ctx, spanID, func(ctx context.Context) { + v, warns, err = promClient.PromqlQueryInstant(ctx, endpoints[i], q, t, promclient.QueryOptions{ + Deduplicate: true, + PartialResponseStrategy: partialResponseStrategy, + }) }) - span.Finish() - if err != nil { level.Error(logger).Log("err", err, "query", q) continue @@ -737,7 +734,7 @@ func queryFunc( return v, nil } } - return nil, errors.Errorf("no query API server reachable") + return nil, errors.New("no query API server reachable") } } @@ -759,3 +756,49 @@ func addDiscoveryGroups(g *run.Group, c *http_util.Client, interval time.Duratio cancel() }) } + +func reloadRules(logger log.Logger, + ruleFiles []string, + ruleMgr *thanosrule.Manager, + evalInterval time.Duration, + metrics *RuleMetrics) error { + level.Debug(logger).Log("msg", "configured rule files", "files", strings.Join(ruleFiles, ",")) + var ( + errs tsdberrors.MultiError + files []string + seenFiles = make(map[string]struct{}) + ) + for _, pat := range ruleFiles { + fs, err := filepath.Glob(pat) + if err != nil { + // The only error can be a bad pattern. + errs.Add(errors.Wrapf(err, "retrieving rule files failed. Ignoring file. pattern %s", pat)) + continue + } + + for _, fp := range fs { + if _, ok := seenFiles[fp]; ok { + continue + } + files = append(files, fp) + seenFiles[fp] = struct{}{} + } + } + + level.Info(logger).Log("msg", "reload rule files", "numFiles", len(files)) + + if err := ruleMgr.Update(evalInterval, files); err != nil { + metrics.configSuccess.Set(0) + errs.Add(errors.Wrap(err, "reloading rules failed")) + return errs.Err() + } + + metrics.configSuccess.Set(1) + metrics.configSuccessTime.Set(float64(time.Now().UnixNano()) / 1e9) + + metrics.rulesLoaded.Reset() + for _, group := range ruleMgr.RuleGroups() { + metrics.rulesLoaded.WithLabelValues(group.PartialResponseStrategy.String(), group.File(), group.Name()).Set(float64(len(group.Rules()))) + } + return errs.Err() +} diff --git a/cmd/thanos/sidecar.go b/cmd/thanos/sidecar.go index e612dc1332..19bb81cd21 100644 --- a/cmd/thanos/sidecar.go +++ b/cmd/thanos/sidecar.go @@ -17,12 +17,14 @@ import ( "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/pkg/labels" "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/extflag" "github.com/thanos-io/thanos/pkg/exthttp" + "github.com/thanos-io/thanos/pkg/extprom" thanosmodel "github.com/thanos-io/thanos/pkg/model" "github.com/thanos-io/thanos/pkg/objstore/client" "github.com/thanos-io/thanos/pkg/prober" @@ -42,46 +44,17 @@ import ( func registerSidecar(m map[string]setupFunc, app *kingpin.Application) { cmd := app.Command(component.Sidecar.String(), "sidecar for Prometheus server") - - httpBindAddr, httpGracePeriod := regHTTPFlags(cmd) - grpcBindAddr, grpcGracePeriod, grpcCert, grpcKey, grpcClientCA := regGRPCFlags(cmd) - - promURL := cmd.Flag("prometheus.url", "URL at which to reach Prometheus's API. For better performance use local network."). - Default("http://localhost:9090").URL() - - promReadyTimeout := cmd.Flag("prometheus.ready_timeout", "Maximum time to wait for the Prometheus instance to start up"). - Default("10m").Duration() - - connectionPoolSize := cmd.Flag("receive.connection-pool-size", "Controls the http MaxIdleConns. Default is 0, which is unlimited").Int() - connectionPoolSizePerHost := cmd.Flag("receive.connection-pool-size-per-host", "Controls the http MaxIdleConnsPerHost").Default("100").Int() - - dataDir := cmd.Flag("tsdb.path", "Data directory of TSDB."). - Default("./data").String() - - reloaderCfgFile := cmd.Flag("reloader.config-file", "Config file watched by the reloader."). - Default("").String() - - reloaderCfgOutputFile := cmd.Flag("reloader.config-envsubst-file", "Output file for environment variable substituted config file."). - Default("").String() - - reloaderRuleDirs := cmd.Flag("reloader.rule-dir", "Rule directories for the reloader to refresh (repeated field).").Strings() - - objStoreConfig := regCommonObjStoreFlags(cmd, "", false) - - uploadCompacted := cmd.Flag("shipper.upload-compacted", "If true sidecar will try to upload compacted blocks as well. Useful for migration purposes. Works only if compaction is disabled on Prometheus. Do it once and then disable the flag when done.").Default("false").Bool() - - ignoreBlockSize := cmd.Flag("shipper.ignore-unequal-block-size", "If true sidecar will not require prometheus min and max block size flags to be set to the same value. Only use this if you want to keep long retention and compaction enabled on your Prometheus instance, as in the worst case it can result in ~2h data loss for your Thanos bucket storage.").Default("false").Hidden().Bool() - - minTime := thanosmodel.TimeOrDuration(cmd.Flag("min-time", "Start of time range limit to serve. Thanos sidecar will serve only metrics, which happened later than this value. Option can be a constant time in RFC3339 format or time duration relative to current time, such as -1d or 2h45m. Valid duration units are ms, s, m, h, d, w, y."). - Default("0000-01-01T00:00:00Z")) + conf := &sidecarConfig{} + conf.registerFlag(cmd) m[component.Sidecar.String()] = func(g *run.Group, logger log.Logger, reg *prometheus.Registry, tracer opentracing.Tracer, _ <-chan struct{}, _ bool) error { rl := reloader.New( log.With(logger, "component", "reloader"), - reloader.ReloadURLFromBase(*promURL), - *reloaderCfgFile, - *reloaderCfgOutputFile, - *reloaderRuleDirs, + extprom.WrapRegistererWithPrefix("thanos_sidecar_", reg), + reloader.ReloadURLFromBase(conf.prometheus.url), + conf.reloader.confFile, + conf.reloader.envVarConfFile, + conf.reloader.ruleDirectories, ) return runSidecar( @@ -89,24 +62,9 @@ func registerSidecar(m map[string]setupFunc, app *kingpin.Application) { logger, reg, tracer, - *grpcBindAddr, - time.Duration(*grpcGracePeriod), - *grpcCert, - *grpcKey, - *grpcClientCA, - *httpBindAddr, - time.Duration(*httpGracePeriod), - *promURL, - *promReadyTimeout, - *dataDir, - objStoreConfig, rl, - *uploadCompacted, - *ignoreBlockSize, component.Sidecar, - *minTime, - *connectionPoolSize, - *connectionPoolSizePerHost, + *conf, ) } } @@ -116,38 +74,23 @@ func runSidecar( logger log.Logger, reg *prometheus.Registry, tracer opentracing.Tracer, - grpcBindAddr string, - grpcGracePeriod time.Duration, - grpcCert string, - grpcKey string, - grpcClientCA string, - httpBindAddr string, - httpGracePeriod time.Duration, - promURL *url.URL, - promReadyTimeout time.Duration, - dataDir string, - objStoreConfig *extflag.PathOrContent, reloader *reloader.Reloader, - uploadCompacted bool, - ignoreBlockSize bool, comp component.Component, - limitMinTime thanosmodel.TimeOrDurationValue, - connectionPoolSize int, - connectionPoolSizePerHost int, + conf sidecarConfig, ) error { var m = &promMetadata{ - promURL: promURL, + promURL: conf.prometheus.url, // Start out with the full time range. The shipper will constrain it later. // TODO(fabxc): minimum timestamp is never adjusted if shipping is disabled. - mint: limitMinTime.PrometheusTimestamp(), + mint: conf.limitMinTime.PrometheusTimestamp(), maxt: math.MaxInt64, - limitMinTime: limitMinTime, + limitMinTime: conf.limitMinTime, client: promclient.NewWithTracingClient(logger, "thanos-sidecar"), } - confContentYaml, err := objStoreConfig.Content() + confContentYaml, err := conf.objStore.Content() if err != nil { return errors.Wrap(err, "getting object store config") } @@ -163,12 +106,12 @@ func runSidecar( statusProber := prober.Combine( httpProbe, grpcProbe, - prober.NewInstrumentation(comp, logger, prometheus.WrapRegistererWithPrefix("thanos_", reg)), + prober.NewInstrumentation(comp, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)), ) srv := httpserver.New(logger, reg, comp, httpProbe, - httpserver.WithListen(httpBindAddr), - httpserver.WithGracePeriod(httpGracePeriod), + httpserver.WithListen(conf.http.bindAddress), + httpserver.WithGracePeriod(time.Duration(conf.http.gracePeriod)), ) g.Add(func() error { @@ -184,22 +127,21 @@ func runSidecar( // Setup all the concurrent groups. { - promUp := prometheus.NewGauge(prometheus.GaugeOpts{ + promUp := promauto.With(reg).NewGauge(prometheus.GaugeOpts{ Name: "thanos_sidecar_prometheus_up", Help: "Boolean indicator whether the sidecar can reach its Prometheus peer.", }) - lastHeartbeat := prometheus.NewGauge(prometheus.GaugeOpts{ + lastHeartbeat := promauto.With(reg).NewGauge(prometheus.GaugeOpts{ Name: "thanos_sidecar_last_heartbeat_success_time_seconds", Help: "Second timestamp of the last successful heartbeat.", }) - reg.MustRegister(promUp, lastHeartbeat) ctx, cancel := context.WithCancel(context.Background()) g.Add(func() error { // Only check Prometheus's flags when upload is enabled. if uploads { // Check prometheus's flags to ensure sane sidecar flags. - if err := validatePrometheus(ctx, m.client, logger, ignoreBlockSize, m); err != nil { + if err := validatePrometheus(ctx, m.client, logger, conf.shipper.ignoreBlockSize, m); err != nil { return errors.Wrap(err, "validate Prometheus flags") } } @@ -265,23 +207,24 @@ func runSidecar( { t := exthttp.NewTransport() - t.MaxIdleConnsPerHost = connectionPoolSizePerHost - t.MaxIdleConns = connectionPoolSize + t.MaxIdleConnsPerHost = conf.connection.maxIdleConnsPerHost + t.MaxIdleConns = conf.connection.maxIdleConns c := &http.Client{Transport: tracing.HTTPTripperware(logger, t)} - promStore, err := store.NewPrometheusStore(logger, c, promURL, component.Sidecar, m.Labels, m.Timestamps) + promStore, err := store.NewPrometheusStore(logger, c, conf.prometheus.url, component.Sidecar, m.Labels, m.Timestamps) if err != nil { return errors.Wrap(err, "create Prometheus store") } - tlsCfg, err := tls.NewServerConfig(log.With(logger, "protocol", "gRPC"), grpcCert, grpcKey, grpcClientCA) + tlsCfg, err := tls.NewServerConfig(log.With(logger, "protocol", "gRPC"), + conf.grpc.tlsSrvCert, conf.grpc.tlsSrvKey, conf.grpc.tlsSrvClientCA) if err != nil { return errors.Wrap(err, "setup gRPC server") } s := grpcserver.New(logger, reg, tracer, comp, grpcProbe, promStore, promStore, - grpcserver.WithListen(grpcBindAddr), - grpcserver.WithGracePeriod(grpcGracePeriod), + grpcserver.WithListen(conf.grpc.bindAddress), + grpcserver.WithGracePeriod(time.Duration(conf.grpc.gracePeriod)), grpcserver.WithTLSConfig(tlsCfg), ) g.Add(func() error { @@ -308,7 +251,7 @@ func runSidecar( } }() - if err := promclient.IsWALDirAccessible(dataDir); err != nil { + if err := promclient.IsWALDirAccessible(conf.tsdb.path); err != nil { level.Error(logger).Log("err", err) } @@ -316,6 +259,7 @@ func runSidecar( g.Add(func() error { defer runutil.CloseWithLogOnErr(logger, bkt, "bucket client") + promReadyTimeout := conf.prometheus.readyTimeout extLabelsCtx, cancel := context.WithTimeout(ctx, promReadyTimeout) defer cancel() @@ -329,10 +273,10 @@ func runSidecar( } var s *shipper.Shipper - if uploadCompacted { - s = shipper.NewWithCompacted(logger, reg, dataDir, bkt, m.Labels, metadata.SidecarSource) + if conf.shipper.uploadCompacted { + s = shipper.NewWithCompacted(logger, reg, conf.tsdb.path, bkt, m.Labels, metadata.SidecarSource) } else { - s = shipper.New(logger, reg, dataDir, bkt, m.Labels, metadata.SidecarSource) + s = shipper.New(logger, reg, conf.tsdb.path, bkt, m.Labels, metadata.SidecarSource) } return runutil.Repeat(30*time.Second, ctx.Done(), func() error { @@ -459,3 +403,29 @@ func (s *promMetadata) Timestamps() (mint int64, maxt int64) { return s.mint, s.maxt } + +type sidecarConfig struct { + http httpConfig + grpc grpcConfig + prometheus prometheusConfig + connection connConfig + tsdb tsdbConfig + reloader reloaderConfig + objStore extflag.PathOrContent + shipper shipperConfig + limitMinTime thanosmodel.TimeOrDurationValue +} + +func (sc *sidecarConfig) registerFlag(cmd *kingpin.CmdClause) *sidecarConfig { + sc.http.registerFlag(cmd) + sc.grpc.registerFlag(cmd) + sc.prometheus.registerFlag(cmd) + sc.connection.registerFlag(cmd) + sc.tsdb.registerFlag(cmd) + sc.reloader.registerFlag(cmd) + sc.objStore = *regCommonObjStoreFlags(cmd, "", false) + sc.shipper.registerFlag(cmd) + cmd.Flag("min-time", "Start of time range limit to serve. Thanos sidecar will serve only metrics, which happened later than this value. Option can be a constant time in RFC3339 format or time duration relative to current time, such as -1d or 2h45m. Valid duration units are ms, s, m, h, d, w, y."). + Default("0000-01-01T00:00:00Z").SetValue(&sc.limitMinTime) + return sc +} diff --git a/cmd/thanos/store.go b/cmd/thanos/store.go index b0191abba2..7536681119 100644 --- a/cmd/thanos/store.go +++ b/cmd/thanos/store.go @@ -5,6 +5,8 @@ package main import ( "context" + "fmt" + "path" "time" "github.com/go-kit/kit/log" @@ -13,11 +15,13 @@ import ( "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/route" "github.com/prometheus/prometheus/pkg/relabel" "github.com/thanos-io/thanos/pkg/block" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/extflag" "github.com/thanos-io/thanos/pkg/extprom" + extpromhttp "github.com/thanos-io/thanos/pkg/extprom/http" "github.com/thanos-io/thanos/pkg/model" "github.com/thanos-io/thanos/pkg/objstore/client" "github.com/thanos-io/thanos/pkg/prober" @@ -27,6 +31,7 @@ import ( "github.com/thanos-io/thanos/pkg/store" storecache "github.com/thanos-io/thanos/pkg/store/cache" "github.com/thanos-io/thanos/pkg/tls" + "github.com/thanos-io/thanos/pkg/ui" "gopkg.in/alecthomas/kingpin.v2" yaml "gopkg.in/yaml.v2" ) @@ -40,7 +45,7 @@ func registerStore(m map[string]setupFunc, app *kingpin.Application) { httpBindAddr, httpGracePeriod := regHTTPFlags(cmd) grpcBindAddr, grpcGracePeriod, grpcCert, grpcKey, grpcClientCA := regGRPCFlags(cmd) - dataDir := cmd.Flag("data-dir", "Data directory in which to cache remote blocks."). + dataDir := cmd.Flag("data-dir", "Local data directory used for caching purposes (index-header, in-mem cache items and meta.jsons). If removed, no data will be lost, just store will have to rebuild the cache. NOTE: Putting raw blocks here will not cause the store to read them. For such use cases use Prometheus + sidecar."). Default("./data").String() indexCacheSize := cmd.Flag("index-cache-size", "Maximum size of items held in the in-memory index cache. Ignored if --index-cache.config or --index-cache.config-file option is specified."). @@ -50,6 +55,10 @@ func registerStore(m map[string]setupFunc, app *kingpin.Application) { "YAML file that contains index cache configuration. See format details: https://thanos.io/components/store.md/#index-cache", false) + cachingBucketConfig := extflag.RegisterPathOrContent(extflag.HiddenCmdClause(cmd), "store.caching-bucket.config", + "YAML that contains configuration for caching bucket. Experimental feature, with high risk of changes. See format details: https://thanos.io/components/store.md/#caching-bucket", + false) + chunkPoolSize := cmd.Flag("chunk-pool-size", "Maximum size of concurrently allocatable bytes reserved strictly to reuse for chunks in memory."). Default("2GB").Bytes() @@ -78,12 +87,31 @@ func registerStore(m map[string]setupFunc, app *kingpin.Application) { selectorRelabelConf := regSelectorRelabelFlags(cmd) - enableIndexHeader := cmd.Flag("experimental.enable-index-header", "If true, Store Gateway will recreate index-header instead of index-cache.json for each block. This will replace index-cache.json permanently once it will be out of experimental stage."). + // TODO(bwplotka): Remove in v0.13.0 if no issues. + disableIndexHeader := cmd.Flag("store.disable-index-header", "If specified, Store Gateway will use index-cache.json for each block instead of recreating binary index-header"). + Hidden().Default("false").Bool() + + postingOffsetsInMemSampling := cmd.Flag("store.index-header-posting-offsets-in-mem-sampling", "Controls what is the ratio of postings offsets store will hold in memory. "+ + "Larger value will keep less offsets, which will increase CPU cycles needed for query touching those postings. It's meant for setups that want low baseline memory pressure and where less traffic is expected. "+ + "On the contrary, smaller value will increase baseline memory usage, but improve latency slightly. 1 will keep all in memory. Default value is the same as in Prometheus which gives a good balance. This works only when --store.disable-index-header is NOT specified."). + Hidden().Default(fmt.Sprintf("%v", store.DefaultPostingOffsetInMemorySampling)).Int() + + enablePostingsCompression := cmd.Flag("experimental.enable-index-cache-postings-compression", "If true, Store Gateway will reencode and compress postings before storing them into cache. Compressed postings take about 10% of the original size."). Hidden().Default("false").Bool() consistencyDelay := modelDuration(cmd.Flag("consistency-delay", "Minimum age of all blocks before they are being read. Set it to safe value (e.g 30m) if your object storage is eventually consistent. GCS and S3 are (roughly) strongly consistent."). Default("0s")) + ignoreDeletionMarksDelay := modelDuration(cmd.Flag("ignore-deletion-marks-delay", "Duration after which the blocks marked for deletion will be filtered out while fetching blocks. "+ + "The idea of ignore-deletion-marks-delay is to ignore blocks that are marked for deletion with some delay. This ensures store can still serve blocks that are meant to be deleted but do not have a replacement yet. "+ + "If delete-delay duration is provided to compactor or bucket verify component, it will upload deletion-mark.json file to mark after what duration the block should be deleted rather than deleting the block straight away. "+ + "If delete-delay is non-zero for compactor or bucket verify component, ignore-deletion-marks-delay should be set to (delete-delay)/2 so that blocks marked for deletion are filtered out while fetching blocks before being deleted from bucket. "+ + "Default is 24h, half of the default value for --delete-delay on compactor."). + Default("24h")) + + webExternalPrefix := cmd.Flag("web.external-prefix", "Static prefix for all HTML links and redirect URLs in the bucket web UI interface. Actual endpoints are still served on / or the web.route-prefix. This allows thanos bucket web UI to be served behind a reverse proxy that strips a URL sub-path.").Default("").String() + webPrefixHeaderName := cmd.Flag("web.prefix-header", "Name of HTTP request header used for dynamic prefixing of UI links and redirects. This option is ignored if web.external-prefix argument is set. Security risk: enable this option only if a reverse proxy in front of thanos is resetting the header. The --web.prefix-header=X-Forwarded-Prefix option can be useful, for example, if Thanos UI is served via Traefik reverse proxy with PathPrefixStrip option enabled, which sends the stripped prefix value in X-Forwarded-Prefix header. This allows thanos UI to be served on a sub-path.").Default("").String() + m[component.Store.String()] = func(g *run.Group, logger log.Logger, reg *prometheus.Registry, tracer opentracing.Tracer, _ <-chan struct{}, debugLogging bool) error { if minTime.PrometheusTimestamp() > maxTime.PrometheusTimestamp() { return errors.Errorf("invalid argument: --min-time '%s' can't be greater than --max-time '%s'", @@ -107,7 +135,7 @@ func registerStore(m map[string]setupFunc, app *kingpin.Application) { uint64(*indexCacheSize), uint64(*chunkPoolSize), uint64(*maxSampleCount), - int(*maxConcurrent), + *maxConcurrent, component.Store, debugLogging, *syncInterval, @@ -118,8 +146,14 @@ func registerStore(m map[string]setupFunc, app *kingpin.Application) { }, selectorRelabelConf, *advertiseCompatibilityLabel, - *enableIndexHeader, + *disableIndexHeader, + *enablePostingsCompression, time.Duration(*consistencyDelay), + time.Duration(*ignoreDeletionMarksDelay), + *webExternalPrefix, + *webPrefixHeaderName, + *postingOffsetsInMemSampling, + cachingBucketConfig, ) } } @@ -135,14 +169,9 @@ func runStore( dataDir string, grpcBindAddr string, grpcGracePeriod time.Duration, - grpcCert string, - grpcKey string, - grpcClientCA string, - httpBindAddr string, + grpcCert, grpcKey, grpcClientCA, httpBindAddr string, httpGracePeriod time.Duration, - indexCacheSizeBytes uint64, - chunkPoolSizeBytes uint64, - maxSampleCount uint64, + indexCacheSizeBytes, chunkPoolSizeBytes, maxSampleCount uint64, maxConcurrency int, component component.Component, verbose bool, @@ -150,16 +179,19 @@ func runStore( blockSyncConcurrency int, filterConf *store.FilterConfig, selectorRelabelConf *extflag.PathOrContent, - advertiseCompatibilityLabel bool, - enableIndexHeader bool, + advertiseCompatibilityLabel, disableIndexHeader, enablePostingsCompression bool, consistencyDelay time.Duration, + ignoreDeletionMarksDelay time.Duration, + externalPrefix, prefixHeader string, + postingOffsetsInMemSampling int, + cachingBucketConfig *extflag.PathOrContent, ) error { grpcProbe := prober.NewGRPC() httpProbe := prober.NewHTTP() statusProber := prober.Combine( httpProbe, grpcProbe, - prober.NewInstrumentation(component, logger, prometheus.WrapRegistererWithPrefix("thanos_", reg)), + prober.NewInstrumentation(component, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)), ) srv := httpserver.New(logger, reg, component, httpProbe, @@ -188,6 +220,17 @@ func runStore( return errors.Wrap(err, "create bucket client") } + cachingBucketConfigYaml, err := cachingBucketConfig.Content() + if err != nil { + return errors.Wrap(err, "get caching bucket configuration") + } + if len(cachingBucketConfigYaml) > 0 { + bkt, err = storecache.NewCachingBucketFromYaml(cachingBucketConfigYaml, bkt, logger, reg) + if err != nil { + return errors.Wrap(err, "create caching bucket") + } + } + relabelContentYaml, err := selectorRelabelConf.Content() if err != nil { return errors.Wrap(err, "get content of relabel configuration") @@ -217,7 +260,7 @@ func runStore( indexCache, err = storecache.NewIndexCache(logger, indexCacheContentYaml, reg) } else { indexCache, err = storecache.NewInMemoryIndexCacheWithConfig(logger, reg, storecache.InMemoryIndexCacheConfig{ - MaxSize: storecache.Bytes(indexCacheSizeBytes), + MaxSize: model.Bytes(indexCacheSizeBytes), MaxItemSize: storecache.DefaultInMemoryIndexCacheConfig.MaxItemSize, }) } @@ -225,18 +268,20 @@ func runStore( return errors.Wrap(err, "create index cache") } - prometheusRegisterer := extprom.WrapRegistererWithPrefix("thanos_", reg) - metaFetcher, err := block.NewMetaFetcher(logger, fetcherConcurrency, bkt, dataDir, prometheusRegisterer, - block.NewTimePartitionMetaFilter(filterConf.MinTime, filterConf.MaxTime).Filter, - block.NewLabelShardedMetaFilter(relabelConfig).Filter, - block.NewConsistencyDelayMetaFilter(logger, consistencyDelay, prometheusRegisterer).Filter, - block.NewDeduplicateFilter().Filter, - ) + ignoreDeletionMarkFilter := block.NewIgnoreDeletionMarkFilter(logger, bkt, ignoreDeletionMarksDelay) + metaFetcher, err := block.NewMetaFetcher(logger, fetcherConcurrency, bkt, dataDir, extprom.WrapRegistererWithPrefix("thanos_", reg), + []block.MetadataFilter{ + block.NewTimePartitionMetaFilter(filterConf.MinTime, filterConf.MaxTime), + block.NewLabelShardedMetaFilter(relabelConfig), + block.NewConsistencyDelayMetaFilter(logger, consistencyDelay, extprom.WrapRegistererWithPrefix("thanos_", reg)), + ignoreDeletionMarkFilter, + block.NewDeduplicateFilter(), + }, nil) if err != nil { return errors.Wrap(err, "meta fetcher") } - if enableIndexHeader { + if !disableIndexHeader { level.Info(logger).Log("msg", "index-header instead of index-cache.json enabled") } bs, err := store.NewBucketStore( @@ -253,7 +298,10 @@ func runStore( blockSyncConcurrency, filterConf, advertiseCompatibilityLabel, - enableIndexHeader, + !disableIndexHeader, + enablePostingsCompression, + postingOffsetsInMemSampling, + false, ) if err != nil { return errors.Wrap(err, "create object storage store") @@ -310,6 +358,14 @@ func runStore( s.Shutdown(err) }) } + // Add bucket UI for loaded blocks. + { + r := route.New() + compactorView := ui.NewBucketUI(logger, "", path.Join(externalPrefix, "/loaded"), prefixHeader) + compactorView.Register(r, extpromhttp.NewInstrumentationMiddleware(reg)) + metaFetcher.UpdateOnChange(compactorView.Set) + srv.Handle("/", r) + } level.Info(logger).Log("msg", "starting store node") return nil diff --git a/cmd/thanos/check.go b/cmd/thanos/tools.go similarity index 81% rename from cmd/thanos/check.go rename to cmd/thanos/tools.go index ae0d43fa27..192b625744 100644 --- a/cmd/thanos/check.go +++ b/cmd/thanos/tools.go @@ -17,19 +17,18 @@ import ( "gopkg.in/yaml.v2" ) -func registerChecks(m map[string]setupFunc, app *kingpin.Application, name string) { - cmd := app.Command(name, "Linting tools for Thanos") - registerCheckRules(m, cmd, name) +func registerTools(m map[string]setupFunc, app *kingpin.Application) { + cmd := app.Command("tools", "Tools utility commands") + + registerBucket(m, cmd, "tools") + registerCheckRules(m, cmd, "tools") } -func registerCheckRules(m map[string]setupFunc, root *kingpin.CmdClause, name string) { - checkRulesCmd := root.Command("rules", "Check if the rule files are valid or not.") - ruleFiles := checkRulesCmd.Arg( - "rule-files", - "The rule files to check.", - ).Required().ExistingFiles() +func registerCheckRules(m map[string]setupFunc, app *kingpin.CmdClause, pre string) { + checkRulesCmd := app.Command("rules-check", "Check if the rule files are valid or not.") + ruleFiles := checkRulesCmd.Flag("rules", "The rule files glob to check (repeated).").Required().ExistingFiles() - m[name+" rules"] = func(g *run.Group, logger log.Logger, reg *prometheus.Registry, _ opentracing.Tracer, _ <-chan struct{}, _ bool) error { + m[pre+" rules-check"] = func(g *run.Group, logger log.Logger, reg *prometheus.Registry, _ opentracing.Tracer, _ <-chan struct{}, _ bool) error { // Dummy actor to immediately kill the group after the run function returns. g.Add(func() error { return nil }, func(error) {}) return checkRulesFiles(logger, ruleFiles) diff --git a/cmd/thanos/bucket.go b/cmd/thanos/tools_bucket.go similarity index 82% rename from cmd/thanos/bucket.go rename to cmd/thanos/tools_bucket.go index e922057e96..bfb48c7a9a 100644 --- a/cmd/thanos/bucket.go +++ b/cmd/thanos/tools_bucket.go @@ -64,15 +64,17 @@ var ( inspectColumns = []string{"ULID", "FROM", "UNTIL", "RANGE", "UNTIL-DOWN", "#SERIES", "#SAMPLES", "#CHUNKS", "COMP-LEVEL", "COMP-FAILED", "LABELS", "RESOLUTION", "SOURCE"} ) -func registerBucket(m map[string]setupFunc, app *kingpin.Application, name string) { - cmd := app.Command(name, "Bucket utility commands") +func registerBucket(m map[string]setupFunc, app *kingpin.CmdClause, pre string) { + cmd := app.Command("bucket", "Bucket utility commands") + pre += " bucket" objStoreConfig := regCommonObjStoreFlags(cmd, "", true) - registerBucketVerify(m, cmd, name, objStoreConfig) - registerBucketLs(m, cmd, name, objStoreConfig) - registerBucketInspect(m, cmd, name, objStoreConfig) - registerBucketWeb(m, cmd, name, objStoreConfig) - registerBucketReplicate(m, cmd, name, objStoreConfig) + registerBucketVerify(m, cmd, pre, objStoreConfig) + registerBucketLs(m, cmd, pre, objStoreConfig) + registerBucketInspect(m, cmd, pre, objStoreConfig) + registerBucketWeb(m, cmd, pre, objStoreConfig) + registerBucketReplicate(m, cmd, pre, objStoreConfig) + registerBucketDownsample(m, cmd, pre, objStoreConfig) } func registerBucketVerify(m map[string]setupFunc, root *kingpin.CmdClause, name string, objStoreConfig *extflag.PathOrContent) { @@ -84,6 +86,12 @@ func registerBucketVerify(m map[string]setupFunc, root *kingpin.CmdClause, name Short('i').Default(verifier.IndexIssueID, verifier.OverlappedBlocksIssueID).Strings() idWhitelist := cmd.Flag("id-whitelist", "Block IDs to verify (and optionally repair) only. "+ "If none is specified, all blocks will be verified. Repeated field").Strings() + deleteDelay := modelDuration(cmd.Flag("delete-delay", "Duration after which blocks marked for deletion would be deleted permanently from source bucket by compactor component. "+ + "If delete-delay is non zero, blocks will be marked for deletion and compactor component is required to delete blocks from source bucket. "+ + "If delete-delay is 0, blocks will be deleted straight away. Use this if you want to get rid of or move the block immediately. "+ + "Note that deleting blocks immediately can cause query failures, if store gateway still has the block loaded, "+ + "or compactor is ignoring the deletion because it's compacting the block at the same time."). + Default("0s")) m[name+" verify"] = func(g *run.Group, logger log.Logger, reg *prometheus.Registry, _ opentracing.Tracer, _ <-chan struct{}, _ bool) error { confContentYaml, err := objStoreConfig.Content() if err != nil { @@ -133,15 +141,15 @@ func registerBucketVerify(m map[string]setupFunc, root *kingpin.CmdClause, name issues = append(issues, issueFn) } - fetcher, err := block.NewMetaFetcher(logger, fetcherConcurrency, bkt, "", extprom.WrapRegistererWithPrefix(extpromPrefix, reg)) + fetcher, err := block.NewMetaFetcher(logger, fetcherConcurrency, bkt, "", extprom.WrapRegistererWithPrefix(extpromPrefix, reg), nil, nil) if err != nil { return err } if *repair { - v = verifier.NewWithRepair(logger, bkt, backupBkt, fetcher, issues) + v = verifier.NewWithRepair(logger, reg, bkt, backupBkt, fetcher, time.Duration(*deleteDelay), issues) } else { - v = verifier.New(logger, bkt, fetcher, issues) + v = verifier.New(logger, reg, bkt, fetcher, time.Duration(*deleteDelay), issues) } var idMatcher func(ulid.ULID) bool = nil @@ -182,7 +190,7 @@ func registerBucketLs(m map[string]setupFunc, root *kingpin.CmdClause, name stri return err } - fetcher, err := block.NewMetaFetcher(logger, fetcherConcurrency, bkt, "", extprom.WrapRegistererWithPrefix(extpromPrefix, reg)) + fetcher, err := block.NewMetaFetcher(logger, fetcherConcurrency, bkt, "", extprom.WrapRegistererWithPrefix(extpromPrefix, reg), nil, nil) if err != nil { return err } @@ -269,7 +277,7 @@ func registerBucketInspect(m map[string]setupFunc, root *kingpin.CmdClause, name // Parse selector. selectorLabels, err := parseFlagLabels(*selector) if err != nil { - return fmt.Errorf("error parsing selector flag: %v", err) + return errors.Wrap(err, "error parsing selector flag") } confContentYaml, err := objStoreConfig.Content() @@ -282,7 +290,7 @@ func registerBucketInspect(m map[string]setupFunc, root *kingpin.CmdClause, name return err } - fetcher, err := block.NewMetaFetcher(logger, fetcherConcurrency, bkt, "", extprom.WrapRegistererWithPrefix(extpromPrefix, reg)) + fetcher, err := block.NewMetaFetcher(logger, fetcherConcurrency, bkt, "", extprom.WrapRegistererWithPrefix(extpromPrefix, reg), nil, nil) if err != nil { return err } @@ -321,13 +329,11 @@ func registerBucketWeb(m map[string]setupFunc, root *kingpin.CmdClause, name str label := cmd.Flag("label", "Prometheus label to use as timeline title").String() m[name+" web"] = func(g *run.Group, logger log.Logger, reg *prometheus.Registry, _ opentracing.Tracer, _ <-chan struct{}, _ bool) error { - ctx, cancel := context.WithCancel(context.Background()) - comp := component.Bucket httpProbe := prober.NewHTTP() statusProber := prober.Combine( httpProbe, - prober.NewInstrumentation(comp, logger, prometheus.WrapRegistererWithPrefix("thanos_", reg)), + prober.NewInstrumentation(comp, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)), ) srv := httpserver.New(logger, reg, comp, httpProbe, @@ -335,15 +341,10 @@ func registerBucketWeb(m map[string]setupFunc, root *kingpin.CmdClause, name str httpserver.WithGracePeriod(time.Duration(*httpGracePeriod)), ) - flagsMap := map[string]string{ - "web.external-prefix": *webExternalPrefix, - "web.prefix-header": *webPrefixHeaderName, - } - router := route.New() - bucketUI := ui.NewBucketUI(logger, *label, flagsMap) - bucketUI.Register(router.WithPrefix(*webExternalPrefix), extpromhttp.NewInstrumentationMiddleware(reg)) + bucketUI := ui.NewBucketUI(logger, *label, *webExternalPrefix, *webPrefixHeaderName) + bucketUI.Register(router, extpromhttp.NewInstrumentationMiddleware(reg)) srv.Handle("/", router) if *interval < 5*time.Minute { @@ -358,10 +359,39 @@ func registerBucketWeb(m map[string]setupFunc, root *kingpin.CmdClause, name str level.Warn(logger).Log("msg", "Refresh interval should be at least 2 times the timeout") } + confContentYaml, err := objStoreConfig.Content() + if err != nil { + return err + } + + bkt, err := client.NewBucket(logger, confContentYaml, reg, component.Bucket.String()) + if err != nil { + return errors.Wrap(err, "bucket client") + } + + // TODO(bwplotka): Allow Bucket UI to visualize the state of block as well. + fetcher, err := block.NewMetaFetcher(logger, fetcherConcurrency, bkt, "", extprom.WrapRegistererWithPrefix(extpromPrefix, reg), nil, nil) + if err != nil { + return err + } + fetcher.UpdateOnChange(bucketUI.Set) + + ctx, cancel := context.WithCancel(context.Background()) g.Add(func() error { statusProber.Ready() - - return refresh(ctx, logger, bucketUI, *interval, *timeout, name, reg, objStoreConfig) + defer runutil.CloseWithLogOnErr(logger, bkt, "bucket client") + return runutil.Repeat(*interval, ctx.Done(), func() error { + return runutil.RetryWithLog(logger, time.Minute, ctx.Done(), func() error { + iterCtx, iterCancel := context.WithTimeout(ctx, *timeout) + defer iterCancel() + + _, _, err := fetcher.Fetch(iterCtx) + if err != nil { + return err + } + return nil + }) + }) }, func(error) { cancel() }) @@ -424,60 +454,18 @@ func registerBucketReplicate(m map[string]setupFunc, root *kingpin.CmdClause, na } -// refresh metadata from remote storage periodically and update UI. -func refresh(ctx context.Context, logger log.Logger, bucketUI *ui.Bucket, duration time.Duration, timeout time.Duration, name string, reg *prometheus.Registry, objStoreConfig *extflag.PathOrContent) error { - confContentYaml, err := objStoreConfig.Content() - if err != nil { - return err - } - - bkt, err := client.NewBucket(logger, confContentYaml, reg, name) - if err != nil { - return errors.Wrap(err, "bucket client") - } +func registerBucketDownsample(m map[string]setupFunc, root *kingpin.CmdClause, name string, objStoreConfig *extflag.PathOrContent) { + comp := component.Downsample + cmd := root.Command(comp.String(), "continuously downsamples blocks in an object store bucket") - fetcher, err := block.NewMetaFetcher(logger, fetcherConcurrency, bkt, "", extprom.WrapRegistererWithPrefix(extpromPrefix, reg)) - if err != nil { - return err - } + httpAddr, httpGracePeriod := regHTTPFlags(cmd) - defer runutil.CloseWithLogOnErr(logger, bkt, "bucket client") - return runutil.Repeat(duration, ctx.Done(), func() error { - return runutil.RetryWithLog(logger, time.Minute, ctx.Done(), func() error { - iterCtx, iterCancel := context.WithTimeout(ctx, timeout) - defer iterCancel() - - blocks, err := download(iterCtx, logger, bkt, fetcher) - if err != nil { - bucketUI.Set("[]", err) - return err - } + dataDir := cmd.Flag("data-dir", "Data directory in which to cache blocks and process downsamplings."). + Default("./data").String() - data, err := json.Marshal(blocks) - if err != nil { - bucketUI.Set("[]", err) - return err - } - bucketUI.Set(string(data), nil) - return nil - }) - }) -} - -func download(ctx context.Context, logger log.Logger, bkt objstore.Bucket, fetcher *block.MetaFetcher) (blocks []metadata.Meta, err error) { - level.Info(logger).Log("msg", "synchronizing block metadata") - - metas, _, err := fetcher.Fetch(ctx) - if err != nil { - return nil, err + m[name+" "+comp.String()] = func(g *run.Group, logger log.Logger, reg *prometheus.Registry, tracer opentracing.Tracer, _ <-chan struct{}, _ bool) error { + return RunDownsample(g, logger, reg, *httpAddr, time.Duration(*httpGracePeriod), *dataDir, objStoreConfig, comp) } - - for _, meta := range metas { - blocks = append(blocks, *meta) - } - - level.Info(logger).Log("msg", "downloaded blocks meta.json", "num", len(blocks)) - return blocks, nil } func printTable(blockMetas []*metadata.Meta, selectorLabels labels.Labels, sortBy []string) error { @@ -523,7 +511,7 @@ func printTable(blockMetas []*metadata.Meta, selectorLabels labels.Labels, sortB for _, col := range sortBy { index := getIndex(header, col) if index == -1 { - return fmt.Errorf("column %s not found", col) + return errors.Errorf("column %s not found", col) } sortByColNum = append(sortByColNum, index) } @@ -595,10 +583,21 @@ func (t Table) Less(i, j int) bool { } func compare(s1, s2 string) bool { + // Values can be either Time, Duration, comma-delimited integers or strings. s1Time, s1Err := time.Parse("02-01-2006 15:04:05", s1) s2Time, s2Err := time.Parse("02-01-2006 15:04:05", s2) if s1Err != nil || s2Err != nil { - return s1 < s2 + s1Duration, s1Err := time.ParseDuration(s1) + s2Duration, s2Err := time.ParseDuration(s2) + if s1Err != nil || s2Err != nil { + s1Int, s1Err := strconv.ParseUint(strings.Replace(s1, ",", "", -1), 10, 64) + s2Int, s2Err := strconv.ParseUint(strings.Replace(s2, ",", "", -1), 10, 64) + if s1Err != nil || s2Err != nil { + return s1 < s2 + } + return s1Int < s2Int + } + return s1Duration < s2Duration } return s1Time.Before(s2Time) } diff --git a/cmd/thanos/check_test.go b/cmd/thanos/tools_test.go similarity index 61% rename from cmd/thanos/check_test.go rename to cmd/thanos/tools_test.go index 299b0276e5..d9bcdbf7f8 100644 --- a/cmd/thanos/check_test.go +++ b/cmd/thanos/tools_test.go @@ -10,17 +10,17 @@ import ( "github.com/thanos-io/thanos/pkg/testutil" ) -func Test_checkRules(t *testing.T) { +func Test_CheckRules(t *testing.T) { validFiles := []string{ "./testdata/rules-files/valid.yaml", } invalidFiles := [][]string{ - []string{"./testdata/rules-files/non-existing-file.yaml"}, - []string{"./testdata/rules-files/invalid-yaml-format.yaml"}, - []string{"./testdata/rules-files/invalid-rules-data.yaml"}, - []string{"./testdata/rules-files/invalid-unknown-field.yaml"}, + {"./testdata/rules-files/non-existing-file.yaml"}, + {"./testdata/rules-files/invalid-yaml-format.yaml"}, + {"./testdata/rules-files/invalid-rules-data.yaml"}, + {"./testdata/rules-files/invalid-unknown-field.yaml"}, } logger := log.NewNopLogger() diff --git a/docs/community.md b/docs/community.md new file mode 100644 index 0000000000..2cb1d0c3c6 --- /dev/null +++ b/docs/community.md @@ -0,0 +1,40 @@ +--- +title: Community +type: docs +menu: contributing +slug: /community.md +--- + +# General + +Thanos is an open source project and we value and welcome new contributors and members of the community. Here are ways to get in touch with the community: + +## Thanos Community meeting + +Thanos Community Meeting is a **public** and **recorded** monthly meeting every second Wednesday 12:00 UTC ([Time zone converter](https://www.thetimezoneconverter.com/?t=12%3A00%20pm&tz=UTC%20(Coordinated%20Universal%20Time)&)). + +Thanos maintainers & the community meet to discuss open issues, features and other Thanos related things. +Everyone is welcome to join & add items to the agenda. The meeting happens in Zoom. Right now meeting is in a Webinar format, where only small amount of people will have ability to speak and video share, due to recent [Zoombombing](https://en.wikipedia.org/wiki/Zoombombing) issues. + +* When: Monthly, every second Wednesday 12:00 UTC ([Time zone converter](https://www.thetimezoneconverter.com/?t=12%3A00%20pm&tz=UTC%20(Coordinated%20Universal%20Time)&)). +* Google Calendar: [Google Calendar](https://calendar.google.com/calendar/embed?src=go39q7eu71vvu3gfrkbup6b254%40group.calendar.google.com) +* Agenda: [https://bit.ly/thanos-community-agenda](https://bit.ly/thanos-community-agenda) +* Link to join zoom webinar: [https://zoom.us/j/96476403386](https://zoom.us/j/96476403386) + +If you have any suggestions, how we can run the meeting better, please let @povilasv know in CNCF slack. + +## Slack + +* General channel: [#thanos](https://slack.cncf.io/) +* Development related channel: [#thanos-dev](https://slack.cncf.io/) +* Thanos PR discussion & review: [#thanos-prs](https://slack.cncf.io/) + +## Prometheus Community & Ecosystem Meeting + +The Prometheus & The Ecosystem community meeting is intended to provide a holistic overview of community activities, critical release information, and governance updates for Prometheus & the Ecosystem projects. + +Thanos Maintainers regularly join and give announcements and updates. + +Meeting details: [https://bit.ly/prometheus-community-agenda](https://bit.ly/prometheus-community-agenda) + + diff --git a/docs/components/_index.md b/docs/components/_index.md new file mode 100644 index 0000000000..869b07d88a --- /dev/null +++ b/docs/components/_index.md @@ -0,0 +1,3 @@ +--- +title: "Components:" +--- diff --git a/docs/components/check.md b/docs/components/check.md deleted file mode 100644 index 8c0599a7f4..0000000000 --- a/docs/components/check.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: Check -type: docs -menu: components ---- - -# Check - -The check component contains tools for validation of Prometheus rules. - -## Deployment -## Flags - -[embedmd]:# (flags/check.txt $) -```$ -usage: thanos check [ ...] - -Linting tools for Thanos - -Flags: - -h, --help Show context-sensitive help (also try --help-long and - --help-man). - --version Show application version. - --log.level=info Log filtering level. - --log.format=logfmt Log format to use. Possible options: logfmt or json. - --tracing.config-file= - Path to YAML file with tracing configuration. See - format details: - https://thanos.io/tracing.md/#configuration - --tracing.config= - Alternative to 'tracing.config-file' flag (lower - priority). Content of YAML file with tracing - configuration. See format details: - https://thanos.io/tracing.md/#configuration - -Subcommands: - check rules ... - Check if the rule files are valid or not. - - -``` - - -### Rules - -`check rules` checks the Prometheus rules, used by the Thanos rule node, if they are valid. -The check should be equivalent for the `promtool check rules` but that cannot be used because -Thanos rule has extended rules file syntax, which includes `partial_response_strategy` field -which `promtool` does not allow. - -If the check fails the command fails with exit code `1`, otherwise `0`. - -Example: - -``` -$ ./thanos check rules cmd/thanos/testdata/rules-files/*.yaml -``` - -[embedmd]:# (flags/check_rules.txt) -```txt -usage: thanos check rules ... - -Check if the rule files are valid or not. - -Flags: - -h, --help Show context-sensitive help (also try --help-long and - --help-man). - --version Show application version. - --log.level=info Log filtering level. - --log.format=logfmt Log format to use. Possible options: logfmt or json. - --tracing.config-file= - Path to YAML file with tracing configuration. See - format details: - https://thanos.io/tracing.md/#configuration - --tracing.config= - Alternative to 'tracing.config-file' flag (lower - priority). Content of YAML file with tracing - configuration. See format details: - https://thanos.io/tracing.md/#configuration - -Args: - The rule files to check. - -``` diff --git a/docs/components/compact.md b/docs/components/compact.md index edd71eb7b1..1ca48e14a8 100644 --- a/docs/components/compact.md +++ b/docs/components/compact.md @@ -6,18 +6,18 @@ menu: components # Compactor -The compactor component of Thanos applies the compaction procedure of the Prometheus 2.0 storage engine to block data stored in object storage. +The `thanos compact` command applies the compaction procedure of the Prometheus 2.0 storage engine to block data stored in object storage. It is generally not semantically concurrency safe and must be deployed as a singleton against a bucket. It is also responsible for downsampling of data: -* creating 5m downsampling for blocks larger than **40 hours** (2d, 2w) -* creating 1h downsampling for blocks larger than **10 days** (2w). +- creating 5m downsampling for blocks larger than **40 hours** (2d, 2w) +- creating 1h downsampling for blocks larger than **10 days** (2w). Example: ```bash -$ thanos compact --data-dir /tmp/thanos-compact --objstore.config-file=bucket.yml +thanos compact --data-dir /tmp/thanos-compact --objstore.config-file=bucket.yml ``` The content of `bucket.yml`: @@ -35,9 +35,9 @@ On-disk data is safe to delete between restarts and should be the first attempt Resolution - distance between data points on your graphs. E.g. -* raw - the same as scrape interval at the moment of data ingestion -* 5m - data point is every 5 minutes -* 1h - data point is every 1h +- raw - the same as scrape interval at the moment of data ingestion +- 5m - data point is every 5 minutes +- 1h - data point is every 1h Keep in mind, that the initial goal of downsampling is not saving disk space (Read further for elaboration on storage space consumption). The goal of downsampling is providing an opportunity to get fast results for range queries of big time intervals like months or years. In other words, if you set `--retention.resolution-raw` less then `--retention.resolution-5m` and `--retention.resolution-1h` - you might run into a problem of not being able to "zoom in" to your historical data. @@ -64,6 +64,14 @@ your Prometheus instances, so that the compactor will be able to group blocks by By _persistent_, we mean that one Prometheus instance must keep the same labels if it restarts, so that the compactor will keep compacting blocks from an instance even when a Prometheus instance goes down for some time. +## Block Deletion + +Depending on the Object Storage provider like S3, GCS, Ceph etc; we can divide the storages into strongly consistent or eventually consistent. +Since there are no consistency guarantees provided by some Object Storage providers, we have to make sure that we have a consistent lock-free way of dealing with Object Storage irrespective of the choice of object storage. + +In order to achieve this co-ordination, blocks are not deleted directly. Instead, blocks are marked for deletion by uploading +`deletion-mark.json` file for the block that was chosen to be deleted. This file contains unix time of when the block was marked for deletion. + ## Flags [embedmd]:# (flags/compact.txt $) @@ -73,76 +81,113 @@ usage: thanos compact [] continuously compacts blocks in an object store bucket Flags: - -h, --help Show context-sensitive help (also try --help-long - and --help-man). - --version Show application version. - --log.level=info Log filtering level. - --log.format=logfmt Log format to use. Possible options: logfmt or - json. + -h, --help Show context-sensitive help (also try + --help-long and --help-man). + --version Show application version. + --log.level=info Log filtering level. + --log.format=logfmt Log format to use. Possible options: logfmt or + json. --tracing.config-file= - Path to YAML file with tracing configuration. See - format details: - https://thanos.io/tracing.md/#configuration + Path to YAML file with tracing configuration. + See format details: + https://thanos.io/tracing.md/#configuration --tracing.config= - Alternative to 'tracing.config-file' flag (lower - priority). Content of YAML file with tracing - configuration. See format details: - https://thanos.io/tracing.md/#configuration + Alternative to 'tracing.config-file' flag (lower + priority). Content of YAML file with tracing + configuration. See format details: + https://thanos.io/tracing.md/#configuration --http-address="0.0.0.0:10902" - Listen host:port for HTTP endpoints. - --http-grace-period=2m Time to wait after an interrupt received for HTTP - Server. - --data-dir="./data" Data directory in which to cache blocks and - process compactions. + Listen host:port for HTTP endpoints. + --http-grace-period=2m Time to wait after an interrupt received for + HTTP Server. + --data-dir="./data" Data directory in which to cache blocks and + process compactions. --objstore.config-file= - Path to YAML file that contains object store - configuration. See format details: - https://thanos.io/storage.md/#configuration + Path to YAML file that contains object store + configuration. See format details: + https://thanos.io/storage.md/#configuration --objstore.config= - Alternative to 'objstore.config-file' flag (lower - priority). Content of YAML file that contains - object store configuration. See format details: - https://thanos.io/storage.md/#configuration - --consistency-delay=30m Minimum age of fresh (non-compacted) blocks - before they are being processed. Malformed blocks - older than the maximum of consistency-delay and - 48h0m0s will be removed. + Alternative to 'objstore.config-file' flag + (lower priority). Content of YAML file that + contains object store configuration. See format + details: + https://thanos.io/storage.md/#configuration + --consistency-delay=30m Minimum age of fresh (non-compacted) blocks + before they are being processed. Malformed + blocks older than the maximum of + consistency-delay and 48h0m0s will be removed. --retention.resolution-raw=0d - How long to retain raw samples in bucket. Setting - this to 0d will retain samples of this resolution - forever + How long to retain raw samples in bucket. + Setting this to 0d will retain samples of this + resolution forever --retention.resolution-5m=0d - How long to retain samples of resolution 1 (5 - minutes) in bucket. Setting this to 0d will - retain samples of this resolution forever + How long to retain samples of resolution 1 (5 + minutes) in bucket. Setting this to 0d will + retain samples of this resolution forever --retention.resolution-1h=0d - How long to retain samples of resolution 2 (1 - hour) in bucket. Setting this to 0d will retain - samples of this resolution forever - -w, --wait Do not exit after all compactions have been - processed and wait for new work. - --downsampling.disable Disables downsampling. This is not recommended as - querying long time ranges without non-downsampled - data is not efficient and useful e.g it is not - possible to render all samples for a human eye - anyway + How long to retain samples of resolution 2 (1 + hour) in bucket. Setting this to 0d will retain + samples of this resolution forever + -w, --wait Do not exit after all compactions have been + processed and wait for new work. + --wait-interval=5m Wait interval between consecutive compaction + runs and bucket refreshes. Only works when + --wait flag specified. + --downsampling.disable Disables downsampling. This is not recommended + as querying long time ranges without + non-downsampled data is not efficient and useful + e.g it is not possible to render all samples for + a human eye anyway --block-sync-concurrency=20 - Number of goroutines to use when syncing block - metadata from object storage. - --compact.concurrency=1 Number of goroutines to use when compacting - groups. + Number of goroutines to use when syncing block + metadata from object storage. + --compact.concurrency=1 Number of goroutines to use when compacting + groups. + --delete-delay=48h Time before a block marked for deletion is + deleted from bucket. If delete-delay is non + zero, blocks will be marked for deletion and + compactor component will delete blocks marked + for deletion from the bucket. If delete-delay is + 0, blocks will be deleted straight away. Note + that deleting blocks immediately can cause query + failures, if store gateway still has the block + loaded, or compactor is ignoring the deletion + because it's compacting the block at the same + time. --selector.relabel-config-file= - Path to YAML file that contains relabeling - configuration that allows selecting blocks. It - follows native Prometheus relabel-config syntax. - See format details: - https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + Path to YAML file that contains relabeling + configuration that allows selecting blocks. It + follows native Prometheus relabel-config syntax. + See format details: + https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config --selector.relabel-config= - Alternative to 'selector.relabel-config-file' - flag (lower priority). Content of YAML file that - contains relabeling configuration that allows - selecting blocks. It follows native Prometheus - relabel-config syntax. See format details: - https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + Alternative to 'selector.relabel-config-file' + flag (lower priority). Content of YAML file that + contains relabeling configuration that allows + selecting blocks. It follows native Prometheus + relabel-config syntax. See format details: + https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config + --web.external-prefix="" Static prefix for all HTML links and redirect + URLs in the bucket web UI interface. Actual + endpoints are still served on / or the + web.route-prefix. This allows thanos bucket web + UI to be served behind a reverse proxy that + strips a URL sub-path. + --web.prefix-header="" Name of HTTP request header used for dynamic + prefixing of UI links and redirects. This option + is ignored if web.external-prefix argument is + set. Security risk: enable this option only if a + reverse proxy in front of thanos is resetting + the header. The + --web.prefix-header=X-Forwarded-Prefix option + can be useful, for example, if Thanos UI is + served via Traefik reverse proxy with + PathPrefixStrip option enabled, which sends the + stripped prefix value in X-Forwarded-Prefix + header. This allows thanos UI to be served on a + sub-path. + --bucket-web-label=BUCKET-WEB-LABEL + Prometheus label to use as timeline title in the + bucket web UI ``` diff --git a/docs/components/query.md b/docs/components/query.md index a0df99a631..a966a6bc35 100644 --- a/docs/components/query.md +++ b/docs/components/query.md @@ -6,7 +6,7 @@ menu: components # Querier/Query -The Querier component (also known as "Query") implements the [Prometheus HTTP v1 API](https://prometheus.io/docs/prometheus/latest/querying/api/) to query data in a Thanos cluster via PromQL. +The `thanos query` command (also known as "Querier") implements the [Prometheus HTTP v1 API](https://prometheus.io/docs/prometheus/latest/querying/api/) to query data in a Thanos cluster via PromQL. In short, it gathers the data needed to evaluate the query from underlying [StoreAPIs](../../pkg/store/storepb/rpc.proto), evaluates the query and returns the result. @@ -15,7 +15,7 @@ Querier is fully stateless and horizontally scalable. Example command to run Querier: ```bash -$ thanos query \ +thanos query \ --http-address "0.0.0.0:9090" \ --store ":" \ --store ":" @@ -81,7 +81,7 @@ This also hides gaps in collection of a single data source. If we configure Querier like this: ``` -$ thanos query \ +thanos query \ --http-address "0.0.0.0:9090" \ --query.replica-label "replica" \ --store ":" \ @@ -106,7 +106,7 @@ WITHOUT this replica flag (deduplication turned off), we will get 3 results: * Prometheus + sidecar "A" in different cluster: `cluster=2,env=2,replica=A,replicaX=A` ``` -$ thanos query \ +thanos query \ --http-address "0.0.0.0:9090" \ --query.replica-label "replica" \ --query.replica-label "replicaX" \ @@ -228,7 +228,7 @@ Additionally, Thanos supports dynamic prefix configuration, which [is not yet implemented by Prometheus](https://github.com/prometheus/prometheus/issues/3156). Dynamic prefixing simplifies setup when `thanos query` is exposed on a sub-path behind a reverse proxy, for example, via a Kubernetes ingress controller -[Traefik](https://docs.traefik.io/basics/#frontends) +[Traefik](https://docs.traefik.io/routing/routers/) or [nginx](https://github.com/kubernetes/ingress-nginx/pull/1805). If `PathPrefixStrip: /some-path` option or `traefik.frontend.rule.type: PathPrefixStrip` Kubernetes Ingress annotation is set, then `Traefik` writes the stripped prefix into X-Forwarded-Prefix header. @@ -333,6 +333,11 @@ Flags: prefixed with 'dns+' or 'dnssrv+' to detect rule API servers through respective DNS lookups. + --store-strict= ... + Addresses of only statically configured store + API servers that are always used, even if the + health check fails. Useful if you have a + caching layer on top. --store.sd-files= ... Path to files that contain addresses of store API servers. The path can be a glob pattern diff --git a/docs/components/rule.md b/docs/components/rule.md index ffa3dfa6fc..e85c2d45ab 100644 --- a/docs/components/rule.md +++ b/docs/components/rule.md @@ -10,7 +10,7 @@ _**NOTE:** It is recommended to keep deploying rules inside the relevant Prometh _The rule component should in particular not be used to circumvent solving rule deployment properly at the configuration management level._ -The rule component evaluates Prometheus recording and alerting rules against chosen query API via repeated `--query` (or FileSD via `--query.sd`). If more than one query is passed, round robin balancing is performed. +The `thanos rule` command evaluates Prometheus recording and alerting rules against chosen query API via repeated `--query` (or FileSD via `--query.sd`). If more than one query is passed, round robin balancing is performed. Rule results are written back to disk in the Prometheus 2.0 storage format. Rule nodes at the same time participate in the system as source store nodes, which means that they expose StoreAPI and upload their generated TSDB blocks to an object store. @@ -20,12 +20,12 @@ The data of each Rule node can be labeled to satisfy the clusters labeling schem Read more about Ruler in HA [here](rule.md#ruler-ha) ```bash -$ thanos rule \ +thanos rule \ --data-dir "/path/to/data" \ --eval-interval "30s" \ --rule-file "/path/to/rules/*.rules.yaml" \ --alert.query-url "http://0.0.0.0:9090" \ # This tells what query URL to link to in UI. - --alertmanagers.url "alert.thanos.io" \ + --alertmanagers.url "http://alert.thanos.io" \ --query "query.example.org" \ --query "query2.example.org" \ --objstore.config-file "bucket.yml" \ diff --git a/docs/components/sidecar.md b/docs/components/sidecar.md index 723dab0775..1eb2a0eb2f 100644 --- a/docs/components/sidecar.md +++ b/docs/components/sidecar.md @@ -6,7 +6,7 @@ menu: components # Sidecar -The sidecar component of Thanos gets deployed along with a Prometheus instance. This allows sidecar to optionally upload metrics to object storage and allow [Queriers](./query.md) to query Prometheus data with common, efficient StoreAPI. +The `thanos sidecar` command runs a component that gets deployed along with a Prometheus instance. This allows sidecar to optionally upload metrics to object storage and allow [Queriers](./query.md) to query Prometheus data with common, efficient StoreAPI. In details: @@ -49,14 +49,14 @@ Thanos sidecar can watch `--reloader.config-file=CONFIG_FILE` configuration file ## Example basic deployment ```bash -$ prometheus \ +prometheus \ --storage.tsdb.max-block-duration=2h \ --storage.tsdb.min-block-duration=2h \ --web.enable-lifecycle ``` ```bash -$ thanos sidecar \ +thanos sidecar \ --tsdb.path "/path/to/prometheus/data/dir" \ --prometheus.url "http://localhost:9090" \ --objstore.config-file "bucket.yml" diff --git a/docs/components/store.md b/docs/components/store.md index f1e900212e..66a1ecfafe 100644 --- a/docs/components/store.md +++ b/docs/components/store.md @@ -6,11 +6,11 @@ menu: components # Store -The store component of Thanos implements the Store API on top of historical data in an object storage bucket. It acts primarily as an API gateway and therefore does not need significant amounts of local disk space. It joins a Thanos cluster on startup and advertises the data it can access. +The `thanos store` command (also known as Store Gateway) implements the Store API on top of historical data in an object storage bucket. It acts primarily as an API gateway and therefore does not need significant amounts of local disk space. It joins a Thanos cluster on startup and advertises the data it can access. It keeps a small amount of information about all remote blocks on local disk and keeps it in sync with the bucket. This data is generally safe to delete across restarts at the cost of increased startup times. ```bash -$ thanos store \ +thanos store \ --data-dir "/local/state/data/dir" \ --objstore.config-file "bucket.yml" ``` @@ -27,8 +27,7 @@ In general about 1MB of local disk space is required per TSDB block stored in th ## Flags -[embedmd]: # "flags/store.txt $" - +[embedmd]:# (flags/store.txt $) ```$ usage: thanos store [] @@ -69,7 +68,13 @@ Flags: TLS CA to verify clients against. If no client CA is specified, there is no client verification on server side. (tls.NoClientCert) - --data-dir="./data" Data directory in which to cache remote blocks. + --data-dir="./data" Local data directory used for caching purposes + (index-header, in-mem cache items and + meta.jsons). If removed, no data will be lost, + just store will have to rebuild the cache. + NOTE: Putting raw blocks here will not cause + the store to read them. For such use cases use + Prometheus + sidecar. --index-cache-size=250MB Maximum size of items held in the in-memory index cache. Ignored if --index-cache.config or --index-cache.config-file option is specified. @@ -138,7 +143,50 @@ Flags: Prometheus relabel-config syntax. See format details: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config - --consistency-delay=30m Minimum age of all blocks before they are being read. + --consistency-delay=0s Minimum age of all blocks before they are being + read. Set it to safe value (e.g 30m) if your + object storage is eventually consistent. GCS + and S3 are (roughly) strongly consistent. + --ignore-deletion-marks-delay=24h + Duration after which the blocks marked for + deletion will be filtered out while fetching + blocks. The idea of ignore-deletion-marks-delay + is to ignore blocks that are marked for + deletion with some delay. This ensures store + can still serve blocks that are meant to be + deleted but do not have a replacement yet. If + delete-delay duration is provided to compactor + or bucket verify component, it will upload + deletion-mark.json file to mark after what + duration the block should be deleted rather + than deleting the block straight away. If + delete-delay is non-zero for compactor or + bucket verify component, + ignore-deletion-marks-delay should be set to + (delete-delay)/2 so that blocks marked for + deletion are filtered out while fetching blocks + before being deleted from bucket. Default is + 24h, half of the default value for + --delete-delay on compactor. + --web.external-prefix="" Static prefix for all HTML links and redirect + URLs in the bucket web UI interface. Actual + endpoints are still served on / or the + web.route-prefix. This allows thanos bucket web + UI to be served behind a reverse proxy that + strips a URL sub-path. + --web.prefix-header="" Name of HTTP request header used for dynamic + prefixing of UI links and redirects. This + option is ignored if web.external-prefix + argument is set. Security risk: enable this + option only if a reverse proxy in front of + thanos is resetting the header. The + --web.prefix-header=X-Forwarded-Prefix option + can be useful, for example, if Thanos UI is + served via Traefik reverse proxy with + PathPrefixStrip option enabled, which sends the + stripped prefix value in X-Forwarded-Prefix + header. This allows thanos UI to be served on a + sub-path. ``` @@ -209,6 +257,7 @@ config: max_idle_connections: 0 max_async_concurrency: 0 max_async_buffer_size: 0 + max_item_size: 1MiB max_get_multi_concurrency: 0 max_get_multi_batch_size: 0 dns_provider_update_interval: 0s @@ -226,8 +275,51 @@ While the remaining settings are **optional**: - `max_async_buffer_size`: maximum number of enqueued asynchronous operations allowed. - `max_get_multi_concurrency`: maximum number of concurrent connections when fetching keys. If set to `0`, the concurrency is unlimited. - `max_get_multi_batch_size`: maximum number of keys a single underlying operation should fetch. If more keys are specified, internally keys are splitted into multiple batches and fetched concurrently, honoring `max_get_multi_concurrency`. If set to `0`, the batch size is unlimited. +- `max_item_size`: maximum size of an item to be stored in memcached. This option should be set to the same value of memcached `-I` flag (defaults to 1MB) in order to avoid wasting network round trips to store items larger than the max item size allowed in memcached. If set to `0`, the item size is unlimited. - `dns_provider_update_interval`: the DNS discovery update interval. +## Caching Bucket + +Thanos Store Gateway supports a "caching bucket" with chunks and metadata caching to speed up loading of chunks from TSDB blocks. To configure caching, one needs to use `--store.caching-bucket.config=` or `--store.caching-bucket.config-file=`. + +Currently only memcached "backend" is supported: + +```yaml +backend: memcached +backend_config: + addresses: + - localhost:11211 + +chunk_subrange_size: 16000 +max_chunks_get_range_requests: 3 +chunk_object_size_ttl: 24h +chunk_subrange_ttl: 24h +blocks_iter_ttl: 5m +metafile_exists_ttl: 2h +metafile_doesnt_exist_ttl: 15m +metafile_content_ttl: 24h +metafile_max_size: 1MiB +``` + +`backend_config` field for memcached supports all the same configuration as memcached for [index cache](#memcached-index-cache). + +Additional options to configure various aspects of chunks cache are available: + +- `chunk_subrange_size`: size of segment of chunks object that is stored to the cache. This is the smallest unit that chunks cache is working with. +- `max_chunks_get_range_requests`: how many "get range" sub-requests may cache perform to fetch missing subranges. +- `chunk_object_size_ttl`: how long to keep information about chunk file length in the cache. +- `chunk_subrange_ttl`: how long to keep individual subranges in the cache. + +Following options are used for metadata caching (meta.json files, deletion mark files, iteration result): + +- `blocks_iter_ttl`: how long to cache result of iterating blocks. +- `metafile_exists_ttl`: how long to cache information about whether meta.json or deletion mark file exists. +- `metafile_doesnt_exist_ttl`: how long to cache information about whether meta.json or deletion mark file doesn't exist. +- `metafile_content_ttl`: how long to cache content of meta.json and deletion mark files. +- `metafile_max_size`: maximum size of cached meta.json and deletion mark file. Larger files are not cached. + +Note that chunks and metadata cache is an experimental feature, and these fields may be renamed or removed completely in the future. + ## Index Header In order to query series inside blocks from object storage, Store Gateway has to know certain initial info about each block such as: diff --git a/docs/components/bucket.md b/docs/components/tools.md similarity index 62% rename from docs/components/bucket.md rename to docs/components/tools.md index 3dc3c7aaf9..feb5ace116 100644 --- a/docs/components/bucket.md +++ b/docs/components/tools.md @@ -1,18 +1,75 @@ --- -title: Bucket +title: Tools type: docs menu: components --- -# Bucket +# Tools -The bucket component of Thanos is a set of commands to inspect data in object storage buckets. -It is normally run as a stand alone command to aid with troubleshooting. +The `thanos tools` subcommand of Thanos is a set of additional CLI, short-living tools that +are meant to be ran for development or debugging purposes. + +All commands added as tools should land in `tools.go` or file with `tools_` prefix. + +## Flags + +[embedmd]:# (flags/tools.txt $) +```$ +usage: thanos tools [ ...] + +Tools utility commands + +Flags: + -h, --help Show context-sensitive help (also try --help-long and + --help-man). + --version Show application version. + --log.level=info Log filtering level. + --log.format=logfmt Log format to use. Possible options: logfmt or json. + --tracing.config-file= + Path to YAML file with tracing configuration. See + format details: + https://thanos.io/tracing.md/#configuration + --tracing.config= + Alternative to 'tracing.config-file' flag (lower + priority). Content of YAML file with tracing + configuration. See format details: + https://thanos.io/tracing.md/#configuration + +Subcommands: + tools bucket verify [] + Verify all blocks in the bucket against specified issues + + tools bucket ls [] + List all blocks in the bucket + + tools bucket inspect [] + Inspect all blocks in the bucket in detailed, table-like way + + tools bucket web [] + Web interface for remote storage bucket + + tools bucket replicate [] + Replicate data from one object storage to another. NOTE: Currently it works + only with Thanos blocks (meta.json has to have Thanos metadata). + + tools bucket downsample [] + continuously downsamples blocks in an object store bucket + + tools rules-check --rules=RULES + Check if the rule files are valid or not. + + +``` + +## Bucket + +The `thanos tools bucket` subcommand of Thanos is a set of commands to inspect data in object storage buckets. +It is normally run as a standalone command to aid with troubleshooting. Example: ```bash -$ thanos bucket verify --objstore.config-file=bucket.yml +thanos tools bucket verify --objstore.config-file=bucket.yml ``` The content of `bucket.yml`: @@ -24,15 +81,11 @@ config: ``` Bucket can be extended to add more subcommands that will be helpful when working with object storage buckets -by adding a new command within `/cmd/thanos/bucket.go`. - +by adding a new command within [`/cmd/thanos/tools_bucket.go`](/cmd/thanos/tools_bucket.go) . -## Deployment -## Flags - -[embedmd]:# (flags/bucket.txt $) +[embedmd]:# (flags/tools_bucket.txt $) ```$ -usage: thanos bucket [] [ ...] +usage: thanos tools bucket [] [ ...] Bucket utility commands @@ -62,28 +115,31 @@ Flags: https://thanos.io/storage.md/#configuration Subcommands: - bucket verify [] + tools bucket verify [] Verify all blocks in the bucket against specified issues - bucket ls [] + tools bucket ls [] List all blocks in the bucket - bucket inspect [] + tools bucket inspect [] Inspect all blocks in the bucket in detailed, table-like way - bucket web [] + tools bucket web [] Web interface for remote storage bucket - bucket replicate [] + tools bucket replicate [] Replicate data from one object storage to another. NOTE: Currently it works only with Thanos blocks (meta.json has to have Thanos metadata). + tools bucket downsample [] + continuously downsamples blocks in an object store bucket + ``` -### Web +### Bucket Web -`bucket web` is used to inspect bucket blocks in form of interactive web UI. +`tools bucket web` is used to inspect bucket blocks in form of interactive web UI. This will start local webserver that will periodically update the view with given refresh. @@ -92,12 +148,12 @@ This will start local webserver that will periodically update the view with give Example: ``` -$ thanos bucket web --objstore.config-file="..." +thanos tools bucket web --objstore.config-file="..." ``` -[embedmd]:# (flags/bucket_web.txt) -```txt -usage: thanos bucket web [] +[embedmd]:# (flags/tools_bucket_web.txt $) +```$ +usage: thanos tools bucket web [] Web interface for remote storage bucket @@ -157,19 +213,21 @@ Flags: ``` -### Verify +### Bucket Verify -`bucket verify` is used to verify and optionally repair blocks within the specified bucket. +`tools bucket verify` is used to verify and optionally repair blocks within the specified bucket. Example: ``` -$ thanos bucket verify --objstore.config-file="..." +thanos tools bucket verify --objstore.config-file="..." ``` -[embedmd]:# (flags/bucket_verify.txt) -```txt -usage: thanos bucket verify [] +When using the `--repair` option, make sure that the compactor job is disabled first. + +[embedmd]:# (flags/tools_bucket_verify.txt $) +```$ +usage: thanos tools bucket verify [] Verify all blocks in the bucket against specified issues @@ -219,22 +277,34 @@ Flags: Block IDs to verify (and optionally repair) only. If none is specified, all blocks will be verified. Repeated field + --delete-delay=0s Duration after which blocks marked for deletion would + be deleted permanently from source bucket by + compactor component. If delete-delay is non zero, + blocks will be marked for deletion and compactor + component is required to delete blocks from source + bucket. If delete-delay is 0, blocks will be deleted + straight away. Use this if you want to get rid of or + move the block immediately. Note that deleting blocks + immediately can cause query failures, if store + gateway still has the block loaded, or compactor is + ignoring the deletion because it's compacting the + block at the same time. ``` -### ls +### Bucket ls -`bucket ls` is used to list all blocks in the specified bucket. +`tools bucket ls` is used to list all blocks in the specified bucket. Example: ``` -$ thanos bucket ls -o json --objstore.config-file="..." +thanos tools bucket ls -o json --objstore.config-file="..." ``` -[embedmd]:# (flags/bucket_ls.txt) -```txt -usage: thanos bucket ls [] +[embedmd]:# (flags/tools_bucket_ls.txt $) +```$ +usage: thanos tools bucket ls [] List all blocks in the bucket @@ -268,18 +338,19 @@ Flags: ``` -### inspect +### Bucket inspect -`bucket inspect` is used to inspect buckets in a detailed way using stdout in ASCII table format. +`tools bucket inspect` is used to inspect buckets in a detailed way using stdout in ASCII table format. Example: + ``` -$ thanos bucket inspect -l environment=\"prod\" --objstore.config-file="..." +thanos tools bucket inspect -l environment=\"prod\" --objstore.config-file="..." ``` -[embedmd]:# (flags/bucket_inspect.txt) -```txt -usage: thanos bucket inspect [] +[embedmd]:# (flags/tools_bucket_inspect.txt $) +```$ +usage: thanos tools bucket inspect [] Inspect all blocks in the bucket in detailed, table-like way @@ -320,20 +391,20 @@ Flags: ``` -### replicate +### Bucket replicate -`bucket replicate` is used to replicate buckets from one object storage to another. +`bucket tools replicate` is used to replicate buckets from one object storage to another. NOTE: Currently it works only with Thanos blocks (meta.json has to have Thanos metadata). Example: ``` -$ thanos bucket replicate --objstore.config-file="..." --objstore-to.config="..." +thanos tools bucket replicate --objstore.config-file="..." --objstore-to.config="..." ``` -[embedmd]:# (flags/bucket_replicate.txt) -```txt -usage: thanos bucket replicate [] +[embedmd]:# (flags/tools_bucket_replicate.txt $) +```$ +usage: thanos tools bucket replicate [] Replicate data from one object storage to another. NOTE: Currently it works only with Thanos blocks (meta.json has to have Thanos metadata). @@ -389,3 +460,111 @@ Flags: --single-run Run replication only one time, then exit. ``` + +### Bucket downsample + +`tools bucket downsample` is used to continuously downsample blocks in an object store bucket as a service. +It implements the downsample API on top of historical data in an object storage bucket. + +```bash +thanos tools bucket downsample \ + --data-dir "/local/state/data/dir" \ + --objstore.config-file "bucket.yml" +``` + +The content of `bucket.yml`: + +```yaml +type: GCS +config: + bucket: example-bucket +``` + +[embedmd]:# (flags/tools_bucket_downsample.txt $) +```$ +usage: thanos tools bucket downsample [] + +continuously downsamples blocks in an object store bucket + +Flags: + -h, --help Show context-sensitive help (also try --help-long + and --help-man). + --version Show application version. + --log.level=info Log filtering level. + --log.format=logfmt Log format to use. Possible options: logfmt or + json. + --tracing.config-file= + Path to YAML file with tracing configuration. See + format details: + https://thanos.io/tracing.md/#configuration + --tracing.config= + Alternative to 'tracing.config-file' flag (lower + priority). Content of YAML file with tracing + configuration. See format details: + https://thanos.io/tracing.md/#configuration + --objstore.config-file= + Path to YAML file that contains object store + configuration. See format details: + https://thanos.io/storage.md/#configuration + --objstore.config= + Alternative to 'objstore.config-file' flag (lower + priority). Content of YAML file that contains + object store configuration. See format details: + https://thanos.io/storage.md/#configuration + --http-address="0.0.0.0:10902" + Listen host:port for HTTP endpoints. + --http-grace-period=2m Time to wait after an interrupt received for HTTP + Server. + --data-dir="./data" Data directory in which to cache blocks and + process downsamplings. + +``` +## Rules-check + +The `tools rules-check` subcommand contains tools for validation of Prometheus rules. + +This is allowing to check the rules with the same validation as is used by the Thanos rule node. + +NOTE: The check is equivalent to the `promtool check rules` with addition of Thanos rule extended rules file syntax, +which includes `partial_response_strategy` field which `promtool` does not allow. + +If the check fails the command fails with exit code `1`, otherwise `0`. + +Example: + +``` +./thanos tools rules-check --rules cmd/thanos/testdata/rules-files/*.yaml +``` + +[embedmd]:# (flags/tools_rules-check.txt $) +```$ +usage: thanos tools rules-check --rules=RULES + +Check if the rule files are valid or not. + +Flags: + -h, --help Show context-sensitive help (also try --help-long and + --help-man). + --version Show application version. + --log.level=info Log filtering level. + --log.format=logfmt Log format to use. Possible options: logfmt or json. + --tracing.config-file= + Path to YAML file with tracing configuration. See + format details: + https://thanos.io/tracing.md/#configuration + --tracing.config= + Alternative to 'tracing.config-file' flag (lower + priority). Content of YAML file with tracing + configuration. See format details: + https://thanos.io/tracing.md/#configuration + --rules=RULES ... The rule files glob to check (repeated). + +``` + +#### Probes + +- The downsample service exposes two endpoints for probing: + - `/-/healthy` starts as soon as initial setup completed. + - `/-/ready` starts after all the bootstrapping completed (e.g object store bucket connection) and ready to serve traffic. + +> NOTE: Metric endpoint starts immediately so, make sure you set up readiness probe on designated HTTP `/-/ready` path. diff --git a/docs/contributing/coding-style-guide.md b/docs/contributing/coding-style-guide.md new file mode 100644 index 0000000000..361cccd27c --- /dev/null +++ b/docs/contributing/coding-style-guide.md @@ -0,0 +1,1073 @@ +--- +title: Coding Style Guide +type: docs +menu: contributing +--- + +# Thanos Coding Style Guide + +This document details the official style guides for the various languages we use in the Thanos project. +Feel free to familiarize yourself with and refer to this document during code reviews. If something in our codebase does not match the style, it means it +was missed or it was written before this document. Help wanted to fix it! (: + +Generally, we care about: + +* Readability, so low [Cognitive Load](https://www.dabapps.com/blog/cognitive-load-programming/). +* Maintainability. We avoid the code that **surprises**. +* Performance only for critical path and without compromising readability. +* Testability. Even if it means some changes to the production code, like `timeNow func() time.Time` mock. +* Consistency: If some pattern repeats, it means fewer surprises. + +Some style is enforced by our linters and is covered in separate smaller sections. Please look there if you want to +embrace some of the rules in your own project! For Thanos developers, we recommend reading sections about rules to manually apply during +development. Some of those are currently impossible to detect with linters. Ideally, everything would be automated. (: + +## TOC + +- [Thanos Coding Style Guide](coding-style-guide.md#thanos-coding-style-guide) + * [TOC](coding-style-guide.md#toc) +- [Go](coding-style-guide.md#go) + * [Development / Code Review](coding-style-guide.md#development-code-review) + + [Reliability](coding-style-guide.md#reliability) + - [Defers: Don't Forget to Check Returned Errors](coding-style-guide.md#defers-don-t-forget-to-check-returned-errors) + - [Exhaust Readers](coding-style-guide.md#exhaust-readers) + - [Avoid Globals](coding-style-guide.md#avoid-globals) + - [Never Use Panics](coding-style-guide.md#never-use-panics) + - [Avoid Using the `reflect` or `unsafe` Packages](coding-style-guide.md#avoid-using-the-reflect-or-unsafe-packages) + - [Avoid variable shadowing](coding-style-guide.md#avoid-variable-shadowing) + + [Performance](coding-style-guide.md#performance) + - [Pre-allocating Slices and Maps](coding-style-guide.md#pre-allocating-slices-and-maps) + - [Reuse arrays](coding-style-guide.md#reuse-arrays) + + [Readability](coding-style-guide.md#readability) + - [Keep the Interface Narrow; Avoid Shallow Functions](coding-style-guide.md#keep-the-interface-narrow-avoid-shallow-functions) + - [Use Named Return Parameters Carefully](coding-style-guide.md#use-named-return-parameters-carefully) + - [Clean Defer Only if Function Fails](coding-style-guide.md#clean-defer-only-if-function-fails) + - [Explicitly Handled Returned Errors](coding-style-guide.md#explicitly-handled-returned-errors) + - [Avoid Defining Variables Used Only Once.](coding-style-guide.md#avoid-defining-variables-used-only-once) + - [Only Two Ways of Formatting Functions/Methods](coding-style-guide.md#only-two-ways-of-formatting-functions-methods) + - [Control Structure: Prefer early returns and avoid `else`](coding-style-guide.md#control-structure-prefer-early-returns-and-avoid-else) + - [Wrap Errors for More Context; Don't Repeat "failed ..." There.](coding-style-guide.md#wrap-errors-for-more-context-don-t-repeat-failed-there) + - [Use the Blank Identifier `_`](coding-style-guide.md#use-the-blank-identifier) + - [Rules for Log Messages](coding-style-guide.md#rules-for-log-messages) + - [Comment Necessary Surprises](coding-style-guide.md#comment-necessary-surprises) + + [Testing](coding-style-guide.md#testing) + - [Table Tests](coding-style-guide.md#table-tests) + - [Tests for Packages / Structs That Involve `time` package.](coding-style-guide.md#tests-for-packages-structs-that-involve-time-package) + * [Enforced by Linters](coding-style-guide.md#enforced-by-linters) + - [Avoid Prints](coding-style-guide.md#avoid-prints) + - [Ensure Prometheus Metric Registration](coding-style-guide.md#ensure-prometheus-metric-registration) + - [go vet](coding-style-guide.md#go-vet) + - [golangci-lint](coding-style-guide.md#golangci-lint) + - [misspell](coding-style-guide.md#misspell) + - [Comments Should be Full Sentences](coding-style-guide.md#comments-should-be-full-sentences) +- [Bash](coding-style-guide.md#bash) + +Table of contents generated with markdown-toc + +# Go + +For code written in [Go](https://golang.org/) we use the standard Go style guides ([Effective Go](https://golang.org/doc/effective_go.html), +[CodeReviewComments](https://github.com/golang/go/wiki/CodeReviewComments)) with a few additional rules that make certain areas stricter +than the standard guides. This ensures even better consistency in modern distributed system databases like Thanos, where reliability, performance, +and maintainability are extremely important. + +Go in Thanos + + + +## Development / Code Review + +In this section, we will go through rules that on top of the standard guides that we apply during development and code reviews. + +NOTE: If you know that any of those rules can be enabled by some linter, automatically, let us know! (: + +### Reliability + +The coding style is not purely about what is ugly and what is not. It's mainly to make sure programs are reliable for +running on production 24h per day without causing incidents. The following rules are describing some unhealthy patterns +we have seen across the Go community that are often forgotten. Those things can be considered bugs or can significantly +increase the chances of introducing a bug. + +#### Defers: Don't Forget to Check Returned Errors + +It's easy to forget to check the error returned by a `Close` method that we deferred. + +```go +f, err := os.Open(...) +if err != nil { + // handle.. +} +defer f.Close() // What if an error occurs here? + +// Write something to file... etc. +``` + +Unchecked errors like this can lead to major bugs. Consider the above example: the `*os.File` `Close` method can be responsible +for actually flushing to the file, so if an error occurs at that point, the whole **write might be aborted!** 😱 + +Always check errors! To make it consistent and not distracting, use our [runutil](https://pkg.go.dev/github.com/thanos-io/thanos@v0.11.0/pkg/runutil?tab=doc) +helper package, e.g.: + +```go +// Use `CloseWithErrCapture` if you want to close and fail the function or +// method on a `f.Close` error (make sure the `error` return argument is +// named as `err`). If the error is already present, `CloseWithErrCapture` +// will append (not wrap) the `f.Close` error if any. +defer runutil.CloseWithErrCapture(&err, f, "close file") + +// Use `CloseWithLogOnErr` if you want to close and log error on `Warn` +// level on a `f.Close` error. +defer runutil.CloseWithLogOnErr(logger, f, "close file") +``` + + + + + + + +
Avoid 🔥
+ +```go +func writeToFile(...) error { + f, err := os.Open(...) + if err != nil { + return err + } + defer f.Close() // What if an error occurs here? + + // Write something to file... + return nil +} +``` + +
Better 🤓
+ +```go +func writeToFile(...) (err error) { + f, err := os.Open(...) + if err != nil { + return err + } + // Now all is handled well. + defer runutil.CloseWithErrCapture(&err, f, "close file") + + // Write something to file... + return nil +} +``` + +
+ +#### Exhaust Readers + +One of the most common bugs is forgetting to close or fully read the bodies of HTTP requests and responses, especially on +error. If you read the body of such structures, you can use the [runutil](https://pkg.go.dev/github.com/thanos-io/thanos@v0.11.0/pkg/runutil?tab=doc) +helper as well: + +```go +defer runutil.ExhaustCloseWithLogOnErr(logger, resp.Body, "close response") +``` + + + + + + + +
Avoid 🔥
+ +```go +resp, err := http.Get("http://example.com/") +if err != nil { + // handle... +} +defer runutil.CloseWithLogOnErr(logger, resp.Body, "close response") + +scanner := bufio.NewScanner(resp.Body) +// If any error happens and we return in the middle of scanning +// body, we can end up with unread buffer, which +// will use memory and hold TCP connection! +for scanner.Scan() { +``` + +
Better 🤓
+ +```go +resp, err := http.Get("http://example.com/") +if err != nil { + // handle... +} +defer runutil.ExhaustCloseWithLogOnErr(logger, resp.Body, "close response") + +scanner := bufio.NewScanner(resp.Body) +// If any error happens and we return in the middle of scanning body, +// defer will handle all well. +for scanner.Scan() { +``` + +
+ +#### Avoid Globals + +No globals other than `const` are allowed. Period. +This means also, no `init` functions. + +#### Never Use Panics + +Never use them. If some dependency uses it, use [recover](https://golang.org/doc/effective_go.html#recover). Also, consider +avoiding that dependency. 🙈 + +#### Avoid Using the `reflect` or `unsafe` Packages + +Use those only for very specific, critical cases. Especially `reflect` tend to be very slow. For testing code, it's fine to use reflect. + +#### Avoid variable shadowing + +Variable shadowing is when you use the same variable name in a smaller scope that "shadows". This is very +dangerous as it leads to many surprises. It's extremely hard to debug such problems as they might appear in unrelated parts of the code. +And what's broken is tiny `:` or lack of it. + + + + + + + +
Avoid 🔥
+ +```go + var client ClientInterface + if clientTypeASpecified { + // Ups - typo, should be =` + client, err := clienttypea.NewClient(...) + if err != nil { + // handle err + } + level.Info(logger).Log("msg", "created client", "type", client.Type) + } else { + // Ups - typo, should be =` + client, err := clienttypea.NewClient(...) + level.Info(logger).Log("msg", "noop client will be used", "type", client.Type) + } + + // In some further deeper part of the code... + resp, err := client.Call(....) // nil pointer panic! +``` + +
Better 🤓
+ +```go + var client ClientInterface = NewNoop(...) + if clientTypeASpecified { + c, err := clienttypea.NewClient(...) + if err != nil { + // handle err + } + client = c + } + level.Info(logger).Log("msg", "created client", "type", c.Type) + + resp, err := client.Call(....) +``` + +
+ +This is also why we recommend to scope errors if you can: + +```go + if err := doSomething(); err != nil { + // handle err + } +``` + +While it's not yet configured, we might think consider not permitting variable shadowing with [`golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow`](https://godoc.org/golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow) +in future. There was even Go 2 proposal for [disabling this in the language itself, but was rejected](https://github.com/golang/go/issues/21114): + +Similar to this problem is the package name shadowing. While it is less dangerous, it can cause similar issues, so avoid package shadowing if you can. + +### Performance + +After all, Thanos system is a database that has to perform queries over terabytes of data within human friendly response times. +This might require some additional patterns in our code. With those patterns, we try to not sacrifice the readability and apply those only +on the critical code paths. + +**Keep in mind to always measure the results.** The Go performance relies on many hidden things and tweaks, so the good +micro benchmark, following with the real system load test is in most times required to tell if optimization makes sense. + +#### Pre-allocating Slices and Maps + +Try to always preallocate slices and map. If you know the number of elements you want to put +apriori, use that knowledge! This significantly improves the latency of such code. Consider this as micro optimization, +however, it's a good pattern to do it always, as it does not add much complexity. Performance wise, it's only relevant for critical, +code paths with big arrays. + +NOTE: This is because, in very simple view, the Go runtime allocates 2 times the current size. So if you expect million of elements, Go will do many allocations +on `append` in between instead of just one if you preallocate. + + + + + + + +
Avoid 🔥
+ +```go +func copyIntoSliceAndMap(biggy []string) (a []string, b map[string]struct{}) + b = map[string]struct{}{} + + for _, item := range biggy { + a = append(a, item) + b[item] = struct{} + } +} +``` + +
Better 🤓
+ +```go +func copyIntoSliceAndMap(biggy []string) (a []string, b map[string]struct{}) + b = make(map[string]struct{}, len(biggy)) + a = make([]string, len(biggy)) + + // Copy will not even work without pre-allocation. + copy(a, biggy) + for _, item := range biggy { + b[item] = struct{} + } +} +``` + +
+ +#### Reuse arrays + +To extend the above point, there are cases where you don't need to allocate new space in memory all the time. If you repeat +the certain operation on slices sequentially and you just release the array on every iteration, it's reasonable to reuse +the underlying array for those. This can give quite enormous gains for critical paths. +Unfortunately, currently there is no way to reuse the underlying array for maps. + +NOTE: Why you cannot just allocate slice and release and in new iteration allocate and release again etc? Go should know it has +available space and just reuses that no? (: Well, it's not that easy. TL;DR is that Go Garbage Collection runs periodically or on certain cases +(big heap), but definitely not on every iteration of your loop (that would be super slow). Read more in details [here](https://about.sourcegraph.com/go/gophercon-2018-allocator-wrestling). + + + + + + + +
Avoid 🔥
+ +```go +var messages []string{} +for _, msg := range recv { + messages = append(messages, msg) + + if len(messages) > maxMessageLen { + marshalAndSend(messages) + // This creates new array. Previous array + // will be garbage collected only after + // some time (seconds), which + // can create enormous memory pressure. + messages = []string{} + } +} +``` + +
Better 🤓
+ +```go +var messages []string{} +for _, msg := range recv { + messages = append(messages, msg) + + if len(messages) > maxMessageLen { + marshalAndSend(messages) + // Instead of new array, reuse + // the same, with the same capacity, + // just length equals to zero. + messages = messages[:0] + } +} +``` + +
+ +### Readability + +The part that all Gophers love ❤️ How to make code more readable? + +For the Thanos Team, readability is about programming in a way that does not surprise the reader of the code. All the details +and inconsistencies can distract or mislead the reader, so every character or newline might matter. That's why we might be spending +more time on every Pull Requests' review, especially in the beginning, but for a good reason! To make sure we can quickly understand, +extend and fix problems with our system. + +#### Keep the Interface Narrow; Avoid Shallow Functions + +This is connected more to the API design than coding, but even during small coding decisions it matter. For example how you define functions +or methods. There are two general rules: + +* Simpler (usually it means smaller) interfaces are better. This might mean a smaller, simpler function signature as well as fewer methods +in the interfaces. Try to group interfaces based on functionality to expose at max 1-3 methods if possible. + + + + + + + +
Avoid 🔥
+ +```go +// Compactor aka: The Big Boy. Such big interface is really useless ): +type Compactor interface { + Compact(ctx context.Context) error + FetchMeta(ctx context.Context) (metas map[ulid.ULID]*metadata.Meta, partial map[ulid.ULID]error, err error) + UpdateOnMetaChange(func([]metadata.Meta, error)) + SyncMetas(ctx context.Context) error + Groups() (res []*Group, err error) + GarbageCollect(ctx context.Context) error + ApplyRetentionPolicyByResolution(ctx context.Context, logger log.Logger, bkt objstore.Bucket) error + BestEffortCleanAbortedPartialUploads(ctx context.Context, bkt objstore.Bucket) + DeleteMarkedBlocks(ctx context.Context) error + Downsample(ctx context.Context, logger log.Logger, metrics *DownsampleMetrics, bkt objstore.Bucket) error +} +``` + +
Better 🤓
+ +```go +// Smaller interfaces with a smaller number of arguments allow functional grouping, clean composition and clear testability. +type Compactor interface { + Compact(ctx context.Context) error + +} + +type Downsampler interface { + Downsample(ctx context.Context) error +} + +type MetaFetcher interface { + Fetch(ctx context.Context) (metas map[ulid.ULID]*metadata.Meta, partial map[ulid.ULID]error, err error) + UpdateOnChange(func([]metadata.Meta, error)) +} + +type Syncer interface { + SyncMetas(ctx context.Context) error + Groups() (res []*Group, err error) + GarbageCollect(ctx context.Context) error +} + +type RetentionKeeper interface { + Apply(ctx context.Context) error +} + +type Cleaner interface { + DeleteMarkedBlocks(ctx context.Context) error + BestEffortCleanAbortedPartialUploads(ctx context.Context) +} +``` + +
+ +* It's better if you can hide more unnecessary complexity from the user. This means that having shallow function introduce +more cognitive load to understand the function name or navigate to implementation to understand it better. It might be much +more readable to inline those few lines directly on the caller side. + + + + + + + +
Avoid 🔥
+ +```go + // Some code... + s.doSomethingAndHandleError() + + // Some code... +} + +func (s *myStruct) doSomethingAndHandleError() { + if err := doSomething(); err != nil { + level.Error(s.logger).Log("msg" "failed to do something; sorry", "err", err) + } +} +``` + +
Better 🤓
+ + +```go + // Some code... + if err := doSomething(); err != nil { + level.Error(s.logger).Log("msg" "failed to do something; sorry", "err", err) + } + + // Some code... +} +``` + +
+ +This is a little bit connected to `There should be one-- and preferably only one --obvious way to do it` and [`DRY`](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) +rules. If you have more ways of doing something than one, it means you have a wider interface, allowing more opportunities for +errors, ambiguity and maintenance burden. + + + + + + + +
Avoid 🔥
+ +```go +// We have here SIX potential ways the caller can get an ID. Can you find all of them? + +type Block struct { + // Things... + ID ulid.ULID + + mtx sync.Mutex +} + +func (b *Block) Lock() { b.mtx.Lock() } + +func (b *Block) Unlock() { b.mtx.Unlock() } + +func (b *Block) ID() ulid.ULID { + b.mtx.Lock() + defer b.mtx.Unlock() + return b.ID +} + +func (b *Block) IDNoLock() ulid.ULID { return b.ID } +``` + +
Better 🤓
+ +```go +type Block struct { + // Things... + + id ulid.ULID + mtx sync.Mutex +} + +func (b *Block) ID() ulid.ULID { + b.mtx.Lock() + defer b.mtx.Unlock() + return b.id +} +``` + +
+ +#### Use Named Return Parameters Carefully + +It's OK to name return parameters if the types do not give enough information about what function or method actually returns. +Another use case is when you want to define a variable, e.g. a slice. + +**IMPORTANT:** never use naked `return` statements with named return parameters. This compiles but it makes returning values +implicit and thus more prone to surprises. + +#### Clean Defer Only if Function Fails + +There is a way to sacrifice defer in order to properly close all on each error. Repetitions makes it easier to make error +and forget something when changing the code, so on-error deferring is doable: + + + + + + + +
Avoid 🔥
+ +```go +func OpenSomeFileAndDoSomeStuff() (*os.File, error) { + f, err := os.OpenFile("file.txt", os.O_RDONLY, 0) + if err != nil { + return nil, err + } + + if err := doStuff1(); err != nil { + runutil.CloseWithErrCapture(&err, f, "close file") + return nil, err + } + if err := doStuff2(); err != nil { + runutil.CloseWithErrCapture(&err, f, "close file") + return nil, err + } + if err := doStuff232241(); err != nil { + // Ups.. forgot to close file here. + return nil, err + } + return f, nil +} +``` + +
Better 🤓
+ +```go +func OpenSomeFileAndDoSomeStuff() (f *os.File, err error) { + f, err = os.OpenFile("file.txt", os.O_RDONLY, 0) + if err != nil { + return nil, err + } + defer func() { + if err != nil { + runutil.CloseWithErrCapture(&err, f, "close file") + } + } + + if err := doStuff1(); err != nil { + return nil, err + } + if err := doStuff2(); err != nil { + return nil, err + } + if err := doStuff232241(); err != nil { + return nil, err + } + return f, nil +} +``` +
+ +#### Explicitly Handle Returned Errors + +Always handle returned errors. It does not mean you cannot "ignore" the error for some reason, e.g. if we know implementation +will not return anything meaningful. You can ignore the error, but do so explicitly: + + + + + + + +
Avoid 🔥
+ +```go +someMethodThatReturnsError(...) +``` + +
Better 🤓
+ + +```go +_ = someMethodThatReturnsError(...) +``` + +
+ +The exception: well-known cases such as `level.Debug|Warn` etc and `fmt.Fprint*` + +#### Avoid Defining Variables Used Only Once. + +It's tempting to define a variable as an intermittent step to create something bigger. Avoid defining +such a variable if it's used only once. When you create a variable *the reader* expects some other usage of this variable than +one, so it can be annoying to every time double check that and realize that it's only used once. + + + + + + + +
Avoid 🔥
+ +```go + someConfig := a.GetConfig() + address124 := someConfig.Addresses[124] + addressStr := fmt.Sprintf("%s:%d", address124.Host, address124.Port) + + c := &MyType{HostPort: addressStr, SomeOther: thing} + return c +``` + +
Better 🤓
+ +```go + // This variable is required for potentially consistent results. It is used twice. + someConfig := a.FetchConfig() + return &MyType{ + HostPort: fmt.Sprintf("%s:%d", someConfig.Addresses[124].Host, someConfig.Addresses[124].Port), + SomeOther: thing, + } +``` + +
+ +#### Only Two Ways of Formatting Functions/Methods + +Prefer function/method definitions with arguments in a single line. If it's too wide, put each argument on a new line. + + + + + + + +
Avoid 🔥
+ +```go +func function(argument1 int, argument2 string, + argument3 time.Duration, argument4 someType, + argument5 float64, argument6 time.Time, +) (ret int, err error) { +``` + +
Better 🤓
+ +```go +func function( + argument1 int, + argument2 string, + argument3 time.Duration, + argument4 someType, + argument5 float64, + argument6 time.Time, +) (ret int, err error) +``` + +
+ +This applies for both calling and defining method / function. + +NOTE: One exception would be when you expect the variadic (e.g. `...string`) arguments to be filled in pairs, e.g: + +```go +level.Info(logger).Log( + "msg", "found something epic during compaction; this looks amazing", + "compNumber", compNumber, + "block", id, + "elapsed", timeElapsed, +) +``` + +#### Control Structure: Prefer early returns and avoid `else` + +In most of the cases, you don't need `else`. You can usually use `continue`, `break` or `return` to end an `if` block. +This enables having one less indent and better consistency so code is more readable. + + + + + + + +
Avoid 🔥
+ +```go +for _, elem := range elems { + if a == 1 { + something[i] = "yes" + } else + something[i] = "no" + } +} +``` + +
Better 🤓
+ +```go +for _, elem := range elems { + if a == 1 { + something[i] = "yes" + continue + } + something[i] = "no" +} +``` + +
+ +#### Wrap Errors for More Context; Don't Repeat "failed ..." There. + +We use [`pkg/errors`](https://github.com/pkg/errors) package for `errors`. We prefer it over standard wrapping with `fmt.Errorf` + `%w`, +as `errors.Wrap` is explicit. It's easy to by accident replace `%w` with `%v` or to add extra inconsistent characters to the string. + +Use [`pkg/errors.Wrap`](https://github.com/pkg/errors) to wrap errors for future context when errors occur. It's recommended +to add more interesting variables to add context using `errors.Wrapf`, e.g. file names, IDs or things that fail, etc. + +NOTE: never prefix wrap messages with wording like `failed ... ` or `error occurred while...`. Just describe what we +wanted to do when the failure occurred. Those prefixes are just noise. We are wrapping error, so it's obvious that some error +occurred, right? (: Improve readability and consider avoiding those. + + + + + + + +
Avoid 🔥
+ +```go +if err != nil { + return fmt.Errorf("error while reading from file %s: %w", f.Name, err) +} +``` + +
Better 🤓
+ +```go +if err != nil { + return errors.Wrapf(err, "read file %s", f.Name) +} +``` + +
+ +#### Use the Blank Identifier `_` + +Blank identifiers are very useful to mark variables that are not used. Consider the following cases: + +```go +// We don't need the second return parameter. +// Let's use the blank identifier instead. +a, _, err := function1(...) +if err != nil { + // handle err +} +``` + +```go +// We don't need to use this variable, we +// just want to make sure TypeA implements InterfaceA. +var _ InterfaceA = TypeA +``` + +```go +// We don't use context argument; let's use the blank +// identifier to make it clear. +func (t *Type) SomeMethod(_ context.Context, abc int) error { +``` + +#### Rules for Log Messages + +We use [go-kit logger](https://github.com/go-kit/kit/tree/master/log) in Thanos. This means that we expect log lines +to have a certain structure. Structure means that instead of adding variables to the message, those should be passed as +separate fields. Keep in mind that all log lines in Thanos should be `lowercase` (readability and consistency) and +all struct keys are using `camelCase`. It's suggested to keep key names short and consistent. For example, if +we always use `block` for block ID, let's not use in the other single log message `id`. + + + + + + + +
Avoid 🔥
+ +```go +level.Info(logger).Log("msg", fmt.Sprintf("Found something epic during compaction number %v. This looks amazing.", compactionNumber), + "block_id", id, "elapsed-time", timeElapsed) +``` + +
Better 🤓
+ +```go +level.Info(logger).Log("msg", "found something epic during compaction; this looks amazing", "compNumber", compNumber, +"block", id, "elapsed", timeElapsed) +``` + +
+ +Additionally, there are certain rules we suggest while using different log levels: + +* level.Info: Should always have `msg` field. It should be used only for important events that we expect to happen not too +often. +* level.Debug: Should always have `msg` field. It can be a bit more spammy, but should not be everywhere as well. Use it +only when you want to really dive into some problems in certain areas. +* level.Warn: Should have either `msg` or `err` or both fields. They should warn about events that are suspicious and to investigate +but the process can gracefully mitigate it. Always try to describe *how* it was mitigated, what action will be performed e.g. `value will be skipped` +* level.Error: Should have either `msg` or `err` or both fields. Use it only for a critical event. + +#### Comment Necessary Surprises + +Comments are not the best. They age quickly and the compiler does not fail if you will forget to update them. So use comments +only when necessary. **And it is necessary to comment on code that can surprise the user.** Sometimes, complexity +is necessary, for example for performance. Comment in this case why such optimization was needed. If something +was done temporarily add `TODO(): `. + +### Testing + +#### Table Tests + +Use table-driven tests that use [t.Run](https://blog.golang.org/subtests) for readability. They are easy to read +and allows to add a clean description of each test case. Adding or adapting test cases is also easier. + + + + + + + +
Avoid 🔥
+ +```go +host, port, err := net.SplitHostPort("1.2.3.4:1234") +testutil.Ok(t, err) +testutil.Equals(t, "1.2.3.4", host) +testutil.Equals(t, "1234", port) + +host, port, err = net.SplitHostPort("1.2.3.4:something") +testutil.Ok(t, err) +testutil.Equals(t, "1.2.3.4", host) +testutil.Equals(t, "http", port) + +host, port, err = net.SplitHostPort(":1234") +testutil.Ok(t, err) +testutil.Equals(t, "", host) +testutil.Equals(t, "1234", port) + +host, port, err = net.SplitHostPort("yolo") +testutil.NotOk(t, err) +``` + +
Better 🤓
+ +```go +for _, tcase := range []struct{ + name string + + input string + + expectedHost string + expectedPort string + expectedErr error +}{ + { + name: "host and port", + + input: "1.2.3.4:1234", + expectedHost: "1.2.3.4", + expectedPort: "1234", + }, + { + name: "host and named port", + + input: "1.2.3.4:something", + expectedHost: "1.2.3.4", + expectedPort: "something", + }, + { + name: "just port", + + input: ":1234", + expectedHost: "", + expectedPort: "1234", + }, + { + name: "not valid hostport", + + input: "yolo", + expectedErr: errors.New("") + }, +}{ + t.Run(tcase.name, func(t *testing.T) { + host, port, err := net.SplitHostPort(tcase.input) + if tcase.expectedErr != nil { + testutil.NotOk(t, err) + testutil.Equals(t, tcase.expectedErr, err) + return + } + testutil.Ok(t, err) + testutil.Equals(t, tcase.expectedHost, host) + testutil.Equals(t, tcase.expectedPort, port) + }) +} +``` + +
+ +#### Tests for Packages / Structs That Involve `time` package. + +Avoid unit testing based on real-time. Always try to mock time that is used within struct by using, for example, a `timeNow func() time.Time` field. +For production code, you can initialize the field with `time.Now`. For test code, you can set a custom time that will be used by the struct. + + + + + + + +
Avoid 🔥
+ +```go +func (s *SomeType) IsExpired(created time.Time) bool { + // Code is hardly testable. + return time.Since(created) >= s.expiryDuration +} +``` + +
Better 🤓
+ +```go +func (s *SomeType) IsExpired(created time.Time) bool { + // s.timeNow is time.Now on production, mocked in tests. + return created.Add(s.expiryDuration).Before(s.timeNow()) +} +``` + +
+ +## Enforced by Linters + +This is the list of rules we ensure automatically. This section is for those who are curious why such linting rules +were added or want similar ones in their Go project. 🤗 + +#### Avoid Prints + +Never use `print`. Always use a passed `go-kit/log.Logger`. + +Ensured [here](https://github.com/thanos-io/thanos/blob/40526f52f54d4501737e5246c0e71e56dd7e0b2d/Makefile#L311). + +#### Ensure Prometheus Metric Registration + +It's very easy to forget to add Prometheus metrics (e.g a `prometheus.Counter`) into a `registry.MustRegister` function. +To avoid this, we ensure all metrics are created via `promtest.With(r).New*` and we disallow the old type of registration. +Read more about the problem [here](https://github.com/thanos-io/thanos/issues/2102). + +Ensured [here](https://github.com/thanos-io/thanos/blob/40526f52f54d4501737e5246c0e71e56dd7e0b2d/Makefile#L308). + +#### go vet + +Standard Go vet is quite strict, but for a good reason. Always vet your Go code! + +Ensured [here](https://github.com/thanos-io/thanos/blob/40526f52f54d4501737e5246c0e71e56dd7e0b2d/Makefile#L313). + +#### golangci-lint + +[golangci-lint](https://github.com/golangci/golangci-lint) is an amazing tool that allows running a set of different custom +linters from the Go community against your code. Give it a star and use it. (: + +Ensured [here](https://github.com/thanos-io/thanos/blob/40526f52f54d4501737e5246c0e71e56dd7e0b2d/Makefile#L315) with +[those linters](https://github.com/thanos-io/thanos/blob/40526f52f54d4501737e5246c0e71e56dd7e0b2d/.golangci.yml#L31) enabled. + +#### misspell + +Misspell is amazing, it catches typos in comments and docs. + +No Grammarly plugin for this yet ): (We wish). + +Ensured [here](https://github.com/thanos-io/thanos/blob/40526f52f54d4501737e5246c0e71e56dd7e0b2d/Makefile#L317). + +#### Comments Should be Full Sentences + +All comments should be full sentences. They should start with an uppercase letter and end with a period. + +Ensured [here](https://github.com/thanos-io/thanos/blob/40526f52f54d4501737e5246c0e71e56dd7e0b2d/Makefile#L194). + +# Bash + +Overall try to NOT use bash. For scripts longer than 30 lines, consider writing it in Go as we did [here](https://github.com/thanos-io/thanos/blob/55cb8ca38b3539381dc6a781e637df15c694e50a/scripts/copyright/copyright.go). + +If you have to, we follow the Google Shell style guide: https://google.github.io/styleguide/shellguide.html diff --git a/docs/img/go-in-thanos.jpg b/docs/img/go-in-thanos.jpg new file mode 100644 index 0000000000..abd6e1d243 Binary files /dev/null and b/docs/img/go-in-thanos.jpg differ diff --git a/docs/integrations.md b/docs/integrations.md index e8df4f21c0..284ec6c371 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -18,10 +18,17 @@ metrics from other storages. Below you can find some public integrations with other systems through StoreAPI: -### OpenTSDB +### OpenTSDB as StoreAPI [Geras](https://github.com/G-Research/geras) is an OpenTSDB integration service which can connect your OpenTSDB cluster to Thanos. Geras exposes the Thanos Storage API, thus other Thanos components can query OpenTSDB via Geras, providing a unified query interface over OpenTSDB and Prometheus. Although OpenTSDB is able to aggregte the data, it's not supported by Geras at the moment. + +### StoreAPI as Prometheus Remote Read + +[thanos-remote-read](https://github.com/G-Research/thanos-remote-read) is another StoreAPI integration from our friends at G-Research. + +It's a proxy, that allows exposing any Thanos service (or anything that exposes gRPC StoreAPI e.g. [Querier](components/query.md)) via Prometheus [remote read](https://github.com/prometheus/prometheus/blob/38d32e06862f6b72700f67043ce574508b5697f0/prompb/remote.proto#L27) +protocol. This means that you can connect Thanos and expose its data to any remote-read compatible applications including [Prometheus itself.](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_read) diff --git a/docs/operating/_index.md b/docs/operating/_index.md new file mode 100644 index 0000000000..1e0094aab9 --- /dev/null +++ b/docs/operating/_index.md @@ -0,0 +1,3 @@ +--- +title: "Operating Guides:" +--- diff --git a/docs/operating/troubleshooting.md b/docs/operating/troubleshooting.md index 58fb4b0ff6..5e2b9fa3bb 100644 --- a/docs/operating/troubleshooting.md +++ b/docs/operating/troubleshooting.md @@ -5,4 +5,74 @@ menu: operating slug: /troubleshooting.md --- -Work in progress (: +# Troubleshooting; Common cases + + +## Overlaps + +**Block overlap**: Set of blocks with exactly the same external labels in meta.json and for the same time or overlapping time period. + +Thanos is designed to never end up with overlapped blocks. This means that (uncontrolled) block overlap should never happen in a healthy and well configured Thanos system. That's why there is no automatic repair for this. Since it's an unexpected incident: +* All reader components like Store Gateway will handle this gracefully (overlapped samples will be deduplicated). +* Thanos compactor will stop all activities and HALT or crash (with metric and will error log). This is because it cannot perform compactions and downsampling. In the overlap situation, we know something unexpected happened (e.g manual block upload, some malformed data etc), so it's safer to stop or crash loop (it's configurable). + +Let's take an example: + +- `msg="critical error detected; halting" err="compaction failed: compaction: pre compaction overlap check: overlaps found while gathering blocks. [mint: 1555128000000, maxt: 1555135200000, range: 2h0m0s, blocks: 2]: , ` + +In this halted example, we can read that compactor detected 2 overlapped blocks. What's interesting is that those two blocks look like they are "similar". They are exactly for the same period of time. This might mean that potential reasons are: + +* Duplicated upload with different ULID (non-persistent storage for Prometheus can cause this) +* 2 Prometheus instances are misconfigured and they are uploading the data with exactly the same external labels. This is wrong, they should be unique. + +Checking producers log for such ULID, and checking meta.json (e.g if sample stats are the same or not) helps. Checksum the index and chunks files as well to reveal if data is exactly the same, thus ok to be removed manually. + +### Reasons + +- Misconfiguraiton of sidecar/ruler: Same external labels or no external labels across many block producers. +- Running multiple compactors for single block "stream", even for short duration. +- Manually uploading blocks to the bucket. +- Eventually consistent block storage until we fully implement [RW for bucket](https://thanos.io/proposals/201901-read-write-operations-bucket.md) + +### Solutions + +- Compactor can be blocked for some time, but if it is urgent. Mitigate by removing overlap or better: Backing up somewhere else (you can rename block ULID to non-ulid). +- Who uploaded the block? Search for logs with this ULID across all sidecars/rulers. Check access logs to object storage. Check debug/metas or meta.json of problematic block to see how blocks looks like and what is the `source`. +- Determine what you misconfigured. +- If all looks sane and you double-checked everything: Then post an issue on Github, Bugs can happen but we heavily test against such problems. + +# Sidecar + +## Connection Refused + +### Description + +```shell +level=warn ts=2020-04-18T03:07:00.512902927Z caller=intrumentation.go:54 msg="changing probe status" status=not-ready reason="request flags against http://localhost:9090/api/v1/status/config: Get \"http://localhost:9090/api/v1/status/config\": dial tcp 127.0.0.1:9090: connect: connection refused" +``` +* This issue might happen when thanos is not configured properly. + +### Possible Solution + +* Make sure that prometheus is running while thanos is started. The `connection_refused` states that there is no server running in the `localhost:9090`, which is the address for prometheus in this case. + + +## Thanos not identifying Prometheus + +### Description + +```shell +level=info ts=2020-04-18T03:16:32.158536285Z caller=grpc.go:137 service=gRPC/server component=sidecar msg="internal server shutdown" err="no external labels configured on Prometheus server, uniquely identifying external labels must be configured" +``` +* This issue happens when thanos doesn't recognise prometheus + +### Possible Solution + +* Thanos requires **unique** `external_labels` for further processing. So make sure that the `external_labels` are not empty and globally unique in the prometheus config file. A possible example - + +```yml +global: + external_labels: + cluster: eu1 + replica: 0 +``` diff --git a/docs/proposals/201901-read-write-operations-bucket.md b/docs/proposals/201901-read-write-operations-bucket.md index 4658e095e7..326fe79200 100644 --- a/docs/proposals/201901-read-write-operations-bucket.md +++ b/docs/proposals/201901-read-write-operations-bucket.md @@ -2,7 +2,7 @@ title: Read-Write coordination free operational contract for object storage type: proposal menu: proposals -status: accepted +status: complete owner: bwplotka --- @@ -179,7 +179,7 @@ We schedule deletions instead of doing them straight away for 3 reasons: * In further delete steps, starting with meta.json first ensures integrity mark being deleted first, so in case of deletion process being stopped, we can treat this block as partial block (rule 4th) and delete it gracefully. Along with this, we also store information about when the block was scheduled to be deleted so that it can be deleted at a later point in time. -To do so, we create a file `compactor-meta.json` where we store information about when the block was scheduled to be deleted. +To do so, we create a file `deletion-mark.json` where we store information about when the block was scheduled to be deleted. Storing the information in a file makes it resilient to failures that result in restarts. There might be exception for malformed blocks that blocks compaction or reader operations. Since we may need to unblock the system @@ -189,7 +189,7 @@ immediately the block can be forcibly removed meaning that query failures may oc This is to make sure we don't forcibly remove block which is still loaded on reader side. -We check the `compactor-meta.json` file to identify if the block has to be deleted. After 15 minutes of marking the block to be deleted, we are ok to delete the whole block directory. +We check the `deletion-mark.json` file to identify if the block has to be deleted. After 15 minutes of marking the block to be deleted, we are ok to delete the whole block directory. ## Risks diff --git a/docs/proposals/201909_thanos_sharding.md b/docs/proposals/201909_thanos_sharding.md index b033707568..938bdf1b93 100644 --- a/docs/proposals/201909_thanos_sharding.md +++ b/docs/proposals/201909_thanos_sharding.md @@ -95,7 +95,7 @@ On each component that works on the object storage (e.g Store GW and Compactor), ### Relabelling -Similar to [promtail](https://github.com/grafana/loki/blob/master/docs/promtail.md#scrape-configs) this config will follow native +Similar to [promtail](https://github.com/grafana/loki/blob/master/docs/clients/promtail/scraping.md#relabeling) this config will follow native [Prometheus relabel-config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config) syntax. The relabel config will define filtering process done on **every** synchronization with object storage. diff --git a/docs/proposals/202001_thanos_query_health_handling.md b/docs/proposals/202001_thanos_query_health_handling.md index 3782d4b6cb..a07b19b2a4 100644 --- a/docs/proposals/202001_thanos_query_health_handling.md +++ b/docs/proposals/202001_thanos_query_health_handling.md @@ -2,7 +2,7 @@ title: Thanos Query store nodes healthiness handling type: proposal menu: proposals -status: accepted +status: complete owner: GiedriusS --- @@ -35,6 +35,7 @@ Thus, this logic needs to be changed somehow. There are a few possible options: 2. Another option could be introduced such as `--store.hold-timeout` which would be `--store.unhealthy-timeout`'s brother and we would hold the StoreAPI nodes for `max(hold_timeout, unhealthy_timeout)`. 3. Another option such as `--store.strict-mode` could be introduced which means that we would always retain the last information of the StoreAPI nodes of the last successful check. 4. The StoreAPI node specification format that is used in `--store` could be extended to include another flag which would let specify the previous option per-specific node. +5. Instead of extending the specification format, we could move the same inforamtion to the command line options themselves. This would increase the explicitness of this new mode i.e. that it only applies to statically defined nodes. Lets look through their pros and cons: @@ -47,10 +48,10 @@ If we were to graph these choices in terms of their incisiveness and complexity ```text Most incisive / Least Complex ------------ Least incisive / Most Complex #1 #2 #4 - #3 + #3 #5 ``` -After careful consideration and with the rationale in this proposal, we have decided to go with the third option. It should provide a sweet spot between being too invasive and providing our users the ability to fall-back to the old behavior. +After careful consideration and with the rationale in this proposal, we have decided to go with the fifth option. It should provide a sweet spot between being too invasive and providing our users the ability to fall-back to the old behavior. ## Goals @@ -77,7 +78,7 @@ The way this will need to be done should be as generic as possible so the design ## Proposal -* Add a new flag to Thanos Query `--store.strict-mode` which will make it always retain the last successfully retrieved information via the `Info()` gRPC method of **statically** defined nodes and thus always consider them part of the active store set. +* Add a new flag to Thanos Query `--store-strict` which will only accept statically specified nodes and Thanos Query will always retain the last successfully retrieved information of them via the `Info()` gRPC method. Thus, they will always be considered as part of the active store set. ## Risk @@ -85,7 +86,7 @@ The way this will need to be done should be as generic as possible so the design ## Work Plan -* Implement the new flag `--store.strict-mode` in Thanos Query which will make it keep around statically defined nodes. It will be disabled by default to reduce surprises when upgrading. +* Implement the new flag `--store-strict` in Thanos Query which will only accept statically defined nodes that will be permanently kept around. It is optional to use so there will be no surprises when upgrading. * Implement tests with dummy store nodes. * Document the new behavior. diff --git a/docs/proposals/202003_thanos_rules_federation.md b/docs/proposals/202003_thanos_rules_federation.md new file mode 100644 index 0000000000..d38de314bc --- /dev/null +++ b/docs/proposals/202003_thanos_rules_federation.md @@ -0,0 +1,226 @@ +--- +title: Global / Federated Rules API +type: proposal +menu: proposals +status: accepted +owner: s-urbaniak +--- + +### Related Tickets + +https://github.com/thanos-io/thanos/issues/1375 + +## Summary + +Thanos allows a global query view for the Prometheus series. This means discovering, connecting various (often remote) "leafs" components and aggregating series data from them. + +Since we work with metrics, evaluating recording rules and alerts is a very important part of our system. Some of our "StoreAPIs" like Prometheus and Thanos Ruler are designed for that. However, we currently don’t have a way to present those resources in a federated way e.g Alerts and Recording Rules. This document explores the potential way of solving this in the Prometheus Ecosystem. + +## Motivation + +Deployment scenarios with various levels of federated setups are not unusual. Some deployments leverage Thanos Ruler to query multiple data sources (i.e. via Thanos Querier) for rule and alert evaluation. This topology sacrifices availability. At the same time in the same deployment topology, a dedicated Prometheus instance is deployed for certain critical alerting rules implying high availability. Here, we are missing a federation middleware exposing a consolidated view of evaluated rules and alerts in the underlying Prometheus and Thanos Ruler instances. + +Pitfalls of current solutions: +* It’s tedious to manually visit each leaf and we are lazy. +* Visiting leaf instances (be it Thanos Ruler or dedicated Prometheus endpoints) have to be implemented manually. + +## Goals + +* Present other Prometheus/Thanos Resources in a global view. + * This also means an up-to-date view (e.g statuses) +* Simple to run if you already run Thanos. + * Use consistent protocols (if we suddenly switch to pure HTTP from gRPC it will break user’s proxies for auth, routing, monitoring, rate limiting, etc) + * Potentially use the same connections, discovered targets by Querier. + +## Verification + +* Unit tests which would fire up a dummy Rules API and check different scenarios. +* Ad-hoc testing. + +## Proposal + +### Rules API + +We propose to add following proto service and propagate all using existing components that have rules, so: +* Sidecar +* Querier (for federation) +* Ruler + +The newly introduced `Rules` service is designed to reflect [Prometheus' Rules API](https://github.com/prometheus/prometheus/blob/bc703b64568ebfaecf27b9b70be737ad318e217a/web/api/v1/api.go) allowing to retrieve recording and alerting rules. + +```proto +service Rules { + /// Rules has info for all rules. + rpc Rules(RulesRequest) returns (stream RulesResponse); +} +``` + +Sidecar proxies the Rules request to its local Prometheus instance and synthesizes the response. Similarly, Thanos Ruler constructs the response based on its local state. + +Thanos Querier fans-out to all know Rules endpoints configured via `--rule` command line flag, merges and deduplicates the result. This new setting is meant to configure rules endpoints as a strict subset of store endpoints as specified with `--store` and `--store.sd-files`. If a user specifies a `--rule` endpoint not matching `--store`/`--store.sd-files` endpoints the initial implementation would log out that fact. In the future (see below) it is planned to have this a more separate setting. + +Generally the deduplication logic is less complex than with time series, specifically: + +* Deduplication happens first at the rule group level. The identifier is the group name. +* Then, per group name deduplication happens on the rule level, where: + +1. the rule type (recording rule vs. alerting rule) +2. the rule name +3. the rule label names +4. the rule expression `expr` field +5. the alerting rule `for` field + +are being used as the deduplication identifier. Disjunct entries are simply merged by adding them to the result set. + +Thanos Querier presents the result of the fan-out on a `/api/v1/rules` endpoint which is compatible with the Prometheus' rules API endpoint. +Additionally Thanos Querier gains a new `--rule.replica-label` command line argument which falls back to `--query.replica-label` if unset. The replica labels refer to the same labels as specified in the `external_labels` section of Prometheus and the `--label` command line argument of Thanos Ruler. + +#### Examples + +A stream of alerting rules is merged from different Thanos Ruler API instances. +These may be remote Thanos Ruler, Prometheus Sidecar, or even Thanos Querier instances. +The merging Thanos Querier has `--rule.replica-label=replica` + +Scenario 1: + +As specified, the rule type and then rule name is used for deduplication. + +Given the following stream of incoming rule groups and containing recording/alerting rules: +```text +group: a + recording: > + alert: > +group: b + recording: > +group: a + recording: > +``` + +The output becomes: +```text +group: a + alert: > + recording: > + recording: > +group: b + recording: > +``` + +Note in the example above how the recording rule `r1` is not deduplicated as it is contained in two different groups. + +Scenario 2: + +The next level of deduplication is governed by the label/value set of the underlying recording/alerting rule while respecting the replica label. +For a given conflict, the youngest is preferred. For alerting rules, the youngest firing rule is preferred. + +Given the following stream of incoming recording rules: +```text +group: a + recording: > last_evaluation:<2006-01-02T10:00:00> > +group: a + recording: > last_evaluation:<2006-01-02T10:01:00> > +``` + +The output becomes: +```text +group: a + recording: > last_evaluation:<2006-01-02T10:01:00> > +``` + +Given the following stream of incoming alerting rules: +```text +group: a + alert: > last_evaluation:<2006-01-02T10:00:00> > +group: a + alert: > last_evaluation:<2006-01-02T10:01:00> > +``` + +The output becomes: +```text +group: a + alert: > last_evaluation:<2006-01-02T10:00:00> > +``` + +Note how in the above output the firing alerting rule was preferred despite being older. + +Scenario 3: + +If, under the above conditions a rule is a candidate for deduplication, finally the rule `expr` and `for` fields are being considered for deduplication. + +Given the following stream of incoming alerting rules will also result in two independent alerting rules as both the `expr` and `for` fields differ: +```text + - alert: KubeAPIErrorBudgetBurn + annotations: + message: The API server is burning too much error budget + expr: | + sum(apiserver_request:burnrate1h) > (14.40 * 0.01000) + and + sum(apiserver_request:burnrate5m) > (14.40 * 0.01000) + for: 2m + labels: + severity: critical + - alert: KubeAPIErrorBudgetBurn + annotations: + message: The API server is burning too much error budget + expr: | + sum(apiserver_request:burnrate6h) > (6.00 * 0.01000) + and + sum(apiserver_request:burnrate30m) > (6.00 * 0.01000) + for: 15m + labels: + severity: critical +``` + +## Alternatives + +* Cortex contains a sharded Ruler. Assigning rules to shards is done via Consul, though a gossip implementation is under development. Shards do not communicate with other shards. Rules come from a store (e.g. a Postgres database). + +## Work Plan + +* Implement a new flag `--rule` in Thanos Querier which registers RulesAPI endpoints. +* Implement a new flag `--rule.replica-label` in Thanos Querier. +* Implement RulesAPI backends in sidecar, query, rule. +* Feature branch: https://github.com/thanos-io/thanos/pull/2200 + +## Future + +These changes are suggestions which we will need to be discussed in future and are not part of the proposal implementation. + +### Type and Info + +Currently, `Info` is shared between the `RulesAPI` proposed here and the existing `StoreAPI` services. To accommodate for future additional APIs the following changes of the protobuf `Info` and `Type` structures are suggested. + + The current `StoreType` enum is renamed to `Type`. This retains binary compatibility with older clients: + + ```diff +-enum StoreType { ++enum Type { + UNKNOWN = 0; + QUERY = 1; + RULE = 2; +``` + + The current fields in `InfoResponse` connected to Store APIs are deprecated and dedicated new API sub types are proposed: + + ```diff + message InfoResponse { + // Deprecated. Use label_sets instead. + repeated Label labels = 1 [(gogoproto.nullable) = false]; ++ // Deprecated. Will be removed in favor of StoreInfoResponse in the future. + int64 min_time = 2; ++ // Deprecated. Will be removed in favor of StoreInfoResponse in the future. + int64 max_time = 3; +- StoreType storeType = 4; ++ Type type = 4; + // label_sets is an unsorted list of `LabelSet`s. ++ // Deprecated. Will be removed in favor of StoreInfoResponse in the future. + repeated LabelSet label_sets = 5 [(gogoproto.nullable) = false]; ++ ++ StoreInfoResponse store = 6; ++ RulesInfoResponse rules = 7; + } +``` + +### Independent `--rule` and `--store` endpoints configuration + +To ease the current implementation, rules endpoints are a strict subset of store endpoints. In the future these settings should be separate, i.e. the user could specify different endpoints for rules and different endpoints for store. diff --git a/docs/proposals/202004_embedd_cortex_frontend.md b/docs/proposals/202004_embedd_cortex_frontend.md new file mode 100644 index 0000000000..da07c0e222 --- /dev/null +++ b/docs/proposals/202004_embedd_cortex_frontend.md @@ -0,0 +1,128 @@ +--- +title: Adding a New Thanos Component that Embeds Cortex Query Frontend +type: proposal +menu: proposals +status: approved +owner: bwplotka +--- + +### Related Tickets + +* Response caching: https://github.com/thanos-io/thanos/issues/1651 +* Moving query frontend to separate repo: https://github.com/cortexproject/Cortex/issues/1672 +* Discussion about naming: https://cloud-native.slack.com/archives/CK5RSSC10/p1586939369171300 + +## Summary + +This proposal describes addition of a new Thanos command (component) into `cmd/thanos` called `query-frontend` +This component will literally import a certain version of Cortex [frontend package](https://github.com/cortexproject/Cortex/tree/4410bed704e7d8f63418b02b328ddb93d99fad0b/pkg/querier/frontend). + +We will go through rationales, and potential alternatives. + +## Motivation + +[Cortex Frontend](https://www.youtube.com/watch?v=eyBbImSDOrI&t=2s) was introduced by Tom in August 2019. It was designed +to be deployed in front of Prometheus Query API in order to ensure: + +* Query split by time. +* Query step alignment. +* Query retry logic +* Query limit logic +* Query response cache in memory, Memcached or Redis. + +Since the nature of Cortex backend is really similar to Thanos, with exactly the same PromQL API, and long term capabilities, the caching +work done for Cortex fits to Thanos. Given also our good collaboration in the past, it feels natural to reuse Cortex's code. +We even started discussion to move it to separate repo, but there was no motivation towards this, since there is no issue on using +the Cortex one, as Cortex is happy to take generalized contributions. + +At the end we were advertising to use Cortex query frontend on production on top of Thanos and this works considerably well, with some +problems on edge cases and for downsampled data as mentioned [here](https://github.com/thanos-io/thanos/issues/1651). + +However, we realized recently that asking users to install suddenly Cortex component on top of Thanos system is extremely confusing: + +* Cortex has totally different way of configuring services. It requires deciding what module you have in single YAML file. Thanos in opposite +have flags and different subcommand for each component. +* Cortex has bit different way of configuring memcached, which is inconsistent with what we have in Thanos Store Gateway. +* There are many Cortex specific configuration items which can confuse Thanos user and increase complexity overall. +* We have many ideas how to improve Cortex Query Frontend on top of Thanos, but adding Thanos specific configuration options will increase +complexity on Cortex side as well. +* Cortex has no good example or tutorial on how to use frontend either. We have only [Observatorium example](https://github.com/observatorium/configuration/blob/5129a8beb9507f29aec05566ca9a0f2ad82bbf76/environments/openshift/manifests/observatorium-template.yaml#L515). + +All of this were causing confusion and questions like [this](https://cloud-native.slack.com/archives/CK5RSSC10/p1586504362400300?thread_ts=1586492170.387900&cid=CK5RSSC10). + +At the end we decided with Thanos and Cortex maintainers that, ultimately, it would be awesome to create a new Thanos service called `query-frontend`. + +## Use Cases + +* User can cache responses for query range. +* User can split query range queries. +* User can rate limit and retry range queries. + +## Goals of this design + +* Enable response caching that will easy to use for Thanos users. +* Keep it extensible and scalable for future improvements like advanced query planning, queuing, rate limiting etc. +* Reuse as much as possible between projects, contribute. +* Use the same configuration patterns as rest of Thanos components. + +## Non Goals + +* Create Thanos specific response caching from scratch. + +## Proposal + +The idea is to create `thanos query-frontend` component that allows specifying following options: + +* `--query-range.split-interval`, `time.Duration` +* `--query-range.max-retries-per-request`, `int`, default = `5` +* `--query-range.disable-step-align`, `bool` +* `--query-range.response-cache-ttl` `time.Duration` +* `--query-range.response-cache-max-freshness` `time.Duration` default = `1m` +* `--query-range.response-cache-config(-file)` `pathorcontent` + [CacheConfig](https://github.com/thanos-io/thanos/blob/55cb8ca38b3539381dc6a781e637df15c694e50a/pkg/store/cache/factory.go#L32) + +We plan to have in-mem, fifo and memcached support for now. Cache config will be exactly the same as the one used for Store Gateway. + +This command will be placeholder for any query planning or queueing logic that we might want to add at some point. It will be not part of any gRPC API. + +To make this happen we will propose a small refactor in Cortex code to avoid unnecessary package dependencies. + +### Alternatives + +#### Don't add anything, document Cortex query frontend and add examples of usage + +Unfortunately we tried this path already without success. Reasons were mentioned in [Motivation](202004_embedd_cortex_frontend.md#Motivation) + +#### Add response caching to Querier itself, in the same process. + +This will definitely simplify deployment if Querier would allow caching directly. However, this way is not really scalable. + +Furthermore, eventually frontend will be responsible for more than just caching. It is meant to do query planning like splitting or even +advanced query parallelization (query sharding). This might mean future improvements in terms of query scheduling, queuing and retrying. +This means that at some point we would need an ability to scale query part and caching/query planner totally separately. + +Last but not least splitting queries allows to perform request in parallel. Only if used in single binary we can achieve load balancing of those requests. + +NOTE: We can still consider just simple response caching inside the Querier if user will request so. + +#### Write response caching from scratch. + +I think this does not need to be explained. Response caching has proven to be not trivial. It's really amazing that we +have opportunity to work towards something that works with experts in the field like @tomwilkie and others from Loki and Cortex Team. + +Overall, [Reusing is caring](https://www.bwplotka.dev/2020/how-to-became-oss-maintainer/#5-want-more-help-give-back-help-others). + +## Work Plan + +1. Refactor [IndexCacheConfig](https://github.com/thanos-io/thanos/blob/55cb8ca38b3539381dc6a781e637df15c694e50a/pkg/store/cache/factory.go#L32) to generic cache config so we can reuse. +Make it implement Cortex cache.Cache interface. +1. Add necessary changes to Cortex frontend + * Metric generalization (they are globals now). + * Avoid unnecessary dependencies. +1. Add `thanos query-frontend` subcommand. +1. Add proper e2e test using cache. +1. Document new subcommand +1. Add to [kube-thanos](https://github.com/thanos-io/kube-thanos) + +## Future Work + +Improvements to Cortex query frontend, so Thanos `query-frontend` as described [here](https://github.com/thanos-io/thanos/issues/1651) diff --git a/docs/proposals/_index.md b/docs/proposals/_index.md new file mode 100644 index 0000000000..7a77eb8108 --- /dev/null +++ b/docs/proposals/_index.md @@ -0,0 +1,13 @@ +--- +title: "Proposals:" +--- + +List of current proposals. + +Proposals can have 5 Statuses (`.Params.Status`): + +* accepted +* complete +* rejected +* in-review +* draft \ No newline at end of file diff --git a/docs/quick-tutorial.md b/docs/quick-tutorial.md index 78a12d786f..ffc378fd1d 100644 --- a/docs/quick-tutorial.md +++ b/docs/quick-tutorial.md @@ -39,9 +39,9 @@ Following the [KISS](https://en.wikipedia.org/wiki/KISS_principle) and Unix phil * Sidecar: connects to Prometheus, reads its data for query and/or uploads it to cloud storage. * Store Gateway: serves metrics inside of a cloud storage bucket. * Compactor: compacts, downsamples and applies retention on the data stored in cloud storage bucket. -* Receiver: receives data from Prometheus' remote-write WAL, exposes it and/or upload it to cloud storage. +* Receiver: receives data from Prometheus's remote-write WAL, exposes it and/or upload it to cloud storage. * Ruler/Rule: evaluates recording and alerting rules against data in Thanos for exposition and/or upload. -* Querier/Query: implements Prometheus' v1 API to aggregate data from the underlying components. +* Querier/Query: implements Prometheus's v1 API to aggregate data from the underlying components. See those components on this diagram: @@ -57,7 +57,7 @@ The Sidecar makes use of the `reload` Prometheus endpoint. Make sure it's enable #### External storage -The following configures the sidecar to write Prometheus' data into a configured object storage: +The following configures the sidecar to write Prometheus's data into a configured object storage: ```bash thanos sidecar \ @@ -163,7 +163,7 @@ thanos query \ Go to the configured HTTP address, and you should now be able to query across all Prometheus instances and receive de-duplicated data. -* _[Example Kubernetes manifest](https://github.com/thanos-io/kube-thanos/blob/master/manifests/thanos-querier-deployment.yaml)_ +* _[Example Kubernetes manifest](https://github.com/thanos-io/kube-thanos/blob/master/manifests/thanos-query-deployment.yaml)_ #### Communication Between Components @@ -208,7 +208,7 @@ The store gateway occupies small amounts of disk space for caching basic informa A local Prometheus installation periodically compacts older data to improve query efficiency. Since the sidecar backs up data as soon as possible, we need a way to apply the same process to data in the object storage. -The compactor component simple scans the object storage and processes compaction where required. At the same time it is responsible for creating downsampled copies of data to speed up queries. +The compactor component simply scans the object storage and processes compaction where required. At the same time it is responsible for creating downsampled copies of data to speed up queries. ```bash thanos compact \ @@ -221,7 +221,7 @@ The compactor is not in the critical path of querying or data backup. It can eit _NOTE: The compactor must be run as a **singleton** and must not run when manually modifying data in the bucket._ -* _[Example Kubernetes manifest](https://github.com/thanos-io/kube-thanos/blob/master/examples/all/manifests/thanos-compactor-statefulSet.yaml)_ +* _[Example Kubernetes manifest](https://github.com/thanos-io/kube-thanos/blob/master/examples/all/manifests/thanos-compact-statefulSet.yaml)_ ### [Ruler/Rule](components/rule.md) diff --git a/docs/release-process.md b/docs/release-process.md index f6e4c52210..6fb63144ac 100644 --- a/docs/release-process.md +++ b/docs/release-process.md @@ -32,7 +32,9 @@ Release shepherd responsibilities: | Release | Time of first RC | Shepherd (GitHub handle) | |-----------|--------------------------|--------------------------| -| v0.12.0 | (planned) 2020.04.01 | TBD | +| v0.14.0 | (planned) 2020.06.24 | TBA | +| v0.13.0 | (planned) 2020.05.13 | `@bwplotka` | +| v0.12.0 | 2020.04.15 | `@squat` | | v0.11.0 | 2020.02.19 | `@metalmatze` | | v0.10.0 | 2020.01.08 | `@GiedriusS` | | v0.9.0 | 2019.11.26 | `@bwplotka` | @@ -88,9 +90,9 @@ Release is happening on separate `release-.` branch. 1. After review, merge the PR and immediately after this tag a version: ```bash - $ tag=$(cat VERSION) - $ git tag -s "v${tag}" -m "v${tag}" - $ git push origin "v${tag}" + tag=$(cat VERSION) + git tag -s "v${tag}" -m "v${tag}" + git push origin "v${tag}" ``` Signing a tag with a GPG key is appreciated, but in case you can't add a GPG key to your Github account using the following [procedure](https://help.github.com/articles/generating-a-gpg-key/), you can replace the `-s` flag by `-a` flag of the `git tag` command to only annotate the tag without signing. diff --git a/docs/sharding.md b/docs/sharding.md new file mode 100644 index 0000000000..6fc3bcc380 --- /dev/null +++ b/docs/sharding.md @@ -0,0 +1,77 @@ +--- +title: Sharding +type: docs +menu: thanos +slug: /sharding.md +--- + +# Background + +Currently all components that read from object store assume that all the operations and functionality should be done based +on **all** the available blocks that are present in the certain bucket's root directory. + +This is in most cases totally fine, however with time and allowance of storing blocks from multiple `Sources` into the same bucket, +the number of objects in a bucket can grow drastically. + +This means that with time you might want to scale out certain components e.g: + +* Compactor: Larger number of objects does not matter much, however compactor has to scale (CPU, network, disk, memory) with number of Sources pushing blocks to the object storage. + +* Store Gateway: Queries against store gateway which are touching large number of Sources might be expensive, so it has to scale up with number of Sources if we assume those queries. + * Orthogonally we did not advertise any labels on Store Gateway's Info. This means that querier was not able to do any pre-filtering, so all store gateways in system are always touched for each query. + +# Relabelling + +Similar to [promtail](https://github.com/grafana/loki/blob/master/docs/clients/promtail/configuration.md#relabel_config) this config will follow native +[Prometheus relabel-config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config) syntax. + +Now, thanos only support following relabel actions: + +* keep + +* drop + +* hashmod + * `external labels` for all components + + * `__block_id` for store gateway, see this [example](https://github.com/observatorium/configuration/blob/bf1304b0d7bce2ae3fefa80412bb358f9aa176fb/environments/openshift/manifests/observatorium-template.yaml#L1514-L1521) + +The relabel config defines filtering process done on **every** synchronization with object storage. + +We will allow potentially manipulating with several of inputs: + +* External labels: + * `` + +Output: + +* If output is empty, drop block. + +By default, on empty relabel-config, all external labels are assumed. + +Example usages would be: + +* Drop blocks which contains external labels cluster=A + +```yaml +- action: drop + regex: "A" + source_labels: + - cluster +``` + +* Keep only blocks which contains external labels cluster=A +```yaml +- action: keep + regex: "A" + source_labels: + - cluster +``` + +We can shard by adjusting which labels should be included in the blocks. + +# Time Partitioning + +For store gateway, we can specify `--min-time` and `--max-time` flags to filter for what blocks store gateway should be responsible for. + +More details can refer to "Time based partitioning" chapter in [Store gateway](components/store.md). diff --git a/docs/storage.md b/docs/storage.md index 999e0b156f..bb0a55a0f0 100644 --- a/docs/storage.md +++ b/docs/storage.md @@ -97,7 +97,7 @@ config: At a minimum, you will need to provide a value for the `bucket`, `endpoint`, `access_key`, and `secret_key` keys. The rest of the keys are optional. -The AWS region to endpoint mapping can be found in this [link](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region). +The AWS region to endpoint mapping can be found in this [link](https://docs.aws.amazon.com/general/latest/gr/s3.html). Make sure you use a correct signature version. Currently AWS requires signature v4, so it needs `signature-version2: false`. If you don't specify it, you will get an `Access Denied` error. On the other hand, several S3 compatible APIs use `signature-version2: true`. diff --git a/examples/alerts/alerts.md b/examples/alerts/alerts.md index 39b4c57bfa..76c435af22 100644 --- a/examples/alerts/alerts.md +++ b/examples/alerts/alerts.md @@ -97,7 +97,7 @@ rules: ) for: 5m labels: - severity: warning + severity: critical - alert: ThanosRuleHighRuleEvaluationWarnings annotations: message: Thanos Rule {{$labels.job}} {{$labels.pod}} has high number of evaluation @@ -144,8 +144,8 @@ rules: severity: info - alert: ThanosRuleQueryHighDNSFailures annotations: - message: Thanos Rule {{$labels.job}} have {{ $value | humanize }}% of failing - DNS queries for query endpoints. + message: Thanos Rule {{$labels.job}} has {{ $value | humanize }}% of failing DNS + queries for query endpoints. expr: | ( sum by (job) (rate(thanos_ruler_query_apis_dns_failures_total{job=~"thanos-rule.*"}[5m])) @@ -158,8 +158,8 @@ rules: severity: warning - alert: ThanosRuleAlertmanagerHighDNSFailures annotations: - message: Thanos Rule {{$labels.job}} have {{ $value | humanize }}% of failing - DNS queries for Alertmanager endpoints. + message: Thanos Rule {{$labels.job}} has {{ $value | humanize }}% of failing DNS + queries for Alertmanager endpoints. expr: | ( sum by (job) (rate(thanos_ruler_alertmanagers_dns_failures_total{job=~"thanos-rule.*"}[5m])) @@ -170,6 +170,27 @@ rules: for: 15m labels: severity: warning +- alert: ThanosRuleNoEvaluationFor10Intervals + annotations: + message: Thanos Rule {{$labels.job}} has {{ $value | humanize }}% rule groups + that did not evaluate for at least 10x of their expected interval. + expr: | + time() - max by (job, group) (prometheus_rule_group_last_evaluation_timestamp_seconds{job=~"thanos-rule.*"}) + > + 10 * max by (job, group) (prometheus_rule_group_interval_seconds{job=~"thanos-rule.*"}) + for: 5m + labels: + severity: info +- alert: ThanosNoRuleEvaluations + annotations: + message: Thanos Rule {{$labels.job}} did not perform any rule evaluations in the + past 2 minutes. + expr: | + sum(rate(prometheus_rule_evaluations_total{job=~"thanos-rule.*"}[2m])) <= 0 + and + sum(thanos_rule_loaded_rules{job=~"thanos-rule.*"}) > 0 + labels: + severity: critical ``` ## Store Gateway @@ -198,7 +219,7 @@ rules: }} seconds for store series gate requests. expr: | ( - histogram_quantile(0.9, sum by (job, le) (thanos_bucket_store_series_gate_duration_seconds_bucket{job=~"thanos-store.*"})) > 2 + histogram_quantile(0.9, sum by (job, le) (rate(thanos_bucket_store_series_gate_duration_seconds_bucket{job=~"thanos-store.*"}[5m]))) > 2 and sum by (job) (rate(thanos_bucket_store_series_gate_duration_seconds_count{job=~"thanos-store.*"}[5m])) > 0 ) @@ -225,7 +246,7 @@ rules: {{ $value }} seconds for the bucket operations. expr: | ( - histogram_quantile(0.9, sum by (job, le) (thanos_objstore_bucket_operation_duration_seconds_bucket{job=~"thanos-store.*"})) > 15 + histogram_quantile(0.9, sum by (job, le) (rate(thanos_objstore_bucket_operation_duration_seconds_bucket{job=~"thanos-store.*"}[5m]))) > 2 and sum by (job) (rate(thanos_objstore_bucket_operation_duration_seconds_count{job=~"thanos-store.*"}[5m])) > 0 ) @@ -336,7 +357,7 @@ rules: }} seconds for instant queries. expr: | ( - histogram_quantile(0.99, sum by (job, le) (http_request_duration_seconds_bucket{job=~"thanos-query.*", handler="query"})) > 90 + histogram_quantile(0.99, sum by (job, le) (rate(http_request_duration_seconds_bucket{job=~"thanos-query.*", handler="query"}[5m]))) > 40 and sum by (job) (rate(http_request_duration_seconds_bucket{job=~"thanos-query.*", handler="query"}[5m])) > 0 ) @@ -349,7 +370,7 @@ rules: }} seconds for range queries. expr: | ( - histogram_quantile(0.99, sum by (job, le) (http_request_duration_seconds_bucket{job=~"thanos-query.*", handler="query_range"})) > 90 + histogram_quantile(0.99, sum by (job, le) (rate(http_request_duration_seconds_bucket{job=~"thanos-query.*", handler="query_range"}[5m]))) > 90 and sum by (job) (rate(http_request_duration_seconds_count{job=~"thanos-query.*", handler="query_range"}[5m])) > 0 ) @@ -383,7 +404,7 @@ rules: }} seconds for requests. expr: | ( - histogram_quantile(0.99, sum by (job, le) (http_request_duration_seconds_bucket{job=~"thanos-receive.*", handler="receive"})) > 10 + histogram_quantile(0.99, sum by (job, le) (rate(http_request_duration_seconds_bucket{job=~"thanos-receive.*", handler="receive"}[5m]))) > 10 and sum by (job) (rate(http_request_duration_seconds_count{job=~"thanos-receive.*", handler="receive"}[5m])) > 0 ) @@ -426,6 +447,14 @@ rules: for: 5m labels: severity: warning +- alert: ThanosReceiveNoUpload + annotations: + message: Thanos Receive {{$labels.job}} has not uploaded latest data to object + storage. + expr: increase(thanos_shipper_uploads_total{job=~"thanos-receive.*"}[2h]) == 0 + for: 30m + labels: + severity: warning ``` ## Replicate @@ -461,7 +490,7 @@ rules: $value }} seconds for the replicate operations. expr: | ( - histogram_quantile(0.9, sum by (job, le) (thanos_replicate_replication_run_duration_seconds_bucket{job=~"thanos-bucket-replicate.*"})) > 120 + histogram_quantile(0.9, sum by (job, le) (rate(thanos_replicate_replication_run_duration_seconds_bucket{job=~"thanos-bucket-replicate.*"}[5m]))) > 20 and sum by (job) (rate(thanos_replicate_replication_run_duration_seconds_bucket{job=~"thanos-bucket-replicate.*"}[5m])) > 0 ) diff --git a/examples/alerts/alerts.yaml b/examples/alerts/alerts.yaml index 400414da89..d83c1e107d 100644 --- a/examples/alerts/alerts.yaml +++ b/examples/alerts/alerts.yaml @@ -125,7 +125,7 @@ groups: }} seconds for instant queries. expr: | ( - histogram_quantile(0.99, sum by (job, le) (http_request_duration_seconds_bucket{job=~"thanos-query.*", handler="query"})) > 90 + histogram_quantile(0.99, sum by (job, le) (rate(http_request_duration_seconds_bucket{job=~"thanos-query.*", handler="query"}[5m]))) > 40 and sum by (job) (rate(http_request_duration_seconds_bucket{job=~"thanos-query.*", handler="query"}[5m])) > 0 ) @@ -138,7 +138,7 @@ groups: }} seconds for range queries. expr: | ( - histogram_quantile(0.99, sum by (job, le) (http_request_duration_seconds_bucket{job=~"thanos-query.*", handler="query_range"})) > 90 + histogram_quantile(0.99, sum by (job, le) (rate(http_request_duration_seconds_bucket{job=~"thanos-query.*", handler="query_range"}[5m]))) > 90 and sum by (job) (rate(http_request_duration_seconds_count{job=~"thanos-query.*", handler="query_range"}[5m])) > 0 ) @@ -166,7 +166,7 @@ groups: $value }} seconds for requests. expr: | ( - histogram_quantile(0.99, sum by (job, le) (http_request_duration_seconds_bucket{job=~"thanos-receive.*", handler="receive"})) > 10 + histogram_quantile(0.99, sum by (job, le) (rate(http_request_duration_seconds_bucket{job=~"thanos-receive.*", handler="receive"}[5m]))) > 10 and sum by (job) (rate(http_request_duration_seconds_count{job=~"thanos-receive.*", handler="receive"}[5m])) > 0 ) @@ -210,6 +210,14 @@ groups: for: 5m labels: severity: warning + - alert: ThanosReceiveNoUpload + annotations: + message: Thanos Receive {{$labels.job}} has not uploaded latest data to object + storage. + expr: increase(thanos_shipper_uploads_total{job=~"thanos-receive.*"}[2h]) == 0 + for: 30m + labels: + severity: warning - name: thanos-sidecar.rules rules: - alert: ThanosSidecarPrometheusDown @@ -250,7 +258,7 @@ groups: }} seconds for store series gate requests. expr: | ( - histogram_quantile(0.9, sum by (job, le) (thanos_bucket_store_series_gate_duration_seconds_bucket{job=~"thanos-store.*"})) > 2 + histogram_quantile(0.9, sum by (job, le) (rate(thanos_bucket_store_series_gate_duration_seconds_bucket{job=~"thanos-store.*"}[5m]))) > 2 and sum by (job) (rate(thanos_bucket_store_series_gate_duration_seconds_count{job=~"thanos-store.*"}[5m])) > 0 ) @@ -277,7 +285,7 @@ groups: {{ $value }} seconds for the bucket operations. expr: | ( - histogram_quantile(0.9, sum by (job, le) (thanos_objstore_bucket_operation_duration_seconds_bucket{job=~"thanos-store.*"})) > 15 + histogram_quantile(0.9, sum by (job, le) (rate(thanos_objstore_bucket_operation_duration_seconds_bucket{job=~"thanos-store.*"}[5m]))) > 2 and sum by (job) (rate(thanos_objstore_bucket_operation_duration_seconds_count{job=~"thanos-store.*"}[5m])) > 0 ) @@ -316,7 +324,7 @@ groups: ) for: 5m labels: - severity: warning + severity: critical - alert: ThanosRuleHighRuleEvaluationWarnings annotations: message: Thanos Rule {{$labels.job}} {{$labels.pod}} has high number of evaluation @@ -363,7 +371,7 @@ groups: severity: info - alert: ThanosRuleQueryHighDNSFailures annotations: - message: Thanos Rule {{$labels.job}} have {{ $value | humanize }}% of failing + message: Thanos Rule {{$labels.job}} has {{ $value | humanize }}% of failing DNS queries for query endpoints. expr: | ( @@ -377,7 +385,7 @@ groups: severity: warning - alert: ThanosRuleAlertmanagerHighDNSFailures annotations: - message: Thanos Rule {{$labels.job}} have {{ $value | humanize }}% of failing + message: Thanos Rule {{$labels.job}} has {{ $value | humanize }}% of failing DNS queries for Alertmanager endpoints. expr: | ( @@ -389,6 +397,27 @@ groups: for: 15m labels: severity: warning + - alert: ThanosRuleNoEvaluationFor10Intervals + annotations: + message: Thanos Rule {{$labels.job}} has {{ $value | humanize }}% rule groups + that did not evaluate for at least 10x of their expected interval. + expr: | + time() - max by (job, group) (prometheus_rule_group_last_evaluation_timestamp_seconds{job=~"thanos-rule.*"}) + > + 10 * max by (job, group) (prometheus_rule_group_interval_seconds{job=~"thanos-rule.*"}) + for: 5m + labels: + severity: info + - alert: ThanosNoRuleEvaluations + annotations: + message: Thanos Rule {{$labels.job}} did not perform any rule evaluations in + the past 2 minutes. + expr: | + sum(rate(prometheus_rule_evaluations_total{job=~"thanos-rule.*"}[2m])) <= 0 + and + sum(thanos_rule_loaded_rules{job=~"thanos-rule.*"}) > 0 + labels: + severity: critical - name: thanos-component-absent.rules rules: - alert: ThanosCompactIsDown @@ -468,7 +497,7 @@ groups: $value }} seconds for the replicate operations. expr: | ( - histogram_quantile(0.9, sum by (job, le) (thanos_replicate_replication_run_duration_seconds_bucket{job=~"thanos-bucket-replicate.*"})) > 120 + histogram_quantile(0.9, sum by (job, le) (rate(thanos_replicate_replication_run_duration_seconds_bucket{job=~"thanos-bucket-replicate.*"}[5m]))) > 20 and sum by (job) (rate(thanos_replicate_replication_run_duration_seconds_bucket{job=~"thanos-bucket-replicate.*"}[5m])) > 0 ) diff --git a/examples/dashboards/compact.json b/examples/dashboards/compact.json index 44fe9a625d..b3acd314ba 100644 --- a/examples/dashboards/compact.json +++ b/examples/dashboards/compact.json @@ -1231,7 +1231,7 @@ }, "yaxes": [ { - "format": "short", + "format": "bytes", "label": null, "logBase": 1, "max": null, diff --git a/examples/dashboards/dashboards.md b/examples/dashboards/dashboards.md index cc6cf091a2..de2dd48423 100644 --- a/examples/dashboards/dashboards.md +++ b/examples/dashboards/dashboards.md @@ -2,14 +2,14 @@ There exists Grafana dashboards for each component (not all of them complete) targeted for environments running Kubernetes: -- [Thanos Overview](thanos-overview.json) -- [Thanos Compact](thanos-compactor.json) -- [Thanos Querier](thanos-querier.json) -- [Thanos Store](thanos-store.json) -- [Thanos Receiver](thanos-receiver.json) -- [Thanos Sidecar](thanos-sidecar.json) -- [Thanos Ruler](thanos-ruler.json) -- [Thanos Replicate](thanos-bucket-replicate.json) +- [Thanos Overview](overview.json) +- [Thanos Compact](compact.json) +- [Thanos Querier](query.json) +- [Thanos Store](store.json) +- [Thanos Receiver](receive.json) +- [Thanos Sidecar](sidecar.json) +- [Thanos Ruler](rule.json) +- [Thanos Replicate](bucket_replicate.json) You can import them via `Import -> Paste JSON` in Grafana. These dashboards require Grafana 5 or above, importing them in older versions are known not to work. diff --git a/examples/dashboards/query.json b/examples/dashboards/query.json index 9f1bfa7ef2..6b4b9a0910 100644 --- a/examples/dashboards/query.json +++ b/examples/dashboards/query.json @@ -2163,7 +2163,7 @@ }, "yaxes": [ { - "format": "short", + "format": "bytes", "label": null, "logBase": 1, "max": null, diff --git a/examples/dashboards/receive.json b/examples/dashboards/receive.json index 1c3081d0cf..7744a14287 100644 --- a/examples/dashboards/receive.json +++ b/examples/dashboards/receive.json @@ -2018,7 +2018,7 @@ }, "yaxes": [ { - "format": "short", + "format": "bytes", "label": null, "logBase": 1, "max": null, diff --git a/examples/dashboards/rule.json b/examples/dashboards/rule.json index 897b168dc2..f197768b9c 100644 --- a/examples/dashboards/rule.json +++ b/examples/dashboards/rule.json @@ -1696,7 +1696,7 @@ }, "yaxes": [ { - "format": "short", + "format": "bytes", "label": null, "logBase": 1, "max": null, diff --git a/examples/dashboards/sidecar.json b/examples/dashboards/sidecar.json index fca87f47d2..05dc6fc300 100644 --- a/examples/dashboards/sidecar.json +++ b/examples/dashboards/sidecar.json @@ -1571,7 +1571,7 @@ }, "yaxes": [ { - "format": "short", + "format": "bytes", "label": null, "logBase": 1, "max": null, diff --git a/examples/dashboards/store.json b/examples/dashboards/store.json index 13d3e4b9df..9c9c1e2389 100644 --- a/examples/dashboards/store.json +++ b/examples/dashboards/store.json @@ -865,7 +865,7 @@ "steppedLine": false, "targets": [ { - "expr": "sum(rate(grpc_client_handled_total{namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job, grpc_method, grpc_code)", + "expr": "sum(rate(grpc_server_handled_total{namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job, grpc_method, grpc_code)", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{job}} {{grpc_method}} {{grpc_code}}", @@ -942,7 +942,7 @@ "steppedLine": false, "targets": [ { - "expr": "sum(rate(grpc_client_handled_total{grpc_code!=\"OK\",namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job, grpc_method, grpc_code)\n", + "expr": "sum(rate(grpc_server_handled_total{grpc_code!=\"OK\",namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job, grpc_method, grpc_code)\n", "format": "time_series", "intervalFactor": 2, "legendFormat": "{{job}} {{grpc_method}} {{grpc_code}}", @@ -1019,7 +1019,7 @@ "steppedLine": false, "targets": [ { - "expr": "histogram_quantile(0.99, sum(rate(grpc_client_handling_seconds_bucket{namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job, grpc_method, le)) * 1", + "expr": "histogram_quantile(0.99, sum(rate(grpc_server_handling_seconds_bucket{namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job, grpc_method, le)) * 1", "format": "time_series", "intervalFactor": 2, "legendFormat": "P99 {{job}} {{grpc_method}}", @@ -1027,7 +1027,7 @@ "step": 10 }, { - "expr": "sum(rate(grpc_client_handling_seconds_sum{namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job) * 1\n/\nsum(rate(grpc_client_handling_seconds_count{namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job)\n", + "expr": "sum(rate(grpc_server_handling_seconds_sum{namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job) * 1\n/\nsum(rate(grpc_server_handling_seconds_count{namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job)\n", "format": "time_series", "intervalFactor": 2, "legendFormat": "mean {{job}} {{grpc_method}}", @@ -1035,7 +1035,7 @@ "step": 10 }, { - "expr": "histogram_quantile(0.50, sum(rate(grpc_client_handling_seconds_bucket{namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job, grpc_method, le)) * 1", + "expr": "histogram_quantile(0.50, sum(rate(grpc_server_handling_seconds_bucket{namespace=\"$namespace\",job=~\"$job\",grpc_type=\"server_stream\"}[$interval])) by (job, grpc_method, le)) * 1", "format": "time_series", "intervalFactor": 2, "legendFormat": "P50 {{job}} {{grpc_method}}", @@ -2002,7 +2002,7 @@ "dashLength": 10, "dashes": false, "datasource": "$datasource", - "description": "Shows size of chunks that have sent to the bucket, in bytes.", + "description": "Shows size of chunks that have sent to the bucket.", "fill": 1, "id": 24, "legend": { @@ -2072,7 +2072,7 @@ }, "yaxes": [ { - "format": "short", + "format": "bytes", "label": null, "logBase": 1, "max": null, @@ -2095,25 +2095,7 @@ "repeatRowId": null, "showTitle": true, "title": "Store Sent", - "titleSize": "h6", - "yaxes": [ - { - "format": "decbytes", - "label": null, - "logBase": 1, - "max": null, - "min": 0, - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": false - } - ] + "titleSize": "h6" }, { "collapse": false, @@ -2217,6 +2199,7 @@ "dashLength": 10, "dashes": false, "datasource": "$datasource", + "description": "Show the size of data fetched", "fill": 1, "id": 26, "legend": { @@ -2286,7 +2269,7 @@ }, "yaxes": [ { - "format": "short", + "format": "bytes", "label": null, "logBase": 1, "max": null, @@ -2797,7 +2780,7 @@ }, "yaxes": [ { - "format": "short", + "format": "bytes", "label": null, "logBase": 1, "max": null, diff --git a/go.mod b/go.mod index f9a10026de..78c199b3ef 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,8 @@ require ( github.com/armon/go-metrics v0.3.0 github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b github.com/cespare/xxhash v1.1.0 - github.com/cortexproject/cortex v0.6.1-0.20200212080622-5292538418b1 + github.com/cortexproject/cortex v0.6.1-0.20200228110116-92ab6cbe0995 + github.com/davecgh/go-spew v1.1.1 github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb github.com/fatih/structtag v1.1.0 github.com/fortytw2/leaktest v1.3.0 @@ -19,6 +20,7 @@ require ( github.com/go-openapi/strfmt v0.19.2 github.com/gogo/protobuf v1.3.1 github.com/gogo/status v1.0.3 + github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 github.com/golang/snappy v0.0.1 github.com/googleapis/gax-go v2.0.2+incompatible github.com/gophercloud/gophercloud v0.6.0 @@ -29,7 +31,7 @@ require ( github.com/lightstep/lightstep-tracer-go v0.18.0 github.com/lovoo/gcloud-opentracing v0.3.0 github.com/miekg/dns v1.1.22 - github.com/minio/minio-go/v6 v6.0.45 + github.com/minio/minio-go/v6 v6.0.53 github.com/mozillazg/go-cos v0.13.0 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f github.com/oklog/run v1.0.0 @@ -38,11 +40,12 @@ require ( github.com/opentracing/basictracer-go v1.0.0 github.com/opentracing/opentracing-go v1.1.1-0.20200124165624-2876d2018785 github.com/pkg/errors v0.9.1 + github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/alertmanager v0.20.0 - github.com/prometheus/client_golang v1.4.2-0.20200214154132-b25ce2693a6d + github.com/prometheus/client_golang v1.5.0 github.com/prometheus/client_model v0.2.0 github.com/prometheus/common v0.9.1 - github.com/prometheus/prometheus v1.8.2-0.20200110114423-1e64d757f711 // master ~ v2.15.2 + github.com/prometheus/prometheus v1.8.2-0.20200213233353-b90be6f32a33 github.com/uber/jaeger-client-go v2.20.1+incompatible github.com/uber/jaeger-lib v2.2.0+incompatible go.elastic.co/apm v1.5.0 @@ -52,13 +55,13 @@ require ( golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e golang.org/x/text v0.3.2 - golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd // indirect + golang.org/x/tools v0.0.0-20200306191617-51e69f71924f // indirect google.golang.org/api v0.14.0 google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 google.golang.org/grpc v1.25.1 gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/fsnotify.v1 v1.4.7 - gopkg.in/yaml.v2 v2.2.5 + gopkg.in/yaml.v2 v2.2.7 ) // We want to replace the client-go version with a specific commit hash, @@ -67,8 +70,8 @@ require ( replace ( // Mitigation for: https://github.com/Azure/go-autorest/issues/414 github.com/Azure/go-autorest => github.com/Azure/go-autorest v12.3.0+incompatible - // TODO(bwplotka): Update once https://github.com/cortexproject/cortex/pull/2146 is merged. - github.com/cortexproject/cortex => github.com/bwplotka/cortex v0.0.0-20200218165228-c04fa1c09090 + // Make sure Cortex is not forcing us to some other Prometheus version. + github.com/prometheus/prometheus => github.com/prometheus/prometheus v1.8.2-0.20200110114423-1e64d757f711 // master ~ v2.15.2 k8s.io/api => k8s.io/api v0.0.0-20190620084959-7cf5895f2711 k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20190620085554-14e95df34f1f k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719 diff --git a/go.sum b/go.sum index 23c863ac15..e97ad5c47a 100644 --- a/go.sum +++ b/go.sum @@ -56,7 +56,6 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt 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/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Masterminds/squirrel v0.0.0-20161115235646-20f192218cf5/go.mod h1:xnKTFzjGUiZtiOagBsfnvomW+nJg2usB1ZpordQWqNM= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= @@ -64,7 +63,6 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/OneOfOne/xxhash v1.2.6 h1:U68crOE3y3MPttCMQGywZOLrTeF5HHJ3/vDBCJn9/bA= github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4= @@ -88,7 +86,6 @@ github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQY github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= github.com/armon/go-metrics v0.3.0 h1:B7AQgHi8QSEi4uHu7Sbsga+IJDU+CENgjxoo81vDUqU= github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -100,7 +97,6 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.22.4/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.48 h1:J82DYDGZHOKHdhx6hD24Tm30c2C3GchYGfN0mf9iKUk= github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA= @@ -116,8 +112,6 @@ github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= -github.com/bwplotka/cortex v0.0.0-20200218165228-c04fa1c09090 h1:7epH/EyWMG+W4Om7OwnIsOCUgxfQU1+LVYcfL0pJHKQ= -github.com/bwplotka/cortex v0.0.0-20200218165228-c04fa1c09090/go.mod h1:xArTQk2WBKDQ8YrIUMLfIuecuV0dKWyVVyTgRF/+a1E= github.com/cenkalti/backoff v0.0.0-20181003080854-62661b46c409/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v1.0.0/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -142,6 +136,8 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cortexproject/cortex v0.6.1-0.20200228110116-92ab6cbe0995 h1:yt8dEfoUiSDnucukhKQiv6lnHWljj7rcIMT/qbpP2e8= +github.com/cortexproject/cortex v0.6.1-0.20200228110116-92ab6cbe0995/go.mod h1:3Xa3DjJxtpXqxcMGdk850lcIRb81M0fyY1MQ6udY134= github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc= @@ -194,7 +190,6 @@ github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structtag v1.1.0 h1:6j4mUV/ES2duvnAzKMFkN6/A5mCaNYPD3xfbAkLLOF8= github.com/fatih/structtag v1.1.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= -github.com/fluent/fluent-logger-golang v1.2.1/go.mod h1:2/HCT/jTy78yGyeNGQLGQsjF3zzzAuy6Xlk6FCMV5eU= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= @@ -217,8 +212,6 @@ github.com/go-openapi/analysis v0.17.2/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpR github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.19.2 h1:ophLETFestFZHk3ji7niPEL4d466QjW+0Tdg5VyDq7E= github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= -github.com/go-openapi/analysis v0.19.4 h1:1TjOzrWkj+9BrjnM1yPAICbaoC0FyfD49oVkTBrSSa0= -github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.17.2/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= @@ -288,6 +281,7 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190730201129-28a6bbf47e48/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/status v1.0.3 h1:WkVBY59mw7qUNTr/bLwO7J2vesJ0rQ2C3tMXrTd3w5M= @@ -345,7 +339,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= @@ -415,7 +408,6 @@ github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/memberlist v0.1.5 h1:AYBsgJOW9gab/toO5tEB8lWetVgDKZycqkebJ8xxpqM= github.com/hashicorp/memberlist v0.1.5/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.8.3/go.mod h1:UpNcs7fFbpKIyZaUuSW6EPiH+eZC7OuyFD+wc1oal+k= github.com/hashicorp/serf v0.8.5 h1:ZynDUIQiA8usmRgPdGPHFdPnb1wgGI9tK3mO9hcAJjc= github.com/hashicorp/serf v0.8.5/go.mod h1:UpNcs7fFbpKIyZaUuSW6EPiH+eZC7OuyFD+wc1oal+k= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= @@ -433,7 +425,6 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -488,8 +479,6 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= @@ -511,8 +500,8 @@ github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.22 h1:Jm64b3bO9kP43ddLjL2EY3Io6bmy1qGb9Xxz6TqS6rc= github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/minio/minio-go/v6 v6.0.44/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= -github.com/minio/minio-go/v6 v6.0.45 h1:aY4NI/DOgSbZiwGN3fEF4NAkC9An4bhaIWuJrQrRYew= -github.com/minio/minio-go/v6 v6.0.45/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= +github.com/minio/minio-go/v6 v6.0.53 h1:8jzpwiOzZ5Iz7/goFWqNZRICbyWYShbb5rARjrnSCNI= +github.com/minio/minio-go/v6 v6.0.53/go.mod h1:DIvC/IApeHX8q1BAMVCXSXwpmrmM+I+iBvhvztQorfI= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= 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= @@ -580,7 +569,6 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/philhofer/fwd v0.0.0-20160129035939-98c11a7a6ec8/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= @@ -604,8 +592,8 @@ github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQ github.com/prometheus/client_golang v1.2.0/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI= github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= -github.com/prometheus/client_golang v1.4.2-0.20200214154132-b25ce2693a6d h1:6GpNaEnOxPO8IxMm5zmXdIpCGayuQmp7udttdxB2BbM= -github.com/prometheus/client_golang v1.4.2-0.20200214154132-b25ce2693a6d/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.5.0 h1:Ctq0iGpCmr3jeP77kbF2UxgvRwzWWz+4Bh9/vJTyg1A= +github.com/prometheus/client_golang v1.5.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -621,6 +609,7 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.8.0/go.mod h1:PC/OgXc+UN7B4ALwvn1yzVZmVwvhXp5JsbBv6wSv6i0= github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20180612222113-7d6f385de8be/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -635,9 +624,6 @@ github.com/prometheus/procfs v0.0.6 h1:0qbH+Yqu/cj1ViVLvEWCP6qMQ4efWUj6bQqOEA0V0 github.com/prometheus/procfs v0.0.6/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/prometheus v0.0.0-20180315085919-58e2a31db8de/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= -github.com/prometheus/prometheus v0.0.0-20190818123050-43acd0e2e93f/go.mod h1:rMTlmxGCvukf2KMu3fClMDKLLoJ5hl61MhcJ7xKakf0= -github.com/prometheus/prometheus v1.8.2-0.20200107122003-4708915ac6ef/go.mod h1:7U90zPoLkWjEIQcy/rweQla82OCTUzxVHE51G3OhJbI= github.com/prometheus/prometheus v1.8.2-0.20200110114423-1e64d757f711 h1:uEq+8hKI4kfycPLSKNw844YYkdMNpC2eZpov73AvlFk= github.com/prometheus/prometheus v1.8.2-0.20200110114423-1e64d757f711/go.mod h1:7U90zPoLkWjEIQcy/rweQla82OCTUzxVHE51G3OhJbI= github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1/go.mod h1:JaY6n2sDr+z2WTsXkOmNRUfDy6FN0L6Nk7x06ndm4tY= @@ -663,20 +649,25 @@ github.com/sercand/kuberesolver v2.1.0+incompatible h1:iJ1oCzPQ/aacsbCWLfJW1hPKk github.com/sercand/kuberesolver v2.1.0+incompatible/go.mod h1:lWF3GL0xptCB/vCiJPl/ZshwPsX/n4Y7u0CW9E7aQIQ= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/vfsgen v0.0.0-20180825020608-02ddb050ef6b/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0= github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.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/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q= +github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 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/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= @@ -698,7 +689,6 @@ github.com/thanos-io/thanos v0.8.1-0.20200109203923-552ffa4c1a0d/go.mod h1:usT/T github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tinylib/msgp v0.0.0-20161221055906-38a6f61a768d/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= @@ -709,9 +699,8 @@ github.com/uber/jaeger-lib v1.5.1-0.20181102163054-1fc5c315e03c/go.mod h1:ComeND github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw= github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/weaveworks/billing-client v0.0.0-20171006123215-be0d55e547b1/go.mod h1:7gGdEUJaCrSlWi/mjd68CZv0sfqektYPDcro9cE+M9k= -github.com/weaveworks/common v0.0.0-20200201141823-27e183090ab1 h1:nhoCrldzSm1le34sZfSNyTELYxIDaAmDw6PPVoEj5Mw= -github.com/weaveworks/common v0.0.0-20200201141823-27e183090ab1/go.mod h1:KLGX4H1D0lPVfHS/hqO9yrKvDzaT0bqYftIW43iLaOc= +github.com/weaveworks/common v0.0.0-20200206153930-760e36ae819a h1:4Sm4LnEnP1yQ2NeNgGqLTuN2xrTvcBOU+EsljpB8Ed0= +github.com/weaveworks/common v0.0.0-20200206153930-760e36ae819a/go.mod h1:6enWAqfQBFrE8X/XdJwZr8IKgh1chStuFR0mjU/UOUw= github.com/weaveworks/promrus v1.2.0 h1:jOLf6pe6/vss4qGHjXmGz4oDJQA+AOCqEL3FvvZGz7M= github.com/weaveworks/promrus v1.2.0/go.mod h1:SaE82+OJ91yqjrE1rsvBWVzNZKcHYFtMUyS1+Ogs/KA= github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= @@ -732,7 +721,6 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20190709142735-eb7dd97135a5/go.mod h1:N0RPWo9FXJYZQI4BTkDtQylrstIigYHeR18ONnyTufk= go.mongodb.org/mongo-driver v1.0.3 h1:GKoji1ld3tw2aC+GX1wbr/J2fX13yNacEYoJ8Nhr0yU= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.0.4/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0 h1:aeOqSrhl9eDRAap/3T5pCfMBEBxZ0vuXBP+RMtp2KX8= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -764,7 +752,6 @@ golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8U 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-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708 h1:pXVtWnwHkrWD9ru3sDxY/qFK/bfc0egRovX91EjWjf4= @@ -790,8 +777,8 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU 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 h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E= -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= @@ -822,6 +809,8 @@ golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343 h1:00ohfJ4K98s3m6BGUoBd8nyfp4Yl0GoIKvw5abItTjI= golang.org/x/net v0.0.0-20191112182307-2180aed22343/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-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -916,8 +905,9 @@ golang.org/x/tools v0.0.0-20191111182352-50fa39b762bc/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2 h1:EtTFh6h4SAKemS+CURDMTDIANuduG5zKEXShyy18bGA= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd h1:hHkvGJK23seRCflePJnVa9IMv8fsuavSCWKd11kDQFs= -golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200306191617-51e69f71924f h1:bFIWQKTZ5vXyr7xMDvzbWUj5Y/WBE4a4sf35MAyZjx0= +golang.org/x/tools v0.0.0-20200306191617-51e69f71924f/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 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= @@ -998,6 +988,8 @@ 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 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1019,7 +1011,6 @@ k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30 h1:TRb4wNWoBVrH9plmkp2q86FIDppkbrEXdXlxU3a3BMI= k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/utils v0.0.0-20190221042446-c2654d5206da/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0= -k8s.io/utils v0.0.0-20190809000727-6c36bc71fc4a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6 h1:p0Ai3qVtkbCG/Af26dBmU0E1W58NID3hSSh7cMyylpM= k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/mixin/thanos/README.md b/mixin/README.md similarity index 97% rename from mixin/thanos/README.md rename to mixin/README.md index 7f35050e50..64eb5523fd 100644 --- a/mixin/thanos/README.md +++ b/mixin/README.md @@ -54,9 +54,9 @@ $ jb update #### Configure -This project is intended to be used as a library. You can extend and customize dashboards and alerting rules by creating for own generators, such as the generators ([alerts.jsonnet](alerts.jsonnet) and [dashboards.jsonnet](dashboards.jsonnet)) that are use to create [examples](../../examples). Default parameters are collected in [defaults.libsonnet](defaults.libsonnet), feel free to modify and generate your own definitons. +This project is intended to be used as a library. You can extend and customize dashboards and alerting rules by creating for own generators, such as the generators ([alerts.jsonnet](alerts.jsonnet) and [dashboards.jsonnet](dashboards.jsonnet)) that are use to create [examples](../../examples). Default parameters are collected in [config.libsonnet](config.libsonnet), feel free to modify and generate your own definitons. -[embedmd]:# (defaults.libsonnet) +[embedmd]:# (config.libsonnet) ```libsonnet { query+:: { diff --git a/mixin/alerts.jsonnet b/mixin/alerts.jsonnet new file mode 100644 index 0000000000..23f4afea68 --- /dev/null +++ b/mixin/alerts.jsonnet @@ -0,0 +1,3 @@ +( + import 'mixin.libsonnet' +).prometheusAlerts diff --git a/mixin/thanos/alerts/absent.libsonnet b/mixin/alerts/absent.libsonnet similarity index 100% rename from mixin/thanos/alerts/absent.libsonnet rename to mixin/alerts/absent.libsonnet diff --git a/mixin/thanos/alerts/alerts.libsonnet b/mixin/alerts/alerts.libsonnet similarity index 100% rename from mixin/thanos/alerts/alerts.libsonnet rename to mixin/alerts/alerts.libsonnet diff --git a/mixin/thanos/alerts/bucket_replicate.libsonnet b/mixin/alerts/bucket_replicate.libsonnet similarity index 87% rename from mixin/thanos/alerts/bucket_replicate.libsonnet rename to mixin/alerts/bucket_replicate.libsonnet index fa6bdfbe27..7517187c4e 100644 --- a/mixin/thanos/alerts/bucket_replicate.libsonnet +++ b/mixin/alerts/bucket_replicate.libsonnet @@ -1,8 +1,9 @@ { local thanos = self, bucket_replicate+:: { - jobPrefix: error 'must provide job prefix for Thanos Bucket Replicate dashboard', selector: error 'must provide selector for Thanos Bucket Replicate dashboard', + errorThreshold: 10, + p99LatencyThreshold: 20, }, prometheusAlerts+:: { groups+: [ @@ -32,7 +33,7 @@ sum(rate(thanos_replicate_replication_runs_total{result="error", %(selector)s}[5m])) / on (namespace) group_left sum(rate(thanos_replicate_replication_runs_total{%(selector)s}[5m])) - ) * 100 >= 10 + ) * 100 >= %(errorThreshold)s ||| % thanos.bucket_replicate, 'for': '5m', labels: { @@ -46,7 +47,7 @@ }, expr: ||| ( - histogram_quantile(0.9, sum by (job, le) (thanos_replicate_replication_run_duration_seconds_bucket{%(selector)s})) > 120 + histogram_quantile(0.9, sum by (job, le) (rate(thanos_replicate_replication_run_duration_seconds_bucket{%(selector)s}[5m]))) > %(p99LatencyThreshold)s and sum by (job) (rate(thanos_replicate_replication_run_duration_seconds_bucket{%(selector)s}[5m])) > 0 ) diff --git a/mixin/thanos/alerts/compact.libsonnet b/mixin/alerts/compact.libsonnet similarity index 94% rename from mixin/thanos/alerts/compact.libsonnet rename to mixin/alerts/compact.libsonnet index 04c1115f2d..87bcfa13a7 100644 --- a/mixin/thanos/alerts/compact.libsonnet +++ b/mixin/alerts/compact.libsonnet @@ -1,8 +1,9 @@ { local thanos = self, compact+:: { - jobPrefix: error 'must provide job prefix for Thanos Compact alerts', selector: error 'must provide selector for Thanos Compact alerts', + compactionErrorThreshold: 5, + bucketOpsErrorThreshold: 5, }, prometheusAlerts+:: { groups+: [ @@ -41,7 +42,7 @@ sum by (job) (rate(thanos_compact_group_compactions_failures_total{%(selector)s}[5m])) / sum by (job) (rate(thanos_compact_group_compactions_total{%(selector)s}[5m])) - * 100 > 5 + * 100 > %(compactionErrorThreshold)s ) ||| % thanos.compact, 'for': '15m', @@ -59,7 +60,7 @@ sum by (job) (rate(thanos_objstore_bucket_operation_failures_total{%(selector)s}[5m])) / sum by (job) (rate(thanos_objstore_bucket_operations_total{%(selector)s}[5m])) - * 100 > 5 + * 100 > %(bucketOpsErrorThreshold)s ) ||| % thanos.compact, 'for': '15m', diff --git a/mixin/thanos/alerts/query.libsonnet b/mixin/alerts/query.libsonnet similarity index 86% rename from mixin/thanos/alerts/query.libsonnet rename to mixin/alerts/query.libsonnet index 88c682c411..6326c846a7 100644 --- a/mixin/thanos/alerts/query.libsonnet +++ b/mixin/alerts/query.libsonnet @@ -1,8 +1,12 @@ { local thanos = self, query+:: { - jobPrefix: error 'must provide job prefix for Thanos Query alerts', selector: error 'must provide selector for Thanos Query alerts', + httpErrorThreshold: 5, + grpcErrorThreshold: 5, + dnsErrorThreshold: 1, + p99QueryLatencyThreshold: 40, + p99QueryRangeLatencyThreshold: 90, }, prometheusAlerts+:: { groups+: [ @@ -19,7 +23,7 @@ sum(rate(http_requests_total{code=~"5..", %(selector)s, handler="query"}[5m])) / sum(rate(http_requests_total{%(selector)s, handler="query"}[5m])) - ) * 100 > 5 + ) * 100 > %(httpErrorThreshold)s ||| % thanos.query, 'for': '5m', labels: { @@ -36,7 +40,7 @@ sum(rate(http_requests_total{code=~"5..", %(selector)s, handler="query_range"}[5m])) / sum(rate(http_requests_total{%(selector)s, handler="query_range"}[5m])) - ) * 100 > 5 + ) * 100 > %(httpErrorThreshold)s ||| % thanos.query, 'for': '5m', labels: { @@ -53,7 +57,7 @@ sum by (job) (rate(grpc_server_handled_total{grpc_code=~"Unknown|ResourceExhausted|Internal|Unavailable|DataLoss|DeadlineExceeded", %(selector)s}[5m])) / sum by (job) (rate(grpc_server_started_total{%(selector)s}[5m])) - * 100 > 5 + * 100 > %(grpcErrorThreshold)s ) ||| % thanos.query, 'for': '5m', @@ -71,7 +75,7 @@ sum by (job) (rate(grpc_client_handled_total{grpc_code!="OK", %(selector)s}[5m])) / sum by (job) (rate(grpc_client_started_total{%(selector)s}[5m])) - ) * 100 > 5 + ) * 100 > %(grpcErrorThreshold)s ||| % thanos.query, 'for': '5m', labels: { @@ -88,7 +92,7 @@ sum by (job) (rate(thanos_querier_store_apis_dns_failures_total{%(selector)s}[5m])) / sum by (job) (rate(thanos_querier_store_apis_dns_lookups_total{%(selector)s}[5m])) - ) * 100 > 1 + ) * 100 > %(dnsErrorThreshold)s ||| % thanos.query, 'for': '15m', labels: { @@ -102,7 +106,7 @@ }, expr: ||| ( - histogram_quantile(0.99, sum by (job, le) (http_request_duration_seconds_bucket{%(selector)s, handler="query"})) > 90 + histogram_quantile(0.99, sum by (job, le) (rate(http_request_duration_seconds_bucket{%(selector)s, handler="query"}[5m]))) > %(p99QueryLatencyThreshold)s and sum by (job) (rate(http_request_duration_seconds_bucket{%(selector)s, handler="query"}[5m])) > 0 ) @@ -119,7 +123,7 @@ }, expr: ||| ( - histogram_quantile(0.99, sum by (job, le) (http_request_duration_seconds_bucket{%(selector)s, handler="query_range"})) > 90 + histogram_quantile(0.99, sum by (job, le) (rate(http_request_duration_seconds_bucket{%(selector)s, handler="query_range"}[5m]))) > %(p99QueryRangeLatencyThreshold)s and sum by (job) (rate(http_request_duration_seconds_count{%(selector)s, handler="query_range"}[5m])) > 0 ) diff --git a/mixin/thanos/alerts/receive.libsonnet b/mixin/alerts/receive.libsonnet similarity index 79% rename from mixin/thanos/alerts/receive.libsonnet rename to mixin/alerts/receive.libsonnet index 94c6410d35..9750681cf7 100644 --- a/mixin/thanos/alerts/receive.libsonnet +++ b/mixin/alerts/receive.libsonnet @@ -1,8 +1,11 @@ { local thanos = self, receive+:: { - jobPrefix: error 'must provide job prefix for Thanos Receive alerts', selector: error 'must provide selector for Thanos Receive alerts', + httpErrorThreshold: 5, + forwardErrorThreshold: 5, + refreshErrorThreshold: 0, + p99LatencyThreshold: 10, }, prometheusAlerts+:: { groups+: [ @@ -19,7 +22,7 @@ sum(rate(http_requests_total{code=~"5..", %(selector)s, handler="receive"}[5m])) / sum(rate(http_requests_total{%(selector)s, handler="receive"}[5m])) - ) * 100 > 5 + ) * 100 > %(httpErrorThreshold)s ||| % thanos.receive, 'for': '5m', labels: { @@ -33,7 +36,7 @@ }, expr: ||| ( - histogram_quantile(0.99, sum by (job, le) (http_request_duration_seconds_bucket{%(selector)s, handler="receive"})) > 10 + histogram_quantile(0.99, sum by (job, le) (rate(http_request_duration_seconds_bucket{%(selector)s, handler="receive"}[5m]))) > %(p99LatencyThreshold)s and sum by (job) (rate(http_request_duration_seconds_count{%(selector)s, handler="receive"}[5m])) > 0 ) @@ -53,7 +56,7 @@ sum by (job) (rate(thanos_receive_forward_requests_total{result="error", %(selector)s}[5m])) / sum by (job) (rate(thanos_receive_forward_requests_total{%(selector)s}[5m])) - * 100 > 5 + * 100 > %(forwardErrorThreshold)s ) ||| % thanos.receive, 'for': '5m', @@ -71,7 +74,7 @@ sum by (job) (rate(thanos_receive_hashrings_file_errors_total{%(selector)s}[5m])) / sum by (job) (rate(thanos_receive_hashrings_file_refreshes_total{%(selector)s}[5m])) - > 0 + > %(refreshErrorThreshold)s ) ||| % thanos.receive, 'for': '15m', @@ -90,6 +93,17 @@ severity: 'warning', }, }, + { + alert: 'ThanosReceiveNoUpload', + annotations: { + message: 'Thanos Receive {{$labels.job}} has not uploaded latest data to object storage.', + }, + expr: 'increase(thanos_shipper_uploads_total{%(selector)s}[2h]) == 0' % thanos.receive, + 'for': '30m', + labels: { + severity: 'warning', + }, + }, ], }, ], diff --git a/mixin/thanos/alerts/rule.libsonnet b/mixin/alerts/rule.libsonnet similarity index 71% rename from mixin/thanos/alerts/rule.libsonnet rename to mixin/alerts/rule.libsonnet index 6d562bc9d4..c0106bcfb0 100644 --- a/mixin/thanos/alerts/rule.libsonnet +++ b/mixin/alerts/rule.libsonnet @@ -1,8 +1,11 @@ { local thanos = self, rule+:: { - jobPrefix: error 'must provide job prefix for Thanos Rule alerts', selector: error 'must provide selector for Thanos Rule alerts', + grpcErrorThreshold: 5, + rulerDnsErrorThreshold: 1, + alertManagerDnsErrorThreshold: 1, + evalErrorThreshold: 5, }, prometheusAlerts+:: { groups+: [ @@ -45,13 +48,13 @@ sum by (job) (rate(prometheus_rule_evaluation_failures_total{%(selector)s}[5m])) / sum by (job) (rate(prometheus_rule_evaluations_total{%(selector)s}[5m])) - * 100 > 5 + * 100 > %(evalErrorThreshold)s ) ||| % thanos.rule, 'for': '5m', labels: { - severity: 'warning', + severity: 'critical', }, }, { @@ -95,7 +98,7 @@ sum by (job) (rate(grpc_server_handled_total{grpc_code=~"Unknown|ResourceExhausted|Internal|Unavailable|DataLoss|DeadlineExceeded", %(selector)s}[5m])) / sum by (job) (rate(grpc_server_started_total{%(selector)s}[5m])) - * 100 > 5 + * 100 > %(grpcErrorThreshold)s ) ||| % thanos.rule, 'for': '5m', @@ -117,14 +120,14 @@ { alert: 'ThanosRuleQueryHighDNSFailures', annotations: { - message: 'Thanos Rule {{$labels.job}} have {{ $value | humanize }}% of failing DNS queries for query endpoints.', + message: 'Thanos Rule {{$labels.job}} has {{ $value | humanize }}% of failing DNS queries for query endpoints.', }, expr: ||| ( sum by (job) (rate(thanos_ruler_query_apis_dns_failures_total{%(selector)s}[5m])) / sum by (job) (rate(thanos_ruler_query_apis_dns_lookups_total{%(selector)s}[5m])) - * 100 > 1 + * 100 > %(rulerDnsErrorThreshold)s ) ||| % thanos.rule, 'for': '15m', @@ -135,14 +138,14 @@ { alert: 'ThanosRuleAlertmanagerHighDNSFailures', annotations: { - message: 'Thanos Rule {{$labels.job}} have {{ $value | humanize }}% of failing DNS queries for Alertmanager endpoints.', + message: 'Thanos Rule {{$labels.job}} has {{ $value | humanize }}% of failing DNS queries for Alertmanager endpoints.', }, expr: ||| ( sum by (job) (rate(thanos_ruler_alertmanagers_dns_failures_total{%(selector)s}[5m])) / sum by (job) (rate(thanos_ruler_alertmanagers_dns_lookups_total{%(selector)s}[5m])) - * 100 > 1 + * 100 > %(alertManagerDnsErrorThreshold)s ) ||| % thanos.rule, 'for': '15m', @@ -150,6 +153,37 @@ severity: 'warning', }, }, + { + // NOTE: This alert will give false positive if no rules are configured. + alert: 'ThanosRuleNoEvaluationFor10Intervals', + annotations: { + message: 'Thanos Rule {{$labels.job}} has {{ $value | humanize }}% rule groups that did not evaluate for at least 10x of their expected interval.', + }, + expr: ||| + time() - max by (job, group) (prometheus_rule_group_last_evaluation_timestamp_seconds{%(selector)s}) + > + 10 * max by (job, group) (prometheus_rule_group_interval_seconds{%(selector)s}) + ||| % thanos.rule, + 'for': '5m', + labels: { + // TODO(bwplotka): Move to critical once we gain more confidence in this, it's not trivial as it looks. + severity: 'info', + }, + }, + { + alert: 'ThanosNoRuleEvaluations', + annotations: { + message: 'Thanos Rule {{$labels.job}} did not perform any rule evaluations in the past 2 minutes.', + }, + expr: ||| + sum(rate(prometheus_rule_evaluations_total{%(selector)s}[2m])) <= 0 + and + sum(thanos_rule_loaded_rules{%(selector)s}) > 0 + ||| % thanos.rule, + labels: { + severity: 'critical', + }, + }, ], }, ], diff --git a/mixin/thanos/alerts/sidecar.libsonnet b/mixin/alerts/sidecar.libsonnet similarity index 94% rename from mixin/thanos/alerts/sidecar.libsonnet rename to mixin/alerts/sidecar.libsonnet index 58aee3bb0b..c81e2ba0a9 100644 --- a/mixin/thanos/alerts/sidecar.libsonnet +++ b/mixin/alerts/sidecar.libsonnet @@ -1,7 +1,6 @@ { local thanos = self, sidecar+:: { - jobPrefix: error 'must provide job prefix for Thanos Sidecar alerts', selector: error 'must provide selector for Thanos Sidecar alerts', }, prometheusAlerts+:: { diff --git a/mixin/thanos/alerts/store.libsonnet b/mixin/alerts/store.libsonnet similarity index 81% rename from mixin/thanos/alerts/store.libsonnet rename to mixin/alerts/store.libsonnet index 77ff1baedd..04d723ffaa 100644 --- a/mixin/thanos/alerts/store.libsonnet +++ b/mixin/alerts/store.libsonnet @@ -1,8 +1,12 @@ { local thanos = self, store+:: { - jobPrefix: error 'must provide job prefix for Thanos Store alerts', selector: error 'must provide selector for Thanos Store alerts', + grpcErrorThreshold: 5, + compactionErrorThreshold: 5, + seriesGateErrorThreshold: 2, + bucketOpsErrorThreshold: 5, + bucketOpsP99LatencyThreshold: 2, }, prometheusAlerts+:: { groups+: [ @@ -19,7 +23,7 @@ sum by (job) (rate(grpc_server_handled_total{grpc_code=~"Unknown|ResourceExhausted|Internal|Unavailable|DataLoss|DeadlineExceeded", %(selector)s}[5m])) / sum by (job) (rate(grpc_server_started_total{%(selector)s}[5m])) - * 100 > 5 + * 100 > %(grpcErrorThreshold)s ) ||| % thanos.store, 'for': '5m', @@ -34,7 +38,7 @@ }, expr: ||| ( - histogram_quantile(0.9, sum by (job, le) (thanos_bucket_store_series_gate_duration_seconds_bucket{%(selector)s})) > 2 + histogram_quantile(0.9, sum by (job, le) (rate(thanos_bucket_store_series_gate_duration_seconds_bucket{%(selector)s}[5m]))) > %(seriesGateErrorThreshold)s and sum by (job) (rate(thanos_bucket_store_series_gate_duration_seconds_count{%(selector)s}[5m])) > 0 ) @@ -54,7 +58,7 @@ sum by (job) (rate(thanos_objstore_bucket_operation_failures_total{%(selector)s}[5m])) / sum by (job) (rate(thanos_objstore_bucket_operations_total{%(selector)s}[5m])) - * 100 > 5 + * 100 > %(bucketOpsErrorThreshold)s ) ||| % thanos.store, 'for': '15m', @@ -69,7 +73,7 @@ }, expr: ||| ( - histogram_quantile(0.9, sum by (job, le) (thanos_objstore_bucket_operation_duration_seconds_bucket{%(selector)s})) > 15 + histogram_quantile(0.9, sum by (job, le) (rate(thanos_objstore_bucket_operation_duration_seconds_bucket{%(selector)s}[5m]))) > %(bucketOpsP99LatencyThreshold)s and sum by (job) (rate(thanos_objstore_bucket_operation_duration_seconds_count{%(selector)s}[5m])) > 0 ) diff --git a/mixin/thanos/defaults.libsonnet b/mixin/config.libsonnet similarity index 100% rename from mixin/thanos/defaults.libsonnet rename to mixin/config.libsonnet diff --git a/mixin/dashboards.jsonnet b/mixin/dashboards.jsonnet new file mode 100644 index 0000000000..94353a6c15 --- /dev/null +++ b/mixin/dashboards.jsonnet @@ -0,0 +1,9 @@ +local dashboards = + ( + import 'mixin.libsonnet' + ).grafanaDashboards; + +{ + [name]: dashboards[name] + for name in std.objectFields(dashboards) +} diff --git a/mixin/thanos/dashboards/bucket_replicate.libsonnet b/mixin/dashboards/bucket_replicate.libsonnet similarity index 100% rename from mixin/thanos/dashboards/bucket_replicate.libsonnet rename to mixin/dashboards/bucket_replicate.libsonnet diff --git a/mixin/thanos/dashboards/compact.libsonnet b/mixin/dashboards/compact.libsonnet similarity index 100% rename from mixin/thanos/dashboards/compact.libsonnet rename to mixin/dashboards/compact.libsonnet diff --git a/mixin/thanos/dashboards/dashboards.libsonnet b/mixin/dashboards/dashboards.libsonnet similarity index 100% rename from mixin/thanos/dashboards/dashboards.libsonnet rename to mixin/dashboards/dashboards.libsonnet diff --git a/mixin/thanos/dashboards/defaults.libsonnet b/mixin/dashboards/defaults.libsonnet similarity index 100% rename from mixin/thanos/dashboards/defaults.libsonnet rename to mixin/dashboards/defaults.libsonnet diff --git a/mixin/thanos/dashboards/overview.libsonnet b/mixin/dashboards/overview.libsonnet similarity index 100% rename from mixin/thanos/dashboards/overview.libsonnet rename to mixin/dashboards/overview.libsonnet diff --git a/mixin/thanos/dashboards/query.libsonnet b/mixin/dashboards/query.libsonnet similarity index 100% rename from mixin/thanos/dashboards/query.libsonnet rename to mixin/dashboards/query.libsonnet diff --git a/mixin/thanos/dashboards/receive.libsonnet b/mixin/dashboards/receive.libsonnet similarity index 100% rename from mixin/thanos/dashboards/receive.libsonnet rename to mixin/dashboards/receive.libsonnet diff --git a/mixin/thanos/dashboards/rule.libsonnet b/mixin/dashboards/rule.libsonnet similarity index 100% rename from mixin/thanos/dashboards/rule.libsonnet rename to mixin/dashboards/rule.libsonnet diff --git a/mixin/thanos/dashboards/sidecar.libsonnet b/mixin/dashboards/sidecar.libsonnet similarity index 100% rename from mixin/thanos/dashboards/sidecar.libsonnet rename to mixin/dashboards/sidecar.libsonnet diff --git a/mixin/thanos/dashboards/store.libsonnet b/mixin/dashboards/store.libsonnet similarity index 96% rename from mixin/thanos/dashboards/store.libsonnet rename to mixin/dashboards/store.libsonnet index 756578989b..7b3a8df815 100644 --- a/mixin/thanos/dashboards/store.libsonnet +++ b/mixin/dashboards/store.libsonnet @@ -60,15 +60,15 @@ local g = import '../lib/thanos-grafana-builder/builder.libsonnet'; g.row('Detailed') .addPanel( g.panel('Rate', 'Shows rate of handled Streamed gRPC requests from queriers.') + - g.grpcQpsPanelDetailed('client', 'namespace="$namespace",job=~"$job",grpc_type="server_stream"') + g.grpcQpsPanelDetailed('server', 'namespace="$namespace",job=~"$job",grpc_type="server_stream"') ) .addPanel( g.panel('Errors', 'Shows ratio of errors compared to the total number of handled requests from queriers.') + - g.grpcErrDetailsPanel('client', 'namespace="$namespace",job=~"$job",grpc_type="server_stream"') + g.grpcErrDetailsPanel('server', 'namespace="$namespace",job=~"$job",grpc_type="server_stream"') ) .addPanel( g.panel('Duration', 'Shows how long has it taken to handle requests from queriers, in quantiles.') + - g.grpcLatencyPanelDetailed('client', 'namespace="$namespace",job=~"$job",grpc_type="server_stream"') + g.grpcLatencyPanelDetailed('server', 'namespace="$namespace",job=~"$job",grpc_type="server_stream"') ) + g.collapse ) @@ -165,7 +165,7 @@ local g = import '../lib/thanos-grafana-builder/builder.libsonnet'; .addRow( g.row('Store Sent') .addPanel( - g.panel('Chunk Size', 'Shows size of chunks that have sent to the bucket, in bytes.') + + g.panel('Chunk Size', 'Shows size of chunks that have sent to the bucket.') + g.queryPanel( [ 'histogram_quantile(0.99, sum(rate(thanos_bucket_store_sent_chunk_size_bytes_bucket{namespace="$namespace",job=~"$job"}[$interval])) by (job, le))', @@ -177,9 +177,9 @@ local g = import '../lib/thanos-grafana-builder/builder.libsonnet'; 'mean', 'P50', ], - ) - ) + - { yaxes: g.yaxes('decbytes') }, + ) + + { yaxes: g.yaxes('bytes') } + ), ) .addRow( g.row('Series Operations') @@ -198,7 +198,7 @@ local g = import '../lib/thanos-grafana-builder/builder.libsonnet'; ) ) .addPanel( - g.panel('Data Fetched') + + g.panel('Data Fetched', 'Show the size of data fetched') + g.queryPanel( [ 'thanos_bucket_store_series_data_fetched{namespace="$namespace",job=~"$job",quantile="0.99"}', @@ -209,7 +209,8 @@ local g = import '../lib/thanos-grafana-builder/builder.libsonnet'; 'mean {{job}}', 'P50', ], - ) + ) + + { yaxes: g.yaxes('bytes') } ) .addPanel( g.panel('Result series') + diff --git a/mixin/jsonnetfile.json b/mixin/jsonnetfile.json index 8f8d9d3559..45189debbf 100644 --- a/mixin/jsonnetfile.json +++ b/mixin/jsonnetfile.json @@ -17,15 +17,6 @@ } }, "version": "master" - }, - { - "source": { - "local": { - "directory": "thanos" - } - }, - "version": ".", - "name": "thanos-mixin" } ], "legacyImports": true diff --git a/mixin/jsonnetfile.lock.json b/mixin/jsonnetfile.lock.json index f2a1581a48..403c88e68a 100644 --- a/mixin/jsonnetfile.lock.json +++ b/mixin/jsonnetfile.lock.json @@ -19,15 +19,6 @@ }, "version": "f4c59f64f80442f871a06c91edf74d014b82acaf", "sum": "ELsYwK+kGdzX1mee2Yy+/b2mdO4Y503BOCDkFzwmGbE=" - }, - { - "source": { - "local": { - "directory": "thanos" - } - }, - "version": "", - "name": "thanos-mixin" } ], "legacyImports": false diff --git a/mixin/thanos/lib/thanos-grafana-builder/README.md b/mixin/lib/thanos-grafana-builder/README.md similarity index 100% rename from mixin/thanos/lib/thanos-grafana-builder/README.md rename to mixin/lib/thanos-grafana-builder/README.md diff --git a/mixin/thanos/lib/thanos-grafana-builder/builder.libsonnet b/mixin/lib/thanos-grafana-builder/builder.libsonnet similarity index 99% rename from mixin/thanos/lib/thanos-grafana-builder/builder.libsonnet rename to mixin/lib/thanos-grafana-builder/builder.libsonnet index a68e8065b3..4153b6ad85 100644 --- a/mixin/thanos/lib/thanos-grafana-builder/builder.libsonnet +++ b/mixin/lib/thanos-grafana-builder/builder.libsonnet @@ -168,7 +168,8 @@ local template = grafana.template; 'inuse stack {{pod}}', 'inuse heap {{pod}}', ] - ), + ) + + { yaxes: $.yaxes('bytes') }, ) .addPanel( $.panel('Goroutines') + diff --git a/mixin/thanos/lib/thanos-grafana-builder/grpc.libsonnet b/mixin/lib/thanos-grafana-builder/grpc.libsonnet similarity index 100% rename from mixin/thanos/lib/thanos-grafana-builder/grpc.libsonnet rename to mixin/lib/thanos-grafana-builder/grpc.libsonnet diff --git a/mixin/thanos/lib/thanos-grafana-builder/http.libsonnet b/mixin/lib/thanos-grafana-builder/http.libsonnet similarity index 100% rename from mixin/thanos/lib/thanos-grafana-builder/http.libsonnet rename to mixin/lib/thanos-grafana-builder/http.libsonnet diff --git a/mixin/thanos/lib/thanos-grafana-builder/slo.libsonnet b/mixin/lib/thanos-grafana-builder/slo.libsonnet similarity index 100% rename from mixin/thanos/lib/thanos-grafana-builder/slo.libsonnet rename to mixin/lib/thanos-grafana-builder/slo.libsonnet diff --git a/mixin/thanos/mixin.libsonnet b/mixin/mixin.libsonnet similarity index 56% rename from mixin/thanos/mixin.libsonnet rename to mixin/mixin.libsonnet index 6590c396e4..8aa275ccbb 100644 --- a/mixin/thanos/mixin.libsonnet +++ b/mixin/mixin.libsonnet @@ -1,3 +1,4 @@ (import 'dashboards/dashboards.libsonnet') + (import 'alerts/alerts.libsonnet') + -(import 'rules/rules.libsonnet') +(import 'rules/rules.libsonnet') + +(import 'config.libsonnet') diff --git a/mixin/rules.jsonnet b/mixin/rules.jsonnet new file mode 100644 index 0000000000..1c9271ab76 --- /dev/null +++ b/mixin/rules.jsonnet @@ -0,0 +1,3 @@ +( + import 'mixin.libsonnet' +).prometheusRules diff --git a/mixin/thanos/rules/bucket_replicate.libsonnet b/mixin/rules/bucket_replicate.libsonnet similarity index 100% rename from mixin/thanos/rules/bucket_replicate.libsonnet rename to mixin/rules/bucket_replicate.libsonnet diff --git a/mixin/thanos/rules/query.libsonnet b/mixin/rules/query.libsonnet similarity index 100% rename from mixin/thanos/rules/query.libsonnet rename to mixin/rules/query.libsonnet diff --git a/mixin/thanos/rules/receive.libsonnet b/mixin/rules/receive.libsonnet similarity index 100% rename from mixin/thanos/rules/receive.libsonnet rename to mixin/rules/receive.libsonnet diff --git a/mixin/thanos/rules/rules.libsonnet b/mixin/rules/rules.libsonnet similarity index 100% rename from mixin/thanos/rules/rules.libsonnet rename to mixin/rules/rules.libsonnet diff --git a/mixin/thanos/rules/store.libsonnet b/mixin/rules/store.libsonnet similarity index 100% rename from mixin/thanos/rules/store.libsonnet rename to mixin/rules/store.libsonnet diff --git a/mixin/separated_alerts.jsonnet b/mixin/separated_alerts.jsonnet new file mode 100644 index 0000000000..329a427bf8 --- /dev/null +++ b/mixin/separated_alerts.jsonnet @@ -0,0 +1,7 @@ +{ + [group.name]: group + for group in + ( + import 'mixin.libsonnet' + ).prometheusAlerts.groups +} diff --git a/mixin/thanos/alerts.jsonnet b/mixin/thanos/alerts.jsonnet deleted file mode 100644 index 574da7f5a6..0000000000 --- a/mixin/thanos/alerts.jsonnet +++ /dev/null @@ -1,4 +0,0 @@ -( - (import 'mixin.libsonnet') + - (import 'defaults.libsonnet') -).prometheusAlerts diff --git a/mixin/thanos/dashboards.jsonnet b/mixin/thanos/dashboards.jsonnet deleted file mode 100644 index a9cd0bbfcf..0000000000 --- a/mixin/thanos/dashboards.jsonnet +++ /dev/null @@ -1,9 +0,0 @@ -local dashboards = ( - (import 'mixin.libsonnet') + - (import 'defaults.libsonnet') -).grafanaDashboards; - -{ - [name]: dashboards[name] - for name in std.objectFields(dashboards) -} diff --git a/mixin/thanos/rules.jsonnet b/mixin/thanos/rules.jsonnet deleted file mode 100644 index c50930e3b9..0000000000 --- a/mixin/thanos/rules.jsonnet +++ /dev/null @@ -1,4 +0,0 @@ -( - (import 'mixin.libsonnet') + - (import 'defaults.libsonnet') -).prometheusRules diff --git a/mixin/thanos/separated_alerts.jsonnet b/mixin/thanos/separated_alerts.jsonnet deleted file mode 100644 index 79402a0b3f..0000000000 --- a/mixin/thanos/separated_alerts.jsonnet +++ /dev/null @@ -1,7 +0,0 @@ -{ - [group.name]: group - for group in ( - (import 'mixin.libsonnet') + - (import 'defaults.libsonnet') - ).prometheusAlerts.groups -} diff --git a/netlify.toml b/netlify.toml index 9d97ed3cc2..3d471bd9d0 100644 --- a/netlify.toml +++ b/netlify.toml @@ -30,7 +30,7 @@ command = "(env && make web HUGO=$(which hugo) WEBSITE_BASE_URL=${DEPLOY_PRIME_U # Force HTTPS only. Strict-Transport-Security = "max-age=31536000; includeSubDomains" # Load scripts only via HTTPS and from allowed domains. - Content-Security-Policy = "default-src https:" + Content-Security-Policy = "default-src https:; script-src https: 'self' 'sha256-3qFt4qPvMCWVUpjUxP5X57GBKae6RHYZ0rMjn9WuNF4='; style-src https: 'self' 'sha256-ouaL9aaaKO9mYd9/M+uyzYAL1CrOXJVRjV2nFgbGI2E='; object-src 'self'" # Only send referred when HTTPS is used. Referrer-Policy = "strict-origin-when-cross-origin" # Disable certain magic features, lol. diff --git a/pkg/alert/alert.go b/pkg/alert/alert.go index 418cb5c831..0a7b4b30e1 100644 --- a/pkg/alert/alert.go +++ b/pkg/alert/alert.go @@ -23,6 +23,7 @@ import ( "github.com/pkg/errors" "github.com/prometheus/alertmanager/api/v2/models" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/pkg/labels" "github.com/thanos-io/thanos/pkg/runutil" @@ -133,34 +134,31 @@ func NewQueue(logger log.Logger, reg prometheus.Registerer, capacity, maxBatchSi toAddLset: toAdd, toExcludeLabels: toExclude, - dropped: prometheus.NewCounter(prometheus.CounterOpts{ + dropped: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_alert_queue_alerts_dropped_total", Help: "Total number of alerts that were dropped from the queue.", }), - pushed: prometheus.NewCounter(prometheus.CounterOpts{ + pushed: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_alert_queue_alerts_pushed_total", Help: "Total number of alerts pushed to the queue.", }), - popped: prometheus.NewCounter(prometheus.CounterOpts{ + popped: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_alert_queue_alerts_popped_total", Help: "Total number of alerts popped from the queue.", }), } - capMetric := prometheus.NewGaugeFunc(prometheus.GaugeOpts{ + _ = promauto.With(reg).NewGaugeFunc(prometheus.GaugeOpts{ Name: "thanos_alert_queue_capacity", Help: "Capacity of the alert queue.", }, func() float64 { return float64(q.Cap()) }) - lenMetric := prometheus.NewGaugeFunc(prometheus.GaugeOpts{ + _ = promauto.With(reg).NewGaugeFunc(prometheus.GaugeOpts{ Name: "thanos_alert_queue_length", Help: "Length of the alert queue.", }, func() float64 { return float64(q.Len()) }) - if reg != nil { - reg.MustRegister(q.pushed, q.popped, q.dropped, lenMetric, capMetric) - } return q } @@ -195,6 +193,12 @@ func (q *Queue) Pop(termc <-chan struct{}) []*Alert { q.popped.Add(float64(n)) + if len(q.queue) > 0 { + select { + case q.morec <- struct{}{}: + default: + } + } return as[:n] } @@ -292,29 +296,26 @@ func NewSender( alertmanagers: alertmanagers, versions: versions, - sent: prometheus.NewCounterVec(prometheus.CounterOpts{ + sent: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_alert_sender_alerts_sent_total", Help: "Total number of alerts sent by alertmanager.", }, []string{"alertmanager"}), - errs: prometheus.NewCounterVec(prometheus.CounterOpts{ + errs: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_alert_sender_errors_total", Help: "Total number of errors while sending alerts to alertmanager.", }, []string{"alertmanager"}), - dropped: prometheus.NewCounter(prometheus.CounterOpts{ + dropped: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_alert_sender_alerts_dropped_total", Help: "Total number of alerts dropped in case of all sends to alertmanagers failed.", }), - latency: prometheus.NewHistogramVec(prometheus.HistogramOpts{ + latency: promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{ Name: "thanos_alert_sender_latency_seconds", Help: "Latency for sending alert notifications (not including dropped notifications).", }, []string{"alertmanager"}), } - if reg != nil { - reg.MustRegister(s.sent, s.errs, s.dropped, s.latency) - } return s } @@ -330,8 +331,6 @@ func toAPILabels(labels labels.Labels) models.LabelSet { // Send an alert batch to all given Alertmanager clients. // TODO(bwplotka): https://github.com/thanos-io/thanos/issues/660. func (s *Sender) Send(ctx context.Context, alerts []*Alert) { - span, ctx := tracing.StartSpan(ctx, "/send_alerts") - defer span.Finish() if len(alerts) == 0 { return } @@ -382,22 +381,23 @@ func (s *Sender) Send(ctx context.Context, alerts []*Alert) { level.Debug(s.logger).Log("msg", "sending alerts", "alertmanager", u.Host, "numAlerts", len(alerts)) start := time.Now() u.Path = path.Join(u.Path, fmt.Sprintf("/api/%s/alerts", string(am.version))) - span, ctx := tracing.StartSpan(ctx, "post_alerts HTTP[client]") - defer span.Finish() - if err := am.postAlerts(ctx, u, bytes.NewReader(payload[am.version])); err != nil { - level.Warn(s.logger).Log( - "msg", "sending alerts failed", - "alertmanager", u.Host, - "alerts", string(payload[am.version]), - "err", err, - ) - s.errs.WithLabelValues(u.Host).Inc() - return - } - s.latency.WithLabelValues(u.Host).Observe(time.Since(start).Seconds()) - s.sent.WithLabelValues(u.Host).Add(float64(len(alerts))) - - atomic.AddUint64(&numSuccess, 1) + + tracing.DoInSpan(ctx, "post_alerts HTTP[client]", func(ctx context.Context) { + if err := am.postAlerts(ctx, u, bytes.NewReader(payload[am.version])); err != nil { + level.Warn(s.logger).Log( + "msg", "sending alerts failed", + "alertmanager", u.Host, + "alerts", string(payload[am.version]), + "err", err, + ) + s.errs.WithLabelValues(u.Host).Inc() + return + } + s.latency.WithLabelValues(u.Host).Observe(time.Since(start).Seconds()) + s.sent.WithLabelValues(u.Host).Add(float64(len(alerts))) + + atomic.AddUint64(&numSuccess, 1) + }) }(am, *u) } } diff --git a/pkg/alert/alert_test.go b/pkg/alert/alert_test.go index 7139dfc652..67f280280d 100644 --- a/pkg/alert/alert_test.go +++ b/pkg/alert/alert_test.go @@ -19,6 +19,31 @@ import ( "github.com/thanos-io/thanos/pkg/testutil" ) +func TestQueue_Pop_all_Pushed(t *testing.T) { + qcapacity := 10 + batchsize := 1 + pushes := 3 + + q := NewQueue( + nil, nil, qcapacity, batchsize, nil, nil, + ) + for i := 0; i < pushes; i++ { + q.Push([]*Alert{ + {}, + {}, + }) + } + + timeoutc := make(chan struct{}, 1) + time.AfterFunc(time.Second, func() { timeoutc <- struct{}{} }) + popped := 0 + for p := q.Pop(timeoutc); p != nil; p = q.Pop(timeoutc) { + popped += len(p) + } + + testutil.Equals(t, pushes*2, popped) +} + func TestQueue_Push_Relabelled(t *testing.T) { q := NewQueue( nil, nil, 10, 10, diff --git a/pkg/block/block.go b/pkg/block/block.go index 740b3d6306..2bc7f86aae 100644 --- a/pkg/block/block.go +++ b/pkg/block/block.go @@ -6,6 +6,7 @@ package block import ( + "bytes" "context" "encoding/json" "fmt" @@ -14,11 +15,13 @@ import ( "path" "path/filepath" "strings" + "time" "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "github.com/oklog/ulid" "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/objstore" @@ -87,7 +90,7 @@ func Upload(ctx context.Context, logger log.Logger, bkt objstore.Bucket, bdir st } if meta.Thanos.Labels == nil || len(meta.Thanos.Labels) == 0 { - return errors.Errorf("empty external labels are not allowed for Thanos block.") + return errors.New("empty external labels are not allowed for Thanos block.") } if err := objstore.UploadFile(ctx, logger, bkt, path.Join(bdir, MetaFilename), path.Join(DebugMetas, fmt.Sprintf("%s.json", id))); err != nil { @@ -126,6 +129,35 @@ func cleanUp(logger log.Logger, bkt objstore.Bucket, id ulid.ULID, err error) er return err } +// MarkForDeletion creates a file which stores information about when the block was marked for deletion. +func MarkForDeletion(ctx context.Context, logger log.Logger, bkt objstore.Bucket, id ulid.ULID, markedForDeletion prometheus.Counter) error { + deletionMarkFile := path.Join(id.String(), metadata.DeletionMarkFilename) + deletionMarkExists, err := bkt.Exists(ctx, deletionMarkFile) + if err != nil { + return errors.Wrapf(err, "check exists %s in bucket", deletionMarkFile) + } + if deletionMarkExists { + level.Warn(logger).Log("msg", "requested to mark for deletion, but file already exists; this should not happen; investigate", "err", errors.Errorf("file %s already exists in bucket", deletionMarkFile)) + return nil + } + + deletionMark, err := json.Marshal(metadata.DeletionMark{ + ID: id, + DeletionTime: time.Now().Unix(), + Version: metadata.DeletionMarkVersion1, + }) + if err != nil { + return errors.Wrap(err, "json encode deletion mark") + } + + if err := bkt.Upload(ctx, deletionMarkFile, bytes.NewBuffer(deletionMark)); err != nil { + return errors.Wrapf(err, "upload file %s to bucket", deletionMarkFile) + } + markedForDeletion.Inc() + level.Info(logger).Log("msg", "block has been marked for deletion", "block", id) + return nil +} + // Delete removes directory that is meant to be block directory. // NOTE: Always prefer this method for deleting blocks. // * We have to delete block's files in the certain order (meta.json first) @@ -138,6 +170,7 @@ func Delete(ctx context.Context, logger log.Logger, bkt objstore.Bucket, id ulid if err != nil { return errors.Wrapf(err, "stat %s", metaFile) } + if ok { if err := bkt.Delete(ctx, metaFile); err != nil { return errors.Wrapf(err, "delete %s", metaFile) @@ -145,16 +178,22 @@ func Delete(ctx context.Context, logger log.Logger, bkt objstore.Bucket, id ulid level.Debug(logger).Log("msg", "deleted file", "file", metaFile, "bucket", bkt.Name()) } - return deleteDir(ctx, logger, bkt, id.String()) + // Delete the bucket, but skip the metaFile as we just deleted that. This is required for eventual object storages (list after write). + return deleteDirRec(ctx, logger, bkt, id.String(), func(name string) bool { + return name == metaFile + }) } -// deleteDir removes all objects prefixed with dir from the bucket. +// deleteDirRec removes all objects prefixed with dir from the bucket. It skips objects that return true for the passed keep function. // NOTE: For objects removal use `block.Delete` strictly. -func deleteDir(ctx context.Context, logger log.Logger, bkt objstore.Bucket, dir string) error { +func deleteDirRec(ctx context.Context, logger log.Logger, bkt objstore.Bucket, dir string, keep func(name string) bool) error { return bkt.Iter(ctx, dir, func(name string) error { // If we hit a directory, call DeleteDir recursively. if strings.HasSuffix(name, objstore.DirDelim) { - return deleteDir(ctx, logger, bkt, name) + return deleteDirRec(ctx, logger, bkt, name, keep) + } + if keep(name) { + return nil } if err := bkt.Delete(ctx, name); err != nil { return err diff --git a/pkg/block/block_test.go b/pkg/block/block_test.go index e6bdfc8ce1..2c35197e7c 100644 --- a/pkg/block/block_test.go +++ b/pkg/block/block_test.go @@ -4,7 +4,9 @@ package block import ( + "bytes" "context" + "encoding/json" "io/ioutil" "os" "path" @@ -14,8 +16,12 @@ import ( "github.com/fortytw2/leaktest" "github.com/go-kit/kit/log" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/prometheus/prometheus/pkg/labels" - "github.com/thanos-io/thanos/pkg/objstore/inmem" + "github.com/thanos-io/thanos/pkg/block/metadata" + "github.com/thanos-io/thanos/pkg/objstore" "github.com/thanos-io/thanos/pkg/testutil" "github.com/thanos-io/thanos/pkg/testutil/e2eutil" @@ -77,7 +83,7 @@ func TestUpload(t *testing.T) { testutil.Ok(t, err) defer func() { testutil.Ok(t, os.RemoveAll(tmpDir)) }() - bkt := inmem.NewBucket() + bkt := objstore.NewInMemBucket() b1, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ {{Name: "a", Value: "1"}}, {{Name: "a", Value: "2"}}, @@ -181,7 +187,7 @@ func TestDelete(t *testing.T) { testutil.Ok(t, err) defer func() { testutil.Ok(t, os.RemoveAll(tmpDir)) }() - bkt := inmem.NewBucket() + bkt := objstore.NewInMemBucket() { b1, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ {{Name: "a", Value: "1"}}, @@ -218,3 +224,60 @@ func TestDelete(t *testing.T) { testutil.Equals(t, 2, len(bkt.Objects())) } } + +func TestMarkForDeletion(t *testing.T) { + defer leaktest.CheckTimeout(t, 10*time.Second)() + + ctx := context.Background() + + tmpDir, err := ioutil.TempDir("", "test-block-mark-for-delete") + testutil.Ok(t, err) + defer func() { testutil.Ok(t, os.RemoveAll(tmpDir)) }() + + for _, tcase := range []struct { + name string + preUpload func(t testing.TB, id ulid.ULID, bkt objstore.Bucket) + + blocksMarked int + }{ + { + name: "block marked for deletion", + preUpload: func(t testing.TB, id ulid.ULID, bkt objstore.Bucket) {}, + blocksMarked: 1, + }, + { + name: "block with deletion mark already, expected log and no metric increment", + preUpload: func(t testing.TB, id ulid.ULID, bkt objstore.Bucket) { + deletionMark, err := json.Marshal(metadata.DeletionMark{ + ID: id, + DeletionTime: time.Now().Unix(), + Version: metadata.DeletionMarkVersion1, + }) + testutil.Ok(t, err) + testutil.Ok(t, bkt.Upload(ctx, path.Join(id.String(), metadata.DeletionMarkFilename), bytes.NewReader(deletionMark))) + }, + blocksMarked: 0, + }, + } { + t.Run(tcase.name, func(t *testing.T) { + bkt := objstore.NewInMemBucket() + id, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ + {{Name: "a", Value: "1"}}, + {{Name: "a", Value: "2"}}, + {{Name: "a", Value: "3"}}, + {{Name: "a", Value: "4"}}, + {{Name: "b", Value: "1"}}, + }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "val1"}}, 124) + testutil.Ok(t, err) + + tcase.preUpload(t, id, bkt) + + testutil.Ok(t, Upload(ctx, log.NewNopLogger(), bkt, path.Join(tmpDir, id.String()))) + + c := promauto.With(nil).NewCounter(prometheus.CounterOpts{}) + err = MarkForDeletion(ctx, log.NewNopLogger(), bkt, id, c) + testutil.Ok(t, err) + testutil.Equals(t, float64(tcase.blocksMarked), promtest.ToFloat64(c)) + }) + } +} diff --git a/pkg/block/fetcher.go b/pkg/block/fetcher.go index bf288a7ad6..835f2ff191 100644 --- a/pkg/block/fetcher.go +++ b/pkg/block/fetcher.go @@ -16,9 +16,11 @@ import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" + "github.com/golang/groupcache/singleflight" "github.com/oklog/ulid" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/pkg/relabel" "github.com/prometheus/prometheus/tsdb" @@ -29,55 +31,75 @@ import ( "github.com/thanos-io/thanos/pkg/model" "github.com/thanos-io/thanos/pkg/objstore" "github.com/thanos-io/thanos/pkg/runutil" + "golang.org/x/sync/errgroup" ) -type syncMetrics struct { +type fetcherMetrics struct { syncs prometheus.Counter syncFailures prometheus.Counter syncDuration prometheus.Histogram - synced *extprom.TxGaugeVec + synced *extprom.TxGaugeVec + modified *extprom.TxGaugeVec +} + +func (s *fetcherMetrics) submit() { + s.synced.Submit() + s.modified.Submit() +} + +func (s *fetcherMetrics) resetTx() { + s.synced.ResetTx() + s.modified.ResetTx() } const ( - syncMetricSubSys = "blocks_meta" + fetcherSubSys = "blocks_meta" corruptedMeta = "corrupted-meta-json" noMeta = "no-meta-json" loadedMeta = "loaded" failedMeta = "failed" - // Filter's label values. + // Synced label values. labelExcludedMeta = "label-excluded" timeExcludedMeta = "time-excluded" tooFreshMeta = "too-fresh" duplicateMeta = "duplicate" + // Blocks that are marked for deletion can be loaded as well. This is done to make sure that we load blocks that are meant to be deleted, + // but don't have a replacement block yet. + markedForDeletionMeta = "marked-for-deletion" + + // Modified label values. + replicaRemovedMeta = "replica-label-removed" ) -func newSyncMetrics(r prometheus.Registerer) *syncMetrics { - var m syncMetrics +func newFetcherMetrics(reg prometheus.Registerer) *fetcherMetrics { + var m fetcherMetrics - m.syncs = prometheus.NewCounter(prometheus.CounterOpts{ - Subsystem: syncMetricSubSys, + m.syncs = promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Subsystem: fetcherSubSys, Name: "syncs_total", Help: "Total blocks metadata synchronization attempts", }) - m.syncFailures = prometheus.NewCounter(prometheus.CounterOpts{ - Subsystem: syncMetricSubSys, + m.syncFailures = promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Subsystem: fetcherSubSys, Name: "sync_failures_total", Help: "Total blocks metadata synchronization failures", }) - m.syncDuration = prometheus.NewHistogram(prometheus.HistogramOpts{ - Subsystem: syncMetricSubSys, + m.syncDuration = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{ + Subsystem: fetcherSubSys, Name: "sync_duration_seconds", Help: "Duration of the blocks metadata synchronization in seconds", Buckets: []float64{0.01, 1, 10, 100, 1000}, }) - m.synced = extprom.NewTxGaugeVec(prometheus.GaugeOpts{ - Subsystem: syncMetricSubSys, - Name: "synced", - Help: "Number of block metadata synced", - }, + m.synced = extprom.NewTxGaugeVec( + reg, + prometheus.GaugeOpts{ + Subsystem: fetcherSubSys, + Name: "synced", + Help: "Number of block metadata synced", + }, []string{"state"}, []string{corruptedMeta}, []string{noMeta}, @@ -87,45 +109,50 @@ func newSyncMetrics(r prometheus.Registerer) *syncMetrics { []string{labelExcludedMeta}, []string{timeExcludedMeta}, []string{duplicateMeta}, + []string{markedForDeletionMeta}, + ) + m.modified = extprom.NewTxGaugeVec( + reg, + prometheus.GaugeOpts{ + Subsystem: fetcherSubSys, + Name: "modified", + Help: "Number of blocks whose metadata changed", + }, + []string{"modified"}, + []string{replicaRemovedMeta}, ) - if r != nil { - r.MustRegister( - m.syncs, - m.syncFailures, - m.syncDuration, - m.synced, - ) - } return &m } type MetadataFetcher interface { Fetch(ctx context.Context) (metas map[ulid.ULID]*metadata.Meta, partial map[ulid.ULID]error, err error) + UpdateOnChange(func([]metadata.Meta, error)) } -type GaugeLabeled interface { - WithLabelValues(lvs ...string) prometheus.Gauge +type MetadataFilter interface { + Filter(ctx context.Context, metas map[ulid.ULID]*metadata.Meta, synced *extprom.TxGaugeVec) error } -type MetaFetcherFilter func(metas map[ulid.ULID]*metadata.Meta, synced GaugeLabeled, incompleteView bool) +type MetadataModifier interface { + Modify(ctx context.Context, metas map[ulid.ULID]*metadata.Meta, modified *extprom.TxGaugeVec) error +} -// MetaFetcher is a struct that synchronizes filtered metadata of all block in the object storage with the local state. -type MetaFetcher struct { +// BaseFetcher is a struct that synchronizes filtered metadata of all block in the object storage with the local state. +// Go-routine safe. +type BaseFetcher struct { logger log.Logger concurrency int - bkt objstore.BucketReader + bkt objstore.InstrumentedBucketReader // Optional local directory to cache meta.json files. cacheDir string - metrics *syncMetrics - - filters []MetaFetcherFilter - - cached map[ulid.ULID]*metadata.Meta + cached map[ulid.ULID]*metadata.Meta + syncs prometheus.Counter + g singleflight.Group } -// NewMetaFetcher constructs MetaFetcher. -func NewMetaFetcher(logger log.Logger, concurrency int, bkt objstore.BucketReader, dir string, r prometheus.Registerer, filters ...MetaFetcherFilter) (*MetaFetcher, error) { +// NewBaseFetcher constructs BaseFetcher. +func NewBaseFetcher(logger log.Logger, concurrency int, bkt objstore.InstrumentedBucketReader, dir string, reg prometheus.Registerer) (*BaseFetcher, error) { if logger == nil { logger = log.NewNopLogger() } @@ -138,17 +165,34 @@ func NewMetaFetcher(logger log.Logger, concurrency int, bkt objstore.BucketReade } } - return &MetaFetcher{ - logger: log.With(logger, "component", "block.MetaFetcher"), + return &BaseFetcher{ + logger: log.With(logger, "component", "block.BaseFetcher"), concurrency: concurrency, bkt: bkt, cacheDir: cacheDir, - metrics: newSyncMetrics(r), - filters: filters, cached: map[ulid.ULID]*metadata.Meta{}, + syncs: promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Subsystem: fetcherSubSys, + Name: "base_syncs_total", + Help: "Total blocks metadata synchronization attempts by base Fetcher", + }), }, nil } +// NewMetaFetcher returns meta fetcher. +func NewMetaFetcher(logger log.Logger, concurrency int, bkt objstore.InstrumentedBucketReader, dir string, reg prometheus.Registerer, filters []MetadataFilter, modifiers []MetadataModifier) (*MetaFetcher, error) { + b, err := NewBaseFetcher(logger, concurrency, bkt, dir, reg) + if err != nil { + return nil, err + } + return b.NewMetaFetcher(reg, filters, modifiers), nil +} + +// NewMetaFetcher transforms BaseFetcher into actually usable *MetaFetcher. +func (f *BaseFetcher) NewMetaFetcher(reg prometheus.Registerer, filters []MetadataFilter, modifiers []MetadataModifier, logTags ...interface{}) *MetaFetcher { + return &MetaFetcher{metrics: newFetcherMetrics(reg), wrapped: f, filters: filters, modifiers: modifiers, logger: log.With(f.logger, logTags...)} +} + var ( ErrorSyncMetaNotFound = errors.New("meta.json not found") ErrorSyncMetaCorrupted = errors.New("meta.json corrupted") @@ -156,16 +200,16 @@ var ( // loadMeta returns metadata from object storage or error. // It returns `ErrorSyncMetaNotFound` and `ErrorSyncMetaCorrupted` sentinel errors in those cases. -func (s *MetaFetcher) loadMeta(ctx context.Context, id ulid.ULID) (*metadata.Meta, error) { +func (f *BaseFetcher) loadMeta(ctx context.Context, id ulid.ULID) (*metadata.Meta, error) { var ( metaFile = path.Join(id.String(), MetaFilename) - cachedBlockDir = filepath.Join(s.cacheDir, id.String()) + cachedBlockDir = filepath.Join(f.cacheDir, id.String()) ) // TODO(bwplotka): If that causes problems (obj store rate limits), add longer ttl to cached items. // For 1y and 100 block sources this generates ~1.5-3k HEAD RPM. AWS handles 330k RPM per prefix. // TODO(bwplotka): Consider filtering by consistency delay here (can't do until compactor healthyOverride work). - ok, err := s.bkt.Exists(ctx, metaFile) + ok, err := f.bkt.Exists(ctx, metaFile) if err != nil { return nil, errors.Wrapf(err, "meta.json file exists: %v", metaFile) } @@ -173,27 +217,27 @@ func (s *MetaFetcher) loadMeta(ctx context.Context, id ulid.ULID) (*metadata.Met return nil, ErrorSyncMetaNotFound } - if m, seen := s.cached[id]; seen { + if m, seen := f.cached[id]; seen { return m, nil } // Best effort load from local dir. - if s.cacheDir != "" { + if f.cacheDir != "" { m, err := metadata.Read(cachedBlockDir) if err == nil { return m, nil } if !errors.Is(err, os.ErrNotExist) { - level.Warn(s.logger).Log("msg", "best effort read of the local meta.json failed; removing cached block dir", "dir", cachedBlockDir, "err", err) + level.Warn(f.logger).Log("msg", "best effort read of the local meta.json failed; removing cached block dir", "dir", cachedBlockDir, "err", err) if err := os.RemoveAll(cachedBlockDir); err != nil { - level.Warn(s.logger).Log("msg", "best effort remove of cached dir failed; ignoring", "dir", cachedBlockDir, "err", err) + level.Warn(f.logger).Log("msg", "best effort remove of cached dir failed; ignoring", "dir", cachedBlockDir, "err", err) } } } - r, err := s.bkt.Get(ctx, metaFile) - if s.bkt.IsObjNotFoundErr(err) { + r, err := f.bkt.ReaderWithExpectedErrs(f.bkt.IsObjNotFoundErr).Get(ctx, metaFile) + if f.bkt.IsObjNotFoundErr(err) { // Meta.json was deleted between bkt.Exists and here. return nil, errors.Wrapf(ErrorSyncMetaNotFound, "%v", err) } @@ -201,7 +245,7 @@ func (s *MetaFetcher) loadMeta(ctx context.Context, id ulid.ULID) (*metadata.Met return nil, errors.Wrapf(err, "get meta file: %v", metaFile) } - defer runutil.CloseWithLogOnErr(s.logger, r, "close bkt meta get") + defer runutil.CloseWithLogOnErr(f.logger, r, "close bkt meta get") metaContent, err := ioutil.ReadAll(r) if err != nil { @@ -218,157 +262,231 @@ func (s *MetaFetcher) loadMeta(ctx context.Context, id ulid.ULID) (*metadata.Met } // Best effort cache in local dir. - if s.cacheDir != "" { + if f.cacheDir != "" { if err := os.MkdirAll(cachedBlockDir, os.ModePerm); err != nil { - level.Warn(s.logger).Log("msg", "best effort mkdir of the meta.json block dir failed; ignoring", "dir", cachedBlockDir, "err", err) + level.Warn(f.logger).Log("msg", "best effort mkdir of the meta.json block dir failed; ignoring", "dir", cachedBlockDir, "err", err) } - if err := metadata.Write(s.logger, cachedBlockDir, m); err != nil { - level.Warn(s.logger).Log("msg", "best effort save of the meta.json to local dir failed; ignoring", "dir", cachedBlockDir, "err", err) + if err := metadata.Write(f.logger, cachedBlockDir, m); err != nil { + level.Warn(f.logger).Log("msg", "best effort save of the meta.json to local dir failed; ignoring", "dir", cachedBlockDir, "err", err) } } return m, nil } -// Fetch returns all block metas as well as partial blocks (blocks without or with corrupted meta file) from the bucket. -// It's caller responsibility to not change the returned metadata files. Maps can be modified. -// -// Returned error indicates a failure in fetching metadata. Returned meta can be assumed as correct, with some blocks missing. -func (s *MetaFetcher) Fetch(ctx context.Context) (metas map[ulid.ULID]*metadata.Meta, partial map[ulid.ULID]error, err error) { - start := time.Now() - defer func() { - s.metrics.syncDuration.Observe(time.Since(start).Seconds()) - if err != nil { - s.metrics.syncFailures.Inc() - } - }() - s.metrics.syncs.Inc() +type response struct { + metas map[ulid.ULID]*metadata.Meta + partial map[ulid.ULID]error + // If metaErr > 0 it means incomplete view, so some metas, failed to be loaded. + metaErrs tsdberrors.MultiError + + noMetas float64 + corruptedMetas float64 +} - metas = make(map[ulid.ULID]*metadata.Meta) - partial = make(map[ulid.ULID]error) +func (f *BaseFetcher) fetchMetadata(ctx context.Context) (interface{}, error) { + f.syncs.Inc() var ( - wg sync.WaitGroup - ch = make(chan ulid.ULID, s.concurrency) + resp = response{ + metas: make(map[ulid.ULID]*metadata.Meta), + partial: make(map[ulid.ULID]error), + } + eg errgroup.Group + ch = make(chan ulid.ULID, f.concurrency) mtx sync.Mutex - - metaErrs tsdberrors.MultiError ) - - s.metrics.synced.ResetTx() - - for i := 0; i < s.concurrency; i++ { - wg.Add(1) - go func() { - defer wg.Done() - + for i := 0; i < f.concurrency; i++ { + eg.Go(func() error { for id := range ch { - meta, err := s.loadMeta(ctx, id) + meta, err := f.loadMeta(ctx, id) if err == nil { mtx.Lock() - metas[id] = meta + resp.metas[id] = meta mtx.Unlock() continue } switch errors.Cause(err) { default: - s.metrics.synced.WithLabelValues(failedMeta).Inc() mtx.Lock() - metaErrs.Add(err) + resp.metaErrs.Add(err) mtx.Unlock() continue case ErrorSyncMetaNotFound: - s.metrics.synced.WithLabelValues(noMeta).Inc() + mtx.Lock() + resp.noMetas++ + mtx.Unlock() case ErrorSyncMetaCorrupted: - s.metrics.synced.WithLabelValues(corruptedMeta).Inc() + mtx.Lock() + resp.corruptedMetas++ + mtx.Unlock() } mtx.Lock() - partial[id] = err + resp.partial[id] = err mtx.Unlock() } - }() + return nil + }) } // Workers scheduled, distribute blocks. - err = s.bkt.Iter(ctx, "", func(name string) error { - id, ok := IsBlockDir(name) - if !ok { - return nil - } + eg.Go(func() error { + defer close(ch) + return f.bkt.Iter(ctx, "", func(name string) error { + id, ok := IsBlockDir(name) + if !ok { + return nil + } - select { - case <-ctx.Done(): - return ctx.Err() - case ch <- id: - } + select { + case <-ctx.Done(): + return ctx.Err() + case ch <- id: + } - return nil + return nil + }) }) - close(ch) - wg.Wait() - if err != nil { - return nil, nil, errors.Wrap(err, "MetaFetcher: iter bucket") + if err := eg.Wait(); err != nil { + return nil, errors.Wrap(err, "BaseFetcher: iter bucket") } - incompleteView := len(metaErrs) > 0 + if len(resp.metaErrs) > 0 { + return resp, nil + } // Only for complete view of blocks update the cache. - if !incompleteView { - cached := make(map[ulid.ULID]*metadata.Meta, len(metas)) - for id, m := range metas { - cached[id] = m - } - s.cached = cached - - // Best effort cleanup of disk-cached metas. - if s.cacheDir != "" { - names, err := fileutil.ReadDir(s.cacheDir) - if err != nil { - level.Warn(s.logger).Log("msg", "best effort remove of not needed cached dirs failed; ignoring", "err", err) - } else { - for _, n := range names { - id, ok := IsBlockDir(n) - if !ok { - continue - } - - if _, ok := metas[id]; ok { - continue - } - - cachedBlockDir := filepath.Join(s.cacheDir, id.String()) - - // No such block loaded, remove the local dir. - if err := os.RemoveAll(cachedBlockDir); err != nil { - level.Warn(s.logger).Log("msg", "best effort remove of not needed cached dir failed; ignoring", "dir", cachedBlockDir, "err", err) - } + cached := make(map[ulid.ULID]*metadata.Meta, len(resp.metas)) + for id, m := range resp.metas { + cached[id] = m + } + f.cached = cached + + // Best effort cleanup of disk-cached metas. + if f.cacheDir != "" { + names, err := fileutil.ReadDir(f.cacheDir) + if err != nil { + level.Warn(f.logger).Log("msg", "best effort remove of not needed cached dirs failed; ignoring", "err", err) + } else { + for _, n := range names { + id, ok := IsBlockDir(n) + if !ok { + continue + } + + if _, ok := resp.metas[id]; ok { + continue + } + + cachedBlockDir := filepath.Join(f.cacheDir, id.String()) + + // No such block loaded, remove the local dir. + if err := os.RemoveAll(cachedBlockDir); err != nil { + level.Warn(f.logger).Log("msg", "best effort remove of not needed cached dir failed; ignoring", "dir", cachedBlockDir, "err", err) } } } } + return resp, nil +} - for _, f := range s.filters { +func (f *BaseFetcher) fetch(ctx context.Context, metrics *fetcherMetrics, filters []MetadataFilter, modifiers []MetadataModifier) (_ map[ulid.ULID]*metadata.Meta, _ map[ulid.ULID]error, err error) { + start := time.Now() + defer func() { + metrics.syncDuration.Observe(time.Since(start).Seconds()) + if err != nil { + metrics.syncFailures.Inc() + } + }() + metrics.syncs.Inc() + metrics.resetTx() + + // Run this in thread safe run group. + // TODO(bwplotka): Consider custom singleflight with ttl. + v, err := f.g.Do("", func() (i interface{}, err error) { + // NOTE: First go routine context will go through. + return f.fetchMetadata(ctx) + }) + if err != nil { + return nil, nil, err + } + resp := v.(response) + + // Copy as same response might be reused by different goroutines. + metas := make(map[ulid.ULID]*metadata.Meta, len(resp.metas)) + for id, m := range resp.metas { + metas[id] = m + } + + metrics.synced.WithLabelValues(failedMeta).Set(float64(len(resp.metaErrs))) + metrics.synced.WithLabelValues(noMeta).Set(resp.noMetas) + metrics.synced.WithLabelValues(corruptedMeta).Set(resp.corruptedMetas) + + for _, filter := range filters { // NOTE: filter can update synced metric accordingly to the reason of the exclude. - f(metas, s.metrics.synced, incompleteView) + if err := filter.Filter(ctx, metas, metrics.synced); err != nil { + return nil, nil, errors.Wrap(err, "filter metas") + } + } + + for _, m := range modifiers { + // NOTE: modifier can update modified metric accordingly to the reason of the modification. + if err := m.Modify(ctx, metas, metrics.modified); err != nil { + return nil, nil, errors.Wrap(err, "modify metas") + } + } + + metrics.synced.WithLabelValues(loadedMeta).Set(float64(len(metas))) + metrics.submit() + + if len(resp.metaErrs) > 0 { + return metas, resp.partial, errors.Wrap(resp.metaErrs, "incomplete view") } - s.metrics.synced.WithLabelValues(loadedMeta).Set(float64(len(metas))) - s.metrics.synced.Submit() + level.Info(f.logger).Log("msg", "successfully synchronized block metadata", "duration", time.Since(start).String(), "cached", len(f.cached), "returned", len(metas), "partial", len(resp.partial)) + return metas, resp.partial, nil +} + +type MetaFetcher struct { + wrapped *BaseFetcher + metrics *fetcherMetrics + + filters []MetadataFilter + modifiers []MetadataModifier - if incompleteView { - return metas, partial, errors.Wrap(metaErrs, "incomplete view") + listener func([]metadata.Meta, error) + + logger log.Logger +} + +// Fetch returns all block metas as well as partial blocks (blocks without or with corrupted meta file) from the bucket. +// It's caller responsibility to not change the returned metadata files. Maps can be modified. +// +// Returned error indicates a failure in fetching metadata. Returned meta can be assumed as correct, with some blocks missing. +func (f *MetaFetcher) Fetch(ctx context.Context) (metas map[ulid.ULID]*metadata.Meta, partial map[ulid.ULID]error, err error) { + metas, partial, err = f.wrapped.fetch(ctx, f.metrics, f.filters, f.modifiers) + if f.listener != nil { + blocks := make([]metadata.Meta, 0, len(metas)) + for _, meta := range metas { + blocks = append(blocks, *meta) + } + f.listener(blocks, err) } + return metas, partial, err +} - level.Debug(s.logger).Log("msg", "successfully fetched block metadata", "duration", time.Since(start).String(), "cached", len(s.cached), "returned", len(metas), "partial", len(partial)) - return metas, partial, nil +// UpdateOnChange allows to add listener that will be update on every change. +func (f *MetaFetcher) UpdateOnChange(listener func([]metadata.Meta, error)) { + f.listener = listener } -var _ MetaFetcherFilter = (&TimePartitionMetaFilter{}).Filter +var _ MetadataFilter = &TimePartitionMetaFilter{} -// TimePartitionMetaFilter is a MetaFetcher filter that filters out blocks that are outside of specified time range. +// TimePartitionMetaFilter is a BaseFetcher filter that filters out blocks that are outside of specified time range. +// Not go-routine safe. type TimePartitionMetaFilter struct { minTime, maxTime model.TimeOrDurationValue } @@ -379,7 +497,7 @@ func NewTimePartitionMetaFilter(MinTime, MaxTime model.TimeOrDurationValue) *Tim } // Filter filters out blocks that are outside of specified time range. -func (f *TimePartitionMetaFilter) Filter(metas map[ulid.ULID]*metadata.Meta, synced GaugeLabeled, _ bool) { +func (f *TimePartitionMetaFilter) Filter(_ context.Context, metas map[ulid.ULID]*metadata.Meta, synced *extprom.TxGaugeVec) error { for id, m := range metas { if m.MaxTime >= f.minTime.PrometheusTimestamp() && m.MinTime <= f.maxTime.PrometheusTimestamp() { continue @@ -387,11 +505,13 @@ func (f *TimePartitionMetaFilter) Filter(metas map[ulid.ULID]*metadata.Meta, syn synced.WithLabelValues(timeExcludedMeta).Inc() delete(metas, id) } + return nil } -var _ MetaFetcherFilter = (&LabelShardedMetaFilter{}).Filter +var _ MetadataFilter = &LabelShardedMetaFilter{} // LabelShardedMetaFilter represents struct that allows sharding. +// Not go-routine safe. type LabelShardedMetaFilter struct { relabelConfig []*relabel.Config } @@ -405,7 +525,7 @@ func NewLabelShardedMetaFilter(relabelConfig []*relabel.Config) *LabelShardedMet const blockIDLabel = "__block_id" // Filter filters out blocks that have no labels after relabelling of each block external (Thanos) labels. -func (f *LabelShardedMetaFilter) Filter(metas map[ulid.ULID]*metadata.Meta, synced GaugeLabeled, _ bool) { +func (f *LabelShardedMetaFilter) Filter(_ context.Context, metas map[ulid.ULID]*metadata.Meta, synced *extprom.TxGaugeVec) error { var lbls labels.Labels for id, m := range metas { lbls = lbls[:0] @@ -419,11 +539,16 @@ func (f *LabelShardedMetaFilter) Filter(metas map[ulid.ULID]*metadata.Meta, sync delete(metas, id) } } + return nil } -// DeduplicateFilter is a MetaFetcher filter that filters out older blocks that have exactly the same data. +var _ MetadataFilter = &DeduplicateFilter{} + +// DeduplicateFilter is a BaseFetcher filter that filters out older blocks that have exactly the same data. +// Not go-routine safe. type DeduplicateFilter struct { duplicateIDs []ulid.ULID + mu sync.Mutex } // NewDeduplicateFilter creates DeduplicateFilter. @@ -433,7 +558,9 @@ func NewDeduplicateFilter() *DeduplicateFilter { // Filter filters out duplicate blocks that can be formed // from two or more overlapping blocks that fully submatches the source blocks of the older blocks. -func (f *DeduplicateFilter) Filter(metas map[ulid.ULID]*metadata.Meta, synced GaugeLabeled, _ bool) { +func (f *DeduplicateFilter) Filter(_ context.Context, metas map[ulid.ULID]*metadata.Meta, synced *extprom.TxGaugeVec) error { + f.duplicateIDs = f.duplicateIDs[:0] + var wg sync.WaitGroup metasByResolution := make(map[int64][]*metadata.Meta) @@ -450,14 +577,16 @@ func (f *DeduplicateFilter) Filter(metas map[ulid.ULID]*metadata.Meta, synced Ga BlockMeta: tsdb.BlockMeta{ ULID: ulid.MustNew(uint64(0), nil), }, - }), metasByResolution[res], metas, res, synced) + }), metasByResolution[res], metas, synced) }(res) } wg.Wait() + + return nil } -func (f *DeduplicateFilter) filterForResolution(root *Node, metaSlice []*metadata.Meta, metas map[ulid.ULID]*metadata.Meta, res int64, synced GaugeLabeled) { +func (f *DeduplicateFilter) filterForResolution(root *Node, metaSlice []*metadata.Meta, metas map[ulid.ULID]*metadata.Meta, synced *extprom.TxGaugeVec) { sort.Slice(metaSlice, func(i, j int) bool { ilen := len(metaSlice[i].Compaction.Sources) jlen := len(metaSlice[j].Compaction.Sources) @@ -475,16 +604,17 @@ func (f *DeduplicateFilter) filterForResolution(root *Node, metaSlice []*metadat duplicateULIDs := getNonRootIDs(root) for _, id := range duplicateULIDs { + f.mu.Lock() if metas[id] != nil { f.duplicateIDs = append(f.duplicateIDs, id) } synced.WithLabelValues(duplicateMeta).Inc() delete(metas, id) + f.mu.Unlock() } } -// DuplicateIDs returns slice of block ids -// that are filtered out by DeduplicateFilter. +// DuplicateIDs returns slice of block ids that are filtered out by DeduplicateFilter. func (f *DeduplicateFilter) DuplicateIDs() []ulid.ULID { return f.duplicateIDs } @@ -533,7 +663,38 @@ func contains(s1 []ulid.ULID, s2 []ulid.ULID) bool { return true } -// ConsistencyDelayMetaFilter is a MetaFetcher filter that filters out blocks that are created before a specified consistency delay. +var _ MetadataModifier = &ReplicaLabelRemover{} + +// ReplicaLabelRemover is a BaseFetcher modifier modifies external labels of existing blocks, it removes given replica labels from the metadata of blocks that have it. +type ReplicaLabelRemover struct { + logger log.Logger + + replicaLabels []string +} + +// NewReplicaLabelRemover creates a ReplicaLabelRemover. +func NewReplicaLabelRemover(logger log.Logger, replicaLabels []string) *ReplicaLabelRemover { + return &ReplicaLabelRemover{logger: logger, replicaLabels: replicaLabels} +} + +// Modify modifies external labels of existing blocks, it removes given replica labels from the metadata of blocks that have it. +func (r *ReplicaLabelRemover) Modify(_ context.Context, metas map[ulid.ULID]*metadata.Meta, modified *extprom.TxGaugeVec) error { + for u, meta := range metas { + l := meta.Thanos.Labels + for _, replicaLabel := range r.replicaLabels { + if _, exists := l[replicaLabel]; exists { + level.Debug(r.logger).Log("msg", "replica label removed", "label", replicaLabel) + delete(l, replicaLabel) + modified.WithLabelValues(replicaRemovedMeta).Inc() + } + } + metas[u].Thanos.Labels = l + } + return nil +} + +// ConsistencyDelayMetaFilter is a BaseFetcher filter that filters out blocks that are created before a specified consistency delay. +// Not go-routine safe. type ConsistencyDelayMetaFilter struct { logger log.Logger consistencyDelay time.Duration @@ -544,13 +705,12 @@ func NewConsistencyDelayMetaFilter(logger log.Logger, consistencyDelay time.Dura if logger == nil { logger = log.NewNopLogger() } - consistencyDelayMetric := prometheus.NewGaugeFunc(prometheus.GaugeOpts{ + _ = promauto.With(reg).NewGaugeFunc(prometheus.GaugeOpts{ Name: "consistency_delay_seconds", Help: "Configured consistency delay in seconds.", }, func() float64 { return consistencyDelay.Seconds() }) - reg.MustRegister(consistencyDelayMetric) return &ConsistencyDelayMetaFilter{ logger: logger, @@ -559,7 +719,7 @@ func NewConsistencyDelayMetaFilter(logger log.Logger, consistencyDelay time.Dura } // Filter filters out blocks that filters blocks that have are created before a specified consistency delay. -func (f *ConsistencyDelayMetaFilter) Filter(metas map[ulid.ULID]*metadata.Meta, synced GaugeLabeled, _ bool) { +func (f *ConsistencyDelayMetaFilter) Filter(_ context.Context, metas map[ulid.ULID]*metadata.Meta, synced *extprom.TxGaugeVec) error { for id, meta := range metas { // TODO(khyatisoneji): Remove the checks about Thanos Source // by implementing delete delay to fetch metas. @@ -574,4 +734,57 @@ func (f *ConsistencyDelayMetaFilter) Filter(metas map[ulid.ULID]*metadata.Meta, delete(metas, id) } } + + return nil +} + +// IgnoreDeletionMarkFilter is a filter that filters out the blocks that are marked for deletion after a given delay. +// The delay duration is to make sure that the replacement block can be fetched before we filter out the old block. +// Delay is not considered when computing DeletionMarkBlocks map. +// Not go-routine safe. +type IgnoreDeletionMarkFilter struct { + logger log.Logger + delay time.Duration + bkt objstore.InstrumentedBucketReader + deletionMarkMap map[ulid.ULID]*metadata.DeletionMark +} + +// NewIgnoreDeletionMarkFilter creates IgnoreDeletionMarkFilter. +func NewIgnoreDeletionMarkFilter(logger log.Logger, bkt objstore.InstrumentedBucketReader, delay time.Duration) *IgnoreDeletionMarkFilter { + return &IgnoreDeletionMarkFilter{ + logger: logger, + bkt: bkt, + delay: delay, + } +} + +// DeletionMarkBlocks returns block ids that were marked for deletion. +func (f *IgnoreDeletionMarkFilter) DeletionMarkBlocks() map[ulid.ULID]*metadata.DeletionMark { + return f.deletionMarkMap +} + +// Filter filters out blocks that are marked for deletion after a given delay. +// It also returns the blocks that can be deleted since they were uploaded delay duration before current time. +func (f *IgnoreDeletionMarkFilter) Filter(ctx context.Context, metas map[ulid.ULID]*metadata.Meta, synced *extprom.TxGaugeVec) error { + f.deletionMarkMap = make(map[ulid.ULID]*metadata.DeletionMark) + + for id := range metas { + deletionMark, err := metadata.ReadDeletionMark(ctx, f.bkt, f.logger, id.String()) + if err == metadata.ErrorDeletionMarkNotFound { + continue + } + if errors.Cause(err) == metadata.ErrorUnmarshalDeletionMark { + level.Warn(f.logger).Log("msg", "found partial deletion-mark.json; if we will see it happening often for the same block, consider manually deleting deletion-mark.json from the object storage", "block", id, "err", err) + continue + } + if err != nil { + return err + } + f.deletionMarkMap[id] = deletionMark + if time.Since(time.Unix(deletionMark.DeletionTime, 0)).Seconds() > f.delay.Seconds() { + synced.WithLabelValues(markedForDeletionMeta).Inc() + delete(metas, id) + } + } + return nil } diff --git a/pkg/block/fetcher_test.go b/pkg/block/fetcher_test.go index eb93a5246b..9224f5f0b1 100644 --- a/pkg/block/fetcher_test.go +++ b/pkg/block/fetcher_test.go @@ -34,6 +34,25 @@ import ( "gopkg.in/yaml.v2" ) +func newTestFetcherMetrics() *fetcherMetrics { + return &fetcherMetrics{ + synced: extprom.NewTxGaugeVec(nil, prometheus.GaugeOpts{}, []string{"state"}), + modified: extprom.NewTxGaugeVec(nil, prometheus.GaugeOpts{}, []string{"modified"}), + } +} + +type ulidFilter struct { + ulidToDelete *ulid.ULID +} + +func (f *ulidFilter) Filter(_ context.Context, metas map[ulid.ULID]*metadata.Meta, synced *extprom.TxGaugeVec) error { + if _, ok := metas[*f.ulidToDelete]; ok { + synced.WithLabelValues("filtered").Inc() + delete(metas, *f.ulidToDelete) + } + return nil +} + func ULID(i int) ulid.ULID { return ulid.MustNew(uint64(i), nil) } func ULIDs(is ...int) []ulid.ULID { @@ -56,14 +75,13 @@ func TestMetaFetcher_Fetch(t *testing.T) { var ulidToDelete ulid.ULID r := prometheus.NewRegistry() - f, err := NewMetaFetcher(log.NewNopLogger(), 20, bkt, dir, r, func(metas map[ulid.ULID]*metadata.Meta, synced GaugeLabeled, incompleteView bool) { - if _, ok := metas[ulidToDelete]; ok { - synced.WithLabelValues("filtered").Inc() - delete(metas, ulidToDelete) - } - }) + baseFetcher, err := NewBaseFetcher(log.NewNopLogger(), 20, objstore.WithNoopInstr(bkt), dir, r) testutil.Ok(t, err) + fetcher := baseFetcher.NewMetaFetcher(r, []MetadataFilter{ + &ulidFilter{ulidToDelete: &ulidToDelete}, + }, nil) + for i, tcase := range []struct { name string do func() @@ -117,7 +135,7 @@ func TestMetaFetcher_Fetch(t *testing.T) { { name: "fresh cache", do: func() { - f.cached = map[ulid.ULID]*metadata.Meta{} + baseFetcher.cached = map[ulid.ULID]*metadata.Meta{} }, expectedMetas: ULIDs(1, 2, 3), @@ -127,7 +145,7 @@ func TestMetaFetcher_Fetch(t *testing.T) { { name: "fresh cache: meta 2 and 3 have corrupted data on disk ", do: func() { - f.cached = map[ulid.ULID]*metadata.Meta{} + baseFetcher.cached = map[ulid.ULID]*metadata.Meta{} testutil.Ok(t, os.Remove(filepath.Join(dir, "meta-syncer", ULID(2).String(), MetaFilename))) @@ -222,7 +240,7 @@ func TestMetaFetcher_Fetch(t *testing.T) { tcase.do() ulidToDelete = tcase.filterULID - metas, partial, err := f.Fetch(ctx) + metas, partial, err := fetcher.Fetch(ctx) if tcase.expectedMetaErr != nil { testutil.NotOk(t, err) testutil.Equals(t, tcase.expectedMetaErr.Error(), err.Error()) @@ -263,14 +281,15 @@ func TestMetaFetcher_Fetch(t *testing.T) { if tcase.expectedMetaErr != nil { expectedFailures = 1 } - testutil.Equals(t, float64(i+1), promtest.ToFloat64(f.metrics.syncs)) - testutil.Equals(t, float64(len(tcase.expectedMetas)), promtest.ToFloat64(f.metrics.synced.WithLabelValues(loadedMeta))) - testutil.Equals(t, float64(len(tcase.expectedNoMeta)), promtest.ToFloat64(f.metrics.synced.WithLabelValues(noMeta))) - testutil.Equals(t, float64(tcase.expectedFiltered), promtest.ToFloat64(f.metrics.synced.WithLabelValues("filtered"))) - testutil.Equals(t, 0.0, promtest.ToFloat64(f.metrics.synced.WithLabelValues(labelExcludedMeta))) - testutil.Equals(t, 0.0, promtest.ToFloat64(f.metrics.synced.WithLabelValues(timeExcludedMeta))) - testutil.Equals(t, float64(expectedFailures), promtest.ToFloat64(f.metrics.synced.WithLabelValues(failedMeta))) - testutil.Equals(t, 0.0, promtest.ToFloat64(f.metrics.synced.WithLabelValues(tooFreshMeta))) + testutil.Equals(t, float64(i+1), promtest.ToFloat64(baseFetcher.syncs)) + testutil.Equals(t, float64(i+1), promtest.ToFloat64(fetcher.metrics.syncs)) + testutil.Equals(t, float64(len(tcase.expectedMetas)), promtest.ToFloat64(fetcher.metrics.synced.WithLabelValues(loadedMeta))) + testutil.Equals(t, float64(len(tcase.expectedNoMeta)), promtest.ToFloat64(fetcher.metrics.synced.WithLabelValues(noMeta))) + testutil.Equals(t, float64(tcase.expectedFiltered), promtest.ToFloat64(fetcher.metrics.synced.WithLabelValues("filtered"))) + testutil.Equals(t, 0.0, promtest.ToFloat64(fetcher.metrics.synced.WithLabelValues(labelExcludedMeta))) + testutil.Equals(t, 0.0, promtest.ToFloat64(fetcher.metrics.synced.WithLabelValues(timeExcludedMeta))) + testutil.Equals(t, float64(expectedFailures), promtest.ToFloat64(fetcher.metrics.synced.WithLabelValues(failedMeta))) + testutil.Equals(t, 0.0, promtest.ToFloat64(fetcher.metrics.synced.WithLabelValues(tooFreshMeta))) }); !ok { return } @@ -279,6 +298,9 @@ func TestMetaFetcher_Fetch(t *testing.T) { } func TestLabelShardedMetaFilter_Filter_Basic(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + relabelContentYaml := ` - action: drop regex: "A" @@ -332,15 +354,18 @@ func TestLabelShardedMetaFilter_Filter_Basic(t *testing.T) { ULID(6): input[ULID(6)], } - synced := prometheus.NewGaugeVec(prometheus.GaugeOpts{}, []string{"state"}) - f.Filter(input, synced, false) + m := newTestFetcherMetrics() + testutil.Ok(t, f.Filter(ctx, input, m.synced)) - testutil.Equals(t, 3.0, promtest.ToFloat64(synced.WithLabelValues(labelExcludedMeta))) + testutil.Equals(t, 3.0, promtest.ToFloat64(m.synced.WithLabelValues(labelExcludedMeta))) testutil.Equals(t, expected, input) } func TestLabelShardedMetaFilter_Filter_Hashmod(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + relabelContentYamlFmt := ` - action: hashmod source_labels: ["%s"] @@ -427,11 +452,11 @@ func TestLabelShardedMetaFilter_Filter_Hashmod(t *testing.T) { } deleted := len(input) - len(expected) - synced := prometheus.NewGaugeVec(prometheus.GaugeOpts{}, []string{"state"}) - f.Filter(input, synced, false) + m := newTestFetcherMetrics() + testutil.Ok(t, f.Filter(ctx, input, m.synced)) testutil.Equals(t, expected, input) - testutil.Equals(t, float64(deleted), promtest.ToFloat64(synced.WithLabelValues(labelExcludedMeta))) + testutil.Equals(t, float64(deleted), promtest.ToFloat64(m.synced.WithLabelValues(labelExcludedMeta))) }) @@ -439,6 +464,9 @@ func TestLabelShardedMetaFilter_Filter_Hashmod(t *testing.T) { } func TestTimePartitionMetaFilter_Filter(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + mint := time.Unix(0, 1*time.Millisecond.Nanoseconds()) maxt := time.Unix(0, 10*time.Millisecond.Nanoseconds()) f := NewTimePartitionMetaFilter(model.TimeOrDurationValue{Time: &mint}, model.TimeOrDurationValue{Time: &maxt}) @@ -488,10 +516,10 @@ func TestTimePartitionMetaFilter_Filter(t *testing.T) { ULID(4): input[ULID(4)], } - synced := prometheus.NewGaugeVec(prometheus.GaugeOpts{}, []string{"state"}) - f.Filter(input, synced, false) + m := newTestFetcherMetrics() + testutil.Ok(t, f.Filter(ctx, input, m.synced)) - testutil.Equals(t, 2.0, promtest.ToFloat64(synced.WithLabelValues(timeExcludedMeta))) + testutil.Equals(t, 2.0, promtest.ToFloat64(m.synced.WithLabelValues(timeExcludedMeta))) testutil.Equals(t, expected, input) } @@ -502,6 +530,9 @@ type sourcesAndResolution struct { } func TestDeduplicateFilter_Filter(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + for _, tcase := range []struct { name string input map[ulid.ULID]*sourcesAndResolution @@ -510,15 +541,15 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "3 non compacted blocks in bucket", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(1): &sourcesAndResolution{ + ULID(1): { sources: []ulid.ULID{ULID(1)}, resolution: 0, }, - ULID(2): &sourcesAndResolution{ + ULID(2): { sources: []ulid.ULID{ULID(2)}, resolution: 0, }, - ULID(3): &sourcesAndResolution{ + ULID(3): { sources: []ulid.ULID{ULID(3)}, resolution: 0, }, @@ -532,15 +563,15 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "compacted block with sources in bucket", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(6): &sourcesAndResolution{ + ULID(6): { sources: []ulid.ULID{ULID(6)}, resolution: 0, }, - ULID(4): &sourcesAndResolution{ + ULID(4): { sources: []ulid.ULID{ULID(1), ULID(3), ULID(2)}, resolution: 0, }, - ULID(5): &sourcesAndResolution{ + ULID(5): { sources: []ulid.ULID{ULID(5)}, resolution: 0, }, @@ -554,19 +585,19 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "two compacted blocks with same sources", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(5): &sourcesAndResolution{ + ULID(5): { sources: []ulid.ULID{ULID(5)}, resolution: 0, }, - ULID(6): &sourcesAndResolution{ + ULID(6): { sources: []ulid.ULID{ULID(6)}, resolution: 0, }, - ULID(3): &sourcesAndResolution{ + ULID(3): { sources: []ulid.ULID{ULID(1), ULID(2)}, resolution: 0, }, - ULID(4): &sourcesAndResolution{ + ULID(4): { sources: []ulid.ULID{ULID(1), ULID(2)}, resolution: 0, }, @@ -580,15 +611,15 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "two compacted blocks with overlapping sources", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(4): &sourcesAndResolution{ + ULID(4): { sources: []ulid.ULID{ULID(1), ULID(2)}, resolution: 0, }, - ULID(6): &sourcesAndResolution{ + ULID(6): { sources: []ulid.ULID{ULID(6)}, resolution: 0, }, - ULID(5): &sourcesAndResolution{ + ULID(5): { sources: []ulid.ULID{ULID(1), ULID(3), ULID(2)}, resolution: 0, }, @@ -601,23 +632,23 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "3 non compacted blocks and compacted block of level 2 in bucket", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(6): &sourcesAndResolution{ + ULID(6): { sources: []ulid.ULID{ULID(6)}, resolution: 0, }, - ULID(1): &sourcesAndResolution{ + ULID(1): { sources: []ulid.ULID{ULID(1)}, resolution: 0, }, - ULID(2): &sourcesAndResolution{ + ULID(2): { sources: []ulid.ULID{ULID(2)}, resolution: 0, }, - ULID(3): &sourcesAndResolution{ + ULID(3): { sources: []ulid.ULID{ULID(3)}, resolution: 0, }, - ULID(4): &sourcesAndResolution{ + ULID(4): { sources: []ulid.ULID{ULID(2), ULID(1), ULID(3)}, resolution: 0, }, @@ -630,27 +661,27 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "3 compacted blocks of level 2 and one compacted block of level 3 in bucket", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(10): &sourcesAndResolution{ + ULID(10): { sources: []ulid.ULID{ULID(1), ULID(2), ULID(3)}, resolution: 0, }, - ULID(11): &sourcesAndResolution{ + ULID(11): { sources: []ulid.ULID{ULID(6), ULID(4), ULID(5)}, resolution: 0, }, - ULID(14): &sourcesAndResolution{ + ULID(14): { sources: []ulid.ULID{ULID(14)}, resolution: 0, }, - ULID(1): &sourcesAndResolution{ + ULID(1): { sources: []ulid.ULID{ULID(1)}, resolution: 0, }, - ULID(13): &sourcesAndResolution{ + ULID(13): { sources: []ulid.ULID{ULID(1), ULID(6), ULID(2), ULID(3), ULID(5), ULID(7), ULID(4), ULID(8), ULID(9)}, resolution: 0, }, - ULID(12): &sourcesAndResolution{ + ULID(12): { sources: []ulid.ULID{ULID(7), ULID(9), ULID(8)}, resolution: 0, }, @@ -663,23 +694,23 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "compacted blocks with overlapping sources", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(8): &sourcesAndResolution{ + ULID(8): { sources: []ulid.ULID{ULID(1), ULID(3), ULID(2), ULID(4)}, resolution: 0, }, - ULID(1): &sourcesAndResolution{ + ULID(1): { sources: []ulid.ULID{ULID(1)}, resolution: 0, }, - ULID(5): &sourcesAndResolution{ + ULID(5): { sources: []ulid.ULID{ULID(1), ULID(2)}, resolution: 0, }, - ULID(6): &sourcesAndResolution{ + ULID(6): { sources: []ulid.ULID{ULID(1), ULID(3), ULID(2), ULID(4)}, resolution: 0, }, - ULID(7): &sourcesAndResolution{ + ULID(7): { sources: []ulid.ULID{ULID(3), ULID(1), ULID(2)}, resolution: 0, }, @@ -691,15 +722,15 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "compacted blocks of level 3 with overlapping sources of equal length", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(10): &sourcesAndResolution{ + ULID(10): { sources: []ulid.ULID{ULID(1), ULID(2), ULID(6), ULID(7)}, resolution: 0, }, - ULID(1): &sourcesAndResolution{ + ULID(1): { sources: []ulid.ULID{ULID(1)}, resolution: 0, }, - ULID(11): &sourcesAndResolution{ + ULID(11): { sources: []ulid.ULID{ULID(6), ULID(8), ULID(1), ULID(2)}, resolution: 0, }, @@ -712,19 +743,19 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "compacted blocks of level 3 with overlapping sources of different length", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(10): &sourcesAndResolution{ + ULID(10): { sources: []ulid.ULID{ULID(6), ULID(7), ULID(1), ULID(2)}, resolution: 0, }, - ULID(1): &sourcesAndResolution{ + ULID(1): { sources: []ulid.ULID{ULID(1)}, resolution: 0, }, - ULID(5): &sourcesAndResolution{ + ULID(5): { sources: []ulid.ULID{ULID(1), ULID(2)}, resolution: 0, }, - ULID(11): &sourcesAndResolution{ + ULID(11): { sources: []ulid.ULID{ULID(2), ULID(3), ULID(1)}, resolution: 0, }, @@ -737,15 +768,15 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "blocks with same sources and different resolutions", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(1): &sourcesAndResolution{ + ULID(1): { sources: []ulid.ULID{ULID(1)}, resolution: 0, }, - ULID(2): &sourcesAndResolution{ + ULID(2): { sources: []ulid.ULID{ULID(1)}, resolution: 1000, }, - ULID(3): &sourcesAndResolution{ + ULID(3): { sources: []ulid.ULID{ULID(1)}, resolution: 10000, }, @@ -759,19 +790,19 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "compacted blocks with overlapping sources and different resolutions", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(1): &sourcesAndResolution{ + ULID(1): { sources: []ulid.ULID{ULID(1)}, resolution: 0, }, - ULID(6): &sourcesAndResolution{ + ULID(6): { sources: []ulid.ULID{ULID(6)}, resolution: 10000, }, - ULID(4): &sourcesAndResolution{ + ULID(4): { sources: []ulid.ULID{ULID(1), ULID(3), ULID(2)}, resolution: 0, }, - ULID(5): &sourcesAndResolution{ + ULID(5): { sources: []ulid.ULID{ULID(2), ULID(3), ULID(1)}, resolution: 1000, }, @@ -785,27 +816,27 @@ func TestDeduplicateFilter_Filter(t *testing.T) { { name: "compacted blocks of level 3 with overlapping sources of different length and different resolutions", input: map[ulid.ULID]*sourcesAndResolution{ - ULID(10): &sourcesAndResolution{ + ULID(10): { sources: []ulid.ULID{ULID(7), ULID(5), ULID(1), ULID(2)}, resolution: 0, }, - ULID(12): &sourcesAndResolution{ + ULID(12): { sources: []ulid.ULID{ULID(6), ULID(7), ULID(1)}, resolution: 10000, }, - ULID(1): &sourcesAndResolution{ + ULID(1): { sources: []ulid.ULID{ULID(1)}, resolution: 0, }, - ULID(13): &sourcesAndResolution{ + ULID(13): { sources: []ulid.ULID{ULID(1)}, resolution: 10000, }, - ULID(5): &sourcesAndResolution{ + ULID(5): { sources: []ulid.ULID{ULID(1), ULID(2)}, resolution: 0, }, - ULID(11): &sourcesAndResolution{ + ULID(11): { sources: []ulid.ULID{ULID(2), ULID(3), ULID(1)}, resolution: 0, }, @@ -819,7 +850,7 @@ func TestDeduplicateFilter_Filter(t *testing.T) { } { f := NewDeduplicateFilter() if ok := t.Run(tcase.name, func(t *testing.T) { - synced := prometheus.NewGaugeVec(prometheus.GaugeOpts{}, []string{"state"}) + m := newTestFetcherMetrics() metas := make(map[ulid.ULID]*metadata.Meta) inputLen := len(tcase.input) for id, metaInfo := range tcase.input { @@ -837,16 +868,65 @@ func TestDeduplicateFilter_Filter(t *testing.T) { }, } } - f.Filter(metas, synced, false) - + testutil.Ok(t, f.Filter(ctx, metas, m.synced)) compareSliceWithMapKeys(t, metas, tcase.expected) - testutil.Equals(t, float64(inputLen-len(tcase.expected)), promtest.ToFloat64(synced.WithLabelValues(duplicateMeta))) + testutil.Equals(t, float64(inputLen-len(tcase.expected)), promtest.ToFloat64(m.synced.WithLabelValues(duplicateMeta))) }); !ok { return } } } +func TestReplicaLabelRemover_Modify(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + rm := NewReplicaLabelRemover(log.NewNopLogger(), []string{"replica", "rule_replica"}) + + for _, tcase := range []struct { + name string + input map[ulid.ULID]*metadata.Meta + expected map[ulid.ULID]*metadata.Meta + modified float64 + }{ + { + name: "without replica labels", + input: map[ulid.ULID]*metadata.Meta{ + ULID(1): {Thanos: metadata.Thanos{Labels: map[string]string{"message": "something"}}}, + ULID(2): {Thanos: metadata.Thanos{Labels: map[string]string{"message": "something"}}}, + ULID(3): {Thanos: metadata.Thanos{Labels: map[string]string{"message": "something1"}}}, + }, + expected: map[ulid.ULID]*metadata.Meta{ + ULID(1): {Thanos: metadata.Thanos{Labels: map[string]string{"message": "something"}}}, + ULID(2): {Thanos: metadata.Thanos{Labels: map[string]string{"message": "something"}}}, + ULID(3): {Thanos: metadata.Thanos{Labels: map[string]string{"message": "something1"}}}, + }, + modified: 0, + }, + { + name: "with replica labels", + input: map[ulid.ULID]*metadata.Meta{ + ULID(1): {Thanos: metadata.Thanos{Labels: map[string]string{"message": "something"}}}, + ULID(2): {Thanos: metadata.Thanos{Labels: map[string]string{"replica": "cluster1", "message": "something"}}}, + ULID(3): {Thanos: metadata.Thanos{Labels: map[string]string{"replica": "cluster1", "rule_replica": "rule1", "message": "something"}}}, + ULID(4): {Thanos: metadata.Thanos{Labels: map[string]string{"replica": "cluster1", "rule_replica": "rule1"}}}, + }, + expected: map[ulid.ULID]*metadata.Meta{ + ULID(1): {Thanos: metadata.Thanos{Labels: map[string]string{"message": "something"}}}, + ULID(2): {Thanos: metadata.Thanos{Labels: map[string]string{"message": "something"}}}, + ULID(3): {Thanos: metadata.Thanos{Labels: map[string]string{"message": "something"}}}, + ULID(4): {Thanos: metadata.Thanos{Labels: map[string]string{}}}, + }, + modified: 5.0, + }, + } { + m := newTestFetcherMetrics() + testutil.Ok(t, rm.Modify(ctx, tcase.input, m.modified)) + + testutil.Equals(t, tcase.modified, promtest.ToFloat64(m.modified.WithLabelValues(replicaRemovedMeta))) + testutil.Equals(t, tcase.expected, tcase.input) + } +} + func compareSliceWithMapKeys(tb testing.TB, m map[ulid.ULID]*metadata.Meta, s []ulid.ULID) { _, file, line, _ := runtime.Caller(1) matching := true @@ -889,6 +969,9 @@ func (u *ulidBuilder) ULID(t time.Time) ulid.ULID { } func TestConsistencyDelayMetaFilter_Filter_0(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + u := &ulidBuilder{} now := time.Now() @@ -932,7 +1015,7 @@ func TestConsistencyDelayMetaFilter_Filter_0(t *testing.T) { } t.Run("consistency 0 (turned off)", func(t *testing.T) { - synced := prometheus.NewGaugeVec(prometheus.GaugeOpts{}, []string{"state"}) + m := newTestFetcherMetrics() expected := map[ulid.ULID]*metadata.Meta{} // Copy all. for _, id := range u.created { @@ -943,14 +1026,13 @@ func TestConsistencyDelayMetaFilter_Filter_0(t *testing.T) { f := NewConsistencyDelayMetaFilter(nil, 0*time.Second, reg) testutil.Equals(t, map[string]float64{"consistency_delay_seconds": 0.0}, extprom.CurrentGaugeValuesFor(t, reg, "consistency_delay_seconds")) - f.Filter(input, synced, false) - - testutil.Equals(t, 0.0, promtest.ToFloat64(synced.WithLabelValues(tooFreshMeta))) + testutil.Ok(t, f.Filter(ctx, input, m.synced)) + testutil.Equals(t, 0.0, promtest.ToFloat64(m.synced.WithLabelValues(tooFreshMeta))) testutil.Equals(t, expected, input) }) t.Run("consistency 30m.", func(t *testing.T) { - synced := prometheus.NewGaugeVec(prometheus.GaugeOpts{}, []string{"state"}) + m := newTestFetcherMetrics() expected := map[ulid.ULID]*metadata.Meta{} // Only certain sources and those with 30m or more age go through. for i, id := range u.created { @@ -969,9 +1051,61 @@ func TestConsistencyDelayMetaFilter_Filter_0(t *testing.T) { f := NewConsistencyDelayMetaFilter(nil, 30*time.Minute, reg) testutil.Equals(t, map[string]float64{"consistency_delay_seconds": (30 * time.Minute).Seconds()}, extprom.CurrentGaugeValuesFor(t, reg, "consistency_delay_seconds")) - f.Filter(input, synced, false) + testutil.Ok(t, f.Filter(ctx, input, m.synced)) + testutil.Equals(t, float64(len(u.created)-len(expected)), promtest.ToFloat64(m.synced.WithLabelValues(tooFreshMeta))) + testutil.Equals(t, expected, input) + }) +} + +func TestIgnoreDeletionMarkFilter_Filter(t *testing.T) { + objtesting.ForeachStore(t, func(t *testing.T, bkt objstore.Bucket) { + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + + now := time.Now() + f := &IgnoreDeletionMarkFilter{ + logger: log.NewNopLogger(), + bkt: objstore.WithNoopInstr(bkt), + delay: 48 * time.Hour, + } + + shouldFetch := &metadata.DeletionMark{ + ID: ULID(1), + DeletionTime: now.Add(-15 * time.Hour).Unix(), + Version: 1, + } + + shouldIgnore := &metadata.DeletionMark{ + ID: ULID(2), + DeletionTime: now.Add(-60 * time.Hour).Unix(), + Version: 1, + } + + var buf bytes.Buffer + testutil.Ok(t, json.NewEncoder(&buf).Encode(&shouldFetch)) + testutil.Ok(t, bkt.Upload(ctx, path.Join(shouldFetch.ID.String(), metadata.DeletionMarkFilename), &buf)) + + testutil.Ok(t, json.NewEncoder(&buf).Encode(&shouldIgnore)) + testutil.Ok(t, bkt.Upload(ctx, path.Join(shouldIgnore.ID.String(), metadata.DeletionMarkFilename), &buf)) + + testutil.Ok(t, bkt.Upload(ctx, path.Join(ULID(3).String(), metadata.DeletionMarkFilename), bytes.NewBufferString("not a valid deletion-mark.json"))) + + input := map[ulid.ULID]*metadata.Meta{ + ULID(1): {}, + ULID(2): {}, + ULID(3): {}, + ULID(4): {}, + } + + expected := map[ulid.ULID]*metadata.Meta{ + ULID(1): {}, + ULID(3): {}, + ULID(4): {}, + } - testutil.Equals(t, float64(len(u.created)-len(expected)), promtest.ToFloat64(synced.WithLabelValues(tooFreshMeta))) + m := newTestFetcherMetrics() + testutil.Ok(t, f.Filter(ctx, input, m.synced)) + testutil.Equals(t, 1.0, promtest.ToFloat64(m.synced.WithLabelValues(markedForDeletionMeta))) testutil.Equals(t, expected, input) }) } diff --git a/pkg/block/indexheader/binary_reader.go b/pkg/block/indexheader/binary_reader.go index 9005cd443b..a070d9275b 100644 --- a/pkg/block/indexheader/binary_reader.go +++ b/pkg/block/indexheader/binary_reader.go @@ -42,8 +42,6 @@ const ( // MagicIndex are 4 bytes at the head of an index-header file. MagicIndex = 0xBAAAD792 - symbolFactor = 32 - postingLengthFieldSize = 4 ) @@ -71,20 +69,21 @@ type BinaryTOC struct { } // WriteBinary build index-header file from the pieces of index in object storage. -func WriteBinary(ctx context.Context, bkt objstore.BucketReader, id ulid.ULID, fn string) (err error) { +func WriteBinary(ctx context.Context, bkt objstore.BucketReader, id ulid.ULID, filename string) (err error) { ir, indexVersion, err := newChunkedIndexReader(ctx, bkt, id) if err != nil { return errors.Wrap(err, "new index reader") } + tmpFilename := filename + ".tmp" // Buffer for copying and encbuffers. // This also will control the size of file writer buffer. buf := make([]byte, 32*1024) - bw, err := newBinaryWriter(fn, buf) + bw, err := newBinaryWriter(tmpFilename, buf) if err != nil { return errors.Wrap(err, "new binary index header writer") } - defer runutil.CloseWithErrCapture(&err, bw, "close binary writer for %s", fn) + defer runutil.CloseWithErrCapture(&err, bw, "close binary writer for %s", tmpFilename) if err := bw.AddIndexMeta(indexVersion, ir.toc.PostingsTable); err != nil { return errors.Wrap(err, "add index meta") @@ -109,7 +108,17 @@ func WriteBinary(ctx context.Context, bkt objstore.BucketReader, id ulid.ULID, f if err := bw.WriteTOC(); err != nil { return errors.Wrap(err, "write index header TOC") } - return nil + + if err := bw.f.Flush(); err != nil { + return errors.Wrap(err, "flush") + } + + if err := bw.f.f.Sync(); err != nil { + return errors.Wrap(err, "sync") + } + + // Create index-header in atomic way, to avoid partial writes (e.g during restart or crash of store GW). + return os.Rename(tmpFilename, filename) } type chunkedIndexReader struct { @@ -417,11 +426,12 @@ type BinaryReader struct { c io.Closer // Map of LabelName to a list of some LabelValues's position in the offset table. - // The first and last values for each name are always present. + // The first and last values for each name are always present, we keep only 1/postingOffsetsInMemSampling of the rest. postings map[string]*postingValueOffsets // For the v1 format, labelname -> labelvalue -> offset. postingsV1 map[string]map[string]index.Range + // Symbols struct that keeps only 1/postingOffsetsInMemSampling in the memory, then looks up the rest via mmap. symbols *index.Symbols nameSymbols map[uint32]string // Cache of the label name symbol lookups, // as there are not many and they are half of all lookups. @@ -431,12 +441,14 @@ type BinaryReader struct { version int indexVersion int indexLastPostingEnd int64 + + postingOffsetsInMemSampling int } // NewBinaryReader loads or builds new index-header if not present on disk. -func NewBinaryReader(ctx context.Context, logger log.Logger, bkt objstore.BucketReader, dir string, id ulid.ULID) (*BinaryReader, error) { +func NewBinaryReader(ctx context.Context, logger log.Logger, bkt objstore.BucketReader, dir string, id ulid.ULID, postingOffsetsInMemSampling int) (*BinaryReader, error) { binfn := filepath.Join(dir, id.String(), block.IndexHeaderFilename) - br, err := newFileBinaryReader(binfn) + br, err := newFileBinaryReader(binfn, postingOffsetsInMemSampling) if err == nil { return br, nil } @@ -449,11 +461,10 @@ func NewBinaryReader(ctx context.Context, logger log.Logger, bkt objstore.Bucket } level.Debug(logger).Log("msg", "built index-header file", "path", binfn, "elapsed", time.Since(start)) - - return newFileBinaryReader(binfn) + return newFileBinaryReader(binfn, postingOffsetsInMemSampling) } -func newFileBinaryReader(path string) (bw *BinaryReader, err error) { +func newFileBinaryReader(path string, postingOffsetsInMemSampling int) (bw *BinaryReader, err error) { f, err := fileutil.OpenMmapFile(path) if err != nil { return nil, err @@ -465,9 +476,10 @@ func newFileBinaryReader(path string) (bw *BinaryReader, err error) { }() r := &BinaryReader{ - b: realByteSlice(f.Bytes()), - c: f, - postings: map[string]*postingValueOffsets{}, + b: realByteSlice(f.Bytes()), + c: f, + postings: map[string]*postingValueOffsets{}, + postingOffsetsInMemSampling: postingOffsetsInMemSampling, } // Verify header. @@ -491,6 +503,7 @@ func newFileBinaryReader(path string) (bw *BinaryReader, err error) { return nil, errors.Wrap(err, "read index header TOC") } + // TODO(bwplotka): Consider contributing to Prometheus to allow specifying custom number for symbolsFactor. r.symbols, err = index.NewSymbols(r.b, r.indexVersion, int(r.toc.Symbols)) if err != nil { return nil, errors.Wrap(err, "read symbols") @@ -540,11 +553,12 @@ func newFileBinaryReader(path string) (bw *BinaryReader, err error) { } if _, ok := r.postings[key[0]]; !ok { - // Next label name. + // Not seen before label name. r.postings[key[0]] = &postingValueOffsets{} if lastKey != nil { - if valueCount%symbolFactor != 0 { - // Always include last value for each label name. + // Always include last value for each label name, unless it was just added in previous iteration based + // on valueCount. + if (valueCount-1)%postingOffsetsInMemSampling != 0 { r.postings[lastKey[0]].offsets = append(r.postings[lastKey[0]].offsets, postingOffset{value: lastKey[1], tableOff: lastTableOff}) } r.postings[lastKey[0]].lastValOffset = int64(off - crc32.Size) @@ -554,21 +568,24 @@ func newFileBinaryReader(path string) (bw *BinaryReader, err error) { } lastKey = key - if valueCount%symbolFactor == 0 { + lastTableOff = tableOff + valueCount++ + + if (valueCount-1)%postingOffsetsInMemSampling == 0 { r.postings[key[0]].offsets = append(r.postings[key[0]].offsets, postingOffset{value: key[1], tableOff: tableOff}) - return nil } - lastTableOff = tableOff - valueCount++ return nil }); err != nil { return nil, errors.Wrap(err, "read postings table") } if lastKey != nil { - if valueCount%symbolFactor != 0 { + if (valueCount-1)%postingOffsetsInMemSampling != 0 { + // Always include last value for each label name if not included already based on valueCount. r.postings[lastKey[0]].offsets = append(r.postings[lastKey[0]].offsets, postingOffset{value: lastKey[1], tableOff: lastTableOff}) } + // In any case lastValOffset is unknown as don't have next posting anymore. Guess from TOC table. + // In worst case we will overfetch a few bytes. r.postings[lastKey[0]].lastValOffset = r.indexLastPostingEnd - crc32.Size } // Trim any extra space in the slices. @@ -636,6 +653,18 @@ func (r BinaryReader) PostingsOffset(name string, value string) (index.Range, er return rngs[0], nil } +func skipNAndName(d *encoding.Decbuf, buf *int) { + if *buf == 0 { + // Keycount+LabelName are always the same number of bytes, + // and it's faster to skip than parse. + *buf = d.Len() + d.Uvarint() // Keycount. + d.UvarintBytes() // Label name. + *buf -= d.Len() + return + } + d.Skip(*buf) +} func (r BinaryReader) postingsOffset(name string, values ...string) ([]index.Range, error) { rngs := make([]index.Range, 0, len(values)) if r.indexVersion == index.FormatV1 { @@ -662,76 +691,107 @@ func (r BinaryReader) postingsOffset(name string, values ...string) ([]index.Ran return nil, nil } - skip := 0 + buf := 0 valueIndex := 0 for valueIndex < len(values) && values[valueIndex] < e.offsets[0].value { // Discard values before the start. valueIndex++ } - var tmpRngs []index.Range // The start, end offsets in the postings table in the original index file. + var newSameRngs []index.Range // The start, end offsets in the postings table in the original index file. for valueIndex < len(values) { - value := values[valueIndex] + wantedValue := values[valueIndex] - i := sort.Search(len(e.offsets), func(i int) bool { return e.offsets[i].value >= value }) + i := sort.Search(len(e.offsets), func(i int) bool { return e.offsets[i].value >= wantedValue }) if i == len(e.offsets) { // We're past the end. break } - if i > 0 && e.offsets[i].value != value { + if i > 0 && e.offsets[i].value != wantedValue { // Need to look from previous entry. i-- } + // Don't Crc32 the entire postings offset table, this is very slow // so hope any issues were caught at startup. d := encoding.NewDecbufAt(r.b, int(r.toc.PostingsOffsetTable), nil) d.Skip(e.offsets[i].tableOff) - tmpRngs = tmpRngs[:0] // Iterate on the offset table. + newSameRngs = newSameRngs[:0] for d.Err() == nil { - if skip == 0 { - // These are always the same number of bytes, - // and it's faster to skip than parse. - skip = d.Len() - d.Uvarint() // Keycount. - d.UvarintBytes() // Label name. - skip -= d.Len() - } else { - d.Skip(skip) + // Posting format entry is as follows: + // │ ┌────────────────────────────────────────┐ │ + // │ │ n = 2 <1b> │ │ + // │ ├──────────────────────┬─────────────────┤ │ + // │ │ len(name) │ name │ │ + // │ ├──────────────────────┼─────────────────┤ │ + // │ │ len(value) │ value │ │ + // │ ├──────────────────────┴─────────────────┤ │ + // │ │ offset │ │ + // │ └────────────────────────────────────────┘ │ + // First, let's skip n and name. + skipNAndName(&d, &buf) + value := d.UvarintBytes() // Label value. + postingOffset := int64(d.Uvarint64()) + + if len(newSameRngs) > 0 { + // We added some ranges in previous iteration. Use next posting offset as end of all our new ranges. + for j := range newSameRngs { + newSameRngs[j].End = postingOffset - crc32.Size + } + rngs = append(rngs, newSameRngs...) + newSameRngs = newSameRngs[:0] } - v := d.UvarintBytes() // Label value. - postingOffset := int64(d.Uvarint64()) // Offset. - for string(v) >= value { - if string(v) == value { - tmpRngs = append(tmpRngs, index.Range{Start: postingOffset + postingLengthFieldSize}) + + for string(value) >= wantedValue { + // If wantedValue is equals of greater than current value, loop over all given wanted values in the values until + // this is no longer true or there are no more values wanted. + // This ensures we cover case when someone asks for postingsOffset(name, value1, value1, value1). + + // Record on the way if wanted value is equal to the current value. + if string(value) == wantedValue { + newSameRngs = append(newSameRngs, index.Range{Start: postingOffset + postingLengthFieldSize}) } valueIndex++ if valueIndex == len(values) { break } - value = values[valueIndex] + wantedValue = values[valueIndex] } + if i+1 == len(e.offsets) { - for i := range tmpRngs { - tmpRngs[i].End = e.lastValOffset + // No more offsets for this name. + // Break this loop and record lastOffset on the way for ranges we just added if any. + for j := range newSameRngs { + newSameRngs[j].End = e.lastValOffset } - rngs = append(rngs, tmpRngs...) - // Need to go to a later postings offset entry, if there is one. + rngs = append(rngs, newSameRngs...) break } - if value >= e.offsets[i+1].value || valueIndex == len(values) { - d.Skip(skip) - d.UvarintBytes() // Label value. - postingOffset := int64(d.Uvarint64()) // Offset. - for j := range tmpRngs { - tmpRngs[j].End = postingOffset - crc32.Size + if valueIndex != len(values) && wantedValue <= e.offsets[i+1].value { + // wantedValue is smaller or same as the next offset we know about, let's iterate further to add those. + continue + } + + // Nothing wanted or wantedValue is larger than next offset we know about. + // Let's exit and do binary search again / exit if nothing wanted. + + if len(newSameRngs) > 0 { + // We added some ranges in this iteration. Use next posting offset as the end of our ranges. + // We know it exists as we never go further in this loop than e.offsets[i, i+1]. + + skipNAndName(&d, &buf) + d.UvarintBytes() // Label value. + postingOffset := int64(d.Uvarint64()) + + for j := range newSameRngs { + newSameRngs[j].End = postingOffset - crc32.Size } - rngs = append(rngs, tmpRngs...) - // Need to go to a later postings offset entry, if there is one. - break + rngs = append(rngs, newSameRngs...) } + break } if d.Err() != nil { return nil, errors.Wrap(d.Err(), "get postings offset entry") @@ -776,7 +836,7 @@ func (r BinaryReader) LabelValues(name string) ([]string, error) { if len(e.offsets) == 0 { return nil, nil } - values := make([]string, 0, len(e.offsets)*symbolFactor) + values := make([]string, 0, len(e.offsets)*r.postingOffsetsInMemSampling) d := encoding.NewDecbufAt(r.b, int(r.toc.PostingsOffsetTable), nil) d.Skip(e.offsets[0].tableOff) diff --git a/pkg/block/indexheader/header_test.go b/pkg/block/indexheader/header_test.go index c0cc76d3f8..2b1e2d802b 100644 --- a/pkg/block/indexheader/header_test.go +++ b/pkg/block/indexheader/header_test.go @@ -45,7 +45,17 @@ func TestReaders(t *testing.T) { {{Name: "a", Value: "2"}}, {{Name: "a", Value: "3"}}, {{Name: "a", Value: "4"}}, + {{Name: "a", Value: "5"}}, + {{Name: "a", Value: "6"}}, + {{Name: "a", Value: "7"}}, + {{Name: "a", Value: "8"}}, + {{Name: "a", Value: "9"}}, + // Missing 10 on purpose. + {{Name: "a", Value: "11"}}, + {{Name: "a", Value: "12"}}, + {{Name: "a", Value: "13"}}, {{Name: "a", Value: "1"}, {Name: "longer-string", Value: "1"}}, + {{Name: "a", Value: "1"}, {Name: "longer-string", Value: "2"}}, }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124) testutil.Ok(t, err) @@ -92,7 +102,7 @@ func TestReaders(t *testing.T) { fn := filepath.Join(tmpDir, id.String(), block.IndexHeaderFilename) testutil.Ok(t, WriteBinary(ctx, bkt, id, fn)) - br, err := NewBinaryReader(ctx, log.NewNopLogger(), nil, tmpDir, id) + br, err := NewBinaryReader(ctx, log.NewNopLogger(), nil, tmpDir, id, 3) testutil.Ok(t, err) defer func() { testutil.Ok(t, br.Close()) }() @@ -100,12 +110,62 @@ func TestReaders(t *testing.T) { if id == id1 { testutil.Equals(t, 1, br.version) testutil.Equals(t, 2, br.indexVersion) - testutil.Equals(t, &BinaryTOC{Symbols: headerLen, PostingsOffsetTable: 50}, br.toc) - testutil.Equals(t, int64(330), br.indexLastPostingEnd) + testutil.Equals(t, &BinaryTOC{Symbols: headerLen, PostingsOffsetTable: 69}, br.toc) + testutil.Equals(t, int64(710), br.indexLastPostingEnd) testutil.Equals(t, 8, br.symbols.Size()) - testutil.Equals(t, 3, len(br.postings)) testutil.Equals(t, 0, len(br.postingsV1)) testutil.Equals(t, 2, len(br.nameSymbols)) + testutil.Equals(t, map[string]*postingValueOffsets{ + "": { + offsets: []postingOffset{{value: "", tableOff: 4}}, + lastValOffset: 440, + }, + "a": { + offsets: []postingOffset{ + {value: "1", tableOff: 9}, + {value: "13", tableOff: 32}, + {value: "4", tableOff: 54}, + {value: "7", tableOff: 75}, + {value: "9", tableOff: 89}, + }, + lastValOffset: 640, + }, + "longer-string": { + offsets: []postingOffset{ + {value: "1", tableOff: 96}, + {value: "2", tableOff: 115}, + }, + lastValOffset: 706, + }, + }, br.postings) + + vals, err := br.LabelValues("not-existing") + testutil.Ok(t, err) + testutil.Equals(t, []string(nil), vals) + + // Regression tests for https://github.com/thanos-io/thanos/issues/2213. + // Most of not existing value was working despite bug, except in certain unlucky cases + // it was causing "invalid size" errors. + _, err = br.PostingsOffset("not-existing", "1") + testutil.Equals(t, NotFoundRangeErr, err) + _, err = br.PostingsOffset("a", "0") + testutil.Equals(t, NotFoundRangeErr, err) + // Unlucky case, because the bug was causing unnecessary read & decode requiring more bytes than + // available. For rest cases read was noop wrong, but at least not failing. + _, err = br.PostingsOffset("a", "10") + testutil.Equals(t, NotFoundRangeErr, err) + _, err = br.PostingsOffset("a", "121") + testutil.Equals(t, NotFoundRangeErr, err) + _, err = br.PostingsOffset("a", "131") + testutil.Equals(t, NotFoundRangeErr, err) + _, err = br.PostingsOffset("a", "91") + testutil.Equals(t, NotFoundRangeErr, err) + _, err = br.PostingsOffset("longer-string", "0") + testutil.Equals(t, NotFoundRangeErr, err) + _, err = br.PostingsOffset("longer-string", "11") + testutil.Equals(t, NotFoundRangeErr, err) + _, err = br.PostingsOffset("longer-string", "21") + testutil.Equals(t, NotFoundRangeErr, err) } compareIndexToHeader(t, b, br) @@ -121,9 +181,9 @@ func TestReaders(t *testing.T) { defer func() { testutil.Ok(t, jr.Close()) }() if id == id1 { - testutil.Equals(t, 6, len(jr.symbols)) + testutil.Equals(t, 14, len(jr.symbols)) testutil.Equals(t, 2, len(jr.lvals)) - testutil.Equals(t, 6, len(jr.postings)) + testutil.Equals(t, 15, len(jr.postings)) } compareIndexToHeader(t, b, jr) @@ -223,13 +283,6 @@ func compareIndexToHeader(t *testing.T, indexByteSlice index.ByteSlice, headerRe testutil.Ok(t, err) testutil.Equals(t, expRanges[labels.Label{Name: "", Value: ""}].Start, ptr.Start) testutil.Equals(t, expRanges[labels.Label{Name: "", Value: ""}].End, ptr.End) - - vals, err := indexReader.LabelValues("not-existing") - testutil.Ok(t, err) - testutil.Equals(t, []string(nil), vals) - - _, err = headerReader.PostingsOffset("not-existing", "1") - testutil.NotOk(t, err) } func prepareIndexV2Block(t testing.TB, tmpDir string, bkt objstore.Bucket) *metadata.Meta { @@ -392,7 +445,7 @@ func BenchmarkBinaryReader(t *testing.B) { t.ResetTimer() for i := 0; i < t.N; i++ { - br, err := newFileBinaryReader(fn) + br, err := newFileBinaryReader(fn, 32) testutil.Ok(t, err) testutil.Ok(t, br.Close()) } diff --git a/pkg/block/indexheader/json_reader.go b/pkg/block/indexheader/json_reader.go index 5a3654f4d6..fe54534972 100644 --- a/pkg/block/indexheader/json_reader.go +++ b/pkg/block/indexheader/json_reader.go @@ -199,7 +199,7 @@ type JSONReader struct { } // NewJSONReader loads or builds new index-cache.json if not present on disk or object storage. -func NewJSONReader(ctx context.Context, logger log.Logger, bkt objstore.BucketReader, dir string, id ulid.ULID) (*JSONReader, error) { +func NewJSONReader(ctx context.Context, logger log.Logger, bkt objstore.InstrumentedBucketReader, dir string, id ulid.ULID) (*JSONReader, error) { cachefn := filepath.Join(dir, id.String(), block.IndexCacheFilename) jr, err := newFileJSONReader(logger, cachefn) if err == nil { @@ -216,7 +216,7 @@ func NewJSONReader(ctx context.Context, logger log.Logger, bkt objstore.BucketRe } // Try to download index cache file from object store. - if err = objstore.DownloadFile(ctx, logger, bkt, filepath.Join(id.String(), block.IndexCacheFilename), cachefn); err == nil { + if err = objstore.DownloadFile(ctx, logger, bkt.ReaderWithExpectedErrs(bkt.IsObjNotFoundErr), filepath.Join(id.String(), block.IndexCacheFilename), cachefn); err == nil { return newFileJSONReader(logger, cachefn) } diff --git a/pkg/block/metadata/deletionmark.go b/pkg/block/metadata/deletionmark.go new file mode 100644 index 0000000000..5f2a9f04ad --- /dev/null +++ b/pkg/block/metadata/deletionmark.go @@ -0,0 +1,76 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package metadata + +import ( + "context" + "encoding/json" + "io/ioutil" + "path" + + "github.com/go-kit/kit/log" + "github.com/oklog/ulid" + "github.com/pkg/errors" + "github.com/thanos-io/thanos/pkg/objstore" + "github.com/thanos-io/thanos/pkg/runutil" +) + +const ( + // DeletionMarkFilename is the known json filename to store details about when block is marked for deletion. + DeletionMarkFilename = "deletion-mark.json" + + // DeletionMarkVersion1 is the version of deletion-mark file supported by Thanos. + DeletionMarkVersion1 = 1 +) + +// ErrorDeletionMarkNotFound is the error when deletion-mark.json file is not found. +var ErrorDeletionMarkNotFound = errors.New("deletion-mark.json not found") + +// ErrorUnmarshalDeletionMark is the error when unmarshalling deletion-mark.json file. +// This error can occur because deletion-mark.json has been partially uploaded to block storage +// or the deletion-mark.json file is not a valid json file. +var ErrorUnmarshalDeletionMark = errors.New("unmarshal deletion-mark.json") + +// DeletionMark stores block id and when block was marked for deletion. +type DeletionMark struct { + // ID of the tsdb block. + ID ulid.ULID `json:"id"` + + // DeletionTime is a unix timestamp of when the block was marked to be deleted. + DeletionTime int64 `json:"deletion_time"` + + // Version of the file. + Version int `json:"version"` +} + +// ReadDeletionMark reads the given deletion mark file from /deletion-mark.json in bucket. +func ReadDeletionMark(ctx context.Context, bkt objstore.InstrumentedBucketReader, logger log.Logger, dir string) (*DeletionMark, error) { + deletionMarkFile := path.Join(dir, DeletionMarkFilename) + + r, err := bkt.ReaderWithExpectedErrs(bkt.IsObjNotFoundErr).Get(ctx, deletionMarkFile) + if err != nil { + if bkt.IsObjNotFoundErr(err) { + return nil, ErrorDeletionMarkNotFound + } + return nil, errors.Wrapf(err, "get file: %s", deletionMarkFile) + } + + defer runutil.CloseWithLogOnErr(logger, r, "close bkt deletion-mark reader") + + metaContent, err := ioutil.ReadAll(r) + if err != nil { + return nil, errors.Wrapf(err, "read file: %s", deletionMarkFile) + } + + deletionMark := DeletionMark{} + if err := json.Unmarshal(metaContent, &deletionMark); err != nil { + return nil, errors.Wrapf(ErrorUnmarshalDeletionMark, "file: %s; err: %v", deletionMarkFile, err.Error()) + } + + if deletionMark.Version != DeletionMarkVersion1 { + return nil, errors.Errorf("unexpected deletion-mark file version %d", deletionMark.Version) + } + + return &deletionMark, nil +} diff --git a/pkg/block/metadata/deletionmark_test.go b/pkg/block/metadata/deletionmark_test.go new file mode 100644 index 0000000000..02f259f856 --- /dev/null +++ b/pkg/block/metadata/deletionmark_test.go @@ -0,0 +1,78 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package metadata + +import ( + "bytes" + "context" + "encoding/json" + "io/ioutil" + "os" + "path" + "testing" + "time" + + "github.com/fortytw2/leaktest" + "github.com/oklog/ulid" + "github.com/pkg/errors" + "github.com/thanos-io/thanos/pkg/objstore" + "github.com/thanos-io/thanos/pkg/testutil" +) + +func TestReadDeletionMark(t *testing.T) { + defer leaktest.CheckTimeout(t, 10*time.Second)() + + ctx := context.Background() + + tmpDir, err := ioutil.TempDir("", "test-read-deletion-mark") + testutil.Ok(t, err) + defer func() { testutil.Ok(t, os.RemoveAll(tmpDir)) }() + + bkt := objstore.WithNoopInstr(objstore.NewInMemBucket()) + { + blockWithoutDeletionMark := ulid.MustNew(uint64(1), nil) + _, err := ReadDeletionMark(ctx, bkt, nil, path.Join(tmpDir, blockWithoutDeletionMark.String())) + + testutil.NotOk(t, err) + testutil.Equals(t, ErrorDeletionMarkNotFound, err) + } + { + blockWithPartialDeletionMark := ulid.MustNew(uint64(2), nil) + + testutil.Ok(t, bkt.Upload(ctx, path.Join(tmpDir, blockWithPartialDeletionMark.String(), DeletionMarkFilename), bytes.NewBufferString("not a valid deletion-mark.json"))) + _, err = ReadDeletionMark(ctx, bkt, nil, path.Join(tmpDir, blockWithPartialDeletionMark.String())) + + testutil.NotOk(t, err) + testutil.Equals(t, ErrorUnmarshalDeletionMark, errors.Cause(err)) + } + { + blockWithDifferentVersionDeletionMark := ulid.MustNew(uint64(3), nil) + var buf bytes.Buffer + testutil.Ok(t, json.NewEncoder(&buf).Encode(&DeletionMark{ + ID: blockWithDifferentVersionDeletionMark, + DeletionTime: time.Now().Unix(), + Version: 2, + })) + + testutil.Ok(t, bkt.Upload(ctx, path.Join(tmpDir, blockWithDifferentVersionDeletionMark.String(), DeletionMarkFilename), &buf)) + _, err = ReadDeletionMark(ctx, bkt, nil, path.Join(tmpDir, blockWithDifferentVersionDeletionMark.String())) + + testutil.NotOk(t, err) + testutil.Equals(t, "unexpected deletion-mark file version 2", err.Error()) + } + { + blockWithValidDeletionMark := ulid.MustNew(uint64(3), nil) + var buf bytes.Buffer + testutil.Ok(t, json.NewEncoder(&buf).Encode(&DeletionMark{ + ID: blockWithValidDeletionMark, + DeletionTime: time.Now().Unix(), + Version: 1, + })) + + testutil.Ok(t, bkt.Upload(ctx, path.Join(tmpDir, blockWithValidDeletionMark.String(), DeletionMarkFilename), &buf)) + _, err = ReadDeletionMark(ctx, bkt, nil, path.Join(tmpDir, blockWithValidDeletionMark.String())) + + testutil.Ok(t, err) + } +} diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go new file mode 100644 index 0000000000..acaa0e159d --- /dev/null +++ b/pkg/cache/cache.go @@ -0,0 +1,21 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package cache + +import ( + "context" + "time" +) + +// Generic best-effort cache. +type Cache interface { + // Store data into the cache. + // + // Note that individual byte buffers may be retained by the cache! + Store(ctx context.Context, data map[string][]byte, ttl time.Duration) + + // Fetch multiple keys from cache. Returns map of input keys to data. + // If key isn't in the map, data for given key was not found. + Fetch(ctx context.Context, keys []string) map[string][]byte +} diff --git a/pkg/cache/memcached.go b/pkg/cache/memcached.go new file mode 100644 index 0000000000..04c249576e --- /dev/null +++ b/pkg/cache/memcached.go @@ -0,0 +1,83 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package cache + +import ( + "context" + "time" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/thanos-io/thanos/pkg/cacheutil" +) + +// MemcachedCache is a memcached-based cache. +type MemcachedCache struct { + logger log.Logger + memcached cacheutil.MemcachedClient + + // Metrics. + requests prometheus.Counter + hits prometheus.Counter +} + +// NewMemcachedCache makes a new MemcachedCache. +func NewMemcachedCache(name string, logger log.Logger, memcached cacheutil.MemcachedClient, reg prometheus.Registerer) *MemcachedCache { + c := &MemcachedCache{ + logger: logger, + memcached: memcached, + } + + c.requests = promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "thanos_cache_memcached_requests_total", + Help: "Total number of items requests to memcached.", + ConstLabels: prometheus.Labels{"name": name}, + }) + + c.hits = promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "thanos_cache_memcached_hits_total", + Help: "Total number of items requests to the cache that were a hit.", + ConstLabels: prometheus.Labels{"name": name}, + }) + + level.Info(logger).Log("msg", "created memcached cache") + + return c +} + +// Store data identified by keys. +// The function enqueues the request and returns immediately: the entry will be +// asynchronously stored in the cache. +func (c *MemcachedCache) Store(ctx context.Context, data map[string][]byte, ttl time.Duration) { + var ( + firstErr error + failed int + ) + + for key, val := range data { + if err := c.memcached.SetAsync(ctx, key, val, ttl); err != nil { + failed++ + if firstErr == nil { + firstErr = err + } + } + } + + if firstErr != nil { + level.Warn(c.logger).Log("msg", "failed to store one or more items into memcached", "failed", failed, "firstErr", firstErr) + } +} + +// Fetch fetches multiple keys and returns a map containing cache hits, along with a list of missing keys. +// In case of error, it logs and return an empty cache hits map. +func (c *MemcachedCache) Fetch(ctx context.Context, keys []string) map[string][]byte { + // Fetch the keys from memcached in a single request. + c.requests.Add(float64(len(keys))) + results := c.memcached.GetMulti(ctx, keys) + c.hits.Add(float64(len(results))) + return results +} diff --git a/pkg/cache/memcached_test.go b/pkg/cache/memcached_test.go new file mode 100644 index 0000000000..b5f6bcf83c --- /dev/null +++ b/pkg/cache/memcached_test.go @@ -0,0 +1,126 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package cache + +import ( + "context" + "testing" + "time" + + "github.com/go-kit/kit/log" + "github.com/pkg/errors" + prom_testutil "github.com/prometheus/client_golang/prometheus/testutil" + + "github.com/thanos-io/thanos/pkg/testutil" +) + +func TestMemcachedIndexCache(t *testing.T) { + t.Parallel() + + // Init some data to conveniently define test cases later one. + key1 := "key1" + key2 := "key2" + key3 := "key3" + value1 := []byte{1} + value2 := []byte{2} + value3 := []byte{3} + + tests := map[string]struct { + setup map[string][]byte + mockedErr error + fetchKeys []string + expectedHits map[string][]byte + }{ + "should return no hits on empty cache": { + setup: nil, + fetchKeys: []string{key1, key2}, + expectedHits: map[string][]byte{}, + }, + "should return no misses on 100% hit ratio": { + setup: map[string][]byte{ + key1: value1, + key2: value2, + key3: value3, + }, + fetchKeys: []string{key1}, + expectedHits: map[string][]byte{ + key1: value1, + }, + }, + "should return hits and misses on partial hits": { + setup: map[string][]byte{ + key1: value1, + key2: value2, + }, + fetchKeys: []string{key1, key3}, + expectedHits: map[string][]byte{key1: value1}, + }, + "should return no hits on memcached error": { + setup: map[string][]byte{ + key1: value1, + key2: value2, + key3: value3, + }, + mockedErr: errors.New("mocked error"), + fetchKeys: []string{key1}, + expectedHits: nil, + }, + } + + for testName, testData := range tests { + t.Run(testName, func(t *testing.T) { + memcached := newMockedMemcachedClient(testData.mockedErr) + c := NewMemcachedCache("test", log.NewNopLogger(), memcached, nil) + + // Store the postings expected before running the test. + ctx := context.Background() + c.Store(ctx, testData.setup, time.Hour) + + // Fetch postings from cached and assert on it. + hits := c.Fetch(ctx, testData.fetchKeys) + testutil.Equals(t, testData.expectedHits, hits) + + // Assert on metrics. + testutil.Equals(t, float64(len(testData.fetchKeys)), prom_testutil.ToFloat64(c.requests)) + testutil.Equals(t, float64(len(testData.expectedHits)), prom_testutil.ToFloat64(c.hits)) + }) + } +} + +type mockedMemcachedClient struct { + cache map[string][]byte + mockedGetMultiErr error +} + +func newMockedMemcachedClient(mockedGetMultiErr error) *mockedMemcachedClient { + return &mockedMemcachedClient{ + cache: map[string][]byte{}, + mockedGetMultiErr: mockedGetMultiErr, + } +} + +func (c *mockedMemcachedClient) GetMulti(_ context.Context, keys []string) map[string][]byte { + if c.mockedGetMultiErr != nil { + return nil + } + + hits := map[string][]byte{} + + for _, key := range keys { + if value, ok := c.cache[key]; ok { + hits[key] = value + } + } + + return hits +} + +func (c *mockedMemcachedClient) SetAsync(_ context.Context, key string, value []byte, _ time.Duration) error { + c.cache[key] = value + return nil +} + +func (c *mockedMemcachedClient) Stop() { + // Nothing to do. +} diff --git a/pkg/cacheutil/memcached_client.go b/pkg/cacheutil/memcached_client.go index 2785f59d00..99fc545786 100644 --- a/pkg/cacheutil/memcached_client.go +++ b/pkg/cacheutil/memcached_client.go @@ -13,16 +13,19 @@ import ( "github.com/go-kit/kit/log/level" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/thanos-io/thanos/pkg/discovery/dns" "github.com/thanos-io/thanos/pkg/extprom" "github.com/thanos-io/thanos/pkg/gate" + "github.com/thanos-io/thanos/pkg/model" "github.com/thanos-io/thanos/pkg/tracing" yaml "gopkg.in/yaml.v2" ) const ( - opSet = "set" - opGetMulti = "getmulti" + opSet = "set" + opGetMulti = "getmulti" + reasonMaxItemSize = "max-item-size" ) var ( @@ -34,6 +37,7 @@ var ( MaxIdleConnections: 100, MaxAsyncConcurrency: 20, MaxAsyncBufferSize: 10000, + MaxItemSize: model.Bytes(1024 * 1024), MaxGetMultiConcurrency: 100, MaxGetMultiBatchSize: 0, DNSProviderUpdateInterval: 10 * time.Second, @@ -87,6 +91,11 @@ type MemcachedClientConfig struct { // running GetMulti() operations. If set to 0, concurrency is unlimited. MaxGetMultiConcurrency int `yaml:"max_get_multi_concurrency"` + // MaxItemSize specifies the maximum size of an item stored in memcached. Bigger + // items are skipped to be stored by the client. If set to 0, no maximum size is + // enforced. + MaxItemSize model.Bytes `yaml:"max_item_size"` + // MaxGetMultiBatchSize specifies the maximum number of keys a single underlying // GetMulti() should run. If more keys are specified, internally keys are splitted // into multiple batches and fetched concurrently, honoring MaxGetMultiConcurrency @@ -139,6 +148,7 @@ type memcachedClient struct { // Tracked metrics. operations *prometheus.CounterVec failures *prometheus.CounterVec + skipped *prometheus.CounterVec duration *prometheus.HistogramVec } @@ -202,28 +212,38 @@ func newMemcachedClient( ), } - c.operations = prometheus.NewCounterVec(prometheus.CounterOpts{ + c.operations = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_memcached_operations_total", Help: "Total number of operations against memcached.", ConstLabels: prometheus.Labels{"name": name}, }, []string{"operation"}) + c.operations.WithLabelValues(opGetMulti) + c.operations.WithLabelValues(opSet) - c.failures = prometheus.NewCounterVec(prometheus.CounterOpts{ + c.failures = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_memcached_operation_failures_total", Help: "Total number of operations against memcached that failed.", ConstLabels: prometheus.Labels{"name": name}, }, []string{"operation"}) + c.failures.WithLabelValues(opGetMulti) + c.failures.WithLabelValues(opSet) + + c.skipped = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ + Name: "thanos_memcached_operation_skipped_total", + Help: "Total number of operations against memcached that have been skipped.", + ConstLabels: prometheus.Labels{"name": name}, + }, []string{"operation", "reason"}) + c.skipped.WithLabelValues(opGetMulti, reasonMaxItemSize) + c.skipped.WithLabelValues(opSet, reasonMaxItemSize) - c.duration = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + c.duration = promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{ Name: "thanos_memcached_operation_duration_seconds", Help: "Duration of operations against memcached.", ConstLabels: prometheus.Labels{"name": name}, - Buckets: []float64{0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.5, 1}, + Buckets: []float64{0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.5, 1, 3, 6, 10}, }, []string{"operation"}) - - if reg != nil { - reg.MustRegister(c.operations, c.failures, c.duration) - } + c.duration.WithLabelValues(opGetMulti) + c.duration.WithLabelValues(opSet) // As soon as the client is created it must ensure that memcached server // addresses are resolved, so we're going to trigger an initial addresses @@ -252,21 +272,27 @@ func (c *memcachedClient) Stop() { c.workers.Wait() } -func (c *memcachedClient) SetAsync(ctx context.Context, key string, value []byte, ttl time.Duration) error { +func (c *memcachedClient) SetAsync(ctx context.Context, key string, value []byte, ttl time.Duration) (err error) { + // Skip hitting memcached at all if the item is bigger than the max allowed size. + if c.config.MaxItemSize > 0 && uint64(len(value)) > uint64(c.config.MaxItemSize) { + c.skipped.WithLabelValues(opSet, reasonMaxItemSize).Inc() + return nil + } + return c.enqueueAsync(func() { start := time.Now() c.operations.WithLabelValues(opSet).Inc() - span, _ := tracing.StartSpan(ctx, "memcached_set") - err := c.client.Set(&memcache.Item{ - Key: key, - Value: value, - Expiration: int32(time.Now().Add(ttl).Unix()), + tracing.DoInSpan(ctx, "memcached_set", func(ctx context.Context) { + err = c.client.Set(&memcache.Item{ + Key: key, + Value: value, + Expiration: int32(time.Now().Add(ttl).Unix()), + }) }) - span.Finish() if err != nil { c.failures.WithLabelValues(opSet).Inc() - level.Warn(c.logger).Log("msg", "failed to store item to memcached", "key", key, "err", err) + level.Warn(c.logger).Log("msg", "failed to store item to memcached", "key", key, "sizeBytes", len(value), "err", err) return } @@ -275,9 +301,13 @@ func (c *memcachedClient) SetAsync(ctx context.Context, key string, value []byte } func (c *memcachedClient) GetMulti(ctx context.Context, keys []string) map[string][]byte { + if len(keys) == 0 { + return nil + } + batches, err := c.getMultiBatched(ctx, keys) if err != nil { - level.Warn(c.logger).Log("msg", "failed to fetch items from memcached", "err", err) + level.Warn(c.logger).Log("msg", "failed to fetch items from memcached", "numKeys", len(keys), "firstKey", keys[0], "err", err) // In case we have both results and an error, it means some batch requests // failed and other succeeded. In this case we prefer to log it and move on, @@ -358,13 +388,14 @@ func (c *memcachedClient) getMultiBatched(ctx context.Context, keys []string) ([ return items, lastErr } -func (c *memcachedClient) getMultiSingle(ctx context.Context, keys []string) (map[string]*memcache.Item, error) { +func (c *memcachedClient) getMultiSingle(ctx context.Context, keys []string) (items map[string]*memcache.Item, err error) { // Wait until we get a free slot from the gate, if the max // concurrency should be enforced. if c.config.MaxGetMultiConcurrency > 0 { - span, _ := tracing.StartSpan(ctx, "memcached_getmulti_gate_ismyturn") - err := c.getMultiGate.IsMyTurn(ctx) - span.Finish() + tracing.DoInSpan(ctx, "memcached_getmulti_gate_ismyturn", func(ctx context.Context) { + // TODO(bwplotka): Consider putting span directly in gate. + err = c.getMultiGate.IsMyTurn(ctx) + }) if err != nil { return nil, errors.Wrapf(err, "failed to wait for turn") } @@ -373,10 +404,9 @@ func (c *memcachedClient) getMultiSingle(ctx context.Context, keys []string) (ma start := time.Now() c.operations.WithLabelValues(opGetMulti).Inc() - - span, _ := tracing.StartSpan(ctx, "memcached_getmulti") - items, err := c.client.GetMulti(keys) - span.Finish() + tracing.DoInSpan(ctx, "memcached_getmulti", func(ctx context.Context) { + items, err = c.client.GetMulti(keys) + }) if err != nil { c.failures.WithLabelValues(opGetMulti).Inc() } else { diff --git a/pkg/cacheutil/memcached_client_test.go b/pkg/cacheutil/memcached_client_test.go index ffee115cfe..ede486a1a1 100644 --- a/pkg/cacheutil/memcached_client_test.go +++ b/pkg/cacheutil/memcached_client_test.go @@ -14,6 +14,7 @@ import ( "github.com/go-kit/kit/log" "github.com/pkg/errors" prom_testutil "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/thanos-io/thanos/pkg/model" "github.com/thanos-io/thanos/pkg/testutil" ) @@ -76,6 +77,7 @@ addresses: testutil.Equals(t, defaultMemcachedClientConfig.DNSProviderUpdateInterval, cache.config.DNSProviderUpdateInterval) testutil.Equals(t, defaultMemcachedClientConfig.MaxGetMultiConcurrency, cache.config.MaxGetMultiConcurrency) testutil.Equals(t, defaultMemcachedClientConfig.MaxGetMultiBatchSize, cache.config.MaxGetMultiBatchSize) + testutil.Equals(t, defaultMemcachedClientConfig.MaxItemSize, cache.config.MaxItemSize) // Should instance a memcached client with configured YAML config. conf = []byte(` @@ -87,6 +89,7 @@ max_idle_connections: 1 max_async_concurrency: 1 max_async_buffer_size: 1 max_get_multi_concurrency: 1 +max_item_size: 1MiB max_get_multi_batch_size: 1 dns_provider_update_interval: 1s `) @@ -102,6 +105,7 @@ dns_provider_update_interval: 1s testutil.Equals(t, 1*time.Second, cache.config.DNSProviderUpdateInterval) testutil.Equals(t, 1, cache.config.MaxGetMultiConcurrency) testutil.Equals(t, 1, cache.config.MaxGetMultiBatchSize) + testutil.Equals(t, model.Bytes(1024*1024), cache.config.MaxItemSize) } func TestMemcachedClient_SetAsync(t *testing.T) { @@ -120,9 +124,43 @@ func TestMemcachedClient_SetAsync(t *testing.T) { testutil.Ok(t, client.SetAsync(ctx, "key-2", []byte("value-2"), time.Second)) testutil.Ok(t, backendMock.waitItems(2)) + actual, err := client.getMultiSingle(ctx, []string{"key-1", "key-2"}) + testutil.Ok(t, err) + testutil.Equals(t, []byte("value-1"), actual["key-1"].Value) + testutil.Equals(t, []byte("value-2"), actual["key-2"].Value) + testutil.Equals(t, 2.0, prom_testutil.ToFloat64(client.operations.WithLabelValues(opSet))) - testutil.Equals(t, 0.0, prom_testutil.ToFloat64(client.operations.WithLabelValues(opGetMulti))) + testutil.Equals(t, 1.0, prom_testutil.ToFloat64(client.operations.WithLabelValues(opGetMulti))) + testutil.Equals(t, 0.0, prom_testutil.ToFloat64(client.failures.WithLabelValues(opSet))) + testutil.Equals(t, 0.0, prom_testutil.ToFloat64(client.skipped.WithLabelValues(opSet, reasonMaxItemSize))) +} + +func TestMemcachedClient_SetAsyncWithCustomMaxItemSize(t *testing.T) { + defer leaktest.CheckTimeout(t, 10*time.Second)() + + ctx := context.Background() + config := defaultMemcachedClientConfig + config.Addresses = []string{"127.0.0.1:11211"} + config.MaxItemSize = model.Bytes(10) + backendMock := newMemcachedClientBackendMock() + + client, err := prepare(config, backendMock) + testutil.Ok(t, err) + defer client.Stop() + + testutil.Ok(t, client.SetAsync(ctx, "key-1", []byte("value-1"), time.Second)) + testutil.Ok(t, client.SetAsync(ctx, "key-2", []byte("value-2-too-long-to-be-stored"), time.Second)) + testutil.Ok(t, backendMock.waitItems(1)) + + actual, err := client.getMultiSingle(ctx, []string{"key-1", "key-2"}) + testutil.Ok(t, err) + testutil.Equals(t, []byte("value-1"), actual["key-1"].Value) + testutil.Equals(t, (*memcache.Item)(nil), actual["key-2"]) + + testutil.Equals(t, 1.0, prom_testutil.ToFloat64(client.operations.WithLabelValues(opSet))) + testutil.Equals(t, 1.0, prom_testutil.ToFloat64(client.operations.WithLabelValues(opGetMulti))) testutil.Equals(t, 0.0, prom_testutil.ToFloat64(client.failures.WithLabelValues(opSet))) + testutil.Equals(t, 1.0, prom_testutil.ToFloat64(client.skipped.WithLabelValues(opSet, reasonMaxItemSize))) } func TestMemcachedClient_GetMulti(t *testing.T) { diff --git a/pkg/cacheutil/memcached_server_selector_test.go b/pkg/cacheutil/memcached_server_selector_test.go index a8da4346ca..ab5848bb07 100644 --- a/pkg/cacheutil/memcached_server_selector_test.go +++ b/pkg/cacheutil/memcached_server_selector_test.go @@ -12,6 +12,7 @@ import ( "github.com/bradfitz/gomemcache/memcache" "github.com/facette/natsort" "github.com/fortytw2/leaktest" + "github.com/pkg/errors" "github.com/thanos-io/thanos/pkg/testutil" ) @@ -144,7 +145,7 @@ func TestMemcachedJumpHashSelector_PickServer_ShouldEvenlyDistributeKeysToServer for addr, count := range distribution { if count < minKeysPerServer { - testutil.Ok(t, fmt.Errorf("expected %s to have received at least %d keys instead it received %d", addr, minKeysPerServer, count)) + testutil.Ok(t, errors.Errorf("expected %s to have received at least %d keys instead it received %d", addr, minKeysPerServer, count)) } } } @@ -199,7 +200,7 @@ func TestMemcachedJumpHashSelector_PickServer_ShouldUseConsistentHashing(t *test maxExpectedMovedPerc := (1.0 / float64(len(servers))) + 0.02 maxExpectedMoved := int(float64(numKeys) * maxExpectedMovedPerc) if moved > maxExpectedMoved { - testutil.Ok(t, fmt.Errorf("expected resharding moved no more then %d keys while %d have been moved", maxExpectedMoved, moved)) + testutil.Ok(t, errors.Errorf("expected resharding moved no more then %d keys while %d have been moved", maxExpectedMoved, moved)) } } diff --git a/pkg/compact/blocks_cleaner.go b/pkg/compact/blocks_cleaner.go new file mode 100644 index 0000000000..7381505118 --- /dev/null +++ b/pkg/compact/blocks_cleaner.go @@ -0,0 +1,59 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package compact + +import ( + "context" + "time" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" + "github.com/thanos-io/thanos/pkg/block" + "github.com/thanos-io/thanos/pkg/objstore" +) + +// BlocksCleaner is a struct that deletes blocks from bucket which are marked for deletion. +type BlocksCleaner struct { + logger log.Logger + ignoreDeletionMarkFilter *block.IgnoreDeletionMarkFilter + bkt objstore.Bucket + deleteDelay time.Duration + blocksCleaned prometheus.Counter + blockCleanupFailures prometheus.Counter +} + +// NewBlocksCleaner creates a new BlocksCleaner. +func NewBlocksCleaner(logger log.Logger, bkt objstore.Bucket, ignoreDeletionMarkFilter *block.IgnoreDeletionMarkFilter, deleteDelay time.Duration, blocksCleaned prometheus.Counter, blockCleanupFailures prometheus.Counter) *BlocksCleaner { + return &BlocksCleaner{ + logger: logger, + ignoreDeletionMarkFilter: ignoreDeletionMarkFilter, + bkt: bkt, + deleteDelay: deleteDelay, + blocksCleaned: blocksCleaned, + blockCleanupFailures: blockCleanupFailures, + } +} + +// DeleteMarkedBlocks uses ignoreDeletionMarkFilter to gather the blocks that are marked for deletion and deletes those +// if older than given deleteDelay. +func (s *BlocksCleaner) DeleteMarkedBlocks(ctx context.Context) error { + level.Info(s.logger).Log("msg", "started cleaning of blocks marked for deletion") + + deletionMarkMap := s.ignoreDeletionMarkFilter.DeletionMarkBlocks() + for _, deletionMark := range deletionMarkMap { + if time.Since(time.Unix(deletionMark.DeletionTime, 0)).Seconds() > s.deleteDelay.Seconds() { + if err := block.Delete(ctx, s.logger, s.bkt, deletionMark.ID); err != nil { + s.blockCleanupFailures.Inc() + return errors.Wrap(err, "delete block") + } + s.blocksCleaned.Inc() + level.Info(s.logger).Log("msg", "deleted block marked for deletion", "block", deletionMark.ID) + } + } + + level.Info(s.logger).Log("msg", "cleaning of blocks marked for deletion done") + return nil +} diff --git a/pkg/compact/clean.go b/pkg/compact/clean.go index af681a940e..8d99927d51 100644 --- a/pkg/compact/clean.go +++ b/pkg/compact/clean.go @@ -21,12 +21,16 @@ const ( PartialUploadThresholdAge = 2 * 24 * time.Hour ) -func BestEffortCleanAbortedPartialUploads(ctx context.Context, logger log.Logger, fetcher block.MetadataFetcher, bkt objstore.Bucket, deleteAttempts prometheus.Counter) { +func BestEffortCleanAbortedPartialUploads( + ctx context.Context, + logger log.Logger, + partial map[ulid.ULID]error, + bkt objstore.Bucket, + deleteAttempts prometheus.Counter, + blockCleanups prometheus.Counter, + blockCleanupFailures prometheus.Counter, +) { level.Info(logger).Log("msg", "started cleaning of aborted partial uploads") - _, partial, err := fetcher.Fetch(ctx) - if err != nil { - level.Warn(logger).Log("msg", "failed to fetch metadata for cleaning of aborted partial uploads; skipping", "err", err) - } // Delete partial blocks that are older than partialUploadThresholdAge. // TODO(bwplotka): This is can cause data loss if blocks are: @@ -41,10 +45,16 @@ func BestEffortCleanAbortedPartialUploads(ctx context.Context, logger log.Logger } deleteAttempts.Inc() + level.Info(logger).Log("msg", "found partially uploaded block; marking for deletion", "block", id) + // We don't gather any information about deletion marks for partial blocks, so let's simply remove it. We waited + // long PartialUploadThresholdAge already. + // TODO(bwplotka): Fix some edge cases: https://github.com/thanos-io/thanos/issues/2470 . if err := block.Delete(ctx, logger, bkt, id); err != nil { - level.Warn(logger).Log("msg", "failed to delete aborted partial upload; skipping", "block", id, "thresholdAge", PartialUploadThresholdAge, "err", err) - return + blockCleanupFailures.Inc() + level.Warn(logger).Log("msg", "failed to delete aborted partial upload; will retry in next iteration", "block", id, "thresholdAge", PartialUploadThresholdAge, "err", err) + continue } + blockCleanups.Inc() level.Info(logger).Log("msg", "deleted aborted partial upload", "block", id, "thresholdAge", PartialUploadThresholdAge) } level.Info(logger).Log("msg", "cleaning of aborted partial uploads done") diff --git a/pkg/compact/clean_test.go b/pkg/compact/clean_test.go index 85654f8c8a..ea0f840c69 100644 --- a/pkg/compact/clean_test.go +++ b/pkg/compact/clean_test.go @@ -14,10 +14,11 @@ import ( "github.com/go-kit/kit/log" "github.com/oklog/ulid" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/thanos-io/thanos/pkg/block" "github.com/thanos-io/thanos/pkg/block/metadata" - "github.com/thanos-io/thanos/pkg/objstore/inmem" + "github.com/thanos-io/thanos/pkg/objstore" "github.com/thanos-io/thanos/pkg/testutil" ) @@ -25,10 +26,10 @@ func TestBestEffortCleanAbortedPartialUploads(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - bkt := inmem.NewBucket() + bkt := objstore.WithNoopInstr(objstore.NewInMemBucket()) logger := log.NewNopLogger() - metaFetcher, err := block.NewMetaFetcher(nil, 32, bkt, "", nil) + metaFetcher, err := block.NewMetaFetcher(nil, 32, bkt, "", nil, nil, nil) testutil.Ok(t, err) // 1. No meta, old block, should be removed. @@ -57,9 +58,16 @@ func TestBestEffortCleanAbortedPartialUploads(t *testing.T) { testutil.Ok(t, bkt.Upload(ctx, path.Join(shouldIgnoreID2.String(), "chunks", "000001"), &fakeChunk)) - deleteAttempts := prometheus.NewCounter(prometheus.CounterOpts{}) - BestEffortCleanAbortedPartialUploads(ctx, logger, metaFetcher, bkt, deleteAttempts) + deleteAttempts := promauto.With(nil).NewCounter(prometheus.CounterOpts{}) + blockCleanups := promauto.With(nil).NewCounter(prometheus.CounterOpts{}) + blockCleanupFailures := promauto.With(nil).NewCounter(prometheus.CounterOpts{}) + _, partial, err := metaFetcher.Fetch(ctx) + testutil.Ok(t, err) + + BestEffortCleanAbortedPartialUploads(ctx, logger, partial, bkt, deleteAttempts, blockCleanups, blockCleanupFailures) testutil.Equals(t, 1.0, promtest.ToFloat64(deleteAttempts)) + testutil.Equals(t, 1.0, promtest.ToFloat64(blockCleanups)) + testutil.Equals(t, 0.0, promtest.ToFloat64(blockCleanupFailures)) exists, err := bkt.Exists(ctx, path.Join(shouldDeleteID.String(), "chunks", "000001")) testutil.Ok(t, err) diff --git a/pkg/compact/compact.go b/pkg/compact/compact.go index b268724e10..126a9127a4 100644 --- a/pkg/compact/compact.go +++ b/pkg/compact/compact.go @@ -18,6 +18,7 @@ import ( "github.com/oklog/ulid" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/tsdb" terrors "github.com/prometheus/prometheus/tsdb/errors" @@ -45,11 +46,13 @@ type Syncer struct { fetcher block.MetadataFetcher mtx sync.Mutex blocks map[ulid.ULID]*metadata.Meta + partial map[ulid.ULID]error blockSyncConcurrency int metrics *syncerMetrics acceptMalformedIndex bool enableVerticalCompaction bool duplicateBlocksFilter *block.DeduplicateFilter + ignoreDeletionMarkFilter *block.IgnoreDeletionMarkFilter } type syncerMetrics struct { @@ -62,82 +65,72 @@ type syncerMetrics struct { compactionRunsCompleted *prometheus.CounterVec compactionFailures *prometheus.CounterVec verticalCompactions *prometheus.CounterVec + blocksMarkedForDeletion prometheus.Counter } -func newSyncerMetrics(reg prometheus.Registerer) *syncerMetrics { +func newSyncerMetrics(reg prometheus.Registerer, blocksMarkedForDeletion prometheus.Counter) *syncerMetrics { var m syncerMetrics - m.garbageCollectedBlocks = prometheus.NewCounter(prometheus.CounterOpts{ + m.garbageCollectedBlocks = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_compact_garbage_collected_blocks_total", - Help: "Total number of deleted blocks by compactor.", + Help: "Total number of blocks marked for deletion by compactor.", }) - m.garbageCollections = prometheus.NewCounter(prometheus.CounterOpts{ + m.garbageCollections = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_compact_garbage_collection_total", Help: "Total number of garbage collection operations.", }) - m.garbageCollectionFailures = prometheus.NewCounter(prometheus.CounterOpts{ + m.garbageCollectionFailures = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_compact_garbage_collection_failures_total", Help: "Total number of failed garbage collection operations.", }) - m.garbageCollectionDuration = prometheus.NewHistogram(prometheus.HistogramOpts{ + m.garbageCollectionDuration = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{ Name: "thanos_compact_garbage_collection_duration_seconds", Help: "Time it took to perform garbage collection iteration.", Buckets: []float64{0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120, 240, 360, 720}, }) - m.compactions = prometheus.NewCounterVec(prometheus.CounterOpts{ + m.compactions = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_compact_group_compactions_total", Help: "Total number of group compaction attempts that resulted in a new block.", }, []string{"group"}) - m.compactionRunsStarted = prometheus.NewCounterVec(prometheus.CounterOpts{ + m.compactionRunsStarted = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_compact_group_compaction_runs_started_total", Help: "Total number of group compaction attempts.", }, []string{"group"}) - m.compactionRunsCompleted = prometheus.NewCounterVec(prometheus.CounterOpts{ + m.compactionRunsCompleted = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_compact_group_compaction_runs_completed_total", Help: "Total number of group completed compaction runs. This also includes compactor group runs that resulted with no compaction.", }, []string{"group"}) - m.compactionFailures = prometheus.NewCounterVec(prometheus.CounterOpts{ + m.compactionFailures = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_compact_group_compactions_failures_total", Help: "Total number of failed group compactions.", }, []string{"group"}) - m.verticalCompactions = prometheus.NewCounterVec(prometheus.CounterOpts{ + m.verticalCompactions = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_compact_group_vertical_compactions_total", Help: "Total number of group compaction attempts that resulted in a new block based on overlapping blocks.", }, []string{"group"}) + m.blocksMarkedForDeletion = blocksMarkedForDeletion - if reg != nil { - reg.MustRegister( - m.garbageCollectedBlocks, - m.garbageCollections, - m.garbageCollectionFailures, - m.garbageCollectionDuration, - m.compactions, - m.compactionRunsStarted, - m.compactionRunsCompleted, - m.compactionFailures, - m.verticalCompactions, - ) - } return &m } // NewMetaSyncer returns a new Syncer for the given Bucket and directory. // Blocks must be at least as old as the sync delay for being considered. -func NewSyncer(logger log.Logger, reg prometheus.Registerer, bkt objstore.Bucket, fetcher block.MetadataFetcher, duplicateBlocksFilter *block.DeduplicateFilter, blockSyncConcurrency int, acceptMalformedIndex bool, enableVerticalCompaction bool) (*Syncer, error) { +func NewSyncer(logger log.Logger, reg prometheus.Registerer, bkt objstore.Bucket, fetcher block.MetadataFetcher, duplicateBlocksFilter *block.DeduplicateFilter, ignoreDeletionMarkFilter *block.IgnoreDeletionMarkFilter, blocksMarkedForDeletion prometheus.Counter, blockSyncConcurrency int, acceptMalformedIndex bool, enableVerticalCompaction bool) (*Syncer, error) { if logger == nil { logger = log.NewNopLogger() } return &Syncer{ - logger: logger, - reg: reg, - bkt: bkt, - fetcher: fetcher, - blocks: map[ulid.ULID]*metadata.Meta{}, - metrics: newSyncerMetrics(reg), - duplicateBlocksFilter: duplicateBlocksFilter, - blockSyncConcurrency: blockSyncConcurrency, - acceptMalformedIndex: acceptMalformedIndex, + logger: logger, + reg: reg, + bkt: bkt, + fetcher: fetcher, + blocks: map[ulid.ULID]*metadata.Meta{}, + metrics: newSyncerMetrics(reg, blocksMarkedForDeletion), + duplicateBlocksFilter: duplicateBlocksFilter, + ignoreDeletionMarkFilter: ignoreDeletionMarkFilter, + blockSyncConcurrency: blockSyncConcurrency, + acceptMalformedIndex: acceptMalformedIndex, // The syncer offers an option to enable vertical compaction, even if it's // not currently used by Thanos, because the compactor is also used by Cortex // which needs vertical compaction. @@ -157,23 +150,40 @@ func UntilNextDownsampling(m *metadata.Meta) (time.Duration, error) { case downsample.ResLevel0: return time.Duration(downsample.DownsampleRange0*time.Millisecond) - timeRange, nil default: - panic(fmt.Errorf("invalid resolution %v", m.Thanos.Downsample.Resolution)) + panic(errors.Errorf("invalid resolution %v", m.Thanos.Downsample.Resolution)) } } +// SyncMetas synchronises local state of block metas with what we have in the bucket. func (s *Syncer) SyncMetas(ctx context.Context) error { s.mtx.Lock() defer s.mtx.Unlock() - metas, _, err := s.fetcher.Fetch(ctx) + metas, partial, err := s.fetcher.Fetch(ctx) if err != nil { return retry(err) } s.blocks = metas - + s.partial = partial return nil } +// Partial returns partial blocks since last sync. +func (s *Syncer) Partial() map[ulid.ULID]error { + s.mtx.Lock() + defer s.mtx.Unlock() + + return s.partial +} + +// Metas returns loaded metadata blocks since last sync. +func (s *Syncer) Metas() map[ulid.ULID]*metadata.Meta { + s.mtx.Lock() + defer s.mtx.Unlock() + + return s.blocks +} + // GroupKey returns a unique identifier for the group the block belongs to. It considers // the downsampling resolution and the block's labels. func GroupKey(meta metadata.Thanos) string { @@ -195,10 +205,11 @@ func (s *Syncer) Groups() (res []*Group, err error) { groupKey := GroupKey(m.Thanos) g, ok := groups[groupKey] if !ok { + lbls := labels.FromMap(m.Thanos.Labels) g, err = newGroup( - log.With(s.logger, "compactionGroup", groupKey), + log.With(s.logger, "group", fmt.Sprintf("%d@%v", m.Thanos.Downsample.Resolution, lbls.String()), "groupKey", groupKey), s.bkt, - labels.FromMap(m.Thanos.Labels), + lbls, m.Thanos.Downsample.Resolution, s.acceptMalformedIndex, s.enableVerticalCompaction, @@ -208,6 +219,7 @@ func (s *Syncer) Groups() (res []*Group, err error) { s.metrics.compactionFailures.WithLabelValues(groupKey), s.metrics.verticalCompactions.WithLabelValues(groupKey), s.metrics.garbageCollectedBlocks, + s.metrics.blocksMarkedForDeletion, ) if err != nil { return nil, errors.Wrap(err, "create compaction group") @@ -225,7 +237,7 @@ func (s *Syncer) Groups() (res []*Group, err error) { return res, nil } -// GarbageCollect deletes blocks from the bucket if their data is available as part of a +// GarbageCollect marks blocks for deletion from bucket if their data is available as part of a // block with a higher compaction level. // Call to SyncMetas function is required to populate duplicateIDs in duplicateBlocksFilter. func (s *Syncer) GarbageCollect(ctx context.Context) error { @@ -234,22 +246,34 @@ func (s *Syncer) GarbageCollect(ctx context.Context) error { begin := time.Now() - garbageIds := s.duplicateBlocksFilter.DuplicateIDs() - for _, id := range garbageIds { + // Ignore filter exists before deduplicate filter. + deletionMarkMap := s.ignoreDeletionMarkFilter.DeletionMarkBlocks() + duplicateIDs := s.duplicateBlocksFilter.DuplicateIDs() + + // GarbageIDs contains the duplicateIDs, since these blocks can be replaced with other blocks. + // We also remove ids present in deletionMarkMap since these blocks are already marked for deletion. + garbageIDs := []ulid.ULID{} + for _, id := range duplicateIDs { + if _, exists := deletionMarkMap[id]; exists { + continue + } + garbageIDs = append(garbageIDs, id) + } + + for _, id := range garbageIDs { if ctx.Err() != nil { return ctx.Err() } - // Spawn a new context so we always delete a block in full on shutdown. + // Spawn a new context so we always mark a block for deletion in full on shutdown. delCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) - level.Info(s.logger).Log("msg", "deleting outdated block", "block", id) - - err := block.Delete(delCtx, s.logger, s.bkt, id) + level.Info(s.logger).Log("msg", "marking outdated block for deletion", "block", id) + err := block.MarkForDeletion(delCtx, s.logger, s.bkt, id, s.metrics.blocksMarkedForDeletion) cancel() if err != nil { s.metrics.garbageCollectionFailures.Inc() - return retry(errors.Wrapf(err, "delete block %s from bucket", id)) + return retry(errors.Wrapf(err, "mark block %s for deletion", id)) } // Immediately update our in-memory state so no further call to SyncMetas is needed @@ -279,6 +303,7 @@ type Group struct { compactionFailures prometheus.Counter verticalCompactions prometheus.Counter groupGarbageCollectedBlocks prometheus.Counter + blocksMarkedForDeletion prometheus.Counter } // newGroup returns a new compaction group. @@ -295,6 +320,7 @@ func newGroup( compactionFailures prometheus.Counter, verticalCompactions prometheus.Counter, groupGarbageCollectedBlocks prometheus.Counter, + blocksMarkedForDeletion prometheus.Counter, ) (*Group, error) { if logger == nil { logger = log.NewNopLogger() @@ -313,6 +339,7 @@ func newGroup( compactionFailures: compactionFailures, verticalCompactions: verticalCompactions, groupGarbageCollectedBlocks: groupGarbageCollectedBlocks, + blocksMarkedForDeletion: blocksMarkedForDeletion, } return g, nil } @@ -427,7 +454,7 @@ func (e HaltError) Error() string { // IsHaltError returns true if the base error is a HaltError. // If a multierror is passed, any halt error will return true. func IsHaltError(err error) bool { - if multiErr, ok := err.(terrors.MultiError); ok { + if multiErr, ok := errors.Cause(err).(terrors.MultiError); ok { for _, err := range multiErr { if _, ok := errors.Cause(err).(HaltError); ok { return true @@ -508,7 +535,7 @@ func (cg *Group) areBlocksOverlapping(include *metadata.Meta, excludeDirs ...str } // RepairIssue347 repairs the https://github.com/prometheus/tsdb/issues/347 issue when having issue347Error. -func RepairIssue347(ctx context.Context, logger log.Logger, bkt objstore.Bucket, issue347Err error) error { +func RepairIssue347(ctx context.Context, logger log.Logger, bkt objstore.Bucket, blocksMarkedForDeletion prometheus.Counter, issue347Err error) error { ie, ok := errors.Cause(issue347Err).(Issue347Error) if !ok { return errors.Errorf("Given error is not an issue347 error: %v", issue347Err) @@ -554,15 +581,14 @@ func RepairIssue347(ctx context.Context, logger log.Logger, bkt objstore.Bucket, level.Info(logger).Log("msg", "deleting broken block", "id", ie.id) - // Spawn a new context so we always delete a block in full on shutdown. + // Spawn a new context so we always mark a block for deletion in full on shutdown. delCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // TODO(bplotka): Issue with this will introduce overlap that will halt compactor. Automate that (fix duplicate overlaps caused by this). - if err := block.Delete(delCtx, logger, bkt, ie.id); err != nil { - return errors.Wrapf(err, "deleting old block %s failed. You need to delete this block manually", ie.id) + if err := block.MarkForDeletion(delCtx, logger, bkt, ie.id, blocksMarkedForDeletion); err != nil { + return errors.Wrapf(err, "marking old block %s for deletion has failed", ie.id) } - return nil } @@ -573,6 +599,8 @@ func (cg *Group) compact(ctx context.Context, dir string, comp tsdb.Compactor) ( // Check for overlapped blocks. overlappingBlocks := false if err := cg.areBlocksOverlapping(nil); err != nil { + // TODO(bwplotka): It would really nice if we could still check for other overlaps than replica. In fact this should be checked + // in syncer itself. Otherwise with vertical compaction enabled we will sacrifice this important check. if !cg.enableVerticalCompaction { return false, ulid.ULID{}, halt(errors.Wrap(err, "pre compaction overlap check")) } @@ -602,6 +630,8 @@ func (cg *Group) compact(ctx context.Context, dir string, comp tsdb.Compactor) ( return false, ulid.ULID{}, nil } + level.Info(cg.logger).Log("msg", "compaction available and planned; downloading blocks", "plan", fmt.Sprintf("%v", plan)) + // Due to #183 we verify that none of the blocks in the plan have overlapping sources. // This is one potential source of how we could end up with duplicated chunks. uniqueSources := map[ulid.ULID]struct{}{} @@ -659,8 +689,7 @@ func (cg *Group) compact(ctx context.Context, dir string, comp tsdb.Compactor) ( "block id %s, try running with --debug.accept-malformed-index", id) } } - level.Debug(cg.logger).Log("msg", "downloaded and verified blocks", - "blocks", fmt.Sprintf("%v", plan), "duration", time.Since(begin)) + level.Info(cg.logger).Log("msg", "downloaded and verified blocks; compacting blocks", "plan", fmt.Sprintf("%v", plan), "duration", time.Since(begin)) begin = time.Now() @@ -679,7 +708,7 @@ func (cg *Group) compact(ctx context.Context, dir string, comp tsdb.Compactor) ( } if meta.Stats.NumSamples == 0 { if err := cg.deleteBlock(block); err != nil { - level.Warn(cg.logger).Log("msg", "failed to delete empty block found during compaction", "block", block) + level.Warn(cg.logger).Log("msg", "failed to mark for deletion an empty block found during compaction", "block", block) } } } @@ -690,7 +719,7 @@ func (cg *Group) compact(ctx context.Context, dir string, comp tsdb.Compactor) ( if overlappingBlocks { cg.verticalCompactions.Inc() } - level.Info(cg.logger).Log("msg", "compacted blocks", + level.Info(cg.logger).Log("msg", "compacted blocks", "new", compID, "blocks", fmt.Sprintf("%v", plan), "duration", time.Since(begin), "overlapping_blocks", overlappingBlocks) bdir := filepath.Join(dir, compID.String()) @@ -734,12 +763,12 @@ func (cg *Group) compact(ctx context.Context, dir string, comp tsdb.Compactor) ( } level.Info(cg.logger).Log("msg", "uploaded block", "result_block", compID, "duration", time.Since(begin)) - // Delete the blocks we just compacted from the group and bucket so they do not get included + // Mark for deletion the blocks we just compacted from the group and bucket so they do not get included // into the next planning cycle. // Eventually the block we just uploaded should get synced into the group again (including sync-delay). for _, b := range plan { if err := cg.deleteBlock(b); err != nil { - return false, ulid.ULID{}, retry(errors.Wrapf(err, "delete old block from bucket")) + return false, ulid.ULID{}, retry(errors.Wrapf(err, "mark old block for deletion from bucket")) } cg.groupGarbageCollectedBlocks.Inc() } @@ -757,12 +786,12 @@ func (cg *Group) deleteBlock(b string) error { return errors.Wrapf(err, "remove old block dir %s", id) } - // Spawn a new context so we always delete a block in full on shutdown. + // Spawn a new context so we always mark a block for deletion in full on shutdown. delCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() - level.Info(cg.logger).Log("msg", "deleting compacted block", "old_block", id) - if err := block.Delete(delCtx, cg.logger, cg.bkt, id); err != nil { - return errors.Wrapf(err, "delete block %s from bucket", id) + level.Info(cg.logger).Log("msg", "marking compacted block for deletion", "old_block", id) + if err := block.MarkForDeletion(delCtx, cg.logger, cg.bkt, id, cg.blocksMarkedForDeletion); err != nil { + return errors.Wrapf(err, "mark block %s for deletion from bucket", id) } return nil } @@ -837,14 +866,14 @@ func (c *BucketCompactor) Compact(ctx context.Context) error { } if IsIssue347Error(err) { - if err := RepairIssue347(workCtx, c.logger, c.bkt, err); err == nil { + if err := RepairIssue347(workCtx, c.logger, c.bkt, c.sy.metrics.blocksMarkedForDeletion, err); err == nil { mtx.Lock() finishedAllGroups = false mtx.Unlock() continue } } - errChan <- errors.Wrap(err, fmt.Sprintf("compaction failed for group %s", g.Key())) + errChan <- errors.Wrapf(err, "group %s", g.Key()) return } }() @@ -856,29 +885,26 @@ func (c *BucketCompactor) Compact(ctx context.Context) error { } level.Info(c.logger).Log("msg", "start sync of metas") - if err := c.sy.SyncMetas(ctx); err != nil { return errors.Wrap(err, "sync") } level.Info(c.logger).Log("msg", "start of GC") - // Blocks that were compacted are garbage collected after each Compaction. // However if compactor crashes we need to resolve those on startup. if err := c.sy.GarbageCollect(ctx); err != nil { return errors.Wrap(err, "garbage") } - level.Info(c.logger).Log("msg", "start of compaction") - groups, err := c.sy.Groups() if err != nil { return errors.Wrap(err, "build compaction groups") } + level.Info(c.logger).Log("msg", "start of compactions") + // Send all groups found during this pass to the compaction workers. var groupErrs terrors.MultiError - groupLoop: for _, g := range groups { select { diff --git a/pkg/compact/compact_e2e_test.go b/pkg/compact/compact_e2e_test.go index 43ce297434..6bf8a44887 100644 --- a/pkg/compact/compact_e2e_test.go +++ b/pkg/compact/compact_e2e_test.go @@ -19,6 +19,7 @@ import ( "github.com/go-kit/kit/log" "github.com/oklog/ulid" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/tsdb" @@ -89,12 +90,14 @@ func TestSyncer_GarbageCollect_e2e(t *testing.T) { } duplicateBlocksFilter := block.NewDeduplicateFilter() - metaFetcher, err := block.NewMetaFetcher(nil, 32, bkt, "", nil, - duplicateBlocksFilter.Filter, - ) + metaFetcher, err := block.NewMetaFetcher(nil, 32, objstore.WithNoopInstr(bkt), "", nil, []block.MetadataFilter{ + duplicateBlocksFilter, + }, nil) testutil.Ok(t, err) - sy, err := NewSyncer(nil, nil, bkt, metaFetcher, duplicateBlocksFilter, 1, false, false) + blocksMarkedForDeletion := promauto.With(nil).NewCounter(prometheus.CounterOpts{}) + ignoreDeletionMarkFilter := block.NewIgnoreDeletionMarkFilter(nil, nil, 48*time.Hour) + sy, err := NewSyncer(nil, nil, bkt, metaFetcher, duplicateBlocksFilter, ignoreDeletionMarkFilter, blocksMarkedForDeletion, 1, false, false) testutil.Ok(t, err) // Do one initial synchronization with the bucket. @@ -103,7 +106,16 @@ func TestSyncer_GarbageCollect_e2e(t *testing.T) { var rem []ulid.ULID err = bkt.Iter(ctx, "", func(n string) error { - rem = append(rem, ulid.MustParse(n[:len(n)-1])) + id := ulid.MustParse(n[:len(n)-1]) + deletionMarkFile := path.Join(id.String(), metadata.DeletionMarkFilename) + + exists, err := bkt.Exists(ctx, deletionMarkFile) + if err != nil { + return err + } + if !exists { + rem = append(rem, id) + } return nil }) testutil.Ok(t, err) @@ -117,6 +129,7 @@ func TestSyncer_GarbageCollect_e2e(t *testing.T) { // After another sync the changes should also be reflected in the local groups. testutil.Ok(t, sy.SyncMetas(ctx)) + testutil.Ok(t, sy.GarbageCollect(ctx)) // Only the level 3 block, the last source block in both resolutions should be left. groups, err := sy.Groups() @@ -164,13 +177,16 @@ func TestGroup_Compact_e2e(t *testing.T) { reg := prometheus.NewRegistry() + ignoreDeletionMarkFilter := block.NewIgnoreDeletionMarkFilter(logger, objstore.WithNoopInstr(bkt), 48*time.Hour) duplicateBlocksFilter := block.NewDeduplicateFilter() - metaFetcher, err := block.NewMetaFetcher(nil, 32, bkt, "", nil, - duplicateBlocksFilter.Filter, - ) + metaFetcher, err := block.NewMetaFetcher(nil, 32, objstore.WithNoopInstr(bkt), "", nil, []block.MetadataFilter{ + ignoreDeletionMarkFilter, + duplicateBlocksFilter, + }, nil) testutil.Ok(t, err) - sy, err := NewSyncer(nil, nil, bkt, metaFetcher, duplicateBlocksFilter, 5, false, false) + blocksMarkedForDeletion := promauto.With(nil).NewCounter(prometheus.CounterOpts{}) + sy, err := NewSyncer(nil, nil, bkt, metaFetcher, duplicateBlocksFilter, ignoreDeletionMarkFilter, blocksMarkedForDeletion, 5, false, false) testutil.Ok(t, err) comp, err := tsdb.NewLeveledCompactor(ctx, reg, logger, []int64{1000, 3000}, nil) @@ -182,6 +198,7 @@ func TestGroup_Compact_e2e(t *testing.T) { // Compaction on empty should not fail. testutil.Ok(t, bComp.Compact(ctx)) testutil.Equals(t, 0.0, promtest.ToFloat64(sy.metrics.garbageCollectedBlocks)) + testutil.Equals(t, 0.0, promtest.ToFloat64(sy.metrics.blocksMarkedForDeletion)) testutil.Equals(t, 0.0, promtest.ToFloat64(sy.metrics.garbageCollectionFailures)) testutil.Equals(t, 0, MetricCount(sy.metrics.compactions)) testutil.Equals(t, 0, MetricCount(sy.metrics.compactionRunsStarted)) @@ -270,6 +287,7 @@ func TestGroup_Compact_e2e(t *testing.T) { testutil.Ok(t, bComp.Compact(ctx)) testutil.Equals(t, 5.0, promtest.ToFloat64(sy.metrics.garbageCollectedBlocks)) + testutil.Equals(t, 5.0, promtest.ToFloat64(sy.metrics.blocksMarkedForDeletion)) testutil.Equals(t, 0.0, promtest.ToFloat64(sy.metrics.garbageCollectionFailures)) testutil.Equals(t, 4, MetricCount(sy.metrics.compactions)) testutil.Equals(t, 1.0, promtest.ToFloat64(sy.metrics.compactions.WithLabelValues(GroupKey(metas[0].Thanos)))) @@ -399,3 +417,102 @@ func createAndUpload(t testing.TB, bkt objstore.Bucket, blocks []blockgenSpec) ( } return metas } + +// Regression test for #2459 issue. +func TestGarbageCollectDoesntCreateEmptyBlocksWithDeletionMarksOnly(t *testing.T) { + logger := log.NewLogfmtLogger(os.Stderr) + + objtesting.ForeachStore(t, func(t *testing.T, bkt objstore.Bucket) { + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + + // Generate two blocks, and then another block that covers both of them. + var metas []*metadata.Meta + var ids []ulid.ULID + + for i := 0; i < 2; i++ { + var m metadata.Meta + + m.Version = 1 + m.ULID = ulid.MustNew(uint64(i), nil) + m.Compaction.Sources = []ulid.ULID{m.ULID} + m.Compaction.Level = 1 + + ids = append(ids, m.ULID) + metas = append(metas, &m) + } + + var m1 metadata.Meta + m1.Version = 1 + m1.ULID = ulid.MustNew(100, nil) + m1.Compaction.Level = 2 + m1.Compaction.Sources = ids + m1.Thanos.Downsample.Resolution = 0 + + // Create all blocks in the bucket. + for _, m := range append(metas, &m1) { + fmt.Println("create", m.ULID) + var buf bytes.Buffer + testutil.Ok(t, json.NewEncoder(&buf).Encode(&m)) + testutil.Ok(t, bkt.Upload(ctx, path.Join(m.ULID.String(), metadata.MetaFilename), &buf)) + } + + blocksMarkedForDeletion := promauto.With(nil).NewCounter(prometheus.CounterOpts{}) + ignoreDeletionMarkFilter := block.NewIgnoreDeletionMarkFilter(nil, objstore.WithNoopInstr(bkt), 48*time.Hour) + + duplicateBlocksFilter := block.NewDeduplicateFilter() + metaFetcher, err := block.NewMetaFetcher(nil, 32, objstore.WithNoopInstr(bkt), "", nil, []block.MetadataFilter{ + ignoreDeletionMarkFilter, + duplicateBlocksFilter, + }, nil) + testutil.Ok(t, err) + + sy, err := NewSyncer(nil, nil, bkt, metaFetcher, duplicateBlocksFilter, ignoreDeletionMarkFilter, blocksMarkedForDeletion, 1, false, false) + testutil.Ok(t, err) + + // Do one initial synchronization with the bucket. + testutil.Ok(t, sy.SyncMetas(ctx)) + testutil.Ok(t, sy.GarbageCollect(ctx)) + testutil.Equals(t, 2.0, promtest.ToFloat64(sy.metrics.garbageCollectedBlocks)) + + rem, err := listBlocksMarkedForDeletion(ctx, bkt) + testutil.Ok(t, err) + + sort.Slice(rem, func(i, j int) bool { + return rem[i].Compare(rem[j]) < 0 + }) + + testutil.Equals(t, ids, rem) + + // Delete source blocks. + for _, id := range ids { + testutil.Ok(t, block.Delete(ctx, logger, bkt, id)) + } + + // After another garbage-collect, we should not find new blocks that are deleted with new deletion mark files. + testutil.Ok(t, sy.SyncMetas(ctx)) + testutil.Ok(t, sy.GarbageCollect(ctx)) + + rem, err = listBlocksMarkedForDeletion(ctx, bkt) + testutil.Ok(t, err) + testutil.Equals(t, 0, len(rem)) + }) +} + +func listBlocksMarkedForDeletion(ctx context.Context, bkt objstore.Bucket) ([]ulid.ULID, error) { + var rem []ulid.ULID + err := bkt.Iter(ctx, "", func(n string) error { + id := ulid.MustParse(n[:len(n)-1]) + deletionMarkFile := path.Join(id.String(), metadata.DeletionMarkFilename) + + exists, err := bkt.Exists(ctx, deletionMarkFile) + if err != nil { + return err + } + if exists { + rem = append(rem, id) + } + return nil + }) + return rem, err +} diff --git a/pkg/compact/compact_test.go b/pkg/compact/compact_test.go index a3c51f61c0..29ecba297d 100644 --- a/pkg/compact/compact_test.go +++ b/pkg/compact/compact_test.go @@ -36,6 +36,8 @@ func TestHaltMultiError(t *testing.T) { errs.Add(haltErr) testutil.Assert(t, IsHaltError(errs), "if any halt errors are present this should return true") + testutil.Assert(t, IsHaltError(errors.Wrap(errs, "wrap")), "halt error with wrap") + } func TestRetryMultiError(t *testing.T) { diff --git a/pkg/compact/downsample/downsample.go b/pkg/compact/downsample/downsample.go index 5e14c26bb3..b1013ba8d2 100644 --- a/pkg/compact/downsample/downsample.go +++ b/pkg/compact/downsample/downsample.go @@ -116,6 +116,13 @@ func Downsample( if err := indexr.Series(postings.At(), &lset, &chks); err != nil { return id, errors.Wrapf(err, "get series %d", postings.At()) } + + for i, c := range chks[1:] { + if chks[i].MaxTime >= c.MinTime { + return id, errors.Errorf("found overlapping chunks within series %d. Chunks expected to be ordered by min time and non-overlapping, got: %v", postings.At(), chks) + } + } + // While #183 exists, we sanitize the chunks we retrieved from the block // before retrieving their samples. for i, c := range chks { @@ -129,6 +136,9 @@ func Downsample( // Raw and already downsampled data need different processing. if origMeta.Thanos.Downsample.Resolution == 0 { for _, c := range chks { + // TODO(bwplotka): We can optimze this further by using in WriteSeries iterators of each chunk instead of + // samples. Also ensure 120 sample limit, otherwise we have gigantic chunks. + // https://github.com/thanos-io/thanos/issues/2542. if err := expandChunkIterator(c.Chunk.Iterator(reuseIt), &all); err != nil { return id, errors.Wrapf(err, "expand chunk %d, series %d", c.Ref, postings.At()) } @@ -139,7 +149,11 @@ func Downsample( } else { // Downsample a block that contains aggregated chunks already. for _, c := range chks { - aggrChunks = append(aggrChunks, c.Chunk.(*AggrChunk)) + ac, ok := c.Chunk.(*AggrChunk) + if !ok { + return id, errors.Errorf("expected downsampled chunk (*downsample.AggrChunk) got %T instead for series: %d", c.Chunk, postings.At()) + } + aggrChunks = append(aggrChunks, ac) } downsampledChunks, err := downsampleAggr( aggrChunks, @@ -334,12 +348,12 @@ func downsampleRawLoop(data []sample, resolution int64, numChunks int) []chunks. ab := newAggrChunkBuilder() - // Encode first raw value; see CounterSeriesIterator. + // Encode first raw value; see ApplyCounterResetsSeriesIterator. ab.apps[AggrCounter].Append(batch[0].t, batch[0].v) lastT := downsampleBatch(batch, resolution, ab.add) - // Encode last raw value; see CounterSeriesIterator. + // Encode last raw value; see ApplyCounterResetsSeriesIterator. ab.apps[AggrCounter].Append(lastT, batch[len(batch)-1].v) chks = append(chks, ab.encode()) @@ -511,7 +525,7 @@ func downsampleAggrBatch(chks []*AggrChunk, buf *[]sample, resolution int64) (ch acs = append(acs, c.Iterator(reuseIt)) } *buf = (*buf)[:0] - it := NewCounterSeriesIterator(acs...) + it := NewApplyCounterResetsIterator(acs...) if err := expandChunkIterator(it, buf); err != nil { return chk, err @@ -524,7 +538,7 @@ func downsampleAggrBatch(chks []*AggrChunk, buf *[]sample, resolution int64) (ch ab.chunks[AggrCounter] = chunkenc.NewXORChunk() ab.apps[AggrCounter], _ = ab.chunks[AggrCounter].Appender() - // Retain first raw value; see CounterSeriesIterator. + // Retain first raw value; see ApplyCounterResetsSeriesIterator. ab.apps[AggrCounter].Append((*buf)[0].t, (*buf)[0].v) lastT := downsampleBatch(*buf, resolution, func(t int64, a *aggregator) { @@ -536,7 +550,7 @@ func downsampleAggrBatch(chks []*AggrChunk, buf *[]sample, resolution int64) (ch ab.apps[AggrCounter].Append(t, a.counter) }) - // Retain last raw value; see CounterSeriesIterator. + // Retain last raw value; see ApplyCounterResetsSeriesIterator. ab.apps[AggrCounter].Append(lastT, it.lastV) ab.mint = mint @@ -549,19 +563,24 @@ type sample struct { v float64 } -// CounterSeriesIterator generates monotonically increasing values by iterating +// ApplyCounterResetsSeriesIterator generates monotonically increasing values by iterating // over an ordered sequence of chunks, which should be raw or aggregated chunks -// of counter values. The generated samples can be used by PromQL functions -// like 'rate' that calculate differences between counter values. +// of counter values. The generated samples can be used by PromQL functions +// like 'rate' that calculate differences between counter values. Stale Markers +// are removed as well. // // Counter aggregation chunks must have the first and last values from their // original raw series: the first raw value should be the first value encoded // in the chunk, and the last raw value is encoded by the duplication of the -// previous sample's timestamp. As iteration occurs between chunks, the +// previous sample's timestamp. As iteration occurs between chunks, the // comparison between the last raw value of the earlier chunk and the first raw // value of the later chunk ensures that counter resets between chunks are // recognized and that the correct value delta is calculated. -type CounterSeriesIterator struct { +// +// It handles overlapped chunks (removes overlaps). +// NOTE: It is important to deduplicate with care ensuring that you don't hit +// issue https://github.com/thanos-io/thanos/issues/2401#issuecomment-621958839. +type ApplyCounterResetsSeriesIterator struct { chks []chunkenc.Iterator i int // Current chunk. total int // Total number of processed samples. @@ -570,11 +589,11 @@ type CounterSeriesIterator struct { totalV float64 // Total counter state since beginning of series. } -func NewCounterSeriesIterator(chks ...chunkenc.Iterator) *CounterSeriesIterator { - return &CounterSeriesIterator{chks: chks} +func NewApplyCounterResetsIterator(chks ...chunkenc.Iterator) *ApplyCounterResetsSeriesIterator { + return &ApplyCounterResetsSeriesIterator{chks: chks} } -func (it *CounterSeriesIterator) Next() bool { +func (it *ApplyCounterResetsSeriesIterator) Next() bool { for { if it.i >= len(it.chks) { return false @@ -618,11 +637,12 @@ func (it *CounterSeriesIterator) Next() bool { } } -func (it *CounterSeriesIterator) At() (t int64, v float64) { +func (it *ApplyCounterResetsSeriesIterator) At() (t int64, v float64) { return it.lastT, it.totalV } -func (it *CounterSeriesIterator) Seek(x int64) bool { +func (it *ApplyCounterResetsSeriesIterator) Seek(x int64) bool { + // Don't use underlying Seek, but iterate over next to not miss counter resets. for { if t, _ := it.At(); t >= x { return true @@ -635,7 +655,7 @@ func (it *CounterSeriesIterator) Seek(x int64) bool { } } -func (it *CounterSeriesIterator) Err() error { +func (it *ApplyCounterResetsSeriesIterator) Err() error { if it.i >= len(it.chks) { return nil } diff --git a/pkg/compact/downsample/downsample_test.go b/pkg/compact/downsample/downsample_test.go index 34666de66c..47fe161a9a 100644 --- a/pkg/compact/downsample/downsample_test.go +++ b/pkg/compact/downsample/downsample_test.go @@ -60,7 +60,7 @@ func TestDownsampleCounterBoundaryReset(t *testing.T) { iters = append(iters, chk.Iterator(nil)) } - citer := NewCounterSeriesIterator(iters...) + citer := NewApplyCounterResetsIterator(iters...) for citer.Next() { t, v := citer.At() res = append(res, sample{t: t, v: v}) @@ -162,185 +162,391 @@ func TestExpandChunkIterator(t *testing.T) { testutil.Equals(t, []sample{{100, 1}, {200, 2}, {200, 3}, {201, 4}, {300, 6}, {500, 5}}, res) } -func TestDownsampleRaw(t *testing.T) { +var ( + // Decoded excerpt of pkg/query/testdata/issue2401-seriesresponses.json without overlaps (downsampling works directly on blocks). + realisticChkDataWithStaleMarker = [][]sample{ + { + {t: 1587690005791, v: 461968}, {t: 1587690020791, v: 462151}, {t: 1587690035797, v: 462336}, {t: 1587690050791, v: 462650}, {t: 1587690065791, v: 462813}, {t: 1587690080791, v: 462987}, {t: 1587690095791, v: 463095}, {t: 1587690110791, v: 463247}, {t: 1587690125791, v: 463440}, {t: 1587690140791, v: 463642}, + {t: 1587690155791, v: 463811}, {t: 1587690170791, v: 464027}, {t: 1587690185791, v: 464308}, {t: 1587690200791, v: 464514}, {t: 1587690215791, v: 464798}, {t: 1587690230791, v: 465018}, {t: 1587690245791, v: 465215}, {t: 1587690260813, v: 465431}, {t: 1587690275791, v: 465651}, {t: 1587690290791, v: 465870}, + {t: 1587690305791, v: 466070}, {t: 1587690320792, v: 466248}, {t: 1587690335791, v: 466506}, {t: 1587690350791, v: 466766}, {t: 1587690365791, v: 466970}, {t: 1587690380791, v: 467123}, {t: 1587690395791, v: 467265}, {t: 1587690410791, v: 467383}, {t: 1587690425791, v: 467629}, {t: 1587690440791, v: 467931}, + {t: 1587690455791, v: 468097}, {t: 1587690470791, v: 468281}, {t: 1587690485791, v: 468477}, {t: 1587690500791, v: 468649}, {t: 1587690515791, v: 468867}, {t: 1587690530791, v: 469150}, {t: 1587690545791, v: 469268}, {t: 1587690560791, v: 469488}, {t: 1587690575791, v: 469742}, {t: 1587690590791, v: 469951}, + {t: 1587690605791, v: 470131}, {t: 1587690620791, v: 470337}, {t: 1587690635791, v: 470631}, {t: 1587690650791, v: 470832}, {t: 1587690665791, v: 471077}, {t: 1587690680791, v: 471311}, {t: 1587690695791, v: 471473}, {t: 1587690710791, v: 471728}, {t: 1587690725791, v: 472002}, {t: 1587690740791, v: 472158}, + {t: 1587690755791, v: 472329}, {t: 1587690770791, v: 472722}, {t: 1587690785791, v: 472925}, {t: 1587690800791, v: 473220}, {t: 1587690815791, v: 473460}, {t: 1587690830791, v: 473748}, {t: 1587690845791, v: 473968}, {t: 1587690860791, v: 474261}, {t: 1587690875791, v: 474418}, {t: 1587690890791, v: 474726}, + {t: 1587690905791, v: 474913}, {t: 1587690920791, v: 475031}, {t: 1587690935791, v: 475284}, {t: 1587690950791, v: 475563}, {t: 1587690965791, v: 475762}, {t: 1587690980791, v: 475945}, {t: 1587690995791, v: 476302}, {t: 1587691010791, v: 476501}, {t: 1587691025791, v: 476849}, {t: 1587691040800, v: 477020}, + {t: 1587691055791, v: 477280}, {t: 1587691070791, v: 477549}, {t: 1587691085791, v: 477758}, {t: 1587691100817, v: 477960}, {t: 1587691115791, v: 478261}, {t: 1587691130791, v: 478559}, {t: 1587691145791, v: 478704}, {t: 1587691160804, v: 478950}, {t: 1587691175791, v: 479173}, {t: 1587691190791, v: 479368}, + {t: 1587691205791, v: 479625}, {t: 1587691220805, v: 479866}, {t: 1587691235791, v: 480008}, {t: 1587691250791, v: 480155}, {t: 1587691265791, v: 480472}, {t: 1587691280811, v: 480598}, {t: 1587691295791, v: 480771}, {t: 1587691310791, v: 480996}, {t: 1587691325791, v: 481200}, {t: 1587691340803, v: 481381}, + {t: 1587691355791, v: 481584}, {t: 1587691370791, v: 481759}, {t: 1587691385791, v: 482003}, {t: 1587691400803, v: 482189}, {t: 1587691415791, v: 482457}, {t: 1587691430791, v: 482623}, {t: 1587691445791, v: 482768}, {t: 1587691460804, v: 483036}, {t: 1587691475791, v: 483322}, {t: 1587691490791, v: 483566}, + {t: 1587691505791, v: 483709}, {t: 1587691520807, v: 483838}, {t: 1587691535791, v: 484091}, {t: 1587691550791, v: 484236}, {t: 1587691565791, v: 484454}, {t: 1587691580816, v: 484710}, {t: 1587691595791, v: 484978}, {t: 1587691610791, v: 485271}, {t: 1587691625791, v: 485476}, {t: 1587691640792, v: 485640}, + {t: 1587691655791, v: 485921}, {t: 1587691670791, v: 486201}, {t: 1587691685791, v: 486555}, {t: 1587691700791, v: 486691}, {t: 1587691715791, v: 486831}, {t: 1587691730791, v: 487033}, {t: 1587691745791, v: 487268}, {t: 1587691760803, v: 487370}, {t: 1587691775791, v: 487571}, {t: 1587691790791, v: 487787}, + }, + { + {t: 1587691805791, v: 488036}, {t: 1587691820791, v: 488241}, {t: 1587691835791, v: 488411}, {t: 1587691850791, v: 488625}, {t: 1587691865791, v: 488868}, {t: 1587691880791, v: 489005}, {t: 1587691895791, v: 489237}, {t: 1587691910791, v: 489545}, {t: 1587691925791, v: 489750}, {t: 1587691940791, v: 489899}, + {t: 1587691955791, v: 490048}, {t: 1587691970791, v: 490364}, {t: 1587691985791, v: 490485}, {t: 1587692000791, v: 490722}, {t: 1587692015791, v: 490866}, {t: 1587692030791, v: 491025}, {t: 1587692045791, v: 491286}, {t: 1587692060816, v: 491543}, {t: 1587692075791, v: 491787}, {t: 1587692090791, v: 492065}, + {t: 1587692105791, v: 492223}, {t: 1587692120816, v: 492501}, {t: 1587692135791, v: 492767}, {t: 1587692150791, v: 492955}, {t: 1587692165791, v: 493194}, {t: 1587692180792, v: 493402}, {t: 1587692195791, v: 493647}, {t: 1587692210791, v: 493897}, {t: 1587692225791, v: 494117}, {t: 1587692240805, v: 494356}, + {t: 1587692255791, v: 494620}, {t: 1587692270791, v: 494762}, {t: 1587692285791, v: 495001}, {t: 1587692300805, v: 495222}, {t: 1587692315791, v: 495393}, {t: 1587692330791, v: 495662}, {t: 1587692345791, v: 495875}, {t: 1587692360801, v: 496082}, {t: 1587692375791, v: 496196}, {t: 1587692390791, v: 496245}, + {t: 1587692405791, v: 496295}, {t: 1587692420791, v: 496365}, {t: 1587692435791, v: 496401}, {t: 1587692450791, v: 496452}, {t: 1587692465791, v: 496491}, {t: 1587692480791, v: 496544}, {t: 1587692495791, v: math.Float64frombits(value.StaleNaN)}, {t: 1587692555791, v: 75}, {t: 1587692570791, v: 308}, {t: 1587692585791, v: 508}, + {t: 1587692600791, v: 701}, {t: 1587692615791, v: 985}, {t: 1587692630791, v: 1153}, {t: 1587692645791, v: 1365}, {t: 1587692660791, v: 1612}, {t: 1587692675803, v: 1922}, {t: 1587692690791, v: 2103}, {t: 1587692705791, v: 2261}, {t: 1587692720791, v: 2469}, {t: 1587692735805, v: 2625}, + {t: 1587692750791, v: 2801}, {t: 1587692765791, v: 2955}, {t: 1587692780791, v: 3187}, {t: 1587692795806, v: 3428}, {t: 1587692810791, v: 3657}, {t: 1587692825791, v: 3810}, {t: 1587692840791, v: 3968}, {t: 1587692855791, v: 4195}, {t: 1587692870791, v: 4414}, {t: 1587692885791, v: 4646}, + {t: 1587692900791, v: 4689}, {t: 1587692915791, v: 4847}, {t: 1587692930791, v: 5105}, {t: 1587692945791, v: 5309}, {t: 1587692960791, v: 5521}, {t: 1587692975791, v: 5695}, {t: 1587692990810, v: 6010}, {t: 1587693005791, v: 6210}, {t: 1587693020791, v: 6394}, {t: 1587693035791, v: 6597}, + {t: 1587693050791, v: 6872}, {t: 1587693065791, v: 7098}, {t: 1587693080791, v: 7329}, {t: 1587693095791, v: 7470}, {t: 1587693110791, v: 7634}, {t: 1587693125821, v: 7830}, {t: 1587693140791, v: 8034}, {t: 1587693155791, v: 8209}, {t: 1587693170791, v: 8499}, {t: 1587693185791, v: 8688}, + {t: 1587693200791, v: 8893}, {t: 1587693215791, v: 9052}, {t: 1587693230791, v: 9379}, {t: 1587693245791, v: 9544}, {t: 1587693260791, v: 9763}, {t: 1587693275791, v: 9974}, {t: 1587693290791, v: 10242}, {t: 1587693305791, v: 10464}, {t: 1587693320803, v: 10716}, {t: 1587693335791, v: 10975}, + {t: 1587693350791, v: 11232}, {t: 1587693365791, v: 11459}, {t: 1587693380791, v: 11778}, {t: 1587693395804, v: 12007}, {t: 1587693410791, v: 12206}, {t: 1587693425791, v: 12450}, {t: 1587693440791, v: 12693}, {t: 1587693455791, v: 12908}, {t: 1587693470791, v: 13158}, {t: 1587693485791, v: 13427}, + {t: 1587693500791, v: 13603}, {t: 1587693515791, v: 13927}, {t: 1587693530816, v: 14122}, {t: 1587693545791, v: 14327}, {t: 1587693560791, v: 14579}, {t: 1587693575791, v: 14759}, {t: 1587693590791, v: 14956}, + }, + } + realisticChkDataWithCounterResetRes5m = []map[AggrType][]sample{ + { + AggrCount: {{t: 1587690299999, v: 20}, {t: 1587690599999, v: 20}, {t: 1587690899999, v: 20}, {t: 1587691199999, v: 20}, {t: 1587691499999, v: 20}, {t: 1587691799999, v: 20}, {t: 1587692099999, v: 20}, {t: 1587692399999, v: 20}, {t: 1587692699999, v: 16}, {t: 1587692999999, v: 20}, {t: 1587693299999, v: 20}, {t: 1587693590791, v: 20}}, + AggrSum: {{t: 1587690299999, v: 9.276972e+06}, {t: 1587690599999, v: 9.359861e+06}, {t: 1587690899999, v: 9.447457e+06}, {t: 1587691199999, v: 9.542732e+06}, {t: 1587691499999, v: 9.630379e+06}, {t: 1587691799999, v: 9.715631e+06}, {t: 1587692099999, v: 9.799808e+06}, {t: 1587692399999, v: 9.888117e+06}, {t: 1587692699999, v: 2.98928e+06}, {t: 1587692999999, v: 81592}, {t: 1587693299999, v: 163711}, {t: 1587693590791, v: 255746}}, + AggrMin: {{t: 1587690299999, v: 461968}, {t: 1587690599999, v: 466070}, {t: 1587690899999, v: 470131}, {t: 1587691199999, v: 474913}, {t: 1587691499999, v: 479625}, {t: 1587691799999, v: 483709}, {t: 1587692099999, v: 488036}, {t: 1587692399999, v: 492223}, {t: 1587692699999, v: 75}, {t: 1587692999999, v: 2261}, {t: 1587693299999, v: 6210}, {t: 1587693590791, v: 10464}}, + AggrMax: {{t: 1587690299999, v: 465870}, {t: 1587690599999, v: 469951}, {t: 1587690899999, v: 474726}, {t: 1587691199999, v: 479368}, {t: 1587691499999, v: 483566}, {t: 1587691799999, v: 487787}, {t: 1587692099999, v: 492065}, {t: 1587692399999, v: 496245}, {t: 1587692699999, v: 496544}, {t: 1587692999999, v: 6010}, {t: 1587693299999, v: 10242}, {t: 1587693590791, v: 14956}}, + AggrCounter: {{t: 1587690005791, v: 461968}, {t: 1587690299999, v: 465870}, {t: 1587690599999, v: 469951}, {t: 1587690899999, v: 474726}, {t: 1587691199999, v: 479368}, {t: 1587691499999, v: 483566}, {t: 1587691799999, v: 487787}, {t: 1587692099999, v: 492065}, {t: 1587692399999, v: 496245}, {t: 1587692699999, v: 498647}, {t: 1587692999999, v: 502554}, {t: 1587693299999, v: 506786}, {t: 1587693590791, v: 511500}, {t: 1587693590791, v: 14956}}, + }, + } +) + +func TestDownsample(t *testing.T) { defer leaktest.CheckTimeout(t, 10*time.Second)() - staleMarker := math.Float64frombits(value.StaleNaN) + type downsampleTestCase struct { + name string - input := []*downsampleTestSet{ + // Either inRaw or inAggr should be provided. + inRaw [][]sample + inAggr []map[AggrType][]sample + resolution int64 + + // Expected output. + expected []map[AggrType][]sample + expectedDownsamplingErr func([]chunks.Meta) error + } + for _, tcase := range []*downsampleTestCase{ { - lset: labels.FromStrings("__name__", "a"), - inRaw: []sample{ - {20, 1}, {40, 2}, {60, 3}, {80, 1}, {100, 2}, {101, staleMarker}, {120, 5}, {180, 10}, {250, 1}, + name: "single chunk", + inRaw: [][]sample{ + {{20, 1}, {40, 2}, {60, 3}, {80, 1}, {100, 2}, {101, math.Float64frombits(value.StaleNaN)}, {120, 5}, {180, 10}, {250, 1}}, }, - output: map[AggrType][]sample{ - AggrCount: {{99, 4}, {199, 3}, {250, 1}}, - AggrSum: {{99, 7}, {199, 17}, {250, 1}}, - AggrMin: {{99, 1}, {199, 2}, {250, 1}}, - AggrMax: {{99, 3}, {199, 10}, {250, 1}}, - AggrCounter: {{20, 1}, {99, 4}, {199, 13}, {250, 14}, {250, 1}}, + resolution: 100, + + expected: []map[AggrType][]sample{ + { + AggrCount: {{99, 4}, {199, 3}, {250, 1}}, + AggrSum: {{99, 7}, {199, 17}, {250, 1}}, + AggrMin: {{99, 1}, {199, 2}, {250, 1}}, + AggrMax: {{99, 3}, {199, 10}, {250, 1}}, + AggrCounter: {{20, 1}, {99, 4}, {199, 13}, {250, 14}, {250, 1}}, + }, }, }, - } - testDownsample(t, input, &metadata.Meta{BlockMeta: tsdb.BlockMeta{MinTime: 0, MaxTime: 250}}, 100) -} + { + name: "three chunks", + inRaw: [][]sample{ + {{20, 1}, {40, 2}, {60, 3}, {80, 1}, {100, 2}, {101, math.Float64frombits(value.StaleNaN)}, {120, 5}, {180, 10}, {250, 2}}, + {{260, 1}, {300, 10}, {340, 15}, {380, 25}, {420, 35}}, + {{460, math.Float64frombits(value.StaleNaN)}, {500, 10}, {540, 3}}, + }, + resolution: 100, + + expected: []map[AggrType][]sample{ + { + AggrCount: {{t: 99, v: 4}, {t: 199, v: 3}, {t: 299, v: 2}, {t: 399, v: 3}, {t: 499, v: 1}, {t: 540, v: 2}}, + AggrSum: {{t: 99, v: 7}, {t: 199, v: 17}, {t: 299, v: 3}, {t: 399, v: 50}, {t: 499, v: 35}, {t: 540, v: 13}}, + AggrMin: {{t: 99, v: 1}, {t: 199, v: 2}, {t: 299, v: 1}, {t: 399, v: 10}, {t: 499, v: 35}, {t: 540, v: 3}}, + AggrMax: {{t: 99, v: 3}, {t: 199, v: 10}, {t: 299, v: 2}, {t: 399, v: 25}, {t: 499, v: 35}, {t: 540, v: 10}}, + AggrCounter: {{t: 20, v: 1}, {t: 99, v: 4}, {t: 199, v: 13}, {t: 299, v: 16}, {t: 399, v: 40}, {t: 499, v: 50}, {t: 540, v: 63}, {t: 540, v: 3}}, + }, + }, + }, + { + name: "four chunks, two of them overlapping", + inRaw: [][]sample{ + {{20, 1}, {40, 2}, {60, 3}, {80, 1}, {100, 2}, {101, math.Float64frombits(value.StaleNaN)}, {120, 5}, {180, 10}, {250, 2}}, + {{20, 1}, {40, 2}, {60, 3}, {80, 1}, {100, 2}, {101, math.Float64frombits(value.StaleNaN)}, {120, 5}, {180, 10}, {250, 2}}, + {{260, 1}, {300, 10}, {340, 15}, {380, 25}, {420, 35}}, + {{460, math.Float64frombits(value.StaleNaN)}, {500, 10}, {540, 3}}, + }, + resolution: 100, -func TestDownsampleAggr(t *testing.T) { - defer leaktest.CheckTimeout(t, 10*time.Second)() + expectedDownsamplingErr: func(chks []chunks.Meta) error { + return errors.Errorf("found overlapping chunks within series 0. Chunks expected to be ordered by min time and non-overlapping, got: %v", chks) + }, + }, + { + name: "realistic 15s interval raw chunks", + inRaw: realisticChkDataWithStaleMarker, + resolution: ResLevel1, // 5m. - input := []*downsampleTestSet{ + expected: realisticChkDataWithCounterResetRes5m, + }, + // Aggregated -> Downsampled Aggregated. { - lset: labels.FromStrings("__name__", "a"), - inAggr: map[AggrType][]sample{ - AggrCount: { - {199, 5}, {299, 1}, {399, 10}, {400, 3}, {499, 10}, {699, 0}, {999, 100}, + name: "single aggregated chunks", + inAggr: []map[AggrType][]sample{ + { + AggrCount: {{199, 5}, {299, 1}, {399, 10}, {400, 3}, {499, 10}, {699, 0}, {999, 100}}, + AggrSum: {{199, 5}, {299, 1}, {399, 10}, {400, 3}, {499, 10}, {699, 0}, {999, 100}}, + AggrMin: {{199, 5}, {299, 1}, {399, 10}, {400, -3}, {499, 10}, {699, 0}, {999, 100}}, + AggrMax: {{199, 5}, {299, 1}, {399, 10}, {400, -3}, {499, 10}, {699, 0}, {999, 100}}, + AggrCounter: { + {99, 100}, {299, 150}, {499, 210}, {499, 10}, // Chunk 1. + {599, 20}, {799, 50}, {999, 120}, {999, 50}, // Chunk 2, no reset. + {1099, 40}, {1199, 80}, {1299, 110}, // Chunk 3, reset. + }, }, - AggrSum: { - {199, 5}, {299, 1}, {399, 10}, {400, 3}, {499, 10}, {699, 0}, {999, 100}, + }, + resolution: 500, + + expected: []map[AggrType][]sample{ + { + AggrCount: {{499, 29}, {999, 100}}, + AggrSum: {{499, 29}, {999, 100}}, + AggrMin: {{499, -3}, {999, 0}}, + AggrMax: {{499, 10}, {999, 100}}, + AggrCounter: {{99, 100}, {499, 210}, {999, 320}, {1299, 430}, {1299, 110}}, }, - AggrMin: { - {199, 5}, {299, 1}, {399, 10}, {400, -3}, {499, 10}, {699, 0}, {999, 100}, + }, + }, + func() *downsampleTestCase { + downsample500resolutionChunk := []map[AggrType][]sample{ + { + AggrCount: {{499, 29}, {999, 100}}, + AggrSum: {{499, 29}, {999, 100}}, + AggrMin: {{499, -3}, {999, 0}}, + AggrMax: {{499, 10}, {999, 100}}, + AggrCounter: {{99, 100}, {499, 210}, {999, 320}, {1299, 430}, {1299, 110}}, }, - AggrMax: { - {199, 5}, {299, 1}, {399, 10}, {400, -3}, {499, 10}, {699, 0}, {999, 100}, + } + return &downsampleTestCase{ + name: "downsampling already downsampled to the same resolution aggregated chunks", + resolution: 500, + + // Should be the output as input. + inAggr: downsample500resolutionChunk, + expected: downsample500resolutionChunk, + } + }(), + { + name: "two aggregated chunks", + inAggr: []map[AggrType][]sample{ + { + AggrCount: {{199, 5}, {299, 1}, {399, 10}, {400, 3}, {499, 10}, {699, 0}, {999, 100}}, + AggrSum: {{199, 5}, {299, 1}, {399, 10}, {400, 3}, {499, 10}, {699, 0}, {999, 100}}, + AggrMin: {{199, 5}, {299, 1}, {399, 10}, {400, -3}, {499, 10}, {699, 0}, {999, 100}}, + AggrMax: {{199, 5}, {299, 1}, {399, 10}, {400, -3}, {499, 10}, {699, 0}, {999, 100}}, + AggrCounter: { + {99, 100}, {299, 150}, {499, 210}, {499, 10}, // Chunk 1. + {599, 20}, {799, 50}, {999, 120}, {999, 50}, // Chunk 2, no reset. + {1099, 40}, {1199, 80}, {1299, 110}, // Chunk 3, reset. + }, }, - AggrCounter: { - {99, 100}, {299, 150}, {499, 210}, {499, 10}, // Chunk 1. - {599, 20}, {799, 50}, {999, 120}, {999, 50}, // Chunk 2, no reset. - {1099, 40}, {1199, 80}, {1299, 110}, // Chunk 3, reset. + { + AggrCount: {{1399, 10}, {1400, 3}, {1499, 10}, {1699, 0}, {1999, 100}}, + AggrSum: {{1399, 10}, {1400, 3}, {1499, 10}, {1699, 0}, {1999, 100}}, + AggrMin: {{1399, 10}, {1400, -3}, {1499, 10}, {1699, 0}, {1999, 100}}, + AggrMax: {{1399, 10}, {1400, -3}, {1499, 10}, {1699, 0}, {1999, 100}}, + AggrCounter: { + {1499, 210}, {1499, 10}, // Chunk 1. + {1599, 20}, {1799, 50}, {1999, 120}, {1999, 50}, // Chunk 2, no reset. + {2099, 40}, {2199, 80}, {2299, 110}, // Chunk 3, reset. + }, }, }, - output: map[AggrType][]sample{ - AggrCount: {{499, 29}, {999, 100}}, - AggrSum: {{499, 29}, {999, 100}}, - AggrMin: {{499, -3}, {999, 0}}, - AggrMax: {{499, 10}, {999, 100}}, - AggrCounter: {{99, 100}, {499, 210}, {999, 320}, {1299, 430}, {1299, 110}}, + resolution: 500, + + expected: []map[AggrType][]sample{ + { + AggrCount: {{t: 499, v: 29}, {t: 999, v: 100}, {t: 1499, v: 23}, {t: 1999, v: 100}}, + AggrSum: {{t: 499, v: 29}, {t: 999, v: 100}, {t: 1499, v: 23}, {t: 1999, v: 100}}, + AggrMin: {{t: 499, v: -3}, {t: 999, v: 0}, {t: 1499, v: -3}, {t: 1999, v: 0}}, + AggrMax: {{t: 499, v: 10}, {t: 999, v: 100}, {t: 1499, v: 10}, {t: 1999, v: 100}}, + AggrCounter: {{t: 99, v: 100}, {t: 499, v: 210}, {t: 999, v: 320}, {t: 1499, v: 530}, {t: 1999, v: 640}, {t: 2299, v: 750}, {t: 2299, v: 110}}, + }, }, }, - } - var meta metadata.Meta - meta.Thanos.Downsample.Resolution = 10 - meta.BlockMeta = tsdb.BlockMeta{MinTime: 99, MaxTime: 1300} - - testDownsample(t, input, &meta, 500) -} - -func encodeTestAggrSeries(v map[AggrType][]sample) chunks.Meta { - b := newAggrChunkBuilder() - - for at, d := range v { - for _, s := range d { - b.apps[at].Append(s.t, s.v) - } - } - - return b.encode() -} + { + name: "two aggregated, overlapping chunks", + inAggr: []map[AggrType][]sample{ + { + AggrCount: {{199, 5}, {299, 1}, {399, 10}, {400, 3}, {499, 10}, {699, 0}, {999, 100}}, + }, + { + AggrCount: {{199, 5}, {299, 1}, {399, 10}, {400, 3}, {499, 10}, {699, 0}, {999, 100}}, + }, + }, + resolution: 500, -type downsampleTestSet struct { - lset labels.Labels - inRaw []sample - inAggr map[AggrType][]sample - output map[AggrType][]sample -} + expectedDownsamplingErr: func(chks []chunks.Meta) error { + return errors.Errorf("found overlapping chunks within series 0. Chunks expected to be ordered by min time and non-overlapping, got: %v", chks) + }, + }, + { + name: "realistic ResLevel1 (5m) downsampled chunks with from counter resets", + inAggr: []map[AggrType][]sample{ + { + AggrCount: {{t: 1587690299999, v: 20}, {t: 1587690599999, v: 20}, {t: 1587690899999, v: 20}, {t: 1587691199999, v: 20}, {t: 1587691499999, v: 20}, {t: 1587691799999, v: 20}, {t: 1587692099999, v: 20}, {t: 1587692399999, v: 20}, {t: 1587692699999, v: 16}, {t: 1587692999999, v: 20}, {t: 1587693299999, v: 20}, {t: 1587693590791, v: 20}}, + AggrSum: {{t: 1587690299999, v: 9.276972e+06}, {t: 1587690599999, v: 9.359861e+06}, {t: 1587690899999, v: 9.447457e+06}, {t: 1587691199999, v: 9.542732e+06}, {t: 1587691499999, v: 9.630379e+06}, {t: 1587691799999, v: 9.715631e+06}, {t: 1587692099999, v: 9.799808e+06}, {t: 1587692399999, v: 9.888117e+06}, {t: 1587692699999, v: 2.98928e+06}, {t: 1587692999999, v: 81592}, {t: 1587693299999, v: 163711}, {t: 1587693590791, v: 255746}}, + AggrMin: {{t: 1587690299999, v: 461968}, {t: 1587690599999, v: 466070}, {t: 1587690899999, v: 470131}, {t: 1587691199999, v: 474913}, {t: 1587691499999, v: 479625}, {t: 1587691799999, v: 483709}, {t: 1587692099999, v: 488036}, {t: 1587692399999, v: 492223}, {t: 1587692699999, v: 75}, {t: 1587692999999, v: 2261}, {t: 1587693299999, v: 6210}, {t: 1587693590791, v: 10464}}, + AggrMax: {{t: 1587690299999, v: 465870}, {t: 1587690599999, v: 469951}, {t: 1587690899999, v: 474726}, {t: 1587691199999, v: 479368}, {t: 1587691499999, v: 483566}, {t: 1587691799999, v: 487787}, {t: 1587692099999, v: 492065}, {t: 1587692399999, v: 496245}, {t: 1587692699999, v: 496544}, {t: 1587692999999, v: 6010}, {t: 1587693299999, v: 10242}, {t: 1587693590791, v: 14956}}, + AggrCounter: {{t: 1587690005791, v: 461968}, {t: 1587690299999, v: 465870}, {t: 1587690599999, v: 469951}, {t: 1587690899999, v: 474726}, {t: 1587691199999, v: 479368}, {t: 1587691499999, v: 483566}, {t: 1587691799999, v: 487787}, {t: 1587692099999, v: 492065}, {t: 1587692399999, v: 496245}, {t: 1587692699999, v: 498647}, {t: 1587692999999, v: 502554}, {t: 1587693299999, v: 506786}, {t: 1587693590791, v: 511500}, {t: 1587693590791, v: 14956}}, + }, + }, + resolution: ResLevel2, + + expected: []map[AggrType][]sample{ + { + AggrCount: {{t: 1587693590791, v: 236}}, + AggrSum: {{t: 1587693590791, v: 8.0151286e+07}}, + AggrMin: {{t: 1587693590791, v: 75}}, + AggrMax: {{t: 1587693590791, v: 496544}}, + AggrCounter: {{t: 1587690005791, v: 461968}, {t: 1587693590791, v: 511500}, {t: 1587693590791, v: 14956}}, + }, + }, + }, + // TODO(bwplotka): This is not very efficient for further query time, we should produce 2 chunks. Fix it https://github.com/thanos-io/thanos/issues/2542. + func() *downsampleTestCase { + d := &downsampleTestCase{ + name: "downsampling four, 120 sample chunks for 2x resolution should result in two chunks, but results in one.", + resolution: 2, + inAggr: []map[AggrType][]sample{{AggrCounter: {}}, {AggrCounter: {}}, {AggrCounter: {}}, {AggrCounter: {}}}, + expected: []map[AggrType][]sample{{AggrCounter: {}}}, + } -// testDownsample inserts the input into a block and invokes the downsampler with the given resolution. -// The chunk ranges within the input block are aligned at 500 time units. -func testDownsample(t *testing.T, data []*downsampleTestSet, meta *metadata.Meta, resolution int64) { - t.Helper() + for i := int64(0); i < 120; i++ { + d.inAggr[0][AggrCounter] = append(d.inAggr[0][AggrCounter], sample{t: i, v: float64(i)}) + d.inAggr[1][AggrCounter] = append(d.inAggr[1][AggrCounter], sample{t: 120 + i, v: float64(120 + i)}) + d.inAggr[2][AggrCounter] = append(d.inAggr[2][AggrCounter], sample{t: 240 + i, v: float64(240 + i)}) + d.inAggr[3][AggrCounter] = append(d.inAggr[3][AggrCounter], sample{t: 360 + i, v: float64(360 + i)}) + } - dir, err := ioutil.TempDir("", "downsample-raw") - testutil.Ok(t, err) - defer func() { testutil.Ok(t, os.RemoveAll(dir)) }() + d.expected[0][AggrCounter] = append(d.expected[0][AggrCounter], sample{t: 0, v: float64(0)}) + for i := int64(0); i < 480; i += 2 { + d.expected[0][AggrCounter] = append(d.expected[0][AggrCounter], sample{t: 1 + i, v: float64(1 + i)}) + } + d.expected[0][AggrCounter] = append(d.expected[0][AggrCounter], sample{t: 479, v: 479}) - // Ideally we would use tsdb.HeadBlock here for less dependency on our own code. However, - // it cannot accept the counter signal sample with the same timestamp as the previous sample. - mb := newMemBlock() + return d + }(), + } { + t.Run(tcase.name, func(t *testing.T) { + logger := log.NewLogfmtLogger(os.Stderr) - for _, d := range data { - if len(d.inRaw) > 0 && len(d.inAggr) > 0 { - t.Fatalf("test must not have raw and aggregate input data at once") - } - ser := &series{lset: d.lset} + dir, err := ioutil.TempDir("", "downsample-raw") + testutil.Ok(t, err) + defer func() { testutil.Ok(t, os.RemoveAll(dir)) }() - if len(d.inRaw) > 0 { - chk := chunkenc.NewXORChunk() - app, _ := chk.Appender() + // Ideally we would use tsdb.HeadBlock here for less dependency on our own code. However, + // it cannot accept the counter signal sample with the same timestamp as the previous sample. + mb := newMemBlock() + ser := chunksToSeriesIteratable(t, tcase.inRaw, tcase.inAggr) + mb.addSeries(ser) - for _, s := range d.inRaw { - app.Append(s.t, s.v) + fakeMeta := &metadata.Meta{} + if len(tcase.inAggr) > 0 { + fakeMeta.Thanos.Downsample.Resolution = tcase.resolution - 1 } - ser.chunks = append(ser.chunks, chunks.Meta{ - MinTime: d.inRaw[0].t, - MaxTime: d.inRaw[len(d.inRaw)-1].t, - Chunk: chk, - }) - } else { - ser.chunks = append(ser.chunks, encodeTestAggrSeries(d.inAggr)) - } - mb.addSeries(ser) - } - id, err := Downsample(log.NewNopLogger(), meta, mb, dir, resolution) - testutil.Ok(t, err) + id, err := Downsample(logger, fakeMeta, mb, dir, tcase.resolution) + if tcase.expectedDownsamplingErr != nil { + testutil.NotOk(t, err) + testutil.Equals(t, tcase.expectedDownsamplingErr(ser.chunks).Error(), err.Error()) + return + } + testutil.Ok(t, err) - _, err = metadata.Read(filepath.Join(dir, id.String())) - testutil.Ok(t, err) + _, err = metadata.Read(filepath.Join(dir, id.String())) + testutil.Ok(t, err) - exp := map[uint64]map[AggrType][]sample{} - got := map[uint64]map[AggrType][]sample{} + indexr, err := index.NewFileReader(filepath.Join(dir, id.String(), block.IndexFilename)) + testutil.Ok(t, err) + defer func() { testutil.Ok(t, indexr.Close()) }() - for _, d := range data { - exp[d.lset.Hash()] = d.output - } - indexr, err := index.NewFileReader(filepath.Join(dir, id.String(), block.IndexFilename)) - testutil.Ok(t, err) - defer func() { testutil.Ok(t, indexr.Close()) }() + chunkr, err := chunks.NewDirReader(filepath.Join(dir, id.String(), block.ChunksDirname), NewPool()) + testutil.Ok(t, err) + defer func() { testutil.Ok(t, chunkr.Close()) }() - chunkr, err := chunks.NewDirReader(filepath.Join(dir, id.String(), block.ChunksDirname), NewPool()) - testutil.Ok(t, err) - defer func() { testutil.Ok(t, chunkr.Close()) }() + pall, err := indexr.Postings(index.AllPostingsKey()) + testutil.Ok(t, err) - pall, err := indexr.Postings(index.AllPostingsKey()) - testutil.Ok(t, err) + var series []uint64 + for pall.Next() { + series = append(series, pall.At()) + } + testutil.Ok(t, pall.Err()) + testutil.Equals(t, 1, len(series)) - for pall.Next() { - id := pall.At() + var lset labels.Labels + var chks []chunks.Meta + testutil.Ok(t, indexr.Series(series[0], &lset, &chks)) + testutil.Equals(t, labels.FromStrings("__name__", "a"), lset) - var lset labels.Labels - var chks []chunks.Meta - testutil.Ok(t, indexr.Series(id, &lset, &chks)) + var got []map[AggrType][]sample + for _, c := range chks { + chk, err := chunkr.Chunk(c.Ref) + testutil.Ok(t, err) - m := map[AggrType][]sample{} - got[lset.Hash()] = m + m := map[AggrType][]sample{} + for _, at := range []AggrType{AggrCount, AggrSum, AggrMin, AggrMax, AggrCounter} { + c, err := chk.(*AggrChunk).Get(at) + if err == ErrAggrNotExist { + continue + } + testutil.Ok(t, err) + + buf := m[at] + testutil.Ok(t, expandChunkIterator(c.Iterator(nil), &buf)) + m[at] = buf + } + got = append(got, m) + } + testutil.Equals(t, tcase.expected, got) + }) + } +} - for _, c := range chks { - chk, err := chunkr.Chunk(c.Ref) - testutil.Ok(t, err) +func chunksToSeriesIteratable(t *testing.T, inRaw [][]sample, inAggr []map[AggrType][]sample) *series { + if len(inRaw) > 0 && len(inAggr) > 0 { + t.Fatalf("test must not have raw and aggregate input data at once") + } + ser := &series{lset: labels.FromStrings("__name__", "a")} - for _, at := range []AggrType{AggrCount, AggrSum, AggrMin, AggrMax, AggrCounter} { - c, err := chk.(*AggrChunk).Get(at) - if err == ErrAggrNotExist { - continue - } - testutil.Ok(t, err) + if len(inRaw) > 0 { + for _, samples := range inRaw { + chk := chunkenc.NewXORChunk() + app, _ := chk.Appender() - buf := m[at] - testutil.Ok(t, expandChunkIterator(c.Iterator(nil), &buf)) - m[at] = buf + for _, s := range samples { + app.Append(s.t, s.v) } + ser.chunks = append(ser.chunks, chunks.Meta{ + MinTime: samples[0].t, + MaxTime: samples[len(samples)-1].t, + Chunk: chk, + }) } + return ser } - testutil.Equals(t, len(exp), len(got)) - - for h, ser := range exp { - for _, at := range []AggrType{AggrCount, AggrSum, AggrMin, AggrMax, AggrCounter} { - t.Logf("series %d, type %s", h, at) - testutil.Equals(t, ser[at], got[h][at]) + for _, chk := range inAggr { + ser.chunks = append(ser.chunks, encodeTestAggrSeries(chk)) + } + return ser +} +func encodeTestAggrSeries(v map[AggrType][]sample) chunks.Meta { + b := newAggrChunkBuilder() + // we cannot use `b.add` as we have separate samples, do it manually, but make sure to + // calculate overall chunk time ranges. + for at, d := range v { + for _, s := range d { + if s.t < b.mint { + b.mint = s.t + } + if s.t > b.maxt { + b.maxt = s.t + } + b.apps[at].Append(s.t, s.v) } } + return b.encode() } func TestAverageChunkIterator(t *testing.T) { @@ -359,38 +565,115 @@ func TestAverageChunkIterator(t *testing.T) { testutil.Equals(t, exp, res) } -func TestCounterSeriesIterator(t *testing.T) { +var ( + realisticChkDataWithCounterResetsAfterCounterSeriesIterating = []sample{ + {t: 1587690005791, v: 461968}, {t: 1587690020791, v: 462151}, {t: 1587690035797, v: 462336}, {t: 1587690050791, v: 462650}, {t: 1587690065791, v: 462813}, {t: 1587690080791, v: 462987}, {t: 1587690095791, v: 463095}, {t: 1587690110791, v: 463247}, {t: 1587690125791, v: 463440}, {t: 1587690140791, v: 463642}, {t: 1587690155791, v: 463811}, + {t: 1587690170791, v: 464027}, {t: 1587690185791, v: 464308}, {t: 1587690200791, v: 464514}, {t: 1587690215791, v: 464798}, {t: 1587690230791, v: 465018}, {t: 1587690245791, v: 465215}, {t: 1587690260813, v: 465431}, {t: 1587690275791, v: 465651}, {t: 1587690290791, v: 465870}, {t: 1587690305791, v: 466070}, {t: 1587690320792, v: 466248}, + {t: 1587690335791, v: 466506}, {t: 1587690350791, v: 466766}, {t: 1587690365791, v: 466970}, {t: 1587690380791, v: 467123}, {t: 1587690395791, v: 467265}, {t: 1587690410791, v: 467383}, {t: 1587690425791, v: 467629}, {t: 1587690440791, v: 467931}, {t: 1587690455791, v: 468097}, {t: 1587690470791, v: 468281}, {t: 1587690485791, v: 468477}, + {t: 1587690500791, v: 468649}, {t: 1587690515791, v: 468867}, {t: 1587690530791, v: 469150}, {t: 1587690545791, v: 469268}, {t: 1587690560791, v: 469488}, {t: 1587690575791, v: 469742}, {t: 1587690590791, v: 469951}, {t: 1587690605791, v: 470131}, {t: 1587690620791, v: 470337}, {t: 1587690635791, v: 470631}, {t: 1587690650791, v: 470832}, + {t: 1587690665791, v: 471077}, {t: 1587690680791, v: 471311}, {t: 1587690695791, v: 471473}, {t: 1587690710791, v: 471728}, {t: 1587690725791, v: 472002}, {t: 1587690740791, v: 472158}, {t: 1587690755791, v: 472329}, {t: 1587690770791, v: 472722}, {t: 1587690785791, v: 472925}, {t: 1587690800791, v: 473220}, {t: 1587690815791, v: 473460}, + {t: 1587690830791, v: 473748}, {t: 1587690845791, v: 473968}, {t: 1587690860791, v: 474261}, {t: 1587690875791, v: 474418}, {t: 1587690890791, v: 474726}, {t: 1587690905791, v: 474913}, {t: 1587690920791, v: 475031}, {t: 1587690935791, v: 475284}, {t: 1587690950791, v: 475563}, {t: 1587690965791, v: 475762}, {t: 1587690980791, v: 475945}, + {t: 1587690995791, v: 476302}, {t: 1587691010791, v: 476501}, {t: 1587691025791, v: 476849}, {t: 1587691040800, v: 477020}, {t: 1587691055791, v: 477280}, {t: 1587691070791, v: 477549}, {t: 1587691085791, v: 477758}, {t: 1587691100817, v: 477960}, {t: 1587691115791, v: 478261}, {t: 1587691130791, v: 478559}, {t: 1587691145791, v: 478704}, + {t: 1587691160804, v: 478950}, {t: 1587691175791, v: 479173}, {t: 1587691190791, v: 479368}, {t: 1587691205791, v: 479625}, {t: 1587691220805, v: 479866}, {t: 1587691235791, v: 480008}, {t: 1587691250791, v: 480155}, {t: 1587691265791, v: 480472}, {t: 1587691280811, v: 480598}, {t: 1587691295791, v: 480771}, {t: 1587691310791, v: 480996}, + {t: 1587691325791, v: 481200}, {t: 1587691340803, v: 481381}, {t: 1587691355791, v: 481584}, {t: 1587691370791, v: 481759}, {t: 1587691385791, v: 482003}, {t: 1587691400803, v: 482189}, {t: 1587691415791, v: 482457}, {t: 1587691430791, v: 482623}, {t: 1587691445791, v: 482768}, {t: 1587691460804, v: 483036}, {t: 1587691475791, v: 483322}, + {t: 1587691490791, v: 483566}, {t: 1587691505791, v: 483709}, {t: 1587691520807, v: 483838}, {t: 1587691535791, v: 484091}, {t: 1587691550791, v: 484236}, {t: 1587691565791, v: 484454}, {t: 1587691580816, v: 484710}, {t: 1587691595791, v: 484978}, {t: 1587691610791, v: 485271}, {t: 1587691625791, v: 485476}, {t: 1587691640792, v: 485640}, + {t: 1587691655791, v: 485921}, {t: 1587691670791, v: 486201}, {t: 1587691685791, v: 486555}, {t: 1587691700791, v: 486691}, {t: 1587691715791, v: 486831}, {t: 1587691730791, v: 487033}, {t: 1587691745791, v: 487268}, {t: 1587691760803, v: 487370}, {t: 1587691775791, v: 487571}, {t: 1587691790791, v: 487787}, {t: 1587691805791, v: 488036}, + {t: 1587691820791, v: 488241}, {t: 1587691835791, v: 488411}, {t: 1587691850791, v: 488625}, {t: 1587691865791, v: 488868}, {t: 1587691880791, v: 489005}, {t: 1587691895791, v: 489237}, {t: 1587691910791, v: 489545}, {t: 1587691925791, v: 489750}, {t: 1587691940791, v: 489899}, {t: 1587691955791, v: 490048}, {t: 1587691970791, v: 490364}, + {t: 1587691985791, v: 490485}, {t: 1587692000791, v: 490722}, {t: 1587692015791, v: 490866}, {t: 1587692030791, v: 491025}, {t: 1587692045791, v: 491286}, {t: 1587692060816, v: 491543}, {t: 1587692075791, v: 491787}, {t: 1587692090791, v: 492065}, {t: 1587692105791, v: 492223}, {t: 1587692120816, v: 492501}, {t: 1587692135791, v: 492767}, + {t: 1587692150791, v: 492955}, {t: 1587692165791, v: 493194}, {t: 1587692180792, v: 493402}, {t: 1587692195791, v: 493647}, {t: 1587692210791, v: 493897}, {t: 1587692225791, v: 494117}, {t: 1587692240805, v: 494356}, {t: 1587692255791, v: 494620}, {t: 1587692270791, v: 494762}, {t: 1587692285791, v: 495001}, {t: 1587692300805, v: 495222}, + {t: 1587692315791, v: 495393}, {t: 1587692330791, v: 495662}, {t: 1587692345791, v: 495875}, {t: 1587692360801, v: 496082}, {t: 1587692375791, v: 496196}, {t: 1587692390791, v: 496245}, {t: 1587692405791, v: 496295}, {t: 1587692420791, v: 496365}, {t: 1587692435791, v: 496401}, {t: 1587692450791, v: 496452}, {t: 1587692465791, v: 496491}, + {t: 1587692480791, v: 496544}, {t: 1587692555791, v: 496619}, {t: 1587692570791, v: 496852}, {t: 1587692585791, v: 497052}, {t: 1587692600791, v: 497245}, {t: 1587692615791, v: 497529}, {t: 1587692630791, v: 497697}, {t: 1587692645791, v: 497909}, {t: 1587692660791, v: 498156}, {t: 1587692675803, v: 498466}, {t: 1587692690791, v: 498647}, + {t: 1587692705791, v: 498805}, {t: 1587692720791, v: 499013}, {t: 1587692735805, v: 499169}, {t: 1587692750791, v: 499345}, {t: 1587692765791, v: 499499}, {t: 1587692780791, v: 499731}, {t: 1587692795806, v: 499972}, {t: 1587692810791, v: 500201}, {t: 1587692825791, v: 500354}, {t: 1587692840791, v: 500512}, {t: 1587692855791, v: 500739}, + {t: 1587692870791, v: 500958}, {t: 1587692885791, v: 501190}, {t: 1587692900791, v: 501233}, {t: 1587692915791, v: 501391}, {t: 1587692930791, v: 501649}, {t: 1587692945791, v: 501853}, {t: 1587692960791, v: 502065}, {t: 1587692975791, v: 502239}, {t: 1587692990810, v: 502554}, {t: 1587693005791, v: 502754}, {t: 1587693020791, v: 502938}, + {t: 1587693035791, v: 503141}, {t: 1587693050791, v: 503416}, {t: 1587693065791, v: 503642}, {t: 1587693080791, v: 503873}, {t: 1587693095791, v: 504014}, {t: 1587693110791, v: 504178}, {t: 1587693125821, v: 504374}, {t: 1587693140791, v: 504578}, {t: 1587693155791, v: 504753}, {t: 1587693170791, v: 505043}, {t: 1587693185791, v: 505232}, + {t: 1587693200791, v: 505437}, {t: 1587693215791, v: 505596}, {t: 1587693230791, v: 505923}, {t: 1587693245791, v: 506088}, {t: 1587693260791, v: 506307}, {t: 1587693275791, v: 506518}, {t: 1587693290791, v: 506786}, {t: 1587693305791, v: 507008}, {t: 1587693320803, v: 507260}, {t: 1587693335791, v: 507519}, {t: 1587693350791, v: 507776}, + {t: 1587693365791, v: 508003}, {t: 1587693380791, v: 508322}, {t: 1587693395804, v: 508551}, {t: 1587693410791, v: 508750}, {t: 1587693425791, v: 508994}, {t: 1587693440791, v: 509237}, {t: 1587693455791, v: 509452}, {t: 1587693470791, v: 509702}, {t: 1587693485791, v: 509971}, {t: 1587693500791, v: 510147}, {t: 1587693515791, v: 510471}, + {t: 1587693530816, v: 510666}, {t: 1587693545791, v: 510871}, {t: 1587693560791, v: 511123}, {t: 1587693575791, v: 511303}, {t: 1587693590791, v: 511500}, + } +) + +func TestApplyCounterResetsIterator(t *testing.T) { defer leaktest.CheckTimeout(t, 10*time.Second)() - staleMarker := math.Float64frombits(value.StaleNaN) + for _, tcase := range []struct { + name string - chunks := [][]sample{ - {{100, 10}, {200, 20}, {300, 10}, {400, 20}, {400, 5}}, - {{500, 10}, {600, 20}, {700, 30}, {800, 40}, {800, 10}}, // No actual reset. - {{900, 5}, {1000, 10}, {1100, 15}}, // Actual reset. - {{1200, 20}, {1250, staleMarker}, {1300, 40}}, // No special last sample, no reset. - {{1400, 30}, {1500, 30}, {1600, 50}}, // No special last sample, reset. - } - exp := []sample{ - {100, 10}, {200, 20}, {300, 30}, {400, 40}, {500, 45}, - {600, 55}, {700, 65}, {800, 75}, {900, 80}, {1000, 85}, - {1100, 90}, {1200, 95}, {1300, 115}, {1400, 145}, {1500, 145}, {1600, 165}, - } + chunks [][]sample - var its []chunkenc.Iterator - for _, c := range chunks { - its = append(its, newSampleIterator(c)) - } + expected []sample + }{ + { + name: "series with stale marker", + chunks: [][]sample{ + {{100, 10}, {200, 20}, {300, 10}, {400, 20}, {400, 5}}, + {{500, 10}, {600, 20}, {700, 30}, {800, 40}, {800, 10}}, // No reset, just downsampling addded sample at the end. + {{900, 5}, {1000, 10}, {1100, 15}}, // Actual reset. + {{1200, 20}, {1250, math.Float64frombits(value.StaleNaN)}, {1300, 40}}, // No special last sample, no reset. + {{1400, 30}, {1500, 30}, {1600, 50}}, // No special last sample, reset. + }, + expected: []sample{ + {100, 10}, {200, 20}, {300, 30}, {400, 40}, {500, 45}, + {600, 55}, {700, 65}, {800, 75}, {900, 80}, {1000, 85}, + {1100, 90}, {1200, 95}, {1300, 115}, {1400, 145}, {1500, 145}, {1600, 165}, + }, + }, + { + name: "realistic raw data with 2 chunks that have one stale marker", + chunks: realisticChkDataWithStaleMarker, + expected: realisticChkDataWithCounterResetsAfterCounterSeriesIterating, + }, + { + // This can easily happen when querying StoreAPI with same data. Counter series should handle this. + name: "realistic raw data with many overlapping chunks with stale markers", + chunks: [][]sample{ + realisticChkDataWithStaleMarker[0], + realisticChkDataWithStaleMarker[0], + realisticChkDataWithStaleMarker[0], + realisticChkDataWithStaleMarker[1], + realisticChkDataWithStaleMarker[1], + realisticChkDataWithStaleMarker[1], + realisticChkDataWithStaleMarker[1], + realisticChkDataWithStaleMarker[1], + realisticChkDataWithStaleMarker[1], + realisticChkDataWithStaleMarker[1], + realisticChkDataWithStaleMarker[1], + realisticChkDataWithStaleMarker[1], + }, + expected: realisticChkDataWithCounterResetsAfterCounterSeriesIterating, + }, + { + name: "the same above input (realisticChkDataWithStaleMarker), but after 5m downsampling", + chunks: [][]sample{realisticChkDataWithCounterResetRes5m[0][AggrCounter]}, + expected: []sample{ + {t: 1587690005791, v: 461968}, {t: 1587690299999, v: 465870}, {t: 1587690599999, v: 469951}, {t: 1587690899999, v: 474726}, {t: 1587691199999, v: 479368}, + {t: 1587691499999, v: 483566}, {t: 1587691799999, v: 487787}, {t: 1587692099999, v: 492065}, {t: 1587692399999, v: 496245}, {t: 1587692699999, v: 498647}, + {t: 1587692999999, v: 502554}, {t: 1587693299999, v: 506786}, {t: 1587693590791, v: 511500}, + }, + }, + } { + t.Run(tcase.name, func(t *testing.T) { + var its []chunkenc.Iterator + for _, c := range tcase.chunks { + its = append(its, newSampleIterator(c)) + } - x := NewCounterSeriesIterator(its...) + x := NewApplyCounterResetsIterator(its...) - var res []sample - for x.Next() { - t, v := x.At() - res = append(res, sample{t, v}) + var res []sample + for x.Next() { + t, v := x.At() + res = append(res, sample{t, v}) + } + testutil.Ok(t, x.Err()) + testutil.Equals(t, tcase.expected, res) + + for i := range res[1:] { + testutil.Assert(t, res[i+1].t >= res[i].t, "sample time %v is not monotonically increasing. previous sample %v is older", res[i+1], res[i]) + testutil.Assert(t, res[i+1].v >= res[i].v, "sample value %v is not monotonically increasing. previous sample %v is larger", res[i+1], res[i]) + } + }) } - testutil.Ok(t, x.Err()) - testutil.Equals(t, exp, res) + } func TestCounterSeriesIteratorSeek(t *testing.T) { @@ -408,7 +691,7 @@ func TestCounterSeriesIteratorSeek(t *testing.T) { } var res []sample - x := NewCounterSeriesIterator(its...) + x := NewApplyCounterResetsIterator(its...) ok := x.Seek(150) testutil.Assert(t, ok, "Seek should return true") @@ -435,7 +718,7 @@ func TestCounterSeriesIteratorSeekExtendTs(t *testing.T) { its = append(its, newSampleIterator(c)) } - x := NewCounterSeriesIterator(its...) + x := NewApplyCounterResetsIterator(its...) ok := x.Seek(500) testutil.Assert(t, !ok, "Seek should return false") @@ -455,7 +738,7 @@ func TestCounterSeriesIteratorSeekAfterNext(t *testing.T) { } var res []sample - x := NewCounterSeriesIterator(its...) + x := NewApplyCounterResetsIterator(its...) x.Next() diff --git a/pkg/compact/downsample/streamed_block_writer.go b/pkg/compact/downsample/streamed_block_writer.go index 267a93bfab..a987c6fa95 100644 --- a/pkg/compact/downsample/streamed_block_writer.go +++ b/pkg/compact/downsample/streamed_block_writer.go @@ -108,7 +108,7 @@ func NewStreamedBlockWriter( // labelsValues sets and memPostings to be written on the finalize state in the end of downsampling process. func (w *streamedBlockWriter) WriteSeries(lset labels.Labels, chunks []chunks.Meta) error { if w.finalized || w.ignoreFinalize { - return errors.Errorf("series can't be added, writers has been closed or internal error happened") + return errors.New("series can't be added, writers has been closed or internal error happened") } if len(chunks) == 0 { diff --git a/pkg/compact/retention.go b/pkg/compact/retention.go index 47f61f0cfb..8d1ba7d5fb 100644 --- a/pkg/compact/retention.go +++ b/pkg/compact/retention.go @@ -9,20 +9,25 @@ import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" + "github.com/oklog/ulid" "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" "github.com/thanos-io/thanos/pkg/block" + "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/objstore" ) // ApplyRetentionPolicyByResolution removes blocks depending on the specified retentionByResolution based on blocks MaxTime. // A value of 0 disables the retention for its resolution. -func ApplyRetentionPolicyByResolution(ctx context.Context, logger log.Logger, bkt objstore.Bucket, fetcher block.MetadataFetcher, retentionByResolution map[ResolutionLevel]time.Duration) error { +func ApplyRetentionPolicyByResolution( + ctx context.Context, + logger log.Logger, + bkt objstore.Bucket, + metas map[ulid.ULID]*metadata.Meta, + retentionByResolution map[ResolutionLevel]time.Duration, + blocksMarkedForDeletion prometheus.Counter, +) error { level.Info(logger).Log("msg", "start optional retention") - metas, _, err := fetcher.Fetch(ctx) - if err != nil { - return errors.Wrap(err, "fetch metas") - } - for id, m := range metas { retentionDuration := retentionByResolution[ResolutionLevel(m.Thanos.Downsample.Resolution)] if retentionDuration.Seconds() == 0 { @@ -31,13 +36,12 @@ func ApplyRetentionPolicyByResolution(ctx context.Context, logger log.Logger, bk maxTime := time.Unix(m.MaxTime/1000, 0) if time.Now().After(maxTime.Add(retentionDuration)) { - level.Info(logger).Log("msg", "applying retention: deleting block", "id", id, "maxTime", maxTime.String()) - if err := block.Delete(ctx, logger, bkt, id); err != nil { + level.Info(logger).Log("msg", "applying retention: marking block for deletion", "id", id, "maxTime", maxTime.String()) + if err := block.MarkForDeletion(ctx, logger, bkt, id, blocksMarkedForDeletion); err != nil { return errors.Wrap(err, "delete block") } } } - level.Info(logger).Log("msg", "optional retention apply done") return nil } diff --git a/pkg/compact/retention_test.go b/pkg/compact/retention_test.go index 371d3c4152..8d3cee397d 100644 --- a/pkg/compact/retention_test.go +++ b/pkg/compact/retention_test.go @@ -7,18 +7,21 @@ import ( "bytes" "context" "encoding/json" + "path/filepath" "strings" "testing" "time" "github.com/go-kit/kit/log" "github.com/oklog/ulid" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/prometheus/prometheus/tsdb" "github.com/thanos-io/thanos/pkg/block" "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/compact" "github.com/thanos-io/thanos/pkg/objstore" - "github.com/thanos-io/thanos/pkg/objstore/inmem" "github.com/thanos-io/thanos/pkg/testutil" ) @@ -236,25 +239,40 @@ func TestApplyRetentionPolicyByResolution(t *testing.T) { }, } { t.Run(tt.name, func(t *testing.T) { - bkt := inmem.NewBucket() + bkt := objstore.WithNoopInstr(objstore.NewInMemBucket()) for _, b := range tt.blocks { uploadMockBlock(t, bkt, b.id, b.minTime, b.maxTime, int64(b.resolution)) } - metaFetcher, err := block.NewMetaFetcher(logger, 32, bkt, "", nil) + metaFetcher, err := block.NewMetaFetcher(logger, 32, bkt, "", nil, nil, nil) testutil.Ok(t, err) - if err := compact.ApplyRetentionPolicyByResolution(ctx, logger, bkt, metaFetcher, tt.retentionByResolution); (err != nil) != tt.wantErr { + blocksMarkedForDeletion := promauto.With(nil).NewCounter(prometheus.CounterOpts{}) + + metas, _, err := metaFetcher.Fetch(ctx) + testutil.Ok(t, err) + + if err := compact.ApplyRetentionPolicyByResolution(ctx, logger, bkt, metas, tt.retentionByResolution, blocksMarkedForDeletion); (err != nil) != tt.wantErr { t.Errorf("ApplyRetentionPolicyByResolution() error = %v, wantErr %v", err, tt.wantErr) } got := []string{} + gotMarkedBlocksCount := 0.0 testutil.Ok(t, bkt.Iter(context.TODO(), "", func(name string) error { - got = append(got, name) + exists, err := bkt.Exists(ctx, filepath.Join(name, metadata.DeletionMarkFilename)) + if err != nil { + return err + } + if !exists { + got = append(got, name) + return nil + } + gotMarkedBlocksCount += 1.0 return nil })) testutil.Equals(t, got, tt.want) + testutil.Equals(t, gotMarkedBlocksCount, promtest.ToFloat64(blocksMarkedForDeletion)) }) } } diff --git a/pkg/component/component.go b/pkg/component/component.go index f86ae85503..d847719405 100644 --- a/pkg/component/component.go +++ b/pkg/component/component.go @@ -81,19 +81,23 @@ func FromProto(storeType storepb.StoreType) StoreAPI { return Store case storepb.StoreType_RECEIVE: return Receive + case storepb.StoreType_DEBUG: + return Debug default: - return nil + return UnknownStoreAPI } } var ( - Bucket = source{component: component{name: "bucket"}} - Compact = source{component: component{name: "compact"}} - Downsample = source{component: component{name: "downsample"}} - Query = sourceStoreAPI{component: component{name: "query"}} - Rule = sourceStoreAPI{component: component{name: "rule"}} - Sidecar = sourceStoreAPI{component: component{name: "sidecar"}} - Store = sourceStoreAPI{component: component{name: "store"}} - Receive = sourceStoreAPI{component: component{name: "receive"}} - Replicate = sourceStoreAPI{component: component{name: "replicate"}} + Bucket = source{component: component{name: "bucket"}} + Compact = source{component: component{name: "compact"}} + Downsample = source{component: component{name: "downsample"}} + Replicate = source{component: component{name: "replicate"}} + Debug = sourceStoreAPI{component: component{name: "debug"}} + Receive = sourceStoreAPI{component: component{name: "receive"}} + Rule = sourceStoreAPI{component: component{name: "rule"}} + Sidecar = sourceStoreAPI{component: component{name: "sidecar"}} + Store = storeAPI{component: component{name: "store"}} + UnknownStoreAPI = storeAPI{component: component{name: "unknown-store-api"}} + Query = storeAPI{component: component{name: "query"}} ) diff --git a/pkg/discovery/dns/miekgdns/lookup.go b/pkg/discovery/dns/miekgdns/lookup.go index 4e3fb492e2..b9b95ce908 100644 --- a/pkg/discovery/dns/miekgdns/lookup.go +++ b/pkg/discovery/dns/miekgdns/lookup.go @@ -140,7 +140,7 @@ func askServerForName(name string, qType dns.Type, client *dns.Client, servAddr if response.Truncated { if client.Net == "tcp" { - return nil, errors.Errorf("got truncated message on TCP (64kiB limit exceeded?)") + return nil, errors.New("got truncated message on TCP (64kiB limit exceeded?)") } // TCP fallback. diff --git a/pkg/discovery/dns/provider.go b/pkg/discovery/dns/provider.go index 90cf72bfb9..1dad2ada9a 100644 --- a/pkg/discovery/dns/provider.go +++ b/pkg/discovery/dns/provider.go @@ -12,13 +12,14 @@ import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/thanos-io/thanos/pkg/discovery/dns/miekgdns" "github.com/thanos-io/thanos/pkg/extprom" ) // Provider is a stateful cache for asynchronous DNS resolutions. It provides a way to resolve addresses and obtain them. type Provider struct { - sync.Mutex + sync.RWMutex resolver Resolver // A map from domain name to a slice of resolved targets. resolved map[string][]string @@ -57,26 +58,20 @@ func NewProvider(logger log.Logger, reg prometheus.Registerer, resolverType Reso resolver: NewResolver(resolverType.ToResolver(logger)), resolved: make(map[string][]string), logger: logger, - resolverAddrs: extprom.NewTxGaugeVec(prometheus.GaugeOpts{ + resolverAddrs: extprom.NewTxGaugeVec(reg, prometheus.GaugeOpts{ Name: "dns_provider_results", Help: "The number of resolved endpoints for each configured address", }, []string{"addr"}), - resolverLookupsCount: prometheus.NewCounter(prometheus.CounterOpts{ + resolverLookupsCount: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "dns_lookups_total", Help: "The number of DNS lookups resolutions attempts", }), - resolverFailuresCount: prometheus.NewCounter(prometheus.CounterOpts{ + resolverFailuresCount: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "dns_failures_total", Help: "The number of DNS lookup failures", }), } - if reg != nil { - reg.MustRegister(p.resolverAddrs) - reg.MustRegister(p.resolverLookupsCount) - reg.MustRegister(p.resolverFailuresCount) - } - return p } @@ -92,27 +87,35 @@ func (p *Provider) Clone() *Provider { } } +// IsDynamicNode returns if the specified StoreAPI addr uses +// any kind of SD mechanism. +func IsDynamicNode(addr string) bool { + qtype, _ := GetQTypeName(addr) + return qtype != "" +} + +// GetQTypeName splits the provided addr into two parts: the QType (if any) +// and the name. +func GetQTypeName(addr string) (qtype string, name string) { + qtypeAndName := strings.SplitN(addr, "+", 2) + if len(qtypeAndName) != 2 { + return "", addr + } + return qtypeAndName[0], qtypeAndName[1] +} + // Resolve stores a list of provided addresses or their DNS records if requested. // Addresses prefixed with `dns+` or `dnssrv+` will be resolved through respective DNS lookup (A/AAAA or SRV). // defaultPort is used for non-SRV records when a port is not supplied. func (p *Provider) Resolve(ctx context.Context, addrs []string) { - p.Lock() - defer p.Unlock() - - p.resolverAddrs.ResetTx() - defer p.resolverAddrs.Submit() - resolvedAddrs := map[string][]string{} for _, addr := range addrs { var resolved []string - qtypeAndName := strings.SplitN(addr, "+", 2) - if len(qtypeAndName) != 2 { - // No lookup specified. Add to results and continue to the next address. - resolvedAddrs[addr] = []string{addr} - p.resolverAddrs.WithLabelValues(addr).Set(1.0) + qtype, name := GetQTypeName(addr) + if qtype == "" { + resolvedAddrs[name] = []string{name} continue } - qtype, name := qtypeAndName[0], qtypeAndName[1] resolved, err := p.resolver.Resolve(ctx, name, QType(qtype)) p.resolverLookupsCount.Inc() @@ -121,18 +124,31 @@ func (p *Provider) Resolve(ctx context.Context, addrs []string) { p.resolverFailuresCount.Inc() level.Error(p.logger).Log("msg", "dns resolution failed", "addr", addr, "err", err) // Use cached values. + p.RLock() resolved = p.resolved[addr] + p.RUnlock() } resolvedAddrs[addr] = resolved - p.resolverAddrs.WithLabelValues(addr).Set(float64(len(resolved))) } + + // All addresses have been resolved. We can now take an exclusive lock to + // update the resolved addresses metric and update the local state. + p.Lock() + defer p.Unlock() + + p.resolverAddrs.ResetTx() + for name, addrs := range resolvedAddrs { + p.resolverAddrs.WithLabelValues(name).Set(float64(len(addrs))) + } + p.resolverAddrs.Submit() + p.resolved = resolvedAddrs } // Addresses returns the latest addresses present in the Provider. func (p *Provider) Addresses() []string { - p.Lock() - defer p.Unlock() + p.RLock() + defer p.RUnlock() var result []string for _, addrs := range p.resolved { diff --git a/pkg/discovery/dns/provider_test.go b/pkg/discovery/dns/provider_test.go index 41f4e86cc5..585a7afb22 100644 --- a/pkg/discovery/dns/provider_test.go +++ b/pkg/discovery/dns/provider_test.go @@ -102,3 +102,35 @@ func (d *mockResolver) Resolve(_ context.Context, name string, _ QType) ([]strin } return d.res[name], nil } + +// TestIsDynamicNode tests whether we properly catch dynamically defined nodes. +func TestIsDynamicNode(t *testing.T) { + for _, tcase := range []struct { + node string + isDynamic bool + }{ + { + node: "1.2.3.4", + isDynamic: false, + }, + { + node: "gibberish+1.1.1.1+noa", + isDynamic: true, + }, + { + node: "", + isDynamic: false, + }, + { + node: "dns+aaa", + isDynamic: true, + }, + { + node: "dnssrv+asdasdsa", + isDynamic: true, + }, + } { + isDynamic := IsDynamicNode(tcase.node) + testutil.Equals(t, tcase.isDynamic, isDynamic, "mismatch between results") + } +} diff --git a/pkg/discovery/dns/resolver_test.go b/pkg/discovery/dns/resolver_test.go index f7d271d0c8..5663ca7380 100644 --- a/pkg/discovery/dns/resolver_test.go +++ b/pkg/discovery/dns/resolver_test.go @@ -76,7 +76,7 @@ var ( addr: "test.mycompany.com", qtype: A, expectedResult: nil, - expectedErr: errors.Errorf("missing port in address given for dns lookup: test.mycompany.com"), + expectedErr: errors.New("missing port in address given for dns lookup: test.mycompany.com"), resolver: &mockHostnameResolver{}, }, { @@ -168,7 +168,7 @@ var ( addr: "test.mycompany.com", qtype: "invalid", expectedResult: nil, - expectedErr: errors.Errorf("invalid lookup scheme \"invalid\""), + expectedErr: errors.New("invalid lookup scheme \"invalid\""), resolver: &mockHostnameResolver{}, }, } diff --git a/pkg/extflag/hidden.go b/pkg/extflag/hidden.go new file mode 100644 index 0000000000..cf8de957a5 --- /dev/null +++ b/pkg/extflag/hidden.go @@ -0,0 +1,21 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package extflag + +import ( + "gopkg.in/alecthomas/kingpin.v2" +) + +// HiddenCmdClause returns CmdClause that hides created flags. +func HiddenCmdClause(c CmdClause) CmdClause { + return hidden{c: c} +} + +type hidden struct { + c CmdClause +} + +func (h hidden) Flag(name, help string) *kingpin.FlagClause { + return h.c.Flag(name, help).Hidden() +} diff --git a/pkg/extgrpc/client.go b/pkg/extgrpc/client.go index eb6ac47595..5262b76fed 100644 --- a/pkg/extgrpc/client.go +++ b/pkg/extgrpc/client.go @@ -43,7 +43,6 @@ func StoreClientGRPCOpts(logger log.Logger, reg *prometheus.Registry, tracer ope ), ), } - if reg != nil { reg.MustRegister(grpcMets) } diff --git a/pkg/extprom/http/instrument_server.go b/pkg/extprom/http/instrument_server.go index 907d3da6e5..c09bb6f8b3 100644 --- a/pkg/extprom/http/instrument_server.go +++ b/pkg/extprom/http/instrument_server.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" ) @@ -40,7 +41,7 @@ type defaultInstrumentationMiddleware struct { // NewInstrumentationMiddleware provides default InstrumentationMiddleware. func NewInstrumentationMiddleware(reg prometheus.Registerer) InstrumentationMiddleware { ins := defaultInstrumentationMiddleware{ - requestDuration: prometheus.NewHistogramVec( + requestDuration: promauto.With(reg).NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "Tracks the latencies for HTTP requests.", @@ -49,7 +50,7 @@ func NewInstrumentationMiddleware(reg prometheus.Registerer) InstrumentationMidd []string{"code", "handler", "method"}, ), - requestSize: prometheus.NewSummaryVec( + requestSize: promauto.With(reg).NewSummaryVec( prometheus.SummaryOpts{ Name: "http_request_size_bytes", Help: "Tracks the size of HTTP requests.", @@ -57,14 +58,14 @@ func NewInstrumentationMiddleware(reg prometheus.Registerer) InstrumentationMidd []string{"code", "handler", "method"}, ), - requestsTotal: prometheus.NewCounterVec( + requestsTotal: promauto.With(reg).NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Tracks the number of HTTP requests.", }, []string{"code", "handler", "method"}, ), - responseSize: prometheus.NewSummaryVec( + responseSize: promauto.With(reg).NewSummaryVec( prometheus.SummaryOpts{ Name: "http_response_size_bytes", Help: "Tracks the size of HTTP responses.", @@ -72,7 +73,6 @@ func NewInstrumentationMiddleware(reg prometheus.Registerer) InstrumentationMidd []string{"code", "handler", "method"}, ), } - reg.MustRegister(ins.requestDuration, ins.requestSize, ins.requestsTotal, ins.responseSize) return &ins } diff --git a/pkg/extprom/tx_gauge.go b/pkg/extprom/tx_gauge.go index d85bf4f921..a619b122e9 100644 --- a/pkg/extprom/tx_gauge.go +++ b/pkg/extprom/tx_gauge.go @@ -7,6 +7,7 @@ import ( "sync" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" ) type TxGaugeVec struct { @@ -24,18 +25,23 @@ type TxGaugeVec struct { // // Additionally it allows to init LabelValues on each transaction. // NOTE: This is quite naive implementation creating new prometheus.GaugeVec on each `ResetTx`, use wisely. -func NewTxGaugeVec(opts prometheus.GaugeOpts, labelNames []string, initLabelValues ...[]string) *TxGaugeVec { +func NewTxGaugeVec(reg prometheus.Registerer, opts prometheus.GaugeOpts, labelNames []string, initLabelValues ...[]string) *TxGaugeVec { + // Nil as we will register it on our own later. f := func() *prometheus.GaugeVec { - g := prometheus.NewGaugeVec(opts, labelNames) + g := promauto.With(nil).NewGaugeVec(opts, labelNames) for _, vals := range initLabelValues { g.WithLabelValues(vals...) } return g } - return &TxGaugeVec{ + tx := &TxGaugeVec{ current: f(), newMetricVal: f, } + if reg != nil { + reg.MustRegister(tx) + } + return tx } // ResetTx starts new transaction. Not goroutine-safe. diff --git a/pkg/extprom/tx_gauge_test.go b/pkg/extprom/tx_gauge_test.go index 4be8b02de4..92af9dc43c 100644 --- a/pkg/extprom/tx_gauge_test.go +++ b/pkg/extprom/tx_gauge_test.go @@ -4,17 +4,17 @@ package extprom import ( - "fmt" "strings" "testing" + "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" "github.com/thanos-io/thanos/pkg/testutil" ) func TestTxGaugeVec(t *testing.T) { - g := NewTxGaugeVec(prometheus.GaugeOpts{ + g := NewTxGaugeVec(nil, prometheus.GaugeOpts{ Name: "metric", }, []string{"a", "b"}, []string{"a1", "b1"}, []string{"a2", "b2"}) @@ -167,7 +167,7 @@ func toFloat64(t *testing.T, c prometheus.Collector) map[string]float64 { if pb.Untyped != nil { exp[lbToString(pb.GetLabel())] = pb.Untyped.GetValue() } - panic(fmt.Errorf("collected a non-gauge/counter/untyped metric: %s", pb)) + panic(errors.Errorf("collected a non-gauge/counter/untyped metric: %s", pb)) } return exp diff --git a/pkg/gate/gate.go b/pkg/gate/gate.go index 43bc3a47b4..549b0f3300 100644 --- a/pkg/gate/gate.go +++ b/pkg/gate/gate.go @@ -8,6 +8,7 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/pkg/gate" ) @@ -27,21 +28,17 @@ type Gate struct { func NewGate(maxConcurrent int, reg prometheus.Registerer) *Gate { g := &Gate{ g: gate.New(maxConcurrent), - inflightQueries: prometheus.NewGauge(prometheus.GaugeOpts{ + inflightQueries: promauto.With(reg).NewGauge(prometheus.GaugeOpts{ Name: "gate_queries_in_flight", Help: "Number of queries that are currently in flight.", }), - gateTiming: prometheus.NewHistogram(prometheus.HistogramOpts{ + gateTiming: promauto.With(reg).NewHistogram(prometheus.HistogramOpts{ Name: "gate_duration_seconds", Help: "How many seconds it took for queries to wait at the gate.", Buckets: []float64{0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120, 240, 360, 720}, }), } - if reg != nil { - reg.MustRegister(g.inflightQueries, g.gateTiming) - } - return g } diff --git a/pkg/store/cache/units.go b/pkg/model/units.go similarity index 96% rename from pkg/store/cache/units.go rename to pkg/model/units.go index 156ea54ddb..cd4944f6d7 100644 --- a/pkg/store/cache/units.go +++ b/pkg/model/units.go @@ -1,7 +1,7 @@ // Copyright (c) The Thanos Authors. // Licensed under the Apache License 2.0. -package storecache +package model import ( "github.com/alecthomas/units" diff --git a/pkg/store/cache/units_test.go b/pkg/model/units_test.go similarity index 96% rename from pkg/store/cache/units_test.go rename to pkg/model/units_test.go index bde202a2f1..1b3f53f18d 100644 --- a/pkg/store/cache/units_test.go +++ b/pkg/model/units_test.go @@ -1,7 +1,7 @@ // Copyright (c) The Thanos Authors. // Licensed under the Apache License 2.0. -package storecache +package model import ( "testing" diff --git a/pkg/objstore/client/factory.go b/pkg/objstore/client/factory.go index 6caf7f8ee4..2a4716fb83 100644 --- a/pkg/objstore/client/factory.go +++ b/pkg/objstore/client/factory.go @@ -42,7 +42,7 @@ type BucketConfig struct { // NewBucket initializes and returns new object storage clients. // NOTE: confContentYaml can contain secrets. -func NewBucket(logger log.Logger, confContentYaml []byte, reg prometheus.Registerer, component string) (objstore.Bucket, error) { +func NewBucket(logger log.Logger, confContentYaml []byte, reg prometheus.Registerer, component string) (objstore.InstrumentedBucket, error) { level.Info(logger).Log("msg", "loading bucket configuration") bucketConf := &BucketConfig{} if err := yaml.UnmarshalStrict(confContentYaml, bucketConf); err != nil { diff --git a/pkg/objstore/cos/cos.go b/pkg/objstore/cos/cos.go index 65768d46b1..6db898f6ca 100644 --- a/pkg/objstore/cos/cos.go +++ b/pkg/objstore/cos/cos.go @@ -52,6 +52,7 @@ func (conf *Config) validate() error { return nil } +// NewBucket returns a new Bucket using the provided cos configuration. func NewBucket(logger log.Logger, conf []byte, component string) (*Bucket, error) { if logger == nil { logger = log.NewNopLogger() @@ -151,7 +152,7 @@ func (b *Bucket) Iter(ctx context.Context, dir string, f func(string) error) err func (b *Bucket) getRange(ctx context.Context, name string, off, length int64) (io.ReadCloser, error) { if len(name) == 0 { - return nil, errors.Errorf("given object name should not empty") + return nil, errors.New("given object name should not empty") } opts := &cos.ObjectGetOptions{} diff --git a/pkg/objstore/inmem/inmem.go b/pkg/objstore/inmem.go similarity index 71% rename from pkg/objstore/inmem/inmem.go rename to pkg/objstore/inmem.go index 7f430c3c97..0233f795f0 100644 --- a/pkg/objstore/inmem/inmem.go +++ b/pkg/objstore/inmem.go @@ -1,7 +1,7 @@ // Copyright (c) The Thanos Authors. // Licensed under the Apache License 2.0. -package inmem +package objstore import ( "bytes" @@ -13,37 +13,36 @@ import ( "sync" "github.com/pkg/errors" - "github.com/thanos-io/thanos/pkg/objstore" ) var errNotFound = errors.New("inmem: object not found") -// Bucket implements the objstore.Bucket interfaces against local memory. +// InMemBucket implements the objstore.Bucket interfaces against local memory. // Methods from Bucket interface are thread-safe. Objects are assumed to be immutable. -type Bucket struct { +type InMemBucket struct { mtx sync.RWMutex objects map[string][]byte } -// NewBucket returns a new in memory Bucket. +// NewInMemBucket returns a new in memory Bucket. // NOTE: Returned bucket is just a naive in memory bucket implementation. For test use cases only. -func NewBucket() *Bucket { - return &Bucket{objects: map[string][]byte{}} +func NewInMemBucket() *InMemBucket { + return &InMemBucket{objects: map[string][]byte{}} } // Objects returns internally stored objects. // NOTE: For assert purposes. -func (b *Bucket) Objects() map[string][]byte { +func (b *InMemBucket) Objects() map[string][]byte { return b.objects } // Iter calls f for each entry in the given directory. The argument to f is the full // object name including the prefix of the inspected directory. -func (b *Bucket) Iter(_ context.Context, dir string, f func(string) error) error { +func (b *InMemBucket) Iter(_ context.Context, dir string, f func(string) error) error { unique := map[string]struct{}{} var dirPartsCount int - dirParts := strings.SplitAfter(dir, objstore.DirDelim) + dirParts := strings.SplitAfter(dir, DirDelim) for _, p := range dirParts { if p == "" { continue @@ -57,7 +56,7 @@ func (b *Bucket) Iter(_ context.Context, dir string, f func(string) error) error continue } - parts := strings.SplitAfter(filename, objstore.DirDelim) + parts := strings.SplitAfter(filename, DirDelim) unique[strings.Join(parts[:dirPartsCount+1], "")] = struct{}{} } b.mtx.RUnlock() @@ -67,13 +66,13 @@ func (b *Bucket) Iter(_ context.Context, dir string, f func(string) error) error keys = append(keys, n) } sort.Slice(keys, func(i, j int) bool { - if strings.HasSuffix(keys[i], objstore.DirDelim) && strings.HasSuffix(keys[j], objstore.DirDelim) { + if strings.HasSuffix(keys[i], DirDelim) && strings.HasSuffix(keys[j], DirDelim) { return strings.Compare(keys[i], keys[j]) < 0 } - if strings.HasSuffix(keys[i], objstore.DirDelim) { + if strings.HasSuffix(keys[i], DirDelim) { return false } - if strings.HasSuffix(keys[j], objstore.DirDelim) { + if strings.HasSuffix(keys[j], DirDelim) { return true } @@ -89,7 +88,7 @@ func (b *Bucket) Iter(_ context.Context, dir string, f func(string) error) error } // Get returns a reader for the given object name. -func (b *Bucket) Get(_ context.Context, name string) (io.ReadCloser, error) { +func (b *InMemBucket) Get(_ context.Context, name string) (io.ReadCloser, error) { if name == "" { return nil, errors.New("inmem: object name is empty") } @@ -105,7 +104,7 @@ func (b *Bucket) Get(_ context.Context, name string) (io.ReadCloser, error) { } // GetRange returns a new range reader for the given object name and range. -func (b *Bucket) GetRange(_ context.Context, name string, off, length int64) (io.ReadCloser, error) { +func (b *InMemBucket) GetRange(_ context.Context, name string, off, length int64) (io.ReadCloser, error) { if name == "" { return nil, errors.New("inmem: object name is empty") } @@ -138,7 +137,7 @@ func (b *Bucket) GetRange(_ context.Context, name string, off, length int64) (io } // Exists checks if the given directory exists in memory. -func (b *Bucket) Exists(_ context.Context, name string) (bool, error) { +func (b *InMemBucket) Exists(_ context.Context, name string) (bool, error) { b.mtx.RLock() defer b.mtx.RUnlock() _, ok := b.objects[name] @@ -146,7 +145,7 @@ func (b *Bucket) Exists(_ context.Context, name string) (bool, error) { } // ObjectSize returns the size of the specified object. -func (b *Bucket) ObjectSize(_ context.Context, name string) (uint64, error) { +func (b *InMemBucket) ObjectSize(_ context.Context, name string) (uint64, error) { b.mtx.RLock() file, ok := b.objects[name] b.mtx.RUnlock() @@ -157,7 +156,7 @@ func (b *Bucket) ObjectSize(_ context.Context, name string) (uint64, error) { } // Upload writes the file specified in src to into the memory. -func (b *Bucket) Upload(_ context.Context, name string, r io.Reader) error { +func (b *InMemBucket) Upload(_ context.Context, name string, r io.Reader) error { b.mtx.Lock() defer b.mtx.Unlock() body, err := ioutil.ReadAll(r) @@ -169,7 +168,7 @@ func (b *Bucket) Upload(_ context.Context, name string, r io.Reader) error { } // Delete removes all data prefixed with the dir. -func (b *Bucket) Delete(_ context.Context, name string) error { +func (b *InMemBucket) Delete(_ context.Context, name string) error { b.mtx.Lock() defer b.mtx.Unlock() if _, ok := b.objects[name]; !ok { @@ -180,13 +179,13 @@ func (b *Bucket) Delete(_ context.Context, name string) error { } // IsObjNotFoundErr returns true if error means that object is not found. Relevant to Get operations. -func (b *Bucket) IsObjNotFoundErr(err error) bool { - return err == errNotFound +func (b *InMemBucket) IsObjNotFoundErr(err error) bool { + return errors.Cause(err) == errNotFound } -func (b *Bucket) Close() error { return nil } +func (b *InMemBucket) Close() error { return nil } // Name returns the bucket name. -func (b *Bucket) Name() string { +func (b *InMemBucket) Name() string { return "inmem" } diff --git a/pkg/objstore/objstore.go b/pkg/objstore/objstore.go index ef8fc4ca4a..c1bb44d079 100644 --- a/pkg/objstore/objstore.go +++ b/pkg/objstore/objstore.go @@ -4,20 +4,19 @@ package objstore import ( + "bytes" "context" - "fmt" "io" - "math/rand" "os" "path/filepath" "strings" - "testing" "time" "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/thanos-io/thanos/pkg/runutil" ) @@ -39,6 +38,20 @@ type Bucket interface { Name() string } +// InstrumentedBucket is a Bucket with optional instrumentation control on reader. +type InstrumentedBucket interface { + Bucket + + // WithExpectedErrs allows to specify a filter that marks certain errors as expected, so it will not increment + // thanos_objstore_bucket_operation_failures_total metric. + WithExpectedErrs(IsOpFailureExpectedFunc) Bucket + + // ReaderWithExpectedErrs allows to specify a filter that marks certain errors as expected, so it will not increment + // thanos_objstore_bucket_operation_failures_total metric. + // TODO(bwplotka): Remove this when moved to Go 1.14 and replace with InstrumentedBucketReader. + ReaderWithExpectedErrs(IsOpFailureExpectedFunc) BucketReader +} + // BucketReader provides read access to an object storage bucket. type BucketReader interface { // Iter calls f for each entry in the given directory (not recursive.). The argument to f is the full @@ -52,7 +65,6 @@ type BucketReader interface { GetRange(ctx context.Context, name string, off, length int64) (io.ReadCloser, error) // Exists checks if the given object exists in the bucket. - // TODO(bplotka): Consider removing Exists in favor of helper that do Get & IsObjNotFoundErr (less code to maintain). Exists(ctx context.Context, name string) (bool, error) // IsObjNotFoundErr returns true if error means that object is not found. Relevant to Get operations. @@ -62,6 +74,33 @@ type BucketReader interface { ObjectSize(ctx context.Context, name string) (uint64, error) } +// InstrumentedBucket is a BucketReader with optional instrumentation control. +type InstrumentedBucketReader interface { + BucketReader + + // ReaderWithExpectedErrs allows to specify a filter that marks certain errors as expected, so it will not increment + // thanos_objstore_bucket_operation_failures_total metric. + ReaderWithExpectedErrs(IsOpFailureExpectedFunc) BucketReader +} + +// TryToGetSize tries to get upfront size from reader. +// TODO(https://github.com/thanos-io/thanos/issues/678): Remove guessing length when minio provider will support multipart upload without this. +func TryToGetSize(r io.Reader) (int64, error) { + switch f := r.(type) { + case *os.File: + fileInfo, err := f.Stat() + if err != nil { + return 0, errors.Wrap(err, "os.File.Stat()") + } + return fileInfo.Size(), nil + case *bytes.Buffer: + return int64(f.Len()), nil + case *strings.Reader: + return f.Size(), nil + } + return 0, errors.New("unsupported type of io.Reader") +} + // UploadDir uploads all files in srcdir to the bucket with into a top-level directory // named dstdir. It is a caller responsibility to clean partial upload in case of failure. func UploadDir(ctx context.Context, logger log.Logger, bkt Bucket, srcdir, dstdir string) error { @@ -171,23 +210,6 @@ func DownloadDir(ctx context.Context, logger log.Logger, bkt BucketReader, src, return nil } -// Exists returns true, if file exists, otherwise false and nil error if presence IsObjNotFoundErr, otherwise false with -// returning error. -func Exists(ctx context.Context, bkt Bucket, src string) (bool, error) { - rc, err := bkt.Get(ctx, src) - if rc != nil { - _ = rc.Close() - } - if err != nil { - if bkt.IsObjNotFoundErr(err) { - return false, nil - } - return false, errors.Wrap(err, "stat object") - } - - return true, nil -} - const ( iterOp = "iter" sizeOp = "objectsize" @@ -198,151 +220,196 @@ const ( deleteOp = "delete" ) +// IsOpFailureExpectedFunc allows to mark certain errors as expected, so they will not increment thanos_objstore_bucket_operation_failures_total metric. +type IsOpFailureExpectedFunc func(error) bool + +var _ InstrumentedBucket = &metricBucket{} + // BucketWithMetrics takes a bucket and registers metrics with the given registry for // operations run against the bucket. -func BucketWithMetrics(name string, b Bucket, r prometheus.Registerer) Bucket { +func BucketWithMetrics(name string, b Bucket, reg prometheus.Registerer) *metricBucket { bkt := &metricBucket{ - bkt: b, - - ops: prometheus.NewCounterVec(prometheus.CounterOpts{ + bkt: b, + isOpFailureExpected: func(err error) bool { return false }, + ops: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_objstore_bucket_operations_total", - Help: "Total number of operations against a bucket.", + Help: "Total number of all attempted operations against a bucket.", ConstLabels: prometheus.Labels{"bucket": name}, }, []string{"operation"}), - opsFailures: prometheus.NewCounterVec(prometheus.CounterOpts{ + opsFailures: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_objstore_bucket_operation_failures_total", - Help: "Total number of operations against a bucket that failed.", + Help: "Total number of operations against a bucket that failed, but were not expected to fail in certain way from caller perspective. Those errors have to be investigated.", ConstLabels: prometheus.Labels{"bucket": name}, }, []string{"operation"}), - opsDuration: prometheus.NewHistogramVec(prometheus.HistogramOpts{ + opsDuration: promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{ Name: "thanos_objstore_bucket_operation_duration_seconds", - Help: "Duration of operations against the bucket", + Help: "Duration of successful operations against the bucket", ConstLabels: prometheus.Labels{"bucket": name}, Buckets: []float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120}, }, []string{"operation"}), - lastSuccessfulUploadTime: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + lastSuccessfulUploadTime: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ Name: "thanos_objstore_bucket_last_successful_upload_time", Help: "Second timestamp of the last successful upload to the bucket.", }, []string{"bucket"}), } - if r != nil { - r.MustRegister(bkt.ops, bkt.opsFailures, bkt.opsDuration, bkt.lastSuccessfulUploadTime) - for _, op := range []string{iterOp, sizeOp, getOp, getRangeOp, existsOp, uploadOp, deleteOp} { - bkt.ops.WithLabelValues(op) - bkt.opsFailures.WithLabelValues(op) - bkt.opsDuration.WithLabelValues(op) - } - bkt.lastSuccessfulUploadTime.WithLabelValues(b.Name()) + for _, op := range []string{ + iterOp, + sizeOp, + getOp, + getRangeOp, + existsOp, + uploadOp, + deleteOp, + } { + bkt.ops.WithLabelValues(op) + bkt.opsFailures.WithLabelValues(op) + bkt.opsDuration.WithLabelValues(op) } + bkt.lastSuccessfulUploadTime.WithLabelValues(b.Name()) return bkt } type metricBucket struct { bkt Bucket - ops *prometheus.CounterVec - opsFailures *prometheus.CounterVec + ops *prometheus.CounterVec + opsFailures *prometheus.CounterVec + isOpFailureExpected IsOpFailureExpectedFunc + opsDuration *prometheus.HistogramVec lastSuccessfulUploadTime *prometheus.GaugeVec } +func (b *metricBucket) WithExpectedErrs(fn IsOpFailureExpectedFunc) Bucket { + return &metricBucket{ + bkt: b.bkt, + ops: b.ops, + opsFailures: b.opsFailures, + isOpFailureExpected: fn, + opsDuration: b.opsDuration, + lastSuccessfulUploadTime: b.lastSuccessfulUploadTime, + } +} + +func (b *metricBucket) ReaderWithExpectedErrs(fn IsOpFailureExpectedFunc) BucketReader { + return b.WithExpectedErrs(fn) +} + func (b *metricBucket) Iter(ctx context.Context, dir string, f func(name string) error) error { + const op = iterOp + b.ops.WithLabelValues(op).Inc() + err := b.bkt.Iter(ctx, dir, f) - if err != nil { - b.opsFailures.WithLabelValues(iterOp).Inc() + if err != nil && !b.isOpFailureExpected(err) { + b.opsFailures.WithLabelValues(op).Inc() } - b.ops.WithLabelValues(iterOp).Inc() - return err } -// ObjectSize returns the size of the specified object. func (b *metricBucket) ObjectSize(ctx context.Context, name string) (uint64, error) { - b.ops.WithLabelValues(sizeOp).Inc() - start := time.Now() + const op = sizeOp + b.ops.WithLabelValues(op).Inc() + start := time.Now() rc, err := b.bkt.ObjectSize(ctx, name) if err != nil { - b.opsFailures.WithLabelValues(sizeOp).Inc() + if !b.isOpFailureExpected(err) { + b.opsFailures.WithLabelValues(op).Inc() + } return 0, err } - b.opsDuration.WithLabelValues(sizeOp).Observe(time.Since(start).Seconds()) + b.opsDuration.WithLabelValues(op).Observe(time.Since(start).Seconds()) return rc, nil } func (b *metricBucket) Get(ctx context.Context, name string) (io.ReadCloser, error) { - b.ops.WithLabelValues(getOp).Inc() + const op = getOp + b.ops.WithLabelValues(op).Inc() rc, err := b.bkt.Get(ctx, name) if err != nil { - b.opsFailures.WithLabelValues(getOp).Inc() + if !b.isOpFailureExpected(err) { + b.opsFailures.WithLabelValues(op).Inc() + } return nil, err } return newTimingReadCloser( rc, - getOp, + op, b.opsDuration, b.opsFailures, + b.isOpFailureExpected, ), nil } func (b *metricBucket) GetRange(ctx context.Context, name string, off, length int64) (io.ReadCloser, error) { - b.ops.WithLabelValues(getRangeOp).Inc() + const op = getRangeOp + b.ops.WithLabelValues(op).Inc() rc, err := b.bkt.GetRange(ctx, name, off, length) if err != nil { - b.opsFailures.WithLabelValues(getRangeOp).Inc() + if !b.isOpFailureExpected(err) { + b.opsFailures.WithLabelValues(op).Inc() + } return nil, err } return newTimingReadCloser( rc, - getRangeOp, + op, b.opsDuration, b.opsFailures, + b.isOpFailureExpected, ), nil } func (b *metricBucket) Exists(ctx context.Context, name string) (bool, error) { - start := time.Now() + const op = existsOp + b.ops.WithLabelValues(op).Inc() + start := time.Now() ok, err := b.bkt.Exists(ctx, name) if err != nil { - b.opsFailures.WithLabelValues(existsOp).Inc() + if !b.isOpFailureExpected(err) { + b.opsFailures.WithLabelValues(op).Inc() + } + return false, err } - b.ops.WithLabelValues(existsOp).Inc() - b.opsDuration.WithLabelValues(existsOp).Observe(time.Since(start).Seconds()) - - return ok, err + b.opsDuration.WithLabelValues(op).Observe(time.Since(start).Seconds()) + return ok, nil } func (b *metricBucket) Upload(ctx context.Context, name string, r io.Reader) error { - start := time.Now() + const op = uploadOp + b.ops.WithLabelValues(op).Inc() - err := b.bkt.Upload(ctx, name, r) - if err != nil { - b.opsFailures.WithLabelValues(uploadOp).Inc() - } else { - b.lastSuccessfulUploadTime.WithLabelValues(b.bkt.Name()).SetToCurrentTime() + start := time.Now() + if err := b.bkt.Upload(ctx, name, r); err != nil { + if !b.isOpFailureExpected(err) { + b.opsFailures.WithLabelValues(op).Inc() + } + return err } - b.ops.WithLabelValues(uploadOp).Inc() - b.opsDuration.WithLabelValues(uploadOp).Observe(time.Since(start).Seconds()) - - return err + b.lastSuccessfulUploadTime.WithLabelValues(b.bkt.Name()).SetToCurrentTime() + b.opsDuration.WithLabelValues(op).Observe(time.Since(start).Seconds()) + return nil } func (b *metricBucket) Delete(ctx context.Context, name string) error { - start := time.Now() + const op = deleteOp + b.ops.WithLabelValues(op).Inc() - err := b.bkt.Delete(ctx, name) - if err != nil { - b.opsFailures.WithLabelValues(deleteOp).Inc() + start := time.Now() + if err := b.bkt.Delete(ctx, name); err != nil { + if !b.isOpFailureExpected(err) { + b.opsFailures.WithLabelValues(op).Inc() + } + return err } - b.ops.WithLabelValues(deleteOp).Inc() - b.opsDuration.WithLabelValues(deleteOp).Observe(time.Since(start).Seconds()) + b.opsDuration.WithLabelValues(op).Observe(time.Since(start).Seconds()) - return err + return nil } func (b *metricBucket) IsObjNotFoundErr(err error) bool { @@ -360,53 +427,49 @@ func (b *metricBucket) Name() string { type timingReadCloser struct { io.ReadCloser - ok bool - start time.Time - op string - duration *prometheus.HistogramVec - failed *prometheus.CounterVec + alreadyGotErr bool + + start time.Time + op string + duration *prometheus.HistogramVec + failed *prometheus.CounterVec + isFailureExpected IsOpFailureExpectedFunc } -func newTimingReadCloser(rc io.ReadCloser, op string, dur *prometheus.HistogramVec, failed *prometheus.CounterVec) *timingReadCloser { +func newTimingReadCloser(rc io.ReadCloser, op string, dur *prometheus.HistogramVec, failed *prometheus.CounterVec, isFailureExpected IsOpFailureExpectedFunc) *timingReadCloser { // Initialize the metrics with 0. dur.WithLabelValues(op) failed.WithLabelValues(op) return &timingReadCloser{ - ReadCloser: rc, - ok: true, - start: time.Now(), - op: op, - duration: dur, - failed: failed, + ReadCloser: rc, + start: time.Now(), + op: op, + duration: dur, + failed: failed, + isFailureExpected: isFailureExpected, } } func (rc *timingReadCloser) Close() error { err := rc.ReadCloser.Close() - rc.duration.WithLabelValues(rc.op).Observe(time.Since(rc.start).Seconds()) - if rc.ok && err != nil { + if !rc.alreadyGotErr && err != nil { rc.failed.WithLabelValues(rc.op).Inc() - rc.ok = false + } + if !rc.alreadyGotErr && err == nil { + rc.duration.WithLabelValues(rc.op).Observe(time.Since(rc.start).Seconds()) + rc.alreadyGotErr = true } return err } func (rc *timingReadCloser) Read(b []byte) (n int, err error) { n, err = rc.ReadCloser.Read(b) - if rc.ok && err != nil && err != io.EOF { - rc.failed.WithLabelValues(rc.op).Inc() - rc.ok = false + // Report metric just once. + if !rc.alreadyGotErr && err != nil && err != io.EOF { + if !rc.isFailureExpected(err) { + rc.failed.WithLabelValues(rc.op).Inc() + } + rc.alreadyGotErr = true } return n, err } - -func CreateTemporaryTestBucketName(t testing.TB) string { - src := rand.NewSource(time.Now().UnixNano()) - - // Bucket name need to conform: https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-s3-bucket-naming-requirements.html. - name := strings.Replace(strings.Replace(fmt.Sprintf("test_%x_%s", src.Int63(), strings.ToLower(t.Name())), "_", "-", -1), "/", "-", -1) - if len(name) >= 63 { - name = name[:63] - } - return name -} diff --git a/pkg/objstore/objstore_test.go b/pkg/objstore/objstore_test.go new file mode 100644 index 0000000000..f78d8550d9 --- /dev/null +++ b/pkg/objstore/objstore_test.go @@ -0,0 +1,64 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package objstore + +import ( + "testing" + + promtest "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/thanos-io/thanos/pkg/testutil" +) + +func TestMetricBucket_Close(t *testing.T) { + bkt := BucketWithMetrics("abc", NewInMemBucket(), nil) + // Expected initialized metrics. + testutil.Equals(t, 7, promtest.CollectAndCount(bkt.ops)) + testutil.Equals(t, 7, promtest.CollectAndCount(bkt.opsFailures)) + testutil.Equals(t, 7, promtest.CollectAndCount(bkt.opsDuration)) + + AcceptanceTest(t, bkt.WithExpectedErrs(bkt.IsObjNotFoundErr)) + testutil.Equals(t, float64(6), promtest.ToFloat64(bkt.ops.WithLabelValues(iterOp))) + testutil.Equals(t, float64(2), promtest.ToFloat64(bkt.ops.WithLabelValues(sizeOp))) + testutil.Equals(t, float64(3), promtest.ToFloat64(bkt.ops.WithLabelValues(getOp))) + testutil.Equals(t, float64(3), promtest.ToFloat64(bkt.ops.WithLabelValues(getRangeOp))) + testutil.Equals(t, float64(2), promtest.ToFloat64(bkt.ops.WithLabelValues(existsOp))) + testutil.Equals(t, float64(6), promtest.ToFloat64(bkt.ops.WithLabelValues(uploadOp))) + testutil.Equals(t, float64(2), promtest.ToFloat64(bkt.ops.WithLabelValues(deleteOp))) + testutil.Equals(t, 7, promtest.CollectAndCount(bkt.ops)) + testutil.Equals(t, float64(0), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(iterOp))) + testutil.Equals(t, float64(0), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(sizeOp))) + testutil.Equals(t, float64(1), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(getOp))) + testutil.Equals(t, float64(0), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(getRangeOp))) + testutil.Equals(t, float64(0), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(existsOp))) + testutil.Equals(t, float64(0), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(uploadOp))) + testutil.Equals(t, float64(0), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(deleteOp))) + testutil.Equals(t, 7, promtest.CollectAndCount(bkt.opsFailures)) + testutil.Equals(t, 7, promtest.CollectAndCount(bkt.opsDuration)) + lastUpload := promtest.ToFloat64(bkt.lastSuccessfulUploadTime) + testutil.Assert(t, lastUpload > 0, "last upload not greater than 0, val: %f", lastUpload) + + // Clear bucket, but don't clear metrics to ensure we use same. + bkt.bkt = NewInMemBucket() + AcceptanceTest(t, bkt) + testutil.Equals(t, float64(12), promtest.ToFloat64(bkt.ops.WithLabelValues(iterOp))) + testutil.Equals(t, float64(4), promtest.ToFloat64(bkt.ops.WithLabelValues(sizeOp))) + testutil.Equals(t, float64(6), promtest.ToFloat64(bkt.ops.WithLabelValues(getOp))) + testutil.Equals(t, float64(6), promtest.ToFloat64(bkt.ops.WithLabelValues(getRangeOp))) + testutil.Equals(t, float64(4), promtest.ToFloat64(bkt.ops.WithLabelValues(existsOp))) + testutil.Equals(t, float64(12), promtest.ToFloat64(bkt.ops.WithLabelValues(uploadOp))) + testutil.Equals(t, float64(4), promtest.ToFloat64(bkt.ops.WithLabelValues(deleteOp))) + testutil.Equals(t, 7, promtest.CollectAndCount(bkt.ops)) + testutil.Equals(t, float64(0), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(iterOp))) + // Not expected not found error here. + testutil.Equals(t, float64(1), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(sizeOp))) + // Not expected not found errors, this should increment failure metric on get for not found as well, so +2. + testutil.Equals(t, float64(3), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(getOp))) + testutil.Equals(t, float64(0), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(getRangeOp))) + testutil.Equals(t, float64(0), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(existsOp))) + testutil.Equals(t, float64(0), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(uploadOp))) + testutil.Equals(t, float64(0), promtest.ToFloat64(bkt.opsFailures.WithLabelValues(deleteOp))) + testutil.Equals(t, 7, promtest.CollectAndCount(bkt.opsFailures)) + testutil.Equals(t, 7, promtest.CollectAndCount(bkt.opsDuration)) + testutil.Assert(t, promtest.ToFloat64(bkt.lastSuccessfulUploadTime) > lastUpload) +} diff --git a/pkg/objstore/objtesting/acceptance_e2e_test.go b/pkg/objstore/objtesting/acceptance_e2e_test.go index 86045424ee..4cfda44c33 100644 --- a/pkg/objstore/objtesting/acceptance_e2e_test.go +++ b/pkg/objstore/objtesting/acceptance_e2e_test.go @@ -4,14 +4,9 @@ package objtesting import ( - "context" - "io/ioutil" - "sort" - "strings" "testing" "github.com/thanos-io/thanos/pkg/objstore" - "github.com/thanos-io/thanos/pkg/testutil" ) // TestObjStoreAcceptanceTest_e2e tests all known implementation against interface behaviour contract we agreed on. @@ -19,142 +14,5 @@ import ( // NOTE: This test assumes strong consistency, but in the same way it does not guarantee that if it passes, the // used object store is strongly consistent. func TestObjStore_AcceptanceTest_e2e(t *testing.T) { - ForeachStore(t, func(t *testing.T, bkt objstore.Bucket) { - ctx := context.Background() - - _, err := bkt.Get(ctx, "") - testutil.NotOk(t, err) - testutil.Assert(t, !bkt.IsObjNotFoundErr(err), "expected user error got not found %s", err) - - _, err = bkt.Get(ctx, "id1/obj_1.some") - testutil.NotOk(t, err) - testutil.Assert(t, bkt.IsObjNotFoundErr(err), "expected not found error got %s", err) - - ok, err := bkt.Exists(ctx, "id1/obj_1.some") - testutil.Ok(t, err) - testutil.Assert(t, !ok, "expected not exits") - - _, err = bkt.ObjectSize(ctx, "id1/obj_1.some") - testutil.NotOk(t, err) - testutil.Assert(t, bkt.IsObjNotFoundErr(err), "expected not found error but got %s", err) - - // Upload first object. - testutil.Ok(t, bkt.Upload(ctx, "id1/obj_1.some", strings.NewReader("@test-data@"))) - - // Double check we can immediately read it. - rc1, err := bkt.Get(ctx, "id1/obj_1.some") - testutil.Ok(t, err) - defer func() { testutil.Ok(t, rc1.Close()) }() - content, err := ioutil.ReadAll(rc1) - testutil.Ok(t, err) - testutil.Equals(t, "@test-data@", string(content)) - - // Check if we can get the correct size. - sz, err := bkt.ObjectSize(ctx, "id1/obj_1.some") - testutil.Ok(t, err) - testutil.Assert(t, sz == 11, "expected size to be equal to 11") - - rc2, err := bkt.GetRange(ctx, "id1/obj_1.some", 1, 3) - testutil.Ok(t, err) - defer func() { testutil.Ok(t, rc2.Close()) }() - content, err = ioutil.ReadAll(rc2) - testutil.Ok(t, err) - testutil.Equals(t, "tes", string(content)) - - // Unspecified range with offset. - rcUnspecifiedLen, err := bkt.GetRange(ctx, "id1/obj_1.some", 1, -1) - testutil.Ok(t, err) - defer func() { testutil.Ok(t, rcUnspecifiedLen.Close()) }() - content, err = ioutil.ReadAll(rcUnspecifiedLen) - testutil.Ok(t, err) - testutil.Equals(t, "test-data@", string(content)) - - // Out of band offset. Do not rely on outcome. - // NOTE: For various providers we have different outcome. - // * GCS is giving 416 status code - // * S3 errors immdiately with invalid range error. - // * inmem and filesystem are returning 0 bytes. - //rcOffset, err := bkt.GetRange(ctx, "id1/obj_1.some", 124141, 3) - - // Out of band length. We expect to read file fully. - rcLength, err := bkt.GetRange(ctx, "id1/obj_1.some", 3, 9999) - testutil.Ok(t, err) - defer func() { testutil.Ok(t, rcLength.Close()) }() - content, err = ioutil.ReadAll(rcLength) - testutil.Ok(t, err) - testutil.Equals(t, "st-data@", string(content)) - - ok, err = bkt.Exists(ctx, "id1/obj_1.some") - testutil.Ok(t, err) - testutil.Assert(t, ok, "expected exits") - - // Upload other objects. - testutil.Ok(t, bkt.Upload(ctx, "id1/obj_2.some", strings.NewReader("@test-data2@"))) - // Upload should be idempotent. - testutil.Ok(t, bkt.Upload(ctx, "id1/obj_2.some", strings.NewReader("@test-data2@"))) - testutil.Ok(t, bkt.Upload(ctx, "id1/obj_3.some", strings.NewReader("@test-data3@"))) - testutil.Ok(t, bkt.Upload(ctx, "id2/obj_4.some", strings.NewReader("@test-data4@"))) - testutil.Ok(t, bkt.Upload(ctx, "obj_5.some", strings.NewReader("@test-data5@"))) - - // Can we iter over items from top dir? - var seen []string - testutil.Ok(t, bkt.Iter(ctx, "", func(fn string) error { - seen = append(seen, fn) - return nil - })) - expected := []string{"obj_5.some", "id1/", "id2/"} - sort.Strings(expected) - sort.Strings(seen) - testutil.Equals(t, expected, seen) - - // Can we iter over items from id1/ dir? - seen = []string{} - testutil.Ok(t, bkt.Iter(ctx, "id1/", func(fn string) error { - seen = append(seen, fn) - return nil - })) - testutil.Equals(t, []string{"id1/obj_1.some", "id1/obj_2.some", "id1/obj_3.some"}, seen) - - // Can we iter over items from id1 dir? - seen = []string{} - testutil.Ok(t, bkt.Iter(ctx, "id1", func(fn string) error { - seen = append(seen, fn) - return nil - })) - testutil.Equals(t, []string{"id1/obj_1.some", "id1/obj_2.some", "id1/obj_3.some"}, seen) - - // Can we iter over items from not existing dir? - testutil.Ok(t, bkt.Iter(ctx, "id0", func(fn string) error { - t.Error("Not expected to loop through not existing directory") - t.FailNow() - - return nil - })) - - testutil.Ok(t, bkt.Delete(ctx, "id1/obj_2.some")) - - // Delete is expected to fail on non existing object. - // NOTE: Don't rely on this. S3 is not complying with this as GCS is. - // testutil.NotOk(t, bkt.Delete(ctx, "id1/obj_2.some")) - - // Can we iter over items from id1/ dir and see obj2 being deleted? - seen = []string{} - testutil.Ok(t, bkt.Iter(ctx, "id1/", func(fn string) error { - seen = append(seen, fn) - return nil - })) - testutil.Equals(t, []string{"id1/obj_1.some", "id1/obj_3.some"}, seen) - - testutil.Ok(t, bkt.Delete(ctx, "id2/obj_4.some")) - - seen = []string{} - testutil.Ok(t, bkt.Iter(ctx, "", func(fn string) error { - seen = append(seen, fn) - return nil - })) - expected = []string{"obj_5.some", "id1/"} - sort.Strings(expected) - sort.Strings(seen) - testutil.Equals(t, expected, seen) - }) + ForeachStore(t, objstore.AcceptanceTest) } diff --git a/pkg/objstore/objtesting/foreach.go b/pkg/objstore/objtesting/foreach.go index 97b0490977..e0c28cb4f6 100644 --- a/pkg/objstore/objtesting/foreach.go +++ b/pkg/objstore/objtesting/foreach.go @@ -16,7 +16,6 @@ import ( "github.com/thanos-io/thanos/pkg/objstore/azure" "github.com/thanos-io/thanos/pkg/objstore/cos" "github.com/thanos-io/thanos/pkg/objstore/gcs" - "github.com/thanos-io/thanos/pkg/objstore/inmem" "github.com/thanos-io/thanos/pkg/objstore/oss" "github.com/thanos-io/thanos/pkg/objstore/s3" "github.com/thanos-io/thanos/pkg/objstore/swift" @@ -48,7 +47,7 @@ func ForeachStore(t *testing.T, testFn func(t *testing.T, bkt objstore.Bucket)) // Mandatory Inmem. Not parallel, to detect problem early. if ok := t.Run("inmem", func(t *testing.T) { - testFn(t, inmem.NewBucket()) + testFn(t, objstore.NewInMemBucket()) }); !ok { return } diff --git a/pkg/objstore/oss/oss.go b/pkg/objstore/oss/oss.go index effc1e217a..5c081d7a5a 100644 --- a/pkg/objstore/oss/oss.go +++ b/pkg/objstore/oss/oss.go @@ -65,26 +65,16 @@ func NewTestBucket(t testing.TB) (objstore.Bucket, func(), error) { return NewTestBucketFromConfig(t, c, false) } -func calculateChunks(name string, r io.Reader) (int, int64, error) { - switch f := r.(type) { - case *os.File: - if fileInfo, err := f.Stat(); err == nil { - s := fileInfo.Size() - return int(math.Floor(float64(s) / PartSize)), s % PartSize, nil - } - case *strings.Reader: - return int(math.Floor(float64(f.Size()) / PartSize)), f.Size() % PartSize, nil - } - return -1, 0, errors.New("unsupported implement of io.Reader") -} - // Upload the contents of the reader as an object into the bucket. -func (b *Bucket) Upload(ctx context.Context, name string, r io.Reader) error { - chunksnum, lastslice, err := calculateChunks(name, r) +func (b *Bucket) Upload(_ context.Context, name string, r io.Reader) error { + // TODO(https://github.com/thanos-io/thanos/issues/678): Remove guessing length when minio provider will support multipart upload without this. + size, err := objstore.TryToGetSize(r) if err != nil { - return err + return errors.Wrapf(err, "failed to get size apriori to upload %s", name) } + chunksnum, lastslice := int(math.Floor(float64(size)/PartSize)), size%PartSize + ncloser := ioutil.NopCloser(r) switch chunksnum { case 0: diff --git a/pkg/objstore/s3/s3.go b/pkg/objstore/s3/s3.go index d924eeb01f..285bebaf7d 100644 --- a/pkg/objstore/s3/s3.go +++ b/pkg/objstore/s3/s3.go @@ -149,6 +149,7 @@ func NewBucketWithConfig(logger log.Logger, config Config, component string) (*B DualStack: true, }).DialContext, MaxIdleConns: 100, + MaxIdleConnsPerHost: 100, IdleConnTimeout: time.Duration(config.HTTPConfig.IdleConnTimeout), TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, @@ -287,7 +288,7 @@ func (b *Bucket) GetRange(ctx context.Context, name string, off, length int64) ( } // Exists checks if the given object exists. -func (b *Bucket) Exists(ctx context.Context, name string) (bool, error) { +func (b *Bucket) Exists(_ context.Context, name string) (bool, error) { _, err := b.client.StatObject(b.name, name, minio.StatObjectOptions{}) if err != nil { if b.IsObjNotFoundErr(err) { @@ -299,24 +300,14 @@ func (b *Bucket) Exists(ctx context.Context, name string) (bool, error) { return true, nil } -func (b *Bucket) guessFileSize(name string, r io.Reader) int64 { - if f, ok := r.(*os.File); ok { - fileInfo, err := f.Stat() - if err == nil { - return fileInfo.Size() - } - level.Warn(b.logger).Log("msg", "could not stat file for multipart upload", "name", name, "err", err) - return -1 - } - - level.Warn(b.logger).Log("msg", "could not guess file size for multipart upload", "name", name) - return -1 -} - // Upload the contents of the reader as an object into the bucket. func (b *Bucket) Upload(ctx context.Context, name string, r io.Reader) error { // TODO(https://github.com/thanos-io/thanos/issues/678): Remove guessing length when minio provider will support multipart upload without this. - size := b.guessFileSize(name, r) + size, err := objstore.TryToGetSize(r) + if err != nil { + level.Warn(b.logger).Log("msg", "could not guess file size for multipart upload; upload might be not optimized", "name", name, "err", err) + size = -1 + } // partSize cannot be larger than object size. partSize := b.partSize @@ -342,7 +333,7 @@ func (b *Bucket) Upload(ctx context.Context, name string, r io.Reader) error { } // ObjectSize returns the size of the specified object. -func (b *Bucket) ObjectSize(ctx context.Context, name string) (uint64, error) { +func (b *Bucket) ObjectSize(_ context.Context, name string) (uint64, error) { objInfo, err := b.client.StatObject(b.name, name, minio.StatObjectOptions{}) if err != nil { return 0, err @@ -351,7 +342,7 @@ func (b *Bucket) ObjectSize(ctx context.Context, name string) (uint64, error) { } // Delete removes the object with the given name. -func (b *Bucket) Delete(ctx context.Context, name string) error { +func (b *Bucket) Delete(_ context.Context, name string) error { return b.client.RemoveObject(b.name, name) } diff --git a/pkg/objstore/testing.go b/pkg/objstore/testing.go index 9e9a864b91..a33475db09 100644 --- a/pkg/objstore/testing.go +++ b/pkg/objstore/testing.go @@ -5,11 +5,29 @@ package objstore import ( "context" + "fmt" + "io/ioutil" + "math/rand" + "sort" "strings" "sync" "testing" + "time" + + "github.com/thanos-io/thanos/pkg/testutil" ) +func CreateTemporaryTestBucketName(t testing.TB) string { + src := rand.NewSource(time.Now().UnixNano()) + + // Bucket name need to conform: https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-s3-bucket-naming-requirements.html. + name := strings.Replace(strings.Replace(fmt.Sprintf("test_%x_%s", src.Int63(), strings.ToLower(t.Name())), "_", "-", -1), "/", "-", -1) + if len(name) >= 63 { + name = name[:63] + } + return name +} + // EmptyBucket deletes all objects from bucket. This operation is required to properly delete bucket as a whole. // It is used for testing only. // TODO(bplotka): Add retries. @@ -44,3 +62,158 @@ func EmptyBucket(t testing.TB, ctx context.Context, bkt Bucket) { } wg.Wait() } + +func WithNoopInstr(bkt Bucket) InstrumentedBucket { + return noopInstrumentedBucket{Bucket: bkt} +} + +type noopInstrumentedBucket struct { + Bucket +} + +func (b noopInstrumentedBucket) WithExpectedErrs(IsOpFailureExpectedFunc) Bucket { + return b +} + +func (b noopInstrumentedBucket) ReaderWithExpectedErrs(IsOpFailureExpectedFunc) BucketReader { + return b +} + +func AcceptanceTest(t *testing.T, bkt Bucket) { + ctx := context.Background() + + _, err := bkt.Get(ctx, "") + testutil.NotOk(t, err) + testutil.Assert(t, !bkt.IsObjNotFoundErr(err), "expected user error got not found %s", err) + + _, err = bkt.Get(ctx, "id1/obj_1.some") + testutil.NotOk(t, err) + testutil.Assert(t, bkt.IsObjNotFoundErr(err), "expected not found error got %s", err) + + ok, err := bkt.Exists(ctx, "id1/obj_1.some") + testutil.Ok(t, err) + testutil.Assert(t, !ok, "expected not exits") + + _, err = bkt.ObjectSize(ctx, "id1/obj_1.some") + testutil.NotOk(t, err) + testutil.Assert(t, bkt.IsObjNotFoundErr(err), "expected not found error but got %s", err) + + // Upload first object. + testutil.Ok(t, bkt.Upload(ctx, "id1/obj_1.some", strings.NewReader("@test-data@"))) + + // Double check we can immediately read it. + rc1, err := bkt.Get(ctx, "id1/obj_1.some") + testutil.Ok(t, err) + defer func() { testutil.Ok(t, rc1.Close()) }() + content, err := ioutil.ReadAll(rc1) + testutil.Ok(t, err) + testutil.Equals(t, "@test-data@", string(content)) + + // Check if we can get the correct size. + sz, err := bkt.ObjectSize(ctx, "id1/obj_1.some") + testutil.Ok(t, err) + testutil.Assert(t, sz == 11, "expected size to be equal to 11") + + rc2, err := bkt.GetRange(ctx, "id1/obj_1.some", 1, 3) + testutil.Ok(t, err) + defer func() { testutil.Ok(t, rc2.Close()) }() + content, err = ioutil.ReadAll(rc2) + testutil.Ok(t, err) + testutil.Equals(t, "tes", string(content)) + + // Unspecified range with offset. + rcUnspecifiedLen, err := bkt.GetRange(ctx, "id1/obj_1.some", 1, -1) + testutil.Ok(t, err) + defer func() { testutil.Ok(t, rcUnspecifiedLen.Close()) }() + content, err = ioutil.ReadAll(rcUnspecifiedLen) + testutil.Ok(t, err) + testutil.Equals(t, "test-data@", string(content)) + + // Out of band offset. Do not rely on outcome. + // NOTE: For various providers we have different outcome. + // * GCS is giving 416 status code + // * S3 errors immdiately with invalid range error. + // * inmem and filesystem are returning 0 bytes. + //rcOffset, err := bkt.GetRange(ctx, "id1/obj_1.some", 124141, 3) + + // Out of band length. We expect to read file fully. + rcLength, err := bkt.GetRange(ctx, "id1/obj_1.some", 3, 9999) + testutil.Ok(t, err) + defer func() { testutil.Ok(t, rcLength.Close()) }() + content, err = ioutil.ReadAll(rcLength) + testutil.Ok(t, err) + testutil.Equals(t, "st-data@", string(content)) + + ok, err = bkt.Exists(ctx, "id1/obj_1.some") + testutil.Ok(t, err) + testutil.Assert(t, ok, "expected exits") + + // Upload other objects. + testutil.Ok(t, bkt.Upload(ctx, "id1/obj_2.some", strings.NewReader("@test-data2@"))) + // Upload should be idempotent. + testutil.Ok(t, bkt.Upload(ctx, "id1/obj_2.some", strings.NewReader("@test-data2@"))) + testutil.Ok(t, bkt.Upload(ctx, "id1/obj_3.some", strings.NewReader("@test-data3@"))) + testutil.Ok(t, bkt.Upload(ctx, "id2/obj_4.some", strings.NewReader("@test-data4@"))) + testutil.Ok(t, bkt.Upload(ctx, "obj_5.some", strings.NewReader("@test-data5@"))) + + // Can we iter over items from top dir? + var seen []string + testutil.Ok(t, bkt.Iter(ctx, "", func(fn string) error { + seen = append(seen, fn) + return nil + })) + expected := []string{"obj_5.some", "id1/", "id2/"} + sort.Strings(expected) + sort.Strings(seen) + testutil.Equals(t, expected, seen) + + // Can we iter over items from id1/ dir? + seen = []string{} + testutil.Ok(t, bkt.Iter(ctx, "id1/", func(fn string) error { + seen = append(seen, fn) + return nil + })) + testutil.Equals(t, []string{"id1/obj_1.some", "id1/obj_2.some", "id1/obj_3.some"}, seen) + + // Can we iter over items from id1 dir? + seen = []string{} + testutil.Ok(t, bkt.Iter(ctx, "id1", func(fn string) error { + seen = append(seen, fn) + return nil + })) + testutil.Equals(t, []string{"id1/obj_1.some", "id1/obj_2.some", "id1/obj_3.some"}, seen) + + // Can we iter over items from not existing dir? + testutil.Ok(t, bkt.Iter(ctx, "id0", func(fn string) error { + t.Error("Not expected to loop through not existing directory") + t.FailNow() + + return nil + })) + + testutil.Ok(t, bkt.Delete(ctx, "id1/obj_2.some")) + + // Delete is expected to fail on non existing object. + // NOTE: Don't rely on this. S3 is not complying with this as GCS is. + // testutil.NotOk(t, bkt.Delete(ctx, "id1/obj_2.some")) + + // Can we iter over items from id1/ dir and see obj2 being deleted? + seen = []string{} + testutil.Ok(t, bkt.Iter(ctx, "id1/", func(fn string) error { + seen = append(seen, fn) + return nil + })) + testutil.Equals(t, []string{"id1/obj_1.some", "id1/obj_3.some"}, seen) + + testutil.Ok(t, bkt.Delete(ctx, "id2/obj_4.some")) + + seen = []string{} + testutil.Ok(t, bkt.Iter(ctx, "", func(fn string) error { + seen = append(seen, fn) + return nil + })) + expected = []string{"obj_5.some", "id1/"} + sort.Strings(expected) + sort.Strings(seen) + testutil.Equals(t, expected, seen) +} diff --git a/pkg/prober/http_test.go b/pkg/prober/http_test.go index e31368a0f3..eb3a69f3f6 100644 --- a/pkg/prober/http_test.go +++ b/pkg/prober/http_test.go @@ -13,6 +13,7 @@ import ( "github.com/go-kit/kit/log" "github.com/oklog/run" + "github.com/pkg/errors" "github.com/thanos-io/thanos/pkg/testutil" ) @@ -29,7 +30,7 @@ func TestHTTPProberReadinessInitialState(t *testing.T) { } func TestHTTPProberHealthyStatusSetting(t *testing.T) { - testError := fmt.Errorf("test error") + testError := errors.New("test error") p := NewHTTP() p.Healthy() @@ -42,7 +43,7 @@ func TestHTTPProberHealthyStatusSetting(t *testing.T) { } func TestHTTPProberReadyStatusSetting(t *testing.T) { - testError := fmt.Errorf("test error") + testError := errors.New("test error") p := NewHTTP() p.Ready() @@ -71,7 +72,7 @@ func TestHTTPProberMuxRegistering(t *testing.T) { var g run.Group g.Add(func() error { - return fmt.Errorf("serve probes %w", http.Serve(l, mux)) + return errors.Wrap(http.Serve(l, mux), "serve probes") }, func(err error) { t.Fatalf("server failed: %v", err) }) diff --git a/pkg/prober/intrumentation.go b/pkg/prober/intrumentation.go index 076996d88f..6c1d7b6540 100644 --- a/pkg/prober/intrumentation.go +++ b/pkg/prober/intrumentation.go @@ -7,6 +7,7 @@ import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/thanos-io/thanos/pkg/component" ) @@ -30,19 +31,14 @@ func NewInstrumentation(component component.Component, logger log.Logger, reg pr p := InstrumentationProbe{ component: component, logger: logger, - status: prometheus.NewGaugeVec(prometheus.GaugeOpts{ + status: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ Name: "status", - Help: "Represents status (0 indicates success, 1 indicates failure) of the component.", + Help: "Represents status (0 indicates failure, 1 indicates success) of the component.", ConstLabels: map[string]string{"component": component.String()}, }, []string{"check"}, ), } - - if reg != nil { - reg.MustRegister(p.status) - } - return &p } diff --git a/pkg/query/api/v1.go b/pkg/query/api/v1.go index 6595a9eb3d..bdadb0c78c 100644 --- a/pkg/query/api/v1.go +++ b/pkg/query/api/v1.go @@ -114,6 +114,7 @@ type API struct { enablePartialResponse bool replicaLabels []string reg prometheus.Registerer + storeSet *query.StoreSet defaultInstantQueryMaxSourceResolution time.Duration now func() time.Time @@ -123,6 +124,7 @@ type API struct { func NewAPI( logger log.Logger, reg *prometheus.Registry, + storeSet *query.StoreSet, qe *promql.Engine, c query.QueryableCreator, enableAutodownsampling bool, @@ -139,6 +141,7 @@ func NewAPI( enablePartialResponse: enablePartialResponse, replicaLabels: replicaLabels, reg: reg, + storeSet: storeSet, defaultInstantQueryMaxSourceResolution: defaultInstantQueryMaxSourceResolution, rulesRetriever: rr, @@ -179,6 +182,8 @@ func (api *API) Register(r *route.Router, tracer opentracing.Tracer, logger log. r.Post("/labels", instr("label_names", api.labelNames)) r.Get("/rules", instr("rules", api.rules)) + + r.Get("/stores", instr("stores", api.stores)) } type queryData struct { @@ -358,7 +363,7 @@ func (api *API) queryRange(r *http.Request) (interface{}, []error, *ApiError) { // For safety, limit the number of returned points per timeseries. // This is sufficient for 60s resolution for a week or 1h resolution for a year. if end.Sub(start)/step > 11000 { - err := errors.Errorf("exceeded maximum resolution of 11,000 points per timeseries. Try decreasing the query resolution (?step=XX)") + err := errors.New("exceeded maximum resolution of 11,000 points per timeseries. Try decreasing the query resolution (?step=XX)") return nil, nil, &ApiError{errorBadData, err} } @@ -432,7 +437,7 @@ func (api *API) labelValues(r *http.Request) (interface{}, []error, *ApiError) { name := route.Param(ctx, "name") if !model.LabelNameRE.MatchString(name) { - return nil, nil, &ApiError{errorBadData, fmt.Errorf("invalid label name: %q", name)} + return nil, nil, &ApiError{errorBadData, errors.Errorf("invalid label name: %q", name)} } enablePartialResponse, apiErr := api.parsePartialResponseParam(r) @@ -467,7 +472,7 @@ func (api *API) series(r *http.Request) (interface{}, []error, *ApiError) { } if len(r.Form["match[]"]) == 0 { - return nil, nil, &ApiError{errorBadData, fmt.Errorf("no match[] parameter provided")} + return nil, nil, &ApiError{errorBadData, errors.New("no match[] parameter provided")} } var start time.Time @@ -599,21 +604,21 @@ func parseTime(s string) (time.Time, error) { if t, err := time.Parse(time.RFC3339Nano, s); err == nil { return t, nil } - return time.Time{}, fmt.Errorf("cannot parse %q to a valid timestamp", s) + return time.Time{}, errors.Errorf("cannot parse %q to a valid timestamp", s) } func parseDuration(s string) (time.Duration, error) { if d, err := strconv.ParseFloat(s, 64); err == nil { ts := d * float64(time.Second) if ts > float64(math.MaxInt64) || ts < float64(math.MinInt64) { - return 0, fmt.Errorf("cannot parse %q to a valid duration. It overflows int64", s) + return 0, errors.Errorf("cannot parse %q to a valid duration. It overflows int64", s) } return time.Duration(ts), nil } if d, err := model.ParseDuration(s); err == nil { return time.Duration(d), nil } - return 0, fmt.Errorf("cannot parse %q to a valid duration", s) + return 0, errors.Errorf("cannot parse %q to a valid duration", s) } func (api *API) labelNames(r *http.Request) (interface{}, []error, *ApiError) { @@ -690,3 +695,11 @@ func (api *API) rules(r *http.Request) (interface{}, []error, *ApiError) { return res, warnings, nil } + +func (api *API) stores(r *http.Request) (interface{}, []error, *ApiError) { + statuses := make(map[string][]query.StoreStatus) + for _, status := range api.storeSet.GetStoreStatus() { + statuses[status.StoreType.String()] = append(statuses[status.StoreType.String()], status) + } + return statuses, nil, nil +} diff --git a/pkg/query/api/v1_test.go b/pkg/query/api/v1_test.go index 7f21f2b461..c400e3b4e7 100644 --- a/pkg/query/api/v1_test.go +++ b/pkg/query/api/v1_test.go @@ -52,34 +52,34 @@ func TestEndpoints(t *testing.T) { defer leaktest.CheckTimeout(t, 10*time.Second)() lbls := []labels.Labels{ - labels.Labels{ + { labels.Label{Name: "__name__", Value: "test_metric1"}, labels.Label{Name: "foo", Value: "bar"}, }, - labels.Labels{ + { labels.Label{Name: "__name__", Value: "test_metric1"}, labels.Label{Name: "foo", Value: "boo"}, }, - labels.Labels{ + { labels.Label{Name: "__name__", Value: "test_metric2"}, labels.Label{Name: "foo", Value: "boo"}, }, - labels.Labels{ + { labels.Label{Name: "__name__", Value: "test_metric_replica1"}, labels.Label{Name: "foo", Value: "bar"}, labels.Label{Name: "replica", Value: "a"}, }, - labels.Labels{ + { labels.Label{Name: "__name__", Value: "test_metric_replica1"}, labels.Label{Name: "foo", Value: "boo"}, labels.Label{Name: "replica", Value: "a"}, }, - labels.Labels{ + { labels.Label{Name: "__name__", Value: "test_metric_replica1"}, labels.Label{Name: "foo", Value: "boo"}, labels.Label{Name: "replica", Value: "b"}, }, - labels.Labels{ + { labels.Label{Name: "__name__", Value: "test_metric_replica1"}, labels.Label{Name: "foo", Value: "boo"}, labels.Label{Name: "replica1", Value: "a"}, diff --git a/pkg/query/config.go b/pkg/query/config.go index 3787695410..12918e614f 100644 --- a/pkg/query/config.go +++ b/pkg/query/config.go @@ -4,8 +4,13 @@ package query import ( + "fmt" + "net/url" + "strings" + "gopkg.in/yaml.v2" + "github.com/pkg/errors" http_util "github.com/thanos-io/thanos/pkg/http" ) @@ -39,3 +44,32 @@ func LoadConfigs(confYAML []byte) ([]Config, error) { } return queryCfg, nil } + +// BuildQueryConfig returns a query client configuration from a static address. +func BuildQueryConfig(queryAddrs []string) ([]Config, error) { + configs := make([]Config, 0, len(queryAddrs)) + for i, addr := range queryAddrs { + if addr == "" { + return nil, errors.Errorf("static querier address cannot be empty at index %d", i) + } + // If addr is missing schema, add http. + if !strings.Contains(addr, "://") { + addr = fmt.Sprintf("http://%s", addr) + } + u, err := url.Parse(addr) + if err != nil { + return nil, errors.Wrapf(err, "failed to parse addr %q", addr) + } + if u.Scheme != "http" && u.Scheme != "https" { + return nil, errors.Errorf("%q is not supported scheme for querier address", u.Scheme) + } + configs = append(configs, Config{ + EndpointsConfig: http_util.EndpointsConfig{ + Scheme: u.Scheme, + StaticAddresses: []string{u.Host}, + PathPrefix: u.Path, + }, + }) + } + return configs, nil +} diff --git a/pkg/query/config_test.go b/pkg/query/config_test.go new file mode 100644 index 0000000000..1169df0498 --- /dev/null +++ b/pkg/query/config_test.go @@ -0,0 +1,95 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package query + +import ( + "testing" + + "github.com/thanos-io/thanos/pkg/http" + "github.com/thanos-io/thanos/pkg/testutil" +) + +func TestBuildQueryConfig(t *testing.T) { + for _, tc := range []struct { + desc string + addresses []string + err bool + expected []Config + }{ + { + desc: "single addr without path", + addresses: []string{"localhost:9093"}, + expected: []Config{{ + EndpointsConfig: http.EndpointsConfig{ + StaticAddresses: []string{"localhost:9093"}, + Scheme: "http", + }, + }}, + }, + { + desc: "1st addr without path, 2nd with", + addresses: []string{"localhost:9093", "localhost:9094/prefix"}, + expected: []Config{ + { + EndpointsConfig: http.EndpointsConfig{ + StaticAddresses: []string{"localhost:9093"}, + Scheme: "http", + }, + }, + { + EndpointsConfig: http.EndpointsConfig{ + StaticAddresses: []string{"localhost:9094"}, + Scheme: "http", + PathPrefix: "/prefix", + }, + }, + }, + }, + { + desc: "single addr with path and http scheme", + addresses: []string{"http://localhost:9093"}, + expected: []Config{{ + EndpointsConfig: http.EndpointsConfig{ + StaticAddresses: []string{"localhost:9093"}, + Scheme: "http", + }, + }}, + }, + { + desc: "single addr with path and https scheme", + addresses: []string{"https://localhost:9093"}, + expected: []Config{{ + EndpointsConfig: http.EndpointsConfig{ + StaticAddresses: []string{"localhost:9093"}, + Scheme: "https", + }, + }}, + }, + { + desc: "not supported scheme", + addresses: []string{"ttp://localhost:9093"}, + err: true, + }, + { + desc: "invalid addr", + addresses: []string{"this is not a valid addr"}, + err: true, + }, + { + desc: "empty addr", + addresses: []string{""}, + err: true, + }, + } { + t.Run(tc.desc, func(t *testing.T) { + cfg, err := BuildQueryConfig(tc.addresses) + if tc.err { + testutil.NotOk(t, err) + return + } + + testutil.Equals(t, tc.expected, cfg) + }) + } +} diff --git a/pkg/query/internal/test-storeset-pre-v0.8.0/storeset.go b/pkg/query/internal/test-storeset-pre-v0.8.0/storeset.go index 326c50b80b..ce0bc729ae 100644 --- a/pkg/query/internal/test-storeset-pre-v0.8.0/storeset.go +++ b/pkg/query/internal/test-storeset-pre-v0.8.0/storeset.go @@ -19,6 +19,7 @@ import ( "github.com/go-kit/kit/log/level" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/pkg/labels" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/runutil" @@ -126,12 +127,12 @@ func (c *storeSetNodeCollector) Collect(ch chan<- prometheus.Metric) { // NewStoreSet returns a new set of stores from cluster peers and statically configured ones. func NewStoreSet( logger log.Logger, - reg *prometheus.Registry, + reg prometheus.Registerer, storeSpecs func() []StoreSpec, dialOpts []grpc.DialOption, unhealthyStoreTimeout time.Duration, ) *StoreSet { - storeNodeConnections := prometheus.NewGauge(prometheus.GaugeOpts{ + storeNodeConnections := promauto.With(reg).NewGauge(prometheus.GaugeOpts{ Name: "thanos_store_nodes_grpc_connections", Help: "Number indicating current number of gRPC connection to store nodes. This indicates also to how many stores query node have access to.", }) @@ -139,9 +140,6 @@ func NewStoreSet( if logger == nil { logger = log.NewNopLogger() } - if reg != nil { - reg.MustRegister(storeNodeConnections) - } if storeSpecs == nil { storeSpecs = func() []StoreSpec { return nil } } diff --git a/pkg/query/iter.go b/pkg/query/iter.go index a994b8216c..1ed3534ea7 100644 --- a/pkg/query/iter.go +++ b/pkg/query/iter.go @@ -18,12 +18,12 @@ import ( // promSeriesSet implements the SeriesSet interface of the Prometheus storage // package on top of our storepb SeriesSet. type promSeriesSet struct { - set storepb.SeriesSet - initiated bool - done bool + set storepb.SeriesSet + done bool mint, maxt int64 - aggr resAggr + aggrs []storepb.Aggr + initiated bool currLset []storepb.Label currChunks []storepb.AggrChunk @@ -39,7 +39,8 @@ func (s *promSeriesSet) Next() bool { return false } - // storage.Series are more strict then SeriesSet: It requires storage.Series to iterate over full series. + // storage.Series are more strict then SeriesSet: + // * It requires storage.Series to iterate over full series. s.currLset, s.currChunks = s.set.At() for { s.done = s.set.Next() @@ -52,14 +53,47 @@ func (s *promSeriesSet) Next() bool { } s.currChunks = append(s.currChunks, nextChunks...) } + + // Samples (so chunks as well) have to be sorted by time. + // TODO(bwplotka): Benchmark if we can do better. + // For example we could iterate in above loop and write our own binary search based insert sort. + // We could also remove duplicates in same loop. + sort.Slice(s.currChunks, func(i, j int) bool { + return s.currChunks[i].MinTime < s.currChunks[j].MinTime + }) + + // newChunkSeriesIterator will handle overlaps well, however we don't need to iterate over those samples, + // removed early duplicates here. + // TODO(bwplotka): Remove chunk duplicates on proxy level as well to avoid decoding those. + // https://github.com/thanos-io/thanos/issues/2546, consider skipping removal here then. + s.currChunks = removeExactDuplicates(s.currChunks) return true } +// removeExactDuplicates returns chunks without 1:1 duplicates. +// NOTE: input chunks has to be sorted by minTime. +func removeExactDuplicates(chks []storepb.AggrChunk) []storepb.AggrChunk { + if len(chks) <= 1 { + return chks + } + + ret := make([]storepb.AggrChunk, 0, len(chks)) + ret = append(ret, chks[0]) + + for _, c := range chks[1:] { + if ret[len(ret)-1].String() == c.String() { + continue + } + ret = append(ret, c) + } + return ret +} + func (s *promSeriesSet) At() storage.Series { if !s.initiated || s.set.Err() != nil { return nil } - return newChunkSeries(s.currLset, s.currChunks, s.mint, s.maxt, s.aggr) + return newChunkSeries(s.currLset, s.currChunks, s.mint, s.maxt, s.aggrs) } func (s *promSeriesSet) Err() error { @@ -98,6 +132,7 @@ func translateMatchers(ms ...*labels.Matcher) ([]storepb.LabelMatcher, error) { // storeSeriesSet implements a storepb SeriesSet against a list of storepb.Series. type storeSeriesSet struct { + // TODO(bwplotka): Don't buffer all, we have to buffer single series (to sort and dedup chunks), but nothing more. series []storepb.Series i int } @@ -119,8 +154,7 @@ func (storeSeriesSet) Err() error { } func (s storeSeriesSet) At() ([]storepb.Label, []storepb.AggrChunk) { - ser := s.series[s.i] - return ser.Labels, ser.Chunks + return s.series[s.i].Labels, s.series[s.i].Chunks } // chunkSeries implements storage.Series for a series on storepb types. @@ -128,20 +162,17 @@ type chunkSeries struct { lset labels.Labels chunks []storepb.AggrChunk mint, maxt int64 - aggr resAggr + aggrs []storepb.Aggr } -func newChunkSeries(lset []storepb.Label, chunks []storepb.AggrChunk, mint, maxt int64, aggr resAggr) *chunkSeries { - sort.Slice(chunks, func(i, j int) bool { - return chunks[i].MinTime < chunks[j].MinTime - }) - +// newChunkSeries allows to iterate over samples for each sorted and non-overlapped chunks. +func newChunkSeries(lset []storepb.Label, chunks []storepb.AggrChunk, mint, maxt int64, aggrs []storepb.Aggr) *chunkSeries { return &chunkSeries{ lset: storepb.LabelsToPromLabels(lset), chunks: chunks, mint: mint, maxt: maxt, - aggr: aggr, + aggrs: aggrs, } } @@ -153,33 +184,47 @@ func (s *chunkSeries) Iterator() storage.SeriesIterator { var sit storage.SeriesIterator its := make([]chunkenc.Iterator, 0, len(s.chunks)) - switch s.aggr { - case resAggrCount: - for _, c := range s.chunks { - its = append(its, getFirstIterator(c.Count, c.Raw)) - } - sit = newChunkSeriesIterator(its) - case resAggrSum: - for _, c := range s.chunks { - its = append(its, getFirstIterator(c.Sum, c.Raw)) - } - sit = newChunkSeriesIterator(its) - case resAggrMin: - for _, c := range s.chunks { - its = append(its, getFirstIterator(c.Min, c.Raw)) - } - sit = newChunkSeriesIterator(its) - case resAggrMax: - for _, c := range s.chunks { - its = append(its, getFirstIterator(c.Max, c.Raw)) - } - sit = newChunkSeriesIterator(its) - case resAggrCounter: - for _, c := range s.chunks { - its = append(its, getFirstIterator(c.Counter, c.Raw)) + if len(s.aggrs) == 1 { + switch s.aggrs[0] { + case storepb.Aggr_COUNT: + for _, c := range s.chunks { + its = append(its, getFirstIterator(c.Count, c.Raw)) + } + sit = newChunkSeriesIterator(its) + case storepb.Aggr_SUM: + for _, c := range s.chunks { + its = append(its, getFirstIterator(c.Sum, c.Raw)) + } + sit = newChunkSeriesIterator(its) + case storepb.Aggr_MIN: + for _, c := range s.chunks { + its = append(its, getFirstIterator(c.Min, c.Raw)) + } + sit = newChunkSeriesIterator(its) + case storepb.Aggr_MAX: + for _, c := range s.chunks { + its = append(its, getFirstIterator(c.Max, c.Raw)) + } + sit = newChunkSeriesIterator(its) + case storepb.Aggr_COUNTER: + for _, c := range s.chunks { + its = append(its, getFirstIterator(c.Counter, c.Raw)) + } + sit = downsample.NewApplyCounterResetsIterator(its...) + default: + return errSeriesIterator{err: errors.Errorf("unexpected result aggregate type %v", s.aggrs)} } - sit = downsample.NewCounterSeriesIterator(its...) - case resAggrAvg: + return newBoundedSeriesIterator(sit, s.mint, s.maxt) + } + + if len(s.aggrs) != 2 { + return errSeriesIterator{err: errors.Errorf("unexpected result aggregate type %v", s.aggrs)} + } + + switch { + case s.aggrs[0] == storepb.Aggr_SUM && s.aggrs[1] == storepb.Aggr_COUNT, + s.aggrs[0] == storepb.Aggr_COUNT && s.aggrs[1] == storepb.Aggr_SUM: + for _, c := range s.chunks { if c.Raw != nil { its = append(its, getFirstIterator(c.Raw)) @@ -190,7 +235,7 @@ func (s *chunkSeries) Iterator() storage.SeriesIterator { } sit = newChunkSeriesIterator(its) default: - return errSeriesIterator{err: errors.Errorf("unexpected result aggregate type %v", s.aggr)} + return errSeriesIterator{err: errors.Errorf("unexpected result aggregate type %v", s.aggrs)} } return newBoundedSeriesIterator(sit, s.mint, s.maxt) } @@ -282,7 +327,6 @@ type chunkSeriesIterator struct { func newChunkSeriesIterator(cs []chunkenc.Iterator) storage.SeriesIterator { if len(cs) == 0 { // This should not happen. StoreAPI implementations should not send empty results. - // NOTE(bplotka): Metric, err log here? return errSeriesIterator{} } return &chunkSeriesIterator{chunks: cs} @@ -332,6 +376,7 @@ func (it *chunkSeriesIterator) Err() error { type dedupSeriesSet struct { set storage.SeriesSet replicaLabels map[string]struct{} + isCounter bool replicas []storage.Series lset labels.Labels @@ -339,8 +384,8 @@ type dedupSeriesSet struct { ok bool } -func newDedupSeriesSet(set storage.SeriesSet, replicaLabels map[string]struct{}) storage.SeriesSet { - s := &dedupSeriesSet{set: set, replicaLabels: replicaLabels} +func newDedupSeriesSet(set storage.SeriesSet, replicaLabels map[string]struct{}, isCounter bool) storage.SeriesSet { + s := &dedupSeriesSet{set: set, replicaLabels: replicaLabels, isCounter: isCounter} s.ok = s.set.Next() if s.ok { s.peek = s.set.At() @@ -400,11 +445,10 @@ func (s *dedupSeriesSet) At() storage.Series { if len(s.replicas) == 1 { return seriesWithLabels{Series: s.replicas[0], lset: s.lset} } - // Clients may store the series, so we must make a copy of the slice - // before advancing. + // Clients may store the series, so we must make a copy of the slice before advancing. repl := make([]storage.Series, len(s.replicas)) copy(repl, s.replicas) - return newDedupSeries(s.lset, repl...) + return newDedupSeries(s.lset, repl, s.isCounter) } func (s *dedupSeriesSet) Err() error { @@ -421,44 +465,130 @@ func (s seriesWithLabels) Labels() labels.Labels { return s.lset } type dedupSeries struct { lset labels.Labels replicas []storage.Series + + isCounter bool } -func newDedupSeries(lset labels.Labels, replicas ...storage.Series) *dedupSeries { - return &dedupSeries{lset: lset, replicas: replicas} +func newDedupSeries(lset labels.Labels, replicas []storage.Series, isCounter bool) *dedupSeries { + return &dedupSeries{lset: lset, isCounter: isCounter, replicas: replicas} } func (s *dedupSeries) Labels() labels.Labels { return s.lset } -func (s *dedupSeries) Iterator() (it storage.SeriesIterator) { - it = s.replicas[0].Iterator() +func (s *dedupSeries) Iterator() storage.SeriesIterator { + var it adjustableSeriesIterator + if s.isCounter { + it = &counterErrAdjustSeriesIterator{SeriesIterator: s.replicas[0].Iterator()} + } else { + it = noopAdjustableSeriesIterator{SeriesIterator: s.replicas[0].Iterator()} + } + for _, o := range s.replicas[1:] { - it = newDedupSeriesIterator(it, o.Iterator()) + var replicaIter adjustableSeriesIterator + if s.isCounter { + replicaIter = &counterErrAdjustSeriesIterator{SeriesIterator: o.Iterator()} + } else { + replicaIter = noopAdjustableSeriesIterator{SeriesIterator: o.Iterator()} + } + it = newDedupSeriesIterator(it, replicaIter) } return it } +// adjustableSeriesIterator iterates over the data of a time series and allows to adjust current value based on +// given lastValue iterated. +type adjustableSeriesIterator interface { + storage.SeriesIterator + + // adjustAtValue allows to adjust value by implementation if needed knowing the last value. This is used by counter + // implementation which can adjust for obsolete counter value. + adjustAtValue(lastValue float64) +} + +type noopAdjustableSeriesIterator struct { + storage.SeriesIterator +} + +func (it noopAdjustableSeriesIterator) adjustAtValue(float64) {} + +// counterErrAdjustSeriesIterator is extendedSeriesIterator used when we deduplicate counter. +// It makes sure we always adjust for the latest seen last counter value for all replicas. +// Let's consider following example: +// +// Replica 1 counter scrapes: 20 30 40 Nan - 0 5 +// Replica 2 counter scrapes: 25 35 45 Nan - 2 +// +// Now for downsampling purposes we are accounting the resets so our replicas before going to dedup iterator looks like this: +// +// Replica 1 counter total: 20 30 40 - - 40 45 +// Replica 2 counter total: 25 35 45 - - 47 +// +// Now if at any point we will switch our focus from replica 2 to replica 1 we will experience lower value than previous, +// which will trigger false positive counter reset in PromQL. +// +// We mitigate this by taking allowing invoking AdjustAtValue which adjust the value in case of last value being larger than current at. +// (Counter cannot go down) +// +// This is to mitigate https://github.com/thanos-io/thanos/issues/2401. +// TODO(bwplotka): Find better deduplication algorithm that does not require knowledge if the given +// series is counter or not: https://github.com/thanos-io/thanos/issues/2547. +type counterErrAdjustSeriesIterator struct { + storage.SeriesIterator + + errAdjust float64 +} + +func (it *counterErrAdjustSeriesIterator) adjustAtValue(lastValue float64) { + _, v := it.At() + if lastValue > v { + // This replica has obsolete value (did not see the correct "end" of counter value before app restart). Adjust. + it.errAdjust += lastValue - v + } +} + +func (it *counterErrAdjustSeriesIterator) At() (int64, float64) { + t, v := it.SeriesIterator.At() + return t, v + it.errAdjust +} + type dedupSeriesIterator struct { - a, b storage.SeriesIterator + a, b adjustableSeriesIterator + + aok, bok bool + + // TODO(bwplotka): Don't base on LastT, but on detected scrape interval. This will allow us to be more + // responsive to gaps: https://github.com/thanos-io/thanos/issues/981, let's do it in next PR. + lastT int64 + lastV float64 - aok, bok bool - lastT int64 penA, penB int64 useA bool } -func newDedupSeriesIterator(a, b storage.SeriesIterator) *dedupSeriesIterator { +func newDedupSeriesIterator(a, b adjustableSeriesIterator) *dedupSeriesIterator { return &dedupSeriesIterator{ a: a, b: b, lastT: math.MinInt64, - aok: true, - bok: true, + lastV: float64(math.MinInt64), + aok: a.Next(), + bok: b.Next(), } } func (it *dedupSeriesIterator) Next() bool { + lastValue := it.lastV + lastUseA := it.useA + defer func() { + if it.useA != lastUseA { + // We switched replicas. + // Ensure values are correct bases on value before At. + it.adjustAtValue(lastValue) + } + }() + // Advance both iterators to at least the next highest timestamp plus the potential penalty. if it.aok { it.aok = it.a.Seek(it.lastT + 1 + it.penA) @@ -466,18 +596,19 @@ func (it *dedupSeriesIterator) Next() bool { if it.bok { it.bok = it.b.Seek(it.lastT + 1 + it.penB) } + // Handle basic cases where one iterator is exhausted before the other. if !it.aok { it.useA = false if it.bok { - it.lastT, _ = it.b.At() + it.lastT, it.lastV = it.b.At() it.penB = 0 } return it.bok } if !it.bok { it.useA = true - it.lastT, _ = it.a.At() + it.lastT, it.lastV = it.a.At() it.penA = 0 return true } @@ -485,8 +616,8 @@ func (it *dedupSeriesIterator) Next() bool { // with the smaller timestamp. // The applied penalty potentially already skipped potential samples already // that would have resulted in exaggerated sampling frequency. - ta, _ := it.a.At() - tb, _ := it.b.At() + ta, va := it.a.At() + tb, vb := it.b.At() it.useA = ta <= tb @@ -497,29 +628,41 @@ func (it *dedupSeriesIterator) Next() bool { // timestamp assignment. // If we don't know a delta yet, we pick 5000 as a constant, which is based on the knowledge // that timestamps are in milliseconds and sampling frequencies typically multiple seconds long. - const initialPenality = 5000 + const initialPenalty = 5000 if it.useA { if it.lastT != math.MinInt64 { it.penB = 2 * (ta - it.lastT) } else { - it.penB = initialPenality + it.penB = initialPenalty } it.penA = 0 it.lastT = ta + it.lastV = va return true } if it.lastT != math.MinInt64 { it.penA = 2 * (tb - it.lastT) } else { - it.penA = initialPenality + it.penA = initialPenalty } it.penB = 0 it.lastT = tb + it.lastV = vb return true } +func (it *dedupSeriesIterator) adjustAtValue(lastValue float64) { + if it.aok { + it.a.adjustAtValue(lastValue) + } + if it.bok { + it.b.adjustAtValue(lastValue) + } +} + func (it *dedupSeriesIterator) Seek(t int64) bool { + // Don't use underlying Seek, but iterate over next to not miss gaps. for { ts, _ := it.At() if ts > 0 && ts >= t { diff --git a/pkg/query/querier.go b/pkg/query/querier.go index 898db30fc1..e437440ed7 100644 --- a/pkg/query/querier.go +++ b/pkg/query/querier.go @@ -52,7 +52,7 @@ type queryable struct { // Querier returns a new storage querier against the underlying proxy store API. func (q *queryable) Querier(ctx context.Context, mint, maxt int64) (storage.Querier, error) { - return newQuerier(ctx, q.logger, mint, maxt, q.replicaLabels, q.proxy, q.deduplicate, int64(q.maxResolutionMillis), q.partialResponse, q.skipChunks), nil + return newQuerier(ctx, q.logger, mint, maxt, q.replicaLabels, q.proxy, q.deduplicate, q.maxResolutionMillis, q.partialResponse, q.skipChunks), nil } type querier struct { @@ -124,10 +124,12 @@ func (s *seriesServer) Send(r *storepb.SeriesResponse) error { return nil } - if r.GetSeries() == nil { - return errors.New("no seriesSet") + if r.GetSeries() != nil { + s.seriesSet = append(s.seriesSet, *r.GetSeries()) + return nil } - s.seriesSet = append(s.seriesSet, *r.GetSeries()) + + // Unsupported field, skip. return nil } @@ -135,38 +137,27 @@ func (s *seriesServer) Context() context.Context { return s.ctx } -type resAggr int - -const ( - resAggrAvg resAggr = iota - resAggrCount - resAggrSum - resAggrMin - resAggrMax - resAggrCounter -) - // aggrsFromFunc infers aggregates of the underlying data based on the wrapping // function of a series selection. -func aggrsFromFunc(f string) ([]storepb.Aggr, resAggr) { +func aggrsFromFunc(f string) []storepb.Aggr { if f == "min" || strings.HasPrefix(f, "min_") { - return []storepb.Aggr{storepb.Aggr_MIN}, resAggrMin + return []storepb.Aggr{storepb.Aggr_MIN} } if f == "max" || strings.HasPrefix(f, "max_") { - return []storepb.Aggr{storepb.Aggr_MAX}, resAggrMax + return []storepb.Aggr{storepb.Aggr_MAX} } if f == "count" || strings.HasPrefix(f, "count_") { - return []storepb.Aggr{storepb.Aggr_COUNT}, resAggrCount + return []storepb.Aggr{storepb.Aggr_COUNT} } // f == "sum" falls through here since we want the actual samples. if strings.HasPrefix(f, "sum_") { - return []storepb.Aggr{storepb.Aggr_SUM}, resAggrSum + return []storepb.Aggr{storepb.Aggr_SUM} } if f == "increase" || f == "rate" { - return []storepb.Aggr{storepb.Aggr_COUNTER}, resAggrCounter + return []storepb.Aggr{storepb.Aggr_COUNTER} } // In the default case, we retrieve count and sum to compute an average. - return []storepb.Aggr{storepb.Aggr_COUNT, storepb.Aggr_SUM}, resAggrAvg + return []storepb.Aggr{storepb.Aggr_COUNT, storepb.Aggr_SUM} } func (q *querier) Select(params *storage.SelectParams, ms ...*labels.Matcher) (storage.SeriesSet, storage.Warnings, error) { @@ -193,7 +184,7 @@ func (q *querier) Select(params *storage.SelectParams, ms ...*labels.Matcher) (s return nil, nil, errors.Wrap(err, "convert matchers") } - queryAggrs, resAggr := aggrsFromFunc(params.Func) + aggrs := aggrsFromFunc(params.Func) resp := &seriesServer{ctx: ctx} if err := q.proxy.Series(&storepb.SeriesRequest{ @@ -201,7 +192,7 @@ func (q *querier) Select(params *storage.SelectParams, ms ...*labels.Matcher) (s MaxTime: params.End, Matchers: sms, MaxResolutionWindow: q.maxResolutionMillis, - Aggregates: queryAggrs, + Aggregates: aggrs, PartialResponseDisabled: !q.partialResponse, SkipChunks: q.skipChunks, }, resp); err != nil { @@ -216,10 +207,10 @@ func (q *querier) Select(params *storage.SelectParams, ms ...*labels.Matcher) (s if !q.isDedupEnabled() { // Return data without any deduplication. return &promSeriesSet{ - mint: q.mint, - maxt: q.maxt, - set: newStoreSeriesSet(resp.seriesSet), - aggr: resAggr, + mint: q.mint, + maxt: q.maxt, + set: newStoreSeriesSet(resp.seriesSet), + aggrs: aggrs, }, warns, nil } @@ -228,16 +219,16 @@ func (q *querier) Select(params *storage.SelectParams, ms ...*labels.Matcher) (s sortDedupLabels(resp.seriesSet, q.replicaLabels) set := &promSeriesSet{ - mint: q.mint, - maxt: q.maxt, - set: newStoreSeriesSet(resp.seriesSet), - aggr: resAggr, + mint: q.mint, + maxt: q.maxt, + set: newStoreSeriesSet(resp.seriesSet), + aggrs: aggrs, } // The merged series set assembles all potentially-overlapping time ranges // of the same series into a single one. The series are ordered so that equal series // from different replicas are sequential. We can now deduplicate those. - return newDedupSeriesSet(set, q.replicaLabels), warns, nil + return newDedupSeriesSet(set, q.replicaLabels, len(aggrs) == 1 && aggrs[0] == storepb.Aggr_COUNTER), warns, nil } // sortDedupLabels re-sorts the set so that the same series with different replica diff --git a/pkg/query/querier_test.go b/pkg/query/querier_test.go index f5cf7a9558..7b49aaec7e 100644 --- a/pkg/query/querier_test.go +++ b/pkg/query/querier_test.go @@ -9,22 +9,33 @@ import ( "io/ioutil" "math" "math/rand" + "os" "reflect" + "sort" "strconv" "testing" - "time" "github.com/fortytw2/leaktest" + "github.com/go-kit/kit/log" "github.com/pkg/errors" "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/pkg/timestamp" + "github.com/prometheus/prometheus/pkg/value" "github.com/prometheus/prometheus/promql" "github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/tsdb/chunkenc" + "github.com/thanos-io/thanos/pkg/component" + "github.com/thanos-io/thanos/pkg/store" "github.com/thanos-io/thanos/pkg/store/storepb" "github.com/thanos-io/thanos/pkg/testutil" ) +type sample struct { + t int64 + v float64 +} + func TestQueryableCreator_MaxResolution(t *testing.T) { defer leaktest.CheckTimeout(t, 10*time.Second)() testProxy := &storeServer{resps: []*storepb.SeriesResponse{}} @@ -95,64 +106,28 @@ func TestQuerier_DownsampledData(t *testing.T) { testutil.Assert(t, len(ser) == 4, "should return 4 series (got %d)", len(ser)) exp := []promql.Series{ - promql.Series{ + { Metric: labels.FromStrings("zzz", "a"), - Points: []promql.Point{ - promql.Point{ - T: 100, - V: 1, - }, - promql.Point{ - T: 200, - V: 5, - }, - }, + Points: []promql.Point{{T: 100, V: 1}, {T: 200, V: 5}}, }, - promql.Series{ + { Metric: labels.FromStrings("zzz", "b"), - Points: []promql.Point{ - promql.Point{ - T: 100, - V: 3, - }, - promql.Point{ - T: 200, - V: 8, - }, - }, + Points: []promql.Point{{T: 100, V: 3}, {T: 200, V: 8}}, }, - promql.Series{ + { Metric: labels.FromStrings("zzz", "c"), // Test case: downsampling code adds all of the samples in the // 5 minute window of each series and pre-aggregates the data. However, // Prometheus engine code only takes the latest sample in each time window of // the retrieved data. Since we were operating in pre-aggregated data here, it lead // to overinflated values. - Points: []promql.Point{ - promql.Point{ - T: 100, - V: 128, - }, - promql.Point{ - T: 200, - V: 30, - }, - }, + Points: []promql.Point{{T: 100, V: 128}, {T: 200, V: 30}}, }, - promql.Series{ + { Metric: labels.FromStrings("zzz", "d"), // Test case: Prometheus engine in each time window selects the sample // which is closest to the boundaries and adds up the different dimensions. - Points: []promql.Point{ - promql.Point{ - T: 100, - V: 16, - }, - promql.Point{ - T: 200, - V: 30, - }, - }, + Points: []promql.Point{{T: 100, V: 16}, {T: 200, V: 30}}, }, } @@ -161,63 +136,661 @@ func TestQuerier_DownsampledData(t *testing.T) { } } -func TestQuerier_Series(t *testing.T) { - defer leaktest.CheckTimeout(t, 10*time.Second)() +var ( + realSeriesWithStaleMarkerMint int64 = 1587690000000 // 04/24/2020 01:00:00 GMT. + realSeriesWithStaleMarkerMaxt int64 = 1587693600000 // 04/24/2020 02:00:00 GMT. + expectedRealSeriesWithStaleMarkerReplica0 = []sample{ + {t: 1587690007139, v: 461993}, {t: 1587690022139, v: 462164}, {t: 1587690037139, v: 462409}, {t: 1587690052139, v: 462662}, {t: 1587690067139, v: 462824}, {t: 1587690082139, v: 462987}, {t: 1587690097155, v: 463108}, {t: 1587690112139, v: 463261}, {t: 1587690127139, v: 463465}, {t: 1587690142139, v: 463642}, + {t: 1587690157139, v: 463823}, {t: 1587690172139, v: 464065}, {t: 1587690187139, v: 464333}, {t: 1587690202139, v: 464566}, {t: 1587690217139, v: 464811}, {t: 1587690232140, v: 465032}, {t: 1587690247139, v: 465229}, {t: 1587690262139, v: 465445}, {t: 1587690277139, v: 465700}, {t: 1587690292139, v: 465884}, + {t: 1587690307139, v: 466083}, {t: 1587690322139, v: 466250}, {t: 1587690337150, v: 466534}, {t: 1587690352139, v: 466791}, {t: 1587690367139, v: 466970}, {t: 1587690382139, v: 467149}, {t: 1587690397139, v: 467265}, {t: 1587690412139, v: 467383}, {t: 1587690427139, v: 467647}, {t: 1587690442139, v: 467943}, + {t: 1587690457139, v: 468121}, {t: 1587690472139, v: 468294}, {t: 1587690487139, v: 468545}, {t: 1587690502139, v: 468676}, {t: 1587690517139, v: 468879}, {t: 1587690532139, v: 469154}, {t: 1587690547139, v: 469281}, {t: 1587690562139, v: 469512}, {t: 1587690577139, v: 469783}, {t: 1587690592139, v: 469964}, + {t: 1587690607139, v: 470171}, {t: 1587690622139, v: 470355}, {t: 1587690637139, v: 470656}, {t: 1587690652139, v: 470845}, {t: 1587690667139, v: 471077}, {t: 1587690682139, v: 471315}, {t: 1587690697139, v: 471535}, {t: 1587690712139, v: 471766}, {t: 1587690727139, v: 472002}, {t: 1587690742139, v: 472171}, + {t: 1587690757139, v: 472354}, {t: 1587690772139, v: 472736}, {t: 1587690787139, v: 472948}, {t: 1587690802139, v: 473259}, {t: 1587690817139, v: 473460}, {t: 1587690832139, v: 473753}, {t: 1587690847139, v: 474007}, {t: 1587690862139, v: 474286}, {t: 1587690877139, v: 474423}, {t: 1587690892139, v: 474788}, + {t: 1587690907139, v: 474925}, {t: 1587690922139, v: 475031}, {t: 1587690937139, v: 475316}, {t: 1587690952139, v: 475573}, {t: 1587690967139, v: 475784}, {t: 1587690982139, v: 475992}, {t: 1587690997139, v: 476341}, {t: 1587691012139, v: 476541}, {t: 1587691027139, v: 476890}, {t: 1587691042139, v: 477033}, + {t: 1587691057139, v: 477305}, {t: 1587691072139, v: 477577}, {t: 1587691087139, v: 477771}, {t: 1587691102139, v: 478012}, {t: 1587691117139, v: 478296}, {t: 1587691132139, v: 478559}, {t: 1587691147139, v: 478744}, {t: 1587691162139, v: 478950}, {t: 1587691177139, v: 479201}, {t: 1587691192139, v: 479388}, + {t: 1587691207139, v: 479638}, {t: 1587691222154, v: 479907}, {t: 1587691237139, v: 480008}, {t: 1587691252139, v: 480167}, {t: 1587691267139, v: 480472}, {t: 1587691282157, v: 480615}, {t: 1587691297139, v: 480771}, {t: 1587691312139, v: 481027}, {t: 1587691327139, v: 481212}, {t: 1587691342159, v: 481395}, + {t: 1587691357139, v: 481598}, {t: 1587691372139, v: 481786}, {t: 1587691387139, v: 482003}, {t: 1587691402141, v: 482236}, {t: 1587691417139, v: 482508}, {t: 1587691432139, v: 482636}, {t: 1587691447139, v: 482780}, {t: 1587691462139, v: 483059}, {t: 1587691477139, v: 483357}, {t: 1587691492139, v: 483566}, + {t: 1587691507139, v: 483711}, {t: 1587691522139, v: 483838}, {t: 1587691537139, v: 484091}, {t: 1587691552139, v: 484254}, {t: 1587691567139, v: 484479}, {t: 1587691582139, v: 484748}, {t: 1587691597139, v: 484978}, {t: 1587691612139, v: 485271}, {t: 1587691627139, v: 485488}, {t: 1587691642139, v: 485700}, + {t: 1587691657139, v: 485945}, {t: 1587691672139, v: 486228}, {t: 1587691687139, v: 486588}, {t: 1587691702139, v: 486691}, {t: 1587691717139, v: 486881}, {t: 1587691732139, v: 487046}, {t: 1587691747139, v: 487291}, {t: 1587691762177, v: 487410}, {t: 1587691777139, v: 487571}, {t: 1587691792139, v: 487799}, + {t: 1587691807139, v: 488050}, {t: 1587691822139, v: 488241}, {t: 1587691837139, v: 488424}, {t: 1587691852139, v: 488629}, {t: 1587691867139, v: 488875}, {t: 1587691882139, v: 489017}, {t: 1587691897139, v: 489254}, {t: 1587691912139, v: 489545}, {t: 1587691927139, v: 489778}, {t: 1587691942139, v: 489912}, + {t: 1587691957139, v: 490084}, {t: 1587691972139, v: 490364}, {t: 1587691987139, v: 490510}, {t: 1587692002139, v: 490744}, {t: 1587692017139, v: 490880}, {t: 1587692032139, v: 491025}, {t: 1587692047139, v: 491297}, {t: 1587692062155, v: 491557}, {t: 1587692077139, v: 491839}, {t: 1587692092139, v: 492065}, + {t: 1587692107139, v: 492234}, {t: 1587692122139, v: 492526}, {t: 1587692137139, v: 492767}, {t: 1587692152139, v: 492967}, {t: 1587692167139, v: 493218}, {t: 1587692182139, v: 493442}, {t: 1587692197139, v: 493647}, {t: 1587692212139, v: 493920}, {t: 1587692227139, v: 494170}, {t: 1587692242139, v: 494358}, + {t: 1587692257139, v: 494632}, {t: 1587692272139, v: 494800}, {t: 1587692287139, v: 495026}, {t: 1587692302139, v: 495222}, {t: 1587692317139, v: 495433}, {t: 1587692332139, v: 495677}, {t: 1587692347139, v: 495901}, {t: 1587692362139, v: 496107}, {t: 1587692377139, v: 496196}, {t: 1587692392139, v: 496245}, + {t: 1587692407139, v: 496300}, {t: 1587692422159, v: 496365}, {t: 1587692437139, v: 496401}, {t: 1587692452139, v: 496452}, {t: 1587692467139, v: 496532}, {t: 1587692482139, v: math.Float64frombits(value.StaleNaN)}, {t: 1587692542149, v: 5}, {t: 1587692557139, v: 101}, {t: 1587692572139, v: 312}, {t: 1587692587139, v: 508}, + {t: 1587692602144, v: 725}, {t: 1587692617139, v: 990}, {t: 1587692632139, v: 1178}, {t: 1587692647139, v: 1406}, {t: 1587692662154, v: 1640}, {t: 1587692677139, v: 1927}, {t: 1587692692139, v: 2103}, {t: 1587692707139, v: 2300}, {t: 1587692722139, v: 2482}, {t: 1587692737139, v: 2638}, {t: 1587692752139, v: 2806}, + {t: 1587692767139, v: 2979}, {t: 1587692782149, v: 3187}, {t: 1587692797139, v: 3441}, {t: 1587692812139, v: 3657}, {t: 1587692827139, v: 3827}, {t: 1587692842139, v: 3985}, {t: 1587692857139, v: 4195}, {t: 1587692872139, v: 4427}, {t: 1587692887139, v: 4646}, {t: 1587692902139, v: 4714}, {t: 1587692917153, v: 4872}, + {t: 1587692932139, v: 5131}, {t: 1587692947139, v: 5318}, {t: 1587692962139, v: 5571}, {t: 1587692977155, v: 5748}, {t: 1587692992139, v: 6030}, {t: 1587693007139, v: 6210}, {t: 1587693022139, v: 6399}, {t: 1587693037139, v: 6658}, {t: 1587693052139, v: 6896}, {t: 1587693067139, v: 7098}, {t: 1587693082139, v: 7341}, + {t: 1587693097139, v: 7495}, {t: 1587693112139, v: 7647}, {t: 1587693127139, v: 7830}, {t: 1587693142139, v: 8058}, {t: 1587693157139, v: 8209}, {t: 1587693172139, v: 8524}, {t: 1587693187139, v: 8712}, {t: 1587693202139, v: 8904}, {t: 1587693217139, v: 9103}, {t: 1587693232139, v: 9404}, {t: 1587693247155, v: 9556}, + {t: 1587693262139, v: 9777}, {t: 1587693277139, v: 9992}, {t: 1587693292139, v: 10268}, {t: 1587693307139, v: 10478}, {t: 1587693322139, v: 10754}, {t: 1587693337139, v: 10998}, {t: 1587693352139, v: 11249}, {t: 1587693367139, v: 11459}, {t: 1587693382139, v: 11778}, {t: 1587693397139, v: 12038}, + {t: 1587693412139, v: 12238}, {t: 1587693427139, v: 12450}, {t: 1587693442163, v: 12742}, {t: 1587693457139, v: 12945}, {t: 1587693472139, v: 13181}, {t: 1587693487139, v: 13440}, {t: 1587693502139, v: 13650}, {t: 1587693517139, v: 13966}, {t: 1587693532139, v: 14122}, {t: 1587693547139, v: 14327}, {t: 1587693562139, v: 14592}, + {t: 1587693577139, v: 14782}, {t: 1587693592139, v: 14956}, + } + expectedRealSeriesWithStaleMarkerReplica1 = []sample{ + {t: 1587690005791, v: 461968}, {t: 1587690020791, v: 462151}, {t: 1587690035797, v: 462336}, {t: 1587690050791, v: 462650}, {t: 1587690065791, v: 462813}, {t: 1587690080791, v: 462987}, {t: 1587690095791, v: 463095}, {t: 1587690110791, v: 463247}, {t: 1587690125791, v: 463440}, {t: 1587690140791, v: 463642}, {t: 1587690155791, v: 463811}, + {t: 1587690170791, v: 464027}, {t: 1587690185791, v: 464308}, {t: 1587690200791, v: 464514}, {t: 1587690215791, v: 464798}, {t: 1587690230791, v: 465018}, {t: 1587690245791, v: 465215}, {t: 1587690260813, v: 465431}, {t: 1587690275791, v: 465651}, {t: 1587690290791, v: 465870}, {t: 1587690305791, v: 466070}, {t: 1587690320792, v: 466248}, + {t: 1587690335791, v: 466506}, {t: 1587690350791, v: 466766}, {t: 1587690365791, v: 466970}, {t: 1587690380791, v: 467123}, {t: 1587690395791, v: 467265}, {t: 1587690410791, v: 467383}, {t: 1587690425791, v: 467629}, {t: 1587690440791, v: 467931}, {t: 1587690455791, v: 468097}, {t: 1587690470791, v: 468281}, {t: 1587690485791, v: 468477}, + {t: 1587690500791, v: 468649}, {t: 1587690515791, v: 468867}, {t: 1587690530791, v: 469150}, {t: 1587690545791, v: 469268}, {t: 1587690560791, v: 469488}, {t: 1587690575791, v: 469742}, {t: 1587690590791, v: 469951}, {t: 1587690605791, v: 470131}, {t: 1587690620791, v: 470337}, {t: 1587690635791, v: 470631}, {t: 1587690650791, v: 470832}, + {t: 1587690665791, v: 471077}, {t: 1587690680791, v: 471311}, {t: 1587690695791, v: 471473}, {t: 1587690710791, v: 471728}, {t: 1587690725791, v: 472002}, {t: 1587690740791, v: 472158}, {t: 1587690755791, v: 472329}, {t: 1587690770791, v: 472722}, {t: 1587690785791, v: 472925}, {t: 1587690800791, v: 473220}, {t: 1587690815791, v: 473460}, + {t: 1587690830791, v: 473748}, {t: 1587690845791, v: 473968}, {t: 1587690860791, v: 474261}, {t: 1587690875791, v: 474418}, {t: 1587690890791, v: 474726}, {t: 1587690905791, v: 474913}, {t: 1587690920791, v: 475031}, {t: 1587690935791, v: 475284}, {t: 1587690950791, v: 475563}, {t: 1587690965791, v: 475762}, {t: 1587690980791, v: 475945}, + {t: 1587690995791, v: 476302}, {t: 1587691010791, v: 476501}, {t: 1587691025791, v: 476849}, {t: 1587691040800, v: 477020}, {t: 1587691055791, v: 477280}, {t: 1587691070791, v: 477549}, {t: 1587691085791, v: 477758}, {t: 1587691100817, v: 477960}, {t: 1587691115791, v: 478261}, {t: 1587691130791, v: 478559}, {t: 1587691145791, v: 478704}, + {t: 1587691160804, v: 478950}, {t: 1587691175791, v: 479173}, {t: 1587691190791, v: 479368}, {t: 1587691205791, v: 479625}, {t: 1587691220805, v: 479866}, {t: 1587691235791, v: 480008}, {t: 1587691250791, v: 480155}, {t: 1587691265791, v: 480472}, {t: 1587691280811, v: 480598}, {t: 1587691295791, v: 480771}, {t: 1587691310791, v: 480996}, + {t: 1587691325791, v: 481200}, {t: 1587691340803, v: 481381}, {t: 1587691355791, v: 481584}, {t: 1587691370791, v: 481759}, {t: 1587691385791, v: 482003}, {t: 1587691400803, v: 482189}, {t: 1587691415791, v: 482457}, {t: 1587691430791, v: 482623}, {t: 1587691445791, v: 482768}, {t: 1587691460804, v: 483036}, {t: 1587691475791, v: 483322}, + {t: 1587691490791, v: 483566}, {t: 1587691505791, v: 483709}, {t: 1587691520807, v: 483838}, {t: 1587691535791, v: 484091}, {t: 1587691550791, v: 484236}, {t: 1587691565791, v: 484454}, {t: 1587691580816, v: 484710}, {t: 1587691595791, v: 484978}, {t: 1587691610791, v: 485271}, {t: 1587691625791, v: 485476}, {t: 1587691640792, v: 485640}, + {t: 1587691655791, v: 485921}, {t: 1587691670791, v: 486201}, {t: 1587691685791, v: 486555}, {t: 1587691700791, v: 486691}, {t: 1587691715791, v: 486831}, {t: 1587691730791, v: 487033}, {t: 1587691745791, v: 487268}, {t: 1587691760803, v: 487370}, {t: 1587691775791, v: 487571}, {t: 1587691790791, v: 487787}, {t: 1587691805791, v: 488036}, + {t: 1587691820791, v: 488241}, {t: 1587691835791, v: 488411}, {t: 1587691850791, v: 488625}, {t: 1587691865791, v: 488868}, {t: 1587691880791, v: 489005}, {t: 1587691895791, v: 489237}, {t: 1587691910791, v: 489545}, {t: 1587691925791, v: 489750}, {t: 1587691940791, v: 489899}, {t: 1587691955791, v: 490048}, {t: 1587691970791, v: 490364}, + {t: 1587691985791, v: 490485}, {t: 1587692000791, v: 490722}, {t: 1587692015791, v: 490866}, {t: 1587692030791, v: 491025}, {t: 1587692045791, v: 491286}, {t: 1587692060816, v: 491543}, {t: 1587692075791, v: 491787}, {t: 1587692090791, v: 492065}, {t: 1587692105791, v: 492223}, {t: 1587692120816, v: 492501}, {t: 1587692135791, v: 492767}, + {t: 1587692150791, v: 492955}, {t: 1587692165791, v: 493194}, {t: 1587692180792, v: 493402}, {t: 1587692195791, v: 493647}, {t: 1587692210791, v: 493897}, {t: 1587692225791, v: 494117}, {t: 1587692240805, v: 494356}, {t: 1587692255791, v: 494620}, {t: 1587692270791, v: 494762}, {t: 1587692285791, v: 495001}, {t: 1587692300805, v: 495222}, + {t: 1587692315791, v: 495393}, {t: 1587692330791, v: 495662}, {t: 1587692345791, v: 495875}, {t: 1587692360801, v: 496082}, {t: 1587692375791, v: 496196}, {t: 1587692390791, v: 496245}, {t: 1587692405791, v: 496295}, {t: 1587692420791, v: 496365}, {t: 1587692435791, v: 496401}, {t: 1587692450791, v: 496452}, {t: 1587692465791, v: 496491}, + {t: 1587692480791, v: 496544}, {t: 1587692495791, v: math.Float64frombits(value.StaleNaN)}, {t: 1587692555791, v: 75}, {t: 1587692570791, v: 308}, {t: 1587692585791, v: 508}, {t: 1587692600791, v: 701}, {t: 1587692615791, v: 985}, {t: 1587692630791, v: 1153}, {t: 1587692645791, v: 1365}, {t: 1587692660791, v: 1612}, {t: 1587692675803, v: 1922}, {t: 1587692690791, v: 2103}, + {t: 1587692705791, v: 2261}, {t: 1587692720791, v: 2469}, {t: 1587692735805, v: 2625}, {t: 1587692750791, v: 2801}, {t: 1587692765791, v: 2955}, {t: 1587692780791, v: 3187}, {t: 1587692795806, v: 3428}, {t: 1587692810791, v: 3657}, {t: 1587692825791, v: 3810}, {t: 1587692840791, v: 3968}, {t: 1587692855791, v: 4195}, {t: 1587692870791, v: 4414}, + {t: 1587692885791, v: 4646}, {t: 1587692900791, v: 4689}, {t: 1587692915791, v: 4847}, {t: 1587692930791, v: 5105}, {t: 1587692945791, v: 5309}, {t: 1587692960791, v: 5521}, {t: 1587692975791, v: 5695}, {t: 1587692990810, v: 6010}, {t: 1587693005791, v: 6210}, {t: 1587693020791, v: 6394}, {t: 1587693035791, v: 6597}, {t: 1587693050791, v: 6872}, + {t: 1587693065791, v: 7098}, {t: 1587693080791, v: 7329}, {t: 1587693095791, v: 7470}, {t: 1587693110791, v: 7634}, {t: 1587693125821, v: 7830}, {t: 1587693140791, v: 8034}, {t: 1587693155791, v: 8209}, {t: 1587693170791, v: 8499}, {t: 1587693185791, v: 8688}, {t: 1587693200791, v: 8893}, {t: 1587693215791, v: 9052}, {t: 1587693230791, v: 9379}, + {t: 1587693245791, v: 9544}, {t: 1587693260791, v: 9763}, {t: 1587693275791, v: 9974}, {t: 1587693290791, v: 10242}, {t: 1587693305791, v: 10464}, {t: 1587693320803, v: 10716}, {t: 1587693335791, v: 10975}, {t: 1587693350791, v: 11232}, {t: 1587693365791, v: 11459}, {t: 1587693380791, v: 11778}, {t: 1587693395804, v: 12007}, {t: 1587693410791, v: 12206}, + {t: 1587693425791, v: 12450}, {t: 1587693440791, v: 12693}, {t: 1587693455791, v: 12908}, {t: 1587693470791, v: 13158}, {t: 1587693485791, v: 13427}, {t: 1587693500791, v: 13603}, {t: 1587693515791, v: 13927}, {t: 1587693530816, v: 14122}, {t: 1587693545791, v: 14327}, {t: 1587693560791, v: 14579}, {t: 1587693575791, v: 14759}, {t: 1587693590791, v: 14956}, + } + expectedRealSeriesWithStaleMarkerDeduplicated = []sample{ + {t: 1587690005791, v: 461968}, {t: 1587690020791, v: 462151}, {t: 1587690035797, v: 462336}, {t: 1587690050791, v: 462650}, {t: 1587690065791, v: 462813}, {t: 1587690080791, v: 462987}, {t: 1587690095791, v: 463095}, {t: 1587690110791, v: 463247}, {t: 1587690125791, v: 463440}, {t: 1587690140791, v: 463642}, {t: 1587690155791, v: 463811}, + {t: 1587690170791, v: 464027}, {t: 1587690185791, v: 464308}, {t: 1587690200791, v: 464514}, {t: 1587690215791, v: 464798}, {t: 1587690230791, v: 465018}, {t: 1587690245791, v: 465215}, {t: 1587690260813, v: 465431}, {t: 1587690275791, v: 465651}, {t: 1587690290791, v: 465870}, {t: 1587690305791, v: 466070}, {t: 1587690320792, v: 466248}, + {t: 1587690335791, v: 466506}, {t: 1587690350791, v: 466766}, {t: 1587690365791, v: 466970}, {t: 1587690380791, v: 467123}, {t: 1587690395791, v: 467265}, {t: 1587690410791, v: 467383}, {t: 1587690425791, v: 467629}, {t: 1587690440791, v: 467931}, {t: 1587690455791, v: 468097}, {t: 1587690470791, v: 468281}, {t: 1587690485791, v: 468477}, + {t: 1587690500791, v: 468649}, {t: 1587690515791, v: 468867}, {t: 1587690530791, v: 469150}, {t: 1587690545791, v: 469268}, {t: 1587690560791, v: 469488}, {t: 1587690575791, v: 469742}, {t: 1587690590791, v: 469951}, {t: 1587690605791, v: 470131}, {t: 1587690620791, v: 470337}, {t: 1587690635791, v: 470631}, {t: 1587690650791, v: 470832}, + {t: 1587690665791, v: 471077}, {t: 1587690680791, v: 471311}, {t: 1587690695791, v: 471473}, {t: 1587690710791, v: 471728}, {t: 1587690725791, v: 472002}, {t: 1587690740791, v: 472158}, {t: 1587690755791, v: 472329}, {t: 1587690770791, v: 472722}, {t: 1587690785791, v: 472925}, {t: 1587690800791, v: 473220}, {t: 1587690815791, v: 473460}, + {t: 1587690830791, v: 473748}, {t: 1587690845791, v: 473968}, {t: 1587690860791, v: 474261}, {t: 1587690875791, v: 474418}, {t: 1587690890791, v: 474726}, {t: 1587690905791, v: 474913}, {t: 1587690920791, v: 475031}, {t: 1587690935791, v: 475284}, {t: 1587690950791, v: 475563}, {t: 1587690965791, v: 475762}, {t: 1587690980791, v: 475945}, + {t: 1587690995791, v: 476302}, {t: 1587691010791, v: 476501}, {t: 1587691025791, v: 476849}, {t: 1587691040800, v: 477020}, {t: 1587691055791, v: 477280}, {t: 1587691070791, v: 477549}, {t: 1587691085791, v: 477758}, {t: 1587691100817, v: 477960}, {t: 1587691115791, v: 478261}, {t: 1587691130791, v: 478559}, {t: 1587691145791, v: 478704}, + {t: 1587691160804, v: 478950}, {t: 1587691175791, v: 479173}, {t: 1587691190791, v: 479368}, {t: 1587691205791, v: 479625}, {t: 1587691220805, v: 479866}, {t: 1587691235791, v: 480008}, {t: 1587691250791, v: 480155}, {t: 1587691265791, v: 480472}, {t: 1587691280811, v: 480598}, {t: 1587691295791, v: 480771}, {t: 1587691310791, v: 480996}, + {t: 1587691325791, v: 481200}, {t: 1587691340803, v: 481381}, {t: 1587691355791, v: 481584}, {t: 1587691370791, v: 481759}, {t: 1587691385791, v: 482003}, {t: 1587691400803, v: 482189}, {t: 1587691415791, v: 482457}, {t: 1587691430791, v: 482623}, {t: 1587691445791, v: 482768}, {t: 1587691460804, v: 483036}, {t: 1587691475791, v: 483322}, + {t: 1587691490791, v: 483566}, {t: 1587691505791, v: 483709}, {t: 1587691520807, v: 483838}, {t: 1587691535791, v: 484091}, {t: 1587691550791, v: 484236}, {t: 1587691565791, v: 484454}, {t: 1587691580816, v: 484710}, {t: 1587691595791, v: 484978}, {t: 1587691610791, v: 485271}, {t: 1587691625791, v: 485476}, {t: 1587691640792, v: 485640}, + {t: 1587691655791, v: 485921}, {t: 1587691670791, v: 486201}, {t: 1587691685791, v: 486555}, {t: 1587691700791, v: 486691}, {t: 1587691715791, v: 486831}, {t: 1587691730791, v: 487033}, {t: 1587691745791, v: 487268}, {t: 1587691760803, v: 487370}, {t: 1587691775791, v: 487571}, {t: 1587691790791, v: 487787}, {t: 1587691805791, v: 488036}, + {t: 1587691820791, v: 488241}, {t: 1587691835791, v: 488411}, {t: 1587691850791, v: 488625}, {t: 1587691865791, v: 488868}, {t: 1587691880791, v: 489005}, {t: 1587691895791, v: 489237}, {t: 1587691910791, v: 489545}, {t: 1587691925791, v: 489750}, {t: 1587691940791, v: 489899}, {t: 1587691955791, v: 490048}, {t: 1587691970791, v: 490364}, + {t: 1587691985791, v: 490485}, {t: 1587692000791, v: 490722}, {t: 1587692015791, v: 490866}, {t: 1587692030791, v: 491025}, {t: 1587692045791, v: 491286}, {t: 1587692060816, v: 491543}, {t: 1587692075791, v: 491787}, {t: 1587692090791, v: 492065}, {t: 1587692105791, v: 492223}, {t: 1587692120816, v: 492501}, {t: 1587692135791, v: 492767}, + {t: 1587692150791, v: 492955}, {t: 1587692165791, v: 493194}, {t: 1587692180792, v: 493402}, {t: 1587692195791, v: 493647}, {t: 1587692210791, v: 493897}, {t: 1587692225791, v: 494117}, {t: 1587692240805, v: 494356}, {t: 1587692255791, v: 494620}, {t: 1587692270791, v: 494762}, {t: 1587692285791, v: 495001}, {t: 1587692300805, v: 495222}, + {t: 1587692315791, v: 495393}, {t: 1587692330791, v: 495662}, {t: 1587692345791, v: 495875}, {t: 1587692360801, v: 496082}, {t: 1587692375791, v: 496196}, {t: 1587692390791, v: 496245}, {t: 1587692405791, v: 496295}, {t: 1587692420791, v: 496365}, {t: 1587692435791, v: 496401}, {t: 1587692450791, v: 496452}, {t: 1587692465791, v: 496491}, + {t: 1587692480791, v: 496544}, {t: 1587692495791, v: math.Float64frombits(value.StaleNaN)}, {t: 1587692542149, v: 5}, {t: 1587692557139, v: 101}, {t: 1587692572139, v: 312}, {t: 1587692587139, v: 508}, {t: 1587692602144, v: 725}, {t: 1587692617139, v: 990}, {t: 1587692632139, v: 1178}, {t: 1587692647139, v: 1406}, {t: 1587692662154, v: 1640}, {t: 1587692677139, v: 1927}, + {t: 1587692692139, v: 2103}, {t: 1587692707139, v: 2300}, {t: 1587692722139, v: 2482}, {t: 1587692737139, v: 2638}, {t: 1587692752139, v: 2806}, {t: 1587692767139, v: 2979}, {t: 1587692782149, v: 3187}, {t: 1587692797139, v: 3441}, {t: 1587692812139, v: 3657}, {t: 1587692827139, v: 3827}, {t: 1587692842139, v: 3985}, {t: 1587692857139, v: 4195}, + {t: 1587692872139, v: 4427}, {t: 1587692887139, v: 4646}, {t: 1587692902139, v: 4714}, {t: 1587692917153, v: 4872}, {t: 1587692932139, v: 5131}, {t: 1587692947139, v: 5318}, {t: 1587692962139, v: 5571}, {t: 1587692977155, v: 5748}, {t: 1587692992139, v: 6030}, {t: 1587693007139, v: 6210}, {t: 1587693022139, v: 6399}, {t: 1587693037139, v: 6658}, + {t: 1587693052139, v: 6896}, {t: 1587693067139, v: 7098}, {t: 1587693082139, v: 7341}, {t: 1587693097139, v: 7495}, {t: 1587693112139, v: 7647}, {t: 1587693127139, v: 7830}, {t: 1587693142139, v: 8058}, {t: 1587693157139, v: 8209}, {t: 1587693172139, v: 8524}, {t: 1587693187139, v: 8712}, {t: 1587693202139, v: 8904}, {t: 1587693217139, v: 9103}, + {t: 1587693232139, v: 9404}, {t: 1587693247155, v: 9556}, {t: 1587693262139, v: 9777}, {t: 1587693277139, v: 9992}, {t: 1587693292139, v: 10268}, {t: 1587693307139, v: 10478}, {t: 1587693322139, v: 10754}, {t: 1587693337139, v: 10998}, {t: 1587693352139, v: 11249}, {t: 1587693367139, v: 11459}, {t: 1587693382139, v: 11778}, {t: 1587693397139, v: 12038}, + {t: 1587693412139, v: 12238}, {t: 1587693427139, v: 12450}, {t: 1587693442163, v: 12742}, {t: 1587693457139, v: 12945}, {t: 1587693472139, v: 13181}, {t: 1587693487139, v: 13440}, {t: 1587693502139, v: 13650}, {t: 1587693517139, v: 13966}, {t: 1587693532139, v: 14122}, {t: 1587693547139, v: 14327}, {t: 1587693562139, v: 14592}, + {t: 1587693577139, v: 14782}, {t: 1587693592139, v: 14956}, + } - testProxy := &storeServer{ - resps: []*storepb.SeriesResponse{ - // Expected sorted series per seriesSet input. However we Series API allows for single series being chunks across multiple frames. - // This should be handled here. - storeSeriesResponse(t, labels.FromStrings("a", "a"), []sample{{0, 0}, {2, 1}, {3, 2}}), - storepb.NewWarnSeriesResponse(errors.New("partial error")), - storeSeriesResponse(t, labels.FromStrings("a", "a"), []sample{{5, 5}, {6, 6}, {7, 7}}), - storeSeriesResponse(t, labels.FromStrings("a", "a"), []sample{{5, 5}, {6, 66}}), // Overlap samples for some reason. - storeSeriesResponse(t, labels.FromStrings("a", "b"), []sample{{2, 2}, {3, 3}, {4, 4}}, []sample{{1, 1}, {2, 2}, {3, 3}}), - storeSeriesResponse(t, labels.FromStrings("a", "c"), []sample{{100, 1}, {300, 3}, {400, 4}}), - }, + // For rate means that hints.func = rate. + expectedRealSeriesWithStaleMarkerReplica0ForRate = []sample{ + {t: 1587690007139, v: 461993}, {t: 1587690022139, v: 462164}, {t: 1587690037139, v: 462409}, {t: 1587690052139, v: 462662}, {t: 1587690067139, v: 462824}, {t: 1587690082139, v: 462987}, {t: 1587690097155, v: 463108}, {t: 1587690112139, v: 463261}, {t: 1587690127139, v: 463465}, {t: 1587690142139, v: 463642}, {t: 1587690157139, v: 463823}, + {t: 1587690172139, v: 464065}, {t: 1587690187139, v: 464333}, {t: 1587690202139, v: 464566}, {t: 1587690217139, v: 464811}, {t: 1587690232140, v: 465032}, {t: 1587690247139, v: 465229}, {t: 1587690262139, v: 465445}, {t: 1587690277139, v: 465700}, {t: 1587690292139, v: 465884}, {t: 1587690307139, v: 466083}, {t: 1587690322139, v: 466250}, + {t: 1587690337150, v: 466534}, {t: 1587690352139, v: 466791}, {t: 1587690367139, v: 466970}, {t: 1587690382139, v: 467149}, {t: 1587690397139, v: 467265}, {t: 1587690412139, v: 467383}, {t: 1587690427139, v: 467647}, {t: 1587690442139, v: 467943}, {t: 1587690457139, v: 468121}, {t: 1587690472139, v: 468294}, {t: 1587690487139, v: 468545}, + {t: 1587690502139, v: 468676}, {t: 1587690517139, v: 468879}, {t: 1587690532139, v: 469154}, {t: 1587690547139, v: 469281}, {t: 1587690562139, v: 469512}, {t: 1587690577139, v: 469783}, {t: 1587690592139, v: 469964}, {t: 1587690607139, v: 470171}, {t: 1587690622139, v: 470355}, {t: 1587690637139, v: 470656}, {t: 1587690652139, v: 470845}, + {t: 1587690667139, v: 471077}, {t: 1587690682139, v: 471315}, {t: 1587690697139, v: 471535}, {t: 1587690712139, v: 471766}, {t: 1587690727139, v: 472002}, {t: 1587690742139, v: 472171}, {t: 1587690757139, v: 472354}, {t: 1587690772139, v: 472736}, {t: 1587690787139, v: 472948}, {t: 1587690802139, v: 473259}, {t: 1587690817139, v: 473460}, + {t: 1587690832139, v: 473753}, {t: 1587690847139, v: 474007}, {t: 1587690862139, v: 474286}, {t: 1587690877139, v: 474423}, {t: 1587690892139, v: 474788}, {t: 1587690907139, v: 474925}, {t: 1587690922139, v: 475031}, {t: 1587690937139, v: 475316}, {t: 1587690952139, v: 475573}, {t: 1587690967139, v: 475784}, {t: 1587690982139, v: 475992}, + {t: 1587690997139, v: 476341}, {t: 1587691012139, v: 476541}, {t: 1587691027139, v: 476890}, {t: 1587691042139, v: 477033}, {t: 1587691057139, v: 477305}, {t: 1587691072139, v: 477577}, {t: 1587691087139, v: 477771}, {t: 1587691102139, v: 478012}, {t: 1587691117139, v: 478296}, {t: 1587691132139, v: 478559}, {t: 1587691147139, v: 478744}, + {t: 1587691162139, v: 478950}, {t: 1587691177139, v: 479201}, {t: 1587691192139, v: 479388}, {t: 1587691207139, v: 479638}, {t: 1587691222154, v: 479907}, {t: 1587691237139, v: 480008}, {t: 1587691252139, v: 480167}, {t: 1587691267139, v: 480472}, {t: 1587691282157, v: 480615}, {t: 1587691297139, v: 480771}, {t: 1587691312139, v: 481027}, + {t: 1587691327139, v: 481212}, {t: 1587691342159, v: 481395}, {t: 1587691357139, v: 481598}, {t: 1587691372139, v: 481786}, {t: 1587691387139, v: 482003}, {t: 1587691402141, v: 482236}, {t: 1587691417139, v: 482508}, {t: 1587691432139, v: 482636}, {t: 1587691447139, v: 482780}, {t: 1587691462139, v: 483059}, {t: 1587691477139, v: 483357}, + {t: 1587691492139, v: 483566}, {t: 1587691507139, v: 483711}, {t: 1587691522139, v: 483838}, {t: 1587691537139, v: 484091}, {t: 1587691552139, v: 484254}, {t: 1587691567139, v: 484479}, {t: 1587691582139, v: 484748}, {t: 1587691597139, v: 484978}, {t: 1587691612139, v: 485271}, {t: 1587691627139, v: 485488}, {t: 1587691642139, v: 485700}, + {t: 1587691657139, v: 485945}, {t: 1587691672139, v: 486228}, {t: 1587691687139, v: 486588}, {t: 1587691702139, v: 486691}, {t: 1587691717139, v: 486881}, {t: 1587691732139, v: 487046}, {t: 1587691747139, v: 487291}, {t: 1587691762177, v: 487410}, {t: 1587691777139, v: 487571}, {t: 1587691792139, v: 487799}, {t: 1587691807139, v: 488050}, + {t: 1587691822139, v: 488241}, {t: 1587691837139, v: 488424}, {t: 1587691852139, v: 488629}, {t: 1587691867139, v: 488875}, {t: 1587691882139, v: 489017}, {t: 1587691897139, v: 489254}, {t: 1587691912139, v: 489545}, {t: 1587691927139, v: 489778}, {t: 1587691942139, v: 489912}, {t: 1587691957139, v: 490084}, {t: 1587691972139, v: 490364}, + {t: 1587691987139, v: 490510}, {t: 1587692002139, v: 490744}, {t: 1587692017139, v: 490880}, {t: 1587692032139, v: 491025}, {t: 1587692047139, v: 491297}, {t: 1587692062155, v: 491557}, {t: 1587692077139, v: 491839}, {t: 1587692092139, v: 492065}, {t: 1587692107139, v: 492234}, {t: 1587692122139, v: 492526}, {t: 1587692137139, v: 492767}, + {t: 1587692152139, v: 492967}, {t: 1587692167139, v: 493218}, {t: 1587692182139, v: 493442}, {t: 1587692197139, v: 493647}, {t: 1587692212139, v: 493920}, {t: 1587692227139, v: 494170}, {t: 1587692242139, v: 494358}, {t: 1587692257139, v: 494632}, {t: 1587692272139, v: 494800}, {t: 1587692287139, v: 495026}, {t: 1587692302139, v: 495222}, + {t: 1587692317139, v: 495433}, {t: 1587692332139, v: 495677}, {t: 1587692347139, v: 495901}, {t: 1587692362139, v: 496107}, {t: 1587692377139, v: 496196}, {t: 1587692392139, v: 496245}, {t: 1587692407139, v: 496300}, {t: 1587692422159, v: 496365}, {t: 1587692437139, v: 496401}, {t: 1587692452139, v: 496452}, {t: 1587692467139, v: 496532}, + {t: 1587692542149, v: 496537}, {t: 1587692557139, v: 496633}, {t: 1587692572139, v: 496844}, {t: 1587692587139, v: 497040}, {t: 1587692602144, v: 497257}, {t: 1587692617139, v: 497522}, {t: 1587692632139, v: 497710}, {t: 1587692647139, v: 497938}, {t: 1587692662154, v: 498172}, {t: 1587692677139, v: 498459}, {t: 1587692692139, v: 498635}, + {t: 1587692707139, v: 498832}, {t: 1587692722139, v: 499014}, {t: 1587692737139, v: 499170}, {t: 1587692752139, v: 499338}, {t: 1587692767139, v: 499511}, {t: 1587692782149, v: 499719}, {t: 1587692797139, v: 499973}, {t: 1587692812139, v: 500189}, {t: 1587692827139, v: 500359}, {t: 1587692842139, v: 500517}, {t: 1587692857139, v: 500727}, + {t: 1587692872139, v: 500959}, {t: 1587692887139, v: 501178}, {t: 1587692902139, v: 501246}, {t: 1587692917153, v: 501404}, {t: 1587692932139, v: 501663}, {t: 1587692947139, v: 501850}, {t: 1587692962139, v: 502103}, {t: 1587692977155, v: 502280}, {t: 1587692992139, v: 502562}, {t: 1587693007139, v: 502742}, {t: 1587693022139, v: 502931}, + {t: 1587693037139, v: 503190}, {t: 1587693052139, v: 503428}, {t: 1587693067139, v: 503630}, {t: 1587693082139, v: 503873}, {t: 1587693097139, v: 504027}, {t: 1587693112139, v: 504179}, {t: 1587693127139, v: 504362}, {t: 1587693142139, v: 504590}, {t: 1587693157139, v: 504741}, {t: 1587693172139, v: 505056}, {t: 1587693187139, v: 505244}, + {t: 1587693202139, v: 505436}, {t: 1587693217139, v: 505635}, {t: 1587693232139, v: 505936}, {t: 1587693247155, v: 506088}, {t: 1587693262139, v: 506309}, {t: 1587693277139, v: 506524}, {t: 1587693292139, v: 506800}, {t: 1587693307139, v: 507010}, {t: 1587693322139, v: 507286}, {t: 1587693337139, v: 507530}, {t: 1587693352139, v: 507781}, + {t: 1587693367139, v: 507991}, {t: 1587693382139, v: 508310}, {t: 1587693397139, v: 508570}, {t: 1587693412139, v: 508770}, {t: 1587693427139, v: 508982}, {t: 1587693442163, v: 509274}, {t: 1587693457139, v: 509477}, {t: 1587693472139, v: 509713}, {t: 1587693487139, v: 509972}, {t: 1587693502139, v: 510182}, {t: 1587693517139, v: 510498}, + {t: 1587693532139, v: 510654}, {t: 1587693547139, v: 510859}, {t: 1587693562139, v: 511124}, {t: 1587693577139, v: 511314}, {t: 1587693592139, v: 511488}, } + expectedRealSeriesWithStaleMarkerReplica1ForRate = []sample{ + {t: 1587690005791, v: 461968}, {t: 1587690020791, v: 462151}, {t: 1587690035797, v: 462336}, {t: 1587690050791, v: 462650}, {t: 1587690065791, v: 462813}, {t: 1587690080791, v: 462987}, {t: 1587690095791, v: 463095}, {t: 1587690110791, v: 463247}, {t: 1587690125791, v: 463440}, {t: 1587690140791, v: 463642}, {t: 1587690155791, v: 463811}, {t: 1587690170791, v: 464027}, + {t: 1587690185791, v: 464308}, {t: 1587690200791, v: 464514}, {t: 1587690215791, v: 464798}, {t: 1587690230791, v: 465018}, {t: 1587690245791, v: 465215}, {t: 1587690260813, v: 465431}, {t: 1587690275791, v: 465651}, {t: 1587690290791, v: 465870}, {t: 1587690305791, v: 466070}, {t: 1587690320792, v: 466248}, {t: 1587690335791, v: 466506}, {t: 1587690350791, v: 466766}, + {t: 1587690365791, v: 466970}, {t: 1587690380791, v: 467123}, {t: 1587690395791, v: 467265}, {t: 1587690410791, v: 467383}, {t: 1587690425791, v: 467629}, {t: 1587690440791, v: 467931}, {t: 1587690455791, v: 468097}, {t: 1587690470791, v: 468281}, {t: 1587690485791, v: 468477}, {t: 1587690500791, v: 468649}, {t: 1587690515791, v: 468867}, {t: 1587690530791, v: 469150}, + {t: 1587690545791, v: 469268}, {t: 1587690560791, v: 469488}, {t: 1587690575791, v: 469742}, {t: 1587690590791, v: 469951}, {t: 1587690605791, v: 470131}, {t: 1587690620791, v: 470337}, {t: 1587690635791, v: 470631}, {t: 1587690650791, v: 470832}, {t: 1587690665791, v: 471077}, {t: 1587690680791, v: 471311}, {t: 1587690695791, v: 471473}, {t: 1587690710791, v: 471728}, + {t: 1587690725791, v: 472002}, {t: 1587690740791, v: 472158}, {t: 1587690755791, v: 472329}, {t: 1587690770791, v: 472722}, {t: 1587690785791, v: 472925}, {t: 1587690800791, v: 473220}, {t: 1587690815791, v: 473460}, {t: 1587690830791, v: 473748}, {t: 1587690845791, v: 473968}, {t: 1587690860791, v: 474261}, {t: 1587690875791, v: 474418}, {t: 1587690890791, v: 474726}, + {t: 1587690905791, v: 474913}, {t: 1587690920791, v: 475031}, {t: 1587690935791, v: 475284}, {t: 1587690950791, v: 475563}, {t: 1587690965791, v: 475762}, {t: 1587690980791, v: 475945}, {t: 1587690995791, v: 476302}, {t: 1587691010791, v: 476501}, {t: 1587691025791, v: 476849}, {t: 1587691040800, v: 477020}, {t: 1587691055791, v: 477280}, {t: 1587691070791, v: 477549}, + {t: 1587691085791, v: 477758}, {t: 1587691100817, v: 477960}, {t: 1587691115791, v: 478261}, {t: 1587691130791, v: 478559}, {t: 1587691145791, v: 478704}, {t: 1587691160804, v: 478950}, {t: 1587691175791, v: 479173}, {t: 1587691190791, v: 479368}, {t: 1587691205791, v: 479625}, {t: 1587691220805, v: 479866}, {t: 1587691235791, v: 480008}, {t: 1587691250791, v: 480155}, + {t: 1587691265791, v: 480472}, {t: 1587691280811, v: 480598}, {t: 1587691295791, v: 480771}, {t: 1587691310791, v: 480996}, {t: 1587691325791, v: 481200}, {t: 1587691340803, v: 481381}, {t: 1587691355791, v: 481584}, {t: 1587691370791, v: 481759}, {t: 1587691385791, v: 482003}, {t: 1587691400803, v: 482189}, {t: 1587691415791, v: 482457}, {t: 1587691430791, v: 482623}, + {t: 1587691445791, v: 482768}, {t: 1587691460804, v: 483036}, {t: 1587691475791, v: 483322}, {t: 1587691490791, v: 483566}, {t: 1587691505791, v: 483709}, {t: 1587691520807, v: 483838}, {t: 1587691535791, v: 484091}, {t: 1587691550791, v: 484236}, {t: 1587691565791, v: 484454}, {t: 1587691580816, v: 484710}, {t: 1587691595791, v: 484978}, {t: 1587691610791, v: 485271}, + {t: 1587691625791, v: 485476}, {t: 1587691640792, v: 485640}, {t: 1587691655791, v: 485921}, {t: 1587691670791, v: 486201}, {t: 1587691685791, v: 486555}, {t: 1587691700791, v: 486691}, {t: 1587691715791, v: 486831}, {t: 1587691730791, v: 487033}, {t: 1587691745791, v: 487268}, {t: 1587691760803, v: 487370}, {t: 1587691775791, v: 487571}, {t: 1587691790791, v: 487787}, + {t: 1587691805791, v: 488036}, {t: 1587691820791, v: 488241}, {t: 1587691835791, v: 488411}, {t: 1587691850791, v: 488625}, {t: 1587691865791, v: 488868}, {t: 1587691880791, v: 489005}, {t: 1587691895791, v: 489237}, {t: 1587691910791, v: 489545}, {t: 1587691925791, v: 489750}, {t: 1587691940791, v: 489899}, {t: 1587691955791, v: 490048}, {t: 1587691970791, v: 490364}, + {t: 1587691985791, v: 490485}, {t: 1587692000791, v: 490722}, {t: 1587692015791, v: 490866}, {t: 1587692030791, v: 491025}, {t: 1587692045791, v: 491286}, {t: 1587692060816, v: 491543}, {t: 1587692075791, v: 491787}, {t: 1587692090791, v: 492065}, {t: 1587692105791, v: 492223}, {t: 1587692120816, v: 492501}, {t: 1587692135791, v: 492767}, {t: 1587692150791, v: 492955}, + {t: 1587692165791, v: 493194}, {t: 1587692180792, v: 493402}, {t: 1587692195791, v: 493647}, {t: 1587692210791, v: 493897}, {t: 1587692225791, v: 494117}, {t: 1587692240805, v: 494356}, {t: 1587692255791, v: 494620}, {t: 1587692270791, v: 494762}, {t: 1587692285791, v: 495001}, {t: 1587692300805, v: 495222}, {t: 1587692315791, v: 495393}, {t: 1587692330791, v: 495662}, + {t: 1587692345791, v: 495875}, {t: 1587692360801, v: 496082}, {t: 1587692375791, v: 496196}, {t: 1587692390791, v: 496245}, {t: 1587692405791, v: 496295}, {t: 1587692420791, v: 496365}, {t: 1587692435791, v: 496401}, {t: 1587692450791, v: 496452}, {t: 1587692465791, v: 496491}, {t: 1587692480791, v: 496544}, {t: 1587692555791, v: 496619}, {t: 1587692570791, v: 496852}, + {t: 1587692585791, v: 497052}, {t: 1587692600791, v: 497245}, {t: 1587692615791, v: 497529}, {t: 1587692630791, v: 497697}, {t: 1587692645791, v: 497909}, {t: 1587692660791, v: 498156}, {t: 1587692675803, v: 498466}, {t: 1587692690791, v: 498647}, {t: 1587692705791, v: 498805}, {t: 1587692720791, v: 499013}, {t: 1587692735805, v: 499169}, {t: 1587692750791, v: 499345}, + {t: 1587692765791, v: 499499}, {t: 1587692780791, v: 499731}, {t: 1587692795806, v: 499972}, {t: 1587692810791, v: 500201}, {t: 1587692825791, v: 500354}, {t: 1587692840791, v: 500512}, {t: 1587692855791, v: 500739}, {t: 1587692870791, v: 500958}, {t: 1587692885791, v: 501190}, {t: 1587692900791, v: 501233}, {t: 1587692915791, v: 501391}, {t: 1587692930791, v: 501649}, + {t: 1587692945791, v: 501853}, {t: 1587692960791, v: 502065}, {t: 1587692975791, v: 502239}, {t: 1587692990810, v: 502554}, {t: 1587693005791, v: 502754}, {t: 1587693020791, v: 502938}, {t: 1587693035791, v: 503141}, {t: 1587693050791, v: 503416}, {t: 1587693065791, v: 503642}, {t: 1587693080791, v: 503873}, {t: 1587693095791, v: 504014}, {t: 1587693110791, v: 504178}, + {t: 1587693125821, v: 504374}, {t: 1587693140791, v: 504578}, {t: 1587693155791, v: 504753}, {t: 1587693170791, v: 505043}, {t: 1587693185791, v: 505232}, {t: 1587693200791, v: 505437}, {t: 1587693215791, v: 505596}, {t: 1587693230791, v: 505923}, {t: 1587693245791, v: 506088}, {t: 1587693260791, v: 506307}, {t: 1587693275791, v: 506518}, {t: 1587693290791, v: 506786}, + {t: 1587693305791, v: 507008}, {t: 1587693320803, v: 507260}, {t: 1587693335791, v: 507519}, {t: 1587693350791, v: 507776}, {t: 1587693365791, v: 508003}, {t: 1587693380791, v: 508322}, {t: 1587693395804, v: 508551}, {t: 1587693410791, v: 508750}, {t: 1587693425791, v: 508994}, {t: 1587693440791, v: 509237}, {t: 1587693455791, v: 509452}, {t: 1587693470791, v: 509702}, + {t: 1587693485791, v: 509971}, {t: 1587693500791, v: 510147}, {t: 1587693515791, v: 510471}, {t: 1587693530816, v: 510666}, {t: 1587693545791, v: 510871}, {t: 1587693560791, v: 511123}, {t: 1587693575791, v: 511303}, {t: 1587693590791, v: 511500}, + } + expectedRealSeriesWithStaleMarkerDeduplicatedForRate = []sample{ + {t: 1587690005791, v: 461968}, {t: 1587690020791, v: 462151}, {t: 1587690035797, v: 462336}, {t: 1587690050791, v: 462650}, {t: 1587690065791, v: 462813}, {t: 1587690080791, v: 462987}, {t: 1587690095791, v: 463095}, {t: 1587690110791, v: 463247}, {t: 1587690125791, v: 463440}, {t: 1587690140791, v: 463642}, {t: 1587690155791, v: 463811}, {t: 1587690170791, v: 464027}, + {t: 1587690185791, v: 464308}, {t: 1587690200791, v: 464514}, {t: 1587690215791, v: 464798}, {t: 1587690230791, v: 465018}, {t: 1587690245791, v: 465215}, {t: 1587690260813, v: 465431}, {t: 1587690275791, v: 465651}, {t: 1587690290791, v: 465870}, {t: 1587690305791, v: 466070}, {t: 1587690320792, v: 466248}, {t: 1587690335791, v: 466506}, {t: 1587690350791, v: 466766}, + {t: 1587690365791, v: 466970}, {t: 1587690380791, v: 467123}, {t: 1587690395791, v: 467265}, {t: 1587690410791, v: 467383}, {t: 1587690425791, v: 467629}, {t: 1587690440791, v: 467931}, {t: 1587690455791, v: 468097}, {t: 1587690470791, v: 468281}, {t: 1587690485791, v: 468477}, {t: 1587690500791, v: 468649}, {t: 1587690515791, v: 468867}, {t: 1587690530791, v: 469150}, + {t: 1587690545791, v: 469268}, {t: 1587690560791, v: 469488}, {t: 1587690575791, v: 469742}, {t: 1587690590791, v: 469951}, {t: 1587690605791, v: 470131}, {t: 1587690620791, v: 470337}, {t: 1587690635791, v: 470631}, {t: 1587690650791, v: 470832}, {t: 1587690665791, v: 471077}, {t: 1587690680791, v: 471311}, {t: 1587690695791, v: 471473}, {t: 1587690710791, v: 471728}, + {t: 1587690725791, v: 472002}, {t: 1587690740791, v: 472158}, {t: 1587690755791, v: 472329}, {t: 1587690770791, v: 472722}, {t: 1587690785791, v: 472925}, {t: 1587690800791, v: 473220}, {t: 1587690815791, v: 473460}, {t: 1587690830791, v: 473748}, {t: 1587690845791, v: 473968}, {t: 1587690860791, v: 474261}, {t: 1587690875791, v: 474418}, {t: 1587690890791, v: 474726}, + {t: 1587690905791, v: 474913}, {t: 1587690920791, v: 475031}, {t: 1587690935791, v: 475284}, {t: 1587690950791, v: 475563}, {t: 1587690965791, v: 475762}, {t: 1587690980791, v: 475945}, {t: 1587690995791, v: 476302}, {t: 1587691010791, v: 476501}, {t: 1587691025791, v: 476849}, {t: 1587691040800, v: 477020}, {t: 1587691055791, v: 477280}, {t: 1587691070791, v: 477549}, + {t: 1587691085791, v: 477758}, {t: 1587691100817, v: 477960}, {t: 1587691115791, v: 478261}, {t: 1587691130791, v: 478559}, {t: 1587691145791, v: 478704}, {t: 1587691160804, v: 478950}, {t: 1587691175791, v: 479173}, {t: 1587691190791, v: 479368}, {t: 1587691205791, v: 479625}, {t: 1587691220805, v: 479866}, {t: 1587691235791, v: 480008}, {t: 1587691250791, v: 480155}, + {t: 1587691265791, v: 480472}, {t: 1587691280811, v: 480598}, {t: 1587691295791, v: 480771}, {t: 1587691310791, v: 480996}, {t: 1587691325791, v: 481200}, {t: 1587691340803, v: 481381}, {t: 1587691355791, v: 481584}, {t: 1587691370791, v: 481759}, {t: 1587691385791, v: 482003}, {t: 1587691400803, v: 482189}, {t: 1587691415791, v: 482457}, {t: 1587691430791, v: 482623}, + {t: 1587691445791, v: 482768}, {t: 1587691460804, v: 483036}, {t: 1587691475791, v: 483322}, {t: 1587691490791, v: 483566}, {t: 1587691505791, v: 483709}, {t: 1587691520807, v: 483838}, {t: 1587691535791, v: 484091}, {t: 1587691550791, v: 484236}, {t: 1587691565791, v: 484454}, {t: 1587691580816, v: 484710}, {t: 1587691595791, v: 484978}, {t: 1587691610791, v: 485271}, + {t: 1587691625791, v: 485476}, {t: 1587691640792, v: 485640}, {t: 1587691655791, v: 485921}, {t: 1587691670791, v: 486201}, {t: 1587691685791, v: 486555}, {t: 1587691700791, v: 486691}, {t: 1587691715791, v: 486831}, {t: 1587691730791, v: 487033}, {t: 1587691745791, v: 487268}, {t: 1587691760803, v: 487370}, {t: 1587691775791, v: 487571}, {t: 1587691790791, v: 487787}, + {t: 1587691805791, v: 488036}, {t: 1587691820791, v: 488241}, {t: 1587691835791, v: 488411}, {t: 1587691850791, v: 488625}, {t: 1587691865791, v: 488868}, {t: 1587691880791, v: 489005}, {t: 1587691895791, v: 489237}, {t: 1587691910791, v: 489545}, {t: 1587691925791, v: 489750}, {t: 1587691940791, v: 489899}, {t: 1587691955791, v: 490048}, {t: 1587691970791, v: 490364}, + {t: 1587691985791, v: 490485}, {t: 1587692000791, v: 490722}, {t: 1587692015791, v: 490866}, {t: 1587692030791, v: 491025}, {t: 1587692045791, v: 491286}, {t: 1587692060816, v: 491543}, {t: 1587692075791, v: 491787}, {t: 1587692090791, v: 492065}, {t: 1587692105791, v: 492223}, {t: 1587692120816, v: 492501}, {t: 1587692135791, v: 492767}, {t: 1587692150791, v: 492955}, + {t: 1587692165791, v: 493194}, {t: 1587692180792, v: 493402}, {t: 1587692195791, v: 493647}, {t: 1587692210791, v: 493897}, {t: 1587692225791, v: 494117}, {t: 1587692240805, v: 494356}, {t: 1587692255791, v: 494620}, {t: 1587692270791, v: 494762}, {t: 1587692285791, v: 495001}, {t: 1587692300805, v: 495222}, {t: 1587692315791, v: 495393}, {t: 1587692330791, v: 495662}, + {t: 1587692345791, v: 495875}, {t: 1587692360801, v: 496082}, {t: 1587692375791, v: 496196}, {t: 1587692390791, v: 496245}, {t: 1587692405791, v: 496295}, {t: 1587692420791, v: 496365}, {t: 1587692435791, v: 496401}, {t: 1587692450791, v: 496452}, {t: 1587692465791, v: 496491}, {t: 1587692480791, v: 496544}, {t: 1587692542149, v: 496544}, {t: 1587692557139, v: 496640}, + {t: 1587692572139, v: 496851}, {t: 1587692587139, v: 497047}, {t: 1587692602144, v: 497264}, {t: 1587692617139, v: 497529}, {t: 1587692632139, v: 497717}, {t: 1587692647139, v: 497945}, {t: 1587692662154, v: 498179}, {t: 1587692677139, v: 498466}, {t: 1587692692139, v: 498642}, {t: 1587692707139, v: 498839}, {t: 1587692722139, v: 499021}, {t: 1587692737139, v: 499177}, + {t: 1587692752139, v: 499345}, {t: 1587692767139, v: 499518}, {t: 1587692782149, v: 499726}, {t: 1587692797139, v: 499980}, {t: 1587692812139, v: 500196}, {t: 1587692827139, v: 500366}, {t: 1587692842139, v: 500524}, {t: 1587692857139, v: 500734}, {t: 1587692872139, v: 500966}, {t: 1587692887139, v: 501185}, {t: 1587692902139, v: 501253}, {t: 1587692917153, v: 501411}, + {t: 1587692932139, v: 501670}, {t: 1587692947139, v: 501857}, {t: 1587692962139, v: 502110}, {t: 1587692977155, v: 502287}, {t: 1587692992139, v: 502569}, {t: 1587693007139, v: 502749}, {t: 1587693022139, v: 502938}, {t: 1587693037139, v: 503197}, {t: 1587693052139, v: 503435}, {t: 1587693067139, v: 503637}, {t: 1587693082139, v: 503880}, {t: 1587693097139, v: 504034}, + {t: 1587693112139, v: 504186}, {t: 1587693127139, v: 504369}, {t: 1587693142139, v: 504597}, {t: 1587693157139, v: 504748}, {t: 1587693172139, v: 505063}, {t: 1587693187139, v: 505251}, {t: 1587693202139, v: 505443}, {t: 1587693217139, v: 505642}, {t: 1587693232139, v: 505943}, {t: 1587693247155, v: 506095}, {t: 1587693262139, v: 506316}, {t: 1587693277139, v: 506531}, + {t: 1587693292139, v: 506807}, {t: 1587693307139, v: 507017}, {t: 1587693322139, v: 507293}, {t: 1587693337139, v: 507537}, {t: 1587693352139, v: 507788}, {t: 1587693367139, v: 507998}, {t: 1587693382139, v: 508317}, {t: 1587693397139, v: 508577}, {t: 1587693412139, v: 508777}, {t: 1587693427139, v: 508989}, {t: 1587693442163, v: 509281}, {t: 1587693457139, v: 509484}, + {t: 1587693472139, v: 509720}, {t: 1587693487139, v: 509979}, {t: 1587693502139, v: 510189}, {t: 1587693517139, v: 510505}, {t: 1587693532139, v: 510661}, {t: 1587693547139, v: 510866}, {t: 1587693562139, v: 511131}, {t: 1587693577139, v: 511321}, {t: 1587693592139, v: 511495}, + } +) - // Querier clamps the range to [1,300], which should drop some samples of the result above. - // The store API allows endpoints to send more data then initially requested. - q := newQuerier(context.Background(), nil, 1, 300, []string{""}, testProxy, false, 0, true, false) - defer func() { testutil.Ok(t, q.Close()) }() +type series struct { + lset labels.Labels + samples []sample +} - res, _, err := q.Select(&storage.SelectParams{}) - testutil.Ok(t, err) +func (s series) Labels() labels.Labels { return s.lset } +func (s series) Iterator() storage.SeriesIterator { + return newMockedSeriesIterator(s.samples) +} + +func TestQuerier_Select(t *testing.T) { + logger := log.NewLogfmtLogger(os.Stderr) - expected := []struct { - lset labels.Labels - samples []sample + for _, tcase := range []struct { + name string + storeAPI storepb.StoreServer + + mint, maxt int64 + matchers []*labels.Matcher + replicaLabels []string + hints *storage.SelectParams + equivalentQuery string + + expected []series + expectedAfterDedup series + expectedWarning string }{ { - lset: labels.FromStrings("a", "a"), - samples: []sample{{2, 1}, {3, 2}, {5, 5}, {6, 6}, {7, 7}}, + name: "select overlapping data with partial error", + storeAPI: &storeServer{ + resps: []*storepb.SeriesResponse{ + storeSeriesResponse(t, labels.FromStrings("a", "a"), []sample{{0, 0}, {2, 1}, {3, 2}}), + storepb.NewWarnSeriesResponse(errors.New("partial error")), + storeSeriesResponse(t, labels.FromStrings("a", "a"), []sample{{5, 5}, {6, 6}, {7, 7}}), + storeSeriesResponse(t, labels.FromStrings("a", "a"), []sample{{5, 5}, {6, 66}}), // Overlap samples for some reason. + storeSeriesResponse(t, labels.FromStrings("a", "b"), []sample{{2, 2}, {3, 3}, {4, 4}}, []sample{{1, 1}, {2, 2}, {3, 3}}), + storeSeriesResponse(t, labels.FromStrings("a", "c"), []sample{{100, 1}, {300, 3}, {400, 4}}), + }, + }, + mint: 1, maxt: 300, + replicaLabels: []string{"a"}, + equivalentQuery: `{a=~"a|b|c"}`, + + expected: []series{ + { + lset: labels.FromStrings("a", "a"), + samples: []sample{{2, 1}, {3, 2}, {5, 5}, {6, 6}, {7, 7}}, + }, + { + lset: labels.FromStrings("a", "b"), + samples: []sample{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, + }, + { + lset: labels.FromStrings("a", "c"), + samples: []sample{{100, 1}, {300, 3}}, + }, + }, + expectedAfterDedup: series{ + lset: labels.Labels{}, + // We don't expect correctness here, it's just random non-replica data. + samples: []sample{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, + }, + expectedWarning: "partial error", }, { - lset: labels.FromStrings("a", "b"), - samples: []sample{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, + name: "realistic data with stale marker", + storeAPI: func() storepb.StoreServer { + s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) + testutil.Ok(t, err) + return s + }(), + mint: realSeriesWithStaleMarkerMint, maxt: realSeriesWithStaleMarkerMaxt, + replicaLabels: []string{"replica"}, + matchers: []*labels.Matcher{{ + Value: "gitlab_transaction_cache_read_hit_count_total", + Name: "__name__", + Type: labels.MatchEqual, + }}, + equivalentQuery: `gitlab_transaction_cache_read_hit_count_total{}`, + + expected: []series{ + { + lset: labels.FromStrings( + "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "replica", "01", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ), + samples: expectedRealSeriesWithStaleMarkerReplica0, + }, + { + lset: labels.FromStrings( + "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "replica", "02", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ), + samples: expectedRealSeriesWithStaleMarkerReplica1, + }, + }, + expectedAfterDedup: series{ + lset: labels.FromStrings( + // No replica label anymore. + "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ), + samples: expectedRealSeriesWithStaleMarkerDeduplicated, + }, }, { - lset: labels.FromStrings("a", "c"), + name: "realistic data with stale marker with 100000 step", + storeAPI: func() storepb.StoreServer { + s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) + testutil.Ok(t, err) + return s + }(), + mint: realSeriesWithStaleMarkerMint, maxt: realSeriesWithStaleMarkerMaxt, + replicaLabels: []string{"replica"}, + matchers: []*labels.Matcher{{ + Value: "gitlab_transaction_cache_read_hit_count_total", + Name: "__name__", + Type: labels.MatchEqual, + }}, + hints: &storage.SelectParams{ + Start: realSeriesWithStaleMarkerMint, + End: realSeriesWithStaleMarkerMaxt, + Step: 100000, // Should not matter. + }, + equivalentQuery: `gitlab_transaction_cache_read_hit_count_total{}`, - samples: []sample{{100, 1}, {300, 3}}, + expected: []series{ + { + lset: labels.FromStrings( + "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "replica", "01", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ), + samples: expectedRealSeriesWithStaleMarkerReplica0, + }, + { + lset: labels.FromStrings( + "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "replica", "02", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ), + samples: expectedRealSeriesWithStaleMarkerReplica1, + }, + }, + expectedAfterDedup: series{ + lset: labels.FromStrings( + // No replica label anymore. + "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ), + samples: expectedRealSeriesWithStaleMarkerDeduplicated, + }, }, - } + { + // Regression test against https://github.com/thanos-io/thanos/issues/2401. + // Thanks to @Superq and GitLab for real data reproducing this. + name: "realistic data with stale marker with hints rate function", + storeAPI: func() storepb.StoreServer { + s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) + testutil.Ok(t, err) + return s + }(), + mint: realSeriesWithStaleMarkerMint, maxt: realSeriesWithStaleMarkerMaxt, + replicaLabels: []string{"replica"}, + matchers: []*labels.Matcher{{ + Value: "gitlab_transaction_cache_read_hit_count_total", + Name: "__name__", + Type: labels.MatchEqual, + }}, + hints: &storage.SelectParams{ + Start: realSeriesWithStaleMarkerMint, + End: realSeriesWithStaleMarkerMaxt, + // Rate triggers special case of extra downsample.CounterSeriesIterator. + Func: "rate", + }, + equivalentQuery: `rate(gitlab_transaction_cache_read_hit_count_total[5m])`, - i := 0 - for res.Next() { - testutil.Assert(t, i < len(expected), "more series than expected") + expected: []series{ + { + lset: labels.FromStrings( + "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "replica", "01", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ), + samples: expectedRealSeriesWithStaleMarkerReplica0ForRate, + }, + { + lset: labels.FromStrings( + "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "replica", "02", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ), + samples: expectedRealSeriesWithStaleMarkerReplica1ForRate, + }, + }, + expectedAfterDedup: series{ + lset: labels.FromStrings( + "__name__", "gitlab_transaction_cache_read_hit_count_total", "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ), + samples: expectedRealSeriesWithStaleMarkerDeduplicatedForRate, + }, + }, + } { + e := promql.NewEngine(promql.EngineOpts{ + Logger: logger, + MaxConcurrent: 1, + Timeout: 5 * time.Second, + MaxSamples: math.MaxInt64, + }) + + t.Run(tcase.name, func(t *testing.T) { + for _, sc := range []struct { + dedup bool + expected []series + }{ + {dedup: false, expected: tcase.expected}, + {dedup: true, expected: []series{tcase.expectedAfterDedup}}, + } { + q := newQuerier(context.Background(), nil, tcase.mint, tcase.maxt, tcase.replicaLabels, tcase.storeAPI, sc.dedup, 0, true, false) + defer testutil.Ok(t, q.Close()) + + t.Run(fmt.Sprintf("dedup=%v", sc.dedup), func(t *testing.T) { + t.Run("querier.Select", func(t *testing.T) { + defer leaktest.CheckTimeout(t, 10*time.Second)() + defer func() { testutil.Ok(t, q.Close()) }() + + res, w, err := q.Select(tcase.hints, tcase.matchers...) + testutil.Ok(t, err) + if tcase.expectedWarning != "" { + testutil.Equals(t, 1, len(w)) + testutil.Equals(t, tcase.expectedWarning, w[0].Error()) + } + testSelectResponse(t, sc.expected, res) - testutil.Equals(t, expected[i].lset, res.At().Labels()) + }) + // Integration test: Make sure the PromQL would select exactly the same. + t.Run("through PromQL with 100s step", func(t *testing.T) { + defer leaktest.CheckTimeout(t, 10*time.Second)() - samples := expandSeries(t, res.At().Iterator()) - testutil.Equals(t, expected[i].samples, samples) + catcher := &querierResponseCatcher{t: t, Querier: q} + q, err := e.NewRangeQuery(&mockedQueryable{catcher}, tcase.equivalentQuery, timestamp.Time(tcase.mint), timestamp.Time(tcase.maxt), 100*time.Second) + testutil.Ok(t, err) + defer q.Close() - i++ + r := q.Exec(context.Background()) + testutil.Ok(t, r.Err) + + // We don't care about anything else, all should be recorded. + testutil.Assert(t, len(catcher.warns) == 1, "expected only single warnings") + testutil.Assert(t, len(catcher.resp) == 1, "expected only single response, subqueries?") + + w := catcher.warns[0] + if tcase.expectedWarning != "" { + testutil.Equals(t, 1, len(w)) + testutil.Equals(t, tcase.expectedWarning, w[0].Error()) + } + testSelectResponse(t, sc.expected, catcher.resp[0]) + }) + }) + } + }) + } +} + +func testSelectResponse(t *testing.T, expected []series, res storage.SeriesSet) { + var series []storage.Series + // Use it as PromQL would do, first gather all series. + for res.Next() { + series = append(series, res.At()) } testutil.Ok(t, res.Err()) + testutil.Equals(t, len(expected), len(series)) + + for i, s := range series { + testutil.Equals(t, expected[i].lset, s.Labels()) + samples := expandSeries(t, s.Iterator()) + expectedCpy := make([]sample, 0, len(expected[i].samples)) + for _, s := range expected[i].samples { + v := s.v + if value.IsStaleNaN(v) { + // Nan != Nan, so substitute for another value. + // This is required for testutil.Equals to work deterministically. + v = hackyStaleMarker + } + expectedCpy = append(expectedCpy, sample{t: s.t, v: v}) + } + testutil.Equals(t, expectedCpy, samples, "samples for series %v does not match", i) + } +} + +type mockedQueryable struct { + q storage.Querier +} + +func (q *mockedQueryable) Querier(context.Context, int64, int64) (storage.Querier, error) { + return q.q, nil +} + +type querierResponseCatcher struct { + storage.Querier + t testing.TB + + resp []storage.SeriesSet + warns []storage.Warnings +} + +func (q *querierResponseCatcher) Select(p *storage.SelectParams, m ...*labels.Matcher) (storage.SeriesSet, storage.Warnings, error) { + s, w, err := q.Querier.Select(p, m...) + testutil.Ok(q.t, err) + + q.resp = append(q.resp, s) + q.warns = append(q.warns, w) + return storage.NoopSeriesSet(), storage.Warnings{errors.New("response caught")}, nil +} + +func (q querierResponseCatcher) Close() error { return nil } + +// TODO(bwplotka): Reuse SeriesSets from chunk iterators from Prometheus. +type mockedSeriesSet struct { + series []series + cur int +} + +func (s *mockedSeriesSet) Next() bool { + s.cur++ + return s.cur <= len(s.series) +} + +func (s *mockedSeriesSet) At() storage.Series { + return s.series[s.cur-1] +} +func (s *mockedSeriesSet) Err() error { return nil } + +type mockedSeriesIterator struct { + cur int + samples []sample +} + +func newMockedSeriesIterator(samples []sample) *mockedSeriesIterator { + return &mockedSeriesIterator{samples: samples, cur: -1} +} - testutil.Equals(t, len(expected), i) +func (s *mockedSeriesIterator) Seek(t int64) bool { + s.cur = sort.Search(len(s.samples), func(n int) bool { + return s.samples[n].t >= t + }) + return s.cur < len(s.samples) +} + +func (s *mockedSeriesIterator) At() (t int64, v float64) { + sample := s.samples[s.cur] + return sample.t, sample.v +} + +func (s *mockedSeriesIterator) Next() bool { + s.cur++ + return s.cur < len(s.samples) +} + +func (s *mockedSeriesIterator) Err() error { return nil } + +func TestQuerierWithDedupUnderstoodByPromQL_Rate(t *testing.T) { + logger := log.NewLogfmtLogger(os.Stderr) + + s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) + testutil.Ok(t, err) + + t.Run("dedup=false", func(t *testing.T) { + expectedLset1 := labels.FromStrings( + "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "replica", "01", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ) + expectedLset2 := labels.FromStrings( + "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "replica", "02", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ) + q := newQuerier(context.Background(), logger, realSeriesWithStaleMarkerMint, realSeriesWithStaleMarkerMaxt, []string{"replica"}, s, false, 0, true, false) + defer func() { testutil.Ok(t, q.Close()) }() + + e := promql.NewEngine(promql.EngineOpts{ + Logger: logger, + MaxConcurrent: 1, + Timeout: 5 * time.Second, + MaxSamples: math.MaxInt64, + }) + t.Run("Rate=5mStep=100s", func(t *testing.T) { + q, err := e.NewRangeQuery(&mockedQueryable{q}, `rate(gitlab_transaction_cache_read_hit_count_total[5m])`, timestamp.Time(realSeriesWithStaleMarkerMint).Add(5*time.Minute), timestamp.Time(realSeriesWithStaleMarkerMaxt), 100*time.Second) + testutil.Ok(t, err) + defer q.Close() + + r := q.Exec(context.Background()) + testutil.Ok(t, r.Err) + testutil.Assert(t, len(r.Warnings) == 0) + + vec, err := r.Matrix() + testutil.Ok(t, err) + testutil.Equals(t, promql.Matrix{ + {Metric: expectedLset1, Points: []promql.Point{ + {T: 1587690300000, V: 13.652631578947368}, {T: 1587690400000, V: 14.049122807017545}, {T: 1587690500000, V: 13.961403508771928}, {T: 1587690600000, V: 13.617543859649123}, {T: 1587690700000, V: 14.568421052631578}, {T: 1587690800000, V: 14.989473684210525}, + {T: 1587690900000, V: 16.2}, {T: 1587691000000, V: 16.052631578947366}, {T: 1587691100000, V: 15.831578947368419}, {T: 1587691200000, V: 15.659649122807016}, {T: 1587691300000, V: 14.842105263157894}, {T: 1587691400000, V: 14.003508771929825}, + {T: 1587691500000, V: 13.782456140350877}, {T: 1587691600000, V: 13.863157894736842}, {T: 1587691700000, V: 15.270282598474374}, {T: 1587691800000, V: 14.343859649122805}, {T: 1587691900000, V: 13.975438596491228}, {T: 1587692000000, V: 13.4}, + {T: 1587692100000, V: 14.087719298245615}, {T: 1587692200000, V: 14.39298245614035}, {T: 1587692300000, V: 15.024561403508772}, {T: 1587692400000, V: 14.073684210526313}, {T: 1587692500000, V: 9.3772165751634}, {T: 1587692600000, V: 6.378947368421052}, + {T: 1587692700000, V: 8.19298245614035}, {T: 1587692800000, V: 11.918703026416258}, {T: 1587692900000, V: 13.75813610765101}, {T: 1587693000000, V: 13.087719298245615}, {T: 1587693100000, V: 13.466666666666667}, {T: 1587693200000, V: 14.028070175438595}, + {T: 1587693300000, V: 14.23859649122807}, {T: 1587693400000, V: 15.407017543859647}, {T: 1587693500000, V: 15.915789473684208}, {T: 1587693600000, V: 15.712280701754386}, + }}, + {Metric: expectedLset2, Points: []promql.Point{ + {T: 1587690300000, V: 13.69122807017544}, {T: 1587690400000, V: 14.098245614035086}, {T: 1587690500000, V: 13.905263157894735}, {T: 1587690600000, V: 13.617543859649123}, {T: 1587690700000, V: 14.350877192982455}, {T: 1587690800000, V: 15.003508771929825}, + {T: 1587690900000, V: 16.12280701754386}, {T: 1587691000000, V: 16.049122807017543}, {T: 1587691100000, V: 15.922807017543859}, {T: 1587691200000, V: 15.63157894736842}, {T: 1587691300000, V: 14.982456140350878}, {T: 1587691400000, V: 14.187259188557551}, + {T: 1587691500000, V: 13.828070175438594}, {T: 1587691600000, V: 13.971929824561403}, {T: 1587691700000, V: 15.31994329585807}, {T: 1587691800000, V: 14.30877192982456}, {T: 1587691900000, V: 13.915789473684212}, {T: 1587692000000, V: 13.312280701754384}, + {T: 1587692100000, V: 14.136842105263158}, {T: 1587692200000, V: 14.39298245614035}, {T: 1587692300000, V: 15.014035087719297}, {T: 1587692400000, V: 14.112280701754386}, {T: 1587692500000, V: 9.421065148148147}, {T: 1587692600000, V: 6.421368067203301}, + {T: 1587692700000, V: 8.252631578947367}, {T: 1587692800000, V: 11.721237543747266}, {T: 1587692900000, V: 13.842105263157894}, {T: 1587693000000, V: 13.153509064307995}, {T: 1587693100000, V: 13.378947368421052}, {T: 1587693200000, V: 14.03157894736842}, + {T: 1587693300000, V: 14.147368421052631}, {T: 1587693400000, V: 15.343159785693985}, {T: 1587693500000, V: 15.90877192982456}, {T: 1587693600000, V: 15.761403508771927}, + }}, + }, vec) + }) + t.Run("Rate=30mStep=500s", func(t *testing.T) { + q, err := e.NewRangeQuery(&mockedQueryable{q}, `rate(gitlab_transaction_cache_read_hit_count_total[30m])`, timestamp.Time(realSeriesWithStaleMarkerMint).Add(30*time.Minute), timestamp.Time(realSeriesWithStaleMarkerMaxt), 500*time.Second) + testutil.Ok(t, err) + defer q.Close() + + r := q.Exec(context.Background()) + testutil.Ok(t, r.Err) + testutil.Assert(t, len(r.Warnings) == 0) + + vec, err := r.Matrix() + testutil.Ok(t, err) + testutil.Equals(t, promql.Matrix{ + {Metric: expectedLset1, Points: []promql.Point{ + {T: 1587691800000, V: 14.457142857142856}, {T: 1587692300000, V: 14.761904761904761}, {T: 1587692800000, V: 13.127170868347338}, {T: 1587693300000, V: 12.935014005602241}, + }}, + {Metric: expectedLset2, Points: []promql.Point{ + {T: 1587691800000, V: 14.464425770308123}, {T: 1587692300000, V: 14.763025210084033}, {T: 1587692800000, V: 13.148909112808576}, {T: 1587693300000, V: 12.928291316526611}, + }}, + }, vec) + }) + }) + // Regression test against https://github.com/thanos-io/thanos/issues/2401. + // Rate + dedup can cause incorrectness. + t.Run("dedup=true", func(t *testing.T) { + expectedLset := labels.FromStrings( + "action", "widget.json", "controller", "Projects::MergeRequests::ContentController", "env", "gprd", "environment", + "gprd", "fqdn", "web-08-sv-gprd.c.gitlab-production.internal", "instance", "web-08-sv-gprd.c.gitlab-production.internal:8083", "job", "gitlab-rails", "monitor", "app", "provider", + "gcp", "region", "us-east", "shard", "default", "stage", "main", "tier", "sv", "type", "web", + ) + q := newQuerier(context.Background(), logger, realSeriesWithStaleMarkerMint, realSeriesWithStaleMarkerMaxt, []string{"replica"}, s, true, 0, true, false) + defer func() { testutil.Ok(t, q.Close()) }() + + e := promql.NewEngine(promql.EngineOpts{ + Logger: logger, + MaxConcurrent: 1, + Timeout: 5 * time.Second, + MaxSamples: math.MaxInt64, + }) + t.Run("Rate=5mStep=100s", func(t *testing.T) { + q, err := e.NewRangeQuery(&mockedQueryable{q}, `rate(gitlab_transaction_cache_read_hit_count_total[5m])`, timestamp.Time(realSeriesWithStaleMarkerMint).Add(5*time.Minute), timestamp.Time(realSeriesWithStaleMarkerMaxt), 100*time.Second) + testutil.Ok(t, err) + defer q.Close() + + r := q.Exec(context.Background()) + testutil.Ok(t, r.Err) + testutil.Assert(t, len(r.Warnings) == 0) + + vec, err := r.Matrix() + testutil.Ok(t, err) + testutil.Equals(t, promql.Matrix{ + {Metric: expectedLset, Points: []promql.Point{ + {T: 1587690300000, V: 13.69122807017544}, {T: 1587690400000, V: 14.098245614035086}, {T: 1587690500000, V: 13.905263157894735}, {T: 1587690600000, V: 13.617543859649123}, + {T: 1587690700000, V: 14.350877192982455}, {T: 1587690800000, V: 15.003508771929825}, {T: 1587690900000, V: 16.12280701754386}, {T: 1587691000000, V: 16.049122807017543}, + {T: 1587691100000, V: 15.922807017543859}, {T: 1587691200000, V: 15.63157894736842}, {T: 1587691300000, V: 14.982456140350878}, {T: 1587691400000, V: 14.187259188557551}, + {T: 1587691500000, V: 13.828070175438594}, {T: 1587691600000, V: 13.971929824561403}, {T: 1587691700000, V: 15.31994329585807}, {T: 1587691800000, V: 14.30877192982456}, + {T: 1587691900000, V: 13.915789473684212}, {T: 1587692000000, V: 13.312280701754384}, {T: 1587692100000, V: 14.136842105263158}, {T: 1587692200000, V: 14.39298245614035}, + {T: 1587692300000, V: 15.014035087719297}, {T: 1587692400000, V: 14.112280701754386}, {T: 1587692500000, V: 9.421065148148147}, {T: 1587692600000, V: 6.3736754978451735}, + {T: 1587692700000, V: 8.19632056099571}, {T: 1587692800000, V: 11.918703026416258}, {T: 1587692900000, V: 13.75813610765101}, {T: 1587693000000, V: 13.087719298245615}, + {T: 1587693100000, V: 13.466666666666667}, {T: 1587693200000, V: 14.028070175438595}, {T: 1587693300000, V: 14.23859649122807}, {T: 1587693400000, V: 15.407017543859647}, + {T: 1587693500000, V: 15.915789473684208}, {T: 1587693600000, V: 15.712280701754386}, + }}, + }, vec) + }) + t.Run("Rate=30mStep=500s", func(t *testing.T) { + q, err := e.NewRangeQuery(&mockedQueryable{q}, `rate(gitlab_transaction_cache_read_hit_count_total[30m])`, timestamp.Time(realSeriesWithStaleMarkerMint).Add(30*time.Minute), timestamp.Time(realSeriesWithStaleMarkerMaxt), 500*time.Second) + testutil.Ok(t, err) + defer q.Close() + + r := q.Exec(context.Background()) + testutil.Ok(t, r.Err) + testutil.Assert(t, len(r.Warnings) == 0) + + vec, err := r.Matrix() + testutil.Ok(t, err) + testutil.Equals(t, promql.Matrix{ + {Metric: expectedLset, Points: []promql.Point{ + {T: 1587691800000, V: 14.464425770308123}, + {T: 1587692300000, V: 14.763025210084033}, + {T: 1587692800000, V: 13.143575607888273}, + {T: 1587693300000, V: 12.930291298224086}, + }}, + }, vec) + }) + }) } func TestSortReplicaLabel(t *testing.T) { @@ -276,7 +849,7 @@ func TestSortReplicaLabel(t *testing.T) { {Name: "b", Value: "replica-1"}, }}, }, - dedupLabels: map[string]struct{}{"b": struct{}{}}, + dedupLabels: map[string]struct{}{"b": {}}, }, // 1 Multi deduplication labels. { @@ -345,8 +918,8 @@ func TestSortReplicaLabel(t *testing.T) { }}, }, dedupLabels: map[string]struct{}{ - "b": struct{}{}, - "b1": struct{}{}, + "b": {}, + "b1": {}, }, }, } @@ -358,9 +931,16 @@ func TestSortReplicaLabel(t *testing.T) { } } +const hackyStaleMarker = float64(-99999999) + func expandSeries(t testing.TB, it storage.SeriesIterator) (res []sample) { for it.Next() { t, v := it.At() + // Nan != Nan, so substitute for another value. + // This is required for testutil.Equals to work deterministically. + if math.IsNaN(v) { + v = hackyStaleMarker + } res = append(res, sample{t, v}) } testutil.Ok(t, it.Err()) @@ -371,197 +951,299 @@ func TestDedupSeriesSet(t *testing.T) { defer leaktest.CheckTimeout(t, 10*time.Second)() tests := []struct { - input []struct { - lset []storepb.Label - vals []sample - } - exp []struct { - lset labels.Labels - vals []sample - } + input []series + exp []series dedupLabels map[string]struct{} + isCounter bool }{ - { // 0 Single dedup label. - input: []struct { - lset []storepb.Label - vals []sample - }{ + { + // Single dedup label. + input: []series{ { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-1"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-1"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-2"}}, - vals: []sample{{60000, 3}, {70000, 4}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-2"}}, + samples: []sample{{60000, 3}, {70000, 4}}, }, { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}}, - vals: []sample{{200000, 5}, {210000, 6}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}}, + samples: []sample{{200000, 5}, {210000, 6}}, }, { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}, {Name: "replica", Value: "replica-1"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}, {Name: "replica", Value: "replica-1"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: []storepb.Label{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: []storepb.Label{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}}, - vals: []sample{{60000, 3}, {70000, 4}}, + lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}}, + samples: []sample{{60000, 3}, {70000, 4}}, }, }, - exp: []struct { - lset labels.Labels - vals []sample - }{ + exp: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, - vals: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}, {200000, 5}, {210000, 6}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + samples: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}, {200000, 5}, {210000, 6}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}}, - vals: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}}, + lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}}, + samples: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}}, }, }, dedupLabels: map[string]struct{}{ - "replica": struct{}{}, + "replica": {}, }, }, - { // 1 Multi dedup label. - input: []struct { - lset []storepb.Label - vals []sample - }{ + { + // Multi dedup label. + input: []series{ { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-1"}, {Name: "replicaA", Value: "replica-1"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-1"}, {Name: "replicaA", Value: "replica-1"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-2"}, {Name: "replicaA", Value: "replica-2"}}, - vals: []sample{{60000, 3}, {70000, 4}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-2"}, {Name: "replicaA", Value: "replica-2"}}, + samples: []sample{{60000, 3}, {70000, 4}}, }, { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}, {Name: "replicaA", Value: "replica-3"}}, - vals: []sample{{200000, 5}, {210000, 6}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}, {Name: "replicaA", Value: "replica-3"}}, + samples: []sample{{200000, 5}, {210000, 6}}, }, { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}, {Name: "replica", Value: "replica-1"}, {Name: "replicaA", Value: "replica-1"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}, {Name: "replica", Value: "replica-1"}, {Name: "replicaA", Value: "replica-1"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: []storepb.Label{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}, {Name: "replicaA", Value: "replica-3"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}, {Name: "replicaA", Value: "replica-3"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: []storepb.Label{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}, {Name: "replicaA", Value: "replica-3"}}, - vals: []sample{{60000, 3}, {70000, 4}}, + lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-3"}, {Name: "replicaA", Value: "replica-3"}}, + samples: []sample{{60000, 3}, {70000, 4}}, }, }, - exp: []struct { - lset labels.Labels - vals []sample - }{ + exp: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, - vals: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}, {200000, 5}, {210000, 6}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + samples: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}, {200000, 5}, {210000, 6}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "d", Value: "4"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "4"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}}, - vals: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}}, + lset: labels.Labels{{Name: "a", Value: "2"}, {Name: "c", Value: "3"}}, + samples: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}}, }, }, dedupLabels: map[string]struct{}{ - "replica": struct{}{}, - "replicaA": struct{}{}, + "replica": {}, + "replicaA": {}, }, }, - { // 2 Multi dedup label - some series don't have all dedup labels. - input: []struct { - lset []storepb.Label - vals []sample - }{ + { + // Multi dedup label - some series don't have all dedup labels. + input: []series{ { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-1"}, {Name: "replicaA", Value: "replica-1"}}, - vals: []sample{{10000, 1}, {20000, 2}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-1"}, {Name: "replicaA", Value: "replica-1"}}, + samples: []sample{{10000, 1}, {20000, 2}}, }, { - lset: []storepb.Label{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-2"}}, - vals: []sample{{60000, 3}, {70000, 4}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}, {Name: "replica", Value: "replica-2"}}, + samples: []sample{{60000, 3}, {70000, 4}}, }, }, - exp: []struct { - lset labels.Labels - vals []sample - }{ + exp: []series{ { - lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, - vals: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}}, + lset: labels.Labels{{Name: "a", Value: "1"}, {Name: "c", Value: "3"}}, + samples: []sample{{10000, 1}, {20000, 2}, {60000, 3}, {70000, 4}}, }, }, dedupLabels: map[string]struct{}{ - "replica": struct{}{}, - "replicaA": struct{}{}, + "replica": {}, + "replicaA": {}, }, }, + { + // Regression test against https://github.com/thanos-io/thanos/issues/2401. + // Two counter series, when one (initially chosen) series is having hiccup (few dropped samples), while second is live. + // This also happens when 2 replicas scrape in different time (they usually do) and one sees later counter value then the other. + // Now, depending on what replica we look, we can see totally different counter value in total where total means + // after accounting for counter resets. We account for that in downsample.CounterSeriesIterator, mainly because + // we handle downsample Counter Aggregations specially (for detecting resets between chunks). + isCounter: true, + input: []series{ + { + lset: labels.Labels{{Name: "replica", Value: "01"}}, + samples: []sample{ + {10000, 8.0}, // Smaller timestamp, this will be chosen. CurrValue = 8.0. + {20000, 9.0}, // Same. CurrValue = 9.0. + // {Gap} app reset. No sample, because stale marker but removed by downsample.CounterSeriesIterator. + {50001, 9 + 1.0}, // Next after 20000+1 has a bit higher than timestamp then in second series. Penalty 5000 will be added. + {60000, 9 + 2.0}, + {70000, 9 + 3.0}, + {80000, 9 + 4.0}, + {90000, 9 + 5.0}, // This should be now taken, and we expect 14 to be correct value now. + {100000, 9 + 6.0}, + }, + }, { + lset: labels.Labels{{Name: "replica", Value: "02"}}, + samples: []sample{ + {10001, 8.0}, // Penalty 5000 will be added. + // 20001 was app reset. No sample, because stale marker but removed by downsample.CounterSeriesIterator. Penalty 2 * (20000 - 10000) will be added. + // 30001 no sample. Within penalty, ignored. + {45001, 8 + 0.5}, // Smaller timestamp, this will be chosen. CurrValue = 8.5 which is smaller than last chosen value. + {55001, 8 + 1.5}, + {65001, 8 + 2.5}, + // {Gap} app reset. No sample, because stale marker but removed by downsample.CounterSeriesIterator. + }, + }, + }, + exp: []series{ + { + lset: labels.Labels{}, + samples: []sample{{10000, 8}, {20000, 9}, {45001, 9}, {55001, 10}, {65001, 11}, {90000, 14}, {100000, 15}}, + }, + }, + dedupLabels: map[string]struct{}{ + "replica": {}, + }, + }, + { + // Same thing but not for counter should not adjust antything. + isCounter: false, + input: []series{ + { + lset: labels.Labels{{Name: "replica", Value: "01"}}, + samples: []sample{ + {10000, 8.0}, {20000, 9.0}, {50001, 9 + 1.0}, {60000, 9 + 2.0}, {70000, 9 + 3.0}, {80000, 9 + 4.0}, {90000, 9 + 5.0}, {100000, 9 + 6.0}, + }, + }, { + lset: labels.Labels{{Name: "replica", Value: "02"}}, + samples: []sample{ + {10001, 8.0}, {45001, 8 + 0.5}, {55001, 8 + 1.5}, {65001, 8 + 2.5}, + }, + }, + }, + exp: []series{ + { + lset: labels.Labels{}, + samples: []sample{{10000, 8}, {20000, 9}, {45001, 8.5}, {55001, 9.5}, {65001, 10.5}, {90000, 14}, {100000, 15}}, + }, + }, + dedupLabels: map[string]struct{}{"replica": {}}, + }, + { + // Regression test on real data against https://github.com/thanos-io/thanos/issues/2401. + // Real data with stale marker after downsample.CounterSeriesIterator (required for downsampling + rate). + isCounter: true, + input: []series{ + { + lset: labels.Labels{{Name: "replica", Value: "01"}}, + samples: []sample{ + {t: 1587690007139, v: 461993}, {t: 1587690022139, v: 462164}, {t: 1587690037139, v: 462409}, {t: 1587690052139, v: 462662}, {t: 1587690067139, v: 462824}, {t: 1587690082139, v: 462987}, {t: 1587690097155, v: 463108}, {t: 1587690112139, v: 463261}, {t: 1587690127139, v: 463465}, {t: 1587690142139, v: 463642}, + {t: 1587690157139, v: 463823}, {t: 1587690172139, v: 464065}, {t: 1587690187139, v: 464333}, {t: 1587690202139, v: 464566}, {t: 1587690217139, v: 464811}, {t: 1587690232140, v: 465032}, {t: 1587690247139, v: 465229}, {t: 1587690262139, v: 465445}, {t: 1587690277139, v: 465700}, {t: 1587690292139, v: 465884}, + {t: 1587690307139, v: 466083}, {t: 1587690322139, v: 466250}, {t: 1587690337150, v: 466534}, {t: 1587690352139, v: 466791}, {t: 1587690367139, v: 466970}, {t: 1587690382139, v: 467149}, {t: 1587690397139, v: 467265}, {t: 1587690412139, v: 467383}, {t: 1587690427139, v: 467647}, {t: 1587690442139, v: 467943}, + {t: 1587690457139, v: 468121}, {t: 1587690472139, v: 468294}, {t: 1587690487139, v: 468545}, {t: 1587690502139, v: 468676}, {t: 1587690517139, v: 468879}, {t: 1587690532139, v: 469154}, {t: 1587690547139, v: 469281}, {t: 1587690562139, v: 469512}, {t: 1587690577139, v: 469783}, {t: 1587690592139, v: 469964}, + {t: 1587690607139, v: 470171}, {t: 1587690622139, v: 470355}, {t: 1587690637139, v: 470656}, {t: 1587690652139, v: 470845}, {t: 1587690667139, v: 471077}, {t: 1587690682139, v: 471315}, {t: 1587690697139, v: 471535}, {t: 1587690712139, v: 471766}, {t: 1587690727139, v: 472002}, {t: 1587690742139, v: 472171}, + {t: 1587690757139, v: 472354}, {t: 1587690772139, v: 472736}, {t: 1587690787139, v: 472948}, {t: 1587690802139, v: 473259}, {t: 1587690817139, v: 473460}, {t: 1587690832139, v: 473753}, {t: 1587690847139, v: 474007}, {t: 1587690862139, v: 474286}, {t: 1587690877139, v: 474423}, {t: 1587690892139, v: 474788}, + {t: 1587690907139, v: 474925}, {t: 1587690922139, v: 475031}, {t: 1587690937139, v: 475316}, {t: 1587690952139, v: 475573}, {t: 1587690967139, v: 475784}, {t: 1587690982139, v: 475992}, {t: 1587690997139, v: 476341}, {t: 1587691012139, v: 476541}, {t: 1587691027139, v: 476890}, {t: 1587691042139, v: 477033}, + {t: 1587691057139, v: 477305}, {t: 1587691072139, v: 477577}, {t: 1587691087139, v: 477771}, {t: 1587691102139, v: 478012}, {t: 1587691117139, v: 478296}, {t: 1587691132139, v: 478559}, {t: 1587691147139, v: 478744}, {t: 1587691162139, v: 478950}, {t: 1587691177139, v: 479201}, {t: 1587691192139, v: 479388}, + {t: 1587691207139, v: 479638}, {t: 1587691222154, v: 479907}, {t: 1587691237139, v: 480008}, {t: 1587691252139, v: 480167}, {t: 1587691267139, v: 480472}, {t: 1587691282157, v: 480615}, {t: 1587691297139, v: 480771}, {t: 1587691312139, v: 481027}, {t: 1587691327139, v: 481212}, {t: 1587691342159, v: 481395}, + {t: 1587691357139, v: 481598}, {t: 1587691372139, v: 481786}, {t: 1587691387139, v: 482003}, {t: 1587691402141, v: 482236}, {t: 1587691417139, v: 482508}, {t: 1587691432139, v: 482636}, {t: 1587691447139, v: 482780}, {t: 1587691462139, v: 483059}, {t: 1587691477139, v: 483357}, {t: 1587691492139, v: 483566}, + {t: 1587691507139, v: 483711}, {t: 1587691522139, v: 483838}, {t: 1587691537139, v: 484091}, {t: 1587691552139, v: 484254}, {t: 1587691567139, v: 484479}, {t: 1587691582139, v: 484748}, {t: 1587691597139, v: 484978}, {t: 1587691612139, v: 485271}, {t: 1587691627139, v: 485488}, {t: 1587691642139, v: 485700}, + {t: 1587691657139, v: 485945}, {t: 1587691672139, v: 486228}, {t: 1587691687139, v: 486588}, {t: 1587691702139, v: 486691}, {t: 1587691717139, v: 486881}, {t: 1587691732139, v: 487046}, {t: 1587691747139, v: 487291}, {t: 1587691762177, v: 487410}, {t: 1587691777139, v: 487571}, {t: 1587691792139, v: 487799}, + {t: 1587691807139, v: 488050}, {t: 1587691822139, v: 488241}, {t: 1587691837139, v: 488424}, {t: 1587691852139, v: 488629}, {t: 1587691867139, v: 488875}, {t: 1587691882139, v: 489017}, {t: 1587691897139, v: 489254}, {t: 1587691912139, v: 489545}, {t: 1587691927139, v: 489778}, {t: 1587691942139, v: 489912}, + {t: 1587691957139, v: 490084}, {t: 1587691972139, v: 490364}, {t: 1587691987139, v: 490510}, {t: 1587692002139, v: 490744}, {t: 1587692017139, v: 490880}, {t: 1587692032139, v: 491025}, {t: 1587692047139, v: 491297}, {t: 1587692062155, v: 491557}, {t: 1587692077139, v: 491839}, {t: 1587692092139, v: 492065}, + {t: 1587692107139, v: 492234}, {t: 1587692122139, v: 492526}, {t: 1587692137139, v: 492767}, {t: 1587692152139, v: 492967}, {t: 1587692167139, v: 493218}, {t: 1587692182139, v: 493442}, {t: 1587692197139, v: 493647}, {t: 1587692212139, v: 493920}, {t: 1587692227139, v: 494170}, {t: 1587692242139, v: 494358}, + {t: 1587692257139, v: 494632}, {t: 1587692272139, v: 494800}, {t: 1587692287139, v: 495026}, {t: 1587692302139, v: 495222}, {t: 1587692317139, v: 495433}, {t: 1587692332139, v: 495677}, {t: 1587692347139, v: 495901}, {t: 1587692362139, v: 496107}, {t: 1587692377139, v: 496196}, {t: 1587692392139, v: 496245}, + {t: 1587692407139, v: 496300}, {t: 1587692422159, v: 496365}, {t: 1587692437139, v: 496401}, {t: 1587692452139, v: 496452}, {t: 1587692467139, v: 496532}, {t: 1587692542149, v: 496537}, {t: 1587692557139, v: 496633}, {t: 1587692572139, v: 496844}, {t: 1587692587139, v: 497040}, {t: 1587692602144, v: 497257}, + {t: 1587692617139, v: 497522}, {t: 1587692632139, v: 497710}, {t: 1587692647139, v: 497938}, {t: 1587692662154, v: 498172}, {t: 1587692677139, v: 498459}, {t: 1587692692139, v: 498635}, {t: 1587692707139, v: 498832}, {t: 1587692722139, v: 499014}, {t: 1587692737139, v: 499170}, {t: 1587692752139, v: 499338}, + {t: 1587692767139, v: 499511}, {t: 1587692782149, v: 499719}, {t: 1587692797139, v: 499973}, {t: 1587692812139, v: 500189}, {t: 1587692827139, v: 500359}, {t: 1587692842139, v: 500517}, {t: 1587692857139, v: 500727}, {t: 1587692872139, v: 500959}, {t: 1587692887139, v: 501178}, {t: 1587692902139, v: 501246}, + {t: 1587692917153, v: 501404}, {t: 1587692932139, v: 501663}, {t: 1587692947139, v: 501850}, {t: 1587692962139, v: 502103}, {t: 1587692977155, v: 502280}, {t: 1587692992139, v: 502562}, {t: 1587693007139, v: 502742}, {t: 1587693022139, v: 502931}, {t: 1587693037139, v: 503190}, {t: 1587693052139, v: 503428}, + {t: 1587693067139, v: 503630}, {t: 1587693082139, v: 503873}, {t: 1587693097139, v: 504027}, {t: 1587693112139, v: 504179}, {t: 1587693127139, v: 504362}, {t: 1587693142139, v: 504590}, {t: 1587693157139, v: 504741}, {t: 1587693172139, v: 505056}, {t: 1587693187139, v: 505244}, {t: 1587693202139, v: 505436}, + {t: 1587693217139, v: 505635}, {t: 1587693232139, v: 505936}, {t: 1587693247155, v: 506088}, {t: 1587693262139, v: 506309}, {t: 1587693277139, v: 506524}, {t: 1587693292139, v: 506800}, {t: 1587693307139, v: 507010}, {t: 1587693322139, v: 507286}, {t: 1587693337139, v: 507530}, {t: 1587693352139, v: 507781}, + {t: 1587693367139, v: 507991}, {t: 1587693382139, v: 508310}, {t: 1587693397139, v: 508570}, {t: 1587693412139, v: 508770}, {t: 1587693427139, v: 508982}, {t: 1587693442163, v: 509274}, {t: 1587693457139, v: 509477}, {t: 1587693472139, v: 509713}, {t: 1587693487139, v: 509972}, {t: 1587693502139, v: 510182}, + {t: 1587693517139, v: 510498}, {t: 1587693532139, v: 510654}, {t: 1587693547139, v: 510859}, {t: 1587693562139, v: 511124}, {t: 1587693577139, v: 511314}, {t: 1587693592139, v: 511488}, + }, + }, { + lset: labels.Labels{{Name: "replica", Value: "02"}}, + samples: []sample{ + {t: 1587690005791, v: 461968}, {t: 1587690020791, v: 462151}, {t: 1587690035797, v: 462336}, {t: 1587690050791, v: 462650}, {t: 1587690065791, v: 462813}, {t: 1587690080791, v: 462987}, {t: 1587690095791, v: 463095}, {t: 1587690110791, v: 463247}, {t: 1587690125791, v: 463440}, {t: 1587690140791, v: 463642}, {t: 1587690155791, v: 463811}, + {t: 1587690170791, v: 464027}, {t: 1587690185791, v: 464308}, {t: 1587690200791, v: 464514}, {t: 1587690215791, v: 464798}, {t: 1587690230791, v: 465018}, {t: 1587690245791, v: 465215}, {t: 1587690260813, v: 465431}, {t: 1587690275791, v: 465651}, {t: 1587690290791, v: 465870}, {t: 1587690305791, v: 466070}, {t: 1587690320792, v: 466248}, + {t: 1587690335791, v: 466506}, {t: 1587690350791, v: 466766}, {t: 1587690365791, v: 466970}, {t: 1587690380791, v: 467123}, {t: 1587690395791, v: 467265}, {t: 1587690410791, v: 467383}, {t: 1587690425791, v: 467629}, {t: 1587690440791, v: 467931}, {t: 1587690455791, v: 468097}, {t: 1587690470791, v: 468281}, {t: 1587690485791, v: 468477}, + {t: 1587690500791, v: 468649}, {t: 1587690515791, v: 468867}, {t: 1587690530791, v: 469150}, {t: 1587690545791, v: 469268}, {t: 1587690560791, v: 469488}, {t: 1587690575791, v: 469742}, {t: 1587690590791, v: 469951}, {t: 1587690605791, v: 470131}, {t: 1587690620791, v: 470337}, {t: 1587690635791, v: 470631}, {t: 1587690650791, v: 470832}, + {t: 1587690665791, v: 471077}, {t: 1587690680791, v: 471311}, {t: 1587690695791, v: 471473}, {t: 1587690710791, v: 471728}, {t: 1587690725791, v: 472002}, {t: 1587690740791, v: 472158}, {t: 1587690755791, v: 472329}, {t: 1587690770791, v: 472722}, {t: 1587690785791, v: 472925}, {t: 1587690800791, v: 473220}, {t: 1587690815791, v: 473460}, + {t: 1587690830791, v: 473748}, {t: 1587690845791, v: 473968}, {t: 1587690860791, v: 474261}, {t: 1587690875791, v: 474418}, {t: 1587690890791, v: 474726}, {t: 1587690905791, v: 474913}, {t: 1587690920791, v: 475031}, {t: 1587690935791, v: 475284}, {t: 1587690950791, v: 475563}, {t: 1587690965791, v: 475762}, {t: 1587690980791, v: 475945}, + {t: 1587690995791, v: 476302}, {t: 1587691010791, v: 476501}, {t: 1587691025791, v: 476849}, {t: 1587691040800, v: 477020}, {t: 1587691055791, v: 477280}, {t: 1587691070791, v: 477549}, {t: 1587691085791, v: 477758}, {t: 1587691100817, v: 477960}, {t: 1587691115791, v: 478261}, {t: 1587691130791, v: 478559}, {t: 1587691145791, v: 478704}, + {t: 1587691160804, v: 478950}, {t: 1587691175791, v: 479173}, {t: 1587691190791, v: 479368}, {t: 1587691205791, v: 479625}, {t: 1587691220805, v: 479866}, {t: 1587691235791, v: 480008}, {t: 1587691250791, v: 480155}, {t: 1587691265791, v: 480472}, {t: 1587691280811, v: 480598}, {t: 1587691295791, v: 480771}, {t: 1587691310791, v: 480996}, + {t: 1587691325791, v: 481200}, {t: 1587691340803, v: 481381}, {t: 1587691355791, v: 481584}, {t: 1587691370791, v: 481759}, {t: 1587691385791, v: 482003}, {t: 1587691400803, v: 482189}, {t: 1587691415791, v: 482457}, {t: 1587691430791, v: 482623}, {t: 1587691445791, v: 482768}, {t: 1587691460804, v: 483036}, {t: 1587691475791, v: 483322}, + {t: 1587691490791, v: 483566}, {t: 1587691505791, v: 483709}, {t: 1587691520807, v: 483838}, {t: 1587691535791, v: 484091}, {t: 1587691550791, v: 484236}, {t: 1587691565791, v: 484454}, {t: 1587691580816, v: 484710}, {t: 1587691595791, v: 484978}, {t: 1587691610791, v: 485271}, {t: 1587691625791, v: 485476}, {t: 1587691640792, v: 485640}, + {t: 1587691655791, v: 485921}, {t: 1587691670791, v: 486201}, {t: 1587691685791, v: 486555}, {t: 1587691700791, v: 486691}, {t: 1587691715791, v: 486831}, {t: 1587691730791, v: 487033}, {t: 1587691745791, v: 487268}, {t: 1587691760803, v: 487370}, {t: 1587691775791, v: 487571}, {t: 1587691790791, v: 487787}, {t: 1587691805791, v: 488036}, + {t: 1587691820791, v: 488241}, {t: 1587691835791, v: 488411}, {t: 1587691850791, v: 488625}, {t: 1587691865791, v: 488868}, {t: 1587691880791, v: 489005}, {t: 1587691895791, v: 489237}, {t: 1587691910791, v: 489545}, {t: 1587691925791, v: 489750}, {t: 1587691940791, v: 489899}, {t: 1587691955791, v: 490048}, {t: 1587691970791, v: 490364}, + {t: 1587691985791, v: 490485}, {t: 1587692000791, v: 490722}, {t: 1587692015791, v: 490866}, {t: 1587692030791, v: 491025}, {t: 1587692045791, v: 491286}, {t: 1587692060816, v: 491543}, {t: 1587692075791, v: 491787}, {t: 1587692090791, v: 492065}, {t: 1587692105791, v: 492223}, {t: 1587692120816, v: 492501}, {t: 1587692135791, v: 492767}, + {t: 1587692150791, v: 492955}, {t: 1587692165791, v: 493194}, {t: 1587692180792, v: 493402}, {t: 1587692195791, v: 493647}, {t: 1587692210791, v: 493897}, {t: 1587692225791, v: 494117}, {t: 1587692240805, v: 494356}, {t: 1587692255791, v: 494620}, {t: 1587692270791, v: 494762}, {t: 1587692285791, v: 495001}, {t: 1587692300805, v: 495222}, + {t: 1587692315791, v: 495393}, {t: 1587692330791, v: 495662}, {t: 1587692345791, v: 495875}, {t: 1587692360801, v: 496082}, {t: 1587692375791, v: 496196}, {t: 1587692390791, v: 496245}, {t: 1587692405791, v: 496295}, {t: 1587692420791, v: 496365}, {t: 1587692435791, v: 496401}, {t: 1587692450791, v: 496452}, {t: 1587692465791, v: 496491}, + {t: 1587692480791, v: 496544}, {t: 1587692555791, v: 496619}, {t: 1587692570791, v: 496852}, {t: 1587692585791, v: 497052}, {t: 1587692600791, v: 497245}, {t: 1587692615791, v: 497529}, {t: 1587692630791, v: 497697}, {t: 1587692645791, v: 497909}, {t: 1587692660791, v: 498156}, {t: 1587692675803, v: 498466}, {t: 1587692690791, v: 498647}, + {t: 1587692705791, v: 498805}, {t: 1587692720791, v: 499013}, {t: 1587692735805, v: 499169}, {t: 1587692750791, v: 499345}, {t: 1587692765791, v: 499499}, {t: 1587692780791, v: 499731}, {t: 1587692795806, v: 499972}, {t: 1587692810791, v: 500201}, {t: 1587692825791, v: 500354}, {t: 1587692840791, v: 500512}, {t: 1587692855791, v: 500739}, + {t: 1587692870791, v: 500958}, {t: 1587692885791, v: 501190}, {t: 1587692900791, v: 501233}, {t: 1587692915791, v: 501391}, {t: 1587692930791, v: 501649}, {t: 1587692945791, v: 501853}, {t: 1587692960791, v: 502065}, {t: 1587692975791, v: 502239}, {t: 1587692990810, v: 502554}, {t: 1587693005791, v: 502754}, {t: 1587693020791, v: 502938}, + {t: 1587693035791, v: 503141}, {t: 1587693050791, v: 503416}, {t: 1587693065791, v: 503642}, {t: 1587693080791, v: 503873}, {t: 1587693095791, v: 504014}, {t: 1587693110791, v: 504178}, {t: 1587693125821, v: 504374}, {t: 1587693140791, v: 504578}, {t: 1587693155791, v: 504753}, {t: 1587693170791, v: 505043}, {t: 1587693185791, v: 505232}, + {t: 1587693200791, v: 505437}, {t: 1587693215791, v: 505596}, {t: 1587693230791, v: 505923}, {t: 1587693245791, v: 506088}, {t: 1587693260791, v: 506307}, {t: 1587693275791, v: 506518}, {t: 1587693290791, v: 506786}, {t: 1587693305791, v: 507008}, {t: 1587693320803, v: 507260}, {t: 1587693335791, v: 507519}, {t: 1587693350791, v: 507776}, + {t: 1587693365791, v: 508003}, {t: 1587693380791, v: 508322}, {t: 1587693395804, v: 508551}, {t: 1587693410791, v: 508750}, {t: 1587693425791, v: 508994}, {t: 1587693440791, v: 509237}, {t: 1587693455791, v: 509452}, {t: 1587693470791, v: 509702}, {t: 1587693485791, v: 509971}, {t: 1587693500791, v: 510147}, {t: 1587693515791, v: 510471}, + {t: 1587693530816, v: 510666}, {t: 1587693545791, v: 510871}, {t: 1587693560791, v: 511123}, {t: 1587693575791, v: 511303}, {t: 1587693590791, v: 511500}, + }, + }, + }, + exp: []series{ + { + lset: labels.Labels{}, + samples: expectedRealSeriesWithStaleMarkerDeduplicatedForRate, + }, + }, + dedupLabels: map[string]struct{}{"replica": {}}, + }, } - for _, test := range tests { + for _, tcase := range tests { t.Run("", func(t *testing.T) { - var series []storepb.Series - for _, c := range test.input { - chk := chunkenc.NewXORChunk() - app, _ := chk.Appender() - for _, s := range c.vals { - app.Append(s.t, s.v) - } - series = append(series, storepb.Series{ - Labels: c.lset, - Chunks: []storepb.AggrChunk{ - {Raw: &storepb.Chunk{Type: storepb.Chunk_XOR, Data: chk.Bytes()}}, - }, - }) - } - set := &promSeriesSet{ - mint: 1, - maxt: math.MaxInt64, - set: newStoreSeriesSet(series), - } - dedupSet := newDedupSeriesSet(set, test.dedupLabels) - - i := 0 + dedupSet := newDedupSeriesSet(&mockedSeriesSet{series: tcase.input}, tcase.dedupLabels, tcase.isCounter) + var ats []storage.Series for dedupSet.Next() { - testutil.Equals(t, test.exp[i].lset, dedupSet.At().Labels(), "labels mismatch at index:%v", i) - res := expandSeries(t, dedupSet.At().Iterator()) - testutil.Equals(t, test.exp[i].vals, res, "values mismatch at index:%v", i) - i++ + ats = append(ats, dedupSet.At()) } testutil.Ok(t, dedupSet.Err()) + testutil.Equals(t, len(tcase.exp), len(ats)) + + for i, s := range ats { + testutil.Equals(t, tcase.exp[i].lset, s.Labels(), "labels mismatch for series %v", i) + res := expandSeries(t, s.Iterator()) + testutil.Equals(t, tcase.exp[i].samples, res, "values mismatch for series :%v", i) + } }) } } @@ -604,10 +1286,10 @@ func TestDedupSeriesIterator(t *testing.T) { for i, c := range cases { t.Logf("case %d:", i) it := newDedupSeriesIterator( - &SampleIterator{l: c.a, i: -1}, - &SampleIterator{l: c.b, i: -1}, + noopAdjustableSeriesIterator{newMockedSeriesIterator(c.a)}, + noopAdjustableSeriesIterator{newMockedSeriesIterator(c.b)}, ) - res := expandSeries(t, it) + res := expandSeries(t, noopAdjustableSeriesIterator{it}) testutil.Equals(t, c.exp, res) } } @@ -615,8 +1297,8 @@ func TestDedupSeriesIterator(t *testing.T) { func BenchmarkDedupSeriesIterator(b *testing.B) { run := func(b *testing.B, s1, s2 []sample) { it := newDedupSeriesIterator( - &SampleIterator{l: s1, i: -1}, - &SampleIterator{l: s2, i: -1}, + noopAdjustableSeriesIterator{newMockedSeriesIterator(s1)}, + noopAdjustableSeriesIterator{newMockedSeriesIterator(s2)}, ) b.ResetTimer() var total int64 @@ -662,47 +1344,6 @@ func BenchmarkDedupSeriesIterator(b *testing.B) { }) } -type sample struct { - t int64 - v float64 -} - -type SampleIterator struct { - l []sample - i int -} - -func (s *SampleIterator) Err() error { - return nil -} - -func (s *SampleIterator) At() (int64, float64) { - return s.l[s.i].t, s.l[s.i].v -} - -func (s *SampleIterator) Next() bool { - if s.i >= len(s.l) { - return false - } - s.i++ - return true -} - -func (s *SampleIterator) Seek(t int64) bool { - if s.i < 0 { - s.i = 0 - } - for { - if s.i >= len(s.l) { - return false - } - if s.l[s.i].t >= t { - return true - } - s.i++ - } -} - type storeServer struct { // This field just exist to pseudo-implement the unused methods of the interface. storepb.StoreServer diff --git a/pkg/query/storeset.go b/pkg/query/storeset.go index 2509d38dc7..2decadb15b 100644 --- a/pkg/query/storeset.go +++ b/pkg/query/storeset.go @@ -36,6 +36,8 @@ type StoreSpec interface { // NOTE: It is implementation responsibility to retry until context timeout, but a caller responsibility to manage // given store connection. Metadata(ctx context.Context, client storepb.StoreClient) (labelSets []storepb.LabelSet, mint int64, maxt int64, Type component.StoreAPI, err error) + // StrictStatic returns true if the StoreAPI has been statically defined and it is under a strict mode. + StrictStatic() bool } type RuleSpec interface { @@ -44,23 +46,29 @@ type RuleSpec interface { } type StoreStatus struct { - Name string - LastCheck time.Time - LastError error - LabelSets []storepb.LabelSet - StoreType component.StoreAPI - MinTime int64 - MaxTime int64 + Name string `json:"name"` + LastCheck time.Time `json:"last_check"` + LastError error `json:"last_error"` + LabelSets []storepb.LabelSet `json:"label_sets"` + StoreType component.StoreAPI `json:"store_type"` + MinTime int64 `json:"min_time"` + MaxTime int64 `json:"max_time"` } type grpcStoreSpec struct { - addr string + addr string + strictstatic bool } // NewGRPCStoreSpec creates store pure gRPC spec. // It uses Info gRPC call to get Metadata. -func NewGRPCStoreSpec(addr string) *grpcStoreSpec { - return &grpcStoreSpec{addr: addr} +func NewGRPCStoreSpec(addr string, strictstatic bool) *grpcStoreSpec { + return &grpcStoreSpec{addr: addr, strictstatic: strictstatic} +} + +// StrictStatic returns true if the StoreAPI has been statically defined and it is under a strict mode. +func (s *grpcStoreSpec) StrictStatic() bool { + return s.strictstatic } func (s *grpcStoreSpec) Addr() string { @@ -82,15 +90,14 @@ func (s *grpcStoreSpec) Metadata(ctx context.Context, client storepb.StoreClient return resp.LabelSets, resp.MinTime, resp.MaxTime, component.FromProto(resp.StoreType), nil } -// storeSetNodeCollector is metric collector for Guge indicated number of available storeAPIs for Querier. -// Collector is requires as we want atomic updates for all 'thanos_store_nodes_grpc_connections' series. +// storeSetNodeCollector is a metric collector reporting the number of available storeAPIs for Querier. +// A Collector is required as we want atomic updates for all 'thanos_store_nodes_grpc_connections' series. type storeSetNodeCollector struct { mtx sync.Mutex storeNodes map[component.StoreAPI]map[string]int storePerExtLset map[string]int connectionsDesc *prometheus.Desc - nodeInfoDesc *prometheus.Desc } func newStoreSetNodeCollector() *storeSetNodeCollector { @@ -101,13 +108,6 @@ func newStoreSetNodeCollector() *storeSetNodeCollector { "Number of gRPC connection to Store APIs. Opened connection means healthy store APIs available for Querier.", []string{"external_labels", "store_type"}, nil, ), - // TODO(bwplotka): Obsolete; Replaced by thanos_store_nodes_grpc_connections. - // Remove in next minor release. - nodeInfoDesc: prometheus.NewDesc( - "thanos_store_node_info", - "Deprecated, use thanos_store_nodes_grpc_connections instead.", - []string{"external_labels"}, nil, - ), } } @@ -131,7 +131,6 @@ func (c *storeSetNodeCollector) Update(nodes map[component.StoreAPI]map[string]i func (c *storeSetNodeCollector) Describe(ch chan<- *prometheus.Desc) { ch <- c.connectionsDesc - ch <- c.nodeInfoDesc } func (c *storeSetNodeCollector) Collect(ch chan<- prometheus.Metric) { @@ -147,9 +146,6 @@ func (c *storeSetNodeCollector) Collect(ch chan<- prometheus.Metric) { ch <- prometheus.MustNewConstMetric(c.connectionsDesc, prometheus.GaugeValue, float64(occurrences), externalLabels, storeTypeStr) } } - for externalLabels, occur := range c.storePerExtLset { - ch <- prometheus.MustNewConstMetric(c.nodeInfoDesc, prometheus.GaugeValue, float64(occur), externalLabels) - } } // StoreSet maintains a set of active stores. It is backed up by Store Specifications that are dynamically fetched on @@ -340,7 +336,7 @@ func newStoreAPIStats() map[component.StoreAPI]map[string]int { } // Update updates the store set. It fetches current list of store specs from function and updates the fresh metadata -// from all stores. +// from all stores. Keeps around statically defined nodes that were defined with the strict mode. func (s *StoreSet) Update(ctx context.Context) { s.updateMtx.Lock() defer s.updateMtx.Unlock() @@ -354,14 +350,14 @@ func (s *StoreSet) Update(ctx context.Context) { level.Debug(s.logger).Log("msg", "starting updating storeAPIs", "cachedStores", len(stores)) - healthyStores := s.getHealthyStores(ctx, stores) - level.Debug(s.logger).Log("msg", "checked requested storeAPIs", "healthyStores", len(healthyStores), "cachedStores", len(stores)) + activeStores := s.getActiveStores(ctx, stores) + level.Debug(s.logger).Log("msg", "checked requested storeAPIs", "activeStores", len(activeStores), "cachedStores", len(stores)) stats := newStoreAPIStats() - // Close stores that where not healthy this time (are not in healthy stores map). + // Close stores that where not active this time (are not in active stores map). for addr, st := range stores { - if _, ok := healthyStores[addr]; ok { + if _, ok := activeStores[addr]; ok { stats[st.StoreType()][st.LabelSetsString()]++ continue } @@ -373,7 +369,7 @@ func (s *StoreSet) Update(ctx context.Context) { } // Add stores that are not yet in stores. - for addr, st := range healthyStores { + for addr, st := range activeStores { if _, ok := stores[addr]; ok { continue } @@ -409,20 +405,20 @@ func (s *StoreSet) Update(ctx context.Context) { s.cleanUpStoreStatuses(stores) } -func (s *StoreSet) getHealthyStores(ctx context.Context, stores map[string]*storeRef) map[string]*storeRef { +func (s *StoreSet) getActiveStores(ctx context.Context, stores map[string]*storeRef) map[string]*storeRef { var ( - storeAddrSet = make(map[string]struct{}) - ruleAddrSet = make(map[string]struct{}) - healthyStores = make(map[string]*storeRef, len(stores)) - mtx sync.Mutex - wg sync.WaitGroup + storeAddrSet = make(map[string]struct{}) + ruleAddrSet = make(map[string]struct{}) + activeStores = make(map[string]*storeRef, len(stores)) + mtx sync.Mutex + wg sync.WaitGroup ) for _, ruleSpec := range s.ruleSpecs() { ruleAddrSet[ruleSpec.Addr()] = struct{}{} } - // Gather healthy stores map concurrently. Build new store if does not exist already. + // Gather active stores map concurrently. Build new store if does not exist already. for _, storeSpec := range s.storeSpecs() { if _, ok := storeAddrSet[storeSpec.Addr()]; ok { level.Warn(s.logger).Log("msg", "duplicated address in store nodes", "address", storeSpec.Addr()) @@ -441,41 +437,52 @@ func (s *StoreSet) getHealthyStores(ctx context.Context, stores map[string]*stor st, seenAlready := stores[addr] if !seenAlready { - // New store or was unhealthy and was removed in the past - create new one. + // New store or was unactive and was removed in the past - create new one. conn, err := grpc.DialContext(ctx, addr, s.dialOpts...) if err != nil { s.updateStoreStatus(&storeRef{addr: addr}, err) level.Warn(s.logger).Log("msg", "update of store node failed", "err", errors.Wrap(err, "dialing connection"), "address", addr) return } - var rule storepb.RulesClient if _, ok := ruleAddrSet[addr]; ok { rule = storepb.NewRulesClient(conn) } - st = &storeRef{StoreClient: storepb.NewStoreClient(conn), rule: rule, cc: conn, addr: addr, logger: s.logger} + st = &storeRef{StoreClient: storepb.NewStoreClient(conn), rule: rule, storeType: component.UnknownStoreAPI, cc: conn, addr: addr, logger: s.logger} } // Check existing or new store. Is it healthy? What are current metadata? labelSets, minTime, maxTime, storeType, err := spec.Metadata(ctx, st.StoreClient) if err != nil { - if !seenAlready { - // Close only if new. Unhealthy `s.stores` will be closed later on. + if !seenAlready && !spec.StrictStatic() { + // Close only if new and not a strict static node. + // Unactive `s.stores` will be closed later on. st.Close() } s.updateStoreStatus(st, err) level.Warn(s.logger).Log("msg", "update of store node failed", "err", errors.Wrap(err, "getting metadata"), "address", addr) + + if !spec.StrictStatic() { + return + } + + // Still keep it around if static & strict mode enabled. + mtx.Lock() + defer mtx.Unlock() + + activeStores[addr] = st return } + s.updateStoreStatus(st, nil) st.Update(labelSets, minTime, maxTime, storeType) mtx.Lock() defer mtx.Unlock() - healthyStores[addr] = st + activeStores[addr] = st }(storeSpec) } wg.Wait() @@ -486,7 +493,7 @@ func (s *StoreSet) getHealthyStores(ctx context.Context, stores map[string]*stor } } - return healthyStores + return activeStores } func (s *StoreSet) updateStoreStatus(store *storeRef, err error) { @@ -500,10 +507,9 @@ func (s *StoreSet) updateStoreStatus(store *storeRef, err error) { } status.LastError = err - status.LastCheck = time.Now() if err == nil { - + status.LastCheck = time.Now() mint, maxt := store.TimeRange() status.LabelSets = store.LabelSets() status.StoreType = store.StoreType() diff --git a/pkg/query/storeset_test.go b/pkg/query/storeset_test.go index 5a6e109728..3ca89cb200 100644 --- a/pkg/query/storeset_test.go +++ b/pkg/query/storeset_test.go @@ -27,10 +27,14 @@ var testGRPCOpts = []grpc.DialOption{ } type testStore struct { - info storepb.InfoResponse + infoDelay time.Duration + info storepb.InfoResponse } func (s *testStore) Info(ctx context.Context, r *storepb.InfoRequest) (*storepb.InfoResponse, error) { + if s.infoDelay > 0 { + time.Sleep(s.infoDelay) + } return &s.info, nil } @@ -51,8 +55,10 @@ func (s *testStore) LabelValues(ctx context.Context, r *storepb.LabelValuesReque } type testStoreMeta struct { - extlsetFn func(addr string) []storepb.LabelSet - storeType component.StoreAPI + extlsetFn func(addr string) []storepb.LabelSet + storeType component.StoreAPI + minTime, maxTime int64 + infoDelay time.Duration } type testStores struct { @@ -78,7 +84,10 @@ func startTestStores(storeMetas []testStoreMeta) (*testStores, error) { storeSrv := &testStore{ info: storepb.InfoResponse{ LabelSets: meta.extlsetFn(listener.Addr().String()), + MaxTime: meta.maxTime, + MinTime: meta.minTime, }, + infoDelay: meta.infoDelay, } if meta.storeType != nil { storeSrv.info.StoreType = meta.storeType.ToProto() @@ -174,15 +183,12 @@ func TestStoreSet_Update(t *testing.T) { discoveredStoreAddr := stores.StoreAddresses() - // Start with one not available. - stores.CloseOne(discoveredStoreAddr[2]) - // Testing if duplicates can cause weird results. discoveredStoreAddr = append(discoveredStoreAddr, discoveredStoreAddr[0]) storeSet := NewStoreSet(nil, nil, func() (specs []StoreSpec) { for _, addr := range discoveredStoreAddr { - specs = append(specs, NewGRPCStoreSpec(addr)) + specs = append(specs, NewGRPCStoreSpec(addr, false)) } return specs }, @@ -193,6 +199,12 @@ func TestStoreSet_Update(t *testing.T) { storeSet.gRPCInfoCallTimeout = 2 * time.Second defer storeSet.Close() + // Initial update. + storeSet.Update(context.Background()) + + // Start with one not available. + stores.CloseOne(discoveredStoreAddr[2]) + // Should not matter how many of these we run. storeSet.Update(context.Background()) storeSet.Update(context.Background()) @@ -460,7 +472,7 @@ func TestStoreSet_Update(t *testing.T) { // Check stats. expected = newStoreAPIStats() - expected[component.StoreAPI(nil)] = map[string]int{ + expected[component.UnknownStoreAPI] = map[string]int{ "{l1=\"no-store-type\", l2=\"v3\"}": 1, } expected[component.Query] = map[string]int{ @@ -529,7 +541,7 @@ func TestStoreSet_Update_NoneAvailable(t *testing.T) { storeSet := NewStoreSet(nil, nil, func() (specs []StoreSpec) { for _, addr := range initialStoreAddr { - specs = append(specs, NewGRPCStoreSpec(addr)) + specs = append(specs, NewGRPCStoreSpec(addr, false)) } return specs }, @@ -540,7 +552,7 @@ func TestStoreSet_Update_NoneAvailable(t *testing.T) { // Should not matter how many of these we run. storeSet.Update(context.Background()) storeSet.Update(context.Background()) - testutil.Assert(t, len(storeSet.stores) == 0, "none of services should respond just fine, so we expect no client to be ready.") + testutil.Equals(t, 0, len(storeSet.stores), "none of services should respond just fine, so we expect no client to be ready.") // Leak test will ensure that we don't keep client connection around. @@ -577,8 +589,8 @@ func TestStoreSet_Update_Rules(t *testing.T) { name: "stores, no rules", storeSpecs: func() []StoreSpec { return []StoreSpec{ - NewGRPCStoreSpec(stores.orderAddrs[0]), - NewGRPCStoreSpec(stores.orderAddrs[1]), + NewGRPCStoreSpec(stores.orderAddrs[0], false), + NewGRPCStoreSpec(stores.orderAddrs[1], false), } }, expectedStores: 2, @@ -588,7 +600,7 @@ func TestStoreSet_Update_Rules(t *testing.T) { name: "rules, no stores", ruleSpecs: func() []RuleSpec { return []RuleSpec{ - NewGRPCStoreSpec(stores.orderAddrs[0]), + NewGRPCStoreSpec(stores.orderAddrs[0], false), } }, expectedStores: 0, @@ -598,12 +610,12 @@ func TestStoreSet_Update_Rules(t *testing.T) { name: "one store, different rule", storeSpecs: func() []StoreSpec { return []StoreSpec{ - NewGRPCStoreSpec(stores.orderAddrs[0]), + NewGRPCStoreSpec(stores.orderAddrs[0], false), } }, ruleSpecs: func() []RuleSpec { return []RuleSpec{ - NewGRPCStoreSpec(stores.orderAddrs[1]), + NewGRPCStoreSpec(stores.orderAddrs[1], false), } }, expectedStores: 1, @@ -613,13 +625,13 @@ func TestStoreSet_Update_Rules(t *testing.T) { name: "two stores, one rule", storeSpecs: func() []StoreSpec { return []StoreSpec{ - NewGRPCStoreSpec(stores.orderAddrs[0]), - NewGRPCStoreSpec(stores.orderAddrs[1]), + NewGRPCStoreSpec(stores.orderAddrs[0], false), + NewGRPCStoreSpec(stores.orderAddrs[1], false), } }, ruleSpecs: func() []RuleSpec { return []RuleSpec{ - NewGRPCStoreSpec(stores.orderAddrs[0]), + NewGRPCStoreSpec(stores.orderAddrs[0], false), } }, expectedStores: 2, @@ -629,14 +641,14 @@ func TestStoreSet_Update_Rules(t *testing.T) { name: "two stores, two rules", storeSpecs: func() []StoreSpec { return []StoreSpec{ - NewGRPCStoreSpec(stores.orderAddrs[0]), - NewGRPCStoreSpec(stores.orderAddrs[1]), + NewGRPCStoreSpec(stores.orderAddrs[0], false), + NewGRPCStoreSpec(stores.orderAddrs[1], false), } }, ruleSpecs: func() []RuleSpec { return []RuleSpec{ - NewGRPCStoreSpec(stores.orderAddrs[0]), - NewGRPCStoreSpec(stores.orderAddrs[1]), + NewGRPCStoreSpec(stores.orderAddrs[0], false), + NewGRPCStoreSpec(stores.orderAddrs[1], false), } }, expectedStores: 2, @@ -663,3 +675,104 @@ func TestStoreSet_Update_Rules(t *testing.T) { }) } } + +// TestQuerierStrict tests what happens when the strict mode is enabled/disabled. +func TestQuerierStrict(t *testing.T) { + defer leaktest.CheckTimeout(t, 5*time.Second)() + + st, err := startTestStores([]testStoreMeta{ + { + minTime: 12345, + maxTime: 54321, + extlsetFn: func(addr string) []storepb.LabelSet { + return []storepb.LabelSet{ + { + Labels: []storepb.Label{ + { + Name: "addr", + Value: addr, + }, + }, + }, + } + }, + storeType: component.Sidecar, + }, + { + minTime: 66666, + maxTime: 77777, + extlsetFn: func(addr string) []storepb.LabelSet { + return []storepb.LabelSet{ + { + Labels: []storepb.Label{ + { + Name: "addr", + Value: addr, + }, + }, + }, + } + }, + storeType: component.Sidecar, + }, + // Slow store. + { + minTime: 65644, + maxTime: 77777, + extlsetFn: func(addr string) []storepb.LabelSet { + return []storepb.LabelSet{ + { + Labels: []storepb.Label{ + { + Name: "addr", + Value: addr, + }, + }, + }, + } + }, + storeType: component.Sidecar, + infoDelay: 2 * time.Second, + }, + }) + + testutil.Ok(t, err) + defer st.Close() + + staticStoreAddr := st.StoreAddresses()[0] + storeSet := NewStoreSet(nil, nil, func() (specs []StoreSpec) { + return []StoreSpec{ + NewGRPCStoreSpec(st.StoreAddresses()[0], true), + NewGRPCStoreSpec(st.StoreAddresses()[1], false), + NewGRPCStoreSpec(st.StoreAddresses()[2], true), + } + }, nil, testGRPCOpts, time.Minute) + defer storeSet.Close() + storeSet.gRPCInfoCallTimeout = 1 * time.Second + + // Initial update. + storeSet.Update(context.Background()) + testutil.Equals(t, 3, len(storeSet.stores), "three clients must be available for running store nodes") + + testutil.Assert(t, storeSet.stores[st.StoreAddresses()[2]].cc.GetState().String() != "SHUTDOWN", "slow store's connection should not be closed") + + // The store is statically defined + strict mode is enabled + // so its client + information must be retained. + curMin, curMax := storeSet.stores[staticStoreAddr].minTime, storeSet.stores[staticStoreAddr].maxTime + testutil.Equals(t, int64(12345), curMin, "got incorrect minimum time") + testutil.Equals(t, int64(54321), curMax, "got incorrect minimum time") + + // Turn off the stores. + st.Close() + + // Update again many times. Should not matter WRT the static one. + storeSet.Update(context.Background()) + storeSet.Update(context.Background()) + storeSet.Update(context.Background()) + + // Check that the information is the same. + testutil.Equals(t, 2, len(storeSet.stores), "two static clients must remain available") + testutil.Equals(t, curMin, storeSet.stores[staticStoreAddr].minTime, "minimum time reported by the store node is different") + testutil.Equals(t, curMax, storeSet.stores[staticStoreAddr].maxTime, "minimum time reported by the store node is different") + testutil.NotOk(t, storeSet.storeStatuses[staticStoreAddr].LastError) +} diff --git a/pkg/query/testdata/issue2401-seriesresponses.json b/pkg/query/testdata/issue2401-seriesresponses.json new file mode 100644 index 0000000000..82faab987a --- /dev/null +++ b/pkg/query/testdata/issue2401-seriesresponses.json @@ -0,0 +1,480 @@ +{ + "series": { + "labels": [ + { + "name": "__name__", + "value": "gitlab_transaction_cache_read_hit_count_total" + }, + { + "name": "action", + "value": "widget.json" + }, + { + "name": "controller", + "value": "Projects::MergeRequests::ContentController" + }, + { + "name": "env", + "value": "gprd" + }, + { + "name": "environment", + "value": "gprd" + }, + { + "name": "fqdn", + "value": "web-08-sv-gprd.c.gitlab-production.internal" + }, + { + "name": "instance", + "value": "web-08-sv-gprd.c.gitlab-production.internal:8083" + }, + { + "name": "job", + "value": "gitlab-rails" + }, + { + "name": "monitor", + "value": "app" + }, + { + "name": "provider", + "value": "gcp" + }, + { + "name": "region", + "value": "us-east" + }, + { + "name": "replica", + "value": "01" + }, + { + "name": "shard", + "value": "default" + }, + { + "name": "stage", + "value": "main" + }, + { + "name": "tier", + "value": "sv" + }, + { + "name": "type", + "value": "web" + } + ], + "chunks": [ + { + "minTime": "1587679207139", + "maxTime": "1587680992139", + "raw": { + "data": "AHjG+/CQtVxBEeOIAAAAAJh16jw3Qrd0qbmVwqUJ1Jnrch/6qASJAaagF8QOIoBHUBtKDt5ALqgMsQCHIHP0A8CAxNAKwh7eQG8oB8ED96AdlAY4gEVQeboBBUBmSAUhA18gPWQCRI/FUApCAwFA1OgHUQHzoBV0HsSAYtAZkgF3QOPIB0UB66ASdD1YgNyQCWoHF0AgMAHwBeX/FAXTAB8HiiARCAGIDJL/QgEAgBiAO1A44gLOQCaJ/tUApSAyVAJmgbVQGXoBfoAUg8Uv9iARqAFIDN0Aw6Bu5AGygNxQCcIfHIAPgFdv+KA1mAD4BR0DeiA6ZAPMg+9QCDIDJEAmCB3FAKAgMfQCao/sEAmqAwxAJ+gclQDioDK0AvqDypAI8gKXQBKIHWkBUSANZAK+h8ygBCApC/4IA8IAQgFCQOmoBN4AOgLFv+SD20A=" + } + }, + { + "minTime": "1587681007139", + "maxTime": "1587682792139", + "raw": { + "data": "AHjG2MyStVxBE+SMAAAAAJh16FaPACE9V/wcyuHgBCNtNuhQRINqP/FUAUFAO/gBKALHf7kB3uAEoAaKAWSgBkQADA6tv/6AIDAAMA8tAFAQHKkAUxANLQBHUHy9AETQDZUAV9AdWgA+AIbf8UA+uAD4AiiB7egBmQAZAECv+iAYnABkASRAcGQBNEAxtAEzQ/b0ARZANDQG50AQtAMtQBJkAO5A6/QDBkAUZADBQGgUAydAF7QffYAUgDW3+xANigBSAP0gPuIA66AfigCgIHcqAZTACEARe/4IDqkAIQBXUANhALeR/ekAWNAM3QAzEARZAcDQBIkA0lAHCQPH0AfRAPQQBaUBzJACtQBA0A79AEBgBSD7Ff7EAVeAFIBvyALQgO+IAvqAHMgHVoAryB98gDmoB+iAI2gOlwAhAETv+CAYRACEAVFD84QBSoAVgGKX+tAFFgBWA+kgDvIBiCAPageUIAiaAeCgC5IDbSAGAA==" + } + }, + { + "minTime": "1587682807139", + "maxTime": "1587684592139", + "raw": { + "data": "AHjGtaiUtVxBFbqwAAAAAJh16kxVxN+SoPygSCGPoI0juKD+oZGg6afBIECg3cAHQOm/5IZfAB0FBR81B30BbQwdBAG5D+30BiKAKSAKYBxL/igcEv8GATmAUIDNb/IgFCgByDxZAI2gCoQG0IGxEAjaAPZAaAgFzQ+XIBc0Bk6AeZA6SgDDgBCARi/4IDDYAQgFCQfuQAfAOBf8UB7MAHwCgoA4EDqSAQFAeogEER+VoB2EB6KAdJA/CgHkQGIoBQUHkqAQpAZCgElQOfICyEAWKAclD66gEeQBroDfUA3KBzZAJKgDRQFfIPXUAj6AMOAEoDE7/cgbbgBKAUpAYCgELT+WIBA0BqsAHwCSX/FAGrAB8DnCAbWAE4Akr/agO2gBOASdAFdACEHpV/wQCfQAhAfIgHwQPcoBBkAbKAzpAKwh/sQD9IDzYAXgHcv9KB7aAF4AmUAjaA3xAJag7VA=" + } + }, + { + "minTime": "1587684607139", + "maxTime": "1587686392139", + "raw": { + "data": "AHjGkoSWtVxBF2kcAAAAAJh16k0VM5zL7qjwJsSJyhSOBn7bqRmuhGa7EaLqTa3MXrqT9XQjPdh7LqJLkZ6KhukbIhA06wg10Kij/EIE4k/10KqlHQmXcy+/ogCGMmjo3bkZ5egu0KyiyE5EgtkK0jA0MA2Jf/SoAQNAGKoAZNAO6IAThAGHoAQFAB/ID3xACtoA19ADXoB1BAC9IAz1AC1IHwxACGIAwxAC1oB2FABTIAXZAHgoAKBACEoD0JADjoA2xABgIAQJAOuIAcFABcoAuqAGIPx6/0IASyAGIAwFACVQAhABDX/BAOBQAhADvoA2FACMoD7RACJoAzqAFIAce/2IB+OAFIAR9AGOwAhACK3/BA+HwAhADYoAwKAFIASS/2IAM2AFIBytAC/wAlAHe3+5ABlQAlACjoDzeAGIAde/0IA3+AGIAM5AC9IAHJAOIoAXhAHuwAxACM3+hD+CwAxACVg=" + } + }, + { + "minTime": "1587686407139", + "maxTime": "1587688192139", + "raw": { + "data": "AHjG79+XtVxBGQjEAAAAAJh17EdrqRPuZfCUUOAD5lV/xR94AP5F+HdSeS6DZupEa5l/9ROULtNZRYXE36ag8iHroOYjpKBjIL6h9qBBIPUnj6BFIIghgKCDo5cgkKGHoLu4HfkKBLkGxIENQ4ygbNARqDgEBooEWR8lACkCk3+xBi8AKQJUgNOAF4dUv9KBCoAXg8VArqAr0/MoEvQGIgqRDpKArkD7oPsQIcj8ZApMAIQcvf8EDuQAhDgSBV0GOoD7QJW3If4CgGHQG7oBe0D4qAaRAZygDuQCQIPE4ATgFAv9qA4WAE4A60AzkAHQONX/JAJ5AB0BjSAL5D2AgDYQCGIDaYAHgH6v/KByaAB4BG0BksAHwCWX/FAF1AB8H0aAKdAKYgMZQCQIHqoARgDUv96AvOAEYAXUAWMAIR9H3/BAKLACEBsyAIBAKIgcCQDtoDxUAyA=" + } + }, + { + "minTime": "1587688207139", + "maxTime": "1587689992139", + "raw": { + "data": "AHjGzLuZtVxBGp6wAAAAAJh15F/rQlEbpDTcy+Ao4sAHzB7/iiPQAfDjcTfXqBJIfMglyO1oHDACMF5v96H9wAjAp07nQTBDRUFFQJxHFUHeQxxAlW8791QDM6k610E11Jg8AJ8yuZv9qFGAE+pPvdCsNSruRnhKFXRqiDfQtKcIQ76NKQnKCkcTPw3YjldSdvAB3Qrfb/kjfgA6Q5zH9upFHADEzX+h0K3uAGJGHIzxlCPI+xCUoLlPEIfhGFocZwO/Y0CPIDJQasgcqACodAv+yA/IAKgVJB/CBM0eQoFZQbMgRaADYcDv+aAsIANgURBmyBxU+nIDZQKcg4uADoEPv+SHJYAOgNVBeqA5IAMgWS/6I8cgAyB+kGlQADAmN//Q5DAAMC1oMCQIYgJZtQ/4t1JvboTn03XYj1cyeG6FWTAAMXt//SawADyL8K6k9dIt0JwqWAA=" + } + }, + { + "minTime": "1587690007139", + "maxTime": "1587691792139", + "raw": { + "data": "AHjGqZebtVxBHDKkAAAAAJh16k/10Kx1IeiucTfscAIQY+/4IEzACEP0QXNA1UcOQQxDe0EdgAGeR3/9BxYABhtCCAoHwjv6D0wAXDLL/qggMAF8Dv31Aa6BjEB7IMIQKwh35A76DB0BCoFLR5agYNBlKBH0BtodXQOQg9NA3qfGECbID8QZygRRD1KBSUHBIHUR++gd9B9qBDkOcoGZQcmgYlAXTef/I0BAUDPUB0EH7UByEDp0Bs0PEEB8EDwkBd0HZEBB0DR0A/kBB0ffUBCoAPgZrf8UBq4APgFeg7/ACUBv7/cgbJACUBAEAv4AUh+ff7EBTYAUgGIgZTAAUBb7/8g7hAAUBgEAkEDL0+7kA80BkUAgUDBUBZUH4UB80D/kB5UP50BNEDfUBbUH6EBn0AwkDZ0B/YAmgETf2kfYYAmgPIA=" + } + }, + { + "minTime": "1587691807139", + "maxTime": "1587693592139", + "raw": { + "data": "AHXGhvOctVxBHcnIAAAAAJh16k0NNlzL66iPJySI+5Ge3oXtBFI9xCMJ3JB7IXhHIoTCAENx3+Df8HUiNgBDoTj3YjrdR5LmXzFF4TBUSByM/NQl6M6Qpic+QfCFiR4iE/cS/uoJDsP7dCuvQYo2YAUhBv9ifyAFIVUaDF793JygAAAAByv0r/kAAAAAAADqgSQCagAAAAAACACoAqwAAAAAAAgAxAAAAAAAEACwHy0AAAAAAC/9oAIWAAAAAABAAsAOTAAAAAAAQAPIAAAAAACAD4AMWAAAAAABf8UAD3gAAAAAAgA+APnIAAAAAAIABlgAAAAAAgAKcAAAAAACAB/gAAAAAAIABcAAAAAAAgAKqAAAAAAEAFQAfQAAAAAAC/7IACBAAAAAABABUADOAAAAAAAQAC6AAAAAABAAWIAAAAAAEAPoIAAAAAAQACUAAAAAABAAbaAAAAAAEAAJgAAAAAAgA6AAWIAAAAAAX/JAA4GAAAAAAIAOgADNAAAAAACAAQUAAAAAAQAhAAduAAAAAAL/ggAH6AAAAAAEAIQAfmAAAAAABAAF6AAAAAAEABfoAAAAAAQAB5AAAAAABAAKUAAAAAAEADi4AAAAAAQAD1AAAAAABAAEwAAAAAAEABpIAAAAAAQAD2AAAAAABAP7lAAAAAAEAAV0AAAAAAQADRAAAAAABAADAAAAAAAEAAUcAAAAAAQAHMwAAAAACAEIAA9AAAAAABf8EAA2UAAAAAAgBCAAJyAAAAAAIAHigAAAAAAgAB5AAAAAACAAXYAAAAAAIAAegAAAAAAgACDgAAAAACAA5kAAAAAAIABYIAAAAAAgACCAAAAAACAAGQAAAAAAIAPtgAAAAABADEAAWQAAAAAAv9CAAauAAAAAAQAxAAHsAAAAAAEAB/0AAAAAAQAB0gAAAAABAAPcAAAAAAEAAaQAAAAAAQAA3QAAAAABAA73AAAAAAEAAL4AAAAAAQAD0gAAAAAA" + } + }, + { + "minTime": "1587686407139", + "maxTime": "1587688192139", + "raw": { + "data": "AHjG79+XtVxBGQjEAAAAAJh17EdrqRPuZfCUUOAD5lV/xR94AP5F+HdSeS6DZupEa5l/9ROULtNZRYXE36ag8iHroOYjpKBjIL6h9qBBIPUnj6BFIIghgKCDo5cgkKGHoLu4HfkKBLkGxIENQ4ygbNARqDgEBooEWR8lACkCk3+xBi8AKQJUgNOAF4dUv9KBCoAXg8VArqAr0/MoEvQGIgqRDpKArkD7oPsQIcj8ZApMAIQcvf8EDuQAhDgSBV0GOoD7QJW3If4CgGHQG7oBe0D4qAaRAZygDuQCQIPE4ATgFAv9qA4WAE4A60AzkAHQONX/JAJ5AB0BjSAL5D2AgDYQCGIDaYAHgH6v/KByaAB4BG0BksAHwCWX/FAF1AB8H0aAKdAKYgMZQCQIHqoARgDUv96AvOAEYAXUAWMAIR9H3/BAKLACEBsyAIBAKIgcCQDtoDxUAyA=" + } + }, + { + "minTime": "1587688207139", + "maxTime": "1587689992139", + "raw": { + "data": "AHjGzLuZtVxBGp6wAAAAAJh15F/rQlEbpDTcy+Ao4sAHzB7/iiPQAfDjcTfXqBJIfMglyO1oHDACMF5v96H9wAjAp07nQTBDRUFFQJxHFUHeQxxAlW8791QDM6k610E11Jg8AJ8yuZv9qFGAE+pPvdCsNSruRnhKFXRqiDfQtKcIQ76NKQnKCkcTPw3YjldSdvAB3Qrfb/kjfgA6Q5zH9upFHADEzX+h0K3uAGJGHIzxlCPI+xCUoLlPEIfhGFocZwO/Y0CPIDJQasgcqACodAv+yA/IAKgVJB/CBM0eQoFZQbMgRaADYcDv+aAsIANgURBmyBxU+nIDZQKcg4uADoEPv+SHJYAOgNVBeqA5IAMgWS/6I8cgAyB+kGlQADAmN//Q5DAAMC1oMCQIYgJZtQ/4t1JvboTn03XYj1cyeG6FWTAAMXt//SawADyL8K6k9dIt0JwqWAA=" + } + }, + { + "minTime": "1587690007139", + "maxTime": "1587691792139", + "raw": { + "data": "AHjGqZebtVxBHDKkAAAAAJh16k/10Kx1IeiucTfscAIQY+/4IEzACEP0QXNA1UcOQQxDe0EdgAGeR3/9BxYABhtCCAoHwjv6D0wAXDLL/qggMAF8Dv31Aa6BjEB7IMIQKwh35A76DB0BCoFLR5agYNBlKBH0BtodXQOQg9NA3qfGECbID8QZygRRD1KBSUHBIHUR++gd9B9qBDkOcoGZQcmgYlAXTef/I0BAUDPUB0EH7UByEDp0Bs0PEEB8EDwkBd0HZEBB0DR0A/kBB0ffUBCoAPgZrf8UBq4APgFeg7/ACUBv7/cgbJACUBAEAv4AUh+ff7EBTYAUgGIgZTAAUBb7/8g7hAAUBgEAkEDL0+7kA80BkUAgUDBUBZUH4UB80D/kB5UP50BNEDfUBbUH6EBn0AwkDZ0B/YAmgETf2kfYYAmgPIA=" + } + }, + { + "minTime": "1587691807139", + "maxTime": "1587693592139", + "raw": { + "data": "AHXGhvOctVxBHcnIAAAAAJh16k0NNlzL66iPJySI+5Ge3oXtBFI9xCMJ3JB7IXhHIoTCAENx3+Df8HUiNgBDoTj3YjrdR5LmXzFF4TBUSByM/NQl6M6Qpic+QfCFiR4iE/cS/uoJDsP7dCuvQYo2YAUhBv9ifyAFIVUaDF793JygAAAAByv0r/kAAAAAAADqgSQCagAAAAAACACoAqwAAAAAAAgAxAAAAAAAEACwHy0AAAAAAC/9oAIWAAAAAABAAsAOTAAAAAAAQAPIAAAAAACAD4AMWAAAAAABf8UAD3gAAAAAAgA+APnIAAAAAAIABlgAAAAAAgAKcAAAAAACAB/gAAAAAAIABcAAAAAAAgAKqAAAAAAEAFQAfQAAAAAAC/7IACBAAAAAABABUADOAAAAAAAQAC6AAAAAABAAWIAAAAAAEAPoIAAAAAAQACUAAAAAABAAbaAAAAAAEAAJgAAAAAAgA6AAWIAAAAAAX/JAA4GAAAAAAIAOgADNAAAAAACAAQUAAAAAAQAhAAduAAAAAAL/ggAH6AAAAAAEAIQAfmAAAAAABAAF6AAAAAAEABfoAAAAAAQAB5AAAAAABAAKUAAAAAAEADi4AAAAAAQAD1AAAAAABAAEwAAAAAAEABpIAAAAAAQAD2AAAAAABAP7lAAAAAAEAAV0AAAAAAQADRAAAAAABAADAAAAAAAEAAUcAAAAAAQAHMwAAAAACAEIAA9AAAAAABf8EAA2UAAAAAAgBCAAJyAAAAAAIAHigAAAAAAgAB5AAAAAACAAXYAAAAAAIAAegAAAAAAgACDgAAAAACAA5kAAAAAAIABYIAAAAAAgACCAAAAAACAAGQAAAAAAIAPtgAAAAABADEAAWQAAAAAAv9CAAauAAAAAAQAxAAHsAAAAAAEAB/0AAAAAAQAB0gAAAAABAAPcAAAAAAEAAaQAAAAAAQAA3QAAAAABAA73AAAAAAEAAL4AAAAAAQAD0gAAAAAA" + } + }, + { + "minTime": "1587679207139", + "maxTime": "1587680992139", + "raw": { + "data": "AHjG+/CQtVxBEeOIAAAAAJh16jw3Qrd0qbmVwqUJ1Jnrch/6qASJAaagF8QOIoBHUBtKDt5ALqgMsQCHIHP0A8CAxNAKwh7eQG8oB8ED96AdlAY4gEVQeboBBUBmSAUhA18gPWQCRI/FUApCAwFA1OgHUQHzoBV0HsSAYtAZkgF3QOPIB0UB66ASdD1YgNyQCWoHF0AgMAHwBeX/FAXTAB8HiiARCAGIDJL/QgEAgBiAO1A44gLOQCaJ/tUApSAyVAJmgbVQGXoBfoAUg8Uv9iARqAFIDN0Aw6Bu5AGygNxQCcIfHIAPgFdv+KA1mAD4BR0DeiA6ZAPMg+9QCDIDJEAmCB3FAKAgMfQCao/sEAmqAwxAJ+gclQDioDK0AvqDypAI8gKXQBKIHWkBUSANZAK+h8ygBCApC/4IA8IAQgFCQOmoBN4AOgLFv+SD20A=" + } + }, + { + "minTime": "1587681007139", + "maxTime": "1587682792139", + "raw": { + "data": "AHjG2MyStVxBE+SMAAAAAJh16FaPACE9V/wcyuHgBCNtNuhQRINqP/FUAUFAO/gBKALHf7kB3uAEoAaKAWSgBkQADA6tv/6AIDAAMA8tAFAQHKkAUxANLQBHUHy9AETQDZUAV9AdWgA+AIbf8UA+uAD4AiiB7egBmQAZAECv+iAYnABkASRAcGQBNEAxtAEzQ/b0ARZANDQG50AQtAMtQBJkAO5A6/QDBkAUZADBQGgUAydAF7QffYAUgDW3+xANigBSAP0gPuIA66AfigCgIHcqAZTACEARe/4IDqkAIQBXUANhALeR/ekAWNAM3QAzEARZAcDQBIkA0lAHCQPH0AfRAPQQBaUBzJACtQBA0A79AEBgBSD7Ff7EAVeAFIBvyALQgO+IAvqAHMgHVoAryB98gDmoB+iAI2gOlwAhAETv+CAYRACEAVFD84QBSoAVgGKX+tAFFgBWA+kgDvIBiCAPageUIAiaAeCgC5IDbSAGAA==" + } + }, + { + "minTime": "1587682807139", + "maxTime": "1587684592139", + "raw": { + "data": "AHjGtaiUtVxBFbqwAAAAAJh16kxVxN+SoPygSCGPoI0juKD+oZGg6afBIECg3cAHQOm/5IZfAB0FBR81B30BbQwdBAG5D+30BiKAKSAKYBxL/igcEv8GATmAUIDNb/IgFCgByDxZAI2gCoQG0IGxEAjaAPZAaAgFzQ+XIBc0Bk6AeZA6SgDDgBCARi/4IDDYAQgFCQfuQAfAOBf8UB7MAHwCgoA4EDqSAQFAeogEER+VoB2EB6KAdJA/CgHkQGIoBQUHkqAQpAZCgElQOfICyEAWKAclD66gEeQBroDfUA3KBzZAJKgDRQFfIPXUAj6AMOAEoDE7/cgbbgBKAUpAYCgELT+WIBA0BqsAHwCSX/FAGrAB8DnCAbWAE4Akr/agO2gBOASdAFdACEHpV/wQCfQAhAfIgHwQPcoBBkAbKAzpAKwh/sQD9IDzYAXgHcv9KB7aAF4AmUAjaA3xAJag7VA=" + } + }, + { + "minTime": "1587684607139", + "maxTime": "1587686392139", + "raw": { + "data": "AHjGkoSWtVxBF2kcAAAAAJh16k0VM5zL7qjwJsSJyhSOBn7bqRmuhGa7EaLqTa3MXrqT9XQjPdh7LqJLkZ6KhukbIhA06wg10Kij/EIE4k/10KqlHQmXcy+/ogCGMmjo3bkZ5egu0KyiyE5EgtkK0jA0MA2Jf/SoAQNAGKoAZNAO6IAThAGHoAQFAB/ID3xACtoA19ADXoB1BAC9IAz1AC1IHwxACGIAwxAC1oB2FABTIAXZAHgoAKBACEoD0JADjoA2xABgIAQJAOuIAcFABcoAuqAGIPx6/0IASyAGIAwFACVQAhABDX/BAOBQAhADvoA2FACMoD7RACJoAzqAFIAce/2IB+OAFIAR9AGOwAhACK3/BA+HwAhADYoAwKAFIASS/2IAM2AFIBytAC/wAlAHe3+5ABlQAlACjoDzeAGIAde/0IA3+AGIAM5AC9IAHJAOIoAXhAHuwAxACM3+hD+CwAxACVg=" + } + }, + { + "minTime": "1587679207139", + "maxTime": "1587680992139", + "raw": { + "data": "AHjG+/CQtVxBEeOIAAAAAJh16jw3Qrd0qbmVwqUJ1Jnrch/6qASJAaagF8QOIoBHUBtKDt5ALqgMsQCHIHP0A8CAxNAKwh7eQG8oB8ED96AdlAY4gEVQeboBBUBmSAUhA18gPWQCRI/FUApCAwFA1OgHUQHzoBV0HsSAYtAZkgF3QOPIB0UB66ASdD1YgNyQCWoHF0AgMAHwBeX/FAXTAB8HiiARCAGIDJL/QgEAgBiAO1A44gLOQCaJ/tUApSAyVAJmgbVQGXoBfoAUg8Uv9iARqAFIDN0Aw6Bu5AGygNxQCcIfHIAPgFdv+KA1mAD4BR0DeiA6ZAPMg+9QCDIDJEAmCB3FAKAgMfQCao/sEAmqAwxAJ+gclQDioDK0AvqDypAI8gKXQBKIHWkBUSANZAK+h8ygBCApC/4IA8IAQgFCQOmoBN4AOgLFv+SD20A=" + } + }, + { + "minTime": "1587681007139", + "maxTime": "1587682792139", + "raw": { + "data": "AHjG2MyStVxBE+SMAAAAAJh16FaPACE9V/wcyuHgBCNtNuhQRINqP/FUAUFAO/gBKALHf7kB3uAEoAaKAWSgBkQADA6tv/6AIDAAMA8tAFAQHKkAUxANLQBHUHy9AETQDZUAV9AdWgA+AIbf8UA+uAD4AiiB7egBmQAZAECv+iAYnABkASRAcGQBNEAxtAEzQ/b0ARZANDQG50AQtAMtQBJkAO5A6/QDBkAUZADBQGgUAydAF7QffYAUgDW3+xANigBSAP0gPuIA66AfigCgIHcqAZTACEARe/4IDqkAIQBXUANhALeR/ekAWNAM3QAzEARZAcDQBIkA0lAHCQPH0AfRAPQQBaUBzJACtQBA0A79AEBgBSD7Ff7EAVeAFIBvyALQgO+IAvqAHMgHVoAryB98gDmoB+iAI2gOlwAhAETv+CAYRACEAVFD84QBSoAVgGKX+tAFFgBWA+kgDvIBiCAPageUIAiaAeCgC5IDbSAGAA==" + } + }, + { + "minTime": "1587682807139", + "maxTime": "1587684592139", + "raw": { + "data": "AHjGtaiUtVxBFbqwAAAAAJh16kxVxN+SoPygSCGPoI0juKD+oZGg6afBIECg3cAHQOm/5IZfAB0FBR81B30BbQwdBAG5D+30BiKAKSAKYBxL/igcEv8GATmAUIDNb/IgFCgByDxZAI2gCoQG0IGxEAjaAPZAaAgFzQ+XIBc0Bk6AeZA6SgDDgBCARi/4IDDYAQgFCQfuQAfAOBf8UB7MAHwCgoA4EDqSAQFAeogEER+VoB2EB6KAdJA/CgHkQGIoBQUHkqAQpAZCgElQOfICyEAWKAclD66gEeQBroDfUA3KBzZAJKgDRQFfIPXUAj6AMOAEoDE7/cgbbgBKAUpAYCgELT+WIBA0BqsAHwCSX/FAGrAB8DnCAbWAE4Akr/agO2gBOASdAFdACEHpV/wQCfQAhAfIgHwQPcoBBkAbKAzpAKwh/sQD9IDzYAXgHcv9KB7aAF4AmUAjaA3xAJag7VA=" + } + }, + { + "minTime": "1587684607139", + "maxTime": "1587686392139", + "raw": { + "data": "AHjGkoSWtVxBF2kcAAAAAJh16k0VM5zL7qjwJsSJyhSOBn7bqRmuhGa7EaLqTa3MXrqT9XQjPdh7LqJLkZ6KhukbIhA06wg10Kij/EIE4k/10KqlHQmXcy+/ogCGMmjo3bkZ5egu0KyiyE5EgtkK0jA0MA2Jf/SoAQNAGKoAZNAO6IAThAGHoAQFAB/ID3xACtoA19ADXoB1BAC9IAz1AC1IHwxACGIAwxAC1oB2FABTIAXZAHgoAKBACEoD0JADjoA2xABgIAQJAOuIAcFABcoAuqAGIPx6/0IASyAGIAwFACVQAhABDX/BAOBQAhADvoA2FACMoD7RACJoAzqAFIAce/2IB+OAFIAR9AGOwAhACK3/BA+HwAhADYoAwKAFIASS/2IAM2AFIBytAC/wAlAHe3+5ABlQAlACjoDzeAGIAde/0IA3+AGIAM5AC9IAHJAOIoAXhAHuwAxACM3+hD+CwAxACVg=" + } + }, + { + "minTime": "1587686407139", + "maxTime": "1587688192139", + "raw": { + "data": "AHjG79+XtVxBGQjEAAAAAJh17EdrqRPuZfCUUOAD5lV/xR94AP5F+HdSeS6DZupEa5l/9ROULtNZRYXE36ag8iHroOYjpKBjIL6h9qBBIPUnj6BFIIghgKCDo5cgkKGHoLu4HfkKBLkGxIENQ4ygbNARqDgEBooEWR8lACkCk3+xBi8AKQJUgNOAF4dUv9KBCoAXg8VArqAr0/MoEvQGIgqRDpKArkD7oPsQIcj8ZApMAIQcvf8EDuQAhDgSBV0GOoD7QJW3If4CgGHQG7oBe0D4qAaRAZygDuQCQIPE4ATgFAv9qA4WAE4A60AzkAHQONX/JAJ5AB0BjSAL5D2AgDYQCGIDaYAHgH6v/KByaAB4BG0BksAHwCWX/FAF1AB8H0aAKdAKYgMZQCQIHqoARgDUv96AvOAEYAXUAWMAIR9H3/BAKLACEBsyAIBAKIgcCQDtoDxUAyA=" + } + }, + { + "minTime": "1587688207139", + "maxTime": "1587689992139", + "raw": { + "data": "AHjGzLuZtVxBGp6wAAAAAJh15F/rQlEbpDTcy+Ao4sAHzB7/iiPQAfDjcTfXqBJIfMglyO1oHDACMF5v96H9wAjAp07nQTBDRUFFQJxHFUHeQxxAlW8791QDM6k610E11Jg8AJ8yuZv9qFGAE+pPvdCsNSruRnhKFXRqiDfQtKcIQ76NKQnKCkcTPw3YjldSdvAB3Qrfb/kjfgA6Q5zH9upFHADEzX+h0K3uAGJGHIzxlCPI+xCUoLlPEIfhGFocZwO/Y0CPIDJQasgcqACodAv+yA/IAKgVJB/CBM0eQoFZQbMgRaADYcDv+aAsIANgURBmyBxU+nIDZQKcg4uADoEPv+SHJYAOgNVBeqA5IAMgWS/6I8cgAyB+kGlQADAmN//Q5DAAMC1oMCQIYgJZtQ/4t1JvboTn03XYj1cyeG6FWTAAMXt//SawADyL8K6k9dIt0JwqWAA=" + } + }, + { + "minTime": "1587690007139", + "maxTime": "1587691792139", + "raw": { + "data": "AHjGqZebtVxBHDKkAAAAAJh16k/10Kx1IeiucTfscAIQY+/4IEzACEP0QXNA1UcOQQxDe0EdgAGeR3/9BxYABhtCCAoHwjv6D0wAXDLL/qggMAF8Dv31Aa6BjEB7IMIQKwh35A76DB0BCoFLR5agYNBlKBH0BtodXQOQg9NA3qfGECbID8QZygRRD1KBSUHBIHUR++gd9B9qBDkOcoGZQcmgYlAXTef/I0BAUDPUB0EH7UByEDp0Bs0PEEB8EDwkBd0HZEBB0DR0A/kBB0ffUBCoAPgZrf8UBq4APgFeg7/ACUBv7/cgbJACUBAEAv4AUh+ff7EBTYAUgGIgZTAAUBb7/8g7hAAUBgEAkEDL0+7kA80BkUAgUDBUBZUH4UB80D/kB5UP50BNEDfUBbUH6EBn0AwkDZ0B/YAmgETf2kfYYAmgPIA=" + } + }, + { + "minTime": "1587691807139", + "maxTime": "1587693592139", + "raw": { + "data": "AHXGhvOctVxBHcnIAAAAAJh16k0NNlzL66iPJySI+5Ge3oXtBFI9xCMJ3JB7IXhHIoTCAENx3+Df8HUiNgBDoTj3YjrdR5LmXzFF4TBUSByM/NQl6M6Qpic+QfCFiR4iE/cS/uoJDsP7dCuvQYo2YAUhBv9ifyAFIVUaDF793JygAAAAByv0r/kAAAAAAADqgSQCagAAAAAACACoAqwAAAAAAAgAxAAAAAAAEACwHy0AAAAAAC/9oAIWAAAAAABAAsAOTAAAAAAAQAPIAAAAAACAD4AMWAAAAAABf8UAD3gAAAAAAgA+APnIAAAAAAIABlgAAAAAAgAKcAAAAAACAB/gAAAAAAIABcAAAAAAAgAKqAAAAAAEAFQAfQAAAAAAC/7IACBAAAAAABABUADOAAAAAAAQAC6AAAAAABAAWIAAAAAAEAPoIAAAAAAQACUAAAAAABAAbaAAAAAAEAAJgAAAAAAgA6AAWIAAAAAAX/JAA4GAAAAAAIAOgADNAAAAAACAAQUAAAAAAQAhAAduAAAAAAL/ggAH6AAAAAAEAIQAfmAAAAAABAAF6AAAAAAEABfoAAAAAAQAB5AAAAAABAAKUAAAAAAEADi4AAAAAAQAD1AAAAAABAAEwAAAAAAEABpIAAAAAAQAD2AAAAAABAP7lAAAAAAEAAV0AAAAAAQADRAAAAAABAADAAAAAAAEAAUcAAAAAAQAHMwAAAAACAEIAA9AAAAAABf8EAA2UAAAAAAgBCAAJyAAAAAAIAHigAAAAAAgAB5AAAAAACAAXYAAAAAAIAAegAAAAAAgACDgAAAAACAA5kAAAAAAIABYIAAAAAAgACCAAAAAACAAGQAAAAAAIAPtgAAAAABADEAAWQAAAAAAv9CAAauAAAAAAQAxAAHsAAAAAAEAB/0AAAAAAQAB0gAAAAABAAPcAAAAAAEAAaQAAAAAAQAA3QAAAAABAA73AAAAAAEAAL4AAAAAAQAD0gAAAAAA" + } + } + ] + } +} +{ + "series": { + "labels": [ + { + "name": "__name__", + "value": "gitlab_transaction_cache_read_hit_count_total" + }, + { + "name": "action", + "value": "widget.json" + }, + { + "name": "controller", + "value": "Projects::MergeRequests::ContentController" + }, + { + "name": "env", + "value": "gprd" + }, + { + "name": "environment", + "value": "gprd" + }, + { + "name": "fqdn", + "value": "web-08-sv-gprd.c.gitlab-production.internal" + }, + { + "name": "instance", + "value": "web-08-sv-gprd.c.gitlab-production.internal:8083" + }, + { + "name": "job", + "value": "gitlab-rails" + }, + { + "name": "monitor", + "value": "app" + }, + { + "name": "provider", + "value": "gcp" + }, + { + "name": "region", + "value": "us-east" + }, + { + "name": "replica", + "value": "02" + }, + { + "name": "shard", + "value": "default" + }, + { + "name": "stage", + "value": "main" + }, + { + "name": "tier", + "value": "sv" + }, + { + "name": "type", + "value": "web" + } + ], + "chunks": [ + { + "minTime": "1587679205791", + "maxTime": "1587680990791", + "raw": { + "data": "AHi+5vCQtVxBEeNUAAAAAJh16g3QnqpwuZfCUqVFobj//mgHw6Ffqkjcy+LwAdELv+SbRAB3IzslCnoxtC+J3NDto/1DqOJn1boVWKSJzK411JhroT9UmnIn8ofuhH26k7NzJ38AGdCtlv+ic2ADOBn4LqRbuhWXuZe70XVMJRaoAk5F+7v7iGRAEkb5CWTiHUnhuhOdT6cS/twAj0Kq+/3pCoAR5k99EJDhN5FZyM8fRZiE0QUad0RYUAMwll/nbzP74AZ6ke7oRgupF65i7dB8LqRLuRXgwARC1f+HQnCwARPdzL6iiVpvqJK4l/9dSOGAD+hWe3/FIfAB/MvVqasiEuRX8upEG6FaukMcy+nor6ZuisuB3+GgV5Bg6BR0OUwAhAm9/wQe/ACECPI9xQJMgr5AUSHa0C6oNJQJIny5AoKDMoANgUK/5oc+gA2BD0FHI8rA" + } + }, + { + "minTime": "1587681005874", + "maxTime": "1587682790791", + "raw": { + "data": "AHjkxMyStVxBE+S8AAAAAMV06FYXAKcobmXwGAFotN/qTPoAWhtIkDah/2bqTLXQrs0uDmV2cAG9iMm/5uhV2wAbH25GdyoVVHloTdO8IXSAGY1q/zoTGAGeJv3tBMUMuQWJHeUENQ/lBbIATnmt/tQNyAE4IWhmKCeo7Egv6GTIKq4GfnupMldCt/cy9noj6ZahuIkzkX0uAGY29/ndSZfADMz3MvcqbwirOJv2tBzUM3QdqAEo+Tf7kGzgBKHToJQnoaCGIWcjrCCowAZA2L/oheEAGbz/62gLCgZygGggL6g4+gLegaYgPah4agI6gZjACsBaL/WgGhACsHZUBAUDg4ANgIvf80fXYANgL8gbWgKUg5ygI4gHygdrACEBe7/gh7LACEBNUD4EBAEHakBa0DdEBcIAIn5Xf+EBE4AIgZKgJIg9WgK8gZggIah7OgIbADcDbb/KgMrADcG/EA3w" + } + }, + { + "minTime": "1587682805791", + "maxTime": "1587684590791", + "raw": { + "data": "AHi+oKiUtVxBFbqAAAAAAJh16kQ7iZ/a6k0tOp0Jw7qTDXMvq8AGx/b/mmdwAbHHci/juxEG6j5XYjJdCc26k31zJ/6PqD7oVhqR9uP/wboVbqKyAPJs7+i5l8ZgFCL9f2MxOAD4r9/+8jPE4AVg8kK6jLkLWnPUJOjQULk4m/B0FWQwpBy0dUQMpBDEN6QeVPHUHFQ7pAw0EzR3xBIUOqQXRwM/ZdSaO6E6tLdzJ5aIboThU2XIzxFCfIyFC4pwJFZIJxDiuJf1XUmIp/uhPNSkdiMVzL3Sh5JcbkZ4uhH0GGjeU1+hEEYMhVW8/+QoCvIGNIBjoCkoOzoDDoBJIHKoC7IBzoemID1IGFICEQAjB0i/3oCEQAjAPFAwOAF4DK3+lHz+AF4COoGhwAbAVO/5oOwQAbAKZAQmAEoGx3+5AQWAEoeXgA==" + } + }, + { + "minTime": "1587684605791", + "maxTime": "1587686390791", + "raw": { + "data": "AHi+/YOWtVxBF2gkAAAAAJh17EerqRTuZfH0e1NrQzUWtwN/IoHkgxyA4upNxgA3mL2/5upHbABvQjfdiMeADuok3/JyM+hgA6FJRtUAGwit/zQX8AGzrSE0gAyPUv+iExgAziP/dSajACnQrF7/YmagBSI1zL4DABsTS/5po8AGxtEMeADeRntd/zQqMAGxcSc3gAyCOv+iFLgAyMIQ38AF7DP/7/q6kR8AF9CcC6k+GADeZfQ7/mhzQAbL6Q5IAdiC3+NyM9tgB2FFR3MAGwpV/zTu0AGwqSDugBCLSv+Dib9ngBCC2IYRACUEkv9yORQAlA6kFMgBGHj3+9ApoARgnye4wAhByL/ggSUAIQytBH4AZj2l/nQTSAGYFyhgkALQQ2/1OB32jAC0GXoDbgAiBq7/whwyACIExQbPADMBq3+dHQ8AMwIOg++AKIHtv7CHDYAogfFB+EAFwPhf9U/2QAXApyDMoARgOu/3oEmgBGHdEDtQAFBqN/+QH3AAUC9I/BgA6BX7/kgzKADoDfQK/ACMA33+9DnUAIwNWgzCAGYFyv87ef/D4AZgIMA=" + } + }, + { + "minTime": "1587686405791", + "maxTime": "1587688190791", + "raw": { + "data": "AHi+2t+XtVxBGQhgAAAAAKB17EZd/4dSLeACOZPbdSaDABvQr97/mkogA3kV5rqTyYAQ6E+2/4OpPlgBDmR+upMtSvdCNN1IiXEf+6kyN0K8lOQ5l9/QxoANi4X/NPggA2FUjqwAZDmv+jkZ97ABkOMjFUI4nPkJij6UNY4G/iUCDQdlAl3MvlKLKhMJyMAGw9b/miZQAbyL+ihSwAHGSv/rqTHYADmI5l9DgA6Prf8k12ADoniF5ABnEv8d/0QNoAM6kVboVYMAA8x+9//dx8cAA9RYuhXxwAnIrf7XIz7mAE4SVG1QAzCoX+dOLQAzBtIveADIMu/6IXeADNx/+HQD5dCthSFuZfo0aSAFJlV/sQ4oAUifuRnpsAGw+F/zRtcAGwY6GtgAuc1v+qFzgAuNnQX0AF8Tfb9/1QMeAC4Jah0cAGQTu/6I4vABkF4Q2iADILNf9EDXgAyfdIF+gr6GVoPyjtUAIQMK/4IWdACEBdQLFwN+zoEo6FYqiggA2dW/5uZP7gA3qT23Qr0UwgA=" + } + }, + { + "minTime": "1587688205791", + "maxTime": "1587689990791", + "raw": { + "data": "AHi+t7uZtVxBGp6wAAAAAJh15Ffm6kSboTo0wHMv+qKFABk3S/6IgMAGQ/HE37mgp0AFQ9y/7IInABUdBQN+ADoKZf8kPPgA6BaIIcncaGiILagQqOfIPmhnCBfIIpABG83+jf+HUjzgAjoVtqQRG85kd7qR2uhGy6kyuAFeRniN/rQmsAKwaSNfQkif1Qj6NqQfcADwtd/5cTP2YAH7EcrqTpXQrb4AMjMv+iR2ADOZPldSLGADJ1v+joVrsAGTxuRf8UIlHodSb+nu5jeupEa6FYikzcDv2WAIYEBv76A1YAhg1NA/SHfUB0oGxQZOgWmAGY9qv86BeoAZgwhAsaHd0BsIFYQZsgaKADoD2v+SfaIAOgSBBwiBFIAJhxq/7oDEgAmBOkGVIFMR+ugQhBsCBMUOJoEzQY6gQdAdDah/xbqTe3Qr6YAMltv+iIuADOY/FFHQnVwArOG/1uRnisAKwkSCCgBmMev86FLA" + } + }, + { + "minTime": "1587690005791", + "maxTime": "1587691790791", + "raw": { + "data": "AHi+lJebtVxBHDJAAAAAAJh16k9eABuhWj3/pJ1AA0c7iZ9WgPkF46Fe+lKRsuZHW6ky90JzaRzkV/LqTRYAW6D5b/U7DcwAt1JnrmR1wAD1I77/+6E4GAAZBOBn6rsRUupHynt0JxqXbmV1qNxDEmqRKuRnjqGKQciMeQqKfMQmSMmQq7ib8VQSpAvkMBQXJHnEFXQ5tBz0/ZQfBD4EHkR+VBp0NUQUdAtm8/+BoCfoHsoCtoPToDtoHyQATAe2/7oeeQATAQ1A1OAGoCbX+ZBz2AGoC1IBXwAbAxa/5oCRwAbH01AQGADoH53/JAXKADoBJoOhwApAY6/2IGqwApAOdAVSADIfq3/RAVWADIB3oGGQAZAV6/6IOKQAZAaZAO+ADYGGX/NASaADZ+KIDJwAhAIO/4IGCwAhAXdB+qAGYCAX+dAxSAGYDyof5wADAWy//oGUwADARhB6JAbhAIxA9ZAR2ADIBXX/RH1mADID8A==" + } + }, + { + "minTime": "1587691805791", + "maxTime": "1587693590791", + "raw": { + "data": "AHW+8fKctVxBHcmQAAAAAJh16k1VOpzK7V1JiroVxKThyK9d1Jr6XroV9aTxES5l8XRkE2NEHgBnch/gN/nQCOQAzAZUgCegBmAWq/zoHCoAZgFEQGIwADAOhf/0HisAAwCDIDbIAOgExv+SBwiADoAtkAmcAHQH33/JAKvAB0Ph6AS2ACoA0b/sgOWgAqADFAGkgBKQD+IAVUAF6AMti9+7k6AAAAAA5X5F/RYAAAAAAB1QOIAhgAAAAAAAgAyAAAAAAACA+igAAAAAAIALIAAAAAAAgBzMAAAAAACAB1AAAAAAAIAMZAAAAAABABkADnAAAAAAAv+iAPmYAAAAAAQAZAAOIAAAAAAEABcAAAAAAAgA6AB8gAAAAAAX/JAALAAAAAAAIAOgAL0AAAAAACAD/AAAAAAAQAfAARcAAAAAAL/igAZaAAAAAAEAHwACrAAAAAABAAWIAAAAAAEAPsYAAAAAAQACugAAAAABAAYwAAAAAAEAAO4AAAAAAQABfAAAAAABAAI8AAAAAAEADpgAAAAAAQACWAAAAAABAAdcAAAAAAIATgAFFAAAAAAF/tQAecAAAAAACAE4AAuAAAAAAAgAE/AAAAAACAAx0AAAAAAIABYgAAAAAAgAcbAAAAAACAAY8AAAAAAIAA/AAAAAABAD0ABogAAAAAAv8SAAfQAAAAAAQA9AP7VAAAAAAEAASIAAAAAAQAAwwAAAAABAANNAAAAAAEAAeEAAAAAAQAH/wAAAAABAAHrAAAAAAEAA2sAAAAAAQAA1QAAAAABAA70AAAAAAEAAOIAAAAAAgAyAAJ4AAAAAAX/RAAMDAAAAAAIAMgACfgAAAAACAA5GAAAAAAIABYIAAAAABABsAAOUAAAAAAv+aAAKSAAAAAAQAbAB8MAAAAAAEAATcAAAAAAQAD+QAAAAABAAEKAAAAAAEABxUAAAAAAQABUAAAAAABAANEAAAAAAIAZgACmgAAAAAF/nQAA3QAAAAACAGYAHggAAAAAAgACqAAAAAACAAeWAAAAAAA==" + } + }, + { + "minTime": "1587686405791", + "maxTime": "1587688190791", + "raw": { + "data": "AHi+2t+XtVxBGQhgAAAAAKB17EZd/4dSLeACOZPbdSaDABvQr97/mkogA3kV5rqTyYAQ6E+2/4OpPlgBDmR+upMtSvdCNN1IiXEf+6kyN0K8lOQ5l9/QxoANi4X/NPggA2FUjqwAZDmv+jkZ97ABkOMjFUI4nPkJij6UNY4G/iUCDQdlAl3MvlKLKhMJyMAGw9b/miZQAbyL+ihSwAHGSv/rqTHYADmI5l9DgA6Prf8k12ADoniF5ABnEv8d/0QNoAM6kVboVYMAA8x+9//dx8cAA9RYuhXxwAnIrf7XIz7mAE4SVG1QAzCoX+dOLQAzBtIveADIMu/6IXeADNx/+HQD5dCthSFuZfo0aSAFJlV/sQ4oAUifuRnpsAGw+F/zRtcAGwY6GtgAuc1v+qFzgAuNnQX0AF8Tfb9/1QMeAC4Jah0cAGQTu/6I4vABkF4Q2iADILNf9EDXgAyfdIF+gr6GVoPyjtUAIQMK/4IWdACEBdQLFwN+zoEo6FYqiggA2dW/5uZP7gA3qT23Qr0UwgA=" + } + }, + { + "minTime": "1587688205791", + "maxTime": "1587689990791", + "raw": { + "data": "AHi+t7uZtVxBGp6wAAAAAJh15Ffm6kSboTo0wHMv+qKFABk3S/6IgMAGQ/HE37mgp0AFQ9y/7IInABUdBQN+ADoKZf8kPPgA6BaIIcncaGiILagQqOfIPmhnCBfIIpABG83+jf+HUjzgAjoVtqQRG85kd7qR2uhGy6kyuAFeRniN/rQmsAKwaSNfQkif1Qj6NqQfcADwtd/5cTP2YAH7EcrqTpXQrb4AMjMv+iR2ADOZPldSLGADJ1v+joVrsAGTxuRf8UIlHodSb+nu5jeupEa6FYikzcDv2WAIYEBv76A1YAhg1NA/SHfUB0oGxQZOgWmAGY9qv86BeoAZgwhAsaHd0BsIFYQZsgaKADoD2v+SfaIAOgSBBwiBFIAJhxq/7oDEgAmBOkGVIFMR+ugQhBsCBMUOJoEzQY6gQdAdDah/xbqTe3Qr6YAMltv+iIuADOY/FFHQnVwArOG/1uRnisAKwkSCCgBmMev86FLA" + } + }, + { + "minTime": "1587690005791", + "maxTime": "1587691790791", + "raw": { + "data": "AHi+lJebtVxBHDJAAAAAAJh16k9eABuhWj3/pJ1AA0c7iZ9WgPkF46Fe+lKRsuZHW6ky90JzaRzkV/LqTRYAW6D5b/U7DcwAt1JnrmR1wAD1I77/+6E4GAAZBOBn6rsRUupHynt0JxqXbmV1qNxDEmqRKuRnjqGKQciMeQqKfMQmSMmQq7ib8VQSpAvkMBQXJHnEFXQ5tBz0/ZQfBD4EHkR+VBp0NUQUdAtm8/+BoCfoHsoCtoPToDtoHyQATAe2/7oeeQATAQ1A1OAGoCbX+ZBz2AGoC1IBXwAbAxa/5oCRwAbH01AQGADoH53/JAXKADoBJoOhwApAY6/2IGqwApAOdAVSADIfq3/RAVWADIB3oGGQAZAV6/6IOKQAZAaZAO+ADYGGX/NASaADZ+KIDJwAhAIO/4IGCwAhAXdB+qAGYCAX+dAxSAGYDyof5wADAWy//oGUwADARhB6JAbhAIxA9ZAR2ADIBXX/RH1mADID8A==" + } + }, + { + "minTime": "1587691805791", + "maxTime": "1587693590791", + "raw": { + "data": "AHW+8fKctVxBHcmQAAAAAJh16k1VOpzK7V1JiroVxKThyK9d1Jr6XroV9aTxES5l8XRkE2NEHgBnch/gN/nQCOQAzAZUgCegBmAWq/zoHCoAZgFEQGIwADAOhf/0HisAAwCDIDbIAOgExv+SBwiADoAtkAmcAHQH33/JAKvAB0Ph6AS2ACoA0b/sgOWgAqADFAGkgBKQD+IAVUAF6AMti9+7k6AAAAAA5X5F/RYAAAAAAB1QOIAhgAAAAAAAgAyAAAAAAACA+igAAAAAAIALIAAAAAAAgBzMAAAAAACAB1AAAAAAAIAMZAAAAAABABkADnAAAAAAAv+iAPmYAAAAAAQAZAAOIAAAAAAEABcAAAAAAAgA6AB8gAAAAAAX/JAALAAAAAAAIAOgAL0AAAAAACAD/AAAAAAAQAfAARcAAAAAAL/igAZaAAAAAAEAHwACrAAAAAABAAWIAAAAAAEAPsYAAAAAAQACugAAAAABAAYwAAAAAAEAAO4AAAAAAQABfAAAAAABAAI8AAAAAAEADpgAAAAAAQACWAAAAAABAAdcAAAAAAIATgAFFAAAAAAF/tQAecAAAAAACAE4AAuAAAAAAAgAE/AAAAAACAAx0AAAAAAIABYgAAAAAAgAcbAAAAAACAAY8AAAAAAIAA/AAAAAABAD0ABogAAAAAAv8SAAfQAAAAAAQA9AP7VAAAAAAEAASIAAAAAAQAAwwAAAAABAANNAAAAAAEAAeEAAAAAAQAH/wAAAAABAAHrAAAAAAEAA2sAAAAAAQAA1QAAAAABAA70AAAAAAEAAOIAAAAAAgAyAAJ4AAAAAAX/RAAMDAAAAAAIAMgACfgAAAAACAA5GAAAAAAIABYIAAAAABABsAAOUAAAAAAv+aAAKSAAAAAAQAbAB8MAAAAAAEAATcAAAAAAQAD+QAAAAABAAEKAAAAAAEABxUAAAAAAQABUAAAAAABAANEAAAAAAIAZgACmgAAAAAF/nQAA3QAAAAACAGYAHggAAAAAAgACqAAAAAACAAeWAAAAAAA==" + } + }, + { + "minTime": "1587679205791", + "maxTime": "1587680990791", + "raw": { + "data": "AHi+5vCQtVxBEeNUAAAAAJh16g3QnqpwuZfCUqVFobj//mgHw6Ffqkjcy+LwAdELv+SbRAB3IzslCnoxtC+J3NDto/1DqOJn1boVWKSJzK411JhroT9UmnIn8ofuhH26k7NzJ38AGdCtlv+ic2ADOBn4LqRbuhWXuZe70XVMJRaoAk5F+7v7iGRAEkb5CWTiHUnhuhOdT6cS/twAj0Kq+/3pCoAR5k99EJDhN5FZyM8fRZiE0QUad0RYUAMwll/nbzP74AZ6ke7oRgupF65i7dB8LqRLuRXgwARC1f+HQnCwARPdzL6iiVpvqJK4l/9dSOGAD+hWe3/FIfAB/MvVqasiEuRX8upEG6FaukMcy+nor6ZuisuB3+GgV5Bg6BR0OUwAhAm9/wQe/ACECPI9xQJMgr5AUSHa0C6oNJQJIny5AoKDMoANgUK/5oc+gA2BD0FHI8rA" + } + }, + { + "minTime": "1587681005874", + "maxTime": "1587682790791", + "raw": { + "data": "AHjkxMyStVxBE+S8AAAAAMV06FYXAKcobmXwGAFotN/qTPoAWhtIkDah/2bqTLXQrs0uDmV2cAG9iMm/5uhV2wAbH25GdyoVVHloTdO8IXSAGY1q/zoTGAGeJv3tBMUMuQWJHeUENQ/lBbIATnmt/tQNyAE4IWhmKCeo7Egv6GTIKq4GfnupMldCt/cy9noj6ZahuIkzkX0uAGY29/ndSZfADMz3MvcqbwirOJv2tBzUM3QdqAEo+Tf7kGzgBKHToJQnoaCGIWcjrCCowAZA2L/oheEAGbz/62gLCgZygGggL6g4+gLegaYgPah4agI6gZjACsBaL/WgGhACsHZUBAUDg4ANgIvf80fXYANgL8gbWgKUg5ygI4gHygdrACEBe7/gh7LACEBNUD4EBAEHakBa0DdEBcIAIn5Xf+EBE4AIgZKgJIg9WgK8gZggIah7OgIbADcDbb/KgMrADcG/EA3w" + } + }, + { + "minTime": "1587682805791", + "maxTime": "1587684590791", + "raw": { + "data": "AHi+oKiUtVxBFbqAAAAAAJh16kQ7iZ/a6k0tOp0Jw7qTDXMvq8AGx/b/mmdwAbHHci/juxEG6j5XYjJdCc26k31zJ/6PqD7oVhqR9uP/wboVbqKyAPJs7+i5l8ZgFCL9f2MxOAD4r9/+8jPE4AVg8kK6jLkLWnPUJOjQULk4m/B0FWQwpBy0dUQMpBDEN6QeVPHUHFQ7pAw0EzR3xBIUOqQXRwM/ZdSaO6E6tLdzJ5aIboThU2XIzxFCfIyFC4pwJFZIJxDiuJf1XUmIp/uhPNSkdiMVzL3Sh5JcbkZ4uhH0GGjeU1+hEEYMhVW8/+QoCvIGNIBjoCkoOzoDDoBJIHKoC7IBzoemID1IGFICEQAjB0i/3oCEQAjAPFAwOAF4DK3+lHz+AF4COoGhwAbAVO/5oOwQAbAKZAQmAEoGx3+5AQWAEoeXgA==" + } + }, + { + "minTime": "1587684605791", + "maxTime": "1587686390791", + "raw": { + "data": "AHi+/YOWtVxBF2gkAAAAAJh17EerqRTuZfH0e1NrQzUWtwN/IoHkgxyA4upNxgA3mL2/5upHbABvQjfdiMeADuok3/JyM+hgA6FJRtUAGwit/zQX8AGzrSE0gAyPUv+iExgAziP/dSajACnQrF7/YmagBSI1zL4DABsTS/5po8AGxtEMeADeRntd/zQqMAGxcSc3gAyCOv+iFLgAyMIQ38AF7DP/7/q6kR8AF9CcC6k+GADeZfQ7/mhzQAbL6Q5IAdiC3+NyM9tgB2FFR3MAGwpV/zTu0AGwqSDugBCLSv+Dib9ngBCC2IYRACUEkv9yORQAlA6kFMgBGHj3+9ApoARgnye4wAhByL/ggSUAIQytBH4AZj2l/nQTSAGYFyhgkALQQ2/1OB32jAC0GXoDbgAiBq7/whwyACIExQbPADMBq3+dHQ8AMwIOg++AKIHtv7CHDYAogfFB+EAFwPhf9U/2QAXApyDMoARgOu/3oEmgBGHdEDtQAFBqN/+QH3AAUC9I/BgA6BX7/kgzKADoDfQK/ACMA33+9DnUAIwNWgzCAGYFyv87ef/D4AZgIMA=" + } + }, + { + "minTime": "1587679205791", + "maxTime": "1587680990791", + "raw": { + "data": "AHi+5vCQtVxBEeNUAAAAAJh16g3QnqpwuZfCUqVFobj//mgHw6Ffqkjcy+LwAdELv+SbRAB3IzslCnoxtC+J3NDto/1DqOJn1boVWKSJzK411JhroT9UmnIn8ofuhH26k7NzJ38AGdCtlv+ic2ADOBn4LqRbuhWXuZe70XVMJRaoAk5F+7v7iGRAEkb5CWTiHUnhuhOdT6cS/twAj0Kq+/3pCoAR5k99EJDhN5FZyM8fRZiE0QUad0RYUAMwll/nbzP74AZ6ke7oRgupF65i7dB8LqRLuRXgwARC1f+HQnCwARPdzL6iiVpvqJK4l/9dSOGAD+hWe3/FIfAB/MvVqasiEuRX8upEG6FaukMcy+nor6ZuisuB3+GgV5Bg6BR0OUwAhAm9/wQe/ACECPI9xQJMgr5AUSHa0C6oNJQJIny5AoKDMoANgUK/5oc+gA2BD0FHI8rA" + } + }, + { + "minTime": "1587681005874", + "maxTime": "1587682790791", + "raw": { + "data": "AHjkxMyStVxBE+S8AAAAAMV06FYXAKcobmXwGAFotN/qTPoAWhtIkDah/2bqTLXQrs0uDmV2cAG9iMm/5uhV2wAbH25GdyoVVHloTdO8IXSAGY1q/zoTGAGeJv3tBMUMuQWJHeUENQ/lBbIATnmt/tQNyAE4IWhmKCeo7Egv6GTIKq4GfnupMldCt/cy9noj6ZahuIkzkX0uAGY29/ndSZfADMz3MvcqbwirOJv2tBzUM3QdqAEo+Tf7kGzgBKHToJQnoaCGIWcjrCCowAZA2L/oheEAGbz/62gLCgZygGggL6g4+gLegaYgPah4agI6gZjACsBaL/WgGhACsHZUBAUDg4ANgIvf80fXYANgL8gbWgKUg5ygI4gHygdrACEBe7/gh7LACEBNUD4EBAEHakBa0DdEBcIAIn5Xf+EBE4AIgZKgJIg9WgK8gZggIah7OgIbADcDbb/KgMrADcG/EA3w" + } + }, + { + "minTime": "1587682805791", + "maxTime": "1587684590791", + "raw": { + "data": "AHi+oKiUtVxBFbqAAAAAAJh16kQ7iZ/a6k0tOp0Jw7qTDXMvq8AGx/b/mmdwAbHHci/juxEG6j5XYjJdCc26k31zJ/6PqD7oVhqR9uP/wboVbqKyAPJs7+i5l8ZgFCL9f2MxOAD4r9/+8jPE4AVg8kK6jLkLWnPUJOjQULk4m/B0FWQwpBy0dUQMpBDEN6QeVPHUHFQ7pAw0EzR3xBIUOqQXRwM/ZdSaO6E6tLdzJ5aIboThU2XIzxFCfIyFC4pwJFZIJxDiuJf1XUmIp/uhPNSkdiMVzL3Sh5JcbkZ4uhH0GGjeU1+hEEYMhVW8/+QoCvIGNIBjoCkoOzoDDoBJIHKoC7IBzoemID1IGFICEQAjB0i/3oCEQAjAPFAwOAF4DK3+lHz+AF4COoGhwAbAVO/5oOwQAbAKZAQmAEoGx3+5AQWAEoeXgA==" + } + }, + { + "minTime": "1587684605791", + "maxTime": "1587686390791", + "raw": { + "data": "AHi+/YOWtVxBF2gkAAAAAJh17EerqRTuZfH0e1NrQzUWtwN/IoHkgxyA4upNxgA3mL2/5upHbABvQjfdiMeADuok3/JyM+hgA6FJRtUAGwit/zQX8AGzrSE0gAyPUv+iExgAziP/dSajACnQrF7/YmagBSI1zL4DABsTS/5po8AGxtEMeADeRntd/zQqMAGxcSc3gAyCOv+iFLgAyMIQ38AF7DP/7/q6kR8AF9CcC6k+GADeZfQ7/mhzQAbL6Q5IAdiC3+NyM9tgB2FFR3MAGwpV/zTu0AGwqSDugBCLSv+Dib9ngBCC2IYRACUEkv9yORQAlA6kFMgBGHj3+9ApoARgnye4wAhByL/ggSUAIQytBH4AZj2l/nQTSAGYFyhgkALQQ2/1OB32jAC0GXoDbgAiBq7/whwyACIExQbPADMBq3+dHQ8AMwIOg++AKIHtv7CHDYAogfFB+EAFwPhf9U/2QAXApyDMoARgOu/3oEmgBGHdEDtQAFBqN/+QH3AAUC9I/BgA6BX7/kgzKADoDfQK/ACMA33+9DnUAIwNWgzCAGYFyv87ef/D4AZgIMA=" + } + }, + { + "minTime": "1587686405791", + "maxTime": "1587688190791", + "raw": { + "data": "AHi+2t+XtVxBGQhgAAAAAKB17EZd/4dSLeACOZPbdSaDABvQr97/mkogA3kV5rqTyYAQ6E+2/4OpPlgBDmR+upMtSvdCNN1IiXEf+6kyN0K8lOQ5l9/QxoANi4X/NPggA2FUjqwAZDmv+jkZ97ABkOMjFUI4nPkJij6UNY4G/iUCDQdlAl3MvlKLKhMJyMAGw9b/miZQAbyL+ihSwAHGSv/rqTHYADmI5l9DgA6Prf8k12ADoniF5ABnEv8d/0QNoAM6kVboVYMAA8x+9//dx8cAA9RYuhXxwAnIrf7XIz7mAE4SVG1QAzCoX+dOLQAzBtIveADIMu/6IXeADNx/+HQD5dCthSFuZfo0aSAFJlV/sQ4oAUifuRnpsAGw+F/zRtcAGwY6GtgAuc1v+qFzgAuNnQX0AF8Tfb9/1QMeAC4Jah0cAGQTu/6I4vABkF4Q2iADILNf9EDXgAyfdIF+gr6GVoPyjtUAIQMK/4IWdACEBdQLFwN+zoEo6FYqiggA2dW/5uZP7gA3qT23Qr0UwgA=" + } + }, + { + "minTime": "1587688205791", + "maxTime": "1587689990791", + "raw": { + "data": "AHi+t7uZtVxBGp6wAAAAAJh15Ffm6kSboTo0wHMv+qKFABk3S/6IgMAGQ/HE37mgp0AFQ9y/7IInABUdBQN+ADoKZf8kPPgA6BaIIcncaGiILagQqOfIPmhnCBfIIpABG83+jf+HUjzgAjoVtqQRG85kd7qR2uhGy6kyuAFeRniN/rQmsAKwaSNfQkif1Qj6NqQfcADwtd/5cTP2YAH7EcrqTpXQrb4AMjMv+iR2ADOZPldSLGADJ1v+joVrsAGTxuRf8UIlHodSb+nu5jeupEa6FYikzcDv2WAIYEBv76A1YAhg1NA/SHfUB0oGxQZOgWmAGY9qv86BeoAZgwhAsaHd0BsIFYQZsgaKADoD2v+SfaIAOgSBBwiBFIAJhxq/7oDEgAmBOkGVIFMR+ugQhBsCBMUOJoEzQY6gQdAdDah/xbqTe3Qr6YAMltv+iIuADOY/FFHQnVwArOG/1uRnisAKwkSCCgBmMev86FLA" + } + }, + { + "minTime": "1587690005791", + "maxTime": "1587691790791", + "raw": { + "data": "AHi+lJebtVxBHDJAAAAAAJh16k9eABuhWj3/pJ1AA0c7iZ9WgPkF46Fe+lKRsuZHW6ky90JzaRzkV/LqTRYAW6D5b/U7DcwAt1JnrmR1wAD1I77/+6E4GAAZBOBn6rsRUupHynt0JxqXbmV1qNxDEmqRKuRnjqGKQciMeQqKfMQmSMmQq7ib8VQSpAvkMBQXJHnEFXQ5tBz0/ZQfBD4EHkR+VBp0NUQUdAtm8/+BoCfoHsoCtoPToDtoHyQATAe2/7oeeQATAQ1A1OAGoCbX+ZBz2AGoC1IBXwAbAxa/5oCRwAbH01AQGADoH53/JAXKADoBJoOhwApAY6/2IGqwApAOdAVSADIfq3/RAVWADIB3oGGQAZAV6/6IOKQAZAaZAO+ADYGGX/NASaADZ+KIDJwAhAIO/4IGCwAhAXdB+qAGYCAX+dAxSAGYDyof5wADAWy//oGUwADARhB6JAbhAIxA9ZAR2ADIBXX/RH1mADID8A==" + } + }, + { + "minTime": "1587691805791", + "maxTime": "1587693590791", + "raw": { + "data": "AHW+8fKctVxBHcmQAAAAAJh16k1VOpzK7V1JiroVxKThyK9d1Jr6XroV9aTxES5l8XRkE2NEHgBnch/gN/nQCOQAzAZUgCegBmAWq/zoHCoAZgFEQGIwADAOhf/0HisAAwCDIDbIAOgExv+SBwiADoAtkAmcAHQH33/JAKvAB0Ph6AS2ACoA0b/sgOWgAqADFAGkgBKQD+IAVUAF6AMti9+7k6AAAAAA5X5F/RYAAAAAAB1QOIAhgAAAAAAAgAyAAAAAAACA+igAAAAAAIALIAAAAAAAgBzMAAAAAACAB1AAAAAAAIAMZAAAAAABABkADnAAAAAAAv+iAPmYAAAAAAQAZAAOIAAAAAAEABcAAAAAAAgA6AB8gAAAAAAX/JAALAAAAAAAIAOgAL0AAAAAACAD/AAAAAAAQAfAARcAAAAAAL/igAZaAAAAAAEAHwACrAAAAAABAAWIAAAAAAEAPsYAAAAAAQACugAAAAABAAYwAAAAAAEAAO4AAAAAAQABfAAAAAABAAI8AAAAAAEADpgAAAAAAQACWAAAAAABAAdcAAAAAAIATgAFFAAAAAAF/tQAecAAAAAACAE4AAuAAAAAAAgAE/AAAAAACAAx0AAAAAAIABYgAAAAAAgAcbAAAAAACAAY8AAAAAAIAA/AAAAAABAD0ABogAAAAAAv8SAAfQAAAAAAQA9AP7VAAAAAAEAASIAAAAAAQAAwwAAAAABAANNAAAAAAEAAeEAAAAAAQAH/wAAAAABAAHrAAAAAAEAA2sAAAAAAQAA1QAAAAABAA70AAAAAAEAAOIAAAAAAgAyAAJ4AAAAAAX/RAAMDAAAAAAIAMgACfgAAAAACAA5GAAAAAAIABYIAAAAABABsAAOUAAAAAAv+aAAKSAAAAAAQAbAB8MAAAAAAEAATcAAAAAAQAD+QAAAAABAAEKAAAAAAEABxUAAAAAAQABUAAAAAABAANEAAAAAAIAZgACmgAAAAAF/nQAA3QAAAAACAGYAHggAAAAAAgACqAAAAAACAAeWAAAAAAA==" + } + } + ] + } +} diff --git a/pkg/receive/config.go b/pkg/receive/config.go index 782e9a9b11..ed706e0f1f 100644 --- a/pkg/receive/config.go +++ b/pkg/receive/config.go @@ -16,6 +16,7 @@ import ( "github.com/go-kit/kit/log/level" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/common/model" "gopkg.in/fsnotify.v1" ) @@ -58,7 +59,7 @@ type ConfigWatcher struct { } // NewConfigWatcher creates a new ConfigWatcher. -func NewConfigWatcher(logger log.Logger, r prometheus.Registerer, path string, interval model.Duration) (*ConfigWatcher, error) { +func NewConfigWatcher(logger log.Logger, reg prometheus.Registerer, path string, interval model.Duration) (*ConfigWatcher, error) { if logger == nil { logger = log.NewNopLogger() } @@ -77,63 +78,49 @@ func NewConfigWatcher(logger log.Logger, r prometheus.Registerer, path string, i interval: time.Duration(interval), logger: logger, watcher: watcher, - hashGauge: prometheus.NewGauge( + hashGauge: promauto.With(reg).NewGauge( prometheus.GaugeOpts{ Name: "thanos_receive_config_hash", Help: "Hash of the currently loaded hashring configuration file.", }), - successGauge: prometheus.NewGauge( + successGauge: promauto.With(reg).NewGauge( prometheus.GaugeOpts{ Name: "thanos_receive_config_last_reload_successful", Help: "Whether the last hashring configuration file reload attempt was successful.", }), - lastSuccessTimeGauge: prometheus.NewGauge( + lastSuccessTimeGauge: promauto.With(reg).NewGauge( prometheus.GaugeOpts{ Name: "thanos_receive_config_last_reload_success_timestamp_seconds", Help: "Timestamp of the last successful hashring configuration file reload.", }), - changesCounter: prometheus.NewCounter( + changesCounter: promauto.With(reg).NewCounter( prometheus.CounterOpts{ Name: "thanos_receive_hashrings_file_changes_total", Help: "The number of times the hashrings configuration file has changed.", }), - errorCounter: prometheus.NewCounter( + errorCounter: promauto.With(reg).NewCounter( prometheus.CounterOpts{ Name: "thanos_receive_hashrings_file_errors_total", Help: "The number of errors watching the hashrings configuration file.", }), - refreshCounter: prometheus.NewCounter( + refreshCounter: promauto.With(reg).NewCounter( prometheus.CounterOpts{ Name: "thanos_receive_hashrings_file_refreshes_total", Help: "The number of refreshes of the hashrings configuration file.", }), - hashringNodesGauge: prometheus.NewGaugeVec( + hashringNodesGauge: promauto.With(reg).NewGaugeVec( prometheus.GaugeOpts{ Name: "thanos_receive_hashring_nodes", Help: "The number of nodes per hashring.", }, []string{"name"}), - hashringTenantsGauge: prometheus.NewGaugeVec( + hashringTenantsGauge: promauto.With(reg).NewGaugeVec( prometheus.GaugeOpts{ Name: "thanos_receive_hashring_tenants", Help: "The number of tenants per hashring.", }, []string{"name"}), } - - if r != nil { - r.MustRegister( - c.hashGauge, - c.successGauge, - c.lastSuccessTimeGauge, - c.changesCounter, - c.errorCounter, - c.refreshCounter, - c.hashringNodesGauge, - c.hashringTenantsGauge, - ) - } - return c, nil } diff --git a/pkg/receive/handler.go b/pkg/receive/handler.go index 4be160972a..5b1aa2daf4 100644 --- a/pkg/receive/handler.go +++ b/pkg/receive/handler.go @@ -22,10 +22,12 @@ import ( opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/common/route" - "github.com/prometheus/prometheus/prompb" "github.com/prometheus/prometheus/storage" + "github.com/prometheus/prometheus/storage/tsdb" terrors "github.com/prometheus/prometheus/tsdb/errors" + "github.com/thanos-io/thanos/pkg/store/storepb/prompb" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -39,6 +41,10 @@ import ( const ( // DefaultTenantHeader is the default header used to designate the tenant making a write request. DefaultTenantHeader = "THANOS-TENANT" + // DefaultTenant is the default value used for when no tenant is passed via the tenant header. + DefaultTenant = "default-tenant" + // DefaultTenantLabel is the default label-name used for when no tenant is passed via the tenant header. + DefaultTenantLabel = "tenant_id" // DefaultReplicaHeader is the default header used to designate the replica count of a write request. DefaultReplicaHeader = "THANOS-REPLICA" ) @@ -54,12 +60,12 @@ type Options struct { ListenAddress string Registry prometheus.Registerer TenantHeader string + DefaultTenantID string ReplicaHeader string Endpoint string ReplicationFactor uint64 Tracer opentracing.Tracer TLSConfig *tls.Config - TLSClientConfig *tls.Config DialOpts []grpc.DialOption } @@ -90,7 +96,7 @@ func NewHandler(logger log.Logger, o *Options) *Handler { router: route.New(), options: o, peers: newPeerGroup(o.DialOpts...), - forwardRequestsTotal: prometheus.NewCounterVec( + forwardRequestsTotal: promauto.With(o.Registry).NewCounterVec( prometheus.CounterOpts{ Name: "thanos_receive_forward_requests_total", Help: "The number of forward requests.", @@ -101,7 +107,6 @@ func NewHandler(logger log.Logger, o *Options) *Handler { ins := extpromhttp.NewNopInstrumentationMiddleware() if o.Registry != nil { ins = extpromhttp.NewInstrumentationMiddleware(o.Registry) - o.Registry.MustRegister(h.forwardRequestsTotal) } readyf := h.testReady @@ -117,16 +122,6 @@ func NewHandler(logger log.Logger, o *Options) *Handler { return h } -// SetWriter sets the writer. -// The writer must be set to a non-nil value in order for the -// handler to be ready and usable. -// If the writer is nil, then the handler is marked as not ready. -func (h *Handler) SetWriter(w *Writer) { - h.mtx.Lock() - defer h.mtx.Unlock() - h.writer = w -} - // Hashring sets the hashring for the handler and marks the hashring as ready. // The hashring must be set to a non-nil value in order for the // handler to be ready and usable. @@ -192,6 +187,13 @@ func (h *Handler) Run() error { TLSConfig: h.options.TLSConfig, } + if h.options.TLSConfig != nil { + level.Info(h.logger).Log("msg", "Serving HTTPS", "address", h.options.ListenAddress) + // Cert & Key are already being passed in via TLSConfig. + return httpSrv.ServeTLS(h.listener, "", "") + } + + level.Info(h.logger).Log("msg", "Serving plain HTTP", "address", h.options.ListenAddress) return httpSrv.Serve(h.listener) } @@ -260,11 +262,16 @@ func (h *Handler) receiveHTTP(w http.ResponseWriter, r *http.Request) { } tenant := r.Header.Get(h.options.TenantHeader) + if len(tenant) == 0 { + tenant = h.options.DefaultTenantID + } err = h.handleRequest(r.Context(), rep, tenant, &wreq) switch err { case nil: return + case tsdb.ErrNotReady: + http.Error(w, err.Error(), http.StatusServiceUnavailable) case conflictErr: http.Error(w, err.Error(), http.StatusConflict) case errBadReplica: @@ -352,22 +359,22 @@ func (h *Handler) parallelizeRequests(ctx context.Context, tenant string, replic if endpoint == h.options.Endpoint { go func(endpoint string) { var err error - h.mtx.RLock() - if h.writer == nil { - err = errors.New("storage is not ready") - } else { - err = h.writer.Write(wreqs[endpoint]) - // When a MultiError is added to another MultiError, the error slices are concatenated, not nested. - // To avoid breaking the counting logic, we need to flatten the error. - if errs, ok := err.(terrors.MultiError); ok { - if countCause(errs, isConflict) > 0 { - err = errors.Wrap(conflictErr, errs.Error()) - } else { - err = errors.New(errs.Error()) - } + + tracing.DoInSpan(ctx, "receive_tsdb_write", func(ctx context.Context) { + err = h.writer.Write(tenant, wreqs[endpoint]) + }) + + // When a MultiError is added to another MultiError, the error slices are concatenated, not nested. + // To avoid breaking the counting logic, we need to flatten the error. + if errs, ok := err.(terrors.MultiError); ok { + if countCause(errs, isConflict) > 0 { + err = errors.Wrap(conflictErr, errs.Error()) + } else if countCause(errs, isNotReady) > 0 { + err = tsdb.ErrNotReady + } else { + err = errors.New(errs.Error()) } } - h.mtx.RUnlock() if err != nil { level.Error(h.logger).Log("msg", "storing locally", "err", err, "endpoint", endpoint) } @@ -395,24 +402,22 @@ func (h *Handler) parallelizeRequests(ctx context.Context, tenant string, replic ec <- err return } - // Create a span to track the request made to another receive node. - span, ctx := tracing.StartSpan(ctx, "thanos_receive_forward") - defer span.Finish() - - // Actually make the request against the endpoint - // we determined should handle these time series. - _, err = cl.RemoteWrite(ctx, &storepb.WriteRequest{ - Timeseries: wreqs[endpoint].Timeseries, - Tenant: tenant, - Replica: int64(replicas[endpoint].n + 1), // increment replica since on-the-wire format is 1-indexed and 0 indicates unreplicated. + tracing.DoInSpan(ctx, "receive_forward", func(ctx context.Context) { + // Actually make the request against the endpoint + // we determined should handle these time series. + _, err = cl.RemoteWrite(ctx, &storepb.WriteRequest{ + Timeseries: wreqs[endpoint].Timeseries, + Tenant: tenant, + Replica: int64(replicas[endpoint].n + 1), // increment replica since on-the-wire format is 1-indexed and 0 indicates unreplicated. + }) + if err != nil { + level.Error(h.logger).Log("msg", "forwarding request", "err", err, "endpoint", endpoint) + ec <- err + return + } + ec <- nil }) - if err != nil { - level.Error(h.logger).Log("msg", "forwarding request", "err", err, "endpoint", endpoint) - ec <- err - return - } - ec <- nil }(endpoint) } @@ -461,6 +466,9 @@ func (h *Handler) replicate(ctx context.Context, tenant string, wreq *prompb.Wri err := h.parallelizeRequests(ctx, tenant, replicas, wreqs) if errs, ok := err.(terrors.MultiError); ok { + if uint64(countCause(errs, isNotReady)) >= (h.options.ReplicationFactor+1)/2 { + return tsdb.ErrNotReady + } if uint64(countCause(errs, isConflict)) >= (h.options.ReplicationFactor+1)/2 { return errors.Wrap(conflictErr, "did not meet replication threshold") } @@ -478,6 +486,8 @@ func (h *Handler) RemoteWrite(ctx context.Context, r *storepb.WriteRequest) (*st switch err { case nil: return &storepb.WriteResponse{}, nil + case tsdb.ErrNotReady: + return nil, status.Error(codes.Unavailable, err.Error()) case conflictErr: return nil, status.Error(codes.AlreadyExists, err.Error()) case errBadReplica: @@ -518,6 +528,12 @@ func isConflict(err error) bool { status.Code(err) == codes.AlreadyExists } +// isNotReady returns whether or not the given error represents a not ready error. +func isNotReady(err error) bool { + return err == tsdb.ErrNotReady || + status.Code(err) == codes.Unavailable +} + func newPeerGroup(dialOpts ...grpc.DialOption) *peerGroup { return &peerGroup{ dialOpts: dialOpts, diff --git a/pkg/receive/handler_test.go b/pkg/receive/handler_test.go index 5d48e32f21..8be28333b6 100644 --- a/pkg/receive/handler_test.go +++ b/pkg/receive/handler_test.go @@ -13,18 +13,19 @@ import ( "strconv" "sync" "testing" + "time" + "github.com/fortytw2/leaktest" "github.com/go-kit/kit/log" "github.com/gogo/protobuf/proto" "github.com/golang/snappy" "github.com/pkg/errors" "github.com/prometheus/prometheus/pkg/labels" - "github.com/prometheus/prometheus/prompb" "github.com/prometheus/prometheus/storage" terrors "github.com/prometheus/prometheus/tsdb/errors" - "google.golang.org/grpc" - "github.com/thanos-io/thanos/pkg/store/storepb" + "github.com/thanos-io/thanos/pkg/store/storepb/prompb" + "google.golang.org/grpc" ) func TestCountCause(t *testing.T) { @@ -164,7 +165,7 @@ func newHandlerHashring(appendables []*fakeAppendable, replicationFactor uint64) TenantHeader: DefaultTenantHeader, ReplicaHeader: DefaultReplicaHeader, ReplicationFactor: replicationFactor, - Writer: NewWriter(log.NewNopLogger(), appendables[i]), + Writer: NewWriter(log.NewNopLogger(), newFakeTenantAppendable(appendables[i])), }) handlers = append(handlers, h) h.peers = peers @@ -181,6 +182,8 @@ func newHandlerHashring(appendables []*fakeAppendable, replicationFactor uint64) } func TestReceive(t *testing.T) { + defer leaktest.CheckTimeout(t, 10*time.Second) + appenderErrFn := func() error { return errors.New("failed to get appender") } conflictErrFn := func() error { return storage.ErrOutOfBounds } commitErrFn := func() error { return errors.New("failed to commit") } @@ -223,7 +226,7 @@ func TestReceive(t *testing.T) { replicationFactor: 1, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, }, @@ -234,7 +237,7 @@ func TestReceive(t *testing.T) { replicationFactor: 1, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, commitErrFn, nil), }, }, @@ -245,7 +248,7 @@ func TestReceive(t *testing.T) { replicationFactor: 1, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(conflictErrFn, nil, nil, nil), }, }, @@ -256,10 +259,10 @@ func TestReceive(t *testing.T) { replicationFactor: 1, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, }, @@ -270,13 +273,13 @@ func TestReceive(t *testing.T) { replicationFactor: 1, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, }, @@ -287,13 +290,13 @@ func TestReceive(t *testing.T) { replicationFactor: 3, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, }, @@ -304,13 +307,13 @@ func TestReceive(t *testing.T) { replicationFactor: 1, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, commitErrFn, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, commitErrFn, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, commitErrFn, nil), }, }, @@ -321,13 +324,13 @@ func TestReceive(t *testing.T) { replicationFactor: 3, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, commitErrFn, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, commitErrFn, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, commitErrFn, nil), }, }, @@ -338,15 +341,15 @@ func TestReceive(t *testing.T) { replicationFactor: 3, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), appenderErr: appenderErrFn, }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), appenderErr: appenderErrFn, }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), appenderErr: appenderErrFn, }, @@ -358,13 +361,13 @@ func TestReceive(t *testing.T) { replicationFactor: 3, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(conflictErrFn, nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(conflictErrFn, nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(conflictErrFn, nil, nil, nil), }, }, @@ -375,13 +378,13 @@ func TestReceive(t *testing.T) { replicationFactor: 3, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(conflictErrFn, nil, commitErrFn, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(conflictErrFn, nil, commitErrFn, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(conflictErrFn, nil, commitErrFn, nil), }, }, @@ -392,13 +395,13 @@ func TestReceive(t *testing.T) { replicationFactor: 3, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(cycleErrors([]error{storage.ErrOutOfBounds, storage.ErrOutOfOrderSample, storage.ErrDuplicateSampleForTimestamp}), nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, }, @@ -409,13 +412,13 @@ func TestReceive(t *testing.T) { replicationFactor: 3, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, commitErrFn, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, }, @@ -426,13 +429,13 @@ func TestReceive(t *testing.T) { replicationFactor: 3, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(cycleErrors([]error{storage.ErrOutOfBounds, storage.ErrOutOfOrderSample, storage.ErrDuplicateSampleForTimestamp}), nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(conflictErrFn, nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, }, @@ -443,13 +446,13 @@ func TestReceive(t *testing.T) { replicationFactor: 3, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(cycleErrors([]error{storage.ErrOutOfBounds, storage.ErrOutOfOrderSample, storage.ErrDuplicateSampleForTimestamp}), nil, nil, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, commitErrFn, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, }, @@ -460,13 +463,13 @@ func TestReceive(t *testing.T) { replicationFactor: 3, wreq: wreq1, appendables: []*fakeAppendable{ - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, commitErrFn, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, commitErrFn, nil), }, - &fakeAppendable{ + { appender: newFakeAppender(nil, nil, nil, nil), }, }, @@ -480,12 +483,12 @@ func TestReceive(t *testing.T) { // on which node is erroring and which node is receiving. for i, handler := range handlers { // Test that the correct status is returned. - status, err := makeRequest(handler, tenant, tc.wreq) + rec, err := makeRequest(handler, tenant, tc.wreq) if err != nil { t.Fatalf("handler %d: unexpectedly failed making HTTP request: %v", tc.status, err) } - if status != tc.status { - t.Errorf("handler %d: got unexpected HTTP status code: expected %d, got %d", i, tc.status, status) + if rec.Code != tc.status { + t.Errorf("handler %d: got unexpected HTTP status code: expected %d, got %d; body: %s", i, tc.status, rec.Code, rec.Body.String()) } } // Test that each time series is stored @@ -548,14 +551,14 @@ func cycleErrors(errs []error) func() error { } // makeRequest is a helper to make a correct request against a remote write endpoint given a request. -func makeRequest(h *Handler, tenant string, wreq *prompb.WriteRequest) (int, error) { +func makeRequest(h *Handler, tenant string, wreq *prompb.WriteRequest) (*httptest.ResponseRecorder, error) { buf, err := proto.Marshal(wreq) if err != nil { - return 0, errors.Wrap(err, "marshal request") + return nil, errors.Wrap(err, "marshal request") } req, err := http.NewRequest("POST", h.options.Endpoint, bytes.NewBuffer(snappy.Encode(nil, buf))) if err != nil { - return 0, errors.Wrap(err, "create request") + return nil, errors.Wrap(err, "create request") } req.Header.Add(h.options.TenantHeader, tenant) @@ -563,7 +566,7 @@ func makeRequest(h *Handler, tenant string, wreq *prompb.WriteRequest) (int, err h.receiveHTTP(rec, req) rec.Flush() - return rec.Code, nil + return rec, nil } func randomAddr() string { diff --git a/pkg/receive/hashring.go b/pkg/receive/hashring.go index 83b0bdc18e..ef6c94390a 100644 --- a/pkg/receive/hashring.go +++ b/pkg/receive/hashring.go @@ -11,7 +11,7 @@ import ( "github.com/cespare/xxhash" "github.com/pkg/errors" - "github.com/prometheus/prometheus/prompb" + "github.com/thanos-io/thanos/pkg/store/storepb/prompb" ) const sep = '\xff' diff --git a/pkg/receive/hashring_test.go b/pkg/receive/hashring_test.go index b2a50fdc4b..0f69e2dea7 100644 --- a/pkg/receive/hashring_test.go +++ b/pkg/receive/hashring_test.go @@ -6,7 +6,7 @@ package receive import ( "testing" - "github.com/prometheus/prometheus/prompb" + "github.com/thanos-io/thanos/pkg/store/storepb/prompb" ) func TestHash(t *testing.T) { @@ -64,7 +64,7 @@ func TestHashringGet(t *testing.T) { Endpoints: []string{"node1"}, }, }, - nodes: map[string]struct{}{"node1": struct{}{}}, + nodes: map[string]struct{}{"node1": {}}, }, { name: "specific", @@ -77,7 +77,7 @@ func TestHashringGet(t *testing.T) { Endpoints: []string{"node1"}, }, }, - nodes: map[string]struct{}{"node2": struct{}{}}, + nodes: map[string]struct{}{"node2": {}}, tenant: "tenant2", }, { @@ -96,7 +96,7 @@ func TestHashringGet(t *testing.T) { Tenants: []string{"tenant3"}, }, }, - nodes: map[string]struct{}{"node1": struct{}{}}, + nodes: map[string]struct{}{"node1": {}}, tenant: "tenant1", }, { @@ -129,9 +129,9 @@ func TestHashringGet(t *testing.T) { }, }, nodes: map[string]struct{}{ - "node1": struct{}{}, - "node2": struct{}{}, - "node3": struct{}{}, + "node1": {}, + "node2": {}, + "node3": {}, }, tenant: "tenant1", }, @@ -147,9 +147,9 @@ func TestHashringGet(t *testing.T) { }, }, nodes: map[string]struct{}{ - "node4": struct{}{}, - "node5": struct{}{}, - "node6": struct{}{}, + "node4": {}, + "node5": {}, + "node6": {}, }, }, } { diff --git a/pkg/receive/multitsdb.go b/pkg/receive/multitsdb.go new file mode 100644 index 0000000000..b907da1315 --- /dev/null +++ b/pkg/receive/multitsdb.go @@ -0,0 +1,304 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package receive + +import ( + "context" + "io/ioutil" + "os" + "path" + "sync" + "time" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/storage/tsdb" + terrors "github.com/prometheus/prometheus/tsdb/errors" + "github.com/thanos-io/thanos/pkg/block/metadata" + "github.com/thanos-io/thanos/pkg/component" + "github.com/thanos-io/thanos/pkg/objstore" + "github.com/thanos-io/thanos/pkg/runutil" + "github.com/thanos-io/thanos/pkg/shipper" + "github.com/thanos-io/thanos/pkg/store" + "golang.org/x/sync/errgroup" +) + +type MultiTSDB struct { + dataDir string + logger log.Logger + reg prometheus.Registerer + tsdbOpts *tsdb.Options + tenantLabelName string + labels labels.Labels + bucket objstore.Bucket + + mtx *sync.RWMutex + tenants map[string]*tenant +} + +func NewMultiTSDB( + dataDir string, + l log.Logger, + reg prometheus.Registerer, + tsdbOpts *tsdb.Options, + labels labels.Labels, + tenantLabelName string, + bucket objstore.Bucket, +) *MultiTSDB { + if l == nil { + l = log.NewNopLogger() + } + + return &MultiTSDB{ + dataDir: dataDir, + logger: l, + reg: reg, + tsdbOpts: tsdbOpts, + mtx: &sync.RWMutex{}, + tenants: map[string]*tenant{}, + labels: labels, + tenantLabelName: tenantLabelName, + bucket: bucket, + } +} + +type tenant struct { + tsdbOpts *tsdb.Options + + readyS *tsdb.ReadyStorage + fs *FlushableStorage + s *store.TSDBStore + ship *shipper.Shipper + + mtx *sync.RWMutex +} + +func newTenant(tsdbOpts *tsdb.Options) *tenant { + return &tenant{ + tsdbOpts: tsdbOpts, + readyS: &tsdb.ReadyStorage{}, + mtx: &sync.RWMutex{}, + } +} + +func (t *tenant) readyStorage() *tsdb.ReadyStorage { + return t.readyS +} + +func (t *tenant) store() *store.TSDBStore { + t.mtx.RLock() + defer t.mtx.RUnlock() + return t.s +} + +func (t *tenant) shipper() *shipper.Shipper { + t.mtx.RLock() + defer t.mtx.RUnlock() + return t.ship +} + +func (t *tenant) flushableStorage() *FlushableStorage { + t.mtx.RLock() + defer t.mtx.RUnlock() + return t.fs +} + +func (t *tenant) set(tstore *store.TSDBStore, fs *FlushableStorage, ship *shipper.Shipper) { + t.readyS.Set(fs.Get(), int64(2*time.Duration(t.tsdbOpts.MinBlockDuration).Seconds()*1000)) + t.mtx.Lock() + t.fs = fs + t.s = tstore + t.ship = ship + t.mtx.Unlock() +} + +func (t *MultiTSDB) Open() error { + if err := os.MkdirAll(t.dataDir, 0777); err != nil { + return err + } + + files, err := ioutil.ReadDir(t.dataDir) + if err != nil { + return err + } + + var g errgroup.Group + for _, f := range files { + f := f + if !f.IsDir() { + continue + } + + g.Go(func() error { + _, err := t.getOrLoadTenant(f.Name(), true) + return err + }) + } + + return g.Wait() +} + +func (t *MultiTSDB) Flush() error { + t.mtx.RLock() + defer t.mtx.RUnlock() + + errmtx := &sync.Mutex{} + merr := terrors.MultiError{} + wg := &sync.WaitGroup{} + for _, tenant := range t.tenants { + s := tenant.flushableStorage() + if s == nil { + continue + } + + wg.Add(1) + go func() { + if err := s.Flush(); err != nil { + errmtx.Lock() + merr.Add(err) + errmtx.Unlock() + } + wg.Done() + }() + } + + wg.Wait() + return merr.Err() +} + +func (t *MultiTSDB) Sync(ctx context.Context) error { + t.mtx.RLock() + defer t.mtx.RUnlock() + + errmtx := &sync.Mutex{} + merr := terrors.MultiError{} + wg := &sync.WaitGroup{} + for tenantID, tenant := range t.tenants { + level.Debug(t.logger).Log("msg", "uploading block for tenant", "tenant", tenantID) + s := tenant.shipper() + if s == nil { + continue + } + + wg.Add(1) + go func() { + if uploaded, err := s.Sync(ctx); err != nil { + errmtx.Lock() + merr.Add(errors.Wrapf(err, "upload %d", uploaded)) + errmtx.Unlock() + } + wg.Done() + }() + } + + wg.Wait() + return merr.Err() +} + +func (t *MultiTSDB) TSDBStores() map[string]*store.TSDBStore { + t.mtx.RLock() + defer t.mtx.RUnlock() + + res := make(map[string]*store.TSDBStore, len(t.tenants)) + for k, tenant := range t.tenants { + s := tenant.store() + if s != nil { + res[k] = s + } + } + return res +} + +func (t *MultiTSDB) getOrLoadTenant(tenantID string, blockingStart bool) (*tenant, error) { + // Fast path, as creating tenants is a very rare operation. + t.mtx.RLock() + tenant, exist := t.tenants[tenantID] + t.mtx.RUnlock() + if exist { + return tenant, nil + } + + // Slow path needs to lock fully and attempt to read again to prevent race + // conditions, where since the fast path was tried, there may have actually + // been the same tenant inserted in the map. + t.mtx.Lock() + tenant, exist = t.tenants[tenantID] + if exist { + t.mtx.Unlock() + return tenant, nil + } + + tenant = newTenant(t.tsdbOpts) + t.tenants[tenantID] = tenant + t.mtx.Unlock() + + var err error + startTSDB := func() { + reg := prometheus.WrapRegistererWith(prometheus.Labels{ + "tenant": tenantID, + }, t.reg) + logger := log.With(t.logger, "tenant", tenantID) + lbls := append(t.labels, labels.Label{Name: t.tenantLabelName, Value: tenantID}) + dataDir := path.Join(t.dataDir, tenantID) + + var ship *shipper.Shipper + if t.bucket != nil { + ship = shipper.New( + logger, + reg, + dataDir, + t.bucket, + func() labels.Labels { return lbls }, + metadata.ReceiveSource, + ) + } + + s := NewFlushableStorage( + dataDir, + logger, + reg, + t.tsdbOpts, + ) + + // Assign to outer error to report in blocking case. + if err = s.Open(); err != nil { + level.Error(logger).Log("msg", "failed to open tsdb", "err", err) + t.mtx.Lock() + delete(t.tenants, tenantID) + t.mtx.Unlock() + runutil.CloseWithLogOnErr(logger, s, "failed to close tsdb") + return + } + + tenant.set( + store.NewTSDBStore( + logger, + reg, + s.Get(), + component.Receive, + lbls, + ), + s, + ship, + ) + } + if !blockingStart { + go startTSDB() + return tenant, nil + } + + startTSDB() + return tenant, err +} + +func (t *MultiTSDB) TenantAppendable(tenantID string) (Appendable, error) { + tenant, err := t.getOrLoadTenant(tenantID, false) + if err != nil { + return nil, err + } + return tenant.readyStorage(), nil +} diff --git a/pkg/receive/multitsdb_test.go b/pkg/receive/multitsdb_test.go new file mode 100644 index 0000000000..2db04f74e6 --- /dev/null +++ b/pkg/receive/multitsdb_test.go @@ -0,0 +1,260 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package receive + +import ( + "context" + "fmt" + "io/ioutil" + "os" + "testing" + "time" + + "github.com/fortytw2/leaktest" + "github.com/go-kit/kit/log" + "github.com/gogo/protobuf/types" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/storage" + "github.com/prometheus/prometheus/storage/tsdb" + "github.com/thanos-io/thanos/pkg/runutil" + "github.com/thanos-io/thanos/pkg/store/storepb" + "github.com/thanos-io/thanos/pkg/testutil" + "golang.org/x/sync/errgroup" +) + +func TestMultiTSDB(t *testing.T) { + defer leaktest.CheckTimeout(t, 10*time.Second) + + dir, err := ioutil.TempDir("", "test") + testutil.Ok(t, err) + defer func() { testutil.Ok(t, os.RemoveAll(dir)) }() + + logger := log.NewNopLogger() + t.Run("run fresh", func(t *testing.T) { + m := NewMultiTSDB( + dir, logger, prometheus.NewRegistry(), &tsdb.Options{ + MinBlockDuration: model.Duration(2 * time.Hour), + MaxBlockDuration: model.Duration(2 * time.Hour), + RetentionDuration: model.Duration(6 * time.Hour), + NoLockfile: true, + }, + labels.FromStrings("replica", "01"), + "tenant_id", + nil, + ) + defer testutil.Ok(t, m.Flush()) + + testutil.Ok(t, m.Flush()) + testutil.Ok(t, m.Open()) + + app, err := m.TenantAppendable("foo") + testutil.Ok(t, err) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + var a storage.Appender + testutil.Ok(t, runutil.Retry(1*time.Second, ctx.Done(), func() error { + a, err = app.Appender() + return err + })) + + _, err = a.Add(labels.FromStrings("a", "1", "b", "2"), 1, 2.41241) + testutil.Ok(t, err) + _, err = a.Add(labels.FromStrings("a", "1", "b", "2"), 2, 3.41241) + testutil.Ok(t, err) + _, err = a.Add(labels.FromStrings("a", "1", "b", "2"), 3, 4.41241) + testutil.Ok(t, err) + testutil.Ok(t, a.Commit()) + + // Check if not leaking. + _, err = m.TenantAppendable("foo") + testutil.Ok(t, err) + _, err = m.TenantAppendable("foo") + testutil.Ok(t, err) + _, err = m.TenantAppendable("foo") + testutil.Ok(t, err) + + ctx, cancel = context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + app, err = m.TenantAppendable("bar") + testutil.Ok(t, err) + + testutil.Ok(t, runutil.Retry(1*time.Second, ctx.Done(), func() error { + a, err = app.Appender() + return err + })) + + _, err = a.Add(labels.FromStrings("a", "1", "b", "2"), 1, 20.41241) + testutil.Ok(t, err) + _, err = a.Add(labels.FromStrings("a", "1", "b", "2"), 2, 30.41241) + testutil.Ok(t, err) + _, err = a.Add(labels.FromStrings("a", "1", "b", "2"), 3, 40.41241) + testutil.Ok(t, err) + testutil.Ok(t, a.Commit()) + + testMulitTSDBSeries(t, m) + }) + t.Run("run on existing storage", func(t *testing.T) { + m := NewMultiTSDB( + dir, logger, prometheus.NewRegistry(), &tsdb.Options{ + MinBlockDuration: model.Duration(2 * time.Hour), + MaxBlockDuration: model.Duration(2 * time.Hour), + RetentionDuration: model.Duration(6 * time.Hour), + NoLockfile: true, + }, + labels.FromStrings("replica", "01"), + "tenant_id", + nil, + ) + defer testutil.Ok(t, m.Flush()) + + testutil.Ok(t, m.Flush()) + testutil.Ok(t, m.Open()) + + // Get appender just for test. + app, err := m.TenantAppendable("foo") + testutil.Ok(t, err) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + testutil.Ok(t, runutil.Retry(1*time.Second, ctx.Done(), func() error { + _, err := app.Appender() + return err + })) + + // Check if not leaking. + _, err = m.TenantAppendable("foo") + testutil.Ok(t, err) + _, err = m.TenantAppendable("foo") + testutil.Ok(t, err) + _, err = m.TenantAppendable("foo") + testutil.Ok(t, err) + + testMulitTSDBSeries(t, m) + }) +} + +var ( + expectedFooResp = []storepb.Series{ + { + Labels: []storepb.Label{{Name: "a", Value: "1"}, {Name: "b", Value: "2"}, {Name: "replica", Value: "01"}, {Name: "tenant_id", Value: "foo"}}, + Chunks: []storepb.AggrChunk{{MinTime: 1, MaxTime: 3, Raw: &storepb.Chunk{Data: []byte("\000\003\002@\003L\235\2354X\315\001\330\r\257Mui\251\327:U")}}}, + }, + } + expectedBarResp = []storepb.Series{ + { + Labels: []storepb.Label{{Name: "a", Value: "1"}, {Name: "b", Value: "2"}, {Name: "replica", Value: "01"}, {Name: "tenant_id", Value: "bar"}}, + Chunks: []storepb.AggrChunk{{MinTime: 1, MaxTime: 3, Raw: &storepb.Chunk{Data: []byte("\000\003\002@4i\223\263\246\213\032\001\330\035i\337\322\352\323S\256t\270")}}}, + }, + } +) + +func testMulitTSDBSeries(t *testing.T, m *MultiTSDB) { + g := &errgroup.Group{} + respFoo := make(chan []storepb.Series) + respBar := make(chan []storepb.Series) + for i := 0; i < 100; i++ { + s := m.TSDBStores() + testutil.Assert(t, len(s) == 2) + + g.Go(func() error { + srv := newStoreSeriesServer(context.Background()) + if err := s["foo"].Series(&storepb.SeriesRequest{ + MinTime: 0, + MaxTime: 10, + Matchers: []storepb.LabelMatcher{{Name: "a", Value: ".*", Type: storepb.LabelMatcher_RE}}, + }, srv); err != nil { + return err + } + respFoo <- srv.SeriesSet + return nil + }) + g.Go(func() error { + srv := newStoreSeriesServer(context.Background()) + if err := s["bar"].Series(&storepb.SeriesRequest{ + MinTime: 0, + MaxTime: 10, + Matchers: []storepb.LabelMatcher{{Name: "a", Value: ".*", Type: storepb.LabelMatcher_RE}}, + }, srv); err != nil { + return err + } + respBar <- srv.SeriesSet + return nil + }) + } + var err error + go func() { + err = g.Wait() + close(respFoo) + close(respBar) + }() +Outer: + for { + select { + case r, ok := <-respFoo: + if !ok { + break Outer + } + fmt.Println(r[0].String()) + testutil.Equals(t, expectedFooResp, r) + case r, ok := <-respBar: + if !ok { + break Outer + } + fmt.Println(r[0].String()) + testutil.Equals(t, expectedBarResp, r) + } + } + testutil.Ok(t, err) +} + +// storeSeriesServer is test gRPC storeAPI series server. +// TODO(bwplotka): Make this part of some common library. We copy and paste this also in pkg/store. +type storeSeriesServer struct { + // This field just exist to pseudo-implement the unused methods of the interface. + storepb.Store_SeriesServer + + ctx context.Context + + SeriesSet []storepb.Series + Warnings []string + HintsSet []*types.Any + + Size int64 +} + +func newStoreSeriesServer(ctx context.Context) *storeSeriesServer { + return &storeSeriesServer{ctx: ctx} +} + +func (s *storeSeriesServer) Send(r *storepb.SeriesResponse) error { + s.Size += int64(r.Size()) + + if r.GetWarning() != "" { + s.Warnings = append(s.Warnings, r.GetWarning()) + return nil + } + + if r.GetSeries() != nil { + s.SeriesSet = append(s.SeriesSet, *r.GetSeries()) + return nil + } + + if r.GetHints() != nil { + s.HintsSet = append(s.HintsSet, r.GetHints()) + return nil + } + + // Unsupported field, skip. + return nil +} + +func (s *storeSeriesServer) Context() context.Context { + return s.ctx +} diff --git a/pkg/receive/tsdb_test.go b/pkg/receive/tsdb_test.go index 5a527bef0f..ec5c7fd37f 100644 --- a/pkg/receive/tsdb_test.go +++ b/pkg/receive/tsdb_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/fortytw2/leaktest" "github.com/go-kit/kit/log" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/model" @@ -19,6 +20,8 @@ import ( ) func TestFlushableStorage(t *testing.T) { + defer leaktest.CheckTimeout(t, 10*time.Second) + { // Ensure that flushing storage does not cause data loss. // This test: diff --git a/pkg/receive/writer.go b/pkg/receive/writer.go index aeccbfbfbe..820ed91c79 100644 --- a/pkg/receive/writer.go +++ b/pkg/receive/writer.go @@ -9,11 +9,12 @@ import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "github.com/pkg/errors" - "github.com/prometheus/prometheus/prompb" - "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/storage" + "github.com/prometheus/prometheus/storage/tsdb" terrors "github.com/prometheus/prometheus/tsdb/errors" + + "github.com/thanos-io/thanos/pkg/store/storepb/prompb" ) // Appendable returns an Appender. @@ -21,26 +22,38 @@ type Appendable interface { Appender() (storage.Appender, error) } +type TenantStorage interface { + TenantAppendable(string) (Appendable, error) +} + type Writer struct { - logger log.Logger - append Appendable + logger log.Logger + multiTSDB TenantStorage } -func NewWriter(logger log.Logger, app Appendable) *Writer { +func NewWriter(logger log.Logger, multiTSDB TenantStorage) *Writer { return &Writer{ - logger: logger, - append: app, + logger: logger, + multiTSDB: multiTSDB, } } -func (r *Writer) Write(wreq *prompb.WriteRequest) error { +func (r *Writer) Write(tenantID string, wreq *prompb.WriteRequest) error { var ( numOutOfOrder = 0 numDuplicates = 0 numOutOfBounds = 0 ) - app, err := r.append.Appender() + s, err := r.multiTSDB.TenantAppendable(tenantID) + if err != nil { + return errors.Wrap(err, "get tenant appendable") + } + + app, err := s.Appender() + if err == tsdb.ErrNotReady { + return err + } if err != nil { return errors.Wrap(err, "get appender") } @@ -94,6 +107,18 @@ func (r *Writer) Write(wreq *prompb.WriteRequest) error { return errs.Err() } +type fakeTenantAppendable struct { + f *fakeAppendable +} + +func newFakeTenantAppendable(f *fakeAppendable) *fakeTenantAppendable { + return &fakeTenantAppendable{f: f} +} + +func (t *fakeTenantAppendable) TenantAppendable(tenantID string) (Appendable, error) { + return t.f, nil +} + type fakeAppendable struct { appender storage.Appender appenderErr func() error diff --git a/pkg/reloader/example_test.go b/pkg/reloader/example_test.go index 5f67a5caf3..dc1ec3ee65 100644 --- a/pkg/reloader/example_test.go +++ b/pkg/reloader/example_test.go @@ -20,6 +20,7 @@ func ExampleReloader() { log.Fatal(err) } rl := reloader.New( + nil, nil, reloader.ReloadURLFromBase(u), "/path/to/cfg", diff --git a/pkg/reloader/reloader.go b/pkg/reloader/reloader.go index 508c14280f..02de1771f3 100644 --- a/pkg/reloader/reloader.go +++ b/pkg/reloader/reloader.go @@ -72,6 +72,8 @@ import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/thanos-io/thanos/pkg/runutil" ) @@ -89,6 +91,12 @@ type Reloader struct { lastCfgHash []byte lastRuleHash []byte + + reloads prometheus.Counter + reloadErrors prometheus.Counter + watches prometheus.Gauge + watchEvents prometheus.Counter + watchErrors prometheus.Counter } var firstGzipBytes = []byte{0x1f, 0x8b, 0x08} @@ -98,11 +106,11 @@ var firstGzipBytes = []byte{0x1f, 0x8b, 0x08} // If cfgOutputFile is not empty the config file will be decompressed if needed, environment variables // will be substituted and the output written into the given path. Prometheus should then use // cfgOutputFile as its config file path. -func New(logger log.Logger, reloadURL *url.URL, cfgFile string, cfgOutputFile string, ruleDirs []string) *Reloader { +func New(logger log.Logger, reg prometheus.Registerer, reloadURL *url.URL, cfgFile string, cfgOutputFile string, ruleDirs []string) *Reloader { if logger == nil { logger = log.NewNopLogger() } - return &Reloader{ + r := &Reloader{ logger: logger, reloadURL: reloadURL, cfgFile: cfgFile, @@ -110,7 +118,39 @@ func New(logger log.Logger, reloadURL *url.URL, cfgFile string, cfgOutputFile st ruleDirs: ruleDirs, watchInterval: 3 * time.Minute, retryInterval: 5 * time.Second, + + reloads: promauto.With(reg).NewCounter( + prometheus.CounterOpts{ + Name: "reloader_reloads_total", + Help: "Total number of reload requests.", + }, + ), + reloadErrors: promauto.With(reg).NewCounter( + prometheus.CounterOpts{ + Name: "reloader_reloads_failed_total", + Help: "Total number of reload requests that failed.", + }, + ), + watches: promauto.With(reg).NewGauge( + prometheus.GaugeOpts{ + Name: "reloader_watches", + Help: "Number of resources watched by the reloader.", + }, + ), + watchEvents: promauto.With(reg).NewCounter( + prometheus.CounterOpts{ + Name: "reloader_watch_events_total", + Help: "Total number of events received by the reloader from the watcher.", + }, + ), + watchErrors: promauto.With(reg).NewCounter( + prometheus.CounterOpts{ + Name: "reloader_watch_errors_total", + Help: "Total number of errors received by the reloader from the watcher.", + }, + ), } + return r } // We cannot detect everything via watch. Watch interval controls how often we re-read given dirs non-recursively. @@ -154,6 +194,7 @@ func (r *Reloader) Watch(ctx context.Context) error { tick := time.NewTicker(r.watchInterval) defer tick.Stop() + r.watches.Set(float64(len(watchables))) level.Info(r.logger).Log( "msg", "started watching config file and non-recursively rule dirs for changes", "cfg", r.cfgFile, @@ -166,11 +207,12 @@ func (r *Reloader) Watch(ctx context.Context) error { return nil case <-tick.C: case event := <-watcher.Events: - // TODO(bwplotka): Add metric if we are not cycling CPU here too much. + r.watchEvents.Inc() if _, ok := watchables[filepath.Dir(event.Name)]; !ok { continue } case err := <-watcher.Errors: + r.watchErrors.Inc() level.Error(r.logger).Log("msg", "watch error", "err", err) continue } @@ -280,7 +322,9 @@ func (r *Reloader) apply(ctx context.Context) error { defer cancel() if err := runutil.RetryWithLog(r.logger, r.retryInterval, retryCtx.Done(), func() error { + r.reloads.Inc() if err := r.triggerReload(ctx); err != nil { + r.reloadErrors.Inc() return errors.Wrap(err, "trigger reload") } diff --git a/pkg/reloader/reloader_test.go b/pkg/reloader/reloader_test.go index 3784635349..f9f93bee4c 100644 --- a/pkg/reloader/reloader_test.go +++ b/pkg/reloader/reloader_test.go @@ -62,7 +62,7 @@ func TestReloader_ConfigApply(t *testing.T) { input = path.Join(dir, "in", "cfg.yaml.tmpl") output = path.Join(dir, "out", "cfg.yaml") ) - reloader := New(nil, reloadURL, input, output, nil) + reloader := New(nil, nil, reloadURL, input, output, nil) reloader.watchInterval = 9999 * time.Hour // Disable interval to test watch logic only. reloader.retryInterval = 100 * time.Millisecond @@ -205,7 +205,7 @@ func TestReloader_RuleApply(t *testing.T) { testutil.Ok(t, os.Mkdir(path.Join(dir2, "rule-dir"), os.ModePerm)) testutil.Ok(t, os.Symlink(path.Join(dir2, "rule-dir"), path.Join(dir, "rule-dir"))) - reloader := New(nil, reloadURL, "", "", []string{dir, path.Join(dir, "rule-dir")}) + reloader := New(nil, nil, reloadURL, "", "", []string{dir, path.Join(dir, "rule-dir")}) reloader.watchInterval = 100 * time.Millisecond reloader.retryInterval = 100 * time.Millisecond diff --git a/pkg/replicate/replicater.go b/pkg/replicate/replicator.go similarity index 88% rename from pkg/replicate/replicater.go rename to pkg/replicate/replicator.go index 2a505d4f94..82455be46d 100644 --- a/pkg/replicate/replicater.go +++ b/pkg/replicate/replicator.go @@ -5,7 +5,6 @@ package replicate import ( "context" - "fmt" "math/rand" "strconv" "strings" @@ -18,11 +17,14 @@ import ( opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/pkg/labels" + thanosblock "github.com/thanos-io/thanos/pkg/block" "github.com/thanos-io/thanos/pkg/compact" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/extflag" + "github.com/thanos-io/thanos/pkg/extprom" "github.com/thanos-io/thanos/pkg/objstore/client" "github.com/thanos-io/thanos/pkg/prober" "github.com/thanos-io/thanos/pkg/runutil" @@ -80,7 +82,7 @@ func RunReplicate( httpProbe := prober.NewHTTP() statusProber := prober.Combine( httpProbe, - prober.NewInstrumentation(component.Replicate, logger, prometheus.WrapRegistererWithPrefix("thanos_", reg)), + prober.NewInstrumentation(component.Replicate, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)), ) s := http.New(logger, reg, component.Replicate, httpProbe, @@ -139,18 +141,20 @@ func RunReplicate( return err } - replicationRunCounter := prometheus.NewCounterVec(prometheus.CounterOpts{ + replicationRunCounter := promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_replicate_replication_runs_total", Help: "The number of replication runs split by success and error.", }, []string{"result"}) - replicationRunDuration := prometheus.NewHistogramVec(prometheus.HistogramOpts{ + replicationRunDuration := promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{ Name: "thanos_replicate_replication_run_duration_seconds", Help: "The Duration of replication runs split by success and error.", }, []string{"result"}) - reg.MustRegister(replicationRunCounter) - reg.MustRegister(replicationRunDuration) + fetcher, err := thanosblock.NewMetaFetcher(logger, 32, fromBkt, "", reg, nil, nil) + if err != nil { + return errors.Wrapf(err, "create meta fetcher with bucket %v", fromBkt) + } blockFilter := NewBlockFilter( logger, @@ -173,8 +177,8 @@ func RunReplicate( logger := log.With(logger, "replication-run-id", ulid.String()) level.Info(logger).Log("msg", "running replication attempt") - if err := newReplicationScheme(logger, metrics, blockFilter, fromBkt, toBkt, reg).execute(ctx); err != nil { - return fmt.Errorf("replication execute: %w", err) + if err := newReplicationScheme(logger, metrics, blockFilter, fetcher, fromBkt, toBkt, reg).execute(ctx); err != nil { + return errors.Wrap(err, "replication execute") } return nil diff --git a/pkg/replicate/scheme.go b/pkg/replicate/scheme.go index 30be01f0f2..5402dd9a78 100644 --- a/pkg/replicate/scheme.go +++ b/pkg/replicate/scheme.go @@ -6,7 +6,6 @@ package replicate import ( "bytes" "context" - "fmt" "io" "io/ioutil" "path" @@ -17,6 +16,7 @@ import ( "github.com/oklog/ulid" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/pkg/labels" thanosblock "github.com/thanos-io/thanos/pkg/block" "github.com/thanos-io/thanos/pkg/block/metadata" @@ -101,10 +101,11 @@ type blockFilterFunc func(b *metadata.Meta) bool // TODO: Add filters field. type replicationScheme struct { - fromBkt objstore.BucketReader + fromBkt objstore.InstrumentedBucketReader toBkt objstore.Bucket blockFilter blockFilterFunc + fetcher thanosblock.MetadataFetcher logger log.Logger metrics *replicationMetrics @@ -124,45 +125,43 @@ type replicationMetrics struct { func newReplicationMetrics(reg prometheus.Registerer) *replicationMetrics { m := &replicationMetrics{ - originIterations: prometheus.NewCounter(prometheus.CounterOpts{ + originIterations: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_replicate_origin_iterations_total", Help: "Total number of objects iterated over in the origin bucket.", }), - originMetaLoads: prometheus.NewCounter(prometheus.CounterOpts{ + originMetaLoads: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_replicate_origin_meta_loads_total", Help: "Total number of meta.json reads in the origin bucket.", }), - originPartialMeta: prometheus.NewCounter(prometheus.CounterOpts{ + originPartialMeta: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_replicate_origin_partial_meta_reads_total", Help: "Total number of partial meta reads encountered.", }), - blocksAlreadyReplicated: prometheus.NewCounter(prometheus.CounterOpts{ + blocksAlreadyReplicated: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_replicate_blocks_already_replicated_total", Help: "Total number of blocks skipped due to already being replicated.", }), - blocksReplicated: prometheus.NewCounter(prometheus.CounterOpts{ + blocksReplicated: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_replicate_blocks_replicated_total", Help: "Total number of blocks replicated.", }), - objectsReplicated: prometheus.NewCounter(prometheus.CounterOpts{ + objectsReplicated: promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_replicate_objects_replicated_total", Help: "Total number of objects replicated.", }), } - - if reg != nil { - reg.MustRegister(m.originIterations) - reg.MustRegister(m.originMetaLoads) - reg.MustRegister(m.originPartialMeta) - reg.MustRegister(m.blocksAlreadyReplicated) - reg.MustRegister(m.blocksReplicated) - reg.MustRegister(m.objectsReplicated) - } - return m } -func newReplicationScheme(logger log.Logger, metrics *replicationMetrics, blockFilter blockFilterFunc, from objstore.BucketReader, to objstore.Bucket, reg prometheus.Registerer) *replicationScheme { +func newReplicationScheme( + logger log.Logger, + metrics *replicationMetrics, + blockFilter blockFilterFunc, + fetcher thanosblock.MetadataFetcher, + from objstore.InstrumentedBucketReader, + to objstore.Bucket, + reg prometheus.Registerer, +) *replicationScheme { if logger == nil { logger = log.NewNopLogger() } @@ -170,6 +169,7 @@ func newReplicationScheme(logger log.Logger, metrics *replicationMetrics, blockF return &replicationScheme{ logger: logger, blockFilter: blockFilter, + fetcher: fetcher, fromBkt: from, toBkt: to, metrics: metrics, @@ -202,7 +202,7 @@ func (rs *replicationScheme) execute(ctx context.Context) error { return nil } if err != nil { - return fmt.Errorf("load meta for block %v from origin bucket: %w", id.String(), err) + return errors.Wrapf(err, "load meta for block %v from origin bucket", id.String()) } if len(meta.Thanos.Labels) == 0 { @@ -217,7 +217,7 @@ func (rs *replicationScheme) execute(ctx context.Context) error { return nil }); err != nil { - return fmt.Errorf("iterate over origin bucket: %w", err) + return errors.Wrap(err, "iterate over origin bucket") } candidateBlocks := []*metadata.Meta{} @@ -237,7 +237,7 @@ func (rs *replicationScheme) execute(ctx context.Context) error { for _, b := range candidateBlocks { if err := rs.ensureBlockIsReplicated(ctx, b.BlockMeta.ULID); err != nil { - return fmt.Errorf("ensure block %v is replicated: %w", b.BlockMeta.ULID.String(), err) + return errors.Wrapf(err, "ensure block %v is replicated", b.BlockMeta.ULID.String()) } } @@ -254,9 +254,9 @@ func (rs *replicationScheme) ensureBlockIsReplicated(ctx context.Context, id uli level.Debug(rs.logger).Log("msg", "ensuring block is replicated", "block_uuid", blockID) - originMetaFile, err := rs.fromBkt.Get(ctx, metaFile) + originMetaFile, err := rs.fromBkt.ReaderWithExpectedErrs(rs.fromBkt.IsObjNotFoundErr).Get(ctx, metaFile) if err != nil { - return fmt.Errorf("get meta file from origin bucket: %w", err) + return errors.Wrap(err, "get meta file from origin bucket") } defer runutil.CloseWithLogOnErr(rs.logger, originMetaFile, "close original meta file") @@ -268,18 +268,18 @@ func (rs *replicationScheme) ensureBlockIsReplicated(ctx context.Context, id uli } if err != nil && !rs.toBkt.IsObjNotFoundErr(err) && err != io.EOF { - return fmt.Errorf("get meta file from target bucket: %w", err) + return errors.Wrap(err, "get meta file from target bucket") } originMetaFileContent, err := ioutil.ReadAll(originMetaFile) if err != nil { - return fmt.Errorf("read origin meta file: %w", err) + return errors.Wrap(err, "read origin meta file") } if targetMetaFile != nil && !rs.toBkt.IsObjNotFoundErr(err) { targetMetaFileContent, err := ioutil.ReadAll(targetMetaFile) if err != nil { - return fmt.Errorf("read target meta file: %w", err) + return errors.Wrap(err, "read target meta file") } if bytes.Equal(originMetaFileContent, targetMetaFileContent) { @@ -296,7 +296,7 @@ func (rs *replicationScheme) ensureBlockIsReplicated(ctx context.Context, id uli if err := rs.fromBkt.Iter(ctx, chunksDir, func(objectName string) error { err := rs.ensureObjectReplicated(ctx, objectName) if err != nil { - return fmt.Errorf("replicate object %v: %w", objectName, err) + return errors.Wrapf(err, "replicate object %v", objectName) } return nil @@ -305,13 +305,13 @@ func (rs *replicationScheme) ensureBlockIsReplicated(ctx context.Context, id uli } if err := rs.ensureObjectReplicated(ctx, indexFile); err != nil { - return fmt.Errorf("replicate index file: %w", err) + return errors.Wrap(err, "replicate index file") } level.Debug(rs.logger).Log("msg", "replicating meta file", "object", metaFile) if err := rs.toBkt.Upload(ctx, metaFile, bytes.NewReader(originMetaFileContent)); err != nil { - return fmt.Errorf("upload meta file: %w", err) + return errors.Wrap(err, "upload meta file") } rs.metrics.blocksReplicated.Inc() @@ -326,7 +326,7 @@ func (rs *replicationScheme) ensureObjectReplicated(ctx context.Context, objectN exists, err := rs.toBkt.Exists(ctx, objectName) if err != nil { - return fmt.Errorf("check if %v exists in target bucket: %w", objectName, err) + return errors.Wrapf(err, "check if %v exists in target bucket", objectName) } // skip if already exists. @@ -339,13 +339,13 @@ func (rs *replicationScheme) ensureObjectReplicated(ctx context.Context, objectN r, err := rs.fromBkt.Get(ctx, objectName) if err != nil { - return fmt.Errorf("get %v from origin bucket: %w", objectName, err) + return errors.Wrapf(err, "get %v from origin bucket", objectName) } defer r.Close() if err = rs.toBkt.Upload(ctx, objectName, r); err != nil { - return fmt.Errorf("upload %v to target bucket: %w", objectName, err) + return errors.Wrapf(err, "upload %v to target bucket", objectName) } level.Info(rs.logger).Log("msg", "object replicated", "object", objectName) @@ -360,24 +360,19 @@ func (rs *replicationScheme) ensureObjectReplicated(ctx context.Context, objectN // partial, this is just a temporary failure, as the block is still being // uploaded to the origin bucket. func loadMeta(ctx context.Context, rs *replicationScheme, id ulid.ULID) (*metadata.Meta, bool, error) { - fetcher, err := thanosblock.NewMetaFetcher(rs.logger, 32, rs.fromBkt, "", rs.reg) - if err != nil { - return nil, false, fmt.Errorf("create meta fetcher with buecket %v: %w", rs.fromBkt, err) - } - - metas, _, err := fetcher.Fetch(ctx) + metas, _, err := rs.fetcher.Fetch(ctx) if err != nil { switch errors.Cause(err) { default: - return nil, false, fmt.Errorf("fetch meta: %w", err) + return nil, false, errors.Wrap(err, "fetch meta") case thanosblock.ErrorSyncMetaNotFound: - return nil, true, fmt.Errorf("fetch meta: %w", err) + return nil, true, errors.Wrap(err, "fetch meta") } } m, ok := metas[id] if !ok { - return nil, true, fmt.Errorf("fetch meta: %w", err) + return nil, true, errors.Wrap(err, "fetch meta") } return m, false, nil diff --git a/pkg/replicate/scheme_test.go b/pkg/replicate/scheme_test.go index c8ca4e0598..fc9e66943d 100644 --- a/pkg/replicate/scheme_test.go +++ b/pkg/replicate/scheme_test.go @@ -19,10 +19,10 @@ import ( "github.com/oklog/ulid" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/tsdb" + "github.com/thanos-io/thanos/pkg/block" "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/compact" "github.com/thanos-io/thanos/pkg/objstore" - "github.com/thanos-io/thanos/pkg/objstore/inmem" "github.com/thanos-io/thanos/pkg/testutil" ) @@ -65,20 +65,20 @@ func TestReplicationSchemeAll(t *testing.T) { var cases = []struct { name string selector labels.Selector - prepare func(ctx context.Context, t *testing.T, originBucket, targetBucket objstore.Bucket) - assert func(ctx context.Context, t *testing.T, originBucket, targetBucket *inmem.Bucket) + prepare func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) + assert func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) }{ { name: "EmptyOrigin", - prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket objstore.Bucket) {}, - assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *inmem.Bucket) {}, + prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) {}, + assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) {}, }, { name: "NoMeta", - prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket objstore.Bucket) { + prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { _ = originBucket.Upload(ctx, path.Join(testULID(0).String(), "chunks", "000001"), bytes.NewReader(nil)) }, - assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *inmem.Bucket) { + assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { if len(targetBucket.Objects()) != 0 { t.Fatal("TargetBucket should have been empty but is not.") } @@ -86,10 +86,10 @@ func TestReplicationSchemeAll(t *testing.T) { }, { name: "PartialMeta", - prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket objstore.Bucket) { + prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { _ = originBucket.Upload(ctx, path.Join(testULID(0).String(), "meta.json"), bytes.NewReader([]byte("{"))) }, - assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *inmem.Bucket) { + assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { if len(targetBucket.Objects()) != 0 { t.Fatal("TargetBucket should have been empty but is not.") } @@ -97,7 +97,7 @@ func TestReplicationSchemeAll(t *testing.T) { }, { name: "FullBlock", - prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket objstore.Bucket) { + prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { ulid := testULID(0) meta := testMeta(ulid) @@ -107,7 +107,7 @@ func TestReplicationSchemeAll(t *testing.T) { _ = originBucket.Upload(ctx, path.Join(ulid.String(), "chunks", "000001"), bytes.NewReader(nil)) _ = originBucket.Upload(ctx, path.Join(ulid.String(), "index"), bytes.NewReader(nil)) }, - assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *inmem.Bucket) { + assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { if len(targetBucket.Objects()) != 3 { t.Fatal("TargetBucket should have one block made up of three objects replicated.") } @@ -115,7 +115,7 @@ func TestReplicationSchemeAll(t *testing.T) { }, { name: "PreviousPartialUpload", - prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket objstore.Bucket) { + prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { ulid := testULID(0) meta := testMeta(ulid) @@ -129,7 +129,7 @@ func TestReplicationSchemeAll(t *testing.T) { _ = targetBucket.Upload(ctx, path.Join(ulid.String(), "chunks", "000001"), bytes.NewReader(nil)) _ = targetBucket.Upload(ctx, path.Join(ulid.String(), "index"), bytes.NewReader(nil)) }, - assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *inmem.Bucket) { + assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { for k := range originBucket.Objects() { if !bytes.Equal(originBucket.Objects()[k], targetBucket.Objects()[k]) { t.Fatalf("Object %s not equal in origin and target bucket.", k) @@ -139,7 +139,7 @@ func TestReplicationSchemeAll(t *testing.T) { }, { name: "OnlyUploadsRaw", - prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket objstore.Bucket) { + prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { ulid := testULID(0) meta := testMeta(ulid) @@ -159,7 +159,7 @@ func TestReplicationSchemeAll(t *testing.T) { _ = originBucket.Upload(ctx, path.Join(ulid.String(), "chunks", "000001"), bytes.NewReader(nil)) _ = originBucket.Upload(ctx, path.Join(ulid.String(), "index"), bytes.NewReader(nil)) }, - assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *inmem.Bucket) { + assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { expected := 3 got := len(targetBucket.Objects()) if got != expected { @@ -169,7 +169,7 @@ func TestReplicationSchemeAll(t *testing.T) { }, { name: "UploadMultipleCandidatesWhenPresent", - prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket objstore.Bucket) { + prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { ulid := testULID(0) meta := testMeta(ulid) @@ -188,7 +188,7 @@ func TestReplicationSchemeAll(t *testing.T) { _ = originBucket.Upload(ctx, path.Join(ulid.String(), "chunks", "000001"), bytes.NewReader(nil)) _ = originBucket.Upload(ctx, path.Join(ulid.String(), "index"), bytes.NewReader(nil)) }, - assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *inmem.Bucket) { + assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { expected := 6 got := len(targetBucket.Objects()) if got != expected { @@ -198,7 +198,7 @@ func TestReplicationSchemeAll(t *testing.T) { }, { name: "LabelSelector", - prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket objstore.Bucket) { + prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { ulid := testULID(0) meta := testMeta(ulid) @@ -218,7 +218,7 @@ func TestReplicationSchemeAll(t *testing.T) { _ = originBucket.Upload(ctx, path.Join(ulid.String(), "chunks", "000001"), bytes.NewReader(nil)) _ = originBucket.Upload(ctx, path.Join(ulid.String(), "index"), bytes.NewReader(nil)) }, - assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *inmem.Bucket) { + assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { expected := 3 got := len(targetBucket.Objects()) if got != expected { @@ -228,7 +228,7 @@ func TestReplicationSchemeAll(t *testing.T) { }, { name: "NonZeroCompaction", - prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket objstore.Bucket) { + prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { ulid := testULID(0) meta := testMeta(ulid) meta.BlockMeta.Compaction.Level = 2 @@ -239,7 +239,7 @@ func TestReplicationSchemeAll(t *testing.T) { _ = originBucket.Upload(ctx, path.Join(ulid.String(), "chunks", "000001"), bytes.NewReader(nil)) _ = originBucket.Upload(ctx, path.Join(ulid.String(), "index"), bytes.NewReader(nil)) }, - assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *inmem.Bucket) { + assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { if len(targetBucket.Objects()) != 0 { t.Fatal("TargetBucket should have been empty but is not.") } @@ -248,7 +248,7 @@ func TestReplicationSchemeAll(t *testing.T) { { name: "Regression", selector: labels.Selector{}, - prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket objstore.Bucket) { + prepare: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { b := []byte(`{ "ulid": "01DQYXMK8G108CEBQ79Y84DYVY", "minTime": 1571911200000, @@ -281,7 +281,7 @@ func TestReplicationSchemeAll(t *testing.T) { _ = originBucket.Upload(ctx, path.Join("01DQYXMK8G108CEBQ79Y84DYVY", "chunks", "000001"), bytes.NewReader(nil)) _ = originBucket.Upload(ctx, path.Join("01DQYXMK8G108CEBQ79Y84DYVY", "index"), bytes.NewReader(nil)) }, - assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *inmem.Bucket) { + assert: func(ctx context.Context, t *testing.T, originBucket, targetBucket *objstore.InMemBucket) { if len(targetBucket.Objects()) != 3 { t.Fatal("TargetBucket should have one block does not.") } @@ -295,16 +295,14 @@ func TestReplicationSchemeAll(t *testing.T) { for _, c := range cases { ctx := context.Background() - originBucket := inmem.NewBucket() - targetBucket := inmem.NewBucket() + originBucket := objstore.NewInMemBucket() + targetBucket := objstore.NewInMemBucket() logger := testLogger(t.Name() + "/" + c.name) c.prepare(ctx, t, originBucket, targetBucket) matcher, err := labels.NewMatcher(labels.MatchEqual, "test-labelname", "test-labelvalue") - if err != nil { - t.Fatal("Failed to create a matcher.") - } + testutil.Ok(t, err) selector := labels.Selector{ matcher, @@ -314,12 +312,15 @@ func TestReplicationSchemeAll(t *testing.T) { } filter := NewBlockFilter(logger, selector, compact.ResolutionLevelRaw, 1).Filter + fetcher, err := block.NewMetaFetcher(logger, 32, objstore.WithNoopInstr(originBucket), "", nil, nil, nil) + testutil.Ok(t, err) r := newReplicationScheme( logger, newReplicationMetrics(nil), filter, - originBucket, + fetcher, + objstore.WithNoopInstr(originBucket), targetBucket, nil, ) diff --git a/pkg/rule/api/v1.go b/pkg/rule/api/v1.go index 2eaa1f2ec3..c915e5ee8b 100644 --- a/pkg/rule/api/v1.go +++ b/pkg/rule/api/v1.go @@ -4,12 +4,12 @@ package v1 import ( - "fmt" "net/http" "strconv" "time" "github.com/NYTimes/gziphandler" + "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/go-kit/kit/log" @@ -111,7 +111,7 @@ func (api *API) rules(*http.Request) (interface{}, []error, *qapi.ApiError) { LastEvaluation: rule.GetEvaluationTimestamp(), }}}) default: - err := fmt.Errorf("rule %q: unsupported type %T", r.Name(), rule) + err := errors.Errorf("rule %q: unsupported type %T", r.Name(), rule) return nil, nil, &qapi.ApiError{Typ: qapi.ErrorInternal, Err: err} } } diff --git a/pkg/rule/api/v1_test.go b/pkg/rule/api/v1_test.go index 759f052474..cf70f5f06f 100644 --- a/pkg/rule/api/v1_test.go +++ b/pkg/rule/api/v1_test.go @@ -98,7 +98,7 @@ func (m rulesRetrieverMock) RuleGroups() []thanosrule.Group { r = append(r, recordingRule) return []thanosrule.Group{ - thanosrule.Group{ + { Group: rules.NewGroup("grp", "/path/to/file", time.Second, r, false, opts), PartialResponseStrategy: storepb.PartialResponseStrategy_WARN, }, diff --git a/pkg/rule/rule.go b/pkg/rule/rule.go index 8491478c13..70c442d5d9 100644 --- a/pkg/rule/rule.go +++ b/pkg/rule/rule.go @@ -70,17 +70,17 @@ func (m *Manager) SetRuleManager(s storepb.PartialResponseStrategy, mgr *rules.M func (m *Manager) RuleGroups() []Group { m.mtx.RLock() defer m.mtx.RUnlock() - var res []Group + var groups []Group for s, r := range m.mgrs { for _, group := range r.RuleGroups() { - res = append(res, Group{ + groups = append(groups, Group{ Group: group, PartialResponseStrategy: s, originalFile: m.ruleFiles[group.File()], }) } } - return res + return groups } func (m *Manager) AlertingRules() []AlertingRule { @@ -216,6 +216,21 @@ func (m *Manager) Update(evalInterval time.Duration, files []string) error { continue } } + + // Removes the rules from a manager when a strategy has no more rule. + for s, mgr := range m.mgrs { + if _, ok := filesByStrategy[s]; ok { + continue + } + + if len(mgr.RuleGroups()) == 0 { + continue + } + + if err := mgr.Update(evalInterval, []string{}, nil); err != nil { + errs = append(errs, err) + } + } m.ruleFiles = ruleFiles m.mtx.Unlock() diff --git a/pkg/rule/rule_test.go b/pkg/rule/rule_test.go index d238db10d4..7c503efd6e 100644 --- a/pkg/rule/rule_test.go +++ b/pkg/rule/rule_test.go @@ -66,14 +66,17 @@ groups: Appendable: nopAppendable{}, } thanosRuleMgr := NewManager(dir) - ruleMgr := rules.NewManager(&opts) - thanosRuleMgr.SetRuleManager(storepb.PartialResponseStrategy_ABORT, ruleMgr) - thanosRuleMgr.SetRuleManager(storepb.PartialResponseStrategy_WARN, ruleMgr) + ruleMgrAbort := rules.NewManager(&opts) + ruleMgrWarn := rules.NewManager(&opts) + thanosRuleMgr.SetRuleManager(storepb.PartialResponseStrategy_ABORT, ruleMgrAbort) + thanosRuleMgr.SetRuleManager(storepb.PartialResponseStrategy_WARN, ruleMgrWarn) - testutil.Ok(t, thanosRuleMgr.Update(10*time.Second, []string{filepath.Join(dir, "rule.yaml")})) + ruleMgrAbort.Run() + ruleMgrWarn.Run() + defer ruleMgrAbort.Stop() + defer ruleMgrWarn.Stop() - ruleMgr.Run() - defer ruleMgr.Stop() + testutil.Ok(t, thanosRuleMgr.Update(10*time.Second, []string{filepath.Join(dir, "rule.yaml")})) select { case <-time.After(2 * time.Minute): @@ -225,6 +228,44 @@ groups: } } +func TestUpdateAfterClear(t *testing.T) { + dir, err := ioutil.TempDir("", "test_rule_rule_groups") + testutil.Ok(t, err) + defer func() { testutil.Ok(t, os.RemoveAll(dir)) }() + + testutil.Ok(t, ioutil.WriteFile(filepath.Join(dir, "no_strategy.yaml"), []byte(` +groups: +- name: "something1" + rules: + - alert: "some" + expr: "up" +`), os.ModePerm)) + + opts := rules.ManagerOptions{ + Logger: log.NewLogfmtLogger(os.Stderr), + } + m := NewManager(dir) + ruleMgrAbort := rules.NewManager(&opts) + ruleMgrWarn := rules.NewManager(&opts) + m.SetRuleManager(storepb.PartialResponseStrategy_ABORT, ruleMgrAbort) + m.SetRuleManager(storepb.PartialResponseStrategy_WARN, ruleMgrWarn) + + ruleMgrAbort.Run() + ruleMgrWarn.Run() + defer ruleMgrAbort.Stop() + defer ruleMgrWarn.Stop() + + err = m.Update(1*time.Second, []string{ + filepath.Join(dir, "no_strategy.yaml"), + }) + testutil.Ok(t, err) + testutil.Equals(t, 1, len(m.RuleGroups())) + + err = m.Update(1*time.Second, []string{}) + testutil.Ok(t, err) + testutil.Equals(t, 0, len(m.RuleGroups())) +} + func TestRuleGroupMarshalYAML(t *testing.T) { const expected = `groups: - name: something1 diff --git a/pkg/server/grpc/grpc.go b/pkg/server/grpc/grpc.go index bc7fd6c176..b492f83476 100644 --- a/pkg/server/grpc/grpc.go +++ b/pkg/server/grpc/grpc.go @@ -17,6 +17,7 @@ import ( "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/prober" "github.com/thanos-io/thanos/pkg/store/storepb" @@ -43,7 +44,9 @@ type Server struct { // If rulesSrv is not nil, it also registers Rules API to the returned server. func New(logger log.Logger, reg prometheus.Registerer, tracer opentracing.Tracer, comp component.Component, probe *prober.GRPCProbe, storeSrv storepb.StoreServer, rulesSrv storepb.RulesServer, opts ...Option) *Server { logger = log.With(logger, "service", "gRPC/server", "component", comp.String()) - options := options{} + options := options{ + network: "tcp", + } for _, o := range opts { o.apply(&options) } @@ -52,11 +55,10 @@ func New(logger log.Logger, reg prometheus.Registerer, tracer opentracing.Tracer met.EnableHandlingTimeHistogram( grpc_prometheus.WithHistogramBuckets([]float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120}), ) - panicsTotal := prometheus.NewCounter(prometheus.CounterOpts{ + panicsTotal := promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_grpc_req_panics_recovered_total", Help: "Total number of gRPC requests recovered from internal panic.", }) - reg.MustRegister(met, panicsTotal) grpcPanicRecoveryHandler := func(p interface{}) (err error) { panicsTotal.Inc() @@ -93,6 +95,7 @@ func New(logger log.Logger, reg prometheus.Registerer, tracer opentracing.Tracer } met.InitializeMetrics(s) + reg.MustRegister(met) grpc_health.RegisterHealthServer(s, probe.HealthServer()) @@ -106,13 +109,13 @@ func New(logger log.Logger, reg prometheus.Registerer, tracer opentracing.Tracer // ListenAndServe listens on the TCP network address and handles requests on incoming connections. func (s *Server) ListenAndServe() error { - l, err := net.Listen("tcp", s.opts.listen) + l, err := net.Listen(s.opts.network, s.opts.listen) if err != nil { return errors.Wrapf(err, "listen gRPC on address %s", s.opts.listen) } s.listener = l - level.Info(s.logger).Log("msg", "listening for StoreAPI gRPC", "address", s.opts.listen) + level.Info(s.logger).Log("msg", "listening for serving gRPC", "address", s.opts.listen) return errors.Wrap(s.srv.Serve(s.listener), "serve gRPC") } diff --git a/pkg/server/grpc/option.go b/pkg/server/grpc/option.go index 6df898ae16..82785f003e 100644 --- a/pkg/server/grpc/option.go +++ b/pkg/server/grpc/option.go @@ -8,9 +8,12 @@ import ( "time" ) +const UnixSocket = "/tmp/test.sock" + type options struct { gracePeriod time.Duration listen string + network string tlsConfig *tls.Config } @@ -42,6 +45,13 @@ func WithListen(s string) Option { }) } +// WithNetwork sets network to listen for gRPC server e.g tcp, udp or unix. +func WithNetwork(s string) Option { + return optionFunc(func(o *options) { + o.network = s + }) +} + // WithTLSConfig sets TLS configuration for gRPC server. func WithTLSConfig(cfg *tls.Config) Option { return optionFunc(func(o *options) { diff --git a/pkg/shipper/shipper.go b/pkg/shipper/shipper.go index 39e7d61d86..a865ac5c71 100644 --- a/pkg/shipper/shipper.go +++ b/pkg/shipper/shipper.go @@ -20,6 +20,7 @@ import ( "github.com/oklog/ulid" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/tsdb" "github.com/prometheus/prometheus/tsdb/fileutil" @@ -37,40 +38,33 @@ type metrics struct { uploadedCompacted prometheus.Gauge } -func newMetrics(r prometheus.Registerer, uploadCompacted bool) *metrics { +func newMetrics(reg prometheus.Registerer, uploadCompacted bool) *metrics { var m metrics - m.dirSyncs = prometheus.NewCounter(prometheus.CounterOpts{ + m.dirSyncs = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_shipper_dir_syncs_total", Help: "Total number of dir syncs", }) - m.dirSyncFailures = prometheus.NewCounter(prometheus.CounterOpts{ + m.dirSyncFailures = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_shipper_dir_sync_failures_total", Help: "Total number of failed dir syncs", }) - m.uploads = prometheus.NewCounter(prometheus.CounterOpts{ + m.uploads = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_shipper_uploads_total", Help: "Total number of uploaded blocks", }) - m.uploadFailures = prometheus.NewCounter(prometheus.CounterOpts{ + m.uploadFailures = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_shipper_upload_failures_total", Help: "Total number of block upload failures", }) - m.uploadedCompacted = prometheus.NewGauge(prometheus.GaugeOpts{ + uploadCompactedGaugeOpts := prometheus.GaugeOpts{ Name: "thanos_shipper_upload_compacted_done", Help: "If 1 it means shipper uploaded all compacted blocks from the filesystem.", - }) - - if r != nil { - r.MustRegister( - m.dirSyncs, - m.dirSyncFailures, - m.uploads, - m.uploadFailures, - ) - if uploadCompacted { - r.MustRegister(m.uploadedCompacted) - } + } + if uploadCompacted { + m.uploadedCompacted = promauto.With(reg).NewGauge(uploadCompactedGaugeOpts) + } else { + m.uploadedCompacted = promauto.With(nil).NewGauge(uploadCompactedGaugeOpts) } return &m } @@ -348,6 +342,7 @@ func (s *Shipper) Sync(ctx context.Context) (uploaded int, err error) { } // sync uploads the block if not exists in remote storage. +// TODO(khyatisoneji): Double check if block does not have deletion-mark.json for some reason, otherwise log it or return error. func (s *Shipper) upload(ctx context.Context, meta *metadata.Meta) error { level.Info(s.logger).Log("msg", "upload new block", "id", meta.ULID) diff --git a/pkg/shipper/shipper_e2e_test.go b/pkg/shipper/shipper_e2e_test.go index 19695426f2..b307b16532 100644 --- a/pkg/shipper/shipper_e2e_test.go +++ b/pkg/shipper/shipper_e2e_test.go @@ -15,7 +15,6 @@ import ( "testing" "time" - "github.com/thanos-io/thanos/pkg/objstore/inmem" "github.com/thanos-io/thanos/pkg/testutil/e2eutil" "github.com/go-kit/kit/log" @@ -180,7 +179,7 @@ func TestShipper_SyncBlocksWithMigrating_e2e(t *testing.T) { testutil.Ok(t, os.RemoveAll(dir)) }() - bkt := inmem.NewBucket() + bkt := objstore.NewInMemBucket() ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/pkg/store/bucket.go b/pkg/store/bucket.go index 2e7b96173f..640bb7138f 100644 --- a/pkg/store/bucket.go +++ b/pkg/store/bucket.go @@ -21,9 +21,11 @@ import ( "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" + "github.com/gogo/protobuf/types" "github.com/oklog/ulid" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/tsdb/chunkenc" "github.com/prometheus/prometheus/tsdb/chunks" @@ -43,6 +45,7 @@ import ( "github.com/thanos-io/thanos/pkg/promclient" "github.com/thanos-io/thanos/pkg/runutil" storecache "github.com/thanos-io/thanos/pkg/store/cache" + "github.com/thanos-io/thanos/pkg/store/hintspb" "github.com/thanos-io/thanos/pkg/store/storepb" "github.com/thanos-io/thanos/pkg/strutil" "github.com/thanos-io/thanos/pkg/tracing" @@ -59,10 +62,8 @@ const ( // because you barely get any improvements in compression when the number of samples is beyond this. // Take a look at Figure 6 in this whitepaper http://www.vldb.org/pvldb/vol8/p1816-teller.pdf. maxSamplesPerChunk = 120 - - maxChunkSize = 16000 - - maxSeriesSize = 64 * 1024 + maxChunkSize = 16000 + maxSeriesSize = 64 * 1024 // CompatibilityTypeLabelName is an artificial label that Store Gateway can optionally advertise. This is required for compatibility // with pre v0.8.0 Querier. Previous Queriers was strict about duplicated external labels of all StoreAPIs that had any labels. @@ -76,6 +77,11 @@ const ( // TODO(bwplotka): Remove it at some point. CompatibilityTypeLabelName = "@thanos_compatibility_store_type" + // DefaultPostingOffsetInMemorySampling represents default value for --store.index-header-posting-offsets-in-mem-sampling. + // 32 value is chosen as it's a good balance for common setups. Sampling that is not too large (too many CPU cycles) and + // not too small (too much memory). + DefaultPostingOffsetInMemorySampling = 32 + partitionerMaxGapSize = 512 * 1024 ) @@ -97,70 +103,76 @@ type bucketStoreMetrics struct { queriesDropped prometheus.Counter queriesLimit prometheus.Gauge seriesRefetches prometheus.Counter + + cachedPostingsCompressions *prometheus.CounterVec + cachedPostingsCompressionErrors *prometheus.CounterVec + cachedPostingsCompressionTimeSeconds *prometheus.CounterVec + cachedPostingsOriginalSizeBytes prometheus.Counter + cachedPostingsCompressedSizeBytes prometheus.Counter } func newBucketStoreMetrics(reg prometheus.Registerer) *bucketStoreMetrics { var m bucketStoreMetrics - m.blockLoads = prometheus.NewCounter(prometheus.CounterOpts{ + m.blockLoads = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_bucket_store_block_loads_total", Help: "Total number of remote block loading attempts.", }) - m.blockLoadFailures = prometheus.NewCounter(prometheus.CounterOpts{ + m.blockLoadFailures = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_bucket_store_block_load_failures_total", Help: "Total number of failed remote block loading attempts.", }) - m.blockDrops = prometheus.NewCounter(prometheus.CounterOpts{ + m.blockDrops = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_bucket_store_block_drops_total", Help: "Total number of local blocks that were dropped.", }) - m.blockDropFailures = prometheus.NewCounter(prometheus.CounterOpts{ + m.blockDropFailures = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_bucket_store_block_drop_failures_total", Help: "Total number of local blocks that failed to be dropped.", }) - m.blocksLoaded = prometheus.NewGauge(prometheus.GaugeOpts{ + m.blocksLoaded = promauto.With(reg).NewGauge(prometheus.GaugeOpts{ Name: "thanos_bucket_store_blocks_loaded", Help: "Number of currently loaded blocks.", }) - m.seriesDataTouched = prometheus.NewSummaryVec(prometheus.SummaryOpts{ + m.seriesDataTouched = promauto.With(reg).NewSummaryVec(prometheus.SummaryOpts{ Name: "thanos_bucket_store_series_data_touched", Help: "How many items of a data type in a block were touched for a single series request.", }, []string{"data_type"}) - m.seriesDataFetched = prometheus.NewSummaryVec(prometheus.SummaryOpts{ + m.seriesDataFetched = promauto.With(reg).NewSummaryVec(prometheus.SummaryOpts{ Name: "thanos_bucket_store_series_data_fetched", Help: "How many items of a data type in a block were fetched for a single series request.", }, []string{"data_type"}) - m.seriesDataSizeTouched = prometheus.NewSummaryVec(prometheus.SummaryOpts{ + m.seriesDataSizeTouched = promauto.With(reg).NewSummaryVec(prometheus.SummaryOpts{ Name: "thanos_bucket_store_series_data_size_touched_bytes", Help: "Size of all items of a data type in a block were touched for a single series request.", }, []string{"data_type"}) - m.seriesDataSizeFetched = prometheus.NewSummaryVec(prometheus.SummaryOpts{ + m.seriesDataSizeFetched = promauto.With(reg).NewSummaryVec(prometheus.SummaryOpts{ Name: "thanos_bucket_store_series_data_size_fetched_bytes", Help: "Size of all items of a data type in a block were fetched for a single series request.", }, []string{"data_type"}) - m.seriesBlocksQueried = prometheus.NewSummary(prometheus.SummaryOpts{ + m.seriesBlocksQueried = promauto.With(reg).NewSummary(prometheus.SummaryOpts{ Name: "thanos_bucket_store_series_blocks_queried", Help: "Number of blocks in a bucket store that were touched to satisfy a query.", }) - m.seriesGetAllDuration = prometheus.NewHistogram(prometheus.HistogramOpts{ + m.seriesGetAllDuration = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{ Name: "thanos_bucket_store_series_get_all_duration_seconds", Help: "Time it takes until all per-block prepares and preloads for a query are finished.", Buckets: []float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120}, }) - m.seriesMergeDuration = prometheus.NewHistogram(prometheus.HistogramOpts{ + m.seriesMergeDuration = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{ Name: "thanos_bucket_store_series_merge_duration_seconds", Help: "Time it takes to merge sub-results from all queried blocks into a single result.", Buckets: []float64{0.001, 0.01, 0.1, 0.3, 0.6, 1, 3, 6, 9, 20, 30, 60, 90, 120}, }) - m.resultSeriesCount = prometheus.NewSummary(prometheus.SummaryOpts{ + m.resultSeriesCount = promauto.With(reg).NewSummary(prometheus.SummaryOpts{ Name: "thanos_bucket_store_series_result_series", Help: "Number of series observed in the final result of a query.", }) - m.chunkSizeBytes = prometheus.NewHistogram(prometheus.HistogramOpts{ + m.chunkSizeBytes = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{ Name: "thanos_bucket_store_sent_chunk_size_bytes", Help: "Size in bytes of the chunks for the single series, which is adequate to the gRPC message size sent to querier.", Buckets: []float64{ @@ -168,40 +180,40 @@ func newBucketStoreMetrics(reg prometheus.Registerer) *bucketStoreMetrics { }, }) - m.queriesDropped = prometheus.NewCounter(prometheus.CounterOpts{ + m.queriesDropped = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_bucket_store_queries_dropped_total", Help: "Number of queries that were dropped due to the sample limit.", }) - m.queriesLimit = prometheus.NewGauge(prometheus.GaugeOpts{ + m.queriesLimit = promauto.With(reg).NewGauge(prometheus.GaugeOpts{ Name: "thanos_bucket_store_queries_concurrent_max", Help: "Number of maximum concurrent queries.", }) - m.seriesRefetches = prometheus.NewCounter(prometheus.CounterOpts{ + m.seriesRefetches = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_bucket_store_series_refetches_total", Help: fmt.Sprintf("Total number of cases where %v bytes was not enough was to fetch series from index, resulting in refetch.", maxSeriesSize), }) - if reg != nil { - reg.MustRegister( - m.blockLoads, - m.blockLoadFailures, - m.blockDrops, - m.blockDropFailures, - m.blocksLoaded, - m.seriesDataTouched, - m.seriesDataFetched, - m.seriesDataSizeTouched, - m.seriesDataSizeFetched, - m.seriesBlocksQueried, - m.seriesGetAllDuration, - m.seriesMergeDuration, - m.resultSeriesCount, - m.chunkSizeBytes, - m.queriesDropped, - m.queriesLimit, - m.seriesRefetches, - ) - } + m.cachedPostingsCompressions = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ + Name: "thanos_bucket_store_cached_postings_compressions_total", + Help: "Number of postings compressions before storing to index cache.", + }, []string{"op"}) + m.cachedPostingsCompressionErrors = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ + Name: "thanos_bucket_store_cached_postings_compression_errors_total", + Help: "Number of postings compression errors.", + }, []string{"op"}) + m.cachedPostingsCompressionTimeSeconds = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ + Name: "thanos_bucket_store_cached_postings_compression_time_seconds", + Help: "Time spent compressing postings before storing them into postings cache.", + }, []string{"op"}) + m.cachedPostingsOriginalSizeBytes = promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "thanos_bucket_store_cached_postings_original_size_bytes_total", + Help: "Original size of postings stored into cache.", + }) + m.cachedPostingsCompressedSizeBytes = promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "thanos_bucket_store_cached_postings_compressed_size_bytes_total", + Help: "Compressed size of postings stored into cache.", + }) + return &m } @@ -215,7 +227,7 @@ type FilterConfig struct { type BucketStore struct { logger log.Logger metrics *bucketStoreMetrics - bkt objstore.BucketReader + bkt objstore.InstrumentedBucketReader fetcher block.MetadataFetcher dir string indexCache storecache.IndexCache @@ -242,6 +254,15 @@ type BucketStore struct { advLabelSets []storepb.LabelSet enableCompatibilityLabel bool enableIndexHeader bool + + // Reencode postings using diff+varint+snappy when storing to cache. + // This makes them smaller, but takes extra CPU and memory. + // When used with in-memory cache, memory usage should decrease overall, thanks to postings being smaller. + enablePostingsCompression bool + postingOffsetsInMemSampling int + + // Enables hints in the Series() response. + enableSeriesHints bool } // NewBucketStore creates a new bucket backed store that implements the store API against @@ -249,7 +270,7 @@ type BucketStore struct { func NewBucketStore( logger log.Logger, reg prometheus.Registerer, - bucket objstore.BucketReader, + bkt objstore.InstrumentedBucketReader, fetcher block.MetadataFetcher, dir string, indexCache storecache.IndexCache, @@ -261,6 +282,9 @@ func NewBucketStore( filterConfig *FilterConfig, enableCompatibilityLabel bool, enableIndexHeader bool, + enablePostingsCompression bool, + postingOffsetsInMemSampling int, + enableSeriesHints bool, // TODO(pracucci) Thanos 0.12 and below doesn't gracefully handle new fields in SeriesResponse. Drop this flag and always enable hints once we can drop backward compatibility. ) (*BucketStore, error) { if logger == nil { logger = log.NewNopLogger() @@ -278,7 +302,7 @@ func NewBucketStore( metrics := newBucketStoreMetrics(reg) s := &BucketStore{ logger: logger, - bkt: bucket, + bkt: bkt, fetcher: fetcher, dir: dir, indexCache: indexCache, @@ -292,10 +316,13 @@ func NewBucketStore( maxConcurrent, extprom.WrapRegistererWithPrefix("thanos_bucket_store_series_", reg), ), - samplesLimiter: NewLimiter(maxSampleCount, metrics.queriesDropped), - partitioner: gapBasedPartitioner{maxGapSize: partitionerMaxGapSize}, - enableCompatibilityLabel: enableCompatibilityLabel, - enableIndexHeader: enableIndexHeader, + samplesLimiter: NewLimiter(maxSampleCount, metrics.queriesDropped), + partitioner: gapBasedPartitioner{maxGapSize: partitionerMaxGapSize}, + enableCompatibilityLabel: enableCompatibilityLabel, + enableIndexHeader: enableIndexHeader, + enablePostingsCompression: enablePostingsCompression, + postingOffsetsInMemSampling: postingOffsetsInMemSampling, + enableSeriesHints: enableSeriesHints, } s.metrics = metrics @@ -450,7 +477,7 @@ func (s *BucketStore) addBlock(ctx context.Context, meta *metadata.Meta) (err er var indexHeaderReader indexheader.Reader if s.enableIndexHeader { - indexHeaderReader, err = indexheader.NewBinaryReader(ctx, s.logger, s.bkt, s.dir, meta.ULID) + indexHeaderReader, err = indexheader.NewBinaryReader(ctx, s.logger, s.bkt, s.dir, meta.ULID, s.postingOffsetsInMemSampling) if err != nil { return errors.Wrap(err, "create index header reader") } @@ -477,6 +504,7 @@ func (s *BucketStore) addBlock(ctx context.Context, meta *metadata.Meta) (err er indexHeaderReader, s.partitioner, s.metrics.seriesRefetches, + s.enablePostingsCompression, ) if err != nil { return errors.Wrap(err, "new bucket block") @@ -826,14 +854,13 @@ func debugFoundBlockSetOverview(logger log.Logger, mint, maxt, maxResolutionMill // Series implements the storepb.StoreServer interface. func (s *BucketStore) Series(req *storepb.SeriesRequest, srv storepb.Store_SeriesServer) (err error) { - { - span, _ := tracing.StartSpan(srv.Context(), "store_query_gate_ismyturn") - err := s.queryGate.IsMyTurn(srv.Context()) - span.Finish() - if err != nil { - return errors.Wrapf(err, "failed to wait for turn") - } + tracing.DoInSpan(srv.Context(), "store_query_gate_ismyturn", func(ctx context.Context) { + err = s.queryGate.IsMyTurn(srv.Context()) + }) + if err != nil { + return errors.Wrapf(err, "failed to wait for turn") } + defer s.queryGate.Done() matchers, err := promclient.TranslateMatchers(req.Matchers) @@ -844,10 +871,12 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, srv storepb.Store_Serie req.MaxTime = s.limitMaxTime(req.MaxTime) var ( - stats = &queryStats{} - res []storepb.SeriesSet - mtx sync.Mutex - g, ctx = errgroup.WithContext(srv.Context()) + ctx = srv.Context() + stats = &queryStats{} + res []storepb.SeriesSet + mtx sync.Mutex + g, gctx = errgroup.WithContext(ctx) + hints = &hintspb.SeriesResponseHints{} ) s.mtx.RLock() @@ -871,9 +900,14 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, srv storepb.Store_Serie for _, b := range blocks { b := b + if s.enableSeriesHints { + // Keep track of queried blocks. + hints.AddQueriedBlock(b.meta.ULID) + } + // We must keep the readers open until all their data has been sent. - indexr := b.indexReader(ctx) - chunkr := b.chunkReader(ctx) + indexr := b.indexReader(gctx) + chunkr := b.chunkReader(gctx) // Defer all closes to the end of Series method. defer runutil.CloseWithLogOnErr(s.logger, indexr, "series block") @@ -918,6 +952,14 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, srv storepb.Store_Serie s.metrics.seriesDataSizeTouched.WithLabelValues("chunks").Observe(float64(stats.chunksTouchedSizeSum)) s.metrics.seriesDataSizeFetched.WithLabelValues("chunks").Observe(float64(stats.chunksFetchedSizeSum)) s.metrics.resultSeriesCount.Observe(float64(stats.mergedSeriesCount)) + s.metrics.cachedPostingsCompressions.WithLabelValues("encode").Add(float64(stats.cachedPostingsCompressions)) + s.metrics.cachedPostingsCompressions.WithLabelValues("decode").Add(float64(stats.cachedPostingsDecompressions)) + s.metrics.cachedPostingsCompressionErrors.WithLabelValues("encode").Add(float64(stats.cachedPostingsCompressionErrors)) + s.metrics.cachedPostingsCompressionErrors.WithLabelValues("decode").Add(float64(stats.cachedPostingsDecompressionErrors)) + s.metrics.cachedPostingsCompressionTimeSeconds.WithLabelValues("encode").Add(stats.cachedPostingsCompressionTimeSum.Seconds()) + s.metrics.cachedPostingsCompressionTimeSeconds.WithLabelValues("decode").Add(stats.cachedPostingsDecompressionTimeSum.Seconds()) + s.metrics.cachedPostingsOriginalSizeBytes.Add(float64(stats.cachedPostingsOriginalSizeSum)) + s.metrics.cachedPostingsCompressedSizeBytes.Add(float64(stats.cachedPostingsCompressedSizeSum)) level.Debug(s.logger).Log("msg", "stats query processed", "stats", fmt.Sprintf("%+v", stats), "err", err) @@ -925,11 +967,10 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, srv storepb.Store_Serie // Concurrently get data from all blocks. { - span, _ := tracing.StartSpan(srv.Context(), "bucket_store_preload_all") begin := time.Now() - err := g.Wait() - span.Finish() - + tracing.DoInSpan(ctx, "bucket_store_preload_all", func(_ context.Context) { + err = g.Wait() + }) if err != nil { return status.Error(codes.Aborted, err.Error()) } @@ -938,10 +979,7 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, srv storepb.Store_Serie s.metrics.seriesBlocksQueried.Observe(float64(stats.blocksQueried)) } // Merge the sub-results from each selected block. - { - span, _ := tracing.StartSpan(srv.Context(), "bucket_store_merge_all") - defer span.Finish() - + tracing.DoInSpan(ctx, "bucket_store_merge_all", func(ctx context.Context) { begin := time.Now() // Merge series set into an union of all block sets. This exposes all blocks are single seriesSet. @@ -962,17 +1000,36 @@ func (s *BucketStore) Series(req *storepb.SeriesRequest, srv storepb.Store_Serie s.metrics.chunkSizeBytes.Observe(float64(chunksSize(series.Chunks))) } - if err := srv.Send(storepb.NewSeriesResponse(&series)); err != nil { - return status.Error(codes.Unknown, errors.Wrap(err, "send series response").Error()) + if err = srv.Send(storepb.NewSeriesResponse(&series)); err != nil { + err = status.Error(codes.Unknown, errors.Wrap(err, "send series response").Error()) + return } } if set.Err() != nil { - return status.Error(codes.Unknown, errors.Wrap(set.Err(), "expand series set").Error()) + err = status.Error(codes.Unknown, errors.Wrap(set.Err(), "expand series set").Error()) + return } stats.mergeDuration = time.Since(begin) s.metrics.seriesMergeDuration.Observe(stats.mergeDuration.Seconds()) + + err = nil + }) + + if s.enableSeriesHints { + var anyHints *types.Any + + if anyHints, err = types.MarshalAny(hints); err != nil { + err = status.Error(codes.Unknown, errors.Wrap(err, "marshal series response hints").Error()) + return + } + + if err = srv.Send(storepb.NewHintsSeriesResponse(anyHints)); err != nil { + err = status.Error(codes.Unknown, errors.Wrap(err, "send series response hints").Error()) + return + } } - return nil + + return err } func chunksSize(chks []storepb.AggrChunk) (size int) { @@ -1205,6 +1262,8 @@ type bucketBlock struct { partitioner partitioner seriesRefetches prometheus.Counter + + enablePostingsCompression bool } func newBucketBlock( @@ -1218,17 +1277,19 @@ func newBucketBlock( indexHeadReader indexheader.Reader, p partitioner, seriesRefetches prometheus.Counter, + enablePostingsCompression bool, ) (b *bucketBlock, err error) { b = &bucketBlock{ - logger: logger, - bkt: bkt, - indexCache: indexCache, - chunkPool: chunkPool, - dir: dir, - partitioner: p, - meta: meta, - indexHeaderReader: indexHeadReader, - seriesRefetches: seriesRefetches, + logger: logger, + bkt: bkt, + indexCache: indexCache, + chunkPool: chunkPool, + dir: dir, + partitioner: p, + meta: meta, + indexHeaderReader: indexHeadReader, + seriesRefetches: seriesRefetches, + enablePostingsCompression: enablePostingsCompression, } // Get object handles for all chunk files. @@ -1332,7 +1393,12 @@ func newBucketIndexReader(ctx context.Context, block *bucketBlock) *bucketIndexR // chunk where the series contains the matching label-value pair for a given block of data. Postings can be fetched by // single label name=value. func (r *bucketIndexReader) ExpandedPostings(ms []*labels.Matcher) ([]uint64, error) { - var postingGroups []*postingGroup + var ( + postingGroups []*postingGroup + allRequested = false + hasAdds = false + keys []labels.Label + ) // NOTE: Derived from tsdb.PostingsForMatchers. for _, m := range ms { @@ -1342,23 +1408,71 @@ func (r *bucketIndexReader) ExpandedPostings(ms []*labels.Matcher) ([]uint64, er return nil, errors.Wrap(err, "toPostingGroup") } + // If this groups adds nothing, it's an empty group. We can shortcut this, since intersection with empty + // postings would return no postings anyway. + // E.g. label="non-existing-value" returns empty group. + if !pg.addAll && len(pg.addKeys) == 0 { + return nil, nil + } + postingGroups = append(postingGroups, pg) + allRequested = allRequested || pg.addAll + hasAdds = hasAdds || len(pg.addKeys) > 0 + + // Postings returned by fetchPostings will be in the same order as keys + // so it's important that we iterate them in the same order later. + // We don't have any other way of pairing keys and fetched postings. + keys = append(keys, pg.addKeys...) + keys = append(keys, pg.removeKeys...) } if len(postingGroups) == 0 { return nil, nil } - if err := r.fetchPostings(postingGroups); err != nil { + // We only need special All postings if there are no other adds. If there are, we can skip fetching + // special All postings completely. + if allRequested && !hasAdds { + // add group with label to fetch "special All postings". + name, value := index.AllPostingsKey() + allPostingsLabel := labels.Label{Name: name, Value: value} + + postingGroups = append(postingGroups, newPostingGroup(true, []labels.Label{allPostingsLabel}, nil)) + keys = append(keys, allPostingsLabel) + } + + fetchedPostings, err := r.fetchPostings(keys) + if err != nil { return nil, errors.Wrap(err, "get postings") } - var postings []index.Postings + // Get "add" and "remove" postings from groups. We iterate over postingGroups and their keys + // again, and this is exactly the same order as before (when building the groups), so we can simply + // use one incrementing index to fetch postings from returned slice. + postingIndex := 0 + + var groupAdds, groupRemovals []index.Postings for _, g := range postingGroups { - postings = append(postings, g.Postings()) + // We cannot add empty set to groupAdds, since they are intersected. + if len(g.addKeys) > 0 { + toMerge := make([]index.Postings, 0, len(g.addKeys)) + for _, l := range g.addKeys { + toMerge = append(toMerge, checkNilPosting(l, fetchedPostings[postingIndex])) + postingIndex++ + } + + groupAdds = append(groupAdds, index.Merge(toMerge...)) + } + + for _, l := range g.removeKeys { + groupRemovals = append(groupRemovals, checkNilPosting(l, fetchedPostings[postingIndex])) + postingIndex++ + } } - ps, err := index.ExpandPostings(index.Intersect(postings...)) + result := index.Without(index.Intersect(groupAdds...), index.Merge(groupRemovals...)) + + ps, err := index.ExpandPostings(result) if err != nil { return nil, errors.Wrap(err, "expand") } @@ -1374,82 +1488,65 @@ func (r *bucketIndexReader) ExpandedPostings(ms []*labels.Matcher) ([]uint64, er return ps, nil } +// postingGroup keeps posting keys for single matcher. Logical result of the group is: +// If addAll is set: special All postings minus postings for removeKeys labels. No need to merge postings for addKeys in this case. +// If addAll is not set: Merge of postings for "addKeys" labels minus postings for removeKeys labels +// This computation happens in ExpandedPostings. type postingGroup struct { - keys labels.Labels - postings []index.Postings - - aggregate func(postings []index.Postings) index.Postings + addAll bool + addKeys []labels.Label + removeKeys []labels.Label } -func newPostingGroup(keys labels.Labels, aggr func(postings []index.Postings) index.Postings) *postingGroup { +func newPostingGroup(addAll bool, addKeys, removeKeys []labels.Label) *postingGroup { return &postingGroup{ - keys: keys, - postings: make([]index.Postings, len(keys)), - aggregate: aggr, + addAll: addAll, + addKeys: addKeys, + removeKeys: removeKeys, } } -func (p *postingGroup) Fill(i int, posting index.Postings) { - p.postings[i] = posting -} - -func (p *postingGroup) Postings() index.Postings { - if len(p.keys) == 0 { - return index.EmptyPostings() - } - - for i, posting := range p.postings { - if posting == nil { - // This should not happen. Debug for https://github.com/thanos-io/thanos/issues/874. - return index.ErrPostings(errors.Errorf("at least one of %d postings is nil for %s. It was never fetched.", i, p.keys[i])) - } +func checkNilPosting(l labels.Label, p index.Postings) index.Postings { + if p == nil { + // This should not happen. Debug for https://github.com/thanos-io/thanos/issues/874. + return index.ErrPostings(errors.Errorf("postings is nil for %s. It was never fetched.", l)) } - - return p.aggregate(p.postings) -} - -func merge(p []index.Postings) index.Postings { - return index.Merge(p...) -} - -func allWithout(p []index.Postings) index.Postings { - return index.Without(p[0], index.Merge(p[1:]...)) + return p } // NOTE: Derived from tsdb.postingsForMatcher. index.Merge is equivalent to map duplication. func toPostingGroup(lvalsFn func(name string) ([]string, error), m *labels.Matcher) (*postingGroup, error) { - var matchingLabels labels.Labels + if m.Type == labels.MatchRegexp && len(findSetMatches(m.Value)) > 0 { + vals := findSetMatches(m.Value) + toAdd := make([]labels.Label, 0, len(vals)) + for _, val := range vals { + toAdd = append(toAdd, labels.Label{Name: m.Name, Value: val}) + } + return newPostingGroup(false, toAdd, nil), nil + } // If the matcher selects an empty value, it selects all the series which don't // have the label name set too. See: https://github.com/prometheus/prometheus/issues/3575 // and https://github.com/prometheus/prometheus/pull/3578#issuecomment-351653555. if m.Matches("") { - allName, allValue := index.AllPostingsKey() - - matchingLabels = append(matchingLabels, labels.Label{Name: allName, Value: allValue}) vals, err := lvalsFn(m.Name) if err != nil { return nil, err } + + var toRemove []labels.Label for _, val := range vals { if !m.Matches(val) { - matchingLabels = append(matchingLabels, labels.Label{Name: m.Name, Value: val}) + toRemove = append(toRemove, labels.Label{Name: m.Name, Value: val}) } } - if len(matchingLabels) == 1 { - // This is known hack to return all series. - // Ask for x != . Allow for that as Prometheus does, - // even though it is expensive. - return newPostingGroup(matchingLabels, merge), nil - } - - return newPostingGroup(matchingLabels, allWithout), nil + return newPostingGroup(true, nil, toRemove), nil } // Fast-path for equal matching. if m.Type == labels.MatchEqual { - return newPostingGroup(labels.Labels{{Name: m.Name, Value: m.Value}}, merge), nil + return newPostingGroup(false, []labels.Label{{Name: m.Name, Value: m.Value}}, nil), nil } vals, err := lvalsFn(m.Name) @@ -1457,67 +1554,81 @@ func toPostingGroup(lvalsFn func(name string) ([]string, error), m *labels.Match return nil, err } + var toAdd []labels.Label for _, val := range vals { if m.Matches(val) { - matchingLabels = append(matchingLabels, labels.Label{Name: m.Name, Value: val}) + toAdd = append(toAdd, labels.Label{Name: m.Name, Value: val}) } } - return newPostingGroup(matchingLabels, merge), nil + return newPostingGroup(false, toAdd, nil), nil } type postingPtr struct { - groupID int - keyID int - ptr index.Range + keyID int + ptr index.Range } // fetchPostings fill postings requested by posting groups. -func (r *bucketIndexReader) fetchPostings(groups []*postingGroup) error { +// It returns one postings for each key, in the same order. +// If postings for given key is not fetched, entry at given index will be nil. +func (r *bucketIndexReader) fetchPostings(keys []labels.Label) ([]index.Postings, error) { var ptrs []postingPtr - // Fetch postings from the cache with a single call. - keys := make([]labels.Label, 0) - for _, g := range groups { - keys = append(keys, g.keys...) - } + output := make([]index.Postings, len(keys)) + // Fetch postings from the cache with a single call. fromCache, _ := r.block.indexCache.FetchMultiPostings(r.ctx, r.block.meta.ULID, keys) // Iterate over all groups and fetch posting from cache. // If we have a miss, mark key to be fetched in `ptrs` slice. // Overlaps are well handled by partitioner, so we don't need to deduplicate keys. - for i, g := range groups { - for j, key := range g.keys { - // Get postings for the given key from cache first. - if b, ok := fromCache[key]; ok { - r.stats.postingsTouched++ - r.stats.postingsTouchedSizeSum += len(b) - - _, l, err := r.dec.Postings(b) + for ix, key := range keys { + // Get postings for the given key from cache first. + if b, ok := fromCache[key]; ok { + r.stats.postingsTouched++ + r.stats.postingsTouchedSizeSum += len(b) + + // Even if this instance is not using compression, there may be compressed + // entries in the cache written by other stores. + var ( + l index.Postings + err error + ) + if isDiffVarintSnappyEncodedPostings(b) { + s := time.Now() + l, err = diffVarintSnappyDecode(b) + r.stats.cachedPostingsDecompressions += 1 + r.stats.cachedPostingsDecompressionTimeSum += time.Since(s) if err != nil { - return errors.Wrap(err, "decode postings") + r.stats.cachedPostingsDecompressionErrors += 1 } - - g.Fill(j, l) - continue - } - - // Cache miss; save pointer for actual posting in index stored in object store. - ptr, err := r.block.indexHeaderReader.PostingsOffset(key.Name, key.Value) - if err == indexheader.NotFoundRangeErr { - // This block does not have any posting for given key. - g.Fill(j, index.EmptyPostings()) - continue + } else { + _, l, err = r.dec.Postings(b) } if err != nil { - return errors.Wrap(err, "index header PostingsOffset") + return nil, errors.Wrap(err, "decode postings") } - r.stats.postingsToFetch++ - ptrs = append(ptrs, postingPtr{ptr: ptr, groupID: i, keyID: j}) + output[ix] = l + continue + } + + // Cache miss; save pointer for actual posting in index stored in object store. + ptr, err := r.block.indexHeaderReader.PostingsOffset(key.Name, key.Value) + if err == indexheader.NotFoundRangeErr { + // This block does not have any posting for given key. + output[ix] = index.EmptyPostings() + continue + } + + if err != nil { + return nil, errors.Wrap(err, "index header PostingsOffset") } + + r.stats.postingsToFetch++ + ptrs = append(ptrs, postingPtr{ptr: ptr, keyID: ix}) } sort.Slice(ptrs, func(i, j int) bool { @@ -1562,22 +1673,50 @@ func (r *bucketIndexReader) fetchPostings(groups []*postingGroup) error { return err } + dataToCache := pBytes + + compressionTime := time.Duration(0) + compressions, compressionErrors, compressedSize := 0, 0, 0 + + if r.block.enablePostingsCompression { + // Reencode postings before storing to cache. If that fails, we store original bytes. + // This can only fail, if postings data was somehow corrupted, + // and there is nothing we can do about it. + // Errors from corrupted postings will be reported when postings are used. + compressions++ + s := time.Now() + data, err := diffVarintSnappyEncode(newBigEndianPostings(pBytes[4:])) + compressionTime = time.Since(s) + if err == nil { + dataToCache = data + compressedSize = len(data) + } else { + compressionErrors = 1 + } + } + r.mtx.Lock() // Return postings and fill LRU cache. // Truncate first 4 bytes which are length of posting. - groups[p.groupID].Fill(p.keyID, newBigEndianPostings(pBytes[4:])) - r.block.indexCache.StorePostings(r.ctx, r.block.meta.ULID, groups[p.groupID].keys[p.keyID], pBytes) + output[p.keyID] = newBigEndianPostings(pBytes[4:]) + + r.block.indexCache.StorePostings(r.ctx, r.block.meta.ULID, keys[p.keyID], dataToCache) // If we just fetched it we still have to update the stats for touched postings. r.stats.postingsTouched++ r.stats.postingsTouchedSizeSum += len(pBytes) + r.stats.cachedPostingsCompressions += compressions + r.stats.cachedPostingsCompressionErrors += compressionErrors + r.stats.cachedPostingsOriginalSizeSum += len(pBytes) + r.stats.cachedPostingsCompressedSizeSum += compressedSize + r.stats.cachedPostingsCompressionTimeSum += compressionTime r.mtx.Unlock() } return nil }) } - return g.Wait() + return output, g.Wait() } func resizePostings(b []byte) ([]byte, error) { @@ -1876,7 +2015,7 @@ func (r *bucketChunkReader) loadChunks(ctx context.Context, offs []uint32, seq i l, n := binary.Uvarint(cb) if n < 1 { - return errors.Errorf("reading chunk length failed") + return errors.New("reading chunk length failed") } if len(cb) < n+int(l)+1 { return errors.Errorf("preloaded chunk too small, expecting %d", n+int(l)+1) @@ -1944,6 +2083,15 @@ type queryStats struct { postingsFetchCount int postingsFetchDurationSum time.Duration + cachedPostingsCompressions int + cachedPostingsCompressionErrors int + cachedPostingsOriginalSizeSum int + cachedPostingsCompressedSizeSum int + cachedPostingsCompressionTimeSum time.Duration + cachedPostingsDecompressions int + cachedPostingsDecompressionErrors int + cachedPostingsDecompressionTimeSum time.Duration + seriesTouched int seriesTouchedSizeSum int seriesFetched int @@ -1974,6 +2122,15 @@ func (s queryStats) merge(o *queryStats) *queryStats { s.postingsFetchCount += o.postingsFetchCount s.postingsFetchDurationSum += o.postingsFetchDurationSum + s.cachedPostingsCompressions += o.cachedPostingsCompressions + s.cachedPostingsCompressionErrors += o.cachedPostingsCompressionErrors + s.cachedPostingsOriginalSizeSum += o.cachedPostingsOriginalSizeSum + s.cachedPostingsCompressedSizeSum += o.cachedPostingsCompressedSizeSum + s.cachedPostingsCompressionTimeSum += o.cachedPostingsCompressionTimeSum + s.cachedPostingsDecompressions += o.cachedPostingsDecompressions + s.cachedPostingsDecompressionErrors += o.cachedPostingsDecompressionErrors + s.cachedPostingsDecompressionTimeSum += o.cachedPostingsDecompressionTimeSum + s.seriesTouched += o.seriesTouched s.seriesTouchedSizeSum += o.seriesTouchedSizeSum s.seriesFetched += o.seriesFetched diff --git a/pkg/store/bucket_e2e_test.go b/pkg/store/bucket_e2e_test.go index 6bdc6a5950..12c3b45680 100644 --- a/pkg/store/bucket_e2e_test.go +++ b/pkg/store/bucket_e2e_test.go @@ -21,7 +21,6 @@ import ( "github.com/thanos-io/thanos/pkg/block/metadata" "github.com/thanos-io/thanos/pkg/model" "github.com/thanos-io/thanos/pkg/objstore" - "github.com/thanos-io/thanos/pkg/objstore/inmem" "github.com/thanos-io/thanos/pkg/objstore/objtesting" storecache "github.com/thanos-io/thanos/pkg/store/cache" "github.com/thanos-io/thanos/pkg/store/storepb" @@ -147,16 +146,16 @@ func prepareStoreWithTestBlocks(t testing.TB, dir string, bkt objstore.Bucket, m maxTime: maxTime, } - metaFetcher, err := block.NewMetaFetcher(s.logger, 20, bkt, dir, nil, - block.NewTimePartitionMetaFilter(filterConf.MinTime, filterConf.MaxTime).Filter, - block.NewLabelShardedMetaFilter(relabelConfig).Filter, - ) + metaFetcher, err := block.NewMetaFetcher(s.logger, 20, objstore.WithNoopInstr(bkt), dir, nil, []block.MetadataFilter{ + block.NewTimePartitionMetaFilter(filterConf.MinTime, filterConf.MaxTime), + block.NewLabelShardedMetaFilter(relabelConfig), + }, nil) testutil.Ok(t, err) store, err := NewBucketStore( s.logger, nil, - bkt, + objstore.WithNoopInstr(bkt), metaFetcher, dir, s.cache, @@ -168,6 +167,9 @@ func prepareStoreWithTestBlocks(t testing.TB, dir string, bkt objstore.Bucket, m filterConf, true, true, + true, + DefaultPostingOffsetInMemorySampling, + true, ) testutil.Ok(t, err) s.store = store @@ -496,7 +498,7 @@ func TestBucketStore_ManyParts_e2e(t *testing.T) { func TestBucketStore_TimePartitioning_e2e(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - bkt := inmem.NewBucket() + bkt := objstore.NewInMemBucket() dir, err := ioutil.TempDir("", "test_bucket_time_part_e2e") testutil.Ok(t, err) diff --git a/pkg/store/bucket_test.go b/pkg/store/bucket_test.go index 94550c7b5b..1e8192ec1a 100644 --- a/pkg/store/bucket_test.go +++ b/pkg/store/bucket_test.go @@ -23,11 +23,13 @@ import ( "github.com/fortytw2/leaktest" "github.com/go-kit/kit/log" + "github.com/gogo/protobuf/types" "github.com/leanovate/gopter" "github.com/leanovate/gopter/gen" "github.com/leanovate/gopter/prop" "github.com/oklog/ulid" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/pkg/relabel" @@ -42,9 +44,9 @@ import ( "github.com/thanos-io/thanos/pkg/compact/downsample" "github.com/thanos-io/thanos/pkg/objstore" "github.com/thanos-io/thanos/pkg/objstore/filesystem" - "github.com/thanos-io/thanos/pkg/objstore/inmem" "github.com/thanos-io/thanos/pkg/pool" storecache "github.com/thanos-io/thanos/pkg/store/cache" + "github.com/thanos-io/thanos/pkg/store/hintspb" "github.com/thanos-io/thanos/pkg/store/storepb" "github.com/thanos-io/thanos/pkg/testutil" "github.com/thanos-io/thanos/pkg/testutil/e2eutil" @@ -479,6 +481,9 @@ func TestBucketStore_Info(t *testing.T) { allowAllFilterConf, true, true, + true, + DefaultPostingOffsetInMemorySampling, + false, ) testutil.Ok(t, err) @@ -524,7 +529,7 @@ func TestBucketStore_Sharding(t *testing.T) { testutil.Ok(t, err) defer func() { testutil.Ok(t, os.RemoveAll(dir)) }() - bkt := inmem.NewBucket() + bkt := objstore.NewInMemBucket() series := []labels.Labels{labels.FromStrings("a", "1", "b", "1")} id1, err := e2eutil.CreateBlock(ctx, dir, series, 10, 0, 1000, labels.Labels{{Name: "cluster", Value: "a"}, {Name: "region", Value: "r1"}}, 0) @@ -709,16 +714,16 @@ func testSharding(t *testing.T, reuseDisk string, bkt objstore.Bucket, all ...ul testutil.Ok(t, yaml.Unmarshal([]byte(sc.relabel), &relabelConf)) rec := &recorder{Bucket: bkt} - metaFetcher, err := block.NewMetaFetcher(logger, 20, bkt, dir, nil, - block.NewTimePartitionMetaFilter(allowAllFilterConf.MinTime, allowAllFilterConf.MaxTime).Filter, - block.NewLabelShardedMetaFilter(relabelConf).Filter, - ) + metaFetcher, err := block.NewMetaFetcher(logger, 20, objstore.WithNoopInstr(bkt), dir, nil, []block.MetadataFilter{ + block.NewTimePartitionMetaFilter(allowAllFilterConf.MinTime, allowAllFilterConf.MaxTime), + block.NewLabelShardedMetaFilter(relabelConf), + }, nil) testutil.Ok(t, err) bucketStore, err := NewBucketStore( logger, nil, - rec, + objstore.WithNoopInstr(rec), metaFetcher, dir, noopCache{}, @@ -730,6 +735,9 @@ func testSharding(t *testing.T, reuseDisk string, bkt objstore.Bucket, all ...ul allowAllFilterConf, true, true, + true, + DefaultPostingOffsetInMemorySampling, + false, ) testutil.Ok(t, err) @@ -810,7 +818,7 @@ func expectedTouchedBlockOps(all []ulid.ULID, expected []ulid.ULID, cached []uli // Regression tests against: https://github.com/thanos-io/thanos/issues/1983. func TestReadIndexCache_LoadSeries(t *testing.T) { - bkt := inmem.NewBucket() + bkt := objstore.NewInMemBucket() s := newBucketStoreMetrics(nil) b := &bucketBlock{ @@ -893,7 +901,7 @@ func TestBucketIndexReader_ExpandedPostings(t *testing.T) { id := uploadTestBlock(tb, tmpDir, bkt, 500) - r, err := indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, id) + r, err := indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, id, DefaultPostingOffsetInMemorySampling) testutil.Ok(tb, err) benchmarkExpandedPostings(tb, bkt, id, r, 500) @@ -911,7 +919,7 @@ func BenchmarkBucketIndexReader_ExpandedPostings(b *testing.B) { defer func() { testutil.Ok(tb, bkt.Close()) }() id := uploadTestBlock(tb, tmpDir, bkt, 50e5) - r, err := indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, id) + r, err := indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, id, DefaultPostingOffsetInMemorySampling) testutil.Ok(tb, err) benchmarkExpandedPostings(tb, bkt, id, r, 50e5) @@ -931,7 +939,23 @@ func uploadTestBlock(t testing.TB, tmpDir string, bkt objstore.Bucket, series in logger := log.NewNopLogger() - app := h.Appender() + appendTestData(t, h.Appender(), series) + + testutil.Ok(t, os.MkdirAll(filepath.Join(tmpDir, "tmp"), os.ModePerm)) + id := createBlockFromHead(t, filepath.Join(tmpDir, "tmp"), h) + + _, err = metadata.InjectThanos(log.NewNopLogger(), filepath.Join(tmpDir, "tmp", id.String()), metadata.Thanos{ + Labels: labels.Labels{{Name: "ext1", Value: "1"}}.Map(), + Downsample: metadata.ThanosDownsample{Resolution: 0}, + Source: metadata.TestSource, + }, nil) + testutil.Ok(t, err) + testutil.Ok(t, block.Upload(context.Background(), logger, bkt, filepath.Join(tmpDir, "tmp", id.String()))) + + return id +} + +func appendTestData(t testing.TB, app tsdb.Appender, series int) { addSeries := func(l labels.Labels) { _, err := app.Add(l, 0, 0) testutil.Ok(t, err) @@ -949,19 +973,6 @@ func uploadTestBlock(t testing.TB, tmpDir string, bkt objstore.Bucket, series in } } testutil.Ok(t, app.Commit()) - - testutil.Ok(t, os.MkdirAll(filepath.Join(tmpDir, "tmp"), os.ModePerm)) - id := createBlockFromHead(t, filepath.Join(tmpDir, "tmp"), h) - - _, err = metadata.InjectThanos(log.NewNopLogger(), filepath.Join(tmpDir, "tmp", id.String()), metadata.Thanos{ - Labels: labels.Labels{{Name: "ext1", Value: "1"}}.Map(), - Downsample: metadata.ThanosDownsample{Resolution: 0}, - Source: metadata.TestSource, - }, nil) - testutil.Ok(t, err) - testutil.Ok(t, block.Upload(context.Background(), logger, bkt, filepath.Join(tmpDir, "tmp", id.String()))) - - return id } func createBlockFromHead(t testing.TB, dir string, head *tsdb.Head) ulid.ULID { @@ -998,6 +1009,7 @@ func benchmarkExpandedPostings( iNotEmpty := labels.MustNewMatcher(labels.MatchNotEqual, "i", "") iNot2 := labels.MustNewMatcher(labels.MatchNotEqual, "n", "2"+postingsBenchSuffix) iNot2Star := labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^2.*$") + iRegexSet := labels.MustNewMatcher(labels.MatchRegexp, "i", "0"+postingsBenchSuffix+"|1"+postingsBenchSuffix+"|2"+postingsBenchSuffix) series = series / 5 cases := []struct { @@ -1022,6 +1034,7 @@ func benchmarkExpandedPostings( {`n="1",i=~"1.+",j="foo"`, []*labels.Matcher{n1, i1Plus, jFoo}, int(float64(series) * 0.011111)}, {`n="1",i=~".+",i!="2",j="foo"`, []*labels.Matcher{n1, iPlus, iNot2, jFoo}, int(float64(series) * 0.1)}, {`n="1",i=~".+",i!~"2.*",j="foo"`, []*labels.Matcher{n1, iPlus, iNot2Star, jFoo}, int(1 + float64(series)*0.088888)}, + {`i=~"0|1|2"`, []*labels.Matcher{iRegexSet}, 150}, // 50 series for "1", 50 for "2" and 50 for "3". } for _, c := range cases { @@ -1298,13 +1311,13 @@ func benchSeries(t testutil.TB, number int, dimension Dimension, cases ...int) { partitioner: gapBasedPartitioner{maxGapSize: partitionerMaxGapSize}, chunkObjs: []string{filepath.Join(id.String(), "chunks", "000001")}, chunkPool: chunkPool, - seriesRefetches: prometheus.NewCounter(prometheus.CounterOpts{}), + seriesRefetches: promauto.With(nil).NewCounter(prometheus.CounterOpts{}), } blocks = append(blocks, b) } store := &BucketStore{ - bkt: bkt, + bkt: objstore.WithNoopInstr(bkt), logger: logger, indexCache: noopCache{}, metrics: newBucketStoreMetrics(nil), @@ -1316,7 +1329,7 @@ func benchSeries(t testutil.TB, number int, dimension Dimension, cases ...int) { } for _, block := range blocks { - block.indexHeaderReader, err = indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, block.meta.ULID) + block.indexHeaderReader, err = indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, block.meta.ULID, DefaultPostingOffsetInMemorySampling) testutil.Ok(t, err) } @@ -1340,11 +1353,12 @@ func benchSeries(t testutil.TB, number int, dimension Dimension, cases ...int) { {Type: storepb.LabelMatcher_EQ, Name: "foo", Value: "bar"}, }, }, - expected: expected, + expectedSeries: expected, }) } fmt.Println("Starting") + benchmarkSeries(t, store, bCases) if !t.IsBenchmark() { // Make sure the pool is correctly used. This is expected for 200k numbers. @@ -1402,9 +1416,10 @@ type noopLimiter struct{} func (noopLimiter) Check(uint64) error { return nil } type benchSeriesCase struct { - name string - req *storepb.SeriesRequest - expected []storepb.Series + name string + req *storepb.SeriesRequest + expectedSeries []storepb.Series + expectedHints []hintspb.SeriesResponseHints } func benchmarkSeries(t testutil.TB, store *BucketStore, cases []*benchSeriesCase) { @@ -1415,17 +1430,25 @@ func benchmarkSeries(t testutil.TB, store *BucketStore, cases []*benchSeriesCase srv := newStoreSeriesServer(context.Background()) testutil.Ok(t, store.Series(c.req, srv)) testutil.Equals(t, 0, len(srv.Warnings)) - testutil.Equals(t, len(c.expected), len(srv.SeriesSet)) + testutil.Equals(t, len(c.expectedSeries), len(srv.SeriesSet)) if !t.IsBenchmark() { - if len(c.expected) == 1 { + if len(c.expectedSeries) == 1 { // Chunks are not sorted within response. TODO: Investigate: Is this fine? sort.Slice(srv.SeriesSet[0].Chunks, func(i, j int) bool { return srv.SeriesSet[0].Chunks[i].MinTime < srv.SeriesSet[0].Chunks[j].MinTime }) } // This might give unreadable output for millions of series if error. - testutil.Equals(t, c.expected, srv.SeriesSet) + testutil.Equals(t, c.expectedSeries, srv.SeriesSet) + + var actualHints []hintspb.SeriesResponseHints + for _, anyHints := range srv.HintsSet { + hints := hintspb.SeriesResponseHints{} + testutil.Ok(t, types.UnmarshalAny(anyHints, &hints)) + actualHints = append(actualHints, hints) + } + testutil.Equals(t, c.expectedHints, actualHints) } } @@ -1502,7 +1525,7 @@ func TestSeries_OneBlock_InMemIndexCacheSegfault(t *testing.T) { chunkObjs: []string{filepath.Join(id.String(), "chunks", "000001")}, chunkPool: chunkPool, } - b1.indexHeaderReader, err = indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, b1.meta.ULID) + b1.indexHeaderReader, err = indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, b1.meta.ULID, DefaultPostingOffsetInMemorySampling) testutil.Ok(t, err) } @@ -1540,12 +1563,12 @@ func TestSeries_OneBlock_InMemIndexCacheSegfault(t *testing.T) { chunkObjs: []string{filepath.Join(id.String(), "chunks", "000001")}, chunkPool: chunkPool, } - b2.indexHeaderReader, err = indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, b2.meta.ULID) + b2.indexHeaderReader, err = indexheader.NewBinaryReader(context.Background(), log.NewNopLogger(), bkt, tmpDir, b2.meta.ULID, DefaultPostingOffsetInMemorySampling) testutil.Ok(t, err) } store := &BucketStore{ - bkt: bkt, + bkt: objstore.WithNoopInstr(bkt), logger: logger, indexCache: indexCache, metrics: newBucketStoreMetrics(nil), @@ -1608,3 +1631,107 @@ func TestSeries_OneBlock_InMemIndexCacheSegfault(t *testing.T) { testutil.Equals(t, numSeries, len(srv.SeriesSet)) }) } + +func TestSeries_HintsEnabled(t *testing.T) { + tb := testutil.NewTB(t) + + tmpDir, err := ioutil.TempDir("", "test-series-hints-enabled") + testutil.Ok(t, err) + defer func() { testutil.Ok(t, os.RemoveAll(tmpDir)) }() + + bktDir := filepath.Join(tmpDir, "bkt") + bkt, err := filesystem.NewBucket(bktDir) + testutil.Ok(t, err) + defer func() { testutil.Ok(t, bkt.Close()) }() + + var ( + logger = log.NewNopLogger() + instrBkt = objstore.WithNoopInstr(bkt) + ) + + // Create TSDB blocks. + block1, seriesSet1 := createBlockWithOneSample(tb, bktDir, 0, 2) + block2, seriesSet2 := createBlockWithOneSample(tb, bktDir, 1, 2) + + // Inject the Thanos meta to each block in the storage. + thanosMeta := metadata.Thanos{ + Labels: labels.Labels{{Name: "ext1", Value: "1"}}.Map(), + Downsample: metadata.ThanosDownsample{Resolution: 0}, + Source: metadata.TestSource, + } + + for _, blockID := range []ulid.ULID{block1, block2} { + _, err := metadata.InjectThanos(logger, filepath.Join(bktDir, blockID.String()), thanosMeta, nil) + testutil.Ok(t, err) + } + + // Instance a real bucket store we'll use to query back the series. + fetcher, err := block.NewMetaFetcher(logger, 10, instrBkt, tmpDir, nil, nil, nil) + testutil.Ok(tb, err) + + indexCache, err := storecache.NewInMemoryIndexCacheWithConfig(logger, nil, storecache.InMemoryIndexCacheConfig{}) + testutil.Ok(tb, err) + + store, err := NewBucketStore( + logger, + nil, + instrBkt, + fetcher, + tmpDir, + indexCache, + 1000000, + 10000, + 10, + false, + 10, + nil, + false, + true, + true, + DefaultPostingOffsetInMemorySampling, + true, + ) + testutil.Ok(tb, err) + testutil.Ok(tb, store.SyncBlocks(context.Background())) + + testCases := []*benchSeriesCase{ + { + name: "query a single block", + req: &storepb.SeriesRequest{ + MinTime: 0, + MaxTime: 1, + Matchers: []storepb.LabelMatcher{ + {Type: storepb.LabelMatcher_EQ, Name: "foo", Value: "bar"}, + }, + }, + expectedSeries: seriesSet1, + expectedHints: []hintspb.SeriesResponseHints{ + { + QueriedBlocks: []hintspb.Block{ + {Id: block1.String()}, + }, + }, + }, + }, { + name: "query multiple blocks", + req: &storepb.SeriesRequest{ + MinTime: 0, + MaxTime: 3, + Matchers: []storepb.LabelMatcher{ + {Type: storepb.LabelMatcher_EQ, Name: "foo", Value: "bar"}, + }, + }, + expectedSeries: append(append([]storepb.Series{}, seriesSet1...), seriesSet2...), + expectedHints: []hintspb.SeriesResponseHints{ + { + QueriedBlocks: []hintspb.Block{ + {Id: block1.String()}, + {Id: block2.String()}, + }, + }, + }, + }, + } + + benchmarkSeries(tb, store, testCases) +} diff --git a/pkg/store/cache/caching_bucket.go b/pkg/store/cache/caching_bucket.go new file mode 100644 index 0000000000..c725719a73 --- /dev/null +++ b/pkg/store/cache/caching_bucket.go @@ -0,0 +1,629 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package storecache + +import ( + "bytes" + "context" + "encoding/binary" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "strconv" + "sync" + "time" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "golang.org/x/sync/errgroup" + + "github.com/thanos-io/thanos/pkg/cache" + "github.com/thanos-io/thanos/pkg/objstore" + "github.com/thanos-io/thanos/pkg/runutil" + "github.com/thanos-io/thanos/pkg/tracing" +) + +const ( + originCache = "cache" + originBucket = "bucket" + + opGet = "get" + opGetRange = "getrange" + opIter = "iter" + opExists = "exists" + opObjectSize = "objectsize" +) + +var errObjNotFound = errors.Errorf("object not found") + +// CachingBucket implementation that provides some caching features, based on passed configuration. +type CachingBucket struct { + objstore.Bucket + + cfg *CachingBucketConfig + logger log.Logger + + requestedGetRangeBytes *prometheus.CounterVec + fetchedGetRangeBytes *prometheus.CounterVec + refetchedGetRangeBytes *prometheus.CounterVec + + operationConfigs map[string][]*operationConfig + operationRequests *prometheus.CounterVec + operationHits *prometheus.CounterVec +} + +// NewCachingBucket creates new caching bucket with provided configuration. Configuration should not be +// changed after creating caching bucket. +func NewCachingBucket(b objstore.Bucket, cfg *CachingBucketConfig, logger log.Logger, reg prometheus.Registerer) (*CachingBucket, error) { + if b == nil { + return nil, errors.New("bucket is nil") + } + + cb := &CachingBucket{ + Bucket: b, + cfg: cfg, + logger: logger, + + operationConfigs: map[string][]*operationConfig{}, + + requestedGetRangeBytes: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ + Name: "thanos_store_bucket_cache_getrange_requested_bytes_total", + Help: "Total number of bytes requested via GetRange.", + }, []string{"config"}), + fetchedGetRangeBytes: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ + Name: "thanos_store_bucket_cache_getrange_fetched_bytes_total", + Help: "Total number of bytes fetched because of GetRange operation. Data from bucket is then stored to cache.", + }, []string{"origin", "config"}), + refetchedGetRangeBytes: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ + Name: "thanos_store_bucket_cache_getrange_refetched_bytes_total", + Help: "Total number of bytes re-fetched from storage because of GetRange operation, despite being in cache already.", + }, []string{"origin", "config"}), + + operationRequests: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ + Name: "thanos_store_bucket_cache_operation_requests_total", + Help: "Number of requested operations matching given config.", + }, []string{"operation", "config"}), + operationHits: promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ + Name: "thanos_store_bucket_cache_operation_hits_total", + Help: "Number of operations served from cache for given config.", + }, []string{"operation", "config"}), + } + + for op, names := range cfg.allConfigNames() { + for _, n := range names { + cb.operationRequests.WithLabelValues(op, n) + cb.operationHits.WithLabelValues(op, n) + + if op == opGetRange { + cb.requestedGetRangeBytes.WithLabelValues(n) + cb.fetchedGetRangeBytes.WithLabelValues(originCache, n) + cb.fetchedGetRangeBytes.WithLabelValues(originBucket, n) + cb.refetchedGetRangeBytes.WithLabelValues(originCache, n) + } + } + } + + return cb, nil +} + +func (cb *CachingBucket) Name() string { + return "caching: " + cb.Bucket.Name() +} + +func (cb *CachingBucket) WithExpectedErrs(expectedFunc objstore.IsOpFailureExpectedFunc) objstore.Bucket { + if ib, ok := cb.Bucket.(objstore.InstrumentedBucket); ok { + // Make a copy, but replace bucket with instrumented one. + res := &CachingBucket{} + *res = *cb + res.Bucket = ib.WithExpectedErrs(expectedFunc) + return res + } + + return cb +} + +func (cb *CachingBucket) ReaderWithExpectedErrs(expectedFunc objstore.IsOpFailureExpectedFunc) objstore.BucketReader { + return cb.WithExpectedErrs(expectedFunc) +} + +func (cb *CachingBucket) Iter(ctx context.Context, dir string, f func(string) error) error { + cfgName, cfg := cb.cfg.findIterConfig(dir) + if cfg == nil { + return cb.Bucket.Iter(ctx, dir, f) + } + + cb.operationRequests.WithLabelValues(opIter, cfgName).Inc() + + key := cachingKeyIter(dir) + data := cfg.cache.Fetch(ctx, []string{key}) + if data[key] != nil { + list, err := cfg.codec.Decode(data[key]) + if err == nil { + cb.operationHits.WithLabelValues(opIter, cfgName).Inc() + for _, n := range list { + if err := f(n); err != nil { + return err + } + } + return nil + } + level.Warn(cb.logger).Log("msg", "failed to decode cached Iter result", "key", key, "err", err) + } + + // Iteration can take a while (esp. since it calls function), and iterTTL is generally low. + // We will compute TTL based time when iteration started. + iterTime := time.Now() + var list []string + err := cb.Bucket.Iter(ctx, dir, func(s string) error { + list = append(list, s) + return f(s) + }) + + remainingTTL := cfg.ttl - time.Since(iterTime) + if err == nil && remainingTTL > 0 { + data, encErr := cfg.codec.Encode(list) + if encErr == nil { + cfg.cache.Store(ctx, map[string][]byte{key: data}, remainingTTL) + return nil + } + level.Warn(cb.logger).Log("msg", "failed to encode Iter result", "key", key, "err", encErr) + } + return err +} + +func (cb *CachingBucket) Exists(ctx context.Context, name string) (bool, error) { + cfgName, cfg := cb.cfg.findExistConfig(name) + if cfg == nil { + return cb.Bucket.Exists(ctx, name) + } + + cb.operationRequests.WithLabelValues(opExists, cfgName).Inc() + + key := cachingKeyExists(name) + hits := cfg.cache.Fetch(ctx, []string{key}) + + if ex := hits[key]; ex != nil { + exists, err := strconv.ParseBool(string(ex)) + if err == nil { + cb.operationHits.WithLabelValues(opExists, cfgName).Inc() + return exists, nil + } + level.Warn(cb.logger).Log("msg", "unexpected cached 'exists' value", "key", key, "val", string(ex)) + } + + existsTime := time.Now() + ok, err := cb.Bucket.Exists(ctx, name) + if err == nil { + storeExistsCacheEntry(ctx, key, ok, existsTime, cfg.cache, cfg.existsTTL, cfg.doesntExistTTL) + } + + return ok, err +} + +func storeExistsCacheEntry(ctx context.Context, cachingKey string, exists bool, ts time.Time, cache cache.Cache, existsTTL, doesntExistTTL time.Duration) { + var ttl time.Duration + if exists { + ttl = existsTTL - time.Since(ts) + } else { + ttl = doesntExistTTL - time.Since(ts) + } + + if ttl > 0 { + cache.Store(ctx, map[string][]byte{cachingKey: []byte(strconv.FormatBool(exists))}, ttl) + } +} + +func (cb *CachingBucket) Get(ctx context.Context, name string) (io.ReadCloser, error) { + cfgName, cfg := cb.cfg.findGetConfig(name) + if cfg == nil { + return cb.Bucket.Get(ctx, name) + } + + cb.operationRequests.WithLabelValues(opGet, cfgName).Inc() + + contentKey := cachingKeyContent(name) + existsKey := cachingKeyExists(name) + + hits := cfg.cache.Fetch(ctx, []string{contentKey, existsKey}) + if hits[contentKey] != nil { + cb.operationHits.WithLabelValues(opGet, cfgName).Inc() + return ioutil.NopCloser(bytes.NewReader(hits[contentKey])), nil + } + + // If we know that file doesn't exist, we can return that. Useful for deletion marks. + if ex := hits[existsKey]; ex != nil { + if exists, err := strconv.ParseBool(string(ex)); err == nil && !exists { + cb.operationHits.WithLabelValues(opGet, cfgName).Inc() + return nil, errObjNotFound + } + } + + getTime := time.Now() + reader, err := cb.Bucket.Get(ctx, name) + if err != nil { + if cb.Bucket.IsObjNotFoundErr(err) { + // Cache that object doesn't exist. + storeExistsCacheEntry(ctx, existsKey, false, getTime, cfg.cache, cfg.existsTTL, cfg.doesntExistTTL) + } + + return nil, err + } + + storeExistsCacheEntry(ctx, existsKey, true, getTime, cfg.cache, cfg.existsTTL, cfg.doesntExistTTL) + return &getReader{ + c: cfg.cache, + ctx: ctx, + r: reader, + buf: new(bytes.Buffer), + startTime: getTime, + ttl: cfg.contentTTL, + cacheKey: contentKey, + maxSize: cfg.maxCacheableSize, + }, nil +} + +func (cb *CachingBucket) IsObjNotFoundErr(err error) bool { + return err == errObjNotFound || cb.Bucket.IsObjNotFoundErr(err) +} + +func (cb *CachingBucket) GetRange(ctx context.Context, name string, off, length int64) (io.ReadCloser, error) { + if off < 0 || length <= 0 { + return cb.Bucket.GetRange(ctx, name, off, length) + } + + cfgName, cfg := cb.cfg.findGetRangeConfig(name) + if cfg == nil { + return cb.Bucket.GetRange(ctx, name, off, length) + } + + var ( + r io.ReadCloser + err error + ) + tracing.DoInSpan(ctx, "cachingbucket_getrange", func(ctx context.Context) { + r, err = cb.cachedGetRange(ctx, name, off, length, cfgName, cfg) + }) + return r, err +} + +func (cb *CachingBucket) ObjectSize(ctx context.Context, name string) (uint64, error) { + cfgName, cfg := cb.cfg.findObjectSizeConfig(name) + if cfg == nil { + return cb.Bucket.ObjectSize(ctx, name) + } + + return cb.cachedObjectSize(ctx, name, cfgName, cfg.cache, cfg.ttl) +} + +func (cb *CachingBucket) cachedObjectSize(ctx context.Context, name string, cfgName string, cache cache.Cache, ttl time.Duration) (uint64, error) { + key := cachingKeyObjectSize(name) + + cb.operationRequests.WithLabelValues(opObjectSize, cfgName).Inc() + + hits := cache.Fetch(ctx, []string{key}) + if s := hits[key]; len(s) == 8 { + cb.operationHits.WithLabelValues(opObjectSize, cfgName).Inc() + return binary.BigEndian.Uint64(s), nil + } + + size, err := cb.Bucket.ObjectSize(ctx, name) + if err != nil { + return 0, err + } + + var buf [8]byte + binary.BigEndian.PutUint64(buf[:], size) + cache.Store(ctx, map[string][]byte{key: buf[:]}, ttl) + + return size, nil +} + +func (cb *CachingBucket) cachedGetRange(ctx context.Context, name string, offset, length int64, cfgName string, cfg *getRangeConfig) (io.ReadCloser, error) { + cb.operationRequests.WithLabelValues(opGetRange, cfgName).Inc() + cb.requestedGetRangeBytes.WithLabelValues(cfgName).Add(float64(length)) + + size, err := cb.cachedObjectSize(ctx, name, cfgName, cfg.cache, cfg.objectSizeTTL) + if err != nil { + return nil, errors.Wrapf(err, "failed to get size of object: %s", name) + } + + // If length goes over object size, adjust length. We use it later to limit number of read bytes. + if uint64(offset+length) > size { + length = int64(size - uint64(offset)) + } + + // Start and end range are subrange-aligned offsets into object, that we're going to read. + startRange := (offset / cfg.subrangeSize) * cfg.subrangeSize + endRange := ((offset + length) / cfg.subrangeSize) * cfg.subrangeSize + if (offset+length)%cfg.subrangeSize > 0 { + endRange += cfg.subrangeSize + } + + // The very last subrange in the object may have length that is not divisible by subrange size. + lastSubrangeOffset := endRange - cfg.subrangeSize + lastSubrangeLength := int(cfg.subrangeSize) + if uint64(endRange) > size { + lastSubrangeOffset = (int64(size) / cfg.subrangeSize) * cfg.subrangeSize + lastSubrangeLength = int(int64(size) - lastSubrangeOffset) + } + + numSubranges := (endRange - startRange) / cfg.subrangeSize + + offsetKeys := make(map[int64]string, numSubranges) + keys := make([]string, 0, numSubranges) + + totalRequestedBytes := int64(0) + for off := startRange; off < endRange; off += cfg.subrangeSize { + end := off + cfg.subrangeSize + if end > int64(size) { + end = int64(size) + } + totalRequestedBytes += (end - off) + + k := cachingKeyObjectSubrange(name, off, end) + keys = append(keys, k) + offsetKeys[off] = k + } + + // Try to get all subranges from the cache. + totalCachedBytes := int64(0) + hits := cfg.cache.Fetch(ctx, keys) + for _, b := range hits { + totalCachedBytes += int64(len(b)) + } + cb.fetchedGetRangeBytes.WithLabelValues(originCache, cfgName).Add(float64(totalCachedBytes)) + cb.operationHits.WithLabelValues(opGetRange, cfgName).Add(float64(len(hits)) / float64(len(keys))) + + if len(hits) < len(keys) { + if hits == nil { + hits = map[string][]byte{} + } + + err := cb.fetchMissingSubranges(ctx, name, startRange, endRange, offsetKeys, hits, lastSubrangeOffset, lastSubrangeLength, cfgName, cfg) + if err != nil { + return nil, err + } + } + + return ioutil.NopCloser(newSubrangesReader(cfg.subrangeSize, offsetKeys, hits, offset, length)), nil +} + +type rng struct { + start, end int64 +} + +// fetchMissingSubranges fetches missing subranges, stores them into "hits" map +// and into cache as well (using provided cacheKeys). +func (cb *CachingBucket) fetchMissingSubranges(ctx context.Context, name string, startRange, endRange int64, cacheKeys map[int64]string, hits map[string][]byte, lastSubrangeOffset int64, lastSubrangeLength int, cfgName string, cfg *getRangeConfig) error { + // Ordered list of missing sub-ranges. + var missing []rng + + for off := startRange; off < endRange; off += cfg.subrangeSize { + if hits[cacheKeys[off]] == nil { + missing = append(missing, rng{start: off, end: off + cfg.subrangeSize}) + } + } + + missing = mergeRanges(missing, 0) // Merge adjacent ranges. + // Keep merging until we have only max number of ranges (= requests). + for limit := cfg.subrangeSize; cfg.maxSubRequests > 0 && len(missing) > cfg.maxSubRequests; limit = limit * 2 { + missing = mergeRanges(missing, limit) + } + + var hitsMutex sync.Mutex + + // Run parallel queries for each missing range. Fetched data is stored into 'hits' map, protected by hitsMutex. + g, gctx := errgroup.WithContext(ctx) + for _, m := range missing { + m := m + g.Go(func() error { + r, err := cb.Bucket.GetRange(gctx, name, m.start, m.end-m.start) + if err != nil { + return errors.Wrapf(err, "fetching range [%d, %d]", m.start, m.end) + } + defer runutil.CloseWithLogOnErr(cb.logger, r, "fetching range [%d, %d]", m.start, m.end) + + for off := m.start; off < m.end && gctx.Err() == nil; off += cfg.subrangeSize { + key := cacheKeys[off] + if key == "" { + return errors.Errorf("fetching range [%d, %d]: caching key for offset %d not found", m.start, m.end, off) + } + + // We need a new buffer for each subrange, both for storing into hits, and also for caching. + var subrangeData []byte + if off == lastSubrangeOffset { + // The very last subrange in the object may have different length, + // if object length isn't divisible by subrange size. + subrangeData = make([]byte, lastSubrangeLength) + } else { + subrangeData = make([]byte, cfg.subrangeSize) + } + _, err := io.ReadFull(r, subrangeData) + if err != nil { + return errors.Wrapf(err, "fetching range [%d, %d]", m.start, m.end) + } + + storeToCache := false + hitsMutex.Lock() + if _, ok := hits[key]; !ok { + storeToCache = true + hits[key] = subrangeData + } + hitsMutex.Unlock() + + if storeToCache { + cb.fetchedGetRangeBytes.WithLabelValues(originBucket, cfgName).Add(float64(len(subrangeData))) + cfg.cache.Store(gctx, map[string][]byte{key: subrangeData}, cfg.subrangeTTL) + } else { + cb.refetchedGetRangeBytes.WithLabelValues(originCache, cfgName).Add(float64(len(subrangeData))) + } + } + + return gctx.Err() + }) + } + + return g.Wait() +} + +// Merges ranges that are close to each other. Modifies input. +func mergeRanges(input []rng, limit int64) []rng { + if len(input) == 0 { + return input + } + + last := 0 + for ix := 1; ix < len(input); ix++ { + if (input[ix].start - input[last].end) <= limit { + input[last].end = input[ix].end + } else { + last++ + input[last] = input[ix] + } + } + return input[:last+1] +} + +func cachingKeyObjectSize(name string) string { + return fmt.Sprintf("size:%s", name) +} + +func cachingKeyObjectSubrange(name string, start int64, end int64) string { + return fmt.Sprintf("subrange:%s:%d:%d", name, start, end) +} + +func cachingKeyIter(name string) string { + return fmt.Sprintf("iter:%s", name) +} + +func cachingKeyExists(name string) string { + return fmt.Sprintf("exists:%s", name) +} + +func cachingKeyContent(name string) string { + return fmt.Sprintf("content:%s", name) +} + +// Reader implementation that uses in-memory subranges. +type subrangesReader struct { + subrangeSize int64 + + // Mapping of subrangeSize-aligned offsets to keys in hits. + offsetsKeys map[int64]string + subranges map[string][]byte + + // Offset for next read, used to find correct subrange to return data from. + readOffset int64 + + // Remaining data to return from this reader. Once zero, this reader reports EOF. + remaining int64 +} + +func newSubrangesReader(subrangeSize int64, offsetsKeys map[int64]string, subranges map[string][]byte, readOffset, remaining int64) *subrangesReader { + return &subrangesReader{ + subrangeSize: subrangeSize, + offsetsKeys: offsetsKeys, + subranges: subranges, + + readOffset: readOffset, + remaining: remaining, + } +} + +func (c *subrangesReader) Read(p []byte) (n int, err error) { + if c.remaining <= 0 { + return 0, io.EOF + } + + currentSubrangeOffset := (c.readOffset / c.subrangeSize) * c.subrangeSize + currentSubrange, err := c.subrangeAt(currentSubrangeOffset) + if err != nil { + return 0, errors.Wrapf(err, "read position: %d", c.readOffset) + } + + offsetInSubrange := int(c.readOffset - currentSubrangeOffset) + toCopy := len(currentSubrange) - offsetInSubrange + if toCopy <= 0 { + // This can only happen if subrange's length is not subrangeSize, and reader is told to read more data. + return 0, errors.Errorf("no more data left in subrange at position %d, subrange length %d, reading position %d", currentSubrangeOffset, len(currentSubrange), c.readOffset) + } + + if len(p) < toCopy { + toCopy = len(p) + } + if c.remaining < int64(toCopy) { + toCopy = int(c.remaining) // Conversion is safe, c.remaining is small enough. + } + + copy(p, currentSubrange[offsetInSubrange:offsetInSubrange+toCopy]) + c.readOffset += int64(toCopy) + c.remaining -= int64(toCopy) + + return toCopy, nil +} + +func (c *subrangesReader) subrangeAt(offset int64) ([]byte, error) { + b := c.subranges[c.offsetsKeys[offset]] + if b == nil { + return nil, errors.Errorf("subrange for offset %d not found", offset) + } + return b, nil +} + +type getReader struct { + c cache.Cache + ctx context.Context + r io.ReadCloser + buf *bytes.Buffer + startTime time.Time + ttl time.Duration + cacheKey string + maxSize int +} + +func (g *getReader) Close() error { + // We don't know if entire object was read, don't store it here. + g.buf = nil + return g.r.Close() +} + +func (g *getReader) Read(p []byte) (n int, err error) { + n, err = g.r.Read(p) + if n > 0 && g.buf != nil { + if g.buf.Len()+n <= g.maxSize { + g.buf.Write(p[:n]) + } else { + // Object is larger than max size, stop caching. + g.buf = nil + } + } + + if err == io.EOF && g.buf != nil { + remainingTTL := g.ttl - time.Since(g.startTime) + if remainingTTL > 0 { + g.c.Store(g.ctx, map[string][]byte{g.cacheKey: g.buf.Bytes()}, remainingTTL) + } + // Clear reference, to avoid doing another Store on next read. + g.buf = nil + } + + return n, err +} + +// JSONIterCodec encodes iter results into JSON. Suitable for root dir. +type JSONIterCodec struct{} + +func (jic JSONIterCodec) Encode(files []string) ([]byte, error) { + return json.Marshal(files) +} + +func (jic JSONIterCodec) Decode(data []byte) ([]string, error) { + var list []string + err := json.Unmarshal(data, &list) + return list, err +} diff --git a/pkg/store/cache/caching_bucket_config.go b/pkg/store/cache/caching_bucket_config.go new file mode 100644 index 0000000000..dce0350fdf --- /dev/null +++ b/pkg/store/cache/caching_bucket_config.go @@ -0,0 +1,208 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package storecache + +import ( + "time" + + "github.com/thanos-io/thanos/pkg/cache" +) + +// Codec for encoding and decoding results of Iter call. +type IterCodec interface { + Encode(files []string) ([]byte, error) + Decode(cachedData []byte) ([]string, error) +} + +// CachingBucketConfig contains low-level configuration for individual bucket operations. +// This is not exposed to the user, but it is expected that code sets up individual +// operations based on user-provided configuration. +type CachingBucketConfig struct { + get map[string]*getConfig + iter map[string]*iterConfig + exists map[string]*existsConfig + getRange map[string]*getRangeConfig + objectSize map[string]*objectSizeConfig +} + +func NewCachingBucketConfig() *CachingBucketConfig { + return &CachingBucketConfig{ + get: map[string]*getConfig{}, + iter: map[string]*iterConfig{}, + exists: map[string]*existsConfig{}, + getRange: map[string]*getRangeConfig{}, + objectSize: map[string]*objectSizeConfig{}, + } +} + +// Generic config for single operation. +type operationConfig struct { + matcher func(name string) bool + cache cache.Cache +} + +// Operation-specific configs. +type iterConfig struct { + operationConfig + ttl time.Duration + codec IterCodec +} + +type existsConfig struct { + operationConfig + existsTTL time.Duration + doesntExistTTL time.Duration +} + +type getConfig struct { + existsConfig + contentTTL time.Duration + maxCacheableSize int +} + +type getRangeConfig struct { + operationConfig + subrangeSize int64 + maxSubRequests int + objectSizeTTL time.Duration + subrangeTTL time.Duration +} + +type objectSizeConfig struct { + operationConfig + ttl time.Duration +} + +func newOperationConfig(cache cache.Cache, matcher func(string) bool) operationConfig { + if cache == nil { + panic("cache") + } + if matcher == nil { + panic("matcher") + } + + return operationConfig{ + matcher: matcher, + cache: cache, + } +} + +// CacheIter configures caching of "Iter" operation for matching directories. +func (cfg *CachingBucketConfig) CacheIter(configName string, cache cache.Cache, matcher func(string) bool, ttl time.Duration, codec IterCodec) { + cfg.iter[configName] = &iterConfig{ + operationConfig: newOperationConfig(cache, matcher), + ttl: ttl, + codec: codec, + } +} + +// CacheGet configures caching of "Get" operation for matching files. Content of the object is cached, as well as whether object exists or not. +func (cfg *CachingBucketConfig) CacheGet(configName string, cache cache.Cache, matcher func(string) bool, maxCacheableSize int, contentTTL, existsTTL, doesntExistTTL time.Duration) { + cfg.get[configName] = &getConfig{ + existsConfig: existsConfig{ + operationConfig: newOperationConfig(cache, matcher), + existsTTL: existsTTL, + doesntExistTTL: doesntExistTTL, + }, + contentTTL: contentTTL, + maxCacheableSize: maxCacheableSize, + } +} + +// CacheExists configures caching of "Exists" operation for matching files. Negative values are cached as well. +func (cfg *CachingBucketConfig) CacheExists(configName string, cache cache.Cache, matcher func(string) bool, existsTTL, doesntExistTTL time.Duration) { + cfg.exists[configName] = &existsConfig{ + operationConfig: newOperationConfig(cache, matcher), + existsTTL: existsTTL, + doesntExistTTL: doesntExistTTL, + } +} + +// CacheGetRange configures caching of "GetRange" operation. Subranges (aligned on subrange size) are cached individually. +// Since caching operation needs to know the object size to compute correct subranges, object size is cached as well. +// Single "GetRange" requests can result in multiple smaller GetRange sub-requests issued on the underlying bucket. +// MaxSubRequests specifies how many such subrequests may be issued. Values <= 0 mean there is no limit (requests +// for adjacent missing subranges are still merged). +func (cfg *CachingBucketConfig) CacheGetRange(configName string, cache cache.Cache, matcher func(string) bool, subrangeSize int64, objectSizeTTL, subrangeTTL time.Duration, maxSubRequests int) { + cfg.getRange[configName] = &getRangeConfig{ + operationConfig: newOperationConfig(cache, matcher), + subrangeSize: subrangeSize, + objectSizeTTL: objectSizeTTL, + subrangeTTL: subrangeTTL, + maxSubRequests: maxSubRequests, + } +} + +// CacheObjectSize configures caching of "ObjectSize" operation for matching files. +func (cfg *CachingBucketConfig) CacheObjectSize(configName string, cache cache.Cache, matcher func(name string) bool, ttl time.Duration) { + cfg.objectSize[configName] = &objectSizeConfig{ + operationConfig: newOperationConfig(cache, matcher), + ttl: ttl, + } +} + +func (cfg *CachingBucketConfig) allConfigNames() map[string][]string { + result := map[string][]string{} + for n := range cfg.get { + result[opGet] = append(result[opGet], n) + } + for n := range cfg.iter { + result[opIter] = append(result[opIter], n) + } + for n := range cfg.exists { + result[opExists] = append(result[opExists], n) + } + for n := range cfg.getRange { + result[opGetRange] = append(result[opGetRange], n) + } + for n := range cfg.objectSize { + result[opObjectSize] = append(result[opObjectSize], n) + } + return result +} + +func (cfg *CachingBucketConfig) findIterConfig(dir string) (string, *iterConfig) { + for n, cfg := range cfg.iter { + if cfg.matcher(dir) { + return n, cfg + } + } + return "", nil +} + +func (cfg *CachingBucketConfig) findExistConfig(name string) (string, *existsConfig) { + for n, cfg := range cfg.exists { + if cfg.matcher(name) { + return n, cfg + } + } + return "", nil +} + +func (cfg *CachingBucketConfig) findGetConfig(name string) (string, *getConfig) { + for n, cfg := range cfg.get { + if cfg.matcher(name) { + return n, cfg + } + } + return "", nil +} + +func (cfg *CachingBucketConfig) findGetRangeConfig(name string) (string, *getRangeConfig) { + for n, cfg := range cfg.getRange { + if cfg.matcher(name) { + return n, cfg + } + } + return "", nil +} + +func (cfg *CachingBucketConfig) findObjectSizeConfig(name string) (string, *objectSizeConfig) { + for n, cfg := range cfg.objectSize { + if cfg.matcher(name) { + return n, cfg + } + } + return "", nil +} diff --git a/pkg/store/cache/caching_bucket_factory.go b/pkg/store/cache/caching_bucket_factory.go new file mode 100644 index 0000000000..3dbd60276e --- /dev/null +++ b/pkg/store/cache/caching_bucket_factory.go @@ -0,0 +1,124 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package storecache + +import ( + "regexp" + "strings" + "time" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" + "gopkg.in/yaml.v2" + + "github.com/thanos-io/thanos/pkg/block/metadata" + cache "github.com/thanos-io/thanos/pkg/cache" + "github.com/thanos-io/thanos/pkg/cacheutil" + "github.com/thanos-io/thanos/pkg/model" + "github.com/thanos-io/thanos/pkg/objstore" +) + +// BucketCacheProvider is a type used to evaluate all bucket cache providers. +type BucketCacheProvider string + +const MemcachedBucketCacheProvider BucketCacheProvider = "memcached" // Memcached cache-provider for caching bucket. + +// CachingWithBackendConfig is a configuration of caching bucket used by Store component. +type CachingWithBackendConfig struct { + Type BucketCacheProvider `yaml:"backend"` + BackendConfig interface{} `yaml:"backend_config"` + + // Basic unit used to cache chunks. + ChunkSubrangeSize int64 `yaml:"chunk_subrange_size"` + + // Maximum number of GetRange requests issued by this bucket for single GetRange call. Zero or negative value = unlimited. + MaxChunksGetRangeRequests int `yaml:"max_chunks_get_range_requests"` + + // TTLs for various cache items. + ChunkObjectSizeTTL time.Duration `yaml:"chunk_object_size_ttl"` + ChunkSubrangeTTL time.Duration `yaml:"chunk_subrange_ttl"` + + // How long to cache result of Iter call in root directory. + BlocksIterTTL time.Duration `yaml:"blocks_iter_ttl"` + + // Config for Exists and Get operations for metadata files. + MetafileExistsTTL time.Duration `yaml:"metafile_exists_ttl"` + MetafileDoesntExistTTL time.Duration `yaml:"metafile_doesnt_exist_ttl"` + MetafileContentTTL time.Duration `yaml:"metafile_content_ttl"` + MetafileMaxSize model.Bytes `yaml:"metafile_max_size"` +} + +func (cfg *CachingWithBackendConfig) Defaults() { + cfg.ChunkSubrangeSize = 16000 // Equal to max chunk size. + cfg.ChunkObjectSizeTTL = 24 * time.Hour + cfg.ChunkSubrangeTTL = 24 * time.Hour + cfg.MaxChunksGetRangeRequests = 3 + cfg.BlocksIterTTL = 5 * time.Minute + cfg.MetafileExistsTTL = 2 * time.Hour + cfg.MetafileDoesntExistTTL = 15 * time.Minute + cfg.MetafileContentTTL = 24 * time.Hour + cfg.MetafileMaxSize = 1024 * 1024 // Equal to default MaxItemSize in memcached client. +} + +// NewCachingBucketFromYaml uses YAML configuration to create new caching bucket. +func NewCachingBucketFromYaml(yamlContent []byte, bucket objstore.Bucket, logger log.Logger, reg prometheus.Registerer) (objstore.InstrumentedBucket, error) { + level.Info(logger).Log("msg", "loading caching bucket configuration") + + config := &CachingWithBackendConfig{} + config.Defaults() + + if err := yaml.UnmarshalStrict(yamlContent, config); err != nil { + return nil, errors.Wrap(err, "parsing config YAML file") + } + + backendConfig, err := yaml.Marshal(config.BackendConfig) + if err != nil { + return nil, errors.Wrap(err, "marshal content of cache backend configuration") + } + + var c cache.Cache + + switch config.Type { + case MemcachedBucketCacheProvider: + var memcached cacheutil.MemcachedClient + memcached, err := cacheutil.NewMemcachedClient(logger, "caching-bucket", backendConfig, reg) + if err != nil { + return nil, errors.Wrapf(err, "failed to create memcached client") + } + c = cache.NewMemcachedCache("caching-bucket", logger, memcached, reg) + default: + return nil, errors.Errorf("unsupported cache type: %s", config.Type) + } + + cfg := NewCachingBucketConfig() + + // Configure cache. + cfg.CacheGetRange("chunks", c, isTSDBChunkFile, config.ChunkSubrangeSize, config.ChunkObjectSizeTTL, config.ChunkSubrangeTTL, config.MaxChunksGetRangeRequests) + cfg.CacheExists("meta.jsons", c, isMetaFile, config.MetafileExistsTTL, config.MetafileDoesntExistTTL) + cfg.CacheGet("meta.jsons", c, isMetaFile, int(config.MetafileMaxSize), config.MetafileContentTTL, config.MetafileExistsTTL, config.MetafileDoesntExistTTL) + + // Cache Iter requests for root. + cfg.CacheIter("blocks-iter", c, isBlocksRootDir, config.BlocksIterTTL, JSONIterCodec{}) + + cb, err := NewCachingBucket(bucket, cfg, logger, reg) + if err != nil { + return nil, err + } + + return cb, nil +} + +var chunksMatcher = regexp.MustCompile(`^.*/chunks/\d+$`) + +func isTSDBChunkFile(name string) bool { return chunksMatcher.MatchString(name) } + +func isMetaFile(name string) bool { + return strings.HasSuffix(name, "/"+metadata.MetaFilename) || strings.HasSuffix(name, "/"+metadata.DeletionMarkFilename) +} + +func isBlocksRootDir(name string) bool { + return name == "" +} diff --git a/pkg/store/cache/caching_bucket_test.go b/pkg/store/cache/caching_bucket_test.go new file mode 100644 index 0000000000..d392d9066e --- /dev/null +++ b/pkg/store/cache/caching_bucket_test.go @@ -0,0 +1,658 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package storecache + +import ( + "bytes" + "context" + "fmt" + "io" + "io/ioutil" + "sort" + "strings" + "sync" + "testing" + "time" + + "github.com/pkg/errors" + promtest "github.com/prometheus/client_golang/prometheus/testutil" + + "github.com/thanos-io/thanos/pkg/objstore" + "github.com/thanos-io/thanos/pkg/runutil" + "github.com/thanos-io/thanos/pkg/testutil" +) + +const testFilename = "/random_object" + +func TestChunksCaching(t *testing.T) { + length := int64(1024 * 1024) + subrangeSize := int64(16000) // All tests are based on this value. + + data := make([]byte, length) + for ix := 0; ix < len(data); ix++ { + data[ix] = byte(ix) + } + + name := "/test/chunks/000001" + + inmem := objstore.NewInMemBucket() + testutil.Ok(t, inmem.Upload(context.Background(), name, bytes.NewReader(data))) + + // We reuse cache between tests (!) + cache := newMockCache() + + // Warning, these tests must be run in order, they depend cache state from previous test. + for _, tc := range []struct { + name string + init func() + offset int64 + length int64 + maxGetRangeRequests int + expectedLength int64 + expectedFetchedBytes int64 + expectedCachedBytes int64 + expectedRefetchedBytes int64 + }{ + { + name: "basic test", + offset: 555555, + length: 55555, + expectedLength: 55555, + expectedFetchedBytes: 5 * subrangeSize, + }, + + { + name: "same request will hit all subranges in the cache", + offset: 555555, + length: 55555, + expectedLength: 55555, + expectedCachedBytes: 5 * subrangeSize, + }, + + { + name: "request data close to the end of object", + offset: length - 10, + length: 3000, + expectedLength: 10, + expectedFetchedBytes: 8576, // Last (incomplete) subrange is fetched. + }, + + { + name: "another request data close to the end of object, cached by previous test", + offset: 1040100, + length: subrangeSize, + expectedLength: 8476, + expectedCachedBytes: 8576, + }, + + { + name: "entire object, combination of cached and uncached subranges", + offset: 0, + length: length, + expectedLength: length, + expectedCachedBytes: 5*subrangeSize + 8576, // 5 subrange cached from first test, plus last incomplete subrange. + expectedFetchedBytes: 60 * subrangeSize, + }, + + { + name: "entire object again, everything is cached", + offset: 0, + length: length, + expectedLength: length, + expectedCachedBytes: length, // Entire file is now cached. + }, + + { + name: "entire object again, nothing is cached", + offset: 0, + length: length, + expectedLength: length, + expectedFetchedBytes: length, + expectedCachedBytes: 0, // Cache is flushed. + init: func() { + cache.flush() + }, + }, + + { + name: "missing first subranges", + offset: 0, + length: 10 * subrangeSize, + expectedLength: 10 * subrangeSize, + expectedFetchedBytes: 3 * subrangeSize, + expectedCachedBytes: 7 * subrangeSize, + init: func() { + // Delete first 3 subranges. + delete(cache.cache, cachingKeyObjectSubrange(name, 0*subrangeSize, 1*subrangeSize)) + delete(cache.cache, cachingKeyObjectSubrange(name, 1*subrangeSize, 2*subrangeSize)) + delete(cache.cache, cachingKeyObjectSubrange(name, 2*subrangeSize, 3*subrangeSize)) + }, + }, + + { + name: "missing last subranges", + offset: 0, + length: 10 * subrangeSize, + expectedLength: 10 * subrangeSize, + expectedFetchedBytes: 3 * subrangeSize, + expectedCachedBytes: 7 * subrangeSize, + init: func() { + // Delete last 3 subranges. + delete(cache.cache, cachingKeyObjectSubrange(name, 7*subrangeSize, 8*subrangeSize)) + delete(cache.cache, cachingKeyObjectSubrange(name, 8*subrangeSize, 9*subrangeSize)) + delete(cache.cache, cachingKeyObjectSubrange(name, 9*subrangeSize, 10*subrangeSize)) + }, + }, + + { + name: "missing middle subranges", + offset: 0, + length: 10 * subrangeSize, + expectedLength: 10 * subrangeSize, + expectedFetchedBytes: 3 * subrangeSize, + expectedCachedBytes: 7 * subrangeSize, + init: func() { + // Delete 3 subranges in the middle. + delete(cache.cache, cachingKeyObjectSubrange(name, 3*subrangeSize, 4*subrangeSize)) + delete(cache.cache, cachingKeyObjectSubrange(name, 4*subrangeSize, 5*subrangeSize)) + delete(cache.cache, cachingKeyObjectSubrange(name, 5*subrangeSize, 6*subrangeSize)) + }, + }, + + { + name: "missing everything except middle subranges", + offset: 0, + length: 10 * subrangeSize, + expectedLength: 10 * subrangeSize, + expectedFetchedBytes: 7 * subrangeSize, + expectedCachedBytes: 3 * subrangeSize, + init: func() { + // Delete all but 3 subranges in the middle, and keep unlimited number of ranged subrequests. + for i := int64(0); i < 10; i++ { + if i > 0 && i%3 == 0 { + continue + } + delete(cache.cache, cachingKeyObjectSubrange(name, i*subrangeSize, (i+1)*subrangeSize)) + } + }, + }, + + { + name: "missing everything except middle subranges, one subrequest only", + offset: 0, + length: 10 * subrangeSize, + expectedLength: 10 * subrangeSize, + expectedFetchedBytes: 7 * subrangeSize, + expectedCachedBytes: 3 * subrangeSize, + expectedRefetchedBytes: 3 * subrangeSize, // Entire object fetched, 3 subranges are "refetched". + maxGetRangeRequests: 1, + init: func() { + // Delete all but 3 subranges in the middle, but only allow 1 subrequest. + for i := int64(0); i < 10; i++ { + if i == 3 || i == 5 || i == 7 { + continue + } + delete(cache.cache, cachingKeyObjectSubrange(name, i*subrangeSize, (i+1)*subrangeSize)) + } + }, + }, + + { + name: "missing everything except middle subranges, two subrequests", + offset: 0, + length: 10 * subrangeSize, + expectedLength: 10 * subrangeSize, + expectedFetchedBytes: 7 * subrangeSize, + expectedCachedBytes: 3 * subrangeSize, + maxGetRangeRequests: 2, + init: func() { + // Delete all but one subranges in the middle, and allow 2 subrequests. They will be: 0-80000, 128000-160000. + for i := int64(0); i < 10; i++ { + if i == 5 || i == 6 || i == 7 { + continue + } + delete(cache.cache, cachingKeyObjectSubrange(name, i*subrangeSize, (i+1)*subrangeSize)) + } + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + if tc.init != nil { + tc.init() + } + + cfg := NewCachingBucketConfig() + cfg.CacheGetRange("chunks", cache, isTSDBChunkFile, subrangeSize, time.Hour, time.Hour, tc.maxGetRangeRequests) + + cachingBucket, err := NewCachingBucket(inmem, cfg, nil, nil) + testutil.Ok(t, err) + + verifyGetRange(t, cachingBucket, name, tc.offset, tc.length, tc.expectedLength) + testutil.Equals(t, tc.expectedCachedBytes, int64(promtest.ToFloat64(cachingBucket.fetchedGetRangeBytes.WithLabelValues(originCache, "chunks")))) + testutil.Equals(t, tc.expectedFetchedBytes, int64(promtest.ToFloat64(cachingBucket.fetchedGetRangeBytes.WithLabelValues(originBucket, "chunks")))) + testutil.Equals(t, tc.expectedRefetchedBytes, int64(promtest.ToFloat64(cachingBucket.refetchedGetRangeBytes.WithLabelValues(originCache, "chunks")))) + }) + } +} + +func verifyGetRange(t *testing.T, cachingBucket *CachingBucket, name string, offset, length int64, expectedLength int64) { + r, err := cachingBucket.GetRange(context.Background(), name, offset, length) + testutil.Ok(t, err) + + read, err := ioutil.ReadAll(r) + testutil.Ok(t, err) + testutil.Equals(t, expectedLength, int64(len(read))) + + for ix := 0; ix < len(read); ix++ { + if byte(ix)+byte(offset) != read[ix] { + t.Fatalf("bytes differ at position %d", ix) + } + } +} + +type cacheItem struct { + data []byte + exp time.Time +} + +type mockCache struct { + mu sync.Mutex + cache map[string]cacheItem +} + +func newMockCache() *mockCache { + c := &mockCache{} + c.flush() + return c +} + +func (m *mockCache) Store(_ context.Context, data map[string][]byte, ttl time.Duration) { + m.mu.Lock() + defer m.mu.Unlock() + + exp := time.Now().Add(ttl) + for key, val := range data { + m.cache[key] = cacheItem{data: val, exp: exp} + } +} + +func (m *mockCache) Fetch(_ context.Context, keys []string) map[string][]byte { + m.mu.Lock() + defer m.mu.Unlock() + + found := make(map[string][]byte, len(keys)) + + now := time.Now() + for _, k := range keys { + v, ok := m.cache[k] + if ok && now.Before(v.exp) { + found[k] = v.data + } + } + + return found +} + +func (m *mockCache) flush() { + m.cache = map[string]cacheItem{} +} + +func TestMergeRanges(t *testing.T) { + for ix, tc := range []struct { + input []rng + limit int64 + expected []rng + }{ + { + input: nil, + limit: 0, + expected: nil, + }, + + { + input: []rng{{start: 0, end: 100}, {start: 100, end: 200}, {start: 500, end: 1000}}, + limit: 0, + expected: []rng{{start: 0, end: 200}, {start: 500, end: 1000}}, + }, + + { + input: []rng{{start: 0, end: 100}, {start: 500, end: 1000}}, + limit: 300, + expected: []rng{{start: 0, end: 100}, {start: 500, end: 1000}}, + }, + { + input: []rng{{start: 0, end: 100}, {start: 500, end: 1000}}, + limit: 400, + expected: []rng{{start: 0, end: 1000}}, + }, + } { + t.Run(fmt.Sprintf("%d", ix), func(t *testing.T) { + testutil.Equals(t, tc.expected, mergeRanges(tc.input, tc.limit)) + }) + } +} + +func TestInvalidOffsetAndLength(t *testing.T) { + b := &testBucket{objstore.NewInMemBucket()} + + cfg := NewCachingBucketConfig() + cfg.CacheGetRange("chunks", newMockCache(), func(string) bool { return true }, 10000, time.Hour, time.Hour, 3) + + c, err := NewCachingBucket(b, cfg, nil, nil) + testutil.Ok(t, err) + + r, err := c.GetRange(context.Background(), "test", -1, 1000) + testutil.Equals(t, nil, r) + testutil.NotOk(t, err) + + r, err = c.GetRange(context.Background(), "test", 100, -1) + testutil.Equals(t, nil, r) + testutil.NotOk(t, err) +} + +type testBucket struct { + *objstore.InMemBucket +} + +func (b *testBucket) GetRange(ctx context.Context, name string, off, length int64) (io.ReadCloser, error) { + if off < 0 { + return nil, errors.Errorf("invalid offset: %d", off) + } + + if length <= 0 { + return nil, errors.Errorf("invalid length: %d", length) + } + + return b.InMemBucket.GetRange(ctx, name, off, length) +} + +func TestCachedIter(t *testing.T) { + inmem := objstore.NewInMemBucket() + testutil.Ok(t, inmem.Upload(context.Background(), "/file-1", strings.NewReader("hej"))) + testutil.Ok(t, inmem.Upload(context.Background(), "/file-2", strings.NewReader("ahoj"))) + testutil.Ok(t, inmem.Upload(context.Background(), "/file-3", strings.NewReader("hello"))) + testutil.Ok(t, inmem.Upload(context.Background(), "/file-4", strings.NewReader("ciao"))) + + allFiles := []string{"/file-1", "/file-2", "/file-3", "/file-4"} + + // We reuse cache between tests (!) + cache := newMockCache() + + const cfgName = "dirs" + cfg := NewCachingBucketConfig() + cfg.CacheIter(cfgName, cache, func(string) bool { return true }, 5*time.Minute, JSONIterCodec{}) + + cb, err := NewCachingBucket(inmem, cfg, nil, nil) + testutil.Ok(t, err) + + verifyIter(t, cb, allFiles, false, cfgName) + + testutil.Ok(t, inmem.Upload(context.Background(), "/file-5", strings.NewReader("nazdar"))) + verifyIter(t, cb, allFiles, true, cfgName) // Iter returns old response. + + cache.flush() + allFiles = append(allFiles, "/file-5") + verifyIter(t, cb, allFiles, false, cfgName) + + cache.flush() + + e := errors.Errorf("test error") + + // This iteration returns false. Result will not be cached. + testutil.Equals(t, e, cb.Iter(context.Background(), "/", func(_ string) error { + return e + })) + + // Nothing cached now. + verifyIter(t, cb, allFiles, false, cfgName) +} + +func verifyIter(t *testing.T, cb *CachingBucket, expectedFiles []string, expectedCache bool, cfgName string) { + hitsBefore := int(promtest.ToFloat64(cb.operationHits.WithLabelValues(opIter, cfgName))) + + col := iterCollector{} + testutil.Ok(t, cb.Iter(context.Background(), "/", col.collect)) + + hitsAfter := int(promtest.ToFloat64(cb.operationHits.WithLabelValues(opIter, cfgName))) + + sort.Strings(col.items) + testutil.Equals(t, expectedFiles, col.items) + + expectedHitsDiff := 0 + if expectedCache { + expectedHitsDiff = 1 + } + + testutil.Equals(t, expectedHitsDiff, hitsAfter-hitsBefore) +} + +type iterCollector struct { + items []string +} + +func (it *iterCollector) collect(s string) error { + it.items = append(it.items, s) + return nil +} + +func TestExists(t *testing.T) { + inmem := objstore.NewInMemBucket() + + // We reuse cache between tests (!) + cache := newMockCache() + + cfg := NewCachingBucketConfig() + const cfgName = "test" + cfg.CacheExists(cfgName, cache, matchAll, 10*time.Minute, 2*time.Minute) + + cb, err := NewCachingBucket(inmem, cfg, nil, nil) + testutil.Ok(t, err) + + verifyExists(t, cb, testFilename, false, false, cfgName) + + testutil.Ok(t, inmem.Upload(context.Background(), testFilename, strings.NewReader("hej"))) + verifyExists(t, cb, testFilename, false, true, cfgName) // Reused cache result. + cache.flush() + verifyExists(t, cb, testFilename, true, false, cfgName) + + testutil.Ok(t, inmem.Delete(context.Background(), testFilename)) + verifyExists(t, cb, testFilename, true, true, cfgName) // Reused cache result. + cache.flush() + verifyExists(t, cb, testFilename, false, false, cfgName) +} + +func TestExistsCachingDisabled(t *testing.T) { + inmem := objstore.NewInMemBucket() + + // We reuse cache between tests (!) + cache := newMockCache() + + cfg := NewCachingBucketConfig() + const cfgName = "test" + cfg.CacheExists(cfgName, cache, func(string) bool { return false }, 10*time.Minute, 2*time.Minute) + + cb, err := NewCachingBucket(inmem, cfg, nil, nil) + testutil.Ok(t, err) + + verifyExists(t, cb, testFilename, false, false, cfgName) + + testutil.Ok(t, inmem.Upload(context.Background(), testFilename, strings.NewReader("hej"))) + verifyExists(t, cb, testFilename, true, false, cfgName) + + testutil.Ok(t, inmem.Delete(context.Background(), testFilename)) + verifyExists(t, cb, testFilename, false, false, cfgName) +} + +func verifyExists(t *testing.T, cb *CachingBucket, file string, exists bool, fromCache bool, cfgName string) { + t.Helper() + hitsBefore := int(promtest.ToFloat64(cb.operationHits.WithLabelValues(opExists, cfgName))) + ok, err := cb.Exists(context.Background(), file) + testutil.Ok(t, err) + testutil.Equals(t, exists, ok) + hitsAfter := int(promtest.ToFloat64(cb.operationHits.WithLabelValues(opExists, cfgName))) + + if fromCache { + testutil.Equals(t, 1, hitsAfter-hitsBefore) + } else { + testutil.Equals(t, 0, hitsAfter-hitsBefore) + } +} + +func TestGet(t *testing.T) { + inmem := objstore.NewInMemBucket() + + // We reuse cache between tests (!) + cache := newMockCache() + + cfg := NewCachingBucketConfig() + const cfgName = "metafile" + cfg.CacheGet(cfgName, cache, matchAll, 1024, 10*time.Minute, 10*time.Minute, 2*time.Minute) + cfg.CacheExists(cfgName, cache, matchAll, 10*time.Minute, 2*time.Minute) + + cb, err := NewCachingBucket(inmem, cfg, nil, nil) + testutil.Ok(t, err) + + verifyGet(t, cb, testFilename, nil, false, cfgName) + verifyExists(t, cb, testFilename, false, true, cfgName) + + data := []byte("hello world") + testutil.Ok(t, inmem.Upload(context.Background(), testFilename, bytes.NewBuffer(data))) + + // Even if file is now uploaded, old data is served from cache. + verifyGet(t, cb, testFilename, nil, true, cfgName) + verifyExists(t, cb, testFilename, false, true, cfgName) + + cache.flush() + + verifyGet(t, cb, testFilename, data, false, cfgName) + verifyGet(t, cb, testFilename, data, true, cfgName) + verifyExists(t, cb, testFilename, true, true, cfgName) +} + +func TestGetTooBigObject(t *testing.T) { + inmem := objstore.NewInMemBucket() + + // We reuse cache between tests (!) + cache := newMockCache() + + cfg := NewCachingBucketConfig() + const cfgName = "metafile" + // Only allow 5 bytes to be cached. + cfg.CacheGet(cfgName, cache, matchAll, 5, 10*time.Minute, 10*time.Minute, 2*time.Minute) + cfg.CacheExists(cfgName, cache, matchAll, 10*time.Minute, 2*time.Minute) + + cb, err := NewCachingBucket(inmem, cfg, nil, nil) + testutil.Ok(t, err) + + data := []byte("hello world") + testutil.Ok(t, inmem.Upload(context.Background(), testFilename, bytes.NewBuffer(data))) + + // Object is too big, so it will not be stored to cache on first read. + verifyGet(t, cb, testFilename, data, false, cfgName) + verifyGet(t, cb, testFilename, data, false, cfgName) + verifyExists(t, cb, testFilename, true, true, cfgName) +} + +func TestGetPartialRead(t *testing.T) { + inmem := objstore.NewInMemBucket() + + cache := newMockCache() + + cfg := NewCachingBucketConfig() + const cfgName = "metafile" + cfg.CacheGet(cfgName, cache, matchAll, 1024, 10*time.Minute, 10*time.Minute, 2*time.Minute) + cfg.CacheExists(cfgName, cache, matchAll, 10*time.Minute, 2*time.Minute) + + cb, err := NewCachingBucket(inmem, cfg, nil, nil) + testutil.Ok(t, err) + + data := []byte("hello world") + testutil.Ok(t, inmem.Upload(context.Background(), testFilename, bytes.NewBuffer(data))) + + // Read only few bytes from data. + r, err := cb.Get(context.Background(), testFilename) + testutil.Ok(t, err) + _, err = r.Read(make([]byte, 1)) + testutil.Ok(t, err) + testutil.Ok(t, r.Close()) + + // Object wasn't cached as it wasn't fully read. + verifyGet(t, cb, testFilename, data, false, cfgName) + // VerifyGet read object, so now it's cached. + verifyGet(t, cb, testFilename, data, true, cfgName) +} + +func verifyGet(t *testing.T, cb *CachingBucket, file string, expectedData []byte, cacheUsed bool, cfgName string) { + hitsBefore := int(promtest.ToFloat64(cb.operationHits.WithLabelValues(opGet, cfgName))) + + r, err := cb.Get(context.Background(), file) + if expectedData == nil { + testutil.Assert(t, cb.IsObjNotFoundErr(err)) + + hitsAfter := int(promtest.ToFloat64(cb.operationHits.WithLabelValues(opGet, cfgName))) + if cacheUsed { + testutil.Equals(t, 1, hitsAfter-hitsBefore) + } else { + testutil.Equals(t, 0, hitsAfter-hitsBefore) + } + } else { + testutil.Ok(t, err) + defer runutil.CloseWithLogOnErr(nil, r, "verifyGet") + data, err := ioutil.ReadAll(r) + testutil.Ok(t, err) + testutil.Equals(t, expectedData, data) + + hitsAfter := int(promtest.ToFloat64(cb.operationHits.WithLabelValues(opGet, cfgName))) + if cacheUsed { + testutil.Equals(t, 1, hitsAfter-hitsBefore) + } else { + testutil.Equals(t, 0, hitsAfter-hitsBefore) + } + } +} + +func TestObjectSize(t *testing.T) { + inmem := objstore.NewInMemBucket() + + // We reuse cache between tests (!) + cache := newMockCache() + + cfg := NewCachingBucketConfig() + const cfgName = "test" + cfg.CacheObjectSize(cfgName, cache, matchAll, time.Minute) + + cb, err := NewCachingBucket(inmem, cfg, nil, nil) + testutil.Ok(t, err) + + verifyObjectSize(t, cb, testFilename, -1, false, cfgName) + verifyObjectSize(t, cb, testFilename, -1, false, cfgName) // ObjectSize doesn't cache non-existent files. + + data := []byte("hello world") + testutil.Ok(t, inmem.Upload(context.Background(), testFilename, bytes.NewBuffer(data))) + + verifyObjectSize(t, cb, testFilename, len(data), false, cfgName) + verifyObjectSize(t, cb, testFilename, len(data), true, cfgName) +} + +func verifyObjectSize(t *testing.T, cb *CachingBucket, file string, expectedLength int, cacheUsed bool, cfgName string) { + t.Helper() + hitsBefore := int(promtest.ToFloat64(cb.operationHits.WithLabelValues(opObjectSize, cfgName))) + + length, err := cb.ObjectSize(context.Background(), file) + if expectedLength < 0 { + testutil.Assert(t, cb.IsObjNotFoundErr(err)) + } else { + testutil.Ok(t, err) + testutil.Equals(t, uint64(expectedLength), length) + + hitsAfter := int(promtest.ToFloat64(cb.operationHits.WithLabelValues(opObjectSize, cfgName))) + if cacheUsed { + testutil.Equals(t, 1, hitsAfter-hitsBefore) + } else { + testutil.Equals(t, 0, hitsAfter-hitsBefore) + } + } +} + +func matchAll(string) bool { return true } diff --git a/pkg/store/cache/inmemory.go b/pkg/store/cache/inmemory.go index 739d73b5bb..f91ec5de48 100644 --- a/pkg/store/cache/inmemory.go +++ b/pkg/store/cache/inmemory.go @@ -5,7 +5,6 @@ package storecache import ( "context" - "math" "reflect" "sync" "unsafe" @@ -16,7 +15,9 @@ import ( "github.com/oklog/ulid" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/pkg/labels" + "github.com/thanos-io/thanos/pkg/model" "gopkg.in/yaml.v2" ) @@ -27,6 +28,8 @@ var ( } ) +const maxInt = int(^uint(0) >> 1) + type InMemoryIndexCache struct { mtx sync.Mutex @@ -50,9 +53,9 @@ type InMemoryIndexCache struct { // InMemoryIndexCacheConfig holds the in-memory index cache config. type InMemoryIndexCacheConfig struct { // MaxSize represents overall maximum number of bytes cache can contain. - MaxSize Bytes `yaml:"max_size"` + MaxSize model.Bytes `yaml:"max_size"` // MaxItemSize represents maximum size of single item. - MaxItemSize Bytes `yaml:"max_item_size"` + MaxItemSize model.Bytes `yaml:"max_item_size"` } // parseInMemoryIndexCacheConfig unmarshals a buffer into a InMemoryIndexCacheConfig with default values. @@ -89,81 +92,78 @@ func NewInMemoryIndexCacheWithConfig(logger log.Logger, reg prometheus.Registere maxItemSizeBytes: uint64(config.MaxItemSize), } - c.evicted = prometheus.NewCounterVec(prometheus.CounterOpts{ + c.evicted = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_store_index_cache_items_evicted_total", Help: "Total number of items that were evicted from the index cache.", }, []string{"item_type"}) c.evicted.WithLabelValues(cacheTypePostings) c.evicted.WithLabelValues(cacheTypeSeries) - c.added = prometheus.NewCounterVec(prometheus.CounterOpts{ + c.added = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_store_index_cache_items_added_total", Help: "Total number of items that were added to the index cache.", }, []string{"item_type"}) c.added.WithLabelValues(cacheTypePostings) c.added.WithLabelValues(cacheTypeSeries) - c.requests = prometheus.NewCounterVec(prometheus.CounterOpts{ + c.requests = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_store_index_cache_requests_total", Help: "Total number of requests to the cache.", }, []string{"item_type"}) c.requests.WithLabelValues(cacheTypePostings) c.requests.WithLabelValues(cacheTypeSeries) - c.overflow = prometheus.NewCounterVec(prometheus.CounterOpts{ + c.overflow = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_store_index_cache_items_overflowed_total", Help: "Total number of items that could not be added to the cache due to being too big.", }, []string{"item_type"}) c.overflow.WithLabelValues(cacheTypePostings) c.overflow.WithLabelValues(cacheTypeSeries) - c.hits = prometheus.NewCounterVec(prometheus.CounterOpts{ + c.hits = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_store_index_cache_hits_total", Help: "Total number of requests to the cache that were a hit.", }, []string{"item_type"}) c.hits.WithLabelValues(cacheTypePostings) c.hits.WithLabelValues(cacheTypeSeries) - c.current = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + c.current = promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ Name: "thanos_store_index_cache_items", Help: "Current number of items in the index cache.", }, []string{"item_type"}) c.current.WithLabelValues(cacheTypePostings) c.current.WithLabelValues(cacheTypeSeries) - c.currentSize = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + c.currentSize = promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ Name: "thanos_store_index_cache_items_size_bytes", Help: "Current byte size of items in the index cache.", }, []string{"item_type"}) c.currentSize.WithLabelValues(cacheTypePostings) c.currentSize.WithLabelValues(cacheTypeSeries) - c.totalCurrentSize = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + c.totalCurrentSize = promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ Name: "thanos_store_index_cache_total_size_bytes", Help: "Current byte size of items (both value and key) in the index cache.", }, []string{"item_type"}) c.totalCurrentSize.WithLabelValues(cacheTypePostings) c.totalCurrentSize.WithLabelValues(cacheTypeSeries) - if reg != nil { - reg.MustRegister(prometheus.NewGaugeFunc(prometheus.GaugeOpts{ - Name: "thanos_store_index_cache_max_size_bytes", - Help: "Maximum number of bytes to be held in the index cache.", - }, func() float64 { - return float64(c.maxSizeBytes) - })) - reg.MustRegister(prometheus.NewGaugeFunc(prometheus.GaugeOpts{ - Name: "thanos_store_index_cache_max_item_size_bytes", - Help: "Maximum number of bytes for single entry to be held in the index cache.", - }, func() float64 { - return float64(c.maxItemSizeBytes) - })) - reg.MustRegister(c.requests, c.hits, c.added, c.evicted, c.current, c.currentSize, c.totalCurrentSize, c.overflow) - } + _ = promauto.With(reg).NewGaugeFunc(prometheus.GaugeOpts{ + Name: "thanos_store_index_cache_max_size_bytes", + Help: "Maximum number of bytes to be held in the index cache.", + }, func() float64 { + return float64(c.maxSizeBytes) + }) + _ = promauto.With(reg).NewGaugeFunc(prometheus.GaugeOpts{ + Name: "thanos_store_index_cache_max_item_size_bytes", + Help: "Maximum number of bytes for single entry to be held in the index cache.", + }, func() float64 { + return float64(c.maxItemSizeBytes) + }) // Initialize LRU cache with a high size limit since we will manage evictions ourselves // based on stored size using `RemoveOldest` method. - l, err := lru.NewLRU(math.MaxInt64, c.onEvict) + l, err := lru.NewLRU(maxInt, c.onEvict) if err != nil { return nil, err } @@ -173,7 +173,7 @@ func NewInMemoryIndexCacheWithConfig(logger log.Logger, reg prometheus.Registere "msg", "created in-memory index cache", "maxItemSizeBytes", c.maxItemSizeBytes, "maxSizeBytes", c.maxSizeBytes, - "maxItems", "math.MaxInt64", + "maxItems", "maxInt", ) return c, nil } diff --git a/pkg/store/cache/inmemory_test.go b/pkg/store/cache/inmemory_test.go index 460c5c8c73..c10cb2dcf6 100644 --- a/pkg/store/cache/inmemory_test.go +++ b/pkg/store/cache/inmemory_test.go @@ -260,7 +260,7 @@ func TestInMemoryIndexCache_Eviction_WithMetrics(t *testing.T) { testutil.Equals(t, float64(0), promtest.ToFloat64(cache.evicted.WithLabelValues(cacheTypeSeries))) pHits, pMisses = cache.FetchMultiPostings(ctx, id, []labels.Label{lbls}) - testutil.Equals(t, map[labels.Label][]byte{lbls: []byte{42, 33}}, pHits, "key exists") + testutil.Equals(t, map[labels.Label][]byte{lbls: {42, 33}}, pHits, "key exists") testutil.Equals(t, emptyPostingsMisses, pMisses) pHits, pMisses = cache.FetchMultiPostings(ctx, ulid.MustNew(1, nil), []labels.Label{lbls}) @@ -286,7 +286,7 @@ func TestInMemoryIndexCache_Eviction_WithMetrics(t *testing.T) { testutil.Equals(t, float64(0), promtest.ToFloat64(cache.evicted.WithLabelValues(cacheTypeSeries))) sHits, sMisses := cache.FetchMultiSeries(ctx, id, []uint64{1234}) - testutil.Equals(t, map[uint64][]byte{1234: []byte{222, 223, 224}}, sHits, "key exists") + testutil.Equals(t, map[uint64][]byte{1234: {222, 223, 224}}, sHits, "key exists") testutil.Equals(t, emptySeriesMisses, sMisses) lbls2 := labels.Label{Name: "test", Value: "124"} @@ -391,7 +391,7 @@ func TestInMemoryIndexCache_Eviction_WithMetrics(t *testing.T) { testutil.Equals(t, float64(1), promtest.ToFloat64(cache.evicted.WithLabelValues(cacheTypeSeries))) pHits, pMisses = cache.FetchMultiPostings(ctx, id, []labels.Label{lbls3}) - testutil.Equals(t, map[labels.Label][]byte{lbls3: []byte{}}, pHits, "key exists") + testutil.Equals(t, map[labels.Label][]byte{lbls3: {}}, pHits, "key exists") testutil.Equals(t, emptyPostingsMisses, pMisses) // nil works and still allocates empty slice. @@ -411,7 +411,7 @@ func TestInMemoryIndexCache_Eviction_WithMetrics(t *testing.T) { testutil.Equals(t, float64(1), promtest.ToFloat64(cache.evicted.WithLabelValues(cacheTypeSeries))) pHits, pMisses = cache.FetchMultiPostings(ctx, id, []labels.Label{lbls4}) - testutil.Equals(t, map[labels.Label][]byte{lbls4: []byte{}}, pHits, "key exists") + testutil.Equals(t, map[labels.Label][]byte{lbls4: {}}, pHits, "key exists") testutil.Equals(t, emptyPostingsMisses, pMisses) // Other metrics. diff --git a/pkg/store/cache/memcached.go b/pkg/store/cache/memcached.go index db7ec61c63..74ce30299e 100644 --- a/pkg/store/cache/memcached.go +++ b/pkg/store/cache/memcached.go @@ -11,6 +11,7 @@ import ( "github.com/go-kit/kit/log/level" "github.com/oklog/ulid" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/pkg/labels" "github.com/thanos-io/thanos/pkg/cacheutil" ) @@ -36,24 +37,20 @@ func NewMemcachedIndexCache(logger log.Logger, memcached cacheutil.MemcachedClie memcached: memcached, } - c.requests = prometheus.NewCounterVec(prometheus.CounterOpts{ + c.requests = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_store_index_cache_requests_total", Help: "Total number of items requests to the cache.", }, []string{"item_type"}) c.requests.WithLabelValues(cacheTypePostings) c.requests.WithLabelValues(cacheTypeSeries) - c.hits = prometheus.NewCounterVec(prometheus.CounterOpts{ + c.hits = promauto.With(reg).NewCounterVec(prometheus.CounterOpts{ Name: "thanos_store_index_cache_hits_total", Help: "Total number of items requests to the cache that were a hit.", }, []string{"item_type"}) c.hits.WithLabelValues(cacheTypePostings) c.hits.WithLabelValues(cacheTypeSeries) - if reg != nil { - reg.MustRegister(c.requests, c.hits) - } - level.Info(logger).Log("msg", "created memcached index cache") return c, nil diff --git a/pkg/store/hintspb/custom.go b/pkg/store/hintspb/custom.go new file mode 100644 index 0000000000..91c081a9fa --- /dev/null +++ b/pkg/store/hintspb/custom.go @@ -0,0 +1,12 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package hintspb + +import "github.com/oklog/ulid" + +func (m *SeriesResponseHints) AddQueriedBlock(id ulid.ULID) { + m.QueriedBlocks = append(m.QueriedBlocks, Block{ + Id: id.String(), + }) +} diff --git a/pkg/store/hintspb/hints.pb.go b/pkg/store/hintspb/hints.pb.go new file mode 100644 index 0000000000..42a4f4e16e --- /dev/null +++ b/pkg/store/hintspb/hints.pb.go @@ -0,0 +1,492 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: hints.proto + +package hintspb + +import ( + fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" +) + +// 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.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type SeriesResponseHints struct { + /// queried_blocks is the list of blocks that have been queried. + QueriedBlocks []Block `protobuf:"bytes,1,rep,name=queried_blocks,json=queriedBlocks,proto3" json:"queried_blocks"` +} + +func (m *SeriesResponseHints) Reset() { *m = SeriesResponseHints{} } +func (m *SeriesResponseHints) String() string { return proto.CompactTextString(m) } +func (*SeriesResponseHints) ProtoMessage() {} +func (*SeriesResponseHints) Descriptor() ([]byte, []int) { + return fileDescriptor_522be8e0d2634375, []int{0} +} +func (m *SeriesResponseHints) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SeriesResponseHints) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SeriesResponseHints.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SeriesResponseHints) XXX_Merge(src proto.Message) { + xxx_messageInfo_SeriesResponseHints.Merge(m, src) +} +func (m *SeriesResponseHints) XXX_Size() int { + return m.Size() +} +func (m *SeriesResponseHints) XXX_DiscardUnknown() { + xxx_messageInfo_SeriesResponseHints.DiscardUnknown(m) +} + +var xxx_messageInfo_SeriesResponseHints proto.InternalMessageInfo + +type Block struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (m *Block) Reset() { *m = Block{} } +func (m *Block) String() string { return proto.CompactTextString(m) } +func (*Block) ProtoMessage() {} +func (*Block) Descriptor() ([]byte, []int) { + return fileDescriptor_522be8e0d2634375, []int{1} +} +func (m *Block) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Block) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Block.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Block) XXX_Merge(src proto.Message) { + xxx_messageInfo_Block.Merge(m, src) +} +func (m *Block) XXX_Size() int { + return m.Size() +} +func (m *Block) XXX_DiscardUnknown() { + xxx_messageInfo_Block.DiscardUnknown(m) +} + +var xxx_messageInfo_Block proto.InternalMessageInfo + +func init() { + proto.RegisterType((*SeriesResponseHints)(nil), "hintspb.SeriesResponseHints") + proto.RegisterType((*Block)(nil), "hintspb.Block") +} + +func init() { proto.RegisterFile("hints.proto", fileDescriptor_522be8e0d2634375) } + +var fileDescriptor_522be8e0d2634375 = []byte{ + // 182 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xce, 0xc8, 0xcc, 0x2b, + 0x29, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x07, 0x73, 0x0a, 0x92, 0xa4, 0x44, 0xd2, + 0xf3, 0xd3, 0xf3, 0xc1, 0x62, 0xfa, 0x20, 0x16, 0x44, 0x5a, 0x29, 0x88, 0x4b, 0x38, 0x38, 0xb5, + 0x28, 0x33, 0xb5, 0x38, 0x28, 0xb5, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0xd5, 0x03, 0xa4, 0x5c, 0xc8, + 0x9a, 0x8b, 0xaf, 0xb0, 0x14, 0x24, 0x9e, 0x12, 0x9f, 0x94, 0x93, 0x9f, 0x9c, 0x5d, 0x2c, 0xc1, + 0xa8, 0xc0, 0xac, 0xc1, 0x6d, 0xc4, 0xa7, 0x07, 0x35, 0x4e, 0xcf, 0x09, 0x24, 0xec, 0xc4, 0x72, + 0xe2, 0x9e, 0x3c, 0x43, 0x10, 0x2f, 0x54, 0x2d, 0x58, 0xac, 0x58, 0x49, 0x9c, 0x8b, 0x15, 0xcc, + 0x12, 0xe2, 0xe3, 0x62, 0xca, 0x4c, 0x91, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x62, 0xca, 0x4c, + 0x71, 0x52, 0x3d, 0xf1, 0x50, 0x8e, 0xe1, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, + 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, + 0xa2, 0x60, 0x2e, 0x4d, 0x62, 0x03, 0x3b, 0xcd, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x84, 0x7b, + 0x43, 0xa2, 0xc8, 0x00, 0x00, 0x00, +} + +func (m *SeriesResponseHints) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SeriesResponseHints) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SeriesResponseHints) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.QueriedBlocks) > 0 { + for iNdEx := len(m.QueriedBlocks) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.QueriedBlocks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintHints(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *Block) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Block) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Block) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintHints(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintHints(dAtA []byte, offset int, v uint64) int { + offset -= sovHints(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *SeriesResponseHints) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.QueriedBlocks) > 0 { + for _, e := range m.QueriedBlocks { + l = e.Size() + n += 1 + l + sovHints(uint64(l)) + } + } + return n +} + +func (m *Block) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovHints(uint64(l)) + } + return n +} + +func sovHints(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozHints(x uint64) (n int) { + return sovHints(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *SeriesResponseHints) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHints + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SeriesResponseHints: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SeriesResponseHints: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field QueriedBlocks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHints + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthHints + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthHints + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.QueriedBlocks = append(m.QueriedBlocks, Block{}) + if err := m.QueriedBlocks[len(m.QueriedBlocks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipHints(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthHints + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthHints + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Block) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHints + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Block: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Block: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHints + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthHints + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthHints + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipHints(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthHints + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthHints + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipHints(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowHints + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowHints + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowHints + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthHints + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupHints + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthHints + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthHints = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowHints = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupHints = fmt.Errorf("proto: unexpected end of group") +) diff --git a/pkg/store/hintspb/hints.proto b/pkg/store/hintspb/hints.proto new file mode 100644 index 0000000000..2bd4a6cc23 --- /dev/null +++ b/pkg/store/hintspb/hints.proto @@ -0,0 +1,28 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +syntax = "proto3"; +package hintspb; + +import "gogoproto/gogo.proto"; + +option go_package = "hintspb"; + +option (gogoproto.sizer_all) = true; +option (gogoproto.marshaler_all) = true; +option (gogoproto.unmarshaler_all) = true; +option (gogoproto.goproto_getters_all) = false; + +// Do not generate XXX fields to reduce memory. +option (gogoproto.goproto_unkeyed_all) = false; +option (gogoproto.goproto_unrecognized_all) = false; +option (gogoproto.goproto_sizecache_all) = false; + +message SeriesResponseHints { + /// queried_blocks is the list of blocks that have been queried. + repeated Block queried_blocks = 1 [(gogoproto.nullable) = false]; +} + +message Block { + string id = 1; +} diff --git a/pkg/store/local.go b/pkg/store/local.go new file mode 100644 index 0000000000..90c174e79e --- /dev/null +++ b/pkg/store/local.go @@ -0,0 +1,311 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package store + +import ( + "bufio" + "bytes" + "context" + "io" + "math" + "sort" + + "github.com/go-kit/kit/log" + "github.com/go-kit/kit/log/level" + "github.com/gogo/protobuf/jsonpb" + "github.com/pkg/errors" + "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/tsdb/fileutil" + "github.com/thanos-io/thanos/pkg/component" + "github.com/thanos-io/thanos/pkg/runutil" + "github.com/thanos-io/thanos/pkg/store/storepb" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// LocalStore implements the store API against single file with stream of proto-based SeriesResponses in JSON format. +// Inefficient implementation for quick StoreAPI view. +// Chunk order is exactly the same as in a given file. +type LocalStore struct { + logger log.Logger + extLabels labels.Labels + + info *storepb.InfoResponse + c io.Closer + + // TODO(bwplotka): This is very naive in-memory DB. We can support much larger files, by + // indexing labels, symbolizing strings and get chunk refs only without storing protobufs in memory. + // For small debug purposes, this is good enough. + series []*storepb.Series + sortedChunks [][]int +} + +// TODO(bwplotka): Add remote read so Prometheus users can use this. Potentially after streaming will be added +// https://github.com/prometheus/prometheus/issues/5926. +// TODO(bwplotka): Consider non mmaped version of this, as well different versions. +func NewLocalStoreFromJSONMmappableFile( + logger log.Logger, + component component.StoreAPI, + extLabels labels.Labels, + path string, + split bufio.SplitFunc, +) (*LocalStore, error) { + f, err := fileutil.OpenMmapFile(path) + if err != nil { + return nil, err + } + defer func() { + if err != nil { + runutil.CloseWithErrCapture(&err, f, "json file %s close", path) + } + }() + + s := &LocalStore{ + logger: logger, + extLabels: extLabels, + c: f, + info: &storepb.InfoResponse{ + LabelSets: []storepb.LabelSet{ + {Labels: storepb.PromLabelsToLabelsUnsafe(extLabels)}, + }, + StoreType: component.ToProto(), + MinTime: math.MaxInt64, + MaxTime: math.MinInt64, + }, + } + + // Do quick pass for in-mem index. + content := f.Bytes() + contentStart := bytes.Index(content, []byte("{")) + if contentStart != -1 { + content = content[contentStart:] + } + + if idx := bytes.LastIndex(content, []byte("}")); idx != -1 { + content = content[:idx+1] + } + + scanner := NewNoCopyScanner(content, split) + resp := &storepb.SeriesResponse{} + for scanner.Scan() { + if err := jsonpb.Unmarshal(bytes.NewReader(scanner.Bytes()), resp); err != nil { + return nil, errors.Wrapf(err, "unmarshal storepb.SeriesResponse frame for file %s", path) + } + series := resp.GetSeries() + if series == nil { + level.Warn(logger).Log("msg", "not a valid series", "frame", resp.String()) + continue + } + chks := make([]int, 0, len(series.Chunks)) + // Sort chunks in separate slice by MinTime for easier lookup. Find global max and min. + for ci, c := range series.Chunks { + if s.info.MinTime > c.MinTime { + s.info.MinTime = c.MinTime + } + if s.info.MaxTime < c.MaxTime { + s.info.MaxTime = c.MaxTime + } + chks = append(chks, ci) + } + + sort.Slice(chks, func(i, j int) bool { + return series.Chunks[chks[i]].MinTime < series.Chunks[chks[j]].MinTime + }) + s.series = append(s.series, series) + s.sortedChunks = append(s.sortedChunks, chks) + } + + if err := scanner.Err(); err != nil { + return nil, errors.Wrapf(err, "scanning file %s", path) + } + level.Info(logger).Log("msg", "loading JSON file succeeded", "file", path, "info", s.info.String(), "series", len(s.series)) + return s, nil +} + +// ScanGRPCCurlProtoStreamMessages allows to tokenize each streamed gRPC message from grpcurl tool. +func ScanGRPCCurlProtoStreamMessages(data []byte, atEOF bool) (advance int, token []byte, err error) { + var delim = []byte(`} +{`) + if atEOF && len(data) == 0 { + return 0, nil, nil + } + if idx := bytes.LastIndex(data, delim); idx != -1 { + return idx + 2, data[:idx+1], nil + } + // If we're at EOF, let's return all. + if atEOF { + return len(data), data, nil + } + // Incomplete; get more bytes. + return len(delim), nil, nil +} + +// Info returns store information about the Prometheus instance. +func (s *LocalStore) Info(_ context.Context, _ *storepb.InfoRequest) (*storepb.InfoResponse, error) { + return s.info, nil +} + +// Series returns all series for a requested time range and label matcher. The returned data may +// exceed the requested time bounds. +func (s *LocalStore) Series(r *storepb.SeriesRequest, srv storepb.Store_SeriesServer) error { + match, newMatchers, err := matchesExternalLabels(r.Matchers, s.extLabels) + if err != nil { + return status.Error(codes.InvalidArgument, err.Error()) + } + if !match { + return nil + } + if len(newMatchers) == 0 { + return status.Error(codes.InvalidArgument, errors.New("no matchers specified (excluding external labels)").Error()) + } + matchers, err := translateMatchers(newMatchers) + if err != nil { + return status.Error(codes.InvalidArgument, err.Error()) + } + + var chosen []int + for si, series := range s.series { + lbls := storepb.LabelsToPromLabelsUnsafe(series.Labels) + var noMatch bool + for _, m := range matchers { + extValue := lbls.Get(m.Name) + if extValue == "" { + continue + } + if !m.Matches(extValue) { + noMatch = true + break + } + } + if noMatch { + continue + } + + chosen = chosen[:0] + resp := &storepb.Series{ + Labels: series.Labels, + Chunks: make([]storepb.AggrChunk, 0, len(s.sortedChunks[si])), + } + + for _, ci := range s.sortedChunks[si] { + if series.Chunks[ci].MaxTime < r.MinTime { + continue + } + if series.Chunks[ci].MinTime > r.MaxTime { + continue + } + chosen = append(chosen, ci) + } + + sort.Ints(chosen) + for _, ci := range chosen { + resp.Chunks = append(resp.Chunks, series.Chunks[ci]) + } + + if err := srv.Send(storepb.NewSeriesResponse(resp)); err != nil { + return status.Error(codes.Aborted, err.Error()) + } + } + return nil +} + +// LabelNames returns all known label names. +func (s *LocalStore) LabelNames(_ context.Context, _ *storepb.LabelNamesRequest) ( + *storepb.LabelNamesResponse, error, +) { + // TODO(bwplotka): Consider precomputing. + names := map[string]struct{}{} + for _, series := range s.series { + for _, l := range series.Labels { + names[l.Name] = struct{}{} + } + } + resp := &storepb.LabelNamesResponse{} + for n := range names { + resp.Names = append(resp.Names, n) + } + return resp, nil +} + +// LabelValues returns all known label values for a given label name. +func (s *LocalStore) LabelValues(_ context.Context, r *storepb.LabelValuesRequest) ( + *storepb.LabelValuesResponse, error, +) { + vals := map[string]struct{}{} + for _, series := range s.series { + lbls := storepb.LabelsToPromLabelsUnsafe(series.Labels) + val := lbls.Get(r.Label) + if val == "" { + continue + } + vals[val] = struct{}{} + } + resp := &storepb.LabelValuesResponse{} + for val := range vals { + resp.Values = append(resp.Values, val) + } + return resp, nil +} + +func (s *LocalStore) Close() (err error) { + return s.c.Close() +} + +type noCopyScanner struct { + b []byte + splitFunc bufio.SplitFunc + + start, end int + err error + + token []byte +} + +// NewNoCopyScanner returns bufio.Scanner-like scanner that is meant to be used on already allocated byte slice (or mmapped) +// one. Returned tokens are shared. +func NewNoCopyScanner(b []byte, splitFunc bufio.SplitFunc) *noCopyScanner { + return &noCopyScanner{ + b: b, + splitFunc: splitFunc, + start: 0, + end: 0, + } +} + +func (s *noCopyScanner) Scan() bool { + if s.start >= len(s.b) { + return false + } + + advance := 1 + for s.end+advance < len(s.b) { + s.end += advance + + advance, s.token, s.err = s.splitFunc(s.b[s.start:s.end], false) + if s.err != nil { + return false + } + + if len(s.token) > 0 { + s.start += advance + s.end = s.start + return true + } + } + + _, s.token, s.err = s.splitFunc(s.b[s.start:], true) + if s.err != nil { + return false + } + s.start = len(s.b) + return len(s.token) > 0 +} + +func (s *noCopyScanner) Bytes() []byte { + return s.token +} + +func (s *noCopyScanner) Err() error { + return s.err +} diff --git a/pkg/store/matchers.go b/pkg/store/matchers.go new file mode 100644 index 0000000000..46c6e9a9ea --- /dev/null +++ b/pkg/store/matchers.go @@ -0,0 +1,38 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package store + +import ( + "github.com/pkg/errors" + "github.com/prometheus/prometheus/pkg/labels" + "github.com/thanos-io/thanos/pkg/store/storepb" +) + +func translateMatcher(m storepb.LabelMatcher) (*labels.Matcher, error) { + switch m.Type { + case storepb.LabelMatcher_EQ: + return labels.NewMatcher(labels.MatchEqual, m.Name, m.Value) + + case storepb.LabelMatcher_NEQ: + return labels.NewMatcher(labels.MatchNotEqual, m.Name, m.Value) + + case storepb.LabelMatcher_RE: + return labels.NewMatcher(labels.MatchRegexp, m.Name, m.Value) + + case storepb.LabelMatcher_NRE: + return labels.NewMatcher(labels.MatchNotRegexp, m.Name, m.Value) + } + return nil, errors.Errorf("unknown label matcher type %d", m.Type) +} + +func translateMatchers(ms []storepb.LabelMatcher) (res []*labels.Matcher, err error) { + for _, m := range ms { + r, err := translateMatcher(m) + if err != nil { + return nil, err + } + res = append(res, r) + } + return res, nil +} diff --git a/pkg/store/multitsdb.go b/pkg/store/multitsdb.go new file mode 100644 index 0000000000..e1acea5514 --- /dev/null +++ b/pkg/store/multitsdb.go @@ -0,0 +1,285 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package store + +import ( + "context" + "fmt" + "sync" + + "github.com/go-kit/kit/log" + grpc_opentracing "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing" + "github.com/opentracing/opentracing-go" + "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" + "github.com/thanos-io/thanos/pkg/component" + "github.com/thanos-io/thanos/pkg/store/storepb" + "golang.org/x/sync/errgroup" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// MultiTSDBStore implements the Store interface backed by multiple TSDBStore instances. +type MultiTSDBStore struct { + logger log.Logger + component component.SourceStoreAPI + tsdbStores func() map[string]*TSDBStore +} + +// NewMultiTSDBStore creates a new MultiTSDBStore. +func NewMultiTSDBStore(logger log.Logger, _ prometheus.Registerer, component component.SourceStoreAPI, tsdbStores func() map[string]*TSDBStore) *MultiTSDBStore { + if logger == nil { + logger = log.NewNopLogger() + } + return &MultiTSDBStore{ + logger: logger, + component: component, + tsdbStores: tsdbStores, + } +} + +// Info returns store merged information about the underlying TSDBStore instances. +func (s *MultiTSDBStore) Info(ctx context.Context, req *storepb.InfoRequest) (*storepb.InfoResponse, error) { + stores := s.tsdbStores() + + resp := &storepb.InfoResponse{ + StoreType: s.component.ToProto(), + } + if len(stores) == 0 { + return resp, nil + } + + infos := make([]*storepb.InfoResponse, 0, len(stores)) + for tenant, store := range stores { + info, err := store.Info(ctx, req) + if err != nil { + return nil, errors.Wrapf(err, "get info for tenant %s", tenant) + } + infos = append(infos, info) + } + + resp.MinTime = infos[0].MinTime + resp.MaxTime = infos[0].MaxTime + + for i := 1; i < len(infos); i++ { + if resp.MinTime > infos[i].MinTime { + resp.MinTime = infos[i].MinTime + } + if resp.MaxTime < infos[i].MaxTime { + resp.MaxTime = infos[i].MaxTime + } + } + + // We can rely on every underlying TSDB to only have one labelset, so this + // will always allocate the correct length immediately. + resp.LabelSets = make([]storepb.LabelSet, 0, len(infos)) + for _, info := range infos { + resp.LabelSets = append(resp.LabelSets, info.LabelSets...) + } + + return resp, nil +} + +type tenantSeriesSetServer struct { + grpc.ServerStream + + ctx context.Context + + warnCh warnSender + recv chan *storepb.Series + cur *storepb.Series + + err error + tenant string +} + +func newTenantSeriesSetServer( + ctx context.Context, + tenant string, + warnCh warnSender, +) *tenantSeriesSetServer { + return &tenantSeriesSetServer{ + ctx: ctx, + tenant: tenant, + warnCh: warnCh, + recv: make(chan *storepb.Series), + } +} + +func (s *tenantSeriesSetServer) Context() context.Context { + return s.ctx +} + +func (s *tenantSeriesSetServer) Series(store *TSDBStore, r *storepb.SeriesRequest) { + err := store.Series(r, s) + if err != nil { + if r.PartialResponseDisabled { + s.err = errors.Wrapf(err, "get series for tenant %s", s.tenant) + } else { + // Consistently prefix tenant specific warnings as done in various other places. + err = errors.New(prefixTenantWarning(s.tenant, err.Error())) + s.warnCh.send(storepb.NewWarnSeriesResponse(err)) + } + } + + close(s.recv) +} + +func (s *tenantSeriesSetServer) Send(r *storepb.SeriesResponse) error { + series := r.GetSeries() + chunks := make([]storepb.AggrChunk, len(series.Chunks)) + copy(chunks, series.Chunks) + s.recv <- &storepb.Series{ + Labels: series.Labels, + Chunks: chunks, + } + return nil +} + +func (s *tenantSeriesSetServer) Next() (ok bool) { + s.cur, ok = <-s.recv + return ok +} + +func (s *tenantSeriesSetServer) At() ([]storepb.Label, []storepb.AggrChunk) { + if s.cur == nil { + return nil, nil + } + return s.cur.Labels, s.cur.Chunks +} + +func (s *tenantSeriesSetServer) Err() error { + return s.err +} + +// Series returns all series for a requested time range and label matcher. The +// returned data may exceed the requested time bounds. The data returned may +// have been read and merged from multiple underlying TSDBStore instances. +func (s *MultiTSDBStore) Series(r *storepb.SeriesRequest, srv storepb.Store_SeriesServer) error { + stores := s.tsdbStores() + if len(stores) == 0 { + return nil + } + + var ( + g, gctx = errgroup.WithContext(srv.Context()) + + // Allow to buffer max 10 series response. + // Each might be quite large (multi chunk long series given by sidecar). + respSender, respRecv, closeFn = newRespCh(gctx, 10) + ) + + g.Go(func() error { + var ( + seriesSet []storepb.SeriesSet + wg = &sync.WaitGroup{} + ) + + defer func() { + wg.Wait() + closeFn() + }() + + for tenant, store := range stores { + store := store + seriesCtx, cancelSeries := context.WithCancel(gctx) + seriesCtx = grpc_opentracing.ClientAddContextTags(seriesCtx, opentracing.Tags{ + "tenant": tenant, + }) + defer cancelSeries() + ss := newTenantSeriesSetServer(seriesCtx, tenant, respSender) + wg.Add(1) + go func() { + defer wg.Done() + ss.Series(store, r) + }() + + seriesSet = append(seriesSet, ss) + } + + mergedSet := storepb.MergeSeriesSets(seriesSet...) + for mergedSet.Next() { + var series storepb.Series + series.Labels, series.Chunks = mergedSet.At() + respSender.send(storepb.NewSeriesResponse(&series)) + } + return mergedSet.Err() + }) + + for resp := range respRecv { + if err := srv.Send(resp); err != nil { + return status.Error(codes.Unknown, errors.Wrap(err, "send series response").Error()) + } + } + + return g.Wait() +} + +// LabelNames returns all known label names. +func (s *MultiTSDBStore) LabelNames(ctx context.Context, req *storepb.LabelNamesRequest) (*storepb.LabelNamesResponse, error) { + names := map[string]struct{}{} + warnings := map[string]struct{}{} + + stores := s.tsdbStores() + for tenant, store := range stores { + r, err := store.LabelNames(ctx, req) + if err != nil { + return nil, errors.Wrapf(err, "get label names for tenant %s", tenant) + } + + for _, l := range r.Names { + names[l] = struct{}{} + } + + for _, l := range r.Warnings { + warnings[prefixTenantWarning(tenant, l)] = struct{}{} + } + } + + return &storepb.LabelNamesResponse{ + Names: keys(names), + Warnings: keys(warnings), + }, nil +} + +func prefixTenantWarning(tenant, s string) string { + return fmt.Sprintf("[%s] %s", tenant, s) +} + +func keys(m map[string]struct{}) []string { + res := make([]string, 0, len(m)) + for k := range m { + res = append(res, k) + } + + return res +} + +// LabelValues returns all known label values for a given label name. +func (s *MultiTSDBStore) LabelValues(ctx context.Context, req *storepb.LabelValuesRequest) (*storepb.LabelValuesResponse, error) { + values := map[string]struct{}{} + warnings := map[string]struct{}{} + + stores := s.tsdbStores() + for tenant, store := range stores { + r, err := store.LabelValues(ctx, req) + if err != nil { + return nil, errors.Wrapf(err, "get label values for tenant %s", tenant) + } + + for _, l := range r.Values { + values[l] = struct{}{} + } + + for _, l := range r.Warnings { + warnings[prefixTenantWarning(tenant, l)] = struct{}{} + } + } + + return &storepb.LabelValuesResponse{ + Values: keys(values), + Warnings: keys(warnings), + }, nil +} diff --git a/pkg/store/opts.go b/pkg/store/opts.go new file mode 100644 index 0000000000..e95a623a70 --- /dev/null +++ b/pkg/store/opts.go @@ -0,0 +1,63 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package store + +import ( + "strings" + "unicode/utf8" +) + +// Bitmap used by func isRegexMetaCharacter to check whether a character needs to be escaped. +var regexMetaCharacterBytes [16]byte + +// isRegexMetaCharacter reports whether byte b needs to be escaped. +func isRegexMetaCharacter(b byte) bool { + return b < utf8.RuneSelf && regexMetaCharacterBytes[b%16]&(1<<(b/16)) != 0 +} + +func init() { + for _, b := range []byte(`.+*?()|[]{}^$`) { + regexMetaCharacterBytes[b%16] |= 1 << (b / 16) + } +} + +// Copied from Prometheus querier.go, removed check for Prometheus wrapper. +// Returns list of values that can regex matches. +func findSetMatches(pattern string) []string { + escaped := false + sets := []*strings.Builder{{}} + for i := 0; i < len(pattern); i++ { + if escaped { + switch { + case isRegexMetaCharacter(pattern[i]): + sets[len(sets)-1].WriteByte(pattern[i]) + case pattern[i] == '\\': + sets[len(sets)-1].WriteByte('\\') + default: + return nil + } + escaped = false + } else { + switch { + case isRegexMetaCharacter(pattern[i]): + if pattern[i] == '|' { + sets = append(sets, &strings.Builder{}) + } else { + return nil + } + case pattern[i] == '\\': + escaped = true + default: + sets[len(sets)-1].WriteByte(pattern[i]) + } + } + } + matches := make([]string, 0, len(sets)) + for _, s := range sets { + if s.Len() > 0 { + matches = append(matches, s.String()) + } + } + return matches +} diff --git a/pkg/store/opts_test.go b/pkg/store/opts_test.go new file mode 100644 index 0000000000..e79fdf35bc --- /dev/null +++ b/pkg/store/opts_test.go @@ -0,0 +1,53 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package store + +import ( + "testing" + + "github.com/thanos-io/thanos/pkg/testutil" +) + +// Refer to https://github.com/prometheus/prometheus/issues/2651. +func TestFindSetMatches(t *testing.T) { + cases := []struct { + pattern string + exp []string + }{ + // Simple sets. + { + pattern: "foo|bar|baz", + exp: []string{ + "foo", + "bar", + "baz", + }, + }, + // Simple sets containing escaped characters. + { + pattern: "fo\\.o|bar\\?|\\^baz", + exp: []string{ + "fo.o", + "bar?", + "^baz", + }, + }, + // Simple sets containing special characters without escaping. + { + pattern: "fo.o|bar?|^baz", + exp: nil, + }, + { + pattern: "foo\\|bar\\|baz", + exp: []string{ + "foo|bar|baz", + }, + }, + } + + for _, c := range cases { + matches := findSetMatches(c.pattern) + testutil.Equals(t, c.exp, matches) + } +} diff --git a/pkg/store/postings_codec.go b/pkg/store/postings_codec.go new file mode 100644 index 0000000000..7b1aaff477 --- /dev/null +++ b/pkg/store/postings_codec.go @@ -0,0 +1,135 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package store + +import ( + "bytes" + + "github.com/golang/snappy" + "github.com/pkg/errors" + "github.com/prometheus/prometheus/tsdb/encoding" + "github.com/prometheus/prometheus/tsdb/index" +) + +// This file implements encoding and decoding of postings using diff (or delta) + varint +// number encoding. On top of that, we apply Snappy compression. +// +// On its own, Snappy compressing raw postings doesn't really help, because there is no +// repetition in raw data. Using diff (delta) between postings entries makes values small, +// and Varint is very efficient at encoding small values (values < 128 are encoded as +// single byte, values < 16384 are encoded as two bytes). Diff + varint reduces postings size +// significantly (to about 20% of original), snappy then halves it to ~10% of the original. + +const ( + codecHeaderSnappy = "dvs" // As in "diff+varint+snappy". +) + +// isDiffVarintSnappyEncodedPostings returns true, if input looks like it has been encoded by diff+varint+snappy codec. +func isDiffVarintSnappyEncodedPostings(input []byte) bool { + return bytes.HasPrefix(input, []byte(codecHeaderSnappy)) +} + +// diffVarintSnappyEncode encodes postings into diff+varint representation, +// and applies snappy compression on the result. +// Returned byte slice starts with codecHeaderSnappy header. +func diffVarintSnappyEncode(p index.Postings) ([]byte, error) { + buf, err := diffVarintEncodeNoHeader(p) + if err != nil { + return nil, err + } + + // Make result buffer large enough to hold our header and compressed block. + result := make([]byte, len(codecHeaderSnappy)+snappy.MaxEncodedLen(len(buf))) + copy(result, codecHeaderSnappy) + + compressed := snappy.Encode(result[len(codecHeaderSnappy):], buf) + + // Slice result buffer based on compressed size. + result = result[:len(codecHeaderSnappy)+len(compressed)] + return result, nil +} + +// diffVarintEncodeNoHeader encodes postings into diff+varint representation. +// It doesn't add any header to the output bytes. +func diffVarintEncodeNoHeader(p index.Postings) ([]byte, error) { + buf := encoding.Encbuf{} + + prev := uint64(0) + for p.Next() { + v := p.At() + if v < prev { + return nil, errors.Errorf("postings entries must be in increasing order, current: %d, previous: %d", v, prev) + } + + // This is the 'diff' part -- compute difference from previous value. + buf.PutUvarint64(v - prev) + prev = v + } + if p.Err() != nil { + return nil, p.Err() + } + + return buf.B, nil +} + +func diffVarintSnappyDecode(input []byte) (index.Postings, error) { + if !isDiffVarintSnappyEncodedPostings(input) { + return nil, errors.New("header not found") + } + + raw, err := snappy.Decode(nil, input[len(codecHeaderSnappy):]) + if err != nil { + return nil, errors.Wrap(err, "snappy decode") + } + + return newDiffVarintPostings(raw), nil +} + +func newDiffVarintPostings(input []byte) *diffVarintPostings { + return &diffVarintPostings{buf: &encoding.Decbuf{B: input}} +} + +// diffVarintPostings is an implementation of index.Postings based on diff+varint encoded data. +type diffVarintPostings struct { + buf *encoding.Decbuf + cur uint64 +} + +func (it *diffVarintPostings) At() uint64 { + return it.cur +} + +func (it *diffVarintPostings) Next() bool { + if it.buf.Err() != nil || it.buf.Len() == 0 { + return false + } + + val := it.buf.Uvarint64() + if it.buf.Err() != nil { + return false + } + + it.cur = it.cur + val + return true +} + +func (it *diffVarintPostings) Seek(x uint64) bool { + if it.cur >= x { + return true + } + + // We cannot do any search due to how values are stored, + // so we simply advance until we find the right value. + for it.Next() { + if it.At() >= x { + return true + } + } + + return false +} + +func (it *diffVarintPostings) Err() error { + return it.buf.Err() +} diff --git a/pkg/store/postings_codec_test.go b/pkg/store/postings_codec_test.go new file mode 100644 index 0000000000..adb9f57d4b --- /dev/null +++ b/pkg/store/postings_codec_test.go @@ -0,0 +1,184 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package store + +import ( + "testing" + + "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/tsdb" + "github.com/prometheus/prometheus/tsdb/index" + + "github.com/thanos-io/thanos/pkg/testutil" +) + +func TestDiffVarintCodec(t *testing.T) { + h, err := tsdb.NewHead(nil, nil, nil, 1000) + testutil.Ok(t, err) + defer func() { + testutil.Ok(t, h.Close()) + }() + + appendTestData(t, h.Appender(), 1e6) + + idx, err := h.Index() + testutil.Ok(t, err) + defer func() { + testutil.Ok(t, idx.Close()) + }() + + postingsMap := map[string]index.Postings{ + "all": allPostings(t, idx), + `n="1"`: matchPostings(t, idx, labels.MustNewMatcher(labels.MatchEqual, "n", "1"+postingsBenchSuffix)), + `j="foo"`: matchPostings(t, idx, labels.MustNewMatcher(labels.MatchEqual, "j", "foo")), + `j!="foo"`: matchPostings(t, idx, labels.MustNewMatcher(labels.MatchNotEqual, "j", "foo")), + `i=~".*"`: matchPostings(t, idx, labels.MustNewMatcher(labels.MatchRegexp, "i", ".*")), + `i=~".+"`: matchPostings(t, idx, labels.MustNewMatcher(labels.MatchRegexp, "i", ".+")), + `i=~"1.+"`: matchPostings(t, idx, labels.MustNewMatcher(labels.MatchRegexp, "i", "1.+")), + `i=~"^$"'`: matchPostings(t, idx, labels.MustNewMatcher(labels.MatchRegexp, "i", "^$")), + `i!~""`: matchPostings(t, idx, labels.MustNewMatcher(labels.MatchNotEqual, "i", "")), + `n!="2"`: matchPostings(t, idx, labels.MustNewMatcher(labels.MatchNotEqual, "n", "2"+postingsBenchSuffix)), + `i!~"2.*"`: matchPostings(t, idx, labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^2.*$")), + } + + codecs := map[string]struct { + codingFunction func(index.Postings) ([]byte, error) + decodingFunction func([]byte) (index.Postings, error) + }{ + "raw": {codingFunction: diffVarintEncodeNoHeader, decodingFunction: func(bytes []byte) (index.Postings, error) { return newDiffVarintPostings(bytes), nil }}, + "snappy": {codingFunction: diffVarintSnappyEncode, decodingFunction: diffVarintSnappyDecode}, + } + + for postingName, postings := range postingsMap { + p, err := toUint64Postings(postings) + testutil.Ok(t, err) + + for cname, codec := range codecs { + name := cname + "/" + postingName + + t.Run(name, func(t *testing.T) { + t.Log("postings entries:", p.len()) + t.Log("original size (4*entries):", 4*p.len(), "bytes") + p.reset() // We reuse postings between runs, so we need to reset iterator. + + data, err := codec.codingFunction(p) + testutil.Ok(t, err) + + t.Log("encoded size", len(data), "bytes") + t.Logf("ratio: %0.3f", (float64(len(data)) / float64(4*p.len()))) + + decodedPostings, err := codec.decodingFunction(data) + testutil.Ok(t, err) + + p.reset() + comparePostings(t, p, decodedPostings) + }) + } + } +} + +func comparePostings(t *testing.T, p1, p2 index.Postings) { + for p1.Next() { + if !p2.Next() { + t.Log("p1 has more values") + t.Fail() + return + } + + if p1.At() != p2.At() { + t.Logf("values differ: %d, %d", p1.At(), p2.At()) + t.Fail() + return + } + } + + if p2.Next() { + t.Log("p2 has more values") + t.Fail() + return + } + + testutil.Ok(t, p1.Err()) + testutil.Ok(t, p2.Err()) +} + +func allPostings(t testing.TB, ix tsdb.IndexReader) index.Postings { + k, v := index.AllPostingsKey() + p, err := ix.Postings(k, v) + testutil.Ok(t, err) + return p +} + +func matchPostings(t testing.TB, ix tsdb.IndexReader, m *labels.Matcher) index.Postings { + vals, err := ix.LabelValues(m.Name) + testutil.Ok(t, err) + + matching := []string(nil) + for _, v := range vals { + if m.Matches(v) { + matching = append(matching, v) + } + } + + p, err := ix.Postings(m.Name, matching...) + testutil.Ok(t, err) + return p +} + +func toUint64Postings(p index.Postings) (*uint64Postings, error) { + var vals []uint64 + for p.Next() { + vals = append(vals, p.At()) + } + return &uint64Postings{vals: vals, ix: -1}, p.Err() +} + +// Postings with no decoding step. +type uint64Postings struct { + vals []uint64 + ix int +} + +func (p *uint64Postings) At() uint64 { + if p.ix < 0 || p.ix >= len(p.vals) { + return 0 + } + return p.vals[p.ix] +} + +func (p *uint64Postings) Next() bool { + if p.ix < len(p.vals)-1 { + p.ix++ + return true + } + return false +} + +func (p *uint64Postings) Seek(x uint64) bool { + if p.At() >= x { + return true + } + + // We cannot do any search due to how values are stored, + // so we simply advance until we find the right value. + for p.Next() { + if p.At() >= x { + return true + } + } + + return false +} + +func (p *uint64Postings) Err() error { + return nil +} + +func (p *uint64Postings) reset() { + p.ix = -1 +} + +func (p *uint64Postings) len() int { + return len(p.vals) +} diff --git a/pkg/store/prometheus.go b/pkg/store/prometheus.go index 8bd6914afc..83754791b5 100644 --- a/pkg/store/prometheus.go +++ b/pkg/store/prometheus.go @@ -26,7 +26,6 @@ import ( "github.com/pkg/errors" "github.com/prometheus/common/version" "github.com/prometheus/prometheus/pkg/labels" - "github.com/prometheus/prometheus/prompb" "github.com/prometheus/prometheus/storage/remote" "github.com/prometheus/prometheus/tsdb/chunkenc" "github.com/thanos-io/thanos/pkg/component" @@ -34,6 +33,7 @@ import ( "github.com/thanos-io/thanos/pkg/promclient" "github.com/thanos-io/thanos/pkg/runutil" "github.com/thanos-io/thanos/pkg/store/storepb" + "github.com/thanos-io/thanos/pkg/store/storepb/prompb" "github.com/thanos-io/thanos/pkg/tracing" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -164,12 +164,7 @@ func (p *PrometheusStore) Series(r *storepb.SeriesRequest, s storepb.Store_Serie for k, v := range lbm { lset = append(lset, storepb.Label{Name: k, Value: v}) } - for _, l := range externalLabels { - lset = append(lset, storepb.Label{ - Name: l.Name, - Value: l.Value, - }) - } + lset = append(lset, storepb.PromLabelsToLabelsUnsafe(externalLabels)...) sort.Slice(lset, func(i, j int) bool { return lset[i].Name < lset[j].Name }) @@ -352,7 +347,7 @@ func (p *PrometheusStore) handleStreamedPrometheusResponse(s storepb.Store_Serie return nil } -func (p *PrometheusStore) fetchSampledResponse(ctx context.Context, resp *http.Response) (*prompb.ReadResponse, error) { +func (p *PrometheusStore) fetchSampledResponse(ctx context.Context, resp *http.Response) (_ *prompb.ReadResponse, err error) { defer runutil.ExhaustCloseWithLogOnErr(p.logger, resp.Body, "prom series request body") b := p.getBuffer() @@ -361,21 +356,24 @@ func (p *PrometheusStore) fetchSampledResponse(ctx context.Context, resp *http.R if _, err := io.Copy(buf, resp.Body); err != nil { return nil, errors.Wrap(err, "copy response") } - spanSnappyDecode, ctx := tracing.StartSpan(ctx, "decompress_response") + sb := p.getBuffer() - decomp, err := snappy.Decode(*sb, buf.Bytes()) - spanSnappyDecode.Finish() + var decomp []byte + tracing.DoInSpan(ctx, "decompress_response", func(ctx context.Context) { + decomp, err = snappy.Decode(*sb, buf.Bytes()) + }) defer p.putBuffer(sb) if err != nil { return nil, errors.Wrap(err, "decompress response") } var data prompb.ReadResponse - spanUnmarshal, _ := tracing.StartSpan(ctx, "unmarshal_response") - if err := proto.Unmarshal(decomp, &data); err != nil { + tracing.DoInSpan(ctx, "unmarshal_response", func(ctx context.Context) { + err = proto.Unmarshal(decomp, &data) + }) + if err != nil { return nil, errors.Wrap(err, "unmarshal response") } - spanUnmarshal.Finish() if len(data.Results) != 1 { return nil, errors.Errorf("unexpected result size %d", len(data.Results)) } @@ -501,32 +499,34 @@ func (p *PrometheusStore) encodeChunk(ss []prompb.Sample) (storepb.Chunk_Encodin // translateAndExtendLabels transforms a metrics into a protobuf label set. It additionally // attaches the given labels to it, overwriting existing ones on collision. +// Both input labels are expected to be sorted. +// +// NOTE(bwplotka): Don't use modify passed slices as we reuse underlying memory. func (p *PrometheusStore) translateAndExtendLabels(m []prompb.Label, extend labels.Labels) []storepb.Label { + pbLabels := storepb.PrompbLabelsToLabelsUnsafe(m) + pbExtend := storepb.PromLabelsToLabelsUnsafe(extend) + lset := make([]storepb.Label, 0, len(m)+len(extend)) + ei := 0 - for _, l := range m { - if extend.Get(l.Name) != "" { - continue +Outer: + for _, l := range pbLabels { + for ei < len(pbExtend) { + if l.Name < pbExtend[ei].Name { + break + } + lset = append(lset, pbExtend[ei]) + ei++ + if l.Name == pbExtend[ei-1].Name { + continue Outer + } } - lset = append(lset, storepb.Label{ - Name: l.Name, - Value: l.Value, - }) + lset = append(lset, l) } - - return extendLset(lset, extend) -} - -func extendLset(lset []storepb.Label, extend labels.Labels) []storepb.Label { - for _, l := range extend { - lset = append(lset, storepb.Label{ - Name: l.Name, - Value: l.Value, - }) + for ei < len(pbExtend) { + lset = append(lset, pbExtend[ei]) + ei++ } - sort.Slice(lset, func(i, j int) bool { - return lset[i].Name < lset[j].Name - }) return lset } diff --git a/pkg/store/prometheus_test.go b/pkg/store/prometheus_test.go index 0c0d33d311..42c76a8f72 100644 --- a/pkg/store/prometheus_test.go +++ b/pkg/store/prometheus_test.go @@ -16,13 +16,13 @@ import ( "github.com/pkg/errors" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/pkg/timestamp" - "github.com/prometheus/prometheus/prompb" "github.com/prometheus/prometheus/tsdb" "github.com/prometheus/prometheus/tsdb/chunkenc" "github.com/thanos-io/thanos/pkg/testutil/e2eutil" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/store/storepb" + "github.com/thanos-io/thanos/pkg/store/storepb/prompb" "github.com/thanos-io/thanos/pkg/testutil" ) @@ -427,14 +427,14 @@ rule_files: { Name: "thanos-receive.rules", File: fmt.Sprintf("%s/../../examples/alerts/alerts.yaml", curr), - Rules: []*storepb.Rule{someAlert, someAlert, someAlert, someAlert, someAlert}, + Rules: []*storepb.Rule{someAlert, someAlert, someAlert, someAlert, someAlert, someAlert}, Interval: 60, DeprecatedPartialResponseStrategy: storepb.PartialResponseStrategy_WARN, PartialResponseStrategy: storepb.PartialResponseStrategy_WARN, }, { Name: "thanos-rule.rules", File: fmt.Sprintf("%s/../../examples/alerts/alerts.yaml", curr), - Rules: []*storepb.Rule{someAlert, someAlert, someAlert, someAlert, someAlert, someAlert, someAlert, someAlert, someAlert}, + Rules: []*storepb.Rule{someAlert, someAlert, someAlert, someAlert, someAlert, someAlert, someAlert, someAlert, someAlert, someAlert, someAlert}, Interval: 60, DeprecatedPartialResponseStrategy: storepb.PartialResponseStrategy_WARN, PartialResponseStrategy: storepb.PartialResponseStrategy_WARN, }, diff --git a/pkg/store/proxy.go b/pkg/store/proxy.go index febd7c1a5a..9b1a340625 100644 --- a/pkg/store/proxy.go +++ b/pkg/store/proxy.go @@ -19,6 +19,7 @@ import ( "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/prometheus/pkg/labels" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/promclient" @@ -185,16 +186,11 @@ type proxyStoreMetrics struct { func newProxyStoreMetrics(reg prometheus.Registerer) *proxyStoreMetrics { var m proxyStoreMetrics - m.emptyStreamResponses = prometheus.NewCounter(prometheus.CounterOpts{ + m.emptyStreamResponses = promauto.With(reg).NewCounter(prometheus.CounterOpts{ Name: "thanos_proxy_store_empty_stream_responses_total", Help: "Total number of empty responses received.", }) - if reg != nil { - reg.MustRegister( - m.emptyStreamResponses, - ) - } return &m } @@ -237,9 +233,9 @@ func (s *ProxyStore) Info(_ context.Context, _ *storepb.InfoRequest) (*storepb.I maxTime := int64(0) stores := s.stores() - // Edge case: we have all of the data if there are no stores. + // Edge case: we have no data if there are no stores. if len(stores) == 0 { - res.MaxTime = math.MaxInt64 + res.MaxTime = 0 res.MinTime = 0 return res, nil @@ -373,9 +369,11 @@ func (s *ProxyStore) Series(r *storepb.SeriesRequest, srv storepb.Store_SeriesSe // We might be able to skip the store if its meta information indicates // it cannot have series matching our query. // NOTE: all matchers are validated in matchesExternalLabels method so we explicitly ignore error. - spanStoreMathes, gctx := tracing.StartSpan(gctx, "store_matches") - ok, _ := storeMatches(st, r.MinTime, r.MaxTime, r.Matchers...) - spanStoreMathes.Finish() + var ok bool + tracing.DoInSpan(gctx, "store_matches", func(ctx context.Context) { + // We can skip error, we already translated matchers once. + ok, _ = storeMatches(st, r.MinTime, r.MaxTime, r.Matchers...) + }) if !ok { storeDebugMsgs = append(storeDebugMsgs, fmt.Sprintf("store %s filtered out", st)) continue @@ -558,9 +556,16 @@ func startStreamSeriesSet( if w := rr.r.GetWarning(); w != "" { s.warnCh.send(storepb.NewWarnSeriesResponse(errors.New(w))) - continue } - s.recvCh <- rr.r.GetSeries() + + if series := rr.r.GetSeries(); series != nil { + select { + case s.recvCh <- series: + case <-ctx.Done(): + s.handleErr(errors.Wrapf(ctx.Err(), "failed to receive any data from %s", s.name), done) + return + } + } } }() return s diff --git a/pkg/store/proxy_test.go b/pkg/store/proxy_test.go index a76f2089e1..35b0aa14db 100644 --- a/pkg/store/proxy_test.go +++ b/pkg/store/proxy_test.go @@ -7,7 +7,6 @@ import ( "context" "fmt" "io" - "math" "os" "reflect" "sort" @@ -16,6 +15,7 @@ import ( "github.com/fortytw2/leaktest" "github.com/gogo/protobuf/proto" + "github.com/gogo/protobuf/types" "github.com/pkg/errors" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/tsdb/chunkenc" @@ -71,7 +71,7 @@ func TestProxyStore_Info(t *testing.T) { testutil.Equals(t, []storepb.LabelSet(nil), resp.LabelSets) testutil.Equals(t, storepb.StoreType_QUERY, resp.StoreType) testutil.Equals(t, int64(0), resp.MinTime) - testutil.Equals(t, int64(math.MaxInt64), resp.MaxTime) + testutil.Equals(t, int64(0), resp.MaxTime) } func TestProxyStore_Series(t *testing.T) { @@ -466,6 +466,60 @@ func TestProxyStore_SeriesSlowStores(t *testing.T) { expectedErr error expectedWarningsLen int }{ + { + title: "partial response disabled; 1st errors out after some delay; 2nd store is fast", + storeAPIs: []Client{ + &testClient{ + StoreClient: &mockedStoreAPI{ + RespSeries: []*storepb.SeriesResponse{ + storepb.NewWarnSeriesResponse(errors.New("warning")), + storeSeriesResponse(t, labels.FromStrings("a", "b"), []sample{{1, 1}, {2, 2}, {3, 3}}), + }, + RespDuration: 2 * time.Second, + SlowSeriesIndex: 1, + injectedError: errors.New("test"), + injectedErrorIndex: 1, + }, + labelSets: []storepb.LabelSet{{Labels: []storepb.Label{{Name: "ext", Value: "1"}}}}, + minTime: 1, + maxTime: 300, + }, + &testClient{ + StoreClient: &mockedStoreAPI{ + RespSeries: []*storepb.SeriesResponse{ + storepb.NewWarnSeriesResponse(errors.New("warning")), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + storeSeriesResponse(t, labels.FromStrings("b", "a"), []sample{{4, 1}, {5, 2}, {6, 3}}), + }, + }, + labelSets: []storepb.LabelSet{{Labels: []storepb.Label{{Name: "ext", Value: "1"}}}}, + minTime: 1, + maxTime: 300, + }, + }, + req: &storepb.SeriesRequest{ + MinTime: 1, + MaxTime: 300, + Matchers: []storepb.LabelMatcher{{Name: "ext", Value: "1", Type: storepb.LabelMatcher_EQ}}, + PartialResponseDisabled: true, + }, + expectedErr: errors.New("test: receive series from test: test"), + }, { title: "partial response disabled; 1st store is slow, 2nd store is fast;", storeAPIs: []Client{ @@ -1318,6 +1372,7 @@ type storeSeriesServer struct { SeriesSet []storepb.Series Warnings []string + HintsSet []*types.Any Size int64 } @@ -1334,10 +1389,17 @@ func (s *storeSeriesServer) Send(r *storepb.SeriesResponse) error { return nil } - if r.GetSeries() == nil { - return errors.New("no seriesSet") + if r.GetSeries() != nil { + s.SeriesSet = append(s.SeriesSet, *r.GetSeries()) + return nil + } + + if r.GetHints() != nil { + s.HintsSet = append(s.HintsSet, r.GetHints()) + return nil } - s.SeriesSet = append(s.SeriesSet, *r.GetSeries()) + + // Unsupported field, skip. return nil } @@ -1394,6 +1456,10 @@ type mockedStoreAPI struct { LastSeriesReq *storepb.SeriesRequest LastLabelValuesReq *storepb.LabelValuesRequest LastLabelNamesReq *storepb.LabelNamesRequest + + // injectedError will be injected into Recv() if not nil. + injectedError error + injectedErrorIndex int } func (s *mockedStoreAPI) Info(ctx context.Context, req *storepb.InfoRequest, _ ...grpc.CallOption) (*storepb.InfoResponse, error) { @@ -1403,7 +1469,7 @@ func (s *mockedStoreAPI) Info(ctx context.Context, req *storepb.InfoRequest, _ . func (s *mockedStoreAPI) Series(ctx context.Context, req *storepb.SeriesRequest, _ ...grpc.CallOption) (storepb.Store_SeriesClient, error) { s.LastSeriesReq = req - return &StoreSeriesClient{ctx: ctx, respSet: s.RespSeries, respDur: s.RespDuration, slowSeriesIndex: s.SlowSeriesIndex}, s.RespError + return &StoreSeriesClient{injectedErrorIndex: s.injectedErrorIndex, injectedError: s.injectedError, ctx: ctx, respSet: s.RespSeries, respDur: s.RespDuration, slowSeriesIndex: s.SlowSeriesIndex}, s.RespError } func (s *mockedStoreAPI) LabelNames(ctx context.Context, req *storepb.LabelNamesRequest, _ ...grpc.CallOption) (*storepb.LabelNamesResponse, error) { @@ -1427,12 +1493,18 @@ type StoreSeriesClient struct { respSet []*storepb.SeriesResponse respDur time.Duration slowSeriesIndex int + + injectedError error + injectedErrorIndex int } func (c *StoreSeriesClient) Recv() (*storepb.SeriesResponse, error) { if c.respDur != 0 && (c.slowSeriesIndex == c.i || c.slowSeriesIndex == 0) { time.Sleep(c.respDur) } + if c.injectedError != nil && (c.injectedErrorIndex == c.i || c.injectedErrorIndex == 0) { + return nil, c.injectedError + } if c.i >= len(c.respSet) { return nil, io.EOF diff --git a/pkg/store/storepb/custom.go b/pkg/store/storepb/custom.go index 9bd0f4ab03..e8a76b76b5 100644 --- a/pkg/store/storepb/custom.go +++ b/pkg/store/storepb/custom.go @@ -5,8 +5,11 @@ package storepb import ( "strings" + "unsafe" + "github.com/gogo/protobuf/types" "github.com/prometheus/prometheus/pkg/labels" + "github.com/thanos-io/thanos/pkg/store/storepb/prompb" ) var PartialResponseStrategyValues = func() []string { @@ -55,6 +58,14 @@ func NewRecordingRule(r *RecordingRule) *Rule { } } +func NewHintsSeriesResponse(hints *types.Any) *SeriesResponse { + return &SeriesResponse{ + Result: &SeriesResponse_Hints{ + Hints: hints, + }, + } +} + // CompareLabels compares two sets of labels. func CompareLabels(a, b []Label) int { l := len(a) @@ -188,6 +199,7 @@ func (s *mergedSeriesSet) Next() bool { return true } +// LabelsToPromLabels converts Thanos proto labels to Prometheus labels in type safe manner. func LabelsToPromLabels(lset []Label) labels.Labels { ret := make(labels.Labels, len(lset)) for i, l := range lset { @@ -196,6 +208,15 @@ func LabelsToPromLabels(lset []Label) labels.Labels { return ret } +// LabelsToPromLabelsUnsafe converts Thanos proto labels to Prometheus labels in type unsafe manner. +// It reuses the same memory. Caller should abort using passed []Labels. +// +// NOTE: This depends on order of struct fields etc, so use with extreme care. +func LabelsToPromLabelsUnsafe(lset []Label) labels.Labels { + return *(*[]labels.Label)(unsafe.Pointer(&lset)) +} + +// PromLabelsToLabels converts Prometheus labels to Thanos proto labels in type safe manner. func PromLabelsToLabels(lset labels.Labels) []Label { ret := make([]Label, len(lset)) for i, l := range lset { @@ -204,6 +225,31 @@ func PromLabelsToLabels(lset labels.Labels) []Label { return ret } +// PromLabelsToLabelsUnsafe converts Prometheus labels to Thanos proto labels in type unsafe manner. +// It reuses the same memory. Caller should abort using passed labels.Labels. +// +// // NOTE: This depends on order of struct fields etc, so use with extreme care. +func PromLabelsToLabelsUnsafe(lset labels.Labels) []Label { + return *(*[]Label)(unsafe.Pointer(&lset)) +} + +// PrompbLabelsToLabels converts Prometheus labels to Thanos proto labels in type safe manner. +func PrompbLabelsToLabels(lset []prompb.Label) []Label { + ret := make([]Label, len(lset)) + for i, l := range lset { + ret[i] = Label{Name: l.Name, Value: l.Value} + } + return ret +} + +// PrompbLabelsToLabelsUnsafe converts Prometheus proto labels to Thanos proto labels in type unsafe manner. +// It reuses the same memory. Caller should abort using passed labels.Labels. +// +// // NOTE: This depends on order of struct fields etc, so use with extreme care. +func PrompbLabelsToLabelsUnsafe(lset []prompb.Label) []Label { + return *(*[]Label)(unsafe.Pointer(&lset)) +} + func LabelsToString(lset []Label) string { var s []string for _, l := range lset { diff --git a/pkg/store/storepb/custom_test.go b/pkg/store/storepb/custom_test.go index 3132b28f97..cbeaed6950 100644 --- a/pkg/store/storepb/custom_test.go +++ b/pkg/store/storepb/custom_test.go @@ -12,6 +12,7 @@ import ( "github.com/pkg/errors" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/tsdb/chunkenc" + "github.com/thanos-io/thanos/pkg/store/storepb/prompb" "github.com/thanos-io/thanos/pkg/testutil" ) @@ -328,3 +329,58 @@ func BenchmarkMergedSeriesSet(b *testing.B) { } } } + +var testLsetMap = map[string]string{ + "a": "1", + "c": "2", + "d": "dsfsdfsdfsdf123414234", + "124134235423534534ffdasdfsf": "1", + "": "", + "b": "", +} + +func TestPromLabelsToLabelsUnsafe(t *testing.T) { + testutil.Equals(t, PromLabelsToLabels(labels.FromMap(testLsetMap)), PromLabelsToLabelsUnsafe(labels.FromMap(testLsetMap))) +} + +func TestLabelsToPromLabelsUnsafe(t *testing.T) { + testutil.Equals(t, labels.FromMap(testLsetMap), LabelsToPromLabels(PromLabelsToLabels(labels.FromMap(testLsetMap)))) + testutil.Equals(t, labels.FromMap(testLsetMap), LabelsToPromLabelsUnsafe(PromLabelsToLabels(labels.FromMap(testLsetMap)))) +} + +func TestPrompbLabelsToLabelsUnsafe(t *testing.T) { + var pb []prompb.Label + for _, l := range labels.FromMap(testLsetMap) { + pb = append(pb, prompb.Label{Name: l.Name, Value: l.Value}) + } + testutil.Equals(t, PromLabelsToLabels(labels.FromMap(testLsetMap)), PrompbLabelsToLabels(pb)) + testutil.Equals(t, PromLabelsToLabels(labels.FromMap(testLsetMap)), PrompbLabelsToLabelsUnsafe(pb)) +} + +func BenchmarkUnsafeVSSafeLabelsConversion(b *testing.B) { + const ( + fmtLbl = "%07daaaaaaaaaabbbbbbbbbbccccccccccdddddddddd" + num = 10000 + ) + lbls := make([]labels.Label, 0, num) + for i := 0; i < num; i++ { + lbls = append(lbls, labels.Label{Name: fmt.Sprintf(fmtLbl, i), Value: fmt.Sprintf(fmtLbl, i)}) + } + + var converted labels.Labels + b.Run("safe", func(b *testing.B) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + converted = LabelsToPromLabels(PromLabelsToLabels(lbls)) + } + }) + testutil.Equals(b, num, len(converted)) + b.Run("unsafe", func(b *testing.B) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + converted = LabelsToPromLabelsUnsafe(PromLabelsToLabelsUnsafe(lbls)) + } + }) + testutil.Equals(b, num, len(converted)) + +} diff --git a/pkg/store/storepb/prompb/README.md b/pkg/store/storepb/prompb/README.md new file mode 100644 index 0000000000..b68a8c8ba4 --- /dev/null +++ b/pkg/store/storepb/prompb/README.md @@ -0,0 +1,11 @@ +NOTE(bwplotka): This excerpt of "github.com/prometheus/prometheus/prompb" reconstructed to avoid XXX fields for unsafe conversion to safe allocs. + +The compiled protobufs are version controlled and you won't normally need to +re-compile them when building Prometheus. + +If however you have modified the defs and do need to re-compile, run +`make proto` from the parent dir. + +In order for the script to run, you'll need `protoc` (version 3.5.1) in your +PATH. + diff --git a/pkg/store/storepb/prompb/remote.pb.go b/pkg/store/storepb/prompb/remote.pb.go new file mode 100644 index 0000000000..83902b37be --- /dev/null +++ b/pkg/store/storepb/prompb/remote.pb.go @@ -0,0 +1,1590 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: remote.proto + +package prompb + +import ( + fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" +) + +// 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.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type ReadRequest_ResponseType int32 + +const ( + // Server will return a single ReadResponse message with matched series that includes list of raw samples. + // It's recommended to use streamed response types instead. + // + // Response headers: + // Content-Type: "application/x-protobuf" + // Content-Encoding: "snappy" + ReadRequest_SAMPLES ReadRequest_ResponseType = 0 + // Server will stream a delimited ChunkedReadResponse message that contains XOR encoded chunks for a single series. + // Each message is following varint size and fixed size bigendian uint32 for CRC32 Castagnoli checksum. + // + // Response headers: + // Content-Type: "application/x-streamed-protobuf; proto=prometheus.ChunkedReadResponse" + // Content-Encoding: "" + ReadRequest_STREAMED_XOR_CHUNKS ReadRequest_ResponseType = 1 +) + +var ReadRequest_ResponseType_name = map[int32]string{ + 0: "SAMPLES", + 1: "STREAMED_XOR_CHUNKS", +} + +var ReadRequest_ResponseType_value = map[string]int32{ + "SAMPLES": 0, + "STREAMED_XOR_CHUNKS": 1, +} + +func (x ReadRequest_ResponseType) String() string { + return proto.EnumName(ReadRequest_ResponseType_name, int32(x)) +} + +func (ReadRequest_ResponseType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_eefc82927d57d89b, []int{1, 0} +} + +type WriteRequest struct { + Timeseries []TimeSeries `protobuf:"bytes,1,rep,name=timeseries,proto3" json:"timeseries"` +} + +func (m *WriteRequest) Reset() { *m = WriteRequest{} } +func (m *WriteRequest) String() string { return proto.CompactTextString(m) } +func (*WriteRequest) ProtoMessage() {} +func (*WriteRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_eefc82927d57d89b, []int{0} +} +func (m *WriteRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *WriteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_WriteRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *WriteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_WriteRequest.Merge(m, src) +} +func (m *WriteRequest) XXX_Size() int { + return m.Size() +} +func (m *WriteRequest) XXX_DiscardUnknown() { + xxx_messageInfo_WriteRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_WriteRequest proto.InternalMessageInfo + +func (m *WriteRequest) GetTimeseries() []TimeSeries { + if m != nil { + return m.Timeseries + } + return nil +} + +// ReadRequest represents a remote read request. +type ReadRequest struct { + Queries []*Query `protobuf:"bytes,1,rep,name=queries,proto3" json:"queries,omitempty"` + // accepted_response_types allows negotiating the content type of the response. + // + // Response types are taken from the list in the FIFO order. If no response type in `accepted_response_types` is + // implemented by server, error is returned. + // For request that do not contain `accepted_response_types` field the SAMPLES response type will be used. + AcceptedResponseTypes []ReadRequest_ResponseType `protobuf:"varint,2,rep,packed,name=accepted_response_types,json=acceptedResponseTypes,proto3,enum=prometheus_copy.ReadRequest_ResponseType" json:"accepted_response_types,omitempty"` +} + +func (m *ReadRequest) Reset() { *m = ReadRequest{} } +func (m *ReadRequest) String() string { return proto.CompactTextString(m) } +func (*ReadRequest) ProtoMessage() {} +func (*ReadRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_eefc82927d57d89b, []int{1} +} +func (m *ReadRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ReadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ReadRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ReadRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReadRequest.Merge(m, src) +} +func (m *ReadRequest) XXX_Size() int { + return m.Size() +} +func (m *ReadRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ReadRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ReadRequest proto.InternalMessageInfo + +func (m *ReadRequest) GetQueries() []*Query { + if m != nil { + return m.Queries + } + return nil +} + +func (m *ReadRequest) GetAcceptedResponseTypes() []ReadRequest_ResponseType { + if m != nil { + return m.AcceptedResponseTypes + } + return nil +} + +// ReadResponse is a response when response_type equals SAMPLES. +type ReadResponse struct { + // In same order as the request's queries. + Results []*QueryResult `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"` +} + +func (m *ReadResponse) Reset() { *m = ReadResponse{} } +func (m *ReadResponse) String() string { return proto.CompactTextString(m) } +func (*ReadResponse) ProtoMessage() {} +func (*ReadResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_eefc82927d57d89b, []int{2} +} +func (m *ReadResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ReadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ReadResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ReadResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReadResponse.Merge(m, src) +} +func (m *ReadResponse) XXX_Size() int { + return m.Size() +} +func (m *ReadResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ReadResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ReadResponse proto.InternalMessageInfo + +func (m *ReadResponse) GetResults() []*QueryResult { + if m != nil { + return m.Results + } + return nil +} + +type Query struct { + StartTimestampMs int64 `protobuf:"varint,1,opt,name=start_timestamp_ms,json=startTimestampMs,proto3" json:"start_timestamp_ms,omitempty"` + EndTimestampMs int64 `protobuf:"varint,2,opt,name=end_timestamp_ms,json=endTimestampMs,proto3" json:"end_timestamp_ms,omitempty"` + Matchers []*LabelMatcher `protobuf:"bytes,3,rep,name=matchers,proto3" json:"matchers,omitempty"` + Hints *ReadHints `protobuf:"bytes,4,opt,name=hints,proto3" json:"hints,omitempty"` +} + +func (m *Query) Reset() { *m = Query{} } +func (m *Query) String() string { return proto.CompactTextString(m) } +func (*Query) ProtoMessage() {} +func (*Query) Descriptor() ([]byte, []int) { + return fileDescriptor_eefc82927d57d89b, []int{3} +} +func (m *Query) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Query) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Query.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Query) XXX_Merge(src proto.Message) { + xxx_messageInfo_Query.Merge(m, src) +} +func (m *Query) XXX_Size() int { + return m.Size() +} +func (m *Query) XXX_DiscardUnknown() { + xxx_messageInfo_Query.DiscardUnknown(m) +} + +var xxx_messageInfo_Query proto.InternalMessageInfo + +func (m *Query) GetStartTimestampMs() int64 { + if m != nil { + return m.StartTimestampMs + } + return 0 +} + +func (m *Query) GetEndTimestampMs() int64 { + if m != nil { + return m.EndTimestampMs + } + return 0 +} + +func (m *Query) GetMatchers() []*LabelMatcher { + if m != nil { + return m.Matchers + } + return nil +} + +func (m *Query) GetHints() *ReadHints { + if m != nil { + return m.Hints + } + return nil +} + +type QueryResult struct { + // Samples within a time series must be ordered by time. + Timeseries []*TimeSeries `protobuf:"bytes,1,rep,name=timeseries,proto3" json:"timeseries,omitempty"` +} + +func (m *QueryResult) Reset() { *m = QueryResult{} } +func (m *QueryResult) String() string { return proto.CompactTextString(m) } +func (*QueryResult) ProtoMessage() {} +func (*QueryResult) Descriptor() ([]byte, []int) { + return fileDescriptor_eefc82927d57d89b, []int{4} +} +func (m *QueryResult) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryResult.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryResult.Merge(m, src) +} +func (m *QueryResult) XXX_Size() int { + return m.Size() +} +func (m *QueryResult) XXX_DiscardUnknown() { + xxx_messageInfo_QueryResult.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryResult proto.InternalMessageInfo + +func (m *QueryResult) GetTimeseries() []*TimeSeries { + if m != nil { + return m.Timeseries + } + return nil +} + +// ChunkedReadResponse is a response when response_type equals STREAMED_XOR_CHUNKS. +// We strictly stream full series after series, optionally split by time. This means that a single frame can contain +// partition of the single series, but once a new series is started to be streamed it means that no more chunks will +// be sent for previous one. +type ChunkedReadResponse struct { + ChunkedSeries []*ChunkedSeries `protobuf:"bytes,1,rep,name=chunked_series,json=chunkedSeries,proto3" json:"chunked_series,omitempty"` + // query_index represents an index of the query from ReadRequest.queries these chunks relates to. + QueryIndex int64 `protobuf:"varint,2,opt,name=query_index,json=queryIndex,proto3" json:"query_index,omitempty"` +} + +func (m *ChunkedReadResponse) Reset() { *m = ChunkedReadResponse{} } +func (m *ChunkedReadResponse) String() string { return proto.CompactTextString(m) } +func (*ChunkedReadResponse) ProtoMessage() {} +func (*ChunkedReadResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_eefc82927d57d89b, []int{5} +} +func (m *ChunkedReadResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ChunkedReadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ChunkedReadResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ChunkedReadResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChunkedReadResponse.Merge(m, src) +} +func (m *ChunkedReadResponse) XXX_Size() int { + return m.Size() +} +func (m *ChunkedReadResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ChunkedReadResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ChunkedReadResponse proto.InternalMessageInfo + +func (m *ChunkedReadResponse) GetChunkedSeries() []*ChunkedSeries { + if m != nil { + return m.ChunkedSeries + } + return nil +} + +func (m *ChunkedReadResponse) GetQueryIndex() int64 { + if m != nil { + return m.QueryIndex + } + return 0 +} + +func init() { + proto.RegisterEnum("prometheus_copy.ReadRequest_ResponseType", ReadRequest_ResponseType_name, ReadRequest_ResponseType_value) + proto.RegisterType((*WriteRequest)(nil), "prometheus_copy.WriteRequest") + proto.RegisterType((*ReadRequest)(nil), "prometheus_copy.ReadRequest") + proto.RegisterType((*ReadResponse)(nil), "prometheus_copy.ReadResponse") + proto.RegisterType((*Query)(nil), "prometheus_copy.Query") + proto.RegisterType((*QueryResult)(nil), "prometheus_copy.QueryResult") + proto.RegisterType((*ChunkedReadResponse)(nil), "prometheus_copy.ChunkedReadResponse") +} + +func init() { proto.RegisterFile("remote.proto", fileDescriptor_eefc82927d57d89b) } + +var fileDescriptor_eefc82927d57d89b = []byte{ + // 486 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0x80, 0xed, 0xa6, 0x6d, 0xd0, 0x38, 0x84, 0x68, 0x0b, 0x34, 0x0a, 0xe0, 0x46, 0x3e, 0x19, + 0x09, 0x85, 0x2a, 0x20, 0x24, 0xc4, 0x29, 0x2d, 0x41, 0x05, 0x1a, 0xa0, 0xeb, 0x20, 0x10, 0x17, + 0xcb, 0xb1, 0x47, 0x8d, 0x45, 0xfd, 0xd3, 0xdd, 0xb5, 0x84, 0x0f, 0xbc, 0x03, 0x8f, 0xd5, 0x03, + 0x87, 0x1e, 0x7b, 0x42, 0x28, 0x79, 0x11, 0xe4, 0x75, 0x1c, 0x6d, 0x08, 0x1c, 0x7a, 0xdb, 0xcc, + 0x7c, 0xf3, 0xed, 0xce, 0x64, 0x0c, 0x0d, 0x86, 0x51, 0x22, 0xb0, 0x97, 0xb2, 0x44, 0x24, 0xe4, + 0x56, 0xca, 0x92, 0x08, 0xc5, 0x14, 0x33, 0xee, 0xfa, 0x49, 0x9a, 0x77, 0x0c, 0x91, 0xa7, 0xc8, + 0xcb, 0x6c, 0xe7, 0xf6, 0x69, 0x72, 0x9a, 0xc8, 0xe3, 0xe3, 0xe2, 0x54, 0x46, 0xad, 0x13, 0x68, + 0x7c, 0x62, 0xa1, 0x40, 0x8a, 0xe7, 0x19, 0x72, 0x41, 0x06, 0x00, 0x22, 0x8c, 0x90, 0x23, 0x0b, + 0x91, 0xb7, 0xf5, 0x6e, 0xcd, 0x36, 0xfa, 0xf7, 0x7a, 0x7f, 0x89, 0x7b, 0xe3, 0x30, 0x42, 0x47, + 0x22, 0x07, 0x9b, 0x17, 0xbf, 0xf6, 0x34, 0xaa, 0x14, 0x59, 0x57, 0x3a, 0x18, 0x14, 0xbd, 0xa0, + 0x52, 0xee, 0x43, 0xfd, 0x3c, 0x53, 0x7d, 0x77, 0xd7, 0x7c, 0x27, 0x19, 0xb2, 0x9c, 0x56, 0x18, + 0xf1, 0x60, 0xd7, 0xf3, 0x7d, 0x4c, 0x05, 0x06, 0x2e, 0x43, 0x9e, 0x26, 0x31, 0x47, 0x57, 0xf6, + 0xd2, 0xde, 0xe8, 0xd6, 0xec, 0x66, 0xff, 0xe1, 0x9a, 0x41, 0xb9, 0xb0, 0x47, 0x17, 0x25, 0xe3, + 0x3c, 0x45, 0x7a, 0xa7, 0x32, 0xa9, 0x51, 0x6e, 0x3d, 0x85, 0x86, 0x1a, 0x20, 0x06, 0xd4, 0x9d, + 0xc1, 0xe8, 0xc3, 0xf1, 0xd0, 0x69, 0x69, 0x64, 0x17, 0x76, 0x9c, 0x31, 0x1d, 0x0e, 0x46, 0xc3, + 0x97, 0xee, 0xe7, 0xf7, 0xd4, 0x3d, 0x3c, 0xfa, 0xf8, 0xee, 0xad, 0xd3, 0xd2, 0xad, 0x57, 0x45, + 0x95, 0xb7, 0x54, 0x91, 0x67, 0x50, 0x67, 0xc8, 0xb3, 0x33, 0x51, 0xb5, 0x76, 0xff, 0x3f, 0xad, + 0x49, 0x88, 0x56, 0xb0, 0xf5, 0x53, 0x87, 0x2d, 0x99, 0x20, 0x8f, 0x80, 0x70, 0xe1, 0x31, 0xe1, + 0xca, 0x01, 0x0a, 0x2f, 0x4a, 0xdd, 0xa8, 0x90, 0xe9, 0x76, 0x8d, 0xb6, 0x64, 0x66, 0x5c, 0x25, + 0x46, 0x9c, 0xd8, 0xd0, 0xc2, 0x38, 0x58, 0x65, 0x37, 0x24, 0xdb, 0xc4, 0x38, 0x50, 0xc9, 0xe7, + 0x70, 0x23, 0xf2, 0x84, 0x3f, 0x45, 0xc6, 0xdb, 0x35, 0xf9, 0xb4, 0x07, 0x6b, 0x4f, 0x3b, 0xf6, + 0x26, 0x78, 0x36, 0x2a, 0x29, 0xba, 0xc4, 0xc9, 0x3e, 0x6c, 0x4d, 0xc3, 0x58, 0xf0, 0xf6, 0x66, + 0x57, 0xb7, 0x8d, 0x7e, 0xe7, 0x9f, 0xb3, 0x3e, 0x2a, 0x08, 0x5a, 0x82, 0xd6, 0x1b, 0x30, 0x94, + 0x36, 0xc9, 0x8b, 0x6b, 0xee, 0xd0, 0xca, 0xf6, 0x7c, 0x87, 0x9d, 0xc3, 0x69, 0x16, 0x7f, 0x2d, + 0xfe, 0x30, 0x65, 0xd2, 0x43, 0x68, 0xfa, 0x65, 0xd8, 0x5d, 0xf1, 0x9a, 0x6b, 0xde, 0x45, 0xf5, + 0x42, 0x7d, 0xd3, 0x57, 0x7f, 0x92, 0x3d, 0x30, 0x8a, 0x25, 0xcb, 0xdd, 0x30, 0x0e, 0xf0, 0xdb, + 0x62, 0x76, 0x20, 0x43, 0xaf, 0x8b, 0xc8, 0x41, 0xf7, 0x62, 0x66, 0xea, 0x97, 0x33, 0x53, 0xff, + 0x3d, 0x33, 0xf5, 0x1f, 0x73, 0x53, 0xbb, 0x9c, 0x9b, 0xda, 0xd5, 0xdc, 0xd4, 0xbe, 0x6c, 0x17, + 0x17, 0xa5, 0x93, 0xc9, 0xb6, 0xfc, 0x70, 0x9e, 0xfc, 0x09, 0x00, 0x00, 0xff, 0xff, 0x4b, 0x5c, + 0x76, 0xc3, 0x7c, 0x03, 0x00, 0x00, +} + +func (m *WriteRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WriteRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WriteRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Timeseries) > 0 { + for iNdEx := len(m.Timeseries) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Timeseries[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRemote(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ReadRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ReadRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ReadRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AcceptedResponseTypes) > 0 { + dAtA2 := make([]byte, len(m.AcceptedResponseTypes)*10) + var j1 int + for _, num := range m.AcceptedResponseTypes { + for num >= 1<<7 { + dAtA2[j1] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j1++ + } + dAtA2[j1] = uint8(num) + j1++ + } + i -= j1 + copy(dAtA[i:], dAtA2[:j1]) + i = encodeVarintRemote(dAtA, i, uint64(j1)) + i-- + dAtA[i] = 0x12 + } + if len(m.Queries) > 0 { + for iNdEx := len(m.Queries) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Queries[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRemote(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ReadResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ReadResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ReadResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Results) > 0 { + for iNdEx := len(m.Results) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Results[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRemote(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *Query) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Query) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Query) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Hints != nil { + { + size, err := m.Hints.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRemote(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if len(m.Matchers) > 0 { + for iNdEx := len(m.Matchers) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Matchers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRemote(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.EndTimestampMs != 0 { + i = encodeVarintRemote(dAtA, i, uint64(m.EndTimestampMs)) + i-- + dAtA[i] = 0x10 + } + if m.StartTimestampMs != 0 { + i = encodeVarintRemote(dAtA, i, uint64(m.StartTimestampMs)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryResult) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Timeseries) > 0 { + for iNdEx := len(m.Timeseries) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Timeseries[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRemote(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ChunkedReadResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ChunkedReadResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ChunkedReadResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.QueryIndex != 0 { + i = encodeVarintRemote(dAtA, i, uint64(m.QueryIndex)) + i-- + dAtA[i] = 0x10 + } + if len(m.ChunkedSeries) > 0 { + for iNdEx := len(m.ChunkedSeries) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ChunkedSeries[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRemote(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintRemote(dAtA []byte, offset int, v uint64) int { + offset -= sovRemote(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *WriteRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Timeseries) > 0 { + for _, e := range m.Timeseries { + l = e.Size() + n += 1 + l + sovRemote(uint64(l)) + } + } + return n +} + +func (m *ReadRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Queries) > 0 { + for _, e := range m.Queries { + l = e.Size() + n += 1 + l + sovRemote(uint64(l)) + } + } + if len(m.AcceptedResponseTypes) > 0 { + l = 0 + for _, e := range m.AcceptedResponseTypes { + l += sovRemote(uint64(e)) + } + n += 1 + sovRemote(uint64(l)) + l + } + return n +} + +func (m *ReadResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Results) > 0 { + for _, e := range m.Results { + l = e.Size() + n += 1 + l + sovRemote(uint64(l)) + } + } + return n +} + +func (m *Query) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.StartTimestampMs != 0 { + n += 1 + sovRemote(uint64(m.StartTimestampMs)) + } + if m.EndTimestampMs != 0 { + n += 1 + sovRemote(uint64(m.EndTimestampMs)) + } + if len(m.Matchers) > 0 { + for _, e := range m.Matchers { + l = e.Size() + n += 1 + l + sovRemote(uint64(l)) + } + } + if m.Hints != nil { + l = m.Hints.Size() + n += 1 + l + sovRemote(uint64(l)) + } + return n +} + +func (m *QueryResult) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Timeseries) > 0 { + for _, e := range m.Timeseries { + l = e.Size() + n += 1 + l + sovRemote(uint64(l)) + } + } + return n +} + +func (m *ChunkedReadResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ChunkedSeries) > 0 { + for _, e := range m.ChunkedSeries { + l = e.Size() + n += 1 + l + sovRemote(uint64(l)) + } + } + if m.QueryIndex != 0 { + n += 1 + sovRemote(uint64(m.QueryIndex)) + } + return n +} + +func sovRemote(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozRemote(x uint64) (n int) { + return sovRemote(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *WriteRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WriteRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WriteRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Timeseries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRemote + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRemote + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Timeseries = append(m.Timeseries, TimeSeries{}) + if err := m.Timeseries[len(m.Timeseries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRemote(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ReadRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ReadRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ReadRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Queries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRemote + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRemote + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Queries = append(m.Queries, &Query{}) + if err := m.Queries[len(m.Queries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType == 0 { + var v ReadRequest_ResponseType + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= ReadRequest_ResponseType(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.AcceptedResponseTypes = append(m.AcceptedResponseTypes, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthRemote + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthRemote + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + if elementCount != 0 && len(m.AcceptedResponseTypes) == 0 { + m.AcceptedResponseTypes = make([]ReadRequest_ResponseType, 0, elementCount) + } + for iNdEx < postIndex { + var v ReadRequest_ResponseType + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= ReadRequest_ResponseType(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.AcceptedResponseTypes = append(m.AcceptedResponseTypes, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field AcceptedResponseTypes", wireType) + } + default: + iNdEx = preIndex + skippy, err := skipRemote(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ReadResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ReadResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ReadResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Results", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRemote + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRemote + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Results = append(m.Results, &QueryResult{}) + if err := m.Results[len(m.Results)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRemote(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Query) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Query: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Query: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartTimestampMs", wireType) + } + m.StartTimestampMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartTimestampMs |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EndTimestampMs", wireType) + } + m.EndTimestampMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EndTimestampMs |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Matchers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRemote + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRemote + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Matchers = append(m.Matchers, &LabelMatcher{}) + if err := m.Matchers[len(m.Matchers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hints", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRemote + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRemote + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Hints == nil { + m.Hints = &ReadHints{} + } + if err := m.Hints.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRemote(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Timeseries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRemote + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRemote + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Timeseries = append(m.Timeseries, &TimeSeries{}) + if err := m.Timeseries[len(m.Timeseries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRemote(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ChunkedReadResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ChunkedReadResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ChunkedReadResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChunkedSeries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRemote + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRemote + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChunkedSeries = append(m.ChunkedSeries, &ChunkedSeries{}) + if err := m.ChunkedSeries[len(m.ChunkedSeries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field QueryIndex", wireType) + } + m.QueryIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRemote + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.QueryIndex |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRemote(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthRemote + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipRemote(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRemote + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRemote + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRemote + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthRemote + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupRemote + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthRemote + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthRemote = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRemote = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupRemote = fmt.Errorf("proto: unexpected end of group") +) diff --git a/pkg/store/storepb/prompb/remote.proto b/pkg/store/storepb/prompb/remote.proto new file mode 100644 index 0000000000..e72d94bb01 --- /dev/null +++ b/pkg/store/storepb/prompb/remote.proto @@ -0,0 +1,91 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +// Copyright 2016 Prometheus Team +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; +package prometheus_copy; + +option go_package = "prompb"; + +import "types.proto"; +import "gogoproto/gogo.proto"; + +// Do not generate XXX fields to reduce memory footprint and opening a door +// for zero-copy casts to/from prometheus data types. +option (gogoproto.goproto_unkeyed_all) = false; +option (gogoproto.goproto_unrecognized_all) = false; +option (gogoproto.goproto_sizecache_all) = false; + +message WriteRequest { + repeated TimeSeries timeseries = 1 [(gogoproto.nullable) = false]; +} + +// ReadRequest represents a remote read request. +message ReadRequest { + repeated Query queries = 1; + + enum ResponseType { + // Server will return a single ReadResponse message with matched series that includes list of raw samples. + // It's recommended to use streamed response types instead. + // + // Response headers: + // Content-Type: "application/x-protobuf" + // Content-Encoding: "snappy" + SAMPLES = 0; + // Server will stream a delimited ChunkedReadResponse message that contains XOR encoded chunks for a single series. + // Each message is following varint size and fixed size bigendian uint32 for CRC32 Castagnoli checksum. + // + // Response headers: + // Content-Type: "application/x-streamed-protobuf; proto=prometheus.ChunkedReadResponse" + // Content-Encoding: "" + STREAMED_XOR_CHUNKS = 1; + } + + // accepted_response_types allows negotiating the content type of the response. + // + // Response types are taken from the list in the FIFO order. If no response type in `accepted_response_types` is + // implemented by server, error is returned. + // For request that do not contain `accepted_response_types` field the SAMPLES response type will be used. + repeated ResponseType accepted_response_types = 2; +} + +// ReadResponse is a response when response_type equals SAMPLES. +message ReadResponse { + // In same order as the request's queries. + repeated QueryResult results = 1; +} + +message Query { + int64 start_timestamp_ms = 1; + int64 end_timestamp_ms = 2; + repeated LabelMatcher matchers = 3; + ReadHints hints = 4; +} + +message QueryResult { + // Samples within a time series must be ordered by time. + repeated TimeSeries timeseries = 1; +} + +// ChunkedReadResponse is a response when response_type equals STREAMED_XOR_CHUNKS. +// We strictly stream full series after series, optionally split by time. This means that a single frame can contain +// partition of the single series, but once a new series is started to be streamed it means that no more chunks will +// be sent for previous one. +message ChunkedReadResponse { + repeated ChunkedSeries chunked_series = 1; + + // query_index represents an index of the query from ReadRequest.queries these chunks relates to. + int64 query_index = 2; +} diff --git a/pkg/store/storepb/prompb/types.pb.go b/pkg/store/storepb/prompb/types.pb.go new file mode 100644 index 0000000000..c9a0775b63 --- /dev/null +++ b/pkg/store/storepb/prompb/types.pb.go @@ -0,0 +1,2272 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: types.proto + +package prompb + +import ( + encoding_binary "encoding/binary" + fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" +) + +// 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.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type LabelMatcher_Type int32 + +const ( + LabelMatcher_EQ LabelMatcher_Type = 0 + LabelMatcher_NEQ LabelMatcher_Type = 1 + LabelMatcher_RE LabelMatcher_Type = 2 + LabelMatcher_NRE LabelMatcher_Type = 3 +) + +var LabelMatcher_Type_name = map[int32]string{ + 0: "EQ", + 1: "NEQ", + 2: "RE", + 3: "NRE", +} + +var LabelMatcher_Type_value = map[string]int32{ + "EQ": 0, + "NEQ": 1, + "RE": 2, + "NRE": 3, +} + +func (x LabelMatcher_Type) String() string { + return proto.EnumName(LabelMatcher_Type_name, int32(x)) +} + +func (LabelMatcher_Type) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{4, 0} +} + +// We require this to match chunkenc.Encoding. +type Chunk_Encoding int32 + +const ( + Chunk_UNKNOWN Chunk_Encoding = 0 + Chunk_XOR Chunk_Encoding = 1 +) + +var Chunk_Encoding_name = map[int32]string{ + 0: "UNKNOWN", + 1: "XOR", +} + +var Chunk_Encoding_value = map[string]int32{ + "UNKNOWN": 0, + "XOR": 1, +} + +func (x Chunk_Encoding) String() string { + return proto.EnumName(Chunk_Encoding_name, int32(x)) +} + +func (Chunk_Encoding) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{6, 0} +} + +type Sample struct { + Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"` + Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (m *Sample) Reset() { *m = Sample{} } +func (m *Sample) String() string { return proto.CompactTextString(m) } +func (*Sample) ProtoMessage() {} +func (*Sample) Descriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{0} +} +func (m *Sample) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Sample) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Sample.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Sample) XXX_Merge(src proto.Message) { + xxx_messageInfo_Sample.Merge(m, src) +} +func (m *Sample) XXX_Size() int { + return m.Size() +} +func (m *Sample) XXX_DiscardUnknown() { + xxx_messageInfo_Sample.DiscardUnknown(m) +} + +var xxx_messageInfo_Sample proto.InternalMessageInfo + +func (m *Sample) GetValue() float64 { + if m != nil { + return m.Value + } + return 0 +} + +func (m *Sample) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +// TimeSeries represents samples and labels for a single time series. +type TimeSeries struct { + Labels []Label `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels"` + Samples []Sample `protobuf:"bytes,2,rep,name=samples,proto3" json:"samples"` +} + +func (m *TimeSeries) Reset() { *m = TimeSeries{} } +func (m *TimeSeries) String() string { return proto.CompactTextString(m) } +func (*TimeSeries) ProtoMessage() {} +func (*TimeSeries) Descriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{1} +} +func (m *TimeSeries) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TimeSeries) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TimeSeries.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TimeSeries) XXX_Merge(src proto.Message) { + xxx_messageInfo_TimeSeries.Merge(m, src) +} +func (m *TimeSeries) XXX_Size() int { + return m.Size() +} +func (m *TimeSeries) XXX_DiscardUnknown() { + xxx_messageInfo_TimeSeries.DiscardUnknown(m) +} + +var xxx_messageInfo_TimeSeries proto.InternalMessageInfo + +func (m *TimeSeries) GetLabels() []Label { + if m != nil { + return m.Labels + } + return nil +} + +func (m *TimeSeries) GetSamples() []Sample { + if m != nil { + return m.Samples + } + return nil +} + +type Label struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *Label) Reset() { *m = Label{} } +func (m *Label) String() string { return proto.CompactTextString(m) } +func (*Label) ProtoMessage() {} +func (*Label) Descriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{2} +} +func (m *Label) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Label) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Label.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Label) XXX_Merge(src proto.Message) { + xxx_messageInfo_Label.Merge(m, src) +} +func (m *Label) XXX_Size() int { + return m.Size() +} +func (m *Label) XXX_DiscardUnknown() { + xxx_messageInfo_Label.DiscardUnknown(m) +} + +var xxx_messageInfo_Label proto.InternalMessageInfo + +func (m *Label) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Label) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +type Labels struct { + Labels []Label `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels"` +} + +func (m *Labels) Reset() { *m = Labels{} } +func (m *Labels) String() string { return proto.CompactTextString(m) } +func (*Labels) ProtoMessage() {} +func (*Labels) Descriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{3} +} +func (m *Labels) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Labels) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Labels.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Labels) XXX_Merge(src proto.Message) { + xxx_messageInfo_Labels.Merge(m, src) +} +func (m *Labels) XXX_Size() int { + return m.Size() +} +func (m *Labels) XXX_DiscardUnknown() { + xxx_messageInfo_Labels.DiscardUnknown(m) +} + +var xxx_messageInfo_Labels proto.InternalMessageInfo + +func (m *Labels) GetLabels() []Label { + if m != nil { + return m.Labels + } + return nil +} + +// Matcher specifies a rule, which can match or set of labels or not. +type LabelMatcher struct { + Type LabelMatcher_Type `protobuf:"varint,1,opt,name=type,proto3,enum=prometheus_copy.LabelMatcher_Type" json:"type,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *LabelMatcher) Reset() { *m = LabelMatcher{} } +func (m *LabelMatcher) String() string { return proto.CompactTextString(m) } +func (*LabelMatcher) ProtoMessage() {} +func (*LabelMatcher) Descriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{4} +} +func (m *LabelMatcher) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LabelMatcher) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LabelMatcher.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *LabelMatcher) XXX_Merge(src proto.Message) { + xxx_messageInfo_LabelMatcher.Merge(m, src) +} +func (m *LabelMatcher) XXX_Size() int { + return m.Size() +} +func (m *LabelMatcher) XXX_DiscardUnknown() { + xxx_messageInfo_LabelMatcher.DiscardUnknown(m) +} + +var xxx_messageInfo_LabelMatcher proto.InternalMessageInfo + +func (m *LabelMatcher) GetType() LabelMatcher_Type { + if m != nil { + return m.Type + } + return LabelMatcher_EQ +} + +func (m *LabelMatcher) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *LabelMatcher) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +type ReadHints struct { + StepMs int64 `protobuf:"varint,1,opt,name=step_ms,json=stepMs,proto3" json:"step_ms,omitempty"` + Func string `protobuf:"bytes,2,opt,name=func,proto3" json:"func,omitempty"` + StartMs int64 `protobuf:"varint,3,opt,name=start_ms,json=startMs,proto3" json:"start_ms,omitempty"` + EndMs int64 `protobuf:"varint,4,opt,name=end_ms,json=endMs,proto3" json:"end_ms,omitempty"` + Grouping []string `protobuf:"bytes,5,rep,name=grouping,proto3" json:"grouping,omitempty"` + By bool `protobuf:"varint,6,opt,name=by,proto3" json:"by,omitempty"` + RangeMs int64 `protobuf:"varint,7,opt,name=range_ms,json=rangeMs,proto3" json:"range_ms,omitempty"` +} + +func (m *ReadHints) Reset() { *m = ReadHints{} } +func (m *ReadHints) String() string { return proto.CompactTextString(m) } +func (*ReadHints) ProtoMessage() {} +func (*ReadHints) Descriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{5} +} +func (m *ReadHints) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ReadHints) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ReadHints.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ReadHints) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReadHints.Merge(m, src) +} +func (m *ReadHints) XXX_Size() int { + return m.Size() +} +func (m *ReadHints) XXX_DiscardUnknown() { + xxx_messageInfo_ReadHints.DiscardUnknown(m) +} + +var xxx_messageInfo_ReadHints proto.InternalMessageInfo + +func (m *ReadHints) GetStepMs() int64 { + if m != nil { + return m.StepMs + } + return 0 +} + +func (m *ReadHints) GetFunc() string { + if m != nil { + return m.Func + } + return "" +} + +func (m *ReadHints) GetStartMs() int64 { + if m != nil { + return m.StartMs + } + return 0 +} + +func (m *ReadHints) GetEndMs() int64 { + if m != nil { + return m.EndMs + } + return 0 +} + +func (m *ReadHints) GetGrouping() []string { + if m != nil { + return m.Grouping + } + return nil +} + +func (m *ReadHints) GetBy() bool { + if m != nil { + return m.By + } + return false +} + +func (m *ReadHints) GetRangeMs() int64 { + if m != nil { + return m.RangeMs + } + return 0 +} + +// Chunk represents a TSDB chunk. +// Time range [min, max] is inclusive. +type Chunk struct { + MinTimeMs int64 `protobuf:"varint,1,opt,name=min_time_ms,json=minTimeMs,proto3" json:"min_time_ms,omitempty"` + MaxTimeMs int64 `protobuf:"varint,2,opt,name=max_time_ms,json=maxTimeMs,proto3" json:"max_time_ms,omitempty"` + Type Chunk_Encoding `protobuf:"varint,3,opt,name=type,proto3,enum=prometheus_copy.Chunk_Encoding" json:"type,omitempty"` + Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` +} + +func (m *Chunk) Reset() { *m = Chunk{} } +func (m *Chunk) String() string { return proto.CompactTextString(m) } +func (*Chunk) ProtoMessage() {} +func (*Chunk) Descriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{6} +} +func (m *Chunk) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Chunk) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Chunk.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Chunk) XXX_Merge(src proto.Message) { + xxx_messageInfo_Chunk.Merge(m, src) +} +func (m *Chunk) XXX_Size() int { + return m.Size() +} +func (m *Chunk) XXX_DiscardUnknown() { + xxx_messageInfo_Chunk.DiscardUnknown(m) +} + +var xxx_messageInfo_Chunk proto.InternalMessageInfo + +func (m *Chunk) GetMinTimeMs() int64 { + if m != nil { + return m.MinTimeMs + } + return 0 +} + +func (m *Chunk) GetMaxTimeMs() int64 { + if m != nil { + return m.MaxTimeMs + } + return 0 +} + +func (m *Chunk) GetType() Chunk_Encoding { + if m != nil { + return m.Type + } + return Chunk_UNKNOWN +} + +func (m *Chunk) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +// ChunkedSeries represents single, encoded time series. +type ChunkedSeries struct { + // Labels should be sorted. + Labels []Label `protobuf:"bytes,1,rep,name=labels,proto3" json:"labels"` + // Chunks will be in start time order and may overlap. + Chunks []Chunk `protobuf:"bytes,2,rep,name=chunks,proto3" json:"chunks"` +} + +func (m *ChunkedSeries) Reset() { *m = ChunkedSeries{} } +func (m *ChunkedSeries) String() string { return proto.CompactTextString(m) } +func (*ChunkedSeries) ProtoMessage() {} +func (*ChunkedSeries) Descriptor() ([]byte, []int) { + return fileDescriptor_d938547f84707355, []int{7} +} +func (m *ChunkedSeries) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ChunkedSeries) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ChunkedSeries.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ChunkedSeries) XXX_Merge(src proto.Message) { + xxx_messageInfo_ChunkedSeries.Merge(m, src) +} +func (m *ChunkedSeries) XXX_Size() int { + return m.Size() +} +func (m *ChunkedSeries) XXX_DiscardUnknown() { + xxx_messageInfo_ChunkedSeries.DiscardUnknown(m) +} + +var xxx_messageInfo_ChunkedSeries proto.InternalMessageInfo + +func (m *ChunkedSeries) GetLabels() []Label { + if m != nil { + return m.Labels + } + return nil +} + +func (m *ChunkedSeries) GetChunks() []Chunk { + if m != nil { + return m.Chunks + } + return nil +} + +func init() { + proto.RegisterEnum("prometheus_copy.LabelMatcher_Type", LabelMatcher_Type_name, LabelMatcher_Type_value) + proto.RegisterEnum("prometheus_copy.Chunk_Encoding", Chunk_Encoding_name, Chunk_Encoding_value) + proto.RegisterType((*Sample)(nil), "prometheus_copy.Sample") + proto.RegisterType((*TimeSeries)(nil), "prometheus_copy.TimeSeries") + proto.RegisterType((*Label)(nil), "prometheus_copy.Label") + proto.RegisterType((*Labels)(nil), "prometheus_copy.Labels") + proto.RegisterType((*LabelMatcher)(nil), "prometheus_copy.LabelMatcher") + proto.RegisterType((*ReadHints)(nil), "prometheus_copy.ReadHints") + proto.RegisterType((*Chunk)(nil), "prometheus_copy.Chunk") + proto.RegisterType((*ChunkedSeries)(nil), "prometheus_copy.ChunkedSeries") +} + +func init() { proto.RegisterFile("types.proto", fileDescriptor_d938547f84707355) } + +var fileDescriptor_d938547f84707355 = []byte{ + // 561 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x53, 0xc1, 0x6e, 0xd3, 0x40, + 0x10, 0xcd, 0xda, 0x89, 0x9d, 0x4c, 0x4a, 0x89, 0x56, 0xa5, 0x35, 0x15, 0x72, 0x2d, 0x9f, 0x7c, + 0x0a, 0xa2, 0xad, 0xe0, 0x82, 0x38, 0x14, 0x45, 0x42, 0xa2, 0x4e, 0xd5, 0x6d, 0x11, 0x88, 0x4b, + 0xb4, 0x89, 0x17, 0xc7, 0x22, 0x5e, 0x5b, 0xde, 0x0d, 0x6a, 0xd4, 0x9f, 0xe0, 0xcc, 0x5f, 0xc0, + 0x57, 0xf4, 0xd8, 0x23, 0x27, 0x84, 0x92, 0x1f, 0x41, 0xbb, 0x76, 0x12, 0x44, 0x73, 0xa2, 0xb7, + 0x99, 0x79, 0x6f, 0xde, 0x3c, 0xef, 0x8c, 0xa1, 0x2d, 0x67, 0x39, 0x13, 0xdd, 0xbc, 0xc8, 0x64, + 0x86, 0x1f, 0xe6, 0x45, 0x96, 0x32, 0x39, 0x66, 0x53, 0x31, 0x18, 0x65, 0xf9, 0x6c, 0x7f, 0x27, + 0xce, 0xe2, 0x4c, 0x63, 0x4f, 0x55, 0x54, 0xd2, 0xfc, 0x97, 0x60, 0x5d, 0xd0, 0x34, 0x9f, 0x30, + 0xbc, 0x03, 0x8d, 0x2f, 0x74, 0x32, 0x65, 0x0e, 0xf2, 0x50, 0x80, 0x48, 0x99, 0xe0, 0x27, 0xd0, + 0x92, 0x49, 0xca, 0x84, 0xa4, 0x69, 0xee, 0x18, 0x1e, 0x0a, 0x4c, 0xb2, 0x2e, 0xf8, 0xd7, 0x00, + 0x97, 0x49, 0xca, 0x2e, 0x58, 0x91, 0x30, 0x81, 0x8f, 0xc1, 0x9a, 0xd0, 0x21, 0x9b, 0x08, 0x07, + 0x79, 0x66, 0xd0, 0x3e, 0xdc, 0xed, 0xfe, 0xe3, 0xa1, 0x7b, 0xaa, 0xe0, 0x93, 0xfa, 0xcd, 0xaf, + 0x83, 0x1a, 0xa9, 0xb8, 0xf8, 0x05, 0xd8, 0x42, 0x3b, 0x10, 0x8e, 0xa1, 0xdb, 0xf6, 0xee, 0xb4, + 0x95, 0x0e, 0xab, 0xbe, 0x25, 0xdb, 0x7f, 0x06, 0x0d, 0xad, 0x87, 0x31, 0xd4, 0x39, 0x4d, 0x4b, + 0xe3, 0x2d, 0xa2, 0xe3, 0xf5, 0xd7, 0x18, 0xba, 0x58, 0x26, 0xfe, 0x2b, 0xb0, 0x4e, 0xcb, 0xa9, + 0xff, 0xe5, 0xd5, 0xff, 0x86, 0x60, 0x4b, 0xd7, 0x43, 0x2a, 0x47, 0x63, 0x56, 0xe0, 0xe7, 0x50, + 0x57, 0x8f, 0xae, 0x47, 0x6f, 0x1f, 0xfa, 0x9b, 0x45, 0x2a, 0x72, 0xf7, 0x72, 0x96, 0x33, 0xa2, + 0xf9, 0x2b, 0xcb, 0xc6, 0x26, 0xcb, 0xe6, 0xdf, 0x96, 0x03, 0xa8, 0xab, 0x3e, 0x6c, 0x81, 0xd1, + 0x3b, 0xef, 0xd4, 0xb0, 0x0d, 0x66, 0xbf, 0x77, 0xde, 0x41, 0xaa, 0x40, 0x7a, 0x1d, 0x43, 0x17, + 0x48, 0xaf, 0x63, 0xfa, 0xdf, 0x11, 0xb4, 0x08, 0xa3, 0xd1, 0x9b, 0x84, 0x4b, 0x81, 0xf7, 0xc0, + 0x16, 0x92, 0xe5, 0x83, 0x54, 0x68, 0x73, 0x26, 0xb1, 0x54, 0x1a, 0x0a, 0x35, 0xfa, 0xd3, 0x94, + 0x8f, 0x96, 0xa3, 0x55, 0x8c, 0x1f, 0x43, 0x53, 0x48, 0x5a, 0x48, 0xc5, 0x36, 0x35, 0xdb, 0xd6, + 0x79, 0x28, 0xf0, 0x23, 0xb0, 0x18, 0x8f, 0x14, 0x50, 0xd7, 0x40, 0x83, 0xf1, 0x28, 0x14, 0x78, + 0x1f, 0x9a, 0x71, 0x91, 0x4d, 0xf3, 0x84, 0xc7, 0x4e, 0xc3, 0x33, 0x83, 0x16, 0x59, 0xe5, 0x78, + 0x1b, 0x8c, 0xe1, 0xcc, 0xb1, 0x3c, 0x14, 0x34, 0x89, 0x31, 0x9c, 0x29, 0xf5, 0x82, 0xf2, 0x98, + 0x29, 0x11, 0xbb, 0x54, 0xd7, 0x79, 0x28, 0xfc, 0x1f, 0x08, 0x1a, 0xaf, 0xc7, 0x53, 0xfe, 0x19, + 0xbb, 0xd0, 0x4e, 0x13, 0x3e, 0x50, 0xb7, 0xb5, 0xf6, 0xdc, 0x4a, 0x13, 0xae, 0x0e, 0x2c, 0x14, + 0x1a, 0xa7, 0x57, 0x2b, 0xbc, 0x3a, 0xc5, 0x94, 0x5e, 0x55, 0xf8, 0x51, 0xb5, 0x09, 0x53, 0x6f, + 0xe2, 0xe0, 0xce, 0x26, 0xf4, 0x94, 0x6e, 0x8f, 0x8f, 0xb2, 0x28, 0xe1, 0xf1, 0x7a, 0x0d, 0x11, + 0x95, 0x54, 0x7f, 0xda, 0x16, 0xd1, 0xb1, 0xef, 0x41, 0x73, 0xc9, 0xc2, 0x6d, 0xb0, 0xdf, 0xf5, + 0xdf, 0xf6, 0xcf, 0xde, 0xf7, 0xcb, 0x97, 0xff, 0x70, 0x46, 0x3a, 0xc8, 0xbf, 0x86, 0x07, 0x5a, + 0x8d, 0x45, 0xf7, 0x3a, 0xfc, 0x63, 0xb0, 0x46, 0x4a, 0x66, 0x79, 0xf7, 0xbb, 0x9b, 0x3d, 0x2f, + 0xbb, 0x4a, 0xee, 0x89, 0x77, 0x33, 0x77, 0xd1, 0xed, 0xdc, 0x45, 0xbf, 0xe7, 0x2e, 0xfa, 0xba, + 0x70, 0x6b, 0xb7, 0x0b, 0xb7, 0xf6, 0x73, 0xe1, 0xd6, 0x3e, 0x5a, 0xaa, 0x3d, 0x1f, 0x0e, 0x2d, + 0xfd, 0x67, 0x1f, 0xfd, 0x09, 0x00, 0x00, 0xff, 0xff, 0x73, 0xda, 0x4a, 0x37, 0x0f, 0x04, 0x00, + 0x00, +} + +func (m *Sample) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Sample) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Sample) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Timestamp != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x10 + } + if m.Value != 0 { + i -= 8 + encoding_binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.Value)))) + i-- + dAtA[i] = 0x9 + } + return len(dAtA) - i, nil +} + +func (m *TimeSeries) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TimeSeries) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TimeSeries) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Samples) > 0 { + for iNdEx := len(m.Samples) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Samples[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Labels) > 0 { + for iNdEx := len(m.Labels) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Labels[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *Label) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Label) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Label) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Value) > 0 { + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Value))) + i-- + dAtA[i] = 0x12 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Labels) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Labels) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Labels) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Labels) > 0 { + for iNdEx := len(m.Labels) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Labels[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *LabelMatcher) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LabelMatcher) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LabelMatcher) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Value) > 0 { + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Value))) + i-- + dAtA[i] = 0x1a + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if m.Type != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Type)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ReadHints) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ReadHints) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ReadHints) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.RangeMs != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.RangeMs)) + i-- + dAtA[i] = 0x38 + } + if m.By { + i-- + if m.By { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } + if len(m.Grouping) > 0 { + for iNdEx := len(m.Grouping) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Grouping[iNdEx]) + copy(dAtA[i:], m.Grouping[iNdEx]) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Grouping[iNdEx]))) + i-- + dAtA[i] = 0x2a + } + } + if m.EndMs != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.EndMs)) + i-- + dAtA[i] = 0x20 + } + if m.StartMs != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.StartMs)) + i-- + dAtA[i] = 0x18 + } + if len(m.Func) > 0 { + i -= len(m.Func) + copy(dAtA[i:], m.Func) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Func))) + i-- + dAtA[i] = 0x12 + } + if m.StepMs != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.StepMs)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Chunk) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Chunk) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Chunk) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x22 + } + if m.Type != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Type)) + i-- + dAtA[i] = 0x18 + } + if m.MaxTimeMs != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.MaxTimeMs)) + i-- + dAtA[i] = 0x10 + } + if m.MinTimeMs != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.MinTimeMs)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ChunkedSeries) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ChunkedSeries) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ChunkedSeries) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Chunks) > 0 { + for iNdEx := len(m.Chunks) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Chunks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Labels) > 0 { + for iNdEx := len(m.Labels) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Labels[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { + offset -= sovTypes(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Sample) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Value != 0 { + n += 9 + } + if m.Timestamp != 0 { + n += 1 + sovTypes(uint64(m.Timestamp)) + } + return n +} + +func (m *TimeSeries) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Labels) > 0 { + for _, e := range m.Labels { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.Samples) > 0 { + for _, e := range m.Samples { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + return n +} + +func (m *Label) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + +func (m *Labels) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Labels) > 0 { + for _, e := range m.Labels { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + return n +} + +func (m *LabelMatcher) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Type != 0 { + n += 1 + sovTypes(uint64(m.Type)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + +func (m *ReadHints) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.StepMs != 0 { + n += 1 + sovTypes(uint64(m.StepMs)) + } + l = len(m.Func) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.StartMs != 0 { + n += 1 + sovTypes(uint64(m.StartMs)) + } + if m.EndMs != 0 { + n += 1 + sovTypes(uint64(m.EndMs)) + } + if len(m.Grouping) > 0 { + for _, s := range m.Grouping { + l = len(s) + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.By { + n += 2 + } + if m.RangeMs != 0 { + n += 1 + sovTypes(uint64(m.RangeMs)) + } + return n +} + +func (m *Chunk) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.MinTimeMs != 0 { + n += 1 + sovTypes(uint64(m.MinTimeMs)) + } + if m.MaxTimeMs != 0 { + n += 1 + sovTypes(uint64(m.MaxTimeMs)) + } + if m.Type != 0 { + n += 1 + sovTypes(uint64(m.Type)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + +func (m *ChunkedSeries) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Labels) > 0 { + for _, e := range m.Labels { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if len(m.Chunks) > 0 { + for _, e := range m.Chunks { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + return n +} + +func sovTypes(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTypes(x uint64) (n int) { + return sovTypes(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Sample) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Sample: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Sample: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 1 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var v uint64 + if (iNdEx + 8) > l { + return io.ErrUnexpectedEOF + } + v = uint64(encoding_binary.LittleEndian.Uint64(dAtA[iNdEx:])) + iNdEx += 8 + m.Value = float64(math.Float64frombits(v)) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TimeSeries) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TimeSeries: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TimeSeries: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Labels = append(m.Labels, Label{}) + if err := m.Labels[len(m.Labels)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Samples", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Samples = append(m.Samples, Sample{}) + if err := m.Samples[len(m.Samples)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Label) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Label: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Label: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Labels) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Labels: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Labels: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Labels = append(m.Labels, Label{}) + if err := m.Labels[len(m.Labels)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LabelMatcher) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LabelMatcher: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LabelMatcher: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= LabelMatcher_Type(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ReadHints) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ReadHints: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ReadHints: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StepMs", wireType) + } + m.StepMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StepMs |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Func", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Func = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartMs", wireType) + } + m.StartMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartMs |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EndMs", wireType) + } + m.EndMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EndMs |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Grouping", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Grouping = append(m.Grouping, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field By", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.By = bool(v != 0) + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RangeMs", wireType) + } + m.RangeMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RangeMs |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Chunk) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Chunk: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Chunk: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinTimeMs", wireType) + } + m.MinTimeMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinTimeMs |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxTimeMs", wireType) + } + m.MaxTimeMs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxTimeMs |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= Chunk_Encoding(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ChunkedSeries) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ChunkedSeries: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ChunkedSeries: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Labels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Labels = append(m.Labels, Label{}) + if err := m.Labels[len(m.Labels)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Chunks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Chunks = append(m.Chunks, Chunk{}) + if err := m.Chunks[len(m.Chunks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTypes(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTypes + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTypes + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTypes + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTypes = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTypes = fmt.Errorf("proto: unexpected end of group") +) diff --git a/pkg/store/storepb/prompb/types.proto b/pkg/store/storepb/prompb/types.proto new file mode 100644 index 0000000000..698a19a48a --- /dev/null +++ b/pkg/store/storepb/prompb/types.proto @@ -0,0 +1,94 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +// Copyright 2017 Prometheus Team +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; +package prometheus_copy; + +option go_package = "prompb"; + +import "gogoproto/gogo.proto"; + +// Do not generate XXX fields to reduce memory footprint and opening a door +// for zero-copy casts to/from prometheus data types. +option (gogoproto.goproto_unkeyed_all) = false; +option (gogoproto.goproto_unrecognized_all) = false; +option (gogoproto.goproto_sizecache_all) = false; + +message Sample { + double value = 1; + int64 timestamp = 2; +} + +// TimeSeries represents samples and labels for a single time series. +message TimeSeries { + repeated Label labels = 1 [(gogoproto.nullable) = false]; + repeated Sample samples = 2 [(gogoproto.nullable) = false]; +} + +message Label { + string name = 1; + string value = 2; +} + +message Labels { + repeated Label labels = 1 [(gogoproto.nullable) = false]; +} + +// Matcher specifies a rule, which can match or set of labels or not. +message LabelMatcher { + enum Type { + EQ = 0; + NEQ = 1; + RE = 2; + NRE = 3; + } + Type type = 1; + string name = 2; + string value = 3; +} + +message ReadHints { + int64 step_ms = 1; // Query step size in milliseconds. + string func = 2; // String representation of surrounding function or aggregation. + int64 start_ms = 3; // Start time in milliseconds. + int64 end_ms = 4; // End time in milliseconds. + repeated string grouping = 5; // List of label names used in aggregation. + bool by = 6; // Indicate whether it is without or by. + int64 range_ms = 7; // Range vector selector range in milliseconds. +} + +// Chunk represents a TSDB chunk. +// Time range [min, max] is inclusive. +message Chunk { + int64 min_time_ms = 1; + int64 max_time_ms = 2; + + // We require this to match chunkenc.Encoding. + enum Encoding { + UNKNOWN = 0; + XOR = 1; + } + Encoding type = 3; + bytes data = 4; +} + +// ChunkedSeries represents single, encoded time series. +message ChunkedSeries { + // Labels should be sorted. + repeated Label labels = 1 [(gogoproto.nullable) = false]; + // Chunks will be in start time order and may overlap. + repeated Chunk chunks = 2 [(gogoproto.nullable) = false]; +} diff --git a/pkg/store/storepb/rpc.pb.go b/pkg/store/storepb/rpc.pb.go index 0a99b10293..bcf1b154cb 100644 --- a/pkg/store/storepb/rpc.pb.go +++ b/pkg/store/storepb/rpc.pb.go @@ -12,7 +12,8 @@ import ( _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" - prompb "github.com/prometheus/prometheus/prompb" + types "github.com/gogo/protobuf/types" + prompb "github.com/thanos-io/thanos/pkg/store/storepb/prompb" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -38,6 +39,8 @@ const ( StoreType_SIDECAR StoreType = 3 StoreType_STORE StoreType = 4 StoreType_RECEIVE StoreType = 5 + // DEBUG represents some debug StoreAPI components e.g. thanos tools store-api-serve. + StoreType_DEBUG StoreType = 6 ) var StoreType_name = map[int32]string{ @@ -47,6 +50,7 @@ var StoreType_name = map[int32]string{ 3: "SIDECAR", 4: "STORE", 5: "RECEIVE", + 6: "DEBUG", } var StoreType_value = map[string]int32{ @@ -56,6 +60,7 @@ var StoreType_value = map[string]int32{ "SIDECAR": 3, "STORE": 4, "RECEIVE": 5, + "DEBUG": 6, } func (x StoreType) String() string { @@ -373,6 +378,7 @@ type SeriesResponse struct { // Types that are valid to be assigned to Result: // *SeriesResponse_Series // *SeriesResponse_Warning + // *SeriesResponse_Hints Result isSeriesResponse_Result `protobuf_oneof:"result"` } @@ -421,9 +427,13 @@ type SeriesResponse_Series struct { type SeriesResponse_Warning struct { Warning string `protobuf:"bytes,2,opt,name=warning,proto3,oneof" json:"warning,omitempty"` } +type SeriesResponse_Hints struct { + Hints *types.Any `protobuf:"bytes,3,opt,name=hints,proto3,oneof" json:"hints,omitempty"` +} func (*SeriesResponse_Series) isSeriesResponse_Result() {} func (*SeriesResponse_Warning) isSeriesResponse_Result() {} +func (*SeriesResponse_Hints) isSeriesResponse_Result() {} func (m *SeriesResponse) GetResult() isSeriesResponse_Result { if m != nil { @@ -446,11 +456,19 @@ func (m *SeriesResponse) GetWarning() string { return "" } +func (m *SeriesResponse) GetHints() *types.Any { + if x, ok := m.GetResult().(*SeriesResponse_Hints); ok { + return x.Hints + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*SeriesResponse) XXX_OneofWrappers() []interface{} { return []interface{}{ (*SeriesResponse_Series)(nil), (*SeriesResponse_Warning)(nil), + (*SeriesResponse_Hints)(nil), } } @@ -754,72 +772,75 @@ func init() { func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) } var fileDescriptor_77a6da22d6a3feb1 = []byte{ - // 1036 bytes of a gzipped FileDescriptorProto + // 1079 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0xf7, 0xc4, 0xf9, 0xfb, 0xd2, 0x04, 0x77, 0x9a, 0x16, 0x37, 0x48, 0x69, 0x65, 0x09, 0x29, - 0x2c, 0x4b, 0xba, 0x64, 0xc5, 0x22, 0xd0, 0x4a, 0x28, 0x4d, 0xb3, 0xdb, 0x88, 0x36, 0x85, 0x49, - 0xbb, 0xe5, 0xcf, 0xa1, 0xeb, 0xb4, 0x83, 0x6b, 0x6d, 0x62, 0x1b, 0xcf, 0x84, 0xb6, 0x17, 0x0e, - 0x7c, 0x02, 0xae, 0x7c, 0x07, 0xbe, 0x05, 0x97, 0x1e, 0xf7, 0x08, 0x17, 0x04, 0xed, 0x17, 0x41, - 0x33, 0x1e, 0x27, 0x76, 0x29, 0x15, 0xa8, 0xe2, 0x36, 0xef, 0xfd, 0x9e, 0xdf, 0x9f, 0xdf, 0xbc, - 0xf7, 0x3c, 0x50, 0x0a, 0x83, 0xe3, 0x56, 0x10, 0xfa, 0xdc, 0xc7, 0x79, 0x7e, 0x6a, 0x7b, 0x3e, - 0xab, 0x97, 0xf9, 0x45, 0x40, 0x59, 0xa4, 0xac, 0x97, 0xc3, 0xe9, 0x78, 0x26, 0xd4, 0x1c, 0xdf, - 0xf1, 0xe5, 0x71, 0x43, 0x9c, 0x94, 0xf6, 0xb1, 0xe3, 0xf2, 0xd3, 0xe9, 0xa8, 0x75, 0xec, 0x4f, - 0x36, 0x82, 0xd0, 0x9f, 0x50, 0x7e, 0x4a, 0xa7, 0xec, 0xe6, 0x31, 0x18, 0x6d, 0x24, 0xfc, 0x5a, - 0x6f, 0x40, 0xe5, 0x30, 0x74, 0x39, 0x25, 0x94, 0x05, 0xbe, 0xc7, 0xa8, 0xf5, 0x3d, 0x2c, 0x28, - 0xc5, 0xb7, 0x53, 0xca, 0x38, 0x7e, 0x0a, 0xc0, 0xdd, 0x09, 0x65, 0x34, 0x74, 0x29, 0x33, 0xd1, - 0xba, 0xde, 0x2c, 0xb7, 0x57, 0x5a, 0x73, 0xa7, 0xad, 0x7d, 0x77, 0x42, 0x87, 0x12, 0xdd, 0xcc, - 0x5e, 0xfe, 0xbe, 0xa6, 0x91, 0x84, 0x3d, 0x5e, 0x81, 0x3c, 0xa7, 0x9e, 0xed, 0x71, 0x33, 0xb3, - 0x8e, 0x9a, 0x25, 0xa2, 0x24, 0x6c, 0x42, 0x21, 0xa4, 0xc1, 0xd8, 0x3d, 0xb6, 0x4d, 0x7d, 0x1d, - 0x35, 0x75, 0x12, 0x8b, 0x56, 0x05, 0xca, 0x7d, 0xef, 0x1b, 0x5f, 0x85, 0xb7, 0x7e, 0x43, 0xb0, - 0x10, 0xc9, 0x51, 0x7e, 0xf8, 0x5d, 0xc8, 0x8f, 0xed, 0x11, 0x1d, 0xc7, 0xb9, 0x54, 0x5a, 0x11, - 0x5d, 0xad, 0x1d, 0xa1, 0x55, 0x29, 0x28, 0x13, 0xbc, 0x0a, 0xc5, 0x89, 0xeb, 0x1d, 0x89, 0x84, - 0x64, 0x02, 0x3a, 0x29, 0x4c, 0x5c, 0x4f, 0x64, 0x2c, 0x21, 0xfb, 0x3c, 0x82, 0x54, 0x0a, 0x13, - 0xfb, 0x5c, 0x42, 0x1b, 0x50, 0x62, 0xdc, 0x0f, 0xe9, 0xfe, 0x45, 0x40, 0xcd, 0xec, 0x3a, 0x6a, - 0x56, 0xdb, 0x8b, 0x71, 0x94, 0x61, 0x0c, 0x90, 0xb9, 0x0d, 0xfe, 0x00, 0x40, 0x06, 0x3c, 0x62, - 0x94, 0x33, 0x33, 0x27, 0xf3, 0x32, 0x52, 0x79, 0x0d, 0x29, 0x57, 0xa9, 0x95, 0xc6, 0x4a, 0x66, - 0xd6, 0x87, 0x50, 0x8c, 0xc1, 0xff, 0x54, 0x96, 0xf5, 0x93, 0x0e, 0x95, 0x88, 0xf2, 0xf8, 0x96, - 0x92, 0x85, 0xa2, 0x7f, 0x2e, 0x34, 0x93, 0x2e, 0xf4, 0x89, 0x80, 0xf8, 0xf1, 0x29, 0x0d, 0x99, - 0xa9, 0xcb, 0xb0, 0xb5, 0x54, 0xd8, 0xdd, 0x08, 0x54, 0xd1, 0x67, 0xb6, 0xb8, 0x0d, 0xcb, 0xc2, - 0x65, 0x48, 0x99, 0x3f, 0x9e, 0x72, 0xd7, 0xf7, 0x8e, 0xce, 0x5c, 0xef, 0xc4, 0x3f, 0x93, 0x64, - 0xe9, 0x64, 0x69, 0x62, 0x9f, 0x93, 0x19, 0x76, 0x28, 0x21, 0xfc, 0x10, 0xc0, 0x76, 0x9c, 0x90, - 0x3a, 0x36, 0xa7, 0x11, 0x47, 0xd5, 0xf6, 0x42, 0x1c, 0xad, 0xe3, 0x38, 0x21, 0x49, 0xe0, 0xf8, - 0x63, 0x58, 0x0d, 0xec, 0x90, 0xbb, 0xf6, 0x58, 0x44, 0x91, 0x37, 0x7f, 0x74, 0xe2, 0x32, 0x7b, - 0x34, 0xa6, 0x27, 0x66, 0x7e, 0x1d, 0x35, 0x8b, 0xe4, 0x4d, 0x65, 0x10, 0x77, 0xc6, 0x96, 0x82, - 0xf1, 0xd7, 0xb7, 0x7c, 0xcb, 0x78, 0x68, 0x73, 0xea, 0x5c, 0x98, 0x05, 0x79, 0x9d, 0x6b, 0x71, - 0xe0, 0xcf, 0xd2, 0x3e, 0x86, 0xca, 0xec, 0x6f, 0xce, 0x63, 0x00, 0xaf, 0x41, 0x99, 0xbd, 0x72, - 0x83, 0xa3, 0xe3, 0xd3, 0xa9, 0xf7, 0x8a, 0x99, 0x45, 0x99, 0x0a, 0x08, 0x55, 0x57, 0x6a, 0xac, - 0x97, 0x50, 0x8d, 0xaf, 0x46, 0x75, 0x6c, 0x13, 0xf2, 0xb3, 0xe9, 0x41, 0xcd, 0x72, 0xbb, 0x3a, - 0xeb, 0x25, 0xa9, 0xdd, 0xd6, 0x88, 0xc2, 0x71, 0x1d, 0x0a, 0x67, 0x76, 0xe8, 0xb9, 0x9e, 0x13, - 0x8d, 0xcb, 0xb6, 0x46, 0x62, 0xc5, 0x66, 0x11, 0xf2, 0x21, 0x65, 0xd3, 0x31, 0xb7, 0x7e, 0x46, - 0xb0, 0x28, 0xaf, 0x67, 0x60, 0x4f, 0xe6, 0x1d, 0x70, 0x27, 0x63, 0xe8, 0x1e, 0x8c, 0x65, 0xee, - 0xc7, 0x98, 0xf5, 0x0c, 0x70, 0x32, 0x5b, 0x45, 0x4a, 0x0d, 0x72, 0x9e, 0x50, 0xc8, 0x76, 0x2f, - 0x91, 0x48, 0xc0, 0x75, 0x28, 0xaa, 0x7a, 0x99, 0x99, 0x91, 0xc0, 0x4c, 0xb6, 0x7e, 0x41, 0xca, - 0xd1, 0x0b, 0x7b, 0x3c, 0x9d, 0xd7, 0x5d, 0x83, 0x9c, 0x9c, 0x0a, 0x59, 0x63, 0x89, 0x44, 0xc2, - 0xdd, 0x6c, 0x64, 0xee, 0xc1, 0x86, 0x7e, 0x4f, 0x36, 0xfa, 0xb0, 0x94, 0x2a, 0x42, 0xd1, 0xb1, - 0x02, 0xf9, 0xef, 0xa4, 0x46, 0xf1, 0xa1, 0xa4, 0x3b, 0x09, 0xb9, 0x44, 0xb0, 0x40, 0xc4, 0x5f, - 0x21, 0xa6, 0xe2, 0x3d, 0xc8, 0x8a, 0xd5, 0x2e, 0x99, 0xa8, 0xb6, 0x57, 0xe3, 0x1c, 0x93, 0x36, - 0x2d, 0xb9, 0xba, 0xa4, 0xd9, 0xff, 0x7b, 0xeb, 0x0f, 0x21, 0x2b, 0x57, 0x63, 0x01, 0xf4, 0xce, - 0xce, 0x8e, 0xa1, 0xe1, 0x05, 0x28, 0x76, 0x76, 0x7a, 0x64, 0xbf, 0x3f, 0x78, 0x6e, 0x20, 0x5c, - 0x81, 0x12, 0xe9, 0x75, 0xf7, 0xc8, 0x96, 0x10, 0x33, 0xd6, 0x4b, 0xa8, 0xa8, 0x2c, 0x15, 0x1f, - 0xef, 0x40, 0xce, 0x09, 0xfd, 0x69, 0xa0, 0x46, 0x66, 0x31, 0x59, 0xcb, 0x73, 0x01, 0x6c, 0x6b, - 0x24, 0xb2, 0xf8, 0x77, 0x43, 0xf3, 0x80, 0x40, 0x69, 0xb6, 0xba, 0x71, 0x19, 0x0a, 0x07, 0x83, - 0x4f, 0x07, 0x7b, 0x87, 0x03, 0x43, 0xc3, 0x25, 0xc8, 0x7d, 0x7e, 0xd0, 0x23, 0x5f, 0x1a, 0x08, - 0x17, 0x21, 0x4b, 0x0e, 0x76, 0x7a, 0x46, 0x46, 0x58, 0x0c, 0xfb, 0x5b, 0xbd, 0x6e, 0x87, 0x18, - 0xba, 0xb0, 0x18, 0xee, 0xef, 0x91, 0x9e, 0x91, 0x15, 0x7a, 0xd2, 0xeb, 0xf6, 0xfa, 0x2f, 0x7a, - 0x46, 0xee, 0xc1, 0x26, 0x64, 0xc5, 0xe2, 0x12, 0x35, 0x92, 0xce, 0x61, 0xe4, 0xaa, 0xbb, 0x77, - 0x30, 0xd8, 0x37, 0x90, 0xd0, 0x0d, 0x0f, 0x76, 0x8d, 0x8c, 0x38, 0xec, 0xf6, 0x07, 0x86, 0x2e, - 0x0f, 0x9d, 0x2f, 0x22, 0x1f, 0xd2, 0xaa, 0x47, 0x8c, 0x5c, 0xfb, 0x87, 0x0c, 0xe4, 0x64, 0x62, - 0xf8, 0x7d, 0xc8, 0x8a, 0x1f, 0x1d, 0x5e, 0x8a, 0x6b, 0x4d, 0xfc, 0x06, 0xeb, 0xb5, 0xb4, 0x52, - 0xb1, 0xf4, 0x11, 0xe4, 0xa3, 0x1d, 0x82, 0x97, 0xd3, 0x3b, 0x25, 0xfe, 0x6c, 0xe5, 0xa6, 0x3a, - 0xfa, 0xf0, 0x11, 0xc2, 0x5d, 0x80, 0xf9, 0x54, 0xe2, 0xd5, 0xd4, 0xda, 0x4f, 0xee, 0x95, 0x7a, - 0xfd, 0x36, 0x48, 0xc5, 0x7f, 0x06, 0xe5, 0x44, 0x33, 0xe3, 0xb4, 0x69, 0x6a, 0x4c, 0xeb, 0x6f, - 0xdd, 0x8a, 0x45, 0x7e, 0xda, 0x03, 0xa8, 0xca, 0x37, 0x87, 0x98, 0xbf, 0x88, 0x8c, 0xa7, 0x50, - 0x26, 0x74, 0xe2, 0x73, 0x2a, 0xf5, 0x78, 0x56, 0x7e, 0xf2, 0x69, 0x52, 0x5f, 0xbe, 0xa1, 0x55, - 0x2f, 0x18, 0xad, 0xfd, 0x09, 0xe4, 0x64, 0x3b, 0xe1, 0x27, 0xf1, 0xa1, 0x76, 0xdb, 0x30, 0xcc, - 0x1d, 0xa4, 0x9a, 0xef, 0x11, 0xda, 0x7c, 0xfb, 0xf2, 0xcf, 0x86, 0x76, 0x79, 0xd5, 0x40, 0xaf, - 0xaf, 0x1a, 0xe8, 0x8f, 0xab, 0x06, 0xfa, 0xf1, 0xba, 0xa1, 0xbd, 0xbe, 0x6e, 0x68, 0xbf, 0x5e, - 0x37, 0xb4, 0xaf, 0x0a, 0xf2, 0xcf, 0x1f, 0x8c, 0x46, 0x79, 0xf9, 0x86, 0x7a, 0xfc, 0x57, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x51, 0xa1, 0x1b, 0x77, 0xbd, 0x09, 0x00, 0x00, + 0x14, 0xf7, 0xc4, 0xf9, 0xfb, 0xd2, 0x04, 0xef, 0x34, 0x2d, 0x6e, 0x56, 0x4a, 0x2b, 0x4b, 0x48, + 0x61, 0x29, 0xe9, 0x12, 0xc4, 0x22, 0x10, 0x12, 0x4a, 0x53, 0x6f, 0x1b, 0xd1, 0xa6, 0x30, 0x69, + 0xb6, 0xfc, 0x11, 0x0a, 0x4e, 0x3b, 0xeb, 0x58, 0xeb, 0xd8, 0xc6, 0x76, 0x68, 0x73, 0x85, 0x3b, + 0xe2, 0xca, 0x77, 0xe0, 0x5b, 0x70, 0xe9, 0x71, 0x8f, 0x70, 0x41, 0xd0, 0x7e, 0x11, 0x34, 0xe3, + 0x71, 0x62, 0x2f, 0xa5, 0x12, 0xaa, 0xb8, 0xcd, 0xfb, 0xfd, 0xde, 0xcc, 0x7b, 0xef, 0x37, 0xf3, + 0x66, 0x06, 0x4a, 0xbe, 0x77, 0xd6, 0xf2, 0x7c, 0x37, 0x74, 0x71, 0x3e, 0x9c, 0x18, 0x8e, 0x1b, + 0xd4, 0xcb, 0xe1, 0xdc, 0xa3, 0x41, 0x04, 0xd6, 0xcb, 0xfe, 0xcc, 0x5e, 0x18, 0x35, 0xd3, 0x35, + 0x5d, 0x3e, 0xdc, 0x61, 0x23, 0x81, 0x62, 0xcf, 0x77, 0xa7, 0xde, 0x78, 0x27, 0x39, 0x6d, 0xc3, + 0x74, 0x5d, 0xd3, 0xa6, 0x3b, 0xdc, 0x1a, 0xcf, 0x9e, 0xef, 0x18, 0xce, 0x3c, 0xa2, 0xb4, 0xd7, + 0xa0, 0x72, 0xea, 0x5b, 0x21, 0x25, 0x34, 0xf0, 0x5c, 0x27, 0xa0, 0xda, 0x0f, 0x08, 0x56, 0x04, + 0xf2, 0xed, 0x8c, 0x06, 0x21, 0xee, 0x00, 0x84, 0xd6, 0x94, 0x06, 0xd4, 0xb7, 0x68, 0xa0, 0xa2, + 0x2d, 0xb9, 0x59, 0x6e, 0x3f, 0x64, 0xb3, 0xa7, 0x34, 0x9c, 0xd0, 0x59, 0x30, 0x3a, 0x73, 0xbd, + 0x79, 0xeb, 0xc4, 0x9a, 0xd2, 0x01, 0x77, 0xd9, 0xcd, 0x5e, 0xfd, 0xb1, 0x29, 0x91, 0xc4, 0x24, + 0xbc, 0x0e, 0xf9, 0x90, 0x3a, 0x86, 0x13, 0xaa, 0x99, 0x2d, 0xd4, 0x2c, 0x11, 0x61, 0x61, 0x15, + 0x0a, 0x3e, 0xf5, 0x6c, 0xeb, 0xcc, 0x50, 0xe5, 0x2d, 0xd4, 0x94, 0x49, 0x6c, 0x6a, 0x15, 0x28, + 0xf7, 0x9c, 0xe7, 0xae, 0xc8, 0x41, 0xfb, 0x1d, 0xc1, 0x4a, 0x64, 0x47, 0x59, 0xe2, 0xb7, 0x20, + 0x6f, 0x1b, 0x63, 0x6a, 0xc7, 0x09, 0x55, 0x5a, 0x91, 0x5c, 0xad, 0x43, 0x86, 0x8a, 0x14, 0x84, + 0x0b, 0xde, 0x80, 0xe2, 0xd4, 0x72, 0x46, 0x2c, 0x21, 0x9e, 0x80, 0x4c, 0x0a, 0x53, 0xcb, 0x61, + 0x19, 0x73, 0xca, 0xb8, 0x8c, 0x28, 0x91, 0xc2, 0xd4, 0xb8, 0xe4, 0xd4, 0x0e, 0x94, 0x82, 0xd0, + 0xf5, 0xe9, 0xc9, 0xdc, 0xa3, 0x6a, 0x76, 0x0b, 0x35, 0xab, 0xed, 0x07, 0x71, 0x94, 0x41, 0x4c, + 0x90, 0xa5, 0x0f, 0x7e, 0x0f, 0x80, 0x07, 0x1c, 0x05, 0x34, 0x0c, 0xd4, 0x1c, 0xcf, 0x4b, 0x49, + 0xe5, 0x35, 0xa0, 0xa1, 0x48, 0xad, 0x64, 0x0b, 0x3b, 0xd0, 0xde, 0x87, 0x62, 0x4c, 0xfe, 0xa7, + 0xb2, 0xb4, 0x9f, 0x65, 0xa8, 0x44, 0x92, 0xc7, 0x5b, 0x95, 0x2c, 0x14, 0xfd, 0x7b, 0xa1, 0x99, + 0x74, 0xa1, 0x4f, 0x18, 0x15, 0x9e, 0x4d, 0xa8, 0x1f, 0xa8, 0x32, 0x0f, 0x5b, 0x4b, 0x85, 0x3d, + 0x8a, 0x48, 0x11, 0x7d, 0xe1, 0x8b, 0xdb, 0xb0, 0xc6, 0x96, 0xf4, 0x69, 0xe0, 0xda, 0xb3, 0xd0, + 0x72, 0x9d, 0xd1, 0x85, 0xe5, 0x9c, 0xbb, 0x17, 0x5c, 0x2c, 0x99, 0xac, 0x4e, 0x8d, 0x4b, 0xb2, + 0xe0, 0x4e, 0x39, 0x85, 0xb7, 0x01, 0x0c, 0xd3, 0xf4, 0xa9, 0x69, 0x84, 0x34, 0xd2, 0xa8, 0xda, + 0x5e, 0x89, 0xa3, 0x75, 0x4c, 0xd3, 0x27, 0x09, 0x1e, 0x7f, 0x08, 0x1b, 0x9e, 0xe1, 0x87, 0x96, + 0x61, 0xb3, 0x28, 0x7c, 0xe7, 0x47, 0xe7, 0x56, 0x60, 0x8c, 0x6d, 0x7a, 0xae, 0xe6, 0xb7, 0x50, + 0xb3, 0x48, 0x5e, 0x17, 0x0e, 0xf1, 0xc9, 0xd8, 0x13, 0x34, 0xfe, 0xea, 0x96, 0xb9, 0x41, 0xe8, + 0x1b, 0x21, 0x35, 0xe7, 0x6a, 0x81, 0x6f, 0xe7, 0x66, 0x1c, 0xf8, 0xd3, 0xf4, 0x1a, 0x03, 0xe1, + 0xf6, 0x8f, 0xc5, 0x63, 0x02, 0x6f, 0x42, 0x39, 0x78, 0x61, 0x79, 0xa3, 0xb3, 0xc9, 0xcc, 0x79, + 0x11, 0xa8, 0x45, 0x9e, 0x0a, 0x30, 0xa8, 0xcb, 0x11, 0xed, 0x47, 0x04, 0xd5, 0x78, 0x6f, 0xc4, + 0x91, 0x6d, 0x42, 0x7e, 0xd1, 0x43, 0xa8, 0x59, 0x6e, 0x57, 0x17, 0x87, 0x89, 0xa3, 0x07, 0x12, + 0x11, 0x3c, 0xae, 0x43, 0xe1, 0xc2, 0xf0, 0x1d, 0xcb, 0x31, 0xa3, 0x7e, 0x39, 0x90, 0x48, 0x0c, + 0xe0, 0x6d, 0xc8, 0x4d, 0x2c, 0x27, 0x0c, 0xf8, 0x69, 0x65, 0x3b, 0x15, 0xb5, 0x76, 0x2b, 0x6e, + 0xed, 0x56, 0xc7, 0x99, 0x1f, 0x48, 0x24, 0x72, 0xda, 0x2d, 0x42, 0xde, 0xa7, 0xc1, 0xcc, 0x0e, + 0xb5, 0x5f, 0x10, 0x3c, 0xe0, 0xbb, 0xd9, 0x37, 0xa6, 0xcb, 0x03, 0x73, 0xa7, 0xc0, 0xe8, 0x1e, + 0x02, 0x67, 0xee, 0x27, 0xb0, 0xf6, 0x14, 0x70, 0x32, 0x5b, 0x21, 0x61, 0x0d, 0x72, 0x0e, 0x03, + 0x78, 0x77, 0x94, 0x48, 0x64, 0xe0, 0x3a, 0x14, 0x85, 0x3a, 0x81, 0x9a, 0xe1, 0xc4, 0xc2, 0xd6, + 0x7e, 0x45, 0x62, 0xa1, 0x67, 0x86, 0x3d, 0x5b, 0xd6, 0x5d, 0x83, 0x1c, 0x6f, 0x22, 0x5e, 0x63, + 0x89, 0x44, 0xc6, 0xdd, 0x6a, 0x64, 0xee, 0xa1, 0x86, 0x7c, 0x4f, 0x35, 0x7a, 0xb0, 0x9a, 0x2a, + 0x42, 0xc8, 0xb1, 0x0e, 0xf9, 0xef, 0x38, 0x22, 0xf4, 0x10, 0xd6, 0x9d, 0x82, 0x5c, 0x21, 0x58, + 0x21, 0xec, 0x11, 0x89, 0xa5, 0x78, 0x1b, 0xb2, 0xec, 0xa9, 0xe0, 0x4a, 0x54, 0xdb, 0x1b, 0x71, + 0x8e, 0x49, 0x9f, 0x16, 0xbf, 0xe9, 0xb8, 0xdb, 0xff, 0xbb, 0xeb, 0xdb, 0x90, 0xe5, 0x37, 0x69, + 0x01, 0xe4, 0xce, 0xe1, 0xa1, 0x22, 0xe1, 0x15, 0x28, 0x76, 0x0e, 0x75, 0x72, 0xd2, 0xeb, 0xef, + 0x2b, 0x08, 0x57, 0xa0, 0x44, 0xf4, 0xee, 0x31, 0xd9, 0x63, 0x66, 0x46, 0xfb, 0x06, 0x2a, 0x22, + 0x4b, 0xa1, 0xc7, 0x9b, 0x90, 0x33, 0x7d, 0x77, 0xe6, 0x89, 0x06, 0x7b, 0x90, 0xac, 0x65, 0x9f, + 0x11, 0xac, 0x31, 0xb8, 0xc7, 0x5d, 0x2d, 0xb6, 0x6c, 0x9a, 0x47, 0x5f, 0x43, 0x69, 0x71, 0xd3, + 0xe3, 0x32, 0x14, 0x86, 0xfd, 0x4f, 0xfa, 0xc7, 0xa7, 0x7d, 0x45, 0xc2, 0x25, 0xc8, 0x7d, 0x36, + 0xd4, 0xc9, 0x17, 0x0a, 0xc2, 0x45, 0xc8, 0x92, 0xe1, 0xa1, 0xae, 0x64, 0x98, 0xc7, 0xa0, 0xb7, + 0xa7, 0x77, 0x3b, 0x44, 0x91, 0x99, 0xc7, 0xe0, 0xe4, 0x98, 0xe8, 0x4a, 0x96, 0xe1, 0x44, 0xef, + 0xea, 0xbd, 0x67, 0xba, 0x92, 0x63, 0xf8, 0x9e, 0xbe, 0x3b, 0xdc, 0x57, 0xf2, 0x8f, 0x76, 0x21, + 0xcb, 0xae, 0x3c, 0x56, 0x2e, 0xe9, 0x9c, 0x46, 0xab, 0x76, 0x8f, 0x87, 0xfd, 0x13, 0x05, 0x31, + 0x6c, 0x30, 0x3c, 0x52, 0x32, 0x6c, 0x70, 0xd4, 0xeb, 0x2b, 0x32, 0x1f, 0x74, 0x3e, 0x8f, 0x96, + 0xe3, 0x5e, 0x3a, 0x51, 0x72, 0xed, 0xef, 0x33, 0x90, 0xe3, 0x39, 0xe2, 0x77, 0x20, 0xcb, 0x9e, + 0x48, 0xbc, 0x1a, 0x97, 0x9d, 0x78, 0x40, 0xeb, 0xb5, 0x34, 0x28, 0x04, 0xfb, 0x00, 0xf2, 0xd1, + 0xe5, 0x83, 0xd7, 0xd2, 0x97, 0x51, 0x3c, 0x6d, 0xfd, 0x55, 0x38, 0x9a, 0xf8, 0x18, 0xe1, 0x2e, + 0xc0, 0xb2, 0x41, 0xf1, 0x46, 0xea, 0xc1, 0x48, 0x5e, 0x31, 0xf5, 0xfa, 0x6d, 0x94, 0x88, 0xff, + 0x14, 0xca, 0x89, 0x73, 0x8d, 0xd3, 0xae, 0xa9, 0x8e, 0xad, 0x3f, 0xbc, 0x95, 0x8b, 0xd6, 0x69, + 0xf7, 0xa1, 0xca, 0xbf, 0x2c, 0xac, 0x15, 0x23, 0x31, 0x3e, 0x82, 0x32, 0xa1, 0x53, 0x37, 0xa4, + 0x1c, 0xc7, 0x8b, 0xf2, 0x93, 0x3f, 0x9b, 0xfa, 0xda, 0x2b, 0xa8, 0xf8, 0x01, 0x49, 0xed, 0x8f, + 0x21, 0xc7, 0x4f, 0x16, 0x7e, 0x12, 0x0f, 0x6a, 0xb7, 0xf5, 0xc5, 0x72, 0x81, 0xd4, 0x39, 0x7c, + 0x8c, 0x76, 0xdf, 0xb8, 0xfa, 0xab, 0x21, 0x5d, 0x5d, 0x37, 0xd0, 0xcb, 0xeb, 0x06, 0xfa, 0xf3, + 0xba, 0x81, 0x7e, 0xba, 0x69, 0x48, 0x2f, 0x6f, 0x1a, 0xd2, 0x6f, 0x37, 0x0d, 0xe9, 0xcb, 0x02, + 0xff, 0x33, 0x78, 0xe3, 0x71, 0x9e, 0xdf, 0xda, 0xef, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xd7, + 0xee, 0xf6, 0x38, 0xf7, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1597,6 +1618,27 @@ func (m *SeriesResponse_Warning) MarshalToSizedBuffer(dAtA []byte) (int, error) dAtA[i] = 0x12 return len(dAtA) - i, nil } +func (m *SeriesResponse_Hints) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SeriesResponse_Hints) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Hints != nil { + { + size, err := m.Hints.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintRpc(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} func (m *LabelNamesRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2032,6 +2074,18 @@ func (m *SeriesResponse_Warning) Size() (n int) { n += 1 + l + sovRpc(uint64(l)) return n } +func (m *SeriesResponse_Hints) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Hints != nil { + l = m.Hints.Size() + n += 1 + l + sovRpc(uint64(l)) + } + return n +} func (m *LabelNamesRequest) Size() (n int) { if m == nil { return 0 @@ -3041,6 +3095,41 @@ func (m *SeriesResponse) Unmarshal(dAtA []byte) error { } m.Result = &SeriesResponse_Warning{string(dAtA[iNdEx:postIndex])} iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hints", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthRpc + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &types.Any{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Result = &SeriesResponse_Hints{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRpc(dAtA[iNdEx:]) diff --git a/pkg/store/storepb/rpc.proto b/pkg/store/storepb/rpc.proto index 30ec66106d..f93602fe11 100644 --- a/pkg/store/storepb/rpc.proto +++ b/pkg/store/storepb/rpc.proto @@ -7,7 +7,8 @@ package thanos; import "types.proto"; import "rules.proto"; import "gogoproto/gogo.proto"; -import "github.com/prometheus/prometheus/prompb/types.proto"; +import "prompb/types.proto"; +import "google/protobuf/any.proto"; option go_package = "storepb"; @@ -22,7 +23,7 @@ option (gogoproto.goproto_unkeyed_all) = false; option (gogoproto.goproto_unrecognized_all) = false; option (gogoproto.goproto_sizecache_all) = false; -/// Store reprents API against instance that stores XOR encoded values with label set metadata (e.g Prometheus metrics). +/// Store represents API against instance that stores XOR encoded values with label set metadata (e.g Prometheus metrics). service Store { /// Info returns meta information about a store e.g labels that makes that store unique as well as time range that is /// available. @@ -54,7 +55,7 @@ message WriteResponse { } message WriteRequest { - repeated prometheus.TimeSeries timeseries = 1 [(gogoproto.nullable) = false]; + repeated prometheus_copy.TimeSeries timeseries = 1 [(gogoproto.nullable) = false]; string tenant = 2; int64 replica = 3; } @@ -68,6 +69,8 @@ enum StoreType { SIDECAR = 3; STORE = 4; RECEIVE = 5; + // DEBUG represents some debug StoreAPI components e.g. thanos tools store-api-serve. + DEBUG = 6; } message InfoResponse { @@ -118,6 +121,13 @@ message SeriesResponse { /// warning is considered an information piece in place of series for warning purposes. /// It is used to warn store API user about suspicious cases or partial response (if enabled). string warning = 2; + + /// hints is an opaque data structure that can be used to carry additional information from + /// the store. The content of this field and whether it's supported depends on the + /// implementation of a specific store. It's also implementation specific if it's allowed that + /// multiple SeriesResponse frames contain hints for a single Series() request and how should they + /// be handled in such case (ie. merged vs keep the first/last one). + google.protobuf.Any hints = 3; } } diff --git a/pkg/store/tsdb.go b/pkg/store/tsdb.go index 3d9baf3776..59e9922dfd 100644 --- a/pkg/store/tsdb.go +++ b/pkg/store/tsdb.go @@ -28,7 +28,7 @@ import ( type TSDBStore struct { logger log.Logger db *tsdb.DB - component component.SourceStoreAPI + component component.StoreAPI externalLabels labels.Labels } @@ -39,7 +39,7 @@ type ReadWriteTSDBStore struct { } // NewTSDBStore creates a new TSDBStore. -func NewTSDBStore(logger log.Logger, _ prometheus.Registerer, db *tsdb.DB, component component.SourceStoreAPI, externalLabels labels.Labels) *TSDBStore { +func NewTSDBStore(logger log.Logger, _ prometheus.Registerer, db *tsdb.DB, component component.StoreAPI, externalLabels labels.Labels) *TSDBStore { if logger == nil { logger = log.NewNopLogger() } diff --git a/pkg/testutil/e2eutil/prometheus.go b/pkg/testutil/e2eutil/prometheus.go index 8d16d47aad..becbd23672 100644 --- a/pkg/testutil/e2eutil/prometheus.go +++ b/pkg/testutil/e2eutil/prometheus.go @@ -4,6 +4,7 @@ package e2eutil import ( + "bytes" "context" "encoding/json" "fmt" @@ -25,6 +26,7 @@ import ( "github.com/oklog/ulid" "github.com/pkg/errors" "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/pkg/timestamp" "github.com/prometheus/prometheus/tsdb" "github.com/prometheus/prometheus/tsdb/index" "github.com/thanos-io/thanos/pkg/block/metadata" @@ -334,81 +336,22 @@ func CreateEmptyBlock(dir string, mint int64, maxt int64, extLset labels.Labels, return uid, nil } -// CreateBlockWithBlockDelay writes a block with the given series and numSamples samples each. -// Samples will be in the time range [mint, maxt) -// Block ID will be created with a delay of time duration blockDelay. -func CreateBlockWithBlockDelay( +// CreateBlock writes a block with the given series and numSamples samples each. +// Samples will be in the time range [mint, maxt). +func CreateBlock( ctx context.Context, dir string, series []labels.Labels, numSamples int, mint, maxt int64, - blockDelay time.Duration, extLset labels.Labels, resolution int64, ) (id ulid.ULID, err error) { - blockID, err := createBlock(ctx, dir, series, numSamples, mint, maxt, extLset, resolution, false) - if err != nil { - return id, errors.Wrap(err, "block creation") - } - - id, err = ulid.New(uint64(time.Unix(int64(blockID.Time()), 0).Add(-blockDelay*1000).Unix()), nil) - if err != nil { - return id, errors.Wrap(err, "create block id") - } - - if blockID.Compare(id) == 0 { - return - } - - metaFile := path.Join(dir, blockID.String(), "meta.json") - r, err := os.Open(metaFile) - if err != nil { - return id, errors.Wrap(err, "open meta file") - } - - metaContent, err := ioutil.ReadAll(r) - if err != nil { - return id, errors.Wrap(err, "read meta file") - } - - m := &metadata.Meta{} - if err := json.Unmarshal(metaContent, m); err != nil { - return id, errors.Wrap(err, "meta.json corrupted") - } - m.ULID = id - m.Compaction.Sources = []ulid.ULID{id} - - if err := os.MkdirAll(path.Join(dir, id.String()), 0777); err != nil { - return id, errors.Wrap(err, "create directory") - } - - err = copyRecursive(path.Join(dir, blockID.String()), path.Join(dir, id.String())) - if err != nil { - return id, errors.Wrap(err, "copy directory") - } - - err = os.RemoveAll(path.Join(dir, blockID.String())) - if err != nil { - return id, errors.Wrap(err, "delete directory") - } - - jsonMeta, err := json.MarshalIndent(m, "", "\t") - if err != nil { - return id, errors.Wrap(err, "meta marshal") - } - - err = ioutil.WriteFile(path.Join(dir, id.String(), "meta.json"), jsonMeta, 0644) - if err != nil { - return id, errors.Wrap(err, "write meta.json file") - } - - return + return createBlock(ctx, dir, series, numSamples, mint, maxt, extLset, resolution, false) } -// CreateBlock writes a block with the given series and numSamples samples each. -// Samples will be in the time range [mint, maxt). -func CreateBlock( +// CreateBlockWithTombstone is same as CreateBlock but leaves tombstones which mimics the Prometheus local block. +func CreateBlockWithTombstone( ctx context.Context, dir string, series []labels.Labels, @@ -417,20 +360,45 @@ func CreateBlock( extLset labels.Labels, resolution int64, ) (id ulid.ULID, err error) { - return createBlock(ctx, dir, series, numSamples, mint, maxt, extLset, resolution, false) + return createBlock(ctx, dir, series, numSamples, mint, maxt, extLset, resolution, true) } -// CreateBlockWithTombstone is same as CreateBlock but leaves tombstones which mimics the Prometheus local block. -func CreateBlockWithTombstone( +// CreateBlockWithBlockDelay writes a block with the given series and numSamples samples each. +// Samples will be in the time range [mint, maxt) +// Block ID will be created with a delay of time duration blockDelay. +func CreateBlockWithBlockDelay( ctx context.Context, dir string, series []labels.Labels, numSamples int, mint, maxt int64, + blockDelay time.Duration, extLset labels.Labels, resolution int64, -) (id ulid.ULID, err error) { - return createBlock(ctx, dir, series, numSamples, mint, maxt, extLset, resolution, true) +) (ulid.ULID, error) { + blockID, err := createBlock(ctx, dir, series, numSamples, mint, maxt, extLset, resolution, false) + if err != nil { + return ulid.ULID{}, errors.Wrap(err, "block creation") + } + + id, err := ulid.New(uint64(timestamp.FromTime(timestamp.Time(int64(blockID.Time())).Add(-blockDelay))), bytes.NewReader(blockID.Entropy())) + if err != nil { + return ulid.ULID{}, errors.Wrap(err, "create block id") + } + + m, err := metadata.Read(path.Join(dir, blockID.String())) + if err != nil { + return ulid.ULID{}, errors.Wrap(err, "open meta file") + } + + m.ULID = id + m.Compaction.Sources = []ulid.ULID{id} + + if err := metadata.Write(log.NewNopLogger(), path.Join(dir, blockID.String()), m); err != nil { + return ulid.ULID{}, errors.Wrap(err, "write meta.json file") + } + + return id, os.Rename(path.Join(dir, blockID.String()), path.Join(dir, id.String())) } func createBlock( @@ -498,6 +466,10 @@ func createBlock( return id, errors.Wrap(err, "write block") } + if id.Compare(ulid.ULID{}) == 0 { + return id, errors.Errorf("nothing to write, asked for %d samples", numSamples) + } + if _, err = metadata.InjectThanos(log.NewNopLogger(), filepath.Join(dir, id.String()), metadata.Thanos{ Labels: extLset.Map(), Downsample: metadata.ThanosDownsample{Resolution: resolution}, diff --git a/pkg/testutil/testutil.go b/pkg/testutil/testutil.go index f4a3933fb4..8b1e8e1d4f 100644 --- a/pkg/testutil/testutil.go +++ b/pkg/testutil/testutil.go @@ -1,24 +1,5 @@ -// The MIT License (MIT) - -// Copyright (c) 2014 Ben Johnson - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. package testutil @@ -29,50 +10,125 @@ import ( "runtime" "testing" + "github.com/davecgh/go-spew/spew" + "github.com/pmezard/go-difflib/difflib" "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" ) // Assert fails the test if the condition is false. -func Assert(tb testing.TB, condition bool, msg string, v ...interface{}) { - if !condition { - _, file, line, _ := runtime.Caller(1) - fmt.Printf("\033[31m%s:%d: "+msg+"\033[39m\n\n", append([]interface{}{filepath.Base(file), line}, v...)...) - tb.FailNow() +func Assert(tb testing.TB, condition bool, v ...interface{}) { + tb.Helper() + if condition { + return } + _, file, line, _ := runtime.Caller(1) + + var msg string + if len(v) > 0 { + msg = fmt.Sprintf(v[0].(string), v[1:]...) + } + tb.Fatalf("\033[31m%s:%d: "+msg+"\033[39m\n\n", filepath.Base(file), line) } // Ok fails the test if an err is not nil. -func Ok(tb testing.TB, err error) { - if err != nil { - _, file, line, _ := runtime.Caller(1) - fmt.Printf("\033[31m%s:%d: unexpected error: %s\033[39m\n\n", filepath.Base(file), line, err.Error()) - tb.FailNow() +func Ok(tb testing.TB, err error, v ...interface{}) { + tb.Helper() + if err == nil { + return } + _, file, line, _ := runtime.Caller(1) + + var msg string + if len(v) > 0 { + msg = fmt.Sprintf(v[0].(string), v[1:]...) + } + tb.Fatalf("\033[31m%s:%d:"+msg+"\n\n unexpected error: %s\033[39m\n\n", filepath.Base(file), line, err.Error()) } // NotOk fails the test if an err is nil. -func NotOk(tb testing.TB, err error) { - if err == nil { - _, file, line, _ := runtime.Caller(1) - fmt.Printf("\033[31m%s:%d: expected error, got nothing \033[39m\n\n", filepath.Base(file), line) - tb.FailNow() +func NotOk(tb testing.TB, err error, v ...interface{}) { + tb.Helper() + if err != nil { + return } + _, file, line, _ := runtime.Caller(1) + + var msg string + if len(v) > 0 { + msg = fmt.Sprintf(v[0].(string), v[1:]...) + } + tb.Fatalf("\033[31m%s:%d:"+msg+"\n\n expected error, got nothing \033[39m\n\n", filepath.Base(file), line) } // Equals fails the test if exp is not equal to act. func Equals(tb testing.TB, exp, act interface{}, v ...interface{}) { - if !reflect.DeepEqual(exp, act) { - _, file, line, _ := runtime.Caller(1) + tb.Helper() + if reflect.DeepEqual(exp, act) { + return + } + _, file, line, _ := runtime.Caller(1) - var msg string - if len(v) > 0 { - msg = fmt.Sprintf(v[0].(string), v[1:]...) - } + var msg string + if len(v) > 0 { + msg = fmt.Sprintf(v[0].(string), v[1:]...) + } + tb.Fatalf("\033[31m%s:%d:"+msg+"\n\n\texp: %#v\n\n\tgot: %#v%s\033[39m\n\n", filepath.Base(file), line, exp, act, diff(exp, act)) +} + +func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { + t := reflect.TypeOf(v) + k := t.Kind() - fmt.Printf("\033[31m%s:%d:"+msg+"\n\n\texp: %#v\n\n\tgot: %#v\033[39m\n\n", filepath.Base(file), line, exp, act) - tb.FailNow() + if k == reflect.Ptr { + t = t.Elem() + k = t.Kind() } + return t, k +} + +// diff returns a diff of both values as long as both are of the same type and +// are a struct, map, slice, array or string. Otherwise it returns an empty string. +func diff(expected interface{}, actual interface{}) string { + if expected == nil || actual == nil { + return "" + } + + et, ek := typeAndKind(expected) + at, _ := typeAndKind(actual) + if et != at { + return "" + } + + if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String { + return "" + } + + var e, a string + c := spew.ConfigState{ + Indent: " ", + DisablePointerAddresses: true, + DisableCapacities: true, + SortKeys: true, + } + if et != reflect.TypeOf("") { + e = c.Sdump(expected) + a = c.Sdump(actual) + } else { + e = reflect.ValueOf(expected).String() + a = reflect.ValueOf(actual).String() + } + + diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ + A: difflib.SplitLines(e), + B: difflib.SplitLines(a), + FromFile: "Expected", + FromDate: "", + ToFile: "Actual", + ToDate: "", + Context: 1, + }) + return "\n\nDiff:\n" + diff } // GatherAndCompare compares the metrics of a Gatherers pair. diff --git a/pkg/tracing/tracing.go b/pkg/tracing/tracing.go index 9664cbc068..929f03c7f2 100644 --- a/pkg/tracing/tracing.go +++ b/pkg/tracing/tracing.go @@ -37,8 +37,8 @@ func tracerFromContext(ctx context.Context) opentracing.Tracer { return nil } -// StartSpan starts and returns span with `operationName` using any Span found within given context. -// It uses traces propagated in context. +// StartSpan starts and returns span with `operationName` and hooking as child to a span found within given context if any. +// It uses opentracing.Tracer propagated in context. If no found, it uses noop tracer without notification. func StartSpan(ctx context.Context, operationName string, opts ...opentracing.StartSpanOption) (opentracing.Span, context.Context) { tracer := tracerFromContext(ctx) if tracer == nil { @@ -53,3 +53,11 @@ func StartSpan(ctx context.Context, operationName string, opts ...opentracing.St span = tracer.StartSpan(operationName, opts...) return span, opentracing.ContextWithSpan(ctx, span) } + +// DoInSpan executes function doFn inside new span with `operationName` name and hooking as child to a span found within given context if any. +// It uses opentracing.Tracer propagated in context. If no found, it uses noop tracer notification. +func DoInSpan(ctx context.Context, operationName string, doFn func(context.Context), opts ...opentracing.StartSpanOption) { + span, newCtx := StartSpan(ctx, operationName, opts...) + defer doFn(newCtx) + defer span.Finish() +} diff --git a/pkg/ui/bindata.go b/pkg/ui/bindata.go index e79365fbba..2c75df0560 100644 --- a/pkg/ui/bindata.go +++ b/pkg/ui/bindata.go @@ -20,6 +20,18 @@ // pkg/ui/static/js/bucket.js // pkg/ui/static/js/graph.js // pkg/ui/static/js/graph_template.handlebar +// pkg/ui/static/react/asset-manifest.json +// pkg/ui/static/react/favicon.ico +// pkg/ui/static/react/index.html +// pkg/ui/static/react/manifest.json +// pkg/ui/static/react/precache-manifest.5b38a4fc0bde14c6f31f0e40057889e9.js +// pkg/ui/static/react/service-worker.js +// pkg/ui/static/react/static/css/2.df42c974.chunk.css +// pkg/ui/static/react/static/css/main.02392ede.chunk.css +// pkg/ui/static/react/static/js/2.b309ab18.chunk.js +// pkg/ui/static/react/static/js/2.b309ab18.chunk.js.LICENSE.txt +// pkg/ui/static/react/static/js/main.bd8c49dc.chunk.js +// pkg/ui/static/react/static/js/runtime-main.5db206b5.js // pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-grid.css // pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-grid.min.css // pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-reboot.css @@ -57,9 +69,8 @@ // pkg/ui/static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css // pkg/ui/static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js // pkg/ui/static/vendor/fuzzy/fuzzy.js -// pkg/ui/static/vendor/js/jquery-3.3.1.min.js +// pkg/ui/static/vendor/js/jquery-3.5.0.min.js // pkg/ui/static/vendor/js/jquery.hotkeys.js -// pkg/ui/static/vendor/js/jquery.min.js // pkg/ui/static/vendor/js/jquery.selection.js // pkg/ui/static/vendor/js/popper.min.js // pkg/ui/static/vendor/moment/moment-timezone-with-data.min.js @@ -145,7 +156,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _pkgUiTemplates_baseHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x54\x5f\x6b\xd4\x40\x10\x7f\xef\xa7\x18\x17\xa1\x2d\x98\x84\xd2\x3e\x08\xbd\x9c\x68\x5b\xb1\x20\xf6\xa8\x67\x51\x44\xca\xde\xde\x5c\xb2\x75\xb3\xb3\xdd\x9d\xc4\x86\x90\xef\x2e\x31\x47\x7b\x97\xde\x51\x11\x35\x2f\xd9\xc9\xe4\xf7\x87\x99\xd9\x19\x3d\x3b\xbd\x38\x99\x7e\x99\x9c\x41\xce\x85\x19\xef\x8c\xba\x17\x18\x69\xb3\x54\xa0\x15\xe3\x1d\x00\x80\x51\x8e\x72\xde\x1f\x7f\x85\x05\xb2\x84\x9c\xd9\x45\x78\x5b\xea\x2a\x15\x27\x64\x19\x2d\x47\xd3\xda\xa1\x00\xd5\x47\xa9\x60\xbc\xe3\xa4\x23\x3c\x06\x95\x4b\x1f\x90\xd3\x92\x17\xd1\x4b\x31\xe4\xb2\xb2\xc0\x54\x78\x9a\x11\x87\x15\xbc\x25\x6d\xe7\x78\xf7\xc2\xd2\x82\x8c\xa1\x1f\xab\x38\xd6\x6c\x70\x3c\xcd\xa5\xa5\x00\x86\x6c\x06\x8c\xbe\x80\xc0\xe4\x65\x86\x30\xf1\x54\x20\xe7\x58\x06\x08\x64\x4a\xd6\x64\x47\x49\x8f\x79\xe0\x30\xda\x7e\x07\x8f\x26\x15\x21\x27\xcf\xaa\x64\xd0\x8a\xac\x80\xdc\xe3\x22\x15\x4d\x03\x4e\x72\x3e\xf1\xb8\xd0\x77\xd0\xb6\x49\x60\xc9\x5a\x25\xba\xc8\x92\x85\xac\xba\x5f\x63\xad\xe8\x55\x95\x36\x0d\xcc\x4a\x6d\xe6\x57\xe8\x83\x26\x0b\x6d\xbb\x6a\x35\x28\xaf\x1d\x43\xf0\x6a\x3b\x67\x85\x76\x4e\x3e\xb9\x09\xc9\xcd\x6d\x89\xbe\x8e\x0e\xe3\xc3\xf8\x20\x2e\xb4\x8d\x6f\xc2\x16\x85\x51\xd2\x33\xff\xb1\x94\x23\xe7\xd0\xff\x4b\x91\x19\x11\x07\xf6\xd2\x45\x47\xf1\x41\x7c\xd8\x89\xde\x7f\xfa\x5d\xdd\x41\xbf\xb8\x76\xb8\x1c\x2d\x15\x82\x58\xf6\x8f\x6b\x83\x21\x47\xe4\xa7\x9a\xb7\xc5\x98\x0a\x43\x67\x2a\x6c\xb3\xf6\x77\x0d\x75\xca\xee\x7e\x5a\xff\x9b\xec\xb0\x0e\x47\x51\x66\x6a\x97\x77\x43\x1d\xd6\xab\xb1\x92\x78\xaa\x30\xc3\x19\x79\xf0\xdc\x3d\x95\xf4\x30\x79\x3d\x7d\x77\x3d\xb9\x3c\x7b\x7b\xfe\x19\x52\x78\xe4\x4e\x1c\x3f\x42\xbc\xf9\x74\xfe\xfe\xf4\xfa\xea\xec\xf2\xe3\xf9\xc5\x87\x25\x66\xa8\xbc\x8e\x7a\xbe\xb7\x28\xad\xea\xae\x3c\xec\xed\x43\xb3\x96\xeb\xf3\xbb\x5f\xe7\x92\x65\xc4\x94\x65\xa6\x2b\x22\x91\x61\xed\xc4\xb7\xdd\xfd\x78\x79\xde\xdb\x5f\x83\xb5\x0f\xe1\x86\xc1\x6c\x1a\xc6\xc2\x19\xc9\x08\xa2\x5b\x95\x02\xe2\xb6\xed\x37\x67\xd2\xaf\xce\x3e\x98\xd1\xbc\x1e\x6f\x44\x59\x59\xf5\xa0\x8d\xd9\xe5\x42\x5c\xa5\xed\xa9\x46\x49\xbf\xb5\x7f\x06\x00\x00\xff\xff\x87\xbe\xb7\x2e\xc6\x05\x00\x00") +var _pkgUiTemplates_baseHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x54\x6f\x6b\xd4\x4c\x10\x7f\xdf\x4f\x31\xcf\xf2\x40\x5b\x30\x89\xd2\x0a\x42\x2f\x27\xda\x56\x2c\x88\x3d\xea\x59\x14\x91\xb2\xb7\x37\x97\x6c\xdd\xec\x6c\x77\x27\xb1\x21\xe4\xbb\x4b\xcc\xd1\xde\xa5\x77\x54\x44\xcd\x9b\xec\x64\xf2\xfb\xc3\xcc\xec\x8c\xfe\x3b\x39\x3f\x9e\x7e\x9e\x9c\x42\xce\x85\x19\xef\x8c\xba\x17\x18\x69\xb3\x54\xa0\x15\xe3\x1d\x00\x80\x51\x8e\x72\xde\x1f\x7f\x86\x05\xb2\x84\x9c\xd9\x45\x78\x53\xea\x2a\x15\xc7\x64\x19\x2d\x47\xd3\xda\xa1\x00\xd5\x47\xa9\x60\xbc\xe5\xa4\x23\x3c\x02\x95\x4b\x1f\x90\xd3\x92\x17\xd1\x0b\x31\xe4\xb2\xb2\xc0\x54\x78\x9a\x11\x87\x15\xbc\x25\x6d\xe7\x78\xfb\xc4\xd2\x82\x8c\xa1\xef\xab\x38\xd6\x6c\x70\x3c\xcd\xa5\xa5\x00\x86\x6c\x06\x8c\xbe\x80\xc0\xe4\x65\x86\x30\xf1\x54\x20\xe7\x58\x06\x08\x64\x4a\xd6\x64\x47\x49\x8f\xb9\xe7\x30\xda\x7e\x03\x8f\x26\x15\x21\x27\xcf\xaa\x64\xd0\x8a\xac\x80\xdc\xe3\x22\x15\x4d\x03\x4e\x72\x3e\xf1\xb8\xd0\xb7\xd0\xb6\x49\x60\xc9\x5a\x25\xba\xc8\x92\x85\xac\xba\x5f\x63\xad\xe8\x65\x95\x36\x0d\xcc\x4a\x6d\xe6\x97\xe8\x83\x26\x0b\x6d\xbb\x6a\x35\x28\xaf\x1d\x43\xf0\x6a\x3b\x67\x85\x76\x4e\x3e\xb9\x0e\xc9\xf5\x4d\x89\xbe\x8e\x0e\xe2\xe7\xf1\xd3\xb8\xd0\x36\xbe\x0e\x5b\x14\x46\x49\xcf\xfc\xdb\x52\x8e\x9c\x43\xff\x37\x45\x66\x44\x1c\xd8\x4b\x17\x1d\xc6\xcf\xe2\x83\x4e\xf4\xee\xd3\xaf\xea\x0e\xfa\xc5\xb5\xc3\xe5\x68\xa9\x10\xc4\xb2\x7f\x5c\x1b\x0c\x39\x22\x3f\xd6\xbc\x2d\xc6\x54\x18\x3a\x53\x61\x9b\xb5\x3f\x6b\xa8\x53\x76\x77\xd3\xfa\xcf\x64\x87\x75\x38\x8c\x32\x53\xbb\xbc\x1b\xea\xb0\x5e\x8d\x95\xc4\x63\x85\x19\xce\xc8\xbd\xe7\xee\xa9\xa4\x87\xc9\xab\xe9\xdb\xab\xc9\xc5\xe9\x9b\xb3\x4f\x90\xc2\x03\x77\xe2\xe8\x01\xe2\xf5\xc7\xb3\x77\x27\x57\x97\xa7\x17\x1f\xce\xce\xdf\x2f\x31\x43\xe5\x75\xd4\xff\x7b\x8b\xd2\xaa\xee\xca\xc3\xde\x3e\x34\x6b\xb9\x3e\xbf\xfb\x65\x2e\x59\x46\x4c\x59\x66\xba\x22\x12\x19\xd6\x4e\x7c\xdd\xdd\x8f\x97\xe7\xbd\xfd\x35\x58\x7b\x1f\x6e\x18\xcc\xa6\x61\x2c\x9c\x91\x8c\x20\xba\x55\x29\x20\x6e\xdb\x7e\x73\x26\xfd\xea\xec\x83\x19\xcd\xeb\xf1\x46\x94\x95\x55\x0f\xda\x98\x5d\x2e\xc4\x55\xda\x9e\x6a\x94\xf4\x5b\xfb\x47\x00\x00\x00\xff\xff\x65\x65\x45\xc9\xc6\x05\x00\x00") func pkgUiTemplates_baseHtmlBytes() ([]byte, error) { return bindataRead( @@ -160,7 +171,7 @@ func pkgUiTemplates_baseHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/templates/_base.html", size: 1478, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/templates/_base.html", size: 1478, mode: os.FileMode(436), modTime: time.Unix(1588865307, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -180,7 +191,7 @@ func pkgUiTemplatesAlertsHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/templates/alerts.html", size: 5106, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/templates/alerts.html", size: 5106, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -200,7 +211,7 @@ func pkgUiTemplatesBucketHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/templates/bucket.html", size: 1382, mode: os.FileMode(420), modTime: time.Unix(1582318785, 0)} + info := bindataFileInfo{name: "pkg/ui/templates/bucket.html", size: 1382, mode: os.FileMode(420), modTime: time.Unix(1586287991, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -220,7 +231,7 @@ func pkgUiTemplatesBucket_menuHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/templates/bucket_menu.html", size: 787, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/templates/bucket_menu.html", size: 787, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -240,12 +251,12 @@ func pkgUiTemplatesGraphHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/templates/graph.html", size: 2298, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/templates/graph.html", size: 2298, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _pkgUiTemplatesQuery_menuHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x54\xb1\x6e\xdc\x30\x0c\xdd\xf3\x15\x84\x02\x74\x73\xb4\xb7\xb6\x87\x2e\x6d\xb7\xa2\xc9\x5e\xd0\x27\xda\x16\x22\x4b\x82\x44\x5f\x53\x18\xfe\xf7\x42\xba\x3b\xe3\xec\x9c\x0f\xc8\xd0\x49\x10\x41\x3e\xbe\x27\x3e\x6a\x9a\x14\xb5\xda\x12\x08\x8b\x47\x31\xcf\x0f\x00\x00\xa5\xc5\x23\x1c\x0c\xc6\x58\xa5\x70\x83\x01\x5a\xfd\x46\xaa\x60\xe7\xe1\x14\x28\xe8\xcd\xa3\x55\x45\x1c\x2e\x01\x85\xe1\x15\x9a\x2e\x9f\xa2\xce\x38\x19\x4b\xe9\x05\xeb\xe0\x2c\xa3\xb6\x14\x8a\xd6\x8c\x5a\x5d\x65\xe5\xcc\x66\x64\x76\x16\xf8\xaf\xa7\x4a\x9c\x2e\x62\x4d\xa3\x60\xd7\x75\x86\x82\x00\x85\x8c\xe7\x5b\xc2\x35\x06\x7d\xa4\x4b\x18\x43\x47\x5c\x89\x47\x8b\xc7\x22\xf5\x24\xcb\x02\x30\x68\x3c\xb3\x26\x55\x89\x16\x4d\x2a\xc8\xd1\x94\x13\x9c\x39\xb5\xd9\x54\x18\x6c\xc8\x54\xe2\x25\xb7\x4a\x5a\x75\x87\xac\x9d\xdd\x90\xcf\x02\xa2\x47\x7b\x9b\x70\xa1\x0f\xa9\xa4\x94\x29\x65\x23\x5b\x9e\xa4\x6e\xa2\xb8\x01\x6a\x02\x5a\x25\xa0\x0f\xd4\x56\x62\x9a\xc0\x23\xf7\x3f\x03\xb5\xfa\x0d\xe6\x59\x8a\xfa\xa5\x47\xeb\x62\x29\x71\x83\x93\x9e\x5f\xab\x8d\xb2\x35\xf4\xe5\xf9\x60\x79\xc7\x1b\xda\x46\xb3\xa9\x4a\x7e\x79\x9f\x97\x73\x8d\xbe\xca\x2d\x34\xd3\x20\xea\x95\xa0\xc2\x68\xfb\xba\x2b\xa6\x0b\xe8\x7b\x51\x7f\x4b\x47\x12\x54\x4a\xa3\xff\x4f\xa7\xc8\x2e\x50\x14\xf5\x73\x3e\x3f\xdc\x0b\x54\x70\x5e\xb9\x3f\xb7\xcc\x70\x35\xc8\x53\xf3\x47\xb1\xa5\xb5\x94\x9f\x5d\xb2\x71\xf5\x02\x0e\xc1\x99\xab\x8d\xc8\xb6\xec\x31\x7a\xe7\x47\x5f\x09\x0e\x23\xed\xb8\xbb\x7e\x66\xe4\x31\xae\x8d\x79\xc0\x40\xbc\x58\xf1\x9d\x61\xde\x99\xe7\x5c\xb6\x70\x1d\xc8\x8e\x77\xf4\xc2\xca\xbc\x4b\x55\x1e\xcd\xfe\x18\x12\x4d\x51\xff\x1a\x2d\xeb\x81\xe0\x13\x0e\xfe\x0b\x7c\x1d\xb5\x51\xf0\xc3\xb6\x2e\x0c\x79\xe5\xee\x73\x95\x4a\x1f\x77\x26\xf7\x31\xff\xdc\x1b\xe5\x8e\xb1\x7a\x66\x1f\x3f\x4b\xc9\x79\x09\x9f\xb4\x93\x1d\x31\x6b\xdb\x15\x91\x31\x30\xa9\xa7\x41\x49\x01\x97\x8f\xe9\x77\x63\xd0\xbe\x8a\xfa\x3b\x19\xbf\x2b\xea\x36\xeb\x52\x8e\x66\xfb\x7f\xac\x84\x5f\x5d\x4b\x69\xf1\x58\x3f\x4c\x13\x59\x35\xcf\x0f\xff\x02\x00\x00\xff\xff\x43\xdf\x18\x28\xeb\x05\x00\x00") +var _pkgUiTemplatesQuery_menuHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x54\x31\x6f\xdc\x3c\x0c\xdd\xf3\x2b\x08\x05\xf8\x36\x47\xfb\xd7\xb3\x87\x2e\x6d\x96\xa2\x68\xd2\xb9\xa0\x4f\xb4\x2d\x44\x96\x04\x89\xbe\xa4\x30\xfc\xdf\x0b\xe9\xee\x8c\xb3\x73\x0e\x70\x43\x26\x41\x04\xf9\xf8\x9e\xf8\xa8\x71\x54\xd4\x68\x4b\x20\x2c\x1e\xc4\x34\xdd\x01\x00\xec\x2c\x1e\x60\x6f\x30\xc6\x32\x85\x6b\x0c\xd0\xe8\x37\x52\x05\x3b\x0f\xc7\x40\x41\x6f\x1e\xad\x2a\x62\x7f\x0e\x28\x0c\x2f\x50\xb7\xf9\x14\x55\xc6\xc9\x58\x4a\xcf\x58\x7b\x67\x19\xb5\xa5\x50\x34\x66\xd0\xea\x22\x2b\x67\xd6\x03\xb3\xb3\xc0\x7f\x3d\x95\xe2\x78\x11\x4b\x1a\x05\xbb\xb6\x35\x14\x04\x28\x64\x3c\xdd\x12\xae\x31\xe8\x23\x9d\xc3\x18\x5a\xe2\x52\xdc\x5b\x3c\x14\xa9\x27\x59\x16\x80\x41\xe3\x89\x35\xa9\x52\x34\x68\x52\x41\x8e\xa6\x9c\xe0\xcc\xb1\xcd\xaa\xc2\x60\x4d\xa6\x14\xcf\xb9\x55\xd2\xaa\x5b\x64\xed\xec\x8a\x7c\x16\x10\x3d\xda\xeb\x84\x0b\xbd\x4f\x25\x3b\x99\x52\x56\xb2\xe5\x51\xea\x2a\x8a\x2b\xa0\x3a\xa0\x55\x02\xba\x40\x4d\x29\xc6\x11\x3c\x72\xf7\x33\x50\xa3\xdf\x60\x9a\xa4\xa8\x9e\x3b\xb4\x2e\xee\x24\xae\x70\xd2\xf3\x6b\xb5\x52\xb6\x84\x3e\x3f\x1f\xcc\xef\x78\x45\xdb\x60\x56\x55\xc9\x2f\xef\xf3\x72\xae\xd1\x17\xb9\x85\x66\xea\x45\xb5\x10\x54\x18\x6d\x5f\x36\xc5\xb4\x01\x7d\x27\xaa\x6f\xe9\x48\x82\x76\xd2\xe8\xcf\xe9\x14\xd9\x05\x8a\xa2\x7a\xca\xe7\xcd\xbd\x40\x05\xe7\x95\x7b\xbd\x66\x86\x8b\x41\x1e\x9b\xdf\x8b\x35\xad\xb9\xfc\xe4\x92\x95\xab\x67\x70\x08\xce\x5c\x6c\x44\xb6\x65\x87\xd1\x3b\x3f\xf8\x52\x70\x18\x68\xc3\xdd\xd5\x13\x23\x0f\x71\x69\xcc\x3d\x06\xe2\xd9\x8a\xef\x0c\xf3\xce\x3c\xa7\xb2\x99\x6b\x4f\x76\xf8\x40\x2f\x2c\xcc\x3b\x57\xe5\xd1\x6c\x8f\x21\xd1\x14\xd5\xaf\xc1\xb2\xee\x09\xfe\xc3\xde\x7f\x81\xaf\x83\x36\x0a\x1e\x6d\xe3\x42\x9f\x57\xee\x63\xae\x52\xe9\xc3\xc6\xe4\x6e\xf3\xcf\x47\xa3\xdc\x30\x56\xc7\xec\xe3\xff\x52\x72\x5e\xc2\x07\xed\x64\x4b\xcc\xda\xb6\x45\x64\x0c\x4c\xea\xa1\x57\x52\xc0\xf9\x63\xfa\x53\x1b\xb4\x2f\xa2\xfa\x4e\xc6\x6f\x8a\xfa\x7c\xd6\x8b\x39\x4c\x93\xb4\xf4\x7a\x85\xe4\x0f\x7a\x85\xdf\x8f\x37\xd2\xdc\xc9\xc1\xac\xbf\xb9\xc5\x7c\x2e\xae\x3b\x69\xf1\x50\xdd\x8d\x23\x59\x35\x4d\x77\xff\x02\x00\x00\xff\xff\x2a\xda\xc1\xa0\x92\x06\x00\x00") func pkgUiTemplatesQuery_menuHtmlBytes() ([]byte, error) { return bindataRead( @@ -260,7 +271,7 @@ func pkgUiTemplatesQuery_menuHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/templates/query_menu.html", size: 1515, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/templates/query_menu.html", size: 1682, mode: os.FileMode(436), modTime: time.Unix(1589208144, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -280,7 +291,7 @@ func pkgUiTemplatesRule_menuHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/templates/rule_menu.html", size: 963, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/templates/rule_menu.html", size: 963, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -300,7 +311,7 @@ func pkgUiTemplatesRulesHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/templates/rules.html", size: 1944, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/templates/rules.html", size: 1944, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -320,12 +331,12 @@ func pkgUiTemplatesStatusHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/templates/status.html", size: 1272, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/templates/status.html", size: 1272, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _pkgUiTemplatesStoresHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\x41\x6b\xeb\x38\x10\xbe\xe7\x57\x0c\xa2\xd7\xc4\xd0\xcb\xc2\xe2\x78\x59\x96\xc2\x1e\xda\xf2\x20\x7d\xbd\x3e\x14\x6b\x12\x8b\x2a\x92\x91\xc6\x6d\x82\xd0\x7f\x7f\xc8\xb1\x13\xb9\x76\xd2\xf4\x5d\x0c\x1a\xcd\xcc\x37\x9e\xef\x9b\xb1\xbd\x17\xb8\x91\x1a\x81\x55\xc8\x05\x0b\x61\x96\x2b\xa9\xdf\x80\x0e\x35\x2e\x19\xe1\x9e\xb2\xd2\x39\x06\x16\xd5\x92\x39\x3a\x28\x74\x15\x22\x31\xa8\x2c\x6e\x96\xcc\x7b\xa8\x39\x55\x3f\x2c\x6e\xe4\x1e\x42\xc8\x1c\x71\x92\x65\x8c\xc9\x6c\xa3\xd0\x2d\x4a\xe7\xfe\x79\x5f\x7a\x0f\xeb\x46\x2a\xf1\x8a\xd6\x49\xa3\x21\x04\x56\xcc\xbc\x47\x2d\x42\x98\xcd\xce\x45\x94\x46\x13\x6a\x6a\xeb\x10\xf2\x1d\x4a\xc5\x9d\x5b\xb6\x66\x2e\x35\xda\xf9\x46\x35\x52\xb0\x62\x06\x00\xe0\xbd\xe5\x7a\x8b\x70\xe7\xc8\x58\x7c\x39\xd4\x08\x7f\x2f\x61\xb1\x32\x8d\x2d\xd1\x85\xd0\x39\xc9\x4d\xe2\xd1\x59\xf3\xea\xbe\xf0\x9e\x24\xa9\x34\x7c\xb1\x22\x2b\xf5\x36\x84\x3c\xab\xee\x7b\x0c\x54\x2e\x8d\xfa\xa9\xdf\xb4\xf9\xd0\x10\xfd\x07\x6e\xed\xab\xb4\x5e\xc4\xd7\x0a\xfb\xd2\x8f\x87\xf6\x39\x5f\x1b\x2b\xd0\x62\x5f\xff\xd1\x39\xf6\x3d\x3d\xdb\xf3\xa1\x73\x28\x1e\xb4\xa8\x8d\xd4\x94\x67\x54\x8d\x6f\x57\xc4\xa9\x71\xd3\x77\xff\x6a\x6d\x1a\x5d\xa2\x80\x47\xbe\x46\xb5\x42\xba\xe0\xf8\x24\x35\xbc\xc8\x1d\x5e\xb8\xe5\xfb\x2b\xb7\x8f\xdc\x11\xfc\x8f\x5c\x51\x05\xff\x55\x58\xbe\x5d\x71\x7b\x42\xe7\xf8\xf6\x53\xa2\x3c\x4b\xdf\x3a\xde\x7d\xea\xc9\xda\x88\xc3\xf9\x3c\xe4\x3d\x72\x2e\xb5\xc0\x3d\xdc\x2d\x56\xd1\xe0\xc6\x74\x5f\xe8\xac\x28\xbc\x3f\xfa\x2e\x9e\xf9\x0e\x23\xef\x24\x46\x4e\x3d\x93\x51\xda\xc8\x86\xd7\xd0\x2b\x4c\x1b\xea\x60\x17\xf1\x3d\x1f\xac\x35\x36\x01\x3f\xa5\x73\x35\xd7\x7d\x42\xae\xd0\x12\xb4\xcf\xb9\x6b\xca\x12\x9d\x83\x16\xe4\x97\xd4\x42\x96\x9c\x8c\x85\x38\x81\xf3\xa6\xae\xd1\x96\xdc\x21\x2b\x9a\x3a\xcf\x62\x8e\xa9\x32\x12\xa5\xde\x84\x29\x62\x17\xed\x97\x90\xc2\x7c\xe8\x2b\xa0\x27\xdd\x27\xfc\x8d\x9b\x38\x0e\xfd\xd6\x98\x9c\x83\x86\x52\x38\xd7\xd1\x49\x42\xf5\x32\x8f\xb2\x38\x11\xd2\xd9\xa6\x9a\xf3\x59\x15\x57\x6b\x1e\x43\xb5\x30\x27\xd0\x23\xd4\x14\xce\x29\x6d\x4a\xc6\x9a\x8b\x2d\x42\xfb\x9c\xd7\x56\xee\xb8\x3d\xb0\x28\xc9\x36\x5f\x27\xc9\xb8\x63\x3b\xc3\x2b\x57\x0d\x86\xc0\x2e\x91\x01\x17\x08\x39\x61\x8f\x88\x81\xd1\xf0\x7d\x95\x27\xcf\x2e\x30\x90\x67\x2d\x79\xc5\x0d\x52\xf0\x7e\x63\xec\x8e\x53\xdc\x28\x8e\xf8\xae\xee\x89\x7a\x92\x3a\xda\x2e\xcc\xe1\x95\x38\xbe\xbf\x1e\xe7\xa4\x2e\x31\x9d\xcf\x76\x4d\x85\x00\x7c\x6b\x6e\x94\x6b\xf2\x1d\xb9\x3a\xe1\xf0\xfd\x89\x9b\xd0\xf9\x11\xf1\x56\xb8\x3f\x1e\xce\x21\xf7\xa3\x0d\x32\xb5\x32\xa1\x34\x2a\xc2\x2d\xd9\x5f\x13\x75\x3f\x1b\x70\xc7\x1d\x6c\x71\x2b\x1d\xc5\x31\xfe\x0e\xfe\xa0\xde\x81\xd6\x06\xfa\x1a\x57\xba\x4e\x3f\x20\xc9\x9f\x43\xda\xfd\x0f\x6e\xb5\xd4\x5b\x56\x4c\x55\x99\x67\x42\xbe\x0f\x3f\xe6\x9d\xa9\x3f\xfe\x0e\x00\x00\xff\xff\xf7\x7e\x17\x21\x2b\x09\x00\x00") +var _pkgUiTemplatesStoresHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\x41\x6b\xeb\x38\x10\xbe\xe7\x57\x0c\xa2\xd7\xc4\xd0\xcb\xc2\xe2\x78\x59\x96\xc2\x1e\xda\xf2\x20\x7d\xbd\x3e\x14\x6b\x12\x8b\x2a\x92\x91\xc6\x6d\x82\xd0\x7f\x7f\xc8\xb1\x13\xb9\x76\xd2\xf4\x5d\x0c\x1a\xcd\xcc\x37\x99\xef\x9b\x51\xbc\x17\xb8\x91\x1a\x81\x55\xc8\x05\x0b\x61\x96\x2b\xa9\xdf\x80\x0e\x35\x2e\x19\xe1\x9e\xb2\xd2\x39\x06\x16\xd5\x92\x39\x3a\x28\x74\x15\x22\x31\xa8\x2c\x6e\x96\xcc\x7b\xa8\x39\x55\x3f\x2c\x6e\xe4\x1e\x42\xc8\x1c\x71\x92\x65\x8c\xc9\x6c\xa3\xd0\x2d\x4a\xe7\xfe\x79\x5f\x7a\x0f\xeb\x46\x2a\xf1\x8a\xd6\x49\xa3\x21\x04\x56\xcc\xbc\x47\x2d\x42\x98\xcd\xce\x45\x94\x46\x13\x6a\x6a\xeb\x10\xf2\x1d\x4a\xc5\x9d\x5b\xb6\x66\x2e\x35\xda\xf9\x46\x35\x52\xb0\x62\x06\x00\xe0\xbd\xe5\x7a\x8b\x70\xe7\xc8\x58\x7c\x39\xd4\x08\x7f\x2f\x61\xb1\x32\x8d\x2d\xd1\x85\xd0\x39\xc9\x4d\xe2\xd1\x59\xf3\xea\xbe\xf0\x9e\x24\xa9\x34\x7c\xb1\x22\x2b\xf5\x36\x84\x3c\xab\xee\x7b\x0c\x54\x2e\x8d\xfa\xa9\xdf\xb4\xf9\xd0\x10\xfd\x07\x6e\xed\x4f\x69\xbd\x88\xaf\x15\xf6\xa5\x1f\x0f\xed\x77\xbe\x36\x56\xa0\xc5\xbe\xfe\xa3\x73\xec\x7b\x7a\xb6\xe7\x43\xe7\x50\x3c\x68\x51\x1b\xa9\x29\xcf\xa8\x1a\xdf\xae\x88\x53\xe3\xa6\xef\xfe\xd5\xda\x34\xba\x44\x01\x8f\x7c\x8d\x6a\x85\x74\xc1\xf1\x49\x6a\x78\x91\x3b\xbc\x70\xcb\xf7\x57\x6e\x1f\xb9\x23\x58\x35\x65\x89\xce\x6d\x1a\x05\xff\x23\x57\x54\xc1\x7f\x15\x96\x6f\x57\x22\x9e\xd0\x39\xbe\xfd\x94\x33\xcf\xd2\x06\xc4\xbb\x4f\xed\x59\x1b\x71\x38\x9f\x87\x12\x88\xf4\x4b\x2d\x70\x0f\x77\x8b\x55\x34\xb8\x31\xf3\x17\x9a\x2c\x0a\xef\x8f\xbe\x8b\x67\xbe\xc3\x28\x01\x12\x23\xa7\x9e\xd4\xa8\x72\x64\xc3\x6b\xe8\xc5\xa6\x0d\x75\xb0\x8b\xf8\x3b\x1f\xac\x35\x36\x01\x3f\xa5\x73\x35\xd7\x7d\x42\xae\xd0\x12\xb4\xdf\xb9\x3b\x76\x12\x5a\x90\x5f\x52\x0b\x59\x72\x32\x16\xe2\x30\xce\x9b\xba\x46\x5b\x72\x87\xac\x68\xea\x3c\x8b\x39\xa6\xca\x48\x44\x7b\x13\xa6\x88\x5d\xb4\x5f\x42\x0a\xf3\xa1\xaf\x80\x9e\x46\x20\xe1\x6f\xdc\xc4\x71\xe8\xb7\x26\xe6\x1c\x34\x94\xc2\xb9\x8e\x4e\x12\xaa\x57\x7c\x94\xc5\x89\x90\xce\x36\xd5\x9c\xcf\xaa\xb8\x5a\xf3\x18\xaa\x85\x39\x81\x1e\xa1\xa6\x70\x4e\x69\x53\x32\xd6\x5c\x6c\x11\xda\xef\xbc\xb6\x72\xc7\xed\x81\x45\x49\xb6\xf9\x3a\x49\xc6\x75\xdb\x19\x5e\xb9\x6a\x30\x04\x76\x89\x0c\xb8\x40\xc8\x09\x7b\x44\x0c\x8c\x86\xef\xab\x3c\x79\x76\x81\x81\x3c\x6b\xc9\x2b\x6e\x90\x82\xf7\x1b\x63\x77\x9c\xe2\x72\x71\xc4\x77\x75\x4f\xd4\x93\xd4\xd1\x76\x61\x0e\xaf\xc4\xf1\xfd\xf5\x38\x27\x75\x89\xe9\x7c\xb6\x6b\x2a\x04\xe0\x5b\x73\xa3\x5c\x93\x27\xe5\xea\x84\xc3\xf7\x27\x6e\x42\xe7\x47\xc4\x5b\xe1\xfe\x78\x38\x87\xdc\x8f\x36\xc8\xd4\xca\x84\xd2\xa8\x08\xb7\x64\x7f\x4d\xd4\xfd\x6c\xc0\x1d\x77\xb0\xc5\xad\x74\x14\xc7\xf8\x3b\xf8\x83\x7a\x07\x5a\x1b\xe8\x6b\x5c\xe9\x3a\x7d\x40\x92\x3f\x11\x69\xf7\x3f\xb8\xd5\x52\x6f\x59\x31\x55\x65\x9e\x09\xf9\x3e\x7c\xd7\x3b\x53\x7f\xfc\x1d\x00\x00\xff\xff\xff\x5c\x1c\xa9\x36\x09\x00\x00") func pkgUiTemplatesStoresHtmlBytes() ([]byte, error) { return bindataRead( @@ -340,7 +351,7 @@ func pkgUiTemplatesStoresHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/templates/stores.html", size: 2347, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/templates/stores.html", size: 2358, mode: os.FileMode(436), modTime: time.Unix(1588865307, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -360,7 +371,7 @@ func pkgUiStaticCssAlertsCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/css/alerts.css", size: 401, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/css/alerts.css", size: 401, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -380,7 +391,7 @@ func pkgUiStaticCssGraphCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/css/graph.css", size: 3844, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/css/graph.css", size: 3844, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -400,7 +411,7 @@ func pkgUiStaticCssPrometheusCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/css/prometheus.css", size: 470, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/css/prometheus.css", size: 470, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -420,7 +431,7 @@ func pkgUiStaticCssRulesCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/css/rules.css", size: 195, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/css/rules.css", size: 195, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -440,7 +451,7 @@ func pkgUiStaticImgAjaxLoaderGif() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/img/ajax-loader.gif", size: 847, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/img/ajax-loader.gif", size: 847, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -460,7 +471,7 @@ func pkgUiStaticImgFaviconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/img/favicon.ico", size: 15886, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/img/favicon.ico", size: 15886, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -480,12 +491,12 @@ func pkgUiStaticJsAlertsJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/js/alerts.js", size: 2637, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/js/alerts.js", size: 2637, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _pkgUiStaticJsBucketJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x57\xdd\x6f\xdb\xba\x15\x7f\xf7\x5f\x71\xae\x16\xc0\x12\x62\x2b\x2e\x30\xec\x21\xb1\x0d\xdc\xa5\x05\x76\x87\xac\x1d\x9a\x3c\x2d\x28\x10\x5a\x3c\xb6\xb8\x50\xa4\x46\x52\x71\xdd\xc0\xff\xfb\x40\x52\x1f\xb4\x22\xbb\x4e\xaf\x10\x04\x16\x79\xce\xef\x7c\x7f\x68\x23\xe5\x86\x63\x9a\xe5\x44\x19\x9d\x72\x49\x68\x3c\xce\x2a\xa5\x50\x98\xf1\x04\x5e\x47\x00\x00\xe3\x92\x64\xcf\x64\x83\x7a\x7c\x0d\x8f\x63\xc3\x0a\xe4\x4c\xe0\xf8\xdb\x68\x9f\xdc\x8c\x0e\x01\x34\x9a\x2f\xe2\x4e\x12\x7a\x4b\x38\x5f\x91\xec\x39\xa6\x8a\x6c\x93\x9b\xd1\x68\x5d\x89\xcc\x30\x29\xc0\x1e\xc4\x49\x0d\xcd\xd6\x10\x9b\x9c\x08\xa9\x53\x85\x6b\x85\x3a\x47\xfa\xbb\x81\xc5\x02\xa2\xd9\x6c\xf6\x61\xea\xfe\x1e\x66\xb3\x6b\xf7\xf7\x9f\xa8\xe1\xb3\x4f\xcd\x87\x4a\xc1\x02\xa2\xfb\x9d\xc8\x72\x25\x05\xfb\xc1\xc4\x06\x56\x5c\x66\xcf\x1a\xd6\x4a\x16\xa0\xb0\x90\x06\x41\x1b\xa9\xc8\x06\xa3\x1b\x07\xb0\x1f\xf5\xe5\x5b\x9c\xdf\x16\x20\x2a\xce\x43\x29\x17\x71\xf4\x17\x54\x2a\x4a\x52\x9d\xcb\x6d\x9c\xa4\x6b\x26\x68\x3c\x4e\x09\x47\x65\xc6\x49\x6a\xf0\xbb\x89\xff\x79\xff\xe5\x73\xaa\x8d\x62\x62\xc3\xd6\xbb\x00\x71\xe2\xf0\x26\xf0\xd7\x24\xb9\x69\x21\x35\x9a\x07\x56\xa0\xac\x4c\xdc\x78\x25\x0e\x45\xda\x87\xcb\x8c\xd8\x8b\x54\xa1\x0b\x4a\xc0\xbe\x9f\xc0\x87\xd9\x6c\x36\xb3\x5e\x75\xef\x80\x5c\xe3\xa0\xca\x39\xa3\x18\x37\x74\xf6\x79\x21\x0a\x32\x29\x0c\x61\x02\xad\xdb\xa8\xcc\xaa\x02\x85\x49\x37\x68\x3e\x71\xb4\x3f\xff\xbe\xfb\x83\xc6\xe3\x5b\x59\x94\xc4\xa9\xa6\xc7\x81\x6c\xc7\x6f\x43\x0d\x0b\x10\xb8\x85\x3a\xfa\x2f\x4c\x57\x84\xb3\x1f\x5e\xe5\x87\x3a\x43\xe2\x56\x52\x0f\x81\x12\x43\x1e\xc8\x8a\xe3\x29\x94\x8f\x0d\x51\xdc\xe3\x36\xcc\x70\xd4\xb0\x80\xd7\x7d\x60\x59\x8b\x99\x12\x4a\x6f\x25\xaf\x0a\x11\xbf\x9a\x5d\x89\xd7\x30\xf6\x91\x19\x4f\x80\xd1\x6b\x18\x7f\xc5\x92\xb3\x8c\x8c\xf7\x01\xee\xf9\xdc\x77\x64\x85\xfc\xfd\xbc\x4a\x72\xfb\x6e\xa4\xe4\x86\x95\x67\xf3\x53\x62\xb0\x91\x7c\x6f\x88\x32\xbf\xc4\xf9\x49\x50\xc7\x37\xcc\xf8\x55\x6e\x75\x93\xb2\xbe\x6e\x0e\x32\x31\x2d\x48\xd9\xe5\x29\xed\x27\xaa\x7d\xae\xae\xe0\xc1\x06\x05\x98\x06\x93\x23\xac\x99\xd2\x06\x32\xa7\x10\xc8\xb5\x3b\x6b\xda\x46\x3a\xc0\x3d\x04\xf8\x3b\x54\x82\xfd\xaf\x42\xf8\xb7\x92\x05\x9a\x1c\x2b\x0d\xdc\xfa\xde\xd6\xbd\x01\x46\x51\x18\xb6\x66\xa8\x01\x49\x96\x83\xce\x89\xa2\x56\x7e\xa5\x91\x0e\xe1\x11\x5d\xab\xe1\xf4\x5c\x43\xa9\x50\xa3\x30\x13\x90\x26\x47\xb5\x65\x1a\x81\x70\xee\x45\x68\x20\x0a\x81\x32\x5d\x72\xb2\x1b\x86\xc3\xef\x06\x95\x20\x9c\xef\x2c\x32\x01\x8e\x1b\x14\xf4\xad\x71\x5e\xde\x02\x8e\x16\x7a\xf3\x04\x9d\xc8\x9b\xf9\xdb\x02\xa2\xe8\x18\x35\xd4\xb5\xf0\x8c\x3b\x5b\xc5\x69\xc8\xa9\x1f\xc3\xb7\x6f\x37\x47\x01\xac\x48\x07\xb0\x80\x4a\x50\x5c\x33\x81\x83\xe1\x3d\xb0\x27\x57\x72\x0b\x4f\xae\x0a\xe0\xe2\x35\x94\xb4\x07\x21\x0d\xac\x65\x25\x28\x30\x01\x17\xaf\x5f\x56\xff\xc5\xcc\xa4\xcf\xb8\xd3\x71\x4f\xc5\x64\xff\x74\x5c\xaf\x37\x0d\x6d\xe8\x51\x68\x2a\x25\xac\x03\x4e\x00\x0d\xde\xfc\x14\xbe\x89\x99\x6f\x34\x8f\x5d\x5f\xef\x1b\xf1\x13\xdf\xd6\x38\xef\xf1\x6e\x2d\xf9\xde\x89\x8c\x43\x07\x7a\x65\x92\x94\xa3\xd8\x98\x1c\x2e\xe1\x43\x72\x5c\x7a\x8b\x75\x52\xfb\xc6\xc4\xf7\x3a\x10\x3a\xf7\x9f\xe0\x7f\xcb\xbb\x3f\x18\x45\xcd\xe3\xb3\x7d\x01\x4f\x1c\x5f\x90\x5f\xc3\xc5\x2b\x4d\xb3\x76\xfa\xa4\xee\x74\x3f\x01\x85\x5a\xf2\xca\x1e\x79\x92\xda\x16\x2a\xb7\x42\x93\xa2\xe4\x98\x76\x14\x43\xc9\x55\x2b\xfc\xe8\x34\x9e\x78\xa9\x13\xd8\xa0\x40\x45\x0c\x3e\xf8\xbe\x1c\xd3\x64\xe2\x26\xd2\x47\x62\x30\xa6\x69\xc1\x84\x1d\x66\xbd\x43\xf2\xdd\x1d\xf6\xa2\xbf\x4f\x42\xeb\xdc\x90\x4c\xdd\xae\xd3\x36\xdb\xf0\xfe\xea\x0a\xee\x73\xb9\x6d\xfb\x48\xdd\x40\x6c\xde\x08\x19\x9c\xfa\x76\xb4\x45\x85\x76\x6d\xe8\xfa\xcb\x9b\x76\xb1\x18\x6a\x17\x76\x13\xf0\xc0\xed\xfe\x72\xa8\xf4\x5a\x2a\x88\x39\x1a\x78\x7c\xc6\xdd\x04\x5e\x08\xaf\xf0\x9b\x6d\xd9\x75\xea\xa1\x30\x8a\x61\x9b\x7d\x43\xf9\x6b\xfb\xc1\x02\x9e\xe6\x46\x2d\x61\x6e\x72\xd0\x99\x2c\x71\x11\x29\xb9\x8d\x96\x17\xaf\x0e\x71\x3f\xbf\x32\xb9\xbd\xa5\xcb\x8b\xd7\x67\xdc\xd9\x77\xba\x84\xf9\x95\x51\xcb\x81\x50\x75\x5a\x83\x71\x5b\x82\x59\x49\xba\x8b\x92\x94\x94\x25\x0a\x1a\x2b\xb9\xed\x99\xd1\xe5\xda\xbe\xde\xee\xf6\xc1\xc6\xd9\x95\x40\x41\xca\xc6\x04\xb7\x49\xd8\xc5\xb1\x5e\x08\xcf\xf5\x84\x85\x38\xd8\x42\xe1\x72\x01\x4f\xde\x2c\x9b\x99\xde\x60\x78\x6a\xd6\xcc\x20\xf7\xcc\xcd\x81\x5a\xfd\xdc\x73\xb3\xf7\x40\x3d\x7f\x11\xae\x69\x99\x42\x62\xb0\xde\xd4\xe2\x88\xb2\x97\xa8\x76\x45\x4d\x9c\x66\x9c\x68\xfd\x99\x14\xb6\x8d\x44\x19\x51\x34\xba\x19\x8d\x3a\xc8\xba\xc1\x1c\x03\xcc\xff\xd6\xe2\x59\xca\xb7\x68\xd3\x1c\x09\x45\x05\x76\xed\x9d\x0a\xb9\x55\xa4\x8c\x42\x06\x26\x04\xaa\x7f\x3c\xfc\xeb\x0e\x16\x7e\x09\x4f\x2b\xce\xe8\x4d\xa7\x01\x13\x6b\x79\x42\x81\x8a\x37\x0a\x58\xc2\x43\xf9\x9c\x69\x33\xdd\x28\x59\x95\xd0\xfd\x9c\xae\x79\xa5\xf3\x28\x90\x50\xa0\x21\x7f\x9c\x96\xc2\x59\x23\xa5\x21\x3e\x26\x69\xca\x0c\x16\x51\x8f\x36\x34\x32\x9a\x97\xcb\xf9\x6a\xe9\x06\xa2\x9e\x5f\xad\x96\xf3\xab\x72\x19\xb5\xca\xb8\xe2\x6c\x76\xdd\x63\xea\xb8\x2c\x6f\x34\xea\x38\x0e\x75\xaa\x4b\xc1\xfe\x9f\xea\x02\x8a\xd5\x74\x16\xbd\x2b\x73\x7d\x38\x0e\x67\x40\x98\xc9\x81\xe0\xce\xc0\xcb\xba\xb4\x7b\xb5\xeb\x5f\xdb\xe2\xa6\xcb\xb0\x96\xf7\x87\xde\xf2\x55\x7b\x9b\x33\x4e\xe3\x4e\x46\xd2\x05\xcc\xae\xaa\x67\x07\xcc\x45\xd8\xb7\xe5\xfa\xeb\xc1\xb5\x65\x6f\x5c\xd3\xaf\x03\x52\xdf\xac\x07\x48\xeb\x2e\x5e\x27\x4e\xa3\xc3\xe9\x3c\x38\x24\x0d\xd3\xa0\x29\xe6\x3b\xfb\xdd\x13\xb9\x55\xdd\x49\xbb\x86\x68\xd2\xe8\x9b\x1a\x79\x27\x33\xc2\xd1\x5e\xd4\x23\x3e\x81\x4b\x88\x20\x82\xcb\x37\x44\xf6\xa5\x21\xaa\x0d\x1a\x90\x7c\xd9\x17\xfd\x49\xd0\x40\xb0\x37\xf2\x27\x82\x7b\x44\xbf\x28\xf8\x63\xa5\x88\x1f\xcf\x56\xb0\x74\x51\xa4\xf5\x59\x5c\xcb\x98\x36\x01\x4a\xf3\xaa\x20\x82\xfd\xc0\xb8\x9d\x9a\x36\x5a\xda\x10\xa3\xcf\x4e\x85\x96\xfa\x8c\xa0\x75\xb4\x27\xa2\x86\xb6\x4e\x9c\xfe\x3e\x47\x1c\x53\x2a\xaa\xc2\xdf\xb4\x1e\xea\x79\x67\x08\xfb\x8d\x7b\xee\xdd\x92\x32\x8c\xee\xaf\xfe\x14\xfc\x6d\x5e\x89\xe7\x41\x74\x7f\x33\x00\x0e\xd0\x39\xbe\x5e\xb8\xce\x76\x7d\x40\x7f\x86\xf3\x43\xea\xe3\xee\xff\x1a\x6c\x78\xad\x19\xa7\xd6\xbc\x01\x5d\x4e\x78\xe8\xce\xaf\x97\x2d\x72\x7f\xc7\x7c\x1f\xda\xbd\xac\x54\x86\x6f\x15\xd5\xee\xbc\xc9\x69\xd6\xef\x7f\x4d\x53\x0c\x67\x5c\x78\xdf\x14\xda\xb1\xfb\x36\x17\x8e\x11\x04\xea\x37\x4a\x34\x9b\x41\x48\xe6\x86\x75\x6f\x73\x08\xef\x59\xc0\xdf\x6c\x2f\x35\x99\xac\x8c\x77\xca\xf0\x36\xe3\xdc\xd3\x0d\xa2\x66\xc0\xd4\x20\xd1\x7c\xb5\xb4\x3d\xc7\x7e\x76\x5e\x42\x64\xe7\xa5\x7d\x75\xa4\xf5\x81\x5a\x46\xa3\xfd\xe8\xff\x01\x00\x00\xff\xff\x48\xba\x37\xe4\x98\x14\x00\x00") +var _pkgUiStaticJsBucketJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x57\x5f\x6f\xe2\x3a\x16\x7f\xef\xa7\x38\x93\x1d\x5d\x12\x15\x52\x46\x5a\xed\x43\x0b\x48\x77\x3b\x23\xed\x5d\x75\x67\x56\xd3\x3e\x6d\x35\x52\x4d\x7c\x20\x5e\x1c\x9b\xb5\x9d\x32\x4c\xc5\x77\x5f\xd9\x8e\x83\x09\x81\xcb\xdc\x1b\x21\x44\xec\x73\x7e\xe7\xff\x1f\x96\x52\x2e\x39\xe6\x45\x49\x94\xd1\x39\x97\x84\xa6\x83\xa2\x56\x0a\x85\x19\x0c\xe1\xed\x0a\x00\x60\xb0\x26\xc5\x8a\x2c\x51\x0f\x6e\xe1\x79\x60\x58\x85\x9c\x09\x1c\x7c\xbb\xda\x65\x77\x57\x87\x00\x1a\xcd\x17\xf1\x20\x09\xbd\x27\x9c\xcf\x49\xb1\x4a\xa9\x22\x9b\xec\xee\xea\x6a\x51\x8b\xc2\x30\x29\xc0\x1e\xa4\x59\x03\xcd\x16\x90\x9a\x92\x08\xa9\x73\x85\x0b\x85\xba\x44\xfa\xab\x81\xe9\x14\x92\xf1\x78\xfc\x61\xe4\x3e\x4f\xe3\xf1\xad\xfb\xfc\x27\x09\x7c\xf6\x69\xf8\x50\x29\x98\x42\xf2\xb8\x15\x45\xa9\xa4\x60\x3f\x98\x58\xc2\x9c\xcb\x62\xa5\x61\xa1\x64\x05\x0a\x2b\x69\x10\xb4\x91\x8a\x2c\x31\xb9\x73\x00\x3b\xf7\x8d\x5c\xa3\xd3\xe1\x5d\x04\xf6\xcb\x2f\x01\xda\xa3\xe4\x1c\xc5\xd2\x94\x56\xa9\xf1\x69\xf9\x9f\x65\x10\x4a\x14\x42\xe3\x42\xbe\x05\xeb\x52\xa4\xad\xd4\xae\xd5\x96\xfb\xdd\x14\x44\xcd\x79\x8c\xfd\x3e\x4d\xfe\x82\x4a\x25\x59\xae\x4b\xb9\x49\xb3\x7c\xc1\x04\x4d\x07\x39\xe1\xa8\xcc\x20\xcb\x0d\x7e\x37\xe9\x3f\x1f\xbf\x7c\xce\xb5\x51\x4c\x2c\xd9\x62\x1b\x21\x0e\x1d\xde\x10\xfe\x9a\x65\x77\x2d\xa4\x46\xf3\xc4\x2a\x94\xb5\x49\x43\x2c\xd2\x58\xa4\x7d\xb8\x2c\x88\xbd\xc8\x15\xba\x54\x88\xd8\x77\x43\xf8\x30\x1e\x8f\xc7\x36\x96\xee\xdd\x3b\xaf\x4f\xe5\x92\x51\x4c\x03\x9d\x7d\x5e\x89\x82\x42\x0a\x43\x98\x40\xeb\x2c\x2a\x8b\xba\x42\x61\xf2\x25\x9a\x4f\x1c\xed\xcf\xbf\x6f\x7f\xa3\xe9\xe0\x5e\x56\x6b\xe2\x54\xd3\x83\x48\xb6\xe3\xb7\x09\x06\x53\x10\xb8\x81\x26\xe7\x5e\x99\xae\x09\x67\x3f\xbc\xca\x4f\x4d\x5e\xa6\xad\xa4\x0e\x02\x25\x86\x3c\x91\x39\xc7\x73\x28\x1f\x03\x51\xda\xe1\x36\xcc\x70\xd4\x30\x85\xb7\x5d\x64\x59\x8b\x99\x13\x4a\xef\x25\xaf\x2b\x91\xbe\x99\xed\x1a\x6f\x61\xe0\x23\x33\x18\x02\xa3\xb7\x30\xf8\x8a\x6b\xce\x0a\x32\xd8\x45\xb8\x97\x73\x3f\x90\x39\xf2\x9f\xe7\x55\x92\xdb\x77\x23\x25\x37\x6c\x7d\x31\x3f\x25\x06\x83\xe4\x47\x43\x94\xf9\x43\x9c\x9f\x04\x75\x7c\xfd\x8c\x5f\xe5\x46\xa7\x07\x75\x76\x90\x89\xb9\x96\xca\xa4\x29\x19\xc2\x3c\x83\xe9\x0c\x48\xde\xd0\x52\xb9\x11\x9a\x54\x6b\x8e\xb9\x42\x2d\x79\xed\x9a\xca\x08\xe6\x67\x09\xb2\x43\xf0\x8a\xac\xf7\x45\x40\xbb\x55\x60\x9f\x9b\x1b\x78\xb2\x11\x07\xa6\xc1\x94\x08\x0b\xa6\xb4\x81\xc2\x59\x0b\x72\xe1\xce\x42\x27\xcc\x7b\xb8\xfb\x00\x7f\x85\x5a\xb0\xff\xd5\x08\xff\x56\xb2\x42\x53\x62\xad\x81\xdb\xc0\xda\x56\x62\x80\x51\x14\x86\x2d\x18\x6a\x40\x52\x94\xa0\x4b\xa2\xa8\x95\x5f\x6b\xa4\x7d\x78\x44\x37\x6a\x38\x3d\x17\xb0\x56\xa8\x51\x98\x21\x48\x53\xa2\xda\x30\x8d\x1e\xde\xb7\x24\xca\xf4\x9a\x93\x6d\x3f\x14\x7e\x37\xa8\x04\xe1\x7c\x6b\x51\x09\x70\x5c\xa2\xa0\xc7\x86\x79\x59\x53\x38\xd9\x41\xc2\x63\x4b\x66\x85\x5b\x98\x86\x36\xe9\x0d\x7d\x37\x85\x24\xb1\x1d\x96\xe6\xf1\xb9\x7e\x8e\xdf\xbe\x45\x39\x13\x3f\xb6\x6d\xae\x70\x7b\x4a\xa4\x7d\x14\x9a\x5a\x09\x2b\xf9\xae\x97\xe6\xa8\x6b\x9d\x32\xd0\x97\xfb\xf3\xbe\xbb\x76\x14\xce\xbe\xf5\x0b\x08\x7a\x36\x38\x53\xa8\x05\xc5\x05\x13\xd8\x9b\x65\x7d\x92\x1f\x9d\xc8\xf4\xcb\xfc\xbf\x58\x98\x7c\x85\x5b\xed\xc1\x74\x16\x06\xd1\x35\x7c\xc8\x4e\x4b\x6f\xb1\xce\x6a\x1f\x4c\x3c\x8d\xb3\xfb\x3d\x27\x9f\xe1\x3f\xe6\xdd\x1d\x0c\x84\xf0\xf8\xa4\x98\xc2\x0b\xc7\x57\xe4\xb7\xf0\xfe\x8d\xe6\x45\x3b\x03\x72\x77\xba\x1b\xc2\xbe\x8e\x3d\xc9\xb9\x4a\xdf\xbd\x1c\xab\xd4\x28\xfc\xec\x34\x1e\x7a\xa9\x43\x58\xa2\x40\x45\x0c\x3e\xf9\xee\x98\xd2\x6c\xe8\xe6\xc2\x47\x62\x30\xa5\x79\xc5\x84\x1d\x29\x9d\x43\xf2\xdd\x1d\x76\xa2\xbf\xcb\x62\xeb\xdc\xa8\xca\xdd\x9e\xd3\xb6\xbc\xf8\xfe\xe6\x06\x1e\x4b\xb9\x69\x8b\xae\xa9\x36\x9b\x37\x42\x46\xa7\xbe\x76\x37\xa8\xd0\x0e\xef\x7d\x31\x46\xeb\x43\xe3\x40\x5b\x55\xdd\xfc\xb2\xf3\xd8\x03\xb7\x5b\xc4\xa1\xd2\x0b\xa9\x20\xe5\x68\xe0\x79\x85\xdb\x21\xbc\x12\x5e\xe3\x37\xdb\xdb\x9a\xd4\x43\x61\x14\xc3\x36\xfb\xfa\xf2\x57\xc9\x8d\x8d\xde\xc4\xa8\x19\x4c\x4c\x09\xba\x90\x6b\x9c\x26\x4a\x6e\x92\xd9\xfb\x37\x87\xb8\x9b\xdc\x98\xd2\xde\xd2\xd9\xfb\xb7\x15\x6e\xed\x3b\x9d\xc1\xe4\xc6\xa8\x59\x4f\xa8\xf6\x5a\x83\x71\xb3\xda\xcc\x25\xdd\x26\x59\x4e\xd6\x6b\x14\x34\x55\x72\xd3\x31\x63\x9f\x6b\xbb\x66\xc7\xda\x45\xdb\xe6\xbe\x04\x2a\xb2\x0e\x26\xb8\x79\x6e\x97\xb6\x66\x2d\xbb\xd4\x13\x16\xe2\x60\x03\x84\xeb\x29\xbc\x78\xb3\x6c\x66\x7a\x83\xe1\x25\x5e\x31\x43\xb1\xdc\x1d\xa8\xd5\xcd\x3d\x37\x01\x0f\xd4\xf3\x17\xf1\xb2\x54\x28\x24\x06\x9b\x7d\x29\x4d\x28\x7b\x4d\x1a\x57\x34\xc4\x79\xc1\x89\xd6\x9f\x49\x65\xdb\x48\x52\x10\x65\xd7\xce\xab\x3d\x64\xd3\x60\x4e\x01\x96\x7f\x6b\xf1\x2c\xe5\x31\xda\xa8\x44\x42\x51\x81\x5d\x3e\x47\x42\x6e\x14\x59\x27\x31\x03\x13\x02\xd5\x3f\x9e\xfe\xf5\x00\x53\xbf\x0b\xe7\x35\x67\xf4\x6e\xaf\x01\x13\x0b\x79\x46\x81\x9a\x07\x05\x2c\xe1\xa1\x7c\xce\xb4\x19\x2d\x95\xac\xd7\xb0\xff\x39\x5a\xf0\x5a\x97\x49\x24\xa1\x42\x43\x7e\x3b\x2f\x85\xb3\x20\x25\x10\x9f\x92\x34\x62\x06\xab\xa4\x43\x1b\x1b\x99\x4c\xd6\xb3\xc9\x7c\xe6\x96\x33\x3d\xb9\x99\xcf\x26\x37\xeb\x59\xc3\x60\xb5\x71\xd5\x19\x56\xce\x53\xfa\xb8\x34\x0f\x2a\xed\x39\x0e\x95\x6a\x6a\xc1\x7e\x8f\x74\x05\xd5\x7c\x34\xfe\xc9\xdc\xf5\x01\x39\x9c\x02\x71\x2e\x47\x92\xf7\x26\x5e\x37\xc5\xdd\xa9\x5e\xff\xda\x96\x37\x9d\xc5\xd5\xbc\x3b\xf4\x97\xaf\xdb\xfb\x92\x71\x9a\xee\x65\x64\x51\xcc\xec\xce\x78\x71\xcc\x5c\x90\x7d\x67\x6e\xd6\x78\xd7\x99\xbd\x75\xa1\x65\x47\xa4\xbe\x5f\xf7\x90\x36\x8d\xbc\xd1\x23\xe8\x70\x49\x2a\xb4\xb4\x71\x2a\x84\x82\x7e\xb0\xff\x40\x12\xb7\x34\x3b\x71\xb7\x90\x0c\x83\xc2\xb9\x91\x0f\xb2\x20\x1c\xed\x45\x33\xe6\x33\xb8\x86\x04\x12\xb8\x3e\x22\xb2\x2f\x81\x28\x3b\x29\xf9\xba\x2b\xfa\x93\xa0\x91\x60\x6f\xe5\xef\x08\xee\x10\xfd\x41\xc1\x1f\x6b\x45\xfc\x88\xb6\x82\xa5\x0b\x23\x6d\xce\xd2\x46\xc6\x28\x44\x28\x2f\xeb\x8a\x08\xf6\x03\xd3\x2c\x4e\x05\x6d\x88\xd1\x17\xe7\x42\x4b\x7d\x49\xd4\xf6\xc4\x67\xc2\x86\xb6\x54\x9c\x01\x3e\x4b\x1c\x53\x2e\xea\xca\xdf\xb4\x2e\xea\xb8\xa7\x0f\xfb\xc8\x3f\x8f\x6e\x53\xe9\x47\xf7\x57\x7f\x0a\xfe\xbe\xac\xc5\xaa\x17\xdd\xdf\xf4\x80\x03\xec\x3d\xdf\x6c\x5d\x17\xfb\x3e\xa2\xbf\xc4\xfb\x31\xf9\x69\xff\x7f\x8d\xf6\xbc\xd6\x8e\xb3\x7f\xeb\xce\xa1\x1f\xb9\xe8\xc1\x2f\x99\x2d\x72\x77\xd3\xfc\x39\xb4\x47\x59\xab\x02\x8f\x15\xd5\xee\x3c\x64\x35\xeb\xf6\xc0\xd0\x18\xe3\x49\x17\xdf\x87\x52\x3b\x75\xdf\x26\xc3\x29\x82\x48\xfd\xa0\x44\xd8\x0f\x62\x32\x37\xb2\x3b\xfb\x43\x7c\xcf\x22\xfe\xb0\xc3\x34\x64\xb2\x36\xde\x29\xfd\x3b\x8d\x73\xcf\x7e\x18\x85\x21\xd3\x80\x24\x93\xf9\xcc\x76\x1d\xfb\xe7\xf0\x1a\x12\x3b\x35\xed\xab\x23\x6d\x0e\xd4\x2c\xb9\xda\x5d\xfd\x3f\x00\x00\xff\xff\xe7\x65\x3f\x08\x9a\x14\x00\x00") func pkgUiStaticJsBucketJsBytes() ([]byte, error) { return bindataRead( @@ -500,7 +511,7 @@ func pkgUiStaticJsBucketJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/js/bucket.js", size: 5272, mode: os.FileMode(420), modTime: time.Unix(1582318785, 0)} + info := bindataFileInfo{name: "pkg/ui/static/js/bucket.js", size: 5274, mode: os.FileMode(436), modTime: time.Unix(1588865307, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -520,7 +531,7 @@ func pkgUiStaticJsGraphJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/js/graph.js", size: 38722, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/js/graph.js", size: 38722, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -540,7 +551,247 @@ func pkgUiStaticJsGraph_templateHandlebar() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/js/graph_template.handlebar", size: 8984, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/js/graph_template.handlebar", size: 8984, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactAssetManifestJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x94\x3f\x4f\xc3\x30\x10\xc5\xf7\x7c\x0a\x2b\x33\x75\xdd\xfc\x69\x13\x56\xd4\x01\x09\xb1\x30\x22\x86\xf8\x7c\x51\x9d\x36\x6e\x15\xbb\x50\x84\xfa\xdd\x91\x4b\xa0\x6e\xfe\x14\x0b\x31\xda\x7e\xbf\x77\xbe\x77\x71\x3e\x02\x42\xc2\x52\x6e\x50\x87\xb7\xc4\x2e\x08\x09\xeb\x42\x2a\x0a\xda\xee\x84\x74\xaa\x4d\x61\x24\x4c\x41\xeb\xe9\xe9\x80\x45\x71\x1e\xa1\x40\x0a\xab\xbd\x5a\x9f\x74\x37\x0e\x57\x5d\x62\x55\x4b\x71\x91\x41\x92\x0b\x68\xa9\xaa\x0b\xd1\xba\xd8\xf9\x81\x27\x65\x0b\x37\x7b\x65\x64\x8d\x93\x91\xca\x17\xc7\xa9\xe0\x11\x9b\xf3\xd4\xa9\xdd\xc1\x87\xee\x30\x66\xe1\xde\xc2\x49\x28\xa2\xa2\x4c\x22\xc8\x17\x89\x13\x4f\x37\xc6\x41\xd1\xa5\x57\x65\x55\x3c\x66\x79\xc1\x67\xd9\x39\xb3\xce\xe5\x86\x24\x3e\x3e\x43\x8d\x8e\xc9\x5a\x3f\xa9\x04\x1e\xe8\xca\xd4\x9b\x2f\xd0\x59\xb7\x8a\x5d\x83\x50\xc0\xca\x46\xa5\x64\x89\xda\xd0\x94\xc7\x59\x91\x94\xc0\xb8\xc0\x59\x02\xf3\x32\x9e\x95\x0c\x13\xc6\xd2\x45\x96\xe5\x98\xff\x74\xf4\x37\xf4\xbb\x53\x6c\x5e\x25\xe0\xe4\x6d\xdb\xac\xb1\x39\xa7\xd4\xdb\xf6\x9b\x56\x2f\x9b\xab\xc2\xbe\xe7\xc8\x1b\x19\xb4\xbd\xa6\xf5\x9a\xe3\xc3\xfd\xdd\xf2\xf1\x69\x49\xcd\xc1\xf8\xcc\xd3\x95\x07\x84\x1c\x6d\x8d\x10\x95\x69\xde\x77\x5b\xa9\x8c\x4d\xee\xb9\x5b\xf6\xb7\x37\xf4\x2f\xdf\xb5\x77\x8c\x7d\xbb\x91\xbf\x4b\x40\xc8\x4b\x70\xfc\x0c\x00\x00\xff\xff\x79\x67\x81\x7b\xde\x04\x00\x00") + +func pkgUiStaticReactAssetManifestJsonBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactAssetManifestJson, + "pkg/ui/static/react/asset-manifest.json", + ) +} + +func pkgUiStaticReactAssetManifestJson() (*asset, error) { + bytes, err := pkgUiStaticReactAssetManifestJsonBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/asset-manifest.json", size: 1246, mode: os.FileMode(436), modTime: time.Unix(1589211666, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactFaviconIco = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xd9\xcf\x6b\x13\x51\x10\x07\xf0\x49\x83\x8d\x28\x36\xe2\xa1\x50\x2f\x11\xeb\x8f\x9e\x04\x2f\x8a\x17\xdd\x09\xd2\x82\x15\xc4\x83\x17\x69\xd1\x3f\x20\x13\xc5\x83\xa8\x20\x2d\xe8\x41\x14\xec\x29\x1e\x54\xa8\x07\x45\xf4\xa0\x55\x54\x04\xa1\xac\xa8\xd0\x7a\x11\x11\xf1\x67\xa1\x58\x14\xad\x08\xed\x41\x2c\x52\x3b\xb2\xed\xdb\x76\xfb\x9a\x74\x93\xdd\xb7\xdb\x4d\xf6\x2d\x7c\x19\xf2\x3a\xbb\x3b\x9f\x64\x93\xe6\x07\x40\x02\x12\x60\x18\x56\x5d\x07\x2d\x59\x80\x46\x00\x68\x01\x00\x03\x00\xba\x61\x66\x5d\x6f\x7a\x5b\x6c\xe3\x6c\x6e\x25\x23\x6d\xae\x82\x6c\x62\xa4\xb5\x8c\xb4\x42\xb1\xbf\x8d\x91\xb8\x8a\xf2\x9b\x91\xde\x31\xd2\x65\x46\x6a\x67\xcc\xd7\xfb\xf4\xb7\x46\xc0\xe4\x27\x3f\x18\xa9\x9b\x31\xd7\x10\x53\xbf\x9d\x51\x46\xea\xe4\xa6\xd3\x71\xf5\xdb\xb9\x59\xc9\x6b\x44\x0d\xfa\xad\x0c\x30\xd2\x9a\x18\xfb\xad\x0c\x96\x73\x1d\xd4\xb0\x9f\xa7\x9f\x0b\x6d\xc7\xa3\xe0\x7f\xc4\x48\xad\x2e\x79\x11\xd0\xb9\x0f\x47\xc0\x7f\xc5\xf5\x3a\x44\xba\x1b\xd0\xb9\x7f\x32\xd2\xea\x18\xfb\xad\x9c\x55\xe4\xef\x67\xa4\x0b\xe2\x7a\x2e\x69\x15\x3d\xef\x7d\xf8\x5f\x89\x63\xdc\x50\x78\x0d\x2c\x57\xe0\x3f\x2a\x66\x3d\x54\xba\x27\xd7\x2c\x7a\x6e\xfb\xf0\x17\xa6\xd7\x0c\xda\xa1\xf0\x1a\xd8\xaf\xc0\x5f\x60\xa4\x2c\x23\x9d\x5b\xa4\xa7\x43\xf4\x98\x3e\xfc\xf7\xc4\x31\x72\x0a\xfd\xd7\x14\xf8\xbd\x66\xa9\x9f\xff\x56\x86\x62\xee\x9f\x60\xa4\x05\x9f\x91\x62\xe4\x67\xce\xd2\x82\x2f\xc4\x62\xe5\x47\xda\x12\x73\xff\xd6\x80\xfd\xd6\xe7\xae\x4b\x8e\xfc\xf3\xe0\xff\xc3\x48\xf7\x1d\x19\x8a\x90\xbf\xc0\x98\x5b\xec\xff\xdf\x49\xc9\xf4\xd7\x83\xff\xab\xb4\x7e\xb1\xc4\xb9\x4e\x89\x59\xae\x87\xe8\x77\x7b\xff\x13\xa6\x7f\xaf\xf8\xfb\x99\x10\xfd\xd6\x7b\x9a\x1e\x46\x7a\x1c\x01\x7f\x9f\x98\x65\x30\x44\xbf\x5b\x7e\x31\xd2\x67\x47\xa6\x3c\xf8\x27\xc4\xfd\x6c\x67\x44\xe1\x7c\x41\xfb\x4b\x25\x2e\xaf\xff\xda\xaf\xfd\x7e\xfd\x1f\x18\xe9\x99\x23\xcf\x1d\xef\x23\x96\xd2\xff\x9a\x91\xf6\x38\xf2\xb2\x44\xdf\x94\x98\x77\xca\xa3\xbf\x43\x5a\x5f\x26\x5e\x13\x9d\xe7\x78\x22\xcd\x32\x1c\x82\xbf\x5f\x9a\xeb\x41\xd1\x3e\x23\xb7\x1e\xfc\x7d\xff\xd1\x29\xad\xd7\x17\xf1\xf7\x4a\x3d\x6f\x22\xe8\xbf\xa5\xe8\xf1\x8f\x8a\x7f\x40\xfa\x3d\xda\x2c\xd1\xf7\x89\x91\xde\x32\xd2\x78\x80\xfe\x3b\xd2\x2c\x1f\x43\xf0\xfb\x49\x25\xfe\x7e\xf1\xdb\xb6\x9d\xab\x8c\x34\xa9\x68\x8e\x6a\xf0\x07\x19\xed\xd7\x7e\xaf\xfe\x02\x23\x9d\x70\xe4\xfc\x12\xfa\xbb\xa4\x59\x7a\x43\xf0\x6f\x9b\xbf\x1f\x35\x17\xe9\x09\xe7\xf3\xef\xee\xfc\x2a\xa9\xa7\x5d\xfb\xb5\x3f\x60\xff\x76\xc6\x23\x89\xd9\x64\x69\x43\x91\x9e\x87\x8c\x74\xcc\x91\x49\x0f\xfe\x31\xe9\x18\x4f\x8b\xf8\x1b\xe6\xcd\x12\x8e\xff\x3b\x23\x7d\x71\xe4\x5b\x99\xfb\x55\xea\x2f\x27\x23\xd2\x2c\xa3\x21\xf8\xfd\xa4\x1c\x7f\x5f\x08\x73\x78\xf1\xb7\x31\xe6\x37\xfa\x4c\xa3\xbb\x3f\xdf\xe4\xff\x3c\x74\x30\x00\x7f\x8b\xdb\xec\x51\xd9\x18\x69\xa7\xf6\x6b\xbf\xf6\x6b\xbf\xf6\x6b\xbf\x22\x7f\x96\x0d\xca\x54\x45\x90\x0e\x04\xe0\xaf\xa5\x68\xbf\xf6\x6b\xbf\xf6\x6b\xbf\xf6\xdb\xfe\x46\x46\xda\x17\x93\xa4\x65\xbf\xde\xe2\xb9\xb1\xb4\x99\xd6\x62\x42\x54\xc8\x88\x9a\x12\x35\x29\x2a\xd8\xb5\x4b\xd4\x5d\x52\xcd\x98\x00\xe9\x31\x80\xb4\x54\x53\x66\x5d\x22\x3d\xd6\x0d\xa9\xd9\xdb\xf3\x6b\xd2\xbd\x26\x7b\xc6\x4d\x48\x9a\x75\x56\x35\xe6\x6e\x97\xbd\x3f\xa4\xa7\xfb\x53\x89\xf4\xb8\x39\x3c\x57\xed\xf5\x72\x8f\x93\xb2\xce\x3b\xbc\xb0\xba\xed\x97\xb1\xee\xe5\x89\xca\xeb\xcc\xfd\xea\xbb\xca\x8f\xf7\xff\x00\x00\x00\xff\xff\x98\xca\x18\x50\x3e\x42\x00\x00") + +func pkgUiStaticReactFaviconIcoBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactFaviconIco, + "pkg/ui/static/react/favicon.ico", + ) +} + +func pkgUiStaticReactFaviconIco() (*asset, error) { + bytes, err := pkgUiStaticReactFaviconIcoBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/favicon.ico", size: 16958, mode: os.FileMode(436), modTime: time.Unix(1589211640, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x56\xff\x6f\xdb\xb6\x13\xfd\x57\x64\x7e\x00\x41\x44\x68\xda\x4e\x03\x7c\x12\xdb\xcc\xd0\x0e\xdd\xba\xa2\x6d\x82\x25\x3f\x6c\x10\x84\x80\xa6\x4e\x11\x13\x9a\xd4\xc8\x93\xd3\xc0\xd1\xff\x3e\x50\xfe\x96\x66\xcd\xd6\x20\xb0\x29\xf2\xdd\xe3\xe3\xbb\xd3\xd1\xf3\x41\xe9\x14\x3e\x36\x90\xd4\xb8\x34\xe7\xf3\xf8\x99\x18\x69\x6f\x05\x01\x4b\xce\xe7\x35\xc8\xf2\x7c\xbe\x04\x94\x89\xaa\xa5\x0f\x80\x82\xb4\x58\x0d\x4f\xc9\xe8\x7c\x6e\xb4\xbd\x4f\x3c\x18\x41\x42\xed\x3c\xaa\x16\x13\xad\x9c\x25\x49\xed\xa1\x12\x84\x8f\x2a\xb9\x8a\x13\x5c\x2b\x17\xf1\x3d\x8d\x95\x4b\x10\x64\xa5\xe1\xa1\x71\x1e\x49\xa2\x9c\x45\xb0\x28\xc8\x83\x2e\xb1\x16\x25\xac\xb4\x82\x61\xff\xc0\xb4\xd5\xa8\xa5\x19\x06\x25\x0d\x88\x09\x0b\xb5\xd7\xf6\x7e\x88\x6e\x58\x69\x14\xf6\x25\x29\xd6\xb0\x84\xa1\x72\xc6\xf9\x67\xbc\xff\x1b\xf7\x7f\x11\x1b\x94\xd7\x0d\x9e\x2b\x67\x03\x26\xbf\x7e\xba\x78\xf7\xf6\xd3\xcd\xe5\xdb\xeb\x0f\x37\x97\xbf\xbf\xff\xe5\xb7\x3f\x04\x21\xf3\xd1\x16\xf3\x2d\xf6\xfa\xc3\xdb\x2f\x17\x57\x37\x3f\x5f\x7c\xbe\xbc\xf8\xf2\xfe\xcb\xb5\x20\x7f\xb5\xe0\x1f\x9f\xc1\x0f\x5e\x2c\xa5\xd5\x15\x04\x3c\xd8\xb0\x9b\xe1\x77\xc1\xd9\xa8\x03\x35\x1a\x38\xbf\xae\xa5\x75\x21\x79\xff\xb5\xf1\x10\x82\x76\x36\x79\xe7\xdd\x43\x00\x3f\x1f\x6d\x00\x1b\xd2\x1d\x4b\x40\x89\x5a\x8d\x54\x08\xa3\x63\x5e\x56\x27\xc7\xea\xec\xff\x27\x5c\xd5\xad\xbd\xe7\x2a\x04\xb2\xcd\x04\x3e\x1a\x08\x35\x00\x92\xd7\xe3\x97\x52\x5b\x3e\x3e\x7e\x73\x76\x0c\x25\xfc\x3b\xc5\x68\x53\x01\x0b\x57\x3e\x9e\xcf\xad\xdb\x1e\xf7\x4f\xd7\x26\x16\xa0\x4c\xd0\x25\x60\xe5\xc2\x40\xf2\x51\xae\xe4\x55\xbf\x1a\x27\x7d\x6b\x13\xac\x75\x48\x64\xd3\xf0\xf9\x68\x1f\x38\x2f\xf5\x2a\xd1\xa5\x20\xde\xb9\x9e\xbe\xd4\xab\xbd\xd7\x83\xaa\xb5\x0a\xb5\xb3\x19\xd0\xf5\x6e\x9c\xf8\xcc\xd3\x75\xe5\x7c\xb6\x92\x3e\xb1\xcc\x30\x29\x7c\x3e\x2e\x58\x23\x7c\x3e\x29\x58\x25\x7c\x7e\x5c\x30\x25\xc6\x2c\x88\xbc\x98\xa9\xb9\xe4\x06\xec\x2d\xd6\x33\x75\x74\x44\x8d\x90\xb9\x2a\xd8\xc5\xe2\x0e\x14\xf2\xc6\x3b\x74\xb1\xdc\x79\x2d\xc3\xc5\x83\xbd\xf4\xae\x01\x8f\x8f\x5c\x49\x63\x32\xc7\x0c\x4d\x53\x97\x9b\x22\x4d\x03\x6f\xda\x50\x67\xf1\x21\x1f\x17\x94\xc5\x81\x18\xcf\xa2\x0e\x9b\x68\x9b\x34\xf4\x87\x28\x1b\x66\x69\x9a\x66\x90\xdb\x42\x34\xb9\x2d\x68\xcf\xa0\xd3\x54\x67\x9e\xce\xc2\x4e\x29\x0d\x3c\xd4\xba\xc2\x8c\x66\x74\xe6\x01\x5b\x6f\x93\xb6\x57\xc0\x65\xd3\x98\xc7\xac\x65\xd5\xd3\x53\x5e\x50\x86\x19\xed\xf6\xd6\x60\x76\x70\x06\x98\x17\xe3\x99\x9f\xb7\x3b\x4e\x7f\x74\x74\x58\x45\xd1\xe6\xbe\x60\x56\x0c\xc6\x4c\x8a\xc9\x4c\xce\x71\x87\x93\x11\x17\x31\x8d\xc0\x5c\x16\xb3\xf1\x40\x08\x97\x37\x45\x9a\x66\x56\x0c\x26\xb4\xb3\x69\x9a\xb5\x3c\x34\x46\x2b\xc8\xfc\x70\xc8\x26\x94\x81\x30\x99\xe1\x41\x60\x34\x87\x76\x5b\xc9\xd0\xf5\x39\x12\xeb\x8e\x39\xb1\x9e\x4c\xc7\x1d\x6b\x63\x4e\xf6\x82\x4d\xcc\xa5\xae\x32\x9b\xfb\x82\x6e\x83\xe2\x98\xc3\xd7\xd8\x0d\xc2\x6c\xa3\x35\x4e\x89\xb5\x9e\x7a\x66\xa6\x83\x09\xdb\x2e\x4e\xd7\x5d\xb7\x33\x07\x62\x50\xef\x30\xee\x62\x19\xb2\xc3\xd8\x50\x86\xdc\xc4\xd3\xee\xe7\x3a\xc3\x97\x02\x98\xe1\x4a\x58\x66\x78\x29\x0e\xd5\xc6\x3c\x43\xba\x36\xdc\xc5\x21\x7d\x7a\xda\xa6\xb6\x84\x4a\x5b\xd8\x25\xb4\x87\xad\xc1\xb6\x4b\xf0\xb1\xe2\xa7\x83\x31\xbb\x05\x9c\x62\x47\x3b\x66\xb8\x17\xcf\xab\x97\xb4\x76\x13\x5d\x92\x81\x88\xd5\xe1\xaa\xe4\xea\x71\xb9\x70\x26\x4d\x37\xdf\x1c\xdd\x15\x7a\x6d\x6f\xaf\xe5\x6d\x9a\xbe\xb6\xe3\x3f\xb1\x6c\xbd\x92\xa6\x85\x29\xf9\xec\xca\xd6\x00\xe9\x28\x7b\x2d\x98\xdc\xdc\x40\xd8\xc2\x76\x61\x83\xf1\x46\x2e\x7e\x73\xfc\x3e\x29\x93\xd4\xc7\x52\x15\x26\x03\x4a\xd9\x69\xea\x77\x19\x82\x99\xae\xb2\x93\xb8\x4a\x5c\xbf\x15\x11\xbb\x33\x41\x9a\xc6\x7f\x7e\xd8\xe9\x10\xb4\xc9\xe5\x56\x9c\xf2\x20\x11\x32\xdb\x1a\x43\x23\x9d\xe1\x3e\xc3\xd7\xa4\x23\x23\x25\x54\xb2\x35\x48\x5e\x3a\xbe\x39\x05\x74\x94\x1d\xf7\x82\x42\xef\xcb\xc1\x64\xa0\xfb\x56\x11\x5f\x53\xa0\x86\x97\x19\x32\xcb\xf6\xc7\xf5\x74\xfd\xac\x88\x3a\xbe\xd0\xb6\xec\x75\x31\x4b\xf7\x2f\x1f\x46\x8f\xec\x37\x29\x8d\x9c\x5e\xbc\x38\xed\x4f\x7b\xc4\x81\x95\x6f\xb5\x77\xd3\xef\x2c\xee\x2b\x38\xea\xf2\x8c\x48\xc2\x3c\x65\x3e\x6e\xe7\x5e\xa4\x64\x0b\xfc\xa1\x3e\x13\x03\x22\x47\x13\x3b\x3d\xe9\xad\x97\x22\x36\x60\xfe\x00\x8b\x46\xaa\xfb\x8f\xc1\xd9\xe6\xd6\xcb\xa6\x7e\x65\x3a\xb6\x17\xd6\x08\xb9\xe9\x3a\xbd\x29\x92\xce\x36\x8f\xc2\x33\x29\x24\x0f\x7d\x07\xd8\xb4\xb0\xb8\x43\x15\x1b\xe2\xa1\xdd\x56\x47\x47\xd4\x67\x32\xaf\x0a\xda\x0b\xd0\xa2\x99\xc5\x76\x95\xe5\x05\x7d\x79\xaf\x26\xc1\xab\x67\x97\xd2\x5d\xbc\xd3\x16\x6f\xc6\x67\x72\x31\x39\xdd\x5e\x48\x77\x21\xde\x0f\xff\x15\xd6\x5f\x65\x8b\xf2\x54\x9d\x9c\x95\xea\xbb\x91\xa3\xcd\xdd\x35\xea\x7f\xe0\xfc\x1d\x00\x00\xff\xff\x6f\xa8\xbe\x2f\xf0\x08\x00\x00") + +func pkgUiStaticReactIndexHtmlBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactIndexHtml, + "pkg/ui/static/react/index.html", + ) +} + +func pkgUiStaticReactIndexHtml() (*asset, error) { + bytes, err := pkgUiStaticReactIndexHtmlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/index.html", size: 2288, mode: os.FileMode(436), modTime: time.Unix(1589211666, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactManifestJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x8e\xc1\x4e\xc3\x30\x0c\x86\xef\x79\x0a\xcb\x5c\x61\xb0\xae\xea\x61\xcf\xc1\x0d\xa1\xca\x4b\xdd\x35\x22\x8d\xa7\x24\x83\x8c\x69\xef\x8e\x9c\x20\xc1\x7c\xc8\xc1\xdf\xe7\x3f\xff\xd5\x00\x60\x5a\x24\xe6\x31\xd0\xca\xb8\x07\x7c\x5d\x28\x48\xc2\x47\x25\xf7\x3b\xf8\xe2\x03\xb8\x90\x39\xce\x64\xb9\x19\xce\x4a\x48\xb8\x87\x37\x03\x00\x70\xad\xaf\x46\x46\xab\x77\x33\x7d\xaa\xb0\x71\x56\xaa\xde\x98\xfb\x66\x3d\xc1\xa1\x2f\x43\x0f\xbb\xae\xec\x3a\xe8\xfa\xd2\xf5\xb0\x1d\xca\x76\xf8\x33\xf3\xe5\x54\xbf\x77\x2b\x1d\xf9\xb9\x3c\x69\x16\x56\x78\x33\x00\xef\xb5\x40\xca\x14\xf3\x78\x8e\x5e\xc5\x4d\x2b\x35\xb9\x74\xf2\x74\xd1\x4d\xca\x14\x26\xf2\x12\x7e\xfb\xe6\x85\x57\x1e\xad\x78\x89\x8a\x1f\x5e\xea\x34\x76\x20\xfb\x71\x8c\x72\x0e\xd3\x3f\x61\xae\x83\xe6\x66\x7e\x02\x00\x00\xff\xff\x64\xee\x72\x4e\x2c\x01\x00\x00") + +func pkgUiStaticReactManifestJsonBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactManifestJson, + "pkg/ui/static/react/manifest.json", + ) +} + +func pkgUiStaticReactManifestJson() (*asset, error) { + bytes, err := pkgUiStaticReactManifestJsonBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/manifest.json", size: 300, mode: os.FileMode(509), modTime: time.Unix(1589211640, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactPrecacheManifest5b38a4fc0bde14c6f31f0e40057889e9Js = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x90\xc1\x8b\x1a\x31\x14\x87\xef\xf3\x57\x84\x39\x29\xd8\x98\xe4\x25\x93\x49\x4b\x4f\xc5\x43\xa1\xed\xa5\x47\x11\x49\x5e\x5e\x70\xac\x8e\x65\x12\x8b\x50\xf7\x7f\x5f\xdc\x75\x4f\xbb\x3b\x28\xec\x39\x79\xdf\xc7\xf7\xcb\xb4\x4b\x7c\xbd\xfe\x3b\x10\x7a\xdc\xd0\x4f\xdf\x77\x89\x72\x61\x5f\xd9\xe4\xbd\xa7\xf3\x99\x2d\x57\x53\x8e\x87\x1e\x7d\x99\x2c\x2b\xc6\xfe\x57\x8c\x31\x56\x0f\xf4\xaf\xcb\xdd\xa1\xaf\x3f\xb3\xda\x46\x32\xd2\x8a\xd0\x58\x61\x5c\x22\x8b\x12\xa2\xf5\x56\x04\x2f\x9d\x0f\x2d\xd4\xb3\xe7\x9b\xe3\xb0\xbb\x7c\xe7\xf3\xae\x8f\x74\xe2\x9b\xb2\xdf\xd5\x15\x63\x0f\xb3\xb7\xb1\x28\x45\x0c\xa9\x89\xc6\x3b\x49\xe0\x1b\x1d\x83\x7e\x85\xca\xc5\x97\x0e\xe7\x98\xf3\x5c\xf1\x98\xb4\x42\x67\x35\xc7\xcd\xb1\xff\xc3\x31\xe7\x31\xbe\x55\xca\xba\x56\x48\x13\x55\x52\xda\xda\x06\xa2\x1b\xe3\xef\x7d\xd7\x73\xa1\xc0\x29\x8a\x74\x9b\xe2\x9e\x84\xed\xa5\x20\x80\x70\x3e\xc8\xf6\x8a\xdf\x8e\xd2\x23\x04\x50\xba\x45\x6a\x0d\x81\x76\xd6\x05\x99\x22\x26\xe1\x94\x93\x1e\x80\xee\x33\xf1\x1f\xdf\xbf\x2d\x7e\xfd\x5e\xf0\x72\x2a\x1f\x35\xdb\xf6\xba\x5a\x88\x2d\x6a\x17\xf1\xa6\xac\xe0\x0c\x81\x74\x08\x36\x79\x0d\x60\x04\x40\x33\x22\x18\x8e\x7d\xe9\xf6\xf4\xe9\x49\x64\x62\x50\xa2\x09\xe6\x45\x51\xad\xa6\x5f\x1e\x03\x00\x00\xff\xff\x69\x36\x34\xfb\xf7\x02\x00\x00") + +func pkgUiStaticReactPrecacheManifest5b38a4fc0bde14c6f31f0e40057889e9JsBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactPrecacheManifest5b38a4fc0bde14c6f31f0e40057889e9Js, + "pkg/ui/static/react/precache-manifest.5b38a4fc0bde14c6f31f0e40057889e9.js", + ) +} + +func pkgUiStaticReactPrecacheManifest5b38a4fc0bde14c6f31f0e40057889e9Js() (*asset, error) { + bytes, err := pkgUiStaticReactPrecacheManifest5b38a4fc0bde14c6f31f0e40057889e9JsBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/precache-manifest.5b38a4fc0bde14c6f31f0e40057889e9.js", size: 759, mode: os.FileMode(436), modTime: time.Unix(1589211666, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactServiceWorkerJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x53\x61\x6f\xdb\x36\x10\xfd\xae\x5f\x71\x33\x86\xda\x4e\x1d\x32\x59\xd2\x2d\x69\xe0\x0d\x45\xb7\x75\x41\xb3\x22\xb5\x53\x18\x43\xe2\x06\x14\x79\x92\x38\x53\x3c\x8d\x47\xc5\x35\xda\xfe\xf7\x81\xb2\x9c\x6e\xdd\xfc\x4d\x22\xdf\xbd\xbb\x77\xef\x51\x1e\x1c\x64\x70\x00\x0b\x74\x9a\x6a\x84\x48\xb0\xa1\x36\xc0\x82\xc2\x2a\xa7\x0f\x87\x0d\xad\x31\xa0\x01\xc6\xf0\x60\x35\xc2\x9a\xc2\x0a\xc3\x37\x19\x74\x55\x7f\x50\x3b\x74\x0e\x3c\xa2\x49\x95\x01\x4b\xcb\x11\x03\xc4\xca\x32\x14\xd6\x21\x58\xbf\xe5\x5b\x63\x0e\xaa\x69\x40\x79\x93\x0e\x80\x2b\x6a\x9d\x49\x1c\xc6\xb2\xca\x1d\xc2\x6f\x37\x37\xd7\xa0\x95\xae\xac\x2f\xa1\xa0\x7f\x92\x44\x22\x91\xa0\x73\x44\xa8\x62\x6c\xf8\xb9\x94\x25\x91\x28\x9d\xf4\xd5\xdb\xea\x55\xd3\x8f\x73\x53\x21\x04\xe4\x08\x54\x40\xac\x10\x34\x19\x04\xcb\xa0\xda\x48\x87\x25\x7a\x0c\x2a\xa2\x11\x70\xed\x50\x31\x82\x21\x3f\x8c\xd0\x36\x46\x45\xfc\xd2\x6d\x3b\x53\x40\x1d\xdd\xe6\x02\xac\xe7\x88\xca\x4c\xa0\x56\x2b\x04\x5d\x29\x5f\x22\x7f\xbd\x25\xc8\x5b\xeb\x0c\x68\xf2\x85\x2d\xdb\xa0\xa2\x25\x9f\x68\x92\xd8\x80\x87\xa1\xed\x97\xb0\x85\x35\x81\x34\x32\xef\x53\xf4\x9d\x9a\xfd\xcc\x55\x06\x07\x32\xcb\x6c\xdd\x50\x88\x73\x1d\x6c\x13\x79\x34\xd8\x21\x39\x52\x50\x25\x8a\x92\xa8\x74\xa8\x1a\xcb\x42\x53\x2d\xd7\xbd\x67\xda\x78\x19\xb0\xd3\xc8\xf2\x54\x9c\x88\xe3\xc7\x2b\x5e\x8b\x3f\x79\x30\xbe\xf8\x9a\x3a\x03\x18\x08\xd9\x04\x4c\x06\xe0\x61\xad\xbc\x2d\x90\xa3\x78\x96\x9f\x9c\xa9\xd3\x42\x1f\xe5\x06\x8f\x4f\xf5\xf7\xc5\xc9\x71\x71\x84\xa7\x47\x47\xcf\x7e\x38\x3b\x3b\xc7\xf3\xc4\x96\x25\x3a\x46\x57\x08\x65\xcc\x2f\x0f\xe8\xe3\x55\x4a\x81\xc7\x30\x1a\xd6\xc8\xac\x4a\x1c\x4e\x60\x84\xe9\x66\x0c\xd3\x1f\xe1\x63\x06\x60\x8b\xfe\x44\x18\x15\x15\x3c\x79\x02\x5f\xfe\x44\xdc\x34\x08\xd3\xe9\x14\x86\xf3\xd7\x97\xd7\xf7\x8b\x17\x97\x37\x97\x6f\x5e\x0d\xc7\x5d\x25\x40\xd7\x8b\x57\xb6\x59\x28\x1b\xad\x2f\x47\xe3\x8b\x0c\xe0\x73\xf6\x39\x0d\xd2\x2b\x15\x9a\x02\x0a\xed\x2c\xfa\xc8\x2f\x9d\xb2\x75\x42\x65\x7d\xda\x53\x50\x7a\xe0\x7c\x21\x76\xb2\x5f\x78\x33\xa3\x36\xe2\x68\x0c\x35\xc6\x8a\x0c\x60\x51\x58\x9d\x28\xdc\xa6\x8b\x26\x72\xef\x29\x37\xe4\x4d\xca\x41\x62\x0b\xf8\x57\x8b\x1c\xb9\x4b\xed\xbb\xd9\x15\xa7\xd4\xa7\xfc\x3d\xae\x71\x8f\xd5\xf3\xf3\xb7\x33\x95\x77\x56\x77\x9a\xee\xef\x77\xa3\xfc\xde\x57\xc2\x14\x6e\x97\x42\x93\xd7\x2a\x8e\xf6\x61\x3e\x7d\x82\xdb\xe5\xf8\xe2\x51\x7a\x0f\xb0\xbe\xfc\xaf\xb4\x3d\x1c\x13\xf8\xf8\xaf\xed\x05\x6a\xd3\x66\xc5\xee\x45\xbf\x51\x0f\xb6\xec\x72\xbd\xa5\xf9\x9f\x56\x25\xc6\x97\x89\xf2\x35\x6e\x7e\xa5\xf0\x6e\x76\x35\x1a\x08\x69\xbd\xc1\x0f\xa2\x8a\xb5\x1b\x8c\x27\x9d\x7d\x19\x40\xee\x94\x5e\x39\xcb\xf1\x39\xdc\xca\xf7\x77\xf2\x5e\x4e\xe4\x9d\xbc\x7d\x7f\x27\x7f\x5a\x3e\xbd\x13\xe9\x63\xf9\xf4\x5b\xb9\x9c\x74\x8e\xfe\x1d\x00\x00\xff\xff\x20\xfd\x71\x4b\xa1\x04\x00\x00") + +func pkgUiStaticReactServiceWorkerJsBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactServiceWorkerJs, + "pkg/ui/static/react/service-worker.js", + ) +} + +func pkgUiStaticReactServiceWorkerJs() (*asset, error) { + bytes, err := pkgUiStaticReactServiceWorkerJsBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/service-worker.js", size: 1185, mode: os.FileMode(436), modTime: time.Unix(1589211666, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactStaticCss2Df42c974ChunkCss = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\xfd\xfb\x8f\xe3\x38\x92\x20\x8e\xff\xbe\xc0\xfd\x0f\xbe\x6a\x14\xba\x73\xda\x52\x4b\xb2\x65\x3b\x9d\xa8\xc6\xce\xce\xcd\xe2\x06\xe8\x1e\x2c\xb6\x77\x81\xfb\xa2\xaf\x0e\x90\x2d\xda\xd6\x94\x5e\x27\xc9\x95\xca\x31\x72\xff\xf6\x2f\xf8\x92\xf8\x08\x52\x94\xb3\xaa\x6f\x66\x3f\x3b\x3d\xa8\xb4\xc8\x60\x44\x30\x18\x64\x30\xf8\x08\xfa\x87\xaa\xea\xda\xae\x49\x6a\x2f\x4d\x3a\xd4\x65\x05\xaa\xb3\xe3\x27\xd4\x78\xcf\x59\x7a\x46\xdd\xc2\x3f\x74\xe5\xaf\x69\xd2\x25\x5e\x72\xec\xb2\xaa\xfc\x70\xcc\x51\xd2\x7c\xdc\x27\xa7\x0e\x35\xcb\xf9\xc5\x53\x74\x6c\x50\x81\xca\xee\x7f\x56\xd7\xa6\xfd\x02\x78\x7e\xce\xca\x6b\x87\xde\x80\x29\x2b\xbf\x0c\x47\x03\x9e\x37\x73\xd4\x5e\xaa\xe7\x37\x32\x83\x51\xbc\x99\x8f\xae\x4a\x93\x97\xb7\x14\x3f\x9f\x73\xf4\x2f\xa8\xc9\xaa\xd4\x1d\x0b\xfb\x6c\x9f\xb3\xee\x78\x71\x2d\xd5\x25\x87\x1c\x2d\xba\x8b\x5f\xa2\xbe\x9b\x5d\xa8\x6e\xd0\x67\x5e\xa8\x6d\xbc\xaa\xcc\x5f\x6e\x75\xd5\x66\xb8\x16\xfb\xe4\xd0\x56\xf9\xb5\x43\x4f\xcf\x59\xda\x5d\xf6\x61\xdd\x3f\x5d\x50\x76\xbe\x74\xe4\x67\x91\x34\xe7\xac\xdc\x7b\xf8\x77\x9d\xa4\x69\x56\x9e\xf7\xc1\x53\xf5\x19\x35\xa7\xbc\x7a\xde\x5f\xb2\x34\x45\xe5\xd3\x31\xcf\xea\x7d\x83\x8e\xdd\x77\xc1\x92\xfc\xf7\xf0\x74\xa8\x9a\x14\x35\xfb\xe0\x75\x8a\xcd\x5b\x9e\xb5\x9d\xd7\x76\x2f\x39\xda\x97\x55\x89\x26\x0b\xf8\x69\x53\xd5\x69\xf5\x5c\x7a\x05\x2a\xaf\xb7\x34\x6b\xeb\x3c\x79\xd9\x1f\xf2\xea\xf8\x89\xf3\x1b\xd5\xfd\x22\x18\x18\x5e\xd7\x3d\xaf\xdd\xba\x41\xc5\xeb\x3f\x16\x28\xcd\x92\xc5\x77\x45\x56\x7a\x34\x3d\xde\x6e\xea\xfe\xe1\x36\x8f\xb4\x2f\xe4\xb7\x87\xf6\x46\x51\xad\x76\xa8\x78\x05\x48\x6c\x37\xbb\xaf\x4d\xe2\xf1\x31\xfa\xb2\x24\xe6\x61\x72\xd4\x4b\xa5\xd0\x01\x9d\xaa\x06\xdd\x8e\x55\xd9\xa1\xb2\xdb\xbf\x7b\xf7\xc4\x5b\x34\x2b\xf3\xac\x44\x1e\x6d\x58\x4d\x5f\x67\x32\xe7\x1f\xaa\xae\xab\x0a\x4e\x8e\xaa\xa7\x97\xa3\x53\xb7\xdf\xd6\xfd\xa2\xad\xf2\x2c\x5d\x74\x4d\x52\xb6\x75\xd2\xa0\xb2\x63\x0a\xec\x35\xa4\x2b\x58\x41\x18\xe6\x11\xa6\x39\x1f\x12\xd6\x13\xfc\xe8\xe1\xa9\xab\xea\xbd\xb7\xad\xfb\x27\x4e\xed\x4e\xd6\x89\x78\x25\xce\x37\xd3\x9c\x5b\x41\x18\xe2\x11\xe6\x9b\xd3\xe9\x44\xf9\xdd\x70\x7e\x77\xf3\xf9\xc5\x08\xbe\x82\x9c\x31\x5a\xa3\x90\x59\x55\x46\x39\x6f\xee\xe3\xfb\xcb\x0b\x19\x63\x55\x24\xcc\x99\xdd\xbc\x41\x29\x4e\x79\x95\x74\x8c\x3e\x13\x36\x41\x95\x5c\xbb\xea\x69\x60\xeb\x2d\x58\xa9\x28\x54\xa4\x77\xb0\xfa\x9c\xa5\xa8\x61\x03\x4b\xb8\xc1\x23\xf0\xb4\x99\x24\x56\xe1\x5a\x12\xbb\x90\xde\xd8\xb0\x3e\x6d\x4d\x16\x89\x68\xa2\x3f\xde\xb8\x09\xc0\x0d\x30\xbb\xf4\x1e\xff\xfd\x8c\x95\xb8\xf7\xda\x4b\x92\x56\xcf\x6e\x16\x6a\x21\x8e\xa9\x97\xea\xea\x32\x2d\x10\x92\x0a\x32\xaf\x99\x57\xa6\x45\xc7\xaa\x4c\x99\x8c\x63\x6c\xf0\x4e\x55\xd9\x79\xcf\xd4\x92\x6f\x83\x80\x7e\xb7\xd9\x5f\xd1\x3e\xf4\x23\x54\x3c\xb9\x8b\xf4\x70\xed\xba\xaa\x34\xca\xd5\x41\x1c\x4e\x53\xd2\xd1\x04\xfc\x89\x67\x2f\x48\xfe\xbb\xb7\x50\x90\x27\x89\x10\x0d\x06\x71\x0f\x15\x70\xb2\x3f\xd2\xf8\x1f\xe8\xcd\xf5\x30\xb8\x01\x10\x8d\x37\xd4\x43\x9d\x90\x8f\xe8\x7f\xb9\x54\xcf\xf7\x73\xaf\xcf\xd2\x15\xcc\x6f\xe0\x19\x98\x7d\x8f\xc8\xff\x8d\x64\x2e\x7e\xff\xf3\x0f\xff\xf2\xf3\x3d\xc8\x45\x27\x70\xc4\xfa\x07\x9c\xba\xe8\x2e\x68\x41\x8b\xdf\xc7\xf6\xe8\x73\x08\xc2\xc0\xd3\xf5\x0b\x5a\x60\x24\x8b\xae\x5a\x10\x28\x17\xf4\x92\x37\x71\xeb\x50\xdf\x79\x49\x9e\x9d\xcb\xfd\x11\x95\x1d\x6a\xe6\x62\x30\xc8\xf1\x7f\x60\xb6\x92\x32\x5d\xfc\x5b\x56\xa0\xc5\x2f\xc7\x06\xa1\xd2\xa9\xd1\x24\xe4\x8b\x2e\xbd\x8d\x3e\x04\x1f\x7f\xb8\xb7\x41\x4c\x0c\x1d\xbf\xc8\x4f\x32\xf7\x63\x79\x59\x79\x41\x4d\xd6\xdd\x41\x70\xd1\xd6\x49\x79\x13\x71\x45\x7e\xfc\x34\xfe\x44\x05\xf7\x0c\x82\xe0\xfd\x34\x7e\xe2\x52\xdd\xc6\x12\x33\x46\x51\xe6\x8d\xa5\xee\x7e\x9b\xde\x9c\xc3\xac\x23\x49\xb3\x6b\xbb\xf7\xa3\xd8\xc9\x98\x0e\x08\x79\xbd\x03\x3c\xef\x10\x65\x12\x0c\x1e\x12\xfe\xe9\x8e\x51\xd1\x3f\xee\x64\xc5\xb3\x70\xa4\x59\x8b\x7f\xce\x90\xcc\x50\x64\x7f\xc1\xae\xe8\xed\x90\x1c\x3f\x9d\x9b\xea\x5a\xa6\xc4\x40\x3f\x1d\xab\xbc\x6a\xf6\xdf\x6c\x8e\xdb\x78\x9b\x3e\x1d\xaf\x4d\x5b\x35\xfb\xb2\xc2\xc2\xcc\xab\x67\x94\xce\xa9\xe0\xe0\x3b\x8f\xbd\xe2\x5f\x1a\xf4\x39\xab\xae\xed\xe2\xe7\xaa\xec\x2e\x0e\xfd\x00\x70\xdf\x47\x6c\x7f\x46\x7d\x37\x1b\x13\x4a\xf0\x5c\x73\x7f\xca\x9a\xb6\xf3\x8e\x97\x2c\x4f\x71\xfb\xb2\x9a\xd6\x55\xe6\xd6\xf9\xad\xd8\x74\xd9\x7e\x83\x1e\xd1\x11\x9d\xdc\x75\x9d\x2b\x1c\x99\x90\x88\x0a\x17\x8f\x2e\x39\xfe\xe9\x8e\xd1\x3f\x3e\xdf\xc6\x99\x8c\xbf\x43\xc5\x93\x55\xa9\x25\x4d\x98\x41\x26\x4d\x5e\xbe\x78\x6f\x21\x58\xa9\x54\x9d\x55\x3d\xf5\xf1\xfc\x71\x76\x21\x3a\x85\x9c\x5d\x8c\xce\x22\x8d\x0d\xff\x74\xa7\x7e\xa5\x7e\x89\x9e\x67\xb0\x51\xe5\xe9\xed\xde\x86\x23\x96\x73\x5c\xdd\x6a\x50\x9e\xe0\x39\xfc\x5c\x0c\xae\xcb\x12\x6c\x40\xa6\xdc\xca\x2e\xa9\xe8\x0b\x2e\xbe\x09\x82\xed\x81\x78\x7e\x04\x9e\x2e\x77\x11\x8f\x90\x27\x51\x85\x0a\x16\xc1\x02\xfb\xb8\xd8\x8d\xd5\x97\xe8\x98\xdf\x88\x3b\x0f\x75\xc6\xe6\xf5\x1d\xea\xce\xcc\x68\x08\x5a\x40\xd3\x07\x56\x5d\x5e\x27\xf6\x45\x96\x0e\xb0\xc5\x62\xae\x52\xb0\xf0\x42\xec\x75\xc9\x9e\x7a\xfc\x30\x9b\x61\xb9\x45\xa4\xa5\x0b\x6f\xa4\x3d\xa7\x1b\xce\x35\x38\xe9\x6f\x66\x70\xd8\x84\x05\xd4\x35\xc1\xb9\xb3\x8e\xab\xc2\x1a\x68\xe8\xc7\x78\x10\x94\xba\xed\xdb\x26\x11\x94\xc1\x2f\x60\x1b\x08\x1e\x9f\x7b\xd8\xbf\xb9\x6e\x51\xf2\x6f\x18\x69\x28\x82\xf9\xaa\x24\x97\xfb\x5a\xfa\xe4\x5f\x5b\xd4\x3d\xa3\xb2\x7b\x39\x55\xd7\x86\xdb\x91\xc1\xa4\x6d\x55\x93\x46\x56\x75\xb2\xb2\xbe\x76\x1e\xe6\xa3\x5e\x50\xa7\x85\x3a\x59\x1f\x64\x12\x1f\xd5\x79\xc6\x7f\xfb\x87\x7f\xf8\xe1\x77\xff\xfd\x1f\x16\xbf\x5b\xfc\x13\xe7\x6a\xf1\x79\xed\xaf\xfd\x70\xf1\xdd\xa5\xeb\xea\x76\xff\xc3\x0f\x67\xd4\x0d\x2c\xfb\xc7\xaa\xf8\xe1\x01\xc3\xff\xa1\xaa\x5f\xc8\x48\xb6\x88\x82\x30\xf4\xa2\x20\x7c\x5c\xfc\xdb\x05\x09\x78\x7e\x7f\xed\x2e\x55\xd3\x1a\x81\x9f\xb3\xae\x43\xcd\x72\xf1\xa7\xf2\xe8\x63\xa0\x9f\xb2\x23\x2a\x5b\x94\x2e\xae\x65\x8a\x9a\xc5\xcf\x7f\xfa\x37\x81\x87\xac\xbb\x5c\x0f\x84\x7a\xf7\x7c\x68\x7f\x18\x18\xfa\xe1\x90\x57\x87\x1f\x8a\xa4\xed\x50\xf3\xc3\x4f\x7f\xfa\xc3\x1f\xff\xfc\xcb\x1f\x31\x7f\x3f\xec\x9b\xaa\xea\x6e\x9e\x77\xc8\xaf\x68\xd0\x49\xcf\xcb\xca\x34\x3b\x57\xfb\x6f\x36\x9b\x30\x38\x45\x4f\x9e\x57\x5f\x9b\x3a\x47\xfb\x6f\x36\xa7\x75\x74\x0c\x71\x42\x56\x7e\xda\x7f\x83\x76\x2b\xb4\x3b\x3e\x79\x5e\x83\xd2\xfd\x37\xe9\x71\x15\xaf\xe3\x27\xcf\xab\x9a\xa4\x3c\xa3\xfd\x37\xa7\x74\x8b\xc2\xf5\x93\xe7\xbd\x20\xdc\xac\x58\xcd\x8f\x61\xb0\x7d\xf2\xbc\x33\xf6\xb0\xf6\xdf\x44\xbb\x64\x4b\x4a\x74\x28\xc9\xf7\xdf\x44\xc1\xf1\xf1\x11\x67\x1f\x5f\x92\x72\xff\x4d\xb8\x4d\xa2\xc3\xee\xc9\xf3\x9e\x2f\x59\x87\x68\x27\xc1\x45\x93\x97\x41\x73\xe8\xa7\x97\x26\xcd\xa7\xfd\x37\xab\xf5\x2a\x59\x07\x98\xb9\x26\x2b\x92\xe6\x45\xa8\x10\x35\xfc\x24\x6d\x28\xd9\x5e\x8f\x47\xd4\xb6\x02\x17\x59\x79\xaa\x44\xb2\x49\x53\x62\x5f\x6e\x64\x3b\xc5\xf5\x6a\x84\x9a\xe6\x44\xbb\xbe\x39\xed\x4e\x8f\xa7\x84\x00\x48\x8c\x1c\x1a\x94\x7c\x22\x5a\xe4\xf5\xed\x5e\x49\x69\x0b\xba\x2d\x23\xa7\x16\x29\xdd\x49\x91\x53\xf3\x33\xdd\xfc\x50\x70\xe6\xfb\x30\x0a\x02\x92\x4c\x26\x8d\xa7\xa4\xc8\xf2\x17\xaf\x4d\xca\xd6\x6b\x51\x93\x9d\xf6\x5e\x52\xd7\x39\xf2\xda\x97\xb6\x43\xc5\xf2\x9f\xf2\xac\xfc\xf4\x73\x72\xfc\x85\x7c\xfe\x73\x55\x76\xcb\x77\xbf\xa0\x73\x85\x16\xff\xfe\xa7\x77\xcb\x7f\xad\x0e\x55\x57\x2d\xdf\xfd\x4f\x94\x7f\x46\x5d\x76\x4c\x16\x7f\x46\x57\xf4\x6e\xf9\xfb\x26\x4b\xf2\xe5\xbb\x3f\x57\x5d\xb5\xf8\x25\x29\xdb\x77\xcb\x91\xc0\xf2\xdd\xef\x31\x81\xc5\x1f\x70\x87\x5e\xfc\xb1\xa8\xfe\x92\xbd\x1b\x71\xea\x09\xbf\xbc\x14\x87\x2a\x7f\xc7\xb0\x89\xa5\x94\x3a\x14\x55\x59\xb5\x75\x72\x44\xfb\x5f\xfe\xf9\xe7\xaa\xac\xbc\x7f\x45\xe7\x6b\x9e\x34\xcb\x9f\x51\x99\x57\xcb\x9f\xab\x32\x39\x56\xcb\x3f\x54\x65\x5b\xe5\x49\xbb\x7c\xf7\x53\x76\x40\x4d\x82\xa7\x13\xd8\xd7\xa8\xde\x2d\xdf\xfd\xa1\xba\x36\x19\x6a\x16\x7f\x46\xcf\xef\x96\x03\xba\xd7\xdf\x2d\xd9\x3e\xce\x68\x70\x7b\x3c\xdb\xc6\x2d\x3d\xd8\xde\xfe\xf5\xd2\x15\xf9\x4d\x60\x68\x3f\xd6\x59\x1a\x59\x42\x3f\x8c\x9f\xbc\x67\x74\xf8\x94\x75\x1e\x1d\xc2\xb3\xbf\x22\x2f\x49\xff\x72\x6d\x3b\xea\x43\x0f\xb9\x49\xed\x5d\xb2\xf3\x85\x28\x0d\xb3\x03\xc2\x1c\xea\x35\x69\xba\xec\x98\xa3\x65\xd2\x66\x29\x5a\x9e\xb2\xf3\x31\xa9\x71\x85\xf0\xcf\x6b\x83\x96\xa7\xaa\xc2\x7c\x63\x6f\x06\xff\x21\xe3\xd8\xb2\x48\xb2\x72\x59\x26\x9f\x97\x2d\x22\x0b\x30\xf2\x7e\xe1\xeb\xa1\x4a\x5f\x86\xd5\xe5\x27\xb1\x3e\x7f\x47\x9a\x21\x2c\xed\x36\xa8\x90\x56\x7e\xd7\x41\xa0\x34\x47\xcc\x8d\x4b\x14\x46\x71\xf4\xf8\x24\x2c\x32\xe4\xe8\xd4\x3d\xe9\xa6\x18\x4f\xae\x7e\xed\x92\x43\x56\xa6\xa8\xff\xf0\xce\x0b\xdf\x7d\xdc\x9f\xaa\xe3\xb5\xc5\x16\xe9\x3b\xfa\xd3\xfb\x9c\xb5\xd9\x21\x47\x0f\xb7\xea\xda\x61\x82\xfb\xe0\xbf\x67\x45\x5d\x35\x5d\x52\x76\xaf\x97\x46\xd4\xa2\xac\xcc\xba\x2c\xc9\xf9\x24\x46\xd8\x4e\x66\x48\x5e\x2f\xe1\xf2\x12\x2d\x2f\xab\xe5\x65\xbd\xbc\xc4\xcb\xcb\x86\x35\x11\xd9\x4b\xe1\x4b\x47\x7c\xf7\xca\x27\xf3\x97\xda\x06\x82\xc5\xf2\x9a\x1c\x0e\x0d\xb5\x6a\x55\x93\x9d\xb3\x32\xc9\xbd\x2e\xeb\x72\xf4\x71\x49\x72\xe8\x6f\xba\xe6\x92\xa2\x63\x45\x3b\xcb\x9e\x98\x11\x5c\x21\x59\x89\x21\x88\x45\x5a\x75\x1d\x4a\x9f\x26\x01\x98\xf9\xbc\xa0\xbc\x56\x76\xe2\x02\x13\x15\xaf\xfd\x94\xd5\x1e\x36\x2a\x64\x7e\x60\xcd\x7d\x4d\xd2\xb4\x41\x6d\xcb\x1c\x65\xb6\xb3\xde\x14\x49\x0e\x2e\xaa\x31\xe8\x65\x9a\x2f\xab\x7c\x79\xcd\x6f\x80\xec\xd4\x3c\x22\xe4\xd7\x2a\x5f\x54\x38\x63\x71\xc5\x79\x0b\x02\xb1\xd0\x10\x04\xaf\x69\x77\x53\x76\x23\x5e\xd3\xf4\x06\xb4\x22\x6f\x36\xb2\xe7\x14\xbc\x92\x2e\xfa\x7f\xaf\x55\x87\x86\x2e\xba\x08\x16\x84\xa1\xc3\xb2\xed\x9a\xaa\x3c\x4b\x88\x0f\x55\x9e\xa2\xe6\xb5\x2d\x92\x3c\x17\x56\x09\x76\xc1\xfb\xd7\xf6\x7a\x58\xb6\xd7\x5a\x77\x0c\x85\xce\xb3\x8d\xdf\x4b\x02\x0a\x9e\x3e\x23\x3c\xe4\x24\x39\xeb\x1f\x4c\x71\x31\xb2\x1b\xdf\xc2\xf3\xa3\x18\x15\xaf\x18\x35\xd9\x36\xf5\xf1\x57\x72\x93\x27\xb1\xaa\x42\x90\x26\xd4\xfa\x19\xc7\x9e\xb0\x39\xe1\x80\x23\xde\x1c\x56\x66\xa5\x7a\x4d\x48\x37\xfc\xf5\xd2\xa0\xd3\xc7\x87\xa5\xf4\x25\x61\x62\xed\x0d\x72\xf3\x7a\xac\x52\xb4\xfc\x74\x48\x97\x75\x83\x96\x6d\x52\xd4\xd2\xd8\xfe\x65\x4d\x8c\x38\x5e\xe1\x9e\xdb\xa0\xa9\xbe\x3b\x8e\x10\xc9\xb5\xab\x5e\xe9\x78\xaf\xe9\x44\x56\x9c\x6f\x92\x7f\x4d\x6a\x96\x15\xe7\x65\xfb\xf9\x7c\x53\xda\xb2\xc8\xd2\x34\x47\xaf\x38\x47\x39\xcd\xf2\x4a\x17\x79\x47\xcf\x3e\x4f\xea\x16\xed\xf9\x8f\x57\x66\x75\xf8\x52\x36\x61\xda\xdf\x12\xf5\xe5\x49\x5c\xa7\x69\xaa\x3c\x99\x57\xc7\x5b\x86\xce\xc3\x46\x6d\x4f\x0b\xbe\xca\x6b\xbf\xbc\xa3\xe6\xc9\x01\xe5\xb0\x6b\x08\x8d\x88\x74\xdb\xee\x26\x7b\x7b\x01\x4b\xa6\xa3\xf6\x30\x58\x63\x67\x8a\x0d\x4e\x3c\x29\xae\xfb\x05\x96\xf6\x82\x8f\x48\x74\x9c\x6f\x70\xfd\x48\x8d\x18\xa6\x25\xf1\x1a\x96\x55\xdd\x51\x83\xdb\xa2\x1c\x1d\xbb\x25\xe6\x3f\x69\x50\x02\x1b\x57\xae\x8b\xa3\x26\xf0\x14\x68\x84\x12\x09\xdd\x34\x63\xc1\x72\x29\x5d\x2a\x37\x32\x6b\x38\x55\x4d\x41\x55\x80\x65\x3d\x57\x4d\xea\x3d\x37\x49\xcd\x46\xc3\xd7\x5f\xbb\x97\x1a\x7d\xa0\xe5\x3f\x2e\xe9\x57\x83\x5a\xd4\xf1\x8f\xf6\x7a\x28\xb2\xee\xe3\x92\x89\x92\x4b\x22\xa9\x6b\x94\x34\x49\x79\x44\x7b\x9a\x23\x63\xa2\x66\x91\x7b\x78\x0f\x12\x62\x38\x8f\xd1\x51\x33\x59\x53\xc9\xa9\xaa\xf3\x25\x93\xde\x7b\x45\xf5\x57\xd6\x54\x59\x59\xa2\x46\xa6\x6e\xca\xe6\x0c\xe8\xf9\x8c\x07\x2d\x43\xd8\xc9\x01\xfa\x1c\x6e\x29\x8a\xf9\x78\x41\xc7\x4f\x87\xaa\xff\xb8\x14\x12\xb1\x32\x56\x1f\xe1\x99\xe5\x78\xcc\x4c\x44\x83\x3d\x50\x09\x05\x77\x49\xbd\xbc\x3a\x26\xb9\x94\x55\x54\x65\x77\x91\x52\x30\xe0\x47\xa8\xf9\xf2\xac\xed\xf0\x6c\x76\xd0\x56\x69\xa0\x79\x6a\x10\xd1\x4d\x3e\x74\xbc\x9e\x32\x94\xa7\x2d\xea\x6e\xe3\x99\xab\xe0\x09\xd8\xd2\x1a\x0e\xbf\xe5\xe8\x8c\xca\x54\x39\xa3\x26\x6d\x1f\xf5\x9e\xf0\xa9\xa2\x92\x8d\xa3\xb8\x83\x4f\x12\x80\xbe\xf2\x24\x8f\xf5\xc4\x33\xf4\xa8\x9f\xc0\x94\xbe\x6e\xaa\x33\x99\x1d\x18\x8c\x1b\x95\x58\x79\x2d\x0e\xa8\xc1\x0a\xc1\x84\x46\x1a\xdd\x6b\x6b\xcc\x14\xed\x70\x06\xc0\xea\xda\xc9\x80\x37\x61\x83\x8f\x61\x6f\x51\xd2\x1c\x2f\x1f\xf9\xf0\xe3\x55\xa7\x53\x8b\xba\xbd\x47\x3c\x38\xbd\x95\x88\x4e\x49\x25\x47\x72\x34\x41\xb0\x67\x50\x33\x13\x04\x63\x99\x53\x96\x23\xef\x5a\xe7\x55\x92\x72\x1e\xb1\x6c\x07\xa9\x99\xfb\x79\x75\xed\xf0\x18\x04\x8d\xc1\xaf\xed\xb5\xc0\x5e\xf5\x90\x49\x4e\xb0\x64\x1d\x36\x00\x72\x8f\xed\x50\x51\xe7\x49\x87\x06\x48\x5a\x3f\x6a\x7d\x3e\x4a\xa9\xc2\x1c\xda\xbf\x84\x4b\xff\x12\x2d\xfd\xcb\x6a\xe9\x5f\xd6\x4b\xff\x12\x2f\xfd\xcb\x66\x69\x9c\x2b\xeb\xba\xc3\xa6\x49\xb1\xe6\x13\x44\x04\xfb\x25\x14\x26\x4d\x11\x35\x22\x98\xe2\x25\x12\xd3\x69\xea\x6a\x79\x59\xdd\x44\x85\xdc\x32\xf0\xf5\xf2\xb2\xbe\xa9\x9a\xfa\x8a\x99\xbd\xc4\x52\x3a\x5b\x76\xc4\x35\xd8\xdc\x64\x0f\xe6\xd5\xcf\x51\x92\xea\xd0\x52\x2d\x56\x41\xf0\xea\x33\x59\x79\x22\xe7\xf4\x80\xd1\x90\xb3\x1c\x7e\x46\x37\xa5\xbc\x2e\x05\x05\x94\xe0\x8b\x59\x15\x78\x9e\x58\xef\xb5\x9a\x37\x52\x5b\xbb\x53\x13\x05\xb6\xa2\x18\x2f\x8d\x38\x27\x0a\x85\xb9\xb1\x38\x2d\xe2\xe3\x8c\x78\xd4\x2c\x04\x4f\xc8\x85\x0f\xaf\x3e\x99\x17\x2f\x81\xd9\xb1\xea\x31\xbe\xfa\x45\xd2\x7c\x5a\xe2\x7f\x86\x61\x9e\x9c\x19\x02\x7c\xc3\xe3\x69\x87\x56\xaf\xf4\xb8\x16\xed\x0e\x4b\xe5\xec\x16\x9f\x14\xd1\x49\xfd\x93\x76\xdc\x57\x28\x4a\xba\x0b\xdc\xbb\x34\x30\x6a\x16\xf3\x84\xef\x58\x3e\x70\x81\xd1\x9d\x11\xd6\x30\x6c\x54\xcb\xda\x42\xa8\xf2\x63\xf0\xfe\x49\x99\x27\x5c\xeb\x1a\x35\xc7\xa4\x45\xaf\xbe\xe6\x75\x48\x22\x07\x54\x78\x2c\xe0\xd1\x25\x08\x65\xbc\x97\x65\xad\x2e\x37\xab\x85\xb5\x9d\xa7\xff\x1d\x05\xe1\xfa\x7f\x07\xc1\xef\x83\x77\xaf\x7e\x56\x9c\xbd\x53\x7e\xcd\xd2\x25\xf9\xd9\x5d\xae\xc5\xa1\x4c\x32\xec\x73\x49\x96\x44\x1c\x73\x15\xc8\xb1\x45\x49\x9f\x02\xfd\x7d\xae\x59\xa3\x32\x7d\x93\x22\x14\xa1\x8d\x61\xf3\x80\xcd\xc8\xe1\x96\xa3\x99\x1e\x9e\x9e\x43\x43\x93\xd4\x2d\x06\x68\x3e\xcb\x96\x5b\x4d\x16\x1e\x76\x5a\x44\x4d\xde\xfa\xf1\x00\xc2\x96\x5e\xc7\x39\x1f\x59\x17\xf4\xf0\xf7\x6b\xf2\x23\x29\x29\x99\xca\xd7\x4f\x87\x54\x10\x4d\x83\x8a\x85\xbf\x96\x1b\x5c\xc2\x4f\x84\xa4\x89\x8e\xad\xa9\xa8\x42\xc2\x32\xfa\x74\x48\x17\x22\x0d\xe9\x44\x5e\xa0\x74\x42\xec\x22\xd7\x82\x40\x35\x45\x12\x59\xa1\x44\x31\xfc\x42\x91\x88\x61\x52\x80\x65\x42\xc4\xc1\xe7\x04\x7e\xdd\x20\xaf\x3d\x36\xd8\xc5\xc1\xbe\x0f\x56\x26\xd6\x22\xab\x75\x50\xf7\x83\xff\xe5\xbd\xec\x29\xd8\xab\x8f\xf5\x33\xc9\xca\xf1\x60\xa7\x30\x81\x61\x7d\x30\x8c\xc7\x5b\x03\xb4\xfb\x93\x14\xa9\x9f\x92\x79\x96\xe8\xf6\x13\x95\x35\x9f\xd0\x1f\xc9\x8e\x1a\x1f\x63\x1e\x6d\x67\xee\xa1\x42\xdb\xc8\x50\x88\x9f\xa2\x87\x0a\x3d\x6e\x0c\x85\xe8\x3a\xb3\xa1\x54\x18\x52\x06\xc7\x4c\xde\x87\xc7\x84\xfc\x2c\x7e\x15\x52\x5e\x5b\x88\x5f\x7d\xfe\xff\x48\xe2\x32\x4b\x77\xc9\xdf\x56\xc7\xbb\xda\xc6\x5d\x84\xf7\xb5\xe2\xdd\x4d\x04\xb4\x7e\x53\x3d\x0f\x1d\xfa\x94\xa3\xfe\x09\xff\x43\x07\x27\xfc\x8f\xdc\x4a\x9e\xd8\x70\xa4\x99\x48\xca\xab\x5f\x56\xde\xf9\xda\x75\xa8\x69\x65\x83\x17\x28\x8b\x67\x02\xe0\x8f\xfe\xb1\xca\x97\x62\xc2\xaf\xc7\x3c\x69\xdb\xdf\x7d\x38\x56\xb9\x37\x1c\xe6\x1d\x10\xc9\x16\xfb\x95\x96\xc6\xa0\x21\xfd\x13\xd1\x3f\x2b\xfa\x67\x4d\xff\xc4\xf4\xcf\x86\xfe\xd9\xd2\x3f\x3b\xfa\xe7\x91\x15\x0f\xd8\x5f\x86\x27\x64\x88\xb0\x02\xd2\x5f\x54\xc4\xf8\x2f\xa7\x95\x9f\x39\xb9\xfc\xcc\x29\xe6\x67\x4e\x34\x3f\x73\xba\xf9\x99\x93\xce\xcf\x9c\x7a\x7e\xe6\x0c\xe4\x67\xce\x03\xc6\x1c\x8c\x3f\x47\x2a\xe1\x48\x66\xe4\x87\x36\x32\xfe\xcb\xf9\x29\x52\xce\x4f\x91\x72\x7e\x8a\x94\xf3\x53\xa4\x9c\x9f\x22\xe5\xfc\x14\x29\xe7\xa7\x48\x39\x3f\x45\xca\xf9\xc1\x98\x83\xf1\xe7\x48\x25\x1c\xc9\x8c\xfc\x50\x35\xc3\x7f\x39\x3f\x6d\xc1\xf9\x69\x0b\xce\x4f\x5b\x70\x7e\xda\x82\xf3\xd3\x16\x9c\x9f\xb6\xe0\xfc\xb4\x05\xe7\xa7\x2d\x38\x3f\x18\x73\x30\xfe\x1c\xa9\x84\x23\x99\x91\x9f\x3e\xe7\x7f\x39\x3f\xfd\xa0\x1e\xfd\xa0\x21\xfd\xa0\x24\xfd\xa0\x27\xfd\xa0\x2a\xfd\xa0\x2d\xfd\xa0\x30\xfd\xa0\x33\xfd\xa8\x36\xfd\xa8\x39\xfd\xa8\x3c\x3d\xd5\x1f\x60\x65\x77\xe6\x28\x49\xf4\xfc\x46\xfa\xe4\x21\x69\xb3\x16\x5b\x68\xfc\x71\x6e\xaa\xe7\x7d\xa8\xb8\xea\xa4\x37\x63\xab\xdf\x7a\xe1\x8f\xbf\x23\xa5\xe8\x42\xa4\xee\xd5\x0b\xa0\x91\x08\x1a\x4b\x90\xb1\x04\xb8\x12\x01\x57\x2b\x7f\x45\xfe\x27\xc2\x8f\x89\x42\xb1\xb5\x58\x2c\x8a\x45\xf8\x28\x16\x01\x63\x09\x50\x62\x24\x92\x18\xd9\x48\x95\xdb\xf8\x1b\xfc\xbf\xad\x54\xc5\x21\xf1\x75\xe8\xcc\x63\x11\xf5\x54\xaf\x2a\x1a\x32\x0c\x8c\xe0\x3b\xa0\xa6\xbb\xb1\xa2\x64\xf0\x99\xc9\xcf\xca\x2a\x11\x32\x80\xcd\x10\x35\x19\xe9\x46\xf8\x75\x08\x70\x30\x26\x52\xf8\x8d\xb5\xcd\xc9\x68\x29\x40\x40\x22\x88\x15\x19\xec\x46\xf8\x0d\x24\x83\x8d\x22\x83\xc7\x11\x7e\x2b\xc9\x60\xcb\x65\x10\x06\x42\x23\x40\x42\xd8\x29\x42\x08\x85\x56\x7b\x84\xa4\xf0\xa8\x48\x21\x8c\x26\x7a\x09\x9d\x33\x93\x33\xa8\x37\xea\x7d\x78\x21\x4f\xc5\x6e\x1e\x4b\x0c\x57\x3c\x31\xb8\x0d\x77\x4c\x69\x42\xc8\x41\x78\x42\xc4\x12\x22\x9e\xb0\x62\x09\x03\x8e\x35\x4b\x58\xf3\x84\x98\x25\xc4\x3c\x61\xc3\x12\x36\x3c\x61\xcb\x12\xb6\x3c\x61\xc7\x12\x76\x3c\xe1\x91\x25\x3c\x0e\x8c\x71\x56\xc3\x91\xd7\x81\xd9\x81\xdb\x90\xb3\x1b\x62\x7e\xc9\x92\x98\x17\xde\x44\xab\x2e\xa8\x01\xcb\x8f\xa4\x7c\x51\xf7\x19\xc0\x4a\x02\x20\x3a\xcf\x72\xd6\x52\x8e\xa8\xe4\x0c\x20\x96\x00\x44\xad\x66\x00\x1b\x09\x80\x68\x33\xcb\xd9\xca\x39\x3a\xdf\x3b\x09\x60\xa3\xf3\xfd\x28\x01\x6c\x05\xbe\xc3\x40\x96\x89\xce\x78\x28\x4b\x4d\xd0\x44\xdb\x2c\x17\x9b\xb6\x3b\x86\x7f\x6c\x1a\xdd\x2d\x00\x36\xd7\xae\x46\x00\x1b\xf4\xfb\xec\x00\x9e\x00\xb8\x9a\x02\x3c\x45\x70\xb5\x06\x78\x12\x31\xdb\x20\xb0\x09\xc3\x3c\x9b\x80\xa5\x3a\xcb\x2c\x60\xc1\xce\x67\x6c\xda\x38\x60\x51\xce\xb4\x0f\x58\xa2\x33\x4d\x04\x16\xec\xa4\x95\xc0\x13\xb7\x99\x86\x02\xcf\xf0\x66\xda\x0a\x3c\x15\x9c\x34\x17\x64\x96\x38\xd3\x62\x90\xe9\xe4\x4c\xa3\x41\xe6\x9d\x4e\x76\xa3\x2d\x0c\xa6\xa3\x2d\x60\xeb\xd1\x16\xba\x01\x21\x5a\xa7\xd8\x10\xa2\x58\x8a\x19\x21\x9a\xa3\x58\x12\xa2\x28\x8a\x31\x21\x9a\xa0\xd8\x13\xd2\xd4\x8a\x49\x21\x2d\xab\x58\x15\xd2\x74\x8a\x61\x21\x6d\xa3\xd8\x16\xda\x14\xaa\x79\xa1\xc2\x56\x2d\x0c\x15\xa7\x66\x64\x88\x28\x14\xef\x71\xcc\x9a\x32\x41\x44\x40\x13\x56\x88\x08\xcc\x64\x88\x88\xe4\x26\x6c\x11\x91\xe4\x84\x39\x22\x92\x35\x59\x24\x22\xe2\x09\xa3\x44\x44\x3e\x61\x97\x48\x13\x98\x4c\x13\x6d\x8b\x09\xeb\x44\x9b\xc6\x60\xa0\xac\x8b\x28\xd8\x19\xbc\xc3\x42\x61\x67\xd2\xdd\x42\x61\x07\xd7\xd5\x42\x61\x17\xf8\x3e\x0b\x85\x5d\x66\x57\x0b\x85\x9d\x6a\x57\x0b\x85\xdd\xee\xd9\x16\x8a\xb9\xd8\xf3\x2c\x14\x96\xea\x2c\x0b\x85\x05\x3b\x9f\xb1\x69\x0b\x85\x45\x39\xd3\x42\x61\x89\xce\xb4\x50\x58\xb0\x93\x16\xaa\x48\x67\x5b\xa8\x22\x9d\x6d\xa1\x8a\xd4\xc1\x42\x91\x75\x95\x99\x16\x8a\x2c\xc0\xcc\xb4\x50\x64\xa5\xc6\xc9\x42\x15\xa9\xc1\x42\x15\x29\x6c\xa1\x8a\x54\xb7\x50\x44\xeb\x14\x0b\x45\x14\x4b\xb1\x50\x44\x73\x14\x0b\x45\x14\x45\xb1\x50\x44\x13\x14\x0b\x45\x9a\x5a\xb1\x50\xa4\x65\x15\x0b\x45\x9a\x4e\xb1\x50\xa4\x6d\x14\x0b\x45\x9b\x42\xb5\x50\x54\xd8\xaa\x85\xa2\xe2\xd4\x2c\x14\x11\x05\x6c\xa1\x88\x44\xec\x16\x8a\x08\x68\xc2\x42\x11\x81\x99\x2c\x14\x91\xdc\x84\x85\x22\x92\x9c\xb0\x50\x44\xb2\x26\x0b\x45\x44\x3c\x61\xa1\x88\xc8\x27\x2c\x14\x69\x02\x93\x85\xa2\x6d\x31\x61\xa1\x68\xd3\xb8\x5b\xa8\x71\x55\x3e\xf7\xf2\xf3\x1d\x16\x2a\x3f\xcf\xb1\x50\xf9\xd9\xdd\x42\xe5\xe7\x7b\x2d\x54\x7e\x76\xb7\x50\xf9\xd9\xdd\x42\xe5\xe7\x3b\x2c\x14\x5b\x94\x9e\x67\xa1\xb0\x54\x67\x59\x28\x2c\xd8\xf9\x8c\x4d\x5b\x28\x2c\xca\x99\x16\x0a\x4b\x74\xa6\x85\xc2\x82\x9d\xb4\x50\xf9\x79\xb6\x85\xca\xcf\xb3\x2d\x54\x7e\x76\xb0\x50\x64\x27\x62\xa6\x85\x22\x5b\x16\x33\x2d\x14\xd9\xdb\x70\xb2\x50\xf9\xd9\xb4\xfc\x76\x86\x2d\x54\x7e\xd6\x2d\x14\xd1\x3a\xc5\x42\x11\xc5\x52\x2c\x14\xd1\x1c\xc5\x42\x11\x45\x51\x2c\x14\xd1\x04\xc5\x42\x91\xa6\x56\x2c\x14\x69\x59\xc5\x42\x91\xa6\x53\x2c\x14\x69\x1b\xc5\x42\xd1\xa6\x50\x2d\x14\x15\xb6\x6a\xa1\xa8\x38\x35\x0b\x45\x44\x01\x5b\x28\x22\x11\xbb\x85\x22\x02\x9a\xb0\x50\x44\x60\x26\x0b\x45\x24\x37\x61\xa1\x88\x24\x27\x2c\x14\x91\xac\xc9\x42\x11\x11\x4f\x58\x28\x22\xf2\x09\x0b\x45\x9a\xc0\x64\xa1\x68\x5b\x4c\x58\x28\xda\x34\xee\x16\x4a\xd8\xd8\xcd\xbd\xfe\x9e\x5d\x9e\x3e\x9f\x63\xa2\xfa\xdc\xdd\x44\xf5\xf9\xbd\x26\xaa\xcf\xdd\x4d\x54\x9f\xbb\x9b\xa8\x3e\xbf\xc3\x44\xf5\xf7\x6c\xfd\xf4\x73\x77\x7f\xfa\xf9\x1b\x40\xbd\xcb\x1e\x50\x3f\x7f\x1b\xa8\x9f\xbf\x13\xd4\xbb\x6c\x06\xf5\xf3\xf7\x83\xfa\xf9\x5b\x42\xbd\xcb\xae\x50\x7f\xc7\xc6\x50\x7f\xc7\xde\x50\xef\xbc\x3d\xd4\xe7\x06\x13\xd5\xe7\xb0\x89\xea\x73\xdd\x44\x11\xad\x53\x4c\x14\x51\x2c\xc5\x44\x11\xcd\x51\x4c\x14\x51\x14\xc5\x44\x11\x4d\x50\x4c\x14\x69\x6a\xc5\x44\x91\x96\x55\x4c\x14\x69\x3a\xc5\x44\x91\xb6\x51\x4c\x14\x6d\x0a\xd5\x44\x51\x61\xab\x26\x8a\x8a\x53\x33\x51\x44\x14\xb0\x89\x22\x12\xb1\x9b\x28\x22\xa0\x09\x13\x45\x04\x66\x32\x51\x44\x72\x13\x26\x8a\x48\x72\xc2\x44\x11\xc9\x9a\x4c\x14\x11\xf1\x84\x89\x22\x22\x9f\x30\x51\xa4\x09\x4c\x26\x8a\xb6\xc5\x84\x89\xa2\x4d\x63\x32\x51\xbe\x21\x92\x94\x74\xd6\x54\x3e\xdf\xe7\x8f\x11\xa4\x86\x80\x4e\xc3\x81\x45\x7a\xd3\x48\x39\xd2\xdf\x55\x35\x7c\x32\x98\x1d\xe6\x1c\x50\xd2\x00\x40\x17\xf5\x4a\x00\xe5\x45\xb9\xa2\x18\x19\xb1\x1c\xaa\xf4\xe5\x7b\xf2\xef\x4d\xa0\x6a\x82\xf7\xda\x62\xac\x0b\xf9\x10\xaa\xb3\x22\xa7\x4a\x69\x16\xc5\x85\x06\x50\xfe\x2d\x94\x1e\x93\x2e\x37\xd3\xc9\x55\x15\x1d\xaf\x35\x84\x84\x89\x43\x0e\x35\xc2\x2c\x46\xdd\xcb\x98\x72\xd4\xb6\x62\xdd\x97\x40\x6e\x0a\x25\x5e\xc0\x44\x89\x34\xee\xa1\x4c\x3e\x5d\x93\xd5\x98\x37\x4c\x62\xd1\x35\xfb\xb2\xbb\x78\xd5\xc9\xeb\x5e\x6a\xf4\x5d\x95\xa6\x0f\x7a\x08\x0d\xf1\xf8\x77\x10\x3f\x70\x4c\xe4\x4a\xe0\x88\x47\xba\x6b\xc8\x8f\xaf\x5a\x51\x6d\x47\x5c\x2c\x90\xc0\x52\xfe\xfc\x71\xac\xef\x90\x72\x01\x42\x7c\x1c\x76\x69\x72\x3a\x29\xb8\x20\x51\x0e\x59\x2a\x5e\x41\x88\x63\x8a\xdc\x78\x8c\xd6\x36\x39\x08\xb4\xa8\x0c\xe4\x92\x3c\x58\xd2\x14\x84\x50\x3b\x1b\x10\x54\xe1\xc7\xd3\x31\x1d\x99\x18\x62\x2e\x2c\xd5\x04\x81\x84\x90\x06\x61\x4c\x37\xe9\x2e\x3d\x68\x18\x21\x21\x0a\x99\x3a\x76\x41\x90\x62\x1a\x28\xca\xc3\xea\xb0\x3d\x1c\x40\x51\x8e\x61\x24\xcc\xc2\x54\x60\x4c\xe2\xd4\xc0\xa0\xea\x1f\x77\xc7\xc3\x71\x14\x28\x0d\x58\xb1\x94\x3f\x45\x61\xf2\x14\x10\xd7\x0a\x6d\x8e\x07\x05\x17\x28\x48\x9e\xa5\xe2\x15\x85\x38\xa4\x80\x22\xdc\x9d\xd2\xf0\x11\xc1\x22\x64\x51\x37\x2c\x02\x14\x21\x8c\xe2\x93\x81\xc0\xee\x17\xa6\xa7\xb1\x1d\xb3\xf2\x54\x2d\x85\xdf\x02\x62\xfa\x09\xa2\x40\x28\x46\x12\x0a\x48\x60\x34\x3d\x95\x3f\x2f\xca\x27\x2c\xa7\xcd\xf1\x94\x26\xa0\x9c\x48\x2c\x12\xb3\x90\xc6\x6c\x93\x84\x44\x08\xa8\x6e\xc9\x21\x4d\x51\xcc\x69\xb3\x58\x27\x4b\xf9\x53\xc0\x3d\xa4\x40\xb8\x4e\x27\x84\x0e\x89\x82\x0b\x12\xd5\x90\xa5\xe2\x15\x04\x36\xa6\x80\x32\x3b\x9d\xd2\xd3\x16\xd6\x2d\x1e\xb0\xc5\x2c\x36\x09\xc2\x24\x39\x05\xc8\x50\xe1\x5d\x12\x72\x26\x68\x58\x98\xa5\xf4\x25\x20\xe7\x09\x20\xa2\xf8\x28\xf4\x4a\x0a\x09\x09\x8e\xe7\xa4\x6a\xc2\x45\x4b\x00\xa5\x86\xd2\xc7\x8d\xa1\x47\xb2\xa0\x36\x66\xa1\x89\x00\x26\x99\xc9\x30\x60\x4d\xc3\x43\x70\xd8\x72\x0e\x48\x0c\x94\xa5\xf8\x21\x60\x66\xdf\x20\x96\xf4\x94\x9e\x90\x84\x05\x12\x17\xcb\x48\x95\xef\x8b\xfa\x0d\x6b\xd8\xe1\x74\x3c\x1d\x41\x59\xd1\x78\x3f\x66\x51\x09\xf9\x26\x49\x49\x20\x50\x15\xd1\x11\x1d\x4f\x9b\x51\x25\x9a\x4f\x4b\xe1\xb7\xa4\x57\xf8\x13\x1c\xeb\x37\xc7\xdd\x31\x11\x51\xc0\x3a\x85\xd3\x53\xf9\xf3\xa2\x7c\x82\x12\x7a\x8c\x1f\x1f\x1f\x61\x09\x91\x08\x48\x36\x5d\xe2\xd9\x66\x4d\x1a\x21\xc0\x31\xf9\xf1\x70\x38\x0c\x1a\xc0\x43\xfe\x89\x5f\x02\x66\x9e\x70\x01\x49\x89\xe1\xff\x26\x01\x4c\xfc\xca\x30\x00\xc7\x86\xc9\xe5\xc2\x27\xc2\xe5\x72\xbe\x59\xef\x5d\xb1\x88\x52\x72\x2b\xac\xe3\x75\x1a\xc7\x0a\x3a\xae\xd9\x1c\xdf\xfa\x31\x0e\xe2\x2d\x80\x92\x85\xbc\x94\x51\xca\xae\x04\x66\xcd\x85\xaf\xd7\x37\x2b\x94\x54\x15\x02\xa9\x38\x2d\x9a\xc3\x20\xc0\xdc\xe1\x3b\x5c\xda\x9c\xb4\xc9\xfb\x25\xf6\x4d\x25\xff\x41\x40\x6c\x73\x25\x40\x79\x68\x68\x71\x73\x0f\xab\xb5\xe3\xf2\xd6\x36\xf6\x1f\xe9\xa1\x17\x4a\xa8\x41\x6d\x5d\x95\x6d\xf6\x19\x3b\x8a\xe6\xdb\xf4\xc3\x2d\xb5\x9e\xae\x38\x0e\x57\xd2\x79\x3a\xbd\xbb\x86\x6d\x57\x57\x5d\x8f\x97\x57\x08\xfd\x8f\x46\xc9\x02\x9c\x6e\x37\x5b\x23\xa7\x85\xe5\xde\xff\x17\xe0\xb4\x48\x67\x71\xfa\xf8\x18\x1a\x39\xcd\xcf\x5f\x95\xd3\xfc\x3c\x8b\xd3\x30\x7c\x7c\x34\xb2\xda\xe7\x5f\x95\xd5\x3e\xb7\xb0\xaa\x81\x7f\x4d\x56\xcc\x7c\xf8\xa7\xaa\x29\xbc\x63\x55\x76\x4d\x65\x91\x06\xbb\xbf\x79\x4c\xf2\xe3\x77\xa1\x1f\xa3\x62\xf1\xfd\x82\x2e\x13\x2d\xbe\x5f\x44\x75\xff\xf0\x34\xae\xb6\xd0\x64\xb6\x88\x74\x5f\x34\x31\xe3\x38\xaa\x0e\x04\x79\x56\xef\xc7\x38\x39\x3d\x70\xd3\xf8\x88\xd2\x75\x9a\x80\x37\x8d\x9f\xc8\x8d\x6d\x7a\xcf\x47\x1c\x21\x17\x7e\x18\xb7\x0b\x94\xb4\x78\x5e\xef\x55\xd7\x6e\x39\xbe\xd9\xa1\xe5\x0d\x3a\x57\x37\xe8\x84\x9a\xd6\x6b\x50\x7a\x3d\xa2\xd4\x2b\x2a\x76\x81\x08\x7f\x3e\xdc\x64\x41\x0b\x94\xc9\xbd\x75\xb9\x1d\xf6\x7b\xaf\x68\x3d\xd4\xd7\x49\x99\xea\xc3\x29\x8f\x78\x06\xb7\xa1\x10\x5b\xa5\xc9\xca\xf3\x4d\x8b\x7c\xa7\x84\x3e\xc5\xff\x31\x79\x2b\x88\x68\x50\x1f\xa7\x16\x91\xfd\xac\xe0\x90\x9e\x4e\x43\xe8\x1f\x6c\x48\x7b\x99\x1e\xbd\x11\xcd\x4c\x75\x18\xad\x96\x51\x1c\xb3\x88\xab\x8a\x18\x86\x78\x21\xf5\xb5\xf3\xea\x3c\x39\xa2\x0b\x09\xcb\x25\xc7\x59\x7d\xaa\xea\xe4\x98\x75\x2f\xe4\xc6\xb7\x26\xc7\xbb\x0b\xcf\x2f\x32\x06\x70\x15\x93\x7f\x6d\x50\x92\x56\x65\xfe\xf2\x11\x9a\x80\xd2\x99\xc1\x88\x91\xc6\x17\x02\x9a\x82\xd6\xe6\x73\x92\x5f\x91\x4b\xab\xc8\xac\x91\x30\x25\x32\x5b\x1e\x09\x1c\x6a\xec\xf3\x74\x33\x85\x14\xa0\xb1\xa2\xc4\x10\x55\x64\x20\xe0\x5d\xfd\xfb\x45\x28\x8c\x00\x7c\x69\x17\x02\x51\x62\xb9\x4d\x44\x6c\x0a\xfd\x58\x65\x02\x5b\x17\x9d\x8f\x49\x2e\x44\x00\x3d\x10\xc8\x14\xcd\xb6\x00\x68\x46\x93\x44\x23\x98\xaa\xbf\xdb\xc2\x54\xa5\xb6\xa9\xf3\x24\x2b\x71\x4f\x35\x8f\xc9\xea\x88\xab\xc6\xf9\x09\xd4\xc1\xd7\x1e\xba\x71\x6a\x9c\x31\x3e\x49\xc5\x58\xa2\x6f\x22\xc1\x95\x90\x93\xf3\xf3\xd2\x09\x4e\x90\xbb\xe9\x32\xb1\x0a\x0f\xda\x29\xd0\x4c\xd1\xd6\x51\x63\x21\x19\x1a\x07\x8c\xc1\xa0\x56\x0a\x24\x1e\x42\xb4\x09\x69\x38\x00\xc8\x14\x65\xb2\x97\x01\x0c\x11\xbf\x16\xd7\xbc\xcb\xea\x1c\x7d\x5c\x42\xb9\x98\xc4\xc7\x21\x8c\x9a\x6c\x8b\xa4\xe8\x1e\x24\x87\xc4\x5e\x83\x22\x37\xd2\x6c\x40\x2d\x85\xf0\x32\x43\x14\x0f\x0c\x3a\xef\x96\xba\x76\x49\x9d\x5c\xa4\xe5\x88\xd8\xc5\xf3\xe1\xd3\x76\xed\x5c\xbb\x93\x3b\x62\x22\x31\xc4\x80\x0b\xbe\x72\x85\xe4\x0b\xbd\x52\x9d\x08\x02\x6a\x55\x80\x87\x2f\x45\x49\xac\xd4\x28\x94\x9e\x11\xd3\x60\x3a\xfe\x43\xcc\x22\xe3\xcf\x52\x03\xfe\x95\x03\x7f\xd4\xa1\xd5\x08\xe4\x5a\xbe\x1a\x4f\x53\xc6\x8e\xd5\x4f\x8d\xbc\x42\x1a\x8e\x6c\xe2\x91\x58\x39\x2d\x7f\x3f\x46\x89\xc5\x23\x47\xcc\xd9\x02\xf5\x24\x61\x4b\x2d\x42\x6c\xbb\xa4\xcb\x8e\x4f\x50\xfc\x46\x86\x75\x15\x46\x40\x68\x4f\xff\x73\x92\x67\xa9\x77\x42\x28\xc5\xa3\x98\x14\xf4\xea\x49\xdf\x15\x1d\xb5\x14\x8e\xa6\x43\x43\x54\x73\xac\x5d\x55\xe1\x9e\x05\x34\x35\xd9\x06\xc5\x78\xff\xea\x91\x68\xb6\xfb\xf8\x49\xa2\x6c\x88\xc7\x26\x0d\x3d\x22\x4b\xa1\xdb\x58\x64\xf3\x89\xc9\x9c\x6a\x1d\x2c\xc3\xcd\x76\xb9\x79\x5c\xfa\x8f\x0f\x86\x18\x3b\x19\x99\x49\x64\xe9\x7f\x28\xb2\x5b\x6a\x39\xac\xfe\x4b\xff\x39\x61\x39\x49\x87\xd2\xc5\xde\x50\xdc\x06\xc5\x45\x29\x47\x4d\x96\x46\xa3\x81\xbc\x8a\x49\x9e\x10\x91\x74\x65\x59\x83\x45\x16\x97\x07\x02\xc0\x63\x79\x10\xc5\x96\x15\xc9\x19\xed\xaf\x4d\xfe\xdd\xbb\x34\xe9\x92\x3d\xf9\xfe\xa1\xfd\x7c\xfe\xbe\x2f\xf2\xa7\xe3\x25\x69\x5a\xd4\x7d\xb8\x76\x27\x6f\xb7\x7c\xbf\xfa\x43\xfb\xf9\xbc\xe8\x8b\xbc\x6c\x3f\x7c\x7b\xe9\xba\x7a\xff\xc3\x0f\xcf\xcf\xcf\xfe\xf3\xca\xaf\x9a\xf3\x0f\x51\x10\x04\xb8\xe8\xb7\x0b\xd2\xea\x1f\xbe\xdd\x7d\xbb\xa0\xed\x86\x7f\xbe\x5f\xfd\xf1\xfd\xea\x0f\x75\xd2\x5d\x16\xa7\x2c\xcf\x3f\x7c\xfb\x3e\x5a\x51\x96\xbf\x5d\xa4\x1f\xbe\xfd\x39\xf2\x57\x8b\x8d\xbf\x5d\xfd\xe4\x6f\x16\x6b\x3f\x5e\x1d\x3d\x7f\xed\x85\x7e\xb0\xf6\xd7\x1b\x2f\xf4\xd7\x8b\xd0\x0f\x3d\x7f\x97\x87\x7e\xb8\xc0\x9f\x2b\x7f\xed\xad\xfc\xdd\xd1\xdf\x78\xfe\x66\xb5\x08\xf1\xdf\x68\xbb\x08\xfd\xc8\xdf\xe6\xde\x7a\xb1\xf6\x37\x18\xc5\xca\x8f\x3d\x7f\x47\x50\x85\x7e\xf8\xd7\x6f\x7f\xa0\x7c\x60\x3e\xdf\xaf\xfe\xf8\x4e\x12\x46\x83\x6a\x94\x74\xfb\xb2\x62\xbf\xc4\xbc\x71\xc0\x24\x6b\x5e\xc3\xec\x8e\x0a\x36\xa4\xba\xfa\xb0\xe0\x4f\x4b\x8d\x05\x89\x2e\x53\x70\x0e\xbd\xe2\xc0\x50\xaa\x41\x1f\xe8\x1c\xd8\x41\x2b\x98\xdf\x02\xea\x86\xcd\x13\x11\x7a\x0d\xf1\x44\x64\x42\xa0\xe9\xa4\x04\x61\xb3\x3a\x30\x7e\x9b\xa7\x90\x83\x9c\xbb\xaa\x36\x4a\xd9\xda\x06\xaf\xfe\xf1\xda\x76\x55\xe1\xb1\x89\x80\xb1\x47\x49\x60\x33\xbb\x14\x6f\xb5\x88\x0f\xc9\x62\x25\xbe\x56\x7f\x5a\x8f\xfd\x29\x06\xfb\x13\x5d\x21\x65\xfd\x69\x11\xfc\x14\x2c\xa2\xcb\xfa\xaf\x45\xb0\x88\x7f\x0a\x16\xab\xcb\x5a\x57\xff\xc5\xa0\xec\x4c\xa8\x6c\x55\x83\xea\xf1\x0f\xbb\xba\x5f\x84\x41\xdd\x2f\xff\x3f\x3c\x42\x90\x57\x66\x05\x39\x51\xd1\x30\x71\xb1\x58\x8d\x3f\xcc\xea\xe0\xb0\x7e\x1a\x7a\x38\xa0\xa5\x5f\xaa\x8b\xab\x33\x11\xc1\xf6\xe9\x93\x30\x70\xe0\x11\x26\x70\x86\x82\x37\x65\x52\x61\xa1\xa9\x9a\xd2\x49\x50\x83\x69\x36\xf2\x66\xb7\xd5\x13\xc5\x0c\xc6\x9b\x35\x0f\x77\x83\x54\x46\x95\x6c\x58\x96\x10\x8e\xbd\x05\x81\x2a\xd3\x3b\x78\x60\x81\x11\xdf\xcc\x8a\xf2\x90\xd4\x1c\xc6\xf6\x44\xd4\xe8\x8b\x31\xe8\x84\x4f\x61\x74\xb5\x3e\x22\x70\x01\x89\x66\x4c\xd5\x80\xf4\xc3\x2f\xc6\xff\x34\xb6\xdb\x9c\xde\xed\xc0\x3a\x0d\xfb\xc9\xe4\xf6\x30\x51\x11\x96\x49\xe2\xfd\x1a\x54\x8c\xe4\xcd\xd5\xf1\x3b\x58\x81\x71\x8f\x9c\xed\x4d\x6c\xd9\xf5\x14\xa8\x9a\xd2\x28\xd3\x15\x54\x99\x30\x22\x78\xfb\xf0\x9d\x95\x5f\xd6\xef\xa3\x0f\x0d\x8d\x78\xff\xfe\x3c\xbf\x28\x0a\x96\xf1\x6a\xd2\xf3\x63\x15\xfc\x0f\x4d\x82\x4b\x30\xd7\xe4\x01\x5a\xd0\x4c\x41\x3a\x7a\x82\x0c\xdc\x3e\xeb\x67\x40\x8a\x3e\xb1\x57\xa3\xfe\x86\xbc\xc1\x30\x1a\x27\x7b\xf8\x37\x9d\xe3\x61\x7d\xf9\x76\xd1\x76\x4d\xf5\x09\x91\x19\x1f\x65\x9c\x4d\x06\x8f\x59\x73\xcc\xd1\xe2\xd8\x7f\xf8\x76\xf3\xed\xe2\xf8\x42\xfe\x34\x1f\xbe\x5d\xfb\x31\x9f\xa7\x91\xf9\x22\x2d\xef\x61\x85\xf9\x4b\x95\x95\x1f\xbe\x25\xf5\xa1\xd3\xc6\xd8\xdf\x2d\x56\xfe\xe6\xe2\xaf\x7f\xda\x2c\x36\x7e\x3c\xcc\xf0\x74\xe4\x3b\x3f\x22\xe8\xfd\xcd\xb7\xe3\x14\x94\x31\x34\xf0\x48\x38\xfe\x3b\x74\x23\x99\x9e\xb8\x38\x92\x12\x28\xac\x58\xb6\x81\x4a\xe8\x86\xce\xae\x24\x57\x75\xa3\x33\xc9\xd5\xfc\x6f\xc0\x9d\x34\x75\x4b\x79\xaa\x3e\xb7\x5f\xfe\x97\x4b\xf9\x5f\xc3\xcc\xd4\x30\xf3\x1b\xf8\xa2\xf6\x61\x02\x54\xf1\x2f\x35\x4e\x40\x0e\xdf\x60\x3a\xe7\x7b\xa4\xc6\xa2\x37\x65\xc2\x63\xa5\xab\x1b\x77\x27\x70\x67\xdf\xd4\x79\x16\xe1\x50\x74\xa6\x8f\x3a\x94\xbf\xdf\x4b\xb5\xa2\x50\xe5\x7c\x17\x1f\xb3\x1c\x29\x17\x4c\xa0\x9e\x4e\x32\xf7\x05\xbd\xd5\x39\x18\xd5\x93\xd5\xeb\x4d\xb0\x49\xa1\x03\x96\x24\x63\xba\x16\x5f\xca\x63\x75\xc7\x67\xf5\x59\xd5\x11\xc0\x89\xfd\xb7\x7b\xad\xaa\x9a\xcc\xf5\x5b\xef\x67\x67\xd2\x69\x34\xb3\x66\xd7\x5b\xb0\x82\x6f\xf1\x5e\xa7\x50\x7c\xa1\xe1\x5e\xd9\x72\x1d\x37\xc9\xc9\xc3\x51\x4d\xf5\xbc\x20\x1b\xe5\xfa\xf6\xab\x54\x5e\x1c\x1c\x85\x7b\xa0\x96\x10\xa5\x62\x61\x5a\x9f\xbf\x5c\xdb\x2e\x3b\xbd\x78\xfc\xad\x10\x33\x19\xfa\x36\x1b\x80\x42\xaa\x05\xb0\x63\x0c\xef\x3d\xeb\xb8\x95\x7b\xff\xba\x3c\xc0\xca\x2b\x87\x18\x81\xe7\xce\x09\x36\xf8\xed\x3e\x33\x42\xe0\x2c\x8e\xf2\x24\x89\x58\x52\x9a\x20\xc8\x32\x12\x9f\xc4\xbe\x8d\x0c\x99\x1b\x72\x4a\x9c\x70\x8b\x89\x75\x05\xcf\xcb\x4c\x6f\xc4\x8f\xef\x59\x62\xc9\xb7\x97\x26\x2b\x3f\x8d\x7b\xf1\xd0\xc6\x3c\xb8\x2d\x0f\x09\x86\xb7\x92\x73\x75\xac\x68\x0c\x67\x1a\x5e\xfd\x43\x67\x78\xf7\x5e\x3d\x81\x6a\x7c\xbf\x96\x31\x05\x6a\x8b\xfa\x08\x3e\x3f\xa7\x78\x6d\x51\xc3\xe7\x86\x64\x21\x88\x1c\xc6\x04\x52\x5b\x3d\x51\x4b\x98\x3a\x90\x35\x1e\x72\x15\x0f\x65\xb9\x9d\xc3\x9d\x3a\xdf\xa4\x1e\x8f\x35\x9d\x8b\x55\x58\x84\x4e\xce\x7e\xed\x73\xb5\xb8\xa5\xf5\xe3\xb4\x87\xae\x04\x6f\x23\x83\xef\x95\x62\x68\x9f\xcd\xf7\x71\x41\xf9\x39\xcb\x79\x07\x58\x31\x2a\xe1\x1d\xff\xae\x1c\x4e\xf6\xdc\xf8\x19\x4f\x7f\x13\xbf\x26\x32\x20\x7f\x0b\x70\x00\x5e\x10\x80\x1b\x53\x30\x0f\x7d\x46\x65\xd7\x8e\xdc\xf2\x0b\xc2\xf6\x0b\x23\xec\xc5\x58\xd9\x50\xd1\x44\x09\x8b\x50\xf7\xe1\xe6\x31\x90\x34\x7d\x25\xe3\x9b\x20\xd8\x3c\xa6\x8f\x1a\xc5\x4d\x74\x3c\xba\x51\xb4\xce\x96\x56\xbb\x65\xb8\x66\xc2\x66\xb2\x1e\x10\x4a\x32\x1f\x70\x0e\xb2\xff\x22\x72\x52\x1e\xcf\x24\x9f\x03\xe1\x07\x9f\x5f\x8f\x72\x2e\xb1\xe7\x25\xda\x4b\xf5\xfc\xa3\x5c\x9d\xa6\xaa\xd3\xea\x19\x0f\xb6\xe7\x73\x8e\x26\xa5\x1e\x1d\x8f\x1a\xff\xf1\xf1\x70\x07\xff\x50\xcb\xbb\xd4\x82\x97\x9b\xac\xcb\x9d\x0d\x3d\xdc\xe1\xb6\xcb\x82\x9d\xd0\x96\x65\x31\xbc\x8f\x26\xe2\x11\x75\x70\xbc\x20\x0e\x26\x3a\x68\x7e\x9c\x6c\xa2\xcd\x4e\xa1\x1b\xaf\xe3\xc3\x26\x72\xa7\x6b\x15\x4a\xb8\x0a\x96\x21\x91\x0c\x24\x15\xa5\x03\x8c\x88\xdd\xba\x80\xbb\xd8\x66\x74\x02\xc7\x32\x40\x37\x10\xaa\x35\xa7\x23\x50\x79\xab\x37\xf7\x50\x1c\xc7\x87\x7b\x6a\x01\x2b\xc3\x7d\x9d\xc1\x58\xa3\xbb\x5b\x9e\x5e\xca\xb7\x0b\x64\xd8\x55\x83\x76\xfd\x04\x2c\x92\x4e\xb2\xdb\xfe\x40\x92\x43\x3f\x88\xc2\xdd\x6e\xa5\xf6\x83\x10\x6d\xd1\x6a\xed\x46\xd1\x2a\x89\x6d\xb4\x0c\x77\xc1\xf2\x71\xab\xc9\x41\xd5\x7f\x86\xd2\x4d\xfb\x5d\xc5\x34\x47\xf7\x5d\x4a\x40\x9a\xcf\xab\x33\x47\xef\xa9\x7c\x55\xa1\x1f\xb7\xeb\x55\x30\x9f\x7f\xa8\xe1\xef\xd4\x79\xb8\x2e\xf7\xb5\x73\x56\x9e\xaa\x09\x29\x6c\x93\xe8\xa0\xa9\x1e\x49\x1c\x51\x88\x7a\x47\xa2\x36\xa8\xdf\x0e\x3a\x1e\xae\x76\xeb\xc7\x8d\x4a\x28\xdc\x26\xbb\xc3\x14\x21\x6b\xad\xe3\xdd\x32\xdc\x6e\x96\xe1\x63\x2c\x57\x5b\xd1\x6d\x82\xcd\x4d\xb1\x9d\x44\x32\x43\xab\xa7\xc1\x01\x95\xa6\x55\x98\xa5\xcf\x44\x96\x2a\xdb\xc1\x36\xd8\x9e\x66\xb2\xad\x35\xef\x7d\x9a\x0c\x55\xe1\xce\x06\x65\x01\x2f\xa6\xa2\x24\x7d\x73\x3a\x1d\xc3\x60\xfb\xa4\xc6\xe3\xc0\x89\x12\x22\x51\xcf\x78\x30\x0d\x20\xc9\x29\x34\xd3\x37\x28\x48\x76\x81\x7a\xf5\x3d\x5d\x3d\xa2\x20\x70\x23\x3a\xb1\xda\x19\x2d\xc3\x2d\xf6\x98\x34\x71\x28\x2a\xce\x71\xaa\x5a\xfe\x66\x69\xcd\xd0\x75\xa7\x12\x80\xba\x0f\x35\x82\x35\xde\x58\x05\x2a\x66\xa5\x0a\xc7\xcd\x63\xac\xc8\x7e\xb6\xde\xcf\xa9\x88\xae\xfa\x86\xea\xdc\xd9\xdc\x34\x74\x89\xbd\xf7\x0f\x4b\xa9\xd0\x72\xef\x88\x44\xd4\x41\x16\x11\x45\x4f\x71\x18\xcd\x8f\xbb\x68\xb5\x5a\x29\xe4\x0e\x69\x14\x72\xe3\x69\x27\x37\x21\x82\x78\xb9\x5b\x49\x76\x8c\x61\x93\xf5\x9d\x21\x74\x1b\xd4\x1d\xe5\x33\x43\xd5\x5d\x0a\x00\x9a\xce\xab\x32\x67\x68\xa7\x82\x55\xa5\x1d\x85\xa7\x28\x9d\xcd\x3c\xd0\xde\xf7\xe9\x38\x5c\x91\xfb\xda\x97\xc4\x04\x99\x1e\xaf\x76\xa7\xc7\x53\xa2\x8e\x57\x24\x51\x40\x23\xea\x1c\x0d\x65\xa3\x25\x38\x8e\xeb\x11\xda\x20\x95\x5c\x9a\xa0\x00\xc5\xd3\xe4\xec\x12\x08\x37\xcb\x28\xdc\x2e\xa3\xf0\x51\x91\x81\xa2\xe2\x14\xa1\xfb\x80\xee\x24\xa0\x19\x3a\xee\x00\x0f\xa8\x38\xab\xc9\xdc\xa1\x9c\x48\x56\x33\xa3\xe9\x63\x7a\x9a\xcb\xbc\xde\xe2\xf7\xa9\x38\x58\x91\x7b\xdb\xd7\x35\x56\xcd\x93\x7a\xda\x98\x06\xb0\xe1\x28\xe4\x21\xb5\xf9\xb4\x57\xbf\x5d\xfc\xcd\x55\xb4\x8d\xb4\xa9\x62\x1a\x85\xd1\x7a\x8a\x90\xb5\xde\xbb\x68\xb9\xdb\x2d\x1f\x57\x72\xa5\xb5\x61\xbb\xf9\xe4\x38\x68\x3b\x09\x64\xd6\x90\x3d\x05\x0e\x0e\xd8\xb8\x0a\xb3\x66\xe2\x44\x92\x9a\x03\x11\x26\x61\x3a\x93\x6d\xad\x71\xef\x1d\xaa\xf5\x2a\xdc\xd5\x9c\x6c\x79\x5f\x5d\x49\x9f\x5c\x0b\x56\xca\xb9\xad\x8a\xcf\xc3\x29\xaa\xab\x4a\x6e\xba\xaa\xc2\x8e\x84\xa1\xae\x8a\x16\xab\x24\x54\x85\xe6\xec\x1b\xf6\xa3\x60\xb1\xb8\x6b\xf2\xac\x92\x80\x52\x6b\x95\x9b\xb7\x74\x3e\xb3\xb9\xe7\xaa\xfa\x3d\xb5\xd3\xb5\x7e\xa2\x8e\x6f\xd3\x0a\x6d\x65\x7d\x72\x31\x58\x2b\xe9\xd2\x0b\xe6\x63\x85\xfa\xc1\xac\x15\xf3\x60\xb7\x0c\xc3\xed\x32\x8c\x6c\xb5\x36\xf4\x06\xf3\x0a\x3a\xaf\x88\x53\x7f\xb8\x67\xdd\x7c\x66\x59\x4b\x9f\xb8\x73\x1d\xfd\x0e\x05\xb8\xb7\x5f\xbc\x75\x5d\x7d\xb2\xa6\x6f\xd6\x13\x79\x9d\x7d\x72\xa9\x58\x29\xe7\x34\x87\x99\x89\x13\xec\x17\xce\x6b\xe8\xc2\x35\x1a\x43\x5d\x4d\x3d\xc2\xb0\xa6\xce\xd9\x77\xeb\x0f\xb3\x57\xd2\x67\x95\xb4\xf5\x85\x7b\x56\xd6\x67\x37\xf7\xdd\xfd\xe0\x4d\x2b\xed\x13\x75\x7c\x9b\x56\x88\x2b\xef\x93\x0b\xca\x62\x21\xa7\xb5\xf4\x39\x08\x21\xc5\x77\x5c\x5b\x8f\x56\xcb\x70\x13\x2d\xc3\xdd\x1a\xae\xa0\x41\xe7\xc1\xb5\x76\xce\xb3\x93\xc2\xcf\x5c\x61\x77\x2f\x66\x51\xf5\x3b\x56\xdc\x67\xb5\xeb\xbd\x4a\xfe\x86\x15\x78\x5b\xd5\xde\xd8\xfc\xca\x8a\xfc\xe4\x52\xb2\x52\xce\x71\x09\x66\x2e\x5a\x48\xd7\x67\x2c\xb5\xc7\xf1\x32\x7c\x5c\x2d\xb7\xc6\xea\x1a\x14\xde\xb4\xf2\xce\xd9\x77\xd2\xf9\xf9\x8b\xed\xb3\x4a\x5a\x34\xff\xde\xc5\xf7\xd9\x8d\x7e\x6f\x17\x78\xdb\x62\xfc\x44\x35\xdf\xa6\x18\xf2\xda\xfc\xe4\x2a\xb3\x5c\xcc\x65\xac\x9f\x89\x12\xea\x01\x33\x56\xde\x87\xc3\xd6\x70\x3d\x0d\xfa\x6f\x58\x89\xe7\xac\x3b\xa9\xff\xec\xf5\xf7\x39\x05\x2d\xca\x7f\xcf\x7a\xfc\xdc\x66\xbe\x57\xef\xdf\xb4\x3e\x6f\xaf\xe0\xdb\xb4\x41\x5a\xaf\x9f\x5c\x75\x96\x4a\xb9\x8e\xfc\xb3\x90\x42\x5a\xef\xbc\x18\xbf\xde\x2d\xa3\xf5\xe3\x32\x8a\x03\x43\x45\x0d\x5a\x0f\x2f\xce\x73\xc6\x9d\x94\x7e\xee\x7a\xfc\x8c\x72\x16\x95\xbf\x6f\x7d\x7e\x66\x33\xdf\xab\xf3\x6f\x59\xaf\xb7\x56\xf0\xad\xaa\x20\xae\xdf\x4f\x2e\x4c\x8b\x85\x5c\x46\xf9\x59\x08\xe1\x31\xde\x69\x85\x3e\x8e\x96\xf1\x6e\xb9\x01\x26\x74\xc0\x4a\xbd\x84\x5b\xd5\x73\xce\xb1\xe3\xe0\x3e\x6b\x9d\xde\xbd\x98\x75\x60\x9f\xbb\x6e\x3f\xaf\x55\xef\x1f\xd4\xef\x5e\xc7\xb7\x55\xed\xae\xc6\xcf\xb3\xf2\xd3\xcd\x70\xbb\x83\xad\xf2\x1a\x0f\xff\x93\xc2\xb2\x6e\x07\x41\xbc\x39\xac\xb4\x22\xd7\x32\x45\x0d\x66\x7c\x2c\x27\xef\x9a\x96\x5c\x75\x8d\x25\xc5\xeb\x04\x32\x07\xda\x8e\x69\xa9\xeb\x2a\x5b\x9a\x33\x5e\x0c\x20\xb7\x8b\x48\x94\xfc\x43\x57\x32\x3c\xe7\xdb\x17\x0b\x3d\x2b\xd0\x68\x0b\x81\xc6\x18\xab\xf7\x8b\x84\xd6\xc5\x28\xc9\x7d\x1d\x4b\x78\xea\x01\xe6\x7b\x01\x5c\x8c\xaa\x42\xe2\x9d\xd0\x80\xa9\xdd\x4b\x8d\x3e\x1c\xae\x5d\x57\x95\x1f\x47\xe8\xa5\x90\xd9\xa0\x16\x75\x86\xbc\xf6\x7a\x28\x32\x31\x53\xbc\x62\xe7\x9f\x92\x14\x89\x37\x50\xd8\x35\x0f\x7a\xa3\x05\xd7\x36\x69\xdc\x83\xc4\x2b\xb8\x78\x70\xf8\x24\x45\xb4\x63\xe1\x0e\xf4\x30\xdc\x24\x09\x48\xac\xea\x3c\xa9\x5b\x29\x5b\x8c\x45\x33\x40\x60\x0f\x57\xbf\xe0\xc5\x1a\x22\x18\x1e\x19\xd8\x5f\xb2\x34\x45\xa5\x78\xf9\x87\xc2\x2c\xfc\x15\xbb\xa1\xe3\x5c\x1b\x81\xb2\x5e\x27\xde\xe7\x97\xe4\x57\x8e\x4e\x1d\xfd\xd5\xd0\xc7\x8a\xf0\xcf\x6b\xad\x73\xfc\xaa\x8d\x83\xcf\x97\xac\x43\x5e\x5b\x27\x47\x2c\x04\x7a\x3b\x50\x1d\x50\x92\x53\x87\x1a\xf8\x42\x98\x78\x67\xcd\x8f\xe2\x58\x7f\xf9\x92\xa5\xf2\x6b\x69\xef\xde\x89\xef\x60\xfa\x2b\x54\xd0\x6b\x58\x83\x26\xb3\x50\xb5\x3c\x1d\x8a\x99\x3d\x84\xe8\x66\xdf\x94\x3a\x58\x44\xaf\x0c\x2a\xea\xee\x85\x55\x49\xb9\x71\x37\x80\x16\xa8\xbc\xda\x02\x17\xb1\x98\xbd\x3c\x7e\x51\x18\x04\x81\x1c\xc2\xe8\x94\x57\x49\xb7\xc7\x60\x4f\xc2\xcb\xd7\x01\xee\xc1\xf2\x60\xc2\x6f\x02\xee\x7d\x1a\xb5\x03\x8f\xd4\xea\x75\x33\x79\x3e\x26\x5c\xb2\x23\xf8\xf3\xac\xed\xbc\xb6\x7b\xc9\x91\xe1\xe2\xdb\xfc\x67\x1f\xc4\x67\x80\xc2\xd8\x14\x0a\x49\x92\x16\x91\xe1\xad\x19\x62\x61\x3f\x81\x32\xa5\xad\x7b\xe3\xf1\xc8\x09\x0c\xb9\xc4\x69\xbe\x69\x2b\x97\x6f\x0b\x47\x42\x6d\x61\xa4\x05\x10\xdb\x6e\x76\x00\xb1\x22\x75\x24\x56\xa4\x73\x88\x3d\x3e\x46\x00\xb1\xfc\xec\x48\x2c\x3f\xcf\x21\x36\xbc\xb6\x2e\x23\xe9\x73\x47\x6a\x7d\x6e\xa6\xc6\x46\x99\x85\xd2\x6f\x70\x2f\x21\x18\x79\xec\x73\x25\x88\x98\x1a\x69\x9f\x69\x3e\x80\xee\xab\x0f\x3f\xc1\x1d\xa3\x8e\x3e\x64\x4d\x0e\x3f\x50\xa5\x26\x86\x21\x16\xfb\x46\x97\x6c\xf0\xa4\xb6\x99\x51\xbe\x94\x2f\x51\xba\x2a\xd6\xdf\x70\x7c\x87\x24\xca\x75\xca\x24\x60\xa8\x8c\x22\x6c\x6b\xbd\x66\xca\x58\x92\x86\x52\x4b\x56\x04\x17\xb7\xb5\xca\x68\x1d\xd8\x3b\xfb\xc6\x2b\xdf\x62\xb3\x28\x58\xbf\x4e\xab\xc8\xd3\x1a\x33\x59\x16\x77\xc3\x46\x77\xb8\xb5\xfe\x35\xd4\x41\xef\x5f\x56\xbd\xb0\x55\x65\xa2\xfd\xad\xf5\x87\xdb\x7f\x68\xf5\x5f\x7b\xfa\x26\x4e\x81\xca\xee\xff\x7c\xa0\x1c\x7e\x5c\xda\x60\x30\x35\x3b\x04\xa9\xbf\x1d\xa4\xab\xea\x8f\xe2\xa0\xcd\x44\x43\x03\x21\x0c\xe5\xd2\xec\x73\x96\xa2\xe6\x36\x4c\x4f\xf9\x1c\x83\x4d\x39\xd4\xd9\xaa\xd0\x42\xc2\xdb\x4f\xf4\x6d\x1d\x01\x6d\xd6\x21\xcb\x8b\x6f\x8a\x03\x13\x52\x0f\xe6\x98\xa3\xa4\xd9\x1f\xaa\xee\xe2\x1e\x3b\x80\xbf\x66\xa3\x4f\x4d\x27\x6f\xf5\x07\x0a\xbb\xdc\x73\x96\x13\x25\x57\x35\xdc\x84\xbb\xf0\x00\x7a\xb7\xc6\xb5\x2f\x85\xca\xb0\x64\x21\x93\xa1\xa9\xe2\x4a\x83\x23\x11\x7e\x82\x4a\x26\x32\xba\xb7\x32\x19\x77\x1f\xd7\xb2\x46\x23\xe9\x1c\x71\x84\xd4\x30\x50\x03\xc4\x05\x25\xa9\x30\x30\x49\x2f\x7e\x70\x17\x59\x0a\xd2\x09\xbc\xa8\xc3\xdd\x59\x99\x65\xab\x2f\x82\xeb\x0a\x3d\x9e\x62\xd0\x3b\x51\xb9\x04\xbf\x7b\x29\xb8\xe0\xbc\x8b\x5b\x9e\x33\x11\xdf\xf0\x30\x44\x3e\xd1\xf1\x09\x8e\x3d\xc9\x20\xdf\x86\xf0\x20\xfb\x70\x11\x2e\x68\xf7\x35\x20\x92\xd6\xc3\x80\xfc\xfd\x54\xbe\xb0\xc0\x02\x65\xb3\x27\x45\x65\x6e\x75\xa2\x06\x5a\x30\x09\x01\xf3\x6d\x70\x92\x68\x0d\xbb\xaa\xca\x0f\x49\x63\x7d\xd7\x46\x0d\x65\x42\xe3\xa8\x74\x49\xd3\x49\x38\xcc\x21\x61\x64\x46\xe8\x4f\xba\xd2\x76\xca\x9a\xb6\xf3\x8e\x97\x2c\x4f\x1f\x34\x86\x35\x88\x9b\xfc\xfc\x4c\xdd\xdb\x50\xe7\xc9\x50\x0e\xd4\x00\x0d\x8a\x2d\xf6\xc9\xf6\xe7\xe1\x36\x8e\xc6\xd4\x22\x72\xbf\x4b\x99\x27\x29\x99\xae\x95\xb6\xb0\x26\xd5\x5c\xe0\x02\xd7\xde\xc4\x84\x94\xa7\x39\xdb\x5e\x5b\xe7\x59\xa7\x04\xdd\xf4\xe3\x0d\x5d\x31\x93\xc2\xeb\xf0\x54\x03\x0e\x6a\xc5\x97\x96\x79\x9b\x0e\x07\x4c\xbb\x45\x20\xe7\x29\x01\x2b\xc4\x26\x06\xd2\x1c\x28\x00\x96\xf4\xbe\x87\xcb\xf3\x95\x3e\x43\xb6\x2a\x24\x1a\x80\x46\x91\xd1\x8a\xbd\x0b\xa4\x2d\x55\x5a\x69\xe6\x67\x47\x9a\x10\x49\x8d\xe2\x30\x6a\x92\x5e\x99\x66\x0d\x3a\xf2\x20\x37\xd7\xa2\x94\x02\x2d\x8d\xfd\xd6\x18\x9d\x68\x7a\xf4\x94\x33\xa4\xce\x3e\xae\x64\x1a\x21\xad\xbd\x5e\x19\x09\x8d\xdd\x1f\x4f\x8c\x94\xde\x6f\xa6\x65\x19\x06\x20\x7a\xce\xe3\x01\xd8\xeb\xed\xbd\x71\xa6\x64\x5c\xd8\x9d\x35\x46\xe8\x43\x98\xc8\x13\xad\x9f\x46\x54\x48\x16\xcd\xa7\x16\xfc\x6c\xaa\xc4\x42\x58\x82\x26\x61\xba\x0e\x55\xff\x71\x9a\x90\x58\x0c\x73\x5d\x99\xca\xcc\xc1\xaf\x23\x05\x56\x17\xc9\xba\x1c\xee\x4d\x6c\xe9\x2d\x78\x80\xf7\x29\x44\xa3\x67\x9e\xb9\x40\x76\x55\xec\x9b\x6d\xd7\xa0\xee\x78\x91\xf6\x04\x04\xcc\x3f\x8a\x21\xfb\x96\x60\x0e\x0f\xd2\x26\xe5\x89\xa1\xdf\x2c\x59\x42\x54\x38\xf3\xbc\x48\x58\x3a\xd5\x5e\x67\x34\x33\xfb\xfd\x34\xe7\x12\x18\x58\x0d\x09\xd0\x52\x27\x09\x87\x03\x65\x05\xd0\x46\x9b\x83\x3a\x4a\xd4\x46\x1c\x84\x9b\x6c\x3e\x67\xd2\x63\x63\xba\x32\x01\x94\x98\x64\x47\x2c\x23\x45\x2c\xd4\xe7\x68\xa6\xa6\x84\x02\x55\x9a\x63\x5c\x9a\x1b\x85\xcf\x77\x8d\xbc\xb2\x4d\x4c\x3e\xf5\x5d\xdd\xc1\xd2\x50\x78\x0d\x17\x1e\x62\xdd\xc9\x36\xc4\xc6\x94\x0a\x7b\xf7\x4c\x73\x8a\x1f\xd9\xdc\x4e\x30\xf4\x05\x66\x9d\x26\xe1\x4e\x85\x80\x34\x97\xd4\x64\xb5\x70\xd5\x10\xd7\xd2\x6c\x0e\xfa\x25\x9b\x60\x24\x2d\xca\x14\xa0\xfd\x76\x31\x7b\x49\x5d\xa3\x32\x95\x44\xe0\xd5\x0d\xc2\x89\x92\xd4\xa1\x52\x0b\x6a\xf2\x81\xa2\x0b\x83\xa7\xcc\xfb\x42\x64\x44\x07\x74\x49\x09\xa9\xb5\x47\x8a\x88\xbe\xd7\x99\x93\x72\xc5\x0c\x3c\x18\xc1\xa0\x2a\x94\x05\xab\x0e\x6a\x27\x21\xd6\x0a\x40\x2b\x67\x3b\xa2\x72\x60\xd7\x02\xab\xa6\xd8\x47\xe4\x41\x4d\xe4\xd7\x6b\x35\x30\x2a\x9f\x09\x5c\xd2\x7a\xd0\xc4\x4b\xab\x6a\x50\xcf\x89\xf7\x9e\xe7\x3d\xb6\xaf\x87\x3e\x75\x59\xbd\xe4\xef\x97\xcf\x7a\x78\x5f\x97\x80\x61\x2a\x6a\x03\x63\xb3\x50\x71\x83\x42\xc6\x8b\x1d\x4b\xb3\x69\x26\xd9\xda\x58\xce\x5f\xdf\x78\x98\x7a\xcc\xf9\x4d\xa4\xf4\x5c\x5d\x6d\x7e\xd4\x15\xd8\x04\x68\xef\x22\x6a\x29\xa6\xbc\x0e\xf8\x07\x48\x4d\x5f\xbf\xdc\x71\x22\x11\x75\x5b\x58\xa5\x88\xb3\x67\x36\x98\xf8\xf4\xf7\x9b\x68\xe9\xb9\x4e\x2d\x66\x02\xb4\xb7\x98\x5a\xca\xdc\x62\x46\x48\x73\x8b\x7d\x81\xc3\x59\x33\x34\x5f\x13\xb3\xb2\x60\x13\xf2\xd5\x19\x69\x36\xa0\x8b\x4c\x98\x8a\xcc\x59\x79\x58\xce\xc2\xab\x0a\x6d\x6a\x6a\x0a\xa0\x33\xac\x9f\xcc\x2f\x66\xd5\x10\x47\xf5\x70\xd5\x8d\x2f\x32\x83\x73\xe9\x0f\x77\x74\x06\xb0\x0e\xe2\xec\xd0\xb0\xb2\x33\x17\x09\xdc\xf6\x33\x31\x9a\xd6\xa3\xee\x29\x68\x6b\xa5\x19\x33\x5e\x25\xea\xfa\xd4\xb3\xf7\x45\x56\x0a\xdd\x5f\x5b\x4b\xa5\x69\xc0\x33\x15\xb9\xe9\xd9\x78\x69\x8a\x14\xc2\x85\xe1\x87\xf4\x95\x13\x6a\x5e\xc8\x17\x7a\x30\x57\x03\x8f\xd4\xd4\x88\xe7\x21\xa1\xf7\x2a\x9c\x5e\x1a\x11\xcf\x9a\x01\xe1\x20\x2c\xbb\x9c\x20\xcd\x37\xbe\x0c\xa2\xc6\x15\x37\xd3\xa0\xda\xe3\xf4\xfe\x86\xf2\x66\xc5\x2e\x38\xa4\x46\xfe\x95\x63\xdd\x74\xdf\xcc\x5d\x82\x7a\xe0\xaf\x55\xba\xd5\x44\x4b\x13\x0d\x1c\x70\xe2\xa6\xf7\x79\xa0\x42\xbf\xf2\x42\x1f\xed\x4f\xf2\xf0\x60\x06\x77\x10\x56\x9f\x56\x99\x45\x7f\x68\x08\xc3\x44\x5a\xe3\x88\x72\xad\xf7\x5b\x75\xee\xaf\xec\xed\x76\x55\x0d\xa3\xe2\x0c\x38\x6d\xae\x0b\x9d\x41\x9c\xda\x27\xe9\x21\x3e\xe8\xc2\x13\x56\x05\x34\xe1\x28\xb4\xa1\x73\xa9\x7c\xda\x48\xfd\x24\x3a\xfa\x80\x67\x35\xc4\x01\xa0\x91\x4e\xea\xd8\x58\x12\x44\x3e\x3e\x4d\xb8\x88\x83\xf7\x3f\xc4\xc1\x7b\xfc\x77\x2c\xcc\x1c\x10\xf8\xb1\x09\xa5\x2b\x29\x8e\xcd\x14\x0a\x97\xf1\x48\x65\xf7\xeb\x3e\x4b\x39\xf9\x04\xf9\xe9\x74\xa2\x2f\xbc\x6d\xfc\x78\xb3\xf6\xb7\x71\xee\xad\xfc\xf8\x71\xb1\xf2\x37\x61\x84\x1b\x6a\xb5\xc3\xff\xc6\x3f\x05\x8b\xb5\x1f\x6d\xf2\xc8\x7f\xdc\xae\x17\x91\xff\xf8\xf8\xd3\x6e\x11\xf9\xe1\xe3\x4a\x7f\x23\xcf\x55\x50\x78\xec\xef\x50\x53\x64\x65\xd2\x4d\x0c\x3e\x77\x8e\xd9\x6f\xa7\xff\xdb\x36\x97\xf0\x60\xe1\xfa\x5b\xed\x69\x3e\xb9\xc1\xc8\x5b\x85\x77\xcb\x9e\x8f\x64\x8e\xef\x74\x81\x0f\xd2\x2a\x51\x87\x66\x12\x9e\xd3\xfa\x33\xc8\x93\x95\x83\x39\x9d\x5b\x1c\x1c\xe0\xc2\x7f\x7b\xdd\x5a\x7d\x06\xf2\x73\x86\x9e\xff\xa9\xea\x3f\x7c\xeb\xad\x17\xde\x7a\xb1\x5b\xec\xe4\xb7\x1f\x9b\x0f\xdf\xae\xbe\x95\x3b\xbd\x51\x71\x6c\x32\xf8\x7a\x5a\xd3\x3e\x67\xdd\xf1\x72\x93\x26\xa4\x91\x32\xee\x52\x18\x7b\xdb\x52\x03\xc3\x4a\x72\x9b\xc2\x4f\x0e\xc8\x56\x31\xc9\x73\xd5\x05\x76\x27\x47\xdb\x1b\x5b\x36\xfa\xf4\x64\x24\x2c\x46\x50\x2b\x47\xd2\x39\x27\x3c\x87\x32\x44\x97\x31\x70\xb2\xb7\x58\xe3\x64\x69\x79\x43\x48\xd7\x47\x38\x6a\x9d\x21\xbe\xc5\x4b\x3d\xe4\xe7\xa9\x6a\x8a\xbf\xcd\x57\x7d\x66\x08\x58\xbb\x59\x64\x2f\x7b\x57\x57\x15\x4f\x40\x72\xc1\x51\x11\xe6\x49\x87\xfe\xd7\x77\xbe\xfa\x9c\xa8\x8d\xf6\x57\xec\x22\x74\x8d\xc5\xf2\x02\x1a\x39\xe8\x0a\x2e\x95\x6d\x45\x25\x54\x17\x9c\x59\xff\x58\xd8\x5f\x95\x9a\xb7\xe0\x0c\xbf\xac\x25\xcc\xd2\xc8\x5b\xaf\xff\xe9\xde\xfd\x9d\xb7\x54\x3e\x3c\x2d\x96\xd4\x35\x4a\x9a\xa4\x3c\x22\xe1\x65\x31\x35\x51\xf9\x7e\x85\x36\x7d\x41\x1f\xf0\xe9\xbe\xc7\xae\x00\xf4\xfb\xbd\x57\x90\x97\x15\xaf\x83\x3f\xc8\xda\x1b\xec\x4e\x0a\x8e\x5f\x8b\x6b\xde\x65\x75\x8e\x3e\x2e\x95\x0c\xac\x65\x1f\x89\x53\x4a\x7e\x7e\x78\x17\xbe\xfb\x38\x2c\xfa\x4a\x6f\xdd\x49\x47\xc1\x34\x73\x0b\xc9\xc5\x35\xc0\x9f\xea\xa3\xb1\xe2\xa4\xc6\xa8\xaf\x13\x61\xe7\x10\x22\x43\x9a\x8c\x08\xa9\x19\xc3\x0d\x89\xb7\x08\xc8\x16\x8c\x24\x7b\x26\x3b\x05\x93\xd7\x16\x93\xcb\xdd\x83\x38\x04\xd7\x6a\xbc\x32\x47\xaf\x23\x80\x87\x18\xc1\x85\x61\x95\x81\xfc\x3c\xb5\x41\x22\xd3\x07\xc9\x03\xeb\x4b\xe0\x4e\xc2\x2b\xb8\x23\x0e\x5d\xeb\x18\xcf\xd6\x48\xa7\x38\xb4\x03\x0a\x80\x3f\x3d\x67\x78\x04\x1e\x1d\x1d\xf6\x65\x23\x7e\x55\x21\x00\x56\xa5\x1c\x4e\x6d\xc0\xdd\xf3\x8e\x4e\x29\xd0\xd2\xd6\x33\xc4\x23\x00\x1a\x38\xb0\x84\x21\xb2\x37\xd5\x29\x04\xba\x79\x52\x9e\xbf\x43\xe5\x03\x80\x87\x99\xd8\xc1\x75\xff\xa7\xa6\x7a\x6e\xd1\x3b\x00\x0b\x50\xf8\x57\x6c\x0f\xbc\x03\x29\xf2\x51\xc1\x94\x74\x5d\xf3\x9d\x90\xaf\x08\x84\x56\x42\xbd\xfd\xea\x60\x11\x55\xdb\xe6\xba\x56\x62\xdd\x06\x9d\x68\x0e\x51\x52\xf0\x9a\x09\xbf\xb5\x15\x98\xb6\x88\xad\x26\x18\x60\x60\x38\xd4\xc1\x96\x95\x86\xe3\x06\xca\x52\x8c\x59\x60\x0f\x4f\x6a\xa3\x4e\xed\x1a\xd3\xbe\xcf\xef\xcc\xc8\x92\xc2\x9a\x4e\xeb\xc3\x2e\x17\x0b\x4e\x48\x79\x46\x37\xbd\xdb\x86\xfe\x5a\xbc\xa4\x6c\x0e\xeb\xf1\x65\x4c\x2b\x61\x43\x7d\x31\x12\xca\xdd\xef\x39\xbd\x36\xcf\xc8\x4a\xfe\xe5\x5a\x1c\xf4\x35\x60\xac\x3b\x58\x97\x96\xae\x1d\x5d\xa6\x81\x79\x27\x29\x5f\x0b\x7f\xfb\x85\x11\x0b\x66\x11\x7b\x08\xc3\x89\x22\x4d\x8a\xb0\xfc\x0c\x6b\x82\xe2\xb9\x67\x66\xe7\x26\x82\x3f\x0b\x57\x69\xa9\xea\x85\xe2\xf4\x4b\xf0\x32\xbe\xa2\x7b\xf4\xf4\x1b\x91\x31\x69\xbe\xaa\xe4\x33\xbd\x35\x5b\x3b\x01\x82\x24\x24\x8d\xee\x9b\x05\x19\xbf\x97\x66\xda\x64\x98\xc0\xd1\x5c\xcb\x12\x1b\x38\xcc\x8b\x14\xcb\x83\x6b\x90\x78\x01\x4b\x9c\x9f\x29\xaf\xfe\x02\xc1\xd4\x10\x8a\x90\xf2\x30\x18\x74\x4d\x74\x54\x30\xb0\x33\x88\xfd\xd7\xa0\xdf\xf7\x29\x33\x46\xfe\x9f\x4c\x93\x5d\xc6\xea\x3b\xd5\x58\x6d\x0a\x55\x7c\x6e\xfa\xab\x60\x99\xad\xbb\x42\xf9\xbf\x45\x75\x6d\x9d\xc7\x61\xed\xc9\x70\xf5\xc5\x70\x9a\x72\xa7\x66\xb7\xff\xc9\x14\xfb\x4b\xe9\x70\x3b\x28\x6f\x7b\x87\xee\xb6\xf7\x2a\x6d\xfb\xc5\xb5\x55\xbe\x27\x6d\xd6\x56\x4a\x51\x5e\xa7\x15\xd8\x3a\x65\x79\xee\xe5\xd5\xb3\xb0\x47\xa9\xe6\x5e\xeb\x1a\x5c\xfd\x93\xbb\xcb\x44\xaf\x10\x30\xc9\x67\x20\xe2\xba\x57\xe0\x87\xf5\x40\xc3\x0c\xd1\xb0\xc2\xeb\x8a\x45\x31\x77\x4c\xce\x29\x3a\x25\xd7\xbc\x33\x23\xd1\x26\x92\xb3\xd9\x50\x47\x2e\x67\xca\xad\x2b\x49\xeb\xbe\x3c\xe0\x55\xb1\xf5\xd1\xdf\xa6\x0b\xcf\xed\xb2\x6f\xaf\x0c\xeb\xc4\x65\xf2\xd9\x7a\x39\x59\x5a\x72\xd1\xee\x25\xa9\xe1\x98\x08\x3e\x1a\x5d\xcf\x7a\x61\x9e\xf4\x03\x0e\xca\x0f\xb3\x0f\xdf\xf4\x26\x35\x1c\x80\x8f\x03\xf9\x33\xe2\x00\xa8\xba\x84\x71\x74\xc9\xa1\x95\xef\x1a\x8a\x8e\x38\xed\xbd\x23\xe4\x82\xfc\x22\x11\x21\x64\x09\xd0\x33\xda\x32\x18\xa9\xbe\xe6\xdc\x03\xa3\x8f\x7a\x3c\x8b\xfb\x1e\x86\x23\x76\x7c\x21\x40\xa7\x26\x4a\x50\xc9\xa1\xb2\x94\xd7\x89\xa8\x43\xbd\x18\xfe\xc2\xb5\xb5\x49\x79\xf6\x80\x0b\x89\x92\xc4\x5d\x18\x69\x41\xec\xfb\x72\x50\x09\xdb\xe2\xb0\x1a\x95\x98\xd4\x69\x31\xfc\x25\xcb\xc7\x23\x01\x39\xa6\x8d\x72\xf1\xd5\xd4\x3e\xd6\x9b\x9e\x18\x77\x9d\xe5\xb9\xae\x04\x50\xfb\x29\x90\x43\x00\x02\x21\x8f\x86\xbf\x1c\x70\x59\xcf\x4b\xf1\x83\x0a\x18\x1a\x1b\x13\x41\x5f\xa5\xb0\x0b\xfa\xc1\x7d\x5a\x86\xde\x57\xce\x50\xaa\x14\xf4\x0e\x49\x9b\xe1\x8a\x93\x8f\x73\x53\x3d\xef\x43\x08\x47\x97\x1c\xf8\x5d\xe7\x1f\xc9\x47\x9d\x08\x67\xfc\x68\xcf\x95\x60\x58\xbb\x2a\x41\x37\xca\xe4\xf3\x21\x69\x80\x05\x57\xc3\xf0\x71\x48\x9a\x25\xfb\xbb\xf0\x31\xee\x24\x2b\x11\x94\xe4\x9d\xf2\x6b\x96\x42\x19\xf9\x19\x4a\x2d\x40\xd8\xb6\x80\x52\xfb\xdc\x3a\x80\x02\x37\x34\xd4\xdb\xe1\xe4\xd6\x84\x77\x40\xdd\x33\x42\x25\xaf\x98\x77\x68\xc4\x3d\x02\x69\x05\x5b\x5a\x2e\x5f\x85\xf0\x82\x3d\x4f\xd7\x4e\x55\x4e\x1c\xbf\x37\xc7\xa3\x91\x59\x13\x06\x9d\x31\x6d\x62\xe8\xc6\x80\xb0\xc5\xd1\x6e\xd6\xdf\x61\x78\x18\x76\xa1\x03\xca\xdb\x3c\x81\x82\x54\x2e\x64\x08\x87\xd8\x76\x49\x97\x1d\x59\x88\x43\x89\x94\x74\x1b\xc7\xdc\x3e\xc6\xed\x8c\x01\x11\x0f\xcb\x29\x76\x39\x32\x0b\x16\x7b\x1d\x74\x9f\x8f\x33\x42\x0e\xb0\x37\xda\xb9\x7d\x6d\xdf\x15\xba\x6c\x31\x19\x64\xc8\x6a\xc2\xf4\xa1\x4d\x60\x48\xd1\x10\x9e\xea\xa0\x23\x0c\xd4\xcb\x8e\x55\x69\xdd\xa1\xf6\x63\xf1\x80\x2f\x10\xa0\x8b\xed\x14\x8b\x01\xba\x0c\x47\xfb\x44\x41\x50\x71\x05\xc1\xfb\x05\xb9\x2a\x3e\x04\x1a\x4c\xfa\x21\x5e\x63\xec\x3f\xd2\x28\x8a\x8c\x65\xba\xa7\x47\x2f\x31\xa8\x23\x11\x98\x29\x8f\x49\x30\xc8\x38\x3a\xc1\xf9\xc5\x44\xf9\x71\xc4\x82\xf3\xfb\x7c\xaa\x8b\x58\x62\x55\xaa\x88\xa9\xfa\x92\x48\x5b\x4d\xf5\xbc\x60\xb7\xc0\x6c\xd1\x6d\x54\x0c\x0b\x71\x8c\x50\x86\x85\xa6\x7a\xb6\x17\x30\xf6\x60\xbe\x09\x32\x55\xdc\x30\x6a\x00\x5b\x8f\x72\xf7\xfd\x7b\x6d\xf9\xd1\x50\x29\xc3\xbb\x2e\x9f\x61\x84\x12\x07\xee\xff\x9e\x15\x75\xd5\x74\x49\xd9\x3d\x09\x03\x17\x0d\x49\x64\xc4\xc4\xc7\x2a\x69\x6e\x00\x74\xb0\xed\x66\x0b\x77\xb0\x22\xb5\x88\x59\xca\x84\xc5\x2c\x83\xe8\x62\x96\xf3\x75\x31\xcb\xf9\xba\x98\xe5\xfc\xbb\x3a\x18\x8f\xcf\xaa\x22\x7e\x6b\x07\x2b\xd2\x99\x1d\x4c\x2e\x30\xbb\x83\xa9\xc5\xdf\xd8\xc1\xfe\xee\x5a\x7e\xaa\x83\x09\xf2\x79\x63\x07\x13\x30\xb9\x76\xb0\xc7\xc7\x10\xee\x60\xe4\x96\x9e\x49\xcc\x52\x26\x2c\x66\x19\x44\x17\xb3\x9c\xaf\x8b\x59\xce\xd7\xc5\x2c\xe7\xdf\xd5\xc1\x78\x4c\x62\x15\xf1\x5b\x3b\x58\x7e\x9e\xd9\xc1\xe4\x02\xb3\x3b\x98\x5a\xfc\x8d\x1d\xec\xef\xae\xe5\xa7\x3a\x98\x20\x9f\x37\x76\x30\x01\x93\x6b\x07\x0b\xc3\xc7\x47\xb8\x87\xf5\xb9\x45\xce\x52\x26\x2c\x67\x19\x44\x97\xb3\x9c\xaf\xcb\x59\xce\xd7\xe5\x2c\xe7\xdf\xd5\xc3\x86\x40\xdc\x2a\xe6\xb7\x76\xb1\x3e\x9f\xd9\xc5\xe4\x02\xb3\xbb\x98\x5a\xfc\x8d\x5d\xec\xef\xae\xe9\xa7\xba\x98\x20\x9f\x37\x76\x31\x01\x13\xdc\xc5\x64\xf8\x37\x2a\x92\xb9\x19\xa6\xda\xc0\xda\x00\x56\xe9\x5b\x45\x3f\xaf\xcb\xc9\x65\xe7\x75\x89\xb7\xf4\x87\x2f\xd9\x19\xfe\xd6\x9b\x60\x42\xf5\xbf\x90\xde\xdb\x95\x9e\x67\xe6\xf4\x90\xb8\xb8\xd6\xb6\xb4\xe4\x29\x2b\x2f\x10\x84\x18\x15\x5a\x7c\x01\xe3\xf1\xc1\x40\x54\x6e\x71\xbd\x60\xec\x54\xd0\xca\x99\x0c\x69\xe2\x70\xeb\x44\x48\xdd\xba\x10\x31\xac\xac\x18\xe8\xda\xf4\xb8\xf4\xee\xc2\xac\xb8\x80\x3f\x05\xda\x5e\xaa\x67\x1b\x20\xb8\xf0\xef\xd4\x44\x5c\x85\xa0\xc6\x91\xf7\x47\xa4\x37\x4f\x26\xd0\xd1\x55\xb8\xdf\xea\x2e\xda\x2a\x18\x6f\x5b\xac\x02\xe8\xd6\x22\xe3\x7d\xc1\xfe\xef\xc7\x0f\xdf\xb2\x3c\x2c\x30\x74\x4c\xea\x0f\xdf\x12\x46\x87\xe4\x22\xeb\x50\x93\x67\x45\xd6\x7d\xf8\x36\x0c\x86\x64\x46\x31\xa2\x17\x37\xd6\x8b\xed\x25\x8a\x7e\x5e\x2f\xc2\x98\xfe\x8d\x56\x97\x28\x02\x2e\xb6\xc1\xb2\x42\x7d\x37\xa7\x53\x90\x08\x45\x89\x41\x0d\x68\xa6\xb5\xab\x30\x10\x87\x5e\x9c\x26\xcd\x27\xc3\xc8\xa1\x67\x29\x34\x01\x00\xf5\x51\x3f\x98\x0e\x34\x58\x5c\xda\x9c\xf0\xf7\x7e\x19\x06\xc1\x7b\x49\x36\xe6\xb2\x36\x86\xcc\xc3\x85\x4a\x6a\xeb\x44\x4b\x1d\x32\x54\x2c\x91\x15\x8b\x71\xd8\xb0\x10\x54\x46\x0d\x0b\xa4\x34\x68\xe8\x70\xc6\xcd\x42\x98\x61\x79\xa0\xd0\x1b\x46\x1e\x2c\xd4\xfc\xd0\x20\x86\xbf\xe5\xf1\x22\x8a\xe3\xe5\x62\xfc\xe7\xff\xd9\xa8\x21\x0b\x6c\x1c\x34\x5c\x3b\x87\x32\x6e\x00\x79\xb6\x1e\x03\x8c\x1a\xec\x62\x55\xd2\xa4\x4e\xe1\x75\xb5\x7d\x3a\x31\x6a\xed\x73\xd5\xa4\x74\xc6\x74\x68\x50\xf2\xc9\xc3\xdf\x8e\x2f\x74\x19\x37\x9d\x24\x4b\x15\x19\x9f\xe7\xc2\x15\xf8\xf1\xa2\x9c\x9f\x92\xdf\x06\x0a\x18\x94\x4f\xf6\x0e\x49\xb4\x1c\x31\x8e\xce\x42\x48\x67\xaf\x69\x8c\x99\xa6\x88\x3a\x8e\x47\x36\x34\xba\x63\xfc\x26\x9d\xec\x98\x67\x0b\x86\x2d\x53\x06\x02\xfa\x88\xb4\xbd\x43\x95\xbe\x28\x47\x01\xc4\xf0\x3d\x75\x3f\x6c\xb1\x87\x52\xb9\x2e\xeb\x72\xa4\x9c\x79\xe1\x61\xb8\x08\x40\x7b\x3d\x48\x30\xf4\x10\xfd\x0a\x02\x59\x32\x94\xa8\xef\xc4\x3a\xea\xd7\xb1\x30\xd4\xe4\x41\xa0\x01\xea\xfb\xf1\xa7\x14\x3e\x51\xae\x08\x7b\xc6\x63\xd8\x22\xe5\x57\x55\x23\x30\x38\xa2\xe9\x1e\x2d\xd1\xc2\x60\xf5\xf0\x64\x3a\x39\xa4\x6a\xab\x44\x1d\x52\x28\xd6\x58\xe2\xad\x6f\x6f\x11\xd6\xfd\xc3\x02\x48\x0a\x16\x81\x84\xf0\x7b\x41\x77\x5c\xd5\x77\x90\xf0\xa9\xaa\x3a\xb3\x44\x5c\x25\x20\xbf\xa2\x63\xa8\x3e\x25\x05\x28\xf6\x70\x71\x27\x80\xaa\xab\x27\x49\xb5\xa7\x67\xb8\x94\xf3\x58\xfc\x2a\xa7\xfc\x74\xa2\x5c\x8e\x1c\xb0\x59\x1a\x51\xb1\x10\x9d\xfe\x46\xd2\x0d\x1a\x09\xc0\xdf\x88\x4a\x95\x15\x67\x0f\xab\x68\x9e\xbc\x4c\xde\xb9\x1a\x4f\x2e\xd0\x03\x0d\x70\x7f\xcb\x8a\xf3\x72\xc4\x4d\xcb\x08\x09\x5d\x55\x53\xb7\xb4\xbd\x34\xb8\x83\x04\x52\x40\x73\x00\x03\x2e\x60\x18\xba\x74\xe9\x1a\x87\x31\x63\x43\x40\xec\xda\x06\x2d\x33\x4d\x60\x00\x33\x52\x4d\xd1\xf1\xd3\x82\x9a\x2c\xb9\xf5\xc9\x79\x59\xf3\x86\xf5\x50\x18\x38\x7f\x32\x2c\x24\x91\x65\x24\x25\x58\x6b\x5c\xf7\xb2\x1a\xb0\x83\xb9\x0a\x33\x6c\x7c\x55\xce\xae\x8b\xa5\x07\x25\x90\x06\x2a\x8c\x8c\x61\x63\x71\xdf\xee\xac\x1b\x29\x3d\x55\x39\x80\x92\xca\xb8\xd2\x6d\x04\xd0\xef\x25\xd6\x98\x2a\x8b\x37\xf3\x80\x32\x5f\x2e\x12\xf7\x24\xe6\x85\xd8\xa9\x97\xce\xf0\x40\x4f\xb9\x97\x34\x1d\xea\xe6\x91\x9e\xee\x37\x46\x06\xbe\x40\x38\xf1\x69\xc4\x4e\x52\x05\x0a\x4c\x0c\x40\x73\x68\xdb\xc5\x6a\xa0\x0d\xca\x55\xe6\x80\xb1\x40\xe7\xb2\x2d\x38\xa8\xb0\xe9\xce\x44\xd7\x63\x18\x86\xab\x6b\xf4\xdb\x3b\x56\xd7\xb2\xdb\xaf\x9e\x94\x4f\x05\xea\x9c\xd4\xc3\xe1\x2c\x72\x12\x1e\x48\x3f\x37\x59\x0a\xa5\x03\x49\x55\x53\x5f\x92\xb2\xdd\x93\x28\x88\xd5\x73\xbb\x0f\xc1\x6a\x4e\x44\xfe\x78\x7d\xf5\x93\xe3\xb1\x6a\xd2\xac\x2a\xd9\x38\xa1\xbc\xa4\xa7\x01\x08\x4a\x5e\x9d\xbc\xee\xa5\x56\xdf\x73\x99\xe8\xe1\x76\x45\x05\x89\xd1\xa6\x57\xa9\xcd\x3a\xb9\xab\xe0\xfd\x51\x9a\x30\x2a\x13\x95\x27\xe8\xf8\x37\x76\x76\xd2\x63\x73\x2d\x0e\x2e\x47\xe9\x87\x99\x96\x3e\xf1\x0c\xe9\xe9\xbc\xa9\x17\x8e\xe5\x0b\xd1\xca\x74\x7f\x64\x86\xcc\x02\xbf\x57\x13\x6e\xd0\xba\xfc\x54\x21\xeb\x33\x99\xd0\xe2\xbf\x7c\x5c\x7c\x38\x7d\xf7\xc3\x3b\x07\x5a\x64\xd6\xcf\x29\x9a\x5f\xc6\x37\x3c\xd0\x2f\x23\x53\x0e\x90\xf3\x48\x8e\x75\x72\xce\x4a\x52\x4c\x6e\x31\xe5\xd0\xa9\xd6\x14\xa0\xc4\xeb\xe4\x8c\xd8\x36\xc8\x44\xc4\x54\xf9\x18\xb3\x1c\x98\x7d\x08\xf9\xae\x5c\xc3\x8f\x86\x7b\xf8\xc6\x30\x75\x70\x30\x01\x7e\xaa\x7f\x60\x4f\x79\xa1\x2e\x1a\xf1\xc6\x9b\xc3\xca\xf5\xb5\x46\x59\xf9\xa4\xd3\xf6\x22\x2d\xe5\x01\x82\x3b\x63\xc6\x10\x7c\xaa\x33\xb3\x10\x24\x0e\x4e\x44\xec\x4e\xba\xc5\x55\x1e\xc9\x89\xfe\xf9\x48\xcd\xee\xe6\xdb\x86\x36\x8d\x02\x53\x4c\x11\xfb\x28\x2c\x87\xb3\xfe\x60\xd8\x59\x11\x3f\x5f\xcb\x14\x29\x38\x5f\x95\xa1\xaf\xad\x3a\x5f\xb3\x10\x3b\x14\x39\x2a\x21\x74\x09\xd5\xbd\x74\x39\x93\xec\xc7\x30\x46\x9b\x26\x98\xda\x7e\x35\xd1\xf4\x2b\xde\x2e\x30\xb5\x99\x8a\x00\x50\xd3\x01\x24\x72\x6d\x01\x8a\x6b\x56\xe8\x75\x18\xe1\x3d\xd2\x8a\xa6\x3a\x8a\x91\xfd\xbb\xba\xcd\x64\xaf\xa1\xd6\x29\x49\xcf\x76\xdb\x83\xe5\x85\xc5\xb5\x96\xa4\xb5\x8d\xdf\x4b\xa1\x58\xb6\x6a\x98\x31\xb7\x77\x2c\x94\x13\xe5\xca\x55\x27\x79\x08\x10\x2e\xd8\x99\x2e\x01\xfe\x0d\x5c\x22\xa4\x02\xd5\x2e\x03\x26\x34\x83\x2d\x20\xf3\x2f\xdb\x22\x1c\x85\x20\x0f\x4f\x2b\xfb\xd6\x87\xae\x5c\x30\x3a\xba\x55\x14\x5e\x18\xc4\x10\x64\x41\x46\x3d\x43\xb0\xd1\x8e\x10\x6c\x46\x65\xe1\xf7\x69\x83\x51\x3f\xbc\xba\xc9\x8a\xa4\x79\x71\xba\x28\x95\xc8\x65\xe4\x1a\x0f\xa9\xea\x32\x39\x88\x6f\x13\x1d\x8f\x2a\x3e\x1f\xc6\xa7\x04\x7e\x71\xb5\x84\xd8\x10\x52\x44\x2d\x3a\x56\x65\x3a\x59\x49\x36\xcb\x49\xd4\x52\x4a\x35\xc7\x74\x87\x8a\xc6\xeb\xf8\xb0\x89\x74\x9c\xbe\x09\xe7\x9c\xca\x86\xc1\x6e\x19\x86\xdb\x65\x18\xc9\xd5\xbd\x1e\x8f\xa8\x6d\xed\x8c\x45\xbb\x64\xbb\x8e\x47\xc6\x68\x19\xb5\xaa\x2c\xd5\xa1\xa2\x21\xda\xa2\xd5\x5a\xc5\xa7\x56\x53\xa4\xe2\x58\xc9\x75\xb0\x0c\x37\xdb\xe5\xe6\x51\xac\x62\x56\x9e\xaa\x09\x7e\xb6\x49\x74\xd8\x0d\xfc\xe0\x02\x4a\xe5\x48\x92\x4b\xcd\xc2\x6d\xb2\x3b\x48\x98\x7c\x00\xd3\x9c\x3a\x45\xab\x65\xb8\x89\x96\xe1\x6e\x2d\x56\xea\x39\x69\xca\x31\x68\x1d\x7f\xf2\x1c\x9a\x4e\x1c\xc3\x60\x3b\x30\xc4\x8a\x29\xb5\xe3\xa9\x52\x05\x8d\x28\xd3\xd5\x23\x0a\x02\x15\xa5\x0f\xa3\x9c\x55\xd3\x38\x5e\x86\x8f\xab\xe5\x56\xac\x68\x9a\x94\xe7\x29\xa9\xa7\xc7\x55\x2c\xe8\x27\x2d\xa2\xd4\x91\x25\x3a\xb4\xe1\x21\x8d\xc2\x55\xa0\x60\xf3\x41\x6c\xb3\x6a\x17\x05\xcb\x78\xa5\xe8\x26\x39\x70\x30\xdd\x88\xf4\x89\xf8\x44\x2c\xa4\x54\x8f\xa6\x39\x36\x60\x82\x02\x14\xcb\xe8\x7c\x08\xdd\xac\xea\xad\x77\xcb\x68\xfd\xb8\x8c\xe2\x40\x6e\xbe\x66\xe2\x5e\x2d\x0d\xec\x29\x88\xbb\xf9\xa4\x35\x5d\xf3\xc9\xa9\xf3\xa5\x51\x18\xad\x25\x4c\x5a\xb3\x71\xe4\x8e\xb5\x8a\xa3\x65\xbc\x5b\x6e\x58\xd7\xfb\xcb\xb5\x38\x54\x5d\x53\x95\xc3\x1c\x32\x32\xac\x32\x18\x22\xa7\xc0\xab\x0a\x2b\xfb\xda\x97\x4e\x75\x8d\xa9\x92\x79\x9b\xc0\x13\x3d\xc5\x37\x71\xa8\x51\x8d\xe6\xf6\xea\x27\x39\x6a\xa0\xf8\x8b\x4e\xbb\x78\xe1\x38\xb9\x9c\x75\x87\x91\x10\x25\xcb\x3f\xe3\x18\xc6\xee\xc4\xf2\x4c\x32\xab\x55\x66\x96\x3c\x2f\xcd\xda\x22\x6b\xdb\xec\x90\x23\xa5\xbe\x6b\x01\xbd\x00\xb5\xf0\x8f\x79\xd5\x9a\x1e\x3a\x00\x82\xf6\xc9\x95\x06\x19\x54\xe6\x42\x41\xb0\x0e\x76\x31\xd0\xe6\xc7\x23\x8a\xf5\x77\x36\x76\x69\x82\x7d\x49\x09\xd5\xe2\x22\xbd\xde\xc8\x40\x1f\x4f\xc7\x54\x07\x15\xa5\x34\x70\x10\x6d\xe3\x88\x03\x6a\xf3\x98\xd5\x6e\x95\xae\x81\xab\xa8\xdf\xa0\x08\xad\x50\xac\x3a\x9d\x9b\x74\x97\x1e\x34\x64\x30\x8b\xc7\xdd\xf1\x70\x3c\xe9\xc0\x00\x93\x51\x10\xad\xa2\xcd\x00\x2a\xcf\x3e\xc2\x38\xde\x46\x6b\x68\xc4\x5a\xa3\x74\x0c\xda\xc8\xa9\xae\xd0\xe6\x78\x50\x50\xc1\x0c\x1e\xc2\xf4\x74\xd0\x40\x21\x19\x1e\x22\x14\xae\x38\xa0\x38\x73\x08\x8e\xf1\x7a\x03\x85\x99\x4c\x43\x74\x3c\x85\x6a\xfb\x22\x14\xa3\x83\x88\x07\x66\x2c\x39\xa4\x29\x8a\x25\x38\x88\xab\x4d\x74\x5c\x0d\x5c\x29\xa6\x7f\x17\x6f\xd6\x01\x24\xb4\xd3\xe9\xb4\x3a\xa6\x0a\x63\xa7\x13\x42\x87\x44\x41\x05\xf3\x76\x3a\xa1\x5d\x12\xaa\xa0\x00\x7b\xf1\x6a\x75\x0a\x06\xf6\x64\x83\xbd\x8d\xc2\x23\xd8\xa4\xa7\x5d\xba\xd5\x9a\xf4\x14\x1f\x85\x26\xa5\x98\x0c\xcc\x85\x87\xe0\xb0\x55\x20\x01\xde\xd6\x8f\x61\x14\x6e\xc7\x41\x45\x30\xb7\xbb\x70\x17\xee\x22\x88\x35\x84\xff\x53\x59\x4b\x4f\xe9\x09\x49\x88\x60\xce\xd0\x11\x1d\x4f\x1b\x19\x10\x60\x6c\xb3\xc3\xff\x8d\x15\x18\xcd\x64\x78\x08\x51\x04\x75\x54\xd2\x27\x1f\xd5\x5e\xb0\x39\xee\x8e\x89\x88\xc7\xd0\x05\x1e\x0f\x87\x03\x92\xe0\x20\x4d\x5b\x07\x71\x10\xbf\xfe\x23\xdf\x3c\xf9\x84\x5e\x4e\x4d\x52\xa0\x76\x51\x37\xd5\xb9\x41\x6d\xeb\x1d\x92\xc6\x6b\xbb\x26\xab\x51\x7b\x0b\xde\x8b\x67\xd0\x86\xd1\x35\xa4\x91\x41\xbb\x0a\xcc\x0d\x16\xc1\xeb\xeb\x3f\x7e\x35\xcc\x3e\xc7\x77\x13\xe3\x9e\x09\xeb\x3b\x5a\x20\x6a\x97\x25\x7f\x8e\x74\xe9\x8b\xec\xca\x2b\xdb\xda\xd6\x8d\x04\x0a\x1f\xed\x52\x2f\x53\xb0\x25\x12\x61\x9e\x73\xe7\x3b\xa0\x6c\x09\x53\x58\x80\x20\xb3\x8a\x85\xbf\xa1\xeb\x19\xce\x0b\x19\x52\x25\xf4\xe0\x46\x40\xeb\xa5\xfa\xc1\x44\x3c\xd5\x4a\x1a\xef\x8c\xa5\x8a\xca\xee\xbb\x75\x9c\xa2\xf3\x52\x3b\xf4\x18\x3f\x2c\xa2\xf8\xfd\x52\x98\x40\x2c\x02\xe9\x2b\x0e\xde\x83\xa5\x02\x30\x75\x6b\xc3\xf5\xa0\x07\x23\x18\x03\x9f\x48\xb5\x4a\xca\xac\x48\x3a\x94\x0e\x1b\x8f\x34\x01\x0b\x01\xd2\xdd\x45\xd8\x2e\x68\x7d\x17\x59\x79\xca\xca\xac\x43\x4f\xb3\x4b\xdc\xd5\x3c\x36\x4e\x69\x20\x46\xe9\xf3\xf5\xd5\x27\x44\xcc\xcf\xdd\x8a\x57\x7b\x08\xa8\x7c\xc8\xed\x55\x38\x0f\xf5\xf6\x78\x23\xaf\xea\xe9\x2a\x2f\x21\xa5\xc5\x98\x75\x72\x90\x22\xa1\x6b\x0c\x93\x33\x18\x07\x3f\xb0\x69\xc8\x95\x77\x6d\x42\x88\xcc\xf4\xae\x0d\xf3\xd2\x4c\x34\xe4\x5d\x32\xa3\x73\xc6\xa3\x77\x2b\x58\xdc\xf7\xbd\x26\xce\x98\xc1\x3b\x59\xfa\xa1\xb2\xaf\x77\x50\xf3\x2b\x9f\xc5\x54\xd0\x0f\x9b\x34\x5a\xe3\x9b\x9e\x19\x70\x7e\x89\x4d\xa7\xc5\xda\x58\xdb\xfe\xbb\x63\x97\x49\x41\xfd\xbd\xa6\x10\x82\x98\xd9\xd9\xe0\xe9\x42\x9c\x41\x4b\x30\x2e\xd6\xd9\xea\x5e\xc2\x76\xa9\x9a\xec\xaf\x55\xd9\x25\x39\x78\xf7\x0d\x84\x74\x3a\x2d\x69\x6c\x48\xdb\x69\x02\x47\x72\xba\x62\xb9\xed\x2a\x2a\x67\x22\xdc\xa8\x01\xa2\x75\x2e\xeb\xd0\xb8\x42\x2b\x11\xf6\xa0\x26\x9f\x43\x41\x61\x77\xdc\x19\xd7\x89\x84\xd6\x43\x71\x20\xfd\x21\x52\x8d\x8b\x9e\x90\xfd\xad\xdf\x54\x55\x40\x8a\x5f\x53\x5b\x20\x82\x33\x14\x06\x2a\xfe\xc5\x75\xc6\x89\xc8\x4c\xb5\xb1\x04\x5e\x81\x79\xe0\x01\x58\x9c\xf4\xa6\x70\xbb\x4f\xf0\x05\xf5\x06\xa2\xf8\x55\xf5\x06\x20\x38\x47\x6f\x80\xe2\x5f\x5e\x6f\x5c\x88\xbc\x5d\x6f\x78\x3c\x11\x98\x07\x1e\x57\xc4\x49\x6f\xf2\xf3\x6f\xad\x37\x10\xc5\xaf\xaa\x37\x00\xc1\x39\x7a\x03\x14\xff\xf2\x7a\xe3\x42\xe4\xed\x7a\x33\x44\xc9\x80\x99\xe8\x67\x4c\x68\x48\xf8\x84\xdf\x56\x71\x20\x8a\x5f\x55\x71\x00\x82\x73\x14\x07\x28\xfe\xe5\x15\xc7\x85\xc8\x5c\xc5\x11\xcb\x9f\xf2\x6b\x7b\xd1\x48\x0c\xc7\x54\x89\xa0\xf9\x75\x3c\x80\x6d\x7d\x8f\x65\x12\xb7\xc9\xbb\x82\x04\x41\x30\xdc\x77\xb9\xcd\xe4\x27\x38\xef\x65\xf0\x6d\x0b\x43\xf9\x99\xce\xf7\x44\x29\x69\xc7\xcf\xc8\x12\xdf\x1e\x99\x87\x5c\x39\xb3\x6a\xf2\xcf\x28\x4d\xc5\x3f\xc3\x89\x3a\x3d\xf7\xfd\x16\xbe\xb5\x62\xc4\x30\x53\x8c\x93\xe5\x24\x41\x1a\xd9\xe2\x9b\x38\x73\xd1\x3b\x89\x92\x53\x95\x44\x49\x13\x01\x8a\x8e\xbb\x42\x7c\x03\xc8\x50\x7e\xae\x18\xed\xa5\x24\x21\x1a\x59\xe2\x1b\x4d\xf3\x90\x3b\x89\x90\xd3\x94\x44\x48\x13\x75\x7a\x4e\x3b\x57\x7c\x93\x0a\x2a\x3c\x53\x78\xb6\x22\x72\x3f\x36\x31\xc3\x77\xc2\x66\x60\x76\xeb\xc4\x8c\xa0\xdc\x89\x49\xa2\x4e\xcc\x7d\x6b\x8d\xee\xa2\x19\xca\xcf\x14\xde\x44\x29\x49\x7e\x36\x96\xc8\x6e\xdd\x3c\xe4\x4e\x22\xe4\x34\x25\x11\xd2\x44\x9d\x9e\xeb\xf6\x1f\xdb\xe9\x83\x8b\xcf\x14\xa0\xbd\x90\x24\x3f\x33\x43\x6c\x43\x71\x16\x6e\x27\xf1\x71\x92\x92\xf8\x68\xa2\x4e\xce\x71\x87\x92\x6d\x46\x82\xa5\x67\x0a\xcf\x5a\x46\xd6\x3d\x13\x3b\x7c\xcb\x73\x0e\x6a\x37\xcd\x63\x14\x65\xcd\x23\x89\x50\x4b\x39\xec\xa1\xf2\xed\x52\xa8\xf0\x6c\xad\x33\x17\x91\xad\x85\x89\x19\xbe\x27\x3b\x03\xb3\x9b\xa9\x60\x04\x65\x53\x41\x12\x5f\xd9\x49\x18\x1a\x6b\x9d\xcc\x65\xa5\x9b\x02\xb1\xfa\x6e\xb4\x7e\xa0\x7b\x98\x08\x05\xca\x03\xb9\x61\xdd\x2f\x02\xf2\x0c\xc4\xf0\xd4\xaa\x1f\x33\x82\xea\x6c\x2e\x30\xdc\x2d\xa2\xc0\xe4\xda\x19\x5f\x9e\x7f\x20\x9f\xfe\xf8\xc9\xda\xc3\x05\x94\x52\x1d\xb8\xd9\xc6\xaf\x87\x6b\xd7\x55\x25\x3f\x0f\x34\xfd\x28\x25\xdb\x2a\x09\xde\xf6\x3a\x65\x42\x09\x8e\xd1\x6f\x80\x4d\x86\x57\xbf\xab\x92\xb6\xbb\x8d\xe1\x2d\x57\x71\x50\x6b\xdb\xca\xc0\x55\x05\x8d\x79\x75\x33\x74\x17\x3f\x68\xd1\x40\xc6\x70\xf9\xc0\x13\xd8\x72\xec\x2a\xf9\x88\x9c\x14\xfa\x5e\x85\xe4\x52\xc2\xd4\xd2\xa6\xaa\xbd\x53\x96\x77\xa8\xd9\x1f\xf2\x6b\xf3\x5d\x18\xf0\x17\xf2\x0d\x59\xc3\x0b\xbd\x86\x5d\x78\x22\x20\xfd\xae\x33\x1c\x3b\x83\x00\x93\xa8\x3d\xd8\xa4\x73\xd4\xa1\x98\xa1\xbc\xa0\xa3\xc1\x5c\xb2\x54\x7b\x62\x03\x67\xf0\x9b\x8b\xc6\x8d\x53\xb6\x53\x0f\xbf\x16\x20\x6f\x37\x7d\xa1\xc6\xb3\xc7\xc9\x08\xe2\x07\xce\x3a\xd9\xc1\x95\x77\x0b\x5f\xfd\xa2\x4a\x93\xdc\xab\x6a\x54\xea\x17\x50\xc7\xbc\x05\xfd\x3d\x80\x78\x3d\xd7\xc9\x21\xe5\x85\xc5\xdf\xa3\x80\xc3\xa6\xe5\x29\xeb\x51\xca\x0e\xdb\xa9\x8f\xfd\x06\x71\xf0\x24\xca\x18\x78\xfa\x99\xfc\x56\xfb\x81\xf0\xba\x2b\x65\x31\xcd\x92\xbc\x3a\x1b\xdf\x92\xa6\x11\x59\xe8\x63\xd0\x2c\x7c\x22\xd4\x09\x09\x2e\xff\x94\xa4\x68\x21\xe3\x15\xce\x3e\x90\x9f\xa7\xaa\x29\x16\xfe\x8a\x5d\x0f\x19\x9e\xa2\xc3\xc9\x14\x20\x4f\x3a\xf4\xff\xfb\xce\xc3\x9d\xf8\xc1\x79\x3f\xdf\x85\x3c\xdf\xbc\x27\xa0\xf4\x85\x1f\x1d\x94\xf0\x21\x56\x89\x82\xd0\xb7\x36\x8c\x05\xda\x63\x92\xa3\xef\x42\x3f\x88\x1e\x64\xb1\x7a\xed\xb1\xa9\xf2\x1c\x8f\x5e\xb2\xda\xe3\xe1\x4a\x7a\x7d\x38\x08\xde\x2f\x3c\x72\x8e\xc2\x8c\x82\xd3\x67\xc7\x5e\x6e\x00\x92\xcf\x17\x8e\x45\x3f\x58\x33\x81\x95\xdf\x64\x9f\x00\x63\x9d\x58\x0a\xf6\x31\x89\x9b\x74\x1f\x58\xdd\x79\x21\xda\xf9\x51\x3a\x39\x3c\x08\xe1\x81\xa6\x44\xc7\x71\xaa\xb7\x84\x81\xd7\x9f\x25\xd1\x8d\x8f\x72\x18\x10\x1a\x1b\x79\xd6\x79\x25\xa1\x9f\xce\xa4\x63\xd1\x04\x41\x79\x5d\xb1\x71\xf1\x70\xf6\x44\x14\x9c\xc2\x5d\x21\xb8\x84\x31\x49\x19\x35\x6c\xf7\x38\xef\x35\xb9\x91\x16\x82\x8b\x5c\x7a\xd4\x46\x3c\x6e\x4a\x1d\x07\xda\xb5\x10\xcb\xe6\xf3\xb3\xd0\x68\x9f\x2f\xe0\xf2\x97\x46\x87\x8c\x4b\x37\xe1\x1d\x7d\x25\x9b\xd8\x54\x71\xee\x27\x75\x34\x87\x63\x46\xf6\x77\x9b\xc6\x80\x3e\x7a\xfc\x21\xed\x56\xb6\xe9\xa6\x32\x0d\x79\xb3\x72\x0e\xc9\xb3\x12\x63\xe3\x88\xf5\x59\x28\x93\x48\xe1\x1a\xc0\xde\x23\x67\xc9\xc4\x7f\xc5\x71\x02\x8a\xf8\x15\xe8\x17\x4e\x85\x01\x47\xd7\x59\x39\xd0\x98\xc8\xc3\xab\x34\x0a\xbe\xf5\xe1\x2c\x52\x02\x95\xa9\x72\xc0\x08\x8e\x4d\xa5\x88\xde\x1c\x9e\x08\x10\xbf\x31\x3a\x11\xd0\x00\xb4\x6a\x3f\xfe\xee\xc6\xcd\x79\x24\x4e\x63\xe8\x70\x70\x48\x1a\xaf\x40\x49\x7b\x6d\x4c\xe7\xfe\xbd\xc7\xc7\xc7\xc7\xba\x67\x7d\x82\xcc\xb5\x99\xf8\xe5\x79\x37\xc5\x67\x39\x03\x21\xd9\x52\xe1\x01\xa3\x20\x18\xc2\x12\xed\x43\x36\x5f\x06\xec\x85\x30\xe8\x1a\x8c\xe9\x8a\xcc\x57\xde\x6e\x4e\x61\x3c\x83\xbd\x32\xd8\x23\x7b\x29\x3e\xe4\x3a\xd0\x6b\x0b\xd1\xb9\xc1\xd2\xb1\xed\xf4\xd2\x32\xf9\x99\xdb\xf1\x3e\x17\x4a\xef\x4c\xa5\x87\xfd\x3e\xa0\x50\x18\xae\x49\x29\xbf\xab\xaa\xbc\xcb\x6a\x40\x2f\xc6\xc1\x72\x1b\x28\x27\xec\x58\x43\x06\xd4\x01\x3b\x25\x45\x96\xbf\xec\xb1\xe7\x97\x23\xaf\x7d\x69\x3b\x54\x2c\xff\x29\xcf\xca\x4f\x3f\x27\xc7\x5f\xc8\xe7\x3f\x57\x65\xb7\x7c\xf7\x0b\x3a\x57\x68\xf1\xef\x7f\x7a\xb7\xfc\xd7\xea\x50\x75\xd5\xf2\xdd\xff\x44\xf9\x67\xd4\x65\xc7\x64\xf1\x67\x74\x45\xef\x96\xbf\x6f\xb2\x24\x5f\xbe\xfb\x73\xd5\x55\x8b\x5f\x92\xb2\x7d\xb7\x6c\x93\xb2\xf5\x5a\xd4\x64\xa7\xe5\xbb\xdf\x63\x02\x8b\x3f\xe0\x31\x79\xf1\xc7\xa2\xfa\x4b\xf6\x6e\xc4\xa9\x27\xfc\xf2\x52\x1c\xaa\xfc\x1d\xc3\x26\x96\x62\x7e\x23\x8b\xb4\xd1\x14\x49\x2e\xf9\xf9\x6b\xd5\xcf\xf7\x63\xf1\x7c\x25\xee\x96\xe2\x37\x1d\xad\xc1\x93\x91\xe2\xa2\xc0\x98\x20\xcf\x49\x9f\x72\xd4\x61\x1b\x8a\x87\x77\x3c\xa8\x30\x86\x48\x70\x4b\x12\xd7\x52\x4a\x51\xa1\xa4\xf3\xcf\x24\x89\x5e\x57\x27\x05\xc9\x78\xa8\xfb\xc8\x60\xdc\x4c\xc1\x92\x31\x95\x50\x4c\xd8\xe3\x90\xb1\xf0\x93\xa6\xa9\x9e\x01\x95\x91\xb5\x84\x3d\x77\xbc\x13\x1e\xde\xf6\xd7\xcc\x1f\x15\x11\xf1\x6e\xa3\xe3\x13\xdf\x51\x13\x57\x70\x80\x6b\x55\xb4\x35\xc9\xd8\xfb\xea\x1f\x5a\x8f\x91\xf0\xb0\x0c\x7e\xed\xbd\x3a\x4f\x8e\xa8\x40\x65\xf7\x7f\x3e\x74\x55\xfd\x71\x29\x82\x74\x78\xd6\xc0\x87\xf4\x35\x3d\x56\x3f\x8d\x82\x31\xaf\x62\xe2\xc2\x19\x8f\xf2\xba\x62\x1a\xde\xd5\x05\x11\x0e\x11\x6a\xc8\x7c\x86\x55\x9a\x49\x98\xf0\xcc\x38\x7f\xd2\xef\x3b\x90\xd9\x8b\x95\x0b\x62\x96\x64\xa1\x90\xa4\x71\x55\x68\xc1\x5a\xce\x01\x0d\x24\x98\x86\xdd\xfd\x20\xa2\x61\x93\x31\x81\xf9\x41\x3d\x76\x33\x89\x40\x32\x13\x69\x71\xa9\x8d\x61\x11\x0d\x72\x53\xa4\x47\xed\xb4\xb3\xfc\x68\x63\xcb\x02\x64\xe1\xc0\xe6\x29\x16\x43\x04\x89\x90\x66\x71\x19\xb2\xa3\x07\x33\x90\x41\xa2\x92\x70\x72\x59\xa9\xb1\xb3\xd8\x56\xb9\x28\x28\x65\xa2\xe2\x2c\x27\xdc\xf2\xb2\x94\x70\xca\x4c\x2d\x23\x48\x20\x09\xe1\x0c\x2e\x1f\xde\xe0\x77\x2a\x99\x48\x03\x12\x9c\x40\x8a\x8b\x4d\xbe\x55\x2a\x6a\x18\x28\x3a\x32\xb9\x13\x05\xc7\x51\x67\x65\x49\x1e\x66\xe7\x96\x9a\x18\x71\x6d\xf9\x4c\x5c\x3d\x83\xaf\xc6\x80\x5e\x8c\xe9\x4a\x4f\x55\xd3\xb0\x1b\xb0\xb3\xb4\x09\x9e\x04\x7e\xf0\x4c\xef\xbf\x0c\xff\x7f\x1a\xc3\xff\x9b\xf8\xeb\x83\x8a\x2d\xf9\x0f\xc7\x49\xc4\xab\x0a\xcf\xa6\xaf\x62\x7f\x16\x6e\x63\xe3\x21\x44\xa2\xc7\x3b\x69\x72\xea\x74\xe2\xe6\x89\x87\x3c\x91\x79\xc3\x34\x84\x11\xb4\x4d\x43\x38\x08\x9e\x86\x28\xcb\xf7\x31\x1f\xa9\xec\x68\x7e\x14\x06\x43\x01\xdb\x8f\xf2\x54\x84\xb8\x23\x9e\x2f\x05\xb8\x75\x45\x2d\x8e\x81\x3a\x05\xbb\xe5\xf0\xc7\x11\x0b\x9a\x9e\x48\xca\x13\xcf\xe1\x89\xb5\x29\xcc\x12\xc9\xbc\x8d\x2b\x22\xb3\x78\xa2\x57\x5a\xac\x8c\x08\x53\x26\x0e\x44\xa7\x4c\xe2\x31\x3b\x97\x06\xa4\x88\xa0\x26\x24\x39\x3f\x8a\x93\x26\xbd\x09\x9f\x84\xfa\x3c\x89\xb7\x3c\xf9\x72\xc0\x6a\x9c\x76\x38\xf2\x00\xb5\xb5\xc8\x8a\xd5\xe0\x09\x72\x55\xa4\x2b\x4e\xa9\xe6\xb5\xb9\xcc\x9d\xde\xea\x12\x73\xb4\xdd\x69\xa4\x63\x5b\xab\x5b\xb8\x73\x68\x7d\x71\xc2\xc7\xa1\xd8\x84\x4f\x38\x1b\xea\xd2\xfc\x0c\x13\xd4\xfe\x34\xeb\x47\x61\xc6\x37\xbb\x0b\xcb\xd8\xa1\x96\x95\x88\x58\x9c\x8c\x40\x94\x1b\x38\xff\x9b\xd7\xa8\x0a\x67\x7a\xab\xca\x8c\xd1\x66\x65\x4b\x6c\x73\x39\x73\x6f\xd0\x05\xb7\x10\x3c\x86\xbe\x51\x62\x06\x48\x63\x5c\x0d\xa2\x91\x71\xf0\x1e\xf4\x91\x43\x3d\xf2\x3b\x9b\xe0\xa9\x86\x47\x5f\xe2\x3d\x6d\xf1\x7f\x13\xd5\x1b\x27\xde\x1c\x86\x4c\xbc\xa5\xc8\xe1\x2e\xda\x4a\xf0\x40\xba\x8a\x33\x7e\x94\xe6\xde\x5f\x6b\xac\x12\x59\x80\x9a\x47\xe0\xc4\xee\xfd\xc5\x6c\x6e\xae\x2b\x8f\x30\x37\x9f\xa7\xd4\x12\x6f\xba\x4a\x8b\xac\x51\x85\x6e\x86\x07\x31\xee\xe0\x8d\xaa\xb5\xac\x86\x37\x5b\xd0\xd7\xc1\x3e\x0b\xc7\x5c\x0c\x37\x63\x89\x52\x99\x95\x0e\x1d\xf0\x7f\x5f\x65\x5f\x41\xe9\x56\x50\xb4\xbf\xb1\x27\x8a\xfb\xf7\xc0\xb9\x02\x7a\xb5\x98\x84\xa3\xae\xae\x2d\xca\xf5\xcd\x83\x31\xcf\x97\x36\xb3\x6e\x5d\x75\x3d\x5e\xf8\x19\xa6\x3a\x29\xbd\x97\x11\x94\xf9\x68\xa6\xdd\x75\x68\x8b\x5e\x2d\xcc\xda\x5f\x99\x67\xe6\x28\x69\xf6\x87\xaa\xbb\x48\x9b\x95\x63\x49\xfb\xed\x67\xe2\x54\xd0\xd3\x4c\xc4\x55\x11\xb8\x51\x5e\x18\xc0\x49\xe2\xf1\x94\x53\x72\x44\xde\xe7\xac\xcd\x0e\x59\x9e\x75\x2f\xfc\x58\x81\x25\x0b\x3e\x01\xb0\xb9\x2f\x40\xa4\x5c\x41\x7d\x77\x5f\xca\xf7\x4a\xd4\x77\x4b\x25\xad\x6e\xd0\x67\x25\x8d\x1f\x0f\x53\xdc\x09\x9a\xaa\x14\x27\x72\x51\x71\x62\x3a\xf4\x10\x95\x9c\x8e\x65\xfb\x70\x03\x0e\x38\xfc\x2f\xb2\x4b\xf0\x60\xa0\x81\x8b\x41\x6c\x43\x24\x08\x3f\x06\x1a\x1e\x23\x32\x94\xa0\x07\x24\x64\x19\x8e\xa7\x87\x46\x69\x7a\x75\x53\xd5\xa8\xe9\x5e\xf6\x2c\xf7\x49\x3d\x1c\x61\x43\x49\xc4\x61\xaf\x12\x54\x0a\xd7\x70\x42\xd8\x40\x31\xf5\xf6\x78\x28\x9e\x47\x52\x0a\xba\x08\xdb\x02\x49\x27\xed\x9c\x50\xf0\x04\x49\x8e\x0b\x6c\x11\xb4\x58\xc7\xe7\xeb\xf5\x17\xe4\xd4\xd2\x3b\xf0\x98\xd1\x54\xb9\xda\x41\x78\x32\x6e\x0a\xe3\xf4\x64\x30\x0d\xa3\xc8\xa7\x8e\x6c\x18\xce\x3f\xb0\x51\x27\x7e\x6f\x5f\x9e\x1a\xb7\xc6\x21\x41\x0f\xb1\x66\xe7\xcb\xda\x45\x0a\x8e\x42\x1c\x8e\x57\x82\x99\x17\xba\x9e\x01\x52\x30\x96\x24\x99\x5a\x00\x3f\x70\x0d\x69\x0c\xcb\x27\xee\xc1\xc0\x15\x12\x1e\x43\xd1\x39\xe5\xf3\x1f\x43\x36\x79\x40\xcf\xc0\x2a\x7d\x5c\xcf\xf2\x74\x43\x24\x6c\x15\x93\xdf\xe3\x5c\x62\x5f\x56\x5e\x83\x6a\x94\x90\x58\x35\x3f\x90\x1d\xd4\xe1\xe5\x20\x13\xa9\xaf\xfe\x8e\xdf\x29\xcb\xf3\x0f\xdf\xbe\x8f\x56\xa7\xd3\x69\x78\xd5\x6f\x37\x3e\xea\xb7\x13\xdf\xf4\x4b\x3f\x7c\xfb\x73\xec\x47\xf1\x22\xc8\xbd\xf5\x82\xfe\x17\xfa\xb1\x17\xfa\xf1\x4f\x6b\x9c\xbe\xce\x23\x3f\xf6\x22\x3f\xfe\x89\x82\xfd\x15\x78\x8a\xcf\x2c\xf4\xbf\xc1\xda\x46\xfe\x96\xd4\x36\xf4\x63\x5c\xd3\x9f\x56\xf8\x7b\x9d\xe3\x2a\x2e\x70\x35\x49\xfe\x2e\x5f\x7b\xe4\x3f\x6b\x75\xb3\x32\xcd\x8e\x49\x57\x35\x2d\x30\xea\x98\xde\xa9\x1a\x86\x9f\x58\x1e\x7f\x0c\x83\x0d\x1c\x46\x87\xbf\x84\xf4\x5e\x79\xf8\xe8\xbd\xfa\xc4\x02\xc8\xed\x22\xcf\x6e\xe4\x94\x6f\xf6\x57\x3c\xaf\xe4\xa7\x9f\xc9\x29\x93\x80\x9f\x32\xe1\x1b\xf7\xa3\xf6\xaf\xc6\x77\x97\x1a\x35\x81\xd0\xc7\xdf\xa4\xa3\xe3\x1a\x96\x1d\x39\x73\x51\xf7\x3c\x06\x3e\x9b\x7d\xde\xbd\x1c\x4b\x8f\x9f\x04\xb6\xc8\x93\x7c\x1a\x0f\x03\x4d\x0c\xc8\x73\x63\x65\x19\x04\x6b\x9b\xdc\x8d\x80\xdc\xfe\x43\x56\xff\x98\xd4\x24\x14\x92\x49\xa7\x70\x33\xf3\xd0\xa3\xb8\x79\x86\xb6\x1f\xf7\x33\x06\xb5\xc1\x32\x8b\x84\xed\x15\x4f\x2c\x68\x33\x5f\x50\x58\xb8\xb6\x26\x33\x7b\x8f\x4a\xfb\xd6\x55\xc2\xfc\xad\xa9\xba\xa4\x43\xdf\x85\xdd\xb5\x29\x1f\xa4\x90\x6f\x33\x4a\xf9\x0a\xac\x6d\x58\x16\x5c\x6c\xf2\x5b\x89\x2a\x4f\x2a\x44\x2b\xcb\x97\xf3\x69\x4c\x7b\xa2\x17\xd2\xa2\x98\x98\x61\x89\x67\x1a\x0b\x2e\xc5\x18\x5b\x4b\xe6\x18\x7b\x67\xb6\x80\x60\x0e\xd0\xaa\x10\xbc\xb6\x00\xb6\x04\xc4\x43\x71\xcc\xa3\x8e\x50\x61\x6b\xb4\x73\x53\x3d\xdf\x82\xf7\xda\xf1\xdf\xe0\xe1\x35\x0e\xde\x0b\x8a\x08\xb5\x9d\x7b\x61\x5f\x2a\xf2\xa5\x1a\x50\x1d\x32\x8e\xd7\x06\xb7\x10\xd9\xf9\x02\x9a\x69\x9c\xe2\x9a\x1b\x0c\xf3\xe7\xda\x5c\x46\x58\xb9\xba\xe6\xa6\x7a\xf5\xe9\xf4\xf2\x90\xb4\x08\xa3\xb8\xc1\x6f\x20\x8c\x8f\xdc\xf3\x02\x5d\x55\xab\xb0\x5d\x55\xeb\x70\x45\x96\xa6\xb9\x86\x96\xa6\xea\xd0\x6c\x21\x57\x81\xa6\xa9\x00\x0f\x63\x4b\x68\xbc\x8c\x59\x86\x72\x50\x05\x58\xba\x58\xe2\x70\x1e\xee\xa5\x9b\x62\x67\x09\xe0\x89\x00\x3f\xc6\x8f\x3e\xcb\x0f\x0d\x2c\xd9\xed\x1f\x0d\x54\x4f\xa7\xd3\x55\xd3\x6b\x04\x0a\x9f\xe3\xe5\x6f\xd3\x4b\x01\x2a\xa7\xc0\x83\x01\x67\xf5\xb5\x00\x81\x2b\x15\x1c\xca\x31\x71\x4c\x9f\x15\x50\x39\x66\x77\xac\x4d\xc1\xfe\x35\x7e\xd5\x98\xff\x67\x39\xe0\xbf\xc8\x91\x04\xaa\xa7\x9b\xf8\xa4\xaf\x02\x28\x7c\x92\x8b\xcc\xa6\x88\xfd\x2a\x93\x72\xe0\xfe\xb3\x10\xb5\x5f\x60\x43\x00\x52\x12\x8d\x8c\x91\xa0\xfe\x0a\x63\xfc\xaa\xb0\x29\xe4\xbe\xca\x9b\x16\x79\xff\x2c\x87\xdd\x17\x98\x91\x41\xf5\x74\x13\x9f\x34\x30\xbf\xc2\x27\xbb\x8f\x6b\x0a\x9a\xaf\xb2\xa9\xc6\xce\x3f\x4b\x81\xf3\x05\x66\x24\x40\x2d\xd9\xc4\x22\x8d\xad\xaf\xb0\x48\xef\xbc\x9a\x02\x2a\xaa\x1c\x2a\xd1\xef\xcf\x62\xe8\x7b\x81\x11\x11\x4c\x4d\x35\x0a\x90\x04\xc6\xd7\x04\xd8\x7c\x02\x60\x69\xd8\x7a\x5d\x7c\x62\xf4\xfa\xb3\x10\xba\x5e\x92\xd1\x00\xa4\x24\x1a\x35\x90\x44\xb6\x57\x35\xf0\x92\x75\x08\xd4\xbf\x93\x02\x29\x4c\x60\x74\x78\xc0\xce\xb0\xa9\x96\x76\xe4\x81\x1d\xef\xd6\x41\x95\x27\x28\x9d\x8a\xd0\x95\x1d\x69\xd2\xe5\x52\x0c\x7a\x70\xd2\xa9\x20\xd9\xfb\x11\x7e\x3b\x15\x0a\xb8\x10\x02\xb8\xd2\x03\x00\x0d\x8b\x63\xaa\xe6\x08\xc6\x5c\x40\x63\xc5\x46\x48\xee\x24\x1a\xaa\x32\x02\x52\x37\x10\x00\x1b\xac\xa7\x12\xc0\x44\xb1\x9c\x1c\x5c\x30\x62\x52\x01\xcd\x80\x0d\x05\xb8\x0d\x91\xc0\x35\xfb\xc1\xc1\xe9\x50\x2e\xdf\x49\x56\x87\x71\x0e\x3b\x8c\xae\x12\xb8\x36\xb2\x72\x70\x3e\xc8\x49\xd0\xda\x00\x37\x88\x4f\xd4\x3c\xd3\x58\x33\xa2\x6e\x3e\x29\xb0\x5a\xd7\x1f\xb8\xa6\x3d\x52\xe1\x59\x92\x35\xe9\x79\x28\xc5\xd3\x42\xf5\x54\x5a\x83\x0a\x00\x52\x03\x8b\x61\x38\xdb\x2b\xb0\xe6\x42\x6c\x59\xda\x80\x03\x88\x29\x05\x21\xe1\x4f\x68\x4b\x48\xa7\x63\xb9\xba\xa0\x12\x3b\xad\x31\xac\x16\x84\x48\x2c\xe8\x2e\x8e\xfc\xac\x8a\x7b\x65\x80\x3c\x66\xcd\x31\x47\x37\xcd\xcf\x80\x60\xc9\xd3\x5b\x2a\xa4\x01\x6f\xa0\xbe\x86\x2a\x02\x91\xad\xb2\x53\xd6\xcf\xd9\x47\x4b\xbd\xb2\x2a\xe5\x4b\xcc\x22\xca\xd4\xa3\x7e\x98\xe2\x96\x41\x20\xd4\x55\x03\xfd\x37\x19\x5c\x86\x03\x00\x3a\xe9\x16\x29\xf9\x02\x00\x3c\xd1\x5b\x1c\x52\x20\xc0\x23\xca\x73\x05\x12\x27\xc9\xa0\xa7\x1c\xf5\xd2\x65\x28\xb0\x8e\x12\x94\x90\x26\x00\x9b\xef\x01\xe1\x6e\x3d\x25\xee\xb6\x70\x91\xf8\x00\xe5\x2c\xf4\xb6\x98\x96\x7b\x5b\x4c\x8b\x9e\xc3\xb8\x48\x7f\x80\x75\x6a\x80\xb6\x98\x6a\x83\xb1\xd6\x0e\xcd\x60\x89\x2d\x9a\x7a\xc5\xa4\xda\x17\x4e\x9a\x5f\xcc\x56\xfe\xc2\x41\xff\x0b\x87\x2e\x50\xcc\xe8\x05\xc5\xac\x8e\x50\x4c\xf6\x85\x62\x4e\x77\xb0\xdc\xe0\xc2\x03\xea\x54\x3b\xe4\x67\x97\x76\x18\xa0\x9c\xdb\x21\x3f\x4f\xb7\x43\x7e\x9e\x6e\x07\x0e\xe3\xd2\x0e\x03\xac\x53\x3b\xe4\xe7\xa9\x76\x18\x6b\x7d\x5f\x3b\x0c\x77\xe1\x52\xaf\xcf\xa7\x1a\xa2\xcf\x5d\x1a\x62\x80\x72\x6e\x88\x3e\x9f\x6e\x88\x3e\x9f\x6e\x08\x0e\xe3\xd2\x10\x03\xac\x53\x43\xf4\xf9\x54\x43\x8c\xb5\x9e\xd1\x10\x75\x93\x95\x1d\x96\x3d\xf9\x31\x25\x7e\x0a\xe4\xd0\x02\x22\xa0\x73\x23\xd0\x42\x93\xed\x40\xc1\x26\x9b\x42\x00\x73\x69\x0d\x11\xdc\xa9\x41\x68\x81\x89\x36\x91\xe4\xe0\xd2\x2c\x3e\x2a\x0e\x78\x76\x8a\xda\xba\x2a\xdb\xec\x33\xf4\x6a\x2a\x78\x4e\x91\x5c\xfa\x1f\x22\x05\x69\x67\x9c\x54\xb4\x70\x88\x06\x71\x4e\xa6\x96\x58\x68\x29\xe4\xd0\xc1\x52\x07\x24\x09\x40\x7a\x46\x16\xe7\x81\x8c\xea\xf0\x17\x74\xec\x80\x8c\xcf\x59\x8a\xaa\xe9\x93\x11\xd2\xb5\x35\x2d\x24\x0b\x77\x8e\xf5\x2a\x79\x51\x78\x78\x79\x1c\xce\x87\x0a\x5b\x4f\xeb\xc8\xdf\xc5\xdb\x70\xbd\x7a\x0f\x94\x0a\x37\x86\x52\xf1\xc6\x8f\x62\xa8\xc4\xfa\xf0\xb2\x82\x0a\x6c\x41\xe8\xf0\xf0\x12\x42\xd0\x74\x8b\x9e\xdc\x75\xc7\x0a\xad\x87\x04\x16\x75\x8f\xe4\xd2\xb8\x10\x70\x94\x0c\x0d\xb8\xa9\x9e\xbd\x06\x7d\x46\x4d\xab\xc5\xd5\x10\xb2\x0c\x34\x4c\x25\xe5\x5c\xad\xf0\x73\x93\xd4\x37\xf9\xbe\xbf\x06\x43\x5f\x0f\x12\xa0\x68\x02\x88\x4b\x66\x63\xc0\x69\xa4\x7f\xc2\x5e\x8f\x14\xa5\x40\x03\x21\x1b\x24\xc1\x6d\xf8\x2d\x7b\x3b\x23\x48\x28\x80\x84\x1a\x08\x0d\xdd\xc2\xf1\xf0\x40\x2e\x26\xb0\x50\x02\x93\xb0\x29\xdb\xed\x34\x22\xc5\x0d\x0c\x88\x40\xb2\x6c\x65\x51\x99\xc2\x25\x51\x99\xda\xca\xd1\x9d\x56\xad\x28\x4d\xb6\x15\x64\x21\x32\xb4\x92\x52\x00\x0d\x1b\x82\x84\xb8\xa0\x86\xf2\x34\x53\xdf\xcf\x21\x67\xa3\x98\xa0\xe0\x88\x1e\xa6\x32\x58\x40\x5a\x09\x64\xa6\xc1\x04\xa3\x1f\xc9\x32\x15\x18\xf6\xd5\xc4\x22\x3c\xd1\x5c\x93\x06\x75\xc7\x8b\x54\x86\xa5\xe9\x45\x64\x3d\x91\xd2\xac\x02\x10\x75\x04\x28\x05\x0a\x41\xd1\x0f\xb9\x98\x49\x10\xaa\x6e\xc8\xa5\x8c\x9a\x21\x17\x66\x7a\x01\x95\x35\x69\xc5\x28\x18\x51\x9a\x43\x59\x93\x3c\x5b\x94\x9f\xc8\xf9\xf2\xdb\xf8\xbd\x57\x07\x0e\x01\x54\x94\x3b\x81\xb5\x09\x9d\x94\x18\x25\x3e\xc2\x83\xe2\x26\xd0\x92\xac\x49\x01\x93\xa0\x09\xb8\xa2\x70\xa4\x80\x59\xdf\x58\x0d\x44\x01\x91\x12\xba\x74\xcc\xeb\x0d\xb4\xbe\x85\xab\xc9\x6a\x8b\x79\x56\x8b\x62\xbe\xc7\x70\x0d\x94\xee\xb4\x5d\x6d\xe1\x64\xbe\xc8\x6a\x8b\x9b\x05\x63\x18\xe7\x1a\xb1\xb6\x70\xb1\x63\x6d\xe1\x62\xca\x38\xd4\x84\x35\x2b\x9c\x0d\x5a\x71\x8f\x4d\x2b\xde\x64\xd6\xda\xe2\x6e\xcb\x86\x75\xe2\x5e\xe3\xd6\x16\x6f\xb7\x6f\x6d\xf1\x26\x13\x57\xdc\x65\xe5\x98\xbc\xe6\x18\xba\x51\x4e\xee\xb6\x0e\xcb\xe7\x2e\x73\x57\xdc\x69\xf1\x8a\xbb\x8d\x9e\x24\x11\x77\xbb\xa7\x4a\xc5\xd5\xf4\x09\x9a\x73\x97\xf5\x1b\xb5\xe6\x2e\x03\xa8\xca\xd7\xcd\x06\x62\xa2\x33\xcc\x60\x71\x87\x25\x94\x9a\xc1\xc5\x18\xaa\x0d\x30\x6d\x0f\x75\xa5\x74\x32\x89\xaa\xc8\x0c\x56\xd1\xb2\xfc\x4b\x6a\x52\xa4\xae\x66\xb1\x48\xe7\x99\x45\x8a\xf9\x1e\xb3\x38\x50\xba\xd3\x2c\x16\xa9\x93\x59\x24\x8b\xdf\x6e\x66\x91\x61\x9c\x6b\x16\x8b\xd4\xc5\x2c\x16\xa9\x8b\x59\xe4\x50\x76\xb3\x58\xa4\xae\x66\x71\x84\x9c\x61\x16\x71\xa1\x37\x98\xc5\x22\xbd\xdb\x2c\x62\x9d\xb8\xd7\x2c\x16\xe9\xdb\xcd\x62\x91\xbe\xc5\x2c\x0e\x72\x9b\x67\x16\x99\xbc\xe6\x98\xc5\x51\x4e\xee\x66\x11\xcb\xe7\x1e\xb3\x48\x6a\x75\x87\x59\x54\xa4\x31\xc7\x2c\x4a\x12\x71\x37\x8b\xaa\x54\x5c\xcd\xa2\xa0\x39\x77\x99\xc5\x51\x6b\xee\x31\x8b\x9a\x7c\xdd\xcc\x22\x26\xea\x6e\x16\x95\xc6\x70\x33\x8b\x52\x33\xb8\x98\x45\xb5\x01\xa6\xcd\xa2\xae\x94\x2e\x66\x51\x13\x99\xbb\x59\xe4\xbb\x71\xa4\x26\xf9\xd9\xd5\x2c\xe6\xe7\x79\x66\x91\x62\xbe\xc7\x2c\x0e\x94\xee\x34\x8b\xf9\xd9\xc9\x2c\x92\xbd\x48\x37\xb3\xc8\x30\xce\x35\x8b\xf9\xd9\xc5\x2c\xe6\x67\x17\xb3\xc8\xa1\xec\x66\x31\x3f\xbb\x9a\xc5\x11\x72\x86\x59\xc4\x85\xde\x60\x16\xf3\xf3\xdd\x66\x31\x3f\xdf\x6f\x16\xf3\xf3\xdb\xcd\x62\x7e\x7e\x8b\x59\x1c\xe4\x36\xcf\x2c\x32\x79\xcd\x31\x8b\xa3\x9c\xdc\xcd\x22\x96\xcf\x3d\x66\x91\xd4\xea\x0e\xb3\xa8\x48\x63\x8e\x59\x94\x24\xe2\x6e\x16\x55\xa9\xb8\x9a\x45\x41\x73\xee\x32\x8b\xa3\xd6\xdc\x63\x16\x35\xf9\xba\x99\x45\x4c\xd4\xdd\x2c\x2a\x8d\xe1\x66\x16\xa5\x66\x70\x31\x8b\x6a\x03\x4c\x9b\x45\x5d\x29\x5d\xcc\xa2\x26\x32\x77\xb3\x38\x1c\x8e\x20\x55\xe9\x73\x57\xbb\xd8\xe7\xf3\xec\x22\xc5\x7c\x8f\x5d\x1c\x28\xdd\x69\x17\xfb\xdc\xc9\x2e\x92\xa3\x21\x6e\x76\x91\x61\x9c\x6b\x17\xfb\xdc\xc5\x2e\xf6\xb9\x8b\x5d\xe4\x50\x76\xbb\xd8\xe7\xae\x76\x71\x84\x9c\x61\x17\xfb\xfc\x4d\x76\xb1\xcf\xef\xb6\x8b\x58\x27\xee\xb5\x8b\x7d\xfe\x76\xbb\xd8\xe7\x6f\xb1\x8b\x83\xdc\xe6\xd9\x45\x26\xaf\x39\x76\x71\x94\x93\xbb\x5d\xc4\xf2\xb9\xc7\x2e\x92\x5a\xdd\x61\x17\x15\x69\xcc\xb1\x8b\x92\x44\xdc\xed\xa2\x2a\x15\x57\xbb\x28\x68\xce\x5d\x76\x71\xd4\x9a\x7b\xec\xa2\x26\x5f\x37\xbb\x88\x89\xba\xdb\x45\xa5\x31\xdc\xec\xa2\xd4\x0c\x2e\x76\x51\x6d\x80\x69\xbb\xa8\x2b\xa5\x8b\x5d\xd4\x44\x66\xb2\x8b\x3e\x09\x9d\x44\x8f\xcb\x8f\x51\x94\xe4\x51\x12\x03\xd0\x33\xfd\xc2\xab\x71\x3a\x08\x39\xe0\x46\x21\x94\xe3\x6d\xb6\x1d\x4c\x5c\xb2\x2d\xa6\x19\x68\x0b\x17\x1e\xf8\xf9\x6b\x90\x0d\xeb\x92\x31\x2e\x5d\xa4\xd3\x7c\x14\xa9\x0b\x1f\xfc\xfc\xb1\x2b\x1f\xa3\x8f\x4e\x5a\xe3\x3c\xcd\x07\x76\xb7\xa7\xf9\xe0\xe7\x6f\x5d\xf9\x10\x26\x45\xb8\x78\x9f\x4f\x33\x82\xe7\x37\xd3\x8c\xf0\xf3\xa7\x30\x23\xfe\xf0\xa0\x12\xe9\xb1\xc3\x11\x3b\xb5\xbf\x0e\x60\xf4\xec\x9d\xfa\x56\x99\x08\xca\x4f\xb6\xb1\x07\xaf\xc6\x93\x6e\xf4\x1b\x04\xe5\xc7\x00\xf5\x83\x81\x20\x38\x3f\x33\xa7\x9f\xa2\x03\xc1\xc9\xd3\x3c\xca\x4b\x3d\x06\x8e\xb3\xe3\x27\xe1\xcd\x17\x7e\x61\x9d\xa6\x8f\x45\x9e\x84\x3a\xc9\x39\xaf\x3e\xc1\x4e\xee\xf3\xb0\xa0\xe9\x34\x81\xdf\xaf\x19\xb3\x95\x97\x83\x78\x88\x12\x2d\x1c\xf6\x4a\xc1\x31\xc6\xfa\xff\xc7\xf6\x5a\x63\xba\xed\xe2\xbb\xef\x0c\x3c\x3f\x2c\xaa\x66\xf1\x9d\xc2\xee\xc3\xc3\xcd\xa7\xbf\x64\x46\xe4\xa2\x6a\x25\xd9\x01\xc5\x91\xb1\x28\x78\x7d\xf5\xdb\xc6\xab\xca\xfc\x05\x38\xcf\x38\xbe\x30\xcf\x0f\x2e\x0a\x81\xc5\x83\xf1\xbd\x1e\xe0\xa1\x45\x12\x74\x04\xcf\xb5\x59\x2c\xc4\xe0\x41\x89\x40\x4d\xde\xd0\x19\xcf\x40\x32\x26\x3c\x72\xb5\x93\xbc\x46\x45\x23\x7a\x2c\x81\x1c\xf2\x4b\x55\x4a\xf1\xa1\x3a\xc6\x2d\xf9\x3d\x30\x46\x42\xd2\xe5\x88\x72\x46\x43\xb2\x68\x21\xb1\x5f\x7d\x1a\x82\x9b\x5e\x31\x13\xdf\x6d\x0c\x59\x18\xf5\x48\x7b\xb8\x31\xd8\xc6\x0f\xa2\xf6\xd0\x32\x4a\x71\x52\x2a\xd4\xde\x7c\x84\x4a\xd2\x8b\x54\x42\x61\x52\x6c\xa5\x95\x05\xc9\xd2\x81\x42\x28\xae\x1e\x96\x7e\xf6\xa2\x98\x05\x55\x88\xe2\xf7\x72\x4e\x1c\xdc\xf8\xe3\x3b\x4a\xce\x96\x97\xd9\xaa\x65\xc2\x80\x17\x0a\x03\xb5\x14\x19\x8f\xc6\x66\x11\x33\x2f\x98\x0d\x1e\xad\x42\xc6\x79\xc1\x7c\x0c\x6f\x09\x29\x59\xdb\xa1\xd4\x56\x2d\x85\x39\x11\xce\xd7\xca\x99\x84\x15\x41\x2d\xc4\xdc\x82\xd6\x42\x78\xea\x46\x29\x5e\x5c\x06\x00\x03\x01\x6c\x04\x3e\x33\x34\xa3\x3d\x08\x82\xcf\xcf\x1a\xd4\x65\x80\x12\x9f\x10\x13\xc1\x3e\x2b\x52\x95\x91\x7c\x56\x6b\x2a\x17\x66\xd3\x14\x94\x7a\x39\xf6\xc4\xe8\x65\x37\xd3\x49\xe5\xc9\x98\x4a\xe0\x7b\x6d\x47\x21\xc6\xac\x7a\x21\x5a\xb8\x2d\xfd\xea\x17\x5e\xc0\x1f\x99\x92\x7c\xc7\xa2\xf3\x82\xa5\x5f\xbc\x0c\xd9\xfa\x05\xe0\xa2\x21\x20\xfd\x08\x02\x5c\xfe\x2d\x0e\x2a\x1e\xe8\xde\x6f\x91\xab\xa8\xf4\x4b\xbf\x85\x17\xca\xcf\x61\x29\xec\x86\x84\x4c\x28\x85\x6a\xd6\xe1\x1a\x02\xd7\x8f\x70\x43\x38\x1c\x15\xf2\xa0\x62\xe4\xf1\xdb\x75\xd0\x5c\x45\x4a\xe3\x84\xeb\x80\x5e\x74\x13\x1f\xe8\x54\x6a\x10\x11\x7a\x91\x16\x6c\x5a\xa9\x40\x44\x68\x45\x40\x9c\x5f\x85\x7f\x05\x9f\x18\x7f\x5e\x61\x5f\x41\x39\x86\x39\x97\xb9\x5f\x71\xee\x43\x9d\xf9\x15\x21\xb6\x12\x99\xd7\xa0\x1a\x02\xd5\x8f\x50\xcd\x10\x2d\x46\x61\x5d\xc1\xc6\xaf\xc1\xeb\x9c\x2b\x08\xe9\xc5\x77\x8d\xf1\xf5\xc0\x38\x24\xf7\x35\x21\xb6\x96\x58\x87\x04\xbf\x26\xb4\xd6\x0a\xf3\x90\xe4\x15\x8c\x9c\x7d\x48\xf4\x0a\x52\x5a\x01\x40\xf6\x31\xaf\x82\x7a\x63\xb7\xe8\xbc\x98\x90\x8b\xc5\x0a\x68\x50\x0d\x81\xea\x47\x28\x16\xcf\x4c\x67\x5e\xc1\xc6\x98\xd7\x00\x73\x15\x21\x8d\x87\xa6\x80\xd5\x5e\x30\xbe\x04\x23\x65\x90\x01\xa6\x7e\x19\xf3\xf5\x11\xa6\x26\x23\x4c\xdd\x0b\x30\xc0\x10\x53\x1f\x34\x4c\xd0\x18\x53\xe7\x1a\x32\x7d\x90\xa9\xbd\xf0\x26\xbf\xca\xa2\xf0\x1c\x12\x4a\xa1\xc4\x33\x00\x48\x86\x99\xba\x17\x00\x4d\xe3\x4c\x7d\xd0\x70\x1a\x07\x9a\x3a\xd7\xd0\x1a\x46\x9a\xda\x8b\xe4\x18\xca\x4a\x35\x22\x42\x32\x92\xab\x01\xd4\x22\x22\xe4\x22\xb5\x16\x40\x25\x54\x8c\xa6\xd1\xa6\xce\x35\xa4\xf0\x70\x53\x7b\x2b\xe9\xe9\x49\xa5\x06\x2b\x42\x6f\x25\xdf\x72\xd1\x2b\xb0\x22\xb4\x56\x4a\x05\x34\xc0\x83\x86\xcf\x30\xe4\xd4\xb9\x86\x12\x1c\x73\x6a\x6f\x3d\x72\x0f\xb5\xc0\x9a\xd0\x5b\xcb\xfc\x43\x4d\xb0\x26\xe4\xd6\x6a\x0d\xa0\x36\x50\x71\x1a\xc7\x9d\x3a\xd7\xd0\x1a\x06\x9e\xda\x8b\x87\x7a\x68\x7d\x9b\x8c\x3c\xf5\xcb\x08\x02\x0e\x3d\x35\x19\x7a\xea\x5e\x00\x83\xc7\x9e\xfa\xa0\xe1\x33\x0c\x3e\x75\xae\xa1\x04\x47\x9f\xc2\x2b\x87\x49\x83\x07\xce\x1a\x4a\x6a\xe4\x4b\x69\xde\x00\x81\x36\x14\xb4\x17\x40\x59\xe0\x6d\x70\xee\xa0\xe1\x65\x35\x81\xa0\x73\x1d\x35\x7b\x2f\x00\x98\x41\x94\xd1\x58\x21\xa8\x3e\xd4\xe8\x97\x91\x5c\x1f\xa8\x3a\xd4\xe8\x97\x91\x5a\x1d\xa8\x36\x2a\xd6\xa1\x36\x50\x65\x54\xc4\xc2\xe3\x07\x4a\x5d\x86\x09\x85\x07\xcc\x28\x4a\x3a\x09\x28\xa5\x39\x85\x0e\xd8\x50\xc0\x5e\x00\xe4\x11\xd1\x81\x8a\xa8\x38\x79\x45\x80\xa9\x85\x86\x96\xd6\x43\x9f\x5d\x94\xeb\xb1\x1a\x60\x9b\xd0\xe9\x40\xb9\x96\x2b\x02\x36\x0a\x9d\x0e\x94\x6b\xb5\x2a\x60\xab\xa8\x78\x87\xca\x80\xcd\xa2\xa2\x66\xd5\x81\xda\x65\x98\x6c\x78\xc0\x6c\xa3\xa4\x13\x84\x52\x9a\x6f\xe8\x80\x0d\x05\xec\x05\x40\x56\x19\x60\xce\xa1\xe1\xe4\x55\x01\xa6\x1d\x1a\x5a\x5a\x11\xbd\xef\x13\x87\x92\x55\x44\x73\x28\x3b\x92\x4d\xa8\x0a\x70\xa4\x2e\x1a\x6c\xc3\x61\x7b\x09\xb6\x81\x5d\xd5\x03\x8c\x99\xd5\x48\x03\xcf\x61\xe4\xa4\x52\x0a\xb0\xe5\x85\x5e\xaf\xb5\x78\x72\x38\x8f\xf0\x23\x00\x81\xfe\x1c\x03\xec\x25\x40\xd8\xab\x03\x71\x1a\x7c\x3b\x10\x2d\xe4\xe1\xb5\x53\x4e\x1e\x06\xe0\x54\xa7\x5d\x3d\x06\xdd\x4b\xd0\x16\x87\x0f\xc4\x6e\x73\xfb\x40\x02\x46\xe7\xaf\x9d\xf0\xff\x70\x3e\x27\x3f\xe9\x05\x32\xe0\x5e\x02\x36\xfb\x82\x20\x6e\x8b\x47\x08\xa2\x37\xf9\x85\xad\xdd\x35\xc4\xd9\x9c\xf6\x94\x83\xc8\x60\x7b\x09\xd6\xe8\x26\x82\x98\xcd\xce\x22\x88\xdc\xe0\x32\xb6\x53\x5e\x23\x06\xe0\xb4\xa7\x7d\x47\x06\xdd\x4b\xd0\x16\x0f\x12\xc4\x6e\xf3\x23\x41\x02\x46\x6f\xb2\xb5\x3b\x94\x38\x9b\x53\x9f\x72\x2b\x19\x6c\x2f\xc1\x1a\x9d\x4b\x10\xb3\xd9\xc5\x04\x91\x1b\x1c\x4d\x32\xb8\x98\x7c\x4d\x3a\x04\xd5\x2f\x12\x14\xe8\x71\x32\xc8\x5e\x86\x84\xfd\x4e\x18\xab\xc1\xfb\x84\x11\x43\x3e\x28\x19\x4d\xac\x6e\x28\x1d\x78\xea\x17\x09\xd4\xec\x8c\x32\xf0\x5e\x06\xb7\xb8\xa4\x30\x7e\x9b\x63\x0a\x93\x30\xba\xa7\x64\x58\xb1\x79\xa8\x74\x00\xaa\x5f\x24\x48\xa3\x9f\xca\xa0\x7b\x19\xda\xec\xad\xc2\xd8\x2d\x3e\x2b\x4c\xc0\xe4\xb9\x92\xf1\xc5\xe2\xbc\xd2\x81\xa8\x7e\x91\x00\x4d\x2e\x2c\x03\xee\x65\x60\xa3\x23\x0b\xe3\x36\xbb\xb3\x30\x7a\x83\x53\x4b\x06\x17\xab\x5f\x4b\xc7\xa1\xfa\x45\x02\x35\x7b\xb7\x0c\xbc\x97\xc1\x2d\x3e\x2e\x8c\xdf\xe6\xe9\xc2\x24\x8c\xfe\x2e\x19\x69\x2c\x2e\x2f\x1d\x92\xea\x17\x09\xd0\xe4\xf8\x32\xe0\x5e\x06\x36\xba\xbf\x30\x6e\xb3\x13\x0c\xa3\x37\xb8\xc2\xed\xb4\x37\x4c\x40\xf8\xf0\xec\xe2\x13\xf3\x02\xbd\x5c\xc0\xe6\x19\x1b\x68\x58\xfd\x63\x03\x19\xb3\x97\xdc\x4e\x3a\xca\x04\x62\x60\x63\xda\x5d\xe6\xf0\xbd\x0c\x6f\x71\x9a\x0d\x14\x6c\xae\xb3\x81\x88\xd1\x81\x6e\xa7\x7c\x68\x02\x30\xf0\x30\xe9\x49\x73\xf0\x5e\x06\x37\xfb\xd3\x06\xfc\x16\xaf\xda\x40\xc2\xe4\x5b\xb7\xd3\xee\x35\x01\x19\x78\x70\x70\xb2\x79\x81\x5e\x2e\x60\x73\xb5\x0d\x34\xac\x0e\xb7\x81\x8c\xd9\xed\x6e\xa7\x3c\x6f\x02\x30\x70\x31\xe9\x7f\x73\xf0\x5e\x06\x37\x7b\xe1\x06\xfc\x16\x5f\xdc\x40\xc2\xe4\x91\xb7\x93\x4e\x39\x83\xe0\x4c\x38\xb8\xe6\x63\x89\x5e\x2d\x61\x74\xd0\x2d\x54\xcc\x6e\xba\x85\x10\xe4\xac\x5b\x4e\x63\x15\x5e\x91\x9a\xbd\x75\x9c\x47\x38\x13\x80\x40\x6f\x9d\x01\xf6\x12\x20\xec\xad\x83\x38\x0d\xde\x3a\x88\x16\xf2\xd6\x8b\x74\xc2\x5b\xc7\x00\x9c\xea\xb4\xb7\xce\xa0\x7b\x09\xda\xe2\xad\x83\xd8\x6d\xde\x3a\x48\xc0\xe8\xad\x17\xa9\xdd\x5b\xc7\xf9\x9c\xfc\xa4\xb7\xce\x80\x7b\x09\xd8\xec\xad\x83\xb8\x2d\xde\x3a\x88\xde\xe4\xad\x17\xa9\xd5\x5b\xc7\xd9\x9c\xf6\x94\xb7\xce\x60\x7b\x09\xd6\xe8\xad\x83\x98\xcd\xde\x3a\x88\xdc\xe0\xad\x17\xe9\x84\xb7\x8e\x01\x38\xed\x69\x6f\x9d\x41\xf7\x12\xb4\xc5\x5b\x07\xb1\xdb\xbc\x75\x90\x80\xd1\x5b\x2f\x52\xab\xb7\x8e\xb3\x39\xf5\x29\x6f\x9d\xc1\xf6\x12\xac\xd1\x5b\x07\x31\x9b\xbd\x75\x10\xb9\xc1\x5b\x27\x83\x8b\xc9\x5b\xa7\x43\x50\xfd\x22\x41\x81\xde\x3a\x83\xec\x65\x48\xd8\x5b\x87\xb1\x1a\xbc\x75\x18\x31\xe4\xad\x93\xd1\xc4\xea\xad\xd3\x81\xa7\x7e\x91\x40\xcd\xde\x3a\x03\xef\x65\x70\x8b\xb7\x0e\xe3\xb7\x79\xeb\x30\x09\xa3\xb7\x4e\x86\x15\x9b\xb7\x4e\x07\xa0\xfa\x45\x82\x34\x7a\xeb\x0c\xba\x97\xa1\xcd\xde\x3a\x8c\xdd\xe2\xad\xc3\x04\x4c\xde\x3a\x19\x5f\x2c\xde\x3a\x1d\x88\xea\x17\x09\xd0\xe4\xad\x33\xe0\x5e\x06\x36\x7a\xeb\x30\x6e\xb3\xb7\x0e\xa3\x37\x78\xeb\x64\x70\xb1\x7a\xeb\x74\x1c\xaa\x5f\x24\x50\xb3\xb7\xce\xc0\x7b\x19\xdc\xe2\xad\xc3\xf8\x6d\xde\x3a\x4c\xc2\xe8\xad\x93\x91\xc6\xe2\xad\xd3\x21\xa9\x7e\x91\x00\x4d\xde\x3a\x03\xee\x65\x60\xa3\xb7\x0e\xe3\x36\x7b\xeb\x30\x7a\x83\xb7\x5e\xa4\x93\xde\x3a\x01\xe1\xc3\xb3\x8b\xb7\xce\x0b\xf4\x72\x01\x9b\xb7\x6e\xa0\x61\xf5\xd6\x0d\x64\xcc\xde\x3a\x06\xb3\x7b\xeb\x04\x62\x60\x63\xda\x5b\xe7\xf0\xbd\x0c\x6f\xf1\xd6\x0d\x14\x6c\xde\xba\x81\x88\xd1\x5b\xc7\x50\x56\x6f\x9d\x00\x0c\x3c\x4c\x7a\xeb\x1c\xbc\x97\xc1\xcd\xde\xba\x01\xbf\xc5\x5b\x37\x90\x30\x79\xeb\x18\x68\xc2\x5b\x27\x20\x03\x0f\x0e\xde\x3a\x2f\xd0\xcb\x05\x6c\xde\xba\x81\x86\xd5\x5b\x37\x90\x31\x7b\xeb\x18\xcc\xea\xad\x13\x80\x81\x8b\x49\x6f\x9d\x83\xf7\x32\xb8\xd9\x5b\x37\xe0\xb7\x78\xeb\x06\x12\x26\x6f\x9d\xc7\x23\x31\x7b\xeb\x0c\x82\x33\xe1\xe0\xad\x8f\x25\x7a\xb5\x84\xd1\x5b\xb7\x50\x31\x7b\xeb\x16\x42\x8e\xde\x3a\xbf\xb3\x54\x78\xf9\xd9\xec\xad\xe3\x3c\xc2\x99\x00\x04\x7a\xeb\x0c\xb0\x97\x00\x61\x6f\x1d\xc4\x69\xf0\xd6\x41\xb4\x90\xb7\x9e\x9f\x27\xbc\x75\x0c\xc0\xa9\x4e\x7b\xeb\x0c\xba\x97\xa0\x2d\xde\x3a\x88\xdd\xe6\xad\x83\x04\x8c\xde\x7a\x7e\xb6\x7b\xeb\x38\x9f\x93\x9f\xf4\xd6\x19\x70\x2f\x01\x9b\xbd\x75\x10\xb7\xc5\x5b\x07\xd1\x9b\xbc\xf5\xfc\x6c\xf5\xd6\x71\x36\xa7\x3d\xe5\xad\x33\xd8\x5e\x82\x35\x7a\xeb\x20\x66\xb3\xb7\x0e\x22\x37\x78\xeb\xf9\x79\xc2\x5b\xc7\x00\x9c\xf6\xb4\xb7\xce\xa0\x7b\x09\xda\xe2\xad\x83\xd8\x6d\xde\x3a\x48\xc0\xe8\xad\xe7\x67\xab\xb7\x8e\xb3\x39\xf5\x29\x6f\x9d\xc1\xf6\x12\xac\xd1\x5b\x07\x31\x9b\xbd\x75\x10\xb9\xc1\x5b\x27\x83\x8b\xc9\x5b\xa7\x43\x50\xfd\x22\x41\x81\xde\x3a\x83\xec\x65\x48\xd8\x5b\x87\xb1\x1a\xbc\x75\x18\x31\xe4\xad\x93\xd1\xc4\xea\xad\xd3\x81\xa7\x7e\x91\x40\xcd\xde\x3a\x03\xef\x65\x70\x8b\xb7\x0e\xe3\xb7\x79\xeb\x30\x09\xa3\xb7\x4e\x86\x15\x9b\xb7\x4e\x07\xa0\xfa\x45\x82\x34\x7a\xeb\x0c\xba\x97\xa1\xcd\xde\x3a\x8c\xdd\xe2\xad\xc3\x04\x4c\xde\x3a\x19\x5f\x2c\xde\x3a\x1d\x88\xea\x17\x09\xd0\xe4\xad\x33\xe0\x5e\x06\x36\x7a\xeb\x30\x6e\xb3\xb7\x0e\xa3\x37\x78\xeb\x64\x70\xb1\x7a\xeb\x74\x1c\xaa\x5f\x24\x50\xb3\xb7\xce\xc0\x7b\x19\xdc\xe2\xad\xc3\xf8\x6d\xde\x3a\x4c\xc2\xe8\xad\x93\x91\xc6\xe2\xad\xd3\x21\xa9\x7e\x91\x00\x4d\xde\x3a\x03\xee\x65\x60\xa3\xb7\x0e\xe3\x36\x7b\xeb\x30\x7a\x83\xb7\x9e\x9f\x27\xbd\x75\x02\xc2\x87\x67\x17\x6f\x9d\x17\xe8\xe5\x02\x36\x6f\xdd\x40\xc3\xea\xad\x1b\xc8\x98\xbd\x75\x0c\x66\xf7\xd6\x09\xc4\xc0\xc6\xb4\xb7\xce\xe1\x7b\x19\xde\xe2\xad\x1b\x28\xd8\xbc\x75\x03\x11\xa3\xb7\x8e\xa1\xac\xde\x3a\x01\x18\x78\x98\xf4\xd6\x39\x78\x2f\x83\x9b\xbd\x75\x03\x7e\x8b\xb7\x6e\x20\x61\xf2\xd6\x31\xd0\x84\xb7\x4e\x40\x06\x1e\x1c\xbc\x75\x5e\xa0\x97\x0b\xd8\xbc\x75\x03\x0d\xab\xb7\x6e\x20\x63\xf6\xd6\x31\x98\xd5\x5b\x27\x00\x03\x17\x93\xde\x3a\x07\xef\x65\x70\xb3\xb7\x6e\xc0\x6f\xf1\xd6\x0d\x24\x4c\xde\x3a\x0f\x93\x66\xf6\xd6\x19\x04\x67\xc2\xc1\x5b\x1f\x4b\xf4\x6a\x09\xa3\xb7\x6e\xa1\x62\xf6\xd6\x2d\x84\x1c\xbd\xf5\x21\xb2\x47\xe1\xf5\xb9\xd9\x5d\xef\x73\xe6\x5a\x0b\x40\xa0\xbb\xde\xf3\x2b\xc9\x22\x20\xec\xae\x83\x38\x0d\xee\x3a\x88\x16\x72\xd7\xfb\x7c\xc2\x5d\xef\x73\xe6\x50\x0b\x90\x66\x77\xbd\xe7\x77\x94\x45\x68\x8b\xbb\x0e\x62\xb7\xb9\xeb\x20\x01\xa3\xbb\xde\xe7\x76\x77\xbd\xcf\x99\x4b\x2d\x00\x1a\xdd\xf5\x9e\x5f\x60\x16\x81\xcd\xee\x3a\x88\xdb\xe2\xae\x83\xe8\x4d\xee\x7a\x9f\x5b\xdd\xf5\x3e\x67\x4e\xb5\x00\x67\x72\xd7\x7b\x7e\xbb\x59\x84\x35\xba\xeb\x20\x66\xb3\xbb\x0e\x22\x37\xb8\xeb\x7d\x3e\xe1\xae\xf7\x39\x73\xa8\x05\x48\xb3\xbb\xde\xf3\x4b\xcf\x22\xb4\xc5\x5d\x07\xb1\xdb\xdc\x75\x90\x80\xd1\x5d\xef\x73\xab\xbb\xde\xe7\xcc\xa9\x16\xe0\x4c\xee\x7a\xcf\xef\x44\x8b\xb0\x46\x77\x1d\xc4\x6c\x76\xd7\x41\xe4\x06\x77\x9d\x0c\x2e\x26\x77\x9d\x0e\x41\xf5\x8b\x04\x05\xba\xeb\x3d\xbf\x32\x2d\x41\xc2\xee\x3a\x8c\xd5\xe0\xae\xc3\x88\x21\x77\x9d\x8c\x26\x56\x77\x9d\x0e\x3c\xf5\x8b\x04\x6a\x76\xd7\x7b\x7e\x87\x5a\x02\xb7\xb8\xeb\x30\x7e\x9b\xbb\x0e\x93\x30\xba\xeb\x64\x58\xb1\xb9\xeb\x74\x00\xaa\x5f\x24\x48\xa3\xbb\xde\xf3\x0b\xd6\x12\xb4\xd9\x5d\x87\xb1\x5b\xdc\x75\x98\x80\xc9\x5d\x27\xe3\x8b\xc5\x5d\xa7\x03\x51\xfd\x22\x01\x9a\xdc\xf5\x9e\xdf\xbe\x96\x80\x8d\xee\x3a\x8c\xdb\xec\xae\xc3\xe8\x0d\xee\x3a\x19\x5c\xac\xee\x3a\x1d\x87\xea\x17\x09\xd4\xec\xae\xf7\xfc\x52\xb6\x04\x6e\x71\xd7\x61\xfc\x36\x77\x1d\x26\x61\x74\xd7\xc9\x48\x63\x71\xd7\xe9\x90\x54\xbf\x48\x80\x26\x77\xbd\xe7\x77\xb6\x25\x60\xa3\xbb\x0e\xe3\x36\xbb\xeb\x30\x7a\x83\xbb\xde\xe7\x93\xee\x7a\x9f\x73\x57\x5a\x04\xb6\xb8\xeb\xfd\x70\x8d\x5b\x2a\x60\x73\xd7\x0d\x34\xac\xee\xba\x81\x8c\xd9\x5d\xc7\x60\x76\x77\xbd\xcf\xb9\x33\x2d\xc2\x9a\xdd\xf5\x7e\xb8\xe3\x2d\xc1\x5b\xdc\x75\x03\x05\x9b\xbb\x6e\x20\x62\x74\xd7\x31\x94\xd5\x5d\xef\x73\xee\x4e\x8b\xa0\x46\x77\xbd\x1f\x2e\x80\x4b\xe0\x66\x77\xdd\x80\xdf\xe2\xae\x1b\x48\x98\xdc\x75\x0c\x34\xe1\xae\xf7\x39\x77\xa5\x45\x60\x8b\xbb\xde\x0f\xf7\xc2\xa5\x02\x36\x77\xdd\x40\xc3\xea\xae\x1b\xc8\x98\xdd\x75\x0c\x66\x75\xd7\xfb\x9c\xbb\xd3\x22\xa8\xd1\x5d\xef\x87\x6b\xe3\x12\xb8\xd9\x5d\x37\xe0\xb7\xb8\xeb\x06\x12\x26\x77\x9d\x47\x6f\x35\xbb\xeb\x7d\x3e\x3a\xd2\x32\xb4\xc9\x5d\xef\x85\xbb\xe4\x4a\x09\xa3\xbb\x6e\xa1\x62\x76\xd7\x2d\x84\x40\x77\xdd\xef\x50\xdf\x79\x45\x55\x56\x24\x92\xdf\xed\x54\x95\x9d\x77\x4a\x8a\x2c\x7f\xd9\xff\xf2\xcf\x3f\x57\x65\xe5\xfd\x2b\x3a\x5f\xf3\xa4\x59\xfe\x8c\xca\xbc\x5a\xfe\x5c\x95\xc9\xb1\x5a\xfe\xa1\x2a\xdb\x2a\x4f\xda\xe5\xbb\x9f\xb2\x03\x6a\x92\x2e\xab\xca\x05\x06\x7f\xb7\x7c\xf7\x87\xea\xda\x64\xa8\x59\xfc\x19\x3d\xbf\x5b\x0e\xa8\x45\x46\x09\x51\x16\xc6\xf9\x46\x3e\x48\xac\xd8\x3d\x4b\xd2\x40\x49\x8c\x70\x3d\xe0\xa0\x06\xc7\xa2\x89\xeb\xb1\x12\x35\xc8\xae\xb9\x96\xc7\xa4\x43\x6a\x20\xcf\x27\x92\x3b\x24\xa2\x3c\xcf\xea\x36\x6b\x81\xf0\x8b\x0c\x11\x89\x52\x2a\x54\x41\x0d\x55\x4a\xb2\x68\x98\x52\x01\x4a\x8b\x55\x4a\xf2\x58\x80\x5e\x01\x4e\x0b\xd0\x6b\x0e\x34\x40\x4a\xf1\x78\xb6\x53\x0c\x0d\x31\x6d\x27\x79\x1a\x5f\x5f\xb3\xb1\x65\xb9\x52\x41\x15\x2c\x75\xe3\x6b\x88\x71\x3b\xc9\xd7\xf8\xfc\xcd\x4c\xbe\xf8\xe1\x11\xda\x7a\x67\x37\xbe\x86\x98\xb7\x93\x7c\x8d\xef\x0f\xcc\xe4\x6b\x58\x26\x23\xe5\x78\xfc\xdb\x29\xc6\x86\x18\xb8\x93\x8c\x8d\x01\xa0\xad\x8c\xb1\x5a\x54\xcf\xa8\x39\x26\x2d\xba\xb1\xde\x92\x94\xed\xa9\x6a\x8a\xfd\x90\xa1\xe1\xbf\xd6\x35\x5c\x64\xc8\xd0\xf5\x3d\xa9\xb3\x2e\xc9\xb3\xbf\x6a\x65\xc6\x1c\xb1\x10\x19\x9c\x9e\x49\xec\x46\x2f\xa7\x91\x7f\xc7\x94\xfd\x2a\x08\xac\xc0\xa8\x91\xc0\x59\x9a\xa9\x08\x1d\x61\xa4\x12\x6b\x33\x81\x43\x95\xa7\x12\xec\xd6\x0e\xab\xf0\x42\x93\xb4\x02\x44\x04\x47\x0a\xd9\x76\x2f\x39\xda\xd3\x14\x7d\x7c\xc4\xa3\xd3\x8d\x06\x91\xfc\xe6\x74\x3a\x69\x00\x75\x93\x15\x49\xf3\xc2\x41\x82\x60\x7b\x90\xa0\x12\x09\x8c\xc6\x88\x5d\x2a\x89\x17\x3c\x2a\x8e\x18\xe2\xcd\x61\xa5\x8f\x16\xe8\x58\x95\xa9\x40\x69\x73\xdc\xc6\xdb\x54\xa7\x34\x00\xca\xb4\xc6\x64\x89\xda\xfa\x71\x7d\x8a\xd7\x3a\xb5\xeb\xf1\x88\xda\x96\x43\x45\xbb\x64\xbb\x8e\x01\x5a\x14\x4c\xa1\xc4\x12\x25\x3a\xe1\xe3\xe6\x31\xd2\xc5\x9b\x95\xa7\x6a\x00\xd9\x26\xd1\x61\xa7\x13\xc1\x30\x32\x05\x92\x22\x0b\xed\xb4\xd9\x6c\xf5\x6a\x3c\x27\x4d\x99\x95\xe7\xb1\xfd\x8e\x61\xb0\xd5\x29\x30\x30\x99\x08\x4f\x94\xe8\x1c\x92\xdd\x41\xd6\x3f\x02\x9b\x26\xe5\x79\x04\x4a\x8f\xab\x18\x92\x16\x85\x92\xa9\xb0\x34\x89\x48\xb2\x0d\xd3\x28\xd1\xc7\x3f\xd2\x2f\x79\x55\x76\xa7\xc7\x53\xa2\xd3\x20\x40\x32\x09\x9a\x24\x51\x38\x1e\xd2\x55\xaa\x53\x48\x93\xe6\x13\x07\x59\xad\x57\xc9\x3a\x80\x2a\xd1\x7c\x52\xab\xd0\x7c\x52\x1a\x3b\x0a\xd7\xe1\x46\x43\x7f\xa8\xd2\x41\x7b\xa3\x30\x8a\xa3\x47\xdd\xf6\x5c\x3b\x94\x1a\x35\x9c\xa1\xc9\x93\xe3\x27\x2f\x0e\x18\x98\x18\x7c\x58\x0e\x3d\x3c\x76\xe0\x11\xfa\xd2\xe6\x04\xfa\xfd\x32\x0c\x82\xf7\x60\x89\x4b\x96\xd2\xd9\xda\x3e\xf8\x21\x58\x24\x4f\x5a\x04\x59\x3a\x93\x11\x02\x19\xeb\xf1\x66\xb3\x32\xeb\xb2\x24\x17\x02\x49\x53\x51\xa1\x63\x45\x67\x74\x34\x20\xb2\x92\xa8\x45\x45\xa6\xf5\x6d\x50\xf2\xe9\xf6\x5c\x35\x29\xfd\xb9\x27\xff\x7a\x38\x61\x84\x1d\xe2\x49\xd3\xa7\x5b\x20\x10\x3e\x63\x42\x2d\xe2\x6a\x94\x95\x17\xd4\x64\x92\x45\x63\xe1\xa8\x6f\xe4\x6f\x96\x67\xdd\x0b\x8f\x50\x2d\x42\x65\x25\x00\xa7\x05\x6c\x67\xa6\xb8\x6e\xb2\xb2\xbb\xfd\x6e\x49\xa3\xfe\x2e\xf7\x07\x74\xaa\x1a\x56\x79\x30\x1c\xf4\x93\x39\x50\x74\xb2\x2f\xab\xee\x3b\xff\xd0\x95\x0f\x9a\xf4\xae\x65\x8a\x9a\x3c\x2b\xd1\x6b\x72\x38\x34\xbf\x76\x59\x97\xa3\x8f\x2c\xd4\xf0\x10\x1c\x78\xf1\xdd\xbb\x45\xd2\x75\xcd\x77\x24\xfb\x61\xf1\xee\xe1\xdd\x6b\xdd\x20\x69\x66\x5b\x37\xc8\x53\xe6\xb6\x87\xbc\x3a\x7e\xfa\xbf\xd7\xaa\x43\x4b\x0c\xcd\xda\x35\xac\xfb\x45\x5b\xe5\x59\xba\xf8\x26\x49\x0f\xf1\x21\x7d\xaa\x93\x33\xa2\xcd\xe4\x65\x65\x9b\xa5\x68\x9f\x7c\xae\xb2\xf4\xb5\xbb\xa0\x24\xbd\xa5\x59\x5b\xe7\xc9\xcb\xbe\x4b\x0e\x39\xf2\x70\x12\x6a\x3c\xac\x38\xf5\x6b\x56\x9c\x97\x5d\x73\x33\x95\xbf\x44\xcb\xcb\x6a\x59\xdf\xaa\xa6\xbe\x24\x65\xbb\x5f\x3d\x3d\x67\x69\xf5\xdc\xee\x57\x34\x4b\x2c\x48\x6a\xcc\xca\xfd\x23\x4e\xbf\xb5\xd9\x5f\xd1\x3e\x59\xbd\xfa\x58\x0c\x49\x56\xa2\x66\x49\x3a\xa3\x32\x77\x13\x5b\xb8\x4c\x3e\x1f\x92\x66\xe0\x18\x37\xc3\xab\x7f\x48\xd2\x33\x54\xf9\x20\xc0\x1a\x8e\x2b\xc5\x32\x71\x37\xc8\x93\xba\x45\x7b\xfe\x43\xd2\x43\x0c\xb9\xe8\xd2\x25\xff\x75\xb9\x69\x3d\x48\x33\xb6\x44\x64\x14\x3b\x4a\xc7\xc2\x42\xd2\x05\xe0\x2c\x45\x28\x42\x1b\x1d\x91\x30\xd4\xb1\x4e\x20\xe6\x2c\x3a\x2c\x9e\xef\xc9\xbf\x4b\x29\x3d\x95\x3f\x2f\xca\x27\x4a\x04\x3e\x78\x4d\x28\x0f\xbc\xda\x3e\x81\xe2\x05\x64\x1e\x9e\xc0\x82\xaf\xff\xed\x1f\x7e\xf8\xdd\x37\x8b\xb6\xba\x36\x47\xf4\x73\x52\xd7\x59\x79\xfe\xf7\x7f\xfd\xe9\x43\xe4\xa7\xa7\x75\x74\x7c\xdc\xae\xfd\xe3\xe5\x5a\x7e\xf2\x8f\x6d\xeb\x17\x49\xbd\xf8\xdd\x0f\xff\xff\x00\x00\x00\xff\xff\xba\xe8\x98\x84\x46\x4f\x02\x00") + +func pkgUiStaticReactStaticCss2Df42c974ChunkCssBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactStaticCss2Df42c974ChunkCss, + "pkg/ui/static/react/static/css/2.df42c974.chunk.css", + ) +} + +func pkgUiStaticReactStaticCss2Df42c974ChunkCss() (*asset, error) { + bytes, err := pkgUiStaticReactStaticCss2Df42c974ChunkCssBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/static/css/2.df42c974.chunk.css", size: 151366, mode: os.FileMode(436), modTime: time.Unix(1589211666, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactStaticCssMain02392edeChunkCss = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x57\x6d\x8f\xe3\xb6\x11\xfe\xde\x5f\xa1\xe2\x5a\x20\x97\x2e\x15\x49\x5e\xaf\xbd\x32\x6e\x81\x06\x45\x1b\xb4\xd7\x22\xe8\xb5\x0b\xb4\x41\x20\x50\xe2\x48\x66\x96\x22\x19\x72\xb4\x96\x4f\xf0\x7f\x2f\x48\xbd\xac\x64\xeb\x92\x62\x01\xad\x45\x0e\x87\xf3\xf2\xcc\x33\xa3\xf0\xe7\x06\xcc\x99\x58\xa4\x68\xbb\x52\x40\x4b\x2a\xa3\x4e\x69\x7c\x28\x95\x44\x62\xf9\x67\x48\xc3\x9d\x81\xfa\x50\x28\xa1\x4c\xfa\x6e\x17\xef\xa3\x3d\x5c\xc2\x42\xc9\x92\x57\xe4\x4c\x6b\xd1\x31\x6e\xb5\xa0\xe7\x34\x17\xaa\x78\x39\x68\xca\x18\x97\x55\x1a\x47\xba\x9d\x69\x89\x37\xba\x1d\x95\x6c\x36\x9b\xc3\x49\x19\x46\x72\x03\xf4\x25\xf5\x4f\x42\x85\x38\xe4\xb4\x78\xa9\x8c\x6a\x24\x23\x83\x68\xb9\x75\x7f\x87\x5c\x19\x06\x26\x8d\x75\x1b\x58\x25\x38\x0b\xde\x15\x45\x31\xac\x12\x43\x19\x6f\x6c\x7a\xaf\xdb\x4b\xf8\x67\x2e\x10\x4c\x96\xa3\xcc\xb2\xf8\x7c\x64\x55\x57\x53\x53\x71\x49\x50\xe9\x34\x7c\x80\xfa\x30\xbc\xe7\x0a\x51\xd5\x69\xbc\x75\xa7\x3e\x15\x86\x6a\xf8\x5e\x29\xf1\x3d\x95\x20\xb2\x42\x49\xa4\x5c\x82\xc9\xb2\xa4\xa6\x45\x3d\x57\x42\xe2\x64\xed\x08\x72\x14\x90\x65\xb1\xd6\x7f\xf9\xa9\x7b\x73\x3b\x99\xa2\x70\x02\x5e\x1d\x31\xdd\x45\xd1\xa1\x68\x8c\x55\x26\xd5\x8a\x4b\x04\x73\xab\x8b\x51\x59\xb9\xbb\xff\xab\xbe\x7b\x79\xe8\xc6\x48\x24\xf7\xf1\x7d\xbc\x72\x31\xcd\xfd\xc5\x9f\x98\x89\xbb\x13\x67\x78\x4c\xe3\x28\xfa\xfd\x8a\x53\x20\x44\x96\x6d\x3e\x3e\xe7\x59\x77\xec\x8d\xa1\x0d\xaa\x3e\x13\x27\x43\xf5\x90\x08\xf7\xbe\x9a\x9e\x5b\x95\x20\x99\x77\x22\xcb\xe2\x7f\xdc\x57\xed\xdd\x8d\x80\xa0\x39\x08\x9b\x65\xf1\xf3\x73\x9b\x0f\xd6\x25\xdb\x15\xe3\x04\xb5\x48\xac\x5f\xcc\xb2\xf8\x31\x79\xfe\xdb\xad\x32\x07\x52\xc8\xb2\xe4\xdb\x9f\xff\xd4\x4e\x9e\xae\xe8\x02\x63\x94\xb1\x59\x96\xfc\xf5\xdb\xd7\xff\x0c\x82\x1b\x27\xf8\x2f\x6a\x2a\xc0\x8f\xbd\x4d\x8c\xdb\x42\xbd\x82\x01\x96\x65\x09\x7c\x12\xf7\xdd\xe9\xc8\x11\x88\xd5\xb4\x80\x54\x2a\x17\x91\x4b\xa8\x9d\xc6\x6e\x89\x19\x97\xd3\x0b\x97\xba\xc1\x1f\xf0\xac\xe1\x43\x71\x84\xe2\x25\x57\xed\x8f\xa9\xff\x05\xec\x0f\xde\xed\x31\x71\xc9\xfe\x21\x7a\x8c\x2e\x61\xd1\x58\x54\x35\x71\xd8\x32\x4a\x90\x41\xe6\x0a\x0a\xa8\xaa\x4a\x80\xb1\x3e\x21\x1a\x4c\x10\x96\xca\xd4\xae\x28\x1b\x7d\x65\x46\xb8\x35\x50\x5f\x7e\x28\x95\xf9\xdd\x07\x32\x9c\xfb\x71\xf5\x96\x94\x96\x08\xe6\xee\xff\x12\xcd\xa1\x54\x06\x3a\x5f\x2e\xc9\xde\x55\xbe\x80\x12\x53\x12\x87\x1b\xf7\x32\x84\x3d\x8c\x13\xf7\x36\xc0\x68\x78\xbd\x84\x05\xd5\x1c\xa9\xe0\x9f\x81\xf8\x7a\x48\x4b\x6e\x2c\x12\x01\x88\x60\x3a\x84\x16\x09\x1a\x2a\xad\xf3\x29\x7d\x13\xbe\x84\xd0\x6a\x03\xd6\x72\x25\x89\x0f\xec\x95\xab\x8e\x4b\x6e\x85\x02\xa7\x90\x1a\xa0\x9d\x01\x5f\x6c\x52\x49\x38\xb8\x9c\x96\x42\x9d\xd2\x23\x67\x0c\xe4\x25\x6f\x10\x95\x0c\xa1\x85\xa2\x41\x20\x39\xca\x01\x12\x7b\x4f\x18\x54\x80\xc1\xfe\x49\xfa\xba\x5b\xbd\x5b\xd2\x57\x82\x34\xb7\x81\xff\x25\xb8\x7c\xb9\x4d\x1d\xcd\x7d\x2c\x41\x62\x37\x30\x93\x0f\xdd\x8c\xb4\x18\x40\x02\x0f\x13\x6f\xf5\xc1\xfb\xd2\xf6\x78\xff\xcd\xfe\x9c\x61\x17\xd7\x06\xbd\x1f\x57\x0e\x44\x97\x90\x51\xa4\xc4\x13\x45\xe8\x9f\x83\x84\xd7\x10\x44\x81\x27\xb4\x37\x99\x27\xcc\x15\x3b\x3f\xa1\x79\x42\xd6\x8d\x97\x6d\xbd\xa4\x7b\xee\x17\xbc\x1e\xee\xa1\xbe\x89\x79\xe8\x88\xc5\x36\x55\x05\x16\x09\x33\x4a\x33\x75\x92\x9d\x56\x96\x23\x57\x32\xa5\xb9\x55\xa2\x41\x58\xa3\x75\x60\xf7\x8c\xae\x35\x82\xb2\x1c\xdb\xc7\xfd\xe3\x36\xda\xee\xe6\xbd\xc5\x61\xf1\x33\xe1\x92\x41\xeb\xc8\x2f\xea\x31\xbb\x7d\xd0\xed\x61\xce\xdc\x0f\x3e\xe1\x2b\xa6\x11\xc1\x2d\x4e\xae\x46\xc3\xa1\x34\x3a\xb8\x75\x62\xf1\x2c\x7a\x70\xfd\xc2\xe9\x40\xf0\x19\xfb\x4e\x39\x0a\x13\x57\xa5\x41\xec\x8b\xf5\x50\x08\xa0\x26\xcd\x15\x1e\x0f\xb7\x64\x73\xeb\x34\x97\x1c\x39\x15\x63\x98\xa2\xc3\xa2\xd3\xfe\xb2\x31\xeb\x9b\x47\xa0\x0c\x4c\x77\x1b\xde\xbc\x64\x50\x96\xf3\x98\xba\xc6\x25\xb8\x04\x32\x15\xf9\xf6\x70\x55\xc1\x8d\x63\xa8\x82\x5a\xe8\x37\xa8\xe0\x95\x4c\x0b\xe8\xcb\xa1\x32\x54\x1f\x47\x72\xb1\x77\x3d\xf0\xa6\xf7\xd5\x22\x5b\x1e\x09\x7c\x91\x5f\x1f\xec\x57\xbb\x5f\xbd\x30\x08\x8d\xab\xe6\x81\x29\xfa\x43\x7d\x7e\xb6\x7d\xd9\xf0\x7a\xb9\xb9\x28\xca\x3e\xd9\x6f\x32\x63\xeb\xda\x45\xba\xfd\x2d\xaf\xb5\x32\x48\x25\xae\x5b\x1c\x1a\xf0\xf0\x7e\x23\xb3\xfe\xf0\xe3\x8a\x8f\x4f\xa9\x54\xf8\xd5\x40\x93\xc5\x91\x0b\xf6\x7e\x8c\x8c\x87\x70\xb2\x16\x97\xd0\xc3\x88\x78\xeb\x72\x94\x37\x11\xba\xda\x9f\x65\xbb\x2f\xa3\x39\x39\x79\xca\x1c\x16\x5c\x8d\xac\x94\xe2\x97\xd8\x68\xd8\x5f\x14\xe5\x68\xab\x80\x0a\x24\x9b\x68\xa6\x27\x0f\xff\x6f\xbb\x5d\xd2\xc7\x6e\x0b\xf5\x82\xd1\x1c\xc7\x4c\x40\xe7\xd2\x43\x70\xc0\x7b\xaf\x95\x70\x84\xfa\x8a\x7d\xa7\x03\x6e\x84\x9d\xd4\x79\xbe\xba\x9a\x12\x37\x37\xb0\xde\x2d\x14\x07\x8c\xbf\xf6\x83\xb0\x1f\x89\xfa\x29\x60\xd8\xb7\x27\x8a\xc5\xb1\xab\xb9\x24\x7d\x4a\x77\xba\x1d\x7b\xa0\xfb\xa9\x1a\xf4\xaa\x55\x59\x5a\xf0\xcc\x3e\x2e\xb9\xea\x59\xce\xae\x43\x68\x1e\x7a\x42\x75\x14\x1c\x44\xbf\xee\x76\x7a\x74\x54\x3b\xcf\xa8\xa9\x72\xfa\x55\x74\xe7\xfe\xc2\x78\xff\x7e\x92\xae\x01\x0d\x2f\x88\xa4\xf5\xc8\xf6\x6f\xfd\x66\x12\xf2\x2d\xbf\x97\xb9\x9a\x51\x87\x44\x8e\x19\xf4\x91\x9c\x80\x78\xa4\x06\xc7\x11\x72\x1b\x39\xa2\x98\x31\x5f\xc9\x85\x58\xe1\x68\xd7\x27\x16\x0a\x82\xb0\x14\x0a\x89\xf3\x47\xd0\xf3\x98\xcf\xc2\x28\x6b\x8f\x94\x4f\xf5\x8c\x4a\x09\xe4\xfa\x4b\x2e\xef\xdf\x1f\x66\x0d\xc2\x5f\x57\xd2\x9a\x8b\x73\xfa\x47\xc3\xa9\xb8\xfb\x0e\xc4\x2b\x20\x2f\xe8\x9d\xa5\xd2\x12\x0b\x86\x2f\x58\x2e\x71\xc6\xdf\x52\xf1\x88\xa0\xfd\x1a\x7e\xae\x4c\x0b\xc2\x7e\xca\x9d\x4d\xfd\x71\x7c\x8d\xb2\x78\xe5\x18\x03\xa4\x5c\x8c\xa8\x5a\xcb\xfd\x14\xd7\x37\x9c\xf5\x4c\x49\x19\x23\x7e\x34\xf5\x05\xbe\x32\x9e\x86\xe8\x67\x5d\x4f\xf8\xd7\xb9\x9d\xf9\x2f\x9c\x94\x33\x4c\x35\x9a\x70\x59\xaa\x6e\x51\x48\x3f\x35\x16\x79\x79\x1e\xe7\x8b\xd4\xc7\x88\xe4\x80\x27\x00\x79\xfd\x25\xe5\x8c\x5c\x8e\x26\x39\x65\x15\x4c\xa3\xec\x93\xd5\x54\x2e\xb1\xb8\xf5\x0d\xba\x1d\xa3\xd4\x5b\x6e\x1a\x01\xf6\xd6\xf0\x07\x07\x4a\xb7\xe7\x3f\x64\x16\xc3\xba\x36\x40\xd6\x3b\xe8\xf8\xfd\xb8\xfc\x44\x9d\xc3\xa4\x56\x52\x79\x2d\x97\xdf\x7c\xf3\xf5\xbb\xc0\xaa\xc6\x14\xf0\x77\xaa\x35\x97\xd5\xbf\xff\xf9\xf1\x43\x4d\xb9\x0c\xa3\x64\xf3\x98\x00\x83\xb0\x38\x36\xf2\x25\x2c\xac\x0d\x6b\xaa\x83\xaf\xbf\xf9\x5f\x00\x00\x00\xff\xff\x6a\x22\x62\x57\x3f\x0f\x00\x00") + +func pkgUiStaticReactStaticCssMain02392edeChunkCssBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactStaticCssMain02392edeChunkCss, + "pkg/ui/static/react/static/css/main.02392ede.chunk.css", + ) +} + +func pkgUiStaticReactStaticCssMain02392edeChunkCss() (*asset, error) { + bytes, err := pkgUiStaticReactStaticCssMain02392edeChunkCssBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/static/css/main.02392ede.chunk.css", size: 3903, mode: os.FileMode(436), modTime: time.Unix(1589211666, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactStaticJs2B309ab18ChunkJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\xbd\x6b\x97\xdb\x36\xb2\x28\xfa\xfd\xfe\x0a\x89\xe3\xc3\x10\x16\xc4\x26\x25\xf5\x8b\x32\xac\xe5\x89\x9d\xd7\xb8\x93\x4c\xe2\x49\x66\x0f\x9b\xce\x61\x53\x50\x8b\x09\x45\x2a\x24\xd4\x0f\x37\x35\xbf\xfd\xae\x2a\x80\x24\x48\x51\x76\x66\x66\x9f\x7d\xd6\xbd\x6b\xd9\x2d\x92\x78\x17\x0a\x85\xaa\x42\x55\xe1\xe4\xf9\x70\xf0\x45\x96\x0f\x92\x38\xe2\x69\xc1\x07\x71\xba\xca\xf2\x4d\x28\xe2\x2c\x1d\x6c\x13\x1e\x16\x7c\x50\x70\x3e\x98\xd8\x37\x53\xe7\x32\xbc\x71\x2f\xec\x68\xbd\x4b\x7f\xb3\x7f\x2d\xec\xb7\x5f\x7f\xfe\xe6\xdb\x1f\xdf\xd8\xe2\x41\x0c\x9e\x9f\xfc\x3f\x96\x58\xc7\x85\x7d\xcf\x6f\xb6\x61\xf4\xdb\x37\x45\x96\x6e\x6f\xf3\x70\xbb\x66\xfd\x9f\xcb\xd2\x0f\x88\xbd\xdd\x15\x6b\xcb\xf7\x27\x01\xf5\x57\xbb\x34\x82\x56\x2d\x4e\x05\x4d\xc9\x93\xb1\x83\xa6\x45\x1e\x47\xc2\x98\x73\x9b\x3f\x6c\xb3\x5c\x14\x2c\xb5\xce\x66\x64\x4f\xbb\xb9\x5b\x19\x2e\x88\xd5\x93\xa5\x55\x61\x6a\x2f\x2d\x41\x8d\xb5\x41\xad\x3a\x1f\x79\xca\xb9\xd8\xe5\xe9\x20\xdc\x13\x42\x55\x8e\xb8\x37\x47\xa1\xe5\xf8\xb5\x37\x47\xa4\xe5\xd8\xf4\xe6\xd8\x69\x39\xc2\xde\x1c\x2b\x2d\x47\xd2\x9b\x63\xa9\xe5\xf8\xad\x37\xc7\x5a\xcb\xc1\x7b\x73\xdc\x68\x39\xa2\xde\x1c\x1b\x2d\xc7\xb2\x37\xc7\x95\x96\xe3\xa6\x37\xc7\xad\x96\xe3\xb6\x37\xc7\x2b\x2d\xc7\xaa\x37\xc7\x87\x3d\x21\xf3\xbb\x30\x1f\xe4\x34\x63\xa9\xe5\x12\x1a\xb3\xd4\x4e\xad\x8c\xcc\xab\xcc\x83\x10\xa6\xbb\x2e\x71\x97\xc5\xcb\x81\xc3\x18\xe3\xa6\x69\x71\x66\x18\x84\xd6\x9f\x84\x69\x5a\x82\xe5\x84\x8a\x05\xb7\x8b\x6d\x12\x0b\xcb\x18\x18\xc4\xde\x84\x5b\xab\x69\x9c\xd7\x75\x09\x9f\x07\x65\xc9\xf7\x84\xd8\xbf\x66\x71\x8a\x99\x3d\xbe\xaf\x5b\x2e\x64\xcb\xd0\xbf\x94\x3d\xed\xe7\xaa\xd8\x77\x37\xbf\xf2\x48\xd8\xbf\xf1\xc7\xc2\xe2\xc4\x5e\x65\xf9\x9b\x30\x5a\x6b\x2d\xe4\xe4\x69\xec\x42\x7f\xec\x38\x5d\xf2\x87\xef\x56\x56\x4e\x4c\xd3\x4a\xfd\x3c\x60\xdc\xcf\x03\x82\x70\x69\xda\x89\x64\x3b\xab\x2c\xb7\xb0\x2d\x9a\xb3\x57\x79\x1e\x3e\xda\x71\x81\xbf\x96\x20\x0b\xe1\xf9\x22\xa0\x19\xcb\xed\x84\xa7\xb7\x62\x4d\x63\xe8\x51\xf6\xd2\x99\x93\xd8\x4f\x59\xee\x67\x63\xe6\x06\x50\x7f\x1a\x54\x1d\x8d\xf7\x50\x5d\x02\x19\xeb\xb6\x76\x30\xfe\x04\x07\x6e\x19\xbb\x74\xc9\x57\x71\xca\x97\xc6\x90\x31\xf1\xb8\xe5\xd9\x6a\x10\x65\x69\x91\x25\xdc\x34\xd5\x83\xcd\xf3\x3c\xcb\x2d\x4e\x28\x94\x62\x43\x87\x60\xad\x5b\x66\x64\x08\x07\x83\xd5\x45\xef\xe3\x74\x99\xdd\x9b\xa6\xfc\xb5\xdf\x24\x7c\xc3\x53\x51\x96\xda\xbc\x6b\x3d\x59\x55\xcb\x38\x5e\x59\x43\x8b\xfb\x22\x88\xd3\x42\x84\x69\x04\x55\x6d\x09\x51\x83\x48\xf9\xfd\xe0\x0d\x76\xc1\xf8\x3a\xbd\x0b\x93\x78\x39\xd8\xe6\xd9\x76\xf0\xbf\x8d\x91\x18\x19\xff\x7b\x50\xec\xb6\xdb\x24\xe6\xcb\x81\xc8\xe0\x5b\x3a\x32\xfe\xb7\x3d\x78\xf3\xb0\xe5\x91\xe0\x2a\xab\xc8\x06\x37\x7c\x10\xa6\x83\xaa\x81\x41\xb6\x1a\xa8\xde\xd9\x83\x9f\xa0\x4e\x49\x1e\x57\x61\x9c\xf0\xa5\x6d\xc8\x21\x2e\x59\x6c\x87\x76\x96\xf2\xef\x56\xef\x1e\xb7\xdc\xf2\xe1\x15\xc8\x4d\x7a\x4b\xe1\x11\x46\x42\x57\xf8\x58\xac\xc3\x2d\xb7\x9e\xa2\x5d\x9e\xf3\x54\x78\xf0\x29\x4c\x1f\xf7\x24\x20\x74\xdd\x57\x0b\x16\xed\x54\xa7\xea\x78\xf6\x4c\x42\x13\x2b\x29\x1e\x37\x37\x59\x42\x73\x9e\x2e\x79\xee\x55\x25\xf7\x04\x0b\x84\x80\x1b\xdf\xad\xac\xff\x03\xf5\x07\x04\xba\x7e\xc3\x9e\xbe\x08\x97\xdc\x73\x4f\x1d\xfa\x79\x96\x24\xe1\xb6\xe0\xde\xf4\xd4\xa1\x57\xd9\x32\x4c\xbc\xa9\xe3\xd0\xcf\xc3\x3c\xdb\x15\x3c\xf1\xce\x1c\x67\x4f\x37\xcc\x37\xe2\xd4\xa0\xc6\x26\xdb\xa5\xe2\xbb\xf4\x4d\x2a\x78\x6e\x50\x63\x97\x56\x1f\x1e\x62\x61\x50\x23\xdc\x6e\x79\x08\x09\x5c\x65\xe0\xf2\xbb\x88\x37\x3c\xdb\xc1\x53\x56\x97\x55\x4f\x71\x7a\xdb\xbc\xf0\xa5\x7c\x96\xa5\xe4\x43\x9d\xe1\x21\x16\x7c\x69\x04\xf4\x8a\x3d\xbd\xf9\xf6\xdd\x9b\x1f\xbe\xfe\xf6\x4b\x4f\x36\x84\x59\xf0\xdb\x9b\xd7\xea\x13\xd4\xf4\xe6\xef\x5f\xbf\x93\x99\xaa\x6a\xe0\x0b\x66\x91\x75\xed\xe9\x2d\xf3\x8d\x70\x27\xb2\x71\x21\xc2\x1c\x47\xb0\x13\x99\xfa\x19\xf3\x14\xba\x23\xb2\x6d\x9d\x2a\xb2\xad\xfa\x22\xd3\xf2\xf8\x76\x2d\xea\x54\x7c\xab\xbf\xca\x1c\x37\x99\x10\xd9\xa6\xf5\xd2\x7c\xad\x0a\x26\x7c\x55\xe5\x87\xc7\xea\x8b\x4c\x0e\xe8\x23\x1b\xea\x4b\xba\xbb\x2e\xcb\x72\xa8\x16\xe6\x32\x8b\x76\x72\x65\x76\xbf\xd8\x51\xce\x43\xc1\xd5\xda\xd0\x88\xf0\x9d\x46\x36\xd3\x5d\x92\x30\xc6\x17\x0d\x29\x5e\x18\xbe\x24\x06\x83\xbf\x55\xcd\x07\x86\x57\x7f\xfc\x76\x97\x24\x81\xe1\x29\xba\xb9\xcd\x33\x91\x41\xcf\x6c\x91\xfd\x88\xe8\x69\x47\x61\x92\x58\x9c\x34\x14\xf1\x15\x34\x07\x6b\x50\x54\x63\xe0\x73\xad\xf5\x21\x52\x7f\x9d\x00\x95\xa5\x51\x15\xc6\x77\xad\xae\x5f\xa0\xae\x78\xd5\xb3\x01\x0c\xad\x21\x2f\xcb\xaa\x9a\x86\x04\x72\x62\x9a\x86\x5a\xcb\x46\x9c\x0e\xf8\xde\xe2\x35\x3d\xe2\xb6\x4a\x99\x77\xea\x04\x32\xf6\xaa\xc9\x38\x74\xe7\x72\x00\x00\x3a\xd5\xf9\x1a\x22\x5f\xa8\x72\x41\xd5\xf9\x2a\xe1\x55\xf1\x98\x46\x47\x53\xbf\xe4\x29\xcf\x43\x91\xe5\x47\x73\x7c\x9f\x67\x0f\x8f\xf2\x6b\xab\xd3\x16\x81\xee\x1a\x92\x1c\x68\xa8\xc1\x4d\xf3\xb1\x82\x74\x8d\x04\xbf\xef\x78\xfe\xf8\x23\x4f\x78\x24\xb2\xfc\x15\x4e\x0d\x94\x16\x6a\xeb\x29\x4b\xeb\x63\x99\x8d\x3f\x19\x23\x4e\x08\x1d\x56\xf9\x89\x58\xe7\xd9\xbd\x4e\xc8\xdf\xad\xf9\x40\x84\xf9\x2d\x17\x83\xcf\x8c\x11\x1f\x19\x9f\x0d\xa2\x6c\x97\x2c\x07\x69\x26\x80\x54\xc7\x4b\x9e\x8a\x78\x05\x54\x3d\x4e\x07\x62\xcd\x07\xcb\x6c\x43\x07\x22\xde\x7a\x83\x68\xcd\xa3\xdf\x06\xc5\x96\x27\x09\x0c\xa5\x02\xed\x40\xec\xab\xb1\x36\x53\x7f\xdf\xc1\xda\xa1\x64\x1b\xda\x9b\x2b\x27\x65\xf9\x68\x9a\x46\xba\xdb\xdc\xf0\x5c\x87\x4d\xd5\xff\xa6\xc2\x0f\x3a\x47\xf0\x4b\x33\xb1\x03\xb1\xb8\xb7\x52\xb2\x48\x3d\xb9\x38\x58\xba\xf0\x03\xcf\x4f\x03\x4f\x7e\xf6\x9d\xc0\x4b\xf7\x9f\xe0\x60\xeb\x56\xf2\x9a\x41\xb2\x72\xa6\x56\x4d\x58\x14\xf1\x6d\xaa\xed\xa5\xbc\x61\x18\x04\x73\xe7\xe2\x45\x98\xdf\xe2\x8c\x14\xaa\xdb\x73\x31\x1a\x55\x5d\xad\xd3\x7c\x11\xcc\xab\x62\x39\x00\x37\x25\x07\xcb\x72\x1d\x16\xdf\xdd\xa7\xdf\xe7\xd9\x96\xe7\xe2\x51\x2e\xce\x94\x22\x0b\x03\xdc\x0b\x4b\x91\x85\xa9\xa1\x4d\xec\x70\xbb\x4d\x1e\x51\x58\xa0\x75\x43\x64\xff\x51\x46\x38\xdf\x93\x1e\x86\x1e\x7b\x35\x1f\x6a\xd9\x5b\x00\xaa\x18\xb1\x4e\x0f\x1b\xc0\x65\x56\x03\x14\xce\xfc\x80\x0a\xe6\x7c\x14\x32\x79\x1b\x32\x31\x70\x6a\x98\x10\x57\x48\x90\x77\xd6\x4d\x5c\x96\x1a\xa6\xc4\x84\x4b\x89\x27\x27\x73\x9e\x80\xb0\xb5\xea\x60\x17\x80\xad\xe2\xd9\x64\xd5\x21\xcb\x14\xc4\x00\x57\x68\x4e\xe6\xa1\x69\xaa\x6a\x42\xb2\xaf\xaa\xd1\xa8\x5b\x4c\xaa\x41\x15\x30\x65\x39\x49\xe5\xa4\xe4\xb4\x80\xda\xfd\x22\xa8\x2b\x28\xc8\xbe\x9e\x99\x86\xa9\xdd\xd7\xc2\xd4\xc2\xca\xec\x25\x5f\x85\xbb\x44\xb0\x8c\x36\x32\x56\x46\xbc\x9a\x9c\x5b\x39\x3b\x9c\xb0\x6c\x5f\x4d\x33\xf5\x03\x42\xca\xd2\x6a\x0a\xe7\x64\xff\x49\xf1\x4c\x43\x6e\x5c\x42\xf1\xca\x52\xfb\x88\xa2\x51\x4f\xfb\xb9\x62\x7e\x69\xc6\x9e\xf6\x34\x66\x6d\x3e\x1b\xd1\x36\x67\xce\x3c\x7f\x11\x57\xf3\x98\x8f\x46\x24\x65\xb1\x9f\x07\xb4\xe1\xb5\x53\xf2\x92\x39\x65\x69\x65\x7e\x2a\xd9\xe1\x7a\x91\x66\xff\x0e\x4e\xf6\x09\x99\xfd\xe5\xb3\x5a\x98\x61\xa9\x35\x9d\x11\x1d\x2f\x75\x11\xa6\xb3\x69\x74\xa9\x51\x4d\xb3\xf7\x48\x9a\xf4\xfe\x60\xfe\x5e\xae\xfd\x47\x64\xe4\x4c\x53\xfe\xda\xb1\x90\xfb\x04\xa0\x8b\x04\x23\x54\xac\x88\x81\x1f\xd0\x9c\x0d\x1d\x9a\xb1\xa1\x4b\x63\x26\xe7\x7d\x2e\xf2\xc7\x7a\xed\x84\xb4\x60\xdc\xef\xd4\x15\x58\x64\x3e\xb4\x72\x66\x85\xac\xb0\x53\xfe\x20\x2c\x42\xec\x65\x96\x72\x94\x6d\x14\xfe\xda\x77\x61\xb2\xe3\x40\xfc\xcb\x32\x55\xd3\x04\xbd\x24\x73\x68\x92\xcc\xf7\x51\x28\xa2\xb5\x15\x91\xa7\x0c\xba\x10\xb3\x68\xbf\x8a\xd3\x30\x49\x1e\x9f\xa0\x03\x79\x59\x4a\xac\x28\x6c\x09\x85\xb2\xac\x9e\x2c\x52\xe7\x8c\x57\x56\xa6\x36\x95\xb8\x46\xf7\x74\xbf\x47\x10\x95\xa5\x1a\x70\x6e\x87\x44\x7d\xd1\xe6\xaa\xd9\x8b\x80\x5b\xee\x08\x16\xa1\x10\x7c\xb3\x15\x20\x30\x2c\x79\x21\xf2\x5d\x24\x76\x39\x1f\xa4\x59\x3a\x46\x28\xdc\x24\xbc\x96\x21\xec\xeb\xf4\xeb\x74\x90\xe5\x4b\x9e\x2b\x01\xa3\xca\x42\xb1\x00\x72\xe7\x03\xb9\x88\x8b\xc1\x66\x57\x88\xc1\x3a\xbc\xe3\x83\x70\xd0\x03\xd8\xc1\x86\x8b\x75\x86\x92\x87\x45\xfe\x85\x7d\x42\x62\x50\xc3\x88\x69\x5b\xed\x0f\x7c\xc5\x73\x9e\x46\xd5\x18\x81\x3c\x0f\xd6\x61\x91\x7e\x06\x5b\x2c\x07\x61\x28\x16\x71\x98\xc4\x05\x5f\x0e\xc6\x20\x46\xf1\xdc\x22\xad\x1c\x40\x64\xf8\xb2\xd9\x62\xf9\x1f\x59\x3f\xff\xc1\x02\xca\x3f\xa9\x73\xc8\x3e\xa9\xd9\x88\x3f\xa9\xd9\x08\x3f\xa9\x3f\x29\x3e\xa9\xb7\x88\x3e\xa9\xfb\x48\xb4\x1c\xfd\x3a\xa9\xdd\x27\x75\x52\xdb\x4f\xea\xa4\x56\x9f\xd4\x16\x2d\x3f\xa9\x71\x5a\x7f\x52\xaf\x75\xd3\x10\xb6\xa7\x6d\xce\x57\xf1\x83\x67\xac\xc2\xc2\xa0\x71\x94\xa5\xdf\x86\x1b\xee\x19\x61\x9e\x67\xf7\xe3\x65\x76\x9f\xca\xaf\x9e\x3f\x9b\x5d\xd0\x53\x77\x42\xfd\x80\x1a\x2b\xe7\x6c\x6a\x50\xe3\x6a\xe6\x4e\x6d\x77\x30\x99\x4c\xec\xd3\x64\x32\xb1\x27\x03\xf8\x13\x5d\xda\xb3\x41\xf5\x7f\x32\xb3\xcf\x06\xce\x60\x3a\xb5\x2f\xdf\x4e\x66\xee\x60\x76\x3e\x8d\xc6\x2a\x71\x8c\x89\xf0\x00\xc9\x03\xe7\xad\x3b\xb1\xcf\x07\x93\xf3\x0b\xfb\x0c\xf3\xd4\xff\x65\x25\x98\x0b\x9b\x19\xab\x66\x4e\xc7\x97\xf6\xe9\x60\x02\x3f\xd3\xc1\x74\x66\x4f\xed\xd9\x5b\xf7\x62\x36\x98\xce\xa6\xf6\xec\xa7\xd3\xb3\xc8\x19\xbb\x53\x7b\x3a\x70\x1d\xfb\x7c\x3c\x81\xce\x8c\x27\xb3\xf5\x74\x12\xe1\x57\x67\x30\x99\x61\xd2\x00\x93\xee\x26\x17\xe7\xf6\x2c\x71\xdd\x99\x7d\x31\x76\x27\x8e\x7d\x1a\x5d\xda\xd3\xf1\xa5\x7d\x01\x83\xb8\x18\xbb\x0e\x36\x31\xb6\x67\x1f\x8c\x60\x0f\x7b\xda\x47\x41\xb7\xdb\x1e\x01\xdc\x04\x00\x37\x9d\xd9\x97\x83\xc9\xc5\xa5\x7d\x9a\x8c\x9b\x11\x1d\x1b\xf4\xdb\x89\x73\x3e\x98\x5e\x46\x2a\x09\x81\x8a\x0f\x12\x6e\x89\x7b\x39\x83\x51\xc2\xdf\xa3\xc0\x9f\xb9\x53\x6c\x70\x16\x21\xd0\x00\x78\x13\xf8\x99\x8e\xd5\xa8\xde\x4e\xce\x66\x03\xf7\xec\xc2\x3e\xfb\x69\x06\xa0\x1b\x00\x90\xc6\x0a\x3e\x12\x7a\xeb\xf1\x74\x12\x49\x90\x3a\xe3\xc9\x6c\xac\xe0\x3a\x9e\xcc\x7e\xc2\x82\x6f\xcf\x2e\x01\x07\x2e\x2e\x6d\x37\xc2\x39\xb9\xb4\x2f\x60\x1c\x17\x03\xd7\x19\xcb\xf9\x41\xd8\xc5\x47\x61\x17\x85\x09\x4f\x97\x61\x3e\x46\xa9\xa0\x17\x82\x93\xf3\x19\xa2\xde\xf4\x6c\xe0\x9e\x39\x5f\xb9\x93\x68\x7c\x66\x9f\x4d\xce\x07\xce\xd8\x9d\x8c\x4f\xed\xe9\xf9\x14\x1e\xdc\xc9\xdd\x78\x0a\x18\x30\x39\xb3\x4f\xdd\xc1\xc4\xb5\x67\x97\xe3\xd9\xc5\x60\x76\x31\x9e\x5d\xac\x67\x17\x3f\xb9\x93\xc8\x51\x25\xab\x42\x03\x2c\xb7\x9e\x39\x91\xaa\x71\xe0\x4e\x64\xe2\x00\x13\xef\x4e\x27\x6b\x77\xf2\x6f\x17\x9d\x5d\x44\xb2\x33\xce\x60\x76\x21\x7b\x34\xc0\x1e\xdd\x41\x47\x07\x58\x70\x5c\x95\x91\x75\x7e\xb8\x82\x9f\xcb\xc9\x7a\x36\x99\x1d\xab\x79\x72\xe6\x44\xce\x00\x6b\x1e\x57\x95\xca\x91\x7e\x35\xbb\x88\xd4\xf8\x9d\xf1\xec\x62\x5c\x01\x61\x3c\xbb\xf8\x69\xe2\xcc\x8e\x0c\xe2\xc3\x66\x3a\x9d\xda\x93\xcb\xb3\xc1\xe5\xa9\x7d\x39\x3b\x4f\xc6\x93\x0b\xdb\x3d\xbb\x84\x9f\xe9\xe5\x45\x34\x9e\xd9\x67\x67\xe7\xe3\x99\x7d\xee\x9c\x8e\xdd\x89\x3d\x39\x3b\x85\x97\xe9\xd9\xd8\x3d\xb3\x2f\xcf\xc7\xb6\x73\x76\xf1\x16\x90\xd1\x9d\x0c\xa6\x67\x90\xf9\x34\x19\xcf\x4e\xed\xcb\x8b\xf1\xec\xcc\x9e\x9e\x4e\x7a\x6a\x38\xd3\x6b\x70\xb1\x8a\x44\xb6\x77\x3e\x80\xd6\xcf\x23\x99\x7b\x50\x97\x84\xe9\x97\x6d\x43\xe6\x01\x16\x4c\x2e\x26\xf6\x99\xe3\x0e\x2e\xa6\xf6\xe4\xec\x32\xc2\xbc\x03\x59\x4e\xe6\x1d\xa8\x82\x90\x19\xdb\x70\x67\x13\xfb\xf2\x74\x3a\x76\x67\xae\x7d\xe1\x9c\x46\xb2\x4b\x75\x41\xe8\x11\x16\x84\xcc\xb2\x73\x88\xc0\xe1\x71\x04\x5e\x87\xb9\x18\x87\x39\x0f\x2b\xe4\x05\xc4\xad\x91\xd7\x5d\x71\x40\xde\x53\xc7\x19\x4c\x2f\x70\x46\xab\xf9\x9c\xa9\xd9\x9c\x39\x12\x15\xc6\xf2\x93\x9c\x95\x0a\xcb\x2b\x1c\x9f\x49\x0c\xff\xe9\xfc\x4c\xce\xe1\x40\x7e\x6a\x21\x61\xb7\xe2\xa9\x73\xb1\x9e\x4d\xcf\x3e\x5c\x4d\xcf\x81\xcc\xba\xa7\x97\xf6\xe9\xdb\xc9\x05\x20\xe2\x59\x32\xbe\x38\x85\xc5\xee\x4e\xed\xf3\x68\x7c\x6a\xbb\xe3\x33\xa0\x78\xa7\xf6\xe9\xf8\x0c\xbe\x5f\xda\x97\x03\xf7\xed\xe5\xd9\x60\x32\xbb\xb8\x73\x9d\xd9\x7a\x7a\x31\x4b\xc6\x17\x97\xf6\xe5\xd8\xbd\x38\xb7\x2f\xa2\xf1\xd4\x9e\x8c\xcf\xec\xd3\xb1\xeb\xda\xb3\xf1\x85\x7d\x3e\x76\xcf\xed\x19\xcc\x13\xc2\xab\xf8\x04\xbc\x92\x38\xe5\xbd\xf0\x9a\x38\x2e\x2e\xf6\xcb\x33\x80\xd7\x57\x67\xb3\x9f\x2e\x9c\xc8\x19\x5f\xd8\x17\xb3\xf1\xb9\xed\x02\xc2\xc8\x7f\x5f\xb9\x67\x9f\xc3\x87\xc1\xd9\x6c\xe0\x0c\xce\x5d\x78\x74\x06\x17\xce\xdd\x14\xd7\x96\x7b\x6e\x9f\x9d\x0f\xdc\x99\x3d\x9d\x0e\xa6\x13\xf9\x6f\x3d\x3b\x9b\x45\x50\x13\x40\xea\x0c\xab\x1b\x60\x5d\x77\x40\xe6\xfa\x1a\xf9\x70\x35\x3b\x9b\x0d\x2e\xcf\xbe\x9a\x02\x3a\xcf\x22\x58\x50\xd3\x0b\x20\xd2\x13\xdb\xb9\x1c\x4c\x4e\xed\x8b\x53\x89\x25\x83\x99\x03\xf8\x38\x9d\x00\x91\x9e\x00\x71\x05\x40\xcf\x26\xf6\xf9\x69\x32\x3e\x9f\xda\xd3\x73\xf9\x37\x02\xfc\x3a\x95\x7f\xa6\x13\xfb\xfc\x4c\x3e\xce\x4e\xed\xc9\xe9\xc0\x49\xc6\x40\x55\x2f\x07\xf8\x17\x10\x60\x72\x3a\x80\x3f\xf2\xc9\x3d\xc3\xc6\x61\xcf\x3d\x9b\xc2\xbe\x78\x86\xfb\xef\xd9\x24\xaa\x33\xaa\x3c\xf8\x88\xd9\x60\x93\xbd\x9c\x0c\x26\xd3\x73\x7b\x72\x9a\x60\x17\x06\xb2\x23\xd0\xee\x00\xff\x60\x3f\xe4\x63\xd5\x8f\xcb\xb3\x31\xcc\x40\x35\x9a\xc8\x3d\x85\xc5\x2d\xff\xe2\x48\x07\x33\x1b\x36\x77\x78\x94\x00\xf8\xc9\x75\x27\x91\xed\xb8\x35\x14\x4f\x11\x84\xa7\xf6\xe5\x25\x00\x12\x90\x22\xfa\x08\x52\xf0\xbb\x3c\x4b\x3f\xc2\x7e\x9c\x5f\x00\x5a\x4c\x9c\x73\xdb\x99\x5c\x0e\xa6\x17\xae\x3d\x3b\x3f\x03\xfe\xe1\xec\xe2\x6c\x00\x28\xe9\x4e\x71\x3b\x05\xba\xa6\xff\x9d\xcc\xec\xd3\xb3\x4b\xb5\xad\xce\x5c\x84\xda\xd9\xf9\x58\xfe\xc0\x7e\x7f\x7a\x3e\xc6\xbf\xb0\x77\x9e\x4e\x26\x58\xec\x14\x77\x50\x07\xc8\xd2\xec\xed\x04\x76\xc2\x8b\x99\x7d\xea\x9c\x26\xee\xe9\xcc\x3e\x9f\x9d\x8e\xe1\xd7\x99\xb8\x50\xfe\xfc\x12\x8a\x4c\x4f\xb1\xfc\x0c\xb6\xeb\xa9\x7b\xae\xca\xdb\xce\x4c\x35\x38\x68\x1a\x3c\x87\x5d\xb2\xf9\x5b\x75\x70\x20\x3b\xf8\x76\x82\x30\x75\xab\x21\xaa\x31\x61\xe6\x49\x35\x1a\xf9\x82\x05\x26\x03\x07\x61\x9b\x7c\x12\xb6\x52\xe1\x2c\x61\x3b\x9d\x38\x1a\x6c\x4f\xa7\x8a\x43\x39\x05\x44\xb9\xb4\x9d\xe9\xdb\xc9\xe4\xc2\xbe\x38\x1f\xcc\x66\x80\x87\xd0\x1c\x76\x03\x3b\xab\x1e\xb1\xf5\x81\x83\xe3\x93\xc3\xc3\xd1\x01\x7b\x27\xff\x28\x88\xda\x8e\xe4\x5a\xde\xba\x53\xdc\xaa\x26\xa7\x67\x89\x04\xdf\x00\xa1\x89\x4c\x17\x70\x2f\xd3\x0b\xf8\x33\x91\x70\x1c\x57\xc5\x90\x5b\xaa\x1b\x90\x4d\x63\x7f\xb0\x2b\xf2\x51\x75\xe5\xad\x1a\xc1\xf9\xc4\xbe\x54\x59\xb5\x3f\x32\xbf\xc2\x03\x04\xd9\xee\x93\x20\x53\x7a\xfe\x5e\x98\x21\x4f\x32\xb9\x38\x85\x49\x52\x6d\xba\x6f\x2f\x5d\xc0\xc3\xc1\xec\xec\xdc\x9e\xba\x33\x7d\xee\xa6\xfa\xdc\x4d\x15\x36\xc2\x82\x6f\x23\xe4\x58\xc3\x48\x89\x8a\x63\x85\x97\xb6\x23\xb9\x66\xc7\x7d\xeb\x5e\x5c\x00\x36\x02\x28\x81\x43\x9d\x5d\x00\x57\xeb\xda\x93\xd3\xd3\x48\xe2\xe2\xb8\xc6\x4b\x57\x0e\x7c\x36\x6b\x8a\x1f\x2e\x81\x6a\xb1\x28\x5c\x54\x2f\x55\x17\xdf\xca\x41\x9e\x2a\xd4\xd0\x50\x78\xa2\xa3\xf0\x85\xed\x38\xae\x2a\x84\xe0\xdd\x1e\x05\xef\x26\x4e\x77\xc5\x11\x66\xf9\x42\x4a\x19\x67\x83\x89\x73\xf1\x15\x32\x9f\x48\xc8\x81\xe2\x4a\x6a\x3e\x46\x52\x7e\x07\x04\xbb\x9f\xc8\xc3\x36\xab\x0a\x0d\xa6\x93\x71\x95\x3a\x9e\x4e\x14\x99\xc7\xc4\x71\x55\x99\xfc\x87\x3d\x5e\x1d\xed\xf1\x36\x39\xda\xe1\x73\xbd\xc3\x93\xf3\xc9\x4f\x67\xb3\x23\x6d\x28\x66\xba\x7f\x3c\xee\x6c\xf6\xef\x0d\xd7\x9d\xcd\xa0\xf0\x51\x68\x4c\x8e\x00\xe3\xa7\xa9\x33\x83\xc2\xff\x26\xac\x96\x47\x61\x55\xf0\x30\x8f\xd6\xbd\x9b\xbb\xe3\x4c\x24\x33\x74\x3a\x98\xc1\xd6\xf8\x76\xe6\x9c\xa2\x20\x37\x05\x6e\xef\x14\xff\xbb\x8e\x7d\x36\x06\x6e\x62\x7c\xfe\xd5\xf4\x7c\x12\x4d\xce\xed\xb3\xf1\x14\xb2\xcd\x66\xe3\xf3\x4b\x1b\x88\xd2\xd8\x9d\x5c\x7c\x0e\x30\xbf\x04\x69\x74\x3a\x99\x80\x50\x04\x13\x30\x70\x7e\x74\xe4\x47\x7c\x2d\xf0\x11\xbe\xab\xff\xd1\xec\x02\xe5\xc0\xcb\x89\x8d\xdb\x16\xb0\x4a\x17\x63\x80\xe0\x99\x3d\x45\x36\x6c\x36\xa8\xb7\xc5\xf3\x81\x7b\x9e\x5c\x42\x8b\xf0\x27\x6a\xc9\x58\x9a\x2c\x06\x4c\x2b\x72\xae\xb5\xb4\x56\x09\x73\xb6\x3b\x9e\xce\x3e\x5c\x41\xdb\xc0\x94\x8c\xcf\x41\xb4\x02\x86\xee\x62\x7c\x7a\x6e\x4f\xf0\xc1\x9d\x00\x3b\x81\x29\xd5\xb7\x41\xf5\x5d\xe6\x87\x57\x4c\x1b\xa8\x34\x60\x77\x40\x0e\xab\xbe\x55\x65\x70\x5e\xd6\xc7\xe7\x65\x1b\xa7\x29\xcf\xfb\xb9\x54\xd7\xc1\x2d\xc0\x99\x0d\x66\x17\x47\x64\x8b\xa2\x23\x50\x74\x24\xac\x8e\x84\xf3\x61\x03\xdf\xa6\x67\x2d\x79\x44\x2f\x52\x68\x99\xe5\x3f\xbd\x3d\xbd\xa1\x31\xd4\x36\x71\x2e\xc6\x30\x81\xff\x2d\xb5\x5d\x01\x63\x7b\x5a\xcb\x8a\x9d\xe4\x1f\x81\xc3\xba\x84\xc2\x0e\xe4\xfa\x78\xd5\x1f\x36\xee\xc4\xbe\x9c\x4c\x00\x47\x9c\xf3\x7f\xb3\x7f\xaa\x23\xce\xa5\xfc\xe8\xea\xe3\x06\xb1\xea\xf4\x6c\xe0\xfc\xb7\xd4\xac\x81\xc0\x75\x2e\xb0\xdf\x67\x0e\xfc\xfc\x27\x70\xd5\xba\x0b\x18\x78\x73\x14\x03\x45\xbc\xe1\x35\x19\x9d\x9e\xb6\x08\xc3\x12\xb7\x53\x20\x0a\x13\xc9\x22\x38\x8e\xed\x9c\x8f\xe5\x0f\xf0\xaa\x88\xe7\x36\x62\x3a\x3c\x4f\x27\xb6\x0b\x6c\xdd\x0c\xf6\x3f\xa9\x52\x99\xc9\xbf\xd1\x58\xcb\x2d\xf3\xa9\x67\xcc\x0b\x0c\x31\x70\xbb\x17\x97\x50\xd9\xf9\xa9\x7d\x39\x1d\xc0\xb3\xfb\xe9\x72\x90\x6b\xe0\x82\xc0\x73\x1a\xb5\x3a\x23\x9f\x55\x97\x06\x98\xfd\xad\xeb\x60\x03\xb0\x47\x63\xb9\xe9\xe9\x19\x8c\xe4\x53\xe5\x50\xdd\x35\x1b\xc8\x91\x68\x79\x21\xd7\x44\x3d\xea\xe3\x00\xe2\x77\x3e\x51\xe0\x1a\xe8\xe0\x3a\x5a\x2e\xd1\x81\xf5\x09\xc8\xbe\x6d\xa6\x04\x26\xb7\xad\xd7\xd6\x4d\xfc\x3a\x47\x22\xff\x73\x0a\xed\x3f\xd2\x25\xa9\xc6\xae\x0e\x7a\x07\x71\x3a\xe0\x0b\x75\x36\x25\x0f\x62\xaa\x83\x48\xcc\xfa\x84\x27\x20\x5e\x4a\x79\xba\xdb\xc8\x03\x01\x6f\xe8\xd0\x28\x4b\x57\xf1\xed\xae\x7e\xbf\xcf\x63\xa1\x9e\xf7\xc4\xe3\xbe\x08\x58\x4a\xbb\xfd\xf9\xe4\x29\x1a\x6f\x8e\x6d\xab\xe3\x32\x69\xc1\x61\x69\x07\xba\x84\x6a\xd9\xec\x28\x4b\xe5\xc9\x46\x96\x33\x4e\xb9\xfd\xcb\x2f\x98\xf6\xcb\x2f\x4c\xfc\xc7\xc7\x63\xed\xee\xfd\xcf\x41\xad\x7b\xd0\x26\xcf\xb9\x3a\xe7\x87\xf1\xca\x52\x5f\x6e\xb9\xd0\x8e\x8f\xe5\x69\x4c\x51\x1d\x08\x7f\x2c\x0f\x54\x23\x4c\xd3\xca\x59\x6e\xaf\xe2\x44\xf0\x5c\xb3\xfa\x6b\x0e\xf8\x7a\xab\x78\xcd\x8b\x28\x8f\xb7\x22\x93\x53\x67\x37\x03\xdd\x13\x54\xc0\x6f\x77\xc5\xba\x3a\x18\xa6\x39\x69\xce\xb5\xea\xd1\xc5\xff\xda\xa1\xbf\xb4\x78\xd0\x0f\xb8\x17\xfa\x8b\xf7\xb4\x9f\x8b\xff\x35\x59\x64\x0a\x2c\x56\x4a\xe8\xd0\xe9\xb3\x67\x84\x91\xc9\x09\xf5\x05\x1a\x2f\x7a\x9f\x18\x61\xd1\x3b\xd3\x31\x2f\x2c\x4e\x3f\x55\xd4\x4a\x09\xf1\xb4\x3e\x1d\xe9\xd0\x71\x54\xfa\x14\xf4\x53\x2a\x08\x0c\x62\xff\xc7\x4e\xb5\xe2\xff\xf0\x54\xf8\x51\x3f\x15\x9e\x5c\x92\xae\xa1\x2b\x0d\x59\x6a\x39\x84\x16\xf8\x1e\x6a\xa7\xc6\x51\x63\xbd\x62\x45\xac\x6d\xdf\xd4\x3e\xf5\x35\xa4\x1d\xdf\x41\x4a\x7d\xc4\xb8\xe8\xb3\x7e\x55\x56\x2e\x7b\xaf\x27\x91\x9b\xe6\xc7\x1a\x6c\x93\x11\xc6\xea\xef\xc3\xea\xb9\xa1\x38\x8b\xaa\x77\x5e\xdd\x22\x69\x19\x7b\x25\xff\x97\x88\xc5\xee\xff\xd7\xc4\x62\xfb\x7f\x84\x58\xec\xfe\x08\xb1\x48\xfe\x67\x89\xc5\xee\x7f\x94\x58\xb4\xed\x97\x3f\x65\xc8\x72\x60\xbd\xf1\x7f\xc1\xe8\x05\xdb\xfe\x63\x18\x1d\x7f\x12\xa3\xff\xc5\x0e\x1d\x18\x97\x6d\x55\x95\x5f\x17\x6f\x6a\x9c\x56\xf6\x9f\x34\x25\xa6\xa9\x8d\x60\x5f\x8f\xa0\x86\xf9\x52\x23\x51\x9f\x32\xa3\xd1\x90\xdf\xa1\x29\x03\x16\x52\xa5\x55\xe6\x58\x73\xf1\x82\xeb\x4b\x01\x30\x96\x01\x9d\x98\xeb\x36\x25\xa4\x6d\x74\x17\xaf\xac\x8f\x19\xd9\xe8\xb6\x9c\xd5\xfa\x41\x7b\xcc\x4f\x5a\xbf\x56\x76\x3f\x72\x20\xab\x3c\xdb\x00\x95\x6c\xb7\xff\xc7\xed\x57\x8a\x6d\xce\xc3\x65\xbf\xe9\x8a\xb4\x32\xa9\x81\xba\xd6\x37\x05\xc6\xa9\x25\xc6\xcc\x21\x40\xf4\x17\xdc\xb3\x38\xe3\x76\xce\xb7\x49\x18\x71\xeb\xc4\xbf\x1e\xff\x72\x5d\x04\x23\xcb\x26\x8b\x93\x5b\x6d\xbb\xd3\xed\x9b\xc4\x42\xd8\x22\xfb\xdb\x76\xcb\xf3\xcf\xc3\x82\x5b\xc4\x33\x0c\x20\x5b\x76\xb1\xbb\x29\x44\x6e\x39\xd4\x25\xb6\xc8\xde\x66\xf7\x55\x86\x11\xaf\xd2\x5c\xb9\x57\x8a\xa6\x77\x37\xfa\xae\x54\x79\x75\xcc\x3f\xe2\xd5\xc1\x6d\x91\xc7\x1b\x0b\x56\xed\x21\xdd\xd5\xb2\x41\x7a\xce\x97\xbb\x88\x5b\x9d\x71\x54\x4e\x18\x0d\x36\x1b\x9e\x01\x1b\xf7\xda\x12\x76\x91\xc4\x11\xb7\x1c\x9a\x13\xd8\xc3\xab\xf7\x7c\x04\x63\xc2\x76\xeb\x85\x67\xa3\x61\x76\xf1\x73\x2c\xd6\x96\x71\xcf\x6f\x7e\x8b\x85\x41\x16\xdc\xb7\x52\x96\xd1\xd4\x8e\xd6\x61\xfe\x4a\x58\x0e\x69\x03\x6b\x94\xaa\x2a\x5d\x42\x02\x16\x7b\xdc\xcf\x02\x16\x53\xbe\x27\xf4\x69\x2f\x1d\x13\x36\x6c\xe8\xa2\xbd\xd6\x86\x0d\x1d\x65\x51\xf5\x8a\x3c\x35\x30\xbb\x3a\xb0\xd6\x66\x7c\x01\x0f\x9e\x66\x55\x08\xec\x05\xda\x0d\xa2\xb8\x0d\x4f\x95\xac\xbd\xe0\x5e\x77\x35\x99\xe6\x04\x2a\x51\xab\x65\x51\xc9\xe8\xdc\x77\x82\x46\x44\xe7\xbe\x1b\xec\xbd\x1e\x23\xe3\xc5\x11\x99\x9e\xef\x95\xd5\x61\xd3\xf5\xdb\x16\x2a\x75\xdd\x60\x4c\xb3\x32\x2a\x7e\xe9\x94\xe5\xb0\x27\x79\x91\x58\x4f\x7b\x0a\x75\x78\x4f\xfb\xa6\xda\xc7\xc6\xa0\x5c\x8e\x93\xa6\x8c\xdb\x9b\xb0\xf8\x8d\x66\x8c\x57\x7e\x10\x31\xe3\x76\x94\x84\x45\x01\xbd\xa3\x21\xe3\xb6\x88\x45\xc2\x69\xc1\xae\x2c\x41\x68\xc4\x6e\x2d\x03\xd3\x79\x61\x50\x3f\x00\x26\x28\x0a\x85\xb5\x6c\xe1\x17\xb6\x82\xd5\x17\xdb\x18\xd0\x88\xdb\xdb\x5d\x52\x70\x6c\x68\x15\x3f\xf0\xe5\xcf\xf1\x12\x1d\x78\xb8\x1d\xa7\x77\x3c\x2f\x64\x53\x37\x68\x4b\x46\x0b\x80\x72\x5c\x88\xaf\x05\xdf\xd0\x08\x8a\x24\xf1\x96\xee\xa0\xba\xf8\x03\xa7\x5b\x58\x8e\x99\x40\x7f\x15\xba\x92\x75\x27\x74\xc9\xac\xc4\x12\xec\xc9\x58\x85\x63\x68\xd5\xf0\x52\x0a\xcf\xd8\xb0\xe1\xe5\xf8\xb2\xba\x37\xbc\x0c\x9f\x54\xb3\x86\x17\xe3\xab\x6c\xd9\xf0\x42\x7c\x4b\x62\xc3\x2b\x64\x81\x24\xde\x8e\xd7\x59\x1e\x7f\xc8\x52\x11\x26\x86\x67\x68\x2f\x80\x41\x65\x69\xdc\x64\x62\x8d\xcf\x4d\x89\x3b\xd8\xbe\x23\xcc\x5f\x3f\x76\x73\xef\x31\xbb\x51\x41\x70\x47\x68\xaf\x59\xe3\xce\x34\x95\xdd\xf6\x8e\xd0\x04\xed\xb1\xc2\x31\x0e\x9f\x37\x85\xb7\x47\x0a\x6f\xeb\xc2\xdb\xa6\x30\x80\xab\x29\xba\x3a\x52\x74\x55\x17\x5d\x35\x45\x8b\xfb\x70\x3b\xce\xb6\x61\x14\x8b\x47\x83\x72\x1b\xde\xbf\x93\xaf\x04\x76\xd8\x1e\xf7\xb0\xe5\x71\x32\xb5\xf4\x79\xb0\xe0\x68\x2f\xfe\x07\x28\x15\x1a\xf3\xd3\xa5\x15\x6b\x7e\x6d\xc0\x09\xee\x00\x25\x45\x1e\xa6\xc5\x2a\xcb\x37\x06\xed\x59\x7c\x76\x9d\xbc\xc8\xed\x65\xf3\x66\x69\x29\xc4\xd3\x5f\xe8\x0a\x6a\x85\xc5\x61\xd0\x2b\xe0\xaa\xe8\x9a\xd5\x46\x95\x37\xc4\x2a\xe8\x16\x16\x59\x44\x9f\xf6\x74\x07\x7f\x56\xf4\x49\xae\x20\x2f\xa3\xb8\x62\xbc\x10\xa4\x9e\x78\x65\x0d\xd7\xa4\xbb\x5d\xcb\x15\xc2\xe7\xc3\x4d\xed\x63\xd6\x2f\x6c\xb4\x1c\xd0\xd0\xdb\x4f\x7d\x21\xf2\x93\xe2\x7f\xb9\x6e\x74\x6e\x19\x9f\xd7\x8e\x04\xab\x38\x5d\x0e\x60\xad\x1b\xb4\x20\x14\x00\x8d\x7b\xcb\x0d\x5b\xdb\x21\x6c\x36\x61\x24\xe8\xab\x7f\xc5\xaf\x4f\x90\xa7\xc7\xca\x7a\x1a\x58\xa3\xa2\x63\x88\x6e\x09\x52\x96\xd6\xab\x8a\x8b\x40\x37\xbf\x3b\xeb\x06\x68\xe4\x2b\xb2\x7f\xb4\x97\x71\xb1\x4d\xc2\x47\x20\x2e\xcc\xf8\x22\x4b\xc5\xab\x7b\x5e\x64\x1b\xfe\x35\xf6\xf1\x11\x79\x23\xd8\xd5\x0b\xf6\x24\x97\x24\x7a\x64\xdd\x64\x59\x42\x6b\xaa\xe4\x69\x5e\x5d\x30\x43\x5e\x8f\xf7\x97\xa4\xf1\x8d\x8f\x98\xe6\x09\x16\x10\xda\x90\xa0\xa6\x7a\x45\x10\x9a\x0f\xb0\x90\x9b\xaa\x2d\x5f\x5f\xf9\xb4\x59\xd6\x54\xae\xe8\x80\x48\xb5\xec\xbf\xdc\x97\x8a\xd0\x35\x0d\xc3\xfa\x6c\x35\x5c\x79\x4b\xe1\x01\x74\x40\x28\x92\xb4\x26\x7f\x45\x0b\xf5\x32\x97\x0e\x75\x2f\x1c\x3a\x39\x77\x02\x42\x81\x6a\xb6\x2a\x4c\x6e\x0d\x6a\x3c\x14\xb0\x56\x60\xc1\xb8\x0f\x06\x35\x26\xf0\x67\x0a\x7f\x66\xf0\xe7\x14\xfe\x9c\xc1\x9f\x73\xf8\x73\x01\x7f\x2e\xe1\x8f\xeb\x3c\x40\x1f\x80\xc4\x36\x5d\x50\xa8\xdf\x33\x78\x09\x5b\x7d\xc0\x72\x75\x68\x73\x58\xaf\xba\xbe\xf2\x9a\xf7\x9e\x84\x23\xb4\xdd\x50\x9d\xba\x0b\x7b\xda\xc6\xcb\x1a\x7f\x86\xae\x86\x39\x86\x21\x31\x06\xdd\x0e\x34\x2c\x18\xba\xf5\xfc\x0f\x5d\x39\xf3\x98\x05\xa7\x14\x9f\xea\x69\x1a\xba\x72\x82\xf0\xab\x9c\x89\xa1\xdb\xcc\x01\x7e\x46\x80\xcb\x27\x00\xd3\xd0\xad\x00\x34\x74\xd5\xf0\x0d\x43\x1b\xb6\xcc\xa9\x0d\x6a\xe8\x4a\xa1\xe8\xae\x16\x9e\x06\xdc\x6a\xdc\x43\x58\x57\x8a\x7d\x39\x31\x4d\xc9\x45\x0c\x99\x26\xc0\x4e\x74\x01\x76\x82\x02\x6c\xaf\x07\x54\x5a\x3b\x9a\x62\xab\x19\xb3\x80\x35\x8b\x93\x65\xce\x53\xe9\xd2\xde\xa6\xe0\x8d\x9e\x42\xf6\x6a\x8f\x7c\xa0\x4e\x3b\x52\x3b\x14\x22\x8f\x6f\x76\x82\x17\x65\xf9\xb4\xff\x18\x9b\x99\x33\x3d\x37\x88\x1e\xc5\x7d\x0c\xfc\x9c\x20\x4f\x51\x58\x70\xc9\x6e\x18\x1e\xc7\x5c\x45\xc3\x9d\xb0\x9c\x2e\x79\xc2\x05\x1f\xe8\x15\xc8\xf4\xf9\x4d\xce\xc3\xdf\xe6\x58\xbe\x10\x8f\x09\x6f\xca\xe3\x2b\xbb\xb1\x72\xa2\x32\x29\xb4\xf1\x9c\x96\xbf\xb2\x11\xe6\x71\x38\x36\x48\x59\x76\xbe\x2f\x43\x01\xdf\x17\xaa\x3e\x5f\xb4\x19\xf9\x80\xe5\x55\x53\x3e\x8c\x21\x60\xb9\xe6\x28\x44\x9f\x30\x05\x18\x33\x42\x43\x96\xcb\xde\xd0\x82\xd5\xfa\xfe\x70\xf1\xb4\xf7\x42\x1a\xb1\x95\x95\x53\x5f\x75\xbe\x91\x65\xe3\xd6\x28\x70\x13\x6a\x7d\x82\xbd\xa8\x20\x54\xa8\x9d\x41\x56\x4b\xfd\xd4\x16\xe1\x2d\xd5\xb3\x43\xc6\x88\x68\x0c\x5c\x46\x08\xd9\xdb\x37\x71\xba\x94\x5e\x39\x85\x1d\x76\x7c\x21\xff\x3f\xa0\xfa\xfe\x0f\xf5\x3d\x6a\x8b\xd7\xbf\x01\x13\x4d\xb3\x36\x76\x93\x79\xdf\x66\xfd\x31\xbd\x01\x48\xf5\x2c\xab\x80\xfd\x51\x0d\x43\xfa\x51\x4e\xe8\xd3\xda\x1a\xde\xd5\x95\x11\x9a\xfd\x11\x8d\xf6\x1f\x54\x06\x67\xbd\xca\x60\x4b\x8f\x55\x71\x31\x23\xc4\x16\x1f\xec\x24\x0b\x97\x56\x6a\x5d\x9c\xfe\x11\x47\xb7\x43\x7c\x3a\xf4\xae\x6f\x7c\xb8\x9a\xe6\x44\xed\xb9\xbb\x80\x4a\x86\x0e\xf1\xba\x2e\xa9\xbc\xce\x72\xe8\x87\xf9\xeb\x5f\x77\x3c\x7f\x1c\xe4\xfc\xf7\x5d\x9c\xf3\x62\x10\x2a\x57\xe1\xc1\x7d\x2c\xd6\x83\x70\x50\x95\x6c\x4e\xcc\xa0\xda\xbd\x07\x00\xdc\xf7\x3b\x22\xc9\x0a\x16\xf2\xc7\x43\x9f\x40\x8d\x76\xd2\xac\xc7\xa5\x2f\x66\x7e\x40\x43\x96\xd6\x1d\xa5\x85\xa6\x86\xfa\xbe\x52\x98\x7c\xb7\xa2\x11\x8b\xa5\x70\x4c\x13\x16\x2b\x7c\xa2\x3b\x16\xa3\x3a\x94\x6e\x59\x5c\x11\x2a\xba\x62\x4f\x7b\xba\x64\xab\x5a\xcb\x42\xd7\x6c\xd5\x61\xd7\x28\x70\x82\x75\xfa\x86\xdd\x48\x4d\x8c\x6c\x9a\xd0\x2b\xa8\xe2\x96\x1d\xa2\x61\x1f\xfa\xf3\xc6\x81\x54\xf3\x23\xb6\xd3\x6c\xc9\x61\x3b\xdf\xd3\xc7\x9e\x8a\x1a\x5f\x66\x8e\xc2\xb5\x04\xda\x9e\xde\xb1\x27\xa8\x01\x56\x7d\x91\x47\xf0\x93\x66\x69\xc4\xe5\xc3\x55\xb6\xdc\x49\x2a\x30\xd7\xdd\xa5\x35\xbc\xa2\x19\x8d\x99\x95\xb2\xb4\x2c\x43\xd2\xa6\x62\x96\x21\xd7\x8a\x81\xcc\x79\x6c\x0b\xfe\x20\x18\x6c\x46\xa8\xd6\x03\x4a\x75\x47\xac\x8c\x09\x3f\x0f\xca\x12\xc1\xff\xaa\xda\x5b\x40\xf4\xd6\xdf\xad\x9c\x10\xd3\x8c\xed\xa2\xf5\x8d\x66\x64\x9e\xda\x6b\x1e\x2e\x81\x06\xf3\x74\xf9\x39\x6c\xa5\x56\x4c\xec\x6d\x98\xf3\x54\x7c\x9b\x2d\xb9\x9d\xf3\x4d\x76\xc7\xab\x94\x8e\xa7\x76\xc7\xc9\x9c\x8f\x0c\xc3\xeb\x59\x0c\x5d\x87\xef\x4a\xd3\xb0\xf2\x97\x95\x42\x2d\x68\x7c\xbb\x9b\xa3\x07\x80\xd0\xfd\x01\x67\xa1\xc5\x9a\xe0\xf6\x2a\xb5\xe3\x34\x16\x72\x77\xa7\x1f\xd8\xc9\x7b\xff\xba\xb8\xde\x7d\xf1\xe6\x8b\x2f\xae\x1f\x5e\x39\xc1\xa8\xec\xbc\x3f\x3b\xb9\x6d\xe6\xe2\xbb\x46\xd3\x30\x1c\x02\x5a\x48\xda\x8b\x7e\xe4\xa6\x59\x69\x50\x68\xcb\x7d\x78\x78\x8b\x2a\x96\xa1\xd4\xb4\xc0\xee\x9b\x87\x8f\x30\xac\x54\x6d\xc0\x2d\xa7\x53\x35\x16\x61\x9a\xe2\xa5\x63\x9a\x62\xec\xe2\x16\x43\xf6\xf7\xf6\x2a\x65\xf7\xda\x91\xf0\xd3\xaf\xe8\x9d\xed\x19\x53\x7b\x66\xbb\x06\xd5\x0e\x6d\xbc\x7b\x2a\x7b\xe2\x39\x54\x64\xa8\x40\xf1\x7a\xfc\x9c\x24\x2c\x61\x19\x93\x3d\xbd\xe5\xa2\xef\xac\xa8\x9a\x2a\x3d\xb3\xc7\x5f\x38\x0b\x78\xf2\xf9\x08\xc3\x05\xc9\xc6\x02\x4f\x7e\x0b\xf6\x14\x96\xec\x8f\x22\x8c\x7e\xf3\x0e\x94\x27\xec\xde\xde\xf0\xfc\x96\xcb\xf8\x43\x5a\xa7\x2d\x42\x35\x97\x6b\x7b\x9b\xf3\x3b\xb9\x5a\x31\x24\x11\x15\x7b\xca\xc3\x68\xdd\xd7\xc7\x7b\x1b\x52\xa4\x8f\x32\x27\x7b\xba\x09\xb7\x7d\xd9\xb0\xc1\xba\x67\xd6\x3d\xf2\x7e\x1d\x22\xa6\x23\x8c\x52\x5d\x0b\x9a\x52\x01\xdb\x08\xd9\x53\xa4\x4f\x3d\xa0\xec\x54\x1d\xf5\x7b\x4d\xc3\x5e\x11\xe7\x85\x38\x56\x01\xff\xdd\x72\xc8\x9e\x26\xe1\x47\xb3\x8c\x5d\xb2\xa7\xfc\xf7\x1e\xc8\x6a\x73\x41\x53\x36\xe2\x23\x0b\x27\xca\x73\x1a\xb0\xb6\xfb\x99\xbe\x64\x8e\x69\xa6\x2f\xc4\xc2\xc7\xa9\x4b\x83\xc0\xf3\x03\xa8\x3e\x5d\x1e\x1d\x65\x3d\x2f\x65\x79\x38\x85\x72\xea\xbd\x1d\x2d\xb2\x5c\x78\xb1\x0d\x3f\xb4\xd8\x22\xd8\xa4\x7a\x23\xe2\x7b\x7a\x6f\xf3\x07\xc1\xd3\x25\x03\xa4\xae\x9e\xbb\x3a\x04\x20\x7a\x14\xe9\x1d\x0d\x35\x5e\xc6\x09\x80\xed\xa6\x05\x73\x69\x74\x20\x2e\xd0\x84\x0d\x5d\x3c\xc6\x30\x40\x74\xe2\xa1\x4e\x3f\x42\xd3\xb4\x12\x16\xb6\x6a\x2b\x54\x6d\xa3\x11\xa1\x87\x84\x28\x2c\xcb\x5b\x2b\x04\xb9\x3f\x64\x4f\x7b\x42\x0b\xc6\x58\x64\x9a\x56\x28\x51\xb2\x18\x8f\xc9\xbc\x78\x11\xcd\xa1\xb8\x3a\xfe\x19\x32\x8b\xb7\xea\x27\x48\x7e\x25\xa3\x48\x72\xd4\x1d\x50\xa3\xb6\xcb\xc0\x0d\xc5\x34\xc3\x21\x63\x39\x74\xcf\x34\xe1\xe7\xde\x8e\x8b\xef\x93\x30\x4e\x2b\xc5\x0c\x74\x21\x63\x5d\xe7\x73\x42\x16\x56\xca\x42\xa8\x31\x66\x99\x69\x76\x54\xa6\x29\x59\xf8\x81\x97\x95\x65\xb7\x3a\x8c\x65\x80\xbc\xdf\xd0\xa5\x50\x9c\x55\x13\x62\x25\x34\xa6\x39\xa9\xfc\xc5\x55\xaf\x30\x4b\x4e\x6a\x2c\x0a\x9b\x19\xb4\x9e\xf8\xc3\x36\x4c\x97\x99\xa7\xf8\x0d\x63\x64\x29\x82\x34\xba\x0a\xc5\xda\xce\x21\x71\x63\xa1\x3a\x5e\x9d\x33\x5c\xbf\x3e\xb9\xa5\x86\x41\x68\x5c\xfc\xc0\xc3\xe5\x23\x6c\x7d\xa8\xf3\x69\xa1\x74\x97\x9f\x81\x85\x9d\x66\xd9\x56\xc7\xcb\x3d\x6d\x0d\xec\x70\x49\xd0\x74\xde\x8a\x06\x52\x9d\xde\xc8\xfc\x01\x40\xbf\xde\x51\x80\x38\x0f\x2d\xc1\x0a\x78\xee\xdd\x81\xac\x94\xad\x2b\x9a\x60\x68\x68\x6f\xa0\xea\x5a\xfb\x40\x4c\x53\xf1\x1b\x29\x61\x8c\x6d\x08\x74\xf4\xcd\x66\x2b\x1e\x8f\x75\x74\xae\x23\x49\x15\x62\x44\x3d\x38\x7b\x7a\x9b\x64\x37\x61\xf2\xe6\x2e\x4c\xbc\xb6\x98\x09\xcc\xc1\x93\x64\x20\x60\xcb\xb0\xf1\x71\x4f\x0e\x68\xa5\x7e\xf2\xe1\xe0\x71\x21\x8c\x12\x1a\x4d\x6b\xc5\xff\x3c\x7f\x91\x9a\xe6\xd0\x05\x94\x54\x40\xf1\xf3\x80\xe6\x14\xc3\x5a\xe1\x49\xa0\x8c\x83\x50\xf3\x13\x1c\xb0\x7e\x28\xa3\x61\x1d\x14\x20\x52\x06\xad\x79\x6f\x2a\xf2\x78\xf3\xb1\x2d\xc6\x30\x3c\x0b\x38\x82\x06\x55\x3e\x00\x9a\x00\x3d\xff\x8d\x77\x36\x31\xed\x70\x5f\x80\x20\x7f\x18\x40\xe6\x3b\xab\xf1\x8d\x5f\x54\x7b\x4e\xda\xa7\x43\x5d\xf8\x3c\xf0\x38\xf1\x76\x55\x34\x0c\x8e\x11\xbc\x68\x9c\x1e\x36\xaa\xf3\x13\xd8\x6d\xb1\x18\xbb\xde\xb6\xc2\x0a\x8e\x5c\x05\xb6\xd5\xe9\x6b\x1d\xff\x8b\x8d\xaa\x53\x0e\x98\x0a\x3c\x37\x68\xc0\x8f\x40\xe6\x7e\x36\x1a\x05\xc8\xa7\xd5\xd0\x53\x79\x58\x46\xf9\x9e\xde\xe6\x7c\x7b\xd0\xab\x3a\xf0\x07\x30\xdc\x19\x73\xf0\x08\x42\x35\x14\xb2\x61\x3a\xcf\x5e\xc4\xf3\x6c\x34\x22\x43\x61\x71\x3f\x0b\x68\x46\x86\x8c\x85\xa6\x99\x4b\xef\x7e\xf8\x56\xaf\xf0\xbc\xbb\x89\x76\x39\x50\x87\x86\xcc\x0f\x5a\x88\x94\x37\x23\x89\x5f\xe4\xf3\x78\x34\x22\x8a\x20\x66\x0c\x9a\x8c\x03\x1a\xd3\x14\x96\x59\x28\x5b\xcc\x34\x74\x8a\x25\x3a\x7d\xb2\x40\xe5\x80\xad\x36\x58\x90\x2d\x80\x77\xd9\xc5\x4b\xcf\xa5\xc5\x6e\x0b\x92\x93\x77\xb5\x27\xf4\x63\x06\x2e\x16\x6c\x3b\x07\x8e\xfa\x2c\x3e\xf8\x44\xa8\x62\x2d\x8c\x3f\xcb\xdd\x64\xf0\x2d\x32\x6a\x03\x29\x56\xd4\x91\x7e\xe4\x51\xd6\xe0\x75\x28\xf8\xe0\x07\x7e\xfb\xe6\x61\xab\x28\x8c\xa4\x5d\xaa\x61\x43\x53\xef\x77\x4f\x57\x57\x7e\x4d\x9b\x30\xf4\x59\x60\x04\xac\xa3\x7e\xa9\x4c\x8d\xde\xb1\x1e\x32\x57\x6d\x94\xb4\xa0\x11\x4d\xe8\x8e\x6e\xe9\x8a\x2e\xe9\x9a\xde\xd0\x0d\xbd\xa2\xb7\xf4\x91\xde\x31\xa3\x88\x3f\x7c\x48\xb8\x31\x72\x9f\x03\x5d\x85\xee\xd2\x57\xac\x91\x21\xe9\x2f\xcc\xa1\xf7\xcc\xa1\x1f\x58\xc4\x2d\x42\xbf\x93\x3f\xef\xe4\xcf\x83\xfc\xf9\x96\xf5\x9e\x0b\x73\x15\xa2\x6f\xcb\x86\x0e\xa1\xce\x9e\xbe\x3d\x8c\xe5\x42\xdf\x00\x6e\xfe\xc8\xde\xd8\xdb\x6c\x4b\x3f\x87\x5f\x10\xed\x7e\xab\x1e\x7e\x67\x6f\x94\x04\xf8\x33\x3b\xb6\x7a\x1c\xaa\xe1\x59\xfa\x22\x9f\xa7\x72\xef\xe5\x7e\x1a\x60\x6c\xa8\x5a\xe1\x27\x1f\xc6\xee\x9e\xbe\x66\x06\xba\x10\xf3\x65\x59\x60\x2c\x23\xbe\x2c\xc3\xe2\x31\x8d\xca\x70\x27\xb2\x55\x16\xed\x0a\x7c\xda\x26\xe1\x63\x19\x65\xa9\xc8\xb3\xa4\x28\x97\x7c\xc5\xf3\x72\x19\x17\xe1\x4d\xc2\x97\xe5\x3a\x5e\x2e\x79\x5a\xc6\xc5\x26\xdc\x96\x49\x96\x6d\xcb\xcd\x2e\x11\xf1\x36\xe1\x65\xb6\xe5\x69\x99\xf3\x70\x99\xa5\xc9\x63\xa9\x04\xee\x65\x59\x44\xd9\x96\x2f\x0d\xfa\x67\x66\xf8\xd7\xd7\x0f\x13\xe7\xfa\x5a\x5c\x5f\xe7\xd7\xd7\xe9\xf5\xf5\x2a\x30\xe8\xf7\xcc\xb0\x16\xde\xf5\xf5\xf5\xb5\x5d\xfa\xd7\xd7\xf7\xe3\xa0\xf4\xdf\x5f\x3b\xe3\xeb\xeb\x87\xd0\x09\xc8\xc8\xa0\x7f\x67\xc6\xf5\xb5\x6f\x8c\xfe\x3c\x32\x9e\x5b\xc6\xe8\xfb\x91\x41\xac\x85\xa7\xde\xfd\xe7\xef\x9f\x95\xc3\x7f\x06\x0b\x46\xd4\x97\x85\xf7\x99\xd5\xd4\xf8\x1e\x7e\x3f\x0b\xc8\x73\xf2\x59\x79\x6d\x74\x13\xae\x0d\x48\xb9\x36\x4a\x55\x2f\x29\x55\x2d\xd7\xd7\x81\x41\x7f\x65\x86\xd7\x34\x78\x7d\x6d\x59\xd6\xbf\x5e\x35\x29\xbb\x29\x16\xf1\xaf\xaf\x83\xa0\x34\x46\x7f\x1f\x19\xe4\x39\x29\xed\xe7\xe4\xfa\x1a\x9a\xa6\x3f\x30\x69\x06\x0c\x8b\xc7\xfa\xf3\xc8\x18\x19\xd4\xb8\x35\x08\xfd\x5a\xff\x6e\xbc\xc7\x3e\x8e\xb0\xe2\xf7\xaa\xd2\x80\x54\xad\x90\xe7\x72\x0c\xa3\x67\xaa\xf0\x57\x3d\x85\x9f\x53\xf9\x63\x10\xfa\x45\x5f\xb2\xe5\xbf\x1c\xfd\x13\xba\xf8\xe7\x91\x41\xea\xac\x7f\xeb\x74\xaf\x7c\x69\x10\xfa\x93\xfe\xf1\x57\x42\xff\xab\x5b\xdf\xf7\x23\xe3\x99\x41\xe8\x97\xec\xe9\xeb\xd7\x5e\x2b\xed\x4f\x0a\xba\x06\xa1\x9f\xbf\x7d\xf5\xe3\x8f\xed\xd4\xeb\x6b\xbb\x49\x7f\xf7\xea\xcb\x76\xaa\x4c\x2a\xfd\xe7\x01\x24\xbf\x7a\xf7\xee\x07\xaf\xd3\xee\xdf\x09\xfd\xfe\xc7\x37\x7f\x7b\xfd\x5d\x37\xe1\x57\x42\x3f\xff\xea\xeb\xb7\x9d\xce\x78\x16\x22\x2e\xca\x26\x25\x48\x1f\x65\x2a\xd6\xf0\x7f\x0c\x2f\x64\x6c\xa1\xca\xbc\xcc\x56\x63\xb4\x38\x96\x18\xa1\xa0\xc5\xef\x78\x5a\x66\xcb\x65\x69\x59\xfe\x68\x1c\x94\xc4\xba\xbe\x5e\x3e\x27\x69\xd9\x20\xa5\x4a\x50\xef\xd7\xd7\xcb\x11\x29\x49\x8d\x6d\x38\xfb\x46\x6c\x10\x0a\x1c\x7b\x67\xa4\x80\xec\xaf\x47\x06\x79\xa6\xb2\xa4\x9c\x2f\x8b\xcf\xb3\x54\xf0\x07\xd1\x1d\x1b\x54\x27\xe7\xce\x6b\x7a\xc5\x7f\x2f\x6f\x45\x99\xc8\x11\x35\x03\x6c\x8f\xc1\x5a\x78\xe3\xeb\xeb\x25\x59\x60\xd7\xb5\x8e\x59\x0b\xe6\xbf\x1f\x07\xe5\x33\xd5\xc5\x3d\xfd\x0b\x3b\xf9\xea\xdd\xd5\xdb\x67\x27\x31\x7d\xc6\x4e\xa0\x83\x71\xba\xdd\x09\x45\x57\x4a\xe8\x57\x98\xf3\xb0\xbc\xd9\x09\x91\xa5\x04\xf2\xfd\x95\x9d\xbc\x5f\x5f\x2f\xe1\xf1\x1b\x76\xf2\xde\x7f\xff\x14\x8c\xae\x9f\xae\x8b\xe7\xd7\x7e\x1a\x8a\xf8\x8e\x0f\xae\xef\x4f\xe8\x3f\x64\x6d\x7f\xb2\x7c\x20\x04\x23\x52\x5a\xd7\xf7\x23\x52\x5e\xdb\xd5\x07\xf2\xec\x84\x72\xce\x4e\xfc\xd1\x3f\x83\x13\x2a\x78\x0b\xd7\x70\x71\xf9\xd7\xd7\xcb\x70\xbc\x0a\x9e\x5c\x7a\xb6\xc7\x51\x2c\x4a\x39\x44\x52\xda\x38\x82\x5b\x04\xe1\x81\xf5\xbb\x64\x1b\x0c\xe7\xc1\x18\x89\xf1\xd9\xe9\xe9\xf4\xac\xe6\x03\x40\x02\x28\xcb\x74\x21\xbc\xfc\x85\xb3\x50\x36\x4d\xab\x3c\xdb\x7c\xbe\x0e\xf3\xcf\xb3\x25\xb7\xf2\x11\x96\x20\x5e\x6f\xe2\xcb\x97\xae\x53\x9e\x9e\x4e\x2e\xcf\xa8\xeb\x4c\xa6\x66\x5e\x9e\x9e\x4d\x27\x20\xe5\xe6\x9c\x9d\x58\x3e\x90\xbb\x07\x77\x75\xfd\x70\xbe\x0a\xca\xf7\xe3\xc5\xf5\x92\x94\xef\xc7\xcf\x14\x21\x54\x29\xe3\xeb\xdd\x17\x5f\x7c\xf1\x05\xc0\xe1\xe4\x96\x66\xbc\x7f\x07\x12\x0b\xe3\xda\x31\x64\xc4\xc2\xeb\xdd\x6a\xb5\x5a\x1a\x1e\xaf\x2d\x7a\xc6\x2e\x19\x19\xd7\xd7\xc6\x88\xa3\x6d\x0e\xf4\xee\x95\xa8\xad\xc5\xc6\x68\xb4\x24\x47\x60\xb9\x67\x64\x64\x0c\x0c\x4f\x66\xdf\xd3\x98\xeb\xb2\xe9\x0a\x84\xdc\x90\xb3\x3b\xde\xa7\xc5\x1e\xa2\x63\x83\x5d\xed\x1a\xa6\x69\xac\x62\x9e\x2c\x0b\x8e\x62\xa5\xd4\x19\x7e\x1b\x6e\x78\x77\x6b\xa7\x4f\xcb\x38\xf7\x8c\x46\x8f\x66\xd0\x14\x70\xdc\x48\xf8\x2d\x4f\x97\xc6\x9e\xa0\x4d\xd0\x6f\x8a\xef\x79\xc3\x7e\x97\x2c\xe7\x2b\x79\x9c\x05\x25\x0a\x42\xdb\x6f\x6f\x7c\xfd\xbd\x52\xd2\x34\x6a\x4b\x69\x5b\xf4\x1d\x27\x4f\xbf\xb1\x27\xac\xd7\x7b\x53\xd9\x00\xb5\x21\xfc\x79\x7d\x1a\xaf\x9a\x15\x84\xec\x8f\x32\xb8\x5c\xe3\x6f\xe7\xdc\x4f\x15\x33\x3b\x1a\x05\x73\x32\xaf\x39\x59\xd8\x99\x35\x1b\x9e\x82\x23\x36\xe6\x34\x53\xc6\x8a\xb4\x50\x7c\xcc\x1a\xf8\x17\x86\xd2\x4d\x76\x9f\xf2\xfc\x75\xc3\xad\x88\x85\xa8\x87\xe3\x5d\x62\x84\x37\x40\x57\x3f\xa8\xd9\xfc\xa1\xae\x54\x04\x11\x10\xa4\x9b\x5f\x4c\xf3\x52\xfe\xb8\xf8\x5a\xf1\x0c\x18\x0e\x6e\x98\x99\xa6\x65\x41\xcd\xad\xd6\xca\x52\x78\xaf\x80\x63\x5e\x9a\xe6\xca\x12\x84\x0a\x10\x3c\x96\xf4\x86\xa0\x26\xde\x55\xf5\x5a\x5b\xf6\x0f\x9b\x3f\xf0\x08\xb8\x62\xe0\x4b\x62\xb6\xf5\xdd\x00\xf3\x5c\x32\x68\x4b\x46\xc4\x4d\x18\x2a\x5c\x95\xe6\xf6\xcf\x8f\x5f\x2f\xad\x98\x90\x56\x47\x12\x3b\x5e\x62\x7c\xb8\xea\xa3\x64\x82\x13\x42\xf3\x3a\x8e\xdc\x2d\xaa\x34\x6e\x7b\xaa\x32\xcd\x47\x4b\xd0\x84\x98\xe6\xa7\xea\x81\x0e\x6d\xfd\x49\x50\xa5\x57\x38\x96\x53\xbd\x8b\xc5\x9f\x1f\xdf\x85\xb7\x80\xba\x68\xac\x82\x3d\xc4\xc1\x4d\x03\x62\x9a\x69\x3b\xe7\xe7\xd5\x41\xa6\xd2\x2b\xf7\xa4\x7c\xb2\xb5\x3a\x27\x8c\x86\xe6\xfb\x78\x65\xa5\xf6\xef\x45\x68\x9a\xc3\x07\x9f\xc3\x02\x0d\x40\x60\xdf\x94\xe5\x70\x63\x0b\x5e\x08\x25\xc2\xe3\x44\xb4\x03\x7f\x1e\x59\x75\x72\xe6\xae\x18\x07\xf4\xa2\x20\xc5\xfe\x62\x9a\x7f\xab\xeb\x42\x8c\xb6\x76\xac\xa3\x19\x37\xe2\xa5\x41\xc8\x62\xc7\x76\xb5\x98\x9a\x73\x9a\x71\xe2\x89\xb6\xba\x1c\x32\xd2\x1d\xbb\x23\xb4\x60\xd6\x9a\x85\x50\x67\xc5\xb8\x16\xe3\xf1\x9c\xac\xfd\x22\x60\xc6\x9f\x8c\xd1\x0e\x46\x33\x7a\xe4\x16\x7c\x21\xf3\x2b\xb6\x56\xd1\xfd\xa8\x41\xe8\x2d\xe3\xbc\xea\x93\x69\x5e\xa1\xf3\x4f\x4d\x25\x48\x59\x8a\x3d\xc6\x56\xeb\x42\xf3\xf6\x30\x76\xe7\x15\xc2\x51\xae\xfa\x7b\xf2\xf4\x60\x71\x3a\x74\x9a\xc0\x6b\x3b\xc6\xd8\x1d\x4c\x98\xd4\xe0\x77\x46\xbc\xaf\x63\xb1\x45\x56\x63\x33\xfa\x35\x35\x9e\xb9\x06\x51\x0b\x57\x0b\x7a\xcd\x2b\x2d\x1e\x6b\x64\xf3\x3a\x55\xc8\xb3\xa2\x5a\xb6\x45\x7c\x4c\x01\x08\xe4\x65\x6e\x47\x61\xb4\xe6\x6f\x11\x4e\xa6\xa9\x8e\xc1\x85\xcf\xed\x62\x1d\xaf\x84\x45\x02\x2a\x7c\xcc\x1b\xb0\x4c\xa3\x1f\x09\xd7\x8d\xaa\xfc\xbb\x80\x0d\x9d\x96\x3f\x00\x6f\xf4\xa4\xcb\xee\xb9\x49\x4d\xa3\x25\x95\x55\xa4\x7c\xc8\x2d\x41\x34\x2a\x59\xe9\x65\x9a\xa0\x76\xda\x4c\x00\xe0\x8e\x9c\x82\x20\xb1\x40\x53\x30\xcd\x80\x9f\x1f\x52\x4d\x25\x1d\x96\x68\x8d\x5a\xc5\xd7\x9b\x67\x80\x2a\x39\x9e\x6c\x7f\x15\xa6\xcb\x84\xfb\xa9\x9f\x05\x01\xd3\xac\x68\x57\xbc\xa5\x0f\x31\x4d\x4e\x73\x96\x9a\xa6\x5b\x6f\x39\x40\x20\xe5\xbb\xd0\xde\xb9\x5d\x64\xbb\x3c\xe2\x5f\xa7\x4b\xfe\x30\x16\xfa\x9b\x8c\x96\xa9\x93\xa3\x14\x85\xfc\x79\xca\x52\x8c\x0f\xf8\x63\x7c\x93\xc4\xe9\xed\x1c\xf5\x9e\x9a\xe0\x35\x76\x6b\x9d\xc5\xc2\xf5\xc6\xae\x66\xde\xcd\xfb\xec\xbb\xeb\xfd\xdb\x40\x46\xca\x60\xc7\xd7\x2b\x80\x18\x4f\x3e\x18\xe3\x1a\x28\xd7\xc7\xea\x55\xe0\x38\x52\x9b\xea\xa6\xd5\xb4\x9b\x96\xa5\x21\xf9\x36\x7c\x3b\xd6\xde\xcd\x27\xc6\x81\xb6\x7a\xb1\xb4\x94\xd6\xf1\x43\xe9\xc9\x2a\xd6\x60\x61\x24\xe1\x0d\x4f\x64\x4e\xed\x59\x2b\xd3\xaa\xa0\x2e\x08\xdd\xf1\x44\xf7\x35\x2e\x5e\x6b\x1f\xca\x52\xff\x32\x64\x6c\xc8\x4d\x33\x04\x7c\xee\x2b\xad\xb5\x0e\x63\xd6\xd3\xb4\x71\x6f\xf4\x71\x27\xbc\xd7\xdf\x45\xb0\x91\xa0\xad\xb4\x94\xe6\x0d\x96\x67\x34\x66\xdc\xf2\x03\x5a\x61\x37\x15\x84\x86\xac\x76\x36\x08\x01\xd7\x53\x3f\x63\xb1\x1f\x06\x01\x46\xd5\xcf\x02\x36\xb4\x72\xf8\x81\x67\xe9\xae\x41\x34\x4a\x73\xc5\x3b\x8e\x4d\x7d\xe7\xd6\xbc\x77\x23\x33\x4d\xbe\xaf\xd5\xae\x29\x2b\xb8\xad\x14\x48\xd2\x59\xa3\xe0\x76\x5c\xfc\xfd\xea\xed\xa1\xba\x05\x16\x55\xb8\xe1\xc5\x36\x8c\xf8\xdf\x7e\xf8\x9a\xa6\xcc\xe2\x5d\x6e\x81\x93\x5a\xad\xa2\x1a\xae\xd4\xb9\x7f\x91\xd4\x5c\x94\x65\x0a\x1b\x67\x85\x9d\x65\x69\x80\x64\x01\x42\xc6\x0a\xfb\xc2\x45\x55\x5b\x8f\xc2\x27\xa3\x21\xe3\x8b\xc3\x56\xbd\x57\xb5\x92\x5e\xf2\x2a\xc0\x74\x84\xda\x9a\x0f\xbb\xdd\x5a\x58\x6b\x66\x2d\x59\x78\xd0\x5f\x7a\xc3\x86\xb1\xb5\x24\xf4\x95\xac\xc9\xca\xd8\xb2\x32\x44\xfb\x29\xe6\xf7\xc4\x34\x33\x5b\x64\xdb\x21\x63\xc0\x32\x65\x76\xb8\x5c\xbe\xb9\xe3\xa9\x78\x1b\x17\x82\xa7\x3c\x5f\x1c\x7e\xb2\x8c\x5d\x9a\x64\xe1\xd2\xa0\x31\xa7\x43\x97\x78\x19\x10\xb6\x30\x5a\x63\x2e\xa8\x50\x7b\xb5\x8c\x2c\x6d\xb2\xa3\x67\x54\x63\x0c\xc5\x76\xbd\xfc\xf7\x40\xb3\xf1\x66\x46\x6c\xd0\x21\xef\x6c\xdf\x75\xb2\x21\x6f\x6a\xe8\x45\x8d\xe3\xb5\xeb\x07\xdf\xd5\x3e\xf2\x79\xb6\x91\xfb\x88\x41\x88\x6a\xf0\x90\x6b\x32\x9e\x1b\xd5\xf6\xdf\xd3\x6e\xcd\xed\xb0\x6f\x24\x7a\x2c\x8f\xf1\x4d\xb2\x24\xb0\x79\xc7\x3a\xb9\x6e\x75\x92\x13\xe0\xff\xee\xe8\xb0\x53\xa3\xc4\xb9\xbe\xaf\xd6\xdd\x41\x47\xa1\xb9\x85\x55\xb9\xba\xd9\x5f\xbf\xee\x5d\x14\x15\x57\x20\x38\x4d\x9b\xa3\xdc\x5e\x30\x1e\xb2\x54\x18\xd5\x7c\x4f\xa1\x8d\x74\xd9\x6e\xe1\x63\xb1\x71\xbb\x6c\xb4\x69\xde\x34\x94\xbf\xc3\x16\x37\x7d\x4a\x17\x7e\x1a\x78\x7e\xb0\xdf\x13\xef\xbf\x61\x58\xb2\xbd\xe3\xa4\xa7\x1e\xaa\xdc\x09\x0e\xbf\x49\x10\xd4\xbd\x03\xba\x80\x86\x63\xff\xed\x40\x91\x7a\xe2\x5e\xd0\x80\xb0\x82\x55\x5a\x29\x8b\x8f\xf4\x90\xe8\x3d\xab\x78\x78\x3f\x96\x61\xc7\x33\x26\x7a\x90\x89\x13\x79\xe4\xc4\x32\x25\x02\xfe\x7b\x2d\x28\xee\x13\xa7\xac\x82\xc7\xbb\x57\x5f\xb2\xfe\xf5\xbb\xe8\xd3\x10\x7c\x12\x54\x5a\xf9\xa3\xa2\x8f\x87\x42\xc8\xa2\x37\x8e\x7e\xe5\xef\x72\xe4\xdc\xad\x3e\x97\x39\x5a\x39\x1a\xb1\x3e\x47\x4d\x81\xdc\x34\xe7\x29\x8b\xf1\x34\x68\x4e\x80\x7b\x48\x35\x42\xae\xc4\xb8\x54\x3b\xb3\xa9\x9d\x9a\x2b\x00\xa1\x6a\xb1\x0b\x22\x4d\x38\xfb\xd7\xb1\xa9\x5d\xfe\x86\xd4\xe6\x1a\x47\x64\x37\x4e\xf6\xf4\x0a\x46\xbe\x81\x3f\x52\x82\x6b\x48\x5c\x17\x86\x28\xc0\x75\xa9\xda\x21\x39\x4b\x53\x9e\xc3\x5e\xc9\x8c\x17\xe1\x20\x5e\xb2\xcf\x8c\xd1\xdd\xc8\xf8\xec\xe5\x8b\x93\xf0\xe5\x0b\xa9\x89\x6b\x3e\x8f\xaf\xf3\xeb\xeb\xcf\x06\x9b\x22\x4c\x92\xec\x3e\x0a\xb7\x62\x97\x73\xf6\xd9\x67\x2f\x5f\x64\x5b\xa5\x79\x90\x47\x02\xf8\xed\x44\x7e\x7c\xf9\xe2\x44\x7e\x7e\x69\x50\xde\x73\x0b\x82\xdf\xae\xee\x3d\xfb\xec\xb3\xa0\x26\xef\xa6\xb9\x91\x73\x63\xf8\xcf\xdf\x3f\x0b\x58\xa3\x9d\xff\xac\xbc\x36\xae\x51\xa9\xdb\x5b\x69\xd5\x93\xa6\xaa\xb2\xac\xaa\x6a\xce\x01\x16\x1e\x2e\x8f\x52\x6a\x46\x8f\xd5\x15\x2f\xff\xc9\xe4\xf8\xfb\x6a\xfb\x27\x3b\x52\xce\x53\x07\x25\x3d\x65\x9a\xa4\xde\x92\xe1\x9f\xb0\xb9\xd1\xf3\x9e\xa2\xf6\x9f\xec\x91\x3f\xfa\x67\x20\xb7\xdc\xee\x04\xf3\xce\x8c\xae\x73\xbe\x62\x9f\x7d\x36\xa8\xf9\xd0\xcf\xaa\xa7\xf6\x14\xf7\xa6\xcb\xf9\x3b\xd1\x26\x70\x7e\x44\xe8\x93\x7c\x3f\x99\x77\xc5\x76\xc0\x7a\x83\x1a\xf2\xbc\x07\x07\xab\xe3\x9f\x20\x9d\xec\xc0\x09\x1a\xd4\x78\x7d\x6c\x22\x20\x9d\x2d\xfb\xb0\x03\x4b\x4a\xb5\x75\x7d\x94\x63\x10\x3a\x19\x82\xd4\xd6\x33\x35\x3c\xc5\x41\xf6\xd4\x54\x27\x51\xc3\xab\x60\x61\x10\x7a\xb0\x72\x6a\x88\x0d\x9d\xe3\xcd\x34\x15\xfc\xd1\x76\xfa\xaa\x79\x4e\xbd\x07\x83\xd0\xaa\x24\xb5\x9f\x7b\x38\xfb\x04\x88\xc0\x06\x64\x6a\x5e\x54\x05\x2a\x82\x70\xcb\xd6\x55\x52\x59\xae\x6d\xe9\x55\x79\xd5\xce\x0b\x09\x9b\xec\x43\xcf\xd7\xac\x2f\x67\xd1\xf9\x08\x14\xa6\x8b\x7f\x29\xc0\x25\xca\xd2\x14\x17\x1f\x16\x60\x95\xe3\x2e\xc5\xd3\x9f\xe6\xcd\x2f\x86\xb0\xd6\x71\x6c\x57\x6a\x6c\x43\x66\xd0\x5f\x11\xb3\x37\x6c\x53\xc3\x4c\x53\xcf\x6f\x94\x3a\xa7\x04\xfe\xf0\x8a\x5d\xf5\xe5\xb9\xd2\xf3\x88\x0a\x22\x6b\x3b\xca\x36\x20\x03\x56\x2c\xfe\xf7\x59\x11\x43\xbf\x09\x7d\x64\xa2\x2c\xb5\x6c\xa9\x08\xe3\xb4\x20\x8b\x3e\x13\x89\xcb\x96\x22\x60\xc1\xbb\xac\xbe\xc7\x69\x2e\x35\xac\x8d\xbc\x39\xd7\x0e\x76\xf3\xb2\x1c\x5a\xc3\x5c\x6a\x4f\xf3\xba\x22\xf8\x9a\xd6\x4d\x2f\x9a\x47\x2b\x27\x1e\x3f\xd6\x75\xd3\x74\xcf\xcc\xa3\xa9\x68\xd6\xd4\xdd\x41\xe3\x95\x25\xad\x58\xe7\x82\xb5\xfa\x08\xcc\x84\xd0\x18\x85\xa1\x33\xaf\xb5\x34\xf4\x5b\x26\x16\x07\xf5\x70\xfd\x90\x78\x0b\x0b\xc1\x51\x01\x3c\x86\x47\xfb\x34\x1e\x8a\x63\x49\xf5\xe6\x5b\x96\x96\x6b\x5a\x79\xaf\x24\xc8\x18\xb3\x0e\xd5\xc9\x64\x71\x1c\x08\x82\x78\x2e\x29\xcb\x61\x8a\x06\x74\xaf\x39\xc8\x44\x7c\x29\xad\x8c\xfa\x4b\x60\x2b\xf9\x02\x86\xb7\x2c\xcb\x4e\x27\x18\x63\xaf\x4c\xf3\xd1\x7a\x45\x39\x59\x8c\x5d\x4f\xc8\x5c\xe2\x58\x2e\x41\x16\xae\xb7\x5b\xfc\x6c\xed\x28\x27\x63\xf8\x11\xc4\x73\xbc\x99\x99\x43\x69\xb7\x6f\x7e\x8e\xc1\x35\xad\xad\x5c\x9a\x69\x43\x16\x48\x7b\x0d\x99\xcf\x03\x5a\x30\x75\x4b\xcb\x30\x2b\xcb\x61\xad\xae\xc6\x11\xd5\x9d\x5e\xb8\x5e\x06\x2f\x71\x5f\x07\xa1\x70\xa6\xab\xba\x95\x62\x6c\xae\xec\x9c\x50\x79\xa5\x63\x4f\x68\xef\x52\xa9\x56\x4c\xab\x4c\xe2\x20\x53\xd1\xcd\x34\x0f\xfd\x3c\x60\x8c\x15\x7e\x1e\xcc\x49\x3e\x1a\xd5\x48\xb0\x58\x71\x0b\x12\x29\x24\x11\x4f\xe5\x7b\x05\x1d\x2e\xaa\x67\xd7\x73\xf6\x74\x49\xbc\xe5\x9e\x16\xbc\x22\x77\xfd\x27\x5a\x78\x26\x82\x1e\x2b\xf8\x47\x10\xbd\x48\x4d\x3c\x0f\xa6\xa2\x0f\x05\xab\x83\x0b\x94\x1f\x3b\x35\x98\xe6\x0d\x2a\xd5\x45\xad\x54\xbf\x2a\xcb\xe1\x95\x52\x53\x48\xbb\x38\x4d\xcd\x2e\x08\x21\x22\x7f\x54\xa7\x86\x35\x69\x94\x51\x28\xf2\xb2\xec\x21\xa7\x80\x90\x15\xc9\x51\x87\x2e\xcd\x87\x9a\x9c\xd4\xea\x46\x4d\xe7\xfa\x20\x1d\x1f\xf6\x0d\x44\x04\x5d\x4a\x70\xf8\x3c\x20\xb5\xbf\x38\x42\xa6\x22\x3f\xbd\xd0\xfc\x04\x54\xd0\x5d\x47\x02\x38\x14\xa2\x0b\xd5\x8f\x17\x56\xbe\x65\x2d\x25\x6d\xd7\x77\x4a\x5a\x68\xbe\x55\x77\xfb\x68\x39\x69\x27\x27\x59\x60\x9c\x2b\x3a\xbc\xa9\xe4\x89\x0a\xbd\x6a\x9b\xcc\x78\x11\x7b\x6d\x3f\xb4\xe1\xcd\xa2\x23\x53\x0b\xe2\x59\x31\xeb\x91\x34\x85\xb2\xec\xdf\xf2\x08\x2f\xe1\x5a\xc4\xb6\xf2\x51\xda\x25\x09\x8e\x9f\x17\x51\xb8\xe5\x3d\x2e\x0d\x1d\xeb\x3c\x79\xec\x21\x8b\xe4\x79\x0b\x13\x0f\xcd\x37\x8d\x1f\x1f\x53\x11\x3e\x0c\x30\x27\x1d\xec\xd2\x9c\x47\xd9\x6d\x1a\x7f\xe0\xcb\x01\x7f\xd8\xe6\xbc\x28\xe2\x2c\xf5\x06\xc6\x48\x55\xb9\x4b\xe3\xdf\x77\xfc\xc7\x2c\xef\x53\x7f\x69\xc2\x14\xae\xfa\x2d\x1b\xa6\xf6\x92\x0b\x1e\x89\xd7\xbb\x6d\x12\x47\xa1\xe0\x05\xdd\x31\x45\x40\x7f\x44\xe7\x2a\x54\x78\xcb\xe3\x60\xe0\x59\x20\xc1\xfa\x96\xd0\xad\x12\xb5\x04\xe3\x7e\x8c\xa2\x16\xee\x28\x7e\x1c\xa0\xce\x4b\xc9\x59\x31\x51\x8b\x1f\xf5\xf1\x5c\x99\x32\xa3\x66\x92\xba\x35\x7e\xee\x50\xcf\x4f\xf9\x9e\x66\xac\x40\xe0\xbf\xe3\x0f\x7d\x03\x48\x99\x61\x20\x65\x8c\xb5\x8d\xb9\x11\xc1\x5d\x79\x19\xd5\xa5\xfc\x71\xf1\x55\x0a\x68\x7d\x2e\xe0\xfc\x41\xa0\x4d\x44\x2a\x9a\x7b\xec\xb4\x8f\xd8\x6f\x8e\xf1\x09\xf2\x42\x20\x33\x38\xe7\x73\xf8\xa0\x29\xf2\x49\x3a\x62\x19\x88\x6b\xd5\xd1\xe2\x54\xb6\x3d\xd3\xe9\xa9\xec\xea\x4f\x80\x2e\xfb\xda\x74\x0f\x01\x27\x45\x7b\xac\xa3\x71\x96\x4f\xf7\xd4\xca\xa5\x2e\x53\x52\x9a\x82\x3d\x69\xa7\x3b\xde\xa9\x43\x25\x4f\xfe\x7d\xc1\x77\xcb\xcc\x4b\x38\x45\xd2\xe4\x7d\x49\x9b\xf5\xe1\x3d\xed\x29\x08\xb3\xf0\x9b\xf3\x04\x2d\x26\xbc\x27\xe3\xa5\xe1\x1d\x1e\x99\x4b\xeb\xfa\xa1\xb3\xa7\xc6\xa0\x27\x7d\x4f\x8d\x51\xfd\x39\xe7\x77\x71\xb6\x2b\xd4\xf0\x5b\x65\xff\x79\x2c\xd3\x7e\x4f\xb7\x39\xff\x02\xb5\x45\xde\x13\x5a\xde\xf4\x69\xb7\x7c\x37\x60\xf0\xa7\xa3\x39\xa2\xdc\x9f\x06\xcc\x82\xbf\x65\xc9\xfd\x19\xfe\x3d\x0d\xca\x52\x5f\x54\x2a\x2b\x48\x68\x88\x85\x93\x00\x6f\x66\x9b\x06\xcc\x80\xb5\xe1\x4f\x03\x3c\x27\xa3\x8d\x65\xc3\x8c\xec\x95\x51\xcf\x47\xfb\xd2\x22\x32\xd4\x48\x65\xac\x06\x4c\xaa\x6a\x9a\x92\x85\xea\x5d\x51\xdf\x0c\xeb\x3b\x01\x74\x7c\x16\xb0\x91\x05\x3f\x0b\xe8\x32\x3c\x9e\x05\x65\xe9\x12\x6f\xf2\xdc\x32\xf8\x1d\x4f\x65\x65\x53\x74\xcb\x59\x2e\xab\x37\x02\x65\x4f\x65\xd9\xf3\x60\xc4\xfd\x8b\x83\x0c\x1e\xfc\x98\x66\xb7\xc5\x7d\x65\xc1\xd4\xb7\x76\x86\xd0\xbc\x69\x02\x74\x2a\x5c\xfb\xd2\x46\x18\xa8\x93\x52\xa8\x43\xc6\x44\xc1\x01\x2d\x20\x27\x6b\x83\xdc\x4b\x4d\xf3\x27\x99\x1d\x43\x13\x09\x16\x5a\x29\xec\x35\xf2\x25\x6d\xdc\x62\x89\x51\x9f\x57\x8c\x05\x19\x57\xcf\xf2\xca\x3c\x07\xea\x75\x1a\x18\x0a\x18\xf1\x24\x60\xa9\xf6\x45\x9f\xad\x29\xc1\x2b\xa0\x14\x0a\xbd\x7b\xf5\x65\x8f\x1f\x47\x57\xe5\xd8\x7b\x70\xa5\xf4\x44\x8b\x03\x37\x8d\xa1\xd3\x1f\xf4\xad\x3e\x69\x00\x3a\xd8\x7f\x26\xa6\xd4\x8d\xd2\x22\xed\xb0\x5f\x1f\xd4\xb9\x7b\xed\x4d\x82\x97\x45\xea\x76\x48\xd6\xfb\xda\x70\x8e\x8f\x0c\x69\x7c\x54\x3e\x23\xa8\xd6\xfb\x60\x71\xda\x7b\x51\xb3\x9c\x84\x3e\xca\x16\x35\xaa\x26\xed\xa5\x2c\xff\x80\xa6\xb5\xab\x65\x55\x8a\x7f\x83\xe0\x72\x43\x4f\xcf\xce\xfa\x6d\x19\x77\xd7\x9f\xd5\x95\x81\x48\xce\x81\x28\x59\xb9\xe6\xa5\x24\x4d\xc0\xb3\x05\x88\x80\xd0\x6f\x6f\x08\x20\xc9\x46\x40\xdc\x0d\xf9\x69\x01\x0c\x69\xea\x55\x39\x16\xd9\x10\x5f\xdf\xab\xd7\xd4\x34\x1d\xc6\x58\xa6\x85\xd6\xf2\x8c\xe7\x4d\xa2\x9e\xf0\x72\xec\x7a\xc6\x33\x3d\x4d\x22\x55\x83\x91\xb2\xa9\x7f\xaa\x2c\x16\x50\x8c\xac\xc6\xa5\x1f\x80\x28\xa2\x65\x13\xe9\x56\x5a\xca\x12\xb8\xdf\xe1\x39\x68\x56\xe3\x6b\x55\xf7\xc8\xc5\xda\x47\xc6\xd8\x40\x0c\xee\x52\x9c\xca\x5b\xa7\x0a\x35\x86\x04\x06\xf9\xbc\x06\xf3\x69\xc8\x8c\x24\x2c\x84\xfe\x7d\x3c\x23\xb4\x60\x86\xb2\x2d\xc4\x6e\x54\xd0\x85\x5d\x2f\x57\xf0\xe9\x89\x71\x38\x1c\xea\x32\x85\x86\xf3\xd0\x93\x48\xf6\xa3\x65\x09\xcd\xe2\x21\x63\xe1\xc2\xd0\x76\x3d\xa3\x67\x23\xd8\xb4\x85\x93\x2b\x56\x48\xc7\x8a\xbe\x05\x43\x6f\xd9\x30\x32\xcd\x61\x41\x1f\xd9\xd0\x85\xfd\x7b\x83\xdb\x74\xac\x78\x8a\x9b\xb9\x7c\x58\x31\x31\x5f\xb1\x95\x7f\x23\xf5\xdf\xc5\x62\x75\x7c\x05\x5e\x79\x30\xf0\x55\x97\x2d\x1e\xba\xf3\x35\xbb\x61\x46\x96\x26\xe8\x3d\xc8\x4d\x73\xb8\x36\xcd\xd6\x68\xf6\x35\x05\x88\x57\xd6\x9a\xf9\xe1\x62\xa3\x6d\xfa\xde\xc6\x06\xe8\xe3\x73\x40\x43\xd3\xbc\x95\x9d\x7b\x64\xd6\x92\x59\x09\xb3\x76\xcc\xda\x32\x6b\xc5\x36\xc4\xbf\x0b\xca\xd2\x5a\xf9\x77\x01\x7b\xda\x13\xe2\xaf\x14\x3b\xf6\xf5\x6b\xf8\xbe\xd5\xdf\x65\x06\x1e\x60\x38\x05\x20\x87\x68\x46\x93\xf8\x6e\x40\xe0\x67\x12\xd0\x15\xf0\xc9\x1b\xcd\x14\xcd\x5f\x06\xf3\x15\x1b\x8d\x80\x7d\x36\x4d\x80\x4a\x59\x5a\x8f\x6c\xc9\x1c\x52\x96\x6b\x7b\x9b\x6d\x2d\x82\x70\x6a\x03\xc2\x34\x47\xa3\x47\xd3\x5c\xa1\xa4\xf9\xb4\xf3\x79\xc0\xfc\x5f\xe8\x92\x3e\x06\x32\xdc\xc1\xbe\x65\x16\x05\xf5\xe9\x83\x12\xff\x4d\x83\xa2\x78\x8e\xff\x28\xd5\x11\xd6\xa7\x86\x01\x9b\xc4\x47\xa6\x7b\x88\xd3\x3d\x6c\x4d\x77\x59\x0e\x47\xa3\xc7\xb2\xc4\x51\xc8\xee\xaf\xfe\x8d\xae\x03\x6c\x1e\x03\x42\x57\x78\x43\x23\x99\xd7\x06\x0f\x8f\x63\x96\x11\xa9\xd4\x79\xfc\x5f\x39\x63\xcc\x31\xcd\xc7\x93\xfc\x25\x73\xf6\xfb\x9e\x5d\xb7\x39\xc1\x40\x5e\x18\x39\xb5\x02\x41\x93\xdb\x05\x17\x92\x19\x2a\xfc\xce\xc0\x74\x1e\xc2\xd8\xa5\xea\x60\x9d\x2f\x07\xb2\x02\xc9\xe7\xd7\xc1\xd4\xfc\xbb\x60\x01\x8c\xa3\x97\x55\x02\x9d\xbb\xb0\x52\xe6\x73\xca\xa9\x61\x50\x11\x50\xbd\xad\x6e\x60\x9e\xae\x59\xd7\x22\x69\x47\xe3\xd0\x9d\x63\x40\x0c\xc3\x31\x1d\x98\x1d\x70\x3f\x67\x3f\x5b\x9c\xc6\x7e\x18\x90\x80\x0d\xe5\x8d\xfe\xf8\xb6\x27\xa4\x6f\x47\x85\x8a\x1c\x0c\x12\xe2\x65\xc0\x19\x4a\xd0\x78\x4f\x69\x26\xbc\xa4\xa3\x63\x94\x1b\xa8\x1f\x50\x75\x43\x67\x71\x68\x44\xd5\x1c\xe4\x00\x38\x3a\x63\x00\x9a\x96\x35\xe3\x88\x69\xc8\xf2\x4a\x39\x90\x51\x3f\x20\x32\xb4\x98\x66\x5d\x66\xc5\x2c\xf4\x8b\x40\x72\x29\x05\x0c\x48\xc0\x4f\x4c\x3a\xc3\xa1\x19\x8d\x9b\xbd\x18\xf9\x19\x9a\x03\x0d\xc5\x28\x31\x34\x25\x14\x3f\xe2\xeb\x30\x95\x58\xbd\xdf\x13\x42\xd7\x61\x71\x30\xcc\xa3\x56\x31\xca\xbe\x53\x13\xd8\xa1\x8a\x4a\x60\x3f\x56\x0f\x3f\x60\x85\xe8\x61\xd5\x96\xd0\x85\x9d\xb2\x04\x44\x6a\x76\x38\x0e\x3b\x1c\x36\x96\x84\xe9\xed\xb1\x86\xfe\x4b\xf1\x8d\xc8\x1c\x1c\x43\x5d\xac\x00\x11\x97\x1e\x76\xac\xb3\x2f\x1c\xd8\x21\xcd\x97\x19\x46\x08\x65\x37\x0b\x61\x63\x4d\x5d\xbb\xc2\x87\x4d\xe2\x41\x02\x74\xa0\x9b\x26\xbf\xab\x9d\xc0\x4a\x59\xda\x41\x79\x69\xf3\xe3\xe0\x11\x61\x3d\x72\xdc\xab\xf7\xf7\xeb\x18\x06\xdd\x56\x9c\x92\xae\x31\x18\x69\xf4\xa6\x00\x2b\x79\x7f\xb7\x77\x68\x4d\xc5\xed\x24\x8b\x42\xa9\xc6\x6d\x9e\x61\x45\xae\x5b\xa7\xd7\x55\x94\x43\x19\x60\x66\xb9\xa7\x79\x96\xf5\xfa\x97\x73\xc6\xd8\x7a\x4f\xd1\x09\xe7\x58\xfa\xd2\x0e\x23\x10\xfb\x94\xb6\xda\x34\xad\xe1\x12\x9a\xfc\x02\x3d\x77\xca\xe6\x19\xe9\xed\x70\x08\x14\x01\xd5\xd3\xdc\x5e\xe7\x7c\x55\x96\xff\xe4\xb6\x08\x6f\xd0\xb0\x0d\x9d\x9b\xf1\xe0\xc2\xbb\xe1\xd6\xd0\x25\xb4\x3a\xc8\xc0\x77\x87\x50\x75\xcc\xd5\xcb\x97\x7f\xd4\x94\x4c\xb3\x60\x83\x5e\x70\xbb\x72\x3a\x2a\x0d\x79\x2a\xa5\x25\x55\x47\x7d\x7b\x5a\x3d\xf5\xf3\xec\xba\x01\x99\xfe\x56\x57\x80\x83\xa2\xca\xec\xbc\xa9\x95\x6f\xb6\xe2\xb1\x55\xe5\x1f\x52\x02\xc4\x2b\xab\x51\x47\xbc\x38\xeb\x73\x45\x95\x7d\xe8\xe9\xed\xb0\xde\x1d\x6c\x6c\x1d\xcf\x7e\xd7\x3c\x5c\xf2\xbc\x6f\x6c\x7f\x55\x4b\xae\x86\x29\xd9\x53\x04\x60\x5f\xe6\x67\x3d\x99\xa5\xa9\xde\x7f\x38\x4d\x9a\xc1\x5f\x85\x34\xda\x27\xb1\xa7\xe8\x69\x72\xe8\xae\xdb\xad\xea\x58\x9b\xa6\x69\x40\x0d\x4d\xfd\xa6\xa9\xa2\x04\x5b\x82\x75\x25\x14\xe4\x80\xd1\xf7\xb8\x2a\xd3\xd5\x0d\x56\x01\x04\x36\x3a\x19\xab\xa0\xe4\x3b\x81\xa4\x73\xdd\x0c\x9a\x16\xd4\x17\x63\x17\x73\xf1\xdf\x0f\xf2\x34\xe2\x8f\x9f\xbe\x70\x16\xe9\x48\x78\xa9\xcc\x7b\xc7\xd3\x9e\x1a\x35\xa7\xbc\x79\xfa\x42\xcc\xd3\x11\x9b\x54\x57\xa6\xa7\xda\x35\x0c\x84\xd0\x6c\xb9\xfc\x68\x05\xee\xa7\x2a\x48\x0e\x87\xd4\x76\x7a\xad\x7b\xfc\x52\x2c\x84\x97\xce\xc7\x63\xe0\x68\xe6\xda\x15\xee\x7a\x75\xb7\x7f\xb8\xba\xf9\x68\x94\xbf\x10\x47\xea\xd9\xef\x49\x8d\xf3\xa9\x58\x33\x6d\x05\xfc\x4e\x9f\xf2\x70\x19\x67\x18\xed\x09\xe8\xc0\x4d\xf6\x00\xcf\xab\x58\x46\x7c\xda\x86\x45\x71\x9f\xe5\x4b\x78\x8e\x37\xe1\xad\x0c\xfd\xd4\x30\x58\x22\x60\xa8\xac\xad\x1d\xc3\x9f\x8a\xdd\xcd\x26\x16\x90\x3f\xe7\x05\x17\x87\xf9\xd7\x32\x7f\x65\x19\x79\xcb\x2d\x3d\x6c\xec\x23\x6f\xc7\x90\x72\x68\xcb\x53\xc3\x30\xe6\xe2\x45\x8a\x41\xa4\xf2\x11\x46\x29\x90\x6a\xe1\xc6\xba\xa4\xae\xe9\x8e\xb7\x1d\x87\x84\xbd\x8c\x73\x9a\xc1\x6e\xc2\x1f\x04\x70\x58\x65\x99\xd3\x90\xa5\xa6\xa9\x6b\xdf\x18\x63\x31\x2d\xd8\x7d\x73\x5e\x22\x24\x31\x5a\xb4\x24\xb7\xac\x56\xc7\xa2\x03\x74\x25\x06\x08\xed\xd4\x31\xac\xf5\x91\xaa\x44\xb3\x79\x7d\x4c\x0a\x04\x8e\xb8\xc0\x13\xa6\xe8\xb0\x8d\x9e\x46\x4c\x93\xab\x5a\xea\xd3\xc5\x96\xd6\xf3\x23\xfd\x8b\x57\x92\x71\x17\x92\x71\x17\x35\xe3\x2e\x3a\x8c\xbb\x68\x33\xee\x34\x33\xcd\xec\x23\x26\xd0\x44\x54\xe1\x7b\xe6\x95\xeb\x86\x95\xb0\x9d\x1f\x4b\x61\x4b\x17\x54\x18\x63\x45\x7d\x0e\xe6\x4f\x02\x06\xb2\x18\x0c\x1e\x72\xb3\x15\xc5\x6f\x87\x03\x6c\xd8\x80\x7a\xbe\x5f\xb5\x4c\x6c\x1b\x0e\xbd\x05\x6a\xdd\xca\xb7\xe1\x44\x51\x59\x8e\x81\xaa\xfc\x2c\x50\xf9\x7a\x36\x15\x0c\x35\xac\x85\x0a\xe2\xba\x3e\x41\xe7\x79\xfd\x80\x16\xcc\xc1\xc8\xb9\x75\xc0\x0f\xe9\x33\x2e\xea\x40\x1c\x56\xcc\xb8\x62\x7c\x53\xd3\x1c\xa6\x56\x8c\xf5\x94\xa5\x15\x56\xaa\x7c\x9a\xe0\x59\x37\xbc\x14\x44\x8f\x6b\x51\x77\xe1\x5e\xeb\x82\xc6\x1f\xe7\xa6\x39\x04\xf6\x1c\x23\xff\xdf\x63\x98\x24\x98\xb2\x61\x26\xbf\x65\xf0\x0d\xf2\x93\xb6\x11\xb4\x72\xcc\xee\x60\x63\x40\x97\xf0\x67\xcd\xc2\x6a\x30\x37\x2c\xd6\xe3\x91\x77\x89\x92\x83\x8b\xac\x8e\x16\x90\x61\xb4\x00\xc9\x58\xfb\x79\x40\x53\x4d\xf1\x6e\x89\xb2\x34\x9e\x1b\xb4\x68\x4e\xfd\xfd\x22\xf0\x0a\x14\x15\x36\x6c\xc8\xcb\x72\x18\x9b\xa6\x58\xdc\x78\xbf\x70\xeb\x86\xae\x28\xc7\x1e\xd2\x2b\x96\x2e\xb2\xb2\xb4\xe2\x05\xf7\xd6\x65\x99\x63\x0c\x91\xd0\xdb\xa0\x0b\x80\x69\xa6\xd6\x86\x5e\xc9\x9c\x39\x8a\xc0\x09\xfb\x85\x5b\x57\x74\x49\x68\x6e\x25\x14\xe6\x07\xd2\x76\x2c\xa9\xfa\xb9\x43\x61\x64\xcb\x12\x7f\x87\x73\x72\xe5\x2f\xfd\x5d\x00\xf2\xc8\x46\x3d\x6d\x89\x66\x7c\x98\x95\xa5\x8c\x6d\xa6\x66\x3e\x01\x10\xed\x6a\x9b\x89\xba\xba\x2b\x59\x5d\x22\x67\x71\xe3\xef\xa0\x9e\x79\x26\x03\xfc\xa1\xc5\x59\x42\x23\x82\xf6\xdd\xc7\x4b\x5b\x09\xcb\x16\x3f\x5b\x31\xdd\x12\x6f\x05\x9f\x5e\x8e\x5d\xd3\xb4\x62\x3f\x81\xfe\x85\xf0\xb3\x05\x2a\x8f\xab\xfe\x0a\x47\x8a\x71\x0c\xaf\xaa\xe3\x9f\x35\xad\xaa\x26\xde\x15\xa1\xd9\x42\x75\x20\xa4\x57\x34\x22\x5e\xe5\x8e\x13\xd2\xab\xb6\xd5\xfa\x87\x36\x31\x06\x22\xd6\x8e\xd7\x90\xdb\xd5\x59\x87\x8f\xea\x65\x60\x0d\x00\xf7\x43\x10\xbb\xeb\x24\x63\x60\x04\x34\x62\xe1\xc2\xf5\x1c\xba\x3b\xe2\x92\x28\x5d\xf3\xf7\x84\x16\x14\xd8\xdb\xed\xb1\x6c\x3f\x5b\x82\x4a\x69\xa9\xca\xba\x62\xbe\x2e\x46\xd3\x5a\x17\x3a\x0c\x61\x01\x94\x65\x3a\x64\x2c\x81\x95\x65\x09\x96\x92\x06\xd5\x76\x2a\xbb\xb7\x55\x0f\x4d\x00\x22\x29\x48\x66\xfb\x60\x1e\xbd\x88\xe7\x91\x0a\x9c\xd3\x1e\x6f\xa4\xc6\x4b\x56\xcc\xbf\xe3\xd6\x2b\x6e\xad\x08\x4d\x49\xd0\xd0\xbc\xb4\xbe\x76\x43\xcb\x5e\x5d\x99\x81\x27\x70\xf0\x55\x9d\x73\x13\xe2\xdf\x05\x12\xda\x19\x1b\x8d\xa2\x79\xf6\x22\x86\x75\xac\x37\x99\xa9\x3a\x30\x42\x46\xd5\xd9\x7b\x6e\x45\x2f\x5d\xd3\x94\x1d\xc0\x47\xd8\x45\x6b\x8d\x66\x34\x76\x49\x15\xf8\x50\x05\x7a\x34\x06\xf2\x64\x23\x1a\x4f\x64\x8d\x0b\xe3\xb9\x21\x43\xe4\x1f\x38\x4d\xa5\x34\x7a\x91\x99\xe6\x87\xa6\xca\x88\x66\x40\x50\xa0\x7b\xf0\xb5\x56\x92\xd6\x5f\x71\x13\x27\xfb\x55\xc5\x23\x55\xe7\x8e\xd8\xc3\xea\xe5\x56\xbf\x38\xaa\x82\x53\xd1\x30\x27\x2d\x65\x0a\xaa\xef\x6f\x39\x0d\x59\x01\x7b\xcd\x6f\x3c\x8d\x3f\x74\x1d\x6c\x95\xfa\x47\x8f\x2f\xc1\xbe\xab\xce\x02\x60\x47\xa9\xcd\x40\x17\x8e\xb7\xab\xcf\x58\x91\x75\x29\x18\xa7\x11\x2e\x47\xe8\x40\x75\x78\x36\x2f\x94\x62\x34\x44\xdf\x0b\xd3\x1c\x5a\x19\xfb\x4a\x3a\x4e\x16\x04\xa3\x1d\x99\xa6\x55\xb0\xa2\x02\x00\xac\x01\xb5\xd0\xca\xb2\x20\x34\x52\xa4\x9c\xf9\x01\x21\x34\x65\x43\x97\x5a\x19\xfb\xa2\xae\x01\x88\x3f\xcb\x2a\x9f\x31\x2a\x83\x08\x5a\x75\x34\x4e\x8c\xc0\x87\x95\x6a\x93\x32\x30\x08\xc6\x78\xaa\x1a\xad\xd5\xea\xd2\xe0\x18\xfa\x4d\xa0\x9f\x5f\xfa\x61\xa0\x75\x35\xf1\xc3\x40\x0e\x00\x9e\x60\xae\xca\xf2\xd3\x8d\x87\x54\x61\xa7\x97\x1d\x69\x14\x4d\x61\x52\x19\x45\x67\x5f\x03\xb8\xf2\xe3\xf5\x8a\x45\x73\x64\x46\xbc\xef\x2c\x4e\x23\x52\x83\x7e\x0f\x35\x4a\xf3\xa2\x38\x39\x32\x9d\x30\x29\xb1\xdc\x51\xdf\x69\x93\x39\x2c\xe4\xcc\xc8\xc3\x1d\xf4\x5a\xa4\x69\xb3\xed\xa4\x48\x41\x0b\xf6\x81\x5b\xc2\x4f\x03\x5c\x5b\x8b\xac\xda\x4b\xbd\xb8\x7a\x9a\x5b\x05\x7b\x67\x71\xda\x1b\xb1\xa7\xd6\x02\x69\xe1\x6f\x5e\x3a\x34\x66\xdd\x1d\x93\xee\x64\x99\x2d\x5d\xd3\x0d\xbd\x62\x0e\xbd\x65\x86\x63\xd0\x47\x16\x9b\xa6\x1f\xd0\x3b\xe8\xff\x2b\x96\xd0\x7b\xd8\x39\x33\xd3\x6c\x2c\xc3\x2d\xd8\xfe\x76\x84\x7e\x60\xbf\x8c\x98\x14\xb9\x5e\x2d\x5c\xaf\x15\x94\xaa\x2c\x6d\x97\x7e\xc7\xee\xab\xc1\xe1\x6e\x21\xa3\x84\x49\x0b\xa9\xb0\x2c\x77\x64\x7e\x3b\x64\xec\xbb\x2a\x68\xbc\xb5\x65\xf7\xfe\x6d\x40\xe6\xb7\xa3\x91\xdc\xa8\x4c\x53\x99\x10\xac\x99\x43\xc3\xb2\xdc\x1e\x98\x55\x2d\xcb\xd2\x5a\x59\x5b\x98\xe7\xe1\x0d\x99\x6f\x18\xf7\xd7\x95\x2d\xfc\xc6\xda\x42\xa1\x25\x2d\x08\x79\x52\x68\xbd\x55\x01\x7c\xf7\xd0\x99\x5f\xd8\x07\xb2\x4f\x4d\xd3\xb2\xb6\x6c\xb8\x81\xc6\x4c\xf3\x6a\x3c\xa6\x40\x0e\xaa\xec\x64\x1f\xaf\xac\xab\x11\xbb\xa5\xa9\x69\x42\x77\xaf\xea\x1e\xcd\x37\x4c\xa8\xd6\x36\xd6\x23\xbd\x03\xc0\x6a\xfb\xed\xd5\x4b\x47\xaa\xb2\x6f\x61\x62\x1f\xfd\xdb\xa0\x2c\xef\xf0\xaf\x05\x3f\xec\x47\x69\xb1\x12\x11\x32\xbf\x83\x0d\xf0\x8e\xec\xab\x5d\x2d\xa2\x77\x84\xee\x4c\x13\x18\x89\xbb\x7a\x16\x4d\xf3\xaa\x8e\x70\x04\x14\xb3\x65\xca\x61\x45\x8d\xa9\x84\x1c\x1a\x4d\xd8\x2b\x42\x1f\xf7\x8d\x67\x46\xc2\xad\x98\x78\xf1\xde\x8a\x81\x1a\x92\xda\x78\x80\xf1\xda\x0a\x68\x4f\xa3\xc6\xac\x80\x1d\xaa\x49\x25\xbb\x58\x07\xc2\xe9\xbd\x5e\x8b\x9b\x26\xa7\x4b\x36\xcc\x4c\x33\xb4\x38\x5b\xd5\xed\x00\x03\x82\xdc\x0e\xc3\x10\xd1\xe8\x18\xbc\xac\x56\x25\xee\x3e\x11\x5b\x02\xab\xbd\xd4\xce\x7d\x6b\xd7\xde\x97\x13\xd3\x34\xbe\x7e\x0d\x0d\x59\x09\x8b\x7c\x27\x20\x4a\xee\xbf\xec\x78\x5f\xde\x00\xb6\xd6\x5b\x50\x84\x67\xf4\xb8\xeb\x49\x0f\x71\xc1\xac\xda\xed\xc3\x4a\xaa\xbd\x4c\x27\x59\x4a\x23\x2a\x48\x75\x4a\x41\x9a\xe0\x37\x2b\x3c\xc4\x6e\xa9\xfc\x68\xb3\x9f\x44\x15\x6d\x92\x32\x5e\x35\x38\xe4\x96\x62\xf6\xa5\xad\x87\xd9\xa8\x7c\x8f\x17\x8e\x17\xd5\xf1\x9d\xc6\x63\x5c\x25\x91\x1f\x07\x54\xdf\x48\x81\xef\x93\x83\x90\x42\xd5\x96\xc9\x31\x28\x76\x2b\x63\xdb\x8f\x0e\xa5\xf2\x74\x8e\x2a\x96\xa7\xdf\xe3\x59\x79\x6e\x47\x15\x17\x16\x53\x97\xd0\xa1\xc5\x59\x56\x5b\xd6\x3e\x72\x40\xd9\xae\x93\x39\x20\x07\x4d\xab\xd3\x22\xa5\x4d\x5d\x95\x65\x61\x71\xba\x24\xc4\xca\xd0\xee\x8a\xa6\x74\x28\xca\xf2\x13\x6e\xd7\x18\x22\x4c\x37\x2f\x62\x77\x95\x07\xaf\x41\x2a\xe3\x22\x65\xd4\x8b\xde\x4d\x77\xf4\xd0\x44\x89\x0d\x87\x5b\xba\xb2\x08\x6d\x1b\x7a\x1e\xf3\xec\x72\x3f\x62\x37\xfb\x11\xa7\xe6\x5e\xab\xfb\x5a\x9e\xeb\x33\xbe\xff\x93\xb4\xb4\x37\xa8\xf1\x27\xa9\xba\x6a\xb4\x86\x1d\x9d\x15\xe4\xc7\xf3\xf4\xb2\xdc\x2a\x15\x56\x89\x4a\xd7\x35\x8f\x6f\xd7\xa2\xbc\x8f\x97\x62\x6d\xd0\x03\x55\x8b\xdc\xdc\xfa\xfd\xc1\x04\x35\xea\xc3\xe0\xb6\xfc\xbb\x70\xbd\x89\x72\xdb\x6b\xcc\xdf\x0e\x2d\xba\x7b\xc7\x86\xba\xba\x13\x74\xe8\xd0\x46\xd3\x36\xe6\xc7\xe5\x60\x60\x70\x42\xe3\x13\x03\x97\x59\x9b\x91\xab\xa2\xfd\x03\x35\xcd\x4f\xab\x0a\x1b\x60\x54\x4e\x96\x68\x67\x75\x7c\xea\x54\xdc\xbc\x4e\xbf\x1a\xbb\xfc\xaa\x6b\xaf\x0f\x3b\x25\x43\x54\xeb\x73\x20\x35\xc8\xbe\x08\x16\x1d\x90\x7b\x18\xd8\xad\xdf\x8c\x30\xd7\xcc\x08\x73\xdd\x8c\x90\x10\x5a\xf0\xbd\x95\x92\xf9\x3d\xae\x7f\xf6\x8e\x5a\xf7\x36\x7f\xd8\xe6\xec\x5d\x63\x0d\x46\x7c\xc3\x33\x64\xf0\xc9\x6d\xc3\x9d\xde\xeb\xa6\x7f\xd5\x0b\x7b\xa7\x7d\xa5\xf7\x32\xb6\xf1\xbb\xca\xc0\x8e\xde\x4b\x57\xdd\xd7\x59\xc4\xde\xc9\x47\x7a\xdf\x98\x83\xbe\xab\x1f\xe9\xbd\xb2\x6e\xac\xad\x67\xdf\xa9\x0f\x68\xc3\xf9\x70\x10\x1a\xa7\x13\x55\xaf\x36\xc1\x4c\xe7\xc0\x9e\xfb\x02\xc8\xda\xe5\x50\xb7\xae\xaf\x35\x42\xcd\xa7\x8a\x4d\xb8\x47\xef\x25\xbc\xd7\x4e\xc5\x46\x54\xa1\xf7\xea\x4d\x31\xdf\x1f\xc4\x57\x6b\x94\xa4\x7e\xd0\xa3\xb1\xef\xfa\xf8\x73\x19\x50\x34\xad\x6a\xd6\x6c\xf1\xde\x56\x90\x46\x02\xdc\x22\xf2\x8d\xd6\xf0\x4d\x3b\xaa\xdb\x1f\x34\x1a\xea\x84\xb3\x81\xfe\xfe\xc8\x4e\xde\xbf\xb0\xfc\x70\xfc\x21\xf0\xdf\x5f\x9f\x5c\x3b\x2f\x3d\x8c\x81\x26\xae\xf3\xeb\xf4\x7a\x15\x3c\x27\x7e\xfb\xfd\xfa\x64\xf1\xd2\x5a\x78\x2f\xae\x4f\xae\xdd\x97\x25\x79\x76\x12\x37\xbd\xfa\xbc\x63\x9e\x73\x6b\x09\xb2\xb8\xb7\x6f\x73\xbe\x6d\x5b\x15\x81\x8c\x5a\x99\x87\x54\x31\x29\x69\x4e\xd1\x5a\x37\xdd\x13\xe2\x35\x3b\x70\x6f\xf9\xb6\xd0\x5c\x15\x3a\x8c\x26\x23\x3e\x5e\xba\x09\x08\x09\x02\x75\x55\xcd\x7d\x15\xfe\x5e\x05\x8a\xac\xde\x8f\x04\x64\x12\xbe\x13\x68\x87\x6a\x16\x67\x86\x97\x66\xc2\x42\xdb\x2a\x62\x10\x2a\xf5\x8e\xd5\x96\x87\xe6\x32\xfa\xe8\x90\x79\xe8\xd8\x7a\xa3\xf9\xd2\xc2\xcf\x03\xcf\x0f\xbc\x76\x16\x8b\x53\x35\x26\xd1\x3b\xa6\x36\xa6\xc9\x78\xc8\x5a\xfc\x5e\xeb\x09\xad\x34\x7b\xcc\xf5\x68\xde\x8a\x4c\x9c\xe1\x9b\x7e\x5f\x87\x66\xc3\x55\x4b\x92\x9d\x58\xcd\x78\x67\x4f\xf7\xee\x00\x25\xa8\x30\x67\x2e\x5e\xe4\xa8\xba\x8e\x57\x56\xb3\xee\xad\xcc\x17\x01\xc5\x88\xd5\x8d\x7e\x93\x90\xda\xd2\xbf\xdd\x84\x1f\x10\xaa\x57\x25\x81\x63\x71\x8a\xb5\x68\x6e\x96\x2f\xdd\x85\x4e\xa2\xac\x94\x78\x69\x6d\xd1\xd7\x67\xdf\xd6\x6e\xe7\x73\x15\xa7\x1a\x79\xcb\xa1\x4b\x30\xac\x6d\xef\xa1\xd7\x47\x0b\x3a\x04\x83\xca\xf6\x9d\xc3\x0d\x55\xce\x1e\x8b\x3a\xd3\x7c\x5b\xf3\x73\x00\x53\xaf\xee\x46\xe5\xf1\xbd\x97\xd6\xec\xbf\xd1\xdf\x65\x40\xb2\xeb\xe2\xb9\xf5\xc2\xbf\xbe\xbf\xfe\x39\x18\xbd\x24\xfe\xfb\x97\xc1\xf3\xf2\x4f\x5a\x4c\xb2\x39\x06\xd3\xc4\x98\xea\xfd\x68\x4c\x33\xdc\x67\x5a\x33\x5b\xb3\xd7\xbf\xf5\x75\x52\x31\xc0\x39\x33\x5e\x48\x65\x8a\x13\x98\xa6\xf1\x52\x3e\x37\x11\xbb\x82\x26\xe0\xfa\x4b\x36\x5d\xf8\x52\xef\x83\x76\x0b\x81\xf7\x7b\x1d\x84\xa9\x2c\x87\xb9\x0f\x99\x2b\xe3\x68\xe0\xed\x84\x2d\x83\xa7\x2f\x30\x0c\x03\x51\x53\x4d\xbc\x83\x80\xd6\xa2\x4e\x43\xef\x86\x2a\x94\x93\x60\xa2\xbe\x70\x31\x5b\x0d\xee\x17\xb0\x56\x3d\xd8\x87\x9a\xd8\xe6\xf4\x1e\x38\xc6\x82\x03\xfb\x81\x25\xa9\xa8\x0c\xc9\x70\x81\xf6\x04\x98\x0a\x71\x5e\xe9\x8f\x72\x8e\x72\x69\x43\xd5\x8d\xde\x2c\x48\x13\xd0\x5f\x90\x5b\x6c\xcb\xcf\x03\xb2\x50\x0f\x96\x40\xe7\x13\x1c\x8a\xb2\x58\x14\x32\x80\x6f\x33\x01\x15\xef\x9b\xb1\xb0\xeb\x09\x9e\xfb\x93\x40\xda\xc0\x42\x75\x4e\xc0\x32\xaa\xad\x5e\xe6\x12\xaa\x55\xa0\xdd\x82\xb0\xa8\x0b\xf0\x76\x01\xb9\x02\xbd\x5b\xc0\xb9\x66\xff\xb4\x73\x1e\x2e\x1f\x17\xea\x17\x51\xd1\xba\x07\x12\x59\x07\xfb\xb5\x64\x3d\x64\x4f\x34\x75\x16\x20\x1b\xfd\x8d\xdd\x5b\xa1\xc4\xd3\x9f\x25\x96\x4a\xd6\xbc\x28\xb7\x39\xbf\xb3\x16\xde\xdf\x52\x11\x27\x25\x3a\x14\x9f\xd0\xd7\xec\xa9\xba\xf2\x47\x5d\xbd\x22\x20\x2f\x5e\xb8\xc0\x1f\xf0\x40\x0d\x8a\xb5\x2f\x5d\xf8\x73\xb3\xf9\x6a\x3b\xbd\xdb\xd9\xe9\x9b\xb3\xc0\x16\x21\x5c\x87\x45\x5f\xdc\xfb\x6a\x40\xba\x3a\x45\x5f\xea\x47\xe8\x9b\x0c\xa3\xe4\xcc\xf9\x8b\x74\xce\x0f\x68\x9c\x8c\x8d\xef\xf3\xa0\x45\xe3\xf6\x34\x4a\xb2\x82\xeb\x71\xe4\xdb\x21\xa0\x15\x15\xae\x68\xb2\xba\xa5\xa3\x87\x20\x4b\xae\x05\x97\x70\x4d\x3a\xa4\xc2\xa0\x3a\x80\x68\xa8\xa9\x9f\x07\xf3\xd4\x34\x53\x28\xde\x71\xa3\x42\x2d\x6f\x63\x59\xe0\xba\xa6\x69\x85\x8b\x50\x1a\xab\x28\x33\xd4\xae\x87\xfb\x91\x1d\x0c\xe3\x33\x93\xa7\xb8\x3e\x27\x6e\x6b\xc8\xda\x44\x33\x6e\x8e\xab\x5a\x44\x3b\x26\x5e\x8c\x06\x07\x4b\xfe\xd0\x6b\x79\xb1\xe8\x0b\x14\xad\xb6\x75\x80\x08\x55\xd8\x4e\xea\xe0\xcf\x48\x9c\x2b\xba\x02\x44\xcb\x53\x04\x05\xe9\x97\x7a\x68\x45\xf7\x91\x93\x9e\x17\x20\x88\x03\x0a\xbe\x4a\x12\xab\x22\xc4\xde\xd8\xdd\xd3\x70\xb9\xf4\x7a\x3d\xc3\x0e\xae\x32\xd0\x86\xd6\xba\x5f\xe1\x96\x0b\x8b\x50\x44\x3d\x82\x3b\x76\xb8\x5c\xfe\xb9\x7b\x2f\x83\x5e\x69\xb8\x5c\x56\xd7\x18\x2f\x3a\xf1\xfe\xbd\xce\x7b\x85\xb0\x1c\x0f\xc2\xab\x50\xc9\x4f\x3d\x06\x22\x95\x5d\xc6\xa1\x77\x69\xe5\x0e\xa6\xd3\x45\xe5\x89\xa4\xd6\x74\x5f\x4f\x1f\x2c\x4e\xf5\xa3\x65\x52\xe7\xc6\x95\x7f\xcc\xa8\xbb\x5b\x0c\x83\x75\xa7\x5d\x03\x0f\x95\x19\x28\x40\xcb\xb8\x96\xec\x25\x9d\x38\x96\xb7\x6b\x48\xac\xea\x7e\x95\x24\x47\x87\xd0\x53\xfd\xc7\xb2\x1f\x69\xe1\xd3\x63\xd6\xdb\xc1\x41\x43\x4d\x7f\x00\x54\x5d\xd3\x68\x28\x5a\xc8\x97\xde\x79\xf9\xd6\xb2\xf4\x49\x96\xf7\xa3\x35\x12\x34\x5e\xce\x51\xd3\xe2\xde\xf2\xba\xc0\x0d\x99\x2b\x62\x7d\x98\xf9\x88\x0f\x80\x2a\x51\xed\xaa\x8b\x83\x2f\x9e\x05\x22\x8e\x21\xf8\x66\x9b\x84\x82\x1b\x68\x20\xc9\xea\x6c\x65\xc9\x49\xbd\x8d\xfb\x01\xe5\x7a\x48\x4d\xb2\xdf\x77\x03\x77\x63\x28\x71\x1e\x34\xbc\x8f\x76\x4c\xa6\xdd\x30\x22\x1a\x0e\xd2\x40\xc0\xb7\x6c\xe0\x4f\x09\x1e\x28\xa7\x84\xe6\xa6\x79\x48\x78\x72\x79\xb4\x5c\xad\xb7\x1c\x4f\x89\x34\xf2\xfd\x12\xa8\xe9\x6b\xb4\xc9\x6d\x51\x82\x8c\xd0\x9f\x1b\x1d\x56\x66\xe7\x1c\x2f\x02\xb4\xaa\xd2\x0d\x01\xc9\xd0\xa4\x13\x77\xd4\xef\xd9\x89\xff\xbe\x25\x99\x8d\xf4\x1b\x70\xfe\xde\xba\xbb\xb4\xfe\xfc\x6b\xe3\xf3\xa7\x7d\xfd\xa1\x3a\x44\x57\x10\xc1\xe8\x7a\xdc\x34\x6f\x2d\x74\x08\xce\xb3\x4d\x5c\x70\xb2\xc8\xaa\x2b\x18\xec\x65\x96\x72\xe4\xb9\xc2\x38\x01\xc6\xba\xce\x2b\xd6\x3c\x6d\x32\x22\x38\xbd\xee\x4d\x70\xbc\xd2\xc6\xe6\xa4\x0a\xdb\x87\xde\xfd\xdd\x5c\x64\xbf\xbf\xb7\x3f\x0f\x93\xe4\x26\x8c\x7e\x2b\x5a\xce\x79\x9c\xf5\x91\xfd\x43\x52\xd6\xdc\x2b\xaa\xa8\x9e\x72\xcb\xb5\xbe\x47\x65\x2c\xed\x98\x1f\x0b\x3f\x0d\x18\x6e\xcc\x54\xec\x81\xd7\x69\xae\xcf\xd8\x53\xe5\x3f\x5a\x1b\x1b\xc8\xad\x18\xcf\x65\xc6\x2e\x8d\x58\x87\x1d\xc8\x58\x86\xfe\xdd\x69\x84\x4e\xfb\x6c\xe8\xcc\xc3\xda\xf0\x97\x8d\x5d\xb5\x1f\x87\x95\x8a\x77\x3e\x1a\x15\xcd\x75\xee\x04\xad\xd7\x63\xbf\xa8\x4f\x4b\x7d\x27\xa0\xa9\xe4\x34\xb9\x5d\x88\x6c\xfb\x5d\xfa\x45\x98\x14\x1c\xcf\xdf\xe2\xe6\x3a\x99\xa1\x4b\xe6\xdc\xde\xf0\x4d\x96\x3f\xe2\x01\xd7\x10\x58\x41\x36\x74\x69\x66\x9a\x56\xcc\xd2\x85\x1f\x78\x78\x5d\x43\xc2\x9e\x5a\x1b\x57\x8d\x2f\xb1\x32\xc9\x10\xad\xba\xc7\x2e\x0d\xab\xbd\xbc\x31\x9c\x1d\x80\x60\xf5\xa4\xa0\x9b\xd2\x4e\x40\xb9\x5b\x2b\x27\x8b\xea\x60\xc1\x34\x13\x7b\x1d\x16\x78\x4b\x4a\x5c\x99\x69\x79\xb9\x69\xe6\xb5\x6c\xac\x31\x36\xbf\x58\x39\x31\x4d\x61\xe5\x78\x22\xdf\x5c\x88\x47\xa8\xea\x5a\x54\xad\x8f\x3d\x95\x51\x1c\x7b\x46\xa2\xfa\x55\x17\x3e\x08\xe7\x5f\x29\x6d\xe6\x56\xca\xee\x6d\x75\x93\x84\x25\xe4\x85\x06\x2f\xc7\xee\x9c\x54\xb7\xe1\x58\x29\x75\x09\x4d\x5f\xb0\xc2\x34\x8b\xf1\x78\x5f\x37\xde\xe5\x22\x6b\xce\xa4\xa9\x8f\xd3\x18\x39\xa7\x58\xf3\x83\xee\x58\x7e\xb6\x80\x8f\xc7\xa5\xaa\x7a\xa5\x27\xec\xc9\x99\xb1\x50\x9e\x0d\xa2\x93\x6a\x2b\x77\xcf\xac\x0e\xe3\x3d\x4d\x32\x9d\xa3\xe8\x56\x94\x96\xa5\x28\x4b\x4b\xd6\x57\x35\x0f\x45\x7a\xab\x1b\x66\x68\xe4\xc8\x7f\x8e\x45\xeb\x02\x93\x66\x6f\xca\x10\xfd\x7c\x4e\xab\x23\x1a\x75\xee\xb9\xa8\xcc\x8e\x89\x97\x06\x0d\x4e\x51\x51\x96\xda\x9c\x42\xdd\x3d\x7d\x4d\xec\xaa\xd1\xee\xad\x4d\x5a\xb9\xde\xfe\xe6\xfb\x9a\x18\x24\xfa\xc5\x38\xaf\xf9\x8a\xe7\x79\xaf\x21\xb1\xef\x1b\x69\x26\xe2\xd5\xa3\x01\x9b\x6c\x76\x9b\xf3\xa2\x30\xa8\x46\x94\x2c\x43\x2e\x34\x83\x1c\xf9\x3a\x09\xa8\x6f\xe4\xbc\xc8\x92\x3b\x6e\x50\x03\xe8\x66\xa7\x02\x20\x10\x83\xfe\x5a\xda\x49\x0e\xad\x2a\x5a\x1a\xb2\x56\x0c\x9c\x4b\x0d\x20\xc2\xff\x6e\xa5\x2e\x55\xf5\x40\xa5\x01\xcd\x99\xb1\xe5\xe9\x12\x99\x88\x8c\x3d\x15\x22\x14\x7d\x93\x90\xef\x69\x98\xdc\x87\x8f\x45\x1f\xfe\xca\xcd\xa1\x99\x17\xb9\x49\x1c\xcc\x13\x12\xfe\x5e\x77\x0d\xdc\x44\x94\x79\x08\xf0\x40\xf1\xb6\xd5\x07\x29\x67\xd5\xf5\x35\x04\xbe\x9a\xc8\xf6\x3d\xb1\xd5\xa5\x63\xad\xcb\xc3\xea\xad\xff\xd6\xe2\x7e\xee\xcf\x02\x24\xab\xf2\x69\x1e\xfb\x20\xd1\x07\x2d\x01\x4f\x36\x9a\x61\xe4\xc3\xbe\x2b\xc3\xe6\xb8\x03\x6a\x7b\x65\xfd\x88\x32\x83\x44\x1d\x94\xac\x00\x9d\xd4\x06\x0a\x42\x35\x4e\x68\xb5\x91\xda\x72\x2e\x88\x97\xfa\xb9\xef\x04\x23\x03\xf0\xdc\x08\x64\x63\x19\xde\x7f\xa3\x5d\xb3\x2d\xcf\x8b\x38\xab\x6e\x2f\xaf\x1b\xdc\x53\x80\xa0\xbe\x28\x35\x87\x3f\xa7\xe1\x11\xc2\x26\x94\x77\xd7\x21\x44\xe6\x2e\xe4\xfd\x59\xda\xfd\x5d\x34\xe9\xde\xff\x95\xd2\x04\xa5\x4e\x8b\xbf\x88\x09\xa9\xad\x7e\x24\x94\x0a\x1a\x11\xa9\x78\xae\x3b\xa7\x5d\x80\x09\x62\x84\x8a\x3a\xf0\x6e\x2d\xad\xfd\x07\x05\x4f\x56\x63\x04\xcb\x0e\x0f\x82\xc9\x3c\x61\xa9\x69\x5a\x87\x97\x7e\xa5\xfd\xb7\x0f\xa6\x18\x99\x0e\x00\x40\x6f\xad\x84\x2c\xb2\x45\x52\xdd\x17\x14\x5a\x31\x15\xf4\xef\x34\x23\xea\xf1\x57\xe0\xd0\x3c\x2b\x1e\x8d\xe8\xc7\x33\xd5\x5f\x85\x9a\x41\x98\x18\x02\x65\xf3\x21\x63\x7f\xc7\x7d\x52\x31\x2e\x11\xf3\xd3\x80\x50\x2b\x2b\x4b\x51\xcd\x2f\xe6\x96\xc0\xd8\xef\xe9\x8e\x65\x8b\x44\xc7\x68\xe0\xb6\x12\xab\xe2\x85\x10\x67\x2b\x5c\xb6\xf9\x43\xc4\xd1\x29\xe1\xab\x2c\xfb\x0d\x64\xed\xfe\x14\x2b\xa5\x3b\xbb\x00\x1e\xf1\x5d\x1e\x46\x9c\x50\x3e\x72\x5f\x32\xd8\x4b\xa0\x83\xbf\xf6\x74\x50\x28\x64\x43\x52\xaa\xba\x36\xe7\x8b\x9d\x45\x3c\x4b\x6b\xe5\x96\x0b\x64\x3d\x65\xf3\x96\xde\x08\x3b\x92\xcd\xc2\x73\xbf\x82\x8b\x77\xf1\x86\x67\x3b\x61\xed\xa0\xee\x4f\x2c\x53\xe1\x3b\x81\x3f\x0d\x50\xae\x0d\x2d\x87\xc2\xec\x65\x64\x91\x79\x7f\xa7\x69\x0b\xe6\x54\xf8\xee\x41\x4e\x58\x70\xde\xdf\x31\x71\x72\x90\x98\x93\x45\xee\xfd\x8a\xab\x45\x5f\x23\xea\xf1\xd8\x4d\x57\x43\x06\x3b\xb8\xda\x24\x38\xcd\xa4\xf3\x58\x7c\xc8\x52\x8a\x2e\x17\x09\xab\x22\x64\xa9\x3f\x01\xd6\x30\xf5\x4f\x83\x79\xe6\x03\xe7\x16\xb0\x10\xfa\x45\x0b\xd3\xc4\x87\xb6\x6b\x00\x2b\xf6\xd0\xfd\xe9\x98\x07\xfe\x24\xa8\x42\x80\x55\x5f\xa6\xfa\x17\x07\x73\xc0\xce\x4c\x2b\xb0\xc1\x0b\xa1\xb2\xda\x14\x3e\xc0\x36\x48\x68\xec\x03\xdf\x18\xb0\x1e\x32\x8d\x29\x2d\x0a\x03\x0c\xa7\xd2\xfc\x79\xfd\x7b\x6b\xbb\x10\x0b\xeb\xbd\x18\x7d\x07\x6a\xe0\xc6\x84\x4a\x4f\x70\x58\x51\x31\x8d\x09\x8d\xf7\xf4\x7e\xcd\xfb\x9c\x40\x0e\x6e\x06\x4c\x99\xa0\x39\xab\x6e\xc6\xa3\x19\x53\x37\x5a\x6a\x9d\x89\x35\xcc\xb3\x08\x0d\xfb\x6e\x75\xd5\x71\x2b\x07\xc1\x4f\xd2\x50\x78\x3a\xb8\xbb\xdc\x5d\x1c\xb4\xe1\xa5\x74\x3c\x16\xc0\xa7\x6a\x4b\x18\x25\xba\x3d\x5e\x61\x2e\x5e\x30\x10\xe6\x40\x70\xaa\x36\x3c\x60\x8b\xab\xdc\x34\x56\xab\x8b\x0e\x05\xa1\xf5\x9e\x0a\x10\xb6\x71\x53\xb5\x48\x59\xde\x5a\x99\x9f\x06\xa6\x09\x7f\xa5\xe0\x54\x9f\x2d\xc7\x72\x0f\x54\xa1\x4c\xd0\x96\xeb\x07\xcc\x4d\xa1\x99\xba\x76\xed\x4e\xee\x06\xb1\xd5\xc9\xc0\xd7\xec\xe4\xbd\xf5\xe6\x2e\x4c\xca\xaf\x53\xc1\xf3\x34\x4c\xca\x1f\xc2\xf4\x96\x97\x3f\x00\xe4\x78\x1a\xf1\x52\x86\x7a\x29\xd1\x18\xfe\x6f\x3f\x7c\x4d\x90\x16\x3f\x3b\x99\x1f\x23\x32\x9d\x13\x4f\x8c\x23\x56\x64\x09\x07\x82\xab\x1e\xed\xfb\x30\x4f\x4d\x93\x9b\xe6\xd7\xb5\x2b\x50\xb8\xe1\xa4\x9b\xa5\xba\xf6\xb8\x6e\x69\x50\xb7\x84\xae\x7b\xf6\x86\x17\x45\x78\xcb\x29\x97\x04\x07\x63\xfe\xdc\x4b\x25\xf4\x9b\x2a\x67\x6b\xde\x5b\x14\x47\x5f\x59\x95\xb4\x4b\x88\xbc\xd2\xfe\xab\x16\xf6\x34\xbb\xe1\x17\x16\x79\x0a\x55\x40\xf8\x4e\x30\xe4\xd7\xdf\x5d\x29\xb7\xc5\xb7\x59\xb8\xe4\x4b\x83\x7e\x01\x24\xae\x37\xaf\x8c\x83\xfc\x05\xa9\x7a\x6b\xc9\x2b\x61\xe5\x4b\x1f\xa6\x7e\x25\xe7\x9a\x13\x5b\xd2\xff\xd6\x99\x5e\x77\xc8\x16\x27\x8d\xe4\xd1\xf0\xb0\xf5\x0d\x8d\x2e\xc5\xfc\x3f\x87\xb1\xf0\xd4\x73\x6b\xd1\x59\xd2\x7e\x60\x31\x1e\xab\x9a\x31\xe7\xbd\xad\x2a\x20\x65\x69\xd5\x2f\x6c\xe8\xd0\xa1\x33\x44\x17\xf6\x56\xfe\x97\x4e\x59\x7e\xd5\x5a\x18\x21\xf5\xef\x83\x4a\xbd\x88\xf9\x70\x50\x4c\x8e\x8d\x1a\x51\xb6\xd9\x26\x5c\xa0\xa9\x48\x28\x33\xfc\x08\xcb\xa0\x2c\x11\x5e\x4a\xe4\xd3\x53\x4c\x73\x78\x10\x02\xdb\x5e\x66\x3f\x46\x79\x96\x24\x8b\xd6\x64\xab\x16\x89\x67\x85\x3d\x81\xac\x8f\xcc\xdd\x61\xc6\x6a\xe2\xe4\xf2\xf9\x5b\xe7\x7a\xe2\xe6\xe2\x36\x49\xb9\x22\xe6\xd0\xa4\x3e\x1f\xa0\x3b\x65\xba\x88\xc6\x1a\x1a\xaf\x02\x52\x2c\x4a\xfa\xd1\x20\x4e\x07\x31\x80\x34\x27\xca\x9b\x83\xe6\x7e\x14\xd0\xa1\x23\x2d\xfd\x2a\x9f\xf8\xfa\xe8\x45\x8a\xeb\x43\x07\x37\xc2\xb2\xb4\x0a\xbc\xb1\x6d\x07\x5b\xf9\xc2\x4a\xab\x83\xeb\x8c\x50\x79\x8f\x3c\xf1\xac\x1d\x4b\x69\x7a\x70\xba\x57\xd9\xf1\x69\x3a\xf1\x54\xda\xe6\xa8\x03\x82\xe8\x45\x82\x06\xde\xa9\x25\xa0\x43\x39\x2d\x16\x99\xa7\x54\x38\xf8\x25\xa2\x55\x92\xe6\x84\x11\x2f\x84\xb7\x5b\x54\xfd\x20\x5e\xb2\x80\x4c\x0e\x64\xf2\xc2\x3d\xfd\x89\x9d\xbc\x1f\x6f\x8a\xf1\x09\xfd\x2f\x76\x32\x96\xf6\x05\x44\x57\x50\x7d\xd9\x56\x94\xdb\x22\xfb\xdb\x76\x5b\x5b\x26\xd4\xd9\xfe\xd2\xb2\x13\xaa\xec\xd0\x7e\xa2\xc6\xa6\x18\x6b\xe1\x78\xfe\x8b\x7e\x29\xcd\x19\x9e\xf5\x2d\xb1\xf6\x91\xb8\x8c\xd7\xa4\xbf\x0f\x47\xda\x81\x79\xd3\xc5\xbf\x22\xf5\x88\x0b\x5b\xdd\x9d\x2a\xed\x32\xe0\x69\xf4\x57\x7b\x17\x2f\x47\xa3\x3d\xfe\x32\x97\xfe\x55\xbf\xf0\x19\x63\x27\xf5\x29\xd6\x7d\xbd\xb6\x4e\x78\x96\xa7\x3d\x7d\x26\x6f\x9e\xd6\x23\x40\xb6\x4b\x30\xe1\x29\x95\xbe\x54\xa9\x36\xae\xf5\x54\xcf\x47\x95\x09\xb3\xa0\x51\x96\xae\xe2\xdb\x1d\x5e\xc4\xef\xc9\x53\x75\x2a\xf6\xb4\xe0\xe2\xd8\x9d\x91\xf2\xb8\x09\x47\x50\x05\x3a\x3e\xd0\xb4\x09\x92\xf9\x7f\xb1\x04\x09\x58\xda\xb9\x68\x54\xa6\xe4\xa4\x7d\x2b\x66\xd6\xbd\xb5\x5a\x9b\x78\x89\xee\x18\x07\xa5\xd5\xb2\xd7\x19\x3a\x88\x67\xad\x0f\xb2\x07\x7b\x1a\x46\x11\x2f\x8a\x63\xfa\xf1\xa6\xfa\xb2\x14\x7d\x3a\x5b\x61\x9a\x75\x9e\x74\x51\x9f\xc5\x40\x17\x3d\x79\x34\x53\xc8\x57\x9a\x12\xda\x1c\x8b\x2e\x52\x4f\x90\x43\xc5\x53\xeb\xf0\xae\x3b\xdd\xfa\xe2\xce\x51\x52\xaa\x5f\x61\x37\x65\x96\xe8\xdc\x1c\x2c\xc8\x42\xa0\x6a\xfa\x2f\xd0\x17\x06\x03\x26\x71\x3a\xc8\x17\xbe\x08\x3c\xd1\xd2\x64\x12\xdd\x34\x5a\x32\x0c\xea\x4a\x96\xdc\x17\x7e\x1a\x04\x7b\x4b\x07\x05\xd0\x78\xed\x9e\x5b\x79\x8d\xfc\xc7\x10\x4f\xb1\x85\xaa\xce\x4e\x2a\x08\x35\xeb\xb0\x78\x1d\x8a\xf0\x8f\x63\x7d\x33\x76\xd3\x1c\x76\xfb\x23\x80\xcd\x82\xe2\xdf\xa0\xdf\xc3\x5f\xe9\x3f\xd4\x2f\xe7\xca\xdc\xe1\x49\xda\x3a\x3c\xbf\xde\x97\xd7\x7e\xf5\x1c\x90\x67\x78\xe5\xda\x89\xff\x6a\xfc\x8f\x40\xa7\x36\x29\x3f\x30\xa9\x6b\xa6\xbd\x7b\x03\x0b\xc1\x0b\xaa\x8c\x65\x28\xc2\xb1\x31\x12\xba\xf5\xab\x31\x7e\x66\x1a\xdd\x20\x02\x07\x58\x85\x97\xf5\x76\xef\xe9\x97\x72\x5e\xda\x43\x9f\x0c\x91\xef\x70\x6b\xc4\x0b\xf5\xc3\xa4\xe0\x86\xdc\x75\x2d\x03\x28\xbb\x8c\x1f\x85\x51\xb2\x38\x63\x6c\xc4\x47\x86\xb1\x18\x71\xaf\x31\x7c\x5d\x7c\xf3\xe3\x77\xdf\x4a\x2b\x06\x5c\x3a\x64\x6f\xa5\x95\x38\x99\x91\xa7\xfd\x3f\x34\x24\x96\x4e\x52\x29\x6b\xc7\x2c\x4c\xf7\xf7\xfa\xb1\xf8\xc1\x54\xaa\x6c\xff\xb0\x55\xa2\xc5\x49\x59\x7e\xa3\xbd\xed\xe9\xb2\x5d\xa6\xb5\x0c\xff\x61\xcb\x65\x5a\xf5\x41\x2d\x9c\xd7\xdd\x22\xe4\xe9\x1f\x8a\xab\x52\x61\x1e\x7f\xf9\x58\xad\xdf\x74\x6b\xfd\xe5\x68\xb5\xdf\xb4\xaa\x45\x36\x45\x33\x04\x38\x68\xa4\x13\x85\x5f\x9e\x09\xd3\x10\x04\xea\x58\xb3\x68\x6d\xa1\x91\xb4\x87\xd1\x8e\x7b\xf0\x34\xe8\x1f\x48\x4e\x62\x69\x04\x16\x6b\xa7\xe6\xc3\x6f\x64\x0a\x35\x14\x10\x01\x59\x0a\x83\xa8\x0b\xad\xd2\xda\xdb\x50\xae\xe6\x10\x45\x05\x68\xc7\xca\x19\xbc\x48\xbe\xba\x89\x7e\x26\xb1\x55\x1e\x50\xfd\xc5\xca\x95\x8a\xf5\x14\xf6\x79\x2e\x5d\x2b\xf1\xb2\xe7\xf9\x37\x88\x0b\xdd\x66\xf5\xe0\x9d\x99\x7a\x38\x54\xb9\xa8\xa3\x66\x14\x7b\x75\x16\x5b\xe2\x57\x75\xaf\x3f\x21\xde\xdf\x0e\xee\xeb\xaf\xc2\x6b\xc4\x2b\x2b\xd6\x48\x6e\x1d\x09\xb1\x26\x07\x56\x5a\xc1\x8c\xa2\x55\x90\x9e\x80\x23\xe1\x84\x2c\xd2\x2a\xe4\xe6\xa7\xfb\x03\xf3\x0d\xb2\xbf\x8a\xcd\x4a\x0f\xa5\x3f\x99\x32\x74\x8e\xa1\x65\xe7\x66\xff\xc3\xc6\x14\x6a\x35\xe3\x57\xc7\xec\x0a\xbb\x7e\xdf\xf1\x1d\xef\xdf\x6f\x01\x1c\x8d\xc5\x15\x43\x6f\xd0\xd5\x83\x41\x46\x06\x16\x32\x68\xce\xbe\xa9\xf7\x23\x9a\x9a\x26\x46\x77\x3e\xb8\x3e\x1e\x72\x69\x4b\x41\x37\xce\x49\x09\xf1\xf2\xe6\xd8\x06\x6f\xdd\xdb\xd3\x25\x3f\xec\x54\xe5\xf5\x73\x6f\x63\x1a\x7c\x62\x55\x7f\x68\x5e\x5f\x74\x85\x77\x5e\xd5\x2e\x53\xec\xde\xfe\x05\xb3\x83\x7c\x58\xc8\xf0\xb2\x46\x9c\xd6\xca\x72\xa6\x2e\x9d\xd1\xca\xe4\xe3\x31\x3a\xe3\x5a\x50\x33\x53\x56\xb0\x55\xe8\x5e\xbd\x2c\xa1\x6a\xbb\x89\xf1\xbc\x8b\xd6\xa7\x8a\x3a\xf4\xef\x6d\x35\x16\xb9\xb2\x09\x3a\xf5\x0e\x73\xd3\xc4\xa5\x8a\x87\x2c\xa8\xa5\xb0\x80\x3c\x34\x3d\xed\xbf\xa1\x5c\x81\x1d\x73\x18\xf3\x9a\xca\xc8\x09\x48\x91\xe2\xd5\x60\x4e\xe9\x93\x3c\xc2\x39\xae\x5d\x3f\x50\xf2\x68\x54\xc8\x17\xf5\x1c\xa7\x81\xc4\xd0\x03\xb2\x74\x7c\x8e\x26\xd5\x19\x75\x9f\x21\x90\x25\x18\xa7\x9c\x01\x78\x69\x0a\xc0\xee\xa2\xfc\x8b\x74\x51\x4d\x72\x45\xda\xea\x4b\x31\x6a\x4e\xcc\xeb\xc7\xf6\x36\x8e\xd4\x4b\x6c\xde\xc6\x03\xb5\x14\xa8\x9a\x62\x2e\xed\xea\xab\x89\x05\x06\x0a\x8d\x6d\x9a\xc9\xd3\xd6\x4e\x0f\x72\x7e\x62\x05\xf6\x57\x13\x25\x3c\xcc\xff\xfa\xd1\x9a\x14\xe2\x48\x24\xa7\x7e\xd0\xab\x15\xd4\x59\x3a\x97\x66\x6d\xdd\x93\xdc\x1c\x68\xd8\xb2\xd2\x2a\x74\x7d\xdb\x78\x9c\x97\x65\xd6\x92\x96\x63\xea\xc7\x01\xd9\x23\xaf\xf6\xb1\x19\x94\x33\x82\x0e\x41\xb2\x8b\x32\x02\x96\x95\x2a\xa2\x10\xfb\x61\x40\x79\x0b\x69\xe5\xbd\x2c\x88\x98\xb0\x13\x8c\x46\x54\xbd\x21\x2e\x16\x8d\xf8\x56\x58\xba\xc6\x4e\xd4\x6a\xa3\x1c\xaf\xae\x1d\x07\x0b\x60\xb2\x96\xcf\xaf\xed\x92\x5c\x2f\x47\xd6\xc2\xf3\xf9\x9b\x00\x13\xae\x97\xa3\x92\x9c\xa8\x4b\xe8\x68\xd6\xbe\xe0\xf6\x7d\x75\x8f\x30\x61\x25\xb1\x8c\x51\xce\x47\x06\x41\xe9\xef\x7f\x05\xcf\xeb\xeb\x81\x63\xce\x7c\xe3\x5d\xb6\x35\xa8\xf1\x43\x7c\xbb\x16\x06\x35\xfe\x9c\x09\x91\x6d\x0c\x6a\xbc\xe5\x2b\x61\x04\x34\xe4\xec\x40\xfe\xa7\x45\x5f\xb4\xe3\x81\x66\x65\xd7\x09\xff\x2c\x0d\x59\x40\x22\xcb\x36\xdb\xac\xe0\x4b\x34\x1e\x0c\x91\x37\xfb\x21\xcb\x54\xbc\x1e\xeb\xdf\xa8\xb6\x2c\x5b\x95\x58\x11\xc6\x75\xef\xe4\x53\x20\x3d\x70\xec\x54\x6b\x37\xcd\x52\xe4\xfa\x2c\xce\xe4\x45\x64\x85\x78\x4c\xf0\xfe\x38\xbc\xe0\xbc\x54\x9e\x2d\xad\xaf\xa6\x89\x2c\x9e\x69\xd6\xa5\xef\xed\x08\xe9\x91\xa1\x72\x18\x64\x4f\x77\xdd\xbb\x83\xeb\x03\x2f\x1a\xd3\x90\x3d\x49\xd4\x8b\xa5\xc4\x16\xfa\x71\x50\x35\xe3\xc7\x01\x6d\x1e\x99\xa8\xae\x0c\xc2\xac\x40\xc4\xab\xfb\x65\x71\x1f\x21\x54\x10\x2d\x37\x54\xd4\x88\x7c\x0d\xef\xbd\xe5\x7d\x9d\x98\x38\xb4\x60\xf9\x61\x58\xd4\x41\x6e\x47\xbb\xdc\xd2\x63\xd7\xeb\x53\xa2\xb6\x38\x34\x60\x88\x18\x60\x31\x9e\x0f\xa5\x18\xd2\xd6\xc2\x0c\xf2\xee\x7f\x5f\x04\x0b\xc3\xf0\x8c\x2d\x6c\x5f\xbb\x96\xef\x45\x27\x5b\x59\x42\xa6\x21\x63\x89\x69\x8e\x22\x62\x9a\x19\x97\x56\xc9\x75\x73\xd2\xc9\x77\x67\x9a\x3b\x7f\x1a\xa0\x2f\x3d\xf2\x68\xd1\x09\x9b\xd0\x84\x25\x65\x09\xdf\xe9\x8e\x8d\xa2\xb2\x74\xe5\x22\xbd\x97\x70\xc1\xce\xee\x46\x09\xa1\x96\x3b\x8e\xc9\x73\xcb\x1d\x5b\x31\x74\xfb\x24\x2a\x4b\xfb\x94\x90\x17\xcc\x31\x4d\x2b\x64\x0e\xa1\xbb\x13\x16\xcf\xf5\x72\xd6\xee\x39\x9b\x10\x28\xac\x0e\xd0\xf7\x9a\x97\xc1\x8e\x8d\x76\x65\x09\x2d\x3a\xb0\x25\xfb\x6e\xb0\xd8\x8d\x2c\xf8\x1d\xb9\xe4\x79\xea\x4f\x02\x6f\x84\x67\x10\x39\x10\x02\x7b\x97\xc6\x82\x25\x34\xb7\x0b\x11\xe6\x82\xed\x68\x6e\xf3\x74\xc9\xd0\x63\x1d\x15\x27\x2b\x8e\x78\x51\x4d\xda\x92\xeb\x81\x7c\xbb\x0b\x20\xd7\xbc\xa3\x68\xc6\x56\x5c\x97\xf6\x65\xb4\x59\xfb\x26\x5b\x3e\xb6\x2e\x36\x49\x3b\x9e\x6f\x18\x94\x43\xe1\xaf\xd0\xf0\x97\x7e\xec\x86\xce\x1a\xef\x25\x5b\x61\xdc\x24\x59\xf4\x9b\x41\x28\x76\x81\x65\xad\xdb\x4d\xd7\xdd\xcb\x3b\x81\x0b\x96\x26\x13\x0e\x0d\x9b\xe8\x27\xf1\x8b\x70\x1e\x8f\x46\xc4\xca\x31\x9c\xb8\x5a\x88\xe8\x9a\x9e\xb7\x97\x1f\x15\x0b\xab\xee\x01\xcc\x42\x06\x88\x2f\xa9\x71\xae\x0d\xa1\x2c\x65\xf8\x04\x3f\x06\xac\xec\x54\xc2\xf0\xfe\x39\x5c\xdd\x79\x77\x75\x27\x1c\xcd\x5e\x64\xbd\x4b\x29\x37\x7a\xb2\xc5\xa1\xd6\xa2\xfc\x42\x25\x2f\xaf\x35\x4c\xd3\xca\x6f\x02\x03\xae\xab\x71\xc9\xe3\xac\x4c\x46\x4a\x87\x11\x76\xfa\x03\x29\xc7\x6c\xa4\x8b\x75\x76\xdf\xb3\x12\xd7\x6a\xaf\x45\xae\x79\x1d\x2f\xfb\xac\x04\x54\x1e\xb2\xa7\x22\xbb\xbd\x4d\xfa\xb6\x61\xe3\x26\xcb\x12\x1e\xb6\xfc\x7d\x17\x4a\xca\x80\x96\x2d\x65\x1f\x0f\x2d\x54\xcf\x07\xdb\x7f\xa2\xda\x59\xdc\xcb\xdf\xaa\x64\xf5\x2a\x0b\x4b\xb6\x1c\x09\xf2\x8d\x52\x22\x54\xf1\x9e\x4a\x8c\x00\x85\x97\xc0\x6f\x38\x3b\x69\x7b\x43\x75\x9c\xa1\x4e\x62\x7a\x05\xc5\x9f\x95\xef\x37\xd9\x72\x97\xf0\x67\xe5\xf5\x89\xb5\xf0\x7e\x0d\xef\xc2\x92\x47\x9b\x90\x14\x51\x1e\x6f\xc5\x49\x4c\x6f\x39\x7b\x92\x01\xe5\x3c\xdf\xa5\x46\x75\x1d\xd2\x66\x97\x88\x78\x9b\x70\xf6\x59\xf5\xf4\xd9\x4b\x83\x1a\xcd\x45\x48\x01\x15\x6b\x1e\x2e\x65\x21\x74\x59\x95\xe9\xea\x31\xa0\x51\x96\x78\xfe\xa4\x4e\x7c\x11\x65\xc9\x6d\x9e\xed\xb6\x32\x5b\xfd\xa6\x95\x10\x79\xab\x80\x80\xb5\xa9\x2a\xc5\x47\x3d\xeb\xd2\xf3\xa7\xdd\xac\x2f\x44\xae\xb2\xe7\x2f\x7b\xca\xfc\xa2\x3c\x21\x3d\xdf\xa1\x86\x41\x0d\x23\xd0\x28\xc9\xa3\x7e\xeb\x6d\xad\x6f\xf8\xc8\x2d\x7c\x87\xb7\xbc\x1d\xb9\xaa\x51\xc6\xce\x21\xde\x91\xaa\xba\x97\x1d\x2d\x7a\xee\x3f\xaa\xaa\xf0\x03\xda\x51\x15\x4a\x07\xbb\x45\x6d\x62\xca\x03\x8a\x1e\x44\xf5\xb8\xee\x0e\xae\x06\x76\x90\x2e\x56\x52\xfb\x8b\x7c\x9e\x8e\x46\x44\xae\x51\xee\xa7\x01\x35\x6e\x93\xec\x26\x4c\xde\xdc\x85\x89\x81\xae\xcb\x92\x70\x88\x6e\x1a\x21\xfb\x5b\x6e\x67\x5b\x81\xf3\xc8\xe4\x73\x9c\xa5\xf4\x96\xdb\x08\x7b\xf8\x24\x56\x59\x26\xe0\xa1\x9a\x6f\x7c\x0e\xe5\xc1\xd8\x2d\x5a\x62\x86\x4b\x2c\xb1\xc6\xd7\x25\xa2\xfe\x2b\xc0\xef\xd2\xfc\xd3\xe2\xfa\x7e\x34\x3f\x69\x26\xe9\x68\x28\xa7\x2a\x90\x08\xdd\x32\xa1\xe8\x77\xb5\x0b\x7c\x91\x87\xb7\x48\xc8\x49\x15\x25\xc9\xa1\xeb\x06\x00\xcb\x17\xeb\xf9\x52\xfa\x41\x60\xa8\xa7\x65\x40\x64\xe8\xcb\x98\x74\xcf\x48\x62\x42\x2a\x38\xaf\x68\xac\x85\x42\x8a\x03\x2f\x6e\x8e\x46\x5e\x29\x85\x57\xac\x74\x24\x21\xc3\x28\x0e\xad\x6b\xbf\xba\xde\xd5\xcb\xf8\x0e\xa8\x6d\xc1\xac\x8d\xda\xd5\x63\x52\x96\xbe\xc4\x52\x72\x18\x70\x3f\x62\xb7\xdc\x2f\x82\xb2\xbc\xe5\x76\x85\xd6\x34\xd4\x1c\x94\x23\xd8\x61\xef\xed\xb5\xd8\x24\xdf\xe7\x5c\x99\xfa\xc6\x64\x14\xc1\x5e\xbb\xc3\x48\x02\x32\x7c\x51\xc8\xc2\x26\x8e\xf3\xbc\x19\x5f\xd8\xba\xfc\xdf\x0a\xd9\x56\xb7\xa5\xd6\x63\xa4\x32\xc3\x50\x81\xcc\xa4\x00\x5f\x0d\xee\x1d\x7f\x90\x5c\x67\x75\xd9\xc5\xb6\x53\x0a\xa6\x62\x1e\xb3\x95\xbf\xac\xa2\x57\xe4\xe8\x9f\xa4\xcc\x11\x63\x9a\x93\x97\x63\x97\xa0\x39\x93\x0a\xb5\x55\x03\x39\x61\xf2\x04\x3f\x64\x8f\xdc\x6a\x03\x37\x26\xd4\x90\xd4\xcd\xc0\xd0\x5c\x77\xdc\x0a\x09\x95\x17\x4e\xef\xb0\xc5\xd0\xdf\x61\x8b\x57\xd5\x4c\x55\xb1\x1a\x0d\x52\xfb\xba\xc6\xf5\x56\xb3\xdd\x0f\x0f\xed\xba\x8e\x22\x59\xab\x2b\xe1\x91\x79\x16\xec\x20\xe5\x13\xf7\xc7\x21\xed\x47\xa6\xa3\x9d\x5c\xdd\xa2\x47\x8d\xe6\x3e\xbd\x6e\x1e\x75\xa7\x9c\xe8\xb9\x7d\x8e\x5e\xc9\xb0\xa2\x9f\x27\x59\x8a\x66\xeb\xf0\x8b\x93\x36\x74\x48\xe7\xad\xc6\x92\x2a\x12\x29\x6d\x7b\xc4\xc3\xe4\x86\x39\x0f\x5f\x3e\xbc\x38\xa9\x9f\x0d\x7a\x65\xa7\x19\x56\xff\xb9\x2c\xc5\x30\x96\xe9\x91\x9a\x5b\xbe\xea\x96\xdc\x07\xef\x61\x23\xfb\x8d\x3f\x9e\xd0\x0f\x6a\x47\xdc\x64\xbb\x82\x97\xdb\x2c\x4e\x05\xcf\xcb\x48\x3a\x1d\x6f\x78\xba\x2b\x97\x79\x78\x5b\x2e\xf3\x6c\x4b\xca\x28\x89\xa3\xdf\x4e\xe8\x77\x58\xc6\x7f\x6f\x07\xcf\x09\x08\x8b\xb6\x65\x8f\x48\x49\x34\xa2\xf2\x8e\xeb\x97\x1d\xd4\x9f\x1f\xb4\xcf\xda\xbd\xe3\xdf\xf2\xb6\x4b\x33\x63\xac\x63\x23\xa5\x52\xc2\x76\x98\xd9\xc6\x84\x7c\xbf\x47\x2f\x67\xcb\xc0\x28\xb5\xc8\x53\x68\xdc\xe0\xdb\x4e\xa8\x38\x34\xd3\xa1\x45\xe7\xc0\xb6\x3e\xe2\x42\x0a\x53\x0c\xe2\x1e\x1d\x4b\x8a\x4a\xd6\xbc\x2c\x53\x9a\xd6\x42\xba\x20\xd8\x40\x81\x0d\x08\xbf\x08\x68\xac\xf1\x54\xf1\x4a\x79\xeb\xe4\x32\x3e\x0d\x63\xd9\xc2\xca\x58\x4a\x73\x56\x57\xe1\xa9\x04\xd3\xec\x39\x73\x4b\x21\x7b\x4e\xf3\x3a\xb3\x7a\xd5\xba\xa0\x42\x9e\x67\x24\x63\x0f\xbc\x5e\xcf\xc3\xac\x0e\x58\xa0\x07\xec\x8f\x51\xea\xc8\xa8\x95\xf5\xca\xbe\x16\xb1\xb3\x15\x5e\xb8\x14\xf6\x1b\x3c\xee\x89\x7d\xbb\x8b\x97\x2c\xc4\x1f\x0c\xda\x87\xef\xf7\xf8\x33\x1a\xe1\x65\x1a\x3d\x9a\x1a\x7e\xc7\x53\x81\xca\x08\xe5\x6f\x91\xd1\x5c\x9e\x47\x37\x33\xf5\xa6\x3e\xac\x49\x17\xd6\x37\xf5\xd9\xc5\xd0\x45\xad\x6a\x5d\x01\x7c\x7b\xaa\x2f\xf8\xf6\x86\x2e\x5d\xe3\x4d\x34\xf9\xc1\x21\x94\x54\xe3\xab\xdd\x16\x9b\x45\x81\xce\x35\xb9\x1d\x17\xef\xf2\xf8\xf6\x96\xe7\xca\xf5\x4b\x48\xc7\xd1\xca\x52\x9b\x58\x55\x8b\x18\x41\x21\x4c\x50\x5e\x7c\xda\x13\x7b\xc9\x13\x7e\x0b\xc4\xb8\xba\xa2\x5f\x64\xdb\xef\xf3\x6c\x1b\xde\x86\x72\xb0\xf5\x0c\xc4\x3d\x26\x4c\xdf\x34\x1a\x6a\x41\x63\xd4\xaf\x56\x3d\xa3\xaa\x1f\x16\xa1\xf1\x90\x31\x2b\x6b\x77\x9c\x94\x65\xbe\x68\x15\xc7\xfb\xb9\xf1\x2e\xf4\x21\xcc\x7e\x7d\x58\x0e\x3d\xfa\x7a\xb3\xe1\xcb\x38\x14\xbc\xd5\x35\xca\xd1\x3d\x8c\xa7\xe2\xb5\x24\x0b\xa8\x0c\xba\x6b\xee\x0b\x8a\x9b\x23\x8c\x56\x53\xea\x60\xb9\x82\x89\x90\xa0\xb3\x6a\x5d\x77\xec\x3b\x01\xbd\xb7\xd1\xb2\xa2\x39\x11\x27\x34\xae\x03\x4d\x57\xbe\xa2\xf4\x63\xfd\x43\x2f\x97\x46\x21\xd9\xa8\xc0\x61\x17\x6b\x23\xc0\x3b\x4e\xf6\xea\x1b\x7b\x92\x3c\x94\xf7\x74\xe8\x91\xd7\xba\xf4\x42\xe7\x6a\xaa\x4b\x27\xe8\xa6\x6a\x86\xc8\xeb\x21\xf0\x10\xc6\x56\x18\x85\xb2\xa0\x15\xb3\x94\x54\x5f\x68\xc6\xe2\x3a\x42\x06\xea\xb3\x8f\xb8\x41\x86\x1c\x6d\x34\xaa\x65\x92\x76\x96\x09\xb5\x22\xb6\x91\xfd\x2f\x48\x59\x6a\x6f\x18\x67\xd4\x0a\xd9\x46\x35\x89\x91\x31\xeb\x37\xa6\x1f\xad\x34\x06\x89\xfa\xb4\xf0\x25\x3a\xec\x09\x19\x65\x40\x26\x81\xc8\x87\x51\x25\x2a\x45\x8e\x66\xf2\xa6\x6e\x45\x26\x34\x61\x96\x3a\x8b\x30\x88\x7e\xca\x0c\x1c\x53\xc5\xdd\x25\x78\xc4\xcc\x6e\x98\x55\xb0\xef\x14\x67\x25\xfc\x24\x50\x41\x8e\xdc\x80\xae\x99\x55\xf8\xff\x2f\x75\xef\xc2\xe5\xb6\x8d\xac\x8b\xfe\x95\x16\xae\x87\x07\xb0\xd0\x6a\xb5\x93\xc9\xd9\x43\x19\xe1\x72\xec\x38\xc9\xc4\x1d\x7b\x62\x67\x92\x0c\x5b\xd3\x8b\x2d\x41\xdd\x8c\x29\x52\x21\xa1\x7e\x58\xd4\x7f\xbf\x0b\x55\x78\x91\x62\x3b\xce\x9c\xbd\xcf\xba\x77\x67\xb6\x5b\x04\x41\x10\xc4\xa3\x50\x28\x54\x7d\xdf\x13\x43\x9b\x64\x10\x77\x26\x16\x72\x87\xf1\x65\x14\xd1\x8d\xe8\xcf\xae\x25\xcc\x2e\xbe\x14\xb4\x4a\x36\x9d\x39\x16\x6f\x26\x97\x79\xb9\x34\xd4\x0b\x4b\xfe\xe0\xb3\x5b\xe1\x8f\x5e\x00\xc2\x6d\xc9\xab\x3a\xbf\x82\x32\x2e\xf1\x94\xb2\x76\x92\xa2\xe4\xba\x1f\x62\xec\x15\x6e\xfb\x33\xae\x78\x88\xba\x11\x43\xef\x3e\x00\xc9\x81\x8a\x8e\xee\x62\x27\x89\xae\x0d\x9c\xd0\x84\xb0\xbd\x9e\xdc\x74\x25\x16\xa8\xfe\x52\xf3\x53\xa4\x73\x2f\x41\x9e\x57\xdb\x52\x89\x29\xdf\xe8\x99\xb6\xdd\x44\xd1\xe8\x74\x24\x84\xb9\xf2\xd8\x18\xd7\x3c\x03\xb3\x63\xdf\x73\x49\x0b\x9f\x03\x6f\xa6\x25\xcf\x18\xe3\x1b\x7d\x43\xb7\xb3\xfe\x6b\x4b\xda\x32\xbe\xb5\xa3\xd8\x8e\xca\x6e\x82\xc0\xe6\x60\x8c\x57\xc9\xca\x86\xbf\xac\xba\xf5\x1d\x8f\xf9\x94\x6f\x59\x6c\x54\xd3\xad\x17\xcd\x38\x09\xf5\x47\x06\x47\x6a\xff\xc1\x64\xf4\x67\xcb\x51\xd4\x99\x9a\x51\x14\xce\x19\x0b\x3f\xfa\x89\x43\x36\x5f\xd1\xff\xa3\x51\x8b\xaf\x7b\x70\xf0\x41\xf7\x0a\x5a\x7f\x7c\xf0\x02\x5f\x09\x6f\x44\x03\xb4\x61\x3d\x62\xa6\xf3\xf3\x09\x23\x63\x3b\x86\xce\xcf\x27\x34\x89\x27\x8f\xcf\xcf\x27\x2d\x23\x6c\x4c\xa8\xfe\xf5\x88\x11\x60\xc6\x10\xab\x00\xea\x6b\xc6\xb6\x62\x05\x48\x5f\x55\x14\x5d\x8e\x84\xd8\x4e\xec\xc0\x6f\x5b\x40\xfb\xd7\xbd\x0a\xe9\xd8\xed\x4d\x14\x8d\x1a\x1c\xbf\xdb\x89\x1b\xbe\x7a\x81\x89\xa2\x1a\xf2\x35\x8e\x7a\x92\x92\xc7\x8f\xb5\x0a\x54\xb7\xed\xc8\xa7\xeb\x21\xbd\xea\xc0\x7b\x85\xcf\xf4\x86\xcc\xf1\x31\xdf\x18\x73\x5e\x14\xd9\x5f\x7e\x54\xb2\x59\x16\x45\xa3\x95\x5f\x79\xf4\xae\x26\xab\x97\xd5\x6d\xe9\xa6\x84\x4d\xb0\x4f\x5d\xf3\x40\x3a\xde\x86\x0e\x99\x54\xf2\xa5\xbf\x69\x4f\x12\x61\x1a\x7a\x70\xe8\xe5\x51\x5e\x1e\x2d\x98\xed\x4b\x77\x38\xb7\x1c\xeb\x41\x01\xc3\x74\x34\x65\xb3\xbe\x77\xca\x02\x46\xa4\xcb\x4d\xf0\x25\x47\x38\x20\x09\xdb\x43\x18\xd6\xe6\x20\xbe\xa5\x13\x3d\xa8\x87\xbd\x1b\x44\xab\xfc\x4e\xab\x5a\x0b\x38\x4a\xc1\x3d\x5a\xff\xcc\x0e\xa4\x72\xa0\x08\x10\xfb\x36\xd0\x46\xd2\x06\xe1\xdc\x60\x5c\x6d\x0f\x06\xa7\xbb\x6b\x2c\xff\x7a\x93\x2a\x1a\xae\xc4\xe9\x4c\x3d\xed\xbf\x09\x50\x55\x16\xa9\x0a\x1c\xa5\x0d\xe1\x6b\xe3\xc7\x34\xf0\x4e\xe0\xd9\xd7\x68\xab\x95\x89\x17\xe6\x8b\xdb\x16\xba\xaa\x93\x16\x04\xde\x37\x6e\xeb\x6e\xeb\x68\x04\x4f\x13\x66\xe2\x05\x62\xbc\xd0\x4a\x64\xa9\x1a\x8f\xe7\x0c\x46\x6a\xde\x04\x5a\xc2\x5b\x55\x6d\x36\xe0\xc1\x0b\x4b\x75\x33\x59\x6c\xeb\x5a\x96\xca\x54\xad\x9a\xc8\x42\xae\x79\xa9\x4b\xc9\x45\xe5\x5e\x93\x96\x41\x71\x43\xda\x47\x50\x6e\x33\xa9\xdd\xac\x30\x43\x30\x9f\x84\x29\x61\x06\xbb\xe1\x0d\xe7\x11\x6d\xcc\x7b\x5f\x5f\xfe\x26\x72\xde\x4c\xf4\xea\x23\x72\xf8\xe3\x9d\xc9\x68\x2d\xe8\x81\x9a\x99\xbb\xb9\x6b\xf4\x4d\x2c\xa8\x6d\x73\xfb\x29\xcc\xac\xe1\xe6\x4b\x17\xc0\xa9\xa1\x55\x7b\xda\x4c\x6a\xd9\x6c\x0b\x25\xc0\x94\xdc\x1c\xea\x7a\xcd\xa1\xb6\xea\x4f\x06\xb7\x93\x4d\xd5\x28\xdb\x77\x51\xd4\xbd\xee\xf4\x25\xb7\x6f\x02\x07\x30\x6c\xe0\x87\xfd\x68\x60\xc8\xa7\x73\xbe\x10\xaa\x2b\x18\x78\x21\xe4\x04\xa9\x4c\x00\xf5\x3d\x8a\x8a\xd0\x51\x86\x12\xd8\x71\x86\xdc\x0c\x72\x82\xe4\x0f\x5f\x8a\x53\xe3\xc4\x5a\x68\x5d\xe7\x3a\x6f\x66\x85\x28\x3a\xa1\xed\xa0\x6f\x1a\xa8\xaf\xb0\x58\x5b\xea\xc8\x33\x4a\x80\xb3\x73\xe1\xd8\xd7\xcd\x50\x35\x81\xbe\xbb\x3d\x47\x02\x85\x05\x98\xf5\x9c\x72\x9a\xa5\x95\xee\x41\x00\x59\x75\xb2\xcf\x32\xf4\x66\x69\x35\x17\x75\x47\x5f\x48\x6e\x29\x22\xb5\x18\xdf\x1d\x5a\x40\x68\xa8\x81\x31\xc2\x5b\x86\x38\xb7\x70\x6b\x17\xe3\xba\xa4\x28\x72\x61\xb3\x33\xaf\xa1\x37\x06\xb6\x56\x8f\x82\xb8\xf0\xfd\x90\xef\x9d\x47\x4f\x61\xe2\xb8\x9e\xaa\x3f\x7c\x4a\x59\xe8\x49\xc0\xd8\x05\x45\x5a\x8f\x93\x5e\xaf\x0e\x7b\xa1\x1e\x28\xfe\x5c\xf2\x9d\x2c\xb7\x6b\x69\x1d\x50\xfb\x0e\xa9\xe0\x17\x0a\x20\x61\xc1\x26\xd1\x7a\x51\xe9\x09\x90\x97\x59\x01\x85\x3a\x27\x99\xa1\x7b\x9d\xb3\xc2\x8f\x3f\x7e\x70\x27\x95\xf3\x9e\x43\xec\x83\xdf\x67\xbc\x1d\xfe\xe0\x93\x6e\xeb\x5c\xd9\xdf\xc6\x0f\x17\x7c\x3b\xf6\x7c\x95\x0f\x63\x98\xa4\xce\xaf\x78\x9e\xc8\x58\xaf\x01\xa6\x25\xc1\xaf\xce\x48\x84\x78\x57\x54\xd9\x32\xde\x95\xd5\x57\xdb\x4b\xe3\xce\xcb\x61\x08\xc7\x3b\xd0\x14\x07\x5c\x2f\x75\x85\xdb\xd6\xed\xfb\x2f\x8d\x90\x52\x16\xb3\x53\x4d\xa0\x80\x28\xfa\x9a\x2a\x6e\x0d\x65\x51\xf4\x35\x40\x3b\xe2\xf4\xd0\x1b\x2c\x3e\x3a\xdd\x73\xb3\xa9\xf8\x9f\x79\x0b\xe3\xfa\x6b\xdc\x31\xc2\x80\x13\xa9\x95\x0f\x7f\xf2\x25\x66\xc5\x74\xef\x69\x5b\xb8\x9f\xc1\x2a\x7d\x29\x57\x55\x2d\xb7\x25\x36\x6c\x28\xe5\xba\x35\xb0\x82\x5a\x1a\x69\xa7\xe5\x4f\x67\x0c\x81\xef\x6c\x27\x65\x82\xf5\x04\x73\x9b\x7b\x8e\xed\xf7\x7b\x8c\x62\x71\x6a\xca\x81\xb7\xbe\x1c\x8a\x2a\xd1\x2f\x1c\x0a\x36\x41\xaf\x47\x3b\xef\x0e\x19\xc6\x47\x30\x64\x3b\x08\x58\x98\xd5\x23\xd0\x86\x83\x8d\x2b\x88\x63\x45\x71\x98\x0c\xcc\x22\x0b\x19\x05\x6e\xee\x98\x0d\x13\xf2\xc6\x2c\x2e\x6f\x70\xa9\x91\x4b\xe1\xe0\x31\x5d\x92\xf5\xe5\x03\x39\xde\xbf\x69\xd6\x2e\x19\x36\x5c\xf2\x4e\xc6\x77\xf6\x95\xb8\xac\xdb\x71\x10\x45\x9f\xe1\x72\x00\x57\x81\xdf\xb2\x4d\xf1\x4b\x40\x6c\xd3\xb0\xa0\xae\x9a\x20\xbb\xd7\x98\x05\x60\x72\xe5\xd2\x65\xe9\x5c\x9b\x53\x48\x6c\x02\xae\x70\x67\x08\xbb\xcd\xd0\x7e\x33\x51\xf9\x5a\xbe\x55\xd9\x7a\x23\xb0\x45\xed\x65\xdb\xbe\xc8\x94\x9c\x94\xd5\x2d\x35\x96\x1e\x3f\xf9\x01\x7a\xa2\x13\x48\xe0\x11\xce\x62\xd3\x4b\xfc\xb0\xa9\x75\x1b\x0d\xa9\x46\x98\xfe\x11\x1d\x07\x33\xbc\xcd\xd7\x5b\xf8\xbe\x78\x74\xca\xbb\xaa\xc2\x61\xd8\xf5\xe1\x98\x98\x3d\x34\x00\xde\x49\xae\x57\x6f\x73\xdb\xbd\x05\xf8\xb1\x7a\x0a\xc9\x9e\xf7\xf4\x91\x3f\xf3\xe2\xc3\xef\xfa\xd8\xab\x0f\x14\x1f\x7c\xf7\x50\x2b\xfd\x99\x4a\x7c\xa4\x95\xff\xa8\x36\x0f\x98\xe8\xf0\x0c\xfc\xa0\xb6\x7b\x87\xdf\x94\x15\xea\x7b\x79\xaf\x57\x99\x4b\x58\x10\x00\x29\x6d\xa1\xe7\x79\xe1\x96\xa6\xeb\xac\xbc\x92\xcb\x77\xd5\x16\x10\xec\x75\x8a\xaa\x0b\xf3\xd4\x52\xaa\x2c\x2f\xf4\x2f\xe8\x8c\x37\xd7\x59\x03\x0f\xad\xa5\xca\x4c\x96\x4d\x76\x25\x7f\xb1\x3f\x7e\xd5\x3f\xc0\x4b\xd3\xdc\xbd\xc9\xe5\xad\x79\x4b\x8d\x0b\xe1\xd2\xbe\xb5\x7e\x6e\x7e\xbf\xc7\xac\xef\xe5\xbd\x4d\x31\x74\x60\xee\x17\x56\xab\xc8\x65\xa9\x7e\xf1\x3f\xe1\x65\xd5\x6a\xd5\x48\x4c\xc5\x9f\x90\x6a\x4e\x27\xbe\x5b\x06\x17\xb0\xc7\xd6\xd5\x5b\xd4\x52\x96\xbf\xf8\x9f\xf0\x04\x4e\xff\xa0\x15\x54\x65\xce\x0e\xf0\xc2\xa5\xdf\x5e\xe7\x43\x7b\x36\x61\xd5\xcd\x2e\x9f\xb0\x9c\x40\xfe\x28\xba\xb5\x8e\xf8\xb8\x18\x25\x26\x7c\x78\x62\x1b\x22\xf1\x3f\x63\x39\x71\x6d\xe1\x9e\x0f\x43\x21\x3e\xf4\xca\x3a\x8d\x54\x72\x1a\x3f\x89\x54\xf2\x59\xfc\x79\xa4\x92\x27\xf1\x34\x36\x0f\xe2\x58\xb0\xd6\x50\x3d\x4c\x3c\xb8\x17\xf2\xf4\xe1\x41\x48\x5e\x12\x7e\x59\x6c\x6b\x73\x59\x6d\x15\x19\x80\x47\xea\x6e\x3f\xe4\x5c\xf4\xb5\x0a\xa7\xaf\x7c\xed\xfc\x3e\x7f\x78\x48\x37\x38\xcc\x8b\x2b\x7c\xc7\x26\xa2\x80\xc2\xd0\xd6\x18\x8e\x9e\xb4\xe4\xa8\x63\x02\xbf\xab\x1b\x59\x13\x0e\x3f\x0b\x99\xdd\x48\x9b\xbc\x55\xc4\x76\xbb\xc9\x6e\xae\xf0\x01\x73\x61\x1e\xb1\xb7\x3e\xf5\x9b\xbb\x15\xe4\xd6\x68\x13\x2b\xa3\x21\x1f\x0c\x0e\x8b\x9a\x0a\x0c\x09\x9d\x85\x02\x88\x62\xdc\xf6\xcf\x79\x47\x19\xf2\xe6\xba\x6d\x03\x07\x43\x80\x8a\x6a\x5b\xd3\xeb\xc2\x6f\xfe\x78\x29\xdc\x86\x6f\xf8\x20\x86\x9b\x67\x00\xe8\xdc\xb4\x68\xe0\xbf\xd3\x61\xde\xb3\x5e\x78\xa6\x2e\xaf\xbc\x03\x2f\xa4\xef\x79\x55\x1e\x5a\xea\x1e\xca\xce\x4f\xf5\x03\xab\xd5\x43\x91\x64\xe0\xdb\x7e\x28\xed\x75\x8a\x6b\x15\xab\x86\xd4\x61\x53\xf1\x5b\x2a\x7b\x96\x06\x3c\x8d\xaa\xfd\xe6\x3a\xa9\x5d\x13\x8d\xc9\x84\x8c\x83\x5b\xb1\xbf\x05\x0c\x2a\xb8\x23\xe3\xb5\xdb\x37\x83\x68\x1d\x3e\xf6\x33\x64\x3f\xd5\x51\x5e\x1e\x49\x86\xe2\x7e\xb5\x02\xbc\x79\x99\x56\x83\xd8\x9c\x60\x16\x50\x51\xe4\xb1\x28\x02\xf4\x61\x40\xc0\x51\x5c\xb9\x53\x42\x50\x72\x4a\x38\x4e\xb8\x33\xe0\x84\x0f\x9f\x92\x75\xe2\x0a\x78\x69\x22\x19\x8c\x13\xd3\x5b\xf0\x54\x4a\x46\x59\x2d\xb3\xf6\xb2\x6e\x17\x55\xd1\xca\xf5\xa5\x5c\xb6\xd7\x75\x9b\xaf\xaf\x5a\xd0\x81\xdb\x22\x2f\xdf\xb7\x5a\xa4\xb7\x9b\xac\xce\xd6\x8c\x7e\xcc\xb9\x09\x60\x63\xd9\xf9\xc9\x97\x27\x57\x39\x7f\xae\x5f\x80\xc7\xfd\xed\x53\x70\x18\x6b\x9f\xea\xd2\x4e\x72\xfe\x5e\x8a\x13\x73\x54\x7d\xde\x3c\xa6\x49\x9c\xfe\x5b\xcc\x5b\x71\xde\x3c\xb6\x27\xd8\x13\x76\x92\xf3\xdf\xa5\x38\xf9\xf7\x79\xf3\xf8\xe9\x88\x26\xf1\x79\xfa\xfc\xc5\xb3\x77\xcf\xce\xd3\xf6\xf8\x98\xb5\x3a\x61\x7e\x3e\xd7\xbf\xbf\x3c\x6f\x1e\x3f\x0a\x63\xb5\x7e\xee\x1e\x04\x23\x0c\x9c\x5e\xd2\x60\xd7\x40\x0f\x71\x08\x55\x88\x5d\x47\x54\xad\xf3\x01\x12\xb1\xc5\xb0\xa3\x04\xdc\x66\x08\x4b\xa7\xf3\xb6\x0d\x80\xcf\x5e\x74\x29\xd3\x60\x22\x51\x14\xdf\x0f\xb1\x3e\x8e\xc9\x09\x19\x1b\xdd\x37\x28\xe9\x2b\xd9\x8b\xe7\x3a\x41\xd7\x5e\xef\x00\xe1\xe8\x88\xfe\xca\x12\x19\xaa\xd0\x2e\x54\x27\xb6\x5a\xfe\xc1\x5b\xc3\x37\xbd\x91\x83\x96\x15\xbe\x40\x20\x96\x1e\x5f\xac\xde\x06\x74\x6d\xe9\x34\x0f\xa2\x45\x18\xcf\x84\x39\xe1\xe3\x39\xe3\x85\xc8\x9d\x5d\xdd\x4d\x04\x63\x3b\xcd\xcc\x04\xe2\x99\x3f\xa0\xe2\x85\x81\x31\x9b\xf2\x5a\x14\x69\x35\xef\x7b\x3f\x75\x0e\x7c\x79\xc5\x75\x9e\xb4\x9c\xb3\xd9\xbf\xba\x75\x6a\xc4\xbf\x82\x3a\x2d\x44\x08\xbc\xd6\x30\x6e\x02\x7a\x10\xa5\xc4\xb5\xc4\x2f\xb2\xcb\x56\xf3\x00\x9d\xa8\x87\xf4\x2f\xa3\xe8\xb2\xb7\xbe\x2a\x3b\x62\x85\xe3\x81\x8d\xcd\x03\xe8\x70\x49\xac\xc7\x05\x5c\xb7\x2d\x55\x1d\x5f\x0a\xd1\xa5\x01\x08\x4e\xb1\x7f\x0b\xdc\x9e\x95\x28\x8c\xf4\x4e\xe7\x7a\x97\xe5\xdc\xa0\x91\x3c\x87\x6f\xc4\x94\xaf\x3c\xaf\xd8\x52\xac\x8e\x4f\xf9\x35\x20\x8b\xf3\x4b\x71\x45\xaf\xe1\xe4\xe3\xb2\x6d\x57\x5f\x9e\x0e\x45\xb1\x5e\x47\xd1\x28\x74\x38\x89\xa2\xf7\xe6\x3b\xaf\x03\xbe\x82\x9e\xa0\x71\x90\x40\x72\x22\x7f\xa7\x15\x9b\x5d\x46\x11\x84\x70\x8b\xd0\xca\x57\xf1\x1c\x9c\x9d\x28\x63\x8c\xff\x26\x01\x07\x07\x16\x0b\x74\x8a\x5e\xc1\x80\xa2\x95\xb8\xd0\xdb\x79\xe0\x40\xeb\xba\x0a\x8f\x4e\xb9\xe4\x35\xeb\xe0\x4b\x82\x9b\x42\xe0\x06\x15\x06\xcc\xe5\x8c\xe7\x6d\x5b\x1b\xe3\x5b\x23\xc0\x54\xbc\xce\x36\xf4\x5e\xd2\x2a\xf0\x3f\x7a\x21\x1d\x97\xcb\x6c\xf3\x74\x35\xdb\x8c\xc7\x6c\x21\x2a\xbe\x19\x09\xb1\x84\x23\xa2\x5b\x74\x86\xa1\x0b\x0e\x40\x06\x8c\x37\x7a\xb3\x86\x6e\x58\x19\xbf\xd7\x37\x5c\x71\x00\x59\x83\x87\x0a\xe9\x66\xce\x17\x7c\x03\x5f\xd7\x18\xdf\xa6\x2c\xcd\x3c\x9e\x75\xef\x03\xb1\x76\x19\xff\x4a\x32\xdd\x8f\xb3\xcd\xd3\xc6\x54\x26\xd3\x45\x59\x57\xa8\x45\xe8\x0a\x35\x72\x33\x70\xd1\xf5\xfc\xd3\x35\x74\x5a\xc1\x96\x2f\xf4\xdc\x58\x4c\x9a\x7a\x11\x45\x04\xfd\x4d\xf5\x30\x0c\x0b\xeb\x11\x6f\xdc\x4e\x2e\xe4\x4d\x56\xfc\x54\x17\x51\x34\x5a\x4c\xca\xea\x0c\x9e\xd2\xe5\xda\x1b\x58\x20\xdf\x95\x55\xb9\x90\xb1\xce\x53\x2e\x64\xdb\x2e\x7a\xf2\x0e\x92\x09\xdb\xb3\xf8\x99\x7e\x9f\x77\x30\x73\xf1\xb0\xbf\x4b\x60\xe0\x58\xf0\x2d\x73\xa6\xc6\x10\x55\x52\x1e\xb0\x33\xf0\x4a\xa8\x24\x84\xd7\x67\xb1\xe4\xb9\x98\xce\x0c\x67\x53\x6d\x7c\x91\xc1\x6b\xb9\x6d\xb5\xa4\xaf\x83\x38\x7d\xdd\xa3\x32\x2b\x41\x6c\xdc\x23\xab\x63\xdd\xa1\x5e\xa6\x25\x04\x48\xd4\x0c\x9c\xd3\x74\x96\xa0\x8b\x3b\x79\x3b\x7e\xe5\x01\xf1\x9d\x0c\x03\x61\x43\x1f\xbf\x61\xde\x67\xdb\x14\x6f\x25\x27\x4f\x1f\x9d\x7e\xf9\xf4\xe4\xd1\x93\x2f\x09\xe2\x3a\x1f\xe8\x52\x81\x33\x0a\xd8\xc2\x7b\xde\x5a\x40\x96\x64\x41\x9c\xfb\xce\x5d\x51\x44\xfb\x28\x06\xa7\xbd\xa8\x65\x13\x47\x8d\xfc\x1a\x16\xfe\x19\xdc\xf8\x1a\x66\xb0\xa4\x69\x2e\x90\x9a\xae\xcf\x4e\xf9\x8b\xa4\x79\x5a\xcf\x79\x06\x08\xe4\xf9\x8a\x2a\x40\x82\x66\x68\x00\xcf\xdb\x16\x1e\xe3\xe0\x71\x19\x16\x98\xf7\x0b\x7a\xd3\x29\x08\x4e\xda\x60\xc1\x6a\x6c\x0b\x9b\x1a\x05\xfd\x12\x50\x52\xdd\xe8\x99\x39\x5a\x20\x81\x5e\xd8\x75\x0d\xc6\x73\x95\x07\xa1\x99\x21\x37\x63\x0d\xe1\x04\x1d\xa5\x1e\x06\x57\x18\x42\x2a\xdd\xf8\xca\x57\xf4\x11\x2d\x99\xc1\x89\x2f\xd3\xbf\xfb\x78\x76\x48\xb2\x0b\xa1\x07\x37\xb0\x29\x55\x5a\xcf\x93\x9e\x92\x06\x34\x8a\xdd\x13\x48\x70\x04\xb3\x27\x90\xb3\xf0\x05\x46\x1d\xdc\x97\xe9\xbf\x02\x80\x03\x1a\x5e\x5a\x8d\x71\x7f\x18\xac\x0c\xe4\x43\x43\xc3\xf1\x47\xa7\x2b\x0e\x9f\xbc\x1f\x66\x64\x03\xc4\xd9\x26\xcf\x41\x08\xaf\x3c\x04\x55\x90\x09\x32\xbc\xa0\xa3\xbd\x71\xcf\x07\x4e\x71\x76\xa8\xd5\x9e\x9a\x13\x9a\xe0\x0c\xe6\x74\x20\xed\x6f\xfd\x24\xbd\xe4\x82\x45\x2d\x70\x71\x95\x61\x4c\xaf\x3c\x08\x70\x64\x7b\x8e\xde\x98\x03\x3b\xd2\xdf\x64\x6f\x07\xd5\xfd\xc4\xff\xbc\x96\x3f\xbb\x46\xed\xb8\x82\x9a\x68\xc4\x4d\x2d\xff\xb3\x0a\x59\x95\xae\xfb\xb2\xd3\x81\xb4\xbf\xf5\x93\xac\xf9\xc2\xd7\x6c\xa6\x26\x79\xd9\xc8\x5a\x7d\x05\xa6\x6f\x2d\x96\x3a\x40\xce\x50\x55\x34\x8b\xff\xf9\x9a\xc2\xbb\x43\x69\xdc\x4b\x38\x78\x35\x7a\x82\xe9\xce\x5a\xa9\x41\xeb\xc1\xff\xc0\x0b\x3b\xa4\x3c\xf0\xf2\x03\x20\x56\x07\xe6\x0f\x67\xd0\x66\x65\x42\xe3\x5f\xaa\xe6\x0c\xce\xc7\xfb\x74\x3e\xb4\xb7\x34\x49\xa0\x0c\xd1\x7b\xf3\x8e\x63\x76\x77\x03\x39\xb0\x48\x04\xee\xaf\xc6\x8a\x14\x45\xba\x1e\x68\x71\x52\x89\x8c\x8d\x8d\x5a\xeb\x1c\x87\xd4\xf2\x47\x56\xe7\xe9\xc4\xbe\x73\xbd\x90\x7d\xea\x1c\xf7\x67\x3a\xb0\x59\xc2\x63\xcf\x2e\x35\x4c\x17\xf6\x00\xd1\x33\x82\x2d\x87\x83\xf4\x71\x3e\xcc\xc3\x30\x32\x32\x8a\x46\xcf\x03\xf2\xb6\xd1\x95\x4c\x9d\x97\xbe\xfc\x98\x97\xfe\x9c\xed\xa4\xe8\xfb\xe0\xeb\xd1\x5d\xdf\x23\x15\x84\xdd\x7e\xc0\x71\xb8\xf9\x9a\xd2\x1c\xa4\x3f\xdc\x69\x0a\x3b\x2d\xa8\xb8\xd0\x85\x8a\x69\x00\xa5\xb1\x57\x66\x98\x59\x39\x87\x73\x1d\xa6\xf9\x47\xc4\x91\xd1\x13\xba\x60\xb9\xd6\xac\x9c\xba\xd8\xb9\x8f\x0d\x78\xbf\xd1\xe9\x8e\xf2\x59\x80\x5b\x8c\xb3\xfc\xe9\x74\xe0\xdb\x80\x5e\x87\x83\x1b\x90\xa9\x8c\x71\x55\x37\xcc\x3b\x7b\xa6\x97\x83\x80\x1f\x00\x3f\xec\x5d\x15\x13\xfc\x45\xac\x0c\xd3\x49\xe6\x27\xe1\xe1\x14\x8b\x09\x8a\x0e\x9b\xfa\x0c\xa6\x35\x81\xd9\x4d\x6c\x13\x3c\x2b\x8a\x98\x04\xcd\x31\x64\x97\xeb\x41\xb5\xcb\x4e\x08\x1f\x32\x7c\x01\x8e\x55\xee\x98\x04\x8f\x4f\x79\x26\xa6\xb3\xec\xa9\xc8\x67\x99\x56\x1e\x81\x19\x34\x0f\x22\xd9\x71\x5e\x68\x35\xeb\x96\x56\x69\x36\x67\xa9\x9a\xd3\x92\xf1\xad\xd9\x98\xd5\xbc\x44\x16\x86\xce\x1c\x0d\xb0\xd7\x6b\x8f\xbd\xfe\x5d\x3f\xe8\xd9\x06\x3a\x27\xa3\xcd\x1d\xc3\x68\xe7\xb1\x0d\x76\xfe\xb6\x1b\x5d\x6c\x2d\xca\x9d\x4d\x84\xdb\x43\xe6\xf2\x36\xa0\x5c\x50\x93\x6a\x23\x4b\x59\x63\x44\xa5\x1e\x99\x57\x52\x3d\xaf\xd6\x9b\xad\x92\xcb\xb7\x18\x27\xca\xf6\xfc\x65\xa7\x3a\xb9\x34\xae\x63\x2d\x61\x50\x03\x6f\x59\xf9\x49\x3e\xa4\x88\x82\x7d\xc7\x6a\x68\x10\x6d\xfa\x2d\xe8\x89\x51\x44\x09\xec\x38\x32\x01\xcd\x63\xcf\xc2\x61\xb3\x4b\x15\x6b\xdb\x52\xcb\xc4\xb6\x05\xcd\x15\x3c\x54\x83\x08\x56\xc6\xf8\xe8\x6c\xb2\xc9\xef\x64\xf1\x55\x75\x07\x15\x6e\x28\x8b\xa2\xef\xcc\xac\xcf\x58\x14\xbd\xb4\x27\xb9\x08\x5d\xd2\x4c\x80\x89\x90\x57\xa2\x99\xac\xf3\xf2\x67\xb8\xc8\xf5\x45\x76\x87\x17\x3e\x3d\x48\xb5\xcf\x89\x8c\xeb\x9a\xde\x9a\x9c\x98\x56\x87\xcf\x54\x3c\x78\x2a\x67\x01\xa8\x53\x96\x64\x63\x42\xe2\x80\x5d\xfe\x9f\x1d\x4b\xd4\xae\x03\x62\x85\x07\xac\x9e\x0f\xd0\xf1\x78\x08\xc5\x1e\xc0\x08\x36\x86\x14\x9b\x71\xbf\xef\xc4\xbf\xb8\xb7\x4a\x2c\x7b\xcb\x76\x85\x09\xd4\x5c\x34\xcd\x3b\x79\xa7\x04\xd9\x18\x16\xc9\x38\xbb\x04\x84\x5c\x39\x2b\xe4\x4a\xc5\xc7\xa7\xfa\xff\x36\x77\x33\xf8\xde\xf8\x8b\xe9\xe6\x6e\xb6\xce\xea\xab\xbc\x3c\x56\xd5\x26\xd6\x77\x36\xd9\x72\x99\x97\x57\xf1\x74\x76\x59\xd5\x4b\x59\xc7\x53\x02\x88\xb1\xc3\xc5\x5b\xa2\xd0\x99\x09\x11\x8d\x21\xcc\x76\x76\x59\xdd\x1d\x37\xf9\x07\x5d\x0e\x96\x72\x7c\x59\xdd\xcd\xaa\x1b\x59\xaf\x8a\xea\x36\x6e\x00\x9c\xcf\xbc\x39\xce\xb6\xaa\xb2\x2f\x0b\x6b\x10\xd6\xf3\x2f\x33\xa8\xdf\x5f\x08\xcf\xba\x01\x34\x45\x57\x89\xda\xe2\xbc\x93\x38\x08\xbb\x33\x60\xcb\x66\xb5\x20\xa7\x7f\x31\x9e\x3c\xd5\x86\x2f\xc4\xe9\x13\xbd\xcc\x00\xda\xbf\xae\xcb\x2b\xb9\x52\xcc\x7d\x6e\x9d\x5f\x5d\x2b\x41\xbe\x98\xfe\x85\xf0\x46\x7c\xf6\x85\xc9\x0a\xc9\x8c\x57\x3e\x05\x6a\xe9\x9f\xb3\xad\x23\x88\x6d\x7d\xc2\x73\xfb\xaa\xed\x04\x8f\xa8\x60\x5c\x9d\x7c\xc6\xf4\x07\x85\x5b\xcc\x82\x19\x8c\xc0\xc0\x7e\xa5\x82\xa5\x18\xf9\x8e\xab\x6d\xb9\xa4\x80\xe3\xf4\xb2\xa8\x32\xe0\xf0\xd9\xfb\xa9\x0a\x36\xbe\xc3\x00\x27\x08\x7d\xe2\xdb\x07\x6e\xcc\xb6\x2e\x9c\xd9\x7e\xc8\x65\xb6\x78\x7f\x05\xef\x7a\x5e\xe4\x1b\x41\x0c\xa5\x86\xee\x4c\x3d\x28\xba\x21\x44\xc3\x8f\x10\x7e\x06\xeb\x4b\x0d\x7b\x54\xe8\x88\x6e\x39\x02\xdc\x47\x07\x9e\xf5\xc0\x38\x67\x7c\x77\x59\xdd\xbd\x85\xf1\xf4\xa3\x2c\xf2\x07\x60\xee\x25\x65\xbc\xda\xf3\xae\x14\x79\x20\x5f\x63\xf2\x59\xb6\xd5\x07\xb2\xd5\x7a\x41\xc6\x17\x9e\xb9\x01\xf2\x40\xde\xc5\x9e\xe3\xb8\xc6\xba\x3e\x54\xc3\x1c\x74\x67\x13\x58\xf5\xab\x14\x29\xf9\x59\x5e\xbe\xcf\x15\xe1\xe4\xac\xfa\x40\x38\x59\x37\x64\xce\xbf\x91\x0f\xf4\x12\x36\x15\xff\xbe\x1b\x84\xff\x48\x06\xb4\x54\x7a\x9a\x6a\xf1\xdb\x00\x81\xc8\xf7\x32\x95\x1d\x04\x41\xa9\xb7\xa8\xdf\xc8\x44\xc6\x70\x6b\x70\xf5\x54\x40\xd2\xd6\x85\x5a\x1c\x4b\x1f\x9b\x51\x8a\x5f\x65\x07\x75\x2a\x5f\x51\x2a\xc5\xaf\x32\x2d\xe7\x63\xc5\xe0\x05\xce\x9c\xb8\x07\x81\x2f\x71\x80\xfe\x03\x82\xc1\xca\xaa\x94\x2d\x98\xea\x69\x32\x3a\x5e\xa4\x32\x9b\xb3\xc9\x98\x9d\xf0\xbf\xeb\xdb\xc7\xc7\x27\xfc\x5f\x52\xec\x9c\x94\x09\xe6\xd1\x4d\xde\xe4\x97\x79\x91\xab\xfb\x98\x5c\xe7\xcb\xa5\x2c\x09\xb7\xb2\xc7\xc4\xf8\xef\xb9\x54\x62\x57\x48\xa5\x64\xfd\x76\x93\x2d\xb4\x2c\x21\x53\xc2\x57\x55\xa9\x7e\x06\x12\xdb\x98\x7c\x3e\x9d\x92\xa0\xfd\x94\xea\x32\x35\x5a\x60\x07\x0f\x9c\x5b\x27\x30\xf1\xd6\xd9\x1d\x9d\xf2\x3a\x7d\x32\x3f\xa6\x65\xdb\x4e\x19\x1b\xd3\x1a\x20\x25\x00\x3f\x22\x56\x7e\xd2\x96\x6a\x20\x8c\x4c\x10\xe4\xcf\x05\xf4\x9c\xd3\x78\xca\x1b\x31\xe5\x0b\x31\x45\x02\x3d\x21\x68\x9d\x10\x14\x85\x24\xb6\xd3\x84\x38\xcb\xec\x14\x51\xfb\xb2\xa7\x9f\xcf\xb2\xb1\x78\xc2\x08\x4a\x2d\x8b\x31\xb0\x18\x3b\x90\x8f\x72\x9c\xcb\x34\x03\xd0\xd0\x8a\x31\x5e\x27\xd4\x95\x66\x33\x1f\x7b\x44\x10\x23\x71\x49\xf7\x21\x5b\xfa\xe8\xf0\x01\x53\x45\xcc\x3f\x26\x3f\x23\x27\x30\x3e\xc7\xe2\xb0\x22\x83\x65\xfb\x54\x80\x48\x0c\xb3\x7f\xa4\xe4\xb8\xf9\xb4\x7c\xb6\xcf\x00\xdc\xe9\x4b\x80\xcd\x58\x8c\x45\xd0\x7d\xf0\x73\x21\xf3\x82\xca\x94\xa0\x34\x26\x63\x75\x38\xe0\x95\x1b\xf0\xf3\xe3\xfc\x78\x71\xdc\x1c\x4f\xfe\xca\x98\xee\x75\xbe\xf0\xfd\x5c\xf7\xc6\x0e\xe8\x43\xbc\x12\x74\x74\x36\x39\x10\x5b\x54\x2b\x42\x2c\x8a\x88\x5f\x16\x3b\xd8\x2c\xee\x01\xc2\x47\xa7\xbc\x06\xcd\x95\x67\xc2\xe8\x63\x35\xe3\x8d\xf8\xb4\x1a\xeb\x01\xe5\xb5\xa7\x1e\x3d\x73\x36\xcb\x04\xd1\xcb\x2e\xb1\xbc\x81\xc3\x75\x8d\xa2\xaa\x6d\x31\xa3\x10\x22\x6b\xdb\x51\xb0\xe4\x68\x9d\x8c\xe4\x65\x91\x3f\x00\x2f\x83\x1f\x00\x2c\x34\x7a\x29\x06\x6f\x8d\x1f\xe5\x42\x35\x8e\x12\xcd\x00\x73\x7c\x62\x4b\xd0\x5c\x34\x78\xdc\x0a\x11\x89\x32\x6d\xe6\x0c\xc3\xa2\xc3\x3a\xe9\xde\x19\xdb\xa9\xd7\xb6\xb4\x1a\x9a\x4f\x3c\xe7\x35\xcf\xd8\x58\xcf\x59\xdf\x91\x95\x0a\x63\x4e\x02\xbf\xb7\x2a\xf0\x54\x05\x62\xcc\x20\x5f\x60\x05\x5e\x34\x0d\x42\x86\xed\x2a\x2d\x75\xd4\x7d\xbc\x3b\x44\x33\x05\x8b\xa9\xd9\x9f\x41\xaf\x12\x93\xd9\x6d\xf9\x01\xef\xa3\x4c\xc8\x29\x89\x4b\xf0\x03\x74\x10\x34\xf1\x2e\x2b\xf3\x35\x38\xf8\x7c\xa7\x64\x0d\x3f\xc0\x2f\x1a\x9d\x6a\x8a\xed\xda\x5f\xae\xf2\xa2\x78\x6d\xaa\xa1\x2f\x0b\x79\xf7\x4d\x5d\xdd\xda\xdf\x6f\xaf\xeb\xbc\x7c\x0f\x57\x5e\x2a\x8e\xa6\xfc\xaa\xce\x97\xcf\x6a\x99\xd9\xdf\xcf\xa1\xd4\xee\xd5\xd7\xe5\xb2\x9b\xf0\x56\x65\xb5\x7b\xfa\x47\x7c\x89\xf9\x19\xe4\xfd\xb1\xba\x75\x19\xf5\xa0\xf9\xd6\xbd\xb4\xf2\xf5\x44\x2d\x10\x7e\x6c\xae\x33\xf4\xf9\xb9\xcd\x97\xd5\x2d\xfc\xfa\xf0\x1d\xd0\xfb\xe9\x5f\x55\xb5\x46\xc7\x56\xb3\xd6\xc5\xbb\x3d\x87\xa5\x71\xc0\x2d\x01\xfd\x0b\x3e\x1b\x75\x2d\x31\xff\xd5\xbb\x36\x7b\x9b\x00\x7a\x88\x37\x00\xa5\xca\x17\xe2\xef\x6e\xef\x01\x2e\xe8\xb8\x09\xca\x57\x74\x01\x1b\xae\x47\x92\xea\x2d\x73\x86\x83\x17\xc6\x00\x44\x7f\x06\x97\x4d\x00\x1b\xe1\xa7\x61\x14\x91\x2b\xa9\x48\x0e\x3f\xbd\xf1\xd9\x90\x78\x82\x6d\x48\x4f\xa1\xa4\x8a\x8b\x54\xcd\x67\x81\x65\x84\xe6\x21\x8d\x05\xad\xdc\x8a\x55\xea\x19\x57\x01\x3f\x2a\x2d\x85\x41\x54\xaa\xb4\x1c\x21\x25\x0c\x22\x82\xd6\x87\x11\x80\x21\x99\xb5\xc0\xde\x1a\x09\x91\xb7\xad\xfe\xa8\x72\x0c\x1c\x26\x87\x60\x49\x8d\x07\x4b\x62\x87\xaa\x5d\xdb\x12\x73\xfa\x09\x5e\x4a\x1e\x74\xd2\xab\x76\x44\x6f\xfe\xf4\xe7\x08\x92\x97\xd7\xb2\xce\xf5\x7c\xd4\x2d\xd1\xf4\x5a\x42\x80\x19\x3e\x33\x51\xbd\xba\x23\x21\xec\x31\x29\x74\x8a\x77\xb5\xe6\x25\x83\xd6\x11\x25\x70\x66\x2c\x0e\x20\x7e\x3b\x68\x52\xa6\x4b\x1d\x64\x9f\xeb\xd7\xb0\x23\xe9\xc7\x7b\x92\x75\xba\x2d\xec\xad\x29\x2f\xdd\x3e\xd1\x21\x0f\x39\xd9\x0d\x98\x44\xf5\x3a\x2b\x0c\x2a\x91\x02\x69\xa6\x20\x93\x54\x7a\x77\x8c\x58\x3f\x65\xdb\x96\x09\xcd\x43\xb9\x56\x31\x0e\x78\xec\x65\xdb\xe6\xcd\x4b\x2d\x82\x24\xcd\x59\x92\xb7\xed\x34\x46\xc2\x09\x67\x8e\x49\x09\x12\xf5\x13\x6e\x54\x8d\xf9\xa1\xd9\x24\xf8\x36\xd1\x97\x51\x76\xc6\x38\x1e\xf9\x7f\x98\x36\x3a\xc4\x0f\xb3\xe0\x66\xc3\xb2\x1d\x6e\x7d\xa5\xbb\x3c\x2f\xaf\x7c\x16\xca\x70\xbb\x94\x98\x75\xb3\x66\x31\x60\x32\xfe\xab\x0b\xd7\x68\xd5\x2e\x9b\x09\xcc\x93\xcd\x40\x55\x4d\xd7\x9a\x65\x37\x13\xa3\xb3\x49\x47\x0d\xd7\xab\x98\xd7\x1f\x01\x5b\xd5\xea\x95\xbc\x11\x34\x6b\xdb\xfa\x93\xd7\xe3\x5c\xcb\x82\x3a\x31\xcb\x4b\xcd\x1b\x9e\xb3\xd8\x41\xe3\x36\x51\x94\xa1\x9e\xf4\x9f\x28\x18\x41\x6f\xe7\x7a\x2c\x1c\x9b\xb7\xd8\xe5\x0b\xdf\x0f\x1a\x08\x5f\x1c\x4e\x79\x83\x4c\x46\x2b\xaf\x8c\x82\xb3\x39\x82\xae\xe9\xe9\xc1\x4b\x11\xe0\x94\x71\xa5\x80\xf5\x64\xc1\xac\x2f\x98\x1d\x14\xc1\x56\x58\xfc\x53\xd2\xb3\xc9\xe1\x0e\xa8\x3f\xa2\x60\x51\x33\x9a\x44\xf0\x1d\xb8\xbe\xf9\xe2\xfc\x88\x19\x1c\x16\x85\x5c\xa9\x63\x18\x0b\x3b\xff\x4c\x3c\xdd\x0f\x8d\x8b\x8f\x97\xb2\x67\xcc\x2c\xee\xa1\xdf\x20\x5a\x1b\x08\xe1\xd6\xc0\x40\x08\x37\x66\x07\xa3\x3f\x0e\x58\x18\xdd\x54\x91\x63\x3d\x59\xf0\xd4\xcd\x0f\xc2\xf0\xcc\x1a\xce\x39\x77\x7b\x2d\x6a\x07\x50\x19\x4a\x1b\x24\x7a\x44\x58\x9c\x96\xf3\x59\xfd\xf4\x73\x38\x08\xad\x52\xa9\xb5\xd8\x7a\xae\x5f\x90\xa7\xf5\xbc\x6d\xf3\xb4\x3e\x7e\x02\x7f\xa7\x01\x50\xde\x3e\xd4\xc8\x1d\x3a\x9d\xaf\x9d\x96\x8b\x42\x81\x25\xbf\x7b\x10\xd8\x97\x89\x1f\x31\xeb\xf7\x8c\x7e\xfa\x73\x32\xdc\x9d\xf4\x11\xc7\xf1\xc3\xbd\xba\xeb\x18\x90\xb3\xa7\x15\x58\x56\xf3\x54\xa5\xd9\x7c\xee\x07\x1d\xa8\xff\x7a\x41\x73\xcc\x00\xfb\x3e\xa6\x6f\x99\x84\xb0\x76\x25\x8b\xfd\x88\xdd\x33\xf0\x27\x3c\x44\xe5\x35\xb6\xe8\x77\xb7\x52\x96\xa2\x52\x3c\xd4\xd6\xba\x9e\xf1\x95\xe2\x5a\x74\x0e\x84\x18\xeb\xfd\x19\x1a\xeb\x0b\xb9\xb6\xc1\x0b\x9b\xba\xda\x88\xd2\xba\xde\x35\x79\x79\x25\x2a\xbd\x14\xe0\x6f\x0f\xfa\x83\xde\x7f\x80\xa7\xd4\x08\x65\xfd\xb1\xb3\x5a\xd9\x43\xb6\x5b\x61\x03\x0a\xac\xbb\xb6\x2c\x97\xa2\xc6\x9f\x80\xb7\x97\xf7\x56\xd9\xd2\xaf\xb2\x7b\xbe\xd8\xd6\x87\x47\x01\xf8\x95\x1b\x23\xc6\x6d\x75\xdd\x68\x91\x46\xfe\x22\x22\x96\x39\x76\x0d\x9f\x71\xd5\xf7\xf7\xf7\xbc\xde\x0e\x30\xef\xf0\xf2\x8f\x5e\x16\x36\xc0\x64\xb9\x45\xc5\xd4\x90\x0d\x57\x8d\x50\xc2\xb6\x59\x1a\xb4\xe5\xdc\x9e\xb3\xf5\x1f\x7c\x2c\xf9\x94\x9f\x0e\xdf\x33\x47\xc7\x58\xaa\x3d\xa7\xab\x6e\x05\xb5\xad\x7a\xec\x5b\x9f\x3d\x56\x63\x7f\xd5\x2d\xaf\x51\x72\x63\x8e\x67\xc2\x24\xef\xcd\x84\xa1\x92\xb6\x7c\x4b\xf3\x1d\x45\xc0\x27\x82\xac\x22\x1f\x6d\x54\x77\x1f\x19\x58\xf6\xfc\x60\x0f\x11\x0c\xd2\xf0\x1e\x0f\xcb\x13\x3b\x17\xe9\xd4\x5b\xa6\x4d\xdf\x38\xa0\x16\xd0\x65\x75\x9d\x83\x63\x5e\xeb\x5d\xae\x93\x53\x89\x5d\x66\x41\x65\x4c\x66\x5c\x1d\xcc\xbd\xa4\x9b\x35\xa6\xca\xce\x5d\x6c\x0d\x4c\xe7\x04\xb0\x63\x71\x57\x38\x02\x10\x60\x2d\xa3\x9b\x5e\xf5\x6e\x27\xab\x3b\x68\x53\x57\xfa\x41\x0a\x95\x2c\x1e\xac\xf8\x28\x14\x6c\x1f\xa9\xf7\x23\x89\x44\x7a\x1b\xd6\xaf\x3b\x28\xf6\xb7\xb1\x13\x26\x9d\x0f\x80\x7b\x63\x20\x1b\x85\x48\xab\x4e\x93\x1b\xe5\xe1\x5d\xb5\x11\x03\xc9\xb0\x28\xee\xfa\xdf\xda\xfb\x00\x3d\xf5\x20\xa1\xe3\x70\x34\x54\x41\x1b\xa5\x01\xb2\x65\xa7\x37\x45\xd9\xb0\xfb\xd0\x9e\x37\xb7\x7a\xc5\x3a\xbc\x37\xf9\xeb\x31\x6a\x1b\x55\x43\xe5\x63\xf8\xf9\xe6\x3b\x76\xf2\x24\x08\x92\x23\xf0\x2c\x81\xf8\xaf\xd5\x9d\x38\x18\x89\x0c\x7a\x45\xec\x90\x48\x21\x57\x3c\x53\xbc\x51\x88\xf3\x84\x80\x8c\x6d\x73\x5d\xdd\xb6\xd7\xf9\x52\xb2\x47\x27\x7c\xa1\xc4\x89\x47\x12\x7e\x14\xe0\x38\x15\x8a\xb2\x5d\xa6\x35\x5a\x70\x5f\xce\x26\x68\xa1\xc3\xa3\xc4\xdf\xb7\xb2\x51\xcf\xec\x06\xf6\x65\x9d\xad\x65\xf2\x40\x3a\x2d\x14\x8b\x3b\xd4\x3d\x85\xe2\x30\x7e\xc0\x49\xff\x26\x2b\x18\x5e\xaa\x7c\xf1\x9e\x86\x88\x40\x5b\xe5\x75\x84\x07\x89\x9e\x72\xeb\x66\xad\x57\xca\x5c\x09\x1f\x68\xe5\x0b\xda\xa8\x43\x82\xfd\x1d\x6a\xd6\xb1\xc4\xe0\x78\x85\x26\x3c\xb3\x90\x8b\x27\xc7\x8a\x55\xa9\x5d\xa2\xc7\xb4\x14\xb0\xaa\xb3\xb9\xa8\x52\x6f\x05\x2b\xe7\x22\xe4\x4a\xa7\xd5\xc4\xec\x7e\x45\x65\x0e\xa1\xf4\x6a\xea\xeb\xb1\x52\x43\xbe\x71\x74\xa9\x26\x4a\x2f\x78\xb2\xc6\x0d\x4a\x3a\x67\x93\x45\x55\x2e\x32\xd5\xb9\x45\x1e\x93\x39\x33\x28\xa6\x55\x1f\xc5\x14\xc8\x2b\xaa\x34\x9f\x5b\x46\x43\xc5\xa5\x33\x35\xd6\xbe\x0a\x4b\x75\xa8\x17\xe8\x02\x97\x7a\x20\x99\x43\xf5\x00\xd2\x3a\x84\xbd\x9e\x20\xfb\x67\xa7\xf5\x2d\xc2\x02\xcc\x07\xdd\x03\x1d\x46\xe4\x7c\x45\x2d\x32\xd1\xe8\x74\xe6\xed\xd1\xb9\x6a\x5b\xdd\xb9\xbc\x0c\x2d\x79\x05\x0a\x77\xdd\xc9\xe3\xc2\xad\x12\xc7\x8a\xf1\x5a\x9c\x1e\xd3\xf2\xc4\x27\x82\xd9\x0e\x2b\x5e\x60\x03\x35\xfd\x06\xb1\xe9\xba\x49\xea\x6d\x49\xbd\xa6\xd2\x04\xcc\x82\x54\xf2\xb4\xe0\x35\x2f\xe7\x8c\xd7\x4f\x4f\xa3\x28\x4b\xca\x58\xef\x23\x0e\x33\x9d\xf2\xe9\xdc\xc4\xbe\x3b\x4c\x6f\x09\xe1\xda\x7c\x74\x0a\xc4\xca\x8d\x43\xd6\xc6\x00\x6b\xc9\x37\x60\xcd\x08\xdd\x9a\x15\xe3\xd5\x46\x05\x69\xa3\x29\xdf\x19\xb7\xb5\xaf\x41\x76\xc4\xbb\x3d\x47\x29\x12\x1f\xa8\x27\x7b\x5e\x32\x6e\x43\xd1\xcc\xb6\x39\x97\x4d\xac\x5c\xe2\x6b\x5c\x01\xe3\x92\xbb\xc6\x8c\x5d\x73\xdb\xe6\x8b\x4b\xd7\x92\x1c\x5b\x29\x4e\xe7\xdc\xc0\x0c\xea\xeb\x20\x2c\xda\xdb\x42\x8d\x5a\x46\x25\x2f\xf4\x42\x0b\xb4\xe9\xe6\xe7\xa4\xf3\x05\x30\x88\xcd\x0d\xfc\x00\xd7\xf6\xae\xb7\x4c\x44\x3b\xaf\x31\x12\x2f\x3e\x74\x78\x00\xf7\x93\xa4\xd7\xbd\x31\xa8\xaf\x55\x18\xd8\x3d\x43\xde\xed\xd1\xd4\xf9\x7f\xb8\xae\x2f\xb1\xeb\x4f\xfd\xe1\x7e\x42\x3f\xbd\x63\xb9\x9a\x33\x16\x37\x21\x63\xa6\x4d\x36\x8a\x00\xe3\x5b\x51\xc0\x1a\x80\xb5\x18\x7d\x04\x05\x01\x32\x94\x68\xf3\xd4\x9f\x20\x54\x5a\x8b\xef\x69\xc9\xe6\x3c\x17\x00\x14\xda\x55\xca\x73\x34\x05\xe5\xe9\xa9\xcd\x20\xf4\x0e\x82\xf1\x72\x04\x78\x72\x14\xa0\x8f\x73\xee\xc8\x79\x80\x7f\xb4\x63\xec\xa8\xc1\xba\x81\xbb\x1c\x30\x70\x30\x57\x87\x5c\x64\xc6\xe9\x90\xe6\xcc\x97\x51\xcf\x79\xce\xb0\x92\x6d\x4b\xcd\x4b\xcb\x39\x07\x8a\xf4\xca\x78\x76\x2a\xc0\x5c\xde\xd3\xed\x60\xe7\xb3\xae\x48\xea\xc8\x15\x27\x9e\x0a\x2e\xb9\x7d\xdc\x49\xa9\x2b\x80\x4c\xae\x36\x0c\x76\x43\x21\xb1\x40\x81\x4b\xbe\x79\x1d\xdc\x60\x90\x55\xe0\x13\x00\xb3\x83\x8e\xc1\x9e\xa6\x73\x9d\x6d\xe8\x96\xaf\x14\x2f\x18\xbf\xa2\xb6\xaa\xa0\x4c\x46\x51\x78\x69\x61\x65\x0a\xc6\x0b\xcf\xda\x6b\x72\xd8\x6b\x43\xde\x6b\x52\xf5\x6f\x5b\x1d\xcb\x72\x67\xe8\x7c\x4d\xaa\xfe\xed\x24\xa6\x49\xc3\x2b\xb7\xda\xad\x43\x0c\xb5\x05\xb7\x32\x23\x2b\xf3\x75\x5c\x70\x64\x43\x08\x3f\x59\x8b\xd7\x62\x7f\x3b\x71\xcb\xab\x8f\x97\x58\x2a\xbe\xb3\xeb\x44\xbc\x23\x8f\x49\x9c\x0e\x0c\x45\xb3\x73\xf1\xd3\x1c\x83\xbf\x2d\x2e\xa7\xa4\xa5\x51\xad\xb8\x3f\x32\xd3\x02\xa7\xdc\xcf\xf7\xdc\x14\xdf\xdb\x7b\x02\x09\xab\x21\x2e\xc0\x05\x2a\x96\xc2\xd3\xed\xcf\x42\x0f\x9e\x29\x44\xcb\xf5\x3c\x87\x4b\x01\xa3\x2e\x5c\xe7\xca\xb9\xe8\x5e\x02\xbe\x4d\x37\xc9\x51\x87\x28\xf4\xb2\x34\x03\xac\xfb\xd9\x07\x2e\x2f\x0e\xd4\xd6\x58\xd3\x72\x38\x44\xb5\x36\x36\x7d\xc5\x57\x18\xd7\xb7\xd4\x9b\xe5\x6b\x6b\x1d\xe6\x97\x1d\xe3\x32\x38\xe0\x78\xe8\x38\x4e\x56\x77\x5a\xa7\x22\xf8\xb9\xe0\x35\x5c\x62\x97\xb5\xad\x01\x80\x84\x89\xd9\xe5\x4c\x01\x8a\x15\x36\xd9\x96\x90\xba\x8c\x22\x9a\xb9\x0b\x31\xe5\x8d\x9e\xa1\x8e\xc8\x84\x87\x17\xe1\x12\xeb\x9f\x69\xdb\x86\xea\x8d\xb5\x4f\x19\x8f\xf9\x6a\x68\xd1\x1e\x4c\xf4\x8f\x1d\x1f\x73\xcf\x06\x03\xb5\x34\x9d\xd6\xb6\x59\x97\x5b\x05\xd8\x75\x19\x57\x4e\xa0\xcd\x79\xe3\xa0\xd1\x60\xf9\xb7\xce\x2f\x20\x59\xf4\xce\x98\xa0\x12\x0a\x56\x53\x5e\x09\x21\xe8\x65\x42\xb4\x32\x4a\x62\x82\x8d\x08\xcf\xe1\xef\x91\xd0\x9b\xf4\xd1\x3a\xc0\x10\x58\x6b\xa9\xb6\xa8\x4a\x95\x97\x5b\x39\xbb\x14\xa3\xe9\x7e\xa9\xe5\xd1\x3a\x8a\xd6\x60\x6e\xf1\x36\x87\x9a\xed\xf3\x15\xa5\x0b\x31\x40\x34\xc6\x60\x63\xd2\x4d\x5d\x32\xef\xf5\xbd\xe9\xb3\x83\x45\x11\x2d\x27\xd6\xe7\x45\xa4\xd7\xee\x37\xf7\x3f\x7f\x09\x7e\xff\x3a\xe7\xa6\xe7\x0b\xa8\x9b\x85\x5d\xd7\xc2\xad\xf0\x23\xc7\x9b\x5f\x3d\xc6\x3d\xdd\x0e\xd0\x3b\xc0\x73\xc9\x56\x14\x31\xbd\x46\x5c\xea\xd1\x34\x38\xbf\xf0\xfc\x11\x05\x1f\x7a\x9c\xe3\x43\xba\xb7\x68\x70\xce\xb7\x6d\x5b\x73\x75\x8c\xc7\xed\x3a\x0d\xb7\x67\x23\x51\x0c\x12\x4e\xac\x8a\x2a\x03\x90\x0d\x38\x2f\x59\xa1\x58\x0c\x07\xd2\xb5\x43\x98\x2f\x80\x6f\x12\x5a\xa1\x00\xee\x02\x77\x8b\x17\xc2\x95\xbc\x4d\x08\x89\xb7\x8c\x71\xff\x60\xb7\x4e\x10\xa5\x63\xdb\x35\x8a\xa8\x6f\x64\xe1\xbc\x06\x06\x87\x74\x90\xd1\x17\x90\x4e\xe7\x61\x97\x85\x77\x4e\xc3\x3b\xbf\x86\x77\x9e\xcc\x61\xa0\x2f\xc4\xe8\x94\x2f\x99\xfe\xf0\x75\x62\xdf\x9d\x97\x47\xeb\x28\xa2\x97\x62\x6d\x76\x48\x2c\x5e\x87\xcc\x4c\x56\x3a\xf0\x9d\x75\x6d\x28\xf6\x8c\xe7\x51\x44\xed\x03\x62\x74\xc9\xf8\x65\x14\x05\x1d\x3b\xd0\xae\x6e\x6c\x5e\xb6\xad\xe9\x4d\x1e\xe2\x91\x59\x21\xc4\x97\x01\x0d\x45\xcd\xf5\xec\x60\xa6\xf6\x2b\x45\x2f\x13\x3d\x4d\xe2\x29\xaf\xf9\x8a\x71\x28\x6f\xad\x3f\x47\xcf\xa1\x85\xb1\xae\x5c\x42\xf8\x91\x2c\x97\x2e\xc5\xfc\x15\x53\xc6\xf6\x73\x2f\x6f\x7b\x8b\x81\x4a\xba\xbb\x08\x2b\xa3\x25\x8b\xbb\x37\x40\xf9\xb3\x7e\xa7\xcd\x46\xca\xe5\x01\x22\x0a\xaa\x9c\x32\x8a\x86\xf8\xc8\x42\x85\x5a\xb2\x78\x67\x97\xe0\xb8\x6c\xdb\x51\x19\x45\xaa\x6d\xaf\xc0\xb9\x58\x7a\x95\x57\x5a\xa5\x1a\xef\xab\x28\x1a\x5d\x81\xfb\xa1\x0a\xa8\xbd\x57\x77\x93\x6a\xb5\x4a\x6a\xa7\x1e\x8b\x69\x1c\x9c\xa7\x99\x0a\xf8\xdb\x40\xb2\x61\x2f\x74\x5b\xa2\x5d\x44\x7f\x51\x13\x96\x12\x24\xa7\x3e\x79\x1e\x0f\x67\x71\xea\xbe\x3d\xdd\xab\x51\x1c\x47\x11\x60\x55\xd5\x6e\x6d\x31\xbf\x84\x61\xeb\x9a\x54\xc5\x52\xd4\x4e\x21\xe1\xfe\x67\xb8\x62\x68\x35\xab\x2a\x96\x2c\x8a\xe0\xaf\x37\x93\xe9\x12\xcc\x7b\x7a\xdc\x4a\x26\x9d\xed\xb5\xba\xde\xb1\x46\xaf\xb2\xa5\x7c\x57\x3d\x1c\x3d\x0e\x1a\x87\x71\xd5\x2e\x24\x03\x21\xe2\x0e\xc9\xf9\xd4\xb2\x36\xe8\xc1\xa6\x37\x98\xa0\xd9\x48\xea\xce\xdc\xd5\x9e\x4b\x13\xa4\x6e\xee\x3d\x74\x1e\x28\xfa\xd2\x5c\x22\x4f\x19\xb4\x28\x52\xf9\x76\x38\xc3\xad\x83\xd5\xd2\x20\xeb\x75\x87\x14\xcf\xd9\x8c\x56\x0e\xaa\x1f\xa0\xf7\x56\x79\x99\x37\xd7\x20\x89\x15\x68\x9d\x74\x34\x65\x6e\xec\x64\x13\xbc\x2f\x32\xae\x97\x2c\xe4\xfd\x83\x56\x0b\xd8\xf3\x32\x63\xf2\xc4\xa6\x35\xf7\x79\xc6\xfa\x7b\xa0\xce\x1c\x18\x72\x23\xd6\xd9\xad\x63\x29\x5e\x71\x45\x4b\x57\x9b\x61\x7a\x29\x8c\x49\x0f\x29\xa6\x94\xc1\xb7\xb3\x41\x14\x07\xcc\x58\x0f\x84\xaa\x63\x35\x46\x40\x41\xe3\xe2\x15\x3a\x8c\x54\xd0\xf6\xa0\xe2\x36\x10\x6b\xec\xec\xd2\xb8\x7d\x43\x5c\x33\xfd\x2f\x54\x3e\x8a\x6a\x00\x4d\x63\x9e\x58\x16\x62\x90\xb3\xc3\x8c\x0b\xa7\x5f\xf8\x87\x70\x03\xe8\x82\xd2\x2a\xf0\x61\xd3\x8f\x68\x6d\xd6\x84\xec\x38\x0b\x6a\x14\xc1\x2d\xa8\xeb\x08\xc8\x37\x29\x24\xe8\xf1\x85\xdd\x5a\x32\xae\xb4\xa0\xcf\x2d\xc4\x65\xc5\x4f\x19\x9b\x8d\x54\x14\x95\x5a\xbf\x18\xa2\x1d\xc3\xce\x1f\x30\xe9\xd9\xf6\xa5\x8e\xce\xeb\xa3\x8d\xca\xcb\xb0\xb1\x78\x2d\xca\xd4\x36\x2c\x99\x03\xe3\x4f\xb7\x9d\xe7\xdd\x86\xae\x93\xda\x6f\x94\x11\xcb\xd8\x0c\xcb\xd1\x94\xf7\xe8\xdb\x74\xf7\x02\x17\x00\x36\x2c\xfe\x0d\x42\x80\xf5\x32\xa4\x7c\xab\x2a\x6c\x55\x85\xad\x6a\x82\x8e\x74\x63\x2a\xd3\x98\x18\x15\x02\xe7\x9d\x41\x63\xea\x52\x5c\x43\x2a\x68\x48\x34\xb7\x4d\x67\xea\x69\x06\x51\x35\x75\xaa\xe6\x51\xa4\xff\x35\x95\xed\x5c\x04\xf2\xc9\x8e\x78\xfb\x51\x9e\x73\x11\xcf\xca\x8d\x6a\xc9\x51\x79\xe4\xa8\x56\x1e\x9c\x98\x5b\x2e\xbb\x55\x99\xaa\xf9\xcc\xfc\x0d\xd7\x9f\x8e\xc7\x10\x1a\xaa\xdb\x76\x90\xb3\xa6\x1c\x76\xf9\xc6\x49\x6e\x85\xd9\x46\x51\x05\x8d\x89\x25\x77\xe0\x4f\x9a\x22\x5f\xca\x17\xd5\x6d\x19\x6f\x94\xd1\x79\x19\x87\xc4\x9f\x36\x90\x04\x9f\x60\x92\xde\x21\x9f\x8e\x4e\x36\x5f\xca\xb8\x96\xbf\xdf\x95\xde\x49\x09\xcb\xd8\x43\xfa\xeb\xad\x0a\x6e\x40\x49\x78\xc3\x14\xe4\xef\x99\xe2\xf6\x9f\x10\x94\x71\x28\xdd\xed\x77\x2a\x2b\xaa\xf1\x03\x71\x4c\x8a\x74\xee\x8d\xbb\x7d\xe9\x0b\xa1\x56\x70\x92\x8d\x99\x91\xc2\x28\x34\xe1\xce\xd4\xd3\x32\x04\x28\xa5\x52\x40\xe4\x01\x35\x21\x08\x38\x81\x4b\x37\xbe\x8e\x8f\xf9\x29\x9b\x95\x6e\xbf\x62\x8e\x29\xaa\x0d\x05\xdb\xb0\x31\x14\x07\x1b\x70\xd1\x3d\xe6\xc0\x7a\x58\xfd\x84\x9b\xc7\xb3\x1a\xd0\xaa\x3a\x36\x6b\x71\xfa\x59\x70\xbb\xb3\x23\x53\x6d\x4b\x33\x10\x8f\x85\xa2\xcc\x3e\x08\xe6\x8a\x4e\x36\x74\x0c\xe7\xc1\xc2\x2f\x76\x4d\x51\xdd\xc6\x5f\x4c\xa7\x7c\x95\x35\x2a\x7e\x32\x9d\x7a\xcb\xff\xe7\xd3\xa9\x59\x7c\x97\x52\x2b\xc9\x0f\x04\x90\xe9\xe2\x00\x96\xdc\x29\x1c\x72\xde\xb6\x01\xad\x27\x0f\x44\x7d\x78\xf8\xaf\xfc\x5a\xda\x31\xb6\x2b\x2e\xd9\xac\x3e\xa8\x7f\x89\xee\x42\x36\x57\x65\xc2\x08\x0f\xce\x36\x1f\x62\xe6\x18\x22\xed\x40\xd8\x16\xf2\x07\xa4\x1f\x78\xc8\x47\x18\x9b\x19\x40\x0d\x62\x29\x9d\x88\xe5\xdf\x78\x5d\x0a\x82\x91\x01\x80\xc5\xc8\xcf\x26\xd5\x46\x21\x38\xbb\x5c\x0a\x65\xf0\x61\xe4\x92\xd3\x87\x2b\xc8\xf0\x59\x41\x14\xb1\x68\x3b\x86\x36\x84\x9f\x4d\xe0\xc7\x3f\xed\x7d\xe1\xde\x64\x7d\xc1\xaf\x15\xbf\x54\xc2\xc0\x87\x67\x4a\xd5\xdf\x42\x40\xf0\xac\xa3\x3c\xe9\xf4\x8f\x9e\xe5\xdf\xc2\xa3\x0f\x1e\x95\x73\x8f\x1b\xf2\x67\x68\x33\xfd\x53\x0f\x92\xd7\x1e\xd4\xac\x7b\x60\xe0\xb7\xc5\x7a\x39\xff\x6c\x04\xc4\x12\xff\x85\x7f\x9e\xe8\x3f\xc6\xa4\x17\x50\x34\x89\x2e\xdb\x93\x43\x1c\x48\x6e\xc1\x7e\x6a\x5d\x04\xa8\x61\xa9\xe8\x84\xb4\xb7\x2d\xd5\xfa\x1d\x34\x23\x9e\x5a\xf7\x02\x03\xe1\xc0\x3d\x40\x6a\xd7\xb2\xda\xfa\x82\x25\xd7\x2a\x76\x54\x19\x21\x95\x3b\x48\x76\x51\x26\x90\xd6\x69\x15\xa0\x81\xaf\xbc\x17\x5b\x15\xfa\xf3\xd5\xa2\x72\x5e\x6c\x8a\xb1\xa4\x8e\xa9\xec\x12\xc4\x28\x5e\x8e\x09\x61\xfa\x73\x2a\xef\x5d\x56\xd9\x6d\x35\x16\x61\xb9\x0d\x74\x01\xc6\x50\x50\x0b\x43\x26\x90\xd9\x4a\xb0\xc4\x30\xb0\x83\x02\x6c\x3f\x3f\x46\x80\xfb\x5d\x9f\xcf\x1f\xfd\x82\xc3\xb1\x19\x45\x66\xc4\x22\xe1\x2e\x60\xea\xd8\xd1\x6d\xd6\x41\x33\x6e\x67\x9e\x3f\x62\x80\x2e\xc7\xb0\x10\x9b\xbc\x10\x93\x06\xce\xac\x83\xe3\xaf\x7f\xd0\x06\x11\x6d\xce\x20\xa8\xd5\xbf\x03\xe6\x75\x8c\xde\x14\x55\x5a\x03\x8f\xd0\x21\x20\x4e\x09\xe3\xf3\xfa\xe0\xb8\x36\x24\x06\x07\x9d\x5b\x25\xbd\x9e\x2c\x59\xdc\xfb\xa6\x12\x4d\x9a\x0e\x52\xef\x70\xe4\x20\xc9\xa9\xa9\xf3\xc9\xf9\xed\xf8\xe4\x8a\x0d\x6b\x11\x97\xca\x78\x14\xba\x7e\x9b\x41\x52\x77\x3b\xdb\x61\xc0\xec\x8d\x5d\x17\x92\xa0\xf5\x50\x5d\x5e\x36\xe7\xf0\x2f\x98\xc7\x8c\x73\xa7\x29\x25\xc9\x60\xa8\x98\xfb\x39\xe3\x95\x8b\x4d\x5c\x9b\x23\x5e\x84\x7f\x42\xf1\xd6\x5a\x0c\x9b\x16\x71\xec\x80\xea\xee\xcc\x64\xcc\x5a\x7d\x47\x27\xf9\x13\xdf\xab\x20\x34\x89\xca\x10\x50\x7f\xce\x4c\x74\xe1\x11\x09\x8e\x55\xef\x55\x07\x15\x23\x9c\xd6\xc6\x63\x25\x64\x56\x2a\xb2\x06\x80\xcb\x49\xe0\xa5\x7d\x13\x96\xd0\x3d\xff\x90\x2c\x91\xf1\x60\xf8\x70\xb7\x66\x5d\xe2\xc2\xcd\x21\x6a\x71\x5f\xa4\xa2\xdb\xc0\xc7\x45\x6a\x0f\xfc\xf8\x0f\x44\x6a\x10\xe1\x97\x62\xf9\x2f\xf3\x3b\x5c\x76\xe7\x07\xa2\xf5\xa0\x86\xff\x99\x68\x3d\x7a\x40\x50\xea\x45\xc7\xd6\x40\x0f\x4d\x05\xe8\x18\x81\xc3\xcf\xbc\x23\x05\x3f\x5d\xca\xa1\xdf\xe1\x27\x4a\x34\x9d\x19\x58\x95\x37\x56\x62\x65\x97\xe8\xee\x3d\xec\xfa\xd2\x93\x7c\x44\x65\x97\xe0\x6d\x1c\x84\xce\x27\xe0\x8b\xf8\x5d\xa9\x15\x92\xd3\x29\x8b\xd7\xca\x42\x3a\x59\x00\x28\xd6\xb6\x67\x87\x89\x80\x3c\x57\xcb\x55\x32\x8d\x8f\x4f\xb5\xd0\x32\xad\x13\xef\x56\x55\x1d\x93\x6b\xb5\x2e\x5e\x56\x35\xe1\x30\x3e\x63\x1c\xa6\xfa\x41\xa2\xbb\xad\xa3\x37\xc0\x2a\x13\x38\x91\x58\x75\xe2\x81\x4f\x92\x61\xb4\x76\x18\xdd\xdb\xc1\x2e\x08\x81\x0b\x6c\x89\xd0\x52\x1c\xb5\xc3\xbe\x7b\xca\x40\xd9\x2a\x8a\xa8\xea\x3d\xfc\xa9\x6f\xe9\x6d\xa0\x4c\x2f\x11\x4e\x6a\x99\x2d\x5f\x97\xc5\x3d\xe1\x64\x9d\xdd\xbd\x82\x09\x42\x38\x59\xc8\xa2\x30\x61\x58\xe6\xea\x8d\x71\x86\xe0\xa4\xae\x6e\xdf\x6e\xb2\x52\xa7\x57\x85\xf9\xb5\x6d\xe4\x59\xb6\x21\x9c\xac\xea\x6c\x2d\xbf\x32\xde\xaf\x36\x78\xe3\xeb\x25\x82\x66\x77\x36\x69\x5a\x45\x71\x23\x18\x20\x40\x3a\x6b\x3d\xec\x3b\x0f\xbc\x22\xb3\xe5\xf2\x39\x74\xe0\x80\xc7\x5b\x88\x96\x86\xee\x8f\x57\xd4\xfb\x46\x0c\x4d\x69\xbd\xf3\x31\x34\xa2\xb6\x60\x2a\x83\xad\xb1\xe2\xf7\x66\x87\xce\x2c\x22\x16\x55\x02\x84\x99\xc3\x6e\x37\x6b\x1a\x08\x85\x85\x25\xe4\xab\xc4\xbd\xa2\x25\x38\x34\x68\xdd\x23\x38\x5d\x20\x47\x64\x7c\xa5\xd5\xe8\xb1\x96\xb1\x86\x2d\x61\x3a\xcb\x85\x4a\x33\x78\xba\xf6\xfe\xf7\x47\x64\x9c\x43\x36\x08\xf9\xaf\xc7\x02\xaf\x66\x95\x9e\x8a\x8d\xb8\x02\x92\x5d\xe3\xde\x76\x20\x81\x79\xe3\x50\x9b\x10\x8e\xc2\xc4\xab\xfe\x8f\xb4\x5e\x50\xf6\x1f\x35\xe0\xe8\x00\x3f\xa1\xb3\xc9\xd4\x82\xc1\x7e\x01\x21\xff\x77\x9a\x1c\xca\x1b\x6a\xf7\x2f\x8f\x4f\x67\xac\x16\xb5\x03\x82\x72\xb7\xf8\xff\x41\x47\xe0\x2e\xbc\xdf\x11\xc1\xe9\xad\x59\x01\x79\x1d\xfa\x24\x97\x6d\xdb\x5f\x38\xad\x15\xf0\xd0\x64\xa1\xa2\xa8\x4e\x90\xe9\x3f\x18\xd9\xc6\x60\xd1\xe9\x2c\x16\xc3\xd1\xee\x50\xff\x96\xbe\x7f\x83\x2a\x77\xfa\xb7\x74\xfd\x0b\xd0\xd8\xba\x8f\x1f\xa0\xf1\xc5\x51\x86\x1e\x12\xf9\x8a\xd6\x08\x40\x28\xa6\x3c\x17\xe6\x25\x3c\xc3\x6e\x9e\x29\x91\xa5\x15\x76\xeb\xe4\x3a\x6b\xf0\xad\x8a\x25\x79\xa7\xe6\x8a\xc5\xb9\xff\x36\x65\x4c\x8a\x1e\xcd\x1d\xc2\x03\xb0\x5d\x0c\xb4\x1f\x55\xc2\x8d\xc6\x28\x0a\x98\xcf\xc8\xc5\x85\x5b\x0e\x2e\x2e\x88\x43\xf9\x6e\x3a\x8a\xce\x41\x92\xeb\x60\x65\x0c\xc1\x32\x21\x24\x0e\x4d\xc9\xdd\x72\x41\x27\x62\x06\xb3\xc5\x7c\xd7\xf0\x4c\x14\x53\x63\x3c\xd3\xe3\x4d\xea\xf1\x66\x87\x7b\x6d\x87\x7b\x7f\x90\x53\x33\xca\x61\x12\xe0\x48\x77\x03\x5a\x01\x1f\xa8\xa5\x6a\x9c\x39\x72\x46\x83\x35\xfa\x4c\x89\x93\xf3\xfa\xe4\xaa\xbb\x69\xbd\xc9\x8a\x87\xc4\x84\xc5\x8f\x71\x36\xf1\xde\x8c\x4e\x68\x2d\xf4\xa8\x1a\x34\x80\x1a\x2d\xa8\x9a\x1d\x60\x1c\x45\x91\x3d\x44\xaf\x44\x9d\x74\x87\x99\x1d\x88\x37\x59\x41\x19\x8b\x25\x4b\x2a\x41\x88\x3b\xb3\xf1\x23\xbf\x4a\xaa\xb1\xbe\xd3\x9d\x2b\x15\x3a\xd9\xa0\xb3\x48\x35\x08\x7b\x65\x2c\x80\xba\x0b\xe5\x98\x10\x38\x49\x03\x2d\xeb\x26\x2b\x02\x1f\x6a\x43\xb5\xd3\x4f\x1e\x06\xa7\x04\xbf\x1c\xa3\x76\xa9\x10\x09\xda\x8f\xbd\x8a\x13\xd8\x6c\x41\x84\x15\x14\x85\x7b\xaf\x0a\xcf\xdc\xe3\x2a\xe9\x56\xa2\x1a\xa8\x41\xf5\xb1\xd7\x5f\x1d\xbe\x9e\x96\x02\x3d\xc8\xfd\xcb\x59\x52\x1e\x2a\xe1\xb4\x14\x86\x37\x90\x25\x0e\x57\x86\x3e\x03\x7e\x7e\xb3\x99\x2d\x75\x7b\x95\x96\x5c\xae\xa3\x00\xdb\xea\xc5\x96\x26\xfb\xd3\x54\x42\x53\xa1\x10\x8c\x7b\x04\xfe\xca\x57\x8a\x1a\x3c\x32\x09\x41\x63\xa8\xdf\x3c\x50\xaa\x19\xa8\x96\x5b\xb9\x01\x8d\xbb\xab\x3a\x65\xc2\xd8\xa1\x8e\xcd\x01\xb5\x81\x7d\x6d\x44\x06\x46\x03\x70\x95\x13\x59\x92\x8f\x4f\x63\xe7\x86\x89\xe1\x13\xf9\xd3\x69\xb2\x88\xb3\x24\x07\x47\xd2\x05\x38\xb8\xe8\x85\x8a\xc2\xde\xd6\x31\xc5\x68\x55\xb2\x06\x4a\xe4\x28\x1a\x95\x8e\x79\x26\x8a\xe8\xa8\x0c\x35\x35\x7b\xa3\x6d\x47\x5f\xd3\xf0\x0e\x27\x96\x26\x9a\x30\x0b\x65\x77\x4b\x4b\x33\x0d\x78\xe6\x96\xce\x99\xb1\x65\x2a\xb7\xd4\x34\x07\x81\x57\x07\x54\xf9\x61\xe3\xe8\x99\xf1\x5e\xda\x30\x91\xd0\xf1\x34\x3b\x3e\x9e\x31\x0a\x4e\xa7\x59\xf0\x65\xc2\xe3\x12\xf9\x91\x68\x0a\x44\xc2\x7c\xc6\x73\x90\x3b\x70\x22\x35\x9a\xfa\x1e\x05\x24\xec\x4e\x5f\x88\xe3\x53\xc0\x58\xe8\x28\xa9\xc6\x06\xe7\x8d\x7e\x7d\xe5\xb1\x33\x03\xe7\x87\x26\x03\x68\xb0\x83\x08\x18\xb7\x8d\xb5\xc8\xb0\xc1\x87\x50\x69\x9b\x16\x44\xe6\x7e\xef\xed\x8c\xb0\x29\xe8\xbe\x11\xe0\x60\x1e\x94\x24\x07\x08\xc3\x66\x60\x27\xa4\x2a\x49\x6c\xcd\x88\x10\xf7\x73\x36\x31\x48\xee\x82\x54\xa5\x05\x75\xcf\xcb\xa3\x12\xc4\xf3\x85\xd9\xc9\x9b\x1b\xf0\xa7\xb5\x58\xef\x97\xc5\xb6\x66\x8f\x4e\xf8\x6d\xb7\x26\x43\x4c\x08\x33\x37\x35\x0d\xb8\x21\xdf\x1d\xb2\xbe\x40\x84\x9c\x23\xef\xeb\x52\xf7\x5d\x8a\xb4\x6e\xdb\x6c\xce\xd7\x16\x42\x56\xef\xe0\x00\xc1\xd8\x40\x1e\xc7\x92\x9f\x05\xf7\x1c\x68\x37\x64\xf0\x5c\x5a\x9e\x78\x2f\x4e\x91\x7a\x4c\x2c\xc5\x42\x00\xe9\x6e\xc6\x3f\xeb\xc0\x82\xe2\xa6\x38\xbc\x1e\x5d\x98\xcd\xdf\x7a\x7c\x40\x89\xc9\xc0\xdb\xc2\x29\x72\x13\x50\xe1\xa2\x88\x9e\x89\x75\xf0\x56\xbe\x16\x67\x13\x74\x59\xd0\x8d\x8f\xe4\x7f\x8c\x6f\x45\xf0\x68\x8c\x5a\xb7\xee\xac\xf1\x9a\x53\x29\x3e\xc2\xe3\xb3\xe6\x03\xce\x0b\x51\xa4\x35\x56\x47\x40\x2b\xaa\xe4\x49\xfc\x19\x0f\x9a\x41\x9c\x79\x22\x49\x2e\x03\xae\x31\x11\x64\x4a\x06\xe9\x03\xcf\xfe\x90\x3e\x10\x0d\x48\x96\x9a\xc6\x1c\x88\x70\xcb\x95\x82\x58\xf4\x48\x80\x52\xb3\x00\x80\x2e\x95\xf3\xb8\x23\x0a\x38\xb8\x9f\xac\x0e\x38\xe7\xd6\x08\x1e\x57\xb5\xed\x68\x65\x9b\xdf\x90\xc3\xb9\x6b\x07\xbd\xa5\x8c\xf0\x1a\x55\x40\x01\x68\x39\x8e\xa2\x68\x74\x4f\x6b\x47\xf1\xb8\xea\x70\x2a\xb6\xed\x9a\xdb\x8e\x2e\xc6\x6b\xa0\x5b\x13\x21\x30\x1a\x9b\x35\xb3\x5e\xca\x25\x0a\xc1\x06\xb0\x56\x67\x0b\x40\xe6\xe8\x22\x71\xb5\x6d\xc6\xa2\xc8\xe4\x5b\x84\xb8\x5c\x6d\xbb\x30\x45\xfd\x9c\x97\xcb\xea\xb6\x6d\x4b\xb6\x47\x7c\xd4\xe9\x8c\x36\xe2\x32\xcd\x0d\xb5\x9c\x7c\x90\xa9\x6e\x29\x1a\x7b\x82\x90\x7f\x79\x9a\x14\xf1\xca\xf1\x42\xea\xcf\xa1\x1b\xcb\xf1\x77\x40\xf0\x87\x4f\xcd\x2d\xa3\x51\x63\x59\x07\xc1\x0b\x61\x63\x1a\x12\xe8\x67\xe8\x46\x6c\xa3\xa8\x49\xb7\x73\x7f\x27\x8a\x1e\xd1\x06\x23\x47\x4d\x7f\x77\x1e\x71\xd4\x3b\x96\xdd\xa8\x4f\xd0\xe2\xe1\x71\xb1\xf2\x6b\xdd\xaf\x72\x80\xf5\x85\xb2\xb6\x5d\x39\xaf\x15\xe3\x54\xe0\x13\xcc\x4b\x2f\x27\x1b\x38\x88\x53\xac\x6d\x47\x8f\x68\xcd\xda\x76\x1b\x45\x57\xb4\x4e\xd7\xd0\x80\xf7\x80\xe0\x4b\xe9\x42\xd4\xf8\x19\x54\xff\x85\x31\xe8\x79\x46\xdd\x94\x16\x6b\xfe\x50\x8b\x47\xd1\xf2\x90\x1b\x75\xcd\x6f\x15\xe3\xfa\x5d\xc0\x84\xfc\xf0\x93\x43\x94\x4b\xf8\xf0\x61\x1d\xcc\xfc\x59\xd8\xba\x2e\x00\xfd\xd1\xb1\xe3\x35\x86\xf5\xe5\x01\xcf\x0e\x27\x78\x03\xa1\xc1\x4b\xbe\x33\x22\xb3\x43\xd2\x33\xdd\xb3\x59\x9f\x80\xb9\x46\xe8\x41\xc5\x0e\xd0\x62\x87\x04\xf8\x1f\x9e\x0b\x75\x0b\xd7\x35\x55\x0e\xab\xd3\xa4\x7e\x7b\x40\xb5\xdd\x75\x2e\xd6\xca\x7f\x10\x6e\xde\xe7\x26\x36\x3e\x3b\xa3\x29\x43\xe3\x9a\x59\xba\x30\x0e\xf3\x3f\x21\x30\xc1\x37\x77\xcf\x70\x8d\x40\x32\x4d\x47\x95\x93\x6e\xbc\x4b\xbc\x89\x2b\x5f\x8f\xe5\x7b\x80\xff\x04\xfb\x0a\xc3\x0b\xbb\x32\x03\x15\x75\xef\xeb\xa7\x25\xda\xac\x6a\xdb\xfa\x70\xf4\x49\xfc\x6c\x1e\xe6\xe5\xb4\x02\x80\x93\x53\xc0\xe3\x45\x8a\xd3\xff\xfc\xc5\xc7\xa7\xb3\x2a\xe9\x14\x5f\xb1\x98\xd6\x83\xc3\xd9\xd7\xc6\xb8\x0f\x82\x2c\xde\xbb\xd3\x84\x0f\x4a\x94\x93\xa2\x5a\x60\x84\xc8\xeb\xf0\x44\x9e\xbf\xd3\xbb\xc2\xe4\x64\x76\x3b\x01\x83\xec\x2f\x67\xaf\x0e\x3d\x94\xc0\x9e\x23\xdb\x76\xc0\x0f\x89\x05\xca\x10\x20\x77\x2a\x01\xc3\xbf\x9c\xbc\x78\x7d\xf6\x46\x97\x58\x33\x2c\xf9\x65\x5d\xad\xdf\xc2\xf3\xa0\x4f\xc8\x3b\x75\x72\xb7\x2e\x08\x33\xb0\x9c\x80\xaf\x6f\xf6\x17\xde\xba\x3a\x82\x0d\x8c\x39\xca\x6d\xbe\xba\x7f\x97\x5d\xe9\xfd\x0f\x25\x50\x64\x2d\xeb\xba\xaa\x03\x7f\xe6\xdb\x09\xa4\x50\xf2\x5d\x79\x93\x15\xf9\xf2\xe8\x97\xb3\x57\xb1\xde\x5b\x33\xae\x30\x82\xee\x4e\x7f\x6e\x7a\x3e\x7f\x74\xc2\x7f\x80\xfd\x70\x72\x5e\x9e\x5c\xf1\x57\x46\xf9\x6a\xb6\x97\xeb\x5c\x99\x03\x96\x36\x5f\x67\x57\xb2\xad\x65\x23\x55\xbb\xca\x0b\x09\x27\x2e\x5f\x7f\xf4\x68\xe6\xbd\xbc\xbf\x92\x25\x0b\x8f\x61\xde\xaa\x9e\x6f\xdb\x60\xc4\xb6\x99\x32\xdd\x13\xfc\x8a\xed\xca\xb6\xb5\xf4\xd4\x92\x25\xba\xaf\x2b\x16\xeb\x22\xc7\x24\x25\xe3\x01\xf6\x13\x67\xc6\xaf\x12\x15\x13\xad\x2d\xcc\x09\xaf\x1c\xda\xbf\xe5\xb3\x2f\xdb\xd6\x3e\x3b\x12\xe2\x02\x54\x66\x43\x1e\xd7\xf1\xd9\x52\xcc\xbd\xac\x82\xa2\x54\x5a\xcd\xb1\x34\x18\x32\xd9\x5a\x0c\x9f\x15\x02\xc0\xe7\xd0\xf4\x06\xa6\x48\x45\x59\xac\x66\x75\x6a\xfd\x9b\xe6\x42\x96\x8b\x6a\x29\x7f\xfa\xf1\xbb\xe7\xd5\x7a\x53\x95\x48\x9c\x38\x26\x82\x8c\x07\xee\x84\xbb\x52\xb6\x07\x19\x85\xfb\x7a\x7b\x52\x4d\x0e\x1b\x19\x80\xce\x26\xbf\xfd\xbe\x95\xf5\xbd\x41\x59\x7f\x53\x64\x79\xe9\x1c\x0c\x6d\x1f\x74\xc1\x2e\x2a\xdc\xae\x6b\x55\x8d\xfb\x8d\xbb\x6f\xcb\x20\x0e\xe8\xad\xa2\x25\x87\xd8\x1f\xdd\x75\xee\x28\xd0\x68\x71\x11\x61\x3d\x6f\xcb\x46\xd6\x79\x56\x0c\xc3\xd1\x99\xc6\xa5\xc6\x1c\x65\x32\xe2\x97\x20\xdc\x46\x98\x34\x50\x80\x1a\x02\x18\x46\x1f\x0e\x73\x46\x8f\xc6\x2b\x69\x26\x97\xdf\x8b\xcb\x24\xd4\x0d\x8d\x39\x71\x0f\xe4\x0f\xe0\xf8\x79\x58\xa0\x33\x99\x74\xa2\xce\x75\x93\xe9\x86\x36\x36\x9d\xbc\xa1\x24\xb6\x7b\x60\x60\x81\x31\xe3\xba\x63\x59\xd1\x9a\xc3\x2b\xe5\xf1\x84\xf1\xae\xd9\xc4\xb5\xed\xc8\x51\x7f\x80\xe1\xa4\xf7\x81\xa1\x43\x58\x68\x49\xea\x52\x7e\xa1\xb3\x40\xcf\x74\x54\xb2\x04\xcd\x46\xe5\x90\xd9\x68\xa7\xbf\x25\x56\x38\x0a\x90\x0f\xd4\xd3\x06\xfc\xa0\x38\x39\xaf\xcf\x4b\x02\x3e\x33\xf1\x40\xde\xf2\x81\xbc\x88\x55\x6b\x0d\x74\xcf\x95\x38\xf9\xcb\x93\xe9\xc9\x15\x7f\xaf\xc4\xc9\xff\x33\x79\xfc\xe8\x84\xff\xae\xc4\x09\x4d\x93\x68\xce\x2e\x44\xfa\xef\x68\xfe\xf8\x84\xff\x0c\x02\x68\xf2\x38\x61\x71\x7a\x74\xae\xe6\x8f\x69\xfa\x6f\x5d\xe4\xfc\x31\x7b\x74\x72\xb5\xe6\x2f\x8c\x80\xfa\xe6\xeb\x77\xed\xb7\x5f\x3f\x7b\xa1\xf7\x8d\x5f\xe9\xb4\xf3\x93\xf3\x93\x13\xfe\x46\x89\xdd\x9e\xff\x02\xff\xfe\xa6\x04\x79\x7c\x42\x6c\x74\x2a\x79\x4c\x18\xff\x71\xc0\x91\x27\x0b\xf1\x67\xbf\x0b\x0f\x79\xbb\x81\x85\x87\x0b\x84\x72\x8e\xaa\xba\xf0\x99\x8d\x91\x9d\xf2\xbc\x7f\x72\xde\x39\x05\xc6\x73\x89\xd2\xd0\x02\xd7\x22\x37\x96\x62\x32\xd6\x92\xae\x4e\xa7\xf3\x84\xd6\xa2\x76\x10\x2d\x6d\x4b\x1e\x13\x8e\x31\x74\x12\xe2\x46\xd2\x39\x73\x0e\xeb\x25\x63\x71\xff\x1e\x6c\x0d\xca\x90\x88\xe6\xdb\xbe\x9c\x46\xbc\x10\x29\x84\xf8\x45\xf9\xcf\xcf\x68\x83\xf7\x17\x0e\xfd\x23\x6d\xe6\xe8\x90\x89\xe2\x23\x6d\x30\xc4\x29\x1c\x97\xe6\x99\x42\x34\xc6\x79\xf9\x41\xd7\xde\xa2\x6d\xf3\xb6\xad\xd2\x62\x9e\xe4\xc9\x88\x2e\x44\xc1\x8c\xdd\x2d\xa6\x0a\x48\xa7\xf5\x46\xc3\x7b\xe3\x17\x8c\x67\xfa\x9f\xd1\x29\x18\x19\x16\x76\xf5\xcc\xc2\xdc\xe9\x74\xae\xb5\xf4\x0a\x62\xba\xa2\x28\x83\xae\xf6\x9f\xfe\x52\xf5\x22\x1c\xc5\xed\x24\xfb\x2d\xbb\x7b\x2b\x95\xca\xcb\xab\x66\xb2\x2a\x32\x65\x42\x51\x1d\xff\x78\x89\xcb\x83\xb7\x76\xa6\xe5\x5c\xeb\xfb\x55\x5a\xea\x9d\x73\xdd\xb6\xb4\x16\xbb\x3d\x63\x69\x39\x47\x66\x65\x27\x11\x03\xbe\xcd\xd1\x14\x98\x65\xb8\xdc\xff\xa8\xe0\x60\x57\x7c\xc0\xbf\xa1\xfb\xd2\x42\xe5\x37\x32\x9e\xf2\x22\x6b\xd4\x59\xb5\xcc\x57\xb9\x5c\x42\x5c\xad\xca\x20\xbe\x36\xac\x6b\xbc\xdb\xd6\x45\x6c\x0b\x01\xdd\x9b\x7c\xf3\xf5\x3b\xc2\xf3\xe6\x55\xb5\xc8\x8a\x18\xfd\x25\x2e\xab\xad\x6a\xb3\xcd\x46\xff\xff\x71\xa3\xaa\x5a\x2f\xf5\x93\xf1\x31\xbc\xb3\xc9\xab\x12\x56\x7c\xbd\xf8\xb7\xb7\xf9\x12\x28\x43\x1f\x9d\xa0\xe8\xf9\x60\x82\xf4\x17\x55\xc1\x38\xf2\xbe\x00\x8b\x61\x5d\x69\x5d\x0d\xc8\x2d\x46\x53\x9e\x35\xf7\xe5\xc2\x50\x0b\x2b\x59\x2a\x60\xa0\x23\x7a\xeb\x94\xa3\x22\x76\x72\x77\x7c\x7b\x7b\x7b\xbc\xaa\xea\xf5\xf1\xb6\x2e\x70\x95\x5b\xce\x8e\x16\xd7\x5a\xb7\x51\xe2\xa7\x77\x2f\x8f\xff\x8b\x70\xad\x01\x6e\x94\x09\x03\xfc\x4d\x21\xd5\x03\xea\x4f\x1b\xbd\x7c\x11\x04\x86\xc7\x14\xfd\x93\xf0\x3b\x7d\xdd\x79\xd3\xba\xe0\x47\x4e\xe5\xe2\xbf\x35\x80\xdb\x19\x64\xd0\x29\x26\xc7\x6f\xd9\x4d\x66\x28\x3b\xf6\xb6\xee\x4d\xbc\xd3\x65\x9e\x9c\x5f\xde\xad\x8b\xf3\xcb\x13\x7c\xe5\xc9\xf9\xa5\xfe\x7b\x82\xe5\x9d\x9c\x5f\xea\xbf\xe7\x97\x27\x7b\x5e\xcb\x66\x53\x95\x8d\x7c\x99\xcb\x62\x69\x1e\x26\x36\xf1\x97\xb3\x57\xc4\x7c\x85\x4d\x7a\x27\xef\x94\xad\x96\x4d\xfb\xfb\xdb\xd7\x3f\x60\x0d\x6e\x64\xad\x4c\x20\x24\x54\x91\xc4\xa8\x47\xa2\x16\x79\x04\xdf\xac\x1b\x1a\x2f\x75\x29\x24\xd6\x4f\xa3\xde\x69\x92\xf5\x87\xc7\x5e\xc9\xdd\xf3\x60\x48\xe3\x90\xb1\x5d\x75\xa7\xf4\xf6\xcc\x0d\xaa\xed\x03\x0e\x28\x2a\x79\xa9\x28\x4c\x9c\xee\x5c\xd1\x1b\xe2\xf8\xa5\xa2\xdd\x54\x60\xe9\xd0\x09\x9e\x8a\xe6\x3b\x45\xdf\x28\x06\x89\xef\xea\xac\x6c\x36\x55\xad\x74\xe2\x2f\x26\xb1\xf7\xda\x41\xdb\x13\xed\x04\x00\xcc\x7a\x28\xc3\xce\xa4\x77\xed\xe7\xf3\x76\x03\x61\xeb\x42\x81\x45\x82\x5f\x8a\xeb\x89\xf9\xea\xb6\xbd\x46\x93\x1f\x5e\x46\x11\xbd\x0c\x70\x3f\x2e\x8d\xe6\xc4\x92\x5b\x7a\xc9\x62\x6b\x5b\x3c\xeb\x40\x0a\xf0\x2b\x71\x3b\x79\x9e\x15\xc5\x65\xb6\x78\xdf\x50\x52\x95\x0b\x79\xb4\x96\xeb\xaa\xbe\x27\x8c\xdf\x8b\xeb\x49\xa3\x32\xb5\x6d\x9e\x03\xa9\xfb\x6e\xcf\x6f\xb4\x8c\x7d\xa6\xff\xb9\x10\x04\x69\x4f\xe5\x92\xf0\x0f\x62\x57\xcb\x6c\x79\xff\x56\xe9\xdd\x36\x10\x8c\xff\x68\x86\xc5\xb7\x32\x5b\x0e\x11\x58\xcf\x10\x6c\x5b\xef\x54\x90\xed\xa5\x11\xbb\xfd\x4c\x89\x9f\x15\x86\xbe\xe6\x6c\xc6\x9a\x54\x1d\xb0\x10\x00\xc9\xbb\xa0\x0f\xde\xea\xc0\x37\xa8\xf4\xc9\x9c\xcd\x94\x68\x52\x39\x90\x75\xdf\xd1\x32\x14\x6a\x19\xca\x68\x7f\xfc\x48\xab\x7f\x57\x52\x3d\x2b\x8a\xee\xb7\x0c\xc1\x20\x6f\x93\x3c\x76\x0e\x23\x3f\x22\x0c\xc7\xc1\x97\x07\x83\x11\x5f\xb9\x85\xb8\x84\x67\xfd\xca\xcd\x07\x92\xda\x56\xf2\x9b\x54\xce\x85\x39\x04\xdd\xf3\xea\x46\xd6\x75\xbe\x94\x67\xf9\x1a\x89\x33\x1f\x34\x79\x6f\x21\x68\x6f\x6d\xf2\x09\x69\x4b\xf0\x7d\x3b\xdc\x3d\x10\x28\xbf\x65\x1f\x6c\x6c\x9f\x4c\x3f\x98\xf1\x10\x46\x8a\x20\xf2\x1e\xbb\xd7\xbb\xf7\x54\xff\xcb\x65\xaa\xe6\xf3\x2e\xe7\x46\x76\xa9\x27\xcb\x80\x23\x4d\xdb\x5e\x04\xab\x4c\x3d\x81\x8c\x54\x31\xfe\x9a\x4e\xed\x81\xef\x1e\x36\x0c\x67\x0e\xdd\xe1\x03\xe3\xd7\x93\x6d\x5d\x08\x4a\x65\xdb\xc2\xcf\xb6\x35\x0b\x08\x1b\x13\xc2\x9c\xf6\xf6\x95\xe2\x81\xf0\x1f\x93\x93\x13\xa2\x9f\x45\xea\xce\xc9\x5a\xaa\xeb\x6a\xd9\xb6\xca\xf0\x7a\x5d\xbb\x14\xcc\xc2\xaf\xfd\x82\x2c\xa8\xbf\x00\xe5\x85\x3d\xac\x0d\x11\x62\x83\x4f\xaf\x27\x8b\xba\x6a\x9a\x17\xd5\x3a\xcb\x4b\xb6\x1b\x80\x11\xd7\x9a\x9a\xde\x86\x17\xb8\x96\xc2\xc7\x70\x73\x81\x7f\x78\xa7\x10\xf1\x63\xef\x7b\xc6\x7a\x19\xae\x1a\x35\x12\x08\x85\x10\xdc\x29\xe0\x86\xd9\xaf\xbf\x63\xbb\x6e\x41\x5a\x66\xe6\x2b\xf3\x59\x51\x74\x3d\x09\xd6\x43\xcf\x76\xe7\xf5\x1c\x9b\xd1\x3c\x21\xec\x86\x07\x2f\x75\xab\xd6\xd9\x12\xa0\x00\xb3\x82\x31\xfe\xad\x96\x96\xfc\x9a\x2b\xfe\x81\xf1\xad\x35\x3b\x7c\x00\x4d\x64\x75\x94\x97\x74\x63\x8d\xd7\xfa\xdd\xb8\x2a\xb3\x28\x9a\x42\xac\x2b\x2a\x10\xe3\x31\xe8\x1d\x1d\x0b\x16\x01\xb1\xa8\xb2\x5a\xf9\x9e\xc4\x3f\x5d\x38\x40\x7e\x0d\x3e\x0a\x86\x03\x66\xf4\xc2\xec\x50\x30\x2b\xe3\x15\xb6\xb4\x1b\x28\xef\xe1\xf0\xb4\xf3\x50\xf2\x40\xcb\x00\x96\xa6\x91\xba\xa8\x25\x20\x23\x9c\x3b\xa2\xf8\x43\x95\x01\xa2\x77\x4d\x2b\xe2\x1f\x57\x8f\xe7\x8a\x93\x31\xd1\xea\xef\xd2\xd4\x10\x35\x66\x7b\xec\xc7\x78\xd0\x0d\x41\xb5\xbc\xad\x47\xf4\x3a\x0c\x4e\xd8\xc7\x82\xbe\x73\x81\x5b\x09\x89\x48\x4c\x12\xc2\xc6\xa6\xeb\x8c\xff\xa4\xc9\x8f\x76\xe9\xeb\xc9\x22\x5b\x5c\x4b\xc4\x46\xf4\xdc\x73\x8a\x93\x47\xa7\x84\xf1\xe5\x70\x81\xe4\x42\x90\xf1\x6b\x35\x1e\x8f\x97\x76\x8e\x56\xf8\x33\x5f\x59\x3d\x10\xd0\x25\x42\xc5\x10\x42\xcc\x3e\x4c\xfa\x82\x93\x92\xef\x56\xc7\x36\xcf\xf1\xdb\xbc\x5c\x48\xc2\x0f\x9e\x04\xab\xb0\xca\xae\x3e\x56\xc8\x0f\x55\x29\x8f\xcf\xf4\x2c\x20\x3e\x37\x63\x3c\x18\xfb\xbe\xdb\x8d\xf5\xbc\xd7\xc1\x2a\xbc\x64\xc3\x6f\x32\x05\x1c\xbf\x03\x9f\xed\x4e\x01\x8c\x0f\x3d\xf0\x0c\x34\x45\x12\x8a\x99\x74\x3a\xd7\xd5\x31\x3a\x64\xda\xbd\x33\x4f\x1e\xbc\x33\xd6\x1b\x04\xa8\x76\x98\x9c\xe8\x55\x6c\xfc\x9b\x1a\x93\xd9\xd1\xef\x62\x3a\x99\x9e\x92\x98\x10\x16\xfb\x62\x10\xd3\xe8\x7a\x72\x8d\x2b\x1b\x1b\xa8\xe6\xca\xdf\x4e\x57\x48\x53\x77\x3d\x41\xca\x99\xb7\xb2\x5c\x5a\x7c\xaa\x30\x0d\x4f\x1a\x2f\xf9\x07\x7e\xcd\xda\x76\xeb\x0e\x77\x3f\x18\xf1\x0e\x85\x5c\x08\x02\x57\x84\x5f\x01\x51\xe9\xb5\x47\xf2\xe0\x1f\x30\xfc\xfa\x7a\xd2\x6c\xc1\x9e\xaa\x53\x00\xdd\xe3\x1a\x0d\x86\x8c\xd7\xe2\x5b\xad\x79\x19\x01\x03\x7a\xc4\x87\x89\xd7\x41\xc4\x29\xdf\x44\xd1\xba\x27\x36\x80\x3b\x27\xfd\xc0\xaf\xe7\x1d\x91\x74\x3d\x01\xdd\x5f\x37\xbc\xc2\x70\x9a\x2f\x01\xe7\x5c\x3c\x08\x7a\x65\x3f\x84\x98\xfc\x84\xed\x41\x1a\xe1\x15\x43\x91\xbe\x15\xa3\x53\xe0\x42\x2e\x97\xf4\x86\xbf\x66\x5e\x10\xc3\xb2\xaa\xae\xeb\xea\xf6\xe8\xdd\xec\x35\x3d\x3e\xe5\xef\xd8\x7e\x0f\x2b\x2a\x5c\x91\x1f\xaa\x23\xa7\x62\x86\x5b\xf9\xd7\xb0\xe3\xcd\xdc\xee\x14\x94\xc5\x1b\xfe\x8c\x5f\x08\x35\xdb\xb6\x2d\xdd\xea\x7d\xed\x22\x8a\x7a\xd1\x41\x0b\xdd\x60\xe6\xb0\x24\x17\x8d\x16\x58\xbc\xd3\x5c\xf2\xcb\x69\xf2\xb9\xde\xb0\x09\xf9\xa5\x78\x32\x9d\x46\x91\x7c\xfa\xd9\x74\xda\xb6\x9f\x4d\x3f\x17\x42\x48\xae\x25\xce\xcd\x41\x94\x78\x00\xa3\xe5\xd9\x15\xcd\x16\x84\x2f\x84\xf4\xa3\x71\x46\x1e\x6b\xd1\xb4\x48\xa7\xf3\x19\x5b\xb8\x53\x5e\x87\x2b\x51\x03\x0f\x8d\x74\x5a\x8a\x9e\x72\x07\x5a\x64\x6f\x8e\xa1\xe3\x62\xed\x39\x73\x1b\xad\xb0\x34\x20\x0a\xf4\xbf\x28\x9f\x6a\xc6\x76\x0b\xb7\xfb\xae\xd8\xec\xb2\x96\xd9\x7b\xbd\xf4\xe9\xca\xe4\xe5\x51\xc9\x72\xac\x97\xee\x00\xcf\x44\x5d\xa2\x72\xba\x40\xf6\xe2\x89\xdf\xd7\xa4\x95\xd6\x1e\xc7\xfa\xc6\x9c\xed\x72\x51\x99\x12\x33\x20\xe2\xa9\xd8\x1e\x80\x36\x32\xfd\x06\xe7\x2d\x9e\x8f\xf0\xdb\xa3\xc8\x57\x25\x67\xbc\x4c\xf3\xf9\x9e\x5e\xf3\x0f\x3c\x63\x8c\xf7\xdb\xb7\x07\xb6\x0c\x3c\x24\xbb\x3d\xdf\x86\xed\x6a\xd6\x07\x68\x89\x6d\x7a\x3a\x47\xfa\x49\x50\xc9\x82\x2a\xb3\x22\xcd\xfa\x3a\x66\xe7\x93\xb2\x39\x06\xff\x89\xad\xed\x9a\x59\x0e\xfe\x6c\x70\x9a\x16\xec\x0d\xd3\x1c\x39\x13\x07\xd2\x41\x37\x1d\x2d\xa2\xa8\x8e\x22\xac\xe1\x4b\xd8\x38\xe1\xae\x27\x48\x80\x33\x21\xfb\x05\x00\x8c\x90\xf3\xe0\xcd\xfa\xb5\x38\x5a\x72\xdd\x33\xce\x02\x8e\x12\x6e\x11\x45\x0b\xf0\xc3\x87\xde\xa1\x99\x28\xd2\x05\xf4\x47\x3e\x6f\xdb\x22\x25\x8f\xe1\x67\x40\xa4\x5c\x80\x0b\x50\x23\xaa\x00\x33\x96\xa5\xa7\x73\xf4\xdf\x0f\x0a\x00\x41\xea\xca\x80\x2b\xc6\x76\x00\x15\x9d\x25\x19\x10\x2d\xc7\x00\x00\x50\xc0\x08\xa3\xb9\xd0\x79\xf8\xd6\x75\x68\xa3\xdb\x3f\x18\x5f\x90\x39\xd3\xaf\xcf\x74\x8b\xc0\x84\x6f\x98\x12\x99\x73\x8b\xc4\x03\x18\x7d\xed\x85\x83\x31\x60\x36\xb0\x95\xea\x9c\x9b\x70\xf8\x13\x67\xc9\xbb\x58\x4b\x08\xec\xbe\x06\x80\xed\xea\x6a\xad\x87\xe4\x98\x1c\xa9\x4a\x37\xc0\x7e\xbf\xef\x96\x63\x04\x29\xe1\xba\xdd\x63\xb5\xd7\xa3\xee\x86\x7f\x00\xd0\xa5\x84\xf6\xd6\x67\xfa\x4c\x7c\x18\x9a\x7d\xaf\xb2\x46\xb9\x25\x19\x31\x51\x0e\x16\x64\xf1\x8c\xf1\x87\x9e\xd7\x4b\xaf\x7d\xcc\x2c\xc3\xe2\x19\x63\xfc\x09\x0a\x99\xb6\x25\xdf\x7e\xfd\xec\x05\x81\xd5\x44\x2b\x31\xc9\x85\x20\x65\x65\x99\x06\x62\x23\x8b\x30\x55\xad\x6d\x3d\x62\x7a\x21\x6e\x60\x63\x22\xf9\x4a\xdc\xa0\x4e\x53\x88\x11\x5d\x8a\x1b\xb3\x5c\xa0\x42\x75\xc1\x47\x32\x8a\x2e\xda\x56\xaf\x3d\xb6\x49\xc1\x87\x5b\x8a\x29\x63\xb0\x48\xc3\xf6\x46\x48\xf7\x13\x28\x9a\xa8\x6a\xdb\x0b\xbd\xb3\xe0\x45\x72\xd6\xc1\x29\xbb\xe4\xe9\x8a\x5f\xf0\x0f\x73\x16\x9f\x85\x40\x65\x97\x7a\x99\xb9\xe0\xcb\xb9\x2f\x54\xef\xb3\xe8\xbd\xde\x55\x1b\x41\xdc\x59\xa0\x8a\x04\x97\x28\xd3\x4d\x31\x5c\x7d\x8d\x75\xd4\x2b\x16\x2f\x92\x55\xac\x8b\xbb\x02\xf0\x9f\xe0\x25\x73\xa6\x4b\xa2\xbd\xb5\xee\xb9\x59\x4b\xdd\x7a\x77\x7c\x6c\xd5\x6a\x38\x76\x1b\x52\xaa\x2b\x70\x67\xb3\xbb\xe2\x0f\xb0\xfb\xfd\xfb\xdb\xd7\x3f\x3c\x10\xf0\x75\x74\x6b\x63\x4e\x78\xc9\x09\x98\x71\x70\xc7\xfc\x16\xac\x51\xc3\x1b\x5f\xfb\x8c\x69\x03\xe5\xe9\x66\x3b\x4e\x66\x57\x52\x11\x4e\x36\x55\xa3\x06\x20\xd7\x7b\x01\x5e\x5d\x8e\x89\x2b\x6a\x41\xfc\xdb\xb6\xe6\x35\x40\x75\x5b\xbc\x05\x34\xaa\x78\xd0\x2f\x30\x23\x49\xb4\x39\x2a\x6e\x25\x52\x5c\xe1\x24\x29\xb9\x99\x34\x31\xa0\x6e\xf4\x4f\x9f\xc0\x91\xc8\x04\x5b\x5b\x92\xe7\xe1\xa0\x60\xf3\xda\xf0\x6d\x68\xe1\x74\x6f\xb4\x8d\xc0\x41\xe9\x0e\xac\x91\xa7\xce\x5e\x79\xda\xb5\xac\x81\x8d\xcc\x3c\x15\xda\x23\xf6\x7b\xee\x05\x6d\x0f\x44\xd6\x53\x5e\x23\x08\xf4\xbe\x7f\xbe\x75\x5b\x67\x9b\x67\xc5\x80\x7f\x71\xb8\x99\x87\x55\x8c\x22\xbe\x0b\x95\x22\xf0\x07\x4e\xa7\x5a\xab\x56\xe2\xd6\xa0\x11\x1f\xd0\x92\xb3\x89\xfc\x9d\x4e\x59\xc0\x0a\x68\xb3\x75\xa3\x65\x3a\x0c\xa2\xb6\x64\xae\x0e\x4e\xc7\x1c\x67\x28\x1c\x68\xcd\x24\xb2\xaa\x9a\xbd\x35\x44\x2f\xcf\x98\xae\xe1\x61\xb2\xc3\x82\x65\x8e\x4b\x12\x1d\xd0\x8d\x69\x44\xb7\xc4\x77\x65\x39\x4c\x40\xfd\xa0\x67\x7e\x10\x79\xe1\x0a\xe8\xc6\x5d\xb0\x3f\x72\xc5\x77\x5e\xf7\xa5\x70\x7b\x8e\x86\xfa\x98\xfa\xa4\x9c\x98\x5e\x82\x83\xbe\x90\x08\x93\x61\xb5\x07\xac\x2c\x57\x3e\x28\x61\xd0\xfb\xa4\xec\xd6\x5b\x17\xae\xba\x8e\xde\x2c\x36\x6f\xd8\x96\x07\xef\xe8\x10\x37\x42\x3f\x52\xc9\x26\x65\xa5\x28\xb9\xac\x96\xf7\x64\x80\x95\xd8\xc7\xa7\x38\x46\x4a\x7b\x6e\x68\xd9\xe9\xe1\x70\xc4\xc2\x3c\x9a\x18\xd1\x4d\x23\xb7\xcb\xaa\xb1\xb0\x4d\x03\x68\x1f\xbd\x8c\x40\x70\x65\xf8\x1a\x87\x6f\x0d\x15\x32\xa2\x32\xe4\x95\xd3\xda\x1f\x5e\x22\xcb\xca\x47\x88\x1a\xe0\x35\x9d\x83\x98\xbb\xeb\x3a\x8c\xda\xd7\x0b\x7e\x40\x86\x53\x4e\x7e\x39\x7b\xf5\xad\x52\x1b\xb3\xe5\x32\x5a\x80\xd4\xf3\x18\x8c\xc3\x3f\x29\xb1\x9b\x02\x0e\xc1\xe9\x93\x27\x9f\xc5\x4f\xa6\x9f\xef\xf9\x3f\x55\xff\xb4\xe7\xee\xba\xa6\x6c\x76\x36\x59\x54\x75\x23\x46\xa3\x7f\xaa\x28\x22\xb7\xb9\xba\x7e\x5e\xcb\xa5\x2c\x55\x9e\x15\x0d\xc9\xcb\xa3\x7f\x2a\x7e\x06\x0f\x8a\x7f\x2a\xc8\x66\x2a\xeb\xb6\x1a\xf4\x90\x93\x96\xd7\x68\x7b\xd3\x45\xb7\xad\x2e\x79\x24\x3b\x46\x2d\xab\x66\x74\x68\x96\x3d\x47\x17\x6c\x09\xb0\x7e\x5a\x37\x07\x6a\x4d\x6a\x3c\xba\x25\x18\xbb\x24\xee\xbe\xf4\x55\x23\xc1\xdb\x92\xcb\xc9\x26\x6b\x9a\xdb\xaa\x5e\x32\x0e\x4f\xa3\x8e\x19\xea\xb6\x3e\x51\x2b\xaf\x22\x48\xb0\xba\xac\xc9\x68\x37\x14\x51\xd4\x4c\xfa\x26\xd3\xa1\x34\xea\x1f\xd1\x2f\x0f\x3e\xb5\x6d\xab\x94\xfc\x72\x6c\xba\x4a\x2e\x8f\x81\x48\x75\xde\xb6\x74\x30\x5d\x90\x6e\xdf\x12\xc6\x2b\xd6\x1c\xee\xaf\x33\x0e\x1e\xdc\xb3\x41\x9f\xe5\x70\xe8\x80\x1e\x5d\x8b\x66\x52\x95\x45\x95\x2d\xe1\x07\x68\x31\xf0\x0b\x36\xa4\xf0\xcb\xec\x42\xe1\x37\x6c\xf1\x40\x35\x5a\x5c\x67\xe5\x15\xf2\x1b\x73\xb3\xf1\x06\x65\xaa\xb1\x7b\xf2\xd8\xa8\x44\x18\x30\x73\x00\xba\xd5\x18\x35\x26\xc9\xe9\x94\x9b\xac\x2c\xce\xa9\x4d\xe7\x4d\xa0\x31\xe9\x1b\x3f\xa9\xd4\x26\xcd\xdb\x76\x30\x1b\x1e\xf5\x00\xd5\x46\xe3\xf6\x13\xc6\xa2\x06\x77\xd8\x90\x0f\x53\x90\x55\xde\xa9\x64\x77\x99\x97\x59\x7d\x1f\xfb\xe4\x7d\xbc\x83\x53\xa1\x6e\xc6\x3d\x07\xfe\xcf\x43\x73\x3e\x65\x18\xb7\x60\xdb\x55\xef\x4b\xeb\x5e\xeb\xda\x36\x55\xd4\x7e\xba\x8f\xe2\x75\xad\x9f\xf8\x7e\xa8\xe3\xc1\xd6\x0f\xba\x53\xab\xb2\x4d\xb0\x05\x37\x61\x6a\x43\xd6\x06\x15\x45\x35\x35\x7e\x80\xba\x06\xd8\x7b\x68\x64\x68\xd0\xbe\x20\x3b\x16\x2c\xdc\x5d\x21\xe4\x92\xdd\x59\x2c\x0c\xb3\x08\x9a\x1d\x16\xfb\x03\x9b\x3c\xbc\x07\xbc\x1b\x50\xa7\xe9\x1c\x7e\x75\x25\x43\x67\x5a\x80\x7f\xab\x5d\xa9\x26\xa8\x92\x08\x73\xb8\xdd\x39\xc5\x72\x07\xa3\x98\xc7\x9c\x80\xfa\xe3\x4b\x7e\xd4\x39\xe1\x7c\x20\x5d\x2e\xd6\x83\xe9\x77\xc7\xfe\x4e\xe7\x20\xd4\xbc\xed\xe4\xfc\x92\x26\xb1\x2e\xb5\xd5\x19\x19\x26\xc3\xe9\xe7\x27\x28\x56\x32\x54\x60\x03\x35\x8a\x71\x69\xa2\x23\xba\xcd\xe5\x14\xba\xae\x44\x75\xf4\xdd\xce\xba\x6a\x7e\xe9\x06\xe3\x87\xcd\x8a\xa8\x27\x5a\x57\x0c\x9a\xd3\x8b\xeb\x07\xde\x82\x81\x36\x70\x82\xd3\x95\x5f\xd2\x74\xcf\x33\xa5\xea\x66\x58\x72\x83\x2a\xad\xb5\x10\xf2\x14\xf3\x7e\x49\x98\x89\x01\x0a\x1f\x46\x52\x6f\xf0\x4a\xda\x99\xf3\xef\xd8\x66\x78\x8e\xd7\xbc\xa9\x17\x31\x88\xf8\x3d\x9b\x54\x25\x25\x7a\x72\x1d\x99\x6d\x57\x77\xf1\x56\xd6\x0f\x52\xab\x3d\xe8\x21\x1f\x45\x15\x0d\x04\x12\x6e\x07\x3f\x9f\x7e\x0e\x6b\x21\x5e\x22\xd8\xea\xb5\xcc\x96\x1d\xbc\x1a\xa5\x95\xc5\x81\xd1\x5d\x46\x51\x49\x03\x27\xcb\x5f\x95\x48\xe7\xfc\x1b\x25\x4e\xa8\x60\xe7\x09\x4d\x44\xd4\x3e\x62\xed\x79\x82\xde\x95\xc1\xc0\xd5\x5b\x9b\x4d\x4c\x16\xe6\x9c\x14\x0f\xbe\x37\xf6\xd8\xf4\x90\x4e\xe4\x57\x85\x9e\xd6\xb0\xd1\xc2\xd0\x84\x31\xb9\x40\xc3\x78\x47\x93\x96\xe0\x86\x22\x07\x07\x90\x7e\x07\x9c\x8d\x6f\x48\x8f\x53\xa6\x47\xc1\x85\x08\x67\x13\xc8\x1a\x45\xf4\x1b\x17\x82\xbf\xad\x0b\x96\x90\x6d\x5d\x90\x21\x1c\x07\x63\xfa\x86\xd3\x0c\xf9\x7f\x7a\x9a\xe1\x5f\x6a\x8e\x1c\x88\xfe\x8b\x61\xc2\x4d\xdb\x12\xfc\x0e\xe8\xc8\x8e\x8b\x8b\x75\xc8\xb1\xf5\xb7\x6d\xaa\x35\xd6\x6e\x0a\x4b\x7a\x09\x94\xc5\xbd\x14\xde\x24\x32\x6d\xe6\x40\x66\xe8\x4e\x2c\xbe\xc1\x13\x8b\x71\xc5\xe2\x5e\x43\x41\x03\x05\x07\x23\xb6\xc1\xec\x59\x86\xc9\x09\x1e\x8d\x15\x4c\x4e\x6f\x2e\x33\x13\x0f\x7d\x17\xe6\xe2\xf0\x3c\x38\xf3\xbe\xad\xd5\x98\x1c\xdd\x66\xcd\x51\x59\xa9\x23\x3d\x84\x74\x8b\xf1\x2c\x9d\xce\xf7\xbc\xdb\x1a\x02\xf7\xd0\x3c\x17\x25\xb8\x6c\xa6\x55\xa7\xe4\x4c\xb8\x78\xce\x3d\xaf\x87\xf0\x56\x9d\x78\xc9\x13\x88\x46\xf3\x58\x1a\xb4\x62\x31\x94\x97\x73\x89\xc6\xab\x7e\x83\xab\x5e\x5b\xea\x31\xbc\x6d\xae\x69\xc5\x80\x50\xee\x0a\xf0\xd0\x73\x9a\xc1\x4e\x2c\x13\x79\x40\xfa\x60\xa5\x10\x86\x4c\xe1\xf9\xe6\xb7\xef\x00\x13\x03\xaa\x7b\x00\x3b\x26\xb2\x49\xbe\xde\xe0\x76\x0c\x06\xd6\xc0\x43\x54\x0f\x42\xbd\x7d\xf0\x31\x10\xb9\xde\x4e\xe9\x3c\x82\x3c\xd5\x63\xf0\xcb\xa7\x27\xf8\x27\xbc\x20\xfc\x09\xca\x57\xb7\x91\x30\xaa\xf9\x9e\xea\x49\x06\xe6\x34\x28\x63\xd8\xa6\x31\xe0\x31\x9d\xa4\xf3\x98\x0e\xc7\x72\x1b\x4f\x39\x2d\xbb\x55\xdb\xd2\xa1\x8f\x4f\x28\xad\x05\x55\x9f\xfa\xc9\xac\x7f\x3e\x7c\x99\x35\x52\x27\xc3\x81\x70\xe6\x9c\xc2\x8d\xb3\xd4\xa1\xf4\xab\xf5\xf6\x52\x64\x8c\xe7\x62\x54\x46\x51\x3a\xe7\xb4\x12\x6f\xd1\xa5\x42\x32\x96\xa4\xaa\xf7\x86\x2a\x3d\x9d\xb3\x79\x4c\x2b\x71\x81\xf0\xb7\x8a\xe7\x00\x8f\x9b\x3b\xf2\xb9\x5b\x9a\x33\x2f\xa1\x6f\x27\x6b\x59\x5f\x49\x9a\xce\x79\x15\xee\xd7\x58\xe0\xce\x62\xec\x0a\xa0\x4e\x3d\x88\xb5\xc2\x33\xc4\xfa\xd6\x3b\x84\x20\xc6\xdf\xf3\x44\x60\x8c\x58\x2d\xae\xf4\xe4\x44\x3b\xb7\xde\xa1\xeb\x1d\x3d\x5e\x4d\xb9\xbe\x06\xff\x64\xd3\x15\xc6\xd2\x13\xab\x21\xe0\x5a\x64\x07\x24\x6f\x5e\xbf\x7d\xa7\xa7\xa0\x85\x9d\x99\x46\xd1\x80\x85\xa6\x6a\xdb\xbe\x91\x06\x9d\xb5\x8c\x01\x95\xf5\x11\x82\x25\xdb\xe5\x7e\x8a\xea\x95\x49\xad\x0b\x5a\x27\x7a\x29\x5d\xe6\x37\x5f\x3a\x58\x35\x1a\x0c\x43\x80\x4f\x58\x21\x7a\x3e\x6e\xb1\xed\xc4\x2e\xa3\xa8\x6b\x4c\xca\x0e\xb7\xd1\x1d\xfc\xc3\xbc\x6d\x03\xab\x3c\xa8\xd7\x8a\xcb\x39\xa2\x84\x5b\xb3\x86\xb5\xaf\xf9\x53\x74\xee\x8d\x7f\xbc\x67\x39\x0c\x6d\x90\x1d\xeb\x24\xf7\xc7\x69\x03\x84\x88\x7d\x40\xc7\xae\x85\x00\x5c\x4f\xa5\x83\x61\x0c\xb7\xe4\x06\xc9\x70\x39\xf4\xec\xed\xe4\xaa\x96\x1b\xea\xb0\x36\x3b\x46\x17\x07\xbe\x27\x84\xb2\x4c\x28\x76\xda\xf3\x5b\xb3\x79\x87\xd0\x92\xd7\xf0\xf3\x61\xfc\x1f\x77\xce\xe2\x29\x97\x0d\xbf\x21\x90\xbd\xdf\x6a\x8d\x0f\xd8\x7d\x88\x56\xeb\xf3\x85\x1e\x5d\x85\xe7\x06\x0c\xd8\xea\x2d\x99\x3f\x61\xbc\x11\x96\xa7\x9e\x22\x28\xae\x29\x1a\x0c\xae\x7c\xe1\x13\x0a\xe0\xf5\xe3\xb4\x43\xb1\x58\xb4\x2d\x59\xe5\x77\x88\xe1\x56\xb0\x28\xa2\xf9\x78\x11\x2e\xd0\x5b\x55\x41\x3c\x65\x42\x33\x41\x6b\xb1\x75\x95\xa0\x8c\x01\x33\x7f\x25\x6a\x60\xf2\x63\x71\x97\xe0\x37\x67\x6d\x3b\xe5\x55\x98\xb4\x40\x46\x66\x44\x66\xa6\x4a\x38\x72\x86\xb2\x83\xd0\xab\x67\xbb\xc1\x46\x56\x13\x80\x2f\xa5\x1b\xfd\x17\xaf\x8e\x1b\xfd\xef\x38\xf3\x59\xf4\xdb\x21\x8f\xfe\x61\xae\x8f\x1b\xf8\xa3\xd7\x56\xb2\x6d\xb4\xd0\xcd\xcb\x23\x95\xa8\x09\x5c\xd8\xf7\x6e\x58\xbc\x85\xe6\xd9\x20\xbf\x53\x60\xad\xac\xfa\x7d\x09\x3b\x9c\x87\x60\x4c\xbc\xee\x0d\xa6\xbb\x41\x1b\x1c\x0c\x5f\x2c\x76\xe2\x06\x8b\xc5\x6b\x05\x14\x8d\x99\xc7\x82\xe8\x81\x2d\xd4\x49\xfd\x90\x55\x28\xd1\xfb\xf6\x87\x38\x16\x79\x29\x7a\xc1\x90\x61\xf8\x23\xdf\xa9\x6a\x13\x43\xab\x8e\xcb\xc9\x26\xbb\x92\xbf\x62\xad\xb8\x6e\xbb\x18\x5b\xd2\xdc\xf9\x05\xef\xec\x59\x0c\x0f\x4d\x31\xcb\x74\x6f\x51\x00\xf8\x66\x80\x9f\x5f\xef\x09\x8d\x81\xd5\x62\x82\x86\x5f\xc7\x2b\xd1\x2d\x4c\x6b\x74\x7e\x38\xe2\xc8\xad\xc3\x59\xc2\x3e\xf2\xad\xfe\x84\xd5\xd0\xf9\xb9\x59\x71\xd0\x08\x5c\xea\x14\xb8\xfd\x06\x6c\x8a\x6d\x5b\x4e\x96\xe6\xa6\x59\xbb\x66\x88\xeb\x2b\x44\x09\x9a\x42\xdb\xe2\xef\x5e\x2e\xc0\x7a\x70\x93\x75\x60\x5e\xa3\x8d\x38\x00\x74\x92\x51\x24\x91\xe4\xe5\x80\x83\x80\x56\x20\x03\x5c\xc5\x61\x82\x1d\x30\xa9\xbf\xab\x36\x8e\x43\x9d\xf1\x0a\x3b\xa9\x9f\xe9\x95\x5c\x29\x9f\xcb\x1e\xbb\xf8\xfe\x3e\xae\xe0\x5f\xd7\xc4\xc8\x85\xf5\x4e\xcb\x69\xa0\x1e\xf0\xfd\x7f\x8c\x6f\xe8\x67\x05\x96\x50\x0c\xf6\xdb\xf3\xb0\x29\x3f\x35\xf8\xa4\x6b\x5e\xef\xf4\x86\x6e\xa3\x4f\x69\xd5\xce\x33\x56\x4c\xb7\x6d\x26\xbb\xd8\xc1\x3b\xcf\x08\x17\x93\x60\x2c\x13\xee\x18\xe4\x30\xdd\x8c\xfe\x87\x22\x11\x3b\x79\xf4\x6a\x30\x3b\x40\xd0\xad\x3f\x46\xd8\xe9\x63\xec\xf5\x38\x07\x10\xbc\x5c\xc8\xf8\x6f\xfd\x61\x90\xeb\x8d\x8c\x9f\xa5\x21\x4d\xb1\x3b\xf1\x4f\xf2\x54\xcd\x63\x99\xd6\xf3\x59\x9e\xe4\x8e\x0a\x8f\x96\x49\x1e\x4e\xd7\xb8\xe2\x65\x52\xc5\x79\x38\xb9\x19\x3c\x26\xaa\x3d\x82\x16\x1f\x88\xb4\x10\xc3\x38\x25\xb8\x74\xc3\xda\xf1\x07\xf4\xc4\xc0\x40\xbb\xc9\xef\x64\xf1\xc6\xb2\xf6\x86\xf9\xcb\x0e\x57\xb1\xe5\x54\x57\x8c\x5b\xee\xfb\x92\x25\x30\xfa\xfd\x02\x93\xaa\x39\x70\xc3\xc6\x25\x92\x91\xb8\x0e\x35\x84\xe4\x8e\x3f\x19\x46\x7a\x6c\x78\x5f\x06\x70\x8e\xf1\x29\x47\x26\x0b\xba\x3e\x19\x4b\x6b\xc7\x89\x15\x27\x24\x26\xd5\x56\x41\x72\x58\x00\xb8\x49\x40\x37\xd7\x41\x37\x7b\x0b\xb4\xe8\x37\x9f\xd6\xdb\x03\x40\x69\xaf\xea\x57\x7a\xa9\x2e\xdb\x96\xc2\x99\x7f\xd5\xb6\x23\xdc\x4c\x59\x1a\xba\xd8\xd2\x07\x3b\x15\xf5\x60\x08\x69\xe1\xe9\x86\x90\xc9\x74\xaf\xf5\x53\xf0\x71\xf1\x8b\x36\x7e\x08\x4b\x54\xea\x3e\x75\x1e\x2b\x27\xba\xfa\x32\x2c\x25\x0b\x10\xa3\x90\xed\x6f\xa0\xe6\xd8\xd1\x98\xd0\x5c\x1c\xe4\xe7\x8e\xd6\x4d\x81\x68\x84\x0d\x6b\x55\x14\xfa\x79\x9e\x77\xae\x6c\x06\xcb\xac\x8c\x19\xba\x57\xfe\xe5\xcc\xc6\xb6\xe8\x06\x4a\x70\xda\xeb\x6f\x6e\x98\xe3\x87\x84\x26\xe0\x0d\x28\x9d\x3c\x4b\x2a\xf3\x00\xcf\x10\xa1\xd8\x8f\x11\x72\x59\x6c\xeb\x23\x08\x2e\x3e\x32\x11\xc7\x47\x36\xd4\xf8\xa8\x96\x4d\xfe\x41\x1e\x61\x45\x8f\x16\x45\xbe\x78\x7f\xb4\xbc\x2c\xf0\xc7\xba\xda\x36\x72\x59\xdd\x96\xf8\x6b\xbb\xc1\xbf\x7a\x83\x82\xbf\xaa\x1b\x59\x9b\x5f\x5b\x85\x3f\x64\xa9\x6c\x5a\x21\xb3\x1b\x79\x84\x26\xd9\x23\x0c\x08\x3d\xc2\x40\xd2\xa3\xf7\xf2\x1e\xca\x7d\x2f\xef\x37\xb5\x6c\x1a\xfd\x63\xbb\x39\x32\x2e\xf6\x6b\x59\x6e\x49\xe0\x46\xf2\xc7\xba\x6f\x70\x5a\x7e\x00\x77\x39\x4d\xbc\x42\x8c\x46\x2f\x6e\x39\x59\xed\xc1\xbc\xb2\x53\x3d\x50\x7b\xae\xf5\xc7\x7d\x24\xb2\xdc\x7f\xad\x9e\xaa\xfe\x83\xa9\x6a\x5b\x79\x18\xaa\x7e\x99\x87\xe6\xbf\xee\x01\xbf\xad\x9f\x34\x81\xee\xbc\x84\x13\xc0\x83\x47\x7a\x0f\xac\x56\xee\x09\xb6\xe7\x16\x3d\xe2\x0f\x48\x2a\x70\x5f\x60\xc8\x26\xb6\xe5\x03\x4f\xb9\x67\x80\x12\xb3\x8f\x6f\x15\xbc\x9e\x3c\x7e\x4c\x4c\x63\xea\x04\xc5\xc1\x6b\xfb\x31\xe1\xa5\x69\x82\x4d\x5d\xdd\xf5\x41\xbc\x5d\x38\x15\x68\x39\x07\x36\x33\xdc\xf1\xcb\x54\xcd\x0d\x8f\x43\xa9\x35\xe5\x80\xe6\x51\x2c\x50\x6d\xf5\xbb\xc0\x27\x4c\xef\xbf\x0f\xd7\x5b\x69\x77\x6e\x26\x98\xbc\xb6\x11\x0b\xfd\x12\x00\xa0\x6f\x72\xb5\xcd\x97\x42\x86\x7f\xda\xf6\x16\xfe\x8e\xc7\xbc\xd2\x7a\xf1\x75\x55\x2c\x7f\x94\xd9\xf2\xbe\x8b\x37\x03\x70\xbc\xd9\xf2\xfe\xe7\x2c\x57\xe3\x71\x6c\xae\x80\x39\x03\x5c\x1a\x20\x96\x52\x74\x22\x2b\xad\x95\xe4\xef\x6f\x5f\xff\x20\x82\xb0\x9c\x5b\x17\xf2\x29\xbe\x86\x67\x5f\x9a\x17\x89\x2b\xb8\x44\x7c\x0e\xa1\x9f\x5f\x64\x6b\x59\x3c\xcf\x1a\x29\xbe\xe7\xb7\x68\xc4\xbe\x80\xe7\x6f\x5d\x24\x3b\x3c\xf2\xc3\x76\x2d\xeb\x7c\x31\x40\xb1\x81\x4f\xf9\x63\x6b\x1a\x22\x8a\x75\x9d\x9d\x59\x14\x8d\xf2\xe6\x87\xec\x07\x2a\x43\xde\x77\xc9\xd8\xde\x2f\xcb\xb4\x1e\xe8\x84\xdb\xbd\xed\x05\x9e\xce\x19\x03\xf4\x15\x79\xb7\xa9\x6a\xd5\x88\x1a\x55\xfd\xef\x95\x28\x27\xbf\xfd\x63\x2b\xeb\x7b\xfe\x48\xff\x7e\xe4\xc9\x6a\xca\xea\x79\x55\xae\x8a\x7c\x31\x8c\x36\x34\x79\xa4\x15\x23\xe0\xad\x7a\x24\x1e\x29\xc6\xe1\x88\x07\xcb\x72\x77\xcc\xe5\xf7\x8a\xf1\x5b\x80\x6d\xf1\x69\xfa\xb1\x5b\x9d\xdc\x81\x75\x37\xb3\x80\x6c\x1b\x79\xa4\x1b\x61\xa1\xc8\xac\x9c\x2c\xa9\xe2\x24\x23\x43\xe4\xee\x3f\x01\x09\x14\xe6\xb8\x1c\xcc\xf1\x7d\x90\x63\x31\x98\xe3\x85\xdd\xf9\xd4\xa2\xa4\x5a\xa3\x15\xe5\xa4\x04\x24\x29\x41\x4b\x7a\xca\x78\x49\x9f\xfc\x17\x63\x3c\x83\xf4\x1c\x96\x51\xfa\xd9\x54\xef\x6d\x75\x42\xc3\x78\x21\x4a\xfa\xe4\x0b\xbd\x85\x1e\x94\x1b\x72\xd2\x6c\x2f\x1b\x55\xd3\x29\xb7\xd4\xe7\x4c\xf7\xed\x9e\x6f\xc4\x03\x50\x59\xd6\x8b\xca\xf9\xb5\x56\x42\x59\xd1\x9c\x10\xa6\xf7\x2e\xb9\xb8\xa7\xb0\xa6\x13\x70\x26\xd4\x49\x0b\x04\xc0\x2b\xc4\x94\x6f\xc5\xc2\x62\x69\x15\x4f\xb7\xb3\x62\x3c\xc6\xc1\xb7\x11\xa3\x53\xbe\x12\x8b\xb4\x98\x4f\x6a\xbd\x4e\x6b\x61\xb0\xb2\xea\x1e\xab\xc5\x0e\x52\xe3\x15\x87\xf8\x87\x26\xde\xed\xf9\xb6\xce\x63\xb5\xf7\xdb\x1b\x5d\xce\x52\xdc\xd3\xd5\x64\x93\xa9\x6b\xc6\x2f\xc5\x6e\xcf\xcf\x3c\xd9\xaa\xb5\xad\xf1\xa5\xf3\xeb\xbf\x11\xd3\xd9\xcd\xd3\xb3\xd9\x8d\xad\xc7\x85\x58\xa6\x37\x73\x7e\x2b\xf2\xf4\x06\xe2\x6b\xd7\xf4\x82\xb1\xdd\x65\x7a\xd1\x8d\xa2\x9d\x8b\xdc\x24\xdc\x60\x78\xf5\x52\xf6\xc3\xef\x2d\x7a\xf4\x09\x09\xbc\x13\xdd\xdc\xb8\x65\xbb\x8d\x18\x4d\xcd\x1d\xc0\x9f\x10\xd7\x68\x31\xbc\x00\x0b\xfe\x87\x28\x1a\x35\x6c\x77\xac\x65\xee\x33\xa7\xc3\x7c\x48\x4f\xe7\xac\x6d\x33\xca\xe8\xe8\x14\x87\xc7\x6b\x71\xf8\x6e\x7a\xcb\x66\x97\xa9\xce\x3c\x17\xaf\xf7\xd6\x97\xf3\x62\xd4\x7f\x2f\x38\x4c\x6e\xd8\xae\x3c\x68\xdf\x4b\x68\x5e\x72\x42\xc6\xb9\xb3\xfb\xdd\x04\x9f\xb4\xb7\x25\xec\x3d\x92\x59\x8d\x87\x9f\x7b\xbe\x12\x07\xd0\x63\x5b\xbd\x3c\x9c\x10\x0f\x39\x36\xb3\x50\xec\x7e\xf8\x00\xf3\xcb\x14\x19\x5f\x80\x00\xb4\x3f\xb6\x32\x71\xaf\x27\x40\x23\xee\x69\x0e\x8d\x04\x63\x2c\x0b\x0e\x35\x6e\x68\xce\x2b\x84\x56\xdd\x82\xdd\x9c\x93\x89\xc5\x7d\x5f\x88\xc6\x0a\xfc\x2c\xec\x1c\xf7\xa8\xbe\x44\xdd\x93\xe8\x2f\x67\xe3\x05\xaf\x10\xf7\xc8\x44\x25\xfb\xc7\xf9\x46\xa4\x73\xbe\x12\x53\xbe\x14\x85\xc3\xc3\x7b\xba\x9c\xad\xec\x48\xba\x16\x45\xba\x9a\xcf\xc8\x64\x02\xae\x95\xc9\x06\x8f\xa7\x62\x32\x81\x90\x81\x28\xda\xa0\xad\xff\xda\xf9\xfe\xdd\xe8\xf7\x8f\x37\xbe\x66\xfa\xed\x7c\x39\x38\x79\x75\xce\x7b\x50\x35\xba\xa1\xfd\x76\x4f\x76\x6d\x8d\xcf\x2e\xa8\x3f\x51\xa9\x6e\xd5\x79\x0c\xee\x57\xbe\x1f\xf9\xb5\x38\xf9\x77\x4c\x27\x63\x76\xc2\x2f\x87\x64\xea\xb5\x85\x12\xd8\xf3\xf5\xd0\x7d\xbd\x29\x05\xc7\x61\x09\xc7\x2b\x67\x83\xf5\x35\xc3\x4b\xf2\x66\x51\xd5\x32\x76\x1b\xb9\x64\x1a\xdf\x53\x89\x13\x76\x52\xcb\xe5\x76\x21\xfb\x48\x05\xf6\x35\x63\xf1\x39\x1f\x1d\xbe\x1f\x86\x80\xdc\x6b\x75\xff\x52\xff\x23\xc7\xe2\x49\xbc\x86\x5f\xc7\xe2\xaf\xb1\x1c\x8b\xcf\xf4\x3f\xa7\x5c\xee\x19\x9f\x32\x0e\x33\x29\x56\xfb\x3d\xbf\x1a\xfc\x1a\x68\xd1\x33\x86\x40\x68\x0f\x54\x65\x02\x5f\xf1\x54\xe1\xdf\xe4\x34\x36\x29\x5f\xda\x94\x63\x9d\x04\x6f\x3a\x56\xf8\x17\x16\x94\xfb\xe1\x37\xda\x63\xb3\x13\xfa\xef\xf3\x93\x71\x7b\x7e\x32\x7e\xc4\x4e\xae\x38\x21\xcc\x8e\x7f\xe8\xa8\x9b\x07\xc4\xf8\x98\xaa\x84\x24\x64\x0c\x40\x26\x7b\xfe\x4c\xa4\x64\x5b\xe7\x84\x13\xdd\xaa\x64\xce\x2f\x04\xba\x4f\x4e\xb2\xa6\xc9\xaf\xca\xb6\x0d\x2b\xe1\xf9\xa9\x4f\x67\xea\x69\x5f\xb9\x03\xfe\x19\x33\xa4\xdc\xbd\x54\xcd\x1d\xc5\x29\xf2\x7e\x32\xf3\x02\xcf\xca\x7e\x9d\x35\xaf\x6f\x4b\x43\xd6\x7c\x6f\xe9\xb9\x01\xea\x0a\x76\xd9\x25\x10\xf4\x39\x87\x40\x7e\x3b\xc8\xf8\xe5\xd0\x78\x4a\x40\x09\xcd\xea\xc5\x35\xaf\x85\xd2\xa5\x5f\xc3\xd2\x03\x07\x32\x5a\x4e\x20\x13\x34\x30\x0d\xd8\x70\x3c\xde\x08\x0c\xd2\xe3\x0b\xf3\x03\xdc\x9c\x0a\x9d\xa5\xaa\x15\x78\xf4\xbb\x93\x1d\xdd\x54\xfa\xf6\x6c\xb4\x8d\xa2\x2a\x8a\x3e\x00\x75\x63\x29\x6f\x8f\x7e\xfa\xf1\x15\xad\x98\xcb\x60\x27\xd4\xce\x26\xc4\x0e\x78\xc5\xaf\x01\x74\xcb\x18\xc7\xfa\xc6\x25\xd7\xb5\x8d\x6b\xae\xeb\x1a\x57\x86\xb3\x3a\xce\xb9\xad\x67\x9c\x71\x5d\xb9\xb8\xe1\xb6\x8e\xf1\x82\x43\x98\x73\xc1\xd1\x8f\x5c\x4e\xae\xf3\x46\x55\xf5\xbd\xf1\xb7\x7e\x2f\xef\xfb\x69\x00\xf8\x1e\x26\x4c\xde\xcb\x7b\xe0\xb9\xcc\x55\x9e\x15\x64\xbf\xe7\x1f\xc4\x88\x0e\x72\x93\xdc\x1a\x8c\xb7\x11\xfe\x70\xdb\xda\xc3\x94\xee\x29\x16\xe3\xaf\x07\xa1\x6b\xd2\x39\xaf\xd1\x68\x5f\x01\xa3\x58\xa8\x04\x5a\xb2\xb6\xdd\x95\x54\x47\xb6\xf5\xbd\xce\x53\x83\x2b\xf3\x91\xaa\xb3\x12\x8d\x1d\x79\x79\xe5\xef\x56\x7b\x7e\x51\x95\xef\xdc\x4d\x7b\x68\x12\x9a\xd6\xf0\x95\x94\xed\x79\x01\xc0\x4f\x1d\x8e\xed\xd2\x02\x83\xce\x10\xba\x22\x54\xba\xb0\xc6\x8a\xee\x6c\xad\xe2\x9a\x67\x70\x37\x26\x6f\x5e\xbf\x21\x7b\x4f\x7b\x27\x0f\xa1\xae\xc8\xa6\xda\x40\xbb\x13\x5e\xb1\x90\x0f\x48\x0e\x62\x51\x75\xb3\x97\xa2\x3c\x44\x8d\x09\x04\xc4\x48\x2b\x65\xe0\x2e\x55\x66\x37\x79\x77\x83\xa6\x1e\x32\xb8\x7c\x79\x1a\x80\xdc\xfa\xb9\x7b\x3a\x4f\xc2\x0b\xad\x47\x35\x22\x33\x03\x6b\x21\x5c\x50\x24\x2f\x84\x7b\x7a\x11\x45\x0b\x58\x6d\x0f\x00\x86\x15\xf3\xc3\xee\xaa\xb2\x11\x16\xbb\x46\x5c\xc0\x81\x05\xdf\xe9\xa1\xea\x71\xb4\x00\x4a\x18\x3c\xa8\xaa\xb6\x2d\x12\xff\xac\x79\x29\xf8\x64\xd1\xc6\x6e\x63\x83\x41\xae\xfb\xad\x77\xd7\xb8\x58\x6d\x74\x1b\xdb\x3e\x4b\x8b\x84\x98\xb2\x48\x4c\x50\xde\x91\x39\xec\xe8\xfd\x90\x9c\x42\xef\xe3\xec\x7e\x63\xa2\x9b\x87\xda\x3d\x17\x7a\xa9\x74\x0b\xe8\x64\x55\xd5\x5f\x77\x8f\x2e\x82\x3e\x1a\x1e\x37\x3f\xbd\xfd\x96\x20\xac\xe9\x76\xbf\xdf\xd3\x0f\x09\x4e\xa8\x43\xef\x95\x43\x3b\xc5\x60\xef\x4d\xc3\xde\x9b\xce\xb5\x96\xa2\x77\xc5\xde\xc4\xa5\xb5\xa8\x52\x78\xe1\xa4\xbe\x3c\x3e\x4d\x42\x45\x9f\xe9\x35\x18\x25\x53\xf7\x9e\x62\x31\x21\x7b\x43\x5f\x93\x96\x5a\xfd\x4a\x75\x4b\xcf\x3f\x3e\x63\xab\xb4\x9e\xef\x79\x7f\x3e\xf4\x0c\x15\x16\x6f\xff\xe3\x79\x4c\x5f\x03\x88\xf1\x91\x2c\x55\x9d\xcb\xa6\x33\xf9\x75\x3a\x7c\xe9\x81\xc0\x80\xe1\xeb\x53\x73\xa8\x94\x1b\x33\x83\x27\x8f\x7a\xdb\x14\xa8\x9e\x0d\xa8\x91\x7a\x06\x68\xd5\xd3\x0e\x7e\x21\xc4\x42\x6b\x83\x80\x6a\xcc\x2b\x14\x1f\xbe\x75\x1b\xdb\x94\x56\x05\x84\x75\xb8\x40\xae\x5b\x47\xf8\xca\xc3\xd1\xfd\xdf\x51\x17\xdd\xe6\x62\xa8\x16\x7b\x9e\x03\x7e\xcf\x9e\x5f\x55\x03\x1e\xe9\xf5\x58\xce\xd4\xd3\x69\xdb\xaa\x2f\xed\x5e\xe8\xf8\x14\x00\x68\xf4\x04\xd9\xef\x29\x63\xfc\x9d\xa0\xaf\x27\x56\xcc\xf0\xff\xcf\x2b\x0e\x41\x98\xe6\x5d\xb8\x06\x19\xf4\x1d\xf7\x26\xc9\x94\x9b\x24\x35\xfb\x52\x4c\xdb\xf6\x93\x5e\x2d\xf1\xd5\xa5\x85\x45\xf2\xe2\xc0\xe3\x02\xfd\xe0\x79\xa8\xa8\x3c\xca\xcb\x46\x65\xe5\x02\xa5\xa3\x71\xfc\xd4\x92\xe6\xdd\xfd\x46\x7e\x8d\xb8\x7b\xcf\xb3\xd2\xfa\x25\x1d\x65\x47\x80\x8a\x7f\x94\x35\x47\x99\x73\x3c\x0e\x51\x87\x5e\xf9\xd2\x65\x50\xdc\x8f\x72\x25\x6b\x59\x2e\x6c\x99\xea\x3a\x6f\x8e\xae\xb3\xa6\xfc\x5f\xea\xe8\x52\xca\xf2\xc8\xac\xfc\x79\x23\x97\x47\xc7\x47\xcd\x76\x23\x6b\xca\x3a\x39\xac\x5f\x94\xc5\xc0\x57\x1d\xb0\x3b\x6f\x7e\x23\xae\x5a\x41\x72\x22\x63\xe5\x2b\xf9\xb5\xab\xe4\x60\x66\xc7\x99\xa3\x86\x1b\xe4\xad\xae\xdd\x91\xbc\x03\xeb\xaf\x2e\x6f\xbd\x6d\xd4\x91\xcc\xd5\xb5\xac\x8f\x2e\x25\x20\x6a\x1c\x55\x75\xd0\x42\x1c\x3c\xbb\xc8\xd8\xad\x43\x33\xe9\x7b\xd2\xea\xbb\xa8\xad\x50\xe4\x9f\xb1\x37\xf9\x6e\x51\x95\x8d\xaa\xb7\x0b\x55\xd5\xf1\xce\xc0\x94\x71\x59\x6e\xd7\xb2\xce\x2e\x0b\x19\x8f\x4e\xf9\x6d\x8d\x1c\x2d\x06\xee\x66\x95\x5f\x6d\xcd\x3d\xc0\x75\x57\x51\x44\xcd\x3b\x1a\xa9\xde\xd8\xa2\x5f\xaf\x92\xc1\x54\xe4\x56\x93\x93\x8b\x0b\xa8\xc5\xc5\x85\x9e\x6f\x7a\x68\xbe\x1d\xd4\x9f\x16\x94\xe9\x95\xd4\xad\x3b\x86\x41\x1b\x8c\x80\x92\x97\x7b\xfe\x5c\xbc\xa5\xe4\x95\x11\xc5\x84\xf1\xf7\x83\xca\x33\x78\x09\xd5\xb2\x74\x00\x5c\x93\x3e\x0e\xc6\xf3\xc9\xf3\xaa\x6c\xf4\x77\xe3\x9a\x3a\xb8\xb0\x25\x40\x65\x7d\xf8\xf0\xef\x6e\x1d\xd6\x3b\x9b\xdf\x3b\x55\x70\xe3\x42\x51\x67\xdf\x9d\xfd\x60\xa3\x71\xdc\xcc\xac\x0e\x96\x3d\x9e\x0b\xcb\x51\xc0\x33\x31\x9d\x65\x4f\xab\x59\x36\x1e\xb3\x3c\xcd\xe6\x81\x1c\xc9\x9c\x03\x40\x29\x6a\xf1\xca\x38\x0b\xc0\x8c\x35\xc6\x45\xc9\x0d\x2c\xb9\xd9\xb1\xe7\x8c\x31\x5e\xa3\x9a\x23\x76\x16\xc1\x08\x9d\x07\xf0\x82\x32\x5e\xcb\x55\x13\xef\xb6\xa5\xd1\x1c\xc1\x96\xb1\xe7\xaf\x68\xcd\x4b\x27\x72\xbe\x06\x47\x1a\x1e\xca\x0d\x5f\xc6\xa1\xd3\x1d\xc6\xe7\xd4\xd5\xa6\xb1\xaa\xcc\xcc\x61\xe5\x19\x55\x4e\x7a\x71\xeb\x54\x08\xaf\xd1\xec\xf7\x9d\x77\x2d\xac\x85\xe7\x45\xbe\x7c\xae\xf5\x9f\x43\x4b\xcb\xe8\x57\x2a\xad\xe0\x91\x33\xbd\xe6\x1f\xd4\xc1\xbd\x91\x81\x03\x66\xce\x77\x66\x89\x02\xc8\xdd\x87\xdf\xf8\xd3\x66\x99\x85\xbc\xda\x48\x80\x6e\xb1\x90\x5c\x9d\x0d\xfb\xb0\xd9\x88\xf4\xef\x1a\xf2\x90\x6e\x85\x06\xf5\x7a\xfa\x91\xaa\x9c\x55\xdb\x21\x27\x47\x1c\x62\xe1\xeb\x75\xa7\xf2\x72\xa8\x23\xca\x87\xde\xca\xd5\xc4\x0e\x02\x51\x4e\xf0\x47\xe7\x8c\xde\x68\x8d\x36\x28\x95\xb2\x89\xba\xee\x65\xa9\x31\xdc\xe4\x19\x78\x57\xe5\x55\xf9\xb2\xce\xd6\x5d\x6a\x7b\x39\xd9\x96\x6b\xfd\x15\x72\x09\x4e\xe2\x52\xa1\x82\x7b\x68\x0a\x76\xe3\x55\x76\xc6\xab\x39\xd9\x33\xff\x1b\x6e\xa9\x9f\xf3\xa2\xf8\x09\x5f\xf3\xc0\xe0\xf4\xad\x34\x83\x6b\x57\x29\xf0\x92\x76\x0d\xd1\xef\x8b\x5a\x96\x4b\x59\x7f\xb4\x4c\x53\x6b\xdb\x1d\xd8\xf8\x9f\x22\x95\xde\xd4\xd5\x4d\xbe\x94\x35\xb7\xd2\x79\xcf\xfd\xb2\x12\x6c\x3e\x50\x34\x29\x1b\x72\xc1\xd5\x9e\xea\xe2\xbc\x05\x76\xf6\xbb\xb5\x33\xe9\x55\xbd\x11\x3b\xab\x62\xbe\xc6\x40\xaf\x9f\xb5\x20\xfd\x2a\x6b\x24\xe1\xbb\xcb\xac\x91\xc6\xe4\xc9\xf5\x6f\xad\x5e\xe9\x8b\x3d\xe3\x2f\x86\xcc\x36\x87\x15\xff\xf9\x41\x71\xaa\x3e\xf2\xd4\xfb\x7e\xe6\xf2\x23\x99\xbf\xe2\xef\x00\x98\x8c\x97\x5c\xfa\x9e\xff\xea\x61\xe1\x6b\x4a\x72\xb2\x97\x3b\x61\x39\x48\xe2\xfc\x31\x31\xf7\xd1\x1e\x87\xce\xe5\x3d\x9b\x4d\x20\xd9\x6a\x21\x27\xb6\x55\x81\x7e\x64\x53\xe7\xeb\xac\xbe\xe7\x59\xb0\x52\xf1\x46\x50\xcc\xa6\x65\x52\x30\x8a\x19\x5f\x78\x25\xb8\x49\xc8\x32\xbf\x21\x71\xc3\x0b\xa1\x75\xbe\x94\xd8\x57\x12\x4e\xec\x0b\x09\x27\xf6\x75\x84\x13\xf3\x32\xe0\xcf\xc0\x57\x99\xfb\x68\x27\x73\xef\x21\x73\xc6\xb7\x02\xc6\x90\xc9\x37\x51\x15\x2e\x48\xd9\x43\xe6\x49\x5c\xb3\xff\x41\xeb\x70\xd1\x96\x76\xdd\x29\xd9\x9e\x01\xe9\xf8\x52\x28\x67\x43\xe2\xd7\x62\x43\xb7\x7c\x89\xb0\x2e\x58\xc4\xa5\xb8\x46\x68\xa7\x06\xe0\xe5\x74\x03\x9c\x89\x6b\x3c\x0b\xe1\x57\xf6\x97\xe5\x2d\x15\x67\xce\x80\x5a\xc7\x67\x50\xb0\xb7\x22\x9e\x3f\x7e\x74\x02\x74\x61\xba\xdc\x7b\x01\x23\xe6\x92\xef\xf4\xe0\x5e\xfb\x25\x46\x0d\x18\x13\x3a\x60\x69\x54\xeb\x2d\x6b\x66\x90\xd6\x6f\xa0\x59\x20\x86\xd8\x0e\xc6\x2b\x7e\xcf\xaf\x7a\xd3\x3a\x39\x1c\xb3\x2f\xf8\x2e\x78\xa9\xe9\x8a\x38\xdf\x1f\x3c\x6b\xbd\x1c\x18\x7f\x26\xf2\xe4\x97\x78\xc1\x2f\x44\x9e\xbc\xa3\x87\x35\x77\x1d\x16\x2f\xf6\xbc\x60\x71\xf1\xb0\x34\xf9\xf9\x40\x9a\xb8\x99\xbe\xf6\xf3\xbc\xde\xef\xf9\xe1\xb3\xcf\xf8\x05\xbf\xf1\x73\x02\xcf\x36\x8c\x90\x79\xb3\xad\x65\x20\x68\xbe\xea\x09\x1a\xfb\x99\xa3\x29\x4a\x9a\x37\x5a\xd2\xbc\xac\x16\xdb\x86\x30\xfe\xcb\xa0\xbe\xa6\xbb\xbc\x0c\x27\x50\x2d\x82\x29\xc0\x73\x33\xd8\x71\xc8\x06\x43\x3e\x1c\xbd\x0f\xb7\xc3\x9b\x4f\xd0\xf5\x0e\x9f\xfa\x0e\xe5\x4d\xae\x95\x66\xdb\xe4\x35\x37\x6b\x1b\x7c\x4e\x2c\xf1\x1c\xce\x77\x4f\x69\xc5\xd2\x6f\x7a\x05\xf9\x51\x4c\xf9\x77\xff\xbf\x52\x0e\xf7\xbc\x9e\x84\x5f\xd8\xa9\xfc\xc8\x64\x9b\x34\xd7\xd5\xb6\x58\x42\x86\x28\x02\xf3\x2b\x78\xd1\xe8\x65\xf2\x01\x85\xf1\x4a\xaa\x17\xb2\xce\x6f\xe4\x12\xd6\xf9\x97\x75\xb5\xc6\xc1\x72\xa0\xc1\x19\x68\x44\x3d\x22\xec\xb9\xd6\x3b\xba\x0b\xde\xa8\x87\x15\x97\xcc\x1d\xa1\x6d\xeb\x7c\x64\x1e\x00\xfb\xf8\x81\x59\x1b\x62\x70\x0e\x52\x75\xad\x0f\x12\xc1\xeb\x6e\x5b\x3b\x47\xaa\xde\x9b\xcb\xb6\xad\xf7\x80\xd3\xf9\xc9\x9a\xd9\x8f\xe3\x31\xea\xa0\xae\x85\xfe\x8c\xaa\xa2\x45\xfe\xf1\xf1\x8f\x51\x44\xf5\x78\xfa\xb3\xca\xa9\x3c\x50\x4a\x51\xe6\xf4\x94\xd1\x81\x3e\x7d\xb8\xc6\xab\xee\xa8\x18\x50\xf5\xc3\xe1\x33\x93\x89\xf4\xe0\xdd\x2c\xfe\x2d\xf9\x4d\x8c\x4e\x63\x97\x62\xc1\xbb\xf5\x6f\x50\x99\xb2\xbc\x6c\xa8\xb3\xb8\x23\x7a\x88\xb5\xb8\xa3\xe3\x0a\xe6\x35\x75\xfb\x13\x7a\x59\x47\x13\xe3\xa5\xa0\xca\x2f\xbd\x0a\x1d\xc9\x18\xaf\x75\x72\xf8\x01\x5c\x85\x0b\x71\xee\x17\xe2\xda\x2c\xc4\x35\xcf\xf4\x33\x7a\xf0\xf9\xa1\xc7\xef\xa8\xe2\x69\xb8\xde\x42\xf9\x40\xb2\xea\xcb\xee\x88\x2f\xde\x97\x6d\x73\xf6\x11\x81\x96\x6b\xd1\x04\x65\xc6\xef\xe8\xae\xda\xaa\x22\x2f\x65\x4c\xca\xaa\x94\x64\xcf\x4b\xc6\x1d\xfb\x2e\x39\x3e\x25\x7a\x6f\x17\x0f\x45\x2f\x40\x5b\x0a\xb5\xdf\xf3\x8c\x0d\x2c\x01\x6f\x0e\x96\x0f\xc3\x1a\xe9\xbf\x61\xcf\x07\xd4\x5b\x36\xa8\x8e\x1a\x18\x93\x62\xb2\xa9\x8a\xfb\x55\x5e\x14\x8c\x7e\x87\xb3\xf8\xdb\xce\x21\x09\x7f\x09\xab\xed\xaa\xaa\x6f\xb3\x7a\xf9\xa3\x5c\xcd\x06\x0f\x6e\x5e\x46\x11\x7d\x39\x78\xa4\x68\xb0\xd2\x7f\x12\x2f\x87\xd5\x15\x13\xd7\xf5\xa3\x5c\xf1\xda\xac\x2b\x36\xe1\xa3\xab\xc8\xc3\x2a\x2e\x04\x28\xdb\xf5\x14\x5e\x9e\x0b\xa7\xcb\x3d\x5c\xe0\x81\xf6\x2b\xad\x45\x34\x58\x08\x9b\x50\x93\x5c\x88\x7a\xa2\x2a\x5e\x08\x23\x89\xf9\xc6\x53\x92\xf2\x25\xba\xc1\x83\x5c\xe5\xd7\x7e\xa8\x2e\x93\x6f\xe3\x25\xbf\x14\x77\xb4\xe6\x29\x51\x15\x0c\x47\x54\x13\xed\x71\x01\x27\xf6\x41\xad\x05\xae\xc5\x8a\x2e\x78\xce\xf8\x99\xa7\x5c\xa0\x6b\xc6\xaf\x44\x16\x4a\xca\x33\x7e\x2f\xb6\xd4\x27\xf1\xb3\x8f\x34\x1e\xc9\x88\x1e\xb3\x7a\x24\xea\x3d\x0b\x27\x59\x9d\x67\xc7\x8b\x6d\x5d\x03\xd0\xd2\x55\x02\x8e\xd4\xc4\x45\x0e\x5c\xf2\x6b\xba\xcb\x9b\xe7\x98\x21\xbe\xe2\x79\xf3\x26\xab\x55\x9e\x15\xc5\xbd\x4d\xbc\xc7\x63\xc5\x40\x3b\xca\xf6\x8c\xef\x4c\x62\x55\x3e\x2f\xf2\x30\x58\x16\xa3\x35\x2e\x27\xe6\x46\x14\xb9\x9f\x54\x32\xfe\x77\x2a\x99\xee\xc6\x3e\x25\x12\xc6\x5f\x88\x0d\x9c\x01\x1d\x7a\xf0\x6e\xa2\xe8\xca\x0e\x2c\x50\x17\xcc\x71\x12\xc8\x92\x72\xf2\x5e\xde\xf3\x3b\x5a\xf2\x94\xbc\x97\xf7\x30\xa7\xd5\xa0\xd9\xcb\x98\xce\xde\xcb\xfb\x26\xf4\x5b\x30\x8b\xbf\x10\x9d\x0c\x8a\x39\xbf\xe2\x72\x22\x6f\x64\x7d\x4f\x87\x76\x50\xaa\x67\xd4\x05\x98\x22\x99\x96\x73\x81\x48\xec\x5a\x4f\xa1\x50\xe7\x82\xf1\x9a\xed\x1b\xba\xe6\x06\xbc\xab\xb0\x66\xfb\x58\xed\x31\x80\xd9\xfd\xcf\xdb\x9c\xff\x09\x81\xd4\xb0\x6d\xae\x73\x21\xf7\x3f\x75\x8c\x75\xe4\x55\x5e\xbe\x27\x18\xf7\x3c\x38\x4d\x43\x63\xf1\x3f\xf7\xfc\x9b\xff\x2b\xfb\xb8\x4f\xb4\xa2\x04\x5b\x3a\x37\xf7\xb4\xe0\x50\x95\xee\x56\x39\x59\xd5\xd5\x9a\x3b\xdf\x05\xc6\xab\x60\x61\x68\xdb\x1a\x39\x26\x61\x82\x66\x02\xa8\xc9\xdf\x5d\xd7\xd5\x2d\x77\x32\x81\xf1\xc6\x48\x9e\x60\xcf\x06\x33\x53\x97\xdc\x99\x98\x76\xaa\x9a\x32\x82\xbd\xdb\x9c\xcd\x3e\xc1\x16\x83\x1f\xb5\xa2\x25\xcf\xd8\x4c\xd1\x25\x30\x0d\x78\x9b\x57\x65\x8e\xd9\xf3\xfd\xa1\x21\xe5\x93\x36\xbd\x34\x68\x22\xdd\x40\x4c\xaf\xad\xfd\x16\xe2\xb6\x39\x5c\x5b\x30\xb7\x2b\xd6\x4b\x67\xf5\xdf\xd1\x1a\x3c\x17\x2b\xaa\x3c\x71\xc2\x51\xef\xd0\xc6\x5b\xdf\xf5\xc8\xdd\xd3\x25\xb8\x4b\x31\xde\xd9\xda\xf8\x05\x8b\x7f\xff\xdf\x60\xf9\x30\x44\x59\xff\xc1\x5a\xf0\x31\xb3\xc9\x37\xd6\x12\xe2\xb6\x73\xe5\x3e\xb4\x89\x3c\xfa\xb3\xae\x36\x7b\xfe\x0f\xf7\xc8\x91\x0c\xde\x1d\x8a\x95\x7c\x45\x47\x65\x87\xcd\x49\xab\xeb\xe8\x6c\x2b\x60\xcd\x7e\x59\x67\x57\x6b\xc0\x03\x29\xfb\x2a\x41\xf0\x2d\xce\xbc\x00\x5c\x2a\xbd\x8c\x5c\xbf\x9d\x61\xc9\x78\x47\x2f\x2f\x6d\x6b\xaf\xcc\x4e\x53\x27\x98\x17\x7f\xef\x3c\x02\x39\xa6\x8d\x20\xcd\x3e\xa0\x87\x90\xaf\x8f\xaa\x86\x73\x0f\xc9\xe4\x81\x36\xbc\xd4\x03\xc7\x47\x59\x48\x47\x78\x53\x1a\x9f\xa9\xc0\xb9\x4c\x08\x71\xaf\x45\xf5\xc3\x39\xf6\x34\xac\x24\xf7\x75\x64\x61\x25\x3b\xdf\x6d\x21\x34\x0c\x69\x0c\x37\xc9\x6e\xab\x5d\x0b\xdf\x2e\x49\x58\x7a\x1c\x36\x27\xcf\x05\x7a\xfb\xd5\x89\x8a\x1f\x51\xc5\xc6\xe4\x84\x8c\x1f\x51\x37\x75\x0e\xca\xef\x55\x83\x83\xe1\xa0\xdf\x77\xc9\x23\x9a\xeb\xa2\x1e\x93\x38\xdf\xef\xf7\xfc\xef\x43\x50\x57\xd2\x1b\x0b\x0c\x97\x20\x42\x42\xc8\x09\x52\x6a\x45\xd1\x88\xca\xc9\x5a\xaa\xec\x7b\x79\xdf\xb6\x72\x92\x15\xca\xfc\x5a\xa8\xba\x30\x3f\x01\xfe\xf2\x7b\x79\xcf\xf6\x5d\x4f\x65\xd3\x77\xb3\x72\xc0\xf9\x1a\x02\x92\x29\xba\x60\x94\xa2\x6c\x5b\x2d\x0a\xac\x4b\x39\x25\x41\x2e\xc2\x68\x40\x3a\x76\x18\xd6\x8d\x8e\x0c\xe0\x9b\x8f\x3f\xd9\xde\xfb\x71\x97\x87\xbe\xd3\x3d\x4d\xd1\xe6\x0c\xaa\xd8\xf1\xae\xb6\x70\x2a\x6e\x46\xd6\xc1\x47\x98\x35\x0f\xa4\x85\x5f\xf3\xfc\x69\x64\xf5\xd0\x1a\x0b\xe6\x83\xb6\x25\x29\x7e\x0e\x5e\xcf\x89\xd7\x2d\xbc\xe0\x57\x15\xd2\x67\x98\x63\xe0\xa0\xf4\xbc\x07\xf5\x3f\x02\x7a\x75\x5b\x24\x16\xf4\x67\xcb\xcc\x82\x32\x7d\xcc\xac\xbf\xdf\x04\xfe\x8e\x07\x4e\x38\x32\xf8\xa2\x1f\xe0\xe6\x9f\x7d\xfd\xe2\xa1\x06\x7b\x91\xa9\xb0\x74\x7d\xf9\x67\xcb\x2e\xfa\x84\x67\x48\x8b\x23\xa6\xb3\xf2\xa9\xb4\xde\x02\xe3\x71\xc9\x6a\xe3\x9c\x45\x81\x1b\xac\xf4\x7b\xbf\xda\x17\xb6\xed\x98\x28\x3f\xf1\x04\x5f\x05\xb5\xd9\xf4\x1c\xda\x91\x9d\x67\x0b\xc4\x4c\xe0\x62\xd0\x67\xe1\xd1\xb7\x88\xfd\x3a\x82\xbc\xa2\xf6\x12\x02\xaf\xf1\x27\xe3\x90\x11\x64\xc6\xeb\x95\xc9\x67\xae\x84\xb2\xbf\x18\x0f\xfa\x74\x75\x10\x92\x73\xeb\xb8\x95\xf8\x68\xca\x26\x5b\xb5\xa0\x41\xd5\x97\x87\xfc\xec\x93\x8b\xcd\x0a\xde\x74\xb1\x59\x89\x9d\x5c\x6f\xd4\x7d\x3c\x3a\xe5\xdb\x72\xdb\xc8\xe5\xbb\xea\xbd\x2c\x9b\x38\x9d\x9b\xeb\xef\xca\xcd\x56\xe9\xcb\xea\x46\xd6\xab\xa2\xba\x8d\x8f\x9f\x70\x80\x11\x7a\x25\x57\xea\xf5\x8d\xac\xe3\x29\xac\xc0\x98\x71\x74\xca\x73\xe4\x07\x3c\xab\x4a\x2d\xe9\xf4\x6c\x33\x29\x2f\xab\x7a\x9d\x41\x96\x6d\x23\x6b\x43\x23\x88\x94\x9d\xa7\x3c\x6f\x2a\xfd\x07\xa2\x42\x96\x7a\xc4\xe8\x4d\x0b\xd4\x63\x2d\xeb\x7c\x99\xcb\x35\x96\x55\xaf\x16\x4f\xfe\xeb\xc9\x13\x38\x6e\x97\xf2\xfd\x32\xbb\x3f\xcb\x1b\x20\x74\x88\x47\xa7\x7b\xc6\xe1\xab\xfc\xe7\x5f\x9b\xcd\x8b\xfb\xf4\xbc\xf9\xa7\x7e\xad\x35\xa0\xea\xe6\xe1\x5a\xf6\x23\x80\xe2\xa4\xf7\xfe\x07\x69\xee\x47\xe0\xe5\xc5\x2b\x61\xe3\x59\x26\x17\x4b\xbd\x87\x7c\x97\xaf\x25\x65\x2c\x8a\xd4\xc4\x36\xd8\xd3\x29\x70\x2d\x42\x3b\xc3\xaf\xb0\x81\xc2\x84\x9f\xf1\x7b\x20\xa9\xf7\x6d\x90\xe6\x5a\x39\x7c\x08\x1b\x15\x52\x7a\xad\x1a\x45\x74\xa4\x26\xb6\xf5\xda\xd6\xff\x8e\xa2\x9a\x21\xe4\xd4\x05\x4a\x4e\x04\x61\xc5\xe5\x44\x4d\x3a\xbd\x6b\x13\xc3\xd1\xe1\x36\x51\x4e\xe8\xa8\xc9\x65\x7e\xf5\x6d\xb5\xad\x2d\x8e\x80\x99\x64\x79\xf3\xb2\xae\x3e\xc8\x32\x8a\x7a\x09\x41\x28\x56\x35\xf3\xdd\x22\x2a\xe7\xa4\xe3\xd2\x7c\x67\x5e\x7a\xc3\xf7\x8a\xfe\x90\xfd\xd0\x63\xb8\x97\xc9\x86\x2e\xa9\x62\x5c\xb2\x58\xff\xed\x37\x88\x18\x4d\xb9\xda\x97\x26\x84\xca\xcf\xff\xa6\x5a\xcb\x64\x28\x31\x1e\xf6\x5c\x32\xf6\x18\x8f\xfd\x69\x9c\xef\xbe\xfc\x72\xca\x6b\x31\x9d\xd5\x4f\x4b\x4b\x67\x0f\x5e\x44\x80\xf2\x16\x00\x8b\xa6\xf5\x9c\x03\x8b\xa8\x59\xd8\xa7\xd6\x95\xe6\x14\x55\x91\xb5\xa8\x27\xeb\x4a\x2f\x4f\x46\x26\xe5\xb2\x01\x09\x68\xdb\xe1\x6c\x20\x04\x2e\xa3\x4a\xb7\xd8\xb3\x33\x78\x10\xab\x88\x61\x52\xfd\x54\x31\x90\x91\xe3\xe3\xf6\x01\xc8\x62\x12\x57\x26\x51\x0b\xa4\x8b\x95\x49\x2c\x4c\x62\x21\xe0\x02\x13\x71\x2c\x99\x3b\x78\x21\x7c\x32\xe6\x51\x1f\xd6\x26\x83\xfa\xb0\x16\x26\xc1\xbc\xbd\xf9\xe9\xdd\x73\x57\xe5\x9f\xde\x3d\x17\x2e\x11\x33\x60\xa0\xab\xc9\x61\x80\x42\x7c\x32\xe6\xd9\xd8\xea\x6e\x56\x42\x8f\x01\x5b\xdf\x6a\x91\x15\xd2\x56\x1a\x2e\x84\x4f\xe6\x6b\xe7\x3f\xc9\xfc\x32\x63\x13\x67\xe5\x78\xcc\x32\x5a\x09\x95\xd6\x62\x9d\x96\xf3\x39\x94\x03\x51\xdf\xfe\xe8\x0e\x3c\x73\xae\xc4\xe8\xd4\x77\x93\x56\x73\x77\x67\x66\xc7\x8d\xb0\x2e\x93\x8b\x25\x38\x90\x6a\x01\x43\xcd\xa8\x9d\x5c\x2c\x93\xae\xf8\x88\xf5\xd8\xc6\xfc\x66\x0e\x50\xfd\xca\x83\x02\x74\x36\xc3\x01\x72\x15\x45\xf4\x4a\x0f\xf0\x7a\xb2\x05\x8b\x76\x00\x88\xc1\xf8\x15\x80\xfc\xb9\x8a\xdd\x3c\xb4\x70\xdf\xe3\xa1\x38\xe8\x26\xae\x76\xbd\xb1\xe2\x8b\x79\x16\x16\xf3\x74\x9a\x40\xc8\xd4\x42\xe6\x05\xd0\x81\x4e\x63\xb8\x5e\x15\x55\x55\x77\x96\xf6\x0b\x3f\x8b\xc7\x92\xeb\xb6\x36\x65\x00\xd1\x5d\x14\xe5\xcd\xcb\xbc\xcc\x95\x44\x5c\x93\x52\x3c\x83\x6e\x0c\x3c\xe7\x6e\x7b\x50\x30\x26\x56\x2b\x2f\xa9\xd5\x0c\x7c\x64\x1a\xcf\xf1\x6e\x76\xd9\xb8\xbb\xc7\xfe\x6e\x26\xa6\xa0\x58\xe0\xb4\xad\x60\xda\xd2\x32\x8a\x74\xef\x02\xed\x5e\x3d\x6f\xdb\x51\x19\x45\x17\xd0\xe1\x0c\xe9\x5c\xf5\x2f\x16\x45\x99\x87\x88\xcb\xc6\xb9\xaf\xdf\x07\x38\xf2\x39\x85\x28\xf2\x66\xbb\x01\xf7\xb4\x17\x72\x53\x4b\xb4\xb5\xfd\x9c\xd5\x65\x5e\x5e\x35\x51\x14\x98\x67\xbd\x5d\x6c\x51\x95\x4d\x55\xc8\x28\x32\x3f\x26\xb7\x59\x5d\x76\xaf\x28\x09\x8a\x3b\xba\xc5\xf2\x90\x8b\xd7\xd7\xe2\x75\xb8\x23\x73\x32\xe6\xa8\x0b\x1b\x61\x56\xc6\x91\xa8\x27\x4b\x5f\xa4\xa1\xae\x8e\xa2\xa1\x54\x54\xa0\x25\x0b\x39\x25\x2a\x9e\x8b\x74\x6e\x8e\xd7\x0e\x9c\x3a\xb3\xf1\x18\xde\x54\x09\x42\x06\x68\xfe\xc3\x33\x38\x5f\x64\xa3\x25\x67\x35\x16\xe4\xbc\x4c\xc9\x38\x1b\x93\xf9\x11\xe1\xa1\x17\x33\xab\xc6\xa2\x19\x13\xfd\xd9\x61\x72\xda\xcc\xc7\x84\x1f\x91\x59\x25\x2a\x17\x82\x76\xfc\x84\x61\x38\x5b\xd5\x3d\xf1\xcb\x2d\x70\xda\xfe\x03\x95\x63\x72\x5e\x3e\xb3\x77\x75\xb1\x07\x4b\x82\x2e\x0d\x05\x79\x6e\x37\xa3\x84\xe9\xc7\xc8\x18\x88\x99\xc1\x2f\x91\x4d\x1a\x95\x2d\xde\xeb\x95\x61\x74\xba\xef\x6d\x3e\x7a\x06\xb7\x3d\x9c\x93\xeb\xcf\x7d\xc7\xef\xc0\xfb\xb4\xe7\x1d\xfa\xa7\x3b\x07\x30\x20\xee\x52\x39\x6f\x5b\xfa\x81\x9a\xdf\x70\x02\x16\xba\x86\x0e\xcf\x7e\xbb\xa3\x0b\x54\x77\x9b\xf4\x67\xd5\xf7\xaf\xbb\xea\x3b\xf0\xe2\x49\x16\x52\x5b\x3a\xe5\x39\x07\xf5\x19\x10\xeb\x40\x85\x4e\x68\xad\xd5\xe9\xdd\x9e\x6f\xe0\x17\x90\xfe\x32\x7b\x01\x59\x58\x6c\xc0\x8a\xd2\x72\x9e\xd4\x56\xf9\x8e\x0d\x37\x52\x0d\x8a\x78\x40\x1d\xbc\x85\xd8\xfe\x28\x1a\xd9\x77\xba\x57\xe2\xab\xa0\x76\xf0\xd4\xd0\xe6\xe1\xad\x6e\x2e\x27\x15\x0d\x65\x30\x04\xb6\x7d\x74\x76\x23\xa1\xcc\x61\x0f\x21\x66\xe6\xbb\xd0\x2c\x9d\x04\xbf\x0f\xfd\xaf\x79\x69\x77\x3f\xca\x7f\x8e\x16\x8d\x3e\x2c\xc5\x39\x17\x23\xd5\x6d\x67\x20\xbd\xef\x1e\xe0\x74\x88\x45\x66\xcf\xf5\xe7\x3f\x4f\xcb\x31\x69\x88\xfe\xa1\xe6\xe1\xf6\xf1\xf7\x60\xfb\x78\x08\x4a\x99\x3c\x87\x51\xf6\xfc\x80\xfe\xce\x9e\x44\xb8\x72\x7e\x0e\xbe\x85\xd7\x22\xa4\x38\xf5\x9d\x43\x95\xf8\x9d\x96\x0c\x3b\x45\xd7\xa3\x43\x6a\x0a\x73\xe4\x45\xe7\xc3\xbe\xc2\x0f\x7b\x01\x44\x7b\xfe\x65\x6f\x3a\x8b\x83\x20\x64\xec\xe5\xbf\xd6\xd7\xd5\xb1\xa5\xc5\xb6\xe1\xea\xf2\x4b\x31\x4d\xca\x84\x8c\x49\x4c\x48\x4c\x8e\x09\xc3\x47\x36\xd5\x2d\x3d\x9d\x7a\x78\x8e\x29\xaf\x00\x43\xc8\x10\xad\x33\x1b\x02\x71\xca\xc6\x58\xbf\x5f\xc4\x09\x3d\x4f\xd3\x7f\x9f\xa7\xf3\xc7\xe7\x73\xd6\xd2\xf3\x73\x96\xd0\xf4\xdb\xeb\xf9\x7a\x4d\x9b\x86\x25\xed\x59\xd5\x9e\x9d\x25\xfa\xbf\xf6\x45\xd5\xbe\x78\x01\xff\x24\xfa\xbf\x76\xb9\x5c\x26\xcb\xa4\x5d\x56\x49\x7b\x9b\x56\xed\xed\x3c\x69\x7f\x4e\xab\xf6\xe7\x79\xd2\xfe\xa3\x4a\xda\x5f\xe1\xff\x5a\xff\x6f\xfb\xeb\xaf\xed\xd5\x15\xbd\xba\xba\x4a\x58\xd2\x7e\xf3\x0d\xfd\xe6\x9b\x6f\xf4\x2f\xd9\x7e\xdd\x66\xed\xb3\xf6\xfa\x3a\x69\xbf\xfd\x36\x69\xdf\xbf\x4f\xda\xf5\x3a\x69\x9b\x26\x69\xdf\xee\x4e\xf9\xdf\xf6\xed\x5d\xfb\x4b\xfb\xe1\x43\xd2\xfe\xeb\x5f\x49\x3b\x61\x27\x57\xfc\xb7\xc1\x8a\xbf\x7a\xf7\xb6\x7d\xf5\xae\x7d\xf5\x2a\xd1\xff\xb5\xc5\xee\x94\x7f\xbe\xd7\xd9\x7f\xd4\x93\xf3\xbb\x4e\x67\x7c\xdb\xa7\xf7\xad\x67\x87\x43\xa6\x86\x6d\xc6\xb0\x79\x29\xad\xe7\x54\x8b\x43\x19\x45\xf4\x3b\xdd\xa5\x15\xfa\x4b\x7f\x97\xaa\x74\x3a\x1f\x82\xed\x7c\x43\xab\x61\xa1\xca\x55\x7a\xaa\x05\xc5\x93\xb9\x2e\xb0\x84\x42\xca\xa1\x12\x60\x2e\xa3\x0a\xf8\x22\x53\x19\x65\x93\xaa\x5e\xe6\x65\x56\x3c\x58\xb2\x64\xfb\x90\xd9\xb7\x17\xde\xe9\x74\xb5\x84\x2a\xf1\x13\x30\xe7\x84\xa5\x33\xfe\xa3\x1e\xd8\xfa\x9f\xae\x79\xdd\x4d\x0d\x5e\x09\x69\xc8\x09\x7f\x41\x09\xa6\xc4\x94\x97\xa2\x72\xe1\x11\x4f\x4b\x08\x91\xf8\x2e\xad\x52\x35\x9f\x27\xfa\x5f\x61\x2e\x62\xb8\xa0\xb5\xd0\x7f\x2d\xc7\xe1\xc9\x79\x9a\x9e\x37\xe7\x6f\xe7\x27\x2c\xa9\xbd\x19\xfb\xdf\xe7\x69\x7b\x3e\x7f\x84\x26\xec\x38\xb8\x71\x7e\x8e\x69\xb3\xbe\x15\x5b\x59\x6d\x2b\x17\x84\x04\x2a\x93\xd9\xe9\x8c\xc5\x2b\x5a\x69\xb5\x28\xd1\xff\x9a\xcd\x8e\xde\x87\xe9\x4b\x5b\x58\xbe\xdf\xeb\x15\x49\x37\x80\xde\xfe\xc5\xdd\xe6\xb1\x1b\x5a\xd0\x6c\x83\x56\xfe\x29\x14\x60\x7f\x0d\x4d\x7b\x01\x5a\xe1\xa4\xa8\xca\x2b\xfd\x24\x6e\x87\x91\x8f\x1e\x62\xb0\x7f\x03\xd2\x1b\x38\xd2\xd7\x5a\xfd\x97\x62\x1a\x45\xbf\xd9\xd8\x64\x04\xbe\xb2\x5f\xff\x1b\xaf\x19\xef\xe4\xe7\xe5\xb1\x38\xed\xaa\xf8\xff\x14\x27\xe7\xcb\x13\xfe\xab\xfe\xa3\x7f\x7c\xa3\x7f\xec\x3e\xdb\x9f\xf0\xef\xe1\xd7\xe7\xfb\x13\xfe\x48\x9c\xa4\xe3\xe3\x79\x72\xbe\xdc\x7d\xb1\x3f\xe1\xff\xc0\xbc\xc9\x09\xff\x3b\xfe\x32\x57\xff\xf2\x57\x26\x45\x4a\x28\xe3\x94\xeb\xf2\x94\xbd\xd0\x45\x96\xd2\x97\x79\xca\x75\xa9\x35\xdc\x1e\x9f\xf0\xca\xdf\x1a\x9f\xf0\x5c\x8a\x93\x7f\xb5\xfa\x5a\x97\x19\x27\x50\xcb\xab\x9c\x67\x9d\x74\x9a\xc4\x78\x8b\x25\xfa\x66\xa3\x8b\x98\x1e\xff\x6d\xbe\x9b\xf2\x27\x7f\xfd\x62\x9f\xfe\xaf\xec\xf8\xc3\xf9\x76\x3a\x7d\x36\x3d\x3e\xdf\x4e\xff\xfa\xf2\xe5\xf9\x76\xfa\xbf\xa7\xfa\xe2\xc5\xff\xd6\x17\x2f\xff\x06\x17\x2f\x5f\x3c\xd7\x17\x2f\x5e\xc2\xc5\xcb\xe9\xff\xd6\xff\x9e\xe2\xc5\xd7\x2f\xe7\xbb\x53\x28\xad\x4d\xcf\xb7\xd3\x2f\xe0\x81\xe9\x17\x2f\x5f\x9e\x9f\xd8\x1b\xf4\xbc\x79\x9c\x74\x6f\xda\x5b\x4c\xff\xdd\x9f\xe4\x7c\x21\x3b\x82\xa6\x90\x56\xbe\x2f\xa4\x16\x13\xaf\xa8\x62\x49\x07\x24\xb2\x0e\x43\xcc\xcb\xa4\x8c\x55\xc0\x43\xbe\x95\x9d\x39\xbb\xa5\x0b\xc9\x25\x4b\xa0\x2c\xbf\x85\xe5\x7e\x6b\x18\x63\xd4\xcc\xd5\xd7\x77\x1b\x0a\x84\x03\x76\xb0\x90\xf3\x73\xc2\x43\xfe\xd2\x93\xf3\x73\x7a\x9e\xb2\x56\xff\x99\xb3\xf6\x3c\xa5\xe9\xbf\xcf\xe7\x5a\xa4\xb2\xf3\xb9\x4e\x05\x51\xdb\x85\x87\xee\xd2\xe1\xa8\xb6\x45\x38\x84\x6a\xcf\x18\x0b\xcd\x8f\x72\xf8\x34\x2a\x3d\x3e\x3f\x39\x3f\xff\xf7\xa3\xc7\xe3\x64\x42\x59\x9b\x9e\xcf\x77\xfb\xb9\x9e\xc0\xe7\xe7\x8f\x22\x82\x8a\xe5\xaa\xdb\x7e\x4b\xd9\xd5\xcc\x14\xcc\xe5\x81\xe5\x1d\xe0\xfa\x52\x39\x67\xbc\xc1\x8d\x58\xdd\x83\x4a\x02\xf4\xa4\x0b\x60\x33\xe1\x3d\xbb\xac\xde\x30\xaf\x64\xaa\x97\xf0\xb9\x08\x54\xa9\x6b\xf3\x72\xa8\x44\x07\xcd\xcc\xb4\xc3\xe4\xe2\x56\xe8\x7f\x80\xbf\x58\xe9\xce\x9c\x5c\xdc\xc2\xbd\x7d\xd8\x1e\x97\x6e\x10\x18\x3d\x30\x8a\xb6\x74\xa5\x7b\x32\x8a\x56\xd8\x95\xbc\x9c\x5c\x64\xe0\xef\xec\x1f\x5b\x87\xcd\x78\xa6\x2f\x92\xcf\xbe\xf8\x22\xfe\xec\x8b\xbf\xfa\x3c\x67\x9d\xa6\xfe\xcb\xe7\x42\x68\x81\x21\xff\x72\x3a\xd5\xbb\xd3\x69\xdb\xca\xbf\x7c\x3e\x9d\xea\xd4\xfd\xb7\x94\xfc\x4a\xf8\xff\xcb\xdc\xbf\x70\x37\x8d\x6b\x8d\xe3\xf0\x57\x49\xf5\x1c\x32\x52\xa3\xa4\x49\x5b\xca\xe0\x22\xb2\x3a\x94\xdb\x1c\x42\x99\x69\x19\x06\x42\x4e\x97\x1b\x2b\x8d\x21\x91\x33\xb6\xd2\x52\xea\x9c\xcf\xfe\x2e\x6d\x5d\x2c\x3b\x4e\xe9\x9c\xf3\xbc\xcf\xff\x07\x6b\x35\xd6\x6d\xeb\x2e\xed\xbd\xb5\x2f\x5d\xda\xa5\xeb\xaf\xc6\x70\xb5\xdc\xf0\x30\xc5\x05\x87\xe0\x09\x7b\xfc\xf8\xf1\xe3\x3e\x42\x2d\x1e\xa0\x16\x6a\x01\x03\xf1\x15\xee\xd2\x21\xfa\xf8\x11\xd1\xdd\x51\x05\x92\x7f\x4b\x69\x50\xaa\x15\x7e\x21\x55\x6c\x5f\x15\x43\x2a\x1d\xf9\x09\x1f\x11\x7d\xb8\x21\xe5\x23\xa2\x07\x74\xab\xeb\xa7\x7e\xc5\xfa\x8b\xa2\x1b\x44\xe8\x2f\x36\xd4\x23\x74\xc6\xa1\x97\x09\x37\x9f\x1f\x11\xfd\x8d\x7e\xb4\x01\x15\x94\x9c\xfe\xb3\x08\x7f\x44\x54\x70\xfa\x0f\x2f\xc2\xc5\x44\x1c\xbb\xb6\xd9\xa4\x11\xed\x42\x82\x81\x55\x91\x3a\x52\x57\x3f\xd3\x36\xa2\x8d\xa2\x64\xaa\x19\xb4\x67\xd7\xc9\x71\x7c\x19\xcb\x8f\x6a\x58\x38\x09\xf4\x32\xb4\x90\xea\xe1\xd4\x17\x75\xa5\xea\x0b\x41\x91\xd7\x42\x2d\xc5\x5e\x17\x32\xd7\x80\xa9\x7b\xef\x54\x2d\x6a\x61\xf5\xf7\xe9\xc1\xcf\xfd\xde\xe3\x6e\x37\xd8\xe5\x7b\x44\x63\xe8\x97\x9c\xde\x70\x76\xc5\x31\x7a\xb1\x9c\xcd\x3e\xc2\x58\x6f\x75\x3d\x01\x91\xab\xf2\x31\x55\x23\xa2\xa2\x17\xbe\xe8\xe3\x73\x6e\x8d\x9e\x0a\x52\xc7\xfc\xb1\x8e\x99\x49\x70\x64\x73\x12\xef\x40\x3c\xe2\x1b\x91\x18\xde\x39\x8f\xb4\x77\xaf\x96\x63\xc9\xf5\xd1\xfb\xb3\x67\xe0\x98\xb4\x25\x47\x9a\x51\xe5\x31\x76\xdc\xb6\xf4\xc0\x38\x8b\x4f\x80\xe4\x17\x1d\x66\xc0\xeb\x51\xdb\xcd\x2c\x6e\x62\x4d\x78\xce\x13\x21\xa7\xaa\xe0\xee\x63\x6b\x85\x9e\xbb\xe6\x64\x77\x34\x47\x50\x57\x98\x5e\x73\x3f\x08\xc8\xc6\x0f\x8b\xfb\x47\xcc\x35\x77\x72\xb5\x86\xc1\x4f\xf2\x5c\x7f\x39\xc6\x6d\xe3\x6d\xf8\xf6\xd0\x1e\xa4\x58\x3e\xc0\x82\xf5\x76\x49\x4b\x90\x07\x4e\x4f\x85\xb7\x18\x96\xed\x94\xec\xf4\x76\x29\x30\x84\xfa\xfa\xdc\xd9\x7d\x1c\xec\xfe\x1c\xec\xf5\xda\xe9\x83\x47\x0f\x76\x57\x97\x7c\x8d\x29\x6d\xd4\x4e\xd7\xf8\xd2\x26\xbe\xc6\xef\x97\xc1\x17\x0f\xe5\x13\x8d\xd8\xda\x37\x32\x49\xac\xe1\x58\x39\x52\x03\x6a\x5b\x6f\x8d\x7c\xb6\x7b\x2b\xfa\x0a\xa3\x01\xa2\x43\x34\x18\xc0\x41\x84\x06\x49\xad\x71\x29\x63\xb4\x0e\xc6\xb4\xd5\xd3\x47\x11\x1a\xa8\x42\xe5\x63\x90\xdf\x81\x63\x43\xf1\xec\x74\x0a\xbe\xc3\xcd\x7a\x74\x80\xfe\x03\x48\x3e\x90\xaf\x18\x41\x24\xa2\x68\xa0\x0f\x32\x13\xfc\x59\x1f\x48\x03\x44\x7f\x33\x5f\x03\xef\x20\x83\x7a\xeb\x8d\xb6\x48\xbf\xbd\xbf\xf3\x4b\xfe\xcd\x1c\x1a\xa6\xdc\x0f\x0b\xfa\x65\xe0\x04\x1c\xa8\xc6\x0d\xd6\xcd\x7f\x2a\xaa\x05\xee\xd3\x76\xaf\xc8\x3b\xd0\xb9\xd7\xf3\xfb\xb4\x96\xb0\xd8\x8a\xa9\xf2\x9d\x3a\xa0\xc0\x42\xaa\x70\xdc\xf7\x43\x7d\x60\x24\x7d\xa8\x26\x09\x22\x2c\x48\xe9\x21\x4a\x5b\x2d\x00\x8b\x52\x9c\xed\x1c\x0f\x93\xe3\x51\xdf\x10\x85\x9f\x47\x8a\x2c\xcc\x3f\x67\xa4\xa5\x9a\xd2\xdf\xa1\x27\x9c\xa1\x5f\x43\xb1\x0c\xd3\x9b\xf3\x17\xfc\x22\x85\x8f\x41\x98\x8e\xa7\xe7\x47\x8b\x34\x9e\x9d\x0f\xc2\x9b\xf3\x5f\x97\x82\x9f\xff\xba\x9c\xdd\x9c\x1f\x2d\x2f\x97\x99\x3c\x3f\xe5\x0b\xc9\xe7\x17\x3c\x3d\x3f\x19\xcb\x44\xfd\xbe\x4d\xae\x74\xc4\x31\x1f\xc3\x87\xb3\xd8\x78\x8e\x08\x3d\xd3\xb5\xa8\x1a\x14\x70\x05\xda\x02\x56\x70\x15\x58\x05\x53\x41\x53\x90\x14\x10\xbf\xbc\xa7\xe3\xcd\xeb\x0c\xda\x6b\xbe\x85\x1a\x37\x9f\x25\x12\x4f\xf0\x96\x66\xb4\x7b\x83\x09\xaf\x02\x6b\xb1\x6c\x38\x32\x4c\x7d\x45\x7d\x0c\xea\x12\x32\xb5\x6c\x2a\x29\x9a\x70\xea\xed\x1e\xb6\x5a\x29\x89\xd9\x04\x0f\x77\xf9\x1e\x4d\x47\x64\x43\x99\x61\x3a\x62\xc5\xc6\x33\x3b\x27\x06\xdc\xb3\xa6\x03\xf5\x2d\xaa\xc0\xd8\x5c\xbc\x30\xfc\x04\x8b\x4f\x9d\xd2\xfd\x76\x6f\x8b\x31\x9c\xb0\x4b\xef\x15\x6b\xbd\x99\x34\x24\xa4\x9f\x00\x67\x2e\xa8\x2f\x51\x69\x93\x5f\xe0\x3f\xa9\x2c\xcf\xff\x76\x35\xf7\x2e\xb0\x09\xf6\x1d\x9d\xf6\x34\xfb\x7d\x1c\x1b\x16\x94\x77\x1f\x16\x96\xcc\xea\xed\x56\xaa\xc3\x7a\xe7\x5f\x9f\xa3\xd6\x3f\x76\x34\x95\x2a\x09\x91\xec\xdc\xb9\xa1\x55\xe0\x32\x6c\x55\xe6\x2a\x67\xa1\xde\xf9\x92\x78\xb5\x38\xa5\x16\xef\x91\x44\xdf\xa8\xea\x8e\xb4\x97\x2f\x95\x04\x9e\xce\xef\xba\x22\x11\xf4\x1b\x01\x72\x5d\x12\x49\x78\xc3\xd7\x1f\xc7\xfb\xf8\xad\x43\x37\x6a\xd1\x12\xeb\x51\xb2\xc0\x4b\x0c\x7c\x4d\xb6\x3c\xe7\x2c\xe3\xf4\x54\xfd\x2d\xf6\xf1\x33\x8e\x3d\x01\x57\x5e\x39\x6f\xcd\xe3\x8e\xc5\x15\x57\x05\xc7\x71\x38\xa2\x89\xfa\x13\x3b\x4e\x2a\x5c\x93\xbd\x5d\x60\xa6\x08\xbb\x05\xe5\x08\xd0\x3b\x60\xaa\x56\xf7\x9b\x50\x1b\x86\x58\x5b\x1e\xfe\x56\x32\x29\xf1\xdf\x48\xf1\x41\x6a\x5e\x8a\x96\x70\xe3\xaa\x02\xfb\x15\xbb\xaf\x52\x6b\x81\x39\xba\xe0\xc0\x24\x25\x34\x31\x21\xe0\xf9\x78\x5d\xdb\xdd\x87\xcc\xb1\x49\x8e\x21\xd9\x3f\xc0\xe0\x5a\x62\x1e\x71\x8b\xfe\x85\x51\x2b\x36\xaf\x1a\xb9\x9a\x6e\x82\x28\x8a\x91\x3d\x50\xaa\xd7\x20\x5b\x83\x56\xce\x08\xd7\x4e\x7d\x2d\xc9\xbd\x6a\xb9\x0b\x42\x5a\x03\xa1\x58\x8f\x5f\x79\x41\x5c\xab\x93\x5e\xef\xc4\xac\x20\xc4\x7a\xe0\x34\xfd\x29\xeb\xf6\x71\x56\xbc\xa6\xf2\xd6\x7e\xb7\x5b\x2a\x47\xdd\x53\x24\xb8\xa3\xb3\xb8\x2b\xe0\xaa\xf0\x0a\xe0\x62\x38\x21\x81\x0f\xaa\x0c\x26\xf3\x78\xea\xbc\x40\xd8\xe2\x09\xf6\xda\x62\x59\x5c\x77\xbc\x3a\x15\x9c\xc8\x43\xa1\xa8\x13\xd3\xe2\xa2\x5e\xb0\x99\xf4\xfe\xec\x99\x2f\xea\x26\x88\xd7\x0f\xd0\x27\x7b\x7f\xf6\xac\xd4\x15\x30\x3c\xe1\x47\x72\xf3\x5a\xf6\x03\xc8\x9e\xe0\xb8\x73\x95\xe5\x71\xfd\xcb\x97\x2e\x7b\xd4\x92\x6d\x8b\x17\xb7\xf1\xa3\x96\x1a\x09\xda\xa5\x29\x31\x4d\x3a\x0e\x6f\x30\x69\x4b\xf2\xe0\x51\x2b\x6d\xf7\x0a\x38\xc7\xdc\x67\x95\x80\x8a\x08\xf8\xd2\xea\xb5\x1e\x6d\x63\xd9\xee\x91\x16\x7e\xd4\x12\xed\x54\x15\xfc\xc0\x8d\x61\x78\xe7\x97\xe6\x09\xeb\xf6\x43\x36\xe7\x38\x66\x5c\xe5\xcd\x82\xec\x29\xf0\x01\xfa\x2a\xa6\xd5\xa3\x21\xcb\xda\x10\x41\x02\x15\xa3\xc2\x84\xde\xaa\x53\x31\x88\x69\x14\xde\x9c\x4c\xd4\x90\x04\xa1\x47\x33\xfd\xb2\x8e\x4e\xb0\x0f\xfe\x59\xaa\xce\xc7\x90\x79\xcf\xdf\x70\xe6\x1a\x50\x98\xb4\xe3\x76\x8f\xec\x3c\x22\x2d\xc7\x5a\x0c\x9f\xf4\xfa\x29\x0b\x5b\xef\x38\x4e\x98\x85\xd3\xee\x01\xa4\x20\x7c\xfa\xae\x02\xbc\x8f\x53\x16\xb6\xab\xb1\xb4\x28\xda\xea\x91\xc0\x83\x44\x53\x16\x12\x7a\x7b\xcd\xf9\xd7\x20\xa5\xd0\xb7\xc4\xeb\xcf\xbb\xca\x4c\xb9\x99\xa3\x09\x7c\xb7\x74\x43\xec\x7b\x09\x8c\x56\x3b\x6d\x25\x64\xe7\x51\x01\xe4\xcf\x2a\x21\xa9\xdf\x5e\x25\x7d\x44\xac\xc2\x64\xe1\x0a\x48\x12\xb2\x7a\x85\xd1\xb5\x22\x39\xae\xaf\x35\xc9\x71\x9d\x20\x8a\x54\x13\x81\x5b\x81\x3e\xa8\xb4\x0f\x1f\x74\xda\x07\x95\x16\x67\xc9\x07\x9d\xfc\x15\xeb\x8c\x14\x5d\xeb\x90\x4d\xa2\xe8\x83\x46\xfb\x75\xf2\x43\xf8\x76\x89\x0f\x35\xd6\x7e\xed\x88\x00\x55\xb5\x23\x02\x3e\xb8\x68\x55\x2b\x44\x4f\x15\x0e\x7e\xad\xaa\xb9\x06\xd0\x54\x25\xd5\x22\xe2\x72\x98\x16\xd6\xb2\x7a\xc4\x32\xc6\xa0\x27\x91\xa2\x69\x50\xa4\xba\x10\x85\x37\xba\x77\x51\xf4\x77\x08\x1d\x23\x0c\x96\x0d\x62\x51\x21\x99\xa2\xff\x0c\x50\x1d\xf5\x15\xfd\x87\xb0\x2a\x60\xb8\x86\x81\x4c\xb2\xee\xee\x73\x13\x69\xa6\x42\xc7\x7f\xc5\x30\x1e\x14\x45\xc5\x94\xea\x08\x5e\x9a\x55\x1d\xf7\x5c\x4f\x2c\x04\x7a\x3d\x37\xc9\x7e\xd8\xcf\xdf\x33\xbc\xab\xc8\xcd\x2a\x77\x5f\xcf\xdd\x97\xea\xf1\x26\xf2\xcd\x1b\xf4\x2a\xdd\x17\xdd\xa7\x5c\x2d\xc5\x18\xdd\xab\xa8\x5f\x0a\xd6\xa0\x2a\xa4\x6b\xd5\x10\xee\x45\x0c\x5a\x68\x77\x93\x83\x9d\xa8\x42\x0d\x9a\x21\xd4\xf2\x8d\xba\x76\x98\x12\x35\x05\x9b\xd6\xbe\x5b\xef\x40\x40\x7e\xe1\x0c\x9d\x2e\x45\x14\xde\x9c\x0f\x12\xf8\x39\x5b\xf2\x4c\xfd\x7e\xe0\x91\xd0\x5f\x67\xd3\x65\x0a\x1f\x2f\xd2\x58\xfd\x9c\x86\x72\x99\xaa\x99\xf3\x09\xc0\xdf\x35\x20\x05\x45\x81\x50\xc5\x55\x41\x55\x46\x15\x28\xe5\x7d\x0d\x79\xcf\x07\xc9\xf9\xd9\xf2\xfc\x03\x3f\x3f\x9b\x9e\xbf\x48\xcf\x4f\xc3\x7a\x8a\xf0\xd5\x7f\x44\x11\x96\x46\xd4\xa3\x09\x4b\xf1\x15\xe2\xef\x43\x7d\xda\x3c\x16\x6b\x29\x9a\x30\x7c\x54\xa6\x0b\x7b\x23\xa2\xee\x0e\x9c\x92\x0d\x25\x1d\x69\xe7\x9f\x12\x3f\x22\x0f\xd7\x9b\xb6\x06\xe6\x7e\x74\xe6\xf5\x9d\x30\xee\x45\x67\xc2\x8a\xbe\x83\xf6\x2b\x55\x51\x22\x1a\x7f\x50\x70\xbd\x93\x3f\xa6\x05\xab\xa3\x5b\xad\xef\xef\xb5\xf4\x4e\x32\x72\xad\x9e\x4d\xb9\x7f\xd4\xa6\xbf\x3f\x06\x9b\x6a\xba\x77\x07\xee\x6a\xd2\xfd\x4b\xfc\xd7\xcd\xb8\x73\x86\x81\x00\x7c\x01\x74\xe4\x7b\xf8\xfb\x47\x99\x9a\xfc\xf8\x9f\x51\x93\xe6\xac\x18\x8e\x68\xa6\xfe\x8c\xd5\x9f\x59\x99\xb0\x7c\x54\xa6\x2b\xed\x16\x96\xc4\x38\xeb\x2a\x6d\x55\x20\x03\x69\x52\xb7\xf9\x74\x52\x5c\xd9\x53\x3a\x36\xd4\x54\x65\x4a\x68\x66\x85\xd8\xe8\x58\x7f\xc5\x84\xce\x5c\xea\xcc\xa5\xce\x6c\xaa\x76\xb9\xee\xc8\xcb\xcc\x7d\x8d\xdd\xd7\xac\x42\x7c\xea\x1e\x65\x86\x9c\xcc\x80\xf6\x1c\x9b\xd0\x18\x42\x33\x13\x9a\x79\xa4\x66\xe9\x3e\x5b\x23\xe2\x66\x9b\xc9\xc0\xf5\x3b\x94\xd5\x40\xac\x64\xb6\x17\xf5\x3d\xb2\xde\x45\x5b\x8e\xef\xd9\xac\xbb\x60\x64\x3f\x86\x31\x88\xc5\x5d\x10\xc2\x3b\x29\xdc\x97\xbc\xc2\x93\x9f\x26\xcb\x34\xc3\xe4\x41\x6f\x37\xcf\x7b\xbb\x45\xc6\x7f\x9a\x65\xfd\x0a\x68\xad\xcd\xef\x8b\x65\x5e\x92\x51\x13\xc0\x3e\x68\xdd\xfc\x79\x2c\x96\x92\x43\xb0\xfc\x24\xfb\x8f\xea\xfe\x39\xb7\x50\x60\x5b\x2a\x6c\xff\x95\xc2\xe8\x5f\xbd\x32\x2f\x9d\x48\xc1\xd5\xd8\xe1\x54\x25\x4c\xa7\x26\xe1\x25\x87\xc8\xaf\x2a\xf2\xeb\xd7\x1f\xbc\x8b\x9a\xc6\xe5\xf9\xee\xbe\xc1\x3f\xa7\xf3\xf9\xfa\xa3\xac\x11\x62\x43\xad\x97\xbe\xe6\x33\x69\xbd\xc3\x95\x5e\xed\x92\x02\x4c\x96\xfd\x57\x80\x6c\x5c\xc6\xc7\x89\x88\x4a\xc0\x5f\xdd\xd9\x46\xbf\x63\x77\xb4\xf0\xd5\x0f\x5a\xf8\x23\x30\x9b\xda\xf7\x4f\x0e\x26\x07\xb6\xba\xfa\xf3\x08\xd1\xad\x1e\xa0\xe3\x30\x61\x14\x4d\x35\x22\xae\x43\xbd\x3d\x8d\xd7\x86\x88\xfe\xc3\x3c\x11\x1f\x15\x9f\xaf\x1c\xa2\x3d\x75\x5f\x5f\xdd\x97\x5a\x0a\x8e\xfa\x52\xd3\xef\x02\x6a\xda\x8b\x14\x35\x58\xbf\xba\x6f\xd5\xe7\x4f\x06\x80\x97\xf2\xca\xa5\xc0\xc3\xc9\x2b\x44\x15\xfc\x11\xdd\x33\x11\x8a\x36\xfc\xfa\x75\x1d\x81\xb5\x34\xaf\xc2\x5f\x0f\xe5\x70\x6f\xc4\x76\xf7\xe1\x9d\xae\x1b\xa4\xee\x19\x26\x44\x14\x1d\xd5\x95\x15\x9d\xf3\x38\x7b\x37\xf7\x90\xee\x38\x7b\x37\x50\xc7\xa6\x28\x36\x80\xc6\xa4\x01\xd0\x54\x8d\xdf\xb4\x0e\x12\x54\xad\x1a\x41\x01\x17\x37\xda\x34\x6c\xab\x6b\x1f\xa8\x61\x18\x36\x34\xde\x09\xb6\xef\x1e\x5a\x38\x05\x35\x9a\x12\x42\xe5\x70\xbf\x14\xab\xe2\x36\xd7\xa3\x06\xf2\x47\x35\xed\x03\xb7\xe1\xef\x56\x4b\x77\x21\xf6\x61\x29\x36\xd9\xdc\x98\x57\xff\xcb\x9d\xf6\xe0\xfe\xdf\x77\xd2\x92\x47\xbf\x71\xfa\xab\x7e\xfd\x57\xbd\xcd\xf4\x56\xfb\xc4\xd9\xad\x5a\x40\x22\x0a\xd3\xe0\x36\x0b\xe7\xfc\x38\xbc\x09\xd0\xf0\x2c\x89\xc2\x9b\x46\x28\x47\x8d\x37\x67\x88\x0a\xfe\x4d\xda\xf8\x79\x92\xa6\xc9\x75\x29\x49\x61\x42\x1a\x4b\x6d\x0c\x6d\xfc\x2c\xcc\x4c\x91\x8f\x3c\x93\x3c\xf5\xc1\xa9\x34\x5d\x66\xf8\x26\xcc\xe4\xa8\x51\x2e\xaa\x5a\xf1\x7c\x96\xf1\x00\xbd\x41\x2b\x5a\x96\xb0\x0b\x6e\xdf\x9c\x9d\x06\x68\x1a\xcc\xe7\x41\x96\x35\x8e\x10\x7d\x73\xa6\x83\xf0\x1d\xa0\xc1\x60\xe7\xf8\x78\x47\x8b\x75\xbc\x81\xf0\x60\xd0\x38\xa6\x0d\x1b\x53\x89\x6a\xb8\xa2\x90\xa4\x1a\x42\x1b\x75\x19\x56\xd4\x93\x13\x0c\x90\x51\xef\x6a\x44\xda\x2a\xbe\x96\xdf\x0c\xd0\x83\x08\x69\xe6\x1d\xbc\x29\x9c\xe8\x68\xb8\x89\x02\x2d\x53\xb7\x0b\x12\x74\xda\xed\xef\x59\x3c\xe7\xc1\xed\x64\x29\x97\x29\x0f\x50\x2c\x1a\x0f\x32\x44\x17\x61\x26\x03\xf4\x20\x6b\x84\x97\x09\xa2\x59\x80\xc2\xc6\x84\x5f\x37\xcc\x69\x89\x68\x96\xa9\x5a\x8a\xf0\x5c\xe5\xd0\xe7\x2b\xa2\xf3\x39\x24\x9a\xe3\x16\xd1\x69\x80\x42\xd1\xd0\x47\xe6\x74\x0a\x69\x53\x3d\xf7\x91\x2a\x06\x1c\x8b\x28\x82\x78\x85\x1b\x20\x3a\x00\x68\xfa\xed\x7a\x30\xd0\xc0\x80\x35\x8e\xe8\x8d\x4a\xd2\xf2\x39\x37\x37\x90\xa2\x02\x19\x5a\x51\x9d\x23\x38\xe1\xd4\x63\xa3\x07\x67\x1c\x14\x25\x83\xdb\x28\xb9\x0e\xba\x34\x4a\x6e\x82\x83\x95\xd5\x9d\xcc\x82\x2f\x9c\x7a\x28\x49\xf0\xba\x08\xea\xe2\xbf\x73\x5a\xba\xc9\x83\x9d\x61\xb8\x18\x7d\xee\xf4\xe7\xfd\xcf\x9d\xfe\x4e\xbc\xa2\x5c\xb2\xdb\x15\x95\xb2\x24\x67\x26\x64\xc9\x1a\x70\x45\x46\xbc\x90\xa2\x3b\x47\x14\xb5\x11\x09\xbc\xe7\xa4\x54\x16\xf6\x1f\xac\xb1\x84\x2d\x2e\x87\x72\xb4\x41\x63\x86\x1b\x53\x6a\x46\x3b\x9c\x68\x35\xf5\xdf\x78\xe7\x3c\xbc\xb8\x48\x3d\xef\x2f\x56\x3a\xcb\xe9\x6a\x38\xa3\xda\x93\x58\xa8\x11\x8e\x96\x33\xde\xf8\xc9\xd5\xf1\x13\x52\x98\x2c\x58\xc4\xed\x8c\x93\x88\x33\x34\x38\x39\x7e\xff\xe6\xf9\xf9\xdb\x93\xb3\xf3\x17\x27\xef\xdf\x1e\x23\xca\x57\x98\xd0\x04\x4c\x36\x3a\xbd\x77\xa7\xc3\xa8\x1a\xed\x29\x98\x4b\xff\x5d\xb0\x10\x52\xc4\x58\xb0\x10\x4b\xd2\x07\xc1\xd5\x20\xd6\xd9\x48\xff\x37\xce\x44\xf0\x9f\xeb\x08\x69\x9a\xbb\x81\x5a\xbc\x85\xc0\xee\xf5\x24\x59\x8a\xa8\xd3\x38\x8e\xa3\xc6\x4d\xb2\x6c\x4c\x92\x14\xbc\x66\x24\x8d\x59\x12\x46\x8d\x58\xf6\x11\x21\xd4\x0e\x9b\xa7\xb9\x2e\x4b\x26\xe6\xc0\x1e\xb7\x93\x1f\xfc\x04\xef\x98\xb2\xa3\x8a\x30\x6e\x94\x3f\xb9\x1c\xf2\x11\x79\x8b\x91\x6e\xb9\x6e\xc8\xc9\x15\x4f\xd3\x38\xe2\x88\x82\xca\xbe\x56\x70\x34\x0f\x83\x3a\x07\xd6\x77\xe8\xdb\x70\xce\x69\x43\xdb\xcf\x26\xaa\x79\xc6\xfb\x63\x28\x1a\xfc\x5b\x9c\xc9\x58\x5c\x36\xcc\x6d\x6b\xa1\xf8\xf5\xd4\x42\xd1\x36\xda\x1a\x89\x98\xdd\x34\x2e\x78\x63\x99\xf1\x48\xf5\xbf\x01\xd6\x41\x14\xc0\x10\xcc\x9b\xe8\xa2\x8d\x53\xce\x1b\x53\x29\x17\xc1\xce\x8e\xae\xe0\x4b\xd6\x19\x27\xf3\x9d\xcb\x65\x1c\xf1\x6c\xe7\x7f\x76\x8c\xca\x55\xb6\xa3\x2b\x6e\xeb\x72\x3b\x00\x72\x9e\xa4\xbc\x11\x8b\x49\xd2\x01\xd7\x54\x30\x16\x9d\x73\xdd\x10\xf7\x84\x6b\x9d\x6d\x6b\x4f\xc6\xba\xe1\xc4\xc5\xab\x75\x53\x4a\x1a\x91\xb4\x26\xb2\x04\xb5\x50\x72\xc6\x82\xa9\x2d\x54\x86\xed\x5e\x84\xe5\x1a\x98\x3c\xc7\xeb\x91\x6c\x38\x22\x74\x3d\xda\xb8\x32\xd0\x1e\x6c\x8c\x8d\xf3\x40\xae\xb4\xd6\xef\x61\xaa\x10\x21\x1d\xe9\x6d\x01\x3e\x82\x0d\x77\x8a\x9f\x63\xd0\x7a\x55\x60\xf9\xa8\xd9\x84\x9f\x7a\xf7\x18\x6a\xc9\x75\xc0\x32\x16\x18\xb7\x53\x53\x08\xda\xd6\x40\x91\x02\x48\x0b\xdf\xe8\xfc\x40\x1c\x2d\x3f\xc3\xc3\x6e\xf2\x9e\xda\xd4\x11\x61\xd0\x34\xef\x53\xaf\x76\x90\x76\xad\xc4\x11\xba\xe5\x64\xa5\x7e\x83\x65\xbe\x95\x80\xa9\x2b\xb5\xe0\x19\x50\xc7\x85\x28\x15\xc8\xca\xae\xaa\xf2\x7a\xbe\xda\xb0\xe5\x1d\xb0\xee\x61\x5c\x88\xca\x12\xe3\x62\x1b\x27\x4c\x1d\x99\xc3\x78\xe4\xbc\x37\xb5\x91\xf3\x8c\x4f\x85\x9a\x55\x9d\xa1\xd5\x1b\x11\xd2\x17\x5e\x2e\xe0\x76\x1c\xca\xa7\xdd\x43\x68\x5b\xaa\xda\x96\x78\x6f\x2d\x86\x94\x54\xf0\x9c\xfb\x4b\xb0\x13\xd3\x6c\x5a\x3b\x59\x4f\x99\x6c\x36\xaf\x71\x42\x85\xc2\x46\x9e\x32\xd9\xee\x11\xf0\xd4\x76\x28\xdb\xed\x55\xdc\x6a\xad\xdc\x40\xac\x4a\x8a\x5e\x99\xf4\x15\x95\xd4\xc8\x39\xce\x5e\xb3\xd9\xde\x65\x0c\x34\xec\x9d\x2e\x3c\xe8\xf9\x88\x61\x6f\xf4\xa4\x9b\xe7\xea\xf7\x69\xaf\xd7\xef\x05\x62\xb8\x3b\x7a\xd2\x53\x31\xbb\xa3\xa7\xd7\x1c\x83\x3f\x37\x95\x4c\xfa\xbb\x81\x18\xee\x99\xec\x7b\xa3\xa7\xbb\xfb\x8a\xd6\x63\x8c\xa9\x50\xb3\x89\xbb\x5b\xea\x73\x7f\x94\xe7\xfa\xeb\xa1\xfb\x3a\x18\x91\xfe\x5e\xa0\xd2\x74\xe1\xfd\xd1\xd3\x87\x8f\xfb\xfb\x81\xca\xa3\x63\x1e\x42\xcc\xc3\x40\xe5\xd5\x31\x07\xa3\xa7\x8f\x1f\x3f\xee\x1f\x04\xed\x1e\x85\x76\x9f\xdb\x86\x1f\xdb\xe7\x3b\xd5\x03\xed\x0c\x63\x57\x6b\x2d\xed\x92\x4a\x56\x85\x51\x65\xcd\x26\xb8\xe0\x93\x90\xe5\x51\x5d\x16\xd0\xf4\xf7\x32\xfd\x6c\x32\xd9\x3c\x4c\x96\x84\x2c\xc6\xb2\xe2\x55\xd5\x0a\x5a\x70\xab\x0c\xd7\x97\x81\xa7\x24\x3b\xf3\x27\x46\xf3\xac\x80\x61\x65\xe4\x51\xce\x23\xbd\xf2\x92\x1a\xa3\xb2\xee\xd1\x37\xd5\xfe\x77\x3c\xfb\xc4\xe7\xcb\x8c\xbf\x3f\x7b\xd6\x1f\xae\x3f\x24\x53\x1b\x35\x30\x22\x98\xd2\x3d\xec\x4a\x50\x0b\xd3\x65\xaa\x05\x4a\xb9\x4d\xd6\x15\x6c\xf3\xce\xf9\xb5\xd6\x42\x06\xbb\x0d\xe1\x70\x77\x54\x0a\xf6\x46\xcd\xe6\x06\x2d\x1a\xdd\x59\x0a\xde\x87\xf4\xe0\x80\xc0\xcc\xf9\x35\xe9\xbc\x7c\x69\x55\x9c\x65\xe7\x43\xf1\xf9\x9c\xc4\xac\x47\x43\xb6\x4f\x05\x1b\xab\xc3\xf3\xe5\x4b\x0a\xb5\x74\x47\xf4\x17\x8e\xbf\x4b\x4c\x68\x8f\xee\x13\x78\x50\x55\xc7\x3a\x64\xfa\x40\x7b\x84\x62\x9c\xe8\xd0\x73\xda\x23\x44\xad\xe2\xe4\xe9\x23\xb5\x34\xc6\x6c\xab\x6b\x3c\x1b\xc5\xfe\xd9\xa2\xf0\xab\x4e\x94\x5c\xc3\x83\x43\x35\xf6\xe6\x50\x3b\x0d\xb4\x95\xc6\x34\x24\x87\xa6\x4d\x97\x97\xae\x4d\xb3\x72\x43\xae\xe9\x0c\xf8\x83\xd6\xfa\x82\xec\x44\x7d\xd5\x2e\xd9\x89\x88\x5a\xac\xc9\xd3\x03\xd7\x22\xbb\x5c\x3a\xbc\x0f\x39\x78\x2b\xa6\x58\x76\x38\x2c\xea\x0e\xf7\x72\x92\x20\x61\xf1\x2a\x55\x5d\x4a\x9f\xbe\xe3\x58\x40\x6b\xfa\x35\xab\x9d\x6d\x75\x0d\xd8\x71\x4d\x72\x14\xde\xa8\x0c\x38\x63\xc7\x0a\x88\x13\x8b\x30\x9d\x61\x5a\xbc\x1d\xc4\x8f\xec\x2e\x63\x59\xf1\x60\x4e\x60\x39\x14\xca\xf2\xde\x4e\x0c\x55\xf7\xed\x98\x24\xc3\xee\x88\x50\xec\x67\x79\x3a\xe7\x38\x24\x79\xae\xcd\x24\x15\xf1\xaa\x8b\x1b\xf6\xb7\xea\x38\x15\xec\x2f\x8e\x43\xda\x2d\xb5\xc9\x34\xb8\x37\x62\xa2\xb2\xd2\xcd\xf2\x74\xf1\x7a\x19\x5b\xde\xe9\x5e\x69\xd9\xca\x11\x88\xe4\x9a\x6f\x06\x2c\xd5\xc4\xba\xb8\x71\x9c\xd6\x52\x72\xa9\x74\x7f\x17\xb8\xfd\xbd\xa0\x1b\x58\x78\x70\x1e\x42\x40\x1d\x89\x5d\x1b\xd8\xf7\x03\x0f\xfd\xc0\xc1\x48\x9b\x7f\x31\xe4\xa4\x36\xd9\x0f\xc5\x59\x57\x8b\x81\x31\x5c\xec\xf5\xbf\x78\xf0\x95\x13\x5f\xf0\x23\x23\x60\xa7\xcf\x66\xb0\xc6\x0b\xac\x10\x47\x60\x23\x20\x54\xcc\x9c\xfc\x3e\x87\x8b\x37\x32\xf2\x26\x03\xc3\x8d\xf2\xca\xdb\x28\xd2\xe6\xc6\x34\x44\xd1\x4c\xdd\xe6\x50\xf3\x68\xec\xf9\x50\x4f\x10\x74\xce\xaf\x3b\x11\xd4\x75\xdd\x89\xb6\x18\x8b\xed\x7c\x57\xcc\xaa\x80\x62\x34\xb0\xf6\x97\x92\xed\xfc\xeb\x73\xb6\x8d\x71\x3f\xd0\x4a\x52\xb7\x07\xab\x1c\xf4\xb9\x48\x1b\xf7\x83\xcf\xd1\xe7\xa8\xad\xfe\xe4\x1f\xcc\xa7\xfe\xc8\xb5\xee\x16\xfc\x10\x82\xfb\x01\x3e\xcb\x1b\x04\x5b\x1d\xab\xca\xef\xb0\x43\x47\x9f\xa3\x16\xe9\xc3\x7f\x3c\xfc\xdc\xfa\xbc\xa6\x8f\x95\x7f\xce\xb6\x3f\xa9\xf4\x7f\xec\xd0\xc5\x1d\xad\x32\x8d\x2a\xda\x74\xbf\x26\x95\x7f\xfe\x6e\x83\x26\x72\x93\x16\x19\x8d\x24\x1b\x5a\x0d\x93\xf6\x60\xd0\x3e\x3e\x46\x74\xc7\x35\xba\xed\x06\x70\x67\x64\x14\x51\x5c\x26\xe8\x4f\x25\xc3\xcb\x97\x2f\x5f\xb6\x87\x1f\x46\x1f\x3e\xb4\x9f\xbb\x2c\x76\xe8\x2b\x39\xca\xe9\x3b\x74\xab\xe7\xaa\x38\x2e\x55\x70\xbb\xb7\xf2\x6b\x2f\x55\xed\x17\xfb\xf8\x71\x30\xf0\x9b\xdf\xeb\x16\xe5\x4c\xca\xe7\xe8\xf6\xe7\x95\x6b\x07\x34\xc3\xb5\xf3\x43\x51\x93\x4b\xf4\xd3\x76\x57\x7e\x65\xae\x89\x8f\x56\x3b\xa3\x11\x9d\xc2\x30\xbe\x7a\xa5\x19\x2b\x9d\xd3\xd3\xd3\x53\x48\xfe\x1c\x05\xee\xcf\xe7\xce\xe7\xa8\x05\xf0\x6d\x3e\x5a\x9b\x8f\x56\xb3\xad\xe5\x28\x52\xfd\x24\x13\x3b\x9f\x97\x1b\xe0\xfe\x7b\xd5\xab\x3c\xb4\x26\x0f\x2d\x67\xa9\xa4\xba\x14\x2f\xde\xc4\x99\x18\x35\x14\x17\xb0\xfa\x77\xfa\xea\x38\xfd\x8c\xf1\xe7\x76\x5f\x2d\xd5\x9d\xb8\xe0\x32\xcc\x65\xed\xcd\x0f\x56\x4b\xe8\x98\x2d\xa5\xf6\x67\x9b\x91\x3c\x5f\xb8\x6f\x85\x15\x8c\x35\xf6\x03\x67\x42\x9c\x25\x60\x19\x08\x54\x6d\x23\x59\xd5\xb5\x8d\x27\x38\x52\x74\xfc\xb0\x37\xd2\x10\xc6\x0a\x2f\x25\xb7\x09\xd3\xd1\xdd\x11\x4d\xd9\x56\x6f\x8b\x99\xf0\xee\xa8\xf0\xdb\xac\x4f\xee\x84\x78\x36\xda\xb0\x67\xec\x68\xab\xa7\x1b\x33\xdc\x1b\x59\x3a\x40\xb5\x61\x5a\xd7\x86\x69\xa5\x0d\x7b\xaa\x0d\x31\xc3\xe3\xe1\xee\x28\xcf\x51\x03\x91\xd6\xd4\xb4\xa7\x5a\x7f\x7c\x47\xfd\xe0\xca\x39\xb5\xd6\x5e\xee\xca\xa9\x5b\xba\x3f\xd2\xe6\x2c\x27\xd2\x36\x64\x7f\x44\xee\x2a\x15\x32\xf4\x09\xad\xc0\x7e\x50\xd2\xc2\x71\x9e\x23\x44\x5a\x38\x84\x5f\x7a\x24\x9d\xac\x61\xa9\x18\x1c\xc9\x03\x35\xfd\xea\xf8\x1a\x24\x22\x3f\x5b\xf2\xfc\x03\x8f\xf2\xb3\xe9\x32\x7f\x91\xc6\xf9\x69\x28\xf3\xd3\xa5\x20\xb4\xff\x39\x23\x7d\x6c\x78\x7a\xe4\x73\x86\x7f\x0d\x45\xfe\x82\x5f\xe4\x83\x30\xcd\x8f\x16\x69\x3e\x08\x6f\xf2\x5f\x97\x22\xff\x75\x39\xcb\x8f\x96\x97\xf9\x29\x5f\xe4\x27\x63\x99\xbf\x4d\xae\xf2\x63\x3e\x56\x45\xd4\x9e\xa4\xfb\x2b\xfd\xf9\x39\x22\x81\xfe\x51\xc7\x9b\xfe\x22\xfd\xcf\x99\x6a\xc9\xfb\xb3\xfc\xe5\xe0\x2c\x1f\x3e\x7f\x36\x78\x37\x1a\x9e\x1e\x8f\xce\x48\x8e\x87\x9f\xbe\x8f\xd4\x8f\x3e\x2b\xf6\x57\x84\xfc\x63\xa7\x58\xa2\x97\xc5\x12\xad\x68\x93\x39\x99\xc9\x27\x6c\xff\x71\x7f\x97\xef\xb5\x64\x20\x41\x49\x10\xf4\xc5\x54\x08\xc6\xe1\x46\xb2\xdb\xf7\x67\x41\x97\xbe\x1c\xa8\xbf\xcf\x8f\xcf\x82\xf6\xee\x7e\x97\x3e\x3f\x3d\x0b\xda\x7b\xdd\x2e\x7d\x76\x6c\x3f\x20\xe6\xa0\x4b\x07\xc7\xf6\x43\xc5\xec\xef\x76\xe9\xbb\x63\xfb\x01\x31\x3f\x77\x3d\x5e\xdd\x95\xd7\xc4\x81\x99\x57\x35\x1d\x9e\x6a\x2b\x1e\xfe\x8b\x8c\xb6\x3f\x93\x7c\xf8\x59\x7c\x96\xa0\x63\xda\xf0\x75\x5f\xf1\xe7\xec\x73\xd6\x22\x6b\xf1\xff\x52\xf1\xdb\x3b\x15\x45\x59\x15\xa7\x9d\x8d\xc0\xaa\xaa\xb1\x1b\x5a\xc8\xcf\x5a\xc3\xde\x43\x18\x48\x7a\x56\x78\xad\x94\x84\xba\x01\x15\x6a\x40\x8b\x60\x5a\x0e\x26\x2a\x58\xa8\xa1\x37\x9b\xe6\xf1\xdc\x65\x88\x55\x06\x42\xc3\x15\x96\xc3\xfd\x11\x95\xc3\x3d\x6d\x40\x00\xd8\xf8\x54\x0e\x0f\xd4\x9f\x47\x23\x2d\x0b\x54\x7d\x34\xb0\xe6\x39\xf3\xfc\xf7\xa2\x71\x9c\x28\x1a\xd5\x12\x52\x52\x9d\x12\x85\x59\x02\x87\x1b\xe5\x39\x86\x97\x8f\x75\xb4\x84\x0a\x7f\x3f\x50\xb5\x53\x31\x00\x00\x17\x3e\xba\xca\x43\x85\x0e\x31\x41\x8d\x31\xad\x6a\xbb\x62\xd5\x0a\x6b\x71\x55\x0e\xf9\x48\x8f\xb5\x35\xb6\x64\xac\x9e\x56\x86\x30\x61\xe9\x83\x5e\xd7\x5a\x0b\xc2\x69\x3b\x21\x3b\xbd\x6e\x77\xfb\xa0\xdb\x4a\x54\x0b\x7e\x56\x5d\x78\x0c\x9d\x51\xd8\x36\xe0\x8a\x7f\x71\x1f\x39\x54\x8d\xd2\x09\x7f\x07\xcd\x83\x93\xd8\xd8\xf6\x63\x5b\xdd\xba\x33\xa1\xd0\x59\x94\xc6\xa8\x9f\x3a\x55\xb6\x18\x4b\x3b\xaf\x4f\x4f\xce\x7f\x3e\xe8\xf6\x88\x1f\xf9\xfb\x8b\x67\xe7\x0a\x1c\xb9\x85\x71\x1a\x8e\x74\x25\x60\x87\xcf\xba\x73\xf5\x69\x63\x84\x5a\xe6\xde\x70\xae\x43\x66\xc6\x3c\x54\xc2\xde\x03\x5c\xea\x08\x36\xe2\xec\x34\xe4\xf9\x70\x64\x30\xfd\xc4\x77\x63\x19\x03\x5a\x4f\xb1\x60\x38\x33\x99\x97\x1c\xc7\x6a\xfa\x54\x11\xa2\xa8\x95\x66\x13\xe3\x90\x65\xc5\x83\x52\xe6\x16\x90\x20\x8e\xfb\xf3\xb4\xdb\x6c\x42\xd3\x3d\x8b\x8c\x7a\x01\x87\x84\x66\xaa\x38\xb0\x7a\xfc\xb2\x2d\xe1\x4c\x5c\xcd\x5a\xac\x08\xbc\x1e\xc6\xa3\x3e\x16\x7d\x7f\x24\x7a\x81\x07\xdc\x18\xf8\xb3\x72\x24\x17\xaa\xc5\xb0\xe4\x02\xcf\x58\xe0\x96\x28\x35\xa8\x5c\xe6\x10\x52\x4a\x36\x04\xd9\xb8\x3d\xa3\xd9\x0f\x7b\x93\x11\x4b\x86\x3c\x61\xbd\xdd\x66\x73\xab\x6b\xd9\x47\xe6\x65\x10\x30\x7a\x95\xae\x60\x60\x3f\x85\x59\x1f\x40\x10\x59\x31\xe2\x08\x44\x8f\xe5\x87\x99\x2c\xc5\xe3\x6c\xf1\x50\xeb\x88\xa0\xda\x67\xc1\xc3\x92\x11\x4d\xd1\x97\x81\x25\x6c\x6c\x79\xd5\x90\x7e\x39\x08\xba\x32\x2e\x63\x9c\xbd\x1b\xf4\x31\x4e\xcd\xa7\x36\x77\x23\x9f\xa8\xbe\x62\xd9\x62\xbd\x5d\x42\xd3\x3c\xef\xed\x2a\x4a\x26\xcf\x15\x36\x40\xa8\x24\x81\x5c\x15\x56\xeb\x6c\x1b\xa9\xd7\x6e\x42\x67\x5a\x90\xa7\xb8\x4d\xe1\x48\xd7\xdc\x66\xc0\x91\x3c\x25\x5d\xe9\x7b\x0f\x3a\xd7\xce\x83\xce\x27\x1e\x8b\xc7\x98\xc7\x73\x5f\x79\x0e\xb2\xdb\xe7\x33\x4d\xca\x31\x68\x9c\xb3\xfc\x28\x9a\x4d\xa4\x05\xd0\x2e\xf0\xad\x67\x07\xb4\xbb\x22\x41\x9d\x7e\x93\xa6\xe2\x62\x26\x3d\xe6\xc7\x22\xe5\x0b\xab\xb9\x44\xaf\xb0\x24\x7d\x75\x72\xde\x60\xad\xfd\x14\xe0\x31\xf8\xe5\x57\x47\x8d\x0c\x12\x2c\x48\x7f\x23\xdf\x47\x1d\x71\x86\xcc\x9d\xd8\x45\x6f\x39\xc5\x80\xeb\xf9\x46\x33\xd5\x31\x6b\x51\x96\xaa\x55\x3d\xb3\xed\xbb\x87\xc9\x13\x0f\xd6\x61\x02\x1b\x5b\x21\x8b\x03\x6d\xd2\xaa\xa0\x6e\x35\x31\xac\x66\xd2\x7e\x17\xb1\x84\x4a\x85\x00\x29\x48\xc3\x64\xa4\xd0\x1e\x49\xe8\x54\xdb\x55\x88\x5b\x60\xa8\xb0\xbc\x63\x68\xdc\x62\xbd\xee\xb6\xb6\x62\xb9\x6e\x79\x93\x42\x42\x36\x4e\x52\xce\x62\x6a\xd0\xbc\x34\xcf\xe3\x27\xa9\x36\xd5\xa0\xa6\x55\x12\x72\xb8\xc0\x9c\x8a\x3c\x97\xc0\x43\x09\x44\x1f\x8e\xce\x1a\x1f\xbf\x6a\x4a\x0e\x43\x37\xcc\x6b\x1c\xc0\x60\xbc\x9e\xe6\xec\xd3\xaa\xf4\x9a\x99\x5e\x9f\x25\x76\xe1\x61\x17\x5a\x06\x19\x56\x0e\x86\x35\xaa\x0d\x19\x16\x67\xbe\xda\xe2\x86\xbb\xef\xe2\xe8\xd5\xbd\x73\xa6\xc6\xf4\xfb\x8b\x34\x99\xc3\x9a\x7c\x11\xce\x66\x17\x21\xf8\xac\xb0\x0a\xe1\x45\x67\x5a\xea\x72\xd5\xa3\x94\xa8\xae\x02\xab\x81\xcd\xb0\x2c\xce\x8d\x3a\xb1\xf8\x75\xfb\x00\xb0\x15\x49\x10\x2b\x20\xa5\x27\x0d\xc7\x76\xd5\x43\xf1\xc1\x0c\x82\xa9\x67\x28\x35\x13\xcc\xa8\x0d\x53\xd9\x89\xc2\x9b\x3c\x97\xa0\xab\x47\x25\x08\xf2\xa8\x44\xb8\x38\xa9\x34\x52\x3b\x10\x33\x9b\xc5\x3a\x34\xaa\x77\xc5\xda\x6c\x6e\x68\xe5\x0a\xba\x9b\xd5\xcc\x2c\x09\xee\x1a\x3d\xe0\xc7\x4d\xb1\x35\xa7\x19\x01\x83\x8a\x80\x19\xfd\x42\x7f\xbe\x30\x4a\x6c\xf5\xaf\x98\x73\xe3\xbf\x05\x1c\xfa\x66\x13\xa8\x26\x01\xae\xa4\x05\x15\xee\x0c\xc7\x31\x06\x4b\x1e\xe5\xd1\x33\x46\xd2\x2e\xb9\xf4\x8c\x35\xbf\x0d\xe7\x3c\x73\x28\x4d\x61\xa3\xae\x26\x97\xda\xfe\x66\x17\x7b\xfa\xf2\xda\x08\x19\xa0\x0d\x15\x9f\x1f\x85\x7d\xd6\x9e\x6b\xf6\x0a\x3a\x9d\x40\xf3\xba\x9e\x5d\x0a\x30\xdc\xec\xda\x9f\xad\x9b\x5c\xdd\x52\x57\xbb\x3d\x16\x32\x6b\xdf\x34\x54\x91\x33\x26\xa0\x04\xe3\xea\x67\xc2\xa4\xfa\x31\xd6\x53\x53\x5a\xcf\x9d\x87\xa3\x11\x4e\x72\x4f\xf5\xca\x67\x94\xc9\x4e\x18\x45\xb8\xa7\x75\x2b\x8a\x14\xd7\x44\xb9\xc2\xbe\xe9\xf3\xef\xf2\x4e\xab\xd2\x3d\xb2\xda\xb8\x1e\xd8\x09\xd6\xf6\xab\x1b\x0b\xed\xf2\x28\x6a\xc4\x19\x3c\x37\xc7\xa2\x11\x36\x52\x3e\x4e\x2e\x45\xfc\x9d\x47\x8d\xdf\x5f\x3c\x53\xe8\x58\x23\x49\x1b\xaf\x4f\x4f\x1a\x13\x38\x83\xed\x13\x6e\xc3\xb9\x57\x06\x23\xd7\xe1\x6c\x96\x35\x14\xf8\x86\x4c\x1a\x5f\x32\xbd\x2c\x09\x6d\x5c\x4f\xe3\xf1\xd4\x56\x90\xf2\x59\x1c\x5e\xcc\x78\x23\x1c\xa7\x49\x96\x35\xc2\xd9\xac\x71\x91\x26\xd7\x19\x4f\xb3\x46\x28\xa2\xc6\x15\x4f\xb3\x38\x11\x59\xa7\xf1\x36\x11\xb6\xfe\x1d\x55\xb9\xda\x55\xa6\x05\x59\x23\x4c\x79\x23\x8a\xb3\x71\xb2\x4c\xc3\x4b\x1e\x41\xd1\xeb\x58\x01\xe3\x0d\xed\x81\x3e\x82\xce\x88\xc6\x72\x31\x4e\xe6\xb1\xb8\x6c\xcc\xc3\x2f\x49\xaa\x1a\xc0\xc3\x8c\x77\x1a\xef\xe0\xb7\x91\xf2\x09\x4f\x55\x8b\xef\xf7\x78\xfc\x25\x6b\xab\x76\xac\x3d\x1b\x57\xfd\x23\xf9\x5b\x53\x1d\x1a\x2d\x8f\x39\x8b\x1a\x56\x3f\xd7\x58\x27\xb1\xa8\x70\xd9\x33\x54\x81\x0d\x97\xe2\x61\x27\x9c\x48\x35\x87\xba\xad\x98\xa8\x23\x46\x0d\xb0\xb5\x5c\xc8\x23\xda\xf0\xde\xeb\xe7\xe1\x37\x30\x19\xc9\xc3\xa8\x73\xcf\x6e\xce\x63\xd1\x9e\x87\xdf\x76\x50\x8d\x9d\x9c\xef\x1b\xac\xf2\x1f\xfa\x42\x9e\x9e\x2d\x91\x92\x7d\x12\xb0\x73\xd1\x57\x7f\x02\x1e\x5c\x60\x18\x80\xb3\x4a\x67\x54\x73\x37\x77\x46\x75\xf5\xff\x91\xce\x3c\x5d\xef\x8c\x67\xc0\x40\x96\xac\x36\x29\x2c\x07\x1e\x0e\x9d\x21\xee\x04\x48\x4c\xfd\x20\x09\x5f\x74\x4b\x56\xf0\x9f\xef\x12\x1b\xab\x98\x90\x83\xa6\xac\x77\x98\x3e\x91\x85\x9d\x90\x94\xc8\x61\x3a\x2a\x59\x6e\x51\x11\x43\x3e\xc2\x42\x1d\xf5\x02\xcc\xe1\x7a\xd6\x26\x55\x6b\xde\x4a\x36\xb4\xb6\x83\xfe\x5a\x86\xa9\xe4\xea\xcb\x1a\xe1\x30\x5a\x7a\x5a\x83\xcb\xc8\x8f\x5a\x19\x29\xa4\x2f\x2d\x88\x71\x57\x18\xf2\xac\x5c\xbf\xf1\x30\xd5\x0f\xf0\x04\xc4\xf4\x25\x99\xe7\x5d\xf0\x57\x68\xea\x53\xc1\x84\x99\x8b\x53\x05\x62\xa6\x55\xa9\xd4\xf5\x69\x74\xc2\x54\x74\xc8\xcc\xa5\xda\xa5\x19\xd3\x37\xaa\xfa\x1e\x33\x7b\xad\xaa\xd0\x8c\xd9\xbb\x55\x85\x96\xac\x74\xc1\xe6\x79\xd7\x48\xb6\x5b\xb2\xb4\xf6\xa5\xdf\xdd\x29\xf0\xba\x6b\x35\x16\xde\x4a\x2a\x89\xb3\xaf\x0c\xd2\x4c\xc6\xb2\xcc\x50\x8e\xbc\xbb\xc6\x39\x19\x00\x0b\xa2\xa0\x12\xf4\xb6\x34\x4b\xea\xb2\x1a\xbe\x55\x73\xa1\x79\x71\xa2\x28\x0b\x17\xfd\x8b\x59\xa2\x10\x76\x9b\x05\x4c\x16\xbb\x10\x58\x54\xde\xea\x5a\x4f\x4f\xea\x4a\x93\x85\x66\x91\xeb\x69\xc6\x5a\xcb\x56\x8f\xef\x6d\xcf\x5a\x07\x7c\x7f\x7b\x0c\xdf\xd9\xf6\x41\x77\xfb\xa0\x6b\x0d\x59\x87\x37\x19\x6b\x85\xad\x47\xdb\x71\x49\x79\x9b\xb5\x92\xd6\xde\x76\xda\xea\xed\x6e\x0b\x97\x55\x86\x20\x23\x66\xcc\x2d\x00\x7d\x11\x4a\xa7\x44\x74\xb1\xbc\xb8\x98\x95\x8c\xfe\x3d\x97\x9b\x8c\xd4\xbe\xf1\x54\x8c\x4f\x65\xc5\x02\x75\xbb\xb7\x0d\x5a\xb7\x69\xb2\x14\x11\x6e\xf7\xb6\x39\x09\xbc\x08\x9f\x0e\x7a\x26\x37\x4b\xc6\x7b\x36\xbc\x96\x72\x6c\xac\x16\xa8\xf5\x87\x5a\xa8\xd0\x22\xef\xc2\xa5\xdf\xe6\x2a\xbe\x8d\x08\x15\xad\x77\xf8\xdf\xff\xc6\x7c\xe7\xa0\x0b\xf2\xd5\x12\xc2\xfc\xc1\x41\x57\x4b\x56\xaf\x9e\x49\x8c\x3e\x21\x8a\x02\x44\x28\x7c\x7f\x02\x0b\x72\x20\xbf\xfc\x09\xd1\xd0\x48\x4d\x7f\x32\xdf\x20\x31\xac\xb2\x7c\xfa\xb4\x41\xf6\xd8\xe0\x13\x9a\x5b\x24\xbf\xcf\xd9\x5f\x12\x87\x9c\x16\x9a\x78\x5f\x25\xdb\x31\x8f\x3a\xfa\x39\x68\xe7\xd2\xe3\x9e\xff\xe5\x9f\x2a\x0c\x4b\xe0\xc9\x1a\x56\x05\x27\x87\x8e\x7f\xcc\xca\xbe\x8b\x34\xdf\x08\x63\x31\xb4\x7c\x85\x76\x6f\x04\x2c\x8d\x56\x51\xfe\xab\x5a\xeb\x43\xd4\x06\x01\xf5\x11\x4d\xd8\x41\x77\x3b\x1d\xf6\x46\xad\x73\x9c\x0e\x77\x8b\x53\x44\x61\x51\x49\xbf\x1b\xa0\x16\x78\xd5\x19\x76\x47\xfd\x24\x68\x27\x9e\x1a\x79\xe9\xe8\x4b\x3c\x6c\x47\xdb\xa7\x50\xc7\x92\x76\x30\x8c\x09\x4d\x18\xbe\x02\x14\x6d\x8c\xb9\x42\x6a\x1d\x81\x12\x28\x0c\x87\x78\x04\x4b\x5b\x14\x01\x35\x7a\xc0\xac\x02\xeb\xeb\x10\x70\x69\xad\x64\xcd\x7c\x85\x00\x81\x78\x61\x61\xc2\x72\xf6\xd7\xee\xb1\xbf\x2a\x7b\x0f\xb7\xdb\xfe\x0a\xf4\xec\xbc\x7f\x4f\x84\x05\x49\x76\x7a\x0f\x3d\x08\xbf\x14\xbe\xdb\xb6\xb6\xaa\xb7\x86\x3d\x80\x80\xd8\x04\xdf\x0b\x10\xa1\xad\xe0\xaf\xca\x6d\x5d\xbf\xec\xdf\x01\x53\xfd\x73\x3b\xff\xdc\x22\x7d\xdc\x0f\xf0\xe7\x68\x9b\x0c\x3b\x8d\x11\x30\xd1\x5b\xe4\x73\x00\x3f\xb8\x1f\xd8\xaf\xcf\x1d\x95\x45\x3f\xff\xfd\x09\xa5\x75\xe1\x77\xaa\xf4\xb0\xdd\x1a\xf5\x87\xdd\xf6\x63\xda\x19\x6d\x93\x8f\x1a\x64\x39\x72\x50\x17\xf9\xa1\x2e\xf2\x18\x22\xcf\xd6\x13\x5e\xdd\x1b\xee\xa9\x6e\x68\xb1\xc6\xbf\xc8\x8a\xaf\x04\xaa\x95\xfc\xb5\xbc\x9a\x9e\x23\x38\x6c\xfa\x31\xbb\x9d\x67\x8a\x2a\xf4\x8f\x41\x1a\x05\x5a\x04\x20\xa3\x03\x48\x83\x23\x6e\x15\x64\xc6\x82\x80\x3a\xd4\xfa\x60\x65\x83\x07\x71\xa7\x74\x80\x72\x12\xe0\x90\xbd\xb3\x14\x2f\x21\x6a\xa9\xa2\xb6\x5a\xe6\xe1\xb0\x37\xea\xb7\x7b\x41\x8f\xc6\xec\xf6\x26\xe8\xd2\x28\x38\xc7\xa1\xda\x16\xdb\x82\x4e\xe1\x7b\x0f\xbe\xe7\xf0\xbd\x0f\xdf\x19\x7c\x3f\xd4\xf1\x2a\x70\x2a\xb1\x3a\x95\xc3\xe1\xc1\x88\x90\x6d\xb1\x82\xfa\xfe\xbc\x47\x7d\xbf\x4b\xa8\x8c\x0a\x42\x07\x3a\xb0\x07\x81\x6b\x1d\xd8\x87\x40\xa4\x03\x0f\x21\x30\xd5\x81\x03\x08\xcc\x75\xe0\x11\x04\x32\x1d\xf8\x59\x05\x56\x9a\xd3\xc5\x58\xac\x06\x73\x15\xac\x9b\x7a\x8f\x9b\x4d\xac\x5d\xd3\x29\xcc\x2b\xcf\x91\x4c\xe0\x8b\x94\x2d\x03\xd7\x48\xc9\x96\x76\x40\xd9\xd2\xee\x07\xa9\xbd\x15\xaa\x3c\xbf\xf0\x49\x92\x72\xe0\x20\xb1\xd7\x7a\xea\x03\x8c\xe1\x5b\xe5\x21\xe5\x29\x6a\x8b\x52\x98\x0a\x63\x9f\x05\x12\xe0\x0b\xf6\xf9\xad\x9f\x29\xe8\x5a\x39\xeb\xee\x6a\x85\xbf\x4b\x1c\x83\x97\x30\x42\xe1\x53\x26\x44\xd1\xaf\xec\x76\x45\x3a\xf3\x8c\x25\x65\xf8\x71\x67\xa0\xa2\x0c\xe4\x14\xb0\xfa\x37\x12\xc7\x84\xc2\x12\x6c\x36\x97\x98\x53\x64\x2e\x48\xf0\x06\x94\xae\xb3\xe3\x08\xf5\x64\x73\x7f\x2f\x1d\xe1\x96\xd4\x37\x18\x40\x21\x65\x4d\x11\x45\x1d\xe4\x68\x45\x6c\x2d\xf2\xf5\xbb\x81\x20\xdb\xde\x8d\xfa\xba\x04\xcf\x11\xec\x0d\x37\x32\xd2\x9a\x7f\x6b\xf3\xc2\x10\xdc\xee\x36\x96\xd6\x68\x85\x33\xe7\x47\xb9\x3d\x96\x81\x16\xb5\x10\xc0\x32\x5b\x27\xce\x8e\x26\x92\xa7\xc0\x01\x6b\xbb\xd1\xa6\xe5\xf9\x60\x2d\xd9\x6e\xdd\x01\xc5\xf7\x09\xf1\x4a\x6e\xb0\x98\xe8\x34\xe3\xcb\xfc\x5b\xe0\x96\xc1\x28\xb4\x52\x85\xdc\xbe\xc5\x92\x16\x64\x03\x6a\xc9\x16\xc2\x0b\x9e\xc6\x49\x44\x1b\xda\x75\x16\x29\x13\x12\x8e\xe8\x2b\xe8\x09\x57\x50\x17\xa0\x0d\x0d\x80\x74\xfe\x86\x40\x71\x18\x45\xed\x58\x5c\xf1\x54\xf2\xa8\x0d\x9e\xfd\x6b\xa4\x8a\x13\x60\x97\xa4\x34\x65\x09\xa1\x2f\x8c\x21\x87\x2f\x52\xed\xf7\x35\x36\x9c\xe8\xb7\x44\xa0\x46\xc1\xba\x20\xf1\x0c\x7f\xbc\xb0\x34\xbe\x35\xac\xc2\x64\xe5\xf8\x0b\xd9\xa9\xc4\x52\x9f\x80\x84\x66\x26\x64\x56\xf0\x61\x69\x57\xe2\xc4\x08\x2a\x25\x79\x9e\xd0\xac\xd9\x04\x33\x58\x60\x5f\xd2\x5a\x76\x6a\x65\xdb\x82\xd0\xb0\xd9\x04\x4b\x91\xe8\x18\x74\x36\x8e\x8a\x6f\xd2\x0a\x55\x86\xb8\x90\x12\x82\x1b\x99\x97\x6f\xe4\x58\xe5\x49\x9a\xcd\xca\xb5\xcc\x69\x98\xe7\x19\x21\xab\x2f\xb2\x33\x11\xec\x8d\xe7\xa8\x80\x7e\x71\xee\x92\x6a\xcc\x80\x7f\x91\xc0\xf2\xd5\xf7\xe3\x7b\xc9\x5e\x49\xdc\xa3\x28\x8c\x22\x44\xe8\x1f\x10\x6c\xf7\x28\xca\x96\x17\x32\x0d\xc7\xd2\xb7\x22\xf0\xb1\xb4\x5b\xea\xb7\x41\x0b\xd7\x6c\x19\xed\xc3\xb3\xb4\xb0\x0d\xd1\x94\x39\xdb\xdb\x6d\x2c\x5a\x58\xb6\xd3\x27\xdd\xbe\x36\x21\x89\xd3\x76\xa5\x8c\x6a\x97\x2d\x45\x02\x93\xab\x92\xa7\xe5\xe5\x69\xa7\x84\x90\x3c\xf7\x4c\xf3\xbf\xf4\x64\xa4\xbd\x47\x7c\xed\x48\xae\xef\xe3\xeb\x5a\x26\x3a\x28\xe4\x29\x41\xbc\x9a\x58\x3f\xe4\xce\xa9\x8e\xb1\xea\xb5\x4a\xad\xb7\x42\xc3\x6b\xf7\x44\x7e\xce\xac\x38\xca\x27\x44\x2b\xd9\xde\xcb\x71\x6d\xce\xe1\xa7\x91\xf6\xee\xf7\xcf\x32\x7d\x3f\x0b\xc5\x25\x5e\xdb\x99\xaf\x35\x4d\x4f\xcb\x7b\xd3\xd7\x71\x6d\xc8\xa4\x01\xca\x0f\x53\xde\x50\x30\x96\xe1\x25\x37\xca\x02\xcb\x54\x7b\xb6\x6f\xbc\x5f\x2f\x8c\x7d\x7d\x04\x5b\x2e\xab\x72\x6c\x36\x0c\xa4\x5f\x7f\xe0\xc5\x18\xcb\x19\x85\x2a\xad\xac\x28\xb9\x9a\xb1\x2d\x66\xed\xb7\xd2\x61\x87\xf9\x03\xd9\x92\xe4\x81\x77\x8c\xff\x5a\x15\x16\xf6\x6d\x5e\xad\x1b\xbc\x22\xed\xde\xee\xc1\xee\xee\xa3\x9f\xbb\x3f\xf3\x87\x41\xd9\x8a\x95\x87\x34\x17\xf0\x3f\xdd\x05\xdf\x9a\x8a\xda\x04\xbf\x48\x87\xb4\x02\x2a\x17\x96\x24\xeb\xd2\x21\xa7\x96\xb9\x3a\xa2\xdd\x92\x33\x3e\x29\xd6\x0c\x42\x95\xcf\x76\xde\xff\xc5\x98\x94\x53\x39\x60\x23\x06\x58\x3e\xc5\x31\x7b\x67\xed\x43\x69\x4e\x49\x4c\xa8\x10\x9e\x67\xae\x02\xac\x57\x9d\x58\xaf\x8e\x95\x6c\x52\xd1\x90\xfd\xc5\x71\xac\xf9\xf7\x5d\x1a\x7b\x92\xab\x87\x6b\x36\x9c\xc3\x75\x03\x5c\xd4\xb3\xaa\x1a\x96\x25\x4b\x4d\x1a\xd8\xeb\x0b\xab\xc2\xa5\xea\x2c\xd7\x66\x9d\x2f\x2f\x7f\xa0\x26\x7d\xcd\xf9\xd7\x8f\x35\x26\xa4\x5f\xbe\xfc\x41\x41\xc3\x3e\x29\x97\xe5\x02\xa3\xcb\x4b\x55\x29\xb2\x80\x51\x11\x5b\x13\xfd\xf2\xa5\xaa\x08\x79\xc0\xbc\x84\xf5\x14\x63\x0b\x48\xdb\x45\x56\x9d\xf3\xad\x01\x99\xd8\x97\x2f\x0b\x43\x4f\x1f\xad\xb1\xea\x5f\x2a\xb9\x8c\x0d\xa0\x97\x85\xfd\xea\xcb\xe2\x53\x55\xec\x94\x8c\x55\xab\x5d\x40\x37\xaa\xb0\x6b\xad\x3b\x55\x84\x4d\xab\x0b\x3b\xd7\xa6\xdb\x3a\x02\x4c\xe6\x98\x71\xb0\xe3\x61\xba\xa9\x0b\xfe\xd8\x80\xd4\xae\x67\x40\xca\x80\xd3\x5d\x5e\x2f\x9a\xa8\xa2\xc9\x5d\xd6\xad\x5f\x61\xf4\x1b\x58\xa0\xfa\x2d\xf1\x78\x74\x30\xa4\x05\xc3\xee\x37\x3d\x9a\x2e\xe2\x91\xee\xd8\x6f\x88\xfe\xa1\x35\x66\x7f\xab\xb1\x8f\xdd\x1b\xb1\xbd\x6d\xac\x4d\xd6\xda\xaa\x8e\x11\x1d\xa2\xe3\x63\x6d\xb6\xeb\x58\xdb\xbc\x92\xdc\x5a\x7b\x02\xbe\xdf\xb1\xb5\xe4\xa4\x42\x8f\x75\x45\xc7\x4e\x2b\x5c\x95\x75\x33\x71\x9c\x6c\x32\x96\xc4\xfb\xd2\x88\x66\xaf\x69\x78\xe6\xb9\xec\x9c\x27\xbe\xca\xe7\xc6\xac\x6f\xb8\x88\xb9\x90\x4e\x3f\xfb\x58\x35\xef\x18\x8d\xe8\xae\xee\x75\x4d\xfd\x72\xb8\xab\x15\x7b\x35\x9f\xe3\x37\x90\xe3\xb0\xfc\x96\x54\x80\x5e\xaf\x46\x6c\xb6\xba\xe4\x50\x8d\xc8\xb1\x19\x13\xf5\xbb\xa7\x46\xe5\xd8\x8c\x8b\x39\x25\x9c\x29\x2c\x13\x84\x1c\xce\xda\x95\x8d\xdc\xb7\xc3\x73\x8c\x28\xe7\x2e\x70\x8c\xe8\x4b\xdb\xf8\x63\xdd\x7c\xe8\x40\x1d\xbb\xa8\x90\xae\xf7\xac\x93\xcd\x55\xe3\xe6\x73\x6b\x95\xc1\x70\x67\xb5\x29\x65\xcb\xa9\x9d\x1b\x5b\xca\x26\xdc\x33\x6d\x99\xbb\x49\x53\xe5\x61\xd2\xa0\x21\x73\x55\x64\x8e\x46\x74\x5f\x8f\x4a\xa2\x47\x65\x60\xb5\x61\xb7\x7a\x30\x30\x99\xaa\x39\xcb\x6c\xcd\x86\x01\x0c\x35\x3b\xd6\x70\xa6\x6b\xb6\xe1\x9e\x31\xe1\x96\xb9\x9a\x55\xf9\xa2\xe6\x4c\x15\xc9\xd0\x88\x3e\xd4\x35\x87\x82\x66\xba\xf2\x53\xab\xa7\xab\x2a\x9f\x24\x29\x7e\x85\xd1\xe9\x26\xeb\x09\xff\xfe\xb7\x35\x97\xe0\x50\x61\x0c\x62\x50\xa4\x38\x3a\x4f\x4f\x37\x1e\x9d\x9b\x8a\x97\x4a\x9f\xc2\x62\xe8\x96\xb9\xdf\x5e\xf2\xa9\x31\xed\x5f\x73\x32\xf7\xba\xdb\xeb\xf0\x4b\xb0\x55\xe9\x87\x1b\x4b\xdf\xa3\xf8\x29\xa2\x07\x9b\xca\xf3\xbd\x7b\x94\x3f\x45\xf4\xd1\x46\x00\xfb\xf7\x01\x70\x8a\xe8\xcf\x1b\x21\x3c\xbc\x17\x84\x53\x44\x1f\x6f\x04\x71\xb0\x01\x04\x2c\xfc\x62\x4a\x28\x9a\x67\x76\xf9\x7b\xb1\xbd\x03\xbd\xfe\x4e\xd5\x6e\x54\x87\x24\x04\x74\xe8\xa3\x0d\xe9\xe0\x4b\x42\x43\xc1\xf4\x9c\x1e\x86\x96\x67\xfa\x84\x3d\x3e\x0c\x45\x8b\xa1\x53\x44\x66\x1c\x87\x82\xa6\xdc\x43\x02\xc7\xee\xb8\x39\x50\xc7\x8d\x1a\x74\x8c\xba\x1d\xd4\x82\x57\xf6\x24\xc5\x00\x72\x03\xbc\x08\xe0\x8d\x85\xde\x04\x33\xbb\xfd\x0a\xba\xce\xed\xc1\xef\xc6\x30\xdf\xf7\x44\xf0\xa3\x8b\x0b\x63\x90\xe5\xbb\x1f\xfd\x36\x9c\x73\xa4\x21\x2d\x05\xf3\x2c\x93\x16\x8d\x5d\x94\xe4\x0d\x56\x4b\xa1\x48\x0f\xf6\x5e\xd2\x25\x60\x57\x60\xd4\xa0\x8e\xbb\xc3\x78\x9e\x83\x96\x53\xc2\x3e\x48\xac\x5f\x0b\xc0\x7d\x5e\x2a\x4f\x26\xd8\x58\x4b\x8c\x59\xea\x80\x18\xef\x3e\x80\xac\x25\x24\xcf\x91\x35\x51\x80\x68\x08\x6a\x74\x6f\xb0\x1c\xc6\x23\xd2\x57\x7f\x3d\xc4\x4e\x90\x00\xe2\x4b\xf8\x98\x7e\xfe\xc5\x61\x9e\xaf\x9b\xc0\xb1\x15\x62\xfd\xb6\x41\xbf\x4b\x10\xc8\x5b\x41\x8f\x14\x79\x55\x43\x47\xea\x87\x79\x4d\xfd\xa8\x7c\x51\x3c\x99\xd4\x8b\x92\x59\x49\xa5\x0a\x6f\xd7\x77\x2b\xa0\x52\x71\xca\x34\xf7\x5b\x81\x24\xf5\xf9\xb2\xeb\x58\x5d\x43\x09\x3b\xe0\xfb\xdb\x38\xf5\xdf\x2b\xda\xd5\x07\x0c\x42\x25\xfb\x0b\x4b\x42\x6e\xc7\x61\xc6\xf5\xab\x5d\x10\xb3\x8f\x66\x40\xc1\x4b\x81\x96\x1d\x3f\x84\x0c\xfa\x15\xaf\x94\xc3\x4f\xb6\xc8\x42\x19\xc4\x9e\x9f\xc5\xec\x96\x20\x66\x90\x0e\x8e\x10\x78\x29\x87\xb9\x53\xfc\x1c\x07\x7c\xdf\xcf\x01\xcf\x86\x7e\xfa\xde\x01\x7f\xe8\x67\x50\xcb\xa4\x48\x6f\x27\x64\xe7\xe7\x83\xfd\x72\x16\x78\x87\x2c\xe7\x39\xe8\xee\xff\xec\x32\x59\x67\xfd\xda\xd4\x56\x3b\x5d\x39\xeb\x74\x71\x70\x84\x63\x3d\x9f\x5c\x44\x27\x93\x75\x75\x49\x35\x55\x8e\xd4\xc3\x9c\xfd\x85\x41\xc2\xb3\x74\x5c\x28\x22\x30\xcf\x37\x4c\xb7\x8a\xd5\x6e\x24\x98\xc7\xdb\xef\x7f\x92\xc1\xaf\xd2\xce\x2f\x2f\xcd\x99\x64\xda\x0e\xa8\xb3\xf6\x4a\xbb\xb4\x47\xda\xbd\xda\xd9\xa9\x64\xf6\xa9\x0d\xb3\x44\x4c\xe0\xc1\x5e\x6b\x6f\x0d\x8c\x59\x03\x77\x01\x69\xf5\xd6\x4a\xe9\xf1\xbe\xab\x90\x47\xd8\x98\x56\x18\x19\x68\x4c\x5a\x8f\x2a\xd0\xac\x01\xd7\xfb\x03\xc4\x3e\xf1\x02\x40\xdb\xbd\x75\xb8\xb0\x70\xcc\x97\x5a\x83\xf7\x05\xdf\xaa\x76\x57\x2f\x51\x69\xa6\xcf\xe3\x55\x51\xd9\x62\x6a\xb9\xb6\x7f\x93\x58\xb6\xb0\x3f\xbd\xdd\xe0\xc0\xde\x83\xa5\x2d\xaa\xb2\x57\xe7\xc0\xec\x91\x0d\x15\x1c\xf0\x7d\x80\x4f\x0f\xf8\x7e\xa5\xa4\xdd\x7f\x1b\x4a\xf6\xf8\x9e\x2e\xd9\xe3\x7b\xa4\x5d\x38\x2b\x35\x79\x2d\xff\x4d\xde\x6d\xc1\x1d\x36\x87\x3e\x4c\x4b\xbb\x83\xe7\x39\x36\xaf\xa8\x71\xf6\x5e\x8e\x31\xe9\xaf\x73\x7b\x82\x4a\x94\xbe\x68\x24\x7b\x61\xcd\xca\x1e\x6e\x34\x53\xb6\x48\x32\x69\xce\x70\xa9\x77\xe8\x24\x4d\xe6\xac\xde\xb6\x6a\xe5\x11\x0d\x9e\x09\x4b\x12\x18\x70\x13\x71\xff\x94\xed\x7f\x91\xf8\x56\x26\xc0\xaa\xa1\x0a\x74\xc0\x57\x8e\x11\xe4\xf3\x6f\x08\xe9\x4c\x97\xf3\x50\xc4\xdf\x39\xde\x92\x25\xde\x4e\xad\x6b\x3b\xdb\xd4\xb7\xc9\x75\x9d\xeb\x20\x7d\x39\xa5\xc9\x5c\x6b\x00\x73\x5d\x40\x56\xdf\x47\xfe\xdb\x9e\x41\x8f\xa0\x6f\x32\xf9\xdf\xec\x99\x4c\xee\xea\x97\x4c\x4a\xbd\xba\xe4\xb2\x2e\xeb\x1b\xed\xaf\x46\x1f\xa6\xea\x3a\x87\xd0\xc8\xf0\xcd\xa0\xa4\xa9\xf8\x48\xd6\xdc\xc4\x91\xbe\x85\x9d\x2a\xbd\x2e\xa0\x9f\x1c\x6a\xf1\x90\x2b\x78\x2e\xd6\x0f\xba\x56\xd8\xaf\x7a\x3b\xe7\xf9\x96\xf0\xc6\xb0\xd9\xc4\xd5\x23\x1e\xeb\xeb\xb5\x72\xf6\xeb\xd6\x17\x1b\xef\xa9\xf7\xf2\x1c\x78\xdf\xda\x6b\x8f\xe5\xdd\x5a\x24\x48\xfa\x8f\xd6\xa6\x1f\xfa\x91\xeb\xff\xf3\x8e\x3c\xf1\x3b\x52\x6a\x3c\xdc\x94\xa5\xa6\xfb\x79\x8b\x6e\xc8\x6b\xce\xd7\xb5\x7e\xac\x25\x63\xbf\x2f\x34\x66\x57\xda\xd3\xdf\x77\x59\x78\xbc\xdd\xda\xc2\xd5\xe5\x9f\xf8\x81\xb8\xd2\x4d\x0c\x9d\x4b\x59\x9a\xe7\x08\x13\xa4\x48\xf7\xbe\x01\xa0\x9f\xa3\x12\x85\x29\xda\xe1\x32\x6f\x89\x2a\x0e\x4a\x13\x2d\xa1\xd0\x73\x65\x4c\x86\xd8\x2f\xa4\xe1\xa8\x28\xdb\xcd\xd3\x70\x5e\x3b\x57\x34\xbd\xef\x6c\xa5\xff\x1b\xb3\x05\xde\xc8\x8b\xf9\xc2\xc2\x0f\xd2\x1f\xae\xbd\x27\x4c\x34\x9b\xe2\x09\xfb\xc1\x3c\x97\x7a\x7d\x92\xd6\xed\xb8\xf2\xb9\xa5\xf2\x41\xbc\xc1\xc2\xed\x08\xaa\xa8\x12\xa8\xda\x45\xff\x23\x58\x66\x86\x3c\x60\x7f\x6c\x78\x04\x9a\x7a\x88\xfb\x2c\x14\x97\xec\x9f\x40\xbd\x98\x57\x8d\x97\x5e\x40\x1d\x7c\xec\x1f\x10\x31\x0f\xbf\xb1\x33\xfd\x15\x0b\x76\x02\x5f\x8b\x30\xcd\x62\x71\xf9\x62\x16\x5e\x66\x35\xf5\x80\xaf\x69\x73\x3e\xe9\xda\x4a\x62\x1a\xd6\xd0\xd2\xfa\xd3\xb9\xb6\x37\x5d\xd5\x93\xb3\xf2\x71\xc6\xfc\x2c\x24\x6b\xf1\x33\xa3\x53\x73\xbb\x14\xb1\x0c\x04\x5d\xa4\x71\x92\xc6\xf2\x26\x38\x1e\x8a\xd1\xca\x13\x1a\x06\x3b\xaf\x1b\x78\x6c\x1d\x5b\xaa\x2d\xdd\xa7\x22\x91\xe5\x0a\x73\x10\xc9\x23\x46\x40\x4d\x38\x97\xca\xad\x16\x81\xc3\x5a\x0c\xd3\x51\x47\xd5\x3d\xc2\xdc\x0b\x14\x4e\x6c\x2a\x47\xbc\x8f\x0c\x83\x03\xc7\xd2\xc5\xaf\x07\x4a\x2f\xcb\xff\x17\x31\x70\xc0\xbf\xff\x5b\xec\xbb\x02\xe2\x1e\x98\x77\xa5\xc4\x7f\x85\x75\x93\xff\x3f\x60\xdc\xe4\x7f\x03\xdb\x26\xf7\xc4\xb4\xdb\xec\x6f\x22\xd9\xf7\x46\xb1\x35\x64\x40\xaf\xef\x8d\x5c\x9b\x32\x0a\xb1\xfe\x6f\xd0\x6a\xfb\xea\xcc\xfe\x90\x1a\xb7\x02\xef\x30\xac\x56\x56\xd1\x6c\x98\xa1\xf3\xfa\x51\x78\x43\x74\x2e\x9f\x38\x88\xbd\xea\x34\xe8\x32\x7c\x5a\xf6\x17\xc4\x7a\xec\xb0\x91\x41\xe8\x8c\x12\xc3\x5d\xb5\x82\xc7\x94\x2c\x70\x75\x1b\x19\x99\xa2\x09\xaa\x01\x81\x6b\x07\x58\x3f\x0c\xb8\x33\x2e\x6c\x2c\x25\x06\xdc\x33\x51\x6b\x05\x6e\xb8\x67\xa2\xb6\x24\x89\x53\x6a\x6d\x86\xc9\xca\x34\x57\x21\xa3\x1b\xf8\x33\x5a\xbd\xa5\x74\x31\x5a\xac\xf5\xf5\xe9\x89\xf6\xec\xce\xaa\x6a\x3b\xf5\x87\x86\x93\x85\x94\x0c\xf4\x59\x38\x15\x4c\xf6\x4b\xf7\xe3\x52\x11\x3d\x81\x37\x4a\x0d\x61\xc6\x07\xcc\x4d\x99\xef\xa7\xe0\x16\xf6\x05\x16\x54\xf6\x4b\xf6\x33\x86\x67\x23\xdf\x0e\xc4\xf0\xd3\x08\x05\x77\x65\xf8\x84\x48\xf0\x46\x7b\xea\x29\xdc\x07\x79\x1d\x23\x7d\xd3\x3e\x3d\x44\x98\xf8\x89\x98\x04\x1b\x06\xa8\x75\xd0\x5d\xdb\x42\xdb\x6a\x61\x97\x8b\x17\xd2\x46\x9f\x10\x55\xbd\x41\x9f\x10\x21\x81\xd7\xaf\x1f\xf4\x6a\x53\x9f\x0c\xba\x9f\x2d\x2a\x6b\x70\xe3\xd4\x18\xf1\x00\x4b\x22\xe0\x9d\xed\x86\x31\x87\x7c\x1e\xb7\x50\x63\x7b\x87\x68\x59\x02\xce\x4c\x4e\x44\x25\x43\xe8\xd0\x00\x7b\xa3\x05\x3a\x81\x7a\x75\xf2\x95\x5e\xdf\xfb\x16\xfe\x52\x8e\x51\x60\x03\xf0\xfc\xf6\x29\x11\x1c\x80\x7d\x32\x1c\x53\xc1\xd0\x10\xb5\x78\xeb\x27\x8c\x46\x3f\xa9\xcb\xf2\x89\xef\x1a\xd8\x08\x73\x9a\x25\x61\xdc\x03\x83\x81\xd4\xc0\xf9\xce\x4d\x98\x6c\xfd\x34\x44\x64\xf4\x53\x1d\xf3\x52\xb4\xd2\x16\xaa\x1d\x38\xd4\x4a\xec\xca\xfe\xf5\xf4\xe4\xed\x26\xf7\xf7\x85\x24\x9d\x59\x19\xa5\x05\xb1\x9c\xcd\x0c\x8c\xea\xd6\x28\x43\xb1\x0b\xde\x90\x8d\x88\x0b\x44\x6c\x13\x51\x14\x45\x0d\x30\xe4\x7a\xac\x0d\xb9\xda\x56\x36\x86\x2f\x07\x67\xa3\x4f\x76\x86\x97\x22\xfe\x56\x03\xdf\xf3\xa2\x54\x5e\x96\x3b\x70\xb6\xaa\x92\x26\x6a\x53\xe3\xfc\x83\xb9\x0d\x6c\x52\xe9\x49\xcc\xe6\x79\xd7\xb0\x75\xc1\x14\x64\x22\x00\xbf\x5b\x03\x75\x1b\x83\x5a\xab\x59\x45\x54\xf7\xcd\x04\x27\x54\xf7\xdb\x04\x8d\xa2\x2e\xdc\x40\x81\x77\x1b\x51\xad\xd4\x65\xa2\x74\x40\x1f\x59\x6a\x01\xb0\x1b\xae\x31\xd4\x37\x3c\x5c\x94\xbd\x0a\xfb\x3e\xab\xbd\x05\xa3\x9b\x6d\x1f\xc0\x6b\x29\xee\x8a\x70\x83\xbd\xf0\xed\x05\xeb\x2e\x7f\xba\x4e\xd8\x17\x66\xca\x36\xa7\xdd\x58\xac\xda\xbd\xb9\xdf\xb7\x15\xa6\x88\xad\xd9\xc7\x1b\xc0\xce\x1a\xc0\x35\x48\x14\x2b\x3e\xb3\x3a\xf8\x56\xe8\x03\x56\xca\x98\xc7\x33\x8c\xcb\xec\x49\xb2\xb3\x67\x08\x54\x1d\xb5\xb7\x8d\xc1\x17\x58\x19\xfd\xd2\x75\x42\x90\xbd\x81\xb9\x88\xc2\x9b\xec\xb5\xd0\xde\x51\xd7\x27\xe3\x9a\x6f\x44\x5f\x8a\x99\x61\xe6\x37\xab\xc1\xd9\xd7\xc7\x15\xe6\x06\x48\x83\xaa\x40\x8b\x59\x35\x61\x14\xe1\x47\xaa\xf5\x92\x80\x6a\x9f\x3f\xfc\xac\xf8\xac\xab\xcd\x8a\xc4\x80\x15\x3b\x55\xd1\xdf\xa9\x02\xba\xf0\x5a\x54\x97\xa5\xa7\x27\xb1\xbe\x3e\x2c\xfc\x77\xe5\x71\xe2\xb0\xa6\xf8\xda\xea\xa9\x01\x5f\x0f\xc0\x2d\x0f\x85\x4a\xb0\x54\x98\x99\x62\x66\xc2\xfe\xc6\xed\xbd\x65\x24\xb3\x02\xeb\xc7\x59\x96\xd0\x7f\x7b\x78\xf8\x96\xcd\xbc\x38\x88\x38\xac\x80\xc3\xf5\x14\xaa\x15\xcb\xf4\x4c\x94\xf5\x79\x60\x1d\x4b\xf7\x91\x16\x18\x2d\xa8\x3d\xcc\x99\xac\xfa\x6f\x22\xc4\x98\x7a\x0c\x2a\xea\xbc\xe6\x85\xa8\x34\x05\x66\x3d\xaa\xc9\xe4\x6d\x09\x13\x49\x02\xe9\xe6\x32\xf2\x71\xc8\xff\x64\x9c\xb0\x41\xd0\x81\x5d\xdf\xbe\xe3\xf4\x20\x0f\x1e\xdd\xb1\xd0\x6c\xdb\xfc\x85\xf0\x5f\xb4\xad\x30\xa0\x6b\x57\xfd\x5d\x93\xe1\xd1\xd6\xfd\xf5\xd1\x7e\xf0\x28\xcf\x1f\x15\x53\x04\x03\xcf\xeb\xc7\xba\x74\x31\x83\xa3\x17\x37\x38\x0f\x1e\xa9\xee\xb6\x1f\x95\x89\x80\x48\xdb\x7e\x79\x64\x96\xb1\x95\xca\x58\xdf\xb4\x9e\xe6\x08\xae\x65\xd1\xe8\x37\xd2\x76\x7d\x9a\x76\xee\x6f\x9e\xc3\x3c\x6f\x83\x3f\x9a\x08\x85\x94\x33\xf3\x9b\xb1\x5f\xb9\x61\x70\x2c\x25\x67\xee\x2b\x63\x89\xd0\xdc\x0b\x85\x7c\x33\xf7\x95\xb1\x4c\xe8\xfc\x0e\x33\x67\xcb\x8a\x58\xf7\x0c\x72\x38\x8c\xaa\xf6\x8d\x34\xb1\x6e\x6f\x8a\x6b\xfa\x8e\x17\xd3\x3b\x57\x42\xad\x9f\x5d\x4e\x0a\x83\xc9\xc0\x33\x30\x9a\x53\x25\x9e\x80\xb6\xa5\x01\x93\x10\x5e\x64\x98\x93\x27\xbd\x03\x6d\xfd\x04\xf3\x6d\x76\xe0\x4c\x38\x6d\x79\xc7\x46\xb3\x29\x41\x16\xfa\x58\x1a\x26\x0f\xf5\xbb\xc1\xcc\xfa\x31\x0a\xe0\x5b\x5d\x63\x3f\x22\x31\xa8\xa0\x9a\x8b\x44\x0b\xdc\xc4\x8a\xa6\x68\x36\xf1\x96\x34\xec\xac\x73\x2d\x77\xfa\x5a\xbc\x4b\x93\xcb\x94\x67\x59\xdf\x13\xfd\xe6\xed\x58\x17\x03\x5b\x41\x41\x7d\x81\x3c\xc7\xf5\x09\xaa\x21\x77\xd1\xa2\x35\x25\x40\xe7\xdf\x50\xaa\x25\x6c\x4b\x1f\x9e\x71\x60\x07\x60\x65\x26\x7b\xe3\x93\x40\x81\x5a\x77\xed\xb3\x00\x6c\xaf\x8d\x05\xec\x40\xe3\x9a\xe2\xe5\xe1\xed\x51\x6e\x06\xd6\x12\xd2\xd8\x36\x0b\x46\xcb\xa3\xb4\x1d\xfe\x5e\x21\x31\x8c\xb5\x54\x80\x2a\xbf\xcf\x49\xa5\x4e\x97\x40\xb7\x7a\xd4\xda\x7b\x6d\xd4\xbb\x76\xd6\x2d\xb3\xd7\xe6\x5f\x12\xc7\x6e\x35\x58\x87\x7c\x46\x54\xb8\x80\xcf\xcd\x5c\xfa\xbd\x2c\xd4\x37\x0b\xe6\xd8\x34\xcc\x8e\x66\xf1\xa5\xe0\xd1\xab\x64\x99\xae\x6d\xac\xcd\xea\x64\x98\x33\xde\xd7\x0f\x44\x1e\x8d\x13\x74\x69\x75\x74\x49\x9b\x93\x07\x07\x8a\x20\xea\xda\xf3\xfa\xf8\xf4\x6c\x13\xd2\xed\x95\x7b\x5a\x3a\x9d\x34\x8a\xd4\x2d\xd5\x66\x16\xf8\x0f\xca\x3c\x2c\x95\x31\x4d\x78\x53\x5e\x29\x9b\xfb\xe9\xef\x51\x53\xf6\xfd\xfa\x09\x74\x2f\xb5\xbb\xa2\x38\xfb\x45\x9a\xef\xb3\x67\xe6\xdb\x4a\xd2\x6c\xa4\x46\xca\x6e\xb5\x57\xb6\xcc\xdb\xd2\x33\x41\x7d\x99\x67\x89\x16\x6b\x94\x3c\x6a\xbc\x17\xf1\x15\x4f\xb3\x70\xd6\x38\x8b\xe7\xdc\x81\x52\x3b\x38\x63\x27\x5a\xbc\x32\x6b\x84\xe3\x31\xcf\xb2\x24\xad\x4a\xc8\xbf\xcf\xb8\xb6\x81\x60\xd5\xdf\x11\x4d\x05\x71\x08\x70\xa6\x85\xec\xd5\xd7\x9d\x20\x20\x8b\x85\x81\xe8\x1b\x4e\x2c\x39\x03\x10\xe0\xe3\x4e\x00\x2a\x47\x51\xfe\x46\x97\x57\xc3\x51\x92\xf2\x57\x11\x9b\xd5\xf8\xb1\xb7\x2e\xfe\xae\x3a\xbf\x82\xbc\xb3\x49\xc6\xd4\x21\x75\x35\xe8\x9b\xd1\xfd\x35\xe7\x8d\xb7\x5f\xa9\xd5\x80\x08\xd6\xe4\x6f\x56\x84\xb8\x7d\x73\x3a\x8d\x27\x92\x47\xaa\x9b\x7e\xb8\x3a\x46\x7f\xc3\x13\x41\x26\xdb\x99\x06\x52\xd1\x18\x52\x94\x6a\x9c\x88\xb2\xc5\x02\x75\x97\x86\x8e\x57\x5a\x34\xa0\x74\xff\x95\x93\x0c\xcf\xe4\x76\xa5\x6e\xd7\x81\x95\x4b\xa2\x98\x33\x6d\x89\xa4\x73\x1e\xfa\xe6\x84\x60\xc9\x82\x39\xb6\x50\xab\xca\xaa\x8f\xc3\x75\xb0\xac\xba\xd3\xae\x21\x2b\x95\x96\xdb\x89\x09\x79\x6a\x0c\xc2\xd5\x94\x76\xd6\x59\x6a\x12\xad\x58\xee\x44\xb0\xd3\x3a\xb9\xb5\x68\xed\xcd\x11\x94\xd2\x63\x36\x51\x68\x14\x97\xe0\xaf\xc0\x82\x4f\x86\x62\x04\xe6\xdb\x0a\xd5\x80\xa9\x6f\x6b\x2f\x83\x77\x77\xac\xae\xf8\xc2\x14\x0c\x67\x3c\xcf\x11\xb2\x66\xb9\x9d\x2d\x2a\x5b\xb1\xe1\xf2\x1b\xe9\x61\xf0\x52\xaf\x1d\xc2\xc3\xb3\x4a\x6f\x17\x1e\x54\x92\x61\x3a\x62\x50\x24\xf5\x8b\xd8\x76\x15\xed\xb9\xf0\xfa\x83\x2e\x92\x64\xc6\x43\x51\x42\x73\x71\xa6\x6d\x4e\x09\x26\xa9\x2c\x8c\xc1\x30\xad\xfa\x1d\xa8\x78\x68\xfe\x56\x8f\xde\x99\xf3\xd0\xa2\x68\x30\x5e\x21\xe3\xfd\xb8\x40\xf9\x83\x6e\x81\x7e\x09\xaf\xc7\x92\x62\xd1\x0a\xc9\x83\x47\x34\x35\x9e\x90\x01\xcc\xd8\xf6\x59\x5b\xdb\x7a\x04\x36\xb6\xc6\xc3\x04\xba\x2c\x29\x4e\x2a\x65\x0c\xc0\xf1\x6a\xb2\x41\xb8\xb0\x70\xe4\x64\x50\x17\x93\x69\xc8\x47\x0e\x93\x32\x51\x1d\x2b\x3f\x78\xe8\x04\x0f\x52\xd2\x4f\x0d\xbf\x82\x0a\x12\xa4\x2b\x3a\x51\xf8\x88\xef\xfb\x68\x13\x2d\x7f\x5e\xce\x06\x1e\x29\x36\xa4\x74\x64\xf2\x7e\xb1\xb0\xee\x70\x9c\x69\x4a\x99\xe7\x5b\xa2\x2f\x03\xbc\x01\x1e\x13\x85\x15\xcd\xc1\x60\x30\xc8\x07\x83\xfc\xf8\x38\x8f\xa2\x28\xda\xb9\xac\xb7\xfe\x64\xec\x57\x69\x01\xfd\x0d\x60\x09\x74\xd2\x13\xe5\xd8\x7c\x11\x15\x79\xa0\x8c\x11\xb3\xdf\x8c\xaa\x99\x0c\x05\x73\xf8\x41\x84\x00\xcb\x9b\x08\x67\xf6\x8d\x2d\x04\x04\x9d\x3c\x8f\x89\xf0\xfd\x33\x6d\x94\x12\xd0\xd5\xf8\x59\x87\x62\x54\x4c\x67\x42\xfa\x89\x2b\x12\x24\xc5\xf0\x3d\x88\x76\x62\xd7\x90\x30\x93\x2f\xc0\xfd\x53\xad\x50\x45\x4d\x15\xfc\x69\xb7\x8f\xb4\xc7\x28\x14\x20\x55\x1e\x79\x95\x0a\xd2\x17\x58\x92\xc0\x9b\xad\x07\xd9\x4e\x0c\xaf\xd0\x93\xea\x8b\xaf\xb3\x60\xa7\x8d\xb3\xe8\xd7\xdb\x37\xea\x1c\x19\x0a\x2b\xfa\x22\x46\x4c\x13\x6b\x43\x74\x8e\x5a\x2a\x64\x0e\x52\xad\xb2\xe6\xa8\x8a\x3b\xb5\x1c\x7c\x1f\x93\xf8\xae\xfc\x9d\x2c\x59\xa6\x63\x6e\x37\x4b\xb2\x9e\x44\x5a\x28\x47\x2d\xe7\x49\xcb\xc6\x42\xef\x0c\x02\xb1\x41\x6b\x23\xb1\xee\x60\xb5\x0a\x69\xdf\x0f\x0d\xdd\x6b\xd1\x28\x28\xc5\x97\xca\x74\xe2\x4c\x2f\xdc\x3c\xff\xce\x49\x47\x72\xb0\x12\xd8\x47\x7a\xe9\xa0\x00\x65\x32\x14\x51\xa8\x50\x47\x34\xf2\x41\xde\x55\x75\xa9\xbe\x4e\x01\xc1\xeb\x11\xb8\xc3\xba\x5f\xb7\x20\x6b\xb9\x02\x88\xda\xd4\x41\x9d\xf8\x9d\xff\xc7\x9d\xd9\x54\xe1\x7a\x2d\xf5\x7d\xd3\x2e\xa8\xef\x94\x55\xf6\x21\x41\xf6\xe7\xdf\xc2\xb1\xbb\xd0\xbe\xf1\xaa\x1a\x9d\xd6\xb2\x58\x2b\xe5\x48\x50\xbf\x62\xe7\x15\x5b\x9d\x4c\x83\xba\x04\x70\xf4\x5b\x4e\xb1\xb2\x07\xe6\x92\x54\x57\x70\x62\x3d\xee\xa6\x23\x42\x85\xc3\xf9\x2b\x50\x87\xe9\xc8\xd3\x5a\xad\x26\x95\x3d\xb1\x22\x8f\x49\x9c\x29\xca\xdc\xb3\x63\x8c\x3a\x60\xbe\xa5\x85\xfe\x51\x72\xf0\x5a\x6d\xea\xdd\x30\xb5\xa3\xdf\xbb\x01\x13\x30\xe1\x58\x1d\xb5\x61\x3a\xca\x73\x1c\xb3\xda\x46\xb6\x50\xbe\xb1\x1e\x5a\x07\xca\x6f\x62\x5c\x6d\x89\x6d\x45\xb3\x09\x3e\xfb\x90\xf6\x59\xb3\x69\x04\xf5\x2a\xe6\x6b\xbe\x86\x50\xb5\x68\xcd\x48\xd5\x96\xdd\x12\xb6\xc4\xfc\xee\xcc\x2b\x6f\x49\x6b\xb7\xba\x1b\xef\xa5\xea\x42\xee\xe3\xa5\x5e\xbc\xe8\xdc\x2b\x8f\x48\x9e\x3f\xf3\x96\x36\xa1\xbc\xbc\xc9\x0a\x0f\xbe\xa5\xad\x06\x31\x24\xd8\x08\x13\xaf\x65\x66\xa7\xbc\x3c\x31\x1e\xe8\x66\xf3\xef\xd4\x5a\x3d\xb2\xfe\x6f\x06\xa2\xe2\x11\x79\xfd\xe0\xd9\x30\x24\x45\xda\xda\xb8\x78\xad\x7f\x5e\x1d\x9c\x4a\x75\x6b\x23\x74\xcf\xe6\xc0\x58\xc1\x3b\x4d\xcd\xf8\xfc\xc2\x2d\xb7\xb7\xf2\x16\x56\x3c\x7f\x41\x59\x00\x32\x89\x53\xf0\xb3\x59\x65\xe5\x56\x46\xdb\x96\xac\x94\xf9\x50\x6a\x42\x7d\x99\x6b\xd7\xd8\xca\x33\x47\x81\xa8\x24\x15\xff\xe9\xf6\x46\x70\xce\x1e\xcb\xc1\x21\x6f\x36\xb5\xe8\x82\xdd\x5f\x36\xc5\xdd\xb1\x3f\xb8\x91\x9c\x61\x4c\xd0\x72\xff\x93\x63\x51\x19\x30\x12\xf0\xbe\x18\x72\xcd\xf1\x1e\x05\xa2\xd4\x87\x41\x2c\xea\x58\x54\x0e\x58\xb9\x4d\x83\xb8\x0e\xf8\x5a\x9e\xa2\xb2\xb5\xa4\x52\xe5\xd5\xeb\xfc\x47\xd5\x43\xfe\x1f\x36\xc0\x5e\xf3\xb5\x4d\x80\xc4\x52\x23\xee\x7d\xef\x96\x0a\x94\x6e\xde\x57\x77\xde\xbc\xa5\x72\x6e\x7f\x95\xab\x77\x97\x6c\xd5\x45\x7f\xe5\xfa\xdd\x90\x36\x59\xce\x66\xd5\x24\x7b\x37\x3f\x5a\xbf\x9a\xad\x33\xfc\xd4\xbf\xa1\xd7\x60\xf8\x77\x74\x5d\x62\xed\x8d\xea\x3c\xe4\xd7\x5c\xa7\x9f\x3f\x77\xfa\x1b\xee\xea\xbf\x05\x7b\xe3\x7d\x5d\x5f\x41\x75\x48\x7f\x04\x7e\x10\x8b\x7b\x00\xaf\xfa\x92\xaf\xc7\x07\xca\xc3\xe1\x61\x04\x35\x7d\xa9\x49\x75\x4d\xd9\x50\xd9\x7d\x31\x06\x45\x9c\x96\xae\xfd\xba\xf9\xdc\x88\x33\x54\x0b\xd7\xce\xd8\x1d\xa5\x4b\x85\x6b\x66\xe3\x07\x08\x47\xb5\xd3\x1b\x50\x0e\x9b\xed\x07\x77\xed\xfa\x2e\xf6\x6e\xdb\x12\x0c\x75\x19\x7e\xac\xbd\x6f\xdd\xe4\xad\xdd\x6e\x25\x00\xfe\x4d\xbb\x06\x19\xd7\x14\x60\x2f\x78\x75\xa6\x6b\x2f\xd8\xfb\xd6\xbf\x7e\xd8\xfe\x5f\x0e\x4e\xfd\xfd\xbf\xde\x9c\xba\x61\xaa\x45\x49\x6a\x7a\xf2\x7e\x7d\xc0\x36\xa2\x25\x7f\xbf\x61\xd5\x9b\xf2\xff\x70\xf4\x06\xb1\xd8\xdc\x44\xdb\x94\xba\x91\xb3\x69\x35\xe3\xe6\x7a\xf0\xc7\xda\xa8\x95\xab\x5b\x1f\xb3\xfb\x35\x47\xb3\xb0\xb2\x77\x83\x9a\x31\x42\x0b\xd0\x93\xe0\x60\x9f\xb2\xec\x88\x7a\x3c\x0d\xd3\x23\x89\xbb\x06\x6d\xb6\x5e\x21\xaa\x57\xb2\x25\xf4\x9f\xf6\x7a\x7d\xd1\x47\x8b\x39\x0a\xd0\xbb\x01\x0a\x44\x1f\x85\xea\xfb\x68\x80\x56\x34\x91\x20\xf9\x46\x6f\x7f\xe0\x79\x1c\xcb\x69\x9e\xc9\x5c\x44\x79\x1a\x91\x1d\xe7\xb4\x7c\x9d\xab\xc8\x1f\xf4\xba\xce\x02\x5e\x0b\x4c\xfe\x9e\x63\x15\xd9\xdd\xe9\x75\x49\x1f\xc9\x29\x0a\xc0\x0e\x70\x1f\x65\x12\x05\xda\x33\x20\x12\x11\x0a\xf6\xf4\x67\x1a\xa1\x40\xe5\x22\xab\x15\xa1\xa9\x56\x6c\x70\x0f\x2b\x10\xac\x7f\xd5\xd1\xc9\xda\x19\x72\xf1\x42\x94\x48\x0b\x04\x64\xe4\xca\x80\x54\xd4\x0f\x81\xe9\x4c\x0e\xa0\x55\xf7\x9b\x0b\x66\x1f\xd9\x0b\xe6\xfc\x60\x8d\xd5\xf7\x45\x02\x4f\xd6\x73\x55\xe1\x8b\x15\xb4\x58\xba\x9d\x54\xcc\x97\x19\xdb\x8d\x26\x09\xcc\x38\x3a\x23\x8e\x36\xbf\xb6\x27\xc7\xeb\xac\xd0\x5e\x8a\x8a\x7d\x59\x4f\x18\xd1\x5a\x96\x05\x81\x33\xff\x51\xe0\xc6\x2f\xb4\xff\x73\xb7\xbb\xcd\x77\x7a\xfb\x07\xdd\xc7\x8f\x8a\x3c\x57\x7e\x1e\x9d\xb8\xcd\x77\x54\x66\xcf\xcb\x8d\x9f\x67\x03\x6d\x10\x66\x60\xc6\x5f\x0d\xcf\xb9\x60\x47\x02\x6b\x63\x05\xd7\xfa\x5b\x7d\x7e\x37\xd1\x88\xd0\x13\xfd\x39\x45\x84\x9e\xe9\xcf\x08\x11\xfa\x4d\x7f\x5e\x23\x42\xdf\xea\xcf\x01\x22\xf4\x8d\xfe\xfc\x0d\x11\xfa\x5c\x7f\xde\xf8\x86\xcf\x4e\xef\xd1\xb6\x8a\x64\x29\x18\x01\x1e\xf2\x51\xf0\x36\x7c\xab\x5b\xfc\x4c\xb0\x53\x51\xd2\x66\x52\x0d\xfe\xaa\x63\x8b\x88\xbf\x6c\x36\x6d\x3d\x84\xd0\x0f\x3a\x42\x3b\xd0\x27\xf4\x58\x07\xc1\x6f\x3e\xa1\xbf\x98\xdc\xc6\xe2\x19\x7d\xa7\xc3\xda\x45\x3e\xa1\x7f\x0a\x4f\xa6\x86\x7e\x11\xec\x36\xcb\x82\xfd\x7d\x9a\x05\xfb\x0f\xe9\x5c\xfd\x99\x06\xbb\xbb\x34\x0a\x76\x0f\xe8\x20\xe8\xf5\x3c\x2f\x59\xbf\x97\xec\x40\xd9\xc7\x97\x12\x93\x1a\xcb\x3c\xef\xd1\xad\x2d\x41\x39\x4d\x09\x74\xf2\x75\xdd\xd2\x7e\xe5\x0d\x1f\xe6\x4f\xbb\xa4\x8d\xf9\x93\x2e\xc9\xf3\x96\x67\xe4\xeb\xc5\x9d\x32\xce\x35\xfa\xb0\x25\x55\x4c\xfd\x58\xa7\xda\xcb\x5e\x0b\x4b\x56\x7b\x23\x0d\xe2\xb3\x34\x2d\x12\xb5\x85\xbf\xc4\xcb\x6d\x8d\xfc\xb1\x23\x2c\xc0\xa6\xb1\x64\x47\xc6\xba\xb1\x78\xc0\x0e\xba\x94\xab\xbf\x87\xda\x22\xd6\x11\x4e\x76\x7a\xbb\x84\x86\x2c\x79\xc0\x7a\xbb\x34\x63\x29\x1d\x33\x49\x67\x8c\xd3\x25\x13\x7d\xd1\x91\xc9\x8b\xf8\x1b\x8f\xf0\x9e\xef\x09\xac\xd3\xef\xb6\xb4\x27\xb0\x00\x21\xba\x60\x66\x55\x9f\x5a\x91\x7e\xc0\xc6\x16\x56\xae\xfb\x5d\xf7\x58\x4b\x6e\x4f\xd8\xe2\x49\xb7\x8f\xda\x48\x95\x8a\xd8\xab\x4a\x9b\xb7\x98\x8a\x5a\x10\x9b\x63\x5a\xe4\x80\x6e\x56\xd3\x2f\x3c\x08\xfe\x18\x55\xf2\xd9\x83\x67\xd2\x42\xef\x50\x0b\xc7\xfd\xa8\x15\xb7\xd0\x47\xb0\xbe\xdf\xc2\x61\x3f\x6a\x85\x2d\x34\x30\xc1\xac\x3f\x6d\x65\x2d\x74\x6c\x82\xe3\x3c\x9f\xe5\xf9\xb2\x8f\xce\x6c\x44\xff\xa2\x35\x6e\xa1\x57\x26\x38\xeb\x5f\xb4\x66\x45\xe9\x65\xff\xa2\xb5\x6c\xa1\x53\x08\xc2\x42\x7a\x5f\x36\x69\x68\xdb\xf2\xfe\x2e\xa5\x36\xdd\x25\x93\xbe\xa2\xef\x85\x5a\x86\x1b\x04\x38\x61\x7f\x96\x9f\x52\x4b\x42\x5b\xf3\xda\x11\xf2\x6d\x81\xcf\xcb\x4b\xc9\x9f\x11\xaf\xb4\x31\x7e\x5a\xd6\xdd\x50\xe9\xe5\x98\x42\x2d\xc5\x24\x7a\xf1\x56\x02\xcd\x14\x82\x80\x55\x6d\x31\xb1\xf0\xe9\x34\x60\x6c\x56\x57\xb7\x96\x50\x80\x48\xf8\xb4\x72\x40\xef\xb5\xe5\x92\x5a\x26\xff\x40\x14\x34\x76\x8f\x40\x5e\xa7\x9d\xf3\xc3\x02\x6d\x53\x22\xbc\xaf\x7c\xaa\x13\xb5\x54\x07\x0e\x5b\x1f\x79\xb5\x31\xcc\x4b\x70\x59\xe9\xcd\x6a\x9e\x69\x85\x37\x2d\x03\xa8\xbe\x89\xd1\x63\x73\xda\x4a\xea\x5e\x4c\xb5\x6c\xa0\x7b\xa6\x34\x37\xe3\x8d\xc0\x92\x50\xab\xf1\x66\x14\xd1\xac\x50\x44\x45\xc1\xcd\x46\xef\xec\x1d\x7a\xfa\x71\x2e\xb6\xb7\xab\x5f\xee\xeb\x6a\xf7\xa4\x1b\xaf\x2a\xeb\xa3\xa8\x5d\x2b\xb5\xd9\x75\xb9\xf3\xa8\x95\x5a\xd3\x1d\x85\x56\x99\x4d\xb5\xfd\xf1\x75\xc5\x4c\xda\xee\xfe\xb6\x4a\x06\xdb\x21\x25\x8d\x2f\x77\x09\xef\x77\x21\xc7\x01\xdf\x2f\xab\x77\x99\x0c\x3f\x1f\xec\x77\x75\x8e\x1e\xdf\xb3\x20\x0a\xfd\xc2\x60\x5d\x5d\x01\x9a\xb2\x2d\x49\x2b\x75\xf6\x45\xe4\x34\x4d\xae\x41\x11\xe9\x79\x9a\x26\x29\x46\xef\xc5\x57\x91\x5c\x8b\xc6\x52\xc4\xb2\x81\x5a\xea\x32\xd7\xcb\xc4\xb7\xd6\xc3\xce\x85\x8e\x34\xc7\x22\xbb\x16\x36\x93\xde\x08\xdf\x4d\xf8\x15\x6c\x80\x13\x13\x3a\x56\x9b\xf2\xcc\x04\xb4\x58\xf8\x37\x5b\x50\xef\x8a\xb7\x26\xf8\x9b\x95\xae\x7f\x63\x22\x3e\xc2\xfe\x78\x0e\xa1\x1f\x68\x57\x54\xaf\xf9\x12\x4a\x66\x86\xa0\x98\x72\x7f\x92\x1f\xf4\x76\xb7\x77\x1f\x3e\xde\xe5\x07\xad\xbd\xde\xc3\xbd\x03\x7e\xb0\x7d\x5e\x5a\x05\xea\x42\x01\x74\x41\x35\xc3\xa0\x67\x6b\xa7\x57\xe1\x29\xb2\x66\x97\xd0\xd0\x5b\x6f\x34\x2b\xad\x72\x75\x3d\xad\x1d\x7c\xf1\x53\xd6\x6d\x36\x43\xf8\x9b\x3d\x65\xdd\x3c\x8f\x9f\x40\x0c\xfc\xcd\x9e\xa8\x18\x1c\xb7\x98\xee\xd8\xa5\x50\x0b\x37\x23\xad\x50\x5d\x7c\x5d\x9a\xb1\x2e\xa1\xe3\xf2\xc9\x16\x3f\x50\x17\xad\xba\x44\x63\xd0\x58\xa1\x63\x77\xae\x81\x6b\x80\xe2\x52\x1d\xbb\x83\x4d\xaa\x04\xc1\x8e\xb0\x34\x09\xfa\x64\x13\x0f\x76\xf7\x69\xd8\x82\xfb\x78\x77\x5f\x5d\xd6\x47\xf8\x46\xe0\x90\x10\x9a\xb5\x58\x42\xc3\x36\xd3\x2d\x4a\x40\x31\xf7\x08\xc3\x08\xd2\x0c\x2e\xe4\xb1\x96\x8e\x0f\x55\x35\x7a\xf6\x33\x3a\x36\x07\x61\x5a\x1c\x7f\x9b\x8c\x1b\x7d\x71\xd2\x9c\xef\x37\x5a\x6d\xd0\x87\x10\xad\x59\x16\x43\xde\x42\x19\x1a\xe1\x62\x3a\x4b\x63\xf4\x0c\x16\x9a\x0d\x7d\x15\x3a\x83\x1e\x8b\xbf\x20\xa4\x07\xe0\x03\x7c\x43\x3f\x8e\xe1\xb3\xa2\x5a\xe1\x5a\x72\xe4\x44\xb0\x33\x4c\x76\x1e\xe9\x56\x9b\x6e\xff\x02\x25\x75\xc7\xdf\x69\xe0\xc6\xc4\xc5\x3d\x8f\xe6\xfb\x60\x5e\x35\xda\x1d\xb4\x6a\xe9\xc0\x4a\xa9\x7c\x01\xe1\xcb\xf0\x22\x03\x43\x58\x7f\x0a\x9c\x2a\xbc\x5e\x61\xef\x84\xc6\x45\x18\xc4\x55\xc3\x22\x3c\x55\xe1\xac\x08\x47\x2a\x3c\x2e\xc2\x03\x15\x9e\x15\xe1\x1b\x15\x5e\xb2\xe4\x09\xfb\x22\x3a\x59\xd6\x6c\x82\xb9\xbc\x64\x94\xe7\xc9\x13\x15\x03\x11\x26\x26\x7e\xc2\x7a\x2a\x3c\x47\x10\xf8\x22\x3a\x73\x08\xce\x11\x8d\x47\x79\x1e\x9a\xe4\x29\x82\xc0\x17\xd1\x99\x42\x70\x8a\x68\x38\xca\xf3\xcc\x24\x47\x08\x02\x5f\x44\x27\x82\x60\x84\x68\x36\xca\xf3\xb1\x49\x1e\x20\x08\x7c\x11\x9d\x01\x04\x07\x88\x8e\x47\x79\x3e\x33\xc9\x37\x2a\x79\x88\x6e\x6e\x10\x9d\x39\xd9\x8a\xe5\x70\x77\xc4\x24\x5d\x0e\xf7\x46\xac\xc5\x9f\x76\xe9\x72\xb8\x3f\x62\x82\xfe\x2e\x7c\xd7\x3b\x4b\xb2\x32\xf2\xcb\xdc\x13\xe0\xe2\x5a\x9c\xc9\x93\xf6\xc0\x70\x1e\x51\x41\x08\x95\xbe\x39\x19\xa1\x17\x8c\xaf\x13\xfa\x42\xe8\x98\x4a\x10\x54\xeb\x74\xa0\x30\x15\xf0\xbe\x6a\x2a\x40\xc3\xca\x6c\xe1\x13\x8c\xbc\xe0\xba\xf9\x62\xcf\xb0\x78\x49\x1f\xcf\x52\xce\x0d\x2c\x12\x19\x8f\x39\x58\x2f\x1e\x87\x8b\x58\x86\xb3\x8c\x20\xfa\x42\x10\xa8\xdb\x98\x2f\x78\x85\xd1\x9f\xc6\x8e\xdb\x52\xc4\xdf\xb4\x69\xb7\x6f\x26\xc6\x9c\xea\xc6\xfb\xc8\xb7\xc2\x2c\xea\x9f\xc6\xed\x79\xff\x73\xd4\x02\xdf\x0f\xb7\x3d\xba\xb7\x22\xfd\x1d\x6d\x11\xf3\x4f\x54\x6f\x5a\xb2\xf0\x50\xd5\xe3\x7b\xdb\xbe\x15\x7a\x70\xad\x6b\x2c\x6c\xaa\x8a\x7e\x50\xfc\x5c\xe1\x31\xda\x95\x95\x71\xdf\xc5\xd0\x6e\x67\x77\xbf\xd3\x45\x54\xb2\xef\x92\xa6\x9d\x89\x60\x4b\x41\x53\x30\xba\xb0\x86\xcc\x0e\x47\x5a\xe2\x49\x33\xb8\x9c\x13\x26\x5a\xf8\x5b\xfe\x26\x31\xb2\xa6\x21\xb4\x2c\x52\x0a\x96\x1c\xfe\x63\x50\x60\xb1\xc2\x42\x12\xbe\xf1\x1b\x77\x20\x81\x52\xae\x48\xae\xfb\xf6\x03\x93\xa0\x65\xfb\xac\x8a\x81\x80\xbc\xfa\x2d\x69\x41\x16\x67\xeb\x77\xed\xec\xc1\xb4\xf6\x0e\x11\x1b\x23\x93\xe8\x28\x60\x95\x3f\xce\x40\xa8\x6b\x4c\x53\xbb\x4a\x13\x35\x8e\xd6\x24\xfa\x05\x4d\x3b\x91\x31\x7b\xcd\xbe\x40\x4a\xa6\xbd\xd7\xb1\x2b\x9a\xd6\x3f\x39\x7a\x4c\x31\x27\x75\x88\x6c\x4e\x5d\x6b\xad\x44\xbd\xeb\x4e\xbd\xab\xac\xa2\x10\x06\x18\xde\x3e\x0a\x75\xc3\x8e\x6d\x43\x9f\x4b\x37\x12\x77\x88\xe6\x94\x87\x03\x32\xea\xd6\xd5\x3f\x42\xfe\xa0\x63\x83\x58\xe8\xd2\x11\x9f\xc4\x82\xbf\xd1\x83\x19\x4b\xa7\x3c\x61\x62\xd6\xec\x79\x58\xf9\xcf\xc2\x0f\x09\xfb\xc4\x8d\xcc\x3f\x4e\x59\x6a\x6d\xa9\x27\x2c\xb5\x42\x5d\x8a\xde\x7e\x8e\x13\x2a\x09\xc5\x02\xf6\xc7\x29\x96\x04\x46\x88\x0b\x69\x2a\xe2\x20\x65\xc8\xb5\x6c\x20\x4d\x0a\x07\xb0\x46\x76\x59\x25\xa8\x63\xaf\x08\x95\xca\xf7\x75\xc9\xf5\x84\xa0\x54\xde\x3a\xd7\x04\x59\x41\x77\x9c\xaa\x50\x31\x47\x75\xd7\xf0\x19\xe6\xb2\x34\xd8\xeb\x13\x75\xe7\x70\x7b\xd3\x25\xd4\xc9\x3c\x8b\xbf\xf3\xf7\x22\x96\x19\xfb\x8b\xa6\x25\xce\xcb\xef\x8a\x8a\xa8\xea\xee\x1b\xb8\x9e\x1d\xf6\x3f\x45\x80\x6c\x0e\x5f\x30\xb6\xd9\xc4\x7f\x0a\xc6\x41\xb3\xa2\x02\xf9\x6c\x9a\xf2\x6c\x9a\xcc\x36\x50\x85\x1a\xf8\x16\x63\x5f\x84\x1e\x6a\x57\x9b\xec\x43\x54\x80\xe1\x87\x49\x8a\x32\x20\xc4\x9a\x4d\x0c\x17\x30\x93\xed\x1e\x51\x35\x42\x95\x65\x0b\x97\xf5\xc6\x32\xc1\xa2\x24\x96\x54\xf3\xba\x40\xdb\xc4\xd2\x59\x4f\xda\x07\xfd\xc2\x18\x66\x20\x9e\xb4\x7b\x7d\x34\x0b\x33\xa9\xcd\x78\x88\x27\x5d\x1d\x3c\x56\xe4\x92\x78\xd2\xd3\x99\x4d\x68\xb7\x8f\x8c\x7f\x48\x15\x7a\xa4\x43\xba\x60\x01\x13\x76\xb4\xe5\x3e\xe8\xf3\xf7\xd5\xd9\xe0\xcd\xc3\xf3\x17\x83\x33\x76\x7b\x7c\x74\xf6\xfc\xec\xf5\xe0\xf9\xf9\x9b\x93\x67\x47\x6f\x82\x35\x13\xfe\x88\x96\x73\x9c\x9f\x3e\x7f\x76\xf2\xf6\xf8\x74\x3d\x67\xa0\x70\x90\x4a\xe6\x41\x7d\x3e\x50\x73\x87\xbc\x7e\x32\xa2\xaa\x64\x80\x4c\xbd\x00\xc6\xd5\x56\x54\x01\xf1\x03\x2f\x4a\x43\xfb\xf0\xfc\xf9\x3f\x03\x30\xd4\xdd\x1e\x7e\x18\x7d\xf8\x80\xe8\xe0\xe4\xed\xd9\x2b\x57\x81\x1a\x87\x15\x26\x2b\xe2\x5b\x17\xc5\x07\x7b\x04\xae\x2d\x5a\x5d\xda\x48\x5d\xe2\x5a\xd5\x1b\x19\xc7\x59\x02\xef\x81\x07\x0f\xfc\x50\xa1\x77\x02\xf7\x1e\x2a\xb4\x4e\xe0\xae\xc2\xe6\x44\x47\xe1\xf3\x74\xac\xe2\x15\xf6\xa6\xc2\x63\x85\xb6\x09\xbc\x4f\xe8\x02\xc2\x4b\x42\x27\x4c\x60\x45\x01\x44\xea\x97\xd0\xa9\x71\x7b\x8a\xe3\x4e\x48\xf0\xed\x8a\x4e\x3a\x67\x69\x28\xb2\x58\x35\x45\xcd\xda\xe2\xec\x66\xc1\x33\x7a\x3b\x9e\xc6\xb3\x28\xe5\x22\x98\x75\xc2\x0e\xb8\x9f\x52\x09\x78\xa8\x82\x61\x9a\x86\x37\x27\x13\xac\xbe\x45\x12\x29\x74\xc0\x7c\x8d\x08\x95\xe1\x65\x10\x75\xbe\xd2\x8b\x30\xe3\xcf\x66\x61\x96\x01\x04\xad\x16\x51\x44\x1e\x8d\xd5\xae\xf1\x93\xc6\x2a\xfa\x6d\x38\x2f\x47\x66\xd9\x20\x89\x96\x33\x1d\xa9\x2d\x1d\xd1\x58\x08\x9e\xfe\xce\x27\x75\x4d\x33\x59\x3c\x10\xea\x53\x8d\xf5\x88\xac\x08\xbd\xb8\xb3\xfb\x86\xf6\x7e\x97\x26\x8b\x8c\xde\xaa\x8e\xa0\x28\xbe\x42\x5e\x57\xd0\x24\x8c\x38\x5a\xeb\x06\xca\xa6\xc9\x35\xa2\x32\x9e\xf3\x64\x29\x83\xa8\xc3\x3b\x2f\xc2\x88\xd3\x70\xb1\xe0\x61\x1a\x6c\x75\x29\x17\x92\xeb\x8f\x6f\xb1\x54\xbf\xb1\x00\xc7\xd7\x05\xa7\x77\xee\xbb\x58\x96\xe1\x25\x78\xdb\x76\x15\xd1\xd8\x0f\xe9\x6a\x69\x08\x9e\x41\xcc\xb0\xd1\xb1\x0a\xd9\xf1\xa2\x33\x15\x32\x73\x48\x97\x8c\x77\xec\xa8\x15\x4b\x20\x51\x63\xc0\xe9\x10\xc9\xf0\x12\x51\xe4\xa0\xfb\xdf\xba\x26\x44\x91\xab\x47\x7d\xdb\x5a\xd4\xb7\xa9\x03\x51\x64\x6b\x40\x23\x6f\xa0\xa3\xce\x17\x82\xa7\x34\xea\x8c\x09\x9d\x17\x91\xb1\x8d\xb4\xe7\x52\xd6\x09\x8d\xdf\xd8\xe7\x33\x0e\xba\x3a\xfe\xd4\xd0\x8b\xb2\xc8\xba\x7e\xe5\x41\x30\xaa\x5c\x9b\x6c\xa2\x93\x02\xfa\x94\xe0\x05\x26\x38\xa4\x82\x26\xcd\x66\x4c\xe8\x5d\xf5\x48\x6a\xca\xa5\xb0\x26\x8a\x75\x38\x59\xd1\x39\xbd\x4d\xf9\x24\x58\xae\x08\x9d\x81\x63\xbe\x79\xb1\x47\xd8\x94\xce\x4b\x4b\x86\x5d\x50\xd9\x09\xd9\x7c\x45\xef\xde\xdc\x5b\x6e\xce\xb9\xe6\xdb\xa3\xa5\xd0\x58\x42\xe4\xe9\x0d\x9d\x9f\xff\xfe\xfc\xe8\xd9\xd9\xf9\xf1\xf3\x3f\xce\x4e\x4e\xde\x9c\x9e\xbf\x7c\x73\xf2\xcb\xd1\x9b\xf3\x57\x27\x27\xff\x3c\x3f\x6f\x36\xeb\x6e\xa7\xbb\xcb\x74\xc6\x53\x3e\xfe\x7a\xfc\xec\x39\xb9\xed\x1e\xca\xf4\xe6\xf6\x9e\xd9\x15\xa6\x30\x06\x13\xf6\x92\xdc\x8e\x13\x91\x25\x33\xde\xe1\xc0\x95\x92\x64\xb5\x5a\x81\xaa\x3e\xff\xb6\x48\x52\x99\x31\x81\x0f\x1e\xde\xef\x74\xcb\xb0\xc0\x8f\x1e\x11\x75\xc2\xa9\xcf\x9f\x77\x81\x88\x55\x9f\xfb\xfb\x40\xbf\xc2\xe7\xae\xef\xef\x24\x2b\x3b\xab\xe6\x9d\xf3\x73\x6e\x96\x62\x9f\x07\xb7\x96\x77\xc6\x57\xab\xa2\x41\xb7\xc5\x2a\x0a\x42\x3b\x5f\xb4\x88\x7c\x99\x26\xcb\x45\x10\xbb\x94\xdf\xf5\x8b\x83\x57\x2a\x71\x69\xcf\x4e\x4f\xbd\x78\x67\x8f\x74\xf5\x83\xfe\x8a\x4e\xa4\xee\xe2\x10\xd5\x99\x17\x4f\x9c\x47\x00\x75\xde\xef\x7b\xbd\x4d\x0c\x73\xc1\x5b\x1e\xc5\x54\x9f\xde\xcc\x2f\x92\x99\x76\x12\xca\x18\x1f\xea\x70\x27\x96\x3c\x0d\x65\x92\x6a\x7f\x9f\xa0\x14\xd5\x89\x33\xad\x1c\xa5\xbd\x70\x33\x7f\xb5\x73\x42\xec\xa1\xd3\xa5\xa2\xec\x03\xd0\x58\x33\xc9\x02\x41\x45\x50\xc3\xd2\x7b\xea\x7c\x5a\xf7\x6f\xa3\x44\x70\x75\x9e\x05\xe6\xab\x47\x81\x6a\x0c\xf8\x50\xb6\x5a\xa3\xd5\x8a\xf2\xd2\x9b\xb5\x66\x6e\xf2\x15\x9d\x04\x62\xb5\x2a\x58\x9d\x6a\x5f\x19\x76\xe7\x6b\x4d\x71\x34\x42\x29\xf9\x7c\x21\x1b\x32\x69\xe8\xbe\xf1\x86\x48\x44\x1b\xbe\x2f\x66\x85\xbf\xcf\xce\x67\xf1\x5a\x34\x92\x34\xd2\x6e\x95\x2f\x78\xc3\x66\xa1\x50\x00\xee\xac\x86\xbe\x1e\xb2\xc6\x7c\x99\xc9\xc6\x34\xbc\xe2\x8d\xb0\xb1\x36\x74\x98\x34\xe6\x5c\x4e\x93\xa8\x63\x1e\x54\x12\x1a\xd3\x10\x1c\x73\x17\x3a\x64\xb7\x99\x3f\x26\x49\xcd\x0c\x28\xb2\xa4\x34\x70\x9a\x54\x4c\x3a\x0a\x67\x2a\xec\x41\xa8\x43\x5c\x0d\x1a\xe5\xd5\x51\x02\x5d\xeb\x98\xc1\x30\x79\x60\xd4\xce\x0d\xed\xc4\x27\x1d\x0d\x26\xcf\xed\x17\x26\xab\x49\x2c\xc2\xd9\xec\x06\x54\xcd\x88\x1e\xdd\x78\xa5\xfe\xdd\xbd\x4c\xdd\xc2\x4b\xcb\xef\x3d\xce\xdf\x76\x92\x82\x35\x0b\x9e\xc6\x57\x3c\x3a\x95\xc6\xc7\x37\x9c\x7d\x9a\x8b\xb6\x80\x9b\x13\x3e\x33\x95\x6c\x75\x95\x15\x2a\xeb\xd0\x5f\xa7\x67\xcd\x25\xc0\x28\x3d\x89\x27\x7a\x79\xf8\xc9\xae\xcd\x65\x2d\x9b\x7b\xb5\xca\x67\xea\x98\xa6\x08\xaf\x29\xa2\x2f\xb4\xe5\xa2\xce\x45\x2c\x9c\xa9\x45\xd7\x98\xd8\x18\xd6\x4f\x6f\xfc\x8a\x75\x27\xcd\x4b\x0b\x74\xf3\xb0\x88\xb7\xfa\x35\x10\xcf\xac\x14\xe8\x79\xca\xc3\xb1\x7c\xad\x6e\x2b\x11\xce\x4e\x45\xb8\xc8\xa6\x89\x7c\x31\x0b\x2f\xd5\x14\xdf\x95\x47\xd7\x72\xc9\xa5\x8d\xd0\xcc\x88\xf7\x40\x42\x82\xcb\x3a\x37\xdb\x5e\x23\x84\xdf\x88\xd4\x73\xe3\x16\xfa\x48\x46\xf1\x42\x08\x1c\xcc\x3c\xdf\x92\x9d\x38\xfb\x5d\x35\xe3\x59\x32\x5f\x24\x82\x0b\x49\xd6\xde\x21\x9e\x85\xa2\x91\x88\xd9\x4d\x63\x91\xcc\x6e\x26\xf1\x6c\xd6\x80\x1b\xb3\x31\xb6\x45\x32\x04\x6f\xb1\xc5\xfd\xe4\xe9\xc2\x6e\x9c\x29\xff\x3e\x2b\xf2\xcb\x4d\x3d\xb7\x0c\x56\x6e\x4c\x67\x69\xde\x80\xfe\xd1\x06\x07\xca\x4d\xf0\x54\xeb\x3b\xae\xa1\x1f\xe2\xd9\x6c\x90\x2c\x85\xec\x0b\x86\xd6\x63\x51\x2d\x01\x28\x3b\xef\xdf\x9e\x1e\xbd\x78\x7e\xbe\x5e\x00\x98\x86\x68\x63\x32\x22\xf4\x1e\x0d\xfa\x9d\x8f\x79\x7c\xc5\x61\x50\xfa\x61\xa5\x5d\x7e\xe2\xdf\x69\x9e\x5f\xae\xd9\xc4\x61\x7d\x2b\x4b\xd0\xef\xd5\x58\x3d\x19\xfd\xac\xd2\x4c\x1d\xfd\x77\x1a\xa8\x4b\x34\x9b\x38\xab\x6f\x9a\x81\x48\xa8\xdd\xc4\xd6\x3b\x36\x0b\xdd\x57\xa6\x57\xf6\x18\xa8\xdf\x6c\x31\x0b\x6f\x14\x16\x97\xe7\xbc\x23\x14\x7a\x3c\x63\xb5\xf4\xfc\xc6\x15\xd9\x47\x1b\x4f\x15\x82\x02\xb4\x69\x4b\x12\x74\xa8\xb7\x8c\x7b\xb6\xcb\xc2\x09\x6f\xcc\xf8\x65\x38\xbe\x69\xcc\xe2\x09\x1f\xdf\x8c\x67\x3c\x6b\x5c\xab\xad\x23\x12\xa9\xae\x2a\x45\x20\xf2\x08\x74\xb1\x8b\x6d\xd4\x58\x66\xb1\xb8\x84\xad\xe7\x22\x1b\x47\xef\x5e\x67\x9d\xcf\xe2\xb3\x40\xad\x71\x0b\x35\x96\x19\xcf\x1a\xa8\x35\x6b\xa1\xc6\xc5\x52\x36\xc2\x59\x96\x34\xc6\x89\x90\x61\x2c\x32\xe0\xf9\x4e\x92\xd9\x2c\xb9\x56\x70\xd6\x5a\x10\xa0\x16\xb6\xc3\xd9\x47\x9f\x45\xa3\x81\x5a\x42\xcb\x14\xd8\xb1\xb5\xd1\x61\x29\x3a\xb3\xd1\x19\x44\x23\xd5\x9c\xb3\x29\x6f\x84\x17\xc9\x15\xf7\xbb\x98\x4d\x93\xe5\x2c\x52\x1d\x4c\xf9\x3c\xb9\xe2\x51\xa7\xf1\x86\x87\xa9\xd0\x0a\xe7\xe1\x45\xb2\x94\xf0\x44\xd2\x30\xaa\xe9\x8d\x29\x4f\x79\xf0\x59\x4c\xa5\x5c\x64\xc1\xce\xce\xe4\xa2\x33\xe7\x3b\x70\x2e\xb6\xc3\xec\x46\x8c\xdb\x6e\x20\xda\xae\x9a\xf6\x34\x49\xbe\x66\x88\xac\x36\x6c\xf8\xbb\xce\x1c\x5c\x77\x1a\xb0\x94\xde\xb1\x27\x59\xb2\x69\x67\x6c\x3a\xaa\x6e\x37\x1c\x86\x5e\x25\xc7\x71\x64\x32\xd7\x1d\xb7\x6a\x91\xb8\xc3\x76\xe3\xba\xab\xae\x1e\x39\x0d\x65\x23\x4a\x60\x89\x69\xf4\xb1\xb1\x5e\x1f\x26\x8d\x44\xc0\x42\x71\x97\x01\x22\x87\xb5\xbb\x9c\xc5\xda\xb1\x0b\xab\x6b\xf7\x61\x5d\xe4\x9d\xaa\xd6\x9b\xaf\xc4\xfe\x5d\x19\x02\x71\xb8\xac\x68\x31\xa4\x64\x65\x6d\x9c\xf0\x95\xe8\x28\xa2\x84\x1a\x8c\xdb\x8e\x5a\x2d\xe2\x1d\xea\xa7\x83\xf3\xf3\x6c\xb9\x58\xa4\x3c\xcb\x8e\xcd\xc3\x4a\x9c\x88\x0f\x7a\x41\xaa\xdb\x39\xf9\x61\x8e\xf8\x47\x39\xee\x8f\x77\xf9\x4c\x60\xc6\xec\x35\x67\x1c\x72\x6b\x66\x70\x2d\xc3\x78\x43\xde\xdb\x15\x8d\x0d\xbe\xdf\xf9\xca\x6f\x14\xf9\xe4\xd9\x0c\x88\x7d\x53\xcc\x82\xc5\xc3\x74\x44\x65\x27\x16\x11\xff\x76\x32\xc1\x82\xc0\xa3\x36\x4e\x86\x62\xa4\x15\x8c\x0b\x33\x02\x1a\xaf\x8a\x27\xd8\xc0\xbe\xe4\xf2\xe4\x5a\xa8\xfd\xc1\x53\x79\xa3\x11\xe1\xcc\x7a\x40\xbc\x2b\xcf\x7f\xd0\x20\x03\xae\x30\x5b\xba\x30\x20\x5f\x67\xcf\xc5\x72\xae\x71\x7e\xbd\x44\x38\x15\xc0\x29\x77\x3d\x58\xb9\x1e\xdc\x49\x92\xa5\xab\x1f\x32\xe8\x0a\xfa\xb2\xaa\x6d\x4e\x81\x5a\xa0\x99\x7e\x17\x36\xe8\xd6\xb8\x64\x78\x5a\x92\x31\xf3\xb6\xf8\x20\x16\xf1\x24\xe6\x51\x83\x7f\x1b\xf3\x85\x46\x83\xc7\xe3\x65\x9a\xf2\xe8\x50\x3f\xed\x4d\x35\xd1\x33\xb7\x19\x23\x7e\xd5\xe0\xe2\x2a\x4e\x13\x31\x57\xb7\x82\xda\xfa\x70\xda\x2f\x67\xb3\x06\x50\xe6\x8d\x39\xcf\xb2\xf0\x92\x37\x42\x11\x35\xc2\x28\x02\x8a\x35\x9c\x35\xa6\x7c\xb6\x98\x2c\x67\xf6\xc4\xcd\x3a\x48\xdb\x21\x82\x56\xce\xd8\xd0\xeb\xc0\x88\x2e\x59\xf7\x10\xfb\x4d\x95\x25\x2d\xf5\xcb\xba\xb1\x9b\x0d\x97\x8a\xe2\x23\x84\x10\xb8\x77\x19\x50\x72\x69\x1c\x0a\xd9\xf8\x23\x4e\x66\xda\xc0\x88\xa1\xf9\xc6\x9d\x49\x1a\xce\x79\x76\x96\xbc\x4b\x16\xac\x47\xc7\x3f\xa4\x51\xfc\x27\xc1\x94\xdc\x96\xe9\x06\x43\x00\x25\xb5\x37\xbd\x5e\x71\xcd\x26\xca\xe0\x63\x2d\xc5\x11\x6e\xfd\x3a\xc9\x79\x73\x97\xac\x82\x3a\x61\x86\x7a\x66\x8c\xad\x90\xfb\xa4\x0a\x63\xcc\xc5\x6f\xd9\xef\x62\x31\xf7\x6d\xeb\x02\x57\x23\x29\xd1\x47\x86\x24\x29\x0c\xbc\x77\x0f\xc5\x13\x69\xf7\x8d\x68\xb5\xdc\x29\x0b\xb6\x0d\x3a\xdc\x6d\x09\xe6\x07\xf2\x7c\xab\x47\xd3\x8e\x73\x63\xab\xd2\xb7\xec\x5b\x2f\x8a\x45\x23\x05\x8f\xe2\xd7\x69\x2c\x4d\x1a\x31\x5c\x32\xf3\x9e\x65\xf7\xb1\x9a\x06\x75\xb4\xc0\x29\xec\x93\x19\xa5\xf7\x1a\x09\xa6\x0a\xfa\x9b\x20\x48\x7a\xab\xd9\x05\x82\x16\x4d\x0c\xb6\xba\xd4\x6f\x9f\x0a\xdb\xf6\x00\xeb\x34\xe0\x43\x39\x62\x82\x7a\x82\xb0\xc0\x1f\xb2\x63\x23\x59\xef\x50\x3e\x71\x0f\x86\x76\x8c\xa4\x1d\x23\x4d\x35\x6c\x31\x97\x63\x28\x47\x7d\x3f\x10\xdc\xae\x68\x5a\x3a\x3e\x05\x39\xac\x9b\xe9\xbb\x4e\x38\x35\x8e\x0c\x46\x7a\x1c\xca\x3b\xcf\x4b\x2c\x48\x67\x12\xcf\x24\x4f\x71\x9d\x79\x8e\xda\xa2\xc7\x3c\x1b\xa7\xf1\x42\x26\x29\x16\x94\x13\x6f\x86\x61\x07\xd2\xb4\x33\x49\xd2\xe7\xe1\x78\x8a\x4b\x64\xb4\x99\x9f\xa1\x04\x7f\x94\xc5\xed\xe9\x06\x72\x5c\xef\x22\x9d\xd7\x72\x95\x1c\x31\xb6\x02\x16\x53\xdd\x83\xd4\x70\x44\x53\xb8\x4c\xd9\x56\x8f\xc6\xc6\x48\x0c\xf0\x20\xed\x6c\x85\x34\xab\xe5\xa1\x1c\x6e\xe1\x94\xe1\x90\x65\x86\x6d\x42\x80\x59\x02\xf6\x66\xb4\xdb\x82\x50\x8b\x9d\x11\xaa\x28\x58\xeb\x5d\x40\x61\x59\xe4\x50\x55\x49\x0e\x0d\xef\x72\x4c\x6e\x13\xcd\x50\x19\x17\x24\x73\x7a\x73\x9b\x5a\x56\x4a\xe6\x58\x29\x59\x2d\x2b\x25\x29\x58\x29\x96\xa3\xb0\x32\x3e\x24\x7c\xee\xcc\x3d\x99\x59\x11\xd7\x47\xc2\x32\xdd\xc0\xd0\x42\x64\xe5\x2b\x18\xcc\xea\xc4\xe8\x37\xcc\x87\xb7\x05\xba\x54\x3f\x08\x9b\x34\x33\x3c\xe4\x50\x3e\xe1\xfe\x86\x50\x4b\x81\xa9\xfd\xe4\x98\x25\xab\xea\x64\x42\x55\x95\xf9\x51\xdb\xda\xb0\x13\x55\x66\x34\xd4\xfc\xb5\xc6\x91\xdd\x45\x23\xb5\x4b\xd6\x6e\x6c\x2b\x1b\x63\x6e\x69\xb7\x80\x74\x47\xc0\x9f\x11\x27\x95\xfa\xef\x3f\xb2\xd9\x22\xe5\x61\x74\xd7\xa0\x9a\xcb\xff\xa2\xf6\xf2\x3f\x01\x1f\xaf\x26\xcb\xb8\x36\xcb\x91\x9f\xa5\x1e\x85\xb8\xf6\xb3\x44\xb5\x59\xbe\x4b\xcb\xf9\x5d\x96\x18\xaf\x74\xa1\xf0\xb6\x89\xfa\x13\x69\x8e\xc6\x94\xdd\xce\xc3\xf4\x6b\xb0\xa4\x73\x1e\x66\xcb\x94\x07\xcb\x15\x6c\x9e\xda\x87\x83\xeb\x58\x44\xc9\x75\xb3\x89\x17\x4c\x7f\x12\x5a\x9b\x2f\x4a\xc6\x30\x49\xcd\x26\x9e\x30\x1b\xd8\x90\x77\xb0\x94\x70\x71\x9f\x5c\x64\x3c\xbd\xe2\xea\x76\x88\x58\x35\x72\x43\xd9\x05\x4f\x41\x58\x4a\x8c\x15\x81\x3f\x65\x5e\xd8\xbe\x2b\xbc\x95\xe4\x16\x38\xad\x17\x0c\x2f\x3a\x22\xbc\x8a\x2f\xd5\xf2\xca\xf3\xdb\x15\xe9\x2c\x33\x9e\x1e\x5d\x72\x21\xe9\x9c\x39\x14\xea\xa2\x8f\x50\x70\x41\x07\x6c\x41\x2f\xd9\x84\xde\xb0\x88\x5e\xb1\x29\x3d\x62\x78\xd0\xb1\x7d\xa1\x5b\x5b\x97\x2e\x60\x5e\x7b\x9a\x4d\x15\x39\xe5\x61\x54\x7f\x69\x5f\x76\xc2\x28\x7a\x7e\xc5\x85\x7c\x13\x67\x92\x0b\xd5\xd5\xfa\x7c\xa5\x47\x24\x42\xcf\xd9\xbf\xe7\x0e\x55\x45\x83\xd3\xd7\xcf\x11\xc9\x73\x3f\xee\x2c\x8d\x23\x2e\xe4\x0e\x22\xf4\x9a\x0d\xd1\xab\xb3\xc1\x1b\x44\xd1\xab\xe7\x47\xc7\x88\xa2\xd3\xb3\x8f\x6f\x9e\xab\xdf\x67\xbf\xbf\x7e\x77\x86\x46\xf4\x3b\xab\xb0\x7c\xad\xce\xb9\x37\x64\x26\xaa\x07\x4f\x30\x27\xec\x76\x12\x66\x01\xca\x92\x59\x1c\x21\x3a\x09\xd3\x00\xa5\xfc\x72\x39\x0b\x53\x15\x9a\x05\x68\x16\x5f\x4e\xa5\xfa\x8e\x02\x14\x2d\x13\x09\x16\xe8\x27\xe1\x45\x80\x2e\xd2\x10\x5c\x7d\x4e\x42\x5b\x7e\x45\xcf\xd8\x2d\x7c\x06\x68\x12\x66\x88\x1a\x50\x2a\x94\x22\x0a\xa0\xd4\xf7\x0c\x51\x03\x0a\xde\x46\x11\xd5\xa0\x54\xe0\x02\xad\xe8\x37\xb6\xf3\x22\x11\xb2\x71\x74\xcd\xb3\x64\xce\x1b\x0f\x1b\xf8\x54\x01\xcd\x7f\xd7\xe0\xf2\x37\x0a\x50\x7e\xac\x41\xe4\xbf\x40\xe1\xfc\x45\xca\x79\xfe\x2e\x4d\xc8\x0e\x7d\xcb\x6e\x1f\x77\xbb\xa6\x0d\xfb\xfa\x2b\x45\x54\xcb\x78\x98\xc0\x9e\x8e\x9e\xa1\x15\x7d\xc3\x86\x3d\xba\x4b\xf7\xe8\x3e\x7d\x48\x0f\xe8\x23\xfa\x33\x7d\x4c\x7b\xdd\x11\x7d\xce\xde\xd8\x3b\x78\xd8\xeb\xd1\xde\x2e\xed\xed\xd1\xde\x3e\xed\x3d\xa4\xbd\x03\xda\x7b\x44\x7b\x3f\xd3\xde\x63\xba\xdb\x1d\x11\x7a\xca\x86\xfa\xb9\x53\xbb\xa4\x0e\xdb\x8b\x94\x4f\xe2\x6f\x36\x14\x8f\x13\x61\xbf\x27\x61\x5b\xa6\xa1\xc8\xd4\x82\xf6\xe2\xe6\x61\xf6\x15\x8d\xe8\x33\x76\xfb\xf2\xf7\x93\xf7\xef\x02\x74\x99\x26\xcb\x05\xa2\xa7\x1f\x8e\xde\x9d\x9f\xbc\x3b\x7a\xf6\xfa\xec\x63\x80\xb2\xeb\x70\xd1\x4e\x16\xe1\x38\x96\x37\x88\xbe\xfb\xfd\xf5\xe0\xe8\xf7\x8f\x01\x5a\xa4\xf1\x3c\x4c\x6f\x10\xd5\xa2\x08\x10\xa7\x05\x5e\x55\xec\x8a\x7e\x65\x43\xf4\x0d\xdc\x17\xab\x2a\x67\x97\x88\xa2\xc9\x35\xa2\x68\x39\x53\xc1\x18\x51\x74\x01\xcf\x20\x88\xa2\xc5\x72\x36\x6b\xcf\xf8\x44\xda\xef\x54\x2f\x01\x94\x2d\x62\xa1\xe3\x32\x8e\x28\x4a\x13\x19\x4a\xde\x7e\xdc\x2d\xbe\x7b\x3f\x7b\x81\xdd\x47\x2a\x30\x99\xc5\x8b\xf6\x34\x49\xe3\xef\x89\x90\x6a\xe6\x75\xcc\x15\x4f\x65\x3c\x2e\xc2\x17\x89\x9c\xaa\x2a\x64\x38\xfe\x6a\x7f\xdb\xbd\x6f\xee\x73\xf7\x1b\xbc\x15\x5f\xf1\x14\xea\x9e\x85\x37\x3c\xcd\xdc\x47\x5b\xf2\x6f\xb2\x08\x8d\x93\xa5\x00\x91\xb9\x67\x1d\x18\x4a\xfa\xac\xe3\x0f\x22\x7d\xd6\x31\xe3\xa6\x12\xec\x78\x8d\xec\x54\xbf\xe9\xcc\xc3\x45\x1d\x36\x85\x90\xcd\xc2\x29\xfa\x86\x14\x16\x44\x6c\xcc\xf3\x8d\x85\xae\xdb\x45\x31\x28\x42\xff\x62\x83\x8e\x5a\xe0\x66\x7d\x3f\x03\x7c\x55\x1d\x5b\x8a\xde\xbb\xdc\x74\x74\xfc\xb5\xe4\xe9\xcd\x29\x9f\x71\x45\x11\x90\xdb\xe1\xd0\x2e\x9c\x79\x3c\xbb\x29\x56\x9b\x0e\xbf\xd3\xc1\x11\x35\xb9\x0c\x05\xa6\x4e\x9d\xb6\x5d\xa5\x5e\x9c\x7e\xc1\x77\xb9\xc3\xa5\x4c\x6c\x91\x76\x76\xa5\x16\x8b\x8a\x32\x8f\x9c\xa7\x57\x97\x95\xac\x61\x14\xb5\xc7\x00\x53\x05\x8f\xa2\xe8\xd9\x1a\xb4\xb0\xd7\xbb\xb1\xe9\xea\xd3\xa5\x66\x3c\x4c\xc7\xd3\xf6\x22\xe3\xcb\x28\x69\x73\x7d\x32\xc2\x42\x85\x84\x77\x10\xff\xdc\x46\xbb\x62\x89\xbe\x3e\xda\x73\x73\x9d\xa8\x12\x26\x6e\xe0\xa2\x5c\x6e\xc8\xc5\xdb\xe1\x62\x91\x26\xe1\x58\x2d\x34\x1d\x73\x64\x23\x5c\xce\xaf\x9c\x2f\xda\x49\x1a\x5f\x2a\x14\xae\xad\xed\x8e\x21\x8a\x54\xf4\x89\x89\x3d\xd5\x91\x05\x70\x7d\xbd\xb6\xbd\x2b\x4a\x55\xa0\x63\xdf\x79\x91\x45\x9f\xa7\xc9\x75\x7b\x1e\x67\x59\x2c\x2e\xe1\x64\x80\xfe\x4e\x93\xeb\x81\x8e\x7b\x0d\x51\xa3\x51\x0d\x1e\xee\x5e\x62\x14\xb2\xbd\x4b\xa8\x60\x72\xd8\x55\x78\xb2\x1c\xf6\x46\x25\x46\x4f\xb1\x6a\x8d\xaa\xce\x24\x54\xfb\xd6\x58\x7d\x46\x32\x5d\x72\x93\xa2\xd0\xa6\xf5\x0a\x2a\x2b\x0e\x23\x4d\x34\x80\xbb\x11\x34\xd2\xcf\x35\xce\x4a\x08\x90\x18\x47\x52\xa6\xf1\xc5\x52\x3f\xce\x61\xa1\xf0\x14\xfb\x66\x96\x34\x9b\x86\x0f\x9c\x34\x9b\xf8\xaf\x61\x3a\x62\x09\x50\x11\xaa\xae\x0f\x2c\xc3\xb7\x2b\x7a\xeb\x2f\x5d\x75\x36\xab\xfb\xa3\xbc\x44\x03\x94\x5d\x5d\xb6\x63\x31\x8b\x05\x6f\xb7\x55\x8e\xf2\xba\x54\xe4\x5e\xb1\x04\x5d\xa8\xd7\xbb\x51\xdf\x75\x2b\x2a\xd8\xea\xd1\xea\xba\x51\x79\xcb\xeb\x23\x40\xc0\x49\x46\x74\x7d\x1d\x40\xe6\xb5\xb9\x56\x60\xab\x13\xaa\xe8\x4f\xfa\x17\x39\xfc\xd0\x29\x37\x3a\xcf\xf1\x87\x4e\xb5\x0d\x6c\xab\xa7\xd1\xbc\x63\x3d\x38\x1f\xc8\x61\xcd\xa1\xc1\x8e\x21\xcf\x2f\x6c\x00\xc7\xc7\x2f\x9d\xf3\xf3\xf3\x17\x27\x6f\xcf\xce\x8f\x3e\x3c\x3f\x3d\x19\x3c\x3f\x3f\x3f\xcf\x73\x5c\x17\xcd\x6e\x57\x84\xd6\x25\x74\x32\x79\x33\xe3\xd9\x86\x62\x26\x75\x73\x69\xe0\xab\x6f\x2a\x0c\x89\x77\xd4\x3c\x8d\xe7\x9b\x2b\x56\x89\x6c\x38\xd2\xa3\xf2\x8e\xd5\x65\xa2\x7f\x2a\x9a\xf1\x0b\xdb\xea\x79\x6a\xb5\x6a\x45\x1f\x35\x9b\xf8\x4b\xdf\x38\xc6\x4a\x96\xea\x00\xef\x92\xe0\x4f\x4d\x0b\x72\x42\x56\x2a\x03\xfe\xc2\xf0\x1a\xea\xd7\x89\x92\xd3\x71\x9a\xcc\x66\xfd\x9d\x7f\xcd\x92\x30\xe2\x51\xfe\xaf\xf1\x4e\x50\x04\x62\x15\x36\x66\x02\x2f\x3b\x8a\x88\xb8\x81\x07\x03\x42\xf2\x7c\x1d\x2f\xc4\xe8\xf8\x64\xf0\x2c\x11\x12\x24\x61\x15\x04\x0f\xcb\x07\xc9\x1e\x05\x63\x9e\x5c\xf1\x1f\x16\xe3\x84\x7e\x61\x3d\xfa\xe7\xa6\x8b\x47\x41\x5b\x81\xa8\xbb\x1e\xb2\xd7\xf4\x55\x99\x62\x78\xc1\x6a\x31\x6f\xde\x6c\xd6\xc7\x2b\x5a\x6c\xcc\xb3\xac\xfe\x82\x72\xc9\x1d\x3e\x8f\x25\x7d\xcf\x6a\x05\x50\x52\x6f\x12\x82\x94\xfe\x01\xb6\x59\x6d\xf7\x3f\xe2\x82\x08\xe5\xac\x7b\xc8\x9f\xfc\x61\xc9\x4d\xde\x6a\x91\x3f\x86\x7c\x34\xec\x8e\x30\xfc\xf6\x46\xe4\x50\x95\xa6\xaf\xd9\x56\xaf\x20\x78\x5f\x6a\xfe\xc1\x1f\x7a\x66\x87\x9c\xca\x11\xa1\xaf\xf3\x1c\xbf\x56\x54\xfc\x7b\xfc\x91\x76\xfd\xb7\xfa\x7f\xfa\x2f\xdb\xc9\xb5\xe0\xa9\x3a\x50\x3b\xe7\xf0\x06\xae\x0e\x55\xad\xbd\x45\x13\xe0\x04\x83\x38\x9d\x9c\x72\xb1\xe9\x99\x38\x21\xb7\x82\xa1\xc9\x72\x36\x89\x67\x33\x1e\x21\x20\xb7\x52\x96\xe0\xd4\xa7\x59\x3e\xe1\x98\xbe\x95\x64\xb5\xfa\x07\x8e\x69\x4a\xf2\x1c\x7b\x45\x18\xc8\x1a\xfc\x06\x29\xea\x8a\x56\x44\xb0\x8b\xfe\x04\xd1\x5e\xfb\xff\xe1\xb1\x4b\xa0\xb2\x78\x82\x39\xf0\x8a\x6b\xe9\xde\xa3\xc6\x22\x4d\xe6\x71\xc6\x33\x78\x3c\xbc\x08\xc7\x5f\x1b\x63\xfd\x54\xe4\x74\x8f\x42\xd9\xc8\xc2\x39\xb7\x39\x3b\xe6\xa0\x57\x57\x46\xdd\x03\x56\x9e\x7b\xae\x24\x13\x2c\xad\x68\x90\x1a\xbb\xbb\x86\x2a\x75\x16\x6e\xac\x31\xdc\x62\x09\xa7\xe4\x56\xe4\x39\x16\x20\xe6\xc0\x18\x4b\xfb\xbf\x02\xe3\x36\xf8\x0d\x7e\xc8\x8a\xd0\x12\x63\xca\x65\xfe\x04\xc3\x01\xda\x1d\x5b\xdd\xd5\x1a\xcd\xd3\x10\x79\xae\xb2\xbc\x95\x90\xee\x08\x21\x37\x9c\xbf\xe9\xe1\xe4\x5b\x60\xd3\xe7\x1f\x86\x4f\xf3\xab\xf6\xef\xe9\x72\xe9\xf0\x2d\x5a\x70\x10\x09\x87\x4b\xd4\x2c\x99\x66\x13\xdb\x4f\x86\x32\x2e\xe5\x0c\x76\xaa\x5e\x45\x4c\xd2\x97\x58\x82\x13\x88\x02\xd8\xa7\xff\x06\x98\xa8\x00\xe3\x1c\xfc\x62\x77\xce\xd5\xc8\x33\xf3\xeb\x90\x88\x7f\x7a\x39\xa5\xcd\x69\xc0\x17\x0b\x90\xf2\xb2\x6c\x8d\xe0\x6a\x88\xa5\xcb\xe9\x96\xa4\xca\xa8\x06\x52\x76\xce\xa7\xa1\x88\x66\x3c\x6a\x36\x5f\x34\x9b\xe5\x73\x00\xa3\xa5\x30\xa9\xbf\x43\x41\x30\x14\x6e\xb7\x95\x3f\xaa\x29\xd4\x53\x2d\x9d\xda\x42\xaf\x34\x10\x54\x2a\x93\x70\xbc\xf9\xa5\x94\xd7\xef\x81\x77\x7a\x5d\x37\x52\x9e\x25\xb3\x2b\x9e\x36\x00\x9f\x69\xc4\x19\xbc\x79\x86\x8e\x4d\x66\xd6\xfd\x34\xce\x1c\x1f\x48\xed\x70\xb5\xbb\xb6\x7a\xf5\xa0\x5f\x84\xf1\x8c\x47\x0d\x09\xaf\xe9\x9a\x51\xd7\xf8\xc9\xd4\xf7\x53\x50\x52\xbb\x9a\xf2\xc6\x4f\x82\x5f\xff\xd4\x48\x16\x9a\x29\x46\xf5\x9b\xb6\x61\x85\x79\xbc\x7f\xbb\x41\x8b\x07\xff\x30\xf3\x9a\xa9\xf6\xa7\x7e\xfa\x84\x39\x1f\x8e\x68\x99\x93\x5a\xcc\xa3\x1a\xaa\x4f\x58\x52\x4e\x56\xea\xa4\xe0\xe5\x3b\xe3\x37\x9d\x42\xa8\xf0\x8f\x2a\x81\xe1\xa0\xb2\xb6\xd8\x57\x89\x27\xff\xc3\x6e\xbd\x56\x06\x09\xa7\x7a\x85\x04\x6e\x29\x53\x68\x12\x88\x4a\x51\x98\xef\x40\xa3\x83\xd4\xae\x17\x85\x24\x41\x96\x3a\xe6\xef\x2d\x1c\xc7\xc6\x81\x38\xc0\xe1\xd7\x8d\xaa\x0c\x17\x7e\x45\xa8\x5b\xba\x01\xa7\x76\x71\x06\x72\xe5\x5c\xa7\x34\x9b\x5b\xce\xd4\xb0\xa9\xd8\x59\x0f\x32\x61\x78\xc5\xf0\xcf\x5a\x63\x0b\x4c\xef\xc2\x17\xcd\xe6\x4b\x9c\x9a\x21\x80\x77\x7c\xef\xb0\xf6\x72\xe6\xf9\x26\x18\xfd\x97\xf8\x9f\x54\x58\xaf\x29\xb0\x29\xe1\x7e\x12\x84\x0a\x38\x25\x57\x14\xc6\xbc\xee\x9d\x08\xca\xa8\x3c\x5a\x95\x09\x34\xb8\x13\xde\x09\x67\xb3\x35\x75\xd2\x35\x96\x6e\xed\x2a\xfd\x98\x2c\xb5\x24\xe3\x22\xcc\xb2\x46\x28\x1a\x5a\xc8\x51\x26\x0d\xb3\x54\x15\x6c\x4c\x3a\x85\x29\x74\x05\x20\xf1\xd7\x8b\xf7\x2e\x3f\x54\x44\x47\xf7\xd0\x7f\x6a\x2a\x84\x54\x5b\xad\x62\x35\x0a\x72\x9b\x6a\x2d\xa2\x76\x3b\xc9\x73\x89\xe1\xed\xc7\xe3\xe3\x77\x0f\xb3\x82\xbd\x9c\xb5\x5a\x04\x87\x8c\x0f\xb3\x11\xa9\xc7\x37\x42\x18\x94\xbe\xfe\xc1\x31\xce\x08\x98\x53\x1f\x66\x23\x16\x1e\xda\x0a\x08\x81\xc1\x4a\xc3\xf1\xba\xf2\xed\xff\xd6\x68\x29\xe0\xf7\x18\x2e\xdb\xd5\x94\x6a\x3b\xf4\xae\xab\x89\xea\x6a\xca\xf8\x30\xd9\xd4\xd5\x54\x77\x55\xff\x68\xb3\xf1\xa5\xde\xe9\x93\xac\x56\x63\xba\xd9\x2c\x5d\xcf\xda\x73\x7f\xf9\x65\x31\xe1\x7d\x1e\xac\xb7\x99\xdc\x1a\x7e\x85\xa9\xa3\xec\xa1\x95\x97\xbc\x9e\xae\xf7\x56\x98\xb2\xda\x7a\x0b\xaf\x7d\x5b\x35\x03\xd8\x37\xbf\xea\x08\x09\x39\xeb\x1d\xd0\x8c\xb3\xdb\x2c\xfe\xce\x83\xde\x01\xfd\x16\x74\xe9\x4d\xd0\xa5\x9a\xa7\x14\x74\xe9\x64\x16\x2f\xfe\x54\x27\x87\xfa\xf8\x18\x6c\xf9\x26\x74\xc6\xf6\x3e\xe0\xcd\xe6\x51\x41\xc7\x96\x25\xf7\x11\x90\x30\x20\xb0\x92\xf9\x34\x2b\x02\x39\x16\x8a\x24\xff\x26\x77\xc6\x59\x86\x08\x88\x11\x08\x9e\xbe\x3a\x1b\xbc\x61\xbc\x70\x80\xcd\x34\x2f\x58\x6b\x4a\xbc\x4d\x22\x9e\xd1\x54\xf3\xdc\x13\x66\xdf\x92\xda\xbd\xc3\xe4\xa9\xfa\xd3\x6e\x5b\x91\x06\x31\x4c\x46\x34\x64\x38\xee\xc8\xf0\x52\x4b\x99\x69\x7b\x61\x9e\xa5\xfe\xc3\xa1\x63\xea\xbe\x79\xfd\xf6\x9f\x68\xe4\x38\xc1\x21\x79\xda\xee\xc1\xbb\x60\xec\xde\xde\x4c\x3b\x62\x91\xf1\xd4\x08\xf6\x60\xa9\x10\x47\xee\x3d\xab\xce\x78\x09\xad\xee\xed\x6a\x67\xa4\xbc\xdd\x6e\x3c\xed\x1e\x12\xd9\x62\xa8\xdb\xdb\xdd\xdb\x7f\x78\xf0\xe8\xe7\xc7\xe1\xc5\x38\xe2\x93\xcb\x69\xfc\xe5\xeb\x6c\x2e\x92\xc5\x5f\x69\x26\x97\x57\xd7\xdf\x6e\xbe\x1f\xfd\xf2\xec\xf8\xf9\x8b\x97\xaf\x5e\xff\xfa\xcf\x37\x83\xb7\x27\xef\x7e\xfb\xfd\xf4\xec\xfd\x1f\x1f\xfe\xfc\xf8\x09\x0d\x0f\x76\xb7\xb5\xad\x8d\x50\x44\xc9\x1c\x93\xbc\x5b\x78\x1c\x28\x1a\xb2\xe4\xe5\x87\xd6\xe1\x88\x0a\x86\x79\x9e\x0f\x47\xc4\x8c\xda\xd3\xa7\x4f\xbb\x87\xa2\xdd\x3e\x24\xd2\x8a\x5f\xd4\x00\x5a\xf0\x92\x03\x02\xe0\x67\x29\x4a\xa9\xaf\x6a\x28\x82\x24\xc0\xbc\xcc\x96\x30\x0c\x5a\xa2\x07\x3e\x5b\xcc\x14\x8a\xd1\x40\x77\xbe\xa0\xf2\x95\x8f\x61\x4d\x78\xd9\xc3\xbe\xb4\x50\xda\x88\xd0\x84\xa5\xc3\xae\xa2\x12\x52\xe7\x14\xa1\xf3\x25\x89\x05\xa4\x3a\x39\x98\x2d\xcd\x8d\x51\x1b\x21\x06\xc4\x35\xa6\xff\xfe\xea\xc9\xab\x18\x5f\x70\x71\x51\x69\xc4\x6b\x79\x90\x9e\x9d\xa3\xe6\xce\x25\x45\xcd\x70\xbe\x38\xf4\x2c\x7b\xee\x20\x88\xfd\x6b\x99\xc8\x52\xf4\x4f\x10\xfd\x3f\x7b\x8f\x4b\xb1\x4f\x20\x76\x56\xce\xfa\x14\x22\x2f\x55\xa4\xe7\x95\x84\xaf\x3f\x30\x6b\x39\x21\xfd\xf4\x92\xf2\x68\x39\x5e\x3b\x11\x9c\x0d\x95\xa2\x07\x82\xa2\x40\x8d\xbe\xed\x90\x22\xb1\x90\xaa\x8a\x50\xe4\x57\x78\x51\x9e\x6f\x75\x34\x6c\x31\x96\xe9\xaf\x3c\xe7\x9d\x6f\x3a\xf8\x4d\x7d\xdf\xe8\xef\x1b\xf5\xad\x0f\x0d\x1d\xa1\xbf\x55\x2c\x9c\x20\xf6\xe3\x63\x51\xcd\x9c\x97\x94\xa9\x2c\x87\x1e\x54\xaa\x8c\x78\x24\x4f\x3f\xc4\x91\x9c\xd2\x94\xf1\x4e\x3c\x4e\x84\x0e\x25\xec\xd6\xe5\x0e\x10\x7c\xce\x42\xb5\xdc\x5c\x47\x77\x76\x29\x6a\xec\x3e\x3c\x20\x88\xac\x68\xcc\xea\xf2\xec\xed\x6e\xcb\xce\x37\x8a\xa8\x37\x22\x10\x77\x43\x11\x69\x20\x42\x43\x86\x32\xed\xfd\xd6\x26\x4b\x18\x80\x9d\xde\xc1\x36\x96\xba\x57\xfd\x76\x2f\xe8\x91\x32\x90\xb5\x5c\x1f\x6d\x2e\x00\x9b\x31\xc3\xaf\xf7\xe1\xea\x18\x8a\x1a\xdd\x46\x97\xb8\xb5\x7b\x9b\x2c\x25\x4f\x83\x44\xeb\xd2\x05\x7e\xa7\x5d\xd9\x98\x22\xaf\xee\xb0\x14\xca\xc8\x8a\x2e\x42\x39\x0d\x7e\x30\x5c\xe9\xce\xee\x76\xbb\x47\x51\xa3\x6d\x86\x4c\xdb\x73\x1b\x70\x76\x6b\xaf\x83\x6b\x35\xf0\x01\xea\x75\xbb\x0f\x10\x9d\x72\xfd\xb0\x04\x21\xef\x3a\xb8\xf4\x26\x74\x0b\x57\x65\x3a\x9e\xf6\x3c\x99\xfe\x42\x82\xa3\x37\x22\x79\xee\x07\x0b\x73\x80\xa1\x3d\x48\x32\x20\xcd\x8a\xa0\x3a\x3f\x66\x79\x0e\x0e\x6d\xd6\xe2\x19\xba\x98\x85\xe3\xaf\x88\xf8\x32\x27\x37\xa5\xb5\x06\x2c\x60\xe0\x3c\xcc\xc3\x58\x1f\x2b\xf3\x30\xfb\x4a\x13\x90\xb7\xe7\x93\xf8\x1b\xb0\x1e\x54\x36\x50\xda\x0b\x4b\xeb\x73\xcc\x78\x47\x0b\x00\x81\xfe\x9e\x8c\xe5\x8c\x83\xf2\x1e\xff\x26\xd3\x90\x2e\x18\xef\x5c\x2b\xec\x12\xd4\x5a\x26\xcc\xf5\x79\xd1\x6c\x2e\x68\xc4\xd2\xce\x24\x59\x8a\xa8\x9f\x06\x82\x4e\x59\xd4\x81\xa1\xa5\x17\x2c\xea\xe8\x71\xa5\x73\x86\x26\x61\xdb\x7b\xc6\x28\xec\x12\x4e\x77\x2e\xb6\x7b\x07\x84\xd0\x01\x1b\x1e\x77\xaa\xdc\x5a\x1a\xf7\x8b\x85\x71\xdc\xf1\xd9\xbb\x54\x1d\x89\x6e\xcd\x80\x71\xb6\xf9\xe8\x8e\x63\xb8\xdd\x63\x8c\x2d\xf5\xd9\xce\x33\x77\x5a\x02\x92\x61\xc1\xb8\x64\x7b\xea\xaa\xe5\x7d\xc9\x0a\xa5\xd4\xe1\x88\x16\x73\x13\x00\x5b\x75\xe9\xcd\x16\xbd\x2d\x3d\xdc\x05\x89\xff\x74\x17\xc4\x5a\xd7\x34\x18\xd0\x34\x99\xf1\xc0\x2f\xd8\x51\x31\x79\x8e\xe2\xf9\x25\xa2\xdf\xe6\x33\x91\x05\xc8\x38\xd5\xba\xbe\xbe\xee\x5c\xef\x75\x92\xf4\x72\x67\xb7\xdb\xed\xee\xc0\x63\xca\x55\xcc\xaf\x7f\x49\xbe\x05\xa8\xdb\xe8\x36\xdc\x00\x4d\x4b\x7b\xe5\x82\xac\xc8\xea\x70\xd2\x6c\xe2\x4b\xaf\x26\xf7\xe6\xd3\x8e\x77\x15\xa8\x11\x43\x88\xd0\x59\xb3\x79\xe9\xd4\x36\x35\x65\xa1\xf5\x50\x61\x29\x20\xbf\xd3\xb7\x71\x14\x94\x01\x86\x69\x1c\xb6\x67\xe1\x05\x57\x14\xcd\x05\x18\x45\xd1\xe5\x8a\xf9\x56\x18\x04\x59\xd1\x62\x1c\x67\xa3\x95\xe6\x29\xde\x68\xe6\xf4\x25\xbd\xd5\x83\xa6\xce\x06\xb3\x48\x83\x98\xaa\xc5\x1c\x08\xaa\x96\x72\x90\xd2\x62\xcf\x87\x54\x2f\xd7\x60\x4c\x35\x3b\x39\x58\x1a\xbe\xf2\x8a\xd0\x2b\xbb\x20\x9b\x4d\x61\x56\xe6\xda\xdb\x84\x3e\x92\xad\x9e\xaa\x3a\x8c\xbd\x59\x54\x9b\x06\xb6\x51\x0c\x1f\xd9\xd7\xb5\xed\x92\x98\x35\x3e\x63\x09\xec\x29\xba\x64\xb1\x89\x5a\xb0\x58\x47\x4d\xd8\x9c\xe3\x5b\xbf\xcd\xe5\x2b\x20\x58\x52\x77\x01\x04\xe3\x15\xa1\x11\xd3\x63\x9e\x2a\x64\x7b\x6d\x9d\x0d\x38\xbd\x55\x87\x41\x80\xae\xa7\xb1\xe4\x68\x45\x56\x74\xca\x66\xae\x13\x7d\x5f\x75\xda\x4d\xe5\x3c\x5c\xe0\x4b\x4e\x56\xc1\xed\x8a\x5e\x18\xf8\x97\xeb\xc0\x27\x1a\x4d\x25\xde\x0c\x5d\x72\x9c\xe9\x45\x30\x03\xb5\xe0\x6a\x91\x99\x3f\x62\x93\x8e\x3a\x95\x55\x8b\x08\x19\xad\xe8\xfc\xae\x9a\xe0\x0a\xf0\x6b\xba\x18\xad\xe8\x80\x21\x35\xd0\x95\x15\x43\x2f\x19\x1a\xcf\xe2\x45\x35\xfa\xc6\xc0\x87\xf7\xee\xda\x91\x8a\xa3\x60\x00\xcb\x06\x8c\x31\x04\x68\x99\xf1\xf4\x74\x11\x8e\xf9\x89\x78\x9f\x71\x04\x49\x86\x1b\x5e\x9f\x63\xe5\xb7\x30\xa2\xf3\xd1\x8a\x5e\x99\x5a\x23\x3e\xc9\x90\x97\xaa\x63\x55\x3b\xdf\x85\x72\xba\xbe\x59\xbc\x75\x8f\x25\x5b\x50\xa4\x5d\x6e\xaa\x51\xed\xcb\x4e\x01\x47\x8e\xc8\x8a\xde\x8c\x56\x8e\x0a\xd4\x1b\xf1\x8a\x6e\x5e\x16\x7a\x41\x80\xcc\xae\x90\xcf\x92\x59\x92\x82\xca\x74\xbc\x68\xab\xf9\x40\x01\x5a\xa6\x33\xfc\x3f\x6e\xf4\x2e\x29\x22\x88\xe8\xed\x54\x49\x1a\x40\x92\x1a\x3c\x85\x3c\x15\x6b\x49\xf8\x35\xa6\xab\x15\xbe\x21\x75\x66\x80\x8b\xbd\x24\xca\x7b\x29\xb5\x7b\x29\x29\x6d\xa1\x98\x29\x1c\xd0\xec\x59\xe0\x93\x59\x21\xec\xa7\x5d\x90\xb1\x83\x14\x16\x13\x7a\xc1\x71\x62\x38\xc2\x61\x65\x47\x25\xd5\x1d\x95\x9a\x3d\x58\xec\x2b\x13\xb3\x52\xb4\x9a\x77\xac\xd5\x2c\xcc\x70\x7d\x61\xde\x91\x77\x6d\xbb\x40\xde\x14\x76\x3e\x6c\x17\x97\x62\xe2\xdc\xf8\x54\x61\x99\x74\x6f\xc8\x42\xb3\x99\x46\xab\xd1\xca\xd8\x4a\x31\x8d\xd7\x79\x1d\x32\xe5\xea\x90\x3e\x54\x01\x93\x44\x8f\xd8\x55\x51\xe9\x39\xbb\xf2\x6a\xb0\x0b\xec\xc6\x65\x60\x47\xf4\xc6\xcb\xc0\xce\xe9\x78\xfd\xcc\x2c\x50\x09\xe1\xa3\x12\xa9\x3f\xfb\x49\x79\xf6\x63\x87\x58\x98\x3a\xcd\x98\xc2\x25\xe6\xef\x13\x98\xee\x00\x19\x05\xaa\xa0\x21\x12\xc1\x0f\xd1\x6a\x6d\x32\x8c\x98\xf2\xda\x28\x26\xb0\xe5\xc1\x33\x86\x8f\x32\xc8\x12\x96\x70\x07\x02\x21\x48\x10\xfb\x5b\x3e\x85\xd1\xbf\xd7\x62\x37\x08\x17\x2f\x10\xae\xea\x00\xc0\x22\x2f\xdf\x21\x6a\xc5\x5f\x70\x1c\x12\x77\x47\x35\x9b\x5b\xe6\xda\xb2\xfa\x64\xb7\xdf\x02\xa1\x97\xef\x8e\x30\x98\xd4\xce\x2e\xbd\x09\x3a\x0f\x57\x87\x89\xd9\x20\x53\x38\xa5\x57\x34\xa6\xb7\xc8\x01\x37\xd2\x07\xc8\x43\xaa\xc7\x9d\x6f\xad\xb0\xf3\x6d\xa7\x77\x40\x11\x9f\x7b\x58\xc2\xb8\x73\xd3\x0a\x3b\x37\x26\x01\x79\x72\xb9\x1b\xa6\x2a\x29\x06\x49\xea\x21\xf2\x8c\x46\x97\x70\xd2\xb1\x3e\x5f\x61\x90\xae\x1d\xd1\x63\x50\xc2\xea\x71\x60\xb1\xce\xd0\x61\x9d\xe3\x12\xd6\x39\x2b\xb0\xce\x71\xb3\x39\xa6\x4b\x66\x76\xa2\x3f\xd8\xfd\x5b\x00\x12\xc4\x70\xdf\x69\x93\x0a\x41\xe8\x70\x3e\x87\xd3\xad\xc8\xe1\xac\xd9\xc4\xcb\x5a\x64\x08\xd0\x92\x85\x05\x6f\x4f\x28\x38\x86\x9a\x4d\xbc\x28\x5a\x5d\xe3\x64\xb1\x4a\xf4\xd9\x6e\x3b\xf9\x41\xd1\xef\x1d\x04\x7a\x9b\x98\x81\x88\x8b\xc4\x44\x25\x26\x30\x04\xe0\x21\xfd\x99\xb1\x33\x41\xb3\xa2\xf3\x61\xb3\xa9\x86\xa6\x30\xf5\x3b\x6e\xb1\xac\xd9\x3c\xef\xd7\x91\x41\xb2\xf3\x6d\x27\xe4\xed\x54\x11\x8f\x7c\x5e\x26\xe9\x6e\x54\x4a\xac\x53\x14\x19\x17\x64\x3e\x88\x71\x38\x1b\xe3\xf6\xc3\xee\x83\x46\xab\x51\x01\x07\x05\x68\xa3\x94\xa3\x02\x17\xb2\x00\xd0\xcd\xad\xaa\x6f\x91\x6d\x0d\x1d\xb7\x36\x11\xab\x21\xbf\x0f\xb1\x5a\xe4\x2a\x13\xab\x0a\xee\x66\x6a\x35\xe2\x97\x2a\xd7\xaa\x7c\xcb\x94\x26\x03\xf4\x01\xe0\x6e\x11\x96\x6c\x4c\x57\x84\x2e\x86\xa8\x7d\xcd\x2f\xbe\xc6\xd2\x93\xcc\x1b\x31\x6f\xb9\x18\x47\xaf\x6a\xcb\x2e\xc8\xe1\xc4\xbf\xee\x0c\xf2\xca\x26\x3a\x4f\xc4\x86\x8e\x66\x8c\xfc\x6b\x2b\x5b\x84\xa2\xb4\x19\x97\xd4\x47\x1f\x56\x84\xc6\xcd\xe6\xdd\x25\xcc\xa6\x40\x59\xda\x4e\xc4\xec\xa6\x74\xc4\xc6\x0a\x42\xe4\xd9\x77\xdf\xb8\x9d\xf5\x5e\x4d\xdd\x5e\x4d\x98\xb9\xcb\xbc\xdd\x28\xec\x6e\x14\xfe\x6e\x4c\xeb\x76\xa3\x46\x07\xd2\x02\x1d\xf0\x07\x27\x71\xb8\xc0\xa1\x46\x02\x8a\xc1\x09\xef\xec\x6a\x52\x1d\x1c\xd1\x6c\xde\x5d\xe2\xae\xc1\x11\x0a\x42\xa8\x0d\xd9\xf3\xb2\x18\xc4\x35\x67\xc7\x9d\x75\x09\x9e\x66\xf3\xaa\xd9\xbc\xea\xcc\xc3\xf4\x2b\xfc\xea\x0c\xfd\xab\x40\x4b\x55\x9f\x73\x27\x56\x7d\xce\x57\xf4\x3b\x67\x3f\xbd\x38\x6a\xa0\x87\x9d\xde\x6e\xa7\x87\x7e\xa2\x27\x65\x7e\xfc\x35\x07\x48\xb8\x38\xd3\xbf\xf3\x12\xbd\xa7\x42\x1c\x0c\xd2\x13\xaa\x32\x6b\xd8\x77\xe4\x27\xf4\x4e\x58\x17\xfc\x32\x16\xa0\x90\x7d\x8f\x1a\x57\xf4\xac\xf6\xf9\xe0\x5e\xad\xb6\x35\x11\x5a\x23\x16\x0f\x6f\xc9\x2b\xfa\x6d\xa3\x7f\x55\xad\x35\x56\x51\x37\xa4\x63\x66\xb9\x34\xfe\xd5\xe1\x2b\x59\xd5\x29\x9a\x18\x35\x34\x9f\x35\x6c\xfc\xec\x9a\x84\xd5\x0a\xd8\xe3\x81\xd4\xbc\xfc\xe2\x58\xc7\x09\xeb\x51\x78\x6e\x1a\x76\x47\x23\x12\xe0\x84\x75\x69\xc8\x04\x39\x4c\x9e\x8c\xe1\x85\x26\x64\x33\x1c\x52\x3e\x8c\x59\x36\x4c\x46\x23\x1a\x53\x5e\x18\xe3\xf0\x78\x4e\x6f\x2b\x4c\x6e\x84\xa8\x56\xb7\xe2\x25\x75\x2b\xd9\x62\x18\x75\xbb\x5d\xd4\xe2\xe0\x22\xe4\x59\x12\xf1\x23\x85\xc8\x38\x35\x07\xdc\x3b\x20\xc4\xf0\x91\xdb\xfb\x85\x43\xfe\x62\x83\xbf\xf1\x79\xd1\x6c\x8d\xbd\xb5\x5b\xcb\xde\xda\xf5\xb5\x95\x76\x8d\xb6\x92\xe8\x64\x5f\xe3\xc5\xab\x24\xf9\xaa\xc8\xe7\x62\xbc\x9b\xcd\xb4\xa2\x0a\x2a\x6b\xd8\xbb\xdc\xd3\xd2\x2d\x18\xf6\x5b\x5b\x1a\xdf\xed\xf3\x61\xea\xd0\xcd\x11\xd3\xdf\x01\x1f\x8a\x11\x4b\x29\x57\xd4\xca\xca\xd7\x8f\x2a\xde\xef\xdf\x69\x71\xb1\x4e\x18\x45\xef\xc2\xf1\xd7\x3c\x4f\xfa\xef\xcc\x19\x33\xe4\x23\x7d\x64\x79\x11\x79\xae\x10\x29\x12\x54\x8a\x61\x4e\x63\x42\x41\x12\xfc\xff\xc7\xdd\x9b\xf0\xb7\x6d\x2b\x8b\xa3\x5f\x45\xe2\xff\x96\x25\x2a\x88\x21\xe5\x9d\x32\xac\x97\x26\x69\x9b\x7b\xb2\xf4\x26\xe9\x76\x14\xbd\x94\xa6\x20\x9b\x8d\x0c\xaa\x24\x94\xd8\xb5\x74\x3f\xfb\xfb\x61\xb0\x72\x91\xed\xf6\xf6\xdc\x77\xde\xeb\x39\xbf\x58\xc4\x8e\xc1\x60\x30\x33\x18\xcc\x48\xe7\x78\x2f\x68\x00\xa6\x85\x5c\xda\x1e\x3e\xa3\x44\x37\x82\xdf\xc2\xef\xcb\xfc\xaa\xc2\x4f\x28\xb9\xdd\xe2\x8f\xf0\xef\xef\xf0\xef\x4f\x6d\xd7\xd0\x5d\x5b\xe6\x9a\x06\xcf\x28\xae\xe9\xbe\x05\xae\xeb\xd5\x9b\x96\x33\x72\x4d\x03\x86\xa9\x98\x37\xe6\x72\xfe\xdb\xf1\x13\x4a\xea\x20\xad\xe9\xcc\xa7\x7b\x33\xdf\x0f\xe8\x54\xfc\x98\x11\x86\x04\xdc\x90\x18\x5d\x47\x1d\xbd\x10\x23\xab\xb8\x14\xb0\x66\xbb\x5e\x75\xc9\xf7\x70\xa2\x3d\xaa\x5f\x96\x70\x02\x26\xf2\x39\xeb\x3d\xa3\xe3\xdf\xa9\x18\xf0\x5b\x8a\x3b\x17\x9c\x4d\xa3\x19\x2e\x08\x9b\xc6\x33\x9c\x13\x66\x7b\x85\x16\xfa\x84\x14\x9b\x0d\xdf\x6c\xe0\x75\x65\x2a\xc8\x11\x44\xf6\xea\xd2\x16\x6d\x35\x32\x38\x9b\xe9\x29\x75\x37\x7a\xf0\x84\xaa\x75\x46\xe2\x44\xf8\x49\xfb\x42\xfe\xda\x2e\xa1\xad\xfa\x7d\xfd\xce\xa0\x03\x69\xcd\xce\x59\xd0\xa6\x6c\x21\x9f\x29\x7f\x2d\x40\x83\xb4\xd8\x44\x38\x3c\x79\xed\xe5\x8b\xe0\x29\x18\x70\x7e\x43\x79\x76\xf9\xf6\xd3\x85\xef\x4f\xe5\x43\x03\xf9\xae\x40\x3e\x6f\x90\xcf\x1a\xe0\x3d\x83\xf8\xd7\xb9\xc7\xe3\xe8\x6c\x18\x77\xb5\x6a\x60\x2a\xca\x83\x19\x90\x2c\x32\xf9\x5d\x2c\xe0\x66\xa3\x81\x06\x17\x8d\x06\x6e\xe0\x88\x26\xb9\xdd\x8e\xad\x4c\x47\xec\x7e\xdb\x6c\x18\x36\x5d\x95\xea\xc7\x66\xa3\x93\x94\x78\xda\x27\xa4\xad\xbc\xf5\x7d\x41\x02\xec\x43\x6a\xa5\x03\x86\x0b\xe4\x92\x56\x4a\xa6\x75\xbc\x1f\x8b\xd5\xdb\x39\x44\x2c\xaa\x24\x53\x21\x12\x9b\x25\xfa\x99\x3a\xd1\xed\xa9\xef\x0b\x70\xcb\x7f\xa7\x6c\xa6\x1f\xa6\xab\x16\xb9\xd3\x1c\x56\x14\x04\xca\x39\x17\x9d\xbf\xd1\x2e\x67\x78\x35\x6d\x86\x43\xf2\x6f\xb7\x8a\x93\x37\xe2\x60\x8d\x97\x9f\xce\x92\x42\xa3\xb2\xf4\x09\x58\x0b\x74\x0f\x57\x72\x89\x77\xea\xca\xaa\xce\xb9\xb8\xfb\x25\xe6\x5f\xbc\x28\xfb\x92\x78\x5f\x9a\xd6\x45\xe7\x02\x44\xf8\x4b\xaf\xf7\xa5\xba\x2d\x0b\x79\x99\x5f\x05\x68\x1b\x94\x08\x7b\x67\x8e\x6e\x1d\x94\x88\xbf\x51\xad\x13\x17\x1c\xc1\xe9\x23\x87\xe1\x86\xd2\x40\x0a\xdf\xd4\x19\x23\xbb\x97\x9e\xbb\xf7\x8f\x4d\x60\x34\xee\x58\x27\xcd\x2b\xd7\xba\x8c\x86\x00\x1b\x64\x7f\xdf\x51\x72\xab\xb0\xae\x4b\x4e\x17\x94\x85\x11\x3a\x8d\x67\x3b\x2d\x5c\x61\xc5\xb7\x48\xcf\xed\xbd\x36\xda\x52\xae\x66\x5f\x15\x73\xea\xfb\x5c\xaa\x86\xbe\x7b\xf7\xf2\x05\x72\x7e\x13\x36\x08\x9e\x86\x6d\x7b\x6e\xdf\x07\xa1\xb9\xaf\x74\x7c\x02\xe5\xea\x21\xbd\x26\xde\xfb\xeb\xbd\xac\x3f\x1c\xba\xa2\x95\x69\x16\x7b\xbd\xe1\xf0\xfd\xf5\x1e\x85\x88\x33\xc8\xec\x6e\x77\x4c\x7a\xa3\x6b\x53\xe3\x96\x81\x82\xe0\x6c\x41\xe7\x65\xaa\xe8\xed\xf9\x44\x20\x6b\x50\x62\x88\x94\xe5\xcc\x65\xbb\xc5\x4c\xec\xb0\x3b\xe1\x28\x60\xf3\xdf\x2b\x2a\x0e\x71\xbd\xab\xdb\xfb\x1e\x39\x81\x3f\xf5\x3d\x30\x35\xbe\xe6\x9c\xd0\x92\xbb\x6f\x76\xc2\xaf\x3c\x84\xc6\xca\xa9\xaf\x38\x21\xdc\xbb\x12\x20\xd4\x78\x47\x66\x3e\x1f\x4b\x27\x8d\xcd\x0c\x60\xed\xdd\x1b\xfb\x6e\x82\xae\xf7\x0e\xe9\xa2\x68\x9b\x0d\x0f\xaf\xc0\xb4\xad\x44\x13\x78\x4f\xfa\xe9\x42\x53\xb1\x44\x7c\x03\xa0\x55\x82\x3c\x8d\x64\x5a\x32\x9d\x61\x28\x0d\x04\x6c\xdc\x39\x36\x52\xa8\x06\x8d\x60\xa4\x02\x17\xb1\x3f\x85\xbd\x4d\x9b\x14\xf5\x56\xa7\xd0\xa3\x33\xad\x23\xdc\x2c\x5a\xdf\x68\x32\xb0\xa6\x63\xbf\x92\x6f\x9d\x1d\xfd\x8d\x34\xff\x74\x9f\x0a\xff\x50\xe3\x26\x3b\x6d\x7d\x27\x3c\x79\x03\x6e\xbf\xc0\xd9\xb1\x7e\x15\xcc\x02\xc7\x19\x44\x49\xbe\xa1\x63\xf5\x58\x02\x16\xa1\xfe\x8e\x02\xec\x57\x5e\x86\x25\xfd\x7d\x4d\x2b\xfe\x98\xe5\x57\xf0\xda\xe1\x9b\x12\xce\xaa\x6f\x28\xc2\xee\xed\x9f\xb9\xbb\x8d\xa0\xa9\xfa\xab\x89\x89\xc5\xcf\xe4\x3b\x3a\x6d\x66\xcf\x36\x1b\x5b\x00\x97\xe4\x1d\x0d\xd4\x9b\x1f\xb1\x29\x61\x4d\xc4\x1e\x0a\x10\x66\xd2\x4c\x1e\x48\xd2\x8f\xb4\xf6\x76\xe0\x17\x1a\xa0\x5b\x48\x83\xdc\x6f\xa9\x74\x12\x66\xcd\xc7\xb5\xbd\xd1\x8d\xef\x3f\x6d\x3d\xe1\x70\xd5\x4a\x94\x3e\x51\x06\xd7\x70\x28\xb1\x62\x6e\x13\x84\x20\xbe\xaa\x3d\x4a\x31\x59\xe2\x7c\x6a\x36\xfb\xa6\x28\x1a\x7a\xa7\x8b\xa4\x18\x8b\xb1\xd1\xcf\xbd\x9b\x3a\xa6\xfd\x48\x37\x1b\x30\xbb\xe9\x7e\x49\x94\x2f\x02\xe9\x8a\xf5\x45\x5e\x71\xc9\x73\x88\xb5\x16\x47\x7c\x3a\x9f\x53\x69\xdb\xe4\x48\xf3\x7d\x71\x12\x38\x59\xd3\x68\x86\x7c\x3f\x78\x1a\x76\xbd\xac\xf1\xfd\x32\x10\xc7\x70\x79\x41\x39\xc2\xdc\xfe\x46\xd8\xb3\xbb\xa7\xde\xab\x2c\x51\x23\xdf\xf7\x37\xee\x52\xd6\x5d\x4d\xc3\xc0\x55\xff\xbe\xff\xdf\x6f\xed\x0d\xb2\xdd\xc9\x82\xd4\x23\x04\x30\x81\x5d\x07\xd5\xeb\xb9\xca\x85\xec\xf7\x34\x58\x51\x77\x42\x39\x29\xb4\x76\x3d\x55\x97\x8a\xa2\xfc\x38\x77\x26\xd5\xb1\x5b\xf5\xa3\xbd\x1c\xe1\xf4\xee\x92\xf2\xf9\x68\xaa\x9d\xaf\xdb\xbe\xe5\x0b\x0f\xfc\xd8\xf7\xbf\x35\xa8\x12\xe4\xea\x0a\x48\x2c\x2b\x3c\x82\xb2\x4a\x92\x7e\x84\x85\xbc\x99\x66\x9c\x96\x4f\x53\x9e\xc2\xbb\xa8\xf5\xb9\xc0\x50\xf0\x8f\xe1\xf0\x53\xff\x41\x9d\x0b\x57\xc0\xd2\x8e\x93\x5d\x4d\x01\x01\xaa\x76\xe4\xc3\xc0\x91\xc1\xd7\x3e\xd1\x4e\x85\xdf\xd1\x6b\x3e\x71\x7e\x2b\x06\x26\xf1\x3c\x9c\x6a\x00\x23\xc3\x5d\x96\xbe\x5f\xf8\x7e\x90\x1a\x5e\x16\xa7\x96\xdf\x2d\x10\xd6\x19\xbe\x6f\xb4\x4f\xf1\xc4\x29\x12\x70\x92\xd6\xee\x3f\x74\xb7\x38\xf8\x28\x38\x49\x29\x55\xb0\x19\x4a\x6c\x4b\x31\x21\x44\xb7\x06\x7d\x9b\xd6\x9e\x52\x33\x12\x2c\x04\x7e\xdb\x1c\x42\x5a\xcd\xf4\x5f\xb4\x43\xc3\xdc\x32\x6b\x6c\x59\x33\x1a\x43\x47\x73\x91\x48\x27\x0d\x06\xe4\xfe\x63\x50\xf9\x9d\xec\xae\x36\xf4\x10\xb6\x82\x5b\x97\xa5\x5a\xbe\x08\x4a\xdf\xf7\x20\xf2\x57\x61\xfc\x74\x48\xa5\x2d\xe9\x47\x98\xea\x12\x9f\x3a\x4a\xfc\x62\x4a\x14\xc4\x09\xd3\x51\x20\x9c\x57\xaf\xd2\x57\x41\x61\x3d\x7f\x8c\x55\xd0\xae\x52\x85\xe2\xba\x28\x8b\xcf\x5e\x22\xcd\xba\x88\xfc\x33\x28\xc6\xe7\x25\x4d\x3f\xaa\x90\x59\x97\x65\xce\x3e\x36\x8a\x0c\x6b\x45\xe0\xdd\x72\x42\xc3\x6b\x42\xc3\xeb\x7a\x96\x7c\xc6\xac\xf3\xea\x2d\xaf\x57\x22\xe3\x86\xd0\xf0\xa6\x5e\x69\x5e\x7c\x66\x26\xab\x5e\x47\xae\x94\xc8\x94\xbf\x88\xfe\x31\x28\xb6\x8e\x50\xc4\x51\xc2\x9d\xa3\xf7\x3f\x1d\x29\x05\x76\x18\xd8\xfd\x38\xf7\x71\x5c\x63\x56\x41\x38\x48\x5a\x38\xef\xbc\xab\xa8\x6f\x36\x65\xd4\x8a\x99\xa3\x60\xe5\x2a\x20\x8d\x5a\xf8\xf1\xbd\xf8\xa2\x0a\x26\xdd\x18\xe2\xee\x45\x57\xc5\x0b\x22\x7d\xa1\xf0\x27\x31\xa2\x08\xd2\x02\x3d\xc2\x6c\x2b\xe6\x99\x76\xe9\x4b\xfe\x8b\xb6\x8c\x34\xdb\x6f\xe4\x11\xf8\xf5\xc0\xd5\x03\xe0\xa0\x2b\xab\xab\xc6\xa6\x1f\x57\x78\xc7\x04\x3c\xcd\x66\xc3\x65\xab\x59\x47\xab\x60\x48\x6a\xa9\xe6\xdd\xec\xa6\x3a\x2e\x80\xb4\xb1\xf4\x0a\x24\x08\x58\x0d\x27\x25\xa0\x53\x0e\x3f\x67\x84\x6b\xd7\x33\x0a\x3c\x40\x8f\xea\x93\x90\x76\x3b\x66\xec\x92\xb7\x79\x1c\xc7\x37\x62\x41\x27\xbc\xc3\x68\x87\xb8\xec\x78\xcb\x0e\xcb\x1b\x2a\x8b\x1e\x54\xb3\xc4\x48\x02\xdd\xd4\x65\x3e\x9f\x53\x26\x9a\x81\x67\xc1\x98\x87\x8b\x22\x5b\x57\xe0\xc5\x49\xbd\x1b\x16\x1c\x27\xc0\x6b\xf9\x27\x56\x01\x4c\x3c\xcc\x3c\xf8\xe4\x7b\x1a\x70\x97\x7c\xed\x7c\xba\xa8\xc5\x59\x84\x50\xf2\x00\xad\x82\x18\x98\xbe\x57\x77\x14\x05\xf2\x06\x63\x07\x74\xb1\x6a\xb6\xd3\x32\xa9\x92\x66\x16\x4b\x0c\x37\x24\xea\x6a\x01\x6e\x25\x94\xc5\x52\xee\x1e\xaa\xd9\xd6\x39\x36\xff\x49\x8d\x37\x62\xe9\xca\xcc\x79\x03\xec\x49\x17\xbb\xca\xcd\x1a\xd8\x01\x8b\xe4\xde\x9a\xa5\x9f\xd2\x7c\x29\xe0\xed\x19\x2f\xbc\xd9\x47\x12\x18\x2f\x6a\x48\xa6\x6c\xff\xe9\xbe\xc0\x51\x3a\x05\x29\x3e\x06\x50\xce\xe6\x22\xec\x96\xad\x19\xfd\xff\x53\x7a\xc0\xa5\x9c\x74\xd9\xa0\x6c\x31\xe7\xe4\xd6\x4c\xef\xdd\xcd\x8a\x26\xde\xcf\x2f\x5f\xc0\x73\x6c\x9a\xf2\x27\xc5\x9a\xf1\xc4\xcb\xe5\xf3\xce\x9c\x53\x0f\xcf\xd7\x65\xe2\x8d\x2a\x6f\x8b\x19\x57\x76\x36\xab\xa6\x35\x0d\x28\x6c\x29\xc7\xb7\xf3\xc4\x7b\x19\x1f\x1c\x86\x07\x78\x7f\xff\x28\x3c\x5a\x0e\xe3\x51\x78\x88\x47\x27\xe1\x41\x36\x8c\x8f\xc3\xa3\xe1\x49\x78\x30\xdc\x3b\x08\x4f\x86\xa3\x38\x1c\x0d\x0f\x62\xf1\xb9\x1f\x9e\x2c\x47\xa3\xf0\x68\x28\xfe\x79\x12\x8f\x8e\xc2\x43\xbc\xbf\x17\x85\x07\x38\xde\x8f\xa1\xa9\x08\x3b\x8d\xfe\xd1\x7b\xb9\x1f\x89\x56\x8f\x46\xdf\x1d\x87\x07\xbd\x2c\x0e\xf7\xb1\x68\x0e\x1f\x84\xfb\x78\x3f\x0e\x8f\x70\x2c\xfe\x39\x8c\xc3\xf8\xc5\x41\x84\xf7\x44\xde\x93\xfd\x83\x30\xc6\x7b\xd1\x81\x68\x25\x0e\x8f\xf1\xe8\xf8\x04\xeb\x66\x4c\x8b\xfb\x91\x68\x4c\x8c\xf4\x18\x1f\x84\xa3\xe1\x1e\x34\x15\x0f\x0f\xf6\xc3\x78\x39\x14\xd3\x80\x09\xf5\x9e\xc4\xfb\xa2\x97\x93\xfd\x70\x0f\xc7\x11\x1e\xc5\x87\xe1\x11\x3e\x0e\x0f\x44\x0b\xdf\x89\xa6\xfe\xe8\xbd\x3c\x84\x4c\x31\xec\xec\x28\x3c\x1e\xc6\xfb\xe1\x09\x8e\x8f\xc2\xd1\x70\x74\x0c\xdd\x87\xf1\x50\xcc\xee\xc5\xe1\x49\x78\x84\x4f\x46\xe1\x5e\x36\x8c\xf7\x44\xab\x07\xe1\xe1\x70\x24\xc6\xb9\x37\x0a\x8f\x01\x3a\x58\xc0\xa9\xf7\xc2\xb6\xf8\x47\xef\xe5\xde\xc9\x11\xde\x8f\x4f\xc2\x43\xa8\x76\x82\xe3\x91\x18\xdf\x3e\x1e\x8d\xc2\xbd\xe1\xfe\x21\x4c\x36\xdc\x5f\xc6\x71\x78\x22\xe0\x7f\x9c\x8d\x22\x00\xff\x09\xde\x3b\x09\x8f\x05\xa8\x0f\xf1\xc1\x61\x78\x32\xdc\x3b\x0a\x0f\x5f\x98\xd6\xfe\xe8\xbd\x8c\xe3\x03\x31\x9e\xfd\x5e\x26\x1a\x1e\xc6\x23\x51\x7f\x5f\xd4\xd8\xc3\xa2\xe1\x21\x34\x3c\x14\x2d\x0f\xa1\xe5\xa1\x68\x1a\x9f\x88\xb6\x4e\xc4\xd4\x46\xe1\xe1\xf0\xe0\x30\x3c\xc6\xd0\xb4\x6e\x4e\x00\x59\x2c\x1f\xde\x3b\x38\x10\xe8\x70\x14\x1e\x63\x01\x94\xa1\x00\x8a\x80\xc7\xb1\x80\x4c\x2c\x56\xe7\xa0\x07\xf8\x20\x5a\x3a\x12\x83\x38\x1a\x0a\xa0\x60\x01\x94\xe1\xde\x48\x4c\x41\xd4\x13\x40\x79\xe1\x34\x29\x3a\x38\x02\x5c\x38\x1a\x65\x43\xf1\x43\xac\xe3\xf0\x20\x1c\xe1\xbd\x23\x31\xdc\x18\xc3\x3a\x8a\x65\xc4\xb0\x8c\xd9\x51\x78\x20\x10\x31\x16\x9f\xa3\xe1\xfe\x9e\xc8\xd8\x0b\x0f\x87\x87\x87\xe1\xf1\x77\xd0\x98\x80\x34\xe0\xd6\xfe\xa1\x68\xf4\x20\x3c\xc2\x30\x86\x11\x3e\x16\x35\x4e\xc2\x11\x3e\x09\xf7\x3f\xed\x8d\xc2\x38\x03\x94\x8e\x15\x0e\x0e\x05\x32\x0a\x14\x14\x3d\x1f\xbd\x30\x8d\xfc\xd1\x7b\x39\xda\x8f\x30\x34\x0e\x7b\xe2\x58\x54\x19\xee\x89\x0a\x23\x40\x34\x18\xaa\xbb\x73\x60\x84\x47\x02\x71\xf7\xe4\xc8\x47\x58\x0c\x10\x86\xfa\xa3\x1e\xe5\xfe\xe1\x08\xc7\x27\x51\x78\x9c\x1d\x60\x18\xe6\xb1\x98\xf7\x48\x8e\x0f\x8b\x81\x5e\x8a\x41\xf6\x00\x32\x6a\xf7\x85\xfb\x43\x18\xaa\x18\xe1\x10\xb6\x8b\x69\xe5\x8f\xde\x4b\xb1\x68\x78\xef\xe4\x28\x1b\xc6\x23\xc0\x31\x40\x01\xc0\x32\x40\x01\xc0\x32\xd8\x15\xc7\x62\x97\x9c\x64\x02\xb9\x00\x15\x00\xb9\x00\x17\x04\x06\x00\x9a\xf5\x5e\xe8\xe6\x04\x00\x8e\x46\xb0\xf7\x32\xd8\x68\x02\x62\x7b\x87\x02\xcb\xc5\x16\xde\x17\xab\x21\x00\x20\xe6\x0f\x5b\xee\xc9\x5e\x2c\xd6\x18\xb6\xdc\xe8\xe4\x40\x6d\xb9\x23\xb1\x02\x07\x3f\xaa\xcd\x06\x63\xc6\x07\x51\x2f\x13\x73\x1f\xc2\xde\x19\x0d\x05\x08\xc4\xcc\x87\x27\xe1\xfe\x8f\xc7\x02\xe9\x60\x15\x62\x35\x6f\x41\x2f\x60\xda\x40\x2f\x5e\xe8\x36\x00\x51\x05\xb2\x8b\x4d\xf9\x02\x76\x05\x8e\xe3\x83\x0c\x5c\x04\x89\x29\x8a\x3c\xd8\x6b\x40\xa3\x04\x14\x7a\x02\xa9\x8e\x61\x4b\x3c\xd9\x3f\x8a\x70\x3c\x12\xc4\x60\xff\xe0\x08\x06\x0b\x0b\x60\x5a\x54\x7b\x57\x80\xc3\x52\x3d\x40\xad\x43\x20\x00\x43\xd8\xf6\x80\xeb\x96\x3c\x5a\x6c\xe8\x3d\xd9\x3b\x8a\xc2\x7d\x7c\x34\x12\x5b\xfc\x78\x3f\xdc\xc7\xc7\x82\x48\xea\x36\xff\x00\xfb\xd3\x92\xcb\x4b\x34\xce\xf1\x6d\x4d\xcc\x4d\x3c\xed\x5f\x68\x8b\x70\xc1\xad\x39\xa8\x73\x9f\xce\x95\x5d\x63\x96\x97\x59\xc3\xc6\xd8\x10\xfa\xec\x3a\xf1\x46\x07\x87\x1e\xce\x6e\x12\x6f\xef\x70\xdf\xc3\xe2\x94\x38\xae\x5b\x67\xca\x66\x52\x50\x05\x75\xb4\xd3\x31\xb8\xd2\x93\x71\x22\x2a\xd1\xd8\x38\xde\x1f\x8f\x8e\xc7\xe6\x07\xcc\xec\x9e\x36\x4b\xed\x3a\xb2\x4a\xbc\x78\x1c\x8d\xe3\xb1\xfc\x57\xd4\x9d\xe9\xda\xbb\xcf\x2f\x05\x9c\xc4\x8b\x3d\x2c\xce\xb2\xd1\xa1\x20\xc9\x7b\xf1\xe8\x72\x18\x1f\x66\xc3\xc3\xf0\x10\x47\x62\x3b\x08\xcc\x11\xbb\x62\x94\x45\xc3\xa3\x18\x1f\x1d\x09\x4c\x12\xc8\x01\xbf\xe2\xe8\x28\x3c\xce\xa2\xe1\x28\x12\xc4\xed\x78\xb8\x1f\x89\xdd\x26\x72\xc4\xaf\x4c\x60\x75\x8c\xa3\xe1\xbe\xa0\xe7\x27\x82\x58\x9e\x48\x0a\x78\xd4\xcb\x86\xa2\x91\x03\x49\xad\x0e\x87\xf1\xa1\xc8\x00\x6a\xbb\x17\xc6\xc3\x13\x51\x59\xe0\x89\xd8\x8c\x82\x76\xc7\xb1\x40\x15\x81\x38\x47\xe1\x48\xd2\x9f\xd1\x11\xd0\x19\xd1\x97\xd8\x30\x27\x22\x4d\xfc\xca\x0e\x04\x02\x46\xf8\xe4\x48\x50\x48\xb1\x37\xe1\xd7\x71\x14\x8e\x7a\x59\x84\x0f\x8f\xc2\xc3\xa1\x18\x3c\x3e\xdc\x0b\x0f\xe4\x2f\x98\xc6\x93\xd1\x91\xa0\x26\x7b\xd1\x21\x9c\x95\x51\xb8\x27\xc0\x81\x0d\x60\xfe\xf8\x53\x4b\xde\x5c\x1e\xf9\xbf\x3f\xbf\x3c\x91\x5a\x9e\xbd\x11\x90\xec\xfd\xf0\x60\x79\x84\xe3\xc3\xe3\x4c\x8c\xef\x30\xdc\xc7\x07\xb0\x69\x81\x5c\xc2\xdf\xcb\x93\x4c\x24\x47\xb0\xd5\x87\x07\x40\xf2\x05\xf8\x0e\x96\x47\x43\x55\x6f\x78\x28\x4f\x0b\xb1\xd7\x0e\xe4\xea\x86\x07\x97\xc3\xd1\x5e\xef\xc9\x68\x0f\x28\xd0\x68\x84\x47\x40\x52\x05\x8f\x72\x84\x9d\xde\xff\x3a\x14\x22\x83\xa4\x91\x82\xc2\x6c\x8b\x73\xde\x71\xed\x09\x96\x21\x6d\xcd\x3f\x2e\x49\x16\x50\x25\xc9\xed\x23\x1c\xa3\xa9\x79\xa2\x77\x0b\x66\x8b\xd6\x30\x8a\x6b\xc3\x28\x75\xd1\x56\x7f\x27\x5b\xa2\x49\x97\x61\xad\xb6\xbd\x79\xc8\x73\x0f\xe5\x94\x0b\xb5\xed\x43\x5b\x8b\xfa\xe7\x9a\x35\xae\xbc\x10\xee\x32\xad\x9e\x27\xe5\x34\x9a\x6d\x77\x62\xd0\x9f\xeb\x4c\x79\x10\xdb\xdd\x55\x3c\xdb\x6e\x67\xdb\x64\x57\x67\x3b\xaa\x6d\x5d\x51\xa2\xe2\xb5\x6b\x0d\x21\x0c\xe4\xae\x10\x6a\xcc\x68\x72\xa2\x57\x31\x56\xab\x78\x10\x8f\xf4\x3a\x8a\x9f\xb0\x92\x05\x07\x0f\x63\xd4\xf7\xb9\xef\xe7\x1c\xae\x5b\xe1\xcf\x94\xea\xfb\xd6\x1e\x0b\x52\x1e\x98\x44\x34\xae\x3d\x1f\xae\x79\x20\xfa\x47\xce\xa5\x13\x22\x04\x02\x6f\xe3\x8a\x54\x3a\x91\xec\x2c\x1f\xf2\xe2\x23\x65\xbe\xdf\xdd\x9a\xcc\xc5\x72\x90\xfd\xa7\x61\xd3\x8b\xd2\xa4\x04\xa1\xe8\x9f\x34\x90\xa2\x53\x5e\xf5\x94\x27\x2d\x70\x68\x2d\x85\xba\x5e\xed\x5e\xf6\x73\xce\x2f\x7b\x02\x02\x3d\x21\x90\xd5\x8c\xa8\x10\x4a\x58\x90\x1b\x4f\x54\x59\xd7\x9e\x5a\x3a\x7b\x0a\xb4\x37\x6a\xe3\xfc\x37\x97\xf6\x73\xad\x57\x49\xde\x42\x08\xe7\xd6\x2f\x1d\x9a\xec\x50\xcf\x29\x3b\x3c\xee\xd8\x9d\x16\x44\xb5\x8a\x73\x37\x3e\x89\x58\xb7\x0f\xb2\x66\x25\xd5\x6a\xcf\x19\x0f\x2e\x28\xc4\x5c\x59\x73\x3a\x7f\x2b\x06\x2d\x15\xfd\x8c\xbf\xcd\xff\x80\xb0\xb8\x60\x85\x7b\x41\xf9\xd7\x2a\x7a\xe5\x93\x65\x4e\x19\x7f\x43\x33\x1e\xa0\x71\x4e\x32\x65\x9f\x5c\xe1\x94\x64\xda\x46\xb9\xda\x76\x68\x1d\xfa\x0c\x4c\xf9\x5a\xef\x86\x1a\x7a\x03\x84\x73\xf3\x1c\x3d\x98\x52\xfc\x89\x06\xb7\xca\xf0\x30\xa1\xf6\x2e\x4a\xa1\x68\xae\x11\x34\x75\x24\xf0\x52\x09\xed\x4c\x49\xde\x05\x36\x56\xc4\xa0\x9f\x9e\x21\xe9\x3e\xb7\xd3\x67\x44\x43\x8f\x26\xe1\x5b\x58\x8d\x5a\x5e\x03\x75\x4a\xb8\x7e\x37\x57\xe9\x17\x77\x4b\x0d\xfe\xf1\xae\x3d\xc7\xf1\x1a\xdd\xe6\xd2\x49\xc2\xb4\xe2\x01\xc3\x05\xc2\x15\x0f\x2a\xdb\x77\xa5\xfa\x43\x33\x24\x9f\xec\xdb\xda\xea\x52\x68\x4d\xb2\xa0\xc2\x23\x84\x57\x64\x2d\xa8\xf4\x82\xac\xa7\xf1\x6c\xcc\x05\xd0\x6e\x68\x00\x3a\x8c\x2a\xb9\x85\x07\x54\x2b\xa9\x8a\x58\x6c\x71\xdb\x6a\x86\x39\x90\xcb\xb5\xee\x22\x55\x15\x14\x24\x4b\x05\xc9\x65\x1b\x92\x70\x77\xb0\x6d\xb8\xb7\x59\x3b\xe8\xfe\xe0\x37\x93\x13\xf7\x23\xd1\x18\xfb\x58\x2f\x4c\xdb\xad\x96\x79\xa5\x8d\xcb\x4e\xaf\x02\x61\x3a\x9f\x3b\x77\xcc\x9e\x40\xeb\x54\x92\x0a\x73\xc3\x39\xac\xed\xe4\x6d\xa7\xf7\xbb\x1e\x53\xfe\xb4\xfe\x6c\x63\x39\xa9\x9b\xf9\x4c\x5c\x03\x8e\xd7\x28\x71\x3f\x33\x8e\x70\x4a\xa6\x5e\xe8\x74\x51\x27\x01\xd8\x4b\x58\xc1\x83\xa9\xed\xa4\x75\x5f\x3b\x43\x1e\x9a\xd5\xcd\x36\xba\xdc\x49\x86\xae\x13\xca\x07\x35\x0a\x6e\x2a\xa5\x76\x16\xf7\xa4\x7a\x1f\x96\x4f\x5f\xe0\x2a\xaa\x32\x9d\x81\x07\xa9\x4a\x2a\x3f\x6b\xbe\xff\x1e\x2f\x97\x41\x8a\x6a\x7e\x77\xf3\x45\x60\x6f\x06\xd1\x6d\x19\x18\xb7\x2f\x08\x17\x01\x44\xf6\x59\x52\xb8\x6c\x95\xcf\x21\xde\xd1\xc0\x2b\xd8\xbb\x92\x0a\x2a\xb1\x04\xb7\xd9\x5d\x1a\x55\x1b\x35\x6b\xc9\x03\x8e\xc6\x0c\x1c\x0a\x49\x5f\x29\x4e\xf7\x7f\x6c\x36\xaf\xb8\xeb\x97\xe7\x9f\xd4\xf7\xeb\x41\x06\x5f\x71\xe4\x6a\xe1\xa7\x33\xb4\x73\x4b\x83\x3d\x9b\xda\xd2\xcb\xd6\x96\x65\xe8\xf6\x07\x1a\xb0\xba\x33\xe6\xc0\x4b\x65\x8c\x4b\x84\x4b\x77\xb6\x62\xee\x16\x10\x9d\xb7\xe8\xbe\xcf\x03\x84\xb3\x00\x61\xe3\xa0\x2d\x94\x33\x73\x7b\xc8\xec\xcd\x34\x42\x35\xa6\x60\xf5\x37\xed\x4f\x38\xd6\x9a\x93\xa5\xe8\x96\xfa\xfe\x0f\x82\x7a\xcf\xb0\xbc\x5d\xb4\xbe\x0f\x78\xcd\x42\xc0\x6b\x21\x5d\xdd\x87\xe7\xd0\xc0\xc1\xb1\xd4\x57\x06\x25\x5e\x22\x77\xdc\xee\x35\x29\x71\xe1\x04\xb6\x6e\x2a\x98\x99\xb9\x44\x2a\x03\x6d\x68\x21\x9d\x3f\x28\x8e\xf2\x6e\x97\x0e\x3b\xb4\xd5\xf5\xf1\x7b\x48\x2c\xda\x16\x09\x56\x19\xa7\xe4\x65\xd8\x3e\x6d\x31\x17\x47\x6c\x2a\x72\xb4\x6f\xfd\x1f\x05\xcb\x2e\x29\x8c\x72\xcd\x0a\x6a\x6e\xb1\xbc\xd7\x02\xf1\x77\x16\xfe\x0c\x67\xa1\x87\xf0\xba\xb3\x8c\x3a\x46\xe5\xf6\xcd\x7d\xbf\x9f\x21\xc7\xb8\x51\x10\x38\x69\x1a\x94\x83\x51\x83\x28\x94\xf9\xbe\xc7\x0a\x06\xd7\x10\x6b\xdf\xf7\xe0\xaf\x5c\xbd\x15\xf9\xef\xa9\xf7\x56\xba\x7c\xf6\xde\x68\x77\xcf\xde\x0b\xe5\xe7\xf7\xa9\x76\xf3\xec\x49\xd7\xca\x8e\xf5\x62\x36\x8d\x67\x68\xf2\x6e\x2a\xfe\xd6\xaf\x17\x67\xc9\xab\xe9\x52\x9c\x64\xaf\x68\xb0\x07\x8f\xb5\x55\x98\xc7\x75\x58\xad\xcf\x2b\x5e\x06\x31\x8e\x51\xb2\x46\x78\x4e\x9e\xd2\x60\x85\x17\x08\x5f\x92\x39\x44\x91\x9b\x6f\x36\xb9\xef\xe7\x77\xdd\x2f\x13\x78\xaf\xde\x59\x44\x5e\x31\x13\x42\x2e\x51\xa9\x6d\x51\x68\xfd\x12\x9d\xe1\x4b\x78\x5d\xd1\x84\xd5\x58\xba\x0f\xbf\xad\xdf\x2a\x28\x0e\x44\xfc\x74\xaf\x1e\xec\x51\x5b\x51\x7d\xd6\xf6\x63\x79\xd8\x4a\xdf\x4c\xf5\xbb\x82\xe9\x4c\x5f\x16\xdc\x6e\x6b\xac\xff\x76\xbb\xc5\x57\xe4\x5c\x31\x1a\x57\x9d\xef\xbb\x1b\xb8\x38\x23\x5c\x30\x19\x73\xbc\x6a\x6d\xd9\x42\x8b\x00\x37\xea\x35\xd9\x39\xae\xf1\x0f\x85\x1c\xe1\x43\x6e\x51\xf4\x74\x57\xb6\xc0\xa5\x9a\xd5\x55\x83\x7b\x10\x07\x5e\xdb\xb3\xce\xa7\x0b\x0f\x8d\xbd\xe4\x1c\x5c\xd1\x00\xd1\x83\x2b\x7e\xc7\x3d\x4d\x8a\x69\xb8\xc8\xcb\x8a\xc3\x12\xa0\x84\x86\xe9\x4a\x10\x0a\xb9\x22\x29\xd2\x2f\x39\xa5\xcd\xd2\x9f\xb1\x9d\xc2\x7a\x71\x5d\x32\x21\x36\x83\x25\xb0\x05\xda\x4a\x03\x0a\x99\xea\x78\x58\xe1\x4e\xdb\x9a\xb9\x5b\xc8\x23\x56\x4d\x06\x61\xf5\x9d\x2e\x38\x2d\x3d\xc1\x3e\x59\x8f\x28\xbc\x46\x5d\xac\x3d\x4a\x9f\x58\x23\x3f\xe9\x3e\xbe\xff\xdf\x9f\x1d\xdb\x13\x6b\x60\xe8\xf8\x00\x42\xbe\xdf\x7f\x28\x89\xf2\xfd\xa0\xef\x76\xb8\xd9\x68\xeb\x45\x37\x55\xf7\xe3\xfa\x54\xe1\x3a\x0e\x04\xda\xcd\xe9\x1a\x93\xe4\x6e\x96\xc0\xfb\xca\x43\x86\xd0\x5e\x72\x79\x9d\x37\xe7\x08\x17\x70\xdc\x77\x3a\x70\x46\xe3\x1f\x21\x68\x8c\x02\x72\xd9\x42\x67\x74\x5b\x04\x08\xff\x42\x03\x84\x79\xb0\xe3\x70\x34\x25\xec\x09\x69\xbd\xb8\x70\x63\x9e\xdf\x72\x16\xcc\x49\x43\xa4\x67\x1d\x66\x82\xb8\x24\x5f\x56\x9f\x2e\x80\xb5\x4a\xca\xa2\xe0\x28\xac\xb7\xd3\xbb\x7d\xcf\x7a\xbd\xe2\x13\x2d\x17\xcb\xe2\x73\xd2\xfb\x94\x57\xf9\xf9\x92\x8e\xdf\xb3\xed\x7b\xf6\x9e\x75\x96\x36\x4f\x63\x55\xc6\xf9\xb2\xc8\x3e\x8e\x45\x0e\x10\x7f\x30\x0b\xe9\xe5\xec\x92\x96\x39\x87\x64\x25\x1a\xf5\x62\x7a\x35\xde\xd5\x5d\xaf\xa7\xbd\xa8\x0f\xd3\x65\x7e\xc1\x92\xde\x30\x0a\xe3\xd1\x01\x54\xd9\xb6\x46\x12\x0a\x9e\xf4\x42\x8e\xa7\xa3\xe2\xe8\xce\x8a\x9f\x87\xb1\xac\x29\x65\xb7\x5e\x14\x46\x87\xf7\x54\x18\x35\x2a\xdc\x3d\xb2\xcf\xc3\xbd\x66\xf9\xe3\xa3\xbb\x2b\xec\x37\x2a\xdc\xd3\xfe\x41\xa3\xf8\xde\x7d\x03\x3a\x6c\x56\xb8\x67\x3c\x47\x8d\xf2\xfb\xf7\x55\x38\x6e\x54\xb8\xbb\xf4\x49\xb3\xf4\x7d\x0b\x10\x47\x8d\x1a\xf7\x56\x68\xae\xf1\xe1\x7d\x4b\x10\x37\x17\xf9\xbe\xf2\xcd\x45\x3e\xbe\x6f\x11\xe2\xe6\x2a\xdf\x3b\xa4\xe6\x3a\x9f\xdc\xb7\x0c\x71\x7d\xa1\xe3\xbb\x0b\xd7\x57\x39\xbe\x7f\x1f\xc4\xc7\x8d\x1a\xf7\x4e\xf9\xa4\x59\xe1\xbe\x39\x8f\xa2\x46\x8d\x3b\x7b\x30\x01\x1e\x64\xa5\xab\xb4\xbc\xc8\x99\x8c\xf2\x00\x68\xae\x48\x8e\x6a\x4c\x08\xc1\x77\x37\x05\x35\x6b\x6d\x89\xc6\xff\x6c\x53\x32\xfe\x84\x6c\xc6\x50\xbf\x3b\xb7\xc4\x32\xaf\xcd\x7a\x74\x47\xd1\xc5\xe7\x9d\x00\x7a\xcf\x42\x23\xac\xf7\xaa\x4f\x17\x9d\xf4\xfb\xbc\xe0\xbc\xb8\x4a\x7a\x11\x4c\x47\x4d\x6f\x6c\x67\x6c\xe6\xd6\xeb\xad\x0a\x15\xe9\xbd\x97\x9e\x57\xc5\x72\xcd\x25\xa9\xd6\xe0\x85\x0f\x5e\xac\xe4\xcf\x66\xff\xf7\x1c\x16\xcd\x53\xc1\xf6\x55\xd2\x65\x2a\x04\x52\xd9\x3c\xbd\xe6\x9a\xb2\x67\xf0\xf2\xf9\xbe\xd3\xa2\x03\xf9\xef\x07\x4a\xeb\xc9\xb4\x72\x5d\xa0\x3b\x75\xfb\xd6\xff\xdd\x5f\xb6\x01\x12\x1d\xcc\x03\xf7\xc2\xba\x4e\xe5\x3e\x58\xed\x58\x87\x4e\xd8\x34\xfb\xb4\xed\xcb\xa5\x3e\x88\xbe\xb0\xeb\xa6\x3f\x5a\xd3\x4f\x7a\xf6\xbd\xfc\xf0\x20\xfa\x02\xf7\xc4\xbf\xa8\x7b\xfe\x77\x15\xfe\x5f\x05\xac\x42\xf0\x34\xfb\x78\x51\x16\x6b\x36\x1f\x66\xc5\xb2\x28\x93\xde\xff\x59\x2c\x46\x07\x7b\xe9\x58\xa2\xbf\xd8\x9b\xc3\x32\x9d\xe7\xeb\xca\xa2\x9f\x1e\xe7\x79\x71\x2d\x58\x98\x9c\x5d\x24\xba\xe8\x79\x71\x5d\x1b\xde\x1d\x45\x6c\x7f\x8b\x71\xd7\xe6\xef\xf5\x60\x65\x4d\xb2\xda\x76\xd7\x43\x85\xb2\xba\xd4\x55\xce\x86\x66\x7f\x1f\xb4\xf8\x26\xa9\xab\x96\xa8\x91\xce\xe7\x30\x12\xc3\x33\x34\xf7\xa7\x40\x12\x5b\x95\x2e\x97\xf9\xaa\xca\xab\xfa\xde\xed\xc4\x00\xe9\xf5\x40\xb4\xbb\x73\xdd\x9b\x45\x76\xaf\x36\x2f\x56\x72\x5c\xf7\xac\xb4\x5b\xae\xb9\xca\x92\x72\xb9\x34\xba\x4e\xcb\xda\x74\xc9\x50\xb2\x7f\xf5\xf4\xe4\x40\x1e\x34\xc3\x46\xd1\x1d\x93\xb4\x67\xda\x6e\x7a\xad\xe6\x6b\x26\xf9\xff\xca\x94\xc5\x80\x1e\x36\x63\x55\xb2\x45\xa0\x8a\x95\xbb\xa4\xdd\x87\xcb\xff\x37\x10\x54\x4c\xc5\x2e\xdc\xbd\x4b\xf5\xbf\x37\xb1\x07\x2c\x92\x53\xcc\x4e\x4b\x89\x58\x8e\x60\x17\x87\x7b\xe6\xbf\x2e\x92\x66\xd8\xe6\xce\x33\x3a\x3a\x3c\x3c\xaa\x33\x2b\xd7\x55\xab\x0b\x97\xf3\x96\x85\xaa\xab\x8e\x42\xc7\xcd\x52\xf1\x75\x7b\xb4\xf5\x12\xa3\x76\x89\x51\xbd\xc4\x5e\xbb\xc4\x5e\xbd\xc4\x7e\xbb\xc4\x7e\xbd\xc4\x41\xbb\x44\x63\xa4\x87\xed\x12\x87\xf5\x12\x47\xed\x12\x0d\xc0\x1d\xb7\x4b\x1c\xd7\x4b\x9c\xb4\x4b\x9c\x34\x20\x16\x75\x80\x2c\xaa\x97\xd1\xec\xe6\x0e\x46\x6c\x27\x17\xba\x5e\xaa\x5d\x90\x57\x7c\x08\xca\xc3\x21\xbf\x59\x51\xe5\x51\xab\xc5\x60\x8f\xcc\x31\xa7\x4e\xb4\xa1\xdd\x3e\x5b\xd3\xe2\x59\x4f\x33\xca\x9d\xec\xa2\x45\xdc\xdc\xdd\x82\xc3\x51\x8b\xc7\xbc\x9f\x8f\x6a\xf0\xe2\x0d\x34\xb7\xfa\x0d\xd3\xa7\xcb\xf4\xcb\xdf\x49\x0f\x02\x08\xf6\xa2\x30\x3a\xa6\x57\xbd\xff\x43\x29\xed\x62\x41\xa2\x30\xae\x4f\x1d\x0e\x73\x7a\xa5\x8e\x74\x91\xdf\x80\x6d\x43\xea\x59\x2c\x8b\x94\x27\xad\xdd\xdb\x14\x68\x54\xb1\x26\xf1\xaa\x35\x88\x21\xa9\xea\x48\x2b\x3b\xd2\x96\x1d\x69\xe7\x0f\x16\xcb\xb6\xf5\xee\x21\xb7\xd9\xbf\x93\x58\x76\x25\x2e\xbb\x12\xcf\x1f\x2c\xce\x59\x0a\xb3\xca\x59\x5d\x12\x48\xf5\x8b\xce\xa4\xa7\xf3\x47\x55\x2f\x67\xd2\x4e\x1c\xb0\x21\xad\xb3\xad\x0f\xad\xe1\x2e\x50\x45\xef\xed\x35\x76\xda\xa8\x38\x5d\x55\xc1\x31\xba\xaf\xdf\x1d\x75\xa0\xe7\xff\x4b\xf7\xf5\x91\xde\xc8\xe8\xe3\xbd\x1a\x00\xa2\x2f\xe4\xdf\xce\x93\x49\x79\xac\x8a\xe6\xf4\xa2\x3e\x88\xda\xe1\xd4\x2a\xb5\x15\xff\xc4\xd1\x43\x9a\xde\x3b\x7c\x58\xe3\x6e\xb9\xad\x9e\xda\xff\xdf\xa6\x24\xb0\xc4\xc4\xa6\x54\x98\x72\x55\x0d\xa5\x9e\x3a\xe9\x79\xab\xb2\xb8\xc8\xe7\xc9\xd3\x9f\x9f\x5f\xa5\x17\xf4\x9d\x6e\x31\x7c\x99\x67\x65\x51\x15\x0b\x1e\x7e\x9d\x56\x79\x06\xb9\x01\x34\x94\x17\x8c\xc4\xc8\xdb\xc5\x79\xa8\x91\x9c\xb4\x07\x7c\x47\x21\x83\xd0\x36\x74\xe6\xdf\x36\xd6\xd1\xbd\x63\x8d\x8f\x1f\x32\x58\x5b\xaa\x39\xda\xd1\xd1\xdf\x37\xda\xbd\x7b\x47\x3b\x3a\x7a\xc8\x68\x6d\x29\x7b\x0e\xd7\x83\x8f\xfe\x6d\x43\x8e\x70\xef\x2a\x2f\xcb\xa2\xbc\x0b\x2d\x24\xb7\x39\x8c\x71\x2f\xbe\x87\x23\x35\x65\xea\x03\xd7\xbc\xe0\xdf\x87\x17\x0f\x1f\x76\x8c\x7b\xc3\xfb\x86\x6d\xca\xd4\x87\x7d\x5e\xf0\x4b\xa9\xad\x69\x80\xff\xdf\x62\x62\xc3\x87\xcc\x6c\x58\x9f\x1a\x5c\x03\xf5\x6a\x74\x05\x77\xa4\xc6\xc7\x9d\xc9\xa3\xa3\x7a\x72\x03\x2a\xed\x3c\x0d\x9e\x76\x8e\x00\x6d\xfd\xec\xd3\x80\x33\x0c\xa2\xfe\xaf\x91\x61\x0f\x6d\x9e\x66\x1f\x1f\xaa\x67\x6c\xf3\x80\x35\x3d\xa3\x66\xf6\xc2\xa6\xe8\xa1\xa2\xf7\x62\xf7\x53\xcb\x11\xff\x5a\x55\x6a\x5b\xf5\xab\x07\xd3\xd0\x2c\x37\xd4\x9e\x77\x6b\xcc\xeb\x33\x68\x42\x67\x17\x18\x54\xb8\x62\x59\xa9\xae\xe5\x52\x83\x95\x9e\x0a\xeb\xec\xaf\x9c\x56\xb6\xcc\x57\x02\xda\x19\x0f\x22\xdc\x53\xff\x47\x75\xfd\xd8\xea\xba\x06\xb6\xa1\x4e\xb8\x47\xe7\x75\x17\x68\x35\x38\xa0\xa5\xda\x20\x87\xe6\x45\x68\x22\x4d\x9f\x70\xaf\x23\x0b\x7e\xa9\x09\xc3\x0c\xcc\x5a\xea\x51\x9b\x04\x3d\xec\xe8\x8e\xfb\x4d\x3b\xca\x4a\xec\xf4\xac\xfb\x32\xa1\x7d\xe7\x0a\x8c\xa2\x8c\x88\xad\xd8\xf8\x7c\xb9\x4c\x7a\x9f\xd2\x32\x18\x0e\x6d\x9e\x54\x75\xe2\x9e\x6b\x85\x2d\x61\xac\x1f\x11\x28\x6d\xa3\xf9\x6c\xb5\xa0\x72\x6a\xf4\xbb\x63\x30\x26\x14\x77\xe7\x70\x4c\xee\x03\x06\x14\x85\xfb\x3b\x86\x64\x5b\x31\x83\x8a\xc2\xfd\x5d\xc3\x82\x51\x39\xb1\xc4\xdb\x30\xfb\xdf\xe9\xb2\x01\x99\xbf\x13\xf0\x57\x69\xf5\xd1\x9d\x16\xbe\xa3\x48\xe7\x02\x41\xe0\x0e\x67\x47\xcf\xef\xdb\xd5\x5f\xca\x70\x97\x29\xb8\x8f\xda\x6c\x58\x9f\x10\xe3\x34\xc4\xf5\x9d\xf4\xfe\x7d\xcd\x54\xd4\xc3\xde\xfb\xf7\x43\x0f\x61\xef\x02\x7c\x65\xd4\x8b\x0e\x87\xbb\xcb\xa6\x3b\x9b\xa5\xb2\xc4\xb8\x24\xa5\x31\xbb\x2b\xb0\x63\x3e\x2a\xbd\x6b\xdb\x60\x3f\x39\xf6\x9c\x9e\x9a\xb9\xa9\x5b\x95\x19\x37\xd3\xbd\xd2\x5a\x5e\xbc\xe4\x01\xba\x55\x56\xe3\x10\x7f\xd9\xf7\xfb\x1f\xb8\xef\x07\x19\x0d\xae\x78\x80\x10\xfe\xc0\x49\x3f\x72\x6c\x35\x2e\xea\xef\x1b\x94\x49\xad\x8c\x1a\xab\xed\xdf\x02\x8a\xbd\xf4\xbc\xe2\x65\x9a\x71\x0f\xdf\x5e\x50\x9e\xf0\x2d\xc2\x3b\xcb\x5e\xf2\xab\xa5\x2a\xd7\xf6\x47\x4a\x43\xdd\xd4\xbd\x96\x45\xdb\xbb\x3a\x61\xc5\x9c\xb6\x3b\xb1\x16\xcf\x1d\x51\xc7\xe6\xf9\x27\xe7\x25\xbc\x1b\x58\x2c\x14\x43\xc6\x36\x96\xc0\x56\x74\xed\xc6\x8a\xe1\x9d\x4e\xdc\x8d\x03\x20\x3e\x11\x68\x91\x70\x13\x95\x48\xba\x9e\x59\x04\x26\xc6\xea\xcf\x34\x78\xac\xa6\x01\xe4\xb4\x02\xa7\x94\x9b\xcd\xcf\x34\x30\xce\x2f\x45\x0a\xbc\x81\xf8\xc4\xf1\x63\x2e\xd0\xca\xb5\xb8\x31\x83\xa1\x01\xba\xed\xd7\x6d\x76\xf3\x45\xd0\x0f\xa8\x6b\x8d\xcb\x77\x04\xd3\x7b\x22\x43\x59\x66\xe9\x72\xd9\x4b\x7b\x60\x27\x57\x8f\x66\xe9\xa1\x2d\x44\x66\xc4\x14\xc9\x67\xf0\xce\x98\xc9\xad\xf4\xd1\x04\xce\x68\x0c\x20\x09\xc5\x01\x23\xd3\xdb\x8f\xf4\x26\xf1\xd2\xf9\x5c\xbd\x0d\x74\x97\xc5\xc6\x3e\x93\xc1\x24\x5b\x56\xb3\x98\xc1\x2e\x92\x0f\x9c\x38\xc2\x25\x89\xc6\xe5\x29\x1f\x97\x83\x01\x62\xd3\x72\xe6\x58\xd2\x96\x33\xed\xa0\x4c\x1b\x30\xcb\x98\x8e\xab\xf5\x72\xf9\xd4\x81\xef\xed\x16\x8d\x5d\x0b\xf1\xa2\xcb\x03\x13\xc4\x3b\x75\x66\x38\xe5\xca\xad\x69\x33\x15\x7c\x9b\x16\x53\x3e\x43\xf8\x05\x0d\xb8\xfa\xf9\x93\xb2\x1f\xde\x62\x39\xfb\x92\x56\x94\x77\xcc\xbf\x0b\x90\xba\x4e\x73\xe0\xad\xea\xb5\xd7\x15\xda\x33\x8e\x7d\x67\xa1\x7f\x4f\x6e\xa3\x84\x6f\x13\x3e\xee\xf0\x76\xc8\x9a\x7e\x1e\xb8\xf5\x1e\xca\x67\xb8\x30\x8e\x29\x21\x72\x9a\x13\xe4\x48\x7e\x8c\xe9\xb4\x98\x6d\x36\x81\xf8\x03\xb1\xc3\xc5\x8f\x69\x3e\x23\xa9\x74\x5a\xba\x9d\x21\xdf\xcf\x03\x6e\x7d\x1d\x60\x86\x70\x09\x69\x32\x16\x9e\x26\x3d\x31\xfe\xcc\xc9\x2d\x98\xc6\x27\x2d\x5f\xae\x2d\x53\xea\xa8\xd3\x94\x3a\x72\x4d\xa9\xa3\x59\x72\xbb\x55\x0f\x1d\x04\xf5\x1b\xeb\x4d\x2a\xe8\x43\x7d\x8b\x5e\xa8\xfd\x99\x59\xd7\x5e\x26\xd7\xf1\x6b\x8c\x6e\xb7\x49\x69\xfd\x7e\x74\xbb\xbe\x3a\x17\x14\x18\xaf\xe5\xdb\x93\xad\xb5\x5a\x94\x41\x1a\x03\xef\x35\xc4\x94\x95\x41\x75\x7f\x5f\xe7\x25\x15\x5b\xec\xe9\xeb\x97\xbd\x62\xd1\xab\x8a\x2b\xda\xfb\x98\xb3\x79\xe8\xa1\x2d\xce\xaa\x2a\xb9\xe2\x58\x5a\x68\x3e\xa9\x2a\x17\x2c\x1f\xf8\x66\xd3\x22\xdd\xd2\x0a\xf4\x6f\x84\x1e\x16\xe0\xaa\xbb\x6e\x03\x07\x67\x6c\x87\xe7\xb3\x71\x3f\xee\x70\x06\x07\x4e\xc8\xea\x49\x62\xb8\xb8\xed\x94\x8d\xf4\x23\xfc\xa6\x66\x4c\x78\xcd\x83\xdb\xf6\x00\xe0\x90\xf9\x07\x04\x2c\xb1\xbe\xdb\x92\x35\xc7\xae\xeb\xb6\x64\xc5\x71\xb7\xe7\xb6\xe4\x9c\xe3\xae\xe1\x27\x6c\xab\xf6\xec\x1f\xdc\x8d\x1a\xb7\xc3\x33\x8e\x28\xf8\x9a\x93\xe0\x13\xef\x70\xba\xf2\x17\x8d\xff\x6f\xb7\xe0\x71\xc8\xbe\x83\xaa\xb9\x45\xad\x28\xb8\x45\x35\x2f\xa3\x1c\xc7\x5d\x85\xef\x17\xf0\x68\x0a\x5e\x4a\x65\xb6\x56\x2a\x23\x16\xa6\xf0\x7a\x4a\x87\x1f\x33\xb9\x4b\x99\xbb\xc4\x2b\xc2\xf5\x53\x39\x13\x86\x8c\x10\xb2\x9a\x4c\x67\xc9\x0a\xcf\x09\x77\x7d\xb5\x5e\xda\x02\xf3\xc9\xed\x36\x99\xe3\x73\x31\x28\x79\x56\x5d\xd9\xcc\x73\x91\x79\x0e\xcf\x1a\x25\x5c\x5e\xda\x33\xf2\xc2\x0d\x74\x72\xa3\x3e\xf4\xe6\xba\xe0\x10\x21\x09\x9c\x9b\x80\x05\xf9\x56\x1c\x3a\x41\x9b\x67\x10\x1b\x1b\xd7\x5c\xf0\xac\x27\x97\x7f\x9f\x0b\x9e\xcb\x1d\x2e\x78\x2e\x3b\x5d\xf0\x34\x1f\x87\xa5\x3c\xb8\x51\x21\x81\xb2\x09\x04\x04\x81\x18\x33\x49\xf3\x39\x28\xd8\x79\xeb\x77\xbd\xda\x02\x5c\x5a\xa2\x2b\x9b\xef\x97\xd6\xe6\xfb\xc2\x35\x75\x17\xe7\x51\x45\x05\x21\x55\x26\xef\xb9\xb2\x8f\x5f\x6b\x7b\x77\xc7\xb4\xfd\x52\x5b\xbc\x5f\x61\x6d\x05\xbf\xd8\x6a\x8c\xff\x7b\x31\x58\x3b\xd1\x95\x3e\xc6\x13\xc1\x24\x41\x82\x89\x9e\xe7\xb8\xab\x0a\x4a\x12\x94\x4e\xf1\x52\x14\x97\x09\x08\x7f\x12\x74\x54\xfa\x1a\xc0\xb7\x32\x56\x19\xd8\x14\xe3\x77\x9c\xdc\xb2\xe2\xf1\x9a\x17\x2e\xbd\x6b\xd3\x99\xb8\x93\xcc\xc4\xf8\x5b\x0a\x4e\xf9\xe6\x79\x95\x15\x8c\xc1\xa3\xcb\x2d\xce\xe0\x91\x6b\xf2\x14\xcf\x8b\xab\xe4\x33\xc7\xcb\xfc\xbc\x4c\xcb\x9b\xe4\x31\xc7\xf0\xac\x33\xf9\x83\xe3\x45\xce\xe6\xcf\xb3\x82\xd9\x73\x39\xb9\x91\x0e\x90\x93\xd7\x1c\x73\x7a\xdd\xe5\xe7\xf5\x5f\x4b\x0d\xe4\xae\xae\x79\x9d\x84\x5d\x2d\x09\x82\xde\xd5\x35\x9a\x30\x9d\x25\x29\x5e\xd7\x77\xf5\xca\x16\x58\x8b\x8d\xbb\xc6\x0b\xbb\xab\xe7\x36\x73\x21\x32\x17\xce\x56\x55\x1b\x55\xbe\xa5\x33\x4f\x4a\xb7\x3b\xf7\x6b\xed\xe5\x69\x37\x3a\xab\x60\x33\x1d\x58\xbc\xd2\x58\x3c\x37\x58\x3c\xbd\xe3\x55\x78\xed\xa9\xaf\x79\xc1\xb7\x0c\x32\x10\x22\x20\x82\xb2\x32\xb5\xfa\xfb\x97\x4d\xbd\x20\x76\x96\x0c\x96\x45\x2e\x9a\x5e\x96\x96\x63\x6b\x58\x34\x67\x59\x2a\x77\xdd\x6e\xb7\x49\x8a\x33\xbb\x2c\x0e\x29\xcf\x44\x66\xd6\x5e\x16\x35\xbd\x07\xad\xcc\xe3\xda\x9b\x60\x13\xed\x00\x35\x5e\xab\xba\xeb\x51\x99\x30\x81\x7f\x66\x3d\xf4\xa0\xdc\x25\xc9\xed\x92\x40\xa9\xbf\x7d\x41\x34\xc8\x6b\x4b\x32\x9d\x25\xac\x0d\x34\x18\x80\x57\x07\x94\xc3\x44\x5a\x37\x7e\x8d\x48\xfd\xcd\xb8\xe5\x13\xda\x96\x65\xb9\x18\x8a\xd2\x03\x18\x91\x57\xcc\x3b\xd9\x99\x83\xa7\x77\x87\x55\xb9\x1f\xe2\x35\x48\x97\xc8\x89\xc2\xb9\xad\x47\x9d\x12\xe0\xe7\xc5\x77\xfc\x6a\x99\xfc\x46\xb7\xf8\x9a\xb7\x23\x2b\xfc\x0b\xf8\xc9\x3a\x33\x3e\x0e\x5c\x11\x45\x4b\xc1\x26\x0e\x75\xb4\xd9\xd4\x9f\xff\x22\xdf\x7f\xec\xfb\x6d\xbe\xf3\x1d\x0f\xe7\xc5\x55\x08\x42\x45\x70\x2b\x98\x43\x60\xf1\xb6\x48\xc5\x1e\x11\x12\x27\x0b\xe2\x13\x84\x59\x70\xb4\x8f\xc2\x8a\xf2\xe7\x57\x57\x74\x9e\xa7\x9c\x22\xf7\x4c\x94\x9e\xf0\xbd\x75\x45\x7b\x15\x2f\xf3\x8c\x7b\x63\x1e\x7e\xf8\x40\xab\x97\xc5\x7c\xbd\xa4\xa4\x1f\x29\x1f\xdc\x79\xc0\x82\x08\x21\x5c\xc0\xaf\xa3\x08\xa1\xee\xe8\xfb\xe0\x50\xd7\x36\x30\xa1\xc9\xed\x9c\x2e\xd2\xf5\x52\x6c\xcf\x2d\xa8\x03\xc4\x07\x29\xf5\x2f\xa5\xb1\x80\xc0\x8a\xd7\x7c\xb3\x29\x74\x06\xa6\x21\xbd\x5e\x15\x25\xaf\x88\xa9\x56\x1f\xba\xa3\x20\xa8\x69\x5b\x74\x35\xa6\x5d\xd5\xa5\x55\x95\x5f\xb0\xcd\xc6\x45\x56\x1b\x2c\x25\x1e\xf3\xd3\xe6\xca\x8f\xf9\x60\xd0\x8a\x71\x32\xe5\x33\x13\x8e\xbd\xec\xe5\xac\xc7\x90\xea\xc0\x3a\xbc\xbb\x4c\xab\xd7\x9f\x99\xd6\xda\xc8\xe5\x60\xb8\x44\xda\x63\xa5\x90\xec\x9d\x27\xc2\x98\x85\xe9\x6a\xb5\xbc\x91\x4b\x66\x7a\x42\x5b\x67\x16\xf7\xac\x17\x0b\xe7\x01\xc7\x5e\xea\x75\x11\xbf\x42\x47\xd7\x28\x89\x58\x3f\xf0\xac\xc9\x82\x12\x85\x69\x1d\xee\xc1\xed\x16\x35\x81\x6b\x87\xd0\x4c\xdf\xe5\x0b\x90\xbb\x7e\x00\x77\xb9\x01\xa4\x58\x20\x08\xe4\x7d\xf8\x40\xf8\xf6\x9e\xe9\x99\x25\x2e\x65\xef\xf0\x36\x57\x7a\xd2\x3c\x33\xde\xc0\x7d\x3f\xe0\xd6\x37\xb8\x13\x33\x3f\xc2\x65\x4d\xcb\x32\x66\xa7\x1c\x62\xe1\x94\xcd\x48\xef\x8e\x4a\xb1\x30\x1a\x26\xe5\xad\xba\x1d\x8a\xc1\x3e\x04\x16\x45\xc7\xb2\xb3\x16\x32\xe8\x73\x46\xa2\x01\xd5\x81\x75\x8e\xf1\xd0\xf8\x35\xf5\x5e\x1b\x4f\x27\xf0\xea\xdc\x81\x14\xf8\x51\xad\xa5\x80\x6b\x47\x84\xbd\x97\xe9\x0a\x2a\x6c\x36\xde\x5b\x2a\xeb\x4e\x24\x81\x5e\x94\xc5\x55\xc0\x50\xe2\x3d\xd6\xa8\xa4\x0a\x3e\xfa\xbf\x83\x49\xf2\x43\xbe\x79\x8e\x18\x0f\x26\xc9\xf1\x26\x3e\xdc\xec\x8d\x50\x30\x49\x9e\x2c\xd3\xab\x15\x9d\x23\xd9\xc2\x7f\x3c\x0a\x39\xad\x84\xa8\x3f\x91\x73\x4b\x24\x05\xdb\x6e\xef\xc5\xb3\x7b\x16\x52\x63\x61\x1c\x1d\xa2\xb1\xc5\xad\x6f\x54\x1d\x07\x6c\xe7\x39\x9b\x6f\x36\xe5\x03\xdb\xdb\x3f\x10\x68\xdd\xf5\xe8\xfd\x2d\x88\x0e\xbe\xaf\x23\x40\x36\x73\x02\x6f\x51\x14\xa0\xfa\xde\xb9\x72\x38\x25\x12\xb0\x35\x5c\xce\x52\x6e\xa3\x47\xd5\xf5\xb4\x38\x23\x95\xef\xb7\x4e\x96\xdb\x2d\xb8\x39\x30\x44\x47\x50\x8f\x2a\xa0\xd8\xbb\xf6\xf0\x2d\x65\xeb\x2b\x5a\xca\x47\xae\xb1\x52\x85\xd1\x2d\xc2\x1a\xcb\xfa\xb1\x8d\x06\x7e\x4d\x08\xa1\xca\x27\x81\x09\xdb\xd1\x8f\xb7\xdb\xa0\xee\x23\xb5\x16\xee\x6a\x1c\xf4\x03\xe8\x92\xa2\xcd\xa6\x03\x52\x41\x41\x04\x85\xf2\xa6\xd2\xed\x4e\x4f\xaf\xc9\xcc\x03\x67\xd4\x80\xbd\x05\xf2\xfd\x12\x9e\x89\x06\xd9\xa4\x82\x0e\x6e\xa5\x58\xb1\x56\x43\x8f\x70\xd7\x44\x18\xfe\x5c\xe6\xdc\xbc\xe0\x4d\x64\xe4\x1f\xb4\xc5\x6b\xd2\xa5\xee\x6b\x07\x94\x6a\x45\x8e\xca\x49\x29\x76\x72\xe1\xfb\x41\x4e\x52\x39\xba\x5c\x6b\xcd\x2f\x28\x77\xe8\xaf\x5c\xe7\x2a\xe0\x08\x59\xaa\x50\x91\x68\x5c\x9d\x6a\x1f\xdb\xe3\x6a\x40\x62\xb4\x0c\x28\xce\xa7\xd5\x0c\xf3\xa9\xf8\x33\xc3\x4c\xfe\x45\xdb\xf1\x3a\xac\xd6\x2b\xc0\xd5\xa7\xb4\xca\xca\x7c\xc5\x8b\xb2\x22\xfd\x7e\xe6\x1c\x50\xeb\x36\xae\x3a\x04\x3c\x38\xda\xbb\x6f\x73\xb8\xa5\x8f\x0f\xd1\x16\xdf\x5d\x3c\x68\x72\x90\x8c\x78\x6b\xe9\x19\x95\xce\x9d\x68\x56\xd2\x1f\x92\xef\x77\x66\xea\x37\xc2\x3b\xb2\x59\xfa\x29\xbf\x48\x79\x51\xba\xbe\x52\x5c\xbd\xf6\xd4\x7b\x36\xbf\xa0\x1e\xf6\xde\x95\xf9\x9c\x32\xee\x61\xef\x9b\xbc\xa4\x8b\xe2\xda\x9b\x61\x4e\xa2\x31\xb7\xe1\xc7\xb8\x00\x72\xbe\x08\x98\xef\x9b\x76\xc3\x75\x45\xcb\xc7\x17\x94\xd9\x70\x3f\x10\xfb\xe8\x8c\x44\x9a\xbc\x1a\xc4\x8f\xb6\x8a\x45\x2d\x04\x99\x54\x6e\x9e\xbe\x2f\x8b\xab\xbc\xa2\x1d\x51\x67\xed\x8e\x71\x35\xd2\x9b\x4d\xc0\x09\x78\x1c\x73\xab\x1b\xd7\x41\x1d\x8f\x82\x41\x7d\x2b\x15\xde\x68\xbb\xed\xe0\xdb\xef\xee\xa8\xa2\xfc\x5d\x7e\x45\x8b\x35\xdf\xd1\x2a\x2e\x45\xbb\x3b\x39\xa9\xee\x0d\x79\xbb\x6d\x1d\x2c\xf6\xec\x4a\xcd\xd9\x15\x4b\x47\xd0\xc5\x1c\x7c\xe9\x2a\x88\x4e\x67\xea\xac\xa2\x61\xf1\x99\xd1\xf2\xa9\x7e\x27\xae\x18\xac\x1f\x73\xfa\xb9\xcb\xe5\x04\xc4\xcf\xb1\x1e\x95\xd9\x94\xcf\x12\xe6\xb8\x0c\x73\x5c\xc5\x7c\xf7\xee\xe5\x0b\x19\xc5\x40\xf4\xfd\x2a\xbd\x12\x4c\x60\xfd\xb5\x38\x0d\x2f\x8b\xca\x89\x29\x97\xa9\x83\xb6\x6f\xce\x55\xf3\x7e\xfd\xbc\x98\xdf\x68\x8f\xed\xb6\x45\xe5\xba\x1d\xba\x4a\xe0\xe7\xd7\xaf\x9f\xfe\xe2\x25\x86\x4c\xd6\x27\x07\x8d\x40\xb1\xff\xa3\x1b\x76\xca\x8a\xdc\xad\x12\xc3\xb4\x67\x74\x6d\x18\x00\x7a\x1d\xfd\xf1\x33\xc8\xb7\xfa\xeb\x17\x05\x8e\x47\x81\xe0\xce\x37\x55\x56\x16\xcb\xe5\x46\xe4\x2e\xd3\x1b\xa4\x8f\xd1\x41\x31\x28\xd1\x84\x26\x59\x50\x81\x87\x1f\xeb\xdf\xab\xc9\x34\x97\x74\x41\x4b\xca\x32\x2a\x60\x34\x69\x7c\x27\x74\x2b\x3d\x38\x31\xdf\xef\x07\x7d\x85\xc1\x2f\xdf\x3e\x67\xab\x35\x7f\x49\xf9\x65\x31\x37\x1c\x74\xdf\x00\x4f\xff\x78\x09\x41\x2a\x56\xa2\xf2\xa3\x97\x6f\x9f\x3f\xeb\xc5\x91\x1e\x5f\x7b\x33\x3a\x8c\xfd\xc2\x19\x63\x1c\x8b\x35\x9d\xac\x93\x18\xe2\xb0\x4c\x56\xc9\x7a\xb3\x59\x39\xce\x0c\x76\xaf\x61\xc3\x0b\xd3\xd8\xb2\xde\x8b\x20\x8e\xd0\xa4\xb6\xd8\x52\x51\x08\x08\xba\x58\x54\x94\x7f\x0f\x78\xb3\xd9\x80\xf7\x18\x46\xc0\x99\x3a\x0d\x19\xbd\xd6\xcd\xbd\xcd\xcf\x97\x39\xbb\x18\x23\x46\x02\x4a\xba\xb2\x50\xad\x29\xcd\x38\xf8\x3e\x33\xf8\xe4\x68\xed\x24\x26\xc9\x38\x84\x12\xc1\x20\x06\xe4\x50\x6c\xa7\xa9\xf7\xee\x3b\x41\xef\x9e\x8a\x7f\x1e\x7f\xfd\xe2\x99\xe3\xa3\xc4\x36\x26\x3d\xd3\xa5\x3c\x87\x60\x34\x69\xc0\xb0\xa7\x2d\x4a\x3c\x34\x99\x0b\xf6\x8c\x25\x62\x85\x1b\x3b\xb0\x0e\xa5\x64\x17\xf8\x1c\x07\x10\xae\xc3\x29\xed\xb1\xc6\xee\xb3\x89\xd8\x31\x4e\x94\x92\xc4\xb9\xdd\x3d\xb7\x97\xa8\x74\xb3\xe9\x5b\x3a\xb1\xd9\xf4\x05\x0a\xf1\x26\xe1\xd8\xbd\x9a\x9a\x9e\x64\xc5\x95\xe8\x4c\xcf\xe7\x7b\x35\xe5\x80\x23\x1f\xbc\x41\x3c\x7d\xfd\xe4\x87\x97\xcf\x5e\xbd\xfb\xf0\xfd\xeb\xb7\xcf\xdf\x3d\x7f\xfd\xea\xc3\x37\xaf\x5f\xbc\x78\xfd\xd3\xf3\x57\xdf\x0a\x26\x7d\x42\x13\x2e\xc4\x93\x09\x4f\x28\xce\x9b\x51\xaa\xde\xa4\xec\x82\x06\x68\x9c\x0b\x51\xf6\x2d\x4f\x4b\x1e\x94\x38\x42\x18\xbe\x9f\xb1\x79\x50\xe0\x48\xc7\x7a\xcd\xc5\x50\xae\x0a\xf6\x98\x65\xb4\xe2\x45\xf9\x44\x07\x7c\x07\x7d\xbd\x8c\x87\xcc\xc5\x9f\xcd\xa6\x0c\x55\x34\xf8\xca\x89\x10\xd1\xe5\x68\xbe\x81\x28\x06\x49\xc0\xb3\xbf\xa6\x78\x7c\xb3\x99\x07\xca\xd1\x88\x82\x8e\xf4\x37\x22\x36\x0c\xda\x06\x29\x9a\xa4\xc9\x3c\x48\xe5\x40\x2b\x72\x69\xbd\xfa\xf5\x2a\x20\x89\x93\xf3\x40\xfe\x10\x8c\xb7\x58\xa3\xcb\x80\x23\x48\x70\x7d\x4d\xfc\x8f\xd5\x46\x1e\x2f\x56\x1e\x66\x04\xfe\xca\xbb\x7c\x49\xbe\xde\x15\x2b\x2f\x51\xbf\x5f\xd0\x05\xf7\xe0\xf6\xd0\x4c\x5e\xc8\x42\x30\x73\x42\x48\xb9\xd9\x98\x89\x6b\x3e\xb3\x7d\xaa\xd4\x71\x05\x62\x76\xd7\x4b\xc8\xbe\x72\x76\xa1\x8a\x6c\x36\x3a\x00\x5e\x2f\x9f\xb2\xd9\xd6\x89\x26\xe9\xd8\x7c\xfc\xa5\x10\xa4\xbe\xef\x7e\xe1\x92\x5c\x09\x79\x46\x80\x40\x08\x10\xf0\x01\x71\x3c\xc0\x16\x06\x02\x40\x5b\xb6\x9b\x17\xab\x01\x29\xbf\xca\xb1\x38\x2e\x38\x2f\xae\xf4\x97\xa8\x31\x20\x05\xfc\x06\x0b\x41\xf5\xe1\x98\x9b\xd4\xfc\x57\x5d\x2b\x78\x03\x74\x13\x4f\x00\x1c\x97\x44\x7e\x82\x1c\xe7\xbd\x91\x01\x43\xbc\xaf\xa1\x1f\x13\xb3\xdb\x89\x6a\x42\xa7\x9e\x34\xdb\xf3\x06\x6c\xe0\xfd\x94\xcf\xf9\xa5\x37\x43\x83\xee\x12\xa5\x2d\xe1\x18\x77\x58\x01\x41\x6b\x49\x53\x7e\x19\x5e\xa5\xd7\x01\x9f\x7a\x92\x5a\x7a\x03\x2a\xd8\x61\x85\x0d\xf0\xc5\xa6\x5e\x06\xce\x1c\xf5\x97\x53\x92\xd5\x4a\x4a\xc2\x6e\x5c\x46\xd6\x8a\xaa\x91\x8a\xf4\x72\xea\x49\x83\x3c\x6f\x10\x78\xdf\x49\x5f\x54\x70\xba\x78\x12\x13\x01\x2c\xe8\x61\x35\x14\xbc\x12\x05\x40\x34\x43\x89\x6b\xf5\xf3\xc9\xdd\xce\xe2\xa0\x81\x33\xa6\x89\xa0\xa5\x3c\x92\x7c\xbf\xc5\x03\x31\x13\xea\x41\x5d\x68\xdd\x98\xfe\x15\x28\xd5\xa5\xd7\x4d\xa0\x00\xae\x92\xa5\xfd\xc8\x63\xf2\xaf\x34\x5f\xc1\x1f\x48\xb7\xd9\x8c\xd4\x92\x59\x75\xc8\x98\x9d\xf2\x5a\x48\x60\x37\x82\x6e\x68\xe5\x37\xe2\x7e\x6c\x36\xfd\x18\x03\xa9\x34\xd2\x9e\xe0\x6e\x3d\x10\xf0\xbc\x5c\x5d\x76\x85\x5a\xce\x83\x3b\xf0\x5d\x46\x4c\x65\xf8\x91\xde\x00\x54\x9a\xd4\xb6\x8e\x8f\xcc\xf7\x69\x87\x75\x05\x95\xd6\x15\x1c\xe4\xdd\xcf\xa4\x29\x24\x69\x06\x15\x64\xdd\xc9\xae\x31\x68\x1f\xc7\x09\xab\x49\xac\x11\x6e\xca\xb3\x5d\x92\x2b\xa6\x5b\xfc\xc7\xbf\xbf\x62\xd1\x32\x71\xaf\x1d\x2e\xe1\x0f\xb0\xf3\xc1\xb7\xd2\x96\x59\x51\x2f\x2a\x1d\xb2\x62\x65\x22\x2d\x89\x1d\x55\x9e\x59\xdd\xd0\xa9\xef\x9c\x90\x52\x52\x9f\x91\x2f\x02\xd8\x2f\x42\xa6\xd9\xed\xf3\x55\xce\xf6\x2a\xa0\x9a\xda\x96\xf2\x43\x52\xdb\x31\x97\xd4\x95\x61\xae\xa8\x69\x89\xb9\xa1\xb2\x22\x55\xd1\xd5\x52\x05\x8e\xdd\xdd\x93\xd2\x8b\xcc\xd1\xed\x56\x9e\x47\xb7\x60\xe8\x2d\xdb\xc5\xbc\x58\x25\xd0\x97\x76\x39\x2d\x1b\x1e\xaa\x6c\xb5\xad\x75\xd7\x43\x28\xba\xc5\x39\xe9\x92\x68\x3e\x05\x8d\x83\x0c\x25\xb7\x5b\x5c\x91\x5c\xc2\x52\x88\x38\x92\x52\xfe\x24\x3f\x0b\x05\xe3\x8c\xe4\x0a\xb0\xb6\xc8\x77\xea\xbb\x50\x39\x78\x69\x98\x5f\xa8\x3d\xac\xf0\xda\xa4\xc8\xc2\xc3\x4c\x9c\xc5\xcb\xcd\xc6\xb8\xd6\x13\x92\xcb\x78\x39\x24\x17\xc1\x0a\x7b\xd7\x1e\xc2\x6b\xf5\xfb\x46\x9c\x6e\xb2\xf7\x21\x59\x62\xdd\xc9\x90\xac\x35\xb2\xbc\x0e\x0a\x67\x91\xaf\xff\x9e\xb3\x15\xd0\x02\x17\x16\x78\xdc\x00\x0f\xe7\xe4\x9d\x0c\xac\xf4\x2e\xe0\x08\x2f\x89\x10\xff\xf0\x9a\xa4\xe2\x6b\xe5\x86\xef\x5a\x87\xf2\x14\x7b\x57\xac\x00\x12\x08\xcf\xbb\xb2\xc5\x29\x21\xf3\xc7\x4c\x46\x6c\xab\xc4\xda\x11\x73\xa6\xc1\xa7\x60\x17\x2b\x58\x6a\x37\x03\x96\x3e\x52\x4a\xf2\x4b\xf2\x3a\xb8\x15\x68\x92\x8b\x0a\x43\xa8\x36\x5c\x61\x40\xa2\x1c\x8a\x0e\x65\x8d\xe1\x5c\x7b\x13\x56\xeb\xaa\x90\x27\x37\xbb\x46\xac\x8f\xe8\x43\x1c\x55\xef\x8a\x15\x89\xb0\xfe\x12\xa3\x25\x11\xee\x97\xbe\xaf\x9c\xe8\x9d\xd7\x27\x65\x2a\x21\x7c\xd5\x95\x23\x1a\x40\xe3\x4b\x18\x1c\x59\x0d\xcf\xf1\xa5\x46\x59\xf5\x05\x23\x24\xf3\xe1\x15\xbe\x54\x28\xae\x3e\xec\x70\xce\xeb\xc3\xb9\x52\xb8\x10\x94\xbe\xdf\x67\x13\x6e\xd9\xe2\x25\x4a\x38\x21\x64\xe9\x08\x46\x4b\x57\xd2\x09\x2e\xc9\xcb\xe0\x12\x73\x84\xf0\xa5\x45\xa2\x57\x7f\x81\x45\x75\x51\x28\x9e\xe1\x0e\x15\x45\xeb\xac\xbe\x06\x27\xaa\xb8\xb0\x0b\xca\xdc\x6d\xa7\x15\x3d\x60\xf5\xaa\x36\xa2\x90\x19\xda\xc5\xe5\xae\xaa\x95\xd7\xbb\x32\x42\x38\x25\x7c\x12\x25\x57\x01\x13\x38\xab\x7e\x1a\x5e\x31\x23\x80\x31\xe9\xb0\x04\x32\x56\x5a\x20\x4b\xbc\xa9\x86\xa5\x24\x6b\xa5\x03\x70\x85\x3d\x85\xc1\x1b\x13\x77\xef\x75\x90\x39\x9b\xf1\x45\xa7\x0c\xe2\xb2\xe1\xdc\x61\xc3\xb9\xd5\x17\x83\x41\x78\x7e\x4d\xe7\x52\x04\xa5\xae\x08\xaa\x4b\x45\x8a\x30\x57\x56\x0c\xe9\xf7\x99\xef\xbf\x08\x98\x33\x84\x67\x46\xae\x07\x39\x51\xca\x93\x86\x59\x5f\x04\xe8\x4f\x88\xfb\x8d\xea\x63\xae\x9d\x85\xc2\x20\x05\x33\x6e\x83\xaf\x8d\x11\x27\xbc\x51\x5e\x1f\xef\x9b\xcd\xfd\xc2\xf1\xdb\x86\x0e\xbc\x8d\x88\xfb\x9d\x88\xb8\x5f\x43\xc4\xfd\x19\xce\xe5\x02\x47\x72\x39\xa3\x2d\x4e\x49\x31\x11\x50\x01\x01\x6d\x19\x70\x04\x9b\xdd\xfb\x94\xd3\xcf\xab\xa2\xe4\x52\x20\xca\xc9\xab\x20\xc5\x85\x13\xa4\x56\x5b\x34\x8c\x15\x9f\x2c\xb5\x11\x50\x7a\x62\x96\x33\x00\x1f\xdd\xa0\xaf\x36\xeb\xed\xfb\xc1\xfa\xbe\xcd\x80\x92\x35\xf1\x24\xfa\xca\x16\xef\xd3\x2e\x94\x63\x79\x6e\x5c\x07\x6b\x0c\xe3\x14\x53\xd0\xea\x8e\xb5\xe9\x7b\xb3\x79\x11\xa4\x08\xe5\x64\x65\x27\xb2\x20\xed\xd3\x0f\xcf\xc9\x42\x1f\x5f\x97\x64\x21\xa9\xe2\x38\x97\x27\xfb\x4a\xd2\x51\x67\x67\xe4\x8a\x62\x91\xf9\x00\x32\x71\xae\x8e\xfe\x95\x24\x5e\x2b\x77\xaf\xe4\x92\x88\x91\xcb\x81\xcc\x95\x0c\xf5\x15\xf1\xd8\xfa\xea\x9c\x96\xce\x35\x06\x23\x4c\x6c\x58\x23\x40\xaa\x46\xaf\x26\x2c\x61\xf0\x7b\xb3\x89\xb0\x1a\x94\x4c\xe4\xc5\x4a\xa6\x29\x3a\x29\x53\x4b\xb5\xf5\xcd\x38\x75\x86\xfc\x82\x1c\x8b\x69\x4f\x6a\x6e\x38\x61\xe6\x5f\x19\xf6\xc9\x94\xfa\xa8\xf1\x11\x1b\xd7\xa9\x2d\x8c\x3c\xe8\xc4\xc8\x03\x57\x7a\x3f\x98\x25\x91\x58\xab\x21\xa8\xe3\xac\xf3\xff\x74\xcd\x0b\xcf\x09\x72\x29\x55\x21\x6f\x05\x8b\x88\x73\x70\x16\x2f\xd1\xf8\x56\x52\x9e\xb4\x7e\x6e\x01\xaf\x33\x4c\x25\xc7\x23\x99\x43\x53\x50\x33\x49\xf2\xd5\xbe\x76\x9e\xaf\xe7\xa7\xb9\xc6\xee\x76\x53\xcb\x4c\xc9\x1f\x5b\xb9\x8b\x6e\x35\x07\x06\xab\x9d\xd6\x18\x30\xd3\xf4\x16\x67\xc4\x35\x97\xa8\x76\x47\xee\xfb\x23\x00\xc3\x72\xba\xc5\xd5\x94\xce\xf0\x6d\x5a\xd2\x34\x79\x12\x88\x0f\x04\x96\x37\x61\x55\x94\x7c\x57\xdc\xee\x50\x14\x1f\x52\xf8\xb3\x45\xc0\x91\x74\x3a\x72\xd6\x44\x4c\x4e\xb1\x24\x7a\x91\x0d\x5d\x3a\x23\xb5\xf3\xc7\xf7\x4b\x9b\xf2\x9d\x62\x0c\x04\xa7\xb3\x34\x06\x1f\x93\xe5\x34\x9a\x89\xe9\x25\x99\xfa\x81\x57\x84\x3a\x41\x53\xa7\xb1\xb9\xa1\x5e\x0f\x82\xd5\xc4\x1b\x7a\x83\x55\xe2\x79\x0e\x85\xfe\x5d\x4b\x3f\x52\x96\x6b\x61\xd5\x5e\x27\x56\xed\xb9\x58\xb5\x27\xbd\x73\xe3\x82\x94\x93\x67\x01\xe8\x9e\x38\x5e\x06\xcc\xba\xca\xbe\x0e\x18\x2e\x84\xdc\x66\xba\xfd\xc9\x05\xc9\x9f\xb9\x4c\x40\x98\xb9\x6c\x0d\xb7\x74\x41\x6c\xde\x41\x47\xd6\xd7\x7a\xdb\x09\xd1\xa1\x23\xff\x85\xdc\xda\x9d\x75\xdf\xe8\x63\x5c\x8b\xef\x12\xf5\x6a\x1c\xf6\xa0\xd4\xc8\x57\x67\xb3\x07\xcc\xf1\x80\xfe\xd4\x91\x7e\x00\x89\x55\x68\x57\xb5\x5f\x24\x3f\xa0\xb7\x83\xd4\xb0\x89\x0d\xe7\xc9\x14\xcf\x46\xd6\x35\xaf\x9b\x1e\x01\x49\x92\xc4\x46\x51\x16\x5e\xac\x1e\x5d\xe0\x2e\x14\xe7\x53\x3a\xab\xb9\x9c\xfd\x5a\x2f\x3b\x23\xcc\x45\x98\x68\xa6\x34\xdc\x62\x81\x70\x41\xd4\x84\xcb\xfa\xce\x2c\xcd\x06\xce\x89\xd2\x6d\xab\xe9\xc8\x89\x38\x8a\x6d\xc1\x00\xe5\x13\x98\x91\x9e\x65\x25\x12\x64\xd0\x5b\x39\xd3\x4c\x24\xc8\x16\xbd\xc4\xfb\x2c\xf5\x1f\x4b\x91\x28\x7f\x27\x3a\x53\x43\xa1\x98\xa6\x33\xc2\xa7\xe9\x6c\xc0\xa7\xd9\xec\xd1\x68\x58\xc2\x1f\x5c\x4c\xab\x19\x61\x84\x90\x6a\xc2\xa7\xd5\x6c\x58\x4e\x97\xb3\x84\x4f\x9f\x06\x15\x9a\xe1\xc2\xce\xfe\xfb\xda\x16\x6e\xde\xd1\x2f\x72\x36\x9f\xc8\x3f\x32\xcc\xbe\xda\xce\x5c\x80\xc7\x36\xf2\x73\x5d\x6f\x10\x38\xd6\x73\x34\xd1\x81\x8b\xa2\xd6\x55\x6c\xbe\x08\xba\x3a\x7c\x2e\x00\xe6\x84\x25\xd6\x49\xdd\xde\xe0\xa7\x7c\x26\x3a\xb2\xf6\x39\x62\x46\xf7\x95\x34\x8d\xeb\xc5\x29\x21\x90\x86\xc7\xd2\x2b\xea\x61\x26\xb8\x86\xce\x90\xeb\x34\xd4\x5f\x36\x60\xc1\xe7\xb4\x64\x81\xf7\xeb\x55\x31\xcf\x17\x39\x2d\x4d\x89\x5f\x7b\x79\xd5\x9b\xd3\x55\x49\xb3\x94\xd3\x39\xee\xad\x2b\xda\x73\x8a\xb1\x5f\xfb\x1e\x32\x5a\x7f\x5d\x4b\x88\xb3\x0b\x36\xa6\x21\x65\xe9\xf9\x92\xce\x7d\x3f\x0f\x18\xd8\xe5\xa8\x1d\x55\x85\xab\x62\xb5\xa2\x25\x79\xdd\x4a\x42\xd8\xa6\x98\x5b\xaf\x5a\x39\x93\x8a\x30\x27\x2c\xe0\x98\xca\x00\xe4\xce\xf9\xfa\x9b\x7c\x0a\xd7\xd7\x71\x4c\x39\x0d\xf3\xea\x29\xad\x78\x59\xdc\xd0\xb9\xb1\xc3\xd0\x0a\xb7\x04\x0c\xae\x1c\x4f\xe9\x65\x59\x7c\x7e\xdb\xed\x38\x1d\xc2\x64\xaf\x28\x18\xb6\xab\x11\x25\xb7\xdb\xed\x98\x76\x8c\xfa\xf7\xc0\x0e\x40\x3e\x26\x93\x73\x94\xbf\x4d\x39\xf9\x59\xac\xc0\x6c\x3b\xd4\xbc\xf9\x37\x82\x63\x07\xcb\x29\x6d\xc6\x4f\x3e\x06\xf5\x92\x3a\x03\x77\x74\xfe\xe0\xfe\xf4\x62\x56\x10\x3b\x3b\x3c\x2f\xd6\x6c\x9e\x96\x39\xad\xb4\x68\x75\x57\x69\xf5\xa4\x5b\x0c\x53\x3a\x24\x4b\x97\xdf\x9b\xe1\xd2\xda\x08\x6b\xf3\x22\xbb\xa7\xec\x4c\x46\x21\xc9\xd7\x81\x3b\x97\xae\xb9\x3a\x3d\xa1\x56\x7d\xd3\xfc\x1d\x9d\x4e\x94\x80\x94\x78\xfa\x2d\xba\x87\x29\xf9\x59\x76\x6c\xe6\x6c\xde\x04\x6a\x94\x7a\x02\xf7\x51\xf3\x49\xad\xe1\x82\xfd\xb0\x9a\xa7\x5c\x1c\x6e\x49\xd0\x55\x9c\xf4\x23\xdc\xa8\x21\x73\xe0\x52\xd8\x62\xf1\x9b\x1a\x59\xa3\x61\x55\x5c\xd1\x36\x13\xc2\x54\x84\x67\x4b\x0f\xcc\xae\x63\x2a\x7c\x84\x6d\xf2\x79\x5d\x29\x39\xed\xc7\xd8\xbb\xaa\x3c\xec\xfd\x04\xbe\x1c\x3c\xec\xbd\x2c\xfe\xf0\xb0\xf7\xda\x93\x42\x77\x76\x99\x96\x8f\x79\x10\xa1\xba\x7f\xf8\x01\x35\x21\xb9\xf5\x53\x45\xad\xd2\x2c\xb5\x4a\xb3\x20\x7c\x5a\x0a\x89\xa9\x98\x78\xde\xa0\x18\xb0\x44\x0a\xab\x77\x59\x9f\x80\x2e\x5e\x1a\xc2\x4e\x73\x13\x10\x2c\xdf\x3a\xf7\x9a\x76\x2e\xdf\x59\x8b\xb3\xee\x7d\x2e\x1f\x5a\x35\x96\xd0\x03\x13\xcb\xb7\x32\x56\xb9\x20\x49\x16\xb5\x5a\xce\xfb\xbd\xeb\xa1\xc1\x2b\x0f\xb9\x3b\x4a\x8e\xd1\x62\x96\xe7\x75\xe4\xf2\x62\xd5\x9d\x01\x7a\xa7\xce\x1c\x29\xdc\x74\x66\x29\x21\xa9\x33\xef\x73\xbe\x5c\x3e\xb9\x4c\xd9\x05\xed\xcc\x9f\x3e\x0f\x5c\x69\x7a\x46\x3c\x3d\x9b\x79\x0e\xcf\x7b\x9e\x7d\xa2\x8c\xbf\xc8\x2b\x4e\x19\x2d\xab\x00\xd5\xd1\x53\x82\xe5\x35\x53\x80\xf5\x7d\xb7\x03\xc7\xc5\xbf\x1b\xd8\xc2\x29\x22\x5b\xb3\xeb\xf6\xcd\x4e\x5e\xd1\xda\x94\xd4\xd8\xc6\x44\xca\xb2\xb6\x85\x1f\xac\x38\xcf\xc2\x35\x6c\x36\xd0\x00\x93\x12\x8b\xc6\xc3\x74\x3e\xaf\xcd\x28\xf0\x4a\x5a\xe5\x7f\x88\x53\xd1\x2d\x8e\x6f\x57\x69\x55\xe5\x9f\xa4\x4a\x5f\x59\x14\x65\xce\x3d\xac\x73\x77\xd2\x90\xd6\xac\xca\xc5\x6a\x32\x05\x63\xc4\x77\x33\xbf\x09\x1f\xa7\xed\x91\x89\x56\x6b\xc3\xc0\xf9\x66\x43\x83\x2c\x48\xdd\xdb\x7a\xd5\x39\x2e\x64\x20\xa2\x14\x6d\x83\x02\xeb\x2b\xb6\xc6\xa4\x58\xe8\xaa\x14\x2a\x64\x12\x14\x3d\x27\x05\x66\x21\x15\x83\xa8\x9e\x49\x42\x21\xf6\x89\x63\xbf\xf3\xa3\x7e\xb0\x2b\x37\x54\xad\xe8\x66\xe3\x50\x34\xf2\x43\x70\xc7\xc1\x82\x9b\x67\x5f\x95\x5d\xd2\xf9\x7a\x49\x25\x75\x74\xa9\xd2\x2f\xda\x34\x12\xf3\xf1\xae\x9e\x7d\x3f\xc8\xc4\x59\xbd\x7c\xac\xdd\xa6\x7d\x53\xa6\x57\xea\xf1\x73\xa3\x69\xa7\x6b\x12\xc8\x37\xd7\xee\x20\x89\x33\x32\xc0\x17\x89\xb8\x3b\x50\x86\xbb\xd0\x15\xdc\x49\x0d\xbc\xbb\x58\xac\xce\x26\xf5\x82\xd5\x9b\x04\xde\xa5\x86\xc6\x32\xd6\x4b\xbd\x23\x32\x9d\x99\x24\xbd\x92\xaa\x5c\x63\x31\x63\xcc\x5d\xe0\x7e\xeb\x98\x63\x41\x54\x0e\xdf\xef\xe7\xd5\xab\xf4\x55\xe0\xde\x11\x23\xe4\xfb\x79\xf5\x0d\xb8\x9e\xab\xd9\x90\xfd\x43\x1e\x42\xae\xec\xcd\xbb\x18\x4b\x23\x72\x7a\xde\x58\xc9\x10\x8a\xf3\xd7\xdc\xbe\xbc\xf0\xc1\x46\xb4\x50\xb2\x50\x87\x8c\xe1\xfb\xdf\x06\x7c\xca\x66\x08\xde\xcd\x79\xab\x6b\x08\xad\x22\x49\x19\x9b\xc1\x05\xe5\xa0\xd4\x01\x13\xff\x03\x2c\x99\x94\xb1\xe1\xa3\xfc\x21\xa6\x4c\xff\x55\x17\x92\x77\x32\xdb\x32\x7a\xbe\x3c\x43\x71\x41\xfa\xfd\xd2\xf7\xbb\x8e\xe1\x66\x79\x30\xde\x36\xa7\xb0\x60\x8d\xe6\xb4\x3c\x2d\xe5\xdf\xad\x54\x11\xf6\x2d\x2d\xf9\xd5\x1b\xf0\x81\xf7\xab\x87\x53\xf8\xcd\xc4\xef\x71\x8d\x33\x4f\x07\x5e\x4f\x1f\x61\x82\x23\x57\x8f\xaa\xe7\xbd\xf3\x9b\x9e\x37\xc8\x6b\xb9\xac\x27\x1d\x5a\xf2\xa2\xf7\xb9\x28\x3f\xe2\xde\x39\xed\x55\xeb\x92\x8a\x84\x9c\x65\xcb\xf5\x9c\xf6\x72\xde\x93\x31\x65\x64\xed\xbe\x67\x2e\x0b\x0b\x80\xe9\x7f\x92\x29\x28\x91\x86\x15\x4f\x4b\xb1\x56\xa0\x51\x92\x7f\x86\x94\xcd\xe5\x5a\x9a\x5c\xb9\xae\x22\x45\xe6\x49\x2d\x91\xce\xd5\xeb\x2d\x53\x65\x09\xa5\x09\x72\x3f\x6c\xaa\xae\x08\xfa\x20\x59\x44\x4a\x9a\x32\x45\x66\xcf\xf0\x3f\xc9\x7f\x2a\x2e\x64\xcf\x59\x5b\x4a\xff\x8e\xeb\x86\x7f\x5a\x2b\x54\xc1\xe1\xfc\x53\x75\xc4\x06\xb1\x79\x3c\xfb\x4f\x23\x12\x3a\x9a\x11\x3e\x11\x5c\x04\x78\x67\x09\x50\x52\x4a\x4b\x42\x4a\x3c\xc1\x2c\x7b\x98\x51\xe2\x65\xcb\x22\xfb\xf8\x39\xaf\xa8\x87\x4b\xf1\x29\x9f\x88\xd9\x54\x3b\x93\x82\x36\xb5\xd6\xd3\x08\x47\xb3\x7b\x65\xf4\x52\xc8\xe8\x5a\x6d\xf4\x28\x78\x3f\xd8\xbc\x1f\xa2\x47\xbb\xf5\x65\x34\xe4\x65\x7e\x05\x76\xad\xb8\x22\xa9\x69\xe7\xfb\x20\xed\xda\x16\x43\x69\x4b\x2a\xfd\x02\x04\x8f\xf0\xe6\x7d\xf5\x08\x6c\x62\xc7\xe9\xb4\x9a\xf9\x3e\x28\x23\xc5\x4f\xab\x8f\xc4\x82\xd3\xaa\x8b\x9a\xaf\x25\x8b\xde\xab\xe8\x2a\x2d\x05\x53\x2c\x50\xf9\xf3\x25\x38\xbe\x5c\xa5\x19\x0d\x2a\xd4\x4b\x4b\xda\x92\x3d\xd3\x5e\x56\x5c\x5d\xa5\xbd\x00\x23\xb0\x97\xa0\xe9\x3c\x34\x11\xfe\x1e\xbd\xaf\xbe\xc2\xef\xab\xaf\x36\xef\xab\xc1\x23\xbc\x94\x70\xaa\x26\xd3\xd4\x2c\x55\x65\x96\x6f\x0a\x43\x94\x40\xca\xd0\x34\x9a\xcd\x10\x6e\xa4\xc5\x33\xf3\x9a\x4c\xb7\x50\x0d\x62\x84\x66\xc9\x34\xd5\x8a\xb8\x60\x49\x96\x4d\xc8\xda\x05\x0b\x62\xd0\xbf\xf7\xf3\x24\x47\x6d\x95\x48\x4a\x5c\x63\xfe\xee\x68\x84\x9a\x70\x13\x42\xe8\x54\x5b\x50\x0f\x63\x80\x33\x20\xc1\x00\xc2\xd8\x59\x60\x73\x34\x09\x6a\x25\x09\x17\x1d\x45\x98\xa2\x24\x6d\x64\x0d\x64\x5e\x2c\xf2\xa8\x71\xbb\x83\x64\xac\xc2\x9d\xf8\xb2\xe3\x5d\x01\xa1\x2a\xc8\xdc\xa3\x20\x98\x24\xef\x87\x9b\xf7\x03\x34\x79\x3f\xff\xea\x7d\x28\xfe\x45\x41\xf8\x15\x7a\x84\x70\x4e\x06\x85\xd8\x62\x29\x29\xa6\xa3\x19\x10\xc2\xdc\x2a\xaa\xf3\x45\x00\x2f\x40\x2d\xea\x7c\xe1\x21\x1d\x1d\x52\xdd\x98\x28\xfb\xdf\x54\x99\xfd\x7e\xb1\xf2\x92\x8a\xb0\xf1\x79\x49\xd3\x8f\xd2\xae\xf7\x0b\x65\x06\xfc\x45\xe9\x25\xfa\xbd\x59\x45\x4a\x7b\xc5\x5d\xa1\x29\x9f\x3d\x8a\xa3\xe8\xab\x7c\x0b\xb7\x35\x97\x70\xe9\xb4\xd9\x78\x9f\xe0\xc6\x24\x35\x4a\x20\x9d\x35\x31\xb7\x84\xbb\x2e\x9b\x1e\x72\x79\x98\x3c\xb4\x95\x3b\x6e\x2c\x91\x1a\xb7\x91\x8d\x02\x8a\x0b\x38\xcd\x64\x18\xaa\x4e\xa5\x8f\x7c\xa9\xd5\x71\x68\x8b\xd5\xfb\x56\xea\x66\x8a\x29\x9f\x0d\x08\xfb\x2a\xf0\x86\x12\xdb\xca\x61\x3c\x03\xcb\x37\xa4\x9a\xc6\xf2\x70\xc8\x29\xb9\x35\x62\x91\x51\x69\xe2\x9a\x3c\x9d\x08\xa4\x72\xd9\x92\xa4\x1f\xe1\x86\x1c\x01\x1a\x14\x25\xf9\xba\xcf\xdb\xb7\x58\x4b\xd0\xf5\x54\x23\xc3\x25\xb7\xd5\x65\xbe\xe0\xc9\xad\x74\x57\x17\x47\x11\xa6\xb6\x97\x05\xeb\x30\xcd\x77\x55\x11\x8c\xf0\xba\x8a\x14\xec\xba\xeb\x5a\x76\x70\x5d\x64\xed\x18\x25\xb1\x12\xb2\xac\xc3\x47\xa6\xa4\xd0\x3a\x89\x4a\x93\x64\x73\x94\x89\x23\xb1\xa6\x36\xcd\x48\x55\xd7\x92\x2e\x45\x42\x43\x21\x8a\xd7\xe4\x16\x8e\xb7\xe4\x73\x70\xbb\xc5\x19\xce\xa7\xd9\x0c\x61\xca\xe6\x6e\xc2\x20\x9f\x2e\x67\xc3\x74\xba\x9c\x21\x57\xef\xa4\xb4\x25\x60\xd6\x93\xe2\x75\xdd\x04\x68\xab\x94\x55\x1a\x68\xa3\x3b\x80\xe6\xfa\xdb\x91\xb5\xe0\x7e\xc3\x42\xb0\x09\x13\x05\x85\xb4\x06\x9e\x8a\x94\x0d\x30\xeb\xb7\xf9\x9a\xe6\x65\xe4\xdb\x60\xc0\xd0\x64\x3a\x60\x38\x9a\x25\x05\x0d\x18\xce\x71\x8a\x2b\xa4\xce\x34\xd0\xfc\x06\xea\x8e\x2e\x13\x4d\x28\xc3\x0b\x02\x41\x20\xb5\xd2\x7d\x57\xb1\x81\x2e\xa6\x2c\x5b\xa1\x90\xce\x80\x52\x60\x35\xa1\x0a\xa9\xa5\x13\xe5\x7c\xbf\xa3\xa0\x6a\x0d\x34\x59\x00\xe8\x1c\x53\x03\xd5\x08\x9c\x58\x08\x84\x7f\xad\xbd\x08\x2a\x40\xef\x3d\x10\xd0\x2d\xbd\x9b\xb4\x1f\xd6\x2a\x4a\x2d\x4b\x8f\x9d\x24\xab\x68\x04\x96\x33\x60\x64\x0e\xb7\x34\x92\xab\xad\xcb\xfc\xb0\x66\x8d\xc6\x24\x47\x0d\x2b\xc8\x8b\x15\x2c\x1f\xdc\xbd\x55\xa4\x98\x96\xb3\x71\xa1\x15\x18\x85\x51\x58\x88\x74\xc1\xe0\xcb\xe3\xf6\x6d\x7b\x7c\xb8\x6b\x78\x98\x6b\x3d\x21\x66\x4d\x45\x20\x52\xdd\xe4\xba\x97\x54\x76\x52\x61\x17\x24\x24\x83\x2e\x97\xe0\x00\x2a\x2f\xca\x9c\xdf\x38\x66\x50\x46\x35\xb8\x22\xb7\xca\xcf\x5e\x8b\x04\x30\xb2\x9e\x52\x7b\x7b\x36\xa5\xb3\xd3\x6c\x4a\x67\xbe\xdf\xe7\x21\xad\xb2\x74\x45\x7f\xca\xf9\xe5\x1b\x3d\x64\x80\xa6\xa1\xd6\xa2\x38\xce\x20\x1a\x3d\xfe\x2c\xad\xe6\x18\xda\x62\xe3\xb0\xaf\xa3\x37\x8b\x9a\xb4\xbe\xed\x4b\xb2\x76\x1e\x9a\x8a\x96\xcf\xee\x19\x48\xa9\x06\x92\xb3\x40\x54\x85\x81\x0c\x03\xb7\x83\xb5\xbc\xce\x49\xd6\xea\x1e\x07\xe9\x71\x4a\x93\x53\xdd\xd9\xb2\x5b\x58\x95\x14\x52\x11\x30\xc5\x68\xd7\xc9\x17\x45\x13\x4f\x01\xd6\x4b\x3c\x33\x6d\x6f\xbc\x96\xd4\x66\x8d\x57\x53\x3e\x0b\x94\x1e\xbe\x45\x91\xd6\x62\xa3\xe8\x75\x4b\x4c\x1f\x65\x4d\x2a\x54\xdb\x6f\x86\xb5\x97\xd0\x03\xdc\xda\x12\x49\xdd\x5a\x62\x8b\x3f\x52\xba\x7a\x57\x5c\x50\x7e\x49\x4b\xbd\xe1\xf6\x1f\x74\x1c\x68\xf2\x05\x3e\xc5\x24\xf6\x88\x53\xc0\xe2\x6c\xe1\x52\xbc\x06\x21\x53\x46\x43\x8b\x65\x51\x08\xaa\xa7\x40\x57\x9f\x87\x01\x1e\x5c\xb7\xa7\x13\x35\x5d\x7b\x5e\x66\x22\xb1\x7e\x20\xa4\x3b\x6f\xc8\xd8\xb4\x9a\x9d\xe6\x41\x29\x8e\x03\xdf\x0f\x9a\x20\x9e\x66\x33\xa2\x72\x87\x4c\x9c\x0b\x98\x4d\xb3\xd9\x99\x48\xaa\xee\xac\x50\xcd\xa4\x03\x33\x79\xe5\xa1\x41\x78\xf0\x10\x9a\x05\xbc\xdb\x7f\xb9\x24\xc0\x55\xb2\x8a\xe6\x3c\xec\xb9\x0b\xd4\xb4\x48\x10\xf0\x56\x51\x44\xc7\x9d\x0f\xab\x4b\x65\x19\x5d\x76\x90\xae\x5a\x24\xd0\xa0\x44\xb6\x6d\x69\x18\x0a\x46\x4a\xad\x5a\xc6\x92\xad\x34\xe5\xeb\x62\xc9\x4f\x8f\xdf\xbc\x7a\xfe\xea\xdb\xa4\xf7\x2b\xcc\x40\x8f\xef\xd7\xde\xd5\xba\x12\x32\x73\x0f\xbc\x48\xf4\x8a\x45\x2f\xe7\x55\x4f\xb6\xda\x53\x85\xfa\x1e\xc2\x74\xac\x79\x86\xdd\xb8\x63\x91\xaf\x22\xb9\x46\xbe\x8c\xe4\x0e\xf2\x2d\x1b\xdb\x51\xe2\x4e\x0d\xa7\xd6\x64\xd9\x96\x28\x56\x22\xd1\xb1\x96\xc7\x0b\xb0\xb7\x71\x62\x24\xe3\xb9\x28\xe2\xa2\xdd\xa5\x48\x38\xd7\xf6\xf2\x6a\x53\x9e\x93\x9f\x82\x12\x4d\xd7\xb3\x71\x36\xbd\x9c\x0d\xcf\x4f\xab\xe9\x62\xd6\x85\x47\x8b\xd9\x90\x88\xbc\x61\x20\x0b\x22\x84\xb3\xe9\x62\x36\x38\x3f\xab\xa6\x97\x3b\x6a\x88\x93\x54\x14\x19\x8a\x22\x1d\xf4\xe2\x75\xab\x92\x3c\xd3\xae\x64\xbd\x6c\xba\x9e\x3d\x1a\x0d\xcf\x1f\x8d\xf0\x4b\x92\x76\x9c\x91\xf8\xc2\xb5\x0b\x78\x69\x1f\x09\xac\x66\x08\xdf\x34\xf2\xf4\xd3\x88\x95\x7d\x1a\x81\x3f\x91\xab\x61\xd7\x4c\x2f\x86\x37\x7a\x43\x7e\xb2\xa7\x83\xa1\xce\xd5\x74\x3d\x1b\x9e\xe3\x4f\x08\x47\x62\x56\x80\x41\x5a\x55\xe7\xde\x5b\x41\x06\x09\x3e\x07\x8c\xdc\x6e\xf1\x02\x43\x03\x10\xf8\x2c\xf8\x04\x94\x9b\xe1\x39\xf6\x3c\x84\x99\xd8\x9b\x98\x6a\xe2\x37\xbd\x1e\x42\xd5\x99\x27\x6f\x21\xf5\x76\x3d\xbc\x67\xbb\xe6\x8b\xe0\xcd\x8e\x7d\x0a\xb2\x85\xbb\x31\xf3\x45\x40\x43\x75\xc5\x09\x81\xef\xcd\x6d\x9e\x10\xfa\x5b\x77\x7c\xf5\x1d\xcd\xfe\x0a\x4b\xd0\xc1\xfa\xb4\x98\x84\x3a\xff\xd9\xd8\x51\x05\x79\x1a\x94\x08\x36\x56\x67\x91\x78\xb6\xd9\x78\x42\xda\x9e\xce\xb4\xf0\xc8\xc3\x73\x7a\x99\x7e\xca\x8b\x52\x4a\x91\x3d\x4e\x93\x94\x4c\x4b\x5c\xcc\x1c\x41\xb2\xc7\x44\x2a\xa5\x41\x89\xdc\xd4\x52\xa7\xe2\x7e\xa4\x33\xb4\x98\x99\x12\xdb\xb4\x66\xbe\xd3\x8e\x63\xb7\xc2\x19\xac\x4b\xd9\x27\xa4\xda\x6c\x52\x25\x93\x13\x42\xb2\x41\x6c\x81\x7a\xff\xb4\x15\x5f\xd4\x62\x85\x5c\xee\xc8\x42\x7d\xe5\x1e\x5c\x0b\x62\xb8\xec\xd2\xf7\x57\xc1\x52\xde\x3e\xa1\xb3\x55\xb0\x06\x5e\x0c\x6d\x36\x96\xcb\x50\x45\x20\xfd\x54\x94\x90\x85\x37\x1b\xcd\x5d\xab\x02\x92\x92\xc8\x46\x78\xb1\x12\x05\x2c\x67\xad\xca\x88\x74\x68\x43\x15\xc6\x73\xe2\xb6\x2d\xcd\xf3\x10\xbe\x24\xb5\x41\x29\x53\x3c\x84\xcf\x89\xd3\x08\x98\xed\x81\x71\x74\xad\x73\x66\xda\x7e\x59\x9b\xe6\xbc\x31\xa7\xcb\xda\x04\xce\x9b\xa3\xbd\xc2\x17\xf7\x1c\xef\xa5\x20\x29\xfd\x3e\x87\x4d\xf3\x63\x5a\xe6\xd2\xfb\x9a\xef\x07\x17\xf2\xe9\xa7\x34\x02\xcd\xa1\x6b\x91\x44\xd9\x5c\x25\x5c\x6e\x36\xfd\x66\xa1\x73\x95\x66\x4b\x5d\x09\x7a\xd4\xee\xe0\xeb\x9b\x27\xd2\x85\x55\x47\x4f\x97\xcd\x9e\xe6\x1d\x3d\x5d\xb5\x7a\x3a\x47\xf8\x31\xb9\xd9\x6c\x3e\x8d\x83\xc5\x66\xf3\x72\xb3\x79\x2c\x59\x07\x45\x0e\x48\x3f\xc2\x90\x21\xd5\xf2\xe9\x34\x1b\x08\x79\xe8\x31\xb8\x5e\x68\xeb\x89\x74\xc3\x74\xa2\xba\x4d\x6c\xf7\x74\x02\xb9\x09\xdd\x06\x39\xaa\xdb\x38\x94\x83\x20\x07\xc3\xb6\x3c\xf1\xbc\x8e\xc3\x41\xbe\x5a\x69\xa2\xfb\xd7\x9d\x74\xe7\x6e\x43\x01\x04\x37\xfc\x9d\x74\x91\x62\xa9\xb1\x55\x0c\xed\x16\xeb\x3d\x9d\x28\x4d\xee\x9d\x4c\xaa\x31\xfe\xc5\xf5\x25\x4b\xfa\x31\xde\xb1\x88\x49\x3f\xde\x62\x20\xc6\x9a\xa8\x1f\xb9\x44\x3d\xfe\x6b\x5a\x0d\xcb\x69\x80\x87\x5b\x09\x96\x1c\xbc\x71\x5b\x25\xc6\xdd\x9c\x06\x98\xb9\x83\x4a\x57\xef\x80\xd6\x6d\x8d\x63\xc5\x55\xe3\x2c\x66\x24\x9f\xb2\xd9\x30\xa8\x26\x90\xd3\xe0\x6c\x67\x49\x54\x5f\xf8\xa7\x41\x87\xed\x06\x79\x2d\x78\x1d\xc1\xa0\x5e\xe6\x73\xaa\x61\x73\x7c\x27\x8b\x7f\x17\x5f\x2a\x5a\xf1\xb0\xd7\x90\xd5\x9b\x9c\x29\xef\x24\x9e\x8c\x7c\xdf\xdd\x6a\x87\x92\xb4\xd5\x83\x7c\x31\x94\x5e\xd1\x2d\x42\xce\x81\x27\xce\x5b\x6d\x0e\x7b\xaa\x2c\x90\xa5\x21\xec\x99\xb1\x3c\x06\x7b\xdc\x33\x6b\x6f\xac\xac\x6f\x4f\x15\x99\x84\xf9\xc2\x33\xfc\x50\xcc\xce\xce\x44\x7e\x83\xea\xd7\xf1\xb4\x37\xf5\xae\x87\xc5\x9a\x0f\x8b\xc5\xd0\x0e\x03\x5c\x87\x02\xe3\x0c\xad\xc5\x77\xb4\x16\x3f\xa8\xb5\x7e\xec\xaa\x9e\x32\x69\xf3\x09\x46\x17\x66\x0d\x0f\x1e\xa6\x17\xb9\x06\xb9\xec\xc6\xd5\x39\x59\x4c\xfe\x13\x0b\xe2\x98\x7d\xd4\xd6\xe2\x62\xb5\x7e\x9c\x65\x74\xa9\xfc\x15\x8f\xcd\xfd\x50\xde\xbc\xb2\xb0\xb2\x41\xa3\xce\xaf\x3d\x79\xe5\xdd\xbb\x2a\x3e\xd1\x79\x8f\x17\xbd\x5f\xdd\x19\xff\x6a\x2f\xe7\x52\x36\xef\x7d\xce\x97\xcb\x1e\x2b\xb8\xbc\x97\x03\x67\x32\x74\xde\xcb\x59\x6f\xb1\xe6\xeb\x92\xf6\x3e\xd1\xb2\x12\xb4\x41\x08\x19\xdf\x4b\xb1\xe5\xb7\x4a\x5b\xd9\xa5\xd6\x17\x6e\x3e\xc9\x13\xde\x1c\x3e\xae\x48\x97\xd6\x08\x67\xe4\x5d\x50\x21\xbc\x24\xb7\x26\x9e\x45\x61\x78\xac\x5d\xee\x77\x2c\xf9\x28\x09\xd3\x40\x97\x7e\xc7\xf5\x9e\x50\x92\x30\x30\xaf\x38\x75\xb9\x8b\xaa\xe3\x48\xe8\xd1\xad\x10\x74\x02\xf5\x04\x4d\x8c\x27\x0f\x4a\xfd\xb1\xbe\x87\x14\xd5\x8c\xbc\x56\x44\xdd\x43\x59\xf6\xc8\xdc\x19\x0c\x3d\x84\x17\x84\x4f\xd6\x9b\xcd\x6a\xb3\xc9\xbe\x18\x11\x42\x96\x5f\x8c\x26\x79\x92\x26\x15\x9e\x13\x3e\xc9\x93\x4a\x5b\x00\x83\xf5\xee\x22\x90\xa5\x62\xdf\x5f\xea\x1f\xfd\x95\xef\xf3\x89\x7c\xaf\x33\x8c\x93\x52\x31\x25\xbc\x58\x25\xf3\xa0\x94\x5c\x87\x32\xf0\x15\xdf\x9a\xdd\x90\x06\xc0\x8b\xa0\x54\xdc\xca\x76\x1b\x50\xad\xc9\x9f\xd3\x4f\x79\x46\xbf\xcf\xaf\xe9\xf2\x8d\x58\xae\xd3\xd1\x66\xd3\xff\x0f\x31\x19\x87\xeb\x60\xda\xba\x56\x2b\x0a\x16\x8e\x32\xa9\x34\x14\x56\x09\x6a\x97\x4d\x3d\xdf\xb9\xc2\x10\xe3\xa1\x58\x90\x98\x2b\xb7\x83\xd5\xc4\x3c\x12\xaa\xec\x23\xc6\x61\x55\xbb\xc1\x18\x68\xe6\x2c\x19\x66\x4a\xab\x64\x93\x80\xb3\xc3\xe7\xce\xb8\x16\x77\xb7\x29\x0d\xab\x15\xcf\x28\x5a\xfc\x5c\x4b\x90\xec\x26\x4e\x7d\xff\x12\x2d\xa7\x97\xe0\x80\x58\x05\xa6\xde\x9b\x07\xde\xe0\x7c\xe0\xad\xae\x71\xcf\x1b\x5c\xc9\x1f\x11\xf2\xf0\x72\xba\x9a\x91\x08\x2f\xa7\x0b\xf8\x53\x33\x81\xb2\xf0\xb0\x0f\x55\x5e\xd6\x41\x30\x8c\x93\x18\x5f\xd4\x66\x00\x8f\xfc\xa1\xd9\xab\xaf\x5e\xca\x86\xcf\xbf\xba\xa8\x37\xbd\x1a\x78\x62\x1c\x0b\xb8\x08\xb9\x21\xb7\x35\x0b\xb1\xc4\xc1\x46\xc7\xc2\xdb\x52\x4b\xc9\xbc\xdc\xd4\x28\xa8\xb1\x6c\x50\xb9\x4b\xf3\x6d\x64\xc8\xb7\x4e\x76\x43\x8a\xac\x17\x01\x56\xa5\x41\x11\x04\x71\xbd\xb6\xc8\x74\xa3\x31\x67\x8b\x2d\x45\xd4\x34\xf9\xe4\x7e\xd5\x19\x36\x6e\x44\xff\xd1\xc9\x72\xe9\xa1\xf3\xb6\xce\x06\x0c\x0a\x1d\x97\xaf\x0d\x07\xfd\x9d\xba\xc9\xbe\xd8\xe4\x6c\x4a\x67\x13\x1e\x56\x94\x5b\xd3\x3c\x8a\x45\x2a\x4a\x78\xcb\x68\x8f\x2a\x25\xa4\x2b\x7e\xfb\xbe\xdb\x59\x1d\x66\x4a\xf4\xf2\xfd\x7f\x04\xf5\x4a\x1d\xb0\x2d\xd8\x8b\x22\x9d\x27\xcd\x1b\x50\x6b\x17\xf6\x7b\x50\x60\x8e\x29\x66\x4d\x01\x36\x25\x1f\x03\xe6\xb0\x6b\xb9\x2a\x76\xaf\xf5\x6d\xab\x88\x36\xb9\xb5\x81\x3c\x6a\x80\xa9\x61\x24\x4e\x11\xfe\x47\xc0\xb1\xa5\xfa\xec\x5e\xbb\xd7\x2d\xc2\xac\x8d\x45\xda\xf1\xdf\x16\xa7\x74\x87\x7b\x01\xc7\xa2\x46\x3a\xb0\x7c\xf8\x8b\xe1\xa6\x5b\xb7\xf1\xe3\x7a\x0c\x8e\xba\x7d\x17\x69\xbb\x1c\x2c\xe9\xef\x6b\x5a\xf1\x86\x6d\x58\xa9\xac\xaa\xd0\x56\x36\x23\xbf\x48\x11\x38\x5f\xe0\x60\x10\x12\x50\xdd\xec\x51\xef\xb7\xa7\x52\xb4\xaf\x04\x2c\x1d\xbb\xb2\x5b\xc7\xd0\x54\x30\xe8\xc6\xba\x57\x7c\xd4\x2c\xb7\x92\xe9\x6c\xdb\xb0\xc0\x26\xdc\xf7\x79\xf8\x1b\x28\x31\x27\x7c\x1a\xcd\x12\xee\x5a\x6d\x4a\x7f\x44\x2a\x9b\x89\x6c\xb6\xc3\x0a\x9b\xdc\x6e\x6b\xfb\xa8\x31\x66\x87\x27\x4a\xed\xef\xce\x3b\x62\x8e\x6e\xcb\x76\xfb\x53\x3e\x6b\xc2\xa1\x96\x09\x61\x41\x9c\xa6\x27\x69\x2d\x3b\xb9\xdd\x4a\xf3\xb6\x9a\x0d\x6e\xed\x21\x57\xf7\xbc\xee\x7c\xdd\x25\x58\xb7\x84\x6e\x71\xd7\x78\xe1\x8d\xd7\x9d\x2f\xbc\x94\x39\xd6\x90\x1b\x73\xac\xc6\xf0\x76\x99\xf4\x39\x8f\x19\x68\x28\x29\x01\x02\xeb\x2e\xf8\x19\xb8\x52\x95\x11\xb6\xcc\x10\xb1\x48\x04\xcc\xb1\x00\x91\x08\x18\x68\x0f\x40\x35\x48\xd4\x2e\xcf\xc7\x95\xb2\xb9\x95\x43\xe8\xb6\xd6\xed\xb0\x99\x24\x95\xe6\xc2\x3f\x04\x14\xab\x08\x35\xb2\xd7\x8e\x20\x2d\xaa\xe8\x6f\xd6\x6d\xb0\x0d\xec\x32\x97\xa8\xbe\xbb\xd6\x77\x5d\xb5\xba\x86\xbb\xbb\x89\x1f\x3b\x3b\xee\x32\x50\xde\xdd\xc6\x2f\xb5\x36\x66\x32\xf4\xca\x38\xa5\xe1\x0f\x3c\x5f\x56\xa4\xdb\xfa\x5c\x72\x67\x13\xf9\x27\xa1\x28\x94\x6c\x37\x54\xc1\xa9\x73\xa8\x57\xe4\x3f\xc5\xb7\xde\x09\x24\xa7\x98\x87\x29\x49\x69\xdb\xd7\xf2\xc3\x1c\xa0\xde\xe5\xa7\x12\x17\x6d\x4f\xa4\x75\xbf\x1f\x5d\xbe\x4a\x57\x2a\xef\x79\xf5\xcc\x78\x33\x19\xbb\x0e\x01\x41\x5e\x94\x6e\x73\x09\xdd\x6c\xcc\x2b\x27\xda\xed\x70\xa6\xe6\xdb\xa4\x97\x49\xf7\x33\xe7\x14\x3c\xd0\x50\x21\xcc\xf0\x4b\x30\xcb\xef\x15\x65\xcf\xc2\x16\xd5\x83\xf0\x88\x33\xb9\xc3\x81\x30\xba\x55\x6e\x43\xfa\xb5\x5e\xec\xc3\x75\xf9\x4c\x47\x8c\x48\xb9\x68\xf7\xd2\xf3\xcc\x03\xf3\x49\x3a\x3d\x98\x11\x0f\x84\xf9\x03\xc1\xbe\x75\x42\x52\x30\xa1\x55\x40\xd1\x34\x9a\xd9\x46\xed\xeb\x07\x70\x98\x1e\x8d\xd9\x69\x1c\x81\xff\x1b\x3e\xf5\x3e\x78\x03\xe5\x4c\x71\x51\x16\x57\x4f\x2e\xd3\xf2\x49\x31\xa7\x01\x43\x33\x02\x17\x5e\x5e\x14\x8f\xf6\xf6\x0f\x0e\x8f\x8e\x4f\x04\x02\xdd\xd1\x2b\xdf\x4d\xc2\xd4\xeb\x3d\xe5\x9c\xdc\xbe\xc1\x8f\x15\x56\xdc\x6a\xe6\x51\x4c\x77\x4e\x17\x17\x97\xf9\x6f\x1f\x97\x57\xac\x58\xfd\x5e\x56\xdc\xd3\x6a\x1e\x6f\x07\xcf\x54\x4e\xe9\x8c\x08\xd9\x16\x77\xd7\xb7\xd0\x02\x02\x5c\x83\xbd\x20\xf5\xa5\x33\x34\xe5\x44\xa5\xa8\x3b\x97\x9d\xd4\xea\x34\x04\x77\xe3\x60\x08\x57\x38\x93\x4e\x14\x97\x24\x1e\x2f\xdb\xde\x6f\x96\x83\x81\x2d\xbe\x06\x57\x37\x6a\x64\x81\xe5\x07\x96\x33\x84\x0a\xed\xe1\x66\x0d\x1e\x67\xa7\xeb\x19\x61\xd3\xf5\x0c\x29\x33\x9d\x8a\x94\x01\xb3\x2e\x5d\x57\x24\x1a\xaf\x4e\x4d\x2f\xab\xc1\x00\xe5\xba\x81\x6a\xba\x9a\xc9\x36\xc4\x2f\xd1\x0c\xfc\xb5\x1e\x88\xb2\xfb\x5c\x50\x37\x3c\xa2\x63\xeb\xc5\x9c\x87\xcf\x7e\x7e\xfe\xee\xf9\xab\x6f\xc5\xaf\x57\xef\x9e\xbd\x79\xf6\x54\xff\x52\x89\x3f\x3f\x7f\x07\x69\x3f\xbc\x7a\xf9\xfa\x87\x57\xe2\xb7\x12\xd1\xe4\xba\x37\x94\x58\x0d\xef\xe9\x4d\x15\x95\x0c\xfb\x24\x5d\xfd\x51\x64\xa0\x2e\x3d\xfb\xe6\x8b\xe0\x41\x4e\x83\x28\x66\x48\x33\x6d\x9d\x1e\x92\x0c\xe7\x5c\xc7\x71\xeb\xfd\x76\x72\x4f\x3e\x74\x21\x58\xba\x52\x14\xd9\x6c\x4a\xc1\xae\xee\xf0\xc6\x24\xcd\x09\x13\xae\xdd\x71\x6f\x0d\x8b\xab\x61\x4c\x31\xdf\x06\x2c\x88\xc1\x1e\xbb\x52\x6e\xe8\x73\xf8\x35\xda\x43\x10\x8c\x30\x18\x1d\xa2\x31\x0b\xf6\x5d\xa3\xe0\xea\x4f\x38\xa5\xb7\x8b\xe3\xad\xd9\x15\x98\xe7\xce\xc5\xb2\xab\xd5\xf3\xe8\x75\xae\x53\xf4\xd2\x7a\x94\x71\x0a\x97\xd7\x63\xbb\xf4\x32\xd1\xd6\x95\x05\xaf\x73\x0e\xe5\xa4\x05\x4d\x97\x78\x65\x06\x5d\x3a\x1c\xf5\x58\x07\xee\x92\x47\x8c\xc8\xd8\x6c\xc4\x4f\x79\xdf\x8c\x73\xc2\x64\x00\x15\x60\xed\xbf\x2d\x8b\xf5\x0a\xa7\x24\xf7\xfd\x7e\x1e\xe6\xd5\x4b\x31\x8b\x9c\x5d\x4c\x78\x08\x83\x4a\x78\x98\xae\x56\x34\x35\x61\xbe\x4a\xf5\xfd\x96\xa7\x7c\x5d\xe9\x77\x05\x39\x9b\xa4\x93\xa0\x30\x53\xc6\x8d\x62\x76\xda\x28\x29\xec\x7c\x93\x82\xf0\x50\x81\xee\x35\x7b\x76\x9d\x83\x0e\x53\x7f\x8a\x42\x13\x07\xb2\x89\xd3\xba\xe2\xac\x2b\x68\x3e\x29\x04\x87\xc7\xe8\x35\xd7\x11\xad\xe4\xb8\xca\x2d\x23\x14\x07\x9c\x94\x68\xa7\xef\x79\xe6\xfa\x9e\xe7\x3b\x7c\xcf\x73\xcc\x1d\xdf\xf3\x4c\xe9\xd7\x4a\x5b\x7a\x6c\x2e\xf0\x2e\xa8\x74\xde\xa8\xdc\xaa\xb6\x05\x90\xdb\x06\xf0\xe1\x05\xfd\x56\x4c\xe0\x82\xf2\xa7\xb4\xcc\x3f\xd1\xb9\x80\x1a\xfd\xa6\x2c\xae\x04\xbe\x37\xfd\xe8\x3b\x8f\x79\xc1\x05\xb3\x06\x0f\x3c\x31\x92\x00\x99\x68\xc0\x68\x88\x6d\x65\x2f\x38\x05\x77\x9b\x05\xa3\x8c\x3f\xcd\xe7\xb0\xd8\xb5\x43\xd6\xf2\x9a\x72\xe1\x02\xfd\xfe\xd0\x5d\x4d\xd4\x6c\xa7\x29\x6b\x99\x5b\x07\x70\xbe\xaa\xbc\x67\x4a\xa1\x45\xcc\xc7\x68\x6c\x2d\x2f\x2a\x87\x3b\xb6\x65\x04\x46\x59\xa4\xe9\x83\xd5\x9a\x41\x1b\xf9\x19\xf0\x1a\x5a\xdd\x59\x1a\x3c\x2b\x9b\x2d\x85\xb6\x1d\x13\x8d\x31\xaf\x4f\xec\xa7\x7c\xb9\xfc\x41\x42\xb7\x05\x23\xf9\xbe\xe8\x95\x83\x71\x01\x54\xbe\x30\x9e\x9b\xab\x56\x98\x10\xa9\x00\x70\xe0\x10\x72\x59\xd4\xe8\x7f\x08\x27\x8c\x94\x58\x12\xea\xd2\xf7\xb5\xa7\x12\xcb\x7f\x96\xbe\x1f\x80\x93\xbd\xeb\x9c\x63\x0e\xde\xf6\x38\xa8\x4b\x8c\xac\xac\x37\xde\x44\xff\x48\x38\xc2\xb7\xa2\x7c\x42\xb1\xda\xd2\x58\xe5\x30\x21\xa3\xd7\xc0\xd0\xf6\x36\x68\xb9\x3e\xe8\xba\x1f\x23\x35\x3e\xc2\xef\x80\x85\xba\xe3\xcf\x4d\xb4\x8e\x45\xce\xe6\x4f\x5f\xbf\x7c\x25\x58\x24\x60\xb9\xc7\x76\xbd\xc0\xb3\xa5\x04\x0b\x2d\x17\x45\x79\x05\x3b\x3f\x60\x98\xa2\xa4\x96\x7c\x9d\xf3\x80\x21\xe5\xce\xcd\x82\xb1\x46\x40\xc4\xc2\x4b\x9c\x27\xa4\x8d\x61\x4a\x38\x92\xce\x60\x39\x0d\xcc\x3e\xb1\xdb\x68\x0b\x0b\xe9\x8e\xa4\x53\xe3\x0d\xc4\xb5\xb6\x9a\x72\x29\x0a\x99\x94\xc9\xed\xdf\xa4\xb4\x93\xbb\x32\x1d\xf2\x9b\x70\x9c\xcb\x86\x1c\x8c\x0a\x10\xf8\x10\xca\xf5\xc2\xe6\xb2\xcb\xb1\x38\x2a\x27\x81\x33\x92\x42\xd2\xce\x80\xe2\x42\x4b\x7c\xe9\x82\xbe\x6d\x4d\xda\xac\x40\x3d\xae\x0f\xab\x37\x23\xb8\x69\x68\x89\x85\x05\x7b\x67\x86\xfc\x8c\xcd\x03\x8a\xd3\x46\xcd\x3b\x3a\x12\xb0\xbd\xab\x1f\x3a\x87\x6e\xb6\xda\x86\x5c\x2d\xfe\xff\xb0\x45\x19\x3f\x29\x75\x71\xa8\x83\x50\x49\x69\xac\xb6\x9a\x62\x87\x95\x1d\x6b\x30\x66\x4d\x58\x0b\xb4\xa4\x77\x03\x5a\x11\x9e\xfa\x68\x79\xad\x09\x00\x33\xb8\x34\x68\x01\x59\xed\xf7\x7a\xdd\xdd\x3d\xb5\xc0\x52\xef\xc8\x40\xe5\x01\x50\xfe\x13\xad\x09\xd2\xd9\xa2\x04\x2e\x11\xd4\x64\x43\x74\xe7\x9e\xd5\xfa\x65\xb5\x9b\xa6\x9a\xd2\x0a\x8b\xd6\xd1\x0e\xdd\xb9\x63\x6e\xec\x51\xfd\x70\x93\xf2\x1a\x5d\xe2\x7a\x95\xf4\x4c\xa9\x22\xfa\x8d\x82\xbb\x31\xa4\x6f\x4c\xd2\xdb\x03\x33\x95\x4a\x74\x2b\x8d\xac\xc5\xa1\xd2\xc1\x97\xd0\xa0\x44\x5a\xd1\xd8\x31\xeb\x1a\xd0\x48\x3f\xee\x28\x29\xc6\xdc\xc0\x93\x96\x53\xd3\x4e\x08\x30\x13\xd6\x47\x86\xc3\xf1\xfd\xbe\x83\xcc\xe9\x7c\xfe\x8c\xcd\xb5\xf2\x64\x4c\x7d\xbf\x5f\xa7\x2c\xf5\x02\xfa\x79\x77\x47\x56\x40\xdb\x83\xd6\x27\x07\xf7\x7d\x27\xc2\x41\xab\x18\xe6\x08\x25\x77\x16\x88\x60\xcd\x4a\xca\xe6\xb4\x6c\x47\xe3\x6a\xb3\x15\xd2\x97\x80\xc3\x27\x19\x09\x09\x18\x14\xbb\xc0\x72\x2a\x32\x36\x9a\x8a\x01\x86\x9b\xe4\xdf\xe8\x44\x74\x23\xb7\x5b\x79\xda\x61\x41\xfc\x21\xce\x48\xed\x06\x41\x4a\x9b\xd2\xf5\x41\xee\xba\x3e\x60\x24\x9f\x96\x33\xcc\x1d\xfb\x88\x33\x12\x6d\x36\x41\xa1\x85\x1a\x6b\x2f\xb1\x0d\x38\x9e\x7a\x7a\x4c\x9e\x94\x67\xe7\x74\x49\x39\xed\x95\x61\xce\xb0\xf9\xed\x32\xcf\x36\xb5\x76\x44\xda\x64\x79\x90\xd8\x6f\x5a\xaf\x45\x6b\x85\x15\xb7\xe2\xd4\xae\xad\xb8\x4d\x2f\x9a\xbd\xdb\x83\xa4\x95\x46\xe7\xb5\xa4\x5a\x87\x86\x2e\x36\x93\xe8\x1c\x77\xc5\xed\x61\x66\x55\xe1\x61\xdd\x58\xde\xb3\x98\xc0\x60\xe1\x13\x05\xbe\xb0\x60\xcb\x1b\xd7\x1a\xc5\xc6\x14\x5b\x16\xcc\x04\x41\xcf\x71\x89\xb6\xb8\xdc\x06\x4e\x0b\x9a\x37\x74\x04\xc6\x65\x80\x6e\xb7\x99\x3e\xd3\xdf\xdd\xac\x68\x45\x5a\x3c\x7e\x19\xca\x88\x1c\x5b\x9c\x49\xcc\x7a\x72\x67\x71\xf7\x31\x93\xa8\x22\xd0\x52\x15\x15\x9f\x6a\x38\x52\x38\xb8\xcd\x59\xd2\x8f\xb1\xbb\xee\xe2\xbb\xb6\xe2\x22\x41\x31\x0d\xfd\x58\x71\x81\xfd\x08\x03\x57\xd8\x8f\xb0\x5a\x8b\x64\x89\xed\x4a\xd9\x0f\x3a\x97\xbf\x45\x61\xfd\xc3\x14\x80\xd5\x48\x96\x62\x54\x56\x1a\x8e\x70\xa6\x65\xe0\x58\xfc\xd4\xc2\xef\x48\x7f\x3c\x7b\x4a\xf6\x54\x19\x91\xbe\x3f\x96\x8e\x0e\x83\x48\x1c\xd4\xc5\xf2\x66\x91\x2f\x97\x28\xc8\xd0\xd8\x8a\xf3\x1d\xa1\x72\xee\x51\xb6\x80\xcb\x6b\xd0\xb0\xbd\xbd\x4c\x57\x14\x02\x50\xca\x43\x5c\x7e\xbb\x0a\x95\x71\x00\x21\xa6\x10\xf2\xfd\xd2\x69\x68\xdc\xac\x03\xf4\xa2\xdd\xb4\x14\xae\xfe\xa2\x32\xa8\xa6\xd8\xa9\x3a\x54\x16\xa0\xa7\x00\x7d\xc5\xf1\x5f\xd3\x54\x98\x2a\x99\x91\x42\x83\xec\xdf\xdf\x17\x35\xda\x11\xe3\xce\xd9\x7a\xb4\x21\xa3\x38\x9a\x69\xf3\x2e\x46\xa9\xa7\x45\x2b\xbd\xcb\xb4\x62\x5f\xf2\xde\x39\xa5\xac\x07\xd1\x6a\xd3\x65\x5e\xd1\x79\x6f\xd8\xab\xd6\x2b\x5a\x06\xa8\x56\x42\x6a\xae\xad\x8a\x5a\x07\x53\x51\x13\x83\x9b\x85\xaa\x0e\xb9\x9a\x32\x5b\x9f\x00\xed\x88\xf2\x8e\x8f\x2e\xe0\x9d\x56\x0f\xd7\xef\xe0\x82\x04\xbb\x54\x3c\x28\xbc\x4c\xd9\x7c\x49\xe5\xb6\x94\xf7\x95\x4b\x19\xdf\x12\x59\x05\x8e\xd2\x9d\xb8\x45\x93\x02\x43\xf8\x89\x37\x70\xa6\x26\xfd\x68\xfb\xaf\x55\x9e\xe4\x5d\xca\x93\xfc\x2f\x28\x4f\x6e\x1d\x99\xa9\xef\x68\x2a\xe8\x7c\xbb\xdd\xe2\xfc\x01\xea\x0e\x5d\xde\xb8\x5a\x52\x7c\x02\x11\x40\xc8\x1f\xa6\x0e\x30\x55\xe2\x3f\xa1\xc7\xd1\x66\x6b\x0e\xa7\xc1\x6b\xeb\xa7\xed\x8e\x6c\x38\xd2\xd0\x59\xa4\x09\x50\xcb\x0b\xca\x9f\x4b\x3c\x06\xc0\xbd\x4c\x57\xab\x9c\x5d\x20\x38\x00\x13\x5d\x02\x38\xc0\x46\x36\x44\x1e\xa8\xad\x79\x0c\x00\x73\x07\xd0\x39\x60\xdd\x68\xbd\x41\x87\x11\xd4\xc3\x45\x63\x2a\x36\x00\xd0\x82\xcd\x26\xa0\x0d\xb1\x01\x9e\x0c\xd4\x05\x09\x8e\x6a\x2b\xd0\x14\xd6\x6b\x3b\x48\x0e\x26\x83\x48\xd8\x4e\x97\xda\xa9\xb0\x64\x18\xd8\x14\x86\x30\xc3\x16\x86\x6c\x0b\x41\xb9\x70\x7e\x37\xff\x28\x19\x41\xae\xe2\xd3\x00\x02\x28\x2f\x57\xf9\x72\xfe\x4d\x2a\x10\xfb\xe6\xdf\x85\x35\xa4\x82\x35\xd4\xa3\xf4\xb0\xe7\x8e\xd1\x9b\x89\x13\x64\xed\x3a\x17\x33\xc0\x02\xb2\xd4\x82\xd9\xc3\xb8\x42\x75\x2d\xc8\x27\x79\x52\x34\x42\xb2\x6a\xfe\x89\xe3\x12\xe7\x77\x70\x50\xab\x87\x70\x42\x36\xde\xab\x64\xa0\xc2\xbc\x7a\xa3\x3c\x9a\x6c\xf1\xaa\xce\x18\xad\x1a\x8c\x91\x81\x49\xe2\xcd\xf3\x4f\x1e\x76\xe1\x92\x74\x9a\x1c\xca\xe5\x5a\x08\x1c\xcf\x1d\x46\x64\xe5\x32\x22\x8b\xfb\x03\xcc\xee\xb8\xc2\x6d\x3a\x7f\x04\x3f\x11\xb8\x20\x2c\xd8\x3f\x44\x75\xdc\x00\x0f\x51\x1d\x43\xcc\x85\xb0\x9d\xb0\x20\x8e\x62\x84\x6b\xd6\x11\xe3\x34\xac\x2e\xf3\x2b\x17\x9d\x9d\xdc\x49\x0b\xcb\x5d\x44\xb4\x67\xeb\xd8\xe5\x27\xcc\x43\x93\x26\x03\xb0\x0d\x62\x3c\x42\x9b\x8d\x1b\x95\xb8\xcb\x86\xb3\x08\x28\x9a\x54\x41\xa9\xc3\xcd\xa1\xa4\x02\x65\x41\xe2\xd6\x4b\xc7\xed\x33\x73\xb3\x49\xb7\x0e\x98\xd3\x3f\x73\x43\xde\x0e\xc6\x39\xee\x8a\x48\xab\xe5\x7a\x33\x38\xcc\x88\x89\x9b\x67\xa2\xa0\x42\xe0\x3c\xa3\xa0\x15\x64\xac\x56\xaa\x4c\x6f\x66\x2a\x9c\x93\x0e\xa4\xe5\xfb\x5e\x61\x42\xb3\xea\xb0\xaf\x56\x95\xeb\x24\x1a\x6b\x32\xfd\xeb\x8c\x44\xbb\x62\xf7\xe9\x51\xc2\x1f\x4a\x11\xc2\xec\xbe\xdb\x47\x17\x28\xb8\x20\xe6\xa2\xbe\x0b\x1a\x86\x74\xf5\x81\xfa\x49\xc2\xdb\x27\xa4\x54\xd6\x4e\x96\xab\x2a\x02\xef\x0d\xbd\x78\x76\xbd\x72\x9d\x98\x2e\xd3\x8b\xaa\x77\x41\x39\xa7\xa5\xbe\xed\x2f\x58\x8f\x15\x6c\xa8\x40\x81\xd4\xfd\xbc\xe7\xd5\xb4\x27\x17\xcb\xe2\x3c\x5d\x0a\xee\x6f\x40\xbc\x0b\xed\x68\x2e\xbf\x60\x45\x49\x9f\xa4\x15\x55\x39\xb9\xce\xb9\x5a\x2f\x79\xbe\xcc\x99\xce\xb8\x32\xbe\xe9\x0a\xfe\x78\xa9\x1b\xaa\x74\xea\x9a\xe5\x59\x31\xd7\x85\xd7\x9e\xb1\x7e\xc9\xb3\x8f\x37\x2a\xf5\xc6\x93\x6f\x06\x1e\x00\x4a\x16\xec\x1f\x41\x24\xe4\x60\xef\x10\x75\x05\xf7\xb4\x5b\x78\xd7\x0d\x27\x4e\x1f\xb0\x0e\xfd\xc2\x81\x77\xba\x13\xde\xca\xb1\x53\xd5\x4b\x7b\xbc\x5c\xd3\xde\xb3\xb7\x07\x3d\xca\x3e\xe5\x65\xc1\x04\xea\xf6\xf8\x65\xca\xb5\xd5\x78\xd5\xd3\xc6\x1e\xbd\xb9\x1d\xaf\x34\x8f\xf0\x2e\x72\x30\x74\x7d\x94\x3e\xba\xc8\xaf\x64\xe3\x9a\x48\xe4\x41\xb3\x73\xec\x41\x01\x65\x59\xe1\xfb\x5d\x72\x38\xc4\x59\xf1\x7d\xef\xbc\x28\x96\x34\x75\x72\x1e\xa5\x8f\xd4\x52\x59\x77\xb7\x17\x94\x6b\x8e\xbf\xfc\x73\x31\x9d\xa5\x39\x25\xce\x71\x2a\xad\x43\xa4\x69\x14\x9d\xe6\xb3\x20\x05\x27\x1a\x92\x41\x57\x76\x09\x4b\x43\x95\x40\x5a\x60\xc1\x12\x6d\x05\xe2\x30\x3a\xe1\x41\x86\x92\x66\x54\xcf\x4c\x85\xf5\x2c\xb1\x1b\xe5\xa4\xe8\x72\x6e\xd3\x50\x11\x1a\x6a\x69\xc8\x06\xfd\xdc\x53\xcd\x3b\x3c\x4c\x81\x73\x59\x31\x25\x54\x0b\x3a\x98\xb5\xe4\xbb\x20\x85\x39\x56\x38\xc3\x1e\xa3\xd7\xdc\xc3\xae\xcb\xb5\xac\x55\x06\x50\x07\x0a\x55\x4a\x2e\x02\xed\xec\x5f\x09\xc3\xdc\x6f\xcd\xf0\x76\xeb\x60\xad\xe0\xeb\xab\xfc\x6a\xb5\xa4\xdf\x80\x97\x64\x97\x19\xb2\x31\x95\x58\xdb\x25\xba\x13\x70\x49\xba\x60\xa3\xca\x25\x0d\x96\xdf\x3b\x1a\x52\xea\x63\xe5\x3a\x48\xfa\x55\x50\x5f\x2d\xdd\x27\x78\xf4\x57\xdc\x97\xe0\xbd\x22\x9c\x93\xe9\x0c\xa7\x44\x3b\x1f\xc5\x15\x89\x70\x46\x22\xbc\x24\x42\x88\xa1\xf0\xee\x73\x0d\x6f\x17\x2a\x0e\x1f\x2b\xc2\xc2\x2c\xad\xe8\x5b\x0a\x0c\xc9\x27\xea\xfb\xea\x85\x8d\xf3\x46\x7a\x4c\xdb\xa5\x20\x50\x69\xbd\x94\x16\x8c\x17\x24\x1a\x2f\x4e\xd3\xf1\x62\x30\x40\x25\xe1\xd3\xc5\x0c\xaf\xa6\x8b\x19\xf8\xd0\x29\x66\x93\xa0\x24\xcb\x41\x39\x58\xe3\x62\x40\x62\x9c\x0d\x48\x3c\xc8\x50\x22\x46\x59\x0d\x48\x86\xf3\xa9\x66\x12\x67\xc4\xdc\xc7\x17\xf0\x44\x45\x26\x4f\x82\x8a\xac\xe0\xcd\x5c\xfc\x28\x4a\x2a\x7c\x2b\x59\x5c\x3a\x4f\x72\x63\xa6\x83\xab\xac\x28\x69\x52\x6d\x91\xba\x12\xe6\x6a\x81\x6a\x50\xaf\x47\xd4\x8a\xfa\x84\x30\xdd\x87\x7e\x7c\x6f\x2f\x25\xe9\x84\x25\x41\x49\x4a\xb0\xf0\x64\x6d\xef\x54\x4c\xef\x52\xb9\x43\x8b\xb1\xe0\x21\x79\x99\x66\xdc\xf7\x83\x8a\x98\xaf\xa0\x40\xda\x3d\x97\x5d\xe5\x0a\x97\x86\x2b\x91\x28\x90\xf9\x7e\xc0\xa6\xcc\x80\xe2\x56\x0e\x28\xc9\x42\x3d\x5d\x35\xc7\x2c\x84\xbf\x18\x98\xe8\x24\xc7\xfa\x49\x72\x52\x80\xe1\xb2\x74\x5d\xd5\x65\xfe\xa9\x25\x33\xa8\x3e\xa4\xf2\xaf\xc3\x04\x28\x3f\xda\x43\xc5\x9f\xc3\x2d\xca\x74\xb6\xdd\x06\xf7\x99\xf2\xb5\x7d\x20\x4a\xd0\x74\x2b\x75\x1a\x46\x3e\x92\x7d\xcc\x2b\x19\x93\x9e\x22\x57\x4d\x13\x61\xe6\xc4\xab\xb7\x11\xed\x6b\xa1\x94\x07\x88\x4d\xb9\x10\x1f\xb8\x71\x2a\xc2\xb6\xdb\x80\xa2\xba\x0a\x23\x5f\x04\xd2\xae\x30\xcc\x39\x2d\x53\x5e\x80\x3a\xc7\x98\xe7\x6d\x36\x3b\xd8\xa4\x7b\xc3\xd8\xa3\x9a\xd7\x75\x08\x39\x4f\x51\xa3\x7f\x21\x50\x77\xd8\x16\x3e\x67\x9f\xd2\x65\x3e\xef\xa5\x9c\xd3\xab\x15\xef\xf1\xa2\x57\xad\x4a\x9a\xce\x81\xcb\x80\x71\x9e\x2f\x6d\x58\x3c\x0f\x89\xb5\x68\x50\x49\xad\xf7\xfa\x2b\x21\xdf\x0d\x28\xba\x98\x72\xbd\x0d\xb6\x9d\x42\x45\xf7\x19\xa9\x3b\xac\xab\x4a\x08\x31\xe9\x7d\xfd\xdb\x02\x74\xa2\x47\x97\x98\x1e\x91\x80\x60\xda\x61\xe5\x5e\x37\xb6\x17\xdb\xd9\x39\xc3\x52\x5c\x49\x4e\x83\x4d\xd3\x99\x72\x7f\xae\x7f\x19\x17\x6b\x79\x90\xc2\xab\x75\xb9\x21\xc5\x7a\xd4\x03\x0b\x2e\x72\x36\xef\x5d\x81\xba\xb1\xf7\xa5\x37\x48\x07\xde\x97\x1e\x1a\xcb\xd5\xcb\x42\xc1\x78\x11\xef\xe5\xeb\xa7\x3f\xbc\x78\xf6\xe1\xd5\xeb\x77\x1f\xbe\x79\xfd\xc3\xab\xa7\x1e\xce\xb6\xf2\x15\xba\xe8\x99\xdc\xaa\xa3\x04\xbc\xa2\x8b\x11\x4c\xa3\x99\x44\x96\xa5\x3e\x65\x3a\xbd\x6d\x16\x01\x14\x8e\x67\x53\x3a\xdb\x6c\x84\x44\x81\x97\xd8\x56\xd1\xce\xe6\x8c\x2f\xe8\x69\x3a\xd3\x99\x5b\xbd\x67\x72\xd2\x8f\x71\x4a\xa2\x71\x7a\x5a\xea\x2d\x92\x0e\x06\xa8\x08\x4a\x01\x0a\x47\xbc\xbe\x8d\x93\x69\xeb\x7c\x09\xcf\x6f\x38\x7d\x21\x05\xa4\xb6\x50\xa1\xe4\x09\xae\x3c\x86\x39\xc1\x38\xf6\xbe\x0a\xd8\xa0\x44\x8f\xf6\x87\xa5\xa0\x95\xbc\xf8\xfa\x86\x53\xd8\x10\x5d\x1a\x40\x5c\xca\xa6\x52\x52\x8a\xa6\x2a\x52\x4e\xe3\x19\x96\xab\x91\x07\xcd\x41\xd9\x2e\xf8\x80\x89\x2e\xd8\x36\x88\xc0\x49\x16\xc2\x6b\x12\xe1\x15\xa9\xce\xa2\x49\x3a\xdc\x4f\x52\x38\x91\xa4\x45\xeb\x6a\xcc\x06\x64\x1f\x71\x52\x4c\xa5\x13\xef\x27\xc5\x9c\x3e\xe6\x01\x43\xb3\xd3\xd3\xf8\x78\xd3\x4c\x1e\xc4\x90\x31\x6a\x67\x8c\x44\xc6\x61\x3b\x7d\x0f\xcd\x70\x36\x5d\x0f\x06\x33\xc2\xcf\xce\xe2\x43\x7f\x74\x70\xe0\x24\x1c\xbb\xdf\xa3\x83\x03\xdf\xc8\x5b\x23\xe5\x61\xab\x7b\x6c\x1d\x23\x88\xd1\xec\xec\x6c\xbf\xd6\x16\xc2\xf1\x9d\xad\xc4\xd1\x8e\x19\xee\x77\x4e\xf0\xec\x6c\x74\xe7\xd0\x11\xce\xc4\xba\x0a\xe2\xd6\xbd\xb2\x86\x66\x83\x3a\x49\x31\x23\x05\x61\x5f\xec\x69\x16\x25\xc2\x15\x61\xc3\x62\x9c\x9e\x56\xe3\x74\x40\xe2\xc3\xbd\xe3\x3d\x94\x4b\x77\xce\x6b\x30\xb9\x48\x07\x90\x78\x56\x4d\xaa\x44\xfd\xb6\xfa\x5d\x31\xdd\x62\x12\x70\x42\xa7\x6c\x18\xcf\xb0\xaa\x59\x4e\xf9\xd9\xd9\x68\x36\x28\xa7\xfc\xf4\x74\xdf\x3f\xdc\x9b\x0d\x3c\x42\x3c\x84\x12\x01\xe5\x02\xe0\x13\x88\x2a\xa3\xd9\xe9\xe9\x31\x1a\x74\xd4\x8e\x23\xa8\x7e\x76\x26\xab\x43\x4b\x23\xd5\x92\x87\x10\xb6\x4c\xc6\xd6\x5e\x05\x88\x39\x15\xe2\x9f\x9c\x74\x5a\xd4\xff\x90\x33\x7e\x0c\x60\x9a\xd8\x9f\x09\xfc\x8b\x53\xe2\x3d\xfe\xfa\xc9\xd3\x67\xdf\x7c\xfb\xdd\xf3\xff\xfc\xc7\x8b\x97\xaf\x5e\x7f\xff\x5f\x6f\xde\xbe\xfb\xe1\xc7\x9f\x7e\xfe\xe5\x9f\x5d\x06\xcb\xeb\x4f\x9f\xaf\x6f\xfe\xb0\x86\xd7\x83\x47\x9e\x62\xf4\xb4\xdb\x8c\x71\x75\x9a\x8d\x07\x83\x0a\x95\xd3\x6a\x06\xbe\x47\x71\x31\x4d\xdd\x65\xae\xd0\x8c\x54\xe3\xfa\x1d\x83\x7e\xe9\xad\xda\xc8\x17\x01\xff\x62\xff\x2c\x72\xe4\xb4\xc6\x39\x25\x59\x92\xb0\x27\x29\x84\x71\x09\x94\xf6\x40\x84\x5d\x2d\x69\xaf\x58\xf4\xf6\x9d\x78\x18\xe6\x45\x2a\x31\xd7\x0d\xf0\x94\x5e\xda\x11\x70\x84\xa7\x0c\x83\x8f\xfe\x49\x94\xec\x0f\xd9\x17\xfb\x4e\x38\x92\xb5\x26\x00\x1a\xe8\xc0\x53\x08\x98\x57\x84\x8f\xab\x53\x36\xae\x06\x64\x0f\x15\x62\x7d\x2b\x81\xf2\x87\x7e\x7c\x78\x14\xc7\x87\xc7\x11\x1a\x88\xb4\x41\x2c\xd6\xdc\x3f\x3c\x18\x41\x8a\x40\x64\x91\x3a\x9a\x21\x9c\xea\xf5\x0f\x72\x52\xa0\xb3\xb3\xf8\x58\xad\x7d\x7e\x76\x16\x8f\xec\xef\x43\xf5\xf3\x70\xcf\xcf\x2d\xf5\x4c\x2d\x46\x14\x53\x6f\xe8\xb9\x70\x8e\xd0\x8c\x1c\x8e\x70\x31\xf5\x3e\xb4\xd3\xf7\xb6\xf8\x76\x3b\xc3\xa3\x36\xe5\x95\x19\x7b\xed\x8c\x96\x76\xb8\x24\x34\xf0\xce\xd3\x8a\x1e\xee\x0f\x7f\xab\xa4\x5f\xbb\xc0\xcb\x29\xa5\x47\x07\xfb\x10\xad\xf9\x4e\x4e\x60\x67\x5e\xb8\x28\xca\x89\xfd\x19\x78\xac\x98\xd3\xdf\xaa\x70\xcd\xf3\x65\x98\xb3\x6a\x05\x17\x24\xeb\x8a\x17\x57\x9e\x64\xb2\xdb\xaf\x2a\xe8\xd9\x28\xde\x3f\xda\x3f\xde\x3b\xdc\x3f\x72\xef\xac\x52\x76\xa1\x58\x9e\x2f\xdf\x5d\xd2\x1e\x08\xb0\x3d\xef\xcb\x01\x1d\x7c\xe9\xf5\xf2\xaa\x97\x2b\xfc\x5a\x14\xa5\x7e\x49\xee\x81\xef\xf1\x2f\x35\x2a\x89\x66\xec\x46\x72\x3c\xd4\x2b\xf6\xac\xa2\xfc\x7b\xcd\x50\xbc\x5e\x04\xcc\xbd\xb6\x41\xae\x6f\x77\xee\x84\xad\xe9\xd0\x5e\xc9\xf4\x96\x23\x2e\xde\xf9\x36\x04\x26\xa3\x0b\xf7\xb4\x80\x6c\xb6\x85\xa8\x77\xb3\xa2\x66\xd7\xbc\xa1\x19\xcd\xe1\x7d\xbc\x48\x95\x7d\x7f\x69\x26\xb2\x16\x3c\x8f\xfa\x5d\xa9\x41\x6e\x5d\x06\x5a\xf2\x3b\x9d\xc3\xa3\xed\x60\xed\x7a\x8a\xad\xb2\xcc\xf7\x3d\x6d\x3c\xca\x88\xb7\xe6\x8b\x63\x0f\xe1\x3e\x0f\xf3\xea\x19\xcb\x8a\x79\xce\x2e\x02\xb6\x23\xf8\xf2\x0f\xec\x23\x2b\x3e\xb3\x1e\x55\x05\x93\x9e\x37\x30\xa6\x37\xd1\xe6\x52\x07\xa0\x4c\xa5\x3b\xa2\x02\x82\x20\xc3\x53\x55\x1b\x85\xae\x0f\x6e\x65\x82\x82\x14\xc6\x27\x71\x0e\x9e\x55\x65\x31\x2d\x11\x7c\xbd\x5e\x2c\x68\x19\xe6\xd5\x8f\x39\xfd\xec\x70\xd9\x2b\xb1\xf6\xce\x8d\x44\xe7\x38\xc5\xba\xc0\x25\x50\xc7\xa2\xb0\xe6\xc2\xe0\x9e\xec\x0b\xf7\x9c\x8e\xd5\x07\xee\x15\xa5\xfc\x35\x5c\xe6\x1f\xa9\xc6\xb6\xc6\x52\x7a\x03\xc1\x8a\xc3\xb0\x7e\x0b\x28\x76\x9a\x41\x9b\x0d\xf5\xfd\xdf\x02\x1a\x9e\xcb\x66\xdd\x3c\xb3\x68\x6a\x6d\x77\x06\x07\x79\x7b\x99\x96\x74\xee\x54\xf5\x7d\xe8\xa8\x95\xde\xea\xae\x5d\xa2\xbb\xd7\x8e\x8d\xb0\x1b\xe1\x65\xa0\xeb\x06\x68\xd5\xab\x28\x0d\x5a\xd9\xe0\x4e\x9c\xd7\x3e\xe2\xa0\xa9\xd7\x0b\x21\x30\xa8\x9f\x01\xb2\x8f\x3a\x0a\xdf\x2f\xfa\x8e\x59\x13\x97\xd2\x55\x21\xc7\x2d\xd9\xdd\x86\x88\x27\xd0\x58\xce\x14\x44\x49\x49\x3c\x22\x70\x24\xaa\x84\x47\x5c\x92\xd4\xb9\x1e\x8a\x40\x0d\x2d\xf3\x20\x08\x71\xb1\xba\x09\x4a\x1c\xe1\x08\x62\x6c\x6f\x5d\xed\x5a\xd4\x77\x94\x12\x6d\x2b\x66\x6a\x9a\x79\x63\xbb\x9b\xa4\x41\x84\x12\x81\xb5\x89\x27\x07\x26\xbd\x6f\x88\x3a\xbe\xdf\x10\x7e\xc3\x79\xca\x53\x34\x59\xe9\x5f\xfa\xd1\xb1\xc2\x79\x2b\xc4\xec\x46\x15\x45\xe7\x25\x00\x15\x39\xe7\xc5\xf7\x65\x7e\xa5\xf4\x38\x9d\xaa\xcd\x69\xbb\xe4\xac\x01\xf5\xce\x32\x86\xbe\x20\xb9\x26\xff\x46\xbb\xb1\x6d\x4f\xd1\xb1\x62\xdd\x58\x2e\xcf\x9e\xdd\x04\xdd\xa0\xb1\x38\xf2\x4e\xa3\xbf\xe9\xa4\xab\x71\x3e\x46\xec\x91\x82\x92\xe8\x66\x12\x25\x80\xc8\xee\xd4\x56\x75\xb3\x16\x8d\x75\xb6\xb0\xc1\x7a\x26\x03\x4a\xab\x58\x45\xe3\x72\x40\x62\xc4\xa6\xa5\xe4\xef\xe9\xb4\x74\x74\x27\xa6\xf5\x85\x73\xe8\xb0\xd3\x48\x6c\x0f\x2b\x1f\x9e\xb2\x1d\xf3\xf6\xa4\x7f\x06\x98\x6e\xb1\xe6\x55\x3e\x07\xc8\x49\x8a\xd4\x83\xf7\xfd\x95\x82\x5d\xad\xb9\x41\x50\x82\x7b\xef\x1d\xad\xca\x89\xdc\xd7\x2a\x10\x16\xab\x44\xb4\x21\xec\xf4\xbb\x7b\x70\x21\xd2\xe2\x26\x92\x3b\x32\x31\x43\x49\x3b\x0d\x97\x26\xaa\x7f\x83\xf7\x28\xea\xbc\x87\x13\xa5\x6f\x6e\xd8\x24\x72\x1f\x9f\xe4\x3d\xb6\x2a\xa1\x74\xb9\x2c\xb2\x94\x53\xb5\x33\x7a\xcb\xb4\xbc\xa0\x65\x8f\x5f\xa6\xac\x77\x95\x5e\xe7\x57\xeb\xab\x9e\xc0\xa1\xa4\x17\x5d\x7b\x03\xdb\x72\x68\x54\x55\x41\x7c\x88\x06\x5e\x4f\x40\xbb\xb2\x76\x3f\xd1\x86\xda\xb1\x5d\x1a\x96\xa1\x4e\x42\xcd\x8d\x86\x15\x12\x3a\xcf\xe7\xcd\xa6\x79\xf4\xd9\xaa\x76\x95\x5d\x37\xa7\xf7\x6e\xc3\x7b\xb8\xab\x3b\x48\x87\x26\x13\x6a\x90\x0d\x02\xf1\xa5\x3a\xae\x15\x37\x6d\xa5\xd5\x2e\x6f\x0d\xe0\x58\xca\x75\xce\x20\x43\x97\xf8\x3e\x20\x8b\x9e\x63\x34\x76\x15\x30\xe3\x31\x52\x6e\x16\x99\xf2\xd1\x9f\x56\x59\x9e\x2b\xa7\xfc\xcb\x94\xe7\x2c\x56\x1f\xe7\x39\x03\x9f\xc2\xfa\xae\x48\xfa\xef\x07\xa6\x2c\xd1\x3f\x87\xc7\x26\xff\xeb\x80\x6a\x77\x1d\xaa\x64\x56\x8d\x74\xc9\xac\x1a\x8e\x6c\xad\xf8\x70\x49\x9d\x36\xe4\xa7\xd6\x40\x7c\xa5\x3a\xba\xa4\xd7\xb6\xef\xb3\xb3\xb3\x58\x26\x4b\xf1\xc2\xe4\x7c\xef\xf4\xaa\xed\xef\xdc\xe3\xa8\x98\x0c\xe3\xc4\x1d\x1a\x23\x81\x27\x38\xc3\x86\xe7\xd5\x9c\xf4\x23\xc7\x6c\xef\xbc\x1e\x84\x46\xc6\xe9\xb6\x56\x6f\x7c\xb3\xe1\xa7\x11\x44\x28\x23\x11\xc2\xfc\x0c\xae\x39\x15\x3d\x53\xcf\x83\xbd\x7a\x15\xb6\xd9\xb0\x5a\x31\x29\x66\x3a\x09\x98\x9d\x92\xa8\x5e\x9b\x9d\x9d\x9d\x91\x08\x9d\x92\x80\xcb\x5f\x36\x5b\x2c\x2a\xdd\x6c\x02\xaa\xf9\x64\xbb\xb2\x54\xad\xac\x0b\xc1\x17\xd6\x70\xed\x9e\x75\x7c\xd7\x2c\xa9\x10\x44\x65\x5f\x37\xb3\xef\xc2\x99\x57\xcd\xc2\x8d\xd5\x7b\xdd\x1a\xd5\x5f\xc2\x99\x67\x4e\x33\x0e\x12\x94\x0f\x97\x14\x28\x1a\x53\x12\xd0\x81\xe7\x35\x11\xa3\xac\x23\xc6\x55\x1d\x31\x40\xb3\x4f\xa5\x8e\x9f\xcd\x30\x44\x40\x2a\x6d\xe9\x97\x92\x1c\x63\xb8\x79\x54\xf1\x33\x68\x1d\x4f\x86\xf1\x0e\xff\xca\x93\xa0\x20\xa5\x38\x14\x51\x52\x3a\xb2\xeb\xa4\x74\x08\x74\x52\x9e\x0e\xcd\xd7\x31\x78\x7e\x74\xbe\x11\x7e\x13\x94\x64\x50\x4a\x97\x90\xf9\x24\x4a\x6c\x78\x11\x84\xcb\xd3\x08\xd2\x75\xda\xa0\x44\xb8\x3c\xb3\xc3\x73\x55\xd3\xc3\x78\x6c\x0b\x0e\x63\xe3\xc5\xb9\x3c\x8d\xa4\x32\xbb\x56\x30\xda\xee\x92\xee\x04\xc6\x4b\x96\x8d\xe1\x02\x22\x6b\x19\x7a\xce\x0c\x51\x86\xdd\xa2\x59\xd9\x61\x9c\x5c\x38\x40\xec\x96\x08\xac\x19\xba\x2f\x78\x86\x4e\x53\x75\x7b\x44\x3a\xf7\x25\x4a\x07\x34\xc9\x27\x77\x65\x9b\xd7\xd8\xb8\x44\x49\x67\xc1\x65\x5a\xf1\xe7\x1d\x85\xc5\xd0\x05\x5e\xa8\xc1\x77\xa2\xe3\xa7\x74\x69\x0e\x0e\x7d\x58\xc8\x19\x8a\xb3\x42\xf1\xe5\x0e\x5f\x75\xd1\x72\x6c\x84\x53\x12\xe3\xca\x9e\x16\x99\xb9\x73\x1d\x1b\x53\x5d\x25\xda\xca\x0d\x46\x08\x09\x4a\xa2\xce\xdf\xb2\x81\xf1\x68\xb3\x51\x7b\x4f\x9c\x22\xe2\x43\x6d\x3e\xfb\x39\x34\xdf\x48\x32\x0d\x9a\xb7\x1b\x49\x07\x89\xf2\xb7\x45\x89\x94\x8c\x70\xf5\x88\x8c\x70\x26\xfe\x61\x8f\xc8\xa8\xc6\x01\x3b\x4f\x6c\x21\x3c\xd1\x44\x6c\xa8\x84\x86\x25\x4d\xe7\x3f\x3c\x67\x3c\x3e\xfc\xfa\x59\xc0\xbf\x4a\x91\xc0\x2b\x35\xe9\x35\x19\x4a\x6f\x11\x39\x61\xe3\xfc\xb4\x1a\xe7\x83\x01\xca\x17\x81\x68\x2e\x47\x84\x90\x65\xc0\x31\xe8\xf3\xd6\x93\x28\xc9\x87\x6b\x39\x52\x99\x02\x71\xfa\x73\x84\xf3\xe1\x7a\x20\x12\x32\x8d\x3f\xeb\xaf\x52\xc0\x6d\x70\x5f\x27\x8a\xe5\x43\x22\xea\x82\xfb\x3b\x89\xf5\xa0\xc6\x1f\x64\x67\x15\x60\x73\x35\xcc\xc0\x5e\x7c\x9c\x9f\x91\x68\x9c\x0f\x87\x96\xe5\x5d\x91\x7e\x84\xe5\xf5\x73\x06\xd7\xcf\x7a\x74\x83\x05\xea\xcb\xf1\x2d\x10\xba\x5d\x89\xc3\x05\xfc\x14\x8b\xd9\xad\x9a\x61\x35\x87\xb1\x05\xd5\x8d\x13\x59\x91\xbc\x02\x14\x09\x18\xda\x6c\x22\x23\xb3\xaa\x0d\xca\xc6\xe5\x24\x28\x75\x91\x12\xa1\xb3\x02\xb6\x7a\x81\x92\x92\x14\x4a\x3a\xb5\x41\x41\xcf\xf2\x47\x23\x49\x22\x1e\x8d\xec\xcd\xb9\xba\xa9\x19\x0f\x06\xe6\x1e\x19\x9c\x73\x3f\x67\x3c\xe0\x61\xb5\x3e\xaf\x78\x19\x8c\xbe\x4a\xf1\x08\xe1\xf8\x10\x76\xe6\x9b\xa0\x32\xbb\x38\x1d\xd3\x29\x1b\xa4\x33\xeb\xe6\x26\xb5\x33\xf9\x64\x67\xa2\x32\x7f\x0e\xbe\x0e\x38\xb6\x33\x40\x58\x6e\x21\x5b\xe7\x71\x47\x9d\x6e\x0b\xfa\xe9\x4c\xb9\x0e\x31\x9c\xe1\x60\xc0\x10\x97\x7a\x55\x90\x29\xea\x77\x12\xd6\x5b\xd7\x16\xdc\x9c\x36\x3a\xfe\xd0\xea\xd8\x0e\xc5\x96\xfa\xdc\x31\xbc\xef\xbb\x9a\xfb\xe3\xce\x79\xd4\x9d\x74\x00\xdd\x50\x77\x14\xe3\xf4\xd4\x1a\xb0\xf5\x83\x80\x0f\xc9\x08\x9d\x46\x08\x16\x48\x87\x83\x55\x73\x4a\xc5\xb9\xc5\xce\xce\x8e\xe1\x9e\x63\x74\x70\xa8\x6f\x15\x0a\x64\xee\x17\xac\xda\x6b\x7b\x0f\xe4\x5f\x37\xae\xbb\x80\x03\x92\x01\x6c\x8d\xca\xa1\xac\x5f\xc0\x08\xb9\xa5\x95\xa4\x94\x6a\xa2\x29\xa7\xf5\x77\xd6\x82\xc4\x38\x6b\x37\xa4\xcc\xf1\x1c\xa2\xee\x35\xf8\xb8\x38\x65\x63\x43\xf9\xc0\x04\x67\x09\xc6\x1c\x78\x2d\xdf\xfa\xad\xc8\xf2\x6c\xb4\x77\x32\xd9\x4f\x96\x67\xa3\xd1\xde\x64\x2f\x59\x9e\xc5\x27\xf1\x64\x94\xc0\x51\x5b\x0c\x56\xa7\x84\x69\x5e\x69\xa5\x7c\x8c\xc7\xc9\xf2\x34\x1e\x1d\x03\x65\x58\xd6\x3c\x8a\x8f\x92\x78\x74\x2c\x28\x66\x7c\x32\xf2\x83\x5c\x74\x35\x88\x67\x08\x1c\x95\x90\x60\x2f\xf6\x97\xe8\xf4\xf4\x70\x73\xb8\xe7\xe7\xe8\x2c\x1e\x1d\x41\x13\x59\xad\x89\xbd\x44\x57\xc3\x29\xfc\x18\xcd\xb0\xd3\x68\x8e\x7c\xdf\xf9\x4c\x55\xd3\xf1\x01\x34\x1d\x8f\x36\x01\x34\xae\x7a\x49\xd1\xd9\x28\xda\x17\xdd\x64\xa7\x07\x07\xa3\x93\xc3\xcd\x26\x3b\x3b\x38\xda\xdb\xdf\x43\x1d\x5d\xef\x77\x74\x5d\xc1\x8f\xbd\xfb\xc6\xe0\x7c\x56\x8d\x21\x1d\x9b\x21\xa9\xd1\xa5\x7a\x74\x15\x3a\x3b\x3c\x38\xd8\x3b\xf0\xfd\xec\x34\x8e\xe3\xfd\x38\x1e\xa9\x51\x6d\x95\x01\xf3\x7a\x12\xac\x89\x28\xb3\x87\x57\x24\x46\xc9\x5a\x57\x08\xd6\x43\x48\x3f\xc4\xa5\xba\x7a\x13\x5c\x7f\xe4\xc7\xd1\x68\x6f\x03\x33\x15\x74\xf8\xe0\x70\x6f\x14\x6d\x44\x9a\xbf\x46\xa6\x24\xc2\xc5\x80\xac\xb6\x1d\x66\x1c\x1d\x17\x49\xa7\x64\x3f\x3a\x39\xd4\x84\xaa\xc3\xa5\x90\x32\x0e\x93\x39\x98\x5a\x1c\x84\x58\xc2\x5a\x4f\x81\xd8\x80\xdc\x5f\x59\x21\x7d\x89\xcb\x81\xec\xd6\xda\xd6\x6c\x03\x77\x97\x5d\xd7\x39\x4b\xcf\x1b\xdf\xb3\x21\xf4\x5e\x18\x0c\x0a\x54\x76\x0e\x25\x10\xe8\x28\xb6\x86\x7d\x8a\x62\xfb\x7b\xf5\x2f\xe8\x6f\x57\x5f\x2f\x1a\x5c\xb3\x5e\x8d\xa0\xdf\x90\xa4\x82\xbe\x90\x93\x4e\x23\x21\x2c\x95\x52\x44\x2a\xdd\x11\x78\x1e\xce\x09\x1f\xe7\x30\x8c\x1c\x15\x03\xf2\x7c\x4a\xa7\xf9\x6c\x66\xad\x07\x4c\xa7\xcf\x9a\x97\x74\xa2\x63\x4b\x82\xb0\x6a\x2d\x1a\xe7\xd6\x1e\x21\x1f\x90\x91\x68\xb5\x6b\x72\xe5\x34\x9f\x0d\x46\x07\x87\x5f\x95\xd3\x5c\x50\x80\x8e\x2e\xdf\x3a\x37\x38\xf4\x0b\xc1\x44\x44\x9b\xcd\x4e\x35\x9c\xd2\x46\xf5\xf2\x0a\x54\xd4\xeb\x9c\x71\x65\xe5\x39\xe0\x67\x3b\x54\x58\xde\xbb\xf2\x26\x67\x17\xa0\x7b\xc9\x32\x5a\x55\xbd\x73\x7a\x53\xb0\xb9\xd6\x36\x29\x55\x94\x83\x57\x4f\x2c\xfb\x8c\x53\x65\x7a\x52\x53\xa3\x74\xeb\x19\x65\x7b\x1d\xca\x8d\x54\xeb\x7a\xb4\xe9\x8f\x54\x98\xb1\xb3\x5c\xac\x5c\xba\x4b\x47\xd6\xd4\xcc\x4b\x5d\x19\xe8\xc9\x1c\xb5\x5b\x39\x28\xce\x8c\x04\xd2\x0d\x00\xe0\xb3\x75\xdd\x52\x64\xb8\xb3\xfd\xe8\xda\xa9\x4a\xed\xe0\xa0\xfc\x2b\x4d\x8e\xa5\x62\xf1\x2f\x0d\xe2\x77\x33\x88\xdc\x9a\x2c\x91\x01\xc7\x52\x9e\xc7\xf9\x66\x23\xc6\x19\x61\x86\xf7\x11\xb6\x57\x51\xb2\xce\x68\x4f\xa4\xb2\xc1\xbe\x6d\xf0\xa7\x87\x37\x78\xdc\x6e\xf0\x60\x24\x52\xd9\xe0\x78\xcb\x42\xb9\x76\x84\x63\x16\xbe\x5d\x16\x9f\xd5\x67\xdb\xe2\x67\x40\xfb\xca\xff\x48\x24\xc4\x34\xd0\xf3\x05\x03\x8a\xb6\x98\x85\xcf\x5f\xbd\xfd\xfe\xd9\x93\x77\x1f\x5e\x3e\xfe\xf9\xc3\xd7\xbf\xbc\x7b\xf6\x96\x1c\x44\x98\x85\x1f\x5f\xa6\xd7\xca\x3e\xc7\x4a\xa8\x98\x87\xef\x7e\xf9\xfe\xd9\xd3\x0f\x8f\xdf\xbc\x79\xfc\xcb\x87\xb7\x3f\x7c\xff\xfd\xeb\x37\xef\x9a\x6e\xe6\xac\x2f\x39\x47\x93\x19\x23\xcc\xc9\xed\xa2\x28\x3a\x5c\x09\xee\x8f\x6c\xe4\xac\x6e\x55\x27\xc7\x5d\x92\xda\x2e\xc5\xa8\xe0\xbb\xf0\xfe\x08\x38\x9a\x45\x51\x04\xda\xb7\x1a\xab\xfb\x56\xeb\x9e\x8d\x10\x8a\xcc\x7d\x87\x95\x38\x95\x83\xf2\xcd\xc6\x8a\xa3\xfd\x66\x66\x48\x05\x3e\x6d\x36\xb5\xcf\xc0\x7b\x77\x99\x57\xbd\xf3\xb2\xf8\x5c\x81\x4e\x35\xfb\x58\x81\x7a\x70\xde\x4b\xc5\x74\x7a\x81\x9d\x1a\xd2\x06\xe7\xbd\xcf\x97\x79\x76\xd9\x8c\x3f\xfc\xab\xdc\xc6\xbf\xf6\x3e\x1d\x84\xd7\x61\xef\x87\x8a\x3a\x49\xfb\xe1\x75\x2f\x5f\xf4\x6e\x8a\xb5\xae\xd3\x2b\x96\x73\xd3\xaf\x6a\x38\xf4\x0c\xd0\x9a\x1e\xc1\x5c\x23\x75\x19\x10\xdd\xc3\xb7\xd4\xb8\x36\x4c\xfa\x11\xbe\xa0\x3c\xa9\x1b\xdb\x3b\xc4\x47\x3e\x75\x70\xdf\x27\xc8\xb1\x6d\xb7\x0f\xea\x52\x29\xf3\xff\xa7\x5d\xde\x70\x2a\x03\xde\x8a\x6e\x1f\x7e\x73\x55\xad\x68\x96\xd3\xca\xf7\xf9\xb4\x9e\x32\x93\xec\xf1\x2e\x2f\x6a\xf5\xc2\xf8\x56\x7a\xcb\x04\xce\x35\x2b\xd8\x22\xbf\x58\x9b\x99\xb8\xf3\x8a\xb1\xd8\xd4\xea\xf7\x16\xde\x7e\x16\xc5\xf2\x6d\xfe\x07\x25\xc7\xf1\xc9\x08\x4b\xbd\x4a\xcb\x2c\xbb\x79\x6b\xbf\x03\xff\x5d\xb8\xfe\x99\x7d\xe3\xee\x32\x43\x27\x76\x0d\x62\x47\x32\x5c\x23\xd1\x53\x12\x4d\x52\x7b\xdd\x21\x80\x3f\xe9\xd0\x21\x41\x99\x70\x91\x2f\x97\x70\x88\x27\xce\xa7\xfc\xd8\x9a\x99\xaa\xd1\xfc\xc0\xaa\x74\x41\xbb\x1e\x4b\x81\x59\x43\xbd\x98\xa0\x89\x77\x15\xd5\x78\xd4\x55\x46\x79\xfb\x53\x7a\x79\x1a\x7e\xd0\x85\xa5\x6d\xa9\x03\x62\x78\x40\x59\x5c\x89\x2d\x43\x5a\x66\x11\xbf\x05\xee\x12\xc0\x4b\x6d\xad\x34\xa3\xc6\xc3\x38\x76\x6f\x2e\x10\xc2\xbf\x05\xac\x51\xc9\xd1\xb4\x31\x5d\x89\xd5\x2b\xd5\xf9\x80\xcd\xa6\x5f\x57\xc7\xed\xbe\xf8\x38\x5f\x2f\x62\x0f\xc3\xdf\x91\x3d\xd2\xab\xce\xfb\x0f\xc5\x2c\x14\xa5\x43\xda\xd5\x15\x1b\x21\x84\xb5\x6f\x29\x6a\xd7\x1e\x5a\x0f\x28\xf8\x34\x1d\xc2\x40\xf0\xa7\x25\x2e\xd0\x38\x3f\x4d\x81\x0b\x04\x8f\xa3\xf9\x0c\x9c\x91\xe7\x33\x74\x5b\xc2\x93\x14\x51\x7b\x9a\xab\x90\x51\xe6\xc1\xcb\x29\x5c\x08\x14\xa7\xe5\x24\x4e\x22\xb9\xa2\xda\xb4\xa4\xb6\xa6\x4a\x3c\x54\x3a\x32\xda\xd4\x91\x39\x0a\xf6\x1d\xda\xf4\x87\xdd\xad\xd4\x94\xe2\x7f\x5d\x03\xde\x8f\x8c\xde\xdb\x1e\x57\x80\x64\x2c\x4b\x9b\xaf\x3b\x04\x07\xd8\xb2\x6c\xef\x66\x02\x97\x79\xc5\xbb\x58\x40\x65\x51\x2e\x16\x59\xae\xaf\x62\xdf\x3a\xf4\xdb\x3d\xcd\x3c\x28\xc3\xe6\x72\xec\xba\x0f\x60\x48\x99\xc5\x2a\xa9\xca\xd1\xd8\x94\x42\xbe\xa2\xd3\x72\xa6\x93\x94\x0c\xe2\x6e\xd7\x80\x21\xe0\xe0\xed\xa3\xde\x5a\x03\xfa\xb1\xcf\xb4\x9c\x49\x03\x98\xb4\xb1\x49\x52\xbd\x49\xd2\xc6\x76\x48\xff\x16\x88\xa4\xd2\x64\x43\x70\xa2\x38\x1f\x18\x8b\x48\x1b\xce\x1f\x73\xd7\xaa\xf9\xb2\xf6\xa0\xdf\x90\x0f\xe9\xbb\xc2\x79\xc4\xfa\x39\x5d\xc5\x87\x3b\x5e\x51\x5b\x31\x97\x7e\x31\x12\xf2\xc7\x0e\x06\x56\x6d\xcb\x2a\xff\x83\xee\xb0\x95\x8c\x0f\x87\xe7\x39\xaf\x3c\xe4\x38\xe5\x8d\xc6\xfc\x94\x8e\xb9\x10\x92\xae\xf4\x9d\x0b\x1f\xc4\xc8\x7d\x63\xb8\x6d\x0d\x76\x6f\xf4\x80\xc1\xee\xff\x8f\x06\xbb\x37\xba\x63\xb0\xfb\xee\x60\xf7\x10\xd6\x5f\x83\x18\xf3\xc1\xe8\x9e\xc1\x1f\xee\x3f\x60\xf0\xc7\xff\xa3\xc1\x1f\xee\xdf\x31\xf8\x63\x77\xf0\x47\x8d\xc1\x1f\x3a\xdf\x23\xcc\x07\x07\xce\xf7\x1e\xe6\x83\xfd\x3b\x26\xa7\x2f\xe0\xef\x9e\x9e\xa3\xf2\xa3\x13\xcf\x4b\xa2\x8e\xc7\xc9\x13\x75\x65\x08\x61\xec\xcf\x77\xb8\x10\x69\xf4\xfd\xa2\xc8\xd2\x25\x55\x23\xe8\x1a\x56\xad\x3c\xfd\x7d\x9d\x2e\xab\xa6\x41\xd5\x03\xe4\x58\xef\xf1\x2e\xf1\xd5\xab\x81\x46\xfa\xdb\x06\xc5\xa6\x3e\x99\x75\x90\x83\xfa\xc8\x95\xb5\x69\x1b\x68\x9e\x87\x39\xe9\x90\x8d\x1c\x57\x93\x02\xac\xc6\xec\x01\x0e\x0f\x1c\x61\x8e\xc2\x92\x82\x13\xf3\xe0\x51\x10\xde\x8e\xb6\xe8\xd1\x05\xf6\xfe\x23\xee\x79\x28\xe4\x65\x7e\xa5\x1d\xb2\xa9\x6b\x7f\xae\x5e\xd1\xf6\xc2\x30\xec\x79\x08\x7b\xa7\x0a\xbf\xbc\x01\x1d\x78\x67\xde\x16\xe7\xbe\xef\xb2\x73\xd3\x7c\x46\x3a\x26\xd0\x74\x1e\xd2\x66\x46\x1c\x11\xfa\x2f\xb1\x24\x0f\xd1\x32\x00\x37\xc1\xd3\xf2\x82\x76\x11\xd5\xfb\xd8\x88\x5d\xc6\x13\xb5\x03\x06\x58\xa1\x08\x61\x6b\x45\x23\x6f\x3d\x27\xfa\xa4\x48\xdc\xcc\x02\xcc\x3f\xdd\x94\x1c\x22\xe8\x35\xee\xe9\xa3\xcd\xc6\x2a\x15\x36\x9b\x42\x24\xe4\xb5\xdb\xfd\x1d\x0a\x1f\x47\x61\xd0\x83\xdb\x45\xa9\x68\x28\xce\x44\x3f\xec\xcc\xb5\xda\x50\xc9\xb5\x6b\x62\xb7\x04\x24\x68\xdc\x6d\xb3\x51\x29\x09\x72\x69\x33\x30\x0c\x0a\xf9\x03\x57\x24\x28\x75\x9a\x32\x2d\xc0\x4b\xcb\x54\x41\x70\xf7\xb5\xf2\xe6\x06\x7a\x32\x38\xb9\x56\x46\x6d\x26\x3d\x98\xc0\x95\xd6\x72\x3c\x18\x2c\x04\xe7\xb5\x9e\x2e\x04\xe7\xb5\x9a\x2e\x66\xe8\x36\x25\xe2\x13\x57\xf0\x59\xe7\xbc\xd2\xd3\x4a\x70\x5e\xd5\x69\xaa\x39\x2f\x17\x27\xb3\xe5\x7a\x4e\xab\x1d\x82\x03\xdc\xc6\xc9\x87\xea\x3a\xda\x94\x61\xf1\x5b\x97\xb5\xbb\x84\x8f\x97\x6a\x3f\x83\x4e\xa4\x1f\x35\x2a\x3b\x17\xb8\x0f\x6b\x20\x6e\x34\x00\x1a\x97\x46\x55\x65\x9e\x66\xad\x46\x50\xa9\x8c\x35\x70\xcd\xf2\x03\x0b\x72\xaf\xaf\xd4\x5d\xcc\xed\x32\xf6\x06\xdd\x4d\x67\x6d\x79\x11\x5f\x7d\x93\xb3\x9c\xd3\x80\xa3\xf6\x5b\x09\x65\x73\x24\xb5\x43\xfa\xae\x59\x9b\x41\xe0\x9e\xdc\xc7\x53\xac\x94\x88\x33\x24\x35\x93\xbd\x65\xc1\x2e\xac\x3e\x00\xdc\x33\x71\xa5\x77\xd2\xbd\x31\x34\x51\x18\xd5\xdc\x68\xca\x3a\x05\x25\x41\x49\x98\x71\x9b\x8b\xb6\x8a\x9b\xb3\xf3\x18\xf2\x0e\x83\x99\x42\x8a\x32\x05\x32\x17\x54\x67\x91\x48\x11\x1b\xee\xff\x61\xef\xcf\xbf\xdb\xc6\x95\xc4\x51\xfc\x5f\x71\x30\xdf\x71\x8b\xd7\xb0\x9b\xa4\x76\x29\x8c\xbf\xce\xd6\xc9\xbd\x9d\x4e\xa6\x93\xf4\x72\x1d\x4f\x3f\x88\x84\x24\x76\x28\x52\x06\x21\x2f\x1d\x6b\xfe\xf6\x77\xaa\xb0\x92\x92\xd3\xe9\xe5\x7c\xde\x9c\x77\xde\x2f\x12\xab\x0a\x4b\xa1\x00\x14\x0a\x40\x01\x90\x0f\xc3\xe0\xee\x4e\x7e\x41\xb7\xf3\x1c\xd6\xb0\xec\xd6\x4b\xaf\xe1\xa2\x07\x23\xc2\xdd\x9d\x63\xf9\x1e\xbf\x29\xb1\xc7\xbb\xe6\xd6\x6b\x1b\xbf\xe7\x5f\x73\xb5\x1b\xb6\xe9\x61\x73\xb6\x1b\xe0\x73\x3e\x36\xbf\xec\x06\x6f\x79\xd9\x5c\xef\xe1\xee\x4f\xf9\xd9\xfc\xd6\x48\xa8\xe1\x6e\xf5\xc5\x9e\x36\x22\x98\x0a\x74\xc1\x6a\xfb\x1d\x68\x17\xac\x96\x9d\xf0\xcf\xb7\xaf\xbf\xdb\x77\x29\xd5\xed\x9a\x5b\xa7\x65\x9a\x31\xc9\x26\x7b\xef\x7a\x71\x77\x76\x9d\xfc\xc2\x84\x50\x77\x76\xd1\x30\x68\xe5\x83\x61\x5b\xd3\x24\xf7\x58\x92\xdd\xad\xe0\xc9\xff\xfc\x0f\x0f\x1e\x86\xa7\x30\x04\x8b\x00\x1d\x68\x78\x12\x06\x13\xfe\x48\x5f\x13\x1d\xd0\x4e\xe9\x79\x76\x9e\x8a\xc9\xff\xfc\x4f\x89\x31\x4a\x1b\x03\x86\xa3\x49\x89\x31\x4a\x88\x51\x3e\xe4\xf8\xc9\x8d\xef\xb9\x52\xc0\x9b\x19\xb3\x4e\x9e\x9f\x5f\xea\xdc\xf1\xea\x6c\x94\xcd\x78\x51\x7c\xfb\x6c\x47\xb3\x71\xd5\x63\x75\x67\x2e\xef\xee\xd4\xfe\x85\xdf\xa1\xbc\x69\x39\xa0\xcf\x39\xcc\xab\x23\x9c\x74\x1d\x1d\xe5\x0f\xc1\x1c\xa9\xfe\x91\xc4\xfd\x41\x30\x0d\xc4\x91\x0e\x73\x94\x5f\xfc\xa3\x72\xdb\x40\x7b\xd9\x79\xfc\xf7\xb0\x73\x74\x7c\x2c\x91\xa5\xa9\x44\xcd\xb0\x87\x19\x08\xf1\xbb\xec\x8c\xee\xb9\xf2\x5d\xb3\xa4\x78\x89\x1a\xbc\x50\x2d\x90\xfd\x09\x46\x83\x96\xc0\xef\x49\x33\xde\x9b\xe6\x9d\xe6\x1d\x8f\x89\xdd\x97\xc1\xe3\xbf\x90\xc1\xc3\x87\x23\x97\xc7\xfe\x0c\xba\xf1\x97\x95\xa0\xd7\xcc\xa0\xb3\xaf\x08\x06\x88\xf1\x30\x5c\x70\x14\x0d\x86\xc3\x61\x1c\x0d\xfe\xa1\xf1\xdd\x7b\x79\xf8\xb2\x42\xb6\x78\x68\x25\x7f\x71\xd4\xf1\x98\x89\x06\x3e\x37\x96\xb5\xee\x45\xb0\xcb\xc3\xff\x93\xfd\xe6\x51\x02\x41\xa2\x78\x84\xfe\x7b\xc7\xca\x4e\x5b\x57\xd7\x9d\x98\x8e\xfe\x21\x83\x80\xee\x69\xca\x7f\x4b\xc7\xd2\x9c\xda\xee\x23\x2e\xa6\xa2\xd9\xb9\xf2\x23\x9f\xea\x78\xce\x1b\x3c\xe7\x7b\x78\xce\xf7\xf2\xfc\x67\x7a\x5f\x14\x8f\x0e\xb5\x68\x4f\x8f\xa3\x7f\x74\xe2\x7e\xff\xd8\x54\x77\xa4\xee\xd8\xde\xdb\x39\xf7\xf7\xcd\xcf\xf5\x99\xa9\xbb\x7f\xbe\xdd\xae\xed\x21\xf3\x78\x38\x18\x1d\x96\xa7\xbd\x78\xdc\x1b\x87\xd1\x70\x10\xde\x95\x93\xf2\x9e\xcc\x77\x9a\xf4\x17\x67\x7e\x14\x99\xec\xff\x64\xe6\x7f\xb2\x4f\xff\x7e\x97\x76\xbd\xe8\xe1\xc3\xb8\x77\x4f\xde\x7f\xaa\x2f\xdb\xf2\xc6\xbd\xbb\x2f\xe9\xc5\xbb\x79\x3f\x2f\x2a\xd6\xee\xc6\x5f\x96\x77\x85\xf1\x8d\xd5\xf3\x20\x54\x7b\xb3\xf7\xe4\xf0\xa7\x4a\xd7\xca\x21\xba\x2f\x87\xa7\xd5\x66\x56\xf0\x2f\x2b\xc4\xe8\x77\x0a\x81\xfb\xc1\xf7\x65\xf1\x65\xa5\xf8\x7c\x16\xd1\xbe\x2c\xd0\xf2\xde\x6b\x88\xc0\x3c\x89\x27\x47\xdc\x2a\x28\xf5\x27\xee\xee\x9e\xf8\x73\xae\x86\x2e\x29\x83\xe3\x88\x86\xc6\x62\x8a\xec\x2a\x30\x36\x03\xa9\x8f\x0e\xa1\xaa\x2d\x7d\xc5\xa5\xc8\x47\xf9\x45\xc2\xbf\xae\x0e\xe3\x7e\xdf\x2e\x02\x1d\x95\xf7\xb0\xbb\xa3\x4f\xff\x3a\xbb\xe5\x31\x30\x1c\x79\x0c\x1f\x55\x86\xe5\xe3\xe3\x0a\x6f\xa5\xeb\xe4\x2d\x9e\x2b\xe0\x39\xff\x32\x9e\x47\xf7\x4d\x62\x1b\x7c\x37\x18\x8e\x68\xdc\xef\xd3\x50\xf7\x37\x23\x41\x2a\x8f\xa2\x7b\xf2\xd8\x51\xa2\x5f\x94\x4d\x4c\xd1\xdb\x6b\x4f\x46\xaa\x94\xd1\x45\x02\x2d\x6d\x44\xe5\x51\x7c\x6f\xc6\x7b\x86\xb8\x3f\x93\xb1\xce\xc8\x66\x6c\x4a\x7c\x5f\xc6\x3b\xca\xf3\x8b\x32\xee\x51\xd4\xcb\x83\x61\x3c\xf6\x72\x3f\xea\xaa\xfc\xe3\x9e\x41\xc4\x0a\x11\x0d\x76\x45\xd1\xaa\x91\xde\xbd\xfc\xfd\x19\xc1\xec\xe7\xaf\xcd\x5d\xd4\xe6\x2e\x6e\xc9\xaf\xfb\x79\xfe\xee\xeb\xf7\xb8\x0f\xe8\x58\x7b\xa0\x37\x6d\xaa\xa6\xe5\x50\x1e\x47\xc1\xb4\xd1\xbb\xaa\xe3\x88\x1e\x57\x6a\x19\x41\xed\x0d\x46\xb4\xfe\xac\x0e\x60\xa6\x3f\x71\x98\x85\x85\xea\x8a\x92\x50\xaf\x2c\x81\x4e\x38\x8e\x2e\xf0\x76\xac\xc8\xd6\x51\x7e\x91\x74\xf8\xd7\xec\xd1\xa3\x30\x38\xae\x7f\xbf\xe7\xdd\xa7\x2c\xfe\x9e\x32\x82\xd2\xd8\x2d\x25\xf0\x68\x14\x47\xae\x14\xc7\xef\x16\xf4\xe8\x6f\x28\xe8\x9f\xd2\x30\x51\x3c\xa4\xc7\x60\x1c\x52\xae\xe7\xce\x71\xbf\x7f\xc4\x8f\xa2\x2f\xd3\x3a\x7f\x41\xe9\x80\x89\x34\xa4\xc7\x68\x29\xfd\x39\xcd\xf3\x17\x14\xcf\xfe\xcc\xff\x88\xf6\xf9\x0b\xca\xc7\x73\xc5\x6a\x1c\x0d\xfa\x1d\x19\xdc\xa3\x93\x3c\xad\x75\x5f\x37\xff\xb3\x5a\xe8\x3e\x46\x4d\x53\x71\x5a\xaa\xd9\x62\xfe\x5e\x3d\xb5\xcf\x56\xf4\x0a\x70\xe9\x38\x7e\x10\xee\x2c\x41\xbb\x14\xee\x17\x81\x9f\x42\xb4\x3f\x85\xbd\xb6\x9e\x97\xc4\x8f\xbf\xcf\xc4\x5e\x5b\xee\x9e\x24\x76\xb9\x48\xab\xf5\xed\xce\x5e\xd0\x17\x6f\xb9\xd9\x7d\x9c\x7a\x59\x6d\x8a\xac\xb5\xe9\x96\xcf\x3b\x6a\x95\x35\x0c\x68\xa5\xb6\xdc\xaa\xbb\xbb\x4e\xd5\xda\x62\x71\x07\xd1\xd4\xda\x98\xa3\xe0\xdd\x20\x10\x19\xa6\xa4\xd5\x43\x75\x61\x87\x08\x68\xd5\x3c\xf4\xda\xf2\x46\xd0\x9b\x7b\x3b\xc7\x34\x55\xc8\xfb\x1d\x3d\xd5\xe6\xd4\x5b\xc9\x84\x6c\xfa\xab\xea\xa2\xa8\xad\xa0\xe4\xf7\xd7\xa0\xef\xf3\x31\xad\xee\xcd\xba\xae\x36\x22\xe5\xcf\xca\x6c\x27\xe3\xca\x5f\xf3\xc6\xf2\x37\x84\xe7\xce\x72\x3c\xac\x8e\x95\x7c\x1c\xea\xc8\x3d\xd3\x72\x2c\xfc\x2d\xa4\xfd\xd7\x2f\xec\x3d\xee\x06\xed\xe3\xc7\x5c\x2e\xf3\x12\x8d\x53\x0f\xee\xa8\xa6\x62\x77\x33\x5c\xe2\x02\x06\xe1\xf2\x61\x15\xb8\x0d\xaa\xfc\x38\x9a\xb2\x47\x49\x38\x3d\x3e\x66\x01\x3f\x67\x47\xe5\x85\x1a\xa3\xd8\x91\xb8\x50\x49\xec\xcd\xbe\xe6\xd2\x9c\xb2\x6b\x2e\x95\x0a\x7c\x33\xcd\x3b\xd8\xd2\x68\xd5\xf3\xbc\x28\xf6\xb7\xea\x7d\xb7\xd6\xdc\x73\x43\xcd\x69\xa7\xc2\x6d\x8c\x90\x36\xd6\x86\x83\xc9\x9e\x13\x9c\xaa\x65\xb6\x02\x52\xeb\xdf\x56\xb9\x0d\x1e\xe7\x6a\x58\xed\xef\x53\x66\x05\xdd\xdb\xc6\x36\xb7\x5b\xec\x3f\x3e\x5a\x1d\x1e\x36\xef\xcd\xa9\xfe\xc0\xbd\x39\x15\x26\x1a\xf9\xce\x3c\xea\xbc\x4d\xf3\x94\x51\x18\x4c\x3b\x6a\x9f\x43\xed\x9c\xe6\x0f\xa3\x78\x74\x77\x67\x76\x2b\x00\xa9\xf6\x8a\xf3\x60\x8b\x87\xe7\xf6\xdc\xe5\x72\xca\xf1\xc8\xe6\x64\xf7\xea\xe2\x03\xe5\x7e\xac\x0f\xb1\xe9\x7d\x5d\xb5\xf1\xe3\xc4\xf9\xb0\x6c\x82\xe2\x9e\xbe\xf4\xfa\x9e\x8d\x57\xf1\xd0\xb9\xa0\x49\xf3\x62\x2b\x53\x5b\xad\x6a\x56\x97\x78\xd7\x2f\x78\x39\x4d\xc4\xa3\x47\x8f\x42\xaa\x4e\x60\x87\x01\xdd\x77\x4d\x0d\xb4\x74\x96\x94\xf6\x14\x9d\x6a\xdb\x17\x09\x57\xdb\x75\xea\x4c\x5d\x43\xa1\x9e\xf2\x89\xdd\x57\xaf\xd4\x8d\xca\xce\xcd\x24\xc4\x93\x8a\xf7\xee\xa3\x7f\xf6\x3e\x0f\xab\x93\xb5\x1f\xfe\x57\x6a\xc1\x4f\x9f\xf1\x3b\x2e\x3d\xfe\xa0\x17\xd6\xe7\xec\x3f\x53\xf7\xc2\xef\x32\xaf\xd5\xc5\xbe\x4f\x93\xaf\xcf\xff\xfb\xe8\xeb\xf0\x78\x7c\x76\xfc\x6f\x76\xfc\xdb\xf1\x2f\x17\x5f\x2f\xdc\x5d\x5b\x8f\xbd\xcb\x5c\xa7\x32\x91\x77\x77\xd1\xd7\xf7\x39\xf6\x6d\x8a\xc2\x3f\xda\xa6\xcf\x19\xe2\xa1\xf7\xf6\x59\xb6\xe0\x51\xbf\x1f\x8f\xfb\xa0\x3e\xfa\xc3\x6e\xaf\x67\xee\xec\x46\xef\xfe\x47\xfd\x41\x37\x1a\x07\x9f\x3a\xf2\x38\xe9\x06\x8f\x8e\xa3\xc3\x43\x7d\xc2\x2d\xee\x8e\x69\x34\x8e\x68\x34\x1a\x07\xd3\xb4\x2a\x65\x5e\x6e\xf8\x36\x9f\x77\x18\x1e\xfa\x14\x5f\x1e\xa7\x4a\xca\x46\x02\xe5\x43\x3c\x85\xf4\x7b\x09\xd0\x46\xbc\x52\x1d\x6e\x3a\xea\x54\xc7\x78\x98\x09\x2f\x42\x2c\x8f\x55\x4a\xea\x6c\x29\xde\x09\xf8\x59\x96\x60\xc0\x50\xb2\x2b\xa1\xb3\x29\x81\xc9\xe3\x24\x0a\x1e\x86\x81\x3a\xf6\xa5\xa3\x99\x57\x3b\x91\xdd\x38\xec\xb9\xb0\xf1\x6e\xd8\x47\x8f\x06\x77\xd1\x38\xa6\x83\xee\x61\x79\x07\xe9\x7a\x71\x91\x6b\x1b\xb9\xbb\x2f\x72\x14\xdf\xc5\x71\x8f\x96\xea\x52\x3a\x48\xa0\x95\x12\x56\x58\xa7\x34\x27\xc2\xf6\x6c\x4d\x9b\x6b\xfc\xd2\x2a\xe3\x07\xeb\xca\x1e\x85\x81\x3c\x7b\x7b\xf3\x1c\xdd\xc5\x3d\x5c\x7c\xc1\x4b\xf1\x30\xd3\xfd\x0c\x6c\xed\x70\x60\x1b\xea\x1b\xcf\x6d\x57\xf8\x57\x82\x76\x5a\x2e\x46\x1d\x9e\x74\x78\xc2\xcd\xab\xee\x09\xc1\xe7\xea\xb5\x63\x8e\x75\xdc\x79\x4a\x09\x09\x82\xf6\xc1\x67\x7d\x49\xc3\xd4\xb4\x7a\xe5\xe2\x36\x0d\xf8\x51\x42\x12\xe2\x5e\x38\x6a\x5e\x9b\xf3\x93\x9b\x37\xba\x63\x4f\xe1\x14\x0d\x9d\x07\x9d\xea\xa8\x7c\x64\x4f\xee\xde\xdd\x55\xde\x79\x7d\x3c\x97\x25\xcf\xab\x23\x7c\xaf\xa4\xda\x77\x22\xea\xd7\xe6\x8a\x9e\x3d\xc1\x53\xcd\x0f\xe4\xdd\x9d\xf5\x5f\xd6\x1f\xfe\x3d\xb9\x7b\x91\x27\x25\x5b\xf1\xd6\x85\xba\x88\x43\x37\x2a\xf8\x70\x59\x7f\xef\x5f\xd0\xfb\x20\x49\xd4\xc3\x4e\x2f\xfd\xad\x5d\x53\x5c\xee\xdd\xab\x0c\x13\x59\xaa\xbc\xe1\xa2\xc1\xf4\xe8\x48\xba\xb7\xd4\x93\x68\xf0\x0f\xa9\xdd\x46\x91\x26\x02\x7e\x5e\x1e\x89\x8b\x84\xb8\xeb\x28\xd5\x95\x95\xe4\x5c\x5e\x1c\xed\xc1\xba\x9b\x85\xf8\xb6\x13\x6c\x03\xef\x85\x27\xde\x31\x27\xa0\x02\x7d\x66\x26\xd8\xd2\x4f\xde\xe5\x86\x93\x88\xaa\x00\x93\x2e\xd5\x37\x1c\x4e\xba\xf1\xf6\x82\xf6\x76\x2f\x4a\x94\xf6\x06\xf7\x4f\x5c\x3d\xd5\x82\x2f\x99\x4d\x3e\xb1\x42\x2e\x8a\xdb\xf5\x72\x42\x58\x21\xbf\x81\x2f\x42\x0d\x2e\xe3\x73\x87\x7e\xca\xe7\x8e\x92\x4b\xbe\x72\xa4\x97\x92\xaf\x08\x65\x65\xbe\x62\x92\xa7\x55\x51\x89\x09\xd1\xd0\x13\x80\x2c\x6d\x55\x01\x4f\x96\xf8\x0a\x41\x4b\xc5\x67\x60\xe6\x95\x58\xd9\x00\xef\x0c\x86\xd0\xb4\xc8\xd7\x6b\x26\x97\x13\x02\x5f\x6f\x98\x5c\x12\x3a\xe7\xb3\x82\x97\xd9\x84\xcc\xf9\x63\xf8\x00\x0c\x66\xbf\x62\x52\xe4\x37\x80\xc7\xfc\x5f\x21\xa8\xa8\xfa\x75\x18\x95\x17\x17\x2a\x8c\x46\xbe\xd3\x48\x1b\xb2\xce\x25\xb7\x21\x00\x50\x94\xf2\xaa\x2a\xae\xb8\x9f\x89\xc2\xb8\x7c\xb2\x7c\x3e\xdf\xd4\xbc\xc8\x17\x4b\x7c\xa5\x8a\xcc\xf9\x53\x85\xfa\x56\xa3\x54\xa8\x1a\x7b\x2f\x54\xc7\x8a\xad\x55\x28\x87\x7a\xc5\xd6\x3a\x94\x64\xa5\xc4\xb4\x74\x10\x80\x31\x21\xa4\x8b\x6a\x5d\x2f\x59\x56\x5d\x23\x55\x54\xeb\xb7\x08\x01\x6d\x5e\x54\x15\xca\xe7\x39\x7c\x20\x66\x53\xa6\x0c\x31\x9b\x32\x3d\x33\x98\x99\xc1\x3c\x36\x98\x85\xc1\x7c\x63\x30\xc2\x60\xbe\x07\xcc\x82\x6d\xea\x3a\x67\xe5\xac\xd8\x20\xe1\x1b\x0d\x3f\x2e\x36\x28\xbf\x7c\xc5\x16\x28\xbb\x97\xf0\x01\x98\x15\x17\x0a\xf3\x0a\x3e\x2c\xa6\xac\x32\x87\xfd\xae\xca\x14\xa5\x12\xeb\x65\x55\x54\x8b\x5b\x24\x59\x08\x68\xca\x47\x08\xf0\xaf\xf5\xe9\x9b\x39\x47\x75\x6d\x25\xf4\x06\x20\x2b\x9f\x7a\xcd\xd3\x4d\xc1\x84\x5f\x19\x6f\x35\xce\xaf\x8d\x7a\x5d\xb9\x24\xde\xae\x2b\x97\x82\xcc\x0b\x64\xf1\x5d\x5e\x20\x77\x72\x23\x66\x9b\x82\x97\xa9\xc2\x5a\x88\xd0\x79\x25\x78\xbe\x28\xd5\x55\xe9\x13\xa2\x41\xe5\x33\x41\x28\x76\x1d\x01\x9d\x0a\xbf\xbe\x87\x1e\x55\xe4\x25\x67\x62\x21\x58\x96\xe3\xa3\x45\x0a\xfe\x46\xc3\x84\xc2\x07\x2b\x1c\x5d\xc1\x8e\x2e\xf9\x8d\x54\xfd\x02\xbe\xb0\x5f\x6c\x29\x93\x52\xe4\xb3\x8d\xe4\xba\x93\xe3\x09\x20\x7c\x60\x69\x23\x8a\x09\x71\xe0\xfb\xef\xbf\x25\x2e\x34\xe8\xcb\x09\x69\x44\xf6\xa8\xca\xe1\xc5\x82\x60\xfb\x11\x0a\xda\x68\x2e\xf8\xe5\x86\x97\xe9\xed\x04\x95\xd3\x73\x03\x2a\xea\x5a\x54\x73\x94\x1f\x00\x6f\x14\x40\x68\xca\x8a\x74\x85\x35\x0f\x5f\xaf\xb0\xda\x4d\x17\xdf\x94\xb9\xac\x5d\x3f\x7f\x0f\x20\xa1\xba\x4b\xa1\xa2\x67\xea\x79\x27\x44\x3c\xd1\x08\x42\x79\xb6\xe0\x2a\x4d\xf8\x52\x69\xaa\x67\x0e\x74\x8a\x0a\xd0\xe9\xed\xab\x0c\x23\x66\x4f\x13\x19\x94\xa7\x8a\x0c\x4a\xa7\x6a\x40\x9d\xee\x47\x2e\x4a\x5e\x18\xe5\xa0\x20\xa3\x18\x14\x04\xf1\xb4\x09\xaf\xe9\x10\x55\x79\xad\x42\x98\x5b\x6c\xcd\x35\x10\x6f\xb1\x29\x63\xaa\xb7\x60\x00\x94\x5c\xa1\xdf\xaa\x6f\xc4\xcb\x7c\xa5\xb1\xef\xe0\x8b\x50\x95\x36\xcb\x7e\xdd\xd4\xd0\xa0\x10\x3a\x43\x08\x9a\xdb\x0a\x1f\xf2\x4c\xab\x92\xb3\x72\x01\xf5\x62\x50\x4f\xaa\x92\x9f\x01\x8a\xd0\x15\x13\x1f\xb9\x58\x72\xd5\x1b\x14\xf4\x82\xab\xee\xa0\x20\x5d\x76\x05\xe8\x92\x2b\xe0\x3a\xcf\xa0\x60\x0a\xf8\x11\x00\xa0\xd4\x1f\xf1\xad\x54\x2b\x34\xc0\x3c\x51\x18\x1b\xbb\xfe\xe8\x11\x35\xb6\xdc\xac\xaa\x54\xb2\x2b\x28\x61\xb9\x59\xbd\x56\xdf\x84\x42\x3b\x31\x32\x84\x6f\x23\xbd\x35\x93\x92\x8b\xb2\x99\x99\x46\x36\xf3\xd3\x48\xaf\xaa\x35\xc6\xab\x69\x8d\x69\x26\x63\xe2\x63\xcd\x30\x79\x33\x21\xea\xf3\x4c\xfe\xe4\xb0\xb7\x0e\xfb\xb3\xc3\xfe\xe6\xb0\xff\x26\x74\x2d\x78\xcd\xc5\x15\x67\xc5\x7a\xc9\x26\xc4\x80\x67\x00\x7a\x54\x74\x96\x16\x4c\xe6\x95\x17\x06\x91\xdf\x03\x12\x42\xea\x0b\x27\x0d\x9f\x06\xd6\x9c\x0a\x3e\xbf\x99\x10\xc1\xe7\x3f\xe1\xf7\x2d\x7e\xff\x0c\xdf\x6b\xce\x64\x5a\x6d\x50\xaf\x20\xf0\x04\x00\x43\xc9\x40\xb3\xab\xcf\xa7\xa0\xd4\xcd\xa9\x4e\x7e\x23\x79\x59\xe7\x55\x59\x03\x59\xe1\x9e\x59\x9c\x0b\x37\xe7\x4c\x6e\x04\xf7\x42\x3d\xd7\x18\x42\x8d\x52\x76\xdd\xd9\x60\x5c\x7f\x36\x18\xb0\x5c\xd4\x8b\x6e\x06\xf3\xec\xc6\xbc\x7b\xa7\x1e\x84\x58\x71\xb9\x84\x71\x4e\x41\xaf\x10\x22\xb4\x96\x4c\x48\x33\x5a\x20\x60\x06\x8c\x5a\x66\x19\xbf\xca\x99\xb2\x46\x6a\x99\x3d\x35\x10\xd0\x72\x99\x2e\x41\xe5\xd7\x40\x02\x00\xf4\x3e\xf0\xbc\x11\x73\x96\xf2\x3a\x65\xd0\x6d\x34\xf4\x16\x20\x42\xeb\xdb\x5a\xf2\x55\xc1\xca\xc5\x06\xc7\x3d\x05\x7f\xab\x61\x42\xf1\xd8\xa4\x7a\x3b\x74\x42\x10\xf8\x01\x01\xa0\x88\x05\x87\x56\xa4\x3e\x7e\x32\x98\x5b\x83\xf9\x59\x29\x79\xd3\xda\xe1\xdb\xb4\xf6\xab\x9c\x5f\xcf\xaa\x9b\x09\x81\x8f\xc7\xd5\x8d\xc2\xa8\x68\x0a\xf9\x4e\x79\xb6\xd3\x9b\x74\xc9\xca\x12\x26\x42\x05\x07\x23\x79\x42\x6e\x9e\x28\xcc\x5b\x8d\x21\xf4\x76\x27\xcc\xed\x4e\x98\xdf\xaa\x6a\xc5\xca\x6c\xcd\xca\x09\x81\xef\xb3\x32\x7b\xc3\x4a\xb2\xdd\xaa\x2b\xba\xfb\xbb\x96\xa7\xbd\x95\x3b\xab\x56\xda\xf4\x84\x91\xc4\x5c\xcd\xcd\x4b\x99\xcb\x9c\xd7\x78\x37\x37\xef\x90\x93\xaf\xf5\xa0\x89\x43\xd7\xc9\xaf\x75\x55\xc2\x34\xec\xc4\xb7\x5a\xfd\x97\x45\x71\x12\x7f\xd2\x1c\xf0\x5a\x74\xb5\xa2\x92\x7c\xb2\x58\x75\xd4\xb5\x96\xb7\xea\x8c\xab\x7a\x1b\x0b\xbe\x6e\x56\x6b\xf8\xcb\xe7\x02\x46\xc2\x07\x21\x2d\x2b\xbe\x9a\xf1\x4c\x7d\x22\xb6\x86\xef\x75\xc1\x72\x7c\xc0\x50\x11\x6c\x02\x5b\x5a\xef\x64\xc3\x04\x67\x10\x0c\x86\x3f\xf3\x3f\xaf\x4a\x8c\x3a\xc3\x17\x99\xd3\xaa\x50\x7f\x2b\x10\x2d\x9e\xba\x35\x99\x5a\x46\x96\x18\x32\x5f\x2d\xf0\xaf\x5c\x6f\x30\x7e\x5e\xab\x67\x6e\x1e\x84\x30\x10\x2c\x78\x09\x5f\x45\x5e\x7e\x84\xff\x15\x97\x98\xf1\x9a\x09\xb6\xc2\x72\xe2\x6a\x2e\x7c\x49\xc1\x52\x0c\x73\x3d\x53\xef\xbe\xa6\x89\xdc\xf3\x5c\x1e\xcc\xd4\xda\xc7\xf4\xf0\x16\xe0\x25\xe7\x22\xaf\x70\xe1\xe9\x9c\x5f\xc0\xf4\x48\xe2\xcb\x4b\x8d\x4b\x4a\xd4\x9c\xd1\x9e\x86\xab\xcc\xfb\xc1\xb9\x9a\x1b\x12\x51\x55\xf8\x5e\x5e\x8e\xb7\xfd\x9e\x96\x47\x49\xda\xc9\xdd\xc3\xa8\x32\x98\x88\x93\xbc\x7e\xc7\x16\x9d\x3c\x00\xea\xa6\x93\x03\x52\x05\xc7\x7b\x89\x9f\xe6\x82\xa7\xa0\xe8\x80\xbc\xee\xe4\x0d\xe2\x93\x6a\x05\x0d\x06\x48\xcb\x36\xe9\xe9\xd9\xbb\x33\x20\x64\x40\x28\x8f\x92\x39\x26\x6d\x9f\x0e\xd9\xd2\x22\x39\x27\xab\x9c\x50\xb2\xaa\xe0\xa7\x84\x9f\x1a\x7e\x24\xbe\xc6\x45\xf0\x35\x14\x54\x18\xc7\x37\xab\x82\xd0\xb6\xa5\x47\x32\x5e\xa7\x84\x12\x09\x23\x3d\xb9\x98\x36\xaf\xed\x0f\x3e\x99\xf0\xb8\x58\x77\x72\xb3\x2a\x5e\xe9\x37\xeb\xd4\xe4\xb5\xd9\xdc\xcf\x15\xf6\x02\x44\x0f\x1f\x94\x9f\xa8\xa3\xee\x87\x87\x85\x3b\x8f\xa0\x71\x18\x22\x50\xdb\xb0\xb2\xf9\xdc\x33\x3e\x9b\x4a\x3f\xe9\xdc\xf0\x0c\xb7\x3a\x24\x63\xf3\x3f\x27\xf5\xd5\x02\x8a\x09\x66\xe4\x85\x97\xf6\x17\x27\x6a\x0b\xb6\x0d\x8c\xdf\x18\x79\x48\x8e\x34\xe3\x7b\xde\x4e\xd5\xf7\xe3\x94\x14\xef\x7f\xb1\x2b\xf3\x07\x79\x79\xc0\x83\x32\xe1\xe7\xec\x82\xa2\x1b\xff\x51\x42\xf0\xb4\xd1\x3d\x92\x63\x49\x5b\x0b\x9c\xb3\x8b\xbb\x3b\x16\x50\x71\x94\x30\xaa\xef\xcc\x4e\xbc\xfb\xdd\x6d\xec\x40\x25\xff\x55\x42\xbe\x3a\xea\xc8\x93\x8c\xa7\x55\xc6\x9f\x69\xbd\x74\x5a\x9d\xe0\xba\x34\xff\xe9\xd5\xb7\x9d\x32\x98\x94\xee\xac\xd4\x07\xf2\xf5\x82\x92\xc3\xcb\x4d\x25\xa7\x24\x08\x8e\xbe\x22\x5f\x79\x37\xcf\x6c\x3b\x5c\x33\x54\x53\xe9\xf0\x87\x87\x9d\x12\x8b\x72\x24\x7c\xd9\xab\x6e\xa5\x9a\xbe\xda\x2a\x77\xb0\x7d\xe8\x0b\x22\x3e\x22\xd4\x0f\xd9\xc1\x6e\xc3\xfd\x6e\x13\x50\xdb\x62\x70\x05\xde\xe6\x80\xf1\x1f\x7e\x6d\x6a\xe3\x88\x3c\x22\x01\x36\x7f\xf2\xf5\x23\xe2\xbf\x02\xb0\x76\x2b\x25\xaa\xf2\x32\x26\x19\x1e\xed\x6a\x5c\x7e\x6c\x1f\xcd\x52\x01\xee\xee\xec\x4b\x8f\x0f\xda\x52\x84\xe2\x99\x36\xdb\x68\xa9\x50\xcf\x0c\xf7\xd3\x9a\x72\x6e\xbc\x4a\x90\xf9\xfc\x3c\x38\xc7\xee\x7b\x0e\x7c\x99\x52\x9f\x87\x17\x9a\xc7\x8b\x0b\x9f\xcb\xa5\x17\xf1\xc3\x4d\x37\x7d\x70\x7c\xec\x8a\x73\x7c\xfc\xe1\xa6\xcb\x09\x8c\x5c\x7b\x47\x9d\x49\x8f\x36\x87\xac\xc9\x80\x9a\xd1\x6a\x12\x87\xdb\x0b\x3a\xd8\x1d\xed\xf6\x5f\xb9\x50\x52\xe2\xde\x69\x27\xe6\xc2\x85\x07\xe1\x36\xa0\xa5\xd2\x71\x7b\x4e\xf3\x13\xc9\x16\xee\x36\xf4\xbb\x3b\xa2\x86\x99\x26\x0a\xc6\x30\x87\xd9\xd2\xf2\xe4\x1d\xbf\x91\x09\x51\x7a\xaa\x74\x2a\x32\x21\x99\xf9\x04\xbc\xd6\x8e\x09\x49\xd5\x07\xe0\xde\x62\xfa\x89\xc9\x07\x30\x90\x7c\xa2\x73\x81\xb4\xd9\x22\x41\xb6\x20\x05\xa8\x85\x84\xa4\x20\x4c\xcc\xa9\x4a\x51\xc1\x92\x4c\x7d\x10\x65\x11\x0c\xff\xba\x8c\xa6\xd6\x84\x38\xf9\xba\x84\x59\x5d\x30\x2d\x4f\xbe\xab\x32\x9e\x08\xfc\xa3\xe5\x89\x7e\x7e\x38\x11\xe6\x0b\x18\x62\x92\xe9\x50\xe6\x93\xaa\x78\x3f\xe6\x72\xf9\x44\x37\x1d\x9d\x86\x8f\xd2\x2e\x72\x5f\x7f\xa8\x8f\xbe\x5e\xd0\x3c\xf9\x54\x56\x62\xc5\x8a\xfc\x37\xfe\xe3\x32\x97\xbc\x5e\xb3\x54\xdd\x86\x91\xcb\x25\x6e\xcb\xbe\x2c\xb3\x3c\x05\xcb\x40\xe1\x9e\x95\x99\xc3\x6c\x69\xe3\xa5\x2e\xdb\x34\xb9\x5d\x99\x53\x6f\x99\xae\x92\xf3\x0b\xb5\x97\xf8\x4b\x56\x95\x3c\x79\xa0\x7d\x8d\x7f\x91\x6c\xf1\x56\xb2\xf4\xa3\xa3\x17\xac\x96\x58\x30\xb4\x2f\x14\x0e\xef\x45\x14\x0a\xb3\x6f\x13\x55\xaa\xfb\x18\xa8\x4c\xf2\x80\x7a\x8f\xd5\xa6\x1d\xae\x6e\xbe\xe2\x94\x9b\x83\x51\x3a\xc9\x94\x15\xc5\x0c\x32\xe6\x6a\x61\x56\xa3\xd5\xbd\xec\x35\x8c\xf8\xb9\x46\xe9\x3e\xf2\xe4\x31\x9e\x98\xda\x14\x85\x7d\xce\xdf\xdb\xfb\xac\x4a\xc5\x63\x5e\xe6\xb2\xd1\xda\x1b\x05\xe0\x5b\xda\x8c\x04\x13\x9e\xdd\xb7\xd7\xff\x2e\x79\xf9\x80\x66\xbd\x95\x3f\x2f\xb3\x9d\xdc\x31\xc7\xbb\xbb\x8e\x9f\x7d\xb8\xa7\x22\x10\xa3\xde\x56\x7f\xa2\x85\x89\xe3\x50\x10\xec\xe4\x22\x44\x25\x76\xa5\xd2\x8a\xcb\x77\xe2\xa5\x45\x55\x73\xc9\x16\xbb\x2c\x36\x0a\x3d\xf5\x4e\x55\x5b\x01\x9d\xac\xab\x75\x27\x98\x72\xfd\xe2\xba\xe6\x1c\x1a\x83\x5f\xcf\x27\xcd\x16\x8d\x36\x0a\x47\x90\xdf\x34\xc4\x67\xb1\x41\xbb\x55\x98\x0c\x2c\x02\xb7\x1b\x5a\x25\xa9\xd6\xbc\x6c\x14\xc4\x1b\x5f\x4a\x7e\x7d\x60\x7b\x36\x12\xa6\x98\x22\xcb\x32\x28\x62\xa7\x0c\x68\xbb\x68\x7a\xff\xa9\x95\x09\x68\xc5\x3d\x2f\xb7\x35\x0b\xbc\xa7\xb7\x9b\xe3\x8e\x56\xaa\xb8\x3d\x7b\x78\xa8\xd4\x2c\x5e\x16\x8c\x07\x9f\xe4\x69\x89\x83\x4b\xd2\x51\xff\x47\xdc\xed\xd0\x54\x14\xec\x97\x89\x26\x98\x1d\x58\x3c\x4c\x9d\xf0\x56\x28\xe3\x1f\xa1\x0a\x6e\xb4\x57\x47\x6b\x75\xde\x2a\x7e\x1e\xb4\x1b\x7a\xbe\xdd\x69\x28\x5a\xdf\xb7\x36\x97\x9a\xf1\x0e\x0f\xed\x70\x60\x3c\x55\x2c\x4d\x17\xb0\x89\x6b\x14\x45\xc9\xb2\xcd\xb2\x1d\x5f\xda\x5c\xcb\x1d\xae\xe5\x7d\x5c\xef\xed\x83\x8d\x06\xbe\x13\x11\x38\xc3\x29\xff\xee\x31\xf9\xfd\x42\x25\x04\xa6\x31\x8a\xd6\x1e\x10\x3a\x66\x94\x83\xc9\xce\x4e\x29\x8c\x3d\x93\xc8\x76\x81\x76\x94\x19\x26\xf3\xc7\x4b\xb3\x16\x55\xca\xeb\x3a\x2f\x17\xb9\xde\xe5\xca\xab\xf2\x33\x3d\xe5\x8d\x0d\xff\xd2\x85\xdf\xdb\x6f\x9a\x39\x35\xd5\x4d\xbb\xad\xec\x1d\x56\x1a\x23\x45\xd0\x04\x8d\x73\x4c\x56\xad\x9c\x3b\x8e\x79\xcd\xa0\x25\x1b\xcd\xd2\xbd\x9d\xd3\xf4\xec\xf3\x56\x47\x37\xf7\x81\x5f\x40\x17\x3d\x95\xd6\x22\x9c\x98\x9c\xa9\x48\xdc\xbb\xb1\xc7\xd1\xc5\xf4\x77\x95\x9d\x3f\xa4\xa3\xba\xab\x35\xa2\xad\xf0\x1c\x3e\xa0\x7f\x55\x67\x82\x21\x88\x4a\x8b\x07\x38\xdd\x01\xd9\xf0\xab\x44\x50\x71\x52\x82\xd2\xe2\x01\x95\x0a\xad\xdb\xda\x4e\xef\xd9\x6d\x38\x2c\xcb\xac\x0d\xb4\x33\xb4\x98\x36\xc0\x77\x12\x82\x9a\xd9\x76\xc0\xc6\x7a\x5a\xad\x5e\x60\x93\x10\x09\xa3\xe5\x89\x3e\x6d\x9b\x30\x65\x31\xa3\x29\x36\x19\x6d\x2f\xe8\xe8\xbe\x55\x1f\x69\xdf\x95\x3f\xf9\xe5\x17\x5c\x36\xcc\xea\xc6\xbb\xaf\xaa\x47\x5a\x84\xe7\x1f\xd8\xe1\xc9\xde\xa3\xa6\x77\x77\xde\x02\xcb\xf9\xc5\xd6\xdb\x40\xc6\x25\x8a\xc3\xc3\xd6\xc1\x26\x6f\x31\x48\x6e\xfd\x47\x6f\x1b\xf7\x1c\xc3\x3c\x44\x06\xf2\x64\xc9\x6a\xef\x11\xf7\x4e\x89\xde\x43\xe7\xe5\x45\x22\xcf\xcb\x8b\x60\x1b\x20\x8b\xf6\xde\xbf\x26\xe3\xd6\xb6\x13\xa6\x5b\xfb\xcf\xbc\xca\xad\xbe\xf4\xd3\x73\x08\x4b\xf4\x85\xb4\xe5\xa9\x2e\x6b\x2a\x38\xc3\xb3\xec\x93\x8e\xf0\x83\x79\x77\xa3\x61\x17\x0f\xb6\x50\x43\x7f\xca\x90\xae\x50\x49\xbc\x62\xeb\xce\xf9\xb9\xb2\xe5\xa3\x0b\x7a\x6e\x8d\x7e\x05\x28\x83\x1f\xbf\xbd\x69\x03\xc2\x4a\x5d\x76\xe1\x53\x6b\xc5\x1e\x7e\x1b\x3d\x3f\xba\xb8\x08\x68\x7e\x9f\xcd\xab\x05\x83\xa5\xd2\xea\x41\xb7\x68\x67\x31\x61\xcb\x77\x20\xb6\x7f\x07\x7a\xbd\xd1\x21\x6d\xef\xf2\xad\xcf\xfd\xe2\xe1\xfe\xfd\x7d\xd0\x86\xd5\x46\xd6\xa7\xd6\x9d\x7d\xc6\x75\xe1\x64\xc1\x65\xc7\xf2\x1c\xdc\xdd\x45\x5b\xda\xbc\xec\xaf\x75\x65\xde\xbd\x17\x07\xf2\xdd\xbb\x0a\xd5\x76\xe7\x3d\x59\x7b\xc2\x31\xa6\x69\xed\x07\x34\xb2\xd4\xf2\xe3\x7f\x0f\x5f\x82\x5f\xe5\xd5\xa6\x7e\x9b\xcf\x0a\xdc\x17\xfd\x2c\x73\x82\x5f\x7d\x9e\x35\xa8\xc9\xbf\x87\x31\x68\x05\x5f\xc4\x14\x04\xfc\x2c\x53\x4a\x9f\xfe\x3e\x53\x5a\x09\x2a\x83\x4a\xaf\x21\xfb\x89\xd9\x66\x2d\x3b\x8d\x8b\x85\x9d\x07\x87\x0c\x94\x6b\xa0\x5d\xfc\x51\xc6\x61\xe9\x1e\x4e\x13\x1d\x49\xf9\x17\xdd\x34\x09\x2d\x15\xb7\x0c\x3e\x5f\x7a\xc8\xe0\x9e\x72\x63\xde\x5f\x50\x6e\xb9\xed\xe4\xa8\xfd\xcd\xd8\xc1\xa6\xca\x4f\xf0\x8f\x15\xbe\xb1\xde\xb0\x23\x08\x5c\xe6\x94\x3b\x82\x90\xdb\x0e\x83\xbc\xf7\x5a\x30\x49\xad\xdf\xa5\xfe\xab\xb5\x60\x8c\x84\x3f\x57\x13\xf8\x58\x1b\x9a\x86\x9f\xaf\x0a\x6f\x71\xca\x4e\x2d\xff\x54\x3f\x68\xe4\x0e\xc3\xf4\x1f\xc9\xbc\x01\x39\x33\xe8\x6f\xe4\x08\x13\x87\x86\x52\x7f\x19\x4b\xf7\x34\x4f\x5b\x29\x7f\xa0\x89\xee\x2c\xe6\xa4\x53\xf5\xd2\xf8\x1f\x6c\xaa\x6e\x65\x4d\x9e\x1a\x60\xe2\x16\xd7\xf0\x1a\x50\xf8\x9e\xa8\x01\xf3\xfc\xe2\xde\xf6\x6c\x96\x7c\xa1\x69\xf9\xdf\x7f\xbc\x99\x49\xb6\x50\x0e\x18\x9f\x55\x76\x6c\xc5\xef\x53\x73\xc0\xd1\x97\xc9\x32\x05\x59\x9a\x25\xb4\x42\xad\xdb\x8d\xff\xde\x75\x3b\xc9\x16\x50\x2c\xbc\x61\xce\xd4\x47\xe5\xcf\x5c\xf4\x8b\xd1\xe6\x56\x4e\xb9\xef\xed\x30\x01\xe6\x99\x9d\x94\xa1\xaf\xb2\x31\x88\xa7\xf9\x34\x28\x4f\x36\x65\xbd\xcc\xe7\x12\x66\xc4\x79\x92\x1b\x92\x7a\xa3\xa5\x19\x59\x06\xa7\x72\x22\xbd\xc8\xd5\x67\x22\x9b\xb7\x48\xf0\xfd\xfa\x24\xa9\xce\xd9\xc5\x34\x60\x47\x47\xc6\x25\x9a\xb9\x0b\xb1\x94\xa6\x2c\xcf\xd9\x31\xbe\xd9\xee\x9a\x35\x55\xcf\xdf\xd3\x8d\x8a\xae\x23\xa4\x76\x8f\xa5\x08\x1e\x39\x60\x13\x9c\xd6\xd8\xee\xe2\x70\xd2\x9b\xe0\xf1\x85\xd3\x28\x9c\xc4\xdb\xf2\x44\xf0\x55\x75\xc5\xdf\x6e\x66\x35\x97\xf5\xfe\x47\xc6\xdd\xe5\xf6\xc7\xc7\xf2\x51\x12\x4e\xed\x3a\xfd\xb9\x44\x01\xe3\x3d\x25\x8d\x1b\xa7\x3a\x25\x95\xc7\x51\xf0\x28\x09\x03\xe5\x69\x8a\x37\xd4\x47\x7a\xda\xe6\xdc\xa7\x4b\x23\x16\x31\x15\x89\xd0\x00\xde\x7e\x6a\x79\x17\xc1\xa3\xe3\x08\xec\x6e\x3f\x19\x75\x0f\x97\x5d\x16\xdc\xd2\xd2\x5c\xf8\xf6\xb4\x4a\xd1\x2d\xfc\x4d\x55\xa3\x47\x52\x52\x51\xa8\xc7\xfc\x72\xc3\xdf\x56\x42\xee\x59\x17\xc7\xf5\x12\xe5\xca\xd3\xb9\xe7\x39\xfc\x07\xa5\xbd\xd0\xab\x83\x47\xf9\x82\x6d\x10\x04\x27\x75\x25\x64\xa7\xb3\x6f\xde\xac\x9a\xa2\x7d\x82\xfe\xb0\x3c\x3d\x8e\x26\xbd\xc3\x12\x2f\x0a\x0b\xc0\x16\x50\x73\x1e\xdb\x8c\x27\x51\x7f\x7b\x41\xa3\x70\xb7\x97\x78\xb3\x00\xbf\x52\xf4\x86\x56\x7b\x82\x01\x83\x53\xa7\x54\xaf\x77\xc9\x8b\x60\xfb\x87\xf7\x0f\x44\x07\xfb\x97\x3a\x7d\x91\xcf\x6f\x49\x60\x71\x52\xb0\x2b\x2e\x6a\x56\x78\xb8\x15\x2b\xf3\xf5\xa6\x50\xbe\x0e\x0e\x7d\xb9\xe1\x78\xa9\xbf\x87\x2a\xf8\x82\xa5\x7e\x72\x4b\x5e\xac\xb9\xa8\xfd\x0c\x6c\xa7\x0e\x94\x78\x4c\x90\xc9\x98\xba\x14\x26\x51\x44\xdb\x39\x4f\xa2\x98\xfa\xd9\x4e\xa2\x2e\x6d\x94\x62\x12\xf5\x68\x4b\xde\xb4\x51\xa4\x49\x34\x80\x0a\x88\xfe\x5e\x35\xe5\xe4\xa0\xbc\x13\xf6\x2b\xae\xdc\xdf\xa4\xd1\x2b\x80\x7a\x03\x46\xbb\x1a\x48\xb6\xf8\x05\xbd\xe9\xf6\x6c\xeb\xec\x59\x46\xe1\xa7\x6e\x26\xe9\x4d\x3d\xd4\xee\xb7\x0c\x0e\x0f\x79\x47\x6f\xec\x6e\x27\xe4\x1f\x98\xdd\xa9\x26\x4f\x7e\x27\xa6\x34\xee\xd0\xd0\x84\x81\x2d\xdc\xc9\xfa\x0b\x6c\x01\x2b\x38\x15\xda\xee\xcb\x5a\x9a\x5d\x76\x93\x5d\x5a\x95\x92\xe5\x65\xfd\x57\xb2\xcc\xad\x0c\xf0\xdd\xdf\xbd\x19\xe7\xba\xb4\x68\xe5\x62\xf6\x5b\x57\x61\xb5\xef\x75\xbe\x77\x1d\xcb\x65\x5b\xee\x88\xb1\x84\x84\x3b\xa5\x19\xce\xcf\xf9\x85\xcf\xc2\xfe\xf0\x7e\x68\xc8\xc6\x7b\xbf\x2f\x6d\xb8\xc0\xef\x49\x87\xe3\x93\x5a\xb2\x53\x06\xdb\xd6\x33\xbd\x4a\xbd\xeb\x06\xfe\x91\xdf\xd6\x1d\x1e\x9c\xac\xd8\xba\xb3\xf3\x0e\xbe\x56\xf6\xa6\x56\x70\x9b\xf5\x94\x9d\xcb\x8b\x4e\x19\x4c\x6a\xb5\x8a\x11\x34\x9e\x79\x36\x2e\xfd\xa7\x60\x18\x4e\xe4\x89\xe0\xd9\x26\xe5\x9d\x34\xd8\x96\x27\x92\xd7\xd2\xd8\x07\xfb\xd4\x67\xe1\x9e\x9c\xc7\xd7\x53\x3a\x12\x5f\x69\x58\x70\x13\xab\x7d\xaf\x22\x3e\x1c\xd7\xbc\xf1\x32\xfa\x3a\x34\xcb\xde\x5e\x72\x07\xf9\xa9\x30\xca\x3e\xd7\x31\x27\xe7\x17\xcd\xd4\x1f\xdf\xbe\xcc\xee\x3b\x66\xda\xba\x86\xf3\x41\x18\xd0\xa6\x4b\x0b\x6a\x60\x99\x80\xf6\xa5\x90\x55\x99\xbd\x2e\x79\xa7\xee\x90\x3c\x23\x38\x25\xc1\xb3\xa9\x8d\xc2\x3c\xbe\x7d\xa7\x8c\xb3\x3d\xa5\x6a\x67\xeb\x0a\x47\x6d\x41\xd8\x89\xd1\x0f\x1d\x95\x01\xad\xf6\x66\xf1\x0e\xba\xd2\xef\x67\xe1\x4a\xf6\x05\xb9\x42\x83\xf7\x72\x55\x7a\xbb\xad\x87\xdb\xc3\x5c\xfc\xb7\x6c\x74\x2b\xd3\x65\xb7\x1d\xe9\x07\xfc\xd6\x82\x5f\xd9\x95\x4f\x3d\x4b\xc7\xbf\x80\xaa\x7f\xe5\x1f\xc3\x6f\xa4\x5e\x57\xc0\x3f\xb7\xfe\xee\x1e\x5a\xd2\xfe\x05\xc6\xf4\x9a\x4a\x6b\x8b\x34\x6c\x1e\x1e\xd0\x08\x24\x60\x5d\x3a\x3e\xd7\xc4\x1b\x99\x4e\x51\xe4\x8a\x47\x69\x06\x10\xe9\xf3\x3c\x45\x9f\x15\x15\x47\xda\x5b\xf5\xec\x5a\x8d\x35\x3c\xed\x6b\x82\x79\x52\x39\x86\xf3\xf3\xbc\xc5\xe9\x05\xee\x8e\x94\x27\x6c\xbd\xe6\x65\x86\x66\xec\xae\x2f\x8d\x4b\x9f\x46\x4d\x0f\x12\x5c\x5a\x96\x81\x73\xd8\xb0\xf3\xc3\x1d\x37\x93\xe3\xf8\x62\x6a\x8a\x46\x75\xa9\x4b\x2a\xdd\x32\x9c\xc7\xc7\x5e\x49\x99\xc2\x51\x61\x64\x81\xac\x61\x7c\x61\x52\xe4\xba\x4e\x55\x1e\x7a\x05\x50\xdf\x54\x61\xc4\x66\x26\x6b\x55\x52\x3a\xd1\x54\xa6\x2e\xab\x86\x84\x44\x80\x17\x19\xab\x43\x9e\x07\x25\x28\xe0\x76\xe1\x81\xed\xb5\xe0\xbf\xcb\x37\xee\xed\x99\x69\xa2\x97\xb3\x30\x39\x8b\x76\x2b\xc2\x9c\xf7\x36\x60\x75\xc9\xb1\x29\x5e\xa3\x0d\x19\x91\xa2\x3b\x17\x96\x57\xfb\x50\x46\xdd\xff\x43\x53\x2f\x5a\xd2\xdc\x59\xa8\x0c\xa6\x60\x75\x12\x4e\xeb\x87\xf6\x5d\xc6\xda\xf8\xec\xa5\x89\x3c\xaf\xd5\xe4\xac\x93\xe2\xb5\xf5\x4a\xaa\x69\x40\x8f\x8f\xf3\x87\x49\x18\x98\xd3\x71\xb8\x2f\xda\x9c\x6b\x41\x84\xb4\xdd\xcc\x1e\x85\x2a\xe5\x02\x6d\x6f\x47\x46\xa6\x20\x19\x96\x30\xfd\x78\x40\xa7\x08\x68\x27\x3f\x4e\x0a\x73\xce\x0c\xf2\x6b\xce\x28\xd8\xb6\xd4\x6a\x6e\xcf\xe5\x27\x5f\xa0\x2f\xd5\x45\xb1\xa8\x2f\xef\x1f\x1d\x2a\xf7\xe6\x22\x2d\x71\xa4\xc0\xc9\x8a\x1e\x32\xf6\xf5\x49\xe7\x0f\x19\x4e\x4b\x27\xd6\x52\x3d\xc5\xc9\x3b\xb8\xa9\x60\x0f\xff\x9e\x97\xee\x99\x79\x5c\x9c\xb1\x69\x27\xde\x12\xfa\xfe\xd1\xf3\x41\xe8\x5f\x16\xab\x1c\x4f\xf1\x54\x6b\xe9\x1e\x6c\xcc\xa7\xcc\xd4\x27\x4e\x51\x2f\xa6\xc6\xc1\x12\x1f\xd7\x93\x9d\x3a\x38\xcd\x93\x7a\x52\x1d\x1e\xee\x2c\x19\xe1\xe5\x7b\x79\x02\xd9\x3b\x5a\x10\x04\xee\x64\x23\x2d\x4f\xf8\x4d\x5e\xcb\x7a\x97\xdf\xf6\x39\xc2\x72\x8f\x4f\x68\x79\x5e\x61\xfb\x72\x3e\x9f\xc8\x52\x1e\xdc\xdd\xe5\xfb\x98\x81\x84\x73\x9f\x13\x6d\x7e\x84\x9a\xa3\x07\x91\x91\xdf\x59\xf3\xcc\x7d\xa3\x5a\xd4\x7b\x8e\xfa\x6e\xe9\x60\x5a\x19\xc6\x9c\x4e\x56\x6b\x02\xc1\x34\x87\x56\xed\xb1\x96\x7b\x4e\x78\x7b\x19\xb4\x0b\x0a\xfa\x36\xfa\xca\x67\x97\x72\x4c\x45\xeb\xa6\x3c\xf0\x7c\x4f\xf7\x4f\x34\xf7\x1c\xe9\xdb\xb3\xc5\x96\xaf\xd6\x95\x90\x4f\xd5\x3e\x9d\xbf\xd7\xe5\x6c\x4b\x98\xf8\x3b\xa5\x71\xca\xf1\x70\x10\x5e\xa2\xcb\xb7\xdb\x3f\xbb\xa3\xd4\xd2\x33\x34\x4f\x70\x86\x98\x55\xab\xe3\x9a\x8b\x1c\xbd\x29\x04\x09\x82\x29\xda\x38\xaf\x37\x92\x8b\x17\xef\x5e\x7d\x9b\xe4\x66\x4f\x51\x19\x3f\x2f\xcb\x52\x13\x9a\xf5\x65\xed\xeb\xf6\xf2\x8f\x93\x7b\xd3\x08\xf6\x5e\xc4\x69\x64\x88\xc9\x6d\x83\xe0\xe4\xd7\x2a\x2f\x3b\x84\x04\x13\x42\xb4\xe1\xf5\xce\x77\x0d\x81\x66\xeb\x9e\x5a\x6d\x29\x84\x53\x89\xb9\x71\x2f\x15\x37\xe1\x3a\x25\x33\x75\x02\x1f\xa7\x5d\xa7\xe4\x43\x49\x26\x60\x77\xd8\x9a\xc7\xb0\xe8\x3b\x07\xa1\x77\x49\xc0\x87\xca\x04\xaf\x14\x26\x64\x4f\x83\xa0\x6d\xc9\x4e\xb0\x8d\xec\x71\xbe\xff\xf3\xe3\x46\xdb\x5b\x7f\x7a\xbf\xa3\xe2\x81\xe9\x18\xea\x6d\x36\x5d\xbc\x7d\x1e\x8d\x6a\xc3\xb0\xe1\xae\xa8\x4a\xbc\xd7\xfd\xb1\x39\xb3\x56\x29\xef\x71\x63\x31\x69\x3b\xcf\x15\x17\xc3\x6b\x30\xfb\x18\xd7\xe2\xf1\x3d\x20\xfc\xd5\x19\x73\xc5\x07\x31\x55\x44\xd0\x60\x6e\x7b\x85\x82\xec\xf7\xb8\x82\x36\x17\x82\xac\x47\x9c\x49\x4b\xaf\xc0\xfb\x43\xb2\x17\xaa\xb1\xef\xe7\x2f\x3c\xf8\xa7\xa7\xcd\x1c\x13\xfa\xb4\x99\x6e\xca\x8b\x3f\xbe\x86\x84\x1d\xc0\x39\x44\x2a\xf8\x8d\xb2\x5a\x2a\x05\xe9\xad\xb7\x7a\x8f\x83\x46\xe5\xcd\xd6\xe4\xa9\xe8\xc8\x60\x82\xb7\x9e\x62\xbc\x33\xe3\x92\x8d\x7b\x57\x49\xae\xea\x44\x61\xf7\xf6\xf2\x07\x0f\x54\x21\x75\xfc\xd6\x2c\xcb\x2b\x3b\x2e\x7d\x6b\x8b\x69\x8f\x93\xe9\xff\x22\xed\x68\x97\xde\xd6\xf5\xd7\xc6\x81\x58\x1f\x6c\xb1\xaa\x52\x93\xd5\x92\x99\x25\xb2\x06\xf1\x66\x55\x58\x4a\x6d\x28\xca\xcf\xfa\x17\xf8\xd1\x77\x16\x78\x66\x5e\x7a\xef\xa2\x81\x52\x5d\x77\x24\xa0\x65\xb2\x41\xa7\x13\x74\x0b\xf8\x9e\x2f\x9e\xdd\xac\x3b\xe4\xb0\x73\x3a\x21\x47\x1d\x79\x94\x90\xbb\xff\x38\xbf\xf9\xe9\xe2\xfc\xc3\x87\x8c\x1d\xcf\xcf\x8e\x9f\x5f\x1c\xdd\xfd\xc7\x87\x0f\xd9\x11\x09\x8e\x48\x30\x25\x94\x2c\xdc\x3b\x26\x7b\x44\xea\x9e\xaf\x32\x2e\x6e\x02\x26\xd4\xdb\x52\x7b\x88\xff\xf4\xea\xdb\x24\xed\x30\x33\x10\x04\xd4\x10\x40\x5f\x43\xe4\x54\x26\x69\xa7\xb2\xf4\x9d\x0d\x1e\xbf\x43\x3c\x94\xa7\xd1\xe4\x38\xda\x36\xce\x5b\xec\x2e\xb5\xb8\xa5\xa0\xff\x50\xba\x3a\x5d\x32\x71\x26\x3b\x51\x70\x4a\x7e\x6a\x60\xe2\xe0\xee\x8e\xdc\xb4\x50\xa7\xb5\xe1\xa6\xb3\xfb\x1c\x79\x17\x9f\x22\x0f\x26\x9f\x0b\x13\x07\x34\x0a\x83\x60\xc2\xcf\x8d\xe9\x11\xd1\xe3\x28\xb8\x70\x52\x69\x0e\x82\xfe\xc5\x04\x7e\x3d\xda\xe1\x53\x2f\x6d\x17\x01\x6d\x56\x74\xb5\x1b\xc0\x3c\x74\xd5\x32\x47\xf9\xb9\xc0\x75\xaa\xf3\xf2\xe2\x14\xcd\xd2\xa3\x84\x4c\x4f\x09\x15\x47\x47\xc1\xc4\xc0\x44\xef\x82\xef\xb6\x14\xe9\x1a\xd4\xd1\x9e\x16\x33\x3d\x55\x6d\x66\x7a\x1a\xa8\x06\x43\xeb\x64\xe3\x57\x6a\xb3\xc5\xea\xca\x99\x12\x9c\xc4\x6a\xa1\x1d\x47\x81\x7e\x78\x66\x0a\xf1\x61\xb0\xf9\x23\xad\x8e\xd1\x14\x9d\x66\xd4\x68\xba\xd3\x6b\x26\xd1\x88\xee\xef\xa3\x93\x38\xa6\xfb\xba\xe7\x24\xee\xd2\x9d\x9e\x39\x89\x7b\xa0\x8f\xbe\xcc\x21\xea\x7f\x83\x3e\x52\x82\x30\x6a\x65\xea\x9c\xbc\xda\xcb\x33\x8f\x12\xbc\x32\xe6\xf0\x90\x3f\x4c\xf0\xa9\xef\xbb\x3b\xfe\x48\x5d\xa6\x12\x99\xdb\x46\x3e\x6c\xe6\xf3\x79\x46\xa6\x78\xaa\xc3\xd6\x2e\x7a\xb8\x5a\x08\x5d\x28\x95\x4a\x22\xee\x06\x12\xfb\x00\x37\x37\x0f\x70\xcb\x7b\x9e\x77\xde\x7d\x90\x9b\xfb\x0f\x72\xf3\xe0\xde\x98\x66\xb1\x6b\xa7\xdc\x93\x38\x82\x4a\xdb\xb3\xe3\xf9\xbf\xa8\xd2\xd2\xce\x3d\x43\x81\xd3\x9c\x79\x52\x74\x2a\xa8\x43\x7b\x90\x26\x59\xe2\xfb\x39\xba\xdb\x36\x93\x68\x8f\x44\x2e\x9d\x3a\x29\x3a\x6c\x7f\x9f\x3c\x68\x0d\x23\xa8\x55\x02\xb3\x56\xdc\xd9\xe7\xc8\x77\x20\xcf\xf9\x79\x79\x71\x91\x90\x43\x72\x54\x1e\x91\x29\xa1\x72\x1b\xd0\x4f\xdb\x60\xef\xe2\xf6\xf9\x05\x85\x69\xd9\x74\x7f\x7e\xf3\x4a\x3c\x63\xe9\x72\xaf\xa9\xef\x5f\x16\x76\x2a\xd5\xcc\x8a\x7c\xf8\x40\x8e\x78\x30\xb1\xce\x95\x5b\xf4\xb4\x34\x5b\xbd\xe4\xdc\xa9\x2e\xd0\x5c\x17\x30\x1e\x3a\xe5\x56\x7a\xc3\x24\x68\xad\xad\x11\x2d\xaa\xe7\x25\xbe\x56\x84\xb2\xdd\x24\x5f\x9f\xff\xf7\x87\xf0\xf8\xc3\xcd\xf0\xf9\xc5\xd7\x0b\xba\x4e\xbe\x3e\xff\xb0\x79\x3a\x0a\xc3\xe3\x0f\x9b\xa7\x8f\x9f\x3f\xbf\x00\xf0\x89\x02\x9f\x3f\x7f\xde\xb8\xb2\x6a\xee\xa9\xbc\xc3\xff\xb8\x51\xe7\x9a\xbc\x1b\xce\xdc\x83\x5d\xd1\x00\x80\xf7\xeb\xb5\x79\xb0\x04\xa4\xd9\x38\x26\xe5\xed\x72\x60\x52\x9d\x28\x8c\x7b\xff\xe8\xb4\x52\x54\xb7\x3f\x05\xcd\x8c\xa2\x40\x5d\x04\x75\xa4\x6e\x5b\xfa\xe2\x5c\x97\xbf\xb7\x9d\xe1\x4e\xcc\x49\xda\xd9\xb7\xa1\x04\x36\x6b\xe0\x34\xf5\x9a\x66\x0e\xd8\xd0\x79\xb0\xc5\x5d\xb5\x99\x6d\xdd\x75\xca\xd6\xf7\x18\x85\x26\xda\x8c\xce\x3f\x9b\xa0\x53\x04\xf7\x2b\xfb\x96\x52\x8f\xf7\xec\xf5\xfe\x95\x65\x39\xa5\x81\xdc\x46\xa3\x6a\x59\x44\xe9\xe0\xb4\xe9\xb3\xeb\x04\xac\x9f\xab\x4f\xc2\x53\xe1\x0c\xa8\x89\xf0\xcc\x86\x40\x4f\xc3\x14\x46\x5b\x50\x7f\x2e\x29\x15\xd9\x24\xa8\x18\xfc\x9d\xa4\xbc\x53\x7c\x93\xca\xeb\x2d\x98\x88\xde\xde\x69\x17\xd7\xa9\xab\xdc\x7d\xd3\x46\x5f\xcb\x3d\x80\xda\x26\x90\xeb\x8f\x46\xd8\xde\x4e\x60\x0b\xf4\x1b\x24\xad\x15\x1b\x95\x31\xf5\xcd\x52\xe6\xbe\x1b\x56\xa9\x25\xe8\x0c\x76\xec\x55\xb6\x83\x6a\x84\xea\xdd\x9f\x40\xff\x7e\x52\xef\xcb\x12\xef\xff\x7e\xb0\x9f\x76\x18\xfd\xe9\xd5\xb7\xbe\x5d\x44\x26\xd1\x90\xba\x3a\x9a\x44\x63\x68\xff\x7b\xb6\xda\xbd\x5b\xa5\xc2\x09\xe8\x8d\x2e\x8d\xe2\xd1\x64\xd4\x1d\xf4\x68\xd4\x0d\x27\xa3\x38\x1a\xd1\xa8\x1b\x4d\x7a\x61\x4c\xa3\x6e\x3c\x19\xc5\x31\x7c\x74\x27\xa3\xb8\x1b\xd2\xa8\xdb\x03\x0c\x84\xed\xc3\x47\x9f\x46\xdd\xc1\x64\x18\x01\x65\x38\x19\xc5\x3d\xf8\x18\x4d\xba\x7d\x88\x33\x06\xc4\x98\x46\xbd\x70\xd2\xed\x8e\x68\xd4\x8b\x27\xdd\x51\x44\xa3\x1e\x44\x8d\x06\x34\xea\x0d\xe0\x63\x48\xa3\x1e\xc4\x8d\x43\x1a\xf5\x46\xf0\x01\x61\x20\x72\x3c\xa0\x51\x1f\x79\x8a\x68\xd4\x8f\xe0\x23\xa6\x51\x3f\x9e\x0c\xbb\xf0\xdf\x9d\x8c\x7a\x23\xf8\xe8\x4d\xba\xfd\x2e\x8d\xfa\x90\x6e\x3f\xa4\x51\x7f\x30\xe9\x76\xc7\x34\xea\x8f\x26\x5d\x0c\x30\x9e\x74\x87\x03\x3d\xf5\x8c\xf7\x6c\x8d\x79\x52\x39\x63\xe9\x46\xf2\x09\xf9\x70\x93\x46\x84\x32\x0b\xf1\x88\xd0\xb3\x99\xe0\x57\x00\x6d\xc2\x28\x8c\x09\x65\x3e\xdc\x25\x94\xa5\xf0\x1d\xc7\x5d\x0e\xdf\x99\x06\xe6\x00\x3c\x33\x94\x0f\x9b\xb0\xdb\xed\x12\x7a\x96\xe6\x22\xc5\x6c\x20\x21\x03\x70\x04\x74\x96\xb3\x1e\x04\xbb\xc5\xf4\x7b\x51\x08\x14\x0d\x74\x43\x42\xcf\x9e\x15\xf9\x02\x13\x18\x10\xca\xb8\x06\x38\x00\x73\xcc\x2c\x1c\x00\xcb\x73\x01\x40\x36\xea\xf6\x3f\x6c\xb2\x2c\xec\x01\xb9\x81\x8a\x38\xa1\x67\x0b\xc1\xae\x54\xa1\x21\x1b\x0b\x71\x80\x0a\x3e\xaf\x6f\x57\x98\x64\xd4\xed\x23\x62\xbd\x74\xe0\x99\xba\x0b\x05\xca\x35\x06\x89\x39\x70\x06\xf9\xaf\x58\x2a\xb4\x84\x20\x31\x0f\x8c\x10\x2c\x16\x98\x14\x43\x31\xad\xd6\x13\x72\x48\xe8\xd9\xab\x37\xf8\xcf\xca\x8c\x95\x4a\x8c\xac\x0f\x59\x59\xa0\x8b\x44\x25\xd3\x78\x88\x80\x21\xa5\x08\xd5\x45\xb5\xe6\x1a\x33\x42\xcc\x95\x86\x18\x40\x0b\x1d\x35\x44\x40\x05\x1c\xb3\x1e\x42\x05\x6f\x10\x57\x75\xc6\x98\x0e\x30\xb2\x98\x99\xc6\x8c\x2d\x26\xd5\x18\x66\x31\x99\xc6\xcc\x2c\xc6\x64\x94\x5a\xcc\x5c\x63\x32\x8b\x59\x68\x0c\xb7\x98\xa5\xc6\xcc\x0d\x46\xf3\x17\x21\x2c\xa4\x02\xa3\xb9\x06\xaf\x14\x6f\xf1\x8c\x5b\x84\xe6\x64\xac\x72\xa9\x75\xf5\xc5\x71\xac\x60\x89\x35\xdf\x47\xe0\x37\x26\xb0\x82\xe2\xee\x30\x25\xf4\xac\x5a\x54\xa5\xae\x2f\x90\x8e\x07\x42\x7d\x54\xeb\xb9\xdf\x94\xba\x20\x9f\x16\xae\x0f\x79\xac\xa1\x81\x2b\xf9\x0f\x80\xcd\xb5\xca\xbf\x07\xe1\xd7\xaa\x6b\xb0\x21\x88\x5b\xd7\x59\xdc\x03\x29\xae\x73\x5d\xd2\x1e\x48\x70\x5d\xd5\x13\xf2\x15\xa1\x67\xeb\x75\x71\xfb\x5c\x77\x60\xd7\xd0\xd9\x7a\x2d\xaa\x1b\x3f\x5d\x80\xf9\xa5\x4b\xef\x4c\xe0\x55\x62\xba\xa4\x06\xe0\x50\x8e\x3a\xf5\xbb\x44\x3a\x86\xfa\x69\xe1\x66\x03\x08\x57\xe7\x0b\x95\x67\xdc\x07\x71\x80\xe4\xfe\x01\xff\xb7\x2b\xbf\x48\x00\xda\x9c\x33\x42\xcf\x64\x5e\x64\xaa\x7b\x41\xc3\xb5\x10\x07\x3d\xb0\x59\x15\x48\x81\xf4\xf4\x37\x87\xef\xeb\xb4\x2a\xf3\x52\x57\x2e\x68\x0c\x76\x6d\x40\x16\x45\x84\xce\x58\xfa\x31\xad\x4c\x4b\xee\xa5\x0a\xc3\xd7\x75\x5e\xe8\x3a\xea\xce\x07\x0a\xb9\x16\xf9\x4a\x09\x36\x84\x1e\x0b\xa8\x3a\x5f\xe9\x94\x33\x8b\x30\x2c\xa7\x19\xa1\x8f\x01\x55\xb0\x5a\xb7\x94\x68\x00\x28\xa1\xfb\x10\x1f\x42\x1c\x71\xc5\x75\x6d\xcd\x30\x0d\x71\xcd\x55\x7d\x75\xa1\x6d\x3c\xf6\xe1\x81\xa1\xeb\xae\x86\x21\x66\x33\xf1\x51\x41\x33\x0d\x49\x87\x81\x18\xcd\xd2\x3d\xb6\x9a\x10\x0a\x6f\x35\x21\x00\xd9\xe5\xa6\x52\xc5\x03\x65\x36\xe3\x29\xdb\xd4\xba\x74\x7d\x03\x73\x87\x78\xdc\x46\xcc\xf8\x6a\x2d\x6f\x55\xe1\xc6\xb3\x10\x10\xeb\x3a\xf7\x64\xc8\x45\x59\x6d\x94\xca\x8b\x81\x15\x84\x8b\x22\xaf\x7d\x9c\x34\x5a\x30\x86\x18\x06\x9a\x29\xc8\x28\x4c\x4c\x4d\x5e\x73\xae\x9b\xd1\x00\xa2\xb6\x74\x34\x70\xd4\xd2\xd1\x73\x42\x67\xf9\x22\x35\x1d\x07\xc6\x0c\x80\xd5\xa8\xb1\x89\xfb\x5c\x07\xd8\x98\x00\x5d\x84\xab\xac\xd2\x2d\x06\x94\x2f\x20\xd6\x85\x16\x0d\x03\xfd\x0b\x18\x7d\x19\x19\xa2\x54\xb2\xf5\xa5\x49\x87\x61\xcd\xe5\x8b\x5a\x32\xd5\x7d\x07\xc8\x5c\xbe\x90\x22\x47\x4d\x99\x55\xd7\xaa\x20\x7d\x6c\x03\x8e\xa0\x13\xe8\xcf\x14\x23\x1b\x2f\xdf\x1e\x62\x6c\xe3\x49\x15\x1f\xae\x71\xc4\x30\x06\xcd\x3e\x32\x51\x5d\xab\x1a\x09\x21\xe9\x82\xa5\x1f\x8b\xea\x37\x6e\xb5\x35\x9f\x69\x6c\x7d\xb9\x61\x42\x21\xfb\xa0\x7d\x11\x69\xf8\xd0\x5c\xf4\x5a\x68\x8f\x6f\xde\x22\x15\x7c\xae\x64\xd6\x47\x29\xfb\x24\xa1\x6e\x57\xc3\x68\x23\xa4\x95\xaa\xbd\xf6\x62\x28\x66\xf1\x31\x8a\x15\x15\x9b\x40\xf1\x31\xea\x69\x30\x42\xb0\x6b\x40\x0c\x5c\xa5\x2a\x6e\x7f\x04\x49\x95\x7c\x42\x12\x68\xc1\xa0\x8f\x66\x25\xbf\xdc\xe4\x57\xba\x85\x44\x16\xfd\x9d\xa9\x4d\x0e\x12\x29\x35\xd4\x05\xd3\xe0\x71\x5b\x15\x8f\x09\x9d\xb5\x55\x31\xe4\xab\x23\xc5\xac\x8f\x80\xac\x56\x3e\x7c\x2d\x73\x53\x09\xc0\x55\x75\x33\xd3\x3a\x75\x9c\x62\x82\x37\x59\xa1\x98\x86\x3c\x01\xfc\x56\x81\x7d\x8c\x7d\xf3\x54\x53\xfb\x03\x05\x1a\xea\x50\x05\x56\x6d\xa8\x1f\xa6\x0a\xfc\x5e\x53\x63\x15\x58\x53\x15\x97\x37\x4f\x0d\xb5\x87\xe0\x52\x47\x55\xd9\xbe\xd0\x34\x05\x2d\x95\x9a\xe9\xc7\x2a\xdd\x17\x1a\x1c\xe8\x98\x4f\x35\xa8\x58\x7c\x61\x40\xc5\xe2\x52\x75\xeb\x7e\x57\x05\x7e\xa1\xc1\x81\xe2\x78\xf9\x5e\x83\x4a\x18\x2f\x0c\xa8\x64\xb1\xca\x4b\xa3\x67\xc6\x73\xc4\xd8\x56\x1e\x8f\x39\x22\x5c\xe7\x8a\x99\x62\x76\x63\x04\xa8\x92\xdc\x18\x11\xcd\x10\x7c\x6f\x04\xa8\x8a\xf2\xde\x50\x33\x15\x58\x8b\x28\x52\xcc\x6e\x8c\x88\x54\x52\xef\x8d\x00\x15\x77\xef\x0d\x95\x21\x78\xa5\x05\xa8\x84\xfd\x83\xa6\x45\x8a\xa6\xa5\xdb\x55\xb9\x5e\x69\xf1\x0e\x54\xcc\x1f\x34\x75\xa0\x58\xfc\xc1\x50\x75\x60\xcd\x71\xac\x78\xba\xd2\x1c\x0f\x54\xca\x3f\x68\xea\x40\x67\x6b\xa8\xaa\x8e\xaf\x4c\x79\x74\x52\x86\x63\x25\xbb\x1f\x4c\x79\x94\x6c\x7f\xd0\xd4\x01\xc8\xb1\x3d\xa2\x59\x3b\x3c\xce\x46\x84\x3e\x6e\x82\x33\x71\x35\x43\xfd\x75\xc3\xa0\xd2\xdb\x03\xfb\x90\xd0\xc7\x1a\xa7\x54\xf9\xac\xe6\xab\x5c\x25\xde\x83\xbc\x9b\x63\x65\x6d\x72\xc6\x71\x72\x56\x57\x85\xb6\x05\xc1\xac\x00\x70\x42\x3e\x7c\x50\x5f\xcb\x7a\xa3\x68\x43\xec\x4d\x9b\x42\x49\x23\x04\xbb\x0b\x20\x2e\x7d\xd8\x9a\x10\x5c\x41\xda\x2e\x62\x1a\x34\x96\xd1\x9c\xd0\xc7\x1b\xcf\xbe\x30\xe4\x4b\x47\x7f\x62\xa6\x10\x60\xa7\x0d\x08\x4d\x7d\x78\x08\xf0\xda\xda\xd5\xbd\x1e\xc2\x33\x61\x75\x7e\x6f\x8c\x18\x33\xd8\x30\xb0\xbe\xec\xc8\x13\x8f\x21\x79\x0d\x64\xb1\x0a\x69\x63\xaa\xb4\xed\xa0\xd3\x0b\x31\x70\x2e\x59\xf1\x34\x9f\xcf\xb9\xe0\xa5\xcc\x59\xa1\x7a\x60\xd4\xeb\x63\xe8\xda\x24\xfc\x61\x33\xe7\xd0\xbf\x53\x26\x8c\x60\x7a\x11\x82\xda\x9e\x89\xd3\x21\xa4\x77\x5b\xf0\x5b\x33\xf0\x66\x84\xa6\x36\x0d\x06\xb6\xd6\x13\x17\x3e\x02\x45\x93\xfa\x30\xd2\x79\x96\x2b\x8b\x0b\xb8\xb5\x10\xd8\x34\x4f\xcc\x80\x1a\x46\xe1\x08\x88\x0e\x84\x62\x37\x0c\x32\x60\x34\xdd\xd8\x9c\x53\x0d\xd6\xaa\xa9\x30\x50\x4d\x4f\xb4\x20\xc2\x28\x64\x84\xa6\x0e\x02\x81\x9a\x7c\x61\x20\x79\x02\x40\xc1\x0c\x98\x36\xcc\x11\x90\x31\x5e\xa5\xf8\xe1\x86\xe9\x6f\x2e\x54\x5a\x37\xd0\x76\x9f\x20\xe2\xa9\x43\xa4\x4d\xdb\x01\xa6\x31\x4f\xe6\xc2\x09\xec\xc9\x0b\x63\x3c\xc1\xcc\x29\x5d\x1a\x08\x6b\x6f\xc9\xf5\xb0\x34\x8c\xba\x1a\x5c\x31\xe1\xa1\x9e\x2c\xb5\x61\xc4\x30\xb8\x06\x50\x96\x46\x5a\x31\xcc\x48\x01\x32\x6d\xb2\xaf\xa9\x05\x67\x42\x54\xd7\x76\x84\x8d\x66\xac\x41\x70\xe3\x6b\x34\x9b\x19\x4a\x86\x56\x36\xea\x54\x87\xb3\x96\x4f\x3c\xb6\x49\x64\x99\x35\x57\x61\xa2\xf3\x04\x91\x4f\xcd\x78\x37\x1e\xdb\x70\xdf\xa3\x2c\xb9\x85\xdf\xaa\x31\x1c\xfa\xa8\x8a\xf4\xca\x53\xec\x03\x83\x7c\xe3\x74\x7b\xdf\xe0\xde\x39\xf5\x3e\x56\x65\xd4\x96\x83\xe2\xf4\x99\x56\x0c\x5d\x84\x78\x43\x18\xf3\xd2\x59\xf3\x21\x62\x56\x7a\xba\xc3\xc0\x98\x4b\x73\x51\x9b\xe4\xc6\x60\x88\x3c\x01\x83\xe1\x3a\xc7\xdb\x73\x65\xb5\x11\x2f\x4b\xc9\x17\x82\x15\xba\x39\xaa\x10\x35\x7f\xb2\x11\xc5\xad\x7a\xc8\xe7\xbf\x36\x95\xd4\x3a\x32\xca\x7c\xb2\x4f\x00\xa9\x14\x9b\x99\x2a\xc4\x00\xf4\x32\x82\x9b\x5c\x7a\x98\x0a\x67\x14\x13\x42\x9f\x54\x7a\x6e\x11\xc7\xdd\xa1\x06\xf5\x2c\x7b\xd8\xd3\x01\x4d\x31\x2d\x7c\xe9\x23\x56\x2b\x36\x21\x54\x7f\xc9\x09\xf9\xff\xe3\xa7\xd6\x27\x60\x92\x02\x34\xd7\x79\xc0\x18\x09\xb0\x72\xdd\x68\x86\x29\xf8\x8d\x16\x3d\x2e\xc5\x78\x73\x85\xbe\x82\xac\x16\x1a\x40\xe1\xab\x72\x21\x36\x36\x91\x01\x26\xe2\x7a\x73\xcc\x31\x88\x83\xe7\x08\xef\xca\x19\x02\xa6\x6d\xb3\xaa\x07\x81\x15\xce\x30\xb3\x16\x95\x9e\xbb\x42\xe5\x3e\x41\x78\x93\x4a\x87\x4a\xab\xf5\x2d\x36\x43\x50\x2c\xaf\xdf\xfc\x6c\xbe\x01\x5f\xeb\xce\x1a\xa1\x88\x37\xd0\xbd\x7f\xa7\xf6\xa1\x92\x84\x99\xb8\x47\x30\x9d\x4a\x45\x55\xd7\xba\xd7\x42\x32\x16\x64\x58\xb6\xf6\x84\x17\x8a\xd5\x1e\x17\x41\xf8\x66\x00\x63\xe9\x5c\x41\xba\xb6\xb3\x08\x41\xad\xf7\xb3\x50\x41\x86\x08\x22\x90\x46\xfe\x31\x36\xe7\x4d\xc6\x84\x50\xec\x8e\xbb\x23\x83\xd0\xed\x1b\x86\xf0\x74\xc3\xd7\x42\x0f\x2b\x1c\xc1\x5a\xf7\xf0\x0c\xe3\x17\xae\x78\x03\x03\xaf\x75\x74\x18\x05\x36\x30\x84\xd9\x21\x0b\x73\xf0\x86\x30\xe8\xc5\x9b\xb5\x1d\xb8\x7a\x2a\x86\xae\x53\x86\x44\x9d\x59\x57\xc5\xb4\x43\x1a\x43\xd8\x16\x66\xa4\x62\x56\x7a\x35\x03\x1b\xdb\xc6\x8e\x61\xcc\x8e\x61\x1b\xaf\x3a\x86\x06\x5e\x69\x7e\x53\x44\x14\xb7\xfc\x72\x2d\x78\xea\x17\x1a\x91\xf5\x26\x6d\x14\x5d\x14\xb7\x6e\xb6\x64\x82\xf9\xf3\x25\x15\x4a\xe0\x9c\xf2\x86\xf5\x10\xba\xda\xd1\xb5\x03\x1f\xef\xab\x5a\xe4\xaf\x95\x83\x99\xbb\xab\xc4\x9b\x6b\x11\x50\xbd\xd7\x0e\x84\xa6\x70\x5b\xa4\x12\x87\x91\xb8\x0b\x43\x4c\xc6\x16\x0b\x2e\xb4\x71\x13\x12\xfa\xd4\x87\x23\xa0\x17\x6e\x4a\x3c\x02\xd8\x08\x0b\xe6\x46\x4f\x2d\xc4\x20\xec\x99\x81\xa0\x6e\xac\x8e\x0f\x23\x4c\xb7\x5e\x9a\x35\x89\x9e\x22\xea\x59\x13\x83\xb0\x8d\x49\xe4\x1c\x10\x05\xd3\x43\x54\x96\x11\xfa\xd4\x37\x0d\x38\xa1\x99\x0f\xcf\x81\x6e\x56\x1c\x20\x6d\xbb\xe2\x00\x40\xd6\x2e\x90\x2b\x41\xca\x08\x7d\xea\x99\x38\x7a\x61\x32\x82\x36\xf8\xf4\x69\x25\x05\xd3\xf3\x95\x71\x84\x11\x2b\x59\x6b\x15\xc9\x86\x43\x42\x33\x8e\xcb\x52\x33\x28\x1d\xd7\xfd\x1b\x6c\xb6\xa7\xbc\xb0\x0b\x0c\xc0\x81\x03\x67\x08\xfa\x26\x03\xa4\x3b\xcf\x6b\x5d\xc1\xe3\x21\x94\xa5\xb5\xc6\x00\x39\xb5\xec\x04\x88\xf5\x42\xcf\xf3\xc7\x30\x5b\xca\x96\x4c\x77\xd9\x08\x86\x30\x00\x4d\x19\x63\x42\x9f\xe6\x2c\x15\xb9\xcc\x53\x56\x9c\xf9\x2b\xd6\x1e\x5e\x0f\xbe\x61\x9c\x8d\x5b\x78\x18\x9f\xce\xac\x51\xaa\x6a\xc3\xd1\xbf\x51\xeb\xcf\xff\x57\x03\xf9\x4e\xaf\x9a\x41\xf0\x94\xd0\x2c\x67\xda\x2a\x4f\x7b\x0a\xaa\xcc\x82\x70\xaa\xb8\x68\x22\x74\x08\x6f\x64\x1b\x28\x64\xed\x83\x58\x0a\x36\x82\xf8\xbb\xf6\x2a\x86\x58\x30\x1c\xc2\x40\xf0\xc0\x75\x96\xd7\xb9\x1e\xad\xe6\x31\x80\x50\x07\x37\xf3\x21\x7e\xe6\x6a\x99\xcf\x41\x55\xe9\x4d\x08\x53\x85\xae\xca\x1b\x07\x3f\xfd\xa7\x69\x66\x30\x8e\x64\xbf\x1a\x08\xe6\xc8\x59\x91\x56\x42\xe5\xd5\x8d\x38\xc2\xa2\x52\x6a\xaa\x0b\x96\x6d\x56\x15\x05\x54\xdf\xff\x8f\xd0\xa7\xed\xd5\x80\x19\x90\x5b\xc3\x56\x1f\xc2\x49\x53\xe0\xac\x51\x57\x95\x34\x86\x53\x88\xc2\xae\xa4\x1d\xc6\x43\x0d\x5a\x95\x08\x93\xc8\xa7\x95\x7c\x76\xb9\x31\xe3\x91\x0e\xe3\xcd\x8f\xbb\x2a\x07\x37\x3f\xc6\x2e\x55\x49\x6f\xed\x26\xc6\xce\x8e\x2d\xa3\xb5\x56\x08\x1d\x07\xf1\xfb\x87\xe4\xb9\x21\x7b\xa5\x31\x88\xeb\xf2\x4c\x18\x15\x80\xfa\x43\x3f\x93\xc8\xe7\xd2\x27\x84\x3e\xe1\x7b\x50\x8d\x3e\xb5\xe7\x53\xdf\x69\x3d\x89\x0a\x47\xa3\xab\x72\xd1\x4c\x71\x38\x1f\xb5\x89\xad\x54\x87\x73\xe6\x87\xd8\xa1\x8e\x0d\x75\x87\x9b\xb8\x41\x31\xec\xc4\xae\xd4\xef\xd7\x7e\xf0\xc8\xa1\xdb\xe2\xe8\x1b\xd2\x0f\x5c\x60\x17\x7b\xac\x7b\x7f\x1c\x23\x49\x87\x36\xd8\x31\x98\xff\x59\x75\x5d\x32\x97\x06\xaa\xeb\x66\xb2\x06\xc5\xda\x82\xd7\xa1\x1a\xec\xcd\x75\x46\x6e\xc6\xde\x45\xad\x58\x5d\x97\x36\xa7\xda\xe9\x55\xc0\x2d\x99\x58\x57\x55\xe9\x06\xb6\xb4\xdb\x20\x78\x23\x1b\xaa\xa9\xea\xba\xb4\xf2\xff\x41\xdf\x92\x0e\xa5\xe9\x87\x8e\xf8\x8e\xf3\x06\x89\x3b\x92\xc2\x5b\x19\xf4\x07\x6d\x92\x1e\x44\x33\x85\x37\x95\xd2\x48\x6e\xee\xd1\xda\xe9\x0d\x77\x68\x9a\xf7\x48\x11\xde\x71\xee\xc9\x8b\x0d\x2d\x56\x57\x3b\xf4\x23\xe1\x0f\x74\x30\x2e\x66\xc2\x53\x15\x73\x84\x9d\xaa\x48\x09\x7d\xda\xb6\xff\x20\x4c\xdb\xfe\x83\x26\xf8\xd6\xaa\xa3\x3e\x86\x30\xea\x08\xa1\x4a\xdb\x73\x73\x90\x49\x2d\x45\xf5\x51\x8d\x9d\xc8\x81\x0f\x43\x8d\x3a\x7b\x70\x8e\xa0\x50\x2b\x2c\xfd\xd9\x5c\x41\x73\x0d\x82\x62\xdb\xd8\x81\x06\xda\x47\xb6\x59\xda\x51\x09\x02\x5f\xbb\x85\xdd\x31\x83\xac\xff\x6d\x99\x04\xf2\x6f\x96\x49\x84\xf2\x85\xb5\xc4\x86\xf3\x39\xa1\xcf\xdc\xfe\xee\x98\x50\xee\xf6\x77\x11\xaa\x25\x37\xfb\x54\x9c\xd0\x67\x9e\x41\x10\x31\x42\xb9\x0f\xcf\x80\x6e\xf6\x70\x91\x68\xf6\x70\x35\xa0\x75\xe1\x00\x20\x37\x6f\x02\xd1\x3d\xb3\x13\xf0\x0c\x88\x66\xfe\x0d\xc0\x53\xa3\x77\xd1\x18\x78\x66\xd7\x0c\x22\x48\xc6\x41\x43\x08\xea\x2b\x60\xdd\x1e\x22\x98\xc4\xf3\xb9\x23\xc5\x84\x3e\x6b\x0d\xfd\x23\x08\xd1\x1c\xfa\x63\x42\xb9\xde\x87\x85\xf9\xf4\x33\xb7\x1d\x0c\x81\xdd\x76\x30\x42\x7a\x1e\x01\x33\x63\xbe\xa8\xed\x34\x6b\x0c\xc4\x42\x7f\x8f\x09\x7d\xd6\x98\xb5\x21\x31\x87\xa9\x8c\x8a\xde\xe5\xc0\xa8\x5e\x10\x8b\x40\xb3\xf0\xc2\x24\xdc\x47\xc0\x25\x0c\x82\x70\xfb\xc6\x11\x30\xeb\x81\x10\x15\x8c\x1f\x9d\x51\x5f\x83\x35\x97\x0e\xf3\x0c\x30\x6f\x57\xac\x28\xde\x7a\x9b\x05\xf3\x99\x0e\x7b\xd5\x0a\xf9\x03\x17\xbb\xa1\x19\x86\xae\xd7\x51\x57\x8d\x8b\x61\x4f\xc3\x3d\x0d\xf7\x15\xac\xa1\x2e\xa1\xcf\xbe\xfb\x46\xf1\x08\x93\x08\xae\xe6\xa7\x61\xd4\x83\x74\x4a\x1b\x0e\x2a\xc8\xed\xaa\xc2\x8c\x97\x7b\x20\xc8\xb1\x3d\x96\xa7\x10\xa4\x35\x96\x43\x5d\xac\x8d\xf6\x06\xc5\x0e\x50\xad\xfb\x27\x07\x11\xb9\x0d\x98\x21\x34\x17\xbb\xbf\x05\x93\xc5\x67\xfe\xa6\x21\x8a\xdf\x47\xcc\x34\xe2\x4a\x81\xd0\x25\xf9\xa5\x5b\x80\xc1\xbc\x2f\x5b\x2d\x9c\x5f\xda\x45\xd3\x5e\x8c\x60\xc1\x4a\xb9\x90\xc2\x6b\x3b\x0a\x57\xf0\xda\xab\x77\x67\x44\xb0\x21\x26\xb3\x61\xd0\x2c\x12\x4d\xb1\x36\xa0\x49\x76\xc3\xcd\xe2\x10\xf4\xf6\x67\x97\x9b\xbc\xc8\x67\x22\xdf\x68\x77\x85\x34\xc5\x40\x6e\x2b\x45\x83\xda\x3e\x67\x43\x10\xf7\xe5\x95\x2f\x2b\xc8\xd5\x6a\x8c\x31\xca\x4a\xb8\xee\x04\x92\x74\x6b\xc5\x90\xa5\x85\xba\x21\xd0\x9c\x55\x14\x02\x51\x0b\x81\x0d\x31\xa2\x2f\x92\x67\xd6\x9a\x87\x8e\x60\x6d\x79\x68\xeb\xef\x5e\x40\x67\x03\xa3\x44\x4d\x92\x6e\xe6\x90\x96\xd9\x27\x86\xe6\x63\xf6\x89\xf1\x5b\xe8\xbd\x4f\x06\x85\xbd\x49\x8b\x09\x79\x00\x1f\xb9\x91\x0c\x36\x45\x3c\xe7\xe7\x60\x7e\xb3\xe6\xa9\x64\x76\x0b\x5d\x71\xaf\xdf\x68\xc9\x59\xe1\x69\x93\x67\x0e\xfb\xcc\x61\xe7\xac\x28\x72\x5c\x64\xa9\xad\x65\x18\x13\xfa\xdc\x6a\xb6\x1e\xa1\x73\xab\xd9\x7a\xf8\x42\x98\x49\x76\xd0\x0b\x09\x9d\xcf\x73\xe5\xb2\xb2\x99\xcf\x80\xa3\xf9\xdc\x81\x48\x2e\x1c\xdc\x23\xf4\x79\x4b\x89\x8d\x21\x48\x53\x89\x75\xf1\xed\x28\x1b\x29\x22\xf4\x79\x5e\x14\x3c\xdb\xed\xf7\xa9\x21\xed\xef\xe8\x8c\xd0\xf9\xaf\x98\xd0\xfc\x57\x42\xe7\x05\x33\x33\x86\x0c\x20\x97\x43\x0c\xa0\x2c\x6b\x3d\x72\x45\x84\xce\xcb\x6a\xae\x7a\xee\x18\x84\xd1\xee\xb9\x10\xbf\xdd\x73\x87\xf8\x04\x19\x2b\xcc\x54\x2f\x84\x78\xe2\xcc\x87\xe7\x95\x5e\x80\x8d\xc1\x14\x05\x48\xcf\x79\xc1\x54\x7f\x5e\x6d\x44\xce\x85\x14\x7a\xfd\x09\xa6\xe3\xf3\x35\x13\xd2\x2e\x2f\xc2\xdc\x60\x2e\x58\x8a\x9b\x93\x37\x33\x03\x29\x35\x16\x41\x93\x46\xb8\x87\xd4\x54\x43\x7d\x4d\xed\x6b\x78\xa0\xe1\xb1\x86\x47\x1a\x9e\x29\x38\x36\xa9\xf5\x34\x6c\xe2\x0f\x14\xdc\x55\xa9\x73\x0d\x19\xea\x50\xc3\x26\x35\x9d\x7b\xcf\xd0\x47\x0a\xee\x9b\xdc\x99\x86\x4d\x78\x5d\x96\xa1\x81\x55\xfa\xba\x2f\x87\xd8\xec\x84\xd9\xe9\xed\xc2\x28\x37\x6f\x1b\x39\x33\x42\x9f\xbb\x2e\x1c\x11\xba\xf0\xf6\x4a\x40\xd5\x7d\xe3\xe6\x7b\x60\xd9\x7a\xd3\xbf\x59\x57\x53\x33\x05\xc3\x44\x69\xe1\xc3\x19\xc0\x7a\x1d\x69\x34\x20\xf4\x1b\xcf\x5d\x0c\x26\x70\x0b\x1f\x9e\x13\xfa\x8d\xd9\x14\xd8\x84\x11\x30\xfb\x8d\xdb\x7f\x88\x20\x6d\x0f\xcc\x80\x6a\x56\x27\x80\x2d\xbb\x3a\x01\x4c\x59\x3b\x21\x0e\x09\x5d\x38\x08\x8a\xa7\xd5\x27\xcc\xef\x17\xda\x29\x6d\x30\x84\x6f\xad\x76\x47\x90\x93\x59\x78\xc8\x66\x00\x5c\x7a\x51\xf8\xe5\xa5\x17\x49\xeb\x70\xad\xe3\xa0\x48\xbc\xd6\x6b\x57\x8c\x8d\x11\x6c\xd0\xec\x98\x3e\x0a\x0d\x5c\x69\x44\x6c\x11\x86\x91\x1e\x62\x2c\x27\x66\x69\x0d\x70\x26\xd9\x71\x8f\xd0\x6f\x5a\x9a\x81\x11\xba\x68\x69\x06\x48\x49\xaf\x0e\x0f\x66\x84\x7e\xa3\xbf\xa1\xfb\x2c\x16\x3e\x90\xaf\x74\xc9\xa3\xee\x90\xd0\x6f\xdc\x64\x1c\x44\xec\x26\xe3\x00\x15\x4c\x17\x13\xa4\xa2\x99\x04\x93\x6d\xa1\xb5\x24\x03\x0d\xb0\x28\x7e\xd5\xa1\x80\x85\xd2\x36\x06\xa6\x20\xeb\xb1\xa4\x31\x7a\x66\x39\x1a\x01\x60\x2a\x67\x8c\x94\x4b\x9f\xe4\x2a\x01\x89\x76\x5c\x01\x9b\xea\x9b\xb6\xd2\x01\xc9\xb7\x95\xce\x08\x9f\xc4\xd3\x6b\x2c\xdf\xe0\x0d\xb6\xc2\x9b\xbf\x43\x4d\xfb\xd8\x6f\xcd\x18\x8d\x0d\x42\x53\x9e\x6f\x8a\xc2\x8f\x33\xb4\x14\xfd\xa7\x4b\x1e\x5b\xbc\x4b\x66\xe8\x02\xbf\x85\x06\xe4\x0f\xfb\xdc\x92\xbc\xd1\x1e\xc6\xcf\x6f\x5a\x7d\x17\x52\x5e\xd8\xbe\x8b\xf5\x6e\x25\x01\xe1\x17\x76\xa7\x96\x8d\xb8\x02\x8d\x79\x0a\xcd\x48\xda\x86\x3a\x44\xc8\x38\xa8\x0d\x21\x21\x39\x21\x8f\x08\xfd\xe6\x9d\xfa\x93\xae\xed\x2c\xdc\x3c\x26\xc3\x78\xc5\x1b\x33\x39\x01\xfb\x65\x21\x9d\x49\xc2\x86\xd0\x95\xa4\x68\xd4\xf3\x40\xa1\xac\x7d\x31\x42\xb8\x95\xa6\xe0\x97\x45\x43\xe4\x88\x72\x38\xd5\x49\xa5\x28\x1a\x02\x5d\x48\xd1\x2c\xff\x15\x17\xd2\x6f\x2b\xb6\x07\x5d\xb9\xc6\x65\x70\x2f\x58\xca\xd5\x74\x0d\xd7\xa1\x96\x2c\x17\xd6\x44\x65\x00\x17\x73\x33\x7a\x2c\xd9\x2a\x2f\xf4\x0c\x3b\x9c\x11\xfa\xe2\xec\x7b\xbb\x52\x1a\x63\x58\x61\x17\x4b\x7b\x0a\x16\x76\x2b\xab\x37\x52\x08\x15\x1d\xfa\xef\xd2\xad\xef\xf6\x14\xcd\xcc\x75\x33\x60\x4b\x4e\xc8\x7f\x13\xba\x9c\x31\x53\xcf\x73\x42\x5f\x38\x4d\x08\x7d\x7b\xe9\x81\x7d\x42\x97\x9c\x09\x69\x56\xf5\x2c\xec\xd6\xfd\x10\x55\x14\xb9\x2e\x5e\x3c\x00\x58\xa4\xc6\x7c\x85\x79\xef\xb2\xa5\x40\xfa\x84\xbe\x30\x5b\xa8\x30\x7f\x7e\x91\x17\x33\x2e\xe4\x5b\x7c\x57\xc4\x0a\x62\xf9\xb1\xe6\x6e\x1e\x8e\xac\x7c\xac\xaf\x3d\x0c\xe4\x54\xb9\xb9\xed\x1c\xc0\x95\x5c\x9a\x85\x74\x48\xa2\xaa\x3e\x16\x7c\x2e\xbd\xc5\x13\xd0\xa3\x80\xc6\x75\x0d\x1f\x0f\xa2\x6d\x77\xec\x31\xa1\x2f\xdc\x56\x14\x54\x56\x25\x8c\xe8\xc2\x08\x8a\x51\x89\xfc\xb7\xaa\x94\xac\xf8\x36\xd7\xfa\x06\x9d\x6a\x96\xed\x81\x11\x84\xef\x3a\x17\xb0\xe6\xdc\x01\x55\x25\x78\x33\x7c\x2c\x99\x0f\x0f\x09\x7d\xb1\x59\xe1\x8a\xd3\x8b\x86\x63\x03\x40\x9e\xd6\xe8\x81\x0c\x6e\x9d\x67\x44\xaf\x0b\xf0\x7a\xa9\xdd\xe3\x70\x91\xff\xa5\x9b\xb1\x67\x84\xe6\x6e\xc6\x0e\x90\xea\xc3\xe1\xa0\x4b\xe8\x4b\x3b\x1b\xe7\x40\x30\xb3\x71\x0e\x14\x33\x54\x8e\x80\x62\x86\xca\x11\xa1\x2f\xed\xe0\x08\x06\xf0\x4b\x3b\x31\x07\x51\xe5\x76\x66\xde\x45\x08\x4d\xeb\x0f\x37\x2c\x22\x34\x9f\xcf\x5d\x93\xcd\x5b\x8d\x65\x40\xe8\x4b\xd3\x58\xa2\x88\xd0\x97\x6e\x36\x9d\x12\x9a\xbb\xd9\x34\x40\x6a\x15\x24\x82\x6e\x91\xe7\xb9\xb3\xd9\x90\xe6\xf6\x23\xa1\xa8\x79\x39\xd7\x4b\xcd\xe3\x0c\xc9\x95\x9a\x35\xc4\x51\x3c\x26\xf4\xe5\x3f\xb5\x61\x1a\x46\xdd\x98\xd0\xfc\x57\x07\x82\x6c\xdc\x84\x19\xba\x68\xee\x81\x33\x04\xb5\x5d\xa0\x18\x5e\xb1\x45\x5e\x32\x71\xfb\xd2\x63\x6e\xc5\x16\x85\x69\x31\xb8\xc2\x03\x18\xb0\x33\x5d\xbc\x7c\xc5\xd4\xa6\x4e\x88\x96\xd4\xcb\x95\x4f\x52\x86\x71\x1c\xc3\x0c\x27\x5f\xad\xd5\xf6\x52\x88\x7b\x95\x2f\x57\xeb\x22\x37\x9b\xb9\x19\x30\x5f\xa6\xc6\x1a\x47\x3f\x63\xb3\xc2\x1e\x02\x23\x56\x0a\x31\xd8\x50\x08\x1a\xa7\xb5\x31\x98\x5c\x79\x59\xb9\x4a\x85\xac\x4b\x99\x9a\xe6\x36\x63\x08\x6b\xa1\xce\x08\x7d\x69\x81\x14\x29\x7c\x61\x16\x28\x50\xb3\xb4\x56\x9a\x67\x2a\x8c\x68\xa4\xf7\x12\x17\x35\xb8\x73\x47\x46\xef\xcc\xbc\x94\x05\x13\x4b\x65\xb7\xb3\x68\x88\x18\xbb\x2b\xcc\x60\x12\xff\xb2\xbc\xca\xeb\x1c\x97\xb5\xb5\x4d\xa9\xdb\xb1\xc1\x3b\xef\x82\x70\x10\x13\xfa\xf2\xb5\x35\x47\xa0\x58\x95\x35\x47\x40\xd6\x6e\xcd\x20\x06\xa9\x78\xe0\x1c\xa8\x4d\x35\x01\xf3\xaf\xbc\xad\x3a\xa0\x28\x95\x9d\x94\x8e\x21\x84\x9d\x95\x02\xd4\x64\x3e\x37\xe3\xdc\xcd\x6c\x4e\x68\xde\xd6\x1e\xd0\xe9\xac\xf6\xc0\xd6\x52\x37\x2a\xb1\xce\x4b\xb7\x1e\xd8\x57\x08\x3d\x26\xcd\xc7\x0a\xd4\x23\xdb\xbc\xa7\x41\x3d\x87\x9f\x77\x15\x7c\xe5\xa5\x26\x3d\x21\x49\xbb\x4d\x14\xc5\x48\xf3\x60\xe8\x26\x9b\x8f\x56\x8a\x03\x42\x73\x07\xc2\x54\xe5\xa5\x99\x64\x43\x99\xcc\x24\x7b\x4e\xe8\x3f\xdd\x08\xd3\xed\x11\xfa\xab\x07\xf6\x81\x6a\xb4\xc6\x18\x68\x46\x69\x8c\x09\xfd\x67\xcb\x36\xcd\x08\xfd\xb5\xa5\x2d\x86\x84\xfe\x6a\xfb\x0d\x7a\x55\xfc\xb3\x5d\x5b\x11\xa1\xbf\xb6\x6b\x6b\x46\xe8\x3f\xdb\xf6\x50\x9f\xd0\x5f\xdb\x15\x01\xcc\xd7\x5c\xd8\x32\x8f\x20\x8c\x83\xc1\x12\xfc\xa7\x27\x12\x28\x9c\x27\x92\x1e\xa1\xff\x62\xeb\xb5\x69\x14\x8c\xd0\x8f\x0e\x9c\x19\xd0\x2c\x0c\x85\x84\xfe\xcb\x9b\xc2\x74\x07\x84\x7e\xf4\xe1\x21\xd0\x8d\xa8\x20\xb2\x15\x15\x23\xf4\x5f\x2d\x51\x71\x42\x3f\xb6\x44\x35\x22\xf4\xe3\x42\x68\xd7\xe9\x10\x37\x8e\xff\xe5\x7c\x99\xfa\x84\x7e\x74\xbe\x4c\x7d\x42\xff\xe5\xcc\xf7\x94\xd0\x8f\xce\x7c\x4f\x09\xfd\x57\x5b\xc6\x31\xa1\x1f\xdb\x32\x86\x70\x6d\x19\x43\x99\x5a\xb8\x34\x24\xb4\x38\xb3\xc3\x7a\xc6\x08\xfd\xd6\x9b\x44\x42\x3b\x28\x7c\x98\x01\xdc\xd8\xaf\xed\x01\x66\x21\x98\x5e\x8b\x89\x62\x48\x61\x35\xcb\x8c\xdc\x67\x40\x77\xf0\x0c\x61\xed\xef\x32\xe4\x23\x08\x6d\x21\xa6\x68\xe6\xc4\x47\xa4\x40\xbd\xf2\x82\x81\x0b\x3b\x0d\xe9\x43\x4c\x3c\x64\x69\x97\x0f\x20\xef\x82\x29\x7f\xfa\x1b\x86\x19\x09\xa1\x7c\x40\x22\xde\xd3\xe0\x5c\xf5\xcd\x31\x4c\x5a\x9d\x5f\x06\x58\xd5\xdf\x3a\x88\x83\x54\xac\x50\x42\x15\xd2\xc6\xcc\x14\xac\x15\x24\x1a\x39\x00\x17\x6b\x0d\xeb\x9c\xd7\xc6\x65\x44\xd3\x8d\x81\x3b\x06\x03\x17\x10\x52\xcf\xd7\x18\xf2\x2d\x59\xae\x23\x40\x57\x2c\xce\x3c\x18\x13\xd4\xa3\xab\x4a\x5d\xfb\x40\x31\x96\x29\xa8\x36\xa0\xb1\x89\x8b\x99\xb5\xd3\xa1\x05\x15\x8f\x1d\x08\x85\xb3\xe7\x17\x86\x43\xc8\x7c\x26\xd0\x18\xfc\xa4\x3f\x3f\x4e\xc8\x39\x7e\x7e\xd4\x63\xd3\x68\xa6\xc0\xba\xd0\x75\x33\x9a\x1b\xc4\x46\x23\x32\x42\xbf\xf5\xb6\x18\xba\xc0\x98\x0f\x73\xa0\x7b\x1d\x0a\x52\xf4\xe1\x14\x61\x5d\xe4\x2e\xf4\xf5\x22\xdd\xcc\x90\xa7\x6f\x6d\xc7\xc3\x48\xa6\xe3\x01\x90\xa5\xfa\x78\x13\x74\xd8\xc2\x3b\x4b\x91\x6a\xd0\x98\x8f\x50\xe8\x4c\x64\x6e\x37\x66\x88\x88\x4d\x6d\x31\x3d\x4c\xcf\x58\x89\x33\x10\x8b\x59\x6f\x80\xb6\x63\x66\x1d\x03\x42\x71\xbf\x14\xda\xe5\x63\x90\x95\x5e\xab\x57\x6d\xd9\xec\xa4\x9a\x3d\x32\xd5\xee\x9a\x46\x31\xb6\xb5\xe6\x26\xae\x41\xb1\xe6\xbe\xae\x0d\xd5\xde\x48\x4d\x07\x5e\xaa\xb6\xa1\x60\x43\x82\x38\x4f\x78\x5e\xe4\xba\x57\xa1\x28\x01\xa9\xb6\x4b\x9b\x2c\x0f\x0c\x09\x77\xe5\xfc\x7d\xbf\x41\xe4\x48\xed\x6d\xbf\x71\x9b\xa4\x99\xea\x2a\xfc\xf3\xa2\xd2\xa8\x2e\x4c\xbf\x80\x4f\xbd\xbd\x69\x4f\x2e\xe0\x96\xa3\x47\xd0\x1e\x4b\xd1\x2c\x55\x68\x5b\x36\xb3\x7f\x3a\x54\xf8\xf6\x3c\x02\xe6\x60\xfb\xb6\xbd\x0d\xbe\x1d\x3e\xeb\xb5\xd3\xa9\x9b\x02\x45\x82\x66\xca\x90\x66\x1e\xa9\xbe\xdc\xe4\x0b\x7f\x22\x93\x79\x0c\xf8\xf2\x83\xf9\x82\xde\x9d\xf5\xb7\x40\x7b\x16\xab\x9a\x13\xeb\x5a\x44\x63\xd7\x55\xcb\x4d\x2e\x05\xe7\xbe\xdb\xc5\x4c\x07\xd7\x87\x3a\x6c\x9d\xc0\xa0\xef\x13\x54\xf0\x59\xdc\xc4\x7a\x93\x97\x99\xe6\x44\xed\xac\x37\xf2\x8e\x0c\xa5\xdd\x24\x42\x43\x68\x37\x88\x51\x93\xa0\xeb\x52\xb3\xd4\x0e\x1c\xfb\x68\xaf\xda\x9f\xe9\x4d\x3c\xd4\x35\xdc\xac\x6c\xa1\x20\x2e\xbd\x7e\xe8\xd6\x04\xb0\xca\x1a\x8b\x78\xd8\xa8\xdc\x22\xde\x08\xc1\x06\xcd\x2e\xe2\x0d\xe7\x06\x36\x8b\x78\x91\x45\xe8\xc5\x94\x51\x17\x31\x96\x13\xab\x5a\x79\x6d\xd7\x06\xc7\x2a\x4c\xdd\x58\x27\xe9\x2b\x9c\x5b\x18\x19\x28\x04\xbf\x34\x9b\x48\xba\x5c\x80\xb2\x38\x2c\xf8\xb7\xbc\xae\xb1\x96\xfc\x75\x28\x0c\x0d\x94\xf6\xb2\xd5\x40\xa1\x1b\x61\x87\x3a\x33\x9b\xd5\x50\x87\xb2\x2b\x58\x8c\xa9\xa2\xd6\x6e\xc5\x25\x56\x41\x76\xd6\xb3\x32\x85\xf7\x17\xb3\x40\x2f\xfa\xfe\x59\x50\x75\xf3\x66\x8f\xff\xb6\x65\x0e\x81\xa8\x5b\xe6\x10\x8c\x70\x0b\x8f\xe1\x85\x59\x78\x04\xd6\x9c\x23\x17\x64\xb6\x64\x22\xf3\x94\xc6\x92\x89\x8d\xd7\x6a\x00\xd4\xc3\xe4\x00\x64\xba\x9c\x15\xe6\x68\x12\xb4\x70\x67\x46\x41\x8e\xce\x8c\x02\xc8\x8d\xfe\xa8\x5e\x8c\x50\xa1\x00\x66\xe1\x16\x5a\x10\x7a\x2e\x69\xe9\xa2\xef\xd2\xb7\x2d\x7d\x8e\x75\xe9\xd8\x1c\x0f\xa0\x01\x17\xd6\x49\x60\x0e\x09\xae\x72\x37\xaf\x03\x71\x78\x30\x4c\x68\x8a\x55\xb5\xa9\x25\x4b\x97\xda\x6d\x68\x66\x71\x1e\xec\x96\x60\xc7\x0a\xf2\x9a\x1c\x62\xcc\x82\x21\x94\xc6\xae\x92\x8d\x90\x72\xe9\x93\x5c\x17\x42\xa2\x5b\x82\x85\x9a\xa8\x9c\x39\x96\x22\x68\x97\x7c\x40\xfa\x95\xb5\x1b\x54\x60\xd0\x2a\xbe\x30\x86\x30\x21\xda\xe7\x53\xa4\xd1\xed\xd0\x23\x97\x48\x4b\x57\x0f\xe7\x43\x97\xd2\x8e\x8b\xd1\xd0\x25\xb7\x13\x8f\xa9\x34\x57\x6c\x5d\xeb\xce\x3d\x9c\xa7\x0a\xb7\x13\x76\xa0\xd2\xd9\x49\x5f\xe3\x77\xc2\x83\x9c\xab\x6a\xdd\x72\x4f\x45\x9b\xcc\xa0\x3d\x1f\x1e\x86\xd9\x9a\xbd\xed\x31\xda\xac\x6d\xe3\xbd\x8b\x41\x9a\xc6\x3b\x4a\xda\x6d\x7a\xc7\x08\x7b\x67\x1d\x61\x1e\x57\x54\xd7\xf6\x70\x01\x4c\xd1\x8b\xea\x1a\x17\xcb\x7e\x81\x3c\xae\xb9\x68\x5b\x18\x63\x8d\xdf\x19\x2a\xb1\x0a\x7e\x53\x6d\x35\x45\xd9\xb9\x83\x8a\x06\xa1\x4f\x7a\x73\x28\x27\x16\xa7\xa3\x3e\xf4\x52\xea\x18\xd5\xa0\xf3\x1a\xc6\xd1\x54\x34\xfa\x0d\x34\x7a\x61\x6c\x2d\x35\xa6\x0a\xaf\xcb\x40\x09\xb5\x8b\x71\x88\x06\xaa\x30\xfd\x27\x86\x71\xa4\xa8\x99\x35\xed\xd0\x9c\x6e\x4f\x63\x60\xcc\x72\x73\x76\x50\x1b\xd6\x90\x83\x51\xcb\x07\x8a\x86\xda\x2b\xbc\x85\xf6\x4c\x81\x66\x1c\xc2\x7c\x2f\x67\xca\x16\xae\x9d\x69\x39\xd2\xa0\x31\x2d\xa1\x7f\x7b\xeb\x87\x30\xe5\x2d\x7c\x18\x72\x71\x0b\xf6\x03\x84\xec\x82\x3d\x14\x46\x4e\xc8\x43\x42\xbf\x7d\xa7\xfe\xa4\xd3\x43\x85\x6c\x8e\x21\x68\x0e\x38\x4b\xa0\xf0\x2d\x03\x4c\xa8\x70\x8b\xf3\x18\xde\x5f\xd0\xc7\x08\x46\x29\x81\xad\x06\x10\x77\xd6\x40\xe1\x1c\x99\x52\x64\x59\xb8\xdd\x01\x48\x6c\x23\x32\xcf\x58\x66\x88\xf1\xbc\x9b\x20\x48\x6b\xd1\x7e\x64\x47\x4c\xb7\x68\x6f\x71\x7a\x15\xef\x86\xcd\xe1\xdb\xee\xae\xc7\x08\x69\xfb\x34\x0e\x15\xc4\xf5\x81\x67\x44\xbc\xd2\x6a\x70\x1c\xf6\x81\x6a\x26\x5d\x03\x04\x4c\x8f\xf7\x60\x67\x74\xb2\xa1\xc1\x79\x5d\xb7\x67\x70\xc6\x06\x65\x98\xac\xf8\xa8\x9b\x6e\x9f\x71\x42\x57\xa9\x5d\xe6\x62\x30\x76\xbd\xb2\x33\x92\x14\x88\x66\x46\x02\x80\xe7\xe4\x0d\x49\x5b\x9f\xa8\x18\xe6\xce\x2b\xce\xea\x8d\xe0\x99\x7f\x53\x43\x44\xe8\x2b\x9e\xe5\x9b\x95\x5b\x91\x0f\xfb\x73\x40\x16\x45\x5e\xba\xbd\xf1\x2e\xa1\xaf\x5a\x27\xab\x41\x3c\xad\x81\x15\x32\x59\x6a\x19\xc4\x50\xde\x3c\x45\x1f\x8b\x9b\x19\x14\x2b\xcf\xcc\xb1\xff\x55\x9e\xd9\x46\x38\x0f\x11\xd6\xfc\x74\x11\xf0\x0e\x69\xa1\x2b\xac\xbe\x97\x61\x3c\xd7\xb0\x56\x3c\xb1\x06\xcd\x7d\x21\x23\x03\x6f\xb4\xb0\x18\xa1\x78\x22\xc9\x9d\x40\x8a\x20\x83\x22\x35\xc7\x2f\x66\x00\x65\xc6\x1d\x1d\x6a\xad\x5c\x37\xc3\x56\x99\x71\xaf\x8a\xa1\x06\x5f\xb5\x35\x28\x88\xb9\xad\x41\xa1\xce\xd6\x5e\x1a\x6d\x7d\x11\x13\xfa\xca\x6d\x9d\x63\x08\x89\x97\x34\x7c\xd0\x57\xa0\xbc\xc2\x02\x84\xdd\x31\xd4\xa9\xfe\x9e\xe1\x37\xf4\x3a\x73\x16\x63\x06\xe5\xdd\x34\xc0\x92\xcd\xf4\xf6\x2a\xba\xbe\x7f\xe7\xad\x9e\x80\xae\x2f\x7d\xb8\x07\xb0\xbb\xcf\x03\x3d\x96\x63\xc0\x99\x4d\x87\x31\x02\xf6\x92\x09\xbc\x7f\x05\xf3\xf0\xae\x97\xf0\x90\xaa\x00\x61\xa4\xe3\x79\x97\x4a\x20\x42\x6e\xcc\x72\xf0\x60\xc0\x2d\x42\x4f\x73\xa2\xbe\xc6\x78\x01\x66\xb8\x8d\x76\xc3\x42\xf8\xf6\xb6\x42\x6c\x96\x8d\xb3\x9d\x16\xeb\x8e\xae\x74\x09\xfd\xce\x5b\x04\xe8\x0d\x91\xea\xe0\x11\xd0\xdd\x22\x40\x0f\x78\xf0\xe1\x01\xc0\xee\x74\xd4\x50\x83\xde\xf1\x28\x97\xa9\x3d\xf5\x12\x43\xa2\xa6\x7f\x66\x40\x32\xfd\x13\x00\xaf\x7f\x42\x75\x70\xbb\xd0\x3d\x8e\x7b\x0a\x36\x8b\x40\x90\x1b\x77\xab\x40\x43\x4d\xb5\x03\x27\x22\xb4\x5a\x03\x09\x71\xcf\x7f\xca\xb0\xf5\x1d\x5f\x30\x99\x5f\xf1\x9d\x1e\x1e\xce\x1c\xf1\xdd\x32\x4f\x3f\xde\x4f\x2b\xef\x21\xfd\xc0\xc5\xed\x1e\x72\xe3\xfc\x3d\xb4\x26\x5e\x73\xa3\xa5\xe3\x11\xc2\xce\x97\xcb\xf1\x59\x4b\x9e\xed\xd9\x03\xc7\x8d\x63\x45\x6d\x4c\x22\x70\x7c\xfa\x8e\x5f\xeb\x9d\xb8\x12\xd2\xf5\xdc\xb6\x7a\x06\xae\x1d\xe2\xbb\x96\xf6\x8a\x08\x2d\x5b\xda\x0b\xd8\x77\x9e\x1d\xb6\x6e\x8d\xe3\xc7\x30\x42\xe0\xb2\x09\x5d\xee\x09\xdf\xf4\xed\xf0\x08\xf5\x0e\xce\x79\x54\xb8\x60\xce\x44\x80\x16\xe9\xf6\xd0\x6d\x0f\x5d\x18\xd4\x1c\x01\xe1\x41\xdf\xc8\x2b\x17\x5c\x27\xe8\x76\x8d\x61\x34\x29\xdd\xb6\x71\x8a\xa0\xb1\x10\xd9\x1c\xd2\xd6\x76\x0f\xd6\x65\x6e\x76\x12\x52\x04\x74\xa7\x07\x13\xb7\x34\x75\x8c\x4d\xc2\xcd\x73\x80\xe4\xe6\x39\x00\x79\xab\x9c\x08\xba\xcc\xa1\x3f\x38\xdd\x0b\x45\x75\xcb\x5c\x96\x77\x33\x50\x0d\x43\x04\x9a\x4b\x59\x90\x60\x6b\xe1\x4a\xa5\xba\x67\xf1\x05\x8b\xbe\x6f\x55\x06\x85\x60\x67\xf9\x3a\x1f\x37\xcd\xf7\x38\x69\xce\xf6\x3d\x42\xbd\x0f\x67\x5a\x2a\xe6\x6b\xa7\x74\x2e\x84\xab\x65\x68\xae\xce\xf0\xb2\xb5\x5c\x48\x2f\x05\x6b\x3c\xc5\x9c\x69\x50\x4b\x06\x26\x4a\xe5\xb7\xb6\xda\x99\xcd\xc1\x0d\xaa\xd0\xfc\xab\xc7\x82\x33\xa5\x6b\x42\x50\x18\xdf\x55\x25\x62\xf2\x72\x61\xba\xb0\x52\xb5\xed\xc1\x6c\x0e\x61\xcd\xc6\x38\xe8\x69\x77\x97\x06\xe4\xac\x4f\x8e\xa4\x88\x6f\x1f\x16\x8d\x15\xd6\x3b\x3f\x08\xb6\xf6\x77\x95\xbc\xef\xf4\xc4\x00\xa9\x4d\x07\xe8\xb1\xc2\x79\x2b\x0f\xa1\xc3\x34\xfc\x5a\xad\x3e\xa9\xe4\xb3\x76\xf7\xaf\x64\x53\xb1\xcc\x7d\x9c\x97\x38\xf4\x6b\x47\xd8\x71\xd5\xf1\xb2\xd8\xaf\xaf\x76\x03\x78\xce\x3b\x63\x1f\xbf\xeb\xbf\xb3\x1b\xd7\x5f\xfb\x50\xa2\xdf\xe7\x1c\xe0\xc5\xdb\xf1\x12\xb0\xcd\xa1\x92\x76\x1f\x71\xac\x41\x6f\x23\xb1\x11\xcc\xee\x27\x36\xb0\x57\xac\x15\xdd\x5c\x97\x05\xf3\x61\x85\xd0\x8e\xcd\x73\x55\x8d\xf7\xac\x15\x7a\xdc\xee\x2e\x1a\x42\xeb\x6e\x11\xbc\xe2\xf0\x54\x53\xfd\xde\xa5\x11\x7e\x1d\x86\x16\xdb\x5c\x9d\x1a\x59\xbc\x3f\x94\x34\x18\xda\xb7\x0e\xd5\x0a\xe0\x57\x8a\x6a\x5a\xf7\x0e\x60\x8c\xf9\x8d\x72\xcf\x48\xc6\x58\xe4\x09\xd9\x6a\xdf\x54\x83\x56\xe6\x16\x61\x64\xce\x0d\xc2\xc8\x5c\x75\xac\x37\x82\xa7\x3c\x33\xf3\xb2\x51\xd8\x40\x7a\x85\x62\x7e\x35\x18\x7a\xab\xe4\x31\x57\xd1\xbf\xe7\x57\x5c\xd4\xbc\xd9\x2b\x55\x4d\xa8\x43\x3b\xed\x3a\xce\x42\x2f\xf1\x46\x10\x9d\xee\x6c\x97\xe2\x67\xab\x8a\xa2\x3c\x8b\xd5\xeb\x9f\xba\x38\x3e\xd3\x3e\xd9\x8f\x1c\x37\xa8\x6b\xe0\xdc\x5c\x64\x10\xee\x89\xae\x02\xf8\x09\x74\x15\xdd\xcf\x37\x36\x4a\xd9\x12\xbc\x08\x23\x9d\xe0\x26\x4d\x39\xcf\x8c\xe4\xa3\x06\xd2\x93\xfc\xac\xc1\x85\xa6\xef\x48\xbe\x19\xdd\x6f\x71\x0d\x19\x34\xca\x37\xea\x36\xd8\xdc\x29\xd9\x48\xa9\x1f\x5f\x65\x46\x0e\xe3\x6b\x8d\x9e\x43\xb7\x34\x20\x58\xc1\x86\xe4\x27\xa4\x92\xde\x55\xe8\x30\xb6\xad\x99\x60\x45\x61\x3c\x63\x41\xc7\x97\x6b\x5f\xe3\x97\xee\x14\x01\x9b\x67\xe6\xce\xa6\xd2\xba\xc8\xc4\xa1\xed\x44\xe5\xba\x2a\xdc\xed\x0f\x98\xb8\x70\x4d\xbd\x5c\x8b\x74\xc3\x5d\xdb\x2d\xdd\x21\xf1\x91\x01\xcd\x62\xa4\xeb\x00\x80\xde\xc1\x09\x26\xf4\x31\x8d\x71\xb7\xdb\xc0\x6a\xdb\x03\xec\x23\xe1\x8c\x99\xb9\xa6\x1a\xd3\xc4\x99\x02\x3b\xbb\x46\x10\xf3\xfb\xb6\x11\x82\xf1\xdd\x18\x3f\xd3\x20\x77\x3d\xa2\x34\xa7\xfa\xa1\x69\x95\x75\xea\x4a\xaa\x60\xbe\xd3\xbc\xda\x3b\xf0\x63\x0c\xd7\x9c\x8a\xc2\x2c\xa4\x5e\x56\x42\x36\xac\x05\x85\xda\x53\x6f\xce\x78\x8f\x14\xc4\x5d\x8b\x29\xbd\x8b\xf0\x14\xdc\x4a\xb3\x59\xe9\xf5\xa5\xbd\x14\x01\x3b\x2d\x22\xcc\x7c\x8e\x23\x5f\xfa\x0a\x85\x78\xd4\x53\x90\x9e\x8a\xa6\x6e\xb4\x72\x49\x8c\x34\xb8\xa7\xd3\x6a\xb4\xe1\xcd\x0b\x69\xec\xbc\x66\x92\x69\x43\xd0\xd0\x05\x2f\xdb\xb2\x2d\xcd\x0d\x0e\xf1\xa8\xaf\x20\xc3\xdb\xc0\x0f\xc2\x5d\xc7\x03\x70\x4f\x4f\xd5\x68\xcb\xdb\xd8\x43\x5d\xee\x24\x29\xad\xbf\x34\xf4\x37\x7b\x1b\x62\x06\x8c\x5a\x68\x8e\x90\xdd\xe0\xc0\x78\xed\x1b\xda\x94\x15\xe9\xa3\x0d\x07\x68\xd4\xed\x5e\xdb\xa6\x9a\x64\x03\x6f\x63\x80\xba\x36\x0b\x16\xd0\x50\xcd\x82\x05\x7e\xaf\x26\xe4\x3f\xf0\x9f\xeb\xd3\x36\x78\x20\xaf\xdc\xb8\xf3\x5e\x60\x3d\x5c\xb9\xfb\x25\xac\x64\xae\xdc\xad\x34\x60\x5e\x96\x57\x4f\x1d\x0c\x49\xff\xe0\xd1\x61\x34\xfc\xc1\xa3\x43\x77\xba\x72\x1e\xfb\x2e\x4d\xf4\x4f\x76\xe0\x0b\xe7\x98\x00\x6d\xec\xca\xf7\x14\x84\x34\xaf\xec\x7c\x65\x1c\x62\x04\xb7\x2b\xef\x12\xc1\x25\x54\x1f\xf4\x56\x36\x1d\x5a\xb8\x94\xba\x08\x7b\xc1\x3c\x06\xdd\x95\x59\xa9\x45\x5e\x7b\xcb\x04\x5d\x05\x1b\x35\x04\xb2\xbc\x76\xcb\x04\x03\x4d\xb5\xca\x06\x11\xa5\x9b\x82\x0f\x09\x7d\x6d\xfd\x40\xb3\x2e\xa1\x95\x85\xe6\x08\xf9\x57\x06\xbd\x36\xae\xa0\x59\x8f\xd0\xca\x00\x73\x0d\xe8\x70\x0c\xc2\x99\x05\x0f\x0e\x24\xb3\xe0\x01\x40\xf3\x66\xa1\xd7\xee\x1e\x89\xa8\x1f\x02\xd9\x83\x23\x80\xf5\xbc\x92\x41\x73\xb7\x77\x30\xe2\x15\x44\x55\x56\x57\xc6\x01\x64\x96\x12\xfa\xfa\x99\xf5\xd3\xec\xc7\x84\x56\xdc\x81\x50\x90\xb9\x75\x9c\x9e\xcd\x09\x7d\xdd\x9a\xfd\x43\x84\xd6\xec\x3f\x25\xd4\xfa\xfe\xa1\xeb\xf8\x6b\xeb\x6f\x0a\x95\x50\x59\x68\x8e\x90\xde\x7b\x48\x81\x6b\xeb\x63\x3d\x9e\xf5\x01\x5c\xa9\x0e\x00\x0a\xb7\x6a\xdc\x94\x53\x79\x77\xb1\x30\x00\x1d\x93\x48\x75\x77\xcf\x8c\x67\x33\x40\x18\xbf\xd1\x10\x85\x69\x36\x3c\xd2\x90\xd0\xd7\xce\x11\xb5\x07\xac\x7b\x20\x08\x7a\xc5\x17\xcc\xe3\xc2\x81\xe9\x18\xa8\x79\x2a\xec\xa9\xc5\x39\xd0\x3d\xc4\x4c\x21\x8c\xa8\x07\x08\x35\xae\x75\x7a\xdd\x5e\x04\x85\x30\x2d\x1c\x4c\xd2\xdc\xe6\xd3\x0c\xda\xdd\x9a\x97\xf7\x5c\xb2\x94\x7a\x54\x1f\x0f\x8d\x60\xcd\xcd\x6d\x35\x33\x28\xc9\xba\x71\x99\x54\xe5\x5d\x16\x03\x55\xa6\xad\xee\x3e\x34\x51\x33\xd8\x40\x22\xc2\xdc\x71\x9c\x21\xc0\xcd\xda\x6b\x4f\x83\xd5\xbc\x81\x40\x8f\x7d\xc6\xf0\x7b\x85\x2b\xd1\xf8\x9d\x2f\xac\x2f\x2e\x94\x58\x98\xbd\xfa\x3e\x42\xfe\xc5\xc9\x43\x40\x98\x7b\x93\xa1\x26\xbd\x9b\xb2\x5e\xb7\xc7\x65\x48\xdb\x2d\x07\xf7\x20\x84\x76\x18\xbf\xc9\x80\x79\x0b\xcd\x11\xd2\xc7\x7c\xe2\x31\xa4\xe5\xc6\x00\x90\x86\x1b\x03\x14\xb4\xe2\x35\x33\xbb\x76\x03\x0c\xed\x76\xf1\x86\x26\x84\x4e\x0d\x6a\x48\x3b\x6e\x82\x1a\xa9\xf4\x37\xcc\xe5\xaa\x2b\xd3\xc0\xbb\x5d\x68\x5c\x57\xdc\x7a\x54\x60\xc3\x44\x84\x30\xeb\x80\xdd\xcc\x43\x19\x6f\x1f\xbc\x6b\x05\x90\xea\xa9\xad\x25\xaf\xf5\xe2\x12\x1e\xfe\x02\x4b\x03\xc5\x3c\x50\xdf\x9e\xd5\xd1\x47\x4c\x03\xb0\x67\x43\x41\x63\x35\x6c\x47\x04\xad\xd1\x48\xe8\x1b\x26\xdc\x35\x24\x0a\x63\x55\xd5\x9c\xd0\xb5\x55\x55\x00\x70\x91\x42\x5f\xfd\x4f\xfc\xcc\xab\x6c\x42\x4e\xf0\x73\xa5\x1d\x9c\xc2\x6e\x88\xb0\x1e\xa9\x58\x1f\x21\xc9\xf5\x4d\xa6\x61\x37\x22\xf4\x4d\x4b\xcf\x00\x83\x2d\x3d\x93\x11\xfa\xc6\xde\x04\x07\xe5\xb5\x37\xc1\x29\x40\xfb\x84\x42\x7d\xae\x97\xea\xaa\x2f\xb3\x4d\xb0\x5e\x9a\x4b\xc2\x06\x21\x27\xf4\x8d\x49\x05\xf8\x32\x89\xe0\xb7\x4c\x97\xcd\xa3\x8f\x6b\x9b\x2c\x64\x52\xb0\x52\xdf\x55\x87\xe7\x11\x14\x6c\x0e\x28\x70\x85\xd0\x27\x25\x75\x80\x4d\xed\xee\xa1\x86\x21\x08\x30\x66\x53\x86\x2b\xd0\xd1\x63\x85\x98\x90\x23\xf5\x91\xa9\x81\x1f\x6f\x2e\x41\xd8\x6c\xcf\xf4\x15\x6c\xee\x41\x83\xea\x29\x36\xb5\xb9\x43\xee\x66\x16\x29\xfa\xaa\xf4\x21\x5b\xfb\xf1\x40\x21\xe4\xb5\x76\xa2\x81\xc1\x6d\xbd\x32\x61\xdf\x54\xca\x19\x1e\x0a\x63\x3c\xe2\xa1\xa9\x81\x46\x76\x53\x08\x60\xa1\xad\xb9\x30\xb2\x5d\xf1\x1a\x43\x88\x0d\x5e\x88\x73\xc3\xa0\xe8\xc2\x6c\x30\x80\x52\x7b\xa3\x0b\x0d\xda\xc7\x4c\x45\x86\x0c\xbe\xad\x7d\x3e\x84\x5c\x05\x4f\x7d\x97\x09\x88\xea\x26\x27\x2a\x02\x4f\xf5\x2d\x56\x2e\x5a\x73\x36\x0f\xc1\xf6\x4e\xe5\x1d\xba\x3d\x8f\xf4\x13\xf1\x27\x91\x5c\x65\xe8\x26\x43\x0a\x6e\xb8\x75\x80\xba\x45\xa4\xb5\x44\x61\x74\x43\x8c\x73\xda\x18\x21\xc6\x4f\x45\x1b\xc2\xb3\xae\x0a\xeb\x96\x39\x31\x4f\x77\xf9\x28\xd4\xb6\x07\x76\x35\xb5\xf6\xc4\x2e\xac\xd3\x89\xe2\xa5\x7c\xe6\xf3\xd1\xe6\xc2\xdc\x1b\x17\xa2\x3c\xbc\x5b\xe3\xb0\x09\x8b\x6a\xce\x0a\xa3\xc5\x62\xae\x30\x76\x7c\xed\x82\x45\x00\x98\x7a\xa3\xb7\x3c\xbb\xd8\x77\xcd\xdd\x1f\x71\x94\x61\xa2\xeb\x4a\xc8\xbc\x2a\x8d\x78\x9b\x58\x85\xeb\x0e\x55\x3c\x59\xb9\x30\x6b\xd1\x12\xc3\x46\x18\x05\x37\x0b\x09\x7d\xd3\x1e\x11\xa0\x31\xb5\x67\x6a\x7d\x08\x67\x7a\x3c\x14\xd8\x00\x30\xa6\xac\x37\x65\x6a\x0d\xea\x11\xa1\xff\xd5\xd2\x43\x3d\x42\x2f\x5b\x7a\x88\x13\x7a\xd9\x38\x35\x73\xd9\xee\x07\x31\xa1\xff\xe5\xfa\x01\x23\xf4\xd2\xab\x3f\x18\xe2\xfe\xab\xcd\x37\xa4\xd2\xe6\x7b\x40\xe8\xe5\x86\x49\x2e\xca\xdc\x7a\x35\x86\x99\x42\xba\x7e\x88\xa1\xd0\x5d\xe0\x54\x7f\xd9\xc3\xf1\x73\x40\x54\x72\xf2\x15\xf9\x8a\xfe\xd7\xfb\xd7\xef\xf0\x43\x78\x6e\xe3\x33\x42\xed\xe0\x13\x77\xd5\xcc\x3b\x22\xf4\x7b\x6f\xb3\x13\x0c\x02\xe1\xc3\x7d\x80\x33\x7d\x08\x2a\x86\xc2\x89\xa6\x67\x79\x17\x30\xd6\x19\x69\x0c\xc9\x59\x68\xa6\x68\xc6\x53\x3c\x56\xa0\xb9\x58\xa5\xaf\x40\xeb\x38\x3e\x06\x58\xfb\x85\xcf\x30\xaa\x30\x2a\x64\x3c\xec\x2b\xd8\xf8\x89\x1b\xd0\x78\x7b\xc7\xa1\x42\xd8\xa5\x08\x05\xaa\xd0\x90\xf1\xf7\x6e\x6f\x07\x82\xba\x99\x40\xac\x42\x5a\xb7\x71\xae\x60\xeb\x36\xce\x14\x6c\xdd\xc6\x53\x05\x1b\xb7\xf1\x9e\xe6\xc4\xb9\x8d\xf7\x54\x66\xd2\xb8\x85\x0f\x54\x00\xeb\x46\xae\x59\xb3\x0b\x20\x00\x7a\x5e\xe4\x90\x9f\xef\x55\x8e\xf9\xc9\x5c\x77\x92\xee\x40\x83\xa5\xdb\x12\x86\x18\x9e\x1f\x39\x24\xe8\xf9\x91\xcf\x09\xfd\xde\x81\x11\x14\xde\x73\x2b\x07\x66\xb4\x5b\xf9\x56\x7f\x7e\x9c\x90\x0b\xfc\xb4\x6e\xe5\xa9\x02\x9d\x5b\x39\x37\x08\xed\x56\x3e\x0e\x09\xfd\xde\xdb\x31\xee\x8f\x08\x15\x3e\x0c\xcd\xc2\xdb\x31\x06\x3b\x50\xf8\xf0\x10\x61\xeb\x56\x0e\x2d\x01\xdd\xca\xb7\x10\xcf\x1c\xbf\x00\xd6\xed\xe9\x0b\x00\x9c\x5b\x39\xc4\xcf\x0a\xcf\x6f\x1c\x52\xf0\xfc\xcc\x33\x0d\x0a\x1f\xb6\xee\x46\x20\x04\xce\xcc\x45\x31\xa9\x82\xdc\x49\xb4\x99\x42\x78\x27\xd1\x74\x10\x53\x01\x19\xa1\xdf\x73\x9f\xa4\x15\x6a\x1f\xa6\xdf\x42\xdd\xb6\x07\x33\xef\xef\x9f\x7d\x63\x3f\xf7\x2d\x15\xcf\x1c\x7e\xe7\x9a\x11\x47\x7b\xbf\x6e\x53\xf1\xd2\x22\xe1\xbb\x7b\x42\xbe\xbe\xbb\x27\x14\xa1\xa5\xd6\xa0\x5d\xd8\x33\x84\xc0\xb5\xf3\xe7\x04\x1d\xe0\xfc\x39\x61\xe6\x26\x9c\x3f\x27\x18\x4e\xc2\xf7\xe7\x4c\x09\xfd\x5e\xf9\xb2\x84\x5d\x86\x61\x35\xa0\x22\x56\xe6\xec\x0e\x68\x1a\xf4\x6a\xdb\xf5\xc9\x1f\x1b\x52\xd3\x29\x1f\xba\x56\x7b\x51\x30\xf6\x83\xb6\x70\xac\x79\x87\x99\x0b\xd7\xf2\xb2\x4b\x7b\x7e\xc2\x9e\x63\x7e\x57\x47\x6a\x7a\xe6\x1b\xee\xf6\xb9\xe6\x0f\x2d\x6d\xc7\x37\x1f\xa6\x50\x96\xd6\x76\xaf\xee\xef\xd0\x34\x6b\x86\xef\xe7\xad\xda\xf3\x3c\xde\x9d\xab\x14\x4a\xd8\xa3\x18\xe7\x28\xac\x23\xc0\xef\x78\xe8\xf7\x3c\x42\xcb\x81\x3e\xd5\xa4\x5d\xaf\xfb\xb1\xa6\xb4\xdd\xea\xc7\xa6\x84\x2d\xf7\xf9\x81\x43\xab\x96\xcd\x62\x87\x69\x88\xc8\x94\x6c\xc7\x83\x3e\x35\x11\x76\xb7\x4c\x5a\x14\x6d\x1d\x74\x5b\x68\xdf\x89\xde\x08\x7b\xd7\x8b\xbe\x37\xb7\xa4\x36\x6b\xa9\xa5\xb4\xeb\xae\xd7\xa2\x68\x2d\xc2\x35\xba\x1d\xbc\xdb\xc0\xfb\x15\xa4\xef\x6b\x42\xc7\x71\x91\xd7\xed\xcb\x6e\x40\x2d\x79\xde\xcf\x50\x75\x85\xf3\xcd\x84\xea\x2a\x8c\x2f\x26\xf4\xff\xb6\x73\x72\x64\x70\x1e\x5c\xba\x1b\xa0\x41\x87\x7b\x5e\xc4\x19\x82\xd6\x8b\x18\xa9\xce\x8b\x18\xf4\xab\xe7\x21\x3b\x40\xb0\x69\x04\x41\x31\x9d\x11\x84\xc9\x79\xbe\xb1\x98\x9e\x3f\xab\x86\x3a\x81\xd9\x82\x7f\x32\x77\x3c\x04\xb1\x60\x36\x81\xfa\x30\xab\x47\x63\x28\xfc\xba\xb1\xa7\x01\xe3\xb6\xe7\xcb\x0a\x9d\x74\xe7\x1c\x09\x34\x2f\xdf\x27\x15\xe4\xdc\x36\xbb\xa0\x07\x3b\x9f\x54\x8c\x61\xc6\x05\xd0\x58\x3e\x20\xd0\xcf\xf4\x02\x3f\xec\xd0\x32\xd6\xa0\xf0\x60\xdf\x03\x14\xea\xc9\x6f\xd9\xc0\x83\xbb\x9a\x6e\xac\x20\xee\x5a\xaa\xf0\x6e\xaa\x1b\x29\xd0\xfa\x34\x8c\x53\x68\x64\x9b\x82\x3f\xe5\x05\xbb\xd5\xf7\xe7\x8e\xe7\x20\x9c\x4d\xe1\x79\x79\x42\xbc\x1b\x5d\x22\x4e\xe8\x5b\xdf\xa0\x63\x84\xd6\x3e\x3c\x23\xb4\x9e\xb9\xe2\x00\xd9\x7a\x86\x01\x03\x6f\xbd\x71\x7c\x10\x22\xd5\xc1\x11\xd0\x75\xd8\x14\x68\xaa\x1c\x43\x48\xd4\x6d\xbc\xc0\x70\xe4\xed\xbb\x00\x60\x26\x28\x3d\x48\xc0\x33\x04\x38\x86\x74\xf0\x1c\xe8\xf6\x28\x6c\x1f\xf3\x70\x20\xa6\xeb\xe6\x3e\xc8\xbb\x9d\xfb\x0c\x10\x72\x73\x9f\x31\xc0\x8d\x26\xd4\x05\x8c\x9b\x70\x60\x5e\xc6\xd8\x88\x80\x66\x8c\x0d\x00\xb2\x4a\xea\x89\x3c\xd3\xa0\xae\xd0\xbe\x82\x74\xf1\x06\x90\xad\xef\xae\xd6\x57\xb0\x31\x45\x47\x00\x3a\xeb\x73\xa4\xa9\xbe\x9f\x77\xad\xec\x87\x1b\x36\x84\xef\x55\x3e\x21\x53\xf8\xa8\xaf\xed\xe2\x34\x14\x85\xfb\x97\x9f\x46\x03\x85\x29\x7d\xf0\x46\x0f\x52\x60\x33\xbe\x6d\xcd\x73\x20\x40\x13\xd5\x0d\x11\xd5\xb8\xcb\xa8\x86\x21\x02\xc1\x01\x98\x18\x6f\x5f\x78\x17\xfb\x03\x0f\x4b\xef\x6a\xff\x31\xd0\x2d\x75\x84\x54\x43\x83\x66\xb4\xac\x84\xdc\x73\x8f\x27\xe2\xf7\x9c\xb3\x6b\xed\xb5\x75\x35\x66\x77\xd1\x0b\x13\xd8\x67\x12\x20\xa1\x71\x15\xe8\x18\x2a\x6e\xa9\x2e\x45\xcf\x08\x7d\x9b\x2f\xcc\x45\x4b\x30\xf2\xd7\x0e\x4c\x0d\x38\xd7\x70\xac\xe1\x2b\x1f\xb6\xfb\x0f\x08\x38\x6f\x47\x86\xb0\xd9\xf0\xeb\x2a\xe8\xb2\x01\x9a\x9b\x10\xb9\x82\xcc\x3b\x1c\x21\x82\xe6\x0a\x99\x4c\x41\xe6\xcc\xcd\x1c\x41\xe3\xcb\xd8\x1b\x20\xe8\xa9\xd8\x1e\x22\xbc\x8b\x5f\x80\xc9\xe6\xd9\x59\xbc\x88\x4c\xbd\x2b\xa0\x1b\x0a\xd4\x13\x20\xf7\x34\xa7\x15\xab\x97\xba\x67\xc1\x74\xaa\x5e\x35\x2e\xfc\x83\xdc\x9a\xd5\xb3\xca\x75\xaa\x5d\x05\x9a\x93\xb0\x0c\x01\xb3\xf4\x91\x2a\xc8\x38\x75\xa4\xc6\xd1\xfc\xed\xeb\xe7\xef\x6c\xeb\x81\x40\xd5\x5c\xda\xf6\x83\x70\xe1\xd6\x56\xe7\x0a\xd6\x3a\xb1\x87\xd0\x84\x7c\x4d\xe8\xdb\xf6\x82\x3b\x64\xde\x1e\xa9\x20\xfc\x9a\x99\xd5\xa2\x01\x2a\x35\x84\xdd\x05\x2e\x0a\xe5\xad\xa6\xd6\x97\xf6\x7d\x12\x68\xb5\x08\x9a\x05\xe1\xae\x29\x83\x7b\xd5\x2a\x86\x01\x0b\x41\x13\xa8\x67\x0b\x7a\x69\x9f\xd3\x03\xe6\x2e\xdd\xe6\xed\x5c\x83\xba\x6e\xb0\xb5\x5e\x36\x76\x6a\xe7\x0e\x63\x1a\x94\x09\x65\xf2\x0d\x35\x68\x12\x89\x35\xec\x39\x77\x38\x8c\x4d\x04\x43\x79\xf7\xd3\x81\x5e\xdf\x0b\xef\x5e\x45\x81\x9d\x78\x8f\x07\x4a\x13\xeb\x99\x63\xe3\xc8\x91\x9a\x5e\x27\x6d\xbc\x1f\x29\x36\xc4\xf7\xa5\xcb\xba\xa7\xd9\xd6\xe3\x25\x36\xb5\xcb\x8d\xe3\xb9\xbe\xdc\xf8\xa4\xe6\x8a\xc0\xdb\xf6\xa2\x0c\x74\xc6\xb6\x75\x00\xfd\xa3\xad\x58\xdb\x2d\xbd\x96\x86\x03\x7c\x96\xe4\xad\x79\xc9\x0c\x21\xef\x5d\x33\x0d\xcd\x35\x08\xad\x4a\x0a\x86\x3b\xc4\x8d\x27\xf5\x3c\x82\x5d\xf3\xce\x14\x12\x8d\x75\x3c\x8c\xe1\x9a\x0d\x14\xc5\x00\x60\x1d\xd7\x9b\x99\xd5\x45\xb3\x0c\x61\xeb\x0f\x80\x90\xd9\x6c\x1f\x28\xc8\x06\x46\xad\xb7\x99\xad\x36\x85\x41\x44\x88\x30\x23\x2a\xcc\x41\x01\x34\xf1\x19\x82\x4e\x03\xcd\x14\x5b\x9e\x06\x1a\x23\xc2\xf3\x34\x40\x56\x2d\xac\xb9\xf5\xb7\xf5\x07\x0e\x73\xe9\x98\xde\x75\x25\xb2\xe1\xec\xe3\x1f\x9a\x1d\x85\xba\x6c\x70\x6c\x57\xc2\xc1\xd8\x03\xd8\x3c\x39\x91\xf5\x35\x6c\x8e\x39\xa0\x04\xd2\xe6\x0a\xf4\x48\xe1\x26\xce\xb2\xd9\xa4\xad\x15\x68\x18\x4c\x1a\x5e\x4d\x10\x6c\xaf\x4b\x93\x43\xef\xac\x40\x7b\x89\x34\xdc\x98\x54\x86\xce\xb5\x42\xc1\xcd\x15\x68\xa6\x91\x6e\x05\x7a\xa0\x31\x4d\xfb\x67\x93\xb6\xec\x9d\x4d\xba\x7c\xb7\x64\xde\x02\x44\xad\xd7\x14\xe2\x08\xba\xa9\x0f\xd4\x1b\x3d\x59\x18\xe0\x08\xb7\x59\x47\xb8\x50\x87\xc9\xae\xd5\xc5\x8f\x31\x7e\x77\xf1\x1b\x45\x69\x7c\x3f\x40\x47\xd8\xf7\x2f\x30\x2d\xf7\x84\x13\x4c\x9c\x00\x76\xb5\x82\x12\x77\x8e\x22\x08\x99\x46\x37\x54\x90\x6b\xb4\x3d\x4c\xba\xe1\xdd\xe5\x30\x7e\x93\x51\x31\x97\x66\x5b\x70\x98\x8e\x35\xc2\xe6\xab\x42\x78\xa7\xb3\x50\x1e\x6b\xaf\x43\xa8\x02\xda\x0e\x91\x2a\xd0\xf0\xa6\x82\xbb\x0e\x91\x62\x5d\xad\xdb\x9c\xb9\xf6\x1f\x19\xba\x6d\xc4\x43\x87\xb9\x6c\x94\xbf\xd1\xd4\x67\x1e\xea\xb2\xc1\x8b\x6b\xea\x4a\x88\xae\x70\x3d\x0d\x9b\xa6\x0e\xc9\xfa\xfe\x12\x1a\x36\x0a\x12\x84\xe3\xf9\x4b\x8c\x35\xd5\x3f\xa8\x58\x5f\x97\xce\x24\x85\x26\xf1\x9b\x7e\x21\x38\x9b\x13\xfa\x0e\xdf\xaf\x95\x84\x4a\x26\x16\x66\x6f\x13\xd4\xe7\x3b\xa6\xdd\x5e\x58\x0f\x88\x1a\x80\x6a\xf4\xde\xe6\xec\x11\xfa\xce\x9f\x67\x00\xd5\x87\xfb\x40\x77\xd3\x84\x41\x0c\x74\x0f\xee\x02\xdd\x58\x13\x48\x34\xa6\x04\x00\x99\x7d\x78\x60\x46\xa8\xe4\x85\xd9\x5f\xea\x46\x90\x6e\xcb\x52\x1e\x12\x2a\x5b\x96\x72\x44\xa8\x5c\x72\xc1\xd5\xb5\xcc\x71\xb7\xa7\xe1\x79\x65\x1e\x1a\x00\xd4\xbb\xbd\x28\x7b\xfd\xd1\x08\x23\xd9\xfb\x8f\x0c\xa8\xdf\x41\x0e\xbb\x59\xa4\x31\x57\x3e\x9c\xa7\x1f\xdb\xcf\xd0\x22\xb2\x61\x8d\xb6\x4f\xaa\xf4\xe7\xe6\x92\xbd\xf6\x41\x94\x31\x46\x77\x57\x45\x23\xfc\xd1\x7f\x3c\x57\x2e\x5b\x69\xbf\x78\xfd\xfd\x77\x58\xc9\x1c\x88\xea\x0e\xf8\x9b\x39\x00\xcd\xd7\x33\x3c\x1d\xd6\x35\xa0\xef\x1f\xd9\xd5\xb8\xb6\xdf\x64\x5f\xe3\x7d\xa7\x49\xe0\x03\xa6\xd0\xc6\x02\x64\x58\x05\x88\x51\x21\xc0\x72\x36\x93\xec\x1b\xe8\xc7\x08\x98\xcb\xa4\x90\xe8\x5f\x74\x26\x2b\xae\x57\x8e\x61\xa2\x22\xab\xb5\x79\xb3\xb2\x0b\x73\x25\x59\xad\xdd\xa1\xbb\x08\x61\x9d\x0b\x54\x61\xdb\xc2\x9c\x61\x80\xa6\x85\xd9\x57\x38\xb3\xb3\xcc\x32\x06\x88\xda\xe4\x09\x52\xf6\x77\xf8\xa0\xfd\x08\xa6\x4b\x8b\xf7\xb2\xbe\xfb\xfe\xec\xe9\x33\x07\xb6\x9e\x1a\xed\x3b\x8c\xf7\xca\xe8\xdc\x61\xbd\x07\x46\xbb\x4d\xac\x51\x21\xb3\x9e\xc3\x9b\xf5\xa6\xd4\xa1\xfc\x67\x48\xc7\x2d\xb4\x4d\x42\xb1\x61\x3a\x53\x9f\xab\xf8\xbc\x91\x9a\x9b\x54\xb0\x2e\xb4\x3f\x91\xaf\xdd\x8b\x69\xaa\xff\x01\xca\x86\x51\x99\xd5\xc6\xb4\xcf\x10\x94\xf6\xf0\x6f\x17\x23\xac\xf9\x6f\x66\xe9\xbb\xcb\x41\x5a\x6d\x4b\x0e\x44\xd1\xb6\xe4\xc6\x84\xbe\x73\xd3\xfb\x01\x86\x30\x4a\x01\xd4\x92\x9b\xbc\xc2\x30\x28\xdd\xec\xb5\x3f\x83\x1c\xdc\x49\xe1\x01\xc6\xf5\x60\x68\x6e\xd7\xf9\x8d\x39\xcb\x01\x05\xbf\xae\x96\x9c\x65\xed\x63\x38\xdc\x52\x76\x0e\xdd\x84\x84\xbe\x77\xee\x66\x8c\xd0\x8d\x73\x37\x43\xc8\x2a\xe6\x08\x42\x5a\x68\x4e\xe8\xc6\x69\x69\x4d\xab\xdc\x5d\x98\x63\x42\xdf\xcf\xdc\xdd\x5c\x9c\xd0\x8d\x03\xfb\x1c\xa9\xf6\x86\x60\x60\x7d\xe3\xc3\x19\xa1\xef\xad\x6b\xdb\x8c\xd0\x8d\x75\x6d\x9b\x01\xc5\x08\xb3\x0b\x14\x23\x4b\x00\xbc\xa7\x8a\xfa\x84\xbe\xf7\x9c\xd7\x86\x21\x90\x3d\x38\x02\xd8\xad\x5c\x01\x83\xfe\x46\x06\x70\xd8\x52\xc8\x23\x08\xd2\x54\xc8\x31\xa1\xef\x9d\x13\xda\x98\xd0\x8d\x73\x42\x03\xc8\x6d\x6d\x00\x77\xee\xcd\x21\xe8\x33\x1b\x77\xea\x0b\x2c\x91\x8d\x77\x35\x05\xf0\xea\xbf\x88\x93\x1a\xd8\x9e\x97\x57\x18\xf7\xf0\x05\xa4\xe7\xdd\x29\x31\x22\xf4\xbd\xf3\x37\x03\xb3\x69\xe3\x81\x20\x50\xe5\x3b\xc4\x20\x60\x99\x69\x6f\xa1\x5f\x0c\xe0\x79\x0a\xcd\x3d\x9c\x73\x15\xea\x6b\xec\xae\xaf\x10\xd4\x9c\x9b\x28\x81\x16\x40\xd0\x9d\xef\x1d\x81\x64\xdd\x1d\x7e\xc3\x98\xd0\x8d\x07\x42\x84\xb6\xa6\x83\xc2\xb6\x35\xdd\x80\x50\xbd\xc4\xe2\xde\x70\x81\xa4\xd6\xac\xb9\xec\xb2\xb3\x0e\xf3\xde\x0f\x91\xb9\x10\xad\x25\x22\x68\x3f\x60\x2b\x36\x9f\x84\x81\x72\xb7\xdf\x9a\x51\xc8\x56\xc8\x0c\x91\xbb\xfb\x65\x50\xd1\xeb\x9d\x67\x5e\xb0\x39\xac\x77\x1f\x79\xc1\x76\xb1\x6e\x8a\x6e\xbd\xde\xbd\xbc\x61\xa0\xf1\x3b\xab\x51\x43\x88\x6f\xdd\x10\x90\x27\x03\x65\xb1\xa2\x2d\x1d\xf8\xde\x9f\x0d\xb2\xbe\xa2\x5b\x84\x8a\xde\xda\x71\x31\x38\x3d\x4e\x61\x1c\x5d\x07\x66\x13\x07\xba\x8d\xff\x66\x4b\x66\x60\xdb\x98\x15\xc6\x35\x66\x28\xa6\xdd\xa4\x88\x50\x66\x1e\x08\xb2\x72\x0b\xd9\xd0\xcd\xde\xb7\x6f\x06\x84\xfe\xd3\x56\xc3\xd0\x07\xbc\x87\x5a\x40\xef\x79\xf7\x27\x0e\x80\x4b\x1f\x86\xde\xeb\x56\xcb\xfb\x0a\x32\xcb\xe3\x3d\x42\x37\x4e\x33\x42\x09\xdf\x1b\xc7\x3c\x68\xab\xc6\x31\x0f\xbe\x1b\x2f\xba\x0c\x09\xbd\x62\xe5\x42\x98\xcd\x85\x14\x60\xb1\x33\x09\xbf\x62\xc2\xbb\x8b\x10\x58\xbd\x62\xa2\xac\xc0\x60\xd2\x3e\xe3\xa1\x0a\xd5\x98\xa5\x03\x6c\xc0\x81\x02\x5b\x4e\x2e\x57\x4e\x7d\x43\x78\xa7\xbe\x55\x6c\xbb\x7f\x0a\xb6\xc7\x15\x13\xfe\xba\x64\xac\x30\xed\x99\xaf\x59\x5b\xf2\x69\x76\x0a\xdc\x20\xb6\xe6\x11\xfb\x68\x76\x42\xe1\x11\x3d\x4b\x35\x53\x5c\xed\x7a\xca\xcf\xe2\x06\xc1\x73\x89\x87\xb9\xe0\x95\xd1\x0f\x8c\x8f\x08\xfd\xc1\x5a\x72\x7c\xa6\x68\xe6\x8d\xbd\x31\xa1\x3f\x58\xd7\x43\x48\xd1\xba\x1e\x02\xe0\x79\xb2\x03\xe8\x39\xb2\x43\xa2\x1e\x15\x92\xf1\xa8\x33\x4d\xd5\xf3\x70\x0e\x15\xc3\xb9\x61\x22\x9e\xcd\x10\x56\x00\x98\x84\x3f\xf8\x4f\xc7\x5f\x71\x6e\x6d\x24\x06\xa0\xbd\xd9\x39\xe6\x1c\x60\x75\xff\xf1\x1d\x44\xf3\xae\x42\xc6\x3c\xa0\x8d\x29\x82\x74\xe8\xdd\xd3\x3f\x5d\x87\x54\x47\xb5\xef\x1c\xe2\x2d\x5f\x33\xc1\xcc\xd6\xe1\xb0\x3f\x72\x24\xdf\x46\x0e\x11\xbd\x73\xd4\x9c\x11\xfa\x43\x6b\x00\x1d\x13\x7a\xd5\x1a\x40\xa1\x82\xdc\xc9\x59\xac\x49\xef\x54\x89\x3d\x20\x72\xe5\x1d\xe7\xb0\x27\x33\x7e\x68\x8f\x13\xd0\xc4\xdb\xe3\x04\x74\xb9\xa6\x93\xd8\x95\x77\x77\x0c\x14\xbf\xad\x3c\x40\xf0\x6d\xe5\x01\xd5\xd4\x58\x90\xb2\x4d\xb4\xb1\x2e\xe5\x61\xbd\xb9\x7a\x03\xcb\xdb\x3d\xe0\x07\xbf\x6d\x41\x2d\xff\x96\x2f\x7e\x63\x0b\xad\x21\x18\xa1\x3f\xba\x7d\xa7\x61\x8f\xd0\x6b\x0f\xec\x13\x7a\xcd\x33\xdb\xa4\xfb\x73\x84\xcd\xa9\x8a\x78\x48\xe8\x8f\xde\x53\x9a\xa1\xa6\x9a\x26\x35\x06\x38\x37\xee\xb2\xf8\x3e\xcf\x8f\xad\x1a\x63\x84\x5e\xb7\x6a\xac\x47\xe8\x8f\x6d\xc1\x73\x42\xaf\xdb\x82\x1f\x11\x7a\xed\xa5\x7c\x2d\x5c\x73\xb9\x16\x5c\xdf\x0a\xab\xe0\x1f\xdb\x55\x10\x13\x7a\xdd\xae\x82\x94\xd0\x1b\xbb\x14\x0e\xfa\xe8\xc6\xbe\xd3\xd3\xe7\x73\x00\x4d\x0b\x01\xa3\xe3\xc6\x7b\x85\x2b\x23\xf4\xa7\x56\xb9\x66\x84\xde\xb4\xca\xd5\x27\xf4\x66\xe9\x9e\xd3\x1a\x02\x78\x66\x41\x46\xe8\x4f\x5a\xb9\x82\x35\x7d\x63\x5e\x18\x82\xef\xc2\xc5\x82\x44\x0a\x17\x6b\x44\xe8\x8d\xb9\xfd\x03\x2f\x99\xba\x71\x27\xf6\x81\x05\x7b\x7e\x82\x41\x4b\xf8\xa9\x2d\x56\x28\x55\x5b\xac\x63\xc4\xd9\x79\x4b\x18\x01\xec\xe6\x29\x21\x08\xc6\x7b\x15\x6c\x00\xa0\x63\x68\x4c\xe8\x4f\x6d\x61\x83\xb4\xda\xc2\xce\x00\x67\x37\x15\x58\x08\xc9\x6c\xbc\x5c\x7b\x00\x3b\x09\x43\x12\x57\xbe\xe6\xba\xb9\x6e\xb6\xbb\x9f\xdd\x14\x23\x23\xf4\xd6\x4d\x31\x32\x42\x7f\x3e\xb3\xf6\xfc\x1c\x69\xc6\xa0\x9f\x13\xfa\xb3\xd7\xd8\x07\x84\xde\x7a\xe0\x10\xa8\x26\xe2\x0c\x68\x26\x1e\x00\xfa\xbd\xd8\x3e\xa1\x3f\xb7\xaa\x3e\x25\xf4\xb6\x55\xf5\x03\x42\x7f\xb6\xf7\xa8\x87\x43\x42\x6f\xed\x45\xea\x7d\xc8\xa6\x7d\xe0\x3e\x24\xf4\xb6\x5d\x2f\x8c\xd0\x9f\xdb\x92\xed\x11\x7a\xdb\x96\x2c\x27\xf4\x67\x37\x81\xe1\x84\xde\xba\x19\x0c\x42\xda\x76\x80\xc2\xab\x6f\x28\xec\x88\xd0\x7f\x7b\x7b\xe7\xc3\x31\xa1\xbf\xf9\x30\x23\xf4\xdf\xde\x32\xd5\x30\x23\xf4\x37\x1f\xe6\x40\x37\x83\xdb\x10\x88\x66\x70\x1b\x12\xfa\x6f\x7b\xd7\xdc\x70\x46\xe8\x6f\x0e\x4a\x09\xfd\x8d\xbb\xfb\x73\x61\x7c\xfa\x37\x17\xd5\x8f\x79\x26\x97\xad\x5b\x45\xfe\xed\xd6\x97\x06\x10\xcb\x2e\x2f\x01\xd4\x12\x37\x64\x69\x1f\x6d\x87\x34\xed\x04\x18\xc6\xa8\xdf\xec\xfc\x17\xea\xc5\x7f\xe3\x2e\x82\xb6\xf3\x5b\x5b\xf0\x90\xb9\x75\xff\x88\x7b\x84\xfe\xbb\x5d\x0d\x7d\x42\x7f\x6b\x57\xc3\x9c\xd0\xdf\xae\x7f\xd5\xfc\x43\xb2\xd7\xa5\x81\x52\xb2\xdd\xd2\x4f\xdb\x0b\x1a\x77\x27\xe7\xf3\x4d\x89\x5b\x4e\x1d\x4e\x25\x2d\x83\x4f\xf2\x84\xdf\xac\x2b\x21\xeb\xe4\xd3\x99\xbb\xbb\x3f\x22\x94\xb9\xbb\xfb\x23\x42\xcf\xec\x7d\xfd\x31\xa1\xcc\xde\xd7\x8f\x80\xf7\x9e\xec\x99\x3e\x21\x75\x93\x0e\x08\x65\xfa\x7c\xd4\x0d\x18\x09\x67\xee\x62\xfd\x90\x50\xe6\x2e\xd6\x07\x68\xb5\x9e\x90\x43\x42\xcf\x5e\xbd\x51\xff\xda\x38\xbe\x01\x0b\x9d\x19\x80\xf7\x09\x3d\xb3\xc7\x4d\x40\x27\x32\x0b\xf1\x2e\xa1\x67\xe6\x3e\xf0\x1e\xa1\xcc\xdc\x07\xde\x23\x74\x26\xf4\x59\x92\x1b\x36\x20\xf4\x89\x7d\xcc\x1f\x9f\xc1\xb7\x10\x1f\xb6\xde\xf9\x6f\xbc\xe3\x7f\xdf\x03\xe0\x8d\x87\x9c\xbd\xd7\x80\x9b\xef\xc9\x7e\xee\x19\xc3\xfb\x9f\x25\xfc\xdc\xc3\x7e\x7f\xec\xd9\xb1\x3d\x0f\x4a\x35\x1e\x90\x72\x0f\x3e\x35\xdf\x52\xf9\xdc\x63\x0e\xf7\x3f\xe0\xd0\x78\x7c\xe1\xb3\xef\x29\x34\xae\xa5\xbf\xef\x3a\xf7\xe6\x05\xd7\x8d\xab\xe3\x1a\x57\xaa\xb5\xee\xfd\xf2\xee\xf3\x6a\x5c\xeb\xe4\x5d\x1e\xf2\x99\xc3\xac\x9f\x3b\xb0\x78\xff\x11\xc5\xcf\x1e\xdf\xbb\xe7\x88\xd7\xe7\x0e\x5e\x7d\xee\xa8\xd5\x7d\x07\xa7\x1a\xe7\x9a\x9a\x27\x59\xfc\x23\x25\x7b\xdc\xdb\x1b\x0e\xe3\x7b\x5d\x6d\x1b\xee\x34\xce\xfb\xe3\x8b\x36\xb0\x1a\x3b\x1a\x9f\x59\xf9\xf6\x56\x9e\x3f\xb7\x8c\xf7\x99\xc5\xb4\xcf\x2d\x5f\x79\x8b\x44\xf7\xcc\x6f\x3f\x37\xb0\x7b\x83\xb0\x37\xac\x19\xe5\xda\xfb\xac\x72\x35\x3a\x4e\x5d\x5a\xf6\x95\xed\x6a\xba\x45\x9b\xfa\x30\x89\xf5\x77\x13\xbb\x62\xe2\x40\x24\xaf\x67\xbf\xf2\x54\x9e\xa4\x78\xe3\xc7\xdd\x9d\x0b\xa4\x02\xc8\xc4\x62\x82\x4f\xdb\xa9\xe0\x72\x23\xca\x03\x79\xb2\x16\x95\xac\xe4\xed\x9a\x27\x9c\x96\xfc\xfa\x40\x6e\x69\x65\xd2\xfa\xc8\x6f\xeb\x7d\x29\x9d\x5f\x4c\xe7\x95\xe8\x00\x50\x1e\xe4\xe5\x01\x0f\x74\x04\x9b\xd8\xc9\x92\xd5\xaf\xaf\xcb\x37\xa2\x5a\x73\x21\x6f\x4f\x52\x56\x14\x1d\x4e\xcb\xe0\xf0\x50\x9e\xac\x37\xf5\xb2\x53\x06\x86\x87\x72\x4b\xf3\xe4\xb9\xce\xc4\x4b\x62\x96\x97\xd9\xbe\xdc\xe5\x32\xaf\x4d\x5c\xaf\x4c\xb6\x44\x6c\xbd\x2e\x6e\x3b\x9c\x32\xb1\xd8\xac\x78\x29\xeb\x60\xbb\x9d\x9a\x80\x07\xac\x13\x7c\x82\x14\x4e\x7e\xe1\x57\x40\x3c\x3c\xfc\x22\xde\x21\x0a\x25\x3a\x0e\x09\xee\xee\x3a\x7e\x22\x89\xe8\x94\x9b\xa2\x08\xa8\x8f\x7c\x52\x6d\x4a\x99\x84\x06\xb9\x62\x37\xdf\xe6\xb5\xe4\x25\x17\x75\xb2\x8b\xba\xbb\xbb\xaa\xf2\xec\x20\xdc\xba\xa6\xc1\x28\x3b\x79\x06\x49\x3d\x5b\xe5\x52\x72\x81\x08\xc7\xa6\xc9\x5b\xc5\x6b\x92\x1a\x99\xa9\x00\x53\x90\x5e\x4d\x8b\x24\x0a\xa7\x52\xdc\xa2\x30\x37\xc9\xa7\xed\x54\x97\x3f\xe3\xf3\xbc\xe4\xa6\xd4\x56\x2c\x4d\x74\x67\x43\xc9\x0d\xa1\x9f\xae\x58\xb1\xe1\x93\x70\x1b\xd0\x3a\x09\x93\x24\xd9\x9c\xdc\x6c\x53\x26\xd3\x65\xe7\x3a\xf8\x54\x27\x0f\xa2\xad\x15\xf8\x1a\x6a\x4e\x57\x8e\xe2\x24\x49\x92\x16\x8b\xa7\x0c\xf2\x61\x9b\x42\xbe\xf2\xb0\x93\x56\x28\x97\xe6\xdc\x34\xfd\x7c\xde\x91\x01\x57\x55\x54\x06\x53\x5e\xd4\xfc\xc0\x34\x4d\x91\xf0\x93\x82\x97\x0b\xb9\xa4\x55\xf2\x4b\x87\x53\x11\xd0\x3c\x09\xa7\xf9\x43\x31\x3d\x3a\xca\x83\xea\x3c\xbf\x30\x31\x5d\xd2\x99\x4a\x9a\x8a\x56\xe2\x54\xb4\x92\xaf\x5c\xf2\x39\x26\x5f\x05\x94\x25\xe1\x94\x3d\xac\xa6\x47\x47\x2c\xc8\xcf\xd9\x85\x8b\xeb\x32\x58\x9a\x0c\x68\xb5\x93\x05\xad\x5a\x99\xe4\x2e\x13\x86\x99\xe4\x28\xf1\x69\xfd\x30\x9f\x1e\x1d\xd5\x01\x3b\xaf\x2f\xfc\xd8\x2e\x9b\x99\xcb\x86\xe6\x7b\x32\xa2\x79\x2b\x2b\xe6\xb2\xaa\x31\x2b\x16\xd0\x34\x09\xa7\xe9\x43\x36\x3d\x3a\x4a\x83\xfa\x3c\xbd\x68\xc6\x77\x99\xad\x76\x84\xa6\x3a\xe1\x9f\x94\x9a\x8b\xec\xb2\x78\xa5\xb3\xa8\x94\x1a\xc8\x29\xa3\xf5\x34\x9f\x77\x88\x09\x41\x1e\x24\x09\x34\xfe\x6a\x7e\x50\x06\x72\x29\xaa\xeb\x03\xd0\x67\xef\x6e\xd7\xfc\x99\x10\x95\xe8\x7c\x45\x0a\xdd\x92\xc8\x81\xd1\x0d\x07\xab\x4d\x2d\x0f\x66\xfc\x80\x59\x55\xf2\x55\x00\xc9\x76\x40\x1c\xba\x87\x05\xa7\x1d\x76\x52\xf2\x6b\xd3\x10\x0f\x0f\x3b\xfc\x84\xaf\x72\xd9\x21\x1e\x96\x00\x7b\x27\x26\x8b\x53\xf7\x39\x29\xa1\x88\x2e\x35\x5a\x27\xec\x5c\x5e\x04\x13\x3f\x0f\xab\x41\xf8\x8e\xfa\xa8\x51\xa8\xae\x9c\x89\x2d\x67\x7d\xaa\x92\x4a\xaa\xd3\xf3\x92\xd6\x17\x93\xf3\x9a\x96\x17\x93\xea\xb4\x3e\xd9\x94\xf5\x32\x9f\xcb\x4e\x19\x4c\x6a\xa3\x70\xe9\x83\xfa\xe4\x9a\x89\x92\x67\x87\x87\x9d\x3c\x81\x8e\x19\x1c\x1e\xe6\x8f\xc2\xc3\xc3\x5a\x57\xca\xa3\x3c\xf8\x64\x02\x25\x0f\x94\xce\x28\x12\x90\xa3\x92\x21\x79\x53\xd5\xf8\xaa\xd1\x81\xaf\x98\x0e\x56\x7c\x55\x89\xdb\x83\x82\xb3\x8f\x07\x19\x97\x3c\x95\x3c\x3b\x39\x20\x47\x26\xd9\xa3\xaf\x0e\xc8\x57\x47\x6f\x25\x58\xec\x1d\x19\x1c\x7d\x45\x0e\x8c\x74\xea\x03\x96\x65\x10\xfa\x7d\xcd\x0f\xb8\x4a\xef\xa4\xe6\x0d\x45\xd0\x09\x0e\x64\x75\x90\x97\x30\xb6\xd5\xfc\xa0\xc8\x57\xb9\x3c\xf9\x2a\x98\x16\x27\x25\x5b\xf1\x84\xf8\x61\x9f\xdd\xa4\x9c\x67\x3c\xfb\x91\x89\x32\x2f\x17\x84\x16\x27\x3a\xd5\x84\xd3\xe2\x04\x47\x3a\x49\x8b\x93\x14\xc5\x6b\x18\xa4\xa4\x42\x75\x07\xc2\xed\x90\x4d\xa9\xb4\x5e\xe6\xc9\x3a\xad\xca\xba\x2a\xf8\xa9\x47\x9c\xa4\x1d\x8d\x05\x39\xea\x4f\x14\x5e\x13\xea\x90\xff\xac\x27\x07\xff\x59\x03\x2f\xc0\x30\x2d\x4e\x56\xbc\xae\xd9\x82\x07\xdb\x2d\xf6\x0e\x5d\x8d\x25\x3d\x3a\x6a\xd6\xbf\x19\xe7\xb8\xeb\x08\x8b\x0e\xb6\x87\x07\x38\x84\xcc\x73\xc1\xb3\xa0\xbe\xce\x41\xf5\x22\x46\xf9\x82\x9c\x08\xbe\xaa\xae\xb8\x91\x8a\x26\xdd\xae\xb9\x1a\x8c\xae\x05\x5b\x3f\x2f\xf5\xc8\x84\x69\x24\x0f\x42\x37\x60\x6a\xa1\x04\x9f\x52\x10\x77\x38\x31\x43\x2b\x84\x36\xf5\xe6\x86\x45\x9d\x65\x30\xc5\xd0\xd1\x97\x85\x76\x99\x9d\x87\x17\x3a\x6a\xfc\x27\xa2\x7a\x40\x64\xd2\xe9\xfe\xd5\x74\x3c\x20\xbe\x08\xa6\x7a\x68\x9a\x18\x1d\xc6\xb1\x43\x9c\x09\xc1\x6e\x3b\x3b\x32\xa3\x32\x09\xa7\xf2\xa1\xd1\x72\xd3\xa3\x23\x19\x70\xa8\x5c\x97\xa6\xbc\x98\x36\x39\x53\xfa\xce\x67\x0d\x5a\x86\xad\xf1\xdb\xa6\xa1\xf7\x09\x2b\x6c\xf2\x20\xa2\xaa\x1a\x27\xda\x00\xd0\x5e\x40\x9c\x42\x3d\x4f\x24\x75\xfa\x07\x4c\xba\x5c\x95\x7f\x01\x1a\x59\x8b\xa7\xb2\x1c\x24\x25\x15\xba\x51\x24\x15\xad\x5c\xd6\x57\xcd\xac\x6d\xe3\x04\x15\xf9\x40\x04\x2a\xa1\xf3\x8b\xa9\x52\xed\x02\x8a\x66\x12\x3f\xdd\xa7\xb1\xaa\xd3\xf2\xf4\xdc\xe5\x7b\x77\x57\x5d\x4c\xce\xab\x8b\x49\x79\xea\xdb\x79\x46\xd0\xd2\x13\x34\xb7\x02\x2e\x93\x70\x5a\x3e\x94\x4e\xc0\x65\x20\xcf\xcb\x8b\x84\x9f\x97\x17\x5e\xca\x00\x5a\x33\x77\xdb\xa9\x82\xc9\x2f\x9d\x8a\x56\x26\x99\xc9\xf9\x85\x2b\xe6\x59\xd3\xba\xf4\x4b\x29\x15\xa1\x4c\xe4\x39\xbf\x98\xde\xa3\x88\x4b\x2d\x89\x83\x08\x42\x58\xa8\xd4\x99\x6d\x35\x1c\xba\x1c\x61\xe8\x93\xae\xa4\xa5\x57\x52\x19\x50\x91\x84\x53\xf1\x50\x4e\x8f\x8e\x44\x50\x9e\x0b\x28\x9b\xb8\x70\xf6\x72\x7d\xba\xdf\x38\x63\x94\xec\x31\xa3\x08\xfd\xc4\xf1\xce\x23\x36\x2b\xf8\xe4\x41\x48\xa1\x95\xec\x1a\xce\xc5\x96\xd6\x3e\x81\xab\x61\xa7\xdc\xac\x66\x5c\x78\x83\x2b\xbf\xbb\xe3\x0f\xc3\xbb\x3b\xfe\x20\x49\xf8\x3d\x03\xed\x3e\x2e\xbc\xa1\x76\x5d\xd5\xb9\xcc\xaf\xf8\x81\x4a\x1c\x34\x79\xc2\xb7\xdb\x60\xb2\xd7\x0c\x4c\x8a\x86\x6d\xdb\x1a\x1b\x92\x2f\x66\x38\xaf\xbf\x63\xdf\xc1\x98\xb7\x9f\xe7\x72\xaf\x55\xb0\xcb\xaa\xaf\x5b\x9a\x76\xb6\x52\xae\xdb\x06\xb7\x8b\xfb\xb8\xb5\x72\x5f\x63\xc7\x0f\x9a\xd1\x60\xc8\x4a\x76\xa6\x3e\xc6\x9c\x03\xdb\x27\x21\x1c\x18\x87\x46\xc8\xa1\xd1\xb1\x46\xcb\x0d\xea\xa4\x3e\x3c\x04\x8b\x22\x49\xd8\x09\x86\x54\x76\x18\xf4\xdb\x5a\xb7\xcf\x07\xd8\x5a\x95\x79\xd1\xd6\x63\x8f\xa2\xc3\xc3\x8e\x4c\x1a\xda\x95\xca\x83\xbc\xac\x25\x2b\x53\x10\x2b\xca\x4d\xcb\x52\xa2\x02\x48\x3d\x43\xe1\xab\xf7\xe5\x92\x95\x59\xc1\xb3\x03\xcd\xe8\x01\x72\x76\x72\xd0\xf9\xea\x48\x1e\x91\x80\x04\x53\x15\x37\x3d\x49\xab\x52\xf2\x1b\x99\x48\x9a\x6e\x81\xbf\x4e\x99\xb0\x73\x7e\x11\x38\x36\x95\x19\xb2\xb7\xe7\x4d\xf5\xe0\x27\x92\x7b\x86\xaf\x68\x32\xef\x94\xb4\xc0\xba\x09\xa6\x33\xc1\xd9\x47\x33\xdc\x64\x96\xd0\x1a\x46\xbc\x50\xdd\xc9\x72\x7f\xa8\xd6\x20\xe1\x45\xe9\x4d\x66\x5f\x10\xc5\x03\xba\x36\xbe\x3f\xd4\x54\x9e\x4e\x10\xc7\x11\x4c\x5e\x22\x9c\xbc\xe4\x47\x47\x30\x79\x39\x8e\xfc\x41\x25\xbf\x98\xae\x5c\xae\x55\xa0\x75\xce\x83\xb0\xd9\xb0\x58\x96\x99\xc6\x98\xf8\xeb\x08\xb6\x39\xbe\x52\x53\x5d\x50\xfb\x0f\xa2\x56\xab\xac\xca\xe4\x9e\xb4\x1a\xc1\xd6\x82\xaf\x79\xf9\x07\xf2\x09\x77\xf2\x49\x79\x2b\xd6\x3d\x96\xbe\xfc\x8b\x96\xbe\xdf\x99\x31\xab\x5b\xcb\x56\x10\xec\xe9\xce\xba\x68\xaf\xcb\x94\xdf\x53\xbc\xff\x03\x8c\xb6\xe4\xfb\xfb\x5c\x37\x8d\xc1\x16\xc3\x38\xfc\x18\xad\x72\xdf\x8c\xea\xaf\xb2\x8f\xdd\xba\x6a\xaa\xa8\xc0\x2b\xd3\x54\xf7\xfb\xca\xeb\xf7\x96\x50\x42\x77\xbf\xbb\x73\x33\x2a\x80\x83\x30\x49\x92\xe3\xe3\x9d\x05\x97\xd3\x7d\xeb\x32\x93\x4e\xc6\x0b\x2e\xf9\x01\xa4\x4f\xab\x96\x40\x0e\x0f\x31\x8e\x9a\xd1\x35\x49\x84\x72\x6f\x52\x77\x77\x27\x83\xc0\xea\xd1\xfd\x33\x4f\x1c\xd2\xf3\xe4\x38\xa2\x2c\x31\xe3\xff\x71\x34\x65\x8f\x60\x92\x7b\x7c\x1c\x40\x79\xce\xd9\x85\x2e\x12\xcc\x76\x1b\xa5\xfa\x54\x27\x0d\x24\xcd\x13\xa6\x74\x03\xa8\xc6\xfc\x61\xd8\x10\x0e\xc8\x20\x3f\x2d\x4f\xd4\x5c\x2f\x98\x34\x6b\xd6\x19\x17\x92\x8a\xa4\x3c\x8a\xa8\x9b\x7d\x4f\xc5\xc3\x6a\x5a\x1e\x25\x11\x15\x47\x49\x14\x70\x65\x40\x89\x8b\x29\x3f\x59\x57\xeb\x4e\xb0\xed\x94\x34\x0f\x68\x94\x24\xb6\x14\x87\x87\x1d\x10\x5f\x52\x82\xc5\xfe\x47\x85\x58\x83\xec\xb6\x1e\xef\xfb\x5a\xe8\x59\x51\xec\x1f\xd7\xcd\xe8\x97\x9b\x76\xf2\xf9\x86\x54\xb6\x78\x33\x01\x40\x5c\xed\x51\xe2\xf4\xcb\x17\xf2\x26\xe5\x39\xbf\x38\x3c\xec\xfc\xa1\x96\xa7\x1b\x1e\x44\x55\xa9\x02\x87\xfb\x18\x51\xa5\x84\x91\xbd\xea\x94\xc1\x54\x35\xa3\x70\x9a\x3f\xac\x9d\xa5\x9b\x07\x6d\xd1\x3e\x48\x92\x0e\x4b\x40\xfd\x07\xba\x06\x76\x45\xd9\x61\x4d\xfd\xb1\x27\x44\x3b\xd9\xa6\x00\x3e\x27\x15\xa5\x6e\xf6\xdb\xc5\x1d\x99\x60\xb9\x03\x2f\x5b\x4f\x6b\x49\xd7\x97\x64\xa0\xca\x2b\x5d\x8f\xc9\xa1\xc7\xe4\xc7\xc7\xf7\x45\x86\x22\x4f\xef\x6d\x50\xc5\xde\x76\x64\x96\x21\x8d\xba\xdc\x19\x79\x04\xbb\xde\xdf\x02\x77\x62\xaa\xb1\xd1\x64\xa3\x84\xb1\x6f\xa0\xdb\x67\xb4\xf0\x66\xbc\xd3\x16\xdc\x91\xc1\xe4\xcc\x2c\x99\xcb\x60\x7f\xc1\x54\x8e\x67\x4d\xab\x11\x2a\xe6\x3b\xb6\xe2\xfb\xec\xcc\x9d\xba\x7b\x14\x9e\x7e\xcf\xe7\x05\xcc\x23\xaa\xeb\xf2\x5f\xfc\xb6\x6e\x74\x05\x9c\x21\xe9\x4d\x87\xc1\x7d\x9b\x0e\x10\x41\xb7\xbb\x5f\x7e\xe1\x37\x92\x97\x99\xbf\x63\xa0\x82\x79\x63\x39\x46\x55\x0c\x75\xb8\xd9\x66\xa8\xb9\x7c\x63\xca\xf0\x7a\x7e\x77\xf7\xe9\x97\x5f\xb0\x4c\xbf\xfc\x02\x2c\x78\x26\x27\xda\x42\x87\x87\x4d\x31\xf3\x13\x1b\x3c\x91\x5b\x7f\xc3\xa0\xa1\x03\x0f\xf2\x12\x46\xb1\xd6\xe2\x7e\xa7\x0c\x0e\x0f\x3b\xa8\xfd\x60\x0e\x19\x6c\x03\x64\x71\xbb\xb3\xbf\x80\x8c\xdb\xd9\x9b\x30\x9b\x08\x69\x55\xd6\x52\x6c\x52\x59\x89\x44\x6e\x39\x06\xa3\xfe\xa6\x8a\x32\xc1\x93\xf2\xb4\xb1\x3d\xd3\x29\x83\x49\x47\xf8\xc1\xdc\x37\xee\xc2\x88\x60\xbb\xed\x04\xb4\x6a\x0a\x38\x5f\xad\x2b\x21\x9f\x2a\x1b\xb1\xb9\x35\x62\xd6\x89\x0e\x0f\x41\x1e\xbc\x7e\x55\x65\x9b\x82\x9f\xf2\xc9\x27\x63\x52\xf2\xed\x3d\x4b\xfd\x9d\x92\x12\x17\xc5\x2e\xee\x3f\x08\xb7\xc1\x54\xad\x41\x37\xe6\xe6\x46\x06\x12\xa7\xc6\x66\x41\x5f\xe2\x74\xe1\x93\x8e\x52\x26\xdc\xdb\x36\xe9\xec\x9d\xdb\x53\x91\x9c\x5f\xd0\x2a\x89\xa6\xd5\xc3\xb6\x2e\x9c\x56\x47\x47\x81\x38\xaf\x9a\x26\x6e\x75\x31\x2d\x55\x1b\xd7\x4b\x9a\xe7\xfc\x02\x6a\x20\x65\xb2\x23\x82\x80\x96\x27\xbf\xa4\xb3\x5a\xe9\x68\x99\x28\x28\x80\x30\x7a\x7d\x85\x8a\x60\x1b\x04\x77\x77\xfe\x06\x92\x0a\x95\x48\x6a\x52\x06\xa6\x4a\x33\x50\x89\x8e\xa4\xbc\x51\xa1\x27\x55\x29\x78\xcd\x1b\xbb\x69\x6a\xe0\xb3\xb1\x55\x65\xa5\xb3\xda\x84\x35\xf5\xe7\xa1\x3a\xc1\xb6\x91\xaa\xe0\xb5\x64\xa2\x91\x2a\xf6\x9c\xe9\x97\x25\x36\x75\x2b\x26\xe1\x54\x3e\xf4\x18\x32\x02\x95\x47\x47\x76\x21\xc3\x51\xcf\xe5\x05\x58\x06\xe7\x21\x54\x44\x79\x52\x17\x79\xca\x3b\x51\xe0\x72\x3d\x17\x20\x4c\x9e\x58\x44\x70\x2e\x2e\xec\x0e\x5b\x15\x6c\xb7\x54\x6e\x3b\x55\x87\x77\xc8\xc9\xd7\xaf\x36\x85\xcc\xd7\x05\xbf\x79\x81\x33\x3f\x41\x82\xc0\xcc\xe7\x83\x69\x79\xf2\xa4\x2a\x40\xd9\xe4\xe5\x42\xd3\x93\x7c\x4b\x3f\xed\x8b\x37\x89\x47\xa0\x75\x86\xff\x9f\xd6\xf9\x7f\x83\xd6\xa1\xf9\xbe\xf4\xde\x4a\x26\x9a\x89\xe5\xf3\x4e\x2b\x21\x63\xb7\xf1\xa9\x6a\xdb\x9f\xb6\x38\x1d\xd8\x14\xc5\x83\x84\x07\xfb\xb7\xa0\xef\xdf\x78\xee\xd8\x55\x42\x67\x37\x98\xf6\x99\x70\x2a\xff\xa4\x7a\x64\x09\x36\xff\xac\x5a\x2d\x6d\xb3\xa7\x75\x92\x6b\xe4\x46\xe6\x45\x0d\xa8\x22\xc1\x4e\xf2\x86\x89\x1a\x0d\xac\xcd\xbd\x6a\xd5\xb5\x56\x6f\x57\x22\xed\xc8\x40\xad\xe8\x3c\x50\xda\xb6\x4c\xa4\xde\xd9\x0d\xa8\xaf\x6d\x21\xba\xd2\x71\x9f\xd5\x62\xbc\xcc\x76\xb4\x4d\xf2\x69\x4b\x65\x32\xef\xac\x94\x0e\xcb\xaa\x55\xa0\x96\x40\xd1\xbc\xe3\x7a\x3f\x04\xf7\x30\xac\x32\x39\x49\x97\x79\x91\x09\x5e\x4e\xb9\xda\x5c\x21\x4c\x56\x2b\x42\x67\x1d\x4e\x49\x9e\x11\xf5\x53\x06\x0a\x21\x73\x09\x32\x34\xff\xa5\x12\xa1\x48\x96\x1d\xb2\x14\x7c\x4e\xe8\xbc\x43\x8a\xbc\xfc\x08\xa4\x60\xaa\x76\xda\x00\x4e\x84\x4e\x20\xe3\x75\x2a\xf2\x35\x1a\x54\x94\xd4\x9b\x99\x4d\x89\x76\xaa\x24\xeb\x90\xcd\x3a\x63\x12\xdf\x28\x08\xb0\x93\x9d\x68\x04\x2e\xa6\x3c\x85\x5e\x50\x05\x3a\x2d\xb6\x91\xcb\x4a\x10\x4a\xf8\x8a\xe5\x05\xa1\x25\xd8\x83\x94\x9f\xe4\x92\xaf\xea\x64\xdd\x21\xbc\x94\xe2\x16\x52\x3a\x59\xb1\x75\xa7\xb3\xeb\x8a\xf0\x69\x4b\x71\xa8\x33\x22\x98\x75\x64\xbb\xd0\xf2\xcf\x14\x5a\x9a\x42\xeb\x85\xf5\xec\xff\x66\xef\xdf\xfb\xdb\xb6\xb1\x85\x51\xf8\xab\x48\x7c\xfa\x72\x88\x08\x92\x25\xe7\xd2\x96\x0a\xac\x5f\x9a\x76\x66\x32\xbb\x49\xba\x9b\xb4\xb3\xbb\x65\x4d\x36\x4d\x41\x16\x27\x34\xa8\x21\xa1\x38\x89\xa9\xef\xfe\xfe\xb0\x70\xe7\x45\x76\x32\xe9\xec\x39\xcf\x39\xff\xd8\x22\xee\x58\x58\x00\xd6\x0d\x6b\x45\x41\xb5\xbf\xba\x4a\xe4\x68\xea\x7a\x1d\x05\x20\x34\x63\x1c\x9a\x2b\xa0\x8a\x03\x1a\x52\xe8\xab\xdb\x87\x88\xc6\xfb\x0c\x2a\xec\xf6\x17\x02\x20\x16\x32\x19\x42\x98\x1f\x10\x02\xa5\x14\x4c\xb1\x98\x33\xb2\x89\x82\x74\x9b\x30\x46\xf3\x00\xdb\xe5\x46\xe6\x17\x56\x0b\x2f\x11\x63\x52\xed\x2f\x2a\x5e\x46\x53\x7c\x1f\x60\xb9\x26\x41\xd0\xb3\xf6\x32\x59\xce\xdc\x00\xa0\x6b\x99\xbd\x2f\xb3\xd2\x79\x52\xf1\xef\xf6\x59\xbe\x16\x63\xff\xa4\xf5\xbe\x4a\x58\x72\x99\xb1\xcb\x1f\xd6\x19\x17\x09\xad\x85\x17\x3f\xfc\xc9\x7e\x32\x02\x5c\xee\x8f\xa2\x80\x4c\x6e\xcf\x9d\xdf\x32\x77\x85\x3a\xeb\x28\x50\xab\xe7\x2e\x6b\xd9\xbd\xac\xa5\x5e\x56\xa9\xee\xa3\x74\xad\x44\xd5\x13\x79\x62\x3d\x4d\xf2\xfc\x22\x49\xdf\x46\x7c\x21\xce\x97\x58\xa9\x7a\xd3\x62\x9f\xaf\xd9\x1f\xf8\x60\x93\xb1\xf5\xa0\x2c\x0a\x3e\x28\x36\x03\x38\x06\x10\x82\x7b\x3f\xb1\xd7\xbb\x6b\xee\xe1\x48\xf9\xaa\xc9\x25\xd5\x21\xb4\xaa\xef\x3e\xbc\x4e\x2e\x05\x7b\x12\x69\xa9\x9f\x6f\xd0\x71\xb7\x5a\x78\x86\x96\xd3\x55\xcb\x60\xa3\x6d\x63\xc2\xe0\x90\x1c\xce\x10\x86\xf6\x5e\xd3\xf7\x3c\x3a\xd2\x32\xc3\x33\x84\x26\xbc\xcc\xae\xa2\xa6\xb5\x86\xe5\xa1\x16\x7c\x92\x70\x5e\x66\x40\x66\xc6\x02\x5a\x9d\x16\x17\x0e\x61\x2c\xf6\x66\x21\x46\x61\x36\xa4\xb2\xf3\xc8\x80\x04\xe0\x2b\xd2\x30\xa4\x30\x67\x7f\x59\x55\x20\xdd\xaf\x6b\x73\xf6\x8a\xdf\xe5\x7a\x13\xff\xfc\xfd\x1f\xe1\xf3\xc0\x26\x7f\xa4\x74\xad\xe9\xa9\x3d\xf4\xf1\x9c\xdc\xbc\xbf\xca\x9f\x17\x6b\xb8\xa4\xe6\x6c\xb2\x13\x57\x8e\x28\xd7\x94\xfc\xf9\xc4\xfb\x73\x4d\xbb\x0b\xc4\xd9\x47\xdc\x1a\x68\xd1\xeb\x41\x3e\x91\x17\x57\xc4\x30\x47\x13\xca\xd6\x11\x15\x04\xb7\x18\xd8\x41\x52\x71\xea\x62\x8b\x4f\xbf\xc5\xf6\x2e\x8c\xbf\xc6\xfa\x0e\x8c\x67\x53\x41\xd4\x7d\xd3\x26\xea\x3e\xeb\xda\x2d\xdd\xdb\xcb\xc0\x8f\x0a\xf8\x49\x3a\x43\xa4\x11\xaa\xef\x40\xea\x5d\x7e\x72\x0d\xf7\xbc\x29\x65\xb6\x35\xa3\xc0\x29\x15\x60\xc9\x87\xfb\x8d\xa4\xeb\x84\x27\x2d\xb2\xdd\x6f\xc2\x96\x09\xba\xeb\x37\xae\xe1\x8e\xda\x94\xad\xdb\x75\x41\x5f\xe2\x1e\x47\x7e\x45\x91\x1d\x60\xda\xaa\xb6\x2b\x8b\x94\x56\x55\xc6\x2e\x33\x45\x41\x8a\xcb\xe2\x18\x0c\x3a\x6b\xf4\xc0\xa3\xb8\x12\xdb\xea\xc8\xb0\x54\x89\xae\x91\xa9\xac\xe3\xe0\x30\x65\x3a\x80\x99\x17\x15\xe5\xc9\xe5\xb1\xde\x55\x91\xae\xee\x8b\x1d\x65\x7e\xed\x36\x28\x54\x99\xee\xc9\xab\x4c\xb0\x47\xe9\x1f\x82\x53\xaa\x6b\x14\xa0\x28\x3b\x52\x5d\x2a\xd2\xba\x2a\x1e\x03\x5b\x27\xbc\xe0\x4c\x28\x33\x96\x1d\x5b\x2f\x5b\xa8\xab\xd3\x6e\x3e\xd8\x54\x86\x6c\xe8\xf8\x10\x09\xf6\x4f\x53\xda\xa5\x92\x29\x7d\xfb\xff\x71\x77\xff\x37\x70\x77\x9f\x2b\x53\x52\x32\x83\xd7\xc5\x5b\xca\xb2\x8f\x92\x6b\x4a\x04\x8b\xa4\x4d\x6c\x71\x05\x17\xd1\x2b\xca\xa3\x65\x90\xb1\xdd\x9e\x07\x38\x28\x34\x59\x54\xec\xf8\x65\x59\xec\x77\x82\x09\xa0\xb9\xe0\x91\x70\x70\xb1\xe7\x5c\xd2\x4c\x09\x4f\xf2\xac\x12\x69\xe2\x24\x4c\x4a\x9a\x04\x2b\x84\x53\xa7\xc1\x9d\x48\xc8\xc9\x0d\x2f\x63\x9b\xc8\x05\x71\xc8\xb7\xe2\xcf\x3a\x00\x71\xbd\x9b\xb9\x85\xa4\xb5\x97\x44\x93\xb5\x5f\xe5\xa2\x58\x7f\x70\x4a\xa8\x02\x8a\xce\x93\x94\x1c\xf4\x9c\x39\x85\xf2\x4c\x24\xed\xe2\x14\x6f\x67\xe2\xcf\xa9\xf8\x73\x5f\xfc\x79\x20\xfe\x3c\x14\x7f\x1e\xc5\x29\x96\x13\x8d\x2b\x0c\xd0\x88\x2b\x5c\xec\xb9\xfc\x21\x67\x1e\x57\x58\xcf\x3c\xae\xb0\x9e\xb9\x28\x07\x50\x73\x7a\x54\x60\x5c\x21\xac\xe1\xe8\x67\x6a\xd0\xda\x72\x6b\x77\xde\x6b\x01\xd9\x35\xcc\x77\xcd\xbb\xd3\x93\xf5\xba\xa4\x55\x15\xa7\x38\x29\x79\x96\xe6\x54\xfc\xaa\xb2\xb5\xf8\x7f\x91\x17\xe9\xdb\x7f\x40\x68\x9d\x14\xaf\x29\x4f\x04\x75\x90\xe2\x75\xf6\x4e\xfc\xcd\xe3\x14\x6f\x32\x9a\xaf\x2b\xca\xe1\xe7\x65\x9a\xc8\xf1\xc3\xc7\xbe\x14\xb5\x36\x45\xc1\x69\x09\x3f\xca\x2b\x01\x1f\x9a\xac\xe1\x7b\x2b\xfe\x5c\x25\x99\x28\xcd\x12\xd1\x60\x21\x1a\xdc\x41\x2d\xed\x54\x2f\xc5\x1c\x6c\x61\x52\xbc\x17\x99\xa5\x3b\x87\x52\xcc\xa1\x04\xf4\x28\x77\xdd\xe9\xbc\xb1\xc8\x06\x0d\x44\x3a\x14\x10\xc3\x3b\x52\xe0\x80\xf7\x0e\x2a\x02\x7a\xe2\xe0\x22\xa9\xa8\xfa\xb7\x29\x18\xe0\xb3\x40\xc7\xb4\xc8\xe1\xef\xd5\x55\xc2\xd6\xc0\xab\x5e\x08\x5e\x2e\xd8\x94\x70\x89\x04\x5b\x51\x28\xbb\xba\x14\x7f\xd5\x26\xc9\xaa\x8c\xad\xe9\xfb\x00\x07\x6f\xe9\x87\x4b\xca\x2c\x02\x5e\x51\x2e\xba\xda\x25\x65\x72\x25\xf0\xb1\xd8\x97\x29\xb0\x25\x65\x92\x8a\xfc\xeb\x8b\x12\x50\xd1\x19\xdd\x55\x02\xd8\x5d\xbd\xbb\x14\x39\x1b\x37\x27\x13\x2d\x16\xe2\x8f\xe8\xe2\xaa\x12\x7f\x24\xe5\x11\x24\x8c\x15\x1c\x7c\xe8\x8f\xdf\x5f\x89\x09\x6c\x8a\x92\x66\x97\x4c\x1e\x16\x8a\xad\x31\xfc\x90\xc0\x23\x72\x72\x5e\xd5\xe7\x27\x27\x78\xdb\x27\x17\x01\xf3\x62\x6d\x43\x6c\xe4\x1d\x0d\x79\x6e\x31\x79\xa3\xaf\xe1\x20\xc0\xc5\xe4\x8d\x24\xe2\x5a\x09\x70\x1e\x79\x29\x15\x9c\xab\xe2\xbb\xe2\x49\xfa\x16\x84\xd3\x93\x37\x6a\xdc\x4f\x15\xc9\x05\x89\x40\xcf\x3d\x13\x20\x26\x53\x5c\x08\x62\x58\x7e\xa8\xfa\x70\x6b\x3e\xdd\xee\xd9\x5b\xe2\x8a\x5c\xae\xcb\x8c\x53\x5c\x4c\xd6\x05\xa3\x5e\x06\x65\x6b\xd1\x93\xdc\x6b\x15\x29\xeb\xfa\xe6\x20\x12\x52\x31\x24\xfd\xf1\xbf\x3d\xa9\x37\x79\x71\x4d\xcb\xa7\x49\x45\x15\xcf\x54\x91\xc0\x4d\xaa\x82\x0c\x80\xaf\x66\xb1\x18\x0e\xed\xc7\xc4\x2b\x18\xbb\x39\x8a\x51\xf1\x3a\x78\xa2\xc9\xee\x66\x37\x7e\xc6\x9d\x3a\xf4\xab\xf4\x75\xcd\xf5\x25\x24\xb0\x3b\x72\xca\x98\xdb\xa9\xae\x33\xc3\xeb\x3a\x05\x70\x81\xd4\x4a\x79\x24\x55\x18\x76\x24\x46\xa2\xec\x11\x91\xdc\x1b\x29\xb8\xf8\x09\x0c\xce\x3c\xaa\x1c\xdd\xa8\x1b\x5f\x4a\xee\xd5\xca\x28\x75\xb3\x19\xfb\xe4\x8d\x3a\xde\x5e\x89\x95\x7c\x4c\xa8\x2c\xe0\xae\x6b\xdc\x4c\x39\xda\xc4\x98\x76\x97\xd7\x03\x18\xcd\xb0\xf7\xdd\x6a\xed\x92\xf2\x27\x17\x55\x91\xef\x39\x85\x02\x4d\xa5\x47\x2f\x1b\xe3\x43\x22\x9a\x21\xbf\xa3\xf1\xd8\xd3\xb1\x88\x46\x7c\xad\x88\x48\x89\x68\xab\xb7\x3e\x1a\x3d\xdb\x28\xc5\x67\x0b\xc7\x41\xf7\x41\x27\xbc\xf8\x51\xe7\x44\x48\x6b\xc1\x75\x4b\x14\x4b\x53\xec\x26\x62\xdd\xf1\x61\x51\x8e\x29\x42\x56\x7d\xa3\xde\xea\xe4\x4b\xba\x12\xc5\x23\x6d\x90\x0a\xdb\x77\xe9\xfc\x36\x8a\xf2\x95\x52\xd7\x58\x06\x27\xe2\x08\xcd\xfb\x06\xb5\x87\x66\xa9\x7d\xc1\x24\x5b\x03\x7d\x1a\x45\x78\xa7\xb2\x15\x76\xf9\x27\x85\x2c\x35\x9c\xa2\x78\xa3\x8a\x69\xb8\x77\x96\x9b\x19\x58\xc9\x65\x71\xe0\xef\xaf\x97\x93\x21\xc6\xd0\x91\x15\x86\x6a\xb4\xfa\x58\xbb\x39\xf4\x2d\x6f\x27\x2f\xd4\x83\x51\xba\x39\xd3\x7c\xa3\xd3\x8e\xc4\xc8\x5b\x7d\xbf\x99\x46\xab\x44\x1a\x4d\xf4\xad\x84\xdb\xb8\x5e\x3a\xbd\x3e\x5e\x27\xa8\xbb\x6c\xa3\x50\x03\x2d\x83\xa0\x09\x9f\x4e\x16\xd9\xe0\x7e\x1f\x84\xee\xb8\x27\xa2\x9d\xc1\x2b\x8d\x1b\xbd\xc8\x51\xec\x22\x03\x15\x17\x97\xeb\xfa\x36\xa4\x45\x9d\xf9\x75\x2d\x48\xa5\x21\x21\x34\x0c\x83\x1d\xfc\xd0\xd8\xdd\x87\x5b\x02\x14\x4f\xe1\x8d\x36\x7f\x9d\x5c\x46\xca\xaa\xcb\x33\x01\x57\x23\x4b\x2a\x79\xf6\xbd\xdc\x44\x14\xb4\x21\xe3\xd9\x90\x10\x50\x89\x74\x2d\x0a\x6c\xe5\x46\x13\x72\xa3\xf2\x39\x1f\x8f\xe7\xe8\xc8\x4a\xaa\x9d\x28\xc0\xa3\x2c\x63\xda\xcd\x10\x0e\x39\x66\x9a\x3d\x00\xf9\xc4\xd9\x1f\x9a\xb8\x52\xd1\x7c\x23\x8a\x65\xec\xd2\xc3\x18\xbd\x9f\x5a\x1d\xfa\xc9\x25\x4d\x8b\x4b\x71\x09\xbc\xa2\xf9\xe6\xa9\x6c\x47\x97\xf1\xb1\x61\xd9\x89\x22\xe6\x6c\x5b\xf4\x8c\x38\xf6\xe7\x47\xd9\xba\x79\xb9\x34\xeb\xb4\x95\x5d\xde\x7e\x99\x77\x34\x88\x6f\x3d\x7a\x09\xe0\x5c\x27\x22\xf4\xec\x59\xea\xb5\xaa\x16\xbb\x09\x7d\x87\xbc\x6b\x5f\x8e\x3d\xb4\xcd\xb1\xab\xca\x69\x8f\x76\xf7\x25\xf8\xc6\x8e\xbe\x1c\xb2\x72\xd4\x57\xb5\xf3\xbc\x95\xb3\x36\x02\x54\x1f\x18\x26\x39\x6a\x0e\x0f\xb7\xba\x6d\x1d\xd4\xc3\x3b\x3f\xd7\x35\x95\x5a\x50\x40\xcd\xeb\x64\xd9\x2c\xb1\x22\xb7\x8c\x44\xd3\xde\xad\x62\xad\x83\xf7\xcd\x25\xe5\xcf\xac\xec\xf4\x45\x73\x55\xe5\x99\x43\x27\x15\x4d\xca\x74\x1b\xad\x11\x66\x84\x3f\x9e\x2e\x68\xec\xe8\xd2\x78\xe3\xdd\x41\xd7\xa9\xcc\x08\x6b\x2e\x3f\x6b\x2e\xd9\x9a\xa6\x79\x22\x83\x9b\x75\x5f\x03\x8a\x6a\xed\x92\xfa\xfa\x2f\x64\xda\xb3\x12\xe7\xe3\xad\x8d\x44\xc1\x30\x18\x71\x2c\xfe\xd2\xf6\xb1\x73\x9b\x7c\xfa\x5f\x3a\xd0\x05\x0c\x74\xd1\x39\xd0\x7e\x59\x77\xe3\x1e\x7d\xe0\x93\x33\xaa\x5e\xe3\x70\x90\x89\x4d\xd2\xc7\x8a\xbb\x3b\x8b\x77\x9c\x79\x4a\x63\x70\x77\x8a\xfa\xce\xe7\xf8\xd3\xef\x9f\xbc\x7e\xb2\xf0\x0f\x3a\xa3\xda\x68\x0c\xcf\xa4\x47\xe8\x6e\x74\x3a\x6e\x55\x6f\xcf\x59\xa5\x46\xc8\x1c\xfd\x1a\x6a\xc1\x12\x06\xb7\x0c\x46\x74\x14\xac\x56\x41\x0b\x26\x7d\x52\x75\xd9\x32\xe4\xfa\x9d\x41\x52\x07\xff\xd0\x38\xe9\x8e\x51\x00\xee\x0d\xe3\xde\x19\x73\x7a\x36\x9d\xdf\x46\x02\x2c\xc7\x63\xba\x42\x3e\x8e\xb6\x20\xd2\xb1\xfc\x3d\x02\xf9\xdb\x8c\xc7\x70\x93\x6f\x6b\xa4\x5b\xc9\xc3\x6d\x07\xa0\x92\x36\x38\x53\x69\xda\xc3\xb9\x3c\x72\x77\xba\x7e\x0d\xe5\x4e\x4c\x4a\x54\x8a\xab\x5d\x4e\x79\xc7\x95\xe8\x8d\x57\xaa\x26\xfd\xfa\x20\x7a\xe9\xc0\x00\x3b\x65\x28\xd1\xaa\xe7\x2d\x78\x47\xad\xae\xbe\x76\xc9\xbe\xa2\xed\x45\xb0\x95\xa0\x40\xc7\xd2\xed\xaf\x8e\x56\x93\x25\x22\xad\x78\x77\x9f\x5f\xa3\x39\x53\xda\x59\xb2\x95\xba\x58\x2b\x55\x8f\xef\x4f\xb1\x94\xa8\xc7\xa7\x0f\x0f\x2b\x7c\x7f\x7a\x27\xb5\xcb\xff\x8e\x56\xa0\x20\x65\x44\xc1\xec\x26\xe3\x19\xad\x4e\xf2\xec\xe2\x64\x4d\xd3\x62\x4d\xdf\x88\x3f\x10\x2e\x39\x40\x08\x67\x1d\xe5\xae\x92\x5d\x75\xa2\x53\x26\x7f\xaf\x0a\x26\x35\x0a\x3d\x25\x73\x7a\x99\xa4\x1f\x4c\xb9\xaa\xaf\xdc\xfb\xab\x5c\x17\xb2\x36\x0e\xa9\xa3\xa5\x1f\x68\xbd\xfc\x39\x33\xbf\xb8\xf9\xb5\x31\xbf\xe4\x4b\x3d\xab\xe9\xcf\x9b\x2f\x6b\xbd\xab\xdb\xbc\xfb\x26\x84\x94\xce\xdb\x58\x5c\xa0\x9b\x02\xd2\x28\xec\x30\x4e\x09\x8f\x23\xf3\x9b\x61\x3a\x79\x93\x49\x19\x09\x3a\xd8\xe7\x20\xd2\x05\x84\xa8\x57\xd7\xe2\x1f\x5d\x14\x4e\xf5\xc2\x56\x2f\x9c\xea\x76\xac\x7b\xe7\xa5\x50\xdf\x48\x4d\x5f\xa5\x1e\x23\xab\xeb\x02\xfa\x2a\x9d\xbe\xcc\xef\xfb\xb8\x74\xfb\x12\x6d\xef\x48\x1e\x05\x4f\x03\x7c\x7a\x1f\xcf\x1e\x21\xbc\x11\x9f\xdf\x07\xf8\xf4\x01\x7c\xae\xc5\xe7\x93\x00\x9f\x3e\x84\xcf\xad\xf8\x7c\x1d\xe0\xd3\x47\xf0\x79\xa1\x73\xbf\x86\xcf\x2b\xb2\x8f\x82\x9f\x03\x7c\xff\x01\xc2\xcf\xc5\xef\x67\x01\xbe\xff\x10\xe1\x4b\xf1\xfb\xa7\x00\xdf\x7f\x84\xf0\x07\xf1\xfb\x75\x80\xef\x7f\x8d\xf0\x3b\x51\x5d\x94\xff\x16\xcf\x10\x7e\x22\xbe\x9e\x05\xf8\xc1\x54\x7c\xbd\x11\x5f\x3f\x05\xf8\xc1\x4c\x7c\x5d\xab\x7e\x1f\x9c\x8a\xaf\x8f\xa2\x8d\xdf\x02\xfc\xe0\x01\xc2\x2f\xc5\xef\x1f\x03\xfc\xe0\x21\xc2\xaf\xc5\xef\x1f\x02\xfc\xe0\x11\xc2\xef\x45\x0d\x51\xe6\x1b\x51\xe3\x85\xf8\x12\xa5\xa0\xa7\x1f\xc5\xd7\x0f\x01\x7e\x08\x3d\xfd\x20\xbe\xfe\x4f\x80\x1f\x9e\xe2\x87\xf7\x11\x7e\x25\x3e\xff\x2b\xc0\x0f\x1f\xe2\x87\x0f\x10\x7e\xda\x67\xf1\x60\x55\xd5\x12\xb4\x4a\x2e\xf7\xe6\x62\xbf\xd9\xd0\xd2\x1e\xd2\xae\x70\x4f\x3d\xdc\x50\x4b\x60\xbe\x64\x95\x97\x9b\x8d\xb8\x49\x4c\x62\x52\xd1\x57\x5e\xcb\xd5\x8e\xa6\x59\x92\x9b\xef\x72\xcf\x58\xc6\x2e\xc9\x50\x57\xa1\x6c\x4d\xd7\x64\x38\xb3\x87\x3f\xe1\xea\xb7\x22\x35\xc8\x30\x1a\xd2\xba\x1e\x52\x4d\x7b\xe8\xfb\x46\x6e\xf8\x1f\xd4\x4e\xb4\xc5\xfc\x74\xd4\x65\xd8\xd1\x73\x01\xfe\xdb\x41\xc5\xd7\xa4\xcb\xf1\xbd\x6e\x8a\x42\x83\xc7\x70\x62\x68\xa2\x0b\x46\x74\xd6\x1e\x72\x07\x45\x65\xe8\xde\x57\x54\x01\xc2\x61\x3a\x39\x25\xa7\x5d\x33\x77\x7a\x51\x24\x56\x63\x25\xc2\x70\xa6\x45\xd0\x7a\xa6\x61\x18\x84\x81\xc7\x03\x7f\x91\x51\x76\x40\x16\xbe\x1e\xce\x6e\x1b\x78\x17\x60\xbf\x83\x00\x21\x8a\x4f\xf2\x21\x7c\x22\x21\xec\xf5\x11\x37\xe0\x7e\x37\xb8\xf6\x42\x32\x38\x53\x37\x00\x48\x8d\x5c\xe0\xd5\x75\x6a\xe5\xac\x0a\x45\xe3\x60\xe8\x75\xae\x92\x1f\xde\xd2\xcd\x68\x86\xe2\x60\xd1\x55\xf3\xeb\x3b\xd4\xf4\x6a\x78\x7b\xb4\xae\x83\x4a\xcb\xd5\x5e\xc1\x8f\xc5\xfd\xf8\xfe\x67\xad\xc2\x33\xd6\xb5\x02\x91\x5a\x82\xba\x36\x70\x4a\xa5\xe4\x50\x3f\x45\xba\xca\x38\x10\x33\x4d\xeb\x19\x1f\xa3\xbf\x71\xb7\xad\xb8\x4f\x7a\xf1\x40\x09\xa3\xba\x06\x93\x4a\xa9\xb8\x1a\x49\x63\x61\x5a\xcb\xb7\x08\x8c\x75\xde\xab\x76\x85\xfb\xa7\x3e\x58\x67\x8d\x01\xfa\xb9\x8f\x6e\x83\x68\x0f\x48\x8f\x4c\x26\xba\x0b\x40\x8d\x45\x94\x0f\xcd\xaf\xef\x00\xcd\x27\x1b\x4e\xcb\x23\xfd\xab\xee\x4d\xbf\x3e\x18\x8e\xa0\x63\xff\xd2\x79\xf2\xae\xae\xce\x16\x5d\x42\xfc\x86\x24\xef\x6e\x83\x88\xbb\x8e\x86\x07\x71\xda\xd0\x9b\x70\x4a\xbe\xfd\xbc\xcd\xe0\xc8\x45\x5f\x37\x24\xf2\x9d\x93\xf1\xe5\xb1\x9f\x31\xa1\x8e\xa1\xdf\x65\xd3\x3c\x63\xfd\x50\x8f\x02\xa2\x77\xc0\x2d\xbb\xd8\x15\xfb\x81\x28\xfa\x8e\x27\xe9\xd8\x3f\xff\x67\xd3\xbb\x22\xe6\x11\x54\x21\x1d\xbb\x7b\x16\x37\x67\xb0\xe8\x18\x79\x1b\x93\x9a\x10\xf4\xa1\x7c\xbc\xee\x67\x21\x4e\x63\x23\xfc\x0a\x02\x47\x77\x7a\x7f\x08\xfe\xd0\x71\x0b\xdc\x76\xe1\x03\xc6\xff\xa1\xeb\xfe\xb8\xff\x79\xa8\x35\x7b\x70\x4b\xbd\x4f\x43\x3d\x98\xa7\x0c\x0d\xff\x9f\xfb\x82\xd3\xea\xd8\x9c\xbd\x13\xce\x4a\xb7\x03\x5f\xcc\xd4\xbb\xa4\x7d\xc4\x4f\x93\xd2\xb9\xad\x1b\x4b\xc4\x38\xcd\x7f\x01\x72\xa6\x09\x96\x57\x19\xbb\xec\x04\x4b\x63\x41\xff\x5f\x06\x96\x17\x45\x07\x48\x24\xa6\x36\xb6\xf8\x3f\x09\x98\xe6\x11\xf0\xef\x0d\x26\x79\x80\x7c\xdf\xa3\x05\x70\xdb\x0f\x96\x12\x4a\xa7\xa7\x71\x30\x96\x3f\x67\xdf\xc4\xb3\x47\xdd\xc0\xef\x6b\xb1\x49\x06\x48\x60\x3a\x5a\x88\x5b\x99\x95\xcf\x24\x19\x9e\xb1\x9f\x8c\x54\xff\x59\x8f\x2e\xa1\x7b\x70\xdd\xda\x80\xdf\x69\x98\x8a\x28\xed\xd0\x26\x68\xa0\xfb\xe7\xea\x6d\xb7\x86\x38\x8f\xbd\x0a\x3d\xeb\x75\xa4\xc7\x06\xc9\x76\x3a\x3d\x42\xff\xc9\x56\x66\xfd\x48\xa4\x26\x71\x3a\x8b\x67\xdf\xde\xd6\xcc\xe9\xed\x64\x90\x96\xf9\xab\x4d\x02\x6c\xb9\x52\x92\x81\x67\xc9\x16\x6c\xbc\xdd\x79\xfa\xe9\x6b\x26\x70\x7f\xd8\x41\xc7\x7e\x7b\x6c\x35\xc5\x4e\x7e\xe4\x4f\x66\xd9\xb1\x98\xa7\xdf\x7c\x2a\x73\x36\x7b\x74\xa7\x7b\xf3\x69\x4b\x09\x14\xac\x3a\x97\xb6\x7b\x16\x72\x4d\x44\x1b\x47\x16\x56\x36\xb8\xb8\x3f\x8d\x4f\xbf\x39\xde\xc8\x5d\x96\x55\x94\xfb\x57\x2e\xea\xaa\x6b\x51\x4f\xbf\x39\xb2\xa8\xaf\x94\x6c\xc7\x9b\x4b\xaa\x89\xc6\xa7\x1d\x1c\xe0\xfd\x38\x30\x72\xe0\xd7\x1d\xdc\xc4\x7d\x7f\x6d\xef\xdf\x99\x85\x55\x43\xf9\xa1\xa1\x9c\x38\x6d\x0b\x18\x82\x54\x73\xef\x4f\x15\xf7\xde\x51\x86\xeb\x32\xaf\x65\x19\x9f\xef\xf5\x86\xfc\xb5\xf7\x79\xbf\x73\xe1\xd5\x18\xc1\xd2\xfd\xe1\xa7\x31\xfb\x5a\x7e\x76\xea\xaf\x68\x03\x32\xbd\xd8\xd6\xd5\xa7\xd7\xd3\xa2\xd1\x8f\xcf\x5d\xdc\xc6\x84\x8f\x9b\x9b\xcf\x3f\x68\x8f\xc0\x82\x7f\xc8\xe9\x83\xcf\x03\xc5\xfd\xcf\x04\x45\xbb\xcb\x2f\x09\x89\x87\x9f\x02\x09\x50\xde\x09\x3e\x6c\x0d\xe4\xd0\x87\x57\xbc\xcc\x52\xde\xa9\x48\x75\x3b\x1c\xcd\x1e\xbb\xc4\x8c\x67\xb3\x73\x87\x33\x62\xe4\x49\x5c\x10\xe6\xbe\x64\x6b\x51\x69\x73\xde\xd8\x18\xf6\xce\xef\x66\x59\x82\xa9\x2f\x4d\xf9\x29\x29\x79\x96\xe4\x11\x37\x1e\x9e\x8e\x53\x01\x5d\xe0\xf9\x11\xb4\x51\x12\x3e\x7d\x86\x4a\xcd\xd9\x79\x2b\x42\xc1\x03\x08\x3f\x7b\x04\x2f\x39\x1f\xa1\x39\x3f\x23\xa7\x73\xcf\xe3\x87\x0f\x35\xe9\x7e\x29\xdb\x44\x77\x9a\xb4\x79\xe8\x8b\x99\xe7\x6d\xcb\x87\x80\x29\xb5\x64\x2b\x84\xdf\x15\xd9\xba\x6b\x61\x08\x1f\xcd\xd0\x9c\x8f\xc7\x4d\x48\xa8\xdb\xcb\x41\x15\x1f\x81\xe7\xde\xcd\xd1\x8d\x56\x51\xd7\x0a\xf8\xa8\x14\x86\x43\x0f\x15\xb4\x68\xba\xb5\x10\x0d\x4a\xbf\x41\x98\xa3\x38\xa2\x8f\x83\x24\xa8\x6b\x7a\x16\x7c\x0c\xe0\xc9\xd7\xe3\xe0\x89\xfc\xfe\x6f\xfd\x3d\x95\xdf\xdf\x06\x16\x67\x1a\xa6\x16\xfe\x40\x8d\x84\x1d\x86\x5a\xd7\x91\x95\x3b\x9a\x9e\x17\x01\x51\x47\xf6\x71\x48\xc4\xbd\xf3\x3a\x3a\xb1\xe3\xf7\x90\x64\x6c\x5e\xec\xaf\x68\x99\xa5\xad\x55\xb2\x5a\xc2\x8e\xc9\x81\x9b\x52\x36\xf4\x66\xe8\x2a\x9f\x3b\xf6\x35\xf3\x37\x71\x46\x60\x32\xcf\x18\x8f\x4a\x81\xbe\x6d\x14\x2c\x34\x0a\x4a\x5f\x06\x47\x37\xe3\xc1\x35\xb1\x74\xed\xde\xc7\xf3\x23\xe0\xe9\x41\xda\x1e\x80\xb4\xd0\xb6\x03\x7e\xd1\x29\x9e\x4d\x3b\xf1\x76\x24\x91\xac\x1f\x89\x16\x47\x06\x1a\xdf\xad\xc3\xe3\xa4\xe4\x9f\xe9\xfb\xcf\x9b\x93\x54\xe1\xf6\xcf\x49\x6d\x9c\x4d\x63\xe3\xfc\xf1\xf6\x8d\xf3\x99\x73\x76\x07\xd4\x33\xe7\x34\xa7\x09\xdb\xef\x3a\x14\x88\xee\xc3\x8a\xe9\xc2\xa3\x54\xad\x22\xd1\xd5\x12\x8e\xfa\x84\x5d\x64\xaa\xf7\xa5\xd2\x0e\x86\x61\xe4\xe8\xd5\x60\x7f\x77\x9c\x9a\xfe\xae\xe9\xd5\xa6\xf9\x47\x7c\xbb\x19\xab\x62\xfb\xe7\xc6\xee\x6d\x29\x6f\x68\xff\x34\x70\xfc\xfa\x77\x9c\x96\xb7\xae\x1d\x67\xcf\x91\x41\x74\xb5\xe3\xab\x84\x1b\x68\xd2\x67\x4c\x04\xca\xdd\x2e\x43\x32\xe5\x4e\x43\xd9\x18\xa1\x41\x22\x28\xb4\xc1\xba\x60\x74\x18\x34\x16\x64\xa4\x1d\x73\xc8\x53\x3b\x6a\x62\x28\xa4\x7a\x66\x00\x45\x19\xcd\x9d\xc9\x3f\xf6\x00\xa6\xfd\x76\x7a\x08\x37\xef\xa4\xa5\xd2\x6d\x52\x3e\xe1\xae\x16\x17\xcd\x9b\x78\xe9\xfc\x7e\x2d\x2d\xf7\xe2\xd9\x69\x7f\x99\x63\x02\x5c\x51\xf7\xdb\x3b\x55\x55\x06\x9b\xf1\xec\x68\xf1\xa7\xc6\x84\x32\xfe\xa6\xbf\x5c\x87\x1e\x49\xd4\xb8\x7f\xac\x65\xe3\x22\x04\xc5\x8f\x8e\x8e\xc0\xd3\x85\x89\xe2\x47\x40\xe3\xe9\xa4\x61\x76\xd3\xfe\xc2\x6d\x8d\x06\xd4\x38\x3a\xea\x7e\x19\x31\xd4\x3d\xb2\xb2\x5d\x2a\x06\x51\xe7\xe1\x6d\x55\xda\x00\xf8\xfa\x96\x39\xb5\x6b\xdc\xbf\x75\x60\x8a\xf9\x05\xf8\xde\x06\x33\x2d\x9e\x82\x29\x3f\xb8\x3b\xb8\xb4\xec\x58\xd4\x3b\x5a\xcd\xd7\xe2\x41\x37\x47\x71\xc4\x91\x92\x42\xe1\x5b\x61\xda\xa8\x70\x7a\x04\x3c\x9e\x24\x0d\x5a\xbf\x75\x23\x38\x9b\xe6\xfe\xad\xc8\x6a\xa5\x0e\x50\xbe\xd9\xb8\x76\x8c\x8a\xe2\xfb\xcd\x8d\xfa\xc4\x64\x3d\x68\xae\xd8\x1b\x5b\xab\x89\xce\x57\x36\xab\xb9\x06\xcf\x6d\x56\x13\x82\x97\x36\xab\xb9\x12\x1f\x6c\xd6\x11\xc4\xf4\xc4\x17\x80\x00\x4d\x98\x5f\xdb\xe9\x1c\x01\x9a\x2b\x91\x80\x66\x9a\xf3\xfb\x68\x9a\x39\x3d\xb2\x50\x4a\x98\x07\x2d\x34\xc1\xf0\xd2\x0e\xa4\x09\x86\xd7\x36\xeb\x08\x42\xba\xe2\x09\xe8\xa1\x09\x97\xf7\xb6\x99\xe6\x18\x5f\xd8\xac\xe6\x7a\xff\x68\xb2\x1e\xde\xb6\x43\x6d\xdf\xb3\x23\x6b\xd2\x23\xcb\x87\x53\xe9\xe8\x29\xe8\x30\x45\xb0\x7d\x9a\xeb\xb5\xb3\x23\x6d\xae\xf2\x0f\x76\x79\x9a\x5d\x6c\x6c\x56\x73\x49\xd6\x36\xeb\xc8\x75\xe5\x08\x58\x61\x2f\xdd\x7a\x8e\x81\x18\x15\x66\xd0\x5c\xe8\xad\xed\xb0\xb9\xd0\x17\x36\xeb\x56\x7c\x97\x22\x6b\x00\xe8\x91\x33\xc9\x61\x07\xa0\xe8\xd1\xb3\xd1\xa7\xbe\x45\xf1\x26\xf4\x5f\x99\x01\xf6\xd2\x4c\x7b\xf6\x96\x15\xd7\x6c\x20\x6b\xf8\x66\x2a\x1e\xd1\x37\x1a\x1d\x54\x23\x92\x86\x6f\x52\x4e\x3d\x56\xd9\xc6\x42\xaf\x21\xb4\xea\x33\xc7\x6e\x59\xf4\xdd\x4a\x74\x29\x3a\x0e\x77\xd0\x88\x9b\x8c\x65\xd5\xb6\x39\xd2\x6e\x9b\xf3\x5b\x89\x4b\xd0\x4c\x36\x49\x4b\x2d\x22\xd0\xd6\xed\xbe\x19\xe2\xd4\x37\x53\x3c\x3e\x2c\x95\x7c\x0b\x6f\xe4\x00\x45\x37\x27\x1d\x81\xbd\x2e\x93\x2c\xcf\xd8\xe5\xf7\xe2\x30\xf3\x35\xab\xea\x21\x83\xd7\x59\xbb\x52\x9f\x54\xec\x56\xd6\x60\xde\x3c\x5e\xeb\xba\xb9\x37\xeb\xba\x67\x0b\xba\xda\x89\x0e\x12\xb4\xae\x9b\x24\x48\x5d\xf7\x5c\xd1\xcd\x87\x3e\xf1\x43\x47\x14\x2f\x6b\xca\x0f\xcd\xe4\x3e\x7c\x70\x4b\xfe\xc3\xe3\xf9\x8d\xe6\xc3\xf0\x9b\x66\xc2\x6c\xd6\x4a\x99\x36\x53\xbe\x6d\x15\x69\xb5\x3b\x3b\x6d\xa5\x3c\x68\xa6\x3c\x6a\x26\xb8\x40\x51\x8f\x80\xe2\xcf\x10\x26\xf8\xf8\xd6\x61\xc7\xd8\x14\x6a\x75\x21\x23\x3a\xda\x75\x9f\x6c\xe6\x0b\x77\x7d\x44\xf8\xf8\xe5\x3b\xf5\x37\x5b\xd3\x4b\x43\xaf\xeb\x78\x8f\x7b\x76\x46\xd2\xd8\xbb\x56\x47\x7e\x4b\x4b\x77\xd6\xf1\x35\x4f\x07\x63\x3c\xd1\xfd\xa8\x6b\x49\x57\x77\x37\x30\xeb\x68\x5a\xc9\x12\xbd\xc6\xbb\xc4\xb0\x2e\x12\x5b\x13\x8e\xa8\x71\x9f\x19\x5f\x14\x0d\x37\x68\x4f\x0f\xf8\xe6\x96\x97\x2e\xf1\xec\x1b\x7c\xeb\x23\x97\xf8\xf4\xb4\xab\x90\xfb\xbe\x25\x3e\xbd\xdf\x55\xc4\x3c\x6d\x89\x4f\x1f\x1c\x56\xf8\xfe\xac\xfd\x32\xc8\x71\x4e\xe6\xba\x6e\x97\x0e\x97\x59\xd3\xef\x19\x47\x75\x1d\xb1\x25\x5f\x11\xba\xe4\x2b\x74\x90\x4f\x7a\xf8\xff\xc5\xbe\x9f\x33\xdf\xa7\xb3\x7d\x87\x95\xa9\x1f\xca\x43\x74\xc3\x3f\xf4\x9c\x4d\xbe\x2f\xae\xb4\xd7\xce\xc4\xf9\xc0\x6c\xa2\x1e\x5d\xf5\xe4\xc2\x41\xf1\xfd\xcb\xe7\x9d\x42\x77\x46\xaf\x07\x6e\xf9\x48\x47\x06\xf4\x5c\x79\x66\xdd\xae\x3c\xd7\xc5\xd5\x01\x33\xe5\x4c\xee\xfb\xe2\xea\x15\x2f\x69\x72\x45\xba\x1f\x8b\xb5\x7a\x92\xb9\x9d\xdd\x94\x98\xa3\x83\x8c\x3e\x4c\x9a\x3e\xdf\xe6\xcc\xfa\xd8\x21\x46\x27\xa7\xa2\x89\x69\xbf\xda\x54\xfa\x6b\x15\x3b\x34\x40\xa2\x8a\x72\xe0\xfa\xfa\xc3\x8e\x92\x14\xb3\xc9\x0f\xbf\xfe\xf0\xe2\xf5\x2b\x72\x63\x1e\x96\xc7\xa7\xd8\x3e\x43\x8d\xa7\x58\x3f\x1f\x8d\xa7\xe0\x16\x2d\x9e\xe1\x4e\x2b\x1f\x51\x4d\x5e\xd1\xf1\x0c\xdb\x67\xb6\xa2\x01\x65\x29\x1d\xcf\xb0\xb2\x2b\x8e\x4f\xb1\x63\x8f\x1e\xcf\x30\xd0\x63\xe2\xbf\xa8\x70\xc0\xa5\xf4\x6f\xe7\xb8\x67\x15\x14\x99\x4a\xfd\x6b\x99\x81\x07\x32\x09\x63\x27\xa3\xe5\x23\x5f\x4c\x58\x46\x3f\x2b\x1a\x0e\xc5\x25\x12\xfd\x22\xbe\x48\x3e\x97\xd1\x9c\xdb\x5d\xce\xd9\xe4\xe7\xaa\x32\x0e\x62\x5d\x77\xb1\xf2\xa9\x60\xbb\xc7\xf8\xf4\x11\x6e\x34\x13\x9f\x7e\x8d\x7d\x17\xaf\xad\x47\x86\xed\x59\xc5\xa7\xd8\x5f\xbc\xf8\xd1\x31\xcf\xb0\xf7\x4f\xdb\xe7\x0f\x9b\x94\x34\x59\x37\x70\x50\x39\xd8\xd5\x41\x80\xc9\x37\xf7\x8a\x71\x39\x9e\xe1\x94\x44\xb3\xc7\x8f\x2b\x34\x9e\xe1\x9c\xa4\x67\x67\x33\xbc\x27\xe3\xaf\xf1\x8e\xb0\x45\x31\x9e\xc5\x53\xbc\x21\x6c\x31\x9e\xc5\x33\xbc\x16\x07\xd4\x68\x27\xa3\x98\xef\x46\x64\x83\x33\xb2\x0e\x45\xed\xf1\x5e\x54\x5f\x9f\x9d\x91\xf1\x1e\xef\x47\xa4\x9a\xef\xcf\xa6\xf3\x8c\x9c\x3e\x7c\x74\x2f\x1b\xc9\x5a\x18\x6a\xec\xc7\xe4\x1b\x19\x77\x21\x21\x99\x53\x37\x33\x75\x4b\xa8\x9b\x40\xdd\xa4\xa3\xae\x8a\x03\x94\xa1\x8c\xcc\xc6\xb9\x74\x40\x92\x6d\xa2\x8c\x10\x92\xea\xd3\x2f\x59\xbc\x48\x5e\xc4\xb3\x93\xe9\xbd\x68\x0d\x63\x47\xf3\x64\x44\x9e\x27\x7c\x3b\xd9\x15\xd7\xd1\x29\xc4\xb4\x1e\x93\x5c\xbd\x86\xd2\x85\xee\x25\xf7\x9c\x32\xd9\xb8\x44\x62\x6b\x37\x25\xd7\x6e\x7c\x68\x15\x7b\x08\xa7\x38\x27\xdf\xdc\xcb\xc6\xc5\x58\x80\x4f\x4c\x2b\x17\xb3\xda\x91\xbd\x00\xe8\x86\x00\x37\x5c\x2c\x9c\xd6\xc7\xa7\x0f\xd0\xd8\xfd\xfe\xfa\x6b\x14\x4f\xf1\x9a\x94\x8b\x69\x9c\x8d\x67\x78\x4b\xca\xc5\x2c\x1e\xcf\xf0\x05\xe1\x8f\xa7\x75\xad\x3c\x0e\xcf\x4e\xf8\xe3\xe9\x62\x16\x4f\xa5\xea\x5a\x4e\x2a\xb9\xa8\x22\x8e\xb0\x0c\xd5\x28\xee\x13\x4e\x08\x99\x9d\x4c\x17\x51\x45\x74\xa2\xa8\x83\x13\xb2\x87\x00\xca\x50\x6b\x93\x17\x45\x19\xc1\xcf\xbc\xb8\x8c\x38\x3a\x81\xdf\x3f\xbe\x38\x45\x98\xdf\x8b\x52\x17\x60\xe3\x04\xa1\xc7\xb3\x30\x8c\x92\xf1\x18\xa7\xf7\xc8\x29\xc2\x11\x1f\x91\x64\xb4\x3b\x23\xb3\xc5\xe6\x24\x8d\x37\x2e\xec\x66\xe3\x1d\x42\xf7\xd2\x33\x72\x2a\xaa\x8c\x46\x38\x3d\x11\x55\xa0\xf8\x5e\x8c\x4a\x0d\x45\xd5\x8f\x2a\x12\xf1\x7b\xe9\x78\x86\xdc\x46\x0a\x51\x81\xec\x50\x1c\x55\x84\xbb\x19\xbb\x8e\x82\x64\x8a\xd0\xbc\x38\x23\xdf\xcc\xe9\x92\x8d\xd6\x2b\x72\xfa\xf0\x61\x58\xe1\xf5\x88\x6c\x71\x75\x22\xb0\x09\x17\x0e\xee\x25\x8f\x1f\x17\x75\x85\xf3\x11\x29\xe6\xf9\xd9\xd4\xad\x94\xc8\x4a\x89\xac\x94\x43\x25\xc8\x1e\x6f\x57\x35\x99\x9d\x7e\x73\xef\x42\x05\xf8\xb9\x7f\xbf\xb1\xf7\x4a\x74\xd3\xf2\x76\xce\x48\xb0\x94\xf1\x08\x06\x4f\x74\x4c\x96\x55\x80\x0b\x9b\xac\x83\xf8\xaf\x02\x9c\xd9\xd4\x3f\x51\x46\xcb\x84\x17\xa5\x93\x9d\xd8\xec\xe7\xc9\x6e\x15\xe0\xca\x26\xbc\xa2\x7c\x15\xe0\x9c\x9c\x9c\x5f\xdf\xfb\xea\x04\xef\xc9\xc9\xdf\xce\x75\xde\x64\xb4\x78\x6a\xdd\xa3\x9e\xaf\xbe\x3a\xc1\x3b\x72\xf2\xb7\x68\x11\x4f\xeb\xe5\x6c\xfc\xed\xea\x7c\x7d\x0f\x7d\x75\x82\x37\x82\x5e\xd8\x88\x3b\x7f\xb3\x74\x46\x5d\x26\x1f\x56\x41\x3b\xed\x3b\xa0\x47\x1b\x39\x82\x5a\xfe\x35\xa3\xd7\x8d\xe4\xef\x8a\x22\xa7\x09\x6b\x17\xa6\x8d\xa4\x3f\xe6\x45\xc2\xef\x9f\x76\x75\x0a\x59\x8f\x1e\x74\x65\x3d\x63\xfc\x9b\x9e\xf4\xd9\xa3\x9e\x0c\xaf\x93\xc4\xcb\x7d\x01\x51\x4b\x1b\x55\x24\xa9\xd3\x48\xfc\x99\x5e\xfe\xf0\x7e\x27\x13\x2b\x2f\x47\x86\xed\x6e\x14\x7f\xf5\xe1\xea\xa2\xc8\x1b\x89\xbf\x64\x3d\xa3\x87\x8c\xa7\x79\x72\xb5\xa3\xeb\xbe\xfc\xee\xe9\x89\x1c\x67\x7e\xc3\x29\x76\x32\x41\xf8\x21\x2b\x14\x5e\xad\xbf\xd2\xe4\x2d\xe0\xd5\x8a\xa8\xe8\xa1\x6b\x62\x63\x69\xa4\xe0\xb8\x0c\xe8\x4d\x09\x0a\x42\x94\xdb\xe0\x30\xa4\x78\xeb\x94\xec\x0e\x05\x5e\xd1\x7c\xd3\x88\x03\x2e\x92\x10\x0a\x43\xf1\x5f\xfe\x6d\x37\x2d\x52\xf1\x05\x59\xd7\xf5\xb6\xae\xf5\x5e\x88\x02\x87\x33\x0a\x50\x84\xf0\x95\x37\xd2\x12\x85\x61\x19\x86\xc3\x72\xc2\x8a\x35\x15\x14\x4f\x18\x96\xf8\x39\xb9\x0a\x43\xb7\x18\x47\x61\xc8\xc3\x70\xc8\x9d\x62\x1c\x5f\x92\xe7\x61\xf8\x7c\x42\xdf\x0b\xa2\xbb\x22\x84\x5c\xd9\x37\xec\x1f\x3c\xc7\xf6\x10\x56\x37\xe2\xcb\xe9\x0a\x73\x08\xf5\x4a\x1b\x31\xa0\x9d\x92\xc9\x7a\x2d\xce\x68\xea\x85\x4f\xd6\xe1\xff\x25\xcd\x2f\xee\x41\x42\x17\x3a\xd8\xa0\x3a\xe3\xcb\x30\xcc\xc0\x4f\x0d\x5d\x8e\x46\xc5\x0a\xcd\x47\xa3\xe2\x71\x36\x47\x8c\xf0\x88\x61\xba\x2c\x56\xb8\xc0\xd4\x12\x91\x5e\xb4\x64\xed\xd4\x45\x06\xad\x55\x7c\x40\x18\xba\x41\x18\x4d\x74\x35\x5e\x48\x9c\x45\xbc\xfc\x70\xc3\xc9\x70\x18\xd1\x51\x10\xa0\x43\x9a\xf0\x74\x1b\x31\x74\x63\x02\x11\xda\x2e\xae\x6d\x17\xe3\x19\x66\x44\x47\x9d\xae\xb2\x8f\x76\x48\x74\xb2\x29\xca\x1f\x92\x74\xeb\xc6\x82\x10\xd3\x66\xcb\xd1\x88\xaf\xc8\xb2\xc4\x74\x75\x00\xc7\x3b\xa6\xe1\x8f\x1e\xf8\x4c\x35\x1b\xb0\x80\x46\x3c\x62\xc8\x7d\x6f\xff\xf2\xb3\xc7\x62\x46\x42\xe5\x28\x44\x23\xaf\x65\x7d\xc7\x1b\xf4\x7b\xa2\xd1\xcf\x49\x7c\x41\x9a\xa6\x60\xf8\x47\x72\xb1\x0c\xde\xbc\x49\x8b\x92\x8e\xff\x5e\xbd\xa9\xb6\x49\x49\xd7\x6f\xde\x04\x2b\xfc\x43\x5b\x1e\x77\xb2\xfc\xdb\x64\x35\xfa\xea\x64\x42\xdf\xd3\x34\xfa\x31\x0c\x7f\x9c\xbc\xa5\x1f\x2a\xfd\x7f\xf2\xec\x87\x37\x3f\xfd\xfc\xf2\xf5\xcb\xba\x0e\x02\x3b\x89\x45\x20\x4f\x92\xa8\x2a\x53\xf4\x66\x36\x09\x46\x34\x0e\x82\x43\x84\xf0\x2b\xf2\xde\x2c\x24\x7e\x4a\x5e\x34\xb8\x3b\xfc\x96\xbc\xb0\xf9\xff\x20\xf2\xfc\x8a\x82\xbf\x05\xa3\x57\x92\xf3\x7b\x8a\x26\x25\xdd\xe5\x49\x4a\xa3\x93\xe5\xf9\xf9\xdf\xbe\x9a\xdc\x1b\x2d\x22\xb4\x3c\x5f\xdd\x1c\xea\xd5\xc9\x25\x0e\xce\xcf\xbf\x0a\x03\xa7\x94\xdf\x43\x6d\xe0\x8a\x26\xf7\x16\xd1\x82\x9c\x9f\x9f\x47\xa8\x1e\x6c\x8a\x52\xdc\x43\x32\x61\x85\x44\x43\x5f\xcd\x26\xf7\x16\x01\x1a\x05\x5f\x05\x08\xff\x95\x5c\x2e\x2e\x26\xf2\x4e\xd1\xb1\xd9\xbf\x27\x17\x13\x39\x51\xfc\x1d\xb9\x98\xd8\x83\x12\xff\x44\x3e\x6a\x1b\xbc\x4b\xcf\x67\x39\x96\xa9\x08\xff\x17\xf1\xfc\x7c\xe3\xbf\x93\x17\x62\x8d\x60\x8c\xcf\xaa\x1f\x4c\x68\x6f\xfc\x33\x79\x3d\xa9\x76\x79\x96\x52\xfc\x8c\xd8\x36\x9d\x29\xc9\x21\x54\xf8\xcf\xe4\xaf\x8b\xbf\x4e\xb2\xca\x1f\xe4\x1f\xed\x50\xc4\x8a\x99\x01\xfc\x42\xae\x68\x74\x81\x03\x7d\x23\x06\x08\xff\xaa\x92\x9e\x27\xbb\x00\xe1\xdf\xd4\xd7\x4f\x65\x71\x95\x55\x34\x40\xf8\x4f\x2a\xe5\x15\xe5\x01\xc2\xff\xa1\xbe\xd4\xb1\x1c\x20\xfc\x95\x48\x91\xed\xe3\x40\xce\x2b\x40\xf8\x3f\xc9\x13\x1a\xfd\x82\xf0\x5f\xc4\xff\x5f\x11\xfe\x6f\xf1\xff\x37\x84\x29\x15\x3f\xfe\x84\x30\x87\x1f\xff\x81\x30\xa3\xe4\xfb\xc5\xf7\x16\x55\xf5\x14\x4a\x4a\x18\x5d\x30\x3a\x01\x46\xfd\xe5\x46\xa5\xdb\x63\xaf\xa0\x8d\xbd\xd5\x3a\xa5\x40\x52\x91\xe6\x34\x29\x23\x71\x42\xf1\xc7\x6c\x6e\x9c\x74\x98\xd0\xfd\xe2\xb4\x2c\xc5\x69\x59\x8a\xd3\xd2\xd9\xba\xd9\xef\xdc\x7e\xf2\x3b\xb7\x5f\x39\x11\x34\xde\x08\xae\xf9\xcd\x1b\x60\xf6\x61\x5e\xb6\x58\x4a\xad\xdc\xa1\x24\xd7\x54\x3a\x7e\x6c\x7b\x89\xb9\x53\xd2\x70\x48\xfd\xdb\x8c\xa2\x03\x5c\xd1\x1f\xa9\xf9\xf9\x54\x4b\x73\x02\xf1\x9f\x52\xb0\x0b\x1b\xfe\xbd\x95\x5a\xd7\x6f\x55\x1a\x22\x84\x41\xe5\x45\x8f\xf7\x7e\x01\xbf\x52\x9f\xad\x02\x54\xec\x31\x9d\xa3\x12\xfc\xf6\x47\x4e\x50\x9d\x43\xa4\x21\x8c\xd5\xb5\x12\x43\xe0\x42\xad\xea\xc1\x19\x19\x0e\x0b\x13\x82\x2f\x91\x22\xa9\xa1\xb8\x8e\xcd\xa8\x13\x54\xd7\xe2\xee\x0b\x64\x95\x80\x90\xa4\xae\x3f\xd0\x28\xc1\x05\x42\x75\x5d\x4a\x8f\xa9\x89\xd3\xa9\x75\x14\x43\x1b\x9e\x62\xc4\x22\x3e\xb5\xe1\x41\xc3\xf0\x0d\x8d\x4a\x29\xe5\x92\xd8\x3e\x04\xdf\x2b\x4a\x4a\x57\xd7\x32\xca\x0c\x73\x56\x6f\x4f\x9b\xa0\x30\x61\x81\xd9\x78\x3c\x47\xd9\x26\x7a\x43\x21\x82\x01\x10\x04\xc6\xe4\x97\xa9\xe1\x8d\x67\xb6\xad\x9d\x1c\x5e\x89\x53\xbc\xc7\x3b\xbc\x96\xc3\xdc\x8a\x4b\x3a\x0d\xc3\x68\x4b\x76\x8b\x34\xa2\x2a\x0f\xde\x8a\x4a\xd3\x60\x18\xe6\x56\xb7\x0c\xe5\x87\xef\xc5\x7a\xfb\x82\xbf\x0b\x89\x5c\x22\xfb\x02\xc4\x84\xdb\x4e\xe7\x79\x6a\x25\x20\x16\x93\xe5\x0f\x9c\x18\x36\x3c\x0c\x03\x29\x6c\x0e\x6c\x18\xd6\xe5\x74\xe5\x62\x96\xf4\x9a\x2e\xe0\xc8\x26\xd2\x1e\x8d\xca\xff\x58\x7c\xef\xf6\x1c\xbe\x77\x7b\x2e\x6e\xd6\x88\x22\x3c\xe4\xa8\x85\xd4\x56\x1a\x07\xe8\x65\x00\x0b\x5b\xb3\xae\x23\xae\x30\xae\x44\x12\xe5\xca\x39\x32\xb2\x49\x33\xd8\x43\x44\xf1\xd6\x09\xc3\x75\x45\x2e\x41\x7f\xf7\x9c\x5c\x11\x52\xd4\xf5\x15\x21\x10\x0a\xf9\xa5\x0b\x30\x7f\x0c\x10\xb7\xcd\x52\x77\x10\xd9\xd1\x0d\xf0\xe3\x03\x4a\x0f\xd3\xa1\x2e\xd2\x62\xf7\x21\x62\x72\xaa\xca\x56\xbc\xc5\x41\x10\x72\x05\x83\x61\x75\xfd\x3c\x0c\x87\x3b\xe8\xf6\x8d\x33\xa6\xdd\x82\xc6\x52\x72\xbb\xed\x08\xa7\xdb\x49\xbc\x39\xc3\xaa\xeb\x77\x62\x82\x8b\x9b\x43\xfc\x9e\x46\x9c\xfc\x24\x5a\x5e\xfc\x57\xc4\x91\x68\x14\xd6\xfe\x10\x3d\x17\xd9\x47\x16\x43\x63\x98\xc0\xd3\xe7\x52\x0b\x2a\x8e\x05\xdc\x59\x8a\x86\xe1\x96\x46\x1c\xbf\xa0\x40\xe2\xa2\x43\xb4\xc5\x54\x07\x44\x13\x28\xba\x59\x5e\xad\x1a\x93\xdb\xb6\x44\x2a\x8a\x0c\x16\x34\xb0\x3b\x9d\x79\x75\x9d\x09\x02\x94\xa3\x9b\x34\xa9\x68\x37\x0f\x1a\xab\xc6\xd7\x80\xf6\x5e\x39\xc3\x7a\xc6\x5e\xb2\xe4\x3d\x63\x57\xf4\x1a\x8d\x9a\x75\x2d\x37\x1b\x1f\x41\x59\xbe\x10\xdd\x4e\xa4\x7e\x06\xc5\xfa\x97\x2b\xd6\xf5\xf1\x86\x61\x3a\xb9\xf8\xc0\xa9\xd4\x0a\xa9\x8f\x1f\x25\x2a\x1d\x80\x34\xf6\x87\xe1\x33\xc5\x71\x3b\xcf\x70\xc5\x7e\x9e\xc3\x16\xb7\x32\x0c\xe3\xd8\xca\xe9\xe9\xc8\x65\x53\x3b\x72\x7c\x3e\xb5\x5d\xa0\xa7\x3f\x8f\x53\xfd\x7d\x81\x9c\xb7\x00\x3c\x48\xba\x7a\x74\xa2\xa2\x3d\x89\xf8\x82\x45\xd7\x70\x6a\x4d\x51\x0c\x3f\x3e\xe0\x56\x5f\xb2\x4d\xcc\x1a\xcb\xa6\xc5\x08\xfe\x8c\xb5\x60\xc0\x47\xbd\x26\xe6\x69\xc1\x42\x7b\x80\xfa\xf8\xee\x3a\x8e\x64\x68\x0a\x9c\x4b\x6e\x82\x22\x47\x6d\x63\x5c\x32\x8b\xc3\x55\xff\xc6\xe2\xcc\x54\xb0\xa8\xee\x04\x8b\x97\x1a\x16\xf0\xe3\xdd\x9d\x61\xa1\x25\x1f\xba\x93\x82\x50\x5c\x52\x15\x8b\x27\x2a\x55\x68\x8a\x02\x89\x33\xea\x20\x9a\xb8\xc2\x3b\x88\x18\x75\x58\xd7\x75\x24\xe3\x12\x56\x54\x1e\xc5\x97\x64\x2d\x28\x74\x75\xc1\x5d\xea\x83\xe5\x52\x7c\xad\x81\x48\x13\xf7\x00\x1e\x5e\x20\x51\xfa\xa3\xe7\x0a\xae\x83\xa0\xf2\xdc\xf9\x45\x96\x55\x84\x2b\x74\x51\xc6\x47\x09\x21\xed\x75\x19\x17\xf6\xd2\x52\x17\x14\x5d\x16\x23\x15\xcd\xc8\xdc\x0f\x07\x41\x73\x88\x85\x11\x53\x7c\x21\x8e\x56\x20\xb6\xe2\x17\xd4\xe9\xf8\x68\x87\x1e\xe5\x0a\x3d\x85\xe1\x10\x14\xad\x40\x7a\x60\x86\x29\x9a\xa3\xf9\x21\xfa\x58\xd7\xd4\x09\x22\xcd\x70\x81\x6e\x3e\x2a\x41\x42\x41\xd8\x0a\xe1\x9c\x46\x5b\x5c\xe0\x1d\x8d\x98\xa2\x45\x0a\x4c\xf1\x1a\x21\xc1\x05\x6f\x9d\x30\x83\xd4\xa1\x3a\x15\xbd\x01\x77\x32\xc5\x3f\x84\xe1\x0f\x32\x9e\x93\x20\x00\x5e\xcb\x1c\x71\x95\x2d\xfe\x11\xef\xd1\x84\xd3\x8a\x47\x4f\xe0\xba\x55\x17\x8f\x69\x74\x4d\x8f\xa3\xb2\x73\x24\xba\x7b\xfc\xbb\x88\x23\x58\x62\xf9\x41\x21\x48\xa3\x69\x74\x4b\xed\x65\xc2\xea\x3a\x62\x10\x5b\x5b\x43\x50\x49\x58\xb8\x5d\x27\x10\xa4\x48\x29\x3e\xe1\xcb\x62\x85\x2b\x52\x2e\xca\x88\x2d\x93\x15\xa6\xe2\x4f\x02\xf0\xd4\xfc\x50\x2e\x20\x95\x60\x13\x01\xb0\x5a\x88\x42\xb1\x75\xab\xe6\x08\x30\x2e\xa8\xef\xfe\x4f\xf3\x05\xed\x45\xd6\x50\x48\x2d\x0a\x38\x44\x57\x5d\x07\x0c\xce\x11\xf5\x51\xc1\x46\x52\x1f\x17\xf2\x6e\x13\x5f\x8b\xc0\x04\xdf\x82\x77\x4e\xb1\x8a\x7e\x41\x0f\x11\x47\x0b\xb6\x6c\xd1\x71\x7c\xa1\x93\xe2\x60\x9b\x54\xdb\x60\x15\xb3\xc9\x55\xb2\x73\xc2\x2a\x7a\x53\xe8\xbc\xf9\x65\x27\x74\x21\x41\x12\x0b\x9a\x59\x11\x3e\x7a\x9a\x34\x62\x68\xc1\x14\x04\x0f\x85\x6b\x37\x00\xec\x56\xdb\x36\x4a\x33\x50\x5f\x2d\xbe\x02\x89\x15\x1c\x09\xd8\xab\xb9\xa6\x2d\x9f\xa6\xae\xa9\x84\x8e\xb2\x20\x8b\x0d\xbc\x66\x97\x74\xd5\x68\xec\x92\xf2\x0e\xea\xd8\xab\x24\x4e\x96\xaf\xcc\x4d\xb4\xa4\x7a\x43\x07\x6f\xde\xe4\xc5\x3a\xa9\xb6\x6f\x04\x04\xdf\x18\xe1\xe6\x9b\x37\x01\x84\x1a\x53\x60\x31\x91\xd1\x9f\xda\xd7\x90\x0b\xd1\x8c\x06\x8b\x3f\xa0\x6d\x52\xdd\x3a\x20\xd5\xe0\x57\x0b\xc3\x15\x40\x7b\x4e\x07\x8d\x46\x3d\x1f\x7f\x5e\x74\xce\x06\x74\xc8\x57\x61\x68\x63\x5c\x2e\x8e\x4c\x31\x96\xf6\x26\x07\x9c\x7d\xc2\xaa\x2e\x57\x8d\xf2\x1d\x6b\xd9\x31\x61\xcc\xc8\x9e\xc2\xbc\xe6\xfa\x20\x62\x8f\xa7\xc0\x75\x10\x62\x5d\xdf\x2f\x54\xa0\x84\xf8\x67\x0d\x08\x86\x67\x70\x61\x35\x7a\xbd\xc3\xa2\xb7\xba\x1c\xb0\xc7\x53\xbd\xa4\xe2\x54\x5f\xce\x9a\x73\x69\xae\x9c\xaa\xb7\xd7\xbe\x9b\x74\xcb\x14\x9d\x8d\x67\x8d\xba\xed\x05\x72\xdf\x04\xea\x9a\xa5\x18\x13\x73\xc6\x54\x3e\x9e\x2e\x98\x0e\xec\x8f\xf9\x0a\xc5\x6c\x59\x8a\xa1\x11\xbd\x3a\xc9\x27\xac\xce\x8d\x58\x64\x88\xc1\x55\x50\x7c\x95\x40\x28\xaf\xe8\xd7\xba\xce\x28\xc2\xf2\xb4\x50\x99\x87\x46\xbb\xfd\x3b\xf2\x82\x6a\x8b\x55\x55\x08\xec\x7a\x92\x63\x8b\xd1\xae\x29\xaf\xfb\x46\xb5\x1e\x68\x3b\xd5\xe4\x41\xd0\xa8\xd6\xbb\x13\x9c\x8a\x92\x88\x50\x4f\x9b\x0e\xb8\xfa\x04\x10\x4a\xb9\x4f\xa3\xce\x2d\x07\x96\xae\xec\x42\xa8\xba\x03\x84\xfc\xca\x1a\x48\xd5\x1d\x80\xe4\xd7\xd4\x70\xaa\x3e\x19\x21\x41\xad\x30\x70\x22\x43\x66\xd4\x58\xbb\x78\x85\x86\xbf\xd6\xb5\x96\xfd\x3c\x9e\x7d\xfb\xad\xa6\xda\x4a\x17\x77\x01\xdc\xf3\x46\x17\xd2\x6c\x86\x46\xa5\xbd\x66\x1b\xeb\x23\x03\xf8\x52\xf2\x6c\xf1\x31\x7a\xa6\x05\xb0\x71\xcb\x8e\x4e\x1c\x3d\x97\x9d\x8b\x60\xa4\x5f\x07\x47\xd5\x43\x5d\xe4\x18\x0e\x23\xae\x42\x48\xf2\xc5\xb7\xd3\xe9\xd7\xb3\x6f\xbf\x3d\x7d\xf8\xe0\xeb\x07\xd3\x6f\xbf\x9d\xc5\x5c\x1c\x44\xce\x3d\xad\xb8\xf2\xba\xde\x49\x12\x08\x9c\x14\xd0\xb3\xf1\x2c\x0c\xe9\xff\x6f\x46\xc8\x34\x0c\xe9\x63\x87\x6e\x79\xe7\x10\x43\xa0\x61\x73\xf9\x5f\xc7\xa9\x71\x64\x79\x7f\x7b\x8f\x87\xa1\xa3\x7d\xa8\xeb\x17\x8e\xc8\x0a\x48\xaf\x1b\xc7\x02\xec\x86\x97\x1f\xf4\xa4\x5f\x99\x49\x4b\x0d\x0f\x47\x37\x07\x27\x9b\x8e\x82\xc0\xc9\x51\xb0\x0f\x02\x47\xbf\x44\x7d\x29\x00\x01\xa2\x84\xaa\x57\xd6\xe2\x4a\x3a\x44\xbf\x84\x61\x07\x37\x3d\x24\x97\x14\x28\xb8\x5f\xe0\xaf\xc3\xca\x47\x33\x84\x50\x5d\xff\x1a\x86\xaa\xc4\xaf\x68\x48\x92\xba\xfe\xcd\x69\x47\x09\xcc\x55\x33\xbf\x4d\x4a\x5a\x15\xf9\x3b\x1a\x89\x8a\x7f\x32\x15\xff\x84\x86\xa4\xaa\xeb\xff\x70\x2a\x1a\x05\xa7\xe9\xff\x3f\x80\x6e\xbd\xec\xba\x7e\x0c\x4e\x60\x47\x85\x6f\x45\x38\x7c\xe1\xad\x92\x11\xa5\x13\xb6\x78\x02\x51\x45\x15\xcd\x98\x6d\xa2\x12\x29\x11\x46\x29\x45\x18\x83\xff\x54\x5c\x50\x07\x64\x24\x2f\xf6\x17\xcd\x26\x25\xf2\xfb\xbf\x9b\x15\x0c\x08\x64\x3e\xa5\xba\x42\x25\x13\x38\x6d\xd6\x30\x73\xb7\x5a\x3c\x49\x93\x5f\x53\xa5\xe9\xca\x2a\xf8\x6f\x77\xc0\x47\x87\xee\x1f\x18\xdd\x61\x87\x40\xaa\x85\xf8\x6d\x64\x27\xcd\x3d\x63\xe5\xc3\x28\x0c\x87\xc0\x39\x80\xde\xed\x25\x25\x7f\xf6\xe2\xd6\xaa\xfd\x37\x73\xb6\xe6\x6b\x67\xbb\x00\x37\xb2\x30\x8b\x15\x07\x81\xe1\x79\x41\xe8\xc7\x09\xc9\x2c\xca\xbe\xa7\x9d\xf4\x36\xc8\xd2\x23\x2b\x4c\x17\xb4\xb5\xbb\xd3\x9c\x2d\xf5\xc2\x05\x0a\x40\x68\x91\xc2\x2b\xbc\x86\x61\xe6\xf0\x9d\x2b\x65\xfc\x63\xa4\x78\x57\x4e\x96\xab\xb9\x67\x87\xa9\x58\x60\x8a\xd0\x53\xd7\xf6\x32\x70\x90\x2b\x18\x12\x06\xbb\x5c\x9c\x94\x56\xc6\x0e\xcc\xfb\x81\x1b\x4d\x75\xc7\xc1\x06\x72\xe6\xe1\x14\x08\xa0\x03\xb2\x51\x5e\xb0\xa3\x88\x1f\x9a\x75\x63\x0b\x16\x77\x66\x80\xee\x5e\xfc\xe9\xce\xbe\xce\xd8\xba\xb8\x5e\xc8\x7f\x31\x04\x19\x03\xfb\x98\x07\x77\xb2\x8f\xe9\x56\x33\x96\x5a\x37\xc9\x94\x54\x03\xe1\xe2\xce\xd6\x08\xd9\xef\x6a\x8d\x90\x08\xbc\xca\x8e\x59\x23\x54\x2d\xad\xb0\x55\xba\xe6\x24\xd1\x4a\xcd\x3d\xc9\x17\x79\x5b\x1d\xb7\x23\xfb\xc5\xde\x54\x68\x29\xe3\x36\x0a\xc3\xda\x92\x79\xab\x04\xc8\x36\x51\xc7\x3e\x35\xbc\x63\xda\xa3\x79\xea\xd5\x29\xb5\xe4\x38\x84\x54\xe6\xfa\xf0\x24\xd7\x3b\x77\x27\xaa\x1b\x6d\x64\x36\x65\x30\x0d\x94\x19\x1b\x25\x64\x3c\x3b\x99\x2e\x82\xf1\x34\x88\x79\x0f\x16\x43\xfd\xb9\x89\x52\x2d\xef\xdf\x88\x13\x8a\x16\x41\x10\x6f\x22\x10\x3b\x94\xfa\x8e\x5d\x50\xa3\x94\x66\x5a\x4d\x1d\xd3\xff\x05\xbc\x7f\xd8\x13\x2d\x02\x17\x38\xeb\x32\x22\x48\xda\x46\x04\x15\xc9\x7c\x94\x69\xe8\xf1\xf7\x1a\xfe\x5a\xdd\xbc\x23\x89\xad\xb0\x21\x51\x49\xba\xf5\xe3\x85\x4a\xc7\x1d\xa7\x45\x19\x15\x20\x9b\x42\xf3\xee\xe5\x00\x51\xfe\x5d\x91\xa6\xae\x5b\xb7\xe6\x90\x18\xec\xf0\xb1\xef\x77\x31\x52\xb1\x68\xa9\xac\x99\x38\xd1\xd1\xe8\x74\x64\x50\x9d\x3f\x55\x2a\x9e\x5c\x73\x8d\xde\xe9\x8b\xc4\xd9\xdb\xa6\xc8\x3a\x68\x31\x16\x86\x1e\x31\xcc\xc2\x50\x2d\x13\x43\x84\xec\xb5\xdd\xe0\xa3\xbe\x68\x22\xfd\xa7\x46\xd1\xb8\xa4\x8f\x9d\xfa\xed\x83\xa1\xae\x87\x05\xec\xe3\xcf\xda\xf2\x4a\x60\x4d\x48\x69\xb6\xbc\x9a\xc8\xd7\x77\x3b\xe0\x8f\x5a\x22\x16\x5d\x96\x88\x19\xbc\x5c\xe8\x37\x0b\x6c\x66\x39\x66\x81\x59\x8f\x59\x60\xd6\x67\x16\x98\xf5\x99\x05\x66\x7d\x36\x7a\xcd\x8c\xa6\x8d\x5e\xd6\x6b\xa3\x97\x1d\xb3\xd1\xcb\x96\x5d\xa6\xa2\x5e\xa5\xae\x86\x1a\xc6\x98\x59\xa7\xd5\x65\xd6\x6d\xa2\x99\xb5\x8d\x31\xb3\x0e\x4b\x41\x17\xdc\xc6\x1c\xd5\x4b\x56\x76\x83\x59\x97\x11\x65\xd6\x65\x44\x99\x75\x19\x51\x3a\x89\x60\xcf\xea\xa7\x18\x8b\xca\xec\x98\xcd\x62\x72\x67\x2a\xa1\xfa\x5d\xa9\x84\x5c\xb0\x2d\xd5\x31\x2a\x61\x7f\x07\x9b\xc5\x1d\xd9\xdf\xc5\x66\x71\x43\x76\x61\xb8\x73\x6c\x16\xf7\x78\x4d\x36\x61\x98\x4c\xd4\x93\x0d\xec\x3f\x42\x2d\x3f\x28\xfb\x33\xa8\x56\xd2\x7f\xec\xb3\x92\x3a\x3f\xa3\x60\xcf\xb3\x3c\x40\x13\x01\x08\x13\x26\x9c\xd6\xf5\x3a\x0c\xd7\x93\x8b\x8c\xad\xe1\xed\xab\xf9\xa9\xcb\xbb\x0c\x63\x84\xf0\x05\xd9\x86\xe1\x76\x92\x55\x62\x9c\xeb\x06\x7b\x71\xa5\xcf\x3e\xc5\x1d\x31\xcd\x0f\x48\x26\x69\x1a\x5b\xa5\x3a\x1c\xca\x4a\x4f\x35\x6b\xa6\x63\xb6\x9c\xae\x54\xe6\x69\x67\x26\x66\xcb\x99\x2e\x71\xbf\xbf\x04\x66\xcb\xd3\x95\x13\x22\x25\xd9\xed\xf2\x0f\xa2\x80\xe4\x4c\x9e\xe3\x4b\xfc\xa1\x65\x15\xf8\xae\xeb\x42\x7f\xd2\xbe\xd0\xdf\x90\xbc\xc7\x2a\xf0\x9a\xbc\xb3\xe7\xfc\x47\xf2\xa4\x79\xd5\xbf\xbc\xcd\x6a\xf0\x4d\x18\xbe\x51\x56\x83\x6f\x3e\xcf\x6a\xf0\x35\x79\x62\x87\xf0\x9e\x5c\xfb\xa4\xc5\x0b\xd7\x4c\x50\xe5\x7d\xfc\x5f\x32\x13\xfc\x91\x6c\x16\x79\xc3\x4c\xf0\x07\x92\x6b\x8a\xfa\x15\xc9\x5d\x33\xc1\xa7\xe4\xc7\xc5\x8f\x93\x24\xcf\x8b\xf4\x17\x56\x25\x1b\x43\x62\xbf\x25\xd1\xf3\x1e\x02\xe9\xf2\x08\x81\xf4\x3c\xba\x94\x04\x12\xfe\x47\xc3\xbc\xf0\xaf\xe4\x49\xb7\x79\xe1\xf7\xe4\x83\x36\x2f\xfc\x8e\xfc\xb0\xf8\xc1\xc0\xf9\x75\xa2\x49\x7b\xfc\x53\xf7\xde\xcc\xad\xb1\x9f\xff\xc0\xce\x59\xd3\xe8\xe6\x80\x83\x00\xdf\x1c\x10\xa6\x8d\xcd\xf7\x5f\x30\xf9\xa6\xb9\xe2\xdf\xe5\xb3\x8e\xab\xe4\x3d\xfe\x99\x88\x33\x7f\xc2\x8a\x6b\xfc\x4c\x74\x96\x6b\xcb\xc4\x3f\xbb\x5d\x1b\x3b\xc3\x3f\xf6\x44\x52\xb2\x34\x97\xc9\x97\x96\x34\xc3\x27\x34\x32\x66\x50\xd2\x9e\xe5\x1f\x9a\x51\xf8\x87\xd8\xcf\x8e\xb4\x91\x70\xd7\xca\xc6\xda\xd3\xd8\x02\x6a\xfc\x4c\xcc\xcd\x1e\x22\xbf\x34\x0c\xfb\xb4\x42\x6a\x1a\xfb\x36\x44\xff\x94\x79\xdf\xaf\xff\x8a\x4e\x7e\xfb\x57\x74\xf2\xa7\x1e\x5d\x07\x80\xfd\x57\x13\xe2\xb3\xca\x3e\x52\xc2\xe1\x9f\xad\xfb\x1f\xae\x10\x58\x46\x46\x2e\xc9\x90\x85\xe1\x05\xfc\x2e\xe0\xf7\xb0\x04\x01\x1c\x45\x38\x33\xdf\xc3\x22\x0c\x41\x99\x8e\x13\xc2\xea\xba\xac\x6b\xc1\x3f\xe3\x8a\x24\xbf\x8f\x91\x61\x4a\x2a\x17\x62\xf0\x10\xd0\x31\x2f\xfc\xa8\xc5\x2c\x39\xaa\xeb\xc4\x33\x2f\xcc\xeb\xba\x00\x41\x10\xd8\x8c\xc8\x84\x60\x97\x94\x94\xc1\x87\x36\x47\x94\xa6\x27\x2a\xdb\x2a\xaa\x9d\x84\x97\xa6\x01\x54\xd7\x7b\xb1\xb5\x52\x84\xea\xba\x92\x22\x9c\xdc\xcc\xa0\xb2\xe0\xfd\x4a\x5f\x87\x8e\x3d\x62\x18\x0e\xb7\x14\x2c\x11\x31\x43\x75\x6d\xd4\x72\x22\x23\x52\xa6\x8a\x28\x0c\xff\x5b\x55\xb5\x8d\xfd\x67\x87\xf5\xe3\x47\xd7\xfa\x71\x7b\xdc\xfa\xb1\xdd\xe2\x5f\x6e\x35\x7e\xdc\xde\xd5\xf8\x51\x37\x7e\xe3\xa8\xac\x41\x2a\xf0\xd3\xe2\x27\xc8\xba\x49\x0b\xb6\xc9\x2e\xf7\x70\x82\xc6\xc3\x29\xa6\xe6\x3c\x15\x5f\xf2\x39\x31\xc3\xd7\xea\xe5\x24\xbc\x2c\x8e\xa5\xbd\xe6\xe1\x97\xbb\x6b\x6a\xfe\xbc\xf8\xb3\x51\x30\x63\x8b\xf7\xd3\x03\xfe\xe5\xce\xfa\xc9\x5b\x54\xcd\x5e\xfc\x61\xd1\xfa\x98\x70\x78\x89\xc7\xfd\x4e\xee\xa8\x83\xfe\xf3\x17\xd0\x41\x7f\xec\xd3\x41\xff\xf2\x79\x2a\xe8\x3f\x37\x54\xd0\x1f\x5d\x15\xf4\x2f\x9f\xac\x4f\x6a\x02\x6c\xe4\xc2\x79\x31\x8d\x67\x98\x2d\xe9\x8a\xfc\xf9\x93\x95\xd4\xbf\x7e\x8a\x8e\xda\x47\x87\x5f\x3f\x47\x5d\xfd\x97\x4f\xd0\x56\x7f\xef\x69\xab\xc7\x63\xd3\xbb\xd4\x5c\xff\xfa\xc9\x8a\xeb\xbf\xdc\xaa\xb7\xfe\xf5\x76\x1d\xe1\x5f\xba\xb5\xd6\xbf\x7e\x86\xd2\xfa\x2f\x2d\x9d\x75\x34\x1a\xd9\x59\x7a\x0a\xec\xb6\x06\xfb\xb7\x5b\x97\x4e\xae\x14\xee\x53\x66\xff\x62\x74\xd9\xcf\xea\xfa\x57\x4f\x95\xfd\xcb\xc1\x6f\xbf\x77\x7d\xd3\x0e\x3d\xf6\xb1\xed\xfd\xdb\xed\xea\xdb\xb4\xad\xe0\xfe\xed\xf6\x65\x49\xdb\xfa\xed\xdf\xee\xb0\x24\xb6\x1a\x2e\x09\x83\xd1\xce\xbb\xf5\xa9\x6a\xdf\xc9\x32\x04\x5e\x24\xcf\xd4\x4a\xfc\xe9\xd3\xf4\xe0\xbf\xfa\xfb\xe8\x4f\x9f\xb3\x8f\xf8\x11\x70\x2b\x1a\x05\x33\xbf\xed\x4f\xd2\x96\xff\xe9\x73\x95\xe5\x7f\xfa\xa7\x75\xe5\xbf\xf6\xa8\xca\x9f\xdd\x55\x55\x2e\x81\x30\x1a\xc9\xa5\xea\xd7\x9e\xff\xd6\xaf\x3c\x97\x4d\x38\x0d\x48\x6d\x3a\xa5\xb8\xf5\xea\xdd\xde\xfe\xa5\x20\xd0\xb4\x24\x59\x12\x7b\x4c\xd2\x77\x99\xa6\x0a\x12\x41\x15\xdc\x48\xff\x15\xd9\x92\xd2\x45\x12\x8f\x46\xe5\x0a\xe6\x07\xde\x9e\xa2\x62\x59\xad\x70\x85\x0b\x84\x2e\x4a\x9a\xbc\x35\x7c\xb7\xa3\xe8\x63\x4d\x0d\xa4\xb5\x35\x03\x57\xca\x56\x98\xa6\x4f\xfc\x55\x10\x3b\x12\xa8\x3c\x5f\x05\xf1\x77\x61\xf8\x9d\xa7\x68\x5b\xb4\x91\xce\xd0\x46\xdf\x21\xcc\x08\x5d\x7e\xb7\x9a\x0b\x3e\x4c\xfc\x50\x8c\xc7\x5c\xce\x7b\x38\x55\x5c\x56\x86\x6e\x94\xab\x96\xd7\x5a\x2a\x6a\x8e\xb7\x30\x8c\xf8\x02\xea\xb2\x58\x11\x06\xe2\x0b\xe1\xe2\xd0\xd4\x14\xaa\x2a\xaf\x5d\x65\x8a\xa5\x94\x4a\x77\xfe\x6f\xa8\x2f\x97\x75\x64\x84\x84\x30\xff\xa5\x51\xe1\x9b\x6c\x3e\xe9\x7b\x6a\x34\x1c\xbe\x0c\xc3\x97\x40\xf5\x1d\x54\x28\x85\x0f\xa0\xd3\x7c\x11\x33\x65\xbe\xd9\x50\x00\x74\x59\x12\x5c\x7f\xa6\x25\x01\xf0\xd2\x66\xcc\x99\x36\x56\x90\xc3\x6d\xbf\x4b\xd0\x8b\xb5\x5c\xf5\x3a\xb5\xb1\xca\xd4\x6e\x6d\xa9\xd2\x03\xec\xa8\xd4\xeb\x3b\xba\xd8\x52\x92\xbe\x51\x43\xef\x5a\xd6\xb5\x60\x1a\x0c\x7e\x94\x02\x46\xea\xba\x2a\xbb\x1e\xdd\x26\xd4\xf5\xb7\x41\x87\x40\xd8\x72\x1a\x71\xc7\x16\x37\xc3\x09\x4c\xb4\xa8\xeb\xa8\x20\xd2\x58\x01\x3f\xa1\x51\x86\xd0\xb0\xf9\x2a\x02\x17\x18\x8a\xcb\x9d\xb4\xa1\xa0\x1e\xc6\xa9\xf8\x25\xb6\x24\xe8\x86\xc4\x51\x96\x82\x62\x23\x47\x82\x8d\x60\x38\x47\x73\xf3\x0c\x66\x8f\x77\x24\x5b\x64\x51\x85\x53\xcc\x46\x41\x80\x45\xcb\x89\x36\x50\xc0\x1b\x62\x36\xd4\x0e\xf4\x86\xb2\xaf\xb5\x60\xf1\x52\x84\xb7\x64\xb8\x06\x96\x2e\x45\xf8\x02\x7e\x0f\xb7\xc0\xce\xa5\x68\xbe\x23\x29\x96\x0f\xb3\x2f\x16\x57\x34\xaa\xd0\x62\x47\xaa\xf8\x0d\x8d\xf6\xa4\x42\x61\xf8\x9c\x46\x7b\x91\xd4\x75\x30\xfe\x53\xcf\x7c\x2a\x14\x6f\x17\xd1\x86\x0c\x67\xb8\xd9\xfa\xb1\x07\x3c\x86\x57\x2c\xc9\xd3\xc5\xd3\x88\xa1\xb8\xe3\xd5\x40\xf3\x2d\x4f\x89\x70\x79\x88\x52\x41\x88\xa1\xf8\xa2\xa7\x57\xfd\x44\xe1\x6e\x56\xfa\x3d\xa6\xcd\xaf\x5c\xd3\xe6\x57\xca\xb4\xf9\x0b\x3d\x79\x50\xe3\xdf\x91\xe5\xaa\x65\xa8\xf0\x86\xf6\x69\xeb\x18\xed\xd0\xa1\xbd\xbd\x45\x87\xf6\xf1\xcb\xeb\xd0\xae\xad\x0e\xed\xfd\x21\x4a\x51\x5d\x5f\x08\xfc\x5b\x44\x3b\x52\xe1\x0b\x85\x78\xb7\xda\xf8\xdb\x87\xf6\x43\x36\x6f\x5b\x87\x67\x02\x27\x13\xd7\x3a\x3c\x7b\x9c\x98\x2b\x8c\x2f\xb3\x15\x4e\x95\x75\x78\xb5\xc2\x54\x5e\x5e\xae\x75\xb8\xd9\x46\x69\x18\x46\x29\x11\x25\x10\x2e\x16\xff\x1d\x31\x5c\xe1\x14\xc5\xff\xa9\x7e\x58\x63\xf1\x88\x62\xb0\x20\x41\x80\xd2\x4f\xc4\x44\xc2\x70\xf8\x41\xfc\xaf\xeb\xa8\x6b\x4a\xb7\xbf\xfd\xda\xe9\xb7\x5f\x7f\x8c\xde\xca\xa6\x53\x84\x50\x2c\xd0\xf6\xb0\x09\xc3\x28\x01\x14\x4b\xf1\x0e\xe1\x22\xda\xe1\x14\x97\x70\xbe\xe0\x44\x93\x59\x29\x42\x58\x1e\x22\x3b\x04\x2f\x31\x38\x58\xc1\x27\x14\x4e\x34\x7b\xac\x48\x53\x79\x38\x90\x12\x24\xda\xd0\x47\x4b\xd1\x86\x48\x15\x86\x51\x45\x32\xd9\x70\x82\x2b\x74\x38\x20\xfc\xd1\xbd\xb0\x2a\xdf\x96\x6c\x4d\xa3\x26\xed\x61\xac\x7a\xfe\x1e\x39\x9c\x1f\x35\xcc\x54\xcc\xf1\x14\x61\x57\x44\x69\x88\x95\x44\xdf\x94\x58\x3d\x01\xf8\x7b\xa4\xe9\xab\x31\xd4\x4a\xd4\xb9\x93\x19\xef\x0a\xc9\xb2\x58\x91\x72\xc9\x47\xc5\x6a\x2e\x2a\x19\x34\xa9\x54\x51\x88\xc7\x22\x0a\xf3\x39\xaa\x64\xe1\xc2\x9c\x51\x15\xc8\x22\xa2\x04\x61\x50\x72\x08\xb2\xbb\xd2\xc0\x7c\x4f\x11\x96\x3a\x6b\x33\xf9\xf4\xff\xf9\x6f\x05\xf2\x2f\xf0\x56\xa0\xf0\xdf\x0a\x98\xb6\xf7\x5e\xdb\x9e\xd9\xd6\x27\x18\x65\x32\x0b\x10\x30\xa7\x2a\xee\x66\x9a\xb9\xfb\x82\xa6\x99\x4f\x90\xff\xa8\x46\x5d\x58\x4d\x9a\xc3\x37\x3f\x1b\x3a\x2f\x6f\xf9\x4a\x10\x80\xee\xe2\xd9\xcb\x4e\x80\x13\x2e\xee\x2e\xa6\x6a\x8a\x19\x99\xb6\xd0\x49\xb3\x1f\x3f\x47\x08\x17\x64\xf6\x68\x1c\x95\x63\x26\x0f\x77\x52\xe2\xe2\x6c\x0a\xc3\x1b\x8d\xf8\x19\xf9\x66\x3a\x35\xde\xb5\xf4\x6e\x5a\x4e\x57\x2a\x1a\x8c\x6d\x5b\x6b\xcd\x14\x71\x61\xca\x0a\xec\xff\x69\xd1\x89\x17\x3f\x45\x14\x07\x5a\x2b\x12\x1c\x17\xfe\xcd\x94\xf0\x2f\x62\x84\xe3\x96\x91\xe0\x80\x1d\x90\x2f\x15\x94\x77\xd2\x21\x7e\x4f\x1d\x9d\xc1\xf6\x76\xbb\x55\x78\x44\x4d\x49\xe9\x1c\x43\xa6\xbc\x99\xd3\x21\x42\x68\x51\xd2\x2e\x7a\x5e\xd1\xea\x1f\x3b\xde\xdf\x0f\xff\xda\x4a\x3c\xe0\xab\x5e\x23\xcc\xe7\x9d\x46\x98\xef\xa8\x67\x3e\xf9\xc1\x98\x4f\x5e\x52\xf2\x5f\xb7\x99\x4f\x7e\xe8\x24\xb4\xcd\x05\xcf\x1c\x56\xbb\x43\xed\x2f\xd1\xf3\x88\x9b\x2a\xbf\xc0\x93\xea\x03\x4b\xfb\x32\x7f\x2a\x8b\xf7\x1f\x20\xb1\x69\x0b\xfd\xcf\x58\x96\x36\xcc\x9f\x5b\x27\xa6\x05\xe3\xdd\x4c\x3e\xdf\x74\x2e\x41\xc3\x66\x46\x99\xd2\x5e\x1c\x7d\x6b\xc8\x5d\xf7\x35\x62\x4b\x5c\x74\x72\x83\x0a\x7b\x1a\x8b\x3c\xcc\x96\xb0\x34\xab\x43\x8f\x89\x2e\xa0\xca\xe2\x3f\xc0\xe2\x13\xc5\x99\x63\x52\x8b\x5f\x53\x12\xbd\x6c\x7b\xb1\x43\x37\x96\x5d\x01\xf3\x7f\xcf\x43\x8f\x4f\xac\x3b\x2f\x1d\xcb\xb3\xd9\x82\x2f\xcb\xf1\x4c\x0b\x8f\x71\x46\xca\xb3\xd3\x05\x5f\x9e\xae\x8c\xb9\x62\x51\x46\x05\x79\xa9\x27\x70\x76\xdf\x35\xe8\x32\xeb\x59\x2c\xa2\x72\x3c\xb6\x24\x03\xce\x5c\x1b\x25\x79\xf1\x2b\x44\x65\x0d\x44\x2d\xc1\x18\xc2\xde\x04\x16\x57\xca\xc5\x73\x51\x3c\x0c\xe1\xf9\x8e\x31\x2b\x88\xed\xb5\x56\x86\x21\xa8\x3a\x98\xd4\x84\xb0\x25\x5f\xc1\xb3\x75\xe3\xca\x09\x67\xe2\xf2\x28\x48\xf9\xf8\xbe\xbe\xaf\x0a\x5c\x92\x19\xc2\xd4\x4a\x3d\x34\x8b\x62\x1e\x10\xb2\xd5\x3c\x09\xc3\x97\x40\x12\x61\x86\x0b\x6b\x4b\x70\x40\xc8\x39\x80\xde\xbb\xab\x46\x1d\xdb\xc7\xd7\xf4\x5f\x6f\xac\xf8\x4d\xdb\x18\xcd\xe3\xf9\xcd\xa8\x79\x53\x03\x34\x75\x58\xb8\xf1\x6c\x5e\x9e\x89\x6b\x60\x3c\xd6\x54\x36\x5d\x96\xab\x79\x30\x09\xc0\xf5\x21\x55\x4a\xf0\xa8\xc4\x33\x14\x07\x13\x95\x1c\x79\xe9\x98\x8d\x46\x28\x66\x61\xd8\x4c\x1e\x8f\xd1\x01\x38\x3b\x88\xdc\xc3\xc6\xe3\x39\x43\x74\xb2\x67\xd5\x36\xdb\xf0\x48\xb4\x66\xd9\x36\x47\x7a\x62\x6e\x58\x3a\xd9\x64\x39\xa7\xa5\xe5\x0c\xe5\xb7\x40\x20\x3b\x9f\xe5\x0a\x97\x62\x0a\x8f\x0d\x5f\x5a\x8e\x46\x88\x47\x62\x22\xb8\x84\x08\x86\x8a\xf3\x17\x29\x0e\xf3\xcf\xf4\x13\x84\x66\x90\x21\xd9\x6e\x10\xe0\x42\x70\x8d\x99\x25\x44\x2d\xd4\xb2\x33\x22\xce\xb3\x61\x31\xcf\x34\xe8\x12\x92\x9d\x91\xe9\xc2\xde\xb3\xd9\x2a\xa6\x93\xf4\x7a\x1d\x49\x7f\x12\x0a\x8d\xed\xd2\x26\x88\x6f\xcb\xe2\x1a\x38\xc2\xd7\x1f\x76\x54\xb9\xb7\x37\x02\xa2\x01\x2f\x06\xbb\x84\x6f\xf5\x30\x07\x57\xfb\x8a\x0f\x2e\xe8\x40\xb6\x54\x05\x48\xe0\x6d\xc4\x48\x32\x0a\x4e\x82\x11\xc3\x05\x91\xa1\x36\x13\x1d\xe1\x68\x8a\x34\x2e\x47\xc5\x22\x38\x09\xe2\x20\x40\x23\x71\x09\x47\x65\xc4\x60\xad\x78\x14\x9c\x04\x08\x77\x98\x1d\x0f\x87\xe0\x56\x6b\x58\xa0\xc9\xdf\x8b\x8c\x41\x39\xc1\x6f\x4e\x82\x03\x66\x13\x56\x94\x57\x49\x9e\x7d\x6c\x53\x2d\x19\x61\xe2\x3a\x54\x5e\xb6\xa5\x78\x51\x0e\xab\x88\x28\x1e\xcf\x90\x35\x0c\x16\xc3\xa0\x77\x1c\x46\xe6\x0f\x23\xab\xeb\x88\x92\x60\x12\x80\xe3\x7f\x01\x06\x3a\x22\xb2\x8d\xcc\xcc\x94\x8a\x91\xda\xb1\x74\x31\x66\x32\x34\xa9\x85\x97\xa8\x21\xfa\x69\x1b\xef\x34\x2c\x88\xa4\x90\x42\x45\x8c\x34\x8c\xca\xd4\xa2\x97\x05\x91\x98\x25\x8e\x5a\x02\x8f\x36\x42\xd0\xbb\x22\x84\x18\x61\x07\x36\x38\xc7\x96\x03\x2c\x31\xa5\x92\xe6\x09\xcf\xde\xd1\x06\x89\xef\xee\x39\xc7\xe5\x35\x99\xce\xb9\xd9\x4d\x61\x18\x00\x8c\xc0\x4a\x61\x34\x72\x77\x9e\x73\x8a\xb0\x33\x71\xad\xab\x92\x6c\x25\x36\xbb\x15\xe1\x9d\xb1\xc5\x52\xec\x05\x29\xd7\xe1\x98\x8d\x05\x1b\x76\xa0\xc4\xec\xc0\x88\x22\x1d\xd6\x60\x86\x30\x77\x32\xb8\x93\xe1\x3c\x09\xf7\x11\x07\x89\x9b\x2c\xe2\x5e\x8a\x72\x97\x7a\x95\xb1\xa8\x30\xce\x8b\xf4\xa5\x82\x2b\x92\xe0\x94\x4c\xe7\xe9\xe3\x64\x9e\x8e\x46\x28\xdb\x44\xc5\x32\x5d\x0d\x09\xc9\x96\xe9\x0a\xdd\x54\x24\x9d\x4b\xf9\x36\xd8\x21\x68\x91\x63\x4a\xaa\x79\xfa\x58\xb7\x07\x35\x73\x79\xb6\xb8\xa7\x59\x94\x93\x5c\x30\x1c\x69\xc2\xa3\x4c\xcd\xba\x42\xee\xa2\x88\x35\xa9\xe8\x4e\x60\x2c\x66\x82\x85\xcf\xae\x32\x4e\x4b\x12\xc4\xf0\x9d\x95\x2c\xb9\xa2\x4d\x23\xee\x0e\x84\x51\x78\x1f\x20\x0c\x92\x75\x3d\x3d\x85\xdc\x93\x60\x6e\xd7\x54\x22\xf9\xd3\x62\x4d\x01\xd1\x31\x23\x32\x04\x0e\x56\x5a\x81\xe1\x14\x5c\xb8\xb8\x27\xdc\x6c\x3e\x1e\x67\x02\x34\x50\x32\x6a\xb4\x91\x21\x24\x6f\xf9\x02\xdd\x94\x24\x53\xe0\x92\xac\x85\x38\x38\x8d\x09\x01\x11\x77\x3b\x93\xbb\x72\x12\x88\x8b\x42\x26\x89\x04\x8d\x14\x53\x2c\xdd\xf6\x5e\x24\x15\x6d\xcc\xbd\x8b\x3f\x45\x37\xc7\x80\x21\x29\x62\x2c\xaf\x3a\x35\x39\xe5\x78\xd7\x99\x20\x17\x17\xdf\x78\xcc\xcd\x04\xbd\xd9\x71\x3b\x39\x46\xf8\x68\xe6\x4e\x4f\x4e\x09\x28\x8d\x21\xd0\x58\x23\x73\xaa\xa9\xd9\x06\x76\x66\x40\xa3\xb9\x5a\x30\x71\x1d\x29\x94\x1e\xcf\xee\x69\xfa\x0c\x49\x47\xc1\x11\x23\x26\x77\x6a\x88\xa0\xb1\x29\x85\x30\x13\x60\xa2\xef\x79\x0b\x43\x8e\x42\xc4\xe2\x01\x58\x29\x4d\xbd\x55\x9f\xe2\xc4\x05\x4c\x22\x01\x63\xa4\xd7\x1e\x5c\x12\xb8\xcc\x1e\x7c\x3d\x24\xa4\x42\x4d\x40\x24\xa3\x19\xc2\x10\x85\xa9\x5a\x40\x1e\x5f\x70\x92\xc4\x33\xb1\xad\xc2\x30\xca\xc8\x0c\xc5\xe3\x99\x14\xae\x47\x19\x11\x97\x01\xa0\x8b\x01\x74\x62\x01\xed\xc0\x93\xd7\xb5\xec\x49\xfa\x53\xce\xea\x5a\x7c\x65\x61\xc8\x45\xa2\xb8\x87\xc5\x0f\x36\x9a\xb9\x70\xe7\x02\xee\x73\x79\x5a\x04\x17\xe2\x60\x0a\x92\x8b\xc0\x42\xde\x77\x95\xe6\x88\xaa\xa8\x09\xb0\x82\x19\x3a\xc4\x7d\x02\xad\xc7\x53\x08\x3f\xac\xe1\x36\xe2\x08\xfb\x35\x3d\x9a\x90\x46\xc1\x1b\x65\xd3\x0b\x47\xf2\x8d\xfe\x8a\x1f\xdd\x17\xe4\xdc\xb7\x3d\x6f\x0b\xe6\xcc\x09\x13\x20\x56\xcb\x06\x55\x70\x14\x5c\x45\x5b\x76\x80\xd9\xdc\x39\xdd\xf5\x16\xd2\x07\x14\xf8\x0e\x33\x83\x03\xdf\xd3\xdb\xac\x92\x76\xc3\x24\x48\x78\x09\x11\x00\xd8\x81\x11\x8a\x23\x4e\x4a\xe4\x58\xf4\x79\x16\x94\x91\x63\x3f\x8b\xb0\xfb\x06\xc2\x11\x8e\x10\x8e\xf9\xc4\x88\x3f\x08\x53\x63\x2e\x6d\x69\x23\x4b\x9a\x24\xbb\x9d\x17\x15\x48\xbf\x26\x02\xa5\x27\x2b\xd6\xb4\xaa\xeb\xc8\x7e\x90\xe5\xca\xbd\x91\x9a\x94\x1a\x96\xde\xfb\xa5\xec\x8f\x21\x5c\x90\xe9\xbc\x78\xcc\xe6\xc5\x68\x84\xca\x65\xb1\xb2\x15\xac\x18\x10\x16\xd5\xce\x43\x0e\x48\xae\xa5\xb1\x2d\x5e\x8a\x11\xac\xf4\x19\x5f\x8a\x15\x2d\x26\xbb\x92\xfe\x9b\x8d\x5d\x8d\xe8\xf6\xc1\x97\x87\x28\x8a\x4a\xe9\x52\x3f\x2d\x18\x4f\x32\x06\xee\xf8\xc3\xb0\x74\xf0\x6f\x51\xc6\x37\x3a\x92\x78\x79\x40\x1a\x13\xdd\x48\x1f\x05\xb6\x6c\x91\x49\x95\xce\xf7\x6d\xbb\xf1\x83\xd9\x61\x85\x1f\x4c\xff\x9d\x70\x5e\x45\x40\x10\x48\xaf\x29\xb8\xdf\x05\xf7\x3d\x50\x0b\x34\xf8\xc2\x50\x86\x26\xe3\x07\xdf\x08\x00\x77\x04\x39\xb9\x13\x68\x4b\x92\xc9\x08\x0d\x6b\x1b\x92\x51\x90\x54\x85\x4e\xd7\xc0\x72\xb9\xe3\xcc\x65\x8e\xfd\xf0\x26\x0b\x6a\x67\x44\x5d\xff\x9e\x2d\xd6\x74\xce\x1e\x1b\x4d\x8e\xe0\x2a\xb5\x7f\x27\x50\x24\x4e\xac\x48\x91\xb8\x1f\x75\x2d\x2e\x9f\x89\x2b\x80\x14\x53\x0b\x40\xe6\x18\x64\x52\xb3\x5f\x4e\xb4\x84\x91\x0c\xa7\x08\x77\x47\x40\xa1\xb8\x9c\xbc\xa5\x1f\xc4\xcd\x71\x50\x9a\x5b\x47\x06\x04\x63\xc4\x99\x9d\x72\xe5\xc4\xfa\xd1\xbb\x4b\xe0\x96\x15\x9f\x4a\x1c\x3b\x64\x84\xe3\x88\x91\xaa\x1f\x95\x32\x17\x95\x58\x0f\x2a\x31\xcc\x1c\x54\xca\x64\xe4\x10\x9c\xe3\x3d\xde\x91\xaa\x7d\x98\xee\x80\x32\xed\xd2\xb0\xd1\x89\xb4\x8e\x25\x72\x2b\x98\x13\x49\xb1\xc9\xda\x7f\xc6\x6e\x42\x93\x74\xdb\x0e\x3c\x94\x27\x15\xff\x21\x49\xb7\xfa\x34\xd3\xdf\x44\x47\x8f\x02\x47\x92\xf6\xb4\x53\x9f\xe4\xe6\xa0\xf2\x75\x85\x11\xd1\xd2\x4b\x2f\x59\x50\x18\x6e\xc5\x25\x5f\x69\x2b\x31\x18\xa6\x83\x32\xb8\x9c\x37\x4a\x3e\x76\xa6\xa3\x39\x98\x48\x59\xd7\xd8\x52\x18\x9c\x6f\xc1\x3e\xb4\xe5\xc1\x11\x17\x42\x68\x8e\x1a\xa5\xc5\x38\x8d\x8a\xcb\x5a\x8c\x3a\xcd\x95\x07\x01\xae\xeb\x24\x7f\xdb\x6b\x89\x44\x7d\xf7\xd5\xce\x79\x07\x46\x17\x44\x5a\x06\x58\x3b\x95\x6c\x23\xb0\xa2\xa8\x78\x5a\x55\x2f\x8a\x35\x25\x1c\x67\x93\x8a\x27\xe9\xdb\x30\xe4\xea\x75\x75\x18\x9e\x9c\xb3\xf3\xea\xe6\xc1\x21\xe1\x83\x13\xa9\x1a\x51\x85\x90\x16\xe8\xe8\xb2\x73\x95\x41\xd4\x7f\xfb\xc6\xc3\x69\x02\x07\x5f\x85\xc1\xa8\x90\xae\x3f\x27\x9b\xb2\xb8\x1a\x05\xb1\x48\x80\xe8\x32\x93\x3c\x63\xd4\x4b\x48\x8b\x7c\x7f\xc5\x46\xa2\x16\x3a\x48\xee\x35\x3b\x68\x81\xdf\x50\x8a\xec\x00\x2c\x62\x0b\x12\xf9\x13\x74\xe4\xe5\x41\xdc\x3b\x12\x64\xdf\xd3\x34\xaf\x7a\xdc\x1c\x2d\xa8\xab\x55\x96\x2f\x5a\x64\x34\x2a\x68\xca\xf5\x94\x56\x4a\x2e\x49\x1c\x5a\x60\x43\x0b\x27\xbb\x38\x89\x00\x2c\xb0\xa9\x76\xc6\x3e\x85\x4b\xc2\x1c\xa9\x00\x56\x77\x6d\x4c\xb6\x22\x98\x85\x76\x43\xe0\x5a\xad\xab\x35\xaa\xe4\xa1\xa6\x35\x0a\xad\xd9\x16\x44\x81\x03\xb2\x00\xf9\x79\x9f\xd3\x2f\x07\x10\x20\xe6\xba\x00\x52\xd1\x9c\x82\xf3\xbf\x4f\x04\x4a\xb3\x41\xdb\xd2\xe7\x02\x46\xb7\x78\x1b\x60\x9e\xf0\x2f\x0b\x1a\x45\xe9\x76\x01\x47\xf0\x57\x9f\x0a\x98\x76\x73\xb2\x9d\xcf\x05\x8b\x6d\xef\x36\xc0\xa8\xf0\xc6\xfd\x76\x90\x8d\x2e\xb4\x88\xde\xd0\x3d\x82\xcd\xf2\xfa\x50\xc7\x91\xec\xa2\x4d\x95\xeb\x13\x98\xb6\xe9\x56\xee\xd0\xad\x60\xaf\x25\xae\x75\x0a\xf7\x39\x98\x05\x59\xba\x95\x39\x86\x5c\x64\x8a\x0b\xc2\xe7\xa5\x95\xae\x94\x9a\x00\xc8\x48\xb1\x2c\x57\x38\x21\xea\xa8\xd6\x72\xb5\xcc\xde\x26\x5a\xa2\xe3\xa9\xe3\xa2\x0a\xe1\x9c\x48\xd6\xbf\x22\xe9\xa2\x8a\xab\xa5\x7c\x71\x36\xc9\xb8\xd4\x7f\xad\x22\x34\x57\xaa\x80\x3d\xb8\x71\x06\xa8\xe4\x67\xe6\x2d\x8a\xb4\x72\x9c\xef\x49\xb5\xcc\x47\xa3\x95\x71\x8e\x1b\xe5\xa4\x9a\x30\xfa\x9e\x47\x08\x4d\xd6\x05\xa3\xa6\x60\x2e\xfd\xb1\x03\x01\xb1\x23\xfb\x79\xf3\x7a\xdd\xa1\xc3\xc1\x59\x19\x01\xde\x0e\xce\xe1\x4b\xc1\x57\x11\x50\x84\x4f\x4a\xfa\x8e\xca\xf8\xac\x8d\x57\xe9\x51\x89\x70\xa6\xc0\x54\x92\x62\x51\xc6\xe5\x11\x30\x25\x02\x4c\x85\xbc\x9e\xce\x8c\x5f\x70\x35\xfb\x84\x94\xcb\xcc\x03\x53\x46\xca\x2e\x30\x25\x24\x73\xc0\x24\xd7\xae\xb1\xba\x8a\x30\xd9\x64\x65\xc5\x71\xa0\x40\x04\x4f\x13\xf5\x3c\x72\x92\xe2\x7d\x63\x2e\x39\xc2\x3b\x35\x97\x9c\xec\x17\x79\x9c\x1f\x99\xcb\x46\xcc\x65\x0f\x73\xd9\x9d\x91\xdc\x9f\xcb\x86\xe4\xcb\x9d\x37\x97\x1d\xc9\xbb\xe6\xb2\x21\x3b\x67\x2e\x6b\xb2\x71\x97\x5c\x6b\x3b\xd6\xe8\xa0\x97\x74\x0b\xae\x37\x1d\x02\xc2\x27\x37\xb6\x2b\xd2\xf8\x1e\xa5\x6a\x64\x4d\xbc\x81\x00\xc0\x3f\x27\xd7\x2d\x7f\x0f\xbc\x61\xf0\x0d\x85\x5c\x71\x04\xf2\xc8\x29\xc7\xea\x19\x52\xf4\x2b\x2e\x03\x55\xc5\x7e\x8a\x19\x30\x52\x2e\x58\xcc\x8e\x40\x35\x93\xde\x93\xc0\x54\xf2\x8c\x30\x1f\xaa\x19\x61\xcb\xc2\x83\x6a\x41\x58\x17\x54\x33\x52\x28\xa8\x66\x76\x0a\xe0\xc4\x40\xcc\x3c\x63\x15\x2d\xb9\x0c\xe8\xdc\x25\x2b\xc4\x25\x99\x12\x42\x22\xea\xc0\x52\x1a\x8d\x18\x4c\xc2\x45\x13\xe3\xb8\x03\x94\x25\x5d\xe1\xd2\x45\xb6\x8c\x14\xda\xe0\xc8\x80\x25\x13\xc7\x8e\x04\x4b\x46\x92\x45\x16\x67\x47\xc0\x92\x0a\xb0\x48\x0b\xd2\xea\xcc\x58\x5c\xab\xd9\xa6\x24\x5b\x56\x1e\x58\x2a\x92\x75\x81\x25\x25\x95\x83\x6c\x39\x49\x5d\x64\x53\xda\x37\x8a\xa7\x38\xb7\xf8\xb6\x6f\xe1\x1b\x7d\x4c\x9a\x24\xf1\x7e\x85\x74\x94\x55\x9b\x44\xd8\xa8\x68\x3a\x4b\xd7\xb8\x27\x57\x00\x62\x76\x37\x16\xa0\x01\xf3\xb9\x5e\x90\xe3\xd0\x46\xde\x01\x55\xe2\xac\x01\x6b\x19\x2e\x4c\x29\xa8\xb3\x45\x11\x17\x47\x60\x5d\x09\x58\x4b\x1a\x3a\x39\x23\x85\x0f\xeb\x8a\x14\xcb\xc4\x83\x75\x42\x8a\x2e\x58\x57\x24\x71\x60\x9d\x92\xaa\x0b\xd6\xa3\x19\x9e\xe2\xd4\x42\x3b\xef\x80\x76\x13\xd8\x79\x1b\xd8\xb9\x00\x76\xd9\x07\xec\x92\x5e\x15\xef\xe8\xd3\x6d\x96\xaf\x3b\x3c\xed\xf8\x01\x42\x7d\xe8\xfb\x40\xd6\x7c\x9f\x8e\x95\xd9\x81\x3a\x33\x9f\x87\x43\x11\xf7\xc7\xce\x56\xe8\x0c\x8c\x30\x1a\xa9\x84\x5b\xdd\x5e\x63\xdc\x4f\xf2\xbc\x27\xa4\xb5\x3c\x6d\x78\x63\xa9\xd5\xa5\x26\xa6\x45\x09\x5f\xd0\x98\x1e\x59\xea\x12\xb8\x45\x69\xe4\x7e\x66\x55\x20\x72\x05\x4b\x42\x97\xcc\x5b\x6a\x46\x68\xd7\x52\x97\x84\xa9\xa5\x2e\x7d\x18\xb9\x47\xae\x11\xdb\x61\x3b\x3f\x60\xa1\x7e\x15\x35\xab\xd6\xbb\x0b\x2d\x48\x02\xa3\x55\x8e\xb9\x65\x80\x0d\xd7\xe3\x90\x64\x25\xba\x81\x63\x7b\x57\x85\xa1\x14\x7b\xcb\x2f\x09\xe3\x97\x9b\xa8\x94\x1c\x4c\x5d\xf3\xc9\x26\xa9\xb8\x2a\x55\xca\x71\x9b\x52\x32\x13\xd5\x75\xa4\x72\x4c\x09\xcd\xef\x09\xda\x11\x9c\x45\x1b\x2e\xff\x1d\x2d\x3f\xf4\x52\x8e\x12\x3f\xa0\x0c\x3c\xa0\xd9\x4d\xaa\xe2\xaa\xdf\x29\xa6\x42\xa7\xe2\x8a\xaa\xd2\x99\x1f\x68\xb9\xc3\x4a\xc8\xe8\x2b\x16\x34\x76\xda\xd0\x33\x92\xcd\x74\x68\x9c\x0d\x0b\x9d\x01\x36\xcd\x3d\xef\x5a\xc6\x9a\x0f\xd9\x37\x3e\x60\xbf\x63\x45\x36\x57\xc9\xce\x25\x89\x9d\x1c\x18\x80\xc0\x71\xb5\xe4\x54\xff\x42\x08\x6b\x09\x80\x76\xdb\xce\x0f\xe0\x17\x3c\x0a\x26\x27\x10\xb0\x36\x40\x11\x47\xaa\xb4\x51\x6f\xf8\x08\xce\x91\xb1\x3e\x11\xec\xb9\xd4\x80\x89\xbb\xc4\x2f\x96\x20\xd0\x51\xca\xd8\x87\xd5\x22\x89\x93\x23\xfb\x20\x17\xd3\xaf\x60\x1f\xa4\x67\x24\xf1\xf7\x41\x4e\x92\x65\xea\xed\x83\x94\x24\x5d\xfb\x20\x27\xa9\x73\xe4\xed\x49\x3e\xdf\xab\xfd\x10\x86\xfa\x97\x7b\x1a\x45\x7b\x1c\x64\x97\xac\x28\x69\x80\x94\xee\x0f\xf8\xb9\xa2\x70\x59\x8a\x1b\x49\x0b\x8b\xc9\x2a\xf4\xd0\x53\xde\x34\xa6\xbc\x43\x78\xad\xa6\xbc\x23\x9b\xc5\x2e\xde\x1d\x99\xf2\x56\x3d\x7c\xc8\x36\xd1\xfa\x8c\xec\xfc\x29\x6f\xc9\x6e\xb9\xf6\xa6\xbc\x26\xbb\xae\x29\x6f\xc9\xda\x99\xf2\x05\xd9\xce\x2f\xcc\x94\x2f\xba\xa6\x7c\xd1\x35\x65\x35\x53\x4e\x96\x7c\x35\xb7\x89\xb0\x63\x81\xd1\xea\x72\x54\xc3\x65\xc7\x8e\xda\x5f\xa9\xfc\xe1\x40\x19\x6c\x32\x9a\xaf\x07\x59\x35\xb8\xca\xaa\x8a\xae\xc1\xf4\xa9\x58\xd3\x01\xc8\x0c\x41\x26\x3b\x6f\x2b\xfd\x54\x9b\x80\xbc\x72\xff\xbf\x52\x71\xc7\x55\x67\x08\x73\xb2\x14\x7d\x95\x5a\xf6\x1b\x71\xb4\x72\x26\x62\xc4\x02\xb2\x9c\x44\x6d\x60\x44\x91\x40\x6d\x77\x7a\xc0\x24\xbb\xc5\x12\x3e\x6e\x96\x04\x35\x2a\x9f\x70\xfa\x9e\xb7\x27\xfa\x0b\x7b\xcb\x8a\x6b\x35\x2f\x31\x83\xae\x49\xaa\xf1\x16\xde\x78\x7b\x76\x71\x5b\xc8\x29\x78\xfa\x8e\x55\xa4\x08\x77\xae\x09\x9d\x94\x82\x56\xbe\x00\xd2\x32\x0c\x59\x18\x76\xdb\x73\xf9\xc5\x22\xaf\x1a\xf1\x72\x1d\x97\x2b\x7f\x3b\xaf\xc0\xcb\x4a\x80\x10\x36\x42\xd8\x0c\x53\x60\xb3\x53\x52\xe1\x28\x27\xcb\x9b\xb7\xf4\x43\x1c\x00\xdf\x13\xe0\x4b\xca\x5d\x97\xb8\x5a\x32\x2a\x8f\x97\xd6\xb9\xbb\x9c\xae\x0e\x07\x2c\x1b\x10\x6c\xf1\x27\xd7\x6f\x09\x4f\xc7\xb3\xd5\xe1\x20\xc8\x95\x24\x4a\x1d\xbf\x38\x39\xc2\x7b\x48\xc3\x7b\x84\xab\x43\xa4\x14\x03\x4a\xa1\xd1\xa5\xb3\xa8\xfa\x75\x16\x1a\x69\xe2\xfb\x10\x6b\x59\x8b\x24\xe2\x07\x10\x69\xd9\x55\x42\xc4\x0f\xee\x63\x47\xc9\x81\xcd\x99\x1b\x3f\x80\xaa\xb2\x99\x87\x8f\x0e\x2b\xfc\xa0\x33\xc4\xf2\x9d\xb4\x1f\x89\x98\x4c\xb5\xdf\xc1\x60\xc7\x69\x91\x17\xa5\x54\x7f\x40\x46\xba\x4d\xf2\xb7\xd2\xe6\x24\x91\xb3\xe6\xb4\xbc\xca\x58\x92\x8f\xb7\xd9\xe5\x36\xcf\x2e\xb7\xbe\x66\x24\xf9\x74\xcd\x48\x65\x2d\x60\x5d\xf3\x4b\x8d\x7c\xcf\x93\xdd\x42\xec\x88\xe7\xc9\x4e\x1b\x6e\x2a\x25\x57\x8b\x13\xd4\x6f\x04\x80\x06\xa1\x18\x48\x06\xe3\xfa\x48\x9b\x6f\xeb\x87\x3a\xe6\xca\x0d\x96\x0c\xec\x85\x06\x69\xb1\xa6\xab\x00\x35\x02\x55\x31\xb8\x6a\xbb\x6c\xdd\xbb\x2d\x98\x5e\xed\x77\xb4\x1c\xd0\xf7\xbb\x92\x56\x15\x38\x91\xda\x57\x7c\x40\x33\xbe\xa5\xe5\xe0\x82\x82\x75\xee\xa0\x28\x07\x89\xb1\xb9\x0d\xa4\xcd\x5c\xd7\xce\x53\xcf\xc5\xd4\x83\x5e\x83\xc3\x3a\xb6\x08\x57\x0f\x65\x4b\xf7\x41\xa6\x55\xd4\x40\x80\x32\x63\xaf\xb5\x8b\xa4\x0e\xd0\x8b\x84\x62\xdf\xed\xf6\x28\x6b\x1c\x15\x2b\xd8\xbd\x1b\x6f\xc2\x2a\x64\x7e\xd9\x30\x7e\x77\x6c\xdb\x71\xc3\x4c\xfe\x70\x40\x78\x1f\x95\x98\xa2\x03\xf2\x83\xce\x45\xfd\xd7\xc6\xcf\x74\x23\x4e\xe8\xba\x1e\xaa\x5f\x76\xfc\xd6\xd8\x36\xdb\x44\xad\xdc\x49\xb5\x4d\xae\xbc\x22\x5d\xd8\x05\xe6\xdd\xf6\x7d\x98\xf3\x24\x14\x1c\x0f\xb5\xdd\x1c\x4a\xf4\x69\xf5\x16\x89\xe2\x78\xb9\xc2\xae\x35\xfe\x01\x21\x84\xcd\x73\x5c\xea\x58\xba\x3b\xaf\x52\x7c\x02\x3a\xca\x49\x1a\xa1\x45\xab\xfd\x96\x69\x86\xdc\xbd\x4b\x81\x4d\xab\xb9\x7c\x76\xad\xd4\x72\x25\xe6\x48\x69\x8d\xc5\x55\x65\x36\xc0\x45\xc6\xd6\xaa\x08\x3c\x12\x35\xd6\x7b\x61\xb8\x8f\x0a\xec\x29\x78\x8b\x03\x52\x45\x45\x07\xee\x1b\x09\xfb\xe4\xc5\x95\x47\x47\x7b\x8d\x36\x95\xe7\xaa\xca\x7d\xd0\xeb\xc5\x9a\xb5\xaa\x3d\x2e\x6e\x04\xc8\x75\x5e\xb4\x58\x60\x45\xbb\xee\x96\x17\x9d\xae\xb1\xba\x4c\xd5\x9d\xce\xea\xba\xb3\x56\xa4\x31\x12\xe4\x64\xc7\x75\xed\x49\x64\xdf\xbc\x56\x5a\xd8\xa1\x86\x9a\xf6\x68\xdd\x41\x2c\x1e\x3c\xad\xaa\x57\x1f\x18\x4f\xde\xc3\x41\x11\xe0\x74\x52\xd2\xa4\x2a\x04\xb7\x94\x85\x61\x94\x4e\x36\x59\x4e\x49\x86\x70\x01\x5f\x92\xe2\x26\x05\xc2\x15\x7c\xef\xf2\xfd\x65\xc6\x48\x85\x7a\x6c\xae\x7b\xee\xee\x12\x2a\xe7\x19\xa3\x84\xe1\x54\xe9\xb0\x48\x89\x70\x2a\x00\xfa\x9c\x56\x55\x72\x49\x23\x84\x61\x50\x93\x34\xd9\xf1\x7d\x49\x5f\xf1\x24\x7d\xfb\xba\x4c\x52\x1a\x86\x3d\x19\xcd\x47\xd7\xf6\xc9\xbb\x73\x2c\xfe\x4c\x37\xb4\xa4\x2c\xd5\x67\xa3\x00\xc7\x60\x9b\x54\xec\x0f\x7c\x70\x41\xa9\xe0\xe1\x33\x9e\x25\x79\x26\x28\xbe\xf1\xa0\x12\x47\x67\x84\xbc\x12\xf0\x00\x65\xed\x1a\x7c\x46\x29\xc2\x82\x5b\xd0\x06\x3b\xc9\xef\x60\xb0\x53\x91\xa4\xad\x63\xae\x1c\x88\xb5\x9c\x4a\x5c\xa9\x74\xf8\x90\x6b\xb5\x70\x7e\x8f\x82\x78\x10\xc4\x41\x80\xdd\xc2\xca\x71\x8c\x58\xf7\x85\xf9\x15\x07\x8f\xd3\xaa\x1a\x80\x52\xf2\x2c\xe8\x5e\x6c\xa9\x0a\xc8\x98\x11\x4d\x98\x06\x83\x38\x18\x99\xdc\x91\xf9\x92\xcb\x8e\x70\xb3\xf0\x40\xe5\x4b\x4c\x3c\xe0\x6a\x52\x6d\x8b\xeb\x57\x80\x7a\x4f\x8b\xce\x77\x5a\x9a\xfb\x1c\x4a\xd7\x0c\xd2\xf1\xb5\xe2\x72\x83\xb9\x23\x5d\x35\x9a\x58\x75\xe9\x87\x61\xf7\x09\x0f\x14\x25\x31\x04\xfa\xa4\xe2\xeb\x62\xcf\xc1\xd6\x39\x62\x24\x9a\x62\xd3\x02\x8a\x40\x63\x2d\xb9\x49\x6d\xd3\x7d\x72\x5e\x2e\xce\xd9\x89\xe0\x28\xb5\xdb\xb8\xc8\x40\x60\x7c\x1f\x4f\x05\x63\x69\xcc\x63\x2d\x6c\x4e\xb1\xe1\x1b\x71\xae\xf9\x86\x14\x99\xf7\xde\xf6\x9c\xf3\xa2\x08\x1a\xc2\x7c\x52\xd2\xf5\xc2\xfb\x9a\x5c\x14\xf9\x3a\xe2\x28\x76\xdf\xe6\xf5\xd5\xbe\x2c\x93\x0f\x0b\xff\x53\x56\xd5\x4f\xb8\xb4\x2d\x2d\x4e\x51\x93\xec\xb7\xe7\x7f\x35\x9a\x49\x5b\xf8\x41\x30\x8a\xc4\x9f\x12\xa9\x7a\xe3\x1c\x8d\x82\x41\x3d\x08\x40\x40\x0d\xec\xa9\x98\xb6\x96\x21\xec\xa2\xc2\xd1\x89\xaf\x05\x9d\x3e\x08\x10\x1a\x59\x1b\x55\xad\xef\x1e\xcf\x90\x47\xd4\xf3\x95\x2a\xac\xb7\xc5\x3e\x0a\xce\x02\x34\xda\x45\x05\x1a\xd1\x51\x70\xce\x06\xc1\x28\x1b\xed\xa3\xe0\x6f\x81\xa6\x2f\xc4\xc8\x64\xbe\x35\xd7\x3e\x67\x01\x12\x08\xa7\x2f\xd6\x1e\xa9\x99\x8f\x8f\x91\x3d\x07\x00\x6b\x82\x73\x76\xce\x02\xd9\x6d\xa0\xe5\x7f\xc9\x15\x1d\x59\xd4\xd6\xd8\x4e\x0f\x38\x39\x44\x55\x04\x47\x11\x72\xa9\xf5\x4d\x3f\xb5\xde\x41\xed\xc6\xa7\x18\xa8\xe2\xf8\x14\x37\xe9\xe6\xf8\x54\xd0\xe2\xf7\xff\x9d\x4c\xbd\x40\x0b\xff\x7f\x93\x9d\x57\xd3\x61\xff\x27\x72\x3a\xbb\x84\x6f\x1d\xfe\x66\x72\x92\x56\xd5\xb8\x82\x6b\x79\x4c\xe1\x5e\x76\x99\x9d\x5d\x49\xdf\x65\xc5\xbe\x1a\x5f\x25\xbb\x2f\xc0\xe6\xfc\x7b\x1b\x80\xe5\x64\x8a\xf7\x3d\x0e\x34\xf5\x3b\x0e\xfb\xac\x1d\x0c\x82\x6f\x0e\x08\x5b\xa6\xcb\x3e\x37\x54\x5e\x8d\x87\xae\x33\xf4\xa6\x34\xe4\xa7\xa2\xe2\x4f\x5f\xbd\x1a\x94\x34\xa5\xd9\x3b\xba\x1e\xc0\x36\x06\xa3\x06\x9a\xac\x07\xc5\x66\x20\x72\x95\xc8\x47\x39\x7d\x4c\xab\x8a\xd8\x36\x23\x84\x83\xf3\xfd\x86\x6e\x36\x70\x9b\xa8\x02\xcb\xe9\xaa\xae\x45\xfa\x66\x43\x1b\xe9\x0b\x79\xfc\x6f\x93\xea\xbb\x97\xcf\x05\xd4\x4c\xa3\xfa\x87\x3a\xfd\x66\xda\xf8\x41\x17\x9d\x61\x69\x20\x14\x86\xd1\xc9\xdf\xce\xaf\x47\xf1\xf9\xc9\xf9\x89\xb2\x41\x92\x39\x10\xec\x59\x9f\xe6\xce\x9b\x20\x95\x6b\xef\x77\x22\x53\x62\x9b\x50\x3a\x97\x88\x7a\x08\x22\x2b\xb9\x61\x7d\x33\x2b\x10\x52\x63\x55\xb1\x7b\x99\x94\x36\x29\x2a\x24\xd9\x19\x93\x63\x06\x5b\x56\xe0\x4d\x84\xa0\xa3\xf9\xd0\xf4\x19\x86\x85\x26\x1d\xe4\x98\x54\xe5\x9f\xd5\x00\x0a\x84\x0e\x26\xb7\xae\xa3\x7c\x44\x66\x4a\x55\xb2\x26\xc1\x63\x20\x4e\x06\x82\x4c\x09\x46\xf9\x48\x1c\xff\x58\xb7\x60\x28\x92\x64\xe7\x34\x0d\xd3\x39\xa8\xd3\x0c\x27\x78\xef\x9a\xee\x9a\x8b\x64\x02\x3b\xb0\x27\xea\x6e\x66\x7d\x35\x00\x8a\x83\x67\x0c\x25\x58\x16\x5d\x14\x65\x76\x99\x49\x39\xb9\x3e\x1a\x33\x92\x2c\x7c\x61\x1a\x15\x97\x7e\xc6\xc4\x3f\x79\xbb\xe1\x44\x8b\xb6\x13\x18\x2e\x2e\x15\xc1\x26\x3d\xaf\xb8\x35\xc5\x58\x2c\xec\x35\x70\x6c\x05\xa4\x62\x49\xdf\x88\x0e\x62\x8e\x65\x07\x31\xc3\xb2\x83\x58\xd7\x3d\x60\x67\x19\xa2\x4c\x9b\x9f\x59\x58\x65\x39\x45\x38\x3b\xe0\xbd\x9a\x53\xdb\x7f\xcc\x50\x83\xd8\x7f\x6f\xca\xcc\x3a\x3a\x4b\x0f\xae\xd4\x64\x43\x49\xfe\x53\x51\x65\xa2\xa5\x3f\x16\x65\x24\xc7\x49\xf5\x38\xf9\x01\xd0\x69\x58\xfa\x34\x9d\x6a\xba\x20\x37\x40\x9c\x36\x11\xc5\x94\xc6\xd0\x5a\x29\xa1\xab\x9a\x2c\x15\x90\x0f\x38\x23\x3a\x46\xca\xd3\x82\x71\xca\xb8\x18\x80\xa9\xab\x11\x40\xb0\x41\x85\x66\x7c\x04\x23\x24\x60\x60\x3b\xeb\xd0\xab\xb4\x36\x23\x45\x0b\x31\x8a\xd6\x86\x6a\xc3\x45\xf5\xf3\x73\x51\x70\x78\xe9\x07\xce\x20\xb9\xb8\x1f\x99\x11\x4b\x96\xc5\x55\x4b\xaa\xe8\xca\x11\xe5\xee\x50\xfb\x42\x8a\x0e\x2b\xd7\x1e\x01\x33\x84\x13\x48\x13\x1c\x0b\x3d\x44\xee\x85\xb7\x3f\x62\x3e\xde\xbc\x94\xe2\x07\xa7\xb8\x79\x1f\xc5\x0f\x4f\xb1\xb8\xce\xe2\xfb\x70\x31\x76\x44\xf4\xf0\xf4\x6d\x77\xa4\x3e\xf6\xf2\xe6\xbb\x4a\x76\xe3\x4b\xfd\x70\x5e\xde\x89\x2a\x47\x9e\xc8\xd9\xe6\x83\x7c\x78\xa6\x52\xaf\x93\x92\x8d\x0b\x96\x8a\xab\x1f\x57\x3a\xb5\xa4\xd5\x3e\xe7\x22\x29\xd7\x49\x4a\x6d\x84\x5c\x02\xfb\x93\xef\xd2\xdd\xbf\xf3\x5d\x6a\x46\xb9\x71\xf4\x7f\xcd\xab\xb1\x4b\x16\x45\x27\x7c\x4b\x99\x36\xac\xe9\xbc\x87\x5d\x1f\x41\xc6\x72\x58\xaf\x48\x46\xd7\x70\x53\x01\xd7\x29\x5f\xdc\xc8\x14\xaf\x77\x86\xc2\x50\x7a\x08\x20\x2c\x0c\x8d\xf6\x4a\x1a\xf1\xa1\x82\x30\xa3\xf2\xf0\x7c\x1c\xd1\xba\xf6\xbe\x2b\x43\xc3\x89\x9b\x46\xb4\x82\x99\x3a\xff\x3b\xb9\xbc\x52\x65\xc2\x7f\x20\x1c\xe0\xd7\x24\x63\xe2\xc4\x00\x0d\xae\xfd\x24\xc3\x99\xce\x17\x28\x4f\xa0\x65\xc7\xb1\x4f\x46\x72\xdd\xfd\xbc\x9c\xc8\x9d\x02\xaf\xac\xf4\xc7\x04\xd0\x4c\xb4\x01\x3f\x4a\x95\x29\x3f\x10\xce\xe4\x2f\x48\x55\xbf\x11\xc8\xfe\x0a\x92\x49\x93\x45\x29\xb2\x4b\xd4\xb5\x2a\xef\xa5\xe4\x70\x50\xcc\xb2\xc0\x6a\x19\xef\xd9\xde\xca\xb8\x10\xf5\xf4\x15\xb7\xc7\xeb\xae\x2b\x6e\x3d\x11\x1b\x25\x63\x97\x15\xe9\x39\x52\xaa\x0f\x2c\x8d\x90\x29\x16\xa1\x03\x5e\x77\xf2\x48\x6e\x25\xb8\x55\xd6\x80\x3e\x9d\xe6\xa2\xc1\xae\x2c\xd6\x7b\x23\xc0\x16\x7b\xe0\xdd\xe4\xc5\xcb\xef\x7f\x78\xf3\xc3\x8b\x5f\xc5\x8a\xc1\x49\xa7\x6d\x39\x8a\x1d\xaf\xea\x3a\x9a\x82\xc3\x25\xc5\x78\x07\x7f\xcd\xf8\xb6\xd8\xf3\xc1\xff\x88\xa2\xff\x33\x28\x76\x80\x91\x9a\x88\x4b\x8b\x7d\xbe\x1e\xa8\x03\x83\x0e\xae\xcb\x82\x5d\x0e\xe4\x01\x3b\xb8\x4a\x76\x83\x84\xad\x07\xd7\x59\x9e\x0f\x58\xc1\x07\x9b\x8c\xad\x07\xdf\x95\xc5\x75\x45\xcb\x2a\xcf\x2a\x3e\x90\x3b\x70\x32\x78\x45\xf9\x20\xe3\x03\x5e\x00\xed\x27\x4e\x57\x78\x03\x3c\x28\x4a\x91\xf6\x3f\x06\xaf\xfe\x07\x5e\x07\x97\xf4\x1d\x65\x1c\xc6\x3c\x50\xf0\x9a\x04\x4a\xd5\x3f\x49\x14\x20\x05\x4c\xa4\x74\x11\xaf\x27\xb0\xaa\xbd\xda\x7c\x5d\x45\x8b\x6b\x45\x8d\x8d\xb8\x35\xf3\x7e\x83\x81\x46\x37\xb2\xd2\x36\x61\xeb\x5c\xca\xbc\x1a\xcb\x21\x70\x4c\x6f\x5b\x89\x54\x14\x37\x05\x83\x43\x42\x28\x30\xb1\x75\x4d\x35\x6d\xa1\xec\xdc\xa4\x81\xfc\xaf\xb4\xac\xb2\x82\x81\x79\x57\xff\xb2\x1a\x4b\x37\x5d\xed\x27\x68\x0a\x17\xa4\xd9\x10\x96\x26\x05\x0a\xaf\xf5\xd1\x51\x94\x93\x77\x2a\x3f\x21\x85\x7e\x6e\x3c\x09\x10\x04\x7e\xb2\x9f\xf3\x28\x59\x4e\x57\x43\x42\x24\xe5\x0d\x9b\xe9\x19\xe3\x51\xb2\x9c\xad\xd0\x99\xf9\xac\xc4\x27\x0a\x43\x71\x01\x17\x39\x95\xb3\xb7\x3a\x51\xf8\x1c\x08\xdc\x32\x38\x25\xa7\x3e\x19\xfc\x56\xec\xcb\x41\xba\x2f\x4b\xb1\xd8\x3a\x53\x0d\x6d\x90\x55\x20\x6d\x08\xf0\xe0\x62\xcf\x07\xc1\x88\x8d\x82\xc1\xbe\xa2\x22\xb5\x18\x05\x93\xc1\x4f\xb4\xdc\x26\xbb\x4a\x22\x49\x26\xfe\x53\x8d\x97\x20\x47\xa3\xaa\xe7\x0b\x9a\x17\xd7\x13\xa3\xe4\xd6\x80\x6f\x41\x8f\x7a\x52\x53\x75\x4c\xa4\xe8\x46\x4d\xab\x31\xbf\xe6\x74\x53\x74\x10\xf8\x01\x48\xf3\x3a\x4b\xdf\xf6\x3a\x64\x35\x67\xbb\x1c\xc6\x19\x71\x0f\xf5\x42\x93\x9c\x95\xff\x06\x7a\xd0\x3c\xf9\xa7\x98\x46\xf2\x5c\x53\xb7\x61\x67\x23\x4b\xa7\xa3\x95\x36\x14\x2c\xf7\x82\x68\x98\xbb\x12\x4c\x32\xc3\x9b\xa8\x40\x8b\x42\x22\xbb\xab\xe8\x60\x76\x4a\x72\xaf\x21\xbd\x8b\x3c\x31\x31\x73\x77\x06\x28\x21\xa4\xd6\xc1\x8e\x17\xfc\xdd\x6a\xe6\xab\xd1\xa6\x79\x2c\xd2\x9e\x26\x8f\x32\x07\xb2\xdd\x92\xa4\x79\x27\x90\x80\x3f\x50\xa1\x2a\x9b\x26\xe3\x6a\xd5\x16\x2c\x52\xbf\x50\xcc\x23\x6a\xae\xdb\x0f\x11\x52\xa6\xed\x4e\x8b\x19\xbb\xd4\x2f\x81\x6c\x0a\x39\xd2\x09\xb8\xfe\x90\xad\x6b\x19\x8d\x49\x98\x1b\x34\x9c\x62\xea\x80\x43\x19\xab\xb7\xd7\xc1\x5a\x03\x78\x48\xe0\x0e\x19\x74\x52\x8d\xf1\xc1\xa1\xd5\x84\x9c\xc1\x40\xdd\x94\x87\x65\xf2\xac\x98\xb7\x0a\x19\xae\xda\x69\xbd\x6d\x08\x51\xd1\x81\xca\x8f\xd2\xaa\x52\x13\x49\x2f\x90\x38\xd6\xaf\x8b\xf2\xed\xe0\x3a\xe3\xdb\x01\x4c\x58\x1d\x03\x95\x54\x92\xda\x83\x53\xb5\x6a\x13\xe6\x8e\xd0\xb0\x75\x92\xa9\x46\xfe\xbd\xac\xef\xd4\xcb\x60\x30\xec\x89\xcc\xae\x2b\x10\xfa\x52\x10\x3b\xb4\x57\x4c\xac\x74\xb9\x67\xed\x77\x6e\x0a\x64\x79\x52\x71\x79\xd4\x11\xea\x6a\x43\x15\x0b\xa5\x4a\x01\xb9\xe7\x24\x38\x5e\x75\x9d\x65\x71\x37\x3b\x07\x33\x6c\xd8\xa3\x06\x19\xbb\xb0\xcd\xa1\x65\xbb\xf0\xad\x4d\xef\x2a\x74\x93\xd7\x70\x07\x0e\x08\x62\x06\x73\x62\xc4\x27\x73\x6a\xe9\x45\x4e\xf4\x87\x1d\x14\x72\xb6\x4b\x06\x84\x23\x94\xb2\x29\x08\x73\x5b\x1a\xb2\x9d\x6f\x57\x62\xe3\x98\xf0\xe0\x63\xc0\x83\x21\xa2\x89\x26\x9e\x22\xdf\x87\xb8\x2a\x93\x56\x15\x81\x28\x50\x6e\x22\x48\x7b\x96\x33\x2f\xb1\xc9\xc3\x9a\x3d\x70\x94\x91\x6d\x6e\x18\x63\x58\x23\xc6\x76\x97\x9a\xa2\x9c\xa9\x94\x56\xc7\xeb\x38\xc7\x11\x90\xae\xa6\x9e\x94\x0d\xdc\xbd\xae\x2c\x6f\xea\x0b\xae\xf8\xae\x75\xaf\x92\x9d\xa9\x07\x3c\xd0\xd1\x8a\x92\xc8\x13\xe5\x6c\x67\x92\x08\xb8\x65\xa6\xb2\xa2\x2e\x2b\x45\x04\xbb\xa6\x88\x60\x0f\x69\x78\xdf\x12\x11\xac\x3b\x45\x04\x47\x7d\x2d\xb4\x78\xf7\xf8\xc1\xd7\x6d\xd3\x21\xc9\x97\xc7\x0f\x1f\x60\x8f\xa3\x8f\x1f\x82\x99\x91\x65\xe6\xe3\x47\x33\xec\x7b\x6f\x78\xd0\x11\x19\xf2\x8e\x02\xf8\x1b\x20\x1a\x5b\x96\x0c\xf6\x55\xd4\x52\x90\x1f\x41\x80\x33\xc1\xb4\x26\x64\x8a\x2b\xf1\x23\x15\x7f\x72\x32\x9d\xe7\xd6\xeb\x55\xae\x59\xfc\x3d\xa1\xcb\x7c\x35\xaf\x16\xe9\x42\x94\x8b\x83\xf3\x73\xc1\x74\xee\xc5\xd7\x34\xde\x1b\xc7\xae\xc3\x19\x8a\xff\x10\xfc\x41\x64\xd5\x75\xf0\x07\x59\xa6\x22\xfb\x38\x88\xe4\xef\x64\x44\x66\x71\x80\xd4\xc7\xd9\x34\x0c\xa3\x64\x4c\x66\x28\x9e\x12\x42\x92\x30\x94\xae\x3c\x8c\xd1\xd0\x1e\x01\xf3\x38\x9c\x22\x9c\x2d\xa2\x40\x90\xdf\x45\x18\x2a\xf7\xf7\xc5\x84\x97\xd9\x55\x04\x6a\x06\x35\x1d\x14\x17\x23\xb2\xd7\x0e\xaa\x58\x5d\xcb\x2a\xa8\xa3\x4e\x79\xc0\xd5\x2e\x49\x3b\x9d\x36\x96\x8a\xf0\xa6\x78\x19\x0c\x02\x1c\x9c\x33\xf1\x87\x07\x2b\x74\xc0\x69\x71\x75\x95\xdc\x56\x09\x07\x2b\x19\x69\x19\x8b\x9b\xe7\x76\xed\x8b\x58\xf1\x66\x08\xcd\xcf\x94\x2c\x49\x4b\x33\xa0\xbd\x95\x3e\x45\x2b\x5a\x94\x52\xe6\x73\xd4\x2b\x8d\x97\xeb\x4d\xa5\x85\x18\xab\xbf\xf5\xf5\x33\xc4\xab\x64\xf7\x72\x07\x93\xbd\x4a\x76\x75\xad\xc3\xeb\x88\x2d\xae\x82\x7a\xc0\x99\x46\xa4\x3c\x86\x77\x31\xf3\x7c\x92\x55\xcf\x93\x5d\x9b\x29\xef\xd7\xd9\x8b\x26\x45\x87\x8b\xe1\xd0\xfb\x8e\x15\xcd\x24\xc5\x7b\x91\xd6\x42\x9f\x4d\x0f\xa0\x83\x93\xc9\x77\xa2\x6b\x65\xd1\xe7\xc9\xae\xb2\x74\xa8\x4d\x33\x71\x63\xc4\x3c\x5b\xef\x24\x15\x9b\xa9\x9f\x5b\xeb\x5f\x4a\x42\x7d\x95\xec\x2c\x4f\xd9\xcc\x99\x83\xb1\x1d\xf5\x3a\x33\x9b\x85\x21\xb0\x4b\x75\xb3\x94\xe7\xfb\x83\x4b\x8e\xda\x6c\x31\xeb\xac\x7a\x26\x65\x41\x3e\x95\xd0\x0f\x5b\xb5\xa2\x4a\x84\xe4\x51\x0f\x7e\x96\x4b\x25\xe8\x9c\x84\xb1\x82\x83\xdd\xa5\x56\x1e\x74\xdb\x2a\xd4\xf5\x50\x1a\xb9\x84\xa1\x92\xc2\xb7\x16\x4d\x09\x84\x9d\x74\x78\x20\xd0\x6d\xb6\x2b\x47\x24\x5f\xb7\x8a\x39\x4b\x55\x77\xa5\xa4\xe4\x9f\x82\x5a\x7a\x26\x95\xd7\xc2\xe2\x48\x5e\xfc\x25\x26\x20\xe8\x4e\xd5\x5e\x24\x5f\xd0\x72\x19\x76\xe5\x89\x81\x68\x63\x05\xe1\xad\x7c\x0f\xf0\x4d\xa8\x04\x8a\xd5\x53\x1c\x40\x54\xdf\x48\x57\x7a\xb3\xe2\xe3\x31\x72\x5f\xf4\xea\xe7\x6f\xb6\xc2\x92\xaf\x90\x7a\x9a\x2c\x3d\x86\x71\xfa\xde\x9e\xe0\xc1\xff\x51\x82\x80\xe7\xc9\x6e\x97\xb1\xcb\x5f\x7e\xfe\x91\x80\x0f\x78\xd3\x88\x6b\x41\xcd\x61\x62\x15\xe5\xfd\x0b\x64\xb1\x0a\x5e\xbf\xcc\x7b\xf7\x99\xe4\xfa\x4c\xd0\x78\x13\x60\xc5\xdb\x53\x9b\xb2\xb8\x02\xd3\x8d\x30\x1c\xf2\x65\xb9\x42\x37\xe2\x2f\x19\xea\xd3\x94\x1a\x3f\x77\x11\x30\x8a\x57\xc9\xce\x0e\x4f\x2f\x48\x81\x1b\xad\x0a\xde\xe1\x70\x50\xcb\x04\x06\x7e\x3f\x95\xf4\x1d\x9c\x0c\xdd\xe6\x17\x16\x09\xfe\xfd\x78\xa7\x84\x94\xb8\xd2\xc4\xbe\x82\x45\xa2\xd4\x67\x29\x49\x00\xf6\x75\x6d\x28\x7f\xed\x6a\xce\x94\xc9\xf5\xfd\x24\xa3\xbd\x1c\xd9\x44\x51\xee\x53\xf4\x93\x57\x1a\x73\x9e\x6a\x7d\x52\x22\xd5\xb0\xa8\x51\x35\x0c\xa3\xbc\x91\x44\x9a\x09\x0d\xf3\x1e\xcf\x8f\xaf\x38\x19\xe2\x9c\x24\xae\x42\xcf\x28\xb3\x60\x01\xcd\x50\xa2\x1c\x57\xd8\x87\x46\x8a\xc4\x4d\x0f\xfa\xe8\xce\xdd\xa8\x54\x7c\xf2\x1c\xd0\x07\x6e\x84\xea\xfa\x0e\xc7\xac\xdd\xb4\x8b\x9e\xf4\x2f\x72\xbe\xd8\xe6\xf4\x21\xc9\x8b\xef\x92\x8a\x3e\x7a\xd0\x25\x93\x2d\x17\x25\xec\x9c\x88\x22\x6b\x26\x10\x5c\x40\xf9\x00\xc5\xd2\xb3\xec\xe4\x82\x17\x49\xb4\x67\xb4\x4a\x93\x1d\x8d\x28\x4b\x8b\x35\xfd\xe5\xe7\x67\x4f\x8b\xab\x5d\xc1\xc4\xbe\xa1\xaa\xab\x64\xbd\xee\x06\x1c\xec\x90\xb9\x7e\x7e\x68\x00\xb7\x08\xd6\x09\x4f\x62\xb1\x2e\x59\x0a\x95\x4e\xfe\x5e\x15\x6c\x2e\x07\x80\x95\x45\x92\x9e\x80\xd5\x4a\x5a\x8b\x06\xd7\x05\xf0\xe7\x82\x5d\x52\x16\x7b\xbe\xdb\xf3\x3f\x66\x39\x8d\xd0\x28\x10\xc5\x02\xe5\x7e\x46\x10\x8d\xf3\xb1\x39\x84\xd3\xca\x5e\xd4\xc1\x79\x79\xce\x02\x78\xaf\x49\xd4\x6f\xa3\xf2\x1e\x11\x3e\x0a\x4e\xee\x75\x9d\x9a\x60\xb8\x71\xef\x24\x10\x20\xb3\xfd\xf6\x29\x2b\x80\xe6\xe1\xc5\xc2\x47\x55\x37\x4b\xc9\xff\xe0\x4b\xac\x66\x6f\x51\x30\x2b\x88\x03\x5e\x88\x01\x42\xf7\x9a\x8b\xee\xa4\xcb\x64\xff\xba\x88\x31\x22\x51\x8b\xe8\x9f\xec\x91\xbe\x0a\x5a\x67\x7e\xd4\x20\x58\x1c\x6a\x4d\x55\xf1\x0e\x56\xdb\x81\x45\x25\xd3\xb8\x87\x60\xb6\xa4\xc1\xa7\xa5\x86\xfe\x2a\x36\x3f\xcd\xfe\x5f\x89\x09\x77\x78\x3b\x85\x53\x56\xde\x78\x66\x61\x1f\x07\xce\xb3\x86\x6c\xd3\xb6\x62\xa1\x8d\x67\x0f\xea\xfa\xd5\x8b\xd5\x3e\x45\xfd\x05\x0b\x26\x41\x2b\xd8\xc3\x2d\xf8\x0b\x58\xd6\x6e\x37\x6b\x2b\xef\x71\x1f\xb5\x80\x10\xa6\xc4\xad\xa0\x31\x04\x53\x84\x15\x2b\x68\xb3\x2b\xba\x5b\x38\x0f\x94\xce\xcf\x4f\x2e\x71\x70\x12\xa0\x98\xc2\xdd\x0e\x8b\xfc\x53\xc2\xfb\x15\x44\x7a\x04\x16\x27\xdd\x94\xd8\xc7\x52\xda\xbe\xcf\x91\x8b\xa1\xc7\xac\x1e\xad\xb5\x93\xb1\x18\x4e\x76\x7d\x57\x90\xf1\x6f\x1f\x39\x26\x1a\xee\xf6\x3f\x18\x27\xa1\xb8\x24\x33\x9c\x91\xd9\xbc\x21\x0e\x31\xa4\x8a\xf3\x7c\xa1\x80\x28\x28\x52\x3e\x0d\xdb\xbf\xc0\x49\x18\x06\x94\xc1\x8d\x50\xc9\x38\x2d\x8a\x53\xd0\xbf\xa4\xa3\xa4\x85\xa4\x46\x92\xf5\x5a\x1d\x12\xd1\x8d\x32\x81\xa1\x0e\x94\xa3\x04\x61\x0d\x8b\x75\x2c\x8d\x51\x4a\x6d\x39\x92\x8d\x67\x07\xac\x8d\x56\x54\xa6\xdf\x89\x67\x68\xd2\xc8\xd2\x86\xab\x87\x03\x8a\x7b\xc7\x12\x3c\x66\x85\x3a\xcb\xce\x82\x66\x5f\x33\xdd\xf2\xf4\x70\x7c\x90\x07\x84\x70\xc4\x49\x31\xb9\x02\x01\xe8\xc9\x39\x3b\xb9\x44\x68\x11\x95\x23\xeb\x8d\x9e\x91\x02\xe4\xaa\xcf\xcc\x29\x2b\xce\xd5\xcc\x3c\xd5\x1f\x33\x14\x67\x23\xf3\x09\x60\x86\x89\x00\xa0\xd5\x1b\x03\x92\xa8\x27\x74\x75\x7d\x53\x26\xd7\x55\x7c\x73\x38\xcc\x95\x97\xa5\x21\x21\xc9\x44\xc6\xef\x48\x86\x84\xa4\xd0\x5b\x5d\xa7\xf2\x61\x5e\x45\xaf\xb2\xb4\xc8\x0b\x08\xa5\xdb\xb1\x66\x94\xad\xbf\xc8\x8a\x9d\xf6\xaf\x18\x65\xeb\xee\xf5\x12\x19\xff\xda\xd5\xd2\xc4\xaf\x2e\xd7\x25\x84\x6e\xf0\x2f\xf6\x5c\x16\x54\x16\x42\x5d\x97\x09\xe4\x28\xc6\x32\x08\xe6\xdd\x52\xc7\xae\x6d\xc6\xd1\x0d\x1d\x11\x2e\xf0\x68\x49\x57\x87\xa6\x04\xb0\xfb\x25\x61\x43\x02\xa8\x82\x3d\x23\x15\x74\x1e\x1d\xf0\x8d\x4c\x8a\xef\x6b\x0b\x21\xec\x4a\x5e\xe2\xaf\xc1\x62\xe8\xa8\x5b\xfd\xbb\xcb\x75\xaa\x63\x86\xb4\x95\x6f\x34\x94\x81\xa7\x4d\x9c\x34\xd3\x3f\x78\xe2\x9f\xea\x93\xc4\x3f\x79\x9f\xf8\xa7\xf1\x2e\x05\x0c\xc6\x8d\x57\x02\xb1\x35\xc8\xcd\x01\xdf\x62\x1a\xa1\x4d\x67\x86\xc6\x70\xa7\x8b\x30\xee\x78\xd5\xac\x15\xd5\xc0\x89\x0e\x1c\xe3\xe9\x41\x92\xa6\x74\xc7\xab\x81\x6c\x19\x83\x49\x44\x30\xfa\xcb\xab\x97\x2f\x1c\x54\xa1\xc8\xf1\x63\x2c\xe3\xfe\x89\x61\x2f\xf9\x8a\x98\x30\x3a\x3d\x42\xa9\xb6\x11\x65\x9f\xe9\xae\x44\x4f\x87\x0b\x55\x06\x84\x3b\x65\x25\xf8\xdd\x07\x1b\xbe\x62\xe0\x14\x56\x57\x1a\x55\x6a\x5c\x26\xf7\x36\xd3\x26\x95\xdc\xc6\x0f\xf3\x4d\x28\x61\xe3\x5d\x27\x25\x6b\x79\x8f\x50\x02\x62\x01\x2c\xb8\xbf\x0e\xd6\xfd\xb9\x0c\x82\x01\x4e\x60\x99\x13\xbf\x8a\x42\x43\xd2\xf3\x31\xd6\xbc\x7a\x1f\xc9\xa7\x1f\x47\x3b\x1f\x3e\x77\xbf\xcd\x2a\x4d\xd5\xb5\x9c\x86\x48\x9e\xa3\x79\x5d\x0b\x88\xf9\xa8\x65\xad\x65\x5c\x8d\x2b\x64\xd1\xa6\x86\x88\x3b\x87\x84\x0a\x7a\xeb\xb1\x3f\x7c\x44\x20\x14\x00\x97\xe2\x94\x82\xd1\x63\x3d\x6b\x4b\x58\xdf\xf9\x83\x85\xab\x58\x06\x3f\xb4\x9d\x07\x5d\xf0\x0a\x0e\x6f\x4c\x5f\x5e\x33\x63\xd2\x56\x20\xe3\x6f\x62\x59\xac\x70\x42\xd2\x28\x43\x73\x1b\x6a\x9e\x14\x6e\x80\x19\x92\x2c\x04\x41\x27\x97\x49\x30\x31\x80\x28\x32\x82\x06\x24\x66\x71\xe6\x9a\x8f\x81\x08\x41\xe5\xf4\xfa\xa6\x50\x8e\xad\x11\x8a\x23\xb7\x27\x63\xbf\x26\xfd\x6c\x43\x50\x4a\x2c\x9b\xb2\x0f\x5a\x0f\x72\x51\x1b\xfe\x62\xba\x62\x35\x6a\x08\xb7\x1c\x2c\x1d\x81\xb3\xba\x26\x0a\xd6\x8a\xf9\xab\xb0\xcb\xf5\xd9\xa4\x5f\x66\x38\xab\xd9\x74\x25\xf4\xcf\x77\x05\x2d\xfa\x3d\x29\x4a\xf7\xaf\x99\x4b\xd2\x3a\x8a\x7d\xa8\xfe\xbf\xe1\xdd\x6e\x7e\x1c\x52\x19\xd2\x76\x76\x62\x87\x46\xc8\xf7\x04\xc6\x41\x30\x74\x6c\x42\xae\xf8\x4a\xf7\xb1\xa6\xef\x15\x42\x74\x40\x50\x79\x0c\x1a\xcd\x56\x07\x2d\x6f\xff\x3d\xda\x1f\xab\xf6\x2f\xda\x88\x76\x27\x0c\x32\xbe\x6a\xf9\x24\x69\xe1\xcf\x5d\x10\xc3\x69\x80\x17\xe2\xc2\x69\x73\x1f\x37\x07\xff\xda\x81\x39\x69\x00\x34\x4e\x08\x0e\x1e\xc6\xe4\x79\x20\xee\x42\xf7\x0e\x59\xf2\xd5\x9c\xb5\x37\x3c\x85\xa8\x83\x7d\x6e\x2c\x5a\x56\xb2\x54\x8d\x73\xa1\x7f\x44\x82\x59\x43\x28\x6e\x5b\xb4\x9a\x92\xb2\x07\x5b\x1c\xbe\x6d\x94\x23\xb1\x2f\x92\xeb\x4e\x2b\xc9\xc8\x7b\x67\x81\x44\x39\x05\x37\x2c\xc5\xbf\xa0\x1c\x72\x89\x0d\xb3\x73\x80\x69\xd3\x4e\x2e\xe6\x48\x9c\xf8\xea\xb7\xdb\x71\xb7\x0b\x3b\xd7\xcb\xae\xe3\x49\x03\xb7\xd2\x61\xd1\x31\xad\xeb\x8e\x1a\xfc\x9a\x52\x06\xc8\xab\xee\xee\x67\xac\xca\x1a\xef\x37\x6d\x5c\x04\x25\x86\x32\x12\x10\xef\xc5\xa6\xc7\x44\x69\x57\x66\x6d\xd6\x4b\xba\x68\xa7\xe0\xa2\x5d\x70\x34\x82\xb2\x58\x16\xab\x45\xc4\xc8\x0c\x97\x23\x32\x43\x31\xb3\xbe\x84\x1b\xc4\x38\x3b\xb8\x63\xfd\xee\x43\x5f\x90\x75\xb7\xdb\x39\xb0\xa2\xb0\xd5\x10\xf7\x09\x15\x39\x59\x93\x6b\x2c\x98\xe9\xe4\xba\x28\xd7\x1e\x6d\x63\x67\x6d\x7d\x2e\xc9\x52\x52\x26\x26\xc5\x12\x5d\xad\x33\x64\x4f\xa2\x16\x9d\x9e\x7f\x96\xa6\xbe\xcf\xce\xdf\x25\x97\xe3\x87\x5f\xb7\x95\xf4\x0d\x9d\x7c\x47\x44\x85\xcf\xd6\xd0\x2a\x53\x01\xff\x21\x1c\x10\x7c\x5f\x46\x45\xeb\x58\x3a\xfa\xef\x9a\x20\xde\x7b\xd2\x30\x9d\x61\xd2\x7e\x31\x91\x46\xda\xc6\xe2\xb2\x52\x86\x46\xb7\x51\xef\x0d\xd3\x5a\x42\x88\x7c\x1f\x1a\x86\x10\xf8\x52\x3f\xe9\x3a\x9f\x54\x69\x55\x7d\x75\x92\x79\x2f\xba\x16\xee\x53\xe9\x73\xf6\x5b\xb1\x1f\xf0\x32\xa3\x6b\x19\x9a\xa8\xac\xe8\xe0\x95\xa0\xf0\xc1\xf2\x0a\xec\x4a\x79\xc2\xd6\x49\xb9\x06\xe3\x65\x09\xc4\xf9\x80\x97\x1f\x06\xc9\x65\x92\x31\x5b\x4e\x59\x94\x8e\x45\x9f\xaa\x5c\x10\x8b\x31\x24\x55\xf5\xe9\x43\x48\xaa\xea\x9f\x18\x42\xe2\x0f\x21\xa7\x6d\x30\x84\x61\x74\xeb\x28\x7e\xa4\xff\xcc\x28\x44\xaf\x03\x8b\x75\x95\x7d\x03\x0d\x16\x37\x9f\xca\x0e\xb7\xb6\x99\xc4\xde\xf8\xc1\x03\x6c\xb1\x3b\x7e\x38\x6d\xec\xa2\x87\x1d\x31\x1a\xee\x68\xd9\x92\xf7\x84\x10\x50\xe9\xbc\x78\x4b\x59\xf6\x91\xca\x2d\x95\x37\xe3\x0a\xe0\x44\xa7\x59\x8f\x52\xb8\xd2\x69\x60\x9c\x84\x10\x4e\x4d\x82\x2c\x31\x77\x5d\x88\x7c\xc2\x56\xec\x7d\xe2\xa9\x2c\x25\xe4\x23\x36\xea\x98\x43\x78\x0f\x1d\x94\x3e\x40\x9a\x63\x5b\x8d\xab\xe2\x25\x77\x49\x4a\xad\xd0\xd2\x48\x9e\xcc\xb3\x14\xf9\xc8\xf8\xb5\x82\x87\x51\x66\x81\x96\x54\xbd\xfb\xba\x81\x01\xc4\x14\xc3\xa1\xdf\x94\xf0\xcc\x0e\x87\x63\xbc\x6f\xa3\xfd\x96\x97\x06\x6e\x72\xa2\x29\x2e\xec\xf3\x06\x3b\x73\xb8\xe8\x01\x47\x3a\x6f\x7a\xf5\x86\xd2\xb4\x33\xa1\x6c\xfd\x72\x23\xe5\xac\x73\x54\x5d\x67\x60\xf4\x4c\x49\xa3\x94\x20\x59\x61\x54\x11\x42\xcb\xe9\x0a\xdd\xa4\x49\x45\x03\x00\x57\x10\x3b\xa0\x1b\x11\xba\x9c\xad\xe6\xca\xfd\xa9\x28\x33\x57\xf9\x9b\x92\xd2\x57\x1a\x9e\x82\x13\x70\xca\x1c\x54\x19\xca\xd6\x8d\x1c\xe3\x5e\x4a\x42\x5f\x7e\x35\xca\x24\x7c\x2c\xee\x3f\x55\x46\xba\xe1\x6e\x14\xb9\xd1\x1d\x5c\xed\xf8\x87\x9f\xbd\x7c\x8d\x5d\x52\xea\xcc\xb7\xb4\x14\x7c\xbe\x1e\x8e\x12\x40\x83\x33\x01\xe8\xbb\xe3\xa2\xf7\x6e\x01\x1d\xe1\x20\xe3\x11\xc7\x74\x79\xba\xc2\x74\x79\x7f\x85\x8c\x7c\x5e\x34\xaa\x5e\x58\xd2\xe5\x83\x95\x46\x0b\xba\x7c\xb8\x3a\xe8\x18\xfa\xcb\xd9\x4a\xbd\xe3\x3d\xc5\xe3\x53\xa4\xd4\x1d\xd5\xbd\xaf\x94\xaa\x83\x21\x24\x5d\xb4\x01\xa2\x4a\x0a\x2a\xa7\x1b\x4e\x98\xfe\x2a\xb3\xcb\x2d\xb0\xe8\xe6\xc5\x51\x09\x54\x2b\x88\x78\xff\x16\x9d\x57\xf7\x50\xb4\xfc\xdb\xea\x1e\xf8\x38\x43\xf0\xfd\xd5\x09\x9a\xab\x56\x4b\x31\x6c\xb7\xdd\x12\x6c\x34\xdd\xa6\xcb\xe5\x7d\xc9\x0b\x18\x88\xf6\x00\x26\xbd\x03\x60\xb4\x3f\x7a\x3b\x1b\x45\x0f\x9a\x8d\x68\xb6\x2b\x68\xe8\xc4\x22\xf5\x10\x86\xc3\x19\x66\x10\xae\x1a\x97\xe2\x77\x21\x7f\x67\x64\xb9\xc2\x89\xf8\x53\x11\x3a\xaf\xe6\x52\x8d\x0f\x0f\x3e\x70\x22\x4d\x79\x2a\x84\xa5\x25\x1d\xab\xeb\x60\x09\x3f\x50\x51\xd7\x51\x41\x2a\x78\x6e\x05\x61\xe3\x64\x81\x45\x80\x82\x38\x58\x05\x96\x4c\x83\x40\x57\xda\x24\x00\x8c\x7c\xe6\xb2\x85\x1b\x70\xae\xac\x76\x37\x9c\xb8\x30\x1d\x71\xce\x46\x89\xc2\xc0\x83\x28\x7f\x23\xcb\xb7\x4a\x02\x2e\xcb\x30\x5e\xc1\x41\xb5\xd9\xd8\x9a\x17\x49\xfa\x36\x4a\x26\xbb\x62\x17\x81\xbb\xc0\xe1\x54\xb5\x1b\xc4\x50\x01\xde\x1a\x0f\xa7\x48\x3e\x0c\x61\x62\xa8\xcb\xcc\x3a\x8c\x83\x27\xbc\x50\x19\xbb\xd3\x80\x38\x61\x02\x78\x08\xcd\xab\x23\xa7\xc1\x41\xf3\x56\x9d\x27\x0a\xd0\xa2\x60\x63\xd8\x54\x31\xee\x59\x9a\x17\x15\x5d\x7f\x57\x26\xe9\x5b\xca\xa3\x02\x61\x1e\x86\xa5\x5c\xcb\x79\x62\x47\xa1\x0e\x19\x42\x48\x54\x91\x64\x99\xd8\x91\x8b\x73\xa8\xae\x5d\x13\x9a\x4a\x47\x03\xe9\x81\xce\xdc\x85\xbe\x8a\xab\x2d\x07\x03\x8f\x78\xfe\x5a\x94\x6b\x91\x21\xb0\xb0\x89\xd1\x54\x36\x31\xbf\x1d\xb3\xa7\x2b\x89\xdc\xd3\x95\xc2\x6f\x0f\xa3\x9d\xb3\xf2\x09\x5b\xeb\x48\x00\x7f\x2c\x8b\xab\x1f\xe0\xf0\x33\xc2\xdd\x88\xe3\x40\xef\x8c\xc0\xf8\x00\xf7\x36\x82\x98\x48\xcf\xb6\x2b\xbb\x06\xa7\xbd\x3b\x17\x84\x2e\x6d\x08\x39\x29\xf8\x90\x18\x5b\x2c\xa7\x2b\xfd\x00\xde\xb9\xfc\xa6\x98\x6a\xfc\x2a\x96\x0f\x56\x8b\x8e\xc3\xac\x70\x0e\xb3\x42\x1c\x66\x71\x67\xa1\x53\xa7\xd0\xfd\xd5\x61\x1e\xc0\xc9\x3d\x24\x04\xe0\x35\x5d\xcd\xd1\xcc\x89\x8d\x68\x70\xc5\x2e\x0f\x75\x20\x2a\xb8\xcc\x11\xa1\x13\xe9\xb4\x1d\x2d\xd5\x54\xb8\xc7\x75\x99\xc3\x56\xae\x8b\x39\x6f\x61\x79\xa4\xb4\xa4\xd8\xc1\x51\xa9\x85\x3d\x5a\xd2\xa3\x87\x24\xf6\x1e\x6c\xa5\xac\xae\x2d\x36\x66\x3e\xea\x65\xca\xc2\x47\xb6\xe7\x8f\xea\x20\x47\xd5\x38\xd9\xdc\x0e\x4d\x17\x60\x38\xa4\x6a\xca\x8b\xd6\xaf\x37\x02\x7b\x79\xbd\xc1\x01\x78\x62\x8f\xc3\xb2\x9d\x9c\x5f\xeb\x0b\x62\x39\x5b\xa1\x0e\xe0\x2d\x59\x0b\x21\x65\x83\x87\xe0\x0d\x48\x40\x60\xf0\xd0\x58\x70\xcf\x4b\xa8\xeb\xa8\x01\x76\x93\xa5\x41\x28\xff\x59\x07\x14\xad\x8e\xfa\x51\xff\x95\x58\x28\x83\xfc\xbb\x92\xa6\x5b\x9a\xbe\x7d\x0e\x8e\x54\x3d\x9a\x41\x1f\xf4\x8d\x10\x88\xd3\x79\x32\x1e\x4b\x28\x0e\xb3\x2b\x41\x5d\x27\xca\xa6\x4e\xdc\xa6\xc9\x4a\x2c\xc2\x84\x17\x3f\x16\xd7\xb4\x7c\x9a\x08\x36\x4c\xc0\xd5\x94\xd4\x46\x69\xea\x9c\x93\x9c\xea\x1f\xc1\x0a\x07\x27\x68\x1e\x0c\x9c\x46\x87\x70\x0e\x39\x53\xb1\x5b\x77\x54\xc1\x79\x27\x67\x6d\x1b\xaf\xdc\x73\xde\x1b\x1d\xeb\x18\x96\x9e\x61\x4a\xa8\x75\xbc\x9b\x8b\x8b\x70\x4f\x92\xf9\xfe\x6c\x3a\xdf\xeb\x18\xc6\x3b\x92\x2e\xf7\x1a\x43\xc5\xd9\x9d\x2b\x13\x6c\x6b\x35\x31\x0c\x50\x18\x2a\x9c\x1d\x12\xb2\x73\x1c\x07\xc3\x7e\x5e\xce\x56\xa3\xfc\x70\xa4\x6e\xe4\x83\x09\xb7\x66\x97\x63\x4a\x52\xb8\x05\x6c\x37\x12\x1d\xcd\xee\x50\x29\xb2\xef\x83\x7b\xbe\xc9\x77\xea\xe2\x70\x53\xd6\xe9\xbe\x77\xec\x20\x36\xf6\x8c\x3d\x08\x01\xa2\x44\xde\x3a\xac\xad\xb5\x80\x38\x0b\x13\xe7\xa9\x35\x78\xb2\x73\x08\xac\x19\xc2\x10\x07\xb7\xd4\x5c\xb5\xdc\x32\xe2\x63\xfd\x44\x52\x92\xa5\x39\x7c\xe1\x14\x2d\x1d\xe2\xc5\x89\x71\x0b\xb1\xa7\x87\x33\x5c\x91\xe5\xea\x38\x8d\x6d\xe9\x83\x3b\x90\xd9\x65\x17\xd9\xe8\x1e\x63\x70\x86\x35\x8f\xeb\x26\x61\x41\xa1\xad\xcc\xcf\x39\x38\x39\x9b\xa8\x32\x17\xb4\xc4\x41\x4e\xaa\x25\x23\x8e\x63\xd9\x39\x37\x98\x04\x92\x32\x71\x56\x8b\x42\xe3\x31\x83\xbc\xa8\x63\xa8\xdc\xb9\x14\xb8\xb8\x14\x2c\x61\x6d\x08\xf0\x03\x74\xee\xc6\x32\xeb\x06\x1c\xba\x29\xec\xf8\x0f\xe5\xa7\xdc\xaa\x15\xc2\x7a\x22\x8b\xa8\x74\x64\x91\x2f\x04\x36\xdc\x76\x2c\x55\xce\x9d\x5c\xe2\x60\x97\x94\xc9\x55\x15\xe0\x4a\xfa\x39\xa4\xa4\x5a\x3a\x50\xc2\x9d\x0b\xd6\xa0\xf3\x3d\x5e\xd3\x9f\x09\x2e\x9b\xd7\x04\x42\x71\x7b\xcc\x41\x20\x3d\x03\x24\x57\x15\x04\x14\xce\x00\xfe\x9e\xc7\x7b\x43\x2a\x48\xfd\xa2\x17\xb1\x46\xb3\xca\xaa\x88\xf6\xa0\xde\x4e\xb3\x64\x98\x97\xe7\x9b\x65\x10\x1f\xff\x50\x2f\xef\xec\xd6\x96\x0a\x80\x8e\x66\x21\xa3\xae\x83\x00\x8d\x1c\x30\x75\xb2\xe7\xba\x9e\x94\x54\x2f\xfc\xc6\xee\xba\x6f\x3c\x49\x80\xdf\xa2\x32\xe3\xdb\x33\xfa\x7e\x47\x53\x4e\xd7\x4f\x05\xc9\xaa\x8e\x1d\xc5\x1c\xb6\x38\x74\xbf\x89\x26\xb5\x9b\x17\xe9\xdb\xc8\xa7\xe5\x7e\x17\xe8\xff\x33\xb0\x3e\x80\xaf\x28\x87\x5b\x6f\x05\xac\x69\xf2\xfb\x1d\xf3\xf1\xa4\xe0\x5e\xce\xb2\x77\xa2\xfa\x94\xd1\x71\xb4\xb8\x32\x7e\x1f\xaa\xe1\x16\xd7\xcc\x8c\xc9\xde\xb4\x6e\x2a\xe9\x47\x19\x65\x48\xcc\x32\xde\x52\xde\xfb\xeb\xa6\x4e\x22\x6a\xe4\x39\xae\x1c\xc7\x7a\x45\x3a\x60\x29\xe7\xb1\x92\x97\x03\xf6\xfd\x8a\x1f\x41\x5f\xf7\x6e\xa4\x6a\x96\x2d\xaa\x7b\x86\xba\x94\x3d\xde\x8b\x33\xf0\xe2\x9a\xe0\xca\x04\xee\xc1\xa9\x68\x3e\x17\x57\xf5\x9e\x9c\xfc\x2d\x5a\x4e\xea\xff\xb3\x42\x8b\x68\x79\x7e\xbd\x42\xa3\x93\x0c\xe2\x2d\xed\x1e\x57\xf3\xdd\x88\xcc\x90\x3b\x8c\xa8\x20\x51\x49\xd8\x72\xb7\x42\x8a\xb1\x82\x65\x30\x03\x5c\xb8\xd4\x6e\xe1\x52\xc2\x45\x18\xee\x04\xf3\x35\x9e\x2d\x72\x32\x9c\xc5\xe9\x08\x04\x06\x71\x94\x88\xe6\xc4\xa1\x98\x89\x1f\xa3\xd9\x0a\x5b\x1a\x21\x91\x34\x82\xf9\xce\xe0\x7b\x2f\xe9\xd7\x44\xd2\xaf\xea\x2b\x13\x5f\x0b\xdd\xaa\xe8\x42\x3a\x7a\xca\x55\x5c\x28\x08\x40\xbf\xde\xa7\x9e\x05\xb6\xeb\xac\x77\xc4\x05\x89\x2b\x6e\x7a\x34\x97\x4b\xb4\xe4\x2b\xa2\xfc\x3f\xa7\xb8\x4c\xae\xe3\xcd\xe1\x00\x8a\xb6\x14\x2c\x29\x7b\x2e\x92\x6e\x99\x03\xf6\x88\x79\x9f\x63\xe5\x3e\xa7\xd5\xe6\x58\x39\x9a\x23\x41\xf2\x1b\x6a\x8c\x19\xaf\xc6\xbd\x23\x81\x6b\xe9\xf3\xc6\x32\xed\x1b\x42\x83\x8d\x6a\x8f\xe1\x28\x08\xfc\x4e\x6d\x9f\xcd\xc9\x0b\x8a\xc1\x99\x2b\xf7\x6c\x18\x2c\xd9\xdd\xd0\xb5\x58\x2f\x49\xe2\xda\x03\xc5\x3c\x75\x15\xf3\x62\xf0\xcb\x72\xe5\x8c\x9b\xea\x08\x39\x1c\x9b\x01\x70\x88\xc6\x0e\x6a\xc1\xc6\x89\xe6\x40\x0f\x97\xb8\x20\x10\x65\x7d\x9e\xd9\x4e\xb2\xd1\x48\x52\x6d\x91\xe2\x29\x00\x96\x99\xdc\x28\x61\x18\x15\x62\x2f\x61\xf9\xf6\x52\x1c\x4c\xc5\x58\x7c\x4f\x95\x89\x49\xec\x8a\x82\xa0\x19\xcd\xb6\x95\x72\x0f\xec\xca\xe2\x32\x53\x09\xb3\x15\x4a\x0b\xc6\x33\xb6\x37\x42\xe1\x4c\xd2\x4c\xeb\x62\x7f\x91\xd3\xa7\x40\xf8\x72\x74\x28\x09\x37\xa1\x3b\xc5\xb4\x1a\xf2\x94\xc6\x5d\x6f\x9e\xb4\xbb\x86\x4f\xc1\x2f\xaa\xce\xe0\x42\x56\x0a\x1c\xd2\x56\xb6\x69\x58\xc7\x3b\xb6\x27\x7d\xa1\xc0\xfc\x5a\x92\x10\xd9\xa2\x77\x95\xde\xb1\x55\x5d\x67\x70\x68\x8f\xd0\xb9\x57\x7b\x5e\x00\x35\x08\x02\xa9\x8a\xbd\x1d\x24\xa2\xc5\x40\xa0\x4f\xc6\x28\xa6\xda\x01\x31\x88\x5d\xec\x4a\xdc\x69\x02\xdf\x43\xf9\x01\x20\x5e\x7b\x02\x0e\xab\xd1\xf4\xb5\xd3\xd3\xde\x13\xa9\x64\x01\x35\x54\xb1\xe7\x03\xd1\x42\x80\x39\x08\x6d\x75\xbb\x3d\x3c\xb4\x0b\x22\xd8\x0c\x47\xcb\xf8\xaa\x6c\xc3\x84\x9b\x27\x70\x5e\x68\x5f\x69\x34\x33\x9e\xcd\x8b\x33\x32\xf5\x4f\x1e\xc1\x84\x17\xb0\x5b\xea\xfa\x14\x22\xf9\x8a\x0d\x83\xe6\xc5\x78\x8c\x7a\x57\x42\x8e\x6a\x60\xee\xc3\x00\x33\x31\x43\x06\x33\x6c\xa9\xaf\x8f\xf8\xa2\xfb\xe4\x80\x15\xa0\xb0\x8a\x1f\x3e\x74\x63\x54\x60\x57\x0b\x16\x3f\xfc\xf6\xb0\xc2\x0f\x3f\x3f\x62\xf7\xba\x47\xdd\xb6\xd6\x5e\x5b\xb5\xcb\x03\xd0\xb7\xad\x3b\xfd\xd6\xad\x5b\x5a\xb8\x4a\xa7\x39\x5a\xb8\x54\xa7\xbd\xa3\x6c\x2d\x1b\xcc\x4d\x37\xca\x93\x1d\xde\xeb\x94\x3c\xab\xa0\xa5\x9d\x4e\xd0\xcd\x6c\x4c\x82\x54\xe6\x59\xdd\xdd\xfa\xd3\x9d\xdf\x6d\xbf\x60\xc4\x4c\xd5\xb3\x8c\xc0\xa5\x2f\xa0\x46\xfc\x26\x75\x4a\x73\x60\x5a\x11\x6e\x46\xa7\x39\x6c\xb5\x93\x9a\xc6\xb5\xa3\xc7\xab\xcf\x13\x46\x74\xe0\x70\x65\x5c\x69\xa3\x0a\x98\x0b\xd3\xf7\xb6\x44\x28\x66\x0d\x5f\x55\x24\xf2\xfa\x47\xc6\x47\x95\x7c\xa7\x5d\xea\x96\xba\xdd\xf4\x31\x1c\xa8\xe6\x02\x7c\xd3\xed\xb6\xa1\xac\x6b\x41\xc7\xc9\x87\xf8\x07\xc7\x41\x91\x4f\x45\x96\xa6\xc2\x36\x5a\xb2\xa8\x44\x2b\xa4\x0b\x2a\x6f\x63\xec\x80\xb7\xce\xb3\x73\xa3\xe1\xc2\x5b\xa5\x5e\xcc\x9d\x14\x89\x5e\x24\x75\x92\x04\x32\x91\xbd\x93\xd0\xa5\x41\x73\xec\x6c\x13\xcf\xce\x76\x3b\x49\x78\x4b\xad\xe4\x94\xae\x1a\xa5\x5b\xb2\x70\xa7\x6c\xd9\x28\xdb\x92\x17\x39\x65\x77\xcd\xb2\x9e\xc9\x94\x5f\x76\xe3\x96\x85\xad\x7d\x41\xb6\xce\xa1\x74\xf1\x05\x0f\x25\xd8\x9a\xf1\x83\x47\x2d\x57\x18\xf6\xb0\x88\x1f\x1e\x3d\xbe\x5a\x5e\x32\xd4\x91\x10\x3f\x9a\x8a\xd3\xac\x23\x02\xcf\x67\x1b\xd3\x37\x9d\x24\x54\xae\xe7\x6a\x65\x3b\xbf\xa9\x7e\x0f\x93\x79\xac\x1d\x09\xe7\x45\xe2\xbe\x4c\xb3\x22\x3c\x78\x92\xaf\xe4\xbc\x49\xc9\xff\x9a\xf1\xad\xe4\xbc\xec\xb3\x2c\x2c\x5f\x41\x06\xda\x19\x0e\x3c\x70\x5d\x70\xe3\xce\x51\x85\xf1\xd1\xa6\x65\xa2\xab\xe7\xc9\x4e\x99\x9b\x80\xfb\x5e\xcd\xcd\x49\x75\x2a\x3a\xaa\xf1\x57\xef\x62\x7b\x5d\x23\xaa\xfc\xa7\x49\xba\xa5\xda\x25\x82\x97\x78\xeb\xd3\x5e\x33\x14\xed\xaa\xc0\xab\x0e\x36\xed\xf6\x11\x7c\xd7\xf3\x5a\xbf\xd3\xa8\xfd\x46\xf8\x78\xbe\x15\x2d\x4a\x3a\x5f\x81\xbd\xd3\x86\x71\x38\x84\xd5\xaf\xf6\x17\x15\x2f\xc1\x8b\xbf\x52\xab\x8a\x13\x5e\x54\xf7\x17\xb6\x83\x58\xa1\xe6\x29\xd3\xc9\xf9\xbd\xf3\xaa\xeb\xc1\x67\x34\xb9\x87\xce\xab\x7b\xe7\xf7\xce\x4f\x4e\x10\x08\x2f\x1b\x18\x40\x38\x88\xe6\xa5\x43\x13\xa5\x6a\x2b\xd6\xb4\xe9\xd0\xc1\x8a\x9a\x49\xf7\xc3\x59\x1c\x38\x4e\x4e\x35\xb6\x41\x48\x47\xed\x4f\x93\xb6\xdf\xee\xea\xc9\x9b\x60\xbc\xca\x02\xa0\xd9\xc3\xb9\x7c\x9b\x9b\x6e\xc5\x71\xc0\xc9\x9e\x6f\xc6\x8b\x6f\xf4\x53\x5d\xf3\x2a\xb2\xae\x7b\x6b\x36\x8b\x9a\x87\x41\xc4\x8c\x41\xc6\x65\x87\xf7\x58\xcf\x05\x54\x4d\xc4\x09\xf3\x50\x99\x63\xf3\x3c\xd9\xb1\x4d\xd4\x2f\x95\x13\x5e\x5c\x44\x26\x9c\x8f\x59\x9a\x9e\x01\x45\xcb\xbf\xe1\xd5\x08\xe1\x13\x60\x42\x3b\xe2\xcf\xa9\x78\x05\x82\x2e\xb4\xbe\x39\xe1\xfd\x73\xc6\x2e\x07\xc1\xa8\x40\x1a\x45\xbc\xf7\xb3\xc6\xed\x34\xd0\x09\x5e\x4c\x25\x99\xd1\x15\x89\x52\x03\xa3\x2f\xf2\x92\x35\x17\x56\x44\x31\x0b\x43\x73\x87\x4d\xe8\xfb\xac\xe2\xd5\xab\x0f\x2c\xed\x4e\x8d\x2c\x0e\x24\xce\xfb\xcf\x04\x84\x8a\xb2\x00\x0e\xc4\x92\x7e\xe3\xc1\x55\xe1\x64\x17\x6c\x12\xc1\x64\xf0\x62\x20\x66\x3f\xd0\x6f\x7b\x1d\x38\xc5\x83\x60\xc4\xdc\x97\xda\xa0\xba\x77\x4d\x9c\x8f\x9c\x21\x7a\xac\xc7\x9e\x6f\x02\x3e\xd8\xd7\xfc\xdc\x1d\xf7\xfc\x0e\x7d\x99\x86\x6c\x98\xb0\x46\x03\x5b\xf3\x88\x8d\x1b\xe8\x35\xde\x1d\xf1\x4e\xd8\x58\xbc\xe9\x00\xcc\x60\x53\x94\x57\x09\x87\x80\x1b\x2d\xf8\xd8\x4b\xc3\x7b\x36\xe7\x9e\x07\xcd\xc3\xc3\x8e\xd5\x49\x73\x3d\x58\xb6\x7c\xb5\x40\x30\x90\xd2\x79\xe9\x0b\x11\x46\xda\x4f\x8b\x29\xc2\x25\x72\x4c\xce\x3a\x5e\x1f\x97\x08\x0f\xa3\x61\x17\xc6\xd5\x75\x67\x72\x54\x22\xe4\xa2\xa8\x87\x83\xe5\x11\x1c\x54\x8e\x19\xfc\x8d\xd6\x6b\x09\xdf\xb1\xc5\xe0\xad\xa4\x38\x92\xab\xba\xee\xca\x7d\xa3\xb3\xd1\xe7\x59\x2b\x1f\x7b\x55\xb8\xa9\xe2\xd3\x23\x4f\x0b\x1f\x76\xc4\x40\xf9\x0c\x6a\x08\x67\x24\x2a\x64\x54\x91\x3c\xf9\xf8\x61\x6c\xdc\x89\x87\x61\xe1\x12\x38\x85\x25\x70\x8a\x03\x4e\xfa\x0d\x1c\x1b\x8f\x6c\x96\x2b\x85\x0c\x8a\x89\x20\xc1\xd7\x93\xe9\xe4\xf4\x6b\xa5\x1f\x51\x7e\x14\x9b\xb1\xbc\xe9\x51\x7a\x64\x5f\x1d\x79\xd9\xe1\x36\xa8\x5d\xb8\xa6\x05\x4b\x13\x1e\x35\x3a\x59\xd2\x15\xb2\xaf\x35\xda\x2c\x88\x33\x33\xee\xbe\x98\x52\x1c\x16\xac\xa1\x13\xb5\xad\x75\x22\x74\x90\x4b\x6e\x60\x8d\x03\xe6\x87\x1e\x71\x70\xc7\x3b\xc2\xa9\x76\x9f\xe2\xbb\xa5\x0d\x43\x65\x49\x29\xc3\x0f\x79\x5e\x15\x6f\x33\xdc\xee\x7a\x65\xd9\xf2\xb1\x7b\x9d\x94\xcc\xff\x8a\x82\xdf\x8a\xfd\x60\x9d\xad\xe1\x55\x65\x45\xf9\x20\x61\x1f\xb4\x43\x4c\xac\x6c\x8c\xf1\xa0\x28\x07\xce\x68\x26\x83\x9f\xb3\xcb\x2d\x1f\xb0\xe2\x1a\x1b\x07\xc3\xeb\x82\x56\xa2\x91\x6d\xc6\x2e\x27\x83\x9f\xb2\xf4\xad\x6e\x46\x9c\x77\x83\x0f\xe0\x94\x38\xa9\xe8\x40\x70\xe4\x9c\xef\xaa\xf8\xe4\xe4\xfa\xfa\x5a\xb3\xab\x62\xe2\xbc\x3a\x01\xc7\xd7\x7b\xb0\x93\xa2\x57\x83\x8c\x69\x93\x67\xe5\x73\x7e\xf2\xf7\x6a\x12\x48\x96\xda\x8f\xef\x81\x95\x17\x5d\xcc\xbb\x62\x41\x1b\x5a\x6d\xb9\xc2\x82\x49\x2e\x1a\x9e\x79\x18\x02\x11\xec\xa6\x28\x23\x46\x8a\x05\x8b\xd9\x11\xcf\x3c\x89\x38\x6e\x0b\xb8\xc6\xb3\x33\xa3\x08\x51\x96\x0e\x09\x61\xcb\xcc\xf3\xcc\x93\x11\xd6\xe5\x99\x27\x21\x99\xe3\x99\xa7\x22\xd0\x6a\xa5\xa1\x01\x2e\xf8\xcc\x17\xf2\x1d\xd2\x57\xa8\x29\x72\x30\x88\x84\x10\x27\x5c\xef\x10\x9b\x6a\x0c\x07\xbb\xe8\x8a\x0a\x71\x6d\x92\x68\x42\xf2\x7a\xaf\x78\x2b\x54\xd7\xc3\x4a\x7b\x80\x1f\x3a\x0f\xb4\x5b\xaf\x78\xab\x51\x30\xc8\x00\x0d\x06\x49\xc3\x2f\xb5\x0a\xda\x79\xd4\x03\x77\xef\xa3\x60\xf9\xe6\x83\x56\x83\x14\xee\xb2\xc1\x05\x15\x48\xb2\x1e\x24\x95\x46\xb2\xc9\xe0\x99\x0c\x84\x83\x07\xbb\x9c\x0a\x3c\xdb\x03\xae\x19\xb7\xd5\xb2\x09\x65\xcd\xee\x3e\x18\x51\xae\xd9\x2b\xd1\x58\xb1\xe7\xe2\x86\x85\x68\xca\x80\xb1\x26\xe8\xce\x9e\x31\x5a\x0e\xd6\x45\x0a\x27\x04\x5c\xa6\xe0\xfd\xba\xf7\x81\x4b\xf2\x59\x96\xf7\xee\xb1\x1d\x3f\x78\xd8\xb4\xb8\xff\xec\x60\x4e\x18\xb4\x6d\x26\xf2\x04\x84\x08\x3a\x1a\x72\xca\x72\xca\xd9\xbf\x73\xec\x08\x69\x9c\x75\xbb\x3b\x43\x23\xb5\x30\xee\x0c\x95\x87\x51\xcf\xc1\x9f\xef\xc8\xd0\x46\x3b\x72\x1e\x37\x83\x63\x11\x15\xfd\xdf\x2a\x71\x92\xae\xbb\x2d\xb9\x5b\x18\x82\xa4\xfd\xc2\xdb\xb9\x78\x9d\xc7\xe7\x6a\x3b\x2b\x6f\x50\xd6\xf1\xb0\x62\x87\x6d\x82\x2f\x14\x04\xcd\xb5\xf6\xce\x7e\xac\x60\xb7\x2f\x5e\x31\x1c\xef\x8d\xa6\x86\x9c\x76\x49\x88\x99\x9e\xc3\xb1\x30\x0d\xa6\xd6\x26\xcb\x39\x2d\x3b\x5f\x33\x6a\xcc\x24\x5a\x07\x2c\x5d\x4f\x78\xee\x79\xef\xe2\xf2\x16\x5c\xe4\xae\x50\x18\x66\x4d\xc7\xb1\x25\xa4\xe1\xb2\xe5\x38\xb6\x7b\xb7\xc2\x96\xd4\xa3\x8a\x1f\x9d\x8a\x2d\xd8\x11\x36\xe6\xdd\x67\x45\xab\xd3\xfc\x1c\x2e\xed\x5e\x2b\xf4\x55\xe5\x44\xab\xe3\xee\x91\xd1\x88\x56\x27\x1d\xf1\x32\x69\xd5\x50\xd7\x11\x33\x36\x39\x62\x59\x4a\xc2\x05\xe4\x8a\xfe\xe0\x75\xa5\x1b\xbc\x8e\xf5\x04\xaf\x63\x98\x39\xc1\xeb\xa4\xdf\xf0\x8c\x14\x6d\x84\xcf\x5c\x1f\x01\x2e\x42\xfb\xec\x88\x7c\xfc\x6b\xde\x66\x0f\x99\x74\x37\x58\x2a\x3c\x76\x2d\x34\xce\x66\x5a\x56\x22\x4d\x39\x66\xab\xb6\xc5\x83\xcc\x29\xbd\x1c\x3f\x12\x9f\x33\x2a\x0f\x96\x07\x9c\x75\x52\x0b\x4e\xcc\x18\xe2\xb6\x63\xca\x7a\xad\x00\x2b\x8e\xe4\xdd\x46\x77\x94\x49\xcd\x2a\xea\x98\xcb\x82\xf5\x8d\xde\x9f\x57\xac\xde\xab\x7a\xc5\x6d\x60\xfd\x2d\x04\x52\x2a\x2b\x3e\x04\x3d\xaf\x5a\x0e\x9c\x34\x88\x9a\x0c\xe1\x4a\x11\x35\x19\x49\x16\x59\x9c\x1d\x21\x6a\x52\x31\x8b\x44\x5a\xe6\x9d\xd9\xb7\x05\xea\x49\x0b\xc9\x96\x95\x47\xd4\x54\x24\xeb\x22\x6a\x52\x52\x29\xa2\x26\xed\x8f\x78\x6f\xee\xcc\x42\xc0\x9f\x17\x3f\xcb\xe8\x30\x1d\xee\x0c\xba\x82\xe7\xd1\xeb\xa8\x83\xbf\x89\x4c\xba\xa7\xcb\xe2\xf2\x75\xbf\xe7\xce\x1f\x17\x4e\xec\x45\x71\x9a\x24\x19\x83\x67\x74\x5f\x32\x00\xa3\x6d\x37\x7e\x30\xc3\x1d\xf7\x7a\x53\x90\x2e\x4e\x96\xcf\x77\x14\x9d\x45\xad\xd9\xe0\x42\xa7\x2a\x25\x9b\x77\xa1\x7f\xaa\x0a\x2d\xf9\x77\xa7\x01\xaa\x6e\x7b\x5c\x9c\xe1\xca\x4e\x3c\xfd\xc4\x58\xa0\xa0\xcd\xe8\x3f\x5d\x95\x62\x46\x46\x08\x4d\xbf\x74\x84\x50\x92\xe2\x28\xd3\xb7\x9e\x7e\x98\xd1\xeb\x3c\xdd\x8a\xb7\xc0\xab\xb5\xb6\xed\x92\xb5\xd0\x01\x57\x6e\xad\xc6\x93\x71\x55\x6a\xe1\x7d\x69\xc9\x29\x3e\xaf\xee\x9d\xa0\x18\x9e\x35\x31\xc2\x17\x7c\x39\x5d\xc5\x81\xf6\xcc\x58\x26\xd7\x51\xa0\x6c\x47\x03\x1c\xc8\x0d\xfe\x72\x47\x99\x0e\x40\x69\xde\x5a\x51\x29\x63\x62\x48\xde\xcc\x89\x7b\xf5\xe0\x0c\x62\x76\x27\x51\x89\x2b\x84\xd3\x43\x54\x76\x6d\xb7\xee\xa7\xac\x3d\xdb\x4d\x69\xaf\xc4\xb6\xea\xf0\xc6\x7d\x57\xff\xeb\x60\x08\x10\x07\xf1\x20\xc0\xe2\xd2\x62\x3c\x0e\x06\x83\xff\x3f\x7b\x7f\xc2\xdd\x36\x8e\x25\x80\xc2\x7f\x45\x42\x57\x33\x40\x08\x6d\x76\x96\x2a\xca\xb0\xda\x95\x4a\xaa\x32\x93\x38\x35\x89\x6b\x99\x91\x59\xfe\x68\x0a\x92\xd8\xa1\x41\x85\x84\xbc\x94\xc5\xf9\xed\xdf\xc1\x4a\x70\x91\x93\x74\xcf\xf2\xe6\x9d\x77\x72\x62\x91\x20\xf6\xe5\xe2\xee\xb7\xd7\x03\x58\x0d\xf4\x07\x1a\xa7\x81\x74\x29\xae\xde\xdf\x6f\x53\xea\xbe\x8b\x89\x08\x80\xcd\x2e\x55\x50\xdc\xef\x5a\xc9\x4a\x25\x49\xdd\x48\xf5\x28\x6d\xdc\xbe\xcf\x16\x77\x01\x00\x58\x8b\xea\xde\xd0\x25\x97\x75\xe9\x77\x49\x81\xcb\x04\xab\xb1\x10\xf4\x27\x25\xce\x3e\x63\xad\x7a\xb9\x4d\xd2\x05\xcd\x09\x7d\x88\x27\xd3\x11\x71\xc2\x4a\xba\xe6\x0a\x35\x0b\x61\xb7\x93\x07\xdb\x4e\xb6\xb8\x53\x6a\x8d\x95\xe6\xa7\xbe\xe0\x75\x17\xa0\xfb\xe9\x33\x26\x8f\x76\xb3\x51\x0c\x52\xba\xe4\x95\x46\xa3\x98\x17\x60\x1d\x32\xe8\x2c\xd2\x66\xb0\xca\x23\xe7\xca\xec\x48\xd3\x3a\x18\x3d\x06\x3e\xf7\x95\x93\x63\x9f\xf9\xe0\xf1\x48\x87\x34\x6c\xca\x76\xeb\x91\x86\x4c\x1b\xd5\xae\x57\xea\x22\x08\xe7\x6a\x32\x37\x3e\xb3\x87\xe3\x57\x01\xd8\x44\x6e\x05\xe1\xd0\x94\x56\xa6\x0c\x02\xd4\xf9\x84\x36\x0c\x1c\x76\xbb\x9a\xf9\x87\xb4\x52\x13\xf9\xc0\xd4\xb8\x16\x35\x03\xc8\x75\x6f\x5b\xd2\x65\x95\x4b\x6a\xfe\x52\xdc\xea\x89\xb5\xf1\x42\x76\x71\xea\x7a\xae\x5d\x6b\xe4\xe6\xc0\x14\x4b\xa7\x86\xdd\xc6\x10\xd5\x64\x81\xbf\x01\x5f\xc5\xe5\x52\x33\x23\xb5\xc7\x67\xad\xfe\x68\xfd\x76\x14\x00\x29\xbb\xea\x76\x17\xd6\xd0\x47\x9f\x31\x3b\x71\x36\x2d\x10\x77\x07\xf3\x09\xe8\x01\x31\x30\xa5\x14\x5c\x9b\x0a\xe6\xe7\x4e\x48\xbc\x8c\x40\x5a\xd3\x7d\x57\x7a\xc9\x90\xcf\xc0\x14\x04\xa0\xb9\x5d\x98\x9f\xfb\x99\x98\x71\xe9\x90\x26\x5b\xdc\xed\xd1\x4c\xa4\x6d\xdf\xdb\x63\xc7\x36\x45\x92\x36\xc6\xd9\xb6\x3c\x48\x53\xc4\x07\x64\x52\xb9\x5d\xaa\x6d\xb2\x4a\x1b\x49\x6c\xaf\xb1\xd4\x44\x74\xeb\xaf\x1c\x05\x65\xb6\xde\x3c\xb4\xf1\xc9\xa2\x1b\x98\x19\xa8\x0c\xd0\x34\x69\x2c\x6e\x62\x54\xe7\x2d\x7a\x94\x61\x81\x54\xe6\xbb\x1d\xd3\x03\xad\xeb\xb9\x55\xab\x6b\x64\xd1\xad\xc3\xd0\xbe\x02\x4c\x6b\xdc\xcf\x7d\x70\x0f\xc4\xf6\x51\xce\x1a\xed\x32\x09\x1c\xc4\x1d\x95\xd6\xac\x37\x20\xa4\x3e\x25\x72\xc1\x01\x42\x41\x57\x32\x06\x16\x76\x0a\xa0\xd0\x18\x2f\x6b\x9c\x20\x50\x82\xda\x66\xee\x52\x7d\xbe\x36\x91\x23\x99\x40\x00\x08\x97\x07\xb2\x6b\x93\xc2\x8c\x58\x5d\x5f\x2b\x2c\xca\x34\xb1\x64\xbd\xdb\x88\x1d\xae\xd7\x43\x2b\x6f\xf6\x93\xdd\xce\x06\x95\x4c\xb4\x6e\x76\xa2\x10\x7c\xe9\x38\x5f\xd7\xa5\x8e\x47\x3f\x31\x55\xe7\x02\xd3\x32\xb6\x69\xa2\xbc\x92\x59\x45\xa2\x0f\x46\x76\x5f\xbd\x48\xe4\xb9\xf3\x6c\x55\x79\xe6\x2c\xac\x44\x84\x4e\x62\xb3\xd3\xbb\x9d\x9e\x6d\xd7\x84\x58\x4d\xac\xcc\xa4\x1c\x28\x09\xaa\x4f\x59\xb9\xe1\x98\x80\x3c\xba\x01\xbe\xa0\x1b\x18\x9a\x8f\xc3\x21\xcf\x7e\xd9\x6c\x8c\x11\x9a\xef\x44\x91\x76\x39\x0d\xf3\x38\x9c\xa9\xe8\x6a\xf3\x38\x84\x11\xa6\x28\x88\x9a\xae\xe1\xe9\xde\x18\x07\x5d\xeb\xd1\x9f\x94\xa8\x36\x0d\x15\x17\x34\x93\x06\xc8\xb9\xb4\x58\xac\x8d\x9e\x64\x38\xd3\x9b\xe3\x01\x95\x45\xd7\xcb\x5e\x47\x07\xf7\x6c\x74\xcf\x53\xfe\x48\x95\x09\x6a\x54\x18\x03\x84\xce\xf1\x70\x03\xf2\x2a\xdb\x8b\xda\xb0\xb8\xee\xe5\x4b\x73\x02\xfe\xf1\x5e\x8e\x2b\x30\x55\xf5\xf4\xc1\x3e\xa9\x4b\xbc\xb3\x3f\xaf\x25\xe6\xd4\x25\xe3\x31\x77\x9f\xcc\x30\xab\xbd\x05\xb0\xd5\xc7\xca\x3b\x9f\x73\x98\x72\xcf\xcb\xfb\x52\x3c\x95\x5b\x0b\x18\xf3\xa4\xc4\x56\x9d\x9b\xbe\x46\x90\x1a\x00\x5a\x4b\x34\x01\x1b\xcf\x05\x1c\xb3\x7a\x0a\x90\x93\x6c\x9e\x55\x3a\xe6\xa8\xf2\x8e\x2c\x5d\x1b\x8c\x56\x18\x00\x84\xfb\xca\xcf\xad\xd6\x43\x30\x13\xf1\xbd\x8b\xf4\x75\x01\xd5\xfa\xf2\x18\x15\xfc\x2f\xda\xed\xbd\x9a\x29\x88\x5e\x07\x69\xe4\x28\x69\x1c\xf7\x9b\xe3\xbc\x5c\xb9\x2e\x67\xd2\xa0\xa1\x1a\x06\x0b\xfd\x6f\x46\x62\x1c\x72\x20\xfb\x0e\x0c\x9b\x39\x00\x98\xcb\xa8\xf6\x06\xfa\x0b\xbc\x18\xa0\x80\x75\xd4\x6d\xa6\x48\x2b\xc7\xdb\x59\xf9\x61\x0f\xca\x55\x9f\x12\x91\xeb\xff\xe0\x7c\xbc\x97\x5a\xad\x5f\x35\x1f\xdd\x1e\x2e\xf6\x9e\x5f\x13\x21\x43\x9f\x5f\x68\x8e\x88\x38\x1a\xbb\x1d\x75\xd8\x45\x5f\x74\x20\xdc\xe9\xe2\xf5\x73\xd1\x9e\x2e\x4e\xf8\xc3\xd3\xc5\x3b\x32\x55\xe3\x6e\x9c\x8e\x96\x9a\xfe\x3f\x01\x5e\x25\xe6\xf5\x39\x7c\xb2\x31\xd8\xda\xa7\xff\xde\xb1\x0a\x24\xe9\xab\x87\x6a\x1d\x58\xd3\x2f\xba\x2b\x34\x62\xd6\x0d\x99\xdb\x26\x05\x1d\x3d\xf8\x47\xce\x9c\x6a\xd3\xd1\xee\x72\xd3\xeb\x73\x13\x38\x30\xd3\x74\xcd\x41\x23\x3a\x61\x02\x23\xce\xb5\x29\x6d\xc5\x1c\x4c\xb0\x03\x10\xd5\xb1\xef\x87\x0a\xbc\x30\xda\xed\x81\x83\xf0\xf0\x7d\xb9\xf5\xb9\xde\x57\x97\xd8\xca\x00\x39\x6e\x3e\x0d\x16\x28\x5d\x01\xe6\x26\x96\xb8\x14\x83\x2a\x4a\x20\xf3\xc9\x04\xe7\x24\x77\x2e\x38\xe5\x63\xaf\xbe\x11\xad\x9f\xd9\x66\xc3\xea\xee\x54\x92\x56\xcb\xc3\xad\x7c\x18\x8c\xa7\xd1\x51\x36\x8d\x94\x09\x53\x52\xba\x46\x57\x86\x22\xeb\xa4\xe4\xe8\x9c\x87\x92\x86\xd3\xe8\x94\xd9\x20\xe2\xf2\x55\xfc\x5e\xe9\xa6\x46\x5a\x0d\x07\xac\x25\x09\x7d\x20\x54\xda\xd3\x0e\x97\xda\x5f\x2d\xd0\xac\xfb\xca\x7e\x88\x8d\x8b\x93\xc6\xf8\x9a\xba\xf9\x35\x87\xd2\xae\x1f\xb5\x64\x3f\xf3\xa9\xe1\x7b\x50\x8c\xaa\xc3\xbd\xe0\xfe\x51\x7d\x4e\xf0\xa7\x9d\xa8\x9c\xe1\x5b\x7c\x8a\xdf\xe0\x97\xf8\x03\x7e\x81\x3f\xe2\x4f\xf8\x37\xfc\x03\xfe\x1e\xff\x8c\x7f\x27\x32\xe0\x80\x5a\x89\x77\x4b\x88\xf0\xdf\x09\x1f\x26\x2b\x96\xe5\x2a\x98\x68\x81\xdf\x93\xdf\x8d\xb9\xc3\x6b\x32\x98\xe0\x9f\xc8\x04\xbf\x22\x63\xfc\x0b\x99\x87\xf8\x57\x32\x0f\x2b\x26\xe9\xbf\x57\x41\x49\x69\xcb\x4a\x09\xf8\x1c\xff\x84\x5f\x0d\x5e\x1b\x0d\x99\xfb\xcb\x28\xfe\x58\xe3\x2c\xfe\x6a\x2c\x5a\x4b\x6c\xbd\x0b\x04\x0d\xe8\xf1\x6b\x23\x0e\xf3\xaf\xda\xd9\x8d\x20\x70\xe0\xab\x63\xf2\x1e\x19\xc6\x8f\x56\xcf\x55\x83\x31\xdd\x98\x1a\xb7\x61\x90\x91\xdf\x87\xf1\x3a\xca\x5f\x64\x0b\x7a\xc2\xe1\x2b\x84\x08\x21\xc5\x6e\xc7\x08\x21\xa9\xfa\xd9\x78\x5e\x3d\x8f\x3f\x41\x32\x4c\x80\xe7\xc1\xd7\xe4\x15\xfe\x49\x1a\xd3\x31\xe5\x61\xac\x57\x04\xf2\x27\x56\x3f\x5b\xf5\xb3\x51\x3f\x69\x70\x46\x5e\x4d\x17\xd9\xfd\x99\x38\xa6\xcd\xb6\xcf\x54\xdb\xb2\xd6\x33\x55\x6b\x79\xb3\x4e\x52\x0a\x45\x2f\x62\xd5\x19\xdd\xb5\xad\xee\x9a\xee\x28\x9a\xfe\x4c\xe6\xda\x7e\x09\xff\xae\x89\xa1\x57\xf8\x0c\x85\xf8\x15\x39\x1b\x4c\x1c\xcf\x62\xbd\xa5\xea\xcb\x42\xfd\x5c\xa9\x9f\xb7\xea\xe7\x5a\xfd\xac\xd4\xcf\x65\x20\xa6\xf0\x47\xa2\x44\xd0\x52\x59\xf2\x85\xee\x2e\x64\xb2\xc9\x1f\xf1\x8f\x6a\x35\x5d\x07\x6a\xbd\x75\x90\x2c\xe1\x0f\xe4\x17\x43\x8c\xff\x62\x0d\x28\x03\x00\xf0\xf7\xa4\x35\x9b\x18\x6c\x73\x09\x8c\x7f\xf0\xbc\xef\xfb\x52\x90\xf7\xbd\x0a\xef\x28\x7e\x62\xf5\x53\xa8\x9f\xad\xfa\x49\xd5\xcf\x06\xdd\xeb\x29\x4d\x96\xf0\x13\xe9\x4f\xb0\x8c\x8a\x07\xcf\xc8\xef\x15\xc4\x43\x00\x9f\xf9\x13\x84\xe4\xce\xf9\xfb\x6e\xc7\x55\x21\xe5\x98\xe1\xdf\x21\x30\xc6\x84\x48\xba\xbd\xf9\x8d\x9c\x4d\x6b\x3d\xfc\x6d\x30\x11\x0b\x93\x4c\xd1\x6f\x03\x32\xc1\x9f\x48\xff\x93\x5e\x97\x4f\x6a\xde\x75\xf9\xa2\x36\xf5\x62\x58\x72\x6a\xf0\x4f\xf8\x6c\xf0\x5a\x2e\x84\x72\xe0\xd4\xec\x9b\x9c\x81\x97\xa4\x51\x56\x8e\xe3\x6c\xb7\xfb\x53\xe9\x3a\xbf\x44\x33\xd1\x14\x04\x58\xfc\x57\x73\x1e\xc0\x7a\xeb\x2f\x5b\x0d\xba\x2e\xe5\x7a\xb9\x5a\xd5\x2c\xb8\x25\x62\xd3\xe4\x33\xf0\x08\x04\x8f\xc0\x23\xfc\xd9\x19\xbc\xed\x9a\x3f\x7f\x52\xcd\xa0\xd6\x85\xfc\x47\x26\xb0\x35\xf0\x53\xf2\xd2\x25\x9d\x30\x7c\x43\x4e\x2d\xbd\x84\x8e\xc7\x33\xf8\x82\xfc\xe4\xbf\xc1\x1f\xc9\xd9\xe0\x74\xfe\x26\x34\x90\x20\x10\xe9\xf8\x23\x79\x8d\xb0\x3c\x0c\xaa\x4b\xdd\x4b\xf2\x02\x9f\x0d\x3e\x86\xf8\x35\xf9\x88\x7f\x22\x2f\xc4\x4c\xb9\x13\x75\x12\x5c\x54\xd1\x43\xc4\x40\xf1\x85\x5a\x84\xdf\x11\x3e\x23\x02\xb4\x3a\xdf\x67\xbf\xdb\xce\xb9\xc5\x06\x07\xb2\x17\xc6\xd3\xdf\xe7\x76\x86\xdb\x7c\x12\x88\x59\x3c\x23\xaf\xf0\x07\xd2\x1f\xd7\xa7\x52\x14\x56\x53\x29\x41\xc8\x07\xd2\xff\x20\x59\x4b\xa4\x95\x0b\x7f\xf0\x3c\xd6\x57\xbe\xdb\xd5\x21\x62\xea\x10\x31\x75\x88\xc4\xcf\x46\xfd\xa4\x9e\x07\x65\x75\xef\xf4\x30\x65\x5d\x0a\x22\x69\x07\x3f\xd3\xd6\x27\xb1\x21\x54\x2f\x3a\x7b\x18\xeb\x3a\x51\x29\xa6\xe1\x6b\xe6\xc0\x5c\xb6\x4c\x39\x9e\x6f\x01\x0b\x42\xc8\xdd\x4c\x7a\x0f\xaa\x9f\xf2\xc7\x23\x71\x94\x0e\x90\x3f\x11\x80\x59\x6c\xd3\xd9\x99\xbd\xb4\x82\x7f\x87\xc0\x31\x3c\xfc\xef\xda\x74\xa6\x09\x7b\x14\xdb\x1b\x0d\x05\xf0\xa6\xb1\xbb\x6e\x1a\xbb\xeb\xa6\x7b\x77\xdd\xb4\x76\xd7\xe7\xa7\xf5\x17\x75\x97\xfe\x8c\x64\xd3\x06\x61\x7b\xe5\xfb\xf8\xe7\xb2\xc4\xd6\x59\x4d\x87\x3c\x50\x74\xe4\x57\xcb\xbb\x11\x57\x6a\x89\x8d\x7b\xe6\x8e\xec\xaf\xca\xb2\xd4\x42\x2f\xf0\x08\xb8\x6b\x36\x46\x38\x23\x8f\xc0\xa3\x46\x5a\x42\xc0\xf9\x79\x33\x63\x44\xc0\xa8\x99\x56\xc8\xf0\x69\x8d\xc4\x98\x80\x5e\x33\x2d\x25\xe0\x7c\xd9\x4c\xdc\x12\x70\xce\x9b\x89\x1b\x02\xce\xf3\x66\xe2\x92\x80\x79\x33\x6d\x41\x40\xd8\x4c\x5b\x13\x00\x9b\x69\x97\x04\xa0\x66\xda\x15\x01\xf7\xcd\xb4\xb7\x04\x94\xcd\xb4\x15\x01\xd3\x66\xda\x1d\x01\x8f\x9b\x69\xd7\x04\x04\xcd\xb4\x13\x02\xfe\xd6\x4c\xbb\x20\xa3\x79\xef\x9c\x9d\xf3\xf3\xfc\x7c\x79\x5f\x42\xf4\x08\x9c\x9f\x4f\x47\xf3\xf3\xf0\x2f\x82\x52\xba\x71\x3f\x43\x74\x5f\x06\xd3\xbf\xf5\x45\x96\xf3\x70\xfe\x97\x70\x77\x3e\x82\x33\x72\xfe\x18\x8d\x56\xf8\x4f\x32\x1a\xce\xcf\xcf\x47\x10\x3c\x3a\x67\xe1\x08\xbf\x23\xa3\x79\x34\x58\x8e\x07\xdf\x85\xa3\x64\xba\x17\x23\x7f\xf6\x8f\x3b\xf5\xbd\xdf\xe4\x74\x99\xdc\x76\xc8\x99\x69\xe5\x0a\x74\x70\x7e\xe3\x0f\xd0\xa8\xe2\xa9\x69\x89\x32\x28\xf1\x96\xa9\x0a\xe8\xa2\x2b\x28\xb3\x13\x88\xec\x0f\x59\x89\xa4\xbb\x4b\x17\x49\xcf\xf7\x13\x1a\xcf\xbe\xca\x78\xba\xd6\xfc\x9c\x86\xbb\x1d\x14\x3f\x52\x57\xe1\x1f\x55\xb4\xa6\x08\x99\x23\x76\x5f\x3e\x30\xff\x1d\x76\x91\x5f\x38\xff\x0f\x98\x28\x3e\x10\xce\x46\xa9\x3a\x18\x25\x37\x5c\x99\x11\x52\xac\xbc\xe5\x78\x9e\xfa\x6d\x06\xbe\x51\x89\xf5\xd0\x37\x4a\xbf\x30\x61\x94\xe8\x18\x37\xc6\x92\x7f\x7b\xc5\x88\x89\x77\x53\x5a\x8a\x58\x05\x53\x91\x1c\xfe\x3c\x24\x7c\x9e\x87\x36\xee\x80\xa3\x26\xf1\x39\x2d\x4a\xd1\x8f\x99\x7d\xd2\x34\x8b\x1d\x07\xbe\x57\xba\x8f\x81\xa3\x70\x2f\xa5\xf9\xb7\x41\xa5\x8d\x86\x05\x2c\x56\xef\xe2\xa9\xb4\x11\xe8\xdd\x52\x33\xe7\xd9\x07\xd2\x7c\xc7\x34\x12\xd8\xa7\x16\xf5\xfb\xd0\xa6\xec\xb0\xfa\xb0\x6e\x76\x48\x55\xec\xbe\x74\xdd\xc8\x1b\xea\xcc\x51\x93\x2e\x28\x3f\x4b\xae\x68\xb6\xe5\xbd\x75\xa4\xd4\xaf\x2f\x29\x65\x3d\xb3\x53\x51\xe9\xd8\xbd\x76\x94\x97\xf1\xbb\xbe\xb4\x86\x58\x13\x71\xb9\xa0\x67\x6c\xc3\x86\x94\xab\x52\x20\xc5\x63\x49\xd2\xc9\x9c\xd1\x6e\xd7\xcf\x91\xe7\xb5\x4b\xe4\x4e\x2d\xb8\x59\x9c\xe7\x77\xd6\xd0\x5c\xa6\x68\x7f\xf6\x82\x46\x75\x3e\x29\x25\x1e\xc9\x04\xa9\x67\xaa\x67\xd0\x96\x02\x63\x54\x96\x65\xdf\xd9\x4d\xb2\x2a\xd2\xa9\x1c\x6f\xfb\x33\xab\x1e\x83\x48\x37\x20\xc0\x03\x89\x4a\x51\x3c\xeb\x2c\xee\x4e\xec\xcc\x7d\x09\x8a\xaa\x8a\x8c\x14\x65\xa9\x5d\xbd\xa6\x78\x2b\x48\xf2\x8d\xc0\xe4\x97\x64\x30\x71\x1d\x1f\xa0\xfb\x8d\xe7\x09\x6c\x4f\x7e\x4d\x0d\x7d\xb6\x25\xa9\xd1\xf8\xdf\xa2\x40\x14\xc2\x5b\x7b\xf3\xaf\x21\x42\x75\x4f\x08\x82\xc6\xde\x18\x87\x25\x31\x5c\xa0\xe9\x46\xe0\xa9\x95\x04\xdb\x14\x9e\xf2\xa9\xc2\x1e\x53\xb2\x95\xbd\x9a\xfa\xfe\xf2\x88\x4f\x51\xea\x79\xe9\x7c\x19\x0e\xf3\x2d\x83\x68\x2a\x1b\xac\x4a\x95\xa9\x72\x81\xac\x46\x50\x27\xfb\x33\x81\x59\x3a\x93\x60\x76\x80\x9b\xa6\x6d\x1b\x65\xde\x62\xb7\xeb\x67\xc8\xf3\xba\xca\x64\xb5\x9a\x70\xb3\x0a\xb9\x24\x90\x76\x6f\x97\xcc\xdd\x2e\xed\xcd\x92\xd5\x95\x44\xcb\x52\xd4\x53\x4d\xe2\xa5\x63\xf5\xbd\xdc\x32\xa3\x50\x1e\xe5\x79\x74\x47\x78\x95\xef\x4a\x5c\xcf\x4a\x4d\xf2\x2c\xa9\x49\xd1\x5d\xc7\xb9\x4a\x57\xb3\xe9\x94\x62\xa0\x5c\x4e\x35\x93\x8f\x27\xa8\xd2\x13\x98\x4c\xd9\x51\x33\x83\xf1\x5a\x31\x98\x34\xfc\x56\x6c\xb5\xb6\x36\xbd\xd1\xfd\x47\x78\x22\x28\x09\x1b\x61\x78\xb3\xdb\xc5\x70\x8d\x4a\x7c\xe9\x2a\xce\x6e\x59\xcb\xdf\xdc\x72\xcb\xb4\xcd\x94\x9c\xbf\x6a\xec\x52\x9d\x96\x27\x3c\xa5\x04\x5c\xe6\xd9\x4d\x41\x73\x80\x93\xa1\x7e\x14\xf7\x56\x32\xa4\xec\x9a\xdc\x8b\x7c\x51\xbe\xba\x16\x1b\x3d\xa9\x4c\xc9\x40\xf5\x52\xa8\x4c\x19\x23\x57\x22\xef\x62\xf1\x26\x29\x38\x65\x34\x97\xef\x19\x8b\xa9\x7a\x58\x2e\xe5\xaf\xd2\xef\xad\xe5\x51\x49\x27\x69\x6a\x52\x0b\x99\x4c\xaf\x12\x2e\x1f\xb4\xaa\x6e\xad\x8c\x4e\x7b\xc7\xe2\x7a\x5d\xa9\xad\xa2\x8d\x96\xcc\x43\xd1\xd1\xcb\x84\x2d\x9a\xc1\xce\x5a\x40\x56\xeb\x7b\x9a\xcc\xc6\x4e\xc6\x9a\x8a\x02\x39\x81\xf1\xcd\xa2\x23\x88\xfd\x08\xc8\x6f\xeb\x45\x92\x7f\x59\x23\x32\xeb\x9e\x26\xb6\x57\x51\xf1\xb1\xe3\x32\x1d\x97\xfa\x5a\x6a\x5a\x99\xe4\xae\x31\x22\x45\xf7\xfd\xa6\x4c\x36\x23\x95\x81\x52\x0c\x05\x98\xcf\x3d\xaf\xaf\x1c\x44\x9e\x49\x29\x45\x2e\x28\x06\x27\x0f\x47\x32\xa2\x48\x9f\x3b\x79\xb8\x20\x20\x9c\x3c\x32\xa0\xd1\x34\x1a\xae\xd2\xec\x32\x4a\x15\x31\x1c\x0d\x95\xa1\xb7\x79\x2b\x68\xba\xec\xcb\xdb\x05\x32\x12\x19\x85\x03\x01\x45\x0f\x26\x4f\x9e\x3f\xf9\xf6\xf0\xd9\x93\xe7\x78\x43\x46\x7f\xdc\xb2\xc1\x60\x84\x97\x64\x34\xff\xe3\xfc\xf6\x60\x3c\x38\xbf\x7d\xfe\x32\x1c\xe1\x05\x19\xcd\xcf\x6f\x0f\x5e\x9e\x6f\x0f\xc7\xe3\x83\xf3\xed\xab\x57\xe3\x97\xe2\xef\xb3\x89\xc0\xb6\xd7\xe4\x3e\xbb\xa6\xf9\x32\xcd\x6e\x02\xf0\xce\x3c\xf5\xa4\xdf\xa0\x1e\xa3\x74\x51\xf4\x6e\x92\x05\x15\x78\x0c\xa7\x2b\x9a\x17\x32\xc0\x87\x36\xe9\xc1\x80\x65\x7c\x70\x19\x15\x49\x0c\x02\xf0\x3a\x4d\xe9\x2a\x4a\x75\xd9\x63\xd2\x1b\xdf\x7e\x3b\xee\x41\x65\x29\x25\x33\xf5\xe2\x6c\x41\x7b\x9b\x2c\x61\x1c\x01\x0c\x12\x76\x1d\xa5\xc9\x62\xa0\x63\x71\x80\xd7\xea\x5d\x55\x00\x4a\x7c\x49\xde\x46\x7c\x3d\x5c\xa6\x59\x96\xe3\xab\x2e\x2e\x5f\x75\x77\xbc\xad\xef\x95\xf7\x11\x5b\x29\xce\x30\x5c\xcf\x69\xe8\x5c\x10\xab\xa6\x9e\xaf\xf1\x49\x86\x73\x71\x01\xb0\xc1\x60\x8a\xf2\x39\x0b\x09\x87\x52\x5d\xc4\x4a\x02\xaa\x2a\xee\x6a\x92\x03\x43\x96\xff\x4d\x2a\x30\x55\x31\xfc\x98\xab\xe0\x9f\x4b\x7f\xbd\x3e\xf8\x1b\xc0\x54\x3a\x29\x46\x38\xf7\x57\x50\xc6\x01\x34\x48\xff\x02\x83\x21\x40\xc8\xd4\x37\x04\x08\x73\xa4\x74\x4a\xc5\x4b\xd5\xfe\x75\xcb\xc5\x9a\x80\x33\xca\xcb\x9a\xf5\xb0\x96\x1d\x25\x53\x24\xa5\x64\x0e\xf5\x95\xf9\x3e\x42\xc7\xe4\xe9\xd3\x83\xef\x9e\x79\x1e\x3f\x22\x4f\x9f\x1d\x4e\xbe\xf3\xbc\xec\x28\x99\x3d\x7d\x76\x78\x30\x26\x04\x3e\x7b\xf2\x74\x72\xe0\x29\xbd\xe1\x46\x49\x34\xcb\x15\x90\x85\x70\x32\x3e\x38\xf4\x38\x3a\x3a\x9a\x8c\x91\xaf\xde\x18\xf2\x9f\x3d\x7d\x7a\xf8\x4c\x7a\x57\x95\xd9\x38\xc2\xd9\x60\x80\x02\xfb\xda\x31\x99\x27\x0e\x01\x24\xd6\x06\xb6\x2f\x11\x27\x2e\xe2\xb1\x68\xe1\xa9\x40\xef\x7d\x72\x05\x21\x1d\x10\xd5\xe4\xf1\xf1\xf1\x64\xec\x89\x6e\xec\xe4\xe0\x10\xa6\x44\x0e\x68\x27\xbb\x46\x11\x96\x05\x28\x2a\x91\x99\x52\x77\x46\x2f\x1a\xde\x0d\x0f\x0e\xfc\xe7\x4f\x1f\x43\x7a\x74\xf0\x0c\x0d\x20\x1c\xf7\x89\x18\xea\x53\xa7\xc4\x4d\x3d\x4c\xa5\xc2\x2e\x28\x61\xb3\x4b\x48\x47\xcf\xc7\x63\x14\xd0\xe3\xe3\x09\xa6\x3e\x11\x09\x1c\x4d\xe9\xf1\x93\xa7\x4f\xa7\xb9\x4f\x0e\x9f\x21\x2a\x13\x0f\x9f\xda\xf9\xb8\x84\xb9\x7f\xf8\xec\x31\x1d\x41\xea\x1f\x7e\xeb\xe2\x33\x7f\xd6\x95\xbd\xb5\x73\x4a\x1c\xe3\x14\x6f\xf0\x12\x2f\xc4\xca\xaf\xab\x3d\x7c\x45\xc6\x78\x45\x26\x07\xdf\xe2\x3b\xf2\xfc\x40\x76\x4a\xae\x64\x2d\xd6\xf0\x00\x20\x74\x34\x96\xa2\xfa\xb1\x51\xba\x63\x53\xdf\xcf\x51\x6d\xc9\x73\x74\x2c\x6a\xf2\xbc\xb7\xd0\x39\xe7\x08\x2f\xb4\xf8\xa3\x9e\x57\x49\x01\x33\xc2\x8e\xc7\x33\xe6\x4f\x82\xf1\x34\x3b\x5a\x6b\xf4\x2a\x21\x57\x38\x22\x13\x5c\x90\xc3\x67\xd3\xec\x98\xac\x65\x9d\xf5\xe3\x8f\x30\x84\x31\x81\xcb\x8e\x6d\x37\x78\xf2\xed\xd1\x64\x3c\x5b\x0e\x0e\x0e\x82\xe5\xe0\xd9\xd3\xa3\x83\x67\x33\xf1\x1b\x2c\x07\xdf\x3d\x57\x2f\xdf\x3d\x0f\xc4\x2e\x20\x87\xcf\x76\xbb\xf8\xf8\x12\xc2\xed\xe0\x0a\x8d\x22\x84\x64\x4b\x06\xc2\x01\x84\xaf\x7c\x12\x3f\x8e\x70\x1f\xc6\x47\x30\x25\xc5\x11\xb9\x9b\x4d\x82\xe2\x98\xdc\xf9\x07\xcf\x66\x07\xcf\x82\x62\x70\x87\xd0\xb4\x90\xcb\x14\x1d\x5f\xc2\xed\x08\x6e\xc8\xe1\xb3\x41\xda\xae\x2a\x7a\x4c\x36\xd3\x3b\x72\x03\xaf\x06\x09\xe6\x64\xa1\xd7\xc0\x9f\xe0\x31\x21\x09\xc2\x97\xf0\x6a\xc4\xd1\xf1\x76\xb0\x6a\x96\x5c\x89\x5d\x21\x3e\xe2\xab\xbf\x12\x8e\x17\xc6\xb7\xe2\x95\xef\xe3\x31\x5e\x59\x36\xd8\x09\x5c\x38\x5b\xe1\xdd\x67\xb6\x02\x5e\xe3\x15\xbe\xc3\x27\x52\xd6\x95\xe5\x70\x41\x20\x25\x02\x56\xa0\xca\x0f\x98\xd8\x19\x4c\x02\x8a\xe7\x07\x58\x89\x4b\x17\x53\xdf\x8f\x90\x98\xf8\x79\x14\xa2\x23\xb9\xe2\x27\x6a\x89\xaf\xe0\x52\xaf\x6b\x4e\x32\x72\x62\xaa\xc9\x6c\x06\xb1\x95\xa6\xf9\xd1\x42\xaf\x73\x41\xb6\x9d\x95\x1e\x0b\x8a\x7c\x79\xa4\x6c\x7e\x97\xaa\xc6\x62\xc0\xd5\x3a\x31\x34\x82\x6b\x92\xfb\x93\xf6\x0c\x33\x9f\x88\x7c\xe8\xb1\xe8\x7a\x51\xab\x5a\x20\xd0\xa6\xcb\xdc\xf3\x7c\x9f\x1d\x6f\x9b\xc5\x97\xd6\xa1\x5e\x4c\x18\x4e\xc5\xe6\x93\xeb\xbe\x21\xe9\x11\x49\x66\x93\x20\x3d\x26\x89\x5e\xf7\x74\x90\x20\x34\x4d\xe5\xba\xdf\x91\x78\xb0\xc1\x2b\xb1\xec\x1b\x6c\xa7\xe2\x02\x6e\xfc\xbb\xbf\xae\xf0\x18\x49\x27\x70\x97\xf0\x6e\xb4\x42\x53\xe7\x73\xac\x3e\x25\xe4\x06\x32\x2c\xae\x13\x92\x49\x5f\x6b\xd8\xf7\xf3\xd2\xf7\x19\xf6\x7d\x6e\x57\xb6\x02\x42\xc9\x12\x16\xe4\x5e\xa3\x85\x01\x98\x0c\x9f\x0c\x27\x00\x6f\xe3\xe2\x20\xb8\x57\x3e\x31\x82\x6b\x2c\x1d\xb2\xd0\xe0\xa4\xc4\x3a\xe9\x4f\x93\xf4\x0e\xf3\xec\xe4\xc3\x8b\xd7\xaf\xbb\x38\x4a\x77\x4d\x80\xaa\xd3\x97\xc6\x3f\xcd\x0c\x08\xac\x01\xf8\x62\x6f\x05\xda\x18\x31\xfb\x85\x25\xb2\xea\xaf\xa8\x70\x63\x2b\xfc\x13\x1a\x2f\xfb\x4f\x50\xc3\x13\xbf\x6a\xa0\x14\xfb\x27\x51\xf1\x65\x0d\xf9\x4f\x32\x94\xd8\x97\x42\xd9\x81\x49\xba\xac\x97\xb0\x5e\x81\x5a\x61\x26\x53\xe9\x23\x74\x9e\x86\xa4\x98\xa7\xa1\x36\xfe\x66\xc3\xcd\x96\xdd\x89\x9e\x93\x42\x87\x7a\xad\x19\x23\x77\x6b\x05\xcd\x58\xd0\xf9\x41\xa0\x5d\x33\xf1\xa7\xfb\xb3\xc2\xd1\x66\xea\x27\xb8\x2f\x91\x46\x2c\x3b\x6c\x27\xed\x01\xce\x6b\xb7\x8c\xb6\xa0\xa9\x48\x91\xfa\x18\x55\xc7\xa5\x05\x42\x35\x4f\xf5\xaa\x71\x82\xee\x39\xe1\xbb\x1d\xf0\x00\x66\x52\x6b\x95\x00\xad\x30\x7b\x5f\x4e\x1d\x27\x3c\x8e\x02\xcb\x6e\x37\x76\xc2\x81\x58\x6d\x58\x1d\xad\x61\x74\xee\x8f\x56\x53\x6a\xb1\x1a\xad\xdf\x17\x93\x09\x3d\x9c\x26\x9e\x07\xd8\xf6\xea\x52\xe9\xc5\xea\x0a\x93\xe1\x55\x74\xfb\xaf\xf4\x4e\x1c\xee\x98\xd8\x37\x4d\xeb\x57\xf8\x48\x7c\x3c\xf6\xbc\xf4\x38\xf6\x3c\x98\x92\xb8\xd2\x19\xd9\x92\xf1\x74\x7b\x94\x4e\x7d\x7f\xab\x63\x30\x68\x58\x76\x49\xe8\x7c\x1b\x5a\xec\xa8\xc0\xe0\xaf\x07\x63\x01\xc1\xc9\xa5\x95\xa9\x30\x34\xbd\x3a\x26\xe3\x19\xdc\x90\xcb\xca\xc1\xd5\x95\x38\xfa\xf6\xfd\x4a\x40\x96\x40\xe4\xc0\x4b\xe9\xd9\x7d\x41\x3a\x5c\x44\x6d\x10\x5e\x77\xa5\x2f\x11\xce\x61\x84\x17\x68\x96\xc1\x68\xbe\x08\xd1\x4c\xfc\x55\x87\x7e\x8d\x02\xf1\x42\xe6\xe2\x2f\x5e\x87\xea\x6d\x6d\x43\xd5\x95\xda\x1e\xb6\x66\xb4\xb8\xdb\x75\x98\x05\xcf\x15\x4d\xa0\x48\xe5\x50\xcc\x6e\x6b\x77\x18\x16\xa1\xde\x17\xc8\x50\x32\x1d\x26\x75\x0d\x5e\x29\x45\xf7\x5a\x9b\x40\x10\x1c\x26\xce\x98\xda\x18\x81\x41\x79\x54\x50\xaf\xcb\x2c\x4b\x69\xc4\xaa\xe4\x19\xe0\xf9\x96\x82\x00\x2c\xa3\xb4\xa0\x40\xe5\xd2\x7b\xc0\x64\x4a\x8a\x57\x09\x4b\x38\x15\xa7\x9f\x06\x00\x58\x01\x99\xd1\xea\x2e\x5d\x66\x70\x63\x0b\x17\x15\xa3\xb3\xb9\x93\xa5\xc6\x8f\x75\xcc\xa2\x98\xbb\x0d\x3f\x11\x14\xcd\x12\x18\x41\x8a\x1c\xa0\x14\xa9\x09\x28\x88\x02\x90\xb5\xd5\xcc\x61\x84\x50\xe5\x10\x3a\x83\xf2\x02\x99\x25\xf2\xb7\x13\xb0\x15\x7e\x67\x35\x14\x55\x98\x24\x47\xc1\xbe\x5c\xa2\xf6\x7a\xc6\x59\x67\xc6\x42\xf4\x6a\x6f\x4b\x01\x00\xff\xbd\x5b\xa9\xe5\x09\x41\x2a\x1c\x5e\x45\x1b\x64\x79\xd5\x57\xd2\x43\x94\x63\xc3\x31\x0f\xad\xb9\x86\xeb\x38\x5a\x63\xfa\x90\xce\xf3\x10\xe7\x95\xb6\x3b\xd3\x7e\x0c\x74\x67\x3e\xd2\xbb\xa2\xde\x7d\xe3\xbd\xa4\x19\x9d\xfb\x0b\xc1\x24\x43\xd2\xb5\x8c\xb2\xd7\xaf\x9c\x60\xeb\x43\xd2\x69\x20\xa7\x4e\xbb\xd2\xb5\x2e\x28\x31\xfe\x63\xb3\x05\x15\xa8\xc7\x50\xad\x06\x61\x8e\xa9\x98\xcc\xa2\xd2\x81\xf6\x66\xa1\x0b\x04\xcf\xa4\xc1\xab\xfe\x16\x3c\x7b\x26\x5a\xed\xd0\xfc\xd2\x5a\x72\xa2\x9e\x2d\x4f\x52\x80\x70\xd6\x5e\x9f\xfa\x08\x71\x42\x3a\x6f\xa0\xb7\xd1\xa6\xc9\x33\x4f\x8a\xe1\x85\x62\xd2\x19\x97\x0f\x17\x05\xe5\x24\x99\x09\x92\xf8\x6d\xb4\x09\x1a\x56\x9b\xdb\x34\x45\x65\x24\x29\x6a\xb9\x5d\xf6\x7a\x09\x97\xce\x44\xb5\x43\xe2\x6a\xbd\x8f\x32\xbd\xe6\xd1\x62\xa1\x16\x9c\x3b\xeb\x8d\x23\x67\x48\x45\xcd\xfc\xdc\x9e\xae\x64\x66\x7b\x29\xb3\x98\x0e\xae\x28\x77\x66\xe0\x34\xba\xa2\x05\xb4\x39\x0d\x3a\x5b\x6f\x21\x5a\x2c\x3a\x35\xfb\x92\x19\x0d\x72\xb1\xe5\x29\xd7\x9e\x8c\x28\xc2\x11\xd1\x2d\xaf\xa3\x42\x60\x3e\x0e\x3f\x54\x36\x81\x19\xc2\xda\x27\x93\x9a\x50\x33\xe6\xc8\xf3\xfa\x5c\xbb\xa7\xd0\x5f\x4c\x74\x83\x68\xb7\x83\xb5\xf1\x50\x0e\x29\x2e\xb4\xf2\xa4\x48\x9a\xb3\x90\x14\xa8\xde\xed\x75\x54\x34\x63\x41\x24\x35\x83\x13\x59\x97\xea\xa6\x8e\x94\xd6\x1c\xcd\xb4\xcd\xd4\x55\x83\xe0\x8d\xb6\xf4\xad\xd9\x6e\xcf\x35\x41\x94\xed\xad\xa8\xe1\x52\xf3\x63\x32\xb6\xfd\x29\xad\x69\x19\x6b\xf7\x22\x59\xc2\x8e\x69\x6c\x8d\x65\xce\xc2\xb2\xc9\xd3\x7b\x04\x1e\xf9\xd4\x7f\x64\x1d\xeb\xc8\x20\xe3\xb4\x27\x7a\xf2\xa8\x31\x86\x88\x37\xbb\x4f\xa5\x73\x6c\x7a\xd4\x5e\xad\x7a\xdb\xf2\xcb\x9c\x76\x38\x41\x3c\xcd\x7a\x34\xa5\x57\x94\x89\x96\x17\xf4\x96\x2e\x7a\x97\x77\x3d\xe0\xd3\x46\xdb\x3c\x6b\x9c\x92\xba\x90\x4e\xb7\xad\x90\x5f\x54\x62\x36\x94\xd9\x3f\x50\x4e\x22\x05\x2c\xe4\x91\x0f\x9e\x3f\x17\xc0\xa1\x43\x81\xd2\x01\x0e\xc6\xff\xe3\xd4\xc2\xa1\x0e\xe3\x6f\x02\x80\x6b\x0c\xeb\x08\x92\x8f\xc6\xb3\x89\x0f\x07\xf4\xe8\x68\x82\x82\xb1\x0f\xe5\x43\x29\x56\x69\x91\xdd\x73\x72\x38\xf1\x32\x0c\xb3\xe3\xe3\x63\xf2\x14\x09\xbc\x0c\xf2\x1d\x39\x3c\x90\x04\x57\xae\x1b\x84\xdc\x28\xf7\x65\xc7\x63\xf7\x58\x5b\xc0\xd9\x69\x47\x26\x88\xd2\x8a\x1d\x51\x90\x31\x8e\xc9\x58\x2b\x6f\xf1\x63\x12\xb5\x1d\x20\xbd\x34\xae\xe8\xaf\xb2\x9c\xf6\x16\xc9\x2a\xe1\x85\xd8\x01\x62\x0a\x7a\xcf\x9e\xf4\x7e\x7d\xf3\x6f\x3d\x15\xc4\x4a\x69\xfd\x2a\xed\xaf\x84\xe4\xba\x1f\x75\x46\x04\x97\x7c\xaa\x76\x2b\x86\xb7\xa8\x26\x56\x35\x13\x88\x35\x36\xfa\x42\x7c\x20\xfd\xa7\x93\x7e\x1f\x1e\x1e\x78\x09\xc2\x85\x4f\x60\xe2\x91\xc3\x09\x3a\x3a\x8a\x71\xec\x93\xa7\x66\x3e\xc4\xaa\x5c\x37\x54\x89\xad\x1e\xc0\xf1\xf1\xc4\x75\xa1\x0d\x27\x1e\x45\xb3\x01\x0f\x78\x09\x0b\x71\xad\xe4\xb4\xe0\x44\x5e\x4c\xd5\x32\x07\xcf\xc7\x65\x88\x9f\x77\xe8\x25\x68\x85\x95\x93\xef\x5f\xfc\xf0\xf2\xd5\x8f\x3f\xbd\xfe\x97\x7f\x7d\xf3\xf6\xf4\xdd\xcf\xff\xf6\xfe\xc3\xd9\x2f\xbf\xfe\xf6\xfb\xbf\xff\x47\x74\x19\x2f\xe8\x72\xb5\x4e\xfe\xfe\x31\xbd\x62\xd9\xe6\x53\x5e\xf0\xed\xf5\xcd\xed\xdd\x9f\xe3\xc9\xc1\xe1\x93\xa7\xcf\x9e\x7f\xfb\x9d\x3f\x02\x86\xa9\xb8\x6f\x47\x25\x4b\x38\x3e\x12\x98\x16\x3d\xca\x1b\xa7\x27\xaf\x9f\x99\xb3\xbb\x8d\x66\xac\x82\xb7\xdb\x42\xfa\xa9\xd2\x5a\xef\xbd\xb1\x74\x6d\xf6\xec\x30\xd0\x67\xa7\x63\xa7\xd8\x2d\xfa\xec\xa9\x6e\x8e\x7c\x37\x9e\xd1\xc1\xb3\xa7\xc1\x77\xcf\x4d\xca\xe4\xe0\x60\x46\x07\xdf\x3d\xf7\x0f\x9e\x05\x4f\xbe\x35\xa9\x4f\x9f\xcf\xe8\xe0\xc9\xb7\xfe\xd3\x83\xe0\xc9\x21\x21\x74\xf6\xec\x20\x78\xf2\x5c\x3e\x1c\x06\x83\x89\xbe\xea\x9f\x77\x6a\x41\xfc\xf8\xfe\xe5\xc9\xd9\xcb\x0f\x67\x17\x6f\xde\xfd\xf6\xf2\xfd\xc5\xf7\xef\x7e\x39\xfd\x81\x4c\x30\x1b\xbe\x79\x79\xf2\xe1\xec\xe2\x97\x9f\x7f\xb6\xa9\x07\x98\x0d\x0b\x1a\xe5\xf1\xba\xe1\xdd\x1b\x2b\x87\x68\x63\xc7\x2f\xba\x35\xac\xd0\x36\x90\x8e\x4e\x02\xaf\x38\x34\xda\xfd\x88\xc3\xcc\x86\x30\x1f\x70\x34\x3a\x40\x3e\xc7\x29\x89\x60\x86\x93\x79\x1c\xe2\x7e\x75\xce\x64\xfc\xb8\x59\x1c\xa4\xc7\xe3\x59\x3e\x88\x8f\x27\x33\x0a\x63\xa7\xca\xa0\x20\xa4\xa3\xf7\xb3\xfc\xc8\x28\xc5\xcf\xf2\x60\x30\x09\xe2\x20\x1e\x70\x59\x9a\xe3\xf8\xb3\xa5\xe3\x80\x1f\x8d\x67\x83\x89\xd8\xac\x83\x89\x75\x14\x8c\xf5\xf8\x77\xbb\xee\x99\x54\xca\xf8\x47\xe3\x6a\x3a\xa4\x46\x5e\x32\x98\x48\xd0\x2c\x3d\xdf\x40\x3e\x4f\x42\xcc\xe7\xc9\x60\xa2\x06\x8a\x06\x83\xa4\x8a\xc7\xa1\x17\xaf\x43\x33\xa4\x85\x31\xb9\xae\x84\xf6\x21\x3d\x52\x14\x24\x83\xeb\xc9\xf7\x34\x2a\x38\xb9\x5f\x29\x67\xa8\x74\xf1\x26\x61\x34\x18\x4c\xb0\x4d\x78\xa1\x02\x10\x8d\xcb\xd2\x71\xf9\x33\xdc\x32\x55\xcf\xab\x2c\x7f\x19\xc5\x4d\xdf\xca\x2e\xc8\x5f\xaa\x1c\xda\x5f\x40\xb6\x17\x2b\x71\xe5\x4a\x35\x11\x42\xad\x6b\x38\x23\xbc\x91\x92\xb8\x79\x54\x6f\x71\xe4\xe6\x52\x69\x16\x13\x38\x66\xbb\x5d\x26\x8d\x6f\xa3\x63\x92\xec\x76\xf9\x30\xce\xae\x36\x51\x4e\xbf\xbf\xfb\xd1\x14\xf9\x59\xab\xb5\x14\xaf\xd9\x32\x15\x09\xb2\x4b\x47\x64\x5c\xc2\x6a\xd6\x30\x45\x33\x58\x9f\x54\x1d\x7a\xac\x8e\xfd\xa0\xc0\x29\x64\xe4\xc5\x8d\x2c\xf5\x99\xf9\xdc\x65\xaa\x9a\x33\xde\xb9\xcd\xdd\x9a\xe5\x1c\x7e\xd1\x60\x50\x73\x2b\x20\xb7\x4f\x02\x36\x69\xe7\xd5\x6f\x92\x82\x93\xac\x75\x3f\x3f\xef\x50\x5c\xa9\x33\x72\x9c\xcd\x39\xe7\xe1\x54\xc6\x3a\xa2\x73\x16\x62\x69\x52\xeb\x48\x38\xb2\x8a\x5b\x93\x2c\x21\x3b\xd2\xf8\x56\x44\xc4\x49\x11\x55\xc1\x2d\x61\x78\x43\x12\x2c\x21\x44\x9e\x6d\xd9\x02\x6e\x7d\xf5\x12\xb1\x45\x76\x05\xd1\x63\xb8\x19\x6c\x25\x77\xb1\xa2\xc1\x0a\x19\x31\x07\xc7\x84\x4d\xe3\xa3\x64\x1a\xfb\x3e\x12\x74\x57\x1c\xe2\x42\x2c\xa3\xe7\x89\xba\x23\x9f\x4c\x70\x8c\xa6\xea\x59\x3e\x2a\xc6\x4c\xe4\x4f\xa6\xa6\x67\xe9\x60\x82\xb0\x7a\x49\xfd\x09\x4e\x94\x37\xd3\x2d\xde\x94\x6c\xf8\x69\x9b\xc4\x1f\x3f\x64\x79\xd3\x8a\x43\x65\x1f\x57\xd1\x80\x26\x86\x25\xf1\xbc\xc3\x85\x5f\x17\xdd\xa3\x10\x9d\x84\x45\xf9\xdd\x40\x41\x5c\x80\xc4\x4e\x97\xf1\x36\xc4\x2a\x0d\x0a\xca\x01\xb2\x58\x94\x40\x2c\x2a\xdc\x68\x70\x9d\x7e\x02\x02\x4b\x97\x69\xb2\x97\x03\xb1\xd8\x00\x55\x5d\x76\xfd\xe2\xb8\xe7\x4d\x9f\x93\x0e\x0f\xb9\x52\x28\x92\x2b\x8a\xd0\x7a\x51\x7e\xcd\x36\x52\xe5\x02\x49\x8e\x44\x5f\x90\x84\x54\x56\x5b\x48\xc2\x6a\x03\x19\xe6\x28\x10\x8f\xa9\x7c\xac\x96\x3e\xad\x37\xfb\xd5\x0d\x6a\xaa\x3f\x17\x08\xf9\x49\xbe\x82\x0c\x03\xcd\x28\x06\x82\x88\x71\xd3\xb5\x7f\x78\x39\x25\x6e\x3a\x13\xc4\x13\xc0\xf3\x10\xe1\xb8\xa3\xc0\x7b\xe5\x5e\x4d\x50\x82\x38\xed\xaa\xf0\x85\xf1\x46\xa7\xf2\x6c\x6b\x79\x8c\x3b\x61\x80\xf0\xa6\xf6\x61\x99\x48\xbf\x42\xa2\x88\x24\x0c\xfa\x9a\xb8\xd0\xbd\x6f\xe3\x67\xae\x43\x69\xc3\x0b\x97\xde\xc7\xa7\xb1\x64\x2c\xe6\x8e\x23\xdc\x58\x86\x3c\x88\x24\x4f\x42\xd1\x1f\x48\x3e\x3b\x79\x54\x42\x17\x43\x27\xf6\xbc\x7c\x98\x14\x27\x97\x45\x96\x6e\xb9\xa8\xac\x91\x40\xd1\x2c\x1f\xe6\x34\x8d\x78\x72\x2d\x2e\x5d\xcd\x18\xd7\xe0\x43\x4e\x27\x49\x2a\x9a\x19\x16\x6e\x3f\x70\x05\x68\xf4\xfc\xd5\xf2\x46\xce\xf7\x48\x37\xf8\x41\xe7\xab\x95\x32\xe0\x11\xee\x1f\x88\x02\x83\xb6\x82\x5f\xde\xbf\x11\x9d\x35\x3e\x62\xa5\xd3\x0b\xbb\xc2\x24\x76\x53\xcc\x9a\x12\xad\xdb\x62\xbd\x42\x93\x6d\xad\xef\x6f\xa3\xcd\x2f\xef\xdf\x18\x8f\x91\x62\x49\xc9\xa6\xda\xdb\x5b\x73\xfb\xd6\xae\x2a\xa2\xef\xdc\xc6\xcd\x64\x92\x75\x00\xc0\x4a\xaf\x26\xcb\x93\x55\xc2\xa2\x54\x96\x6d\x27\xeb\xd2\xd5\x07\x19\x6d\x56\xbc\x56\x1d\xd9\xfc\x0f\x1e\x32\x7d\xee\xc1\x3f\xbd\xab\xeb\x7b\x44\x7a\xfb\xad\xed\x30\x99\xa2\x99\xf2\x2a\x4e\xe2\x60\x62\x02\x25\x8e\x4b\x53\x5c\x77\x47\x9f\x85\xb6\xcd\xf0\x36\x4f\xdb\x9d\xfa\xa0\xba\x24\x7d\x16\x6f\xf3\xb4\xb7\x4c\x68\x2a\xdd\xc1\x9a\xea\x14\x0d\x7e\xb5\x51\x34\x31\x5d\x0c\x6d\xd8\x0e\x3b\x17\x14\x83\x6c\xb9\x94\xf0\x19\xd7\xa7\x4e\xf4\x55\xc2\x71\x37\x51\x75\x5c\xcf\xda\x91\xd2\x9f\x95\x18\x0a\x51\xcf\x9e\x97\x1c\x19\x25\xda\x8e\x0e\x53\x7d\x91\xca\x16\x8b\xde\x95\xa6\x3b\xb2\x7c\x41\x73\xba\x90\x54\x07\xcb\xd8\x20\xbb\xa6\x79\xaa\xb6\xf2\xb0\x72\x69\x50\x10\x86\x2b\xdc\xef\x9d\xac\x23\x68\x20\x83\x99\xdf\xc6\x06\x13\x7f\x52\x62\x13\x80\x43\x42\xf7\x18\xba\xe3\x97\xa1\x58\xc4\x71\x2b\x11\x2a\xe3\xba\xa7\xfe\xce\x38\x1c\xbd\xb4\xe1\xce\x5f\xa1\x8b\xb1\x83\x14\x99\x9d\x44\x0e\xeb\xc9\x17\xb6\x73\x6f\xcd\x51\x95\x47\xa2\xdb\x73\x9c\x53\x14\x83\x76\x51\x80\xef\x5d\xf7\x74\x41\x7f\x8c\x2b\xff\x75\xe2\xed\x01\xbf\xa3\x1d\x3d\x31\xdc\x30\x79\xba\x4c\x22\xac\x03\x96\x26\x3c\x32\x30\xb0\x5d\x5b\x59\xa2\xc6\xd0\x0d\x28\xf8\xfa\x91\x37\x4b\xfe\x73\x03\x6f\xd6\xf6\x4f\x8d\xbb\x59\x59\x6b\xd8\xf1\x3a\xca\x5f\x17\xfa\xf3\x07\xba\x89\xa4\x3b\xcb\x6e\xdb\x65\xcb\xc2\x30\x7b\x5e\xc5\xc2\x66\xbb\x1d\xc0\xf2\xa1\xb1\xc9\x6a\x3d\xee\x8c\x90\x57\x83\x16\x97\x71\x1a\x15\x05\xd5\xe7\xce\xc2\x85\x5e\xbd\x1e\x20\xb7\xf2\x8f\x2f\x4f\x5f\xbe\x3f\x39\x7b\xf9\xc3\xc5\xbb\xf7\x3f\xbc\x7c\x2f\x70\xcf\xe1\xbb\xf7\xaf\x7f\x7c\x7d\x7a\xf2\x46\x27\x1d\x88\x6c\xdd\xf4\x78\xdc\x49\x8f\xbb\x7d\xa7\x51\xbc\xd6\x2d\xee\xe3\x3f\x11\xbe\xdb\x89\x2d\x62\x4c\x68\xd9\x6e\xd7\xea\x97\x36\x85\x6d\xa5\x07\x99\x86\xe8\xad\x7d\xe9\xda\xbf\x35\x87\x64\x4b\x35\x57\xb5\x61\x30\xd6\x71\x3d\xa8\xe8\x8e\x12\x90\xf5\xb2\x65\x4f\xb9\x2d\xd5\x8e\xb7\x15\x91\xd0\xd8\x41\xd3\xac\x0d\xea\xb5\xaa\xad\x96\x96\xe9\xcc\x33\xf1\x1e\xd4\x91\x8a\x48\x86\xc2\x51\x36\x0e\x7a\xab\xdc\xab\xd7\x80\x93\x0e\x7c\x22\xc2\xbc\x03\x21\x40\xb8\x0e\x3c\x9b\xe4\x6b\x13\x90\xb6\x49\x57\xf7\xd2\x0f\x68\x0d\x07\xc0\xf5\x9b\xdf\xf9\xaa\xcb\x8a\xeb\x31\xb0\x63\x65\xd2\x55\x5a\x35\x52\x79\x79\xaa\x71\x8a\x47\x01\x9c\xe5\x08\x90\x43\xa3\x27\x0d\xa0\x1b\xa5\x69\x9b\x8e\x7c\x95\xe5\x1d\xdc\x3d\x17\xfe\xeb\x8b\x8e\x11\x33\x85\xee\x47\x95\x24\x2e\x47\x77\xa8\xbc\x39\x3a\xb7\x88\xbe\x23\xf1\x18\x49\xd1\x3d\x33\xb8\x92\x1a\xd8\x32\x61\x0b\xb5\x30\x52\x8d\xcb\x7e\x46\xd8\x3c\x59\xfe\xcb\x3c\xd4\xec\xa8\x79\x88\x23\xa7\xb8\xde\x95\x50\x7b\xfd\x6e\xed\x56\x0c\xdc\xce\x82\xea\xf5\x85\xee\x99\x43\x78\xbf\xd3\x9f\xec\x7c\xe1\xac\x7d\x76\x95\x82\xf7\x31\x19\x1b\x89\x6c\x77\xbb\xf3\x48\xfa\xdf\xaa\x02\x71\x18\x44\xc0\x10\xba\x31\xa9\xe3\x89\xd3\xc2\xf3\x1a\x98\x23\x21\xf1\x14\x25\x8a\xd5\xa0\xd0\x25\x3b\xb5\x05\x06\xb5\xfd\x69\x28\x99\xb8\xb1\x04\x6e\x3e\x33\x62\x4d\x17\x45\x05\x6f\x2e\x58\x81\x81\x48\xfe\xb1\xb3\x44\x59\x49\x8f\x5a\x83\xf5\xfd\x28\xac\x14\x5c\x14\x2d\xde\xc4\x77\x3b\x07\xc8\xdd\x34\x8d\x17\x93\xf4\xff\xd0\xa8\x4b\xcb\xed\xc3\xac\x1d\x0e\x89\xc4\x38\xdd\xeb\x5f\x36\x76\xfd\xcb\xa6\x0d\xff\xb2\xed\xd2\xad\xe3\xd2\x29\x3d\xa1\xf2\x98\x49\x8a\xbe\x01\x64\x35\xbd\x60\x89\xc0\xc6\x67\xcc\x50\x83\xc8\x93\x02\xba\x96\xb0\x4b\x7f\x73\x94\x55\xc4\x92\x73\x32\x9e\xf2\xa3\x4e\x1a\xd0\x48\x19\x7d\x9f\x23\xe3\x06\xbb\x99\x67\xce\x43\x42\xaa\xc8\x49\x53\xc3\x73\x2d\x71\xfa\x20\x0e\xaa\x70\x85\xfa\xb4\xa6\xee\xb4\x66\x84\x75\x91\xb7\xd4\x00\x55\x4b\x91\x4a\x1a\x36\x12\xb9\xbb\x48\x5c\xda\x41\xc3\x4a\x86\x2f\x73\xe9\x51\x9b\x4b\xcd\x67\x93\x30\xa5\xd5\x0d\xfc\xa1\xf6\x05\xb2\xae\xea\x59\x0d\xc5\x62\x8a\x54\x95\xbb\x20\xa5\x98\xb5\xc8\x59\xd6\x26\xbe\xbb\xaa\xfd\x1a\xca\xdb\xed\x81\x21\xc2\xa7\x15\xfc\x72\x22\x2f\x39\xf5\x6b\x49\x21\xde\x88\xe6\x3b\x50\xfc\x79\x88\x97\xf2\x53\x0b\x05\x9e\x87\x78\x41\xc6\x78\x4d\x62\xb3\x65\x16\x47\xeb\xe9\xc2\x78\xca\xbc\x24\xf1\x7c\x11\xe2\x2b\x49\x45\x6e\xa7\x57\x0d\x12\xfd\xb2\x71\x61\x5f\xb5\xa8\xf5\xcb\xd6\x95\x7d\xa9\x07\xe8\x79\xf0\xca\xdc\x4c\x91\xdd\xda\x97\xf6\x36\xba\xaa\x83\xad\xcb\xfa\xe5\x7e\xd5\x04\x60\x97\xcd\xeb\xfd\x52\xde\xdb\xb2\x15\x49\xea\x67\x4e\x1b\xf2\x46\x47\x78\xa9\x55\x2e\x11\xc2\x1b\xf3\x68\x60\x4b\x01\xbb\xe6\xeb\xc1\x9b\x4b\xfa\x25\x4b\xbb\x89\xb0\x6e\x2a\x23\x75\xa9\x0c\xc3\x77\xdb\x17\x3c\xb6\xfb\xa0\x1b\x21\x71\x59\x07\x67\x0f\xa2\xe6\x55\x64\xe8\x0c\x27\x4a\xed\x97\x4c\xf0\x92\x8c\xf5\x5e\x18\xe3\x4b\x32\x96\x1a\xe0\x6f\x2b\x09\xec\x8a\x8c\xf1\x1d\xb9\x2f\xb1\xb4\x4a\x3a\x11\x3b\xe7\x82\xcc\xc3\xe9\xea\xe8\xed\x54\x7a\xf4\x9f\x2a\x97\x51\x9a\x84\x58\x21\xb4\xf1\x7d\xbc\xf2\x7d\x51\x71\x15\x54\x07\x37\x73\xad\x7c\x5f\x39\x9a\xd5\x2a\xe6\x72\xa7\xa1\xc6\x46\xdb\xe0\x98\xac\xa6\xf1\xd1\x5b\xcf\xeb\xab\x79\xe8\x26\x6b\x20\xc5\x31\x92\x0c\x6c\x29\x49\x22\x77\xf3\x8c\x18\x2d\xd2\x15\x8e\x51\x88\x56\x3e\x31\x3e\x09\xab\x66\x13\x35\x90\x78\x8a\x22\x2b\x0b\xc6\x2b\x7c\x8d\x70\x4a\xae\x95\x84\x16\xaf\xc8\xb5\x14\xb9\x62\x7d\x4d\x2a\x7e\xe4\x81\x74\x44\xaa\x85\x78\x2d\xb4\xfc\x55\xb6\x65\x8b\x5e\xa4\xe3\xd9\xe1\xde\xe5\x96\xf7\x58\xd6\x13\x17\xac\xe4\x35\xb8\xdc\x8c\xc3\xaf\xa8\x49\x16\x96\x36\xc3\xa6\x4a\x5b\xd3\xdd\x3c\x0b\x49\x52\xb2\xd6\x49\x5c\xfa\xc9\x7c\xac\xe0\x40\xf3\x48\x26\xae\x81\x89\x45\x17\x2f\xfd\x64\x3e\x09\xf1\xa5\x4f\xe4\x2f\xab\x9f\xc7\x85\x9f\xcc\x0f\x04\xf0\xa8\xa7\x37\xb2\xf9\x52\x36\xda\x38\xaa\x6b\x3f\x99\x1f\x86\x78\x4d\x9a\x5f\xaa\x8e\x3c\x91\x1d\x91\xe7\xf6\xca\x4f\xe6\x4f\x42\x7c\x25\xba\xf1\x24\x44\x08\x5f\xd8\x60\x2a\x6d\x1d\xd2\x7a\xeb\x56\xbb\x9c\xa1\xb2\x80\x17\xf8\x41\x79\xcf\x0f\xb4\x2e\xef\xe9\x00\xa3\x17\xb8\x80\x27\x9f\x01\x01\x7b\xc8\x72\x72\x52\xb6\xf1\x8a\x6e\xfa\x53\x7a\xe2\x57\xe1\x25\xe8\x9c\x85\x47\x64\x8c\x3a\x85\xe6\x62\x84\x96\x83\xb5\x92\xf7\x70\xde\xe3\xeb\x48\x50\x81\x3d\xfa\x69\x1b\xa5\x3d\x9e\xf5\x26\xb8\xb7\xca\x78\x0f\xf8\xca\x06\x49\x56\x9a\x87\x47\x7b\xea\x54\xeb\xf0\xf9\x5a\xc7\x55\xad\x79\xe8\xe8\x0d\x29\xe9\x8b\x1c\x87\x18\x43\xd9\x40\xb1\xe4\x5d\xa7\xda\xf8\xb0\x89\x58\x2d\x00\x4e\x15\x75\x7c\x3c\x35\x3a\x38\xad\x25\xa8\xf0\x9a\xba\xbb\xf3\x76\xce\x39\x95\xb4\x00\xf5\x27\x9f\xa9\xab\xe6\xaf\xbc\xab\x1e\x7f\x22\x6b\x6a\x48\x52\x09\x71\x0f\x92\x48\x41\xf7\x7c\xd8\x81\xd3\xb6\xcf\xdb\x60\x32\x8d\x33\xc6\x13\xb6\xa5\x65\xd9\x5d\x66\x32\x1a\x97\xf5\xc9\xcb\x1a\x5b\xad\x9b\xac\x6c\x70\x23\x3b\xa8\xcc\x26\x4d\xdd\x41\x38\xa2\xd2\xb8\x91\xae\x51\x7b\x86\x82\x6f\x4d\x51\x8b\x40\x68\x13\x02\x5f\x74\xf2\xb0\xdb\x97\xcb\x24\x2a\xc0\x1e\x06\x8f\x0a\xba\xcb\x2c\x3d\xb8\x97\xd7\xa2\x1d\x32\x67\xad\xa5\xe3\xcd\xa5\x53\x74\xae\xed\x40\x66\x09\x6f\x2d\x7a\x52\xd8\x3d\x49\x3c\x0f\x26\xa4\xc5\x0b\x49\x14\x9b\xba\x85\xcc\x35\xd1\xfd\xa4\x8b\x09\x82\xb4\xa2\xbd\xdb\xb8\x80\x7c\xa6\x69\xa3\x30\xa5\x7a\x10\x79\x1e\x34\xb4\xb8\xe5\x51\x44\x08\x61\xc3\x3c\x48\x70\x9d\x7e\xcb\x9a\xd4\x78\x37\xf9\x96\xb5\xa9\x74\x95\x51\xb2\x49\xa2\xd2\x44\xa2\x31\xcd\x48\xde\xa9\x6c\x49\x3e\xe9\xea\x54\xe8\x0b\xc3\x58\x69\x6c\xe1\x75\x64\x90\xef\xe2\xdd\xf2\x24\x4d\x0d\xca\xdc\x42\x75\xfa\xfd\x0e\x19\x93\xf6\x4f\xde\x1d\xbd\xba\xb1\x24\x45\xf2\x27\x85\xc8\xe0\x0a\x8d\x22\x45\x76\x45\x3b\xb1\x71\xc5\x0b\x52\xb6\x2b\x6e\xbf\x55\x79\x5d\xfc\x55\x8b\x77\x9a\x2c\x61\x57\x3b\xc8\xa9\x75\xea\x82\x98\x26\x03\x86\x56\xbb\xd9\xc5\xf4\xea\xb5\x19\x07\xe6\x19\x4e\x1e\x26\x37\x93\x87\xc8\xcd\xc4\x4a\x9e\xdb\x05\x33\x92\x0f\xb7\x79\xfa\xb3\xc0\x1b\x9b\x05\x11\x32\x9a\x06\x89\xe3\x59\x46\x10\x45\xc1\xf9\xe8\x7c\x24\xbd\xcb\xa8\x50\xcc\x49\x4a\x01\x21\xd9\xb0\x88\xd7\x54\x60\xdf\x6d\xe2\x36\x42\x0f\x0d\xb3\x9b\xe0\x8d\x90\x3c\xc7\xb0\x9f\x0d\x37\x11\x5f\xef\x76\x60\x24\x5b\x11\x2f\xa8\xab\x11\x30\x02\x7e\xf2\x0f\x34\xa4\xca\x85\x32\xba\x70\x6d\x01\xbb\x14\x4d\x93\xb6\xa2\xa9\xa5\x99\xa5\xba\xa9\xbb\x89\x56\x4d\xb0\xf7\x79\xbe\xa0\x61\xfd\xc9\xa1\xf3\x3d\xbb\x87\x23\x64\xf9\x75\xf7\xdd\xe7\xd1\xe1\xbf\xc8\x53\xa9\x77\xa3\x65\xd8\xd6\x59\x8b\x1d\x77\xc6\xe7\x79\x8d\xa8\xc4\xd9\xff\x18\x83\xf0\xeb\xae\x89\xcc\x5e\x13\xc9\x3e\x9e\x52\x16\x2a\x27\xb0\x1a\xf1\x15\x37\xbb\xa6\x42\xdd\x79\xb5\xcd\x26\x5f\xc8\x11\x4b\xbe\x8a\x23\x96\x3c\xc8\x11\x2b\xbf\x6a\x85\x4b\xcc\x86\xdf\x47\x45\x12\xb7\x99\x63\xa9\x20\x75\xbf\x84\x39\xb6\xd9\x13\x7c\x29\xae\x7d\xf9\x2c\x89\xbb\xf9\x22\x12\xb7\x42\xfe\xe6\x21\x76\xf9\x5a\x46\x92\x6c\xfd\xac\xf8\x3e\x6a\x44\xd6\xaa\xe5\x9b\xf3\xd0\xb2\xf2\xcc\x91\x77\xfd\x7d\x50\x6d\x56\xf2\xd9\x42\xae\xc5\x3e\x15\xd4\xf5\xe6\x7f\x11\x19\xb3\x88\xb5\x95\xa2\xe8\x9e\x63\xf8\x05\x6a\x80\x03\x07\xdb\x51\x52\xeb\xfa\x77\x8b\x61\xec\x76\x2d\x09\xcb\x43\x65\x55\x8e\x52\x5a\xaa\x36\x26\x94\x59\xbf\xc7\xc9\x2c\xa9\xe6\xb6\x63\xde\x34\xbb\xb9\xd1\xa5\x01\x4c\x1e\xee\xf3\x60\x62\xcf\x5b\xab\x47\x9f\x2d\xdc\x46\x00\x67\x0f\x94\x30\x48\x7b\x30\x46\x58\x80\x9b\x80\x0e\xc5\x4f\x89\x82\xaf\xc4\x85\x36\xff\x08\x2e\xd4\x6b\x9c\x03\x7a\x4d\xf3\xbb\x4e\xf4\xa5\xe2\x61\xef\xab\x1d\x22\x89\xdb\x6c\xbe\x1c\xb7\x79\xe8\xa8\x75\x45\xb4\x6b\xee\x82\xe6\xb1\xaa\x1a\x82\x54\xf2\x72\x93\x25\xcc\xad\x7e\xf8\x97\x5d\xbb\x1d\xf6\x1d\xf5\x6b\x77\xf3\x35\xd7\x6e\xe5\xcb\xe9\x61\xa0\x53\xa3\x12\x1d\xc0\xe1\xf8\x1d\xb7\x63\x6d\x5d\xd2\x5d\xb7\x3a\xaa\x42\x69\xd8\x82\x5d\xbd\x35\x16\x31\xb5\xbb\x28\x93\xca\x2e\x3e\x64\x5f\x7c\x4a\x32\x2d\x0b\xfb\x6c\x19\x22\x10\x2b\x51\xfb\xec\x81\x8c\xce\x99\x28\x1f\xbe\x9b\x1a\xfb\xfe\x33\x2a\x03\x7b\x18\x2f\x56\x1f\xbb\x8b\x81\x3d\xfd\xd2\x4d\x6a\xf2\x65\xed\x7d\x8a\x13\x92\x39\xeb\xd7\x26\x71\x95\xc7\x80\xc4\x5a\x6f\x99\x1d\x11\x93\x64\x1e\x85\x38\xad\x15\x77\x28\xc3\xd8\x4a\xc9\xd3\x2e\x02\x31\x6b\x1e\x10\x89\xa6\xa7\x9d\xb2\xf2\x06\xd5\xb9\x58\x40\xa9\x69\xd9\x8d\xc8\xa6\x8a\xaa\xdc\x4a\x61\xfe\x34\x36\xbc\xf0\x6d\xad\x9f\x96\x7e\x54\xdf\x6b\x9a\x89\xb2\x81\x2d\xc2\xdb\x1a\xad\x69\xaa\xdf\x6a\xaa\x75\x63\xb1\xc8\xb4\x21\xcb\x8f\xeb\xbb\xca\x77\x89\xf0\x7d\x5b\xb5\x79\x1d\xc6\xcd\x0d\xf7\xd9\x5a\x08\x21\x8d\x86\x67\x0f\x94\x70\x21\x7b\x0d\x07\x8e\x1f\xd4\x24\x88\x3b\x35\x09\xb6\x46\x97\xae\x83\xd3\x24\x71\x8e\x4d\x17\xc3\x72\xd3\x60\x58\xee\xd9\xe6\xa6\x86\xd2\xe8\x05\x75\x6c\xd1\x2f\xe4\x6e\xda\x1a\xbe\x4e\xb6\x21\x50\xca\xd7\xca\xa6\xad\x8d\x54\x6e\x94\xd6\x7b\xa5\x6b\x1d\x3c\xfb\x16\xd7\x15\xac\x83\x67\xdf\xe1\x96\x96\x76\xf0\x5c\x46\xa0\x74\x74\xae\x83\xe7\x87\xb8\xa1\x3f\xbf\x2f\x88\x74\x87\x0e\x77\x56\x53\x0c\xff\x02\x0d\x70\x2d\x4b\x1b\xa8\xb8\xaf\xae\x26\xff\xd4\xf1\x02\x49\xd1\x3d\xdd\xed\x20\xad\x1c\x81\x4a\x81\x20\xc9\x1c\xb0\xee\xe8\x29\xd7\x4e\xaa\x14\x52\x66\x2d\xf8\xef\x6a\x4b\xeb\xec\x1f\x93\xcd\xaf\x51\x9a\x2c\xa4\xda\x4e\xbd\x48\xed\x13\xc0\xfd\x49\x53\x35\x78\x8f\xda\x67\x53\x2b\x57\x59\xdf\xd6\x8a\x1a\x3c\x41\xa9\xc2\x16\xdd\xa8\x7d\xb1\x57\x20\x5c\x79\xad\x75\xa5\xb0\xb2\xa1\x02\xde\x4b\x0e\x01\x95\x52\x54\x5c\x7d\x0f\x78\x59\xa1\xd6\xae\x22\x56\x5b\x19\x29\x77\x90\xe8\x40\x5d\x30\x4d\x25\xa1\x78\x8f\x6e\x50\x59\x6a\xa6\x1d\xad\x04\x8e\x06\xca\xda\x34\xc3\x0d\x71\xbf\x65\x0e\xff\x04\x9b\x54\x84\x70\x85\xbe\x12\xd3\x93\x1a\x94\x88\xbb\xf5\x8c\x4a\x6c\xba\xa1\x61\x70\xae\xe4\x1a\xd4\x48\x21\xa5\xd5\xb3\x99\x81\x5c\x2a\x5d\x53\x4b\xba\x18\x65\xa3\x6a\x66\x72\xcb\xac\x34\x4c\x49\xc5\xf6\xa9\x77\x5b\xd6\x5b\x63\x89\x24\x68\xb7\x63\xf5\xfb\x23\x41\x36\x28\x5e\x0b\x3d\xcb\x0d\xcf\x33\xf2\x3c\x36\x2c\x28\xff\xe0\xe6\x80\x39\x8e\x64\x4f\x59\x89\x8b\xba\x95\x52\x5b\xa8\x61\xf6\x88\xbb\xa5\xed\x62\x49\xc5\x27\xf7\x8b\x99\x3d\x73\x3a\xf2\x8e\xd3\x63\xbe\x25\xb5\x6f\x2e\xd3\xb4\xeb\x4c\x19\x3d\xcb\x6b\x95\x42\x2b\xc6\xb6\x94\xb9\x18\xd6\x98\x8c\xab\xac\x7d\xc4\xc1\xbc\x4b\x3f\x23\x47\xa6\x2a\x77\x36\x73\xcb\x5c\x53\x5c\x62\x5d\x43\x52\xbf\x56\xcd\x52\x34\xaf\xda\xc4\x6a\x82\x58\xf9\xbe\x48\x6e\xd0\x90\x5c\x79\x0a\x6e\x5e\x94\x5c\x23\x77\xf5\x5b\x4c\xdb\x98\x88\xf5\x4b\x3b\xae\x31\xe7\xb3\x2e\x6d\xd4\xcf\xd4\x85\x96\x94\xa8\xbe\xb8\xcd\x4d\xd0\xad\x43\x3a\x75\x18\x8c\x17\x0d\x4d\x98\xac\xc1\x9a\xbc\x68\xa8\xc2\xe8\xa2\x33\xd8\x09\xa2\xac\x09\x57\x13\x74\x75\x38\x23\x40\xdd\x50\x6e\x9e\xd5\x8c\xcd\x19\x0a\x09\x47\x41\x67\x56\xcf\x83\x3a\xb4\xfc\x17\xd6\x84\xc7\x95\x8b\x8c\x8f\xf4\xae\xe8\xee\x2c\xb2\xee\x66\xf7\x0c\x46\x75\xbf\x71\xac\x36\x9b\xf4\xae\x5b\x1f\xa7\xba\x0e\xb9\x61\x0b\x4b\x67\x55\xf6\x59\x81\xdf\x96\x44\xf9\x91\xad\x4e\x23\x0b\x59\xbe\xb7\xc1\x5e\x4e\x3f\x6d\x93\x9c\x16\x3d\x9a\xf0\x35\xcd\x7b\x11\xeb\xd1\xdb\x4d\x9a\xc4\x09\x37\x12\x69\x09\xe3\x7b\x59\xae\xec\xed\x55\xda\x55\xb4\x39\x7f\x54\xf4\xd4\xdd\xd8\xdb\x18\x47\x1b\xbd\xef\x33\xbe\xee\xdd\xd0\x9c\xf6\xb2\xab\x84\x73\xba\x18\x3e\x42\xd3\x5c\xf7\xd4\xd5\x56\x75\xf6\x47\x05\x8d\x60\xee\xee\xa3\x48\xfa\x06\x51\x5a\x81\xea\xce\x8b\xb5\xc9\x43\xe3\x34\x35\x8c\x30\x1d\x88\xaa\x66\x8b\x57\xec\xbf\xdc\xf3\xf4\x4e\xac\x41\x78\x03\x78\x3b\xf9\x3f\x96\x8f\xd1\x75\x27\xf0\xe6\x9d\x60\x80\x6b\x52\xdd\x4d\xb6\xfd\xa4\x7e\x37\x31\xf7\x5b\xa6\x23\x83\x63\x5e\xdd\x4b\xd5\xc4\xf0\x8e\x2b\x2c\x72\xb3\xd6\x7b\x47\x12\xed\x77\xbc\x29\xa0\x4f\x0c\x40\x30\x9d\xd4\x37\x17\x57\x37\x57\xa2\x6f\xae\x52\xe9\x1c\x9a\xfa\xa7\x6a\xbf\xa5\xbb\x9d\x82\x72\x29\x12\x4f\x8a\x4e\xd1\xc4\x88\xaa\x40\x67\xdc\xee\x76\xb1\xcc\xb8\x45\xe2\x49\xd1\x1b\x46\xcb\xb6\x81\xdf\x14\x35\xdc\x26\x7e\xf0\x82\xe4\x16\x3f\x6c\xdf\x6a\xdc\x4c\xbc\x0c\x80\x5c\xcd\xaf\x33\xb1\xf5\x19\x6d\x4c\xa5\x35\x88\x6a\xde\x87\xf2\xca\x35\x9d\xaf\x1f\xde\xe6\x7d\xd3\x12\xf7\xab\xed\x57\xb9\xc4\xaa\x3c\xb3\x70\x6d\xd3\xd2\xf5\x65\x9f\x8d\x8b\x59\xcb\xa1\xd5\x32\xb1\x29\xaa\x48\x2f\xca\xa9\x64\x9e\xa8\x4a\x8b\xde\x60\xd0\xbb\xcb\xb6\xe2\x7c\x5e\x46\x97\xe9\x5d\xef\x8a\x46\x8c\xf7\x78\x26\x4f\xa7\x3c\xcf\xa6\x86\x9e\x3e\x4d\x3d\xca\x78\x92\xd3\xf4\x4e\xd5\xcf\x44\xa1\x68\x23\xb3\xda\xab\xa9\x67\xbc\xdd\x0f\x7b\xaf\x97\xbd\x22\xc3\xbd\x4d\x54\x14\x92\xad\x23\x0d\x86\x3a\xeb\x4d\x58\xc1\x69\xb4\xe8\x65\x4b\x01\x63\xb4\x03\xa2\x9b\x84\xaf\x7b\x32\x56\xb1\x80\x2f\xb2\x02\xa9\x92\x53\x68\x3f\x0e\xb0\x0f\xc5\x1c\x49\x9e\x6a\xc2\x7a\x54\x86\x90\x96\xcc\x53\xf5\x46\xe5\x54\x1c\x8f\xc5\x93\xfa\x70\x4c\xc6\xe2\x0a\xde\xed\xd8\x6e\x97\x23\xcf\xfb\x4c\x05\xdc\xf9\xc8\x6b\x1f\xf9\x9e\xda\x3d\x8f\xdb\x64\xee\x26\xb3\x07\x3c\x4a\xe8\x49\x08\x7a\xc0\xff\x97\x0f\xef\x4e\x9d\xf8\x6a\x0e\x12\x6c\x10\xe9\xa0\xba\xec\x03\xae\x2e\xec\xbc\x6c\xde\x1b\x17\x05\xcd\x13\x69\xc6\xd8\xe6\xb8\x38\x4c\x77\x65\x54\x8c\x23\x32\xc6\x05\x99\xe0\x98\x8c\x71\x4a\xc6\x78\x4b\xc6\x78\x43\xc6\xd2\xd9\x19\x5e\x90\x06\x3c\xad\x94\x26\x95\xc2\x98\xf1\x5a\x39\x5d\x1f\x5d\x4e\xd7\xbe\xaf\x14\x58\x44\x51\xc8\xc9\x62\xbe\x0e\x1b\x3a\x5d\x32\xae\x98\xe8\x42\x44\xc6\x53\xde\xfe\x36\x45\x54\x46\x72\xc7\x85\x56\x10\xeb\x25\x4b\xb8\x3e\x1e\x2b\x81\x6b\xf6\x45\x76\xe8\x1c\x2f\xe6\x32\xf4\x2c\x32\x0a\x17\x53\x51\x29\x06\x25\x75\xfd\x93\xb4\x38\x02\x11\xea\x32\x8a\x37\xe8\x49\x05\xb3\x9b\xaa\x00\x86\x3d\x62\x41\x2e\x76\xdb\x49\x06\x1b\x24\xad\xb3\xeb\x8d\xbb\x20\x79\x30\x19\x28\xa6\x4e\x23\x75\x4f\x11\xdd\xdd\x18\xe1\x98\x34\x53\x6d\x6f\x35\xf0\x66\x9d\x8c\x1c\xae\x39\x3f\x6e\xfd\x6c\x20\xf9\x3e\x02\x21\x5b\xfa\x84\x1a\x8d\xc8\x65\x63\x6f\x75\xeb\xd5\x76\x1b\xac\xd1\x4e\xb3\xc2\x7e\x37\x86\xe4\x32\x80\x2b\xfa\xac\x41\x98\x19\x73\x4b\x81\x54\x76\x7b\x31\xfa\x22\x7f\x5f\x9d\x3d\xc0\x0c\xcd\xba\x91\x3e\x16\x2a\xa6\x66\x27\xa0\xe7\x99\x38\xb6\xee\x09\x53\x22\x2d\xeb\x92\x93\xbb\x36\x9e\xfa\x1c\x17\x0d\xcb\x1a\x47\x17\x59\x2c\x54\xcd\x1a\xa5\xfa\x66\x4e\xa1\x75\x09\xd5\x38\xe6\x10\x95\x75\xbd\x91\x8a\x6b\x21\xa6\x52\xe9\x35\x57\x69\x35\xad\x80\x3a\xd2\xee\x12\xf6\xad\xef\x7b\xb0\x6c\xa7\x98\xdd\x16\x75\x0d\x9d\x86\x2e\xb6\xcd\x8d\x69\x4d\xeb\x00\xd3\xe6\x0c\xef\x8d\x6e\xd2\x80\x98\xb2\x39\xb5\x20\x10\xa1\x9a\x9d\x80\xc5\x77\x49\xf1\xc5\x6c\xab\x1a\x9f\x28\x78\x7e\xd0\xe4\x51\xed\xf5\x9d\xa8\x82\x6e\xca\xa6\x07\x57\xd1\x66\xb0\x32\x8d\x03\xd4\xd1\xa3\x16\x03\x6b\x04\xcf\xf3\xd9\x39\x43\x23\x1c\x11\xf0\xcd\x37\xdf\x24\x85\x2a\x74\x9a\x2d\xe8\x37\xdf\x7c\x03\x6a\x5c\x2a\xad\x3c\x98\x69\x46\x7a\xbc\x4e\xd2\x45\x4e\x99\xe5\x9e\xd7\xb0\x21\x19\x36\x40\x26\xa7\xc6\x60\x9a\x10\x6d\x01\xd5\x08\x45\xa3\x48\x0a\x6d\x1c\xd5\xb2\xbe\x26\x84\xa9\x4f\xac\x61\x57\x4d\x48\xa6\x3e\x64\xf2\xc3\x3c\x92\x31\x81\x2c\xfa\x25\x33\x2b\xba\xb9\xd4\xfc\x25\xb9\x7a\xbf\x25\x7c\xfd\x39\x52\x47\xb2\x97\xa4\x7b\x28\xe5\x8d\x28\x41\xfa\xd2\x6a\xef\x0b\x0a\x91\x0f\x29\x44\xbb\x1d\x70\x3d\xbe\xd0\x2a\x47\x7c\x14\x19\x4f\x37\xd1\x3c\xf6\xfd\x30\x50\x06\x44\x65\x89\xb7\x64\xa2\x6f\x40\x09\x8c\x8c\x44\x6e\x3f\xcf\xca\x2a\xe6\x90\xa5\x82\x70\x70\x7b\xd4\x60\x58\xd9\x70\x9d\x90\x91\x68\x1e\x87\xb2\x63\x95\xcb\xd1\xb6\x04\x76\x63\x21\x9a\xc8\x4e\x98\xc9\xdb\x95\x13\x6f\x3a\xfc\xbb\x2c\xe0\x12\x73\x84\xc5\xa8\xe0\x92\x50\x54\x8a\x84\x14\x22\x84\xb7\xbe\x2f\xc6\x27\x83\x0c\x4d\x5b\x3d\x9d\xa2\x5c\xa1\xef\x3a\xab\xc0\xb5\x36\x47\xad\xfa\x0d\xe5\x6f\x06\x33\x55\xa5\xd8\x03\x63\x42\x08\x7f\x66\x2c\x9d\x23\x29\x97\x84\x5a\x02\xa1\x5a\x36\xcf\x83\x4b\xcf\xb3\x83\x52\xcd\x47\xc6\x15\x76\x5c\xb9\x69\x97\x14\xd0\x7e\xc2\xc1\x12\x78\xbc\x43\x5a\x69\x29\xb6\x1a\xe1\xe0\x50\x64\x8a\x45\xd8\x22\x0c\x28\x4e\xa4\xe3\x4e\x9c\xbb\xe1\x69\x8c\xe2\x98\x31\x3f\xdc\xed\x1c\xa3\x35\xa3\x7b\x22\xc7\xc1\x95\x4f\x62\xdd\x33\x36\xab\xda\x33\xf9\x02\xf3\x64\x26\x5e\xf2\x5e\x1b\xcc\xc9\x96\xf5\x63\x82\x39\x36\x2c\xc8\xb2\x6c\x71\xf1\x9a\x3e\xbd\x6a\xee\x42\x21\x45\x88\x76\x4f\xa0\x3d\xd5\xd4\x52\x43\xaa\xff\xe2\x30\xd0\x79\x14\x7a\x5e\x87\x2b\xe1\x6e\x65\x64\xeb\xcf\x2d\xea\x55\x50\x0f\xf7\x54\x71\xc9\x6b\x88\x04\x31\x93\x47\x77\x82\x5e\xa8\xb2\x14\x92\x2a\x51\xd9\x8a\x61\xef\x47\xa5\xa8\x8c\xa6\x46\xbc\x62\x00\xa3\x0d\xbe\xeb\x48\xda\xeb\x13\xa1\xa3\x9c\x7c\x76\x32\x2a\x21\x72\xe5\xc4\x66\xca\x8f\x05\x62\x3b\x18\xc8\x98\x5d\xa6\x2a\x48\xe7\x3c\xfc\x7f\xce\x94\xd4\xe7\x63\xcb\x8a\x75\xb2\xe4\x0f\x4e\xc9\x4d\x94\x7e\xec\x16\xa0\x4b\x0f\xe5\x5a\x07\xc0\x56\x69\xc4\xaf\x47\xb9\x14\xc1\x1a\x35\x36\xf3\x7d\xce\x42\x34\x8f\xc2\x19\x57\x01\xdc\x29\x0a\x00\x50\x1c\x6d\x81\xe3\x59\x0d\xb5\xea\xca\x51\x6a\x16\xf6\xde\xb2\x0c\x96\xea\xbe\x52\xb4\x90\xbd\x8a\x9a\x4c\x4c\x71\x7a\xba\x8c\xf8\xf6\xf5\x3c\x59\xc2\x5c\x10\x1d\xca\xe0\x6e\x1e\x62\x25\x65\xce\x07\x13\x15\x3f\xc8\xd1\x27\x72\x07\x85\xb9\xd9\x5d\xd3\xfd\x59\x6a\xb7\x34\xdf\x3f\xe7\x5a\xe5\xf2\x7d\xb2\x5a\x77\x33\x5d\xeb\x75\x77\x8d\x63\x30\xb1\x1a\x39\x4c\x4c\x38\xab\x55\x2a\xeb\x0a\xda\xfe\x4e\x74\x18\xb7\xcf\xd5\x4c\xaa\x38\xf5\xb2\xa2\x8e\x53\x06\x40\x2d\x8b\x1a\xfc\x57\xb1\x97\x3b\x50\x98\x79\x13\xf5\x0f\x09\x6f\xef\xd6\x0f\x75\xb4\x67\x8f\xf2\x07\x66\xdd\xeb\xcf\x8f\x98\xd4\xff\x68\x4c\x44\x28\xcf\x6d\x33\xb1\xa3\x3d\xe3\x6d\x35\x6f\xb3\x86\xeb\x83\xb1\x36\x9d\x98\x91\xbc\xd9\x3a\x85\x99\x42\x91\xec\x60\x73\x01\x47\xba\xf0\xba\xb9\xf8\x12\xb6\x48\x93\x36\xe2\xac\x88\x93\x2a\x24\x8a\xac\x4b\x1e\xc3\x1a\x2f\x8d\xfa\x84\x97\xfb\x51\xf1\x7d\xe8\x9a\x55\x82\x93\x01\x00\x00\x50\x07\xd7\xf1\x3c\xa3\xa5\x84\xe2\x6a\xc5\x19\xe9\x4f\x70\xa2\xfc\x71\x44\xea\x47\x7b\xe7\x88\xeb\x98\x57\x47\x17\x29\xce\xd1\x3d\x1f\x8a\x66\x7c\x62\x98\xa6\x24\xb7\x44\xba\x4d\x50\xac\x34\xfb\xaa\x3a\x32\x83\x09\x71\x73\x47\xa4\xca\x5a\x90\x2a\x9f\xe7\xc5\xf2\x4d\x80\x94\xdd\xae\x26\xb2\xab\xac\xf6\x35\x88\xb2\x7c\x19\xa3\x37\xea\x42\x2a\x53\x61\x89\x9b\x82\x4d\x5e\x87\x68\x36\x9f\xe2\xed\x68\x60\x26\xed\x0c\x74\x3b\x91\xee\xa9\xf4\xd3\xa5\x81\x5f\xac\xfb\x28\xa6\x74\x8c\x82\x4c\xda\x51\xb9\x9d\xfd\xc2\x56\x65\x4b\x72\x05\xc4\xda\x54\x16\xa8\x8a\x2f\x64\x3d\x37\xa7\x47\xdb\x69\xea\xfb\x68\x32\xb6\x56\x7d\xda\x7d\x6a\x8a\x66\x50\xd5\xed\xfb\xd8\x54\x2b\x70\x74\x7f\x42\x08\xd9\x8a\x79\xaf\xaa\x17\xfd\xfc\xdf\x9b\x53\x64\x3f\xf8\xbe\x75\x79\xd5\x71\x92\x1b\xba\x96\x1d\x52\x51\xe3\x34\x4b\x6d\x7a\xb5\x29\x05\xad\x1e\xb0\xb2\x22\x41\x4f\x55\x5c\x09\x49\x7a\x76\x52\x86\xc1\xf3\xa7\x4d\xfa\xb2\xd3\xed\xb8\x92\x7c\xb6\x48\xa4\x64\x09\xb9\xf2\x78\x6e\x48\x20\xad\xa6\x76\x48\x08\x69\x06\xc1\xb3\xcc\x96\x4e\x55\x3b\xae\x55\xed\x22\x23\x01\x5a\xf4\x4c\x05\xc3\x47\x36\x44\xeb\xe8\x0f\x38\x0b\xe0\xfc\xfc\xc6\x3f\x1f\x0c\x43\x1f\x05\x68\x76\x3e\x3a\x1f\x89\xc4\xf3\x1b\x3f\x38\xbf\xf1\xd1\xdf\xd0\x4c\x64\x18\x0e\xc2\xc7\x08\xce\x82\x00\x9e\x2f\x7c\x84\x66\x70\xf8\x18\x7d\x33\xc2\x19\x19\xfd\xb1\x88\x78\x14\x0c\xfd\x73\x3c\xf4\xbf\x19\xd5\xdc\xc8\x37\x03\xe3\xe6\x4e\x3c\xdc\x7b\x65\x67\x10\xf0\xf9\x24\xc4\xd1\x96\xaf\x03\x3e\x3f\x08\xf1\x3a\x2b\x78\xc0\xe7\x87\x21\xde\x64\xb9\x78\x7a\x12\xe2\x4d\x24\xbf\x3e\x0d\xcb\xa0\xee\xf5\x2b\xea\x8c\x0f\x65\x2d\x18\x20\xf7\x89\x79\xf3\x41\x00\x64\x00\x28\x30\x1a\x01\x4c\x87\xa2\x45\x93\x43\x3c\xfb\x32\x76\x17\x1d\x8a\xf6\x4d\xba\x78\x16\x69\xa2\x27\x2a\x0d\x04\xc0\x57\xef\x32\x3d\xaa\xea\x90\xf6\x0c\x98\x97\x75\xdd\x13\x3d\x7c\x9c\x93\x44\x2b\x03\x2a\x91\x41\x3f\x57\x05\x6c\xe4\x05\x4e\x54\x8a\x0d\x1a\x9b\x09\x30\xea\xba\xa4\xe3\x8a\x53\xa8\xa8\xe6\xd1\xf9\xc8\x1f\x21\xcd\xea\x8d\x2b\xc4\x75\x2b\x10\xd7\xed\x60\x80\xc0\x50\xe0\x02\x30\x23\xf1\x7c\x1b\xa2\x59\x6c\x48\xaa\x2d\x9e\xa0\x00\x0c\xe5\xd7\x6c\x96\xfa\x7e\x90\x4a\xdf\xcf\x40\x25\xc0\x2a\xa3\x3f\xc1\x92\x9f\x39\x46\x81\x93\x8a\x0f\x10\x4e\x07\x03\xeb\xd3\x5f\x96\x83\x9c\xc4\x9a\x52\x1b\x01\x84\xa4\xf0\xa5\x98\x81\x11\x08\x64\x00\xb3\x7c\x06\xd5\xe0\x08\xc7\x11\xcc\xc5\xa1\x2d\x9b\x4e\x19\x65\x3d\x2a\xc8\x83\x2c\x23\xdf\x55\x08\x5f\x50\xb9\x1e\x4b\xc4\x2c\x38\x73\x29\xf3\xe7\x95\x61\x09\xc2\xcc\xf3\xfa\x4c\x2f\xb9\x55\x4e\x55\xa6\xb1\x32\x4d\x80\x60\xf5\x11\x47\x90\x29\xf3\x9d\xdd\x8e\xeb\xfd\x99\x55\x76\x27\xba\xfe\x7e\xae\x77\x44\x63\xc5\x54\xb2\x1e\x90\x0e\x8f\x22\x2d\x5b\x08\x37\x06\xd2\x63\x34\xe3\x81\xa0\xe6\xac\xd9\xcd\xf9\xc8\xff\x46\x1a\xdc\xf8\x60\x04\x7c\x27\x12\x9a\x9d\xa0\x58\x4f\x50\x5c\x32\x6b\xd1\x43\x12\x2c\x5f\x0c\xb3\x9c\x44\x98\x55\x4e\x0e\x49\x81\x99\xc2\x8c\x63\xec\xee\x97\x0e\x7f\xcb\xaa\x7f\xb4\xea\xdf\x6e\x97\x9b\x90\x3d\xa5\xf4\x4a\xad\x58\xb4\x0d\xec\xad\xb9\x34\x6e\xb8\xba\xd1\xf9\x48\x8d\xa8\xa6\xc9\x39\x16\x74\x80\xe5\x53\x53\x31\x5a\x34\xad\x44\x7b\xb5\x38\x64\x23\x25\x08\xca\x8f\xc6\xb5\xa9\x97\x41\xf1\x94\xf1\xf7\x18\xe7\x08\x55\x91\xb5\xe7\x7f\x9c\x8f\x42\x3f\x38\x1f\x09\x50\xf5\xf8\x9b\x91\xb3\x64\xbe\xcf\x6c\x6c\x25\x49\xdf\x31\x7f\x62\x83\xe7\x0d\x47\x00\xf9\xbc\xe2\x5a\x98\x40\x5d\x1a\x16\xa6\xa4\x0f\xc1\xc5\x85\xc4\x92\x2e\x2e\x40\x62\x99\xd0\x35\xd5\x84\xa9\xe3\xf9\xd0\x51\xdf\xae\xf9\x21\x54\x07\xdc\xec\xbe\xfe\x64\x5a\x27\x2f\xa5\x41\xea\xd1\x77\xd5\xe7\x64\x09\xbf\x7b\xda\x6f\xdc\xc1\x7c\x30\x41\xbb\x5d\x57\xfa\x01\xda\xed\x26\x93\x49\xfb\xc3\xa1\xfc\xf0\xac\xfd\xe1\xc9\xbe\x12\x4f\xe5\x87\x27\xed\x0f\xcf\xe4\x87\x83\xf6\x87\xe7\x7b\x3a\xf5\xed\x9e\xf4\xef\x50\x35\xce\x6a\x87\xf0\xc1\x64\x3c\x65\x02\x54\xb1\xc1\x00\x89\xeb\xad\xd5\x6b\xe6\x14\xd4\x0f\xe3\x6a\x96\x97\x75\x09\x85\x38\x75\xb3\xb1\x75\x08\x35\x9b\x98\x47\x3e\x1b\x4c\x02\x7a\xcc\x67\x93\x60\x30\x29\x99\x4b\x72\x90\x74\xb6\xed\x0a\x6e\xb5\x91\x01\xb1\xbe\x01\x3e\x0d\xa8\x38\x14\x35\xd4\xfd\xc1\x42\x66\xbf\x4e\x90\x2a\xb9\x5f\x23\x73\x0f\x6b\x74\x69\x99\xe9\x95\xe0\xdf\xfa\x02\x17\x88\xef\x6e\x27\x7e\x60\x4e\xea\x1c\xa2\x41\x43\xd7\xa1\x23\x9b\xb5\x08\xa9\x27\x20\x29\x46\xb5\xb9\x1f\x30\x20\xb1\xf9\xdb\x99\x9b\x76\x2a\xb2\x0f\xb3\x3c\x58\x6a\xff\x5b\x58\x0b\xaa\x6a\x73\xb2\x5f\xcd\x75\xcf\xe4\x7c\xa6\xc1\x7d\xf3\xf4\x25\x43\xaa\xa6\xa0\x6b\x05\xba\xa6\xf3\x9f\x9c\xf5\xaf\x9f\x1c\x23\x16\xdd\xe3\xfb\xef\x8b\xa7\xc6\x0c\x95\x7d\xcd\x6a\xb3\x07\xe7\x85\x7d\xd9\xbc\xb0\x2f\x99\x17\xd6\x39\x2f\x1d\x2e\x5b\xbb\xa2\x09\x48\x31\x92\xcc\xeb\xde\xb9\x7f\x9c\xa3\xb0\x7c\x34\xff\xe3\x9c\x85\x8f\xcf\x99\xbc\xab\xec\x64\xbb\xfa\xfc\x9d\xb8\xb8\x8c\x46\x05\xb0\xb8\xfc\xc0\x08\x08\x18\x35\xaf\xb8\x84\xa1\xe7\xa9\x44\x3e\x1f\x87\xe2\x7a\x14\xb8\xa5\xc0\x31\x09\xf5\x39\xaa\x76\x6e\xa2\xf1\x8c\x7e\xde\xd6\x1f\x70\xcd\x04\x7a\x71\xb6\x4d\x17\x3a\x26\x7d\x4f\x0e\x64\xa1\x2f\x47\x85\x7a\xdc\x1b\x1f\xb5\xe2\xad\x7d\x8b\x66\x52\x4b\xc1\x60\x12\x3a\x97\xba\xee\x04\x5d\x36\xc6\x99\x3f\x41\xa8\xe4\x24\x86\x91\x54\x8e\x74\x1c\xe6\x70\xeb\xb7\xbb\x23\x5e\x51\xa7\x00\x4e\x0a\xbb\xd2\xe4\xf2\x2b\x24\x64\x5d\x0e\xbf\xba\xaa\x31\x56\x0e\x6e\x2d\xa6\x40\x9d\x14\x6b\x96\x66\x32\x28\x93\x93\x43\x91\x6a\xfb\xea\x0f\x9e\x3f\xc1\x0f\x8d\x42\x53\x73\xcd\x06\x82\xe7\xcf\xc4\x4c\xed\x0d\xde\x32\xfa\xe3\x7c\x21\x28\x21\x13\x54\xaa\xbd\x57\x65\x48\x5e\x1d\x8d\x03\x83\x0e\x27\x53\x9a\x01\x53\x56\x34\x0d\xcf\x93\x2b\x88\x2c\xfa\x5f\xf8\x23\xd4\xc5\xc6\xd7\x3b\x57\x9e\x75\xb3\x61\x2a\x44\xca\xf1\xd3\x8e\x93\xfa\x66\xc6\x11\x91\xbd\x7d\xcd\x38\xcc\xf0\x64\x8c\x70\xa1\x12\x5e\xa5\x59\xc4\x61\xa6\x8c\xc4\x6f\x04\x2e\x98\x78\x9e\xc6\x1b\x33\x84\xf8\xf0\x26\x59\xf0\x35\x89\x2a\x3f\x41\xeb\x8e\x4c\x6b\x2a\x39\xa0\x91\x65\x9f\x83\x5b\x71\x74\x92\xdd\xee\x54\xaa\x32\x0d\x93\xe2\x34\x3a\x85\xc5\x03\x3a\x36\x45\x1e\x17\x94\xf7\x16\xb4\x88\xf3\x64\xc3\xb3\x3c\xe8\x81\x61\x9c\xb1\x38\x52\x1e\x9c\xf9\x70\x41\x59\x91\xf0\x3b\x52\x94\x32\x48\x51\x8f\x0b\xb4\x99\x28\xc7\xdd\x25\x42\x48\x85\x0e\x40\xc3\x65\x92\x72\x9a\x37\xa7\xad\x5b\x1a\x4d\x51\x9f\x90\xa6\x84\x5a\x46\x9e\x97\xee\xbd\xe4\x42\x09\x78\x52\x05\x08\xeb\x00\x4d\x85\x94\xec\x7c\xa0\x1c\xee\xd1\xa6\xd8\xe3\xa5\x59\x40\x85\xa4\xb0\x14\x3c\x30\xd1\x9f\xe6\x32\x7f\x58\xed\x0e\xb9\x06\x36\xf8\x19\xa8\xe6\x45\x7d\xc1\xe0\x06\x48\xdd\x74\xb5\x0c\x9d\x19\xd5\x27\x0c\xd6\x2a\xa7\x9e\xcb\xce\xac\xfa\x1b\x06\xb7\x40\xca\xe5\x14\x86\xdd\x03\x62\x46\x6c\x68\x65\x2c\xde\x15\x50\xf9\x76\x6f\x50\x1b\x0a\x81\x89\xd7\xd9\xb4\x01\x71\x19\x09\x9a\x85\x2c\x91\xf3\x38\x4b\x1d\x57\xe0\x45\x1a\x15\x6b\x5a\x38\x29\x82\x98\x77\x5e\x25\x99\x56\xbd\x0a\xd2\xbd\xf1\xd5\x4a\xbd\x75\x52\x54\xb8\xe5\x75\x18\x98\x2a\xe1\xd3\x96\xe6\x77\x6e\x8d\x11\x5f\x37\xaa\x90\x00\xd8\xa9\x31\xa7\x4a\x0a\x5d\x1a\x88\x70\xad\x62\x00\x65\x69\x8b\xd8\xd2\x2b\x7a\x0d\x29\xee\x4f\x70\x7f\x8c\x4c\x3e\x01\xa2\xab\x52\x8a\x36\xd9\xa3\xb0\x33\x6b\x97\x56\xf9\x21\x17\xa4\xb7\x40\x6a\x05\xf5\xd8\x79\x89\x66\xc3\xa4\xb0\x3c\x79\x15\x73\x51\x06\x3d\xa0\x52\xbf\x2f\x62\xb1\x0c\xf7\x39\xa3\xba\x0a\x88\x82\xc4\xe1\x2c\xab\x44\x1b\x52\x10\xb3\xe1\x2f\x79\x4a\x12\x6d\xaa\x20\x88\xb7\x68\xf0\xe7\x78\xf0\xdd\xd0\x1f\x84\x7e\x80\x46\x09\x2e\xc8\x28\x98\x8f\x07\xdf\x85\x8f\xbf\x19\xe1\x54\x64\x39\x1f\x9d\x8f\x66\x70\xd6\x3f\x1f\xa1\xf9\x1f\xe7\xb3\xf3\x22\x7c\x8c\xe0\xf9\x6c\xfe\x87\x7c\x9a\x7d\x33\xc2\x5b\x32\x07\xf7\x00\x83\x12\x60\xb0\x03\x18\x9c\x9f\x03\x0c\xfe\x00\x18\xfc\xff\x40\x68\x36\xe9\x1c\x1c\x01\x0c\x8e\x01\x7e\x04\x1e\x89\x0f\x18\xf4\x44\xce\x5c\xfc\x61\xe2\x0f\x07\x21\xc2\x1b\x32\x07\x8f\xaa\x42\x5b\x84\x97\x64\x0e\xfe\x0a\x30\x18\x01\x0c\x66\x00\x83\x29\xc0\xe0\x2f\x55\x8e\x0d\xc2\x0b\x32\xb7\x5f\xff\x02\x42\xbc\x26\xa3\x3f\xe6\xbe\x1a\xd7\xc9\xe0\x3f\x2e\x06\xe1\xfd\x18\x3f\x3b\x2c\xbf\x19\xe1\x4b\x39\xe4\x8e\x6f\x48\x73\xcf\xae\xc8\xfd\xdf\xa3\xeb\x48\x01\xb4\xa0\x3f\xc6\xc0\x79\x05\x41\x7f\x5c\xe2\xb7\x9f\xcf\xb2\x22\xf7\x6b\xce\x37\xe2\xa3\xf8\x2d\xc4\xc3\x52\xbd\xaf\xb2\xcd\x9a\xe6\x32\x21\x51\xee\xad\x81\xcc\x0a\xec\x63\xa1\x9f\x97\x36\x55\x97\xd1\xc9\xa2\x98\x6a\x46\x86\x3e\x94\xbb\x5f\x0b\x9b\x9c\x23\x7a\xed\x60\x4d\xd4\xf3\xc4\x2e\xd2\x5b\x4e\xec\xa2\xfa\xe6\xa9\x98\x5e\x95\x46\x88\x8d\x02\x94\x1b\x0c\x4e\x56\x87\xf3\xd2\xdd\x5e\xcd\xeb\xd4\x36\xd9\xaf\x6d\xdb\x6e\xf9\xeb\xcf\x51\x1e\x5d\x51\x4e\xf3\xde\xa3\x6d\x9e\x3e\xb2\x8e\xb2\x22\x2b\x82\x65\x52\xb4\x1a\xdb\x70\x00\x09\xa1\x95\x77\x91\x99\x0c\xaa\x21\xcd\x85\x13\xcf\x4b\x8e\x9c\x4f\x7f\x01\x68\x06\x66\x20\x00\x7f\x01\x92\xc1\xae\xee\xe8\x02\x4d\xb7\xf3\x71\x48\xc4\x1f\x87\x5f\x72\x3e\x5a\x61\x89\xae\x89\x16\xae\x09\x25\x5b\x05\x2f\x0b\x79\xc1\x5e\x93\x6b\x7d\xd3\xe3\x3e\xf3\xbc\x89\x52\x2a\x50\x88\xc2\x5f\x00\xaa\xf9\xbd\x3a\x21\xe9\x90\xde\xd2\x18\x5e\xcb\xa2\x27\x35\x97\x29\x12\x04\x5d\x3b\xf0\xe7\xba\x01\xad\x4e\xe6\x93\x10\x9f\xcc\x0f\x42\x6d\xb1\xa1\xe1\x9c\x48\x71\xe1\x1c\x9f\xdd\xe9\x15\x71\x72\x19\x26\xca\x04\x69\x81\x61\x47\xb2\x31\x92\xd0\xf5\x02\xe0\xd6\x6a\x8c\xf1\xa4\x1a\xfa\x05\x89\xdc\x71\x5c\xa8\xd1\xdd\x10\x78\x41\x2e\xe6\xe3\xb0\x11\x40\x7a\x5a\xbf\x09\x6e\xb0\x98\x32\xdd\xf0\x85\x99\x9f\x52\xb1\xf5\x2e\x76\xbb\x6b\xcb\x38\x12\x70\x65\xfe\xc7\xdf\xce\x47\xa1\xff\x37\xfd\x3b\xd2\x0a\x3d\x7f\x4a\xa6\x30\x21\x55\x4d\x63\x7c\x80\xa6\xfd\x3f\x77\xbb\x0b\xcf\x7b\x3b\xbf\x08\x77\x3b\xe8\xb4\x73\x80\xea\x97\x4f\x7f\x2c\x5b\xec\x8b\x9c\x9e\x07\x55\xb1\xfe\x6a\x7e\x11\xa2\x4a\x50\xf9\x0e\x9f\xe1\x5b\x32\x98\xe0\x53\x32\x9e\x9e\x1e\x59\x9d\xdb\x53\xdf\x47\x72\x5b\xc1\x37\xe4\xda\x6e\xaa\xc5\xfc\x34\x94\x9c\x54\x19\xe9\xee\x76\xb7\x7b\x73\x74\x2b\x5e\x6f\xc9\x1b\xc5\x6b\x53\x45\xce\x88\xfa\x3e\xbb\xae\xd3\x03\x7f\x03\x28\x68\x25\xe1\x5b\x59\xe3\x3b\x31\x10\x8d\x10\x9e\x21\x35\x7f\xf2\xf5\xcc\x37\xc6\x89\xf2\x0e\xed\x08\x84\xfc\x0e\x21\x77\x0c\x4b\x77\x0c\x72\x26\xdf\x4c\xdb\x43\x59\x3e\x30\x94\x52\xa5\xc9\xb7\x6b\xb3\x7a\xce\xc5\x5d\xf5\xf4\xd6\xed\xe9\x2d\x32\xbb\x39\x2f\xe8\x4f\x59\xc1\x21\x6a\xdc\xe7\xb5\x37\xa9\xda\x24\xba\xf7\x92\x80\xb9\xe4\xd1\xba\x5f\x25\xf5\x06\xc2\x76\x7a\xed\xcd\x11\xc6\x8b\xa5\x7e\x69\x15\x47\x3e\xd4\x4b\x59\x0c\x7d\x38\x42\xf8\x05\x81\xa7\x64\x8c\x3f\x98\x91\x4d\x4f\x8f\x5e\x54\x93\xf5\x91\x7c\x98\x9f\xca\xea\x3e\x7a\x5e\xff\xa3\xde\xa9\x6b\x67\xcf\x7c\x12\xe7\xe6\x37\x32\xc6\x3f\x90\x8f\x66\xae\x7f\x3b\xfa\x61\xfa\x9b\xef\xa3\x8f\x2e\xbb\xec\x37\x74\x3c\x39\x78\x3e\xfb\xe4\x13\x70\x0b\x82\x4f\x3e\xf9\x38\xff\x4d\x75\xf4\x93\x53\xad\xa8\xf2\x7b\xf2\xc1\xce\xe9\x29\xc2\x3f\xdb\xd7\x53\xb1\xfa\xbf\x13\xd3\x8d\x4b\x34\xfd\xdd\xf3\xe0\xf7\x0a\xfb\xfb\x7d\x3e\x09\x11\xfe\xd9\xaa\x99\xfc\x3e\x3f\x08\x91\x48\xb0\x6a\x5c\xd7\x82\xf8\xf5\x7f\x36\xdc\x56\x80\xfc\xeb\xe6\x9a\x7c\x5f\x7d\x54\x4e\xf1\xcb\xb2\xec\x9a\xe3\xe3\x83\xa7\x4f\x67\xf5\xa2\x00\x04\x0f\xac\x6f\x1d\x42\xe0\x97\xc6\xda\xcc\xe6\xce\x87\x3a\x3e\x7e\x3d\x5d\xc3\xf9\xbf\x13\x8b\x1a\x0a\x28\xee\xdb\xb7\x00\x00\xfc\xbe\x63\x2b\x55\xfb\xf3\xbd\xff\xf7\x0a\xc6\xfa\x55\x56\xfc\xd2\xc0\xbf\x3d\x3d\x36\xa0\x12\x77\x6e\xb2\x03\x84\x15\x6b\xe1\x5a\xb1\x16\xd4\xe4\x5e\x23\x05\x66\xae\xe6\x37\xa1\xdc\x7e\x62\x6f\xbd\x20\x1b\x7b\x0a\xdd\xcd\xf5\x9a\x6c\xf4\xe6\x92\x27\xb2\x3a\x8e\xaf\xf5\x46\xf8\xa9\x2b\x36\xf6\x6b\x34\xfd\x89\x10\xf2\xda\xf3\xe0\x4f\x84\x16\x71\xb4\xa1\xa2\x80\x3a\x7a\x72\x63\xbf\xd6\xf8\xfd\x4f\xa8\x94\xd0\xfb\x95\x53\xb5\xb8\xa2\x14\x00\x78\x65\x87\x2f\xb0\x69\x0b\x38\x5f\xb9\x87\x78\x8c\x5f\xe9\x05\xf8\xc5\xad\x63\x66\x22\x7c\xf6\x09\xf9\xa5\x7e\x39\xd9\x7a\x7e\x41\xee\x6d\x52\x25\x4b\x00\x66\x9a\x56\x1f\x6b\xd7\x97\x4c\x42\xf5\x4e\xfc\xf2\x45\xb7\xd5\xb5\xc9\x61\x2f\xd0\x6b\x84\x57\xf3\x1b\xa3\x49\x62\x56\xd0\x38\xae\x33\xd9\x5a\xc5\x14\x8b\xc8\x4d\xd2\x06\xa5\xaa\x69\x74\x6f\x76\xa3\xfd\xaa\x61\xd7\xaf\xc4\xc9\x56\x6d\x43\x79\xd1\xff\xdd\xff\xd5\x55\x41\x52\x37\xbe\x7c\x32\x68\xba\x56\xda\x69\x23\xeb\x6d\xb5\x12\x7b\x03\xc8\x46\x94\xe0\x07\xd2\xae\xdd\x42\x11\xaa\x30\x9b\xbf\x1e\x9e\x8c\x12\x2c\xa5\xac\xd4\x27\xe2\x06\x9a\x3a\x5e\x3e\xcd\x85\x2d\xf9\x69\xac\x3d\x44\xa3\xc3\x25\xf6\x8b\x7c\x4f\x48\x7f\x82\x23\xe2\x9e\xb6\x59\x42\xa8\x6f\xdf\x82\xc6\xbc\x43\xf1\x55\xdd\x31\xf5\x33\x65\x77\x56\x00\x50\x1d\xac\x04\x60\x0e\xfc\x5a\x8a\x0f\x42\xbb\x3c\x4a\xe8\x9b\x28\xa1\xaf\x4d\x42\xee\xd6\xab\x61\xba\xce\x0e\xf3\xbc\x96\xc6\x90\xfa\x50\xc1\xcb\x88\xdc\x35\x75\xde\xf5\xee\x9c\x3a\x71\x12\xcc\x6a\x47\x9e\x07\x66\xc0\x8f\x94\x92\xae\x5e\x69\xcf\x03\x81\xe4\x3f\x9a\xfd\x3f\x98\x20\x2b\xa6\xae\xa3\x28\xbb\x1d\xec\xf3\xdd\x6e\x35\xe7\x21\xf2\xbc\xbe\xc4\x62\x67\x30\x91\x78\x8f\x0f\x13\xa9\xc8\x8c\x99\x61\x68\xb2\x4a\x44\x28\xad\x4f\x04\xf0\x61\x08\x05\xc9\x6e\x27\xca\x00\x84\x73\xcf\x03\x7f\x01\x4a\x19\xc7\xc9\x9a\x13\xf0\x17\xe0\xe7\x08\x17\xb2\xbf\x7d\x42\x8a\xda\xf7\x82\x88\x51\x14\x08\x73\x3f\xf1\x21\x73\x94\xcf\x46\xf3\xd9\x5f\xc2\xd1\xaa\x33\xfc\x7e\xe7\xce\x2b\x11\x42\x3e\x2c\x48\x61\xab\x10\xe8\x37\xf8\xeb\xc1\x21\x40\xc8\xcf\xeb\x5b\xbd\x4d\x6b\xd7\x7d\x34\xd5\xa9\xe4\x8a\x7c\x46\xf6\xfc\x74\xd6\xd7\xa2\xc2\x25\x31\x52\xa7\x45\x4c\x60\x16\x65\xd7\x6a\xa9\x1b\x55\x3f\xa6\x84\x97\xf5\x08\xeb\x09\x6e\xab\x9b\x21\xed\xc3\x26\x6f\xf9\xb0\x29\x48\x3e\x8f\xc2\x29\x9b\x17\xa1\xdc\x30\xf3\x42\x3a\x40\x64\x0a\xee\x4a\xbb\x99\xb5\x92\xa5\x53\x09\x14\xac\xce\x88\x66\x4a\x54\xf0\x81\x49\x97\xbb\x66\xbf\x78\x5e\x9f\xda\x33\x5b\xe1\x23\x71\xad\x6b\x54\xaa\x07\x4c\xd3\x23\xeb\x80\x3e\x35\xfd\xda\x92\x78\x9e\x86\x53\x60\xaa\x10\x5b\x61\x2b\xf6\xd2\x7c\x1b\x12\x3a\xdf\x86\x96\xf7\xbc\x9a\x33\xdb\x50\xe8\x79\xcc\x85\xa4\xcc\x05\xa3\x4c\xb3\x55\x1a\xa0\xb4\x63\x24\xa5\x1c\x89\xa9\xd4\xf3\xaa\x67\xb9\xb7\xab\x61\x89\xcb\x74\x35\xaf\x3e\x87\xd5\x48\x37\xcd\x91\x2e\xc9\x78\xba\x3c\xb2\x77\xed\xd2\x8c\x74\x41\x36\xf3\xa5\x58\x81\x85\x18\xd8\xc2\x06\xb8\xd8\xd3\xaf\xaa\x79\x52\xb5\xab\xd5\x4e\x76\xbb\xb7\xb5\xce\x38\x43\xa5\xf6\xb1\xf2\x7c\x2e\x5a\x5f\x13\x48\x6b\x70\xd4\x70\x88\x25\x89\xb9\xb6\xe0\xa6\x0f\x55\x13\x64\x3d\x54\x08\x1c\x42\x53\x34\x35\xcd\x9a\x8f\xc0\x6a\xc0\xa8\xea\x20\x75\x31\x30\x84\xa5\x82\xef\x5a\xa2\x24\x6b\x8b\x0a\x8a\x0f\xa6\xa1\xa3\x83\xe6\x17\x67\x0c\xeb\x4a\x45\x44\xcd\x84\xbe\x6c\xa9\x7e\xc0\x4c\xdf\xb7\x54\xfd\x62\xb5\x17\x88\xe9\xa5\xb8\x38\x14\x65\xa2\x34\x76\x70\xb5\x57\x88\xdb\x6b\xf5\x2c\x5a\xce\x72\x51\x5a\xfc\x38\xfd\xd8\xed\x98\xbd\x6b\x55\x9c\x04\x56\xbf\x89\xae\x08\x73\x6f\x59\xbd\xef\x2e\xfd\xab\x6a\x69\x2d\xd7\xb1\x82\xaf\xf6\xe8\x74\xee\x48\xd1\xd0\x1d\x71\xf7\xb3\x52\xc6\xa8\x52\x2a\x38\x89\xaf\xed\x90\x69\xab\x00\xed\x2a\x70\x42\xae\x77\xbb\x3b\x31\x30\xa5\xab\x52\x65\xc2\x17\xe4\x04\xdf\xd4\x1a\x76\x9a\xac\xb6\xca\x6e\x37\x0f\xf1\x9f\x04\xae\x89\xdb\x24\xdd\x9b\x95\x39\xc7\xab\x5f\x3b\xc2\x12\x79\xfb\x53\x9e\x57\x67\xef\x98\xd5\x50\x8e\xf5\x8c\x92\x95\x04\x4c\x37\xf3\x71\x38\x13\x7f\x88\x4a\x0f\x6e\xec\x06\x52\x09\xd2\x1f\x8a\xde\x9f\xd8\x3d\xd7\xee\xf6\x94\x15\x53\xa7\x11\x5a\x6b\x44\x6c\xda\x99\xf8\xa3\xa7\x36\xa8\x76\x29\x35\x8d\xd0\x8a\x57\x2c\xa6\xf4\xc4\x2d\x2b\x76\x82\xee\xab\x40\x1f\x51\x6b\x6b\x2a\x08\x2b\x90\x14\xdd\x00\x33\xbb\xb0\x73\x8f\x3a\x05\x64\xf4\xaa\xea\x31\xa8\x4a\xe0\xcf\x1f\x91\x1b\xb2\xae\x0c\x6c\x0d\x95\x79\xb3\xdb\xc1\x1b\x32\x0f\x11\xbe\x19\x6e\xb2\x0d\x44\xf8\x86\xdc\x18\x0e\xe6\x1a\x7d\xbe\x5a\x5b\xa5\xe4\xab\x9d\x6e\xd3\xf4\x5d\xfe\x0b\x53\xde\x41\x17\xd0\x94\xb2\x8a\x37\x8d\xd5\xd6\x73\x73\x63\x20\x0d\x86\x6f\x48\xbf\x0f\xcd\xaa\xab\xdf\x0a\x2b\xfb\x1b\x40\xc7\x02\x39\xd0\xe9\x7a\xa3\xfd\x4d\xe9\x91\xe9\x03\xff\xc6\xd6\xa5\x2b\x77\x9a\xb3\xdf\xd0\x17\x8c\x0c\x9b\x01\xc1\xea\x18\x20\x85\xc5\xe9\x54\x3d\xb6\xdd\xce\x5c\x38\x4e\xce\x59\xf5\x18\x00\x80\x7c\x9b\x7d\x66\x1e\x44\x72\xe7\x9d\x24\x69\xf1\x9b\xa6\xe6\x66\x43\x78\xe0\x54\x27\x9b\x96\x78\x97\xa9\x99\x39\x62\x85\xae\x06\x2c\x9f\x49\xcc\xbc\xa4\x6d\x06\x13\x34\x1f\x87\xf8\x8c\xe8\xb9\x37\xa0\x71\xb7\xbb\xb1\x51\x23\xc4\x24\x2b\x5d\xc1\x77\xbb\x9d\xd6\x0b\x7c\x87\xf4\x06\x7d\x87\x6f\xc9\x18\x9f\x92\x1b\x4b\x61\x1e\x93\xf1\xf4\xb4\x52\x2f\x7c\x47\x6e\xe6\xa7\x21\x9a\xdd\x18\xfd\xc0\x53\x47\xbd\xf0\xdd\x0c\xd6\xd2\xf1\xad\xef\xa3\xe0\xd6\xf3\x9a\xc9\x83\x81\x92\x8f\x9f\x78\x5e\xff\x42\x12\xb6\xd3\xdb\xc1\x60\x7a\x8b\x2a\x48\x20\xaa\x44\xd3\xfe\x89\x73\x0e\x77\xbb\x1b\xc5\xb9\x19\x99\x14\x57\xb1\xed\xa6\x76\x0b\x9d\x19\xcc\xf6\xa6\xba\x83\x6a\x48\xf3\x8d\x11\x72\x29\xec\xfb\x0d\x7e\x49\xbe\xa8\xa1\xe9\x83\x47\xe0\xe5\x0c\x80\xc0\x4c\xde\xcc\x1e\x88\x00\x80\xff\xc1\x33\x01\x4f\xc8\x49\x75\x35\xd8\x2d\xe8\x79\xfd\x97\xe2\xd5\x9d\x26\xdb\x55\x67\x63\x3a\x33\x16\xc0\xf6\x86\xb5\x7b\x12\xfd\x4f\x1d\x2d\x07\x03\x90\xda\xfc\x0a\x13\xf8\xea\x1b\x19\xb7\x04\x0b\x3f\x89\x49\xec\xa6\x86\x25\x28\xe7\xa4\x50\x7c\x6a\x8a\xa6\xf2\x62\x91\xc4\x17\xe4\x52\xff\x03\x59\x42\x5f\xdc\x40\xdc\x61\x85\x4b\x7d\x49\xc7\x9e\x52\xb3\x78\x8c\xff\x7b\x91\xa1\xc5\x2b\xa2\x52\x72\x6a\x15\xc9\xbf\x9d\x60\x23\x25\x0d\x9e\x3d\xc1\x8e\x0c\x26\x78\xf6\xbc\x0c\xf1\xb7\x93\xb6\x7c\x95\x0f\xe9\xad\xe8\x4b\x41\xee\x0d\x39\xd2\xa1\xb9\xd6\x11\x27\xb9\xc4\x86\xa2\xed\xca\xaf\xfc\x7a\x88\xfc\xb1\x14\xed\x68\x9b\x0c\x59\x4a\x2c\x73\x97\x76\x9c\xd1\xcb\x33\x79\x9c\xcb\x64\x7f\x76\x5a\x1a\xe1\xf1\xc1\x43\x83\xeb\x74\x44\x7d\x5f\x6a\x47\xd4\x4d\x95\x79\xd7\x1d\xac\xfd\x36\xe7\x95\x1f\xd2\xac\x97\xb0\x1e\x43\xb9\x12\x61\x32\x9c\x49\x19\xe8\x3c\x0b\x09\x9b\x67\x15\xd1\x42\xcb\xba\x61\xd0\x3e\x47\x05\x7a\x04\x87\x0f\x88\xbf\xd7\xfc\x2a\x95\xdb\x2f\x3f\x30\x12\xf0\x5b\x4e\xd9\xc2\x38\x41\x4c\xb3\x45\x54\xac\x87\x8a\x17\x97\xd3\x15\xbd\xdd\xc8\x88\xd4\xd5\xa7\x38\xcd\x18\x5d\x50\xba\x31\x91\xf0\x75\xfa\x15\xcd\x57\xf4\x26\xe1\x6b\x80\x70\xec\xa4\x27\x85\x91\xdf\xe1\xb4\x96\xbc\x49\xa3\x84\xe9\x05\x46\x78\x2b\xbe\x29\x9d\x0b\x19\xd9\x9d\x42\xb0\xc9\x0a\x1e\x17\x05\x10\xd4\x10\x85\x60\x9b\xd7\xc4\xf4\xda\x34\x96\xd6\x99\x1f\xb4\x4b\x4d\x45\x2c\xa1\x8c\x90\x83\x99\xf4\x6b\x6c\xeb\x58\xbb\x92\xec\xfb\xb2\xd3\xef\x03\xad\x45\xd7\xbf\x74\x35\xe1\xe6\x56\x25\x42\x74\xa6\x6e\xdd\xaa\xb6\xab\x35\x1c\x95\x0e\xf0\xaa\x7d\xf4\x56\x2e\xe8\x15\x19\xfd\x31\xff\xe3\x7c\x7c\xce\xcf\xd9\xf9\xf2\x3c\xef\x8d\x8e\xc8\x71\x58\xb3\x6a\x78\xeb\xae\xe0\x9d\x40\x49\xaf\x09\x70\x8c\xf9\x4f\x9a\xc6\x7d\x8a\x7f\xc5\xa3\x15\xd1\xb6\xf9\x11\xe7\x79\x72\x59\x10\xbe\xdb\x19\x3b\x7e\x1e\xad\x8c\xaa\x1f\xb9\x33\x51\xbb\xd4\x17\x7a\xcb\x2d\x3b\x72\xbb\x59\x44\x9c\xfe\x1c\xe5\x94\xf1\xd3\x6c\x41\xcf\xc4\x47\xe7\x04\xbc\xa9\xd8\x4b\x6f\xe6\x6f\x2a\x89\x85\xac\xc5\x27\x4c\xfe\xa2\xb2\xe4\x33\xc8\x49\x06\xdf\x0e\x75\x50\xda\x02\x73\x84\x14\x10\xcc\x67\x9a\x47\x91\x93\x0c\xae\xb0\x79\x41\x81\x4d\x5e\x05\x90\x93\xaa\x28\xb2\xe9\x72\x06\x2f\xf0\x0d\xfe\x93\xf0\x21\xcb\x98\xe8\xdd\x59\xb4\x2a\x76\xbb\x39\x50\xf2\x6a\x80\x41\xc1\xef\x52\x0a\x30\x10\x3d\x89\x72\x1a\x81\x70\xca\x87\x51\x9a\x66\x37\x74\x71\x22\x27\x66\xcb\x69\xe1\x79\xf0\x42\x9c\xe2\x1b\xf1\x67\x01\x3b\x72\x34\xbd\xa7\x5f\xcc\x79\x48\x74\xd0\x53\xb9\x0f\xf6\x18\x39\x2b\xa8\xe5\x30\x05\x1f\x03\x74\x4c\xc6\x33\xbd\x31\x12\xb1\x5f\x1d\x61\xed\xf9\xe3\xd1\x0a\x83\xe1\x63\x80\x50\x20\x9a\x70\xb7\xcf\x8d\x68\x92\xd1\x9b\xde\x7b\xba\x7a\x79\xbb\x81\xe0\x0f\x28\xd0\x35\x75\x5d\xee\x00\xf2\x01\xfa\x46\xa9\xc4\x4c\x15\x5e\x76\x5f\x4e\x9d\xb1\xbc\x50\x01\x95\x5b\x03\xf1\x3c\xb8\x86\x17\x98\x8b\x7b\x52\x8f\x0a\xe1\xaa\x6d\x20\x03\x31\x8b\xab\xf0\x9d\xf8\x48\x8d\x12\xd2\x19\xbe\x35\x0d\xf0\x3c\x62\x85\xb8\xea\xc4\xec\x77\xba\x99\x9f\x02\x93\xe8\x42\xfe\x19\x23\xb4\xc3\x92\x54\x79\xa0\x79\x3b\x2c\x64\xd4\xe7\x33\x53\xb9\x54\x0b\x01\x8f\x65\xc6\xd9\x19\x61\xc1\xad\x9c\x0f\xd3\x9f\x53\x32\xc6\x6f\xc8\x3c\xc4\x2f\xc5\x1a\x7e\x10\x7f\x5e\x90\xfe\x04\x7f\x24\x63\xfc\x49\x99\x0f\x0e\xa5\x79\x43\x0e\xef\x33\x96\x6d\x28\xe3\x91\x7b\x43\x69\xc9\xfe\x0b\xf4\xd1\x04\x99\xab\xb4\x05\x4e\xe4\xe7\xe9\x1b\x35\x23\xda\xfe\x22\x53\x2c\xe3\x98\xf4\xfb\xb9\xdc\xe8\x02\xa7\x5c\xc3\x5b\x2c\xf5\x58\x32\x72\x3b\xa7\xa1\x2c\x87\x73\x7b\x04\x19\xc9\xcc\x33\x56\x56\xfc\x7d\x42\x32\x59\x5a\x6a\x52\x26\x8c\xd1\x5c\x9e\x32\x95\x88\x30\x55\x19\xa2\xd5\x69\xdd\x23\x68\x95\x88\x3f\xcc\x4f\xc3\xea\x15\x49\xec\x13\x66\xe4\xec\xa1\xc6\xff\x91\x6a\xab\xad\x24\xd6\xd9\xf3\x14\xeb\xdb\x4d\xab\x4c\x30\x04\x46\x9f\xd3\x78\x9b\x17\xc9\x35\x7d\x29\xef\x12\x65\xab\xb2\x48\x0a\xa7\xc0\xdb\x6c\x41\x3d\xaf\xdf\x69\x67\xab\xec\xd2\xe4\x9c\x4a\x33\xe0\xb6\x7a\x3e\x7c\x29\xf1\xd3\x84\xf4\xc7\xf8\xa5\xe8\x6d\x7f\x8c\xc1\x22\x29\xe2\x28\x5f\xec\x6f\x4d\x0a\x7a\xfe\x74\xba\xea\x79\xf0\x85\x28\xfa\x91\x4c\x90\xa9\x07\xe1\x53\xdf\xc7\x89\xdc\x12\x9f\xab\x52\xf7\x6c\x7a\x4d\xee\xb0\x00\xd0\xe5\x9d\x4f\xc0\x11\xf0\x29\x86\xfd\x8b\xdd\x4e\x1c\x2e\x31\x1f\x17\x73\xf0\x18\x08\xbc\x6d\x01\x99\x73\x48\xc4\x9d\x2f\x5a\xb9\xb2\xca\x8b\xca\x7f\x83\xd8\x58\xd2\x56\xa3\xaa\x43\xf7\xfd\x62\x4e\x43\xdb\xfd\xcc\xd6\x6c\xbf\x8a\x97\xda\xf7\x35\xbc\x91\xa5\x6f\x44\x41\xdd\x8a\x20\x32\x54\x29\xf5\x6b\x5b\x8f\x49\xbf\x0a\xc1\x78\xe1\x79\xa2\x35\xd5\xa5\xb7\x62\x92\x56\x62\xcf\x5f\x13\xb5\x79\xa7\x3c\xbf\xb3\x0b\x76\x82\xff\x94\x5d\x9b\x7f\xb8\xbb\xba\xcc\xd2\xa1\x0a\x2b\x9e\xe5\x21\x44\xd3\x3e\x7c\x4b\xe0\x09\xf9\x73\xc8\xe8\xad\xa0\x12\x86\x8b\x8c\x51\x34\x15\x35\xaa\xba\xcf\xc8\x89\x8a\x9d\x28\x46\x9c\xc2\x33\xe4\x79\x67\xda\x1b\x95\xfa\x25\x84\x64\xe8\x5e\x76\x4e\xe4\xbf\x15\x77\xa0\x98\x9c\x31\x21\xe4\x6c\x78\xb5\x4d\x79\xb2\x49\xb5\x22\xeb\xa9\xc0\xca\x15\x09\xd3\x03\x08\xbf\x91\xfb\x43\xf4\xfb\x43\x57\xbf\x5f\xe0\x8f\xe4\xb4\xbb\xd3\x6f\x08\x7c\x41\x3e\x36\x3a\xfd\xc6\x76\xfa\x13\x79\xa1\x3b\x2d\x67\xfe\x6c\xa8\x5d\xcd\x99\xb9\xff\x84\x0c\x4b\xe7\x76\x76\x4b\x3e\x05\xb7\x3e\x01\x3d\xe0\x7f\x42\x65\x19\x4b\x99\xf7\xcf\xe8\xfe\xa5\xe8\xdc\x07\xf2\x73\xb9\x4c\x58\x94\xa6\x77\xf7\xa2\x6b\x6f\x54\x30\x79\x42\x3e\x0e\xd5\xde\xda\xed\xcc\x13\x44\x36\x67\xb2\x84\x2f\xb5\xea\xd1\x87\x52\x6b\xa0\xb6\xfa\xc0\x90\xd2\xd2\xbe\x25\x0c\x4d\x19\xb9\x2d\x9d\xb6\x57\xa2\xed\xeb\x46\xdb\x6f\x4d\xdb\x7f\xda\xb6\xff\xec\x6c\x7b\xa5\xdb\xbe\x2e\xcb\x32\x59\xc2\x58\xee\x62\x39\x11\x16\x26\x7c\x90\x96\x6f\xc5\xc9\x66\x93\x26\x74\x71\x96\x55\xd7\xa9\xb3\x3f\x3d\xef\x07\x09\xa9\x0c\x93\x42\x2e\x91\x76\xa7\x6a\x81\x97\x8e\xbb\x03\x92\x65\x1e\x5d\x51\x6d\x20\x26\xb0\x45\xa0\x36\x86\xd2\x34\xe8\xab\x95\x85\x09\x59\x6a\xc1\x07\x33\x82\x15\x45\x39\xc8\xb8\x99\x9a\x04\x36\xaf\x86\xbf\x37\xfb\x9e\xac\x21\xc7\x40\xf6\xfd\xb5\x6c\xe7\xbd\x36\x50\xfb\x25\x4f\x0b\x80\x66\x7a\x5c\xed\x6f\x41\xdf\x0e\x59\x7d\xfc\x49\x13\x56\x45\xb0\xef\x83\xe7\xc1\xef\xc9\xbe\x8f\xc3\x65\xc2\x16\xdd\x81\x3b\xec\x08\xb4\x3d\x32\xd2\xcb\xf9\x3b\xba\xff\x9e\xf4\x27\x52\x5e\xff\xfd\xe7\xa6\x52\xe4\x32\xa8\xb6\x9c\x3f\x31\x6b\xc9\x12\x2e\x60\x42\xb6\x66\xe6\x50\x1d\x9f\xfd\xc1\x96\xc0\x4a\x79\x58\xf2\x43\xe9\x75\x92\x4a\x75\x24\x84\x70\x1f\x26\xe4\x12\x26\x5d\x22\xb5\xbe\xca\x29\x75\xa2\xeb\x2c\xa9\xbd\xab\xcd\xc8\xd6\x91\x57\x7e\xbe\x5e\xec\x96\x26\xac\x9a\x96\x2f\x99\x0b\x85\xe3\x88\xa9\xf0\xbc\x3e\x64\xdd\x7a\xae\x7c\xa6\x8c\x04\x1d\x8d\xf8\x2e\xd5\x6e\x93\x5f\x1f\x85\xea\x9e\x29\xad\xaa\x72\x0f\xa0\x80\x96\x90\xe1\x77\x02\xb8\x7e\xf1\x94\xc8\x55\x93\xf8\xac\xbb\x68\x02\x02\x42\xd6\x25\x6a\xa4\x43\x96\x2d\x68\x31\x1f\x87\xea\x61\x98\xd3\xc5\x36\xa6\x4d\xe3\x74\x9b\x5b\xf9\x1e\x11\x07\x62\xe3\x4b\x19\xb4\x02\x26\x08\xd3\x12\xe1\x79\x68\x7a\x3f\x05\xa8\x84\x1d\x71\xed\xea\x7a\x96\x0c\xe7\x24\x52\x0e\x1b\xaa\x7e\xe8\xbb\x1b\x32\xc2\xe7\xd9\xb0\xa0\x29\x8d\x05\xb0\xf5\x3c\x2e\x2f\xa1\x59\x01\x23\x58\xfb\x82\xb0\xfa\xd2\xc4\x2a\xbb\x3c\xeb\xb8\xb1\x6d\xe2\x88\x43\x69\x5f\x1f\xd4\xaa\xdb\xed\xb8\xb9\x85\x05\xca\x53\x9b\x1d\x92\xd5\x67\xa9\x63\x42\x2b\x5f\x17\x8e\xfe\x7e\x93\x06\x57\x22\xb7\x8d\xc0\xfa\x95\x9c\x62\x13\xee\x8f\x23\x48\xd5\xbd\xcb\xf4\x4c\x97\x02\x50\x71\x1b\xb4\x96\x97\xa5\xf8\x99\x87\x62\x7b\x97\x70\x63\xa4\xb9\x3e\xe8\xdd\x03\x9f\xf9\xa0\x04\x08\x57\xd0\x56\x6c\x8d\xe2\xcb\x8f\xd8\x97\x1f\x91\x3b\x75\x71\x65\x58\x39\x08\x37\x34\xdf\x9d\x4f\x1e\x11\xf0\xc8\xff\x4d\x80\xd9\x31\xf2\x1f\x81\x47\x48\x5d\x43\x5d\x95\xec\xfd\x80\x10\xd6\x67\xa5\xa0\xe9\xf2\x45\x9a\x15\x09\x5b\x39\xe7\x66\x26\x9b\x1f\x1d\x83\x40\xb4\x08\x8e\x01\xee\x3b\x98\xf2\x6e\x17\xef\x76\x5c\x62\xcb\xaf\xe4\x59\xdc\xed\x44\x36\x27\x07\x42\x38\x11\xbd\x25\xd7\xfe\x6f\xf0\x0e\x49\xfa\x19\x95\x25\xce\x98\x28\x14\x34\x4d\x23\x5e\x68\x9a\x05\xe7\xa4\x46\xd4\x1a\x03\x70\x46\x72\x81\x14\x63\x4a\x2c\x06\xef\x34\x36\x73\x9e\x03\x8a\x2a\x7c\xb4\xdf\x8d\x3c\xee\x76\x86\x56\xed\x13\xc2\xa4\x7b\x27\x71\xc0\x5d\x73\x9a\xdf\xa4\xf8\x1e\x4d\xdd\x41\x8a\x39\x71\xdf\x61\x86\x82\x3b\x9f\x64\x6a\x96\xef\x7c\x42\xa7\x9f\x21\xce\xa9\x9a\x82\x38\xcd\x0a\x5a\xa7\x84\x34\x1d\x24\xaf\xf3\xc1\x47\x83\xdd\x0a\x62\xaa\x54\xd4\xee\x1b\x25\xe5\x91\xb6\xec\xe8\x5e\x52\x59\xa7\x83\x81\xe6\x50\xbd\xd4\x5a\x60\xca\xef\x80\x5e\x6f\x91\xf8\x59\xd4\xbc\xb6\x5f\x59\x27\xf3\x01\xa2\x0a\xcb\x16\xf4\x89\xd4\x15\x12\x0f\x58\x37\x24\x9e\xc5\x91\xa0\xb7\x71\xba\x15\xb4\x87\x9a\x1e\x71\xa8\x1a\x49\x90\xa1\xd9\x1d\xb9\xab\x38\xa5\xcc\xe5\x8a\x48\xde\x73\x77\x0f\xb0\xa6\x7b\xba\x37\xab\x3a\x16\xe0\x68\x04\x7c\xea\x8b\xbd\x9a\xb7\xb6\x9e\x72\xa2\x66\x39\x1d\x86\x83\xf4\x69\x78\x93\x27\x9c\x0a\x90\xf9\x69\x48\xd9\x02\x22\x7c\x57\xb1\x79\x7e\x73\x6d\x86\x3a\x7c\x80\x69\x7b\x40\x09\x0f\x54\xc5\x3a\x3a\xf9\x4b\xc6\x13\x9e\x48\x84\xa3\x66\x48\xef\x8d\x56\x18\x78\xd1\xd5\x66\x0a\x1c\x0e\xc4\x91\x4c\x4d\x79\x2d\xf1\xfc\x58\xa6\xae\x44\x2a\x66\xcd\x8a\xce\x81\xfc\xfa\x69\x9b\x89\xef\xa8\x61\xaf\xef\xc1\x59\x7f\x1e\x0d\xfe\x3c\x19\xfc\xc7\x78\xf0\xdd\x5f\xc2\xfb\x09\x3e\x18\x97\x53\xf4\xdf\xd4\x3a\x76\x4c\xe3\x15\x5a\xa9\xc9\x78\xc8\x48\x43\xff\xe7\xfc\x76\x3c\x1e\x9c\xdf\x1e\x8c\x43\x5f\x54\x01\x5c\xdd\xb2\xa3\xf3\xfe\xf9\xe0\x7c\x30\x7c\x3c\x13\x3f\xaa\x07\xa0\xe6\x14\x40\x0d\x29\xf4\xd1\x79\x30\x32\xd6\x96\x26\x22\x2d\xb3\xf9\xe6\xe7\xa3\xf3\xf3\xf0\xfe\xa0\x1c\xc9\x08\xb3\x0a\x52\xff\xac\x11\x4e\x83\x41\x4e\xb5\x99\xe5\x5c\x9c\xcd\x9a\xea\xb9\xde\x19\x6b\xd8\xc4\xa8\xbf\xbf\x3b\x13\x10\x08\xcd\xea\x34\xb8\xfb\xb5\x4e\x24\x3a\x18\xaa\xce\xb4\xdb\x75\x96\x75\xca\x28\x7d\xcb\x15\xb9\xaf\x6f\xa4\xa0\x3f\x2e\xa7\x15\x3f\x8e\xdc\x3b\xc7\x38\x98\x83\xf5\x21\xc0\x60\xfd\x44\xfc\x79\x2a\xfe\x3c\x03\x18\x5c\xa6\x59\xfc\x51\x2c\x11\x05\x18\x6c\x00\x06\x11\xc0\x60\x9b\x02\x0c\x32\xf1\x87\x89\x3f\x69\x22\x32\x02\x0c\x12\xc9\xb5\xcb\x33\xb6\x02\x18\xd0\x2b\xf5\x96\x7c\x14\x45\xa5\xd9\x16\x06\xeb\x5c\x64\x15\x7f\x16\xc9\x35\xc0\x80\x47\x97\x8a\xc7\xb7\xa6\xd1\x42\x64\x8b\x36\x2a\xf8\x0d\xe0\x97\xd9\xe2\x4e\xfc\xe6\xf2\xb3\xf8\x23\x32\x6c\x72\x91\x5d\xd3\x12\x21\x6e\x83\xa2\xc0\xc2\x2a\xdc\xe2\x04\x06\xf7\x91\x18\x66\x4e\x97\xc0\xc4\x11\x01\x3c\xca\x57\x94\x83\x10\x27\x57\xab\x60\x2e\xe9\x92\xb0\xc4\x0e\x84\x08\xe6\x20\xb9\x5a\x99\x6e\xcb\x01\x48\x6e\x24\x06\x97\x51\x41\xf5\xcf\x32\x63\x5c\xf4\x8b\x6d\xb6\x5c\xce\x08\xfb\x08\x30\xb8\xa2\x3c\x02\x21\xae\x2f\x93\xe8\x01\xe7\x62\x2a\xa5\x4d\x0d\x90\xf6\x34\x22\x73\x94\xa4\x3c\x6b\x65\x97\x3b\x22\xb8\x2f\xf1\x67\x09\xb3\x6a\x68\x62\x10\x18\xc4\x09\xa7\xa6\xba\xe6\xc6\x55\xf6\x42\x4d\x3e\x5d\xcb\x5e\xc6\x88\x59\x88\xf5\x5b\xc9\x76\x3b\x86\xb9\x66\x48\x57\xd1\x6a\xb0\x26\xe4\x12\x75\xb3\x08\x02\x3d\x91\x61\xfb\x50\x36\x4f\x42\xc2\xe7\x49\xa8\x38\x13\x19\xe1\xfa\x6c\xdc\x6b\xf6\x54\x40\xb1\xc6\x28\x82\xac\x94\x92\x1c\x47\xce\x11\x1c\x4e\x70\x5b\x78\x11\x1c\x1e\xe2\x4e\x69\x47\x70\xf8\x04\x77\x0b\x29\x82\xc3\xa7\xb8\x25\xd5\x08\x0e\x9f\xe1\xb6\x08\x24\x38\x7c\x8e\xb5\xf8\x22\x78\x3a\xc1\x8a\x74\x0a\x9e\x7f\x87\xb7\x79\x1a\x7c\x3b\xc6\x52\xe6\x12\x7c\x7b\x50\x86\x25\xbe\x2f\xf1\xfc\xdb\xc3\x10\xc1\x6f\x0f\x51\x89\x6b\x22\x2f\x8e\x3c\x0f\x6c\x8d\xf4\xca\x05\xf8\x33\x6a\x65\x09\x11\x44\x01\xcc\xc8\x3c\xc4\x76\x86\x61\x42\x3a\x58\xae\x30\x27\x11\x9a\xe5\x2a\x64\x07\xe4\x38\x43\x41\x8e\xa4\xda\x95\xa9\x4a\x3a\x20\xad\xdc\x5d\x63\x06\x27\xdf\x21\xe4\x2c\x92\x5e\x53\xb0\x2d\xa8\xb4\x63\x8a\x39\x30\x66\x55\xf0\x50\x20\xfb\x0c\x3e\x95\xfe\xc0\xe0\x18\xe1\x88\xb0\x21\x83\x09\xc2\x05\x61\x70\x82\x70\x2c\xdf\x0b\x84\x53\xc2\xe0\x13\xe9\x38\x7c\xc8\x60\x8a\xf0\x86\x30\x78\x80\xf0\x92\x88\xf5\x0c\x36\xc3\x8f\x58\x52\x64\x72\x65\xe3\x61\xa4\x09\x41\x1c\x17\xe2\x74\x6e\x53\x95\xa8\xe6\xa9\xc4\x8b\xce\x18\x53\xb6\x02\xcc\xc4\x9b\x29\x89\x13\x42\x25\xfa\x66\x42\xc1\xc0\x6c\x18\x21\x48\xf1\x1c\xd8\x12\x62\xdb\x9b\xfc\xf2\x70\xaf\x40\x28\x3a\xaf\x0b\x6c\x86\x6b\x04\xb7\x10\x41\xae\xcf\xea\x60\x95\x67\xdb\xcd\x40\xe0\x55\xe2\x8a\xaa\x7c\xf0\x0e\x23\xed\xcd\xe5\x65\x4a\xaf\x28\xe3\x30\xd1\x91\x6f\x61\x2e\x1a\xbd\x2f\x71\x81\xef\x9d\x91\x96\x08\x95\xd3\x85\xa4\x19\xce\xee\x36\xb4\x20\x4b\xbc\x30\x80\x56\x90\x17\x85\x9a\x1f\x50\x6c\x22\x06\x04\x0a\x11\x91\xc5\x67\xd6\xa6\x65\xe5\xcd\x5c\x01\x8e\xa0\x28\xbb\x76\xd7\xdb\x68\x63\xb0\xb1\xb7\xd1\xc6\x75\x85\xec\x08\x9b\x06\x13\xc7\x03\x56\x83\xc0\xc1\x79\x45\xe2\xcc\xc7\xa1\xf6\xad\xc4\x48\x8e\x35\xb3\xc0\x3a\xce\x71\x05\xaa\xa6\x19\x0e\x6d\x80\x47\xca\x78\x9e\xd0\xe2\xe2\x82\xcc\xad\xaa\x63\x77\xf4\x60\x5e\x8b\x1e\x9c\xfc\x49\xdb\xa1\x83\x6b\x61\x52\xab\xaa\x35\x6e\x5c\x62\xca\xb6\x57\x34\x17\xb7\x49\xd0\x1f\xe3\x38\x63\xcb\x64\xb5\x35\xef\xa5\x44\xad\x9c\x68\xa1\x8e\x28\xac\x72\x8d\x01\x9b\x95\x63\xe9\x41\xaa\x99\xea\x44\xbd\xcd\x3d\x4f\x5c\xfd\x65\xad\xf6\xa2\x56\xbb\x2b\xc0\xed\xa8\x7f\xfa\x9f\xf9\xac\xd5\x40\x1e\xce\x27\x21\x31\x8e\xe4\x9d\xc1\x4a\xe2\x72\xce\x31\x0b\x51\xbd\x4d\x85\x42\x77\x0c\xaa\xd5\xa4\xe8\x07\x53\x0d\xcb\x88\x5f\x4a\xb9\x26\xc7\x93\x46\x8d\xeb\xa8\xa8\x55\x67\x10\xa4\xff\xec\x1c\x46\xbd\x6c\x9c\xd2\x28\x77\xf7\x6a\x6b\x20\xba\xd9\x71\xa3\xa0\x16\xc3\x35\x3d\x97\x18\xc8\xa8\x7c\x7c\xa9\xc8\x5f\x8e\x0f\xa9\x8e\x35\x9a\xb2\x4a\x01\xda\x06\xae\x15\x78\x1a\x0b\xa7\x54\xc3\x48\x9c\xcd\x27\x21\xce\xe6\xe3\x50\x90\x53\xbc\x84\xa8\x84\x62\xbd\x3b\x4f\xd5\x4d\xc2\x16\xd9\xcd\x1e\x80\xbe\xc8\x62\xa9\x1e\xe0\x79\x2a\xdb\xd0\x24\x10\x42\xcc\x23\xce\xba\x2b\x96\xaa\x93\x6f\x23\xbe\x26\x84\x88\x9f\x19\x0d\x3a\xf3\x09\x84\xc4\xf3\xc4\xdf\x5a\x6e\x91\xd0\x5d\xc0\xf4\x58\x77\xc9\x2d\xa4\x92\x82\x57\x66\x96\x81\x73\xb8\x00\x82\xe2\x0e\xe8\x12\xfa\xe5\xf4\xd3\x96\x16\xfc\x84\x25\x57\x32\xd0\xda\x2b\x81\x83\xcd\x3a\x53\x87\x97\x09\x5b\x08\xdc\xb5\xcb\xc1\x01\xe5\x67\xc9\x15\xcd\xb6\xdc\x81\x3a\x8e\x23\xf7\x1f\x22\x4e\x87\x2c\xbb\x81\x32\xd2\xce\x84\x1e\x8e\x9e\x8d\xb5\xe3\xad\x88\xcc\x01\xcf\x04\xb2\x94\x27\xab\xb5\x40\xb4\x2e\x33\xce\x33\x81\x68\xa6\x74\x29\xde\xa5\x0b\x03\x81\x5a\x51\x9d\x41\x41\x13\x70\xa3\xde\x43\x5c\x74\x2f\xc3\xdb\x2d\x97\xbd\x7f\x77\x59\xd0\xfc\x9a\xe6\x38\x26\x5d\xd0\x8d\x9a\xcd\x1c\x67\x8c\x49\x17\xcd\x17\x82\x84\x96\x49\x57\xba\x8a\x97\xd7\x94\xf1\xe2\x64\xb1\xe8\xfa\x58\x98\x06\x2e\x1c\xa3\xff\x4c\xa7\x15\x17\xd6\x89\x7f\xc6\x24\x52\x26\x09\xda\x97\x6c\x71\x41\x3a\x53\xd5\x34\xf3\x2a\x92\x52\x4e\x97\x39\x2d\x5a\x07\x48\x9e\x93\xfe\x04\xe7\xe2\x4f\x46\xc6\x53\xc7\x2b\x22\xba\x67\x12\xbc\xf7\x27\x98\x4a\xbf\xea\x9e\x17\x43\xe4\xfa\x26\x44\xf7\x09\x8c\x90\xeb\x86\xcf\x28\x3c\x55\x4b\xa5\x19\x0a\xc9\x12\xd2\x41\x76\x74\x60\x38\x0f\x39\xe9\x8f\x15\x5f\x83\x91\xfe\x58\xb5\xef\xac\x7f\x21\x00\x51\x56\xc5\x1e\x89\x4b\xe8\x0e\xc3\x1d\xde\xc1\xb8\xd2\xa8\xa9\xfb\x30\x37\x33\x5a\x43\x25\xfe\xb3\x31\xb1\x35\xf1\x66\xf3\x9b\x16\xd4\xe3\xc6\xca\xea\x8c\x3a\xe1\x02\xa2\x12\xd3\x9a\x61\xc7\x55\x76\x4d\x3b\x5b\x77\x8c\x99\xaa\x66\x30\xab\xb1\x94\xa7\xff\xc9\x3c\x8f\x1b\x48\xc8\xf0\x04\xe1\x3e\xb7\x7c\x9f\x46\x57\x74\x82\xa0\x6c\xf6\xf6\xa6\xb1\xf2\x7a\xa3\x2a\x46\xc8\x3b\xdb\x0b\x88\x74\x5d\xba\x40\xb3\x9e\x66\xfe\x3d\x5a\x6e\xce\xec\xed\x67\xa3\xf7\xe8\x70\x15\xf1\x35\xcd\x4f\x62\x19\xce\x45\xea\x4d\x47\x85\x79\x2b\x91\x13\x1f\xb4\x53\x03\xc3\x7e\xbd\xcc\xb3\x68\x11\x47\x05\x77\xca\x5a\xfd\xb8\xe3\x71\x7d\x08\x66\x8a\x6a\x61\x22\x8c\xb1\x9d\x3b\xa7\xd0\x00\x67\xb1\x8d\xe4\xb1\x7d\x93\x14\x9c\x32\x9a\x43\xc0\xed\x41\xa3\x6c\x01\xba\x0f\x25\xc2\x1a\xb8\xb6\x8b\xe7\x54\x01\x1e\x77\xaa\x11\x2e\xb4\x8d\x62\x17\x34\xa0\x37\x2d\x20\x04\xeb\xa5\xf7\x14\x35\x6b\x61\x47\x83\xef\xa3\x8a\x26\x14\xc8\xd0\x3a\x49\x17\xa2\x6b\xea\x25\xca\xa3\x98\xd3\xfc\x87\x88\x47\x22\xa1\xd8\x5e\xf2\x9c\x2a\x2c\x09\x05\x0f\x4d\xc9\x0f\xef\xde\x7e\x50\x99\xdf\x66\x8b\x64\x99\xd0\x45\x73\x7c\x0f\xc0\xc1\x71\xeb\x78\x49\xd9\x53\x6d\xe1\x9c\xed\xdd\x58\xbb\x07\x96\x4e\x1d\xc3\x7f\x66\xf5\x3a\x6b\xe8\x5e\xc0\x3d\x4b\xa0\x3b\xd8\xb1\x36\xd5\x90\xe0\x03\xd3\xe3\x79\x0f\x0f\xe7\x2b\x67\xbe\xf3\x92\x79\xf0\x7a\xaa\x5d\x67\x8d\x55\x69\x5d\x45\x5d\x24\x9b\x89\xfa\xa8\xa9\xb6\x0a\x65\x9b\x01\x10\xf0\x69\xb4\x57\x8c\xd2\xef\xff\x27\xab\x0b\xda\xba\xe0\xd3\x8a\xf2\xd7\xda\x2d\x48\x47\xf0\x17\x99\xdf\xb8\x0d\xb9\x30\x16\xdd\x36\x41\x9e\x2d\x03\xde\x6d\xaa\xa8\xd6\xc9\x22\xed\x40\x04\x02\x98\x36\x2e\xcf\x3a\xa2\x59\x33\xb7\x43\x0f\xa1\x99\xdd\x94\x0e\xc5\x19\xbe\x97\x02\xa3\x80\xcf\xb3\xb0\x46\xb6\x4c\xf0\x4d\x9e\x70\xf3\xdc\x22\x61\x2a\x85\x52\xbc\xed\x14\x19\x0a\x4c\x32\xbb\x61\x34\xff\xc1\xe2\xa3\x8d\x04\x43\x90\xfe\x9a\xd0\x9b\xdd\x2e\x2b\xf1\x86\xbc\x85\x63\x2c\xff\x39\xda\x99\x4b\xd7\x5d\x65\xe5\xd7\x4b\xfa\xe7\x2b\x5d\x1d\x4e\xd7\xb5\xbe\x8c\x99\x30\x99\xb2\xb6\x22\xad\x0c\xa0\x20\xdd\x60\x39\x8a\xb4\x15\x11\xc5\xdb\xb2\x4d\x97\xf7\xc4\xfd\x25\xa4\x73\x70\x99\xe5\x0b\x9a\x0f\xa4\xe8\x6c\xa0\xb0\xbc\x50\xe0\x87\xe3\xba\x46\xa8\xcb\x44\x48\x28\xe3\xbf\x49\x97\x56\xcc\xbe\xff\x24\xf1\x40\xc9\xf4\xe5\x9e\xd7\x67\x86\x54\xde\x68\x4e\xc8\x16\x52\x24\x76\xdb\x0b\xe5\xf2\x4f\x09\xe6\x94\x28\xb4\x53\xd3\x89\xdc\x97\x3a\x20\xc6\xc3\x98\x69\xf8\xc0\x56\x91\xee\xd5\xc0\x26\x5a\x2c\x12\xb6\x1a\x00\x3f\x0b\xa7\x62\x6f\x90\x25\x4c\xaa\x08\x1d\x25\xcc\x55\x20\x64\x51\x9d\x9f\x0d\x65\x33\x38\x92\x61\xd1\x36\x7e\x36\x54\xcd\xe1\x82\x2c\x61\xae\x1c\x79\x21\x81\xc3\xc2\x5c\x3b\xeb\x52\x3e\xd9\xf4\x2c\x5e\x66\xb7\x40\xfa\xb9\xbf\xcc\x6e\x3f\x24\x7f\x26\x6c\xe5\x79\x50\x90\x06\xc3\x3c\xdb\xb2\x05\x2c\xfc\x04\xe9\x88\xd3\xc5\x80\x2c\x60\x6e\xf1\x6b\x35\x3a\xe4\x27\x08\x3b\xf9\x63\x3f\x42\x4a\x06\x06\x63\x9d\x5f\x4d\x86\x9e\x04\xe4\x47\x08\xe1\xfe\x1e\xa5\x08\x39\xe7\x16\x00\x9a\x07\xcd\x77\x29\xad\x61\x6c\x4a\x1a\x3d\x1c\x70\xbc\x26\x8d\x5e\x0c\xd8\x74\xd2\x57\x64\xce\x30\xba\x2c\xa0\xd4\x75\x28\x06\x24\x45\xb8\x96\xbe\x46\xaa\xaf\x6b\x3b\xc3\x6f\xa1\x9a\x5b\x2c\x67\x14\x17\x38\x56\x91\x4f\x2f\xbb\x09\x86\x0f\xbf\xfe\xf8\x63\x1e\x6d\xd6\x49\x5c\xe8\x9e\xce\xba\x86\xe7\x7a\x33\x92\xe3\x6c\x97\x2b\xbb\x88\xa4\xce\x82\xba\x80\xe7\x75\xaa\x64\x8a\x6d\xfb\xfd\xf7\xd9\x6d\x59\x1d\xe4\x2b\xa7\xc6\x7c\x76\x09\x29\x9a\x75\x01\x6f\x5d\xb0\x92\x5a\x28\xa0\xa0\xdd\xf5\x61\xe3\x91\x0f\x89\xb5\x08\xc4\x21\x0b\x36\x65\x53\xc9\xb9\xe2\x1a\xdd\xdf\x06\x14\xdf\x05\x1c\xcb\xd2\x01\xc3\xaa\x74\x90\x1b\xa1\x44\x37\x61\x65\xa2\x0a\x59\x54\x4f\x1e\x5d\x32\xc6\xf5\x54\x75\x80\x4d\x72\xac\x3c\xf2\xbf\x97\x28\x43\x05\xca\x8c\xa6\x74\xbe\xa2\xbc\xa2\x2e\xdc\x4b\x2d\xd1\x58\x68\x1b\xbd\xbd\x82\x4e\x61\x54\x0b\x49\x51\x6b\x8d\x62\xed\x30\xaf\xaf\x9d\x08\xd4\x3b\x2e\x0d\xa8\x64\x5f\x5b\xdf\xd5\x10\xea\x97\xac\xfd\xf8\xbe\x66\x25\x5e\xc3\xb9\xdd\xe6\x6b\xfd\x6a\x4c\x99\x71\xe4\xd7\x39\x71\xd6\x79\x1f\x2d\xd5\x7d\x77\xd7\x49\x2c\x76\x6d\x93\x5b\x09\x47\xef\x70\x6e\x5b\xc8\xaa\xea\x92\xee\x63\xf2\xc3\xbb\xb7\xa2\xbf\xef\x69\xb4\x78\xc7\xd2\xbb\x59\xe3\x3d\x50\xb7\x24\x8e\x1a\xc1\xbd\x1d\x83\x1b\xbb\x04\x29\x8c\xf0\xfd\x6d\xc0\xf1\x5d\xc0\xf4\xde\xca\xcd\xde\xca\x30\xcf\x36\x01\xc3\x12\x3c\x05\xdc\xcf\xb1\x82\x3c\x41\xe6\x33\x2c\x4e\x75\xc0\x4b\x84\xa3\x52\xdc\xd9\x9a\x3d\x7e\xaf\x56\x38\xa0\xd8\x99\xd7\x80\x95\xa8\xc4\xd7\xfb\xb6\x28\xe6\x26\x8c\xaf\x54\xce\x97\x3b\x48\xe1\x5a\x0a\xef\x72\xe8\xf7\x5a\xaa\x40\x40\x18\xae\x4e\xed\x67\x03\x40\x9d\xad\x69\x2f\x8e\xd2\xf4\x32\x8a\x3f\xf6\x36\x79\x76\x9d\x2c\xe8\xa2\x17\x15\xe2\x3a\xd6\x9e\xc9\x26\xbd\xa4\x90\x6e\xc8\x22\xcb\x87\x1d\x02\x13\xea\x49\x17\xbd\x20\xb4\x3a\x27\x79\x96\xa6\x02\x25\xd4\xb1\xfd\x4c\x9e\x17\xfc\xf6\x82\xe4\x5d\x67\x44\xd3\x15\x4d\x9f\x05\xfd\x56\x70\x89\xce\x21\x4c\x6c\x0c\x09\xeb\x93\x12\xf7\x2e\xb7\x5c\xc5\x11\x1e\xf7\x36\x39\x2d\x04\xbc\x57\x2e\x5c\x3a\x37\x8f\x85\x77\xfa\xc1\x85\x89\x6a\xbf\xe8\xe8\x7b\x6d\x68\xa9\x4b\x74\xfb\x77\x7b\xd4\x31\x8b\xd9\xb2\x27\x5a\xed\x01\x5d\x12\x0c\x1f\xd5\x9c\x92\xd4\x16\x74\xca\x65\x44\x6b\x81\x10\x41\x3e\x2c\x28\x87\x14\x8b\x26\xa4\x17\x87\xd6\x8c\xbb\x4c\x0a\x97\x59\xe3\x66\xb1\xd8\x2e\x2a\x1b\xf4\x38\xfb\xff\x96\xe1\xb3\xcb\x20\x83\x96\x2b\x1e\xb8\xe4\xe3\x0c\x05\xed\x56\xb1\x6f\x9c\x59\x76\x59\x36\x6a\x2d\x9a\x13\x5e\x51\x6c\x2d\x5e\x8a\xe4\x6b\x5b\x5e\x46\xbb\x3f\x2a\x03\xec\x5c\xde\x76\xc3\xf5\x66\x5d\x46\x49\x37\xfc\x9f\x7e\x59\x1f\x3a\x23\xa5\x73\x7b\xe1\x41\x69\xd2\xd2\x01\xba\xb4\x0a\xa1\xb4\xb1\xea\xbe\x9a\xda\x9d\x33\x90\xd0\x61\xea\xd4\x6f\x2c\x07\xc6\x60\xbd\x82\x5d\x4d\xb7\xfc\xdc\x1a\xb9\x33\xbd\xe9\xdd\x41\xaa\x2f\x63\xdc\xb8\x26\x25\x83\xb8\x09\xf1\xac\xdd\x17\xb6\x0c\x3d\x77\xc6\x1a\x8b\xed\x7c\x6b\xad\x76\x57\x47\x1d\xb9\x05\xad\x0b\x4b\xda\x95\xb8\x37\x74\x57\x5d\x0e\xf3\x4a\xdc\xc3\x27\xdd\x17\xe8\x6f\x34\xfa\xf8\x36\xda\xcc\xc4\x54\xe8\xe7\x40\x5d\x27\x15\x21\xde\xa3\xd0\x1c\x41\xd1\x9a\x7b\x0a\xf7\x79\xb8\x7c\x11\x31\x71\xdc\xc4\x64\xf5\xa2\x9e\x94\x63\x8a\xeb\xa5\x7e\x97\xfc\xb7\x40\x19\x85\x5f\xc4\x2e\x49\x2f\xc5\x2e\xa2\xc6\x6b\x41\xf9\xe9\x70\x92\x27\x12\xae\xca\xab\x3a\x47\xe5\x74\x0e\x34\x1c\x04\x18\x58\x98\x08\x94\x62\x9a\x3a\xae\x20\xec\x66\x22\x5e\x54\x0b\x35\xa7\x61\xf3\x6c\x19\x6d\x04\xc8\xc9\x89\xe8\x93\x06\x0a\x73\x1a\x5a\x51\xbb\x9d\x02\x54\x1a\x8b\xa5\x9b\xee\xc5\xca\x86\xef\x25\xdb\xc8\x1c\xf4\x59\x33\x21\x10\x30\x2b\x22\x37\x5f\x2f\xa8\xef\x10\x06\x57\xda\x06\x8e\x2c\x49\x9c\x6e\xed\x6b\x88\x68\xa4\xca\xf3\xa8\x6c\x95\xfd\xe3\xea\x01\xdf\x3d\x43\xc3\x17\xd9\xe6\xee\x2c\x7b\x91\x26\x9b\xcb\x2c\xca\x17\xd3\xbc\x99\x42\x72\x5c\x69\x23\xe4\x25\xc6\x75\xc4\x92\xb6\x0d\x71\xeb\xf1\x51\x8d\x16\xe1\x7d\x69\xb4\x90\x71\x26\xe8\xeb\xa4\xe1\x5f\x47\xca\xfe\x72\x32\x9e\xe6\x47\x89\x21\xa9\x73\xdf\x47\x8c\x24\xf3\x3c\xc4\xbc\x6e\x40\xb1\xdb\xc1\x6c\xce\x42\x42\xe7\x2c\xb4\xb8\x64\x56\xb6\x07\x6e\xc6\xfa\xe4\xa9\xd2\x85\x98\x8c\x0f\x94\x36\xc4\x64\x7c\x28\xf5\x21\xe0\x64\xfc\x44\xeb\x43\x8c\x9f\x4b\x8d\x08\x38\x99\x1c\x22\x9c\x2a\x39\x48\x4d\xbe\x7c\x96\x5c\xd1\x5a\x00\x98\xaa\x8d\x05\x61\xbb\x9d\x75\xd7\xde\xef\xc3\xc5\x50\x4d\xf7\x2c\x51\x71\x15\x65\x8c\x12\x81\x5a\xf4\xe9\x6e\xd7\xe7\xbb\x9d\x59\xe8\x9a\xd4\xb0\x9d\xc8\x67\x1d\x35\xb9\x4a\xb2\x55\x1f\x12\xbc\x90\xb1\x65\x74\x6d\x4e\x1d\xb5\x58\x33\x1b\x89\xe2\x6c\xa0\x6b\xc2\x55\x39\x4c\x12\x45\xa4\x6a\x6c\x85\xab\xbb\xb9\x32\xe5\x0f\x3d\xab\x95\x56\x8e\x88\xa4\x72\xf9\x25\x89\xa0\x62\x4b\x08\x12\xea\xb2\x56\x76\xbd\xdb\x5d\x22\x47\x43\x41\x86\xa1\x26\x4e\x4c\x7e\xb1\x0f\x08\x21\x85\xae\x41\x99\x6a\xc6\x55\x53\xbd\xd4\x78\x96\x26\x84\xe8\x67\x8e\xb4\xe1\xee\x52\x34\xff\x96\x2c\x75\xe1\xab\x3e\x21\x6f\x6b\xcd\x5f\xed\x76\x6f\x95\x30\x4b\xef\x2f\x39\xcc\x9a\x6a\xb6\x0e\x52\x93\x90\xf1\x34\x39\xaa\xe2\xf5\xf8\x3e\x12\xc5\xe6\x49\x28\x83\x3d\x24\x61\x87\xed\xdb\xe7\x26\x9e\xe7\x77\xf7\x8a\x52\x96\x51\x13\xef\x48\x2e\xae\x65\xa5\xf1\x7d\x6d\xf9\xa6\xd2\x5e\x64\x55\xf5\xef\xae\xb3\x7f\x2b\xed\xc7\x1e\xdf\x99\x87\x84\xac\xaa\x18\x60\xc9\xb1\xe8\xbf\x0a\xac\xb3\x92\x9d\xbe\xab\xf5\x59\x0d\x71\x4f\x81\x05\x11\x45\x70\x7f\x0b\xe9\x7c\x11\x62\x2e\xfe\x74\xc6\xe2\x91\x3b\x6f\xe1\xda\x6e\x6f\x3a\x4c\xfe\xdd\xe0\xc8\x65\x17\x2f\xb2\x2f\x0f\x44\xc7\x61\xd8\xed\x00\x93\x91\x01\xdc\xc4\xca\x79\x05\xec\x66\x97\xc4\xd9\xe6\x6e\x1f\x2b\x45\x3a\x45\x51\xae\xb0\xcc\x35\xed\x79\x1d\x8d\x48\x1f\x3f\x65\x05\xd9\xb6\x5f\x08\x4f\xc7\x12\xc4\x0c\x99\x62\xea\x31\x78\xa0\x21\xcc\xd3\x43\x01\x60\xda\xc4\xb7\x64\xae\x4a\x1e\x75\xde\xe5\xc6\x20\x6f\x05\xfc\x13\xd5\xd3\x1b\x1d\xda\x4a\x36\x22\xf6\x69\x2e\x37\xa8\xd4\xc8\xab\x38\xb1\x49\x38\xe5\x24\xc3\x6c\xb7\x83\x8c\x74\x4a\xf3\x6b\x72\x7a\x66\x7c\x26\xa9\xeb\x51\xad\x99\x0a\x88\x88\xca\xca\x35\x77\x2c\x2e\xf6\x5a\xa4\x76\xc9\x1d\x94\xa9\x8d\xda\x19\xd2\x83\x43\x25\xce\x4b\x05\x57\x91\x0e\xb4\xd5\x21\x55\xd5\x53\x3f\x75\xb6\x4f\x5f\xc6\x1c\x73\xee\xc3\xdd\xce\x5d\x57\x8e\x4a\xbc\x15\xb3\xfb\x04\xe1\x4d\xfb\xda\xac\x54\x2b\xb4\x82\x45\xeb\xfe\x14\xa9\x78\x49\xb6\xc3\x68\xb7\xdb\xec\x76\xfb\x15\x27\x16\x1d\x08\xe0\x72\x58\x89\xc9\x4b\xbc\x26\xcb\xa1\x32\x58\xc4\x97\x2d\x97\x10\xf8\x8a\x5c\x36\x4c\x52\xf0\x5b\x72\x69\xa3\xb0\xe2\x15\x59\xcf\xd6\xf6\xf5\x2c\x5a\xe9\x20\xf6\x53\xe5\x61\xa0\x3d\x5b\x57\x06\x1f\x5e\x89\x49\xa6\xf3\x55\x28\xc1\x8b\x78\x20\x4e\x51\x29\xa7\x57\x10\x26\x41\xf7\xa5\xe2\x4d\xbf\x35\x20\xd4\x51\x77\x82\x7c\x26\xcb\xb2\x40\x6b\xed\x8b\x37\x84\xb3\x12\x5f\xb7\x1d\x5c\x98\x7e\x4e\x95\x0b\xf2\x0e\x04\xff\xba\xf2\xff\x7f\xf1\xd0\xd0\x6e\xba\x0a\x6b\xac\x61\x56\x81\x8d\x19\x98\xab\xc5\xed\x59\xaf\x21\x21\x08\x6c\xe2\xe9\x36\x4d\x43\x10\x5c\x78\xde\x45\xcf\x06\x6d\x93\x56\x2a\x90\xa2\xe0\x44\x74\x63\xaa\x7c\x7c\xef\x69\x4d\xee\xb3\x36\xda\x55\x6a\xa3\xfd\x76\x29\x50\xc8\xa5\x06\x2e\xac\xfa\x53\xde\x55\xb6\x53\x6a\x33\x84\x80\x90\x1b\x39\x0f\x67\x64\xf4\xc7\x79\xe1\xef\xce\x0b\xff\x9b\xd1\x0a\xdf\x92\xd1\x1f\xf3\x81\x1f\x8e\x6f\xe7\xe3\xc1\x77\xd1\x60\x19\xfa\xdf\x8c\x12\x7c\x4a\x46\x7f\x8c\x2f\xe7\xe3\x89\x7a\x7d\x23\x5e\xb3\xf9\x78\xf0\x5c\xbd\xbf\xb4\x01\x5a\xa6\xca\xef\x74\x83\x79\x60\x40\x99\xc3\x87\xb2\x16\x60\xc9\x12\xbe\x73\x6c\xb2\x4e\xa3\x53\x65\xd8\x5b\x39\xa8\xac\x9d\x2d\x03\x32\xa5\x50\xeb\xdd\x72\x66\x9f\x20\x0a\xe8\x94\x12\x71\xef\xce\xb8\x0f\x40\xc0\x95\xed\xa2\xb1\x7f\x68\xb6\xac\x56\x90\x06\xbe\x28\x55\x99\x09\x9c\x61\x60\xa9\x86\x53\x13\x82\xd0\x1e\xfe\xdd\xee\x8d\x49\x9b\xbd\x84\x26\x7a\xcd\x01\xc2\x6c\x76\x10\x7c\x8b\x82\x5b\xfb\xf5\x34\x3a\x0d\x7c\x5a\xe2\x17\x4a\x08\x70\x15\xdd\xe2\x8f\xfa\x31\x61\x53\x65\x13\xdc\x89\x12\xe2\x0c\x27\x38\xc2\x05\x8e\xf1\x96\x8c\xf1\x86\xf4\x27\x78\x29\xfe\xac\x49\x7f\x2c\x99\x26\x0e\x5f\xef\x8b\xe3\xba\xdb\x32\x8e\xdc\xed\xb2\xd2\xdb\xcb\x71\x42\x32\x7b\xee\x48\xa6\x0f\x2b\xde\x12\x8e\x23\x62\x80\x6f\x82\x99\x73\xa9\xba\xdc\xfe\x2d\xa1\xb8\x20\x8e\xaa\xcd\x0a\x73\x84\x37\x52\x06\x10\x44\x35\xee\xbd\xd5\x7f\x1c\xc4\x53\xd7\x8c\x47\xac\x47\xbc\xdb\xb1\x63\x01\x4e\xd9\xd1\x78\xb7\x5b\x7a\x1e\x1d\x6c\x8f\x49\x52\x95\x5f\x59\x16\xc5\x42\x29\x01\xbd\x75\xb6\x8e\x38\x56\xd3\x46\x2f\xda\x64\x0c\x1f\x40\x3a\x88\xed\x92\x2e\x67\x1f\x21\xc3\x89\x48\xdc\x22\x14\x30\x29\x00\xaa\x1a\xbc\x73\x35\xc9\xcc\xac\xac\x3d\x4f\x89\x37\x02\xe8\xcc\x95\xab\xb3\x74\xed\xf6\x13\x33\xf2\xd6\x84\x05\xad\x2e\x42\x9c\x49\x06\x05\x8e\x89\x71\x28\x61\xa7\xa1\x30\x23\xba\x82\xb1\x2c\x66\x9d\xa3\x4a\x06\x82\x55\x67\x42\x1d\x73\x7e\x09\x63\x2b\x63\xaa\x2a\x94\x0e\x6e\x1b\x59\x11\x8e\xac\xb8\x8f\x7c\x80\x82\x04\x18\xe3\x14\x32\x81\xc2\x6c\x48\xbf\xcf\x86\x29\x8d\x16\xe2\x1a\x48\x08\x5c\x12\x70\x15\xdd\xfe\x16\x25\x1c\x48\x37\x44\xb3\x17\xf0\x03\x64\x43\x9d\x26\x8b\x72\x14\x24\x78\x4d\x00\xcf\xa3\x24\x15\x67\x4e\x64\x9c\x89\x7a\x4c\x4a\xb0\x46\xf8\xba\xe3\xaa\xb6\xd6\x71\x85\xe7\x35\x47\xb8\x95\xd2\xce\x98\x64\xc4\x4c\x7f\x89\xaf\x87\xcb\x74\x5b\x57\x3e\x6a\x8d\x78\x16\x05\x77\x70\x01\x05\xc9\x79\xad\x00\xe6\x6f\x7b\xc2\xf7\xf5\xc7\x32\xac\xf5\x7f\xc5\xd1\xb2\xa2\x03\xa6\x5d\x0e\xeb\x19\xac\xa6\x42\x27\x04\x82\xd6\x7c\x68\xa6\x32\x84\x3f\xc9\x6e\xde\x57\x25\xf4\x64\x07\x1c\x57\xd9\x4a\x54\xe2\x1f\xc8\xfd\x82\x5e\x66\x5b\x16\xd3\xe0\x13\x16\xdd\xe5\x3c\xa5\xc1\x6f\x25\xfe\xbe\xeb\x8e\xe8\xc2\x40\x4b\xfc\x73\x7b\x36\x1d\x9e\x03\x69\xe8\x79\x3a\x42\xbf\xdf\x9d\xd8\x61\xbf\x77\x2a\x72\xaa\x2b\xc7\xf3\xaa\xdb\xa9\xfe\xc5\xba\x52\xe8\x12\x69\xda\x1e\x76\x8a\x2d\xbb\x11\x6a\xd3\xa0\xd4\xcd\x2a\x78\xbe\x8d\x79\x96\x13\x42\x6c\x7a\xdf\x3c\x57\xd8\xc3\xcc\xf4\x2e\xb0\x2d\x22\x71\x41\xda\x71\xfe\xbd\xb2\x5f\xae\x73\x9e\xf7\xb0\x9b\x3f\xcf\xf3\x02\x4e\xed\xef\x5b\xda\x1f\x53\x76\xc4\x5b\x12\xfc\x9c\x70\xa9\xca\x30\xac\x14\x39\x88\xfb\xb2\xdb\xf5\x27\x38\x1f\xba\xca\x1c\xd2\xd5\x89\xbc\x23\xc5\x36\xcb\xa5\x39\xb3\x51\xfc\x90\x7a\x52\xfb\x34\x47\xf2\xe1\x47\x7a\x87\x73\x54\x56\xbd\x7c\xed\x9a\x81\x37\x58\x05\xbf\x2b\x0b\x94\x0e\xa1\x53\x5d\x54\xed\x02\x3a\xf7\x70\xbd\xa7\x4b\x9a\x53\x16\x9b\xe9\x93\xac\xc5\x75\x54\xb0\x47\xbc\x77\x49\x29\xeb\x25\x2c\xe1\x49\x94\x26\x05\x5d\xf4\x06\xbd\x62\xbb\xa1\x39\x44\xb5\x1c\x62\xaa\x65\x28\x32\xab\xba\x22\x60\xb4\x13\xd1\xf9\x27\x67\xaf\xfe\x64\x10\xc8\x82\xf2\x9f\xcd\x2e\x78\xb7\x9c\xe9\xd4\x55\x2d\xb5\x73\xf3\x0d\x6d\x4c\xde\xdd\xae\xb3\x94\x54\x30\xaa\x6d\xa2\x57\xee\x04\xc2\x57\xdd\x5d\xd8\xed\xea\x1c\xab\x76\x7b\x84\x63\xb9\x3d\x05\x1d\xa4\xa2\x14\xd4\xb4\x45\x5c\xe3\x08\x5d\xf8\xef\x8a\x0b\xc7\x11\x56\x81\x26\xf0\x4f\x90\x23\xc3\x72\x14\xef\x15\xd7\x51\x55\x29\xd9\x61\xd3\xa6\xe5\x85\x39\x02\x9d\xcb\x6c\x5d\xee\xf1\xee\x03\xf1\x41\x2c\x59\x8f\xde\x6e\x72\x5a\x14\x12\x83\xd8\x16\xbc\x47\x13\xbe\xa6\x79\xef\x92\x4a\x94\xb7\x97\xe5\x75\x90\xea\x30\x7f\x1a\x42\x5b\x15\x2b\xce\xd2\x32\xf7\xce\x59\x0f\xb4\xce\x13\x75\x54\x9c\xda\x56\x1a\xa5\x8c\xc8\xa0\x96\xa4\x84\x92\x83\xcf\x08\xc7\x30\x27\xf3\xfb\x8f\xf4\x2e\x00\x39\x65\x0b\x9a\x03\xac\x2a\xdb\xc3\x6b\xdf\xe4\xd9\xa6\x18\x4a\xa5\xc7\x9c\xb2\xb2\x0c\x91\xe7\xbd\x37\xce\xb4\x65\xcf\x72\x84\x33\x99\x86\x33\x84\x79\x09\xf3\xe1\xcf\xdb\x9c\x5a\x8f\xf1\x0e\x46\xf6\xab\xb3\x3f\x7f\xfd\x7f\x31\x2c\xfd\xf7\xff\x13\xd0\xee\x47\x67\x35\x7e\xfc\xdf\x80\x16\xff\xfa\x3f\x0e\x2f\x6d\xd3\xdf\xd4\x00\xd5\x37\xff\x15\x80\xca\xd6\xfd\x6f\x0d\x73\x4f\xe5\xbf\x6b\xb6\x6f\x65\xb8\xd1\x60\x64\x0f\x5b\x5d\xb9\x67\xbd\x44\x01\x95\x3e\xdf\x30\x95\xd0\xec\x5f\xf6\x01\x48\x43\x16\x4c\xfb\x2d\x18\xf7\x5f\x78\xcd\x5b\xe0\xdb\xed\x2f\xa6\x71\x93\xfe\xfa\xc0\x4d\xfa\xaf\xea\x46\x53\x15\xfe\x28\x60\x78\x25\x62\xa1\x08\xe1\x7f\x83\xff\xfa\xff\x67\xef\x5d\x98\xdb\xb6\xd9\x46\xc1\xbf\x22\x71\x3b\x1c\xe2\x08\x52\x24\xbb\x4d\x5b\x2a\xa8\x4e\xe2\xd8\x6f\xdc\xda\xb1\x1b\x27\x4d\x52\xbd\x3a\x1e\x9a\x82\x6c\xd6\x14\xa8\x82\x90\x2f\x91\xf4\xdf\x77\xf0\xe0\x42\x80\xa2\x9c\xf4\xfd\xbe\xb3\xb3\x3b\x7b\x26\x13\x0b\x77\xe2\x8e\xe7\xfe\x44\x0c\xe1\x40\x01\xd9\x6f\x12\x36\xcd\xe5\x0d\xe6\x51\xd4\x7a\x4a\xd8\x58\x67\x86\x61\x2d\x41\x03\xe8\x60\xce\xb7\x29\x03\xcc\xfa\x7a\x19\x9a\x9a\xe6\x7c\x9e\x27\xb3\x83\x9c\x26\x6c\xeb\xcb\xc9\x0c\xbe\x97\xcc\xbc\xaf\xd8\xa8\x6a\x3b\x99\x6d\xb7\x28\x8a\xeb\xeb\xdc\x32\xb6\x02\xdc\xe0\x93\x96\xc9\x03\x65\xf4\x27\xc1\x10\xae\xe9\xa7\xa9\x36\xa6\x93\xc6\x44\xc5\x87\xb6\xdf\xaa\x9a\xf1\xfb\xaf\x30\x3a\x65\xa9\xa5\xc4\xc2\x58\xee\xbe\xd0\x36\x63\x40\x52\x49\xf1\x8e\x5f\x17\xf3\xc3\x1c\x18\x9a\xe7\x11\x52\x8c\x6b\x83\xc2\x59\xc9\x43\xaf\xae\xe6\x0d\xc8\x0b\x2b\x2a\x08\x47\xce\xc6\xd3\x5d\x59\xaf\x0b\x77\x3b\xbe\x79\x7f\x7a\x62\xe4\x6c\x2d\x06\xcc\xb5\xb9\xc1\x84\xb0\x1e\x35\x62\x14\x9a\xee\x94\x81\xa9\xa8\xd7\x67\xa7\x6f\x8b\x29\x45\x91\x2d\x00\xdf\x4d\x90\x55\x44\x5d\x80\x11\x0b\x23\x2c\xe8\x4e\x8b\x7a\x77\x3f\x80\xc6\x46\x6d\x4f\x19\xfa\x48\xcf\x2c\xbc\x5d\xc8\xb2\xc9\x7b\xb0\x11\xe8\xe2\x95\x40\x57\x61\xe6\xb5\x57\x30\xc5\xc4\x1c\xbe\x02\x93\x5f\x45\x24\xe4\x0b\xca\xe4\xdd\x73\x21\xe4\xc3\xbf\x52\xd2\x58\xa2\x92\xf4\x53\x7a\xa2\xf2\x7b\xdb\xfd\x7d\xe7\xee\xd4\x1d\xfb\xa6\x94\xed\x62\x4e\x84\x15\x34\x13\x95\xa0\x99\x59\xef\x84\x64\xbd\x1b\x68\x46\x49\xf9\x96\x36\x5e\x49\xf9\x26\xeb\x75\xa9\x9a\x4d\x09\xeb\x79\x13\x16\xa1\x5d\x86\x3f\xf5\x9c\xe8\x37\xd6\xc8\x86\x81\xc6\x7b\x66\xbb\x94\x57\x5d\x5a\x92\x24\x0c\xb9\x72\x51\x5c\x86\x61\xd1\x26\x24\x1f\xb6\x59\xaf\xbc\xcd\x16\x67\xec\xb4\x58\xca\x55\x5f\x86\xa1\xdc\x7b\x61\x98\x9a\xf9\xca\xcc\x7c\xe5\x1b\x98\xce\xaa\x34\x69\x0f\x36\x08\x79\x6b\x2d\x17\x61\x56\x9b\x2d\xbb\x65\x94\xdf\x62\xe7\xb4\xbc\x03\x40\x49\x5e\x8a\x5f\x3b\x30\x0a\xa4\x02\x49\x3e\x03\x32\x99\xd7\xe7\x55\x24\xd0\x48\xc3\x5c\xf2\xfa\x0f\x62\xb9\x01\x46\x01\x94\x33\x34\xf0\x20\xb6\x6a\xd1\x59\xf9\x47\x92\x67\x53\x23\xf3\x53\x95\x0d\x62\xdf\xe0\x93\xcd\x80\x68\x10\x07\x6a\x8b\x07\xb5\x41\xbc\x87\x93\x6b\xc1\xb2\xff\x60\x24\xa0\x31\xce\x8a\x29\x95\x33\x01\x87\x50\x6d\xac\x92\xe8\x25\x48\xf4\x62\xea\x85\x48\xf4\x8a\x6e\x86\xe5\x7d\x26\xd2\x9b\x08\x6e\xb0\x6a\x32\xe5\xd5\x91\x26\x25\xf5\x26\xc5\xd3\x6c\x8e\xb8\x32\x53\x60\x27\x01\x68\x26\x06\x7a\x95\x1b\xbf\x3b\xa5\x02\x6e\x98\x60\x83\x86\xd0\x58\x6d\x3e\x9f\x6e\xaf\x88\x4a\xe4\xd6\xfb\x6a\x79\x5c\xba\xc5\xf5\x8c\x1b\x36\xf8\x2e\xc9\x9b\x76\xdb\x9a\x66\xde\x6a\x91\xe2\x12\xe4\x6e\xb4\x2e\xc1\xf6\xf7\x5d\xb5\x79\x14\x65\x95\xd4\x04\xb8\x17\xaf\x76\x39\x4e\x89\xd5\x5b\x3b\x2d\xa6\x14\xe7\x55\xfc\x9d\x5c\xa6\x65\x15\x3f\x03\xb3\x20\xe5\x50\xaf\xa0\x59\x3f\x43\xff\x53\xcb\x67\xc8\x51\xfe\x59\x2a\x9c\x17\x0c\x57\x47\x46\x47\x97\x6c\x2e\x4b\xd1\x29\xd1\xdc\xe9\x05\x79\x3d\x4e\xad\x72\x42\xfd\x61\x5d\x8c\x16\x91\xb9\x47\xbc\x8b\x0c\xe7\x78\x89\xe2\xe6\xac\xfa\x03\x07\xac\xb9\xa4\x97\xd4\xdf\x73\xe3\xfd\x85\xe1\x14\xe7\xff\x7f\x40\xf5\xbe\xdb\x42\xf5\x52\x83\xea\xa5\xe6\xd8\xbf\xce\xa6\xb0\x8e\x0d\x58\x9f\x12\xd4\xf6\xe0\x90\xc8\x8a\x09\x81\x59\x7c\xbf\xa9\x8f\x59\x9e\x7f\x50\xeb\xfd\xad\xad\x55\xa2\x46\x46\xc3\xb6\x7a\x4f\xb5\xe0\x99\x03\xd7\x99\x44\x67\x53\xf5\x6d\x37\xbe\x86\xbc\x16\x5b\x26\x27\x3e\xe0\x15\xa7\xb3\x58\x6b\xaf\xbd\xa3\x33\x6d\x02\x7c\xfb\x6e\x04\xb9\x51\x89\xe8\x7e\xf6\x10\xdd\x14\xe1\x1c\xd2\x70\xde\x8c\xe8\xfe\xea\x18\xac\x58\x39\x6f\x69\x9c\xf6\xae\x8a\x22\xc7\xee\x73\x6a\xd2\x9c\xb3\x65\x92\x9c\x43\x1b\xa7\x3d\xc5\x5b\xc2\xce\xc9\x8e\x53\x63\x06\xc4\x3f\xce\xe6\xed\x48\x7b\xe5\x4d\xb2\xa0\x28\xb2\xc4\x55\xdd\xb0\xa5\xab\xaa\xf8\x06\x61\x0f\x48\xab\xda\x75\xa0\xbc\x38\xed\x25\xec\x11\x1b\xa8\x25\x4e\x7b\x72\xae\xb1\x9a\x7e\x13\x33\x2f\x84\x2e\x6c\xde\x08\xd9\xfb\x62\x4a\x37\xf8\xd7\x9a\xed\x0e\x77\x6e\xda\x03\x7f\x5e\xda\x03\x6f\x4e\x24\x0a\xec\xcc\xc7\x80\xee\x7b\x53\xa1\xaf\xac\xda\x44\xe8\x54\x7f\x74\x4a\x79\xcf\x19\x19\x24\xd8\x81\x29\x79\x00\x35\x2c\x5d\xdf\x0e\x4b\xdd\x6e\x66\x54\x60\x6c\x49\x11\xdd\xff\x24\xbf\x82\x30\xd8\x9f\xdf\x28\xa9\xa0\x85\xa1\xf6\x95\x9c\xc2\x8f\x5a\x10\x6a\xaf\xd9\x2e\x4c\x1f\x0d\x59\xb4\xff\x13\xf2\x24\x9f\x9e\xe2\xa0\x3a\xf2\x4c\xca\x7f\xb5\xe9\xb2\x27\x2a\xe2\x20\xbe\x80\x99\xdd\x64\xd3\x29\x85\xeb\x0f\x44\x7f\x83\xbb\xac\xcc\xae\x94\xe5\x3d\xd9\x7a\x9a\x67\x0b\x95\xe9\x89\x91\xe8\xeb\xd3\xd7\x04\x7b\x41\x7b\x65\xca\x8b\x3c\x57\xd1\xf5\xda\x53\x1c\xb3\xb9\x10\x33\x0c\xab\x6d\xf5\x30\xac\x6c\x52\x18\x5d\xb2\x88\xf5\x8a\x3b\xca\x67\x79\x71\xff\x19\x8c\xb3\xbb\x29\x9f\x20\x65\x1b\xdc\x6c\x24\x51\x7c\xbb\x3a\xdf\xe8\x89\xbc\x1e\x58\xcb\xd2\xb7\x0a\x6c\x8d\x4d\xc5\x43\x6d\xb7\xc1\xac\xc6\xd3\xb3\x22\x9e\x98\x15\xd9\xd6\xc6\x0a\x25\xd9\x19\x9f\x1a\xbd\x20\xc3\x3f\xb5\xc3\xca\x5e\xd0\x30\x4c\x7e\x11\xeb\x75\xf6\x8b\x0c\xbd\x10\xa3\x7e\x9c\xbd\x90\x6b\x57\xbe\x20\x6c\xbd\x4e\x7e\x21\x22\x0c\xcb\x5f\x08\x1b\x65\x5d\xda\xe5\x71\xf2\x8b\x8c\xbf\x60\xeb\x35\xd4\x2d\x7f\x61\xa3\xa4\x2b\x3a\x45\xdc\xdf\x28\x81\xb2\xbe\xcb\x44\x7d\x9a\xb3\x32\xa2\xf1\xdc\xe5\x99\xa2\x55\x4d\x97\x09\xad\x8c\xa3\x92\x30\xf4\x1f\x5f\xcd\xaf\xd4\xa3\x07\x90\x45\xa2\x28\x60\x22\x0d\x50\x94\x8c\xe5\x19\xa3\x80\x24\x5c\x15\x4b\x36\x4d\xf8\x23\x4e\x64\x05\x79\x3d\xe8\xf5\x7f\x03\x9b\x57\x2f\x46\x89\xcb\x46\xaa\x62\x36\xca\x1a\x69\x56\x12\xc7\xd8\x00\x1a\xbb\xdc\xe9\xbc\xfe\x98\xdd\x49\x30\xbc\xa5\x0d\x9b\x55\xa6\x52\x52\x6b\x8c\x44\x8f\x20\x63\xd7\x16\x97\xdd\xa5\x7f\x87\x73\x32\x9e\xe0\x05\xa1\xc3\x65\xb4\x40\x61\x58\x46\x0b\x34\x84\x83\x14\x2d\xc8\x42\x23\xa7\x80\xc1\x12\x42\x52\xb4\xca\x95\x1c\xf9\xc2\xb8\x6d\x5e\x38\x36\x50\x7a\x57\xc5\xf4\x31\x0c\x67\xd0\x50\x7b\x16\xed\xfa\xa6\x3c\x1f\xd1\x02\x27\x28\x0c\x6d\x73\x9b\xca\x8d\xa1\x56\xdb\xbe\xcb\xca\x65\x92\xcb\xfd\x0d\xde\x98\xfd\x68\x4f\xa3\x58\x8c\x51\xae\xb0\xc3\xab\x6f\xab\xa7\x41\x49\xa8\xa8\x76\x3f\x9e\x9b\x9a\x6a\xd6\x3e\xad\xd7\x8b\xe4\x9a\x7e\x3a\x9b\xcd\x4a\x2a\xf0\xa9\x9f\xfb\x59\xe5\x7e\xd6\xb9\xd7\x5a\xbd\x4e\xee\x86\x8c\x5d\x1f\xc0\x29\x52\xc2\xeb\xf8\x91\x5c\x1b\x0c\xf2\x8e\x5c\x6b\x4c\xe4\x25\xb9\x06\xfd\xc3\x4b\x72\xad\x75\x3c\xef\xc9\xb5\xd1\xee\xfc\x02\xa2\x78\x33\x81\xcf\x48\x50\x8a\x84\xc3\x15\xca\xd7\xeb\x80\xd1\x84\xd3\x52\x45\x47\x2f\xe3\x80\xb2\xa9\x0a\xdf\xc7\x2f\x3b\x8f\xcf\xf6\xf0\x7b\x12\xa4\x94\x09\x10\xf9\x20\xc5\xe8\x4b\xe7\xee\xd9\x9e\x2d\x56\x8c\x2e\xe3\x2f\xf8\x41\x2e\xb4\x72\xd6\x9e\x6f\x3b\x6b\x27\xf9\xf8\xed\x04\x1f\x92\x93\x9d\xc3\xb9\x20\x87\x66\x38\x07\xe4\x50\x0f\xe7\x96\x1c\xc2\x70\xfe\x26\x87\x7a\x38\x1f\xc9\xa1\x19\xce\x6b\x72\x08\xc3\xd1\xe6\xc1\xbb\x8c\xd2\xa9\xe2\x6d\xb2\x30\x7c\x09\xc6\xcf\xbf\xc0\xdf\xfb\x17\xe4\x2a\x0c\x2f\x5f\x90\x1b\x48\xbf\x85\x94\x8f\x90\xfb\x1a\xd2\xff\x36\xe4\x92\x87\xa1\x32\x27\xbe\x75\x47\x9f\x20\x7c\x6e\x85\x62\xa2\x57\x3d\xa5\x09\x7b\x42\x67\x5a\x45\x78\xd0\x47\xf8\xd3\x76\x81\xf7\xc5\xa2\xca\xff\x6b\x3b\xff\x9d\x1c\x53\x55\xe2\xdd\x76\x89\x57\x30\xd6\xaa\xc8\x31\xe9\xe3\x37\xa4\x8f\x8f\x48\x50\xc0\x1e\x81\xac\x20\x63\xad\x93\xd1\x49\xcf\x49\xea\x9e\xb8\x97\x6e\xf7\xbc\xfb\x57\xdc\xc7\x1f\x4c\x2d\xb5\x37\xfd\x6a\x2a\xcd\xd6\xd3\xd1\x4f\xdd\x77\x31\x30\xd3\x53\x42\xc8\x09\x3a\x76\xb7\xce\xe8\xcc\xd9\x2b\x67\xdd\xab\xd8\xdf\x49\xd3\xe8\x14\x9f\x76\xae\xf0\x15\xfe\x84\xdf\xe1\xd3\xce\x99\xfc\xdf\x79\xc4\x8f\x28\x3e\xeb\x5e\x3d\xdb\xc3\x6f\x9c\xc6\x8a\xd1\xfb\xd8\xdb\x64\xef\xbb\x37\xde\x26\x7b\xdf\xbd\x89\xa7\xd1\x1c\xcf\x3b\x37\xf8\x06\x9f\xe3\xbf\xf0\xbc\xf3\x5e\xfe\xef\xdc\xe1\x3b\x39\x31\x46\x30\x27\xea\xe3\xe3\xce\x29\xc2\x6f\xdc\x94\x37\x9d\x39\x52\xce\x3d\x6a\x23\xe8\xde\x76\x3f\x79\xa3\xf8\xd8\x79\xd7\xf9\xb0\x35\x92\x5b\xfc\x11\x5f\xc8\x71\x74\x3e\xe0\x33\x6c\x47\x11\xdd\x76\x2e\x9e\xed\xa1\xce\x87\xed\xd1\x74\x5f\x77\xcf\xeb\x23\x8a\x5e\x77\x0e\x64\xf1\xa3\xda\xc8\xfe\xee\xfc\xd5\x39\x8a\xa7\xd1\x6b\xfc\x37\x3e\x90\x63\xeb\x1c\xe1\xf7\x58\x8d\x4c\xbb\xe4\x3e\xd1\x37\x84\xdc\x73\xf8\xb3\x8d\xbe\x2f\x16\xc3\xb3\x0e\xf9\xdc\x8d\xbc\x09\x30\x92\x49\xd1\xe7\xce\x31\x3e\xf1\x9e\xe3\xee\x45\xe7\x03\x42\x08\xbf\xef\x90\x3f\xba\xd1\x9b\xc6\x5a\x7f\x74\xde\xd8\x5a\x6a\xff\x1c\x74\x8e\x10\x42\x9b\x07\x75\xa1\xae\x68\x1e\x9f\x80\xd2\xe4\xb1\xd2\x8f\x7c\x53\x19\x18\x78\xd8\x44\x14\xaf\xcc\x03\x16\x0b\x0c\x0f\x5c\x35\xa1\xb8\x7a\xff\x62\xe7\xd8\x6e\x9a\xbc\x37\x39\x14\x46\x9a\x83\xfe\xa8\xbc\x0d\x38\xa1\xea\xe0\x8b\x6a\x12\x08\xc3\xc2\x99\x21\xc2\x3d\x67\x4f\xd7\x3e\x43\x83\x80\x8c\xa7\x22\xcf\x25\x19\x2b\x0d\xa9\x4e\x86\x23\xe1\x8b\x0b\x55\x9e\x6c\x6c\x2a\x57\xe2\xa8\x9e\x68\x8b\x2b\x49\x55\x38\xb2\xb5\xc5\xb6\x6c\x6d\xe6\xc8\xd6\x16\xc6\xe1\x72\x01\x9e\x96\xb3\x71\xe2\xca\xd6\x26\x93\x21\x07\x79\xa3\x1d\x46\xaf\x9a\x85\x69\x33\x24\xd1\x63\xbb\x1e\x85\x91\xd0\xe1\xb8\xf0\x25\x9a\x2a\x37\x66\x5b\x7d\x14\x4e\x1f\x01\xb9\xee\x0f\xd9\x0b\x6a\x6c\x31\x34\x5b\x62\xf0\x58\x32\x96\x15\xb8\xd5\x34\x77\x9a\x66\xbf\x0c\x46\xac\x3b\x88\x41\xa0\x79\x30\x2c\x5e\xb0\x61\xd1\xe9\x20\x3e\x2e\x7c\x73\x0f\x85\x63\xee\xa1\x66\x0a\xc4\xb1\xd2\x1f\x86\xc2\x9f\x89\x31\x9d\x18\x93\xf0\x1c\x2c\xfe\x2c\x38\xbd\xa3\x4c\xbc\x2e\xee\x95\x2f\xc2\xd7\x0a\xca\x05\x6d\x6b\xdf\x94\x7b\xc0\xc0\xd0\x29\x98\x3b\x09\x40\xe9\xcd\x49\xd8\xd5\x0e\x50\x5d\xed\x14\xbf\xfc\xdf\x3b\xc5\xa2\x59\x57\xaf\x09\x1e\x14\x23\x01\x7c\x26\x05\xa9\x2f\x39\x07\xa2\x2f\xf2\xbb\x7b\xe9\x9e\xb6\xac\x3c\x5b\x50\x06\x27\x4e\x99\xd0\xa7\xd3\x63\x41\xe7\x70\xf4\x38\x2d\x97\xb9\x38\x00\x1a\x5c\x41\xd4\xa4\x66\xc5\xb2\x7c\xe7\xa4\x67\xb2\x0d\x41\xe7\xef\x8d\x0c\xaf\x59\xa3\x11\x1f\xf1\xb6\xbc\xf4\x78\x27\x68\xa9\x96\x82\x4e\x34\x80\x5b\x36\x68\x65\x65\x10\x07\x65\x2b\xe1\x34\x40\x9d\xa0\x95\xdc\x25\x59\x9e\x5c\xe5\x14\xb7\x24\x72\xb9\x5c\xb4\x12\x36\x6d\x4d\x8b\x7b\xd6\x4a\xb8\x84\x5d\x6f\xe9\x63\xd9\x12\x45\x8b\x25\x77\xd9\x75\x22\x68\xaf\x75\xce\x69\x59\xb6\x0e\xe5\xa5\x2b\x73\x65\xa6\x1a\x40\x2f\x88\x83\x20\x0e\xde\x16\xfa\xab\xf0\x95\xea\x0b\xbd\x20\x66\xa3\x2c\x62\x28\x0e\x82\x6a\x4e\xee\x3d\xb6\x5e\x44\x49\xdd\xf5\xc0\x88\x8e\xfb\x93\x58\xe2\x91\x62\x24\x62\x07\xef\xfc\xf2\xa4\xe7\xc3\x9e\xf0\x90\xd4\x33\x0f\x6b\x03\x9a\xf4\x46\xf9\xc6\x19\x07\x37\xd9\xf5\x4d\x2e\xef\x6d\x3a\x3d\x66\x53\xfa\x60\xcc\x04\xff\x01\x4c\x71\x1c\xa8\x95\x0a\x70\xe0\xae\x53\x80\x03\xf9\x85\x60\x52\x5d\x5a\x0f\xb0\xbc\x96\xf3\x0c\xd6\xb4\x57\x1b\xa3\x1d\x6b\x15\x8a\x5a\xef\x9b\x9d\xe8\x6d\xfb\x3a\x00\xb5\x59\xab\x1a\xb5\x41\x08\x3b\x92\x39\x6f\xdd\xcd\x74\x4b\x1f\x61\x27\xdd\xd2\xc7\x83\x62\x5a\x89\xde\xff\x42\xf6\x7f\x0c\x43\xf6\x82\x7c\xdf\x0f\xc3\xbe\xe7\x33\x23\x78\x29\xd7\x37\x40\x23\x1d\xe8\x08\x57\xee\xe7\xa4\xa6\x74\xd5\x1d\x0c\xa3\x6d\xf5\x0a\x89\x78\xbe\xe8\xaf\xd7\xe2\x17\xa2\x3a\x4b\xe8\x2f\xfd\x51\x77\x10\xf3\xce\xc0\x50\x94\x45\xc7\x76\xa7\x78\xd1\x1f\x15\x84\xc7\xc5\x2f\x1c\xbc\x68\xc9\x3b\x09\x56\xe1\x90\x3c\x7a\xb7\xee\x41\x84\xc0\x92\xfe\x81\x62\xee\x90\x20\xd8\x20\xfc\x43\xdf\x35\x81\x73\xe1\x62\x7c\x07\x91\x40\x43\xe5\x57\xde\xad\x46\xf1\x61\xe4\xbe\x51\x07\x0d\x0b\x64\x30\x1b\xb3\x4c\xd4\x61\x89\xbe\x7a\x3c\x9e\x46\x41\x32\x18\x3c\x76\x4b\x91\x88\x65\xd9\x9d\xd3\xb2\x4c\xae\x69\x25\x00\x20\xd6\xeb\x28\x02\x6b\x36\x1e\x61\x10\xe8\x39\x08\xf5\x4a\x2a\xac\xf9\xe7\x28\xc8\xa6\x01\x6e\x6e\x0e\x8b\x5a\x51\x5e\x80\x79\x5c\x55\xae\x21\x3f\xe1\x59\xd2\xcd\x33\xd0\xb0\x5c\x14\x79\x26\x9a\x1a\x81\x42\x9c\xe6\xf4\x2e\x01\xe3\xd7\xc9\x74\x0a\x46\xa2\xca\x96\x36\xa7\xab\x69\xc6\x49\x59\x66\xd7\x2c\x12\x3d\xf0\x8f\x20\x21\x0b\x09\x17\xc7\x41\x3f\xc0\x69\x9e\x2d\xe2\x80\x4b\x04\xa2\xdf\x82\x7f\x28\x30\xd4\xfc\x60\xb0\x78\x08\xf0\x3c\xe1\xd7\x19\x8b\x83\x2e\xc4\x0c\x11\x25\x36\x34\x20\xac\xcd\xe6\x40\x6b\x0b\xed\x01\x20\x0e\x92\xab\xb2\xc8\x97\x82\x06\xda\x50\x04\xb4\xb5\x91\x0f\x88\x44\x41\xe5\x1b\x43\xd9\xf4\xe0\x26\xcb\xa7\x91\x40\x46\x68\xeb\xd6\x10\xb9\x67\x9c\xd2\x2f\x34\x5a\x59\xa9\x09\x45\x4e\x5b\xb2\x5b\x56\xdc\xb3\xb8\x8f\xe7\xc5\xb2\xa4\x1f\x16\xf1\x00\xcb\x2b\xf2\x54\xc6\xe0\xc2\x8a\xf7\xf0\x2d\x7d\x94\x8f\x0a\x6c\xfa\x0f\x8b\x78\xdf\x4b\x90\x81\xf8\x7b\x93\xa4\x7c\xab\xc5\x3f\xd8\x38\x34\xf1\xdc\x44\xdf\x14\x73\x1a\xff\x58\x65\x4e\xe3\x9f\xe4\x7c\xa5\xb7\xf2\x7e\x88\x7f\xc6\x57\xf9\x92\x1f\xcb\x8b\x24\x1e\x80\x59\x37\x76\x4d\x75\x74\x60\x2a\x5d\x2c\x92\x94\xbe\x5a\x0a\x51\xb0\x78\xb0\xa7\x6a\x9b\xe8\x3e\x34\x60\x62\xdf\x63\xab\xae\x3e\x95\x37\x84\xe2\x91\x4e\x2f\x9c\x2b\x29\x1e\xfc\x80\x45\xb1\x4c\x6f\x64\x57\x06\xcf\x37\x08\xff\xbd\xad\xa8\xbe\x43\xaa\xa3\x32\xb2\xeb\x88\x47\x08\x6d\x8a\x71\xc8\x7a\xd9\xd4\x72\x9b\xb3\xe9\x7a\x1d\x4c\xcd\xbb\xdc\x0d\x3a\xea\xfd\x89\x6e\x3a\x1d\x84\x59\x6f\x4e\xd9\xf2\xb8\x2a\xad\xa2\xeb\xb5\x6c\xa2\x13\x74\x65\x34\xc0\xac\x97\x27\x57\x34\x77\x8a\xe9\xb8\x2d\x07\x71\x59\x10\x6e\x62\xa7\xa0\x8e\xdb\x82\xda\xa0\x3b\xf0\x01\xe5\x24\x38\x45\x6d\x8a\x4f\xcd\xb3\x8c\x23\x55\x5f\xd0\x79\x37\xe8\xd0\x8d\xf9\x96\xe1\x3b\xc9\x8c\x12\xf4\xba\x20\x08\x8f\xae\x75\x94\xbc\xfd\x1e\x13\x70\x72\xa1\x20\xc8\xe3\xa9\xa9\x28\x37\x0c\x4b\xf2\x0b\x0b\x5c\x36\xd8\x72\xe1\x3b\x61\x4f\xb7\x3d\x37\xf2\xa4\x45\xc7\x36\x01\xc8\x1c\x83\x0d\x46\x2c\xd0\xd0\xab\xa9\x9d\x2c\x6e\x94\x74\xc0\xb1\x1d\x98\xcf\xb5\xae\x06\x0c\xf3\xb2\x64\xcd\x65\xfd\xa2\x40\xb6\x54\xed\xbe\xa9\xbd\xa8\xbb\xec\x05\xab\x2b\xd8\xac\x97\x26\x88\xd6\x2b\x23\x5c\xb3\x2f\xbc\x92\xe3\x22\x0f\xf2\x62\xf0\xa6\x58\xc9\x3a\xb8\x96\xc7\x57\xf5\xa7\x3d\xa6\x1b\x2c\x10\x0c\x1f\x70\x0b\x75\x7c\xb2\x82\xd5\x27\xa0\xde\xea\xca\x7d\xfb\xd5\x6d\x53\xc1\x08\x71\x10\xe0\xad\x2f\x7d\x65\x54\x58\x41\x15\xf5\x62\xc7\x90\xba\xc1\x54\x2f\x91\xfc\xa8\xfc\xa4\x2f\x89\xcf\xd1\xea\x1b\x27\xe0\xa9\xaf\xfc\xf3\x3e\x7b\x93\x40\xdd\x19\xb0\xc7\xd3\x81\x48\x41\x5b\x4a\x20\xcc\x6b\x63\x79\x29\xb6\x37\x85\x1c\x92\x82\x17\xf4\xc9\x1b\xd3\xc9\x50\x91\x79\x0b\x30\x83\x6d\x6b\x47\x05\x94\xae\x9a\x74\x7b\x59\x9f\x29\xe7\xb4\x6f\x7d\x5f\xc9\x0e\xa8\x39\x43\xbd\xfa\x5c\x60\x60\x7c\x36\xcc\x6f\xd3\x09\xc6\x19\x4e\xc8\x6a\xb3\x83\x56\x6c\xe0\x9f\x36\x60\xc1\x75\x2c\xc8\x01\x35\x95\x4f\x63\x2d\xd2\x73\x6c\xd3\x0f\xe0\xe9\x88\x68\xaf\x2a\x8a\xbd\x45\xde\xe0\x6a\x28\x2f\xd9\xf4\x0d\xcd\x17\x94\x97\x11\xc2\xab\x0d\x88\xb8\x39\x92\x40\xbe\xd1\x11\xe2\x4c\x81\x86\x80\x52\x52\x8e\x64\x24\xa6\xc3\xd4\x9e\x4c\x60\xe9\xbf\x03\x23\x80\x3c\x12\x38\x45\x98\x93\x74\x6b\x24\x1e\x78\x6c\xf4\x43\x57\x1b\xbc\x74\x60\x5f\x1e\x86\xa9\x87\xef\x18\xdf\x54\x36\x01\x9c\x8e\xfa\x65\x10\x4e\x01\x9c\x27\xea\x67\xbd\xee\x63\xd7\xe0\x40\xba\x83\xae\x21\xc6\x74\xd2\x26\x24\x05\x19\xb6\x28\x19\xd3\x09\x84\x91\x86\xdc\x15\x03\x21\x5a\x9a\x74\xb9\xd6\xe5\x81\xf7\xc8\x2a\x03\x42\xb9\xad\x09\x30\x78\x29\x87\xf0\x1f\xaf\x62\xfa\x1f\xad\x62\x8a\x10\xce\x37\xc8\x13\xb0\xb9\x8a\x04\x8a\x90\x37\x13\x89\x71\x4f\xf6\xcb\xc0\xed\x04\x34\xa9\xbf\x9f\xec\xf8\x0a\xd8\x95\x76\xaa\xc0\xf4\x47\x35\xdc\x74\x57\x55\xab\x8e\x94\xb9\x6d\xe8\x2f\x66\x3b\xab\x55\x45\x3f\x94\xca\xb4\x4e\xc1\x76\x77\x70\xa3\xee\x6d\x5e\x14\xe2\x1d\x9d\x35\x6a\x80\xf6\x2e\x65\xee\xdb\x62\x4a\xd5\xc3\x75\x4d\xc5\xbb\xa2\xd0\x2c\xe2\xed\x73\x2b\x4f\xad\xa3\x9b\xba\xda\xc4\x14\x97\x24\xe9\x71\x3a\xfb\x8d\x3e\xe2\x94\x38\xca\x51\x01\xa7\xb3\x20\x2e\x71\xae\xf2\xf1\x92\xb8\xde\x26\x12\x3c\x0e\x54\xad\x00\x43\xc9\x09\xc2\x0b\x12\x39\x56\x56\x57\x9b\x58\xa0\x5e\xb9\x5c\x80\x80\xc7\x3b\x3a\x03\x66\x10\x9e\x55\x8e\xce\x16\x61\xb8\x18\xfa\x7d\xee\x29\x79\x63\xd2\xee\xd7\x06\xa3\xbb\x48\xd2\x7a\x7a\xfd\x03\x64\x36\xd4\x26\x2d\xdc\xcb\x4e\xbd\x0a\x43\x5f\x30\x08\x76\x61\x14\x65\xf2\x7d\x1d\xa7\x13\xf2\x32\xca\xab\xe9\x46\x38\xeb\x49\x9c\x84\x04\x69\x31\xbf\x2a\xae\x8a\x87\x00\x67\x63\x85\x61\xd0\x87\x45\xc2\xa6\x74\x1a\x4c\xc8\xd4\x26\xde\x24\xe5\xa2\x58\x2c\x17\xc1\x84\x04\x79\x56\x0a\xaf\x86\x04\x1e\x65\xe9\x91\x01\x17\xf5\x8b\xaa\xb3\x01\xf8\xcb\xe9\xf4\xea\x31\x98\x10\x0b\x2b\xe2\x0c\xe1\x25\x6c\x01\x03\x7f\x2b\x99\x8e\x92\xac\x2a\xd8\x7d\x9b\xae\x09\x00\xac\xb6\x89\xa1\x48\x4a\xea\x71\x33\xa2\x20\x5b\xd3\x52\x41\xc2\x00\xe0\xfe\x46\x1f\x47\x3f\xc4\x03\x65\xc5\x68\x5e\xdc\xd1\xfa\xab\x18\x31\xbc\x92\x17\x4a\xfc\xfd\x46\x7b\xe8\xd3\x76\x6c\xeb\x20\x84\x7e\x8b\xdb\x7d\xac\x8b\x37\xc8\xcb\x09\x03\xb5\x02\x4c\x15\xa1\x21\xfd\xa5\x0f\x56\xc8\xb7\x81\xaa\xe8\x24\x1a\x60\xf1\xf4\x1b\x86\x9c\xae\xc9\xe3\x63\xb0\x9e\xff\x3d\xd3\xd4\xfd\x21\xee\x7e\xcb\x44\xed\xff\xb3\x89\xda\xff\xaf\x4f\x54\xf7\x1f\xcf\x94\xc2\xf5\x9a\xe7\xc9\x69\x49\xd9\x8c\x57\xe0\x14\x27\x62\xab\x61\x30\xbb\x6f\x64\xbf\x38\x5a\x6d\x4f\xaf\x21\x93\xc0\x54\x00\xe4\xc3\x27\x38\xb3\xdf\x91\x43\x94\x17\xda\x11\x2f\xe6\x6a\x34\x5c\xd9\xf2\x07\xdd\xfa\x62\xbd\xce\xc2\x30\x03\xfb\x56\x15\xde\x3f\xcd\xca\xe4\x0a\xf4\x14\x8c\x99\x7f\x68\xad\x11\x5c\x8a\xd4\xb0\x9f\x6f\xd0\x66\x83\x35\xc2\xeb\x8e\x7a\xd7\x7e\xe0\xb4\xa4\x42\x57\xfe\x01\x7f\x05\x3a\x86\xc6\x59\xef\x0a\x70\xd9\xdf\x6a\xa7\x77\xeb\x11\xac\x1d\x6f\xbc\x0a\x5a\xc1\x37\xf5\x49\xc9\x86\x9d\x52\xb6\xd4\x1d\x1b\xec\xc9\x2f\x23\x83\xda\xfd\xf3\x2f\x03\x8a\xef\xc1\x14\x60\x4d\xcd\x4c\xe1\x51\xc6\x4b\x71\xc6\x4f\x92\x52\x83\x94\x14\xb7\xfb\x7a\x23\xfd\xb8\x81\x5d\x34\xfd\x87\xd5\x07\xba\xfa\x4f\xa6\xe7\xd7\x54\xbc\x87\x71\x29\x4a\x40\xfd\x2d\x33\xfb\xb2\xfe\x8e\x65\x44\xc8\x27\x38\xcf\xd2\x5b\x9c\x90\x48\x46\x80\x70\x8b\x65\x48\x4f\x04\xc2\x25\xd1\xd1\x0f\x0b\x9c\x42\xf8\x55\xbe\xe4\x38\xf7\x1e\x37\x81\xc7\x81\x6e\x2a\xc0\x81\x6e\x07\x42\xba\x1d\x13\xfe\xb0\x80\x90\x6c\x42\x3e\x80\xcb\xa6\x47\x07\x2f\xc8\x4a\x37\x16\xdf\x01\x6c\xa0\x76\x85\x9a\x73\x48\x47\xd8\xb6\x1c\xdf\x01\x3c\xe0\x16\xb1\x7d\xd7\x9f\x8c\xef\xa2\x72\xbb\xc8\x87\x85\x2c\x20\x7b\x12\xdf\x45\x69\x2d\x5f\x26\xa3\x0d\x9e\x91\xbc\x67\x8e\x8a\x9c\xb4\x45\xd3\x83\xa8\x56\x23\x50\xd5\x03\x2c\xdf\xc0\x2a\xe6\x3c\x57\x41\xbc\x1c\x05\xe0\xf0\xb3\x05\x34\x8e\x38\x28\x16\x94\xa9\x30\xae\x3d\x89\x31\xf8\xd2\x4f\x44\xd2\x55\x3b\x36\x00\x67\x6f\x33\x09\xe8\xe5\x68\xd3\x34\x18\xf2\xf4\xf6\x6f\xa8\x23\xe7\xa8\x61\x9b\xbc\x8d\x28\x1a\xee\x38\x89\x63\x01\xba\x1e\xbb\xf2\x14\x61\xc8\xea\x46\x24\x28\x62\x48\xe3\xa9\x5b\x4b\xf8\x95\xfe\x5a\xc8\x8f\xb2\xbb\x8c\x17\xcc\x93\x31\xd1\xb6\xf8\x34\x29\x95\x10\xf2\x64\x61\x25\xb1\x62\xb4\x48\x7a\xb3\x22\x5d\x96\x11\x6a\xa4\xbd\x34\x79\xb3\x61\x0d\x97\xc6\xfe\xc6\xc0\x9a\xf5\x4d\xd3\x68\x75\x57\x7d\x79\xf8\xd5\x2f\x4a\xf4\x02\x28\x91\x72\x5e\x95\x23\xf8\xf6\xd3\x63\xf3\x26\xa2\x82\xac\xbf\x5e\xb6\x97\x4d\x61\xde\x1c\x62\xd9\x3f\x98\x6f\x21\xcb\xbb\xf7\xfb\xe0\x7b\x3b\x23\xd7\x54\x9c\xc8\xed\xbe\x7d\x0d\x35\x9d\x9d\x1b\x31\xcf\x8f\x0a\x1e\xdb\x9e\xe0\x6c\x1a\x5b\x80\xce\x50\x39\xc0\xd0\xe0\x62\xb9\x05\xa6\x3f\x7d\xb5\xe9\x0d\x0a\xe2\x5b\xfa\xda\x52\xb7\x99\x42\x3b\xf4\x75\x06\x0d\xe3\x5c\x5d\x80\x2a\xe7\x3d\x7d\x10\x78\xfb\x7e\x73\xef\x32\xb8\xc1\x64\x40\xd5\x80\xe0\xb1\xf6\x1c\xe9\x36\x13\x4c\x10\x52\xe8\x2d\x08\xa6\xe3\x99\x77\xe3\xe1\x29\x99\xb9\xd8\xde\x8d\x8c\xaa\x4b\xf0\x8a\xcc\xb6\x41\x85\xea\x36\x5a\xaf\xa3\x68\x21\xe1\x70\xdb\x69\x22\x6f\xb9\xd4\x3c\x64\xfa\xa4\x41\x0e\xc2\x8b\x6a\x36\x88\xba\x52\x9d\x42\xf6\xba\x5c\xe8\x59\x22\xea\x4a\x75\x8a\xc0\x75\x88\x97\x64\x81\x1a\x2f\x40\x75\x79\x25\x4b\x51\xa4\xc5\x7c\x91\x53\x41\x83\x18\x40\x7a\x73\xaf\xa9\xfd\x33\xa5\x65\x4a\xd9\x34\x61\x22\x88\x6f\x2a\x5b\x5c\x15\x19\xe4\x2a\x0c\xaf\x7e\x21\xfd\x91\x43\xaa\x8d\xae\x90\x82\x16\x54\x43\x9a\xc2\x5d\x06\xf1\x4d\x0d\x33\xd8\xc2\x0b\xaa\x5d\x84\x65\xcf\x0e\x74\xcf\xe2\xa0\x98\xcd\x8c\x04\xb7\xde\x6d\x7a\xeb\x6d\xf0\xb2\xba\x60\xb7\x27\x68\xd7\x5d\x09\xe7\xae\x09\x7a\xd0\xb7\xe5\x8e\xac\x27\x2e\xcb\xad\x15\xfc\x2a\xed\x51\x1d\xc2\x01\xae\xe0\x62\x07\xba\xb2\x57\xdf\x9d\xda\x64\xff\x90\xa6\xb7\xa9\xf7\xc9\xbf\xe7\x6a\x1d\x6a\xba\xd7\x3c\x45\x9f\xc6\x1b\x26\x0c\xdb\xed\x7f\x72\xd1\xfd\x93\xd2\x3d\xf9\x8e\x96\xf4\x9f\x5d\x8f\xba\x8e\xbe\xfb\x65\x55\x4b\x38\xf0\x22\x95\xc8\xca\xb7\x37\x2e\x9f\x57\xef\xa2\xa7\x5b\xd7\x69\xdf\x5e\xa7\x72\x8f\xd7\x89\x19\xac\x77\x29\x93\x3d\x2a\x86\x7c\x9e\xfe\x3f\x44\xc5\xb0\x8f\xab\xdb\xf5\x3a\x31\xa3\xca\xf0\x89\x19\x55\xfa\x36\x31\x03\x3f\x49\xab\xd0\xb3\x59\xd1\x2a\xb6\x08\x0f\x1e\x65\x61\x19\x86\x4b\x37\x3d\x98\x8c\xe4\x65\xe3\x5c\x2d\x99\xe2\x7b\xa9\x9b\xa8\xa2\x3f\xe8\xfb\x6b\xc7\x7b\x85\xb3\xad\xe5\x48\x48\xd6\x2b\x18\xec\x89\xd3\xe2\x8e\x82\x22\xa4\x8e\xc3\x1b\x96\x42\x5c\x01\xeb\x39\x89\x32\x0b\xac\x67\x8a\x5d\x2f\x6f\xe7\x0c\xb0\x43\xbc\xa8\x1a\x5f\x6a\xc3\x6a\xf1\x12\xcf\xbc\x75\xcc\xe0\x41\xb3\x9f\x83\x47\xcb\x7e\x4c\x3d\x61\x5b\xc0\x7c\x66\x24\x1f\x04\x9d\x07\x13\x34\xb4\x5f\xc9\x47\x91\x26\xc9\x1b\x49\x5f\x9c\x1b\x22\xbd\x15\x26\x58\x20\x14\x1b\xc2\x7d\x3e\x21\x0b\x4d\x74\x4a\xf1\x0d\x89\x22\x21\x21\x7e\xdb\x1b\x00\xe9\xdd\xfb\x23\x6f\x13\xf2\x24\x29\x1e\xf8\xfa\x4d\x78\x7d\xae\x71\xa5\x3d\x40\x94\x12\xd9\xe5\x0b\x23\x37\xad\xb6\xd9\xb7\x02\x81\xf5\xba\x83\x0d\xc2\x7b\x3f\xf4\x15\xc1\xd7\x99\x3c\x40\x36\xa2\xaf\x00\xe3\xe0\xe6\x57\xcf\x31\xb9\x8b\xa6\x35\x8d\xee\x6d\x46\x84\x19\xc7\xcf\x4a\x2d\x57\x20\x80\x0f\x2a\xd4\xc4\xed\xc0\x8d\xbb\x71\x36\xf1\x4d\xe3\x93\x0d\xef\x5e\xf5\xca\xe6\x48\xe3\x2d\x85\xf1\xdd\x0d\x9b\xde\x20\xed\x41\xfc\xe4\xf4\xcb\x3d\xb0\xc1\x57\xf2\xf1\x9c\x55\x9c\xb3\x63\x60\x8f\x6e\xb1\x02\x4b\x32\x9e\x6c\xb0\xbe\xef\x9e\x66\xfb\xad\x36\x08\x53\xf2\x00\x92\x59\xdb\x8f\x9e\xc7\xa8\xd0\xa6\x2d\x3c\x62\x74\xf3\xc0\xff\x5b\xd9\x5d\x5f\xe3\x6f\x49\x24\x92\x6a\x51\x40\xec\x62\x12\xff\xed\x03\xdf\x4d\xb0\xb5\xc4\x32\xbe\xc1\x3c\x0c\xb7\x39\x9e\x5f\x7b\xff\x15\x93\xa8\xc6\x5b\xd0\x52\x3f\x2e\x30\x5b\x10\x6e\xa0\xd7\x8c\xf0\x6d\xe8\x15\xd8\x74\x3e\x4d\xce\xb5\xc9\xea\xa8\x4e\x28\x7e\xde\xf6\x71\xce\x30\x45\x58\x71\x35\xf4\xf3\x28\x51\xe8\xda\x7c\x36\x43\x48\x16\x32\x32\x38\x05\x60\xe2\xff\xa8\xea\xc0\x54\x55\x0e\x16\x2f\x40\xf2\xa6\x26\x97\x64\x40\x1d\x67\x5a\x44\xc5\xb0\xdc\x9a\x93\x09\xd6\x73\xe8\xcc\x49\xa5\x1e\x2f\x33\x5e\x0e\x06\x8f\xea\x4b\xa7\x4a\x14\xa8\xc6\xbd\x75\x76\x5b\xe3\x16\xc4\x0d\x92\x08\x71\xa3\x7c\x02\x76\x64\x0a\x63\xee\x9d\x05\x41\xe7\xb1\x00\x4e\xe1\xb0\x59\xb4\x81\xe3\x0b\x40\x2b\x76\x83\x40\x72\xff\xec\xf5\xfb\x48\x3b\x81\x35\x5a\xdf\x12\x0c\xd9\x75\xb8\x52\x92\xf4\xb4\xc1\x95\xad\xbc\xbc\x7a\xe4\xd2\x51\x19\xa7\x78\x59\x35\x74\x6c\xc8\x48\xb6\xba\x4e\x99\x55\x95\x16\xa3\x65\xbc\xc0\x53\xa7\x48\x85\x85\xcd\xab\x62\xd3\x51\x10\xc4\x53\x7c\x5a\x95\x73\xc5\x69\xf0\x75\x55\xf2\x54\x41\x06\xa7\xf8\xd2\x5d\xfd\xed\xc3\x96\x1b\x18\x7d\xe6\x5e\x1e\x73\x9f\x3e\x7a\xbd\x41\xbe\x6d\xdc\xcb\x1a\x03\xb4\xf2\xe5\x6f\x85\x5e\x6a\xa3\x08\xc3\xe8\xd2\x41\x2d\x49\xe3\xf5\xe4\x37\xab\xf8\xc0\xc0\xc1\xbe\xc4\x6c\xa3\xf7\x59\xa2\x10\x60\x6a\x0c\x78\x3a\x4a\xc3\x15\x14\x67\x0e\xcd\x81\x23\x8e\x5d\x6e\xb9\x63\x70\xe5\x53\x9a\xd8\xb1\x9e\x30\x37\x55\x2f\x9d\x5f\x4f\xbf\x1d\xd7\xdb\x9c\x76\x8f\x4b\x51\xb7\x5c\xa8\x6e\x55\x45\xe2\x96\xf5\x7c\x9e\x28\x45\xdb\xee\xeb\x1c\x67\x58\x2d\x36\xe6\x13\xb8\x61\x6b\xac\x5f\x8e\x46\x42\xcd\xea\x98\x4f\x62\x3a\xe6\x13\xcc\x36\x08\xaf\x34\xc2\x54\x2b\xde\x68\x3b\xd7\xc0\xc4\x95\xd5\xab\x31\x9d\x38\x00\xe4\x96\x38\x8d\xe3\x99\x43\xc1\x57\xc6\x78\xbe\xbb\x5b\x6c\x36\x54\x1f\xd1\x5a\x42\xdc\xf0\xd9\x2a\xb7\x9a\xaa\x5a\x06\xc2\xd4\xe9\x99\xc7\x71\x68\x1a\x9b\xd3\x44\x23\x4a\x54\x13\xa2\x74\xb9\x19\xc7\x53\x30\x18\x2a\x77\xa3\xd2\x99\xf0\xaf\xa2\x63\x26\x8a\x3f\x32\x7a\xbf\x63\x5e\x1a\x59\x22\x75\x0e\x55\xfd\x5c\x6a\x1f\x24\x5a\x98\x01\xbe\x6a\x3e\x13\x69\x07\x4c\x16\xe7\x52\x78\x59\x03\xfb\xaa\xd1\x0d\x97\xdb\x27\xc3\x89\xca\x66\x11\xfb\xa5\x6f\x1e\xd1\x13\xf3\x85\xa7\xd8\x4f\x0c\x19\x16\xcd\xf6\xb3\xc8\x25\x78\x21\x3b\xb5\x93\x6f\xb0\xc3\x4c\x67\x43\xdf\xba\x83\x21\x7f\xd1\x5f\xaf\xdb\xcd\x3c\xbd\xf5\x7a\x27\xff\xaf\xa9\x67\x62\xd4\x8f\x39\x66\x96\x32\x58\xe3\xd9\xef\x5e\xc1\xea\xf1\xdc\x7e\x34\x41\x8e\xd9\xa1\x9a\xf1\xba\x80\x7c\x51\x09\xcf\x67\xf5\xad\x6c\xdf\xc5\x44\x9f\x8a\x29\x2e\xed\x57\x2d\x97\x1c\xa7\x36\x6d\x8b\xb5\x82\x73\x9b\x57\x11\x3a\xf1\xd2\x26\x5a\xec\x14\x2f\xaa\x09\xb6\xd4\x4b\x3c\xf3\x66\x5d\xa5\x4d\xb5\x67\x24\x0d\xcc\xe0\x1b\xed\x7b\xc7\x80\x28\xf8\x8a\xd4\xd8\x57\x78\x4e\x1c\x8e\x1d\x8c\xfa\xb4\x9e\xa2\x91\x07\x7c\x4d\x76\x33\xf7\xf0\x23\xd9\xb5\x78\xf8\x8e\x54\xce\x77\xac\x18\x1c\x7e\xe9\xa4\x02\x88\xaf\xef\x9e\x95\x3b\x7f\x71\x89\x9b\xa6\x2e\x4e\xb1\x37\x6b\x71\x8e\xdd\x09\x8b\x97\xd8\x9b\xab\x78\x81\xdd\x69\x8a\x67\x18\x90\x86\xb8\x62\x2f\x62\x33\x65\xf1\x14\xdb\xd9\x8a\x6f\x70\x35\x51\xf1\x15\xae\x66\xc4\xbe\xb3\xce\xf4\xc4\xa7\xb8\x71\x66\xe2\x6b\xdc\x30\x29\xf1\x23\xf6\xe7\x23\xbe\xc3\xd5\x54\xc4\x2f\xb1\x2b\x07\x19\x9b\xa9\xb5\x29\xd8\x17\x94\x8c\xb5\xa9\x09\xaf\x88\x91\xc4\x8a\x1b\x79\xdf\xd8\x83\xf8\x32\x9c\x4d\xe3\x64\x1b\x6f\x11\x1e\x66\x62\x40\x8e\xc2\x87\x32\x38\xdc\x19\x5b\x56\x3a\x76\xb8\xae\xaa\xa9\xb8\xab\x5b\xc4\x82\x21\xca\xff\xbc\x06\xef\xb8\xf6\x26\xdc\x7c\xf3\xeb\xfd\x32\xa6\x15\x15\x0d\xd3\xea\x76\x9d\xec\xf4\x33\xdc\x92\xcf\xb8\xd2\x22\x5b\xaf\x59\x18\x5e\x83\x89\x41\x9f\xb4\xa6\xf1\x02\x77\x0c\xd4\x25\xb6\x11\x89\x00\x38\xd4\x4b\xb6\x95\x3f\xc0\x6d\x11\x31\xe3\x3c\x32\x0c\xe9\xf6\x25\x28\x13\x3d\x72\xdd\xa6\xc9\x70\x17\xb5\xb2\x4b\x67\x4b\x41\x39\x20\xfb\x11\x7d\x42\x72\xa9\xa8\xf7\xfa\x7d\xb1\x4c\x6f\x4e\x8b\x3b\x4a\x24\xee\x91\x3d\x91\xdd\xdf\xe0\xc4\x1b\x94\xbe\xdf\xed\x40\x70\x7b\x80\x86\x5e\xa5\xf5\x9a\xaf\xd7\xed\x86\xd1\xad\xd7\xb5\xd1\x3d\xff\xef\x19\x5e\x49\x9a\x41\x82\x61\xd9\xe0\xa8\x1c\xc4\xf3\xa7\x40\x8c\x62\x08\xef\x2c\xb1\x5c\x04\x98\x37\xe7\x83\x9c\xbb\xd2\x05\xc5\xc5\x13\x45\xe6\x40\xff\xca\x9e\x28\x01\xfe\xc7\x13\xc7\x15\x19\x5b\x2e\x6a\x6b\xd1\x04\xfe\x82\xaf\x7c\x17\x55\xac\xec\xf1\x95\xcd\x3e\xc2\xeb\x83\xde\x5d\xc8\x8e\xbb\xd9\x75\x7a\x7d\xe8\xbb\x4b\x39\xa3\xdf\x5d\x48\x4f\x00\x5c\x17\xe5\x4d\xb1\xcc\x35\x21\xac\x11\xde\x71\x88\xc1\xd5\x72\xd7\x2f\xa8\x51\xed\x9d\x8f\xab\xb2\x0d\xb0\x0f\x77\x1b\xdd\x6e\x8b\xc6\x62\xbb\x92\x85\x88\xb5\x2f\xf2\x86\x43\xdc\xa6\x76\xc7\x33\x90\x89\xaf\xdd\x86\x4a\x81\xa2\x36\x48\x75\x29\xd7\x51\x81\x9a\x64\xab\xfe\xa6\x86\x26\x9d\x2c\xc5\xce\x99\xd6\xa5\x26\x77\x94\x36\xed\xec\xe2\xf7\xfc\xe0\xde\xf2\x3b\xe0\x9c\x68\x57\xdb\x1b\x84\x15\x8c\xe7\x53\x36\xf5\x27\xdd\x65\x06\xec\xcf\xa4\x3f\x05\x90\x5b\xdb\x49\xce\xa6\x57\xa2\x07\x4d\xf6\x9b\x1a\x7d\x33\xb2\xe5\x42\xd5\x50\x46\x71\xb6\xdf\xa2\xfb\xa8\xc1\x42\x30\x9e\xa3\x61\x0d\x2a\x71\xa4\xd2\xb6\x85\x25\x07\x0d\x79\x9a\xc5\x60\x9c\xe1\x6c\xe5\x6f\xb1\x1a\x6a\x25\xb7\xb9\x18\x83\x86\xbc\xe6\xaf\x3c\xc1\xd0\xa8\x95\xac\x60\xa7\x86\xcf\x54\x90\x53\x95\xa9\xdf\xed\xfb\x88\xfa\x38\x90\x77\x3f\x57\xca\x6a\xa3\x5d\x93\xa6\x5d\x71\x2e\x1a\x7b\x39\x12\xf1\x97\x48\x20\x6d\x6e\x36\xca\xeb\x06\xf4\xb6\xa7\x33\x3a\x8b\x04\x42\x48\xa3\xa2\xca\xa0\x0d\x16\x9b\x28\xef\x39\xa6\xad\xec\x4b\xe3\x1b\x72\xda\x41\x2f\x52\x7c\x60\x8f\x06\x14\xb7\x07\xb8\x89\x86\x16\x5f\xfa\x60\x54\x93\xa4\xb0\xf6\x4c\x13\x04\xb1\xa3\xab\xe0\x49\x4a\xc7\x73\xbc\x2d\xbe\x0d\x89\x95\xb0\x32\x44\x9d\x1c\x05\x37\x42\xb0\x7a\x36\x6b\xe4\x1f\x7d\x49\xc4\x8d\x6a\x0a\xe0\x6f\x6c\x83\x9d\xf7\x33\x7e\xc2\xa7\xc0\x68\xb5\x89\x55\x08\xbb\x12\xfa\xcd\x4d\x8b\x0d\xae\x2f\x2c\x18\xc6\xf2\xb0\xe1\xf8\x74\x83\xa9\xa2\xa2\x68\x29\x07\xb0\x3c\x76\x0b\x1e\x30\x87\x69\x2f\xe9\x25\x5a\x3d\xf7\x9d\xf1\x22\x29\x13\x95\xc5\xae\xc6\x00\x58\x09\x93\x01\x6d\x74\x6c\x77\xd0\x96\xdc\x0e\x24\xec\xb1\xf1\x57\xdb\x16\xdb\x1d\xb4\xdd\x68\x4a\xfb\x96\x00\x98\x3d\x8b\x56\x75\xd8\x21\xb6\x85\x1a\xde\xd5\x2a\xd3\x00\xc5\xb1\xd3\x94\x4f\x19\xa9\xca\x7a\x90\x6e\x6c\x46\x79\x55\x4c\x1f\x4d\x64\x83\x36\x68\xf8\xc4\x76\x58\xaf\xd5\x2f\x98\x0f\xfb\x7b\x83\xbf\xc5\xbf\xa3\x03\xf0\xdd\xd3\xab\x45\x92\xde\x9e\x17\xf9\xe3\x2c\xcb\x73\xa0\x05\x4c\xe9\x82\xd3\xd4\x7b\x27\xd1\x0a\x5c\xab\x26\xe2\x06\x94\xdc\x2a\x5b\x9e\x50\xc1\x44\xc8\x78\xb2\xdb\x72\x78\x90\x17\xc9\x94\x4e\x03\xbc\xf2\xcd\x53\x5f\x53\xd1\x60\x76\x8f\xf6\xf2\xcd\xe6\x89\xc6\xb2\x6f\x6f\x28\xdb\x80\x8a\x69\x6d\xa4\x64\x80\x30\x6d\xf0\x37\xd9\x68\x6e\xed\xfb\x01\xc2\xc5\x93\x86\xe6\xb5\x6d\xf7\x59\x01\x2e\x82\x46\x55\x34\x0a\x38\x4d\x52\x61\x0c\x5c\x06\x28\x7e\xde\x1f\xf4\xf7\x71\xd2\x58\x4a\xae\x54\x92\xeb\x42\xcf\x71\xd9\x58\x68\xc6\x93\x6b\xa7\xad\x1f\x71\xda\x58\x4c\x0d\xe2\x72\x5e\x4c\xa9\x2e\xf9\x13\xce\x9b\xbf\xca\x8b\x59\x96\x53\xae\x8a\x0d\xbe\xc7\xcb\x5d\xc5\xee\xb2\xa9\x29\xd6\xff\x19\x2f\x1a\x8b\x81\x71\xde\x07\xdd\xbb\x41\x1f\xcf\x9a\x07\x51\xf0\xfb\x84\x4f\x2f\x39\x9d\xe9\x92\x7b\x78\xda\x3c\x8e\x65\xb9\xa0\xac\xd4\x83\x18\xec\xe3\x9b\xc6\x62\x73\x3a\x2f\x74\x91\x1f\xf0\x55\x63\x91\x3c\xf9\xf2\xa8\x8b\x3c\xc7\xf3\x6f\x59\x4f\xe3\x26\xa0\x52\x41\x3f\x75\xcd\x70\x08\x12\xdc\x08\xb1\x28\xe3\x67\xcf\xe0\x0b\x7f\x95\xbd\x82\x5f\x3f\x9b\x16\x69\xf9\x8c\xca\xcb\xb6\x3b\xa5\x69\x31\xa5\xbc\x77\x23\xe6\xf9\x28\x63\x77\x09\xcf\x12\x26\x48\xd0\xa1\x98\x91\xc1\x90\xbd\xa8\xdb\xaf\x50\x86\x2a\x3a\x24\x08\x13\x7e\x5d\x8e\x27\xb2\x28\x93\x6d\x7c\x78\x77\x5c\x19\x96\x74\x8d\x58\x98\x47\x35\x38\xcd\x58\x36\xcb\xe8\xb4\xf5\x4e\xf6\xa5\x05\x1d\x68\xfd\x5f\x41\x87\x76\x82\x61\xeb\x2e\x2b\x33\xd1\x0a\x3a\xa2\x13\xb4\x66\x05\x6f\x89\x1b\xda\x9a\x2d\xf3\xbc\xa5\xd5\xd1\x5b\x05\x07\x63\x10\x32\x9d\x15\xac\x3b\x37\x8d\x4d\xe9\x5d\xcb\x79\x9a\xa0\x32\x54\x84\xf6\x4b\x30\x1d\x61\x74\xcc\x93\xbc\x75\x43\xf3\xc5\x6c\x99\xb7\xee\x13\xce\x32\x76\x5d\xf6\x82\x8d\xf2\x9a\xb9\x02\x94\x9c\x09\xf7\x15\x74\xdc\x66\x62\xca\xfe\x5e\xd2\x25\x3d\x2a\x78\xaa\x6d\x41\xc7\xfe\xf5\xa3\xf2\xdf\x29\x07\x64\x8a\x9c\xd2\x54\xc0\x40\xd4\x5e\xe6\x06\x3f\x92\x95\xe3\x8d\xe7\xce\x1c\xf7\x0a\x02\x72\x9d\xf2\xd3\x07\x61\x1c\xf2\x73\x3a\x2b\xc9\xa3\x0b\x04\x73\xc2\xd6\xeb\x6b\xdf\x1e\x89\x67\xee\xe3\xbf\xda\xf2\x9d\xe3\xac\x4f\xbe\xb9\x49\x5a\x99\x14\x25\xab\x0d\x76\xf3\xcb\x66\x05\xc5\x6c\x16\x35\xbb\xa7\xb5\x5b\xde\x4b\xd6\x36\x20\xb5\xe5\x3a\x65\xb1\xee\x34\xfa\xe9\x07\xe3\xc7\x5b\x77\xaf\x57\x9b\x62\x6d\x4f\x1f\x0b\x1c\x98\x7e\x04\xc8\xef\xdf\xac\x5a\x4e\xb2\x25\x13\x5f\x6b\xd6\x59\x7a\xd3\x72\xe0\xd4\x97\x4d\xbf\x74\x6c\xdf\x3a\x9f\xd1\xde\x08\x1d\x9f\xd2\xca\x08\xcc\xf0\xde\x73\xc7\x71\x89\x79\x74\xef\x76\x0f\xe1\xfb\x5e\x56\x9e\x2f\x39\xad\xcd\x72\xbb\xaf\x5d\x0e\xae\xb4\x59\x17\x0d\xce\x9e\x6d\xbb\x53\xac\x39\x86\x7c\x4f\xc0\xae\x6c\x1b\x6c\x89\xca\x9f\xcb\xcb\x92\xe6\x26\x04\x7e\x72\xe3\x76\x7f\xe3\x19\x10\xf1\xdc\xda\xc9\x15\x4e\x94\xce\x79\x09\x3f\x46\xf1\xa3\x4d\x04\x02\x1f\xcb\xad\xcc\x65\x33\xc9\x7d\x04\x7e\xcb\x20\xe4\xa8\xe5\x01\x2b\x2c\x0c\xa3\x84\x04\x41\x07\x22\x08\x0b\x74\xa6\x55\xfd\x31\x47\x61\xd8\x7e\x5f\xd7\x69\x94\xa9\x51\x01\xdc\xb1\x31\x9f\x18\xed\xd0\xfa\x25\xd5\xdd\x93\x9d\x1a\x80\x6d\xc1\xa2\x7a\xfe\x19\x58\x02\x6b\xc9\xac\x17\x69\x75\x4b\xe6\xca\xbc\x4b\x94\x82\x9b\xb2\xe1\xf2\x45\x3a\x5c\x76\x3a\x28\x1f\x2f\x5d\x6b\x3c\xcb\xce\xde\x64\xe8\x34\x96\x6f\xb2\x59\x04\xd6\xde\x5d\x54\xa1\x9a\x81\x94\xd4\x72\x2c\x3d\x41\x76\xdf\x8c\x22\x85\x51\x68\x72\xf6\x77\xdf\xa9\x2d\x1f\x67\x4a\xc7\x88\x62\xb9\x54\x09\xac\x54\x89\xe1\xac\xc6\x05\xbe\x04\x8b\x9d\xf1\x17\x63\xd1\x67\x53\x33\xbf\xa2\x6f\xdb\x26\x6b\xa9\x95\x89\x4a\xda\x33\x1f\x23\x84\x64\x1b\x65\xac\xef\xd9\xbf\x9f\x75\x9e\x5d\xe3\x43\x32\x9e\xd4\x6c\x9a\x60\x60\x4e\x66\xb3\xe8\xd0\x38\xc8\xd5\x8a\xd1\x87\xbd\x45\xb1\x88\x2a\x0f\xd9\xda\x4a\x10\xa1\xb8\x90\x2b\x7a\xce\xe9\x2c\x7b\x20\x02\x17\x00\x4f\x12\x86\x0b\x7b\xcd\x70\x08\x2b\x2b\x05\x85\xb6\x5a\xb5\x52\xd5\xd5\xc8\x55\xe5\x58\x00\x0c\x14\x33\xac\x2b\xc6\x1c\x43\xb5\xb8\xbf\xa9\x59\x51\x31\x36\x8a\x8c\x79\xac\xaa\x03\x3a\x41\xf5\x41\x85\x4d\x37\x6c\x54\xf5\x64\xd0\xff\xc5\x8c\x31\x0c\x0f\x95\x74\x99\x6b\x12\xf6\xb6\xe6\xf5\xc4\x20\x6d\x7d\x7b\x9f\xb7\x68\xa4\x2d\x98\xaa\x49\x2a\xad\x61\x9a\xa1\xef\xfe\xbd\x0c\xc3\x40\x62\x13\x34\x81\xeb\xae\x5c\xaf\x23\xd5\x1d\xb3\xad\x95\x5b\x69\xed\xe9\x58\xa0\x54\x1e\x7b\xd8\xc1\xda\xce\x7c\xa9\xed\xca\x6b\x43\x43\x31\x44\xb4\x68\x4b\x0c\xa5\xc1\x9a\xa6\x32\xe4\xae\xf7\x43\xac\xeb\x0a\xbb\x01\x54\x23\xad\x0c\xaa\xb7\x12\xa8\xb8\x91\x9b\x3b\xb5\xfe\x28\x40\xbd\x3d\x00\x13\x8b\xa3\xa0\x17\x74\xfe\x8e\x04\xee\xa3\x98\x21\x3c\x50\x26\x02\xfb\x98\x91\x2a\x3f\x66\x9d\x20\x0e\xb0\x6f\x34\x49\x20\x54\x1d\xb8\xfe\x30\xaf\x1c\x05\xe5\xc6\x5c\xe4\x92\xb0\xce\xdf\xf2\xa6\x18\xe7\x13\x9c\xa3\x61\xda\x21\x34\x2a\xf1\x12\xe6\x72\x63\xce\xae\x99\x8f\x26\xa7\xce\x62\xb4\x84\x19\x8c\x97\x4d\xd0\x53\xb4\x24\xf3\x30\x14\xe3\xf9\x64\xbd\x16\xe3\xe0\x7f\xfe\x4f\x03\x3e\x05\x13\x34\x5a\x6a\xa1\xee\x06\xa0\x6b\x09\x3d\x17\x64\x69\x3c\x82\x63\x39\x82\x36\xdc\x69\x8c\x3e\x88\x08\xa1\xde\xb4\x60\x74\x88\x54\x8f\x49\xa9\xe5\x9e\xf5\x80\xb0\x1c\x21\x0c\xc2\x5e\x40\xce\xf1\x2c\xf5\xb3\xc6\xe1\x1e\xc4\xe6\x75\xdb\x1f\x60\xeb\xed\x55\x5d\xea\x13\x65\x94\x50\x57\x6d\xdd\x67\xe2\x46\x59\xc2\x5a\x05\x1d\x57\xb8\x40\xa0\xde\x5f\x45\xc6\xa2\x00\xb7\x02\xd4\x09\x36\x41\xcc\x71\x10\x54\x14\x97\x74\x23\x31\x94\x00\xb6\x71\xb5\xb1\xff\x76\x11\xf3\xaf\xdc\x1e\xfa\x3d\x96\x9f\x1b\x6d\xcb\x43\xac\x02\x12\xc4\x01\xe9\x07\x38\x88\x65\x60\x2f\x30\x9a\xf6\xc1\x77\x41\x27\x0a\x82\x0e\x88\x3f\x28\x47\xad\xcf\xc6\x24\x9e\x3c\xbb\xc6\x4d\xcc\x17\x31\xa6\x93\x0d\x42\x9b\x08\xbe\x84\x62\x61\x1d\xfd\x46\xfb\xcf\x9d\xae\x7f\x34\xa8\xa4\x4c\xd1\xbe\x81\xcd\xf9\xc6\xc2\x1c\xee\x4e\xc7\xa9\xf2\xda\xe7\x4a\x9b\x9b\x03\xf8\xb8\xf6\xda\x00\x8f\xb2\x5f\x6b\x13\x6f\xd9\x06\x7b\x15\x51\xcc\x31\x6b\x1c\x12\xdd\x20\xa5\x5d\xa0\x9c\x4f\xbf\x05\xaf\xbe\x51\x1d\x3c\xda\xf5\x1e\x80\xa5\x01\x78\x14\x04\x3c\x0a\xe0\xe8\x40\x3f\x0c\x9a\x39\x62\x9e\x07\xda\x53\x81\x8d\x5c\xec\xa2\x13\xb5\x61\x5c\xeb\x35\x58\xcb\xbb\xa5\x8f\x60\x37\x5b\xae\x5f\x10\xc4\xb0\x24\x30\xc5\x76\x59\x4e\x70\xf0\x5d\xf8\x4c\x6e\x1f\xf9\x87\x21\x84\xb9\xb9\x0b\x9d\x59\x7c\x55\x59\x6b\xd6\x62\xdf\x24\x08\xb4\x85\x0c\x06\x36\x13\x64\xd3\x6c\x47\xb3\x58\xde\xa5\xaf\x31\x78\x2d\xc5\x19\x34\x82\xf0\x41\xa4\xed\x2a\x9d\xd7\x60\x1b\xd7\x55\xa5\xa1\xcc\x9e\x9b\x37\xd0\xb9\x27\xeb\x50\xe2\xfe\xde\x00\x39\xae\xb1\x64\xc5\xbf\xc8\x4a\xc1\x53\xaa\xf2\xeb\xac\x5c\x24\x22\xbd\xa1\x3c\x3e\xc7\x6e\xc6\x2b\x99\x7a\x00\x3e\x08\xe2\x95\x41\xf3\x34\xa4\xe5\x96\x3b\x53\x0f\x32\x3e\x2e\x2f\x8a\x39\x55\x8e\x3f\x14\x35\x8e\x5d\xc7\x76\x14\x12\x89\x50\x46\xad\x62\xbe\x19\x8a\xde\x81\x81\x24\x56\xf3\x64\x11\xd7\xf1\x7c\x3b\x20\xc7\xc7\xb2\xda\xab\xe3\x49\xe5\x6a\x05\x36\x1a\xd8\x7b\xc7\x0c\x61\xbe\xc1\x5a\xc8\xe9\x9b\x9a\x93\xd3\xff\x11\xa6\x5f\x59\x10\x32\xed\xe8\x45\xd0\xaf\x6c\xc3\x26\x96\x15\x9b\x24\x96\xe5\xc4\x20\xac\x7d\xb2\x8b\x02\x0e\x44\x83\xb6\xb2\x3f\x00\xa1\x3e\xbc\xeb\xb0\x60\xb1\xc1\x05\xcb\xfd\x76\xb2\x59\xd4\x7e\x5b\x99\xb2\x36\x4b\x3d\xf8\x7e\xdf\x5d\xea\x0d\x16\x15\x69\x97\xdc\x61\xd1\x3b\xd2\x94\x09\x52\x62\xd1\x3b\xd7\x54\x05\x92\xcb\x88\xeb\xe1\x80\x5c\x62\xd1\xbb\x00\xf2\xc4\x69\x31\xa5\x24\x95\x51\xbd\xfc\x64\x8a\x45\xef\xf2\xf2\xe2\xf0\xe0\xdd\xe1\xfb\xcb\xe3\xb7\xef\x0f\xdf\xbd\x7d\x79\x72\x71\xf9\xfa\xec\xf2\xed\xd9\xfb\xcb\x0f\x17\x87\x97\x67\xef\x2e\x3f\x9f\x7d\xb8\xfc\x78\x7c\x72\x72\xf9\xea\xf0\xf2\xe8\xf8\xdd\xe1\x6b\xf2\x17\x16\x1e\x89\x7a\x4b\x3c\xc6\xd9\xc1\xeb\xf5\x96\xab\x38\x33\xc4\xbd\xe7\x3f\x82\x4c\xa4\x82\xbe\x78\xa4\xe8\x5e\x00\x5f\x82\x87\xe7\x5b\xfa\x88\x4b\xe5\x00\x05\x1c\xa5\xa8\x4b\xc0\x05\xd1\x2b\x4f\x74\xdb\xd0\x39\x4e\x89\x05\x2b\xbf\x02\xa9\xab\xbb\x08\x94\x1c\x25\x96\xe1\x43\xba\xf0\xc6\x37\xe4\x80\x51\xf1\xa5\x84\x8e\x1d\x40\x7f\xd9\x08\xe8\x2f\x15\xa0\xbf\x9c\x54\xf2\x8e\x62\xbc\x9c\x18\x39\xc4\x36\x21\xf9\x48\x42\xe8\xb1\x4c\x55\x37\xc6\xf2\x09\x3c\x60\xb9\x0b\x0f\x58\xa2\x95\x81\xff\x97\x95\xd1\xf3\x05\xe9\x0f\x17\x2f\x96\xc3\x05\xe0\x01\x0b\x17\x0f\x58\x6c\xe1\x01\x5f\xbf\xad\x77\x80\xf0\x29\x6c\x51\x65\xa4\xef\x40\x83\xa3\x8d\x64\xf2\x9a\xad\x29\x38\x61\x38\xa2\xa4\xfa\xe6\x02\x5f\xa6\x49\x9e\x2e\x73\x4b\x24\x9f\xbe\xca\x44\x19\x0b\x7c\xa9\xd7\x53\x2b\x66\xf9\xf1\x3d\x99\x20\x6e\x38\x4d\xa6\x4a\x3a\xa4\x8f\xcf\x35\x15\x4d\x81\x43\x07\x05\x2b\x97\x73\x1d\xdb\xa0\x9e\xc9\x75\x3e\xbd\xc4\x97\x06\x32\xa7\x72\x37\x9a\x2a\x84\x56\xa3\x33\x9b\xfe\xc1\xa6\x1c\x25\x12\xe5\x7d\x6c\x10\xa7\x7c\xe8\x5d\x65\x6c\xaa\xee\xa4\xca\x67\xbb\x50\xc6\x76\xa8\xbc\x0f\x84\xf5\x97\x33\xdb\x76\x77\xec\xbf\x1a\xb2\xb0\x26\xe5\x35\xdb\x67\xa9\xc6\x31\x33\x5e\x31\xd4\xcd\xe1\xfb\xa5\x22\x6f\xb1\xa2\xcf\x3d\xd9\xc4\x15\xbe\x04\x17\x1c\x14\x5f\x2a\x23\x89\x71\x77\x80\x2f\x35\x4e\x63\xfb\x33\xa7\xf3\xe2\x2b\x0f\xfe\x8d\x41\x00\xd3\x62\xbe\x48\xb8\xf1\xff\x01\xea\x4e\x00\xdf\x0a\x68\x69\x59\xd2\x83\x24\xcf\xaf\x12\x4f\xb9\xd9\xd9\x38\x9f\x22\xe4\x16\x52\x8e\x73\x74\xc5\xa7\x36\x9c\xa9\xa7\xca\xb8\xd5\x5e\xd3\xab\xe5\xb5\x92\xef\xf5\xa8\x5b\x90\x79\x38\x9b\xd1\xf4\xe9\x26\x55\x11\xb7\xc5\xe3\xf9\x42\x42\xe1\xd9\x9d\x76\x68\xb4\x75\x33\xfa\x0d\xd4\x8b\xeb\x52\xba\xb1\x93\xe4\xb1\x58\x8a\x6f\xe8\x87\x5b\xd0\xed\xcd\xe9\xae\xc5\x31\x15\x65\x01\xb7\x82\xe6\x6f\x7d\xa5\xd7\xc6\x4e\x95\xd7\xd9\x1d\x16\x83\x6c\x95\x99\x32\x56\x26\x23\xdb\xb2\xc7\x7e\x61\x45\xef\x52\xc5\xef\x28\x2f\xb3\x82\x91\x60\xf0\xbc\x37\xd8\xef\x0d\x82\x6f\xe4\x22\xf4\x95\xd3\x96\xef\x07\xca\x6b\xcb\xf3\xe7\x8e\x65\xd3\xe4\xff\x90\x95\xff\x29\x59\x59\x02\x29\xdc\x7b\xbe\x93\x68\x6f\xef\x47\xe4\xcc\x6a\x59\xf7\x76\x82\x53\x75\x0b\xea\x27\xc9\x25\xa4\xe6\x59\xaa\xcd\x60\xda\x59\xc0\xfb\x68\x28\xf8\xe3\xca\x98\xbf\x66\x38\x47\x9b\x54\x02\xad\xd1\x52\x93\x30\x0b\xa6\x3e\xbd\x44\x9b\x8d\x21\x2a\xe0\x5c\x11\x3d\x96\x32\xbc\x50\xe1\x19\x59\xe9\xa2\x1e\xa0\x95\x92\x76\x1f\xe7\x84\x6e\x1c\xf0\xbb\xee\xa2\x65\x89\x17\x50\xd0\xb6\x5b\xea\xee\xcc\x1c\x6f\xd4\xda\xe3\x0a\xe4\x5f\xa9\x9f\xb9\xa2\x1e\xba\x9c\x0b\x1f\x25\x53\x66\xd5\x02\x6d\x40\xb5\x0b\x02\xc0\xc1\x90\x1a\x00\x45\x39\xb3\x22\xf3\x88\xa1\xda\xfe\xd6\x5d\x2b\xf1\x0c\xdf\x00\xbc\x33\x6d\x76\x91\x2d\x67\x5b\xae\x52\x5a\x5b\xa5\xc1\xcf\x3f\x69\x10\xeb\x8a\xe4\x43\x6f\xca\xd6\xeb\x68\x29\xe7\x64\x41\xae\xd0\x66\x13\x71\x2c\x34\x98\x84\xa9\x84\x89\xfc\xae\xc1\x8d\xaf\xb8\x0b\x50\xbb\x4e\xe3\x87\xaf\x5f\x5b\xb2\x08\x95\x80\xd1\xa3\x79\x06\x1f\xc1\xfa\x1b\xb9\xb6\xea\x8c\x14\x84\xb8\xdb\x51\x77\xf0\x82\xa1\x5a\x8f\x7f\x7e\x0e\x50\xa1\xcc\xbf\x94\x67\x03\x86\x25\x7a\xf4\x41\xf0\x24\x15\xc0\x08\x2e\xeb\x55\x14\x20\x69\x3e\x0e\x34\x4b\x59\x97\x08\x30\x1f\x04\xb3\x0d\x8c\x76\x43\xea\x33\x66\xe6\x09\x1b\xf3\x09\x2e\x89\xc0\x29\x01\xc8\xf2\xbe\x0e\xbb\xa5\x5b\xdd\xfb\x19\xa7\x08\x0d\xef\xc7\xe9\x84\x64\xda\x06\x5f\xd6\x5b\xdc\x24\x25\x9d\xbe\xa3\xd7\x59\x29\xe4\x8d\x5e\xb0\xb7\xc9\x9c\x82\xc1\xa7\x5c\x5d\x36\x85\xec\x54\x8e\xf2\xfa\x07\x0a\x14\x86\x2f\xa3\x7c\x5c\x4c\xe0\xc8\x0c\x0b\xd2\xee\x6b\xfa\x50\x8f\xd7\xda\x1b\x45\x2f\xa3\xed\x54\xa8\x87\x65\x3d\x14\x17\x9a\xd0\xd6\x2e\xea\xdd\xfe\x09\x73\x39\x49\x9b\x8d\x67\xde\xbd\x02\xd8\xbf\x8c\xe9\xa4\xbe\x77\xfa\x7d\x98\x57\x99\x45\x04\x3e\x83\x1f\x67\x36\xc7\x6c\xd2\x9b\xd2\x85\x84\x34\x58\x9a\x51\x65\xf0\xfb\x92\x8c\x27\xf8\x9e\xac\x36\xf8\x8b\xfc\x73\xe6\xed\x93\xf7\x95\x12\x2f\x93\x3d\x05\x5a\x14\xf8\x5a\x46\x60\x1a\xab\x36\x37\x02\xd9\x13\x34\x16\x13\x18\xd7\xe3\x76\x99\xf5\xfa\x71\x2c\x26\x6d\x42\x14\x59\x57\x46\xb6\x06\xb2\x87\x05\x42\x43\x99\x45\x38\x06\x31\xd6\x0d\x0b\xc3\xbb\x48\x1d\xe6\x07\xd2\x8e\x9e\xe4\xfb\x3f\x91\x69\x05\x73\xbf\xad\x54\xcd\x39\x24\x7e\xab\x8e\xd3\x89\xfa\x39\xac\xdd\x23\x17\x1a\x43\xa4\xe4\x4a\xa2\x88\xbb\x9c\x1f\xbe\xad\x5f\xcd\x3f\xf5\x51\x65\x6f\x1b\xa4\x4d\xde\x16\x53\x3a\x54\x20\xf7\x4d\x24\xbf\x1b\x39\x19\x1a\x03\x02\xcb\xad\x35\x3a\xf4\xc9\xe8\x70\x64\x49\xc7\xf1\x21\x19\xd3\x49\x7c\x42\xa8\x4b\x44\x86\x6e\x9d\x18\x3a\xc6\x09\x16\xe4\x50\x2e\xd5\x21\xd1\x83\x92\x83\xc0\x8a\x9f\x42\x49\x7f\x48\x2b\x6a\x29\xed\x74\xd0\x45\x24\xe4\xce\xdb\xec\xa0\xde\xb5\xa8\xe7\xcd\xe2\xa3\x4b\xa5\xa9\x4a\xe8\x14\x97\x26\x86\x56\x1b\xe5\x08\xe7\x6f\x7c\x2e\x6f\xbd\x4f\xb0\xdf\x4c\xfe\x5f\x91\x72\x72\x45\x08\x39\x51\x34\x40\x42\xc8\xe1\x7a\x1d\xbd\x8e\x10\xbe\xf5\x8c\x9a\xbf\x73\x0e\xc9\x27\xe4\x7e\x13\x0d\x3f\x91\x76\x1f\x9e\x2d\x9f\x08\x80\x36\xb3\x8c\x25\x79\xfe\xb8\x92\x5f\xc5\x7f\x45\xfa\xc5\x3a\x26\xcf\xfe\xd7\x38\x7e\xd9\xfd\xf3\x32\xe9\x7e\xf9\xf7\xb2\xdf\x3f\xe8\x77\xe5\xcf\xeb\xe7\xf0\xf7\x27\x88\x1c\x41\xe4\x08\x22\x7b\x47\x47\xff\x5e\xf6\xf7\x7f\x84\x62\xfb\x3f\xbe\x86\xbf\x47\xdd\x7f\x2f\x07\x47\x32\x67\xaf\xdf\x3f\xe8\xc2\xcf\x6b\xf9\x17\x8a\xed\x0d\x7e\x92\x39\x07\x7d\x88\x1c\x1d\x1e\xfd\x7b\xb9\xdf\xef\x0f\xba\xff\x5e\xbe\xfe\x51\xd6\x39\xfa\x19\x72\x8e\x5e\x1f\xc8\xc8\xeb\x23\x88\x1c\x1d\xbd\x9e\xfc\xbf\xb5\x63\xff\xee\xf6\xfa\xdd\x9f\xe5\xa7\x5f\xfd\x28\x3f\xd3\x57\xdf\x7c\x0e\x9f\xd9\x3f\x82\xcf\x7c\xdf\x9f\xfc\x8f\xef\x9e\xe1\x37\x5f\x65\x19\x1e\xc9\x3b\xe9\x83\x77\x27\xfd\xe1\x3e\xb4\x1a\xd4\x48\xd2\x94\x2e\x44\xf9\x4a\x71\x34\x4a\xb2\xa7\x88\xf4\xfb\xea\xe7\x7b\xf9\xa3\x98\xc9\x89\x31\x0a\x27\x2f\x62\xc2\x1b\x12\xcb\x45\x92\x52\x52\xa8\x9c\xf9\xb2\x14\x1f\x4a\x2b\x5d\x43\x58\x25\xbb\x2a\xe3\xd0\x88\xe6\x60\x03\x8a\xa8\xbf\x52\x26\x2c\x13\xd9\x17\xfa\xe1\xdd\x89\x66\x70\x7d\x96\x43\x08\x0c\xe2\xde\x9a\x4a\x2c\x99\x17\xcb\x32\x7f\xbc\xa0\xe2\x18\x5c\x77\xbd\x3f\x3d\x69\x19\x17\x78\x12\xc7\x31\x91\x83\x1b\x9a\xde\xd2\x69\x2b\xb3\xa5\x8c\xd8\x9a\x36\xeb\x7f\x38\x55\x5e\x4b\x3f\x2a\xf8\xcf\x66\xbf\x79\x9c\xaa\x47\xc7\x66\x88\xc7\x9c\x06\xbd\x72\x91\x67\x22\x0a\x5a\xc1\x0e\x33\xb1\x9f\xe5\xbb\xc1\xe8\x3d\xcc\x74\x1f\xb7\x07\x58\xb9\x0b\xc4\xed\x01\x28\x29\x8e\xc7\x81\x9a\xef\x83\x9b\x84\x97\x14\xcc\xde\x40\xbc\x9b\xea\x84\x09\x1e\x07\xe0\xc6\x5e\x4e\x50\x80\x55\x18\x52\xb5\x01\xa4\x00\xb8\xd7\x3a\x45\x2c\x0e\xff\x5e\x66\x77\x01\x86\x70\x97\x42\x64\x32\x79\xd2\x37\xcf\xb8\x3f\x19\x7e\x06\xf7\xfc\xd0\x4f\x81\x07\xd0\xcf\xf1\x60\xe2\x77\x35\x48\xfd\x39\x0a\x70\x30\xe5\xc9\xf5\xb5\x0e\x97\x0b\x9a\xe7\x30\xc1\x01\x0e\x80\x6f\x12\xec\xf8\xae\x37\x29\x7b\xf0\xb1\x9e\x28\x4e\x8a\x7b\xca\x0f\x92\x12\x0c\x1f\x7a\xdf\x4d\x96\xa2\x78\x47\x25\x3a\x24\xbf\x43\x1f\x94\x48\xf3\x3b\xaa\xd8\xdc\x56\x5a\x10\x26\x22\x5d\x96\xba\x3f\x72\xdd\x28\xbf\xa3\x2f\xf3\xc5\x4d\xf2\x0f\xba\xe2\x7d\x3c\x48\xf2\xbc\xb8\x3f\x5a\xe6\xf9\x45\xca\x29\x65\xad\xa4\x7c\x64\x69\x4b\xf6\xe8\x48\x7e\x0b\x42\xe7\x79\xf2\xd8\x32\xf6\x85\xcc\x56\x93\xbf\x94\xb7\x8c\xa1\x05\x13\x38\xcf\x52\xb1\xe4\xf4\x98\xe9\x80\x44\x48\xe6\x6f\x0b\xa0\x51\x24\x82\xb6\x94\x67\x83\x56\x5e\x14\x8b\x16\x2b\x4e\x8b\xe9\x32\x97\x18\x8d\xcd\x07\xc3\x6f\x8b\x3c\x79\x2c\x8f\xc1\xdd\x60\x8b\xd3\x64\x7a\xc6\xf2\xc7\x16\xd7\xd3\xd0\xe2\x6a\xaa\xa6\xad\x32\x2d\x16\xf2\x87\x26\xf3\x9c\x96\x65\x2b\x13\x74\x7e\x21\xd3\xfe\xe1\xbe\xdd\xff\xfa\x12\xa5\xea\x60\x05\x38\x98\x2f\x73\x91\x2d\x60\x05\xe6\x4b\x01\x49\xd6\x16\xc4\xb7\x2c\xc2\x3e\x6e\xf7\xeb\x87\x24\x48\x93\x85\x9c\x2c\xb9\xe3\x8a\x7b\x96\x17\xc9\xb7\xb5\xf5\x7d\xc3\x81\x0b\xd2\x22\x2f\x03\x1c\xf0\xe2\x5e\xfe\x94\xd9\x17\xb5\x79\x13\xf6\x4d\x4d\x3e\x6f\x6a\x92\x17\xf7\x17\xb2\x01\xac\x3d\x88\x7d\x4b\x43\x3f\x7c\x65\x52\x01\x84\xf9\x17\x79\x36\xfe\x77\x37\x9e\x44\xe3\xa4\xfb\x65\x82\x9e\x5d\x57\x57\xf7\x6f\x2e\x81\x7d\x3c\x98\xf4\x44\xf1\x61\xb1\x30\x2d\x6d\xe0\x1a\x61\xa2\xab\xdc\x69\xb4\x92\x3c\xbb\x06\x04\xb8\x7b\x95\x94\x14\x36\x4e\xc2\x93\xab\x2c\xed\xca\xfd\xd7\x32\x89\x5d\x30\xb7\xda\x4a\x93\x85\xa9\x98\xe6\xd9\xa2\xbb\x48\xc4\x8d\x0a\x71\xb9\x1d\xd3\x22\x2f\x78\x17\x54\x0b\x16\x45\x0e\xd7\x62\x53\x5a\x57\x79\x12\x28\x75\x9e\x96\xfe\xd3\x31\x45\xa3\x93\x37\xe9\xb4\x98\x67\x2c\x71\x7b\x46\x99\x3c\x29\xdd\xab\x24\xbd\xbd\xe6\xc5\x92\x4d\x5b\xb3\x2c\xcf\xbb\xc5\x22\x49\x33\xf1\xa8\x22\xd0\x91\x59\x5e\x14\xd3\x2e\x34\xa8\xc3\xb6\x4c\xc1\x44\x77\x96\xcc\xb3\x5c\x87\xe5\x3a\x57\xa1\x6e\x32\xfd\x6b\x59\x0a\x9d\x20\x38\x15\xe9\x8d\x89\x3c\xe6\xba\xa0\xa6\x76\xa8\xc8\xbd\x9a\x8e\xeb\xfc\x71\x71\xd3\x65\xc9\x9c\xea\x60\xc1\x33\xca\x84\x1a\xef\x4d\xc1\xb3\x2f\x05\x13\x49\xde\x90\x79\x47\xb9\xc8\xd2\x24\x6f\x41\xa9\x6e\x32\xbd\xeb\x3e\xe8\x70\xc1\xb3\xeb\x8c\x75\x1f\x5a\xd9\x3c\xb9\xa6\xce\xd4\xe4\x54\x08\xca\xbb\xf2\x19\x85\xa8\xec\x42\xc6\xae\xf5\x88\xe7\x09\xbf\xa5\xbc\x4b\xd9\xd4\x04\xe7\x99\x0d\xc2\x46\x6c\x15\x77\x94\xc3\xba\x1a\xe7\x28\x55\x8a\xb8\xc9\xd2\x5b\x26\xaf\x85\x45\x92\x31\xd1\x05\xb7\x2c\xad\x45\xc2\x8a\x92\x76\x07\xad\x45\x01\x6b\xa9\xb0\xf5\xb2\x65\xfb\x04\x4b\xcc\x44\x0b\x04\x8e\x9d\xae\x96\xa2\x58\xe8\x7e\x41\xd0\x2c\x44\x29\x78\x76\x4b\x25\x88\xbe\xbc\xbe\xa9\xba\xe1\x27\x57\x7d\x29\x05\x2f\x6e\x69\x77\x9a\x94\x37\x20\x0c\xee\x26\x28\x37\x87\x26\x45\x0e\x22\x4d\x16\x6e\xf4\xaf\x22\x63\x26\x3e\xcf\x84\x1c\xe8\x3c\xb3\x15\x9c\x1e\xc9\x28\xb8\x86\x01\x5f\x35\xdd\x84\xa5\x37\x05\x57\xe1\x29\x4d\x0b\xf5\xd2\xab\x78\x35\x42\x89\xe0\xd4\x26\xb3\x4a\xaa\x46\xb0\x64\x59\x5a\x4c\x69\xf7\x2a\x9b\x66\x36\xc2\x25\x8c\x22\x63\xa2\xec\x2e\xe4\xac\xce\x5b\x77\xdd\x44\x3e\x4c\x57\x54\x64\x69\xeb\xae\x7b\x93\xb0\x6b\xf9\x95\xbb\x6e\x36\xa5\xc5\x35\x4f\x16\x37\x90\x3e\x4f\xc4\x0d\x9d\x27\x6a\xeb\xdc\x81\x67\xe8\x2e\x05\x6a\x67\x4b\xee\x28\xd8\x47\x8f\x2a\x68\xb7\x91\x1b\x7b\x6c\xdd\x17\x7c\x6a\xb7\xd0\x3d\xcf\x60\x07\xcd\x8b\x29\x6d\x3d\xcc\x73\x56\xc6\x0f\x79\xc6\x6e\x5b\x0f\xfa\xc0\x7f\xfd\x69\x30\xa8\x95\xe1\x05\xff\x0b\xff\x86\x9a\xe0\x07\xff\x1d\x85\xaf\xc4\x49\x2a\x96\xf2\x15\xd3\x31\x9e\xf2\x22\x37\x31\x27\x58\xde\x14\xf7\x3a\x28\x32\x61\x93\xc1\xb2\xfe\x7f\x5f\xff\x00\x44\x8a\x9f\x3d\xbb\xbf\xbf\xef\xdd\xef\x03\xe9\x73\xf0\xf3\xcf\x3f\x3f\x83\x8f\x05\xd5\xed\xfe\x30\xcf\x63\x79\x37\x05\x18\x82\x79\xc2\xae\x75\x10\xe0\xdb\x5d\xb7\xfd\x7f\xa5\x1f\x9f\x4e\x4f\x64\x5f\x7e\x7a\xc6\x0c\x14\xed\xf4\x47\x24\x57\xc6\x95\x58\xca\x8b\xb2\x3c\x83\x95\xfe\xa6\x47\x67\xf0\xb5\x97\xfc\x73\x0f\x46\xff\x86\xd3\x99\xae\x14\xd8\x84\x40\x55\xd7\x4b\x79\x03\x29\x5f\x9b\xc3\xbe\xec\x70\xc9\x53\x59\x52\x55\x48\x14\x02\x0f\x40\xeb\x5c\x69\xba\xfc\x57\xbb\xde\xb7\xef\xe5\x77\x84\xff\x07\x4c\xdd\xea\x51\xfd\xbd\x12\x92\x53\xc4\xb2\xcf\xdb\x24\x97\x91\x5c\x43\xe0\x02\x0d\x35\x33\x96\x14\x23\x90\x07\x04\xbc\x25\x6e\xf3\x30\x8c\xf6\x2c\xa2\x1f\x86\x51\x50\x00\x4d\x64\xdc\x9f\xac\xd7\xc1\x99\x09\x83\xf3\x72\x25\x9e\x34\x1e\xc8\x9c\xb7\x26\x8c\x10\x5a\xaf\xa3\x3a\x2d\xd4\x65\x2d\xef\x22\xb8\x08\xd7\x1b\x51\xad\x5a\x1b\x74\xad\x95\xe5\x17\x10\x4a\x35\x32\xd1\x43\x23\x4a\xa6\xdb\xd0\xd2\x68\x96\xd6\xa2\xe4\xd1\x4a\x90\x54\x0f\x62\x5d\xab\xaf\xa4\xd1\x8c\xdc\x9b\x49\x96\x63\x37\x1f\x1b\xb5\x59\x1d\x99\x8c\x95\x65\xe2\xa0\x4d\x48\x44\x49\x6d\x35\x15\x6d\x3c\xea\xe3\x1f\x10\x0a\x43\x65\x46\x4c\x79\x72\x1f\x6a\x98\x3a\xb6\x62\xdc\x1b\x3b\x3c\x64\x3b\x94\xcd\x22\x5e\x0d\xca\x19\x35\xd2\x03\xd4\xe3\x56\x72\x72\xfb\xa6\x31\x01\x23\x69\x7d\x6f\x1b\x97\xd3\xa9\xd2\x7e\x88\x8d\xd3\xf2\xf2\x6d\xf2\x36\x12\x48\x25\x3f\xaf\x27\xaf\xd7\x83\x5f\x44\xe5\x05\x1d\x68\x32\x05\x48\xbe\x46\x4c\x73\x79\xb9\x32\xca\x0b\x0e\x63\xb7\xd9\x3f\xed\xf6\x1b\xc5\x13\xf8\x80\x29\x5a\xaf\x4d\xec\x08\xb4\x27\xa3\xe3\x9e\xa0\xa5\x88\x28\x1a\x7d\x90\x27\xa2\xdd\x8f\xa3\x23\x15\x90\xc7\x16\x6d\x22\x81\xf4\xb4\x83\xe4\x1e\xd5\xfa\xb8\x95\xd1\x76\x81\x62\xea\xbb\x6f\x13\x18\x04\x7a\x50\x5c\xd4\xf1\xf2\x11\x1d\x17\x1e\x52\x3e\x21\xb6\xe5\xfd\xb6\xd9\xe5\x61\x18\x04\x31\x8b\x23\x41\x0a\x1f\xe5\xc7\xbc\x9e\x02\xd7\x17\x7e\xba\x77\x11\x23\xfb\x84\x90\xa8\xd0\xcd\x23\x45\x68\x28\xc2\xb0\xdd\x57\xd2\x88\x41\x2c\x3b\x8c\xf9\xc8\x1f\xc8\xdb\x0b\xa0\xdd\xb3\x86\x01\x32\x84\x10\xda\x7c\xb7\xe5\x4d\xa5\x59\x64\x28\x90\x47\xee\xbb\x5e\x73\x66\x4d\x84\x09\xe1\xa7\x5b\x75\xe4\x8d\x1a\x9a\x75\x72\x49\x4d\x1a\x49\x5d\x62\xbf\x92\x67\xff\x2b\xea\xfd\x0f\x34\xfe\xf7\xbf\xff\xfd\x6c\xf2\x0c\xff\xf9\xad\x1a\x41\x94\x92\x3f\xbf\x41\x25\x48\x34\x17\xab\xe9\x04\xb1\xe6\x52\x5b\x4a\x41\xbc\xb9\x5c\x93\x56\x50\xb1\xe3\xc3\x75\xb5\xa0\x6c\x67\x39\x5f\x2f\x28\x69\x2e\x57\x57\x0c\x2a\x77\x16\xd3\xab\xea\xf4\x72\x30\xc0\xe9\x8e\x81\x37\x28\x12\xe5\x3b\xc6\x5e\xd7\x24\x5a\x3e\x5d\xee\x12\x0c\x1e\x43\xe1\xbd\x3e\x5e\x34\x17\xf6\xf4\x8e\x66\xcd\x65\x3c\xc5\xa3\x69\x73\x19\x70\xe7\xac\x3f\x36\xc0\x37\xf4\x3f\x53\x4f\xba\xa2\x5b\x0a\xaf\x84\x36\x49\xf2\x52\x25\xe7\xd0\x24\xc5\x4b\xc9\x0d\x0d\x43\x3a\xbe\xa1\x93\xf5\x9a\xd6\xe5\x78\xf5\x91\xb0\x5f\x9c\x53\xcd\x0f\xa8\xc9\xbf\x19\xd5\x85\x46\xe7\x58\xa8\xd2\x03\xce\xca\x45\x9e\xc0\x85\xb6\x5e\xd3\x1e\x83\x5f\x5b\x77\xdb\xc5\x6b\x25\x5e\xa7\x1f\x0f\xf3\x6e\x30\xaa\x6f\xff\xc0\x48\xa1\x05\xea\x55\x10\x36\xe3\x5c\x9d\x24\x95\x5c\x54\xc9\x66\x9f\xab\x0c\x6e\x33\x2a\x11\x35\x9d\x95\x57\x59\x66\x2b\xa9\x8c\xe5\x56\xc6\x89\xdc\x3a\x1b\x5f\x12\xd9\x8e\xc1\x74\xbd\x2e\x23\x9e\xd8\x66\xb4\x64\x88\x15\xf6\xd1\xdf\xc9\xb6\x0a\x18\x81\x21\x5d\x20\xa5\x71\x05\xdf\x4a\x2c\xc8\xca\xf7\x10\xe1\xcf\xb5\xd0\x73\x1d\x04\xb8\xb6\x0a\x51\x00\xfb\x64\x14\x1c\x59\xc1\x9e\x08\x38\xfc\x28\x88\x9d\xb4\x40\xbf\xba\x0b\xd3\x27\xd8\x0a\xea\x99\x50\x39\x53\x3f\x47\x75\x48\xe7\xcd\x68\x0c\x3c\xa4\x01\x08\xca\x6a\x71\x9e\x11\xed\xb9\xd2\x3c\xc8\xa9\x6d\xfd\x6e\xfb\xbb\xef\x94\x56\x20\x7d\x10\x0c\xa7\xc5\x8a\xc6\x76\x76\x45\x72\x6d\x81\x0a\x0d\x4b\x68\x38\x01\x7e\x7e\x54\x3f\x83\xbe\xfa\xfd\x39\x56\xd6\x2e\x82\x40\x89\xf5\xb7\xa8\x05\x6f\x0c\xc7\xfc\x72\x4a\xaf\x96\xd7\x20\x8e\x0a\x92\xcc\x2a\x7e\x01\xe4\x4e\x9c\x11\x67\xfc\xda\x85\x38\x80\x5d\x32\x9d\xab\x74\x84\x39\xc9\x70\x46\x82\x00\x17\xa3\x8c\x04\xad\x28\x11\xad\xa0\x53\xf4\xe4\x06\x94\xb3\x6f\xb1\x92\x5f\x71\x10\xa0\x4e\x10\xcb\x4c\x89\xc9\xbe\x05\xb5\x03\x58\x03\x25\xf9\x1b\xb4\x22\xc5\xb6\x9b\xb6\xae\x1e\x5b\x41\x87\xc9\x3c\x84\x19\x09\xfe\xcd\x5a\xad\x56\x2b\x63\xad\xa0\x13\xf1\xf5\x3a\xf8\xa0\x18\xfc\x01\xea\x64\x1b\xd1\x21\x0c\x53\xd8\x1d\x72\x36\x37\xf7\x37\x59\x2e\xa7\xd0\x6e\x13\xc7\xb9\x3b\x4c\xad\x0f\x83\xea\xc3\x56\x81\x97\xbe\x4a\x84\xab\x07\xb1\xad\x39\x51\x01\xc6\xb1\x3d\xc4\x3e\x00\x19\x04\x0e\xcb\xed\x91\x7a\x0e\x17\x2a\xe3\x84\x00\xa1\xb2\x62\x0a\x13\x26\x21\x52\xe5\x0e\x14\x36\x92\x07\xb8\x4a\x40\x1e\x08\xa0\x57\xc5\x43\xa0\xa1\x73\x9e\x4c\x33\x05\xf6\x3b\xec\xb4\x3b\xaa\xd4\x5b\x2e\x81\x3c\xfe\x9e\x27\xe9\x2d\xe5\xa0\xda\xec\xa5\x34\x08\xd3\x41\x27\x47\x96\xcc\x1a\x6b\x02\x3b\x66\x86\xeb\x73\x4d\x85\x03\x8f\xbc\xa6\x65\xca\xb3\x85\x28\xb8\x92\x76\x37\xaa\x69\x15\x73\x08\x7c\x27\x92\x20\xe8\x58\xee\x72\x03\x07\x3a\x0c\x7d\x4d\x17\xbd\x3a\xcc\x55\xf0\xab\xee\x1b\x30\xd3\xb6\x2b\xab\xa4\xa2\x72\xc2\x78\x4d\x05\x98\x2a\x2d\xa9\xf0\xcd\xce\x6e\x6b\x60\x0b\xbc\x4a\x01\x56\x5a\x7e\x45\x01\xbb\xa8\x7c\xcb\xa2\x0d\x2e\x69\x4d\xe2\x19\x86\x8a\x33\xc7\x01\x2d\x45\x4f\x69\x7e\x0b\x4f\xed\x9b\xf5\xaa\xc8\x06\xe1\xd5\x35\xd5\x72\x98\xdb\xfd\xe0\xf0\xf1\x5a\xae\xed\xc1\x06\x97\xa2\x58\xc0\x3a\x7b\xd6\x23\xb6\x76\x05\xd1\x26\x29\x72\x2a\x68\x4b\xae\xd1\x66\x23\x91\x1e\x97\x39\xfb\xd2\xbc\x88\x6d\x07\x97\x33\xfb\xd8\x6b\x0c\xd6\x57\x54\x98\x92\x31\xc7\x69\x86\x11\xa9\xbd\x30\x74\x8c\x65\x71\xbd\xe5\x68\x4f\xef\xb9\x51\x20\xf8\x92\x06\x71\x30\x4b\xf2\x92\x06\x31\x55\xba\x31\x20\xbf\xca\x91\x42\x2e\x23\x70\x91\xa5\x9a\xa4\x08\x10\xf3\x4a\x61\x95\x7a\xa6\x0d\x4d\xb3\x56\xe3\x2c\x5a\x6d\xe4\xa4\xfb\x8c\x3a\x2d\x2f\x89\x5d\x5e\x9e\x49\xbb\x73\x23\xba\x35\xad\x92\xc1\x46\x2c\xa6\xbd\xcb\x7b\x9e\x2c\x16\x94\x83\x4c\x9d\x31\x73\xaa\x1b\xde\x38\x3d\xbb\xf7\x7a\xa6\xc0\x0b\xd1\x73\x3f\x29\xd1\x0f\x3f\x05\xab\x05\x6a\x57\x03\x19\xd9\x50\x55\x54\x7f\x6c\xc8\xc8\x35\x35\x82\xdb\x6a\xda\x46\xfa\x37\x66\x08\xd7\x7a\x4a\x56\x7e\x57\x63\x8e\x75\x82\xb1\xc9\x56\x39\x6b\x8e\xfd\x7b\xc7\x88\x5a\x55\x97\x0f\xa4\x8c\x6a\x5d\x8d\xbd\xae\x38\x57\xe1\x17\x3d\x13\x2a\x3f\x12\x55\x15\x14\x86\xbf\x47\x14\x57\x7c\x1e\x30\x0b\xe6\xb8\xc0\xd7\x35\x75\x0b\x7a\x87\x5d\xd3\x48\x98\x6d\xc2\x75\x67\x2a\xc4\x9c\x21\xc7\x7e\x33\x1f\x45\xda\x1a\x5c\xa0\x6e\x58\xa8\x26\x41\x35\x08\xb4\x95\x0f\x78\x1d\x23\x80\xbc\xc6\x36\x0f\xe2\xf5\xec\x4a\x47\xab\x5c\x5e\xcd\x33\xb8\xb8\xe5\x33\x05\x06\xca\x20\x82\x5c\xb1\xec\x6d\xbc\x54\xdf\xb1\x68\x28\xb6\xb0\x3d\x9d\x33\x7a\x80\xe1\x2a\x01\x12\x86\xe2\xed\x82\xee\x9e\x09\x50\x18\xba\x15\x60\x76\xdc\x02\x08\x61\xb3\xfb\xf4\x3c\x1b\x15\xad\xfa\x8e\x82\xb1\xfa\x49\xa4\xdd\xae\x97\x72\xd6\xe7\x3d\x75\x24\x39\x76\x8e\x47\x42\x6b\x4f\x8f\xa0\xb2\x1a\x6e\xd6\xb2\x6d\xe7\xb7\x4d\x08\x0f\x43\x3d\xbf\x6d\x98\x6c\x47\xf5\xe0\x4e\x99\x16\xd6\x34\x19\xb3\x2d\xac\x0f\x39\xb8\x1d\x9b\x8f\xac\x3a\x70\x6c\xbd\x16\xee\xc6\xb0\x8b\x2d\xe4\x09\x72\x7b\x49\xc4\x06\x20\xcb\x88\x11\x05\xe8\xab\x9d\x23\x43\x24\x08\x9c\xd2\xd5\xcc\x3d\x7d\x59\x60\x68\x8e\x55\xad\xb8\xfa\x76\x0f\x76\x66\x5d\x6b\xe4\x61\x48\x7b\xa0\x1c\xf0\x7a\x97\x23\x24\x39\x04\xb5\xda\x6c\x54\xeb\xff\x57\xa6\x22\xf6\x8b\xbb\xdb\xbf\xde\x0c\x73\xdf\x8b\xb7\xd4\x17\x2e\x22\x45\xb4\x32\x52\x14\xfa\x1e\x05\x97\xca\x91\x68\x00\x40\xaa\xd7\x81\x5b\x8d\x27\x4b\xb5\xa5\xbe\xda\x4f\xa5\x17\x27\x3a\x44\x1b\x63\xde\x44\xc2\xea\x5a\x20\xb5\x20\x56\xf5\x02\xec\x03\xdb\x6e\x9e\x50\x8f\x74\x29\x81\x30\xe5\x5a\xa0\x04\x23\x6a\x20\xbf\xa2\x85\x1d\x0b\xd2\x1f\x16\x2f\x98\x11\xa9\x2a\x3a\x1d\x24\xc6\xc1\x77\x41\x87\x8d\x8b\xc9\x84\xb4\xfb\x50\x92\x91\xfe\x90\xbd\xa0\xae\x84\x72\x41\xb6\x37\xfa\x77\x12\x16\x62\x13\x73\x5f\x41\xd8\x70\xae\xdb\x40\x8b\x8a\xbc\x34\x52\x20\x5c\x84\x21\x37\xe9\x7a\xee\x8d\x95\x6f\x22\x5f\x3f\x79\x05\xad\x54\x1f\x82\xa0\x23\x1f\x01\x30\xea\x2e\x9f\x76\xd5\x77\xea\xf6\x1d\x86\x3b\x2e\x74\x17\xe4\x6d\x68\xb1\x50\x99\x5a\x56\x2d\x83\xb0\x6a\xa4\x3e\x5d\x34\x7e\x1a\x0d\xcd\x49\x93\xb8\xb5\x2c\x53\xb9\x7f\x12\x44\xa6\xa0\x8d\x29\xa1\x1f\x6e\xa7\xdf\xd5\x6a\x1c\x52\x6b\xe9\xc1\x5e\x45\xcd\x02\x37\x75\xa1\x4b\x47\x5d\xcf\x3c\xee\xde\x93\xdd\xf4\xa6\xdb\xed\xf8\x95\x23\xe0\x3e\xdf\x17\x35\xc0\x02\x3e\x52\x29\x12\x6a\x95\x2c\x52\x6d\x3f\x2c\x6a\xcf\x3b\x36\xef\x91\x33\xca\xfa\x68\xf6\x94\x58\xae\xaf\x24\xca\x94\x58\x62\x3b\x1a\xfc\x42\xcc\x2e\xdc\x92\x99\xdd\x47\x80\xa6\x8d\xfb\x93\x8d\x20\x6c\xa3\x6f\x78\x90\x46\x0c\x00\x91\x12\x9b\x5d\x10\x80\x9a\x1b\xd8\x36\xae\x6c\xa2\x37\x60\xff\x8d\xdd\x7e\x53\x1c\x35\x4e\xb5\x0b\x99\x04\xd6\xa8\xb9\x8f\xed\x35\xca\xaa\xc7\xc7\xad\xef\x18\x46\x30\xb7\x4d\xc3\x55\xc3\xf4\xd3\xd5\x26\xbc\xf1\x1e\xe2\xae\xe6\xbd\x8f\x6f\xd1\x07\xa1\x65\xaf\x86\xea\x7e\xdf\xbd\xea\x12\x36\x50\xfb\xd5\xd9\xb9\xd5\x33\x00\xc2\x61\x7f\x53\xb2\x93\x27\x75\x23\xe6\x79\x80\x3f\x36\x96\xd8\xeb\xf7\xfb\xcf\xca\xbb\xeb\xa0\xa2\x71\xbd\x76\x11\x53\x83\x91\xca\x22\x06\x8b\x7c\xaa\x15\x28\x3c\x4f\xc4\xcd\x13\xa5\x81\xc3\x77\x9a\x88\x1b\xf8\x73\x7a\x12\xd4\xd1\xd4\x27\x07\xe2\xec\x88\x57\xfe\xcd\xae\x29\x64\xeb\xf5\xd3\x0d\x80\x0b\xa1\xd7\x40\x7f\x7f\x6a\x28\xca\x08\x7e\x30\x2b\x38\xcd\xae\xd9\x59\x45\x65\x1a\x3d\xdd\x7c\xac\x94\x74\xcf\x29\xfe\xd4\xa4\xf1\xd2\x88\x59\x9e\x5e\xbc\x5c\x2c\xc2\x10\x7e\x7a\xf4\x81\xa6\x1f\x58\x99\xcc\xe8\x49\x91\x26\xf9\x91\x6e\xa2\x62\x9f\x58\x61\xd8\x27\xcb\x37\x39\xe5\x51\xfc\x81\x0d\x42\x9b\x98\x6e\xa2\x68\xcb\xa8\x8d\x7a\xe7\x81\x73\xf1\xe1\xdd\x71\x9b\x90\x8f\x72\x36\xad\xd4\x60\x00\x52\xdb\x72\x73\xea\x04\x22\x86\xf6\xaa\x8f\xce\x29\x39\xa7\xeb\x75\xb3\xd4\x73\x14\x4c\xb3\xbb\x00\x21\xa7\x6e\xf0\xa2\xbc\xbb\xfe\x25\xe8\xe8\x63\x7c\x36\x8b\x50\xa5\x20\x8f\x3a\xc1\x8b\x67\x90\x8f\x05\x39\xa7\xbd\x59\xc6\x4b\x01\x0f\xf0\xd0\x8b\x20\x03\xbf\x42\x34\x72\xf3\x94\x72\xc0\x50\xd4\x8a\xcb\x43\xc6\xa6\xaa\xb8\x9b\x27\xd1\x62\x47\xb7\xe5\xaf\xea\x01\x10\x95\x5b\x66\xa7\x29\xed\x84\x18\xce\x6e\x9e\xe8\xd4\x30\xdc\x07\x46\x23\x2b\xa6\x60\xe6\xcf\x05\xb5\x23\x95\xfc\x87\x39\xb6\xde\x25\x40\x1c\xca\xd0\x3b\xef\xa2\xab\xfc\xfc\xb3\x71\x8d\x00\x33\x91\xf0\xa8\xcf\x18\x1e\x07\x1f\xe9\xd5\x6d\x26\x82\x0e\x9d\x90\xe0\x5e\x87\x85\xcc\x38\x2d\xbe\xa8\xd4\xb9\x0c\x08\xcc\x94\x7c\x32\x25\xab\x84\x65\x73\x90\xfd\xa0\x6c\x1a\xbf\xa3\x51\xf0\xd2\x24\x04\xb8\x0a\x1f\xb2\x69\x80\xb0\x2d\xab\x88\xd6\x59\xc1\x76\xd7\x38\x36\x45\xdc\x7a\x20\xa1\xb3\xbb\xce\x05\x48\x92\x21\x2c\x78\xc2\x94\xb8\x89\xe9\xd4\x7b\x9b\x12\x60\x27\x02\xdd\xda\xe0\x37\x94\xac\x36\xf8\x88\x7a\x72\xbe\x1f\x0c\xa9\xe0\x0d\x1d\xd3\x89\x59\x0c\x88\x00\x0c\x7f\xec\x26\x2b\x05\x75\x81\x19\x81\xe4\x4a\x51\x81\x21\xb9\xd6\x4d\x64\x22\xc8\x3e\xa2\x5e\xc3\x84\x8d\xc5\xa4\xd2\xe2\x7e\x08\xc3\xe8\x88\x92\x27\x4f\x45\x0f\xa4\xaf\xdc\xa9\x06\x5d\xa1\x8c\x59\x65\x84\x48\x53\x44\x8e\x69\xcf\x5d\xac\x2a\x82\x1b\x0a\xd8\x15\x7a\xba\x18\x2c\x48\x15\x45\xde\xe4\xd6\x3b\x52\xd5\xf7\x16\xc8\x89\x29\x24\xf8\x0f\x4a\x3e\xd0\x28\x70\x3b\x1b\x20\xfc\xb9\x96\x9a\x39\x1b\xe4\x5f\xb5\xbc\x52\x6f\x84\xdf\x54\xba\xf7\xb9\x00\xe1\xef\x28\x09\x92\xab\x82\x8b\x56\x9a\xb0\x05\x48\xa2\xaa\x5f\x2d\x5c\xd5\x9a\x2e\x55\xd3\x29\xa8\x13\xb7\xe8\x7c\x21\x32\x3a\x6d\x51\x96\xf2\xc7\x85\x80\xd0\x54\xfe\x05\x7d\x3b\x65\x3c\x71\x9a\x88\x44\x07\xe7\x54\x24\x36\xaa\x84\xca\x16\xc9\xb2\xa4\x20\x83\x0a\x7f\x32\x76\xdd\x5a\xf0\xe2\x9a\xd3\xb2\x6c\xf1\x44\x50\xfd\xa1\x92\xd2\x5b\x90\x3e\xa5\xb7\x4a\x40\x0c\x8c\xc1\xb6\x14\xd3\x6b\xda\x12\xd9\x9c\x2a\xc3\x5c\xad\xbb\x22\x5f\xce\x4d\xb5\xfb\x04\x24\x94\x5c\x39\x1f\xfc\x3b\xd8\xd9\x6a\x64\xf1\x7c\xa4\xc9\xed\x69\xb2\x18\xe9\xdf\xf8\x34\x59\x38\x97\xd7\xaf\x0e\xac\xf1\x3b\x58\x18\x77\x68\xd0\x75\x6d\x6c\x7a\xdf\x3a\x4d\x16\xf8\x77\xe0\x24\xc3\xcd\x23\xf1\x16\xdb\xd6\x9f\x2e\xdc\x82\x19\xa1\xca\xa3\x7d\x92\x83\x38\xb2\xa0\x48\xdf\xb2\x1a\xa3\x45\x82\xd8\x30\xbc\x0d\x94\x88\xe1\xb4\x58\x49\x6c\x38\x1a\xf4\xf7\x9e\xcb\x6f\x52\xd4\x53\xc2\x5c\xef\x93\x6b\x25\x2d\x60\xea\x20\x4c\x6d\xd8\x52\xcf\x0d\x6f\x62\x5f\x91\x76\x92\xeb\x11\xab\x71\xc9\x60\x80\xf2\xa0\x0f\xf6\x15\x9d\x3a\xb9\xae\x60\xad\x39\x9d\x17\xd9\x17\x3a\x05\xc8\xca\x35\x49\x54\x09\x6d\x00\xba\x55\x0d\x09\x26\xa6\x56\xd1\x82\x7a\xc4\x50\x14\x5b\x12\x64\xbc\x01\x09\x79\x3a\x6d\xe6\x9f\x08\xd3\x2f\x98\xc5\x76\xdd\x20\x42\x12\x0d\x7e\xfa\xc9\xc5\x55\x99\x29\xdf\x8e\x9a\x5c\xf5\x38\x7d\xd4\xb4\x4d\x47\x38\x26\x12\x04\xbe\x52\x87\xc4\xe1\x13\x96\x01\x21\xfb\xa0\x78\x93\x74\x63\xf0\x49\x46\x28\xe6\x44\x0c\x87\x15\xa9\x5a\xaf\x60\xd5\x7a\x81\x94\x31\x26\x65\x26\xa5\xf0\x3b\xa2\xcb\x64\xae\xd0\x4d\xc4\x49\x61\x16\x15\xad\x18\xe1\xc3\xb4\x60\x22\x63\x4b\xba\x81\x96\x36\xd9\x2c\xd2\x76\x08\x64\x55\x15\x52\x7a\x73\xb2\xfd\x54\x3d\xb2\x43\x68\x32\x73\x91\x42\x21\xa2\x02\x61\xf8\x6e\xe6\x92\xb3\x54\xba\x18\x66\x24\xeb\x95\xd9\x55\x9e\xb1\xeb\x4d\xd3\x64\xc3\x65\xae\x69\xc2\x84\x70\xd3\x47\x46\x0a\xcc\x49\x56\x01\x34\xca\xf8\x55\x7b\x80\x53\xdb\x9d\x54\x75\x27\x85\xee\xac\x4a\xf0\x87\xa8\xab\xd9\x31\xa5\xd0\x27\x95\xc9\x49\x81\x99\xcd\x4c\x49\x6a\x3b\x26\x57\xaf\x54\xa3\x4d\xcd\xe0\x9b\x9b\xcf\x64\x2b\xbb\x9a\xcf\xe4\xf7\x77\x36\x5f\x1f\xfd\xcf\x08\x6d\xd4\xf0\xed\xea\x81\x0a\x5d\x5d\x7d\xb4\xaf\x66\x69\x1f\x9c\x48\xca\xa3\xf4\xc4\x86\x62\x95\x4a\x99\x51\x1f\x55\xf2\x2e\xb1\x00\xba\xbd\xc7\xaf\xae\x34\xb0\xe9\x50\x8d\xf5\x07\x73\xa4\xd7\xeb\xe7\x26\x68\x17\x74\x08\x44\x3b\xb5\x31\xf4\xaf\x5e\x2d\x22\xb0\x30\xa8\xad\x5a\x31\x59\x14\x0c\x8e\xa8\x6d\x0a\x97\x52\x5b\x98\x09\x19\x1a\x95\x52\x55\x7d\xbd\x36\x21\x52\x67\xa9\x57\xd7\xd7\xc6\xd6\xb6\x1f\xd5\x01\xf8\xb6\x99\xea\xe6\x83\xcf\x85\x47\x3f\x20\x5b\x98\xf5\x7e\x1f\x79\x1e\xcb\xe4\xb1\x14\xf1\x96\x31\xa6\xba\x11\xb2\x51\x44\x41\x33\x4f\x6b\x04\x03\x3f\x8b\xa2\x58\xa7\x46\x2a\xb6\x55\x69\x4c\x27\x20\xf7\x91\x08\x89\xf5\x8c\x29\x16\x93\xaa\xab\x85\x30\x94\xbc\xad\xaf\x53\x4b\xea\x52\xb2\x46\x61\x28\x14\x27\x89\x61\xaa\xf0\xce\x4c\xd4\xd4\x17\x13\x73\x83\x39\x97\xd6\xe5\x54\x8b\x14\x19\x6b\xce\x25\x38\x24\xb2\xc9\xc7\xf2\xb1\x67\xa9\xd2\x9d\xdd\x69\x76\x8d\x93\xfe\x90\x3b\xf2\x85\xe0\x8c\x40\x82\x63\xc9\xb5\x86\x1c\x8b\xc5\x82\x4e\x23\x34\xe4\x9d\x0e\x02\x75\x6c\x70\x30\x06\x26\x0a\x81\x28\x2e\xc2\xd0\x68\x69\x0f\x9b\x7a\x65\x8c\xe9\x6d\x77\xcc\xe4\x64\xe5\x39\xe5\x25\x94\x17\x11\x5a\xaf\x7d\x2e\x23\xa7\x39\x95\x70\x38\x75\xc9\x16\xa5\x70\x04\x38\x94\xfd\xb1\x28\x13\x84\x8b\x28\x13\x58\xbe\x2a\x94\x64\x02\x67\xc6\x92\x1f\x14\x85\x25\x49\x04\xc2\xd9\x16\x41\xe6\x07\x45\x90\x59\xea\x74\x4a\x16\x9e\x22\xbc\xcb\xd6\x48\x45\x85\x76\x2a\xb1\x43\xd0\xeb\x96\xbd\x2e\x79\xaa\x41\x50\x63\xe0\x1a\xf5\xd2\x82\x73\x5a\x2e\x0a\x36\xcd\xd8\xf5\x87\xb2\x72\x1d\x0d\x75\x77\xe4\x22\xac\x1e\x5c\x83\xf0\x8c\x68\x6f\x91\xc8\x4b\x40\x5e\x08\xb1\x43\xde\xcc\xed\xcb\xf6\x50\xe7\xda\x45\x94\x04\x05\x0b\x3a\x14\x65\xac\x55\xf3\x79\xd3\x12\xeb\x75\x14\x89\xa7\xe1\x67\xe4\xcb\xc0\x51\x1c\xe8\xe7\x4b\xe2\x11\x8d\x82\x3e\xa0\x7f\x8a\x85\xb2\xbb\x23\x3c\x83\x91\x0b\xa1\x98\xd5\xa2\x58\x9c\xd0\x3b\x9a\xbf\x07\x73\xa7\x6a\xf9\x19\x18\xee\x00\xa0\xd8\x24\xa9\x39\x95\x1b\xc5\xa4\xc0\x86\x11\x05\x37\xb6\x21\x94\x55\xc6\x65\xb5\x71\x97\x62\xdb\x2e\xe3\x4c\x78\xd4\x5f\x5b\xda\xbc\xc8\xb2\x8e\x6f\xa9\xd2\xeb\x1f\xc5\x85\x52\xd2\xbe\x78\x2c\x05\x9d\x1f\xe5\xc9\x75\x09\x16\x2a\xdd\x1e\x0b\x5c\x78\xdd\xad\xcc\x56\xba\x6d\xc5\x14\xd7\x5b\x8a\x39\x76\xda\x89\x05\xae\x5a\x89\x19\xb6\xe3\x8d\xc7\x13\x67\xf7\x4d\x85\x47\xef\xb2\x35\x30\x53\x00\xa1\xdc\x0a\xe0\x4b\xa8\x9a\x2f\x98\x15\x86\xf4\x7b\xa6\xed\x7a\xc8\xdd\x2e\xf7\x18\x57\x4f\x03\xe1\xee\x83\xa3\x5c\x89\x53\x7e\xcc\x66\x45\xf5\x72\x0f\xb9\x85\x46\xb9\x7d\xe0\x87\x9c\xec\xb7\x75\x33\x0a\x00\xda\xd9\x92\xb6\x7d\xa1\x5e\x92\x1f\xda\x00\x5a\xa9\x87\x30\x0c\x9f\x6b\xda\xf2\x76\xb7\x31\x23\x0f\x2c\xe2\x48\x83\xad\x0c\x79\x54\xf8\xfa\xae\x00\x7a\xfc\x0a\x40\x3a\x93\x33\x66\x13\x6d\x18\x4b\x9e\x5c\x77\xe9\xd0\x10\x0c\x4a\x38\xab\xa4\xe1\x30\xaf\x14\x58\xd0\xaa\xaf\xdd\xd0\x38\x9b\x4a\xd6\xe4\xf9\xf7\x95\xc1\x04\x7d\xa5\xa5\xa4\x3f\x4c\x5f\x5c\x9a\x4e\xa5\xc6\x96\x65\x4e\x2e\xc7\xe9\x64\x98\x87\x61\x94\x93\xdc\xb7\xc4\x00\xa2\xa7\x19\x2e\x70\x02\x1c\x8d\x52\xde\x65\x25\xce\x11\xda\x94\x22\x2a\xdd\xbb\xef\x46\x38\xec\xb7\x36\xa0\xd0\xa0\xd3\x5e\x27\x2e\x82\xbf\x84\x20\xfe\x97\x88\x04\x36\x31\xdc\xee\x23\xd7\x00\x28\xe8\x38\x6a\x51\x97\xab\x7c\xc9\x4d\x71\x95\x0e\x22\xf7\x2a\x01\x32\x21\x0e\x92\x16\x91\x4e\x50\xf2\xc8\x3a\x49\x57\x82\x34\xf7\x23\xca\xdf\x90\xfe\x0a\xb8\x47\x0b\x62\xb8\xb9\xc2\x10\x1a\xa7\xf5\x5e\x65\xec\x2e\xc9\xb3\xa9\x91\xc7\x51\x1c\x41\x15\x51\x0c\xc1\x58\x15\x36\x14\xce\xee\x80\x10\xf2\x1d\x75\xac\x62\x84\xe1\x67\x6d\xc1\x87\x69\x04\x4c\x59\xa0\x83\xfd\x7f\x25\xf0\x5c\xe0\x53\x81\xaf\x85\xbc\xe4\x1f\xe5\x55\x85\xef\xf4\x55\xf3\x52\xff\x5e\xea\xdf\xfb\x0a\x99\xfb\x52\x05\xcf\xa0\xce\x7b\x41\x2a\x67\x49\x2d\xed\x11\xa9\x05\xbe\x8a\xd4\x98\x5b\xc6\x6f\x51\xab\xf2\x85\xd4\x4a\x96\x0f\x69\x9e\xa5\xb7\xad\xe9\x55\xae\x02\x5a\x3f\x4a\xd7\xd1\x31\x68\x53\x87\x97\x8b\xd6\x94\x27\xd7\xb2\x21\xf9\xab\xda\x99\xf2\x62\xd1\x02\x8f\x36\x16\x85\x77\xa3\xaa\xd0\x2d\x7d\x84\x86\x6e\xe9\x23\xe8\x1e\xcb\xc0\x72\xd1\x02\xe9\x23\x50\x4a\x02\xc7\x21\x2d\x58\x95\x96\xee\x40\x5a\x2c\x1e\x5b\xe9\x52\x22\xe7\xa5\xa0\x2d\xd5\x47\x8d\x51\x6b\x79\xd8\x39\x65\xcb\x16\xac\x45\x4b\x2f\x8f\x8b\x62\x3f\xc8\xf7\x01\x34\x5a\xe5\x2e\xd1\x5d\x17\x54\x85\x72\x9a\xdc\x51\x35\x59\xc5\x1d\xe5\x3a\x24\xbf\xa6\xc6\x0a\x89\x26\xbc\x14\xad\xeb\x42\xd8\xf9\x01\xc5\xcd\x56\x5e\x94\xb5\x24\xf7\xeb\xd5\xa3\xf3\x56\x6c\x1b\x39\x58\x81\xc8\x2a\x9d\x9e\xb1\x98\x62\xef\x86\x16\xdb\x37\xf4\xfe\xde\x9a\x79\x97\x74\x81\xed\x95\x16\x73\xe7\x48\x9e\x68\xc0\xb4\x76\x04\xb7\x4f\x97\xde\x65\xee\x66\xb7\xb3\xa3\x0b\xda\x39\x0a\xe2\x97\xdb\xa5\xed\xbc\xe9\xd2\x66\xf6\x82\xf8\x72\xbb\xb0\x33\xa3\xba\x78\x35\xaf\x41\x7c\x2f\x31\xed\x9c\x0a\x1a\xc9\x67\x10\xd2\x8f\xa7\xde\x39\xdc\x9a\x7a\xdd\x4a\xc3\x02\xc4\x5f\x1a\x5b\x73\x99\x7f\xc2\xb7\x0f\xb0\x25\xef\xeb\x5d\xbb\x6d\x42\xb2\x51\x44\xc9\x5b\x11\x55\x75\xb0\xc3\xaa\x31\x08\xb1\x20\x6f\x99\x04\x68\xc3\x70\x2e\xe1\x70\x03\xb8\xd7\xd7\x72\x4d\x38\x76\x41\x83\x0b\xe7\x21\x7d\x60\x91\x79\x4b\x91\xa3\xea\x61\x89\xc5\x7f\xd2\xc8\xcb\x00\xd2\x25\xd0\x44\xec\x13\xe6\xe1\xe8\x82\x50\x11\xb1\x0a\x4b\xa3\x3d\xbb\xe9\x88\x36\x0d\x94\xf5\x96\xf2\x80\x5e\xe5\xf4\x92\x2f\xd9\xc7\x4c\xdc\x9c\xf3\xac\xe0\x99\x78\x04\xbf\xa6\x2a\xe8\xd9\xd3\x3c\x95\x4d\x6e\x50\x65\xf2\x78\x5f\x11\x5b\x5c\x54\x51\x93\x4d\x3c\xfa\xb8\xfb\x71\x45\x46\x87\xa7\x7a\xd7\x2b\xad\x64\x58\x37\x6e\x2d\x1f\x07\x3b\xa8\x43\xde\x55\xc9\x3a\x08\xfa\xab\x7c\x70\xdd\x33\x86\xb7\xd7\x05\x3b\xdf\xc7\xb5\xe7\xb9\x61\x29\x60\xad\x7d\x2f\xc3\xf2\x1d\x9e\xcb\xc9\xc1\xfe\x3c\xb7\x07\x46\x89\xa6\xef\xf0\x0b\xed\xdb\x79\xa0\x1e\x20\x66\x77\xad\x6b\xf6\x58\x44\x8a\x8a\x00\x0f\xc4\xb0\xff\xe2\xd1\x5a\x5a\x31\xd6\x59\x1e\xc5\xb8\x3f\x19\x36\x4f\xc3\xaa\xa2\x7f\xbd\x65\xee\x02\xc8\x5d\x7a\x05\x54\xc3\x0a\x18\xfb\xaf\x4f\x93\x99\xa3\x91\x37\xfe\xf8\x51\xf4\x40\x01\x3b\xb2\xbc\xf9\x3b\x11\x86\x07\x22\xba\x03\x0d\x9f\x3b\x63\x32\x52\x67\xbe\x54\x99\x2f\x21\xf3\x65\x2d\xf3\x52\x65\x5e\x42\xe6\xa5\xc9\xbc\x17\x16\x93\xbd\x15\x08\x7f\xf1\xa2\x8e\xa9\x19\x61\x4c\x31\x57\xdd\x33\xec\x56\x7f\x97\xe1\x6b\x89\x98\xc8\x49\xef\x63\xe7\x84\x94\xe9\x0d\x9d\x2e\xf3\xca\x62\xa1\x93\xf7\xb6\xe0\xf3\x24\x37\x87\x07\xff\x2d\x90\x4b\xf9\x7b\x0d\x9b\xb5\x22\x1c\x46\x15\x5f\xf3\x23\x40\x1e\x40\x92\x71\xd6\x17\xad\x3e\x8a\x08\xd6\x16\xd3\x0a\xac\x53\xe6\xe9\xaa\x4d\xc0\x0c\x40\xc7\xe5\x3e\x60\x93\x21\xf7\x86\x06\x22\x8f\xb5\xa1\xc9\x9b\x50\x02\xae\xd5\x4a\x7c\x94\x2b\x81\xa9\xb7\x00\x1f\xe5\x02\x38\x69\x97\x2a\xed\x12\xd2\x9c\xe9\xf6\x67\x5b\x48\x28\x59\x02\xc4\x67\x5e\x0f\x23\x4e\xce\x64\xef\xd0\xd7\x3b\xa7\x28\x3b\xfd\xaa\x01\x6b\xca\x27\x62\xb2\x91\xbe\xdb\xc8\x10\x5d\xc0\x71\x33\x5a\x58\x55\x4e\x18\x9e\x55\x9b\x0e\x8c\x06\x81\xef\x8f\xf3\x0a\x6e\xfa\x54\x05\xff\x12\x64\xac\x98\x0d\x01\x36\xbf\x7f\x50\x5c\xf1\x2a\x0e\xd9\x34\xc0\x9f\xdd\x94\x8a\xf5\x85\xff\xe5\xa6\x2b\xf6\x16\x0e\x34\xb3\x42\x85\xce\x6d\xc8\x61\x60\x54\x59\xef\x6d\x82\xcf\xd3\x70\x12\x0e\x4c\x82\x66\x73\xf8\x21\xc3\xf2\xd8\x0a\x4f\xfd\x5f\xce\xc1\xac\x8a\xf9\xdd\x7e\x53\x21\xed\x5c\xa5\x1d\xd8\x34\xb0\x4b\xe1\xfd\x28\x56\x8a\x8d\xbc\x76\x23\x86\xb3\x62\x13\x4e\xfd\x04\xed\x85\x13\xc2\x17\x36\xbc\xf5\x8a\xab\xc4\xad\xbe\x68\xce\x8c\x1f\xd2\x5c\x1a\x3f\xa8\x19\x34\x7e\x48\x31\x6b\xfc\x90\x62\xdc\x78\xa1\x8a\x89\xa3\x23\xda\x85\x0a\xfe\x8d\x62\x87\x53\x05\xdb\x22\x30\x9c\x9d\x2a\xe4\x50\x1b\xde\xe9\x1b\xa7\x3a\xbf\x35\xa1\x2d\xb2\x57\xd9\x43\x63\x13\x5c\xc8\x9f\xce\x60\x82\x33\x45\x33\x89\x8a\x71\xbf\x66\x03\xa3\x53\x68\x8d\xd2\x01\x42\xc3\x8c\xac\x76\xd8\xa9\x8b\x57\x57\xcb\xab\xab\x9c\x4e\xe3\x0c\xeb\x49\x9d\xc6\x59\x27\x30\x73\xb9\xc1\xae\x9d\xb7\x78\xcc\x27\x0a\xea\x34\x17\x58\x2c\x36\xf8\x13\x08\x3e\x83\x37\x75\x7c\x6e\xc2\x19\xc2\xaf\xc4\xb8\x98\x90\x6c\xb3\x79\xa7\xd1\x2f\x05\x5d\x1b\xa0\x5d\xff\x28\x60\x5d\xff\x05\xa0\x5e\xfd\x75\xe0\x76\x1d\x3e\x55\x61\x09\xeb\x1b\x80\x5f\xfe\xb7\xe8\x49\xb2\x7c\x38\xf0\xf1\x94\x69\xb1\xbc\xca\xa9\x4e\x74\xf0\x91\xc3\x1a\x5e\x92\x5c\x5f\x54\x18\x0a\xfc\x51\xd8\x80\xfa\xab\x70\x0f\xf3\x17\x30\x3d\xfb\xeb\xa0\x2b\xaf\xeb\x68\xcb\xb9\x83\xbf\xdc\xd2\xc7\x0f\x8b\x56\x0d\xf7\x7a\xed\x62\x61\xf0\xfb\x61\xa1\x71\x18\xf3\x17\x98\x8d\x3e\xcb\xb1\x19\xfb\x3a\xd8\x89\x8b\xbd\xf6\xf1\x32\x1d\xfa\xb0\x70\xd9\x95\xdc\x5a\x5c\xd6\x48\x92\x46\x95\x2a\x2e\x26\x30\x2f\xaf\xc0\xa2\x84\xfa\xd9\xc2\x1a\x0f\x9a\x30\xc8\x43\x1f\x95\x84\xa0\x9a\x6b\x8f\xef\xa9\x22\xfa\xfe\x72\x31\xb3\x3e\xc2\x72\xf7\xc8\x25\x6a\xd9\x3f\x15\x6e\x76\x68\x43\xf4\x21\x53\x2b\x79\x68\x02\x0a\x6f\x93\xa1\x13\x1b\x02\x5c\x4d\x06\xce\x2c\x26\x37\x2f\x0c\x76\x77\x6a\x43\x12\x8d\x83\xc0\x99\x09\x54\x98\xdf\x99\x83\xee\x41\x5d\x1d\x3e\x75\xc2\x0e\x76\x78\xd6\x8c\x28\x42\x2b\x8a\xc6\x61\x7e\x94\xef\xf5\xea\x47\x7b\x19\x56\x21\x68\xfd\xfe\x86\xd2\x5c\xfd\xf5\x26\x69\x00\x93\xf4\x97\xc0\x7b\x15\x08\x70\x2c\x48\x60\x79\xd1\xda\xe7\xba\x8e\x3b\x58\x74\x1d\xfb\xde\x8d\x9d\xeb\x8b\xce\xfd\xec\x1b\x41\xfa\xc3\x37\xe2\xc5\xb1\x7d\xc5\xdf\x88\x4e\x07\xe9\xeb\xe0\x58\x8c\xdf\x88\x09\xd6\xae\xcd\x8f\x04\x71\x80\xa0\x0f\x25\xe5\xaf\xe4\x23\x9c\xb1\x6b\x0b\x0a\x7d\xf0\x8a\xd4\xb0\x0c\xfc\x07\xf8\x8b\xb2\x37\xa6\xa6\x96\xac\x0c\x3d\xc6\x15\xc7\xff\x97\xf0\x8d\xb0\x7e\x02\x5d\x0f\x09\x87\x6b\x74\xd7\xf2\xbe\xf9\x68\x2f\xe6\x5a\x7b\xad\x1f\x73\xf2\x9b\x70\xcc\x76\x0b\x3c\xc0\xd4\x45\x2f\x5b\x83\x98\x93\xef\x76\x16\xb1\xe2\x6b\xe4\xf7\xed\x32\x1b\x36\xa2\xdb\x7e\xb2\x05\xe6\xb8\xdd\x47\xf1\xae\x2c\x77\x54\xbf\x39\xb4\xe1\xf3\xf5\xfa\x75\x64\xec\xe7\xff\x2e\x70\x46\xce\x87\xe7\xc6\x22\xe1\xc7\xa8\xc0\xa6\xa4\x35\x47\x18\x9d\x93\x0c\xad\xd7\x60\x90\xd0\x36\xf9\x9d\xd3\xe4\x07\x11\x1d\x09\xec\xf5\xdc\x1a\x19\xa8\x6a\xfc\xee\x13\xa8\xff\x10\xc8\x07\x47\xc3\xb0\x3b\x78\xf1\x5e\x38\x84\x2d\x04\x28\xb1\xd7\x1e\x7e\xb4\xa4\x6f\x45\xad\x55\xe3\xf8\xb5\x6a\xdb\xe3\x38\x03\xad\x82\x57\x1a\x0d\xcd\x5f\x28\x76\x36\x2f\xeb\xb4\xb7\x6d\xeb\x56\x5a\x77\x3e\xf1\xc3\xe0\xa2\x82\x1c\x2a\x80\xd7\x56\xc0\xc6\xee\x83\x43\x01\xd1\xa5\x5f\x42\xe9\x97\x8d\xa5\x1d\x0a\x88\x2e\x7d\x09\xa5\x2f\x1b\x4b\x7b\x24\x10\xc3\x66\xb7\xf4\x09\x83\x49\xde\xab\x33\x96\xe1\x43\x11\xdd\xab\xed\x2d\x97\xd7\x9d\x66\x70\x44\x62\x5a\x6d\x20\x8c\x18\x2b\x0e\x6e\xf3\x12\x48\xb7\xed\x7e\x79\xb2\x5d\xc7\xe0\x43\x35\xf5\x68\xa5\x17\x0b\x53\x02\xbc\x0c\xe3\xd8\x43\x99\x78\x7e\x17\x4d\x01\x85\x31\x9b\x12\x98\x2c\x9e\x5d\xda\x5f\x45\x93\xe5\x8e\x08\x68\xea\x8c\xa4\x22\xe2\x08\x21\xc3\x0d\xf9\x13\xc8\xeb\xee\x56\x51\xd8\x41\xb5\xa9\xe4\xe0\x44\x72\x3d\x34\xe4\x8f\xac\xd6\x2a\x15\x51\xe1\x30\xa7\xb5\x42\xa9\x47\xb1\x50\x55\x8a\xdd\x44\x8b\x7d\x65\xfc\x24\xb9\x1e\x15\x4f\xd2\x28\xbc\xc6\x0b\x2d\x49\x6c\x71\xad\x6a\xbe\x9e\x9e\x2c\x97\xcd\x2c\x47\xf8\xa7\x70\x04\xf7\x2c\xba\xa1\xdc\x20\xb4\xfb\xf8\x0a\x0c\x5b\x1d\xcf\x93\x6b\xf9\x94\x95\xb4\x9e\x78\x21\x41\xc4\x5a\xda\xc7\x6c\x2a\x6e\x54\xda\xc3\x51\x4e\x1f\x9c\xe0\xbf\x78\xb1\x5c\xe8\xf8\x19\x9f\xca\x9e\xd9\xa4\x54\x3e\xe1\xd5\x97\x55\xb4\x94\xc1\x99\x6e\x64\xa6\x5a\xb8\x37\xe1\x73\x78\x5a\xee\xa8\x89\x5f\xdc\xf0\x8c\xdd\x9a\xd8\x5b\x7a\x9d\xb8\xb9\x67\xb2\x83\xa0\x01\xc9\xb3\xe9\x4b\x4e\x13\x13\x7e\xa7\x5a\xd4\xc1\x43\x36\x75\x62\x17\x8b\x84\xb9\x51\x90\x3a\xd4\xf1\x03\xe8\xa1\x1f\x73\x6a\xab\x04\xb7\x01\x9d\x62\xda\x98\x15\x4c\x7c\x04\xb3\x51\x32\x96\x67\x8c\x1e\xe4\xc9\x7c\x61\x22\x6f\x6c\x96\xb6\xbd\x05\x41\x33\x88\x82\x2f\x6e\x12\x35\x3d\x22\xb9\xba\xc8\xbe\xc0\x38\xef\xb3\x69\x71\x0f\x89\x5f\x94\x6b\x6e\x19\x2a\x8a\x39\x7c\x2e\xcb\xf3\xb3\xaa\x25\xb0\xf8\xe6\xc4\x4b\x51\x2c\xbc\x28\x2f\x6e\xe9\x6b\x63\x49\xcc\x4f\x52\xb6\xc4\xaa\xb4\x53\x6b\x2e\xac\x4a\xdb\x6a\xcb\x6c\x8b\x0d\xa6\x8c\x58\x01\x53\x1c\xcc\x25\x1a\x75\x5a\x7c\x09\x70\x70\xe6\xe2\x34\xa2\xee\x44\x40\x4b\x40\xac\xd7\x56\xb1\xd9\x33\xdd\x13\x68\xb1\xea\x20\x66\xeb\xb5\xd1\x26\x6a\xbb\x25\xfa\x4a\xbb\xf8\xcf\x2d\xed\x15\x8a\xc2\xf0\x4f\x31\xa6\x93\x51\x14\x04\x1d\x81\x7a\x82\x67\xf3\x08\xc5\xa2\x13\x2c\x1e\x02\x47\xae\x8a\xd5\xd0\x2c\x30\x40\x0d\x86\x92\x1f\x73\x99\xd3\xa4\x1e\xc6\xac\xda\x97\xb2\x1e\x64\x1e\x9e\xa0\xdb\x0d\x10\x2e\x88\x60\x11\xc3\x42\x62\x65\x1c\x0d\x83\x59\x5e\x24\x20\x20\xae\x4e\x77\x90\x96\xe5\x11\x24\x21\x63\xbd\xa5\x6a\x18\x17\x28\x96\xe8\x1c\x29\x36\x1b\xd7\xf5\xd9\x9f\x62\x87\x71\x2f\x47\xe9\xa8\x4a\x07\xb5\x20\xd1\xa1\xbd\xf4\x26\xe1\x2f\x45\xd4\x47\x35\x44\x90\xf6\xca\xe5\x95\xd2\x11\x8f\x06\x08\xff\x29\xc6\x62\x42\xfe\x34\x6e\xc9\xb4\xed\x28\xce\x48\x11\xad\x24\xb6\x95\x09\x3a\x87\x65\x5e\x25\xfa\x90\x5d\x25\xa5\xba\x23\xb8\x3e\xd8\xf2\x87\xce\xaf\x28\x9c\x95\x1b\x48\xcd\xe6\xd7\xf0\x23\xc1\x4a\x19\xb8\xa5\x8f\xd7\x94\xe9\xb3\x00\x67\x5a\x62\xfc\xf2\x77\x91\xf0\x04\x36\xb4\xf5\xd3\x89\x05\x4f\x52\x28\x73\x0f\x9f\xd8\x38\x2c\x11\x47\x2c\x5d\xfd\xe5\x6c\x4c\x27\x96\x9c\x2e\x1c\x1f\xd9\x5f\xd3\xd0\xa9\xcb\x2f\xed\xff\x88\xa9\x72\x29\xf7\x0d\xea\x3d\xae\x0a\x90\xd5\xe4\xf2\x1b\x7c\xde\x57\x4d\x35\x38\xf4\xdb\xd5\xec\x7a\xdd\x8e\x82\xcb\x4b\xd0\x18\xc8\xd8\xee\x72\xf5\xbe\x3f\x1f\x68\x09\x36\xdd\x23\xd8\xbf\x61\xd8\xf4\x65\xc8\xaa\x57\xdf\x83\x71\x3b\xef\x6e\x52\x4d\x73\x57\x19\x8b\xa8\xb6\x79\x60\x1e\xc8\x6d\x43\x21\xa2\x97\x95\x35\x13\x21\x41\xc2\x58\xa1\xad\x3e\x3e\xcc\x2d\x13\xd5\x35\x82\xa9\xd3\xb4\x95\xca\x74\x2b\xde\x2d\x79\xba\x95\xb6\xe4\xd9\x56\xda\xac\xe0\xf3\x44\x6c\x25\xb3\x64\x6e\xda\x9c\x67\x65\x99\xb1\xeb\x2e\x58\xa4\xb4\x76\xba\x06\x75\x93\x5a\x7d\xc5\x67\x2d\x19\xf9\x9b\x56\x7b\x2f\x65\xae\x04\xfe\xaf\x34\xa2\xe4\x67\x4f\xcc\x65\xbd\x1e\x0c\x6a\x72\x2f\x71\x4d\xf3\x11\x0d\x05\x39\x1b\x8b\xc9\xb0\x59\x7e\x09\x84\x94\x6e\x44\x04\x32\x4a\xd4\x73\x65\x98\x33\xcf\xe5\xf1\xd2\xf8\x0c\x6b\x32\x7d\x16\x51\xd0\xa8\x6c\xd4\x2a\x31\x32\x33\x23\xeb\x32\x5f\xa1\x3f\x35\xa1\x3c\xc7\x96\x39\xf5\xd5\x35\xd7\x6b\xda\xbb\x2a\xa6\x8f\xda\x29\x87\xa3\x43\xa9\x92\xab\x3e\x2e\x98\x71\xb0\x32\x04\xd5\x29\x4f\xe5\xc2\xd7\x9b\xb0\x92\xf1\x95\xec\x8b\x3b\xdb\x98\x13\x68\x6c\x68\x6c\xc7\x73\x25\xbb\xa7\x44\x40\xac\x5e\x85\x52\x6e\xa3\x1d\xee\x2a\x51\xe8\xa9\xc5\xf4\x05\xb0\x9b\x7e\xb1\x92\xba\x2b\x59\x2f\xe6\x58\x3f\x7f\xa2\x4b\x37\x43\x4a\xd8\x86\xc6\x5a\x5e\x44\x7d\x83\x83\x3b\xcc\x0b\x25\xd8\x87\x56\x9c\x78\x09\xc6\x6c\xc9\x46\xa6\x57\x42\x4e\x1b\xae\x5d\x4b\x6c\xa0\xe7\xdc\x3d\x5c\x53\x16\x55\x6f\x0e\x25\x4a\xd2\x0a\x0b\xb2\x64\x11\x1a\x8a\x56\xa6\xc5\xcb\x8a\x59\x8b\xf6\xe4\x69\x3f\x3e\xe2\xc9\xdc\xcc\xfe\x10\xad\xe4\xd2\x68\xab\x29\x0d\x27\x50\xdb\xa5\xfe\xa8\xbc\x0d\xe4\x45\xaa\x84\xfd\x6f\x38\x9d\xe9\x15\xe3\x68\xc5\x48\x7b\xb0\x51\xb2\x36\x0a\x59\x85\xaf\x47\x94\xd4\xea\x23\xeb\xae\xc0\x82\x9a\x8e\x10\xf8\x8d\x2b\x84\x2c\x17\xd8\xd8\x07\x71\xc3\xbe\x2e\x8a\x15\xe0\x0a\xc3\xa8\x32\x21\x02\x31\x30\x53\xa5\xe4\xb4\x95\xe2\x7e\x49\x13\x9e\xde\x78\x49\x82\xe6\x5e\x7c\xc9\xfd\xf8\x22\x29\xcb\xfb\x82\x4f\xab\x44\x04\xb5\x1e\x84\x7c\xbc\x8c\x39\x12\xb0\xdd\x00\x25\x6a\x46\xbc\x15\xd1\xff\x4a\x33\x73\xe6\xac\xee\xcc\x85\x35\x72\xc9\xaf\x96\x42\x58\xcb\x80\x6a\x4c\x5a\xf0\x03\x08\x2d\x3a\x62\x3b\x61\x2e\x99\xb6\xe8\x59\xcb\xd9\x15\xf6\x54\x59\x82\xf1\x1c\x35\x79\x63\x00\xdb\x52\x0b\x23\xbc\x26\x63\xac\x50\x26\x4e\x4c\xbc\x69\x5f\xd8\x87\xd1\x55\xcd\x6e\xc8\xdd\x32\x9d\xb4\xf3\x19\x72\x14\xd8\xbf\x52\x62\x67\x81\x9e\x7a\xed\x60\xde\x1f\x59\xa3\x54\x5e\x49\xc5\xfb\x6c\x4e\x8b\xa5\x18\x55\x41\x6b\xf7\xa2\xb9\x4e\x9a\xd3\x84\x9b\x5a\x6e\x44\xd7\xab\xd6\xf4\x65\x75\x47\x69\x4d\x6d\x70\x90\xea\x1d\x79\x23\xae\x66\xee\x19\xe3\x7f\xcf\x38\x02\x50\x67\x68\xb3\x7d\x87\x5d\x2a\x30\x8d\xd0\xde\x82\xd3\xbb\xac\x58\x96\xe6\xd6\xa8\x64\x9e\xfb\x43\xaa\xee\x99\x9f\xbc\xa7\xa3\xd2\x2e\x9b\x26\x22\x01\x38\xe2\x3b\x80\x23\xd7\xeb\xe0\xbb\xb6\x0d\x8d\x02\x62\xb4\x7a\x01\x1c\xae\xd4\x96\x44\xb7\x0b\xb8\x65\xf0\xec\x3b\x0d\x7f\x8a\x4e\x67\xd3\xd0\x97\x2d\x1c\xf2\x9e\x91\xd3\x44\xdc\xf4\x78\xc2\xa6\xc5\xdc\xd5\xbf\xdb\x7f\x6e\xec\x52\xee\x21\xfc\x85\x91\xe0\xf2\x12\xec\xa8\x1d\x33\x65\x85\xde\x48\xc6\x7e\x17\x74\xee\x19\x3e\xab\x0a\x00\x2d\x4b\xb9\x36\xe3\xa5\xca\x7d\x5f\xe5\x1e\x18\xe4\x58\x55\x74\xdc\xb4\x7b\x96\xf9\xbf\x30\x60\x58\x57\x8a\x16\x0e\x7f\xd3\x15\x30\x1d\x32\x35\xa1\x82\xb0\xf1\x7b\x36\x59\xaf\x99\xac\x6a\x35\x9f\xad\x94\xbb\x95\xc6\x50\xbb\xdf\x40\x8c\x72\xaa\x4c\x48\x8b\x99\xab\x57\x07\x56\xd3\x70\xab\xf5\xa2\x31\xd5\xaf\x8a\x64\xa0\x8b\x55\xb7\x25\x23\x11\x25\x0c\x79\x6f\x43\x93\x6c\xf8\x5b\xd7\x02\xa6\x7c\xc0\x65\xbb\xeb\x35\x95\x43\x40\xeb\xf5\x0f\x6d\xad\xc1\xa2\x84\x0d\x75\x70\xb0\x5f\x85\x6d\xd0\x2a\x72\x58\xe9\x1e\x03\x2b\xfc\x60\xd4\x60\x94\x5c\x3d\x75\xe5\xea\x3d\xf7\x30\xbe\x50\xfa\xbe\x4b\xf2\x3b\xf4\x9c\x99\x8e\xcf\x60\x82\xbd\x91\x5c\x40\x89\x69\xb1\xda\x36\x79\x15\x86\x76\x1c\x95\x4f\xd3\x7a\xfd\x03\x0f\xce\x72\xfb\xa5\x5e\x2c\x17\x4c\x51\x20\xd4\x8d\x26\xfc\xb4\xb9\x97\xc9\x08\x97\xa0\x96\x35\x4e\x66\x28\x7b\x05\x03\x16\x90\xb1\x9d\xa5\x62\x07\x9e\x84\x50\xc1\x5e\x57\xbc\xa2\xa6\xb4\x7a\xf1\x53\xc3\xc0\xd9\x4e\x69\x2c\x7a\x5a\xdc\x35\xa4\x34\x16\xfd\xb0\xa8\xc7\x1b\x8b\x1d\x2a\x0a\x64\xc4\x49\x9b\x5b\x03\x07\x68\xbd\x96\x09\x91\x79\xa4\x88\xb1\x35\xab\x9f\xc6\xca\x8a\x17\x3c\xb8\xb9\xbe\xf9\x69\xed\xd5\x54\x12\xe9\x6d\xbe\x65\xa4\x8d\x6a\x40\x62\xcb\x02\xa1\x67\x16\xcb\xb1\x96\x55\x77\x50\xb4\x3f\xc0\x02\xdb\xcc\x4a\x34\xc6\x11\x79\xb1\x84\x83\x48\x10\xd8\x1b\xac\x67\x44\xf1\x95\xe5\xd0\x5d\x4e\xb7\xc6\x62\x02\xb2\xa8\xac\x49\xaa\x9f\x8b\xc6\x74\x2c\x10\x66\x4d\xb2\xfe\x7e\x79\x9b\x8e\x3d\x2b\x54\x7f\x9b\x93\xa6\x4c\x05\x7c\x53\x2f\x5d\x17\x84\xb4\x77\xe9\xc9\x44\x8f\x27\x43\x31\x44\xcc\xaa\x71\x08\x72\x01\x02\x44\xca\x75\xbb\xb5\xf5\xd1\x7f\x21\xba\xdd\x21\xba\x65\x11\x1b\x8b\x09\x36\x1e\x22\xa6\x81\x11\x02\x91\xcf\x8c\xa8\x6c\x83\x88\x4e\xa7\x2a\xac\x19\xbe\x01\xf6\x14\x14\x3e\xda\x59\xa7\x61\xc8\x40\xce\xc8\x1f\x4d\xdd\xf9\x18\x68\xc7\x35\x2f\x4f\xbd\xe8\xff\xc3\x8b\xf2\x5a\xbd\xc2\x0d\x2b\xb2\x3d\x06\x39\x6c\x7f\x0d\x94\xfe\x85\x63\x5e\x00\x5a\x03\x5d\x8c\xbf\x99\xf6\xea\xad\x01\xc6\x4f\xfa\xf7\xaf\x3a\xe0\xf8\x8e\x29\xdf\x58\x7f\xd9\xcb\xeb\x2f\x06\x57\x17\x4c\x31\xf9\x24\xf1\x1b\xb3\x38\xb8\x20\xda\x02\x51\xc6\x5a\xe7\x6c\x74\xce\xb4\x71\xac\x73\xe6\x62\x35\x38\x23\x85\x59\xce\xca\xa1\x16\x0f\x43\x36\xa6\x13\x42\x48\x31\xa6\x13\x70\xab\x05\xdf\x49\x08\xef\x52\xbd\x13\x06\x43\xf1\x82\x24\xb2\x20\xef\x0a\x55\x34\xeb\x8a\x09\x6c\x8a\xa1\xed\x1e\x31\xf2\x02\x14\x0f\x5e\x88\xd1\xa0\x6b\xf1\xc4\x6a\x2a\x8e\x2b\x23\x02\xae\x8c\xda\x1b\x27\xd9\x01\x68\x8f\x1c\x2b\xdc\xd6\x66\x0d\xb8\x4d\xbe\xc9\xca\xda\xca\x18\xdf\x47\xce\x4a\x18\x17\x48\x9e\xb6\x05\xa6\x04\x12\x5d\x7d\x1b\x00\x46\x24\xe2\x8f\xb6\x8c\xf8\x15\x72\xe3\x19\x8b\x2f\x23\x59\x73\x5c\x4c\x88\x88\x18\x8a\x03\xf5\xa5\x00\x6c\x52\x2b\xbf\x4b\xca\xdf\x21\x8f\x4d\x39\x26\x6b\x59\x04\x46\x16\xc9\xca\xd7\xc6\x11\x34\x48\x41\xd0\x29\x31\xe6\xbc\x2a\x17\xd1\x3a\x67\xb4\x9d\x14\x83\x79\x6d\xa3\x76\xa8\x2c\x94\x8c\x8e\x59\xfc\x46\x7b\x83\x6a\x52\x64\x22\x3a\xb3\x9a\xd7\x0f\xbe\x75\x73\xa8\xa9\x64\x32\x8a\x22\xaf\x29\x8c\xd4\x32\x3d\xe5\x11\x35\x91\x49\x9e\xbb\xbc\xb3\xc2\x02\x2b\xf4\x1e\x4a\x44\x15\x2b\xd1\x74\xe0\x0f\x56\xa9\xa7\xba\xd8\x2b\x58\x1f\xac\xdf\xf7\x3f\xfe\x8c\xd0\x90\xf6\xa6\xd4\xac\x57\x84\xf0\xa0\xff\x4b\x63\xaf\xc3\xb0\xde\xdf\xba\x82\xcc\x67\x75\xb4\xab\x22\x64\x3c\xc1\xa0\xda\x2c\x23\x74\x4a\x3e\x30\x4c\x8d\x06\x16\xf9\x83\x6d\x8a\xe8\x88\x39\x76\x1f\x57\x0b\xb5\x16\x7a\x19\x5d\x13\x84\x6a\x57\xd6\x97\x57\xdb\x0b\xd4\xdb\xce\xd9\x8b\x43\x65\x3e\xc6\x6f\x6f\x54\x4f\x88\x50\x6c\x5c\x7f\xba\x66\x81\xdd\x1d\x00\xcd\x38\x71\xd2\x1e\x20\xbc\x6b\xb7\x1d\x33\xa4\x8c\x28\x3a\x1b\xc5\x1d\xc4\x93\x7d\xad\xd5\x1b\x6d\xa5\xec\xea\xad\x92\xf2\x78\x05\xef\x86\x32\x5e\xe5\x24\x90\x76\x1f\x3d\xb1\x7d\xa1\xc7\x0b\xa5\x2e\xb7\x35\xdd\xae\x22\x1d\x39\x66\x1b\xec\x26\xc8\x63\x51\x6d\x9b\xad\x51\x62\xf1\xc4\x55\xa0\xae\x48\xe5\xa3\x1d\x8e\xb3\x36\xe4\x3e\xdc\xba\x52\xb6\xaf\x9d\x86\xdb\x49\x31\x31\x77\x8e\x71\xd7\x6a\x99\x73\xdd\xf0\x90\xf9\xe9\xbe\xee\xe1\x66\x83\xf0\x11\xab\x06\x43\x56\xe0\x5a\x41\x75\x02\x3a\xaa\xc2\x9e\x9f\xd6\x06\x63\x9c\xd0\x96\x16\xd7\x92\xa0\x88\xaa\xa5\x9e\xff\x52\x37\x01\x0b\xa9\xac\x7c\x42\xf3\xd9\x9c\x5e\x88\x64\xbe\x88\xb7\x6d\xd6\xb4\x68\xcf\x66\xaf\xd7\xaf\x13\x21\x91\xd7\xfb\x08\x6d\xf0\xd6\x3d\x07\x6d\x65\xe5\x7b\xbe\x2c\x4d\x74\x23\x87\x44\x1f\x04\x65\x53\x4f\xa5\xdd\x91\x75\x75\xc9\x9d\xae\x4d\xd1\x66\xbf\xb7\x5a\x33\x4c\xa6\x0e\x1d\xbf\x7f\xc4\x31\xf3\xaa\xd5\xa3\xe0\x2a\xab\xac\x71\x65\xd8\xb9\x11\x90\x1b\x21\x5e\x96\xbb\xb3\x08\xc3\xee\x82\x80\x49\x2f\x67\xbb\x81\x04\xac\x19\x1d\xd7\x01\xfc\x99\x81\xd4\xe9\x46\x06\x8e\xb4\x45\x8c\x7f\x31\x62\xe7\x21\x5a\x49\x54\xdf\x58\xd5\xff\x6d\x67\xce\x77\x8c\x8c\x7f\xc6\x83\x7d\xbc\xf7\x23\xde\xdf\x9b\xe0\xdf\x19\x79\x08\xc3\xe0\xa0\x12\xce\xa9\x19\xe8\xc0\xbf\x6a\x80\x44\x16\x33\x04\x3d\xb0\xb0\xed\xa8\x56\x86\x61\xf4\x2b\xab\x34\x2a\xdd\x62\xaa\xab\x7f\xaa\xcf\xbc\xa7\x0f\xa2\xd6\x7e\x18\xb6\x7f\x65\x98\x72\x99\x1f\xb5\x7f\x67\xeb\xf5\xaf\x2c\x0c\x7f\x7a\x21\xff\x0e\x06\xbf\x90\x5f\x19\xc2\x82\x13\x45\x44\xe8\xcd\x78\x31\x3f\xb8\x49\xf8\x41\x31\xa5\xd1\xfe\x1e\xc2\x8c\x93\xd5\x15\x9d\x15\x9c\x82\x14\x52\xfc\x75\xd9\xc4\xa0\x60\xaf\xaa\x0a\x41\x25\xa9\xe8\x67\xec\x12\x5a\x0c\x7c\xb1\xa6\x00\x07\x46\x4c\x2f\xc0\x81\x95\x86\x0a\x70\x00\x52\x77\xc1\x64\x83\x9d\x0a\x87\x6c\xfa\x6d\x3d\x3c\xf0\xea\xf8\x9d\xf4\xf3\x76\xf4\x53\xc9\x48\xd6\x44\xb0\x76\xe8\x43\x59\x49\x42\x57\x22\xcb\xeb\xb7\xe2\x53\xff\xd3\x9e\x6b\x59\xdb\x1d\x7d\x87\xdc\x6f\xed\xfd\x93\xfa\x5c\x5f\xef\xbf\x12\xa6\xfd\xc7\x03\x30\x32\xb8\x3b\x46\xa0\xb2\xbf\x75\x08\xda\x44\xcb\x3f\x1a\xc3\x06\x73\xee\x79\x9c\x2d\x78\x23\x15\x19\xda\x30\xc4\xe1\xee\xa0\x4d\xc8\x77\x15\x73\x19\x38\xc1\x07\x70\x14\x4d\x61\xf8\x90\x91\xda\xd9\xdb\xfb\x19\x08\x59\xba\x94\x2d\xa4\x36\xb5\xa3\x69\x35\xad\x28\x14\x4a\xa1\xcb\x9a\x41\xde\xf6\x2a\x63\x7b\x9c\x71\xc7\x52\x59\x9d\x3c\x0c\xe4\x84\x29\x15\x49\x96\x23\x79\xbd\x24\x22\x01\x8b\x60\x23\x45\xb9\x8c\x2d\x59\x31\x81\x69\x00\xbe\x1a\x27\xab\xca\x79\x74\xcc\x38\xf6\x34\x49\xe3\xba\x70\x96\x86\x5e\x87\xd9\x2c\xfa\x9d\x21\x1a\xd7\xa7\xae\xbe\xc9\x8c\xa0\x14\xe3\xbd\xfa\x01\xb0\x04\x8c\x7a\x45\x79\x0f\xc4\xf5\x2a\x87\x6c\xba\xb3\x82\x16\x80\xdc\xaa\xa3\x76\x94\x65\x0b\x65\x86\x0f\x04\x72\x3e\x09\x1f\xc1\xf2\x83\xfd\xde\x86\xaf\xa1\xd8\x2e\xad\x52\x75\xd8\xdb\xfb\x19\x50\x04\xbd\xb0\x0d\xb5\x60\x58\x16\x88\xcf\x46\x11\xe5\x61\x18\xdc\x16\x60\xa5\x15\xf8\x3f\x00\xa4\x25\x7c\xbd\xce\x64\xd2\x76\xe5\x11\x18\x52\xa9\x77\x25\x0c\x13\x1e\x86\x51\x41\x24\xf2\x8a\xe2\xe8\x13\xab\xf0\xd2\xe8\x9c\x11\x8e\x76\xa2\xa6\x72\xa5\xfb\x08\xe1\x8c\xfc\x8b\x55\xb0\x78\x94\x59\xa4\x62\x94\xc1\xde\x20\x45\x6c\x64\xaf\x0a\x92\xf1\x48\xd9\x42\x35\x79\x08\xbf\x62\x51\x86\x70\x41\x32\x14\x17\x0a\xe6\x8a\x28\xf9\xd3\xb1\x79\xd7\x74\x8e\xea\x6b\x6a\x26\x86\x1b\x8f\x45\xce\xb9\x30\x22\x5b\x7b\x70\x78\xee\x6f\xb2\xf4\x46\x11\x4f\x23\x79\x66\xfb\x58\x68\xc7\x09\xce\xa3\x10\x5b\xcb\x09\x02\xfa\x89\xe4\x41\xe0\x61\xc8\xb9\x26\xbb\xd6\x0e\x92\x82\xba\x36\xb0\xe6\xf1\x96\x69\xbd\xc4\x10\x2c\xeb\xdd\x56\x34\xb8\xf6\xef\x2c\x0c\xf5\x7d\x31\x8a\x28\x2c\x05\xfe\x8b\x91\x4f\x8c\x18\x9a\x03\x9c\x2a\x4c\x91\x92\x29\xab\xcd\x85\x7a\xbf\xdc\x9e\xd4\x67\x00\xb0\x36\xd1\x4b\x05\xcf\x7f\xa3\x8f\xeb\x35\x90\xc7\x75\x68\x4e\x45\xf2\x1b\x7d\x04\x43\xc8\xba\x40\x18\x9a\x02\xda\x76\x72\x7a\x23\x77\xc9\xe0\x85\x0a\x19\x6c\xd3\x5a\x42\x92\x89\xca\x5e\x0b\x4c\xae\xc9\x68\x82\x04\x4c\x91\xcd\x56\x6f\x77\xac\xa8\xb3\xcf\x85\xde\xe7\x6a\x09\xd4\xc2\x3c\xb1\x0e\x68\x14\x45\x82\xfc\xe6\xee\x4d\xc6\x7b\x0e\x08\x62\xc4\x17\xd5\x4e\xa4\x72\x23\x0a\x84\x62\xad\x51\x6d\xc4\x0b\x47\x0a\xee\x06\x31\xa5\x22\x1e\x17\x58\x4c\x36\x1b\x9c\x72\xb2\x02\xf1\x86\xb8\xdd\xc7\xf0\x64\xe9\x5f\x09\x2c\xcb\x70\x60\x22\x5d\xe8\x74\xa0\xa4\x67\x92\x0c\xc4\x68\xe6\x05\x53\xc2\x76\x8a\x47\xa7\x04\x64\x14\x4f\x53\x86\xc1\x75\x22\x08\xcb\x00\x6f\x14\x84\x65\x68\xae\x7e\x1e\x40\xd0\xc6\x7c\x65\xc9\x21\xf9\x9e\xd2\xdb\xb8\xdd\x77\xac\xdf\xe5\xfc\x3f\x65\xda\x3a\xfc\xda\x51\xbb\x9d\xf2\xb1\x22\x23\x4f\x62\x9f\xc1\xaa\xcc\x67\xc8\x59\x00\xf1\xf2\x6f\x7c\xb1\xb5\xaa\x92\xf7\x4c\x43\xda\xd3\x6f\xb3\x56\xea\x06\x8d\x0e\x57\x3b\xc3\x79\xa2\x97\x8b\xba\xc4\xbb\xff\x3e\x3b\x46\x3e\xb8\x2f\xa2\x16\x51\x09\x82\x57\x9b\x64\xc9\x7b\xaa\x01\x45\x1f\x41\x48\xf9\xe6\x0e\x8c\xe2\xd5\x81\x84\xef\x81\x3e\x88\x95\xb9\xcf\x99\xf1\x5c\xc0\x6b\x04\xc1\x1b\x58\x04\x30\x02\x53\x3d\xb3\x57\x5c\xd3\x51\x5e\xd2\x08\x58\x36\x95\x02\xae\xe3\xf9\x87\xdb\xcb\xc3\x7c\xd7\xb5\x56\xa4\x66\xff\xd4\x87\x38\xae\x79\x84\x56\x33\x79\x9b\xcf\x38\x3c\xd5\xe9\x0d\xbc\xb4\x51\x50\x30\xe3\xdc\xcc\x8c\xe1\x91\x23\xd9\x5d\xdd\x73\xa7\x77\x8f\xa6\x77\xfa\x15\x00\xfe\x91\xeb\x1a\x2d\x0c\xaf\x78\x34\xe5\x08\x81\x9d\xea\x85\x0c\x63\x8a\xc1\xdc\x0c\xc2\xe7\x08\x06\xab\x44\x71\xad\x68\xfa\xdf\xd1\x0d\x77\x65\x5a\xcf\xad\x93\x7c\xc7\x4d\x88\x5d\x14\x2d\x91\x0d\x96\x5a\x23\x39\x26\x98\x57\x1c\xcd\x38\x11\xa8\x97\x88\xaf\x8d\x0b\xa9\x4d\xa3\x5f\x56\xd9\x80\xe3\x3e\xc2\x8e\xae\xbe\x57\x34\x37\x44\x81\x67\x55\xc4\xbe\xd1\x66\xe6\xd5\xe0\x1d\xde\xaf\xbb\x50\xc0\x45\xaa\x95\x76\x55\x4c\xef\x9d\xc2\x1e\x4b\xa6\x61\x89\x55\x55\x89\x6a\x9d\x72\x92\x0b\x53\x41\x3e\x9d\xed\x46\xf4\x6d\xbd\xfe\xf9\x45\x33\x5e\xa7\x10\xbb\x2f\x3e\x38\xb6\xe4\xf8\x32\x2b\xe1\x1e\x84\xd9\xbc\x58\x2e\x16\x05\x97\x78\xfb\xe9\x37\x02\x6a\x44\x8c\x4e\xe4\x8d\x19\x6b\xf4\x33\x23\x85\x73\xcb\x14\xbb\x6e\x99\x6a\xf6\xe5\x78\x33\x97\x3b\x95\x85\x61\x00\xa2\x62\xd6\xb3\x24\x52\x64\xed\x39\xb7\x32\xfd\x39\x8f\x0a\xd8\x7c\xa7\x1c\x25\xe4\x5e\x65\xac\x12\xf2\x92\x2b\xa0\x93\xdc\x71\x00\xc2\x22\xb7\x3b\x9e\x27\x9b\xec\x69\x4f\x36\xc5\x96\x47\x09\xdd\x15\x09\x5e\x91\x4b\xa5\xa6\x90\x40\x24\x51\x16\x13\xcd\x92\x2d\x78\x94\x28\x45\x86\x32\x0c\xcb\x88\xe2\x02\x0b\x84\xdd\xdd\x18\x51\x52\xf8\xc6\x9e\x91\xbc\x8f\x2b\xe7\x16\x61\xe8\x88\x6d\x18\xb7\x83\x0f\x34\x2a\xb0\x49\xc7\x85\xb6\x7c\xbd\xd9\xe0\x33\xee\x12\x0f\xee\x32\x7a\xaf\x68\x30\x0a\x4e\x37\x84\x84\xf7\x9c\xac\x5e\xe6\x22\x0e\xd4\x93\x1e\xe0\x03\xf5\xb9\x38\xd0\xcf\x7d\x80\x4f\xa9\x48\xe2\x40\x43\x02\x01\xbe\xb8\xc9\x66\x22\x0e\x40\x45\x56\x26\x38\x97\xe7\x83\xf3\xae\x6c\x11\x1c\x2d\x40\x70\x4d\xe5\xce\xcb\x66\x99\x1e\xe5\x68\x3b\x29\xa2\x28\x6e\xb7\x23\x4a\xde\xf3\x31\x9d\xa0\x30\x6c\xb7\x41\x38\xb5\xe2\x94\xf3\x8a\x18\xf4\xc0\xe1\xc2\x3b\xe1\xa4\x8f\x0f\xe5\x9f\x0b\x80\x87\x0e\xe0\xef\x2d\x27\x67\xdc\xce\x42\x09\x3e\xeb\x3f\xa9\x89\x50\x91\xcf\x9a\xea\x95\x67\x94\x89\x4f\x6e\x44\xe7\x2c\x92\x6b\xfa\xa9\x0a\x9a\xf2\x6a\x76\x74\x4b\x7a\x2e\x54\x4c\xcd\xa4\x0a\xeb\x59\x53\x91\xfa\x28\xe3\xb7\x1c\x2b\x9e\xac\x21\xc3\xc9\xb0\x26\xc3\x71\x9a\x27\x82\x4e\xeb\x94\x3c\x97\xf4\xe6\x15\x01\x07\x10\x12\x9a\x72\x3c\x2a\x38\xd6\xbc\x46\xf2\xa4\xe9\x70\xec\x15\x44\x1b\x3c\x2f\xee\x20\xf8\xc9\xfb\x8e\x3c\x8b\x36\x47\x59\x78\xb6\x9f\xb6\xe9\xda\x4c\xc2\x89\xf5\x77\x76\xc2\xe5\x77\xd5\x3c\xe3\x0b\x3e\x0a\xac\x46\x5d\x25\x90\x35\xb2\x25\xba\x22\xee\xc7\xd1\x05\x40\xda\x7d\xa7\x27\x9f\x77\xf6\xe4\xf3\x8e\x9e\x7c\xd6\x3d\x39\xb4\x3d\x39\xac\x7a\xf2\x19\x1f\x7c\xa5\x27\x9f\x55\x4f\x0e\x4c\x4f\x36\x08\xff\xcd\xc9\x6d\xb5\x75\xac\x42\x8c\x5a\x1e\xf0\x96\xad\x82\xca\x4f\xb4\xde\x21\x12\xa4\x5e\x72\x4b\x99\x65\xd7\x94\x89\x2c\xc9\xcf\xfd\xf4\x2c\x37\x5b\x4d\x06\xf5\x96\x12\xf7\x59\x69\x9a\x51\x1f\x7b\x6f\x69\xbc\x59\x79\xce\xb3\x79\xc2\x1f\xcd\xb9\xfd\xc8\xc9\x6a\x6e\x59\xfe\xf1\xaa\xce\xc6\x8c\x7d\x91\x80\x3a\xf5\xcb\x9a\x5c\xc1\x8e\x2e\xd2\x44\xce\xff\xb2\xa4\xa0\x1b\xf9\x44\x93\x90\xff\xcd\x4d\xea\xb1\x3c\xd1\xcf\x73\xa7\xc4\x56\xb3\x8e\xb5\x17\xec\x69\x42\x55\x4d\x3f\xd1\xdf\x73\xa7\xc4\x3f\x69\x7a\x83\x5f\xfb\x2f\xe2\xc7\xaf\xbd\x7b\xb8\x40\x5a\xbf\xc8\x19\xbe\x7e\xc1\xdd\xb6\x65\x12\x4e\x48\x35\x5d\xb5\x32\x3a\x05\x8c\x98\x2a\xef\xc4\xd1\xfe\x5e\x58\x28\x76\x79\xed\xc4\x33\xef\x1c\xaf\xd7\xed\x24\x0c\xdb\x99\x27\x86\x11\x65\x84\xf7\xd4\x1b\x0c\xca\x8d\x3c\x86\x14\x5f\x20\x59\xe2\xe2\xda\x41\x41\x46\xef\xd7\xeb\x4c\x4b\x2a\x29\x01\x50\xf3\x84\x27\x68\x14\x25\x44\xe0\xca\x44\x0c\xc8\x1f\x6c\xf5\xc9\xde\x33\x68\xf4\x00\x20\x00\x40\x91\x61\x18\x89\x36\x51\x76\x68\x94\x28\x93\xa8\x44\x99\x84\xb6\xa1\x16\x69\xb3\x1c\x28\x4e\x88\x91\x22\x49\x5c\x99\x36\x93\xb8\x35\x7d\xfe\x9c\x23\xf5\xda\xdf\x72\x9c\x92\x8f\xbc\x57\xed\x6a\x9c\xdb\x38\x6c\x37\xbc\xd4\x2b\x11\x00\xa8\xe0\xae\x82\xb2\xc8\xe8\xad\x5d\x5b\x79\xa9\x29\xc9\xdf\xba\x61\x77\x03\xaa\xa6\xdd\xdd\x2e\x1b\xd7\xf1\x00\x00\x03\xaa\x9d\x69\x25\xa3\x2c\x3e\x61\x51\x82\x70\x66\xdc\x6b\xa9\x14\x81\x70\x94\x92\xd2\xc1\x37\x52\x9c\x68\x3c\x14\xf0\x8c\x65\x27\x50\x76\x95\x70\x6a\x98\xd3\x14\xa7\xfe\x1a\x90\x0c\x47\xcc\x6b\x24\xb7\xc8\xac\x69\x44\xa9\x2a\x62\x66\x1a\xc9\x70\x6d\x21\x09\xc5\x4b\x22\x70\xc4\x49\x82\xc2\x70\x89\xb4\x40\x74\x4e\x96\x38\x21\x7d\x4c\x49\x49\xf8\x90\x0e\x29\x01\x49\x2f\x94\x74\x3a\x46\x04\x01\x0b\x92\x0f\xc5\x50\x8b\xa9\x20\xaa\x73\x86\xfd\x17\x49\x97\x0e\x51\x29\xd3\x4b\x84\x93\x6e\xd7\xa4\xd3\x6e\x32\x44\xb9\x4c\xcf\x11\xa6\x26\x5d\x16\x80\xab\xbf\x24\x84\xe4\xeb\x35\xfc\x38\xa6\x98\x0d\x51\xce\x34\xa8\x1b\xd8\x94\x8e\x4e\x5d\xa9\x71\x2e\xe8\x79\x89\x4b\x32\x9e\x0c\x79\x18\xf2\x36\x21\x79\xe5\x21\x3a\x4a\x08\x77\x1a\x5e\xaf\x13\x99\x8f\x86\x48\x5b\xf0\xe3\x08\x73\xd9\x38\x57\x82\x34\x5c\xb6\xb2\x0c\xc3\xe5\x56\x2b\xcb\xc6\x56\xb8\x6a\x65\x89\xf0\x52\xb6\xb2\x54\xad\x2c\x49\x7f\xb8\x7c\x61\x8d\xfe\x2d\x3b\x1d\xf4\x91\x45\xe5\x78\xe9\x8a\xe3\xa4\xa6\x2c\xaf\xc4\x7c\x96\x72\x5e\x3e\xb2\x88\x43\xd1\x4a\xcc\x87\x59\x02\x20\x5c\x1a\xcf\xbf\x0f\x0b\x34\x1a\xa7\x93\x78\x9c\x62\x36\xd9\x6c\xe0\x7d\x7c\xc5\x1b\x65\x65\xb5\xaa\x51\x56\x8e\x6c\xa8\x46\xa8\x32\xef\xad\x96\xd4\xee\xab\xa3\x30\x78\x26\x13\x06\xcf\xe4\x91\xa6\xea\xc0\xc8\x43\x2e\x36\xf8\x9c\x1b\x47\x8c\x15\xf3\xcc\x97\xc4\xa8\xc0\xc6\x4f\x15\xe6\xf3\x4a\x05\x3d\x1f\xe6\x0d\x3e\x74\xad\xef\xf0\x46\x17\xbb\xc2\x66\x0b\xdf\x9c\x93\x75\x0e\x09\x3a\x55\xe0\x1f\xc6\x4d\xd0\xe6\x9a\xf4\x54\x83\x49\x48\x8f\x98\x25\xf1\x69\x58\xff\xfe\x90\x57\x82\x54\xbc\xd3\x91\x18\x47\xfb\x9c\x6b\x5f\x8a\xca\xb0\xec\x7a\xdd\x96\x83\x19\xcb\xc8\x04\x0b\xf5\x8b\xaa\x96\xac\xcc\x8c\xec\xd8\x5f\xc0\x37\x7b\x82\x2f\x37\x18\xfc\xd2\xcc\x97\xc3\xef\x38\x59\x29\x8c\xe9\xdb\xa8\x2c\xca\x27\x92\x4f\x65\x51\x69\x5f\xe1\x80\x54\xb6\x37\x8c\xd9\x0c\x45\x6c\xf1\xc9\x2c\xdb\xa6\x04\x9f\x24\xbc\xe0\x63\x4d\x1e\x79\xa3\x7f\x8f\xf4\xef\x07\x9f\x7c\xf1\x07\xf7\x7d\x1a\xd9\x17\x4d\x8c\xaa\xf9\x88\x7f\x06\x43\xd1\x56\xf3\x46\xc4\xc2\x7f\xe8\xcc\x01\xf9\x60\x9d\xcf\x1f\xf3\xf5\xfa\x58\x5e\x07\x4b\x16\x31\xa4\x09\xbf\x15\xfe\xaf\x58\x5f\x19\x8b\x18\x39\xe6\x28\x0c\x6f\x54\x29\xb2\x52\xbe\x2a\x58\xcf\x2f\x89\x29\x9b\xba\x89\x87\x6c\xba\x89\x19\x59\x25\x2c\xbd\x29\x38\x18\xbe\x8d\x18\x89\x98\xdf\xab\x30\xac\x25\xf8\x8f\xb1\xb1\xc2\x7b\x4d\xb5\x3f\x2b\x60\xe8\xa3\x5e\xd5\x28\x56\xc1\x33\xa5\xc3\xc2\x7a\x6e\x14\xc3\x22\xc1\xa7\x59\xcf\x86\x55\xaa\xad\xe0\xc4\x36\xf8\x88\x87\xe1\x27\x1e\x1d\x71\x6c\x27\xe4\x08\x68\x2c\x35\x4a\xd8\x3b\xae\x07\x8a\xdf\x70\x0c\x87\x56\x93\xc2\x34\xfe\x6e\x4d\xe0\x92\x63\x6e\x28\x62\x48\xb1\xe8\x3f\xfb\xb0\xd5\xbb\xaf\xc3\x56\x38\xd3\xd2\x45\x19\x69\x47\x05\xc9\xd6\xeb\xc8\x07\x6b\xfc\x4d\x50\xe9\x03\x8d\x78\x5c\x87\x76\x10\x42\x2b\x1a\xaf\x0a\xf2\x2b\x8d\x0a\xf9\x04\x9f\xf5\xcc\x11\xb0\xd2\xe4\x09\xe9\x0f\x93\x17\x99\x39\xe3\x89\x3e\xe3\x05\x18\x2a\xcd\xc6\xc9\x04\xa1\x55\x21\x77\xa8\xe1\xf1\x14\xa4\xdd\xdf\x64\xa4\x0d\x26\x62\x7d\x10\x4c\x13\xe4\xb7\x48\x22\x35\x0b\x8b\x8a\x78\xe1\xa8\xa6\x14\x5b\xaa\x29\x61\x18\x1d\x73\x52\xc8\xc3\x22\xcc\x49\xf1\x8c\x1d\x2a\x7e\xde\x11\x27\x6f\x38\xd1\x27\x6b\xcb\xf0\xa2\x62\xff\xc9\xf3\xd5\xf7\x0c\x9c\x56\x07\xdc\x65\x16\x2e\x17\x8e\x49\x47\x97\xf4\x0e\x07\x14\xff\xc1\x23\xa0\x69\x38\xba\x2e\xd5\x49\x8f\xb3\x59\xf4\x97\xb1\x96\xeb\xf3\x2c\xb7\xd9\x9d\x2d\xdd\x94\x27\x19\xbf\xc1\xff\xf2\xa8\x18\x56\xad\x1d\xe0\x7b\x25\x97\x99\x27\x8b\x92\x4e\xdf\x67\x26\x61\x51\xd2\xe5\xd4\xa2\xba\x46\x92\xc2\x6b\x26\xcd\xb3\xc5\x55\x91\x70\xb0\x3f\xd5\x80\x5b\x07\x5e\x01\xc3\xca\xf4\x6b\xa9\x45\xf4\x13\x25\xd6\xf8\x9d\x47\x70\xf0\xb1\x78\xd5\x99\xea\x56\xfb\xdd\xa5\xc3\x5b\xc6\xad\xe9\x83\xe6\x8a\xa8\xcf\xf7\x8d\xd4\xb6\x49\x46\x61\x38\xd8\x37\x36\xe8\xc8\x60\x1f\xc5\x94\x08\x3c\xe8\x5b\x5a\xd2\x60\x1f\xe1\xfd\xbd\x17\xf0\x4c\x83\x29\xee\x11\x8d\xd5\x6b\xf3\x2b\x27\xab\xc3\x32\x8d\x83\xc3\x32\x4d\x16\x34\xc0\x17\x8b\x24\xa5\x57\x09\x8f\x83\x56\x80\x4f\xe8\x4c\xc4\xc1\x4b\xce\x8b\x7b\x19\x0c\xf0\x87\x85\x8e\x7e\x58\x04\xf8\x1d\xe0\xba\x2a\x0e\xe1\x00\xbf\x2e\xee\x99\x4e\x01\xe1\x77\xfc\x9a\xe6\x71\xf0\x1a\x4c\x12\x06\xf8\x63\xc6\xe2\xe0\xec\x22\xc0\xa7\x94\x2d\x63\xe3\x3e\x5d\x46\x02\xfc\x72\xb1\x28\x6b\x49\x17\x60\xf8\x26\x0e\xd4\xef\x49\x91\xde\x06\xf8\xb4\xf8\x72\xce\x33\x06\x67\xe0\x37\xfa\x18\x07\x1f\x58\x36\x95\x78\xf5\x2c\xa3\xd3\x60\x83\xff\xe4\x64\xf5\x53\x1c\xbc\x4a\xd2\x5b\xf0\x50\x15\xe0\x9f\xe3\xe0\x7d\x72\x15\xe0\xc1\x5e\x1c\x1c\xe4\x34\xe1\x01\x1e\xec\xc7\x81\xc6\x30\x07\xcf\xe3\x00\xa8\x58\x01\x1e\xfc\xa8\xbe\xcf\x8b\x3c\xc0\x83\x9f\xe2\xe0\x65\x2e\x53\x7f\x8e\x83\xf3\x44\x62\x05\x78\xaf\x1f\x07\x07\xc9\xa2\x54\x3d\xd9\xfb\xb1\x9a\xb4\xfd\x3d\x98\xae\xfd\x7d\x59\xf6\x9a\xca\xc9\xd9\xff\x5e\x85\xd5\x34\xec\xff\x20\xbf\x38\x0d\xf0\xfe\xf3\x38\x78\x53\xcc\x65\x9d\x1f\xbd\x99\xdd\xff\xc9\x99\xd9\xff\x9b\xbb\x7f\x71\x6e\x22\x57\x16\xc7\xf1\x7f\x25\x76\x6d\xcd\x95\x6e\x84\x8f\x9d\x17\x64\x8c\x70\x85\xd7\x81\x5d\x42\x58\x60\x97\xdd\xcd\x4d\xa5\x26\x63\x25\xd1\xe2\x8c\xbc\xa3\x71\x20\xc4\xfe\xdf\x7f\xa5\xd6\x5b\x33\x0e\xb0\xe7\x9c\xfb\xb9\xbf\x6f\x15\x45\xc6\x1a\x8d\x1e\xad\x56\xab\xd5\xcf\xed\xfd\x18\xac\x3b\xc3\x08\xa8\x3b\xbb\x79\xff\x65\x25\x59\xad\x5e\xed\x79\xf8\x8e\xd4\x1c\x9f\x8f\xd4\xc3\x76\xde\x7f\xbe\xa5\x1e\x76\xf2\xfe\xf3\x6d\xf5\xb0\x9b\xf7\x9f\xef\xa8\x87\xbd\xbc\xff\x7c\x57\x3d\xdc\xcf\xfb\xcf\xf7\xd4\xc3\x83\xbc\xff\xfc\xbe\x7a\xd8\xcf\xfb\xcf\x1f\x28\x50\x0d\xf3\xfe\xf3\x7d\xf5\x30\x52\x0d\x0e\xd5\x13\x34\xad\xda\xde\x52\x6d\x8f\x54\xe3\x3b\x3b\x79\xff\xf5\xe2\x4a\xc3\x63\xa4\x46\x15\x2e\xd5\xd6\xd6\x4e\xde\x3f\x64\x4d\xd1\x5f\x11\x26\xc2\x9d\xf0\x91\xdd\xa4\x32\x1d\x40\x79\x8b\xff\x3f\xd6\xc7\xf0\xfb\x64\xb9\x84\xbf\xc0\xf9\x45\x0b\x1d\x25\x58\x31\x64\xc2\xab\x31\xbd\x48\x47\x47\x35\x65\x14\x76\x17\x9e\x98\x55\xcf\xbb\x14\x8e\x2c\x51\xb6\x5b\xe9\xae\x97\xf4\xeb\x26\xff\x30\x83\x53\x1f\x9d\x40\x66\xf7\x60\x5c\x79\xbf\xbf\x22\xd6\xc9\xf2\xef\x4b\x07\x6b\x36\x67\x85\x91\xff\x68\x55\xe6\x7a\xa9\xa1\x25\x02\x5d\xb4\xab\x03\x22\x00\x89\x7c\xb8\x22\x66\x0a\x6b\x3e\xfb\x2a\x18\x1c\x0c\x54\x5b\xa0\xaa\xfd\xae\x01\x7c\x77\x1f\x2b\x4c\x1a\x11\x0a\xe1\xa6\x45\x53\x40\x0e\xaa\x73\x56\x5b\xd2\x5e\x45\x68\xa6\x43\x8d\xc9\xd0\x32\xf2\x7d\x58\xa4\x8f\xa6\x69\x54\xb6\x76\x49\xee\x58\xc6\x8e\x55\x59\x61\x52\x8b\xf0\x98\x09\x35\x63\xdf\x73\x58\x89\x78\xce\x6c\xd6\x14\xbf\x75\x01\x5a\xbf\x71\x96\x36\xba\x5e\x1f\x62\x81\x3d\x0d\x5e\xdd\x63\x83\xa0\x4c\x2d\x1d\x54\xfd\x7d\x6d\x93\xbf\x47\x4d\xfe\x1e\x36\xf9\x7b\x47\x93\x51\x85\x8e\xf7\xae\xc7\x3f\xac\x02\x62\xd6\x14\x87\xc0\x91\xea\xf9\x72\x11\xb1\x83\x8f\x9b\x6f\x54\x31\xbd\x69\x6c\x02\x2b\xe0\xcd\xba\x98\xae\xc0\xb2\xca\x5b\x3b\xa8\x33\xf2\x67\x30\x35\xe9\xb2\x8a\x68\x33\x28\x8c\x32\xd1\xe6\xb2\x42\xde\x8d\xd1\x1f\xea\x88\x99\xd2\x2e\x63\xfc\x1c\x6d\xe9\xe8\xa2\x20\xd9\x6f\x77\x67\xe3\x14\x5a\x1e\xcb\x04\x29\x5c\x63\xad\xe5\xe5\xd7\x5d\x0c\x9a\x8f\xa2\xdd\x19\x64\x3b\xe2\xef\x18\xfd\x58\xa7\xf1\xbb\x53\x3e\x6f\x6d\x60\x6f\xf6\xd9\x45\xb2\x0f\xe2\x7c\xbb\xdf\x41\x9f\x2e\x9e\xa2\xfb\x2d\x00\x9c\x4d\x04\xce\x20\x6a\xa0\xf5\x93\x36\xf1\x02\xc3\x9f\xc1\xbc\x7d\xf0\x40\xd5\x58\x15\x36\xb6\xf1\x2b\x83\x3a\x1b\xbf\x9b\xbf\xff\x64\x39\xa3\xff\x0c\x27\xbb\xf1\x93\x2a\xaa\xa3\x21\xd8\x3c\x03\x8c\x1e\x45\x70\xd1\x71\xf5\x72\x46\x85\x88\x79\xe5\xf9\x8d\x05\xab\x03\xb8\x31\xb4\x61\xf4\xa7\xfa\xef\xc6\x1f\x0f\xa3\x7d\x45\x00\x09\x42\x38\xc6\x25\x01\x54\xc2\xb0\xe8\x77\x47\x4e\xd7\x38\xfd\x57\x9d\x04\xa9\x53\xf7\x3b\xcb\x7d\x3f\xae\x20\xcf\x99\xbf\xed\x09\x2b\x42\x24\xcd\x6a\xa5\xf6\x5b\x2b\xf7\xd3\x70\x84\xf1\xf8\x82\xea\x2c\x3d\x5e\xe8\x03\x1e\x44\x5a\x32\xd2\x7f\xab\xf3\xc4\xb0\x1a\x36\xf6\x9b\xd9\xe2\x82\x57\x1b\xef\xf8\xd5\x7c\xc6\xc2\x92\x67\x4e\xa6\x1a\x96\x6a\x53\x90\xe8\x4b\xb8\x6f\x84\x25\x81\xe1\x6f\x50\x1c\x8a\x1c\x30\xb9\x46\x98\x5c\xd2\x67\x15\x39\xa3\xaf\x2b\x72\x45\x5f\x55\xe4\x3d\xba\x6d\x8d\x22\xe7\x82\x74\x0e\x24\x7f\x5a\x93\xd6\x58\xf2\x2f\x35\x69\x0d\x27\xff\xbd\x26\xdd\x23\xca\x65\xbd\x32\x5e\x59\x82\x1e\x9f\x10\x29\xe8\xbd\x40\xda\x51\x0a\x45\xb8\x86\x8f\xa4\x00\xad\x9e\xcd\x9e\x55\x88\x63\x29\x4e\x88\xfe\xa3\xc5\x24\x52\xdc\xbb\x17\x06\x08\x11\xc6\x1e\x4e\x6c\x6e\xda\x7a\xee\x7b\xe2\x5b\x32\x06\x3a\x82\xde\xae\xc8\x5c\xd0\x5b\x53\x9e\x2f\xc4\x8a\x9c\x07\xbf\x7b\xa3\x15\xb9\x14\x74\x21\xfc\xd8\xce\x44\xec\x99\x6b\xcd\xe2\x15\x71\x01\xfa\x1d\x7b\xe8\x2e\x84\xf1\xcf\x4d\x7c\x78\xeb\x2c\xab\x07\x89\xeb\xf8\xa1\xc9\xaa\xf7\x4b\x75\x55\xc8\x8f\x4c\xa7\x62\x35\xb7\x83\x50\x09\xb0\xf6\xc3\xc3\xd6\x67\x3a\x1e\x22\xe1\x36\x49\xba\x30\x69\x3b\xc1\xe7\xeb\x58\xb8\x74\x9c\x75\x96\x21\xc4\xc2\x41\xe2\xef\x1a\x9d\x02\xee\x37\x0f\x8a\x72\x4c\x78\x60\xce\x23\x02\xad\x6e\x15\xa4\x1d\x2c\x83\x6f\x00\xb4\x38\xcb\xb4\x25\x69\x8f\xd2\xc0\x1e\xe8\x50\x20\x7c\x5b\x0a\x74\x2e\x30\x29\x05\x9a\x8b\x00\x23\x2e\x44\x90\x68\x65\x2e\x2c\x06\xf4\x28\x5d\x88\x74\x07\xef\x3d\xc0\x78\x3c\x53\x0d\x90\x06\x93\x99\x6a\x30\x0a\x3f\x73\x23\xe2\x20\x9a\xc9\x92\x32\xeb\x45\x1f\x0e\x99\x74\x79\x00\xd7\x8a\xb0\x84\x10\xf1\xbe\xf3\x56\x00\xc3\xd5\x42\xd5\xb4\x55\x13\x81\x79\x47\x0f\xc1\x7b\xd6\x0a\xe0\x34\x7c\x40\xae\xb4\x86\xa9\xff\x8b\xf1\x5a\x22\x3c\xc9\xbb\x5e\x91\xdb\x55\xe4\xbc\x76\x1d\x2e\x00\xa3\x09\x1e\x64\xd9\xfa\xa5\x65\xf5\x45\xbc\xb4\xcb\xe5\x42\xa8\x1d\xe3\x21\x4d\x34\x40\x99\x05\xe8\xb9\x7b\x03\x21\x13\xbd\xf5\xd1\xdd\xc0\xed\xb5\x92\xf1\xed\xed\x63\x3c\xae\x26\x88\x51\xb3\x2e\x97\x02\x93\xf5\x5b\xa3\x35\x54\xca\x48\x84\x33\x6e\xa0\x38\x37\xe5\x0e\x03\xd4\x88\x4e\xc5\x5d\xa1\x58\x3f\x45\x6f\xd3\x60\xf7\xe4\x4b\xf4\x5a\x1f\x6d\xee\xe5\x51\xdc\x32\xfb\x6b\xc1\x64\xf3\xa6\xe0\x55\x43\xde\x47\xaf\x2a\xf1\x89\x7c\x8e\x4a\x14\x72\x68\x60\xda\x91\x40\x02\x02\xf2\x3a\xaa\xf5\xf2\xea\x8a\x4d\x79\xd1\x30\x37\xdc\x57\xe2\xab\xa1\x67\x9f\x45\x55\x92\x10\xfd\xef\xa2\x97\xaf\xc4\x27\xf7\xe6\x49\xdc\xf3\x74\xe6\x3b\xfd\x08\xe4\xf6\xaf\x18\x52\x97\x62\x31\x9b\xfe\xce\xd9\x6c\x4a\x3e\x08\xea\x76\xf7\x91\x98\x1c\x89\xd0\x7f\x6b\x45\x9e\x1a\xfb\xe7\xc7\xe6\xef\x1b\x41\x7b\x23\xf2\x9b\xa0\xef\x05\xc2\xe4\x4f\x41\x47\x6c\xe7\xd1\x6f\x62\xf2\x5e\x74\xf8\x7d\xa9\x3a\xf7\x7e\x13\x81\xad\xce\x5b\x45\x34\x0c\x97\xfc\x59\x20\x6c\x42\xde\xbe\x16\x56\x1e\xb7\xbf\xaf\xd9\xa5\x57\xbe\xe4\x81\x2e\x79\xe6\x4b\xee\xeb\x92\x77\xbe\x64\x4f\x97\x3c\xf1\x25\xbb\x8e\xc3\x48\x63\x4a\x6c\x45\x01\xc7\x5e\x8a\x76\x7a\xf9\x8d\xfd\x7d\xdb\xce\x6b\xa1\x5b\xde\x7f\x60\x4b\x5e\xd9\x92\xfb\xb6\xe4\x99\x2d\xd9\xb3\x25\xef\x6c\xc9\xae\x2d\x79\x22\xbe\x71\x3c\x2f\x44\xa2\xfa\x82\x01\x92\x53\x5d\x1c\x38\x35\x8b\x24\xaa\xa1\xad\xf9\xc9\xbe\x08\x1c\x75\x53\x5a\x4f\x29\x7d\x2a\x26\xe8\xa9\xa0\xc7\xec\x44\xad\xed\x27\x81\x5e\x0b\xf2\xbb\xc0\x38\x7f\x2a\xac\xb7\x2b\xf9\x28\x02\x5f\x5b\x81\xc2\x98\xa5\x8f\x85\xf5\xf1\x7c\x2c\xc6\x16\x39\xbe\xa8\x7e\x56\xbf\x8b\xd0\xbe\xf1\x77\xf3\x5d\xef\x8d\x70\xd1\x4d\x9e\x0a\x7c\xab\x10\xc9\xba\xb4\x6a\x9b\x4c\x2d\x91\x79\x2a\xc6\x2f\x04\xda\xdf\x8f\x52\xb8\xe8\x48\x5e\x3e\x58\x19\xb3\x69\x24\x2a\xda\x1c\xb3\x93\xf1\x54\xdc\x56\xb4\x42\xbd\xa1\xcb\x76\x66\xf3\xcd\xac\x56\x18\x5b\x24\x36\x51\xa8\x2a\x7c\xab\x97\xc0\x8d\x26\xcb\x14\x28\x9e\x3a\xc7\xf3\xcd\x11\x06\x38\xbe\x16\xe4\x57\x81\x49\xe5\xcd\x44\x15\xf6\x87\x36\xa2\xff\x4c\x57\x61\x34\xbc\xbf\x7d\x7f\x67\xf4\x60\x6b\x74\x0f\x8d\x36\x11\x0a\x7e\xb3\xcd\xe6\x1f\xa3\x21\xfe\x07\xaa\xfe\x41\x47\x43\xbc\x1c\x62\xfc\xdf\x41\xb4\x89\x9f\x84\xcf\x7b\x0f\x11\x03\xac\x2f\xa3\x98\x4b\x1c\x05\x8a\x6c\xb4\xdb\x5f\x83\x89\xf6\x80\x09\xea\xf9\x64\xca\xc7\xd5\x49\x96\x21\xf5\x07\x22\xf5\x7b\x67\x6b\xa0\xab\x3f\x04\xec\x96\x76\x8a\xfc\xd9\xac\xe1\x8f\xe6\xef\x1f\x22\xb1\x1c\x66\x1c\xe1\xdb\x3f\x04\xfd\x51\x50\x53\x37\xc8\x2b\xcc\xbd\x48\xf9\x07\x77\xd4\x8c\x4b\x81\x7e\x10\x98\x18\x76\xed\xd4\xf0\x6b\x83\x53\xf3\xde\xa4\x9e\x0f\x7c\x2d\xb9\x0f\x8b\x19\x86\xbb\xb1\x5c\x5f\x94\xe4\xd7\x70\x2a\xcf\x3e\xcf\xb9\xd6\x3a\xbe\xe7\x57\xec\x61\x83\x3b\xcb\xbd\x01\x09\x44\x94\xe8\xfc\x12\x6c\x5d\x3a\xbf\xc5\x2e\xa7\x6b\x0f\x7d\xb5\x19\x6c\x54\x0f\x6b\xda\x5a\x05\xb1\x69\x82\xfc\xac\x66\xe6\x3f\x0b\xca\x88\x06\xb2\xb3\xf8\xb7\x8c\x59\xa8\x1f\xc5\x6e\x2f\xd9\x60\x76\x1a\xb6\xe0\x14\xcd\xa2\x2e\x1f\x81\xb0\xfe\x59\x01\xee\xd1\x71\xed\xd4\xd2\x5a\x70\x87\x82\x7f\x08\xad\x58\xef\x8d\x74\xd6\xa8\x21\xc8\x41\xf9\x39\xea\x88\xe1\x95\x65\x0e\xcb\xb7\x75\x3a\x42\xf4\x87\x9a\x47\x43\x7d\x39\x26\x0d\xbd\x35\x08\x90\x33\x22\xce\x24\xab\xaf\xd9\xf4\x31\x6f\x64\xde\x90\x4a\x95\x6a\x3c\x34\xe4\xe9\x47\x11\xe6\x92\xfe\x39\xe5\x1a\xb7\x87\x8a\x6b\xfc\x51\xd0\x86\xfc\x2c\x22\xc8\xd0\xdb\x78\xfa\xf9\x90\x84\x53\xce\x1b\x52\xdb\xfb\xa0\x16\xc4\xad\xb4\xd1\xc6\x8f\x0a\xe8\x10\x7d\x8b\x3a\x8d\x2d\x8b\x51\x55\x67\x98\xe5\x91\x8a\xb8\xe0\x3a\x0e\x80\x76\xca\xfa\x79\xc1\x16\x8c\xde\x9e\x15\x92\x69\xf9\x5c\x92\xb4\x1b\x22\x98\x42\x25\x2b\xdd\x2b\x6a\x36\xcd\x6f\xd5\xf0\x79\x75\x61\x40\xa0\x73\x91\xdb\xd1\xb9\xae\xa4\x59\x1d\x85\x0b\x41\x77\xa4\x89\x3a\xd7\x8a\x98\x66\xfd\x80\xdc\x73\x30\x18\x5d\xaa\x9b\x33\x63\x62\x03\xfd\xe0\x46\xc3\x4c\x8e\x74\xb9\x0a\x30\xa6\xe4\xe1\x69\x85\x58\x0b\xfa\x8c\xe8\x34\x25\x92\x69\x0f\x76\xc8\xd6\x79\x91\x0f\xc9\xbc\xb8\x99\x89\x62\x6a\xbd\xbf\x35\x57\xa6\x7f\x79\x6c\xc0\x7a\x41\xc2\xbc\xad\x3c\x4a\x64\x6c\xf7\x46\x30\x5b\x6c\xe9\x85\xe6\xa8\x61\x12\x78\x60\x20\x3c\x36\x08\x55\x4d\x1a\xb3\xd6\x39\x32\x4f\x15\xfc\x21\x95\x29\x57\x7b\xc5\x7c\x44\x9b\x60\x15\x16\x3c\xbe\x89\x7a\x9a\xe4\x29\x83\xe4\x90\x91\xd8\xe2\x32\xaa\xda\x83\xf4\x00\x87\x1c\xca\xee\x17\xb5\xe3\x22\xf6\x01\xaf\x1d\x61\x10\xef\x92\xc7\x52\x4a\x1e\xf7\x36\xd6\x48\xab\x55\xcc\x3c\x5c\x6b\xca\x0d\x84\x1c\x80\x3c\x60\x65\x08\xe5\x42\x37\x5c\xd2\x02\x7a\x1f\xeb\x3f\x54\xea\x21\xe9\x3f\xb4\x5c\x15\x54\x92\xb4\xc9\x98\x92\x95\x69\x66\x7b\xff\xa2\x8c\x20\x94\x65\xa8\x0c\xe0\x22\xc3\x40\xb3\x6a\x38\x6e\x28\x3a\x3f\x28\x0f\x10\x7b\x41\x87\x36\x01\xf1\xb9\xf1\x83\x71\x86\x7d\xa6\x81\xd2\x1d\xa9\x97\xb4\x34\xc9\xbf\x91\xa4\x97\x09\xf1\xc4\x0f\x0d\x44\xcf\x5a\x98\x9d\x56\x4d\x11\xfd\x72\x10\x17\x00\xde\x5f\x0e\x9a\xe2\xc2\xe1\xfe\xe5\xc0\x3c\xf9\x0d\x70\x39\xb0\x8f\xc1\x36\xb0\x58\x3b\x9d\xa0\x73\x3a\xa5\x67\x64\x4e\x67\x38\x9f\xd2\xa9\x06\xfb\x19\x91\x8f\x16\x59\x86\x16\x54\xea\x24\x77\x36\x8d\xda\x34\xcb\x90\xab\x95\x8e\xdf\xd3\xe6\xff\xe0\xc8\x31\xe1\x25\x92\x24\x6d\x11\x8f\x59\x0e\x60\xbd\xa2\x8c\x1c\xd2\x4b\x2b\x38\x97\xb4\x21\x67\xb4\x22\x87\x60\x99\x79\x6b\x72\x5d\xa8\x53\xa7\x6d\x3e\x86\xae\xe8\xa1\x1d\x05\xc6\xb7\x33\x7a\xa5\xe5\x7d\x67\x64\x46\x24\x76\x26\x12\x33\x7a\x15\x79\xd2\x6e\x6c\xe7\x57\x86\x92\xbd\x2f\x2e\xe8\xbd\x9d\xe1\xfe\xfd\x2c\x28\x59\xee\xed\x8c\x4d\x1a\x0e\x7f\xfe\x20\xd9\x65\xc0\x16\x8d\x60\x12\x75\x9f\x5f\xe1\xe5\xd2\x31\x63\xd2\x99\x0d\xce\x34\xeb\x16\x8e\x50\xf7\xb6\x95\xab\x3d\x3a\x5c\xd9\x8c\x73\x1e\x9a\xfa\x48\x77\xc3\xa3\xdb\x5b\xc4\x8f\x8a\x5b\xa2\x8c\x27\xee\x91\x1e\x5f\x9e\xe4\xc6\x88\xf0\xd2\xef\x1a\xf5\xc1\x25\xbd\x04\x64\xc0\xcb\xe5\x25\x55\x9b\xe0\x36\x9a\x63\xba\x73\x2d\x2b\x73\x49\xbb\xb7\x3b\x09\x68\x09\x5d\xbb\xf5\xf5\x9c\x00\x7d\xe7\x74\x96\x1b\x74\x3c\x27\xc1\x8e\xa5\xf3\xa8\xa9\x29\x29\x4a\xb4\x50\x14\x38\xc6\x59\xba\x20\xc9\x81\x4a\xc3\x03\xf2\x9c\x07\x52\x27\x45\x49\x0d\x40\x88\x7b\x8a\x48\x11\xc3\x3e\x40\x19\x0b\x03\x94\xb9\x04\x57\xcd\x09\x11\xb4\x76\x2b\x11\x90\x0f\x61\x02\xf4\xda\x57\xba\xe1\x9a\x0a\x22\x68\xd5\x2d\x7d\x4a\x25\x29\xfb\x23\x52\x63\x3c\x36\xf6\x7b\x02\xaf\x74\xe8\xe7\x29\xa7\x3f\x0c\xde\x42\x70\x4a\xcd\x7a\x3c\xf6\xe1\x5f\xc8\x25\xa7\xa8\x62\x9f\x36\xea\x01\x44\x12\xa8\x58\xd5\xe0\x41\xcd\xce\x65\x20\x29\x0d\x8e\x82\x8a\xfa\x13\xa8\x42\x35\x69\x68\x02\x3e\x1c\x62\x69\x35\x69\x72\x7d\xb1\x20\x90\x12\x32\x06\x74\x45\xc0\xc8\x23\x59\x11\x40\xce\x80\x6a\x07\x4b\x6a\x24\x38\x57\x9c\xde\x72\x79\x28\x16\x10\x8f\xa5\xad\xfc\x03\x87\x1b\x36\x88\xe5\x47\xcf\xf9\x19\xab\x71\x96\xfd\xc1\x10\xc3\xaa\xdb\x15\x61\xd5\x5f\xaa\x83\x77\xac\xd1\x8c\x4c\xac\x9e\xd3\x5c\x51\x47\x23\x46\x0e\xfc\xab\x44\x98\x08\x3a\xe5\x8e\x10\x8d\x91\xa0\x25\x47\x35\xfd\x5d\xa2\x9a\x30\x22\x30\x11\x18\xdb\xed\x6c\xb3\x8d\x0e\xe3\xa8\x9c\x59\x86\x44\xb0\xe6\x98\x00\x3b\x22\x30\xf9\xa7\x84\x6c\x23\x6e\x98\x6f\xd9\x7c\x56\x94\xec\x3f\x3a\xd4\xa6\xb8\xa0\x23\x22\xfe\x5d\x43\x7e\x2e\xea\xd2\x24\x8e\x4b\xac\x70\xef\x1a\x6f\xa5\xc7\x5b\xc7\xe3\xad\xd5\x78\x2b\x35\xde\x8a\x40\x16\x96\xda\x8c\x77\xcb\x8f\xb1\xf1\x41\x7c\x21\xb1\xa2\x1b\x63\x63\xc6\x58\x9b\x31\x56\x91\xab\xec\x21\x0f\xed\xf3\x48\xe1\x94\xc8\x1d\xf4\x39\x11\xad\x6b\xb1\x97\xdb\x39\x7a\xae\x13\xd6\x5d\x8e\x6a\x68\x3d\xef\x05\xb6\xc4\xcb\x65\xf8\x6b\xc0\xe5\x9b\x45\xcd\xf4\x5e\xb5\x1f\x2f\x97\xa8\xf7\x9b\xb6\x29\x5b\x2e\xd5\x93\x20\x3c\x0c\x09\x78\xc1\x63\x81\x6b\x6f\x44\x04\x5d\x08\xc2\x6d\x00\x6c\x2d\xc1\x1e\xaf\x89\x79\xb1\xc1\x1d\xd4\xf8\x84\x53\xc1\x11\xc7\x39\x12\xf4\x4a\xa0\x06\x4f\x2e\x45\x1e\x88\x80\x39\x45\xda\x18\x4f\x71\x57\x75\xdc\x7e\x24\xd4\xaf\xf1\x04\xf4\x2b\x02\xe7\x0b\xa1\x2e\x6a\x10\xa7\x08\x55\x84\x77\x90\x01\x1b\xb9\x16\xe0\x1a\x34\x62\x4a\x26\xe6\xaf\x31\x85\x30\xb4\xa1\xa6\x57\x9c\x04\x6b\x01\xec\x6d\x07\x4a\x51\x46\xfe\x55\x9d\x88\xf8\x5e\x9d\x48\x20\x7f\xb8\x09\x68\x27\xb3\x33\x22\x5d\xa6\xeb\x8d\x8e\x59\x51\x81\xbb\xca\x6c\xf6\x96\x95\x8c\x5f\x33\x90\xc1\x64\xd9\x1d\x2f\x01\x31\xd6\xb4\xf8\xcb\xeb\x77\x07\xcf\x9f\x9d\xde\xd9\xf0\xd7\xea\xe8\xf6\xcd\xc8\xf5\x0d\xfe\x8a\x0f\x3a\x88\x12\x6a\x6c\x2d\x92\x08\x01\xae\x79\x6a\xf1\x10\x2a\x05\x04\x78\x5e\x4b\x5a\x11\x93\x64\x28\x3d\x52\x88\x80\x03\x89\x5e\x72\x02\x77\x63\x13\xfa\x2a\xc6\xee\xbb\xf1\x5a\xd8\xba\x16\xbf\x79\x27\x7e\xfb\x6a\x80\xbd\x1c\x63\x02\xf7\xa0\x8a\x08\x88\xf5\xb1\x66\x7c\x5d\x84\x42\x8d\xef\x82\x35\x4f\x59\xcd\xaf\x4d\xbd\xe7\xb5\xb8\xd2\x32\xb5\x2c\x43\xe6\x50\xe5\xea\x60\x5c\xd3\xee\xba\x55\x5d\xd7\xec\x72\xd9\x55\x5f\x80\xc1\x75\x55\xcc\xe5\xa5\x68\xb4\x16\x57\x93\xa3\xb0\x7a\x2f\xa8\xde\x85\x10\x70\xd8\x76\x47\xc1\x15\x83\x76\xcd\xe5\x12\x35\x54\xdc\x81\xec\x5d\x1f\x65\x59\x57\x29\xea\x86\xc2\x9d\xc3\xbc\xe3\x25\xc2\xa4\x51\xcc\x96\x25\x36\x6b\x50\x59\xd8\x35\xd1\xa8\xfc\x2d\x58\xb0\x6e\x9c\x6e\x0c\x4f\xf9\xd4\x8c\x2f\xe6\xbe\x77\x34\x57\x73\xc0\x8d\xc9\x01\x97\xf0\xd7\x9f\x4f\xa7\x21\x13\xea\x45\x14\x95\xda\x15\xb8\x7b\x51\x3a\x13\xa6\x98\x9c\x12\x83\x53\x30\x23\x37\x21\xbf\xa3\x9f\xa3\x9e\xc9\x49\xde\x92\x8d\xed\xdb\x5c\x3a\x34\xc8\x56\xbe\xea\xd4\xe7\xed\xdc\x27\xd6\x1b\x5f\xd0\x7e\x7f\x93\x25\x29\xc2\x83\x53\x5a\xcd\x20\x9c\x40\x88\xe5\xf0\x0a\xfe\x0c\x4e\x75\x0a\x80\xb7\xec\x5c\x87\x2a\x51\x85\x39\x42\x4d\x14\x6c\x4f\x8b\x8a\x6b\xcd\xbb\x36\x94\xd2\x4b\x0e\x7e\x78\xba\x84\xde\xae\x9c\xf0\x84\x4d\x74\x9a\xf1\x8d\xe6\x58\x9c\xe4\x90\xc8\x95\xad\x70\xd8\x8b\x20\x0d\x5c\x72\x6c\xee\x81\x10\x86\x49\x0c\xd0\x07\x3b\x3a\x33\x4e\xcf\x01\x32\xa9\xb0\x3f\x04\x77\x81\x76\xf4\x8b\x4f\x5e\xee\xe4\x83\x8e\xf4\x5c\xae\x87\x64\x05\x46\xa4\x7f\xac\x57\xd4\x38\x39\x9d\x28\x68\xb5\x5c\x93\x6c\x78\x7b\xe3\xc2\x83\x27\x06\x0d\x36\x3e\xf1\xe6\x72\xe3\x23\xbb\x91\x1b\xb7\xfd\xcd\xd8\x59\x68\xf0\xa7\xe0\x15\xea\x93\x8d\x3e\xde\xec\xaf\xfa\x79\xa3\x33\xe8\xb8\x81\x7e\xe1\x69\xe2\x6e\x7b\x21\xb2\x2c\x47\x33\x98\x15\xb2\x79\x06\x38\x6d\x85\x56\xf5\xc4\x64\x1b\xd1\xc5\xb4\x22\x61\x2d\x5a\xe1\xbc\xd1\x92\x63\x53\x10\xbf\x35\x22\x29\xfb\x13\xee\x58\xc1\x1d\xfb\xc1\x2a\x0c\xa7\x68\xc3\xc5\xf6\xe2\xc8\xdd\xa1\xcc\xbf\x1e\xe3\x46\x9f\x64\x35\xad\x07\xd2\x64\x2e\xe8\x0c\x5e\x5f\x7b\x8d\x01\xb3\x09\xb2\x5d\x5e\xf7\x31\x76\xb8\xfb\x91\xdd\xe8\xac\x57\x3a\xa2\x19\x69\x70\x6e\x7f\x42\xa8\x33\x02\x31\xae\x9b\xb4\xb3\x00\x03\x44\x22\xe9\x7c\x5f\x6a\xa7\x31\xfd\x3d\x1d\x2a\xfe\x46\x7f\xac\x21\x10\x7c\xca\x91\x39\x4f\x5d\x34\x02\xfd\x4d\x4d\x74\xe0\x20\xcb\xa0\x79\xb9\xd8\x04\xa9\x99\x43\x2d\xfc\xb0\x9a\xa0\x26\x00\xe7\x16\xa9\x70\x5e\xe7\xed\xb2\x40\x99\x24\xc3\xec\x38\x2e\x25\x79\xd0\x03\xc8\x88\x83\xef\x23\x3e\xa8\xf4\x1c\x40\xac\x34\x6c\x96\x4b\xe7\x38\x0b\xa1\x8c\x5e\x95\x8a\xc3\x1f\x5c\x89\x29\x03\x1e\x5f\x57\xa7\x0a\x30\xb0\xe7\x05\xd2\xe1\x6a\x82\xf2\x40\x96\xdb\xd9\x8d\x26\x3a\xcd\x80\x69\xf3\x54\xc5\x2f\x80\x35\x23\xd8\xe9\x22\x54\xeb\x36\x35\x1b\x02\x2d\x9f\x53\x47\x73\x49\xed\x7b\xaa\xd5\x08\x6a\xfa\xb9\x44\xfa\x5b\x02\xb1\xcc\xec\x97\x26\xbc\x76\x38\xf2\xb5\xed\x04\xc2\xdf\x3b\x00\xb3\x63\x01\xb3\x5c\x36\xeb\xf2\x2f\xea\xcc\x0e\x61\x49\x5c\x19\xcc\xc1\xd4\xac\xe1\x82\x0d\xb5\xe3\x22\x00\xfa\xb3\x6f\x01\x7a\x90\x58\xe5\xf8\x64\xdd\x0a\xcc\xdd\x5d\x8a\x77\xcc\xe8\x7e\xb4\xd4\xaf\xc3\x5e\x15\xb7\xf5\x7d\x8b\x7d\x1e\x1c\x8b\x1d\x59\x62\x3a\x93\xc3\x18\x02\xa1\xf1\xac\xdf\xdf\x6c\x6c\xff\x71\x2f\xa1\xbb\x66\xa4\x96\xb2\xe8\xe4\x33\xac\x0e\x7e\xf8\x41\xbf\x36\xc2\x45\xc6\x6c\x58\xb5\x4a\x61\x4a\xa3\x31\xc5\x90\x88\x0e\x4c\xa9\x42\x4c\xd1\x57\x1c\x4c\x2a\x3f\x96\x4a\x4b\xf3\x1a\xd7\x2c\xac\xd6\x9a\x71\xab\x43\xeb\x80\x83\xdd\xd0\x19\x43\xce\xff\x54\xc3\xda\x7f\xa3\xb9\x9a\x68\xc2\xe6\x34\xea\xce\xe7\x31\x4d\xf9\x77\x0b\x86\x09\xcc\x2b\xb7\x92\xf0\xf6\x2a\x74\xa6\xe8\x89\x0c\x88\x15\x37\xa6\xdd\xf3\x34\x8d\xe8\xf7\x37\x6d\x9a\xdc\xf6\x0a\x04\x52\x08\xb7\x02\xd5\xda\x15\xd8\x80\xfd\x09\x3c\x83\xde\xb0\x6a\xd7\xb3\x89\x41\x51\xbd\x16\x0e\xa9\x21\xf2\x41\xee\x09\x48\xee\xac\x9b\x3d\xec\x83\x06\x17\x71\x45\x03\xf8\x4a\x03\x3e\xb6\xc8\xf6\x33\xf4\x9b\x03\x16\x40\x03\xbd\x5a\x03\xf4\xcb\x30\x22\x43\x27\x70\xeb\x2e\xe0\xba\xb4\x21\xb0\xe0\xda\xf6\x15\xc6\x05\xb8\xd5\xef\x6f\xaa\xf6\xba\xa1\x5b\x3b\xe8\xd6\x0e\xba\xf5\x7a\xe8\xba\xc6\xf5\xf6\xae\xe1\x44\xac\x72\xf8\x6b\xfb\xab\x23\xb8\x37\x84\x91\x3a\x85\xbb\x20\xfa\x8b\x7c\xa6\xdf\xab\xe1\x25\x60\x5f\x84\x53\xb9\xab\x37\x22\xb0\x59\x89\x5a\xaf\x44\xed\xe3\x16\x75\x81\xa3\x26\xc2\x2f\x45\x93\x7a\xed\x79\x09\x28\x12\xa4\x20\x92\x94\x3e\xda\xff\x4c\x1f\xc9\x0b\xfd\x67\x4e\x0b\x72\x46\x0b\x3a\x24\x57\x5a\x2d\x64\xe0\x38\xcf\xb2\x33\xef\x1b\x7f\xb6\xb9\x89\x6f\xe7\xfa\x0c\x7e\x74\x36\x41\x57\x74\x6e\x94\x4a\x38\xbf\xa2\x73\xc7\x29\x40\xd8\x33\x3a\x45\x82\xcc\x89\x3c\x3e\x3b\x21\x65\x98\x0a\xf8\x10\xdf\x9a\xa7\x79\x96\xa1\x39\xbd\x32\x72\xff\x15\xcb\xb2\xb9\x3b\x98\x0f\xc3\x83\xb9\x51\x4d\x61\x52\x50\x8e\x0e\x49\x41\xce\x1c\x2b\xbc\x98\xcc\xe8\x61\xbe\x70\x6c\xc6\x21\x59\xd0\x43\x32\xa7\x57\x0a\x8a\x67\x94\x52\x99\x84\x41\xac\x74\x4b\xb3\x60\x3c\x73\x63\x5d\x91\x4c\xd4\x72\x21\x73\x7a\x8e\x84\x9d\x86\x0e\x2f\xc5\xd1\xbc\x35\x8a\x79\x30\x8a\x39\x59\xd0\xb9\x33\x2f\x99\xad\x54\xf3\x73\x5a\x43\xd7\xeb\xba\xb9\xa2\x97\x68\x4e\x04\x39\x0b\xbb\x62\x0e\xa1\xaf\x42\x70\xcc\x07\xfa\x02\x60\x67\x70\x05\xb8\x74\x96\xc3\x5f\x0d\xa6\xab\xd6\x00\xaf\x82\x01\x5e\x91\x85\x02\xbb\xe7\x86\xe6\xdd\x49\x4d\x2d\x73\x86\x04\x61\x78\x85\x31\x09\x70\xea\x4a\x41\x85\x94\x64\xa6\x69\xea\x82\x9e\x31\xa4\xd7\xb9\xeb\x42\xb7\x48\x6f\x59\xbb\x43\x1c\x20\x05\x2a\xe9\x42\xb3\xfc\x25\x6e\xd9\x92\xee\x8e\xb0\xcf\x9d\x3f\xa7\x06\x65\xcf\xa8\x24\x57\x54\xd2\x21\x39\xd4\x05\x17\xb4\x04\x9e\x1b\xb9\xbc\x50\x67\x59\xd6\xbb\x18\x4c\x45\xc5\xc6\x57\x9b\x9b\x41\x05\x7c\x7b\x66\xb0\xf8\x6a\x82\x0e\xe9\x19\x39\x33\x58\x7c\x48\xcf\x22\x2c\xbe\x01\x2c\x3e\x23\x17\x3a\x9c\x17\x99\x85\x88\x7c\xe3\x10\xf9\x2c\xcb\xd0\x19\x3d\x0c\x10\xf9\xcc\x21\xf2\x4d\x8a\xc8\x67\x98\x48\xca\xd1\x0d\x91\xe4\xca\xad\xd0\x7c\xb2\xa0\x37\xb9\xdb\x42\xf4\x86\xcc\xe9\x0d\x39\xa3\x87\x0a\x91\xf5\x1c\x42\x14\x3e\xc3\x64\x11\x8c\xe4\xcc\xa0\xf0\x9a\xd9\x5a\x1c\xbb\x00\x54\xf6\x73\x51\x28\xa6\x86\x72\xd1\x1a\xca\x45\x30\x94\x0b\x32\xa7\x3e\x43\xd4\x02\xb0\xf9\x0c\xb0\xf9\x0c\x7f\xbd\xc7\x4b\x74\x46\x04\xb9\x4a\x7a\xf5\x88\x7d\x11\x82\xe7\x2c\x41\xec\x0b\x40\xec\xab\xfc\x42\x23\xf6\xf7\x8e\x15\x5a\xfc\x36\xc4\x5e\x58\xc2\x19\xc8\xf9\x6b\xc2\x15\xc5\xd4\xd4\xf2\x4e\xf9\x5c\x96\x71\x7f\x4e\xb8\x95\xe7\xe0\x3e\x39\x83\x38\xc1\x3c\x39\x35\xb4\x7c\x61\x71\x77\xb3\x6a\x85\x17\xd8\x1c\x64\xbc\xe3\x20\x33\xc1\x60\x16\xba\x2b\x32\xa3\xb5\x45\xfd\x99\xd6\xdf\xcf\xcc\x79\xbf\x70\xe7\xe1\x2c\xd0\x23\xdf\xcf\xf9\x39\x0a\x46\x8e\x6f\xd5\xb4\x67\x16\x9a\x98\xc0\xd5\x62\x46\x5a\x83\x0f\x38\x2f\x46\x5d\x22\xaa\x55\xec\xc6\x02\xdd\xc7\x57\x16\xdd\xd7\x57\xba\x09\xf9\xc9\x19\xe1\xd1\xcd\x23\xec\x6d\x05\xad\xd8\x3d\xd7\xc0\x0f\x32\xa3\xae\xdd\x55\x30\x33\xb8\x25\xbd\x2e\x51\x3a\x13\xcb\x51\x96\x04\x20\x98\x4c\x4c\xf1\xf0\xa5\x62\x82\x75\x4b\xba\x8e\x1d\x66\xc4\x04\x97\xe1\xa0\xd5\x55\x00\x62\x01\xb9\x96\x4a\x77\x2e\x4b\xc4\x3c\x77\xe0\x62\xf9\x68\x4c\xf1\x57\x7d\xad\x49\xd5\x4b\x37\x83\x5f\x3b\xc0\x32\x40\x9c\xa6\x7a\xdd\x55\x0a\x00\x1c\x95\xc4\x95\xe3\x7b\x13\xd4\x8e\x8b\xf4\xc2\xd4\xc9\xc2\xd4\x84\xaf\xbd\x39\x85\xeb\x01\xdf\x86\xcb\x11\x0b\x2b\x56\xa8\x56\x8c\x3f\x8f\x41\xe6\xdb\x09\x21\xb4\xea\x64\x17\x79\x17\xbb\xe8\x42\x3c\x70\xda\xef\x6f\x72\xab\xc9\xae\xb3\x6c\xcf\x82\x6c\x82\xd6\x4c\xab\xbd\xdc\x7a\x0e\xaa\xc2\xab\x3b\x86\x8a\x89\x34\xce\x8e\x07\x1c\x71\xc7\xa1\x9d\x39\x9a\xa1\x5e\x9d\xb1\xe0\xd5\x55\xf4\x6a\x91\x65\xc0\x39\x73\x4c\xba\x32\x06\x2b\x12\xd0\x9b\xd9\x7d\xcf\x22\xc3\x0f\x63\x87\xa1\x4f\x48\x9b\x3c\x8e\xf8\xa3\x72\x8b\xe8\xc4\x5a\xb3\x02\xbc\x5d\x97\x4b\x36\xa8\xe0\x6f\xdf\xe9\xe3\xfa\x5e\x9a\xa7\xa7\xab\xb5\xec\x47\x9c\x7e\xe1\xa8\x37\xc4\xe4\xbd\x7e\x1a\x61\xf2\x99\xd3\xdb\x15\x79\xcd\xbd\x65\xec\x67\xbe\x22\xaf\x92\xdf\xcf\xe2\xdf\x5e\xf0\xfb\x8e\x5b\x07\x73\x4a\xe9\x67\x9e\x9e\xeb\xf7\x77\xbc\x43\x48\x20\x1a\x7a\xc2\xa3\x58\xe2\x33\x81\x9e\x71\xe3\x07\xf3\x8a\x1b\xff\x8d\xd7\x9c\x7c\xe6\x98\xb0\x20\xca\x8c\xb5\x53\xd7\x20\x1a\x8d\x72\x08\x8b\xe6\x83\xd2\xb8\x58\x68\x0d\x40\x04\x02\x14\xfc\xf2\xf6\x65\xfe\x58\x9f\x36\xa4\xdf\xc7\x89\x1f\x5e\x43\x1f\x33\xd4\x50\xc4\x28\xa4\x03\x9d\x34\x41\xde\xc8\xbc\xc1\x51\x33\x86\x1f\x67\x3a\x9f\x22\x44\x33\x5d\x95\x6a\x9c\x76\xb8\xe1\xc5\xff\x23\xd7\x7e\x42\xea\x6d\xa9\x66\x05\x7f\x9e\xf1\x30\x79\x1d\x80\xee\x1d\x47\xcf\xb8\x73\x53\x31\x81\x15\xdf\x71\xf4\xda\x17\x92\x0a\x46\x69\x2c\x8a\xf1\xb8\x31\x1a\xee\x04\x5a\x55\x28\x10\xfd\x00\x8d\xbf\x72\x8d\x18\x0b\xc9\x68\x44\x5a\xa8\xff\x34\x58\xda\x30\x70\xf5\x63\x6e\x33\xb5\x9a\xa0\x19\x81\x80\x11\x04\xf1\x10\x11\x43\x63\xae\x0d\x15\x14\x69\x1b\x02\xc3\x91\x2a\x08\xdd\x55\x41\xb2\xae\xcb\x9b\x69\x5d\x34\x90\x30\xd1\x66\x55\x85\xe8\xdf\x3e\xdd\xaa\x0e\xf7\xee\x83\x10\xd8\xb8\xb3\xa3\x7d\xea\xe2\xd9\x05\x7a\x58\xdb\x35\xa8\x99\x06\x35\xbb\x66\xc5\xec\xa8\x9e\x1a\xad\x81\xaa\x83\xf6\x76\xb2\x40\xfa\xd7\xd1\x74\x15\x25\x28\xc5\xb7\xe6\xc1\x12\x86\x06\x64\xa5\x50\x34\x56\x34\x98\x57\x0b\xd0\x2f\x00\x70\x8d\xd1\x90\x13\xe8\xc2\x20\x2d\x9f\x19\x5a\x1c\x35\xa6\xb9\xe5\xd2\x3e\x85\xd1\x86\xe1\x66\xd6\xb8\x4a\x2b\xd7\x86\x1b\x84\x79\x08\xe5\xb6\xdd\x37\xc2\x37\x91\x95\xea\xad\x33\x00\xce\x19\x81\xd3\x2d\x6f\x34\x55\xf8\x2d\xb5\xbd\x79\x6a\xd2\x22\xb1\x9a\xfc\x79\x97\x5d\xce\x5b\x4e\x87\xe4\x25\x37\x41\xa5\xcc\xdf\xe7\xe6\xef\x2f\xb1\xc5\xf0\xaf\x1c\x59\x07\x04\xa7\x2f\xd8\x1a\x85\x18\xfb\x7b\x6c\xe3\x1a\x47\x14\xf3\x99\x67\x87\xe3\xca\x79\x44\x64\x59\xe5\x6d\x98\x2a\x13\x37\x48\x47\x02\x83\x30\x60\x9d\x31\xc0\xbc\x17\x03\x6f\xc5\x3c\x7a\xcb\x29\x57\x33\x6a\x48\xd3\x61\x01\x90\xd8\x1c\x9b\xa2\xc4\x58\x6b\x48\x7e\xf3\x9b\xae\x72\x91\xd3\xec\x53\xdc\xec\xe4\xb0\xc8\x2f\x0a\xc2\xc0\x4e\x49\xe0\x76\x6b\x94\xbe\x55\x23\xa3\xc3\xf1\x54\xe8\x0c\x00\xad\xee\x7a\x68\x6b\xf7\x11\x4f\x6f\x54\xdb\xe0\x22\xcc\x37\xe9\x48\xad\x88\x5d\x9c\x8e\x09\x04\xa3\xbd\xf1\x23\x31\x0e\x25\xdd\xe3\x51\x38\x1f\x7c\x76\x55\x90\xc6\x4a\xdb\x5e\x78\xd6\xf6\x05\xd7\x66\x73\x80\x25\x7a\x0c\x2f\x43\xdc\x20\x4d\x6b\xc8\xc3\xce\xc3\xe2\x27\xee\x32\xab\xdd\x46\xd0\x33\x91\x7c\x9d\x95\xb7\xfb\x19\xd8\x9a\xff\xe5\x1f\x03\xcb\xd2\x58\xe8\xfb\x9c\x4f\x5e\xf2\x64\xbd\x9f\x73\xca\xf2\xe7\x9c\x3e\xe7\xc6\x18\x9b\x3c\x0f\xdc\x48\x7f\xe0\x28\x44\xd4\x17\xdc\x0e\xf0\x25\x0f\x4c\xa3\x9d\xdd\x08\x9b\x24\xeb\xae\x87\x01\x64\x87\x59\x40\x19\xd2\xbf\x7e\x4c\xb9\x19\x4b\x40\x57\x1b\xfc\x5c\x21\xeb\x0b\x4e\x99\x73\xd6\xb0\x98\xd6\xd2\xce\x29\xe8\xb6\x40\x88\xd4\xb7\xb8\xc3\x5e\x5f\xbf\x7e\xc1\x3b\x2d\xe7\x5f\x84\xe6\xd4\x7f\xd9\x22\x78\xe8\xf0\x6a\xf8\x26\xf8\x5a\x1a\x16\x82\xf9\xe7\x88\x82\x75\xea\x60\x27\x0d\x62\x38\x0f\xb4\x38\x3f\x86\x4e\x39\x1c\xa9\xc3\xb3\xd1\x23\x0b\x2e\xd3\x69\x5a\xdc\xed\x91\xda\x2d\x15\xa8\xf7\xde\x32\x45\x24\xd9\xf4\x2d\x9b\x2e\x4a\x56\x53\x66\x94\xca\x2f\x38\x98\x45\xfa\x79\x73\x5a\x75\xd8\x8f\xf3\x50\x05\x6e\xdc\xc5\x24\xd5\x3e\x16\x63\xe3\x6a\x61\x76\x86\x99\xba\x5c\x05\xad\x52\xa1\xb3\xa0\x85\x96\xa4\x51\x7b\xc2\xb4\x05\x7c\xb7\x5b\x9b\xb1\x36\x53\x97\xd4\xec\xb0\x19\x15\x8a\x62\xe8\x0b\xe8\x2c\xd9\xc5\xc0\x9f\x3e\x7c\x6b\x90\x76\xde\xb2\x91\x4e\xeb\xa7\x96\xd2\xb3\xd4\x52\xba\x00\xd0\xe7\xb3\x81\x7e\x20\xac\xb8\x60\xb5\x81\x9f\x6a\x2d\xf8\xa9\xdf\x69\xe4\x32\x6f\x34\x72\xb5\xed\xbe\xcb\x09\x92\xb4\xa4\x73\xc2\x15\xdf\x5e\x1a\xc9\x03\x9d\x93\xc5\xa3\x97\xbc\x6d\x91\xd9\x2a\xa3\x0b\x6d\x50\xab\xad\xc3\xad\x98\xbb\x54\x5c\x90\x6d\xeb\xdb\xad\xc3\xff\xc3\x73\x06\x8b\xf1\x05\x49\x7b\x51\xb7\xab\xb8\x2d\xe0\x52\xc3\x46\x72\x86\x6a\x62\x47\x81\xc7\xea\x72\xac\x9a\x8d\x3d\x02\x67\x59\xa6\xd1\xc7\xc3\x96\xd3\x3a\x37\x50\x90\xe4\x71\x8d\xea\xf4\xc8\xc3\xcb\xa5\xf5\x9f\x4a\x0f\x43\x55\xd7\x9b\xbc\x72\xf3\x4b\xe3\x6f\x49\xe2\x6d\x64\xbe\x30\xdb\xfb\x38\x69\x2a\x48\x5e\x1c\x44\x9c\xff\xe3\x3f\xb5\x87\x7d\x6f\x44\xf8\xdd\x0b\x66\x88\xeb\x58\x57\x81\x6f\xe3\xed\x68\xb2\x1b\xd8\x7d\x08\x07\x33\x65\x88\x13\x69\x17\x81\x48\x63\x32\x6e\x16\x41\x6a\xd0\x3f\xae\x11\xff\x0e\x20\x73\xe2\x18\x46\x07\x5d\xd0\x5f\x07\x90\xc7\x9d\xc0\xe6\x16\xd8\x9c\xd4\x01\x54\x59\xe1\xa1\xaa\xce\xd4\xf1\x7a\xb2\xaa\xa3\xda\x31\x84\xdb\xc3\x0a\xfb\x57\x37\x65\x30\x39\xff\x4b\x3b\x5c\x85\x0e\x5d\xc4\x42\xda\x44\xd9\x6a\xaf\x4a\xfe\x33\x27\xad\xc1\xe7\x6c\x85\xdd\x22\xd1\xb3\x62\x70\xc6\xab\xa9\xbe\xbd\xbd\x84\xbb\x4e\x0b\x83\xc2\x54\x05\x4d\xd1\x52\x55\x33\x7a\xdb\x14\x17\x39\x23\x65\xcd\x54\xfb\x8d\x4e\x6a\x2a\x6e\xf2\x8a\x4c\xd9\x5c\xe6\x75\xc7\x89\x85\x1a\x75\x92\x87\x7e\x39\x13\xd4\xd0\x5b\x6f\xfd\x61\xaa\xc7\x95\x80\x6d\x0c\x2c\x44\x98\x39\xda\x70\xee\xef\x3e\x61\x05\x75\x4f\xed\xa8\x9e\xa3\x3a\x71\x7a\x62\xc4\xbc\xab\x93\x0e\x70\x68\x6f\x51\x15\xde\x07\x5d\xed\x9a\x18\x4e\x81\xf1\x48\x91\xaa\x4a\x01\x1b\x5e\xf2\xd0\xe2\x8b\x11\x91\x2e\x7c\x81\x46\x4b\xf5\x99\xbe\x74\x11\x67\x41\x6f\x32\x71\x85\x16\x03\xa2\xd5\xc5\x0f\x80\x70\xb4\xf5\x91\x31\x94\xd4\xe5\xc1\xb6\xb3\x2c\x55\xa1\xd8\xa3\xd6\xde\xe4\xb4\x18\x98\x65\x0c\xa4\x41\xbf\x73\x54\x13\xf5\x62\x2e\xdd\xe5\x0e\x1a\x6e\x0a\x30\x45\xe1\xa4\xc6\xab\x6f\x9e\x26\x8f\x6c\x20\x78\x11\x39\xa8\xd7\x05\xda\x1d\xed\x91\x1d\x12\xab\xfb\x8b\xb8\x96\xe8\xae\x25\x5b\xb5\x76\xc8\x56\x52\xa7\x2c\xbe\xce\xfa\xe8\x2d\x4a\x14\x07\x44\x02\xb7\x71\xad\x7f\xc4\x2b\x6c\xb3\xbd\x35\xe1\x45\xd9\x7d\xe5\xf8\x77\x16\x7d\x1c\xdd\x5d\x56\xd8\x64\x21\x0f\xcc\x57\x8a\xc4\xf7\xbb\xa2\xfe\x92\xef\x4d\xf1\x27\x60\xf1\x51\x16\x0d\x3a\x66\x27\x7a\x24\xc4\x4c\xb4\x0c\x37\x75\x03\x1e\x83\xa1\xb1\x49\x11\x25\xa2\x9d\xc7\xb0\xfa\xa9\x85\xd7\xf4\x98\x79\x54\x6c\x4c\x46\xb2\x93\x70\x5f\x9c\x17\xa1\xef\x22\x20\x62\x43\x5b\x9f\xb8\x13\x22\x46\xb6\x58\x47\x5e\x87\xd6\xfb\xbf\x83\x3a\xf6\x78\x74\x82\x27\xf5\xf1\xf0\x24\x47\x55\x7b\x64\x6a\x24\xc1\xe4\xa6\xff\x5b\x43\xd1\x6b\xfc\xf5\x01\x5d\x16\xb1\x61\xfe\x5b\x81\x30\x44\x22\x78\xf0\xa8\x9e\xec\x3f\xc8\xeb\x28\x20\x01\x83\x58\x03\x18\x13\x55\xe3\xfe\xc3\x7a\xb2\x7f\x3f\xa9\xa1\x5b\xf9\x33\xf0\x8a\x08\x9e\x3b\x66\xda\xd4\x37\xaa\xd5\x11\x26\x15\xf2\x79\xa9\xc2\x6f\xea\xd5\x2a\x94\x12\x9c\x25\x03\xee\xf0\x1b\x11\x2d\xb6\x2e\xf4\x21\x49\xf8\x3a\x61\x19\xb9\x84\x83\xd3\xa2\x3e\xcf\x65\xa5\x37\x48\x6b\xdf\x9d\x5c\x00\xa8\xb6\xe4\x06\x62\x2d\x72\xd4\xc9\xef\xc3\x3d\xdf\x72\x14\x82\xf0\xd0\x35\x94\xa8\x2b\xf6\x4b\xae\xe5\x05\x46\xed\x04\x25\x58\xdd\x99\x87\x44\xa4\x3c\xee\x5b\x4e\xda\x8c\xef\x5b\xee\x6e\x83\x6b\xdc\x97\xec\x58\x97\xcb\x21\x28\x09\x12\xff\x4f\x87\x5b\x60\x23\xde\x71\x76\x63\x6c\x63\x57\x14\x49\x05\x7d\x28\x4b\xca\x51\x41\x2a\x10\x85\x8b\x98\x81\xe5\x44\x04\xec\xab\x66\x3e\x25\x71\x92\x3e\x13\xae\xa2\xc4\xb7\x2b\xeb\xab\xa3\x3d\xaa\x0a\x7a\x5b\xb3\xc2\xfa\x30\xe4\x82\x93\x85\x74\x51\x6f\xf2\x5f\xf5\x4f\xf3\x52\xff\x32\x47\xb5\xfe\xf1\xf2\x6a\xce\x6a\x48\x91\xf4\xa2\xa8\xa6\x33\x66\x8a\x5f\x15\x37\x62\xd1\x44\x35\x0f\xd9\x95\x30\x8f\x16\x1b\xec\xaf\x73\xf3\xa4\x71\x42\x3f\x3f\x65\x67\x8b\x0b\xf0\x94\x77\xd5\xac\xa0\xcd\x56\x38\x67\x75\xcd\xa6\x61\x1d\x08\xac\x09\x29\x16\xf3\x5f\xf9\x8a\x1c\xde\x3d\xb9\x79\x11\x4e\x4e\x84\x93\xe3\x45\xe7\xe4\x52\xe7\xab\xef\xa6\xd5\xf5\x1d\xb4\xba\x05\xb7\xd8\x71\xca\x1f\x91\xee\x58\x73\x60\x8d\x6b\x6a\x32\x18\xf0\xa2\x1b\x1d\xd4\x90\xdc\x49\xcb\x56\xe1\x32\xa5\xb3\xd6\x24\xa2\xab\x7d\x3d\x6d\xd4\xe0\xbc\x21\x75\x7a\xbb\x09\x38\xdc\x46\x73\xb8\xf5\xdf\xe4\x70\x59\x07\x83\xdb\x7c\x8d\xc1\xad\xdb\x0c\xae\xc5\xbe\x0e\xfd\x36\xf3\xd2\x7b\xb6\x22\x1d\xe7\xa3\x06\x91\x61\xae\x8b\x04\x63\x17\x45\x8c\xb1\x6f\x3a\x30\xb6\x6b\xcd\xe0\x2e\x41\x6a\x5a\x1d\x0f\x4f\xd4\x55\xea\x78\xe4\xc2\xbb\xf1\x02\xa5\x27\x42\xf5\x9d\x27\x02\x04\xd4\xe9\x3a\x0c\xaa\xd5\x0a\x13\x58\x79\x4c\xea\x55\xb2\x91\xda\x96\xf6\xac\xd0\x47\x0b\x6d\x8e\x87\x27\x1e\x05\x9a\xe3\xd1\x09\x39\x9e\x17\xe8\xb2\x85\xdd\xc7\x0d\x61\x27\x18\x72\x78\x90\x8b\xbb\x37\xe5\xf9\xfa\x4d\x59\x74\x6f\xca\x59\xd1\xda\x39\xb2\x70\x5b\x63\x5a\x84\xa8\xfc\xa3\xa3\x38\x55\xe1\xd7\xaf\x1d\x6c\xea\x47\x8e\x7e\xe6\x7a\x83\xfd\x1b\x96\x55\xb7\xd6\xbd\xae\xc5\xff\x9d\x75\x35\xc3\xec\x5e\xd7\xf3\xaf\xad\xeb\xcd\xff\xcb\x75\xfd\xe3\x1b\xd7\xf5\x8f\x7f\xeb\xba\xfe\xf1\xff\x1f\xeb\xfa\xc7\xbf\xb4\xae\xd7\x3a\x8f\x15\x39\x30\x7f\x4f\x8b\x48\x03\xf5\x29\xe2\xbd\xbf\x94\x68\x57\x9b\x77\xc0\x7f\x43\x3c\xae\x22\x43\x96\xfe\xd3\x67\xaf\x9e\xbd\x7f\xf6\x14\xf2\x36\xa5\x05\xa1\x47\x67\x68\x06\x1d\x7a\x7f\x38\x7f\xfb\xe0\xc2\x3e\x41\xe1\xaf\xd8\xf3\x84\x25\x9e\x27\x2c\xf2\x3c\x89\xdf\x06\x7e\x2f\x45\x9c\x94\x3b\x30\x24\xd8\xcd\xc3\xb0\xa1\xc9\xed\x01\x35\x14\x42\x1c\x39\xd5\xba\x4e\x26\x16\x64\xe3\x74\x6f\xdb\x99\x43\xcd\xd2\x83\x91\x57\x04\x8b\xde\xd0\x18\xbe\xec\xe5\xad\xee\xfa\x26\x83\xad\x3e\x40\x8d\x33\xe0\x76\x34\x86\xaf\xb7\x3b\xda\xce\xef\xc8\x9b\x7f\x54\x18\x5b\x84\xd3\xc2\x62\xd4\x41\x01\xe9\xb0\x9d\x86\x1a\xdc\xa0\x0c\xd0\x4c\x96\x93\x86\x1e\x54\x48\x0b\x5a\xde\x19\xeb\x11\xbc\x5c\xba\x4a\x2e\x28\x52\x10\x3d\x63\x34\xdc\xda\xcd\x42\x07\xb9\x2d\x8d\x6c\x70\x11\x45\xd7\x05\x65\x78\xfc\xa9\x40\xd7\x85\x0e\xe8\x48\x99\xc2\xc9\x83\x0a\x19\x6f\x22\xf0\xc5\x35\x52\xe9\x6f\x6c\xb7\xa0\x2c\x98\xe8\xfb\xc2\xaa\xe6\x7d\x58\x2d\x17\x39\x2c\xcb\x76\xb5\x87\x56\x71\x91\x65\xdb\xfe\x71\xe4\x9e\xc7\x38\xf8\x0c\x9a\x76\x2d\x7f\xb6\x20\x64\x3d\x4a\xaf\x0b\xaf\x3e\x55\xa0\x3a\xb5\xbf\xf5\x00\x60\x6c\x43\x62\x42\xec\x34\x16\xd1\xf8\x39\x72\x03\x58\x2e\xfb\x97\xac\xd0\xe9\x04\xb2\xac\x7f\x26\xa6\x37\xe6\xb9\x77\x51\x69\x63\xff\x50\x6d\x8f\x4d\x6c\x8a\x83\x62\xdc\x8c\xb1\xd9\xb0\xa4\xd1\xa0\x0b\x17\x48\x75\xa2\xc7\xa0\xd3\x6d\x68\xb4\x87\xe5\x74\x4a\x37\xd4\x76\x7f\x84\x30\xeb\xd6\xf2\x40\xa7\xca\x6b\x09\x91\xef\x63\x08\xd3\x62\x81\x1b\xf4\x4a\x1a\x3a\x1c\x33\xad\xcb\x07\x6b\x91\xc0\x2e\xc5\x6e\x35\xc8\x84\xce\xcf\x51\xff\x1f\x3f\x80\x11\x03\xb6\x77\xb0\x06\xdf\x6a\x1c\x60\xf1\x44\xac\x65\x55\x73\xef\x1e\x20\x44\xff\x87\xbe\x66\xcf\xfb\x3f\xf4\xdc\xd3\x04\x9e\x96\xcb\x66\x73\x73\x95\x0c\x6a\x65\xa8\x9d\x89\xe7\x75\x50\xd0\xeb\x62\x02\xdd\x78\xa3\xb0\xb0\x43\xed\x32\xd0\x56\x86\xbf\x2e\x10\x8c\xf0\x3a\x24\x9e\x3a\xd7\x6b\x91\x98\x00\x1c\x7d\xaa\x58\x4d\x9e\xc5\xd4\xf5\x5d\x20\xf1\x33\x36\x12\x4e\xfb\x3d\x79\x0f\xae\x60\x40\x6c\x49\x8d\xf3\x23\x0e\x4b\x0f\x95\xa0\x24\x30\x0c\x2a\x42\x8f\x82\x0a\x1c\x48\xd5\x49\xe7\xee\xdb\x35\x3b\x77\x71\x84\x55\x33\x42\x9d\x6a\x81\x26\x9f\xab\x12\xaf\x76\x7f\x56\x44\x5e\x64\x4b\x3a\x22\x66\xa4\x46\xdf\xae\x2d\x3d\xf2\x24\x74\x58\x1a\x6a\xcc\x35\x90\xd1\x7b\xbb\xa3\xfb\xad\x10\x2d\x0f\xa9\xe8\x88\x41\x47\x87\x98\xfc\x53\xf7\x26\x42\x19\xc6\xc7\xa2\x65\x78\xe0\x94\xb6\xe6\x4e\x5d\x85\x44\xbb\xcb\xd8\xba\x58\x2e\x8f\x4a\x54\xb8\x48\x26\x3d\x0a\x22\x51\x1f\x14\xd1\x89\x10\x2a\x70\xef\x2d\x6a\x16\x54\xad\xa2\xaa\x13\x84\x58\xe8\x31\xa6\xbd\x0e\x8c\xc1\x00\x58\xc7\x71\x63\xfb\x08\xf0\x27\x2c\x30\x88\x31\x4b\xcd\x00\x84\x10\x9b\x63\x97\x68\x7f\x22\x5a\x90\xbf\xf4\x44\x0b\x33\x51\x67\x93\x56\xd8\x80\xcb\x44\x3c\xe4\x59\x86\x04\x2d\x62\x42\x40\x90\xbb\xa9\x82\xbd\x90\x99\x01\x9e\x54\xf9\x6f\x35\x46\x82\xd4\x10\x2a\xb8\x06\x6f\x5b\x18\x14\x9e\x18\x48\x73\x9c\xa7\x2b\xae\xdd\x16\x0b\xe7\xf0\x76\xc7\x2c\x02\xeb\xac\x64\x91\xe2\x03\x8d\x41\xde\xae\x84\x7c\xb5\x47\x65\x42\x10\x8e\xd4\x3c\xf1\xa4\x6d\x4e\x91\x62\x0c\x71\x93\xc0\xf9\xd3\x22\x70\x53\x0b\x0c\xbb\x8a\x38\x3b\x9b\xda\x10\x0e\x7d\xbc\xeb\x91\x5b\x7e\x66\x86\x04\xfe\x48\xb1\xff\xe3\x92\x8e\xb6\x1e\x04\x4d\x3f\x2d\xda\x09\x56\xaf\x04\xaa\x92\x10\x04\xee\xa2\x47\xcf\x04\x6a\xc0\x7a\xd7\xec\xc4\xea\x6f\xed\xc4\xea\xff\xdd\x4e\x7c\x5c\x24\x0e\x4c\x30\x5d\x3b\xf7\xde\x70\x7c\x2d\x50\x63\x4e\x6a\xb0\x67\xe2\xe7\xc8\x4d\xd6\x19\x79\xb9\x90\x1d\x1e\xe4\x28\x90\xe9\x59\xd3\x9b\x56\x41\x00\x8c\x2d\x4c\x2e\xac\xbf\x2c\xb9\x36\x4f\x9a\xb8\xf5\x86\xe3\xd0\x3e\x2d\xa4\x12\x41\xdf\x44\xa6\x36\x70\xe3\xc2\x04\xad\x90\x63\x1b\xc3\xce\x44\x8e\x20\x33\xe3\x8f\xb9\x3e\x30\xc5\xcc\x61\xd2\x6c\x32\xa3\x82\xa3\x19\xce\x67\x7a\xbd\x67\x5d\x38\x61\x6d\xdd\xab\xb5\x91\x1f\xc8\xbc\x33\x1b\xe6\xa2\x3b\x22\x44\xb1\x2e\x22\xc4\x78\xde\x1d\x13\xa2\xf8\x86\x40\x22\xdd\xdf\xad\xfd\x60\xb9\x04\xcd\x6d\xbd\x5c\x96\x90\x5d\x34\xcb\x6e\xd4\xc2\x28\x6a\x36\xc3\xc4\x07\x17\x3c\x6f\x69\x8f\x0b\x13\x7e\xe1\x9c\xcc\x41\x30\x4f\x0a\xb5\x94\x65\x5a\x8f\x98\xe6\xd5\xde\x2c\x97\x4b\x1f\xad\x7c\xb9\xe4\x7c\xd2\x15\xfd\x6d\x63\xa1\xc3\x72\x28\xf4\x58\x28\x54\x69\xb5\x89\x09\x92\x94\xf3\xe5\xf2\x50\xd7\x92\xa4\x26\xe7\xe0\xc2\x83\x27\xe8\xbb\x60\x77\x47\x3c\x8d\xa2\x3b\x9e\x46\xf7\x42\x76\x35\xda\x55\xba\x26\x8a\xc6\x9d\x83\xbb\xe3\x25\xc2\xeb\xda\xeb\x8a\x76\xd1\xc4\xd1\x2e\x70\xfe\xb5\xc9\xac\xff\x96\x24\xfb\x90\xb6\x2c\x2b\x68\x89\x89\xdd\x9c\x35\xb1\xc8\x52\x12\xb7\x41\xe9\x8c\xd4\x54\xfe\x4b\x83\xa8\x69\x6f\x64\x08\x57\x42\x27\xb4\x4d\x55\x9b\x5e\xb8\x21\x35\xd6\xa7\x22\xf2\x46\x9f\xc8\xfc\x27\x61\x5d\x85\xa5\xc2\x3c\x4f\x4f\x5a\xf4\x03\x25\x14\x06\x7f\x2f\x39\x21\xa8\x93\x5c\xa0\xbb\x28\x0c\xfe\x4e\x52\x82\xff\x2f\x51\x92\x0e\xea\xe0\x11\x23\xa4\x22\x2d\x6a\x43\x82\xa6\xcf\xff\x1e\x15\x69\xb5\x89\x09\x5a\xa4\x54\xa4\x24\xe7\x7f\x83\x8a\x68\x50\x7f\x13\xc4\x6c\xc8\x9f\x6f\xa1\x23\xb6\xd9\xce\x62\x54\xc3\x50\xbf\x83\x9c\xf8\xe6\xd6\xbf\x35\xad\x7e\x0b\x55\xb1\xcd\xb5\x76\xe5\x77\xe1\x67\xfa\xfd\xd6\xee\x5e\x4c\x98\x3a\x21\xe9\xba\xd7\x59\xbc\x13\x16\x35\xcb\xca\xb6\x15\xf2\x72\x79\xc7\x40\x7b\x5f\x1f\xe8\xdf\xef\x49\x4d\xe9\x1b\xe8\xe5\x79\x17\xbd\x3c\x4f\xe8\xe5\xe2\xff\x8b\xb0\x01\x32\x6e\x19\xee\x37\x45\xc4\x5c\x07\x96\xfe\xc9\x5d\xc5\xdc\x11\x4c\xe8\xe3\x2e\xdf\x07\x9d\xe6\x24\xcb\x7a\x4e\xa4\x23\xb2\xec\x00\x42\x59\x90\xde\x08\xfb\x7b\xc8\xb8\x8e\x4e\x8f\x57\x85\xcf\x6b\x64\x0c\xe1\x8a\xee\xcd\xdd\x49\xa7\x41\xcc\x62\x2c\x7f\xcc\xcd\x3e\xd0\xcd\xc5\xb7\x03\xcf\x4c\xc3\xcd\x41\xdf\xd0\x62\xd1\x81\x62\xa3\xb9\xbb\x3b\xe8\x97\x50\x28\xe1\x06\x65\xee\x17\x52\xd7\x49\x95\x7c\x3a\x76\x56\x30\xed\xa1\x6b\xc9\x43\xf6\xb7\x22\xcc\x1a\xeb\x03\xc2\x39\x05\xbe\xd1\x13\x4c\x2e\x04\x1a\x92\xb4\xb4\x55\xa0\x9d\x4b\x4c\x1e\x9e\xdc\x3d\x66\x99\xf9\xdc\x1e\xa8\x6a\x09\xb4\x8f\x54\xec\xec\xa7\x3d\x76\xfe\x2c\xc8\xdb\x82\xbc\x2c\xc8\x8b\x82\xde\x26\x02\x2d\x52\xb3\xa6\xbe\xd1\x21\xe0\x03\x67\x9e\xe7\xb1\xd9\x04\x11\xd4\xde\xec\xbd\x0d\x83\xe1\x02\xe8\x53\x67\xda\x4f\xa4\xb9\xf3\xa0\xba\x13\x8b\xf0\x72\x69\xdf\x6c\x65\x05\xf6\x76\x05\xcc\x5f\x3f\xd3\xd0\xab\xa4\x9e\x20\x49\x7b\xc3\xe4\x2e\xb7\xb7\xeb\xcc\x95\xbc\x77\x6d\x6b\x87\x38\xf5\x03\x1f\x9c\x1b\x7d\xcd\x72\xd9\xd3\x05\x2e\xcf\x4b\xa1\x6a\xbd\xbf\xe4\xf2\xb9\xab\x82\x8a\x25\x1d\x81\x9f\xd4\x53\x4e\x46\x59\xe1\x2f\xa6\x70\xeb\x73\x72\x11\xdf\x6c\x96\x1d\x15\x48\xb1\x49\x50\x41\x06\x6f\x08\xe2\x10\x15\x06\x2c\x9a\xc8\x30\x89\x53\xd2\x40\xc0\x58\xb4\x95\x69\xf8\x6a\x89\x66\x10\x40\x32\x76\xff\xb0\x0e\x46\xf0\x7f\x6e\x7e\x59\x5f\x4c\xef\x71\xc5\xc6\xd8\x49\x2b\x38\x38\xa0\xc5\x01\x9b\x50\xa5\x46\x24\x89\x68\x85\x4d\x69\x08\xf7\xf1\x99\x5a\x9b\xe0\x45\xe1\xf6\x0e\x27\x2e\x1f\x9d\xa0\xde\x19\x74\x9d\x1f\x8c\xfe\xc8\xcb\xf5\x20\x75\x91\xb7\xde\x4b\x57\x5d\xc1\x50\x04\x89\xb6\xb0\x1d\x94\x81\x2f\x8f\xe0\x5b\xe9\x28\x53\xb1\xb2\x60\x3d\x88\xc1\xc3\xfd\x7b\x00\x8c\x61\x84\xfa\x51\x2d\x8f\x89\x1a\x44\xa5\x85\xb7\x1c\x63\x69\x7b\xab\xc0\x9a\x37\x81\xb7\x50\x23\x14\xa1\x77\x69\x43\x2a\x07\x68\x41\xba\xb3\x60\x0c\xef\x5a\x80\x8a\x08\xe7\xc6\x15\x93\xb9\x60\x35\xaa\x36\x21\x8b\x16\xa4\x5a\xf1\x73\x0f\xe5\xbf\x81\xbc\x0e\xf5\x48\x24\xcb\xb0\xb8\x87\xff\x2f\x63\x77\x15\x9d\x9e\xb6\x9f\xef\x59\x83\x60\x13\xdc\x09\x66\xbd\x3c\xf1\xc2\x04\x79\x87\x8c\x84\xae\x25\x9a\xea\xca\x53\x42\xcd\x31\xbd\x2e\xa9\x42\xd5\xd5\x48\x5a\x48\x1b\x4c\x2a\xee\xd6\x29\x32\x24\xfd\x35\xe1\x0d\x34\x4f\x90\x6c\x50\xeb\x16\x50\xa4\x8e\x4a\xf4\x96\xcb\xc7\x45\xf9\xf1\x53\x51\x4f\x25\x64\x11\x51\x67\xb6\xb3\x80\x71\x3f\xdf\x35\x45\xdd\x98\xc4\x23\xb3\x42\x36\x79\x4d\x9a\x82\xcf\xf2\x0a\xfe\xf8\x35\xc8\x87\x50\x00\x19\x69\x05\x09\xec\xa9\xf9\x2a\x47\xc5\x20\xe8\x8c\x36\xa4\x18\xb8\xf6\x35\xfc\x83\x02\xd7\x21\x1d\x92\x02\x94\xa3\xc0\x1a\xaa\xc6\x69\x65\x1e\x7c\xb7\x50\xc9\x76\x4c\x85\xf9\xc2\xa8\x53\x43\xe9\xea\xef\x89\x79\x61\x72\x38\x0a\x08\xd5\xe8\x5c\x4b\x09\x07\xef\x73\x0e\xa1\x66\xac\x5e\x21\xda\xad\xe6\x6c\x44\x75\x70\xaa\x62\x8c\x6b\x3a\xca\xea\xe5\x56\x2c\x03\xdc\xdb\x89\x7c\xb8\xf4\xe6\xb3\xc7\x2e\x0b\x8f\x5d\x96\xeb\x7d\x67\x9d\x51\xfd\x46\x72\x8e\xb9\x5a\x25\xd6\x4d\x8e\xb3\x0c\x50\xb4\xc2\xe3\xc8\xa7\x56\x7f\x92\xbe\x72\x4d\x18\x9f\x58\x16\xfb\xc4\x32\xe2\xc8\x4d\xe4\x13\x0b\xf2\x03\x97\x00\x20\xf4\x8a\x65\x9d\x5e\xb1\xcc\x79\xc5\x32\xef\x15\xeb\x1b\x08\xd2\x07\xb1\xd4\x23\xd6\xa1\x7d\x40\x3a\x56\x75\x46\x47\x6a\x1c\xfa\xc8\xaf\x5b\x84\xab\x6b\x7f\xeb\x39\x1b\x55\xba\x30\xd9\x8c\xcf\x45\x0d\xf8\xd8\x07\x98\x57\x16\xe6\x44\x44\x41\x94\x2a\x17\x74\x11\xa2\x9e\x86\xa9\x3e\xcc\x04\xc1\x9d\x1a\x74\x1d\x15\x26\x15\x75\xa7\xc5\xd8\xfb\x06\x08\x3c\x41\xc2\x75\x10\x6a\xd1\x20\xda\xb5\xfb\x24\x38\x6a\xe0\x25\xf9\xb5\x40\x8a\x67\x04\x0a\xc9\x23\x17\x01\x1c\xe5\x52\xb6\x7b\xcb\xce\x45\x1f\x03\x9d\x3d\xda\x89\x89\x71\x12\xd2\x55\xac\x9d\x9c\x57\xfc\x09\x1b\x24\x87\x0a\x37\x66\x11\x52\x6a\xc8\x18\xc0\x56\x7a\xdc\x43\x43\xd7\xef\x1a\x7a\x23\x2e\x58\x73\xc9\xea\x7e\x6e\xe7\xea\x6d\x37\x8c\x3f\x42\xd7\xb7\xce\xcd\xbf\x63\xb5\x3d\xa5\x4f\x78\xfe\x7f\x3a\x1a\x10\x9c\x81\x4d\x9c\x6e\x29\xc9\x4b\x35\xb6\xd4\xa2\xed\x68\x37\xd4\xb6\xda\x45\x89\x6a\x77\xbf\x48\x92\x67\xc5\xc9\xaa\xa3\xed\x6f\x3e\x08\x36\x60\x1a\x38\x69\xdb\xc7\x58\x0a\x5d\xd7\xf5\x02\x2b\x3e\xca\x2d\x6f\xc2\x4f\x05\x9c\x87\xb3\x61\x71\x91\x51\x83\x4d\x1a\xec\x2a\x50\xcb\xb9\x75\xbc\x9b\x49\x1b\xc7\x48\xba\x16\xda\x3f\xb5\x2d\x58\x34\x99\x36\xfb\xef\x92\x4f\xa7\xac\xea\xe7\x60\x5f\xa0\x48\xad\x77\x05\x0f\xf1\x34\x8c\x7a\x1a\x86\xfb\xac\x68\x12\xe2\xb4\xb2\xa9\x90\x98\x39\x2c\xd4\x65\x34\x1e\x6b\x9c\x7e\x7a\xa6\xf3\xc8\xf7\xf3\x2a\x1d\x41\xbd\x86\x04\x54\xd1\x08\xea\x35\x1b\xbe\x9e\x34\x81\x5b\xb8\x6a\x38\x1a\x92\x7e\x8e\xc6\x95\xd7\x31\x48\x03\x7f\xe4\x3b\x8f\xad\xb1\x8b\x03\xe9\xad\x83\xb6\x4c\x0c\x8d\x3d\xf3\x77\xd7\x86\x1d\xb1\xa1\x35\x4c\xf4\x20\xf8\xf3\xc0\x94\x9a\x8f\x6c\xfc\x8d\x9d\xd0\xca\xc7\x18\xe8\xd8\xa2\x2b\x2b\x2b\xc6\x59\x76\x28\x90\xbe\x70\xd9\x54\x34\xa6\xce\x47\x8e\x70\x92\x17\x15\x08\x6c\x10\x03\x3f\xbe\x3e\xeb\x5c\x75\x36\x8b\x5b\x7a\xd9\x4e\x0b\x0c\x71\x8c\x6f\x95\x7e\x27\x2d\x97\xbd\xcf\x05\x84\xa1\x6c\x49\x78\xfc\x58\x77\xf3\x0f\x1c\x41\x04\x8e\x8e\x38\x1d\xdc\x88\xca\xe3\x2d\xab\x9f\xc2\x59\xbc\x35\xc2\x14\x52\xeb\x14\x23\x5a\x1b\x6b\x15\xc4\x2d\x85\xac\x4f\xbb\x57\xc7\x71\x23\x7c\x8b\x69\x7a\xda\x3d\xef\x38\x5f\x19\x8f\x61\x96\x06\x11\x81\xc9\xe2\xdb\x58\x9e\xe3\xa6\xa0\x65\x39\xa9\x0a\xd1\x06\x58\x3c\xfe\x52\x9d\xd0\x86\xd4\xc7\x47\xd5\x09\x95\x8a\x8d\x84\xcd\xc1\xcf\xeb\xe2\xca\xe6\x44\x37\x3a\x00\xfd\x83\x5d\x9d\xa9\x2d\xf3\x7b\x83\xfa\x33\x51\x4c\xfb\x2e\x6a\x90\xde\x55\xd7\x7c\xca\x84\xa9\x5a\x2c\xa6\x5c\xf4\x0d\x47\x33\x1c\xb3\x87\x3f\xb0\x30\xe1\xe5\xef\x0d\xfa\x81\x1d\xb3\x93\xa4\x05\x29\x16\x75\xc9\x74\x0f\x4c\xc1\x21\xed\x82\x5f\xd9\x2c\xfb\xfc\xaa\xb8\x70\x99\xe0\x79\xf5\x31\xf9\x88\xac\x1b\xe4\xb9\xa8\xaf\x74\xdd\x9a\x49\xd6\xb8\xba\x72\x71\x76\xc5\x9b\xb4\xf6\x94\xa9\xfd\x2a\xf5\x07\x8d\xb8\xb8\x98\xb1\xd6\x90\xaa\xf9\xa2\xe9\xe7\x9f\x18\xaa\x89\xd4\x6d\xf1\xea\xba\x98\x71\xe8\x9a\x94\x15\xaa\x48\x5f\x54\x3a\xe1\x79\x3f\x9e\x2e\xe4\x3b\xef\xe7\xf5\xe0\xf4\x53\x5d\xcc\xe7\xd6\x7b\xe2\xf6\x53\x21\x0f\x17\xb3\x86\xcf\x67\x2c\xef\xf5\xe4\xe0\xca\xfc\x58\x7d\x57\xf3\x2e\xb6\x77\xfe\xee\x1b\x07\xb7\xb2\x44\xb0\xdc\xe0\xd5\x86\xa8\x10\x57\x5f\x99\x7b\x92\xc4\xea\xda\x39\xb8\x2c\xe4\xd1\xa7\x4a\x61\x12\xab\x9b\x1b\x54\x62\x1b\x68\x4d\x1e\x97\x27\xe3\xbe\xe5\x93\xfb\xe0\x8f\xdc\x8e\x05\x35\x9b\xd4\x03\x35\x30\xd8\xce\x90\x46\x7b\x06\x6e\xa9\xc7\xfe\x4b\x32\x3b\xc1\x79\x3b\x60\xd4\x2c\xcb\xd2\x4f\xfb\xfd\xcd\xf6\xd7\xaa\xf0\x04\xe7\x5f\xda\x23\xb5\xdb\x78\x96\x65\x30\xf3\x12\xaf\x6c\x8c\x36\x8b\xfb\x7a\x31\xaf\x99\x3a\xd7\xdf\x03\xd4\xc0\x4e\xb1\x13\xaa\xba\xd6\x47\xf5\x7f\xd7\xaa\xea\xfd\x33\x07\x09\x6a\x1e\x73\x2e\x5d\x1a\x03\x39\x10\xd5\x93\x19\x87\x24\x59\xf5\x40\x54\xa5\x7a\xa6\xb3\x0a\xaf\x20\x4e\x6e\x1c\xe3\x23\xc8\x00\x9a\xd2\x39\x9d\x35\xcd\xcc\xab\xa4\xfb\x10\x75\xc7\x1b\x63\xe6\xd5\x00\xa2\xc5\x3f\x35\xd1\x95\xc0\x37\x49\x56\x00\xc5\xa7\x10\xf9\xca\x94\x4c\xfa\xb2\xac\xf9\x1c\xf4\x7f\x1c\x8c\x89\xca\x81\xf6\xb6\x35\x01\x99\x50\x7f\xca\xaf\xfb\x10\x34\xbc\x62\xf5\x8b\xf7\x87\xaf\x68\xff\xa1\xfe\xe6\xd1\xc3\xff\xf9\x87\x79\xea\x13\xcd\xe5\x5f\x89\x6b\x06\x26\x92\x88\x85\xf6\x92\x38\xef\x88\x2e\x3b\xe0\x72\xd2\xee\x8e\x93\x5b\x2e\x73\xf5\x72\x85\xf3\x8e\xe1\x70\x4c\x2c\xec\x29\xf8\x58\xa1\x92\x32\x52\xbb\xcd\x33\x29\xdd\x23\xed\x0d\xe1\xd8\xfd\x02\xd1\x93\xe0\x81\xea\xdf\x18\xe3\xbc\xd5\xf4\xeb\x77\x3a\xe6\x17\x33\x14\x93\x01\xc5\xac\xc9\x9f\xd6\x96\x31\xb0\x6b\x65\xa4\xa4\x85\xda\x38\x35\xfe\x3b\x14\x95\x61\x08\x06\xf8\x75\xaa\x3a\xa3\xc3\xf1\x2c\xa0\xaa\x33\x47\x55\x67\x27\x84\xe1\x71\xd2\x4a\x07\x65\x6d\x77\xf5\x8d\xd4\x95\x85\xd4\xb5\xdd\x4a\x8b\xc2\xb2\x98\xc2\xb6\xbf\xe8\xa4\xb2\x1d\xc3\x73\x94\x16\x62\xbd\xcd\xe8\xa9\x79\x8a\xc8\x1a\xbb\x9b\x28\xda\x0d\x39\xa3\xaf\x59\x10\xf7\x2e\xde\xba\xec\x6e\x82\x5c\x07\x04\xd9\x64\xc1\xab\xc9\x2d\x84\xc9\xb4\x9e\xb5\xdf\x37\xa8\x88\x52\x9b\xc9\x3d\xfb\xbe\xc9\x59\xd2\x32\xa3\xf5\x0a\x08\xf7\xcc\x5a\xef\x68\xd6\x56\x2a\x8a\xbe\x50\x24\x7c\x91\x12\x46\x89\x6d\xcc\x90\xc5\xb1\x3c\x19\xf7\x65\x73\x33\x63\x6a\x0f\xc9\x49\x55\x21\x46\xe6\x38\xef\x4f\x55\x67\xb5\x58\xc8\xd9\xcd\x3b\xd6\xbc\xb4\x3b\xde\xd4\x02\x62\x84\xe6\x74\x3e\x99\x0f\x4e\x4f\x2f\x9b\xab\x99\x81\x03\xce\xb2\xdf\x98\x69\x22\x3c\x19\x64\xc7\xc9\x30\x9f\xc4\xe9\x28\xf8\x72\xd9\x57\x7f\xe7\x38\xcb\xfe\xb4\x8d\xb4\x4e\x85\xb9\x79\xd9\xef\x6f\xaa\xf7\x72\x31\x9f\xd7\x4c\x4a\x73\x46\x3c\x9b\x72\x50\x1f\x7c\x28\xea\xca\xe4\xd3\x90\x59\xe6\x6a\xbd\x00\x25\x0b\x17\x55\xf2\xbe\x58\x34\xe2\xb9\x28\x17\xd2\x14\xa0\xd6\x61\x22\xb1\x99\xf5\xdc\x9c\x25\xd2\x6a\x3a\xe6\x59\xf6\x33\x62\x44\x92\x39\x29\xf1\x1d\x07\x0c\x83\x03\x86\x91\x9a\xf4\x46\xeb\x0f\x18\x06\x07\x0c\xeb\x44\x61\xdd\x5f\xad\xe3\xb3\x66\x19\xe4\x80\x38\x68\x9a\x9a\x9f\x2d\x1a\x86\xfa\x50\x0c\xc7\xe1\x05\x43\xa6\x16\x5e\x83\xee\x9e\x30\x06\xc8\x6d\x0e\x19\x54\xd9\x3e\xf0\xe4\x95\x1a\x71\x5c\x47\x0d\xdf\x0d\xc5\x60\xe1\xaf\x7a\x44\xed\xda\x71\x8d\xe0\x68\xbd\xeb\x64\x9c\x05\x27\x23\x8b\x4e\xc6\x43\x4d\x68\x3b\x0e\xc1\x2a\x4a\xf4\xd2\x61\x1f\xd9\xba\xe4\xec\xe5\x3a\x5b\x79\x9b\xd3\x7f\x59\xa0\x21\x69\x99\xb5\x2b\xd2\x61\x79\xfa\x76\xba\x96\x3a\x48\x54\x71\x37\x87\x9f\x5e\x42\x48\x17\x87\x3f\x89\xaf\x50\xa4\x6e\xd9\xf9\x54\xe6\x6c\xd2\x67\x3d\x80\x57\xcb\x28\x3a\xac\xa0\x50\x45\xd1\xd7\xf8\x02\x6c\x8e\xc0\xf7\xec\x33\xc4\x4d\x44\x35\xc6\xa6\x8b\xf0\xb8\xab\x3a\x20\x39\x72\x77\xc1\x52\xa0\xa7\xe0\xa1\x94\x5a\xb7\x74\xe9\x1d\x3b\x2c\x69\x2b\x48\xc7\xe0\xac\x86\x6b\xd0\x9c\xfb\x6c\x3a\x6b\x03\x05\x7a\x7d\x1f\x40\x2f\x0f\x92\xc7\xf1\x76\xfa\xa4\xca\xdd\xd8\xbd\x8b\x36\xd4\xd3\x32\x51\x1b\x7d\x34\xc8\xef\xab\xee\x54\x81\x23\x0f\x0c\x3d\x74\xec\xe1\xc6\x2b\xdc\xfc\x94\x60\x00\xbb\x36\xe7\x4c\x52\x5b\x5f\x70\x79\xe8\x76\x84\x31\xa9\xb2\xac\x57\x1b\xc9\x71\xa8\x24\xf3\x46\xc2\xbd\x2e\x48\xdc\xa5\x3f\x85\xb6\x46\x59\x20\xc3\x9e\x7c\x96\x94\xd2\x6b\x45\xf1\x3e\x4b\x7a\xa0\xc6\xfd\x59\xf6\x74\x09\x3c\x1c\xc8\xe5\x52\xbd\x3a\x95\x5a\x0a\xfe\x44\xba\x0b\xf8\x17\xf5\xd5\xc7\x12\x7d\x91\xe4\xbd\xc4\xe4\x2f\x78\x7a\x22\x31\xc6\x98\xa0\x6a\xb9\xec\xda\xa6\x26\x04\x3e\x60\xcd\x4e\x24\x40\x08\xb0\x69\x68\x5f\x34\xfa\xd2\xee\xdf\xdc\xff\x06\xb9\xc4\x68\x5f\xed\x6b\x83\x88\x56\x2a\xdb\x42\x48\x9c\x0a\xeb\x78\xa7\x6a\x3c\xc8\x56\x5b\x7b\xad\x85\xf6\x39\xe2\xf8\xa7\x02\x69\x62\x6e\xa5\xec\x06\x76\xa1\xd5\x76\xa7\xe4\x1f\xce\xe7\x54\xee\x2f\x53\x19\xed\x63\xae\x4e\x6a\x2d\x04\x4c\x54\x0c\xc4\x76\x4d\x42\xf4\x4d\x32\x50\xc7\x57\x08\x4e\xba\xd6\x02\x22\xef\x7a\xd4\x84\xaf\x42\xbc\xd5\xb8\x19\x61\x6f\x58\x1f\x76\x7a\x34\x8b\x7a\x8c\x25\xad\x08\xe2\xb4\xc6\xa1\x69\xc0\x56\x1b\xe7\x09\x6f\x75\x45\x78\xe4\x21\x67\x85\xc3\x14\xe0\xc1\xa3\x1c\x43\xeb\x14\x83\xad\x30\x0a\xd2\xe9\x2a\x4d\x0f\xb1\x9d\x52\x52\x18\xe8\x09\x79\x3b\xcc\x22\x8f\xe5\xc7\x46\xa8\xdf\x3d\x14\xd6\x55\xda\x1e\x5e\xcb\x79\xc0\x69\x56\x9d\xa6\x35\x1e\x70\x7a\x2c\xa5\x63\x4f\x73\x06\xf2\x3b\x2c\xf1\x53\x11\x78\xd7\x04\x1d\xc7\x97\xa7\x01\x39\x64\x3a\x74\x7d\xcf\x33\x3e\xb7\x72\x10\xfe\x24\x2e\x70\xa9\xcc\xe5\xc0\xff\x58\x75\xe6\xc9\xb2\x26\x1e\x9e\x54\x2d\xb7\xbc\x5d\x4f\xa0\xca\xd7\x0e\x53\x20\x66\xe3\xb8\x73\xf7\xe8\x70\x9b\xd1\xe6\x81\x18\x1c\x95\x73\x4c\xf9\xca\xc6\xa9\x5a\x1b\x47\x6f\xbe\x61\xb0\x83\xd4\x75\x26\xcb\xac\x94\xdb\x15\x1d\x8a\xa9\xa2\xd3\x32\x40\xdc\x96\x47\xe5\xda\xbd\xa5\x47\xd2\x3a\x27\x2a\x17\x73\x72\xeb\xbf\xff\x14\x08\xdf\xab\x3b\xd4\xa9\x8f\xea\x44\x75\x9a\x65\xa3\x87\x2d\xd9\x81\x05\x85\x23\x26\xad\xf3\xb8\x53\xd3\x41\xab\x7b\x23\x3c\xae\x43\x35\xef\x04\xb9\x15\x69\xe9\xa1\xd4\xa1\xe2\x81\xad\x67\x88\x27\x5e\x56\x2f\x73\x57\x93\xe8\xb7\x54\x46\x4c\x46\xcf\x82\x73\x02\x3e\x78\xed\xa9\xa1\xb4\x88\x2a\xc0\x6c\xee\x0e\xd5\x12\x99\xfa\xa4\x0e\xd5\xd0\xa4\x36\x32\x7a\xa7\x13\x09\x21\x1f\xad\x09\xe9\x82\x2f\x74\x90\x28\xf0\x48\x13\xda\x5c\x69\x0c\xe6\x93\x51\xd6\x2c\xb7\xf2\x51\xa6\x0e\x32\x93\xc0\x27\xd5\xfd\xec\x11\x2d\xd2\x0f\x14\xd8\x3f\x83\xc1\x5a\x67\x5c\xf1\x2b\x81\x58\x78\xf4\x39\xb7\x4d\xb7\xb0\x76\x13\xed\x0c\xf7\xf7\x32\xf0\x56\x4e\x53\xc6\x37\xcb\xbd\x1d\xc2\xc2\xc4\x43\xdb\xea\xd0\xec\x90\xe4\xdb\xe3\x0b\x45\x3d\xb4\x32\x7f\x6c\x3d\xd8\x0d\x82\xbe\xae\xe9\xcf\xca\xe2\x4d\x35\x88\x6d\x4d\xee\xe0\x22\x61\xfc\x49\xc7\xdf\x36\x9b\xd1\x7e\xd2\x94\x7f\xf5\x4d\x5c\x87\x1d\x57\xec\xa5\xbc\x91\xa8\x6b\x7e\x8c\x82\x5a\x19\x71\x00\x23\x5a\xf2\x92\x37\x44\x36\x45\xf9\x31\x3f\x64\xa8\xc1\xab\xd5\x9f\x05\x8d\x5d\xfa\xbd\x02\x2c\x39\x41\x2b\xcd\x07\xec\x52\x93\x21\x73\xb9\xdc\xb3\x8f\x98\x0d\x8a\xb9\x22\xcf\x5a\xb0\x16\xb8\xb0\x7b\x1e\x64\xc7\x66\xd6\xf4\x5e\x64\x56\x9b\x58\xc5\x4a\xff\x0a\xf4\x59\x6d\xa5\x7f\xa0\xb3\x8f\x54\xfe\x55\xa7\xca\xbf\x72\x2a\xff\x2a\x54\xf9\x5b\x77\x66\xf7\x7e\x55\xa5\x1a\x7f\xfb\x26\x54\xab\xad\x56\xe4\x6d\x0c\x29\x9b\xe1\x2d\xb5\x78\xd1\xaa\x0d\x7e\x8e\x0a\x9d\x45\x0a\x54\x1f\xa4\x24\xb3\xf0\xde\x64\x55\x1f\xc9\x15\xcb\x9c\xe6\x55\x7c\x47\x2f\xe8\x29\x43\x33\x52\xa8\x13\x09\x9e\x6a\x55\xf3\xf8\xa4\xeb\x2a\x5e\xd0\xd7\xae\xee\xeb\x35\x75\xed\x6d\xbb\xd0\x12\xa3\xa2\x25\x31\xaa\xd7\x89\x92\xd2\x96\xbc\x84\xa0\xa0\xcf\x5c\xbf\xcf\xda\xfd\xb6\x6f\xd5\xa1\x71\xb3\xbb\x55\x77\x5d\xba\xeb\xe0\xd2\x3d\x8b\x2e\xdd\x4e\x9a\x24\x74\x02\x4c\x62\x4c\x0e\x0a\x08\xd4\x5d\xb7\x25\x25\x59\x56\x74\x15\x6a\x74\x2c\x8e\xe5\x09\xd6\x57\x68\x2b\x75\x02\x7e\x18\x34\x10\x33\xfd\x7a\xd6\x25\xca\x57\x77\x0a\x54\xe9\xf4\xaa\xc7\xe5\x09\xed\xf7\x35\xd2\xaf\x15\x55\x19\xd9\x8e\x13\x43\x25\xb2\xa0\xff\x05\x89\x11\x5b\x2e\x91\x5a\x1d\x10\x5f\x33\x48\xc9\x31\x98\x2f\xe4\x25\x92\xc6\x04\xce\x4b\xea\x6a\x9b\x9c\xa9\x3e\x96\x27\x0a\xad\x67\xe6\x06\x5b\x4c\x14\x48\x0c\x6e\x90\x4e\x68\x2f\x8c\x52\x45\x7f\xb0\xb0\xd7\x8f\x19\x4e\xe1\xac\x9a\xd5\x94\x47\x43\x1b\xf7\x3a\x20\xbd\x5c\x2e\xb2\xac\x25\x33\x54\xe5\x5d\x2b\xe0\x1a\x5b\xe0\x8e\x6f\xb2\x6c\x76\x5c\x9e\xf4\x28\x5d\x1c\x97\x27\xed\x25\x54\xa5\x36\xae\xaf\x02\x95\x05\x17\x61\x0e\x4c\xea\x26\x4c\x17\x77\x2f\x34\x70\xa8\x68\x41\x17\x93\x45\x2c\x8d\x24\x33\x3a\x9b\xcc\x92\x32\x03\x25\x1d\x4b\x77\xa1\x43\xa4\x46\x4b\xb3\xc0\x2d\xe1\x25\xa4\xe6\x5a\x2e\xdb\x62\x9f\x45\x96\x59\x11\x65\x2f\xf4\x86\x6c\x35\xda\xef\x6f\x2e\xfe\x5d\xe2\xca\x4e\x5c\x43\x6e\x5e\xa5\x55\xe3\x2d\x97\x66\xdc\x1a\xaa\x1d\x58\xb8\xc0\x78\x55\xb5\x40\x60\x50\x86\x54\x98\x70\xca\x48\x7a\x91\xec\x12\xbf\xad\xc8\xcb\x36\xd9\xc6\xb7\x55\xb7\x48\x4a\x07\xde\xfb\xa3\xe8\xf4\x25\xfd\xc0\x8a\x8f\xef\x58\x33\x31\x7f\xf3\x77\xac\xf1\x16\xf0\x4c\xc6\x7e\xd3\xfa\xb0\x25\x46\x1d\x5e\x7e\x74\x66\x19\xfe\xf4\x03\xe3\x8d\x43\x48\x95\x18\x68\xd1\xae\x98\x71\x94\xd7\x76\x25\x3a\xe5\x95\xbf\xb6\x8f\xa8\x8b\xb8\x71\xc5\x90\x4b\xd9\x51\xdf\xdc\x96\xa2\x92\x62\xc6\x06\xa0\x1b\x51\x47\xbb\x8e\x74\x27\xf0\xad\x64\xc0\x1b\x8a\x45\x13\x85\xe2\xd1\x9c\x92\x58\x61\x1c\xf0\x0e\x8d\x0c\x3d\x12\x6a\x76\x1e\x85\x83\x8f\x52\xb3\x85\x39\x45\xd5\x00\x6c\x60\x50\xdd\x6f\x85\x6f\x2f\x4a\x9d\xdb\x11\xf6\x51\x12\xf9\xd3\x87\x95\x95\x91\x81\x4e\x68\x44\x92\x58\x8b\x58\x23\x92\xad\x2d\xc3\xf7\x58\x9b\x10\x7e\x8e\xb6\x76\xf7\x42\xf9\x88\x37\xc6\xf0\xb1\x33\x12\x99\x69\xcb\x46\xb5\xd1\xb1\x86\x03\xeb\x90\x35\x3e\x37\x28\x4d\xa3\xab\x25\x3e\x93\x2a\xf0\x60\xac\x30\x1c\x80\x83\xd3\xd3\x9a\x15\x65\xf3\xb2\x82\x6b\xd6\xac\xab\x39\xda\xac\xc2\xe9\x6c\xe7\x86\x1b\x35\xb2\x60\xc3\x1c\xc6\x72\xa6\x94\x55\xdf\xdb\x0e\x99\xf4\x5a\x46\xa9\x2e\xf4\x75\x2e\xbc\xd8\x45\x91\x87\xc3\x3b\x85\x09\x5a\x62\xb1\x98\x36\x3e\x06\xf5\x39\x42\x9a\x7b\x63\xd8\xfb\x88\x43\xc8\x6b\x1d\x28\x77\xec\x9e\x68\x14\xc1\x57\x6f\xb4\x1a\xe1\x55\x65\xc2\x0e\xdb\xd8\xe1\x80\x51\x01\xea\x89\xff\xd5\x61\x6b\xa1\x72\x30\xea\x6f\x19\x22\x97\xd6\x10\xca\x65\x5e\xfd\x76\x74\xd5\xc1\x82\x85\x44\xdb\xa4\xc2\x01\xee\xb2\x30\xa1\x3c\xd9\xc9\x02\x43\x73\x1c\x66\x2b\x61\x6d\xcf\x5c\x64\x24\xff\x76\x52\x9d\xe9\x9d\x13\x49\xac\xc2\xd2\xca\xa6\xe4\x8d\xe3\xe3\x8c\x59\x87\x33\x5b\x3b\x74\xfb\xb7\xe1\xb5\xbb\x2a\x43\xd4\xa2\x60\x45\x13\xa9\xc6\x39\x47\x15\x44\xdb\xc2\xc1\x8d\x6f\x5d\x75\x93\x0b\xca\x09\xe0\x82\x5b\x84\x5b\x11\x7d\x97\x08\x23\x55\x31\x5b\x29\x60\xc0\x3d\x17\xbb\x31\xea\xaa\xb0\x72\xe3\x8a\xb6\xe7\xae\x4f\xfd\x1a\xae\x9a\x9b\x23\x85\xf0\x43\xd1\x22\x66\xd9\x61\xe5\xd3\x65\xc7\x10\xcf\x32\x36\x38\x57\xdc\x1a\xc2\x2e\xb6\x55\xb4\xe3\x13\x5a\xb7\x9d\xa7\x40\x85\x75\x4e\xec\xaf\xc1\x8e\xd2\x07\x7d\x0d\x0e\x9c\x2a\xad\x9c\xbe\xf4\xfe\x5e\xc1\x9b\xa7\x8d\x3a\xa4\xb0\x1d\xe2\x68\xdf\x91\x23\x8d\xe1\x06\xf3\xb7\x46\xdf\x44\x9e\x8a\x74\x13\x75\x1d\x29\xa7\x65\x96\x9d\x96\x08\x6c\x1a\xd6\x6f\xb1\x9d\xd6\x56\x8b\x44\x6d\x4d\x82\x6a\x55\x10\xba\x29\x90\x67\x59\xa2\xa0\x43\x19\x8d\x75\xf4\xe1\x6a\xb2\x7f\x3f\xaf\x5a\xd1\x87\x19\xad\x6d\xe6\x0b\x08\xc8\x64\x88\x5f\xe8\xe5\x55\xd9\xa0\xe4\x3a\x7a\x5d\x85\xec\x91\xc8\xe1\x48\x14\x84\xe3\x95\x8b\xb3\x64\x28\x0d\xa8\xc8\xb0\x3a\x8a\x23\xbc\x6c\xa4\x82\x40\x97\xa7\x7a\x62\xc8\x18\x3b\x14\x57\x57\xda\x6d\x3f\xbe\xd8\xc3\x19\x6d\xfc\x5c\xd3\xe3\xd0\x34\xd6\x92\xd1\x36\x9d\x2d\xa3\x8e\x43\x7e\x05\x79\xca\xc3\x6d\xb5\xab\x87\x1f\x16\xed\xe4\x0b\xbb\xf8\x01\x55\x95\x11\xcf\x11\x24\xb8\x71\x17\x72\x9d\x27\x31\x10\x96\xa7\x7e\x24\xa6\xb0\x25\x17\x67\x6d\xb1\x31\x69\xc5\x4e\x61\x6d\x71\x3f\x6b\x89\xfb\x63\x4b\xe4\x74\x14\x51\x61\xa0\x94\x0c\xe8\x54\x93\x65\x52\xc1\x23\x08\xc2\x2e\x83\x40\xab\xbb\xd4\x05\x35\xdb\xf6\x8f\x3b\xf6\x31\x88\x90\x0e\x5f\x99\x18\x62\x9e\x51\x0b\x83\xb4\x99\x14\x6a\xa5\x44\x8d\x3f\x15\x7d\x2c\xb0\x20\xfd\x57\xb2\x4f\x87\xde\x4e\xa0\x89\xe8\x5b\xd5\x8a\xfc\x57\xd3\xde\x28\x5c\xda\x6d\x4b\xb7\x1a\x9a\x78\x95\xea\x20\x33\x89\xc5\x7c\xd2\xf1\x08\xe3\xd5\x68\x2f\xa6\x9a\xe8\x4f\x86\x1a\xd2\xef\xe3\xd0\xf5\x2a\xa3\xf7\x46\xf7\xf1\x98\xe5\x8d\x71\x32\x60\xe3\xb1\x49\x5d\xfb\x8d\xd2\xa0\x52\x22\xfb\x03\x43\x0c\x30\x67\x92\xbd\xc1\x56\x81\x58\x48\xbb\xee\x7d\x83\x68\x68\xbc\xeb\x25\x5b\x7b\xfe\x71\xf4\xc0\x3e\xeb\x81\x6c\x45\x07\xbb\x95\x6b\x6d\x34\x61\xce\x11\x6b\x3a\xbc\xe3\x04\x6b\x41\xbd\xf5\x52\xb2\x15\x84\xa6\x8b\x3b\xd0\xe1\xcd\x92\xf3\x6e\x83\xad\x56\xf5\xc4\x5f\x5a\x50\x94\x44\x01\x28\x2d\xe1\x54\xa1\xa2\xd0\xd2\x3d\x01\x2a\x48\xdc\x50\x3e\x09\xe8\x4d\xde\x84\x39\x41\x2b\xd9\x14\x55\xc9\x48\x35\x79\x00\x52\x70\xa7\xca\xaf\x83\x6c\x87\xaa\x1a\xab\x0d\x83\x00\xa4\x22\xaf\x3b\xca\x50\xd2\x04\x08\xe6\x7d\x2b\x38\xfd\x04\x32\x6e\xd2\x1a\x47\xe2\xc7\xc6\x6b\x1f\x6b\x5a\x0f\x34\xab\xf2\x56\x08\x50\xf9\x00\x5a\xe2\x20\x3e\x75\x1d\x84\x32\x33\xd2\xa5\xe5\x12\x55\xa1\xa4\x29\x16\x62\x0a\x7f\x90\xb8\x84\x7d\xc6\x55\xd1\x86\x58\x4a\x3d\x02\xf4\x9e\xec\x7a\xbd\x52\xd4\x93\x34\x38\xff\x8f\x2d\x4a\x17\x98\xeb\x04\x5e\xff\xf9\xf9\x05\x19\x18\xdc\xf1\xef\x1c\x1d\x88\x20\x9c\x1a\x77\x70\xbd\x59\x7a\x12\xdf\x4a\xca\x2d\x5d\xd3\x1e\x69\xe3\x68\x47\xcb\x96\x11\xcb\x10\x63\x67\x52\x4e\x65\x18\x94\x26\xa2\x5e\xc2\x51\xae\x0d\x96\xd0\x2e\x85\x2e\x31\xed\x12\x8e\x76\x6d\x30\xd0\xef\x19\xea\x20\x69\x6f\xb8\x32\xd2\x70\xee\xa5\xe1\x5c\xf7\xa4\xc7\xab\xe3\x62\x31\x32\xa3\x9c\x2c\x68\x45\xe6\x74\x36\x1e\x2b\x96\xbe\x90\xa8\x24\x73\xb2\x70\x78\x3a\xd7\x50\xce\xb2\x1d\xf8\xa1\xda\x98\xc7\xbb\x7d\x4e\xe6\xb6\x96\x33\xf6\x99\x43\x6e\xdf\x2e\x27\xb8\x79\x27\x0d\x9c\x3b\x1a\x38\xf7\x12\x71\xdf\xc0\xdc\x55\x58\xcd\x53\xba\x67\xdf\xc0\x28\xec\xd2\x8a\x09\x2a\x69\xad\xa6\x17\xc0\x5a\x6d\xe0\xd2\x6f\xe0\x32\xa4\x01\xa1\xf1\xed\x0c\xe7\x65\x52\x80\x21\x6a\x83\x2f\x09\x9a\xc5\x2e\x89\xe6\x8e\x87\x72\x90\x15\xcd\x6a\x12\xea\x70\x2c\x1d\x4b\x69\x95\xd8\xde\x21\x98\xdb\x8f\xbd\xaa\xc1\xf5\x05\x9c\x2a\x57\x97\xf9\xb4\x9f\x6f\x69\x06\x8c\x37\xba\x35\x16\xbc\x73\x7d\xb8\x5b\x1f\xde\xa1\xb1\x50\x13\x07\x4f\x76\x73\x76\xe9\x53\x06\x49\x88\xc4\xc4\xd3\x05\xb3\xd5\x60\x60\x4e\x87\xe1\xf3\x9e\x7c\xbb\xd4\xa5\xcd\x63\x87\xd7\xd9\x5a\x5d\x67\x1b\x1c\xbb\xe7\x8c\xa3\x08\xc1\xa1\xda\xc3\x2d\x59\xe0\x4b\x14\x73\xa2\xa2\x2b\xab\xa1\xbe\xb8\xd6\x63\x16\xfa\x93\xf0\x98\xbf\x87\x48\xbc\x6d\x0e\xb0\x72\x79\xf3\xe0\x40\x37\x06\xd3\x46\xb5\xa2\xed\x95\xfa\x75\x31\xe5\xc2\x68\xc7\x6f\xe6\xce\xf4\xae\x86\xfc\xbc\x59\xf6\x85\x69\xf5\x42\xa1\x18\x69\xa1\xc8\x5b\x61\xb2\x3c\x0b\x3a\x1c\x8b\x87\xdc\x9a\x3e\x8b\x4d\xba\x65\x53\xf2\xf1\x63\x71\x42\x4a\xf5\x67\x73\xd4\x32\x65\xad\x48\xf9\x35\x53\xd6\xdf\x98\xa9\x15\x0b\x7c\xff\x34\xc5\x3f\xa3\x8a\x48\x52\x2a\xca\x6a\xb5\xb1\xb1\xd2\xe8\x48\x0f\xba\x5b\x5b\xf3\xa4\xfd\xd2\x2a\x85\x14\xdf\x17\xd9\x1c\x0f\x02\x93\x63\x72\xc7\xbb\x4e\x8b\x4d\x16\x59\x6c\x56\xb1\x0d\x26\x03\x8b\xcd\xa6\x47\xa3\x4f\x9d\xbe\x20\x36\xd1\xec\xf8\xbe\x6d\xc3\x99\x77\x55\x72\x66\xf7\xc7\x27\x79\xbf\xaf\xfa\xc4\xab\x55\x74\xa9\xdf\xcb\xbf\xcd\x0f\x6a\xcb\xeb\x92\xe1\xfe\x1d\x9e\xb8\xce\xd8\x31\xc5\x68\x9c\xb8\xa5\xc1\x97\x70\xb2\x06\xf7\x37\x73\xe9\x06\x89\xb4\x79\xa6\xbd\x11\x79\xda\xa0\x34\x44\x8b\xbb\x84\xb7\x24\x03\xa0\x21\x6d\x7c\xe0\xc8\x38\x5a\x82\xe2\xd7\x73\x54\x83\x85\x89\x33\x85\xf8\x4b\x82\xc1\x80\x97\x3f\x3b\xdf\xef\x6a\xec\xb5\xbd\x5a\xcf\xcf\xc3\x08\x35\xa4\x9e\x74\xdd\x4a\x81\xd8\x28\x4c\xc7\x03\xc9\x1a\xab\x05\x98\xf0\xf0\x17\xea\x9b\xec\xe2\x7d\xd2\xaf\x44\xc5\xfa\xa4\xcf\xaf\xe6\xa2\x6e\x8a\xaa\xe9\xe3\x9c\xdb\xe4\xe3\x54\xbf\xcd\x51\xdc\xb1\xf0\x29\x36\x90\x48\xef\xb1\xa6\x73\xc7\xc0\x88\x2c\x13\xa9\x4a\xc2\x75\x8f\x27\xc2\xf6\x95\x1b\x23\x2a\xf8\xdc\x0d\xa0\xa9\x82\xb1\x8a\x80\x0b\xdc\x73\x40\x61\x9d\x18\x50\x4f\xfa\x60\xcb\x1c\x69\x84\xed\xa9\xed\xfd\xe7\x03\x97\xc1\x44\x80\x53\x75\x06\xa8\x09\xf3\x5a\xdf\x76\xd8\x85\x86\x4e\xf3\x3c\xd6\x9c\xff\x0d\x2f\x7b\xeb\x66\x5f\x75\x9c\x5f\xdf\xe1\x64\x5f\xfd\x0b\x4e\xf6\xc1\x39\x73\x0e\xa2\x84\xc4\x88\xa2\xf5\xe6\xdb\xe4\xe3\xe7\x91\xbc\x21\x39\x42\x9c\xae\xe3\xb6\x2d\x4e\x70\xa1\x34\xfc\x81\x66\x6f\x6e\x20\x3e\x8b\xae\xfe\xec\xd3\xc6\x1f\x05\x26\xcd\xe0\x5c\xd4\xcf\x8a\xf2\x32\xd0\xbd\x34\xf6\xf0\xbb\x2e\x83\x8c\x03\x10\x53\xab\x52\xe8\xaa\xdd\x46\xab\x41\x31\x9d\x1a\x09\xd8\x25\xab\x50\x4d\x6a\x0c\x22\x22\x88\xd2\x34\x95\x6b\x95\x54\x87\xc5\x7c\x62\xfe\xe6\x87\xc5\xdc\x2b\xa9\x2e\x1d\xeb\x8d\x2a\x5a\x72\xe4\x02\x9e\x34\xc5\x05\xdd\x26\xd5\x60\x5e\xdc\xcc\x44\x31\xa5\xb7\x46\x90\x1c\x64\xa3\xaa\xad\x32\xca\x79\x82\x0e\x4a\x63\xc0\x4b\x03\x19\xd9\x53\xb9\x5c\xa2\xa7\x10\x81\xe9\xb1\xa4\x35\x26\x46\x31\xb6\x22\x41\x5a\x81\xb3\x3b\xc7\x31\xb6\xd2\x38\x35\xa5\xb5\x61\xbe\xc6\x6b\x74\x51\xc1\xc5\x49\x0f\xd7\xcf\xaa\x9d\x06\xc3\x0c\x8e\xd4\x48\x18\xb0\x46\xc4\x26\xc9\x6a\xc0\xbb\x0d\x14\x78\x24\x34\x7f\x52\x34\xe5\xa5\xf6\x24\xee\x00\x4f\x97\xfd\x43\xed\x8d\xa7\xdf\xc8\xc9\x1b\x09\xa8\xf3\x8e\x35\xe8\xb8\xb9\xe4\xf2\x04\xe7\x6f\xa4\xc6\x84\x4b\x2e\x1d\x3c\x6d\x58\x17\xab\x5e\x54\x2f\xdb\xe3\x40\x56\x81\x78\xeb\x5e\xbd\x03\xe3\x1f\x4b\xef\x27\x55\xde\xef\xaf\xf0\x0a\x93\x4a\xa7\xc1\x92\xe4\x50\xd2\xc3\xa2\xb9\x1c\x94\x8c\xcf\xc8\x85\x5c\x9f\xbc\xfd\x26\x7d\xa7\x23\xb7\x5f\x4b\x3a\x24\x07\x92\x6e\x93\x53\x49\x77\xc8\x27\xf5\xf3\x8b\x91\x8d\x1d\x99\xbf\xef\x55\xe1\x67\x49\xaf\x25\x79\x6d\x8a\x5e\x49\x1a\xa4\xc7\x7d\x16\xfd\x7a\x67\xea\x3c\x51\x9f\x7d\x54\x1c\xaf\x3a\xb9\x86\xe4\x83\x29\x7f\x0a\x45\x8f\xcd\xaf\x37\xe6\xef\x6f\x50\xfa\xa7\xf9\xf5\x56\xd2\xfd\x21\x79\x69\x7e\xbd\x50\x9f\x3f\x37\x3f\x7e\x91\x74\x18\xa4\x92\x97\x1e\x3f\xe0\x94\xd9\x79\x90\x7d\x92\x78\xe2\xc6\x33\xba\x87\xd4\xa1\xf9\x8f\xd1\x70\x39\xc4\xb9\xaa\xf2\x8b\x9c\xfc\x22\xf3\x5f\x82\x31\x47\x75\x82\xf8\x2f\x0e\xf1\x4d\xdc\x7e\xb4\x95\x01\x2b\xa0\xa3\x86\x58\x23\x4c\x3f\xf5\x71\x90\x37\xcf\x7e\xb2\x93\xf9\xbc\x11\xfb\xfb\xe0\xea\xef\x3f\xf0\x39\x86\xb7\x6c\x78\x08\x34\xda\x53\x13\x70\xc9\x15\x64\x40\xe6\x2a\xcc\xe8\x3f\x05\x62\x64\xb8\xac\x06\x8d\x56\x12\x1f\xca\xe5\x72\x97\x6d\x93\xad\xdd\x21\x8e\x62\x96\xd4\xe6\x86\xb0\xbf\x9f\xb3\x60\x79\x42\x29\xe0\xfe\x83\xdc\x34\x38\xda\x1d\x92\xd1\x30\xf2\x58\xdd\xd8\x37\x0a\x83\xfd\x3d\x5b\xcb\xf5\x13\xd6\xda\xcd\x19\xdd\xba\x53\x60\xb8\xbd\xb5\x87\x53\x53\xcc\x2f\x32\xcb\xd4\x79\xf5\x5e\x66\xd9\xbd\x7b\x2c\x4c\xd1\xf8\x4f\xaf\x59\xdc\x1d\x3e\x7c\x61\x25\x07\x11\x12\xb8\xb3\x02\x2c\x06\x23\x35\xc2\x4f\x66\xcb\x59\x51\x2a\xac\x86\x9f\x3f\xa4\xab\x01\x40\x03\xa2\x64\x99\x5e\x25\x8d\x35\x7f\xa8\xb3\x26\x47\x3f\xab\x3f\x10\x24\xe6\x93\xcc\xb2\x5f\x15\xcf\x95\xfb\x32\xb4\xa3\xea\x2e\x97\xfb\x0f\xb4\xbe\x65\x7f\x5f\xc7\x58\xb7\x64\xe1\xa5\x9c\xbc\xd4\x64\xe1\xb0\x98\xa3\x63\xc8\x78\x73\x82\x73\xe4\xe2\xd5\xa1\x8a\xbe\x94\x8a\x54\x22\x86\xf1\x72\x59\x3d\x6a\x70\x96\xbd\x94\x8a\xed\xd2\x43\x0f\xae\x7e\x66\x36\xff\xbb\xf1\xa3\x1c\x4d\x37\xc7\xbc\x09\x6f\xe3\x79\x87\x3a\xcb\x7c\x5c\x21\x11\x11\x61\x40\x41\xc7\x7d\x68\x53\x7e\xe0\x3a\x68\x1d\x28\xb9\xea\xce\xd8\x27\x0d\x18\xe1\x76\xd9\x0a\x37\xa1\xd1\x45\x67\x40\x35\x33\x97\x3b\x3e\x86\x1b\xa3\x9e\x91\x1e\x7e\xad\xef\xd1\xc2\xc6\x7f\xf4\x92\xd7\x55\xed\xaa\x26\x78\x2b\xb2\x0c\x7d\x91\x54\x3f\x14\xa0\xf2\x02\xe7\x97\x53\x99\x65\x1f\x4b\x24\xc8\x7b\x89\xc1\x8b\x45\xa8\x85\x24\x22\x08\xcb\x11\xf1\x31\xa0\xb0\x50\xc3\x64\xd3\x30\x38\x8c\x95\x1f\x68\x41\x73\xef\x49\xa9\x56\x9f\x1a\x95\xc7\x1b\xad\xd2\x80\xa4\x8c\xbe\x9e\x5d\x70\xd5\xe2\x1b\x5e\x5d\x98\x06\xcd\xfb\xad\x47\x10\x84\xe8\x91\xcb\x5f\xf2\x53\x25\x3e\x55\xa6\xa5\x57\xec\x9a\xcd\xf0\xa4\xca\x15\x13\xde\xc0\x2d\x7e\x98\x07\x3b\x11\x70\xfe\xd6\x0c\xad\x35\x66\xcc\xdc\xa1\x99\x00\x3c\x38\x0c\x7c\x9d\x37\x35\x17\x35\x6f\x6e\xe8\xfe\x7e\x50\x0a\xdc\xd7\x2f\x02\xfd\x21\x43\xde\x0a\x07\x9a\xf2\x86\x02\xe4\x88\x9a\x63\xf8\xd5\xd8\x25\x53\x09\x94\xa2\x49\xc3\x56\x15\xd5\x3d\xcc\x61\xe7\xe8\x86\x91\x96\x5e\x9d\x2f\xaa\xa7\x84\x80\xd4\x74\x7f\x3f\x1f\xa9\xc7\xe5\x72\xcb\x96\xec\xe6\x35\x1d\x3e\xa2\xa8\xa6\xa3\xe1\x7f\xa3\xe0\x74\x69\xf0\xbd\xa4\xa4\xc6\x78\xb2\xbf\x9f\x6f\xed\x0e\x1f\x51\xc8\xad\xba\x6b\x1f\xef\xe7\xfb\xbb\xfe\x82\x67\xb8\xa3\xf6\x38\xd5\x98\xd6\x4e\x0c\xd4\x57\xe2\x11\xad\x9d\xfd\x6c\x8f\xd2\x8f\x22\xcb\xbe\x08\x54\xe1\xd5\xda\xef\x9a\x2e\x80\xd4\xa4\xa1\xc9\xec\x3b\xd6\x2b\x7f\x2e\x50\x4d\x7e\x8c\x4b\xc9\xad\x39\xa4\xf2\x36\x40\xd4\x81\xbb\xc2\x29\x26\x34\xab\xd0\x32\xda\x1f\x04\xea\xd0\x27\x6e\x73\x7c\xd0\xdb\x42\xad\x0d\x26\x9a\x30\x07\x0c\x3f\xa0\x8b\xdd\x50\xfa\xf0\x6e\x12\xdc\x21\x01\xab\x90\x26\xfd\xd9\xba\xaf\x4f\x94\xb3\x12\xe9\x98\x06\xea\xa8\xaa\xe0\xa8\x5a\x2e\x2b\xad\x3f\xb5\x0b\x74\x24\xed\xdd\xe0\x93\x1c\x7f\x92\x4b\x3a\xda\x73\x01\x81\x04\x15\x25\xc2\xe3\x31\x58\x5b\x95\xea\x51\x93\x16\x97\xd2\xb4\x56\x6d\x95\x10\x29\x93\x71\x84\x15\xef\x55\x93\x0b\xe9\x2c\xaf\x04\x51\x08\xf6\xd9\x9e\x7f\x0d\x7d\x2d\x89\xed\xff\xa3\xf9\xab\x27\x1f\x6a\xa5\x8e\xa4\xb5\xad\x10\x40\x37\x2a\x2e\x2f\xd9\xf4\x83\xa8\x3f\x2a\x18\xe8\xa6\xc3\x14\xb3\xae\x4a\xea\x9d\x41\x6a\xfa\x59\x3a\x5e\xd0\x72\x13\xd7\x32\xb7\xda\xee\x18\x6c\x3b\xbb\x56\xd6\xb1\x95\xc3\xfa\x6c\x3d\xac\x26\x5b\x79\xac\x64\x3e\x90\xe0\x20\x60\x81\xa8\x7d\xea\x34\x61\x79\x07\x69\xe2\xa6\x86\xb4\xc0\x56\xee\x24\x57\x74\x5e\x22\x81\x31\x89\x50\xf2\x95\xcc\xb2\xd1\xf0\x21\x12\xf4\x2f\xb9\xb9\x3b\x1c\x02\x76\x69\xf3\x93\x8f\xd2\x66\xf0\x68\x91\x48\x43\x40\xf8\x72\xc9\x1f\x29\x44\x49\x2b\xd0\xca\xc2\xdb\x2c\xdd\xca\xf2\x68\x5c\x23\x19\xce\x32\xde\xf3\x77\x6e\x1f\xe0\xab\xd6\x98\xd7\x6a\xb0\xb6\xb1\xd0\x2c\xf7\xa6\x93\x06\xd2\x9b\x0a\x9d\x97\xf1\xd6\x11\xb6\xd3\xf3\x32\xf6\xe3\xde\x38\xfd\xf7\x01\xf1\xa3\xcc\x32\xcd\xa6\x8a\x16\x78\xf0\x72\x29\x14\x58\xbe\x01\x2e\x16\x2c\xc2\x81\x45\xfc\x2d\xb0\x44\x74\xb6\x47\xe9\x33\x39\x69\xd1\xd2\x67\x52\xd3\x8e\x3c\x41\x80\x49\x4d\x87\x79\x9b\xf4\xbe\x92\xf8\x9e\x62\x5b\x87\x8f\x50\xad\x06\x08\x88\x71\x0f\x9c\x4a\x6b\x3a\x84\x18\x53\xc9\x17\x15\xbe\x27\xf0\x43\x55\x7b\xb4\x35\x7c\x54\x4f\x46\x5b\xc3\x7c\xe7\x81\x7a\xda\x79\x30\xcc\x47\x43\x78\x54\x7f\xf2\xd1\xbe\xae\xb0\xbf\x35\xcc\xb7\xd9\xf6\xa3\x7a\xb2\xcd\xb6\xf3\x9d\x6d\x28\x55\x7f\xf2\xd1\xfe\xde\xf0\xbf\x0f\x25\xaa\xff\xa1\x9e\x7c\xc7\x15\x20\xf0\xc3\x5a\xc1\xe2\xab\x98\x50\xaf\xc5\x84\xdd\x3c\x85\xd8\x2b\xef\x58\xfb\x4e\xe2\x5b\x4e\x5f\x49\x13\xcd\xe9\x1d\x5c\x24\xf4\xf1\x34\x5c\xca\xc1\xd9\x42\xde\x1c\xf2\xea\xe9\x42\xef\xf9\x43\x89\x35\x04\x85\x7b\xfb\x94\xcd\x8a\x9b\x43\x49\x6a\x85\xef\xe0\x23\x86\x12\x50\x71\x7c\x0f\xa9\xda\xf1\x55\x04\x63\xfc\x90\x8a\xc9\x30\x17\x9b\xf5\x3d\x6e\x27\x6a\xf1\xf5\x7b\x26\x1c\xcd\x78\xdd\xdd\x62\x1f\x03\x09\xd5\x94\x30\x39\x4e\x02\x86\x2a\x39\x9a\x56\x21\x5f\xe7\x8f\x9c\x3f\xbe\xc6\xa4\x35\x54\x27\xce\x6f\x02\xfc\xfb\xee\xd3\xa4\x09\x4f\x93\xa6\x75\x9a\x54\x1d\xa7\x49\x1d\x9e\x26\x32\x3d\x4d\x84\x39\x4d\x44\x74\x9a\x54\xe1\x69\x52\xc7\xa7\x49\xe5\x4e\x93\xc6\x9c\x26\x8d\x3b\x4a\x83\xfb\xd4\x51\xaa\xb7\xdd\xda\x1b\x29\xe6\xec\x5f\x38\x58\x1a\x77\xa6\xc0\xea\xea\x4e\xbb\x57\x83\x95\xa1\x99\xb6\x05\x0a\xd8\x69\x59\x91\x10\x98\xe8\x98\x64\xa3\x40\xc8\xd4\xbc\xb1\xbe\xb4\x85\x86\xd2\xed\x96\x32\x7a\x6f\x8b\xa8\x06\x1f\xfc\x9d\x06\x0d\xe8\x6e\x13\x48\x38\x0b\xa5\xce\xa9\x0f\x1d\xb3\x1e\xed\x01\x05\xef\x7b\x23\xc7\xc1\xc6\xfb\xe3\xde\x88\x5c\x57\xa1\xd5\xf9\x91\x76\x74\xa9\xe8\x91\x4c\x0c\x89\xaa\xb1\x33\x98\x75\x9a\xf5\xc8\xe9\x2f\xb4\xb3\x00\x71\x1d\xdc\x96\x9e\xf8\xd4\x2c\x32\x32\xb5\x30\x9e\x81\x91\xd9\x50\xdb\xb9\x2f\x26\x48\x1f\x78\x1c\xd6\x6a\x63\x07\x3e\x89\x0c\x38\x8d\x02\x7f\xb4\x9f\x6b\xbf\xba\xe8\xe5\x30\x6f\x54\x13\xa1\x6d\xcf\x17\x49\x19\x39\x92\x10\x63\xd2\x79\x46\x82\x0c\x92\xbc\x97\xb4\x49\x44\x53\xcf\x24\x7d\xf5\x15\x79\x54\x60\x7c\x5d\x7a\x37\xba\xf1\x58\x5b\xdd\xd9\x1d\xf4\x9b\x73\xf5\xa2\x57\x05\xf9\x85\x63\xef\x6b\xf7\x92\x77\x84\x4c\x8e\x57\x40\x27\x09\x77\x97\x60\xb8\xd9\xda\x3c\xff\x7a\xec\xce\x7c\x99\x9f\xa3\xb7\x9c\x0e\xc9\x73\x4e\x5f\x70\xfa\x92\x1b\x39\x17\x0f\x82\x56\x1c\x49\x17\x6c\xc2\x2d\xbb\xa5\x6c\x9f\x25\x1d\xa9\xd9\x37\x56\x60\x37\x66\xb9\xbd\x37\x10\xee\xeb\x93\x82\x1e\x49\x22\x75\xde\xd3\x86\xbe\x97\xa4\x88\x82\x64\x0f\x77\x1e\x90\x22\x32\xae\x2b\x3a\xdd\xe8\x8d\x77\x49\x2b\x4d\x98\xec\x16\xb8\x4a\x90\x87\x6b\xb8\x94\x54\x8e\xbd\x2c\xad\x30\x82\x34\x13\x08\xae\x08\x64\x16\xb3\x09\x2a\x22\x81\xfe\x2c\x72\x38\x2f\x12\x83\xc2\x59\x2b\x5b\x4e\x22\xd3\x98\x25\x05\x38\x4f\xda\xaf\x74\x48\xe9\xb6\x9d\xa2\xce\xb2\xb0\xa0\xed\xa8\x17\x64\x4e\xb9\xb5\x2e\x05\xc7\x8b\x73\x0a\xda\x22\x6d\x11\x02\xc5\x53\x3a\x4f\x10\xc5\x93\xd6\x29\x3e\xb7\xca\xf3\x69\xa0\x2b\xf2\x97\xcf\xcb\xe0\x63\xad\x94\x3a\xf7\xda\xb4\xcb\x20\x58\x09\xea\xe9\x92\xbb\x82\x76\xf4\x16\x18\xd8\xd7\x73\x3d\xb0\x33\x3a\xef\x52\xa5\x50\x4a\xcf\x74\x85\x2b\x2b\xd7\x1e\x5f\x81\x38\xbb\xc4\x24\xfa\x82\x5e\x69\xbb\x8b\x33\xf3\x36\x58\xd6\xb9\x5d\x56\x7e\x8e\xe6\x89\xa3\x78\x11\xd9\x06\x6e\xed\x3f\x18\xc1\xb1\x54\x68\x9d\xa5\x1b\x44\x80\x0a\xb8\xd0\x99\x24\xef\x7b\xc0\x1c\xd2\x92\x07\x6c\x8f\x89\x06\x72\x08\xf5\xb6\xc8\x8c\xa3\x82\x1c\xe2\x55\x0b\x07\x52\x19\x28\x98\x08\x19\xef\x87\xc2\x64\x30\xb9\xa0\x62\x30\xe7\xd5\xc5\x93\xa2\xbc\x0c\xa1\x72\x31\x41\xd1\x2b\x80\xce\x54\xed\x26\x03\x26\x72\x01\xe2\xbb\x92\x48\x8c\x73\x2f\xe9\x93\xf4\x02\x04\x7d\x25\x36\x99\x09\xda\xb5\x49\x0f\x82\x23\xa2\x02\xe3\x5b\xad\x3a\x28\xb4\x00\xee\x86\xde\x84\x8c\x91\x20\x25\x29\xf0\xb8\xd4\xea\xa5\x1b\x72\x83\x57\x11\x74\x77\x86\xfb\x7b\x64\xde\x12\xe6\xb9\xb9\x06\x06\x43\xc6\x5f\xc2\x58\x33\xe1\xb1\xa4\xfa\x78\x47\x57\x0c\x15\xda\x49\x69\xb9\xec\x1f\x6c\x80\xba\x60\xc3\x29\x23\xfa\x78\xb3\xbf\x21\xed\x15\x63\x03\x5a\xd9\x70\x5e\xed\x64\xe3\x6c\xd1\x6c\x54\x62\xc3\x22\xe6\xc6\x2f\x2f\x37\x3e\x15\x72\x43\xce\x59\xc9\xcf\x39\x9b\x0e\xfe\xa7\xfa\x9f\xea\x60\x3a\xdd\x28\x36\x1e\xbe\x33\x59\xc1\x5d\x6d\x3a\x18\x0c\x1e\xf9\xbe\x36\x2e\xf9\xc5\x25\xab\x37\x78\xb5\xd1\x5c\xb2\x8d\xa6\x66\x6c\xa3\x11\x1b\xf3\x5a\x5c\xf3\x29\xdb\x28\x36\x66\xa2\x50\xb4\x74\x83\x57\x53\x5e\x16\x8d\xa8\x37\x44\xbd\x31\x9f\x15\x25\xbb\x14\xb3\x29\xab\x55\x6d\xa3\x0e\x1e\xf4\x37\x0f\x99\x82\xef\x6a\xb7\xa7\x58\x20\x1d\xa6\x66\x0b\x13\x49\x7f\x2c\x90\x24\x85\xdb\xca\xe6\xd4\x9c\x07\xa7\xe6\x76\x5e\x52\x49\xbe\x05\xd2\x64\xc1\xd1\x9c\x5c\x4a\x34\x07\x4b\x0f\x1c\x5b\xad\x8d\x54\x3b\xb0\xae\xd7\x8a\x42\xdc\xcc\x19\x39\xa0\xf3\xd8\xd8\x06\x50\x66\x6f\x27\x0b\x7a\x53\x68\xd3\x45\x55\xaf\xd7\xaa\xda\x9c\x81\xe4\x41\x37\x3d\x3e\xe8\x56\x80\x59\x95\xd6\x72\xd9\x7b\xa3\x11\xf2\x00\xab\x2b\xf4\xb7\xcf\xfc\xac\x35\xf3\xd5\x1d\x48\xb7\x3a\x92\x74\x51\xa2\x23\x69\xad\xd3\x4f\xf1\x6d\x43\x4f\xbd\x46\xdb\x5e\x01\x9c\xc3\x51\xe9\x8c\xfa\x3d\x5b\x6b\xc5\x9c\x01\xa3\x7b\x55\xf8\x48\x4f\x57\x45\x28\xce\xe4\x96\x67\x7b\xa8\xae\x49\x5b\x0f\x59\x96\xa1\x57\x92\x32\x1c\x18\x7d\xb3\x87\xcf\xdc\xbb\x67\x8a\xef\x78\x27\x69\x68\x0f\x59\x94\x60\xcf\xfd\xe8\x89\xc2\xa2\x27\x32\xca\x12\xab\xd8\xf2\xdb\x50\xf4\x7d\x24\xc7\xf8\x48\xd2\x99\x9e\xa6\xb7\x24\x6f\xd7\xcb\xb2\xde\x5f\x8a\xd7\xea\xaa\x3e\x2b\xfd\x9d\xe4\x4a\x86\xc9\x44\x09\x23\xef\x65\x10\x30\x21\x8d\xf0\x12\xa5\x2b\xa8\x9c\xbf\x0b\x6a\x14\xe4\x19\xc6\xe4\x46\x46\x7e\x7e\xa4\x09\x0c\x3f\xa1\xd7\x23\x49\x99\x3d\xe3\x1a\xc5\x4a\xf8\x23\x1a\x0c\x0e\x3c\x73\xa1\x89\xff\x70\xe7\x41\x76\x24\x23\xc3\x66\x60\x36\x7e\x28\x90\x62\x4f\x20\xc4\xd3\xc8\xdc\x7e\x46\x30\xf3\x2e\x89\x7d\x18\xd6\x60\x48\x6a\x57\x2b\x54\x29\x68\x06\xa7\x6e\x85\xbd\xa1\x9d\x0a\x84\xb1\x78\xa4\x95\xfe\x02\x13\x6e\x1e\x79\x14\x33\x66\xd5\x3d\x14\x9d\x45\xc5\x99\x19\x38\xa9\x7b\xe5\x43\x33\xb9\x89\xb3\x78\xdb\x3a\x3b\x8b\x80\xa5\x02\x06\x3f\x64\xb1\x8e\x64\x14\x11\xcc\x33\xf9\x71\x38\x25\x67\x12\x12\x95\x86\x3f\xc3\x10\x2f\x69\xa3\x91\x7f\x44\xd4\x34\x26\xa3\x87\xe1\x7a\x75\x77\x35\x59\xdf\x51\x9e\x4e\x27\xed\x0c\xe3\x55\x92\xc8\x02\x35\xf4\xe7\x42\xa1\xb8\x57\x62\x44\x21\x9e\x86\x3b\xf7\x49\x08\xe0\x04\x62\x5d\xce\x1e\x09\x1b\x1b\x66\x1f\x42\x30\x63\x6b\x74\xe3\x17\x50\x61\x76\x4c\x93\x8e\xfc\x56\x8a\xe2\x99\xed\x9a\x68\x39\xde\x1c\xb3\x0c\x85\x04\x49\x94\x7f\xdb\xc1\x23\xb4\x26\x76\x13\x9e\x34\x21\x51\x3a\x0f\x1a\x03\x55\xa5\x69\xe0\x85\x40\xfb\xfb\x64\x9a\x9a\x9c\xa4\x63\x99\x1a\x9a\x36\x15\xb7\x67\x25\xc2\xf1\x8c\xfe\x94\x4e\x0e\x7e\x97\x78\xc2\x5e\x4a\xc3\x9b\x2c\xb8\xdc\x76\x5f\x63\x43\x17\x88\x34\xfe\xd9\xf7\x5d\x87\x41\x78\xe9\xae\x74\xa9\x01\xdf\x7d\xc8\xbe\xff\x6f\x50\xe8\x90\x75\x52\x50\x7d\x1f\x17\x74\x5e\xa2\x0a\xdb\xe1\xc7\x8a\x36\x2a\x48\xfd\xb0\x4b\xba\x3a\x31\x75\xa3\xc2\xae\x8a\xeb\xf4\x6e\x74\x98\x43\xcb\xed\x56\x3c\xca\xc7\x0d\xd5\xf7\x46\xd8\x8f\xc6\xcb\x4f\x1d\x25\x08\x44\xaa\xc3\xa0\x66\x20\xc2\xf2\x44\xc3\x97\xa9\xba\x56\x32\x85\x8e\x24\xfd\x12\x98\x7d\x28\xfa\x10\xf8\xa9\x4c\xec\x3d\x37\x24\x0e\xa8\x5a\x43\x1d\x40\x71\x1c\x51\xa2\x5c\xd0\x2a\x4f\x0a\x2d\xc9\x73\x59\xc6\x8d\x9c\x67\x7b\xab\x75\x3c\x9d\x55\xf4\x57\x9b\x69\x70\x5a\x69\xc5\xdc\x65\x05\x81\x68\x21\x44\x05\x18\xc5\x72\x51\x41\x80\xa5\x3e\xaf\x36\x24\xd6\xb7\xce\x5b\xa9\x4a\x72\x39\x88\xab\x10\x56\x4d\xc3\xc2\x67\xd5\x74\xa5\x15\xd8\xe6\x06\x3d\xa3\xa8\x54\xff\x64\x12\xe4\x32\xcb\x4a\x67\xcd\xca\xd9\xa7\xe5\xf2\x13\xaf\xa6\xe2\x93\x76\x42\xb7\xad\xa9\x4a\xe1\x6f\x3d\xde\x99\x0e\xe6\x37\x1b\xd4\x45\x75\xc1\x9e\x88\x45\xd5\xe0\xdb\x92\xce\x06\x45\x55\x5e\x8a\x1a\x58\x41\x13\x80\xd7\x14\x1d\x9d\x9f\x4b\xd6\x90\x39\x9d\x69\xe7\x53\xa8\x32\xb3\xbf\xf4\x5b\x1d\x53\xc0\x19\xf2\x93\xb9\x7b\x34\xdc\xd5\x7b\xd5\x49\x15\x3a\x4f\xe9\x6c\xd5\x43\x32\xa5\xf7\x46\xe4\x52\xfd\x77\x46\x87\xe4\x8a\x0e\xc9\x21\x95\xc4\x24\xbf\x68\x9c\x2b\x87\x3d\x91\x6f\xc6\x87\x3a\x43\xf5\x50\xc7\xbd\xd8\xee\x51\x7a\xe8\x7a\x5b\x2e\xd1\x94\x9e\x6f\x2e\x30\x51\xb5\xe6\xba\xd6\xac\xa3\xd6\x25\x3d\xdf\x9c\x61\xa2\xee\xcb\xbe\x3c\xcb\xd0\xf9\xa6\xf9\x0d\xb6\x99\xc6\x54\xdb\x7b\x08\xdd\xd0\xc3\x30\x0c\xf8\x18\x5f\xd0\x43\x72\x48\x6f\xc6\x81\xc7\xc9\x21\xb8\x9b\xe8\x69\x82\xac\xe3\x82\x52\x5a\x66\xd9\xe6\xe6\x19\xd5\xa1\x3a\xa6\xf4\x1c\x13\x55\x3a\x57\xa5\x57\x54\xc7\x3d\xb9\x54\xa5\x61\x47\x0a\x95\xdf\xd9\x83\x43\xcb\xa8\x2e\x28\x3a\xa4\x17\x38\x70\x93\x58\x1d\xd2\x9b\x55\x49\xef\x29\xae\x66\xba\x5c\xc2\xdf\x4b\x13\xe8\x4e\x63\xdd\x14\xd0\xec\xd2\x38\x2a\xe8\x55\x58\x95\x0a\x84\xa6\xc2\x10\x2a\x0c\xa3\x0a\xe3\xab\x8a\xde\x16\x65\xc3\xaf\x6d\x34\xf1\xa7\xac\x51\x37\x4f\x93\xd9\x11\xd6\x9e\x4d\xd5\xbb\x5c\x12\x87\xc1\x6f\x15\x52\xe5\xe5\x8a\xfc\xda\xd0\xde\x88\x7c\x90\x54\x28\xf6\x4d\x61\xc7\x65\xe9\x1c\x41\xdf\x87\x76\xa0\x1f\x52\x11\xef\xf6\xf6\x10\xe3\xf1\x45\x89\x3e\x48\xf2\x1e\xab\x36\x3e\xc8\x60\x5b\xaf\xe2\x33\xe6\x83\xc4\xe3\xb0\x1b\x1d\x94\x92\x91\xd2\xe7\x8f\xf9\x20\x0d\xbf\x76\xad\x5a\xf2\x01\xc6\xf8\x39\x1a\xed\x65\xd7\x10\x89\xf9\x43\xe8\x01\xd4\xef\x63\x32\xda\x7a\x90\x5d\xeb\xcf\x0e\xd4\x67\x11\xe3\x69\x6f\x38\xfa\xfd\x29\x3d\x80\xd8\x17\xa6\xf4\x74\xcd\x95\xe9\x74\x72\xaa\x63\x5e\xe4\xa7\x11\x59\xc1\x2b\x6b\x94\x3f\x1a\x6e\x43\xa7\x46\x8d\x39\x93\xe8\x83\x54\x00\x88\x84\x16\x91\x05\xd5\xde\xba\x4a\x64\xae\xca\x03\x56\x5d\xc1\x29\x92\x73\x6e\xed\xe4\xc9\x47\xa3\xe1\xd6\x6e\x52\xe7\x41\x57\x9d\xaf\xb5\xbd\x93\x7f\xa5\xc2\x83\x7c\x21\x91\x24\x0b\xfa\x41\x92\x12\x13\x29\xd1\x02\xaf\xda\xeb\xfc\x9f\x41\x16\x7e\x8e\x4e\xe9\x55\x45\x0e\x80\x84\x93\x6b\x7a\x3a\x08\x90\x99\x94\xf4\x74\x10\xa3\x33\x39\xe8\x51\x7a\x9d\x29\x44\xb9\x8e\xe9\xb0\xf7\x99\xd6\x7e\x78\xd6\x12\xb0\x87\x7a\xcd\x72\xd9\xab\x20\xc4\x0c\xd5\xc6\x59\xaa\x64\x1b\x22\xdd\x5a\x6a\x03\x3c\xba\xb6\x04\x0a\x22\x1a\x43\x43\xa1\x13\x63\xde\x37\x26\xfd\x52\x9d\x28\xcd\xc4\x99\xf8\x4b\x54\xe1\xbc\xd7\xd3\x4e\xd7\x45\xcd\xec\xa8\xde\x08\xc9\x35\xfd\xef\xf5\x14\x82\xaf\xad\xa0\xdd\xf4\x57\x28\x99\xd5\x60\x6a\x1e\xcc\xc6\x27\xd7\xd8\x65\x9f\x2a\xb3\xec\xb2\x42\xd7\x6a\xe8\x07\xb4\x1c\x00\xfd\x20\x5e\xdc\x74\x4a\xcb\x01\xab\xa6\xea\xf5\x29\x3d\x70\x89\x0d\xc2\x23\xf1\x7a\x82\xae\x93\x63\x90\x1e\x90\xeb\xe8\x10\xd4\x26\xa5\x57\xbc\x42\xa7\xe4\x5a\xdb\xa4\x5a\x4a\x8c\x73\x74\x4a\xd1\x01\x4d\xc6\xbc\x5c\x4e\xfd\xd9\x78\xf0\x2d\x67\x23\x3a\xa5\xa7\xc9\xf1\x48\x16\xf4\x3a\xcc\xd4\x61\xfa\x24\xd2\x8f\xc7\x4e\x79\x81\x49\x49\xdd\xbc\x61\xd2\x13\x99\x07\xd5\x58\x35\x55\x95\x7a\xa7\x03\xf6\xb9\x61\xd5\x34\xcb\xe4\xa3\x32\xcb\xd0\x82\x96\xa4\xa4\x92\x48\xba\x50\xfd\x9d\x57\xe8\x9a\x48\x4c\xe6\xfa\xa9\xc4\x64\x91\x65\xf3\x2c\x43\xea\x72\x7a\x1a\x9c\xd1\xcb\xe5\x69\x70\x42\xab\xa3\x0f\x50\xc6\x17\xeb\x73\x18\x5e\x08\x78\x54\xaf\xdc\x79\x0d\x8e\x82\xf6\x83\xe0\xdc\x86\x72\x5d\x5f\x2d\x1a\x3a\xa0\x07\x26\xd6\x09\xa0\x3e\xc2\xe0\x9a\x01\xab\x84\x74\x8f\xc4\xb6\x8f\xc9\xa9\xf1\xbf\x3b\x98\xcd\xa0\xb6\x44\x98\xc8\x47\xe5\x04\x9d\x0e\x8a\xe9\x54\x37\x70\xa0\xaa\x69\x10\x20\x3d\x02\xe2\x3a\xc4\x39\x3a\x50\xcd\x3f\xeb\x78\x47\xa2\x36\x20\x1a\xf3\x01\x3d\x3e\x81\x73\xf6\x94\x5e\x8f\xd5\xea\xf9\x4d\x32\xc6\xea\xd8\x3b\x0d\x0e\xf2\x03\x1d\x03\xca\x99\xa6\x9f\x92\x19\x3b\x6f\xf2\xd3\x81\x2c\x6b\x31\x9b\xbd\x62\xe7\x0d\x69\xc4\xdc\x15\xbc\x17\xf3\x95\x0e\x03\xd6\x2d\xed\x02\x98\x29\x02\x60\xe2\x6f\x90\x6b\xc5\xbd\x3f\x3c\xb0\xce\x5c\xd7\x9b\x9b\x58\xe1\xfc\xf1\xf5\x09\xb6\x81\x55\x82\xbe\xe8\xe9\x40\xf5\xaf\x60\x11\xbd\x7b\x2f\xe6\xf4\x74\xd0\x88\xf9\x4a\x1d\x98\xbd\xb3\x8a\x5c\x55\xf4\xcc\xc7\x30\xb0\xc7\x04\x49\x8f\xb8\x6b\x9f\xb2\xd4\x1d\x6f\x9f\x5a\xc7\xdb\xf6\x5e\xf6\x29\xcb\xb8\x44\xd7\x24\xa5\xc7\x70\xc0\x7d\xc2\xb7\x07\x06\x8d\x81\xe9\xfb\xa2\x5a\x88\xc3\x38\x7d\xd1\x6d\x1f\xd1\xf0\x84\xb4\xea\xbd\x0f\xb1\xaf\xec\x01\x3d\x4a\x94\xe5\x07\xf4\x68\xd5\x05\xd0\x2f\x93\x2f\xe8\x00\xe7\x5f\xdc\x0c\x0f\x56\xff\x6b\x07\x80\xb5\x03\xff\x20\xb4\x9a\x9a\x6b\xbe\x27\x80\xb6\x9a\xfe\x6f\x12\x3b\x93\x70\x46\xde\x4a\xda\x78\xd3\x52\x58\x8c\x00\xfa\x4d\xdc\x27\x89\x7e\x99\xce\x8c\xde\x0b\xc8\x64\xa7\x45\x65\x96\x21\x63\x8b\x9e\x18\x17\x35\x13\x75\x3b\x7a\x2e\x27\x2f\xe4\xe6\x66\x8e\xac\x1d\x32\xc3\x39\x3c\x76\xca\x58\xcb\x2c\x3b\x28\xc3\xc8\x9a\xa4\xb6\xea\xf5\xa7\x16\x82\xda\x0e\x9e\xd1\xc7\xd2\x19\xc3\x3b\xf1\x81\x37\x50\x5e\x2e\x7f\xb5\x91\xc9\xfd\xad\xff\x32\x95\x20\x3a\x1c\x64\x31\x0e\xea\xb8\xef\xbb\x7b\x19\xb8\x59\xb5\xb9\x02\x2d\xb6\xdb\x1d\x6d\x65\x0c\x2f\x97\xbf\xc9\xe5\x12\xfd\x06\xee\x20\xcf\x05\xda\xbf\x1f\xc5\x53\x31\x23\x03\x43\x06\x18\x8d\xa2\x09\xed\xe5\xf6\x6e\x23\x6a\x8c\xfc\x1c\xed\xab\x31\xbc\x95\x76\x78\xfb\xf7\x1f\xbe\x95\x93\xfd\xfb\xf9\x5b\x69\x27\xab\x8d\xfd\x5f\x08\xc4\xc8\x55\x19\x2a\xd9\xaf\x4c\x13\x06\xf7\xfe\x94\x46\xdc\xd0\x1b\x8d\x75\x63\x7f\x82\x3a\xd1\x3a\x0d\xdc\x21\xe7\xd8\x1e\x61\x1b\xe2\xf6\x93\x04\x32\x63\xae\x98\x2c\x30\x5e\x08\x2e\xa5\x61\x16\x55\xb5\xe5\x8d\x88\xc4\x49\x53\x14\xc4\xa2\xf8\x0d\xdf\x17\x61\x4a\xa2\x5d\x52\x61\x22\xf4\x5f\xbb\xd1\xa2\x0c\x6f\xa9\x3f\xa3\xdb\x67\x0a\x95\x56\x95\x91\x2a\x18\x84\x67\x2d\x7c\x67\xd4\x59\x2e\x7f\x92\xb4\x21\x80\x44\xbd\xa1\x87\xed\x61\x69\x9d\x1b\x66\x90\x5b\x9e\x6a\x77\x23\xfa\x63\x81\x2a\xd2\x84\x5b\xc0\x9b\x1e\x58\xeb\xfa\xf0\x5d\x96\x69\x03\x0e\xd7\xf0\x45\xe9\xac\x36\xbd\x8d\x38\xf4\x06\x2e\x53\x6e\x13\x5b\xa9\x53\xdb\x86\xc1\x7c\x69\x60\x79\x58\xa2\x4a\x7f\xea\x8d\xc4\xfc\x5b\xab\x6d\x8f\xf4\x28\x5d\x5b\xb2\xba\xdb\x41\x69\xb9\xec\x8e\x66\xfa\x8d\xba\x92\x1a\x63\x00\x64\x45\x18\x3d\x93\xf0\xe7\xc7\x02\x35\x84\xad\x01\x64\xa5\x00\x59\xb5\x01\xe9\x4d\x0d\x03\xfb\x07\x0f\xdb\x9b\x32\x4e\xed\xc8\x02\x65\xa5\xb7\x34\xa8\x07\x53\x36\x63\x0d\x43\x0d\x26\x60\xab\xce\xb2\xec\xbd\x84\x3c\x97\xc6\x56\x7d\xb9\x84\x87\x03\x30\x9b\x4c\xec\x28\xc1\xd2\xeb\x2f\xf9\x70\x77\x38\x9c\x80\x95\xcb\x7b\x89\xf3\x8f\x8a\x28\xe4\x4f\xb4\x0d\x57\x96\xe9\x4d\xd0\xb4\x6d\x06\xb3\xac\x79\x08\x31\x38\xdb\x26\x83\x80\x26\xa1\x63\xdf\x75\x64\x93\x93\xba\xe9\x59\x53\x7f\x3f\x15\x43\xba\x87\x9a\xab\xff\x5d\x22\x6d\x01\x4c\x98\xf1\x47\x4b\xb1\xb4\xf1\xc8\x79\x25\x93\xa8\x92\xde\x9f\xbd\x9d\xa4\xb5\x8a\x82\x11\x8a\x34\x7f\x26\x88\x09\x23\x4d\x4b\x0f\x62\x7d\x9c\x0b\x27\xc8\x7c\x56\xd0\xde\xd0\xb9\x90\xd6\x0f\x7d\xf0\x2c\xf5\x66\x14\x05\xc9\xda\xce\x7f\x2b\xd4\xec\x5e\x17\xa8\x6d\xdb\xf7\x17\xa4\xae\xd8\x31\x79\x3b\xb2\xcc\x18\x09\x89\x81\x0e\x11\x1f\xc8\xcf\xbf\x25\xe0\xba\xb6\x26\x89\x63\xa9\x85\x29\x30\xae\x45\x2b\x00\xd4\x13\x8e\xa2\xc4\x2d\x89\x7b\x73\x62\xb9\xd3\x8a\x0f\x60\xfc\xd9\x84\x09\x04\x30\x38\x35\xf9\x3a\xc9\x4c\xa0\x1f\x04\x11\x83\x53\x03\x32\x90\xf6\xe0\xb4\x20\xca\xe3\x65\x9d\xa6\x6d\x86\x9e\x38\x11\x47\x78\x6e\xba\x6c\x12\x9d\xe2\xf7\x2c\xab\x1f\xd1\x6a\xf2\xdc\x66\x49\xcd\x51\x3b\x4d\x80\xc7\xa5\x86\xba\x0c\xc0\x78\xe2\xe2\xa4\xe8\x10\x86\xe3\x8e\x0f\xa3\x01\x43\x0e\x91\xba\x7b\x35\x1e\xd1\x8a\x74\x66\xf5\x00\x94\xb1\xf3\x71\x29\xc8\xc7\x49\xc8\xfd\x50\xc3\x21\x5a\xd0\xc8\x32\x24\xd2\x7c\xe9\xc2\xe7\x93\xc5\x26\xae\x7c\x38\xe1\x5e\x1d\xca\xf2\xed\xd9\xe1\x26\xbf\x02\xcc\x35\x22\x2a\x78\xf6\x89\x64\x59\x3b\xab\x7e\x98\x5b\xd6\xc0\x40\x47\xd4\x0b\xb5\x3a\x49\x60\xaf\xa6\x5d\x10\xea\x75\x30\x61\xed\x0c\xec\x67\x02\x35\x64\xee\x77\x1e\xa9\x39\x08\x02\x88\xa0\xff\xe4\x5a\x6b\xd2\x90\x9a\x30\x22\x54\x61\x9c\xce\x89\xb4\x4d\x98\x44\xe8\x8b\xde\x75\x20\x58\xa8\x5a\x33\x39\x4a\xa9\x18\xfc\xf0\x83\x7e\x6b\xb2\x44\x80\xb9\x4a\x1a\x85\xd1\xce\xa8\x65\x73\x74\x25\xd4\xe1\x61\x44\xdf\xbd\xe1\x18\x36\xa1\x89\x69\xa2\xa0\xdc\xd5\x8e\x1a\x9f\xde\x93\x81\xb9\x9e\x29\x99\x98\xbf\x5a\x4c\x58\x28\x02\x62\x24\xe6\x75\xd7\xe1\xa7\x69\x5a\xa7\xdd\x56\x96\x9d\x29\x60\xd6\x44\x82\x3d\xba\x19\x7a\x4d\xaf\x78\x94\xca\x09\xb6\x71\x14\x5f\xf2\x39\x3f\x63\x35\x6d\xc8\xb5\xfe\x1c\xcc\x7e\x1b\xfa\xa6\xf0\xeb\xd1\x1b\x42\xa0\x16\x1b\x6b\x56\x41\x6c\x48\xde\xb9\x0a\x7a\xb1\x5c\x44\x7b\xa7\xb3\x2b\x4d\x96\x62\x96\x2b\x48\x2b\xb4\x0f\x42\x68\xfe\x9b\x71\xcb\x9f\x17\xb0\xac\xf7\x74\x28\xdf\x53\x35\xef\x85\xc4\xb7\xee\xd1\x28\x91\xd4\x59\x78\x5a\x36\xa2\x1e\x37\xb4\x41\x10\x4c\xb6\x66\x72\x31\x6b\x20\xf1\x15\x98\xec\x44\x1e\xe5\xc3\xb0\xb9\x4c\xbb\x95\x9a\x4b\x1b\xf1\x6d\x8f\xc2\x76\xf0\x0a\x93\x3b\xdb\xf0\xdf\x6d\x25\xdf\xe1\xd5\x0a\x09\x4c\x46\x80\x26\x76\x0e\x26\xa2\xb0\xad\x38\x76\x6e\x23\xae\x88\xe8\x5d\x4b\x85\x4e\x0d\x5c\x5c\xd0\x04\x2a\x5d\x78\xe3\x68\xf1\x51\x89\x18\x9e\x8c\xf2\x61\x14\x6f\x91\x85\xd1\x7e\xf9\x39\x02\x35\xa9\xdb\x41\x94\xd2\xd2\x35\x30\x1a\x8d\x4d\x54\x83\xb9\x2f\xdb\xb1\xa4\x69\x0b\xa6\xc4\xe8\x4f\x02\x09\x85\xa0\xdc\xb1\xdd\x0d\x7d\x1a\xa0\x92\xf7\x53\xf0\xa6\x38\x0d\x7d\x7c\x77\x0d\x55\xe5\xc9\xdd\x55\x76\xf2\x86\x7e\x0c\xaa\xa8\x71\x68\x22\xc7\x30\x24\x77\xf6\x21\xfc\x62\x46\x7e\xb8\x47\x04\xe9\xf7\xbd\x4b\xac\x41\x6c\x97\x3a\xc2\x51\xcb\x94\xf7\x20\x4f\x35\x39\xae\x49\x82\xfb\xe0\x56\x2c\xf2\x9f\x04\xaa\x89\xc0\x41\xc0\xda\xaf\xb6\xf8\xf8\xfb\x5a\x84\x23\x58\x33\x2c\x75\x1c\xd0\xc7\x19\xdd\x38\x43\xd5\xba\x95\xdd\x63\x4b\xdb\xc2\xa7\x29\xc9\x7d\x14\xa1\x8e\xa3\x6c\x22\x06\x61\x78\x03\x22\xb9\xb6\x55\x9f\x6b\xe2\xa2\xad\x52\x31\x69\xe7\xe6\xb2\x9f\x29\x9c\x12\x58\xb1\x57\x24\x38\xcc\x1d\x77\x06\x5d\x7a\xfe\xc6\x98\x61\x82\x80\xb5\xa0\x07\x15\x5a\xcb\xfc\x84\x7a\x28\x72\x5d\xd0\x86\x08\x7a\xaa\x18\x3f\x4c\x84\xb1\xd0\x7e\x0f\x87\x11\xb8\x4f\xe9\xe3\xc7\xc4\xc4\x1c\x57\x63\x5c\x85\x09\x48\xb6\xc3\xcb\xe4\x72\x34\xdc\xda\x89\x42\x16\x02\x99\x7c\x67\x57\xaa\x32\xcc\xa2\x23\x90\x09\x1e\xb9\xa0\xb7\x7f\xb9\xc4\x67\xfa\x0e\x70\xe4\xd6\xad\x1b\x17\xf8\xfa\x60\x4e\x1a\xf4\x54\x0c\x6c\x7c\x23\x72\x51\x01\x66\x4c\xa4\x49\x9a\xef\x82\x2e\xc0\x8b\x76\x74\xf7\xd1\x1e\x26\x1f\x4c\xe2\xdb\xb5\x0c\x6d\x47\x2e\xbf\x75\xac\x6c\x63\xd3\x66\x19\xb8\xc8\xe8\xcc\xc0\xa4\xb1\x0a\x9a\x80\xab\x09\xc1\x50\x75\x64\x8c\x71\x3c\x61\x92\xe4\xe5\x2b\x5c\x30\x69\x21\xb4\x33\x40\xb3\x4b\x7e\x14\x61\x42\x1e\xae\xa5\x3d\xe5\x2c\xe1\xf9\xea\x96\x7d\xf2\x7d\x5b\xd6\x65\xbb\x33\x9d\xa6\x43\x4d\x46\xf0\x20\x09\x65\xdc\xfd\x99\xc7\x83\xd6\x0c\x86\xea\x78\xae\x5b\x1c\x7f\x6b\x1a\xad\x04\xf3\x84\x53\x61\xa2\x80\x68\xad\x7d\xd2\x04\x68\xcf\xe1\xde\x50\xa6\xf7\x86\xa4\x80\x72\x67\xa8\x8e\xf9\x39\xe8\xef\xf5\x45\x64\xa8\xa3\xb2\x3d\xae\x51\x49\x38\x9e\x0c\xf3\xe1\xb2\x3b\x2c\xc9\xe0\xb4\x2c\x66\xe5\x62\x56\x34\x4c\x27\xcc\x9d\x3e\xe6\x8d\x9c\xac\x29\x87\xd6\xf2\xf0\x32\x0f\x47\x9b\x87\x12\xb0\x89\xf6\x47\x96\xf5\x82\xbb\xe2\x6d\x48\x94\x9c\xdd\xa4\x93\x92\x58\xc2\x58\x3a\xcc\x86\xd4\xd3\x26\x10\x4f\x83\xed\x5d\xb9\x1c\x5b\x33\xfa\x32\x0a\xa2\x1b\x5c\x68\x67\xf8\x56\xd2\xd2\xac\x95\x95\xc0\x2c\xe8\x2c\x4a\xb0\x66\xdb\x5b\x68\x39\xcc\x62\x60\x80\xaf\x9d\xfe\xe1\xc2\xb2\x18\x88\x33\xc9\xea\x6b\x3d\xf7\x8c\x63\x7c\x3b\x02\x25\x8c\x0e\x71\x87\x16\xad\x20\x31\x60\x94\x5d\x92\x05\x56\x2b\x95\x84\x20\xa8\x60\x3e\x69\x02\x4f\x7f\x01\x5b\xd0\x32\x30\x06\xcf\xb2\x45\x57\x03\x69\x21\x34\xc0\x1d\x9c\x14\x92\xa6\x1e\x00\xf0\x5d\x5a\x48\x9d\xfc\x65\x41\x17\xda\x39\x43\x2f\x85\xa4\xa3\xa1\x9f\x63\xa9\xd9\x22\x9f\x4b\x40\x51\x40\x0b\x59\x0f\x70\x89\xad\x75\x24\x2d\xbd\xdc\x4b\xd2\x32\xc9\xd5\x28\xc1\x4f\xed\x56\x06\xf6\x19\xe1\xf5\xae\xa4\x81\xfd\xda\xad\x5b\x7b\x67\x79\xa9\x1a\xd4\x1f\x05\x11\x2f\x4b\x2a\x57\x66\xe7\x8a\x78\xb3\xae\x39\x35\x5c\x98\x26\x7b\x59\xd7\x7e\x7f\xf1\xa6\xc5\xbe\x29\x7b\xd1\xaa\x69\xad\x58\x46\x8e\x04\xe1\xde\x03\x21\xc4\x10\xdc\xba\x78\xad\x27\x7f\x8e\xe4\x72\xe0\xeb\xec\x50\x92\x51\x90\x8f\x66\x66\x44\x57\xd3\x95\xb8\x61\xbb\xac\xb4\xd5\x9e\x82\x96\x7e\x75\xb4\x14\x7e\x70\xff\xeb\x94\xf7\x2b\x04\xf7\x5f\xb9\x7f\xd8\x6b\x23\x5c\x07\x27\x88\xd1\xde\x90\xc0\x55\x10\xe7\x10\x5b\xce\x82\xfb\x42\xb3\x3d\x02\xdb\xdb\x15\xdc\x95\x92\xbb\x15\xf3\xb3\x72\xcb\xea\x24\x09\x77\x24\x8e\x03\xba\x7b\xa0\x0d\x50\xc8\xa9\x31\x44\x71\xf2\xba\x4f\xa5\xcf\xc8\x02\x01\x8c\xd4\x88\x19\x81\xc7\x8f\xec\x86\x56\xfa\xd1\x25\xf0\x83\x18\x47\x70\xfa\xc1\xa3\x25\x59\x50\xc7\xdd\x1e\x75\x43\x0a\x98\xf0\x14\x42\x57\xcf\x48\x95\xf2\x6a\xca\x3e\xd3\x21\x31\xed\x9c\x07\xaf\xa2\x30\xdf\x8d\x2e\x8b\x82\x88\x43\x49\x7c\x85\x86\xa2\xf0\x22\x1e\xd5\x09\x82\x83\xeb\x72\x35\xcc\x5a\x3f\x7b\x96\xcd\x0c\x26\xcc\xf6\xa7\x7e\x47\xc9\x7a\x55\x41\x2a\x97\xf7\x50\x49\xdd\x22\xa1\xfd\x96\x24\x45\x95\xc6\xa8\xe3\x05\xa8\x5f\x82\x05\xb1\x5c\x0e\xfb\x14\xae\x93\xaf\x0b\x97\x31\x6f\x1e\x01\xb7\xae\x79\x2d\x1a\x61\xbc\x3d\x7a\x6c\xc0\xa5\x0e\x0f\x65\x25\xde\xc1\xd7\xef\x13\x51\xad\x37\xc6\x89\xb9\xab\x6a\x82\x50\x45\xd5\xb8\x20\x0e\xb2\xba\xca\x7e\x64\x37\x84\x19\x8f\xa0\x68\x79\x59\x7c\x79\xd7\x48\xc0\x6c\xe2\x05\x8f\x21\x2c\x0a\x6c\xee\x61\xc1\xe2\xd0\xf0\x38\x47\x55\x8a\x0d\x55\xb4\x60\x55\x6b\x31\xaa\x76\x28\xf9\x2a\xb5\x2e\xc6\xa4\x3b\xa8\x4c\x77\x5e\xd6\x56\x30\x9d\x56\x5e\xd6\x2a\xc9\xcb\x5a\x7d\x25\x2f\x6b\xf5\x95\xbc\xac\xd5\x1d\x79\x59\x9b\x34\x2f\x6b\xd5\x99\x97\xb5\xe9\xce\xcb\x9a\xb2\xe2\x71\x5e\xd6\x66\x6d\x5e\xd6\x26\xcc\xcb\x1a\x64\xb7\x74\xa1\x02\x49\x65\x76\x34\xd3\x7f\x49\x05\x9b\x1a\x12\x18\x85\x81\xe7\x3e\x3b\x44\x56\x94\xde\x86\x6a\xdd\xd2\x57\x48\xd6\xa9\x78\x65\x18\x10\x1d\x7c\xad\x82\x8c\xca\x36\xe3\x56\x58\x51\xd2\x5d\x6b\xeb\x19\xc7\x64\xdd\xa8\x98\x25\x9a\xaf\x4b\x1b\x52\x48\x1d\x79\x82\x70\x17\x3c\x57\xb2\x5c\xd2\x07\x44\x2c\xe9\xfd\x50\xe4\x5b\xbb\xe2\x28\xdc\xbe\xb0\x2d\x22\xa6\x76\xc7\x68\x8b\x54\xa4\x21\x0f\x96\x22\xd9\x13\x42\x21\x75\xe3\x9e\x12\x5c\xe2\x36\xf9\xe5\x2c\x69\x6e\x1b\x9a\x53\x8d\xc1\xb7\x33\xf8\x36\x68\x76\x76\x57\x63\x8b\xa4\xb1\x7d\xd7\x58\xd8\xc4\x62\x4d\x13\xd6\xd0\x40\x01\xb9\x25\x4e\x0d\x65\x3d\x2e\x0b\xa9\x97\x96\x42\xf7\x5c\x41\x6c\x34\x8c\x85\x2b\x85\x2a\xdc\x8f\xcb\x4a\xa8\x98\xc4\x02\x9f\x43\xe1\x4e\x5c\x78\x0e\x85\x7b\xa4\x8e\x0c\x5e\xf5\xbb\xa9\x7a\xb7\xb5\xb5\x46\x36\x33\xda\x1e\x9a\xbb\x1b\x9b\xb0\xdc\xce\x22\x14\xd6\xa0\x46\x01\x49\x76\xc2\x88\x59\x79\x59\xdd\x4e\x81\xcb\x43\xdf\x9a\xd7\x2d\xc2\xad\x61\x7f\x9f\x30\x52\x93\x46\x35\x9b\x06\x63\x09\x3c\x06\x5e\x39\x25\x60\xf8\xed\x9e\xd1\x83\x7d\xf5\xf3\x67\xe9\xe7\x30\xa3\x1d\xc7\xbe\x38\x7c\x9f\xf8\xc7\xfc\xf8\xc4\x90\xf2\xce\xd6\x43\x71\xf0\x6d\x74\x37\xce\xd3\xb0\xde\x86\x42\x3f\xb1\x0d\xc3\x90\xf9\xd5\x5c\x83\x11\x1a\xcd\xd9\x20\x2e\x58\x85\xb0\x7b\xe7\x86\xef\x78\x10\x73\xec\xc7\x9e\x4c\x3a\xc2\x62\xd0\xb5\x65\x55\xbc\x0f\x67\xc8\x40\xd8\x01\x05\x5f\xaf\xf5\x5a\x88\xde\x7a\x3f\x07\x3d\x9e\xd4\x79\x3f\xea\xc4\xdc\xa5\xdc\xe0\xd4\x0f\xff\xad\x0d\x25\x6c\x18\xa9\xb6\xe3\x43\x54\x1c\x3a\x38\x78\x5e\x24\x30\xeb\x77\x85\x81\x1a\xd6\xf1\x24\x6d\x77\x04\x57\x3d\x76\x3a\xf0\x6c\xcd\xba\xf2\xd0\x5b\x22\x30\x30\x78\x92\xf0\x0c\xed\x36\x9c\xe3\x5a\x97\xdb\x04\x28\xc7\xaa\x2c\xab\x1e\x69\xb7\x3c\x1a\xe0\xc0\xc7\xaf\x36\x4d\x3a\x23\xe2\x8c\xab\x87\xcd\x3a\xe7\x8a\x06\x13\x54\x3f\x6a\x96\xcb\x21\xf8\xb5\x38\x47\x89\x56\xad\xe6\x9b\x1d\x30\x9a\x6f\x77\xc0\xf0\x73\xfb\xcb\xcc\xad\x79\xd4\xb6\x51\xf2\x63\x0f\x61\xde\x84\x1e\x3c\x2d\x18\x1b\x30\xa2\xe6\x11\xad\xfe\x1d\x3e\x2b\xcd\xa3\xae\x0f\xd6\x81\x6b\x73\x84\x89\x9a\x49\x67\x6b\x77\xc4\x27\x6a\x42\x43\x81\x0f\xc9\x72\xa7\x61\x59\xc0\xa8\xab\xb2\x81\x14\x3b\xe0\x1b\xb2\xb2\x4f\x03\xda\x6b\xf5\xfb\x36\xa6\x04\xd7\x06\x05\x92\x4e\xf9\x40\x1a\x07\xe5\x31\xa7\xbf\x4b\xc4\x89\x20\x12\x8f\x19\x68\xa0\xf1\x6d\x03\x0a\xa8\x3f\x18\x24\xe1\xea\x50\x7e\x61\x1d\x11\x72\x64\x73\xca\xb4\x5c\x9b\x86\xc6\x1c\xa9\xa4\x55\xe0\x77\x5c\x26\x7e\xc7\x65\x22\x72\x64\x9f\xad\x3b\x77\x13\x64\xa4\xbb\x12\x48\x0b\x24\x30\xbe\x8d\xbf\x49\xf2\xbe\x1d\x1a\xc6\xf1\x90\xd5\x17\x4c\x67\x13\x79\x12\xb7\xba\x5a\xa9\x06\xba\x1c\x76\x4b\x3c\x4e\xe7\x30\xd2\x81\x77\x12\x63\x9c\x99\x49\x64\x37\xd6\x23\x9b\x41\x6a\x9b\x1b\x81\x2a\x32\x23\x65\x20\xe1\xaa\x68\x69\x52\xb6\xd2\x85\x48\xae\x11\x8d\x9d\xed\xa4\xf1\x64\x32\x6f\x52\x32\x5a\x11\xd4\xd0\x92\x43\x9a\x52\xdc\x8e\x86\xcc\x56\x41\x62\x19\xa7\xae\xad\x35\xb3\x5b\x6b\x01\xb5\x8b\xfa\x5b\x63\x32\xe3\x10\xb4\x91\xfc\x53\x42\xd6\x2f\xc2\x3d\xd2\x3c\x2e\x8d\xc2\x4b\x5f\x9c\xac\xec\xce\x48\xe4\x42\x1f\x38\xc7\xe6\xb4\xf3\xda\x25\x69\xc0\x59\x2b\x87\x9d\xef\xef\x8d\xc1\xf8\x2a\x48\x81\x96\x6a\xf8\xdd\x79\xed\x63\x47\x64\x19\x98\x53\xd5\x37\x41\x84\x50\xf7\x3b\xda\x05\xbf\x99\x0e\x4c\x47\x04\x7a\x08\xc5\x6c\xe6\x85\xff\xe2\xcf\xc4\xf4\x08\x22\x19\x98\x32\xa3\x37\xa8\xb2\xac\x07\x5b\xd1\x69\x51\x88\x50\xbc\xc5\xb6\xd1\xd2\xa8\xff\x74\xb0\xc4\xfb\x3a\x76\xe2\x64\x3b\x1f\xe2\x71\x1d\x44\xbc\x13\x01\x27\x51\x93\x82\x83\x8a\xef\xf8\x7d\x75\x42\x6b\x1f\xf9\x45\xcb\x21\x5b\x19\xd3\x34\x79\xf8\x91\xa1\x06\x8f\xdf\x77\x05\xf2\x66\xf8\xf6\xb2\xb1\x52\x10\x8c\xc9\xe7\x6f\xa8\xb4\x42\x43\xb2\x0f\x7a\x56\xef\x21\x90\xb3\xc4\x1d\x4c\x9f\xbf\xa7\xdc\xec\xb3\xb7\x42\x34\xb4\xf6\xa0\x7b\x1b\xdf\xbd\x99\x26\x0c\x2c\xb0\x96\xde\x4f\x7e\x8f\xd2\x0a\xe8\x41\x54\xb0\x5c\xf6\x37\x60\x6b\xdf\x83\x0c\x6f\xf7\xe6\x82\x57\xcd\x3d\x2b\x7d\xdb\xe8\xbb\xca\x5a\x3e\x1e\x2c\xe3\xcb\xe0\x4e\x65\xad\x0e\xaa\xae\xa4\x4b\x3a\x6b\x91\xc9\x97\xce\xe3\xc9\xad\xb3\xb1\x13\xf6\x8e\x26\xc6\x82\xb6\x52\xf1\x3d\x2e\x51\x81\xc7\x9a\x81\x41\x0c\xaf\x56\x4f\x4b\xd4\x90\x82\x40\xd8\x2a\xab\x8e\x5b\x33\x9a\x24\xeb\x3d\x3f\x47\xcd\x72\x89\x1a\xda\x43\x3d\xd4\x50\x36\x49\x97\x28\xf5\xa1\xb0\x6e\xca\x40\xf4\xb4\xf5\x8e\x5e\x85\x26\x80\x69\xaf\x19\x5c\x16\xf2\xa0\x69\x6a\x7e\xb6\x68\x18\xea\x4f\x8b\xa6\xb8\x07\x83\xa9\x85\x68\xfa\x18\x63\xd2\x6b\x7c\x18\xa0\xb1\x3d\x8c\xa0\xd5\x31\x8e\x53\xe6\x54\xce\x95\x57\x6d\x15\xd8\x3e\x43\xd2\x4c\x6e\xcd\xde\xc8\x7b\xc3\x95\x09\x14\x82\x57\x26\x63\x49\x0a\xe7\xce\x2b\xae\xb0\xa1\x74\xee\x00\x72\xe9\x81\xdc\x94\x51\x1a\xe1\x10\xe6\x5e\x03\x0d\x5f\x79\x24\x79\x91\xec\xf5\xed\x87\x45\x7d\x01\xe0\x94\xc6\xde\x3e\xb0\x3b\x71\xaf\x8e\xb7\x4f\x26\xe1\x0f\x00\xb3\x81\xc1\xad\xbd\xf5\xe5\x0d\x23\x1f\x99\x4e\xe1\xe0\x88\x71\xbf\xbf\x59\x13\x77\xd7\x60\x24\xbe\x42\x34\xe9\xfd\x20\xb4\x88\x7c\x1e\xf1\x06\x5b\xdf\x36\xd0\xad\x70\xa0\x5b\x66\xa0\x8a\xba\xbf\x2d\x51\x93\xda\x0e\x6f\x0d\x87\x3e\x91\x88\x85\x8c\xd6\x3a\xaf\xfe\x2c\xbd\x10\xcd\x58\x06\x45\x26\x12\x9a\xd9\x68\x11\x07\x4f\x0f\xf1\x8a\x44\x6d\x2c\x74\xca\xc6\xf6\xba\x76\x34\x02\x41\x4d\x43\x48\x8d\x9f\x96\xd6\x51\x1c\xfe\x44\xe9\xa3\x81\x88\x1a\xbb\xed\x15\x39\x6b\x52\x53\x0e\x9f\xe8\xc2\x7a\xa3\xff\x53\x20\x60\x87\x5c\x6c\x70\x13\x98\x9b\x98\xc3\x63\xb5\x22\x57\x71\x33\x61\xb2\x0c\x04\xb5\xb7\x4d\xed\x6d\xd5\xe9\xe1\x37\x74\x0a\xf1\x76\x75\x47\x60\xe2\xe9\xad\x3b\x7d\xaf\xaf\x5b\xc6\x9c\xd6\x14\x2d\x4e\xaa\xc3\xcf\xd1\x11\x43\xc6\xfc\xa8\x82\xf4\x40\xc4\x67\x0f\xaa\xa2\xec\x41\x26\x06\x58\x45\x75\x0a\x02\xef\xd8\xa2\x38\xbc\xe0\xb7\xae\x04\xd1\xbd\xea\x1b\xed\xbb\x24\xea\x83\xd9\x0c\xe9\x4e\x8f\x55\x27\xb4\xbf\xf9\xe3\xbb\xa3\xd7\x03\x2d\x74\xe2\xe7\x37\xa8\xdf\xdf\x6c\xf0\xe6\x7f\x9d\x1c\x83\x78\xc0\x8c\xe1\xe4\xbf\xd4\xb8\x86\xe3\xe6\x61\x65\xbd\x58\x9a\xcd\x4d\x77\xbe\x1e\x37\x90\xc0\xbf\xd6\x2a\x85\x5a\x1d\x55\x57\x3a\x9c\x84\xa8\xaf\x2c\xef\xfa\xac\x42\x35\xd8\x54\xf4\x44\x82\xb6\xfb\x0a\x6b\x0f\x18\xaa\x31\x39\x62\xa0\xa0\x58\xad\x56\xeb\xd2\x0b\xb1\x38\x19\xa8\x4b\x2f\xa4\x61\x03\xd9\x25\x75\x5e\xa0\x2c\x7b\xa5\x6a\xf7\x7a\x95\xcf\xd9\xd3\x90\xde\x48\x2d\xcb\x5f\x94\x95\xe4\x43\x2b\x7d\x3b\x49\x1d\xbb\x77\xc2\x78\x7b\x2f\x04\xda\x7f\x40\x58\x10\xe5\xc0\x7e\xd4\x0e\xc3\xc7\x5d\x18\x3e\xf2\x34\xdc\x21\x3a\x28\xfb\xbe\x0e\xe7\x1e\x22\xbd\x57\xa2\xbd\x74\xfe\x07\x2f\xe5\xf8\xa5\xcb\xfd\xd9\x71\xfc\x2b\x62\xf2\xa1\xd4\xa6\xdb\x3f\x43\x06\x50\x8c\x89\xee\x15\x61\x72\x56\x22\x85\xc9\x8f\x69\x17\xeb\x61\xe6\xb7\xf5\x1d\xf1\x04\xe1\x12\xf0\x4b\x49\x6f\x9f\x5d\x2b\x62\x94\x1f\xbf\xae\xc8\xab\x8a\x3c\xab\xc8\x7b\xf2\x89\x3c\xae\x22\x33\x34\xa1\xf8\x92\xa7\x15\x5e\x91\x27\xe4\x23\xf9\xb9\x21\xb2\x21\x67\x25\xb9\x35\x8c\x51\xde\x1b\xad\x4e\x56\xe3\x5e\xf8\x89\x35\x4d\x3b\xe7\xd5\x14\x6e\x26\x8f\x6f\x5e\x08\xd9\xbc\x34\x09\x07\xc7\x28\x35\xe8\x5a\x54\x53\x76\xce\x2b\x36\x0d\x1d\x67\x4f\xdf\x3e\x3b\x78\xf2\xfe\xf4\xe9\xb3\x5f\xdf\x1f\x1d\xbd\x7a\x77\xfa\xcf\x57\x47\x8f\x0f\x5e\x9d\xbe\x38\x3a\xfa\xe9\xf4\x34\xf6\xc9\x68\xe8\xdd\xb5\x75\xde\x2f\x2e\x9f\x72\xa9\x58\x95\x29\x9c\xba\x72\x31\x9f\x8b\xba\x91\xfa\xee\x64\xda\x1b\x8e\xbd\xe3\x45\x33\xe0\xd5\x9f\xac\x6c\x10\xc3\xe3\x83\x32\xa2\x22\x3a\x4f\xae\xa8\x9e\x88\xab\x2b\xde\x40\x0b\x8a\x3a\x82\xcf\x80\x09\xee\xb5\xb7\x43\xad\x9d\xad\x75\xf5\x08\xec\x6d\xbd\xf3\xc5\x6a\x45\x4e\xbf\xda\xb8\x4d\xaa\x5b\x11\x16\x7d\x1a\x3e\x63\x24\xd0\xed\x8a\x30\x72\x2b\xae\x59\x5d\xf3\x29\x7b\x21\xc4\xc7\x77\xde\x2c\xd3\x16\x87\xc6\x35\xac\xb1\x31\xb1\xb4\xf0\xa8\x36\xe5\xe5\x25\x9b\x2e\x66\x26\x4d\xb7\x2e\x2b\xd3\xec\x1e\x6f\xd9\x79\xbe\x36\xf3\x87\x5a\xfb\x70\xd1\x1f\xdf\xc0\x44\xf2\x70\xa2\xf1\xfd\x0b\x31\x5a\x41\x72\x02\x7d\x3c\x07\x1a\x98\x15\x59\x83\x49\x5d\xad\x35\x13\xd5\x88\xce\x4a\xd3\x1a\x85\x7c\x2e\xd4\xb0\x6b\x26\x2f\xe3\x89\x76\x17\x0a\xd1\x38\x38\x99\x1a\x11\x98\x2e\x98\x9d\xb9\x9e\x9c\x3d\xe9\xd0\xed\xba\x01\x7f\xae\xc8\xd9\x42\xb5\xa0\x98\xbf\x7c\x48\xae\x59\x2d\x15\x77\xd1\x1f\xed\x0d\x46\xdb\x83\x51\x9f\xe8\x03\x9d\xd5\x6f\x8a\xf2\x63\x71\xc1\x5e\x17\x57\x2c\xef\x6b\xb6\x7b\x2a\xae\xfa\x2b\x4c\x9a\xc1\xe9\xe9\xbb\x67\x4f\xde\x3e\x7b\x7f\xfa\xf2\xf5\xfb\x67\x6f\x5f\x1f\xbc\x7a\x77\xfa\xf4\xe8\xf4\xf5\xd1\xfb\xd3\x5f\xde\x3d\x3b\x3d\x7a\x7b\xfa\xfb\xd1\x2f\xa7\x1f\x5e\xbe\x7a\x75\xfa\xf8\xd9\xe9\xf3\x97\x6f\x9f\x3d\xa5\xbf\x94\xa4\x31\x4e\x9e\x6f\x44\xdd\x14\x33\xfa\x5c\x95\xa8\x71\x3e\x3d\x3a\x84\xab\x4f\xb2\x2b\x8d\x48\x3a\x0d\xb6\x32\x8a\x98\x5e\xfb\x96\x79\x7b\xd4\xb6\x60\xc2\x9b\x62\x6a\x9b\x83\x75\x36\x9c\x86\x99\x49\xe5\x16\x0f\x1e\xe0\x54\x0e\xb0\xb5\xf7\x80\x1c\x81\xe0\x7f\xf0\x91\xdd\x18\x1f\x0f\x27\xd8\x8b\x10\xaa\xe9\x44\xa8\x66\x70\x3e\x5b\xc8\xcb\x77\x37\x55\xd9\xe6\xf2\xd7\xbb\x74\x8d\x1e\xf8\xd0\x35\x5d\x91\x61\x75\xfc\x9c\xe8\x60\x09\x8e\x14\x88\x8e\x6b\xce\x12\x9f\xc3\x2d\x65\x2b\xbe\x89\x25\x7c\xe9\x98\xae\x86\xf4\x86\x8a\x2b\x24\x4d\x9b\x17\xfc\xbb\x0d\x8e\x4c\x83\x86\x31\x74\xca\xd9\x83\xa6\x0b\x51\x7a\x70\xd5\x4c\x1a\xdf\xf1\x6d\xf7\x7a\xac\xeb\x76\x95\x65\x28\xb9\x26\xd8\x31\x98\x81\xf4\x46\x11\x33\xd9\xd9\x88\x39\x53\x23\x3e\x53\x5d\x98\x86\x66\xfc\xc6\x32\xe4\x0c\xa8\xd2\x54\x93\x33\xa9\x58\x86\xe0\x65\xb4\x2b\x62\x64\xb0\x26\x7a\x9a\x01\xff\x17\x18\xfd\x78\x38\x7a\xa1\xde\x2d\xce\x9a\x9a\xb1\x97\x55\x23\xba\xaf\x9c\x5a\x5e\x68\x20\x5c\x75\x2f\x9f\xdf\xa8\xcb\xa5\xdb\x63\x9d\xbb\x30\x75\xed\x7b\x10\x2d\xbe\xee\xae\x37\x22\x35\x0c\xd5\xd0\x25\xea\xe8\xd2\x8a\xa4\x68\xd5\x5f\x48\xb6\xa1\xb8\xcd\xb2\xe9\x8f\x41\x4d\xa7\x4e\x53\x5a\xa1\xbd\xfb\xf8\x2b\xb5\x5d\x46\x5f\x52\x10\x30\x16\xeb\xe4\x00\xb4\x0b\x7f\xe8\x23\xe7\x13\x62\x1d\x32\x29\x8b\x0b\x30\x87\xab\xd8\xcc\x5e\x4e\x01\x19\xb4\xb7\x09\x59\xd0\x20\x4c\x43\xc8\x95\x95\x38\x3c\xe2\xdd\x9a\x54\xe2\x13\xc2\xe3\x12\xc1\x6e\x22\x36\x60\x8a\x3d\x5e\x35\xec\x24\x6b\xde\x6b\x55\x8b\xba\x57\x63\x52\xaf\x56\x64\x4e\x9f\x16\x8d\x22\x88\xea\xf3\xb8\xbd\x8e\x6c\x62\xbe\xee\xbd\xf9\x8a\xc4\xf7\x36\x3b\xbe\x49\xd0\x4d\x4d\x86\x84\xe1\x1c\x95\x94\x91\xa0\x78\x41\x86\x8a\x23\x14\x09\xba\xce\x68\x34\xc2\x06\xaf\x08\x0f\x07\x51\xce\x58\x51\xdb\xf7\x0a\x27\x8b\xf6\x10\x7b\xa3\x15\x58\x49\xba\x89\x9c\x8b\xba\x64\xcf\xeb\xe2\x8a\xbd\x8d\xc8\x95\xe2\x39\x5c\x74\xd4\x73\xaa\x57\x6b\x30\x67\xb5\xba\x2a\x40\x62\xe9\xa9\x2d\x54\xb3\x26\x97\xf6\x97\x1f\x23\x39\xb3\x65\xe1\xc8\x12\x84\xf0\x8b\x5e\x8a\x4a\x8a\x19\xb3\xb1\x62\xed\xa7\xaa\xaf\xd9\x41\xc5\xaf\xe0\xa2\x0e\x23\x1d\x77\xe1\x8c\xa9\x5f\xb3\xbf\x16\x4c\x36\xf1\x07\x59\x66\x1a\x1f\x30\xd8\x1f\xfd\xf7\x97\x5c\x6e\x9c\xd5\xe2\x93\x64\xf5\xc6\x54\x30\x59\xfd\x57\xb3\x61\x58\xc6\x8d\xce\x26\x06\x1b\x87\xc5\x47\xb6\x21\x17\x35\xdb\x68\x2e\x8b\x66\xe3\x46\x2c\x20\x60\xe8\x46\xb1\x31\x17\xb3\x9b\x73\x3e\x9b\x6d\xf0\x6a\x43\x07\x0a\x35\x4d\xcb\xc1\xc6\x65\xd3\xcc\x65\xfe\x8f\x7f\x9c\x9f\x0d\xae\xd8\x3f\xf4\x49\x6f\xeb\xcb\x3e\x26\x5d\x53\xb9\xfa\xbe\xf1\x76\x81\xe8\x3f\x34\xdc\x55\xa7\x4e\xfe\xbc\xdb\xb1\xe9\x5c\x6d\x05\xfc\xd5\x4d\x73\xae\x77\xcc\x2a\x0c\xc6\x3b\xfd\xd6\x1d\x67\x2a\xde\x3b\xd4\xc9\xfb\x2e\x68\x6f\x44\x6e\x34\x89\xb8\xa6\xf7\x46\xe4\x80\xee\x92\x53\x3a\x1c\x77\x6c\x85\x8d\x94\x3c\x3c\xa2\xa7\x6a\x73\x84\x5b\x80\x7c\xc3\x4e\x61\xf8\x76\xf8\x88\x2d\x97\xa3\xad\xdd\x87\x6c\x92\x2c\x5c\xfc\xd1\x46\x53\x7c\x64\x12\x96\x40\xf2\x86\x5f\xb3\x0d\x5e\x35\x1b\x67\xac\xf9\xc4\x58\xb5\x31\xdc\x28\xaa\xe9\xc6\x68\x6b\x97\x6c\xa8\xcf\x78\x75\xb1\x71\xae\xbe\x54\x7c\x84\xb4\xc1\x6b\x9b\xcb\xa2\x52\x75\x36\xce\xe7\x72\x83\xcb\x8d\x4a\x34\x1b\x8b\xca\xa0\x02\x9b\xf6\x71\x7e\x40\x87\x0f\xd9\x04\xe2\x96\x9c\xcf\x84\xa8\xd1\x88\x6d\xff\x83\xe1\x7c\x57\xdf\x0c\x3f\xe9\x34\x62\x11\x85\x25\x5f\xe8\xa7\x81\x6a\x60\x6b\xac\xff\x8e\x06\xa2\xba\xd2\x55\x68\xe7\xe5\xf7\xc6\x09\x91\x52\x1a\x7b\x4a\xd9\xe6\x01\x70\x4d\x37\x8a\xda\x32\x3c\xf9\x32\x98\x0b\xd9\x98\x1e\x4d\xb8\x24\x14\xac\x94\xbd\xf3\x54\x96\x10\x77\x7c\x40\x2a\x63\x35\xab\xbe\x4b\x49\xeb\x0d\x65\xe4\x62\xb9\x54\x6d\x0e\x49\xc7\xc7\x29\x2d\xad\xf0\xed\x35\xbd\x8c\x98\x13\x86\xd2\x89\x40\x4a\xc4\x94\xc4\x9e\xa1\x6b\x0c\x88\x15\x88\x0b\x8f\x12\x4d\xa2\x16\xbb\x30\x1d\xac\xa4\xc1\x41\xea\x7a\x23\x85\xb9\x37\x7a\xf4\xe8\xd1\x88\x08\xca\x8e\x6b\x90\xc7\xf4\xbc\x2b\x93\xc8\xb2\xe1\xc3\xd7\x3a\xd3\x97\xcf\x9b\x7a\x5c\x9f\xd0\x86\xb0\xe3\xea\x84\x0a\x52\xd1\x3a\xe8\xfd\x7d\x70\x39\xf2\x41\x7b\x18\x65\xc7\xc3\x13\xcb\x1a\x07\xe6\x4f\xc1\x05\xfe\x78\x78\x12\x79\x51\x05\x73\x98\x8b\xb9\x8e\x2c\x57\x99\x44\xa8\xc7\xc3\x13\x6a\x93\xf0\xeb\x59\x0c\x89\xf0\x93\xad\x1f\x8a\xb1\x95\xc8\x6c\xfd\x37\xaa\x37\x47\xf8\xde\x88\x14\x94\x1d\xf3\x13\x22\x29\xdf\x1c\x91\x92\xb2\x63\x19\x77\x58\x64\xd9\xf0\xd1\x6b\x54\x90\x0a\x63\x57\x58\xea\xc2\x92\x14\x78\x82\x60\xe2\x25\x51\x5f\x42\xf2\x20\x89\x73\x5d\x56\x10\xd5\x34\x94\x71\xef\x77\x13\xc0\xd1\x35\x53\xa5\x70\x0c\x9b\x73\x59\xa0\x37\x9a\xee\x6c\x11\xaf\x13\x77\x72\x51\x37\x2f\xab\x29\xfb\x7c\xaf\xf1\xcf\x61\x7c\x8d\x6a\x02\xa6\x26\xd3\x7b\xcd\x80\x4f\x81\x22\xbd\xa2\xc7\x27\xe4\x99\xfa\xef\x1d\x1d\x91\x27\x9a\x34\x7d\xa4\xdb\xe4\x2f\x08\xa6\x06\x39\x9e\x69\x6f\xe4\x4d\x62\x1f\xa3\x20\x56\x6d\x43\xdf\xa3\x67\xce\x20\xbf\x89\x92\xed\x7a\x4d\x23\xfe\xac\x2a\x79\x28\x34\x3a\xa2\x11\x68\xec\x28\xb3\x71\xe6\x54\x25\x12\x8c\xbb\xe5\xa8\x4e\x8e\xd0\x2b\xc5\x55\xe8\x4e\x43\xd5\xa1\xb9\x0a\x3c\x85\x24\x9b\x88\x61\xd2\xfb\x80\x3d\x2d\x78\x8f\x5e\x61\xfc\x41\xed\xbd\x1a\xfd\x16\x65\x59\x8b\x06\x9f\x65\x02\xbd\x21\xc1\xd8\xee\xb1\xb0\x93\xdf\xf4\xc6\xd4\x10\xc9\x32\xdd\xd9\xff\x8f\xbd\x37\xe1\x6a\x5b\xd7\x16\xc7\xbf\x8a\x9a\xff\x5d\x5c\xfb\xe2\xb8\xb2\x33\x00\xe1\xf8\xf0\x0b\x43\x0b\x85\x00\x2d\xa1\x70\x1e\x97\xc7\x53\x1c\x25\x98\x24\x72\xf0\xc0\x90\x3a\xdf\xfd\xbf\x34\xd8\x96\x13\x87\x86\x16\x28\x3d\x87\xe5\x16\x2b\xb6\x26\x6b\xd8\xf3\xde\x72\x14\x55\xa5\x23\x05\xc5\xf1\x81\xbd\xd5\x38\x58\xce\xba\x42\x54\x6d\x83\xb5\x1d\xb7\xb0\xb1\xb0\xa0\xbc\x53\x36\x26\xbe\xea\x4f\xa2\x46\x11\x5e\x58\x78\x87\x14\x55\x5d\x8d\xb5\x49\x1b\xc9\xe0\x65\x8c\xeb\xbf\xa5\xcf\xe3\x99\xda\xd0\x87\xc2\x2a\x86\x99\x11\x08\x15\xbb\x3f\xd5\xce\x1f\x16\x51\x57\xa7\x69\xce\x5c\x7d\x8b\xbd\x26\xb5\x63\xd7\x36\x2c\x3e\x88\x0b\x0b\x77\xca\x9e\xaa\xad\x2b\xb1\x1b\x2b\xfd\xb9\xca\x3f\x52\xb2\xde\xdf\x50\xb9\x52\x3c\x8e\x07\xc0\x7d\x2e\xe4\xb1\x0e\xf9\x58\x87\xd2\x58\x13\x55\xeb\x53\xd0\x29\x16\x6b\x3f\x61\x5b\x93\x25\xe9\xb1\x25\x29\xcd\xc8\x15\x9d\xf6\x09\x3b\xc6\xd8\x97\xa8\x68\xc4\x07\x73\xc5\xae\x93\x15\x38\xe1\x2a\x26\xc5\xc6\xcf\xba\x3e\x19\xb8\xbc\x3a\xa1\xb8\xae\xe0\x12\x47\xe0\x5f\x2c\x5f\x46\xfa\x3b\xed\x3e\x4e\x8c\x92\x2a\x32\x36\xde\x19\x0c\x70\xdb\xa1\x9c\x5d\xfc\xda\x90\x5f\xef\xb9\xb7\xc9\x8b\xb2\xfc\x62\x9f\x92\xaf\xfd\xe4\x5d\x49\x7e\x77\xe8\xb9\x1d\xa7\x9f\x78\xb7\x4b\x6f\x8e\x7d\xec\xad\xf7\x5d\xbb\xc7\x2c\x81\x45\x59\x33\xc3\x66\x32\x22\x6c\x63\xea\xc4\x5f\xcc\xce\xda\x96\xd7\x54\x86\xa8\x88\x43\x93\x6f\xdd\x61\x3b\xa4\x05\x64\x6c\x73\x12\x45\xd7\x51\xa4\x24\x5b\x2b\xcb\x66\xa6\xe2\xa9\x43\x79\x81\xe6\x10\x3a\xbd\xc9\x72\x1f\x98\xde\x52\xb6\x05\x9b\x2e\xc4\x16\x9d\x5c\x8e\xe0\xbb\xac\xb2\x45\x2c\x8d\x5e\xb2\x34\xc4\x8a\x10\xb6\x26\x1c\x04\x94\x26\x8f\x5a\xb2\x7a\x63\x0e\x4e\x7b\xab\x3d\x2b\xc8\xca\xb5\x53\x61\x4a\xcf\x22\xe3\x4c\xeb\x43\x14\xfa\xf9\xa3\x34\xc1\x7b\x33\xda\xfd\x10\x39\x24\xb0\xbe\x64\xde\x84\xe4\xc4\x09\x2e\x93\xd9\xcb\xf2\x56\x53\xcb\x3c\xfb\x2d\x62\x01\x8b\x05\x9e\xfd\x22\x6c\x95\xa4\x2f\xc2\xf2\x17\x05\x0f\x7d\x51\x2c\x87\xcc\x59\x33\x1a\xd1\x50\x0c\xa9\xa6\x08\xac\x5c\x12\x1c\x25\xc6\x1b\x28\x66\x97\x91\xde\xc6\x7d\x74\xbf\x6a\x5b\x05\x12\x0e\x5a\xd8\x93\x01\x10\x25\x33\xec\x35\x7f\xd1\xae\xf9\x1a\xca\xc9\x80\x62\xab\xc3\xb5\x24\x55\xa3\xf0\x80\xc3\x25\x64\xd1\xb4\x66\x5b\x7e\x6a\x6f\xf7\xcd\x69\xd7\x8e\x16\x17\xb5\x78\xad\xd7\x88\x96\x01\x9c\x35\xac\x25\xd0\xa8\x66\x6b\x13\x86\xe1\xc8\xb2\x17\x91\x96\xe0\xa6\x5a\xd1\x18\x6b\xf6\x9f\xfe\x9a\x22\x21\x5d\xcb\xd6\x0e\x94\x2d\x0d\x27\xfe\xa7\x1c\x66\xb2\x23\x7f\x95\x2d\x95\xe2\x8c\x35\x47\x51\x6b\x9b\x74\xbf\x50\xf8\x67\x17\x7d\x55\xa5\x24\x83\x54\x07\x62\x58\x0e\xab\xda\xd4\xe6\x52\x35\x9c\x9d\x9f\x4b\x37\xec\xb7\xff\x72\x70\xbf\x9d\xa3\x3b\x9d\x9c\x15\x8a\x16\x85\xe8\x90\xe1\xa4\x98\x9c\xe0\x78\x29\xc5\x50\x24\x8d\x43\x13\xc7\x3d\xb6\x93\x53\x57\x48\x06\x71\xe7\x1c\xae\x3b\x89\x74\xa2\x08\x29\xd9\x5d\x7a\xeb\xa1\x61\x2e\x14\xe2\xdb\xb1\x17\x77\x6c\xe2\x8b\xf2\xb6\xa3\x8e\x86\xc3\xfe\x3d\x3b\x75\x5c\x4b\x44\x5e\x13\x0b\x7a\x3c\x8f\x2c\xc8\x22\x4a\x75\x45\x4d\x49\x1c\x97\xee\xda\xe4\x97\x43\x7f\x39\xba\x87\x7d\x1c\x9c\x20\x8f\x24\xb6\xb4\xae\x96\xca\x9d\xa4\xee\x4a\x82\x1f\x2e\xd6\x62\x92\x26\x46\xa0\xa0\x77\x96\xe5\xc5\x1b\x87\xb2\x39\x5c\x1c\x56\xa0\x03\x42\xd9\xa9\x43\xcf\x1d\xb2\x33\xa9\xc0\x0d\xea\x3b\x6d\x14\xb8\x9e\x0f\xda\x8e\x87\xed\xa0\x7f\x1f\x73\x53\x09\x2f\x05\x5a\xf7\xec\xa0\x90\xff\x1b\x7a\xee\xb0\x48\x37\x86\xff\x7f\x60\xc8\x05\xf7\x3a\x38\xf6\x71\x5a\x9f\x6e\x5f\x62\xbb\x97\xfc\x54\x54\x10\xb8\x80\xce\x2b\xad\x60\xa0\x83\x2f\x18\xb5\xc1\xc0\xf5\x30\x40\x01\xe3\xb1\x13\x16\x3b\xf4\x71\x91\x15\x2e\xa6\xad\x14\x62\x81\xb8\xaf\x73\xdd\xef\x0e\xb9\x41\x9e\x83\x48\x00\xbe\x3a\x6e\x9f\xcd\x7e\x41\xf3\xe5\xb3\xc8\xa4\x13\xed\xc7\xdc\xed\xe6\x3a\x74\x3c\xdc\xb6\xb0\x58\x94\xdf\x90\xe7\xa1\xfb\x1a\xd6\x5a\xae\x4b\xf7\x22\x2d\x5a\xc3\x1a\xdf\xf8\x35\xac\x71\x88\xc2\x36\xa9\xe7\x90\x2e\x4d\xdc\x0f\x5a\x2c\x2b\x22\xb4\x1c\x2b\x7f\xd0\xa9\x05\x5a\x62\x0c\xa7\x49\x96\xea\x35\xac\x39\x42\x0d\xc2\x32\x11\xb7\x8d\x93\x6a\xd9\x13\x97\xe0\xf4\xce\x8a\x04\x9a\x7f\x89\xd8\x1d\xdf\x21\x3b\xa8\x05\x5a\x76\x18\x6b\x8e\x36\xb5\x2a\x6a\xee\x38\xd9\x5b\x7a\x92\xd3\x22\x94\x41\x9c\x57\x88\x59\x10\xfa\x15\xa1\x55\x39\xac\x1f\x1d\x5d\x34\xb7\x77\x8e\x72\x75\x2b\xdf\x93\x8d\x06\xfa\xc5\x05\xf6\x1b\x2e\x05\xe5\x29\xa1\x4a\x14\xa8\x6a\xae\xa5\x20\xc5\x53\x35\xa4\x10\xc5\xa0\x00\xc6\xb1\x68\x72\xc9\x50\xd5\x55\x96\x30\x55\x69\x57\x20\x89\x93\xc3\x0b\x0b\x58\xaa\x77\x0d\xd7\xbe\x25\xe8\x46\x9a\xf6\xf4\x30\xdb\x77\x0a\x06\xf1\xf8\xbb\x1d\x90\x68\x03\xe8\x26\xa0\x23\x94\x6c\x04\x42\x97\x38\x5b\x99\x08\xd8\x7d\xe4\xfb\x00\xf9\x00\x25\xe0\xa0\x20\x9f\x29\x92\xd6\x8e\xa5\xea\xbe\xe0\x0e\xf6\x30\xb1\xe3\x3a\x29\x7c\x00\x97\x88\x89\xa4\x5a\x18\x13\xe0\x10\x27\x70\x50\xdf\xf1\x71\x1b\x14\xe9\x76\xc2\x9e\xa2\x66\x72\xd0\xf6\x71\xbb\x90\xa8\x10\x82\x28\x8a\x51\x5a\x2a\x05\x0b\x64\xa9\x92\xf4\x78\x0d\xd7\x24\xbb\xed\x7e\xd2\xc9\xdc\xcc\x09\x98\x0d\xf2\x07\xe4\x88\xf6\x0e\xe0\xbb\xa1\x87\x7d\x9f\xc5\x07\x0c\xfd\x00\x60\x27\xb8\xc4\x1e\x68\x61\xc6\x0e\x02\xd7\x93\x46\x48\x63\x40\xa2\xb0\x18\xb7\xa0\xae\x4a\x5e\x6f\x96\x50\x5b\x71\xa5\x83\x12\x2c\x2c\x04\xe9\x4b\xed\x9b\xed\x12\x3f\xf0\x42\x3b\x70\xbd\xda\x37\x66\xfd\x40\x37\x11\x09\x07\xd8\xa3\xc0\xbb\xf6\xce\xd0\x6e\x3d\x27\xe0\x69\xa8\xd9\x2e\xe9\x38\xdd\x50\xbc\x83\xe3\xb1\xaa\x05\x0b\x0b\x8a\x68\xc3\xc7\xc1\x61\x5c\xf5\x41\x67\x2d\xf7\x29\x1b\x9c\x1a\x5d\x4a\xac\x17\x17\x17\x19\x8b\xcd\x30\xc5\x0b\x67\xe7\xb1\x55\x95\x4b\x32\x7a\xd7\x80\xcb\x31\xb0\x3a\xd6\xdc\x4e\x27\xfb\xca\x0a\xf4\x8e\xd3\x0f\xb0\x97\x8d\x43\x13\x13\x3f\xef\x2c\x0b\x33\xcb\xa0\x2e\x0e\x6a\xd3\x04\x26\x1e\x6b\xbe\xfc\x82\xa9\x43\xb8\xeb\xc7\xb4\x0d\x85\x54\x2d\x8f\x56\xa8\xaa\xe3\xf1\x38\x89\x6f\x93\x67\x3b\xa1\x21\x6d\x68\x15\x2e\x84\x02\x88\xdb\xdc\x15\x85\xe9\x6f\xb1\xb0\xa8\x40\xcd\x89\x8b\xab\x8a\xba\x58\xb8\xb8\x28\x68\x9d\x0c\xca\x4c\x06\x2a\xc6\x92\x81\xe6\xad\xfa\x1c\x21\x12\x55\x3a\x95\x79\x52\x71\xa4\x39\x56\x9d\x82\x4b\xc5\x55\x35\x64\xc1\x55\xf4\x87\xbb\x8a\x16\x17\x55\xe7\x0c\x9d\x4b\xaa\x24\x74\x9e\xc4\x21\xb2\x3c\xcb\xe6\x15\x73\x6e\x41\xe0\x5e\xac\x9d\xd1\x87\xe7\xba\xed\x12\x1b\x05\x8a\x43\xa1\x88\xa7\xe3\x81\x13\x04\xd8\xb3\x42\xc5\xa3\xcb\x2b\x0e\x8a\xa6\x6a\xb6\xe2\x51\x0e\x3e\x66\xf2\x98\x45\x81\x46\x24\x63\x30\xca\x34\x48\x46\xda\x53\x84\xcd\x6a\xe2\xff\xf3\x6d\xac\x9e\x0d\xcf\x85\x0f\x29\x6f\x8f\x12\x48\x72\x65\x49\x20\xc3\x13\xa7\xdf\xff\x82\x6d\xec\xdc\x70\xf3\x83\x49\x1d\x22\x77\x58\x49\x3b\xca\x6c\x49\x79\x97\x63\x55\xcd\x44\x0e\xe6\x6c\x11\x47\x7a\x13\xd1\x6c\x15\xc5\xb1\x88\x6a\x59\x96\x82\x2c\x4f\x5d\x83\xef\xd8\x39\xcb\xc6\x7b\xc7\xb2\x2c\xe3\x3d\xaa\x39\x3c\x58\x08\x62\x44\xf0\x9a\xcb\x4f\x9e\xcd\x63\xbf\x83\xb5\x80\xad\xb6\xa9\xf3\x56\xdd\x88\x85\x02\x94\xbf\x99\x1d\xaa\x96\x74\x45\xe5\x47\xf7\x39\x1a\xca\x8e\xc4\xa4\x6e\x36\x5d\xad\xe9\x77\xc5\xc6\x88\x63\x8d\x8c\x15\x4f\x4f\x7d\x62\x57\x3b\xd3\x87\x66\x5a\x8a\x42\xe2\x29\x70\xe3\x65\xaa\x73\x18\x29\xa1\x77\xba\x0c\xf9\xa1\x80\xf2\x4e\x99\x5a\xb7\xf8\xb9\xd6\x2d\x4e\xd7\x6d\x20\xaf\xdb\x20\x7f\xdd\x32\x15\xbd\x25\x20\x1f\x8b\x1d\xc6\x8c\x89\x29\x09\xeb\xe9\x2e\xe1\x0a\xdc\x89\xbd\xcc\x26\x46\x81\x91\x97\x09\x11\xa1\x2e\x04\xea\xc2\x82\x27\x22\x59\x07\x58\xc9\xab\x54\x1d\xb3\x0d\x81\x33\x1b\x22\x50\x7f\x60\x0d\xc7\xe6\x0f\x72\x17\x56\xd9\xdc\xca\x4f\x52\x8f\x80\x20\x89\x58\x14\xac\xa5\x8b\xac\x16\xcc\xd8\x3f\x9b\x4e\xbb\x31\x69\xa3\x29\x3b\x74\x9d\x0d\xcf\xc5\xaa\x4c\x1f\xe8\x74\xae\x59\x0f\xc4\xb8\xa9\xab\x92\x59\x27\x5f\x72\xf3\x76\x37\x0d\xb0\x84\xe5\xee\x3e\xb4\xdd\x8f\xa7\xad\x4a\xbf\xdf\xe3\x4e\x67\xa2\xcb\xe3\x49\xe0\xc4\x63\xad\xcc\xd8\x47\x69\x55\x6b\x93\x55\x77\x71\xa0\xa8\x93\x1d\x9e\xb5\x2b\x95\xcc\x20\x25\xbe\xb8\x6c\xe9\xeb\x8e\xcf\xb7\x00\x56\xd7\xf0\x19\x3c\xaf\x61\x55\x49\xe3\x0b\x08\xa0\xc5\x47\x7a\x7a\x23\x27\x4a\x29\x3b\xbb\x95\xd1\xac\xad\xac\x21\x55\xfb\x76\xc8\x0f\x20\xf4\x6a\x1d\x6d\xc3\x25\x3e\xa5\x06\x6a\xed\xf1\x58\xe2\x7e\x12\x3c\xf7\x1d\x5a\x34\x83\x2f\x39\x60\x2d\x5c\x5c\x74\xfb\x6e\x0b\xf5\x2f\x42\xe2\x5c\x87\xf8\xc2\x69\x5f\x5c\xc8\xc4\x70\xce\x58\x9f\x91\x73\x4b\xa1\x7f\xa3\x08\xaa\x8b\xc6\x78\xac\x72\xdb\x6f\x0e\x40\x14\x63\x45\x9d\xcb\x04\x20\x23\xa4\x91\x5a\xf4\xa6\x0b\x4f\xe4\xc7\x39\xd5\x05\x31\x6d\x95\xd2\x53\xc4\x62\xd6\xf5\x07\xb7\x84\xee\x58\xec\x05\xf7\x9a\x97\x0b\xf0\x8f\x18\x2b\xb3\xc6\x6f\xb5\x6f\x63\xcd\xb5\x3c\xdd\x09\xb0\x47\x39\xc0\x28\x2a\xfc\xbf\xff\x17\xff\x28\xb0\xd3\xde\x90\x7f\x4f\xec\x1d\xf9\x7d\xe6\x49\x41\x43\x96\xa7\x07\xee\x11\x63\x95\x9a\xa8\xcb\xb2\x48\xbf\x0b\xab\x59\x12\x3d\xe3\x1a\x96\xa1\x09\x65\xa2\x3d\x5c\x0b\x6a\xa1\xe6\x4c\xd0\x90\xae\x14\x53\x41\x43\x8c\xab\xbd\x50\xbc\x28\x3a\x3b\x4f\xd6\x1b\x33\xf1\xbf\x71\x7b\xd3\xd6\x46\x7c\x5c\x0b\xc9\x01\x9b\xfc\xc8\x86\x29\x19\x00\x73\x85\xa7\x24\x34\xe6\x02\x36\xee\xd6\xee\x49\x24\xb3\x20\x97\x3f\x62\xc2\x87\x80\x32\xcb\xa8\xef\x61\xd4\xbe\x07\x5e\x48\x28\x7b\x56\xe0\xa2\x29\x0a\x25\xfa\x38\xe0\xb6\x1e\xdc\xc0\xa5\xc0\xea\x29\xb0\xa0\x69\xbc\x4a\x27\xee\xc2\x48\x51\xc7\xcc\xfe\x59\x1f\xe0\xe0\xd2\x6d\x5b\xae\x46\x74\xe4\x75\x2d\x27\x56\x98\x21\x8b\x07\xec\xed\x8a\x73\x5a\x12\xc1\xd8\x3d\xd3\x1c\xd1\x47\x7e\x12\xf2\xa6\xaf\xc6\x02\xd5\xb8\x01\x9f\x1d\x51\x5b\x20\xf8\x2e\xe0\x16\xda\xbc\x1d\x95\xe8\x3e\x73\xec\xd5\x2f\xc4\x1d\x79\xdd\xd4\xb7\x3f\xe9\x70\x92\x9f\x9f\x06\x95\x1d\x47\x69\x8c\x3c\x4b\xfa\x70\xfe\x09\xab\x44\x6f\x0b\x8b\xc9\xad\x3b\x1b\x0f\x39\x91\x4b\xdf\x70\x29\x5a\x81\xf7\x50\x6e\x65\x61\x81\xe8\xa8\xe5\x85\xc3\x40\x89\xdf\xf2\xba\xd4\x55\xcf\x92\x26\x47\x9c\xe6\x14\xbb\x54\xb0\x71\x27\x4c\xb0\x4d\x6b\x0b\xb9\xe7\x1e\x0b\xfa\x4a\x07\xcf\x25\x78\x4d\xea\x5d\x2d\xfd\x0c\x26\xdc\x2a\x68\x21\x1b\xf1\x9c\xd1\x13\x48\x95\xbd\xd7\x68\x3d\x35\x5e\xdd\x78\x9c\x8e\x50\x28\x6c\xde\x95\xc9\x21\x10\x13\x2a\x72\x8a\x69\x0d\xf9\xf7\x8f\xc7\x42\xc8\x29\x7b\xc4\xa5\x5e\xd8\x89\x10\xea\x1b\xad\xbb\x16\x7f\x9b\x86\xbc\x6e\x0d\x0b\x58\x94\x0d\x72\x9e\xc9\x2e\x5a\xa4\xb9\xbd\xf1\x78\x8c\xf5\x5b\x0f\x0d\xc5\x49\xa9\x7d\xeb\xdb\x78\x55\xe2\x80\x64\x49\xd4\x30\xf3\xab\x43\x7f\x71\xe2\xea\xdb\x78\xb5\x7d\xe6\x9e\xcf\xc0\x4b\x5c\xaf\x7e\x19\xef\xdb\x6e\x86\x03\xd3\x5a\xd6\xe5\xc2\xc2\xa5\x72\xa9\xdc\x2a\x67\xe7\xaa\xaa\xae\xb6\x16\x16\x5a\x5c\x1f\xc6\x45\x7f\x4a\x4b\x73\x55\x76\x82\x54\x8b\x23\x96\x81\xd5\x91\x38\xca\x70\x26\x77\xd9\x96\x84\x07\x0d\x0a\x33\xcf\xf8\x32\xd7\xe2\x01\x88\xd7\xd0\x79\x3e\x43\x85\xcf\x82\x73\x2b\xcf\xc6\x56\xf8\x85\x50\x88\xc2\x8c\xd6\xc7\x63\xd9\xdd\xab\x9b\xf2\x58\xde\xaa\x9c\xd7\xca\xc2\x13\x49\xb0\x91\x89\x25\x13\x48\xbd\xf0\x34\xa4\x7e\x4b\xac\xcb\x81\xa7\x08\xab\xb1\x24\xf0\x98\x82\xcf\xdc\x73\x0d\x6b\x0e\x5f\xe4\xfc\xc3\xd8\x59\x67\x7c\x8d\x27\xc7\x9a\x79\x5d\x6d\x68\x85\x22\xd6\x9b\x68\x6d\x98\x77\xa4\xf8\x30\x19\xf7\xa1\x56\xb8\xb8\x40\xb7\xc8\x09\x0a\xea\x1a\x8b\x30\xe2\xf6\x6f\xb0\x32\xd4\xc5\x53\x75\x32\xc6\x2a\x1d\x22\x01\x4a\x34\xcc\xba\x99\x09\x9f\xca\x5f\x8b\xb1\x8f\xdf\xab\x35\xa9\xe6\xbc\x1a\x45\x9f\x2d\xac\x21\x25\x9c\xae\x50\xc4\x8f\x9a\xae\x77\xec\x2b\x7d\xbe\x99\xd8\xa0\xd1\x91\x94\xbc\xaf\x3c\xcb\x5b\xf3\x78\x6b\x48\x43\x6a\x0d\x29\xb2\xae\xf5\x3e\xab\xd6\x8e\x91\xdf\x59\x20\x36\xed\x79\xc6\xa6\x97\x88\x20\xc4\x31\x14\xe6\xda\xb1\x14\x02\x04\x32\x8c\x4c\x6b\x13\x3e\xbf\xcc\x27\x36\x86\x05\x31\x50\x0b\x18\x30\x10\xb6\xf4\xbc\x37\x79\x15\xc6\xf6\xc7\xfd\xd5\x60\x12\x9c\xf0\x1a\x26\xa4\x39\xcd\x4b\x0c\xe2\xe6\x99\x99\x14\x93\xd5\xa4\x07\x3c\xff\x9b\x15\xfe\x37\xe0\x75\x15\x52\xbe\x60\xcc\x11\x25\x3b\x16\x20\xf9\x00\xde\x86\xbc\xf0\x28\xc0\xe7\x0b\x2f\x31\x21\xca\xed\x96\xc7\xd6\xe3\xe4\x88\xf5\xc5\xd1\x90\xec\x6d\xbc\x46\xdd\x35\x97\x43\x68\x25\x38\xa3\x14\xab\x1f\xf6\x83\x7d\x34\xc0\xe7\x71\xe0\x42\x8d\x9f\x7f\x28\xdc\xe7\xf7\x5c\x3b\xd9\xd6\xef\xd2\x91\xca\x0c\x32\x5f\xa0\xf2\x10\xab\xd3\x7d\x51\x6b\x6e\x4d\x99\x6f\x54\x93\x11\xe5\xbd\x8b\xe5\xe4\x88\x00\xb1\xb9\xf2\xaa\x97\x62\xf2\xa7\x0c\x14\x85\xec\x7b\xae\x5d\xa3\x84\xf5\x78\xd5\x00\x0e\x93\x74\x32\x9f\xe9\xc0\xbe\xdc\x73\x6d\x0b\x9f\x19\xe7\xaa\x66\xa6\x6f\x84\xb6\x81\xbf\x33\xcf\x69\x0f\x3b\x01\xf6\xf8\xef\xd2\xb9\xf0\x93\x0d\xbc\xfb\x2d\x12\x78\x0e\xf6\x63\xb3\x9b\xb4\xfd\xba\xcc\xc0\x09\x0c\xe5\xb8\x24\x8a\xbe\x8d\x57\x45\x70\x95\x04\xc1\xf0\x93\x01\x00\x1b\x06\x4d\xce\x2d\x87\x8a\xb8\x60\xc2\xaf\x6c\xb3\xd6\x59\xfc\x6d\x05\xe6\xd7\x39\x3e\x97\x5c\x81\x6e\x58\x27\xd5\x38\xd6\x98\x8f\x03\xe5\x9d\x1c\x9f\xe1\x56\x88\x49\x24\xdb\x1c\x97\x6d\xc1\xf4\x70\xe0\xd8\xf9\x72\x96\x9b\x2c\x5f\x1d\xa9\xbd\xbe\xd3\x51\xde\x39\xfe\x3e\xda\x57\xd2\x63\xb6\x04\x35\x58\x34\x24\x9b\x26\xa6\x39\x60\xf6\x49\x8b\x8b\xde\x1f\x89\x41\x0f\xb3\xee\x10\x6d\x6a\x9e\x74\xa8\xae\x80\x55\x67\x1e\x9d\x09\xba\x6e\xd9\xd9\x03\xab\x13\xef\xc5\xc6\x8e\x73\x40\x2d\x18\xa7\xb4\x2a\x5b\xcd\x4e\x6c\x79\xf3\x8d\xfe\xac\x8d\x24\xe0\x34\x4a\xd0\x85\x20\x3f\x44\x6d\x8c\xfe\x78\x07\x13\x93\x9d\xa1\x84\x18\x07\xba\x24\x5a\xb5\x3a\x5a\x27\xf3\x7b\xa8\x75\xce\xd0\xb9\x35\xd4\xc5\xe1\xed\xfb\x4c\xa9\x92\xd0\xb2\x1f\xe2\xe1\xa4\x7b\xdf\x9f\x7a\x9c\x23\x08\xc8\x9d\x81\x85\x05\x2c\xb7\x9a\x98\xc7\x07\xe2\xc4\xb8\x61\x14\xe5\xb4\xc9\x0e\xa0\x90\x3b\x16\x45\x01\xd3\xfa\x50\x1e\x0b\xeb\x03\xe4\xf5\xf2\x70\xf4\xe3\x64\xc0\x1d\xa6\x04\x4d\x85\xc0\x1d\x0d\xb1\x1d\x16\x45\x0a\xa6\x23\x93\xd3\x2f\x55\xd5\x66\xcb\xb5\x07\x4c\x57\x8a\x75\xc4\x08\xab\xe9\xee\x7d\x13\x18\xb4\x86\xc7\x63\xad\xa1\x74\x65\x16\x46\xfa\x71\xe6\xcc\x24\xa9\x34\xac\xd7\x65\x96\xcb\xa2\xdb\x91\x31\x61\x92\xa4\x4b\x0a\xe3\x15\xe3\x2a\x67\x61\x41\x71\xac\x43\xcf\x1d\x38\xbe\xe0\xd3\x39\xcf\xd4\x55\xfc\xb8\x80\x4a\xa9\x89\x44\xc9\x99\x33\xe3\x0a\x51\xd7\x50\x0d\xb1\x95\xaa\xe4\x52\x01\x71\x61\x06\xb9\x85\x54\x20\x29\xc0\x64\xde\x0d\x3a\x48\x83\xec\xe0\x16\xb4\xc1\x03\x54\xa4\x36\x48\x58\xca\xe9\x2c\x85\x33\x0e\x6b\x41\x52\xd9\x79\x61\xcc\xe3\x27\xe5\x49\xaa\xc4\xa9\x6a\x0c\xc1\xb3\x99\x56\x85\x1c\x3f\xf5\x20\xa7\x64\xc9\x0d\xf6\x7c\xac\xa8\x5a\x46\x60\xc8\xa0\x41\x90\x40\x82\xe4\x54\x93\xc4\x28\xd0\xe3\x35\x26\x5a\x38\xbe\xe7\x3d\x8d\x24\x00\x21\x39\x27\x88\x24\x10\x80\x30\x81\x06\xcb\xea\x5b\xb7\xda\x85\xb4\xb6\x32\x6a\x91\x0b\xae\xf2\xab\xe5\x4b\x90\xf1\x4d\x1c\x2b\x89\x41\x11\x91\x66\x1c\x1c\xa7\x44\x59\x32\x06\x3f\x2c\x70\x63\x0c\xa3\x78\x14\x47\x19\x49\x89\x10\x8d\x19\xa4\xc9\x62\x23\xa6\xa4\xc9\x24\x72\x89\x21\x7a\x5d\xd5\xde\xe1\xc4\x6b\x3f\xa0\x03\xc2\x40\x7c\x81\x53\x9a\xba\x7d\x89\xbc\x7a\xa0\x40\x35\x21\x36\xb9\x8c\x54\x5d\x58\x10\x60\x79\x31\xd0\xfd\xbe\x63\x63\xc5\x50\x59\xd8\x90\x4b\xc7\xa7\xe4\x78\xec\xbd\xaf\xf9\x81\x3b\xac\x4d\x0a\xd7\xc4\x60\xca\x82\xbe\xb4\x73\x67\xf0\x5c\x42\x58\x59\xaa\x85\x47\x80\x13\xbc\x2a\x96\xe9\x0f\x8e\x93\x6e\x50\x7f\xac\x4d\x71\xab\xb9\x93\x40\xfb\x10\x57\x24\x04\x33\xf4\xf9\xaa\x44\xc4\xcb\xd1\x23\x91\xc0\xb0\x31\x4f\xc6\x46\x37\x21\x6a\x88\xe6\x7d\x97\x74\x79\xf7\xce\x1b\xa7\x22\xeb\xc9\x19\xe1\xcb\xb4\x68\xac\xba\x7f\x5a\x70\xb5\x58\x4c\x3c\x83\x27\x47\xc7\x3d\x67\xc1\x10\x26\x46\x88\x21\x6b\x0a\x37\x74\x8e\xbe\xd5\x94\xe0\xc6\xa4\xcd\x45\x1a\xf1\xbb\x3f\xac\x64\x15\x26\x36\x06\x7c\x72\x1d\xad\x10\x53\x30\x05\xe6\x5d\x92\x3c\x4e\xc9\x17\x5e\x97\xbf\xb0\x60\x67\x17\xf4\x1f\x4e\x42\xfd\xa4\x8d\xa7\xcf\xb4\x77\x90\x15\x94\xf3\xa7\x95\xca\x25\xa4\xa7\xe3\x58\x90\xe1\x3f\xba\xad\x24\x6a\xc6\x3b\x7b\x5a\xfc\x13\x78\xf7\x80\xc9\x41\x07\x98\x04\xe0\xd6\x09\x2e\xdd\x30\x00\xac\x38\x70\x3d\x20\x7a\x50\xf8\x81\x0e\x8f\xc7\x63\x8d\x4b\x3e\x6a\x59\xf1\x7f\x6a\x71\x3c\x73\xe6\x3d\x3e\xf3\xa9\x84\x6d\x62\xe6\xb9\x91\xb5\x3b\x3d\x8b\xc9\xe6\x74\xb3\x13\x25\x24\xd7\xac\xf3\xae\xdc\x4d\xb1\xb4\xdc\xf8\x40\x2d\x8a\x6d\x0a\x2c\x5d\xe0\x52\xf4\x42\x2c\x40\x61\xbf\xd5\x85\x05\x69\xed\x2c\x2c\x04\x7f\x58\xf2\x57\x33\x54\xc5\x0c\xd4\x05\x9e\x72\xd6\xe4\xf5\x59\xfb\x96\x10\x4d\x62\x13\x61\xb1\x7d\x02\xcd\x59\x53\x66\x41\x2f\x4e\x5e\x49\xcd\x50\x5a\x5f\x88\xcb\xb9\x74\x46\x41\xea\x58\x8b\x7f\x4c\x0c\xf7\x7c\x50\x43\xfa\x66\x96\x65\xf2\xc3\x79\x08\xeb\xb4\x3b\xac\x6c\x4d\x12\x78\x89\x1c\x4a\x02\x7d\xac\x04\xf2\x62\xce\x3b\xc9\x5f\x97\x70\x8d\x49\x85\x7c\x73\xd6\x24\xa1\x17\x16\x62\xa8\x40\x00\x53\x9e\x2f\x50\x35\xee\x27\xec\xf8\x97\x19\x68\x96\x1a\x58\xcf\x5c\x56\x01\x5f\x56\x41\x46\x45\x29\x2d\x2b\x1e\x4b\x81\xc8\x1c\x8a\xe4\x50\x9b\x1d\x71\x22\xcd\xab\x46\x12\x16\x46\xd5\xea\x0a\xa1\x5d\x1c\x6b\x6c\x13\x3d\x57\x17\xf9\x1a\xb4\x92\x03\xc8\x3c\x8b\xcc\x44\x15\x9e\x24\x59\x89\x79\x55\xda\xcb\x18\xa5\xbb\xe3\xf1\x14\x5c\x70\xfa\x14\xaf\xf6\x05\x24\x40\x41\x80\x07\xc3\xa0\xa0\x8e\xb5\x18\xe1\x32\x41\x63\x6d\x52\x3a\x2d\x0f\x55\x82\x9a\xbf\xc5\xec\x66\x8d\xb2\x45\x5a\xca\x11\xd7\x02\x4d\x70\xc0\x35\x32\xd6\x12\x89\xae\xb4\x52\xe2\xa9\x97\xb1\x07\x1d\x5b\x3c\x56\x12\xed\x83\x2a\x4c\xdc\xba\x31\x1d\xf5\x25\x24\x81\x33\xc0\x96\x27\x84\x89\xae\xfa\x2d\xa1\x03\x0b\x1e\x13\xa2\x4d\xe6\x05\x16\xf0\x0a\xaa\xe2\xa9\x39\x26\x47\xca\x24\x31\xe6\x59\xb9\xde\x6e\x94\x5d\x88\xa2\xdc\x57\x3e\xee\x77\x16\x16\xe8\xdf\xf8\xa0\x63\xcd\xb5\xe2\x3e\x49\xea\x2d\xa6\x6a\x5d\x95\xec\xe8\x78\x90\x3f\x2e\x91\x6b\xc7\xb1\x29\x2f\x98\xf3\xdd\x07\xca\xc1\x06\x92\x73\x5e\x0e\x15\x4a\x27\xd4\x51\x5c\x0e\x12\x25\x37\x3e\x4f\xb2\xfe\xd3\x64\x57\x3e\x66\x79\xe8\x63\xee\x88\x7a\x83\xf2\x4c\x8f\x27\xeb\x8c\xb3\xe6\x54\x1a\xbf\x62\xb5\xca\xcd\x58\xe2\xe7\x74\x33\x58\xfd\xc6\xd9\xae\xbe\xeb\x33\x2d\xb2\x93\x89\x7b\xe3\xe1\x8e\xe5\x64\xf4\x81\x9d\xac\xe1\xb0\xfc\x92\xd5\x31\xa5\xce\x8c\x47\x8f\x7f\x80\x17\x07\xde\x69\xb3\x4e\x62\xe2\xb9\xfd\x49\xa7\xe2\x8c\x17\x26\xa6\x79\xfb\x58\xfc\xdc\x69\xb3\x43\x9c\xa4\x27\x56\xc0\x8d\x37\xa7\x6a\x7a\x6c\x3d\x45\x83\x56\x74\xc1\xbe\xb9\xce\x8e\xf8\xb7\x02\x9d\x9f\xf5\xff\x88\x5a\x53\x37\x7f\xe9\x39\x83\x32\xfc\x28\xa8\x4c\x6e\xd9\x1b\x75\xc2\x93\x9b\x1b\xa7\xba\x61\xc0\xcc\xd8\x92\x5f\x94\x35\x62\x2e\xf3\x1a\x51\x96\x2a\xaa\x58\x3c\xb1\x21\x7f\xfe\x3e\x49\x37\x43\x26\xf3\x8c\xad\xc3\x56\x43\x36\x1f\x9d\x31\x81\xd0\xe5\x17\xf1\x1a\x9b\xbf\xf9\x6c\xf6\x87\x3a\x30\x99\x53\xea\x42\xf6\xd5\x5c\x8a\xd5\x89\x40\x32\xef\x64\x33\xf1\x09\x3d\x29\x33\xd5\xcb\x7c\xa6\x80\x41\x9a\x6b\x19\x9a\x63\x7d\x1b\x6b\xec\xb0\x48\xdf\x4a\xa3\x99\x69\x76\xbe\xe2\x62\x61\x21\xf7\xb1\x82\xd5\x55\xdb\xb2\x17\x16\x6c\x09\x98\xac\xd9\x35\xac\x25\x2c\xea\xd0\x73\x6d\xec\xfb\xe7\x14\x3a\x7f\x1b\x27\x4c\xad\x10\x27\xe9\xe2\xb5\xba\x96\x55\xf8\x72\x8e\xa0\xe9\xd8\xbd\xcc\x6a\x0a\x15\xcc\x18\x6a\x99\x17\x62\x62\x66\xc9\xcb\x6f\x61\xe1\x1d\x8b\xef\xeb\x7a\xc1\x91\xed\x39\xc3\xc0\x8f\xf9\x60\xca\x78\x5a\x38\x75\x66\x4c\xd9\xfe\x5c\xff\xc6\x80\x39\x17\x66\xea\x56\x0a\x05\xad\xf0\x9f\x02\xdd\x70\x69\x11\xa2\x05\xe3\xb1\xa2\xae\x4d\x58\x4f\x05\x56\x41\x1e\xfb\x7f\x15\x16\x99\x17\xa6\x87\x48\xdb\x1d\x28\xea\x62\xe1\x5f\x05\x4d\x12\x27\x11\xf5\x1b\xd1\x7d\x37\xf4\x6c\xcc\x4f\x11\x9a\x0e\x29\x4e\xf4\x36\x0a\xd0\xc2\x02\x0f\x81\x48\xd3\x3c\xbc\xf9\x41\x47\xa1\xbc\x64\xa8\x2c\x8a\xa7\x9c\x97\x0c\x12\x59\xdf\x78\x15\xeb\xa8\xdd\x66\x21\x80\xf6\x1c\x3f\xa0\x18\x6c\x6d\xfa\x91\x52\x10\x9f\x54\x60\xe1\x01\xd4\x1a\xd6\x51\x10\x20\xfb\x92\xe5\x52\x0a\xc9\x27\x17\xf8\xb9\x1c\x72\xdf\xb3\xc3\x14\x2c\x12\x36\x4e\x74\x5c\x6a\x58\xcf\xfa\x97\x4e\x0e\x14\xce\xf1\x41\x5d\xc5\xb3\x3d\x4f\x31\x5b\x07\xec\x4b\xd5\x8c\xf3\x67\xc0\xbb\xe1\x05\x66\xb6\x33\xbc\x1b\xfe\xc2\x42\xc1\x25\x4c\x49\xcd\xb8\x16\x9b\x1d\xaf\x53\x70\x08\xf0\x85\x24\x4b\x84\xf2\x53\x0a\x3e\x5b\x37\x85\xa9\x29\xc5\x96\x3f\x19\xf7\x6f\x35\xdb\x3e\xa7\xbc\x66\x56\xb8\x4a\xf4\xe9\x2e\x58\x99\x05\xce\x2c\x92\x72\x32\x89\x80\x52\xd9\x00\x80\x22\x32\x26\x93\xbe\x0d\x87\x98\xb4\xe3\x17\xec\x8b\xb3\x5b\x2a\x1b\x52\x40\xc3\x94\xec\xcf\x82\xdc\x8c\xc5\x45\x8e\xfd\x2c\x0b\xc2\xcb\x26\x2b\xa5\x89\x0a\x8b\x58\x4d\x8d\xc8\x02\xf6\x96\x9b\xcc\x4c\x9a\x93\x15\x0d\xda\x5d\xb8\x4a\xfe\x48\xc4\x49\x64\x71\x51\x65\xf6\x25\xa9\x35\x19\x59\x34\xce\x05\x03\xf4\x2d\x71\x1e\xc1\x94\x3c\xf0\x6b\x92\xdc\xf8\xcc\x3d\xb7\x90\xe6\x29\xae\xaa\xb9\x8b\x8b\xf4\x4b\x26\xe0\x77\x3f\x63\x14\xac\x7e\x13\xb2\x7c\xe7\x0c\x9f\x4f\x98\xbc\x32\x2b\x82\xa9\xc1\x91\x1d\x17\x69\x21\x2e\x80\xff\xc6\xce\xdd\xa5\x34\x63\x6e\x10\xac\xb8\xc3\x0c\xcc\xd0\x2e\xaf\x26\xa7\x76\x8b\xad\x98\x9c\x20\x98\x3d\x8b\xd7\xa8\x05\x0a\x39\x83\xe7\x99\x87\xa6\x78\xa8\x91\x33\x23\xfb\xa6\x24\xbf\xd1\xc8\x99\x99\xbc\x4e\x1c\xab\x84\xe9\x9d\x90\x5c\xb1\x05\x21\xc5\x09\xa3\x43\xa2\xf1\xf3\x56\xc7\xe3\x71\x7e\x48\x0e\x8a\xe6\xd6\x72\xdf\x70\x66\xae\x86\x6b\x34\x8b\x3a\x8d\xb6\x28\x42\xaf\x4e\x22\xaf\xd8\x0e\xd7\x63\xae\xc2\xb1\xf5\x8f\xac\x7e\x77\x94\xd8\xe5\x5b\x62\x26\xd2\x89\x01\x97\x88\xab\x9a\x98\xd1\x78\xdc\x2b\x49\x71\x82\xf2\xca\xcb\x24\xce\x77\x6b\xf0\xe3\x70\x48\x96\x25\xd1\x33\x31\x13\x37\x11\x11\x84\xae\x08\x96\xd3\x89\xa2\x77\x44\xa5\x74\xc1\x64\x09\x22\xd5\xa2\x4d\x16\x97\x9c\x6b\x08\x7b\x22\x58\x8e\x40\x36\x79\x00\x82\xd6\x14\x61\x72\xe4\x4c\xd9\x0c\xdc\x5a\x98\x66\x18\x8f\xdf\xc9\x48\xcc\xbb\xff\x46\x72\x55\x14\x12\xc2\x4e\x93\x35\x47\x34\x80\xd5\x6f\xc4\x72\xc6\xac\x27\xb9\xc5\xe5\x81\x5d\x93\x7f\xd4\x50\x5a\x85\x67\x21\x0a\x89\xb8\x9b\xac\xd6\xb7\xce\xce\xb5\x90\x92\x1c\x43\xab\x28\x39\x39\x77\x28\xe0\x5b\x58\xb0\x17\x16\x14\xf6\xd6\x16\xbb\x65\xad\x6f\xd9\xb1\xcd\x68\x5f\xad\xd1\x42\x5a\x3f\x89\xc6\xd3\x56\x64\x3b\x84\x36\xa7\x04\xde\x85\x09\xa4\x56\x3a\xea\x6a\x48\xb7\x6b\x0a\x9c\xfa\x49\x18\xc4\x55\xce\x51\xdb\x56\x9f\xf5\x6a\x75\x71\x71\xf8\x47\xb0\xaa\x52\x4a\xe6\x6c\x78\xae\x7b\x21\x51\xd4\x55\xd6\x60\x5a\x6a\x6c\xc7\xd1\x66\xde\x19\x93\xa7\xb7\x7a\x96\x65\x65\x98\x21\x31\x3b\x59\x0a\x9b\xaf\x19\x9a\x17\x45\xd1\x3b\x4f\x5d\x58\xc8\x2b\xe3\x65\x6a\xd2\x26\xab\x60\x53\xa2\xe0\xfc\xe5\xe2\xc9\xcb\x65\x7a\xb1\x78\xf2\x62\xe1\x86\x37\xb2\x25\xc0\xa5\xc4\x34\x76\x42\x12\x33\x8d\xcc\xd9\x47\xd6\x79\xb6\x28\xbf\xe4\x26\x24\x5a\x8e\xca\xe1\x41\x34\xc0\x0c\xb7\x26\x1e\xff\x69\xa4\x61\x6f\x2d\x63\x95\x4c\x85\x5f\x8a\x91\x45\xd1\xc8\xa0\x8b\xf3\xd5\xbe\xd0\x65\xe0\x5b\xd1\x7f\x7e\x0c\x6d\x3c\x6b\x51\x14\x46\x91\xaf\x50\x1e\xed\x52\xe6\xfe\x42\x32\xc5\xde\x75\x42\x22\xc0\x66\xaa\x11\x60\xdf\xae\x8e\x35\x57\x0f\x9c\xa0\x8f\xad\x82\x88\x8e\x52\xd0\x5c\x5d\x24\x99\x83\xa1\x8e\xc9\x0d\xa5\xa8\x5d\x0a\xf7\x6f\xe8\x42\x77\xd3\xc0\x4a\x85\xf4\x87\xcf\x33\xb9\xc4\x6a\xd1\xbc\xed\x76\x4c\x7c\xb1\xdf\x2e\xb1\x31\x4f\x74\x3a\xec\xce\xd1\x7d\x26\x0f\x7f\x54\xef\xf7\xe3\xa7\x3e\x7b\x8c\x07\x4e\xc0\x12\x43\x8f\x9d\xc0\x93\x29\x23\x9e\x1d\x10\x3b\x5b\x57\x3f\xa9\x62\x5a\xa1\x75\x76\x4e\x3b\xda\x72\x58\x44\xf4\x2c\x71\x3e\x09\x64\x05\x11\x1f\x67\x9e\xf2\x9d\x2b\xb0\x01\xb4\x6f\xdb\x39\xaa\xac\xf7\x05\xf6\xee\xb2\xed\x78\xf3\x35\xc2\xb2\xce\x68\x22\x1c\x20\xbf\x97\x23\x78\x80\xdf\x73\x07\x9b\xf0\xdb\xd2\x52\x5f\x12\xe1\x6e\xf0\x6e\x62\xc3\x4f\xf8\x64\x4d\xc6\xc6\xfb\x36\x4e\x23\x09\xa4\xaa\x21\xa1\x7d\x73\x3a\xca\xa4\xf5\xea\x84\xe5\x6a\xac\x6c\x27\x89\x9e\x5e\x14\xe0\x48\x2b\xce\x26\x73\x65\x52\xe9\x4d\xcc\xe9\x4d\xd7\x5b\xfb\xce\x7b\xd6\x04\x13\x2d\xd3\x2c\x51\xc4\x4c\xe8\xd7\x72\xdb\xe2\xfa\x52\xb5\xc6\xe8\x35\x7c\x46\xce\x25\x7f\x1b\x3c\xe6\x3e\x6d\xc2\xd2\xd7\x57\x88\xb2\xb4\xac\xaa\x9a\xcb\x92\xcb\x06\x73\x76\xa3\x49\xa8\x52\xb2\x83\xa6\xca\xa6\xaa\xae\x12\xa5\x5c\x52\x57\xb3\xe8\xf7\x71\x3e\x6f\x76\x6a\xc6\x9d\x70\xae\xc8\xf7\x9d\x2e\x89\xa2\x7c\xf1\xa9\xb1\x1a\x4c\xc3\x96\x24\x2c\x2e\x91\x60\x4b\x90\xaa\x4d\x99\x92\x93\xa8\x73\xcd\x1a\x1d\x25\x4a\x28\x9f\x79\xe7\x16\x39\xf3\xce\xd3\x60\x85\x63\x75\x86\x13\x2d\x37\x6f\xcb\x52\x4b\xe9\x38\x30\x1b\x61\x7f\xd8\x77\x02\xa5\x00\x0a\xea\x43\xfe\x50\x0a\xd4\xbc\xd4\x8d\x89\x45\x05\xa3\x74\x58\xf8\x44\x75\xbb\x39\x75\x0f\xa7\xa1\xbf\x46\x64\xfd\x9f\x34\xf8\x1a\x99\x76\x32\xf1\x24\x5c\xc1\x8e\xd5\x87\xab\xee\x1f\x64\xd5\x5d\x5c\x54\x3d\x46\xe5\x27\xf3\xe1\xc6\x8e\x26\x4a\x4c\x6b\xcf\xf0\x8b\xf2\x54\x95\x8b\x59\x54\xdd\x25\x5b\x24\xc8\x86\xda\x23\xa9\x12\xbb\x8b\x83\x8d\x3e\xf2\xfd\x7d\x34\xc0\xbe\x42\xd6\x0a\x94\x89\x42\x5e\xa1\x56\xc0\xb4\x54\x41\xd5\xed\xf8\xf5\x6a\x10\xb3\x5e\xf4\x09\xf6\x15\xac\x15\xf0\x9d\x13\x14\x54\x8d\x5b\xc5\x68\x41\xec\x66\xc1\x9b\x14\x86\xdd\xe9\x03\xd6\xf4\x58\x0b\xe2\xdf\x59\xa8\xfa\xb8\x6e\x71\x59\xde\x46\xa6\x73\x9d\xbe\x7b\x5b\x27\xed\x7a\xbb\xcd\x9e\xe7\x76\xca\x21\xdd\xa9\x7e\x39\xa4\x3b\xd9\x35\xdc\x9e\xab\x67\x71\xbf\x54\xa6\x06\x4e\x5e\xb0\x53\x2c\x27\x72\xc6\x1d\xcf\x66\x74\x2c\xb2\xe6\x2d\x16\x40\x61\xd1\xad\xb9\x39\x23\x9c\xf3\xe9\x6c\xb4\x9d\xa9\x0f\xc3\xed\xa9\xef\xc2\x6d\xf9\xb3\xee\x9c\x60\x6a\xa1\x92\x9c\x7e\xb2\x29\x7d\x78\xda\xe3\xaf\xd6\xf2\x96\x84\xd4\x4b\x92\xe9\xe5\x9d\x13\x64\xba\x78\xe7\x04\xcc\x8f\x32\xee\xdd\x24\x92\x7d\xb8\x83\xf3\x2d\x80\xa9\x1e\x4c\xce\x3f\x7f\x94\xe9\x47\x66\xee\xbf\xd7\x8d\xcc\x74\x7e\x67\x8b\x4c\x75\x66\x62\xce\xd8\x13\xd1\x95\x4c\x6b\xb9\xfd\x11\xde\x3a\x49\x26\xcd\xb3\x72\x04\x66\x9a\x6b\x79\x6b\x8a\xb7\xb0\x40\xd6\xc8\x62\xa1\x58\xa8\x15\x0a\xea\x22\xae\x11\xca\xd0\x0b\xe3\xa4\xa4\x8a\x9a\xab\x4d\x8c\x6a\xcd\x5b\x73\x17\x0b\x45\xfe\xb4\x40\x4b\x2d\x16\xb8\x38\xbd\x70\xae\x65\x3e\x5d\xe4\xa4\xcf\x44\xbe\x4d\x9a\x3c\x1f\x8f\xb5\x60\x4c\xe9\x68\x25\xb0\x3c\x75\xa6\x05\x15\x91\x4d\xa2\x82\x8c\x93\x55\x6a\xb7\x16\xb0\x60\xc0\xb1\xd1\x16\x49\xcc\x47\x93\xdc\x89\x11\x69\x76\x1a\x72\x23\x89\x33\xda\x36\x3b\xa7\xec\xe4\x76\x92\x0e\xa9\xe6\x5a\x64\x72\x9d\xd1\x1d\x3b\x31\xe9\xde\xc2\x42\xc8\x61\x8d\xcb\x53\xae\xaa\x39\x3c\xe5\x30\x9a\x6c\x6a\x61\x4e\x74\x88\x9d\x22\xc3\x24\xf5\xb6\xe7\xf6\xfb\x4d\x77\xa8\x71\x37\x6e\x51\x7a\xd2\x6b\x8b\xb3\x77\xb6\xf2\x6d\xac\xa5\x7e\x5b\xa9\xb7\x15\x97\xf3\x60\x79\x69\x24\x9e\xbd\x13\x62\x39\x14\x3f\xd7\xec\x38\x9a\x36\x07\x1d\x35\xe1\x97\xc6\x7e\x68\x09\x3c\xc9\x3c\xc6\x6d\x2d\x05\xa0\x99\x37\x0e\xe9\x6a\x7c\x3d\x27\x8f\xef\x9c\x40\x4b\xb6\x9b\xfc\x34\xcd\x2b\x55\xcf\x7e\x31\xe4\xea\x8d\x95\xb4\xf3\x92\x6b\xd9\x30\x7e\xc8\x9d\x13\xd3\x45\xec\xd7\x0a\x85\xb1\xc6\x8c\x21\x45\x2c\x84\x6f\xdc\x21\xa1\x63\x0d\x57\x25\x07\xe9\x1f\x70\x27\x8b\x43\x19\x2c\xad\xa8\x0f\x90\xcb\xd9\xb9\x15\xd3\x40\x79\x8e\x35\x29\x4d\xf9\x1e\x25\x50\x6b\xd3\x24\x45\x14\xe5\x1d\xa5\x99\x4e\xe6\x9a\x94\xb6\xa4\x34\x43\x22\x41\x8d\xa9\x3b\xa4\xf3\x55\xd8\xfb\x82\xa6\x48\x39\xb9\x4a\x46\xfc\xd0\x5b\xc8\xc7\x5f\x51\x3f\x8a\x28\x60\x60\x75\xc4\xa7\x14\xbb\x96\x47\x69\x57\xa8\xaa\xab\xdf\x1d\x2b\xfa\xa1\x53\x1e\x74\xf3\xd2\xb2\x3f\xcc\x99\xe4\xd3\x74\xd2\x88\x33\x6b\x53\x79\xd8\xc5\x61\x1e\x74\xaf\xd7\x8a\x94\x49\xa6\x44\xdf\xa2\x92\x3b\x20\xd2\x43\x36\x32\x6a\xa2\x6b\x60\xc3\xc4\x1e\xfd\x88\x57\xa2\x44\x19\x66\xfb\xed\xe1\x61\x1f\xd9\x58\xe1\x51\x25\xba\x5b\x77\x43\xa5\xa0\xfc\x6f\xf4\xdf\xff\xfa\x2a\x6b\x4f\x59\xab\xfd\xf7\xbf\x7e\xf4\x2f\xb5\xa0\x15\xba\x05\x55\x2b\xfc\xcb\x28\xa8\x49\xa9\xf7\xff\xf5\x17\xdf\x77\x35\xd6\xd1\xe4\xd9\xff\xfe\xd7\xff\x4f\xf4\x5f\xff\x3f\xff\xa2\x6f\x0a\xea\x38\x6f\x96\x1e\x5a\xa6\x1c\x8e\xd2\xd1\x9a\x7f\x51\x7a\xf2\x70\xf2\x78\x0b\xb9\x6b\xd2\x9b\x6b\x51\x32\x30\xf8\xb3\xbc\x2b\xca\x70\x67\x48\xf0\x61\xae\x45\x14\xb3\x14\x87\x21\x29\x97\x7f\x2c\xfa\x08\xb7\x7c\x7b\x90\x05\x40\xbf\x96\x05\xb8\x64\x51\xfc\x27\xd8\x80\xb4\x47\x78\xba\x3f\x44\xea\x0f\xa6\x58\x11\xae\x7a\x7f\xe0\x55\x6f\x71\x51\x25\x2c\xde\x64\xd2\x1f\x2f\x8d\xd9\x20\xda\xd9\x73\x3a\xd8\xbe\xb7\xfb\x58\x29\x08\x74\x50\xd0\xe2\x98\xed\x52\x4f\x26\xcc\x7a\x5f\xac\x33\x74\x0d\xe7\xf5\x07\xb7\x7f\x49\x77\x70\x7b\xaa\x37\x19\x42\xfd\x85\xba\x42\x89\x54\xcd\x98\xea\xc7\xaf\x98\x24\xde\x6c\x5e\x6f\x7e\xc1\x14\xb1\x56\x93\xbe\xc4\x84\x2c\x7a\x06\x42\xd6\xb7\xd0\x34\x21\xeb\x4f\x76\x2a\xd7\xa3\xd9\xd1\x50\xae\x03\xbf\x6f\x79\x29\xe9\x24\x1e\xea\x81\x2b\xa4\xd2\xea\x59\x70\xbe\x2a\xca\x9c\xe1\x73\x66\x7d\x19\xd3\x92\x67\xf8\x5c\x80\x15\x87\x71\x2d\x49\xe5\x2c\x63\xe6\xa7\xc2\x48\x18\xe9\x64\x0d\x1e\x1f\x80\xd2\x6e\xfe\x4c\xda\x35\xad\x81\x1f\xb1\x15\xf7\x98\x79\xdf\x91\xa9\x48\xef\x53\xe7\x73\x08\x92\x8e\xeb\xd2\xbe\x8d\x53\x27\x71\x71\x3e\x06\x13\x5b\xf1\x69\x77\x92\xa0\xbc\x74\xf6\x2d\x87\xbb\xea\xc4\x98\x9c\xa8\x7f\x5a\x30\x8a\x14\x37\x96\xe9\x25\x64\xb4\x3b\xa6\x20\xb5\x10\x77\xad\xa0\x15\x1c\x52\x38\x57\x99\xab\xfb\xcc\x41\x0d\x54\xcd\xb7\xd0\x19\x3c\xd7\x6c\x0b\x9d\x19\xe7\x13\x34\xb9\x9b\x50\xd4\x93\x0f\x28\x15\x3c\xf9\x0c\xb7\x33\x8f\x28\x05\x3d\xf1\x7b\xb2\x14\x5b\xad\xa9\xfc\x6b\x82\xd8\x4f\xe8\x68\xcd\xd5\xc8\x9a\x94\xab\xef\x92\x24\x93\xaf\x7d\xeb\xe1\xfb\x5a\x81\x1d\xe5\x57\xd0\x32\xec\x80\x04\x2d\xa7\x28\xff\x2c\x64\x9f\xe4\x18\x32\x70\x76\xac\xd6\x66\x34\x6e\x8b\xc6\x7d\x6c\xbb\xa4\x9d\xdf\xba\x60\x24\xf2\x1a\x4f\xb9\x89\x9c\xb6\x53\x96\x02\x8d\x15\x2f\x8f\xa5\xf0\xa7\x79\x06\x9b\x85\x5f\x8d\x89\x09\xfb\x07\x88\xbd\x69\xd2\x24\x0e\x39\xd4\x40\xc3\x21\x85\xaf\xae\x16\xe8\x03\xec\x75\xb1\xfc\xd4\xb7\x1c\x9e\x75\x87\x07\x0f\xcb\x94\xc8\x25\x7b\x5d\x45\xda\x47\x8a\x6c\x98\x22\x09\x46\xe5\xd1\x56\x15\xc2\xd8\x3d\xc1\x79\x49\xa7\xb8\x10\x55\x73\x48\xed\x1d\xd4\xb8\x9c\xa7\x86\x14\x92\xc8\x7c\x34\xac\x6a\x4c\xc4\xc3\x9f\x72\x69\x0f\x7b\x48\xb9\x3d\xfe\x8c\x21\x13\xac\x8e\xb9\x78\x94\x7d\xc6\x3e\xbe\x0b\x66\x7e\x43\x0c\xc7\x7c\x4b\xfe\x08\x55\xb3\x2d\x47\x09\xb4\x94\xb3\x95\xf7\xb8\x9d\x27\xa9\x4d\x9c\x1d\x6c\xe1\x30\xc8\x3e\xda\xf1\xbf\xa2\xbe\xd3\x4e\x3e\xdb\x51\x63\x77\x6a\x97\x39\xaa\x68\x21\x4f\xf8\xda\xd0\x0a\xce\xdc\x73\xad\x63\xe5\x96\x1b\xaa\x0b\x0b\xef\x86\x02\xc8\x3a\x64\xf5\x5d\x18\x45\xfd\x85\x85\x77\x9d\xb5\x30\x8a\xde\xf5\xa3\xa8\xb3\x16\x2e\x2c\xf4\x17\x16\x66\x96\x56\x68\xbf\xac\x9c\x99\x70\xa4\x99\x20\xd2\x4c\x38\x6c\x26\xd2\x36\xe3\x51\x76\xd2\x51\x4e\x66\xc3\x91\x66\x63\xac\xaa\xb5\x07\xda\xa2\xb3\x6b\x8c\x1f\xcc\xf2\x40\x77\xde\xc1\xf9\xbb\x31\x1e\xab\xaa\x66\x8f\xa5\x28\x80\x72\xd8\x4b\x49\x1c\x33\x81\x45\x99\x17\x40\x4a\x7e\x7b\x29\xa8\x1d\xa0\xa1\x82\x73\x9d\xc2\xf1\x58\xcd\x5b\x14\x58\xfd\x46\xce\x98\x67\x58\xbe\x77\xff\x8c\xf9\xc2\x2a\x3f\x5a\x0b\x8f\xb9\xc5\x9d\x46\xc6\x93\xa6\xc5\x92\x9b\x58\x6a\xbd\xcd\x34\x5c\xc1\x5a\x70\x46\xce\x6b\x4c\x49\x84\x2d\x1c\x45\xdf\xc6\x5a\x60\x05\xcc\xc7\x36\x36\x40\xcc\xf9\x62\xcd\x91\x3d\xd5\xb8\x4f\xa2\x8a\x78\x85\x4e\xa2\xf6\x57\xdc\x33\x74\x6e\x39\x2c\xb3\x5a\x73\xb8\xf2\x17\xa9\x82\x8a\xf8\x36\x4e\x2a\xb0\x59\x49\x86\x3e\xdd\x33\xfb\x5c\x4d\x91\x22\xfd\x29\xe3\xc5\x78\x3f\x9c\xd9\xe7\x94\x24\xf2\xcf\x44\xea\xdc\x22\x4a\x5f\x1d\xfb\x67\x36\x4d\xd9\x3c\x36\x49\x0e\x5e\xf5\xcf\x1c\x91\x9b\xde\xd5\x34\xd8\x88\xcc\x4f\x65\x8c\xdc\xc5\x71\xc6\x67\xc1\xf9\x1a\xfd\x53\xc3\x82\xa0\x08\xce\x73\x98\xbd\x9b\xf8\x04\x1d\x49\x09\xc9\xa2\x22\xe4\x07\xb4\x5c\x4b\xc1\xb4\xaf\x10\xc5\x84\xaa\x5a\x53\x5c\xeb\x8c\x25\xcf\xb5\xf4\x58\x00\x27\xcf\xae\x43\xf1\x2c\x5f\x5d\xf3\x92\xc8\x5d\xae\x5a\xf3\xd4\x28\x4a\x4d\xe6\x2d\x87\x9f\x59\x9c\x59\x62\xd3\xf1\x79\x34\x42\x29\x13\x8f\x69\xbb\x39\x8d\xc2\xcc\x4d\xbf\x8d\x57\x73\x4d\x1b\x71\xac\x1f\x8f\xa2\x3d\xa5\xd0\x70\x99\x4b\x51\xd3\x19\xe0\x91\x4b\x30\x3b\x83\xc5\xf1\xb0\x0f\xf8\x0b\xfd\xca\xd7\xc1\x11\xc6\xc9\xf9\x24\x03\xf6\xf8\x8a\xb9\x58\xbc\x0f\x44\xa9\xf7\x6d\xd7\xf6\xdf\xff\x7f\x2c\xa6\xaa\x13\xbc\x17\xca\xfa\xf7\x85\x78\xa9\x24\x4d\xc6\xfa\x2f\x9d\x79\x6b\x2d\xfa\x94\x80\xe9\xd3\xbb\x71\xbe\x9a\x35\x15\x8b\xb7\xda\x9f\x2b\xd5\x35\x5c\x5c\x5e\xaa\xe1\x3f\xab\xe5\x35\x5c\x34\x57\x6a\xb8\x58\x5e\x96\x63\x87\x24\x96\x10\xdc\xe6\x54\x6a\xc2\xb3\x98\xe9\x96\x6b\x91\x33\xe3\x9c\xf1\xf8\x8e\x65\x68\xc8\x82\x9a\x6f\x19\x6c\xf5\x96\x2b\xcc\x85\xc5\xbe\x44\xde\x86\xdb\xc6\xc2\x75\x50\x09\x2c\x43\xf3\xad\xa2\xa1\xae\x06\x7f\x78\xb2\xe6\x12\x59\x55\xf8\x1f\xb4\x18\x2a\x9e\x5c\x26\x10\x76\x79\xfc\x04\x50\x57\x2e\xe0\xbc\xb7\xaa\x50\x43\x8b\x56\xa8\xb8\x13\x45\xfe\x93\x04\xe3\x41\xff\xf1\xe5\xf0\x27\x19\x25\x2a\xad\x11\xcb\x35\xb2\xe8\x21\x43\x85\xde\x32\x46\x39\xb2\xe1\x57\xbc\xbb\x73\x8c\x00\x3d\x4e\x80\x52\xb0\x91\x50\x8d\x5e\xc6\x2e\x25\x35\xb2\x13\x43\x19\x15\x54\x8d\x58\xc1\x99\x79\x2e\xe9\x2f\x35\xcf\x0a\xce\x4a\xc9\x93\x82\xaa\xb9\x56\x70\x56\x96\xb3\x24\xe1\x8e\x14\xa2\x6a\x1d\xc5\xa3\x7f\x5c\x55\xcb\xf7\x33\x13\x5d\x65\x7d\x64\x07\x6e\x70\x13\x5e\x37\x24\x6d\x45\xc1\xcc\x18\x85\x45\xc5\xaa\xe2\xf2\x7f\x38\xfd\x8c\xcf\x82\xa2\x71\x6e\x19\xef\xe1\x58\x71\xb5\x78\x9a\x54\xed\x1b\x61\x4e\x2b\x74\xe6\x51\xab\xe5\xf9\xb5\xb6\x12\x9c\x19\xd9\xbe\xab\x9a\xdb\xe9\xf8\x38\xa0\x2f\xd9\x79\xcd\x21\x09\x9c\xbe\x5f\x73\xb5\xa1\x3b\x0c\x79\xa4\xdf\x1a\x8c\x82\xb3\xca\xf9\x58\x36\xc6\xe1\x8e\x0f\xb1\xcb\x6b\xa0\xd0\xe1\x92\x66\x61\x20\x59\xf5\xb0\x08\xc2\xc2\xac\x87\x6e\x12\x5f\x36\xeb\x69\xc8\xc3\x1c\xb8\x74\xfb\x71\x63\x6d\x85\x0d\xb5\x3e\x60\xd6\x44\xef\xff\xab\x9c\xa1\xe2\x08\x9c\x2f\xfe\x57\x7d\xef\xa8\xab\x85\x8f\x8d\x26\x73\x5c\x27\x2c\x8e\xf5\x19\x3c\x5f\xa3\xc9\x33\x78\x1e\x17\x38\xab\x17\xff\xe7\xfc\x7d\x57\x55\xd7\x88\x7e\xe5\x3a\x84\x4e\x8c\xf0\xe3\xaf\x29\x52\xc5\x2c\xdf\xb7\x92\x56\x19\xf3\xcc\x67\xf0\x3c\x3e\xc0\x7a\x61\x41\x21\x69\xf8\x0a\x66\x98\x13\x58\x8b\xb1\x7d\x52\xab\xe5\x59\x84\xa7\xf9\x08\x5a\x2c\x7c\x5c\x0c\x3f\x0e\xd8\x33\x25\x1b\xb5\x46\x0c\x08\x7d\x1f\x0f\x08\x2f\x7b\x64\xbb\x1e\x8e\x9d\x89\x69\xd5\xe2\xc1\x54\xc0\x94\x64\x91\x68\xde\xaa\x67\xd1\x25\xa0\x28\x81\x8e\x82\x22\xd6\x51\xa0\xbe\x37\x4c\x5c\x8e\xa0\xba\xaa\x2a\x9c\x21\x6f\x30\xc9\xe6\x26\x45\x77\x34\xc3\xa2\xa7\xaa\x6a\xdc\x5d\xba\xdd\x79\x72\x0d\x5b\xa4\x16\x58\x24\x41\xff\x99\xd0\x19\x19\x81\xa9\xd4\x5d\x16\xfc\x43\xfa\xbd\x96\x79\x5b\xcc\xbc\xab\xe1\xf4\xab\x58\xb9\xe4\xd7\x9a\xf4\xa6\x28\x3d\xaf\x61\x36\x4c\x7a\xba\x0a\x59\xb9\x89\x67\x6b\x53\x4f\x8a\x53\xe5\x6a\x22\x0f\x5d\x86\x7a\xdf\xb5\x51\x1f\x53\x16\x04\x79\x74\x4c\x92\x37\xd9\x70\x1d\x12\x04\x61\xe0\xa3\xc3\x4c\xa4\x73\x60\x88\x45\xc1\x87\x86\x98\x88\xe3\xcc\x3b\x67\x64\x07\x4d\x9c\xe1\x73\xeb\x1d\x9c\x88\xd8\x21\x90\x94\x30\x47\x15\x92\x13\x66\x9c\x65\xc7\x70\x4a\x00\x4e\x06\xdf\x18\xdc\xa2\x04\x85\x67\xa1\x33\x0a\xe5\xc4\x88\xb2\x56\x54\x6f\xc2\x10\x44\x21\x74\xc1\xfa\x14\x60\xbc\x83\x02\x0a\x33\x1a\x5b\xf5\x27\x73\x06\xea\xc2\x82\xcd\x89\x18\x87\x02\xcf\x78\xde\x6d\x39\x20\x08\x37\xf1\xe3\xc2\x83\x1d\x12\xf4\xd9\x21\x6b\x74\x75\x7f\x70\xbd\x01\x0a\x14\x35\x0e\x2a\xd4\x3e\x60\xae\xda\xbe\xa2\xb2\x38\xfd\xff\xe3\x12\x16\xfc\x83\x89\x70\x85\x9d\x5d\x49\x4d\xac\x9a\x47\x0a\x56\x27\x22\x8b\xac\xe6\x60\xdf\x0e\x05\x77\xa0\xb0\x88\x17\x0b\xa0\xe3\xb9\x03\x16\x06\x9d\x76\x03\xa0\xa1\xa3\x81\x56\x18\x80\xb6\xd3\x66\xe6\x58\x97\xe8\x46\x9c\x30\xd6\x46\x01\x62\x47\x8c\xe1\xb6\x5e\x48\x62\x73\x85\x22\x88\x16\x0f\xd5\x80\xa6\x44\x23\x3c\x38\x9e\x95\xec\x14\x95\x6e\xe3\x0f\x61\xbf\xff\x17\x46\x9e\xa2\x16\x4d\x8a\x36\xb3\x7b\xc9\xd3\xa0\xc6\x0d\x8c\x28\xd7\xc3\xf1\x8b\xb1\x4a\xfe\x28\x2f\xb3\x55\xa1\x04\xd3\x05\x08\x2d\x10\xef\xbd\x77\x96\xe5\x8a\x24\x33\x6f\xbf\x67\xc7\x2d\x69\x4e\x1c\xe9\x38\x4e\xe5\x6d\xe1\x2a\x2e\xab\x2a\x13\xa5\x07\x12\x66\x2b\xb3\x86\xf3\x8b\x79\x8b\x84\xf7\x77\x56\xbd\x34\x43\x95\x65\x48\x6c\xdd\xc7\x0a\x93\xab\xc4\x8b\xd4\xb6\x2e\x14\xa4\x72\xb3\xd5\x94\x20\xb5\x33\x04\xad\x38\x44\x9c\x45\xba\x68\x2a\x36\xa5\x4a\x35\x3f\x96\xac\xfb\x4c\xb2\x4e\x74\x9f\xee\x6d\x0e\x1b\xeb\x81\x82\xce\xdc\x73\x35\x31\xa6\x4c\x83\x21\xb1\xd3\x12\x94\x1b\x35\xb1\xbc\xfd\x13\xae\xf5\x29\x70\x4f\xb6\xab\x80\xd1\x72\xcc\x16\x9c\x06\xd7\x64\xaa\x35\x3d\x70\xf7\xdc\x5b\xec\x6d\x20\x1f\x2b\xb2\xd2\xe6\xfd\xfb\xae\x56\xb8\x90\x6d\xb0\x0f\xd2\xdd\xc9\xd6\x08\xfb\xc6\x1c\x82\x91\x4d\xd6\x19\x3e\x8f\x8f\x38\xc7\x59\x8a\x68\xa4\x78\x96\xe2\x5a\x6c\xab\xa6\x14\x83\x7a\x06\xcf\x55\x8d\x50\x0e\x82\xbe\xd1\x58\x28\x5b\x4f\xab\x2b\x48\x73\xb3\x94\x84\x9a\x39\x54\x8b\x29\x89\xac\x51\x7c\xaa\x03\x5d\xba\x92\x0d\x01\xe3\x55\x92\xc0\x8d\xad\x35\x94\xa3\x2e\x42\x6b\x0a\x0f\x3d\xd2\xa2\x93\x47\x0b\x5b\x2c\x14\x97\xc7\x65\x8a\xef\x2c\xab\x49\x79\x1b\xab\xa9\xd0\x27\x5a\x53\x55\xd7\x14\x85\xb7\xc2\x8b\xa9\x1c\xb7\xbb\xaa\x86\x38\x16\x77\x68\x3e\x24\x4e\x3f\x4e\x3a\x7b\x27\x03\xb7\x1f\x1d\x3e\xd7\x1a\x29\x0a\xc9\x1f\x3c\x3a\xb4\xcc\x21\x41\xe3\xba\x19\x8d\xf9\x62\x30\x92\xd6\xa3\xa3\xe9\xf2\x41\xa5\x59\x32\x27\x67\x25\x4e\x51\xa7\xdc\x41\xfb\xa2\x13\x45\x85\xbb\x38\x1d\xc7\xc7\x51\xde\x61\xfd\x02\xc5\xc7\x9b\xb2\xc8\xd0\x17\xc1\x68\x10\x45\x72\x0c\xa7\x3d\xce\x72\xcc\x3e\x35\x32\xff\x04\xc2\xcc\x61\x7c\x93\x87\x2a\xca\x48\x67\x2b\xf5\xe4\xe1\x51\x60\x53\x39\x36\xf3\xac\xe2\x76\x7e\x89\x18\x5d\x83\x5a\xd1\xa0\xa4\xa7\x14\x13\x79\xca\xe8\x99\x12\xfc\x4d\x4a\x6d\x3a\x16\xd6\xc3\xc0\x96\x0d\x8d\xd3\x30\x2c\x2e\x77\x5e\xf3\x39\x08\x66\xc8\x61\x5f\x71\x58\xe4\x00\xd4\x6e\x2b\xae\x3e\x44\x9e\x8f\x15\x47\xd5\x0a\x03\x87\x84\x01\xf6\x0b\x14\x90\x04\x23\x56\xf3\x58\xb1\xff\x30\xa3\xc8\xb4\xd8\x89\x67\xfd\x3f\xaa\xea\xc2\xc2\x5c\xdc\x14\xf8\xd3\x02\xa6\x5e\xd5\xa1\x0e\xfe\x72\x43\x80\x3c\x0c\x42\xdf\x21\x5d\x29\x47\x61\x31\xe1\x97\x16\x0b\x9c\xfb\x92\xb9\xae\x82\xaa\xb5\xe4\x20\x2e\x17\x93\x51\x5b\x24\xea\x93\xdd\x52\xf2\x8a\x72\x62\xec\xce\x1f\x71\x9a\x97\x0e\x12\x4b\xc8\x94\x99\x9f\x50\x49\xe2\x71\x4a\x58\x58\x32\x95\x31\xd6\x2e\x98\x84\xbb\x96\xa3\x96\xa4\x44\xa3\x88\x1e\xc1\x1b\x90\x50\x7d\x86\xa9\x72\x3a\x0a\xf9\xc3\xa3\x28\x39\xc6\x8d\x63\xcd\x76\x43\xee\x4b\x5f\xcb\x97\xe9\x13\x66\x10\x33\x2d\xae\x73\xd5\x07\x42\xe3\x33\x45\xbc\x4b\xb7\x1a\x23\xc8\x13\xe1\x3c\x16\xf6\x95\x74\xc6\xf3\xbe\x84\x47\x3b\xa2\xdf\x23\xf4\x1f\xf1\xd0\xf8\xf2\xe7\x69\xb6\x25\x85\x08\xa0\xdf\xca\x91\x80\xcd\x90\x00\xc5\xfd\x16\x85\xfc\x1a\xa1\xb7\x45\xe3\x9c\x2e\xe3\x33\x77\xcd\x2d\x1a\x35\xf7\x5c\x0b\xfe\x20\x0b\x0b\x5b\x3a\x33\x38\x1f\xb4\x9c\x6e\xe8\x86\xfe\x07\xd7\xbb\x45\x5e\x7b\x2d\xa0\x84\xea\x9f\x5e\xfc\x7e\x87\xb0\x53\x54\xc4\x5b\xc6\xae\xd2\x35\xf9\x87\x7f\xe6\x9e\x17\x29\x71\x9c\x10\x19\x28\x55\xe3\x02\x74\x66\x9f\x8f\x19\x47\x94\x7b\xbe\x7b\xb2\x46\xce\xe2\xd0\x92\x6d\x4c\x21\xdc\xf9\x58\xb0\x4a\x79\xa5\xf6\x94\x02\xc3\x4d\x3c\x07\x73\xfa\x11\x0e\x3f\x43\x0f\xdb\x28\xc0\x6d\x4a\x8b\x75\xd0\x8d\xeb\x01\xb7\x03\x58\xde\x30\xb0\x39\x26\x2c\xa8\x99\x15\x37\xdd\x6e\x92\x73\x66\x87\x67\x15\x1d\xcb\xd1\xae\xb2\xd8\xd7\x9a\xda\x2a\x12\xc1\xbe\xc8\xb9\x4e\xd4\xe2\x41\xdb\xf5\x6c\x87\x19\x25\xa2\x16\xe3\xcf\x55\x53\xde\x8e\x8d\x1c\x7f\x9d\x62\xdc\xb3\xff\xe5\xcc\x98\x56\x28\xa8\x0c\xbc\xd2\x4c\x82\x79\x4c\x08\xfe\xc5\xc5\xb1\xb6\x95\xba\x2f\x40\xbd\xa2\x9b\xcb\x05\x6d\x8b\xf9\x5c\x7e\x4d\xbd\x1a\xb6\xf4\x0b\xce\x44\x12\x9a\xec\x3b\xa4\xe7\x5b\x1e\x4d\x12\x66\xb7\xe7\xd0\x64\xb2\x67\x2c\x57\xdb\xa2\x50\xcc\x3a\xd0\xb6\x74\x9a\xd7\xba\xa3\x09\x17\x65\x0d\x0e\x0f\x04\x27\xe0\xab\xda\x9d\x82\x59\x46\x5f\xd5\xf2\xd7\xbf\x33\x41\xdc\xaa\xe9\x5e\xce\xe0\x33\x62\x29\x4e\x1e\x36\xd3\x03\xf7\x78\x38\x8c\xc9\x12\xcd\xb3\x9c\x09\x96\x9c\x29\xc6\x28\xfa\x1d\x30\x86\x7c\xac\x60\x3d\xf9\x1e\x75\x62\x3c\x12\xf8\x48\xc7\x8e\xb1\x95\x4d\x91\xd8\xba\x73\x7c\xc9\xe6\x04\x60\x45\x66\xe3\xda\x4e\xfb\xe8\xd2\xbd\x65\x5e\x0e\x4c\xd0\x26\x3f\xb0\xde\x41\x6d\x4f\x29\x70\x50\xab\x07\x23\xa9\x3e\xe5\xdf\xcc\x2c\xe6\xdf\xea\x77\x57\xf8\xbb\x6c\xf1\xa4\x60\x41\x55\xb5\x77\xef\x9a\x4a\xa0\xd2\x2e\x77\x43\xec\xe7\x9a\x2f\x05\x14\x29\x45\x91\x12\x58\xb7\x8a\xaa\x6a\x01\xcd\x4c\xb2\x86\x99\x09\xf9\x1e\x13\xa5\x98\x76\xc0\x51\x9d\x49\x76\x07\x33\x4e\xfe\x0c\x9f\x47\x11\x39\xa3\x94\xce\x39\x45\x6e\x9c\x06\x8a\xb9\x20\x7c\x2e\x85\x25\x63\xd4\x27\xeb\x1f\x65\x66\xac\x96\xb6\xa5\x87\x64\x88\xec\x9e\x75\x99\x24\xd7\x91\x8f\xab\xd0\x1a\xd2\x7e\x61\xdc\xf6\xf9\xc6\xb0\xf6\xb5\x3c\xc8\x44\x47\x34\x1f\xa2\x59\xef\x0c\x6d\x2b\x9d\xdf\x1c\x37\x92\x2c\x4c\x8f\xe7\x99\x96\xdf\x60\xa5\x26\xcf\x91\x63\x34\x04\x73\x04\xb1\x28\x39\xa5\x4e\xac\xb7\x77\x0a\xb6\x5c\x16\x58\x9d\x1f\x4c\x2b\x09\x87\x85\xca\x40\x6c\x05\x31\x0a\xc9\xa8\xac\x79\x4c\x11\x90\xa3\x06\xe0\x62\x26\x1c\x43\xc7\xa6\x82\x55\x09\x54\x24\x6c\xd5\x78\xac\xaa\x35\x8f\x4b\xe3\x8f\xb4\x0d\x0b\xeb\x1d\xc9\x60\xa7\x27\x4d\xfe\xf4\x20\x70\xb0\x36\x5a\x13\x77\x0e\x65\x98\xd2\x3b\x89\xc6\x4c\x7f\x48\x12\xaa\xeb\x79\xea\x8b\x1d\x9c\xf3\x3d\x24\xc6\x58\x0f\x46\xd6\x96\x86\x63\xc5\x23\x5b\x0d\xa2\x48\xc8\x8e\x0f\x10\xb3\x9e\x22\x58\x49\x76\x6e\x65\xca\x65\xe2\xd9\x06\xfa\xc5\x88\x52\xde\x94\xd2\x62\x11\xd9\x02\xfd\xc2\xf1\x8f\x9b\x1b\x2c\x14\xd9\x45\x9b\x93\x6b\x34\x89\x54\xfd\xa2\xad\x05\xec\xa7\x9a\xa1\xc7\x02\x99\x1e\x53\x35\x5a\xa5\xe5\xf2\xbb\xca\x9c\x03\x69\x4a\x9a\x87\x40\xd5\x12\x90\xee\xa9\x7f\x18\xd5\x85\x05\xc5\x7b\x6f\x55\xa1\xaa\xa5\x07\xf0\xa6\xf9\x93\x20\x66\xfa\xc5\x68\x55\x7a\xae\x14\x3d\x6e\x55\x7d\x31\xb2\x1c\x1e\xe5\x8b\xcb\x57\x28\x8f\xab\x8e\xb5\x0d\x3a\x66\xd9\xf1\xe0\x5e\xcc\x2c\x7a\x39\x67\x09\xa4\xd3\x91\xa6\x23\x7c\x51\x92\x91\xe1\x47\x40\x97\x15\x3f\x0d\xa9\x85\x01\x02\xbc\xb0\x06\xba\xfc\xf0\xa3\xc5\x02\x38\x4b\xcf\x40\x5a\x2c\x9c\xa7\x62\xd6\x78\x76\x29\x94\xd1\xe2\xa5\x93\x9d\xb2\xf8\x28\x92\x5a\x0e\xad\xca\x3d\x76\xb9\x34\xa1\xe3\x7a\xbc\xb1\x54\xf8\xff\x3d\xd9\x3f\x2d\x57\xa4\x28\xc6\x21\xdd\xf7\xba\xc0\xed\xe3\x38\x1e\xd9\xc5\x48\xcd\xf6\x92\x81\x35\x3a\x6e\xb4\x0e\x66\xcd\xd7\x53\xd2\x1f\xaa\x78\x51\x6f\xb5\xbc\xe4\x05\xfd\x41\x5f\x84\x81\x6d\x5d\x2b\xec\x4e\x7f\x32\xd9\x16\x7b\xc0\x52\x22\x87\x58\xa2\xca\x91\x25\xfd\xd4\xa6\xb7\xc4\x94\x73\x24\x8c\x83\x19\x89\x7d\xa2\x6a\x47\x33\x36\x8a\xaa\xd1\x9d\xa2\xfb\x38\xd8\x9c\x34\x13\x4d\x3d\x79\xb2\x6c\xc2\x4a\x3e\x9b\x90\x56\xa1\xa8\x33\x79\x86\x95\xf9\x79\x06\x16\x35\x43\xde\xbd\xc1\x1a\x5d\x14\x35\xbe\x89\x39\x2c\x3a\xb1\xb0\xce\x27\x54\x60\x0c\x07\xc7\x87\x4a\x26\x01\x45\x18\x4b\xc6\xc2\x89\x4c\xb9\x63\x65\x83\x8b\x9c\xa8\x6b\xca\x09\x47\x2a\x85\x8b\x51\x41\xd5\x92\x1f\xa8\xa0\xaa\xb5\x93\x85\x05\xe5\x24\x1d\x50\x7e\x38\x95\x0c\x51\x53\x95\xd7\xa7\xa3\x83\x7d\xb1\xd5\xff\xfd\xad\x20\x3e\xa9\x50\x2b\x98\xd0\x58\xb1\x0b\x1a\x23\x37\xfd\x42\xed\xac\x50\xef\x78\x8e\x8d\xde\xd7\x5b\x4e\xfb\x0a\x91\x68\xaf\xd1\x04\x1f\x1b\xcd\xa8\xab\x2f\x03\x18\x41\x23\x2a\x9a\xfd\xf6\xe9\xb6\xfe\x39\x2a\x2f\xe3\x4a\x41\x4b\xf2\xdb\xb6\x87\xe2\xdc\x60\x11\x42\x13\x46\xfa\x67\x00\x41\xb1\x17\x41\xc3\x7c\xd4\x15\x15\xcd\xea\x7a\xeb\x54\x5f\x06\xd5\x60\x44\x6f\x0d\xb2\x05\x8c\xf5\x7a\x6f\x56\x62\x03\xce\x7c\xf5\xba\xf2\x44\x65\x43\x1e\xb4\x7d\xe4\x78\x6e\xcb\x61\xc3\xb6\x55\xa7\xc3\x66\x96\x20\xfd\x5b\xae\x44\x45\xd3\xd3\xbb\xa0\x58\x82\xa0\x68\x86\xa0\x68\x7e\xa2\xc3\x58\x32\xa2\xa2\xf1\xa1\xb4\x41\x5f\x95\x36\x47\xf4\xe6\xf6\x1a\x21\x68\x7c\x38\xfd\x14\x95\x97\x32\x13\xd2\xef\x3a\xd8\xf3\xa3\xc3\x46\x13\x9c\x6c\xd1\xff\x47\x4d\xb0\xb1\x45\xff\x1f\x35\xa3\xe2\x8a\xde\xa7\x93\x63\x88\xff\x26\x9c\x9a\xa5\x52\xb9\x54\x2e\x19\x25\x9a\xa6\x09\xd3\x28\x45\x45\x93\xd8\x2e\x2d\x69\xef\xb7\xe8\x6d\xbb\x0e\x81\xb1\x42\xff\x38\x0d\x08\x0c\xc3\x86\xc0\x70\x5d\x08\x4e\x5c\x08\x0c\xcf\x86\xe0\x33\x7d\xbc\xd5\x80\xe0\xb8\x01\xc1\x66\x1d\x82\x9d\x81\x0b\x81\xd7\x86\x60\x13\x43\xb0\x72\x3a\x82\xc0\xe8\xb4\x20\x30\xd0\x10\x02\xa3\xba\x0b\x81\x79\xef\x42\x30\xd8\x1a\x42\x70\x79\xbb\x07\xc1\xd5\x1d\xad\xdd\xa8\x43\xd0\xde\x6c\x43\x60\x2c\xd1\xcc\xc6\x3a\x04\x86\xbd\x0f\x81\xb9\x79\x2f\x52\x46\x87\x3d\xdb\x83\x91\x59\x95\x47\x61\x0f\x75\x5d\x9f\x8d\xef\x49\xbd\x19\x15\xdb\x7a\x9d\x7e\x2f\x5f\xc7\xe6\x3d\x6c\xeb\xf5\xc8\x58\xc2\xd5\xb4\xc0\xba\xe3\xfb\x28\x64\x25\x8a\xd0\x60\x4b\xdf\x30\xf5\x1e\x30\x20\x5b\xfe\x26\x5f\xff\x10\x98\x77\xae\x0b\xa3\xd2\x0a\x2e\xa7\x65\x1b\x68\x18\x06\x2e\x2b\xbb\x41\x5b\x33\x91\xde\x13\x43\x1b\x15\xcd\x8f\x9f\x30\xd2\x7b\x13\xfd\xdb\xa0\x2b\x20\xda\xda\x6a\x82\x2d\x36\x2d\x26\xa4\x53\x1e\x41\xe3\x97\x5e\x51\xd1\x68\xed\x1c\x40\x70\x43\x47\xdb\xa1\x53\x63\xd0\x99\x72\xe8\x40\x13\x9a\x32\xe9\xb3\x21\x4d\xc1\xfd\x38\x55\xa5\xcf\xae\x46\x10\xf8\xa5\x36\x04\x5f\xe9\x23\x97\xbe\x34\x68\x25\xee\x41\x26\x2f\x4f\xb5\x1e\x4c\xcd\xca\x67\xd0\x75\xe0\xee\xc5\xa9\xbc\x67\x79\xa9\x97\xc8\x77\xb2\xc7\x17\xb7\xf1\x65\x04\xc1\xed\xf0\x87\x6a\xbb\xde\x83\xe0\xf4\xc7\x3a\x47\xee\xe3\x99\x72\x8d\x87\x52\xd7\xfb\xf3\xe5\xfb\x7e\x09\xfa\xc1\xec\xe5\x17\xda\x31\xfa\xc5\x07\x04\x02\x63\xd4\x86\x60\x8f\xe6\xd9\xda\x87\xe0\x43\x0b\x02\xdb\x80\x60\x99\x40\xb0\xbc\xdf\x86\xa0\xbb\x07\x01\x36\x20\x18\x10\x18\x19\x15\x79\xf3\x6d\x20\x1f\xb5\xfa\x88\xd8\x1c\x93\x2c\x42\x0a\x0c\x8d\x28\xd4\x7b\x1c\x56\x3d\x1a\x93\x3c\xf2\x8a\x8a\x66\xb7\x41\x02\x7d\x0b\x18\x25\xb8\x47\xef\x5e\x0b\x02\x0a\x78\xda\x5f\x5b\x10\xb4\xe8\x12\x6f\x9e\x42\xb0\xe5\xae\x43\xb0\xb7\x07\x41\x97\xb4\x21\xf0\x46\x10\x94\xe9\x9a\xaf\xd3\xd1\xa0\x5f\x78\x7a\x0a\x81\xb1\x31\x84\x80\x2e\xe2\x36\x05\x66\xe5\x01\x81\xe0\xe8\x7e\x5f\xca\x74\x4b\x47\xea\xc3\x3a\x04\x9b\x2d\x79\xc8\xf6\x3b\x10\xdc\x36\x20\xb0\x5d\x08\xba\x14\x8e\xba\x10\x02\x1f\x42\xd0\xae\x43\x70\x63\x0b\x68\x58\x87\x10\x60\x08\xc1\x3d\x14\x0f\xc2\x06\x7f\xb0\x19\xe7\xf0\x45\x8e\x9d\x06\x04\x27\x0d\x08\x28\xe0\xed\x36\x20\xd8\xab\xf3\xdf\x57\x75\xfe\xde\x5c\x16\x25\xcd\x2a\xcc\x7b\x42\xcb\x3c\xfe\xd5\x4f\xd4\xf3\xfd\xcc\x51\xc9\xcc\xc0\x50\x1c\x06\x28\x9a\xc6\x71\x93\xe8\x2d\xe7\x32\x4b\x2f\x74\x45\x45\xb3\xb2\x1b\x6f\xa2\x36\x83\x11\xcb\x43\x08\x4a\xdb\x74\xa5\x2c\xd1\x9f\x1d\x3a\xf9\x88\xee\x2e\x87\xce\x3a\xa2\x13\x7b\xbf\xe4\x3e\x76\x9d\x7d\x65\x78\xb0\x31\xdf\x9f\x4e\xfd\x11\x99\x27\x8a\xb9\xf1\xca\xcb\x4d\x5d\x8b\x55\x97\x4d\x3c\x36\xff\x0f\x17\x9c\x9d\xff\xa9\xbb\xf8\x72\x2d\x3d\x54\x30\x5a\xae\xe0\x52\xba\x23\xb6\xfa\x17\x75\xe4\x84\x24\x21\x63\x62\x48\xfa\x59\x6f\x30\x4a\x26\x06\xa6\x4f\xbe\xd0\xa3\xa2\xe1\x6d\x8e\x96\x74\x1b\x18\x1f\xbf\xd6\xe9\xbd\xba\x37\x6b\xc1\x1a\xf6\xfa\xfa\x1b\x3c\x7c\x0a\x78\x68\x42\x99\x0c\xfd\xe4\xb2\x00\x84\x7e\x2b\xf4\xba\xd1\x51\xfd\xa8\x09\x92\x3f\x51\xd1\xa0\xbc\x44\x4c\x64\x0a\x66\xeb\xe3\xa7\x76\x08\x8c\xfa\x15\xfd\x6b\xef\xc5\x14\x35\x25\xa6\x97\xcb\x32\xa0\xfd\x14\xb6\x50\x4c\xdd\x82\x0d\x5a\xe7\x16\x23\x73\xab\xba\x1f\x57\x2a\x55\xfc\xd0\x45\xd7\xc9\xfd\x09\x2b\x68\x8c\x76\x21\xbb\xd3\x85\xc2\x49\x4c\x46\xe4\x5f\x25\xe4\x3e\x23\x40\x97\x18\x01\x4a\xc1\xe3\x12\x5d\x43\x97\x14\xcc\x51\x8a\xc2\xb8\xa4\xf9\x56\x68\xbe\x2e\xcd\xb7\x32\xca\xd4\x32\x51\x36\x2d\xb1\x4c\x5b\xeb\xee\xcf\x2a\x9b\x69\xed\xfe\x63\x1b\x46\xe9\x30\xec\x5e\x22\x2f\x70\xc3\x41\xde\x50\x20\x7d\xf9\xb1\x43\x61\xf0\xb1\xa0\x25\xe9\x58\xb0\xfb\xeb\x1e\x0b\xb0\x7d\xb5\x07\xa3\x4a\x86\x95\x6d\xb8\xc4\x73\x6f\x1c\x14\x35\x1a\x4d\xd0\x10\x42\x83\x6d\x7d\x19\xec\xe8\x61\xc2\x39\x95\xf6\x46\x5d\xfd\x33\x30\x97\x3f\x42\x43\x1f\x44\x46\x96\x19\x6e\x5f\xa1\x01\x26\x28\xe6\xd6\xc0\x09\x5f\xb0\x50\xb7\x33\x3c\x2a\xe5\xc0\x30\x7b\x6a\x7e\x2a\xd9\xf4\x7e\x42\x09\xc9\x92\x5c\xd7\x11\x72\x2f\x9a\xee\x00\x27\x02\x09\xca\xfd\xd5\xf5\x4f\x12\x19\xc9\xaa\x81\x10\x94\x9d\x2a\xe5\x24\xaf\xa1\x3c\xc5\x4d\xcf\x19\xba\x7d\xce\x98\xc7\xf4\x04\xd8\xda\x6a\x46\xc5\xcf\xfa\x4e\xdc\x9b\x0c\xd7\x5c\xca\x99\x58\x93\xfe\x8b\x8a\xa6\xf1\xc9\xa6\xc5\x8c\x4b\xb2\x4e\xef\x37\x77\xb4\xd5\x43\x08\xee\x68\x02\xef\x43\xb0\xde\x82\x60\x89\x4e\xcf\x31\x24\x10\xd4\xe9\x58\xb7\x5b\xf1\x3e\x64\xa9\x76\x3b\x4e\xd1\xfc\x46\x8b\xa5\x0c\x18\xef\x57\x63\x3a\x5f\x5a\xf6\xda\x80\xa0\x53\xa7\xb3\x8d\x87\xe2\x59\x7d\xf7\x1a\x82\x66\x8c\x3c\xb2\xf3\xd0\x0c\x89\xc3\xc5\x06\x59\x69\xc1\x2c\x39\x41\xae\xfc\x46\xc8\x09\x8c\xe5\x21\x62\xf7\x6b\xc1\xff\x97\x9a\x76\xcc\xc0\x8f\x30\x07\xbc\x74\x7d\x51\xaa\xc6\x28\x27\xa0\xa7\xb3\x42\x29\x20\x8f\x32\x95\x9f\xe8\x82\x3c\x5d\x17\xe8\xcf\xab\x0b\x31\x03\xb9\x75\x21\xd8\x75\x33\x64\x09\x7b\x09\x1b\x10\x8c\x28\xf0\xe7\x1c\x23\xda\x9f\x89\x3d\x29\xd4\x94\x3e\xfb\xc4\x21\xed\x4b\x17\xf7\xa2\x45\x68\x94\x60\x0a\x32\xd9\x0e\x67\xc2\x83\x14\x74\xf2\xbb\x58\x48\x4c\x4e\xf2\x98\x2b\x0f\xe2\x1e\x51\xb6\x6f\x65\x87\x7e\x50\xf5\x90\xb2\x72\xa7\xf1\x30\xd1\x17\x27\xfb\x22\xc1\x1f\xa5\x2f\x1f\x4e\xfd\x64\xd1\x67\x6d\x8c\xd2\xf0\x0c\x67\x0d\x30\x17\x57\xb5\x51\x2f\xda\x3f\x6a\x82\xfd\x93\x26\xd8\x3f\x6c\x82\xf5\xa3\x26\x58\xdf\x6c\x82\xfa\xf6\x51\x13\xb0\xff\x9b\xcd\xa8\x05\x01\x62\xff\x92\x04\x82\x60\x85\xcd\x03\x7c\x78\xd4\x2b\xd5\xa5\x17\xbc\xa2\xa2\xb1\x74\x74\x0a\xc1\xf2\xed\x09\x04\xce\x3a\x04\x9f\xfb\x2d\x08\x2a\xe6\x01\x9c\xc0\xb0\xf1\x82\x1f\x4d\x3f\xa3\x29\x9f\x6e\xec\xaf\x23\x08\xf6\xe8\xd8\xad\x9f\x66\xf2\x33\x66\x61\x56\xc9\xd9\xa9\x6c\x59\x7b\x40\xb7\xca\xf5\x43\xa5\xca\x14\x6a\xd0\xfe\xf3\xd4\xcc\x59\x9d\xc8\xf7\x33\x25\x9e\xa3\xb5\x2f\x14\xc6\x8c\x5a\x10\x1c\x0c\x27\x13\x0f\xbc\x7a\x20\xf1\xa8\x52\xaf\xb5\x89\xa8\x64\x56\xe5\x6d\x48\xec\x4b\xd7\x43\x5d\x1c\x51\xd0\x57\x3f\x69\x82\xfa\xa1\xd8\x83\xf5\xed\xcd\x26\xf8\x8b\x26\x76\xd9\x9f\xcd\x66\xc4\x36\x1f\xfd\x97\x24\x56\x20\x58\x7e\x9d\xdb\xb1\x09\xe9\x76\x3c\x85\xc0\xa9\xbf\x6d\xc7\xb7\xed\xf8\x4a\x9b\x88\x4a\x30\x83\x16\x0f\x5d\x2f\xb8\x70\x3b\x17\x47\x43\xe4\x70\x76\x9e\x12\xc5\xe5\xaa\x5e\x06\x65\xa1\x57\xe8\xed\xdf\x7c\xd1\x8f\xa3\x72\x89\x4b\x00\xe2\x8d\xec\xa1\x6e\x88\x1c\x41\x4e\x17\x61\x09\x14\xa1\x19\x95\x6c\xbd\x01\x4a\x10\xcc\x45\xc6\xe5\x12\x76\xdd\xfe\xed\x9e\x6e\x83\xed\xf6\x2e\xbd\x19\xb6\x1d\x13\xa2\xad\x53\x08\xb6\x28\xd7\x7e\x44\x89\x98\x9b\x3a\x04\x0d\x4a\x72\x52\x16\xbf\xb1\x27\x12\xa3\x53\x08\xae\x69\xee\xbb\x16\x04\x26\xa5\x46\x99\x36\x61\xc3\xe0\xaf\x58\x62\x2f\x4e\xd0\xe2\xdb\xa6\x21\x64\xcb\xc1\x3a\x04\x3b\xb4\x9e\x0f\x6d\x08\x3e\x9c\xc6\xb2\x65\x9a\xd8\x5e\xe7\xa2\x82\x76\x63\x5f\xc8\x0c\x68\x37\xb8\x44\x7a\x1f\x52\xee\x80\x17\x4f\xea\x61\x52\xeb\xe4\x09\xcd\xcc\xa4\xd6\xb4\x1e\x5a\x21\xb9\x37\x58\x3d\x91\x51\xce\x92\x28\x5e\x17\x93\xc0\x21\xe8\xfd\x7a\x88\x89\xeb\x5f\xd4\x1d\x0f\xfb\xd1\x06\x1b\xdf\x72\x32\xc6\xe5\xae\xde\x00\x65\xf8\xf8\x61\xce\x91\x19\xc2\xe3\xed\x6d\xdd\x06\xc3\x5d\x42\x6f\x6c\x40\x29\x4f\xd6\x6c\x4d\x0e\xd6\x74\x82\x65\x9e\x23\x0f\x1d\x34\xf3\x6a\xc4\x13\xe5\xfe\x29\x04\xa1\x01\x41\x65\x8f\x36\x31\xa4\x23\x42\xa7\x88\x3e\x0a\xe9\xa8\xdd\xd0\x09\x9e\x4a\x70\x1e\x71\x16\xe8\x44\x3e\xe1\x42\x9d\x11\xcd\xbb\x3e\x12\x83\xdf\x3c\x15\x2a\x83\x44\x77\x90\x24\xe8\xab\x3a\x85\x1e\x61\xac\x5f\x38\xd9\xe3\xec\xd9\xd4\x54\x6c\xa0\x00\x0d\x90\x67\xa3\x27\x9f\x07\x83\xfe\x35\xfe\x71\xf3\x70\x0d\xc1\x17\x24\xcd\x83\xd7\x5f\x87\x60\x69\x1d\x82\x65\x0a\xa7\xc2\x99\xf3\xe0\x7a\x6d\xb7\xf5\x4c\xb3\xf0\xcf\xdb\x0d\x93\xb3\x30\xe7\x6e\xf8\x14\x5e\x85\xf7\x4f\x3c\x07\x94\xc5\xfd\xc7\xcc\xc0\x08\x8b\x44\xbf\x0d\xc1\xc9\x6e\xce\x0c\xe4\x0f\xfc\x1e\xba\xf8\xe2\xb8\x57\xcf\xb0\xfe\xcd\x7f\x1a\x18\xfa\x4c\x20\xb8\xa6\x94\x79\x95\x4c\xa0\x84\x39\x41\x51\x03\x93\xb6\x3b\x7a\xea\xa9\x60\xc9\x7f\xce\x4c\x84\xa6\x54\x4d\x33\x99\x85\x13\x08\x3c\xc7\xe0\xf4\xea\x12\xcd\x38\x73\x16\xbe\x38\xee\xc5\x47\xd4\xef\xe3\xae\xfb\x4c\x34\xd2\x3f\x65\x2a\x66\xd3\x48\x73\x6e\x88\x23\xd4\x0f\x9e\x0d\x33\xff\xb3\x66\x60\x16\x5e\x9e\x35\xf0\xe4\xe2\x53\x88\xc8\x1b\x56\x78\x56\xac\xd0\x86\x60\x60\x40\xb0\xdc\x7f\x78\x13\x90\x8b\xbd\xd0\x79\x6a\x58\x14\x27\x0d\x6e\x3e\xf4\x77\x9e\x0b\xa6\xbc\xbf\x16\x78\xa1\xbe\x0f\xc1\x0d\xcd\x93\x8c\xfc\xf2\x1e\x04\x4c\x51\x29\x28\x54\x96\xc8\x9f\x8b\x66\x68\x87\x83\xe7\xd8\x16\xf1\xae\xf8\xe7\xec\x8b\x07\x98\xb6\xf2\x3e\x04\xcb\xeb\xa7\xf3\xf0\x0d\xc7\xfe\x65\x88\x9c\xa7\xc7\x11\xff\x38\x30\x35\x03\x4f\xf7\xe8\x54\x0c\xf3\xf1\xf4\x46\xe8\x21\x1b\xb9\x42\x4e\x57\x2e\x41\x2e\xe2\x1b\xe9\x7b\xa0\x1c\x72\x29\x1f\x1d\xbe\xde\xd7\x25\x57\x6f\x03\x73\x79\x77\xef\x48\x6f\x47\x46\x25\x2b\x9b\xf2\x43\x62\x3b\x2e\x89\xea\xe9\x0c\x46\xa5\x03\x7d\x8b\xcf\xde\x73\x1b\x4e\x7e\xff\x8a\x8a\xc6\x5d\x65\x79\x45\xef\x01\x63\x73\xb7\x41\xef\xa5\x8d\x3d\x08\x4a\xcc\xaa\x1b\xee\x89\x09\x32\x20\x99\x4e\xb1\xc1\x4f\x15\xdb\x2c\x95\x3e\xcb\x4b\xfd\x60\x3e\xba\x69\x8c\x32\xc9\x3c\xeb\xb4\x05\x30\x63\x36\x7b\x88\x15\xa5\xb0\x90\x59\xc5\x0e\x21\x38\x6d\xc5\xe6\xb1\xec\x23\xbc\x78\x31\x24\x72\xc6\x87\x8d\x6d\xaf\xe3\xd5\x95\xa7\x3a\x75\x86\x52\x1d\xd9\x44\x20\xb7\x93\x24\x8c\x95\xd3\x8c\x22\x62\x42\x25\x21\x59\x81\xe4\xa4\x58\xd9\xce\xfa\x74\xea\xf1\x25\x7e\xa6\xec\x33\xb4\x16\x99\xc2\x55\x25\xde\x2c\x81\xd3\x73\x7b\x14\xff\x1c\x35\xc1\xc6\x66\x13\x6c\x9c\x34\xc1\xc6\x61\x13\x6c\x1d\x35\xa3\x2a\x04\x95\xf4\x1f\x33\x1b\x35\x4b\xe5\xa8\x68\x56\x9a\x9f\x69\x75\x94\xfc\x20\x2d\x08\x4a\x57\x18\x82\xe5\xbb\x12\x04\xce\x2d\x6b\xc1\x94\x5a\x58\x47\x97\x0e\xba\x58\x47\xa4\x8d\x3d\xc4\xfd\x0f\x1a\xb4\xad\xa3\x26\x38\x3c\x6a\x82\xc6\x26\x6b\x37\x5a\x32\xc0\x12\x04\x55\x08\x96\xd9\xdf\x8a\x6c\x4e\x52\x7e\xe0\xaa\x98\x3f\x76\x45\x45\xe3\xf8\xf3\x07\x08\xda\x78\x8f\x22\x6d\x9b\x8e\x91\x2d\x8c\x26\xd8\x9a\x77\x83\x53\x08\xba\x83\x7d\x08\x0e\x4d\xba\x62\x4a\x5f\xdb\x8f\x55\x09\x75\xe2\x85\xcf\xa6\xe5\x51\x3a\xa4\x79\xb4\x49\x27\xaf\x41\x77\xf5\xc2\xad\x3d\x54\x36\x5a\x2e\x67\xf4\x3e\x6c\xe5\x65\x74\x3e\xe6\xbd\x5e\xfe\x09\x9d\x4f\x7a\x31\xed\xcf\xdd\x50\x3f\x06\xdb\xed\x3d\x7a\x7b\x55\xda\x1f\xf6\x64\x2f\xae\x90\x65\xde\x8e\x8d\x49\x69\x22\x71\x4c\xc8\x7a\x28\xfc\x9c\xaa\xa8\x5f\xe1\xaf\x22\x73\x29\x03\x61\xd6\x91\xd7\x42\x6d\xe1\x79\xb4\xce\xb5\x76\xa0\xbe\xd9\x8c\x4a\x27\x7a\x00\xd8\x9f\x04\x2f\xa7\x02\x6e\xe3\x33\xdc\x31\xf4\x1b\x70\xe5\xd3\xfd\x78\xb0\xb9\x41\x7f\xb0\x2f\xc9\x03\x6c\x94\xed\x31\x4a\x2d\x06\x7b\x64\x52\x60\x1d\xf7\xf1\x20\xab\xf5\x6b\xeb\xc7\x73\xad\x00\xae\xdf\xdb\xd5\xcb\x60\xbb\xbd\x4b\x6f\xbf\x6e\x86\x13\xeb\xac\xf4\xab\x9c\x11\xb7\xe7\xa3\x50\xb4\x08\x2b\x25\xc8\x60\x68\xe5\xb3\xde\x60\xc0\x33\x94\xe1\xe7\x63\xae\x12\xb3\xc1\x34\x7b\xeb\xe1\x92\x6e\x83\xce\x21\x33\x5b\x3e\x20\x21\x30\x46\x76\x08\xbe\xb4\x42\x60\xdc\xba\x93\x09\xfa\x2a\xc9\xf3\xbd\xcc\x3f\x56\x2a\x3f\xf3\x53\x74\xac\x03\x1b\x21\xb8\x26\x10\xf4\xef\xd6\xb9\x1f\x4e\x65\x29\x0b\x45\xfa\x88\xd8\xc5\x23\xd4\xea\x53\x92\x92\xaf\xdd\xd8\x1a\x24\xe2\xfc\x40\x49\xac\x5f\x68\x96\x20\xc3\x8e\x47\x02\x3b\x1e\x7f\xa4\x84\xee\x5d\x05\x02\x27\x64\xb6\x85\x19\xc4\xe8\xa2\x8b\xaf\x8e\x1f\xc4\x20\x8a\x13\xaa\x65\xf3\x11\x84\x2a\x5b\xa4\x37\x5f\xf5\x1e\x5d\xa4\xf4\xf6\x0b\xc1\x90\x3f\x18\x4a\x30\xc2\xdc\x83\x51\xd5\x9c\xf8\xde\xae\x1b\xa0\x68\x9d\x7d\x6c\x85\x7e\x70\x54\x3e\xd6\xbb\x94\xb8\x28\x27\x76\xa8\xb8\xb5\x54\xd2\x77\x40\x69\xf9\xde\xa5\x77\x13\x13\x18\xad\x4c\x2c\x7f\xd7\xf1\x71\x44\x69\x87\xc3\x4d\x4e\x4b\x34\x4e\x9a\xa0\x71\xc8\x68\x89\x68\x19\x52\x3a\x82\x93\x12\xec\x5f\x24\xbc\x5b\xca\x3f\x48\x28\x3c\xd7\x15\x15\xcd\xaa\x71\x3d\x85\xd7\x96\xe9\x50\x7f\xa2\xfc\xc0\xf2\x9d\x09\x81\x73\x07\xc1\xe7\xdb\x47\x1b\xd1\xe4\xbc\x65\xdc\xc5\x2e\x79\x46\x83\x9d\xef\x94\xf8\x9b\x90\x20\x6f\xc6\x3a\xb9\xc6\x3a\xa6\x91\xc1\xbc\x1b\x68\xd0\xf2\x9c\x76\x17\x5f\xac\xa3\xfb\xa8\x08\xe1\xc4\x46\xdd\x14\x94\xbf\xe0\x3a\xb8\x8f\x5a\xb2\x6b\x2b\x52\x82\x63\x32\xca\x04\x54\xe6\xbb\xaa\x4b\xcb\xd5\x39\xb3\xce\x71\x71\x9b\x75\x08\xbe\x1c\xac\x48\x5b\x72\x6f\x63\x4f\x38\x7f\x8d\xba\x0f\x5a\xce\xfd\x46\x9b\xa3\x2e\x52\xe6\x2e\x04\x27\x9f\xdf\xf6\xc7\xd3\xee\x0f\xa3\x92\x41\x86\x1b\x68\x30\x74\x2f\x3e\x7a\x94\x2d\xce\xe0\xff\xd2\x86\xee\xbf\x80\xa0\x8a\x93\xb7\x7d\xfd\x96\x32\x30\xf4\xf6\xc6\xc0\xf0\x3e\xd3\x7a\x76\x86\x10\x30\x6f\xd4\x4c\x1e\xd6\x8d\xc4\xaf\x3b\xc9\x4c\x13\xd3\xfd\x49\x9a\x48\xf2\x3c\x90\x39\x9b\x10\xfd\x89\x96\x96\x26\x20\x2a\xb1\x85\x1b\x23\x85\x9a\xcc\x0b\x47\xc8\x4e\x2a\x7b\x7a\x59\x40\xcb\x72\x02\x30\xe9\xf5\x90\xe0\x84\x5f\x5c\x0e\xf2\x11\x02\xf3\xda\x74\x21\xb8\xdf\x9b\x21\xa9\xa0\xbd\xbf\x5b\xff\x35\x72\x8e\x47\x94\xd8\x6c\xc3\xa8\x5a\x9a\x18\x37\x0f\xd9\x28\xd1\x75\x95\x20\xa7\x3c\x3d\x4a\x66\xc7\x32\xe5\x58\xaa\x7c\xab\xf7\x80\xb9\xbc\xdb\x60\x51\x2e\x76\x6e\x0f\x42\xd0\xbb\x76\x61\x64\xae\x64\x08\xd0\x0d\x74\x8f\x09\x99\xd8\xb6\x81\xde\x4b\xb7\x6d\x54\x34\x07\xde\x6d\xa8\x6f\x01\xb3\x7b\xe2\x86\xfa\x56\x54\x59\xce\x30\x15\x87\x88\xa0\x01\xd7\x31\x50\xd4\x57\xb9\xd2\xeb\x7c\xde\xa2\xa2\x19\xb6\xc3\x2d\xdd\xa5\x00\x23\xd3\xe8\xa5\x63\xa3\xae\x1b\x49\x18\x33\x96\xd5\xe5\xc9\xe9\xbe\x7b\x99\x52\xba\x54\xfe\xc5\x41\x36\x7e\x26\x3c\x87\x59\x35\xfc\xe9\xb5\x11\xab\x1b\x52\x59\xb2\xbd\x3f\x97\x14\xfa\xe9\x82\x44\xcc\x6c\x8c\xf5\x72\x7b\x14\xaf\xdb\x47\x14\xfd\xb2\x9e\xca\x59\x9f\xa8\x33\x33\x53\x3f\xc8\x0d\x3c\x1f\xff\xf0\x6a\x1c\x13\x5e\x3f\x29\xf7\xc6\xe7\x3c\x1b\x1d\xb7\x62\x4e\x82\xe5\xcb\x10\x5d\x86\x28\xa3\xd8\xd8\xe0\xec\x4d\xb4\x54\xd6\x7b\x82\xab\xa9\x08\x59\x04\x23\xbf\x28\x72\xfe\x3e\x6e\x7e\xdc\xf5\x5d\x85\x86\x39\xfa\xbc\x9f\xb3\x06\xae\x7f\xa1\x06\xe3\x55\x2c\xf4\x57\xa5\xc1\x98\xe0\xa2\x5d\x3f\x40\x17\x5f\x1c\x1b\x45\x47\x9f\x1a\xc9\xda\x8a\x2a\x75\xbd\x3d\xa1\x25\xa3\x24\xbd\x71\xda\xae\x12\x7d\x0f\x98\xfd\x10\xd2\x3b\xa3\x97\x77\x87\x9c\x70\x1e\x52\xe4\x61\x54\xe8\xa3\xde\x10\x82\xc1\x1e\x8c\x8c\x89\xb5\xec\x61\x3f\x70\x49\xd4\xe0\xaa\xb9\x68\x49\x38\xb0\x51\x24\xbb\xb2\xf9\x05\x82\x72\x69\x1d\x46\x95\x52\x96\x91\x09\x1d\xd4\xca\x8a\x30\x4b\x3b\x32\x2d\xf4\xac\x0c\x4c\x47\xdf\xa2\x0c\x0c\xbd\xbd\x31\x30\x65\x8a\xa1\x7e\x3d\xdf\x52\xc9\xba\x0a\x6d\x22\x32\x40\x5e\xcf\xbf\x44\x37\x44\x56\xc5\xf0\x78\x72\x58\xdf\xe2\xea\x18\x30\x67\xac\x0c\x13\x55\x4e\x3e\x51\x32\x7d\x54\xe9\xd0\xbb\xb1\x72\x0c\x9f\x33\xc0\xcf\x4f\x94\xdd\xdc\x80\xd1\x72\x66\x24\x6e\x7d\x97\x5c\x6c\x78\x18\xf7\x12\xf9\xf5\xe1\x49\x13\x1c\x1e\x32\xd4\x91\xca\xae\xd9\x3f\xa1\x50\xf8\x01\xaa\x98\xab\xe8\x0f\xb2\x4a\x08\x03\x02\xe7\x1e\x82\xd2\xfe\xfa\xd3\xd3\x8a\x4f\x42\x25\xbf\x00\xa9\xd8\xe0\x40\xaf\x34\x35\x29\xd1\x5f\x47\x4d\xf0\xd7\x66\x13\xfc\x75\xd2\x04\x7f\x1d\xd2\xf4\x26\xb7\x4f\x38\xdc\x6c\x46\xcc\x93\x57\xfc\x5b\x12\x7f\x63\xb5\x02\x2c\xc3\x4a\xf5\x17\x5c\x6c\x8a\xf7\xc5\x14\xf3\x31\x2d\x7d\x85\xe0\x08\x7b\x74\xb2\x21\x04\xce\x48\x16\x53\x5e\x79\x75\x08\x3a\xfb\xed\x37\x02\xf7\x8d\xc0\xfd\x8e\xa0\x32\x8b\xdf\x37\x31\xb9\xc1\x1e\xa3\x09\x1a\x9b\x89\x04\x3f\x9a\x52\xb0\x19\x3f\x0c\xad\x5e\x42\x42\xe0\xcd\x58\x07\x71\xa4\x8e\x01\x81\xe0\xc0\x6b\x67\x24\xfc\x6f\x0c\xea\xdb\xfe\xfd\x0d\xf7\x6f\x1c\x54\x37\xd9\xbf\x81\xe7\x3a\x41\x56\x6e\x7c\xd2\x04\x5b\x87\x4c\x7e\x1c\x55\x6e\xf5\x56\x2a\x3b\x2e\xc7\xba\xf8\x57\xa4\x2e\x8f\x8a\xe6\x46\xd7\xf1\xf4\x7d\x30\xc4\xd7\xf4\x66\x54\xaa\x4c\x3d\x5e\x86\xc0\xb9\x81\xa0\xda\x69\x0b\x82\xe2\xd3\xdd\xa9\x01\x8e\x1a\xa7\xd2\x62\x47\x27\xc6\xe4\xb6\x7b\x72\xca\xe2\x6d\xdf\xbd\xf6\x4d\xf1\x22\xd1\x2a\xb2\x66\x6f\x5b\xed\x81\x4b\x28\x37\x1d\xcb\x85\x32\xd8\xf3\x4e\xff\x3c\x61\xa3\x92\x61\x73\xca\xcf\xa8\xf9\x7b\x24\x93\x7d\xdf\x2e\x5f\xeb\xcb\xc0\xbf\x6c\xd3\x1b\xa7\x36\x97\xda\x10\x5c\x8e\x20\x30\xdb\xeb\x99\x3d\x30\x83\x83\xd8\xf9\xb8\x2f\x21\xd6\x94\x01\x39\xfd\x3c\x7c\xae\xad\xf6\xb6\x4d\xdf\xb6\xe9\x0c\xf2\x36\x6b\x4c\xb6\xe5\x78\x21\xc1\xc3\x58\x99\x27\xcc\xd2\x36\x75\x5f\x32\x4b\x9b\x43\x10\x75\xd3\xe3\x9a\xf4\xde\xaf\xd5\xa4\xb7\x0f\x85\x6c\xe9\xbe\xd9\x86\xa0\x5d\x39\x85\x51\xc9\xc8\xb0\xbb\x5b\xfd\x8b\x23\xd4\xbf\x41\x6d\xd7\x4b\x48\x02\x26\x51\x3c\x16\xa6\xa3\x69\x2c\x54\xe3\xd4\xf9\x58\xd2\x6d\x60\x7e\xb8\xb1\xe9\x5d\xf6\xba\x48\xe2\x24\x8a\x6a\x9b\xce\x55\x88\x48\x2a\x04\x9f\x90\x6e\x44\x4b\x0d\xbd\x9c\xb0\xce\x89\x78\x83\x49\xc2\xcb\x95\xa7\x0f\xbd\xfb\x13\x17\x13\xa3\x6f\x41\x50\x3e\x3c\x85\x60\x79\xd0\x10\xb2\xf4\xa3\x18\x3c\x0c\xb7\xd7\x21\x58\x2e\x79\x10\x8c\x76\x20\xa8\x1c\x18\x22\xc4\xbd\x7d\x70\x00\x73\xa3\x17\xcf\x13\x15\x39\x49\xad\x1f\x0f\xdf\x40\xdd\xd3\xca\xd4\xc1\xb1\xf1\x3a\x41\xd1\x8b\x30\x03\x59\x68\xf7\xc1\xf5\x82\x8b\x7d\xdc\xf7\x5d\xf2\xac\x02\xc8\x67\xb9\xde\xa4\x9a\xbf\x5c\xdd\xfe\x0f\x83\x2b\x4f\x48\x42\x45\xa5\x95\x8c\x58\x8d\xed\xc4\x13\x74\x4f\x70\x9e\xe7\x1d\xe3\xcc\xb3\x56\x3d\x9c\x18\x61\x57\xee\x9e\x2c\xc3\x72\xe5\x09\xae\x19\xf6\x34\x9f\x77\x0c\xae\xbd\x7a\x41\x0b\x94\x4a\x33\x4e\x5d\x33\xaf\xe5\x89\x35\x76\xcd\xe2\x75\xbf\x51\xba\x33\x61\xff\xc4\x6a\x43\x7d\x3c\x9a\xf4\x86\x7b\xa4\x2f\x1c\xf7\x7a\xbb\xa6\x84\xee\xf5\xeb\xd2\xb7\x12\x5f\x76\x3e\xa9\x50\xde\x74\xb0\xcf\x48\xe1\xa8\x54\xce\xa0\xc0\x8f\x7d\x64\x73\xa3\xf4\xbd\xd4\x17\x2d\xf1\xe7\x29\x9d\x26\x4e\xfe\xa5\x44\x81\xfd\x9a\xd8\xf1\x1d\x7f\x07\xea\x36\xd8\xb8\x3d\xa0\xb7\x69\x27\x23\xe0\x5c\xc7\x9b\xe8\x53\xd7\x78\xc3\x0d\xbf\x03\x6e\xf8\x3b\x01\x1d\x63\x25\xc3\x6e\x7e\x74\xdb\xc1\x25\x6a\x65\x5d\x30\xaf\xe7\x74\xc1\x7c\xc6\x6d\x84\x2a\xc7\x77\x7a\x19\x98\xa3\x4a\x9b\xde\x5f\xb1\x11\xc1\xdb\x09\x43\xaf\xef\x84\x21\x63\x69\x62\x91\xbb\x3e\x47\x29\x2c\x68\xff\x66\x13\x24\x77\x11\xc0\x3f\x41\x33\x9b\x9b\xcd\xa8\x14\xea\x9f\x81\x49\xff\x94\x42\x60\xc6\xff\xa4\xc8\x32\xd9\xa3\xb8\x1e\x21\x1f\x79\x54\x20\xf0\xe5\x17\x09\x36\x6e\x56\x9a\x47\x41\x2c\x38\xde\x3c\xa5\xb8\x7f\x9b\x1d\x67\x3a\x4f\x30\x8f\xe9\x3c\x4b\xc7\xdb\x21\x70\x82\x70\xd6\xfb\xe9\xca\x58\xa2\xdf\x7e\x56\xb6\xef\xc7\x30\xe6\x91\x01\x41\x17\x86\x7f\x37\xd6\x8f\x18\xd3\x41\x2a\x36\xfe\xc6\xe8\xdd\x3e\x7d\x25\xb8\xf7\x25\xd0\xfb\x52\x35\xc3\xc5\x32\xff\xb5\x8b\x66\xe8\xf5\xa2\xdd\x46\xea\x93\x54\x3f\x6a\x46\x95\x25\x1d\x25\x4a\xe5\xa7\x44\xf4\xa5\x47\xa0\xf9\xbe\x11\x7e\xd6\x0f\x80\xb9\xbd\xbd\x4e\xef\x6f\x64\xec\xf3\x93\xb1\x95\x9d\xdf\x70\x59\x97\x96\xb2\xcb\x3a\x44\x01\x1e\xa0\x3e\xca\xa8\x48\xaa\x66\xec\x65\x97\x31\xba\x36\xcb\xbb\x97\x5f\xf5\x63\x60\xe2\xce\x29\xbd\xd7\x09\x04\x83\xa0\x0d\xc1\xfe\x08\x02\x87\xd9\xcd\x2f\xb5\x20\x18\x6d\x0a\x09\x65\x72\x3c\x57\xda\xd8\x3d\xba\x0e\x9d\x7e\xf4\x59\x52\x41\x55\x70\x26\x2e\x82\x71\xff\xf5\x68\x17\x98\xe1\xce\xde\x2e\xf0\x46\x53\x31\x56\x3e\x86\xf7\x28\x3d\xde\xa0\x5c\x11\xb4\x76\x39\x2a\x7d\xd6\xb7\x40\xe9\x13\x25\x2d\x84\x5d\x47\x54\x34\xdb\x37\xc7\x4b\x7a\x0f\x98\x5e\x75\xef\xb3\xde\x03\xeb\x77\xad\x4e\xb4\x9c\x3d\x6b\x61\x1b\xf5\x9d\x0e\xba\xcb\xe5\x91\xcb\x58\x77\xa7\x78\xe4\xc7\x5d\xaf\x86\xa3\x9e\xff\x62\xbc\xf7\xf6\x27\xbd\x0e\xee\x46\x23\x7a\x63\x11\xd3\x4a\x3b\x25\x21\x8f\x66\xc7\x97\x32\x29\xc5\x96\x21\xc4\x1e\xf7\xfb\x10\x1c\xd2\x1d\xb8\xde\x8e\x25\x22\x6d\x08\xbe\x50\xd8\x72\x6b\x88\x70\x69\xb7\xb1\xd8\x23\xfb\x24\x16\x8d\x7c\x1a\x89\x0a\x0f\xe2\x0a\x8f\x49\x26\xda\x1a\x5d\xc1\xc6\xa9\x5c\x8c\x89\x44\x62\x41\xca\x87\x4c\xd5\x49\xb1\xf5\x38\x0f\x5d\xa7\x99\x57\x5f\x3a\x92\x2c\x61\x5e\x6a\xa9\xc4\x14\xf9\x4f\x97\xaf\xea\x7c\x5f\x72\xf1\x26\x39\xff\x47\xa1\x95\xbf\x07\xf9\x14\x9f\x91\x9f\x40\xd9\x1b\x0a\xb6\xb7\x65\x3d\x7c\xc0\x3c\x81\x9f\x98\x66\x7a\x06\x68\x68\x34\x70\x18\xea\x2e\x58\x32\x47\xf4\x46\x01\x9e\x4f\xd9\x2c\x76\xb8\xe2\x7e\x5b\xf8\xba\xec\x8b\x27\xd5\xad\xa1\xf4\x8a\x26\x3e\x6d\xc6\x40\xb1\x1e\xbb\xa6\x70\x3b\xbe\x53\x99\x83\x63\x07\xc7\x3f\xbc\x85\x59\x90\xca\x7e\x72\x68\x62\x6f\x5f\xf6\x72\x9a\xbd\x0d\x3b\x89\xc2\x30\x6f\x21\xcf\x01\xf8\xa4\x76\xc9\x23\xb6\x0d\x3f\xd6\x9a\x24\x7d\xa9\xc7\x07\x5c\xcf\x91\xca\x93\x0c\x31\x1f\xbf\x39\x2c\x0e\xca\x2e\xed\x81\x9d\x49\xd1\xb7\x55\x07\x42\xf0\x85\xfe\xba\x75\x21\x38\xa6\x59\x83\xfa\xe4\x93\x24\x31\xb2\x45\x82\xb6\x73\xe0\x8a\x27\xd3\x09\x56\x3c\xff\xd5\x4f\x66\x7e\xc1\x26\x22\x33\x6b\xe4\xb2\x8d\xbd\x81\xeb\x3b\xfd\xbe\x9b\x17\xc5\x32\x5a\x22\x89\x51\xdf\x72\xc6\xa8\xaf\x34\xaf\x87\xe6\xa3\x42\x4e\x46\xd5\xac\x9f\xd5\x0e\x69\x3b\x88\xa0\xf7\xbb\xc4\xbd\x9b\x37\x9a\xe7\xf7\xd5\xfb\x3f\x10\x19\xa0\xfc\xb3\x8a\xfe\x19\x3a\xc8\xa3\xee\xbe\xa4\x7b\x7c\x16\x8d\x7f\x1e\x82\xce\xcb\xf7\x20\x29\x51\xda\x20\x10\x2c\xcf\x84\x5c\x7f\x6f\x57\x81\xd1\x72\x7c\x2e\xf9\x1b\x09\xf0\x3d\xad\x6c\xbc\x63\x1b\xc8\xc3\x44\x0a\xed\x31\xa7\x21\x40\xce\xde\x95\x14\xf9\xc6\xf3\x19\x03\x64\x37\x62\xfb\x3e\xde\x25\xa9\x21\xfe\x4f\xdb\xcf\x5c\x79\xa3\x1f\xda\x2a\x75\x7e\x88\x3d\xdf\x2a\xb8\x3a\x7c\x23\x47\x1f\xb9\x16\x0f\x71\x80\x3d\x7e\x5c\xfe\xcf\x2f\xc7\x07\x10\x08\x45\x12\xcf\xbf\x36\xc9\x55\x12\x02\xe6\xc7\x0c\xbf\xe6\x04\xaa\xa5\x0f\xad\xa7\xe2\x41\xe7\x04\xf9\x2b\xf6\x34\x9c\x75\x7f\x97\x85\xf7\x8b\xd6\x76\x13\xf7\xfb\x17\x1b\x4e\x70\xff\x24\x4b\x9b\x2e\x6c\x06\x68\x5f\x82\xda\x79\xde\x85\xbc\x7c\x4b\x72\xde\xee\xc2\x69\x73\xab\x37\xc4\xfe\x98\x05\xf7\x15\xdf\xa0\x1f\x59\x6c\x4f\x62\xc9\x37\x37\x90\xec\x1d\xae\x43\x50\xe7\x4b\xe0\xfb\x80\xaa\x4f\xde\xcc\xee\x1e\xbd\x0e\x1c\x62\x63\x42\xb0\xff\x44\x38\x35\x21\xf5\x5e\x04\x89\xa6\xa0\xa4\x0b\x87\x39\xe0\x65\xef\x47\x20\x53\xb2\xaa\x1e\xb4\x94\xb6\xd9\x21\x23\xb9\x86\x9f\x6f\xa8\xef\x31\x2b\xf0\xc4\x21\x68\x80\xec\x27\x5c\x7f\x99\x55\xf8\x02\x50\xea\x17\x44\xbb\xfb\x19\x5e\x65\x72\x91\xa2\xdf\x69\x05\xbd\xf8\x22\x0d\x6f\x9c\x1e\x0b\x12\xcd\x9d\x52\x36\x13\x8f\xd9\x28\x3e\x0f\x66\x29\x91\xa8\x95\xca\xbf\xe0\x8a\x8a\x1f\x48\x1d\x82\xe0\xe4\x58\xc8\x5d\x6f\x0f\x31\x04\xe6\xf0\x41\x2e\xf5\x4d\xe7\xf3\xda\x57\xe1\x8b\xe8\x7c\xb2\x81\x9f\x77\xae\x51\x3f\x74\x02\xb6\xda\x93\x38\x0c\x0c\x0a\x6f\x8a\x80\xbe\x42\x13\x14\xc7\x63\xa8\x40\xae\xbd\x4f\x4d\x0f\x4a\xe5\x52\x65\xbe\xab\xba\x34\x6f\xce\x39\xae\xa8\x68\x54\x77\x21\x04\x4b\x74\xb2\x9d\x9b\xbf\x67\x10\xf4\xd4\x52\xad\xfe\xb6\x11\x9e\x76\x23\x54\xb3\x46\x36\x9f\xd0\x00\x39\x36\x92\x0d\xc7\x24\xa3\xb1\x19\xda\x4f\xc9\xa6\x2b\x6c\x18\xcc\xa6\xeb\x39\xc5\xe3\xd1\x4a\x56\xc7\xf2\x29\x24\x18\x85\xdc\x75\x52\xb8\x4d\x1e\x6e\x8a\xc0\x61\x47\x4d\x50\xdf\x65\x7f\x36\xb3\x8e\x94\xcb\x10\xac\xb0\x7f\x2c\x98\xa2\x09\x4b\xb9\x57\x99\xdf\x2b\x2f\x60\x95\x2b\xdb\xe7\x1a\x4b\x4d\x53\xf2\xa3\xfc\xea\xce\xb2\xbc\x78\x36\x15\x45\xaa\xd3\x9c\x01\x34\x98\xa4\x0b\x5e\xbf\x72\xc0\xf1\x86\x41\x9f\x0f\x83\x96\x32\xe6\xf6\xbb\x98\x04\xa1\xdd\xbb\x7f\xbf\xe7\x86\x8e\x7f\xe3\xf4\xfb\x3f\xe0\x43\xf9\x30\x6f\x93\x61\x4f\x9e\x42\x93\xf2\x0c\xec\x51\xe9\x43\x1b\x82\xfd\x16\x04\x7b\x87\xb1\xda\x25\xeb\x9c\x49\x4e\x0d\x80\xe1\x29\x58\xb9\x69\xff\x9c\xf7\xf3\xa3\x45\xda\x77\x23\x08\xba\xbe\xfb\x93\x32\xf0\x8c\x2e\xe7\x95\xab\x3d\xdf\xe0\xc9\xef\xd3\x44\x94\x07\x4b\x1a\x2e\x09\x1c\x1b\xf7\xfb\x4f\xa1\x86\x7d\xf4\xf5\xfc\xd0\x22\x2b\x4c\x39\x3a\x19\xfe\xe4\xe6\xfc\x9d\x6c\x12\x9e\x73\x73\xbe\x71\x09\xcf\xb7\x39\xf7\xd0\xc5\x21\x1a\xb1\x43\x52\xd6\xd9\x39\x97\xe5\xa8\x7c\xab\xd7\x41\x89\xfe\x89\x0f\x03\x37\xee\x4a\x4b\x9e\xee\xf2\xe3\x3f\x8d\xec\x41\x2d\x7b\xce\x00\x65\x02\x3b\x55\x96\x67\x5a\x57\x46\x45\x33\xb8\xff\x78\x48\x6b\x6a\x6d\x8e\xe8\x9d\xb9\xa5\xa3\x9c\x05\x78\xe8\x09\x7f\x76\xe3\x40\x78\xaf\x57\x3f\x0e\x79\x62\x65\x99\x27\x22\xc3\xc0\x55\xb9\x27\xae\x7f\x51\x27\x5d\xdc\xc7\xfe\x64\xe0\x95\x28\x1b\x13\xe9\x75\xc5\x5c\x99\xff\x9a\x71\x9c\xa1\x80\x3b\x82\xbd\xa8\x9c\x0c\x0d\x60\x7c\x45\xa7\xa0\xd4\xae\x3f\xd2\xaf\xf3\x27\xa2\x2a\x4d\x78\x74\xce\xe1\x6f\x2b\xd9\x5c\xbe\xa0\x52\xff\x1f\x02\x33\xdf\x08\x9a\x27\x86\x99\x46\x25\x03\x6c\x1a\xc8\xc6\x8e\x9b\x0d\xf5\x31\xd0\x3f\x3f\xda\xe7\x9e\x87\xfb\x58\xd7\x97\xc1\x76\x7b\x8f\xde\x5e\x55\xc8\x8f\x76\x43\x1c\xb1\xb0\xfc\xd9\x98\x15\xfb\x63\x25\x7b\x14\x58\x03\x11\xd4\x0d\x51\xd4\x90\x62\xe1\x32\xa3\xfb\x4f\xba\x9d\x39\x6d\x92\x9d\x83\x6c\x26\xe7\x21\x1b\xd7\xa1\x83\xf5\x06\x30\xee\xeb\x0d\x7a\x2f\x0f\x08\x04\x2b\xc7\x43\x08\x36\xe9\x07\xed\x1a\x3c\xe1\x97\x3e\xd0\x5f\xdb\x10\x6c\xae\x43\xb0\xb2\x43\x20\xe8\x51\x7c\xc0\x0f\xe4\x77\x4b\x74\x25\xdf\xc3\xc8\xcc\x9e\xba\x41\x3b\x15\xfa\xd9\x33\x80\xa1\x5e\x9e\xf3\x00\x0d\x1e\x7d\xf0\x94\x1d\x44\xbe\x7b\xfa\x6b\x0f\x22\x8f\xa3\x0f\x4e\xa2\xe1\x06\xf2\x02\x87\x38\xd7\x21\x8e\x3e\x7c\x90\x0e\x00\x2f\x97\x33\xe7\x84\x44\x45\x73\x70\xd8\x6c\xea\x5b\xc0\xdc\x3b\x6c\xd1\x3b\x1d\xb8\x49\x9f\x89\x06\x0a\xd0\xc0\xf5\xc4\x79\xe2\x89\x6f\xde\xd6\x94\x67\xde\x93\x3b\x3c\xf0\x63\xf2\x3e\x5c\xc5\x22\x62\xa7\xfa\x68\xd0\xf7\x5c\xc7\xe9\xfc\x93\x43\xdc\x95\x2b\x13\xeb\x63\x84\x82\x3e\x22\xf9\x26\xfa\x15\x7d\xeb\x41\x13\xfd\x17\x3e\x92\xe9\x51\x06\xff\x2f\xbb\xa4\x5e\x13\xda\x7f\xe1\xd6\x1e\x2a\x1b\x95\xb3\x1a\x81\x06\x26\xee\xc0\x21\x38\x57\x04\xf9\x90\xcb\xc5\x4f\xdb\x0d\x3e\x11\xc9\x3e\xbf\xdd\x45\x7a\x22\x42\xb5\x6c\x40\xb0\xf2\xa9\x25\x48\xe6\x37\xea\xf6\x8d\xba\x7d\x46\x00\xbf\x9c\x55\xa0\x37\xb0\xe7\xb4\x51\xe6\x3c\x03\x46\xc3\x9d\xe8\xfe\x34\x0d\xf7\xd4\x57\xf6\xb4\x5c\xf3\x72\x04\xc1\x6d\x58\x7a\x83\xd9\xbf\xbc\xb5\x07\x61\xf6\x44\xb0\xea\x06\x0e\xfa\xa8\x47\xa9\x84\x29\x4d\x6e\xbe\x06\xf7\x7b\xba\xdb\x44\x87\xcb\x44\xb0\xf3\x9a\xef\xbe\x06\xe5\xeb\xf7\x21\xef\x25\xa5\x2d\x1f\xd8\xb8\x61\x03\x82\xab\xf5\xdf\x06\x98\x18\xe5\x09\x60\x72\xe7\xd8\x2e\x77\x0a\x98\x3c\xc0\x73\xe3\xa4\x19\x55\xeb\x7a\x3d\x3d\xc0\xb3\x92\x3d\xc0\xf3\x39\x23\x90\x3f\x44\x35\x76\xb7\x08\x0f\x92\x55\xba\x6b\x43\x40\xd1\x70\x75\xb4\x0e\xc1\xd1\x1e\x04\xb8\xd2\x16\xf1\x46\x8c\xc3\x4e\xe7\x0d\x2e\xfd\xf2\xd6\x1e\x84\x4b\x26\xcc\xca\x6d\x28\x8b\xdc\x17\x47\x86\xd4\x8f\xa4\x88\x89\x3b\xfa\x96\x1c\x20\xee\xc5\x42\xe1\x9b\x83\xdd\x5e\x47\xef\x01\x73\xaf\x59\xa7\xf7\xee\x67\xe3\x6f\x31\x2d\x6f\x94\x56\x2e\x70\xac\x1a\x59\xe0\xe8\x12\x3b\x70\x49\x44\x49\xac\xc9\x20\x40\x3c\xb2\xd7\x77\x42\x00\xfd\x86\x61\x7e\x62\x69\x8f\xb9\xe3\x6f\x43\xb0\x71\xbb\x2f\xa2\x35\x8c\xea\xee\x44\x00\x8b\xb9\x12\xbb\x71\x54\x1e\x0a\xa0\xf7\xe9\x1a\x0c\x0d\x7e\xb2\xeb\x91\xf9\x03\x81\x76\x9e\x30\x90\xfd\x8f\x29\x32\x9e\x88\x61\x7b\xb0\xb5\xd2\xc6\xf0\xb9\xda\x78\x11\x86\x92\x18\xaf\x06\xcc\xe1\xd3\xdf\x0d\x06\xbd\x08\x98\x2b\x67\xec\xc9\x1a\x2e\x09\xb0\xe7\xe1\xfb\xac\x44\xf9\x83\xde\xfd\x47\xcb\x94\x5f\x13\xbe\x7e\x4d\x44\x5b\x79\x82\x99\xa4\xab\xe7\xc6\x69\x63\x11\x14\x26\x55\xe3\xd0\xff\x25\x48\x09\x38\xfe\x17\x14\xa1\x51\x82\x94\x98\x3b\x04\xec\x8f\x40\xa0\x3c\x02\x30\x45\x0d\xc2\xb8\x3f\xef\xaa\x94\x2a\xa5\x6a\xa9\x2a\xfe\x2e\xf1\xdb\xbc\x57\x54\x34\x83\x2f\xc7\x1d\x7d\x05\xf8\x5f\x6d\x08\x96\xaf\x6c\x9a\x66\x01\xec\x8c\xb6\x1d\x52\xa0\x17\x4a\x29\xc7\xa3\x29\x63\x14\x02\xc3\x85\x0f\xa5\xae\x1b\x21\x38\xd9\x93\x13\x9d\x7a\x5c\x5b\x92\x6b\xbf\x1e\x82\xd2\xd5\x69\x08\x46\xa7\x21\xd8\xbc\xa6\x8f\x57\x4e\x43\x30\xb4\x43\x70\x35\x82\xc0\x1e\x18\x42\x43\x56\x0d\xe8\xb0\x77\x5a\x21\x28\xd1\xc2\x57\xa7\x10\x94\x6f\xd6\xb9\x35\x21\xc3\x09\x83\x41\xc8\x41\xf8\x4e\x23\x64\xe1\xa5\xca\xb6\x01\x41\xb8\x27\x23\xdc\xa3\x7d\xfe\x64\x30\x84\xc0\x5c\xde\x83\xc0\x39\x5c\x87\x20\x8c\x5f\xdd\x31\x5c\x3c\x75\xdc\x7a\x72\x86\xf9\xed\x90\x3f\xf1\x99\xde\x8e\xed\x28\x67\x18\xe3\xcd\x34\xd8\xd3\xbc\x41\xa1\xe6\x28\xc1\x22\x42\x66\xa3\x39\x36\x5d\xcf\x25\x81\x1b\xc5\xe1\x54\x85\x9b\x48\x94\x3d\xa2\xf3\x31\xd7\x6f\x69\x51\x92\x08\xa9\x2b\xcd\x2f\x71\xcc\x2c\xe3\x24\x04\x06\xa1\x6b\xaf\xb3\x09\xc1\xc9\x27\x3a\x65\x1e\x37\x83\x4d\xe3\x88\x65\x66\x33\x09\x26\x3d\x9d\x78\x14\x21\xf5\x13\x94\xd7\x8c\x4a\xca\xbd\x86\x74\x8a\xa9\x94\x8b\xc3\xa0\x9c\x3a\xae\x69\x51\x63\x33\x03\xa6\xfe\x9e\x34\xe0\x8b\xb4\xf6\xa6\x5e\x78\xed\xa4\xda\x8b\x50\x83\x95\x0c\xf0\xdd\x47\xbe\x8f\x42\x86\xcb\x13\xaf\xa4\x15\x3d\x7c\xd5\x31\x19\xa3\xa2\xd9\xdb\x0f\x0f\xf4\x10\x98\xd5\xd3\x36\xbd\xbf\x6d\xca\xb7\x4d\xf9\x3b\x6f\x4a\x33\xab\x65\xdf\xc7\xb7\x17\x7f\xb9\x5e\xef\x09\x49\xa2\xdf\xd5\xce\x36\xa1\x8a\xaa\x46\x30\x63\x5d\x31\x32\xe1\xa1\x03\x99\x5f\xec\xf0\xc3\x27\x2b\xca\x3d\x9b\xa6\x49\xa5\x97\x0a\x05\xf1\xea\xc0\xe4\x9b\x91\xf1\x1b\x48\x7e\x61\x90\x9c\xf5\x68\xd8\x77\x86\x4e\x57\x28\x07\x1e\x82\xc8\xaf\x00\xc8\x66\x58\xc8\x2f\xa4\x05\x41\xe9\x0a\xcb\xf0\x64\xe5\xfe\x8d\x9c\x79\xdb\x3b\xcf\xb8\x77\x8c\xec\xb1\x39\xfb\xee\x00\xf3\xb3\xc2\xc4\xf9\x60\xeb\x47\x4d\xb0\x3e\x15\x44\xa0\x05\x01\x62\xff\x78\x22\x1b\x44\xe0\xc1\x78\x35\x2f\x1f\x45\xe0\xe8\x14\x82\xe5\xdb\x13\x08\x9c\x75\x08\x3e\xd3\x85\x52\x31\x1f\x8c\x09\xf2\x4b\x10\x98\xdd\x7f\x0b\x25\xf0\x6a\x77\xc9\x8b\x84\x12\x58\x9e\xd8\x88\x9e\x4b\x2e\x63\x1f\x41\x26\xa1\x8f\xcc\x15\x7d\x8b\x89\xe3\x1f\x7b\x2e\xee\x81\xde\x03\xdb\xed\x5d\x7a\x7b\x55\x8e\x32\xd9\xb3\x71\xcd\x3d\x08\xcc\xa1\x70\xd4\x28\xc1\xc9\xe1\x08\x2e\x2f\x36\x51\xcf\x0d\xd0\xfb\x75\x1c\xf6\xd1\x65\x24\x02\x71\x81\xc6\x49\x13\x34\x0e\x53\xfd\x18\x37\x8a\x4a\xfe\xcd\x1d\x50\xfe\x87\xaf\x9f\xf1\x87\xf6\xa6\xf6\x87\x30\x72\x36\x21\x70\xee\x20\xf8\x7c\xfb\x46\x80\xff\x66\xb0\x6b\x2a\xe2\xe3\xdf\x1e\x76\xcd\xda\xa8\x1b\x98\x04\xd8\x7b\x99\x8d\xfa\xdc\x61\x4e\xde\x36\xea\xf7\xb7\x8e\xfb\x7b\x6d\xd4\xd7\xb5\x8b\x7e\xe5\x46\xdd\xc7\xb7\x17\x47\xa8\x8f\x07\xbf\x12\xa9\xbe\xed\xd5\xbf\x2f\x52\x7d\x08\x32\xbc\xed\xd5\xef\xed\xd5\x83\x2b\x87\xa0\x2e\x9a\xf2\x03\x68\x6c\x36\xa3\xea\xd7\xc4\x71\xb4\x22\x3b\x8e\x32\x3f\x80\x97\xf6\x1a\x35\x47\x9f\xf7\x73\x66\xff\xfa\x57\x58\x89\xfd\x93\x3d\x8f\xcd\x6c\x5c\xba\x43\x44\xba\xc4\xf1\x82\x90\x74\x59\x74\x57\x66\x32\xcd\xcd\xa5\xd9\xc1\xef\xcc\x7e\x9a\x89\x4a\x8f\x26\xa2\xbc\x96\x84\x69\xbf\x08\xf4\x5a\x91\x63\xbd\x1a\x65\xa3\xf2\xe0\x95\x88\x61\x96\x57\x9e\x50\xa8\x13\x15\x8d\x53\xa7\x01\xc1\x21\xf9\x28\xd9\x29\xff\x1e\x11\x5f\xf9\x79\x77\xf3\x02\xd7\xb7\x88\xaf\xcf\xb6\x41\x26\x9c\xad\x0e\x91\x87\x06\xc8\x73\x5a\xdc\x54\xf2\x50\xfc\x8f\xcd\x24\x4b\x51\x69\x4b\xdf\x02\xa5\x2d\xfd\x33\xfd\x53\x07\xa5\x50\xb8\x16\x94\x28\xc1\x41\x36\x8f\xaf\xf4\x1e\x38\xb9\x76\xa1\x6e\x83\x6b\x44\x4e\xf5\x1d\x60\xdc\x7f\x3d\xdd\xd7\xdd\x49\x7d\xf1\xe1\xa5\x8b\x89\x73\x27\xd3\x59\x09\x6d\x25\x48\x2a\x68\xc6\x6a\xd4\x19\x74\x4c\xb9\xde\x37\x40\x9d\x7e\x4a\xbb\x05\xc1\xd1\xc9\xf5\x29\x5b\xb3\x51\x39\x1b\xbe\xe3\xd0\xf5\x82\x22\x0a\x8b\x87\x9e\x43\x6c\x1c\x1d\x1e\x4a\x86\x23\xe5\xfd\x67\x35\x1b\x89\x8a\xe6\xf2\x97\xed\x16\x30\x3f\x90\x46\x4b\x44\x19\x99\x97\x0e\x62\xd8\x62\x66\xd0\xa4\xbc\xc3\x22\xcb\xee\x23\x4b\x38\x55\x32\x35\xb2\xed\x72\xe9\xfb\xeb\xa7\xe4\xec\xff\xc6\x8b\xde\xcc\x1e\xef\xfd\xc5\x71\x2f\xd6\x3d\x44\x6c\x37\x13\x89\xac\x7c\xa3\xdb\x73\x2e\x0e\x1e\xe2\xc5\xd7\x1b\x60\xbb\xbd\x47\x6f\xbf\x50\xba\xb8\xbf\xde\x86\xa0\x5d\x39\x85\x51\xc9\xc8\xee\x38\xd7\x0b\xdc\x8b\xaf\xb8\x7f\xe9\x66\x43\xd9\x74\x58\xac\xb6\xef\x87\xb2\xe1\x5f\xb9\xa3\xbb\x60\xbb\xbd\x4b\x6f\xbf\xee\x2b\xa3\xd2\x52\xf6\xdb\x42\x4c\x3f\xee\x8b\x63\xbb\x91\x84\xd4\xa3\xb2\xe4\xfd\x04\xa3\xa2\xb1\xd4\x3f\x86\x60\xe9\xb4\xc9\x70\x25\x05\x49\x19\x38\x11\x92\x00\x5d\xd4\x3d\x4c\x90\x1f\x1d\xa5\x2b\x81\x8f\xd2\x47\x7d\x17\xc4\x2e\x55\x11\x07\x4f\xd9\xf1\x79\x66\x5f\xbf\xa8\x68\x5e\x9b\x57\x97\x3a\x06\x9d\x4f\x75\x7a\xab\xf4\x08\xed\x93\xf1\x75\x44\x7f\x5d\x7d\xa9\xb3\x5f\xc3\x16\xfd\x65\x18\x74\x63\xb8\x74\xc4\x66\xa6\x86\x2d\x91\x22\xdb\xa7\x10\xb8\x43\x08\x5a\xfd\x11\x04\x3d\x17\x82\xcf\xd8\x15\xb4\x68\x62\xa8\x9b\xda\x58\xe7\x18\x6f\xa4\x46\xd4\x73\xda\x73\x64\xb2\xfd\xb8\x91\x6f\xde\xc9\x34\xb3\xf2\x33\xaa\x9a\x01\xe0\x1f\xb3\x27\x66\x1e\xbb\xe9\x28\xb0\xd4\xc4\x31\xc5\xf9\x7d\x7b\xec\x70\x4c\xb6\xe4\xc6\xd6\xf7\xbc\x25\x0a\xa3\x3f\xd2\x47\x5b\x7b\x93\x80\xf0\x96\xf0\x44\x99\x82\xf5\xfa\x30\xc3\x3a\x7d\x41\x0e\xb9\xbf\xf8\xe2\xdc\x60\x6f\x32\x0e\x8a\x1c\x03\xe5\x55\x19\x04\x7c\xce\x31\x08\x88\x63\x9e\xbc\x19\x04\xbc\x89\x08\x9f\x95\x48\x58\x2e\x9b\x99\xed\x43\x7a\x0e\xb9\xd8\x21\x7d\xcc\x0f\x06\xe1\x7b\x68\x93\x6f\xa4\xad\x23\xca\x26\x56\x63\xd6\xf0\xb1\xd1\x4d\xca\x4f\x19\xfd\xe4\x66\xd3\x86\xa0\x87\xc3\xdf\x80\x0b\x7c\x5b\xeb\xaf\xa3\x89\xc8\xcc\x1a\xbf\x7c\xc1\xb6\xd3\xc1\xd9\xe8\x94\x57\x94\xdb\x7b\x54\x74\x4a\xae\x72\xdf\x62\xe4\xe2\xde\xd6\x2f\x25\x17\x1f\xa9\x72\x9f\x60\x0f\x70\xd7\x21\xa9\xcc\x71\x42\x29\x10\x55\x4f\x92\xf8\x23\xd5\x94\x7f\xcd\x1f\x92\x07\xbd\xed\x2b\x51\xd1\xac\x6f\x56\x0c\xdd\x05\xe1\x36\xa6\x37\x86\xfc\x7c\x73\xef\x71\x06\xb4\xd5\x6a\x76\xff\xa6\xa4\x83\xbd\x97\x49\x25\xbb\xbb\x51\x92\x74\x02\x9c\xf2\x60\x19\xf2\x68\xbe\xe7\x70\x74\xa7\x29\x7e\x58\x7c\xdc\xaf\xc8\xc8\x86\x94\xfc\x82\x7d\xb7\x1f\x06\xf8\x59\x41\xef\x4f\x82\xe1\xa8\x78\x44\xea\x10\x7c\x3c\x39\x7a\x03\xbd\x6f\xa0\x77\x6e\xd0\x6b\xae\x48\xeb\xfc\x08\x91\x00\x79\x78\x90\x61\xd0\x4b\x1b\x7a\x63\xbe\x58\xb3\x0c\xe4\xde\xf6\x75\x9b\x82\x5c\x7a\xfb\xc5\x72\x88\xc8\xcc\x8a\x20\xe8\xe7\x39\xa8\xeb\x3e\x9a\xbb\x2e\x3d\x3f\x7f\xfd\xaa\x38\xf1\x95\xf5\x11\x04\x57\xf4\xb1\xbb\xff\xc6\x92\xff\x8d\x58\x72\x60\xec\xb7\x26\x13\xa3\xd6\x77\xd5\x7a\x79\xee\x43\x8f\x2e\xc1\x8f\x00\x7e\xca\xa2\x51\x35\x2b\x69\xa7\xfb\xdb\xbd\xd8\x74\x07\x0e\xa1\x9b\x7c\x33\x15\xb4\xd3\x9d\x5e\x62\x0a\xb7\xa8\xbc\x25\x76\x7a\x39\x8c\x65\xab\x29\x12\x2d\x1b\xe5\xa8\x68\x04\xc1\x55\x0f\x18\xfd\x4f\x8d\x1e\x83\x32\x55\x4a\xab\xed\xb5\x42\x60\x6c\xb8\x21\xb8\xdf\x0b\x81\xf1\xa5\x1e\x82\x5b\x9a\xf8\xdc\x08\xc1\xdd\x88\x26\x60\x08\xee\x4e\x43\x60\x1c\xd6\x43\x60\x94\xae\xd6\x21\xc0\x10\x46\xe6\xca\x44\x0f\xdd\x8b\x43\x14\xf6\xb3\xb1\xd7\x4b\x55\xdd\x7f\x74\xec\xf5\xc7\x5f\x1c\x3c\x7f\xd1\x6f\xc1\x76\x7b\x97\xde\x7e\x00\x3c\x0f\x9b\x6d\x08\x0e\x4f\x9f\x81\x22\x66\x4f\xf6\xe2\x0a\x59\x66\xfa\x6a\xb3\x25\x12\x59\xc7\xfd\xe9\x08\x0d\xb7\xfb\x3c\x6c\x12\x6b\x2b\x69\x34\x21\xb1\xb3\x51\x1c\x68\x85\x1f\x92\x3e\xd3\x7a\x76\x86\x10\x50\xf0\x97\xcd\xc3\xba\x71\x1b\x87\x0d\x48\x32\xd3\xc4\x74\x7f\x92\x26\x92\x3c\x0f\x64\xce\x26\x44\x7f\x26\xe3\xbd\x1d\xd9\xae\x87\xfd\xd6\xbd\x1f\x92\xb6\x6c\x82\x0c\x16\x21\x8c\x0c\x4f\xff\xcc\xcd\x90\x81\x58\xc6\x2f\x8e\x8b\xa2\xa2\x89\x2a\x27\xb7\xfa\x32\x30\x47\x15\x4c\xef\xfc\x5c\x0c\x7b\x37\x01\xc0\x0f\x1e\xa2\xf1\xf0\x39\x1b\x4f\x5d\xb6\xf3\xc8\x63\x40\xe6\x38\x7c\x24\x3f\xff\x0f\x17\x7c\xf4\x49\x25\xbf\x41\x4b\x0f\x15\x8c\xca\x15\x99\xf1\x3f\x72\x82\xde\x74\xc4\xd5\xd9\xe7\x66\xce\x71\x68\xa6\xb8\xca\x95\xea\x0b\x5e\xbf\x45\xdc\xd6\xb7\x43\x33\x5f\x31\x5f\xf6\x12\xac\xdf\x4a\xd6\xb5\xe3\x28\xb8\xf8\xe4\x5e\x12\x9f\xbb\x9d\x6d\x36\x41\x72\x17\x2e\x68\xfb\x9b\x9b\xcd\xa8\x14\x52\xa4\x43\xff\x88\xa8\x54\xec\x1f\x0b\x4c\x35\xc7\x35\x81\x3e\xca\x95\x67\xc1\x4a\xd5\x97\xc1\x7c\xcb\xae\x13\x50\x8c\x57\xa6\x5b\x85\xac\xc7\x01\x88\xba\x03\x71\xe8\xcb\xa7\x69\x49\x97\xc4\x72\xcc\x91\xfa\xe9\xb2\x79\x6f\xe1\x01\x04\x78\xf7\x94\x76\x9c\xfd\x76\xae\x67\x72\x28\xf9\xa1\x90\x92\xc4\xd2\xf1\x76\x08\x9c\x20\x9c\xf5\x7e\xba\xb2\x94\x33\x7c\xbe\x18\x03\xaf\xc3\xd3\xfe\x19\x5b\x9b\x5b\x6e\x47\x8c\x0c\x70\x3c\x81\x19\x53\xb6\xbf\x1f\xf0\xb6\x4f\x5f\x09\x64\x7d\x11\xc3\xb9\x09\xc9\xd6\xad\xd3\x09\x2e\x36\x42\xcf\xc3\x24\x98\xa9\x2b\x58\x6a\xe9\xbd\x3c\x5d\x41\x8e\x5e\x80\x6b\x03\xca\x0d\x7d\x0b\x84\xdb\x6d\x7a\x63\xd0\xed\xf8\xe3\x50\x96\xd5\xb3\x1d\x97\x27\x9c\xc8\xa6\x1c\x3f\x5e\x95\x93\x91\x5b\x33\xb2\x8e\x61\x63\xc8\x1c\xa1\x65\x93\xd9\x26\xee\x86\xb6\xd3\x45\xfd\x21\xca\x04\xdf\xac\x34\xf4\xcf\x13\xc1\x37\xa3\xa2\x71\xf2\xf1\x63\x8b\x32\x23\x5b\x4d\x9b\xde\x33\x10\xe8\x23\x1d\xe8\xfa\xde\x54\xac\xff\xe6\x65\xd8\xc7\x49\x40\x6d\x76\xea\xd4\x48\x5f\x9e\xf3\x70\xad\x27\x60\xc9\x51\xa5\xe9\x52\x74\x6a\xec\xaf\xd3\x7b\x2e\xd4\xff\xdd\xb6\xe2\xab\xd9\x27\x2f\x13\x1e\xac\x9a\x5d\x4e\xa4\x8d\xbd\x8b\x75\x74\x1f\xc5\xa7\x8f\x88\xc8\x17\xd2\x19\xc1\x52\x00\x0c\xf3\x79\x4e\x96\xfa\x11\xaf\x02\xf3\xba\x72\x44\xf7\x32\xda\x97\x62\x5f\x9c\xee\xaf\x3f\x80\xf2\x7e\xf7\x50\xcc\xbf\x23\xa2\x7b\x35\x4b\xff\x17\x20\xba\xaf\x88\xd8\x6e\x78\x83\xbd\xef\x1d\x92\xfb\x0a\x8c\xc8\x7e\xca\xf8\xec\x00\x66\x30\xae\x10\x24\xfc\x82\x30\xf0\x8f\x6e\xec\x9f\x49\x6d\xbf\x01\xa1\xbf\x31\x10\x9a\xb0\xd8\x3f\xb9\x74\x02\x7c\xe9\x7a\x3e\x8e\xfe\x3a\x6a\x82\xbf\x36\x9b\xe0\xaf\x93\x26\xf8\xeb\x90\xa6\x37\xf9\x61\x92\x87\x9b\xcd\x88\x09\x27\xc5\xbf\x25\xf1\x37\xf1\xd7\x2d\xc3\x17\x95\x49\xa6\xb2\x49\xb3\xd2\xdc\x8f\x85\x15\x6c\x0f\x97\xbe\x42\x70\x84\x3d\x0a\x66\x20\x04\xce\x48\xf6\xe2\x2a\xed\xd7\x21\xb8\xf1\xda\x6f\x7b\xe4\x6d\x8f\x7c\x77\x8f\xc8\x8c\xdb\x89\x43\x88\x33\xc4\xdd\xef\x5a\x7b\xff\x9e\xb8\x9a\x32\x6e\x3b\x0e\x47\x7b\xa5\xfd\x4d\xb1\x9f\x3e\x21\x11\x1d\x1e\x6d\x64\x4e\xc8\x0c\xd6\x33\x46\x02\x33\x11\x29\xdb\x67\x90\xee\x15\xf7\xc1\x7c\x3f\x88\xb6\xb3\x7c\x77\xd5\x11\xa7\x62\xb3\xc4\x0f\x28\xd5\x7e\xb0\x84\x74\x72\xfe\xb3\x95\xfd\x09\xa7\xb4\x1f\x2d\xf1\xd4\xad\xbd\x81\x9a\xd9\x1c\x77\x35\xc3\x13\xfc\x85\x7a\x61\x80\x02\x8e\x8b\x13\x3c\x2c\x2b\x0d\x65\x44\xfc\xb8\xa3\x1a\x5f\xe8\x62\x1a\x43\x43\xc2\xc0\xaf\x52\x63\x48\xde\x34\x86\xaf\x76\x53\xbc\xc8\xbe\xcb\xf8\xa4\xfc\x85\xfb\x7d\xf7\xb6\x47\x9c\x0e\xb7\x8b\x66\x12\x67\x21\x6d\x6e\x6c\x8a\xb0\x18\x30\x95\x37\x27\x61\x31\xbe\x1f\xb1\xe0\x79\xae\xa8\x68\x0c\xdb\x75\x08\x2e\x9d\x3b\x49\x88\xfd\x7b\x44\x2c\x78\xdb\x03\xaf\xa3\x89\xc8\x58\xe1\x64\x2e\x09\x90\x67\x07\x74\x1f\x6c\x20\x1f\xdf\xb3\x1d\xb0\x08\x97\xc1\xa2\x61\x44\x10\x14\x97\x21\x28\xb6\x64\xdd\x84\x79\x4d\x31\xfb\xe6\xd5\x11\x04\xcd\x15\x08\xca\xf0\x10\x82\xdd\x3d\xe1\xf4\x5a\x1a\x18\x30\x32\x60\xb6\xde\x4d\x74\xe3\xf8\xa2\xde\x25\xb0\x08\x2b\xb4\xde\x25\x08\x8a\xb1\x9b\x24\xab\xf7\xe6\xde\x85\xc0\x39\x0d\x20\x40\xfd\x2b\xda\xc2\xd2\x0d\x04\x5f\xd7\x21\x28\x9d\x10\x08\x76\xf7\x61\xb4\x34\x59\x6f\x38\x70\x49\xb0\x79\xec\xdd\x38\xfd\x3e\xdf\xba\x8b\x06\xa4\x95\x23\x5e\x71\x54\x3c\x86\x2e\x04\x76\xe7\x1a\x82\xd6\x87\x01\x8c\x96\x27\x6a\x68\x20\xfb\x3a\x44\x9e\x83\xa3\x3a\x3b\xf9\x91\x1b\x58\x42\xf6\xed\x45\xc4\xbe\x1c\xc4\xdf\xcf\xa2\x28\x3c\xc3\x55\x8a\x8a\xe6\xca\xd6\xb2\x50\x6b\x97\x8f\xe8\xce\x43\xf7\xf7\x10\xec\xdd\xf8\x31\x15\x48\x89\xa9\x2f\x94\xc8\xba\x75\xa5\xc4\x31\x14\x89\x3d\x4a\x66\x6d\xc0\x38\x54\xa0\x9d\x97\x60\xa5\xf2\x5f\x3d\x90\xc8\xb1\x87\x9a\x91\x9b\xf6\x83\xe5\x09\xea\x52\x82\x75\x31\x93\xe0\x35\x4e\xd0\xc0\x0f\xa7\xf2\xa8\xe6\x99\xa9\x94\xf8\x74\xdc\xc7\xb6\xc1\xfe\xa0\xa4\xec\x0c\xa2\x3c\x32\x26\x17\xd1\xad\xef\x12\xb1\xbe\xab\xf1\xfa\xae\xc6\xeb\xdb\x8c\x8a\x1b\x5b\x2e\x04\x66\xe7\xbe\x07\xa3\x2a\x5d\x81\x87\xc8\x76\x3a\x8e\xfd\xbe\x1e\xda\xbd\x3e\x22\xed\x68\xff\x7f\x1a\x4d\xb0\xff\x3f\x47\xc9\x9f\xcd\x66\x54\x6c\x85\xa0\x68\xd3\xff\x10\x14\xdb\xb1\x31\x7f\xfe\xf5\xfc\x66\x22\x0f\x5e\x51\xd1\xf8\xb8\xf1\x35\xe4\x56\xa2\x82\x45\x7c\xe8\x44\xb5\x32\x09\x29\xd3\x90\x49\xf5\x5b\x34\x4b\x3d\xa4\x30\x7b\xbe\xd4\xf5\x5e\x08\x4e\x1a\x22\x21\x5e\x1a\xad\x10\xec\x34\xc4\x6e\xf8\xb1\x25\xff\x14\xa5\xae\x73\x58\xb7\x89\x14\x8b\x73\xc5\x96\xd9\xcc\xd4\xe3\xcb\xfe\x4c\x6b\x2c\xf5\x7c\xfb\xf2\x69\xca\x3e\x6a\x4f\x3f\x6b\x4f\x23\x43\x04\xbd\x48\x01\xc1\x21\xea\x0f\xb0\xc7\x00\x01\x37\x88\x2f\x33\xa3\xf8\x38\xd6\xd5\x84\x51\x7c\xe9\x89\xf4\xee\x36\x72\x21\x20\x9b\x10\x18\x37\x6d\x7e\x32\x3a\x4b\x18\x4b\xa3\x07\x18\x2d\xe4\x13\x6e\x91\x7e\xc5\x2c\x1a\xca\x0f\x79\x97\xbc\x79\xa3\x7c\x3f\x40\x44\x79\x82\xb0\xf8\xe2\x06\x97\xd8\x43\xf1\x5a\x88\x84\x0d\x46\xd4\x3d\x70\x61\x64\x94\x26\x72\x1f\xdd\xbb\xb7\x48\x20\x10\x9a\xb7\xc8\x33\x17\x6f\x7c\x08\x23\x73\x22\x73\xd3\x73\xfb\x7d\x91\x99\xfe\xa7\x0b\x0c\x82\xe2\x13\xb9\x5c\x44\xc6\x30\x74\x21\xb8\x6c\xff\x86\x06\xda\xaf\xc5\x14\x7c\x62\xc2\xbe\xba\x7e\xe0\xf6\x62\xfa\x80\xd3\x06\x6c\x7a\x83\xab\x3a\x8c\x4c\x0a\x44\xb6\x42\xcf\x1d\xe2\xf7\x07\x7e\xdf\x8d\x36\xb6\x9a\x60\x63\xeb\xa8\x19\x15\x8d\x78\x5a\x5f\xd1\x15\x15\x4d\x74\xdb\x80\xe0\xf3\x00\x82\x93\xaa\x0b\x41\x65\xd8\x11\xe3\x31\x4b\x9a\x79\xfb\xc9\xfe\x71\x39\x69\x3c\xda\xa3\xa1\x1d\x43\xe0\xe7\xf3\xab\x78\xf3\xc9\xf8\xdd\x5a\x7a\x70\x23\x56\x4d\x2e\x5d\xf5\x1d\xf4\xfe\x8b\x73\x8f\xda\x97\xcc\x3a\x8e\xc2\xd8\x62\xa9\xaa\x7f\x4e\xe0\x6c\xf3\x66\xb3\xaa\x7f\x8e\x2a\xe2\x6c\x5a\x9a\xbf\xde\x1f\xa0\xe0\x5e\xe4\xaf\x08\xc2\x7e\x29\x2a\x56\x96\xf4\x06\x25\xec\x39\x81\xbf\xc4\xc5\x40\x39\xd7\x43\x6e\xb6\x51\xd1\x38\xb4\x59\x45\xf8\xd8\xa5\x37\xb3\xc4\x44\x37\xec\x90\x62\x86\x5a\x27\x52\x6d\xa6\xb5\x3c\xf8\xb9\x35\xcd\xc2\x32\x50\xda\xd8\x3b\xfd\x95\x2b\x3a\x32\x2a\xd2\x28\x0f\x06\x88\xf0\x03\x28\xb7\xe8\x7f\x0a\xf5\x4c\xa2\xef\x50\xb8\x27\x66\xe7\x79\xcd\x16\x67\x11\x55\xc6\xfd\x09\xeb\x87\xb1\xed\x34\xe8\x7d\x77\x4f\xb8\x10\x1b\x46\x2b\x93\x1a\xd2\xa9\x69\x33\x02\x6b\x98\xbc\x8d\x53\x9d\x03\x23\x9e\x42\xfc\xa0\x14\x9c\xd5\x02\xb3\xc7\x28\x5f\x52\x1a\xa4\x92\x50\x28\x79\x21\x0f\x19\xfd\xc2\x4b\x7c\x9f\xd2\x3f\x72\x21\xb8\x67\x14\xac\xcd\xce\xc2\xa6\x95\xb8\x49\x2a\x3b\xf5\xe9\x8c\xa5\x75\xe6\xbd\x7d\xe4\x4a\x28\xb7\x4e\x21\xd8\x9c\x22\x2d\xe6\x01\x17\x33\x5a\x7a\x0e\x48\xf3\x44\x4d\x45\xa6\xbc\xd0\x09\x6a\xdf\x7b\x1c\x9c\x18\x26\x58\x34\x4a\x60\xd1\x28\x73\x39\x53\x6b\x5f\x3f\x8e\xb9\x7c\x50\xc4\x89\xbc\xad\x34\xbd\x30\x1f\x0a\x7b\x22\xe7\x62\x10\x86\xd5\x8b\x8f\x09\xbd\x49\x10\xc6\xbc\x36\xfe\xb6\xc0\xe5\xb1\xe8\xd2\x64\xc1\x6b\x28\x50\x12\x3a\x7f\x36\x57\xd7\x81\x38\x15\x77\x11\x96\x63\xe8\x1f\x15\x4b\x7d\xbd\x0c\x8a\x65\x18\x43\xff\x7c\xc8\x2f\x9e\xe5\xcd\x0b\x9b\x14\x56\x0b\x3e\x26\xf4\x66\x96\x99\xff\xf1\xf0\xf4\xd7\xcd\xc7\xfe\xb3\xcd\x07\x85\xf3\x65\x69\x48\xdd\x16\xce\x19\xd3\x86\xbe\x35\xf7\x98\xce\xc6\xa5\xac\x1a\x7c\x4c\xe8\x8d\xaf\xf4\xd2\xe6\xdf\x18\x83\x9a\x4b\xd2\xc8\xfa\x97\x5d\xd4\x42\x41\xce\xd8\x7e\xd1\x6f\xbf\x3f\xb6\xa5\x64\x61\xd2\xec\xf8\x98\xd0\xdb\x8b\xd2\x23\x51\xd9\x90\x3e\x27\xb8\xf7\x92\xcd\x57\x92\x48\xaf\x72\x54\x2c\x79\x94\x30\x28\xc1\x94\xfc\x2a\xcf\xf8\xa8\xf2\xd4\xef\xf8\xe2\x9f\x4a\x2b\xc2\xc7\x2e\xbd\x99\xe5\xc3\x93\x5f\xbc\x07\xe7\x5b\x2e\x31\xa8\x9a\x77\xfb\xc5\x23\xba\x8e\xba\x97\x6d\xd4\x8e\xd6\x93\x21\x2d\x47\x45\xf3\xab\x5e\xe7\x43\xf9\xc3\x11\x9b\xa3\xa2\x59\x5d\xc7\xb4\x1e\xb3\xbe\x41\xe8\x9d\x13\x3f\x8c\x0c\x62\x04\x11\x1b\xc4\x74\xe5\xb0\x17\x8f\x67\xa9\xda\x38\xa6\x51\xd2\x3f\xec\xed\xcc\xd4\xaf\xc9\x17\x55\xab\x29\xba\xff\x8c\x02\xe4\x49\x5b\x92\x32\x1c\xd7\xfa\x32\xdf\x8e\x25\xa1\x15\x30\x8d\x4f\x1d\xfa\xd0\x5c\x5a\x3f\xbd\xd6\x97\xa3\x95\x6a\xba\x0f\xd6\x51\x4f\xde\x05\x6c\x5b\x47\xc5\xd2\x95\xee\xc6\xd3\x16\x6b\x17\x1e\xcb\x7c\xe4\x81\x4f\x5a\xad\x71\x75\xec\xd2\xfb\xc9\x4b\x6d\x7d\xf6\x73\xe5\x13\x4e\x16\xed\xe8\x37\x64\x9b\x29\x2c\xae\xa4\x93\x46\xba\x3d\xb7\x27\xb6\xda\x52\x54\xac\x7e\xa4\x24\xc3\x12\x67\x32\x4d\x63\xf9\xe8\xa3\x5e\xa6\x78\xb1\x9a\x96\xf0\x08\x0a\xfb\x62\xa6\xab\x42\x3f\xba\x1c\x15\x2b\xa3\x98\xc1\x04\xc5\xe5\x39\xe6\xf9\xfb\x1b\x96\x76\xe0\xa8\x32\x02\xc3\x0d\x32\x7a\x75\x0c\xe7\x70\x05\x82\xbd\xad\x57\x43\x16\x66\x0b\x2e\x6f\x8f\x20\x28\x79\x6d\x09\xa6\x62\xc7\x0b\x83\x48\xe2\x59\xe3\x6d\xfd\x8a\x2e\x3a\xe1\x88\x85\xbe\xa7\xdc\x64\x39\xe1\x44\x57\x12\x07\x6f\x27\x8e\xdc\xd8\xff\x3c\x9c\xe6\x6c\x27\x78\xdc\xec\xb3\xeb\xea\x3e\x04\x5b\x64\x46\x81\x07\x8b\xa6\xec\x71\xbb\x9e\x7a\x5d\xee\x3f\x94\xba\x59\x17\x8a\x8d\x01\x2d\x5a\x1a\xcd\xc8\x76\x45\x1b\x33\x49\x6c\xe1\x32\xd3\xae\x25\xcf\x27\x7d\x22\x95\x89\xd5\x34\x47\xbc\xa7\xfc\xfc\x3f\x5c\xf0\xd1\xe1\xa4\x7e\x83\x96\x1e\x2a\x18\x99\xa6\x04\x46\x1d\xff\xb2\x87\x7b\xd3\xb2\xb7\xf2\x09\x45\x7f\xf3\xc8\xde\x1e\x02\x83\xc6\xa1\xcd\x2a\xc2\xc7\x84\xde\x5e\x06\x14\x62\x0a\x55\x82\xd3\x8c\xce\xe9\xe1\x14\x97\xf7\x1c\x86\x4f\x3a\x25\xd1\xb2\xc4\x3a\xac\x7b\x21\xc1\x8e\x18\xe6\xa5\x12\xe4\x98\x67\x69\x93\xb2\x64\x4b\x61\x8c\x77\xa2\xa2\xb1\xbb\xd3\xa4\x0f\xbb\x9b\xf6\x8a\xbe\x15\x95\x25\xa9\xea\xae\xdb\xef\xa1\x00\x45\x8d\x46\x13\xec\x1c\x31\x1c\x56\x82\x51\xb1\xd2\xd7\x11\x28\x56\x42\x50\xac\x86\x51\x6c\xdf\x63\x8e\x0e\x02\xfa\xdc\xf0\xcc\xbd\x43\x7a\x0f\x09\x04\xdb\xeb\x10\x2c\x8d\x4e\x61\x06\x2b\x6e\x5c\x3a\x01\x12\xfd\x5a\x06\x8b\x70\x85\x99\xf5\x14\x97\xee\xf4\xcf\xdc\x1e\x69\x25\x36\xf1\xf9\x39\xea\x87\x23\xc5\xcf\xac\xde\x61\x9d\xd0\xdb\x6b\x43\x8c\xcf\xc9\x47\x3e\x09\x56\xc4\x2c\xcc\x6f\x39\x9d\x3a\xd7\x69\xa1\xbe\x2f\xa4\xba\x82\x9e\xa1\xf3\x47\xe7\x31\x2a\x2e\x6d\xc4\x34\x0d\x60\xf6\x55\x2b\xe2\xd0\x9b\xf9\x2f\xc1\xc6\x99\xf5\xc3\xed\x0d\x60\x1e\xf7\xdc\x0d\x60\xef\x52\x98\xdf\x46\xc9\xfc\xcc\x69\x14\xfc\x34\x9e\x79\xdf\x47\x29\xd5\xcb\xcd\x98\xbe\x7d\x74\x5f\x98\x20\xe3\xd2\xe8\xd0\x67\x9f\x18\x44\xe0\xa9\xa8\xb4\x9c\x4a\xac\x8e\x2e\x11\xe9\x5e\x22\x27\x76\x51\x89\xc4\x2e\x79\x88\x20\x89\x8a\x86\x6d\xde\x42\xf0\x85\x76\x8b\x45\xcf\xbc\xdd\x83\x80\x62\xe4\x65\x16\x3d\xee\xa3\x01\x41\x33\xd1\xbf\x5f\x25\xfc\x71\x82\xcc\x11\xed\x67\x70\x5c\x12\xe1\xe2\x1e\xe9\xb1\x19\x99\x25\x69\xc3\xbb\x7d\x77\xd0\x72\x19\x18\x59\x84\x95\x52\x6c\x48\xc5\x81\xc9\x95\x7e\x2b\x80\x09\x8c\x01\x4a\xc9\x28\xc5\x20\x85\xbe\x35\xbc\x0f\xad\x7d\x7a\x1f\x8d\x42\xb0\x54\x1f\x86\xc0\x2c\x31\x16\xd4\x18\x85\x80\x94\xec\x30\x83\x5f\x36\x2f\x51\x0f\x45\xdb\x0d\x01\xae\x32\x2d\x2e\x45\xc5\xca\x17\xbd\x47\xdb\x49\xdb\x5c\x8a\x83\x4b\x94\xa2\xa2\xb1\xbc\xf7\x81\x66\x30\x42\x42\xf4\x1e\x83\x5f\x83\x2a\x81\xc0\xec\xdd\xb5\x42\x60\x38\x90\x05\x7e\x48\xbe\x6c\x13\x0d\x90\x6f\x87\xfe\xa4\x8e\x63\xa8\xdb\xbf\x58\xc7\x31\x17\x87\x6f\x7c\xc2\xb4\xa7\xdb\xec\xef\x3c\x08\xeb\xee\x0b\xb3\xd1\x38\x8d\x09\x3e\xe6\x02\xc4\xb8\xbd\x94\x08\x84\x29\x25\x77\xfa\x7d\x62\x71\x5e\xa2\xf2\xbb\xf9\xf6\x69\xa2\x2e\x12\x2d\x3b\xe9\x72\x37\x4e\x95\x98\x26\xe5\xee\x14\x82\xaf\x34\xb1\x3e\x82\xe0\x88\xbe\xbb\x61\xd1\x86\x12\xb1\x46\xba\x49\x39\x46\xa0\x7f\xba\x74\x55\x23\x46\x79\x0e\xe3\x67\x9d\xf6\x0c\xf4\xd1\xce\x8a\x49\x6c\x46\x99\xe7\xc8\x9f\x66\x22\xa1\x39\xf2\xad\x24\xf6\x32\x29\x5d\x40\xf9\x80\x93\xe1\x23\xe8\xbe\xd7\x43\x3b\x3e\x77\x4b\x91\x29\x09\x6f\x36\x9d\xbe\x23\x53\x1f\x51\x71\x79\x40\x41\x42\x02\x53\x39\x37\xdd\xc7\xec\xb1\xd1\x26\xa7\xec\x4e\x28\x96\x3e\xed\xb7\xd3\x98\xeb\xac\xb2\xb0\x85\xe2\xda\xca\x51\xb1\xf4\x81\x6e\xfc\x72\x2c\x11\xf8\xd4\xf9\xa0\xdb\x51\x69\x45\x6a\x3c\xf4\x2f\x11\x49\x64\xe5\x32\xf5\x3b\xa2\x45\xe7\xa0\x7e\x39\x89\x4b\x73\xe3\x63\x42\x6f\x2f\x43\xd4\x5c\xae\xc3\x68\x49\x12\x61\x7d\x40\x03\xd4\x0d\x7d\x41\xc9\xc5\xb0\x8f\x0b\xc3\xcc\x8e\xde\x88\xe1\xdf\xf3\xc1\xc0\xf9\x2d\xec\xa2\xa2\xf1\xd5\x66\x9d\x32\x51\xc9\xee\xb0\x83\xc7\x18\x06\x1b\x42\x70\x3a\x8a\x99\xe6\xd4\x34\x2c\xdd\xc2\x13\xe1\xc9\x9e\x8f\xc2\x78\x16\xea\xc4\x2d\xfd\x0e\x42\x36\x91\xaa\x1c\x43\x60\xee\xfa\xbf\xbf\x5d\x4a\xbc\x43\x3e\xa2\x11\x4a\x84\x48\x8c\x7f\xda\xd9\x4c\x84\x49\x60\x5e\xa1\xd2\x77\xb8\x9c\x67\x92\x2d\x19\xb6\x79\x0d\x41\x85\x91\x7e\xd0\xa3\xc8\xf6\x8e\xa6\xe8\xa2\x1a\xd2\x45\x5a\x65\x54\xe3\x7a\x92\xba\x83\x60\xb8\xde\x86\xe0\xeb\x28\x8b\xac\x0f\x32\xa5\x78\xaa\xf5\x60\x6a\x56\xbe\x24\x16\x7c\xfb\x04\x82\xcb\x4e\x1c\x71\xb9\x23\x42\x26\xb7\x4e\xdb\x10\x74\x29\xe3\xf2\x19\x72\xee\xcb\xb8\x6d\xc4\x54\x69\x12\xa8\x99\xf9\x1e\xc2\x38\xa0\x40\x36\x4c\xfc\x44\xbc\xbf\x32\xc9\xa4\x48\x22\x7c\xa2\x29\x06\x34\x98\xa2\x9d\x3e\x6a\x18\x10\x6c\xc0\x87\x8c\x33\xd8\x02\x99\x57\x38\x25\x19\x80\x24\xb5\x2c\xd3\x9f\xad\x51\x8c\xfa\x19\x51\x53\xa5\xed\x3b\x7b\xd9\x5e\x33\x43\x91\xba\x01\x8e\x76\x4f\x81\x71\xd7\x36\x40\x83\x26\x28\x5d\x24\xdb\x3c\x27\x2d\x30\x7c\x69\xd2\x92\x2c\x44\xb6\x69\x3e\x80\x69\xd9\x87\xb8\x71\xca\xb3\x21\x38\x71\x27\x13\x93\xb9\xf2\x52\x8f\x2e\xf0\x13\x45\x3d\x1b\x46\xc6\x72\x8a\x7f\xb7\x71\xcb\x73\xc9\xef\xb9\x2b\xdf\xf6\xe5\xef\xb6\x2f\xd9\x91\x44\x83\x7d\xd9\x80\xab\x49\x07\x27\xde\x97\xad\x75\xe1\xac\x6c\xff\x93\xf7\xa7\x29\x59\x92\x6c\xbb\x17\x1b\x97\xce\x45\xc3\x21\xdc\x98\xf3\x30\x23\x66\x62\x22\xa6\x2a\x13\x60\x56\xf5\x30\x15\x35\xc5\x62\x26\xa1\xf3\x34\xef\x37\x58\xae\xd6\x2e\x84\x3a\x02\xc6\xe5\x52\x8b\x66\xaf\xf4\xe9\x10\x2e\xbb\x10\x94\x0e\xae\x21\xe8\x55\x5a\x10\xa0\x13\x08\xc1\x7a\xbd\xc1\xa2\x0c\xa7\x50\xc2\x25\xdd\x8b\x5d\x97\x74\x59\x1f\xb6\x77\xe9\xff\x23\xfa\xe7\xa4\x09\x3e\x51\x06\x7f\xa9\xae\x7f\x4c\x65\x95\xcb\x61\xda\x85\xa7\x60\xcb\x37\x3e\x6c\x43\x60\x04\xe8\x00\x82\x6d\x1b\x82\xbb\xe3\x10\xac\x04\xeb\xa1\xd8\x05\xc1\x66\x98\xfa\x08\x72\xaa\xc3\xfe\x3e\xf1\x33\x11\xbe\x81\xae\x2b\x76\xe0\x7d\x30\x12\x89\xd8\xe7\x81\x25\xb2\xaf\xa6\x13\x99\xcc\x0f\x94\x32\x96\x1e\x0c\xc8\xf3\x13\xc4\x71\x12\x45\x20\x57\x22\xd7\x11\x66\x96\xd1\x52\x49\x9e\xd5\x9b\xf6\xb4\x2a\xb6\x5a\xd5\xeb\xf3\x28\x63\x1f\x56\xb3\x9b\xf5\xc3\x8f\xb4\x22\xf3\xb8\xe7\xd2\xbb\x90\x59\xb6\xfe\x8e\x32\xcb\xde\x16\xe3\x8c\x32\xe2\xca\x65\x23\x15\x57\xee\x78\xbd\x30\xf0\x7b\xd1\xce\xe4\xd6\xad\x7e\xd5\x2b\x53\x9b\xf6\x67\x24\xfc\x4c\xc0\x3f\xfa\x48\xab\x1d\x5e\x9d\xd2\xdb\x9b\x80\xff\x31\x02\xfe\xa8\x0a\x19\xe8\x15\xfe\x29\x3b\x7e\x80\x48\x2b\xec\xb3\x99\x93\x39\x7a\x2e\xdc\x30\x8e\xf5\x63\x99\xab\xff\x11\xeb\xa2\x52\xf9\xa7\xfd\xe2\x4a\x51\xd1\x74\xbb\xfb\xb4\x33\xed\xd1\x88\xde\x18\x4d\xb3\x1c\xac\x3f\xa0\x0c\x2f\x51\x20\x75\x9c\x51\x68\x8f\x8e\xf6\x21\xa0\xab\x85\xc9\x2a\x19\x28\xe9\xee\x43\xb0\x7c\x4f\x73\xdd\x0f\xc5\x79\x32\xbd\x1c\x79\x68\x2a\x0f\x48\x25\xa3\xc9\xdb\xeb\xf6\x3a\x04\xa5\xe5\x3d\xa1\xb0\x6e\x8e\x20\xe8\x57\x0f\xc4\xe8\x27\xd8\xba\xb9\x2e\x14\x86\x29\xa8\x34\x12\xc5\x3d\x05\x9a\xa3\x15\x4a\x1a\x60\x08\x28\x91\x65\xb2\xe0\xa5\xcb\x09\x1c\xcf\xb3\xe9\x7e\x78\xf1\x3d\x9c\x25\xcf\x4f\xfa\xe5\xd6\xec\xc1\x5c\x05\x4f\xe9\x37\x5f\xbb\xf9\x0d\x99\xf4\x0f\xa9\xc7\xcf\x12\x8f\xf4\xca\x2d\xb3\xfd\x4d\xe4\xf5\x9f\x50\x0f\x79\x01\x8a\x4d\x78\x4c\x98\xa8\x46\x57\x18\x98\x3a\xd9\x59\x8f\x8a\x4b\x4b\xba\x0d\x8a\x4b\x3d\xae\x26\x5d\x11\xe0\x2a\x96\xc8\x95\xcd\x4a\x54\x34\x3e\xc3\x66\x0f\xf4\xc3\x06\x04\x83\xc3\xd1\x01\x58\xbe\x39\x09\x41\xb5\x37\x0c\xff\x7f\xf6\xde\x45\x39\x6d\x5d\x7b\x1c\x7e\x15\x95\xf9\x4f\x4e\xf8\xc5\xb0\x6d\x20\xd7\x1e\xce\x1e\x20\x69\x92\x06\x48\x1a\xc8\xa5\xbb\xa7\x5f\x46\xd8\x0a\xa8\x18\x89\xf8\x92\x94\xd4\x79\xf7\x6f\x24\x59\xb6\x6c\x0c\x81\x36\x6d\xb3\xf7\x61\x68\x63\x5b\x5a\xba\x6b\x2d\xad\x9b\x24\x50\x39\xbb\xf6\xc1\xd7\x81\xe9\x07\x65\x43\x2d\x77\x02\xc7\xbe\x23\xad\x9e\xac\xb0\xdd\xb2\x0e\xae\x8e\xbb\x41\x61\x77\x54\x6c\x89\x62\x76\x63\x3e\x22\x28\x18\xbe\xcf\x63\xdc\x56\x8b\x3d\x9a\x15\xe2\x07\x25\x45\xff\xf6\x1e\x39\xbe\x0b\x6d\x34\x0a\xde\xb7\x22\x39\x06\x1c\xef\x73\x61\x66\xc8\x78\xa4\x52\x36\x96\x2e\xe2\x4d\xf4\x0b\x7e\xc2\xc1\x90\x55\xb4\x33\x69\xb1\xc7\x52\x42\x4d\xb9\x59\xd7\xc1\xc1\x48\x07\x94\xc1\x73\x1e\xda\xe2\x00\x24\xbc\x3a\xc0\xf8\x02\xd9\x44\x68\x48\x94\x89\xe7\x39\x9f\x21\x6d\xa8\x83\x1a\x83\x6d\x9d\xe9\xa0\xc6\x96\xb2\x93\xb1\x0e\x9a\x8d\x90\x39\xbd\xb2\x75\x70\xf0\xa1\xfd\x8a\x64\x19\xb1\x5f\x84\xdb\x11\x10\xeb\x04\x6e\x9e\x43\x5c\x18\x61\x61\xe4\x56\x66\xcc\xc9\xe0\xee\x95\xdc\x93\xc2\x09\x16\x4f\xd1\x6f\x4a\x79\x85\x33\x14\x22\x2d\xb7\x6e\xdc\xb1\x3f\xac\x8c\x5d\x2b\x61\xb5\xe0\x39\xf3\x72\x67\xc6\x0e\x93\x76\x8e\xb8\x56\xfc\xd6\x3e\x7d\xd6\x9b\xf3\xa8\x83\x2b\x23\xfd\xf2\x72\xf0\x2f\x5d\xd2\xbc\x84\x8c\xf7\x89\x3d\x26\x20\x5b\x3f\x85\x47\x67\xa5\xac\x07\xdc\x93\xb3\xe2\x73\x7b\x80\xa1\x7f\x70\xf5\xa0\xa2\x98\x22\x4e\xe0\xc8\x1c\x40\x6f\x18\xd2\x05\xc3\x90\xbb\x47\x82\x02\x9c\x30\xb6\xb4\xa7\x2b\xe7\x43\xfc\x00\xaf\xc4\xfd\x3c\x3a\xcd\x13\x96\x29\xbe\xbf\x66\x8f\x15\xa7\xb4\xc8\xbe\x91\x1d\x75\x68\x1d\x68\x0e\xa4\xb1\x27\xb4\x29\x0b\xfb\x32\x38\x3b\xe9\x82\xb3\x13\x26\x19\x56\x5c\x6e\xc6\xf1\x43\x13\x73\xc2\x3d\xdf\x28\x47\xa7\xa8\x95\xbe\x52\x97\x41\x1a\x77\xa7\x27\x57\x45\x93\x3b\xc9\x00\xe4\x33\x1a\x74\xd7\xf2\x81\x71\x3b\x91\x9a\x09\xeb\xc4\x90\x5a\x1b\xae\x58\xf8\x72\xad\x07\xa5\x4a\xbc\xb4\x5c\x38\xfe\xe8\x4e\xd6\x6a\x2b\x28\x6c\x9e\x72\xfb\xb6\x30\x41\x19\x87\x7d\xef\xb4\x38\x0c\xca\x25\x75\xd2\x79\x83\x11\x24\x96\x9f\x68\xc9\x66\x65\x33\x28\x6c\xbe\x2b\xf6\x45\xe5\x37\xdf\x47\x4e\xcc\x03\x16\x58\x3a\x38\x6c\xf5\x8a\xfd\xc0\x50\x33\x1a\x40\x62\x4d\xfa\x53\xae\x3c\x62\xdb\xd3\x6e\xa9\x68\xa9\xee\x3c\xf1\xb6\xa7\xa5\x26\x71\xda\x41\x44\xf8\xf4\xf0\xcc\xc7\xb5\x31\x7b\xfc\x0f\x4c\xe4\xbb\x13\x1d\x4c\xda\x2f\x62\x96\xd9\xbe\xd4\xc1\xf6\xe3\x3e\xf7\x67\x2f\x45\x23\xe9\x40\x97\xd0\x09\x74\xdc\x61\x86\x80\xdc\x2b\xde\x2d\xe7\xad\xbc\x88\xd4\x76\x84\x59\xb6\x63\xa7\xc6\x1e\xff\x03\x43\xf8\x92\x52\x9b\xa1\xa8\xaa\x4e\x7c\x68\xc3\x9b\xa6\x3f\x1a\xfb\x0e\xbf\x2e\x58\x8c\xdb\x14\x6b\x1b\x14\xb6\xba\xc5\xb1\x18\xc3\x24\x6b\x1b\x7a\x68\x6d\x06\x85\x52\xbd\xcf\x81\x8c\x6d\x48\xd8\xd3\xde\xbc\x3e\x60\x3c\xc2\x29\xd8\x79\x37\xf1\x81\xe1\x52\xc3\x0f\xb6\x0d\xb5\x70\x73\x80\x43\x2d\x59\xe4\x63\xc8\xfe\x97\xa4\x3f\x98\x5d\x1c\x4a\x6f\x43\x50\xd8\x19\x66\x4b\xfd\x95\xd0\x0b\x91\x01\xf7\xf7\x7b\x67\xc5\x21\xd8\x9a\x10\x1f\xd4\xc8\x01\x30\x4e\xf5\xa1\x78\x69\xd7\x66\xbe\x4c\xc1\x8c\x6b\x43\xb0\xf3\xee\x91\x33\xff\x11\x01\x6f\x41\x33\xdc\x7b\xd4\xe8\x74\x23\x62\xc5\xfd\xa9\xb6\x27\x45\x98\x24\x56\x71\x3d\x5f\xe2\xbe\x8a\xc6\xbb\xa3\x09\xf7\x89\xbc\x3b\x61\xcf\x33\xce\x3a\x31\x9e\x6a\x53\xfa\xce\x54\x3e\x70\x5f\xee\x96\x54\x8c\x0e\x19\xd3\xea\xeb\x49\x0d\x9f\x39\x6b\x42\x32\xe0\x8a\x3e\x15\x9b\x3c\x9e\x2b\x3e\x5c\xcc\xf1\x5f\x5a\xc3\x77\x12\x21\x68\xf4\xf6\x8b\x34\x7c\x9b\xdb\xea\x08\xf7\xa1\x25\x7d\x13\xc5\x42\xc4\x38\xaa\xa0\x00\xcb\x6c\x55\x0e\x4f\x7c\x2b\x98\x2f\xe3\x5b\x6a\x9c\x99\x3c\x5f\x74\x41\xcb\xbf\xcc\x0d\xe3\x9f\x42\xc4\x40\xb9\x71\xa7\x07\xbb\x9b\xb1\xda\xb0\x05\x87\xd0\x75\xc3\x7d\x55\x2d\x85\xa5\xb8\x3a\xee\xd6\x82\xc2\x36\xdf\xd3\x26\xfe\x46\x8a\xf7\x90\x78\x71\x3e\xe5\x0b\x8b\xba\xbf\x35\x75\x30\x9a\x34\xd9\xfb\x4e\xab\x99\x3c\x8e\xa0\x05\x09\xb6\x61\x74\x21\x07\xd7\xe4\xcb\xac\x76\x95\x33\x00\x83\x82\x31\x7c\x7f\xcc\x2f\x61\x02\x26\x63\xbf\xb6\x36\xaf\x75\x30\xba\xae\xeb\xe0\xfe\x5a\x07\x97\x27\xa1\x7e\x29\xc1\x87\xb5\xb1\x49\x5d\x0c\xd3\x9e\x80\x56\xd1\x7d\x35\x9e\x80\xc2\x0d\x86\xd5\xa8\x04\xcb\x26\x7b\xae\xdc\x60\x5e\x9d\x1b\xcc\xdf\xad\xa4\xb9\xae\x30\x65\x65\x33\x41\x9b\xde\xd3\xa1\xff\x48\x90\x97\xc5\x65\x6e\xb6\x8a\xad\x97\xe3\x32\x43\xf2\xec\xb5\xf8\x21\x2c\xcd\xd6\xff\xd8\x21\x2c\xdf\x2d\xef\x6e\x6e\x26\xc7\xcb\xc5\x3d\x9c\x29\x14\x6c\xde\x17\x0f\x16\x1f\xae\xc5\xe8\x13\x97\xec\x08\xcb\x78\x5c\x7b\x77\x1f\xed\xf5\xff\x3d\x43\x36\xb2\x75\x70\xea\xbe\xea\x51\xcb\x58\x54\x2b\xa8\x9d\x5c\xf2\x4e\x47\x6e\xd6\x4e\xab\xf3\xa2\xff\xa3\xa7\x1c\x4d\x89\x74\xa5\x8a\xcb\xb2\x1d\xb7\x9a\xec\xb1\x42\xb7\xe5\x44\x3a\x45\xaf\x72\xea\x40\x7b\xc6\x11\x09\x63\xb9\x41\x7c\xde\x11\x09\x95\xb9\x3f\xb1\x25\x7c\xcc\x77\xc8\xd1\xb1\xd8\x21\x77\xf2\x02\x27\x6a\xc4\x9b\xbe\x53\x96\x24\xae\x27\x3f\xf8\x0d\x63\x93\x38\x48\xe3\x8c\x12\x0f\x43\x02\x05\x36\x9c\x29\x02\xab\xb4\xfc\x74\x6b\xa1\xf9\x67\xc0\x65\xd6\x41\x31\x65\x00\x4a\x19\x81\xb6\x82\x42\xc9\x87\x1c\xec\xfa\x40\xd7\xc1\xc8\x27\xcd\xe2\x10\xec\x9c\xc3\xb4\x25\x08\x5c\xdd\x11\x3f\x28\x29\x92\xe8\xd9\x84\x92\xfe\x04\x86\x92\xf3\x49\x87\xf3\xa2\x80\xeb\x0f\x77\x88\xf4\x27\x89\x64\x50\x7e\x84\xb4\x3f\xda\x21\x60\x77\xfb\xfa\x1c\x18\x76\xf7\xd1\x07\xa5\x53\x62\xea\x60\xab\xce\x9a\xa9\xf8\x97\x7f\xa0\xae\x07\x09\x9c\x4c\x9f\x17\x52\x41\x8c\x13\xfd\x81\xb3\x58\x84\xdf\x39\xcb\x05\x5d\x50\xf6\xf8\x47\x1f\xc5\x12\x79\xf1\x7e\x98\x3c\x4e\x6c\xea\x58\x30\xa3\x4b\xed\xe2\x87\x45\x8e\x60\x99\x4d\x34\x59\x8f\xb2\x4c\xd0\x05\xb5\xa3\xed\x89\x3f\xa5\x47\xcb\x90\xfe\x26\x34\x04\x8f\x1f\x6c\xee\x88\x13\x1f\xd6\x07\x49\x9f\x52\x12\x9c\x2b\x7b\xb4\x76\x83\xc2\x16\x2d\x36\x85\xda\x3c\xdc\x86\xc1\xc5\x3a\xcc\x42\x3b\x23\xd2\x29\x36\xc1\xf6\x97\x5d\x3f\xa8\x28\xee\x9c\x1d\x38\x1c\x40\x1b\x93\xd8\xae\x1a\xd9\x50\xf4\xa0\xb0\xeb\x4b\xcb\xaa\xb4\xa3\xcc\xde\x55\x5a\x59\x82\x80\x96\x6a\x87\x97\x2c\x6b\xa3\x4e\x5b\xfc\x79\xf7\x0e\xbe\xe2\xb5\x4e\x50\xe6\xd7\xb0\xcc\x89\x63\x16\x36\x15\xa3\x4a\x07\x8e\xa0\x33\x84\xc4\xca\xc0\x2e\xa7\x78\xbe\x08\x76\x09\x2c\x62\xc0\xfc\xcc\x9f\xf3\x9f\x89\x45\xd1\x67\x50\x56\x4c\xf1\x1d\x44\xc3\x43\x3e\x14\x52\x0e\x4e\xf6\xf9\xff\xa0\xb0\xe3\xf0\x8d\xcd\x11\x51\x0f\x15\x8c\x7e\x62\x6b\x6c\xe2\x02\x10\x1e\x22\x88\x3e\x4b\xbb\xbb\x7d\x7d\x59\xfc\x00\x8c\x91\xf1\xe8\x83\xad\x46\x4b\x07\xef\x98\x84\x3c\x6c\x4b\xc3\xb1\x78\x53\x2d\xcd\x5b\x4c\x94\x2f\x1d\xeb\x3e\x38\x65\xc1\xef\x42\x0b\x36\xdf\xb3\x19\x5d\x95\x9f\xfd\x52\xe2\x7b\xdc\x4a\xef\xb8\xc3\x61\x72\x3d\x55\x3c\x29\x3a\x0e\xb2\x08\x1a\x52\x7b\x12\x71\x98\x09\x85\x1b\x62\x6d\x7e\x41\x85\x5b\xa8\x6f\x43\x82\x58\xa2\xd5\x5e\xee\x65\x39\xcc\xf2\x66\x6c\xef\xe9\x42\x3c\x46\x62\x3b\xf1\xfb\xe4\x96\xe2\x58\x11\xb6\xc8\x2f\x28\x18\xf8\x61\x47\x07\x5f\xb8\xde\x7a\x42\x9f\xd9\x52\x3c\xfb\x8d\xdb\xd2\xeb\xd1\x46\x4c\xe1\x6c\x9e\x7c\x5b\x6a\xe3\x64\xbd\x1e\xba\x6f\xd5\x2d\xf1\xe2\xdf\x19\x53\x50\xbb\xdb\x75\x71\xd1\xfa\x76\x25\x5e\x51\xba\xd0\x1d\x0c\xe5\xdd\xf4\x49\xa1\xa9\x5e\xec\x2d\xb1\x41\x8f\x41\xa3\x0b\xc2\x1e\xbf\x6c\xa6\x46\xf7\x7f\xf2\x96\xf4\xb0\x8d\x5d\x1c\x74\xeb\xe9\x73\xa6\x4a\xd7\xac\x25\x8b\x9c\x33\x65\x64\x22\x68\xa8\x5d\xe1\xd9\x18\x5f\x2e\x08\x7b\xfe\xc2\x73\xa5\xb8\x85\x61\x5a\xcd\x57\xe2\x73\x25\xd2\x04\x96\xdb\x91\x53\xdd\x77\x6f\x22\xad\x11\xa1\x04\xe0\xae\x00\x8a\xdd\xab\x8b\x06\x4e\x68\x66\xe8\x8a\xce\xe5\x3c\x8c\x5c\xbc\xb8\xe3\x47\x79\xcc\x8f\xb3\x13\x7f\xfd\x78\x21\xab\x48\xba\x5f\xda\xfc\xa9\xbf\xa0\x50\xea\x79\xfb\xac\x78\xc3\x2a\x9b\x3a\x30\x06\x7e\xb3\x5b\x3c\x06\xdd\x6b\x5f\xa0\x95\xdb\xd6\xc1\x7d\xcd\x97\x9b\x9d\x59\xc3\x11\xd1\xc1\xb8\x5d\xd7\xc1\x45\xd4\xbd\xf1\xd9\xb7\x8b\xbc\x2d\x9a\x62\x59\xb8\xad\xca\xcf\x2f\xe3\x57\xc3\xfd\xa4\x9c\x03\x43\x31\x4a\x74\x07\x78\x34\x1e\x24\x3d\x3d\xb6\x82\xc2\xe6\x55\xb1\x26\xcf\x3f\x10\x7e\x1e\x1d\x9f\x87\x19\xf5\xc3\x96\x5b\xac\x05\xdb\xbb\xb1\x5d\xa6\x4b\x87\x13\x1a\xb0\x75\xe2\x3d\x5b\x27\x76\xe3\xfb\x97\x42\x63\xc9\x87\xf7\xef\x43\xc3\x62\x7c\x2b\x49\xfa\x16\x95\xa0\xbc\xa3\xd4\x8a\x8e\x32\x75\x8a\xfb\xc5\xb3\x1f\x51\x01\xcf\xd2\x29\xb6\x07\x2c\xe3\xf1\xd7\x47\xf6\xf8\x27\x72\x0d\xfc\x9c\xe7\xde\xc2\x4c\xfe\xd2\x4c\xfb\x87\x71\xd2\xe7\xe0\xc2\x86\x90\xf4\xa0\x72\x08\xa2\xba\x3f\x67\xbb\xf8\xb0\x88\x93\xff\x7c\x5e\xaf\x54\x3b\x3b\x62\x19\x95\x2e\x86\x94\x3d\xff\xd7\xf6\x53\xa8\xfa\xc0\x0b\xd7\x2b\xb4\x91\x93\xf6\xb3\x2a\x85\xdc\x36\x13\x74\x1f\x8a\x9d\xd8\x2a\x6a\x86\x5c\x37\x9c\x79\xf8\xce\xe6\xc2\xc7\xf1\x6c\x0a\x77\x2b\x96\xff\xb8\x36\x66\x0f\x89\x40\xbb\xff\x20\x04\xfa\x49\xb6\xbf\xd8\xd7\x4a\xe1\xbd\x2f\x6d\x68\xe1\x7b\x71\x67\x48\xac\xb5\x08\x9d\xe6\x76\x9a\xc5\xfb\x1f\x74\x98\x9b\x16\x9b\x3a\xef\x8f\x59\xb6\xd8\xbb\x66\x8f\x7f\x22\x01\xfc\xf9\x3b\x64\xf8\xd0\xf1\xfb\x7b\xa3\x95\x4b\x39\xba\x6c\xa7\x51\xbc\x7a\xd1\xa3\xcb\x84\x2d\x8c\x67\x3b\xae\x51\xf6\x58\x0d\xdb\x52\xc3\x56\x52\x74\x4c\x1f\xd1\x10\x7a\xc8\xc1\xa4\xe7\x3b\x7d\x45\xfd\xaf\xea\x9a\x4a\xc5\xaf\xa0\x50\x7e\x5f\xdc\x9c\xd2\x38\x65\x91\xc5\xc5\x4f\x34\x0b\x0a\x25\xd8\xe7\xb9\x6f\x8f\x3e\x0c\x8a\x2e\xb8\xab\xdf\xbf\x5f\xed\x53\x5b\xda\x3c\xa6\x48\xe8\x1f\x91\x83\xee\xa3\x03\xe8\x54\xb1\xf6\x6a\x71\xa1\xf6\x39\x4c\x14\x02\xee\x15\x17\x6f\xaf\x7e\xf1\xa1\xc9\xf3\xff\x54\xce\xaf\x5f\xcb\xd0\x18\x77\xe2\x6a\x05\x3e\x34\x9e\x0d\x89\x87\xcd\x3f\x6a\x8f\xd4\x41\x2e\x3f\x7f\xad\xa0\x97\x40\x41\x37\xf8\x45\x66\x57\x07\xdd\xc0\xe8\x30\x8e\x4e\x07\x86\x0e\x74\xb0\xa4\x3b\x54\x39\xf5\x7f\xd1\x54\x73\x7f\x95\x65\x19\xd3\xc5\x7f\x41\xa1\x64\x5b\x57\x3a\x80\x67\xd7\xe2\x9c\xb1\x26\x1b\xb6\x7b\x53\x07\x5d\x26\x24\xf9\x2d\x1d\x74\x5a\x6a\x08\x7b\x89\x42\xb6\xb6\x58\x67\x33\xbe\xbe\x7c\xa0\xcb\x03\x07\xb2\xae\x49\x8c\x8e\x32\x28\x1f\xeb\x53\x37\xb9\x94\xdf\x45\x9f\xf1\x0e\xbf\xf8\xf0\x83\x78\x5e\xa5\x62\xd9\xf8\xee\x9b\xf2\x42\x57\x0e\xc1\x77\x1c\x56\x74\x1d\xf4\x9b\x82\xa4\xb8\x86\xf0\x2a\xb5\xae\x85\xec\x37\xb6\xc4\x93\xc5\x33\xc1\x2f\xeb\x5b\xd9\x89\x25\x18\xdd\x19\x53\xbc\xdc\xa0\xdf\x7f\xa3\xd8\x0f\xa0\xe0\x02\x70\x77\xc7\xf6\xac\x14\x29\x16\x3f\x2b\x83\x18\xe4\xe7\x55\xb7\xf9\x77\x23\xf0\xff\xe3\x2e\x72\xf2\xf4\x0b\x49\x3f\xeb\xc8\x19\xf9\xa1\xb5\xb9\xd6\xe9\x82\xda\x7e\x37\xa8\x7c\x29\x62\x50\x09\x2f\x99\xfc\x1d\x9e\xa3\xea\x2f\x28\x18\x75\x72\x7e\x50\x3c\x04\x46\xb3\xdb\xe3\xcf\x99\x52\xf6\xa2\x57\xd1\xff\x48\xda\xd5\x35\xf6\xff\xe4\x6b\xec\xb7\x42\x0f\x71\x89\x1e\x0d\x48\xa0\x23\xdc\x5b\x18\x6b\x71\x75\xd0\x05\x57\x07\x9d\x6e\x60\x18\xc5\x9a\x60\x2c\x0a\xc6\x77\xe9\x9c\x5e\x66\xd1\x37\x2e\x3c\x78\x55\xa4\xe0\xfa\xac\xc6\x1e\x86\x5d\x3b\x89\xce\xab\x7f\x15\x0b\xd8\x6a\x45\x78\x0d\x25\xcd\x5d\x11\x36\x2b\xc9\x15\xa1\x01\xc7\xe8\xe6\x12\x39\x16\x0a\xa7\x3d\xe7\xaa\x03\x63\x52\xac\x08\x6e\x3a\x3e\xb3\xd4\xe2\xfb\xbe\x0f\xa8\x38\x75\x1d\x18\xd6\x97\x5b\x3d\xd8\xd4\x93\xf9\xbd\x83\x0e\x15\x59\x45\xd8\xe3\x14\x2b\x31\xe6\xfc\x86\x15\xa5\xe4\x77\xc8\x43\xf1\x02\x94\xae\xfa\x94\x3d\x57\x78\xf2\x9a\x67\xef\x2b\xc1\x93\xca\x6e\x72\x69\x68\x41\x0b\x61\x07\x06\xef\xc2\xb5\x41\xdc\x9f\xad\xae\x11\xdb\xca\x1a\xf1\x3d\xf3\xfd\xbb\x84\xd0\x70\xcf\xf7\xef\xf8\x71\x92\x70\xbd\x12\x42\x57\x42\xe8\x2f\x16\x42\x57\xa4\xf4\xd5\x95\x34\x5f\x08\xdd\x4e\xb2\x08\xe7\x68\x32\xfc\x02\xef\xf1\x30\x62\xb4\x19\x31\x3d\x6c\x75\x03\xc3\xfd\x2e\xf5\xdd\x8c\x1f\x77\x72\xbc\x1a\x3d\x80\xd1\x2d\x7c\x88\xbd\xb5\x8c\x66\x5d\x07\x0d\x12\xbe\x94\x6f\xaf\x75\xd0\x30\x74\x70\x24\xf4\xd8\xa7\x3a\x60\xc1\xc6\x41\x53\x07\x4d\xd6\x82\x86\x1e\x3a\x1b\xc4\x3b\x9c\xa7\x5e\x12\x0e\x09\xca\x7d\xca\xa9\xb7\xb8\x5b\x52\x61\x33\x53\xcc\xcc\x65\xa9\x14\x2f\x51\x5a\x60\x94\x92\xa3\xd8\xa1\xbe\x37\xb8\x39\x44\xd4\xe9\x63\x18\x14\xf4\x52\x50\xd2\x03\x3d\x08\xca\x7a\x02\xca\x83\xc4\x46\x13\x7e\x78\x40\x41\xaf\x80\x82\x5e\x66\x3c\x66\x50\x3e\x2b\x52\xa1\x74\x00\xa5\xa9\xd1\x2e\x2f\xa1\x84\x8d\x7f\x41\xa1\x34\x7c\xff\xb0\xc3\x56\xe1\x52\xaf\xc6\x9f\xf1\x6e\xd3\xd4\x81\x6a\xb7\xf5\xec\x37\x3e\x2d\x1a\xa6\x3c\x5a\xe9\xae\xa9\x6c\x46\x2f\x8d\xda\x73\xaf\xa6\xe2\x2f\x89\xed\xeb\xcf\x01\x27\x52\x2d\x0c\x7c\xd7\xfe\x9e\x43\x35\x13\x7b\xef\x33\xa3\x82\x92\x21\x0c\xc9\xbe\xeb\x39\xd0\xc6\xf0\x8f\xce\xc4\x22\x68\x12\xd4\x0e\x3a\x5d\x50\x3b\xd8\xef\x06\xb1\xe1\xf8\x35\xfd\x82\x42\x69\xb7\x6c\x5f\x83\xaf\xe6\x35\x30\xf4\x2f\x96\x0e\x26\x19\xce\x15\x7c\x8c\xb7\xd9\xd0\x26\xd1\x3a\xed\x4c\x24\x5e\xa6\xd1\x7a\x91\x97\x18\x65\xe6\x00\xf1\xe3\x12\x22\xa2\xc9\x18\x90\xe8\x25\x3a\x52\xe1\xfb\x6a\xb6\x14\xbd\x8f\xc3\x97\x20\xf8\x71\x64\x1c\xa4\xb0\x3c\xaf\x82\x81\xf9\xbd\xc9\xe6\xa5\x0d\x2a\xa1\x9f\x53\x84\x61\x35\x0b\xd9\x10\x5b\x28\xa8\x35\x18\x8e\x71\x5f\xe9\x5d\x1f\x14\xa0\xff\x2a\x71\xcc\x7b\x05\x38\xb6\x48\xaa\x45\x50\x6c\x1a\xd7\xa2\x29\x1d\x15\x11\xc1\xfc\x3a\x96\x6a\x85\x61\x3f\x84\x61\xd2\x91\x3a\xc2\xb0\xba\x83\xdd\x1e\x24\x68\x91\x55\xec\x7b\x16\x92\x23\x63\x16\xb9\x0e\x4a\x69\x6c\xaf\x3b\x74\x88\xc8\xcd\x11\xb6\xed\x15\xc2\xff\x23\x17\xd5\x15\xc6\xff\x7a\x8c\x0f\xef\x32\x8c\xb0\xac\xe1\x3b\x0e\x5e\x08\xdf\x7f\x3b\x82\x1d\xec\x48\x1c\xfa\xbd\x18\x36\x3d\x29\x67\x40\x3f\xd0\xc5\xd6\x54\x91\x63\xac\xce\x5b\xe0\x2d\x1e\xe4\x05\x52\xc4\xf8\x14\x2b\x0a\x17\x2d\x83\xff\x89\x55\x8b\xbf\x7b\x02\xbf\xae\x64\x73\x51\x6d\xbb\xb2\x95\xc0\xb4\x7d\xe8\x3c\x60\x32\x6f\x29\x5b\x78\x15\x89\xd4\x0b\x51\xe6\x07\xbe\x69\xc3\x60\x43\xdf\xa9\x6c\x82\x0d\x7d\xb7\xb2\x19\x14\x76\xde\x83\xc2\xee\xfb\x2c\x3c\xe6\xe5\x0c\x8f\x67\x97\xd3\xef\x8c\xc5\x14\xb6\x37\xc3\x95\x00\xbf\xaf\xe9\xe0\x50\xd7\xc1\xe3\x85\x3c\x6f\x79\x9a\x68\x07\xe5\xad\x9d\x44\xad\x8e\x68\x0f\x3a\xde\xab\x27\x2e\xdf\x41\x64\x2e\x6f\x23\x17\x41\xd6\xfa\x69\x4d\x57\x74\xcc\xdf\x8a\x10\xad\x08\xd1\xef\x25\x44\x25\x23\x45\x2c\x9a\xd4\xb1\x6e\x8e\xe8\x43\xb8\xec\x6f\x18\x7a\x99\x6f\x7a\x28\x87\x5b\x1f\x18\x92\x42\x1f\x14\x7a\xbe\xdc\xf8\x20\x75\xc4\xbf\xea\x17\x38\xb0\xc1\xb7\xd0\xfb\x62\xaf\x7c\x74\x6a\x7b\xf6\x0b\xdf\x48\x79\xd7\xf2\xc1\x55\xd3\x67\x33\x59\x79\xe1\x51\xec\xe5\x94\xf8\x0c\x23\xb2\x5e\xce\x7b\x33\xa3\xf8\xbd\xc6\x06\xd5\xe7\xbd\x45\x05\x1b\x35\x7e\x87\x7c\x18\xb4\x40\x82\x24\x58\x1c\x54\x61\xc5\x9b\x2d\xbe\x21\xf4\xd9\xb7\xdb\xda\x62\x70\x2f\x98\xf6\xf6\xf1\x57\x96\x36\x2f\x6d\x50\xae\x6c\x27\xe7\x36\x26\x16\x1a\x41\xb2\xe8\xa2\xf3\xb2\x52\xec\x34\x39\x0f\x0c\x3d\x51\xbf\x16\xb2\x7b\xd4\x77\x16\x13\xb1\x7f\xfb\x6a\xf8\x3a\x14\xc5\xcb\x2b\xb1\x62\xde\xe4\x19\x2d\xd6\x9c\x32\xbe\x4f\x8b\xb5\x52\x14\xff\xfa\x05\x4e\xde\xea\x1c\x21\xd9\x19\x72\xbc\x41\x50\xbb\x62\x08\x76\x35\xff\x92\x7e\x3e\xcb\xbf\xcc\x99\xe5\xdf\xcb\x0b\x87\x57\x5d\x36\x0e\xba\x41\xe3\xa0\x0b\x1a\xfc\x0c\x5a\x83\x5f\x6b\xf9\x7a\x10\x3d\x28\x94\xe0\x3b\xa4\x87\x57\x47\xe2\xd3\xa9\x79\xfa\xc1\x31\x75\xb0\x85\xe5\xcc\xcc\x1a\x81\x2d\xf6\xa7\xdf\x6a\xcd\x60\xd9\x52\x0c\xe2\x2b\x9e\xcc\xbf\xdb\xf4\xff\x4a\xbc\x13\x5e\x89\x1f\x44\x4e\xcb\x9d\x41\x13\xdf\x62\xf3\x8f\x03\xe8\x7a\xc8\x09\x0e\xb8\x55\x7c\x1b\x14\xf4\x2d\x50\xd0\x37\x83\xed\x41\xd1\x05\xdb\x3a\xd8\xd2\xc1\xe6\x33\x3e\x10\xbf\xd4\xf7\x38\x28\x18\x7e\xa7\x7f\x58\x7c\x00\x86\x5b\x39\x66\xcf\xe4\xcd\x43\xdc\xb0\x1e\xdf\x3c\xc4\xdf\xee\xda\xa1\x11\xdd\xb6\xe4\x49\x52\x51\xd0\x5d\x7b\x1a\x3e\x23\xe5\x0c\xf8\xd2\xb8\xb6\x70\xa2\xd8\x5d\x69\x16\x7c\xbc\xe6\xcf\xaf\xd5\x8c\xa2\x94\xeb\xdb\x8c\xe8\x78\x22\xbe\xb1\x80\x67\x3c\xa7\x6e\xcb\xf6\x44\xba\x24\x0e\x16\xfb\x30\x90\x6b\x1d\x1c\x1a\xa1\xe7\x4a\xd2\x2f\x5e\x3a\x0a\x54\xb6\x88\x0e\x6a\x2c\xaa\xdd\x4b\xbf\x3c\xf2\xeb\x76\x67\x1c\x55\x93\xf9\x36\xf7\x70\x9b\x99\x29\x9e\x3f\x17\x67\xd9\xa4\x41\x59\xe7\x7e\x0b\x8d\x4e\x77\xab\xb1\xdf\xe5\x07\x4f\x35\xf6\xbb\xa0\x71\xd5\x05\x8d\xb3\x6e\xc0\x91\x49\xfc\x13\xcb\x54\xa9\xfc\xdb\x57\xa9\xa9\x35\x6b\xcb\x70\xa7\x5a\xde\xe1\x37\x06\x7e\x2d\xeb\x00\x3f\xe8\xe0\xc3\xc3\x4b\x1c\x43\x11\xdd\x7b\xc0\x9d\x9c\xea\xd7\xfa\x6a\x43\xcd\x6a\x43\xcd\xcb\x6d\xa8\xc9\x69\xb9\x83\x83\x6e\xa0\x5c\x51\xb0\xd8\x8d\xe7\x3f\x13\xb9\x06\xfb\xf5\x15\x23\xb7\x62\xe4\x5e\x96\x91\x0b\x2f\xb5\xdd\xf7\x7b\x36\x26\xc1\x7e\x78\x49\xe6\x61\xab\x0b\xea\xe2\xe2\xff\x60\x5c\xb4\x41\x61\x52\xdc\x0f\x37\x04\x4c\x6d\x1c\x9b\x7f\x0e\xec\xdf\xf5\xc7\xc4\xaf\xaf\xbb\xac\xd9\x5c\xfd\x70\xfb\xc8\x5e\x8d\x0a\x9f\xc8\x2c\xa0\xcf\x11\x8d\x4a\x7f\x7b\xfe\x16\x5f\x30\xc4\xc3\x76\x6b\x52\x23\x8e\xa5\x92\x3f\x76\x5b\xe5\x6f\xa9\x7b\xf6\x63\x0c\xe6\x6e\xab\x33\x63\xb3\xee\xe8\x8f\x91\x72\xa9\x14\x71\xac\xdc\x49\xd0\xdf\x8a\xea\xf8\x90\x4c\x15\x4f\xa0\x54\xfa\x2c\x6b\xc3\xcc\x0a\xc4\x4d\x5b\xb4\x7a\x70\x86\xfe\x28\xa1\x94\x99\xf1\xe2\xd5\x84\x1a\x60\x57\xa7\x59\xca\xa6\xe9\x97\x39\xf9\x64\x19\x65\x1e\x17\x42\xe3\x45\xd0\xfd\x59\xfd\xd3\xc2\x6f\x29\x17\xed\x15\xa1\xfd\xed\x9d\x21\x0f\x2a\x63\x9c\x04\xfb\xbf\xc9\x1d\xcc\x45\xc0\xe6\xc1\x3e\x0f\x04\x07\xfb\x5d\x70\x70\xd5\x05\x07\x67\x0c\x00\x54\xc2\x7f\xaf\x99\xd5\xf7\x66\xb1\xfa\x15\x1d\xe0\xfb\x15\xab\xbf\x62\xf5\x5f\x7f\x11\x1c\x0d\x3d\xf3\x8f\xc3\x56\xb7\xa0\x07\x87\xad\x6e\x10\x21\x67\x18\x6a\x04\x1b\xe2\x62\xe2\x30\x5c\xea\xbe\xce\xa8\xe3\xdd\xb4\xa8\x83\xdc\xde\x24\xe0\x27\x9c\x41\x0e\x12\x9e\x55\x11\x25\x37\x02\x6e\xba\xed\xa5\xd3\x77\xa1\x03\x1f\x60\xc0\x4f\x02\x37\x45\x4a\xb1\x57\x33\x4a\x59\x0e\xf8\x2d\xc7\xd6\x54\x8d\x2a\xc1\x86\x51\x09\x0a\x28\x1d\x51\x0a\x36\x74\xc6\xba\xa4\xc3\xcb\xc1\x86\x5e\x0e\xb8\x00\x93\x08\xaf\x04\xfc\xc6\x94\x4a\x3a\x7c\x33\xe0\x67\x45\x6d\xa6\xc3\xb7\x02\x7e\x10\xd8\x96\x0c\x3f\x26\x16\x86\xe4\x8f\xc6\xc0\xc1\xae\x37\x82\x6e\xc0\xcf\x80\xde\x16\x8d\x11\xbb\x30\x64\xd2\x9d\x80\x1f\x5f\xba\x33\xd5\x8b\xd0\x86\x7e\xc0\x0f\xc5\xdc\x95\xe9\x94\x4e\xd8\x30\x02\xbe\x8d\x3b\x55\x13\xde\xdd\x86\x1e\xc0\xa9\x70\x36\x52\x46\xd0\x9b\x0a\x2f\x05\x05\xa3\x14\x98\xe9\xf0\x72\x50\xd0\xcb\x41\xba\x63\x36\x2a\x41\x41\xaf\x04\xe9\x7e\xd9\xd8\x0c\x0a\xfa\x66\x90\xee\x96\x8d\xad\xa0\xa0\x6f\x05\x5b\xe9\xe0\xed\xa0\xa0\x6f\x07\xdb\xe9\xe0\x9d\xa0\xa0\xef\x04\x3b\xe9\xe0\xdd\xa0\xa0\xef\x06\xbb\x6a\xf0\x45\xb7\x11\xb0\xff\x51\x98\x60\xd6\x6b\x23\xd7\x43\x8e\x05\x47\x41\xad\xd5\x05\x6d\x7e\x4d\xa7\xc1\x2f\x13\xd5\x4b\x3a\x37\x67\x80\xc6\x41\x37\x28\x7c\x29\x3e\x80\x82\x21\xfe\x0e\x41\x61\x28\xae\xd8\x33\x96\x93\x62\x05\x97\xff\x1b\xb7\xe7\x86\x3f\x6e\x0f\x31\x59\x63\xc4\x61\xe8\xf8\x4c\x2e\xb0\xb1\xd3\xc9\x7c\x87\x15\x53\xb2\xe2\xfc\x0c\xf6\x33\x33\x01\x51\x37\x75\xd0\x62\x71\x9e\xa9\x83\x0b\xaa\x72\x7a\x3e\xe3\xde\xd9\x8b\xab\xeb\xe0\x92\x01\xbb\x54\x07\x97\x2c\xbd\xdb\xd2\xc1\x45\x4b\x75\x30\xf2\x19\x53\xca\x92\x3b\xb5\xa9\x54\x11\xb0\xae\x83\xdb\x4b\x1d\xd4\x1b\xd7\xac\x39\x71\x41\x32\xad\x3b\xd2\xc1\x96\x6e\x0c\x57\x96\x9d\x15\x9f\xfa\x6b\xf9\x54\x71\xed\xbe\xa4\x33\xc4\xa2\x8e\x03\x83\x2b\x6e\x24\x0d\x0d\xa5\xa1\x16\x60\x7a\xb3\xe3\x4f\xfd\x05\x85\x8b\x3a\xab\xe4\xd7\xe3\x99\x3b\xb6\x57\x53\xf4\x7f\x62\x8a\x86\x87\xae\xcb\x29\xea\x7a\x0e\x1c\x0e\xb2\x0e\xba\x2c\x9b\x45\xf3\xb9\xa3\x2e\x97\xdb\x96\x6b\x9c\x99\x8e\xc9\xaf\x32\x6e\x99\x3f\xe3\x2a\xe3\xac\xcb\xe1\xc4\x01\x0b\x7f\xbf\x59\x1a\x5f\x64\x14\x9e\x89\x2e\x07\xcc\x1b\x20\xe2\x72\xc6\x45\x2a\xd7\x15\x8e\xc5\x98\x14\x3f\xc8\x8b\x80\x15\x6e\xa5\x24\x4e\x98\xfd\x85\xf4\x66\x16\x15\x2a\xc1\x2d\xe3\x6b\xf1\x03\x68\xb4\x7b\xec\x31\x22\x3a\x18\x5e\x18\x3a\xd8\xed\xe9\xa0\x7c\xe0\xea\xe0\x1a\xb2\x01\x91\xc3\x3f\x2c\x5f\xeb\xa0\xfd\xa8\x83\x4e\x63\x2c\x0f\x0e\x89\x26\x84\x50\x6e\x51\xa9\x51\x14\xd2\xe8\x21\x8b\xed\xb3\xe4\x4c\x76\xeb\x71\x61\xf7\xc3\x6a\xf5\x7e\xdd\x04\xeb\x95\x90\xc6\xf2\xa6\x8a\x69\x4d\x4a\x2c\x4a\x02\xa9\xca\xaf\xef\xa7\x16\xef\x65\x7f\x31\x1a\x88\xaf\xdf\xae\x82\x5a\xee\xc7\x15\xfa\x30\xe4\xd2\xf9\xe4\xfd\x1f\x50\xe6\x97\xce\x1f\xc3\xf3\x81\xa6\x3d\x2a\x15\xed\x7e\x4b\x07\xef\x6a\x3a\xf8\x5a\x4f\xe4\xc4\x9a\xd6\xeb\x09\xef\x51\x16\x15\xa7\x5a\x59\x02\x56\x96\x80\xbf\x1b\xe5\x7c\x25\x34\xda\xd0\xf9\x0d\x3f\x21\x8d\xae\x23\xbb\xef\x40\x0b\xbd\x1a\x3f\xd4\xa0\x60\xec\x9e\x37\x74\x50\x3e\x3e\xd3\x33\xb5\x0f\x8e\xa9\x83\x0f\x6c\x5a\xdd\x8f\xe8\x8a\x05\x79\x3d\x93\xee\xb5\x4c\xef\x92\xca\x82\xd4\x91\x63\x63\x12\x4d\x6e\xd0\x38\x68\x45\x33\x3c\xc3\x9d\xe6\xb7\x73\x16\x2f\xe0\x73\x3d\x6c\xea\xa0\x6d\xea\x60\x64\x84\x30\x9c\xc1\x37\xc7\xe2\xf8\xbd\x2f\x6c\x39\xb6\x66\xac\x6e\x68\x50\x5b\x29\xec\xfe\x2e\x58\xf0\x4a\xf0\xad\x62\xa8\xf8\x76\xe6\xc0\xbe\x1f\x2f\x26\xfc\x28\x3a\x89\x6e\x19\x4b\x4a\xe9\xb7\x21\xda\x0b\x21\x9b\xf8\x23\xfa\x86\xe1\xdc\x58\x07\x5f\x6b\x3a\x97\xca\xa7\x98\x48\x53\xe2\x62\xaf\x6d\x4e\x33\xa9\x2b\x84\x7b\xed\x68\xf0\x4a\x10\x2e\xbc\xc8\x45\x2e\x70\x8e\xef\xba\xc8\x76\x13\x2a\x72\x71\x8c\x6e\x24\x6a\x27\x0e\xd0\xd5\xcb\x8b\xff\x7e\xb7\xb6\x2b\xd4\x78\xa1\x81\xa9\x83\x32\x3f\x28\xdb\x30\xb3\x31\x75\x34\xd1\xc1\xb1\x19\xf6\x1a\x17\x13\x0f\xa4\xad\xcb\x67\x30\x3a\x55\x85\x67\x81\x90\x59\x66\xab\x99\xf2\x2c\x2c\x3f\x2b\x0b\xc7\xb9\x64\xed\x44\xff\xae\x43\x75\x27\xba\x0e\x36\xaf\xc8\x14\xfd\xe1\xc6\x37\x1c\xbd\x35\xf4\xd0\x62\x88\x10\x5d\xd9\xe3\x56\xd4\xe6\x05\xa9\x4d\x29\xb1\xbc\xd7\x7d\x73\x00\x1d\xe4\x7a\x41\x5d\x51\x9f\x07\x05\xe3\xb8\x48\x15\x96\xfa\x77\xd3\x0c\x49\x39\x8c\xaf\xb5\x31\xab\x59\x49\x6f\xb2\xc7\x79\xed\xc5\x26\x78\xed\xab\x19\x6e\xd8\x12\x38\xc5\x2f\x8e\x78\xde\xd0\xf2\xe3\x38\x75\xf2\x3c\x70\xc6\x46\x6c\xe1\x86\x75\xb0\xc2\xa9\x57\x81\x53\xc6\x6e\x12\xa7\x2c\x38\x66\x28\xf5\x5a\x34\x30\xdf\xcb\x36\xf3\xfd\x74\x7c\x67\x1d\x65\x6f\x5e\x4f\x07\x1f\x4a\x23\x1d\x94\xdb\x28\x9b\x81\xa6\xef\xa5\x6e\x5b\x2f\xcf\x43\x0e\x65\xb1\x95\x9f\x3b\x47\x50\x17\xa7\x7f\x3c\xb4\xc3\x97\x7a\x5d\x07\xcd\x47\xb6\x1a\x96\x84\xa3\x66\xa7\x7d\xbd\xba\xd3\xe5\xef\x82\x30\xaf\x05\x35\xb7\x55\xd4\xfc\xcb\x77\xb0\x39\x78\x35\x88\x19\x14\x8c\xdd\x66\xc6\x39\x8a\x5f\x0f\x9f\x9f\xe3\xab\xe9\xbd\x9a\xde\xfc\x76\xff\x4a\x3c\xbd\x1b\x03\xec\x62\x02\xfd\xa0\xd1\xea\x82\x7a\x96\x3f\x04\x68\x75\x4e\x40\xab\xb3\x1f\x14\x8c\x2e\x48\x70\x79\x52\xae\x94\xfe\x2d\x99\x57\x79\x71\xbf\xc9\xad\xed\xe9\xdf\xcf\xbf\xe0\xab\xb4\xf5\xc5\xea\x82\x87\xc3\x16\x2c\xd6\x5e\x9e\xff\x2b\x6d\xd7\x74\x50\x42\x44\x07\xe5\xdd\x7e\x7a\x71\xbb\xdc\x65\xab\xdf\xf6\xe3\xcf\xbc\x8a\xb6\xdf\xd4\xc1\x55\x2a\xf9\xc9\x34\xf3\x37\xf3\x7e\x7c\xc1\x10\xee\xaf\xd0\xf2\x55\xa0\xe5\xd6\x76\x02\x2d\xe9\x18\x91\x01\xec\x23\xf2\x6a\x56\x9e\x69\x06\xf0\xb1\xa1\x83\xee\xa3\x0e\x2e\xfd\x53\x1d\x6c\xe9\x77\xb3\x55\xa4\x1d\xd6\xd4\xa3\x9a\x30\x4a\x70\x55\x05\x77\x07\x60\x5f\x35\xaa\x03\x63\xb0\x59\x5b\x69\x25\xfe\x2e\xd3\xf8\x95\x20\x4c\xd2\xc8\x77\x88\x7b\x0e\xb4\x3d\xe8\x24\x5c\x8d\x32\x1c\x86\x7f\xae\xef\xd1\xc2\x97\xcd\xbf\xd4\x6f\xe5\x50\xf4\xca\x1d\x8a\xf4\xf7\x8f\x2b\x32\xf6\x1a\x89\xcb\x2b\x21\x63\x65\x5d\xf5\x24\x3f\x42\xb6\x8b\xc9\x10\x07\x47\x49\xdd\xea\x7e\xb1\xfd\x9b\x75\xab\x41\xc1\xb8\xf2\xdb\xac\x1e\xa7\x17\x4d\xf6\x30\x2c\x21\x77\xde\x65\xcc\xb5\xf6\x6a\xa2\xbf\x9e\xe9\xf7\x4a\x26\x7a\x72\xbd\x3e\x81\x36\x26\x98\xf4\x1d\x68\xc5\x9e\x02\x91\xec\x19\x8a\x9c\x80\xef\x17\x95\xeb\xb6\x14\x3a\xe5\x66\x8a\x69\xcf\x9d\x72\x69\x6a\xc7\xde\x32\x12\xe3\x56\xe9\x05\xbc\x01\xca\xbb\x3a\x60\x92\xa1\xc1\x24\x43\xa3\xc4\x30\x61\xdc\xeb\xfd\x0c\x39\xb0\xfd\x0f\xc4\x91\x9d\xa3\x47\x3d\xa8\x54\x54\x51\xe8\x04\xa3\xfb\xe0\x24\x24\x87\x6c\x62\x28\x8a\x89\x7d\x79\x2e\x52\xa9\x58\x99\xd6\x4a\x44\x93\x84\xef\xdb\x28\x6d\x4e\xff\xb6\x8c\x9f\xf9\xe3\x7b\x75\x78\xd5\xd0\x05\x65\x0f\x87\x3c\xea\xa0\x74\xa4\x6a\x0b\x2c\xa8\x03\xe3\xbe\x32\xfa\x99\x8a\x82\xfd\x9e\x0e\xca\xa5\x92\xfe\xac\x7e\xe0\xc3\x6b\x9e\x1a\xff\xe3\xe4\xb3\x5c\x49\x90\x4f\xec\xd0\xfb\x8c\xdd\x66\xb8\xd8\x7a\xc1\xdd\x66\x0c\xb1\x58\xa5\xee\x8e\x76\xf5\xd5\x46\xb3\xe7\xe9\x56\x42\xb3\xda\xc4\x6e\x8f\x92\xc4\xdd\xed\xe0\xea\xa0\xa5\xc8\xa4\xb5\xe2\x7b\x90\x25\x97\x2e\x31\x44\xdf\x77\xcb\xf5\x73\x10\xe1\xda\xf9\x73\xd8\xc8\x92\x8d\xf4\xd5\x35\xd7\xff\xb0\x6b\xae\xc7\xf7\x93\xb9\xc9\x56\x77\x5d\xff\xbd\x96\xa2\x57\xb2\xe8\x95\x12\xa6\xd8\xa6\xff\x15\x8d\x7a\xd4\x77\xfa\x9c\xaa\x2a\x9e\x8e\x11\x79\x15\x5f\x41\x81\x16\x6b\x11\x61\xcd\xf6\x81\x5c\x46\xcb\xb6\xb9\xb5\xb9\xb5\xf9\x13\x88\xe1\x92\x84\x73\xff\x50\x67\xed\xf2\xb6\x46\xec\xd1\x95\x36\x9c\x8b\x31\xeb\xad\x52\xd8\x6f\xce\x95\x0e\x1a\xbc\x4f\xcf\x74\x70\xbe\xab\x03\xe3\xe0\x54\x07\x17\x8c\xf1\xf3\x19\x8c\x3e\x92\x6e\x1a\x98\x3b\x28\x33\x69\x67\xf7\x4a\xda\x84\xc4\x9a\x1e\xc7\x5a\x89\x53\xaa\x78\x58\xfc\xb6\x7d\xfb\xeb\xbc\x20\xef\x6b\x3a\xd8\xd2\x9b\x53\x72\x57\xac\x30\x5c\x79\x41\xae\x68\xd1\xcf\xa4\x45\x9b\x09\xa9\xb4\x05\x2d\x07\x5b\xc1\x0c\xce\x6e\x11\x6b\x43\xe9\x37\x58\x0b\x9e\xb1\x24\x6c\x76\x19\xbe\xef\xd6\xe5\x4a\xcc\x58\xfa\x1e\xdf\x53\xba\x33\xd6\x41\xf9\xe8\x3a\x83\x24\xc4\x2c\x97\x24\x18\xf8\x98\xe8\xe0\xc8\x0a\x33\xe1\xba\x8f\x92\xae\x83\x92\x5b\x0a\x4f\xae\xdf\x84\x4d\x1d\xb4\xf8\x51\x04\x8f\x32\xc7\x98\xdc\x64\xbc\x6d\x0d\xe4\x11\x72\xd7\x47\xd7\x89\x23\xf3\x60\x74\x6a\x7b\xfa\x40\xbd\xc6\x0a\xe9\x57\x48\xff\xc3\x48\xbf\x95\x50\x5a\xb6\xa0\xed\xc1\x57\x6a\x90\x5f\xd4\x68\xef\x48\x17\xc9\x58\x72\xaf\x30\x84\xa1\x44\x07\x57\x0c\x27\xf9\x95\x00\xdb\x12\x7d\x5b\xe5\xba\x0e\x36\x5b\xa5\xc4\xc2\x9b\x30\xb1\x19\x5b\x5c\x79\x85\xa4\xe9\x8b\xeb\xb2\xd8\x1b\xf7\x4d\x61\x1d\x7b\xd8\xbd\x0a\x1d\xa5\x1b\xea\x35\x50\xfc\xe5\xa0\x95\x0e\x89\x4c\x7a\xd1\x55\x51\x66\xc4\x3f\xd8\x35\x1d\x5c\xf3\x2d\x1e\x77\xfa\x42\x97\x4b\xc4\x6f\x98\x35\x77\x37\xba\x49\x62\x85\xfc\xaf\x18\x25\x5f\x09\xf2\x57\x4a\x89\x15\x1f\x13\x77\x18\xb4\xe6\x29\xa2\x43\x7b\xc5\xe9\x2c\x55\xb4\xaa\x8e\x2e\x67\xe8\xa3\x17\x55\x2c\x6f\x73\xcd\xb2\x71\x0a\xd0\x05\x39\x05\x77\xed\x6b\x1d\x94\xfb\x1f\xd2\xbc\x71\xcd\xd6\x81\xe1\xb9\xe4\x27\xa9\x96\x43\x2d\xca\x32\x27\xa1\xbd\xc2\x39\x9e\x72\xc4\x6f\x51\x02\x4d\x1a\x9c\xcd\x56\xda\x15\x76\x8b\xf6\x8f\x6a\xed\xc4\x2f\xe9\x22\xf9\xbb\x7e\x41\xa1\x44\x4c\xca\x1a\x65\xb6\x7b\xec\x71\x54\x8b\xfc\x42\x78\x07\xb2\x51\xa6\x54\x9e\x27\x69\xea\xe0\x43\x6b\xce\xd6\xba\xe8\x08\xca\xe5\x76\xd6\xe9\xbf\x7c\x67\xdd\xad\x0e\x4a\xe7\x97\x72\x75\xe0\xc7\x13\x3f\x4e\xef\x51\xb8\x85\x2c\xf9\x9d\x14\x2f\xd1\x90\x48\xde\x98\x33\x98\x2b\xf9\x72\xb5\xda\xbc\x98\x81\x67\x47\x75\x04\x69\x51\xd7\xa4\x0f\x7c\xb9\xe1\xff\x3b\x5d\xd0\xda\xef\x88\xa5\x86\xad\x3d\x1b\xfa\x66\xc2\x5c\x1e\x14\x4a\x7e\x71\x00\x0a\xa5\xfb\xe2\x17\x50\x28\xf3\xbf\x15\xf1\x37\x5c\x7a\x36\x15\x13\xba\xf0\xd5\x36\x04\xed\xd9\xaa\x6c\x6e\x67\xd2\x86\x9d\xec\xe0\xe9\xdf\x2e\x3f\x17\xb7\xcf\x6b\x50\x1a\x4f\xae\x8a\x57\xc0\xe8\xb1\x76\x19\xd7\x3a\x38\x64\x2b\xc4\x51\x4f\x07\x26\xaf\x0f\x1e\xea\xa0\xbc\x5f\xd3\x81\xc5\xf0\x6e\xb3\xa6\x03\xd3\xd0\x41\xe9\xce\xd0\x01\x6e\x19\x3f\xc1\xcc\x34\x07\x63\xda\x42\x67\xef\x5c\xff\x7d\x91\x86\x1b\x9e\x8c\x2d\xf5\x38\x9f\x33\xe8\x60\x37\xb9\x84\x45\x9c\xca\x15\x3f\xfb\xe4\xe5\x96\x30\xc6\xc8\x6c\x96\x36\x7f\xab\xe6\x42\xac\x60\x3b\x62\x05\xdb\xf9\x9f\x5a\xc1\x8e\x87\x4c\x38\x2b\xa7\x97\xad\xcb\xaf\x3a\x18\xd4\x57\x2b\xd7\x6a\xe5\xfa\x25\x2b\x97\x61\xa8\xe4\xe7\x1c\xf7\x61\x70\xde\xea\x82\x66\x67\xae\xcf\x8e\x51\x2b\x4e\x40\xa1\x24\xfe\xce\xf2\xdc\xe1\x97\x8e\x88\x45\xa6\xbc\x95\xfa\x6d\x97\x7e\xee\x8f\x2b\x44\x1f\x59\xfd\x44\x53\x19\x31\x19\x52\x1d\xf4\xaf\x46\x3a\x98\xec\x5f\xb3\x98\x52\x8f\xc9\x5e\xb7\x07\x53\x8c\x23\xfb\xc3\x35\x21\x6e\x73\xf2\x6a\x9d\xbf\xe2\xac\x66\xcd\x84\x32\xa5\x2b\xf4\xf9\xd9\x3a\xc6\x84\x61\xe1\x9c\x8e\x5e\xcf\x41\x7c\xbf\x4f\xc5\xd8\x4a\x9e\x70\xf2\xb3\x55\x8c\xd9\x51\xcf\xa5\x8a\x42\xe2\x25\x75\xb5\x68\xbe\x76\x5c\x7c\x25\x58\x5f\x4e\xe8\x9d\x3a\x70\x04\x1d\x98\xe1\xd0\x37\x2c\x0e\x17\x71\xe8\x5b\xc4\xbd\xd9\x28\xfd\x52\x7f\xbe\xd2\xc4\x90\xa8\xfa\xb7\x99\xa1\x25\x77\x1c\x6a\x05\x4b\xc9\xd1\x71\xa0\x97\xe9\x6f\x59\x29\xe2\xf9\xc3\xb3\x9c\x3c\xf5\x33\x06\x48\x19\x96\x0c\x3a\xf2\x77\x76\xb8\x04\x9b\x3b\x86\x7a\x7d\x68\x07\x8f\x6e\x91\x43\xc7\xd4\x0e\x3a\x73\xd5\xf4\x42\x5f\xd2\x9f\xad\xa6\xaf\xcc\x55\xd3\x0b\x2d\xfc\xa2\x2a\xfb\x6d\x71\x67\x43\xa9\x0f\xd0\x05\xed\x03\xe7\x80\xe8\xa0\x74\xe7\xa6\x57\xbb\xf2\x25\x17\x45\x7f\x9a\xee\xe3\x83\xae\x83\x0a\x6a\xea\x99\xfe\xdf\xd6\x75\x78\x33\x7a\x6a\x8b\x38\x2d\x4b\xdd\xe8\xab\x18\xf4\xd9\xf0\x8c\xdb\x20\x57\x7a\x50\x2e\xab\xbc\x54\x87\xde\x62\xc8\xaf\x4f\x56\xb6\x98\xc8\x7b\x94\x13\x07\xc0\x96\x96\x3c\x15\xef\x05\x7f\x41\xc1\xd8\xda\x99\x76\x6c\x8a\x79\xf3\xd1\xc9\x91\x1c\x7b\x7e\xa5\x03\x1c\x47\x6f\x25\xf6\x36\x91\x47\xd3\xbd\x38\x9f\xb1\xe0\x69\x02\xab\x83\xa6\x5e\x31\x9f\x91\x5a\xc9\x3c\x6a\x0e\x07\xd4\x1e\xbd\x1a\x11\x23\x3a\x48\xa0\xce\x58\x86\x7d\xb4\x62\xa4\xff\x2e\xd3\xee\xb5\x4c\xf0\xc4\x7d\x23\x5d\x68\xdb\x98\x90\xa0\xdb\x4a\x10\xfd\x78\x4b\xa1\xdc\x50\x0b\xa6\xf6\x15\xc6\xdb\xc5\x0c\xbd\x2c\x36\x3f\x4c\x99\x3a\xd2\x3a\xa8\x97\xfd\x05\x85\xd2\x16\x6d\xef\x03\x0f\xed\x87\x0d\xec\x42\x1d\x54\x9c\x6b\x1b\x9c\x74\x9a\xfb\xa0\xf4\xee\x5a\x07\xa5\xf7\x53\xa7\xcd\x18\x3b\xef\x75\x60\xb8\xdd\xeb\x57\xab\x69\xca\x9c\x25\x86\x3a\xea\x9b\x5c\x29\xbf\x42\x90\x97\x47\x90\x8a\xa1\xf2\x44\x5d\xec\x40\x82\x12\x0e\xf4\x41\xc1\xf8\xc2\xc4\xcc\xdf\x70\xa3\xde\xec\x1f\x63\xd0\xed\x3a\xab\x97\x51\x19\x9b\xec\xb9\xd9\x6c\x88\x96\x8a\x13\x2e\x1a\x8c\x3b\xd1\x89\x1e\x1e\x35\xc8\x59\x40\xbe\x9b\x86\xbf\xdd\xb5\x43\x8e\xf6\x6e\xac\x83\xeb\x5e\xfa\x45\x00\xd9\x75\x15\x5c\xf1\x13\xdb\x22\x2f\x6c\x69\x5c\xad\x31\xaf\xbd\xa4\xf9\x28\x94\xf0\x04\xbb\xb0\x27\x90\xd0\x7b\x77\x98\x56\x08\x00\x7e\xef\x71\xd9\x2a\xd6\x54\xa5\x80\x44\xaa\x0c\xbd\xcd\x12\x97\xc9\xfd\x5a\xdd\x0d\xfb\xfc\x27\x98\xc6\xc3\xcb\xff\x12\xc7\xa5\x5f\x3c\x0e\xfa\xd4\xa1\xca\xb9\x03\x31\x6f\x10\x1d\xb8\x91\xe2\x0b\x92\x37\x85\x64\x28\xd7\xf4\x9f\xec\xa4\x65\x98\x77\xcd\xec\x93\x07\x46\xb6\x0e\x0c\x7e\xb1\x9f\x53\xbe\xfa\x99\xda\x03\xa3\x7d\xcb\x66\xc6\xc3\x5c\x51\x70\xb5\x85\xfc\xf5\x52\x31\x23\xc1\x08\x5c\x62\x44\xc8\xeb\xf6\x66\x7f\xf6\x38\x8e\xf2\x49\x2b\xdc\x3e\xdb\xac\xe9\xcf\x1c\xcc\x51\xd1\x75\x50\xe2\x5d\x03\x93\x4e\xe5\xb1\xbf\x45\xff\x08\x46\xdb\x49\xe6\x6d\xc4\x5d\x89\x9f\xaf\x60\xaa\xbf\x16\xa4\xda\x51\xd7\x96\x4b\x6c\x13\xec\xbb\xc1\x55\xab\x0b\x4e\x42\x16\x3b\xa1\x87\x56\x44\x50\x0a\x0a\xc6\xa3\xb2\x4f\x35\xd2\x44\x2b\xe7\x96\x94\x2a\x5c\xcd\x5c\xd9\x4a\xfd\xb6\xcb\xe9\xdf\x66\x69\x73\x2a\xec\xfb\x7e\x41\xa1\xb4\x5b\xb6\x28\xd8\x3a\x6e\xb6\x8a\x14\x18\xa7\x94\xd5\xf2\xf1\x51\x07\xad\x5b\x4b\x07\xa5\xdd\x2b\x1d\x94\xf1\x94\x02\xbb\x79\xa9\x03\xc3\xeb\xff\x14\x05\xf6\x4f\x91\x41\xeb\x53\x43\xbf\x83\xe9\x0a\x37\x5e\x10\x37\x92\x5b\x26\x2f\xa9\xdd\xa7\xfc\xc0\xa7\x29\x3b\x5a\xe9\xb2\x78\xf0\xc2\x76\x34\xe3\xf8\x8e\x65\x3a\x76\x9b\xec\xb1\xb2\xa5\x3d\xc7\x28\xef\xbe\x9f\xba\x25\xfb\x0a\x3a\x2e\x7c\xe0\xb4\x6c\xea\x88\xae\x90\x7e\x25\x54\x68\x52\x73\x50\xae\x94\x7f\xbb\xfa\x60\xae\x62\xc1\xf4\x2c\x0a\x8c\xe6\x35\x9d\xcd\x59\x70\x67\x15\xfe\xb6\xf5\x38\xd1\xc1\xd1\xd5\x99\x0e\x36\x8f\x5b\x53\xec\x05\xf7\x62\x1e\x35\xe5\x79\x5f\x9b\x91\xd7\x25\xa9\xc9\x9c\x32\xbc\x42\xf1\xfe\x75\xe8\x54\x12\xcf\x8c\x78\xbb\x5b\x14\x94\x38\xdd\x32\xf9\x22\xbd\x52\x7c\xf7\xd7\xee\x73\x9f\xb5\xdd\x67\xc5\xd0\xfc\x8d\x4a\x9a\xcf\xd0\x24\xaf\x3f\x80\x63\xea\xd0\xc7\xc1\x04\x05\x1b\x7a\xa9\xa4\xcf\x3d\x85\x6d\xf8\x3d\x67\xb0\x2d\xbc\xeb\xed\x47\x0e\x61\x1b\x02\x74\x41\x87\xc0\x61\xc4\xbe\x74\xae\xba\x6b\xee\x8c\x74\x60\xdc\xef\xc2\x5f\xb5\xe7\xe0\x44\x7f\xd6\x9c\xba\x92\xa1\x5f\x2f\x76\x6c\x8b\x63\xda\x8f\x3a\xdd\x80\xfd\x87\x7a\xa0\x07\x41\x4e\xcb\x1d\x13\x0b\x43\xf2\x47\x63\x00\xfb\xd4\x0d\x19\x9c\x4d\xb0\xa1\x6f\x05\x85\x4a\x9b\x31\x37\x9b\x3a\x28\x6c\x71\x44\x08\x0a\xa5\xaf\xd4\x65\x81\xe5\xda\x61\xb3\x5d\x3c\x08\xca\x3a\x2a\x29\x79\x50\x93\xba\xc1\x86\xbe\x55\xd6\x83\xc2\x96\xcf\x0a\xd8\xdc\xdd\x8a\xe3\x4f\x90\xd3\xf7\x91\x8d\x48\x50\xd0\x75\xce\x3f\x49\x9e\x29\x28\xb4\x0e\xf9\xed\x80\x7a\x0c\xdd\x82\x03\x14\xd6\xa7\x12\x14\xca\xef\x8a\xad\xd0\xbd\x25\x28\x94\x26\xa7\xec\x3b\xd8\xde\xe5\x3b\x8f\xa2\x04\xb6\x85\xef\x91\xcb\xf7\x1e\x71\xee\xac\xd2\x89\xf2\xa7\x76\xbf\x13\x94\x37\x79\x1f\x44\xf0\xbe\x83\x3d\x26\xf4\x84\xa5\x84\xae\x51\xa7\x2a\x33\x27\xd6\xdd\xaf\xd4\x39\x05\xe5\x8a\x4f\x4e\x81\x51\x61\x53\xbd\x34\x74\x74\xae\x77\x0f\x8c\x44\x9e\xe7\xc8\x27\x38\x3c\x3c\x4d\xd6\xfb\x43\x5c\xef\xd1\xfe\xfe\xbb\xe2\x87\x60\x47\xb0\x97\x67\xd0\xc4\xb7\xd8\xfc\xe3\xe4\x01\x7e\x81\x36\xc2\x24\xd8\x30\x0c\xb0\x61\xb0\xbe\xd9\x05\x05\xa3\x04\x36\x58\xa7\xf7\x74\x50\x80\x3a\x28\xec\xea\xc0\xd4\x41\xc1\xe4\xf5\xd2\xcb\x95\xa0\x60\x0c\x6d\xa2\x03\x38\x1c\xeb\x60\x8b\x1f\xa6\x53\x72\x26\x3a\xb8\x82\x44\x0f\x8c\x0a\xef\x9a\xd6\x41\x37\x68\x31\x5a\xf7\x2a\x15\x25\x2f\x71\x87\x29\xf7\xb5\xed\xb7\x5a\xab\xad\x21\x2b\x72\xf9\x82\xe4\x92\xe1\x4e\xa7\x1b\xb0\xff\xdb\x92\x54\xb6\x3a\xdd\xed\xd6\x3e\x0f\x04\xad\xfd\x2e\x68\x5d\x75\x41\xeb\x8c\x01\x80\xad\xf0\x9f\xdc\xf9\xf1\xdb\x51\x6b\x0a\xd1\xb6\x0c\x27\x72\x71\x92\xce\x4e\x9d\x7e\x5b\x07\x3b\x5f\x4b\x3a\xc0\x5f\x75\xf0\xe1\x61\x41\x67\xa9\xf8\xc4\x9a\x8c\x58\xd7\xd0\x81\x71\xf9\x28\x6e\x31\x33\xea\x59\x27\xdc\xcc\x48\xf9\x4c\x59\x8b\xa6\xad\x30\x42\x68\xf7\xe4\x5b\xb2\xc5\xca\x5b\x0a\xee\x47\x52\xfc\x8c\xd2\xce\x19\x49\x7c\xec\xe9\xe0\x74\x9c\x7e\x99\x13\x35\xe7\x65\xa9\x54\xaf\xb5\x88\x40\x59\x36\x1b\x03\xe8\x0d\xe0\x28\xd8\x30\x4a\xc6\x26\x5b\x2a\x2b\xec\x6f\xb9\xb2\x19\x14\xcc\x5b\x50\x30\xdf\x83\x82\xf5\xfe\xf7\x3b\x05\x04\x85\xab\xbb\xda\x2d\x30\xa0\x85\x6e\xb9\x69\x92\x8b\xc0\xe7\x53\x97\x40\x2c\xf2\xf2\x12\xa9\x38\xc5\xe3\x07\x77\x8a\x2d\x29\x19\x6f\xa9\xcb\x2c\xb2\xde\x96\x4f\xfb\x23\xa5\x61\xaa\x4f\x5d\x6b\x31\xff\x2d\xb5\xee\xff\x8a\xb4\x98\xfe\xca\xd2\xe6\xa5\x0d\xb6\x74\x5d\x41\x94\xda\x18\x8b\x1d\x1a\x05\xc3\x60\x22\xae\x61\x70\x11\x77\xc3\xa8\x30\x7c\x09\x7a\x77\xc5\x0b\xd0\xf3\x41\x4f\x07\x8c\xcd\x44\x3a\x28\x58\x52\x91\xf9\xdd\x27\x73\xec\xb7\xbe\x16\x2b\xc0\x98\x5c\xe9\xe5\x62\x05\x94\x9c\xf3\x9e\x0f\x8c\xdb\xdb\xb0\xa6\x8d\x63\x1d\xd4\x3e\xfc\xcf\x0f\x53\x79\x9b\x33\xe9\x72\x9c\xea\xd4\xef\x43\x4c\xee\xb1\x6d\xa3\x40\x8a\x01\x1b\x86\x11\x48\xf6\xbf\xd0\xe3\x0c\x46\x29\x28\x18\x5b\x57\x13\x1d\x6c\x37\xda\x3a\x28\xb5\x3e\x8c\xb9\x35\xa7\x92\xa0\x8d\xbe\x3f\x94\x79\xc8\xf4\x81\xe4\x05\xd0\xc3\x44\x07\x90\xdf\x21\x73\x79\xcd\xde\x2c\x3d\xa8\xec\x26\xea\x72\x70\x0b\xbd\x50\xfc\xe2\x32\x09\x93\x43\xac\x62\x1f\x70\x69\xc4\x9c\xe5\x6b\x15\x14\x4a\xf6\x2e\x61\x70\xa5\xce\xa3\xc9\x9e\x62\x4d\xa6\x6c\x75\xd6\x23\x47\x6b\x6e\xa8\xbc\xad\x2f\xc1\x01\x44\x4e\xda\x7c\x7b\x5e\xdb\xd2\x41\x8d\xe8\xc1\xd6\x56\xb2\xce\xc4\x42\x4e\xcf\x77\x26\x01\x93\x9d\x0a\xbc\xde\xe5\xc0\xd4\xd9\xcc\x0e\xa7\x74\x40\x8e\x4d\x1d\xd4\xb7\xaf\xf5\xc0\x50\x52\xbe\x83\x43\x48\x6f\x69\x20\xd3\x44\x09\x02\xe3\xf0\x96\xe8\x41\x65\x47\x2d\xe7\x1d\xfe\x82\xc3\xae\x29\x71\xf0\x42\xaf\x5b\x3c\x66\xdd\x22\x8b\xf9\x51\x3d\x6f\xef\xe2\x91\xe5\x58\x1e\xed\xb4\xd9\x33\xda\x0d\xc8\x96\x0f\xf2\xde\x0c\x55\xb0\x54\x57\x2e\x01\xe2\xd7\x91\x45\xf7\x92\x7d\xd0\x75\xf0\x95\x75\x55\xa7\xad\x03\x9f\x4d\xbf\x4e\x2b\x7c\xb9\xac\xe9\xc0\xd5\xb3\x5e\x4a\x3a\xd5\xc1\xd8\x0c\x5f\xa6\x43\xe6\xbc\xcc\xc9\xe7\x99\x54\xdf\x55\x44\xb0\x93\x9c\xee\x87\xd0\x86\xe3\x48\x81\x51\xd0\x37\x41\x41\xdf\x0a\x36\xaf\x8a\x14\x6c\x86\x6c\x39\x5f\x89\x8d\xc9\x65\xc7\x28\xd6\x40\xc9\xea\x3e\xb2\x67\x9f\xcd\x24\xe7\x51\x0f\x4a\x9b\x89\x99\x74\x08\x47\x3d\x8c\x9c\x30\xb7\xdd\x60\xe7\xba\xd8\x02\xbb\xa1\x10\xff\x85\xde\xea\x45\x33\x30\x4a\x9b\x6a\x0a\x1f\x5a\xd0\x36\x21\x81\xb6\xc4\x9a\xa0\x00\xf7\x8b\xad\x10\x69\x79\xba\xc9\x7e\xb1\x25\x9d\x19\x94\x84\xa3\xe0\x90\x1f\xc1\xb5\x0b\x0e\xf7\xbb\xa0\x31\x60\xa2\x7a\x8c\xf1\x4c\xf8\xe7\x58\x9f\xfa\x95\x83\x82\xb1\xf3\xe5\x44\x07\x5b\xe3\xba\x0e\x6a\x83\xba\x0e\xca\x1f\x9a\x3a\xe8\x97\xc6\x3a\x28\x8f\x77\x0d\x70\x75\x7a\x2d\xfc\xa0\x1e\x2d\x79\xdf\xf0\x58\xbc\x6c\x7e\xb5\x84\x8b\xd4\xa6\xdb\xd6\xc1\x63\xcf\x60\x4c\xc9\x35\xdf\x87\x7a\xd1\xec\x71\x55\xaa\x5a\xc7\x23\x4a\xa8\xed\xdb\x7e\x70\xd4\xe9\x82\xa3\xfd\x2e\x38\xba\xea\x82\xa3\xb3\x2e\xe0\x9a\x24\x1f\xec\xca\x7f\x61\x4d\xcb\x7a\x25\x28\x18\xde\xa0\xe9\x83\x9d\xaf\x3a\xb0\xd1\xad\x0e\x76\x1e\xae\x7c\x80\x6b\x3e\xa8\x6c\x8d\x39\xe5\x4b\x68\x40\xb0\x83\x3d\x3c\x82\x1e\x0e\x0a\x86\x5e\xd1\xe5\xfa\x14\xc0\x83\x70\x4d\x0a\x91\x17\x1e\x30\xe4\x1d\x06\x9b\x06\x57\x3c\x45\xe9\xa9\xeb\x40\x24\xd4\x27\x9c\x66\xea\xb1\xea\x64\x37\x54\x9f\x98\xa2\x6e\x06\xdf\xb9\x52\x42\x0f\x8f\x8c\xf0\x35\x74\x70\x54\x9f\x84\x3a\x14\x46\x07\xc1\xd5\xe9\x89\x0e\x8c\x9e\xf5\xc8\xc9\x8b\x5a\x48\x0b\x7e\xf1\x1d\xba\x68\x21\x33\xca\xd8\x3a\x67\x64\xaf\xe4\x8f\xf4\xa0\xb4\x93\x98\x73\x2d\xe8\xdc\xf9\xc8\x85\x72\x0e\xef\x96\xf5\x60\x17\x83\x5d\x5f\xce\x1e\x74\x18\xec\x24\x6b\x74\x06\xfb\xf4\x86\xfd\xe1\x49\x3a\x9d\x6e\xd0\x1b\x15\x5b\x40\x4e\x38\xb2\xdf\xaa\x17\x4d\xd6\xd7\x6a\xa2\x36\xf4\x1d\x5f\xce\xd1\xb2\x5c\x64\x58\x3b\xb6\x8b\x07\xa0\xd0\xf3\x45\x6b\x42\x1a\xcf\x66\xd9\xb5\x45\x58\xd4\x87\x06\xa9\x17\x0f\xc0\xf6\xe8\xce\x07\x86\x4d\x7a\x7e\x60\xe8\x89\x16\xb4\xb1\x8f\x18\x09\xe5\x2a\xf4\x90\xd3\x08\x7a\x43\xc1\x5b\x08\x05\xe2\xc9\x6d\xeb\x00\x18\xdb\x13\x1d\x06\x46\x29\x59\x2d\xea\xdc\x52\x9b\xad\x59\x06\xa7\xaa\xbc\x6a\x46\x89\xff\x95\x0b\x90\x29\xaa\x67\xfa\x89\x65\x68\xd1\xc3\x56\x4e\xfa\x3d\x13\x5c\xe9\xc6\x61\x68\x88\x62\x7f\x77\xdf\x9b\xfe\xaf\x51\xef\xbc\xac\x46\x89\x11\xac\x4a\xa2\xf7\xfc\x11\x82\xa9\xf5\x7a\x53\x50\x9f\xc4\x7a\x2d\x56\x68\x16\x53\x3a\xb8\x6b\xb1\xe7\x57\x46\x21\xce\xea\x3a\x98\x10\x1d\x1c\xa1\x33\xbe\x82\x04\xbb\xc9\xc9\x79\x86\x3d\x13\x62\x87\x04\x05\x7d\x87\x0d\xac\xbe\x13\xec\xf8\x60\x47\x2c\x91\x3b\x97\x43\x3f\xd8\xdc\x52\xc1\xe9\x80\x8c\x11\x56\x71\x45\xc5\x93\x10\x47\xe6\xa0\x61\x50\xae\x24\xca\x3f\x87\x0e\xf5\x28\xe9\x43\x46\x1f\x78\x05\x76\xcb\xe2\x58\x74\x18\x13\x9e\xd9\x22\x98\x3d\xb9\xf2\xc1\x71\x93\x8b\x41\x3e\x38\x25\x7e\xea\x85\x73\xa7\xd9\x51\x73\x5e\xe6\xa7\x0a\x8c\x72\xa2\x09\x5d\x38\xc0\x1e\x0e\xf9\x70\x3d\xd8\xbd\x2a\xf6\x45\xb5\x05\x72\x1b\xc5\xe3\x34\x13\xd7\x65\x0d\xf6\xe0\xd8\x67\x22\x6e\x89\x21\x42\x99\x13\xc5\x82\x39\x64\x8c\x86\x24\x8b\xd1\xc8\x1a\xb0\xae\x0f\x41\x89\x6c\x5a\x43\x71\x40\x15\x67\x0c\x38\x1b\xf0\xc1\x10\x2f\x8f\x57\x6d\xb1\x80\x6e\x87\x0b\x5e\xa7\xbb\x73\xb6\xdf\x0d\xce\x3a\x5d\x70\xb6\xdf\x05\x67\x57\x5d\x70\x76\xd6\x0d\x76\x74\xb0\x1d\xfe\x7b\xcd\x2a\xad\xbb\x59\x2a\x2d\x43\x07\x78\xb2\x52\x69\xad\x54\x5a\xaf\xbf\x88\x20\xa7\xe5\xae\x0e\xba\xd1\x89\xec\x81\xbc\xee\xe1\xf7\xa1\xd6\x60\xbf\xbe\x32\xa7\xac\xcc\x29\x2f\x69\x4e\xf9\xac\xe5\x6c\x4c\x86\x6e\x6e\xef\x53\xae\x76\xeb\x60\x13\xfe\x51\xeb\x61\xeb\x0b\x24\x41\xf8\x59\x87\x23\x38\xa4\x39\x6d\x66\x34\xf9\xe2\xdb\x33\xa3\x1b\x94\xc0\xa1\x33\x99\x19\xbf\x0f\x87\xd0\x99\x19\xfb\xce\x41\xc8\xa3\x0f\x64\x26\x40\x93\x8e\xd0\xcc\xc8\x36\xf5\xe1\xd0\x1c\x50\xcf\x9b\x09\x72\xea\xc3\x3e\xb4\xa8\xdf\xa7\xfe\x4c\x98\x2e\x1e\xf5\xfc\xa1\x97\x05\xe0\xd9\x90\x78\xd8\xfc\xa3\xe3\xdd\x1c\x21\x1b\x11\x18\xc3\x34\x20\x76\x68\x70\xd0\x9f\x8c\x95\xd2\xdf\xd3\x01\x24\x04\xb9\x3d\xdf\xe9\xcb\xec\x5b\xd0\x45\x8e\xff\x0c\x4c\x0f\xf6\x20\x51\x5a\xda\xe4\x42\x75\x3c\x04\x7d\x1f\xcf\x8a\x74\xe0\xe3\x23\xe4\xba\xab\x19\x10\xfb\xd4\x87\x36\x9c\x11\x79\x82\x89\x3b\x80\xee\xac\xe8\x26\xee\x39\x68\x5e\xe6\x4d\x1f\x12\x6b\x56\xea\x16\xb4\x61\x8f\xce\x88\x6c\x63\x38\x42\x93\x19\x91\x67\xd4\xf1\x68\xa1\x4d\xef\x95\xd4\x2d\x38\xf6\x3d\x1a\xb5\x9b\x0d\xcd\xc4\x41\x33\xe3\xfd\x2f\xfe\xa8\xe7\x3b\x70\x16\xc0\x21\xec\x51\x87\x92\x99\x19\x1c\x41\x07\xce\xce\xfe\x04\xf7\xa1\x8d\x67\xc5\x36\xfd\x9e\x3f\xea\x41\x77\x30\x07\xc2\x85\x43\xa5\x6e\x6d\x36\x9d\x7a\x58\x46\xd7\x2c\x0b\xbb\x37\x35\x36\x2d\x66\xc3\xb8\x23\xe8\xcc\x8d\x46\x73\xa2\xf7\xa1\x73\x83\xdc\x9b\x0e\xb4\x21\x1c\xcd\x86\xfa\x82\x7b\xd4\xf7\xf0\x4c\x80\x13\x38\x1a\x27\x66\x57\x2a\xbe\x45\xfb\xd0\xc2\xee\xc0\x9f\x86\x08\x5d\x37\x6a\xc4\x83\x04\x12\xe8\x60\x75\xb0\x53\x40\x0d\x3a\xa2\xce\xec\xe8\x16\x9c\x50\xcf\x53\x06\xab\xeb\xe0\x31\xb5\x71\xd0\xc4\xbd\x09\xaf\xdc\x08\x85\xfd\x0a\x87\x41\xf4\xe1\x0d\xa7\xe2\x2e\x3a\x7f\xd4\x6c\xe4\x7b\x18\x12\x35\x8a\x98\x03\xea\xc0\x3e\x12\xf1\xd0\x4d\x26\x74\xfa\x88\x78\x98\xb0\x49\x87\x08\x75\x6f\x6a\xd8\x41\x6e\x54\x8c\x1a\x98\x99\xaa\x01\x3d\x38\x82\x8e\x09\x83\x8c\x38\x3a\xa2\xd6\x39\xbe\x87\x16\xbc\xc7\xd9\x85\x4e\x27\x8f\x42\xb2\xe1\xa9\x63\xd1\x9e\x02\x2d\xbe\x17\x82\x3d\xa7\x2e\x74\x30\xcd\x84\x7d\xef\x7f\xf1\x27\x11\x24\xff\xca\x84\x6b\x21\x62\xd1\xc7\x38\xcf\xf0\x5b\x85\xf5\xf0\x90\x0e\x19\x01\x8e\xab\x08\xed\x9b\x23\xe8\xf4\xa8\xef\x28\x80\x8d\x01\x36\x61\x9f\xb2\x51\x69\x20\xe2\x39\xd0\x56\x23\x7d\x07\x9a\x90\x2a\x9d\xea\x27\x5a\x99\x8e\x3f\x71\xa0\x8d\x88\x85\xbf\x0c\xe7\x00\x35\xe9\x03\x72\x6e\xce\x1c\x4c\xcc\xc4\x68\xee\x23\x72\x8f\x9c\x08\xac\x33\xc0\x63\x87\x9a\xc3\x69\x88\x36\xbc\x87\x5f\xe8\x74\xf8\x45\xe7\x8f\x16\xf5\x89\x07\x31\x49\x44\x7a\x0e\xc5\x1e\x8f\xc5\xe6\x00\xf7\x13\xd3\xf2\xc0\x1a\x51\xe2\x51\x12\x34\x20\x81\x16\xcc\xca\xe0\x1d\x75\xbc\x9b\x2b\x38\x21\x28\xaa\x9b\xc0\x99\xe8\xc9\xf0\xc4\x5d\x28\xc5\x1c\xc8\x8b\xce\x1f\x07\xd0\xf5\x0a\x21\xa4\x02\x74\x04\x6d\x7c\x0b\xbf\xca\x2a\xca\x25\x35\x01\x71\x0f\x09\x0c\x1a\xc9\xd1\x91\xb5\x3c\x21\xf4\x6b\x3c\x44\x84\x7e\xbd\x39\x6e\xcf\x02\xbb\xe8\xc8\xef\x42\xc7\x83\xce\x10\x29\x80\xef\xe1\x08\x62\x13\x06\xe1\x53\x89\x39\x41\xc4\xf3\xcd\xe1\xe4\x8f\x26\xf5\xb1\x2b\xac\x40\xf1\x70\xcb\x20\x25\x41\x93\x61\x33\xe9\x23\x1b\xb9\xac\xc8\x50\x6d\xf0\x2c\x40\xa1\x8d\x1e\x14\xa0\x16\x24\xd0\x77\x03\xb6\x7e\x63\xfb\x8f\x2b\xe4\x7a\x89\xc8\x47\xc8\x7a\x2a\x68\xa1\xaf\xd8\xa4\x7f\xd4\xe1\x17\xd8\x49\x4c\x7d\x11\x71\xd3\xc0\xde\x44\x02\x1d\x22\x82\x92\x28\xd0\x46\x0f\x37\x1f\xa9\x33\x94\xe3\x83\x1c\x75\x6e\xb4\xd9\xfa\x37\x80\xb2\x0a\xfb\x28\x0c\x50\x40\xce\x20\x81\x23\x95\xb0\x4c\x46\x89\x19\x78\x36\xa0\x88\x60\xde\xf3\x35\x07\x3f\xd2\xc4\xd0\xb3\x45\xfc\x86\xde\xde\x74\xc6\x10\xc7\xb8\x5c\x63\xcc\x8c\x6d\x2f\x02\xe8\xe1\xbe\xff\x3c\xdc\x3e\x1d\x61\x92\x1c\xd2\x6c\xc0\x43\x07\xb1\x39\xf8\x3c\x9c\x0f\x2d\x64\x53\x7f\x8c\x9e\x05\x6d\x41\x07\xf7\xa9\xf7\x3c\x1c\x25\x9e\x8b\x1c\x07\x3e\x0f\xda\xf1\x6e\xea\xd0\xf1\x06\xc8\x46\xa3\xc9\x22\xd0\x27\xd8\xf3\xdc\x45\x00\x9b\xbe\x89\x9f\x6f\x7d\xc7\xbb\xe9\x0e\xe8\x08\x2e\x94\xe5\x25\xa3\x83\xe4\xf9\x46\x75\x19\x3f\xb7\xc0\x98\x5f\x62\xa7\x9f\xa0\x5f\xe7\xa8\x8f\x19\x71\x10\xd4\xa3\xc3\x56\x5e\xcf\x1c\xa0\x87\xc4\x2c\x3c\xc7\xf4\xa6\xee\x40\x62\xc6\x74\x9a\x33\x90\x37\x35\xd3\x41\xd9\x70\xe1\x9c\x4f\x01\x74\x18\x6d\x62\x0b\x4a\x63\x80\x6d\xc4\x84\x1b\x0f\x13\x44\xbc\x04\x52\x75\x20\xbd\x39\x83\xbe\x1d\x65\xc2\x30\x4b\x8d\xf7\x6e\xde\xd3\x01\x71\x65\xa5\xdb\xe8\xe1\x96\xfa\xc4\xb2\x21\xb1\x14\xb0\x2e\xfe\xe2\x33\xba\x17\x11\x73\xe2\xa6\xa7\x67\x1a\x84\x55\x0f\xde\x1c\xbb\xb0\x87\xec\x0c\x30\x85\x56\xb4\xa9\xe3\xa9\x0d\xeb\x32\xcc\xf6\x68\x62\x3e\x3a\x28\xd1\x2c\x09\x12\xd6\x7a\x9a\x5c\x5c\xb2\x8e\xf3\xd9\x5a\x15\x82\x4c\x13\xbe\xab\x01\xf6\xd0\x80\x3a\x2e\x92\x30\x1f\xfd\x21\x55\x33\xb9\xc2\x84\xe0\x31\xea\xcb\x78\x65\xd9\x76\x31\x63\x5a\x07\x7d\xd8\x83\x5e\x20\xbf\x86\x03\xd8\x83\x96\x8c\x66\x92\xd0\x90\x0e\x45\xec\xd9\x80\xd0\xd1\xcd\x19\x22\x83\xcc\xe8\x4b\xcc\xf8\x8d\x50\xaa\x62\x01\xfb\x03\x38\x84\x22\x6e\x1f\x9a\x82\x5e\xf0\x0f\xbf\x07\xb1\x08\x6f\xf9\xae\x29\x50\x94\x7d\x1d\xd1\x9b\xc6\x00\xdf\xb4\x30\x19\x88\xe8\x0e\xc4\x7d\xd1\x1a\x11\x4d\xfa\x37\x27\x94\xf4\x03\xf6\x36\xa4\xa4\x2f\x63\xde\x23\xc7\x77\xa1\x8d\x46\x22\x59\x17\xd9\x37\xb5\x7b\x7c\x3f\x1d\x7d\xec\x3a\x10\x45\x8d\x3f\x81\xde\x60\x04\x89\xe5\x07\xf2\x93\x7f\x45\xd1\xd4\x1e\x42\x2f\x6c\x41\x03\xda\xa6\xef\x79\x51\x23\x4e\x98\x8c\x77\xd3\xf4\x47\x63\xdf\x09\x2b\x8b\x49\x1f\x8e\xa9\x83\x32\x41\xa6\x62\x5b\xd0\x84\x61\xc1\xec\x95\xc6\xe1\x43\xe8\xba\x30\xcc\xf4\xe2\x8b\x4f\xfa\x37\x67\x4c\xe6\x8b\x9b\xdb\xc6\x26\x75\x31\x0c\xc2\x1d\x20\xe1\xa7\x8c\xfd\x00\x3d\x99\xba\x0e\x07\x4e\xc8\x9e\xb0\xcf\x73\x48\xfa\x94\x12\x11\xf7\x91\x7d\xc4\x51\x78\x02\xad\xb0\xd7\x6b\x16\xca\x0c\x3f\xf1\x1f\x20\x8e\x06\xab\x83\xa8\x6f\x07\xe7\xa7\x27\x51\xc0\x00\x92\xfe\x40\x8e\x6c\x63\x40\x49\xff\x0e\xc7\x95\x4e\x47\xfb\xa4\x3f\x9c\x19\xcd\x38\xcf\xb8\xde\x51\xdc\xd9\x79\x43\x86\x75\x21\x1e\x23\x1c\x9c\x9f\xc6\x21\x68\xe0\x40\x12\x1c\x3b\x30\x4a\xd8\x1d\xe0\xd1\x78\x10\xf6\x32\xfb\xe8\x45\x83\xdb\xa5\xc3\x09\x0d\xde\xc3\x71\x0c\x7d\x61\x43\x48\x7a\x30\xee\xbe\x0b\x1b\x92\x9b\x3a\xf4\xa8\x13\x81\x38\xfe\xe8\x0e\xcb\xe9\xc2\x70\x87\x47\x49\xb5\xc5\x3b\xe8\x50\x14\x28\x9f\xc8\xa1\x48\x05\x38\x47\x93\xe1\x17\x78\x8f\x87\xc1\xb1\x89\x24\x7d\x8a\x94\x1e\xd4\xf7\x06\x37\x87\x88\x3a\x7d\x36\xb8\x9e\xf9\xc7\x61\xab\xbb\x51\x62\x20\xbe\xcb\x90\x56\x8c\x8d\x0d\xb1\x85\x82\x38\x88\x27\x4b\x00\xd5\x1d\xec\xf6\x20\x51\x81\x3e\xf8\x08\x11\x57\x96\xa8\x40\xd2\x21\x22\x37\x47\xd8\xb6\x15\xe0\x8f\x8c\xf0\x3c\x60\x22\x98\x8b\x28\x78\x1f\x3a\x0f\x6c\xe9\x88\x02\x18\xd1\x4b\x96\x7c\x44\x7b\xd0\xf1\x14\x90\x2e\x74\x47\x90\xe0\x64\x46\x4d\xea\x58\x37\x47\xf4\x41\xad\x60\xf3\xe8\x38\x01\xd3\x42\x36\x93\x3d\x12\x8d\xb8\xc4\xa6\x47\x9d\x54\x66\x67\xc8\xf1\x06\x0a\x90\x64\xec\xe2\xfe\x99\x58\x04\x4d\x14\x88\x5a\xa3\x3b\x1f\xa0\x01\x49\x8f\xf1\x0e\xf3\xa1\xda\x9d\xab\x9c\x96\x0b\x87\xa9\xa0\xcb\x01\xcb\x0a\xdb\xd0\xb3\x42\x33\x02\x1d\x84\xc8\x03\x36\x07\x89\x98\x74\xa6\xd3\x19\xf2\xbf\xe9\x90\x54\x40\x2a\xeb\x8b\x6e\x83\x17\x79\xd1\xe8\xa6\x43\x08\xbe\x47\x8e\xcb\xd7\x08\x35\xfc\x2f\xdf\xf6\x95\xa0\x64\xc2\x8b\x6e\x43\xfd\xca\xc8\x42\x26\x17\x34\xab\x8e\xec\xbe\x03\x2d\x24\x69\x58\xf3\x8b\xdf\xb3\xbf\x08\x49\x66\x06\xc8\x19\xb5\xfa\xd4\x11\x7c\xe7\x0c\x90\x0e\x74\xe0\x17\xc4\xd5\x1a\xb3\x20\x86\x74\xfc\x05\xcd\x8e\xff\x0b\xf6\x1d\xd4\x8b\xe3\x1b\x03\xec\x62\x02\xfd\x40\x39\x9c\xcb\x1d\x53\x3b\x86\xd8\xf7\x7b\x36\x26\xc1\x01\x76\x94\x6c\x8f\x90\xed\x62\x32\xc4\x41\x74\x2f\xa5\x83\xd1\x00\x8e\x48\x0c\x72\xec\x7a\x90\xf4\x7c\x5b\x10\x13\xf9\x95\x11\xdf\xf5\x9d\x21\xd7\xdb\xc9\xae\xc2\x6e\x8f\x92\x80\x31\x5c\x7e\x1f\x2a\x29\x9a\x94\x58\x94\x04\x71\xcb\x6e\x05\x9f\x94\x19\x7d\xe8\x23\x87\xb8\x89\x7c\x13\xf1\xc7\xae\x8d\x18\xbb\xd8\x82\x64\x16\xc8\x7b\xe4\x64\x65\x70\x58\xcf\x08\x2a\x24\xfb\x27\xbc\x3c\xe9\xaa\xd0\xb9\x88\x03\x4f\x5d\x9b\x06\x35\xc7\x64\xb4\xb0\x49\x49\x7f\x82\xa0\xd3\x9b\x20\x92\x86\x90\xf4\xf2\x3d\x24\x37\x2d\x98\x00\x38\x73\x60\xdf\x8f\x06\xb3\xee\x40\x0f\xbb\x36\xbc\x87\xa9\xd3\xfb\xa3\xe9\xc2\x32\x70\x30\xa1\xd9\xf1\x97\xd0\xc3\xa6\xda\xfe\x70\xbf\xf5\x19\x0d\x09\xa9\x9c\x34\xbe\x83\xcd\x41\x54\xaa\xef\x62\xd2\x57\x6b\x95\x8c\xbf\x84\x96\xff\xa8\x6e\x48\x73\xb0\xeb\x8d\xa0\x2b\xc9\x42\x61\x5b\x75\x69\xf5\xcd\x21\x2b\x2c\xa8\x11\x0f\xf2\xae\x81\x7f\xb4\xcc\x96\xef\x58\xf4\x19\x28\xb1\x9a\x9c\x51\x2e\x49\x4f\x01\xb6\xff\xca\x70\x30\x6f\xff\x55\x68\x1c\xd5\xba\x53\xee\x95\x91\x9d\xde\xf1\x87\x33\x23\x3f\xc2\xb1\xea\xa2\xc8\xb9\xd9\x90\xad\x17\x1f\xc7\x72\xf9\x49\x78\x84\xc9\x8f\x0e\xc4\x62\x29\x9e\xf2\xc5\x92\x01\x9c\xc7\xf7\x68\x26\xcc\x45\xe7\x8f\x23\xf8\x00\x31\xce\xdc\x6d\x16\xbd\x65\xba\x14\x45\x7e\x49\xd8\x7a\x80\x93\xb9\x20\x1d\x38\xa2\x30\x13\xe2\xa2\x93\x11\x69\x33\xba\x11\x0e\xea\x6e\x86\xd7\x48\xfc\x4d\xe0\x18\x25\x00\x1c\xef\xa6\x45\x1d\xe4\xf6\x26\x51\x0e\x86\x9e\x70\xb2\x70\xe0\x03\x8c\xe3\x4a\xd3\x71\x91\x17\xa7\x4f\xe0\xad\x50\x29\xcf\x80\xb8\x82\x43\x34\x2f\xd6\xb6\xb1\x9b\xfb\xac\xe5\x4c\xea\x13\xcf\xc1\x48\x18\xb7\xf6\xe5\x84\xae\x11\x8b\x86\xab\xe5\x41\x10\x73\xf8\xec\xfb\x9d\x64\x95\x04\x69\xab\x1d\x06\x99\xe2\x28\xc8\x50\x41\x1c\x3f\x0b\x1a\xab\x35\x9a\x41\xe2\xec\x44\x16\xd4\x0a\xb9\x5c\xe4\xa0\x7b\xc1\xe2\x9d\x06\xaa\xe1\x03\x4c\xd9\x53\x3e\xa8\xd8\xd3\x80\x2e\x9a\x00\x25\x60\x1f\xde\x63\x37\x11\xe0\x8f\x28\xf1\xf6\x2f\x1c\xae\xad\x52\x63\x5a\xf0\xc1\xa5\x44\x0d\x39\x83\xf6\x08\x39\x6a\xc8\x39\xf5\x06\xc8\x81\x6a\x50\x67\x42\x1f\x12\x01\x5d\x87\xda\xb6\x1a\x70\x49\x5d\x8f\x0e\x41\x1a\x99\x41\x26\x6d\xa8\x9d\x67\x68\xb7\x55\xd5\x38\x98\xa9\x7d\xce\x88\xe9\x40\xdb\xcb\x0a\xe7\x5a\xe7\x8c\xf0\xae\x6f\xfa\x23\x48\xb2\xca\x90\xba\xf2\x8c\xb8\x26\xbc\x39\xc7\xf4\x4b\x76\x05\xc8\xcd\x7b\x3f\x33\xc7\x50\x9f\x3d\x23\x51\xd3\xc7\x59\x4d\x3d\xc7\xf4\xe6\x10\xda\x36\xe2\x73\x61\x2a\xfa\xc2\x1d\xf8\x50\x70\x9a\x9d\x60\x0a\xdd\x59\x70\x37\x48\x1c\xd3\xc5\x82\x2e\x82\x0c\x1e\x37\x39\x33\xcc\x3b\x9f\xb1\x02\x20\xcd\x32\x2b\x01\x0d\xdf\x49\x42\x44\xac\x30\x48\x73\xa3\x20\x93\x93\x07\xd3\x92\x80\x12\xd4\xc4\xc4\x42\x7c\x68\xa6\x84\x0a\x90\xe6\xf5\x41\x8a\xcd\x56\xbe\x0f\x7c\x53\xe0\xde\x55\x90\x52\xdd\x83\x29\xfd\xff\x75\x90\x62\x8b\x40\x06\x5b\x54\xfb\x4b\xca\xac\x43\xc6\x27\xd6\x6b\x41\x8a\x45\x03\xd3\x4c\x5e\xbd\x1e\x1b\x7d\xa0\xd3\x83\x16\x75\x59\xe8\x7e\x10\xeb\x1f\xd8\xf7\x41\xcc\x10\xf8\xae\x8b\x6c\x0e\xf4\x2e\x48\x1a\x9f\x41\xa6\x05\xbb\x7e\x18\xa8\x47\xd5\xb3\x90\xa3\x20\x16\xb3\x41\x4a\xcc\xae\x1f\x07\x09\xeb\x23\xc8\x30\x8e\xd6\xdf\x67\x12\xa2\x84\x05\xb6\xde\x7c\x86\xfa\xa5\x95\x96\xf5\x56\xcc\x17\xd5\x91\x33\xf2\x39\x4d\xab\xb7\xc3\x3e\x75\x7c\x82\x18\x41\xae\x9f\xc6\x9a\x76\x78\x73\x06\x19\x1f\x52\xff\x30\x73\x04\x13\x16\x9a\x7a\x4c\x50\x42\xbd\x75\x04\x57\x67\xd5\x00\xaa\x99\x02\xda\x48\xc1\xc8\x73\x64\xe2\x5b\xa4\x4c\x0c\xd8\xf7\x21\x26\x31\x40\x0b\x9a\x08\xc7\xe5\xd6\xe1\x00\xc7\x91\x91\xfe\x0f\xc4\x6a\xf1\xd1\x98\xde\x1c\x3a\x90\x58\x71\xae\x0d\x1f\xc3\x9e\x9a\x8a\xe1\x9d\x52\x2d\xa1\xa1\xbc\x44\xf6\x40\x29\x88\xc2\x9b\x4b\xec\x7a\x6a\x4d\x08\xf4\x63\x8a\x70\x80\x59\xd7\x8d\xe3\x52\x62\x95\x26\xeb\x92\x4e\xdc\x25\xd0\x75\x21\x9f\x31\xdd\x40\xd5\x3d\xb0\x90\xab\xec\x49\xa1\x18\xc4\xeb\x1f\x03\xf5\x12\x6b\x16\xf2\x57\xa0\xf4\x2e\x7e\x64\x50\x8d\x5a\x90\xd6\x79\x82\x94\xd9\x27\xfa\x3e\xb4\xa1\x89\x6e\xea\x30\x26\xce\x2d\x4a\x4c\x8f\xc6\x53\xe8\x90\x52\x37\x09\x51\xb7\x21\x31\x0b\x1d\xd8\xb3\x15\xb0\x50\x4d\x19\x7d\xb7\xf1\x18\xf7\xd5\xf8\x81\x4f\x2c\xe4\x24\x32\x3a\xbe\x83\xb6\x8f\x3d\xa0\x58\x35\xfa\x04\x3b\x9e\x4f\xfa\xf1\x24\x08\x6d\x8e\x20\xad\xa9\x8c\xbb\x1a\x62\x32\xb9\x39\x67\xa2\xa4\x32\x93\x5c\x6a\xfb\x9e\x32\x1e\x90\x0c\x31\xb9\x39\x26\x36\xf2\x40\x52\x89\x1d\x4f\x85\x07\x7c\xeb\xdd\x30\xba\x8a\x48\x0c\x24\x8d\x79\xea\xac\xea\x39\xd8\xea\x27\x3b\xe5\x23\xb2\x6d\xfa\x30\x24\xea\x04\x3e\x26\xfe\x3d\x1e\xc6\x09\x1d\xe4\xaa\x19\xed\x73\x06\xe0\xa6\xe1\x20\x34\x4c\x60\xc5\x4d\x1b\xd9\xae\x02\x18\x69\x78\xc1\xb4\x42\x37\x95\x1b\x1b\xfe\x46\xa0\x1e\x40\xc1\x42\xf6\xb3\x67\x56\x82\xb0\x48\x8f\x13\x90\xe5\x2b\xd1\x78\x97\x49\x8c\x22\x0f\x98\xc6\x61\x76\x7c\xc2\x09\xa6\x71\x14\x24\x24\x1d\x16\x74\x9c\x22\xaf\x2c\xec\x24\x98\x72\x73\x66\xc1\xcd\x20\x6d\x0e\x88\x27\x8e\x4f\x3c\x78\x53\x73\x10\x81\x2e\x48\xca\x16\x2c\x65\x2b\xb3\x72\x91\xff\x4d\x23\x24\x7f\x52\x7f\x08\x14\x1d\x1e\x8b\x8e\x89\x61\x9d\xf6\x29\xd7\xed\x36\xce\x15\x1b\xb8\xeb\x31\x7e\x84\x2b\x1c\x1a\x17\x41\x8c\x69\xf7\x42\x4f\xd1\xb8\x8c\x69\x6e\x03\x8e\xd1\xcd\x25\x72\x2c\xde\x1f\x53\x6b\x22\x0b\xbc\x0e\xd2\x12\x1f\x0b\xfd\x18\xa8\x2a\x5d\x51\xc3\x77\x70\x04\xfb\xbe\x2b\x2a\xf4\x57\x90\x90\x6d\x73\x5a\x6e\xff\x20\xd9\xdd\x20\x5a\x28\x1d\x1b\x13\x30\x2d\x86\xee\x47\x2b\x4e\xe8\xc6\x01\xa6\xbd\x4d\xf6\x4f\x64\xa6\x0d\x3a\x46\x64\x00\xc3\xa4\xad\x67\x16\x22\xc5\x18\xb8\x7f\x9a\x18\x48\x7a\xc3\xe3\x38\xb7\xb4\xff\x57\x34\x1d\xec\x3e\x46\x0e\x6b\xfa\x41\x43\x35\x00\x4e\xe0\x9d\x8f\x6d\x30\xb5\xd1\x89\x01\x46\xed\x0d\xef\x0e\x60\x61\xd1\xbc\xe4\x7e\x61\x2c\xe4\x48\x86\x1c\xd8\x37\x35\x88\x7d\x0e\x76\x3e\xa3\xe5\x91\x2f\xcf\x41\x27\xd6\xd1\x58\x0e\xb6\x24\x40\x03\xf9\x6c\x55\x88\xc7\x97\x40\xee\x75\x77\xd0\x9d\x95\x63\xc2\x83\xe8\xdd\x71\x9a\xe7\x61\x81\xef\x03\x75\x6b\x1d\x0b\x39\x51\x7d\xde\x20\xb1\xb9\x3e\xe5\x5d\x2b\x48\xc8\xd8\x20\x25\x38\x82\xe4\x76\x20\x96\xe2\x34\x48\x2a\xa1\x59\xd8\x79\xa0\xde\x37\x9c\xd3\x72\x87\xb5\x6c\x11\x48\xf5\x39\x3b\xac\x07\x09\xdd\x0d\x0b\xda\x7f\x66\x0e\xc4\x76\xde\xc3\x50\x00\xec\xf6\xb0\x8d\x5d\xd6\xc2\xc3\x77\xaa\x31\x1b\x11\xbe\xdc\x1d\x1e\x26\x0b\x01\xd3\x4a\xa9\xc3\x68\x38\x6b\xa6\xc9\x47\xea\x30\xea\xd2\x43\xdc\x73\x98\x3c\xc2\x68\xc0\x61\x4c\x3d\x0e\xa9\xe5\x0d\x60\x4f\x21\x9c\x64\x04\x9d\xa1\x3b\x80\xf7\x0a\xe3\x64\x0a\xb1\xda\xf5\x99\xe0\x14\xaf\x61\xa2\xf1\xad\x19\x4c\x61\xe4\x94\x79\xd8\x9e\x01\x11\xfb\x65\x1e\x9e\x3d\xd7\x5d\xaa\xb9\xfb\xf0\x43\xe6\x98\x44\x9e\x7c\x87\xd1\x28\xd6\xbc\x01\x22\x7c\x18\x3b\x41\xb6\xcd\x80\xc5\x75\x55\xa4\xf2\xd0\x48\x50\xc2\xc3\x8b\x40\xd5\xba\xb0\x90\x88\x29\xa9\xe3\x90\x73\x39\xfc\xa8\xa4\x9d\x08\x1a\x77\x74\x12\x24\x6d\x6f\x2c\xac\x1d\x9b\x99\x51\xdf\x37\x71\x1f\xda\x63\x0e\x7c\x3e\x8b\x67\x8f\xd4\xaa\x47\xdd\x44\xe7\x14\xa0\x5f\x10\xbe\x3d\x2c\xee\x22\x56\xa1\x59\x70\x2c\xf4\xf8\xc7\x21\x33\xff\x1e\x0e\xa1\xe3\x85\x04\xf2\x8c\x72\x4b\x23\x1c\x82\x84\xc9\x0c\x84\x90\x13\x38\x16\xac\xf6\x71\x44\x39\x84\x96\x96\x05\x35\x83\xa4\x4d\x90\x85\xb5\xb2\xa7\x63\x52\x07\x7a\x1c\xae\x26\xa1\x59\x90\x85\x9c\x06\x89\x53\xa5\x58\xd0\x07\x29\xc5\xf4\x07\x16\xb7\xa3\x1e\x9f\x07\x8a\x79\x8a\x05\x28\xc3\x17\xd9\x83\x58\x78\x24\x51\x9e\x0b\x27\xdc\xf7\x07\xd9\xd5\x8a\xf4\xae\xef\x63\xe2\x1c\x7b\xd9\xbc\x3f\x0d\xad\x78\x23\xe1\x39\xf2\xfe\x2c\x88\x0d\x5e\x39\x2d\x77\x72\x90\x22\x60\x2c\xec\x30\xac\x35\x76\x07\x43\xc4\x2a\x73\x72\x14\xa8\x16\x5e\x30\x6d\x00\x3e\x39\x0e\x92\x0a\x23\x30\xb5\x3d\x19\x4c\x6f\x7b\x64\x09\x5b\x69\x0a\x9a\xf6\x39\x3c\x69\x3f\x2f\xfd\x48\x27\x8c\x93\xb0\x79\x67\x13\x4a\xfa\x13\x61\x24\x3d\x09\xbb\x9c\x9b\x28\xd9\xf7\x55\xa0\x18\x33\x41\xd2\x98\x79\x12\xcf\x7a\xe1\x7c\xa3\xf0\x83\xa1\xf3\xcd\x49\x28\x9a\xd6\xec\x11\xf4\x26\x22\xfd\x87\xc9\xe3\xc4\xa6\x8e\x15\xce\xc8\x0f\x8c\x59\x20\x30\x8c\xac\xdd\x79\xb4\x87\xa2\x77\xe8\x87\xaf\xde\xc4\x91\xef\xa7\xc2\x08\xdf\xac\x65\xf4\xb3\x6a\x49\x6f\xd6\x43\x00\x84\x1d\x9f\xd5\xb7\xd9\x78\xbe\x73\xa4\xe3\x49\xf3\x38\x9b\x53\x90\x2a\xe8\x66\x88\xdd\x0d\x6a\xd3\x11\x27\x37\xcd\xf3\xd8\x91\x94\x38\x54\xb8\x40\x36\x3b\x41\x86\x2f\x35\x48\xfb\x5b\x37\x15\x95\x08\x3f\x64\x99\x85\x45\x38\xdd\xf4\xbf\xa2\x51\x8f\xfa\x0e\x1b\xa1\xe6\x65\xa0\x5c\x46\xcd\x02\x3e\x06\x49\x4f\xd2\x9c\x96\x6b\xd5\xe2\x35\xde\x85\x3d\x26\x9c\x30\xd0\x56\x23\x5a\xb1\x29\x81\x5c\x0e\x6b\x45\xba\x48\x69\xaf\xe1\x47\x82\xcd\xa2\x46\xaa\x25\xa9\xf5\xee\x99\xee\x8c\x3d\x8e\x5a\x87\x33\x26\x6e\xca\xa3\xb6\x75\x14\x24\xb7\xd2\x82\x29\x95\x34\x83\x3a\x99\xa9\xe0\x90\x36\xaa\x56\x73\xe6\x72\x14\x6e\x21\x68\xb5\x52\xc6\xfc\x56\x3b\x48\xdb\xb2\x41\x48\xc0\xef\x2d\x20\x2d\xf3\xb8\x07\x6d\x97\x4f\xed\xd6\x69\xec\x82\xc0\x3b\xed\x2c\xb1\x50\x80\x29\xf5\x7c\xeb\x83\xea\x8b\xe5\x61\x82\xef\x38\x53\xda\x3a\x9f\x51\xd7\xc4\xa6\x81\x56\xe7\xb9\xde\x56\xfd\xb6\x5a\xdd\x98\x37\xb3\x39\xc5\x6d\x5d\x04\xe9\x43\xed\x58\xe8\x65\x90\x3a\x1a\x8f\x05\xce\x90\xba\x15\x3f\xf6\xd6\xb5\xe2\x13\x1b\x79\xf7\x29\xf8\x4f\x4c\x5f\xa9\x1a\x72\xb0\x05\x13\x35\x45\x8e\x83\x14\x01\x1b\x7a\x90\x51\x30\x57\x09\x11\x5e\x85\x71\x96\x03\x3c\xf0\xe1\xc0\x8f\xb3\x39\xfd\x82\x09\xec\xc7\xdf\x47\xc8\x19\x51\x17\xdb\x8a\xb6\x23\x74\x37\x4a\x6a\x47\x6e\xea\x90\x91\x59\x2e\x44\xb4\x3e\x06\x53\x0e\x27\x92\xca\x99\x03\xe1\x64\xd1\xfa\x2b\xd9\x1d\x39\x2d\xd7\x8e\xf0\xeb\x0a\x13\x6b\x40\x39\xe1\x6f\x37\x82\xe4\x5e\x5b\x16\x76\x90\xc9\xa3\x44\x1b\x0a\xda\xef\x82\xd4\xee\x66\x16\x98\x94\x1c\x59\xc8\x71\xa0\x6a\x59\x84\x9e\xbf\x1d\xe9\xee\x6b\x23\x26\xd6\x59\x9c\x3b\x69\x9f\x06\x8a\xc9\x8f\x05\x9c\x05\x49\x97\x1d\x16\x76\x1e\x24\xf6\x7a\xb3\xa0\x98\xcf\x69\x63\x3e\x2f\xdb\x7f\x05\x53\xfa\xf2\x94\xdd\x2b\xa7\xe5\x4e\x5b\x8a\xe1\x02\x24\x5d\x93\xce\x6a\xa9\x05\x82\x85\x1d\xc4\x7a\x34\x2c\x42\xde\x05\xc9\x0d\xb0\x60\x6a\xbf\x3b\x48\x9d\xba\xc0\x52\x1d\x06\x59\x36\x1f\x90\x75\x52\x0a\x03\x3f\x92\xd8\x4a\x30\xe7\xeb\xce\x4e\x64\xb7\x38\xd0\xe4\x02\xfd\x59\xd4\x9f\xc2\x58\xc9\x82\x62\x36\xa1\xc5\xb0\xd5\x16\x36\xb4\x76\x90\xde\xf4\xcc\x42\x63\xf9\xf7\xcc\x47\x8e\x47\x99\x00\xcc\x4d\x8d\x1d\x51\xd2\x21\x7c\x0c\x97\xbc\x23\xd4\x73\x44\x4e\x11\x9a\x0a\xd3\x74\x2c\x35\xb5\xa0\x85\xb0\xa3\x88\x51\xb5\x47\x2a\x9c\xf2\xcf\xae\x82\x84\x9d\x8c\x05\xc5\x0b\x71\xcd\xf5\x89\x89\x79\xe6\x1f\x6a\x8a\xba\x35\xa7\xe5\xce\x0f\x82\xe4\x11\x94\x2c\xec\x34\x66\x1c\xcd\x01\x74\x04\xe7\x78\xde\x49\x13\x58\x16\x18\xad\x47\x27\xd0\xc6\x04\x13\x16\x01\x12\x56\x69\x30\x75\x59\xad\x0c\x39\xc1\x0e\xbd\x97\x1f\x35\xd7\x73\xe0\x70\x00\x23\xb6\x2c\x3a\x3d\x1d\x24\x2f\x25\x06\xe9\x4b\x89\x40\xe2\x4a\x69\x10\xda\xa9\x86\xd0\x43\x0e\x26\x62\x65\xe5\x1c\xc2\xc8\x0d\xf9\x81\x36\xbd\xa7\x2e\xee\x61\x47\x06\xd4\xa1\x43\xa0\x6f\x83\x90\xb1\x4b\x00\x0e\xfd\x47\x82\x3c\x19\x72\xe2\x40\x97\xd0\x09\x8c\x92\x1e\x3b\x43\x3f\x8a\x6d\x0c\xb0\x64\xa9\x3f\x42\x25\xfc\x64\x00\x89\x35\xe9\x87\x51\x97\x36\xb4\xf0\xbd\xb0\x3d\x89\xc5\xc5\xf5\x0a\x6d\x24\xab\xde\x82\x7d\x68\x31\x1a\x27\x3c\xf6\x86\x03\xd6\xb1\xe1\x97\x83\x2c\x82\x86\xd4\x9e\x44\x55\x3c\x81\x23\x73\x00\xbd\x61\x98\xb8\x46\xa0\x35\xe1\xe3\x3a\x83\x5c\x47\xfb\x7e\x3a\x35\x95\x89\x63\x01\xf5\x20\xe3\x50\x12\x16\xd1\x08\x94\xa3\x55\x59\x40\xa4\x26\x3b\x19\x40\xc7\xa3\x3e\x43\xf9\x4e\xc4\x1e\x44\x57\x6e\xb2\xd0\xc3\x69\x67\xbe\xce\xd1\xd4\xd2\x96\xb5\x4f\xad\x73\x3c\x6b\x41\x57\x9d\x5b\x3a\xef\x55\xca\x06\xb2\xdd\x1d\x3a\x27\x49\xa5\x0f\xc8\x72\x68\xe8\xcc\xe2\x0e\x94\x4d\x7e\x9d\x96\x2a\x53\x80\x2c\xbf\x87\xce\x2c\x89\x56\xee\x24\xec\x9c\xce\xd0\x78\xa8\x5b\x8d\x3a\x0a\xdd\x80\x0e\x9b\xd8\x98\xf3\x93\x9d\x98\x75\x14\xc6\xa0\x4e\xa4\x3f\xe9\x40\x7a\xd3\x15\x92\x4e\xe7\x32\xf6\xca\xb5\x6f\x3a\xd0\xbe\x87\x16\x77\xba\xeb\x5c\xcf\xb4\x4d\xa4\x37\x86\x74\x3e\x4a\x57\xd3\x11\x74\x4d\xce\x17\x74\xfe\x9a\xcb\xb7\x46\x7b\x00\xbb\x8a\x26\xca\x81\xc4\xba\xe9\xfa\x0e\x5b\xc2\xba\xd1\xbc\x69\x5b\x5f\xe0\x48\x0c\x73\xf7\x5d\x8a\x00\x81\xf4\xa9\xbf\x0c\xe8\x70\x46\xa7\x86\xfb\x2b\xbb\x49\xf1\x8a\x85\xbc\x97\x2b\x90\x3b\x80\xa4\xc7\x81\x62\x7d\x69\x78\x6e\x13\x0b\x0c\xe5\xd7\x7d\xcc\xb1\xa2\xdb\x8a\x3c\x77\xb9\x1f\x2f\x0b\x8a\x06\xb4\xeb\x13\xae\xf7\xe9\x9e\x06\x53\x47\x2d\xb0\xe0\xf3\x20\xe5\x6b\xc4\x02\xbb\xd9\x1c\x1a\x8b\xba\xcc\xf2\x29\xe8\x86\xc2\x95\x70\xc8\x64\x01\x7f\xcd\xd2\x36\xa6\x76\xc0\x5d\x44\x26\xbe\x2c\x52\x8b\x62\xc2\x19\x5e\x07\x06\xa6\x4e\x3c\x67\x99\x4c\x31\xe5\x53\x1b\xe5\x2e\x5a\xd3\x16\x5c\xa0\xfa\x3e\x80\xb4\x3f\x09\x98\xf2\x09\xb9\x50\x2c\x3d\xe1\x1e\x8f\x58\xcf\x24\xf6\x0c\xc5\x56\xb3\xe9\xfd\x2d\xd3\x71\x8c\x7d\xc4\x26\x52\xf9\xbc\xac\x7d\x42\x53\x91\x62\x03\x00\x41\xd3\x31\x57\x98\x31\x27\xe6\x54\x78\x0b\x3a\x88\xf4\xa7\x8b\x39\x43\x1e\x72\x42\x8c\x48\x17\x82\xee\x15\x0b\x48\xb8\xe9\x6b\x0a\xaa\x8b\x6c\x3b\xc9\x31\xab\x9b\x83\x14\xbe\x99\xd0\x11\x26\x28\xee\x04\xee\x37\x7a\xb3\x0f\x87\xd4\x13\x0e\xe9\x8a\x01\x24\x11\xc7\xba\xba\x03\x55\xdb\x62\x22\xba\x8e\x7c\x1b\x0e\x94\x71\x20\xaa\x29\xa5\x4e\xb1\x62\x45\x09\x37\xce\x28\xe4\x23\xda\x32\xa4\xb8\x94\x84\xbb\x0e\xa3\x90\xf7\x3e\x41\x4c\x62\x97\xa2\x35\xe6\x0b\x57\xd4\x30\xcf\x86\x43\xc6\xe0\xc7\xc6\x22\xb6\x8a\x42\x4f\xa9\xee\x48\x31\x7b\x5a\x70\x38\x35\xd5\xd8\xdc\xfa\x98\xd8\x26\x80\xee\xb1\x85\x18\xaa\x5f\xfc\x25\xbd\xe0\x47\xd0\x19\x72\x47\x0f\x81\x68\xee\x60\x28\xf6\x80\x5c\xd6\xb2\xc8\x7b\xec\xb6\x76\xb9\x80\xae\x20\xde\x51\x72\x79\xa0\xa8\x6a\x19\xb1\x65\xb4\xe3\xf2\x39\x97\x9d\x78\xa7\xc9\xe5\x73\x2e\x3b\xea\x4e\x97\xcb\x76\x86\xe2\x43\xd9\x00\xc0\x40\x62\x66\x9e\x9f\xd2\x97\xd3\x72\x57\xef\xd2\x6e\x49\x5a\xee\x2a\x76\xd0\xa8\x8d\xb9\xbe\xe2\xe3\xc1\xb4\xbe\x27\x74\x6a\xff\x38\xa5\xbe\x9f\xda\xd1\xfa\x57\x2d\x6b\xd5\x60\x11\xad\x19\xd6\x36\xb9\xb5\xf8\xaf\x19\x3c\x4c\xb8\xb3\xf9\xf3\xd3\xbf\xf2\x4f\xda\xad\x4f\x4c\x0f\x53\xb2\x8e\x34\x4f\x23\xf9\x6f\x39\xdf\x45\xc0\xf5\x1c\x6c\x7a\xb9\xb7\xf7\xd0\x01\x4e\x35\x27\x61\x72\xd5\x6a\xd5\x9b\x8c\x11\xbd\x05\x9d\xc9\xa8\x47\xed\xb5\x35\xf1\x2c\xde\x52\x47\xa3\x55\xe7\xcf\xf8\x73\x3d\xe7\x20\x68\x7a\x45\x64\xa3\x11\x1b\xcf\xfc\xde\x96\x6e\xe8\x65\x0d\x67\x42\x8d\xb9\x8d\x3e\x04\xda\xd2\x60\x26\xd0\xad\x03\xfb\x4a\x5e\xdb\x9a\x9b\x09\x26\x2a\x7f\x33\xa2\x16\x0a\x21\x77\x34\x33\xbb\x54\x87\xde\x62\x1b\x39\x02\xcc\xa8\x68\xf6\x2c\x30\x86\x03\x21\x98\xbe\xab\xf9\x99\x60\x26\x43\x96\xaf\x61\xed\x0c\x5d\x1b\x67\x42\x41\x77\x42\x4c\xa5\x72\x86\xa1\xdd\xce\xca\xce\x14\x26\xe2\x24\xb4\x95\xdd\x37\xd4\x79\x80\x8e\x75\xe3\xa0\xdb\x10\xb2\xa4\x0d\xb2\xbb\xc7\x77\xc7\x88\xb8\x32\xc3\xb2\xd6\x9b\x0b\x76\x63\x63\x37\x6c\x53\x49\xd7\x46\x99\xb0\x23\x34\xa2\x61\x76\x9b\x5a\x2b\x13\xc4\x86\x8f\x93\x10\x64\x4b\xeb\x67\x82\xf4\x6c\x6a\x0e\xc3\x92\x0c\x6d\x92\xdd\x4c\x9f\x58\x8c\xf3\x89\x26\x8b\xb1\xad\xdd\x67\x42\x3a\xc8\x1d\x53\x12\x8d\x9a\xb1\xa3\xd5\xb2\xdb\x69\xd2\xb1\xec\x8b\xdd\xb7\x72\xa6\x83\x9b\x75\x94\xff\x86\x6f\xd7\x73\xb4\xf7\x05\x99\x9e\x32\xf3\xd1\xda\x1a\xf1\x6d\xfb\x4d\xb5\x8a\xf2\xdf\x18\x82\x78\x55\x54\xfc\x7f\xff\x4f\xc4\xbe\x75\x1f\xb0\x67\x0e\xd6\xbd\xfc\x37\x13\xba\x08\xd0\xbd\x30\x00\x55\x51\x91\x81\x84\xe1\xe3\x3d\xfe\xb8\x15\x0f\x28\x1e\xa6\x78\xb8\xe2\x31\xd8\x73\x90\xe7\x3b\x04\xa0\xb7\x16\xba\x85\xbe\xed\x29\x79\xad\xad\xc5\x65\x86\x59\xfa\x22\x99\x25\x1e\x2d\xf1\x18\x89\x87\x3d\x9d\x57\x18\xe0\x3d\x3d\x71\x08\xac\x04\x3c\x45\xbd\xf0\xc0\x7a\x21\x8c\x60\x3d\x52\xad\x56\x6f\x9f\xbc\x62\x8d\xcd\xe1\x16\xb5\x50\x75\xac\x79\xc5\x46\x34\x51\x79\xd0\xad\x08\x62\xa8\xd0\xa0\xc4\xf5\x47\xc8\xa9\xfa\x71\xd8\x59\x88\x4c\x55\x5b\xf3\x8a\x07\x82\x38\x54\xa9\xe6\x15\xdf\x89\x19\x7c\x8e\x6e\xab\x16\xfb\x0c\x91\xbd\x0a\x35\xaf\xd8\x84\x8f\x93\x6a\x4b\xf3\x8a\x2d\x34\xa2\xd5\x91\xe6\x15\xcf\x38\xc1\xa8\x62\xf6\x1a\x62\x71\xd5\xd4\xbc\x62\x87\x23\x3f\xaf\x88\xcb\x3e\xc3\x59\x5c\x1d\x68\x5e\x11\xbb\x71\xc5\x63\xb2\x17\x35\x90\x35\x36\x08\xc2\x66\x8e\x9f\x78\x82\x54\xdb\x1e\x64\x60\xa2\x75\x19\x79\x85\xb9\xf8\x4f\x6a\x82\xa8\xe9\xb3\x13\xd8\x22\x81\xec\x97\x69\xc0\xb9\xf3\x51\x9d\x15\xd5\x6a\x95\x8a\xcc\x94\x8e\x9d\x5d\xb0\x15\xc2\xca\x5e\x9f\x0d\x09\x05\x24\x1f\x92\xd9\x50\x2d\x01\xc5\xc7\x6b\x36\xd4\x48\x40\x85\x83\x39\x1b\x0e\x87\x70\x72\xa4\x67\x43\x9a\x02\x52\x99\x06\xb3\x61\xdd\x10\x56\xce\x91\xd9\x90\x03\x01\x79\x09\x6d\x6c\x85\x63\xd3\x9d\x8c\xb3\x52\xe4\xd8\xea\x43\xfa\xea\xf8\x04\x41\xd6\x02\x8a\x82\x00\xb1\xde\x14\x8f\x5b\xf1\x30\xc5\xc3\x15\x8f\x81\x78\xf4\x82\xe0\x99\x51\x5f\x4f\x0c\x7b\x2b\x08\x12\xdf\xa3\xd4\xb7\x9d\xfa\xf6\x53\xdf\x56\xea\x7b\x92\xfa\xbe\x4f\x7d\xd7\x52\xdf\xfd\x3c\xeb\x2d\xf6\x79\x7a\x5b\xbd\x59\x88\xc3\x20\xeb\xc6\x76\x5e\xa3\x55\x52\x24\xeb\x4e\x5e\xc3\x55\xb2\x5e\xd2\xf3\x1a\xe4\x01\x38\xff\x76\x9d\xa5\xcd\x57\xff\xf3\xcd\xa4\xc4\xf5\x00\xa9\xe6\x2c\xe8\x21\x0f\x8f\xd0\x18\x9b\x43\xe4\xe4\x34\xa7\x9a\xcb\xf1\x25\x13\x7a\xeb\x84\x65\x95\x2b\x46\xdf\x3c\xc7\x6f\xfb\xb5\x6e\xed\xa6\x7b\x7a\x78\xd8\x3c\xd8\xfb\xd7\x27\x0b\x7a\xb0\xe0\xd1\x7e\xdf\x46\xd5\xdc\xbf\x22\x48\xed\x5f\xb9\xcf\x8c\x2b\x82\xd5\x6f\xc7\xed\xb3\x8b\xee\x9e\x92\xab\x96\x2b\x60\x32\xf6\xbd\x5c\xfe\x49\x73\xab\xdf\x1a\x47\xb5\xf6\xe1\xc1\x5e\xce\x1c\x40\xd2\x47\x11\x18\xcd\x6b\xf5\xe6\xc5\xf9\x5e\xae\x67\xfb\x8e\x1a\x7a\x72\xf0\xf1\xe2\x6c\x2f\x37\x44\x13\x7f\x9c\x0a\xdf\x3f\xbd\x6a\xf3\x18\x8b\x3e\x10\x35\xee\xdd\x69\xe3\xa2\xb3\x97\xbb\xa5\xa6\xef\xaa\xe1\x8d\xe6\x71\xe3\xe4\x86\xb7\xa8\x76\x76\xbc\x97\x33\x6d\x6c\x0e\x15\x00\xf9\x96\x2b\xf2\x76\xc2\x31\xce\xe5\xb5\x8b\xb3\xfd\x5a\xf7\x60\x2f\xe7\x8f\x59\xe7\xa9\xd9\x1d\x9c\x9f\x9f\x9e\xef\xe5\x90\xe3\xd0\x44\x95\x8f\x8e\xf7\x0f\xf6\x72\x03\x6c\x25\xa0\x3b\x47\xa7\x57\x7b\x39\x77\x40\x1f\x94\xd0\x27\xcd\xac\x7e\xfa\xd6\x68\xd6\x3a\x9d\x9b\x76\xad\x75\xb0\x97\xb3\xe0\xc4\xcd\x69\xed\xda\xe5\xcd\xbb\x8b\x76\xa3\x7b\x7c\xda\xde\xcb\xb5\x44\x40\xa7\x7b\x70\xb6\x67\x3c\x69\x09\xf8\x11\x25\xde\x60\x2a\xc5\x64\x4e\x8a\x09\x82\xce\xfc\x04\x7a\x2a\x85\x85\x4c\x68\xa1\x67\xd2\xe8\x4f\x9f\x35\xbb\xfa\xcd\x1f\xef\x95\x77\xb4\xf2\x0e\xeb\xb0\x9c\xc6\x46\x66\xaf\xa2\x6b\x15\x7d\x2f\xc7\x47\x49\xb3\xd1\xad\xb7\x57\xde\xd6\xca\xdb\x7b\x39\xf6\x9e\xd3\x1c\xdc\x1f\x78\x7b\xe5\x5d\xad\xbc\xbb\x97\xe3\x1f\x39\xcd\x83\xbd\xbd\x5d\x6d\x77\x2f\xe7\xc1\x5e\x4e\x43\xae\x09\xc7\x68\xaf\xb4\xad\x95\xb6\xf7\x72\xe2\x2b\xa7\x71\x89\x73\xcf\x28\x6b\x46\x79\x2f\xc7\x3f\x72\xda\x18\xf6\xd1\xc5\x78\xaf\x5c\xd6\xca\xe5\xbd\x9c\xf8\x12\xa1\xfb\xac\x26\xe5\x8a\x56\xae\x88\xf0\x7d\x5e\x1b\x77\x80\x6f\xbd\x3d\x63\x4b\x33\xb6\xd8\xd8\x60\x56\x1f\xc6\x90\x3a\xd4\xde\x33\xb6\x35\x63\x7b\x2f\x17\x7e\xe6\x34\x77\x0c\x4d\xb4\x57\x2e\x69\xe5\xd2\x5e\x8e\x7f\xe4\x34\x6f\x6f\xa7\xa2\xed\x54\xf6\x72\x5e\x4e\xb3\x90\x8d\x3c\xb4\x57\xd9\xd2\x2a\x5b\xac\xcf\xd8\x57\xee\x49\xf3\xab\x9f\x72\x0c\xe5\x98\x90\x23\x06\x37\x1a\x33\x39\x14\x51\x07\x7f\xd6\xc6\xd5\x6f\x4f\xda\x6d\xf5\xdb\xd3\x5b\x1b\x79\xc0\xaa\x7e\x63\x49\xff\xa2\x04\xed\xe5\x72\xda\x2d\x75\x46\xd0\xdb\x7b\x63\x68\x16\x9c\x5c\x62\xf4\x70\x84\xa0\x85\x9c\x77\x22\x38\xd7\x6a\xb5\x5a\xe0\xe3\xc7\x8f\x1f\x73\x1a\xfa\xea\x39\x50\x84\xbb\x0c\xde\xf5\xd0\x78\x8c\x49\x7f\xcf\xd0\x46\x98\xec\x43\x0f\xb1\xd0\x11\xfc\x2a\x5f\x7d\x17\x85\x9e\x95\x7b\x6f\x74\xcd\xa4\xb6\x0d\xc7\x2e\x62\xef\x36\x35\xa1\x8d\xf6\xbc\xa2\x78\x59\xcf\x6b\x21\x2f\x24\x93\x5a\xd8\x85\x3d\x1b\x59\xec\x9b\x17\x86\x48\xf2\x1b\x33\xf2\xb3\xc7\x5b\xb2\x97\xbb\x85\xe0\x16\x16\x4c\xc6\xb4\x16\x68\x4e\x63\x38\x15\x05\x72\x37\x65\xe8\xe4\x34\x7f\x2c\xc3\xa0\xe3\xd0\x87\x42\x34\x95\x12\xa1\x62\x42\x8d\x1d\x74\x8f\xa9\xef\x46\xb9\x0c\xd0\xbd\x43\x49\x41\x4c\x2e\x82\xbe\x7a\xe9\x18\x39\xc7\xa8\x05\x27\xe9\xb2\x19\x90\xa8\x99\x69\x23\xe8\xc8\xe8\x70\x34\x35\xd3\xa6\x6e\x54\x5f\x31\xaa\x4f\x9a\x47\xa9\xed\xe1\x31\x6b\xa2\xc8\xf2\x90\x02\x8f\xfd\xb3\xe0\x24\xca\xa7\xc1\x1e\xc0\x45\x36\x12\x4b\x9a\xcc\xaa\xc1\x1e\xc0\x1b\x20\x20\x69\xb2\x80\x69\xb1\x39\xb2\x97\xeb\xf0\x0f\xc0\xbf\x44\x5b\xc3\x88\xb3\xb0\xd9\x32\x8a\x35\x34\x8c\x6a\xa3\xaf\x51\x0a\x91\xd9\x47\x5e\x85\x30\x2f\xf6\x21\xb2\x12\xc1\x51\x4e\x22\x82\x65\x24\x22\x78\x3e\x22\x50\x64\xb3\xcf\xa7\x69\x94\x91\xf8\x14\x59\xc9\xa8\x28\x33\x19\xc9\xb2\x93\x91\x3c\x43\x35\x55\x03\x11\xcf\x77\x26\x4a\xb2\x30\x44\xa4\x8b\xa2\x79\xc2\x28\x8a\x75\xd4\x11\xf5\x59\xd5\xb1\x39\x04\x47\xfc\x70\x23\x4c\x4c\x87\x73\x18\x22\xe6\x58\x7e\x86\xd1\x16\x4a\x44\xef\xa3\x64\x34\xcb\xb2\x85\x89\xcf\x26\x23\xcf\x54\x7c\x28\xd9\xca\xd8\x38\x63\x09\x12\x65\x2d\x41\xe2\xcc\x25\x08\xcb\xbe\x83\x4c\x4a\xac\x30\x7b\xf1\xa1\x64\x2f\x63\xe3\xec\x25\x48\x94\xbd\x04\x89\xb3\x97\x20\x62\x41\x3e\x43\x0e\xa6\xd6\x5e\xae\xcb\xbf\x80\xf8\x94\x43\xd7\xe5\xc8\x17\x0e\x1c\xfb\x88\xc6\x94\x23\xa0\x1c\x51\x28\x48\x96\x8b\x04\x27\xc8\x49\x07\xb6\x50\x7d\xd2\xc1\x16\x0a\x09\x8f\x7b\x7a\x7b\x85\xd0\x70\x3f\x44\x7b\x16\x2a\xb1\x87\x85\x73\x94\xbf\xc7\xe8\x81\xb1\x91\x72\x3d\x63\x28\xd2\x83\xce\x99\x0d\x4d\x5e\x75\x46\x1f\x39\x11\xc9\x69\x3d\xdf\xf3\x38\x7d\x60\x4b\x63\x97\x23\x10\x2b\x75\x40\x1f\x38\xca\xc4\x1f\x0c\x5d\xde\x18\x4f\xda\x03\xb6\xfa\xc8\x3b\xa3\x2e\x66\x88\xc4\x88\xda\xb7\x01\xe5\xa7\xe8\x78\xd0\xde\xcb\x41\x6e\x16\xbf\x47\x8e\x87\xcd\xe8\x3b\x4a\x05\x39\x89\x63\x3c\xa0\x86\xfb\x84\x3a\xe8\x1c\x41\x8b\x12\x9b\x17\x3a\x44\x68\x7c\x3a\x46\x84\xbd\x73\xe6\xe1\x94\x74\x06\xf4\x81\x51\x41\x4c\x6c\x4c\x90\x04\x3a\x26\xf7\x8c\xa7\x15\x9f\x93\x3a\x26\x96\xbb\xc7\x56\xbe\x88\x67\xe3\x42\xf0\x1b\x6f\x80\xdd\xa2\x28\x38\x2f\xf8\xdc\x37\xc6\x5b\xc1\x8b\xa1\x2a\x8f\xbc\x61\xf4\xcf\xfd\xa4\x7f\x0e\x02\xfe\xdd\x47\x5e\x8b\xb2\x0e\x5a\xcf\xbf\x95\x92\x65\x9c\x49\xf1\x16\x13\x4b\x70\x27\x92\x83\xcb\x17\xb1\xbb\x9e\xdb\xbb\xc7\x2e\xee\xd9\x28\x97\xff\x93\x83\x33\x80\x75\x54\x34\x6d\x4a\xd0\x7a\xbe\xe8\xfa\x3d\xcf\x81\xa6\xb7\xbe\xad\xe5\xac\x5c\x3e\xbf\x97\x05\x04\x2d\x6b\x9d\x87\xcb\xb5\x62\x3d\xaf\xe5\x46\xb9\x7c\x5e\x7b\xa3\x3f\x09\xea\xfb\x6c\xf3\x44\x65\xd9\x70\xad\xe7\xb5\xdf\xd3\x56\xd6\x8c\x79\xcd\x8c\xfa\x62\x76\x5b\xe5\x92\x0f\xfc\x71\xee\xd5\x0f\xa9\xa1\xe5\x26\xf3\x86\xd4\xd0\x72\x83\xa9\x86\xf1\x95\xf3\xb5\x36\x2d\xac\xf5\xcc\x56\xa9\x4d\x8f\x9a\xc6\xd9\xca\xdf\xdf\xa0\xb5\xb5\xe7\x6a\x6c\xc9\x1a\x0b\xb6\xf7\xb5\x56\x39\x1c\x84\xa8\xb6\x21\x63\xfd\x5a\xab\xab\xf6\x70\x4b\xad\xf3\xfe\x42\x74\xeb\xf7\x76\x72\x54\x61\x21\xd1\x28\xb5\x0d\x6b\xa7\xd6\x78\x6d\x4d\x50\x2e\x26\x5e\x32\x22\xab\xe7\x9f\xa4\x7c\xb4\x7c\xc2\x88\x20\x08\x71\x66\xc1\x1c\x92\xad\x56\xd4\x09\x33\x5a\xad\xc2\xff\xab\xd8\xf3\x88\x50\x23\x40\x5e\x54\x35\xa7\x72\x2f\xb9\xcf\xff\xca\x17\xb9\x58\x2e\xab\xe8\x2d\x58\x29\xde\xb5\xe9\xc1\x0a\xf3\x08\x25\xb3\xc5\x32\xe2\xfc\x7a\x58\x3a\x4b\xda\xf3\xfb\x6c\x9d\x87\xb6\x4d\x1f\x8e\xc9\xd8\xf7\x04\x7f\xa5\x4a\x3e\x8c\x9f\x3a\x66\x63\x77\x0f\x6d\x57\x8d\x60\xcc\xa5\x2a\x12\x45\xdf\x8c\x3f\x92\xf2\x13\xcf\xb9\xe5\xdb\x1e\xb6\xa4\x5c\x26\x3f\x3a\x68\xcc\xbd\x8f\x9c\xbd\x9c\x96\x7b\x7a\x6b\xda\xd0\x75\xc1\x40\xa8\x73\x1c\xdf\xf4\xa8\xc3\x35\x3c\xdf\xc4\xa4\xa5\x63\xd6\x3a\x37\x9c\xc2\x7d\xe4\x9d\x8a\x80\x75\x2f\xaf\x89\xb0\xd0\xaa\x54\x45\x9a\x32\xcd\xab\x9f\x3e\xab\x9f\x42\x6a\xf4\x90\x15\x87\xcb\xda\x56\x39\xdf\xc4\xc3\x7c\xe2\x22\xaf\xfa\x46\x17\x5f\x26\x1d\x8d\x29\x61\x39\xbf\x31\x34\xa5\x4f\xa3\x4f\xdf\x45\xa5\x0a\x6f\xbd\x92\x07\x34\x3d\x1f\xda\xa2\x3c\x25\x78\x0c\x1d\x17\x85\xb2\xab\x12\x1c\x2a\x94\x2f\x43\xce\x52\x89\x69\x61\x22\x43\xdb\xfe\xa8\x87\x9c\x6a\x58\xad\x1b\xcc\x26\xc1\x93\xeb\x41\x0f\x9b\xa0\x8f\x3c\xd0\xae\xb5\x0e\xa2\xe1\x07\x44\x8d\xe2\x6a\xa1\x93\x83\x8f\x71\xb4\xa3\x46\x1f\x5c\x1e\xb4\xbb\xc9\x78\x3a\x95\xbc\x76\x76\x9c\x00\x51\x14\x49\x09\x58\xe8\xa1\x33\x8e\x32\xac\xce\x6e\x9c\xa3\xa9\x42\xc9\x36\x29\xf1\x7e\xa2\x46\xf7\x7c\x8e\xcb\x38\x57\x8d\x13\xfc\x3c\x75\xe2\x68\x9c\xa8\x80\x60\xbe\xe3\x58\x4b\xc6\xba\x4a\x2c\xca\x7f\xb3\xaa\x48\x4d\xd7\x60\x13\xb0\x0d\x47\x28\x4e\x09\x9f\x44\x2f\x87\x3a\x46\xaf\x9a\x98\x69\xbc\xfd\xeb\x39\x0f\x3a\x7d\xe4\x49\x3d\xe0\xdb\x24\x08\xa3\x19\x61\x8c\xe0\x07\xf8\x47\x32\x9f\xbd\x7b\x8a\x2d\xa0\xbf\xa9\x56\x23\x3c\x15\x50\x39\x82\x84\xa7\x60\xb5\x5a\xf5\xfe\x4c\x66\x2c\x08\x54\x98\xf5\x1e\x5a\xf7\xf2\xf9\x39\xf3\xfe\x93\xfe\xb9\x9a\xa6\x1f\xe9\xf9\x9f\x8e\x97\x94\x5c\x43\x45\xf4\xd5\x43\xc4\x5a\x97\x18\x21\x91\x31\x2e\x01\x76\xa9\xc4\x47\x59\x0f\x2a\xf1\x53\x4d\x91\x8f\xe6\x2e\xf6\x42\x5c\x14\x0c\x6a\xdc\x05\x51\xf3\x43\x02\xcb\xdf\xd5\x7e\x5c\x5b\x4b\xc2\x15\xef\xa1\xbd\x9e\x2f\x7a\x0e\x1e\xad\xe7\x8b\x36\x22\x7d\x6f\x10\x76\x96\x8b\xbc\x4b\x68\xfb\x21\xed\xbc\xe1\xc8\xc7\xc9\xdc\x7e\x44\x50\xa7\xb3\xc8\x6b\x7a\xc8\x9b\xc9\x5a\x17\x15\xa5\xd0\xda\x5a\x66\x55\x45\x60\x35\x51\x2f\xe8\x79\xce\x7a\x6e\xcc\xc4\xc2\x01\xb5\xb9\xd9\x31\x6c\x53\xba\x62\x19\xe5\x68\x7a\x3e\xd9\xd9\x45\x21\xa5\x85\x39\x08\x31\xe4\xe9\x46\x28\x6e\xd7\x43\x2a\x99\x24\xf6\x37\xb7\xd8\xb6\x79\x4b\x65\x56\x2c\x80\xd1\xf3\xf5\x7c\xfe\x29\xae\x03\xa7\xb2\x52\x8b\x1e\x13\xc0\x3f\x19\x11\xda\x53\x27\x91\xf7\x99\x2b\xee\x9c\x6a\x2e\xf7\x96\xf1\x1a\x28\x21\x19\x45\x15\x4d\xd2\xfc\xb5\x35\x43\xf6\x95\xc8\x46\x0e\xd1\xba\xaa\x9f\xcf\x42\x2c\xae\x92\xce\x6b\x39\x2d\x97\xd7\x9c\xaa\x53\x74\x10\xef\xcb\x75\x45\xff\x5e\x14\x5a\xc3\xf5\x29\x92\x1b\x26\xcb\xe5\xf2\x71\x32\x8d\x85\x29\x01\x7f\x68\xff\x75\xff\xef\xff\xfd\xc1\xc2\x54\x5c\x29\xba\x63\x1b\x9b\x68\xdd\xd3\x8c\x7c\xe6\xda\xa1\x02\xe4\xf7\xd6\x33\x96\x8c\x67\xd7\x9e\x19\x13\x3e\x3d\x25\x9d\xb0\x02\x22\xc4\x73\x70\xbf\x8f\x9c\x08\x11\x52\x0b\x9f\xda\x6b\x9a\x4c\x79\x43\xa8\x87\x6f\x27\x82\x9c\x7e\xf3\x26\x63\xb4\x37\x28\xf2\xaf\xa2\x30\x56\x68\x72\x5d\xa6\x36\x57\x6a\xee\x91\xa7\xb0\x72\x22\xbd\x9c\x60\x6c\xc0\x51\x35\x66\xef\x42\x85\x69\x72\xe4\x45\xa0\x2c\x7a\x00\xdd\x6e\xa8\xe0\x5d\xcf\xaf\xad\xa1\xa2\xf7\x98\x82\x97\xfa\xdf\xbc\x16\xcf\x11\x19\x27\xa5\x57\x96\x70\xc4\x55\x4d\xee\x7a\x0b\x7a\x83\xa2\x43\x7d\x62\xad\xc7\x81\xf9\x3f\xb2\x13\xe6\xff\x6f\x46\x78\xd1\xe5\xaa\x25\x77\x3d\x42\xb1\xd0\x8c\xb7\x8e\xf2\x9c\x89\x4e\xce\xf9\x24\x43\x11\x8d\x22\x8f\x91\xf3\x2f\xf7\xf1\xe3\xc7\x8f\x85\x56\xab\xb0\xbf\x9f\x9b\x22\xac\x51\xa7\x69\xf3\xf1\x64\x1a\x47\xfe\x63\xe4\xbf\xdd\x52\x67\x9d\x61\x1d\xaa\xea\x6f\xd1\xbf\xa7\x61\xde\xa2\x8d\x8d\xbc\xb3\x31\x85\x4b\xa2\xfa\xe8\xf3\x6c\x14\xc9\x27\x13\xc8\x6a\x4d\x33\x68\xf9\xb7\x2a\xfa\x29\x68\xf3\x84\x6c\x17\x01\xa7\x9a\xec\xb0\xd9\x25\xbe\xfd\x45\xb3\x3e\xc4\xc6\x90\x3f\x8b\xe6\xf0\x52\x28\x91\x6a\x93\x1c\x42\x05\x4d\x44\xeb\x93\x9d\xa7\x28\xd0\xfe\x5c\xa6\x34\xa4\x66\xbc\xb7\x50\x37\xa5\x06\x5c\xd0\xec\x5c\x2e\x5d\xf1\xd9\xc3\xbf\x50\x37\xcf\xae\x3e\xb7\x10\x66\xd4\xfe\xe9\x46\x98\x3f\xd7\x95\x55\x05\xad\x7b\x45\xc1\x27\xe5\x13\x6b\xad\xe6\x54\xc9\x9f\x99\x8b\x33\xc9\x73\x45\x66\x42\x22\x8d\x97\x2c\x36\xd0\x45\xd7\xa3\xe3\xe3\xd1\x08\x59\x98\xb1\x9c\x0e\x1d\xc3\x3e\x14\x22\x90\xf6\xc6\x78\x4a\xca\x08\x92\xa3\xf3\xaa\x2a\x37\xf3\xed\x49\xb3\x34\x2f\xff\x94\x24\x55\x12\x36\x1e\x85\xa2\xf7\x98\x5e\xf7\xa7\x68\x58\x64\x7c\x9f\x15\x9d\xcb\xcd\x8c\x7c\xba\xc1\xee\x81\x90\xa2\xa4\x8f\x51\xe8\x33\xf0\x26\xe1\x1c\x10\x93\x05\x6f\xe0\xd0\x07\x40\xd0\x03\xe8\x4e\xc6\xe8\xc0\x71\x28\x1b\x3a\x99\x09\x40\x5f\xc7\xc8\xf4\x5c\x00\x81\x8b\x49\xdf\x46\xc0\x1c\x40\x07\x9a\x1e\x72\x80\xc8\x18\x30\xd4\x1e\x21\x8f\x31\x25\xd2\x41\x29\x74\x44\xca\x4d\x72\xa1\xe3\x4f\x21\xa2\xca\xea\xc4\x29\x62\x62\xa1\xaf\xa7\xb7\xeb\xb9\x8f\xb9\xfc\x5b\x9e\xa2\xb5\x68\x8a\x96\x4c\x61\x3d\x93\xc2\xa3\xdc\x79\xbe\x01\x5d\xb6\xd8\x44\xe9\x2d\x99\x7e\x90\xe3\x5e\x4c\xb9\xa3\xef\xcb\x67\x20\xf3\x19\x2d\x5a\xf3\x91\x4c\xe1\x2e\x9a\xc2\x95\x29\x60\x58\xd7\xda\xf7\xd5\x15\xe6\xf2\x29\x0f\xad\x37\xc6\x53\x34\x65\xe3\xe9\x2a\x97\x32\x39\x91\x58\x23\x43\x15\x8f\x1a\x3a\xca\x0c\x75\x73\x02\x0b\x04\xbb\x38\x33\xcb\x49\x66\xe2\x56\x66\xa8\xc5\xb2\x4c\xc9\x06\xf3\x04\xa9\x3c\x67\x2e\x49\xf5\xdb\x53\x84\xf4\x5c\xf1\x11\x26\x5e\x5b\x4b\x7c\x02\x4c\x5c\x0f\x12\x93\xa1\xc6\x29\xf7\x84\x59\x5b\x5b\x27\x09\xec\x26\x5a\x22\x45\x9e\x4b\x32\xd0\x1c\x24\xd7\x3b\x6d\x5d\xf5\xd8\x11\xf5\x73\x84\x33\x49\x44\x60\x51\x91\xe1\x4f\xcd\x5b\xd7\xf3\x45\x8f\x5e\x8c\xc7\x72\x94\xf2\x31\x84\xcb\x79\x42\x23\xaf\x2e\x72\x9f\x9c\xcf\x7f\x92\x4f\xe8\x33\x7f\xdb\x13\x9a\x1a\xc0\x02\x9e\xf2\x79\x8d\x3c\x25\x88\x2b\xca\x7f\x13\xee\x80\xd5\x6a\x35\xb9\x42\x30\x0e\x48\x70\x08\xe2\x59\xc4\x6e\x87\x89\xa9\xa8\x18\x52\xdd\x7c\x10\xbc\x91\x20\x6f\xa2\x50\x39\x24\xb2\x93\x25\x85\x47\xf9\x27\xce\x9b\x5c\x88\x55\x11\xe5\xbf\xe5\x26\x4c\xc2\xe4\x4e\x43\x55\xce\xc9\xe4\x9e\xa7\xfe\xc2\x73\x44\x13\xa4\x7e\x0f\xc5\x4a\x9f\x24\xf3\x23\xd7\x4d\xb6\x2c\x30\x99\x85\xc9\xfc\xac\xc8\xa4\xb8\x82\x22\xfd\x54\x4a\x0f\xc2\x19\xbe\x11\xfc\xba\x9e\xad\x0b\xd1\x44\x3c\x26\xeb\xe5\x4c\x3d\xca\x06\x8a\x56\xb9\x59\xda\x4c\xf0\x1f\x60\xe1\xfb\x5c\x3e\x54\x1d\x16\x6f\xb1\xed\xb1\x65\x50\x01\x29\x44\xf3\xc0\xfc\x94\x55\xca\xe7\x62\xec\x4f\x92\xcf\x87\xa2\x59\x9e\xd1\xf4\x63\xb2\xaf\xfa\x0f\xc4\x2e\x61\x6f\x22\x51\x31\x96\xfd\x54\xc8\x4f\xd9\x9c\xe5\x67\x91\xe9\x01\x59\x30\x4f\xd5\x59\x61\x7e\x96\xfb\xaa\x52\x6f\xa1\x7a\x72\x48\x25\xd3\xa3\x74\xf5\x9e\xcf\x4a\x55\x1c\x66\xe4\x24\x78\x72\xee\x1f\xc6\x35\xdb\xd2\xdb\x6e\x3d\x1f\x6b\xb6\x23\x6e\x3d\xb3\x1b\xd7\xd6\x72\x16\x9b\xda\x44\x32\xd7\xd3\x43\xe2\xcd\xcb\x4c\xed\x3f\x25\xaf\x37\x71\x66\x89\xa1\x98\x9b\x57\xe8\x9a\xc2\xc8\x18\x76\xeb\xe8\x96\x3a\x69\xe9\x29\x84\xd0\xc8\xdc\x6c\x84\x5b\x8b\xc8\xa6\x76\xcb\xe6\x6a\x26\xc0\xfc\x5c\xa6\x2d\xdd\x4a\xf3\x0a\xd3\xc2\xd8\x34\x7c\xb4\x3e\x31\x1a\x3b\x59\xcf\x2f\x32\x26\x7c\xa0\xd7\xd6\xd8\xca\xc4\x4a\x0a\x82\xdc\x48\xbe\xb8\xfc\x25\x9f\x35\x4e\x62\x1e\x2d\x32\x4e\x8b\xe4\x3f\x3d\x76\x0b\xe4\x9f\xa9\x0b\x9f\x5b\x50\xfe\x9b\x58\xcc\x44\x6e\x59\xeb\x4e\x76\xa6\xca\x6a\x24\x44\x51\x3e\x59\xbc\x07\x84\x08\x4f\xfe\x49\x17\x3a\x85\x4f\xc6\x67\x59\x61\x56\x8a\xce\x38\x5e\xb6\xa6\x44\x8d\x78\x92\x58\xf7\x94\xe6\xac\x51\x8a\xc1\x9d\x42\xcb\x24\xfc\x9f\xdc\x67\x57\xe8\x04\xd9\x4a\xb3\x3e\xa5\x29\x44\xf9\xfc\x1e\x9a\x9b\xc7\x3a\xca\x6b\xe8\xe9\x26\xf4\x66\x64\x35\x60\xbd\xe3\x69\x44\x73\x34\xaa\x61\xae\xee\x0e\x8d\x54\xb0\xfa\xe9\xb3\xe6\x56\xbf\x3d\x69\x66\x15\x15\x1f\x06\xd8\x1c\xbc\x65\x22\xb0\x07\x30\x01\xe3\x4f\xe6\xe7\x6a\x6e\x9c\xd3\xc6\xf9\x71\x71\x00\xdd\xd3\x07\xc2\xf8\x7e\xe4\x78\x93\x75\x2f\xbf\xb6\x96\x1b\xb3\xde\x1f\x7f\xf2\x3e\xaf\xad\xad\xc3\xe2\xd8\x77\x07\xeb\x5e\x5e\x0b\x2b\xe3\xad\x7b\x9a\xa1\xe7\xdf\x54\xab\xe6\xda\xda\x3a\x17\xed\xdf\xe8\xf9\x7c\x9c\x7d\x5a\x94\x13\xce\x0f\xf9\xa9\xe9\x20\x63\x32\xab\x90\xe1\xd7\x9b\x9d\x5a\xd4\xd2\xa9\x7a\x5c\x9f\xe4\xad\xe7\x40\x2e\xaf\x39\x21\x8b\x5f\xad\x56\x61\xf8\xba\xb6\x66\xb3\x66\x57\xab\xce\x27\x19\x5b\x60\xa3\xcf\x35\x03\x94\x8d\x3d\xa9\x46\x11\xa5\xb7\xe4\x3f\x55\xfd\x2d\x29\x14\x58\xb5\xdf\xac\xdb\x9f\x9c\x4f\xe4\xf3\x67\x4c\x80\x9b\xcf\x7f\xa3\x6c\x3e\xf6\x1c\x04\x87\x4f\xf8\x76\x9d\xe6\xbf\xe1\xea\xcc\xba\x85\x70\x4f\x78\x6d\x0d\x17\x4d\x68\xdb\xbc\x13\xf2\xdc\xb3\x98\x49\x5e\x49\x81\x0b\x15\xc7\x0e\x62\x8c\x41\xa4\x7d\xcf\xf3\xf1\xf6\xc7\x6c\xb4\xc7\x9f\xc2\xa1\xfc\x5c\xcd\x39\x39\xed\x36\xfa\x5c\x5b\x5b\x8f\x3f\x98\xc0\xbe\x70\xde\x9c\xfc\x1c\xe2\x7b\x44\x24\xed\x8d\x84\xcd\x6f\x4f\x9a\x50\x49\x48\x3e\x52\xa2\x5f\x02\xb9\xa4\x4d\xd4\xc9\xd4\x0b\xe7\xdf\xa2\x78\xb9\x61\x9c\xe5\xac\xe5\x93\x4d\x21\x86\x79\x6f\xde\x08\x2e\x94\x75\xa1\xbb\x4e\xf2\xd1\xe0\x11\xb5\xae\x92\xd6\x28\x75\x9d\x5b\x49\xc2\x19\x0e\x56\xc8\xf3\x65\x24\x35\xea\xdf\x92\x36\x5f\x39\xc0\xa2\x0d\x41\x90\x6b\x82\x66\x37\xa7\x09\x46\xfc\xed\x94\x2c\x52\x45\xb1\xba\x67\xfd\xbf\x9f\x3e\xfd\x7f\xff\xfd\xf4\xf9\xff\x3e\xe7\x83\xf5\xff\xfe\x37\xff\xe7\x7a\xb3\xdb\x09\x9a\xdd\xa0\xd9\xfc\x93\xfd\x02\xfb\x9b\xa1\x55\x9e\xf2\x7f\xf4\x93\xac\x74\xc4\xc4\x47\x26\x88\x50\x3f\xb8\xcf\xb9\xfd\xa2\x4d\x49\x9f\xf5\xb7\x28\x91\xd3\x16\xf4\x24\xd9\xb5\x84\x9d\x2c\x45\xec\x15\xf7\xcf\x3f\x67\x47\x85\x0c\x79\x7e\x4f\x6a\x61\xd5\x2c\xa3\xd5\x0b\xe5\xff\xad\x87\x8b\x4e\x66\xfc\xb4\xda\x24\x1b\x5e\x90\x9a\x69\x2d\xb4\x50\xcd\xc4\x06\xc2\x65\xa4\xbe\x7f\x1b\x61\x49\x09\xf8\x68\x5c\xfe\xfb\xa9\xf8\x7f\x7f\x7e\xfe\xa3\xcf\x75\xda\xaa\x64\xfb\x6f\x43\xcb\x12\xdc\x24\x8f\x3d\x6d\x51\x2c\xe5\xa7\x13\xb4\xe6\x25\x30\x32\x12\x58\xf3\x12\x48\x4d\xeb\xb2\xfc\x7d\x56\x22\x55\xc7\x27\x65\x9c\x94\x3d\x45\x4e\x38\x4d\xcf\x73\x3d\x50\x13\xba\x1e\xb7\x49\x5a\x59\xf2\x6d\xa8\x2a\x1b\x84\x86\xe5\x24\xf0\x31\xeb\xd8\x75\xc6\x90\xce\x8a\xca\xc8\x2c\x22\xd3\x4f\xea\x2a\x29\x58\x82\xb7\xd1\xaa\x1d\x2d\xbf\x28\x08\xd8\x0a\xc8\xde\xfe\xf4\xd6\xa5\xf1\x29\xa1\x93\xfa\xd3\x2b\x7a\x8f\xeb\x68\x7a\x26\x6b\x59\x1a\xf8\x54\x60\xe4\xf2\xa8\xcd\x50\xbf\xef\x79\x3f\x9c\xf5\x0c\xa5\x3f\x99\xa7\xf4\x27\x4f\xc2\x3d\x22\xd5\x87\x42\x54\x13\xa8\x2d\xa4\x32\xd1\x23\xa1\xcd\x2b\xe9\xda\x18\xea\xcb\x58\x37\x42\xa7\xef\xb3\xae\x96\xdd\x9f\x6d\x9d\x4a\x26\x67\xdc\x59\xae\x47\xa9\x8d\x20\x51\x95\x6d\x33\x14\x6c\x89\xb4\x60\x3d\xaf\x28\xda\xc2\x4c\x12\x8a\xb5\x79\x25\x57\xd1\x13\x8d\xd5\x93\xcf\x34\x21\xa5\xb4\x4c\xe4\xcb\x4d\x33\x6f\x38\x07\x93\xd2\x88\xe4\xb3\x5b\x21\x8b\xcd\x8b\x9e\x09\x3f\xe3\x8a\x03\x77\x40\x7d\xdb\x02\x3d\x04\x20\x01\xe1\x36\x23\xb6\x20\xce\x34\x03\xe7\xdf\xaa\xe6\xc3\xb7\xcf\xa9\x59\x34\x2f\xff\x2d\x52\x92\x90\x4f\xe8\xf3\xda\x1a\xfb\xbb\xee\xb1\x95\xf4\x49\x68\x25\x42\xa9\x8f\x30\xa6\x5a\xd7\x9e\x1d\xde\x29\x8b\x65\xb6\x91\xe5\x4f\x15\x49\xbf\x50\x4c\x9e\xb7\x7d\x24\xf4\xe9\x24\x32\x04\xb0\x4e\x8f\x77\x5b\x65\xa8\x6b\x99\xa8\xa1\x72\xce\x6b\x6b\x6f\xd6\x91\x3a\x46\x5c\x73\x93\x3d\x42\xc2\x5c\xa1\x8c\xc8\xc8\x77\x3d\x36\x1e\x94\x20\x40\x6f\xc1\x27\xee\x1f\x12\xaa\x72\x35\x30\xe2\x65\x00\xea\xf0\x3c\x3f\x47\x13\x2f\xa2\x8a\x11\x75\x51\x3a\x68\x9a\x43\x27\xf9\xa7\x5b\xb9\x16\x2f\x87\x53\x22\xd9\xdb\x6c\xbd\x35\x93\x93\x32\x30\x2c\x08\xde\x18\x7c\xc3\x6c\x76\x17\x84\x35\x51\x31\x2c\xd4\x5c\x53\x47\xe2\xda\xde\x2d\xb4\x5d\xa4\x74\x53\xac\xb0\xcb\xa7\x91\xef\x36\xe4\x6b\xa6\xbd\x73\x22\x99\x33\xc5\x41\x3d\x49\x42\xb5\x74\x77\xc8\x84\x33\x3a\x24\xbb\xc1\x04\x3d\x08\xa2\x39\xdd\xe2\xd9\x24\x45\x96\x54\x45\x4f\x19\xbb\x66\x96\xae\x78\x46\x1e\x4b\xb5\x21\xab\x0e\x4b\xb5\x27\x23\x83\x2a\x7a\x52\xd9\xba\xa5\xdb\xa4\x26\xe6\x94\xd2\x10\x28\x9b\xc2\xc6\x9a\xe3\xc0\xc9\x8c\xb9\x98\x28\x5f\x69\x0f\x01\x90\xa5\x62\x33\x32\x35\x13\xa7\x1a\xa6\x66\x51\xcd\x58\x6b\x67\x4e\x42\x2b\xa5\xad\x5a\x72\x40\xd5\xd4\x7f\x46\x14\x3c\xbd\x84\x24\xe1\xa6\xbc\x5f\xd4\x48\xde\x85\xde\x02\xa5\x65\x98\x5f\xdf\xe8\x19\x4b\xd5\xbc\x8e\x4f\x36\x3e\xa3\xe7\xe7\xcc\xa4\x44\x5d\x64\xe7\xa6\x65\x46\x6d\xb6\xbe\x6f\xba\xfe\x4f\x88\xfc\xc0\x50\xa8\x89\xe7\x8c\x84\x0a\x96\x1e\x08\x35\x6e\xde\x38\xcc\x6f\xc6\xf2\xc3\x90\x68\xf7\x52\xa3\x90\xa8\xc9\x82\x83\xf0\xcc\x2c\x7a\x9a\xd6\x45\x7e\x0f\x9d\x4b\xab\x33\x43\x9f\x1e\x3d\x9f\xe0\x08\x13\x9b\xab\x67\xf9\x3b\x4d\xe7\x36\xa7\xd3\x17\x26\x3a\x19\xcd\x7c\xa6\xeb\x17\xd0\xf2\x72\xb9\xde\xf2\x4d\xb4\x9e\x62\xc7\x44\xc3\xd6\xbd\x6a\x52\x57\x96\xff\xcf\x56\x10\x78\xff\xd6\x83\x00\xbb\x6d\xd8\x5e\xf7\xf2\x41\x50\x30\x18\x2b\x11\x4b\xc8\xdc\xb5\x47\xaa\xda\xd0\x53\x5e\xfb\xf4\x39\x5f\x74\xa9\xe3\x4d\x39\xbc\xc4\xfb\x30\x23\x3d\x6c\x86\xdf\x44\x5e\x7a\xbc\x78\x55\xfd\xad\x97\xe5\xf1\xe2\x6d\x6c\x08\x61\x0a\x55\x75\xae\xbd\x7b\x1b\x69\x75\x43\x9b\x81\x2a\xd7\x7d\xe6\x9e\xfe\x6f\x33\x3c\x7b\x94\x8d\x00\x5a\x99\xb7\x4a\x0c\x45\xae\xeb\x60\x64\x81\xb2\x01\xf8\x2e\x48\xe0\x51\x70\x8b\x89\x05\x20\xe0\x15\x04\xdc\x36\xf8\x16\x6d\x6c\x3c\xcd\x91\x3e\xbd\xcf\x9a\x97\x7f\x4a\xcd\xdd\x50\x39\xbf\xf4\x84\x0d\xd3\xfd\x99\x19\x2a\x59\xd2\xbd\xcc\xd8\x39\xf3\x59\x34\x79\x5e\x81\xd9\x13\x39\xe3\x40\x03\xc6\xe4\x11\xfa\x90\x0b\xd9\x61\xc1\x91\xf2\xaf\x2c\x8d\x71\x3e\x2f\x25\x06\x69\x09\x9e\xe2\x46\xdf\xa6\x4d\x3e\x99\x48\x22\xfb\x33\x0f\x1a\x5c\x64\x21\xd4\x03\x3c\x2b\x3e\x46\x31\x76\xec\x25\x59\xc3\xef\x37\xce\x3c\x5b\x8f\x64\xb9\x00\xbb\xa0\xc7\xb3\x4b\xc8\x5a\x32\x37\xa5\x5a\xde\x3c\x47\x9d\xb7\xd9\x83\xe3\xbd\x95\xa8\x42\xaa\xfa\x5b\x92\x85\x2a\x64\x63\x23\xff\x3d\x48\x98\xf0\x46\x63\x62\x8f\x34\x36\xa1\xe7\x7c\x58\x63\xfb\x53\x58\xeb\xc8\x14\x1c\xd9\xab\x22\x45\x91\xe2\x7c\x3c\x63\x0f\xdb\x94\xf7\x5e\xb8\x95\x2d\x8d\x57\xa2\x3f\x97\xc7\x2b\x91\x2e\x8d\x57\x22\x74\x16\x5e\x89\xd8\xef\xc4\x2b\x91\xf8\xd5\xe3\x55\xd8\x9f\x3f\x8c\x57\x0b\x5a\x2b\x9f\xad\xc6\x34\x5a\x41\x96\x5b\x0a\xab\xc2\x2d\xff\xdf\x89\x55\xe1\xd0\xfc\x5a\xac\x0a\x89\xcd\xf3\x68\x15\x19\x87\xa7\xd1\x4a\x12\xac\xb9\x78\x15\x6d\x81\x5d\x10\xa5\x14\x5f\xf4\xe5\xf9\xab\x38\xed\x9f\x33\x63\x66\xa0\x97\x02\x31\xcf\xc9\x5c\x01\x63\xc8\x34\x13\x7b\x50\x95\xe3\x8f\xd0\xb2\x4a\xfc\x11\x9a\xd6\x14\xee\xec\xa5\x02\xd0\x4b\x21\x93\xda\x93\xcb\x23\x54\x9a\xb5\x59\xa8\x90\x30\x53\xd7\x45\x16\xc3\x15\x2c\xa6\x1f\x80\xa6\x49\x1d\x8b\x89\xe0\x1e\x05\xd1\xbe\x26\xe0\x22\xcf\x1f\x0b\xde\x86\xdb\xdc\xdc\x69\x69\x4a\xe9\x6d\x4f\x9b\xbd\x6b\x41\x4e\xe2\xe4\x9e\x85\x20\xc8\x74\x68\xcd\xe5\xaa\x33\xf7\x71\x2c\xb7\x53\xe2\x29\xf4\x46\x5f\x76\x9e\x8a\x64\xe1\x28\x2a\xc6\xa9\x59\xf4\x48\x9e\x12\x02\xc4\x8b\x32\x56\x5a\x8e\xf5\x33\x1b\x55\x9b\x42\x0b\x59\xe0\xd6\xa1\x23\xa9\x98\x13\xd0\xee\x9b\xdc\x14\xcd\x11\x31\x55\xf4\x76\x21\x9e\x37\xc5\xbd\xce\x73\xc1\x4f\x13\x89\xe7\xdd\xf5\x17\x51\x89\xa9\xae\x54\xa9\x2d\x97\x8a\x86\x3e\xff\x14\xed\x3c\x5f\x76\x40\x64\xc2\xb7\x28\x16\x44\x10\x13\x44\xb4\x75\x21\x80\x70\x2b\xe1\xbf\x0d\x6e\x86\x8e\xcd\x50\xe9\xe4\x55\xf4\x14\x13\xe4\xd8\xad\xcf\xab\x7e\xe2\xa7\xd2\xc8\x53\x6a\xc4\xa1\x35\x39\x2d\x37\xe0\xe7\x64\xe4\xc4\x8e\x82\xdc\xe7\xb7\x4b\xd5\x39\x2e\x69\x96\x31\x21\x53\x3f\x9c\x3d\xc3\x94\x6a\x67\x19\x17\x68\xa6\xff\xae\xa2\xa2\x4b\x10\x3f\x2e\xa9\xc5\x1e\xa9\x28\x69\x6b\x9c\x31\xc7\x67\xd4\x20\x5d\x2c\xa0\xb7\xea\x32\xcb\x75\xe9\x39\x0d\xe4\xa6\xd7\xd5\x38\xc3\x2a\x7a\x92\x87\xef\x2c\x3d\x33\x64\xc2\xe5\x0c\x36\x51\x71\xcf\x59\x6a\xa6\x38\x17\x99\x52\x61\xe5\xde\xe8\x6f\x67\xc0\xa0\x45\x11\x83\x9f\x16\xb4\x8c\xbd\x67\x4a\x3f\xc4\x73\x58\xda\xe4\x23\xca\x8d\x3b\x21\x1e\x46\x8f\x86\x76\x9e\xd3\x29\x3b\x4f\x46\xc1\x9a\xb7\x30\x0d\x90\x07\x07\xfd\x50\x6b\x65\x26\x4b\x37\x38\x2a\xfd\x87\xda\x2c\x73\x59\xa2\xd9\x91\x41\x74\xe9\x19\x1e\xa5\x5c\x6e\x8a\xc7\x05\x2e\x67\x8d\x8c\xd2\x55\xd1\x53\x7c\x0c\xce\xf2\x14\x3b\x4a\xba\x5c\xb5\x95\x22\x97\xab\x77\x9c\x70\x71\xb4\x93\x27\xf6\x2c\xdd\x3a\x99\x70\x29\x2b\x48\x54\xda\x33\xa6\x0f\x7c\xbb\xce\x29\xf4\xa0\x18\xed\x86\x56\xfc\x52\x9e\xcd\x7b\xa6\x75\x70\x3d\xa2\xcb\x6a\xce\x31\x85\xd6\x72\x79\xc6\xec\xf9\x68\x9a\x1f\x91\xd9\xcb\xae\x9d\xe9\xaf\x91\x5d\xe7\x82\x31\x63\xd3\xba\x5c\xa8\x23\x17\xf0\xfc\x53\xe2\x58\xa5\xe5\x97\x03\x35\xf5\x92\x6b\x42\xa2\xe0\x39\xf4\x21\x9a\x8c\x61\x67\xa5\xa9\xbf\x9a\x4f\xb4\x49\x30\x92\x9f\xc2\xa3\x9f\x7e\x88\xfc\x85\x79\x2c\x4d\xfd\x64\xd9\x8b\x11\x3f\xe1\xa0\x9a\x45\xff\xc2\x7c\x18\xf9\xcb\xe8\xdf\x4c\xd8\x62\x74\xd2\xd5\xdc\xaa\xc5\x60\xcf\x2f\xcc\x4b\x15\xcd\xcf\xd5\x7a\xbe\x68\x71\x62\xdd\x4b\x17\x4d\xdd\x19\x73\x6e\x0a\x6c\x11\x92\xf7\x3c\x5d\x93\x67\x7a\x2d\x8d\x3e\x32\xe1\x72\x98\x13\x15\xb7\x1c\xc5\x96\xc9\xaa\xe8\x49\x39\x78\xec\x3b\x9c\x0c\xa2\xb4\xcb\x55\x5b\x2d\x74\xb9\x9a\x2b\x29\xab\xe8\x49\x08\xb3\xcb\x3b\x1c\xf1\x64\x4b\x3a\x1a\x89\xa2\x96\xf4\x2f\xe2\x89\x18\x93\x2d\x4e\x79\xf9\x96\x92\xa0\x89\x6f\xdb\x6c\xce\x08\x17\xdf\xef\x98\x33\x22\xe1\xd4\xe8\x8a\xe0\x2a\x7a\xe2\xe7\xc9\xc8\x0d\x8c\x0b\xb7\x55\xa4\x5a\xae\xa9\x3c\x4d\x15\x3d\xa5\x0f\xae\x59\xba\x51\xe9\x0c\x96\x1b\xa6\xa9\xe2\x97\x6b\x45\x3a\x79\x15\x3d\x29\xca\xc2\xef\x42\xea\x30\xed\xf2\x78\x2d\x0b\x5d\x1e\xb5\xc3\x94\xdc\x05\x45\x6e\x99\xe2\x8d\xfa\x0e\xb3\x6c\x22\xfd\x92\xae\x27\xc9\xb2\x97\x74\x3b\x49\x24\xae\xa2\xa7\xe9\x3d\x13\x4b\xb5\x24\x99\x9c\x37\x24\xda\x17\xf0\x6c\x53\x52\x65\xe7\x55\x7f\x3c\x17\x44\xf9\xa4\x1b\x91\x4c\xc6\x86\x23\x6b\x83\xc9\x77\xbb\x90\x24\x72\x59\xc0\x95\x24\x01\x3f\xcb\xa5\x24\x01\xb4\x88\x6b\x49\x22\xc1\x4b\xba\x98\x24\x3b\xe9\xbb\x5c\x4d\x92\x75\xf3\xa6\x14\xea\xa9\xfd\x4c\xdf\x37\x0c\x3c\xf5\x02\xdd\xcf\xe1\x66\x75\x3b\x8f\x5c\xa4\xbb\x85\xd3\xfa\x0b\x76\xb3\x68\xfc\xd2\x8e\x0c\x89\xea\x48\xdd\x64\x7a\x53\x45\xb6\x27\x4d\xaa\x09\xdf\xe9\x8b\x30\xf7\xf4\x8d\x6f\x52\x73\xfb\x9c\x2f\x02\xfa\xcc\x4f\x75\x9c\xf6\x45\x40\x9f\x95\xf3\x2c\xb5\x52\xa5\x5a\xad\x7a\x09\x5f\x84\x52\x65\xae\x2f\x82\x37\xdf\x17\x01\x7d\xd6\xd0\x94\x2f\x02\x22\x3f\x30\x1d\xd5\xc4\xcf\x7b\x33\x65\x4e\x46\x35\x6e\x01\x6f\xa6\x17\x9b\x8a\x89\x76\x2f\x3b\x13\x13\x95\x59\x70\x22\xce\x40\xa6\xd5\x4c\x94\x33\x51\x5a\x29\x16\x5e\x66\xd3\xbb\xcb\xb3\x0c\x85\x91\x09\x34\xb5\x27\x64\xfa\xd4\xcb\xf8\xa4\x33\x31\x97\x5e\xd8\x99\x3b\x6a\xdd\x3c\x87\xee\xe7\x5c\xb9\x93\xa7\xb4\x65\x38\x6f\xc7\x60\x17\xb2\x5b\x93\xae\xef\x4b\xf3\xe5\xa9\xe4\xdf\xc1\xda\x46\x89\xab\xe8\x69\xda\xb3\x7e\x79\x67\x8d\xa9\x2c\x66\x8c\xd6\xf3\x27\xa5\x4c\x67\xb5\xe4\x91\x29\xcf\xd5\xac\x8a\x9e\x9e\x9e\xf2\xeb\xb4\x08\x35\x58\x84\xa9\x3b\xd5\xc4\x40\xf8\xc4\x42\xb7\x98\x20\x4b\x31\xda\x7c\xf9\xe0\x23\x47\xd5\x9c\x84\xf5\xed\xa2\xd1\xd8\x77\xc1\x3e\x1d\x61\xe2\xbb\xa0\x4e\xa9\xe7\x7a\x0e\x1c\x57\xfe\xe5\x02\x07\xdd\xf9\xd8\x41\x6e\x98\xb8\x18\x3e\xa3\x29\x86\x89\x69\xfb\x16\xb2\xa4\x23\xd2\xbc\xbc\xde\xc3\x7b\xd8\x31\x1d\x3c\xf6\x8a\x82\xfa\xa9\x1b\xfa\xc4\xc5\x56\x61\x29\xb7\xa4\xf8\xe5\x8e\xbf\xc5\xbb\x57\x3f\xe9\x9f\xe5\x57\x98\xdc\xfb\xa4\x7f\xfe\x77\x69\x6d\xcd\xfb\x64\x7c\xfe\xf7\x6e\x10\x70\x83\xd4\x27\xfd\xf3\xda\xda\x2e\x7f\x33\x3e\xb3\xb8\xd2\xe7\x7f\x1b\x41\xc0\xc2\xff\x53\xad\x7c\x67\xe3\xa1\x07\x6c\x04\x5d\x4f\xb6\xfe\xbe\x5c\xd4\x8b\x3a\xe8\xf9\x2c\xdc\x75\x81\x37\x80\x04\xdc\x57\x58\x60\x2e\xff\xb4\x9e\xd7\x32\xfb\x5f\xa0\xdf\x77\x56\x41\x24\x2e\x7e\x71\x8b\xa0\x25\x5f\x5f\x60\x14\x58\xb7\x93\x6a\x98\xf9\x3d\x72\x5c\x4c\x49\xaa\x9b\x09\xeb\xe6\x6a\x69\x6d\x8d\xb0\x7e\x36\xb6\x83\x80\xf0\xce\x2c\xff\x68\x67\x46\x4d\x02\xf7\xa5\xa2\xb1\x3d\xdd\xa1\x65\xd1\xa1\x6f\xdf\x28\x9b\x56\x59\x85\xd1\xdc\x1b\x02\x73\x2e\x7f\x99\x8a\x29\x62\x0f\x71\xf4\xf9\x33\x6b\x23\x69\x88\xdd\x4f\x7b\x19\x91\x28\x7b\xe7\xb5\x2c\x10\x15\x95\x63\x65\xab\xd5\x6a\x14\xfe\x46\xbe\x17\xc7\x0e\xf5\x28\x4b\xf6\xa7\xac\xdd\x5e\x54\xa2\xa6\x5c\x7e\x95\xff\x16\x5d\x85\x16\x1e\x9d\xc8\xd6\x5a\x31\x48\xdc\x5d\x48\x75\x12\xfa\x26\xee\x32\xf2\x3e\x91\xcf\x6f\x9d\x22\x22\xfe\x08\x39\x8c\x17\xa8\xaa\x1f\x41\xf0\xc6\xd0\x1c\x56\xc3\x5b\xdc\xf7\x45\xfc\x1b\x5d\xcb\x09\xb5\x33\x26\xc0\x59\x5b\x5b\x77\x8a\x0f\x0e\xf6\xc2\xb8\xbc\x16\x6e\x04\x16\x33\x38\xda\x80\x8e\x34\xa7\x38\x44\x13\xcd\xc9\x3f\x85\xfb\xff\x23\x71\x71\x9d\xef\xb6\x8f\x4f\x87\x5d\x5b\x43\xeb\x5e\xdc\x68\x8d\xe4\x35\x87\x87\xf1\x43\xd4\x9e\x9e\xd6\xf3\xf1\xc5\x77\x31\xd1\x4a\xad\x7a\xb3\xf4\xcf\x0d\x48\x08\xf5\x80\x09\x6d\x1b\x40\x20\x4e\xf6\x85\x8c\xb4\xc6\xc2\xeb\x93\xe8\x19\x85\x2c\x3a\xa2\xb7\xe8\xf4\x45\x4e\xb8\x2a\x8e\x63\x51\xc3\xe0\xdc\xdb\x9b\x52\xd0\x9f\xff\xc5\xaf\x67\x12\xd7\x37\xd1\x0d\x79\x69\xd3\x93\x66\x4e\xdd\xd9\xb4\x81\xd5\xbb\x9a\x36\x70\xf2\x8e\x26\xf1\x9d\xbc\x9b\x69\x03\x27\xef\x64\xda\xc0\x33\xee\x62\xda\xc0\x1b\xca\x99\xb9\xe9\xbb\x97\x36\x70\xf2\xce\xa5\x0d\xac\xde\xb5\xb4\x81\xd5\x3b\x96\x36\xf0\x93\x66\xff\x93\xee\x56\xf2\x57\x77\x2b\x4d\xdd\xad\x34\x5e\xea\x6e\xa5\xdb\xea\xb7\x27\xcd\x62\x7f\x06\xaf\xe7\x5e\x25\x67\x75\xaf\xd2\xea\x5e\xa5\xd5\xbd\x4a\xab\x7b\x95\x56\xf7\x2a\xfd\xd8\xbd\x4a\x82\xa5\x7e\x4e\x91\xf1\x4f\xb8\x55\xe9\x97\xb7\xf4\x77\xdc\xa9\xf4\xfb\x86\xf3\x27\xdf\xa8\xf4\x5b\x46\xef\xe7\xdd\xa7\xf4\x33\x9b\xf3\x53\x6e\x53\xfa\xf5\x15\xfe\x81\xbb\x94\x7e\x6f\xef\x7e\xdf\x4d\x4a\xbf\xad\x83\x57\xf7\x28\xad\xee\x51\x5a\xe8\x1e\xa5\xb4\xde\x47\xd1\x57\xf5\x84\x1e\x47\x1c\x7a\xa3\xf5\x52\x76\xaa\xd5\xd5\x4a\xa9\xab\x95\xc2\x9e\xec\xc5\x5a\x32\x1e\x53\x4d\xa9\x3a\x57\xb7\x02\xad\x6e\x05\x7a\x5d\xb7\x02\x69\x89\x29\x2b\xf4\x8b\xea\xac\xcd\x20\x68\xf3\xef\x0a\x4a\x66\x28\xab\x59\x4d\x9d\xe8\xc5\x55\xe0\x31\x96\x67\xdd\x1f\xa4\xbd\xdc\xdd\x41\xeb\x4e\x26\xde\x71\x5d\x6a\x7e\x23\xa7\x29\x17\xfd\xcc\xb9\x26\x88\x01\xae\x6e\x09\xca\x38\xe7\xbd\xb7\xba\x25\xe8\xef\x76\x4b\x90\xb0\x9e\xe8\x6f\x69\x96\x77\x08\x95\xb7\x04\x6d\xa8\xf5\xa6\x73\xee\x87\xd9\x48\xd6\x23\xc3\xfa\xfe\x0f\xbf\x15\x28\x0b\x05\x52\x6d\x7a\xc1\x5b\x81\xb2\x4a\xfb\xae\x5b\x81\x36\x7e\xf1\x7d\x40\xbd\xe7\xee\x03\x4a\xae\x1e\xc2\xce\x16\xaf\x1d\xd1\xca\xf1\x1b\xee\x08\x4a\xd6\x2c\xe6\x7c\x13\xb5\x9b\x75\x73\xd0\x40\xf3\xd2\x6d\x53\x68\x59\x75\x4a\x90\x88\xef\x13\x72\x7e\xfa\x7d\x42\xff\x3f\x7b\xff\xde\xe5\xb6\x6d\x34\x8e\xe3\xff\xff\x5e\x85\x84\xc6\x0a\x61\x41\xb2\xe4\x26\x69\x4a\x99\xd6\x71\x1d\xa7\xf1\xaf\x59\xdb\x4f\xbc\x69\x93\x23\xeb\xf1\x87\x22\xa1\x15\x6b\x8a\x54\x49\x68\xbd\xca\x8a\xef\xfd\x7b\x30\xb8\x10\xe0\x45\x97\xb5\x73\xeb\x93\x9c\x1c\xaf\x88\xcb\x60\x00\x0c\x06\x83\xc1\x60\xc6\x46\x4b\x7b\xe9\xf5\xcc\x9b\xf3\x3f\xa2\x0c\xfd\x11\x65\xe8\x58\x94\xa1\x46\xf2\x6e\x20\x6d\xb5\x41\xde\x39\xf6\x50\xad\xa1\xaf\x2a\x32\xeb\xc7\x8a\x48\x64\x37\x64\x1d\x52\x4e\x3a\xd8\x61\xf2\x2b\x47\x28\x12\x76\x13\x62\x6b\xeb\xb7\x06\x26\xea\x97\x01\x89\x4e\x8f\x47\x64\x8f\x8d\xc1\xe9\x2d\xbe\xa1\xa3\x14\x2d\x7e\xe6\x28\x45\x36\x3a\xa5\x69\xa3\x85\xcd\x39\xb1\x8b\x16\x77\x8e\x5d\x54\x39\x00\xc9\x57\xac\x16\x22\xf6\xa1\xea\xb7\x1e\xd1\xa8\x1f\x1f\x0f\x65\xa4\x9f\x19\x56\x77\x93\x4a\x0c\x1d\xaf\x6e\x8f\x75\xe7\xf8\x46\xf5\xa6\xcc\x08\x3b\xa7\xb5\x74\x52\xd4\xa3\xf6\x3e\x09\x75\xd3\x59\x7d\x6a\x8c\x60\xd4\xda\x95\x33\x1a\x38\x14\x21\xa9\x0a\x1f\x0e\x27\x9e\x69\xef\xf5\x47\xdc\xa4\xf3\x3d\x91\xfd\x11\x37\xe9\x57\x8e\x9b\x24\xf6\xb7\x5f\x22\x6e\x52\x56\xc6\x4d\xca\x1a\xe2\x26\xd9\xeb\xab\xf2\xba\xae\xc1\x04\xf5\xb4\x68\x4a\xd9\xc7\x8a\xa6\x64\xa3\x27\x8d\x11\xbd\xba\xbd\x36\xe8\xbb\x55\xb0\x09\x92\xa9\x1f\xa9\xfa\x11\xa9\x1f\x6d\x91\x97\x92\x4e\x94\x74\x96\x2a\xf2\xd2\x12\x2f\xab\x61\x8f\x12\x1d\x79\x69\x39\x4b\x8c\xc8\x4b\x89\x11\x79\x29\xb1\x22\x2f\x25\x46\xe4\xa5\xe4\x63\x44\x5e\x4a\xce\x8b\xbc\x04\x58\xa6\x5e\x62\xd8\xae\xe3\xa6\xc0\x4b\x5b\x11\x78\x29\x9d\xa5\x46\xe0\x25\xd0\xb5\x44\x9c\x76\x32\x2f\x2d\xe3\x2e\x65\x8f\xbd\xd1\x24\x53\x71\x97\xb6\xb3\x74\x96\xe9\xb8\x4b\x91\x15\x77\x29\xc2\xb7\xac\x2d\xee\x52\xa2\xe3\x2e\x31\xce\xaa\xee\x14\x77\xa9\x46\x19\xdb\x8d\x45\x17\x4b\x3b\x1a\x53\x68\x46\x63\x0a\xef\x14\x8d\xa9\xb2\x15\xd9\x1e\x9e\x1b\x8e\xfa\xa7\x45\x68\x12\x77\xad\x3f\x7f\x7c\xa6\x36\xec\x2b\xfb\xb4\x81\xfd\xc7\x89\xd9\x54\x6d\xd7\xbc\xfc\xa8\x9e\x45\xfe\x88\xe3\xf4\x47\x1c\xa7\xff\xdb\x71\x9c\x6a\xba\x3a\x3b\x18\x53\xab\xae\x20\x3c\x29\xba\xd3\x11\xe8\x50\xee\x70\x13\x65\xcc\x27\x0b\x96\xde\xd8\x1b\xb6\x66\xb1\xf1\x6a\x5d\x42\x73\x40\xa8\xac\x25\x20\x54\xf6\xb3\x06\x84\xca\x7e\xae\x80\x50\xec\xd0\xfd\x0e\xb3\xc7\x4e\xbe\xe6\x68\x19\xf6\x23\x61\xa2\x2c\x48\x95\xd0\x4b\x15\x35\xe8\xef\x32\x78\x94\xd5\xbf\xb4\x41\x6f\xfd\x7b\x0f\x29\x55\xde\x27\x7f\x60\x40\x29\x6b\xa4\x2a\x0a\x24\xf9\xae\x89\x79\xec\xb7\x14\x66\x8a\x9d\x15\x66\x2a\xfb\x7d\x85\x99\xaa\xde\x9a\xc8\xc8\x4c\x77\x5e\x93\xbf\x99\xe0\x53\x7d\xfa\x11\x82\x4e\xd9\x0c\xb0\x76\x99\xf4\xbb\x08\x45\x55\x59\x70\xf5\x90\x4e\x77\xee\xce\x6f\x34\x40\x95\xd5\x61\x2b\xd4\xd3\x9d\x7b\xfa\x3b\x0f\x5b\x65\x93\x40\xb3\xb6\xf8\x8f\x60\x56\xbf\x66\x30\x2b\x9b\x66\x1b\x95\xec\x7f\x84\xb8\xfa\x95\x42\x5c\x55\x19\x68\x35\x8a\xd3\x87\xf0\xcf\x3f\x02\x5f\xfd\xa6\x03\x5f\x89\x93\xe1\xa1\xc0\x57\xa6\xbb\x81\x8f\x14\xf7\x2a\x39\x27\xee\x55\x72\x87\xb8\x57\x16\x41\xab\xf0\x45\x77\xa6\xe2\xff\xc2\x68\x58\xa6\xbd\xc1\xcf\x1f\x0b\xab\x4f\x7f\x53\x31\xb0\xfa\x87\xc2\xf4\x1c\x8c\x7d\x65\xb8\xdd\xa8\xaf\x96\xff\x23\xb1\xaf\xec\xb5\x25\x83\x18\xdd\x7d\x6d\xfd\xf7\x45\xc4\xfa\x18\x6b\xeb\xf4\x78\x58\xcd\x6b\xeb\x57\x8a\x83\x75\xd6\xca\xb2\xe2\x5f\xfd\x52\x2b\xeb\x37\x1b\xff\xca\x96\xc1\x8c\xf8\x47\x77\x17\xbe\xfe\x5b\xa2\x62\x7d\x84\x05\x75\x66\x4c\xac\x3e\xfd\x23\x16\xd6\xa9\xb1\xb0\x2c\xc2\x95\x01\xa6\xee\x4c\xb3\x46\x84\xac\xec\x4e\x11\xb2\xfa\xb4\x7f\x5a\x68\xac\x43\x91\xb1\x8e\x0a\xc5\x15\xf9\xf6\xb7\x1b\x19\xcb\x9a\x1c\x1d\xae\xea\xce\xd3\xf3\xf1\xe2\x65\x59\x88\x19\x21\x9b\xea\xb7\x56\x7f\xc4\xd0\xfa\xa8\x31\xb4\xfa\x56\xf0\xac\x43\xb1\xb3\xac\x29\xd2\xb1\xa7\xee\x4c\x3b\xff\x1d\x11\xb5\xec\x6b\xbe\xe0\xae\x97\x60\xbf\xdf\x38\x5b\x95\x1b\x53\xe1\x55\xea\xe3\x8c\xc1\xef\x2f\xfa\x56\x95\x8b\xc9\x08\x57\x77\x5e\x23\xbf\x62\x4c\x2e\x7b\xa7\x28\x83\x5e\xdd\x7d\xaf\xf8\x3d\x44\xea\xb2\x7a\xad\xa3\x51\xdd\xb9\xcf\xbf\x48\xfc\xae\xc5\x47\x8f\xdf\xd5\x5f\x34\x06\xee\xea\x97\x81\xbb\xee\x1a\xb7\xab\x19\xd7\x73\xe2\x76\xd9\xbb\x90\x15\x03\xeb\xee\x5b\xd1\x6f\x3e\x9a\x97\xd5\x6b\xe9\x7d\xec\xe3\x30\xd9\x3f\x62\x7c\xfd\x11\xe3\xeb\x64\x8e\xa8\x43\x69\xdd\x79\xa9\xfd\x5a\x91\xbf\x2a\x26\x1f\x65\x5c\xad\x0f\xb0\xfb\xf8\x95\xe3\x81\xd9\xa2\xa7\x08\xbe\x75\x77\xcb\xb2\x5f\x3c\x4a\x98\xcd\xc8\xf9\x5a\xa9\xf9\x08\xa9\xc6\x0e\xab\xd0\xa2\x0c\xfc\xf5\x01\xb4\x78\x2c\xa2\x58\x45\x09\xb7\xd8\xd6\xce\xca\xbf\x4c\x9c\x31\x0b\x8f\x5a\xd8\xae\x3b\x0f\xc0\x6f\x2d\xfa\x58\x8d\xd7\xa8\xd8\x5e\x1f\xc4\x6e\x7e\xd5\x98\x64\x35\xe3\x3f\x33\xce\xd7\x07\xdc\xa3\xff\x66\x22\x95\x59\x1d\x3c\xf0\x4a\xe9\xf7\x17\xbf\xac\xd1\x86\xc8\x0e\xb2\xf5\xc1\xb6\x44\x7f\x44\x35\xfb\xc0\xa8\x66\x8d\x93\x54\x7f\x39\xf3\x47\xac\xb3\xdf\x47\xac\xb3\xa3\xd7\x7e\xda\xfc\x24\x3b\x6c\x7e\x92\xb4\x05\x98\x4a\xea\x01\xa6\xb2\x73\x02\x4c\x65\x87\xcd\x4f\x92\x39\x49\x0e\x9b\x9f\xd0\xc6\x57\xd8\x7f\x04\x40\xfb\x3d\x04\x40\xfb\x3f\x40\x9e\xfa\xea\xfa\xec\xcd\xfb\xd7\x88\x8a\x76\xe7\xb7\x07\xbf\x5a\x54\xb4\xba\x28\x5f\x86\x29\xbb\xf3\xd9\xe2\xe3\xc6\x4a\xb3\x2d\x7a\xea\xb1\xc5\xee\x6e\xdc\xf3\xfb\x8a\xa0\x46\x98\xb3\x20\xf0\x06\x65\x76\xfb\x8e\xee\x5c\xf4\xe2\xc9\xc5\x33\x44\xae\x68\x83\xbf\xdf\x4e\x5a\x14\x44\x94\x82\xb8\x3b\xff\x78\xf6\x63\x4b\xc9\x6a\x70\x20\x5d\xef\xd9\x3f\x9f\xbd\xb8\x3c\x50\xb1\x13\xd9\x4d\x3c\x79\xf5\xfc\x50\x33\x65\xa8\x9f\xb2\x9a\xcf\x28\x3c\x2a\xcc\x40\x03\xdb\xd6\x4e\xac\x2b\x68\x65\x6d\x5b\xd1\x4d\x89\xfd\x35\x4d\x58\x5b\xb1\x40\x17\x13\x41\x1b\xd2\xac\xad\xa4\x5f\x22\xab\x82\x2d\x34\x17\x5c\x15\x24\x37\x33\x28\xbe\x5d\x79\x54\xd7\x7e\x1a\xfb\x79\xfe\xc2\x5f\xd3\xb6\xfa\x79\x51\xcc\x31\x59\x14\x0e\x2e\x1c\x11\xb3\x8d\xc8\xe8\x6b\x46\x30\x31\xa6\x62\x42\xb1\xe1\x32\x99\x65\x43\x4e\x00\x73\x12\x79\x33\xc4\xd2\x0d\x22\x68\x91\x32\x96\xae\x11\x11\x01\x1b\xe6\xc4\xf7\x66\x32\x38\x90\x0a\x08\xa4\x72\x72\x6f\x56\x86\x8f\xb0\x6b\xcf\x49\x50\xbb\xe6\x4e\x3c\x6a\x39\xf2\x45\x58\x7b\x4c\x50\xef\x35\x93\xfd\x1e\xdc\x39\x09\x87\xae\xab\x8c\x2e\x11\xde\xef\x11\x22\x89\xf7\xe0\x7f\xff\x34\xf3\x07\x3f\xcd\x1f\x44\x43\x46\x73\xe6\x24\x78\x9a\x80\xab\x3a\x0c\x4f\xcc\x9c\xd4\xe3\x69\xea\x2d\xf8\x7e\x9f\x8a\xb6\xb2\xa1\x22\x5d\xbc\xdf\x33\x43\xa6\x48\x95\xef\x29\x61\xc7\x85\xe5\x27\x26\x69\x41\xe2\x12\xf7\xd4\xf0\xf5\x1c\x58\xbe\x9e\x03\x61\xb4\x93\xd5\x5f\xbe\x75\x4d\x8e\xf6\x1d\x5d\xd2\x8c\x26\x81\xbe\xc7\x5b\x45\x79\x67\xe5\xe7\xc9\xa7\x9c\x2d\xd3\xa4\x13\x25\x11\x8b\xfc\x38\xca\x69\xd8\x19\x74\xf2\xed\x86\x66\x0e\xb6\x4a\x04\x7e\x1c\xd3\x10\x29\x17\xe8\x5d\xb6\xdf\x23\xf9\xde\xcf\xd0\xaf\x9a\xde\x1a\x8c\xe4\x29\x75\x59\x21\x30\x4e\x4b\xdf\x07\x84\xe3\xaa\x7d\xaa\x67\xc2\xf8\xc2\xc1\x24\xab\xc5\x38\xd3\xb1\x15\x9b\x80\x97\x0e\xf5\x9a\x39\xda\x6b\xde\x1b\xce\xc4\x32\x9a\xe7\x7c\x08\x61\x37\xa2\x11\x5b\xd1\x8c\x6f\x4a\xbc\x36\xdf\x82\xca\x28\x66\x04\xac\x5a\x50\x5f\xb5\x80\x27\xb4\x64\xdc\x9e\x7c\xf7\x1f\x64\x14\x9c\x16\xf4\x7a\x66\xb8\xb5\x5b\x23\x1e\x9d\x7b\x0b\x57\x12\x2e\x25\x65\x4c\x38\xb7\x3b\x26\x2a\xe0\x9b\x08\xae\x54\x06\x87\x73\xbb\xa3\xa2\xc0\x84\xf5\x7a\x8e\x6c\x23\xa7\xec\x95\x02\xfd\x72\x39\x6d\x4c\x85\xc1\x71\xe9\xf0\xed\x5b\xc0\xe2\xed\x5b\x8f\xe1\xc2\x09\x48\x8a\x49\x50\xf5\x43\xe0\x55\x9c\xa9\x00\xab\x56\x1e\xba\x56\x7e\x0e\x8b\x5b\xba\x86\x1c\x5c\x65\xe9\x76\x83\xb0\xed\xa7\xc0\x76\x48\x6d\xa8\x2d\x84\x96\x1c\xe1\x09\xbc\x73\xb6\x1c\x33\x97\xde\xc0\x1b\x60\x1c\x0b\xf0\x26\x85\xeb\x12\x06\x67\x45\x41\xe5\x51\x77\xc9\x7f\x2f\xe9\x7a\x13\x57\x9e\x8d\x4b\xfc\x1d\xf4\x88\xad\xa8\x1f\x3e\x46\x78\xe8\x6f\x36\x70\x63\xc2\xd3\xb2\x6a\xc2\x0a\x12\xc2\x50\x8e\xc6\x26\xa3\xd7\x3c\x01\xd8\x81\xe1\xbc\x1e\x11\xa4\xc2\x4d\xd9\x00\xf2\x8d\x9f\x58\x20\x1a\x0c\x01\x86\xaa\x2a\xc6\x87\x1b\x17\x7e\xbd\x84\x8f\xc5\x36\x2c\xa0\xcc\x6b\xbb\x48\x90\xc6\x1c\x0f\x44\x0e\x5c\x87\x4d\xd1\x17\xc8\x45\x9f\xa3\xc3\x28\x24\xf4\x86\xb5\xb4\xac\xb2\xce\xec\x3b\xaf\x86\x31\xc6\x24\x11\xb3\xb2\x48\xc3\xdd\xd1\x59\x11\xf3\x76\x46\xdf\xbe\x44\x2e\xfa\x0b\xc2\x9a\xc3\xcc\x38\x98\x30\xba\xb6\x7b\x67\x38\x4f\x83\xe8\x44\x76\xa3\x7c\x59\xda\xe5\x21\xa9\x03\xff\x0e\xf2\x75\x59\x9c\xda\x15\x65\x97\x30\x67\xed\x87\x5b\x95\xb1\xdf\x4e\x6a\x77\x10\xa4\x49\x48\x93\x9c\x33\x62\xdd\xb0\x92\xe7\x75\x4a\xa2\x53\x8e\xb7\x2e\x02\xce\xfd\x4a\x8d\xab\x28\x77\x3f\x4f\xf3\xf3\x3a\x9f\xb8\x8c\xd6\x4a\x4e\xf3\xa3\xe4\x08\xaf\xe0\x14\xa8\x28\x14\x7e\x67\xe5\xef\xc9\x01\xff\x98\xe0\xd1\xa7\x4e\xb9\x65\x82\xaf\x29\xf9\x96\x4b\x17\x2e\xfa\x13\xc4\x37\x84\xe3\xb6\x8b\x06\x63\x44\x58\xc4\x62\xea\x36\x5b\xcd\x0c\xad\xe0\x66\x85\x39\x4e\x0b\x96\xb4\x2c\x54\xab\xce\x5d\xd8\xd5\x76\x23\x16\xec\xc1\x8e\xd5\x20\xa1\x92\x95\x0f\xc0\x8e\x50\xf5\x5b\xa0\xc7\x73\x07\x9a\xb3\x23\x17\x6c\x0d\xf3\x23\xdd\x57\x01\xdf\x8a\xe6\x9e\xe6\xab\xf4\xbd\xec\x24\xc6\x24\xfb\x39\x27\xc2\x0a\x23\x77\xe2\x44\x58\x75\xee\x32\x11\x61\xfa\x3e\xc1\x58\x3b\x8b\xac\x78\x61\xd5\x86\xf2\x27\x91\xa4\xc6\x37\x57\x87\x33\xd4\x32\xc7\x4d\x25\x87\x2b\xb6\x8e\x1d\xe4\xa2\x96\x71\x6e\x84\x8e\xc9\x2f\xb3\x36\x44\xb0\xbd\x73\x57\x87\xa8\xf5\xeb\xac\x0f\x69\x60\x7b\x64\x85\x48\xb7\xf7\x27\xac\x91\x72\x04\x5a\x56\x89\xee\xec\x2f\xb6\x4e\xce\x9a\x94\x4a\xad\x8f\xbc\x56\xf2\xe6\xb5\xb2\xfe\xbf\xb8\x56\x44\xe4\xc8\x73\xd7\x8a\xa8\xf5\xeb\xac\x15\x11\xc2\xe1\xd8\x5a\x91\x81\x1e\x4e\x58\x2b\xe5\x08\xb4\xac\x15\xdd\xd9\x5f\x6c\xad\x9c\x35\x29\x95\x5a\x1f\x61\xad\x94\x2e\xd1\xf6\xfb\x0f\x5c\x0f\x65\x82\x38\x23\xda\xd5\x17\x2c\xe9\x2c\x58\x32\xd8\x64\xd1\xda\xcf\x76\x95\x39\x95\x3d\x74\xed\x38\x61\xe7\x0c\xa8\x59\xb1\x68\x9b\xbe\x96\xe5\xd7\x28\xbf\x1a\x64\xa8\x23\x9f\xdd\x51\x7c\x9d\x51\x92\x90\x6c\x8e\xf1\x21\x49\xf5\xb0\x94\x7a\x08\xbd\x55\x5d\xc4\x38\x05\x3b\x25\xf4\x1e\x02\xbd\x6e\xe2\xc9\xa7\x01\xcf\x8e\x02\xcf\x9b\x88\xf8\x34\xe0\xa9\x57\x7a\x84\x6b\x16\xf6\x1d\x3c\x3f\x2c\xbc\xa7\xe2\xe9\x3f\x6d\x13\xb0\x52\xed\x04\xb5\x79\x53\x91\xf9\x19\x28\xf1\x6a\xd3\x2a\x42\xdf\xd6\xe7\x72\x36\xaf\x5f\xc9\xd5\xcc\x2d\x4b\xbf\x04\x77\xe3\x3c\xb5\x35\x05\x2f\x7c\x8e\x2c\x9f\xd0\xdf\x15\xe7\xb3\x13\xa8\x07\xec\xa4\x72\xf3\x57\x1a\x8f\xab\x27\x57\x32\x28\x80\x83\x8d\x04\x19\xa0\x4a\xaa\x6c\x2b\x3e\x6e\x27\x32\x7c\x7a\xcd\x25\xaf\xb2\x96\x9e\x3a\x49\x35\x80\x86\xea\x4f\x19\xe7\x98\x64\x5e\x23\x1f\xf4\x19\xc5\xee\x31\x00\x1c\xbf\x16\x00\x1c\x37\xf0\xa6\xfa\x31\x27\x0a\x78\x98\x0c\x09\x2e\xe6\x2b\x39\x32\x29\x19\x1f\xfc\xa2\xf1\xb6\xa8\x66\x4b\xfb\x91\xe9\x0a\x6c\x0e\x8f\xd0\x15\x94\xb9\x03\x5d\x41\x3d\x43\xa4\x6b\xb5\xe5\xfd\xe8\x7d\x4a\x73\x7a\xb4\x4f\x69\x4e\xef\xd4\xa7\x34\xa7\xd0\x27\x4b\x77\x8a\x90\x7b\xee\x86\x72\x92\x36\x8d\x37\xd5\xc0\x99\xce\xdb\x66\x16\x69\xca\x72\x96\xf9\x9b\x81\xad\xb1\x1d\x08\xc3\xe7\x4e\x98\xa5\x1b\x2e\x52\x0c\xd6\x34\xd9\xa2\xd6\x2d\xc5\x8a\x9a\xaa\x10\x56\x0c\xbc\xae\xd5\x75\x4e\xd9\x3f\x1a\x20\xd5\x77\x53\xb8\x64\x01\x48\xdb\xd8\x06\x14\x47\x39\x1b\x6c\x93\x9c\xed\xe0\xbe\x83\x44\x50\x2a\x8e\x0e\xe9\x65\xfb\x2d\x4f\xe2\xa6\x48\x3d\x47\x4e\x13\xa9\xe2\x46\x2e\x32\xf5\xad\x1a\x43\xb1\x31\x38\xb8\xa2\x5a\xb2\xad\x7b\x39\x51\x67\x74\x9d\x5e\x53\x35\x7e\x95\x61\xae\xc8\x6e\xbc\x7c\x89\xf3\x36\xa7\xec\x3d\x4d\xd8\x6e\x09\xaa\x98\x96\xfd\xab\x7b\x10\xc6\xfb\x08\x22\x1b\x56\xdf\x9b\x9e\xc1\xd4\xa7\x0e\x6d\xd9\xf6\x17\x39\xc2\xe2\x0a\xaf\xc6\xd9\xab\x21\xe3\x01\x29\x31\x84\x51\xe5\x98\x54\xa3\x8c\x2c\x7d\x8f\x0c\xfd\x60\x99\x11\xa4\xf1\x60\x1d\x0e\xbe\x30\xe6\x23\x6b\xce\xc6\xfa\x4e\xb1\x1e\x9a\xa9\x86\x99\xbe\x8e\x3c\x5a\x76\xbf\xb7\x7a\x81\x5d\xe7\xd4\xde\xa7\x46\xbd\xda\x80\xa7\xe6\x70\x54\x08\xb7\x99\x4e\xeb\x93\xa4\xdf\x83\x02\xbd\x9e\x5d\xbf\xd7\x3b\xba\x47\x23\x7e\x42\x5b\x59\x73\xc3\xc7\x59\x0d\xde\x5d\x07\x41\xb5\xff\x41\x83\x20\x46\xf2\xee\x83\xa0\x66\xe2\xf8\x20\xc0\x08\x08\xe8\x92\x02\x0d\x62\x3b\x73\x0c\x34\x31\xa5\x35\x06\x0f\x2e\xa9\x9b\x2e\xc3\x65\x54\x1f\x5f\xfd\x1d\x8a\xc5\x28\xcc\x86\x48\xe6\x25\x65\xe3\x82\xb3\xbf\x4a\xf3\x88\x7f\x47\xc9\xd5\xf0\x9a\x66\x2c\x0a\xfc\x98\xa4\x87\xcb\xad\xd2\x2c\xfa\x29\x4d\x98\x1f\x9b\x51\x09\x9c\xa4\xbc\xd5\xeb\xf5\x8c\x0f\xb5\x01\x1a\x49\x6e\xa2\xaf\x0d\xf1\x70\x23\x41\x3b\x98\xe4\x77\x87\x92\x2e\x97\x39\x65\xd2\x13\x6b\x0d\x7b\x3f\xe3\x85\xa2\x86\x7e\x41\x4e\xc9\x4e\x64\x20\xf1\x09\x44\x07\x14\xa0\x1a\xa2\x01\x0b\x48\x2a\x03\x5c\xbb\x94\x75\x87\x1b\x5f\x3c\x29\x07\x20\xb7\x36\x3e\x82\xf1\x63\x23\x16\x85\x63\xc3\xaa\x20\x82\x27\x66\x36\x31\x4a\x06\xab\x28\x0e\x33\x9a\x40\xe8\xa0\x2c\x67\x0e\xae\x22\x52\x44\x4b\x47\xd8\x55\x78\x9e\x97\xf5\x7a\x4e\xe6\x71\x9a\xdb\xf4\xc7\xc3\xcf\xef\xab\x52\xc3\x15\x8d\xae\x56\xcc\xc1\x8f\x3d\xe6\xbc\x8f\x92\x30\x7d\x8f\x75\x5a\xbf\x4c\xca\x83\x2c\x8d\xe3\xcb\x74\xc3\x17\x42\xad\x72\xdf\x40\x2c\xdd\x32\x9a\x7d\x23\x33\x1e\x41\x8b\x53\x60\x84\xae\x5a\x08\x98\x68\xb4\x52\x88\xf0\x10\x71\x78\x6c\x05\xc5\x63\xba\x64\x7d\xdd\x00\x00\xfb\x97\xc8\x7c\xf0\xb0\xd7\x3b\x94\xff\xb8\xc4\x56\x82\x9b\x4a\xf3\x12\x57\x58\x9b\x94\xdb\x51\x36\xd5\x10\x8c\xcd\x2b\xdd\x40\x40\x59\x63\x43\x56\x08\xbb\x0d\xc5\x55\x9e\x5d\x03\x80\x28\xb3\x16\xde\xc1\xa6\x96\x96\x71\xea\xb3\x81\x28\x63\xc0\xb6\x00\x59\x65\x08\xca\x68\xec\xb3\xe8\x9a\xf2\x6d\x28\x1a\x06\x20\xb4\xc8\x85\x03\x4a\xce\xc8\x8b\x24\xe1\xe5\x65\x30\x29\xa7\x6e\xee\xa4\xe1\x70\x6e\x24\xcd\x54\x2a\xd0\x0a\xac\x49\x4a\xc8\xb0\x91\xb2\x56\x2b\x0d\x32\x8c\x47\x12\xe5\x9e\x6f\xfa\x67\xd1\x6f\x09\x80\x57\x85\x9d\xf7\x11\x5b\x45\x49\xc7\xef\x28\x04\x3a\xaa\x41\x1a\x76\x02\xce\x4d\xa2\x04\x0c\xce\xf4\x68\x70\xac\x6e\x59\xba\x71\xcb\x49\x13\x64\xe3\xfa\x40\xc5\x6d\x24\xd7\x47\x9b\x1b\x44\xc4\xec\x18\x75\x23\xbb\xd4\xc0\x89\x3c\xcf\x58\x5a\xd3\x91\x00\x2b\xaa\xbb\xa2\x25\xc2\xc9\x46\x12\x0f\xcc\x65\x53\x25\x9e\x6b\xd7\x82\x49\x33\xab\x49\xbc\x23\x8b\x5c\x07\xd5\x0e\xa8\xf4\xc3\x8d\x14\xd5\xcd\x00\x42\x42\x9b\x2f\xf4\x1a\xaf\x3d\x1b\x4d\x4f\x87\x39\xf3\x33\xf6\x72\xe9\x20\xbe\x6f\xeb\x8f\x10\x89\x98\x2f\x0d\x91\xae\xac\x4b\x79\x43\x6c\x6b\xb2\x34\x08\x38\x50\x46\x6f\x98\x83\xfe\x84\x30\x9f\xd9\x8a\xc3\xba\x1a\x3a\x34\x09\x25\x32\x78\x82\x0f\xc2\x0e\x53\x0d\x5c\x87\x8d\x46\x61\x88\xa4\x26\x5a\x3b\x4e\x34\x9f\x6f\xd6\xad\x5c\xc0\x46\xa0\x03\x66\x24\xe6\x81\xaa\x61\x80\x2f\xe0\x5a\xdf\x1c\x63\x65\xc1\x4c\xbd\xd9\xfc\x84\x01\xde\x55\x07\x38\x51\x91\xf7\xec\x9a\x84\x97\xe4\x9d\xd7\xa7\x5d\x7d\xe8\x6c\x52\x66\x83\xfa\x02\x90\xb3\x86\x67\x2d\x53\x2a\x03\x74\x71\x71\x61\x8f\xd0\xc5\xd1\x11\x12\xf6\x0c\x1d\xc6\x07\x88\xae\x37\x6c\xe7\xb4\x0f\x94\xb0\x94\xae\x0f\x95\x61\x71\x74\xa4\x1d\xa0\x55\x2a\xb3\x79\x0f\x48\x56\x7e\xf2\x93\x30\xc2\xf2\x0b\x2c\x46\xe0\xd0\xb7\x8a\xf2\x49\x32\xa4\xff\x71\x46\x76\x9e\x1c\x30\x38\xe3\x57\x6d\x4b\xca\xeb\x82\x8c\x5e\xff\x48\xfd\x8c\x8f\x09\xfd\x8f\x33\x3e\xad\x96\x18\x76\xa3\xde\xc3\x3b\x34\x9d\xd0\x1b\x09\x82\xea\xf1\x90\x16\xf8\xd5\x4d\xa5\x4c\x27\x4d\xb6\xf2\x75\xaa\x53\x0e\x0a\xc7\x40\x4e\x44\x84\xdf\x54\x83\x64\xac\xa2\x12\xae\xea\x3e\x50\x4c\x05\xec\x8e\xc2\x51\xf6\xb4\xb6\x25\x65\x55\x9a\x7d\xd8\xd2\x6c\x66\x77\x94\x13\xf6\x35\xd5\xdd\xac\x05\xf8\x70\xf0\x81\x55\xa3\x0f\xbb\x49\x4e\x59\xaf\x97\xf1\x76\xdb\xe1\x00\xc1\x81\xa9\x89\xc6\x4b\xb7\x9e\x89\x40\x06\x56\x7c\x9d\xb4\xec\x79\xda\xd0\x6d\x01\x8e\x62\x22\x83\x9a\xca\xad\xb5\xa9\xd3\x45\x93\xc2\xe6\x35\xe7\x0d\xcf\x92\xf0\x47\xeb\x81\xaf\x11\xb1\x9f\x3e\x18\x8f\x48\x26\x5c\x44\x2c\xe3\x34\xcd\x1c\xf6\x80\xe2\xfb\x54\x99\x43\x65\x24\xeb\xff\xf5\x7e\x42\xac\x02\x09\xbe\x9f\x54\x0d\x67\xc4\x2a\xe5\xed\x9c\xbd\x48\xa5\x79\x11\x61\xf6\x1a\x55\xdc\xaf\xd2\x0d\x67\x3c\x22\x2d\x94\x94\xb5\xf1\x4b\x28\x90\xcc\x46\x73\xb5\xb4\xdb\xcb\x8c\xe7\x98\x44\x1e\x42\xb0\x55\xb1\x0f\x61\x00\x5f\x81\xe1\x12\x26\xec\x6c\x16\x60\xd5\xbc\x2b\x13\x50\x40\xce\x67\x03\xda\x2c\x5f\xfb\x84\x6d\x4a\xd6\xbe\x2c\x33\xb9\x4c\xd8\x21\x46\xc0\x4c\x46\x90\xc9\x19\xeb\xa3\x01\xea\xa7\x15\x46\xa0\x9b\xd1\x5e\x33\x9b\x92\xcb\x4d\x3f\x35\x9b\x6f\x63\x08\x51\xdf\xfb\x14\xb6\xbc\x8e\xb1\xd3\x79\xa8\xe4\xb8\xa8\x13\xf0\x4a\x1e\xb8\x37\xeb\xa4\x71\xf8\x69\xdf\xb1\x19\x93\xe8\x26\x68\x24\x3a\x25\xe4\xfe\xa7\xe8\xf1\xa7\x7d\xdd\xa3\xc1\x18\xf7\xd1\xa3\x07\x62\x73\x9d\xc0\x03\x19\x31\x48\xa9\xdc\x81\xcf\x43\x04\x20\x5b\xac\xa9\x81\xe7\xd4\xb9\x14\x68\x14\x81\xe9\xb8\x08\xe1\x73\x3a\x52\xce\x8c\xea\x04\xc9\x0c\xde\x3b\xf9\x99\xc7\xb1\xa1\x79\xcd\x12\x42\x65\x20\x11\x35\x0b\x08\x82\xde\xcf\x66\x3e\xda\xbc\xf0\x74\xf6\xf3\x0b\xf0\x9f\xee\x98\xf8\xfc\x9f\x5c\x69\x42\x82\x8f\xc2\x92\x9e\xd2\x84\x6d\xb3\xdd\x07\x72\x16\x0d\xe5\x1c\xd6\x02\x0f\x95\xd4\xfc\xaa\x88\x5f\x77\xe2\x34\xbf\x71\x56\x53\xb2\x82\xd1\xa3\xd1\x34\xe8\x7b\x52\xd6\xee\x25\x8b\x7c\x33\x51\x74\xed\x06\x87\x56\x92\xa0\x65\xbd\x96\x04\x8d\xf2\xd5\x84\x44\x69\x51\x0a\x2a\x18\xcc\xa7\xff\x45\x9d\x1d\x8d\x8e\xf0\xa3\x5c\xcf\x49\x7f\x3c\x26\x91\xf7\x61\x3b\x40\x63\x29\x01\xfe\x91\x97\x13\xbf\x0a\xfe\xd8\xb8\x1f\x04\x2f\x4b\x95\xe0\xcf\x1f\x52\xcd\x9c\x9a\x45\x42\xd9\xbc\x6e\xba\xa9\x94\x6e\xfe\x14\xa6\xbb\xdf\x47\xfb\xbd\xdf\xc0\xfb\x4e\x9a\xd6\x76\xe6\x3c\x12\xb3\xf9\x73\xd2\xd4\x49\xac\x39\x68\xd4\x22\x34\x5f\x18\x1e\x3d\x41\x37\x9d\xda\x66\xf3\xc6\xd8\xb5\xf2\x87\xe2\x96\xa5\x95\x84\x56\xb3\x8b\x93\xf5\x07\x1d\xe8\xe0\x04\x7a\x97\x13\x9d\x59\xf1\xae\x3c\x57\xc2\x38\x87\xe3\x1e\x3a\x7b\x99\x7e\xc1\x0d\xf7\x22\xb5\xf0\x46\xa7\x1e\xcf\xcc\xa3\xe1\x05\x52\xc7\x95\x83\x47\xc3\x73\x8e\x7d\x15\x90\x6d\xac\xb7\x75\x6f\xd5\x2a\x92\x0b\x74\x40\x3b\x45\x72\x6f\x34\xc9\x1f\x7d\xf6\x70\x92\xf7\xfb\xfa\x71\x6d\x3a\x7c\x4f\xe9\x3b\x08\xd7\x0d\x0a\xd1\x52\xff\x75\x50\x87\x15\x29\x7d\xc6\xa7\x8f\x58\xa8\x16\x5d\xf0\x9e\x2f\x25\x01\x51\x2c\x25\x30\x3a\x20\x99\xd0\xcb\x44\x18\x13\xdf\x43\x88\xa4\x6d\x3a\x2d\x22\x43\x7a\xfa\x7d\x0f\xc1\xda\xc5\x50\xd6\x74\x2a\xdf\x58\x34\xa1\xef\x6b\x08\xdb\x2f\x8f\xc5\xba\x0c\xe4\x08\xc2\xcb\x70\xe9\xe2\xd8\x08\x5b\x9e\x36\x86\xd9\xc5\x13\x08\x7e\x1e\xf4\x7a\xa9\x2d\xac\xda\x50\x66\x81\x08\x4a\x52\x39\x50\x0b\x04\xd5\x21\xb9\x80\x2b\x92\xf4\x04\xa1\xf7\x18\xa4\x89\x4d\x60\x29\xd4\xd8\xef\x45\x21\x93\x68\xac\xb6\x8c\x37\xf0\xb2\x09\x51\x41\x98\x41\x61\x32\xea\x72\x8a\x90\xd4\xf0\x45\xf9\xa1\x00\xf3\x99\xa5\x09\x1c\x39\x2c\x02\x68\x62\xc8\xfe\x4e\xb2\xde\xd0\xdf\x71\xa6\x5b\x8e\xee\xb7\x62\x53\x50\xac\xda\xdf\x7d\xda\xf7\x05\x1b\x86\xc7\xa0\xd4\xa4\x9d\xd4\xd0\x4b\x16\x55\xad\x56\x45\xb7\x96\xd9\x8e\xee\x85\x4e\xcd\xb1\x13\xe1\x08\x5f\x49\x93\xb2\xb5\x83\xab\xcf\xea\x38\x7f\xaf\xf8\xd2\x38\xc0\xe0\xab\x66\x87\xe2\x85\xd4\x49\x9a\xe4\xb0\x64\xff\xe5\xfb\x1a\x90\x87\xed\x8a\x1c\xae\x83\x1f\x8f\xc7\x4d\x36\x0a\x89\xc8\x1e\x3f\x3c\xa0\x27\x35\x22\xe0\x9a\xe6\xad\x8d\xcd\x3c\x1a\x3f\xd4\x40\xf9\x47\x4b\xb1\xc7\xe3\x31\x9e\x60\x55\xee\xde\x67\x9e\xe7\x8d\xe0\x82\xca\x78\x35\x24\x18\x40\x8a\x61\x3e\x0f\xd3\x0d\xc7\x48\xd3\x06\x87\x59\x3b\x62\x25\xe0\xbf\xa2\xf9\x88\x95\x58\xbc\xbf\xec\xe2\x14\x7d\xf3\x0d\x72\xd1\x6a\x85\x0c\xda\x4a\x0c\x77\x18\x13\x5a\xa7\xa6\x26\x95\xb6\x30\xfa\x6c\xd6\x69\x1f\xa6\x09\x69\x2f\x7a\x06\x55\x18\x42\xc1\xb8\x76\xa9\xa0\xfc\x9b\x4f\x3f\x77\x9b\x33\x88\xc1\xcc\xeb\x71\x25\x80\x3a\x12\xe9\x28\x24\x19\x0a\xe4\x1c\x7c\xcf\xf9\xec\x7e\x8a\xe5\x14\x46\xf5\x29\xe4\x3c\xfc\xe8\xd2\x17\x83\xa4\x27\x51\xc0\x6e\x9a\xc6\xf5\xd1\x69\x44\xeb\x75\x7d\xc6\x52\xa8\x79\xe2\x8c\x49\x73\xf0\xbb\xcc\x98\x34\xc2\x3d\x63\xc6\xd6\x4d\xeb\xb8\x75\xec\xd7\x62\xec\x45\x33\x0e\xbe\xf7\x70\xf4\x81\x6b\x47\xf4\x55\x0f\xbc\x00\xdc\x34\xf0\xf9\xf1\x81\xcf\xf3\xfa\xc0\x7f\x0e\x35\x4f\x1c\xf8\xcb\x68\xdd\x20\x18\x4b\x59\x56\x05\x84\x56\x63\xda\x36\x07\x1d\x2e\x48\xce\x1a\xde\x36\x68\x47\x29\xb6\x95\xfe\x11\x68\x33\x73\xd0\x4c\xb3\xf8\x39\x68\x48\xda\xcf\x41\xf5\x48\x2b\x4d\xa5\x56\xc2\xed\xd0\x63\x6f\xfc\x70\x3a\x18\x3f\x74\xc7\x0f\x85\xab\x1d\x6a\x4a\xa9\x4d\x15\xd5\xa0\x3f\x41\x75\x91\x54\x70\xbb\xaa\xd1\x9b\x9e\x37\x97\x36\x4a\x8b\x7c\xca\xe4\x85\x36\x6a\x1a\x3f\x0f\x70\x9d\x23\x7c\x22\x6a\xed\xfc\xf4\x68\x4b\x92\xf1\x9d\xde\x16\x2c\xfa\xa3\x60\xe5\xea\x3c\x03\x2c\x27\x69\x35\xbc\x7a\x6b\x77\xcc\x14\xc9\xde\xad\x34\xc9\x40\x9c\x2a\x8d\x87\xe9\x13\x41\x47\xc6\xc5\x43\xa2\x7d\x7a\xb4\x21\x03\x87\x37\x87\x2a\x2f\xd6\x97\xe0\x81\x03\x83\x9d\x8c\x71\xea\x51\x31\x04\xc6\x13\x61\x5d\xe9\x24\x5e\xb2\xdf\x37\xd4\x13\x7e\x3c\xe4\xd5\x26\xc6\xb7\x81\x9f\x53\xf1\x24\xdd\xe5\x88\x44\x5e\x36\xac\x38\x66\x11\x8f\x03\x2a\x4e\xb4\xe7\xc3\x17\x4f\xfe\xf9\xf6\xeb\xef\x5f\x3c\xbd\x7c\xfe\xf2\x45\x95\x63\x71\xa2\x3f\x07\xce\xeb\xcb\x67\xaf\x48\x64\x8e\xa1\x94\x6a\x4b\xb8\xd2\x65\x51\x84\x27\x8b\x8c\xfa\xef\x26\x80\xb7\x76\x25\x00\xb8\xfb\x1f\x05\x77\x7d\x74\x3b\xbb\x03\xfe\x29\x1d\xf0\xed\x0e\x98\x5e\x08\xe4\xb6\xac\xdd\x8b\x8f\xad\xa2\xe6\x25\x34\x74\x37\xf7\xf8\xf4\x32\x39\xaf\x60\x0f\x9d\xb3\xe6\x0b\x5c\x71\x60\x71\x8c\xf2\xb5\x4d\x46\xdc\xac\xe5\xb8\xd9\x65\xba\x94\x25\x6a\x2e\xd1\xa7\x72\x11\x69\xf7\x5e\xa9\xad\xbf\x6d\x56\x0c\xcb\xc6\x1a\x31\xc0\xad\xb7\x92\xcf\xa1\x0f\x35\x65\xa5\x8a\x24\x04\xa9\xc2\x67\x34\x76\x9d\xca\x50\x0e\xc6\xf5\xb9\x69\x98\x1c\xb8\xa9\xaf\x8d\x39\xe8\xf1\x5d\x71\x1c\x2c\x03\x63\x1a\x63\x0f\xdc\x04\x93\xf1\x08\xef\xf7\xa3\xea\xc0\x42\x9f\x83\x5f\x64\x5c\x7f\xcd\x91\xe3\x07\xe0\xa6\xc1\x93\x6a\x36\x18\xbe\xb8\x79\xf8\x04\x4b\xd2\xfa\x36\x74\x70\x24\xe3\xff\xbb\x23\xe9\xef\xc4\x30\x6e\x5b\xa4\xca\x89\x39\xa8\xb0\x3f\x80\x46\xa4\xd7\xdb\xd6\xf4\x51\xb5\x92\xa0\x10\xe1\x25\x0d\x93\x15\xde\xd6\xc6\xdb\x8a\x13\xf6\x11\xc2\xc7\x64\xe9\x55\xe3\xd7\xd8\x0a\x95\x29\x28\x45\x9c\xe5\x61\x8d\xca\xa6\x59\xa3\x82\xa7\x95\x59\x04\x47\x68\x4b\xe5\x44\x52\x27\x6f\x8e\x4c\x5c\x7f\x7c\x76\x95\x9a\x99\x74\xf5\xb2\x46\xf9\x75\xaf\xa6\x5b\x44\xd1\x32\x28\x16\xc9\x98\x53\x5e\xf1\x3d\x01\xf3\x1e\x7a\x69\x55\x11\xb8\xaa\xe9\x75\x42\x22\x5e\xe4\x55\x7a\x19\x1e\xeb\x65\x63\xe3\xea\x15\x39\x34\xbf\xaa\x34\xdf\x72\x88\x84\x43\x8a\x8d\xd3\x8a\x88\x57\x80\x15\x9c\x56\x77\xc2\x49\xbd\xd6\x05\x9c\x16\xf5\x21\xc9\x6b\xcd\x2f\x88\x78\xa4\x51\x69\x7e\x71\x4e\xf3\x15\x17\x14\xd0\xf8\xda\x68\xdc\x5c\x60\xf5\x49\x59\x37\x4f\xca\xfa\x4e\x18\x58\x93\x72\xd1\x84\xc3\xe9\x33\x73\xd1\x3c\x33\x17\x77\x42\xcc\x9a\x99\xab\x96\xc1\xa9\x4f\xcf\x55\xf3\xf4\x5c\x9d\x83\x83\xf5\xd2\xb9\xba\xc2\x6d\x12\x49\x5b\x0f\x5d\xe7\xb7\x27\x9e\x4e\x41\x7f\x77\xa6\x34\x46\xae\xbd\x5d\x29\x91\xf9\x08\x93\x27\x66\xc2\x36\x46\x98\xbc\xf5\x9e\xa8\xf3\xa6\x78\xd1\x41\xde\x97\x29\xea\x79\x84\x9b\xa4\xcc\x81\x7c\x8c\x30\xf9\xc9\xdb\x01\xb7\x16\x42\xdd\x74\xe7\xee\x6c\x33\xbd\x97\xc6\x7d\xcf\xdb\x5e\xef\xad\x32\x28\xbe\x8d\x96\x8e\xf3\xd2\x7b\x2b\x77\x5a\xfd\x40\x03\xe3\x5e\xef\xe5\x90\x65\x7e\xa2\x9f\x1d\x94\xb1\xc8\xde\x96\x0f\xb2\x9c\xf2\xb7\x83\x38\xaf\xe2\xc8\x1a\x49\x02\x7f\xec\x3a\x6f\xed\x33\xa7\xea\x97\xf9\x56\x5c\x14\x25\x3f\xc9\x37\xe6\x07\x1e\xc3\x46\x6b\xda\x47\x1d\xd4\x6f\xca\x04\x0d\x3d\xf9\xa9\x74\xbf\xd6\x5a\x68\x7a\x7d\x8e\xa1\x11\xbc\x63\x3d\xa7\x06\xdf\x12\x70\x61\xee\xd5\xab\xf4\xbd\xa2\x8b\xc3\xaa\x85\xc7\x9d\x30\xba\x16\x13\x5c\x7b\x1e\x8f\x11\xb6\xe2\x9f\xb4\x02\xa9\x57\x45\x58\x46\x4b\x99\x54\xb0\x92\x9c\xeb\x0e\xf0\xce\xc6\x44\x3d\xa2\x6f\x46\x44\x33\xb0\x5f\x02\x95\xf2\xd1\x7d\x33\x32\x9a\x69\xfd\x12\xc8\x94\x8f\xf4\x1b\x90\x29\x95\xd9\xc0\x50\x2e\x8f\x9d\x35\x1a\xb4\x59\x36\x6f\x1b\x3f\xec\x7a\xde\x65\xaf\xe7\x5c\xf6\xbd\xf1\x43\xec\x8e\x1f\x7a\xf2\xdb\x1b\x69\xb1\xa6\x81\x4b\x0a\x18\x97\xa7\x0a\xc1\xc6\x5b\x48\x1f\x69\xe9\xc8\xf6\x00\x70\x9e\xcc\x24\x85\x3d\xa5\x2f\x71\x28\x31\x97\x95\x94\xe0\xea\x32\x93\xa5\x4b\x6e\xdf\x04\x24\x45\x1c\x97\x68\x3f\x52\xf7\xf3\x5f\xb4\xfb\x52\xa3\xdb\xde\x7d\x49\x83\x3f\x6f\xf7\x7f\xd6\x8e\x8a\xa7\xf2\xd2\xc5\x65\x0c\x07\x36\x3b\x3b\xcd\xd5\xfc\xd7\x2b\x8b\x8b\x4b\x58\x61\x37\xb5\xf8\xe8\x15\xc9\xe4\x46\x5e\x7f\x55\xc6\xf2\xe6\xd8\xd0\x14\x4a\x19\x67\x2b\x00\x57\x56\xc4\x42\xa5\xdf\xee\x8e\x9b\x82\x5f\xd9\xec\xa4\xdc\xb1\xab\x26\xd3\xca\x6e\xd9\xf2\x85\x6b\xec\xf0\xca\xf3\x6c\xb2\xdf\x77\x13\x7b\xab\x07\xed\x77\x77\x44\xba\x63\x5c\x60\x4c\xe8\x7e\x2f\x9a\x36\x5e\x06\xda\xdf\x86\xb3\x53\xf0\xaa\x53\xcb\x37\xb7\xf4\x8a\x91\xb9\x7a\xc9\x26\x39\xa6\x7e\x42\x96\x2e\x97\x0e\xca\x68\x1e\xfd\xa4\x77\x5a\x78\xca\xa4\x09\x4c\xbd\x40\xe3\xe5\x82\x38\x0a\xde\x21\x82\x4c\xa5\xfc\x1c\x35\x14\x5c\xa7\xdb\x9c\x86\xe9\xfb\x04\xf1\xde\x59\xf9\x42\x40\xb1\xb9\x76\xe9\x85\x3f\x49\x59\xb4\xdc\x81\xf7\x68\xe7\x96\x4f\x9a\x9b\x0d\xe1\x6b\xf8\xcd\xf3\xaf\x9e\x11\x2e\x51\xb8\x2d\x93\x5f\xea\xfc\x0b\x4c\x1a\xc3\x5a\x97\xbf\x87\x8b\x78\x9b\x59\xda\x41\xc3\x71\xfb\x01\xc8\x55\x93\xf6\x7c\xd5\xf4\x22\x49\x5f\x94\xdc\xee\xa8\x9f\x59\x4e\xa9\x75\x00\x3e\xa1\x6c\x1b\x61\x71\xb8\x1f\x2b\xa6\x3f\x2a\xf9\xc3\xa8\xe4\x94\x23\x5c\x10\xa8\xd0\x0c\xeb\x54\x10\xa1\xbf\x6b\x06\x70\xac\x22\xcf\x6f\xae\xd9\x86\x2c\xfc\x3e\x56\xa5\x28\xb8\xa0\xdc\x30\x55\xa5\x9f\x5f\x31\x5b\x9b\x2c\xdd\x98\x57\x25\xfb\x7d\xc5\x3f\x4b\x74\x95\xa4\x19\xfd\x8e\xfa\x61\x9a\xc4\x3b\x6b\xa6\x45\xdd\x4c\x66\x69\x0e\x29\x1f\x8f\x0a\xac\x26\x0d\x38\x88\xa0\xe7\xbd\x5e\x53\xaa\x0c\x85\x6e\xf9\x0b\xae\x46\x58\xa8\xb8\xff\x6f\x01\x81\xc9\x48\xb2\x59\x69\x33\x62\xf7\xcb\x0c\x46\xa1\xae\xca\x2c\x8b\x90\x5a\x90\xe8\x83\xf5\x93\x59\x5b\xf6\xdc\xa1\x75\x89\x84\x92\x11\x96\x06\x30\xbf\x69\x14\x4d\xfe\x5d\xae\xe1\xd2\x69\x86\xa9\xf5\xe3\x52\x9f\x79\x7d\x64\x59\x9c\x1c\xb6\x0e\x39\x51\xe0\x34\x24\xde\x93\x8a\x97\x32\xa9\x59\xbc\x8c\xa8\xc2\x6c\x2d\xa6\xc5\xbc\x93\x92\x77\xdf\x0a\x70\x40\x4c\x85\xc9\xc9\x2b\xec\x39\x69\x63\xe3\x04\xd6\xca\xcd\xce\xb1\x85\x02\xa8\x5d\xdd\x0c\x92\x66\x16\xff\xb3\xec\x5c\x6a\x3f\xb2\x30\x10\xe2\xfb\x01\x36\xaf\x09\xc8\x88\x92\xa8\x4c\x70\xc4\x32\xe4\x07\x79\x17\x72\x35\x3e\x22\x03\xd2\xf4\xc0\xb7\xef\x48\xaf\xbf\x79\xf9\xaf\xea\x33\xd5\x90\xe6\x2c\x4b\x77\xb5\xd8\x85\xd6\xd4\xaa\xe7\xb0\x62\x2b\xfc\xaa\xe2\x6c\xbf\xbd\x10\xbc\x43\x46\xd5\x16\x05\x57\x3c\xd8\xe2\xdd\xe7\xa5\xd1\xac\xf1\xd8\xe6\x5a\x61\xd7\xa4\x3b\xaa\xe0\x2c\xc2\xf6\xd4\x50\xbe\x3b\x9a\x6d\x26\xa7\x67\x63\x3a\xae\x60\x5a\xf5\x5d\x71\xf7\x68\x27\x55\x48\x67\x45\xe9\xab\x56\x3e\x35\x18\xf4\xf1\x10\xd0\x0d\x90\x0f\x85\x82\x3e\x2d\x00\x74\x6d\xd4\x4e\x8f\xb8\x6d\x0e\x7e\xcd\x27\xc7\x59\xa3\xdf\x1a\x05\xab\x06\x56\x04\xde\x9d\x89\xc0\x10\x32\x4a\xf1\x9c\x4f\xca\x6d\x31\x64\xe9\x6b\x18\x5e\x11\x00\xa2\x6d\x14\x6b\x20\xed\x48\x56\x12\xf2\xb5\x9f\x45\xc2\x30\x49\x44\x40\x2e\x3d\x8c\x88\x38\x11\x75\x6a\x30\x8b\x9c\xdc\x70\x59\x47\xb7\xa8\x67\x52\x51\x4b\x1d\x05\xcf\xfc\x18\xb2\xf4\xdb\xf4\x3d\xcd\x9e\xfa\x39\x9f\x22\xa0\x25\xbf\xa4\x25\x13\xad\xf3\x07\xc4\xc0\xaf\x1a\x24\xba\x24\x34\xdf\x26\xb4\x1a\x89\x1d\xf2\xd7\x62\x75\xa5\x80\x7e\x2a\xa7\x2f\xad\x03\xad\x0b\x9c\xdc\x1d\x55\xe3\xf8\x20\xab\x92\x5e\xf9\xb3\x69\x80\x23\x63\x80\x35\x3a\xe7\x0f\xaf\xc6\xab\x7d\x70\xa3\xb3\x07\xb7\xa1\x0b\xb5\xb8\x61\x0d\x4b\x17\x3c\x75\xdc\x9d\x67\x9a\x50\x4c\x7e\xe9\x99\x51\xbf\xb8\xd0\x09\xa2\xa1\x0c\xa8\x42\x7b\xbd\xe6\xe8\x60\x76\x34\xb0\xb6\x48\xe6\x66\x9b\x4d\x6c\x16\x62\xae\x88\x10\x41\x6a\x5d\xb7\x07\x92\xb2\x86\xe1\x1c\x26\xf8\x56\xb4\xf0\x8d\x9f\x84\x31\xbd\x5c\x45\x86\x35\x64\x42\x52\x12\x89\xa3\xa6\x0f\x91\x7b\x6a\xe1\x7a\x60\xa8\x64\x98\x1b\xcf\xf3\x1c\xb4\x4d\x42\xba\x8c\x12\x1a\x1a\x23\x97\x4e\x8d\x64\x97\x3a\xa9\x7c\xc7\xa6\x99\x66\x36\x94\x31\x97\x48\x8a\x89\xbf\xdf\x3b\xbe\xc7\x87\x2a\x70\x78\x9b\x3c\xad\xa9\x6d\xe2\xe3\x26\x91\x3f\x85\x89\x17\xbb\x31\x9f\xfd\x59\x3a\xaf\x79\x59\xf9\xf4\x45\xda\x59\x53\xb6\x4a\xc3\x4e\xe2\xaf\x69\xd8\x41\x9f\xf6\xd3\xfe\xa7\xe8\x53\xed\x5c\x4e\xd7\x8f\xa6\x1c\x82\x83\x5d\xf8\x13\x09\x2b\x70\x39\x64\x10\x1d\x74\x69\x3b\x8e\x22\x4c\x9f\x3f\xb5\x59\xae\x3c\xbb\x35\x0c\x35\x4c\xcc\x6c\x34\x87\x48\x3f\xe2\x70\x56\x53\xfa\xb4\x55\x83\x3a\xe2\xe5\x7b\xe1\x64\x78\xc2\x9c\x30\x0d\xb6\xd2\x77\x53\xe2\x28\xd1\xf1\xe9\xb7\xcf\x9f\xfe\xe3\xad\x8a\xdb\x45\xb2\xa1\x0a\x84\x25\x06\xf2\xf2\xe5\xdf\xff\xfe\xed\x33\x52\xd5\x32\x51\x8f\x0f\xbe\x90\xc7\x27\x5c\xaa\x51\x5e\x17\x7b\xbd\xb8\xd6\x7d\xb9\x61\x11\x79\x55\x26\xfc\xdd\x98\x28\x7c\xf3\xe4\xc5\xdf\x9f\x11\x34\x44\xfd\x6c\xa8\xe3\x63\x0d\x9f\xbf\x78\xf5\xfd\x25\x71\xea\x4e\xb7\x2a\x4d\x27\x47\x9b\x4e\x08\x7a\x1b\xac\xfc\xe4\x8a\x22\x42\xab\xad\xff\xed\xdb\xef\xbf\xbb\x4b\xdb\xe0\xb4\xab\x46\xef\x36\x42\x4e\x6a\x3c\x21\xa2\x8b\xed\xd5\x7e\x2f\x0e\x4c\xea\xeb\x00\xc6\x70\xb9\x46\x28\xae\xe2\xfb\x8f\x67\x3f\x7e\xf5\xf2\x5f\x2f\x7e\xe6\xe1\x7a\x47\x77\xe2\x44\x55\x1b\xaf\x7f\x3c\xfb\xf1\xfb\x57\x3f\x7f\xeb\xdb\x4d\x43\xdb\x5f\xbf\x7c\xfa\xfd\xeb\x9f\x6b\xb2\xd2\x8a\x65\x86\x11\x02\xfc\x20\xb6\x70\x8f\x29\x70\x25\x66\x38\x36\xaf\x5e\xc7\xca\x1f\x3e\x2d\x43\x5d\x79\xb1\x9d\x95\xa4\x4f\xd3\x64\x19\x47\x81\x15\x72\x4a\xcb\x93\x46\x23\x29\xa9\x37\x53\xa8\xc8\x71\xb8\xe0\xbb\xa1\xc9\x7d\x48\x82\x6f\x0b\xc2\xff\xb3\x79\x52\xb7\x3a\x7a\xcc\xbb\x95\xf7\x9b\xee\x2d\xef\xa1\xdb\x1d\x93\x20\x17\x67\x1f\x17\x2d\xe3\x94\x5d\x46\x1b\x44\x82\x34\x61\x34\x61\x2e\xba\x97\x77\xf6\x9d\x1f\xdc\xce\xbd\x9b\xce\xbe\xf3\xa3\xdb\xb9\xb7\x43\x04\x5e\xa1\x0a\xc3\x1e\x88\xf2\x46\x76\xd5\x04\x50\x25\xf2\x49\xcc\xc5\x77\xe8\xef\x8c\xaf\x7c\x15\x2d\x59\xee\xde\xde\xb8\xe3\x11\xd9\xb9\x0f\x47\x05\x91\xee\x0d\x2f\x57\x74\x0d\xf1\xbf\xf2\xc4\xdf\xf0\xbf\x71\x94\xd0\x1c\x70\x8c\xa3\xe0\xdd\x65\xb4\x81\x8f\x34\xf9\x26\xbd\xa6\xa6\xc2\x90\xf7\xb5\x20\x9f\xf0\xf3\x9a\xcf\xdc\xee\xb8\x28\x26\x4c\x5d\xe4\xbe\xdc\xb0\xdc\xd3\x5f\x13\x41\x43\xe6\xb8\x00\x03\x66\xd1\x46\x89\x23\xde\xed\x8d\xcb\x11\x1b\x49\xb9\x1e\xe2\xaf\x51\x5c\x4c\x12\x43\xfe\xb0\xe3\x86\x69\xef\x22\x4c\xf8\x07\xa4\xc3\x4d\x9c\xb2\xe1\x26\xde\x5e\x45\x89\x8e\xd8\xaa\x74\x8e\x3c\xef\x95\xc8\xf2\x66\x73\x92\xe9\x58\xaf\xa9\x37\x9a\xa4\x8f\xb2\x49\xda\xef\xe3\x6a\x49\xe9\x7f\xdb\x02\x3c\x4b\xe7\x43\xbe\x95\xe1\x89\x0e\x84\x17\x95\xeb\xe4\x96\x63\x7c\xc3\x71\xf1\xaf\xe8\x0f\x24\x19\xee\xe4\xef\x1f\x09\x44\x4b\xbb\x14\x23\xa2\xba\xed\x24\xb8\xd0\x60\x7c\x27\x13\x52\x40\x32\x84\xa1\x5f\x83\xff\x68\xea\xb0\x21\x17\x37\xf8\xb1\x6b\x95\xc6\x21\x05\x5b\xcf\x05\x68\x9c\x38\x5e\x2b\x3e\x2d\x88\xe4\x7c\xc5\x70\x46\x27\x5b\x70\x30\x31\xc0\x78\xdd\x31\x76\x9d\x5c\x36\x40\x12\x0e\xf1\xab\x74\xfd\x2c\x96\xc7\x43\xa1\x37\xb9\x8e\xf2\x08\x4e\x32\x5c\xfe\x6a\x6c\x76\x9b\x34\x35\x6c\x35\x34\xc2\x46\x97\x54\x8b\x52\xb0\xb1\x97\x0f\xc9\xf4\x3a\x04\xc7\x2f\xf9\x7f\x32\xe6\x38\xc9\x80\xe2\xfb\xf0\x6f\xdf\xc9\x06\x0c\xdf\x87\x7f\x31\x68\x95\x23\xcc\xa4\x0b\x72\xd1\xc7\x88\x24\x06\xc5\x09\xbb\x9c\xc4\xdf\x4c\x23\x37\x35\xdd\x20\x72\x6c\x75\x3e\xcd\x22\x9a\x0f\x81\xc8\x01\x56\xaf\x07\xae\xc2\x6a\x80\xa0\x84\x40\x3c\xf7\x6c\x18\x57\x59\x14\x0e\x41\x55\xf6\x04\x94\x5a\xdf\xf9\x61\xb4\xcd\x49\xe0\xdd\x86\x91\x10\x45\xdd\xbc\x3f\x2e\x48\xec\xa5\x13\x2a\xc4\x0c\x18\xcc\xaf\x44\x84\x45\x83\xbd\xf2\x21\x50\x84\x18\x79\x23\x92\x7b\x83\x31\xd9\x7a\xe3\xc9\xf6\x51\x26\x9c\x60\x4a\x32\xde\xf6\xfb\x58\xa4\xcc\xb6\x83\xf1\x7c\x36\x9a\x3f\xf2\xd2\xe1\x4d\xaf\xa7\x12\x79\xd2\x63\x91\xe4\x44\xde\x76\x30\x26\xb9\xb7\x95\x3a\x83\xae\xe7\xc9\x9e\x6c\xf8\x3a\x93\x55\x22\x5e\x85\xec\x8c\xcf\xf1\xbc\x20\x4b\xa3\x44\x6e\x97\xc8\x45\x89\xb0\x36\x8d\x7c\x8a\x49\x2e\x62\x3d\xe6\xfb\xbd\x93\x37\x96\x10\xa7\xb4\x52\x3c\x2d\xe5\xf8\x44\x1e\x14\x6e\x6f\xdc\x84\xec\x5c\x06\x73\xdd\x58\x32\x2b\x4b\x52\x8e\x58\x01\xac\xc5\x87\x71\x7b\xe0\x38\xd1\x20\xc3\x0f\x9c\x74\x90\x68\xdf\xc5\xb7\x37\xae\xef\x39\xe9\x7d\x87\xde\xcf\x07\xac\x9f\xe1\x7e\xc2\x7f\x0f\xf2\x3e\x1b\x44\x18\x3f\x70\xf2\xfb\x50\xbe\x9f\x0d\x22\x4c\x76\x6e\x7e\xdf\x1f\xe4\xf7\x69\x9f\x15\x85\x85\x3b\x1e\xde\x3c\x16\xfe\x8b\xd6\x11\x48\xeb\xb8\xd7\xcb\x87\x37\x8f\x64\x9a\x7f\xa3\xd3\x76\x46\xb9\x8c\x44\x22\xcd\x28\xc7\xd3\xd4\x33\xd8\x6c\x10\x71\x22\x19\x24\x64\xeb\x25\xf7\xa3\x41\x76\x3f\x9d\x98\x2b\xc2\x5f\xe4\x4e\x70\x9f\xf6\xe3\xfb\xac\xbf\xc5\x0f\xca\x55\x12\xdc\x0f\xfa\xf1\xfd\x18\x17\x62\x52\x7d\xbd\xa0\xc8\x52\x7e\x70\xa4\x15\xac\xcd\xe3\xe5\x74\xe9\x6e\x0a\x27\x1b\xde\xf8\x37\x9c\xc5\x3d\x0c\x9c\x74\x78\x03\x6e\x24\x8c\x84\x1d\x4f\x28\x4b\x6c\xaa\x25\x36\xd5\x12\xcb\x6a\x89\x25\x2f\xd1\x1d\x03\xdd\x85\x8f\x82\xa1\x5a\x0f\xa2\xc3\x2b\xcf\xe7\x40\xc9\x66\xb8\x23\xe9\xf0\x86\xf0\x16\x1f\xf9\x8e\xfc\x49\x96\xc3\x1b\xc2\x01\x4c\x23\x37\x27\x0b\xcf\x11\x64\xb7\x49\x23\x7e\xa2\x14\x7f\xa2\x9f\x28\x99\xa5\x02\x44\x9f\xb7\x36\xe0\x38\xdd\x77\x38\x8c\x01\xc7\xf7\x01\xc7\x09\x7e\xe1\x39\x9e\x98\x2b\x32\x24\x11\xa3\x6b\xf7\x56\xc3\x74\x17\x84\xff\x86\xeb\x65\x77\x45\x04\x63\x70\x33\xf9\x43\x24\xd3\xa2\x68\x66\x31\xbd\x9e\x13\x7b\xb7\xc0\xe4\x5d\x73\x44\x16\xe0\x7e\x05\x18\xbe\x6b\x0e\xcc\x62\x36\x9e\xe3\x02\x17\xf2\xe2\xc5\xe6\xd4\x5c\xdc\x29\xc7\xea\x51\xde\x1f\x4f\x6d\x3e\x17\x0c\x39\xee\x24\xc6\x6e\xb5\x66\x23\x38\x36\x5c\xa5\xe9\xbb\x1c\x36\x09\x90\xf6\xe4\x46\x56\x32\x1e\xc6\x19\x4f\x95\x37\x7a\xc0\xa4\xe4\x87\x03\xbe\x7f\x45\x6c\xea\xf2\xc8\x67\xf3\x41\x39\x2e\xbd\x9e\xd3\x98\xce\x85\x00\x71\x99\xda\x98\x4d\x1a\x53\x9b\xcb\x72\x50\x24\xa4\x31\x65\xb4\x19\x07\x5e\x80\x53\x1e\x88\xa1\x0d\xf9\x92\xd5\x37\xb3\x9f\xd6\x0a\x7c\x2b\xb6\x27\xbf\xb5\x2b\x15\x1a\x91\x62\xd1\xd4\x49\x86\xef\xf9\xa8\x7b\x08\xdc\xba\x22\x92\x0c\x57\xe2\x5b\xb8\x9f\x45\xd8\x2d\x8b\x44\x49\x22\x3d\x69\x1a\xe5\x20\xf1\x1b\x59\x78\x52\xdb\xb9\x27\xa7\xcb\x07\x35\x24\xb5\x80\xd7\xeb\x1d\x83\x22\x6f\x97\xfc\xaa\x54\x41\xa8\x93\xa9\x72\xb0\x23\xae\xd3\x6b\x8a\x08\x3f\xbd\x83\x0c\x2f\x08\x31\x5f\x6d\x19\x3f\x03\xd5\xc9\x30\xc1\xb7\xe7\x48\x1a\xc7\xcb\x96\x88\xaa\x0b\x84\x52\x20\xa2\x4e\x52\x16\xb6\xb1\x05\x64\xeb\xf2\x59\x4d\xda\xcc\xbc\xda\x0c\x90\xd4\xcb\x2c\x27\xa8\xfd\x3a\xc7\x00\xe9\x7b\x78\x43\x22\x55\xf4\x9b\xd2\xf9\x70\x73\xd9\xdd\x84\x0d\x6f\x06\xb4\xe2\xc3\xf8\x5b\xba\x64\x0e\x7e\xac\x93\x67\x92\x76\xe6\x0e\x1e\xa4\xbd\x9e\xc3\xeb\x78\x29\x61\xc3\x9b\x72\xc3\x61\xc3\x1b\x02\x96\x47\xc3\x5d\x0d\x1e\xf8\x44\xb6\xc0\xad\x14\xb8\x08\xc0\xed\x06\x5e\x84\x49\x94\xbf\xf0\x5f\x70\x40\x78\x9a\x98\x52\xfb\xf0\xc6\xab\x7c\xbf\xca\xe8\x35\xa7\x68\xbb\x10\x47\xa1\xa1\x20\x4f\x2f\x81\xef\xaa\xc0\x77\x15\xe0\xbb\x26\xe0\x3b\x8f\x0d\x77\xa4\xa1\x20\x4f\xc7\x05\xb1\x18\xa9\x29\x97\x64\x24\x15\x53\x1a\x35\x4c\xa9\xef\x25\x43\xa1\xef\x12\x47\x2c\xa7\xbe\x76\xc4\x69\x8d\x50\x3c\x41\x9c\x97\xf8\x5c\xee\x12\xfe\x69\xfc\x66\x5a\x72\xb8\x78\x63\x0f\x02\xd9\x55\x52\x76\x05\x26\xc2\x43\xf2\x2d\xb8\xef\xad\x94\x3f\x40\x59\x2c\xdd\x54\x61\xb5\xd3\x56\xa1\x4c\x25\x49\x19\xc6\xda\x64\xf2\x95\x6a\xf2\xec\xd7\xeb\xb5\xe5\x38\x94\x0b\x35\x85\x7d\x02\x31\x8f\xdb\xf5\x03\x87\x50\x91\xca\x60\x74\x08\xea\x5a\xcb\xf5\x70\x6d\x65\x6f\x04\xdb\x73\x79\x40\xb4\x8a\x55\x4d\x78\x98\x47\x75\x4c\x06\x2b\xb2\x85\xdd\x27\x79\x95\x58\x9d\x6e\x79\x5e\xef\xf5\x20\xba\x3a\xc0\x1a\x4a\x2b\xea\x96\xa2\x3a\xf8\x7a\xaf\xe7\x38\xba\xf1\xce\x83\xba\xff\xff\x76\x00\xe2\x61\xf7\x65\xea\x20\xf9\xfe\x50\x0e\x1b\x50\x88\x72\x42\xed\x22\x7f\x91\xa7\xf1\x96\x51\x54\x48\xa5\x73\x05\xa2\x79\xd4\xef\xf5\xa4\x7b\xea\x85\x1f\xbc\xbb\xca\xd2\x6d\x12\xba\xe8\x4f\xcb\xe5\x12\x11\xf4\xd3\x00\x2e\x2b\x90\x8b\xc6\xa3\xcf\x46\x88\x6c\xfc\x30\x8c\x92\x2b\x17\x8d\x86\x9f\xd1\x75\x67\x34\xfc\x82\xae\x21\xa8\x7d\x16\xd2\x6c\x90\xc1\xb1\x07\xf1\xdc\xcf\x21\x7d\x99\x26\x6c\x00\x86\x0b\x3c\xed\x4b\x9e\x26\x8a\xba\x68\xbc\xb9\xe9\xe4\x69\x1c\x85\x9d\x3f\x8d\xc7\x63\x44\xc2\x28\xdf\xc4\xfe\xce\x45\x49\x9a\x50\x44\xd0\xfb\x55\xc4\xe8\x20\xdf\xf8\x01\xaf\x9c\xa4\xef\x33\x7f\x83\x80\x2b\xdb\x33\x6c\x2e\xca\x26\x57\xa3\xf2\x30\xc2\x4f\x04\x0f\xee\xe5\x0f\x48\xe0\x3d\xb8\x17\x3c\x20\xb1\xf7\xe0\x5e\x7c\xf3\x80\x6c\xf9\xdf\xdd\x03\xb2\xf1\x1e\xdc\xbb\x79\x33\xbc\x1d\x91\x71\xe1\xbc\x09\x6f\x47\xa4\xc0\x0f\xc8\xd2\x7b\x70\x6f\x57\x4d\x6d\x3d\x8b\x30\x75\x96\x64\xab\x8c\xe6\x7c\x37\x82\x60\x4f\xa5\xd0\xca\x0f\x4f\x99\x95\x30\x06\x8f\x04\x46\xc2\xc3\x39\x76\x0f\x03\x0f\xb6\xd9\x35\x0d\xbf\xe5\x87\xd1\x13\xc0\x1f\x83\x06\x87\x5a\x4e\x01\xf6\x31\x98\xd1\x8d\x84\x2e\xd3\x6b\x82\xf7\xec\xe1\x7d\xd1\x12\xc8\xc5\xa2\xe1\xd3\xca\xf6\xa1\xd3\x08\x89\x48\x56\x66\xa5\x99\x09\x51\xf5\xa6\x35\x5f\x8e\x5d\x6b\xfe\xc3\xb9\xb8\x2c\xe2\x7c\x4c\x77\xcf\x5f\xd0\xd8\xe8\x6e\x9a\x45\x57\x51\xf2\x1a\x3e\x60\x7b\x33\xcb\x79\x8d\xc5\x44\x5e\x33\xa3\x14\xf7\x54\xb4\x02\x07\xce\x8c\x0c\x37\xca\xcf\xb4\xd7\xeb\xaa\x08\x0a\x08\x71\xd2\x4a\x05\x8c\x61\x46\x85\x45\x0c\xba\x17\x30\x44\x52\x5e\xfd\xe0\x4c\x6e\x68\x16\xd0\x84\x4d\x23\xaf\x9a\x74\x84\x04\x64\xa9\x5c\x38\x16\xa9\xa6\x5a\x63\x8a\x09\x4a\xe0\xb9\xa7\xd1\x83\xa8\x34\x08\xf3\xc3\x7f\x6f\x73\xf6\x4f\x3f\x7e\x95\xd1\x20\xca\xf9\x42\x7c\x70\x6f\x53\x5b\x55\xb0\x37\x10\xdd\xd2\xca\xcf\x5f\xbe\x4f\x5e\x65\xe9\x86\x66\x6c\xe7\xa0\x4d\x04\x0a\xa7\xc3\x48\xc3\x74\x8f\x38\x11\xf4\x7a\x8e\xef\x35\xa4\x37\xe1\xea\xd7\xc6\x36\x41\x70\x97\x45\xbd\x23\xcb\x84\xcf\xe3\xb4\xac\x98\x13\x3b\x0b\xbb\x66\x1e\x42\xc7\x21\x06\x69\x9c\x66\x06\xc4\x80\xd8\x59\x26\xc4\x40\x42\x14\x57\x89\x7e\xfe\xe4\x26\xca\xbf\xe5\xcd\x3a\x08\x0e\x9a\x88\x30\x6c\x80\x8a\x4b\x50\xe2\x1c\xaa\x55\xef\xaa\x9e\x09\x3c\x6e\x07\xbe\x6b\x00\xbe\x2d\x81\xef\x8e\x03\xdf\x02\x70\xa1\xc0\x85\x77\x9d\x60\xdc\x56\x62\xad\xcc\x74\xf2\x1f\x4a\xed\xb5\xc3\x70\x65\x9a\xe4\xdb\x51\x08\x58\xc3\xfc\xf5\xe6\x32\x05\x63\xcb\xa4\x71\x6b\x33\x14\xe3\x2d\xe3\xa0\x23\xb4\x99\x28\xed\x6a\x28\xfd\x78\x08\xa5\x65\x33\x4a\x59\x23\x4a\xbb\x26\x94\x76\x55\x94\xea\xe4\x9a\x1c\x5c\x5a\x1b\x42\x49\xd2\x58\x2f\x3b\x58\x6f\x49\x28\xc9\x8e\xb2\x13\x31\x62\x2c\x0a\xde\x49\x4d\x61\x38\x09\x35\x8d\x7c\x97\x32\x9f\xd1\xf0\x07\x4e\x2b\x97\xbc\x88\xc3\xf0\x14\x65\x22\x15\x12\x90\x8b\xa0\x2e\x9a\x08\x3d\x8f\xc9\xff\x55\x1b\xf0\x35\x51\xda\xce\x45\x27\x4a\x2a\xcd\xcf\xc2\xb9\xb0\x11\xae\xa6\x56\x79\xc6\x4a\xfb\x64\x6b\xa4\x32\x2c\xed\x72\xf3\xa7\x3e\xa3\x57\x29\x07\x55\x29\x31\xad\x35\x31\x5b\xcd\xc5\xd2\x76\x1b\xb3\xae\xb1\xe7\x79\x49\x9d\x4e\x5b\xc1\xe8\x42\x0f\xde\x7c\xf2\xe0\x8a\xa0\x4f\x3e\xf9\xe4\x13\x84\x31\x2e\x8a\xa3\xe2\xc4\xce\x98\x0a\x35\x5a\x6b\x6b\xb4\xcc\x12\xd6\x80\x19\x19\xd5\x31\x5b\xb7\x0f\xcb\xae\x3e\x2c\x06\xa0\xd9\xba\x36\x32\x95\x5c\x18\x9c\xac\xbe\x62\x0e\x01\x6b\x1d\x1f\xb9\x37\x9e\x48\xac\xea\xa9\x7b\xb5\x75\x74\xef\x06\x55\xd9\x81\x55\x9e\x73\x13\x2b\x1b\xd7\x31\x12\xd1\xd6\x4e\x9c\xab\x76\x4c\x76\xa8\x69\x28\x4a\x4c\xb2\x4a\x76\x1b\x26\xd4\x96\x84\x4b\xd2\x6f\xb4\x89\x38\x88\xf7\x8c\xce\x35\x23\x5f\xa7\x21\x95\xe1\xc1\x90\x21\x3b\x55\x8b\x54\x1b\x37\x38\xb8\x57\x7f\x11\xd0\xdc\xfa\x61\xf6\xdd\xeb\x49\x5b\x9f\x23\xe5\xaa\x98\xfc\xf8\x71\x30\xd9\x9d\x88\xc9\xae\x1d\x13\x7b\x61\x7d\x94\x69\x09\x34\xc8\xd3\x27\xa7\xb2\x4b\x79\xa6\xba\x8d\x64\xca\x35\x92\xbc\xd5\x0c\x7d\x46\xff\x4e\x13\x0a\xa1\xa6\x41\x2f\x3c\xd1\x8f\x3a\xa0\x80\xf0\x1c\x01\xdb\x5d\x4a\x9a\xf7\xe0\xf2\xea\xb9\xf9\xf4\x29\x6f\xa2\xb1\x8d\x66\x7d\xaf\xf2\xaa\xd7\xeb\xa0\x71\x53\xf8\xa8\x39\x19\xae\x7d\x16\xac\x1c\xca\x85\x46\x3e\x88\xdf\xd1\xab\x67\x37\x9b\xe1\x27\x63\x88\x12\xa6\xbf\x48\x02\x77\x7a\x5f\x47\x37\x54\xb8\xa4\xf4\x98\x5e\x58\x62\x27\xad\xcc\x9f\x29\x0c\x79\xb6\x8a\x52\x60\x00\x17\x69\x74\x18\x25\x4f\xb2\xcc\xdf\x39\x48\x8b\x40\xb9\x7c\x64\x65\xdc\x1c\xb7\x49\xb4\x89\x9a\x41\x36\xaf\x8b\x52\xbd\xde\xc1\x6c\xa9\x4e\x78\x3c\xaa\xe1\x5d\xdb\xa0\x2d\xbd\x65\x33\xf6\x9c\x09\x7d\x97\xb2\x34\x3b\x1d\xf9\x0a\x43\x35\x05\x80\x62\x52\xb9\x7e\x07\x4d\xef\x6d\x94\x44\xcc\x7a\x30\x94\xd0\xf7\x9d\x04\xa2\xef\xc8\xee\xb9\x8c\x24\xfe\x9a\xba\x48\x12\x0d\x22\xd7\x34\xcb\x41\xab\x31\x1a\x7e\x39\xfc\x1c\x15\xb8\x34\xc1\x20\x35\x03\x0c\xb4\xcd\x29\x18\xf1\x05\x0c\x4d\x84\x91\xef\x50\x20\xae\x77\x3e\x46\xd0\xdb\xb7\xb0\x24\xb7\x31\x45\xe4\x16\xac\x9b\xdd\xee\xa8\xe0\x87\x92\xa7\xe9\x66\x77\x99\x3e\x8d\xa3\xcd\x22\xf5\xb3\x50\x3d\xf5\x17\xaa\xde\xc8\x49\x9c\x11\x58\xbc\xf0\x5f\x7f\xfd\x0b\xae\xde\xf9\xab\x95\xd2\xeb\xd1\x61\xd9\xc6\x94\xba\xb7\x52\xe3\xe2\xd2\xc2\xbc\xdf\xd7\x55\x1c\xdf\x6b\x3a\x50\xbe\xde\xad\x17\x69\xdc\xeb\xa1\x1c\x7e\xd4\x72\x86\x11\x13\x0b\x75\xda\xf0\x08\x4b\x1d\x31\x8b\xc6\x17\x5a\xbd\xde\xa1\x06\xe9\x30\x30\x2c\x68\x3c\x4f\xa7\x77\xd5\xef\x92\xe0\xa6\x0a\x3b\x57\xb7\x88\xf9\x8c\x1a\x97\xfe\x46\xe8\x17\x39\x27\xef\xe8\x2e\x77\x28\xdc\x0b\xca\x94\x2b\xca\x0c\xf9\x44\x34\x92\x2b\x25\xfb\xa1\x32\x1c\x0c\x83\xb5\x9e\xd5\x63\xc5\x95\x36\x81\x8d\x20\xbe\xa2\x79\x90\x45\x1b\xce\xea\x38\x8e\x43\x9a\x6c\xd7\x34\xf3\x17\x31\x2d\x44\x6c\x29\x4e\xb6\x43\x7f\xb3\x89\x77\x0e\xe7\x95\x2a\x6a\x75\x52\xf6\x2e\x10\xbd\x8b\x96\x8e\xd0\x36\xa8\xe3\xfc\xad\xb8\x8b\x06\x0d\x54\x85\xf5\x1f\x2e\x7b\x5b\x90\xa8\x3a\x4c\x5c\xee\xcb\xbc\xd1\x24\x7b\xa4\xe2\xd7\x4d\xb2\x7e\x1f\x27\x5e\x34\xcb\xe6\x84\x69\x9b\xe2\x04\x3f\xf6\x46\xfb\xbd\x93\xce\x92\xb9\x47\x67\xc9\x5c\x73\xef\x14\xee\xaf\x4f\x1c\xf0\xe8\xe8\x80\x9f\x89\x90\x04\x57\x32\xa9\x8d\x04\xf9\x3c\x7f\xa6\x87\x5c\x19\x33\x26\xfc\xb4\x55\xf6\xa0\xd0\x3d\xd0\x63\x1e\xeb\x71\x3c\xd1\xde\xf7\xa9\x9f\x24\x29\xeb\xf0\x06\x3a\xbe\xf0\xc3\xd9\xf1\xf3\x8e\xdf\xd1\x6b\xc0\xa0\xd7\xad\x80\xae\x64\xed\xc4\x1b\x4d\x92\x47\x2a\x68\xe7\x24\xe9\xf7\x15\x55\xb2\x59\x32\x9f\x64\x06\xd1\x78\xe6\xc7\x7e\xdf\x1d\x93\x8c\x2f\xa4\x65\x74\xb5\x15\xf9\xdd\x11\x41\xe2\x35\x45\x94\xc0\x39\x2d\x1b\xbe\xcf\x22\x26\xf3\x30\x69\xe6\x58\x94\x64\x9c\x12\x38\xfd\x95\x58\x6e\x4c\x31\xa2\xcb\xf6\x7b\x65\x0c\xdc\xf5\x3c\x1f\x4e\xac\xe5\x02\x37\x58\xf6\x34\x74\x28\x76\x59\x09\x67\x69\x70\xa1\xa5\x9a\xf7\x9c\xb2\x57\x6a\xae\x5e\x2e\xa7\x25\x35\x18\xa9\xcd\x0f\x3f\xdf\xbe\x85\x49\x7e\xfb\x56\x4f\xba\x5d\x8b\x73\x06\x9b\x3d\x84\xd2\x62\x5c\x1b\xfe\x9a\xcf\x63\xbe\xa3\x4b\x9a\xd1\x24\xd0\x2f\x59\x56\x51\xde\x59\xf9\x79\xf2\x29\xeb\x2c\x28\x4d\x3a\x7c\x47\x89\xfc\x38\xca\x69\xd8\x19\x74\xf2\xed\x86\x66\x0e\xb6\x4a\xf0\x49\xa7\x61\xa9\xe3\xa7\x65\xd3\x2b\x73\x0c\x9d\x55\x73\xef\xf7\xfb\x46\x1b\x63\xa3\xab\x1e\x23\xc0\xf3\x08\x33\xba\xb5\x50\x5b\x92\x62\xc7\xfc\xc8\x46\xa7\x6d\x33\xcc\xd4\x46\x94\x90\x92\x84\xdc\xee\x88\x98\xf4\xc3\xbf\x15\xbd\xc0\x8e\xe5\xd2\x19\x9b\x7b\x09\xa1\x85\x70\x95\x64\x4e\x89\xc6\x84\x29\xcb\x62\x92\x4c\x62\x61\xc0\xcc\xf0\xa4\x34\x33\xaa\x9a\xe9\x13\x61\x03\x2e\xe4\x82\x48\x39\xa8\x8f\xc0\x3f\xbd\x3f\xcb\xe7\x65\x85\x59\x3e\x57\xa3\xba\x70\x42\x27\xf1\x36\x02\xbc\x43\xbd\xa5\xc3\x30\x86\x15\x2d\xd9\x27\x25\xf0\xe8\x73\xce\x17\x44\xe0\x33\xc7\x87\xb0\xf2\x28\x4d\x9e\x8a\x1b\xda\x9a\x91\x29\xf3\x40\xaa\xd9\xe4\x24\xf2\x18\xf8\x4c\x20\xbe\xc7\x86\x69\xc2\xf7\x68\x92\x7b\x65\xd8\x58\x12\xf0\x74\x21\x3f\x90\xd8\xcb\xd4\xfd\xc6\xf0\xa9\x2c\x30\x4c\x93\x78\xe7\xe4\x98\x6c\x3d\x67\x44\x52\x95\x8f\x9d\x88\x04\x78\xe2\xf7\x7a\xbe\x13\x91\x2d\x26\x71\xaf\x17\x8b\x36\x9b\xb7\x47\x99\x39\x94\x48\xeb\xd2\x2a\xc1\x11\xa6\xaa\x49\x21\xb8\x79\x44\x7c\x35\x3c\xb5\x0d\xa0\x71\x71\x96\x07\x8d\x66\x36\xf6\x9a\x93\x77\x87\xde\x6c\x32\x9a\x73\x99\x48\x3c\x46\xa1\x11\x5b\xd1\xac\xb3\xa0\x20\x12\x8b\xb7\x0b\x25\x5f\x9b\xd0\x92\xed\x2a\x02\x0f\x32\x0a\xcf\x95\x7b\x3d\x83\x27\x93\x5b\x63\xcf\x77\x25\x35\x52\x93\xde\xaa\xb4\x58\x70\x91\xa9\xd7\x13\xab\xa8\x70\x18\xa1\xe0\x8c\x99\x38\x91\x37\xbb\x7d\x47\x77\x2e\xca\x68\x12\xd2\x0c\x11\x01\xac\xd9\x5b\xbb\x98\x63\xe6\x39\xc2\x1d\x2f\xa1\x6a\x8a\xa9\x9e\x53\xaa\xa7\x9a\x37\xc0\x77\xdc\x19\xe2\x65\x11\xd0\x4f\xba\xd9\xf1\x1f\xa2\x2c\x22\x48\x95\x45\x73\x71\x17\xdf\x4c\x0d\x4c\x33\x84\xb2\x04\x38\x00\x50\xb7\x8a\x29\xb1\x56\x93\x5c\x2e\xcc\x1b\x4f\xd8\xa3\xea\x92\x99\x30\xb5\x2b\x24\x9e\x98\xc2\x72\x8d\xb0\xf9\xd4\xfc\x70\x6f\x8b\x09\xbb\xf7\x70\x9a\x3b\x09\xe9\x8e\xc0\x0b\xee\x33\xfb\xe1\x01\xc3\xb7\x92\x79\xcc\xd8\x9c\x13\x94\x7b\x44\x76\xc9\x1b\xb9\x4a\x44\xb9\xe0\x75\xac\xaa\x93\x60\xec\xf2\x7f\x9b\x11\x69\x67\x57\xc7\xe4\xa9\x84\x30\x30\xb0\x2f\x34\xdb\x75\x6e\x0b\x92\x90\x5b\xb9\x56\xc4\x9b\x0b\xf9\xc1\xcb\x15\x73\xdc\xeb\x6d\x1d\xe3\x28\x43\x22\x4c\x7c\x48\x03\xfb\x8d\xc2\x29\x67\xea\xd5\x36\xa3\x4f\xd5\xcb\x50\x3c\xa9\x0b\xee\x6b\xb2\x70\xd6\x3a\x66\x3b\xc7\x2f\x47\xd0\x76\xba\xd9\xb9\xd2\x77\x83\x3a\x72\x88\xcf\xa2\xc1\x9e\xdb\x3a\x4e\x48\x7b\x0f\xe7\xaf\x5f\x72\xba\xba\x05\x0a\x7c\xb0\x89\xfd\x28\x41\x2e\xba\x14\xe4\x08\x69\x2b\xb6\x8e\x91\x8b\xbe\xcf\x62\xa4\xac\xaa\x65\x01\x7e\x2c\xa2\x37\x9b\x34\x63\x79\xe3\x6d\x25\xdc\x54\x92\x80\xc4\x64\x0b\x2e\x4b\xf6\x7b\x87\x79\xb7\x05\x2c\x2b\xf5\xb0\x81\xa7\x67\x3b\xce\x43\x7c\x2f\x83\x40\xe3\xea\xf5\x89\x5c\xd7\xdf\xf9\xc9\x15\x75\x30\x09\xca\x8c\x2b\xca\x5e\x2b\xcf\x9f\x0e\x26\x4e\x5c\xad\xa3\x88\x5e\x3a\x39\x13\x3e\x6a\x9e\x0a\x9b\x06\x8f\x92\x78\x98\xb3\x5d\x4c\x87\x7e\x1c\x7b\x08\x3c\x04\x20\x9d\xa6\xae\x9d\x3d\xb4\xe4\x67\xeb\x32\x83\xa5\x1b\x6f\xa4\xbf\x82\x38\xda\x78\x28\xa3\x01\x73\x46\xa4\x23\xff\xc7\x65\x69\xb8\xf1\x7d\xbd\xf1\x03\xea\xa1\x4d\x46\x8d\x0c\xba\x78\x17\xb1\xef\x73\x9a\x89\x2e\x78\x72\xe9\xab\xfc\x8b\xf4\xa7\xf6\xcc\x75\xde\x9e\xb7\x6d\xc8\xf1\x43\x61\x21\xf7\x6d\x94\x33\x9a\xd0\xcc\x41\x01\xb0\x97\x72\x51\x08\x43\xb9\x6c\x98\xb3\x74\xc3\xc9\xca\xbf\xf2\xe5\xa8\x2a\xdd\x08\x86\xfc\x4d\x46\x39\x20\xf9\xbc\xca\xb1\x34\x87\x86\xae\x1e\xc6\x05\x48\xf6\x2b\x9f\xf9\xf8\x36\xe9\xf5\x38\x1b\x4e\x79\xc7\xfd\x2c\x71\xd0\x16\x9e\x51\x77\x58\xda\xe1\xb4\x48\xed\xf2\x08\x93\x5a\x05\x96\xed\xa2\xe4\xaa\xf3\xfc\x59\x27\xdf\xd0\x20\x5a\x46\x41\x27\x67\xdb\xe5\x12\x61\x22\x5f\xc8\x58\x20\x84\x73\x1f\x61\x8a\x3c\x11\x02\x41\x3a\x53\x5d\x99\xef\xf7\x7a\xb7\x9c\x34\xd6\xce\xa5\x19\x73\x44\xa8\xb4\x3e\xcc\xda\xe1\x93\x6a\x9e\xaa\xad\xda\x23\xfc\x2c\x27\xf9\x3f\x48\xc7\xb5\x51\x54\xb9\x4e\x75\xe4\x60\xe7\xd5\x54\xbd\x48\xc3\x9d\xb4\x96\x00\xb6\xef\xc4\x98\x28\x6f\x72\x2f\xd2\x90\x4a\xd2\xce\x79\x7a\xc0\x67\x5d\x2c\x9a\x1c\x93\xae\x86\x41\x6f\x68\xf0\x34\x5d\xaf\xfd\x24\x94\x64\x80\xeb\x51\xc3\x79\x7a\x27\x10\xa5\x3a\xef\xfd\xbc\xb3\x4d\xf2\x6d\x10\xd0\x3c\x5f\x6e\x63\x84\x27\x5b\xaf\x3b\x2a\x02\xd0\x50\x6d\xac\xd9\xa5\xa2\x7e\x39\xbd\x00\x69\x9b\xf3\xb9\x33\x5a\x76\x3b\x88\x6c\xce\x9a\x65\xe0\x0e\x07\xe7\x4a\x8d\xf6\x7e\x2f\xe9\x9e\x96\xe3\xca\x45\x02\x39\xc2\x4d\x30\xb8\x08\x75\x87\x0e\x59\x30\xea\x5d\x92\x55\x97\x7e\x1c\xf3\xd2\x0b\x3f\x78\xc7\x01\x6c\xb2\x74\xbd\x61\x08\x93\xc8\xab\x0b\x87\xce\x83\xb5\x1f\x74\xd2\xbc\x73\xf3\x20\x1a\x32\x9a\x33\x27\xf1\xaf\xa3\x2b\x9f\xa5\x19\xac\xec\x27\x57\x7c\x67\x98\xa2\x37\xdb\x87\x7f\x1e\x7f\x89\x5c\xf4\x94\x65\x31\xc2\x7d\xd4\x7f\x8a\x4a\x95\xa6\x56\xad\xff\xe9\xf6\x4d\x7e\xff\x1d\xdd\xbd\xc9\xef\x17\x0f\xae\x40\x9e\x41\x6b\x9a\xe7\xfe\x15\x9c\xd5\xd8\x94\x0d\xe5\xa7\x8b\xf8\xe8\x40\x07\x55\xaf\xdc\xce\x9f\xb8\xbc\x53\x90\xce\xb3\x04\x5e\x88\xaa\x95\x26\x7a\x20\x16\x47\xb1\x8c\x12\x3f\x8e\x77\xb7\x41\xaf\xe7\x98\xd2\xa5\x64\x05\x81\xb4\x62\x02\x4a\x9c\x5a\x5f\x4e\x8e\x5d\x95\xf0\x24\x8e\x21\x2d\x77\x30\x08\xac\x36\xc9\x4b\x1f\x09\x8a\xe4\x7d\x47\xef\xbf\xdb\xa2\xa8\x3c\x4c\x6a\xd8\x8a\x94\x60\xd6\xb2\x71\x4c\xf8\x89\x9b\x0e\x33\xde\xfe\xd3\x74\x9b\x28\xd7\x3a\x1d\x03\x40\x31\x29\x45\x25\x0d\x46\x38\xfb\x90\x9b\x0c\x49\xe0\xc5\x0d\x68\x0f\x4c\x60\x42\x83\xa0\xde\xd8\x5c\x51\x06\xfd\x7c\xc2\x9c\x0c\x63\xe5\x70\x9f\x0d\x99\x7f\x05\x4f\xd3\x58\xfa\xfd\x66\xa3\xde\x56\x4b\x0f\xfb\xf0\x5c\x0d\xb9\xf0\xfb\xf2\xd9\x0f\x97\x4f\xbe\x7b\xf6\x04\xb9\xca\x11\x94\x74\x50\xa6\x76\x64\x06\x92\x5a\x61\x90\x42\x65\x78\x89\xd1\x2b\xf4\xd4\xcf\x28\x3c\xb4\xa5\x43\x3e\x5f\xbd\x5e\x53\x05\xb3\x37\xfb\x7d\xd2\x2c\x52\xd1\x92\xdd\x30\x61\x68\xca\xd7\x9c\xf4\x47\x52\x14\x0d\x4a\x4d\xa7\xf6\xc6\x69\x92\xd8\xf6\x05\xfa\x74\xcf\x5c\xf1\x40\xb5\x41\xca\x80\x7d\x8b\x0e\x9f\xbe\x7e\xcd\x91\x7f\xfa\xfa\xf5\x90\xe6\x81\xbf\x51\x3a\xa8\x8e\x99\x36\x11\xf3\x57\x7f\xd3\x5d\x7b\xd2\xdd\x78\x4e\xf9\x7f\x25\xa4\xff\xd7\xc9\xe8\x7f\xb6\x51\x46\xc1\x47\x82\xaa\x3e\x44\xe5\x01\x94\xd3\x83\x70\xbf\xe0\x50\x4c\x32\xfd\x6c\x90\xa4\xde\x60\x0c\x51\x91\xc1\xfc\x32\x58\xf9\xd9\xd3\x34\xe4\xf4\x30\xc2\x93\x7e\x3f\x7d\x94\x4d\xf0\xa8\xeb\x39\xcc\xce\x4c\x31\x9e\x46\x7d\x8f\x3d\xf6\xc6\xbd\x1e\x7b\xe4\xfd\x79\xbc\xdf\x8f\x1f\xfe\xc5\xf3\xd8\x7e\x3f\xf2\xbc\xb4\xd7\x63\x8f\xbd\xcf\xbe\x84\xbc\xcf\xff\xb2\xdf\x8f\x6b\x69\xbd\xde\x67\x9f\x7b\x9e\x3f\x45\x6f\xde\xa0\x3e\xd3\xce\x21\x9c\xf1\x17\xb8\x8f\x3a\xc8\x15\x50\xc6\x70\xc7\xc9\x4b\xb2\xfd\xbe\xeb\xf0\xf6\x1e\x7e\xb9\xdf\xcb\x84\xbf\x8a\x3f\x76\x53\xec\xb1\xf7\xc5\xe7\xf0\xf5\xd7\x11\x7c\xfd\xf5\x2f\xf0\x35\x7e\xf8\x10\x8b\xd6\x44\x4f\xa0\x17\xae\xf9\x3b\xea\x7b\xe8\xcd\x76\xb9\x5c\x86\x9a\x77\x45\xc5\xc4\x9c\xb8\xfd\x5e\xcc\x2d\x48\x8b\xe6\x54\x7a\x8c\x4b\xce\x09\x2e\xc4\x69\x5c\x1c\xd0\x13\x67\xfc\x57\x7c\x92\xbc\x0b\x4b\xde\xd0\x46\xaa\xeb\xa2\x9a\x46\xcf\xbe\x5f\x2e\x55\x98\xa6\x9b\x15\x31\x90\x7c\x3a\x9d\xcf\xbe\xe0\x92\xeb\x49\x7a\x41\x12\x78\xdd\x5c\x20\x7f\xab\x60\xc0\x2b\xc6\x82\x20\xf5\x8d\x30\x89\x3d\x59\xc8\x7c\x51\x5d\x60\x82\x34\x74\xc4\x77\xaf\x59\x59\x87\x57\xff\x36\x0d\xfc\x98\xea\x04\x38\xa8\xbe\x5c\x22\x82\xec\xfe\x20\x82\xa2\xdc\x50\x0a\x21\x00\x5b\x43\x95\x9f\x3e\xcb\x43\x34\x9a\x93\x4d\xc3\xce\x65\x29\xd7\xb5\xe5\xa9\x75\x16\xe7\x7c\x06\xde\x5e\x7d\xe2\x6f\x36\x71\x14\x80\x88\xf9\xd4\x0f\x56\x70\x0c\xff\x44\xee\x9b\xf0\x9b\xde\x30\x9a\x25\x7e\x0c\x1f\xcb\xcc\x17\x8f\x37\xc5\x2f\xc9\x70\xcb\x84\x1c\x7e\x1a\x4f\x08\xca\x6f\x30\x56\x87\xcf\x34\x59\xa7\x3f\x2d\xb7\x71\x9c\x07\x19\xa5\x89\x78\xde\xdd\x94\x03\xdb\xb6\xc8\x28\x6d\xd8\xcb\xef\x12\x22\xbc\x8b\x79\xb9\x5c\xe6\x94\xe9\xef\x1f\xad\xef\x4c\xa1\x59\xda\xb5\x1b\x9f\x97\xe9\xc6\xf8\xfa\xc1\xf8\xfd\xa3\xf8\x4d\xe3\x25\xfc\x10\x67\x05\xb0\x2c\xa1\xe1\x57\x7f\x33\xd2\x5e\xb3\x34\xf3\xaf\xe8\xf3\x64\x99\x8a\x54\xd8\xa0\xdd\xee\xc8\x7a\xc0\x56\x7d\x93\x56\x0a\xea\xd2\x22\x5e\x07\x80\xd1\xc1\xaa\x3a\x51\xa2\x32\xe5\xb1\xac\xbb\x9c\xa1\x4f\x50\x9f\xce\x7b\xbd\x54\x50\xa4\xc8\x27\x14\x6b\x05\x8f\x48\x99\xf1\x32\x86\x13\x07\xab\xad\x19\x9d\x03\xc4\x8d\x53\x7e\x4b\xc1\xab\xd4\xfb\x8e\x8a\x86\x24\xed\x18\xd3\xc1\x93\xac\x81\x00\x0d\x1f\x1a\xb5\xb6\x29\x49\x3c\xed\x25\xe7\x6b\x59\x75\x8e\xc0\x73\x89\xf4\x8e\x43\x32\xcf\xe7\x7f\x72\x8f\xf5\x7a\xba\xac\x58\x42\x95\x92\x4b\x6f\x36\x07\x0e\xc2\x7a\xbd\x6e\xd2\xeb\x75\xb3\xe6\x0d\xc3\x60\x30\x52\x5f\xdb\x49\x93\x8e\xdf\x49\xd2\x64\x20\x51\xc4\xd2\x94\x28\xee\xf5\x12\x0e\x32\xe7\xbb\x98\xba\x01\xed\xf5\xba\xa9\xba\x3e\x18\x61\x6d\x26\xb3\xf0\x46\x93\xc5\x23\x55\x6c\xd2\xef\x2f\xf0\x52\xc8\x17\x92\xa5\x2f\x30\xc8\x34\x99\x09\xab\x34\xb2\xf1\x46\x93\xb5\x59\x7b\x5d\xa9\xbd\xc6\xf2\x55\xa9\xaa\x71\x01\x3a\x5e\xbc\xea\xf5\x0c\xa6\xe3\x79\xde\xc5\x7e\x5f\xe2\x77\x81\xf7\x7b\x1b\xce\x85\xc0\x22\xd0\x2d\xd7\x7c\x20\x1d\x20\xc9\xfd\xbe\x1b\xaa\x2d\x7c\x03\x77\x61\xd9\xee\xd6\xf8\xae\xd1\xc7\xb8\x28\xf8\xd4\xec\xbc\xd1\x64\xf7\x68\x5b\xf6\x6e\x87\xaf\x7a\x3d\x8b\x7d\x79\x9e\xb7\x9d\xed\xe6\x26\xf2\xfc\xbb\xc4\x1f\xbe\xb4\x8a\xb3\x28\x4a\xb1\x23\x3b\x49\x97\x72\xa7\x3b\x4f\xc5\xbe\x2f\xfd\x2b\xd2\xb0\x0f\xe9\x5d\x26\x6a\xb0\xfe\xe8\xc2\x54\x37\xd2\x7d\xaf\x57\x87\x2f\xa6\xd3\x20\xf2\x27\x4a\xfc\x01\x3a\x57\xa3\x82\x0b\xe2\x37\x35\xd6\x8d\x1c\x8a\xf7\xfb\x83\xcb\xad\xd7\xab\x1b\xf0\x95\x1e\x3f\x34\x55\x7a\x23\x0b\x8b\xcc\xdf\x81\xef\x2a\x8d\x81\x91\x6b\x2d\x5a\x55\x00\xfe\x50\x8e\x69\xde\xe0\xf6\x20\x72\xb4\x5c\x87\x39\xd3\x88\x86\x51\xfe\x2d\xbd\xf2\x83\x9d\xee\xb0\xe7\x1b\x42\x65\x3e\x8d\x5c\xff\xa4\x19\x6e\xba\x23\xe2\x63\xd1\xae\x08\x93\xa5\xe0\x22\x48\xbc\xae\x60\xd3\xf1\x03\xbe\x23\x8e\x1f\x30\x17\x42\xd0\x70\x79\xab\x9b\xc1\xd8\x76\x33\x87\x61\x5c\x9c\xa8\xb9\x1b\x8f\x3e\xc7\x24\x55\x36\x21\x86\xab\xba\x1b\x1a\x90\x96\x4b\xcf\x52\xa5\x49\xfc\x03\xd4\x96\x7f\x30\x31\x37\x8e\x88\xb8\xe4\xa4\xd6\xed\x9e\xf6\x22\xa7\x37\x23\x78\x68\xad\xcc\xc8\x15\x1d\x88\x5e\x02\x15\xf8\x8a\x4c\xa4\x5c\x1f\x39\x94\xa0\xd8\xcf\xc5\x4e\x59\xfa\x2f\x76\xba\x4c\x0c\xa9\xba\xa5\xc4\xb8\xd7\xb3\xdc\x34\x64\x3b\x2d\xc4\xe8\xfa\xa5\x1c\xaa\x93\xbc\x11\xd1\xa4\x49\xb4\xbe\x20\x31\x78\x90\x3a\x0c\x9b\x95\xe0\x91\xf5\xc9\x93\xf9\xe7\xcf\xb1\x31\x64\x99\x68\x4e\x11\x3f\x7c\x91\x23\x42\xea\x69\x0a\x5f\xa4\x61\x96\x70\x16\x51\x12\x1a\x1b\x55\x94\x88\xe7\x9d\xd1\x22\xa6\x1d\x44\x52\x0f\x56\xa8\xf9\x4c\x25\x8e\x02\x7a\x48\x26\x6e\x99\x7c\x31\xd6\x5c\x64\x9f\xb4\xdd\x19\xed\xf7\x0d\x2b\xbf\xab\x37\xe1\x96\x1b\xf1\xac\x6f\x5c\x01\x26\xc4\x57\x8c\x42\xf3\x01\x32\xc6\x36\xab\x90\x8e\x33\xcc\xdb\xf6\x44\x5f\x84\xcb\x3b\x3e\x38\x5b\xf8\xea\x86\xaf\x0a\x12\xeb\x57\xf8\xd2\x18\xc3\xc9\xc0\x52\x74\x2a\xfd\x99\x6a\x1f\x2c\xea\xc2\xf0\x10\xa4\x82\x04\xe5\x93\xc6\x11\x51\xd7\xf3\x03\xe5\x21\x81\x9f\x07\x66\x73\xb2\xf5\x46\x93\xed\xa3\x00\xfc\x25\xc4\x62\xd3\xe2\xb2\x99\xf0\x84\x90\x78\x6a\xc4\x1c\xc4\x67\x94\x66\x88\xa0\x8a\x46\xa3\xe3\xa0\x7e\xac\x3c\xa9\x81\x23\xb5\xdb\x8e\xba\xf2\x84\x2a\x56\xd7\x35\x82\x93\x4e\x81\x30\x04\x7a\x2b\x27\x5b\xb9\x5c\xb0\x94\x25\x06\x1b\xf2\xcc\xcb\x38\x83\xda\xe0\x36\x76\x43\xcc\x92\xa6\xe6\x22\x39\x79\xc1\x7c\x01\xce\x7a\x9c\xf1\xe8\x4b\x4c\x22\x7e\x06\xfb\x0b\x16\x67\xb1\x2f\xf9\x5c\x27\xce\x78\xfc\x10\x93\xc0\x4b\x9d\x08\x4f\x32\x27\x20\xb7\xe0\x1f\x2e\xde\x2d\xa3\x38\x76\x7d\x12\xad\x37\xe2\x3c\x01\xa7\x11\x37\x22\xf9\x2a\x5a\xbb\x39\x9c\x37\x15\xf1\x06\xa7\x2f\x5e\x89\xcb\x5f\xb1\x83\xee\xa9\x79\xb8\x07\xca\xbe\x54\x8c\xa9\xa6\xca\xa6\xc5\xa1\x37\x0a\x35\x01\xbe\x31\xfa\x45\x89\x91\xc8\x3d\x50\x2f\x32\xeb\x9d\x84\xbd\x5e\x45\xa5\xf8\xd1\xb6\x65\xc0\x8b\x1e\x90\xe2\x53\xe7\xb6\x20\x08\x29\x71\xec\x02\xdf\xa6\x62\x16\x85\xca\xdd\xc0\xaf\x5c\xae\x19\x97\x2b\xd2\xa9\x99\x57\xca\x76\xa5\x26\x46\x6c\xed\x24\x92\xa0\xa9\x55\x2c\x35\x96\x34\x12\x25\x11\xe6\xf8\x56\xe5\xc2\x4e\x54\x14\x85\x83\xf9\xb4\x02\x29\x8c\x30\x5c\x21\x35\x1a\x71\x98\x26\x11\x4d\x06\x11\x05\x89\x95\x7f\xf4\xad\xd7\x28\xbb\x7e\x1f\x25\xec\x4b\xe0\x92\x53\x51\xd0\x0d\x9c\x32\x0d\x93\x8d\x77\x8b\xee\xc1\xef\x7b\xc8\x85\xbf\x44\x7e\xff\x6d\xbb\x5c\xd2\xec\x1e\x72\x1b\xe1\x1a\x45\x14\x60\x23\xc9\x86\xa1\x3b\x74\x37\x60\xc6\x62\x95\x60\x9f\x4b\x6b\x3c\x13\x70\x3e\x0d\x9c\xd9\x7c\x56\xb1\xd7\x9b\x3b\x18\xab\x5b\x48\x59\xd9\xac\x54\xd9\x3e\xac\x22\x6f\x69\xc2\xb2\x88\xe6\xf5\x62\x43\x99\x63\x17\x97\x3a\xc8\x86\xe2\x32\xc7\x2e\xce\x8f\x60\x0d\x65\x79\xb2\x5d\x10\x04\x84\xa6\xa2\x22\x83\x17\xce\x77\x49\xf0\x75\x96\xae\x5f\xef\x92\xa0\x69\x6c\xca\x01\x80\x92\x9a\x07\xb4\x64\xb4\x57\xd5\x06\xcb\xed\x39\xad\xd0\x75\x89\x76\xf0\x4d\xb8\xc7\xbd\x5e\xae\x8f\x0c\xbe\x59\x6a\x1a\xcf\x9a\x92\xe7\x8e\x39\xe3\x2c\x5d\x47\x41\xde\x4a\x78\x22\x5b\x13\x9d\xf8\x24\xe8\xde\xdf\xc4\x0b\xc2\x7b\xc8\x95\xbf\xca\x34\x13\x39\x99\x64\x51\xd0\x57\x3e\xf3\xff\x19\xd1\xf7\x6d\x6d\xaa\x7c\xd5\xa8\xfa\x36\xaa\x1e\x5d\x30\x6d\x30\xaa\x88\x70\x00\x22\xf0\x3d\x7c\x99\x70\x21\xd4\xa2\x59\x3c\xa4\x41\x1a\xd2\xef\xbf\x7b\x7e\x0f\xb9\xfa\xb7\x99\xae\xcd\x00\xcc\x02\x3a\x91\xa0\x7b\x34\x29\x21\xe8\xdf\x66\xba\x09\xa1\x9e\x48\xd0\x3d\xe0\xf6\xf7\x90\x2b\xb8\xbe\xfc\x36\xb1\x86\x04\x0b\x6d\x7a\xed\xc7\x1c\xdc\xb5\x1f\xf3\x0a\xd7\x7e\xac\x81\xa8\xdf\x66\xba\x05\x4c\x25\x5a\x00\xbf\x8e\x53\x9f\xfd\xf9\xa1\xe2\x89\x8d\xe3\x6f\x96\x51\x73\x60\xa6\x55\xc0\x1c\x9d\xcf\x63\xf0\xea\x08\x7e\xf1\xd9\x71\x04\x65\x19\x0b\xa0\x4c\xab\x80\x39\x0d\xc1\x03\xf0\x6c\x04\x4b\x16\xa0\x7e\x1a\xa9\x66\x5b\x75\x89\x9f\xa0\x7b\x8d\x4c\xe6\x20\x7f\x39\xcc\x5a\x9e\xab\xdd\xae\xad\x73\xcf\xab\x5b\xa4\x4e\x30\x6b\x1f\x1d\xa3\x76\x30\x56\xf7\x9e\x27\x6c\xfc\xc5\x31\x7c\x64\x09\x03\x92\x4c\xb1\x00\x9c\x82\x52\x1d\x52\x33\x4e\x47\x28\xbe\x2c\x61\x40\x2a\xa9\xbd\xfc\x38\x05\xa7\x56\x48\x16\x52\x51\xfe\x75\x94\x44\xc0\xc3\xd4\x4f\x48\x7d\xe1\xbf\x80\xa4\x17\xfe\x0b\xde\x72\x8b\x2c\xd0\x26\x0d\x18\x9b\xc3\xff\xff\xf5\x4b\x0e\xa9\xae\x2c\xe2\x19\x53\xfe\x8f\x5d\xf6\x95\x9f\xe5\xf4\x70\x85\x21\x04\x2a\x29\xab\x5d\xf8\x9b\xb6\x71\xb8\xf0\x37\x6a\x00\x2e\xfc\x8d\x28\xdb\xd4\x99\xc6\x17\x21\x17\xfe\xa6\xd7\xe3\xdd\x74\xb8\xfc\x7a\xe1\x6f\xf0\x61\xc9\xe7\xc2\xdf\x1c\x9d\x18\x1b\x21\x6b\x2a\xf8\x01\xf0\x1e\x72\xf9\x1f\x82\xee\x89\x50\xc4\xf7\x90\x2b\x7e\xe8\x14\xb3\x05\x91\x62\x01\x11\x12\xee\x3d\x24\xad\xec\x74\x8a\x59\xad\x7a\x6e\x17\x85\x84\x20\xa4\x8e\xf0\x0d\xc5\x4a\xf5\x90\x51\x5e\x5e\x31\x35\x15\x97\x59\x04\xdd\x83\xf9\x02\x4e\x76\x0f\xb9\xe5\x87\xca\x79\x9e\xe8\xf4\xe7\xb0\x43\xbd\xca\xd2\x75\x94\xb7\x8e\xa1\xcc\x56\xe3\x28\x3f\xcb\x7a\x47\x27\xa1\x19\x80\x35\x20\x26\xa8\xb7\x6c\x45\x93\xbb\xc2\x1a\xf2\xca\x25\xc0\xb7\x7e\x1c\x9f\x09\xca\x8f\x63\xa3\x7e\x46\xe5\x04\x9f\x03\x42\x54\xb2\xa0\xe4\x69\x7c\x7d\xee\x00\xc9\x5a\x02\xce\x4d\x2b\x1b\x83\x4c\xa3\xee\x0d\x67\x5e\x60\x23\xa0\xa4\x86\xf2\xc3\xca\x31\x27\xae\x4c\xb5\xe6\xc5\x36\xa1\xe7\xe5\xac\x84\x5a\x09\x0b\xa4\x95\x53\x05\x1b\x1f\x18\x56\x99\xad\xfa\x24\x3f\xa1\xde\xd5\xb3\x9b\x0d\xc0\xe6\x3f\x74\x8a\xdd\xac\xad\xa0\x25\xe8\xde\x6b\xda\xda\xd4\x6b\xaa\x9b\x79\x4d\x99\x28\x7b\x32\xc7\x7a\x4d\x99\xc1\xb1\x5e\x53\x76\x84\x63\xbd\xa6\xec\xe8\x62\xb1\x11\xb2\xbb\xb1\xf2\x33\x1a\x9e\x70\x90\xad\x15\xd4\x10\xab\x19\x4d\x50\x8f\xa3\x78\x32\x78\x1b\x7d\xc5\xe9\x34\x5b\x13\x3f\xda\x76\x3b\x84\x8e\x8c\x26\xd4\x36\x6b\xc9\x40\x1c\x56\xa3\x00\x01\x20\x8a\x9f\x46\x7d\xf8\xb6\x5b\xad\xbe\x4f\x33\x4b\x27\xcc\xbf\x51\xcb\xc0\xf8\xb2\xf3\x2c\x74\xca\x64\x0b\xa7\xcb\x55\x96\xbe\xd7\x8a\xa0\x7b\xc8\xf5\x79\xe2\x6e\x23\x87\xee\x1e\x72\xb7\x56\x82\x09\x73\x3b\xdd\x36\x61\x67\x42\xcb\xcc\x6f\xb3\xae\x8d\x45\xa9\x31\x69\x9b\xe7\xba\x9e\xa5\x4c\xb1\x00\x1c\xa5\x98\x43\x90\xea\x48\x3d\x8d\xfd\xb5\x31\x18\xed\x10\xcd\x82\x16\x60\x33\xa3\x09\xea\x69\x08\x9f\x04\xbe\x86\xfe\x11\x41\xd8\x28\x62\xc2\x2c\x45\x61\xe3\xeb\x24\x34\xdb\x81\xd5\x50\x3b\x22\x0f\x1b\x45\x4c\x68\xa5\x44\x6c\x7c\x9d\x84\x5a\x3b\x30\x1b\xb5\xef\x9e\x2b\xda\x55\x3f\x8d\x54\xb3\x25\x95\x66\x55\xff\x17\xf5\xdf\x1d\x90\x49\x65\xb6\x42\x42\x7e\x96\xf5\x8e\xf6\xa4\x19\x40\x0d\x85\x03\x9b\x8c\xcc\x36\x21\x88\xcd\x46\xfe\x3a\x09\x85\x3a\x80\x12\x85\x82\x2c\x85\x5e\xbc\xe9\x22\xab\xca\x15\x95\xdd\x2a\x26\xa1\xf7\x60\xf6\xbf\xf7\x86\xb3\x37\xf3\x79\x7f\xff\x66\xe6\x4c\x5d\x67\x30\x7d\x13\xf6\x9d\xa9\xfb\x66\xf8\x26\xec\xe3\x29\xde\x3b\x33\xf4\xe9\x1c\x3b\x3c\x6f\xda\x7d\xf3\x10\xcf\xfe\xf7\xcd\x9b\xf9\xfe\xcd\x9b\x21\xbe\x3f\xc5\x6f\x1e\xe2\x37\xf3\xbd\x33\xf5\xa0\xc6\xfe\xcd\xec\xcd\x1c\x97\x3f\xf7\xf7\x3e\xc1\xf8\xc1\x15\x59\x79\x0f\xde\xbc\x71\xde\xbc\xc1\xd3\x07\x57\x64\xd1\x70\x47\x35\xd3\x2f\xc1\x96\x0e\x25\xa1\xe5\xd4\x3a\x11\xce\x15\xd9\x4c\xdd\xd2\xcc\xbd\x6c\xba\x74\x52\xb2\x22\xe8\x93\x31\xc2\x6e\xb2\xdf\x53\xe9\xdc\x6d\x5d\x7f\x2b\x2b\xde\x78\x76\x36\xe6\x4d\x96\xc1\x97\x1d\x14\x25\x7c\x78\xf2\x28\xe8\xa0\x3e\xed\xa3\x4e\x98\xd2\xbc\x93\xa4\xac\x43\x6f\xa2\x9c\x75\x45\x84\x9e\xc6\x49\xd9\x80\x05\x4e\xd7\x7c\x6e\xd5\x00\x0f\xc0\xe4\xa4\xb3\xd8\xb2\x4e\x24\x20\xfb\xd7\x7e\x14\xc3\xa3\xd5\xce\xab\x98\xfa\x39\xed\x2c\xa3\x98\x76\xfc\xa4\x13\xe5\xf9\x96\x76\xcb\xe7\x86\xbc\x89\xf6\xdb\xee\xe6\x40\x45\x60\xa9\xa8\x03\x7f\x34\x9b\xcc\x94\x48\x26\xfe\xda\x0c\x4b\x94\xa4\xc9\x80\xae\x37\x6c\x67\x05\x28\xaa\x1a\x6e\x3e\x1e\xf7\x7a\xda\x21\x99\x71\x9d\xd8\xd8\xd8\xa7\x08\xc2\x36\x5c\x44\x79\xce\x01\xea\xbb\x07\xa3\x55\x09\xea\x53\xe3\x56\xd1\x5b\x38\x14\x93\xc8\x5b\x3b\xe8\x1e\xea\x3b\x89\xb6\xb0\x99\x26\xb3\xd1\xdc\x45\x08\xf7\xd1\x3d\x44\x18\x26\xbe\x37\x9e\xf8\x8f\x54\x81\x89\xdf\xf7\xc6\x58\x3e\x92\xee\x7a\x11\x16\x6e\xd1\xfc\xfe\xf8\xb1\x36\x0e\x55\x8e\xd8\x53\x27\x22\xc9\xcc\x9f\x63\x6d\x65\xe4\xf0\xcf\x28\xe9\x44\xd8\x9e\xd4\x05\x9f\xa4\x72\xd0\x96\x69\xd6\x30\xbb\x6c\x45\x3b\xca\xae\xaf\x3e\xd5\x7c\x24\xbd\x7c\x0a\xa1\x2f\xf7\xfb\x5c\x1c\xd7\xdc\x68\xc6\x5b\x9c\x8b\xc7\x0f\x91\x27\x3f\x4b\x33\xcd\x23\x77\x4a\x35\xe3\xde\xcc\x63\x43\x21\xc3\x88\x1b\xb2\xf1\x18\x1f\xba\x00\x6b\x32\x3b\xc8\x2a\x16\xe6\x55\x73\x04\xa7\x6e\x8f\x90\x39\x68\x99\xa6\xe0\xea\xbf\xcd\x58\x81\x8f\x61\xc6\x4b\xa4\x0e\x06\xd7\x45\x67\x5b\x94\x36\x76\xa3\xe5\x62\x5b\xb4\xb9\xdf\x37\xe5\x1d\x7c\xc1\x6e\x5a\x45\x1c\x75\x9c\xa0\x4a\x0b\x17\x0f\xd4\xbb\x2d\x08\xf3\x54\x77\x19\xcd\x19\xc2\x44\x39\x2d\x70\xc4\xf3\xf9\x86\x58\xa7\x76\x9b\xda\x22\x0e\xc0\xc0\x65\x7c\xab\x62\x40\x5f\xd2\x7f\x20\x84\x04\xdb\xa6\x89\xe2\xb5\xf1\x8c\xcd\xbd\xcf\x1e\x12\xdb\x52\xa4\x89\x30\x0c\xfb\x3b\x11\x0c\xd7\xf6\x3f\x60\xc7\xef\x3a\x0a\xc6\x9e\x17\xf0\xf5\x62\x41\x6d\xc8\x6f\x6a\xe4\x34\xd7\x0f\xd1\xd2\x19\x77\x3d\x2f\x93\xd5\xf7\xfb\x6c\x36\x9a\xc3\x13\x5a\xcb\x3c\xe6\x2c\x0f\x04\xd5\xf9\x38\xb5\xab\xe5\xc5\x6f\xc5\x4c\xfa\xa0\xd7\x09\xde\xc4\x67\x0f\xc1\x9a\x0b\x38\xca\x7e\xdf\x1d\xc1\x57\xf9\x10\x5c\xa3\x53\x94\x76\x9f\x27\x5f\xfa\x0f\xf3\xed\x06\x56\x9d\xf1\xec\x13\x58\xcb\x67\x60\x07\x70\xb2\xd5\x93\xfd\x08\x94\xe4\xc6\x45\x78\xcb\x3d\x31\x89\xbd\x07\xfe\x83\xd6\x65\xdf\xcd\xf6\xfb\x6e\x60\xb0\xe9\xdc\x41\x35\xdb\xac\x65\xec\x5f\xe5\xc6\x23\x82\x0e\xcb\xb6\xb4\xf3\xec\xf5\xe7\x1d\x9a\x5c\x47\x59\x9a\xc0\x46\xc4\x56\x3e\xeb\xa8\x7e\x96\x2c\x3c\x2c\x7b\x2c\x0d\x48\xa9\x97\x3a\x98\x30\x2f\x70\x62\xbe\xb2\x23\x87\x11\x04\x4d\x94\x3b\x76\xd2\xeb\x81\x87\x61\xbe\x05\xef\xf7\x7e\x59\x02\x5e\x48\x5b\x8f\xf1\xcd\xa7\xfa\x63\x72\x45\x99\x4b\x0b\x4c\xe8\x69\x93\x63\x5f\x75\x89\x80\x20\xbb\x23\x26\x8d\x3f\x93\x91\x99\xdc\x4a\x9a\xcc\x13\x4b\xeb\x45\x27\x9a\x56\x6d\xc1\xb4\x2d\x45\xcd\xd6\xab\x6a\x6f\xea\x6a\xa6\xc6\xbb\x6d\x9b\x4f\xe2\xa6\x47\x2f\x05\x39\xe2\xdd\x47\x53\xb8\xb0\x24\xf9\x5c\xd8\xb4\x8c\x3f\x17\x36\x2d\x23\x30\x69\x19\x26\x8e\x8f\x49\xc0\xd3\x31\x89\xe1\x3b\xc0\x64\xcb\x69\x1f\x93\x0d\x7c\x6f\x31\x08\xde\x0f\xb9\x28\x9d\x38\x0f\xc7\x98\xac\xbc\x5b\xf5\x84\xdc\x8d\x87\xfe\x30\x49\x43\x4a\x02\x15\x13\x0b\x92\xc4\x16\x40\x82\x38\xcd\xe9\xd3\xd6\x9c\x27\x59\xe4\x83\xa7\x26\x2b\x27\x97\x6e\x81\x20\x51\x8c\x09\x01\x9f\x9f\x66\xa9\xa5\x1f\x8a\x02\x5c\xae\x22\x51\xfe\x72\x23\x91\x81\x6f\x11\xed\x0d\xbe\xf9\x10\x11\xe6\x5f\xb9\xcb\xe1\x3b\xc2\x32\x3f\x91\x3e\xa0\x01\xd6\xca\xdf\x50\x27\x1c\xfa\xc0\xec\xf8\x6a\xcd\x31\x01\x63\xff\xef\xe8\x52\x34\x9f\xd0\x97\x4b\x9e\xe1\xcc\x0c\x6c\x0c\x3c\x54\x13\x73\x5c\x90\x85\x77\x2b\xf0\x44\xf2\x85\x23\x52\x88\x75\x47\x80\x02\x0a\xa3\x6b\x54\xed\x3a\x7a\xca\xbf\x91\xe8\x11\x2f\x58\xe2\x28\xb7\xd5\x68\xe8\x63\xe7\xb6\x20\x1c\x51\xf3\xbd\x36\xb9\xdd\x26\xeb\x74\x9b\xb0\x97\xc9\xb3\x9b\x88\x81\xc3\x8b\xa2\xf4\xb8\xb4\xb6\x5e\x54\xa8\x49\x20\x09\x7c\x99\xf3\x42\x7c\x95\xa4\xb1\x22\x01\x4f\x52\x33\x41\x62\x8f\x0e\x99\x7f\x45\xb6\xf0\x36\x23\x4e\x33\xb2\xf2\xe8\x50\x74\x8e\x2c\x78\x26\x0c\x38\x59\x7b\xa5\x27\x02\x72\xc1\xd3\x75\x67\xc8\x95\x47\x87\xbc\x8f\x64\x07\x5e\xb5\xc4\x20\x93\x6b\x25\x3b\xa4\xbc\x93\x94\xcc\x90\xc6\x14\x11\x64\xe3\xa9\x12\x34\x96\x3c\x21\xd7\x8e\xaa\x10\xf3\xaf\xe0\x7d\x49\x9c\x66\xf0\x1c\x85\x63\x87\x74\xe8\x3f\xc3\xef\x01\x41\x25\x5e\x88\x20\x8e\x15\xaf\x20\x71\x42\x73\x4c\x9e\x28\xb4\x96\xc3\x15\x76\x36\x0e\xe6\x4c\xce\x8f\x69\xc6\x90\xfc\x3b\x40\xfd\x2d\xb9\x95\xbf\xc3\x28\x5f\x73\xd9\x7f\x11\x53\xe4\x2e\x0a\x4c\x02\x4c\xde\xd6\x40\x08\xec\x11\x49\x20\xff\xbd\x77\x74\x7a\x0b\x72\x41\x6e\xb9\x5c\x2e\x42\x9f\x5d\x4d\x2f\x86\xe5\x17\x42\x84\x45\x6b\x9a\x6e\x19\x64\xa8\xdf\xa3\x42\xf3\xe9\x7c\xe8\x57\x5e\xaf\x87\x43\x9f\x28\xd3\x42\xd9\xea\x35\x79\x4f\x6e\x39\x71\xc6\xc6\x12\x7e\x42\xa2\xc4\x5d\x91\x2c\x8d\xa9\xab\xba\xad\xd7\xc5\xae\xc0\x64\x31\xad\x03\x47\x8b\x2d\x63\x7c\x40\x45\x80\x70\xfd\x59\x82\x7d\x4b\x90\x9f\x45\xfe\x00\x3c\x5a\x22\xd7\x27\xca\xd5\xc1\xa2\x20\x0d\xf0\xe0\xa9\x3d\x1f\x63\x5e\x67\x15\x85\x21\x4d\x90\x8b\xf8\xf6\x86\x0a\x82\xde\xdc\x84\x7f\x41\x18\xcb\x60\x6e\xb8\x58\x97\x8b\xd8\x5b\x91\xb5\x35\x94\xde\x82\xb0\xa1\xef\xad\x4f\x95\x09\x2c\x8e\x39\x12\xe1\x0d\x12\xe1\xea\x05\x38\x65\x00\xdf\x39\xb0\x4c\xce\x29\xb7\xf0\x1d\x03\xcb\xe4\x9c\x72\xe9\xc1\x90\x6e\x86\xef\x48\x1e\xfd\x44\xdd\xc0\x64\x7c\x6a\x34\x82\x26\x9e\x17\x68\x2e\x63\x07\x8e\x6a\x5d\xc9\x7a\x8d\x46\x72\x8d\xe6\x1e\x1d\x42\xdc\x9f\xe0\xf0\xd2\xaa\x2d\x1c\x70\x44\x3f\xe7\x7d\x92\xf5\x36\x9c\x70\xb7\x82\xf6\x21\x52\xf8\xe0\x2a\x4b\xb7\x1b\x44\xf2\xa9\xf9\x3d\x40\x7d\x11\x34\x0f\x93\x44\xd3\x9e\x5f\x9b\xce\xa8\x4a\x79\x01\xb9\x35\x36\x8d\x02\xe3\x62\x12\x1a\x73\xb8\x24\xa1\x3d\x87\xb7\x9a\x85\x16\x30\x9b\xe1\x2f\x37\x9b\x89\xf3\x39\xec\x7f\x7a\x56\xfd\x30\x4c\x13\x8e\xa7\x98\x30\xbe\x4b\x38\x33\xb4\xc9\xe8\x86\x26\x21\x67\x11\xf0\xb2\x1e\xcd\xf1\x30\xca\xbf\x13\xa2\x59\x48\xf4\xa6\x19\xd4\x37\xcd\xa3\xc4\xb0\xba\x33\x31\x68\x5c\x05\x53\x57\xec\x39\x3e\x93\x3c\x34\x98\x8a\x07\x99\xf0\x08\xb9\x70\xf2\x30\x28\xa3\x7e\x3a\x0c\xa6\x27\x10\x4b\x6c\x12\x4b\x58\x60\x52\xaf\xb3\x1c\xfa\xa4\x14\x4c\x82\x02\x63\xf7\x6c\xc0\xc4\xaa\x5f\x4c\x56\x06\x41\x86\x64\x75\x98\x20\x57\x77\x22\x48\x69\x63\x3c\x7e\x28\xe8\x71\x54\xa1\xc7\x71\x85\x1e\x3f\x03\x7a\x1c\x26\xce\x46\x0a\x64\xb6\x3c\xb6\x55\xa4\x05\x3c\x78\x5b\x52\x15\xf0\x21\xe3\x7b\x91\xbf\xae\xa4\x5c\xfb\x71\x14\x42\x82\x90\xa9\x92\x4a\x02\xef\x6d\x38\x7c\x57\x6e\x04\x5b\x5b\x40\xda\x96\x02\xd2\x56\x09\x5e\x25\xf8\x39\x26\xe0\x0a\x86\xd1\x1b\x56\xc2\x04\xa2\x2a\x3f\xcb\x99\xd8\x36\xad\x87\xad\xb1\x1e\x16\x6d\xbe\xbc\xf4\x13\x70\xe9\xb5\x0c\x16\x86\x56\xc3\x30\xbc\xdf\x43\x5c\x56\x78\x3f\x4f\x97\x22\x96\xcd\x77\x74\x29\x62\x32\x99\x5b\x72\x02\x0e\x0e\xe1\xdd\xb9\x27\xff\xb6\x14\x2a\x64\x8a\xcf\x53\xc0\x47\x87\x0c\xb4\x59\x9e\x51\xf4\xd9\x49\xb5\x6b\x9d\x14\xb4\x9b\x27\x2d\x18\x49\x37\xeb\x76\x22\x3f\x40\x40\x72\x46\x97\x1e\x38\xb1\x15\xd8\x59\xc6\xd1\x22\x5b\xd6\xcf\xe8\x52\xbf\x9c\x27\xc9\x50\xb8\x9b\xaa\xbb\x33\xb0\xfc\x4c\x1d\xe1\x2a\x9c\x91\x70\x81\x51\x10\x10\x70\x18\x20\x14\x10\x12\x25\xd1\x80\xa0\xc8\xf9\xcf\x46\xf1\x1f\x10\x18\x35\x01\x80\xcc\xa8\x65\xc0\xf5\xe9\x9c\x48\xb0\x1f\xd1\xb4\x78\x8d\x1c\x85\x20\xba\xa9\x5f\x06\xaf\x42\x04\xe9\x06\x2b\xe2\xdd\x85\x37\x43\x99\x1f\x46\x29\xf0\x32\x1a\xbc\x5b\xa4\x37\x68\xae\x9d\x32\x46\xf8\xf1\x60\x4c\xae\x3c\xe1\x60\x8f\x9f\xb7\x1d\xf4\xe6\xcd\x57\x88\xa0\x2b\x84\xc9\xce\xdb\xee\xf7\x0e\x12\xbe\x52\xe0\x39\xa7\xf4\x13\xe2\x67\xd4\x87\xef\x69\xe4\x0a\x0e\x88\x30\xb9\xf6\xd0\x32\xcd\xd6\x83\x20\x4d\x58\x96\xc6\x68\xb2\x9a\x3a\xd7\x7d\x0f\x0d\x0c\xdc\x00\xa2\xaa\xe1\xa2\x65\x14\x53\x01\x07\x0a\xc2\xa7\x7b\xd1\xeb\x39\xd7\xde\x66\xca\x37\x5a\x57\x82\xe4\x98\x0f\x54\x43\x6b\xd8\xf5\x7b\xbd\x2b\xe1\xec\x43\x7c\xe2\x5e\x4f\x91\x6b\x38\x5c\x63\xe7\x53\xa9\x8c\xe7\x6c\x49\xe9\x72\x3b\x6a\x3c\xe1\xe9\x0a\xf5\xc3\x0e\x78\x7c\xa6\x1d\x21\x11\x40\xdc\xfc\x34\x65\x39\xcb\xfc\xcd\x9b\x4f\xf3\x0e\x34\xd8\xc9\xa3\x9f\xa2\xe4\x6a\xf8\x29\xe7\x5e\xa2\x2d\x15\x6f\x4e\xb6\x0c\x6b\x40\xcb\xd1\x21\xdf\x1c\x96\xb0\x39\xf0\x93\x78\x94\x0f\xf4\x9c\xe5\xe2\x5b\x7e\x75\xbb\x7e\xaf\x67\x0d\xd9\x00\xf5\x7d\x72\x6d\x6c\x21\x8e\x1c\x2a\xcf\xf3\x76\xfb\xfd\xb6\xd9\x15\xdd\x96\x77\x7d\x0d\xe4\xea\x45\x7c\x74\x14\x8b\xec\xf5\xba\xab\x5e\x4f\x4d\x5f\xd7\xf3\xa2\x32\x54\x7e\x59\x7d\x67\x15\xd9\x55\x87\x11\x02\x34\x77\xde\x47\x6c\xd5\xf1\xc1\x91\x2c\x1f\x33\xf4\x69\x3f\xea\x7f\x8a\x3a\x81\x70\xa6\xb9\xf2\xaf\x69\x47\xb5\xaa\xaf\x41\xf8\xc8\xcb\xc7\x63\x0f\x94\xf7\xad\x7f\xc2\xa7\x1a\x7e\x3e\xa6\x7a\x28\x4b\xbf\x6e\x41\x6d\x2f\xdb\x55\xf7\xb2\x35\xb9\xcd\xe8\xd2\x5d\x98\x92\x3c\x84\x61\x67\x85\xc3\xab\x1b\x0e\xc1\x16\x96\xb4\xbc\xa8\x6e\x6c\x20\xc0\x03\x71\x8a\xad\x6d\xf1\xeb\x6d\x6d\xc2\x35\x4a\xb9\x47\x58\x47\x08\x73\x43\x8b\xd3\xe0\x9d\xb1\x95\xc0\x49\xdc\xc8\x0f\xa3\xdc\x5f\xc4\xd4\xd8\xd0\xd2\x2d\x8b\xa3\x84\x7e\xc4\x1d\x4e\x9d\x67\x74\x6e\x75\xd7\xad\xef\xd3\x27\x6f\x79\x42\x6f\xa0\x91\xfd\x08\x3b\xa0\xc4\xd6\x4b\xd4\xaf\x8f\xb1\xbd\x29\xa0\x2d\xfb\x9b\x9a\x85\x29\xad\xb9\xae\x72\x8d\x62\xda\x81\x64\x3d\x0d\x9e\x13\x9f\xbc\x95\x09\xea\xe1\xfb\xd8\xcc\x24\x9c\x39\xec\x65\x40\x32\x52\xfb\xa1\x76\xbc\x5c\xe9\x42\x60\x3f\x2b\xf7\xbe\x52\xf5\xc1\xf7\x34\x49\x3a\xb0\xab\x01\xef\x5b\xc8\x0d\x6f\x6d\x6e\x6c\x17\xb5\x8d\x4d\xa0\x83\x2c\x22\x26\x08\xf0\x00\xed\x46\x45\xd3\x51\xd9\xfe\x94\x6a\x43\xb6\xae\xce\x6c\x6a\xd7\x33\x76\xb8\x49\x6e\xb9\x24\x37\x8c\x45\x0d\x3e\xe8\x94\x1f\x5e\x9d\xbb\x34\x1f\xbf\xbb\xa3\xf2\xe8\x3d\x11\x4f\xf1\xd1\x82\x25\xa8\xef\x6c\xa6\x68\xa0\x10\x13\x77\x97\xa0\x22\xd9\xd5\x76\x00\x2e\xa5\x03\x29\xe7\x05\xc9\xf7\x7b\xa8\xce\x7f\x5c\x91\x2e\x70\xe6\x05\x4b\x06\xa8\xbf\x22\xdd\x6e\x24\xbf\xe4\xf8\x28\x56\xc0\xca\xb5\xdc\x40\x59\x05\x26\x31\x9e\x5c\x0c\x57\x20\x05\x29\x2d\x84\xe7\x79\x8b\x5e\xcf\x59\x78\xc8\x97\x8a\xee\x6b\x2f\x9f\x4a\xdd\x1b\x9c\x5e\x15\x09\xd7\x47\x62\x61\xf3\x59\x4b\xbb\x21\xe0\x5e\x28\xe2\x9c\xaa\x74\xe5\x33\x91\x5c\x98\xe7\x8b\x1d\xe1\xfc\x79\x4d\x9a\x5c\x3c\xda\x8c\x2d\xd9\xef\xaf\xef\xc4\xba\x95\x06\x92\x06\x69\x12\xfa\xd9\x0e\x09\xcd\xa3\x44\xeb\x57\xe7\xe6\x75\x06\x18\x25\x1f\x99\x09\xff\x06\x0f\x11\xf9\x76\xb1\x8e\x98\xa7\x7e\xfc\xe6\x8e\x11\x12\xbf\xc3\xe7\x08\x51\xe8\xa3\x1d\x24\xc4\xbc\x03\xf7\x55\x9a\x0a\xcd\x38\x4f\xd7\x4d\x08\x28\x4d\x2c\x90\x6c\x1b\x64\x4f\xc1\x53\x40\xba\x94\x35\x4d\xa5\x55\x7d\xe9\xd7\xd4\xa5\xb1\x10\xb1\x72\x93\xca\xd4\x3a\xcd\xcf\x10\xb0\xf8\x9a\xe4\x68\x7c\xd0\x8a\xfc\x30\xcd\xa4\xc5\x6f\xee\xa2\xa1\x14\xfa\xe1\xa0\xa2\x63\x30\xbe\xaf\x69\xc6\xa2\xc0\x8f\x21\x4d\x08\x2d\xe7\xeb\x34\x73\x7d\xca\x94\xd0\x40\x8d\xc5\x49\xe6\x74\x2a\x91\xdb\xa4\x82\x20\xc9\x65\xce\x87\xa3\xae\xbc\x2a\xf7\x1d\xa5\xbf\x8a\x48\x3e\x35\x12\x34\x18\xb7\x4c\x44\x87\x95\x9f\xc1\x41\xb5\xd3\xf2\x1c\xe5\xa7\xd4\xca\x8b\x56\x7f\x71\x4d\xe8\xed\xe9\xd4\x51\xa5\x06\x11\xda\x94\x86\x9a\x1a\x64\x4a\x4c\xf3\xbc\x4c\xe3\x85\x37\x66\xa1\xd0\xcf\xde\x95\x5f\x10\xda\xba\xfc\xcc\x68\xbe\x49\x93\x9c\x4b\x05\x81\xbd\x4d\xe8\x22\x81\xb9\x37\x28\xda\x2f\xeb\x5d\xca\x14\xbd\xdd\x34\xc0\x81\x3d\xc6\xec\xae\xee\xe4\x1c\x7f\x10\x49\xab\x21\x01\x92\x2e\x47\x03\x44\x4f\x39\x10\x64\xe9\xd1\x21\x1f\x03\x12\x7a\x74\x08\xdd\x07\xa9\xb3\xec\x81\x25\x7b\x5a\x1d\x83\x2b\x38\xcd\x54\xaf\xce\x5d\x2e\x0a\x3b\xfd\x33\x86\x3b\x4d\x24\x31\x43\x04\x71\xbc\x10\x41\x32\xde\x38\x2a\x1b\xd7\x0c\xd9\xc2\xa7\xc2\xa0\x77\x4d\x9a\x63\x26\xdc\xc4\x89\x45\x08\x1f\xb0\x00\xbb\xdd\x5c\x7f\x97\x78\x75\xbb\x41\x25\x55\xa0\xd8\xed\xc6\x3a\x5d\x63\xdb\xed\x2e\x75\xa2\x40\xbc\xdb\x0d\x75\x8a\xe8\x03\x5f\xc5\xe4\xda\xab\x2f\xe0\x45\x75\x01\x5f\x89\x8d\xe0\xc2\x60\x97\xbb\x42\xf8\xa9\x92\xc6\x77\x4f\xac\xee\x75\x47\x9e\xe7\xad\xa6\xb2\x35\x63\xa4\xdc\x5a\x12\x48\xbf\x87\xb8\xc9\xda\x64\x1e\x4f\x0a\x72\xad\x9d\x98\x5e\x9f\xc4\x46\xe4\x18\xdb\x8b\xe0\xd7\xb9\x59\x69\x58\x6d\xc2\xdd\x93\xbd\x6e\x8d\xab\x97\x24\xfd\xfb\x96\x31\x9a\x19\x3c\xe3\x74\x9e\xc4\xb7\xdc\xb2\xde\x4d\xee\x2e\x49\xbe\x76\x97\x64\x1d\xba\x4b\x12\x5f\xb9\x4b\x72\x13\xbb\xcb\x82\x4b\xaa\x25\xc3\x7d\x1f\x85\x6c\x95\xbb\x33\x74\x03\xd4\xbf\x46\x04\xad\x39\xf5\xc7\x9c\xa0\x6f\x62\x34\xaf\x0a\x92\xa7\xf0\x00\xdd\x0d\x60\x04\x7c\xf9\x72\x1e\xc0\xf1\x83\xd5\x2f\xda\x2c\xf7\xa7\xa3\x6b\x56\xc3\xd3\x4b\x0f\xc4\x0b\x82\x04\x24\x71\x53\x33\x9b\x4f\xe2\x26\xa7\xab\x3a\x76\x98\x47\x67\x0c\x1c\xd2\x49\x05\xd4\x72\xc6\xe6\x65\x08\xb4\x6e\xc2\xa9\x6b\x9b\xaf\x9c\x74\x8a\xb2\xf4\xfd\x20\x48\xe3\x7c\x80\xfa\x99\x6b\x7e\x31\x38\xf9\x65\xb8\x28\xb0\xf2\x49\x57\x5f\xe7\xd1\x14\x25\xe9\xe0\x4a\xa2\x2c\x2e\x71\x83\xa9\x90\xcc\xb2\xf4\x3d\x02\x88\x88\x84\x87\xb7\xd5\xbc\xba\x2a\x97\xe6\xca\x58\xc1\xb6\xba\xb0\xae\x70\x2a\x82\xd8\xea\x97\x96\xbe\x4e\xa6\xf7\x43\xdb\x59\xad\x86\xf8\x09\xd6\x2c\xb7\x7a\xdb\x3d\xb9\xf6\x1c\x13\x11\x75\x7c\x49\x52\xe1\x73\x72\x59\xe0\x39\x56\x8b\x80\x2f\xba\x9b\xdc\x0d\xf9\x4a\x09\xf9\x4a\x09\xf9\x4a\x09\xf9\x4a\x09\xcf\x58\x7a\x72\x15\xf1\x14\x3f\xcb\xfc\x1d\xd8\xcb\x9c\xb5\xc8\xd6\xb5\x78\x77\xca\xd8\xcf\xf3\xbc\x64\xbf\x47\xfc\x34\x9e\x4c\xe9\x14\x05\x29\x17\xce\x02\xd0\x1d\x33\x17\xf9\x5b\x96\x9a\x79\x03\x48\xd0\x05\xfa\x48\x26\xc8\x5c\xd4\x4f\xcc\x3c\xd4\x4f\x0a\x72\x71\xf6\x02\x97\x2b\xb8\x5c\xdd\xa7\xae\x64\xb9\x60\xb5\x8c\x1a\x83\x8f\xc8\xc6\x65\x5b\x06\x27\xb4\x97\x6d\xc0\x97\x6d\x2a\x47\x24\x55\x31\xab\xba\x59\x19\xdd\xca\xd9\x0c\xaf\xb0\x93\x62\x91\xe7\x93\xdc\x8b\xa6\x68\x80\x5c\xa4\x3a\x4d\x96\xde\xda\x89\x08\x23\xa9\x54\xe7\x4b\xef\x50\xd5\xa5\xec\x38\xbe\x77\x5b\xe0\xd9\x72\xee\x89\x92\xaa\x55\x21\xe5\xf8\x33\x04\xb4\x85\xfa\x79\x3f\x1d\xc2\x4f\x5e\x10\x7e\x08\x2b\x7e\xf9\x01\x25\x81\xfa\x64\x51\xf8\x0d\x65\xe1\x97\x2e\x0c\x5f\x10\x95\x3a\xc1\xc2\xa3\xbe\x88\xbf\xab\xd0\xd5\x98\x86\xb8\xe0\x2c\x88\xc4\xda\xf2\x55\x39\xb8\xe2\xe4\x21\x58\x53\x93\xfc\x7f\xc4\x8e\xa1\xc6\x73\x82\xba\x28\x7f\x61\x1d\xfe\x2e\x9a\x6c\x51\x2e\x7e\xd1\x13\xdf\xc2\xd8\x2d\x37\x51\x1c\x1b\x9f\xd6\x21\xed\xa8\x00\xbd\x4a\xb3\xe8\xa7\x34\x61\xb2\xbc\x5c\xf0\xff\xde\xe6\x2c\x5a\x46\xa6\xd8\x0e\x3e\xb1\xf4\x57\xe2\x5f\x2f\x7c\x43\x6e\x0f\xfc\xcc\x28\xab\xb8\xcc\xcf\x6c\x1b\xb3\x10\xab\x11\xfa\x0f\xbb\xad\x3e\x51\xc6\x20\x5a\xab\x9e\x81\xc8\xad\xbb\x04\x72\x37\xef\x0d\x88\xdd\xa2\x23\x20\x72\xf3\x3e\x80\xcc\xcd\x40\xd2\x3e\xdd\x9a\x62\xc1\x17\x37\x60\x61\x9f\x49\x4b\x0c\x10\x41\xba\x7d\xbe\x93\x47\x31\x4f\x12\x6d\x73\x70\x7e\x16\x96\xfc\xe1\xaa\x81\x86\x57\x53\x59\x7a\x90\xf8\xd7\xc8\xe5\x1f\x4a\x2a\x16\x80\x77\x70\xbb\x46\x13\x36\x40\xfd\x98\x34\xf8\xe6\x1c\x4b\x9b\x56\x60\xae\x7c\x51\xdf\x40\x44\x55\x3a\x45\xcb\x98\xde\xf0\xbd\x7e\xbb\x4e\x90\x2b\xbe\xe0\xa1\x88\x4a\xc3\x85\x13\x60\x72\xcb\xdb\x1c\x40\x67\xdd\x48\xa0\x3c\x58\x51\x3f\xa4\x99\x4c\x5c\xf4\x7a\x11\xf4\x69\x20\x86\xc2\xcd\xed\x52\x32\x75\xd1\xeb\xe5\xa2\x58\x39\x22\xee\x52\xa4\xc0\xb8\x80\x35\xc8\x61\x69\xb9\xb2\x60\x2d\x95\xec\xd5\xa9\x67\xef\x6d\x8c\xca\xb5\xd2\x1d\xff\xf2\x27\x6f\x6d\x7b\x24\xb4\xe0\xe7\x4b\xbf\x77\x59\x35\xf2\xfe\xe4\xfc\x5d\x4c\xdf\x74\xe8\x5d\xac\xe1\xb0\xc7\x27\x31\x62\x74\xad\xce\x7b\xb2\xd2\x87\x30\xe0\x93\x0d\xc9\xe2\xe8\x83\x4e\x3b\x1f\x45\x1b\xfe\xc1\xba\xee\xfa\xa5\x66\xf5\xba\xf4\xf4\xfb\xc5\xda\xe5\xe5\x2a\x93\x18\xf9\xc9\xee\xbf\xf0\xba\xd1\x41\x7f\x82\x8b\xb1\xb2\xb4\xb8\x32\xaa\x17\x25\x27\xdf\x4c\x7e\x2c\xe5\xb8\x5c\x76\x1f\xa8\x1c\xb7\xd6\xe0\x71\xe5\x38\x2c\xc7\x38\x4a\xde\x21\x72\xab\x09\x2b\xd6\x63\xa8\x48\x2b\x2a\xee\xaa\x33\x6f\xbc\xf6\x6a\x50\xa4\x9f\x67\xab\xc0\x17\xb3\x7f\x37\x3d\x3a\x5f\xbd\x4d\x0c\xf9\xe1\x17\xa7\x3d\x8a\xf8\xf3\xc3\xa6\xd5\x2c\xc6\xe9\xd2\x5f\xc0\x13\x02\x3f\xd9\xb5\x3c\x8e\x68\x78\xe8\xf0\x11\x96\x59\xce\x7c\x46\x95\xd9\x04\x47\x42\x46\x89\x1c\xea\x94\x82\x24\x85\xed\x67\x36\x55\x4b\x8d\xc0\x0b\xa5\xaf\x68\x16\x5d\xd3\xf0\x35\x87\xf4\x75\x96\xae\xc5\x48\x37\xba\xa1\x66\x25\x58\x08\x97\xad\xbf\xa6\x06\x06\x46\x72\x21\x03\x53\x30\xeb\xad\xf6\x07\xad\x97\x54\x2e\x92\xa8\x24\xe9\x08\x3b\x46\x65\xf3\xad\xde\x0a\x97\x61\x35\x04\xed\x83\x65\x3e\xf3\x17\x4a\x20\x82\x07\xb7\x87\xf6\x9f\xe5\xd0\x1f\xbe\xca\xd2\xeb\x88\x9f\x5a\x64\x18\xc8\xb2\xb3\xcf\xe5\xa5\x34\x4c\x83\xd1\xef\xa2\xc1\x62\x35\xad\xae\x94\xc8\xdc\xc9\xf2\x02\xcb\xf5\x10\x99\xab\x41\x56\xc9\x87\x1b\xe9\x79\x16\x3b\x0b\x2c\x88\x9f\x9c\xb0\x52\x40\xcb\x77\x64\x95\x24\xc3\x10\xde\x3b\x98\x61\xdd\xf4\x8c\xaf\x94\x5a\xe7\xc3\xe5\x9a\x3f\x3f\x34\xde\x16\xdd\xaa\x47\x3a\xa7\xab\x14\x18\x0c\x77\x20\x77\xa8\xf2\xe5\xcb\xea\x8c\x33\xc1\xf3\xf0\x0e\xc2\x0d\xd4\x33\x65\x9b\x06\x77\xaf\xe6\xeb\x8f\xad\xa2\xb1\x8d\x9f\x50\x44\x98\x36\x65\x88\x20\x90\x09\xa7\xb7\xa2\x9d\xe0\x36\xc0\x0e\x93\x7c\xbb\xa6\x19\x01\x4d\x59\x43\x2c\x58\x83\xd6\x9e\x87\x77\x16\x9e\x44\xc4\x25\xfe\xff\xa9\x96\xcf\xa7\x30\x5c\xa0\x91\x3f\x0b\x1a\x91\xcf\xcf\xfe\x22\x29\xe4\xa1\x64\xb4\x9f\x0b\x0a\x19\x55\x28\x64\x5c\x11\x9b\x3e\xe3\x8c\x96\x7f\x87\x98\x2c\x38\xe5\x7c\x86\xc9\x5a\x50\x90\x3e\x81\x05\xb2\x67\x8b\xe1\xa5\x7e\xe5\x53\x76\x86\xdc\xca\x37\x59\x4b\x2d\x21\x29\x93\x84\xa5\x2d\x7c\x2d\x95\xa6\xea\xe5\x12\xd6\x7c\x92\x86\x14\x13\xf5\x4b\x5e\x26\xad\x2d\x82\x55\x99\xea\xbc\x5b\xb6\xa1\xc9\x77\x59\x92\xaf\x96\xfa\x1a\x1a\x06\x01\x6c\x69\xbc\x77\x33\xaf\x9c\x8c\x33\x5f\x63\x67\xed\x57\x44\xea\x0d\xda\x98\xf8\x9b\x0d\xf5\x33\xfe\x8b\x26\x8c\x42\x64\x1a\x2a\x1e\x8e\x19\xcf\xd3\xd4\x43\xa2\xf5\x90\x0e\x9f\xa6\x71\xec\x6f\x72\x4e\xa1\x3b\xcf\x71\x32\xd0\xf4\xac\x87\xe1\xf0\xd9\x8b\xcb\x67\xdf\x3d\x7f\xf1\xf7\xb9\x87\x02\x51\x06\xc2\x03\x65\x65\xe6\xb3\xaf\xca\x3c\xda\xc9\x57\xe9\x7b\x9d\xfd\xc3\xf3\xcb\xd6\xaa\x3f\x3c\xbf\xb4\x6a\x22\x92\xe1\x72\x61\x5f\x5b\xee\x94\x45\x84\x1b\x11\x55\xa7\x10\x37\x2e\x1f\x67\xef\x5c\x89\x40\x3d\x62\xa7\x9a\xa1\x34\x81\xa8\x75\x22\x00\x92\xfc\x80\x73\x79\x0a\xef\xee\xf4\x0f\x5d\xe0\x26\x62\x34\x44\xf3\x06\x95\x1d\xc5\xb7\xc9\x8c\xce\x3d\xfe\x8f\x25\xfe\xfa\x52\xfc\x2d\x4c\x09\x38\x3f\x4d\x02\x56\xd8\x55\x76\x68\xb1\x0d\x51\x06\xdb\xb8\xa3\x3a\x75\x0d\x31\x98\x6d\x89\x56\x01\x10\x71\x8a\x89\x86\x49\xc3\x93\x40\xc2\x38\x35\x81\xa4\xa1\x09\xf1\x26\x62\x75\x31\xfd\x34\xfc\x6e\x22\x26\xcd\xfe\xf4\x48\x5b\xa0\xa8\x54\x0b\x0a\x5a\x98\x34\x43\x1e\x35\x81\x15\x51\xd5\x4a\xc8\x34\x3c\x01\xc7\xc6\x0e\x43\xe5\x13\x8c\x13\x09\x33\x05\x1b\x3e\xa9\x7c\xef\xc9\x3c\xa6\xde\x53\xfa\x1e\xb3\xec\x11\x99\x52\x3a\xc5\x3c\x43\xef\x5f\x1b\x33\xc0\xf7\xd2\x73\x58\x79\x42\x30\x8f\x54\x8c\xcc\x94\xf8\xaf\x1e\x44\x9a\xbb\x5a\xa9\x53\x32\xed\x0c\xcb\x87\x92\xc6\x99\x81\x73\x60\x43\xb4\x11\x63\x51\xb2\xdd\xf5\xf0\xdf\xd8\x59\x92\xf5\x30\x30\xd8\xd3\x9a\x8b\x62\x22\x51\x51\xec\xb6\x7e\xb7\x6a\xf0\x2e\x62\x6e\xc1\x42\x57\x13\x25\x6e\x46\x4a\x22\x55\xa7\x07\xf5\x4d\x34\xb1\x59\x39\x34\x24\x62\x52\x74\xea\x4d\xc4\x88\x9e\x74\x33\x55\x02\x81\x09\x34\xd3\xc1\x96\xb0\xc1\xfd\x48\xc3\x66\xbf\x9b\xd1\xf9\x7e\x5f\x72\xad\xc2\x61\xa5\xeb\x00\x67\xcd\x65\x80\x15\x98\x3e\x66\x60\xee\x2e\x75\x73\xba\x38\x26\x31\x6c\x74\xdb\x38\xf6\x3c\x2f\x14\x46\xfe\x8a\xda\xc2\xa2\x7d\xe8\x6a\xe3\x75\x45\x6e\x21\x78\xaf\x5b\xd9\x1f\xae\x44\x4c\x5f\x72\x5b\x90\xa5\x69\x22\x17\x81\x45\x22\xad\x58\x88\x15\x98\x6c\xb0\x3a\x8d\xc5\xa6\xf4\xf9\xc4\x10\x0b\x2e\xc8\x13\x5b\x2c\xb8\x02\x31\xf4\xc9\x2f\x69\x8d\x02\xd6\x8e\x86\x9c\xb8\xb1\xd4\xce\xec\x04\xe3\x0e\x65\x5d\x5d\xb7\xf3\x98\xe3\x0f\x7b\xb2\x77\xbe\xb6\x4d\x18\x18\x5b\xa7\xfd\x40\x6a\xac\xf5\x1b\xec\xd3\xaf\x84\xf5\x4b\x68\xb5\x86\x85\xd6\xb9\x94\x5b\x1b\x9f\xee\x2d\xfc\xf0\x0a\xac\x3f\xf8\x5f\x69\x7b\x11\xf4\x7a\xf2\x1b\x00\x98\xe7\xa3\xa5\x32\xb4\x05\x73\x61\xcf\xf3\xe2\x5e\xcf\x89\xc1\xcc\xb6\xe1\xc4\x13\x1f\xbc\xb0\x0d\x81\x18\xf3\x13\x34\x78\x75\x2b\x57\x98\xf8\xee\x58\x08\x32\x80\xcb\xaf\x60\x1b\x55\xa3\x96\x2c\x7d\x6f\x28\x6a\x57\x34\x30\x4c\x99\xa4\xe1\x6b\x69\xe8\xa4\x54\x2e\xbf\xec\xbd\x48\x96\xbe\x07\x8a\xd3\x6a\x1e\xf1\x4a\x94\x06\xef\xe4\x8b\x2e\x30\xd3\x5c\x4a\xea\x0b\x4f\xa6\x3e\xb8\xbf\x47\x0a\xaa\x7a\x68\x55\x35\xd9\x84\x6b\xe6\x36\x1b\x3c\x00\xa1\xac\x02\x44\x75\xf9\xf4\x49\x3e\x44\xee\x3a\xdd\x60\xbf\xef\xc6\x58\x3f\x19\x92\x4f\xa2\x44\x0b\x32\x3b\xe7\xd9\x1a\x11\xf3\x2d\xea\x32\xa2\x71\x98\x8b\xb8\xb5\xcb\x5e\xcf\x09\xf5\x28\x78\x79\xe3\x13\xd3\x2a\xf9\x86\x75\x7b\x83\xdf\xea\x1b\xe6\x0f\xb1\x3c\x30\xac\x0c\xcc\x3a\x86\xc1\xc1\xb2\xd5\x84\xa0\xbe\x28\xc4\x5b\x82\xd6\x75\x51\xb5\x1b\x5c\xda\x1c\xfe\xec\x45\xd1\x6e\xbc\xd0\x6e\x92\x20\x5f\x66\xfc\xd7\x19\x25\x88\xa1\x87\xf5\x2e\xed\x13\x4a\x63\x5a\xb5\xea\x97\xca\x42\x31\x14\x06\x49\xe5\x02\x3d\xba\xe6\xe5\x2b\x91\x8a\x0d\x43\xb9\xf4\xa5\x61\xe1\x32\xcd\xf8\xc2\x5f\x78\xb3\xf9\x24\x3f\xcb\xb0\x61\xd5\x64\xd8\x40\xfc\x03\xa6\x0d\xbc\x87\xbe\x6d\xda\x30\x89\xbc\xb5\xe3\x97\xa6\x0d\x64\xd1\x66\xda\x90\xc3\x81\x37\x6a\x36\x6d\xc8\xb5\x69\x43\x70\xc4\xb4\x21\x2f\x4d\x1b\x82\xe3\xa6\x0d\x39\x06\xdb\x06\xe5\x2f\x4f\xa2\xaa\xb1\x8c\x4a\xc3\xaa\x8b\x56\xce\x99\x67\x83\x34\x89\x77\xea\xce\xd7\xe0\x8d\x92\xb2\x85\x31\x24\xa7\x27\xc8\x83\xd4\x01\xea\x2f\xc9\x82\x74\xbb\x0b\x1d\x5f\xb1\x52\xe2\x3c\x2b\xe7\x15\x5b\xc7\x5f\xa7\x99\x1b\x16\x64\x65\xf2\xc9\x8b\xdf\xa2\x8d\x44\x0c\xb2\x76\x8b\xd5\xf1\x72\x6b\x4a\x95\xcb\xe8\x46\xee\xd2\xca\xee\x9d\x45\xc1\xbb\x9d\xc5\x87\xaa\x72\x69\xd5\x54\xfe\x7c\x2e\x46\x6f\x36\x7e\x12\x9e\x64\xa5\xd1\x28\x06\x00\x37\x10\x40\x84\xac\x69\x3f\x79\xd3\x6c\x82\x33\x04\x18\x0c\x60\x09\x60\x79\xbc\x04\x0b\x88\x1b\x69\x0b\x21\x7a\x0b\xd6\x10\x42\x5e\x2d\xed\x8f\xab\x7c\x42\x34\x57\x7d\xd9\x66\x30\x0c\x68\xa8\x34\x24\x86\x46\xc0\xc2\x98\x37\x61\x88\xb0\x52\x54\xa8\x13\x7c\x54\x1e\x61\xcf\x32\x62\x90\x27\x30\x89\xa0\x6b\x7f\x0f\x50\x9f\xe2\xc2\x49\x30\x71\x1c\xe6\xdd\xaa\x4c\x81\xac\x1b\xa8\x26\x85\x15\xb1\x1b\x17\x78\x86\x16\x57\x03\xd4\x5f\xcd\xbd\x15\x61\x33\xd1\x0d\xbe\x9a\xe6\xde\x92\x7f\x8b\xee\x0c\x50\x3f\x9c\x7b\x21\x61\x18\x93\xfc\xc0\x2a\xaa\x99\x1a\xaf\xeb\x8b\xe7\x04\x21\x03\x4c\x3e\x24\xd1\xfc\x9a\xe6\x0a\x4c\x79\x49\x39\xfb\x79\x49\x4d\x72\xb8\xd3\x91\x4a\xa9\x48\xce\xd7\xf2\x9b\xfe\xa2\x0e\x1b\x31\x70\x62\x10\x6e\xa6\xb2\xf3\x8c\x17\xac\x37\x38\xe8\x12\x40\x74\x12\xff\x3a\xba\x82\x18\x82\xa8\x6e\xdc\x40\xa2\xfd\xbe\x0e\x56\x3d\xd6\x2c\x8b\x9a\x88\x56\x50\x1c\x44\x41\x9a\x20\xbe\xc5\x9c\x48\x4a\xca\x93\x93\xf5\xf2\xf1\xd7\xa3\xa8\x65\xbc\x8d\x4e\x63\x84\x3f\xef\xc9\x09\xf0\xb8\x03\x5d\x41\x3d\x93\xa8\x50\x90\x26\xcc\x8f\x12\x9a\xa1\x09\xb0\xaa\x68\x6a\x26\x0e\x44\x05\x37\x12\x27\xeb\x32\x1d\xf5\xa3\x9f\xd5\x8c\xf1\xe7\x3c\xca\x8c\x80\x12\x86\x89\x93\xca\x18\x9b\x15\x7f\x84\x7f\x91\x76\x34\x0f\xc5\xcd\xfb\xb8\x72\xf3\xfe\xb9\xb8\x0f\x1a\x7f\x0e\x17\x42\xce\xc3\x3f\xc3\x7d\xd0\x30\x71\x56\xe2\x42\xe8\xf3\xbf\xf0\xdd\x82\x27\xac\x31\xb9\xe2\xcd\x8e\x31\xd9\x41\xc2\x15\x26\xd7\x10\x59\x13\x93\x27\x90\x70\x8d\xc9\x5b\x5e\xe2\xcf\x98\xbc\x87\x84\xb7\x98\xfc\x04\x9e\x85\x31\x79\x09\x09\x3f\x61\x72\xc9\x81\x7e\x89\xc9\x0d\x24\x5c\x62\xf2\x82\x23\x3d\xc2\xe4\x5b\x5e\x75\x84\xc9\x33\xc8\xf8\x16\x93\xd7\xde\x33\x07\x3b\x98\x3c\x95\x7f\xdf\x79\x4e\x5a\xaa\xd0\x48\xdd\xbf\x75\x83\xf7\x0a\xe5\xd0\xb4\x63\xd2\x64\x6b\xd9\x5b\xe5\x52\x9a\x79\x55\x37\xd6\x24\x01\x2f\x26\xe0\x90\xde\x61\x8f\xc7\x53\x36\x18\xbb\x23\x4c\x32\x6f\x3c\xc9\x1e\xb1\x49\xd6\xef\xe3\x64\x96\x0d\xc6\xf3\xb2\xea\x2c\x9b\x97\x21\x8b\x45\x10\x50\x19\x84\x21\xc1\x45\x21\x5c\xb2\x0a\xaf\x97\x7c\x6f\xa5\xc3\x60\x9b\x65\x34\x61\x1e\xc3\x05\x26\xff\xf1\x6e\x37\xa9\xf4\x5f\x88\xfc\x45\x9e\xc6\x5b\x46\x11\x61\xe9\xc6\x1d\x91\x98\x2e\x99\x3b\x22\xe9\xc6\x0f\x22\xb6\x73\x47\x64\x93\x46\x09\xa3\xd9\xb3\x6b\xde\xae\x8b\x92\x34\xa1\xa8\x20\xff\xf2\x6e\x0b\xf2\x55\xdb\x65\x8e\xd1\x5d\x92\xd4\x3b\x9c\x19\x1d\x4e\x38\xad\x8d\x26\xe9\xa3\x64\x92\xf6\xfb\x38\x9b\xa5\x66\x37\x53\xdd\x4d\x26\xef\x83\x74\x64\xdd\x19\x5b\x45\xf9\x5c\x85\xd7\xcd\xb0\xbc\x21\x22\x2f\x1d\xec\x3c\xe1\xcb\x0b\x73\x21\xc5\xe7\x3d\xbb\x0d\x7d\xe6\xab\x28\x15\xe0\x74\x9e\x43\x57\xef\xbf\xb1\x55\x65\x93\x6e\x36\x34\x7b\x2e\x23\x04\x23\x22\x0a\x35\x95\x79\x91\x86\x14\x11\xe1\x55\xcd\xcc\xf5\xb3\x2c\x7d\xdf\x96\x99\x53\xf6\xca\xa8\x6d\x5d\x3b\xd1\x5e\x8f\x0d\x4b\xd8\x52\x30\x7a\xe7\xb0\x8a\xea\x57\x18\x81\x94\x05\x3d\x4a\xd8\x70\xbb\x09\x7d\x46\x5f\x59\xd8\x3b\xe2\xb2\xaa\xd2\xfe\x93\x12\x3f\xab\x79\x36\xd4\x98\x7b\xb4\x5a\x4f\x80\x87\x3b\x96\x8b\x34\x8c\x96\x11\xcd\x10\xb9\xa5\x89\x50\x87\x75\x47\x52\xb7\xf0\xd7\xd1\x88\x2c\x13\xb7\xca\xa6\x13\xe1\x59\x48\x8c\xbb\x9e\x51\xe3\xd6\x06\x26\x88\x1a\x73\x93\x08\x1f\xb4\x36\x12\x57\x94\xbd\xdc\x70\xb8\x79\x93\xd9\xc3\x6d\x59\x5b\x8d\x98\x4e\x21\x60\x2d\x96\x3f\x93\xf8\xaa\x7c\x2b\x95\xa8\x45\xf1\x35\x1c\x1e\x34\x0c\x33\x95\xac\x65\xe7\x73\x77\xe7\x00\x4f\x56\xc5\x74\x06\xb9\x85\x61\x6c\xcd\x87\x49\xb6\x93\xc4\xc0\x1b\xc3\xd9\x35\xe6\x82\xd0\x58\x75\x4a\xa7\x15\x98\xc0\x32\x78\x0d\xf7\x08\x65\xbd\x71\x41\x1a\x26\xca\x55\xd4\x61\xa5\x16\x70\x48\xad\x8e\xaf\x20\x20\x80\xdb\x68\x5a\x62\xd2\x1d\xef\x89\xb8\x68\xe2\xd3\x37\x85\x0e\x6b\xc6\x62\x66\xc9\x63\x73\x2e\xeb\xea\x21\xe5\xa3\x63\x94\x82\xeb\x8f\x1c\xbb\xff\x69\xc5\xeb\x95\x9a\xcf\x16\xdc\x0c\x6c\xd4\x47\x7d\xb9\xd7\x60\xc3\x82\x38\xd4\x65\x3d\xee\x95\x1e\x5b\xd8\xfb\x1a\x4a\xee\xfe\xab\xa1\x95\x97\x5b\xf6\x72\xf9\xb7\x74\x9b\x84\x7e\x16\xd1\xfc\xb5\x60\x4d\xa7\x76\x03\x9a\x58\x45\x21\x6d\xe9\x46\x48\x73\x96\xa5\xbb\x57\x15\xee\x65\x82\x57\x53\xa7\x72\x7b\x3d\xa7\x9a\x34\x94\x60\x9c\x92\xc1\xa8\x2c\xb8\xf9\xaa\xb1\x93\x26\xae\x53\x6d\xb5\x11\x35\x47\xb9\xb2\x16\x90\x0c\xaa\x22\xf2\x12\x7d\x03\x2e\x0d\x64\xe8\x2e\xb1\x04\x26\x49\xaf\xd7\x84\x36\x6c\x27\x2f\x86\xbe\x93\x10\x2a\xcc\xe3\x24\x9b\x70\x70\x03\x07\x0c\x56\x94\x4b\x79\xdf\x03\xea\xc7\x86\xa8\x36\x42\x76\x75\x07\x8b\x98\x1f\xef\x9d\xe3\x56\x00\x81\x92\x2f\xbe\x8a\x42\x51\xbb\xe9\xea\xbe\xc2\xb8\x20\x86\x86\xfe\xb2\x4c\x5a\xab\xa3\x03\x45\xab\x89\x56\x0d\x8b\x95\x09\xc8\x66\x4a\xaf\x77\xe3\x98\x56\x79\x06\x4f\xa3\x26\x7f\x13\xe2\x22\xf8\x32\x9e\x1a\xa5\x2d\x66\x0a\x96\x86\x56\x8a\xc2\xa4\x46\x83\x2d\x10\xa6\x0d\xc5\x87\x82\xd3\x81\x2c\xf2\x6d\x94\x33\x9a\xd0\x2c\xd7\x6e\x89\x2a\xa4\x2c\xae\x09\xaa\x65\x65\xe1\xe6\xed\x92\x53\xbd\x1a\xeb\xae\x67\x5e\xa5\x57\xa7\xa0\x46\x06\xc4\x98\xe0\x7f\x45\x71\xfc\xbd\xf0\xfb\x6c\x1a\x18\xbc\x73\x1a\x3c\x7d\x48\x19\x01\x72\x5a\x56\x4a\xb3\xb9\x82\xb4\x93\x31\x6d\x30\xcb\x93\xb4\x88\x6e\x14\xe5\x42\xc6\xa2\x78\x4a\x67\xa3\xb9\x4b\xb1\x03\x66\xbe\xca\x64\xa2\x94\x44\x88\xb8\x91\x86\x0c\x7b\x17\x70\xb0\xb1\x2b\xdb\xf9\x9a\x1b\x3b\x98\xa4\x36\x77\xd3\x25\x9b\xb8\x9e\x83\x89\x3d\x7c\x6e\xc3\x90\x12\xe0\xa7\x70\x8e\x71\x2d\xa4\xb5\xf8\x52\xc1\xb9\xe4\xe2\x0e\xdf\xd9\x04\x7b\x81\xdb\xf1\xd4\xb2\xcd\x74\xb0\xf3\x15\x41\xe6\x39\x09\x11\x43\x74\x40\x8b\x94\xb1\x74\x8d\x2a\x12\x43\x77\x44\xaa\x4b\x4b\x0b\x94\x96\xd8\xd0\x1d\x17\x78\xf2\x62\xe8\x97\x14\x93\x97\xc6\x51\x7f\x33\xcf\xad\x55\x78\x24\xf1\x2e\x1c\x71\x2c\xad\x66\xa1\xb9\x3e\x26\xa6\x95\x43\xe2\xeb\x43\x76\x87\x2d\x75\xbe\x22\xb0\x57\xb7\x74\x88\x13\xfe\x94\xb9\xb4\x20\xc2\xd8\x09\xec\xb6\x5e\x89\x23\xfe\x0f\xc2\xbf\x3c\x0c\xee\xbf\x8d\x8b\xa3\x8d\x54\xff\x98\xbe\x74\xc5\x7a\x2c\x5d\xcb\x6f\x0c\x13\x00\x3d\xdc\x4d\x89\xaf\x32\xba\x8c\x6e\xcc\x2c\xa0\x85\x46\x48\x7c\x4b\x84\x99\x87\x44\x7d\x25\xfb\x6a\xf8\x4e\x39\x76\x57\xe9\x96\x9b\x5f\xad\x5e\xd8\x18\x8f\x2b\xc4\xad\xd8\xc6\x56\x5a\x98\x08\xea\xbb\xb5\x39\x26\x4b\x3f\x8e\x17\x7e\xf0\xee\x95\xd5\x95\xf6\x8a\x70\x7b\xc5\xeb\xc5\xd1\xa6\xc4\x55\x2b\x0a\xdc\x57\x43\x8e\x79\x76\x45\x19\xff\x69\x22\x5b\x8a\x9c\x06\xb2\x0b\xbd\xa4\xd4\xe4\xb5\x37\xff\x6a\xe8\x4b\xc7\x77\x69\x4e\x43\x28\x28\x6c\x17\xfd\x90\x1a\xc3\x56\x3a\xb5\xdf\xe8\x9b\xc3\x1f\x2c\xc7\xfb\x05\xf9\xce\xbb\xad\xb7\x8c\x84\x95\xdf\x2b\x3f\x03\xc9\xcc\x58\x4b\x70\x3d\x66\xcc\x51\x77\x4c\x4a\x53\x47\x39\xde\xa3\x86\xa1\x44\x7c\x94\x90\x18\xab\xee\xc8\x18\x25\xb4\x48\xc3\x1d\x32\x86\xe4\xb6\x28\x3b\x66\x30\xc7\xe2\x80\xaf\xfe\x50\x6a\x53\x7e\xa8\x38\x73\xc7\x05\x79\xfe\xc1\xd6\x89\x94\x5d\xc2\x24\xc2\x29\x2a\xb1\xbf\x2d\x6b\xc2\xa0\x74\x3d\x75\x55\xa9\x74\x75\x62\xa5\x56\xb7\x56\x46\x31\x35\x38\x5e\xf9\xb3\xad\xa8\xb4\xac\x94\x13\xa4\x6c\xdd\x8a\xd2\xd6\x31\xbe\xf3\x13\x04\x15\x88\xa0\xd7\xeb\x2a\xb8\x53\xd5\x90\xca\x93\xcf\x0e\xee\x2a\x41\x49\xf1\xe9\x2d\xb5\xe4\x1e\xf5\x29\x76\x46\x3e\x9e\x79\x7b\xce\x6c\x34\x3f\x98\x29\xdc\xf4\x9e\x50\x44\x6c\xd9\x36\x2d\xd4\x4c\x16\x59\x99\x57\xf7\x6d\x4a\xa7\x72\xcc\x5f\x0d\x97\xd8\xa1\x18\xb8\x71\x85\x50\x1a\x4e\x0e\x36\x5c\x59\xe5\xa9\x5a\x3d\x2d\xb5\xcc\x96\x4c\x59\x42\x55\xc3\x05\x69\xf7\x65\xa6\x86\x41\x38\x29\xd3\xd4\x56\x9d\x96\xf2\x11\x16\xcf\x56\xcf\xb5\xca\xf3\xbf\xe6\x0a\x85\x21\xed\x3c\x55\x9e\x0f\x8f\x3e\x3b\xd1\x3a\xdf\xc4\xbc\x4e\x48\xcb\x00\x18\x3e\xe8\x82\xa3\x0d\x09\x3c\x87\xca\x21\x22\xca\x24\x15\xc3\x35\x5a\x8d\x0b\x81\x3f\xc9\xca\xa6\x24\xbc\x25\x5b\xbb\x11\xdc\xb2\x69\x16\x07\x37\x6d\x95\x9d\xcf\x78\x81\xec\xd0\x72\x5c\x4d\xa1\x1a\x43\xec\x8d\x1a\x6b\x25\x3b\x5e\x43\x0d\x1b\x11\xd1\x39\x30\xb9\xb6\xc3\x76\x3c\x31\xf1\x34\x83\x5a\x28\x25\x77\x8b\xdd\xa8\x32\x36\x15\xcc\x16\x89\x51\x41\x44\x5d\x84\x13\x54\x1b\x12\xe1\xaf\xd9\x1c\x10\x24\xf5\x5d\x66\x04\x10\x3d\x18\x48\xa9\xca\xcc\x5c\x15\x02\x44\xa9\xd3\x09\xd2\xa3\x00\x5e\x8c\x2a\x43\x00\xe6\xda\xa2\xff\x65\x1c\x10\x2b\x36\x88\xc6\x08\xcd\x8d\x90\x1d\xaf\x86\x2b\xec\xe4\x0e\x76\x04\x7e\x88\x6c\x30\x61\x98\xfc\x54\xcb\x5f\x90\xed\x74\xab\x4d\x39\x10\xb2\x8c\x86\xf5\xd0\x61\xf2\xd2\xb3\xf6\x0f\xb9\x7b\xa9\xbf\x41\x21\x76\x2b\xad\x8b\xf1\xc9\x82\xae\xfc\xeb\x28\xcd\xdc\xb8\x20\xf2\xb9\xe2\xcb\x6b\x9a\x2d\xe3\xf4\xbd\xdb\xb0\x8b\x5e\x15\x05\xb9\xc0\xe4\xd2\x3b\xb2\x4d\x11\x88\x08\x62\xc4\x1c\xd9\x4d\xaf\x9b\x63\x8e\xf0\x8c\x86\x98\x23\x51\xed\xa2\xe1\x87\x7a\xcc\x91\x4b\xf2\x16\xcc\x7a\xd3\x9a\xd9\xad\xa4\x45\x78\x59\x51\x60\x52\x87\xf6\x37\x52\x97\x2c\x2b\x9c\xc9\xd8\xc0\x5f\x1a\xf2\xc2\x93\xa2\xf9\xd9\x4c\x46\x97\x24\x83\x6b\xed\x9d\x7c\x4c\x56\x92\xbb\xaf\x16\x24\x0c\x4e\x7b\x1f\xc5\xcb\x09\x71\x92\x90\x27\x87\xcc\xb8\x7b\xfa\x89\xa0\x9b\x41\x49\x49\x6e\x5a\x90\x84\x74\x57\xbd\x5e\x03\x24\x79\x91\xc7\x41\xf9\x80\x5b\x09\xe6\xbd\x04\x2d\x95\x59\xe2\xa1\xce\xc1\x03\x5c\x47\x71\xc2\x92\xb3\x9b\x5c\x58\x8c\x99\xe2\x97\x70\x14\x95\xfb\xa7\x32\xd2\xb3\xdf\xc7\xea\x75\x35\x95\x4e\x21\x4d\x46\xea\x60\x77\xa1\xbb\xf3\x2a\xcd\x98\x1f\x3b\x87\x47\x4a\x9e\xad\xbe\xa3\xcb\x82\x34\x02\x94\x98\x55\xb7\x19\x47\x46\x7d\x91\x6f\xe3\xac\xb7\xa2\xcf\x8d\x2b\xab\x7f\x93\xe7\xf6\x95\xd5\x77\xb0\xff\x7f\xe3\x3d\x27\x5f\x7b\xb7\x9b\xba\x6c\xed\xbc\x1a\x2e\x70\x8b\xa0\x6c\x0b\xd3\x15\xf1\xbf\xb4\xdd\xd4\x29\x0d\x67\x87\xf3\xc5\xea\xa0\xe9\x54\x02\x87\xfb\xc6\xf3\x4a\xfb\x49\xe6\xc0\x71\xa9\xf1\xb8\x22\x03\x68\x69\x69\x9e\xf3\x2f\x50\x10\xea\xce\x1c\x38\x50\x85\x34\xf6\x77\x8d\x7d\x93\x06\x83\x2b\x39\x2a\xd2\x96\x50\x03\x16\xdf\x05\xb6\x0f\x43\x8d\x47\x94\xf3\xce\x53\xda\xfe\xbb\xa1\x3c\xf4\xaf\x52\x51\xbd\xb4\x22\x2c\x8b\xae\xae\x68\x66\xf6\xce\x3e\xd8\x58\x27\xae\x82\x7c\xef\x89\xde\x8d\x44\xa7\x3e\x1f\x15\xe4\x9f\x9e\xf1\x02\xcb\x3a\xad\xe8\x41\xed\x8e\xe5\x98\x7d\xaf\x06\xde\x3a\x6d\x28\x24\x50\x10\x47\xc1\x3b\x1d\x29\xcc\x78\xf0\xf8\xa3\xfd\x26\xb7\xd7\x73\x28\x5f\xb9\xfb\x3d\x53\x6b\x36\x87\xc7\xe9\xba\xc2\xdf\xad\x0a\xe2\x68\xce\x6b\xf4\x7a\x0e\xf3\x66\xbc\xe3\xbd\x1e\xd3\x56\x60\x6c\xb8\xe4\x52\xbd\xf5\x14\x42\x56\x15\x2d\xab\x83\xfc\x3f\x3e\xf4\x88\xf3\x56\x2c\xbe\xdc\x9b\xcd\x49\xa2\x2e\x16\x05\xf3\x52\x8a\x48\x50\x44\x24\x43\x3f\x0c\x65\x3a\xa8\x52\xbc\x5a\x4a\xdb\x49\x64\xe5\x27\x61\x4c\xbf\x4a\x03\xb8\x05\x54\x2e\x09\x1a\x52\xdb\x00\x64\x74\x9d\x5e\xd3\x4a\xe3\xf5\xc4\xb6\xea\x62\x86\x3d\xf5\xa3\xf5\xc0\xb4\x4a\xdf\xff\x2b\x62\xab\xaf\x38\x61\x78\x95\xef\xd6\xbe\x45\x21\x35\x2b\x59\xdf\xed\xa7\xb8\x8b\x74\x9b\x53\x2e\x3e\x5c\xa6\x69\xcc\xa2\xcd\x53\xf1\x12\xda\x3b\x90\x77\x04\xd8\xb7\xd4\xbf\xa6\x6d\xd0\x1a\x32\x0f\x8d\x82\xec\xfc\xa1\x3e\xcb\xae\xb6\x23\xf5\x2c\x0f\xfe\x41\x77\x5f\xa5\xef\x13\xcf\xfe\xfc\xc0\x13\x70\xeb\xb1\x76\xf8\x36\xca\x2f\xd2\x6d\xc2\x68\xe8\x75\xc7\x0d\xc7\xdc\x53\x8f\xa2\x17\x55\x45\xaf\x38\x19\x19\xd0\x47\xc4\x50\x3a\x0b\x0a\x3c\x4d\x65\x5c\x83\x34\x56\xdb\x70\x95\x96\xd5\x99\x4a\x2f\x4f\x58\x84\x90\x14\xc4\xd4\xcf\x5e\xaf\xd2\xf7\x97\x42\x18\x54\x45\x21\xfd\x9b\x28\xa4\x3a\xbd\xf8\x39\x4f\xf6\x07\xe9\xb8\xf9\xc0\x28\xd9\xaa\x8e\xfa\x22\xdd\x98\xe2\xc7\x83\x31\x6f\xb0\x2c\xa8\xf8\xb4\xba\x4f\x78\xbb\x2a\xbb\x25\x0f\xec\xf5\xde\xd6\x85\x2a\x1b\xa8\x4a\x13\xc2\x2b\xb0\x02\x07\xe3\xe2\xf0\x12\x6a\xf1\x72\x72\xf7\x9e\xe4\xe5\xc4\x99\x3d\xb1\xe7\x93\x0e\x37\x34\xcb\xa3\x5c\xf7\xca\x1c\x00\x8f\x4b\x97\xb2\x28\x64\x96\x0b\x11\x78\x3b\x2d\x85\x38\xe0\x42\x0e\x9c\xe0\x10\x56\x7d\x35\x56\xa6\xd9\x3b\xf4\x2c\x0f\xfc\x0d\x08\xa0\x74\xf8\x8e\xee\x24\x76\xbc\xae\x7c\x63\xd9\xa0\x34\x10\x22\x7d\xc3\x3d\xc8\x84\xb5\x04\xfc\x66\x53\x06\xb1\x57\x6b\x81\x5d\x61\x27\xd4\x96\x2d\x54\x89\xa2\x6f\x37\xe9\x86\x8f\xad\xa7\xf4\x1f\x82\xd3\x1e\x44\x02\xb6\xf6\x49\x5b\x04\x59\x36\x8d\xf2\x17\xfe\x0b\x87\xcd\xe8\x1c\x4f\xbf\x9f\xd1\xb9\xcb\xe0\x9f\x42\xb1\xbf\x8a\x09\x50\x9d\x88\x20\xf9\xf0\x62\x6c\xda\x48\xe9\x94\xda\x19\xfb\xbd\xd2\x5e\x08\x7f\x9c\xb4\xd7\xa3\x82\x89\xe4\x34\x7c\xe5\x83\x3d\x78\x93\xfd\x91\x55\xc6\x30\x9d\x33\x52\x1d\x3c\x69\x47\x84\x93\xde\x6c\x34\x17\x32\x40\x63\x91\xc2\x5c\x25\x14\x17\x45\x6d\x83\xac\xeb\x8e\x4e\x5f\xa4\xe6\x2a\xa8\x91\x73\xb9\xf5\xb4\x90\x33\x3c\x6d\x17\xd4\x0c\x5b\x51\x9b\x47\x7e\xb9\xde\x9d\x83\xa8\xb4\x4b\x3c\xf6\x08\xe8\xe6\x0e\x8d\xc0\x49\x8b\xfb\xe3\x2d\x68\xd8\x72\x2a\x0d\x98\xac\x17\xf2\x2c\xc8\x26\x86\x4d\x73\xa1\x62\x68\x24\xb5\xf1\x3a\x02\xd7\xe8\x4e\x53\x0f\x4b\xb8\x4d\xc2\xe0\xc1\xc5\xac\x58\x6d\xbe\x89\x23\xe6\xa0\x0e\xc2\x13\x56\xf2\xdd\x98\x5e\xf9\xc1\x4e\x32\x5e\xa7\x36\xfb\xfb\xfd\xdf\x4b\x05\xa1\xb5\xa1\x62\x3c\x3d\x7b\x6f\xb1\xe9\xaa\xfb\x63\x15\xb4\x64\x55\xf2\x1a\xdd\x22\x16\xce\xf3\x1a\xb0\xd3\x04\x6f\x16\xc4\xae\xd1\x41\x71\x02\x11\xfd\x6b\xed\xcb\x1d\xf6\x49\x13\x8f\x43\xf8\xd6\x90\x2b\xc4\x51\x00\xc4\x94\x97\xc9\xa5\x14\x4f\xaa\x86\xa8\x16\x7e\x0d\x0f\x8e\x32\x7c\x9b\x69\x30\xea\x3e\x5f\x56\x2e\x94\x8a\x85\x0b\x45\x1f\xa3\x1d\x03\x52\x73\x53\xd5\xa3\x8d\x41\xeb\x8a\xd1\x5b\xc4\x58\x57\x5c\x37\x91\xe9\x60\x0c\x7b\xa9\x9e\xca\xb5\x9f\x6c\xfd\x18\xf1\xd9\x72\x68\xd3\x0c\xf3\xed\xa0\x89\xb2\x71\xaf\x17\xca\x05\x53\x1f\x33\x75\x46\x15\x73\x58\x5f\x5d\xa4\x3b\xaa\xc8\x92\xea\xca\x43\x8d\x9a\x3a\x74\x9a\x48\x99\xf2\x8c\x18\x80\xda\x9c\x3b\x68\xcd\xa5\x26\xe1\x89\xbe\x4e\x2b\x65\xbb\xad\x35\xb7\x4c\xa1\x6d\x92\x1e\xaf\xc8\x45\x20\x8d\x0b\x5c\xc2\x1c\xc3\x05\x0a\x45\x89\x81\xc9\x41\x04\xa0\xb8\x8d\x80\x68\xb7\xad\xc2\x3b\xba\x0b\xd3\xf7\x0a\xbe\x29\x45\x41\x3d\xb1\x43\x36\x1c\x54\x6b\xd2\xbf\x9e\x04\xc7\x10\xfd\xef\x38\xb2\x87\x2a\xb7\x0f\xee\xa1\xba\x87\xbb\x79\xa8\xe6\xa1\x09\x38\x50\xa3\x69\x0e\x34\xb1\x37\x2d\xdc\x53\xe8\x9d\xcf\x85\x79\x3a\xab\x5f\x39\xb5\xdc\x92\x49\xee\xda\x1d\xe1\x09\x55\x16\x43\xcd\x33\x76\xf0\xb0\x46\xa7\xc2\x62\x67\x99\xa5\x6b\xce\x49\x67\xf3\x03\xc2\x46\x6b\x8e\xdc\x1e\x14\xd4\xd9\x68\xae\xa9\xd3\x6e\x1d\xfa\x2b\xb5\x1c\x0d\xf6\x22\xa6\x64\x2c\xb5\xa6\xfb\x7d\xb7\x72\x16\x9d\xd2\x26\x3f\x8c\xe6\x9e\x55\x0a\x83\x8d\xfa\xef\x66\x41\x59\x9d\xb0\xb7\x71\x3c\x69\x38\x34\x4f\xce\xf6\x3b\x67\xeb\x62\xe1\xbe\x40\x5e\x0a\xe6\xd6\xc5\x5d\xd0\x78\x01\x17\x5b\x97\x0d\x27\xde\x08\x2e\x1b\xee\x00\x43\xcf\xbc\xfa\x5b\x79\xa6\x45\xdd\xc2\x53\x57\x91\x70\x55\x08\x21\xf8\x2f\xd4\x8d\xe5\x55\x49\x7a\xed\x3e\xf3\xbe\xc6\x46\xac\x0e\xb8\xda\x5a\x8a\x30\x19\x66\x52\x6a\xbc\x36\xa9\xab\xfd\xbf\x31\x1f\x97\x30\xa5\x62\x3f\x87\xd6\xe4\xb1\xdf\x37\x54\xa8\x79\x83\x46\x3d\x30\x6e\x7c\xea\x4a\xea\x6d\x4d\x45\x5e\xd3\x8c\xef\x0c\x4d\xbf\x69\x1e\xb3\x52\x2a\xe7\x85\xa1\x31\x4f\x84\x2e\x76\x2d\xd4\xc0\x17\x45\xc3\x85\x95\xb8\xf0\x68\x0e\x1e\x62\xdc\x80\x18\xaa\xfe\x6b\x19\xe1\x87\x89\xb3\x3f\x22\x86\x62\x43\xdd\x93\xb5\x68\x3a\x88\xa9\x3b\xb0\xca\x36\x68\x13\x48\x9a\x48\x66\xea\xd6\xd8\xab\xe1\x7a\xd0\xba\x5e\xf9\x87\x71\xbd\xf2\x35\xf9\x87\x7d\xbd\xf2\x4f\x58\x3f\x9f\x78\xff\x20\xff\xd3\x20\x44\xc3\x75\xa9\xee\x93\x38\x36\x91\x1a\x29\x63\x92\x58\x25\x07\xb0\xc2\x10\xa9\x2e\xb5\x03\xb4\xf6\x49\x75\xb4\x29\xb9\xad\xce\x32\xab\xde\xa2\x24\xf0\xe0\xe9\x7f\xac\xee\xfd\x4f\xe5\xc1\x93\x61\x7b\xc4\xd2\x0d\x32\xf4\xf7\xa3\x1a\xa5\xa1\x45\x3e\xd0\x9d\xd5\x0a\x7c\x90\x63\x3a\x42\x82\x28\x26\x6c\xe8\x7b\xff\x53\xcc\xe7\x78\xf2\xff\x7b\xf0\xe0\x4f\x9d\x3c\xdd\x66\x01\xbd\xf0\x37\x9b\x28\xb9\xfa\xfe\xbb\x6f\xbd\x87\xc3\xc5\x9f\x47\x7f\xf5\x17\xe3\x2f\x87\xc1\x6a\x9b\xbc\x1b\xfe\x3b\x1f\xae\xfd\xcd\xff\x17\x00\x00\xff\xff\xe4\xfe\x08\x43\x9d\x6d\x0f\x00") + +func pkgUiStaticReactStaticJs2B309ab18ChunkJsBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactStaticJs2B309ab18ChunkJs, + "pkg/ui/static/react/static/js/2.b309ab18.chunk.js", + ) +} + +func pkgUiStaticReactStaticJs2B309ab18ChunkJs() (*asset, error) { + bytes, err := pkgUiStaticReactStaticJs2B309ab18ChunkJsBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/static/js/2.b309ab18.chunk.js", size: 1011101, mode: os.FileMode(436), modTime: time.Unix(1589211666, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactStaticJs2B309ab18ChunkJsLicenseTxt = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x56\xcf\x52\xdb\x4c\x12\xbf\xfb\x29\x7a\x39\x01\x25\x64\x1b\xf8\xb2\x09\x27\x84\x2d\xe3\x21\xb2\xe4\x95\x44\x58\x72\x1b\x4b\x6d\x6b\x88\x3c\xa3\x9d\x19\x99\x22\x4f\xbf\xd5\x23\x61\x30\xa9\xd4\xd6\x5e\xbf\x9c\x5c\xee\xe9\xee\xdf\x9f\xd6\xb4\x34\x3c\x1d\xa8\xd5\x13\x16\xf6\x8c\x1b\x23\x36\x72\x70\x5c\x9c\x40\x26\x64\xa9\x11\x32\xa5\xab\xd6\x0c\xae\x6b\x51\xa0\x34\x08\x0b\x96\x0f\x4e\x87\x83\xc1\xf0\xf4\x1f\x03\x00\x38\x85\x4c\xfc\xfc\x59\x23\x4c\xb2\x0c\x32\xac\xb1\xb0\x4a\x43\x28\x37\x42\x22\xec\xce\xfd\x0b\xff\xb2\x4b\xab\xac\x6d\xcc\xd5\x70\x68\x5c\xfa\x93\xf1\x0b\xb5\x1d\xba\xa3\xee\x7c\xa2\x9a\x17\x2d\x36\x95\x85\xbb\x0c\x66\xaa\x95\x25\xb7\x42\x49\xe0\xb2\x04\x65\x2b\xd4\x50\x28\x69\xb5\x58\xb5\x56\x69\xd3\xd5\xa4\x58\x23\x37\x58\x42\x2b\x4b\xd4\x60\x2b\x47\x0f\x7a\xaa\x87\xb8\x4f\xc6\x5f\xef\xbb\xbe\x07\x9e\x72\x8b\x57\x70\x3e\x1a\x7f\x39\x1b\x5d\x9e\x8d\x3e\xbb\xe8\x5e\xe0\x1b\x2d\xf2\xe4\x7c\x34\xfe\x27\xdc\x61\x09\x0f\xdc\x1a\x25\xfd\x01\x40\xd4\x81\x7d\xe4\xd0\x87\xe1\x78\xc1\xf2\x13\x0f\x0c\x12\x1d\xe2\x42\x54\xb0\x7c\xee\xea\x37\xc2\x56\xed\xca\x17\x6a\x58\xd4\xdc\x18\xc9\xb7\x68\xde\xdc\x3d\x85\xa7\x7f\xb5\xa8\x5f\xe0\x8e\xef\x78\x56\x68\xd1\x58\x88\xc4\x4a\x73\xfd\x02\xbb\x0b\xff\xd2\x1f\x0f\xde\x0b\xfc\x0f\xe5\xf6\xb6\x9e\xd2\x09\x93\x45\xdd\x96\x68\xfa\x11\xf9\x4f\x66\xf0\xfb\x41\xb8\x8a\xff\x77\x08\xff\x7b\x04\xbf\xf0\x53\x7a\x33\x7c\x3b\x1d\x7c\x18\xc0\x5f\x67\xa3\x71\x7e\x3e\xbe\x1a\x5d\x7e\x1f\xf4\x53\x38\x85\xfd\xb3\x97\x22\x2f\x2c\xec\x46\xfe\xf8\x4b\xa7\xdd\x14\x15\x96\x6d\x8d\xda\x6f\xb4\x2a\xdb\x82\xc8\xfa\x5b\x21\x3b\xa9\x87\x8a\x68\x7e\x33\x5e\xe0\x4a\xa9\x1f\x1e\x79\xe3\x3b\x59\xc2\x1a\xe0\xeb\xb5\xa8\x05\xb7\x68\xfc\xbe\x2c\xaf\x84\x01\xa3\x5a\x5d\x20\x14\xaa\x44\x10\xe6\x55\xd3\x6f\xa4\x82\x7b\xba\x40\x48\x3a\xa0\x16\x11\x9b\x84\x71\x16\xc2\x5a\xd4\xd8\x87\x41\x2b\x65\xa1\x14\xda\xdd\x92\x17\x50\x6b\xb0\xef\x80\xac\x46\xf4\x7f\x2f\x7b\xfc\xc9\x1f\x5f\x74\xba\x35\x45\xce\x4a\xb5\xfd\x23\x75\x0b\xf3\x27\xca\xfe\x1b\x6a\x76\x3b\xee\x9a\xaa\x93\x1d\xea\x9d\xc0\x67\xf8\x2a\x8a\x1f\xdc\x10\x93\x6e\xcf\x59\x05\x85\x46\x6e\xd1\x29\x69\x6a\x5e\x20\x34\xaa\x69\x50\x1b\x90\xc8\x1d\x47\xa1\x41\xe3\x1a\x35\xca\x02\x01\x6b\xdc\xa2\xb4\x4e\x26\x5c\xef\x50\x1b\x5a\x60\x63\x9f\xec\x74\xa1\x77\xab\xe9\x97\xe5\xfe\x09\x66\x58\xa2\x16\x85\x82\xef\x62\xa7\x6a\xe5\x50\x3f\xec\x3c\xaa\x5c\xa2\xde\x0a\xe3\x5a\x0b\x03\x15\x6a\x5c\xbd\xc0\x46\x73\x69\xb1\xf4\x60\xad\x11\x49\x79\x51\x71\xbd\x41\x8f\x44\x70\xf9\x02\x44\x5a\x49\x50\x2b\xcb\x85\x14\x72\x03\x1c\x0a\xd5\xbc\x50\xbf\x37\x9b\xd6\xf6\x99\xeb\x4e\x2d\x37\x46\x15\x34\xb3\x12\x4a\x55\xb4\x24\xab\x5b\xc7\xe4\x98\x81\x63\xb2\xfb\x28\xeb\x2b\x8e\x4e\x1c\x4e\x89\xbc\xa6\x86\xfd\x34\x5e\x4f\xe1\x59\xd8\x4a\xb5\x16\x34\x1a\xab\x85\x7b\x8a\x3c\x10\xee\x05\x41\x4c\x5e\x8f\x6b\xb1\x15\x3d\x88\x1b\x26\x99\xe3\xf6\xbc\x55\xd0\x1a\xf4\x1c\x61\x0f\xb6\xaa\x14\x6b\xfa\x45\xa7\xaf\x69\x57\xb5\x30\x95\x07\xa5\x30\x9d\x53\xe8\x81\xa1\xa0\xb3\xda\x23\x35\x43\xa5\xc1\x60\xed\xc8\x15\xaa\x11\x68\x3a\xd1\x6f\x1c\x5d\x1a\x01\x35\x64\xae\xed\xed\x32\x14\x79\xae\xd4\xf6\x50\x8f\x70\xac\xd6\xad\x96\xc2\x54\xe8\xca\x4a\x05\x46\x39\x5c\xfa\x94\xa1\x08\x55\xac\x55\x5d\xab\x67\xd2\x58\x28\x59\x0a\x92\x66\xae\xf6\x57\x00\x81\xaf\xd4\x0e\x9d\xac\xee\x49\x90\xca\x8a\xa2\xf3\xdf\x4d\xa4\x79\x9b\x74\x7f\x64\x2a\x5e\xd7\xb0\xc2\xde\x3e\x74\x37\x82\x1f\x2a\xd3\x44\xc3\x58\x2e\xad\xe0\x35\x34\x4a\x3b\xdc\x8f\x8a\xf7\x57\x71\x1e\x42\x96\xcc\xf2\x87\x20\x0d\x81\x65\xb0\x4c\x93\x6f\x6c\x1a\x4e\xe1\x28\xc8\x80\x65\x47\x1e\x3c\xb0\x7c\x9e\xdc\xe7\xf0\x10\xa4\x69\x10\xe7\x8f\x90\xcc\x20\x88\x1f\xe1\x2b\x8b\xa7\x1e\x84\xff\x5e\xa6\x61\x96\x41\x92\xba\xd7\xfe\x62\x19\xb1\x70\xea\x01\x8b\x27\xd1\xfd\x94\xc5\xb7\x70\x73\x9f\x43\x9c\xe4\x10\xb1\x05\xcb\xc3\x29\xe4\x89\xc3\xec\xbb\xb1\x30\xa3\x7e\x8b\x30\x9d\xcc\x83\x38\x0f\x6e\x58\xc4\xf2\x47\x8f\x7a\xcd\x58\x1e\x53\xe7\x59\x92\x42\x00\xcb\x20\xcd\xd9\xe4\x3e\x0a\x52\x58\xde\xa7\xcb\x24\x0b\x21\x88\xa7\x10\x27\x31\x8b\x67\x29\x8b\x6f\xc3\x45\x18\xe7\x3e\xb0\x18\xe2\x04\xc2\x6f\x61\x9c\x43\x36\x0f\xa2\x88\xd0\xa8\x5d\x70\x9f\xcf\x93\x94\x88\xc2\x24\x59\x3e\xa6\xec\x76\x9e\xc3\x3c\x89\xa6\x61\x9a\xc1\x4d\x08\x11\x0b\x6e\xa2\xb0\x43\x8b\x1f\x61\x12\x05\x6c\xe1\xc1\x34\x58\x04\xb7\xa1\xab\x4a\xf2\x79\x98\x76\xab\xe7\x95\x26\x3c\xcc\x43\x8a\x12\x6a\x10\x43\x30\xc9\x59\x12\x93\x9e\x49\x12\xe7\x69\x30\xc9\x3d\xc8\x93\x34\xdf\x57\x3f\xb0\x2c\xf4\x20\x48\x59\x46\xce\xcc\xd2\x64\xe1\x94\x92\xbb\xc9\x8c\xb2\x58\x4c\xa5\x71\xd8\x35\x22\xe7\x0f\x07\x94\xa4\xee\xff\x7d\x16\xee\x7b\xc2\x34\x0c\x22\x16\xdf\x66\x54\xdc\x6b\x7d\xcd\xdf\xaf\xbb\xeb\x46\xa3\x41\xbd\x73\xab\x27\xc7\x6d\xd3\x1a\x98\xaa\xad\x90\xad\x81\x1b\xa5\xac\xb1\x9a\x37\x97\xb0\xfb\xcb\x1f\xfb\xe7\x70\xfc\xfa\xdd\x64\x5d\x66\xd9\x25\xbe\xfb\x62\x5c\xbd\x96\x9c\x5d\x0e\x4f\x0e\xb7\x19\x6d\xb2\xb3\xf3\xd1\xf8\x33\xdc\x29\xc9\x6d\xc5\x25\x2c\xd1\xba\xeb\xe4\xbc\x3b\xdc\xf2\xb4\xe1\xf7\x68\x7d\x7f\xfa\x26\x3c\x00\x7e\x07\x77\x31\x5c\xd5\x6a\x35\xdc\x72\x63\x51\x0f\xfb\x77\xc0\x89\x53\xf9\xdf\x00\x00\x00\xff\xff\x2e\x8b\x56\x53\x49\x0c\x00\x00") + +func pkgUiStaticReactStaticJs2B309ab18ChunkJsLicenseTxtBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactStaticJs2B309ab18ChunkJsLicenseTxt, + "pkg/ui/static/react/static/js/2.b309ab18.chunk.js.LICENSE.txt", + ) +} + +func pkgUiStaticReactStaticJs2B309ab18ChunkJsLicenseTxt() (*asset, error) { + bytes, err := pkgUiStaticReactStaticJs2B309ab18ChunkJsLicenseTxtBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/static/js/2.b309ab18.chunk.js.LICENSE.txt", size: 3145, mode: os.FileMode(436), modTime: time.Unix(1589211666, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactStaticJsMainBd8c49dcChunkJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\xfd\x09\x7b\xdb\x36\xb6\x38\x0e\x7f\x15\x1a\x9d\x51\x88\x0a\xa2\x25\x2f\x69\x42\x05\xd1\x9b\xc5\x6d\x32\x93\x6d\x62\xa7\xbd\x1d\x55\x3f\x3f\x10\x09\x49\xac\x29\x50\x25\x21\x2f\x91\xf9\xdd\xdf\x07\x07\x00\x37\x51\xb6\xd3\xf6\xde\xe7\x7f\xe7\x36\xa6\xb0\xe3\x00\x38\x3b\x0e\x5c\xb9\x88\x32\xef\x8a\x4f\x57\x2c\xb8\xf8\x57\x96\x88\xd5\x3c\x65\xab\x05\x6d\x4f\xbe\xbd\x1d\x4f\xb0\xb7\x5a\x67\x0b\x77\x3c\xee\x4f\xc8\x66\x30\x38\xf2\x67\x6b\x11\xc8\x28\x11\x2e\x27\x92\x30\xbc\xc9\xc9\x60\xf0\x78\x2b\x15\xad\x33\xee\x64\x32\x8d\x02\x89\x86\xcc\x4b\x5d\x89\x87\x97\x2c\x75\x04\x65\xee\xe0\x07\x4c\x52\xca\x3c\xe1\x0a\x3c\xbc\x8a\x44\x98\x5c\x79\xbf\xff\x67\xcd\xd3\x1b\x9a\x7a\x8c\x98\x94\x65\xb2\xe4\x42\x52\xe6\x1e\xf4\x75\xd5\x84\x32\xb7\x8f\x49\x0c\x35\x13\x4c\x22\x95\x77\x88\x49\x06\x09\x11\x26\x81\x6a\xfb\xf0\x29\x26\x6b\xf5\xf1\x04\x93\x05\x65\xee\xe1\x0f\x98\x2c\xa1\xc4\x02\x93\x15\x94\xc0\x24\xa4\xcc\x3d\x7a\x8a\xc9\x9c\x32\xf7\x31\x1e\x06\x89\xc8\xa4\x33\xa3\x6a\xf0\x98\x3e\xdf\xe8\xdf\x8c\x7e\x9c\xfe\xce\x03\xe9\x26\xde\x3a\xe3\xa7\x92\x49\x8e\xdd\x4d\x26\x99\x5c\x67\x3e\xca\x24\x4b\xa5\x33\xe3\x32\x58\x44\x62\x8e\x72\x4c\x84\x2d\x3f\xf7\x18\x76\x19\x39\x50\xb3\x14\x0a\x6e\x31\x15\xe3\xc1\x84\x44\x6d\x0d\xaa\xf1\x57\xeb\x45\xaa\x5e\x40\x33\x55\x6f\x4d\x33\x55\x6f\xd1\x56\x6f\xaf\x8f\xc9\xac\x56\x73\xa1\x6a\x5e\xd3\x99\xaa\x39\xa5\xb3\xf1\x60\x32\x4c\xb9\x5c\xa7\xc2\xa9\x56\x3f\x99\xcd\x78\x20\xb1\xeb\xaa\x89\xba\xc5\xb2\xe1\x8d\x02\x71\x31\xe5\x50\x35\xb8\xf4\x98\xb7\x64\xe9\x85\x5b\x14\x73\x98\x29\x28\x48\x6a\x1b\x57\xa5\xae\x52\xb6\x2a\x4b\xb9\x0c\x6f\x66\x49\xea\x0e\x87\x38\xbb\x8a\x64\xb0\x70\x99\xb7\x4a\xf9\xa5\x5a\x05\x7e\x2d\xf1\x26\x60\x19\x77\xfa\xbe\x69\x60\x0a\x73\x31\x45\x06\x44\x17\xa2\x47\x04\x60\xeb\x72\x62\x86\xb4\x52\x43\xda\x04\x2c\x58\x70\x1f\x89\xa4\x97\xc9\x24\xe5\x88\x04\x29\x0f\xb9\x90\x11\x8b\xd5\xa2\xb0\x25\xef\x25\x69\x34\x8f\x04\xca\x89\xc4\x78\x08\x5d\x1d\xf9\xd1\xcc\x75\x05\x65\x5e\xc6\x85\xc4\x5e\x72\x81\x37\xa6\x9b\x1f\x86\xd3\x94\xb3\x8b\x5c\x2e\xd2\xe4\xca\x11\xfc\xca\x39\x49\xd3\x24\x75\x85\xa7\x17\xfa\x4c\x0d\x58\xb7\xf2\x83\x1d\xb0\xa9\xfa\x94\x08\xef\xf7\x4c\xc1\x4e\xe7\x3f\xf5\x53\xd3\x03\x89\xdd\x14\x93\xa9\xbb\x37\xc0\x76\x3a\x03\xd3\x91\x2e\x3a\x38\xf2\xed\x7c\x8f\x08\xf3\x64\x9f\x32\x2f\x60\x6a\xba\x03\x4c\xd6\xae\x4a\x31\x8d\x0e\x7e\xf0\xd5\x5f\xc4\x45\x88\xca\xfe\x33\x99\xac\x5c\x9c\xe7\x98\x30\x22\xd6\x71\x4c\xc6\xe3\x01\x19\x1c\x4d\x26\x38\xc7\x18\xdb\x95\xa9\x2c\x6e\x51\x93\xad\x56\xf1\x0d\x60\x01\xc2\xd2\xf9\x5a\x1d\xb1\x4c\x35\xe4\x62\x17\xe7\x64\xcc\x89\x9c\x60\xb2\x49\x79\xb6\x4a\x44\xc6\xfd\x94\x70\x05\x0e\x3f\x20\x51\xf6\x2e\x61\x61\x24\xe6\xfe\x75\x9e\xc3\x79\xbc\x56\xe7\xef\x07\x4c\xa6\xea\x50\xa9\xe3\x76\xa3\x3e\x8e\x30\x39\xa1\xcc\x7d\x6a\x4f\xd5\x25\xe5\xf4\xb9\xa4\xcf\x37\x31\x57\x47\x4a\x7a\xd0\x20\x11\x54\x7a\x45\x93\x24\xa5\xd2\x0b\xd6\x99\x4c\x96\x00\xfd\xf7\xd9\x9c\x24\x2a\x29\x59\xae\x12\xc1\x85\x3c\x8b\x64\xcc\xcb\xf3\x73\xad\xb6\x82\x24\x63\x04\x6d\x21\x82\x8a\x96\x10\x41\xf5\x76\x54\x42\xad\x15\x34\x29\xe0\xc3\x46\xb1\xc7\xbc\x20\xe5\x4c\xf2\x93\x98\x2b\x58\xb8\x53\x8f\x91\x4d\x90\xc4\x49\xea\xa3\x90\x89\x39\x4f\x51\x4e\xd2\xdb\xdb\xed\x92\x2a\xe5\xc7\x94\xcd\xd5\x0f\xbd\x08\xdb\x65\x50\x26\xd3\x44\x8d\x0a\xf2\x11\x0c\xca\x47\x98\x20\xbd\xcb\x0a\xf4\xe1\x20\x92\xdc\xde\x72\x2f\x8c\xb2\x55\xcc\x6e\x3e\xb0\x25\x27\xc8\x77\x10\x61\xde\x92\x67\x19\x9b\x73\x8c\x7d\xd1\x32\xdc\x1b\x35\xdc\x2c\xfa\xca\x7d\x74\x78\x8d\x48\x14\x24\xc2\x3f\xf1\x62\x92\xad\x22\xe1\xef\xf5\x49\x10\xb3\x2c\x53\xcd\xf9\x68\x95\x64\x91\xda\x0d\x3d\x36\xcd\x92\x78\x2d\x39\x22\x99\xbc\x89\xb9\xbf\x91\x29\x13\xd9\x2c\x49\x97\x3e\x82\xcf\x98\x49\xee\xf6\x8e\xfb\xff\x24\x8e\xfa\x17\x23\x22\x93\x95\x8f\x8e\xfb\xff\x44\x24\xe6\x33\xa9\x3f\xf3\x1c\xfb\xdb\x03\xe2\x24\xc2\x7a\x7b\x5c\x00\xae\x3d\xc2\xe4\x0a\x3e\x0e\x31\x39\x55\x1f\x07\xc7\x98\x9c\xa9\x8f\xc7\x98\xbc\x02\xbc\x7c\x86\xc9\x7b\xc8\x79\x8c\xc9\x47\xf8\xf8\x01\x93\x4f\xf0\xf1\x04\x93\x0f\xf0\xf1\x14\x93\x73\x68\xa6\x8f\xc9\x57\xf8\x18\x60\xf2\x23\x7c\x1c\x60\xf2\x19\xca\x1c\x60\xf2\x3b\x6c\xc5\xa7\x98\xbc\x86\x94\x3e\x26\x6f\x29\x73\x8f\x0f\x30\x79\x07\x09\x03\x4c\x7e\x51\x28\xbf\x8f\xc9\x0b\x95\xd1\xc7\xe4\x0d\x8c\xe1\x05\x26\x7f\xa8\x84\x01\x26\x2f\x21\xe1\x0f\x3c\x04\xd8\x39\x5f\x1c\x7e\x2d\xb9\x08\x33\x27\xf1\x5e\xd9\x9d\xa4\x29\x44\xba\x0e\x64\x92\xba\x1c\x6f\xb2\xf5\x8a\xab\x0f\x02\x74\x94\x5f\xaf\xd2\xb7\x62\xb5\x96\x9f\xf9\x8c\x96\x20\xfa\xcc\x67\xae\x29\x91\x71\xf9\x86\x47\xf3\x85\xa4\x6e\x49\x6f\x38\xdd\xaa\xed\x05\xeb\x34\x55\xfb\x4b\x52\xee\x25\xb3\x59\x51\x8f\x30\xca\xbd\x20\x8e\xb8\xb0\x09\x82\x72\x2f\x0b\xd2\x24\x8e\x4d\x42\x4a\x65\x8f\x0d\x6d\x77\x40\x35\xdc\xcd\x02\xf2\x7c\xd1\x4d\x73\x9c\xeb\xb1\x2c\x98\x08\x63\x0e\x3d\xea\xd1\xd8\x2a\x3f\xb3\x78\xcd\xdd\x9d\x63\xf2\x2e\x55\xbe\x6d\xc5\x96\x57\xa7\x7d\xe3\xf6\x75\xe2\x2a\x4d\x56\x99\x97\x88\x93\xeb\x55\xca\xb3\x2c\x4a\xc4\xab\x85\x3a\x53\xb8\x00\xd5\xd6\xc8\x10\x5b\xcb\x04\xe5\x0d\x30\xd5\xc7\xfa\x6f\x7e\xf3\x49\xb5\x07\x7d\x69\xd8\x49\x5a\xe9\x90\x5f\xf3\x60\x2d\x39\x70\x14\x43\x74\x22\x24\x4f\xd1\x1e\xa5\xdc\xbb\xe0\x37\xea\x94\x65\x8b\x68\x26\xff\xad\xbe\x5d\xe9\x62\xc2\x01\x13\x73\x21\x5f\xf3\x19\x5b\xc7\xd2\xc5\xb6\xbb\x39\x97\xa7\x9c\xa5\xc1\xe2\xbd\xc2\xcd\x3c\xb3\x0c\xc2\x1b\x8f\x79\xb3\x28\x96\x6a\xcd\xbd\x94\xaf\x62\x16\x70\x77\xdf\xd9\x9f\x13\x84\x30\x91\x64\xb3\x4a\xb9\x8f\x9e\xe9\xc3\xff\x1c\x91\x55\x92\x49\x1f\x3d\xdb\xb7\x09\xb9\x99\xbd\xde\x17\x2f\xd6\x32\x51\x38\x2a\xe6\x92\x9f\x72\xc0\xd8\xb5\x99\x71\x2f\x52\xa0\x07\xf0\x12\x46\x2f\x93\x28\x74\xfa\x94\x52\x39\x42\xc8\xd7\x0b\x1f\xc4\x49\xc6\xdf\x73\xb1\x26\x29\xe5\xde\x22\x9a\x2f\x62\x05\x36\x1e\xbe\x15\x21\xbf\x56\xb8\xb4\x84\x0e\xdb\xee\x2e\x1b\x2a\xe4\x1c\xd1\xbe\xc1\xd9\x8a\xa3\x8a\xb9\x98\xcb\xc5\x48\x63\x5c\x8f\x0b\x99\x46\x3c\x73\x13\xec\xa5\x3c\x5c\x07\xdc\x55\xf8\x57\x90\x64\x52\xee\xdf\x8c\xb6\x02\xcd\x65\x24\x29\x50\x6e\x66\xdb\x1d\x7b\x9e\x27\xdb\x30\xe6\x3a\x46\x64\x53\x41\x5b\x6a\xb8\xd9\x7a\x3e\xe7\x99\xec\x85\x69\xb2\x0a\x93\x2b\xd1\x8b\xa3\x4c\x22\x72\xc1\x6f\x7c\x91\xb7\x35\x12\x47\x0f\x68\x64\xc1\x59\x08\xe8\x5d\x60\x92\x79\x59\x1c\x05\xdc\xed\x93\x41\xbf\x8f\xbd\xa5\x62\x67\x36\x9a\x91\x60\xb1\x2f\x89\xe2\x64\xc5\xdc\x67\x79\x39\xdd\x84\x72\x35\xd7\xb7\x92\x2f\x3f\x29\xc0\xba\x1b\x35\x1e\x49\x22\x05\x72\x3f\x22\x91\xe4\x4b\xa8\x09\x38\x76\xca\x82\x8b\x79\x9a\xac\x45\xf8\x0a\x88\x4b\x4a\x29\x8d\xba\xdd\x11\x82\x85\x9a\xa7\xec\x06\xf9\xe8\x6a\x11\x49\xae\x10\xab\x05\xd7\x8e\xa9\x99\x45\x61\x59\x16\xcd\x85\xee\x57\xe4\x24\x21\x1b\x4d\xb1\x92\x75\x16\xdf\x9c\x72\xf9\x56\x08\x9e\xbe\x39\x7b\xff\xce\xdf\x9c\x9f\x2f\xe4\x32\xf6\x5f\xba\x8a\x31\xdd\xb0\x38\x4e\xae\x78\x78\xc6\xe6\x99\x3f\xb6\x34\x6a\x92\x2b\x3e\x40\x31\x10\x13\x5f\xe6\x64\x3c\xc1\xfe\x78\xb2\xb5\x6e\x2d\x23\x0a\xa3\xcb\xad\x21\xe5\x04\x80\xa3\xb6\xa4\x06\x0e\xbe\x77\x3d\xd4\xa9\xc8\xb0\xef\x66\x5c\x9e\x45\x4b\x9e\xac\xa5\x2b\x30\x10\xce\x02\xc7\x28\x4c\x41\x1b\x98\x22\x2f\xc8\xfb\xeb\x28\x7c\x9f\xac\x85\x74\xf1\xa6\x8e\x3d\x5c\x5c\x2b\xf4\x65\x15\x2a\x8c\xc3\x71\x1b\xee\x00\xa4\x36\x94\x80\x2e\xe0\xbb\xd3\x69\xe0\x43\x9c\xa7\x5c\x84\x3c\x75\x71\x1d\x6f\x43\x7d\x40\xd4\x55\xfc\x03\x88\x1a\x1a\x52\x2c\x4f\x31\x0b\x4f\x4f\x62\xf7\x3a\xff\xa2\x08\x7b\x22\x4e\x79\xcc\x03\xe9\xd7\x86\x90\x13\x4e\x9f\xef\x5a\x87\x1d\x8c\xc8\xef\xc0\xd6\x94\x0b\xc0\x0b\x8c\xdc\x03\xe4\x82\xda\x8e\xd1\x6b\x55\x89\x85\x61\x22\xce\x6e\x56\x8a\x83\x48\xf9\x4a\xf1\xa1\x6d\x65\xdf\x7a\x86\x13\xad\xc0\x32\xd6\x3c\xd9\x2e\xb6\xa5\xc9\xac\xb4\xf2\x13\xd5\x92\x17\x8a\xb9\x6d\xe9\xfb\x9d\xc7\x9a\xfb\x2f\x11\x40\xae\xfc\x26\x85\xb3\xc7\xd1\xd2\xc1\x9c\xa8\x5d\xf4\x63\x12\xac\x33\xc5\x2e\x49\x98\xa7\xe4\xd7\x92\xa5\x9c\x21\x92\x26\x57\x99\x8f\x06\x88\x24\xc2\x12\x1d\xbf\x85\x10\x11\xa0\x00\x8b\x24\x0e\x79\xea\xa3\x92\xda\x39\x2e\x7c\x39\xa7\x8a\xe0\x74\x81\x10\x39\xb3\x24\x55\x62\x46\x1c\x09\x9e\x61\x44\x22\x75\x46\x3f\xf3\x99\xbf\x45\x67\xcd\x11\x82\x9f\x06\xc1\xc0\x28\x5e\x27\x57\xc2\x57\x0c\xb5\x91\xad\xa4\x22\x6b\x5a\xa6\x42\x6f\x92\x25\x47\x5a\x60\x38\x51\x02\x83\xf4\x04\x93\xd1\x25\x3f\x51\xe4\xad\x20\x73\xc9\x95\x00\x12\x68\xe8\x1d\xdd\xeb\x57\x64\x13\xf4\x22\x4d\x93\xab\x2f\x2b\xd3\x0c\xfc\x52\x35\x90\xcf\xbd\x28\xfb\xb8\xe2\x42\x91\xcd\x07\xb6\x8b\xab\x0d\x6b\x42\xec\x57\xa8\x95\x5b\xcf\xcf\x02\xb6\xe2\xd5\x7e\x76\xf3\x1e\xd3\x78\x9d\x2a\x01\x28\xc7\x64\x03\xa7\x4b\xa1\xe6\xb6\xbd\xd1\xdc\xc3\x6c\xb5\x73\x0b\x7f\xde\x3a\x23\x70\x8c\x7b\x53\x29\x10\x31\x22\xc1\x2a\x8d\x96\x2c\xbd\x51\x1b\xe2\x55\x1c\x05\x17\x0a\x53\xa2\x13\x5d\x10\xa9\xdd\x69\x07\x6f\xd0\xc6\x4e\x0a\xef\x72\x8c\x71\x9e\x2b\x46\xf9\x67\xfa\x85\xfc\xaa\x64\xa9\x63\x4c\x7e\x02\x36\xf5\x10\x93\xff\xc0\xc7\x11\x26\xff\xa0\x2e\x73\x9f\xfc\x80\x09\x73\x9f\x3c\x81\x7f\x9f\xaa\x7f\x0f\x9e\x62\x3c\xfc\x87\x17\x78\x2c\x0c\xdd\x13\x6f\x4e\x4e\xbc\x05\x39\xf1\x02\x72\xe2\x4d\xc9\x89\xc7\xc8\x89\xb7\xc4\xe4\x1f\x4a\x36\x07\xb9\xd2\xb2\xb3\xff\x73\x2f\x3b\xeb\x79\x5e\xc1\xd1\xc2\xb7\x3e\xd2\x32\x5a\xf2\xbb\x99\xda\x7f\xa8\x22\xb4\x44\x02\x73\x2e\x5f\xb2\x8c\x2b\x64\x0e\x8c\x65\x05\x33\xa8\x92\xb7\xb7\xaf\x94\xd0\xa9\x91\xe3\xc7\xa2\x95\x80\xc5\x01\x9c\x97\xcf\x8a\x96\x41\xc5\x01\x3f\xfc\xbe\x52\x39\x55\x19\xfb\x07\xba\x78\x24\xd4\x38\x2a\xbd\xd4\x91\x72\x65\x0c\x2e\xee\xb6\x74\xe0\xe2\x61\x8d\x55\xd5\x0c\x2a\x94\x2f\x78\xdb\x90\x3f\xbc\x8f\xde\x9f\xec\x23\x88\x39\x4b\xcb\x0e\x76\x95\xaf\x92\x43\x05\xc4\xaf\x89\xd8\x02\xee\x3a\xe3\xef\x92\x80\xc5\xaa\xc2\xe8\x95\xc7\x3c\xf9\xd5\x9b\xaf\x79\x96\xb9\xd8\x47\x5f\xce\x5e\xa1\xdd\x24\x53\x2f\x61\xea\x62\x77\x6b\xcd\xed\xd1\xab\x2e\xb6\xa7\x08\xa9\xfa\x58\x45\xc1\x05\x4f\x5d\x40\xd4\x99\xbf\x91\x49\xc8\x6e\x7c\x34\x63\x99\x33\x63\xbd\x80\xc5\x5c\x84\x2c\xed\x05\x0b\x1e\x5c\xa0\x9c\x4c\xd7\x52\x42\xb9\x6c\x91\x5c\xbd\x52\xc8\x40\xe1\x5e\xf5\xe3\x0c\x2a\xee\xf5\x73\x92\x45\x21\x7f\x79\x73\x1a\x85\x90\xa7\x84\x53\x26\x7d\xf4\xeb\xaf\xbf\xfe\xda\x7b\xff\xbe\xf7\xfa\xb5\xf3\xe6\x8d\xbf\x5c\xfa\x59\x86\x48\xac\x26\xab\xce\xab\x40\x44\x0d\xe6\xbf\x89\xe0\x7e\x0d\x42\x2e\x26\xa1\xc6\x49\xaf\x99\x34\x79\xe5\x46\xcc\x6b\x53\x4a\x84\x8b\x02\x00\x78\x63\x76\x48\x91\xdd\x8d\x4e\x35\xa7\xbb\x6d\x41\x21\xbf\xdc\xd4\x38\xaf\x30\x1f\xbf\x44\x71\xfc\x45\x2c\xb7\x20\xde\x84\x23\x0a\xb9\x62\xca\x6e\xd0\xc3\x19\x17\xc2\xa8\x84\xd9\x80\x66\xa5\xba\x05\x86\x1c\xd2\xf7\x28\x65\x66\xd8\x3b\xfa\x64\x92\x23\xc2\x46\xea\x54\x32\xec\xc3\x4e\x23\xbc\xd6\xd4\x1e\xa5\xe2\xce\x36\x92\x15\x88\x13\x88\x6c\x1e\xb4\x10\xaa\x8f\xbc\xc2\x4f\xed\xe4\x86\x9a\xec\x8b\x6a\xcf\x30\x2e\x44\x6b\x3f\xb2\xe5\x5f\x66\x61\x00\xff\xcb\x48\xaa\xbd\xf4\xda\x1c\x79\x47\xf5\x54\xc1\xf6\x4d\x74\xd0\xd6\x4e\x95\x65\x99\x93\x59\x74\xcd\xc3\x5f\xa2\x50\x2e\x80\xc5\xd9\xc9\xc0\x6c\xaa\x3c\x44\x65\x77\x55\x92\x1b\xcc\x42\xf5\x74\x92\x44\x68\x26\xa6\xc0\x05\xed\x0b\xa4\x0e\x19\xc2\x24\x11\x2f\xe3\x75\x7a\x5f\xe1\x45\x14\x72\x28\x6c\xb9\x0e\x4e\x9f\x8f\x2d\x99\x26\x86\x9e\x4f\x14\x0a\x8e\xd7\x21\xcf\x5c\x10\xb0\xf1\x9d\x1b\x44\x37\x69\x4f\x5c\x79\x06\x3b\x9d\xbf\x95\x74\x03\x36\xed\xc1\x2e\x01\xea\x6d\x56\xf5\x95\x4a\x6e\x5b\xd2\x02\xfb\xde\xb7\x9e\xcb\x07\xad\xe7\xb7\x8e\xdc\x0c\xef\xad\xd8\xbd\xe9\xaa\x74\xee\xbe\x41\x2e\xb6\x07\x69\x58\x8d\x7f\xd3\xff\x31\x7c\xc0\xbf\xfe\x2c\x1f\x00\xd4\x77\x27\x0f\x90\x72\xd0\x2d\x46\x89\xd8\x5d\x44\x35\x70\x2a\xf9\x2a\xa3\xe3\x01\x19\xf4\xc9\xe3\x3e\x39\xec\xf7\xc9\xd3\x7e\x9f\x0c\x9e\xf4\xfb\xe4\xf0\x71\xbf\x4f\x7e\x38\xe8\xf7\xc9\xc1\x40\x7d\x1e\x1d\xaa\xef\x27\x8f\x8f\x54\x81\x1f\x0e\x54\x91\xc7\xfd\x23\xf5\x67\x70\xd0\x7f\xaa\x4a\x1c\x1c\x0d\x9e\xaa\x32\x47\x4f\x0e\x9f\xa8\x52\x87\x83\xe3\xc3\xc7\xfc\x90\x3c\x3e\xec\xff\x70\xc0\x0f\x27\xba\x63\x8b\xa7\x81\x26\x6b\x7d\x57\x55\xcd\x72\xaa\x30\xeb\x50\xa1\x24\xd0\xad\xe8\x7d\xd1\xa8\xe0\x36\xd9\x10\xec\xb7\x10\x02\x4d\xf4\x0b\xa5\x55\xb3\x11\xe8\xb5\x06\xcb\xba\x4a\x8d\x9e\x55\xf8\x02\xbb\xee\x25\x37\x04\xf6\x17\x4e\xa4\x55\x86\xff\x0a\xca\xf0\x3a\x64\xf1\x50\xa6\x37\x60\x83\x91\x5e\xe6\xe2\xe1\x9e\xcb\xa9\xf4\x84\x8b\xb1\x17\x26\x82\x0f\x71\x45\xb9\xa4\x25\xde\x68\xb6\x35\xb7\x67\x12\x1b\x84\xbc\x03\x16\x98\x80\x2e\xea\x2e\x08\xe4\xda\xaa\xc1\xf0\x46\x7a\xdc\x65\x38\x9f\x45\x82\xc5\xf1\xcd\x46\x7a\x33\xc5\xbf\xd7\x19\xac\x6f\x9b\xa4\x51\xd9\x60\x4f\x89\x1f\x69\xc6\x5d\xfc\xb7\x4c\xfb\xf9\xff\xc1\xb4\x77\x90\x75\xae\x47\xb0\x47\x69\x73\x50\x56\x9c\xb8\x77\x3f\x12\x5e\x39\x83\x8d\x86\x8a\xf4\x4e\xc7\xdd\x3e\xad\x8d\x4d\xa8\x0e\xc2\xae\xfa\xa3\xd6\x54\x4f\x26\xa7\xa0\x26\x53\x7c\x26\x7a\x08\x59\xff\x09\x90\x96\x50\xb2\x70\xc3\x58\x01\xe6\xe7\x5e\x90\x08\x99\x26\x71\xa6\x70\xe1\xe9\x7a\xba\x8c\xa4\x22\x41\xdb\xfa\xda\x36\x84\xd8\x64\x19\x00\x3c\xff\x37\x3c\x03\x74\xb5\x83\x69\x80\xb5\xbb\x0f\x81\x47\x0f\xe7\x1a\x0c\x3b\x05\x8a\x21\xff\x8c\xb7\x6c\x88\x3a\xd3\x60\x51\xce\x16\x0b\xb0\x8d\x1d\xdd\x3b\x70\x94\x22\xe1\x7f\x3f\xdd\x6b\x03\x5c\x0d\x01\xde\x07\xb8\xdf\x5b\x28\x5f\x4b\x95\x7f\x6b\xfe\xb4\x8a\xbb\xb9\x08\x15\x69\x25\x55\x76\xd7\xdf\x21\x54\x11\x18\xa7\xdf\x04\x75\x43\x0b\x24\xc2\x92\x8e\x17\xf2\x41\x1b\xb9\x38\xd1\x5d\xb7\x42\x74\x8b\x33\x44\x9f\x79\xe6\x39\x6e\x86\x51\xf5\xb8\x94\x87\xd0\xee\xf0\xda\xbe\xf8\xab\x67\xb9\xb9\x87\xaa\x68\xa3\xba\x91\x0a\xb9\x78\xc5\xd2\x8c\xbf\x15\xf2\x5e\x34\xd3\x2a\x19\x7f\x2e\xca\xbb\xfc\xf6\xd6\x88\xbc\xd3\xec\xb4\x38\xb4\x6d\x90\xfa\x4f\xe3\xbc\x67\x92\x05\x17\x3c\x7c\xd0\x89\xaf\x6e\xc6\xd3\x45\x72\xe5\xac\x85\xa9\xee\x28\xdc\xe4\x00\x36\x2a\xf7\x65\x43\xde\xb6\xc3\x3e\x55\x55\x14\xc8\xc0\xec\x1f\xc8\xe8\x92\xfb\x7b\x95\x72\xa6\xc9\xfb\xf6\x30\xdf\xda\xc3\x0f\x19\xb1\x1d\xef\xb7\x0e\xb5\x5f\x0c\xf5\xdb\x47\x1a\xee\xe4\x33\xff\x4b\xff\x45\x38\xa7\xcc\x3d\x7e\xaa\x7d\x77\x24\xa7\xee\x26\x66\x53\x1e\x67\x3e\xb7\xe2\xbc\xcc\x31\x7d\x6e\x18\x2e\xde\xa2\x25\xde\xb6\xb0\xa3\x2c\x60\x31\x4b\x11\xf6\xe5\xc8\xad\xec\x38\x49\xc7\x93\xa1\x76\x30\xd8\xeb\x0f\x15\x03\xa0\xd3\x85\x13\x09\x87\x63\x74\x7e\x2e\xd8\x92\x9f\x9f\x23\x2d\xc1\xba\x52\x3b\x35\xb5\x19\xec\x57\x4c\x20\x62\x4d\x2a\x7b\xac\xd3\x41\xc4\x41\xad\xa6\x7d\x5d\xb2\xb2\xe5\x62\x3e\xe7\x22\xec\xc1\x34\x7b\xaa\x43\x6d\x5b\x42\xf4\xcf\xd4\x87\xe3\x81\x72\xf2\x08\x3d\x22\x7c\x2c\x26\xea\x43\x61\x33\xd6\xe9\xb8\x8c\xee\x0d\xf0\x5d\x46\xa2\xbb\x4c\x01\xbb\x3b\x5e\x72\x99\x46\x81\x1d\x39\xf7\x2c\xd4\x6e\x6f\x11\x6a\xdb\x84\xf7\x4d\x61\x9a\xb2\x40\xb5\x84\x36\x60\x15\xfd\x0b\x0d\xe4\x08\xe3\x1c\xbb\x6d\x06\x82\xed\x4d\x72\xa1\x78\x29\xab\xef\x64\xbc\x22\xe8\x7c\x5a\xa7\xfc\x9b\x84\x1d\x63\x71\xca\xc0\x0a\x63\xac\xa9\x3c\xf3\xc7\x93\x9a\x3d\xfa\x94\xa7\x11\xcf\xb4\xa9\xc6\x7a\xbb\x58\x17\xb2\x8a\xc9\xa7\xd1\x0a\xec\x57\x41\xc7\x7c\x02\x5c\xa8\x17\xc8\x34\x06\xa3\xb4\xf4\x96\x5c\xb2\x7f\x83\x52\x7f\xdb\x40\x15\x2c\x58\x2a\x5f\x33\xc9\x86\x82\xb2\x8a\xec\x8d\x47\x85\x4d\x5a\xd2\xe7\x60\xc0\xc2\x7e\x9f\xd2\xd2\x94\x2b\x2b\xa6\x5b\x46\x84\x3a\x7b\x70\xf0\xa4\xaf\x8d\xb1\x62\xa2\x8d\x7e\x9e\xe7\x31\xc2\x27\x39\x8f\x33\xee\x0c\x2a\x2d\x74\x3a\xb5\x0e\x3b\x1d\x57\xd0\xf1\x04\x37\x7d\x0c\x9a\xd0\x12\x75\x71\x3f\x11\x1a\x5e\x67\xc9\x7c\x1e\x73\x57\x10\x8e\x77\xf1\xc3\x55\x94\xb4\x48\xd6\x71\xf8\x99\x67\x5c\x76\x3a\xbc\xfa\xb3\x4e\xd8\x6a\xe5\xee\x19\xd8\x78\x92\xdf\x6f\xcc\x2b\xe0\x0d\x96\xbc\x44\xbc\x83\x0d\xfa\x3e\x59\x67\xfc\xe3\x5a\x5b\xdf\x13\xf1\x26\xb9\xe4\x29\x49\xef\x58\x6d\xf0\x67\xd2\x60\x7c\x3e\xe8\x74\xd4\xc2\xa4\xe6\xf7\x7d\xe7\x78\xb3\xc5\x17\xeb\x43\xa2\xb0\xbc\x1d\x87\x9f\x8c\x98\xaf\x3d\x03\x72\x22\x8d\xfd\x5a\x5b\xa2\xb9\xb1\x5d\x30\x62\xf0\x6f\xa4\xd0\xee\xce\xce\x8c\x81\x2c\x59\xb1\x20\x92\x37\x7e\x75\xa0\xb7\xb7\x69\x6d\xc3\x0d\x7c\xef\x38\x2f\xb9\xb5\x62\x7a\xa3\x1d\x67\xc3\xe5\xd8\x8c\xb1\x18\xf9\x25\x4f\xfd\x64\x24\x2a\x39\x0a\xf3\x72\xb2\x8d\x11\x22\xc9\xdb\x89\xf7\x6e\x24\x92\x81\xe9\x03\xed\x32\xc1\xb3\xbc\x95\x91\x90\x9c\x58\x4a\x15\x59\x4a\x65\x78\xf0\xea\x0a\x3e\x64\xb5\x56\x71\x6f\xe0\x2c\x65\x6f\xe0\x48\x7e\x2d\x7b\xcb\xb5\xe4\x61\x31\x9c\x59\x22\x24\xb0\x34\x83\xc3\x3c\x27\x48\x03\xd1\xd1\xdb\xc6\xc9\x00\x6c\x8a\xf2\x08\x76\x19\xcd\x99\x4c\x52\x6f\x15\x33\xa9\xc6\x53\xae\x01\x7a\xcf\x02\x84\x47\xe8\xd5\xfb\xd7\xc8\x47\xaf\xce\x3e\xbf\x43\x04\x39\x5d\x27\xd0\x6d\x49\x38\x61\xce\x72\x1d\xcb\x68\x15\x73\xd3\xa8\x42\xa5\xb9\x21\x8f\xda\x5d\x27\x9a\xb9\x96\x0a\x1b\xd1\x17\xa9\xdf\x68\x68\xd1\xcf\x7b\x26\x17\x1e\x9b\xaa\x45\x07\x5c\xf5\x9c\x0e\xf8\xc1\x91\x29\xeb\xf2\x7d\xf8\xe5\xc9\xe4\x47\xc5\x0e\xb8\x07\xb8\x8b\x7e\x45\x65\xc1\x41\xad\xe0\xa0\x5e\xf0\xbf\x65\xc1\xc1\x93\x6a\xc1\xc1\x93\x7a\xc1\x93\x4a\xc1\xe3\x5a\xc1\xe3\x7a\xc1\x4f\x95\x82\x07\xb5\x82\x07\xf5\x82\x67\x65\xc1\xa7\xd5\x72\x4f\xeb\xc5\x7e\x2a\x8b\x3d\xae\x16\x7b\x5c\x2f\xf6\xbe\x2c\x76\x58\x2d\x76\x58\x2f\x76\x51\x14\xb3\x5a\x06\x5e\xc9\x57\x79\xe0\xda\xb3\x2b\x53\x3e\x1b\xf0\xde\x41\xad\x83\x5e\x13\xf6\x37\xa8\x2c\xd9\xaf\x97\x6c\x00\xff\x6b\x59\x72\xf0\x43\xad\x64\x13\xfa\xac\x52\xf2\xa8\x5e\xb2\x01\xfe\x59\xa5\xe4\xa0\x5e\xb2\x01\xff\x55\x59\xb2\xb6\xf2\xbd\xc6\x02\x88\xb2\x5c\x6d\xe1\x7b\x8d\x15\xf8\xed\x7a\x7a\x6c\x8a\x7a\xfd\x4a\xd7\x5e\xbf\xdf\x98\xf7\xd2\x14\xdb\xb1\x08\xda\x17\x58\xfb\x01\xa3\x40\xd1\x13\xf1\x48\x3a\x1a\x15\x38\xcc\xd1\xde\x1c\xa0\xff\x71\xa2\xcc\x61\xce\x74\x3d\x47\x38\x27\x29\xa7\xc6\xfb\xbd\xa0\xff\x82\xa6\x0a\x4d\x28\x74\xe3\x81\x4c\xe4\x72\x4c\x12\x2a\xbc\x94\xc4\x54\x78\x73\x12\x51\xe1\x4d\xd5\x60\xf6\x98\x3d\x7a\xe9\x7c\xca\x5c\xe4\x05\x89\x08\x98\x74\x13\xa2\xf8\x4f\x6c\x7f\xc6\xf5\x9f\x51\xfd\xa7\x24\x08\x23\x5c\x38\x71\x1d\x1c\x1f\x7f\xef\x0e\x7a\xd2\x72\x8a\xaa\xe9\xb2\x65\x38\xd4\x80\x0e\xdd\xac\x2b\xbf\x4f\x30\x41\xa4\x6c\xaa\x91\x1b\xdf\x99\x1b\x61\xe8\x38\x27\x09\xb7\x2e\x72\xae\xe6\x30\x6a\xbe\xdb\x39\x29\x7c\x6b\x53\xee\x1a\xb8\x10\xa1\x58\x95\x91\x77\xe8\x0f\x88\x04\xb5\x82\x12\x15\xfe\x58\xf3\xf4\xe6\x13\x4b\xd9\x52\xc9\x0b\x21\x93\x4c\x4b\x0b\x05\x5f\xe5\x56\x55\xb7\x63\xf4\x1d\x0f\x83\x83\xa3\x3e\x22\xe8\x3b\x36\x0b\x9f\xcc\x9e\xa8\xaf\x60\x7a\x34\x3d\x9a\xaa\xaf\xa3\x90\xfd\x70\x14\xaa\xaf\xa7\x47\x47\x7d\x1e\xa2\x09\xd8\xcb\x0c\xfd\xd5\x8c\x58\x7f\x58\xec\x85\x94\x67\xeb\xd8\x50\x51\x4e\x12\x35\x9d\xe4\x9f\x8c\x52\xda\xef\x74\x12\x60\x7b\xc4\x73\xda\x1f\x89\x67\xde\xf1\xa8\x27\x7a\xde\x81\xdf\xf7\x7b\x02\x93\xe6\x62\xcb\x71\xf2\x4f\x36\xb9\xbd\x45\xdf\x3d\x7e\xfc\x18\x61\x4f\x49\x2f\xdc\x55\xcb\x80\xc8\xa0\x2b\x30\x30\xb5\x12\x2b\x26\x02\x76\x05\xdc\x29\x00\x0d\x83\xda\x1d\x56\x25\xa1\xf6\x48\x29\x42\xdb\x51\xca\xda\x28\xb5\x13\x84\x82\x95\x66\xe2\x7d\x99\x03\xfc\x0d\x88\x52\x2b\x1f\x65\x54\x8b\x47\x5a\x56\x4a\x86\xec\x19\x8d\x87\xac\x4b\xa3\x8a\x6a\x74\x9c\x4d\x86\xdc\x52\xba\xac\xd3\x91\xe3\xfe\xe4\x19\xeb\x46\xfb\x83\x7e\x7f\xe4\xa6\xe6\x3e\x08\x18\xe5\xc7\xfd\x09\x89\xd4\x3c\x07\x13\x3c\xc1\x24\xeb\x76\xb1\x5f\x2d\xa0\x7d\x82\x26\x8a\xcb\x52\x83\xb6\x74\xd5\xea\x23\x46\xd2\xdf\xe4\x96\x3d\x19\x8b\x49\x45\xeb\xa0\xd7\x3c\x35\xde\x74\x22\xcf\x71\x4e\x22\x5e\x53\xd8\x03\x8c\x7f\x8c\x13\xa6\x18\x0b\x0b\x96\x28\xfb\xc0\x3e\xb8\x12\x8f\x54\x1f\xbe\xcc\x87\xcc\x7d\xaa\x64\x5c\xf7\xe9\x00\xfe\x3d\x80\x7f\x0f\xe1\xdf\x23\x2b\x24\x64\x7f\x49\x48\x00\x0e\x71\xb7\x57\x04\x64\x1b\xaf\x4d\x6b\x01\x99\xbd\x7d\x4d\xfb\xd6\xc7\x55\xf3\x89\x9a\x51\x32\xdc\x22\x1d\x4f\x6a\x02\x48\xc1\x84\xfa\x71\x55\xc5\x67\x8d\x04\xab\x38\x91\xea\x44\x54\xd8\xcf\xa2\x86\x55\xa6\x4b\x62\x9c\x81\xed\x70\xad\x22\xc6\x2a\x83\x8d\xcd\xf9\x53\x9c\xc8\xc6\xd8\xd5\xb6\x56\x5d\xb8\x85\x63\x40\xb3\x0d\x4c\x38\x71\x6b\x62\x8a\x51\x21\x90\xcd\x3c\x8d\x42\x7f\xb3\x50\x0c\x32\x9b\xc6\x46\xcf\x1b\x05\x17\xf6\x07\x5b\xcb\xe4\x8d\x75\x58\x55\x09\x4b\xc5\x18\xbe\x00\x9d\xc4\x67\x16\x46\xeb\xcc\x1f\xf4\xfb\x39\xd1\x3c\x9d\xf6\x19\xf0\xf7\x06\x39\xb9\x66\xd7\x51\xe6\x6f\x96\x49\x68\x0c\xc2\x48\xbb\x10\x44\xc1\x45\x66\xfd\x09\xde\x47\x22\x49\x8b\x14\x55\xe8\x25\xcb\xb8\x8f\x96\x51\x1c\x47\x19\x0f\x12\x11\x66\xda\x69\xe0\x6b\x22\xb8\xef\x32\xba\x43\xe5\x87\x47\x68\x9a\x26\x57\x19\x4f\x51\xc1\x66\xdf\xe8\x01\xc8\x28\xb8\xf8\x11\x68\x83\xe4\xa9\x2f\x78\x4e\x82\x34\xc9\xb2\x05\x8b\x52\x3b\xba\xeb\x9b\xc2\x81\xe8\xbb\xe9\x74\x8a\x72\x22\x93\x44\x31\x65\x76\x3a\x7d\x12\x64\xd9\x2b\xb5\x17\x2d\x8b\x6f\x0a\xa8\x7a\x42\x72\x21\x7d\x20\x2d\x82\x6c\x34\x13\xe7\xa7\x35\x4f\xd4\xd4\xd3\x27\x8b\xc4\x34\xd5\x18\xc8\x78\xf4\xbe\x52\x2b\x56\x5e\x78\xb8\xbd\x75\x23\x1a\x79\x6b\x19\xb8\x18\x93\x47\xbf\x09\xa7\xf2\x7f\xcf\xc2\xe8\xd2\x81\x03\x41\xb5\x33\xc0\xf3\x47\x05\x9d\xf1\x34\xf5\x73\xdb\x3c\x30\x9c\xff\x22\x4c\x1e\x3d\xdb\x0f\xa3\xcb\xe7\xdb\x2d\x36\x92\x1c\xe7\x99\xe2\xd7\x8b\x7e\xb8\x64\x51\x6c\x39\x75\x07\x58\x63\x8a\x4a\x4e\xbd\xa7\xc1\xe6\x3c\xaa\x50\xc0\x47\xc8\xd9\x6f\x6f\xf5\x79\x59\x2c\xa9\x6a\x2f\xb4\x2e\x85\x20\xdf\x29\x7c\xb2\x8b\x82\x42\x0d\xdd\xa4\x3e\xdb\x87\x56\xee\x9d\x44\x15\x52\x1a\xf0\xc0\xe5\xa3\xad\x51\x95\xe3\x31\xfe\x89\x17\xfc\x06\x9c\xa8\x15\xd2\xe6\xf4\x79\x4d\x31\xc5\x47\x8f\xaa\x0d\x2f\xa7\xaa\x45\x3b\xe0\x62\x29\x38\x29\x1d\xc9\xfd\x0a\xed\xbf\xe4\x6e\x32\xe6\x13\xac\xb2\xd5\x88\x11\x18\x61\xbc\xdf\x93\x48\xb8\x08\x61\x82\x1a\x53\xd8\x5a\x2e\x45\xbf\x8d\xd6\xf8\x6c\xc1\x97\xdc\xdf\x1b\x10\xf0\x52\xd4\xfe\x38\x7a\xdb\x6d\xe0\x5c\xfb\xd2\xe4\x6c\xd4\x1f\xad\xff\x93\xa3\x81\x7f\x40\x32\xc9\x57\x99\xaa\x39\x8b\x00\xfd\x92\x6c\xc1\xc2\xe4\x0a\xe4\x9c\x7e\xae\x84\xa8\xc2\xe4\x57\x60\x1b\x6d\xf0\x3b\x31\x88\x4d\xe3\x9c\xc2\x8b\x00\x7e\xd9\xd2\x2e\xde\xad\x77\x69\xde\xdd\x6b\xc3\x85\xc3\x02\x5b\xba\x03\x6a\xd4\x06\xad\xf8\xb7\x50\x78\xdc\x51\xa4\x90\xc2\x24\x1e\x31\x58\xd0\x84\xbb\x92\x6c\xe3\x40\x8c\xfd\x42\x35\xe3\x6a\xf6\x90\x97\xb5\x19\x08\x96\xbb\x29\x01\x6f\x99\x32\xa8\x1b\x14\x2d\x2c\x7d\xc5\x80\xa6\x74\x3a\x01\x13\x01\x8f\x5f\x88\x68\xc9\x14\xb3\xf0\x63\xca\x96\xdc\x2d\x0b\xe0\x2a\x01\x4a\xf9\x1f\x6b\x9e\xc9\x46\xe1\x8a\xfb\x59\x9c\xc8\x53\x2e\x5f\x88\xf0\x75\xca\xae\xdc\x36\x80\xda\x69\xf3\xd6\x69\xe3\xc6\x1d\x93\xba\xea\xc4\x78\xd2\x3d\x68\xc0\x8d\xa1\xd4\x9b\xfd\xcc\xb3\xe8\x2b\xbf\x6b\x17\xc1\x8a\x57\xf7\xd3\x9c\xc3\xf0\x5d\xbc\x53\xf5\xb4\xc3\xc3\x4a\x71\x25\xe0\x61\x65\xe9\x5b\xba\xed\x6d\xa5\xca\xec\x51\xca\x46\xee\x43\x08\x7c\xa1\x9d\x7a\x00\x8d\xc7\xd8\xe7\xb6\xe7\x8a\x2f\xd6\x43\xda\x00\xe8\xf4\x1f\xb2\xe9\x47\x25\xc8\xac\x77\x43\x01\xbe\xe6\xf2\xdb\x5d\xad\xcf\xde\xc3\x0e\x8b\xda\x16\xdb\x7e\x65\x69\x75\xa9\xf0\x6e\x0f\xc5\x66\x7e\x8b\x4b\x5d\x8d\x91\xc9\x1b\x5b\x67\x07\x93\xb4\xbd\x71\x6a\xfb\x25\x33\xfb\x85\xd7\x18\x23\x2f\x84\xcd\xb8\x4b\x87\xd8\x44\x3e\xdf\xaa\xe6\x6b\xd5\x76\x71\xee\x31\xb2\xd1\x1b\xdf\x1a\x5e\x48\x22\xf4\x19\xf0\xb7\x4e\x05\xc9\x2e\xa2\xd5\x47\x01\x20\x04\x2d\x56\x9b\x02\x6d\x87\x96\x11\x46\x8e\x48\x6a\xcd\x7e\x96\xe9\x6b\x6d\x84\x71\xb2\xa9\xe8\x5e\xfd\x07\x6d\x35\x52\xee\x57\x4e\x8c\x16\xd5\x6f\xc7\x76\xa4\xa9\x79\xf5\x77\x22\x16\x52\xd7\x30\x6f\x37\xa8\x29\x46\x6e\x8d\x55\x01\xa7\x19\x37\x42\xf3\x5a\x09\x9f\xa1\x1e\x90\x39\x68\xbe\xac\x1b\x85\x19\x89\x59\x26\xff\x53\x11\x50\x85\xe2\xc5\x4e\x14\xda\x18\xa9\x69\x17\xf2\xe3\xce\x2b\x33\xd5\x4b\xa6\x9a\x0b\x65\xe9\x0d\xca\x09\x3a\x59\xae\xe4\x8d\x03\xc2\xaf\xa3\x1b\x51\x64\x7c\xc9\x64\x1a\x5d\xeb\x2b\x6c\x3a\xf5\xec\x66\xd5\x66\x30\x6b\xbd\xbc\x8a\xfe\x53\x69\xce\x89\x32\x27\x99\x39\x57\x8a\x7d\x70\xe4\xcd\x8a\x3b\x8f\x10\xa9\xb6\x4a\xd0\x23\xe2\xe8\x85\x74\xa6\xdc\x79\xa4\xfb\x7e\xe4\xb8\x60\xe2\x76\x2e\xb9\x92\x84\xb0\x87\xda\x4c\x31\x01\x27\xf7\xc2\xee\x8f\x3a\xdc\x5a\x5a\xa9\x4e\x02\x84\x02\x35\x87\x0f\x89\xa3\x5a\x06\xd0\x44\x3c\x74\x6e\xb8\x44\x98\x2c\x40\x20\x2c\x64\xd5\x01\x3f\x1a\xf1\xf2\x22\x17\x3f\xc2\x3e\x07\xeb\xe3\xb2\x5c\x55\x60\x9b\xb7\x15\x9e\x2d\xa7\xf2\xe1\xe3\x18\x56\xda\x33\xa0\xbc\xbd\x6d\xd9\x09\x0f\xeb\xeb\xde\x0d\x01\xac\xbd\x54\x14\x84\xd1\xbd\xc1\xd0\x6a\x9a\x1a\x9d\x3d\xa3\x03\x7e\x38\x34\x77\x44\xaa\x2b\x6c\xae\x8a\xe8\x95\x44\xbe\xa4\x0b\x5e\xe4\x63\xab\xf3\x90\xed\x26\x02\x99\x1a\xdb\xa8\x6c\xd5\xc4\xcb\x70\xa7\xd5\xb1\xa2\x55\xe7\x9e\xd6\x51\x58\xe5\xba\x68\x37\x71\x97\xad\x19\x67\xad\xf1\x60\x02\x06\xd0\x42\x71\xb3\xb7\x05\xe1\xea\x75\x12\x73\x6a\xee\x98\x60\xc1\x2b\x9a\x0e\x32\xcb\x96\xab\xae\xba\xc8\xf9\xff\xa1\x2e\x1f\xf7\x27\x96\x89\xfe\x4d\xa0\xbb\x6c\xae\x00\x1b\xa3\xdb\x87\x8b\x7c\xa7\x2b\x16\x68\xf7\x21\x94\x93\xff\x73\xa0\x31\xa0\xb3\x0f\x05\x96\xb1\xab\xfb\xbb\x0d\xe3\xc5\xd2\xa3\x7e\xbb\x19\xa6\xe8\xb9\x30\xd2\xdf\xb3\xa8\x7a\x30\x7a\x55\x6b\x63\x01\x15\xd0\xdf\x35\x16\xdd\xd8\x9f\x18\x8b\x91\x85\xfc\x07\x1d\xda\x12\xdb\x7e\x11\xd9\x7a\xb5\x4a\x52\xc9\x43\x8b\x73\x61\x73\x01\xb6\x45\x56\x13\xd6\xd2\xdc\xb6\x21\x9b\xb5\x59\x99\x5a\x7b\xbd\x37\xf2\xc0\x2f\x2c\x15\x91\x98\xeb\xd8\x03\x3f\x72\x19\x2c\x78\xe8\x94\x98\xdf\xd2\x63\xe4\xe8\x5d\x96\x11\x27\x11\xf1\x8d\x63\xe2\x11\x44\x62\xee\xcc\xa2\x34\x93\x0e\x22\x65\x59\x0f\x61\xb2\x27\xee\x1b\x63\x15\x9d\xdd\x3b\xcc\x0f\x89\x8c\xd4\x99\x51\xa3\x3c\x5d\x24\x57\xaa\xe3\x65\x92\x72\x47\x2e\x98\x70\x10\x19\xf0\x43\x82\x0a\xe3\x98\x02\xa4\x2a\x91\xcc\x66\x0e\x1c\x13\xa3\xa3\x97\x30\xde\x24\x75\x56\x3c\x85\x14\x11\x70\x27\xe5\x2c\x4b\x44\xe6\xb5\x6e\x85\x53\x60\xaa\x80\xfd\xd8\xeb\x97\xbe\x42\x55\x33\xa4\x42\xfb\x3d\xc9\xa6\x31\xdf\xb1\xe5\xa6\x49\x78\x63\xe6\x01\x4c\xee\x90\xb9\x4f\x8f\xb5\xf7\xcb\x8a\x37\x2e\x74\xc7\x09\xd3\xba\x5d\x46\xab\xfe\x9a\xa4\xc4\xe2\x9a\x53\xf9\x16\x9e\x11\x88\x44\x4f\x31\x9d\xd9\x43\xed\xa4\xb3\x38\x61\xb2\x97\x5a\xe2\xf6\x2e\x61\xda\x67\xcd\x57\xeb\x4c\xd0\x32\x73\x7e\x5b\x1f\xf4\xfb\x07\x4e\xe9\x91\x05\x41\x29\x08\xaa\xe6\xa8\x2d\x6e\xd4\x03\x0e\x22\x42\x4d\x5d\x51\xa8\x90\x0f\xf7\xca\xa8\x40\x78\xc3\xbd\x9f\x20\xd4\x90\x61\x6e\x09\xf7\xce\x14\x34\x29\x32\x40\x75\x43\x7e\x7b\xeb\x86\x9c\x6e\x72\x6c\x6d\x18\x73\x4e\x37\x70\x27\x33\x34\xa5\x09\xbf\x5e\xa5\x3e\x42\xc6\x05\x0f\x5c\xc5\x8d\x9e\x1c\xb4\xca\xa4\x04\xa6\xfe\x6d\x19\x91\xbd\x41\x6e\x94\xbd\x33\xfe\xed\x11\x1d\xd8\x34\x49\xe5\x5b\xf1\x23\xf0\x01\x70\x7c\x2a\xf7\xdc\xaa\xd7\x7d\x5b\xae\x87\x69\x31\xa0\xb8\xc5\xa8\xaf\xf1\x4b\xfa\x5a\xa5\x8a\xe4\xca\xc5\x0d\x27\xe4\x44\x9c\x54\x1a\x2c\x86\x60\x32\xf5\x05\x1b\x68\x4e\x61\xf4\x52\x02\xfc\xa8\x73\xdc\x0d\x40\x88\xe7\x98\x20\x54\x61\x70\x86\x3b\xe6\x61\x05\x9d\xed\x1c\xf7\xee\xb9\xdb\x25\x62\x54\xf0\x2b\xe7\x85\x2a\xf4\x4a\xbb\xeb\xc6\x3c\xdd\xd5\x1b\x80\x87\xe9\x0c\x77\x2b\x04\x84\xb9\x2f\x0c\x72\x4a\xc1\xd6\x40\x99\x39\x97\xc6\x4b\xb2\x7a\x61\x70\x5f\xa1\x83\x94\x8a\x5e\x0b\x80\xb4\x47\x66\x2d\xf0\x41\x91\x55\x6c\x91\xdb\x5b\x30\x64\x2d\xd9\xb5\xb6\x68\xcd\xe2\x24\x49\xdd\x5d\xad\xed\x1f\x1c\xf7\x31\x19\x60\x12\xc3\x94\xbf\x7c\x7e\xa7\xe3\x1c\x68\x6e\xd6\xd8\xac\x7c\x4e\x42\x1e\xae\x57\x0d\xdf\xd1\xd7\x2a\x2d\x8e\x02\xd6\x70\xae\x24\x2b\x96\xca\x88\xc5\xe7\x45\xc4\x9d\x87\xd5\xcb\x35\x17\x18\x59\x06\xaf\x65\xcc\xb2\xe4\xf5\xf4\x89\xf3\x23\x8a\xf6\xd9\x2a\xda\xbf\x1c\xec\xc3\x58\xcf\x8d\xbf\x6d\xec\x69\x47\x5d\x57\x07\xb5\x42\x24\xad\xf4\x84\x2b\xd9\xe0\x74\x22\x76\x64\x66\x92\xaf\x10\x49\xaa\xb9\x55\xaa\xae\x4f\xf9\xd6\x18\xaa\xbd\x6b\x25\xbe\x68\x69\xc1\xd2\xe2\x66\x94\xa6\x47\x6f\xc5\x25\x8b\xa3\xd0\x59\x31\xc1\x63\x2d\xd0\xa0\x47\xdd\x1d\xd0\xe8\x3e\x42\x8f\x70\xae\xc3\x4a\xa1\xc2\x0e\x5a\x29\xbc\x62\x72\xf1\x29\xe5\xb3\xe8\xba\x6a\x61\x1d\x55\xcc\xaf\x98\x7c\x43\x04\x2a\x92\x45\x73\xc1\x62\x9f\x79\xfa\x23\xc7\x9e\x5c\x70\x01\x1c\xa6\x89\x1c\x55\xa6\x28\xa1\x04\x65\xeb\x20\xe0\x59\xa6\x45\x3d\x1d\x80\x0a\x37\xe7\xcc\x75\x04\xa5\xdb\x5b\x14\x99\xc9\xdb\xbd\xe3\xfc\xeb\xf4\xe3\x07\x23\x1f\x30\xda\x57\x78\x45\x6b\xa3\xaa\xf7\x1e\x0a\x0d\x56\x45\xe6\x4b\x8b\x9f\x43\xcb\xbc\x51\x4a\xc5\x88\xd1\x81\x9f\x76\x3a\xd6\xff\xe7\x79\x1f\x7c\x0f\xed\x4f\x9c\x37\xce\xaf\x0e\x15\x05\x88\x51\x0b\x5b\xba\xb3\xa6\xb8\xbc\x29\xcc\x9c\x7e\x5a\x22\xef\x2a\xe6\x4e\x72\x02\x74\xcc\xdf\x58\x42\xe9\x97\xe8\xb2\x27\x6b\x45\x49\x95\x5e\xfa\x2c\x27\x05\x16\x19\xe4\x77\x63\xb0\x1c\x9b\x98\x5b\x0a\xfa\x08\x30\x18\x40\x58\x43\x5f\xb0\x25\xdf\xd2\xaf\xe9\x19\xea\x38\x4e\x8e\xc6\xfb\x8a\xd7\xd0\x27\xdf\x41\x5d\x6e\xc3\x35\xd5\x46\xd1\x50\x83\x36\xa3\xe1\x94\xf7\x81\x2a\x1d\xd5\xc8\x85\x42\xe7\xb5\x26\x2a\xae\xfa\xb5\xda\x05\x11\xd0\xe4\xb1\xac\x56\x22\x50\x40\xc1\xf6\x96\x53\x0b\x61\xd1\xa5\xe0\x16\x68\xfd\x72\x53\xbd\xc0\xf6\x68\x6c\xfb\xad\xe3\xb1\xcb\xbc\x63\x22\xc5\x7a\xee\x98\x4d\xb9\xde\xed\x0d\xa8\x5d\xdc\x06\x46\xd8\x86\x7a\xad\xc9\x56\xab\xc0\x58\xb4\xb7\x67\xfd\xa3\xdb\x87\x63\x79\x8a\xb2\xae\x31\xd3\x16\xdd\x6d\xab\x88\x20\xb1\xd8\x13\xa4\x72\x54\xf4\x4e\xd7\x72\x48\x63\xd5\x6b\xe4\xbe\x55\x53\xbd\x31\x25\xd4\x58\xda\xbc\x45\x4d\x36\xc8\x81\x76\xe5\xe0\xf0\x03\x79\x34\xe7\xde\x72\x9f\x09\x95\x80\x27\x87\xdc\x96\xa5\x70\x69\xd8\x5c\x4b\xa2\xa0\x71\xae\xf2\xab\x14\xf4\xb6\x1c\x2a\x51\x4a\x93\x22\x62\x43\x85\x7f\xb9\x43\x97\xdb\x28\x57\x01\x71\x45\x01\xdf\xf0\x20\x69\x99\xdb\x26\x27\xcd\x7b\x04\xa6\x1d\xbd\x98\xe1\x43\x62\xb6\xac\xcc\x82\x29\xc1\x42\x31\xe5\x5a\x0e\x52\x6c\x72\xa6\x7d\x3c\x75\x8b\xdf\xc2\x90\x03\x4d\x6a\x65\xc5\xdf\xdb\x60\x29\xdb\x59\x1f\x77\x67\xfd\x6c\x43\x5d\xec\x66\x2b\xb7\x43\x6d\xf9\x77\x20\x1e\x52\x5d\x00\x7f\x6b\x49\x8a\xfd\x5a\xe9\xcf\x24\x91\xb6\x20\x52\xfe\xc6\xa8\x1a\xdf\x44\x8a\x32\xde\x20\x5f\x12\xf4\x1e\xe0\xe8\x00\x20\x11\xb8\x5c\xb6\xea\x2d\x1e\x02\x91\xea\xb4\xd5\xf1\x79\xb0\x74\xdc\xac\xf8\xe7\x87\xb0\x9d\xf5\x09\x2e\x62\xb0\xa9\xb6\x92\x6e\xe7\x7f\xd8\x5d\xf5\xbc\x79\xa9\x1d\x38\x24\x75\xca\xe0\x40\x8d\x90\xbe\x98\x81\x94\xb8\xb3\x75\x9f\xa3\x89\xfd\x5c\x2b\x21\xe1\x9c\x20\xf8\x40\xad\xb3\xfc\x86\xf1\x68\xae\xf1\x2f\x8c\x07\xe4\x3d\x35\x1e\xf8\x50\xe3\xd9\xdb\xde\x4a\x9d\xce\xde\xf6\xc2\x56\xfd\xa8\x15\x7a\x6c\x5b\xea\x15\x27\xcd\x62\xad\x33\xfe\x0a\x97\xd2\x60\xe8\x67\x6c\xea\xeb\xc9\xb4\x2d\xd5\x8f\x66\x29\xdf\x86\x76\x2d\x72\xd2\x5c\x94\xb6\x81\x3c\x28\x10\xe4\x16\x76\x80\x86\xcb\x1b\x8e\x6d\x03\xb2\xd7\xd4\xc4\x9f\xb9\x9d\x26\x5a\x2f\xa5\x29\x04\x02\xb2\xc4\xce\xbb\x69\x2d\x24\xbd\x5d\xd5\xb8\xb4\xda\xfe\xca\x2a\xa8\xdf\x3b\x4e\x78\x15\xba\xd6\xbc\x55\x6e\xb1\x1d\x1c\xfb\x9f\x05\xf7\x7f\xc9\xa6\x0e\x85\x82\xcd\xfc\x46\x50\x56\xb4\x09\x55\x4a\x69\x39\x00\x51\xd8\x81\x6b\xd7\x27\xb7\x21\xf9\x59\x8b\xa3\xf5\x1b\x7f\x3b\x01\x4e\xb6\x6f\xc2\xb5\x34\x59\x21\xdc\x8d\x6b\x5d\xdb\x85\x6d\x4e\xab\xed\x6e\xbd\x63\x25\x5b\xa6\xf9\x20\xa8\x35\x99\x9f\xea\xa1\xaf\x67\xc1\x95\xb1\xbf\x11\x1b\x37\xe3\x40\x54\x15\x5c\xa4\xb0\xe5\x88\x8b\xc6\x1d\x53\x7b\xfb\x71\x99\x5c\xf2\x4f\x8a\x6a\x57\xaf\x0b\xa2\xcf\x90\xee\x40\x06\x2a\xef\xb8\x5d\x73\x3a\xb3\x66\xc3\xa9\x66\xab\xd1\x79\xc3\xbb\x96\x89\x30\x59\xba\xb8\x94\x68\x0f\x1f\x63\x2f\x5b\x4f\x33\x99\xba\x07\xe4\x29\xc6\xe4\xa6\x6e\xc2\xea\x93\x13\x48\x30\x1e\x92\xbc\xd3\xd1\xde\x66\xea\x9b\x5c\xd6\xd5\x88\x1b\xd4\x41\x3e\xea\xb0\xe5\x6a\x88\x08\x7a\xa6\xbe\x95\x00\x47\xd0\x73\xf5\x39\x57\x9f\x8f\xd0\x23\x1f\x75\xfe\x58\x27\x90\xfe\x48\xa5\x7f\x77\xf8\x54\x7d\xef\xc3\xf7\xf5\xc1\x8f\x43\x94\x5b\xa6\xc6\x8c\x91\xe3\x32\xa6\xe5\xb8\xf3\xec\x39\x7a\xb4\x3f\xd9\x9f\x13\xb7\xaa\xcc\xb3\x4e\xa8\x63\x3e\xc9\x31\xce\xc9\xc5\xce\x9b\x04\x46\x9e\x34\x46\x2b\xb7\x71\xab\xac\x8b\x36\xa8\x50\x24\x8d\x27\xf7\x5f\xdd\x63\xda\x28\x20\xba\x8f\x28\x7a\xd4\xe5\x63\x31\x01\xa9\xbe\xf0\x8a\xed\x52\x66\xcc\x35\xc4\x51\xcd\xe7\x88\xc8\x9c\x5c\x71\xba\xb9\xf1\x6d\x58\x88\x2b\xdf\xc4\x8f\x08\x7d\x1d\x55\x62\xa1\x15\x89\x4b\xff\x71\x9f\x64\xfe\x20\x1f\x16\xf1\xae\x4f\x6b\xce\x20\x4a\x08\xff\xcc\xe7\x27\xd7\x2b\x17\xfd\x3f\x77\xdc\xef\x3d\x9d\x74\xb1\x3b\xbe\xb9\x0a\x17\xcb\x6c\xd2\xc5\xff\x40\x58\x33\x8f\x20\x56\x4a\xac\x1d\xbb\x6f\x6f\x0f\xf7\xca\x4b\x54\xd6\x08\xa8\xe0\x54\x28\xb9\x8a\xfb\xb2\x6c\x3c\x98\x40\x70\xf4\xf1\x41\x11\x7b\x51\x7c\x7f\xc5\xc7\xe9\x24\x2f\x06\x05\xf1\x21\x20\xcc\x01\x38\x76\xd2\x3e\xb1\x71\xbb\xb5\x7f\xd9\x95\x62\x87\x9f\xd9\x0e\x87\xb2\xdb\xc5\x85\x3f\x3a\x1b\x4b\xb8\x6f\xc6\xff\x79\xa5\x80\x47\x29\xed\x17\x3e\xf0\xfb\x90\xd4\x15\xd6\x46\xc1\xbb\x28\x43\x65\xb7\xaf\x78\x65\xe5\x5f\x79\x0c\xdc\x08\x79\x45\x1f\x67\x6e\x95\xbc\x6f\x68\xbb\x9f\xf5\x47\xa8\x07\x5c\x03\x83\x1f\xbd\xc1\xf7\xdc\x57\x62\x88\x6a\x23\x5c\xa7\x4c\xc7\x0c\x27\x68\x99\x21\x35\xf7\x8a\x2a\x4e\x78\x55\x4f\x4d\x17\x63\x92\xd4\xb3\x2b\x39\x71\xb3\xa2\x58\x4b\x0e\x39\x51\x3d\x67\x91\xac\x53\x48\xcf\xea\xe9\x2c\x7b\xcd\x6e\x54\x86\x05\xbc\x3a\x75\xd9\xa8\xa2\x29\x2a\xf4\x40\x19\x41\x61\xdd\x0d\x7f\x51\x77\xd2\x5f\x56\x7e\x26\x04\x65\x08\xfb\xaa\xb5\xa8\xb5\xb5\x07\x57\x8f\x5b\xab\xef\x2e\x9f\xb4\x96\x4f\xc0\x74\x63\x7f\xa5\xba\x38\x7b\xde\x6f\x2d\xcc\x8a\x8b\x11\x87\x58\xaf\x90\x8f\xfa\x8a\x5d\xf9\xc8\xb7\x5c\xee\x60\x83\x14\xbe\xa6\x6a\xd9\x3f\xf0\x4b\x9e\x22\xff\x3d\x77\x65\x8f\xe1\x9c\x7c\xe2\x74\xff\xff\xcd\x7f\x0b\xbb\xbf\x79\x5e\x97\x7a\xdd\x7f\xec\x93\x0f\x05\xe6\xa8\xe9\xab\xc7\x93\x61\xa9\xb3\xd2\x18\x53\xe1\xa6\x01\xf6\xb2\x55\x1c\x49\x17\x75\x4a\x63\x6c\x79\xb1\x91\x9b\x8b\x8d\x85\xdb\xbb\x45\xac\x24\xa1\x68\x8e\x2a\x73\xf6\xb4\xd9\x9e\x69\x9f\xfb\xec\x97\x48\x56\x75\x82\x09\x81\x08\x99\x54\xa1\xfb\x62\x7a\x49\xfd\xbe\xde\xd8\xf3\x3c\x4e\x36\x51\xe8\x4f\xb9\x8b\xc1\xc0\x5b\x36\x90\x62\x62\x25\x73\x69\x3c\x12\x04\xae\x0c\x13\xdc\xa5\xaa\x7d\x27\xb8\xd3\xf9\xc4\x3d\xc9\x33\x05\xfd\x51\x43\xea\xe5\x4a\xc8\x3d\xe7\xae\xac\x80\x82\x61\x8c\x7d\x4e\xe6\x1c\xe7\x93\xe2\xc4\x42\xdc\x56\x55\xb4\x61\x70\x32\x40\xa3\x80\xa0\xaa\x8f\x06\x48\x72\x80\x89\x42\x0b\xfd\x09\xa0\x9d\xc1\x84\x24\x34\xe4\x41\x12\xf2\x2f\x9f\xdf\x16\xe6\x11\x37\x2d\x69\xc2\x6f\xdd\xfd\x39\x41\x0e\xc2\xd8\x6a\x9f\x85\xd1\x33\x2b\x98\xd9\x28\xf5\xda\x0e\x91\xe4\x85\xf6\xb7\xc8\xd0\x41\x36\xfb\x6a\xb5\x93\x91\x15\x13\x0a\x0b\x4f\x6e\x8d\xc0\xc0\x70\x14\x95\x2c\x2b\x82\x06\x50\xcf\x94\x02\xe6\xee\x5c\x5f\xf1\xf7\xad\x64\x7f\xca\xdd\x32\xe0\xb0\x76\xcb\x29\xf4\x61\xfe\xc6\xd4\xe4\x22\x2c\xea\x81\xb7\x00\xbc\x36\x61\x93\xec\x14\x0c\x9f\xf6\x4a\xb5\x58\x0c\x8c\xaf\xea\x3d\xca\x12\x7d\x97\xfd\xca\xe7\xfd\x51\x55\x6f\x25\x55\xd7\xf6\x1a\x44\x9e\x93\xaf\x9c\xea\xc0\xbd\xbc\xdc\x28\x5b\x17\x5c\x8c\xb7\x68\x65\xe7\xf2\xda\xd9\x95\x44\xad\x68\x91\x27\xb6\x56\x4d\xed\x11\x97\x63\x50\xf9\xa8\xf5\x00\x8d\x8f\x82\x3f\xe8\x7a\x2c\x53\x17\x17\x0a\xa1\xa8\xa2\x26\xca\xea\xca\xa1\x80\xee\xed\x9d\x70\x37\xc2\x9d\x4e\x0b\x23\x50\x21\x07\x77\x78\x8a\x23\x9c\xbb\x91\x05\xd1\x98\xb9\x7a\xc3\x10\x81\x09\x73\x61\x8b\x90\x94\x52\x6a\xb7\xc4\xa8\xef\xc3\x9d\x8d\x62\x2f\x90\x64\x34\xf0\xe1\x32\x47\x6d\xe1\xc9\x19\x77\x63\x8c\x49\x50\x41\x60\xcc\xad\xac\x30\x09\x30\x51\xf8\xa2\x92\x59\x5b\x6e\x12\x60\x88\x72\x71\xc2\xdd\x0c\x8f\x98\x5b\x5d\x63\x92\xa9\xac\x89\xf5\x74\xbc\xe1\xd6\x1b\xa4\x83\x70\x4e\x7e\x84\x73\x86\x3c\x6f\x1f\x24\x99\xd1\xbc\xef\x69\xbc\x71\xc7\x9a\x70\x35\x98\x79\xdf\x93\x6c\x4a\x07\xea\xc3\x4c\x8f\xf6\xd5\x8f\xca\xc4\xe8\x60\x81\x30\xf9\x5c\xe0\xd9\x46\x28\x6e\xae\x7d\x59\x24\x26\xbf\x73\xaa\xef\xa3\xd0\xe7\xea\x2f\xe0\x64\x6e\x47\xfc\x32\x49\x62\xce\x04\xac\xcb\x09\xd3\xda\x6e\x6e\x9e\x81\xb0\xc6\xea\x9c\xbc\xe6\x74\x33\x8b\x20\xc6\xb5\xd5\x9b\x90\x15\x17\xa0\xfe\x41\x57\xda\x79\x00\x91\x48\x98\x58\x11\x85\xa1\x22\x27\x6f\xd5\x46\x66\x42\x24\x92\x15\x9a\xc8\x36\xdf\xa1\xe4\x7e\x19\x59\xa6\xbb\x83\x16\xc8\x10\x81\x62\xe7\x74\xc5\x84\x7f\xd4\x6a\xdf\x5e\x1c\x37\xac\xdb\x89\x90\xbd\x2b\x08\xf4\xdb\x9b\x26\x71\xa8\x78\xf9\x17\xe5\x40\x51\xbb\xe0\xf1\x4d\xa3\x68\x5f\x12\x17\x9e\xd1\x80\xa3\xbb\x53\x13\xa0\x8e\x3e\xbb\xdf\x23\x82\xef\x76\xd8\x2c\x3c\x0d\x30\xd6\x5e\x06\xef\xd4\x4a\xa4\xeb\x58\x31\x57\xd9\x22\xb9\xaa\xcc\xb5\x81\x5b\xda\x9e\x93\x19\xdc\xf5\x80\x4d\x04\x0f\xd8\xec\x56\x7e\x3e\x44\x26\x07\xd5\xdc\x8c\x85\x70\xb1\xa0\xaa\x3f\x8a\xdc\xbd\x14\x1b\xe9\xec\x35\x1f\x6b\x5d\x0e\x9f\xd8\x7b\xd2\xc1\x3a\xcd\x20\xf4\x6e\x12\x41\xc0\xc1\xfc\xee\xb0\x24\xe9\xe8\xc4\x9b\xb5\x05\xc1\xbb\x1f\xd6\x60\xf3\xc1\x04\x39\x2e\x22\x25\x2a\xe1\x1e\x8b\x79\x2a\xb3\xd2\x47\xc6\xe8\xc1\xf4\xa5\xc7\x96\x66\xaf\x60\x30\x10\x06\xd8\x4f\xab\x3e\x24\xcb\x69\xef\xa0\xdd\x37\x63\x95\xf2\xd2\x7b\xac\xbc\xfe\xe2\xa3\xef\x66\xc7\xea\x7f\x88\xac\x58\x08\xa7\x71\x70\xdc\x0a\x00\xa4\xf0\xcc\xee\x8d\x5b\xee\x18\xa4\x26\xe9\xb7\x86\x34\x59\x83\x8a\x26\xf1\x7f\xe4\xee\xa3\x17\xef\x4e\x3e\x9f\x9d\x6e\x60\xea\xaa\x06\x45\xe5\x0d\x14\x80\x13\x79\x84\xf2\x47\x0a\x75\x18\xb0\xdd\xb3\x51\x01\xd5\xdf\xdb\x2d\xf7\xc0\x94\x06\xad\xea\xaf\x7b\x9a\xbd\xbb\x4f\xe3\x3b\xd7\xee\xfd\xb5\xa5\x91\x5b\xc6\xbd\x63\x85\x23\x32\xc5\xb4\x46\xf2\xc6\x07\x07\x29\xdd\x86\x67\x13\xff\xda\x80\xaa\x78\xf2\x5b\x47\xb5\x5e\x2e\x59\x6a\x06\x55\x69\xc7\x33\x19\x58\x47\x9f\xae\xed\xd5\xe7\xfd\x36\x05\x1a\x38\x3b\x4d\x93\x34\xe4\x29\x0f\x6b\xfe\x4e\xed\x8e\x4d\x0b\xce\x76\xbb\x28\xde\x8d\x2e\x17\x76\xe2\xef\x00\x8a\x3b\xdc\xf0\x8a\x52\x80\x8b\xee\x2b\xa4\xaf\x06\x3a\xa7\x91\x08\xee\x2d\x0b\x56\x91\x9d\x88\xbe\xe2\xb1\x55\x00\xce\xb8\x87\xb6\xe3\xee\x0a\x0d\xbb\x03\x81\xdf\x4b\x40\xcc\x31\xbf\xe4\xa9\x8c\x02\x16\xbf\x88\xa3\xb9\xf0\xd1\x32\x0a\xc3\x98\x2b\xf4\xd6\xa4\x2a\x66\x0f\x3e\x80\xb8\x5c\xa8\xa5\x85\x91\x6d\x05\x2c\xaf\x6e\xa9\xb4\x37\x40\x4a\xa8\x40\x14\x01\x05\xf9\x46\xb7\xd4\x2d\x4a\xbb\xec\xb5\xfb\x61\x5e\x94\xd6\x98\x0a\x62\xef\x22\x1d\x0e\x63\xbd\x5a\xf1\x14\x78\xea\xda\x33\x45\xd7\xbd\x43\x88\x3e\x04\x85\xef\x1b\x1c\xf7\x34\x32\x7e\x21\x1f\xe4\x42\x8c\x31\x91\x6d\x47\xe2\x2d\x27\x75\x1e\xa6\x7a\xc2\x8c\x92\x12\xe7\xe4\x17\x0e\x2f\x0e\x1d\x63\xf2\x42\x7f\x3d\xd6\x94\xf7\x0d\x2f\x49\xea\x92\x2f\x13\x0c\x2e\x05\x5a\xe3\xc5\xbd\x60\x11\xc5\x61\xca\x05\xa8\x86\xae\x52\xa6\xa6\x7d\xaa\xb6\x80\xb6\x2c\x46\x21\x49\x6b\x0f\x5b\x71\x32\x46\xb6\x0e\x22\xa8\x56\x03\x11\x14\x85\x95\x27\xac\xb6\xa7\xf2\x0b\x6f\xc6\xc2\x85\xf7\xb0\xac\xa5\xc1\xb1\x3f\x17\x3c\xb8\x98\x26\xd7\x36\x1c\x49\xeb\x56\x6e\x79\x58\x21\x27\x29\xc8\xbc\xc2\xbc\x95\x50\xb6\xb3\xb3\x4b\xfb\xc2\x44\xeb\x52\xbe\x80\xe1\x9a\x13\xb1\xce\x78\x6a\x5e\xbc\x40\x22\x11\x1c\xe5\x77\xb4\x0a\x87\x02\x91\x59\x92\xfa\x02\xde\x7a\x2b\x9c\xc6\xfe\xe0\x74\x3c\x46\x96\x59\x45\xa4\xe0\x56\x27\x64\x8c\x0c\x57\xab\x00\x6b\xd8\x5a\x95\xaa\x79\x5f\x44\x2c\xf3\x3b\x99\x90\x97\x8a\x9d\x52\x64\x78\x95\xf9\x9c\x8e\x27\xda\x50\xff\x0a\x6e\xd2\xdc\xcb\x4e\x59\x66\x7a\xaf\x5f\xb0\xd1\x7b\xfd\x92\x7f\x06\x7e\xe4\x3e\x76\xab\x7c\x18\xb0\xc9\xa8\x05\xb5\x9a\x99\xaa\xb9\xa6\x81\xaa\xb9\xa0\xc1\x5f\x66\xd4\xb6\x69\x50\xd8\x9b\xc5\xfc\xda\xc4\x93\x49\xb3\x9e\xd9\x92\x28\x27\x7f\xf0\x02\x29\x31\x78\x0a\x68\x67\xcf\x6f\x38\x31\xf2\x6e\x6d\x43\xfb\x9b\x25\x4b\xe7\x91\xf8\x0c\xd7\xbf\x07\xfd\xe2\x0e\xea\x2b\xb5\xb1\x34\x7d\x8a\xc2\x8a\x66\x85\x13\xd4\x33\x03\x81\xd8\xd4\x86\x8f\x14\x94\xeb\x3b\x6e\x91\xdb\xd0\x9d\xa4\x64\x33\x16\x13\x7f\x2f\x1d\x0b\xd0\x55\xb7\x46\x0b\xad\x60\x2a\x56\xdd\x73\x80\xa8\x02\xb6\x8a\x24\x8b\xa3\xaf\x5c\x63\x4d\xc5\x1f\xca\x31\x9f\x00\xff\x67\x9e\xb5\x6c\xe5\x2f\xd5\x9c\x5b\x67\xfb\x0e\x5e\x51\x33\x4f\x5d\xa9\xe9\x29\x7e\xbd\x57\xc1\x39\xc5\x14\x6b\x9c\xf2\xc2\xdd\x5b\xb7\x0e\xdf\xfa\xf6\x36\x43\x0b\xa1\xbe\xf7\x34\xe5\x4b\x04\xd7\x75\xf5\x63\x38\xfe\xc0\x7b\x9a\xe7\x44\x47\x0d\x64\x0d\x71\x88\x57\xaf\x47\x70\x4f\x09\x13\x99\x97\x25\x4b\xae\x10\x5a\x5a\x60\x70\xdc\x72\xf7\xa8\x49\x1b\x5b\x2f\x3b\x7c\xe1\x04\x24\x14\x85\x61\xe1\xaf\x42\xf4\xb3\x28\x56\x40\x7d\x0e\x9c\x8d\x66\xc1\x6d\xd7\x95\xd1\x94\xbd\xb7\x21\xf0\x77\x76\x77\x41\x03\x5d\xb9\x25\x00\xad\x89\x96\x8c\x14\x32\xd7\xb1\xed\x71\x4e\xbe\x58\x89\x29\xf3\x39\xb1\x28\xb7\x71\xb8\x79\x43\x6b\xb7\xad\x99\x1b\x4b\x33\x30\x9f\x17\x9f\x5d\x59\xe7\xc4\x72\x4c\x2c\x4a\x28\x31\x42\xff\xce\x87\x9e\x5a\x6e\xe5\x25\xeb\x55\x2f\x12\xb3\xc4\xd1\xdc\x9b\x03\x32\x02\x0f\x7b\xd9\xb2\x88\x2a\x55\x5b\xe8\x41\x9e\xb7\xc7\xdd\xdb\x6a\x7b\xca\xc2\x39\xaf\x1e\xec\x13\xee\x32\xcf\xe2\x2b\xdc\x06\xf2\x8b\xaa\x93\x7f\xa1\x0e\x28\xd1\x2e\x3c\xe9\xa9\x67\xda\xce\x87\x56\x1b\xb0\xb8\x38\x27\x16\x41\xab\x43\x56\x34\xa0\x25\x2d\xe6\x69\x10\xde\xdf\x5c\x79\x1d\x43\xd7\xd0\x8d\xe9\x6f\x7d\x6a\x71\x3e\x7c\x59\x7b\x6f\x91\xa2\x17\xb0\x60\xd6\x1c\xf5\x33\xa7\x97\xee\x4b\xae\x8f\xf7\xaf\x6a\xa3\x94\xde\xa1\x3e\xa7\x08\xe5\xd5\xf0\x93\x33\xb7\x86\xa1\xac\x8b\x2b\xec\xad\x11\xb8\x47\xc1\x76\x40\xe6\xfe\x92\xf5\xd8\xd4\x8a\x39\x78\x10\x33\xad\x3d\x88\x99\xd0\x4d\x41\x2c\x2a\x1b\x86\xd8\x3d\x54\xd8\xec\x18\x58\x6a\x3b\x1d\xfd\xd7\xd3\xf4\xaa\xf1\xb3\xae\xfa\xd1\x27\xab\x92\x94\x94\x9c\x59\xb7\x95\x46\xff\xcc\x9b\x5c\x40\x85\x14\x26\x39\xd1\x9d\x11\xeb\xff\x59\x79\x2a\x34\x05\xe3\xe0\x4f\x10\x09\xf4\x18\x93\xff\x70\x78\x5b\xf1\x27\x8e\x87\xcc\x7d\x5a\x3c\x11\xfa\x0f\x05\xdd\x1b\xb6\x8c\x77\xe9\x8e\x8c\x78\x5c\xe5\x05\x12\x31\x8b\xe6\x3d\x55\x09\x81\xfb\xd7\x3f\x1a\x8b\xf9\x0a\x0a\xd8\xc5\xfc\x1f\xb5\x98\xff\xe0\x98\xfc\x5b\x75\xa5\xc7\xd9\x1a\x56\xe8\x4f\x6a\x46\x48\x46\x65\xa7\x23\x3d\x35\x9e\xbf\x48\x7c\x17\x07\x56\x78\xd1\x53\x30\xf6\xb1\xdf\xae\x59\xbf\x4d\x78\xfe\x0f\xf0\x4f\x8a\x4c\xf9\x99\xa2\x15\xc9\xea\xc6\xb7\x76\x99\xc8\x95\x98\x54\x9e\x53\x8b\xc8\xe0\xb8\xdf\xc7\xad\xfa\x83\xcf\x5b\xb7\x1d\x49\x18\x65\x6c\x1a\x2b\x12\x9c\xe5\x24\x1d\xa1\x57\xc9\x2a\xe2\x21\xf2\xd5\xc7\x8d\x23\x13\x27\x88\xa3\xd5\x34\x61\x69\xb8\x43\xc2\xfa\x1f\x4e\x0a\x58\x97\x7b\x62\x2f\x23\xb0\xd6\x8a\xaf\xd6\x2f\x85\xfe\xab\x79\xba\x1e\x72\xb4\xb4\x77\xf4\xbe\xde\x08\xbb\xcf\xd5\xee\xd5\xf8\x37\x2f\x77\x2c\xec\x04\x66\xdc\x57\x72\xb3\x69\xfe\x5b\xde\x1a\xa5\x9b\xbc\x7d\x67\x7e\xf3\x92\x2e\x97\x4c\x84\xbd\x77\x91\xe0\xce\x8f\x31\x9b\xb7\x8b\xc4\xbb\x25\x74\x78\x88\x70\x05\x89\xf7\xde\x42\xaa\x9a\x84\xad\xb2\xf8\x4f\xdd\xea\x5c\x14\xca\xc6\xbb\x65\xac\xb1\x9c\x18\x7f\x0e\x2e\xe9\xa5\xfb\x5f\x8e\x87\xff\x6d\x1c\x4b\x3d\x67\x1d\x12\x58\xfe\x39\x9c\x6a\x16\x7e\xa6\xa1\xf7\x30\x7c\xba\x7b\x17\x70\x69\x7c\x5f\x0c\x12\x6b\xc5\x61\x39\x61\xf6\x21\x72\x63\x47\x87\x38\xaf\x7f\x72\x3b\x34\x94\x8e\x10\xc5\x99\xa0\x76\x7d\xd0\xba\x21\xcc\x2d\xe3\xde\x11\x22\x56\x59\xc6\xaf\x57\x29\xe8\xca\xe0\xa3\xad\xaf\xa9\xd1\x45\x60\x4c\x52\xb5\x26\x6e\xf9\xb4\x73\xfd\x94\xf1\xf2\x41\x39\x7b\x6b\x24\xb9\xb0\x86\xb0\x82\xbe\x1b\xdb\x59\x5a\x58\xf9\x2c\xa5\xd5\x19\x6b\x71\x21\xe0\xa9\x38\x93\x59\x50\xf5\x7c\xfb\x2e\x02\x33\x77\x11\x0c\x8d\xfa\xdb\xb0\xe6\x67\x45\xde\x80\x59\xb8\x53\x95\xb3\x75\xc4\xee\xd0\xe7\xfc\x05\x05\x58\xd5\x5e\x70\xd8\xda\x3a\x43\x64\xb3\x48\xf9\xcc\x47\xdf\xa1\xae\x66\x5f\xdb\xad\x1b\x07\x08\x04\x6f\x5b\xc4\xaa\x5d\xbf\x5d\x79\x63\x41\xf5\x91\xbb\xda\x21\xab\xf4\x0a\xb4\x6f\xad\x33\xe9\x89\xe4\x0a\xbb\x18\x13\xe4\xb0\x79\xd2\xee\x4b\xfa\xb0\x6e\xde\x73\x77\xc0\x0f\xbf\xaf\x46\x6b\xf3\x78\xd1\x23\x04\xd7\xda\xe5\x04\x56\x43\x67\xbb\x10\xd7\xdd\x16\x9f\xbb\x46\x0d\x7b\xe5\x9e\xab\xc1\x77\xea\x24\xc3\xda\xc3\xde\xf7\x15\x7a\xc7\x32\xe9\x94\xb0\xbe\xb7\xcd\xd2\x57\x53\x01\x09\xe1\x2d\xb1\x68\x87\x81\xa9\x40\xe7\x2c\x2f\xf4\x9a\x6d\xef\xb6\x56\x75\x91\xcd\xd8\xb8\xe8\xbb\x1f\x8f\xd5\xff\xea\x1a\x18\xd5\xfb\x79\xc0\xe3\x76\xaf\x76\x25\xf9\x99\x90\xf4\x9a\xd9\xd5\x97\x35\xcd\x86\x6d\x9b\x6d\xa5\x86\xb6\x04\x9b\x0a\xa0\xfa\xbf\x23\x56\xc9\xc3\x5e\x5b\x2f\xb5\xff\x0f\x50\xa8\xde\x65\xab\xdb\xc2\xbf\x20\x69\x82\x2a\x00\x6e\xca\xee\xd8\xbc\xdf\x30\xd4\x86\x5d\x60\x6b\xbc\x95\xfc\xbf\x71\xd0\x6d\xd1\x37\x1e\xb8\x2b\xee\x59\xff\x94\x07\x49\x1a\xfe\xe5\x0d\xf0\xad\x48\xa7\x22\x02\x2a\x2c\xb3\xe0\x2c\x96\x0b\x20\x90\xfa\xd3\x93\xc9\x17\x25\xdf\xbe\x62\xf0\x5a\xd0\x7d\x2a\x63\xc0\x8d\xea\x64\x3f\x34\xd4\x4a\xa5\x8a\x7d\x40\xef\xae\x1e\xbe\x09\x01\xdf\xd9\xd2\x43\x71\x2c\xc6\x45\x00\x02\x7d\x2b\x0a\x38\xb1\xa4\xc9\x89\x3d\x58\xb4\xfd\xeb\xfc\x57\x2a\x49\xc9\x92\xec\x62\xbf\x0c\xd7\x15\xab\x71\x16\x6a\x1a\x4e\xe0\x11\x20\x5f\xeb\x7a\xde\x27\x29\xd7\xcf\x73\xb7\xd1\xa2\x43\xbb\xa6\xbb\x24\x1f\xcd\x60\x5f\x67\x15\xc7\x60\xab\x51\xb1\x86\x57\xd4\xf7\x0e\xf9\xd2\xb1\xff\x1e\x1c\xdb\x1f\x88\x54\xf5\x6d\x87\x3f\x1c\xab\xa4\xaa\x9e\x6f\xa0\x12\x1a\xd6\x9e\x29\xcb\x78\x1c\x69\x15\x77\xdd\x52\x93\x13\xd0\x06\x3a\x88\xb0\x11\x8a\x15\xd7\xe5\xa3\x65\x92\x02\x01\x88\x80\x51\xbb\xcb\xeb\xe0\x3e\x9f\x83\x56\xe6\xa2\xaa\x3a\xb9\xc3\x60\x54\xdd\x07\x8f\x28\x7a\x54\xf1\x43\xd2\x8f\x53\x60\x92\xa9\x25\xd2\xb7\x94\x38\x01\x4b\xf3\xff\x07\x3c\x0f\xee\xc4\xc4\xb1\x24\x1b\xbd\x91\x8c\xfa\x78\x4f\xb1\xd4\xc5\x96\x4a\x1f\x18\x4a\x41\xb2\x74\xce\x25\xbc\x29\x8f\x72\x4d\x12\xda\xd0\xc6\x69\xb9\xd9\x94\x34\x57\x65\x40\xcb\xf0\x13\xf7\x88\x78\x7f\x87\x3d\xf6\x75\x94\x05\xaa\x3f\x1e\x3a\x0f\x33\xcd\x9e\xc1\xfc\x8a\xc2\x0f\xb1\xa8\xc2\xa6\x94\x0f\xe1\x52\xee\x42\x6d\x91\x74\xf9\x98\x4d\x94\x18\x69\x46\xac\xc7\xa0\xd8\x21\x95\x1e\x65\xaf\xd3\x64\xb5\xe2\xe1\x7d\x2c\x8e\x3a\xa4\xbf\x98\xa7\xe3\x35\x73\x98\x13\x64\xea\xb6\x86\xb3\xda\x1e\x83\x61\x1b\xe0\xff\x7c\xf3\x2e\x51\xa0\x76\xbc\xbd\x5e\xa4\x60\x04\x01\xab\x75\xb3\x36\xa1\xe1\xd9\xd7\xf4\x9b\xdd\x68\x35\x88\x28\xed\x80\xf0\xdc\x1d\x2f\x9f\xb3\x4b\xcd\x73\x76\x82\xa6\x2d\xcf\xd9\x71\x2a\xb4\x79\xd3\xcb\x82\x94\xad\xf8\xa7\x24\x89\x87\x6c\xcc\x27\xb7\xb7\xae\xfa\x43\x37\x32\x91\x2c\xf6\xfb\xf6\xa9\x9f\x7e\x8e\x89\xca\xf0\x20\xbd\xdb\xd5\x3f\x74\x66\xb7\x6b\x5f\xaf\x8b\xf0\x26\xf5\xb8\x1b\x95\xaf\xd7\xa5\xf0\x7a\x1d\x90\x0c\x12\xd7\x9f\xe6\x2b\xc7\x1a\x9b\xb1\x26\x34\x6e\x1d\x6b\x62\xc6\xda\x5c\x50\xef\xf7\x64\xfa\x4d\xa3\xae\x8c\x33\xae\x8f\x33\x86\x71\x5a\x0d\x69\x8e\x01\xe0\x44\xfc\x2f\x42\x1e\xee\x90\xd6\xa0\x2f\xf5\x3c\xe4\x84\x8e\x27\x6a\xdc\x72\xa2\x6f\x2e\x6c\x9a\xf3\xf6\xb7\x41\x41\x8a\xa0\x4f\x26\xac\x6f\xb1\xc9\xf5\x7d\xf2\xff\x93\x05\x82\x29\xed\x58\xa4\xbf\x34\xb9\xca\x64\xfa\x76\xa6\x9b\xbc\x36\xad\x87\xac\xe7\xdf\xa6\x31\x38\xe5\xe9\x65\x14\x70\xc7\xe2\xc4\x9b\x76\x5c\xb8\x8e\x4d\x85\xcf\xdc\x65\xe4\x2e\x6a\x1b\x47\x77\x11\xdb\x86\xc4\x5f\x5a\x14\xcd\x01\x24\xc8\xd9\x87\x38\x4b\xb0\xcd\x0b\x77\x33\x47\x53\x98\x0c\x8c\x17\xad\x03\x5c\x58\x5d\x8f\x1a\xa1\xb8\x6b\x84\x99\x2c\xae\x12\x6b\x22\xcd\x8d\x74\x00\x76\x91\x40\xd6\x75\x76\x06\x3e\x05\x78\x5e\xe9\x88\xd4\x56\xb7\xbe\x96\xf4\xd2\x0d\xa4\x66\x25\x17\x7f\x86\x95\x34\x33\xfb\xeb\xcc\xe4\x5a\x6e\xbb\x2b\xdc\x61\x9c\x20\xc5\xcd\xf4\x33\xf3\x92\x5a\x73\x27\x38\x91\xd0\xee\xcc\x4a\x5e\x07\x7d\xb5\x9e\xca\x52\xd2\x4a\x14\x8b\xe2\x21\x36\x95\x62\x2e\x56\x6a\x67\x85\xe8\x2b\x37\x57\xf9\xe9\x73\xc1\xaf\x9c\xd7\x3a\xba\xac\x92\x43\xce\x5e\x15\xb1\x5c\xc8\xab\x5f\x5e\x17\x8d\xfc\x92\xa4\x17\x91\x98\x3b\x61\x94\x42\x84\x3e\xc5\x10\xa6\x3c\x4e\x58\xa8\xed\x01\xa7\x5a\x15\x57\x94\xaf\x59\x09\x1c\x5d\xb2\xad\x7b\x3e\x42\xa6\xea\x6c\x1d\x23\x1f\xe2\x94\x15\x3f\x73\xb8\xb3\xa7\x9b\xaa\x4d\x09\x74\x16\x65\x41\x27\x68\xeb\x2d\x27\xc1\x62\x2d\x2e\xb4\x3d\xc8\xd6\x7c\xc3\x59\xe8\x40\x7a\xa6\x18\xa2\x68\x69\x82\x6f\xb6\x94\x52\x99\xf6\x71\x1a\xc5\x0e\xa7\xe9\x1a\x5c\xe2\xeb\x45\x7f\x79\xf1\xce\x29\xf3\x54\xc9\x79\x92\x26\x6b\x19\x09\x5e\x2f\xf8\x93\x4d\x56\x65\x32\x99\xa4\x6c\xce\x3f\x73\xb5\x65\xa3\x44\x54\x16\x0b\x32\x9c\xd4\xe6\xa0\xdc\x10\x1a\xb0\x03\x2e\x99\x60\x73\x9e\x66\xfe\x46\x83\xf2\xb3\x09\xd3\x5e\x87\xeb\xce\x48\x89\x0f\xb2\x86\x3f\x90\x57\x3b\x11\x21\xf8\xbe\xa2\xd2\x40\xbf\x59\xa7\x71\xe3\x6c\x99\x90\x44\x2e\xd7\x87\x48\x87\xa0\x81\x23\xa4\x8e\xa3\x3a\xe5\xf7\xc5\x2e\xdc\x8d\xb1\xee\xd2\xf3\x15\xd8\x8c\xe7\x84\x61\x08\xff\x85\x71\x6e\x39\xa0\x06\x2c\xb3\x8b\x68\xa5\xf8\xda\x9c\xac\x64\x19\x68\x55\xaf\x88\xfc\x3b\x2c\x2c\xad\x26\x8a\xd3\x86\x12\x7d\xd1\x03\xcf\x0b\xd2\xce\x87\x7f\xbb\x85\x65\x97\x20\x56\xb0\x19\x4b\x09\x6c\xcd\x26\x27\x82\x32\xa3\xf0\x4f\xcd\x93\x10\x10\x68\x87\xfb\x82\x24\x94\x79\xf5\xed\x45\xa2\xb2\x4c\x32\x52\x67\xd8\x4f\x48\x56\x14\xfb\x9c\x5c\x95\x56\x60\x05\x59\xfd\xe6\x45\x36\x8a\x5c\x49\x78\x3b\x47\x7b\xcf\x3a\x2f\x1a\x56\xd6\xc2\xf1\xa5\x07\x83\x2e\xbc\x0c\xae\xc0\xab\x1a\x1d\x1e\xff\x53\x71\xd1\xed\xa6\x07\xad\xfb\x6e\xb8\xd2\x40\x38\x27\x94\x13\x35\xc4\x14\x42\x41\x2b\x62\x16\x2a\x12\xb2\x92\x78\xb8\x6a\x92\x1e\xb0\xf5\x68\x7b\xd1\xfc\x3e\x7b\x51\x1b\x6d\xb9\x2b\x62\xe7\xf6\xce\x1a\x6f\x20\x38\x94\x8e\x69\xe7\x57\xa9\x95\x24\xc8\x1a\x9e\xd2\xb5\x50\x08\x4b\x51\x06\x75\x22\x0d\x3a\xf9\xac\x53\x9d\xb7\x55\x82\x41\x1e\xd2\xde\x74\x1d\xc5\x61\xa3\xb5\x97\x2a\xed\x5b\xda\x62\xd5\x73\x56\x69\xa8\x76\xfe\x50\x3e\x31\xe8\xa3\xda\x54\xed\xfc\xd5\xdc\x5e\x0a\x32\xcc\x2b\x9e\x09\x29\xe5\xf7\x59\x56\xc3\x86\x4d\xcd\xb4\x5f\x21\xbd\xc2\x28\x7a\xb6\x48\xb0\xcc\x35\xfa\x98\x49\xca\xdc\xc3\xa7\x98\x5c\x4b\x70\x19\x98\x19\xfe\x62\xaa\x36\x81\xbe\xd9\xe2\x73\x92\x71\xf9\xa3\xfe\x6e\x0e\x5e\xc9\xef\x6f\x40\xe7\x77\x43\x04\xdd\xb0\x38\xf6\x8d\x90\x56\xf7\xef\x62\x71\xec\x14\x80\xbc\x96\x1e\xf3\xa6\x52\xe0\x2d\xe7\xd9\x5a\xb8\x8b\xa6\x83\x99\x8e\x7c\x6d\xbb\xd3\x6f\xc5\xe5\x64\x2d\x16\x26\xc1\x76\xbc\x57\xeb\xb9\xc8\xff\xdb\xfb\x1f\x40\x64\xeb\xdd\xcb\xf3\x9f\xbb\xef\xcf\x0b\x8f\x81\x9b\x75\x1c\xb7\xf2\xc1\xba\x48\x31\x7a\x82\xbe\xd8\x4f\x64\xed\xf9\x37\x60\x2c\x3d\xc0\xe4\x44\x2f\xde\x8d\x59\xbc\x4b\xb5\x78\xdc\x50\x33\x9f\x93\x79\x9c\x4c\x59\xfc\x25\x8d\xcd\xf2\x41\xdc\x32\x10\x53\x58\x85\x9c\x19\xa9\x60\x7d\xc7\x3b\xe2\x7f\x2e\x26\xea\x89\x0e\xe6\x85\x09\x72\x10\x59\xdb\xc8\x5d\xf6\x16\xb3\xa0\x8c\xa4\x54\x78\x8b\x24\x93\xf0\x38\x93\x25\xa3\xf0\x1e\xd3\x2a\x4d\x64\x12\x24\x31\xc9\xa8\xf0\xb2\x4a\x18\x40\x12\xd0\x17\x69\xca\x6e\xbc\x59\x9a\x2c\xdd\xac\xa0\x0d\x77\x3d\xd7\xfa\x20\x12\x57\xd0\x59\x59\x55\xc4\x45\x04\xed\xef\x57\x2e\xf3\x96\x97\x7c\x31\x26\x41\x71\x0d\xa0\x4d\x37\x52\x98\x86\x75\xec\xa9\xe0\x3e\x25\xe2\x43\x94\x84\xe5\x5e\xe6\xd8\x1a\x1c\xee\xd7\x1a\xe6\xe4\x42\xed\x98\xc1\x51\x1f\x93\x2b\x49\x5d\xe6\x0e\xfa\x70\xcd\xef\xf8\x31\xc6\xe4\x54\x6f\xa2\x2b\xb3\x89\xce\x80\x71\xd8\x12\x33\xad\x20\x29\x49\x14\x5e\xfb\x8c\x94\xb2\xb8\x0e\xcf\x5e\xdc\x08\xde\xa1\x81\x8c\x6a\x1a\xc8\x94\x1c\x60\x92\xd1\x68\xdc\x9f\x90\x80\x46\xe3\xc1\x84\xac\x29\xd2\x2c\xaa\x76\x3c\xce\x7a\xa8\x7c\x41\x06\xf5\x2a\x97\x0b\xff\xea\x42\x6b\x5d\x6d\x14\xfa\xeb\x2a\x74\xeb\x7d\x07\x89\x90\x2c\x12\xb0\xcf\xab\x6e\x1e\xb2\x78\x59\xe6\xff\x62\xfd\xc6\x7c\x52\x28\x7e\x5b\xfa\x93\x95\x6b\x50\x19\xd1\x42\x9e\xff\xea\xf4\xd4\xe3\x59\xc0\x56\xdc\x5d\x63\xa2\xbd\x5c\x01\xad\x05\xee\x5e\x86\x2d\x7f\xb1\x64\xd7\xfa\xe2\x96\x76\x03\x27\x8a\x77\x30\x8a\xf3\x98\xcf\x64\xbb\xfd\x09\x4d\xed\xc9\x7e\xc9\x67\x49\xaa\x58\x7b\x00\x97\x89\x7b\xec\x96\x9a\xf3\x86\x4b\x4c\x95\x94\xd6\x66\xc8\xc7\xd2\xce\xb0\x60\xee\xfe\x1a\xc7\x5f\x1c\xba\x07\x69\x95\x4f\x15\x41\x28\xf7\x7a\x4e\xb4\x19\xa7\x12\x9f\xe2\x95\x84\x01\x15\x94\xef\x5f\xa7\x1f\x3f\x98\xc7\xe7\xe2\x24\x60\xb1\x91\x72\xbc\x39\x97\x6f\x25\x5f\xba\x1c\xdf\xde\x42\x19\x7d\x89\x3c\x9a\xdd\xb8\x12\x57\xf4\xef\xd5\x63\xc1\x70\xa9\x16\x83\x53\x21\xd4\xa9\x88\x69\xaa\xf5\xf2\x69\x45\x2f\x5f\xad\x7d\x32\x9b\xf1\x40\xe2\xfa\xf3\xdc\x8d\x3e\x63\x3c\xac\x0d\x2f\xb3\xc3\x23\x12\xe7\x64\xcc\x49\x3c\xc1\x64\x1c\x93\x68\x62\x63\x4a\x48\x3a\x2e\x05\x21\x6b\x95\x2f\xee\x15\x19\xe3\xfa\x29\x1c\x7a\x95\x0d\x1f\xce\x6b\x23\xa8\x22\x6b\xa1\x9f\x00\x0a\xf9\xa8\x50\x48\x05\x41\x70\xb3\x39\x7f\x4a\x93\xf5\xaa\xc1\x4a\xbc\x52\x9c\xac\xd6\x4f\xf4\x6a\x3e\xe8\xfc\x7a\xc5\x44\xc8\x43\x84\xc9\xc6\x7e\xdf\xe3\xd7\xef\xd9\x72\x8a\x9e\x28\x9c\x12\x51\xe9\xad\x57\x20\xbd\x3e\x93\x9e\xe9\xc6\x3e\x1b\x61\x29\x99\x3a\x03\xe9\x92\xc5\x88\x64\x14\xad\x92\x24\xee\x55\x0f\x69\x40\x0b\x5d\x52\x11\x9c\x02\x93\x28\xf4\xb3\x3b\x38\x80\x2d\x13\xf1\x89\xda\x68\x05\x52\x69\xdb\xb9\x75\x33\x49\xe2\x56\xe6\x9c\xe6\xf8\x3e\x7b\x09\x43\x4d\xc5\x4c\xbd\xef\x71\x34\xc9\xe1\x96\x76\x15\xc4\x8e\x5b\xb9\xe9\x6e\xe1\x44\xd0\x7e\x35\xb5\x0e\x33\x82\x9c\xf5\x0a\xef\xb0\x4e\xd4\x6e\x65\xb6\x8d\xb2\x21\x26\x02\x4c\x20\x4a\xd7\x0e\x41\xf1\x6f\x34\xd8\xe8\x60\xf6\xaa\x1c\xa0\xf4\xf7\x72\x37\x1a\xd7\x42\x9a\x35\xe6\x3f\xc4\x71\xa6\x84\x52\xfb\xdb\x07\x5b\x0a\x5a\xc5\xf0\x1b\xc5\x73\x5a\x53\x6b\x93\xa4\xf8\xf9\x25\x8d\x49\x44\xb9\x57\xf0\x70\x24\xa3\x15\xf3\x37\x09\xcc\x2f\x7d\x12\xc9\xba\xf6\xd3\x9e\x4b\xb2\xa0\xd6\x34\x4f\x96\xfa\x49\xcf\xe2\xc1\x0a\x99\xbc\x4b\xae\x0a\x53\xbd\xf6\x48\x5b\xaf\x76\x78\xa4\x85\x55\xaf\x33\xeb\x92\x56\x0f\xe0\x5f\x71\x46\xc3\xee\xe2\xde\x87\x1c\x14\x80\x93\x9d\xca\x90\xe6\x36\xb1\x4c\x6d\x5b\x85\x4b\x75\x72\x2c\xd3\x9b\x54\x98\xde\xe8\x0e\x07\x87\x66\x07\xe0\x9f\x7d\x8f\xe9\x76\x99\x93\x07\x7b\x38\x34\xdb\xd7\xcb\xdd\xd6\xc1\x99\x12\xe6\x9a\xec\x56\xf1\x96\xb8\xa8\x32\x5a\x29\xf0\x5e\xf2\xe1\xd3\x1a\x23\xb5\x27\x7a\xba\x09\x34\xc9\xc9\x47\xee\x06\xdb\x2e\x10\x0f\x6f\x4e\xb7\xd4\xb3\x41\x85\x54\x93\xc6\x35\x62\xfd\x70\x58\x80\x68\x9a\xe5\xa4\xcd\x69\xaa\x0e\xee\xac\xb8\x4a\x62\xe8\xb2\x3e\x54\x9f\x6a\x42\x6a\xdd\x36\x58\xa7\x2e\xb2\x71\xb9\xa4\x92\x61\x8e\x05\xbc\x35\x56\x1e\xc0\x94\xaa\x43\x00\x6f\xf2\xd7\x0e\xc8\x68\xe0\x97\xef\xd7\x8e\xc5\xe4\xf6\xd6\x85\xf0\x4e\x1b\x83\x36\xfd\xbe\xa1\x71\xfa\xd5\x7b\xc2\xe1\xb5\x55\x83\x16\xc0\x74\x23\x4d\xa2\xa9\xd0\xa5\x29\xe1\x39\xd9\x54\x22\xb1\xd7\xa5\xea\xd4\xfc\x2e\xc4\xbf\x6f\x61\x7b\xab\x7c\x18\x6b\xc6\xc5\x29\x5e\xb5\x64\x8a\xfd\x8a\x68\x62\xc7\x44\x29\x4d\x1a\x18\xbf\x78\xf6\xb5\xd3\x11\xb7\xb7\x7b\x51\xa7\x93\x8e\x74\x60\x9e\xed\x61\x7c\xb4\x9c\x59\x75\xcf\xca\x1a\xed\x4f\x72\x3c\xf1\x75\x10\x1d\x9c\x0f\x3f\x35\xb5\x51\x45\xb5\x86\x09\xe4\x83\xa4\x97\xee\x27\x23\xa0\x9c\x37\xf5\x54\x64\xd6\xa6\xa3\xb8\xdb\x16\x32\xd2\x11\x85\xed\x55\x1a\x08\xd1\x53\x6a\x64\x52\x6a\x76\x29\x28\x0d\x4b\xdd\x4c\xa4\xdf\x10\x96\xeb\x4c\xf1\x0a\x95\x60\xe2\x51\xa7\xa3\x63\xbb\x3b\xa0\xf9\x51\x68\x50\xa5\xee\x5e\xb2\x0f\x2d\x96\x14\x61\x2c\x29\x76\x3a\x46\x87\x93\x8d\xca\xd8\xe4\x11\x56\x48\xa0\x50\xf3\x24\x5b\x16\x16\x73\x0c\xb6\xed\x2a\x0a\x72\x5f\xef\x34\x1e\x55\x39\xb1\x15\x9b\xf3\x9e\x1e\x07\x6a\x6a\x5f\x48\x6d\x57\x6a\x96\xec\xae\x98\x47\x76\x3e\xa2\xa2\x4e\x62\xe3\xc1\x24\x27\x49\x25\xaf\x36\xac\xbf\xcd\xf4\x78\x66\x2d\x5f\x2d\xc5\xa6\xb2\x5d\xb1\x7a\x2e\x49\x52\xe2\x9a\x1f\x65\x2d\xd2\x13\x1a\x55\xe2\x56\x28\x72\xff\xb5\x1a\xb0\x06\x0f\xaf\x22\x11\x26\x57\xde\x42\x47\xe8\x85\x93\x6f\x42\x65\x2b\x41\x0f\xb8\xef\xcf\xba\x45\x7b\x7b\xd9\x3e\x08\xc3\x4a\x5d\xb4\x1c\x8d\x27\xbe\x04\x36\xa1\x1e\x2d\x53\x27\xd4\xde\x2c\x00\x26\x61\x9d\xf1\x4f\xfa\x9d\x83\xcf\x76\x0b\x67\x10\x73\xd9\xc2\x14\xd8\x05\x70\xfa\x33\xb1\x83\x4f\x04\x5c\x3d\x21\xeb\xad\x9b\xd1\x66\x3c\x88\xa0\x6a\xdf\xfa\x67\xad\x67\x9d\xd4\xe8\x17\x11\x54\xf6\x8a\x08\x6a\xe9\x13\x4d\x2c\xca\x5b\xb4\x49\x45\x6b\x0f\xe2\x3a\x67\x98\x2c\x6b\x9b\x6a\xa1\x36\x55\x48\x97\x6a\x53\xcd\xe8\x52\xb1\xf7\x53\xd8\xb3\x06\xd6\x48\x21\x15\x72\x53\xab\x33\x55\x75\x4e\xe8\x8d\xaa\x73\x49\x6f\x94\x40\xb5\x53\x92\xda\x0b\x8b\x47\x49\xaf\x5c\x4c\xcc\x42\x26\x62\x95\xac\x34\xae\xa8\xbd\x3c\xf2\x81\xbb\xa6\x84\x92\xb3\xe0\xf1\x08\xad\xa5\xc2\xe5\xd3\xde\xfd\x4e\x67\xe6\x72\x9c\x03\xba\x33\x53\xbe\xb0\xc1\xd8\x7a\x03\x88\x59\x08\xcf\x6f\x7f\x9c\x81\xdc\xb8\xc7\xeb\x21\x0c\x8b\x00\x6d\x27\x05\x02\xd7\xde\x3e\x8c\x52\xca\x47\xd2\x57\x88\x58\x12\x36\x21\x63\x3e\xc1\xc3\x4b\x57\x16\x6f\xb3\x1d\xf7\x31\xce\xc9\x95\x1e\xf3\xef\xdc\x9d\x91\x1f\x25\x76\x55\xf9\x70\x57\x44\x35\x3b\xfd\x32\xb0\xda\x9c\xe7\x13\xfc\x4d\x67\x31\x34\xea\xef\x28\x6c\x86\xdd\xda\xae\x7d\xcd\xc9\xa6\xfe\x14\x8b\x7f\x41\x1a\x01\xbb\x48\x33\xd2\xb8\x2f\xe9\xf3\x62\x3a\xba\x37\x46\x9f\x43\x18\x75\x2f\x0a\x9b\x51\xdd\x18\xd9\x54\x06\xe1\x33\x8c\x49\x25\x06\x29\x08\x5a\x95\xc6\x1a\x30\xf6\xa2\x10\xde\x0c\xd6\x40\xde\x6e\xb9\x0e\xbd\xe2\x09\x3a\x45\xe0\x24\xd0\xb7\x7a\x2c\x57\x41\x9a\xe7\xc7\x4f\xc9\xf6\xf9\xf1\x23\x52\x89\x8c\xee\x33\x52\x89\x9b\xee\x07\xa3\x13\x7f\x3c\xa9\xa2\xca\xac\x9d\x17\x6c\x86\x69\x5d\x4e\x7b\x87\x68\xa7\xd2\xfb\x2a\x27\xe8\x45\x18\x16\x01\x58\x35\xb1\xf8\xfd\x3e\x73\x50\xcb\xd9\xed\x3f\x20\xfa\x5d\x04\x87\x76\x9d\xf1\x1e\x68\x28\x7a\xda\x9c\xbf\x37\xc0\xe5\x75\x7c\xa8\x1a\xa9\xaa\x01\xcd\x54\xd5\x35\xcd\x54\xd5\x05\x54\xe5\x80\x46\x7a\xfa\x39\xa6\xe2\xf0\xab\x06\x5a\x10\xc6\x4a\x23\x8c\x50\x23\x8c\xeb\xa2\xef\xb0\x8e\xc9\xf6\xfa\x4d\xd4\x71\xbd\x85\x3a\xc8\x45\x51\xdb\x3c\x2a\xd3\x4b\x0b\xac\xa7\xba\xbf\xaa\x35\x70\xa1\x1a\x38\xa5\x57\xaa\x81\x33\x7a\xa5\x1a\x78\xb5\x8b\x29\x01\x66\x7f\xdf\x46\x62\xdd\xd7\x8f\xe5\x29\xae\xe4\x3d\x7d\x55\x72\x25\x1f\xe9\x2b\xc3\x95\x7c\xa2\xae\xf5\x76\xc0\xde\x5c\x5f\x40\x34\xcf\xf5\x7c\xd8\xd5\x07\xc0\x6b\x04\xff\x52\x09\xe5\x55\x07\xe7\xf4\x43\xd9\xc1\x57\xfa\xa1\x6e\x7a\xda\x89\x2c\xa3\x99\x7b\x5e\xbb\x6d\xc4\xa9\xfe\x6d\x1f\x7a\xeb\x4f\x86\xa9\x8e\xd1\xcb\xa6\x99\xfb\xa9\xc7\x31\xe0\x41\x5d\x68\xd2\xb6\x67\x1f\x42\xd9\xef\xbe\xef\x7f\x48\x0c\x37\xe9\xa3\x48\xc4\x91\xe0\xbd\x69\x9c\x04\x17\x26\x02\x40\x6d\xbf\x54\xc2\x73\x14\x81\xfc\xdd\x8d\x51\xa1\x02\x5b\x14\xba\xdc\x0b\x74\x88\x04\xdc\x0c\x99\xb0\xca\x09\xd2\xc4\xcc\xbc\x1c\x69\x77\xe1\xb7\xc7\x28\x38\xe8\xdf\x39\xe8\xfa\x31\xb9\x7f\xd4\xeb\x3b\x46\x1d\xe4\x04\x7d\xc9\xb8\x03\xed\x69\x2f\x9a\xff\x95\xf1\xd6\x8e\xd6\xfd\x43\xbe\xbc\x63\xc8\x27\x66\xc8\x75\xbe\xe3\x7f\x65\xd4\xcd\x23\x7d\xff\xc0\xcf\xee\x18\xf8\xa9\x19\xb8\xc1\xee\x4e\xc1\x1e\x61\xe2\x8a\xe7\x87\xfd\xdb\xdb\xaf\xad\x77\xfe\xff\xda\xe3\x83\x0e\xc2\xe4\x6b\xa7\x83\xbe\x08\x7e\xbd\x82\x47\x81\xcb\xa7\x8b\xb4\xd8\xe2\x5c\x2d\xb8\x28\x64\x14\x27\xe3\xe9\x25\x4f\xed\x93\x74\x16\x69\x7c\x2d\x4c\x75\x44\x3c\xa7\x87\xfd\x4e\xc7\x3c\xc8\xd3\x5e\xef\x35\x97\xba\xaf\xaa\xc1\xc6\x31\x81\x83\xb5\xef\x51\x18\xcd\x66\x3c\xe5\x22\xe0\xce\x94\xcb\x2b\xce\x85\x73\x93\xac\x53\x67\x9a\x26\x57\x19\x4f\x1d\x26\x42\x47\x2e\xb8\x69\xd7\x73\xce\x16\x4c\x24\x99\x93\xf2\x38\xe2\x99\x93\x08\x87\x05\xc1\x3a\x65\x92\xeb\xe6\xa0\x38\xb4\x9b\x46\x33\xe9\x2c\xa3\xf9\x42\x3a\x01\x5b\x67\xdc\x59\x97\x53\xaf\x3e\xea\x9a\x79\x0a\xd9\x7d\xfc\xdf\x01\x79\x13\x3a\x86\x83\x76\xe2\x28\x93\xbe\xf3\xe0\xc5\xd0\xd5\x1c\x01\x84\xdf\x41\xe4\x63\xb9\x0c\x2d\x14\x5e\x92\x8d\xe6\x93\xfd\xdd\xac\x68\x4d\xa8\xaa\xb3\x23\x41\x1b\xef\x71\xba\xcd\xa3\x9c\x18\x76\x24\xf3\xdf\x6b\xe9\xb4\x85\xa1\xf7\x57\x15\xcf\xbd\xd7\x8a\x6d\x00\x7a\x06\x2e\x36\xa0\x57\x78\x79\x03\x6a\xad\x0f\xda\x13\x32\x2b\xdd\xd4\x5e\xde\xbc\x2f\x98\x1d\x5f\x92\x25\x5f\x26\xe9\xcd\x5b\xf1\xf2\x46\xf2\xac\x5a\x89\xd5\x2b\xbd\x2b\x9a\xff\xc4\xa2\x54\xdb\x1f\xbf\xf5\x7e\x58\x45\x46\x3c\x7d\xfd\xd2\x31\x8e\x30\xed\x7e\x9f\x87\x8d\x77\x67\x20\xc8\xa0\x76\xad\x7b\xc5\xd2\x30\x12\x2c\x8e\xe4\x0d\xb4\xa1\x9a\x18\x5b\x17\xb8\xb3\x64\xe5\x0c\xfa\xe6\xe9\x4c\x58\x57\xe7\x2a\x92\x0b\xf3\x5e\x69\xa0\x26\x83\xcc\xf3\x44\x3c\x27\x8d\x5a\x7a\xc6\xba\x94\x33\xbd\xa9\x6d\x0f\x5b\x4b\x6e\xd5\xda\xea\x6b\x11\xcd\x17\x8e\x06\xac\xb3\x56\xbb\x09\x91\xb5\x88\xa4\x8f\x00\xc8\xb6\x21\x76\x6f\xf7\xba\x61\x3d\xf2\x15\x8b\xd2\xa2\xaa\x28\x9c\x5e\x74\x03\x5c\xb7\x2f\x29\x7a\x55\x9d\xe0\xae\xab\x43\xdb\xaf\xfa\xf4\x0e\x8a\xbb\x74\x77\x5e\x35\xfa\x9b\x2f\xf6\xff\x1d\xb7\x3e\xd4\x0c\xee\xb9\xe8\xb1\x33\x1c\x5c\xc5\xa0\x60\xae\x56\x6f\x8c\xeb\xb0\xf1\x24\xde\x01\xc0\x87\xba\x16\xb6\x47\x3a\x2d\xb2\xa5\xbd\xbf\x36\x7c\xdd\xd0\xca\xa9\xf3\xa1\x8f\x47\x43\x2b\xf7\x56\xd2\x4b\xf7\xb5\xd1\xca\xbd\xfb\x33\x8e\xc9\xc6\x43\x4b\x66\xe1\xf4\xaf\x3b\x27\xbf\xdd\x52\xa9\xb5\x5d\x76\x2b\xfc\x95\xb7\x34\x67\x25\x1a\xd8\xd2\x9e\x91\x5f\xc0\x7f\xe2\xf0\x07\x4c\x5e\xe8\xaf\x27\x56\xa0\x7f\x23\xa9\x79\x98\x72\xac\xd7\xcb\x3c\xc6\x43\xd6\x69\xe4\xa3\x7d\xc1\xaf\xf6\xcd\x6b\x2c\x13\x2d\x57\xfd\xb1\xa5\xbe\x94\x40\xed\x8a\x00\xc6\xff\xdb\x37\xba\x7e\x91\xad\xd2\x61\xc8\xd2\x0b\xf0\xc0\xb5\xa4\x30\xbd\x80\xeb\xa2\x4c\x84\x3e\x5a\x86\x48\x87\x7b\xf5\x91\x4c\x56\xad\x04\xf2\x05\x34\xbb\x15\x77\xb6\xfd\x41\x94\xc6\x08\x04\xbb\x9c\xb2\xb4\x37\x4d\x99\x08\x21\xfa\x42\x7d\xb7\x94\x40\x84\xc7\x97\x34\x73\xd0\x73\x10\x51\x72\x46\xdd\x22\x43\x6c\x04\x77\x77\x50\xbc\xa4\x7c\xbf\xb5\x92\xe8\x01\x68\x5b\x23\x38\x48\xfc\xbe\xce\x64\x34\xb3\xae\xf8\x3e\xca\x56\x2c\xe0\x3d\xc3\xbc\xb4\xbb\x47\x7c\xda\x0e\x25\xd1\x47\x65\xcb\x39\x79\x23\xc7\x72\xb2\x3b\x4c\xc8\x07\x1b\x5b\x52\x7a\xeb\x34\x6a\xeb\xe1\x5c\x3f\xf1\x33\xf7\x15\xfc\xea\x50\xaa\x1a\x72\xd3\x08\xe7\x44\xde\x11\xbe\xe0\xbe\x37\xaa\xb4\xc1\x7b\x21\xe5\x2a\xf3\xf7\xf7\xf5\xf6\xf4\xa2\x64\x7f\xce\xe1\xe9\xe7\x1e\x68\xba\x79\xe8\x2d\xc3\x7d\x4d\x08\xe3\xd5\x9f\x7b\x0c\x4b\x77\x54\x5b\x6b\xb3\xce\x36\x69\x07\x67\x93\x13\xf4\x4a\x41\x3a\x0a\x9c\x2f\x6f\x91\x31\x0e\x31\x77\x30\x38\xd2\xd8\xe8\xe5\xc3\x0e\xd9\x9f\x93\x42\xff\x00\xde\xeb\xee\xb6\x5b\xaa\x05\x10\x9f\x39\x5e\x47\x61\x65\x9f\x99\xcb\xaf\x67\xc9\xca\xff\xa1\xdf\xba\xad\xd6\x5e\x40\x36\x53\x96\x71\xd5\xe5\xf6\xc1\x40\xad\xf1\xea\xd6\xde\x94\x6c\x66\x69\xb2\xf4\xd1\xfe\x3d\x07\xaa\x6d\xa8\xbf\x9b\x19\xfa\x76\x3d\xea\xea\xf9\xb6\x2a\xbf\xf2\xa2\x8a\x8e\x88\xf0\x80\x3a\xff\x2a\xeb\x98\x30\x43\xf7\xd7\x91\xe5\xd0\x74\x84\x9a\xfb\xab\x24\x65\x15\x7d\xa9\xfa\xfe\x2a\x8b\xb2\x4a\xa6\xef\xac\xf4\xc2\xe2\xf6\xd2\xfd\xd5\xe7\x95\xea\x9a\xb1\xbc\xbf\xce\xbb\xb2\x8e\xa2\x87\xbd\x07\x57\xfc\x5a\xa9\x68\xcc\x1d\x8d\x4a\x8a\xaa\xab\xc3\x71\xac\x9f\xae\xfd\x22\xe9\x4f\xef\x3e\xbe\x7c\xf1\xee\xfc\xd3\x8b\xb3\x37\xe7\x9f\x3e\x9f\xfc\xf8\xf6\x7f\x86\xa8\xf2\xe3\xfc\xd3\xbb\x17\xaf\x4e\xde\x7c\x7c\xf7\xfa\xe4\x33\xda\xa3\x2d\xc5\x3b\x1d\xb4\xbf\x2b\xe7\x84\xbb\xdb\xc9\xf8\xf6\xd6\xfd\x22\x29\x32\xcf\xe7\xfe\x2c\xe9\xd9\x9b\x17\x1f\x3e\x9e\x9e\xbf\xfa\xf8\xfe\xd3\xc7\x0f\x27\x1f\xce\x86\xf0\x3e\x49\x33\xb5\xd3\x71\x7f\x96\x54\x6b\x6f\x10\x26\x99\xc7\x3c\xf3\xd4\xe4\x36\x24\x5e\xd6\x0f\xe6\x17\xb9\x75\x32\x7f\x56\x47\x33\x4c\x82\xb5\x2a\x0f\x8f\xb6\xea\xaa\x2f\x6f\xde\x86\x2e\x4a\x93\x44\x22\x45\xee\x0f\x0e\xfc\xf2\x0d\x06\x22\x09\xc3\x1b\x88\x01\x94\xa4\x32\xa3\x9b\xc2\x8f\xc7\xaf\x58\x2c\x41\x79\x7a\x5e\x64\x9d\x9f\x1f\x2c\x59\xb0\x44\xd6\x4f\xbc\x59\x10\x92\xcf\xcf\x07\xab\xd5\x4f\xbf\x23\xa2\x1d\x90\xb6\x4b\xe9\xf4\xf3\xf3\xc1\x8b\x75\xf4\xc1\xb9\xbb\x0d\x2d\xbb\x6e\xb7\xa1\xd3\xcf\xcf\xff\x9b\xbc\xb9\x78\x7c\x4f\x1b\xe0\x8d\xd3\x32\x58\x95\x7c\x7e\x3e\x38\x0d\xd3\x01\x22\x01\x8f\x5b\x86\xaa\x52\xcf\xcf\x0f\xdf\xfd\x3c\x3d\x47\xa4\x70\xc7\xd8\x2a\x66\x73\xce\xcf\x07\x1f\x8e\xe6\xd7\x5b\xe3\xa9\x35\x63\x03\x8c\x34\x0b\xe9\xf4\xf3\xf3\xc1\xcf\x3f\x5f\x4f\xef\x6e\x02\x4c\x37\xdb\x2d\x40\xf2\xf9\xf9\xc1\xcb\x3f\x5e\xdf\x33\x86\x9a\x07\x45\xdb\x50\x8a\xdc\xf3\xf3\xc1\xd3\x83\x9f\xff\x7d\x77\x73\xda\xf7\xa1\x05\x2e\x90\x7e\x7e\x7e\xf0\xaf\x97\x97\xbf\xde\xd9\x44\x9e\x93\xc3\xa7\x77\x6d\xcf\xa9\x14\x3e\xd2\x76\xd6\xf3\xa9\x14\xe7\xe7\x83\x9b\x45\x38\x57\xf5\x8e\x1f\xdf\x55\xaf\x74\x42\xb1\x66\x64\xed\x8c\x72\x5e\x66\x9c\x9f\x1f\xf0\xd3\xf8\x48\xb5\xf5\xf8\xae\x23\xa2\x90\xcd\x63\x9c\x93\xa7\xfd\x5a\x21\xbc\xd9\xab\x3e\x6d\xc2\x3d\xe0\x35\xe9\x26\x27\xe6\xd3\x5b\xb2\x0b\x4e\x8b\x32\x92\x30\x22\x48\x8a\x37\x70\xe1\x96\x6e\x0a\x5b\x54\xe2\xa5\x54\xde\xde\xf6\x49\xe2\xcd\x29\xd3\x1f\x53\x2a\xf4\x07\xa3\xfa\x71\xb7\x74\x94\xfa\x03\xf5\x3b\x0c\x69\x7d\x14\xf6\x65\x2f\x46\xfb\x43\xf6\xcc\x5a\xdd\x86\xdd\x2e\xc3\xc9\x98\x7b\xc1\x82\xa5\x2f\xa4\xcb\xf0\xa4\x4b\x65\xd9\xa5\x3e\x8c\xd1\x57\xee\xe2\x9c\x24\x5e\x16\xb0\x98\xff\xd9\x86\xbf\xbf\xa3\x61\xfb\x96\x5d\xd9\x76\xe1\x99\x9f\x78\xec\x39\x1d\x8c\x50\x3a\x9f\xba\xa8\x3b\x4e\xbc\x54\x41\x40\x4d\x7e\x62\x1f\x65\x43\xb8\x8b\x30\xf2\x55\x11\xd6\x28\xa3\x60\xd1\x28\xa7\xfa\x2b\xba\xaf\x76\x58\x38\xc0\x72\xbb\xba\xf6\xdd\x9d\x67\x7c\xc4\x7d\xf9\x9c\x8d\x98\x2f\xf3\xca\x7a\x70\xb7\x4f\xca\x77\x7a\xbc\x14\x93\x83\xe3\x63\x0c\x2b\xd4\xc8\x9a\x17\x59\xd3\x66\xd6\xb4\xc8\x62\x90\x95\x78\x8c\x0c\x30\x49\xd4\x38\x83\x38\x11\xbc\x05\x28\xd5\xbd\xe3\xea\xe9\x4e\xcd\x94\x19\xae\x4d\xd0\xc5\xe5\x4e\xe3\xd7\x32\x65\x81\xac\x6d\x36\xbd\xd1\xc4\x30\x4c\xf4\x73\x59\x7b\xd4\x55\x52\x68\x90\x81\x13\x4d\xdd\x61\xae\xd3\x41\x32\x65\x22\x5b\xb1\x54\x89\xc4\x7b\x54\x60\xfd\x94\xbe\x84\x1b\x81\x2a\xd1\xc5\xf9\xd5\x22\x8a\x79\x61\x1c\xec\x74\xf6\xb8\x27\x92\x90\x2b\x01\xc1\x05\xfa\xe3\xf6\x31\x41\x20\xfa\x17\x17\x18\xf4\xd2\xf5\x89\x63\xfe\x1f\x23\x78\x98\xcf\x15\xb4\xd6\x23\x2e\xa6\xa2\xdd\x91\x45\x65\x72\x90\x52\x4e\xcd\x4e\x0c\x1c\x08\x4a\x60\x0d\xa3\x99\x2b\xe8\x7e\x3a\x9f\xfe\xe6\xfe\x96\x7d\xaf\xdf\xdb\xdb\x0c\xc8\x61\x8e\x7f\xcb\xbe\x27\x0f\x4a\xfa\x0d\xef\xc3\x9b\xc6\x2e\xc3\xf6\x99\xbb\xd4\x2d\x16\x14\x9c\x70\x07\x7d\x4c\x2a\x29\x07\x5b\x29\x87\x90\x82\xcb\xe1\xb0\x3f\x3f\x9e\x32\xa9\xeb\x8e\xfc\xdf\x3c\xf3\x86\xe0\xe8\xef\x1d\x2b\xa9\x04\x02\x12\xe3\xa3\x49\x75\xf0\x95\xb1\x37\x87\xf0\xcf\x3b\x07\x78\x7f\x6e\xeb\x04\x0e\xbc\xe3\xe3\xef\x6b\xe3\x19\x4c\x30\xd9\x4e\x3d\x68\x4d\x3d\x9c\xec\x02\xfc\xdf\x3d\xf8\x6f\x5e\x99\xbf\x3c\xb1\x9d\xab\xf4\x9d\x3b\x66\xbd\xd9\x8b\xde\x8f\xb0\x75\x0e\x72\x7c\xdf\xef\xfb\xf7\xcd\xe3\xad\x7d\xf3\x78\x6b\xdf\x3c\x6e\x1f\x00\xde\xfd\xe3\xbe\x7e\xbb\xed\x9d\x77\xdb\x47\xd0\x2d\x87\xa1\x09\x2a\xf7\x64\x1a\x2d\xb7\x70\x9b\xc5\x43\x55\x6c\x43\x69\x32\x4a\xdd\x83\xe3\x63\x62\xff\xeb\x63\x3f\x75\x15\x7e\x1c\x27\x93\xdb\xdb\x71\x9f\xf4\x49\x7f\x82\xc7\xfd\x09\x81\x41\xc1\xba\x68\x8d\x97\xa4\x1b\xf6\xc7\x9a\xf9\xe3\xbe\xad\x3c\x21\xec\xeb\x3a\xe5\xfe\xf8\xe0\xa8\x92\x36\xe5\xd1\x1c\xd2\x8e\x09\xfc\x77\xd0\x9f\x90\x69\xcc\x82\x0b\xdf\xb4\x4e\xa6\xf1\x9a\xeb\x1f\xba\x42\x9a\x5c\x09\x7f\x3c\x78\x7c\x4c\x8e\x0e\xc8\xd1\xc1\x84\x04\x37\x4c\xd4\xfa\x09\x59\x7a\x51\xd6\x1a\x1c\x3e\xd5\x49\xb6\xdc\xe0\xf0\x69\x99\x38\x4f\xf9\x8d\x6a\xed\x29\x31\xff\x15\xc9\x5c\x17\xee\xc3\x20\x54\xda\xc5\x82\x5d\x44\xfe\x78\xf0\xe4\x29\x19\x3c\x39\x24\x83\xfe\x0f\x3a\x7d\xc9\xe6\x5c\x48\xe6\x8f\x55\xc3\x95\xfe\x92\x38\xba\xe4\xa6\xa1\x27\xc7\xaa\x3c\x39\x32\x55\x12\xfd\x74\xde\x58\x0d\x79\x70\x54\xf4\x90\xa4\xc1\x22\x0a\xfd\xf1\xe0\xf8\x90\x1c\xf7\xc9\x41\xff\x48\xa7\x2b\xf6\xcc\xb4\x6e\x4a\x66\x2c\x5e\x26\xc2\x1f\x1f\x1c\x1e\x92\xc1\x71\x9f\x0c\x0e\x0e\x74\xc6\x65\x94\xc4\x5c\xfa\xe3\xc1\xd1\x13\x05\xb1\xc1\x60\x42\x66\xeb\x60\x91\x45\x4c\xf7\x66\xa0\x38\x4f\xe2\x50\x27\x1c\x0c\x8e\x55\xa3\xe5\x84\x0f\x9e\xa8\xdf\x91\x08\xa3\x79\xe2\x8f\x7f\x38\x86\x29\xf5\x27\xc4\x4c\x1f\x56\xef\xb0\xaf\x86\x3d\x21\x10\xd4\x58\x83\x7a\xf0\xc3\x21\x39\x18\x3c\x56\x79\x26\x5d\xc3\xfb\xe0\xe0\xa8\x5c\x19\x48\x37\x5d\x0d\x8e\x8e\xc8\xc1\xe1\x13\x32\x38\x3a\x2a\x33\x6e\xfc\xf1\xc1\x60\x40\xcc\x7f\x26\x7d\x15\x89\x0b\x03\xab\x27\x07\x64\xf0\xf4\xd0\xa4\xdf\xf0\x38\x4e\xae\xcc\x34\xd4\x7f\x07\xd0\xd2\x92\xdb\xdd\xd0\x9f\x90\x62\x71\x2a\x93\x5f\xb2\x34\x51\xc0\x83\xa9\xaa\x42\x82\x5d\xde\x98\xcd\x72\xf0\x64\x42\x60\xe1\x74\xb6\x81\x46\x6d\xbd\x1e\x43\xc3\x95\x41\x3d\x3d\x20\x07\xfd\xc3\x09\x59\xad\xd3\x55\xcc\x6d\xbb\xd0\x54\xb1\x1c\x65\x12\x2c\xa6\x1e\x4d\x7f\x42\xb2\x28\xbe\xe4\xa9\x3f\x56\x8d\x98\xff\x26\xe4\x6a\x11\x49\x5e\x99\x97\x1a\x74\x73\xb2\xfd\x49\x9e\x5b\x4d\xd9\xef\xe0\x4a\x85\x49\x95\xd1\xd6\xae\x86\x46\x39\x0e\x37\x2b\xe5\xcd\x8a\x7b\x0b\x96\x7d\xbc\x12\x9f\xd2\x64\xc5\x53\x79\x53\xde\x79\x62\x15\x5e\x88\xb2\xe2\x79\x15\x17\x79\xa8\x2b\xd5\x09\x1f\x16\xcf\x10\x2b\xbe\xc4\x15\xb4\x90\xa8\x1b\xd6\x85\x80\x89\x4b\x96\x21\x8c\xbd\x42\x2f\x4a\x25\x81\xa7\x3a\x15\x53\xb5\xd1\x31\x38\xa2\x44\xf8\x28\x96\x29\x22\xab\x24\x8b\xf4\x4f\x36\x85\x87\x11\x39\x22\x31\x9f\x81\x77\x75\xb2\xf2\xfb\x39\xf6\xd8\x6a\xc5\x45\x78\x96\xb8\x0c\x93\x3d\xa1\x58\x28\xd0\xd1\x5e\x4b\x8c\x15\xd3\xb6\x67\xc0\xf0\xd3\xf9\xe5\x32\x7e\x05\xdd\xbf\xd7\xb7\xb3\xb1\x5c\xa4\xc9\x95\x53\xfa\xd2\x22\x9d\xed\x44\x99\x23\x12\xe9\xb0\x4b\x16\xc5\x4a\xd0\xf5\x9c\xb7\x33\xe7\x26\x59\x3f\x4a\xb9\xb3\xce\x22\x31\x77\xde\x9e\x68\x5b\x1a\x73\x66\x2c\x8e\x7b\x53\x16\x5c\x38\xd9\x3a\x58\x38\x2c\x73\x4e\xae\xf5\x24\x89\x23\x17\x5c\xa8\x7f\x52\xfe\x28\x73\x78\xa4\xbe\x1c\xe6\x2c\xa3\x4c\xb2\x0b\xee\x44\xc6\xe4\x1d\x24\x22\x84\x39\xb2\xd8\x89\x44\x10\xaf\x43\x4e\x9c\x24\x05\xf3\xf7\x8a\xcd\xb9\xb3\x60\x6a\x3c\xce\xeb\x8f\xaf\xce\x7e\xfd\x74\x02\xb6\xee\x28\x73\xb4\xce\x43\x0d\x26\x12\xce\x7f\xd6\x51\x7a\x91\x39\xef\x93\x90\x7b\x08\x0f\x05\xdd\x39\x69\x2f\x12\x91\xd5\x71\x28\x0e\x11\x5e\xe3\xe6\xfa\x37\x15\x80\x9d\x53\xfd\x36\x7c\xa0\xa1\x48\xab\x20\x75\xd1\x41\x68\xf4\x35\x89\xed\x23\xe4\x97\x51\xc0\x3f\x45\xd7\x3c\xfe\xcc\x64\x94\xdc\xde\x0e\x48\x4c\x53\xef\x8a\x4f\x2f\x22\xf9\x52\xbf\x82\x7e\x2a\x93\xb4\x56\x26\xf5\x96\xc9\xd7\x3b\x32\xb3\xdd\x79\xc9\xee\xac\xe9\x8e\x9c\xc1\x50\xbf\x3a\x5e\x24\xd1\x64\x3f\x26\x90\x96\xf2\x4c\x09\x02\xcc\x83\x08\x0b\x2e\x26\xcc\x5b\x40\xcc\x32\x17\x63\x5d\x42\x4d\xfc\x95\x55\xe3\x50\x6d\x1b\xb3\xe9\x4a\x54\x85\x1f\xe7\x50\x8a\x05\x0b\x5e\x4f\x3a\x8d\xbe\x72\x9d\x6c\xc0\x35\x8b\x13\x79\xf6\xa0\x8c\xdb\xdb\x4d\x5e\xbe\x05\xad\xe4\x11\x41\x52\x92\xe8\xd3\x1b\xd3\xf1\x84\x44\x54\xfb\x29\x64\xfe\x18\x7d\xc7\xc3\xe0\xe0\xa8\x8f\x08\xfa\x8e\xcd\xc2\x27\xb3\x27\xea\x2b\x98\x1e\x4d\x8f\xa6\xea\xeb\x28\x64\x3f\x1c\x85\xea\xeb\xe9\xd1\x51\x9f\x87\x68\x42\x62\x3e\xe7\x22\xf4\xc1\x99\xdb\xdf\xeb\x13\x91\xbc\x4a\xe2\xf5\x52\x64\xfe\x40\x2b\x5a\x7e\x04\x93\x17\x78\x63\x83\xde\x5b\xa5\xbd\x4c\xae\x5f\x82\x35\xd5\xc6\x27\x0d\x82\x00\x91\x52\x01\x06\x25\xcb\x53\x2b\xb8\x0d\xcc\xe8\x1f\x93\x66\x70\x53\x28\x5b\x26\x7e\x5c\xb1\x20\x92\x37\xbe\xf7\xe4\x98\x64\x49\x2a\x79\x08\x25\x72\x72\xcd\xae\xa3\xcc\x8c\xb3\xd1\xfe\x34\x91\x32\x59\x22\xb2\x4c\x42\xae\xf3\x66\x89\x90\xe6\x7e\x75\xd9\x89\x8c\x82\x8b\x4a\x9f\xc0\xc7\xcc\x92\x74\xa9\x7f\x46\xe2\x92\xa7\x19\x3f\xab\xa7\x2e\x23\x61\x3e\xd8\xb5\xfe\x60\x6b\x99\x80\x90\xff\x5e\xcf\xa8\x68\x3a\x2b\x3f\xdb\x60\xa6\x2f\xd6\x96\xbf\xcd\x6b\x21\x90\x90\x72\x70\x71\x39\x5d\xb1\x80\x97\xad\xbc\x03\xe9\xd0\xf4\x1a\x47\x73\x71\xa6\x7a\xf9\x25\x92\x8b\x17\x0a\x14\x45\xb9\xd7\x3c\x88\x96\x2c\xae\xa4\x40\x50\x4c\x3b\xfe\xb3\x6a\x42\x4e\x6e\x34\x1c\x9b\xd3\xf0\xfa\x07\x15\x88\xea\xdb\xbe\x0a\xe6\x3c\xf3\xc7\x13\x55\x49\x7f\x68\xfb\xbf\xbf\x01\x6d\x9d\x5d\x8e\xbd\x01\x49\x59\x18\xad\x33\xff\x10\x5e\xbc\xd1\x53\x3d\x20\xb3\x28\x8e\xd5\x9e\x52\x7f\xed\x4e\x99\xc1\xff\x21\x92\xdd\x2c\xa7\x49\xec\xa3\x20\x4a\x83\x98\xa3\x1c\x2a\x66\xfa\x21\x95\x7a\xfd\x41\xa5\x3e\xcc\x29\x93\x7c\x95\xf9\x7b\x83\x9c\x4c\x59\x5a\x19\x43\xb5\xea\x94\xa5\xfa\x73\xd0\x32\x8a\x12\xa2\x66\xa6\x64\x91\xa4\xd1\x57\xb5\x7d\xa1\xbf\xaf\x3c\x4d\xc0\x34\x97\x2d\x58\x98\x5c\x01\xf0\x0e\xc9\x22\x9a\x2f\x80\xa9\x28\x1b\xc9\xc9\x3c\x8d\x2a\x87\x87\x4d\x93\x4b\xfe\x9a\x49\xa6\x5a\x31\x16\xd3\xef\x8e\x8f\xd4\xff\xd0\x8e\x8d\x5f\x39\x46\x6d\x9b\xd4\x1c\x1b\x13\xb0\xed\xbd\x3d\x44\x70\x25\xf4\x54\x13\x49\xb3\x91\xfa\x44\x2d\xac\x29\xf1\xc4\x34\x6c\xc1\xb1\x8c\x84\x3e\xb0\xd5\x4d\xbb\x64\x10\xf2\x2a\xab\xff\x2a\x16\xea\x48\xfd\x0f\x15\xe9\xef\x2a\xd0\x0d\xe2\x28\xb8\x00\xa5\xf0\xde\x40\xdf\xc7\xb4\x3f\xd4\xb6\x7a\x63\x01\xa5\x40\xb2\x4c\xd6\x19\xd7\x6f\x07\x7e\xd6\x7b\x64\xd0\xcf\x09\x3c\x29\xca\x34\x8d\xdf\xa4\x3c\x4c\xd9\xd5\xc7\x4b\x9e\xc6\xec\xe6\xad\xca\xb9\x64\xb1\x3f\xe0\x87\xfb\x8f\xfb\x39\x59\x24\xc9\x05\x04\xaa\x23\x99\x46\xbb\x81\xfe\xb3\xd6\x7f\x16\xfa\xcf\x52\xff\x59\x29\x84\x18\xaa\x7f\xe6\x74\x63\x58\x84\xd4\x80\x07\x58\x05\xa2\x71\x85\xdf\xcf\xc9\x8c\xf6\xc9\x35\xed\x93\x29\xdd\xac\xd2\x24\xe0\x59\x66\x9c\xca\xc1\x99\x5a\xa7\x7c\x66\x57\xb0\x9c\x65\x8a\xfa\x69\x36\x7f\x99\xf8\x71\x36\xcb\x14\x0f\x57\xa9\x07\xcc\xe0\x84\xa8\x99\xbd\x2c\xdf\x15\x35\x29\x3a\x24\x97\xfd\xa5\xfe\x4e\x23\x11\x9e\xa8\x45\x2d\x52\x0d\x3c\xe0\xd0\x2d\xd6\x32\x04\x99\x66\x92\x93\x1b\x20\xcc\x25\x5b\x76\xa2\x75\x8c\x92\x8e\x6f\x26\xe5\x3b\xf2\xc3\x3b\x74\x8e\x10\x53\x53\xbf\x44\xac\x9a\x22\x12\x97\x04\xe6\xd2\x95\x78\x13\x57\xd4\x5f\x9a\xd0\x30\x3a\x9e\x40\x93\xea\x87\xa0\xfd\xa1\x78\x26\xcb\x26\x85\x2e\x04\x21\x6a\xae\x25\x17\xa1\xbb\xd7\x27\x9b\x9c\x44\x9e\x46\x17\x78\xa8\x55\xaf\x72\x2c\x26\xe0\x66\x31\x72\x53\xf8\x5b\xa6\x90\x90\xc7\x5c\x72\xa7\x4c\xa8\xb6\x95\x12\x95\x8e\x49\x91\x4b\x75\x7d\xec\x57\xda\x21\x4c\xdf\xa8\x4b\x2b\x21\x0b\x5d\x59\x61\x79\x35\xef\x2a\x09\xa3\xb1\xbd\xb8\x2c\x68\x6f\x00\xf3\x92\xb4\x3f\x94\xcf\xe2\x72\x4e\x66\xe2\x9c\xc6\x63\x39\xd1\xda\x31\x33\x0b\xde\xe9\xb8\xac\xd7\x23\x48\xac\x97\x53\x9e\x22\x4a\x15\xdb\x9c\xcc\x1c\xde\xe9\xf0\xe7\x5a\x25\xc7\x31\xce\xd9\x33\xe0\x83\x19\x15\xdd\x81\x16\xad\x53\x92\xc0\x83\x76\x34\xd2\x0d\x66\x24\xa0\xc5\x1d\xea\x35\xed\x57\x46\xc2\x86\xb2\xdb\xc5\xa5\x62\x4e\x2b\xf3\xb2\xb1\xfc\x67\x30\xb9\xbd\x45\xdf\x3d\x7e\xfc\x18\x61\x22\xff\x19\x50\xda\xef\x74\x64\xa7\xe3\xae\xe9\xfa\x39\xed\x8f\xd6\xcf\xbc\xe3\x51\x6f\xdd\xf3\x0e\xfc\xbe\xdf\x5b\x63\x92\x8c\xe5\x84\xa6\x5a\x2f\xed\xa2\x74\x3e\x45\x64\xd0\x5d\x9b\xb0\x81\x64\x59\xeb\xb5\x3e\xff\x82\x9d\x77\x17\x00\x05\xac\xc7\x32\x72\x17\x46\x43\x9f\x8c\x97\x93\x42\x2f\xed\x62\xd2\xed\x2e\xb1\xbf\x05\x16\x53\xba\xd3\xa9\xd4\x33\x5f\xd5\xda\x98\xe8\xce\x16\x1e\x50\x02\xb8\xe4\xa8\x57\x6c\x4e\x66\x74\x4f\x0f\x13\xf8\xdc\x05\x8e\x66\xee\x62\x3c\x9f\x74\x3a\xea\x5f\x53\x72\x46\xf7\x06\x43\xd0\xb5\xe6\x33\xe8\xab\x6c\x86\xee\xf5\x71\x5e\x6f\x5d\xa1\xf8\x4a\x29\xf5\x93\xee\xed\xd9\x9f\x8a\x54\x60\xb2\xf0\x80\xe7\xa0\x67\xee\x8a\x5c\xb8\x0b\x82\xae\x11\x56\xa9\x37\x26\x35\xd4\xa9\x10\x80\x27\x77\x6b\x1b\x0d\x44\x2b\x6d\xa6\x20\x09\x89\x48\x46\x02\xb2\x26\x0b\xb2\x24\x2b\x12\xd2\x0f\x00\x21\xef\xd3\xc7\xd3\xb7\x67\x6f\x7f\x3e\x39\x7f\xfb\xe1\xc7\xb7\x1f\xde\x9e\xfd\x4a\xe6\x36\xeb\xc3\xc9\x4f\x2f\xea\x59\x33\x9b\xf5\xfe\xc5\xff\x9c\xff\xfc\xe2\xdd\x97\x93\x12\x05\x5c\x5b\x65\xbc\x7c\xa6\x1f\xf7\x58\x46\xa2\xd3\x91\x7b\xb4\xa7\x20\x51\x24\x51\x89\x09\x7b\x6e\x7e\xb2\xeb\x4e\x87\xed\xd1\x4a\x01\x76\x4d\x19\xce\x15\x94\xb9\xc7\x59\xb0\x70\xaf\x5c\x4c\xdc\xba\x25\x43\x16\x6d\x85\x44\x16\xd5\xe6\x44\x7a\xeb\x8c\x87\x14\x62\x20\x91\x96\xbd\x94\xc0\x06\x22\x09\x54\xd1\xe8\x93\x6e\x0a\x34\x9a\x93\x13\x77\xea\xd5\x51\x2e\x19\x27\xa6\x78\xad\xd6\x04\xdf\xb5\x5d\x4d\x37\x4b\x6a\x6a\xae\x68\xb5\xae\x79\x22\x9f\xec\xad\xa0\x30\xd0\x8a\x95\x09\xa0\x7a\x0d\xbc\x2f\x40\x58\x7d\xa5\xfc\x8f\x75\x94\xda\xc8\x12\xb6\xd0\xcd\x5d\x85\x12\xfd\xa0\xfc\xed\x6d\xe2\x29\xb6\x04\x36\x9e\xfa\x51\x6e\xc3\x4e\x27\xa9\xee\x2f\x83\x5f\xf6\xf6\xdc\x4a\x0d\x55\x06\x7e\xa8\x1d\xb9\xab\xba\xca\xc3\xc3\x7b\x47\x35\xb0\xee\xe7\x3a\x68\x62\xbf\x64\x5d\xc1\x65\xc0\x74\x54\xb2\x3e\x9d\x8e\x6b\xb0\xf0\x6a\xbc\x32\xa0\xed\x0d\x26\xde\x0d\xa9\xff\xbe\x86\xf3\xd4\x02\x59\xba\xca\x0d\xce\xd8\xab\x03\x5e\xff\x89\xbe\x72\xac\x64\x84\x48\xac\xf9\xb0\x3d\x9f\xda\x7e\x48\xb6\xa3\x05\xb8\x98\xbc\x95\x31\xd4\xb0\x6c\x07\x17\xf0\x8b\xb0\x6d\x12\x7d\xa2\xf5\x66\x4d\xf4\x41\x36\x3b\xb7\x4f\x18\x15\x40\x2b\x97\x15\x5a\x49\x44\x97\x66\x78\xb3\xa0\xcb\x31\x9b\x0c\xb5\xc2\xc4\x20\x92\x61\x34\x73\xf7\x24\x86\x60\xc5\xb4\x3f\x4c\x9f\x65\xc3\x6e\x37\xc5\x01\x5d\x8c\xd3\x09\x59\xd3\x15\xfc\x51\x88\xd9\xd3\x8b\xd3\xe9\x68\xc8\x04\x9d\x8e\x1b\xd0\x6e\x40\xa2\xec\x03\xfb\xe0\x06\x78\xa4\x39\x1a\x3f\xa0\x74\xb0\xdf\x1f\x05\x74\xa6\x3e\x7b\x83\xfd\x3e\x94\xec\xcd\x0a\xdc\x18\x40\x73\x76\x85\x3b\x1d\x57\xaa\xa5\x20\xba\xdd\xb5\x57\x5d\x6e\xa8\x5a\x4f\xc2\x18\x93\x68\x2c\xba\xe9\x84\x06\x6a\xf4\x6d\x83\xd7\xf9\xa4\x1c\xa9\x99\xc8\xde\x60\x8f\xd2\xb5\x57\xec\x20\x18\xc8\x75\xa7\x73\x6d\x61\x4a\x02\x12\x60\xb2\xf6\x6e\x74\xda\x4d\x91\x56\x76\xaa\x1a\x85\x07\x89\x3a\x1d\xf1\x5c\xcd\x6d\x4f\xde\xde\xea\x9e\xa2\xb1\xe8\x65\x13\xac\x4d\xa5\xd5\x11\xa9\xaa\x99\xaa\xac\xdb\x18\xaa\x3f\x83\x89\x2e\xdf\x1d\x4c\x6e\x6f\xfb\x44\x11\xbf\x68\x2c\x26\x74\x31\xee\x4f\x30\xac\x58\x9e\xe7\xf7\x63\x89\xd6\x8d\xb4\x7b\xdf\x21\xc1\xe7\x4c\xb1\xb1\xbd\x5f\x91\xbe\x11\x6f\x25\x45\x00\xa3\xe6\xb3\x22\xdb\x17\x53\xfb\xc6\xce\x8d\x4d\x60\x35\xa2\x31\xeb\x0e\x26\x44\xff\xa1\xbd\x00\x0f\x2b\x68\xaf\xe4\x2b\x4b\xcc\x67\x51\xde\xce\xc9\xfc\xb9\x99\xb4\x62\x45\x1d\x41\x8e\x86\xe4\x92\x86\xe4\x82\xce\xc9\x29\x9d\x0f\x77\x4d\xac\x38\xe5\x6a\x6e\xad\xbb\x88\x75\x6b\x87\x60\x7b\xfb\x04\x40\x7b\x02\x43\xa3\x60\x2f\xb9\xc1\xb3\x9b\x4e\xc7\xbd\xa1\x01\x26\xc1\xf3\x8b\x4e\xc7\xbd\xa0\x01\x36\x9b\xca\x0d\x9e\x5d\x76\x3a\xee\xa5\xce\x3c\xed\x74\xdc\x53\x95\x09\xa6\x93\x0a\xfe\xd4\x1c\xc3\xd9\xd0\xc4\x33\x31\x39\x20\xeb\x99\x60\x26\x20\xf0\xf9\x67\xb4\xaf\x99\x05\x1d\xc8\x04\x64\x04\x95\xda\x33\x35\xac\xfc\x68\x0a\xd9\x98\x26\xdb\x05\xf6\x0f\xf2\x2d\x44\x3a\x72\x2f\xbb\xf4\x8c\x9c\x76\xe9\x59\xb7\x51\x1c\xfb\xee\x8d\xca\xbb\x68\xcb\xcb\xcb\xd3\x74\x43\x2e\x30\x29\x0f\xd2\x25\x39\xc5\xf9\x43\xc8\x32\x05\xac\x50\xfc\xd4\x31\xaf\x4a\x4a\x4d\xe7\x65\x36\xbb\xd6\xd9\x39\xc6\xb9\x5b\x11\x01\x2e\x74\x9b\x5a\x78\xe0\x63\xd9\x45\x6a\x08\xc8\xba\x0e\xa3\x04\x14\xc6\x25\x7f\xc7\x80\xc9\x65\x9e\xc0\x05\x4b\xbc\x57\xcf\x1b\x60\xc2\xca\xf6\xaf\xaa\x36\xfa\x79\xca\x57\xee\xaa\xb8\x6c\x5c\x9b\x59\x59\x4c\x0d\xb1\xa8\x7f\xaa\x72\x0c\x27\x4f\x04\xdd\xe4\x15\x8e\x60\x55\x3d\x1e\x2e\xa3\x2b\xc5\xb6\x2a\x8e\x7c\x8c\xae\x51\x97\x79\x62\x42\x99\x17\x1c\xac\x5c\x25\x10\xcd\x24\xae\x72\x13\x61\xa3\x6e\x58\xd6\xbd\x69\xd4\x95\xc9\xaa\x0c\x2c\xa8\xef\xe7\xef\x51\x2a\xbc\xeb\x81\x2a\xef\x5d\xc3\x27\x26\x95\x9c\x1b\x9d\x73\x03\x9f\x98\x88\x72\x3a\x67\x6e\xcd\x8f\x62\xcc\x7a\x0a\xad\xb9\xfa\x83\x6e\x84\xcf\x48\xa9\x0f\x97\x94\xae\x46\xe8\x1a\xf9\xe8\x06\x15\xf7\xa1\x1b\x52\x17\x94\x89\xf4\x3e\xf2\x23\xbd\x81\x70\xae\x84\x27\xd5\x62\xd9\xf1\x2b\x17\x6f\xde\x74\x3a\x41\xcc\x59\x6a\x9f\xaa\x7c\xa3\x4e\xdb\x5a\x28\x69\xd4\x45\x20\xba\x2f\x93\x4b\x8e\xc8\x1f\x5b\xe9\x31\x67\x2a\xe3\x65\x35\x03\xd4\x02\x88\x7c\xc1\xc0\xcf\x59\xa9\x95\x8c\xd7\x93\xca\xf2\xbd\x2f\x4d\x0f\xdc\x33\x53\x80\x27\xda\x41\x87\x76\x7b\x3b\x9e\x80\x8f\x7f\xa9\x33\x53\x38\x3e\xb5\x29\x5a\xd9\x01\x1e\x3d\x54\xdc\xde\xba\xe8\x1a\x51\x88\xa5\x64\x20\x34\x82\xcb\xa5\xb3\x38\x49\x52\x37\xd3\xda\xdc\x7d\x97\x99\x95\xbd\xbd\x1d\xe0\xe2\x81\xa0\x6a\xad\x2e\x7a\x71\x1d\x65\x0e\xea\x56\xd3\xb8\x67\xd2\x11\x89\x28\x9a\xc5\x89\xec\xd5\x0b\xa0\x9e\x02\xad\xd3\x92\x03\x55\x75\x2e\xea\xc6\x24\xa0\xd2\x9b\x25\x42\xde\xde\xea\x66\xd4\x4c\x75\x48\x41\x07\xf4\x7c\xf0\xa2\x7a\x21\x5e\x2b\x41\x70\xfd\x8c\x95\xbb\x71\x6d\x59\x45\x36\x5e\x83\x91\x65\xcf\xc4\x89\x2a\xb9\x29\x0d\xcf\x0c\x2e\xfd\xf2\x6b\xf9\x56\xcc\x12\x37\x22\xa6\x18\x09\xb4\xcb\x72\x82\x87\x82\x02\x7c\x96\xec\xda\x15\x44\x6a\xf8\x74\x07\x98\xa4\x65\x7a\x4a\xa4\xd1\x7d\x2b\x8c\x53\x2e\x43\x63\x4d\x84\x6d\x5d\xaf\x48\x73\x7d\xd2\x72\xc1\x3f\x96\x4a\x84\x6a\x13\xe5\x2a\xeb\x3a\xb0\xc6\x66\x3f\x78\x56\x13\x49\x12\x0a\x2b\x4c\x65\x09\x5d\x12\x57\x0a\x96\x7a\x52\x12\xd0\xc8\x9b\xa7\x51\xe8\x95\x7a\x30\xb2\xb6\x69\x15\xf5\x19\x59\xd8\xc4\x6d\x2d\x1a\x59\x2a\x4e\x50\x89\x9b\x44\x71\xb9\x64\xaa\x84\x4a\x83\x77\x93\xd1\xca\x0f\x6b\x98\x97\xe1\x0d\x20\x38\xc3\xeb\xc3\x2d\xe7\x42\x8f\x8b\x01\xf5\x51\x2a\x47\x53\xba\xd7\xf7\xd9\xd6\xdc\x28\xa5\x4a\x28\x9e\x8e\x94\xe4\xea\x2f\xe9\xde\x00\x93\xe9\xed\xad\x7b\xad\xbe\x14\x56\x26\x33\x60\x1b\xfa\x96\xfb\x53\x0c\x7a\x4c\xaf\x47\x68\xb6\x8e\x63\xe4\x1f\x63\xc3\x41\x76\x63\x7c\x7b\xeb\xae\xbb\xb4\x1b\x63\x92\x8c\x5c\xd1\xa5\x6b\xc5\x06\x2d\x88\xd5\x8c\x53\x9a\x8e\xdc\xb9\xa7\x7f\x75\xa9\xe8\x06\x44\x7a\xd3\xe4\x9a\x6e\x64\xb2\xf2\x33\xb3\xde\x3d\x5b\x82\x2c\x8c\x6e\x3a\xc7\xbe\x5b\x29\x38\x57\x88\xaf\x1b\x94\xd9\x44\xa7\xa8\x06\x31\xf6\x5d\xa6\x3a\xd6\x04\x16\x7a\x34\x55\x41\x0f\x37\x07\x84\xdb\x0d\x88\x8e\x61\xcd\x54\x5d\x48\xa1\xac\x1b\x60\xdf\x9d\x7b\x40\x83\xe1\x27\xa9\x56\x34\xa7\xb8\x67\x0a\x14\xf5\x95\xa0\x59\xc2\x52\xed\xda\x72\x2f\xd0\x58\x37\xe1\x19\x3f\x7a\xba\x36\xbf\xab\x2b\xfe\xc9\xe4\x2d\x88\xf4\x22\x21\x78\xba\x4c\x32\x49\x97\xe5\xc6\xfd\xe4\x5a\x2a\xa8\x48\xae\xb0\xbb\x46\x2d\x76\xa1\x5e\x4b\x9d\x48\x38\x73\x7b\x40\x4d\x09\xad\xb4\xbd\xbd\xed\x0f\xe7\xe3\x74\x42\xb7\x15\x45\x23\xee\xf3\x71\xaa\xb8\xd7\xbc\xd6\x50\x85\x1f\xd4\x2a\x45\x32\x9e\x4f\x30\x99\xe3\x2d\xa2\x6b\x7a\xaa\x68\x79\x47\xaa\xaf\x2e\x15\xa3\xed\xac\x71\x3a\xf1\xfb\xfe\xee\x7c\xbf\xaf\xdf\x09\x85\x6d\xce\x9a\xcc\x85\x3d\xba\x66\xff\x0e\xa5\xd6\xa9\xe8\x3d\xa9\xf7\xfe\x48\xcb\xff\xbe\xfe\x45\x64\xed\x20\x14\x25\xab\x89\x23\xdd\x8a\x5f\x4f\x6d\x31\x4f\x57\x69\x44\xd7\x70\x9d\xd2\x5b\x46\x62\x04\xff\xfa\x85\x76\x43\xad\x50\xa5\x00\xbb\x1e\xc1\xbf\x7e\xa1\xdd\x80\x9b\x50\x3d\xa6\xa6\xda\xa7\x34\xb5\x6b\xe6\x1d\x1c\x5b\xf4\xc7\xa6\x99\xca\x12\xa3\x81\x2f\xbe\xe7\x5a\x6b\x49\x75\x6f\xa0\xf3\xa3\xa9\x95\xb5\xa0\x69\x2d\xd0\x99\x02\xb7\xb7\xea\xdc\xa5\x38\xe7\x71\xc6\x37\xda\x36\x2a\xbd\x86\x95\xc5\x68\x10\x13\xc5\x0b\x6c\xb5\xfd\x7d\x42\xd8\xb3\xbe\x95\x12\x2b\x8a\x9c\xe2\xf3\x39\xed\x03\x52\xe9\x17\x02\xa1\x19\x07\x74\xfd\x7d\x42\x40\xac\xaa\xd5\x57\xb9\xc5\xe7\x33\xa8\x2f\x54\x7d\x85\xdb\x15\x83\xc8\xe0\x69\x83\x6b\x2a\x72\x57\x02\xce\xa9\x69\x62\xc4\x9c\x43\xf8\x1c\x61\x7d\x6d\x0d\xc3\xc6\xda\xd9\x34\x83\x07\x79\x6d\x4d\x73\x8c\x0d\x79\xda\x1b\x14\xc7\x26\xa0\xfd\x61\xf0\xec\x00\x94\x4f\x1a\xb9\x36\x11\xeb\x07\x97\x61\x72\xae\xfe\x91\xf4\xab\xcb\x08\xd3\xfc\x01\xbe\xbd\x95\xe4\xbd\xcb\x60\xac\xb2\xd3\xa9\x0f\xb6\x08\xb1\x83\x87\x41\xb7\x8b\x5b\xe7\x52\x8c\x23\xa0\x49\xa1\xd4\x18\x06\xcf\x69\x7f\xd8\xeb\x05\xf8\xa3\x9b\x8c\x83\x09\x1e\xee\x6d\x6b\xf3\x8a\xe3\x5d\x37\xa6\x94\x6e\x0f\xcc\x4a\x82\x6d\x2a\x30\x56\x92\x58\x46\x0e\xbe\x77\x41\xaf\x6c\x44\x30\x6d\x3d\xeb\x56\x93\x0a\x63\xd6\xfe\x81\x01\xa0\x30\x08\x91\x19\x8b\x06\x03\x8b\x06\xb3\x16\x0d\x96\x0f\xef\x12\x10\xaa\x4b\xd2\xe9\x68\x64\x99\x15\x1f\x85\x27\xaa\xbb\x45\x6e\x47\xae\x00\x44\x5d\xe1\x1c\xe0\x37\xa9\x12\xf3\xfd\x03\x4c\x84\x46\xd0\xd5\x72\x1a\x63\x37\x0a\x62\xdf\x15\x86\xd0\x54\xcb\x1a\xd2\x53\xe3\x09\x74\xb3\x32\x59\x55\x0b\xca\x64\xb5\x55\x4a\xd3\xcb\x79\x65\xa0\x01\x8f\x62\xb7\x39\xe4\xb9\xe1\xfa\xc9\xbc\x3a\xd6\x66\x51\x3d\x6a\x53\x04\x0a\x17\x23\x68\x16\x55\x63\x99\x6b\x71\x80\xcc\x6b\x93\x6a\x96\x34\xd3\xb3\x85\x40\xe6\x22\xad\x9b\xbf\xe9\x0f\xbf\xc5\xe2\xba\x1c\x68\x19\xcc\x55\xcf\xa8\xc7\x6b\x20\x26\xba\x00\x50\x4a\x5a\xd2\x4f\x28\x69\xe9\x6c\xb5\x06\xf6\x4d\x93\x6a\x9e\x30\x9d\x1e\xaf\x03\xd8\xb4\xa8\x09\x3f\xdd\x62\x18\x7a\x9a\x0f\xa8\x55\xc2\x06\xa3\xe4\xb3\x1d\x43\x20\xd7\xbb\x1a\x22\xbb\x48\x51\x0d\x2e\x05\x9d\x96\x35\x51\x11\x28\x36\xd1\x4e\xcd\x05\x97\x68\x55\x35\x0a\x7b\x24\x95\x8c\xa6\xd1\x7f\xb8\x0d\x6c\x78\xd6\x40\x3b\xf5\xef\x17\x54\x22\x85\x30\x6f\xd7\xb8\x07\x1f\x91\x80\x48\x81\x7a\xb5\x23\x51\xe4\x92\x22\x57\x31\x47\xb4\x57\x69\xeb\xfa\xae\xb6\xca\xc6\x14\x3f\xbe\xdd\x18\xe1\xde\xea\x20\xa0\xa9\x62\x2e\xb7\xf1\xb0\xcb\x7b\x02\x7f\xcf\x72\xbf\x25\x2b\x75\x39\xd6\xb9\x84\x2b\x59\x96\x26\x2d\x0d\x38\x89\x2b\xba\x7c\x9f\xe1\xb6\x26\x1c\xc8\xca\x2d\xb9\x00\xf2\xb4\x0b\xeb\x00\xe7\x60\x6c\x20\x31\x44\x5d\x9e\x26\xd7\x20\x0d\x6d\x4b\x5e\xd5\x34\x59\x4a\x5e\xeb\x42\xf2\x92\x3b\x25\xaf\xad\xaa\x56\xf2\x0a\xc8\xa2\x22\x2a\xdc\x2f\x81\x45\x33\x37\xf3\x74\x28\x30\x25\x45\x41\xa4\x74\xa3\x4b\xee\x2b\x9a\x5f\x45\x95\xd8\x8a\x6b\x4b\xda\x1f\x2e\x9f\xd5\x33\x87\xdd\xee\x12\x33\x5b\x63\xbc\x9c\x90\x3d\x13\xeb\x55\x49\x09\x97\xcf\x0c\xc7\xc0\xbc\xcb\xe7\x40\xc1\xad\x20\x5b\x43\xbb\x09\x45\x01\x17\x10\x6a\x51\x98\x73\xde\x95\x6a\xe1\x5d\xe6\x5d\xe2\x0a\x6f\x5f\xb2\xc1\xa3\x94\x46\x70\x12\x23\xcb\xf9\x76\xa3\x36\x9e\xd7\x77\xcb\x82\xe6\x04\x16\x35\x48\x4c\x6d\xd3\x6a\xdb\xc6\x14\x2d\xa3\x30\x8c\x39\x22\xa9\xc6\x0d\xb5\x41\x18\x66\xbf\x32\x04\x57\x31\xca\x30\xd8\xc8\x1c\xfb\xb2\xe9\x84\x1a\x4d\x1b\xf6\x2b\xa5\x4c\x2e\xdc\xe2\x0b\x43\x0d\x79\xd8\x35\x06\x66\x64\xa1\xe5\x57\x2d\xc4\x92\xd8\x08\x47\x25\x7d\x36\xba\x48\x4f\xfb\x32\x95\x01\xb5\x47\xdc\xdd\x4e\xc4\xde\x42\x2e\x63\x17\x21\xec\x4b\x6f\x06\x7a\x0b\x53\x06\x61\xb3\xf8\x2e\x68\x15\xf7\x8a\xba\xa0\x58\x34\xc1\xf7\x0a\xbb\x3a\xa0\x98\xf1\xc4\x9a\x74\xf7\x06\x20\x80\x9a\x1a\x75\xcf\x29\xa2\x45\xfa\xb8\x2a\xd2\xbb\x8c\xc6\xe3\xf5\x04\xeb\xa2\xc0\x96\x05\x23\x05\x55\x3d\x65\x86\x7d\xf3\x89\x3b\x9d\xc4\x58\x7a\xe0\xb7\x2f\x8c\x67\x09\xd3\x36\xd4\x1c\x06\x5b\x8e\x15\x7c\xa6\x30\xf0\xf3\x51\xf6\xa3\x05\x52\x33\x1f\x27\xf0\xb5\x95\x3e\x54\xec\xab\x13\xcd\x5c\x94\x72\x40\x8d\x88\xd2\x66\x99\xc4\x33\x79\xae\x2e\x0e\xbc\xe1\x82\xa2\x90\x67\x01\x17\xa1\x8e\x72\xda\xa8\x34\x34\xfd\x35\x30\x44\xc1\x39\xc2\xd4\xa8\xd5\x08\x8c\xfa\xf6\x0d\xc6\x67\x26\x65\x8f\x2e\x46\x03\xbf\x07\x6f\xac\xa8\x25\xd0\x10\x4d\x5a\x94\x24\xc9\x78\x3d\x19\xae\xff\x59\xf4\x5f\x38\xb4\x81\xa5\xdc\xcd\x3a\x9d\x54\x83\x13\x3d\xdb\x97\xe9\x73\x84\x49\xf1\x5b\xff\xcc\xc0\xa6\x62\x12\x1f\x3d\x93\xa1\x03\x5e\xaa\x14\xe9\x06\xc1\x3f\xe6\x65\x72\x8d\x9e\x3f\x0b\xa3\x4b\x07\x2e\x6c\xab\x13\xa3\x18\x42\x7f\xb0\xba\x76\xb2\x24\x8e\x42\xe7\x51\xb7\xbe\x19\xea\x2e\x73\xdd\x47\x43\xfb\xbe\xf1\x60\xd5\x68\x4a\x0b\xb8\x47\xab\xeb\xa1\x91\xb3\xfb\x43\xd3\xfa\x71\xa5\x75\xe3\x18\xd0\x7d\x34\x4c\x2e\x79\x3a\x8b\x93\x2b\x7f\x11\x85\x21\x17\xe8\xf9\xb3\xfd\x30\xba\x2c\xfe\x95\xe1\xf3\xad\x39\x68\x7c\xf7\xfc\x91\xa5\xd8\x5d\x04\xe5\x10\xce\xb7\xc1\x63\xe5\xa5\x46\x10\x4a\xb5\xe6\x4b\xfa\xe8\x19\x5c\x02\xb5\x43\x57\x28\xb6\x07\xb1\x55\xb2\x25\x8b\x63\x9e\x0e\xf5\x56\x55\xc0\x00\xd6\xd9\x8c\x59\x75\x9d\x9a\x2b\x67\x08\x43\xef\xaa\x99\xe7\x68\x58\x5a\x16\xb6\x0f\xee\x1d\xa7\x79\x59\xd9\x89\x2b\x8a\x10\x09\xcb\x06\x0a\x5d\xd2\xac\x4c\x5b\x96\xe2\x18\xa5\xb3\x71\x7f\xd2\xe9\xb8\x33\x3a\x9e\x91\xd9\x04\x13\x24\x10\xa5\xa1\xbd\x96\xd7\xc7\xa3\x55\x97\x22\xc5\x6b\xa3\xae\x3b\x1b\x0f\x26\x5d\xcd\xf1\x75\xd1\xea\x7a\x88\x7c\x94\xd5\x4b\x77\x3a\xae\x2a\x6f\xb8\xf2\xb2\x8a\xe1\xfb\x74\x2d\x4c\x10\xaf\x56\x1b\xe8\x4e\x34\x63\x0f\x75\xfa\xaa\x8e\xe6\x40\x6d\x47\x57\xf5\x1a\xa6\x23\x90\x09\xca\x2a\xc0\xe0\x9a\x4e\x60\x91\xae\x29\x77\x1f\xc1\xfe\xaa\x6d\x01\xb5\x04\x4b\x2f\xe5\xab\x98\x05\xdc\x7d\x64\x16\xf0\x11\xb1\x5f\x85\x2f\xa0\x75\xb9\x1e\x3e\xea\xae\xba\x68\xa8\x97\x4b\x6d\x2d\x54\xf1\xba\x96\x7a\x9b\x54\x96\x6d\xcb\xa3\xd3\x0a\xf4\x2d\x25\x5e\x15\xde\x35\x94\x4a\xb0\x6a\x5a\x1d\x45\xbd\x08\x91\x2a\x1b\xe9\xf7\x2c\x4a\x5d\x88\x1c\xd5\xbd\x64\x24\xf6\x1b\xd7\xf9\xdc\x6b\x82\xca\xb6\x7a\x90\x87\x14\x71\x67\x74\xa0\x1a\xad\xba\xa1\x0c\xb5\xbe\xe3\xba\x74\x70\xc7\x43\x0b\xc1\x9d\xb0\xd1\x67\xf6\x51\xf7\xff\xcf\xdc\x97\x36\x39\x8e\x1b\x0b\x7e\xdf\x5f\x51\xc5\x75\xcb\x44\x11\x62\x89\xea\xe9\xf6\x34\x25\x48\xd1\x3b\xf6\x1c\x7e\x33\xf3\xc6\x6e\xfb\xd9\x6d\xad\x62\x03\x45\x41\x12\xdd\x3c\x64\x92\xaa\x96\x5c\xd2\x7f\xdf\x40\x26\x2e\x1e\x55\x33\x7e\x6f\x63\x77\xa3\x3b\x4a\x20\x90\x48\xdc\x89\x04\x90\x87\x11\x20\x86\x11\x50\xeb\xd7\x0b\xac\x34\x31\x8e\x8c\xec\xc9\x6e\x7d\x62\x2f\x68\x82\x5f\xcf\xbc\xc5\x0d\x76\xef\xaf\x49\x78\xa8\x84\xea\xdf\x13\x4a\xc6\x7b\x25\xf6\xa5\x47\x5f\xe8\xe7\xeb\xb5\xf5\x9c\xf3\xa3\x6f\x39\x31\xe7\x16\x87\xf7\xaf\xa5\x0a\x7d\x28\x54\x81\xc5\x64\xa9\x42\x71\xf8\xfa\x0e\x18\xd2\xfa\x1f\x55\xd3\x67\x55\x14\x7f\x6f\x2e\x12\xb1\x0f\x2b\xe6\x03\x73\x33\x06\x6e\x87\xdc\x73\x5a\xb2\xb1\x73\x3d\x0f\xc1\xac\xdc\xf9\x15\x41\x66\xf8\xfb\x1f\xa3\x09\xa1\x19\xc3\x42\xb5\x54\xab\xba\x33\xc9\x46\xa3\x72\x21\xf7\xc9\x92\x65\x88\x3f\xa5\x09\x72\xc9\x87\xf2\xb3\x1f\x4d\xe8\xb8\x24\xf4\xc8\xaa\x7b\x78\xdb\x3e\xce\xa3\xf0\xcd\x32\x65\x51\x7c\x9c\xbf\x5e\xfa\x29\x9b\xd2\xe3\x62\x1a\x4e\xdf\x98\xab\x97\xec\x72\x29\x83\x68\xce\xe4\x06\x2b\xd3\xc3\x37\x34\x08\x4a\x42\xe2\x94\x1d\xe7\xbf\x09\xdf\x2c\xdf\xc4\xd1\x84\xa6\x77\x2c\x51\x77\x3e\x45\xe8\x08\xd3\x8e\x46\xe9\xbc\x13\xe1\xa7\x6d\x10\x78\x77\x13\x59\xc3\xcd\xe5\xa4\x6e\x92\x65\xee\x27\x0a\x77\xb6\xcc\xe2\x92\x28\x30\x99\x59\x75\x82\x0c\x5e\x2e\xa9\x82\xea\xf4\xcc\x68\xe4\x3c\x30\xb9\x09\x97\x8b\xdf\xe0\x39\x63\x63\x8a\x6c\xd7\x20\x28\x09\xf5\xc0\xd6\xa3\xcc\x9b\x97\x1b\x31\x1a\xdd\x22\xc8\x37\xa2\x10\x15\x6f\xca\x01\xcd\x88\x3f\xa5\xb9\xb8\x91\xc0\x37\x4a\x04\xa1\x06\xfd\x04\xc9\x51\x87\x60\x78\xef\x90\x1d\x77\x69\x11\xe2\xa6\xd1\x41\x07\x95\x6a\xc5\xb0\xde\x6d\x1f\xe5\x0c\x9e\x7f\xfc\x8c\xc1\x59\x87\xfa\xa9\x7a\x18\x82\x0e\xbd\x73\x66\x4f\x76\x9f\x12\x42\x2b\x36\xa1\xa5\x11\x9a\xe2\x3f\x02\xc5\xcb\x68\x3a\xdb\x94\x4f\x0d\x2b\x69\xc9\x8a\xa0\xba\xb3\x28\xb4\x8c\x60\x49\x68\x10\x54\x4a\x0f\xb7\x9c\x0b\xbc\x46\x2b\x6f\x99\xf5\x6f\xcc\xaf\x6a\x38\x0c\x1b\xc7\x86\xef\x45\xdd\x7e\x5d\xba\x13\xb2\x9d\x44\xe2\x08\x9d\x5e\x33\xcf\x0b\x00\x0c\x56\xad\x2f\xee\x38\xb9\xe7\x76\xe3\xeb\xe4\x7a\x42\x65\x8c\xc2\x98\x84\xf6\x42\xa5\x7b\x21\xd8\x38\x62\xac\x5a\x4e\xe2\x42\xdf\x63\x55\xe3\x08\x6e\x72\xe7\x1d\x24\xfa\x60\xb8\x2c\xe2\x22\x90\x08\x02\xdf\xf3\x02\x4e\x5c\xa3\x48\x6e\x86\xb1\x30\x32\x94\xc5\x55\x1e\x37\x1d\x4e\xb2\x68\x77\x0a\x81\x07\xe5\x97\xfa\x49\x3d\x1b\x7b\x41\x27\x27\x7a\x1d\x22\x66\x75\xf5\x45\xdc\x89\xe2\x2c\xfb\x14\xe7\x10\x6f\xc8\x6a\x28\xcb\x38\x82\x17\xb2\xfd\x68\xb4\x87\x2b\xe9\xd1\x68\x2f\x07\x55\xf1\x86\x9d\x09\xa8\xb6\x2d\xd7\x32\xb7\x56\x60\x52\xf7\xb2\x40\xba\xec\xc1\x1e\x3e\xa9\x58\x4d\xd6\xe6\x06\xb6\x08\xd5\x1d\xab\xc2\x11\x61\x2e\x7e\xb2\x8b\x1c\x3e\xa9\x58\x09\x2b\x43\x45\x88\x5e\xec\xc3\xab\xc1\x3e\x6f\x2b\xb9\x5b\x94\xc2\xd8\x77\x4f\x99\x9c\x34\xcc\x57\xb1\x2b\xbe\x0e\x1f\xc7\x7b\x24\xb6\x3e\x14\xad\xbe\xc0\xa5\x78\x9e\x16\x41\x73\x87\x97\x09\x63\xbc\x49\xa0\x85\xf6\x41\x31\x33\xa3\x4d\x6f\x1b\x45\x0f\x74\xfb\xda\xd3\x11\x3b\xd2\x21\x60\xd1\x20\x4d\x57\xa4\xcf\xa5\xec\x68\xc8\xad\x37\x00\xdc\xe9\xb9\xfb\xff\x19\x86\x77\x93\x5f\xdd\x87\x8d\xa8\x1b\xdf\xe7\xab\x68\x3d\xe6\xb2\xb7\xc3\xa6\xfc\x3a\x3d\x89\x8d\x2f\x08\x31\x84\xc4\xd0\x36\x21\xf7\x3c\xbb\xe3\xfd\x2f\xdf\x88\x2f\xb4\x1f\x0a\x6b\xec\x4f\xd8\x9c\x68\x09\xfd\xaa\x2e\x6e\x2f\x97\xde\x6e\xc8\x47\x23\x2e\x77\xc0\x81\x3a\xc7\x1c\x85\x7c\xdd\x65\xc1\xc9\x92\x43\x92\x1e\xd8\x5a\x92\x32\x14\x8b\x29\xec\x80\x99\x67\x07\xd4\x41\x60\xc5\xaa\x5a\xcf\xfa\x22\x15\xf2\xf4\x1f\x80\x79\x6c\xb7\x7b\x7c\x01\xb6\xb2\x09\x89\x65\xaa\x9a\x80\x02\xe2\x3b\x4b\xd0\x2f\x69\x43\xf4\xfb\x60\x49\x2e\x17\x7d\x3f\x81\x07\xc9\xc7\xb8\x44\x85\x82\x58\x5c\x89\xd3\x73\xff\x74\x29\xdb\x6d\x64\x3c\x9b\x98\x5e\xec\xbc\x67\x8c\x46\x4d\x7f\xed\x58\x68\x5c\x43\xa2\xbd\x86\x90\xb0\x83\x89\xb6\x47\x39\x25\x6e\xcd\xfb\xa6\x93\x51\x2e\xa9\xa6\xd5\xf2\xf6\x92\x82\x4f\xda\xac\x1a\x47\x2c\x51\x63\x6b\x09\x9b\x7c\xed\x93\xa7\x3a\x04\x19\x07\x1f\x1f\x37\xda\x12\xf9\x74\xb5\x5f\x6b\x72\x8a\x4c\xe7\x4c\xa8\x2b\x1f\xd1\x65\x3f\x41\x5e\xb8\xe6\x8f\xc2\x27\x74\x8f\x77\x8a\x19\x6f\x84\xbf\xd3\x97\xcb\xf2\x54\x40\xf7\x20\xdd\x09\xd6\x86\xd9\xdf\xfc\x67\x18\xd9\x13\x9d\x50\x34\xe8\x30\x7d\xf3\x86\xde\xd8\x3f\x13\xe2\x69\x14\x7f\x14\x49\xe3\x4f\xe8\x84\x6e\xe9\x49\xc6\x55\xa2\x6e\xca\x4a\xf8\x70\xff\x87\x55\xbc\x15\xa1\x51\x39\x19\x8d\xfe\xee\x13\x23\x44\x30\xf0\x00\xa1\x1b\x8f\xca\x07\x74\xb5\xa7\xd9\xaa\x59\xaf\x09\xfd\x2d\xbc\x45\xa0\x34\x9a\x04\x80\x3e\xa1\xb6\x1b\xda\x45\xd0\x5a\x5b\x5a\x22\xf4\xa3\xcb\x68\xfe\xd1\x91\x1b\xd2\x97\x7e\xec\xb3\x53\xa7\x94\x4d\x66\xa9\x5b\xa7\x94\xa4\x5b\x1f\x2e\x42\xd2\x35\xb1\xd4\x1d\x0f\x01\x62\x55\xb2\x26\xe0\x61\xa1\xe5\x8f\x2e\x97\xe8\x96\xf1\xb0\xb8\x5c\x7c\x99\x82\xb1\x84\x8a\x55\xb9\x26\xe4\xa9\x60\x32\x00\xee\x3f\x69\x85\xe1\xa6\x54\xf2\xe0\x92\xc6\x83\x3a\xba\xcf\x51\x9c\xa0\x59\x1e\x56\x93\x75\xbc\x01\xb5\x74\x94\x71\x8a\xbc\x35\xe4\x6b\x02\x6f\xea\xad\xcd\xae\xa4\x9f\xd3\xaa\xd1\xa8\x58\xd8\xc5\x3b\x2b\x58\x25\xc1\xd5\x2e\x89\x36\xd5\x0a\xda\x94\x71\x05\x6a\x38\x31\x77\x56\xd5\xdf\xdb\x02\xe1\xb3\x9f\x9f\x44\x4a\xb7\xd2\x3e\x27\x83\x06\x0e\x88\xba\x11\x14\xd0\x76\x28\x4f\x89\x92\x06\xe7\x70\x27\x9a\xf7\x27\x51\x83\xf6\xe2\x09\x1e\xf7\x94\xb8\xab\x5c\x70\x32\x8a\x9f\x6c\x14\x3f\x51\x1e\x9e\x11\xea\xec\x40\x9d\x11\xea\x6c\xa0\x4a\x56\xfa\xdc\x48\x75\x97\x03\x1a\x12\xe5\xaa\x59\x53\xce\xe4\xf8\x7b\x27\x8f\xd0\x02\x83\x67\x64\x03\xf5\xeb\xaf\xec\x22\x10\x96\x90\x01\xc6\x43\x5d\xa6\x5e\xfd\x3c\x6c\x4a\x48\x6f\x4a\x93\xca\x4f\x76\x9b\x55\xf9\x31\x20\xd9\x85\x4e\xfe\x02\xf3\xcb\x1f\x93\x2a\xf3\x4b\x84\x73\x5b\xdc\xe5\x82\x35\x58\xd8\x32\x2e\x17\x99\x69\x5e\x38\x30\x58\xca\xc2\xc1\x63\x44\x6d\x54\x03\xec\x63\x1e\xce\x39\xb7\x41\xd0\x06\x43\xf0\xe4\x17\x6d\xb5\xa8\x83\x01\xbf\x69\xab\x49\x2d\x0c\xf2\x8b\x3a\x75\x51\xc7\x2b\x55\x13\xec\x3a\x38\x37\xa9\x6f\x09\x0f\x37\x98\xd5\xe5\x72\x9b\xc9\x45\xe6\x56\x1a\x77\x6a\x55\x21\xbc\xc9\x95\x89\xc4\xad\xf7\x00\x4c\x53\x92\x76\xd5\x11\xa6\xb0\x30\x85\xc6\x53\x74\xf0\xb4\x60\x00\x4f\x75\xb9\x64\xf6\x85\xdf\xbc\x75\x5e\x2e\x9d\x29\x6f\x94\xce\x68\xc9\x9a\x57\xd3\x65\xf8\x26\x9e\xcc\xf6\xe1\x83\xd8\xa5\xc5\x4f\x1c\x34\x75\xf7\x61\xdd\x54\xe5\x27\x81\x14\x57\x1d\xfc\x7b\x88\x90\xec\xee\x6d\x51\xac\xa1\xa0\xc9\x02\x97\xfd\x25\xb4\x2f\x28\x55\xfb\x88\x02\x74\xe3\x65\xb5\x63\x17\x5e\x8d\x99\x4c\xee\xc0\xeb\x58\x5b\x37\x1f\xc5\x02\x6e\xdc\xbd\xe1\xe7\x6a\x6a\xb6\x00\xa7\x28\x18\xa1\xb1\x89\x90\x3f\x63\xa8\xda\xb5\x23\xa3\xe2\x08\x77\x18\xf2\x2b\xd8\x64\x26\x5c\xb9\x32\xc5\x67\x66\x4a\x3b\x25\x67\x7c\x25\xd6\xf4\xc0\x72\x78\xa6\xd9\xb0\xdc\x91\xa8\x91\xd3\x29\xb7\x6f\x21\x79\xfb\x2d\x04\xc4\xb6\xdd\xce\x8d\x28\xd0\xd9\xdc\x7d\xcf\xc8\xd8\x84\xd6\x0c\x85\x97\x18\xdb\x2c\xc1\x64\xac\x84\x31\x4f\x07\x93\xf8\x14\x1f\xe0\xf9\x11\x1f\x1a\xfc\x3e\xc8\x21\xd4\x97\xa2\x72\x38\x6a\x36\xa1\x99\x8b\x52\x3d\x47\xb4\x70\x6e\xe3\x83\x7e\x77\x84\x07\x07\x7f\x00\xea\xa0\x6e\x30\x24\xf7\x90\x5b\x69\xa0\xcb\xc5\x6f\x4f\xaf\xdc\xb0\x28\x89\x1a\x26\x77\x2a\x26\xec\xc8\x26\xfd\x96\x27\x6c\x1b\x44\xf1\x91\x9d\x82\x88\x46\x5a\x05\x09\xfa\x49\xbf\xb7\xbb\xd0\xb5\xbb\x72\x6a\x12\x84\x6f\xe2\xcc\x8d\xca\x64\x94\x9c\x5a\x6a\x26\x66\xb4\x76\xe6\x5f\x16\x24\xb4\x0e\x8e\xee\xd4\xeb\x2e\x91\xbc\xc5\x13\x7f\x35\xd0\x0e\x24\xf5\x79\xf7\xb0\x61\x08\xbe\x4a\x59\x35\xeb\xf0\x71\x86\x8d\x46\x4e\x53\x90\xcb\x45\xcc\x73\xa4\xa1\x62\x91\x23\x75\x35\xe3\x23\x9b\xdb\x65\x75\xe5\x0e\xbb\xb2\x23\xb1\x5e\x4c\x2e\x97\x62\x01\xd7\xa8\x42\x76\x0c\xa2\x82\x10\x3f\x11\xfd\x50\xd6\x99\x58\x39\xd0\x16\x41\xe0\xb9\x50\x4f\x86\xf1\x29\xde\xd0\xde\x0c\x02\x95\x86\xf1\x11\x67\x8f\xc9\x97\xb8\xf9\xb6\x32\x5f\x6f\x8e\xa0\x2e\x46\x42\xc8\x2f\x18\xc3\xfe\x80\xc5\xfd\x61\xfd\xd9\x31\x24\x57\x87\x7e\x5c\x65\x05\xaa\xf6\xfa\xc6\xb1\xeb\x77\xe9\xe5\xd2\x8b\xab\x96\xa6\xeb\x6f\xdd\xbe\xf7\x0b\x14\xed\x2b\x94\x50\x49\xa1\xc5\x49\x0a\xb4\xb0\x21\x8f\xff\xfd\x8c\x15\xd4\x05\x32\x56\x2a\x63\xa5\x33\x56\x98\xb1\xba\x2a\xd1\x0d\x38\x19\xb4\x67\x60\x05\x8f\xfc\x2e\xbd\x28\x54\x4c\x9b\xb0\xab\xde\x99\x8c\x95\xf8\xc6\x04\x88\xdd\xe1\x7e\xea\x74\xd6\xb6\x1d\x6b\x27\xbd\x92\xe3\x18\x2c\x1e\xe5\x0f\xda\x15\xd0\x71\x83\x55\xd8\x06\x0a\xe0\x7e\xaa\xcb\x73\xeb\xe0\xa4\x9e\xba\xb5\xc0\x6e\x19\xac\x86\x96\xb6\x6c\xd5\xc3\x44\xbe\x5c\x11\x7a\x0a\x34\x6c\xab\x3f\x26\xbd\x04\xb7\x32\xb2\x1b\x07\xab\x02\xfd\xdb\xae\x88\x8a\x7a\x71\x48\x64\x83\x4d\x71\x6e\x2d\x6c\xfa\xa4\x55\x07\xd8\x43\x9d\x52\x3a\xb4\x69\x60\x7a\x6b\x00\xd8\x0b\xc7\xc5\xfd\x94\xc2\x9f\x6d\x50\xc8\xa2\x09\x69\x1d\x8d\x2c\xd3\xfd\x5b\x34\x25\xe9\xea\x83\xf9\xcf\x49\x8f\x50\x63\x51\x12\xf9\x6e\xa1\x55\x68\x32\x13\x44\xcd\x33\x34\x3f\x80\x8a\x4c\xad\x9e\x31\x9b\xec\x86\x65\xb3\x8d\xe5\x92\x37\x01\xcb\x70\x97\x4d\x58\xb9\xda\x8c\xb3\x35\x3d\x62\x20\x88\x40\x4f\x71\xb5\x91\x3b\x6e\xb9\xda\x04\xd1\xda\xde\x01\x26\xfa\xd8\x91\x83\xc2\xd2\x71\xce\x0e\xa3\xd1\x71\x5e\x01\x73\x08\xba\x8b\x2a\x6c\xb8\xd2\x84\xf9\x10\x33\x3e\x92\x7b\xff\x30\x3e\x92\x3b\x3f\x1f\x27\x24\x48\xe8\x91\x41\xc2\x55\x3f\xec\x1e\xe6\xec\x38\x1a\x1d\x1c\x64\xc7\x2e\xb2\xfc\x59\x64\x07\x85\x4c\xe6\x5a\x40\xa5\x16\x15\x10\x66\xa8\x94\x0a\x77\x2a\xc5\x4f\xcf\x54\x8a\x9f\x6c\xa5\x16\x50\x29\x07\xd9\xb1\x8b\x2c\x7f\x16\xd9\x41\x21\x4b\xb7\x7e\x32\x67\xf9\x68\x94\xe0\xd5\x3c\xe0\xc9\x55\xd8\xe0\x39\x32\x1f\x62\xc6\x09\xb9\x07\x0c\x77\x80\x2d\x38\xd2\x04\xaf\xfd\x4c\xa5\xf2\xb9\x1c\x88\xdc\x41\x96\x74\x91\x1d\x9e\x45\x96\x2b\x64\x32\xd7\x02\x2a\xb5\x28\x4c\xe3\x72\x15\xee\x54\x8a\x9f\x9e\xa9\x94\xd3\x53\xf9\x02\x2a\xe5\x20\x4b\xba\xc8\x0e\xcf\x22\xcb\x15\xb2\x04\x5c\x93\x1e\x19\xab\x2f\x17\xb3\xa6\x0b\xd8\x0c\x13\x12\x34\xb4\x82\xe0\x91\x04\x9c\xd0\x94\xe5\xb4\x66\x07\xbb\xb6\x11\x2e\xb7\x70\x07\x09\x77\x75\x37\xab\x5f\x74\x4d\x22\xd1\xfd\xbe\x4c\x0b\xe6\xc1\xc5\x88\xa7\x1e\xde\xf4\x9a\x35\x44\x82\xa2\x0b\x5c\x6d\x89\x43\xae\x12\x0e\x72\xae\x8b\x09\x79\x7a\x89\x98\x68\x8b\x99\xf0\x2f\x8c\x88\xa7\x0c\x1b\xc1\x46\xfc\xd3\x77\xf7\xd1\x97\xb3\x46\x29\x3f\xab\xf5\x8e\x6f\x5c\x69\xe1\x57\xe4\xce\xe7\xf7\xd3\xa0\x90\x24\x14\xe5\xf9\xca\xba\x1d\x2b\x94\xa6\x96\x50\x1a\x36\x6d\xea\x79\x3f\xa5\x3f\x8f\xfb\x8b\x41\xdc\x5f\xf4\x71\x5f\x5d\xdc\x7c\xf8\xc8\xa3\xee\x0c\xfe\xe2\xab\x0e\xd4\x56\x3f\xe9\x84\x9e\xc8\x0c\x95\xdd\xed\xe9\xa3\xa4\x5d\x33\xbd\x28\x62\x6a\x48\x5f\xd5\x22\x7d\xce\x61\xd4\xb9\xfa\xe5\xfa\xb8\x0b\xc7\x5a\xc9\xdf\xa7\xec\x36\xa2\x35\x8b\x68\xc2\x26\xc6\xa2\xc1\xec\xd6\xaf\xe4\x80\x65\x0b\x7d\x11\x1a\x54\x64\x46\x9e\xb2\x80\x55\xea\xea\xad\x58\x65\xe3\x6a\x4d\x37\x18\x08\xea\x35\xdd\xc9\xe0\x9a\x6e\xe5\x4f\x50\x03\x6d\x4c\x61\xba\x57\x8e\x8c\xb3\xbe\xa4\xde\x91\xa7\x23\xcb\x68\xc5\xc6\x15\xad\xd9\x74\xa6\x97\x82\x5c\x7d\xd5\x5c\x16\xcd\x58\x12\x54\x72\xba\xc8\x2e\xf0\x09\x56\x54\xc1\x47\x34\x63\x09\x3b\x06\x95\xcd\x67\xf5\x98\x85\x2e\x6c\x07\xa5\x8b\x39\xdb\x8d\x46\x02\x25\xb8\x20\x66\xa7\xc2\x66\xf9\x6d\x18\xbe\x13\x8c\x05\xb9\xf7\x77\x63\x41\xee\xfc\xed\x78\x43\x82\x0d\x15\x28\xef\x6d\xd6\xf2\x6e\x2e\xd1\xef\x1c\x64\xa2\x8b\x6c\xfb\x2c\xb2\x9d\x42\x26\x73\x2d\xa0\x52\x28\x4b\x86\x95\x52\xe1\x4e\xa5\xf8\xe9\x99\x4a\x39\x04\x66\xb7\x80\x4a\x39\xc8\x44\x17\xd9\xf6\x59\x64\x3b\x85\x4c\x8e\x16\x1c\x9e\x06\xb9\x87\x46\xb3\xdd\x1c\x02\xf2\xa4\x9c\xc2\x3d\xf0\x66\xc1\x38\x5e\xfe\x6e\x55\x88\x18\xb2\xd3\xc9\x84\xa9\x0e\xcb\x81\xe9\xbb\x4e\xba\x91\x67\xda\xcc\x19\xc7\x0b\xe9\xad\x0a\xbd\x84\x1a\x24\x3a\x5f\x40\x2d\xd3\xad\xc4\x49\xce\x04\x3d\xb0\xdd\x6c\x33\x67\xdb\xd1\x68\x33\xd7\x05\x2d\xb0\xa0\xa5\x2f\x18\x66\x1a\x6f\xc8\x3d\x74\xd5\x1d\x74\x5b\x20\xe8\x46\xd5\x25\xde\xce\xe5\xf9\x68\xab\xf3\x6e\x16\xba\xba\xfe\xee\xd9\xcc\x5b\x95\x59\xf6\x9b\x2c\x78\xa1\x3b\x6f\x8e\x9d\xa7\x0b\xe6\xa7\x67\x0a\xe6\x27\x12\x6f\x17\x50\xb0\xce\xbb\x99\xeb\x21\x50\x05\x0f\x65\xde\xaa\xcc\x54\xdc\xca\xad\xad\xd3\x51\xb9\xee\xa8\x4d\xbf\x13\xc5\x0b\x69\xa6\x83\xb7\x84\xd0\xdd\xad\x64\x2f\xfc\x97\x40\x3a\x69\x07\x27\x0d\x1e\x84\xda\xf4\xb7\x4b\x53\xc9\x0c\x76\x91\x0e\x95\x96\x7b\x45\x17\x72\xe6\x32\x98\xb2\x05\x9a\x32\x1a\x7d\x07\xc7\xe0\x43\x5f\x83\x65\xb5\xa6\x68\x7b\x9c\xa2\x3e\x2e\x90\x56\xa7\xc8\xd2\xb5\xad\x83\x8a\x11\x95\x25\xbd\xe3\x29\xa8\x32\x28\x11\xc0\x09\x79\x06\x52\x33\x9c\x49\xc0\x9c\xcc\xea\x82\xc7\x44\xad\x92\x35\x4d\x9d\x2f\xc9\x74\x16\x2c\x61\x8c\x75\xf0\x8c\x1d\x24\x4b\x30\x4e\xe0\x64\x72\xd2\xb4\xa5\x00\x96\x69\x32\x29\x19\x0b\x24\xca\x8c\x9b\x10\x3e\xa5\x42\x0b\x40\x1d\x19\x42\xa9\x0e\x69\x5b\x44\xb4\x84\x37\xc2\x0c\x44\xb8\x6b\x53\xa5\x99\x0e\xb0\xc6\xf6\x3c\x6a\x4c\xf4\x99\x85\xfb\x29\xfd\x4e\x0e\x91\xc9\x53\xcb\x11\x93\x43\xe6\x98\xd8\xe8\x8d\x91\x56\x17\xff\xc5\x7c\x0b\xee\xc4\x0a\xa9\xe5\x54\x06\x37\x66\x5d\x76\x5f\x09\xbd\x19\x54\x42\x6f\xd8\x58\xbc\xa8\x84\xde\x07\xb8\x9f\x5e\x95\xba\x36\xc6\xcb\x4d\x6e\xd9\x36\x61\xae\x9e\xf2\x24\x7b\x20\x41\x0c\x77\x20\x13\xaf\xa0\x13\x3b\xf3\xbb\x16\xf6\x41\xd8\x16\xa6\x50\x0a\x12\xbe\xca\xac\x40\x63\xc7\xbf\x33\x1b\x53\x67\x1a\x5a\xf3\x07\xc9\x7a\x34\xfa\xde\x4f\x61\xf2\xc1\x9c\x83\x9f\xe9\xda\x16\x42\xf7\xba\x93\xac\x12\x3d\xed\xf6\x2e\xb9\x92\xf6\x5a\x6d\x68\x13\x74\x3a\x82\xf2\x21\xbe\xec\x85\xd5\x3b\x1a\xc9\xe9\x62\x8f\x8d\xdf\x3d\x77\x36\x44\x11\x76\xec\x8d\xda\xb2\x49\x89\xcb\x26\x99\xde\x38\xb0\xc9\xec\x30\x37\x8b\xf2\x10\xb0\x04\x73\x1e\x59\xbd\x3a\xc8\x83\x5f\xbd\x3a\xc0\xe2\x83\xf5\x71\xbc\x5c\x8e\xf3\x12\xaf\xba\x8e\x8b\x12\x6f\xcd\xf2\x79\x86\x31\xf9\x22\x53\x32\xe2\xed\xed\xf4\xc8\x4a\xc5\xa6\xd3\x9c\x65\x9a\x29\x2f\xa8\x36\xa9\xc7\x58\xba\xdc\x87\xbc\x4a\xfc\x23\xcd\x69\x43\x27\xb4\x5a\x2a\xd6\x37\x9e\xde\xa9\x10\xbd\x8d\x48\x9c\xfa\x7b\x8a\x30\x95\xec\xae\x24\x2b\x6b\xa1\x0a\xe1\x1d\xbe\x91\x53\xcd\x42\xb5\x8e\xf5\xd7\x5f\xc0\xf2\x1b\xfe\xbe\xab\xe1\xd4\x61\xf0\x1d\xd6\x53\x2d\x73\x6a\x8f\xe4\x21\xda\x0d\x54\x42\xa9\xca\xbc\x80\x18\x7f\x41\xa8\x3d\x13\x60\x39\xc5\xfd\x74\xf6\x12\xdb\xdc\x3b\x1d\x74\x19\xf6\x4a\x79\xdd\x0b\xf8\xfd\x94\xde\xf6\xb6\x05\x5a\x76\x2f\x56\xdb\x18\xa7\xcf\x63\x7c\x0e\xdf\x2f\x61\xf3\xfb\x38\xe5\x92\x36\x7b\x1c\xc0\x10\x3a\xa1\xb7\xd1\x70\x85\x07\xae\x4a\xbe\xef\xce\x72\x7c\x10\x50\xd2\x37\x68\xb3\x8a\xee\xe8\x96\x9e\xe8\x03\x3d\xcf\x92\xa5\xff\xc0\xb6\x0c\xf4\xa3\x77\x92\x8d\xde\xb0\x26\x28\xe8\x81\x35\x41\x45\xfd\x9c\x09\x32\xf7\xf7\x8c\x13\x30\xe5\x91\xd3\x9c\xed\xe9\x9e\x9d\x25\x28\x68\x56\x47\x84\xc4\xfe\x4e\x23\x78\x90\x08\xf6\x4c\x04\x05\xcd\x99\x90\x08\x36\xac\x21\x73\xff\xa0\x11\x6c\xe8\x86\x1d\xe8\x81\x9d\x25\x28\x68\x65\x47\x84\x50\xb3\x38\xf6\x7a\x71\x6c\xe6\x29\xc6\x1c\x16\xa9\x5e\x2e\x08\x24\x67\x30\x83\x10\x54\x97\x50\xb5\xa0\x46\x23\x5f\xae\x9b\x9c\x9f\xb0\x5a\xf4\x80\x28\x46\x23\xff\xc0\x20\x04\xb5\x93\xdc\x55\xaa\xe0\x37\x0c\x42\x58\x0b\xba\x57\xab\x6e\x4f\xa8\xcc\xa0\x78\x10\xbb\x16\x41\x08\x19\x79\x1d\x2a\xcf\x5f\xb5\x7b\xfe\xf2\x0f\x74\x43\x68\x6d\x9f\x79\xf6\x74\x43\xf3\xf1\x9e\x1e\xc6\x92\x35\x3a\xc2\x2d\xdd\xee\x72\xd9\x5e\x2e\xa7\xcb\xe5\x81\x40\x7e\x77\xf9\xd7\x9a\x9b\xde\xd3\x03\xa1\xbb\x65\xad\xb9\xa1\x3d\xdd\x90\xd8\x49\xdd\x10\x7a\xb2\xa9\x79\x2b\x55\x7e\xd1\xad\x9b\x7a\x68\xa5\x1e\x08\x7d\x70\x31\x1f\x5a\x98\x0f\xb2\x16\xf6\x6a\xcf\xce\xa8\xbf\xf8\x9d\x1b\xb5\x06\xda\x09\x6f\x92\xa5\x36\x5a\xaf\xcd\x01\x61\x1a\x5c\xf6\xe9\xa4\xbf\xb9\x91\xa8\x0a\x82\xe4\x23\xeb\x18\xc4\xe3\xc4\x71\x68\xd8\x97\x68\x2d\x97\x65\x1c\x7e\x41\x33\xd7\xd7\x07\xcd\x1c\x69\xdf\xeb\x39\xac\x45\xf3\x5b\xde\x70\xf6\x48\x21\x7c\x3c\x7c\x53\xa5\x1b\xf6\x13\x3d\x83\x2c\x04\xfb\x9a\xc2\xc3\xfa\x4f\x19\x4f\xc4\xbe\xcc\x36\xae\x78\x9b\xb5\xda\x71\x45\x28\x34\xb2\x3c\x00\x60\xac\x2b\x5f\x35\xba\xb2\x41\x0d\xef\x01\xe0\x9d\x04\x42\xe5\xbd\x7e\xe2\x56\x26\x2a\x3d\xbc\x7e\xea\x49\xa6\x96\x3d\xc4\x78\xc8\x3e\xaa\x14\x63\xca\xff\x46\x28\x15\x7c\x45\xa7\x05\x6a\xf3\x2b\x1d\x3c\x55\x55\xe8\x9c\x7e\x49\x99\x4a\x7e\x7f\x12\xad\x06\x2b\xcb\xfe\x57\x5b\x04\x68\x87\x3d\x63\xe2\x45\x9b\x50\x68\x56\xdc\x51\xe2\xf2\x51\xd0\x63\xc9\xc3\x22\x06\xfd\x00\x14\x00\x61\x4a\xeb\x57\x95\xfc\xd7\x6e\xd1\xaa\xc4\x83\x4a\xff\xf8\x4c\xfa\x46\xa6\x27\xd3\x03\xfb\x40\xcf\xa0\x47\x37\x28\x78\x47\xab\x17\x2c\xcb\xa0\xd8\x8a\x32\x2e\xc3\x95\xa0\xa1\x5f\x30\x65\x64\x46\xcb\x33\xad\x8a\xf5\x68\x14\x31\xd9\x16\x9d\xac\x05\x4b\x64\x1a\x21\x4f\x78\xf1\xce\xf0\xdc\x02\x71\xda\x84\xe1\xb0\x59\x1a\x2c\x78\xd3\x2f\xf8\xfc\x72\xc1\xe7\x7e\xc1\x4d\x79\x18\x28\x57\x3b\x94\x50\x7d\xa8\x2c\xa2\x0e\xf4\x62\x0a\xf3\x50\x5b\x7a\x65\x7f\xa0\xe7\xf0\x58\xd8\xef\x5f\xd1\x73\xd8\x54\xe9\x6e\x27\xaa\x3f\xba\xe6\x5d\xd9\x47\xd9\xe9\x72\xb7\xea\x4e\x7f\xa3\x61\x88\x5a\xce\xc6\x45\xc5\x61\xf5\x49\x09\x96\x8c\xa3\x35\xd4\x37\x10\xe1\x89\x28\x55\x07\x70\xbb\xd2\x94\x07\x0b\xbf\x41\xf8\x73\x0b\xfe\x4c\x50\x69\x43\x82\x5f\x65\xcd\xb5\x71\x1a\xf6\x95\x5c\xe8\x42\x12\xb1\xb3\xdb\xca\xaf\xc0\x67\x28\xaa\x83\xc9\x15\xe0\x7b\x87\xac\x6c\x3c\x12\x8a\xfc\xd0\x9c\x25\x15\x41\xd3\xdb\xce\x8b\xc0\x2f\x34\x4c\xfb\x80\x11\xef\x65\xf8\xcc\x94\x4d\x66\x65\x80\xbc\xbf\x66\x1b\x6b\x91\x9c\x35\x46\x8b\x60\x66\x2c\x96\xcb\x15\x44\x13\xf7\x0b\xc6\xa5\x2c\x3f\xd5\xec\xa1\x67\x91\x92\x3d\x21\x85\x8a\xf9\xd5\xf0\xaa\x28\x59\x5a\xba\x32\xa5\xea\x2e\xb0\x5c\xf1\xf5\xac\x00\x5b\xf1\xfe\x99\x36\x84\x16\xfa\xe5\x18\x94\x3e\x8d\xcd\xa1\xd4\x26\x74\x0c\x61\x2a\xef\x5f\x16\x90\x03\x47\xa9\x34\xd7\xea\xd1\xc8\xd7\x96\x50\x99\x8e\xd3\x56\x17\x94\x01\x23\x63\x3b\xb4\xf5\xdd\xd9\x05\x5c\xe5\x22\xa2\x2d\x9d\x72\x8f\x86\xd3\x29\x69\xa9\x76\x68\xd4\xe7\x0e\xea\xf3\xff\x39\xd4\x58\x4b\xf3\xb2\xee\xd4\xdc\xc4\xe9\x57\x2e\x13\x71\xb9\xb4\x5a\xd7\xad\x67\x1b\xd9\xf9\x17\x20\x3b\x0f\x21\xeb\xbe\xac\x01\xb6\x6e\x24\x6b\x35\xb8\x9d\xb7\x5d\x8f\x76\xd4\x7f\xb6\xdb\x94\x03\x2a\x90\x15\x44\x97\x5a\x56\x89\x0c\x74\xf1\xb2\x65\x90\x19\x35\x25\xef\x70\xf2\xa8\xe7\x91\x38\x7a\x4d\x13\xf6\x84\xce\x52\x5b\xd9\x64\x8c\xcc\x97\xfe\x53\xc4\x8e\x90\x7d\xf8\xe5\x5d\x4d\xe8\x23\xaf\x52\x5e\x34\xad\x1c\x2a\xce\x23\xf4\x33\x0a\x96\xb8\x89\x18\xe5\x11\xba\xe5\x79\x9a\x9d\x5b\x69\x18\xe5\x11\x5c\x49\x25\x0e\xbd\xa8\xad\xa9\x29\x8a\x76\x92\x4b\x30\x90\x0c\x4f\xf7\x00\x20\x89\xed\x68\x74\x5b\xb5\xba\xd3\xf9\x62\x95\x66\xe2\x07\xec\x29\x23\x43\x5f\x11\x6a\x91\xb1\x8a\x56\xa0\xdb\x0c\x68\x64\xc0\x66\x7b\xba\xd2\x44\xa5\x12\xf5\xab\xa5\x8e\x7c\xf7\xd3\x29\x13\x63\x25\xc3\xa7\x4d\x39\xf9\xbd\x38\xe6\xf4\x6c\x14\x46\x6f\xee\x14\x04\x5c\x39\x29\x9b\x6a\x25\x4e\xdf\x97\x3b\xe4\xfc\x5f\xee\x90\xb3\xed\x90\xf3\xff\xbf\x1d\xa2\x97\x77\x51\xfe\x49\x69\x58\xf5\xa8\x45\xdd\xa1\x14\x35\xeb\x64\x92\x58\xce\xc3\x58\xce\x1d\x2c\xe7\x16\x96\x73\x17\xcb\x69\x2a\x63\x74\x79\xa2\x5e\x45\xeb\xe7\x66\x9a\x06\xb6\x13\x4e\xee\xa9\xda\xe8\x12\x08\xd7\x50\xd3\x96\xa9\x96\x5f\x6c\xa1\x0e\xad\x1d\xc2\x2e\x24\x9c\xa9\x5c\x48\x6d\x92\x10\xda\x6a\x6b\x79\x7e\xb6\x96\x67\x55\xcb\xb3\xa9\xe5\xb9\x5f\x4b\xbc\x57\x33\xa5\x9f\xdb\xf5\x3c\x3f\x5f\xcf\x73\xbb\x9e\xe7\xc1\x7a\x5a\x42\x27\x36\xef\x2b\xc1\x6b\x4b\x1d\xb5\x48\x1f\x1b\x80\x1a\xcc\xda\xa1\xae\x2d\x91\xc0\x21\x24\x78\x68\x9a\xa5\x78\x0b\xda\xd9\x95\x95\xf1\x75\xf5\x1a\xa8\x60\x24\x30\x5e\x16\x3c\x03\xad\x6e\x12\x34\x94\x84\x7f\xe0\xd5\x73\xd0\x70\x95\x88\x10\xda\xc8\x7b\xea\x5c\xe5\x40\x53\x14\xa8\x8d\x6d\x81\xd8\x6c\x6d\xff\x0a\x6e\xd6\x76\x4a\x0f\x14\x09\x0e\x12\x97\x36\x15\x06\x4a\xf3\x27\xff\x40\x8b\x20\x22\x9a\x47\x71\x08\x71\x2b\xe3\xb9\x9f\x71\xd3\xcd\x78\x76\x33\xc2\x85\xde\x4d\x5a\xdc\x3c\x90\x14\x59\xae\xd5\x71\x3d\x1a\xd9\xb0\xb5\xaa\xf3\xb0\x3a\xae\x99\xfc\xa3\x8f\x41\x16\x88\xb4\xcc\xc0\x2a\x86\x9b\xae\xd2\x35\xb9\xfa\x55\xcb\xcc\x81\x31\x57\x80\x26\x2c\x44\x7e\x18\xcb\x53\xa5\x63\xb6\x80\x7a\x75\xc3\x9b\x34\x01\x6d\x29\xd8\xaa\xf4\x2a\xf0\xc8\x68\xd4\x8d\xa2\x5e\x25\x32\x30\x69\xeb\x91\x59\xcd\x0a\xf1\xf9\x86\xfb\x68\x1f\xe3\x81\xd7\xc2\x93\x2c\x5f\xd2\x8a\x2e\x91\x89\x87\x94\x3d\x33\xde\x81\x68\xce\x12\x13\x3e\x32\xe1\x27\xfa\xb8\x4b\xb4\x6d\x48\xb5\xd3\x33\xb4\x3d\xaa\xb9\xe9\x19\x1c\x4f\x0c\x33\xee\x4b\x56\x56\xe9\x6a\x90\x59\x0b\x94\x9e\xc1\x60\xce\xa3\x5f\x10\xfa\x93\x4f\xe8\xd7\x6d\x7b\xeb\x6a\x6d\x18\x57\x14\x60\x52\xd6\xd8\xaf\xf4\xc1\x7c\xe5\x90\xf1\x4a\xbb\x0a\xb5\x47\x8b\xd1\xe8\x88\x1f\xfe\x9f\x71\x60\xac\x67\x06\x34\x64\xa9\x9a\x02\xfc\xfb\xb7\x28\x0a\x64\xee\x3d\xfe\x21\x4f\x31\xfd\xba\xfc\x07\x36\x02\x62\x3c\x2a\x06\x8d\x67\x4d\x6e\x99\xb0\x79\x5a\x06\x4f\xff\xc7\xbf\x8a\x55\x23\xbd\x8d\x5a\x78\xfe\x2c\xf1\x9c\xc3\xb4\xfe\x20\x32\x79\xd2\x2e\x76\x97\x8b\x42\xa2\x2c\x77\xbe\x50\x35\xd3\x41\x2d\x94\xff\x21\x8f\x1c\xd4\xf8\x7f\xb0\x37\x0c\xb4\x94\x87\x4b\xbe\x13\x7f\x1d\x57\xae\xf4\x2d\xad\x55\xfc\xc7\x71\x65\x25\x7d\x69\xc2\x3e\xf8\x78\xee\x2b\xe1\x34\x57\x5f\xc9\x2c\xc1\xfc\x1a\x0f\xc5\xef\x8f\x3a\xbf\x9c\x2a\x4d\x95\xfd\x9b\x38\xcb\xb3\x03\x86\x68\x12\xe6\xa2\xe1\x18\xa7\x42\x70\x6f\xb4\x67\x83\xe2\x0e\xc0\x78\x1a\xf2\xdc\x73\x55\x42\x13\x56\xdf\xd5\x41\xa4\x8e\x74\x8a\x5a\x64\xd6\x6a\x58\x81\x56\xc3\xf0\xed\xfe\x96\xfb\x19\x1c\xae\x5b\x56\x39\x53\x26\x23\xc1\xf6\x00\x6e\xa9\x27\xbd\x25\xd3\x07\x96\x0e\x98\x6d\x3e\xb3\x2d\x5a\x99\x25\xf4\x77\xec\x04\xc1\x86\xd0\x47\x56\xdf\x6f\x91\x91\xa6\x9f\x58\x7d\x7f\xc2\x30\xa8\x84\x0c\xa1\x49\xff\x29\xe8\xf6\x59\x33\x47\x60\x48\xb9\xeb\x4f\x80\xd0\xd3\x4b\x19\x3e\x0d\x64\x48\x1d\xf9\x3a\x79\xee\x70\x1e\x56\x1c\xab\xd0\x0f\x9a\xa8\x56\x01\x2b\xb5\x4e\xe7\xc3\xaa\x5a\xd3\x5c\xfe\x38\x92\x6f\x8c\xed\x6d\xef\xa5\x5b\x7f\x3f\x3e\x2f\x1e\x2f\x97\xfd\xf8\x3c\x1f\x3f\x5e\x2e\xf9\xf8\x77\x8b\x4f\xf0\x33\x1f\x7f\x6a\x77\x33\xb7\x16\xfc\xb6\xea\x52\x76\x2c\xe4\x29\xdd\x44\x9f\xd4\xad\xec\xb8\x21\x34\x65\xfc\x8e\x07\xd9\x5d\x36\x4b\xe7\x68\x8e\x3d\xa5\x47\xb6\x2a\x68\x75\x5f\xae\x09\x48\x2f\xb8\xef\x85\xb7\xea\x2e\xfc\x40\x37\xfa\xa5\x30\x7d\xee\x4d\xef\x30\xf8\xa6\x77\x60\xe3\xf4\xc5\x37\xbd\x3e\xc0\xfd\x14\x2e\x81\x36\xec\x10\x74\x52\xe8\x60\xb7\x76\xbb\x14\x3c\x67\xc0\xc7\x74\xad\xf6\x58\xb9\x13\xc1\x1c\xed\x19\xac\x3e\xcf\xad\x3a\xca\x8e\xee\xc9\x68\x74\x5e\x58\x91\x1f\x8c\xf9\xdd\x82\xe5\xc1\x61\x34\xfa\xdd\x9c\xe5\xc1\x26\x3e\x2f\xd8\x5e\x7e\x9e\xe7\x6c\x1f\x6c\x20\xd9\xc9\x90\x13\x00\x74\x90\xe6\x84\x80\xec\xb5\xee\x65\x72\xbd\xea\xdb\xa6\xe3\xd2\x2f\xd8\x71\x35\x59\xd3\x8a\x1d\x57\xd1\x9a\x96\xb0\x68\x86\x67\xf5\x93\x89\x8d\x87\x81\xc2\x3a\x4b\x13\xe1\x57\x77\x25\xf5\xab\x20\x22\x77\x25\xa1\x12\xe8\xbb\x62\x23\x4e\x71\xa5\x5d\x58\xc1\xb2\xc4\x30\xa6\x14\x57\xb4\x0d\x7c\xf5\x4b\x5a\xd3\x82\x28\x3d\x62\x7f\xaf\xe8\x90\xb9\x61\xda\x6b\xbe\xe4\x64\xd4\x5a\xf6\xb6\x1a\xab\xc9\x9a\x04\x48\xf3\xdc\x3b\xaa\xbd\xa2\x5e\x7d\x2c\xe7\x41\x2c\x11\x60\x69\xca\x83\xbd\xb8\x92\xeb\x0d\x0d\xdc\xba\x4e\x96\x50\xf9\xc2\xea\xfc\xbd\xef\x09\xec\x73\xf6\x7e\xd5\xac\x67\x1c\xf2\xdd\x32\x71\xb9\xec\x47\x23\xae\x8a\x67\x4c\x57\x44\xc6\xe9\x16\xc8\x58\xb7\x45\x36\x2d\xea\xa4\x45\xeb\xcb\xe5\x57\xbe\xc6\x46\x15\x18\xb9\xee\x47\xa3\x3f\x98\x36\x52\x27\x07\x15\xe4\xda\xe8\xbb\x41\x5f\xd0\x55\x42\xf7\xae\x7d\xe8\x8f\xbe\xb5\xa6\xea\xb8\x89\x0a\x07\xbd\x44\xcd\xc6\xd1\x2d\x13\xcb\x6f\x2f\x17\xff\x5b\x56\x8b\x46\xdb\xb1\xfe\x86\x0a\x42\xe2\x6f\xdc\x57\xae\x6f\x34\x5e\xda\x00\x21\xff\x56\xdd\xcf\xe9\x77\x4b\xc3\x79\xd0\xfc\xd9\xc7\x7f\x54\xa1\x79\xef\xaa\xd0\x34\xec\xfd\x4a\xac\x69\xe3\x72\xc4\x68\x13\xf5\xf7\xbe\x8e\xa4\xea\xc5\x9c\xc4\xff\xd6\x8f\x9b\xe5\xf6\x4d\xce\x28\xa8\xaa\x66\xd2\x55\xee\x76\xcd\x1f\xf4\xe6\x95\x6e\xfd\x21\xef\x43\xbe\x60\xd9\x4a\xac\x49\xdf\x35\x91\x99\x09\x62\x70\x51\xcd\x9a\xa1\x04\xb5\x90\xf8\x5d\x43\xf9\x9d\xdf\x04\x11\x21\x57\xbc\x19\xfc\x2b\xa8\x7a\xce\xc6\x11\x63\xc5\xd2\x7f\xaf\xb4\x8a\xd5\xc2\x12\x14\x57\x67\x03\xfe\x46\x62\x7e\x05\x3d\x51\x12\xf3\xcb\xc5\x7f\x2f\x57\xac\x8c\x66\xb7\x91\xd3\xb0\x5f\xa1\xea\xa8\xd9\x05\x8c\x60\x5f\xa3\x5f\x84\x80\xdd\x02\x73\x17\x1f\xd1\x3a\xd7\xff\xc3\xf6\x73\xdb\xfe\x5b\x78\x82\x7e\x1f\xd6\x07\x04\xa5\x11\x36\xd6\x36\x0d\x41\x9f\xda\xb7\xad\xef\x07\x6e\x5b\xdf\xaf\x38\xee\x83\x66\x61\xca\x5e\x70\x56\x24\xae\xc3\xc2\x59\x87\x40\x25\x8c\xb9\x0a\x0c\x8c\x23\x5b\xf6\xbf\xb5\x3c\xb6\x22\x7d\xe5\x48\x5f\x1b\xc5\x8d\x64\xac\xd1\x87\x68\x66\x0d\xeb\x98\x6e\xeb\x9c\xb4\x96\xdd\x88\xb8\x63\x79\x67\xe0\xc6\xef\x8d\x7b\xe1\x07\x0d\xd4\xa2\x0e\x85\x16\x75\xa8\xf4\x6b\x6e\x85\x2f\xb3\xda\xc6\x94\xec\x18\x2b\x6e\xa2\xad\xa4\x36\x03\x26\x52\x67\xb9\xf3\x72\x5e\xcb\x45\xed\x2a\x15\xcc\x50\x42\x25\x0a\xdf\xdc\xd5\xb3\x42\x89\x4d\x14\x84\x56\xea\xa9\xb6\x92\x6b\xde\x7d\x5b\xb5\x22\x14\x4d\x5b\xee\x60\x99\x83\x40\x85\x64\x1c\x13\x3a\xa1\x6d\x31\x8a\x0e\xac\x9f\x53\x84\x83\x37\xe7\x96\x54\x45\x6e\x45\xa5\xcd\x60\xfd\xde\x19\x2c\x5a\xfd\xdf\x18\x0c\x5a\xb2\x4a\xf3\x33\xcd\x73\xfc\x4c\x31\xc8\xcf\x14\x6c\xdc\xbc\xc8\xcf\xf4\x01\xee\xa7\x57\x77\x90\x9a\xae\xec\x54\x7b\xcc\x2a\xfa\xbd\x8f\xf6\x0f\xe4\x7c\xe5\xab\x29\xb8\x7a\x29\x68\x11\x74\xd0\x0e\x1c\x7b\x6e\xca\x2b\xa1\x7a\x82\xeb\xe9\x9d\xd3\xa6\x27\x61\xd4\xad\x83\x33\x1a\x7f\xb3\x2f\xd8\x92\xd8\xf4\x4c\x4e\xe9\x65\xd7\xcc\xd4\x0b\xf7\x5e\x39\x39\xfe\x3e\x2d\x04\xaf\xbe\x91\x73\x55\x14\x8d\x2f\xeb\x3c\xa1\x9c\xb8\xcf\x2d\x60\x87\x09\x5f\x3b\x8c\x57\x95\x79\x61\x69\x41\x66\x92\x15\x49\xd0\xc5\x1b\xb7\x1a\x8e\xee\xac\x3b\xe2\x95\xbe\x4c\xc9\xc2\x07\x18\xa8\x42\xd4\x35\xd8\xd3\x6a\x5a\xfe\xdf\xdc\x64\xa2\x1f\x06\xb3\x50\x19\x97\x02\x59\x3d\x7e\x67\x23\x08\x50\x09\xe7\xd1\xbc\x0c\xf9\x06\x0d\x19\x7c\x68\xca\x83\xcf\xef\xfd\x62\x1c\x11\x9a\x19\xa3\x31\xe5\xf5\x7a\x15\xe1\xb6\x08\x37\xa2\xe1\xc9\xfe\x72\xf1\x9d\xaf\xa1\xf7\x73\xf0\x3f\xcc\x93\xbd\xef\x8e\x26\x7a\xeb\x05\x47\xf3\x3f\x82\x45\x92\x4e\x84\xba\xf6\xf8\x6a\x9f\x66\x1b\xf0\x64\x08\xe6\x66\x41\x0a\xd4\x38\xb3\xee\xbe\xab\xe9\x7d\x46\xcc\xd9\xe4\x72\x69\xe6\x6c\xd2\x37\x73\xf4\x5d\xf1\xc8\xb3\x74\x73\xb3\x49\x73\x51\xd4\xf2\x3c\x74\xb3\x2d\xab\x1b\x79\x4e\xa6\x37\xf0\x1c\x77\xc3\x6e\xbc\x40\x04\x1e\xbd\xc1\x17\x39\xf8\x6e\xb4\x84\x93\xeb\x4d\x59\x8e\xb5\xe3\x47\x99\x2a\xb7\xca\xd6\x07\x31\xfa\x24\x06\xac\xca\xb5\xa0\x7a\xfa\x17\x77\x15\xe5\x21\x3c\x68\xe8\x98\x00\xde\x3f\x6c\x06\x26\x94\x73\x62\xac\xc5\x2d\xd8\x4d\xd0\xb6\xc6\x58\xe3\x20\xd0\x51\x0e\x06\x1d\x05\x9a\x72\x86\x01\x29\x34\x3b\x54\xa8\x19\x53\xd1\x8a\x5c\x5b\x5d\x0a\x6c\x12\xeb\x8e\x93\x6a\x20\xa6\x1a\xd3\x15\xb6\xae\x6e\xa1\x1d\x84\x68\x4e\x62\xe0\xed\xb3\xed\x52\xd9\x2c\x21\x30\x95\x2f\x08\x88\x8e\x24\x3c\xcb\x7c\x41\x2b\x62\x24\x4d\x64\x26\xe5\x06\xe3\x7b\x7e\x16\x95\xa4\xee\x19\x13\xab\x6a\x3d\x2b\xc3\x7d\xba\x11\x8e\xb6\x16\xf8\xdf\xce\x1c\x4c\x99\xe4\x1b\xd5\x65\x86\x64\x25\xda\x90\x95\x03\x59\x19\xc8\x86\x55\x2b\x61\xef\x9b\x6b\xd7\x44\xa8\xdc\xed\xc1\x39\xe5\xac\x08\x02\xc2\x43\x0e\xb7\x0b\x4b\xae\xda\x2c\x36\x97\x8b\x5f\x2a\x33\x7a\x3e\x37\xb7\x66\xd4\x02\xb0\xdb\x09\x38\x61\x50\x1c\x46\x31\x1e\x4b\x1e\xc3\xa6\x4b\xce\x5c\x65\x53\xeb\xcb\x27\x64\x36\x01\x53\x9a\xea\xf6\x51\x39\x75\x93\xb5\xbc\x5e\x4b\x60\x4e\x7d\x72\x6d\x8f\x81\xdb\x63\x03\xde\x3f\x8d\xab\x6b\x79\x90\x70\xe4\x77\x50\x04\x4f\xf1\x6a\x3d\x37\xd9\x92\x92\xf4\x7d\x67\x0b\xdf\x73\xcc\x11\xfe\x5a\x5d\x66\x9e\x9a\x9b\xf6\xb5\xe6\xaf\x17\xc6\xcc\x20\x38\x85\x1f\x72\x02\x8f\x2e\x5d\x95\x9f\x57\xed\xd9\xd5\x38\x7c\x75\x5e\x12\x63\x4f\x19\xa4\xf4\xba\x6e\x79\xaf\x24\x4c\x8b\x5a\x54\xcd\xfb\x6d\x23\x2a\xdf\x5d\xbb\x68\xb1\xc8\x69\xb9\xae\xba\xad\x99\xa4\x83\xb2\x19\x7e\xf3\x9f\xad\xa5\xeb\xbb\xbe\xdf\x59\x60\xcc\x66\x68\xa0\xbe\x2b\xb6\x25\xeb\xcb\xeb\xaa\x0d\x04\x45\xf8\x40\x53\x8a\x79\x5e\xc0\x69\xc6\xac\x46\xb0\xd1\xfe\x5d\x16\x48\x1d\x02\xef\xc6\x0b\x8a\x50\xbd\x84\xaa\x2f\x7c\xfa\x54\x1f\xb2\x0f\x25\xe9\xb8\x97\x1f\xf6\xd9\x4b\x46\x41\xba\x7a\x1e\x2d\x68\xda\x5d\xb4\xab\x66\xad\x9f\x53\xc0\x42\x5e\x3f\x99\x3d\x5d\x09\xad\x59\xba\xca\x34\xa4\xdc\xb2\x30\x02\xd2\x12\x26\xf7\x41\xed\x01\x4f\xcb\xd1\xf6\x86\x02\xec\x80\xf2\x17\x86\xc1\xcb\xf9\x69\x0c\xb4\xc8\x53\xb7\x8c\xe3\x77\xef\xde\xbd\xeb\x0d\x40\x8b\x78\x34\x84\xcc\x86\xba\xee\x88\xe5\x80\x9f\x71\xe3\x64\x5c\x1b\xe4\x8d\xfb\xcc\x5b\x31\x1a\x1d\xed\x6c\x29\x74\xab\xd8\x93\x9a\x6b\xf1\xd1\x78\xdf\x06\x8f\x98\xca\xc4\xc7\x80\x0b\x79\xc9\x13\x54\x4b\x3f\x51\x5b\x40\xa5\xc8\x6b\xa2\x09\x7a\xa5\x89\x6c\x6c\x60\x8e\x61\x79\x6c\x94\x39\x08\xff\x76\x42\x2c\xb0\x4a\xc1\xe1\x84\xa4\xe1\x12\xd9\x13\xda\x47\x50\x18\xb5\x07\x18\x8d\xe7\x4a\xe8\xd1\x50\x1f\xcd\x04\x24\xed\x89\xab\x4c\x3b\x77\x2e\x62\x5d\xa1\x53\x9c\xbc\x49\x8b\x84\x83\x27\x23\x61\x84\xd1\xe9\x91\x25\x0e\xa5\xd5\x06\xb2\x19\x4b\x97\xcd\x98\xa9\xda\xdd\x4f\x63\xc5\xa7\xe2\xac\xb3\x29\x84\x6a\x63\xd6\x8c\xd5\x4b\x2e\xe3\xf7\xca\xc2\x7d\x6c\xed\x69\xd7\xe8\x90\x23\x31\xd6\x2c\x35\x41\x47\x77\xb9\x7b\x76\x5c\xe5\xeb\x59\x1e\x04\xe0\x87\x36\x3c\x81\xbd\xa2\x7d\x78\x66\x8c\x13\xc7\x27\x98\xbf\x57\xe4\x5e\x92\xf0\xd9\x9e\x3d\xe1\x17\xfa\xe8\x44\xe2\x1d\xdf\x46\xd4\x4c\x00\x45\xaf\x97\xe6\xf1\x44\x1e\x19\x0a\xe1\x93\xd8\xc4\xd0\x53\xdc\xd0\x73\xcc\xaf\xf4\x88\x67\xee\x3d\xa1\x7b\x0b\x2e\x67\xa4\x9c\xd7\xce\x6b\x34\x27\x48\x78\x9c\xa8\x86\x50\x4f\x8e\xef\x18\x98\x7d\x2f\x4e\xaf\xbd\xfd\x58\x5b\x40\x77\x07\xcb\xd1\x08\x30\xe7\xf4\xaa\xb5\x3f\x38\xcb\x5a\x38\xca\xcc\x9c\xb4\x36\x51\xee\x6c\xa2\xdc\x6c\xa2\x05\x18\x1f\x69\x6f\xb7\x85\x03\x59\x48\x48\x3d\x0e\x29\x2b\x5a\x3b\x2e\xad\xd9\x64\x96\xb0\x74\x55\xaf\x67\x75\x10\x90\xc4\x74\x7c\x74\xbd\x1a\x2d\xad\x04\xb0\xa7\x43\xd3\x0b\xdb\xf5\x12\xc2\x13\xec\x74\x89\x1c\x64\xb0\x04\x61\x4b\x90\x3b\xa9\x08\x25\x73\xd8\xa6\xc7\x95\xb5\x98\x2f\x3e\xdf\x14\xbe\x90\x1d\xcf\x69\xa5\x80\x43\xb4\x95\x59\x13\x9d\x3b\x7c\x14\x55\x0d\xef\xd5\x93\xf0\xcb\xf0\xb5\xd7\x81\x63\xab\x35\x05\x26\xba\x57\xd2\xcf\x70\xd1\x88\x46\x79\xfa\xa6\x20\x42\x79\xbd\xfa\x9f\xd3\x62\x53\x7e\x0e\xff\xfe\x87\xa3\xa8\xce\xe4\x4a\xdf\x45\x71\x9b\x47\x6e\x01\xb4\x6a\xa2\x6e\x7b\xd2\x22\x6d\x5a\xfe\x01\x04\x3e\x69\xf6\x1d\x5a\x62\x06\xbf\xfb\x02\x63\x66\x51\xa3\x3d\xe7\xde\x46\xcc\x7c\xe9\x3b\x80\xa4\x2c\x6a\x39\x3d\x86\x6c\x6f\x9a\x47\x99\xbe\x57\xf2\xd1\x48\xa0\xbf\x71\x78\xc9\x05\xbf\xe1\x80\x96\x31\x81\x01\xd0\x1c\x00\xaf\xe2\x33\xc7\x5b\x38\x15\x5a\xe4\xd5\x47\xd7\x92\xb7\x85\x7b\x19\xd1\x92\x8f\xa7\x92\x1c\xf0\x96\x5f\x4d\xfd\x45\x37\xac\x18\xbe\xbd\xde\x0d\x25\xd0\xad\x1c\xdd\x13\x6b\x9c\xe7\x14\xfa\xc0\xfa\x07\xd6\x33\xcb\x17\x53\xf0\x19\xc6\x95\xdb\xce\xd5\x74\x1d\x9e\x62\xf7\xeb\x0c\xef\x46\x60\x3e\xcf\x7a\xbf\xa5\x8f\xec\x61\x19\xc5\x13\xfa\x89\x3d\x2c\x27\x71\x44\x3f\xb3\x09\xfd\x60\xf5\x73\x3f\x2f\x8c\xe7\xdd\xd1\xe8\xc3\x02\x04\x82\xc1\xb2\xcf\x0c\x95\xf1\xd9\x56\xfb\xe5\xfd\x3c\xb7\x80\x38\x7c\x87\xd5\xe7\xb5\xb2\x00\x24\xa9\xe3\x3c\x9f\x05\xc1\x9e\x6c\x71\xd4\x0f\xab\xcf\xc1\x7e\x4d\x66\x9f\x03\x96\x1b\x15\x53\xa7\xb4\x67\x33\xee\x56\x1f\x20\xa3\x3c\x8e\x6e\x57\xc7\x60\xba\x66\x32\xea\xd3\x9a\xd0\x0f\x01\xdb\x18\x5c\x6e\x65\xff\xa5\x4a\x7c\x98\xef\x3a\x0d\xd9\xad\x3e\xac\x89\x44\x8e\x9a\x9d\xe9\xd6\xaf\x64\xe3\x82\xc7\x35\x2d\x21\xf0\x69\x4d\x53\xa8\xc5\xe3\x9a\xd6\xaa\x3a\xa0\xe9\x5c\x31\x96\xfe\x6c\xe9\xb2\x15\x9f\xd6\x01\x83\x67\x45\x2a\xeb\xd2\x6e\x49\xb5\x40\x05\xe7\x09\x63\x9f\x7f\xb6\x5b\x12\x56\x5f\xa1\x27\x8d\x32\xf4\x61\xf5\x79\x9c\xab\x81\xc8\x58\x19\xf8\x10\x11\x7c\x5a\x8f\x4b\x72\xe7\xa7\xe3\x8a\xdc\xab\xa8\xc7\xf5\xb8\x22\x74\x6b\xb4\xf0\x54\x28\x0b\x6a\x42\xf7\x6c\xfa\x5c\xfd\x65\x91\xa6\xc2\x3f\xd7\xd8\x0f\xb6\x62\xbb\xd5\x87\xf1\x06\x3d\xe0\xd6\x81\x0f\x5f\xb2\x56\x35\xb9\xf3\xab\x71\x4a\xee\x55\xd4\xe3\x7a\x9c\x12\x42\x75\x2f\x25\xd0\x43\xd7\xe3\xad\x99\x7a\xa3\x91\x33\x17\x12\x78\xa5\xfb\xdd\x68\xd4\x02\x38\xda\x52\xb7\x20\x8b\x21\xff\x42\x78\x9c\xe3\x57\x10\xe9\xef\x20\x1a\x9a\xb5\xab\x63\x90\x07\xfb\xb5\x04\x09\xf6\xeb\x19\xe6\x30\x19\xae\x57\xbd\xc2\xd9\x56\xd2\x51\xe3\x82\x53\xdf\x7d\x3f\x01\x6d\xc1\x67\xa4\x2b\x2d\x78\x2e\x24\x2f\xc8\x93\x4f\x1e\x55\xe4\x3d\xf6\xa2\x70\xea\xc9\x2d\xf7\xdd\x34\xfe\x85\xde\x6d\x1c\x4f\x09\x8d\x6b\x03\x59\xdc\x37\xce\x95\x15\xd7\x1c\x15\x5e\x59\xe9\x78\xe7\x86\x3c\xac\x9b\x6a\xdb\xa4\xb9\x20\xd6\x63\x97\x8a\xf1\x1b\xa2\x48\xed\xb0\xf9\xde\x9b\x46\x1e\x24\x34\xc1\x5e\x7a\x13\x2f\x6e\xc0\x12\x92\x2f\x64\x82\x20\x9a\x7b\x69\x02\x11\x8b\x2b\x2a\xb5\xe2\x65\xd6\x6d\xa4\x30\xa7\x0c\xa8\xeb\xb7\xe5\xb1\xaa\x7d\xe0\xf9\xe7\xd1\x14\xef\x66\x67\xf6\x30\xc9\xd9\xca\xfb\x3d\x2f\x3c\xea\x7d\x2d\x1e\x3c\xea\xfd\xc0\x2b\x8f\x7a\xef\x0f\x15\x84\xcf\x1e\xf5\x7e\x7f\x2c\xe0\x6f\x26\xe3\x8f\x3b\x8f\x7a\x1f\xc4\xc1\xa3\xde\xbf\x27\x8d\x47\xbd\x1f\xcb\x47\x8f\x7a\xbf\x15\x89\xb6\xe2\x88\x3b\x76\xc1\x56\xde\x07\xc8\xf8\x03\x88\xbe\xfc\xe9\x28\x8f\x04\x7f\x11\x1b\x19\xde\x1f\x65\x71\x55\x2a\x51\xf1\x46\x66\x4c\x58\xba\x88\xa6\xcb\x74\x1c\x4d\xe3\x89\x64\x2f\xa3\x69\x9c\x76\x5c\x74\x36\x3d\xef\x13\x7b\xd6\x68\xfb\xfc\x47\xd8\x3e\x32\xf2\xa4\x55\x4b\xd5\xad\x2a\xf7\xe2\xbd\xec\xb1\x62\xa5\xb6\x9a\xb3\x4f\xd6\xee\x0d\xeb\x83\x02\xe0\x08\xf0\x43\x59\x34\xfb\x0e\xc8\x46\x82\x54\xbe\xde\xab\x40\xf0\xc7\x23\x2e\x84\x18\x80\xb8\x69\x83\xec\xbd\x18\x7e\xbf\x45\xd0\xb4\x95\xf8\x1d\x46\x26\xad\xc8\x4c\x45\xf6\x50\xe5\x4e\x69\xaa\xbe\x41\xd4\xad\xd2\x0f\x2e\x50\x5a\x1c\x1b\x51\xcb\x3d\xd6\x81\xf8\x87\x6a\xb9\xef\x4e\x71\x07\xe7\xfd\x6b\x12\x44\xad\x1c\x1f\x1c\x9c\x1f\x44\x52\x16\x9b\x2e\xce\xb3\x03\xf1\xf5\x31\xcb\x3e\xc2\x13\xdf\xab\x68\x32\x69\x81\x7d\x54\x45\x77\xe0\x5c\x90\x83\x04\xa9\x97\x1e\xcf\xbd\xd8\x3b\xe4\x9e\x9b\xf6\x93\x4a\x7b\xff\x83\x17\x7b\x3f\xfd\xd0\x4a\xfb\xec\xa2\x86\xe1\xbe\x96\x86\x79\x97\xab\x03\xe8\xa9\xf7\xca\x63\x6c\xbf\xcc\xd8\xed\x24\x36\xc9\xe6\x3a\xd5\xb8\xca\xb0\xab\xfd\x19\x23\x46\xe4\x09\xce\xd4\xfd\x2b\x56\x0e\x2f\x6f\xa0\x68\xcd\x29\xaf\x76\x47\x79\x64\xa8\xc9\xf5\x8a\x6b\x93\xb3\xa7\x0d\x6f\xe4\xd2\x9d\x69\xa3\xf2\x96\x38\x8c\x46\x8d\xcf\xa9\xa7\x3f\x3d\x2a\x9c\x0f\x42\x21\x71\x87\x8f\xaf\x90\xa6\xc3\x2a\xa9\x76\x92\x74\x98\x18\xc6\x6e\xe5\xc9\x09\x2a\x97\x2c\x2c\x6e\xdd\xf9\x1e\xf5\x80\x50\xc8\x05\x9b\x66\x59\x5a\xe3\xf0\xc2\x27\x4c\x1e\x5c\xc9\xcd\x1e\x96\x3f\xa6\xd9\xf3\x43\xc7\xee\x72\x15\x04\x44\xd7\x52\x2e\xbd\x6a\xad\xaa\xf9\xe7\x3f\x7d\x85\xdf\xb6\xaa\x36\xbd\x76\xd3\x2d\x97\x68\x3a\xbd\x6a\xd9\x37\x7f\xa8\xca\xcf\x35\xbe\x39\x82\x31\xfc\x7f\x96\x85\x58\x4a\xd6\x1f\xd6\x9f\x80\x4b\x3c\x1d\x8f\x7e\xf7\x30\x4c\x0b\xdf\x81\x22\x44\x0d\x48\xc9\x9e\xb0\xc9\x71\x24\x5e\xd3\x1c\xda\x1c\xbf\x15\x5f\xd0\x7d\x79\xac\xe2\xd7\x6f\xc5\x1b\xba\xe1\xe7\xf8\xcb\xb7\x5f\x88\x37\x34\x97\x1d\x11\x4f\xdf\xbc\x9b\x8a\xb7\xf4\x1f\x47\x5e\x35\xa2\x8a\x7f\xf3\x9b\xdf\xbc\x15\x6f\xe9\x59\xf0\x2a\x7e\x33\x7d\xf3\xee\x8b\x77\xe1\xf4\xee\xed\xe4\x2e\x12\xaf\xaf\x34\x63\xab\x55\x24\x9b\x28\x8b\xf0\xd6\x74\x35\x75\x3f\xde\xb8\x1f\xd1\xc4\xfd\x7a\xdd\xfa\x8a\xe4\x81\x5a\x56\x4d\xa1\xb0\x1f\x6f\xdc\x0f\x89\xc2\x7e\xbd\x6e\x7d\x45\xd4\x93\x4d\x52\x08\x74\xf0\x0b\x1b\xfc\xd2\x06\x23\x07\x22\xa2\xde\x86\x9f\x55\x36\x15\x7a\x6d\x42\xe1\x54\x56\x00\xe6\x87\xfc\x72\x3f\x22\x27\x3c\x35\x61\xc9\xda\x65\x5a\x3a\x73\x25\x31\x19\xa0\xb7\xed\xcc\xb2\x43\xbd\xf5\x1a\x94\x13\x6c\x86\x88\x7a\xaa\xe3\x15\x5e\xe7\xcb\xc9\x34\x13\x3f\x7f\x96\x2a\xc8\x53\xd1\x3e\x4b\xfd\xbb\x76\x1d\xdc\x3e\x48\x15\xa0\x5e\x23\x0f\x7c\x85\x63\xfc\xd7\x3d\x68\x15\xe4\x09\xa7\x53\xc6\x8c\x8e\xce\x4c\x3b\x7e\xc8\x94\xa1\x77\x65\xd2\x7f\xd8\x12\xbd\x26\x0f\xe0\x97\x41\xb9\xa0\xa3\xca\x03\x07\x28\xfd\x43\xfa\x91\x65\xc6\xc7\xc2\x68\x64\xda\xce\x98\x13\x0f\xa2\x22\x59\xdb\x67\x46\x1b\xd2\x49\x5a\x45\xeb\x65\x1d\xa7\xe6\x3d\xab\xed\x69\x23\xe9\xab\x7a\xda\x72\x96\x36\x18\xb7\x71\x4e\xd6\x77\xe5\xaa\x5b\xcc\xda\xb9\xdf\x01\x4e\xf0\x68\xe4\xfb\x46\xa3\x5b\x5f\xa0\x21\xfb\xb9\x7f\x5c\xed\xd7\x88\x01\x42\xd1\x7a\x1d\x1c\x57\xfb\x20\xb2\x91\x32\x2c\xf1\xdd\x4f\x47\xa3\x3e\xf4\x82\x25\x04\x78\xcc\x19\x7a\x8d\x53\x10\xf4\xc0\x14\x04\xbc\xf4\xc1\x3c\x61\xec\x60\x8e\xc7\xbd\xc6\x6b\x90\x6e\x3b\x48\xcb\x2c\x6f\xb7\xe1\xca\x5a\x0d\x8e\x56\xd3\xf2\x9b\x32\x64\xbe\x5f\xb5\xfa\xbe\x0c\x65\x69\x5d\x2b\xfe\xed\xd4\xfb\x66\x96\x33\x0e\xfe\x56\xa2\x98\xcf\x5f\x2f\xa7\x31\xb7\x0e\x54\xf2\x3b\xd6\x5c\xf3\x79\x04\xda\xd6\x11\xb9\x5a\x5f\x1c\xce\xd4\xb8\x5c\x56\x39\x3d\xac\xd5\x64\xda\x38\x3e\x3f\x56\x93\xf5\xec\xe0\x7e\x47\x1a\x6a\xc7\x36\x77\xe5\xea\xb0\x9e\x69\x72\xc4\xd8\x61\x59\x84\xb5\xe5\x04\x1a\x5c\x16\x86\x31\xa0\x1b\x42\x62\x4d\x79\x0c\xb4\xe6\x45\x14\xb4\x61\x4d\x10\x1a\xa8\x8d\x81\x45\xd6\x55\x41\x6a\x3e\x16\xb1\x02\x81\xb0\x48\x81\x63\xd1\x28\x91\x7d\x41\x40\x3b\xe1\x5b\xa0\xaf\xef\xda\xc0\xf7\xaf\x11\x5c\xcf\x87\xd1\x08\x80\x0d\x6b\xa2\xa0\x2d\xab\x22\xc1\xa9\x6a\x90\xdd\x2e\xfd\x09\xa1\xbb\x05\x03\x81\x8b\x63\x23\x14\x96\x0f\x9d\x44\xd9\x48\x95\xa4\x9b\xaf\x93\x36\xfc\xac\x52\xb0\xb9\x18\xff\xc5\x9d\x9b\x02\x5b\x57\x04\x09\xd3\xbb\x32\x84\xae\xd0\xe8\x86\xfa\xe1\x35\x31\xb0\xaa\x37\x5e\x82\x7e\x4b\x54\x55\x64\x57\xb4\x00\x27\xb8\x94\xb6\xf4\xc4\x26\xf4\xc1\xf5\x02\xb3\x29\xe5\xf2\xd9\xb2\x07\xfa\xc0\x00\x99\xe4\x39\xc0\x2e\x3a\x50\xd0\x07\x42\xed\x80\x5d\x2e\xee\x98\x10\x30\x15\x15\x49\x0a\x6c\x5b\xa6\x66\x9c\x70\x71\xcd\x9c\x8a\xb8\xf5\x0d\xfc\xd6\x10\xbf\x8e\x23\xa2\xf3\x37\xfd\xfc\x10\x7e\x08\x4e\x77\x38\x08\x81\xdf\x8c\x05\xb9\xdb\x10\x7a\x62\xad\x39\xd6\x1a\x01\xbc\x31\x78\xae\xfc\xcd\xdd\x50\x0d\x80\xc7\xd4\x93\x69\xd9\x9e\x4b\x9d\x99\x14\x6c\x48\xec\x56\x6e\x47\x94\x9f\x9c\x07\xed\x27\xe7\xe1\x96\x6d\x5d\x3f\x39\xc5\x8b\xfe\x5f\x34\xa3\x07\xec\x92\x51\x14\x9d\x39\xf4\x4d\xee\x47\x78\x81\x65\xa4\x99\xfc\x82\xba\xf1\x34\xc3\x69\xf5\x23\xcf\x45\x4d\x33\x39\xf9\x20\x48\xcc\xd1\xb2\xed\xe9\xa3\xb7\xbb\xf4\x93\x61\x3b\x6a\x5c\x5f\x15\x83\xdb\xd2\x20\xc4\x2a\x5a\x53\xed\x52\xc9\xee\x2c\x8d\x8b\x7b\x0d\x7e\x4e\x8d\xfb\x2b\x0a\x3b\xe4\x67\x91\x3d\x0a\x39\x8c\x5f\x65\x65\xf2\x69\xe9\xdd\xbc\x3a\x78\xb1\xe7\x81\x25\x89\x5e\xe2\xab\xef\xbc\xd8\x7b\xf5\x2d\xda\x45\xcc\x75\x77\xe7\xac\x9e\xeb\xe5\xbc\xdc\x07\x5e\xfc\xea\x87\xf8\xd5\x07\x2f\x38\xc6\x32\x7e\xc3\xcf\xcb\x64\x3e\xc5\xe5\xa9\x92\x65\x9a\xf7\xea\xe1\xe6\xd5\xe6\xc6\x0b\x6c\x14\xa0\x91\x7d\xba\xc4\x44\x2f\x4e\x47\x23\x19\xa9\xda\x7e\xb9\xdc\xaa\x08\x39\x6d\x96\x89\x0e\x78\xaf\x1e\x3c\xc4\xf7\xd1\x64\xe9\x40\xfc\xe1\xd5\x3f\xbc\x58\xfe\x05\x18\xef\xd5\x47\x8f\xca\x01\xcd\x9f\x1d\xc5\x2b\x4a\x6e\xb8\x17\x2a\x20\xbd\x13\x3f\x69\x2e\x19\xae\x54\xa8\x9d\x10\xea\xbb\xdd\x67\xf1\x6d\x44\x6d\x01\xed\x5b\x18\x3c\xb8\x38\x97\x30\x13\x0f\x3c\x1b\x01\x37\x86\x38\xe5\x6a\x67\x7c\xe0\x6e\xfc\xf5\x7f\xf9\x6e\x5c\x13\x80\xa7\x53\x3c\x8e\xe8\x59\xfe\x91\x15\x86\x17\xa0\xeb\xcc\xb9\xc2\x21\x4f\x4d\x88\x29\x97\xcb\x38\xba\x65\x4d\x78\x02\x79\x9c\x13\x1b\x47\x54\x0c\xaa\xd4\xb7\xc4\x0d\x41\xe7\x1a\x9e\x4d\x10\x8b\xbe\xbd\x06\x37\x47\xb0\x19\x66\x68\x64\x61\x34\x6a\x7f\xfb\xa4\xf5\x76\x85\x25\xda\x53\x9a\xb0\xb6\x23\x64\x92\x63\x04\xd2\xf1\x73\x80\xfa\x1e\x85\x36\x26\xa1\x34\xd7\xc1\xd5\xd1\xf9\x85\x2c\x1f\xd1\xa0\x32\x15\x46\xbf\x1d\x0c\x76\x0d\xb7\xf5\x2a\x24\x69\xfa\xaa\x2a\xeb\x7a\xcf\x53\x87\xd6\x60\xbb\xb9\xa5\x37\x02\x8d\xf5\x3d\x5f\xe1\x7f\xa1\xa2\xfd\x0a\x22\x11\xc6\x6e\x9a\x3d\x5b\x59\xaa\xc4\x65\x6c\x7d\xdb\xd5\xa7\x02\xc6\x69\xb8\x39\x5c\x8e\x91\x0b\x0d\xde\xf0\xd5\xc0\xb2\xdb\x89\xc4\x7e\x2c\x9e\xc9\x6f\x27\x12\xbb\x8d\x24\x24\x1e\x28\xac\x36\xd3\xc0\xab\x8c\x3c\x4e\x58\xa3\x0f\x3e\x09\x13\x8d\x57\x9f\x14\x1a\x54\x92\x29\x8f\x0d\xd6\xc5\xaa\x58\x15\xe8\x95\x57\x97\xe3\x74\x43\xbf\xa0\xd6\x20\x0d\x17\x88\x6f\x2f\x50\x6c\xfb\x25\xa8\xc2\x2c\xd6\x80\x0a\x0a\x95\x72\x2d\xb7\xc4\x1d\xe1\x6d\x65\xd6\xba\x42\xe1\x6d\xb5\x9c\x74\xd9\xd5\xb3\x65\x5b\x81\x40\xed\x71\x02\x0b\x70\xc4\x13\xd5\x53\x3f\xe5\x6d\x8b\xd9\x46\x98\x91\xf7\xac\xdb\x52\xde\x92\x30\x95\x95\xc1\xe6\x59\xc7\x6e\x27\x8f\xd8\x8e\x71\xb8\x72\x59\xe9\xa0\x9a\x71\x63\xa8\x97\x4e\x88\x2a\x01\xbe\x9c\x69\x79\x4d\xb7\xfe\x10\xea\xf3\xb3\xa8\xcf\x2d\xd4\x13\x5a\x38\xa8\xcd\xca\xa0\x05\xb9\x72\x2b\xb3\xca\x1d\x2b\x52\xce\x98\x6b\x35\xbe\xc1\x99\xd5\x68\x4d\x40\x4f\xcf\x20\x8f\xc2\x14\x6a\x45\xcb\x6a\x78\xb2\xb4\xd6\x5e\x60\x46\x26\x7e\x92\xcd\x42\xda\xaf\xe4\x78\xc0\xe6\x56\xf4\x9b\x09\xbd\x51\xff\xc3\x2f\x27\xc4\xa3\x66\x28\xe2\xc8\x6c\x01\x06\x4d\x6f\x1f\xb8\xd2\x77\x6f\xe2\xee\xfb\xe4\x95\xbe\x7b\xd7\x8f\xbc\xd2\xd5\xea\xed\x94\x46\x74\xba\x96\x47\xc7\xff\x76\x7f\xff\xdf\x6f\xea\xf2\x58\x25\xe2\x07\x7e\x38\xa4\xc5\xee\xcf\x7f\xfc\x9e\xe5\x3c\x2d\xc2\x87\xcd\x97\xc9\x17\xef\x36\x49\x98\xec\x8f\xc5\xa7\xf0\xef\x75\x98\xf3\xc3\xff\x0e\x00\x00\xff\xff\xde\xbc\xc4\x7a\x09\x78\x01\x00") + +func pkgUiStaticReactStaticJsMainBd8c49dcChunkJsBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactStaticJsMainBd8c49dcChunkJs, + "pkg/ui/static/react/static/js/main.bd8c49dc.chunk.js", + ) +} + +func pkgUiStaticReactStaticJsMainBd8c49dcChunkJs() (*asset, error) { + bytes, err := pkgUiStaticReactStaticJsMainBd8c49dcChunkJsBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/static/js/main.bd8c49dc.chunk.js", size: 96265, mode: os.FileMode(436), modTime: time.Unix(1589211666, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _pkgUiStaticReactStaticJsRuntimeMain5db206b5Js = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x54\xdf\x8b\xe3\x36\x10\x7e\xef\x5f\x91\xb8\x20\x34\x64\x56\xeb\x2c\xbd\x52\xe2\x1d\xfa\x5e\x7a\x5c\xe9\xb5\x4f\xc6\x1c\x8a\x23\x27\xbe\x2a\x92\x18\xcb\x77\x5d\xbc\xfe\xdf\x8b\x9c\xd8\xb9\xdb\xde\xc2\x41\x20\x63\x69\x7e\x7c\xf3\x7d\xa3\x59\x37\xbd\xab\x63\xeb\x9d\x34\x30\xcc\xf6\x8a\x25\xc3\xd0\x78\x96\x9f\x34\xaf\x1c\x5a\xd4\xc4\x65\x5e\x61\x20\x2e\xb7\x15\x36\xc4\xe5\x43\x85\x35\xe5\xd8\x51\x59\x15\xf5\xa3\x56\xd6\xb8\x63\x3c\x15\xf5\x66\x03\x96\x74\x59\x57\xf8\x6e\xff\xd1\xd4\x51\x05\xf6\xd1\xc7\xa7\x60\xd4\x49\x77\xef\x3e\xbb\x3f\xd8\x07\xc3\xf1\x49\xd5\xda\x5a\xe9\xd1\x82\x10\xbe\xb4\x95\x10\x9d\x0a\x7d\x77\x92\xe9\xa3\xcc\x2b\xc0\x64\x50\x5e\x24\x1c\x6e\xd5\xba\x55\x80\xef\x4a\x19\xd0\x81\x10\xd2\x94\xae\xa2\x50\xba\x0a\xa6\x0c\xad\x10\xad\x64\x28\xba\x19\x29\x74\xaa\x3b\xb5\x4d\x94\x20\xa1\x60\x13\x7b\x76\xab\x7e\x42\xa0\x74\x08\xf6\x49\xf6\xd8\x3c\x3f\x97\x15\x60\x94\x30\x2e\xd4\x44\x79\x63\xc6\x20\x53\x5e\xf0\x63\x3f\xe7\xe4\xcd\xe6\x76\x1b\xa9\x2f\xb9\x42\x47\xeb\x1c\x35\x6d\x0b\xfd\x18\x67\x3f\x9d\xfc\x92\x4f\xa0\x58\xea\xaa\xc8\xd7\x44\xbe\x0c\x95\x10\xd2\xd1\x7a\x0b\xa3\x13\x42\xf6\xaa\x0b\xb6\xad\x8d\xe4\xbb\x3b\xdc\x02\x1a\xb2\xd2\xaa\x8e\x62\x22\x07\xc6\x2b\x64\x33\x4e\x1a\xd1\x30\xa2\xa7\x61\xbb\xcb\x47\xec\x93\x26\x0b\x60\x9b\xb4\x6c\x1b\xe9\x4a\xae\xe0\x1a\x94\x6c\x65\xfe\x0d\x9e\x63\x57\x5c\xb0\xa6\x23\x1a\xda\x1d\xa3\xdd\xad\xb7\x78\xbd\xdc\x0d\xe3\x38\x93\x63\x52\xd0\xc4\x70\x9c\x63\x31\xe2\xcd\xb6\x80\x51\xd9\xd4\xed\x72\x36\x5a\x75\x26\x83\x56\xd5\xe4\xd0\xaa\x03\xdd\xa6\x0d\x19\x23\x0c\x56\xf9\x64\xc2\xf3\xf3\x55\xda\x83\x69\x5a\x67\x66\x41\x27\xb7\xc1\xb8\xfe\x6c\x58\xef\xad\xd9\xad\x73\x3c\x9a\xb8\x8b\x23\x8c\x68\x15\xd3\x97\xd3\x9b\xf5\xee\x12\x7d\xc8\xd6\x44\x69\x3c\x7c\xb3\x7a\xff\x74\xde\x7b\x2b\xc4\xe5\x5f\x45\xff\x3e\x72\xeb\x8e\x7f\xe9\xa3\x10\xaf\x95\xfc\xbf\x2f\x0e\x9f\xb4\xed\xcd\x2e\x7b\xeb\x0f\xbd\x35\xd9\x08\xf8\x5a\x70\xf6\xe1\x83\xe9\xae\x6e\x73\xd8\x3a\xbf\xe0\x8d\x5f\xf5\x3f\xa9\xb2\x15\x9c\x66\x95\xac\x34\x00\xf8\x8b\xe0\x59\x22\x53\xb4\x8d\xfc\x29\xdd\x66\x7e\x2a\x95\xd1\xd2\x94\x11\x22\xfd\xd4\xad\xd4\x2d\xea\xa2\xe6\x15\x5d\xcd\x46\x47\x23\x5d\x6f\x2d\xa4\x7c\x56\xb1\x8c\xaf\x61\x8f\x98\x1d\x4c\xa3\x7b\x1b\xb3\x97\x9c\x5f\xda\x30\x23\xe0\xc3\x84\xa8\x9b\x88\xc9\xd6\x0b\x20\x58\x96\x45\x7a\xa8\x06\xac\x3a\xc8\x88\x0e\x97\x7e\x19\x86\x2f\xc6\x68\x54\xfb\xd6\x1d\x26\x5c\xe8\x60\x79\x7e\x31\x91\xe4\xbe\x12\x35\xe5\x64\x7a\xd1\xed\xaf\x8b\xc7\x2d\xab\xba\x62\x1f\x77\xdf\xb8\x5c\x66\x38\xe1\x62\xcc\x74\x86\x0c\xc8\xa9\x9c\x7f\xa1\xc9\xd5\xf1\xbb\x36\x4d\x0a\x48\x39\x02\x65\xea\x3e\x9b\xa8\xd7\x14\x4f\x6d\xa7\x3e\x9b\x7d\xd0\xf5\x3f\xbf\x75\xde\x85\x23\xeb\x70\x7a\xe5\x38\x2d\x18\x0c\xa4\x2f\x7b\x67\x22\x45\x43\x71\xf9\x24\x46\x4d\x5a\x75\xd3\x0e\xb8\x2c\xb1\x54\xa1\x49\x2b\xf1\xb6\x70\x9b\xcd\x06\x58\xea\xb2\xa9\x60\x02\xd0\x52\x28\xd2\xc2\x92\x65\x05\xc5\x0f\xf7\xf7\x3f\xae\x3a\xdf\x73\x6d\xde\xea\x10\x5a\x77\xfc\xfb\xcf\xdf\x89\x7b\x17\xdb\xb3\xb9\x3b\xeb\xd6\xa9\x37\x87\xfd\x43\xfe\xf3\xfe\x8d\xfa\xd8\xa9\xb3\x0e\xff\x05\x00\x00\xff\xff\x5b\xf1\xe9\xe4\x10\x06\x00\x00") + +func pkgUiStaticReactStaticJsRuntimeMain5db206b5JsBytes() ([]byte, error) { + return bindataRead( + _pkgUiStaticReactStaticJsRuntimeMain5db206b5Js, + "pkg/ui/static/react/static/js/runtime-main.5db206b5.js", + ) +} + +func pkgUiStaticReactStaticJsRuntimeMain5db206b5Js() (*asset, error) { + bytes, err := pkgUiStaticReactStaticJsRuntimeMain5db206b5JsBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "pkg/ui/static/react/static/js/runtime-main.5db206b5.js", size: 1552, mode: os.FileMode(436), modTime: time.Unix(1589211666, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -560,7 +811,7 @@ func pkgUiStaticVendorBootstrap413CssBootstrapGridCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-grid.css", size: 37644, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-grid.css", size: 37644, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -580,7 +831,7 @@ func pkgUiStaticVendorBootstrap413CssBootstrapGridMinCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-grid.min.css", size: 28977, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-grid.min.css", size: 28977, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -600,7 +851,7 @@ func pkgUiStaticVendorBootstrap413CssBootstrapRebootCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-reboot.css", size: 4896, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-reboot.css", size: 4896, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -620,7 +871,7 @@ func pkgUiStaticVendorBootstrap413CssBootstrapRebootMinCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-reboot.min.css", size: 4019, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-reboot.min.css", size: 4019, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -640,7 +891,7 @@ func pkgUiStaticVendorBootstrap413CssBootstrapMinCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap.min.css", size: 140936, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap.min.css", size: 140936, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -660,7 +911,7 @@ func pkgUiStaticVendorBootstrap413JsBootstrapBundleJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/js/bootstrap.bundle.js", size: 212345, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/js/bootstrap.bundle.js", size: 212345, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -680,7 +931,7 @@ func pkgUiStaticVendorBootstrap413JsBootstrapBundleMinJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/js/bootstrap.bundle.min.js", size: 70966, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/js/bootstrap.bundle.min.js", size: 70966, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -700,7 +951,7 @@ func pkgUiStaticVendorBootstrap413JsBootstrapMinJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/js/bootstrap.min.js", size: 51039, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap-4.1.3/js/bootstrap.min.js", size: 51039, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -720,7 +971,7 @@ func pkgUiStaticVendorBootstrap3TypeaheadBootstrap3TypeaheadMinJs() (*asset, err return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js", size: 11273, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap3-typeahead/bootstrap3-typeahead.min.js", size: 11273, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -740,7 +991,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsCssBootstrapGlyphiconsCss() (*asset, e return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.css", size: 14523, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.css", size: 14523, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -760,7 +1011,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsCssBootstrapGlyphiconsMinCss() (*asset return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css", size: 11830, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/css/bootstrap-glyphicons.min.css", size: 11830, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -780,7 +1031,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaBrands400Eot() (*ass return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-brands-400.eot", size: 98620, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-brands-400.eot", size: 98620, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -800,7 +1051,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaBrands400Svg() (*ass return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-brands-400.svg", size: 507478, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-brands-400.svg", size: 507478, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -820,7 +1071,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaBrands400Ttf() (*ass return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-brands-400.ttf", size: 98384, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-brands-400.ttf", size: 98384, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -840,7 +1091,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaBrands400Woff() (*as return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-brands-400.woff", size: 63712, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-brands-400.woff", size: 63712, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -860,7 +1111,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaBrands400Woff2() (*a return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-brands-400.woff2", size: 54420, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-brands-400.woff2", size: 54420, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -880,7 +1131,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaRegular400Eot() (*as return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-regular-400.eot", size: 31156, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-regular-400.eot", size: 31156, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -900,7 +1151,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaRegular400Svg() (*as return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-regular-400.svg", size: 107199, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-regular-400.svg", size: 107199, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -920,7 +1171,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaRegular400Ttf() (*as return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-regular-400.ttf", size: 30928, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-regular-400.ttf", size: 30928, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -940,7 +1191,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaRegular400Woff() (*a return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-regular-400.woff", size: 14712, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-regular-400.woff", size: 14712, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -960,7 +1211,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaRegular400Woff2() (* return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-regular-400.woff2", size: 12220, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-regular-400.woff2", size: 12220, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -980,7 +1231,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaSolid900Eot() (*asse return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-solid-900.eot", size: 102152, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-solid-900.eot", size: 102152, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1000,7 +1251,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaSolid900Svg() (*asse return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-solid-900.svg", size: 378215, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-solid-900.svg", size: 378215, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1020,7 +1271,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaSolid900Ttf() (*asse return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-solid-900.ttf", size: 101932, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-solid-900.ttf", size: 101932, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1040,7 +1291,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaSolid900Woff() (*ass return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-solid-900.woff", size: 48704, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-solid-900.woff", size: 48704, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1060,7 +1311,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsFontawesomeFaSolid900Woff2() (*as return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-solid-900.woff2", size: 38784, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/fontawesome/fa-solid-900.woff2", size: 38784, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1080,7 +1331,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsGlyphiconsGlyphiconsHalflingsRegu return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/glyphicons/glyphicons-halflings-regular.eot", size: 20127, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/glyphicons/glyphicons-halflings-regular.eot", size: 20127, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1100,7 +1351,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsGlyphiconsGlyphiconsHalflingsRegu return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/glyphicons/glyphicons-halflings-regular.svg", size: 108738, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/glyphicons/glyphicons-halflings-regular.svg", size: 108738, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1120,7 +1371,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsGlyphiconsGlyphiconsHalflingsRegu return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/glyphicons/glyphicons-halflings-regular.ttf", size: 45404, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/glyphicons/glyphicons-halflings-regular.ttf", size: 45404, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1140,7 +1391,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsGlyphiconsGlyphiconsHalflingsRegu return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/glyphicons/glyphicons-halflings-regular.woff", size: 23424, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/glyphicons/glyphicons-halflings-regular.woff", size: 23424, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1160,7 +1411,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsFontsGlyphiconsGlyphiconsHalflingsRegu return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/glyphicons/glyphicons-halflings-regular.woff2", size: 18028, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/fonts/glyphicons/glyphicons-halflings-regular.woff2", size: 18028, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1180,7 +1431,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsMapsGlyphiconsFontawesomeCss() (*asset return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/maps/glyphicons-fontawesome.css", size: 51062, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/maps/glyphicons-fontawesome.css", size: 51062, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1200,7 +1451,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsMapsGlyphiconsFontawesomeLess() (*asse return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/maps/glyphicons-fontawesome.less", size: 53867, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/maps/glyphicons-fontawesome.less", size: 53867, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1220,7 +1471,7 @@ func pkgUiStaticVendorBootstrap4GlyphiconsMapsGlyphiconsFontawesomeMinCss() (*as return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/maps/glyphicons-fontawesome.min.css", size: 42307, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/bootstrap4-glyphicons/maps/glyphicons-fontawesome.min.css", size: 42307, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1240,7 +1491,7 @@ func pkgUiStaticVendorEonasdanBootstrapDatetimepickerBootstrapDatetimepickerMinC return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css", size: 7771, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css", size: 7771, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1260,7 +1511,7 @@ func pkgUiStaticVendorEonasdanBootstrapDatetimepickerBootstrapDatetimepickerMinJ return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js", size: 48881, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js", size: 48881, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1280,27 +1531,27 @@ func pkgUiStaticVendorFuzzyFuzzyJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/fuzzy/fuzzy.js", size: 5669, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/fuzzy/fuzzy.js", size: 5669, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _pkgUiStaticVendorJsJquery331MinJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\xbd\x7d\x97\xdb\xb6\xf1\x28\xfc\xff\xf3\x29\x56\xac\x7f\x0c\xb0\x82\xb8\x92\xd3\xe4\xde\x52\x0b\xeb\x38\xb6\x93\x3a\x2f\x4d\x1a\xbb\x49\x5a\x8a\xce\xe1\x8a\x90\xc4\x98\x02\x14\x12\x5a\xed\x46\x64\x3f\xfb\x73\x30\x00\x48\x90\xa2\x9c\xb4\xf7\xde\xe4\x78\x45\x82\x78\xc7\x60\xde\x30\x33\xb8\xb9\x1e\x5d\xfd\xf2\xf7\x03\x2b\x1e\xaf\xee\x3f\x0e\x3e\x0e\x66\x57\xd5\x15\x5a\xe1\xab\x2f\xdf\x5c\x7d\x2e\x0e\x3c\x4d\x64\x26\xf8\x55\xc2\xd3\x2b\x21\xb7\xac\xb8\x5a\x09\x2e\x8b\xec\xee\x20\x45\x51\x5e\x55\x57\xbf\xfc\xaa\x8a\x06\xa2\xd8\xdc\xe4\xd9\x8a\xf1\x92\x5d\x5d\xdf\xfc\x7f\xa3\xf5\x81\xaf\x54\x41\xc4\x88\xc4\x27\xef\x50\xb2\xab\x52\x16\xd9\x4a\x7a\x73\x4f\xdc\xfd\xc2\x56\xd2\xa3\x54\x3e\xee\x99\x58\x5f\xed\x44\x7a\xc8\x99\xef\x5f\xf8\x10\xb0\x87\xbd\x28\x64\xb9\xe8\xbe\x52\x16\xa4\x62\x75\xd8\x31\x2e\x17\x12\x31\x32\x9a\xe2\xb0\x6d\x15\x9f\xb2\x35\x1a\xb5\x59\xb0\xdc\x16\xe2\x78\xc5\xd9\xf1\xea\x55\x51\x88\x02\x79\x66\xcc\x05\xfb\xf5\x90\x15\xac\xbc\x4a\xae\x8e\x19\x4f\xc5\xf1\xea\x98\xc9\xed\x55\x72\x65\x4b\x7a\x78\x5e\x30\x79\x28\xf8\x95\x44\x0c\xd7\x21\xfc\x45\xde\x81\xa7\x6c\x9d\x71\x96\x7a\x23\xdb\x5d\x5d\x7e\xa1\x7f\x42\xb9\xcd\x4a\xf2\x81\x69\xb8\x4f\x8a\x2b\x4e\xa3\x98\x14\xce\x48\x48\x46\xbf\x85\x49\x08\x36\x4c\x7e\x57\x08\x29\x54\xdd\xdf\xae\x89\xa0\x3c\x28\xd5\x04\x93\x84\xf2\x60\x25\xf8\x2a\x91\xa4\xa4\x3c\xd8\x1f\xca\x2d\x39\x50\x1e\x64\x3c\x65\x0f\xdf\xae\x49\x4e\x4f\x35\x59\xd1\x3c\x90\xe2\x8d\x2c\x32\xbe\x21\x6b\x9a\x07\xdb\xa4\xfc\xf6\xc8\xbf\x2b\xc4\x9e\x15\xf2\x91\xec\xe9\xba\xfd\x9e\xd2\x7d\xb0\x4a\xf2\x1c\xe9\xa6\x31\xd9\xaa\x2a\x36\xd4\x76\xfe\x8a\x21\x89\x4f\x7a\x12\x3c\x9b\xd8\xae\x92\xf4\x7d\x8f\x1f\x76\x77\xac\x68\xa7\x42\x06\x5c\xa4\xec\xed\xe3\x9e\xd5\xe4\x71\xb0\xa2\x2b\x7e\xc8\xf3\x11\x95\xbe\x2f\x29\xa5\x32\xd0\xb3\x56\x93\x7b\x7a\x52\x75\x84\xa3\x29\x29\x8b\x95\xfa\xe1\xe2\x1b\x58\xf8\x70\x34\xad\xe7\x4d\x55\x3b\x35\xa5\x84\xe3\x93\x9a\xc7\x8c\x08\x8a\x24\x95\x55\x55\xe0\x60\x55\xb0\x44\xb2\x57\x39\x53\x13\x8a\xbc\x72\x55\x64\x7b\xb5\x8a\xd9\x1a\x89\x40\xb2\x07\x49\x19\xe1\x78\x2d\x0a\x94\x5d\x65\xfc\xea\x1e\xf3\x28\x8b\x7d\x1f\x89\x28\x8b\xa9\x7a\xc6\x73\x19\x6c\x59\x92\x06\xc9\x7e\xcf\x78\xfa\x62\x9b\xe5\x29\x12\x38\xd8\x27\x05\xe3\xf2\x6f\x22\x65\x41\xc1\x76\xe2\x9e\xd9\x2f\x75\xd3\xab\x07\x05\x79\xce\x00\x29\x65\x0b\x36\xf6\xbc\xf0\x0c\xb6\x59\x55\x0d\xcc\x25\x5b\xe4\xd1\x4a\x2f\x06\xc3\x71\x55\xd9\x62\xa1\xfd\x5e\xab\xe1\xde\x51\x0f\x76\xaa\x47\x8e\xb4\x0b\x61\xb6\x69\x76\xbc\x3a\x06\x6b\x05\x14\x99\x84\x2f\x35\x79\x4b\x6f\xde\x45\xcb\x72\x79\xf8\xfc\xd5\xe7\x9f\x2f\x1f\x9e\x4f\xe3\x71\xd5\x7b\x7f\x72\xb3\x99\xab\x62\xf4\x18\xec\x2d\xec\xd1\x93\xde\xe1\xa1\x6d\x72\x25\x78\x29\x8b\xc3\x4a\x8a\x22\x3c\x92\x9c\xf1\x8d\xdc\x86\x53\x22\xc5\xf3\xa2\x48\x1e\xdb\x2d\xd8\x74\x46\xe8\xf1\xa8\xfd\x80\x6b\xb2\x61\xb2\xb3\x4d\x7b\x93\xe5\x66\x0e\xd9\xed\x74\xa1\x9e\x22\x36\x56\x3f\x81\x6e\x2c\x0e\x75\x5a\x5c\x13\x05\xfc\x6f\x64\xb2\x7a\xdf\xa9\x52\x4d\x91\xa4\xc7\x60\xc7\x8a\x0d\x83\xaa\x02\xa7\xd3\x08\x13\xd6\x6e\xe9\x60\x5f\xb0\x7b\x0d\xf7\x14\x76\xac\xac\x09\x4b\x56\xdb\xa1\x3e\x1e\x03\xf5\x05\x2a\x24\x0c\xd7\x64\x97\xec\x87\xb2\x41\x83\x4d\xcf\xd0\x31\xd8\x25\x7b\xd4\xc5\x06\x00\xb8\x26\x3b\x33\x23\x26\x5c\x2d\x13\xc6\x35\x81\x7d\x3e\x30\x91\xbd\x8a\x85\x82\xcf\xfc\x51\x57\x9d\x14\x1b\x40\x20\xa5\xaa\x60\x9d\x15\xa5\xbc\x54\x01\xfb\x15\x4d\x71\x4d\xf2\xe4\x83\x59\x26\x33\x5c\x13\xf6\xeb\xc0\xbc\x3a\x2b\x41\x38\x1d\xb3\x31\x82\x65\x0a\xa7\xed\xa4\x76\xfb\xc9\x9f\xd1\xa9\xef\xf3\x5b\xb9\x88\x60\xe1\x78\x1c\x87\x51\xac\xaa\xe7\xe9\xc5\x51\x36\xab\x52\x55\xe7\x0b\xa8\x17\x3e\x2c\x49\x29\x0a\x19\xf2\x40\xfd\x90\x72\x0f\xd3\xc6\x03\xfd\x50\x93\x63\xc0\x1e\x24\xe3\x29\x85\x9d\x60\x9e\x9d\xf6\xd4\x70\x00\x87\x90\x82\x64\x44\x90\x84\x36\x93\x18\x4d\xe3\xaa\x3a\xd5\xa4\xa4\x33\x72\x68\x93\xed\xb0\x73\x3a\x9a\xcd\x15\x02\xf1\xee\x84\xc8\x59\xe2\x6c\xe0\xc4\xf7\x51\x4e\x93\x4e\x65\xa5\xa9\x6c\x3c\xc6\xe4\x0c\x0f\x24\x55\xb5\x41\x09\xae\x2a\x94\xd0\x53\x8d\x49\x49\x29\x3d\xf8\x3e\x4a\x34\x38\x96\x93\x09\x9e\x97\xb7\x87\xb9\x2a\x9d\xad\x91\xc6\x9a\x88\x75\xaa\xc7\x80\xcd\xa4\xc2\x66\x0c\x73\x9a\x44\x32\x26\xc9\x88\x52\x54\x50\x16\xc9\x18\xab\x3e\xf9\x7e\xe1\xfb\xe8\x18\x64\xe5\x77\x79\x92\x71\x3d\xb9\xa8\x50\x0d\x67\x14\xb6\x6e\x90\x95\xf0\x8b\x0a\x8c\xf1\x02\x65\x0b\x94\xd1\xd1\x4c\x51\x1e\xdf\xef\x66\xe0\x78\xc1\xd5\x12\x86\xf0\xad\x5f\x27\x7c\x3d\xd5\x44\x75\x83\xda\x45\x40\x39\x11\xa4\xc0\x38\xbc\x17\x59\x7a\x35\x1d\x51\xaa\xba\x03\x59\x0a\xdc\x40\x4e\xd2\xae\x1a\x3a\xb1\x87\x7d\xc2\x53\x11\x1a\x4a\xed\x8d\x91\x41\x41\xe3\x6f\x12\xb9\x0d\x0a\xf5\x71\x87\x30\x0e\x0a\xb6\xcf\x93\x15\x43\x37\xcb\x97\x37\x1b\xe2\x79\x98\x64\xe5\xf7\x2c\x49\x1f\x15\xf5\x60\x8a\xda\x77\xc0\xb8\xcf\x09\xa8\xad\xcc\x85\xd8\xbb\xb0\x58\x93\xce\x98\xce\xb7\x01\xe1\xa6\xcf\x23\x34\x52\xa8\x3c\xd2\xeb\x7a\xa5\xf3\xc7\xde\x88\xd2\x06\x8f\xab\xf9\x1f\x21\x49\x33\xf5\x3c\x84\xf6\x11\xa7\x6b\x8b\x05\x3c\x07\xd2\x3d\xec\xfb\xd2\x05\x7d\xec\xfb\x86\x54\x73\x4c\x29\x4d\xb1\xea\xe7\xab\xdd\x5e\x3e\x5e\xea\xe7\xdc\x81\x0c\xd3\xe1\x99\xed\xf9\xb4\x26\x9b\x5c\xdc\x25\xf9\xab\xfb\x24\xef\x14\xdd\xc1\xa4\xf4\xf0\xa0\xa2\x2f\xc0\xb4\x90\x82\x4e\x15\x35\x7d\xa1\xc6\x73\x52\x0d\x70\xca\xcc\xde\x98\x17\xb7\x7c\x5e\x68\x58\x1d\xcd\x80\xb2\xeb\x59\x88\x8a\x98\x14\x44\xfd\x60\x7c\x57\xb0\xe4\x7d\xcd\xf2\x92\x5d\xa9\xd2\x85\xee\xde\xef\x96\xb0\x50\xc2\x6a\x22\x8b\x6c\xf7\x21\x32\xe2\x79\x21\x52\x74\xb7\x05\x8e\xb7\x0a\x30\x14\xce\x7e\xcf\x7a\x84\xaa\x1d\x98\x62\x20\xa2\x78\xde\x61\x50\x98\xef\xa3\x17\x86\x33\x52\xe3\x5d\x58\xba\xc2\x89\x57\x02\xff\xe4\x52\xef\x88\xc5\x21\xc3\x61\x69\x16\x89\x30\x8c\x09\xaf\x49\xc6\xcf\xdb\x74\x48\x80\xee\xb5\x5c\x4c\x66\xe1\xc1\xc2\x81\xe2\x51\x6a\x02\x4d\xf5\xba\xaa\xa6\x4c\x77\x77\x2c\x2d\x46\x2a\xe8\x94\x64\xe7\x8b\xc0\xa2\x6c\x3c\x8e\xa9\x8c\x8a\x66\x54\x36\x0f\xcd\x08\xab\xc9\xa6\x60\xfb\xb3\x5e\xd9\x06\x0a\x92\x29\xfe\x54\xd0\x29\x49\x9a\xba\x49\x49\x47\x7c\x2e\x6e\x93\xb9\x18\x8f\x31\x2a\xe8\x48\x22\x16\x89\x98\x08\x8c\x47\x94\x96\xbe\x9f\x01\xee\x87\xc4\x66\x63\x67\x7d\x6a\xd9\xf2\x6e\x80\x7c\xe9\x94\x94\x34\x8a\x1b\xa8\x02\xb0\x68\xc7\x23\x6e\x0b\x68\xce\x60\xbf\x8c\xda\x36\x09\x57\xbb\x4b\x53\x1b\x94\xe1\x79\x03\x53\xc2\x20\xc3\xdf\x2b\x60\x11\x8f\xa1\xa5\x51\x4c\x80\x49\x39\x64\x69\x38\x23\xe5\x61\xaf\x44\x8d\x70\x5b\x63\x32\xc0\xac\xbd\x79\xdc\xdd\x89\x1c\xb0\xea\x9a\x47\xfa\x2d\xc8\x24\x2b\x12\x29\x0a\xc5\x4a\xf6\x93\x30\x31\x2c\x84\xf7\x99\xa6\x1b\x57\x7f\x03\xbe\xf9\x4a\x33\xe2\x57\x9f\x5b\x36\x12\xa0\xe5\xea\x65\x22\xd9\xd5\xf7\x6c\xf3\xea\x61\x6f\xf0\x8a\xc6\x58\xa6\x61\x0f\x28\x9d\x44\xde\x95\x87\x7b\x82\x46\x1e\x35\x08\xc9\x1b\xcb\xb1\x17\x7b\x31\x95\x81\x14\x5f\x8b\x23\x2b\x5e\x24\x25\x43\xb8\xc6\x2d\x2f\xfd\xa2\xa5\xee\xa3\x91\x12\xc4\xf4\xb4\x7b\x6a\x0a\x7d\x9f\xb5\xd4\x5e\xb1\xb7\x16\x7b\x6c\x10\xc3\xbe\x3f\x7a\x84\x1f\xe4\x25\xaa\xcb\x1e\xa5\x94\x57\xd5\x54\xed\xe2\xaa\xb2\x52\x81\x2b\x29\xc8\x67\x53\xdf\x97\x93\x99\x5e\x1e\xe0\x66\x5f\xd1\x01\xec\x6a\x69\x32\x29\xc9\x81\xe4\x64\x45\xd6\x64\x4f\x52\xb2\x25\x1b\xf2\x48\xee\xc9\x8e\x3c\x90\x3b\xea\x95\xd9\x6f\xbf\xe5\xcc\x1b\xcf\xae\x15\x3a\x57\xf3\x45\x8e\xae\x34\xf5\x96\x4e\xc9\x0b\x3a\x25\xaf\x68\xc2\x10\x26\xef\xf5\xcf\x1b\xfd\xf3\x72\x98\x77\x66\xaa\xf3\xbe\x8f\xd6\x74\x34\xc5\x64\x5a\x93\xbf\xd1\x53\xdd\x97\x9f\x9e\xab\x8d\xf1\x0b\x7d\x1e\xec\xc5\x9e\xfc\xaa\x7e\x95\x18\xf6\xb5\x7d\xf8\x2b\x7d\x6e\xa4\xb5\x6f\xe9\xa5\xcd\x3b\x25\x0e\x80\xf3\xdb\x62\xce\x35\xd6\x64\x11\x8f\x55\x17\xb0\x45\x0e\x66\xc2\x27\xb3\x9a\x7c\x47\xbd\xd5\x96\xad\xde\xb3\xb4\x2a\x59\xce\x56\x92\xa5\x55\x52\x3e\xf2\x55\x95\x1c\xa4\x58\x8b\xd5\xa1\x84\xa7\x7d\x9e\x3c\x56\x20\xa8\x8b\xbc\xac\x52\xb6\x66\x45\x95\x66\x65\x72\x97\xb3\xb4\xda\x66\x69\xca\x78\x95\x95\xbb\x64\x5f\xe5\x42\xec\xab\xdd\x21\x97\xd9\x3e\x67\x95\xd8\x33\x5e\x15\x2c\x49\x05\xcf\x1f\x2b\x23\x1a\xa7\x55\xb9\x12\x7b\x96\x7a\xe4\x1b\xea\x45\xcb\xe5\xc3\xd3\xe9\x72\x29\x97\xcb\x62\xb9\xe4\xcb\xe5\x3a\xf6\xc8\xf7\xd4\x43\x8b\x70\xb9\x5c\x2e\x83\x2a\x5a\x2e\x8f\x93\xb8\x8a\xde\x2d\xa7\x93\xe5\xf2\x21\x99\xc6\x78\xec\x91\xd7\xd4\x5b\x2e\x23\x6f\xfc\xcd\xd8\xbb\x46\xde\xf8\xfb\xb1\x87\xd1\x22\x34\xef\xd1\xf5\xbb\x27\xd5\xe8\xdf\xf1\x82\x62\x93\xb2\x08\x3f\x42\x6d\x8d\xef\xd4\xef\x47\x31\xbe\xc6\x1f\x55\x4b\xaf\xff\x61\xe9\xa9\x2f\x4b\xaf\x32\xf5\xe2\xca\xd4\xb2\x5c\xc6\x1e\xf9\x91\x7a\x61\xdb\xe0\x72\x89\x10\xfa\xcf\xab\xc6\x55\xff\x0b\xc2\xd1\x72\x19\xc7\x95\x37\x7e\x3d\xf6\xf0\x35\xae\x82\x6b\xbc\x5c\xaa\xa6\xc9\x13\xaa\x60\x51\x6f\x5b\xf4\xcd\xd8\x1b\x7b\xc4\xdb\x78\x98\x7c\xe6\xa6\x7b\xef\xa0\x8f\x63\xa8\xf8\x9d\xa9\x34\xc6\xb6\x15\x7c\xad\xc7\x30\x7e\x62\x0a\x7f\x3e\x50\xf8\x9a\xe8\x1f\x0f\x93\x9f\x87\x3e\xa3\xe8\xd9\xf8\xdf\xaa\x8b\xdf\x8c\x3d\xdc\x64\xfd\xad\x93\x95\xda\xac\xef\x96\xcb\xf8\xa3\xa5\x17\x5f\x2f\xdc\xd9\x83\xb6\x7f\x72\x4b\xfc\x88\xc9\x3f\xfa\x8d\x7d\x3f\xf6\x9e\x78\x98\xfc\x40\x4f\xaf\x5f\x86\x9d\x6f\x7f\x32\x53\xef\x61\xf2\xe2\xeb\xe7\x6f\xde\x74\xbf\x2e\x97\x41\xfb\xfd\xed\xf3\x2f\xba\x5f\xf5\xa7\x2a\xba\x8e\xd5\xe7\xe7\x6f\xdf\x7e\x1f\xf6\xda\x7d\x8d\xc9\x77\x6f\x5e\xfd\xe3\xe5\xb7\xfd\x0f\x3f\x62\xf2\xe2\xaf\xaf\xbf\xee\x75\x26\x44\x00\xd5\x20\x1c\x55\x4a\xfc\xa9\xb8\xdc\xaa\x7f\x13\xf5\x82\x27\x68\xa5\xc4\xf9\x4a\xac\x27\x0a\x5d\x19\x70\x31\xf3\xc3\xee\x19\xaf\x44\x9a\x56\x08\x45\xe3\x49\x5c\x61\xb4\x5c\xa6\xd7\x98\x57\x2d\xc4\x9a\x0f\xe6\x7d\xb9\x4c\xc7\xb8\xc2\xcd\x64\x02\x68\x78\x99\x87\x89\x12\x19\x7a\x23\x55\x3b\xe1\xbb\xb1\x87\x9f\x98\x2c\x9c\xb1\xb4\x7c\x21\xb8\x64\x0f\xb2\x3f\x36\x55\x9d\x5e\xd8\xb0\xed\x15\xfb\xb5\xda\xc8\x2a\xd7\x23\x6a\x07\xd8\x1d\x03\x5a\x84\x93\xe5\x32\xc5\x0b\xe8\xba\xd3\x31\xb4\xa0\xd1\xbb\x49\x5c\x3d\x31\x5d\xac\xc9\x17\xf4\x46\xf5\x2a\xe3\xfb\x83\x34\x98\xa6\x52\x9d\x49\x0a\x96\x54\x77\x07\x29\x05\xc7\x4f\x6e\x32\xf2\x4f\x7a\xf3\x6e\xbb\x4c\xd5\xe3\xdf\xe9\xcd\xbb\xe8\xdd\x29\x1e\x2f\x4f\xcb\xf2\x7a\x19\xf1\x44\x66\xf7\xec\x6a\x79\xbc\x21\x5f\xea\xda\xfe\x84\x22\x85\x1a\xc6\xb8\x42\xcb\xe3\x18\x57\xcb\xc0\x26\xe0\x27\x37\xe4\x2b\x7a\x13\x8d\xff\x1d\xdf\x90\x7f\x75\xc0\x0b\x36\x5b\xb4\x5c\xa6\xc9\x64\x1d\x9f\x66\xe4\xd3\x1a\x3a\xbe\xa8\xf4\xa8\x70\x15\x40\xa7\x15\x9c\x32\x46\x07\xf9\x0b\xea\x4d\x1f\xbc\xb1\x9c\x7c\xfa\xc9\x27\x1f\x7f\x6a\x09\x7e\xa1\x24\x90\xaa\xe2\x0b\x19\x16\xb7\xd3\x85\x26\xc0\xc1\xba\x10\xbb\x17\xdb\xa4\x78\x21\x52\x86\x8a\x31\x94\xc0\xe1\xe0\xc7\x67\xcf\x66\xd3\xea\x93\x4f\x9e\xfe\xe5\x53\x32\x9b\x3e\xfd\xd8\x2f\xaa\x4f\x3e\xfd\xf8\xa9\x92\xac\x25\xa3\x37\x28\x52\xe8\xef\x61\xb6\x5e\x3e\xfc\xaf\x75\x5c\xbd\x9b\x2c\x96\x29\xae\xde\x4d\x9e\x18\xc4\x68\xbe\x4c\x96\x87\xcf\x3f\xff\xfc\x73\x35\x0b\x37\x1b\xc2\xd9\x30\x45\x92\x0b\x6f\x39\x55\xa4\x95\x2d\xbc\xe5\x61\xbd\x5e\xa7\x5e\xc8\x34\x7d\x41\x53\x32\x99\xe1\xb1\xb7\x5c\x7a\x63\x16\xac\x4c\xef\x9e\x4b\x64\x29\xcb\x64\x86\x1b\x45\x1f\x9a\x7d\x8a\xc7\xde\x95\x17\xea\xec\x35\x29\x98\x2b\x0f\xef\x95\x60\x9d\x31\xba\x63\xe8\x9c\xb3\x1e\x29\x9a\xce\x02\x4b\x44\x14\xc5\x5f\x8b\x62\x07\x2c\x42\x55\x79\x79\x72\xc7\x72\x4f\xd3\x74\x72\x4a\xb3\x22\xf4\x5a\x6d\x99\x47\xb8\x02\x64\x2f\x67\x1b\xc6\x53\xaf\xc6\x73\x59\x3c\x9e\xbe\x36\x2c\xd7\x73\xfa\x57\xcd\xf3\x1e\x03\xd8\x80\xaa\x44\xa9\x38\x25\xf7\xed\x79\xe4\xbe\x5b\x45\x50\xab\x64\x5c\x25\x72\xb5\x55\xbd\xfd\x9a\x9e\xa0\xda\xf0\xb9\xc9\xb4\xe8\x4e\xe9\xaf\xa6\x55\x46\x4c\xab\x12\xe3\x7a\x50\x16\x60\x0e\x6f\x3d\x3f\x6e\xb3\x9c\x29\xd2\x6c\xd8\xe9\xf1\x38\xc6\xf3\x86\x95\x56\xb4\xb9\x6e\x95\x80\x82\x01\xfc\x15\x24\xd3\x75\x09\x52\x1a\x16\x66\xab\x58\x17\xd0\x79\x06\xe2\xc8\x59\xf1\xb2\x65\x54\xe4\xa2\xd5\x99\x86\x7f\x51\x8c\x70\xa1\x00\x34\x8a\x1b\x31\x63\xe4\xa8\x0e\x95\xcc\x39\x1b\x51\xfa\xd6\xf7\xff\xa2\x7f\x66\xf0\x6a\x99\x86\x42\x55\x30\xca\x7c\x1f\x21\x55\x71\xa7\xb1\xaa\x92\xe1\x51\xf1\xea\xa9\xef\xef\x91\xc4\x04\x14\xa7\x29\xd9\x60\x50\x9a\xcf\x4c\xbd\x68\x4d\xbf\x0c\xd8\x03\x5b\x29\x7e\x5c\x31\x26\x82\xae\xa3\x59\x0c\x79\xfe\x42\x55\x5b\xa0\x62\x47\x39\x05\x65\xb5\xd1\xb7\x7e\xf6\xf8\x3a\x45\x02\xe3\x4e\x47\xf2\x20\x4b\x29\xa5\xa2\x49\xd4\xec\x77\x8e\x49\xa1\xa5\xc0\x6c\x8d\x76\xa0\x38\xd9\x0d\x54\xe5\xfb\x0f\x48\x92\x1c\xfb\xfe\xef\xd5\xa3\x3a\xb4\x8e\x9e\xc6\xf6\xbb\x05\xb1\x82\xb8\x5d\x2c\x3f\x7b\x7c\x9b\x6c\xfe\x96\xec\x98\x1a\x19\x81\x1e\xc2\xe0\x3e\x8e\xb1\xef\xf3\x6e\xce\x17\x79\x52\x96\x2a\xaf\x5a\xb3\xe1\x2f\xbf\xdb\x5a\x93\x53\x8d\x86\x14\x75\xb6\x46\x3c\xf8\xb5\x4c\x7c\x7f\xf4\x26\x62\x6a\x47\xc6\xbe\x8f\x46\x8f\x55\x35\x7a\x0c\x24\x2b\x41\xce\xd4\x6b\x01\x6b\xba\xa3\x92\xdc\x53\x36\xb7\x53\x65\x75\x48\x23\x25\x2b\x2b\x98\x51\x75\x77\xb9\x7b\x7c\x42\x2b\xbd\x2e\xcf\xa5\x3e\xad\x61\xc8\xcb\x52\x0f\xe3\xc5\x8a\xae\x1a\xa1\x58\x32\xc2\x19\x0e\x65\x50\xf6\x33\x92\x15\xbd\xc3\xa4\xa4\x68\x4b\x13\xd5\x1d\xcb\xa8\xea\x8d\x50\x4e\x26\x78\x1b\x95\x31\xf5\xfe\xe4\x8d\x57\x6a\x04\xe3\x7b\x86\x54\x0a\x9e\xdf\xd3\x6d\xf0\x8b\xc8\x38\xf2\x88\x87\xc9\x8e\x7e\x65\x87\xe4\xfb\x1b\x86\xa4\xa3\x45\xc7\x55\x25\xd5\x64\xdc\x63\x85\x0f\xce\x66\x71\x17\x80\xe2\xf9\x0d\x90\x1f\x51\x3c\xcf\x73\x74\x0f\xf3\xd7\x6c\xf6\x7a\x9d\xf1\x24\xcf\x1f\x4f\x2b\x4a\xe9\x9d\x5a\x21\xad\x97\xef\x8d\xb9\xae\x6b\x53\xf9\x01\xb1\x66\xec\x9f\x11\xef\xc9\xcc\xc3\x66\xa3\xb6\xbb\x57\xc9\x06\x5a\x37\xa8\x04\xd2\x26\x59\x22\xae\xf6\x73\x23\x45\x03\xe4\x71\x35\x74\xfc\xac\x08\x56\xc9\x6a\xcb\xbe\x86\x29\xf2\xfd\x94\xe5\x4c\xb2\x2b\x19\xb1\xa0\xdc\x66\x6b\x89\x70\x4c\x64\x04\x79\x63\x9a\xd9\xbe\xc8\xb6\xc9\x92\x39\x2a\x0c\x16\xdd\xc5\x74\x34\x25\xac\xfd\x7e\x60\xad\x80\x96\xf6\xcf\x37\xd6\x19\xcb\xd3\x92\x49\x4f\xa3\x55\x83\xae\x47\x0c\x49\xdc\xce\x94\x55\xfd\x34\x33\xe6\xae\x83\x9a\xb8\x0b\x67\x1b\x80\x1d\x94\x10\xed\xa0\xb7\x9c\x75\xd1\xa4\x91\x42\x2b\x0f\x93\x8c\xf2\x2e\xa0\x64\x93\x09\x2e\x82\x44\xca\xe2\xaf\x09\x4f\x73\x16\xf1\x28\x8b\x63\xea\x8c\x7d\xd5\xa9\x4d\xfa\x3e\x23\x05\xe5\xbe\x3f\x03\x7a\x63\x31\xa2\x7e\x97\xce\x3b\x0b\x4a\x71\x28\x56\xec\x35\x4f\xd9\xc3\x44\xba\x6f\x80\x3c\x3b\x08\x88\x63\xdd\x1d\x4e\x79\xa0\x68\xd1\x9b\xec\x2e\xcf\xf8\x06\x14\xaa\x8e\xac\x35\x99\x35\x5a\x92\xc5\x2c\x9c\xcc\xda\x5e\xae\xdd\x15\x6a\xd5\xf8\xcd\xa9\x18\x70\x4a\x1e\xbd\xbc\x21\xd5\x1c\xc3\x71\x0a\xa5\xcc\x99\xcb\xfd\xa5\x7a\xcd\x74\x5c\xa8\xcd\x74\x13\xb5\xed\xf2\xaa\xf2\x34\x63\x06\x6f\x97\xda\x4b\x7f\x67\x1c\x96\xa6\x2b\xa2\xe1\x02\x88\x51\xcc\x59\xf2\xbf\x68\x09\xbe\x74\x9f\x9d\x32\x9d\x0a\x9a\x82\xaa\x3b\xa1\xec\xbf\x66\xe5\x4b\x27\xa1\xaa\xdc\x94\x11\xa5\x23\xe6\xfb\x99\x82\xe7\xa1\xd2\x4e\xeb\x6a\xcc\xee\x37\x67\xdc\x5b\x77\xdc\xa5\xc3\xe0\x38\x5c\x16\x1d\x4b\xe2\x7e\xe2\xa4\x68\x4f\x17\x19\x8a\x62\x62\x81\x9b\x48\x4c\x12\x2a\xba\xa0\x9e\x4c\x26\x98\x47\x19\x15\x51\x12\x2b\x7c\xae\x20\x9d\x8e\x50\xd1\x9c\x2a\xe2\x5a\xfd\xdf\x74\x69\xd3\xd9\xf4\xbe\x3f\x74\xa2\xcc\x06\xc9\x96\xef\xb3\x9a\x53\xc1\x02\xa3\x9f\xa2\xa7\x9a\x08\xf5\x9e\x95\x3f\x7d\xf3\xf5\xb9\x36\x05\x74\x98\xac\xcf\x04\x30\xdc\xe8\x49\x4c\x0b\x56\xb3\x33\x92\xbe\xef\xfd\xf5\xed\x37\x5f\x77\x29\x4c\x4d\xf6\xd0\x28\x93\xb6\x92\x01\xc5\x4d\x46\x12\xca\x16\xe7\x8d\x85\xc7\x46\xd5\xa6\x39\x0f\xc5\x42\x24\xce\x7e\x4e\xfa\xbd\x59\xa0\x94\x26\x64\x4b\xd3\xfe\x07\xb2\xa1\x23\x81\x52\x4c\x8e\xba\x26\x94\xa9\x3c\x6c\x9d\x1c\x72\xf9\x43\xc6\x8e\xd8\xf7\xb3\x40\x8a\xfd\x88\x52\xc5\x00\x65\x41\x92\xa6\xaf\xee\x19\x97\x5f\x67\xa5\x64\x9c\x15\x8b\xf3\x24\xe4\x1d\x78\x2e\x92\xd4\x23\x05\x23\xa3\x19\x0e\x33\x85\xb4\x92\xd5\x16\x72\xa9\x0a\x9d\x57\xe4\x09\xde\x66\xc7\x98\x70\xc0\x70\x40\x71\x4a\x7a\x18\x62\x9f\xaf\x58\xb0\xb2\x5c\x00\xf5\x32\x8f\x8c\x58\x8f\x38\x37\x9f\x3d\x5c\xab\x1a\x87\x16\xfe\x62\xdd\xee\x41\xb5\x25\x10\x2f\xc4\x4e\x13\x08\x0f\x63\xd3\xdc\x39\x03\xe4\x5d\x7b\x96\xb4\x9f\xb7\xda\xf0\x2d\xf4\xef\x9a\x86\xa7\x97\x38\x20\x5d\x52\x31\x6c\x17\xba\xb8\xed\x74\x91\x61\xc5\xc8\xdd\x91\x51\xaf\x42\x55\x57\x55\x0d\xa5\xa2\xbb\x7e\x37\x55\x63\x0b\x54\x04\xeb\x2c\x97\xac\x08\x5e\xbf\x1c\x82\xfb\x86\xd8\xff\x8b\xb0\xf6\xd0\x77\x70\x0a\xcf\x59\x25\x85\xf1\xea\x9a\xa8\x26\x78\xda\x6d\x40\x11\x2c\xc5\x88\x0d\x6c\xd9\x3e\x33\xec\xfb\x9b\x16\x9b\xf7\x98\xdb\xb6\x4b\x7c\x11\xf1\x38\x8c\xe2\xba\xc6\xe1\xff\xf9\xa0\x74\x73\x17\x11\x4a\x33\x4e\x8d\xdb\xcf\xd3\xf4\xf8\x9b\xbe\x29\xa6\xf8\x3e\xc9\x0f\xec\xff\xf6\x8c\x68\x25\xef\xe0\xbc\x28\x79\x03\x6a\x44\x9c\x8a\x0b\x1d\xc4\x6e\xc7\x2c\x1b\x1e\x89\x78\x9e\x51\x39\x00\x42\x0c\x3b\xa2\x9c\xa0\x99\x96\xe2\xfe\xbb\x26\x0c\x13\x07\x0b\x66\xe7\xe3\xed\xf3\x2f\xe8\xf0\xbe\x5d\x0c\x89\xf5\xbf\x37\x55\x4e\xf1\x8b\xd2\x4b\x08\x72\xc4\x42\x9e\x73\xca\xcc\x9e\xb4\x0e\x0a\xb7\xa4\xa0\x51\x4c\x32\x3a\xed\xcd\x7e\xa7\x72\xb5\x06\xde\x35\xe8\x1d\xf0\xc9\xf2\x4f\x02\x4e\x94\xb0\x62\x07\xb8\x83\xbd\x8d\x24\xc6\x1b\xa0\x29\x2c\x9b\x2b\x1a\x78\x01\x0d\x60\x7f\x86\x1c\xf9\xea\x3f\x06\xa6\x6e\xf1\x0d\x6e\x6c\x3a\x2e\x48\x5f\x0c\xd7\xe4\x5e\x0d\xfc\x51\xfd\xd1\x32\x58\x8b\xda\xfa\x53\x08\xc7\xb6\x3d\x6c\x76\x8e\xc6\x38\x67\x85\x22\x95\xd4\xbb\x4d\xae\xb2\x94\x7e\xe4\x8d\xef\xc6\xde\x47\xcf\x6e\x6f\x92\x67\xb7\x5a\x73\xd6\x26\x4f\x96\xc5\x72\xf9\xd1\xd5\xae\x4c\xf2\x5c\x1c\x57\xc9\x5e\x1e\x0a\x46\x3f\xfa\xe8\xd9\xad\xd8\x1b\x41\x40\x2b\xf5\x21\xed\x46\x27\x3e\xbb\xbd\xd1\xc9\xcf\x3c\xc2\xce\x17\xda\x8b\xba\xd5\xbd\xa3\x1f\x7d\x14\x37\x48\xdd\xf7\x1f\xf5\xca\x78\xd1\xf5\xbb\x27\x31\x6d\xf5\xeb\x1f\x55\x4b\x6f\x09\x9a\xd7\xc1\x4a\x6d\x4f\xda\xaa\xaa\xca\x56\xd5\x6a\xf2\x17\x21\xec\x8d\x4a\xab\x2f\x2f\xd5\x95\xa5\xff\xa6\x7a\xfc\x43\xb5\xfd\x9b\x5e\x28\x17\x9a\xa3\x8e\x81\x32\xed\xa7\xc1\x92\xc9\x9f\xa0\xb9\xf1\xf5\x40\xd1\xe0\x4f\xc1\x38\x1a\xff\x3b\x06\x32\xdb\x5b\x5e\xd6\x5b\xcf\x6d\xc1\xd6\xf4\xa3\x8f\xae\x1a\xa6\xf2\x23\xfb\xd4\x5d\xe0\xc1\xef\x7a\xf5\x6e\x9c\xe5\x9b\x5f\x90\xe0\x34\x13\x8f\xe7\x7d\x31\x5c\x81\xbc\x47\x3c\x7d\x5e\x03\x43\x75\xa1\x4f\xe2\x5e\x76\xae\x98\x07\xe2\xbd\xbc\xb4\x0c\xea\x3b\x4d\x87\x60\x03\x4a\x6a\xcd\x72\x73\x14\xe3\x61\xf2\x74\xa4\x44\xb0\x81\x85\x61\x1c\x06\x39\x50\x53\xf3\x89\x78\xa1\x9d\x0b\x0f\x93\xb3\x7d\xd3\xcc\xd8\x68\x7a\xb9\x99\xb6\x82\x3f\xda\xce\x50\x35\xd7\x24\x7c\xf0\x30\xb1\x25\x49\x70\x1d\xaa\xb5\xc7\x0a\x01\xec\x94\x7c\xcc\x4a\x9b\xdf\x22\x83\x1d\xdd\xda\x4f\x55\xb5\x0d\x8e\xec\xee\x7d\x26\xbf\xe9\xe6\x55\x1f\x76\xe2\xb7\x81\x54\x31\x94\xb3\xec\x25\x2a\xec\xd2\x83\x3e\xae\x66\x65\x25\x38\x87\x8d\x07\xf9\xe9\xce\xd8\x42\x10\x38\xbb\x69\xdf\xa2\x72\xa4\xf6\x39\x8c\xec\xde\x8c\x6c\x44\x3d\xf2\xa3\x82\xea\x47\xfa\xd8\x4c\x98\xa3\x4b\x7f\x34\x6a\x99\x4a\x31\x84\xf7\xf4\x7e\x28\xcf\xbd\x9b\x47\xda\xf9\xd8\x06\x2b\xb1\x53\xd2\x9c\x65\xe8\xbf\x13\x65\xa6\xba\x8d\xc9\x03\x95\x55\xe5\x64\xe3\x32\xc9\x78\x89\x17\x43\x1a\xd5\xbf\x74\x44\xfa\x05\xeb\x33\xf6\xa1\x12\xfd\x65\x57\x1b\x31\x77\x4e\x65\x8b\xaa\x1a\xa1\x51\xa1\x35\x9f\x45\x53\x91\x4a\xe5\x4d\xd3\x8b\xf6\x11\x15\x38\x64\x97\xba\xee\xfb\xb3\x4f\xfd\x8b\x5f\xc1\x06\xaa\x4f\x3a\xb3\x35\x92\x46\x91\x20\x69\x47\x91\xa5\xbe\x38\x0c\xc2\x68\x3a\x6f\x14\x2e\xe4\x25\x95\x8b\xb3\x7a\x98\x7b\xc2\xbb\x56\xbb\x60\x3a\xd7\x87\x15\xa3\x8b\x7d\x9a\x8c\xe4\xa5\x4f\x0d\xd5\xad\x2a\x34\xf3\x51\x41\x87\xc4\x3d\x4a\x29\x3a\x57\x05\xe3\xc5\xe5\x49\x90\x38\x9c\xe1\xaa\x1a\x69\x0b\xbb\x97\x4c\x49\x40\x2c\xd5\x36\x49\xc3\x25\xa0\x95\x62\xa1\x86\x97\x56\x55\xaf\x13\x94\xd2\xa3\xef\x3f\xa0\x23\x61\x78\x31\x99\x85\x52\xe7\x92\x97\x72\x49\xbc\x98\x85\xab\xc5\xb7\x68\x45\x18\x9e\xa8\x1f\x89\xc3\x69\xf8\x67\xbf\x50\xa5\x67\x43\xeb\x73\x69\x5e\x79\x63\x21\xd3\xae\x1a\xf0\x3e\xce\x6b\x42\x23\x16\x93\x92\x46\x32\xd6\xda\xf3\xaa\x1a\x35\xaa\x66\x18\x51\xd3\xe9\xc5\x2c\xcc\xd4\x8b\x18\xea\xa0\x2a\x9c\xb9\x6a\x6a\xa3\xe2\x9a\x73\xca\xe6\xad\x1e\xca\x01\x9f\x24\x38\x70\xad\x29\xe4\x2a\x97\x1c\xce\x55\xba\xb9\x8c\xce\x21\x2a\x62\x4a\x69\x19\x15\x31\x2e\xc6\xe3\x06\x0c\x16\x2b\xfd\x8d\xc0\x97\xd0\x64\x3b\xaa\x2e\x97\xf6\x79\x16\x4e\x6b\x92\xe2\x30\xad\x89\x60\x16\xdd\x0d\x1f\x40\xc1\x81\x06\x3f\xe4\xb9\xfe\x23\xb1\x5b\xa4\x41\x9e\x67\x8b\x31\x04\x84\xf6\xd8\x81\xc1\xb1\x43\x23\xca\xfc\x46\x3c\xfa\xd1\x93\x99\xe2\x5c\xc8\x19\x5a\xf6\xfd\x0d\xa8\xca\x65\xa3\x2a\xbf\xaf\xaa\xd1\xbd\x46\x3a\x52\x9b\xd7\x39\xca\x73\x89\x31\x28\x94\xf5\x7e\x6a\x70\xa6\x04\x86\xb6\xa8\xaa\x01\x3c\xab\x40\xd5\x22\x23\x73\x94\xd2\x26\x34\x88\xa6\x51\x29\x3a\x1a\xe8\x76\x86\x24\x49\xf5\xf4\x44\x2c\xb6\x04\xeb\xd9\x14\x66\xca\x22\xa4\xc1\xd9\xfd\x9d\x59\x7a\x30\xe6\xdb\x82\x81\x92\xa1\x57\xc5\x87\x0b\x03\xe8\x67\xb4\xa3\x80\xed\x99\x01\xc5\x44\xd0\xcc\xf7\xff\xa6\x67\xc9\xcd\x49\x7a\x39\xf1\x22\x83\x63\xad\xd1\xc6\x8a\x16\x16\xdc\x1a\x93\x4e\xb1\x10\xa1\xab\x0b\xa9\xaa\xd1\x66\xd1\x13\xad\x25\x0e\x91\xa0\x03\x32\x27\x2c\xa4\x08\xca\x3d\x5b\x65\xeb\x8c\xa5\x0b\xa1\x05\xaf\x10\xd4\xcf\x6a\xfc\xac\x5c\x25\x7b\x46\xcf\xc5\xf7\x9e\xa9\x9f\x3e\xd5\xd0\x45\x8a\xa2\x03\x99\xe7\xd6\x9f\xde\x9b\x47\x2e\x93\x87\x2b\xc8\x49\xae\x0e\xbc\x60\x2b\xb1\xe1\xd9\x6f\x2c\xbd\x62\x0f\xfb\x82\x95\x65\x26\x78\x78\xe5\x8d\x4d\x95\x07\x9e\xfd\x7a\x60\x6f\x44\x31\xa4\xfe\x72\xe4\x2a\xc0\x03\x6b\x3a\xe2\x41\xca\x24\x5b\xc9\x97\x87\x7d\x9e\xad\x12\xc9\x4a\xb2\xa2\x06\xa5\xbe\x91\x8a\x73\x01\x65\xb6\x3e\xcd\x55\x2c\x8c\xfa\x80\x5e\x62\xb2\xb6\x52\x97\xa4\x2c\x12\x4a\xea\x02\x1a\x13\x89\x18\x74\x5e\x46\xe4\x12\x18\x3b\xba\x76\x66\xac\x9f\x41\xed\x48\x66\xd8\xc2\xe7\x0a\x94\xf8\x84\xd5\x24\xa3\x02\x26\xff\x2d\x7b\x18\x1a\x00\xa7\x9e\x07\xb8\x52\x38\xa4\xba\x95\xc6\x95\xdc\x27\xaa\xea\x2f\xfa\x67\x06\xaf\x5a\x56\x3b\xb3\x85\x04\x57\x0b\x30\x62\xe0\x0d\x46\xee\x24\x82\x69\x2a\xa3\x2c\x00\x83\x05\x60\x0d\xe7\x6c\xae\x12\x5c\x15\x3d\x1f\x83\xdd\x6c\x73\x4e\xf8\xb1\x6e\xfa\xcf\x2e\x82\xd5\x3d\xfd\x41\x41\x8b\xce\xd7\xce\x1b\xc8\xf8\x50\x87\x6c\x15\x1a\x35\x41\x85\x56\x65\x6a\x04\x53\xd2\x93\x73\x80\x13\x7e\x32\x25\x9a\x43\xff\xae\x64\x87\x54\x84\x25\x23\x80\x91\xc2\x1f\x48\xbb\x3d\xc2\x53\x4d\x94\x58\xab\x7e\x0b\x96\x83\xb5\x43\x78\xf2\x9e\x79\xe1\xf9\xf1\xb7\xb6\xc7\x1f\x4d\x6b\xe2\x5d\x0d\x7c\xaf\x89\x37\x6e\x92\x0b\x76\x9f\x89\x43\x69\x86\xdf\x29\xfb\xef\x4b\x99\xea\x9a\xec\x0b\xf6\x39\x28\x8d\xc2\x13\x98\xca\x0c\xe9\xb8\xa2\x59\x4c\xd5\x9f\xae\x02\x89\xb0\xe8\xe3\x98\x22\xf5\xb7\xaa\x58\xf4\x67\xf8\xfb\x49\x5c\x55\xee\x96\xd2\x39\x95\xac\x06\x20\xf8\x54\x81\x20\x94\xf3\xd4\xc6\x88\x3e\x8e\xe1\x20\x8c\xb4\x56\x09\x7f\xc6\xb5\xb1\xc1\xf9\x60\x4f\x3a\x18\x86\x78\x5c\x6e\x75\x03\xb3\xb8\xa9\xe9\x63\xbc\x30\x9d\xb3\xfb\x19\xb1\x68\x1a\xab\x7e\xff\x39\xa6\x63\xa4\x7e\x16\xaa\xc7\xea\xf1\xd3\xb8\xaa\x66\x38\x7c\x7a\x8d\x3c\x76\xcf\xb8\xae\xec\x63\x70\xa4\x49\x53\xfb\x86\x55\xd9\x4f\x74\xd9\xff\x15\x8f\x59\xf4\xbf\xcf\x32\x84\xea\xc7\xf7\xfb\x2d\xd6\xd6\xe0\x68\x68\xe3\x8c\x54\xf3\xbe\xaf\x66\xc7\x42\xda\x0f\x01\xcc\x81\x39\x01\x55\x75\x2c\xd4\x3e\x0c\x61\x40\x0b\x95\x93\x76\x67\x3c\xe4\xbe\xff\x93\xce\xce\x15\x5d\x93\x34\x41\x9c\x8c\xa6\x58\xbf\x34\x5e\x5e\xc8\xc3\x5e\x73\x1c\x31\x91\x78\x62\x9f\x31\x2c\xcc\x54\xd5\x3b\x6d\xe7\x50\xaa\x11\x3f\x8d\xad\x0f\x19\xa4\xb8\xab\xf5\x31\xc6\xb5\x02\x67\x0d\x40\x6f\x9f\x7f\x31\xe0\xf7\xd1\xd3\x3b\x0e\x1e\x48\x19\x75\xd1\xe2\xcc\xab\x63\xd4\xd1\x43\x39\x6a\x57\x7b\xb8\xa0\x70\xe0\xf0\x59\x97\x51\x3a\x6a\xfb\xb1\xf3\x6e\xbd\x32\x27\xe8\x8d\xf3\x49\x55\xa9\x89\x72\x4c\x88\xd0\xbb\xc6\x06\x8e\x8d\x3d\x6d\x37\x54\x3d\xc1\xa0\xdc\x7b\x85\x18\x19\x72\xe1\xd1\x4b\x30\x80\xd4\x56\xad\xc2\xc9\x79\xa9\xaa\xdf\x57\xb6\xf6\x15\xad\x46\xe5\xef\x61\xd8\x69\x35\xae\x49\x6f\xe3\x76\x4c\xc4\x9b\x64\x7b\x26\x45\x0d\x43\x80\x0a\xc7\x9d\x49\x1b\x92\x67\x0b\x25\x0b\xaa\x79\x0b\x47\x6a\x3a\xb2\xb1\x42\xea\x9e\x4e\x5a\x28\xd6\x94\x87\x36\xc7\x22\x1b\xc1\xeb\x3b\xf3\xca\x7d\x7f\x4a\x29\xcd\x1a\x40\xe3\x38\xf4\xae\xdb\x8f\xee\x87\x67\x93\x59\xe8\x3d\x71\xbf\x69\x78\x6a\x81\x51\x37\xf5\x6f\x93\x05\x29\x64\x91\x35\x60\xf4\x44\x61\x43\x30\x48\xc2\xfd\x4a\x2b\x5d\x02\xe8\x1c\x9c\x6d\x66\x0d\xa8\xda\xba\xc7\x33\xa8\x7d\xec\x4d\x3c\x00\xde\x3e\xb2\xb1\x8e\x3d\xc6\x04\x87\x02\x6e\x01\xbe\xae\x05\x7a\x92\x50\x2f\x4f\x4a\xe9\xa6\x4f\xfe\x8c\x49\x49\x3d\x63\x05\x08\xdd\xb0\xb3\xab\xa8\x5d\x61\xe6\x67\x31\x60\x22\x35\x72\xa5\x0b\x07\xde\x55\x4f\x0e\xba\x1f\x1d\x4b\x66\x2a\x46\x94\x26\x0b\xcf\x21\x77\xde\x00\x05\x78\xec\x8a\x29\xf7\xb4\x54\x12\xd8\xf0\x66\x21\x3b\x3a\x3a\xf8\xfe\xa8\x24\x0f\x74\x34\x53\x74\xfb\x11\xc8\xb3\xb0\xbc\xc4\x06\x9f\xf6\x8d\x80\xb1\xa7\xfb\x68\x03\x2a\xf0\x72\xb1\xbf\xbc\xfd\xee\x43\x35\xf2\x7d\x9f\x0f\x1e\xcd\xe6\x5b\xba\xa1\x9e\xe0\x39\x18\x7e\x33\xdf\x1f\x6d\x7d\xbf\x33\x9c\xba\xd9\xfe\xd9\x1a\x6d\x69\x94\x2c\x1e\x1d\x72\x1f\x3e\x06\x6a\xfa\xe1\x39\x26\x89\xef\xef\xf0\xe9\x81\xa2\x94\xa2\x9c\xa2\x15\x45\x6b\x8a\xf6\xf4\x11\x47\x77\x71\x55\xa1\x7d\x74\x17\xd3\x53\x8d\x71\xb4\x37\x3c\xd8\xeb\x97\x2a\x7d\xed\xbe\xeb\x0c\x2c\xae\xaa\x28\xc6\x0a\x0d\x82\x29\x53\x1e\xcd\x62\xac\x7e\x9e\xc6\x64\xaf\x98\xe3\x47\xc7\x98\x2c\x4a\xe3\x66\x3a\xc6\x63\xc5\x39\xfb\xbe\x9a\x96\xaa\x42\x0f\x34\xa5\x53\x5c\x55\xdb\x60\x2f\xf6\x08\x8c\xa0\xba\x33\xe1\xfb\xe3\xf1\x83\xef\xef\x41\xea\x3c\xad\x22\x16\xd3\xe8\x2d\x49\xc9\x43\x3c\xd7\x3e\x2e\x1d\xf3\x26\x55\x9d\x3b\x32\xf9\x7f\x69\x64\x04\x4e\xe7\x1f\xf0\x1f\x1f\xc5\x7f\xb8\xde\x66\x98\x30\x08\xdd\xfb\xfd\x7f\xd1\x73\x35\x35\x0f\x31\x26\x7a\xb6\x3a\x2e\x3d\xe8\x61\x42\x33\xac\x55\x3c\x0f\xff\x53\x50\x3a\xf5\xfd\x87\x9b\xe2\x19\x9d\xd6\xf5\x00\xcd\x6d\xcf\x31\x80\x0d\x06\x2e\xad\x84\xb9\x29\x82\x92\x49\xcd\x08\x95\x51\x6f\x64\x2e\x07\xe1\x1d\xb8\x39\x3c\x67\xe9\x95\xae\x40\xb3\xf8\x8d\xc3\x4a\x74\x17\x2f\x14\xd3\x18\x66\x56\x96\x9b\x2d\x10\xa7\x11\x23\x8c\x78\x1e\x91\x31\x71\xdb\xea\xf9\x07\xa0\xbe\x39\xd6\xc2\x35\x2c\x60\xad\xeb\x8b\xa0\x20\x54\x5d\x30\x27\x60\x51\x41\xbf\x45\x8c\x88\x28\x89\x71\x4c\x47\x88\x2b\xe1\x1d\xde\x6a\x3c\x44\x4f\x55\x65\x53\xc2\xd5\xd7\x4c\x31\x85\x7a\x66\xc2\x13\x17\x32\x2c\xbb\xda\x46\x4d\x3d\xa3\x98\x18\x1f\xf4\xf2\xdc\x34\xaa\x3d\xcc\x51\x93\xd1\x1d\x81\xc2\x69\x8d\x79\x63\x42\x0b\xab\x20\xc8\x48\x14\x2b\x04\xca\xce\x0d\xc6\x90\xa0\x49\x54\xc6\x9a\x43\x29\xd5\x70\xa4\xfa\x11\xb8\x3b\x18\x92\x11\xd1\x12\x62\x60\x65\x48\xa1\x70\xa8\xaa\x5e\x10\x8e\x09\x24\xc2\xeb\x88\x6b\x98\xae\x6b\x4c\xb6\x49\xd9\x1f\xe3\x45\x3b\x17\x63\xa2\xe9\x88\xe9\x35\x26\x56\x4a\xbf\x50\x0b\xeb\x73\x40\xe4\xbc\x5e\x24\x5d\x01\x07\x0c\x59\x38\x67\x85\x92\xb5\xaa\x4a\x41\x53\x4b\xe9\x98\xa2\x74\xaa\xd9\x3c\xe1\x9b\x0b\x4d\xfe\xc3\x30\x8e\xc0\x21\x5c\x82\x5e\x28\x0f\xb0\x4b\xce\xba\xd8\x23\x0e\x67\x06\x46\xf3\x54\x9c\xc0\x06\x6a\xb3\x90\x01\x54\xd4\xb7\x19\x7c\xd8\xe5\xa1\xfa\xa0\xda\xef\x7f\xd3\xe9\x86\x1a\x80\xb6\xaa\x0b\xf4\xda\x98\x67\x0a\x47\x85\xcd\xb0\x81\x60\xd7\x1a\x2a\xfa\x6a\xd4\xbe\x95\x17\x6e\xd5\xa8\x35\x26\x32\x29\x3a\xce\xe3\xae\xa5\xae\x58\x25\x5a\xa9\xdb\x3e\xab\x2d\xb9\xed\x9c\x61\x6b\x02\x0f\x7c\x83\x0c\xb2\xb4\x26\x85\x10\x83\xce\xe8\x8c\x52\xba\xad\x09\xf8\xd3\x5c\xfa\x9e\x06\xc9\x4a\xc9\x7c\x46\x77\xed\xfb\x68\x94\xaa\x26\x3f\x07\x27\x9c\xaa\x7d\x46\x8a\xcf\x1c\x8d\x14\x4a\x00\x65\x35\x0b\xb6\x05\x5b\x57\xd5\xbf\x59\x20\x93\x3b\x30\x58\x03\x5f\x68\x38\xc3\x08\x53\x86\x46\x33\x4c\xec\x99\x06\xbc\x4f\x31\x31\xe7\x5d\x83\x6c\xf9\x07\x4d\xc4\x1c\xcb\x34\xd5\x0b\x16\x58\xff\xa1\xca\xd3\x07\x54\xce\x27\x7b\xe6\x57\x13\xfb\x34\xcc\xb3\xbb\x86\x61\xee\x5b\x53\x01\x0c\x8a\x18\x93\xf1\xb6\x56\xb6\xdb\xcb\xc7\x4e\x95\x7f\x48\x03\x90\xad\x51\xab\x8a\xb8\xfd\x74\xc8\x8d\x55\xf7\x61\xa0\xb7\xa3\x86\x3c\x04\xd0\x3a\x9c\x01\x6f\x59\x92\xb2\x62\x68\x6c\xff\x34\x1b\xae\x99\x53\x5c\x13\x98\xc0\xa1\xcc\x5f\x0c\x64\xd6\x26\x78\xff\x87\xcb\xe4\x18\xf2\x59\xa0\x71\x92\x64\x4d\xc0\x2f\xe4\xdc\xd5\xb7\x5f\xd5\xa5\x36\x7d\xdf\x53\x35\xb4\xf5\xfb\x3e\xd2\x92\x03\x92\xb4\x2f\xa4\x00\x17\x0c\x6e\xcb\xb6\x4c\x5f\x2f\x68\xe3\x0d\x6c\x1d\x1c\x66\x27\x29\x9a\xc6\x80\xe2\x7a\x9f\x1d\xf5\x67\x24\x27\x33\x95\x87\xfd\xda\xcf\xd1\x4a\x3f\x11\xbf\x9d\x2e\xf8\x58\x86\x1c\x72\xde\x33\x7e\x5e\x9b\xe3\x58\x37\xe7\xb7\x72\xce\xc7\xf4\x29\x66\x7d\xb3\x04\x56\x63\x22\xd2\xf4\x43\xc5\x67\xbf\x53\x3c\x3f\x1b\x4a\xc7\x67\x96\x36\x7d\x9d\x4f\x26\x8a\x83\x99\xdb\x6a\x8a\x4e\x35\x9b\x3f\x5c\xcd\x78\x5c\xdc\xca\xe1\x5a\xea\x1a\x37\xf0\xcd\xe5\x96\x3a\xd0\xfe\x6b\xe3\xf9\x7d\x2a\x92\x34\x13\xe1\x68\xaa\xb1\xc8\x9d\x78\x50\xcf\xeb\x0c\x22\xaa\x90\x7d\x52\x96\x47\x51\xa4\xea\x39\xdb\x25\x1b\x08\xb3\x82\x5b\xae\x4a\xc6\x74\xcd\x90\xc4\x6d\x75\xe5\xe1\x6e\x97\x49\x95\xbf\x60\x25\x93\xe7\xf9\xf7\x3a\xbf\x35\x74\x7c\x64\x08\x9f\xea\x47\xe6\xc4\x14\xb1\x16\x4e\x65\xdb\xe3\x0e\x3b\x05\xf2\xfb\x23\x53\x5c\x91\x82\xdd\xf7\x8c\x67\xbf\xf5\x9d\x63\x0c\x03\xe8\x3a\x89\xd2\xf7\x56\x19\x90\xad\xd1\xaa\xb1\x07\x59\x4c\xc3\x55\xa3\x60\x9d\x97\x94\x91\x83\xe2\x79\x72\xd5\xb8\x55\x9b\x59\x3e\x05\x9f\xb8\xef\x8f\x50\x46\x3f\xd7\xbe\x0f\x25\x86\x08\x09\xbe\x8f\x4a\x5a\x9a\x4a\xb2\x68\x1a\x5b\x09\xb7\xaa\x4a\x4c\x0e\x46\x15\x4b\xa3\x18\x63\xc2\xe9\x68\x46\x50\x46\x7f\x6e\x6a\x50\xfb\x8b\x66\xd6\x18\x9c\x08\x9d\xfd\x64\xd4\xdb\x04\xe2\xdd\x40\xa5\x0e\x03\x76\x05\x06\x0a\x6d\xa3\x8d\x4c\xad\x57\x22\xb9\xca\xf8\x95\x9d\x46\xac\x3a\xfc\x43\x94\xc4\x4e\x9f\xf3\x28\x89\xf5\x48\xd4\x13\xca\x60\x1c\xbf\xdb\x8b\x84\x98\xb3\x97\x30\xbb\xd4\x7a\xb6\x46\x23\x6e\x5c\xf8\x9b\x19\xb6\x2e\x39\x61\xb9\x68\x75\x66\x38\x7c\x8f\x18\x39\xe0\x66\xee\x9d\xf0\x3d\xf7\xcc\xe2\x7f\x8d\x1f\xa7\xa4\xe3\x71\xe3\x79\x73\x79\xcb\xe7\x72\x3c\xc6\xc5\x18\x82\x58\xe8\xc3\x80\xd6\xbc\xa8\xa9\x69\xc7\xba\xde\x5e\x32\x48\xb3\x82\x64\x8a\x8d\x60\x0f\x52\x71\xd8\x55\x55\x90\x84\x72\xdf\x77\x95\xae\x94\x52\x41\x4a\xfa\xa2\x3d\x35\x93\x9a\x0c\x2d\x3a\x72\x7b\xd6\x2a\xe1\x65\x54\xc4\x56\x04\x94\xce\xe9\x73\xd2\xa8\xa1\x4d\x89\x96\x6b\xf9\x90\x0e\x40\x89\x43\x25\x40\xea\xe1\xbc\x8d\x81\x46\x7c\x9f\x99\x5a\x9a\x53\xe6\xae\xb2\xfb\x72\xff\xe0\x20\x42\x6a\x91\x4d\x1a\x91\x8d\xac\xe8\x3a\x92\x3d\xa9\x4d\x76\xa5\x36\x92\xf9\x7e\xf6\x01\xa3\x76\xac\x1b\xad\x2a\x39\xb7\xee\x37\x28\xa7\xab\x48\x68\x69\xdb\x15\x52\x29\xa5\xa5\x9d\xa7\x7d\xf4\x34\xa6\x4a\x18\x87\x6d\x1a\x89\x98\xee\x09\xa4\x9d\x0f\xb0\xe5\xff\x9a\xf5\x7e\xe8\xd8\x4d\xb7\xc2\x59\x67\xaa\x1b\x2d\x19\x3b\xf7\x47\x80\xc0\x60\x51\x16\x9b\x8c\x03\xfc\x44\xc8\x14\xdd\x6a\x5a\xbc\x63\xe7\xe8\x79\x0a\x10\xd6\x84\x5b\xc8\x20\xdc\x82\x96\x2a\xa2\x22\x26\xdc\x39\x6c\x68\xea\x39\x32\x57\x2d\x65\xeb\x52\xe2\x53\x14\x93\x92\x4e\xc9\xa1\xdd\x02\x39\x35\xf1\xb1\x9a\xe0\x2f\x48\x50\x66\xc4\x27\x85\xa2\x38\x12\x50\x4f\x55\xa1\xc4\x9e\x04\x91\x1c\x8c\x27\xd4\x4b\x89\xdd\xa8\x2a\x4d\x17\xde\x3a\x5d\x70\xc4\xac\xc2\xf7\x47\x4a\xc8\xf3\x7d\x54\xd0\xb7\x0c\x15\x18\xd6\x7e\x94\xe9\xb4\x4c\xa5\xa9\xfc\xb8\x63\x20\x6f\x30\x6f\x0f\xaa\x63\x92\xaa\x3f\x5b\x9a\xd8\xb1\x6c\xa8\xa8\xaa\x3b\x86\x64\x55\x79\xd7\x1e\x29\x5b\x13\x90\xa8\x8c\xc3\x12\x24\xc6\x47\x3a\x62\x55\x35\x12\xbe\x2f\x17\x9b\xf0\xc8\xd0\x86\xec\x09\x83\xea\xc9\x3d\xe5\x8b\xac\xaa\x90\x58\xb0\x70\x5b\x55\x05\x5e\x44\x71\x98\x84\x8f\xe0\xd9\xe1\xfb\x1c\x3d\x92\x7b\x9d\xb3\xc0\xa7\x9c\x1e\x19\xba\x27\x29\x26\x05\xca\x89\x9a\x58\xf5\x61\x45\xf3\x2e\x20\xac\x94\x40\xba\xa6\x79\xb4\x82\x19\xbd\x8f\xd2\x68\x15\x2b\x99\xf4\xd1\x3c\xad\x31\xae\x9b\x63\xaf\xac\xaa\x74\x44\xb9\x4c\x35\x10\xc5\x64\xd5\x98\xcf\x74\xeb\xbb\xd7\xf5\xe5\x7a\x11\x1e\xa3\x95\xaa\x68\x9e\x01\x7b\xa5\x6d\x0f\x73\x72\xc0\xf5\xef\x14\x47\x39\xcd\x16\xdf\x22\x41\xd6\x38\xdc\xab\xa4\x67\x93\x19\x04\x28\xcb\x55\x0f\x13\xf5\xa3\xba\xa7\xb7\xff\x3d\x0c\x98\x52\x9a\x2c\xee\xed\xe9\xdf\x96\xd8\xfa\x71\x78\x8f\x49\xb6\x30\x3d\x48\xc8\x3d\x39\xe0\xd0\xfa\x58\x25\xe4\xbe\xe3\x92\xf0\xa2\x8b\x94\x09\x90\xd7\x16\x26\x13\x5a\x04\xf6\xa8\x2b\x82\xf3\x05\x45\x33\x14\xe8\x26\x55\xe5\x7c\x52\x14\x98\x1c\x68\xb2\x98\x85\x53\xb2\x1a\xf6\x27\xd5\x61\x16\x6a\x52\x12\x25\xde\xac\x2f\x64\xfa\x16\x49\xa2\x05\x65\x93\x71\x4f\x23\x57\x8d\xd2\xee\xf3\x51\xa2\x60\xb7\xaa\xf8\x88\xd2\x5c\x6d\x0a\x24\x29\xc7\x2d\xa4\xad\x4c\xf6\x70\x6d\x1e\xda\x68\x55\x5a\x95\x90\xd5\xf1\xfc\x70\x2b\xe6\x07\x13\x67\xa9\x3b\xd6\x83\x19\x2b\xde\xd3\x68\xc7\xd0\x03\x43\x7b\x4c\x38\x8e\x5b\xbc\xc7\x1b\xa6\xc6\xc9\x6e\xe6\x59\x9f\xbd\xaa\x54\x43\x5d\x31\x8e\xee\x62\x3d\xd3\x19\x1d\x8f\x0f\xf3\xec\x56\xcc\x33\xdd\x72\xa7\xdd\xcc\xb6\xdb\x09\x80\xf3\x96\xa1\xc3\xb3\x99\xef\xeb\x6e\xc0\xa3\xa2\xa7\x8d\x66\xfb\x30\x99\x61\x13\x23\xd0\xd2\x77\xef\x4a\x1f\x6e\x1d\x26\x4f\x75\x95\x0b\xef\xda\x0b\x3d\xaf\x76\xe2\x27\x59\x8f\x38\x4e\x0e\xb7\x99\xef\xbf\x68\xab\x3c\x90\x4c\x61\x84\x5b\xa1\x53\x1b\x65\x79\x93\x0a\xe4\x1c\xd7\x7b\xcb\x30\x5b\xce\x00\x7a\xd8\x02\xd8\xab\xae\xb3\x57\xa3\x7e\x71\x62\xd7\x3c\x9b\x12\x41\xfb\x28\x86\xac\x74\x99\x35\xd9\x92\x47\x72\x4f\xa7\x64\x47\xbd\xa9\x47\x1e\xa8\xf0\xfd\x28\x26\x77\x6a\x67\x1d\x69\x4e\x5e\x28\x54\x93\xf9\x7e\x6b\x92\x8d\x14\xca\x59\x61\xf2\x8a\xbe\x1d\x53\x2d\xe5\x1c\x17\xb3\xb0\x13\x42\xaa\xaa\x82\x19\x79\x4f\x5f\xd8\x3d\xa9\xd6\x65\xa5\x03\x79\x69\x13\xa5\xa4\xaa\x56\x78\xbe\x1b\x51\xfa\xde\xf7\x4d\x4c\x99\x35\x7d\x11\xed\x62\x3c\xdf\x8d\xc7\x1a\x35\xf8\xfe\x1a\x9f\xb6\x74\x4a\x92\xaa\x5a\x9f\xd9\x34\xa5\x55\x85\xf6\x68\xad\x98\xaa\xd1\xc6\x1e\xd9\x3f\x52\x16\x6d\x8d\x15\xfa\x23\x5a\xab\x92\x29\x29\x31\x3e\x19\x8e\x72\x8d\x8d\x1e\x59\xf5\xe6\x2d\x7d\x85\x6b\xee\xfb\x08\xad\xe9\xe8\x51\xb5\xe6\xfb\xf7\x93\x09\x11\xbe\xff\x60\xb3\x03\xce\xba\x1f\xd3\x1d\xe1\xbe\xaf\xfa\x7b\x0f\x5d\x6a\x9a\x93\xba\xb9\x47\xf4\x40\xee\xd4\xd4\x3a\x86\xf6\xf7\xcf\xa6\x46\x83\xbc\x9b\x4c\xf0\x43\xb4\x8b\xab\xea\x0e\xfe\x22\xf5\x43\x7f\xd1\x26\x22\x07\x8c\xe7\x77\x0a\xe5\xdc\xe1\xda\xe2\x91\x03\xb9\xc3\x64\xe5\xfb\x0a\x7d\xdf\x35\xeb\xe8\xfb\xf7\x4d\x80\x22\x05\xa2\x1d\xdb\x09\x74\x68\x6d\x13\xf4\xd8\x48\x4e\x8f\x98\x3c\xd4\xad\x4b\x44\xc9\x90\xc0\xa1\xb0\xf9\x4a\x2a\xb4\xa9\x5a\x96\x0f\xcb\x02\xc6\xf8\x02\x42\x16\xbd\x71\x24\x81\x91\xc0\x27\x7d\x2c\x08\xae\xac\xa4\x85\x3c\x6b\x68\xa5\xb5\x93\x2f\x18\x92\x11\x8f\x61\x73\x2e\x1a\xf3\x8a\x30\xb3\x4f\x73\x24\xe8\x1b\xc4\xc8\x2b\x45\x0c\x0b\x8c\x71\x63\x40\x40\x99\x63\xee\x7e\x68\x4d\x0b\xe8\x25\x8d\x69\x13\xd3\x86\x0e\x05\x81\xf4\x7d\x46\x52\x3a\xca\x7c\x3f\x41\x8c\xee\x9b\x66\x14\x15\x02\xa2\x47\x39\x78\x86\xcf\x40\x0f\x65\x10\x3d\x60\xa1\x03\x4d\x15\xdb\x95\x3a\x87\xbf\x8d\xef\xee\xb3\xa7\xbe\xef\xbd\x7e\xa9\xf0\x00\xca\xe9\x21\x9a\xc6\xd8\x48\xff\x7f\xe9\xf9\x56\x6e\xd4\x06\x6a\xb0\xd0\x01\x0e\xea\x01\x0b\x69\x8f\x6f\x49\x51\xe3\x02\x82\x72\x8b\xd3\x5c\xf9\x45\xeb\x47\x25\xb6\x87\x15\xb8\x0d\x66\xb3\x87\x83\xec\x8e\xda\x8f\xb4\x08\xe5\x60\xc5\x13\xcd\xee\xdb\xb1\xd5\x82\xfe\x10\xb8\x51\x31\xac\x4f\xf1\x62\x1a\x1e\xba\x6b\x29\x26\x13\xe8\xa6\x1a\xa1\x88\x89\x33\x0e\x88\x89\xea\x20\x53\x35\x5f\x6b\xaa\x47\x62\xe8\x6e\x46\xd7\x1f\x1a\x90\x71\x65\x3e\x58\xd2\x37\xec\xd2\x6c\x7c\xb7\x0f\x96\x18\x0b\x32\xc3\x64\x84\x18\xcd\x1a\x8b\xdb\x7b\xa6\xf6\x51\xdf\x71\x5c\xc1\x07\xe1\xf6\xe4\xc8\x40\x14\xda\x57\x55\x89\x18\x49\x31\x46\x19\x98\x5f\x11\x4e\x46\xb2\xaa\x3e\xec\x57\x0d\x61\xc7\x5c\x23\x23\x7a\x67\x1d\x75\x3d\x6c\x4d\x8c\x8c\xb1\x2f\xb8\x3a\xdd\x91\x73\x43\x25\x3a\x1a\xad\xc9\x1e\x61\xd2\x35\x00\xbd\xe0\xe3\x35\xfb\x80\x39\xed\x07\xbc\x96\x07\xec\xf0\x1b\xe6\x7e\xc8\x1c\xff\x4f\xda\xf6\xde\x23\xde\x9f\xb4\x06\xab\x55\x1e\xf6\x54\x57\x2a\xbf\x92\xa2\xab\x2a\x37\x8a\xac\x0a\x54\xaf\x5b\x96\x6d\xb6\xb2\x3a\x66\xa9\xdc\x7a\xa4\xaf\x82\xd1\xf2\xed\xb0\x5f\x98\x24\x5e\x73\x2a\xdc\x15\x85\x16\xb3\xf0\xa9\x76\xdc\x6b\xcd\xdf\xce\x2c\xbc\x07\xc7\x05\xea\xba\x1b\x70\xee\x70\x46\xd2\x35\xed\x87\xcd\xe0\x41\x68\x43\xef\x77\x06\xad\xb3\x36\xa3\x36\x25\x07\x07\xe9\xfb\xbf\xaf\x2b\x6c\x27\xc2\x7a\x58\x82\x95\xd5\xa5\x25\x33\xf1\xf7\x7a\x7d\x6a\x2d\xf4\x4d\xb7\xbe\x3b\xeb\x10\x48\x55\x73\x77\xee\xb5\xfa\x38\x92\xf1\xa2\x37\xd5\x21\x44\x86\x1b\xb6\x1f\x2c\x1c\xfb\xc1\xc2\xb5\x1f\xc4\x44\xb0\x1a\x31\x3c\x3f\xc2\x7e\xa7\xaf\x20\xd0\xe4\xbe\xa0\xaf\x5a\x2b\x30\x93\x14\x79\xa1\xa7\x03\x57\xee\x5b\xed\xd4\xd1\xb5\xfb\xb3\x2f\xf4\x95\x93\x4a\x8e\x3a\xb8\xf0\x2b\x6b\x5d\x47\x8e\xda\x21\xf7\xa5\x58\xd1\x57\xfa\x91\x1c\x5b\x5b\xd0\x57\xcd\xa3\x6a\x17\x4c\x1b\x1b\x53\xda\x57\x26\x01\x0c\x38\xdf\x5f\x08\x6b\x03\xc4\xae\xb1\xbd\xe4\x06\xff\x29\xee\x4c\xc7\xfc\xfc\xcb\xc8\x35\xb7\xb7\x9a\x01\x27\xc5\x70\x2d\x47\x70\x64\x2a\x11\x6f\xce\x64\x4d\x00\xbf\x86\x42\x17\x35\x79\x73\x31\x8e\x59\x14\x0f\xe8\xec\xfb\xde\xfb\x6c\x04\x9a\x6d\x6e\x6b\x76\x4c\xf1\x5e\xda\xa9\x06\xb4\xdb\xc1\xf2\xad\xba\xe8\x6f\xdd\x10\x6d\x7f\xd0\x6c\xa8\x17\xf1\x4e\xf5\xf7\x39\xbd\x79\x77\x8b\xa2\x64\xf2\x5b\x1c\xbd\x5b\xde\x2c\xa7\xcf\x42\x08\x68\x26\x97\xc5\x92\x2f\xd7\xf1\x35\x8e\xba\xef\xcb\x9b\xc5\x33\xb4\x08\x6f\x97\x37\xcb\xd9\xb3\x0a\x3f\xb9\xc9\xda\x5e\xfd\xd2\x33\xd2\xd9\x20\x89\x17\xc7\x60\x53\xb0\x7d\xc7\xae\x48\x89\x29\x8d\x6f\xb5\xb5\x47\x2e\x08\x98\xea\xf2\x1a\x87\x2d\xed\x1d\x2a\xdd\x15\x99\x4c\x91\xb3\xa0\x30\xf2\x83\x45\xdb\xb0\x92\x4a\x9a\x32\x75\x1c\x8d\xc0\x62\xa3\x4d\xda\xf7\x0b\xf0\x26\xa3\x69\xec\x9c\xa7\x21\x46\xbd\x90\x0b\x89\xc0\xac\x0a\x7b\x98\x68\xc5\x93\xa5\x71\x60\x2d\xe3\x0e\x0c\x38\x86\x9e\x69\x37\x58\x2f\x2d\xa2\x22\x0e\xa3\x38\xec\x66\x41\x8c\x98\x11\xc9\xa1\x11\x75\x21\x0c\xe2\x26\x3b\x71\x7e\xd1\x09\x6c\x33\x07\xcc\xf4\x48\xd1\x89\x60\x9c\xc1\xdb\xdc\xb1\x60\x6d\xcd\xb7\x1a\x05\x72\x2f\xa0\xb3\xda\x2f\x66\xe6\x9c\x03\x0f\xd0\x8f\xd3\xe9\x5c\xde\x16\xa0\xb7\xcc\xd6\xa8\xdd\xed\x28\x8b\x64\x4c\x20\xaa\x75\xab\xdc\x32\xaa\x5c\x4e\x7b\x0d\x44\x31\x26\x6e\x4d\x7a\x5e\x10\x23\x50\x89\xe3\x63\xf9\x6c\xb6\x70\xf1\x12\xe2\x38\xe4\x8d\x19\xdf\x90\x59\x5b\xb7\x9d\x5f\x4c\x28\x6b\xe0\x25\x47\x33\x0c\x71\x70\x07\x8f\xba\x3e\x58\x70\x8a\x21\x0c\xed\xd0\xe9\xdb\xc8\xe4\x3c\x37\xa4\xf3\xfd\x97\x0d\x0f\xa7\x26\x34\x6c\x7a\x61\xfd\xbc\x6b\x6d\xbe\xfe\x2b\xf9\x5a\x87\x0f\x5b\x96\xd7\xe8\x36\x5a\x1e\x97\x3f\xc6\xe3\x67\x38\x7a\xf7\x2c\xbe\xae\xfe\xe4\x44\x10\x9b\xa3\x26\xe2\xf9\x20\x00\x67\x44\x00\x7d\xe9\x2c\x6b\xc3\x4d\xff\x3a\xd0\x47\xc3\xee\x66\xd4\xbb\xd5\xc2\xf3\x34\xf6\x7d\xef\x99\x7e\x6e\x03\x6c\xc5\x6d\x88\xcc\x67\xf4\xe3\x45\xa4\xa5\x7d\xb0\x57\x88\xc3\xaf\x9b\x10\x4a\x55\x35\xca\x22\x95\xd9\x5a\x43\x8f\xc0\x40\x40\x47\x57\x5f\x20\x59\x55\x1c\x9b\x85\xc6\xe1\x59\xcc\x6b\xd9\x7c\x03\xf7\x12\x1b\x88\x49\x52\x79\x95\xf1\x52\x26\x7c\x05\x37\x10\x2c\xd4\x26\x0d\x15\xe9\x69\x83\x9f\x93\xa3\xe2\x0d\x4b\xa6\xf8\x0d\x28\x49\xa4\x35\x20\x83\x9d\x39\x10\x1e\xaa\x80\x55\x25\xcf\xf5\x12\x65\xda\x7c\xaa\x1f\xe7\x59\xe2\x36\x88\xbe\xc4\x1b\x68\x2b\xca\x62\xbc\x30\x0f\x48\xaa\x37\x3d\x14\xb0\x54\xcc\x08\xa4\xb8\x61\xc2\x2d\x93\x2b\x68\xd1\x77\x02\xcf\xa2\xa7\xb1\x36\x7b\x55\xd5\x4d\x63\x2a\x88\xb3\x71\xe9\x0c\x13\xa7\x82\x2b\xc7\xaf\xac\x29\xc0\xba\x05\xf4\xf6\x0b\x37\x0a\xe4\x5a\xb2\x19\x14\x2c\x49\x1f\x17\xe6\x17\x20\x11\x1d\x15\x6e\x6c\x22\x05\x23\x5d\x0f\xae\xb1\x73\x82\xa5\x60\x8d\xfc\x4a\x8f\xa8\xd0\x60\xfa\x57\x0d\xa4\x9a\x09\x2f\xab\x7d\xc1\xee\xd1\x22\xfc\x07\x97\x59\x5e\x81\x33\xf1\x0d\xf9\x96\x9e\xc0\xea\xac\x60\x1c\x0e\xe3\xb4\x91\x48\x09\x57\x1c\xb0\x07\x38\x50\x53\xc5\xe0\x9a\x83\x0e\x2a\xdb\x26\xe5\x50\x7c\x7b\xdb\x2f\x57\x9e\x75\xf7\xeb\x30\x8a\xd2\x91\x8d\xa6\x73\x76\xcb\xe7\xec\x0c\x4d\xe9\x10\xf8\x11\x8b\x5d\x34\x55\x93\x55\x2e\x4a\xe6\xc6\x8b\xef\x06\x83\x36\x58\xd4\xe2\x54\xa1\x58\x93\x84\x9e\x23\x54\xcd\x6b\xc0\x2e\x6c\x76\x3f\xc0\x50\xa3\x41\x6f\xf1\x61\x54\xc4\x73\xee\xfb\x5c\x31\x0e\xf3\x9e\x27\x14\x04\xd0\x6a\x2c\x02\x66\x33\xdf\x47\xc9\x22\xd1\x36\x26\xc6\x84\xb4\xef\xa0\x7e\x81\xfc\x40\x84\x66\x7c\x12\xcd\x41\x6f\xf7\x5c\xab\x1f\x70\xbf\x39\x6c\xe8\xa0\x5d\x81\x43\x01\x86\x02\x29\x7b\x18\xb4\x98\x58\x0c\x44\x8a\x36\x14\xf9\x08\x9e\x50\x1a\x60\x71\x13\xfd\x19\xb0\xab\x45\x0d\x0a\xef\x84\x06\x27\x00\x0a\x32\x0f\x9d\x60\x3b\x7a\xc1\x8b\x52\x89\xce\x0a\x8a\x9e\xe7\x39\xb2\xa8\x34\x9c\xcc\x6a\x92\xa4\x69\x38\xe8\xdc\x75\x76\x5d\x81\x33\xb2\xce\x1d\x0a\x1b\x26\x11\x26\x00\x76\x18\x2b\x9c\x9f\xa4\xe9\x67\xfd\xbb\x17\xdc\x4a\x93\x34\x45\x36\x20\x77\x2f\xaa\x7f\xd8\x7b\xb7\xc0\xca\x30\xae\xdd\xc8\xc4\xdf\xe9\xae\xf6\x59\xdb\x59\x97\xb5\x6d\x4f\xc4\x4d\x7c\xe5\xd3\x80\x41\x88\xb5\xc3\x38\xf7\x2d\xb5\x2e\x5f\x2e\x4e\x34\x5e\x47\x66\x3f\x0f\x0d\xf1\x3d\x62\xc4\x3d\x50\xc4\x4d\x6e\xd8\xf5\x97\x0c\xb9\xfb\xc5\x20\xcc\x37\xef\x1b\x74\x98\xcc\x6a\xf8\x1d\x7b\x5a\x5c\x6b\x1c\x71\x29\x6f\xdf\x78\xd8\xd4\xfd\x3c\xcf\x2f\x0e\x61\xa0\xfa\x0f\x65\xbf\xd0\xc2\xef\x8f\xd9\x6d\x07\x06\xad\x6a\xfa\x03\x53\xd5\x37\x87\x56\x45\x4b\xfd\x32\xb8\x2e\x6f\x10\x72\x17\xb9\xaa\x4e\x35\x76\xc4\x65\xb8\xb9\xa3\xc1\xc3\x83\xe5\x5d\xe9\x5a\x65\xb6\x88\x7a\x20\xb3\x92\x4b\xbc\x6c\x5d\x40\xdc\x9e\x85\xf6\xf4\x63\xbc\x09\x90\x14\x22\xc8\x20\xd9\x6e\x9f\x27\x92\x79\x60\xfb\x48\x9b\x6c\x55\xc5\x70\x43\xaa\xa3\x98\x30\x37\xe6\x25\x78\x64\x74\x36\x2c\x84\x19\x67\x71\xcb\xdd\x38\xe7\x1f\xce\x2d\x23\xb2\x65\x11\x3d\x98\xdf\x8e\x79\xfb\x27\x18\x0e\xf9\x38\x26\x85\xef\x9f\xe1\xa5\x02\x94\x60\x8d\x60\x50\x80\xde\xdf\xc1\xed\xcf\x14\xae\xfd\x16\x4c\x6d\x3b\x88\x22\xc3\xe4\xaf\xad\x3e\x2a\x0b\x0a\x76\xcf\x0a\xd0\x1f\x90\x1e\x7e\xc9\xb0\xe5\xec\xbe\xa1\x37\xd1\xbb\x8e\xb0\x35\xbe\xd9\xb4\x5b\xff\xfb\x76\xd3\x9e\x1a\xa5\xb0\xd9\xdf\xc6\xf9\x14\x7d\x03\x1a\x46\xd2\xb5\xac\x95\x11\x8f\xa9\xa2\x5b\x44\xd6\xc7\xe0\x45\x92\xe7\x77\xc9\xea\x7d\xd9\x71\x76\x63\x74\x00\x25\xab\x16\xc3\xf6\xfe\x89\x9a\x18\x0f\xca\xe6\xbc\x54\xd3\x35\x38\xac\x9d\xcc\xc8\x81\xf6\x48\x6b\x46\x33\xf0\x79\xe6\x2b\x70\x64\xa7\xa3\xe9\xdc\x9e\x81\xce\x55\x09\x7c\xe2\x34\xb1\x0a\x4e\x23\xae\x8f\xc7\xe5\xad\xa5\x2b\x18\xec\xb8\x45\x54\x36\xe7\x46\xd1\x34\x26\x5c\x73\x5f\x2c\x28\xa5\xd8\x7f\xcb\x3f\x4f\xf2\x92\x81\x39\x8a\x68\xe3\xb2\x8f\x66\xb8\x66\xc1\x8e\xed\x44\xf1\x08\x66\x1e\x23\xc5\x1e\xd1\xd1\x8c\x64\xbe\x8f\x04\xe5\x8b\x28\x0e\xe1\xfe\x83\x9c\x9e\x3a\x94\xa0\xb5\x88\x35\xe7\xca\xb2\x53\xf7\x64\x46\x12\x4b\x1b\x5b\xfb\xd1\x2b\x25\x6a\x9c\xcc\x5a\x70\xd2\x85\xc7\x0d\x2a\xd4\x4e\xd0\xc0\xe1\xfb\x70\xf5\x14\xdc\x33\x22\xac\x01\x53\x58\xf8\x7e\xd1\xc8\x89\x2d\x9b\x40\x1f\x50\x81\x7d\x5f\xa2\x02\xd7\xb8\x46\xed\x95\x36\xc4\x74\xec\x60\xe1\xa9\x26\x3a\x48\xe1\xc0\x38\x4c\xaf\x9a\xc2\x64\x80\x67\xb1\xaa\x12\x4e\x8f\x81\xb9\x9a\x01\x49\x7d\x37\xc0\xb3\xc9\x0c\x0b\xab\xb9\xe5\x64\x86\x09\xbf\xa5\xa5\xef\x97\x93\x49\x6d\xdb\xee\xf3\x63\x0d\x99\x6f\x6b\x63\x44\x00\x1b\x22\x1c\x47\xe0\x9e\xf9\x63\x67\xe6\xc1\x74\xc8\x54\x6f\xb4\x65\x03\x39\x33\x9a\xe8\xd3\x0d\xf0\xd2\xec\xe4\x1e\x58\xd2\x91\xa8\x49\x2e\x5c\xfa\xdc\xaf\x88\x57\x95\xac\x2a\xa4\xeb\xb3\xcd\xab\x22\x83\xd5\x8d\x32\xb0\xf4\x63\x3f\x66\xb2\x73\x2d\x48\x8b\xb0\x33\x80\xbd\x88\x11\x7b\x42\x61\x4c\x7f\x16\xd6\xf6\x16\x87\x3c\x6e\x01\x8a\xc8\xaa\x72\x96\x54\xd5\x3d\xd0\xd7\x3c\xb0\x8d\xf6\x6f\x3a\x72\xca\x0d\xf6\xb7\xa8\x1b\xbc\x91\x3b\xa6\x47\xaf\xdd\x35\x6b\xcf\x26\x7f\x6c\xbd\x83\x9d\xd4\x27\xd6\x5e\xc2\x20\x5a\x88\xb1\xc9\x7c\x7f\x83\x20\x98\x40\x21\x76\x59\xc9\xf0\x22\xb3\x77\xbd\x04\xa9\xe0\x0c\xa4\xb5\x24\xcb\x95\x40\xde\xe4\x95\x5b\xc6\xdb\x8c\x80\xa5\x43\x69\x36\xba\x16\x47\x48\xc4\xec\xa9\x4d\x81\x9d\xe0\x9d\xfc\x2c\x17\xae\xeb\x16\x4f\xbd\x64\x6b\x56\x74\xa6\xa0\x39\x61\x8d\x22\x8f\x0b\x99\xad\x1f\x3d\x45\x48\xc5\xa6\x60\x65\xe9\x11\x07\x29\x22\x4f\x23\x0d\x0f\x5f\x48\x7d\x1a\x93\xc8\x2b\x58\x29\xf2\x7b\xe6\x11\x4f\x8d\xae\x57\x81\x42\x77\x57\xc3\xb5\x74\x3f\x4d\x89\xad\x28\xf5\x74\xad\x10\xc5\x96\x78\x6a\xaa\xfe\xdb\x4a\x67\xc4\xd4\xa3\x2a\x8d\x49\x41\xbd\x3d\xe3\x29\x30\x0a\x19\x3d\x95\x32\x91\x43\x30\x55\xd4\x24\xc9\x8f\xc9\x63\x39\x78\x5d\x19\x2c\x61\x0b\x66\x7a\x29\xcf\xc0\xce\x83\xf5\xf1\x06\xdd\x30\x60\xb1\xcd\xb1\xbf\xe2\x74\xb2\x7d\xa7\x17\x5a\x06\x6b\x6a\x6c\x89\x9b\x5d\xca\x4e\x7c\xca\x0b\x78\x56\xd3\xfd\x0d\x62\x51\x11\xfd\x39\x06\x12\xa1\x9f\xe6\x22\x2a\xa2\x59\x1c\xa3\xb3\x16\x33\x08\x64\x38\x74\x69\xd8\x1c\xc0\xd4\x01\xe8\xe6\x11\xe4\x09\x0d\x39\x48\x31\xc8\x0a\x9a\x2c\x94\x07\x66\x3d\xcd\x14\xa9\x77\xb8\x40\x30\x94\x51\x11\x4d\xe3\xb1\xa7\x76\xad\x17\xeb\xc6\x32\xb8\x1c\xa7\x6d\xb2\xc6\x35\x26\x4c\x07\x97\xc5\x6d\x6b\x35\x51\x73\xe7\x1a\xce\x39\x4e\x7c\xd3\x76\x17\x27\xa8\xb1\xa4\xea\xbb\x79\xe8\xdc\xa5\xbe\x40\xcb\xb9\xbe\x8b\xe4\xe7\xd7\x7f\xe5\x73\x7d\xa4\x79\x2b\xb0\x89\x59\x41\x0b\x33\x45\x25\x39\x80\x0f\x03\x6f\x3b\xe7\xdc\x22\xa9\xc4\x04\x13\x41\xe0\xed\x56\x5b\xef\x5f\x95\x2c\x5f\x4f\x60\x4e\x0e\x70\xa2\x8b\xe7\x39\xc4\xde\xfc\xa3\x97\xff\x01\x99\x57\xc3\x27\x1b\x94\xe3\x45\xb6\xc8\x2d\xb6\x48\x90\x20\x9c\xbc\x26\x19\x36\x8f\x3f\x2a\xce\x2c\x44\x62\x3c\x26\x1f\xce\xd4\xa4\x72\xb3\x78\x6a\x4d\xb0\x2a\x5b\x8c\x28\x7d\x0d\xd4\xde\x20\x96\x03\x55\xa8\x85\xa0\xac\xaa\xb8\x5d\x5a\xc8\xad\xa7\xa2\xae\xc9\x8a\x66\x8b\xdc\x85\x64\x85\x0d\x73\xe4\xe0\xaa\x16\x86\x03\xf6\xb0\x62\xe0\x62\xf0\x57\x21\xde\x2b\x09\x7c\xf8\x0b\x62\x64\x15\x94\x8a\x37\x7c\x5b\x24\x2b\x25\x0d\x8f\x67\xcf\xa8\x22\x8a\xaa\x83\x3f\x0e\x74\x90\x1b\x38\x03\x9a\x60\xba\x36\x97\x8b\x15\xc2\x21\x72\x5a\xd9\x30\x09\x2c\xa7\x6e\x1e\xb9\x8d\xd0\x0b\xd9\x90\xf6\x8a\x66\xf2\x6d\xb6\x63\xe2\x20\xd1\x4a\xd5\xfd\x81\xed\xa9\xb0\x73\x34\x8d\xa3\x8f\x63\x90\x76\x13\x34\x25\x8c\x6c\x50\x86\x17\x59\xf8\x9a\xb0\xce\x94\x03\x27\xd7\xcf\x29\xf1\x42\x86\xaf\xe1\xe3\xd3\xb3\x8f\x05\x5e\x14\xe1\x8f\x18\x77\xf7\x87\x79\xbc\x74\xfd\xd5\x88\x2a\x46\xc4\x10\x07\x46\x32\xed\x0a\x26\xce\x99\x68\x3e\xc0\x1a\x25\x54\x46\x4f\x15\x7f\x2b\xa3\x4f\xe2\x79\x16\x49\x85\x48\x68\xa2\x7a\x45\x4a\xdf\x87\x87\x8e\x95\x3f\x2d\x6b\xc2\xa3\x8f\x27\x2c\x8e\x9e\xc6\x36\xac\x97\x4d\xf9\xd8\x4d\x99\x42\x0e\xc5\x5d\x10\x3b\x65\xea\x05\x13\x5d\xa9\x54\x09\x8a\x94\x63\x22\x22\x19\x4d\xe3\x98\x0e\xe0\x66\xf8\xd2\xc1\x2b\x8a\x63\x36\xea\xbc\x70\x98\x3f\xe8\x16\xa2\x49\xc3\x4f\xd4\x98\x64\xcd\xc4\x0a\xac\xd5\xa2\xb0\x97\x04\x11\x98\x88\x9a\x1c\xb7\x6c\xc8\x99\xe3\xec\x42\x40\x4e\x25\x29\xa8\xbd\x1c\x8f\x64\xd4\x5c\x63\xe9\xf4\x25\x71\x60\x0e\x61\x52\x0e\x84\x31\x69\x31\x98\x62\xa9\x94\xa4\xa7\x11\xa7\x7a\xea\x37\xf9\x6c\xb6\x38\x6b\x23\xe4\x64\x32\x91\x55\x95\xb8\x9b\x17\x64\xb8\xba\x56\x68\x4e\xde\x52\x25\xbe\x29\x96\x26\xd1\x18\x1c\x0e\xfd\x6c\x6e\x92\x98\x7d\x45\x46\x12\x93\x86\x8e\x42\x9c\x5e\x20\xa4\x08\x57\xd5\x06\x65\x11\x8f\x7d\x5f\xfd\xd5\x2c\x4d\x73\x44\x9c\x68\xaa\x87\x1d\xa3\x9a\x27\x90\x9b\xa8\x66\x9a\xda\x9d\x3b\xb7\x5a\xa0\x36\x22\xe1\x67\xf4\xe6\x1d\x7a\x75\x9f\xe4\xd5\x6b\x2e\x59\xc1\x93\xbc\xfa\x3e\xe1\x1b\x56\x7d\xaf\x66\x8e\xf1\x15\xab\x74\xb8\x96\x0a\x4c\x9b\xff\xf1\xfd\x6b\x0c\x38\xf8\xc9\xcd\xfc\x12\x7a\xa1\xae\x5d\x30\x3e\x81\xec\x5d\x0a\x1d\x74\xc5\x3c\x06\xc7\xa4\xe0\xbe\x2f\x7d\xff\x33\x13\x41\x28\xe0\xc9\x4e\x63\x63\x37\x8b\xbd\x33\xb8\x69\xe9\xaa\x69\x29\xbc\xf2\xc6\x32\xd8\xb1\xb2\x4c\x36\x8c\x48\x8d\x6a\x40\x55\x71\xd4\x8a\xe5\x57\x36\x27\x75\x49\x7b\x07\xd7\xb8\x68\x15\xc8\x8c\xac\x71\x0d\xd3\xf2\x79\x07\x76\xb4\x72\x18\x6a\x1d\x02\xa2\xcf\xf5\x32\x30\x1c\x19\x0e\x25\xee\xa0\xab\x7e\x7f\x10\xc3\x8d\x60\xd3\xf2\x94\xcd\x05\x8a\x33\x02\xd9\x7f\x4c\x32\x19\x9a\xe7\xce\x86\x40\xfa\x98\x7e\x31\x99\x98\x8a\x21\xe7\x31\x30\x15\xe0\xaa\x42\xcd\x0b\x1d\x4d\xc9\x68\x3a\x02\x4f\xf1\x4e\xfe\x67\xd3\xaa\xfa\xbc\x07\xb4\xd1\x31\x06\x5d\xa0\x9d\x40\x18\x15\xd5\x83\x6b\xb9\x80\x9f\x15\x6e\x30\x11\xeb\x7b\x01\x9d\x5f\x7e\xfb\x8d\xf1\xc3\xfc\x5a\x24\x29\x4b\x3d\xf2\xb3\x42\xee\x83\x79\x75\x2c\xe7\x9f\x9b\xc6\x10\xae\xbd\x95\xd8\xed\x73\x26\xc1\xd8\xa3\xd0\xc9\x6f\xd4\x2e\xa8\x2a\xc8\x6e\x44\x56\xf7\x8b\xef\x8f\x8a\x7e\x4c\xbb\x20\x15\x6f\x56\x85\xc8\xf3\x45\x67\xad\x4d\x3b\x10\xec\xf7\x3c\x16\xf5\x85\xae\x9f\x67\xb4\xfd\xd6\xbb\xe7\xb7\xbe\xb9\x99\xb9\x43\xcd\xf2\x43\x03\x06\xe6\x94\xf2\xb9\x73\xa3\x04\x55\x32\x38\x57\x9c\x10\x1d\x4d\xe1\x70\xb2\xbc\xca\xf8\x15\xc7\xbf\x41\x8d\x25\xe1\x51\x19\x93\xd1\x14\x6a\x6d\x7c\xdb\x3b\x57\x7a\xaa\x92\x40\xba\xe0\x46\xd3\xd1\x14\x8c\xd2\x51\xb2\x40\xed\xc1\xb7\xbd\x53\x00\x87\x28\xa7\x92\x9c\x1f\xd7\x35\x92\x5f\xab\x22\xe7\x10\xb2\xd1\x1c\x39\x35\x36\xf1\x12\x3c\x89\x09\x27\xc9\xa2\x08\x0b\x7b\x6f\x64\x19\x93\x92\xd8\x4f\x8e\x1d\x7c\xb6\x60\x61\xbe\xb0\xfd\xc0\xe1\x61\xa1\x83\xb2\x28\x49\x4c\xd4\xe4\x27\x7a\xf3\x6e\xb2\x2b\x27\x37\xe4\x1f\xf4\x66\xa2\x6d\x04\xb0\xab\x91\xfa\xa1\xab\x37\x0f\xa4\xf8\xc7\x7e\xdf\x58\x17\x34\xd9\xbe\xe8\x98\xfa\x58\x0b\xb2\x9f\x88\xb7\x2b\x27\x4e\x48\x9d\x7f\x90\x1f\xb4\x49\xc2\x3f\x87\x76\x71\xf7\x78\x5b\x47\x5c\x72\xdf\x47\x63\xe7\xf0\xbb\xed\xe2\xdf\x01\x79\x64\x65\x60\x2e\x4f\xd5\xb6\x15\xea\x69\xfc\xf7\xe0\x90\xa5\xe3\x71\x0d\xbf\x74\x46\xfe\xee\xde\xf1\x0c\xe1\x8f\x86\xd4\xe5\x91\x5b\x5b\x2f\xc8\xca\xa9\x26\xff\xd4\xb7\xff\xb9\x51\x1d\xbb\x25\xa8\x0c\x8d\x86\x5f\x87\x47\x69\x3d\xe4\x89\x9b\x8f\x18\x33\x65\x49\x56\x82\xaf\xb3\xcd\xa1\x00\x15\x08\x1c\x92\x63\x22\x6b\x52\x32\x79\xe9\xf6\x48\x7d\xf6\x04\x23\xb0\x51\x8b\xfb\xba\x3d\x89\xb3\xe8\x0b\x24\x71\x4c\xf9\xbc\x7b\xed\xa8\xfe\x52\xe0\xee\x25\x99\x59\xff\x9e\x6a\x67\xdd\x35\xb4\x43\x40\x93\x4e\xc3\x61\x6f\xe4\x4a\x1e\xeb\x24\xe8\x1e\xd4\x24\x59\xad\x58\x59\x5e\x52\x7a\xb7\xd5\x57\x95\x1c\xd0\xd0\x4a\xdf\x6f\xb2\xf0\x45\x73\x30\xa3\x7a\x18\xea\x73\x9a\x52\xbf\x12\x8e\x49\x7b\xcc\xb9\xe0\xa1\xc4\xe7\x6a\xb3\xce\x39\x5e\x7f\xb1\x3b\x5b\x5b\xdb\x08\xdb\x57\x89\x4f\x9c\x22\xd9\xbb\x38\x58\x31\xb3\xa0\x87\xfe\x42\xf5\x85\xaa\xf1\xe2\x8c\x5f\x15\x8b\x48\xc6\xa1\xec\xe8\x6c\xf1\xb9\x05\xae\xb9\x36\xa5\x88\x64\xc4\xe3\xb8\x46\xee\x4c\x28\x1a\xe2\xdc\x73\x8b\x20\x7e\xea\x87\xc0\xce\x70\x84\xa6\xce\xde\x57\x25\xca\x6c\x93\xf2\x65\x22\x93\x3f\x0e\xf3\xed\xd8\x7d\x7f\xd4\xef\x8f\x54\x2c\x96\x2a\xfe\x25\xb8\x2e\xfe\x9d\x7c\x65\x7e\xff\x65\x8c\x17\x4e\xda\x72\xe1\x7a\x59\x57\xcb\xc8\x3e\xc7\xf8\xc9\x0d\x61\x8c\xde\x44\xcf\x27\xff\x8a\x5d\x54\x23\x1d\x27\x27\x4f\x16\x07\xa0\x42\x20\x35\x26\x79\xc9\x3c\x4d\x43\x91\xa7\xb0\xa8\x8e\xb8\x04\x61\xa5\x18\xa5\x74\xcc\xc6\x9e\xb7\x18\xb3\xf0\x5f\x8d\x7d\xc5\x97\x6f\xbe\xfd\x9b\x36\x01\x00\x30\x75\x50\x15\x67\x67\xf6\x77\x2d\x70\xf5\xef\x60\x01\xe7\x04\xea\xa5\x89\x4c\x26\x8a\xdb\xb1\x88\x8c\x31\xe2\x4d\x9e\xf8\x5e\x3f\xda\x40\x1f\x74\xe1\x96\xe0\x8e\x61\x60\x81\xb1\x16\x21\x39\x95\x0c\x71\x47\x8c\xac\xbf\x72\xc0\x58\x13\x1a\x4e\xbb\x51\x07\xb9\xa3\x02\x1b\x5a\x4c\x93\xed\xab\xc0\x7c\x44\x0c\x57\xd5\x97\xce\x5b\x4d\xd2\x6e\x99\xce\x3e\xfc\x2a\xd0\xfb\xd4\xf6\xc1\x6c\x9d\x97\xfd\x22\xf8\xf4\x95\xe1\x29\x4c\xa0\xc6\x9f\x3f\x54\xeb\x97\xfd\x5a\x7f\xbe\x58\xed\x97\x9d\x6a\x81\x11\x72\x6c\x02\xce\x1a\xe9\x85\xd4\xd7\x47\xc4\x24\x51\x82\xb4\x70\x6c\x52\x3b\x4b\xac\x2d\x5c\x9c\xe3\x1d\xa0\xdf\x5f\x01\x42\x11\xda\x9e\x4b\x38\x67\xe8\xa3\x2f\xf5\x17\xe2\x99\x49\x54\x2b\x59\x7a\x6a\x11\x79\xe3\xed\xe5\x6c\xe8\x04\x24\x05\xd5\x10\x2a\xa8\x7a\xd1\x6c\x75\x1b\xc3\x4c\x83\x92\x3e\x90\xfa\x02\x15\x46\xf7\xf9\x89\x92\x86\x99\x76\x6f\x83\xcb\x9f\xe7\x5f\x02\x30\xf4\xdb\x25\xa3\x69\x63\xa1\x68\x6f\x55\x3a\xd7\xb4\x68\x14\x09\x02\xaf\xc3\x60\x6b\xf0\xb2\x37\xf9\xe3\xf0\xb7\xfe\x05\xfd\xf6\xa4\x20\x5b\x23\xe1\x60\x5c\xd9\x45\x83\x88\xdb\xd9\x02\x3b\x82\xc6\xc8\xbd\x97\x07\x46\xe3\x66\xd0\x10\xfd\xbb\x3d\x53\x0b\x8f\x6b\x13\x74\x95\x9c\x8b\x80\xfa\x8b\x9a\x86\x61\xe8\xec\xdd\xea\x7f\xd6\x92\x01\xb0\x66\x1a\x34\x94\x59\x10\xfb\xf5\xc0\x0e\x6c\x98\xe8\xaa\x01\xb6\x76\x54\x14\x3c\xfb\xd6\x0f\x1e\x1e\x7b\x50\xc8\x23\x05\xfd\xb2\x21\x4b\x84\xfb\x3e\x84\x6d\x3e\xbb\x44\x5e\xe5\x72\xf6\x83\x6b\x73\xc3\x31\x0e\x8b\xf6\xe4\x09\x6e\xc2\xab\x49\xca\xce\x3b\x85\x4f\x70\x7f\x9d\x6a\x5f\x87\xfa\xa5\xc7\x00\x72\xe9\xc6\x8b\xe6\x4a\x2a\xb8\x9d\xaa\xf1\x7e\xa6\xc7\xe0\x67\xc8\xa6\x84\xc4\xd2\x06\xe1\x71\xa6\xe7\x18\x98\xd6\xf4\x06\x9c\x7b\x19\x6f\x54\xe8\xd4\x5c\x2d\xe3\x54\x58\x4c\x26\xe0\x33\x89\x54\x47\xa8\xb1\x76\xb5\x01\x7b\xdd\xb2\x98\x18\xa2\x24\xe0\x44\x8f\x34\x27\x02\x09\x38\x58\x8e\x0a\xdf\x87\x3d\x0b\xc7\x45\xa0\xab\x40\x0a\x4f\xb4\x7d\x1d\xbe\xb9\xdc\x4c\x3d\xe4\xf0\xe6\x0d\xba\xd1\x8b\xc0\x01\xf5\x35\x53\xcd\xc9\x49\x1f\x46\x5d\x56\xac\xf7\x15\x3d\x0e\x36\x8a\x64\xb3\xcc\x3c\xd6\x97\x1a\xf5\xb1\xd3\xd0\x2a\xe9\x7e\x3e\xb5\x27\xd3\x03\xc6\x41\x48\x52\x46\x18\x55\x13\x48\x14\xfe\x38\x83\xf8\x5b\xbe\xb0\x6b\x6b\x11\x5c\x73\xcf\x45\xc3\x90\x85\x83\xc0\xde\x85\x8c\x66\x7b\xcd\xbb\x50\x60\x76\x02\x31\x6b\xc8\xb4\x85\xbc\x5d\x39\xc5\x47\x81\x01\x4e\x0b\x1a\xed\xd6\x19\x80\xcd\x0f\x6f\xbf\xc1\x4a\x56\x39\x4b\x8a\xbf\x7f\xb0\x1e\x03\x93\x1a\xe2\x49\x14\x0f\x6a\x04\x5d\xb6\x6e\x46\xb2\xae\xee\x49\x93\x07\x92\x74\x8c\xb6\x4a\x17\xf6\x27\x93\xa2\xaa\xb2\x8e\x44\x2e\x48\xa4\x18\xa7\xf9\x07\x16\x4e\x2f\x04\xb8\xf3\x98\xfd\xd8\x86\xb2\x42\xdc\x60\x04\x11\x25\x31\x61\x1d\x68\xd5\xb7\xac\x00\x44\x2a\x52\x30\x1e\x13\xf3\x06\x40\x58\xb6\x02\x5c\x89\x5c\x8d\x9d\x6c\xd4\x46\x85\x62\xa1\xc6\x93\x78\xa1\x38\xad\xf4\x7a\x19\x54\x78\x99\x8e\xd1\x22\x8c\xd8\xab\x18\x3e\x2c\xd3\x71\x85\x6f\xcc\x25\x71\x24\x63\xb4\x7f\x01\x2f\xdc\xde\x8b\x69\x85\x91\x37\x2e\xd8\xd8\xc3\x20\xff\xfd\x4f\x7c\xdd\x5c\xca\x2b\x18\x8d\xbc\xb7\x62\xef\x11\xef\xfb\x6c\xb3\x95\x1e\xf1\x3e\x13\x52\x8a\x9d\x47\xbc\xaf\xd9\x5a\x7a\x31\x49\x86\x2f\x70\xf5\xb8\xe0\xc0\xc0\x21\x46\xf5\xc5\x5b\xa5\x7c\xcc\xe1\x52\x34\xb8\xa8\xbb\x32\x3e\x1d\x9d\x54\x05\x65\x8d\x59\x5e\x2f\xca\x33\x51\x42\x57\x53\xeb\x31\x58\xc1\xae\xf6\x4c\x49\x0f\x2b\x71\xe9\x4c\x17\xd0\x58\xc1\x92\x84\x9e\xea\x79\x73\x49\xbe\xc4\x49\x24\x62\xdb\x7c\x24\x62\xd2\x3e\x52\xa9\xaf\xd3\xe1\xcd\xad\xa9\x80\x88\xb1\x5b\xda\xc9\xad\x2a\x6a\x45\xa8\x96\x9b\x3d\xb0\xa1\x4e\x3c\x9d\x92\x92\x16\xe7\xb1\x42\xaf\x8a\x60\x75\x28\x90\x1b\xde\xdd\x39\xdd\x5f\x19\x62\x01\xd6\x0c\x07\xaa\x40\x22\x57\xbc\x2a\x87\x30\xaf\x08\x32\xe8\x5b\xf5\x23\x19\x2f\x3c\x2f\xf4\xf6\x0f\x1e\x26\x2b\xda\xfb\x54\x55\xea\xc3\x88\xd2\xdc\xf7\xc7\x07\xec\xfb\x19\xd3\xa6\xba\x4d\x13\x3a\xd6\xc5\xca\xf7\x57\xd1\xc7\x31\xb8\x15\x9f\x0e\x37\xf4\x29\xc9\x69\x5e\x55\x2a\x8d\xac\xe8\xf8\x50\x55\x33\x07\xcc\x8f\x7a\x32\xa0\x87\xab\x71\x8e\x09\x9a\x4d\x04\xbe\x46\xb3\x09\x12\xaa\xaf\x37\x87\xaa\x0a\x3e\xc1\xf8\x96\x4e\x7d\x1f\x25\x74\x8a\xc9\xea\x86\x8a\xf9\xea\x9a\x3e\x25\x67\x85\xcd\x29\x7a\xed\x18\xdd\xaf\xe8\x78\x55\x55\xaa\xd9\xa9\xa2\x67\xd1\x2c\x5e\xac\xc6\x48\xfd\x8e\x67\xf8\x9a\x47\x4f\xe3\x70\xac\xfe\x92\x42\x6d\xa5\xe0\xc0\x33\x49\x73\x52\x04\xa5\x4c\x0a\x49\x57\xa4\x08\x18\x4f\x29\xf8\xed\x82\xf2\x21\x67\x00\x0c\x76\xa5\x56\xcc\x8d\x68\xdb\x07\xbb\xc2\x71\x13\x22\x19\xcd\x99\x2b\x32\xeb\xb8\xab\xc1\x9d\x48\x1f\x3b\xb7\x7d\xf0\x9e\xeb\x17\xc4\x16\x30\x40\x2b\x1d\xa0\x25\x1f\xba\x84\xb2\x01\x76\x4d\x76\xbd\xbb\x5c\xac\xde\x7b\x98\x40\x17\x68\xd6\xb9\xc0\x73\xcd\x7a\x2e\x2a\x8a\x91\xd4\x76\x13\x53\x92\xb4\x11\x21\xc4\x6d\x32\x17\xe3\x31\x46\x05\x04\xd5\x36\xbb\x12\x62\xb5\x14\xdd\xbd\x48\xe4\x02\x35\x3d\x50\xab\x90\x29\x68\xd7\xf8\xac\x70\x86\x50\x55\xda\x95\x3c\x12\x0a\x14\x7b\x95\x50\xb8\x88\xcd\xd3\xea\xc4\xde\x56\x4f\x18\x58\xbe\xe8\x7a\xf5\xf1\x3f\x0e\x75\x8b\x23\xa7\x45\x9d\x42\x34\x3b\xec\x34\xac\xb5\x5c\xb0\x27\xe9\xb4\x19\x97\x3e\x0c\xca\x74\xbc\x70\x35\xc2\x5e\x7f\xd4\x97\x8e\xe9\xa4\x43\xc0\xcb\xad\x38\x0e\x6c\xbf\xb5\x21\x56\xc0\x72\x6e\xb3\x74\xe8\x6c\xdd\xe4\xc1\x35\x91\x62\xb3\xc9\x87\x08\x99\x77\x27\x44\xce\x12\xf7\xe8\x73\x61\x18\x75\xd5\x30\x32\x46\xe3\xaa\x01\xfb\xdc\xa7\x9e\x89\x69\x65\x71\xd4\xbf\xb6\xa0\x7d\xd5\x65\xeb\x86\x44\xec\x99\x16\xc4\x6d\x08\xa4\x0a\x82\x22\xc1\x25\xe6\x29\xa3\x37\x5d\x97\xa0\xae\x51\x1a\xbe\xc9\xc8\x56\x15\x7f\x52\xbd\xdb\x89\xf4\x90\xb3\x27\xd5\xf2\x06\x2d\xc2\x5f\x92\xfb\xa4\x62\xab\x5d\x82\xcb\x55\x91\xed\xe5\x4d\x46\x36\x8c\x9e\x74\x5c\xb5\x30\x9a\x11\xcf\x5e\x10\xb4\x3b\xe4\x32\xdb\xe7\x8c\x7e\x64\x9f\x3e\x7a\xe6\x11\xaf\xbd\x1a\x28\x26\x72\xcb\x92\x54\x17\x02\x7f\x4d\xfd\xdd\x3c\xc6\x64\x25\xf2\x30\x7a\xda\x7c\xbc\x5d\x89\x7c\x53\x88\xc3\x5e\x67\x6b\xde\x9c\x12\xb2\xe8\x14\x90\x6a\x63\x9a\x4a\xe1\xd1\xcd\x9a\x86\xd1\xc7\xfd\xac\xb7\xb2\x30\xd9\x8b\x67\x03\x65\x7e\x36\xfe\x80\x61\x34\x25\x9e\x47\x3c\x2f\xae\xe7\x1b\x16\x88\xbd\x84\x9e\x50\xfd\x9c\x09\x4e\x36\x2c\x80\xd2\x2a\x49\xae\x85\x90\xea\xc1\xf6\x18\x9e\x13\x7d\x32\xb2\x81\xc3\xef\x24\x85\x12\x5b\x78\x4d\x3b\x61\xa4\x1c\x0b\x2e\x8b\x12\x2f\xdf\x72\x77\x7e\x8d\xda\x85\x3b\x10\x75\x58\x12\x1c\x0e\xd7\xd4\xbf\x50\x68\x31\x70\xc7\x90\xad\x21\x8a\x49\x4f\x7d\xa7\xfd\xd6\x16\x8d\x8d\x27\x03\x65\xb3\x13\x13\xe6\xbe\x8f\xac\xe8\x14\xd0\xac\xc1\x51\xfc\xb6\x98\xf3\xf1\x18\xeb\x2d\xcf\x22\x1e\x13\x6f\x93\x8b\xbb\x24\x7f\x75\x9f\xe4\x1e\x38\x02\x6b\x3c\x24\xfb\xdf\xb0\xd6\x2e\xef\x14\x74\x57\xfe\x9f\x16\xcb\xe3\x78\x7e\xd3\x4e\xe7\xc3\xa5\x60\x34\x36\x98\x16\x59\x53\x69\x50\xb7\x25\x00\x9f\x17\xc9\x06\x70\x38\xb6\x81\x5e\xa6\x64\xdb\x76\x36\xbd\xdd\xce\x53\xed\x52\x00\xc1\x6a\xd2\x18\xeb\xf0\x8f\x02\xf7\xcf\x18\x04\xc6\x76\x4e\xf6\x44\x38\x01\x61\x44\x1c\x0a\xdc\xdc\x74\xbd\x63\x5a\x89\x25\x30\x3e\x25\x14\xe2\x2a\x74\xae\xc0\xea\x7b\x15\xa7\xd9\xbd\x42\xb2\x25\x45\xa9\xa1\xe6\x02\x57\x55\xa4\xe1\x13\x9f\x07\x9c\x3f\xd0\x0d\x8b\xca\xb8\xaa\x36\x2c\xb0\x00\x4d\x12\xc7\x3d\xf7\xa0\x08\xeb\x31\xd8\xca\x5d\xfe\x5d\xc1\x8c\x55\xac\xc0\xe3\x83\x22\xb1\x2b\x70\xa2\x77\x22\xb8\x24\x34\x69\x03\x1a\xcf\xdb\x01\x26\x9d\xbb\xec\x51\x42\xd7\xae\x85\xb1\x1b\x32\x94\x7a\x9e\xd6\x0d\x98\x48\x1a\x76\x84\x6f\xd9\x03\xd0\x45\xb8\xee\x61\xdd\x2b\xa1\xd6\xa1\xb9\xd6\x70\x1f\xa5\x26\xa0\x44\x01\x2e\x3b\xc6\x20\x51\x90\x02\x6c\x1b\xc1\x04\xc8\xc6\x33\xb0\xd3\x9c\x53\x87\xd7\x14\x3d\xa2\x2f\x94\x5c\xfc\xc8\x50\x77\xea\x05\x26\x9e\xc6\x7a\x1e\x9c\xf0\xdc\x33\x94\x60\xc2\xf1\x69\xe5\xf4\x25\x89\x56\xaa\x2f\x5b\xbb\x8a\x36\x98\xa1\x87\x1b\x57\x50\xd1\xa8\x70\xd6\xf5\xe8\xcc\x60\xa9\xb8\x08\x80\x9d\xce\x14\x17\xe0\x40\xd2\xb3\x2f\xbf\x73\xd7\x1a\x50\x05\xe0\x45\xba\x9f\xed\x7d\x73\xc4\x6b\x6f\x9e\xeb\xe7\x31\xf7\xaf\xc9\x81\x9b\xda\xc8\x56\xc7\xdd\x7c\x91\x0b\x0e\xf6\xdf\xea\x17\xd6\x73\x34\xc5\xbd\xb7\x06\x80\x6c\xa8\x4e\xd2\xf5\x17\x57\x6b\x9f\x14\x2c\x79\xf6\x70\x7b\xd3\x3c\x7b\x64\x1b\x70\x01\xd5\xbf\xd0\xa5\x28\x04\xfb\xbc\x50\x73\xc7\x97\x1b\x69\x0a\x79\xa7\xa6\xbb\x7f\xd5\xee\x51\xd1\xbd\xf7\xec\xf1\x86\xbc\x35\x04\x74\x27\x0e\x25\xab\xf6\x22\xe3\x92\x15\xd5\x4a\x3b\xea\xee\x18\x3f\x54\x69\x91\x6c\xaa\xb4\x10\x7b\x5c\xad\xf2\x6c\xf5\xfe\x86\xbc\x80\x32\xd1\xbb\x20\xbe\xc6\x4a\x34\x0b\x50\x30\xc6\x15\x76\xb0\xd0\x2b\xe6\x5e\x11\xd0\x24\xbf\x77\x92\x9d\x5b\xb8\xdf\x30\x63\x72\xd4\x08\x0a\x9d\x18\xac\x8e\xfa\xb8\x2d\xf3\xb2\x17\xf1\x0a\xac\x5c\x48\xd9\x3d\xf5\x6c\x8e\x89\x4e\x67\xe2\x2d\x07\xed\x64\x51\x55\x9c\x58\x0d\x34\x6e\x4f\x46\x25\x86\xfa\x4b\xa8\x5f\x46\x65\x4c\x84\xc3\x52\x65\x6b\xe3\xff\x52\xe8\xa8\x31\x94\x66\x0b\x94\x51\x25\x94\x37\x75\x85\xe6\x83\xef\x9f\x1f\x5b\x71\x95\xbb\x20\x45\x93\xd7\xbc\x3a\x5d\x31\xc1\xbf\x33\x9c\xd1\xf7\xac\xd9\xd0\xa3\xac\xf1\xdb\x77\x83\xd7\x0b\x90\x39\x32\x82\xb2\xa1\x23\xc7\x23\xc2\x81\x58\xaf\x11\x03\x93\x9c\x21\x2b\xc1\x1a\x07\x9b\x43\x96\xd2\x04\x7e\x20\xf2\x18\xbc\x1f\xe1\x67\x3c\x06\xeb\xa9\x73\x3d\x07\xbb\x67\x5c\x6a\x23\x1f\xed\x9f\x90\x91\x02\x0e\x74\x6b\xf3\x8d\x9e\x34\xdd\x0a\x4f\xe7\x7e\x4a\x9d\x28\xfe\x2e\x75\xb2\x51\xf4\xc9\xa3\xd5\x35\x62\x13\xef\x9e\x07\x5b\xb8\xa2\xa5\x00\x5e\x1e\x09\xca\xb1\x4d\x01\xd3\x1c\xeb\xf0\x0f\xfa\xba\x0b\x8e\x61\x77\x0c\x82\x71\xd8\x81\xf2\xde\x40\x09\x3a\xd0\x47\xdd\xf9\x12\x57\x95\xf3\x06\x71\xf3\x50\x42\x1f\x4d\x93\xfa\x1c\xdc\xbe\x75\xac\x3f\x0c\x33\x3c\xc0\x76\x1c\x55\xbf\xf4\xb4\xc9\x22\xdb\x6c\x58\x01\x17\xa1\xeb\x2b\xdd\x17\xf6\x93\x62\xe4\xc1\x67\xde\x0a\xe7\x8e\x29\x90\xb9\xfc\x55\x09\xc7\xc8\x28\x68\x3d\xec\x9e\xc0\x29\x82\xd8\x55\xd9\xe7\x93\x09\x4e\xe9\x86\xa2\x92\xbe\x30\xd4\x53\x46\x79\x6c\x82\xb8\xcc\x62\xb2\xa5\xa8\x8c\x9e\x9a\x9b\x61\x4c\x30\x91\xc0\x46\x13\xc1\x24\xf5\x7d\xb4\xa6\xb6\x73\x10\x87\x21\xc9\xa3\x34\xae\xaa\x53\x4d\x52\x8a\xb2\xc5\x3a\x48\x59\xce\x36\x8a\x9e\x3d\xee\x59\xb8\x0e\xee\x32\x9e\xc2\xd1\x52\x55\xa5\xe4\x62\xd9\x15\x6d\x95\xd2\x10\xa5\x32\x25\xa2\xc8\x36\x50\xc7\x46\x1f\xe2\x14\xc4\x2c\x70\xc8\x89\x5a\xa2\x50\x2f\x18\xb1\x4b\x1d\x66\xc4\x0d\x2c\x10\xc2\xc2\x5f\x88\x3a\x60\x9c\x5e\x31\x51\x08\xbd\xdc\x27\x2b\x16\x6e\x4d\xa4\x94\xc0\xc3\xb5\x22\x88\x68\x4f\x0f\x9a\xbd\x41\xe6\x91\x46\x31\x6e\x46\xf7\x42\x1c\xb8\xa4\x53\xb2\x56\x14\xe2\xb0\xf7\xfd\xd1\x6c\x44\xa9\x79\x6b\xfd\xff\xb7\x24\xc1\x55\x75\x6e\xd7\xe1\xfb\x03\xb6\x1e\x29\x49\x30\x26\x6b\xf5\x41\xcd\xb3\xfa\xb5\x35\xad\x30\x59\x59\x00\xb7\x00\xdb\x4d\xa0\x7a\x3a\x94\xe4\xbd\xd8\x5b\xef\x86\x7d\xb7\xbf\xe3\x31\x99\x92\x15\x0e\x0d\xe7\xb1\x82\xa3\x00\x58\x0e\xbd\x39\xd5\x20\x95\xdc\x37\x78\x88\xfc\xc7\x76\x69\x7b\xf6\xe6\xfb\x9d\x3d\xeb\xfb\xee\x7e\xc2\xa7\xff\x0c\x68\xb3\xf5\x10\xc8\x12\x05\xcb\xe5\x1f\x81\x5b\x7c\xba\x08\x7a\xb0\xb8\x14\x15\x1f\x06\x5d\xb8\x94\x81\x94\xb4\x84\x8b\x91\x7a\x77\xcf\x2c\x97\x01\xf6\xc6\x16\x82\x96\xcb\x00\x2d\xc2\xe0\x7a\xb9\x0c\x2a\xec\xe1\xb1\x87\xd4\xd3\x13\xec\xc1\x15\x00\x74\x7f\x1e\xcc\x68\x45\xf7\x91\x88\xc9\x28\xf3\xfd\xcd\x88\xd2\x55\x60\x61\xbf\xaa\x20\xaa\xb9\x5a\x58\x48\xd7\x2b\x5f\xfa\xfe\xa8\xd4\x20\xbc\x0a\x1a\x08\xc6\x55\x55\xf8\x7e\x01\xf9\xca\xe6\x5a\x3d\xe4\x5d\x5f\x83\x11\x53\x55\x8d\xda\x74\x05\xd5\xfb\x4e\xf0\x22\xb7\x4c\x0f\x6a\x26\x13\xb2\x36\xca\x1a\xdf\xb7\x4f\x2d\x60\xe2\x79\xe2\xfb\xa3\x7d\x7b\xbc\xa8\x78\xd7\xa4\x48\xc5\x91\x37\xbb\xc2\x26\xd8\x52\x5b\xe2\xe0\xce\xa3\x6b\xb0\x85\x18\x49\xdb\x8f\xf6\x1c\x05\x76\x62\xdd\x98\x75\xa4\x8a\x2e\x1f\xb0\x5d\xd0\xe6\xd8\x22\x1d\x2b\xd0\x00\x40\x1d\x4d\xf1\xbc\x7f\x82\x7f\x00\x98\x6c\x72\x7b\xba\x91\x2b\x0d\x92\x9e\x02\x7b\x8b\x6e\x87\x7c\xb1\x4d\x63\xeb\xec\x01\x8c\x95\xac\xe5\x95\xda\x07\xa0\x6a\xd6\x4c\x78\xff\x3c\x03\xb0\xb3\x11\xdf\x20\x4c\x82\x6d\x0d\x9c\x16\x23\x8d\xee\x35\x70\xad\xce\x20\xb4\xf9\x6a\x94\xb9\x4a\x16\xa1\x92\xe8\x00\xd6\xfd\x96\x40\x88\x3c\x44\xdc\x31\x24\x8d\x38\x58\x78\xc8\x16\xb0\x21\xbe\xbe\x3e\x1b\x18\xad\x82\x7d\xc1\x5e\x9a\x11\x57\x15\x2c\x55\x27\xcd\xf1\x54\x96\x18\x9f\xca\xa6\x7f\x06\xef\x94\x6e\x06\x02\xca\x4c\x2b\x18\x20\x41\xcb\x88\x2b\xc9\xc0\xf7\x47\x32\xc8\xca\xef\x0a\xb1\x4f\x36\x10\xb5\xff\x8d\x14\xfb\x3d\x4b\x11\xc6\x27\x19\xac\x0e\x45\xc1\xb8\x34\x1d\x13\x01\xcb\xd9\xce\xb9\xc3\x1d\x25\x54\x34\xcd\xe9\x9b\xde\x4c\x85\xaf\x77\x3b\x96\x66\x89\x64\x83\x35\xcb\xa0\x68\x36\x06\x14\x68\x5f\xf5\xc6\x49\x3a\x1b\x07\xd9\x31\x7d\x7b\xf7\x0b\x4d\x88\x0c\x14\xc5\xa1\x09\xfc\xb4\x16\x36\x28\xa3\x08\xf5\xd7\x28\x69\x36\x6b\xac\xfd\x50\x75\x45\x55\x95\xd8\x7e\x63\x43\xbc\xcd\xe0\x0e\x70\x59\xc0\x4c\x5f\xd5\x5a\xb0\xf2\x90\x4b\x9a\x41\x10\x04\x70\x96\x66\x5c\xbe\xd4\xac\x3b\x02\xf9\x43\x8a\xbd\x33\x42\x84\x71\x1b\x54\x2f\xd8\x8b\x52\xda\xc5\xf2\xfd\xee\x7b\x67\xf1\x88\x6d\x09\xac\x62\xf4\x6c\x5e\x36\x2d\x50\x40\xad\x64\xff\x03\x95\x5d\x4c\x40\x72\xca\x02\x7d\x47\x03\x04\x35\xf6\xfd\xdc\xb5\x1d\x40\x1e\x08\x05\x6e\xd0\x79\x16\xe8\xa8\xf6\xcf\xe8\xcc\xd8\xf5\xe5\x8a\xc9\xd9\x66\xe5\x3c\xa7\x79\xc7\x87\x17\x94\x7a\x26\x82\x91\x5b\xad\xad\x75\xd4\x86\xca\x07\x0b\xd3\xbc\xb9\x61\x1a\x6b\xe5\x86\xf1\xdd\x3c\xd5\x44\x07\x88\x3f\xc0\x8e\x68\xb4\x35\x49\x94\x51\x54\x50\x08\xff\xd7\x20\x3b\x7b\xdd\x68\x12\x65\x31\x2d\x3a\x3c\xc2\xe2\x88\x32\x1d\x7d\xc1\x44\x1d\xc8\xc1\xdd\xcf\x44\x6a\xd1\x9f\xcc\x6d\xa0\x79\x43\xb2\x30\x51\x35\xf9\x7e\xe3\x08\x39\x17\x0d\x62\x2c\x4d\x34\x6e\x05\x05\x61\xde\xae\x83\xa8\x9b\x25\xcd\x8d\x43\xcb\xad\xfc\xdd\x52\xd2\x86\xd3\x83\x18\xe2\xc0\x54\x2b\x38\xe9\xad\xea\xb0\x61\xde\x31\x00\x5c\xdb\x5a\x07\x12\x46\x4e\x8c\x1f\x76\xcc\xda\xe4\xf5\x6d\xf4\xc0\x56\x0e\x5c\x19\x1c\xb6\xdf\x1a\x96\xa8\x0d\x90\xf1\x24\x87\x4a\x1b\x93\x81\xa1\x6f\x9d\xf3\x9e\x0f\x17\x3f\xfb\x12\xb1\xb8\x67\x23\x78\x71\x7c\xe6\xec\xf7\x77\x86\x74\x2c\x32\x69\x9f\x8d\x69\x22\x28\x93\x6b\xb2\xce\x86\x83\x3c\x44\x8d\xa9\x65\xbc\x60\xa1\x42\xfa\x66\x26\xc1\xd4\xc8\x60\x84\xf0\x94\x8b\x24\x0d\x4f\x5c\x7c\x76\xb8\x33\x16\x8e\xe6\x9e\x91\x93\xe1\xf4\x07\x66\x61\x44\xe9\x1b\xb8\xb7\x41\x87\x79\x50\xd9\x3b\x53\xb1\xd6\xf7\x8c\x90\xd1\xac\x26\x1d\x36\xc5\x83\x2f\x19\xf7\x6a\x72\x97\x1f\x8a\x0f\xb5\x41\x3b\x6d\xa8\xdc\x9d\x26\x54\xc2\xe5\x16\xc4\x41\x7a\x35\x81\xad\x78\xa9\x0d\xcf\x6a\xde\xc1\x38\x42\x55\xa9\x91\x80\xb6\xa1\x54\x25\x7d\xff\x6f\x86\x0c\x1a\x25\x4d\xa7\x03\x90\xc5\xf4\xa0\xd1\x3d\x0f\x7b\xe4\x1b\x2c\x44\xbc\x04\xe8\xf6\x1d\x5b\x8b\x82\x1d\xb8\x9e\x79\x17\x0d\x76\x29\xb9\xc5\xe4\xcc\xa0\x43\x85\xa0\x3a\x40\x06\x16\x87\x9d\x94\x40\x37\x0a\x7a\x94\xa6\x1c\xae\xeb\x5a\xdb\xfd\x37\x8c\xcb\x99\x85\xf3\xa0\x1d\xba\x6a\x70\xc8\x3c\x5d\x1a\x47\x82\xf3\xaa\x6c\x40\xce\x6d\x56\x76\xc2\x00\xe9\xac\xad\xbd\x91\x0b\x8c\x44\x82\xb7\x9f\x46\x97\x8b\x81\x5d\x66\xe3\xe6\x80\x65\xb0\xce\xa6\x13\xb2\xd2\x10\x9f\xef\x34\x29\x62\x29\x6d\xc2\x02\x36\x49\x55\xd5\x9a\x97\x9d\x7d\x34\xb4\x8d\xb9\xf3\xb6\x78\xc5\xc2\xf7\xb6\x49\x4d\xe9\xed\x0a\xfa\xfe\xc7\x9a\x5c\xc0\x9b\x7b\x73\xbc\x49\x69\x49\x44\xd8\xac\xba\x86\x96\x0e\xe7\xc0\xba\xef\x3a\x0b\xc4\x05\x65\x69\x93\xa5\xf3\x6e\x4e\x9d\xf4\x14\x10\xa9\xa5\x45\x90\x40\x1b\xa2\x09\xdf\xb3\x1d\x7b\x23\x93\xdd\x9e\xea\x19\xb5\xaf\x55\xf5\x32\x91\x2c\xe0\xe2\x88\x4c\x74\x97\x16\x39\x50\xb5\xe5\xcf\x90\x2c\x3d\x39\xd1\x9e\x42\xf3\x99\x9c\xcf\xb8\x9a\xaa\x21\x86\x49\xa7\x7f\x80\xef\xd1\x19\xde\x64\xbb\x03\x0c\x33\x1c\xcd\x48\x97\xa3\x38\x77\x50\x3d\x07\x8d\xf9\x25\x38\x78\xc5\x08\xb0\x52\xfa\x73\xd3\x0a\xdc\x0f\xd4\xe3\x5b\x6a\xd2\x63\x5b\xfe\x93\x86\xcf\xc7\xf5\xa1\xa6\xcf\xf8\x23\xdd\xf6\xd0\x2c\xfd\x27\x9d\xf8\xc0\x2c\xff\x5e\x6f\x86\x8a\x1a\x10\x19\xe8\x2d\x78\xe4\x40\x3c\x9b\x24\x97\x5f\xb1\x47\x45\x8c\xee\x80\x6e\x40\xd4\xa8\x95\xda\xee\x79\x43\xc1\xb6\x09\xdf\xb0\xf4\xad\x38\xc0\xfd\x1d\x2a\x45\x16\xb9\x29\x95\x32\x99\x64\xb9\x7a\x82\xc5\xf8\x6e\x9b\x94\x50\x68\xc7\x64\x62\xb2\xec\x93\x0d\xfb\xc9\x3e\xfc\x53\x3d\x80\xed\x9a\xf9\x7a\x9f\xb1\xa3\xfa\xf5\x56\xdb\xa4\xf0\x4c\x7b\xc5\x0b\xb5\xf3\x46\x53\xf2\x5e\x67\x7a\xcf\x1e\x6d\x8a\xb9\x08\xa9\x79\xd2\x1d\xca\x33\xc6\xe5\x4f\xed\x23\x34\x23\xd6\xeb\x92\xe9\x54\xfd\x08\xa9\x46\xc3\xfc\x3a\x75\x5e\x80\xe2\xa8\x8e\xad\x0a\xc6\xf8\x4f\xed\x23\x94\xd0\xfb\xdf\x19\xbf\x14\x46\x31\xac\x5f\x9a\xf4\xe3\x36\x1b\x94\xe2\x2c\x3f\x3a\xef\x05\x33\x85\xfc\xbe\x7f\x64\xf6\xc2\x27\x88\xfd\xbb\x30\xce\x96\x81\x9d\x88\x45\xfb\x18\xb2\xa0\x99\x8b\xa6\xbc\x6b\x40\xfe\xb6\x57\xd7\xcc\x97\x8b\x59\xf8\xd4\x97\x8b\x8f\xc3\x3f\xfb\x72\xf1\x34\x9c\x86\xa6\xa0\x86\x02\xab\x42\x55\x00\x82\x1b\xb0\x00\x65\xbc\xda\x81\x45\xe8\xc1\xb3\xb8\x67\x85\x47\xe0\x31\x67\xc9\x3d\xb3\xc9\x07\xe9\xd9\x49\x34\xd9\xcd\x9b\x2e\x60\x5e\x4c\x11\xfb\x09\x88\x7a\x97\xdc\xf4\x05\x1c\x16\xd3\x53\x87\x1f\x90\xc4\x2a\x46\x42\x69\xf8\xd1\xb3\x99\xb6\x31\x18\x21\xea\x7b\x07\xed\xc2\x6d\x03\x8d\xb0\xd5\x98\x96\x98\x7b\x60\x8b\xaa\x72\xce\xa9\x20\x36\x4d\x55\x99\x29\xa4\xa2\x11\xb5\x08\x6f\xc5\xc2\x61\x3d\x36\x31\x65\x20\x4a\xf2\x99\xf1\x62\xe7\xfe\x2e\x6b\xb6\x64\xba\xf2\xb2\xb5\x1d\x84\xf4\x9a\x08\x7e\xae\x09\xbb\x94\x9d\xcc\x54\x81\xf5\xfa\x92\x27\x0b\x98\xd5\x9e\xe3\x4c\x95\xd2\x4c\x8a\xa5\xe9\x85\x3b\x53\xe4\x88\x58\x4f\x8e\xd7\xba\xfc\xa2\x95\x64\x17\x45\x33\x43\x63\x2f\xf0\xc6\xce\xa7\xb0\xfd\x04\xd7\x30\x69\xf1\x87\x14\x8d\x90\x0a\x08\x6a\xf0\xc8\xc4\xdc\x17\x01\x41\x00\x19\xd6\x38\x73\xbd\x86\x48\xd5\xec\x42\xb0\x3f\xd0\x25\x48\xdf\x6f\x3d\xe0\xdb\x20\xa6\x10\x40\x44\x12\xd9\xd8\x12\x02\xbf\xc0\x41\x91\xff\xde\x44\x4a\xbb\x78\xc2\xd0\x31\x67\x26\x5c\x5b\x4f\x1b\xfb\x8f\xbf\x81\x91\xc7\x62\x94\x14\x2c\xa9\xee\x8a\x6a\x25\xf2\x8a\xed\xee\x58\x5a\x6d\x8b\x2a\xdb\x6d\x2a\xe0\x39\xab\x3c\xe3\xef\x2b\x85\x14\xab\x7d\x52\x24\x3b\x8c\x2e\xdb\x85\x5c\xeb\x18\x94\x78\x79\xf3\xec\x66\x93\x91\xe7\xaa\x01\x7d\x22\x5a\xdd\x82\xa1\x4d\x75\xab\x6a\xbb\xc9\xc8\x2f\x8c\xde\x98\xb3\xbc\x65\x79\x8d\x16\x61\xf4\x8e\xc6\x15\x5d\x96\xd7\xf6\x88\x2f\xc0\x37\x19\xf9\x95\xd1\x9b\x77\xcb\xf2\xfa\x76\x84\x16\xe1\x32\x7a\xf1\xf2\xf9\xdb\xe7\xcb\xa8\x9a\x4c\x70\xa5\x12\xe2\x65\xac\x9e\x9f\x2d\xcb\xeb\x27\xae\xab\xc8\xd7\xac\xe3\x9e\xa4\x03\x4e\x29\xa2\xe0\x61\xc5\x51\x9f\x47\x36\x93\x6e\x34\x2c\x4f\x16\x9e\x8e\xc0\x19\xd8\xa0\x58\xc8\x03\x73\x0d\x0f\x47\xd3\xb8\xaa\x58\xe8\x44\x43\xf9\x6b\xf7\xee\x1d\xd8\x44\x48\xe3\xc1\x4b\x17\xc7\x8d\xbd\x1b\x6f\x6c\xb8\x48\xa7\xa6\x6f\xfb\x0e\x2e\x37\xda\x40\xb2\x3d\x22\x6e\x6e\xb3\xf8\x04\x2f\x98\xcb\x8c\x36\x6e\x02\xa1\x65\x97\xcf\x5a\x75\x5b\xfa\x8e\x0d\xea\x30\xc8\x41\xc7\x7e\xe8\xdd\x38\xa9\x18\xea\xae\xa2\x1a\x09\xc7\x4a\x1d\x93\x84\x6a\x5b\x0c\x38\x18\xcf\xa9\x68\x95\xd6\x46\x1d\x69\x55\x3b\x24\x69\x4f\x84\xe6\xcd\x1e\xc9\x4d\x88\xc3\x29\x29\x68\x1e\x65\x71\xdf\xd0\xa3\x73\x5a\x46\x32\xa2\xf2\x44\x3c\xc6\xf5\x57\xdd\x4e\x95\xf4\x2b\xa7\x53\x07\xea\x86\xad\x2a\x31\x31\x5e\x04\x3a\x36\x42\x33\x15\xdf\xf4\xae\xdf\xb8\x70\x25\x61\x1b\x15\x9c\xfb\xfe\xbe\x47\xa9\xa4\x85\x59\xda\xdc\x25\x19\x9a\x02\xda\x54\xcd\xb3\x87\xd2\xf0\x0e\xea\x33\xf7\xb8\x99\x76\x23\x89\x3b\x76\x7b\xdf\x3b\x56\xa2\x92\xda\x23\xc8\x28\x56\x02\x8b\xb5\x1a\x6d\x6d\x53\xa6\x64\xdf\x3a\xb3\xa6\x74\x3f\x99\x91\x47\x08\x51\x4c\xee\xe9\x06\x3d\xc2\xb9\xc2\x7d\x55\xed\x9f\xcd\x06\x9c\xe8\x1e\x7d\x7f\xe4\x1e\xc9\xfb\xfe\x2f\x66\x98\x8f\x4e\xc4\xf3\x2e\x9e\x69\x82\x90\xb0\x80\xfd\x8a\x32\x3c\xbf\xf7\x7d\x04\x57\xd1\x3e\x3a\xea\xb4\x8c\x08\xb0\x16\x41\x18\x63\xf2\x3d\x43\xc2\x12\x0a\xe8\xd0\x1e\x28\xd9\x03\x43\x0a\x3b\x4e\xe3\x9e\xa5\xc5\x68\x46\xc0\x3b\x56\xd0\xcc\xdd\xa2\x70\xbe\xeb\x58\x90\xb8\xbe\x3a\x02\x13\x51\x55\x85\x51\x72\x1d\x28\x2a\x4d\x24\xb8\x47\x86\x32\xc7\x42\xe3\xaf\xac\xb9\x06\x62\xbe\xbe\xdd\xcf\xd7\xe3\x31\xce\x69\x46\xd6\x23\x4a\x53\xb8\xe9\xe4\xa8\x8d\x05\x50\x4e\xc0\x4b\x1b\x93\x83\x12\x7a\xb4\x05\x4b\x49\x1e\xd5\x87\xa6\x3a\x8c\x89\xd5\xd6\x47\xeb\x98\xe4\x64\x8d\xf5\x3d\x66\x70\x71\x0a\x2d\xa3\xb2\x0d\x8e\xdb\x1b\xa3\xee\x5d\x49\xbe\x65\x58\x2d\xe2\x7c\x7d\x7b\x30\x9d\x29\x55\x55\xd6\x54\x24\x77\x4d\x45\x46\xcd\xfe\xcb\xbb\x16\x4e\x1d\x1b\xe9\x15\xc9\xe1\xea\xa4\xa0\x2c\x56\xbe\xef\x69\x4b\x3d\x05\x83\x6e\x65\xbd\xa0\xfd\xc7\xe0\x67\x76\x9f\xe4\xff\x28\x72\x55\x95\x7d\xd6\x75\xe0\x70\xa7\x4a\xb6\x96\x36\x8d\xc3\xdb\xaf\x0c\x22\xf1\xab\x06\x1b\xe5\x9c\x83\x70\x5e\x9f\x5f\x17\x46\x32\x2a\x17\x6e\xb8\x6d\x1c\x32\x22\xe8\x74\x6e\xee\x92\x29\x8c\x31\x26\x98\x6d\x56\xd5\x6c\xe4\x86\xce\x06\xae\x27\x67\x09\x87\xdd\xff\xa8\x6f\xe7\x2a\x3a\xb7\xb0\x22\xde\x99\x8a\xa2\x6f\xb7\x8b\xc1\x40\x47\x15\x75\x16\xb1\x53\x47\xc7\xe0\xd6\xb9\x1d\x89\xb9\x5e\x76\xae\x15\xd4\xf0\xd5\xb0\x76\x8a\xfe\xc6\x88\x77\xfb\x64\xf6\xec\xf6\xe6\xc9\xd3\x67\x9e\x8e\x20\x7b\xc6\x28\x35\x7c\x8f\xd1\x2a\xf7\xec\x55\x00\xab\x7d\xc0\x04\x5e\x47\xee\xe9\xdb\xbd\xe8\xd9\x73\x63\xcf\xcf\xba\x09\xda\x99\x54\xc7\xe5\x47\x0c\x6b\xcd\x33\x58\x38\x95\xd8\x04\xb3\x45\x42\xbd\x3a\x5b\xc6\x86\xa7\xfd\x86\x21\x11\x15\x31\x49\xa2\x22\x86\xf6\x25\xc4\xa2\xc5\x5a\xc3\x2c\xaa\x0a\x8a\x11\x30\x55\x73\x2b\x14\xfd\x8a\xbe\xeb\x54\x04\x67\x57\x40\xa7\x4a\x3b\xf1\xa6\x47\xce\x72\xb9\xf7\xea\x30\x94\x90\xd1\xc1\xf7\xc1\x26\xd2\x59\xd1\x52\x7b\x90\xf0\x33\x3f\x30\xf7\x4e\xaf\x02\xcc\xaf\x3b\x7c\x3c\xc0\xa2\xeb\xb1\xc6\x1a\x70\xcc\xd6\xe8\x9f\x3a\x24\xc0\x1a\x49\xca\xa3\x2f\x5b\x2f\x5a\x48\xb2\xf4\xaf\xf5\xa8\xb6\x29\x59\x54\xc4\x8b\x1e\x6f\x06\x57\x70\x75\xcf\xf4\xc0\x72\xc6\x9e\xe9\xcd\xdd\x06\x0c\x13\x58\xf3\xe8\x2b\xc7\xab\x1a\xb9\xaf\x96\x4f\x3c\xe7\xe2\x53\xb8\xac\x64\x08\x4a\x5f\x37\x2c\xa2\xe3\x39\xf7\xc1\x8c\x78\xe0\xca\x5d\x93\xa7\xef\x38\xc8\xce\x1d\xb9\xd9\x42\xdf\x0c\xa1\x2d\x93\x8d\x39\x33\x5c\x46\x8c\xcf\x58\xd9\x99\x39\x00\xe9\x83\x6f\x2f\xed\x2f\xfd\x24\x45\x66\x41\x21\xe5\x18\x06\xb2\xd6\x79\x90\x9d\xb9\x52\xe1\x9a\x68\x13\xb5\x01\x0b\xee\xef\x59\x4f\x60\xea\x0c\xef\xbf\xef\xe2\xd7\xcd\x7c\x76\xcc\xe3\x74\x3f\xf7\x05\xfb\xaf\xba\x63\x59\xb8\x6e\x53\xb3\x81\xb4\xbf\xf4\x93\xac\xdc\xdf\xf6\x6b\x2e\x83\x8c\x97\xac\x90\x9f\x81\xce\x58\xa1\xa9\x4e\x2c\x58\xd5\x51\xad\x4e\xfe\x8f\xfb\x09\x2d\xbb\x38\xbb\x97\x70\xd6\xb0\x0e\x39\x5e\x93\x64\x2d\xbb\xca\xf4\xff\x67\xcd\x75\x6e\xf0\x50\x4d\x9f\x45\xac\x6c\x02\x88\xc3\xfd\x04\x86\x78\x69\x55\x59\x24\x63\x0c\xb7\x15\xf4\xaf\xfe\x40\x3d\xea\xc5\xe0\xaa\x01\x25\x82\x77\x8c\x58\xbb\x92\xe2\x00\xbd\x70\xae\xc1\x30\x9a\x17\xdf\x67\x26\x92\x08\xa5\x72\xc1\x42\xa3\xd8\x55\x0c\xc6\xa0\xe7\x10\xf0\x37\x1d\xcf\x5a\x45\xd1\xfe\xe0\xae\xd6\xa0\x62\xdc\x0e\xc1\x36\x44\x33\xf1\x8e\x0f\x5d\xd7\xb7\xfa\xec\x32\xfb\x26\x6e\x48\x63\xcd\x39\x18\xab\x82\xf9\xfe\xe8\x39\x6b\x83\xe9\x8e\x36\x2c\x6a\xcc\x99\xd9\x87\xcc\x99\x63\x7c\x62\xb4\x6f\xac\xac\x80\xba\x78\x84\x95\x6b\x84\x0c\x7d\xbe\xac\x07\xc3\xcd\xc9\xf4\xe5\x05\x93\x7a\xc1\x9c\x7e\x53\x55\x29\x9d\xba\xf6\x96\xd2\x40\x98\x45\x6c\x7a\x83\xc3\xd1\xd7\x65\x0c\x64\xb8\x85\x6e\x40\x51\xab\x7f\x8d\x1a\xd7\xa2\x0f\x40\x7a\x2b\xcc\x74\xc1\x7b\xee\x04\x76\xd5\x5b\xfb\x76\x3a\x30\x32\xb8\x8f\x83\x80\x19\x8d\xe9\x8b\xb1\xd8\x35\x57\x75\xd4\x0a\xf7\xd7\xad\xbe\x4d\x8f\xea\xad\x08\x3d\xfd\xe4\x59\xb4\xa5\x92\xcc\xa3\x47\xdc\xad\x15\x7a\x1a\x5f\xd8\xd4\xe7\xb0\x9b\x3d\xd8\xd4\x9e\x9d\x80\xe7\x79\x1e\x7a\xce\x64\x0c\xa8\xdd\x7a\x91\x9f\x59\xc7\xbd\x49\x5f\x05\x04\x71\x72\x44\x73\xcb\xd8\x64\x46\x12\x3a\x9d\x27\xb7\x54\xcc\x13\xc5\x57\xc2\x65\x86\xc2\xf1\x91\xd5\x1b\x42\x71\x5a\x47\x94\x45\x49\x8c\x23\x19\x23\x8e\x49\x69\x44\xaf\x82\x70\x1d\xf4\xbd\xb3\x37\x9d\x58\xce\x45\xa3\x5e\xf9\xb1\xef\x51\x69\xbd\x28\x17\xa3\xfd\x03\xd6\xae\x94\x63\xeb\x49\xf9\xa4\x6b\x06\x69\xa5\xd1\x0e\x7f\xd7\x08\x89\x19\x3b\x3a\x97\xce\xf0\x40\xec\x19\x67\x05\xe8\x89\x18\xd6\x1d\x7c\x21\x76\xfb\x83\x64\xe9\x1b\xf0\x9e\x93\xb8\x26\x9f\x75\xba\x23\x98\x31\xbe\xaa\x3c\x0c\x3d\x98\xbb\x96\xe6\x6d\xcc\x0d\x7d\x50\xb9\xc2\xa7\xdc\x78\x4a\xad\xca\xf2\x2d\x7b\x90\xd4\xdb\x9b\x7b\xcc\xc2\xe4\x0e\x82\x3b\xb2\x79\xce\xd6\x32\x9c\xcc\xd4\x7f\xfb\x87\x39\x5c\x25\x16\x7e\x3a\xdd\x3f\xcc\x77\x49\xb1\xc9\xf8\x44\x8a\x7d\xa8\xbe\xec\x93\x34\xcd\xf8\x26\x9c\xce\xef\x44\x91\xb2\x22\x9c\x7a\x10\xee\x70\xb8\x7a\x7b\x57\xdd\xdc\xf8\x68\x85\xe0\xe7\x36\xbf\x13\x0f\x93\x32\xfb\x4d\xd5\xa3\x6b\x99\xdc\x89\x87\xb9\xb8\x67\xc5\x3a\x17\xc7\xb0\x84\x00\x53\xa6\xe5\x30\x39\x48\x61\x1b\x73\x7b\xe0\xf6\xf3\x7f\xe6\xd0\xbf\xff\xf1\xc8\x5d\xd7\x54\x3d\xef\x92\xe6\x95\x09\x80\xad\x95\x3b\xdd\x79\x5e\xe1\x79\x46\xbd\xd9\xff\x78\xda\x30\x55\xec\xc9\x81\xce\x9e\x52\x4a\x39\x92\x81\xee\xcb\xd7\x6c\x2d\x71\x33\xdc\x22\xdb\x6c\x25\xf5\x3e\x9d\xfe\x8f\x47\x4a\xfa\xf1\xa7\x26\x2b\x24\x2b\xc0\x6d\x52\xa0\x97\x6d\x39\x3b\x3b\xd4\xb3\xb3\xef\x91\x44\xe7\x5e\x05\xfa\xc4\xe0\x47\x55\xa2\xaa\x9c\x0c\x77\x5d\x89\x26\xc7\x64\xa5\x43\x8d\x3a\xc1\x4f\x1c\x84\xaf\xaf\x03\x15\x07\x9e\x22\x08\x94\xf2\x79\x2e\x12\xb8\x9d\xa2\x6e\xfc\x55\xb5\xee\xe1\xdc\xa3\x00\x7c\x0d\xc8\xea\xc2\x87\xf9\xaa\x71\x2b\xb4\xe3\xb9\x4b\x56\xef\x37\xd0\xd6\x8b\x3c\xdb\x53\xcf\x04\x83\x57\x6b\xaa\x60\xa3\x6b\xb3\x3f\x5c\xc4\x23\x5b\xc0\x64\x05\x48\x3e\xb0\x1e\xdd\x7a\x60\x6e\x86\xca\xb6\xf1\x1d\xb6\xe4\x74\x27\x1e\xde\x00\x58\x7d\xcf\xf2\xec\x42\xcc\x69\x08\x96\x50\x93\x7d\xf6\xc0\xf2\xcf\xc4\x03\xb4\x35\x14\x36\x57\xe5\x2b\x4d\x3e\x7b\xed\xdf\x85\x6c\x99\xc2\xfc\xba\xc1\x6f\x1a\x38\xb9\x90\xf7\x50\x13\x0d\xde\xba\xaf\x97\x7a\x98\xd4\x35\xc6\x35\x72\x6e\x8e\xf8\x9c\x5d\x12\x32\x61\x5a\xac\x98\x05\x2e\xb6\x4f\x40\xd8\xf3\x7d\xe4\x81\xbe\x20\xa1\x80\x56\xac\xc5\x08\xe8\xa9\x90\xc4\x55\xc5\x15\x93\xd3\x39\x84\x38\x97\x4a\xc1\xdc\xdb\xf1\xe4\xc5\x98\x8c\xb6\x41\x77\xfa\x10\xf6\xfd\x1f\xad\xad\x19\xf6\xfd\xcf\xcc\xb3\xd4\xa1\x50\x4a\xbd\x03\x48\x46\xcb\x60\x97\x71\x00\x6e\x22\xd4\x4b\xf2\xa0\x5f\xda\x74\x27\xd5\x96\xa3\x09\x51\x23\x38\x9a\x9c\x3a\xad\x70\xcb\x64\xc4\x29\x25\xb0\x13\x27\x2a\x59\x24\x63\xcf\x0b\x9d\x1b\xc3\x7f\xee\xa8\x97\x4f\x9d\xb0\x58\xda\xfc\xa0\xbd\x25\xb0\xb9\x27\x84\x4a\x7c\x21\xce\xb0\x51\x92\xda\x8c\x75\x0d\x1b\xec\x37\x70\x14\xe1\x82\xb3\x0a\x54\xd7\x68\x31\x9a\xac\x22\x96\xc4\x38\x18\xe3\x1b\xf2\x93\xfa\x3c\x99\xdc\x90\x7f\x30\x7a\x6a\x90\xa5\xb3\xdb\xef\xb3\x32\xbb\xcb\xf2\x4c\x3e\x86\xde\x36\x4b\x53\xc6\x3d\x62\x51\xa8\xf1\x15\xae\xc9\x0f\x8c\x9e\x72\x26\x25\x2b\xde\xec\x93\x95\x42\x89\xde\xd4\x23\x6b\xc1\xe5\x8f\x70\x21\x64\xe8\xfd\x79\x3a\xf5\x6a\xf2\x05\xa3\x91\xf7\x23\xbb\x7b\x9f\x49\x8f\x78\xdf\x88\xdf\x3c\xe2\xed\x4a\x2f\x26\xff\x64\x17\x36\xb9\x01\xa9\x36\x0a\x1b\x33\x92\x09\x53\x02\xf1\x3f\x59\xeb\x8c\x61\x23\x4c\x4d\xe3\x6e\xf4\xb8\xb1\xd5\x6a\xcf\x30\xe1\xf4\x0b\x76\x1e\x4c\x47\xc7\x26\xfe\x82\x45\x3c\x1e\x4b\xdc\xad\xb6\x5d\xad\x2f\x99\x6b\x94\xba\x2a\xe1\xc0\xbc\x8c\x58\x2f\x72\x5b\xe7\x13\x85\xee\xc2\x5d\x14\xb2\xad\xe9\xab\xee\xfe\xa1\xd6\x3d\xbe\x8d\xdf\x59\x2c\x00\x6b\xee\x92\x07\x34\x25\x45\xf4\x34\x9e\x20\x5e\x55\x53\x8c\xc7\xa8\x00\x67\x7c\xf0\xbc\x0f\x9d\x3a\xff\x35\xe4\x8b\x43\x3d\x7d\x11\x27\x04\xf0\x98\x85\x53\x73\x13\xfe\x54\x5f\xcd\x45\x29\x2a\x16\x9e\x26\x67\x5e\x68\x71\x5c\x6b\x1b\xa4\xa3\x14\xce\x93\xdb\x3f\xcf\x93\x31\x7d\x8a\x3d\x4d\x79\xac\xa3\xf6\x61\xdc\x84\x47\xe0\x63\xc1\xa2\x04\xa2\x17\x66\x18\x93\x62\x81\x9a\xda\x6c\xe6\x49\x1b\x4b\xc1\x50\x4d\xaf\x5b\xc8\xd6\x3e\x3a\x2f\x60\xba\xa8\xf3\x8f\xbd\x1f\xf5\xe5\xa2\xba\x1c\x0e\xdd\x8e\x0c\xd6\xdd\xa6\x42\xb4\x36\x37\xfb\x07\x6a\x0e\xcb\x3f\x96\xcf\xae\x19\x04\x97\x79\x06\xb1\x07\x0e\x63\xea\x2c\x1f\x3c\xae\x58\x96\x23\x16\x79\x9a\xa6\x7a\x63\x79\x0e\xa6\xb2\x01\xd3\x78\x22\x26\x87\x49\x39\x09\x3e\xc1\x58\xa1\xe9\x66\x91\x9b\xb0\x5d\x06\x70\x00\xb9\x92\x8c\x1a\x84\x0c\xfa\x6d\xaf\x65\x63\x3a\x11\x2c\x1a\x82\xe4\x91\xd1\x4c\x65\x4d\x28\x5c\xda\x66\x91\x65\x86\x7b\xf7\xb3\x66\x8a\x07\x51\x1c\x8f\x67\x15\xb1\x09\x4d\x7c\x1f\x6d\x83\x33\xda\x86\x70\x55\x65\x6d\x9c\x0d\x85\xca\x09\xd2\x65\x29\xa5\x59\x55\x8d\x1c\xca\x9f\x61\x08\xfd\x92\x67\x17\x42\x6c\xe8\xee\xe9\x2b\x83\xff\xf0\x8c\x11\x1d\x0f\x13\x65\xb4\xd3\x92\xda\x33\x63\xbb\x35\xaa\x0a\x89\x21\x78\x27\x09\x38\x58\x8c\xd5\x9e\x72\x54\xb2\xab\xb2\xd4\x31\x81\x4e\x42\xe1\x34\xf9\x18\x9e\xce\x03\x17\x82\x9e\xd2\xb0\xd9\xb0\x0a\x9e\xc9\xdc\x08\xdd\x10\x95\x80\x2f\xbc\x99\x17\x72\xb0\x5e\x6b\x22\x65\x84\xa7\x84\x67\x3b\x30\x48\x79\x2d\x59\x01\x0f\x60\xee\xab\x8d\x26\xf3\xc3\xae\x7d\x5d\x67\x79\xfe\xad\xe9\x86\x7a\xcd\xd9\xc3\x17\x85\x38\xda\xe7\x37\xdb\x22\xe3\xef\xe1\xad\xc5\xb9\xa3\x29\x51\x93\xfc\xd7\xe6\x4d\xb4\x15\x68\x1e\x16\x1e\xf6\xdb\x44\x9b\x90\x1c\xb3\x54\x1c\xe1\xe9\xb7\xd7\x70\xdf\x96\x7a\x12\x62\x07\x86\x94\x16\xa9\x85\xa7\x9a\xc0\x22\x0f\x9c\xcc\xeb\x23\xf6\x8f\x7b\x3a\xe2\xff\xdd\x7b\x37\x40\xe2\x84\x2b\x21\x25\xc4\x33\x24\x07\xfa\x53\x43\xad\xc1\xe4\x59\xe3\xfe\x6c\x8d\x0e\x80\x5a\xbf\x64\x48\xc9\x94\x89\x86\x19\x58\x1c\x88\x36\xe2\xbc\x96\x8e\x9b\x78\x03\xc9\x89\xef\x7b\x1b\x26\xbd\x0c\x1e\x5d\xb3\xf2\xc4\x04\x71\xd2\x20\xb7\xc8\xc2\x3c\x92\xf1\xbc\xd5\x1b\x20\xd1\xf8\x0b\x6a\x80\xb4\xa8\x9a\x2b\x00\xd5\x77\x0e\x22\x4e\x4d\x10\x96\x0c\xf6\x1f\x87\xc5\xf5\x30\xd1\xaa\x14\x25\x59\x19\x24\x68\x3f\x19\x77\x41\x3e\x86\x5b\x03\xce\x83\xab\x94\x6d\x70\x15\x7c\xce\x8d\x56\x95\x67\x8e\xff\xc0\xe0\xa5\x0d\xf9\xd6\x72\xa3\x9e\x62\x95\xd4\x50\xa8\x97\xf1\x2d\x2b\x32\x80\x72\xdf\xf7\xca\xde\x2c\x50\xd0\x48\x27\x26\x20\xa0\x5a\x44\xf0\xb8\x5b\xe4\x2a\xa5\x35\xeb\x25\x1c\xc3\xcc\x50\xae\x43\xd5\x9f\x85\xd8\xec\x44\x9f\x31\xcb\x69\x69\x59\xbb\xa6\xee\x22\xa2\x0f\xaf\x22\xee\x2c\x99\xbb\x52\x53\xc2\x1b\xae\xaa\x09\x5a\xd2\x20\x40\x08\x67\x52\xec\x92\xdc\x04\x34\x91\x8a\x4b\xf8\x81\x41\xa6\x1f\x34\x62\xd2\x1b\xb2\xaa\xf8\x02\x89\x2e\xb6\x20\x10\x70\x99\x57\x55\x56\x7e\x9e\xf1\x4c\x32\x24\xf0\x42\x54\xd5\x34\xd4\x91\xde\x1b\x65\x45\xe4\xe9\x7b\xae\x3d\x62\x08\x6c\x7c\xa6\x54\x70\x86\x46\xfb\x78\xc3\x6e\x96\xe6\x3a\xe6\xdf\xcc\x14\x9d\x87\x1b\x02\x27\x36\x25\x1f\x82\x4d\xd7\xf7\x6c\x25\xcb\xe6\xee\x39\xb5\x95\x36\x4c\x7e\xa6\x56\x3c\xe3\x9b\x36\x0b\xc2\x9a\x33\x5d\x18\x7a\x51\xe0\xb0\x54\x13\xf4\x0f\xe7\xfe\xda\x56\xe5\x67\xf3\xd4\xf8\x2c\x14\xac\xbb\xae\x86\xd8\x24\x7f\x90\xc0\x08\x4c\x4a\x5a\xf8\xbe\x41\xbe\x05\x84\x60\x9b\xb7\x1b\x72\x1b\x74\x64\x0f\xb8\x54\x58\x34\xf2\xa8\xef\xa3\x72\x42\xff\x1b\xca\xe9\x2c\xa8\x50\xcb\x3d\x31\x1d\xb0\x78\x5f\xf7\x0d\x48\x2b\x29\xcf\xb7\xb4\x09\x5c\x84\xb2\x96\xcb\x02\xd3\x64\x4b\xd7\xc0\x3f\xd8\x09\x63\x44\x80\x97\xe3\xa4\xb4\xc7\x24\x76\xdd\x1d\x31\x9d\xfe\xcc\xd0\x36\x38\x17\xcb\xc8\x00\x29\x31\xcc\xbe\x33\x0a\x4d\x55\xda\xda\x5a\x98\x18\x5c\xf8\x9c\xad\xe5\x04\x56\xfb\xd4\x96\x09\xa7\xf5\xd0\xca\x7f\xb0\x92\x1a\x1b\x8a\xe8\x98\xc4\x69\x2d\x88\xe7\x11\xab\xf8\xf0\x3c\x62\xd4\x21\x86\x27\x3a\xd7\xae\x35\x1b\x81\x8d\xd5\x56\xd0\xa7\x4b\x2d\x90\xb9\x47\xb9\x70\x9e\x77\xaa\x15\x12\x3d\x77\xd7\xe6\xd6\xbd\xf0\xca\xc3\x61\xc4\xe3\x79\x71\xfb\x67\x38\xef\xcb\x22\xa6\xf8\xb2\x22\x56\xf5\x8b\xa8\x88\xab\x4a\x44\xc5\xe4\x29\xfc\x4e\x9d\xa0\x59\xb5\xcb\x63\x1a\x65\xac\xdb\x39\x85\xf3\xe8\x57\x10\xb3\xbd\x73\xdc\xd5\x47\x77\x97\x55\xd9\x3d\xa1\x58\x8d\x25\xd1\xdc\x76\x3f\x98\xaf\x1e\x75\xcb\xc1\x35\xb7\x8c\x26\xb7\x19\xa8\x14\x45\x24\xa3\x24\x8e\x5b\x58\x03\x76\x56\x91\x29\x3b\x20\x51\xf7\xa3\xe7\xf2\x85\x1b\xe6\x8a\xe3\xb0\x05\xd4\x1a\xec\xe4\xce\xc3\x5c\x76\xaf\x84\x94\xd2\x75\x38\x75\x2c\xdc\xa5\x63\x4e\x0d\xd7\x00\x3b\xf9\xea\x63\xf0\xf6\xc8\x18\xa7\x52\x12\x79\xd1\xec\x5a\x4a\xa2\xca\x0d\x78\xb6\x2a\x69\x45\xeb\xb7\x73\xb6\xb3\x06\xf2\xfb\x42\xec\x29\xb7\x36\x69\x65\xc6\x37\x8a\x8d\x3c\x9a\xe7\x36\xa0\x88\xb6\x8a\x83\x18\x37\x25\x95\xd6\xd8\x37\x29\xa4\x3d\x8e\x3a\x52\x6b\xb4\x6e\x6d\x81\x19\x4f\x69\xa1\x1f\x21\x84\x97\xe8\x51\x5f\xde\x52\xdf\x9a\xac\x0e\xc5\x80\xf9\x32\x8c\x72\x6f\xf0\xbb\xed\x6e\x03\x69\xcc\x20\x66\x1d\x14\xc7\x1e\x4d\x3a\x65\x9a\xee\xb7\xdf\x6b\x52\x1c\x06\xae\xc3\x20\xfc\xf7\x1a\x73\x27\x20\x48\x0f\x9a\x8b\x34\x57\x82\x8a\x92\x82\xff\x24\xcc\x59\xe4\xcc\x65\x6c\x4f\xa5\xfa\x05\xaf\x19\x99\x92\xd9\xf0\x37\x73\xbc\xaa\x6b\xb5\xa7\x5a\xe2\x48\x91\x9d\xd5\x49\x3b\xfb\xf8\x5a\x8e\xdb\xb7\x6e\x7d\xa5\x64\x7b\x73\xa2\xe1\x26\xb5\x86\x3e\xda\x5d\xcf\xd6\x6f\x2f\xe2\xf5\x7d\xae\x36\xe8\x82\x37\x41\x5c\x2f\x4d\x6a\xf3\x5d\x5f\xbd\x50\x93\x33\xe8\x75\x80\xd4\xfd\x46\xdc\xfa\xe8\xa9\x71\x85\xe9\xd1\x6f\xb3\x36\x4d\xf4\x07\xe0\x6f\x55\x9f\x9d\x03\x51\x6b\xc0\xac\x92\x23\xa6\x97\xcc\x06\xaa\x30\x99\x35\x49\x31\xdf\x16\xdd\xac\xa1\x55\x24\x20\x9d\x4e\x74\x3a\xf1\x20\xa0\xa3\x96\xac\x46\x10\x95\x53\xa1\xf6\xb2\xd7\xbd\x63\xb0\x7e\x80\x39\x6d\x6a\x3f\x4b\x41\x0c\x87\x17\x3b\xde\xeb\xa2\xab\xd1\xd0\xa5\x63\x08\xd3\xdd\x22\xcf\xc1\x31\x00\xd3\x7f\x0c\x1b\x94\xd4\x19\x08\x7c\x1b\xc3\x55\x86\xe0\xd4\xd3\x99\x7a\xc3\x1a\xbc\x15\x7b\x3a\x90\x0c\x24\xf5\xd4\x1f\x73\x6f\x20\x6a\x0b\x42\x42\xc7\x94\x67\xa8\x83\xd6\x15\x00\x70\xcc\x49\x09\x4c\xc9\xb0\x01\x4e\x4d\xca\xa3\xa2\x79\xe7\xdf\x82\x4f\x26\x9a\x55\x11\x25\x62\xd7\xf0\xf8\xdd\x6b\x7c\xf3\xd4\xf1\xa6\xf2\xa0\xac\x07\x17\xe9\x3f\xd0\x33\x80\x24\xcd\x02\xd1\x93\x0e\x76\xce\x25\x29\x24\xc9\xa4\x8e\x0c\xa3\xc3\xbd\x55\xe5\x56\x1c\xab\x6d\x96\x32\xfc\xe4\x86\x08\x49\x6f\xda\x48\x9f\x4f\x9c\xc8\x2f\x89\x54\x44\x5e\xfa\x3e\x02\x13\xdf\x22\xd0\x7a\x3b\xed\x03\xf5\xeb\x81\x95\xf2\xb9\x15\x3c\x3f\x2f\x74\xf4\xae\xc1\x74\x94\x48\x1c\x76\xee\xd6\x48\x4c\x4f\xc1\x88\xfd\x3e\xc9\xb1\x7e\x95\xe0\x3f\xe6\xd8\x1b\x96\xd2\x65\x33\x86\x2f\x62\xe1\xd6\x12\xb9\xc6\x84\x4b\xda\x7a\xf5\xb4\xd5\x1c\xe4\xf9\x6d\xd8\x27\xcd\x7a\x87\x4c\x5b\x7e\x4a\xad\xd9\x32\xdc\x00\x7d\x3a\x91\x38\x8b\x2c\x9d\x1f\x23\x4e\x81\x35\xc0\x31\xcd\xa2\x56\x39\xc4\x63\xea\xde\x50\x8c\xb2\xc0\x88\xc6\x34\x33\x3a\x5d\x45\x94\xdb\x7e\xe4\x72\xc8\xec\x0c\xed\x65\x20\x15\xe5\x63\x85\x96\x60\xa2\x18\x07\x2b\xc1\x57\x89\xec\x7c\xf2\xae\xbd\x18\x9b\x08\x89\x59\x3f\x42\x22\x04\x7e\xcf\x22\x11\x6b\xfc\xc7\x89\x24\xac\xd1\xc0\x15\x6d\x17\x56\x72\x50\xe7\xde\xd8\x6c\x1a\x41\x24\x03\x35\xa4\x15\x4f\xd4\x1b\xd9\x6b\x87\x80\x54\x71\x23\x5b\x2b\x54\x93\x4d\x47\x26\x4f\x80\x0d\x69\xa2\xbd\x10\x6f\xfd\xa0\x60\xcd\xc3\x73\xae\x83\xe2\x56\x95\x09\xb7\x03\x72\x5b\x37\xba\x33\x84\xa7\xc6\xc1\x81\x43\x6a\xea\xfb\x28\x69\x5e\xe8\x94\x94\x34\x71\x02\x2e\x13\xf7\xc5\x8d\x8b\xdb\x96\xa9\xaa\x12\x29\x26\xac\x4d\x19\x8f\xc9\x3e\xd0\xb7\x0a\xba\x10\x34\x94\xd6\x16\x9a\x4c\x48\x1b\xad\x1a\xfa\x68\xe6\xbe\xaa\x92\x6e\x04\x68\x5c\x9b\x10\x8f\xf6\xda\x8a\x35\xca\xe0\xce\x0a\x92\xc9\x8e\x72\xcc\x6a\xd8\xd5\x27\xb0\x49\xf3\xf4\xc6\x04\x61\x93\x64\x4a\x9a\xde\x2c\x3c\xb5\x41\xbd\xd0\xd3\x13\xa8\x1d\x34\xe1\x79\xa4\x55\x61\x8f\x8e\x1b\xdf\xa3\x82\xcd\x95\xe0\x32\xe3\x07\x36\xdf\xd0\xd1\xb4\x4e\xa3\x22\xa6\x8f\xbe\xff\x08\x9c\x6c\xcb\xd0\x15\xb8\xce\xd6\x08\x1d\xe8\xc0\x05\x09\xb8\xaa\xce\x52\xc1\x3b\xbb\x7f\xcf\x80\xef\x23\x1e\xd8\xc3\x4d\x1a\x6d\x9b\x67\xd2\x3e\xfe\xe4\x3c\xff\x33\x26\x66\xd9\x73\xe8\x93\x0d\x70\x09\xd6\xa0\x2d\xb4\xb4\xe2\x6a\x1b\x4d\x14\xad\x06\xa2\xe7\x42\xb9\xc5\x8a\xe6\x21\x5a\xeb\x90\x7d\x70\x8b\x4d\x3f\x40\x6f\x55\xe5\x64\xa8\x38\xd1\x85\x30\xc6\x04\x39\x2a\xc4\x55\x55\x99\xb7\x89\x3e\x90\x50\x69\x9a\xda\x8e\x68\x3e\x18\xcf\x77\xad\x64\x2b\x90\xed\x0e\x10\x92\x03\xae\xec\x72\xc0\x68\xdb\x84\xf2\xcc\x6b\x6c\xe6\x20\x87\x18\xb1\xcd\x17\x92\xd3\xa6\xde\x95\x62\x19\x57\xa0\xad\x69\x42\x92\x76\x7a\x04\x66\xbd\x76\x56\x41\x89\xda\xac\x42\x73\xaa\x32\x04\xce\x4e\xbe\xb6\x7c\xf4\xff\xf3\xf6\xae\x4d\x8e\xdb\x48\xba\xf0\xf7\xf7\x57\x48\x78\xfb\x30\x80\x16\x4a\xa5\x6a\x3b\x4e\xec\x52\x86\x19\x9e\x72\xf9\x32\xdb\x17\x8f\xbb\x66\x6c\x87\x9a\xdb\xc1\x92\x50\x12\xdd\x14\xa9\x21\xa1\xba\x4c\x51\xff\xfd\x04\x32\x01\x10\x20\x59\x6d\xef\x6e\x9c\xf3\xa1\x4a\x24\x48\x82\x20\xae\x99\x89\xcc\xe7\x59\xa4\x7e\x7b\xf9\x57\x2e\xfc\x2b\xbf\xf9\x57\x5e\xa5\x27\xc6\xf8\x51\x4c\x2f\xba\xae\xbe\x61\xfa\xeb\x1f\x13\x5b\x84\xbc\x9c\x3c\x46\x11\xdd\x8a\x47\xb3\x64\xb0\xf8\xd1\xc7\x91\xb7\xd3\x02\x7f\xb2\x3b\x40\xba\x76\xaa\x28\xa2\xf6\x01\x31\xdd\x32\xbe\x8d\x22\xaf\x75\x87\x95\xbb\x6d\x5b\xd3\x90\xdc\x87\x05\x71\x73\x8e\x57\x3e\xaf\xff\x73\x3d\x32\x18\x7e\x44\xa1\xe8\x36\xd1\x23\x24\x5e\xf0\x9a\x1f\x18\x87\xdb\x1f\xf5\xc7\xe8\xe1\x73\x34\x72\xe7\x56\xb7\x2f\x08\xfc\x36\xc5\xfc\x8a\x45\xe0\xbc\x7f\xab\x46\xe2\x18\xa0\x18\x25\x06\xdf\xc0\x2c\xfd\x3d\xf2\xcf\x99\xd1\x0f\x80\x91\xa1\x5a\x57\xa1\x8d\xb0\xd2\xad\x80\x37\x08\xad\x81\x32\x5e\x1a\x02\x27\x40\xd4\xad\xb8\x63\x4e\x29\xd3\xbe\x21\xac\x06\xcb\x17\x2a\xc9\x60\xfc\x62\x4f\x95\x9e\x3f\x21\x81\x56\xac\x7b\xb6\x4e\xbb\x02\x56\x0c\xcb\xd9\xb6\xd4\xbc\xb5\x4c\x39\x70\x75\xe7\x06\xbd\x45\x01\x96\x6f\xf7\xc5\x87\xe1\x72\x02\xeb\xd3\x01\xc0\x30\xd0\xbf\xc9\xc3\x2f\xf7\x31\xce\x47\x7a\xa9\x45\x8b\x01\xf1\xea\xc4\x42\xfa\x6e\x3d\x9b\x5a\x43\x17\xf6\x3d\xdc\x43\x2b\x55\xdb\x6a\x39\x81\x97\xfe\x6e\x49\x81\x0d\xa4\xe5\x85\x59\xe1\x74\x8f\x33\x60\x1b\xb8\x38\xa3\xe5\x79\x97\xd8\xb6\x0b\xbb\xac\x16\xb8\xda\x36\xfd\xd5\xd5\xa6\xeb\xf5\xb5\x3e\x96\xb4\xd3\x9e\x1b\x8f\x3f\x92\x4a\xbe\x2a\x78\xcd\x75\x73\xd4\x5f\x5d\x44\x51\x96\x94\x31\xcd\xda\x76\x78\xd3\x05\xd7\xed\xd9\x04\xf0\xed\x12\x80\x28\xf8\xf4\x02\x38\xc0\x1b\x07\xa2\x8e\xd0\x11\x92\x1f\xc0\x6e\xee\x47\x91\x28\xc6\xab\x83\xf2\xd2\xa6\x0b\xfe\x64\xfc\x85\xaf\x40\x12\x8d\x9f\x4e\x1c\x65\xd2\x78\xa0\xf4\x9e\x78\xc9\xb8\x8d\x9e\x35\x46\xda\x5c\x36\xb1\x72\x89\xef\x50\xaf\x8a\x4b\xee\x2a\x33\x76\xd5\x6d\xab\x2f\x2e\x5d\x4d\x72\xac\xa5\x78\x95\x72\x83\x89\xa9\xcf\x7d\xa2\x58\xb7\xe5\x64\x94\x7d\x2a\x79\xa1\xd5\x37\xa0\xc4\x37\x87\xf3\xe0\x0b\x40\x22\x32\x17\xf0\x03\x5c\xdd\xbb\xd6\x32\x58\x1d\xbc\xc6\xe0\xe1\x11\x96\x65\x70\x03\x4c\x7a\xcd\x1b\x83\x49\x25\xf7\x31\x0c\x30\x0a\x48\x4c\x17\xce\x11\xcf\x35\x7d\x89\x4d\x7f\xd1\x79\x5a\x25\xf4\xcf\x37\x2c\x57\x29\x63\x71\xe3\xd3\xa2\xda\x64\xa3\x5e\x32\xbe\x16\x05\x68\x14\x58\x8a\x5b\x45\xd7\xa3\x35\xc2\x42\xa1\x2f\x18\x6a\x4e\x00\x2c\xb8\xe4\xf6\x71\x27\x07\x6e\x01\xf0\xba\x3a\x30\x30\x5a\xf9\xd2\x57\x81\x5a\x95\x79\x1d\x5c\x60\x70\xab\xc0\x27\x00\x4b\x0b\xa3\x1a\x3a\x8a\xd2\x7d\x76\xd0\x45\x04\xe8\xa0\x2d\xb5\x45\x05\xbd\x3d\x8a\xfc\x53\x0b\x1b\x55\x30\x5e\x74\x54\xc5\xe6\x0e\x7b\x6e\x18\x8b\x4d\xaa\x3e\xb6\xc5\xb1\x34\x7f\x86\xc3\xd8\xa4\xea\x63\x37\x89\x98\x34\x3c\x73\xda\xc4\x5e\xd6\xd4\x8d\x8d\x23\xb7\x03\x29\x2b\xf3\x7d\x5c\x70\xe4\x82\xf0\x3f\x59\x2f\x0a\xc5\xe9\x7e\xee\xd4\x97\x2e\x66\xeb\xa0\xf8\x93\x95\xc4\xe3\x27\xf2\x92\xc4\xab\x11\xfc\x1d\x63\x24\xea\xfa\x3e\x62\x39\x98\x1a\x3b\x4a\x5a\x1a\xed\x95\x77\x7b\xf5\x7a\x14\x96\xa7\xf4\xc4\x4d\xf6\x3d\x1b\xe1\x96\x4a\x96\x18\xf6\x06\x54\x01\x62\x29\xa4\x43\x5c\x5b\xfa\x3e\x86\x0b\x08\xd7\xed\xc5\x31\x94\x42\x4f\xf2\xdc\xd7\x24\xca\x54\x84\xa7\x80\x5f\x15\x26\x39\x62\x14\x85\x9e\xdf\xa6\x83\xc5\xab\xb5\x4a\xbb\xf3\x3e\xcd\x4b\x12\x4e\xfc\x36\x0f\xc9\xe2\xf0\x02\x8c\x58\xeb\xb8\xd9\x1c\xa4\xdc\x0c\xf0\x37\x70\x9e\x90\x51\x34\x42\x18\xe4\x4f\x82\x92\xc5\x4f\xb6\x87\xc4\x65\xdb\x4e\xcb\x28\x52\x6d\xbb\x05\xcf\x5c\xd9\x4d\x53\xd2\x4e\x84\x78\x5d\x45\xd1\x74\x0b\xee\x3c\xca\x63\xdd\xbd\x7d\x98\x57\xb7\xb7\x49\xed\xa6\x34\xb1\x88\xed\x76\x9b\x0b\x81\xed\xae\x02\x80\xbf\x3d\xd1\x4b\x27\xea\xdf\xfa\x7b\x1a\x3f\x13\x2f\x79\xd5\x25\xa7\xf1\xf8\x2d\x6e\x86\xb6\x7b\x7f\x35\x76\xcf\x28\x02\xe0\xa4\xda\xa9\x52\xe6\x08\xe8\x58\x18\xaf\xe7\x55\xb1\x11\xb5\x1b\x2e\xbc\x3b\xf4\xd7\x51\x3d\x09\x54\xc5\x86\x45\x11\xfc\x76\xf6\x32\x9d\x83\x79\x4f\x8f\xf8\xc4\xa4\xb3\x93\x9e\x61\x03\x9b\xf6\x6d\xb6\x91\xd7\xd5\xf3\xd1\xd5\x88\x7d\x83\x6e\xce\x99\x64\x20\x36\xbb\xad\x6d\xbe\xb0\x98\xf0\x5a\xb6\xd2\x12\x01\x8c\x3b\x49\xdd\x4e\xb9\x3a\x71\x69\x82\xb8\xcd\xb5\xe7\x36\x0c\x45\x5f\x6f\x91\x48\x20\x04\x35\x8a\x3c\xe4\x3d\xf2\x20\x94\x1e\x0e\x06\xd7\x2d\xec\x51\xbc\x62\x4b\x9a\x3b\xdc\x6e\x40\xbc\xb9\xcd\xcb\xbc\xd9\x81\xee\x81\xb0\x5e\x74\xba\x60\xa7\x8e\x29\x17\xaf\x8b\x8c\x6b\xe5\x0c\x79\xb9\xa0\xd6\x3c\x76\xab\xcc\xd8\x3e\xb1\x6a\xcd\x75\x9e\xb1\xfe\xb2\x15\x8c\x80\x31\x10\x04\x7d\xbb\xf5\xd3\xc2\x33\xae\x68\xe9\x4a\x33\x4a\x00\x83\x41\xdb\x3e\x09\x8c\x32\xf8\x7e\x36\xf4\x60\x40\x5b\x33\x1e\xcb\x8d\x85\x98\x02\xb9\x85\xf3\xf2\x0f\xd8\x62\xa0\xe6\x61\xfa\x6d\x20\x18\xd7\x99\xa7\x71\xbd\x45\x88\x2d\xfd\x1f\x8a\x1e\x45\x35\xe0\x77\xb1\x8e\xf7\x11\xe2\x70\xb3\xe1\x8d\x95\xd3\xa3\xbb\x87\x70\xc5\x76\xe1\x5b\xf9\xd9\xd9\x92\x55\xfa\x11\x3d\xd3\x9a\x08\x17\x67\x48\x8d\x22\xb8\x04\x65\x9d\x02\x5d\x1f\x85\x04\xdd\xbb\xb0\x51\x4b\xc6\x95\x98\x5e\xf0\xca\xc2\x2b\xe6\xfc\x82\xb1\xe5\x54\x45\x51\xa9\xf5\xe8\x11\x46\x20\x6c\xf9\x11\x83\x9e\xad\x5d\xea\xe8\x76\x3e\x57\xa5\xbc\xf4\xab\x8a\xd7\xa2\x5c\xd9\x6a\x25\x29\x30\x89\x84\xb5\x9c\x86\xd5\x5c\x27\x75\x27\xd7\x80\x48\x6f\xbb\xe4\x74\xc1\x7b\xac\x4a\xba\x6d\x01\x66\x1c\xab\x15\x7f\xbd\x10\x59\xad\x6f\xa9\xae\x4e\x15\xd6\xa9\xc2\x3a\x35\x31\x3a\xba\x2a\x95\xa9\x4a\x0c\xa6\x80\x9d\x52\xaf\x2a\x75\x2e\xae\x1a\x15\x54\x23\x9a\xda\x16\x4b\xf5\x55\x06\x91\x28\xf5\x4a\xa5\x51\xa4\xff\x9b\xc2\x06\x27\xde\xdc\x64\x7b\xbb\xfd\xa8\x13\x0b\xf6\xd1\x8d\xfd\x84\xa3\x85\x84\xa3\xed\xa4\xbf\x9b\x6e\x09\xa6\x6e\xcb\x95\x4a\x97\xe6\xd7\x5f\x77\x82\xed\x2a\x34\x60\xb7\xed\x18\x13\x46\x39\xee\x3a\x89\xa3\xdb\xce\x62\x47\x45\x15\xd4\x24\x66\xec\x07\x29\x34\x45\xbe\x91\xdf\x56\xf7\x65\x7c\x54\xc6\xaa\xc3\x38\x24\xfe\xfd\x00\x49\x50\x7e\x93\x74\x8d\x1c\x1d\x3a\xd9\x7c\x26\xe3\x7a\xde\xfd\xb1\xec\x5c\x8a\x30\x8f\x13\xa4\xbf\x3b\x2a\xef\x02\xe4\x84\x17\x4c\x46\xdd\x35\x93\xdd\xe9\x8f\x63\x19\x86\x93\xba\xfd\x4a\x65\x67\x68\xf8\x3c\xec\x8d\x62\x95\x76\x06\xdd\xfe\x9c\x0b\x81\x49\xb0\xfb\x8d\x37\x63\x5f\xf5\x0d\xb7\x4b\xf5\x55\xe9\xba\xde\x6c\xc6\xa8\x14\xe0\xd6\x4b\x8d\x7f\x2f\x0e\xdc\xd2\xf5\xac\xb3\x33\x7e\xc1\x96\xa5\x33\xcb\x19\x23\x78\x75\xa0\x60\x11\x36\xd6\x61\x4f\x28\x14\xe1\x2e\x07\x96\xc3\xca\x24\xd6\x86\x9e\xd5\x80\x84\x14\xd8\xa9\xc5\xc5\x17\xde\xe5\x80\xfd\x5e\xe9\xf5\x18\xa6\xc5\x4c\x51\x66\x1f\x04\x11\x3a\xb8\x0d\x5d\xdc\xb9\xb7\xdc\x8b\xa7\xa6\xa8\xee\xe3\xff\xbd\x58\xf0\xdb\xac\x51\xf1\xab\xc5\xa2\x33\xf8\x7f\xb9\x58\x98\x25\x77\x23\x8b\xec\xb1\x47\x95\xee\xe8\xfd\x74\x76\x89\x2f\x65\x68\xad\x49\xc5\x0a\xf9\x89\x60\x3e\xf7\xa6\xf8\xb2\x6b\x6f\x6f\x05\x0d\x0c\xec\x25\xc8\xad\x83\xf2\x4b\xf4\x22\xb2\x77\xe5\x06\x6f\xaf\xbf\xb3\xf9\x1c\xa6\xff\x18\xdc\x3f\x62\x99\x90\x3f\xa0\x0b\xc0\x2d\x3e\xc2\xd8\xd2\x00\x4d\x74\x60\x75\x16\xb9\xff\x5d\x29\x08\xa2\x4c\x02\x1a\x20\xdf\x69\xc9\x1e\xd1\xc2\xe5\x46\x28\x03\x9a\x22\x37\x9c\x3e\x5f\x40\x86\xcf\x0a\xa2\x88\x45\xa0\x31\x84\x03\x7c\x37\x87\x83\x7f\xd8\xeb\xc2\xbd\xc9\xc2\xf3\x6f\x14\xdf\x29\x61\x40\xab\x33\xa5\xea\x1f\x20\x62\x76\x19\x48\x4c\x3a\xfd\xb3\x6e\x00\xf7\xf0\xe8\xb3\xfb\xec\xbc\xc3\xd3\xf8\x2f\xf0\xd8\x75\x0f\x3d\x47\x25\x39\x28\x57\x68\xd4\xe9\x6c\xbf\x7a\x0d\xff\x62\x0a\xae\x67\xff\x86\x3f\xaf\xf4\x0f\x1b\x40\xa5\x8b\x80\xeb\xc5\x01\x80\x24\xf7\xa0\xe4\x5a\xdf\x02\x6a\x50\xef\x83\x88\xef\xb6\xa5\x5a\xa2\x83\x3a\xc4\x0d\xeb\x5e\x18\x1d\xec\xb5\x7b\xe0\xe0\x7a\x8e\xb6\xee\x61\xc9\x46\xc5\x0e\x7a\xdf\xa7\x57\x86\x19\x5d\x94\x09\xa4\x05\x75\x02\xd4\xcc\x79\xe7\xd8\x96\xfb\xee\x7d\xb5\xc8\x9d\x63\x9b\x62\x2c\xa9\x63\x2a\x43\x5e\x09\xc5\xcb\x19\x21\x5a\x93\x83\x4c\xb6\x2e\x13\x83\xbb\x02\x59\x58\xae\x4d\x9d\x81\x31\x86\xd7\xc2\x40\xdb\x67\xb6\x10\x2c\x31\xac\xc8\x20\xf2\xda\xcf\x8f\x11\x53\xfd\xa9\xcf\xb0\x8d\x9e\xb6\x7e\xc7\x8c\x22\xd3\x5d\x91\xde\x12\x90\x66\x6c\xd7\x36\xeb\x9f\xe9\xb4\x4b\x7f\x5b\x6d\xc0\xb2\x61\x28\x41\xcd\xbd\x42\x0b\x45\xe0\x74\x3a\xda\xf9\xfa\x5b\x6b\x4a\x4b\xc8\x4e\x41\xd5\x22\xdf\x80\xa7\xd8\x38\xcd\x8b\x1c\x31\x81\x87\x28\x31\x25\x74\xcf\xcd\x60\x87\xd6\xa7\xea\x05\x29\x5b\x25\xbd\x96\x2c\xcd\x5e\xa3\x97\x17\xaa\xd8\x0e\xaa\x6d\xd8\x73\x90\x74\xd0\x94\xf9\xfc\xc3\xfd\xec\x7c\xcb\x46\x85\x87\x9d\x32\x3e\x86\xae\xd9\x96\x90\x14\x6a\xaf\x01\x87\x5e\xaf\xeb\x3a\xd7\x7c\x2d\x7a\xea\xfc\xb2\x94\xc3\x7f\xd8\xf9\x31\xbe\x9e\x26\x97\x24\x83\x9e\x62\xae\x57\x8c\xe7\x36\x98\x6f\x6b\x36\x74\x11\x12\x09\x67\xb6\xd6\xa2\xba\xb4\x88\x91\x06\xcc\x59\x8f\xe6\xc6\xac\xd5\x57\x74\x52\x38\x1d\x1d\x86\x98\xb3\xfd\xe9\x08\x37\xda\x3f\x3f\x1d\xf5\xa0\x6b\x3f\x3f\x1d\x79\x01\x26\x2b\xcc\xfe\xbb\xfc\x61\x25\xd3\xb6\x95\x69\x7f\x5a\x1a\x94\xef\xbf\x37\x2d\x4d\x9e\x99\x65\xf4\x74\x6d\x0b\x00\x4b\x26\x00\x2f\x78\x8e\x32\x69\x30\x85\xfc\xf9\x29\x02\x9d\xfc\xfe\xe4\x74\xa0\x6f\x06\x8a\xd0\x83\x1d\xee\xd9\x0d\xba\x4e\x8f\xbb\x8c\xf4\xa6\x0d\xa2\xb2\x1b\xf0\xde\xf5\x22\xb4\x13\x70\xfd\xfb\xb1\xd4\x32\xe8\xc5\x82\xc5\x5b\x65\x31\x82\x2c\xa2\x10\x6b\xdb\xc7\x61\x22\x00\x99\xd5\xf2\x36\x59\xc4\x67\x17\x7a\xc4\x9b\xda\x89\x9f\xc8\x6d\x55\x93\x98\xec\xd4\xbe\xf8\xae\xaa\x09\x27\xeb\x22\x6b\x1a\x12\xe3\xaf\x7e\x98\xe8\xa6\x0b\x56\x5d\x98\xa6\x3d\xc7\x0b\xbb\x18\x3f\xf3\x59\xd2\x0f\x0f\xee\xf6\xd5\x55\x18\x25\xef\x87\xc8\xdb\x1c\xa1\xb6\x38\x8a\x56\x7d\x97\x8e\x91\xbc\x15\xc0\x75\x87\x0f\xff\xd9\xb7\xf4\x14\x0f\xd3\x52\x84\x93\x5a\x66\x9b\x77\x65\xf1\x48\x38\xd9\x67\x0f\xaf\x61\x88\xe8\x6a\x92\x45\x61\xa2\x99\xcc\xd9\x4f\xc6\x7f\x80\x93\xba\xba\x7f\x7f\xc8\x4a\x9d\x5e\x15\xe6\xe8\xd8\xc8\x37\xd9\x81\x70\x72\x5b\x67\x7b\xf9\x17\xe3\x6e\x6a\xc3\x0c\xae\x36\x08\x7a\xec\x2b\x37\x7a\x81\x77\x9d\x18\x20\x26\x82\xb5\x12\xb4\x35\xdf\x3d\xef\x4e\x75\x23\x94\xca\x1e\xe7\x3f\x86\xe1\x4e\x88\xe7\x3e\xb1\x57\x01\x80\x8c\xbf\x98\x1b\x17\x35\x9f\x86\x09\x7a\x05\x6b\x5b\x42\xba\x1c\x1e\xfc\x1c\xc2\xcd\x2e\xc9\x12\x19\x0f\x23\xec\x93\xb0\x5c\xf1\x2a\x0d\xd9\x0f\xb3\xcd\xe6\x52\xbf\x69\xcc\xd7\x2d\x80\xf6\x07\x1b\xff\x96\xca\x10\xaa\x38\x9c\x92\xb4\xca\x63\x48\x09\x6d\xbe\x54\x06\xe0\xf8\x7b\xa3\x95\x33\x83\x12\x45\x95\x80\x6f\x72\xb8\xe1\x76\x41\x83\x49\xed\x68\xe8\xbd\x72\xb1\x57\xb4\x84\x2d\x27\x2d\x78\x78\xdb\xe7\x64\x42\x66\x77\x5a\x7e\x9e\xe9\xaa\x7e\xca\x3c\x46\x2e\xb5\xca\xf4\xe3\x75\xe7\x90\x3f\x21\xb3\x0a\xee\x83\x00\xf9\x7a\x26\xf0\x6c\x99\xeb\xb9\xa4\x11\x77\x40\xd8\x69\xfc\xda\x06\x2d\xc1\x1b\x07\x80\x84\xb0\x0d\x26\xe6\xf6\xff\x46\xe5\x79\x59\xff\x41\xfd\x4d\x07\x50\x03\x81\x6e\xa9\xe7\x35\x5b\x7e\x42\xfe\x1f\xd5\x38\x9e\x8e\xd5\xfb\xd7\x67\x17\xac\x16\xb5\x83\x4e\x72\x57\xf8\xff\xa0\x1d\x50\xf9\xee\xb7\x83\xb7\x95\x60\x46\x02\xaf\x3d\x37\x66\xad\xcd\xf5\xc7\xcf\xf2\x39\xc6\x4e\x15\x45\x75\x82\x8c\xdb\x5e\xbf\x36\x56\x8a\xa0\xad\x58\x0c\xdb\x0c\x23\xad\x5b\x76\xad\xeb\x15\x38\x68\xdd\xd2\xb5\x2e\x80\x2e\xb3\xd3\x33\x7c\xa0\xd8\xc1\x70\x4f\x3c\xbf\xa5\x35\x7b\xca\xc5\x82\x57\xc2\xe4\xcf\x33\x6c\x60\xd3\x2c\x4a\x64\xab\x5c\x37\x4b\x35\xdf\x65\x0d\xbe\x55\xb1\xa4\x0a\x0a\xae\x58\x5c\x75\x9f\xa6\xcc\x26\x75\x07\x13\x1e\x45\xae\x56\x0c\xd2\x1d\x55\xc2\xf5\xc5\x28\xfa\x6b\xc7\xe4\x4f\x3e\x7e\x74\x0b\xd9\xc7\x8f\xc4\xe1\x47\x37\xc1\x6c\x37\x48\x72\xcd\xab\x8c\xd5\x57\x26\x84\xc4\xbe\xdd\x38\xcc\x17\x26\x46\x86\xc8\x26\xe6\xb3\xc6\x47\xa1\x58\x2c\x95\xd0\x1d\x4d\xea\x8e\xb6\x0c\x7a\x7b\x6d\x7a\x7b\xbf\x8f\x53\xd3\xc9\x61\x0c\x60\x47\x77\xbd\x59\x61\x2f\x36\x3c\x6e\x4b\xc7\xdc\x66\x04\xca\x1b\x25\xce\x3f\xd4\xe7\xdb\x50\x3a\xbc\xcb\x8a\xe7\xe6\x08\x8b\xb3\xb2\xd4\x3a\xc8\x73\xa3\xb9\x16\xba\x5f\x8d\xd9\x3c\x8d\x14\x97\x2f\x07\x28\x40\x51\x64\x5d\xc4\x72\x51\x27\x61\x47\xb3\x5d\xf1\x2e\x2b\x28\x63\xb1\x64\x49\x2e\x08\x89\xbb\x80\x28\xd3\xf3\xf3\x24\x9f\xe9\x0b\xe1\x50\xc9\xd1\xaf\x02\x37\x2e\xf3\x31\x40\x28\x63\xf4\xd3\x4d\x28\x67\x84\x9c\x18\xe3\x20\x22\xde\x65\x85\xe7\x38\x6d\x48\x5d\xfa\xc9\xe3\x50\x8d\xe0\x88\x61\x64\x46\xe5\x23\x0c\x77\x5d\x2f\xe7\x04\xd4\x2c\x08\xb7\x82\xac\x50\xeb\xca\xed\x6c\x99\xbb\xe0\x6d\xbf\x2c\xf9\x48\x41\xf2\xcf\x95\x62\x3b\x2c\x85\xee\x51\xd0\x57\xbb\x32\xb0\xa4\x1c\xac\xc7\x5a\x53\xc3\x42\xb1\xc4\xe1\xb0\xd0\x1b\xa0\xf8\x36\xca\x6c\xa9\x2b\xcd\x42\xf5\x7a\xfd\xc7\xc5\x3e\xc2\x26\xdc\x9f\x93\x67\x4d\x49\x7c\x90\xe7\x29\x38\x29\xdf\x29\x6a\x80\xba\x24\x44\x90\xa1\x60\xf6\x4c\xae\xa6\x9f\x5a\x92\xdb\x06\xd4\x85\x50\xe6\xcb\x84\x31\x3f\x9d\x19\x07\x2c\x83\x82\xda\x88\x0c\xcc\x05\x31\xb0\xa8\x64\x49\x35\xbb\x88\x9d\xcb\x25\x46\x5c\x54\x5f\x2d\x92\x63\x9c\x25\x15\x38\x8d\x1e\x31\x84\xe4\x96\x52\x54\x6a\x1d\x45\x89\x96\x81\x6b\xe0\x57\x8d\xa2\x69\xe9\x28\x4f\xa2\x88\x4e\x4b\x5f\xc4\xb4\x17\xda\x76\xfa\x96\xfa\x57\x38\xb1\x7c\xbd\x84\x59\x88\xb7\x7b\x5a\x9a\x31\xc0\x33\xb7\x70\x2e\x8d\x05\x53\xb9\x75\xa6\x19\x04\x62\xf9\xbe\x49\x41\xc5\xe8\x31\xf1\x49\xda\xa8\x12\xdf\xc1\xb4\x23\x4e\xa7\xe0\x61\x9a\x79\x9f\x26\x3a\x08\x9f\xae\x0f\x9a\x5c\x91\x79\x9b\xf1\x0a\xe6\x1d\xd8\x7f\x9a\x2e\xba\x26\x05\x54\xe8\xa0\x31\xc4\xd9\x05\xe3\xd5\xe9\x14\x88\xd7\xc6\xf6\xd6\x19\xfb\x7a\x62\x6f\x30\x02\xd3\xa1\xb1\x00\x2a\x6c\x10\x34\xe3\x44\x59\x8b\x93\xea\x7d\x07\x95\xb6\x6a\x61\xc6\x3c\x9d\x3a\xf3\x22\x68\x33\xe1\x1b\x01\x49\xe1\xd9\x89\x64\x00\xb8\x6b\x3a\x76\x42\xaa\x92\xc4\xd6\x7a\xc8\x40\x6b\x32\x34\x20\x82\x54\xa5\x65\x04\xc9\x2d\x1c\xc1\xbd\x51\xe2\xcd\x05\xf8\x69\x2d\xab\x07\xf0\x80\xbc\x38\xe7\xd7\x61\x41\xc6\xa0\xf5\x97\x6e\x64\x1a\xcc\x3f\x3e\x64\x02\xd1\xc3\xc6\x67\xe1\x34\x9e\xc1\xc8\x11\x77\x27\x56\x79\xdb\xd6\x29\xdf\x8b\x5b\x33\x31\x73\x83\xe7\x9b\x20\xd9\x55\xac\xf8\x83\x77\xcd\xe1\x57\xc3\x0d\x1d\x87\x53\x47\xf1\x16\xaf\x80\xe3\xaa\x11\x3b\x71\x14\xb9\xd0\xd9\x73\xad\xc7\xe7\xbd\xd0\x5f\xff\x7c\x7a\x6f\x14\xd7\xfd\x6c\xc0\xc1\xa8\xbb\xda\xbe\x93\xe1\xe6\x20\xbd\xe9\x34\x41\x1f\xc4\xde\x7b\x31\x9b\xa3\x6f\x02\xe3\x0f\x86\x66\x8e\xf1\xb5\xf0\x1e\x8d\x51\xe0\xd6\x6d\x35\xdb\x73\x25\x94\x4f\x1f\xa3\x02\xfa\x98\x3d\x1f\x12\x95\x46\x11\xf0\x36\xe5\xcd\x35\x16\x4d\x54\xc9\xab\xf8\x0b\xee\xd5\x82\x78\xe8\x38\x0b\xb9\x4f\x71\x25\xbc\x9b\x92\x51\xae\xba\x87\x3f\xe4\xaa\x43\xcb\x91\x63\xa8\xc2\x19\x9f\x2b\x43\xc1\x01\x98\xbf\x86\xca\x23\x67\xbc\x14\x76\x12\x5f\xa9\x34\xf6\x27\x83\x92\x83\x0d\x64\x33\xe0\x36\xdb\x23\xc2\x5a\xd5\xb6\xd3\x8d\xad\x7d\x43\x42\xe6\xce\xcd\x2e\x59\x0e\xe4\xf7\x60\xab\xac\xa2\x68\xba\x99\x5b\x6a\x9d\x28\x9a\x3e\x82\x4f\xb4\x9e\x52\x0b\xb1\x09\x08\xfc\xda\x76\xcf\x6d\x3b\x17\xb3\xbd\x5e\x1b\x1b\xe1\x03\x88\xb1\x65\xb3\xec\xa5\xdc\xe1\x14\xd8\x30\x7e\x14\xcd\xf2\x28\xb4\x10\x11\xc2\xbf\xb4\x2d\x20\xad\xe2\x7d\x47\x1f\xc2\xaa\x6d\x8f\x26\xab\x5f\xf2\x72\x53\xdd\xb7\xad\x64\xa7\x4e\x4d\xd0\x02\x3e\xea\x09\x9f\x63\x44\xdb\x89\x86\xe3\x40\x10\xd9\xd7\x17\x49\x11\x6f\x1c\x0b\xa1\xfe\x1e\x7a\xb0\x64\x72\xcf\x31\xc9\x59\xd6\xc5\xc6\xd2\xdb\x81\xc3\xc1\xc1\xd4\x64\xc3\x4b\x60\xb6\x5c\x47\x51\xb3\x5a\xa7\xdd\x95\x28\xfa\x8d\x36\x48\x42\x66\x1a\x3c\x78\x04\x2d\xa5\x8e\x34\x67\xc8\x54\xd6\x19\x8e\xb0\xf0\x7b\xdd\xb0\x6a\x84\x46\x84\xb2\xb6\xdd\x38\x07\x15\xe3\x40\xd0\x25\x98\x97\xde\xcd\x0f\xb8\xfb\xc6\xda\x76\xfa\x1b\x00\x28\xac\xa3\x68\x4b\xf3\xd5\x1e\xea\xcf\xc8\x62\xf4\x28\x72\xfc\x0c\xaa\x7f\xa1\x13\x76\x9c\x96\x6e\x48\x8b\x3d\x7f\xae\xc2\xa3\x68\x37\xe4\xe1\xdc\xf3\x6b\xc5\xb8\x7e\x17\x65\x9f\x7d\x72\x8c\xc9\x07\x1f\x1e\x96\xc1\x0c\xa0\xa3\x2d\xeb\x91\x05\xac\x6c\x8d\xa1\x11\x79\xc6\x89\xc3\x4d\xbc\xde\xac\xc1\x4b\x8e\x76\xfd\x1e\xeb\xcb\xe2\xc4\x96\xbd\xf7\xd3\x1a\x21\xfa\x14\x1b\x80\xa8\x0e\x26\x70\xdf\x86\xfb\xcc\x6e\x50\x98\xb7\x2e\xa8\xb2\x50\x96\x26\xf1\x07\x43\xd5\xfa\x9c\x8f\x9b\x16\xfc\xbd\xc8\xf3\xc9\x58\x9e\x25\x80\xb7\xfa\x8b\x1b\x46\x5e\xae\x77\xf4\x09\xf9\xb4\x1c\xf7\x15\x52\x5f\xf9\x44\x55\x63\x2f\x0e\x77\x6d\xcd\x74\x64\xea\x8d\x2a\xee\xe8\x85\x42\xaa\x47\x5c\xf6\x42\x5e\x46\x94\x14\x8e\x87\x7e\x4c\xa6\xc1\x8a\xec\xcd\x18\x28\xa4\x77\x0e\xec\x35\x57\x6c\xa9\x17\xaa\x61\xd7\x93\xf8\xd5\xdc\xbf\x97\xd3\x1c\xf0\x43\x2e\x00\xa3\x16\x89\x34\xff\xfb\x2f\x3e\xbb\x58\xe6\x49\x90\x7d\xce\x62\x5a\x8f\xf6\xe5\xae\x34\xc6\x3b\x5e\x67\x00\x11\xe6\x20\x56\x5c\x2a\x21\xe7\x45\xb5\x46\xdf\xdd\x2b\x7f\x0b\x9e\x7f\xd2\xfa\x60\x72\xbe\xbc\x9f\x83\x21\xf9\xd7\x37\xaf\x87\x80\x80\x60\xc8\x51\x6d\x3b\x70\x37\x72\x2c\x70\xba\xd3\x02\xb6\x65\x29\xa0\xe7\xcb\xf9\xb7\xef\xde\xfc\xa4\x33\xac\x19\x66\xfc\x5d\x5d\xed\xdf\xc3\xe3\x20\x4a\xc8\x07\x75\xfe\xb0\x2f\x08\xeb\x80\x2b\x2d\x8f\xf6\xa9\x83\x18\x9c\x82\x74\x69\xf6\x6e\x9b\xbf\x3c\x5e\x67\x5b\xad\xf2\x50\x02\x59\xd6\xb2\xae\xab\xda\x0b\xd3\xb9\x9f\x43\x0a\x25\x3f\x96\x77\x59\x91\x6f\x26\xbf\xbe\x79\x1d\x4f\xc8\x0c\xb8\x45\xa0\x26\xde\xeb\xaf\x5d\x7d\x48\x5f\x9c\xf3\x6f\x41\x11\x4e\x3e\x94\xe7\x5b\xfe\xd6\xc8\x5d\xcd\xf1\x66\x9f\x2b\xb3\xad\xd2\xe6\xfb\x6c\x2b\xdb\x5a\x36\x52\xb5\xb7\x79\x21\x61\x9f\xe5\x9b\xcf\x6e\xc8\x7c\x92\x8f\x5b\x59\xb2\xf3\xbc\x33\xc2\xfe\xae\x7a\x1e\x6c\xa3\xe1\xdd\x66\xbc\x78\x31\xfe\xba\xbd\x9f\xca\xb6\x7d\x6f\x6d\xf7\x2c\xd1\x0d\x9d\xb3\x58\xe7\x38\x23\x2b\x32\x1b\x52\x80\xb8\xbd\x87\x3c\x51\x31\xd1\x72\x42\x4a\x78\x6e\x51\xef\x2d\x25\x79\xd9\xb6\xf6\xc9\xa9\x10\x0f\x20\x29\x1b\x32\xb2\xc0\x31\x4b\x31\xf7\xaa\x1c\x72\x52\xab\x3c\xc5\xcc\xa0\xbb\x64\x7b\x31\xbe\x39\x08\x18\x98\x63\x23\x1b\x98\x09\x15\x65\xb1\x5a\xd6\x2b\xeb\xc6\x94\x0a\x59\xae\xab\x8d\xfc\xfb\xcf\x3f\x5e\x56\xfb\x43\x55\x22\x51\xdf\x8c\x08\x32\x1b\xb9\xe2\xab\xa1\xec\x34\xac\x4d\xc0\xcf\x9a\xff\xfe\xcf\xa3\xac\x1f\x21\xee\x34\x6f\x7e\x2a\xb2\xbc\x74\xfe\x82\xb6\xb2\x03\x74\x8b\x1c\x15\x72\x2d\x8e\xf1\x4e\x35\x77\xb5\xe6\xc5\x76\xfc\xae\x68\xc9\x21\x9a\x43\x37\x91\xdb\xe6\x33\x82\x5a\x44\x58\xcf\x75\xb2\x91\x75\x9e\x15\xe3\x78\x79\xa6\x1a\xa9\x31\x37\x99\x1b\xf1\x3b\x18\xe0\x6b\xf8\x49\x63\x80\x7b\x23\x28\xbb\xe8\x9a\x61\x76\xdf\xd1\x36\x25\xcd\x10\xea\x74\x6d\x99\xf8\xd2\x9f\x31\x16\x9e\x98\xf5\xe1\x1c\xc6\xb0\x5b\x83\x48\x10\x48\xae\xab\x4b\xd7\xb1\x31\xd7\xe4\x0d\x25\xb1\xd5\x70\x09\x8b\xa2\x6f\x4c\xe7\x0d\xec\x26\x5a\x30\x78\xab\x3a\x54\x5d\xbc\xba\xb6\x98\xf1\x53\x47\x73\xc1\xd8\x89\x85\x1f\xe7\xbb\x77\xf9\x26\xa2\x90\x26\x0a\x5d\x00\x7a\x46\xa1\x92\x25\x68\x10\x2a\x47\x0c\x42\x4f\xfa\x43\x62\x94\xc6\x0d\xc7\x64\x07\xa0\xff\xad\xe2\xe4\x43\xfd\xa1\x24\x7a\x91\x8b\x47\x6e\x2d\xc7\x6f\x45\xc0\x56\x3b\x09\xff\x53\x89\xf3\xff\xf5\x6a\x71\xbe\xe5\xaf\x95\x38\xff\xff\xe7\x2f\x5f\x9c\xf3\x1f\x94\x38\xa7\xab\x24\x4a\xd9\x47\xb1\xfa\xcf\x28\x7d\x79\xce\xdf\xc1\xfc\x32\x7f\x99\xb0\x78\x35\xf9\xa0\xd2\x97\x74\xf5\x9f\x3a\xc7\xf4\x25\x7b\x71\xbe\xdd\xf3\x9f\xec\x3e\xef\x4d\x75\x54\x6d\x76\x38\xe8\xbf\xb3\x46\x55\xb5\x9e\xac\xe6\xb3\x33\xe8\x76\x4d\x5e\x95\x30\x67\xe9\xe9\xab\xbd\xcf\x37\xc0\xa3\xf7\xe2\x9c\xbf\x31\x8f\x7f\x7f\x75\xdd\xfe\x70\xf5\xcd\xb7\x5a\xa1\xfc\x59\xa7\x7d\x38\xff\x70\x7e\xce\x7f\x54\xe2\xe9\xc4\x7f\x81\xff\x2f\x94\x20\x2f\xcf\x89\x8d\x50\x25\x2f\x09\xe3\x7f\x19\xf1\xeb\xc9\x08\x5b\xfe\x45\xc1\x66\xa2\xb8\xc4\x5f\x0f\xfa\xd1\xdf\x10\x0a\x7d\x9a\x86\xab\x89\x73\x5e\xd5\xef\x5a\xda\xb0\xd9\x05\xaf\xfa\x7b\xeb\xc1\x96\x11\x6e\x5d\x94\xcc\xda\xf5\x45\x85\xf6\x64\x32\x23\x42\x88\x7a\xb5\x48\x13\x5a\x8b\xda\x61\xbe\xb4\x2d\x79\x49\x38\xc6\x56\x49\x08\x9a\x5c\xa5\xcc\x79\xb0\x97\x8c\xc5\xfd\x6b\xa0\x43\x94\x7e\x00\xd8\xc7\xfe\xa4\x8e\x30\x24\x52\x08\xf1\x8b\xf2\x02\xab\x69\x83\xd7\x8f\x0e\x55\x64\xd5\xa4\xe8\xa7\x89\x53\xd0\xaa\x41\x9f\x7c\xaf\x87\x9b\x47\x0a\xd1\x18\x77\xe6\xe7\x9c\x7d\x8b\xb6\xad\xda\x36\x5f\x15\x69\x52\x25\x53\x7a\x14\x05\x33\xfe\x30\x31\x45\x66\x64\xad\x8e\x74\xce\xf9\x05\xe3\x99\xfe\x37\xbd\x60\x27\xc6\x8f\x0e\xa5\xcd\xbf\x79\xb5\x48\xb5\x28\x9f\x43\x04\x42\x14\x65\xd0\xec\xdd\x77\xff\xab\x1f\xf8\x26\xee\xe7\xd9\xef\xd9\xc3\x7b\xa9\x54\x5e\x6e\x9b\xf9\x6d\x91\x29\x13\x4d\xe4\xd8\xb0\x4b\x5c\x4b\x3a\x8b\xe8\xaa\x4c\xb5\x52\x90\xaf\xca\x34\x91\x71\xdd\xb6\xb4\x16\x4f\x27\xc6\x56\x65\x8a\xb4\xbf\x6e\x52\xf5\xc8\x1e\xa7\x0b\x64\x64\xf1\x10\x16\x7f\x1d\x8f\x71\x16\x72\x6e\x36\x51\x1b\x7e\x14\xb2\xfb\x38\xa3\xe1\x91\x97\xba\x63\x1c\xf5\xa7\x1e\x9d\x6d\xc0\x85\xd8\xd6\x80\xfb\x29\xe7\xfb\x7c\x6f\xd4\x53\x30\x9c\xfe\x2c\x9b\x43\x55\x36\xf2\x07\x99\x6d\x64\x4d\x89\x41\x4b\x3f\xbb\x46\x6a\x25\xdc\xe8\x70\x2b\x27\x10\x24\x37\xe0\xd5\xac\xff\xe3\x7c\x56\x33\xf6\x74\x74\xad\x91\xb3\xe5\x4d\x2d\xb3\x4f\xa7\xfc\x16\xf8\xc2\xf3\x72\x52\xb2\x0a\x8a\x05\x4b\x4e\xc7\xe5\x55\xa2\x4a\x7d\x44\x0e\x28\xfd\x6d\x77\xb2\x86\x20\xa0\x7c\x46\x26\x64\xa6\x2f\xa4\xec\xa9\x12\xb9\xc9\x31\x03\xe0\xd3\x9c\x9d\x20\xe6\x38\xd3\x6f\x70\xfe\x11\xd5\x14\x3f\x3d\x8a\xba\xa2\x54\x8c\x97\xab\x2a\xed\x2a\xf6\xef\xfd\xee\xed\x81\xee\x3e\x9d\xf8\xda\xaf\x54\x33\xae\xa0\x06\xd6\xab\x8b\x14\x39\x3c\x60\xa9\xf4\x8a\xca\x8a\x55\xd6\xdf\xae\x0e\x3e\x25\x4b\x97\x95\x58\xdb\xe6\xb0\x5b\x76\xba\x1a\x81\xcb\x15\xea\xfe\xbb\x5c\x16\x9b\x66\x65\x98\x27\x46\xd2\x53\xa1\x18\x90\x71\x00\x7f\xab\x2e\xe2\x77\xb0\x9c\xe9\x35\x46\xf8\x09\xa0\x45\xd8\x4f\x80\x08\xd1\x8a\x7b\xaf\xd7\xaf\xc5\x5e\x52\xe9\x26\x71\x82\x13\x01\x8a\xfe\x63\x14\x1d\xc1\xe5\x04\x19\x5f\x33\x51\xac\x8e\xd0\x10\x55\xda\xb6\xc5\x8a\xbc\x84\x43\xc6\x3c\xa2\xa9\xfc\x96\xd2\x46\xe4\x1e\x24\x11\x5b\x5d\xa4\x06\xd7\xad\xcb\x40\x0f\xbf\x2e\x0f\x38\x63\xec\x09\x50\xc6\xb2\x24\x03\x92\xaa\x18\x39\xb5\xa1\x6b\x01\x79\xfb\x22\xe5\x6b\xd7\x92\x8d\x6e\x00\xaf\x63\xc1\xcd\x99\x7e\x7d\x16\x45\x72\x45\xd4\xae\xae\xee\x1b\x92\x32\x25\x32\x6a\xe5\x3d\x2d\xb7\xe3\x79\x27\x8c\x9b\x65\xb1\x51\x5a\xd5\x0d\xc4\x6d\x0e\x3f\x71\x96\xc8\x98\xbc\xad\x26\xd8\x84\x0d\x44\xc5\xd6\xd5\x5e\x77\xc7\x19\x99\xa8\x4a\xd7\xc1\xe9\x74\x0a\xf3\x69\x8e\xa0\xcd\x10\xae\xab\x3e\x56\x27\x0f\x3d\x31\x5b\xab\xfc\x4e\xc6\x0b\x5e\x64\x8d\x7a\x53\x6d\xf2\xdb\x5c\x6e\x20\xaa\x51\x65\x10\xdd\xe8\x4f\x33\xf1\xd3\xb1\x2e\x62\xb3\xd8\x70\xd0\xad\xc9\xf7\x57\xd7\x84\xe7\xcd\xeb\x6a\x9d\x15\xf1\x4f\x46\xbc\xb8\x34\xc0\x19\xeb\xaa\x60\x1c\xe9\x8a\x80\xc3\xb2\xae\x74\x39\x80\x9a\x65\xba\xe0\x59\xf3\x58\xae\x0d\xf3\xb4\x1e\xd4\xc8\xa6\x9c\x1d\x0e\x45\x8e\x3a\xd3\xf9\xc3\xd9\xfd\xfd\xfd\xd9\x6d\x55\xef\xcf\x8e\x75\x81\x42\xe9\x66\x39\x59\xef\x74\xc5\x28\xf1\xf7\xeb\xef\xce\xfe\x8d\x70\xad\xab\x1d\x94\x09\x1b\x7b\xa1\x90\xa8\x04\x75\x9d\x83\x96\x40\x09\x92\x1c\x60\x8a\x3e\x24\xfc\x41\x9f\x07\x6f\xda\x17\x7c\xe2\xd4\x23\xfe\x7b\x03\xe8\xba\xde\x0d\x3a\xc5\xdc\xf1\x7b\x76\x97\x19\xc2\x99\x93\x2d\x7b\x13\x3f\xe9\x3c\xcf\x3f\xdc\x3c\xec\x8b\x0f\x37\xe7\xf8\xca\xf3\x0f\x37\xfa\xf7\x1c\xf3\x3b\xff\x70\xa3\x7f\x3f\xdc\x9c\x9f\x78\x38\x86\xf0\x61\x62\x13\x7f\x7d\xf3\x9a\x98\xaf\xb0\x49\xd7\xf2\x41\xd9\x62\xd9\xb4\xbf\xbe\x7f\xf7\x16\x4b\x60\x46\xb3\xae\x01\x28\x22\x89\x51\xe7\x43\x8d\x6f\x02\xdf\x0c\xd4\xa5\x70\xaa\x73\x21\xb1\x7e\x1a\x75\x44\x93\xac\x3f\x3c\xee\xf4\xd1\x13\xf7\x16\x15\x6c\x79\xdb\x54\x0f\x2a\x9e\x2e\x4e\xae\x6f\x1c\x9f\xf1\x70\x53\xc9\xbf\x14\x85\xa5\x2b\x5c\xad\x18\x57\x2c\xfe\x97\xa2\x61\x2a\x70\xcc\xe8\x84\x8e\x5f\xe9\x3b\x45\x7f\x54\x0c\x12\xaf\xeb\xac\x6c\x0e\x55\xad\x74\xe2\x2f\x26\xb1\x17\xf9\x3a\x66\x23\xee\x71\x29\x82\xbb\xb6\x81\x6e\xe9\x41\x73\xa0\x09\xbe\x5b\x58\x8f\x07\xfa\x04\x21\xbc\x5b\xb1\x9b\x9b\xcf\x6e\xdb\x1d\x7f\xec\x4e\xa3\x88\x6e\x3d\x4c\x9e\xad\xd1\x7e\x58\x72\x4f\xb7\x2c\xb6\x7b\x00\x77\x41\x58\x36\xdf\x8b\xfb\xf9\x65\x56\x14\x37\xd9\xfa\x53\x43\x49\x55\xae\xe5\x64\x2f\xf7\x55\xfd\x48\x18\x7f\x10\xbb\xb9\x1e\xb4\xc7\xe6\x12\x48\xff\x9f\x4e\xfc\x46\x4f\xfd\xd7\xfa\xdf\xa5\x20\xc8\x77\x2b\x37\x84\x5f\x89\xa7\x5a\x66\x9b\xc7\xf7\x30\xc4\x81\x80\x3e\x5c\x2b\x47\x90\x90\x10\xda\x5f\xcf\x4f\x0d\x7b\x02\x52\x3e\xeb\x0b\xf0\x4e\x61\xb8\x64\xc6\x58\xb3\x52\x43\x5a\x0d\xa1\x56\xaf\xd2\x93\x12\xcd\xaa\xbf\xf1\x79\x0a\x54\x00\x85\x2a\x80\x3a\xe9\xf2\x7c\x53\x14\x61\x91\xc6\x40\xd3\xd7\xc6\x09\x13\xf6\xd2\x7e\x46\x78\x9b\xc1\x07\x78\x9d\x0a\xdf\xb3\x86\xa0\x9f\xeb\x41\x69\x46\x92\xda\x56\xf2\x9b\x95\x84\x35\x0a\x3d\x43\xaa\x3b\x59\xd7\xf9\x46\xbe\x31\xa2\xc6\x98\x63\x65\xf7\x9a\x9d\x13\x49\x84\xb4\x39\x74\x4d\x34\x5e\xcb\x80\x44\xb0\x66\x57\x36\x7c\x56\xae\xae\x4c\xb3\xfa\x51\x58\x0a\x15\xdb\x87\x95\x4a\xc5\x4a\xff\xe7\x72\xa5\xd2\x34\x64\x81\xc9\x6e\x74\xa7\x1f\xf1\xb7\x6b\xdb\x4b\x8f\x1d\x36\x9f\xc3\x8d\x54\x31\xfe\x89\x2e\xac\x77\xc5\x09\xf4\xf4\x3b\x17\xea\x7e\xc5\xf8\x6e\x7e\xac\x0b\x41\xa9\xee\xcb\xfa\xb0\x6d\xcd\x7c\xce\x66\x84\x30\xa7\x51\xfd\xac\xb8\x37\x89\xcf\xc8\xf9\x39\xd1\xcf\x82\xf1\xba\x9c\xef\xa5\xda\x55\x9b\xb6\x2d\x0d\xad\xdc\xce\xa5\xe0\x2d\x7c\xd7\x09\x2a\x82\x76\x27\xa0\x03\xb0\xe7\x95\x0a\x42\x2c\x90\xc9\x6e\xbe\xae\xab\xa6\xf9\xb6\xda\x67\x79\xc9\x9e\x46\x48\x07\xb4\xfe\xa3\x97\xd0\x02\x55\x20\xf8\x18\x6e\x4e\xf0\x87\x07\x99\x88\xbf\xf4\xbe\x67\xa6\xb5\xa7\xaa\x51\x53\x0c\x0b\xf7\x2e\x14\x90\xde\xad\xca\x61\x3e\x7a\xea\xcb\x6f\xcd\x57\x45\xd1\x6e\xee\x2d\x6b\x1d\xd1\xa2\x53\x17\xec\x7d\xe6\x01\x61\x6d\x0f\x78\xaa\xeb\xb4\xce\x36\x80\xa6\x99\x15\x8c\xf1\x8f\x7a\xce\xe3\x3b\x5e\xf2\x2b\xc6\xd7\x56\x7c\xbc\x5a\xd2\x5b\xbb\x45\xa4\x5f\x89\x6b\x2a\x8b\xa2\x85\xd0\x33\x16\x2c\xe2\xb3\x19\x88\xed\x81\x9d\x98\xc0\x64\xa6\xb2\x5a\x75\xcd\x87\x3f\x21\x36\x27\xdf\x81\x17\x90\xa1\x22\x9a\xbe\x31\xeb\x38\xde\xca\x78\x85\xd5\xeb\x7a\xc7\x6b\xf0\x4c\x08\x1e\x4a\x9e\xa9\x0f\xc0\xae\xdd\xcd\xbd\x25\x1e\x59\x08\xdd\x36\xe0\x1f\xae\xf7\x00\xff\x62\x2a\x0f\x7f\x3a\x1a\x42\xc5\xc9\x8c\x68\xd5\x71\x63\x4a\x88\x52\xb1\x8d\xac\x63\xdc\xab\x7d\xaf\x58\x9d\x4d\x55\x84\xcd\x04\x64\xa7\x33\x41\x3f\x99\x0a\xa8\x58\x42\x22\x12\x93\x84\xb0\x99\x69\x30\xe3\x5d\x6d\xee\xc7\xad\x9f\xdd\x7c\x9d\xad\x77\x10\xa2\x27\x2a\x57\xba\x1f\x14\x27\x2f\x2e\x08\xe3\x9b\xf1\x0c\xc9\x47\x41\x66\x57\x6a\x36\x9b\x6d\xec\xb8\xac\xf0\x30\xbf\xb5\xa2\x18\x20\x09\xf8\xb2\x19\x88\xe1\x57\xf3\xfe\x64\x49\xc9\x8f\xb7\x67\xf6\x9e\xb3\xf7\x79\xb9\x96\x84\x0f\x9e\x84\x8d\x17\x95\x6d\x3f\x97\xc9\xdb\xaa\x94\x67\x6f\x74\xd7\x27\xdd\xdd\x8c\x71\xaf\xc3\x77\xad\x6e\x36\xa8\x7a\xed\x5b\xfa\xa7\x6c\xfc\x4d\x81\x22\xc7\x83\x0c\x18\x1f\x7b\xe0\x1b\x90\xf2\x88\x3f\xb5\x80\x3e\xb5\x9b\x1b\xf9\x6f\x15\x5e\x49\x93\x67\xaf\xcc\x8c\x46\x11\x26\x27\x84\x4f\xc8\xec\x85\x9a\x91\xe5\xe4\x9f\x62\x31\x5f\x5c\x90\x98\x10\x16\x77\xd9\x00\x3c\x00\xe8\xd6\x07\x3d\x75\xef\xe6\x3b\x5c\xd6\xd8\x48\x79\x0f\xdc\x5d\x5e\x1d\x90\x29\x71\x37\x47\x22\xa4\xf7\xb2\xdc\x58\xd0\x37\x3f\x0d\x77\xf5\xb7\xfc\x8a\xef\x58\xdb\xae\x9d\x1f\xc5\x95\x99\xdb\x21\x93\x4b\x41\xe0\x8c\xf0\x3d\x30\xe4\xee\x3a\xf8\x06\x7e\x85\x10\x0f\xbb\xb9\x11\xf8\x75\x0a\x40\x3a\xec\xd0\x42\xcf\x78\x2e\x3e\x6a\xf1\xc9\xcc\x2f\x20\x0b\x5c\xcd\x3b\x39\x42\x5c\xf0\xdb\x28\x7a\xec\x4d\x1f\xc0\xe8\xb4\xba\xe2\xbb\x34\x98\x91\x76\x73\x10\xe0\x75\x0b\x28\x8c\x57\xfb\x1a\x50\xf5\xc5\x73\x48\x72\xf6\x3b\x88\xb9\x9d\xb0\x13\x77\xcf\x32\x9c\xcd\xd7\x62\x7a\xc1\xf3\x79\xa3\x95\x93\x1b\xfe\xc9\x53\x8d\x60\x45\x05\x45\x6a\x22\x97\x9f\xe8\xd9\x05\x10\x53\xc1\x62\x0a\x67\x5a\x2b\x72\x52\x22\xf1\xdc\xb1\x3f\xa1\x3d\xc7\x19\x78\x40\xd0\xbb\xe1\xd7\xfc\x52\x94\xcb\x75\xdb\xd2\xb5\x98\xc2\xc6\x63\x2f\xf8\xee\xa8\xab\xcb\x6c\x4b\x66\xa2\xd1\xd3\x16\x0f\x2a\x4b\x7d\xbd\x48\xbe\xd4\xaa\x93\x50\x5f\x8b\x57\x8b\x45\x14\xa9\xaf\xbe\x58\x2c\xda\xf6\x8b\xc5\x97\x42\x08\xc5\xb5\x02\x7c\x23\x7e\x55\x74\xc7\xaf\x00\xf4\xfa\x46\xfc\x5d\x9f\xdc\xf0\x2b\xc0\xea\x48\x68\x6f\xa8\xd3\x6b\x71\x35\x66\xf5\x78\x9d\x35\xca\x8d\x6e\x84\xe7\x1a\x8c\x6d\x71\xcd\xf8\x73\xcf\xeb\x51\x6c\x1f\x33\x23\x5a\x5c\x33\xc6\x5f\x61\x41\xdb\x96\xfc\x70\xf5\xcd\xb7\x04\xfa\xa3\x9e\x0f\x93\x4b\x41\xca\xca\x22\xef\xc7\xe6\x7b\x30\x55\xed\x6d\x39\x62\x7a\x29\x6e\x40\xae\x91\xfc\x20\x6e\x70\x7a\x2c\xc4\x94\x6e\xc4\x8d\xe9\x70\x38\x35\x5f\xf2\xa9\x8a\xa2\xcb\xb6\xd5\xbd\xd7\xa8\xb3\x0a\x9c\xad\x01\xe1\x09\xc6\x3b\x48\x47\x42\xb9\x43\xa0\x85\xa2\x65\xdb\x5e\x6a\xc1\x84\x17\xc9\x5d\x80\xf9\xb2\xe5\xab\x03\xbf\xe4\x57\x29\x8b\xef\x7c\xd0\x97\xad\xee\xa8\x97\x7c\x93\x76\x99\x6a\x31\x8d\x3e\x68\xd9\xda\x34\x66\xd0\xc5\x8b\x04\x3b\xb9\x51\x91\x63\x38\xbb\xc2\x32\xea\x3e\xcf\x8b\xe4\x10\xeb\xec\xf6\x00\x43\xe7\xbd\x24\x65\x3a\x27\xda\x1b\x2d\x97\x66\x34\xba\x11\x73\x76\x66\x17\x68\xd8\x29\x1b\x5b\x9e\x2b\xf0\x3d\xb3\x92\xf4\x15\x08\xcf\x5a\x3d\x7b\x26\x2e\x6b\x72\x6f\xa3\x5b\x78\xc9\x09\x68\x73\x0c\x9e\x79\x0f\x4a\xe9\xb8\xdc\x6c\x9f\xb1\x8e\x2a\x1d\x67\x6a\xe0\x10\xb6\x95\x8a\x70\x72\xa8\x1a\x35\x04\x4b\xef\xc5\x61\x85\xf0\xc3\x5b\x6a\xa1\xf7\xdb\xb6\xe6\x35\x00\x70\x5b\xad\x0b\x75\xaa\x0e\x2a\x06\x94\x49\xc9\x8d\x3f\x93\x9d\x83\xe3\x1c\xed\x13\x25\x37\xd3\x57\x0c\x68\x18\xfd\x6d\xa4\x28\x02\xdf\x44\x9d\xab\x65\x2b\x1e\xf3\x10\x33\xef\xf4\x5f\x85\xb6\x0a\xf7\x3a\x5b\x01\x1c\xd6\x6e\xcf\x20\x71\xe1\x4c\x16\x17\xdc\x9a\x6e\xc0\x6d\xa0\xb7\xc3\x74\x5f\x67\x87\x6f\x8a\x11\x0f\x5e\x5f\x82\x87\x35\x8a\x22\x5a\x0a\x95\xc2\xf3\xb7\x5d\x2d\xf4\xb2\xaa\xc4\xbd\x41\xf9\x1d\xb0\x61\xb3\xb9\xfc\x27\x5d\x30\x8f\xa4\xce\xde\x16\x46\xd2\x04\x3c\x96\x36\x67\xae\xc6\xf7\xa7\x00\x85\x09\xd5\x3e\x89\xc4\x9e\x46\xa2\x46\x7e\x4f\x5d\xc2\x41\x6a\xc7\x84\xec\x58\x0d\xd1\xc3\xdb\xa8\x43\xba\x22\x7e\x2c\xcb\x71\x46\xe4\xe7\x3c\xdf\xbd\xb8\x06\xf7\x7c\x18\xd5\xc0\x3e\xef\xea\xee\x1c\xdb\x4b\xa1\x9c\xe5\x99\x76\x81\xea\x49\x39\x37\x2d\x04\xfb\x6c\x1e\x1f\x23\xc3\x22\x8f\x68\x55\xdb\xce\xdf\x7f\xcc\xb9\xa3\x0c\xcb\xac\xb3\x56\xa1\x0b\x35\x8b\x31\xff\x63\x39\x78\x43\x40\x20\x08\x0d\x48\x25\x9b\x97\x95\xa2\xe4\xa6\xda\x3c\x92\x21\x15\x6e\x17\xf7\xe1\x78\x11\xed\xa6\x9d\x65\x42\x67\xa7\x0e\xdf\xca\xc4\x5d\x1e\x1a\x79\xdc\x54\x8d\x45\xfa\x1b\x81\xcd\xe8\xdd\x08\xd4\x51\xba\x3f\x40\x07\x1f\xbb\x34\x96\xc9\x94\xca\x90\x7a\xce\x9e\x22\x91\xc9\x67\x08\x11\xe0\x35\xc1\xf6\xc5\xc3\xae\xf6\xa3\xe0\xb5\x20\xe0\xa1\x9a\xcb\xf9\xaf\x6f\x5e\xff\xa0\xd4\xc1\x48\x58\x3e\xe9\x26\x58\x72\xfe\xa1\xc4\xd3\x02\xe2\xfa\x2f\x5e\xbd\xfa\x22\x7e\xb5\xf8\xf2\xc4\xbf\x57\xfd\x3d\x92\x87\x5d\x4d\xd9\x52\xcb\x4b\x75\x23\xa6\xd3\xef\x55\x14\x91\xfb\x5c\xed\x2e\x6b\xb9\x91\xa5\xca\xb3\xa2\x21\x79\x39\xf9\x5e\xf1\x1d\x3c\x28\xbe\x57\x70\x9b\x29\xac\x93\x2d\xe8\xc0\x51\x83\xd7\x28\xde\xe9\x9c\xdb\x56\x67\x3c\x55\x81\xfe\x6a\xcd\xb1\x01\xbb\xaf\xef\x05\x2a\x94\x29\x5e\x7e\x4b\x1b\x20\x78\xa4\xe8\x29\xc6\x15\xe8\xb5\x0a\x65\x2d\x7d\xd6\xc8\x1a\x77\xcb\xe7\x87\xac\x69\xee\xab\x7a\xa3\xc7\xfa\xc3\xae\x46\x53\x62\xb7\x0f\xe0\x27\x36\xab\x2c\x15\x5e\xc2\x2a\x4b\x97\xca\x19\x36\xa2\xa8\x99\xf7\x8d\x22\x63\x69\xb4\x7b\x44\xbf\xd3\xfb\xc2\xb6\xcd\x57\xe4\xd7\x33\xd3\x40\x72\x73\x06\x1c\x9e\x69\xdb\xd2\xd1\x74\x41\xc2\x16\x35\x60\x92\x50\xec\x9c\x35\x43\x69\x3a\xe3\xe0\x19\xbd\x1c\xeb\xce\x13\xaf\xe7\x94\x60\xf1\xab\x45\x33\xaf\xca\xa2\xca\x36\x70\x00\x12\x07\x1c\x81\xfc\x09\x47\x46\xea\x84\x63\x10\xe9\x40\x8c\x59\xef\xb2\x72\x8b\xe4\xba\xdc\x88\xd9\x10\x72\xd2\x58\x09\x3c\x36\xe2\x0b\x06\xa2\xf4\x81\xab\x1a\x23\x71\x24\x15\x5d\x70\x73\x27\x8b\x2b\x6a\xd3\x79\xe3\x09\x37\xfa\xc2\x3f\xd4\xca\x26\xa5\x6d\x3b\x7a\x1b\x1a\x67\x81\xec\xa2\x71\x3b\x2f\x46\x8d\x86\x2b\x6c\xc4\x41\xc8\xbb\x53\x3e\xa8\xe4\xe9\x26\x2f\xb3\xfa\x31\xee\x92\x4f\xf1\x13\x98\x71\xc3\x1b\x4f\x1c\x18\xe9\x86\x76\x3b\xca\x30\x1c\xc0\xd6\x6a\x49\x19\xaf\x7b\x75\x6b\x6b\xb4\xa4\xf6\xcb\xbb\xc8\x5e\x57\xf7\x49\xd7\x0a\x75\x3c\x5a\xf7\x5e\x63\x6a\xa1\xb3\xf1\x04\x6e\xe0\x24\x1a\xc7\xa8\x8e\xa2\x9a\x22\xd7\xb7\x7e\x3f\xb6\x1c\x2a\x14\x0d\xea\x12\x2a\x50\x5a\x71\xe7\x15\x51\x8b\x42\x15\xa3\xb4\x2a\xc6\x69\x60\x7a\x83\xd7\x94\xd4\x32\x88\x04\xa6\x6a\x1a\xba\x86\x7b\x23\x03\xa2\xfc\xed\xea\x34\x47\x91\x43\xe0\x56\x70\x60\x6a\x76\x9b\x18\x78\x8b\xd9\xad\xe8\xb6\x1a\xf8\x24\xd8\x8d\x78\x26\x5d\xae\xf7\xa3\xe9\x0f\x67\xdd\x95\x60\xd3\xc2\xbc\xed\xfc\xc3\x0d\x4d\x62\x9d\x6b\xab\x6f\x64\x98\x0c\x3b\x15\xc1\xf6\x02\x6c\x14\x98\x6c\xc6\x16\xb7\x7b\x63\x99\xba\xba\xcb\xf4\xaa\xcb\xe5\x68\x65\x39\xc9\x2b\x58\x80\x1d\x6d\xb4\x33\xa6\x98\x23\x5d\x5d\x7c\x58\xa9\x88\x1e\xa2\x65\xba\xae\x32\xbb\x49\x7a\xf4\x1d\xb0\xad\x19\x18\x16\x4d\x24\xcb\xf2\xf9\x19\x5a\xcb\x19\xe4\x2b\xcc\xed\x6b\xc2\xd0\xbd\xe7\xc9\x6c\x41\xc5\xd2\x34\xe9\x25\x9e\xf3\xa6\x5e\xc7\x52\x4f\xd9\x27\x36\xaf\x4a\x4a\xf4\x70\x99\x18\x95\x27\x9c\xbc\x94\x75\x1a\xb4\xee\xe1\x5c\x46\x51\x45\xbd\x09\x06\x55\xb1\x2f\x17\x5f\xc2\xd2\x86\xa7\xfa\x53\x6b\x30\x2c\x04\x78\x2e\x4a\x8b\x7c\x9f\xeb\xb1\xc6\x1b\xe6\x37\x25\x56\x29\xff\x9b\x12\xe7\x54\xb0\x0f\x09\x4d\x44\xd4\xbe\x60\xed\x87\x04\x7d\x11\xbd\xfe\xa8\xd5\x8a\x43\x4c\xd6\x66\xa7\x02\xf7\x9e\x0e\x76\xe3\x62\x48\xb6\xf1\x9b\x42\x9f\x64\x50\x72\xd0\x8b\x7f\x46\x3e\xa2\x7d\x2b\x90\x87\x25\x38\x62\xc8\xd1\x7e\xa1\xdf\x01\xdb\x53\x07\xc2\x83\x88\x89\x1e\x6f\x15\x18\x9d\xd4\x1c\xee\x8c\x22\xfa\x37\xeb\xee\xa4\x2b\x9e\x25\xe4\x58\x17\x64\x18\xf3\xac\x8c\xfd\x0a\x2c\x92\xea\x7f\x6a\x91\xec\xde\x69\xec\x86\x44\xff\x62\x2c\x6d\xd3\xb6\x04\xbf\x02\xdc\xc2\x03\x2f\x0f\x6b\xb2\xb7\xc5\xb7\x35\x2a\xb6\xb4\x97\xc2\x92\x5e\x02\xd5\x52\x6c\x90\xc2\x9b\x44\xad\x9a\x54\xe8\x7f\xce\xec\xf8\x37\x34\x3b\xce\x72\x16\xf7\xea\x09\xea\xc7\xb3\x6e\xda\xfa\xb2\x06\x49\x73\x27\x78\x00\xe6\xb0\xc2\x77\x8e\x02\x66\x3c\xe1\xe6\x61\x2a\x86\x1b\x39\x59\xe7\x08\x9a\xcf\xc8\xe4\x3e\x6b\x26\x65\xa5\x26\xba\x03\xe9\x1a\xe3\xd9\x6a\x91\x9e\x78\x58\x1b\x02\xb5\x57\x40\x61\xce\x53\xae\xff\x05\x58\xf3\xc2\x05\x3e\x9e\x78\x3d\x02\x68\xec\xe6\x8c\x2a\x81\xc0\xa2\x0e\x2c\x83\xe6\x2c\x86\xec\x2a\xf0\x9e\x84\x8f\x0f\xeb\xbb\xec\x55\xa5\xee\xc0\xc7\x66\x47\x73\x06\x1c\x6c\x5b\x80\x89\xae\x68\x06\xca\x54\x26\xaa\x8e\x05\xc1\x4e\x2d\xe0\x7a\x8d\xbb\x12\x3f\x5c\x03\xe8\x05\x94\x75\x00\xc8\x25\xea\x79\xbe\x3f\xa0\x3e\x05\xbd\x6a\xe4\x21\xaa\x7b\xa0\x56\x03\x3a\xdc\x98\x8e\x6b\x9e\x7c\xa5\x3b\xe0\xd7\x5f\x9d\xe3\x8f\x7f\x42\xf8\x2b\x9c\x32\x9d\x46\x60\x84\xec\x13\xd5\xe3\x0b\x36\x73\x21\x8f\xbe\x29\xc1\xe3\xdd\xef\x60\x0c\x4d\xef\x5c\xa5\xcb\xd1\x68\x67\xb3\x99\x3a\xbd\x60\xdd\x06\xaa\xcf\xaa\x3a\x56\x1b\x09\xa5\xb9\xa0\xea\xcf\xd6\x01\xeb\x6f\xf3\xdc\x64\x8d\xd4\xc9\xb0\xaf\x53\x3b\x77\x6a\xe3\x82\x30\x9c\x09\x73\xc6\x62\x25\x80\x62\xf3\x1b\xdc\xd3\x04\x36\xb4\x69\x19\x45\xab\x94\x57\xc9\x4a\xf5\xde\x50\xad\x2e\x52\x96\xc6\xb4\x12\x0f\x08\x86\xae\x78\x06\x3d\x20\x73\xfc\x6d\xf7\x34\x63\xdd\x6c\x7d\x3f\xdf\xcb\x7a\x2b\xa9\xce\xce\xd7\xc4\xac\x79\x00\x24\xa4\x67\x21\x55\x78\x86\x3c\x0f\x8d\x90\x7e\x24\x7c\x07\x78\x8d\xe1\x54\xb5\xb8\x53\xd4\x32\xe2\x6a\x4d\x5b\x2b\xe6\x78\xb6\xe0\xfa\x1c\x5c\x7a\xc3\xdd\xed\x58\x8d\x80\xb9\x02\x6f\x86\x20\x3f\xbd\x7b\x7f\xad\x07\xa1\x85\x96\x59\x44\xd1\x88\x85\x24\x6f\xdb\xbe\x91\x04\xfd\x25\x8c\xe3\x08\xeb\x61\xc4\x4b\x80\x3d\xb7\x63\x94\x67\x73\x7d\x37\xad\x13\xbd\x62\x6e\xf2\xbb\xaf\x1d\xea\x18\xf5\xba\x22\x80\x0c\xdc\x22\xde\x31\x68\xcb\x76\x60\x97\x51\x14\x5a\x9c\xb2\x81\x46\x1c\x00\x03\x56\x6d\xeb\x79\x23\x81\xb0\xac\xb8\x4c\x81\x28\xc2\x5a\x26\xac\x5d\xab\xdb\x07\xe3\x9d\xd1\x8d\xf7\x2c\x76\xbe\xed\x2f\xb0\x0a\xf2\xce\x10\x3e\xa4\x10\xec\xc3\x1c\x86\x9a\x3e\x2c\x60\x92\x8d\xe8\xe7\x06\xe1\x6f\x33\x6e\xbd\xda\xd6\xf2\x40\x1d\xfc\xa4\xaf\x72\xda\x09\x02\xd6\x16\x44\x72\xb7\x63\x9e\xdf\x1b\x1d\x1c\xe2\x2f\xde\xc1\xe1\xf3\xe8\x3e\x9d\xf7\x83\x47\xcc\x6b\x98\xfd\x08\xe3\xb7\x42\xcf\xa9\x1c\xa8\x6e\x88\x16\xd1\xf3\xb5\x61\x6c\xb0\x44\x7b\x1e\x2f\xbd\xa5\xed\x27\x8c\x37\xe2\xd6\x94\x82\x22\x46\xac\xc9\x1a\xcc\x9c\xfc\xd8\x25\x14\x40\x93\xc7\x69\x21\x68\x47\x64\x6d\x78\x22\x6e\xf3\x07\x80\x38\x13\x6b\xdc\x92\x3b\xfa\xeb\xf3\x51\x55\x08\x1a\x91\xd0\x4c\xd0\x5a\xdc\xba\x82\x50\xc6\x80\x87\x3f\xd7\x53\x85\xbc\x55\x2c\xa6\x99\x4f\x1e\x59\xb1\xb6\x5d\xf0\x80\x7d\xf6\x08\xec\xb3\x1c\xb1\x8a\xa9\x12\x0e\x4d\xbb\x0c\x40\x6b\x1b\xc6\x2c\x5c\x30\x50\xfd\x47\x11\x3d\xe8\x5f\x3c\x3b\x6b\xf4\xff\x59\xd6\xdd\xa2\xdf\x0e\xf7\xe8\x03\x73\x7e\xd6\xc0\x8f\x5e\x5b\xc9\xb1\xd1\x53\xaf\x56\xd3\x13\xad\xd4\xe7\xe5\xd6\xbe\xf7\xc0\xe2\x5b\xa8\xa2\x03\x72\x1e\x79\x16\xc7\xaa\xdf\xa2\xec\x73\xe8\x00\x9d\x44\x0d\xf6\xb7\x31\x53\x1a\x74\x60\xcc\x75\xee\x7a\x8c\x45\x31\x55\xcc\x48\x8d\x08\x98\xe0\xc5\x25\xd5\x0e\x80\xe0\x39\x1b\x4f\x02\x53\xfe\x33\xc4\x85\xbc\x14\x75\x68\xea\xf4\x03\x05\xf9\x93\xaa\x0e\x31\x54\xeb\xac\x9c\x1f\xb2\xad\xfc\x0d\xcb\xc5\x75\xe5\xc5\x58\x95\xe6\xca\xaf\x78\xe5\xc4\x62\x78\x68\x81\xb7\x2c\x4e\x27\x7e\x18\x21\xe0\xcf\x6f\x9d\x79\xd4\x42\x65\xfa\x5f\xc6\x73\x11\xe6\xa2\x3f\xb5\xeb\x89\xd8\x6f\x6b\x7f\x8c\xb0\xcf\x7c\x24\x7a\x93\x1a\x82\x3b\x37\x1e\x06\x5f\xce\xb5\x78\x80\x97\x7f\x02\xa3\x60\xdb\x96\xf3\x8d\xb9\x68\xd6\x28\x6b\xaf\x05\x0b\xb2\x10\x25\x08\x0a\x6d\x8b\xc7\xbd\x7b\x01\x0e\xc1\x0d\xd6\x91\x71\x0d\x26\x5e\x0f\xab\x49\xab\xd5\xc8\x7b\x31\xe0\xa0\xa1\x39\x4c\x01\xae\xf4\x30\xb6\x06\x74\xdb\xd7\xd5\xc1\x11\x6d\x33\x9e\x63\xf3\xf4\x6f\x7a\x2d\x6f\x55\x77\x97\xdd\xeb\xe8\x5a\xfa\x2c\x87\xff\xae\x8e\x91\x19\xea\x5a\x4f\xd2\x40\x3d\xd3\xb5\xfc\x19\xbe\xa1\x7f\x2b\x70\x6e\x62\x44\xdc\x89\xfb\xf5\xf9\x5f\x8a\xde\xf0\x1a\x0b\x9f\xee\xaa\xfe\x4f\xd4\x6a\xf0\xa0\x9d\xa6\xdb\xf6\x46\x9e\x42\x74\x5a\xc7\x8f\x16\x13\xaf\x13\x13\xee\xf8\xd4\x30\xdd\x74\xfb\x67\xa2\xf5\x82\x5b\xf4\x5a\xb0\x1c\xc0\xca\xd6\x9f\xa1\xc0\x84\xbd\x1b\x9d\x13\xb0\x8b\x03\x4e\x54\x25\x64\xfc\xef\xfd\x3e\x50\x09\xe9\x0f\x4e\x9f\xd2\xd7\xf9\x36\x27\xd5\x4a\xa5\x31\x70\x9d\x54\x49\xe5\x68\xe1\x68\x99\x54\xfe\x28\x8d\x73\x5e\x26\x79\x5c\xf9\x63\x9a\xc1\x63\x22\x3f\x01\x8a\xef\x60\x26\xeb\x81\x10\xeb\x25\x1b\x56\x8d\xcf\x13\xf9\x02\x91\xeb\x21\x7f\x90\xc5\x4f\xa6\x81\xfc\xdb\xcb\x80\xd4\xd7\x12\x82\x2b\xc6\x2d\xc5\x7a\xc9\x50\x9b\xe8\x16\x95\x95\x4a\x81\x64\x35\x2e\x4f\xcc\x6b\x48\x43\xd9\xed\x58\x86\xa1\x83\xc7\x86\xe2\x6b\x08\xfa\x8b\x0f\x39\x4e\x56\x90\xef\xc9\x4c\x5a\x6b\x4c\xac\x38\x21\x31\xa9\x8e\x0a\x92\x4f\x3d\x10\x59\x68\xdd\xda\x6b\xdd\xce\x7e\x2c\xfa\xf5\xa6\x45\x75\x0f\x59\xd9\x09\xf8\xb9\x5e\x9d\xcb\xb6\xa5\xe0\xdb\x9c\xb7\xed\x14\x95\x27\x4b\xc4\x16\x5b\xfa\x5d\x27\x8e\xf6\x3b\x0e\xc0\x17\xd8\x8e\x63\xee\x79\xd4\xa2\x28\xf8\xf0\x77\x6b\x34\x7e\x05\x4b\xd4\xca\x7d\x67\x1a\x2b\x37\x59\xf5\x67\xad\x15\x59\xc3\xd4\x09\xb7\xfd\x3b\x48\x36\xb6\x0f\x26\xb4\x12\x83\xfb\xb9\xa3\xa2\x51\x30\x19\x82\x7a\x5a\x15\x85\x7e\x9e\x57\xc1\x99\xbd\xc1\x12\x13\xe3\x0d\xe1\x59\xf7\x72\x66\x63\x39\x74\xfd\x24\x38\xd0\x15\x10\x07\x3b\x86\x44\x44\x70\x68\xd8\x49\x6b\x0a\x49\x1e\x5b\x17\x01\xc0\xea\x75\x9d\x83\xdc\x14\xc7\x7a\x02\x11\xb7\x13\x13\x86\x3b\xb1\xf1\xb7\x93\x5a\x36\xf9\xbf\xe4\x04\x4b\x39\x59\x17\xf9\xfa\xd3\x64\x73\x53\xe0\xc1\xbe\x3a\x36\x72\x53\xdd\x97\x78\x74\x3c\xe0\xaf\xd6\x3e\xf0\xa8\xba\x93\xb5\x39\x3a\x2a\x3c\x90\xa5\xb2\x69\x85\xcc\xee\xe4\x04\xad\xa9\x13\x0c\x94\x9c\x60\x80\xe5\xe4\x93\x7c\x84\x7c\x3f\xc9\xc7\x43\x2d\x9b\x46\x1f\x1c\x0f\x13\xe3\xcd\xba\x97\xe5\x91\x78\xae\xf2\x7f\x28\xe8\x7a\x3b\xd2\x03\xe8\xca\x45\xd2\x49\xbf\x68\xdc\xe2\x96\x99\xd4\x6e\x7e\x8f\x04\x5b\xef\xf4\xa7\x7d\x26\xd4\xba\xfb\x56\x3d\x3e\xbb\xcf\xa5\x0a\xd0\x04\xfa\xd9\xdd\xe4\xbe\x35\x2f\xdc\x43\xb7\xc5\x93\x26\xf2\x9b\x97\xb0\x6b\x37\x78\xa4\xf7\xc0\xed\xad\x7b\x82\x9d\xb8\xc5\x53\xf8\x03\x82\x06\xd4\x01\x0c\xd1\xc2\xb1\x7c\xe6\x29\xf7\x8c\x5e\x87\xfb\x15\x9a\x78\xaf\x27\x2f\x5f\x12\x53\x97\x3a\x41\x71\xf0\xab\x7c\x49\x78\x69\xaa\xe0\x50\x57\x0f\x8f\xe3\x31\xa2\x1c\xe2\x60\x87\xb6\x31\x50\xee\xe5\x4a\xa5\x86\xc3\xa0\xd4\x12\xb1\xc7\x70\x28\x2a\x14\x4f\x3b\x65\xef\x15\xf3\x83\x4d\x3d\xfc\x42\xa3\xa1\x99\xf0\xea\xda\x06\xb2\xf5\x33\x60\x5a\x61\xce\xe7\xdb\x63\xbe\x11\xd2\xff\x69\xdb\x7b\xf8\x9d\xcd\x78\xae\xe5\xdf\x5d\x55\x6c\x7e\x96\xd9\xe6\x31\xc4\x5f\x01\x5c\xda\x6c\xf3\xf8\x4b\x96\xab\xd9\x2c\x36\x67\x40\x1a\x01\x5e\x03\x10\x7e\x28\x82\x60\x44\x6b\x10\xf9\xeb\xfb\x77\x6f\x85\xe7\xff\x7e\xef\x62\x24\xc5\x5b\x78\xf6\x3b\xf3\x22\xb1\x85\x53\x04\xac\x10\xfa\xf9\x75\xb6\x97\xc5\x65\xd6\x48\xf1\x3d\xbf\x47\x13\xf4\x03\x3c\x7f\xef\xa2\xbb\xe1\x91\xb7\xc7\xbd\xac\xf3\xf5\x08\xbb\x04\x3e\xd5\xed\x33\xd3\x0e\x5d\x4b\x28\xdf\x31\x51\x68\x59\x6e\x9a\x37\x6f\xb3\xb7\x54\xfa\x84\xe9\x52\xd7\x1c\xb1\x39\x77\x8d\x88\xc0\xd0\x51\x84\xbf\xf3\x6c\xbf\xb1\xc7\x94\xa0\x67\x3a\xe1\xab\x74\x84\x61\xfc\xde\xc8\xf9\x7f\x55\x42\xce\x7f\xff\x9b\xbe\x93\xff\x87\x3e\x7e\xd1\x31\xb7\x94\xd5\x65\x55\xde\x16\xf9\x5a\x89\x31\x65\x74\xfe\x42\xcb\x45\xa0\x1a\xbe\x10\xff\xa1\x80\xfc\xc2\xe6\xe5\xae\x98\xd3\xbf\x2a\xc6\xef\x4f\x5c\x01\x46\x91\x49\xd3\x8f\xdd\xeb\x64\xb6\xfc\xff\xfe\x4f\x00\x00\x00\xff\xff\x84\x5b\x9a\x60\x8f\x53\x01\x00") +var _pkgUiStaticVendorJsJquery350MinJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\xfd\x7b\x77\xdb\x36\x12\x38\x0c\xff\xff\x7e\x0a\x8b\x9b\x65\x81\x08\x92\xa5\xa4\xed\xf3\x94\x32\xaa\x93\x3a\x49\x9b\xdd\x5e\xe3\x74\xdb\x2e\xc5\xf4\xd0\x22\x64\xb1\xa1\x40\x95\x04\x7d\xa9\xc8\xfd\xec\xef\xc1\xe0\x42\x90\xa2\xdc\xee\xfe\x7e\x4f\x7b\x62\x91\x20\xee\x18\xcc\x0c\x66\x06\x33\xe7\x4f\x47\x67\xbf\xfd\x50\xb1\xe2\xe1\xec\xf6\xf9\xf4\x93\xe9\xec\xac\x3e\x43\x6b\x7c\xf6\x8f\xab\xb3\xd7\x79\xc5\x93\x58\xa4\x39\x3f\x8b\x79\x72\x96\x8b\x2d\x2b\xce\xd6\x39\x17\x45\x7a\x5d\x89\xbc\x28\xcf\xea\xb3\xdf\x7e\x97\x45\xa7\x79\x71\x73\x9e\xa5\x6b\xc6\x4b\x76\xf6\xf4\xfc\xff\x37\xda\x54\x7c\x2d\x0b\x22\x46\x04\x3e\x78\x55\xc9\xce\x4a\x51\xa4\x6b\xe1\x2d\xbc\xfc\xfa\x37\xb6\x16\x1e\xa5\xe2\x61\xcf\xf2\xcd\xd9\x2e\x4f\xaa\x8c\xf9\xfe\x89\x0f\x53\x76\xbf\xcf\x0b\x51\x2e\xbb\xaf\x94\x4d\x93\x7c\x5d\xed\x18\x17\x4b\x81\x18\x19\xcd\x70\xd0\xb6\x8a\x0f\xe9\x06\x8d\xda\x2c\x58\x6c\x8b\xfc\xee\x8c\xb3\xbb\xb3\x57\x45\x91\x17\xc8\xd3\x63\x2e\xd8\xef\x55\x5a\xb0\xf2\x2c\x3e\xbb\x4b\x79\x92\xdf\x9d\xdd\xa5\x62\x7b\x16\x9f\x99\x92\x1e\x5e\x14\x4c\x54\x05\x3f\x13\x88\xe1\x26\x80\xbf\xc8\xab\x78\xc2\x36\x29\x67\x89\x37\x32\xdd\x55\xe5\x97\xea\x27\x10\xdb\xb4\x24\xb6\x43\x97\x84\xf5\xa6\xe1\x36\x2e\xce\x04\x0d\x23\x52\xd0\xef\x60\xdc\xd3\x1b\x26\xbe\x2f\x72\x91\xcb\xea\xbe\xdb\x90\x92\x8a\x69\x29\xe7\x94\xdc\x50\x31\xdd\x64\xb1\x58\xba\xe3\x33\x9d\x82\x2f\xd3\x75\x9c\x65\xd0\xbd\xc1\x2c\xeb\x9c\xaf\x63\x31\x8d\xf7\xfb\xec\x01\x85\x11\x61\xb8\x21\x15\x15\xd3\x7d\x55\x6e\x49\x4a\xc5\x34\xe5\x09\xbb\xff\x6e\x43\x38\x3d\x34\x24\xa7\x7c\x2a\xf2\x2b\x51\xa4\xfc\x86\xdc\x52\x3e\xdd\xc6\xe5\x77\x77\xfc\xfb\x22\xdf\xb3\x42\x3c\x90\x98\xde\xb6\xdf\x33\x1a\xab\xc6\xd5\x20\x30\x79\x90\x55\xec\xe8\x71\x3f\x3c\x93\xd4\x2e\xb0\x5c\x74\x5e\xed\xae\x59\xd1\xce\x22\x9b\xf2\x3c\x61\xef\x1e\xf6\xac\x21\xf7\x03\xd5\x9c\xf1\x2a\xcb\x46\x94\xf9\x3e\xa3\x94\xb2\xa9\x9a\xee\x86\xbc\xa2\x97\x76\xb5\xc9\x9a\x1e\x64\x75\xc1\x68\x46\xca\x62\x2d\x7f\x78\xce\xd7\x4c\x3d\x7c\x03\x70\x14\x8c\x66\xcd\xc2\x54\x7f\x76\x2d\x01\x95\x70\x7c\x90\xcb\x52\x90\x94\xe4\x14\x71\xca\xeb\xfa\x15\x9e\xae\x0b\x16\x0b\xf6\x2a\x63\xb2\x6a\xe4\x95\xeb\x22\xdd\x4b\xb0\x48\x37\x28\x9f\x0a\x76\x2f\xa8\x04\xf2\x4d\x5e\xa0\xe2\x2c\xe5\x67\x6b\x8c\x52\x2a\xc2\x22\xaa\x6b\x58\xd3\x17\x42\xed\x17\xe6\xfb\xdd\x77\x54\x60\xec\xfb\xf9\xb4\xec\xa4\x91\x14\x2f\xf8\x74\xcb\xe2\x44\xae\x17\xe3\xc9\xe5\x36\xcd\x12\x94\xe3\xe9\x3e\x2e\x18\x17\xdf\xe6\x09\x9b\x16\x6c\x97\xdf\x32\xf3\xa5\xb1\xc3\xb8\xeb\xcd\x13\xa5\x6c\xc9\xc6\x9e\x17\x1c\xed\x2d\x56\xd7\x43\x0b\xb2\xe4\x61\x6e\x80\x29\xaa\x6b\x53\x2c\x30\xdf\x1b\x39\x3f\x1b\xea\x01\xa6\xf0\xc8\x15\xed\x6e\x74\xd3\x34\xbb\x3b\xbb\x9a\x6e\xf8\x34\xe5\xa9\x80\x2f\xce\x54\xef\x65\x1f\x15\xf4\x8f\x46\x12\x02\x32\xc6\x6f\xc4\xd6\x4b\xb9\x84\x07\x36\x55\xaf\x84\x53\x39\x18\xbd\xf7\x46\x3b\xc4\xb0\xef\x8f\xee\xe1\x07\x79\x71\x51\xc4\x0f\x1e\xa5\x72\x85\x66\x94\x52\x51\xd7\x06\x90\xec\x58\x84\xef\xcf\x2e\x84\xef\x8b\xc9\x5c\x2e\x0b\xc3\x8d\xec\x12\xbd\x9a\xee\xcd\x26\xa3\x07\x85\xbd\x82\x0d\x59\xe7\xbc\x14\x45\xb5\x16\x79\x11\x5c\x11\xd5\x85\x60\x46\x44\xfe\x42\xb6\xd4\xee\x2a\x3b\xc4\x52\xcd\x92\xdc\xe5\xb8\x21\x37\x4c\x0c\xed\x3c\xb3\x04\x6e\xe6\x80\x5d\xcc\x96\xf2\x29\x64\x63\xf9\xa3\xc7\x1b\x05\x2a\x2d\x6a\x88\xdc\x95\x57\x22\x5e\x7f\xe8\x54\xa9\x66\xec\x6a\xba\x63\xc5\x0d\x83\xaa\xa6\x4e\xa7\x11\x26\xac\x45\x54\xd3\x7d\xc1\x6e\xd5\x86\xa4\x80\x87\x44\x43\x58\xbc\xde\x0e\xf5\xf1\x6a\x2a\xbf\x40\x85\x80\x17\x76\xf1\xbe\xcd\xc6\x5b\x24\x22\x1b\xb4\x3d\x43\x57\xd3\x5d\xbc\x47\x5d\x1c\xd7\x81\x00\x0d\x44\x44\xc8\x4a\x31\x6e\x08\xa0\xb2\x81\x89\xec\x55\x5c\x6a\x2c\x05\x55\xc7\xc5\x0d\xec\xe7\x52\x56\xb0\x49\x8b\x52\x9c\xaa\x80\xfd\x8e\x66\xb8\x21\x59\xfc\x68\x96\xc9\x1c\x37\x84\xdd\x32\xfe\xe7\xfd\xb8\x9a\xde\x14\xec\x91\x11\x22\x31\x9e\xe3\xbf\x3f\x83\xa1\xe5\x49\xf2\x7f\x5e\xe1\x99\xd0\xb5\xb1\xdf\x07\xd6\xdd\x81\x14\xc2\xe9\x98\x8d\x11\x80\x51\x30\x6b\x17\xbd\xdb\xdc\xec\x82\x72\xdf\xe7\x17\x62\x19\x02\x60\xf1\x28\x0a\xc2\x48\x56\xcf\x4f\x77\xd6\x42\x4d\x5d\x1f\x03\x98\x02\xcc\xa0\x22\x65\x5e\x88\x40\x4c\xe5\x0f\x29\xf7\xb0\xac\x62\xaa\x1e\x1a\x72\x35\x65\xf7\x82\xf1\x84\xc2\xfe\xd7\xcf\x4e\x7b\x72\x38\x80\x6a\x09\x60\x59\x12\x53\xbb\xc8\xe1\x2c\xaa\xeb\x43\x43\x4a\x3a\x27\x55\x9b\x6c\x86\x9d\xd1\xd1\x7c\x21\xb1\xac\x77\x9d\xe7\x19\x8b\x1d\xb4\x15\xfb\x3e\xca\x68\xdc\xa9\xac\xd4\x95\x8d\xc7\x98\x1c\x61\xbf\xb8\xae\x77\x28\xc6\x75\x8d\x62\x7a\x68\x30\x29\x29\xa5\x95\xef\xa3\x58\x6d\x97\x72\x32\xc1\x8b\xf2\xa2\x5a\xc8\xd2\xe9\x06\x29\x92\x83\x58\xa7\x7a\x0c\x28\x5f\x28\xdc\x52\x50\x16\x8a\x88\x78\xbf\xfe\x0a\xd8\xe5\xd7\x5f\xbd\x11\xa5\xc2\xf7\xe3\x11\xa5\x85\xec\x9d\xef\xcb\x9f\xab\x69\x5a\x7e\x9f\xc5\x29\x57\xd3\x8c\x0a\xd9\x85\x94\x02\x92\x99\xa6\x25\xfc\x4a\xb2\x80\x97\x88\xd3\x58\xd6\x98\xd3\xd4\xf7\x47\xdd\x0c\x1c\x2f\xc3\x28\x48\xeb\xba\x5f\x1d\xc7\x4b\x1e\x1c\x1a\x92\xd2\xd1\x9c\xc8\xe2\xd4\x2c\x07\xca\x48\x4e\x0a\x8c\x83\xdb\x3c\x4d\xce\x66\xba\x57\x90\xa5\xc0\x16\x86\xe2\x76\xfd\xd0\x81\xdd\xef\x63\x9e\xe4\x81\xe6\x94\xbc\x31\xda\x8c\xbf\x89\xc5\x76\x5a\xc8\xe4\x1d\xc2\x78\x5a\xb0\x7d\x16\xaf\x19\x3a\x5f\xbd\x3c\xbf\x21\x9e\x87\x49\x5a\xbe\x65\x71\xf2\x20\x09\x2d\x93\x7c\x56\x07\x94\xfb\x3c\x98\x44\x37\x3c\xcf\xf7\x2e\x3c\x36\xa4\x33\xa4\xe3\xad\x40\xb8\xa1\x09\x68\x24\x89\x58\xa8\xd6\xf6\x4c\xe5\x8f\xe4\xbc\x5b\x0a\x26\x69\xc5\x08\x09\x2a\x9b\xc2\x43\x04\x0f\x71\x7a\xab\x71\x33\xf1\x1c\x68\xf7\xb0\x24\xd6\x4e\x02\xf6\x7d\xcd\xe7\x70\x4c\x29\xcd\xb0\xec\xe7\xab\xdd\x5e\x3c\x9c\xea\xe7\xc2\x85\x0e\xd5\xe1\xb9\xe9\xf9\xac\x21\x37\x59\x7e\x1d\x67\xaf\x6e\xe3\x2c\x70\xb1\x81\x64\x41\x24\x2f\x72\x50\xfc\x8a\x24\x5f\x53\x78\x6c\x08\xc7\x47\x48\x5c\x62\x0f\xd9\x18\x27\x05\x9d\x49\x7e\x44\xd2\x56\x7c\x90\x2d\x73\x6a\x28\xe9\xa2\xb8\xe0\x8b\x42\x01\xf2\x68\x2e\x89\xa5\x9e\x9e\xb0\x88\x48\x41\xe4\x0f\xc6\xd7\x05\x8b\x3f\x34\x2c\x2b\xd9\x99\x65\x64\xd8\x9f\x97\x30\x80\xc3\x24\xdd\xf8\xc0\x7a\xc4\xb2\xed\x9f\x24\xd0\x61\xb4\xe8\x73\x70\x68\xaf\xd9\x46\xd9\xed\xa5\xa1\x6d\x9c\x78\x25\x30\x97\x2e\x5f\x12\xb2\x28\x60\x38\xa8\xf4\x22\x10\x86\x31\xe1\x0d\x49\xf9\x71\x9b\x84\xf7\x08\xb0\x58\x4e\xe6\x41\x6a\xd6\x99\xc1\x4c\x42\x53\xbd\xae\xca\x91\xab\xee\x8e\x85\xc1\x3a\x05\x9d\x91\xf4\x78\x2e\x59\x98\x8e\xc7\x11\xb0\x79\x76\x0e\x74\x1e\x9a\x12\xd6\x10\x89\xec\x8f\x7a\x65\x1a\x28\x24\xdf\x9f\xd2\x19\xc9\x6d\xcd\x24\xa6\x23\xbe\x48\x2f\xf2\x45\x3a\x1e\xe3\x91\x40\x2c\x4c\x23\x92\xe2\x11\xa5\xb1\xef\x17\x80\xd9\x21\xcd\x6e\xd6\xa2\x47\xab\x8f\x18\xd8\x19\x89\x69\x18\x59\xb0\x80\x75\x6d\x47\x92\x5f\x14\x8b\x7c\x3c\xc6\x1a\xb7\xa5\x54\x36\x99\x47\x24\x27\x1c\x03\xb4\x43\x8b\x29\x5e\x58\xa0\xc8\x15\x50\xfc\x69\x01\xdd\xbf\x1b\x14\x4b\xce\xa8\x4a\x93\x60\x4e\xca\x6a\x2f\x4f\x6d\xc1\x43\x83\xc9\x00\xdf\x79\xf5\xb0\xbb\xce\x33\x40\x90\x1b\x1e\xaa\xb7\x69\x2a\x58\x11\x8b\xbc\x90\xd3\xdc\x4f\xc2\x44\xf3\x2d\xde\x17\x8a\x18\x9c\x7d\x0b\xec\xdf\x99\x3a\x96\x9c\xbd\x36\xdc\x26\x80\xc7\xd9\xcb\x58\xb0\xb3\xb7\xec\xe6\xd5\xfd\x5e\x23\x0a\x85\x82\x74\xc3\x1e\x90\x2f\x81\xbc\x33\x0f\xf7\x88\x33\x0f\x2d\x86\xf1\xc6\x62\xec\x45\x5e\x44\xc5\x54\xe4\x5f\xe7\x77\xac\xb8\x8c\x4b\x86\x70\x83\xe1\x30\xe7\x90\x39\x6e\xe8\x5c\x42\xae\x49\x4e\x52\xb2\x25\x1b\x72\x43\xee\x48\x45\x32\xf2\x8e\x5c\x92\x98\xbc\x22\xb7\xa4\x24\x6b\xf2\x40\xae\xa8\x57\xa6\x7f\xfc\x91\x31\x6f\x3c\x7f\x2a\x91\xa3\xec\x2c\xd9\x53\xde\x1e\x67\x3e\xd0\x19\x00\xe2\x8e\x56\x0c\x61\x72\xaf\x7e\x5e\xa8\x9f\x6f\xd5\xcf\xcb\x61\x56\x5c\x1e\x92\x04\x90\xc7\xd1\x0c\x93\x59\x43\x7e\xa3\x87\xa6\x7f\xa2\x83\x73\xe8\xef\xf2\x40\x98\xef\xc9\xd7\xe6\x60\xf8\x95\x79\xf8\xce\x9e\x44\xbf\xa7\xa7\x76\x8c\xec\xa0\x85\x2d\x7e\x51\x2c\xb8\xc2\x38\x2c\xe4\x91\xec\x02\x36\x3b\x52\x83\xc7\x64\xde\x90\xb7\xd4\x5b\x6f\xd9\xfa\x03\x4b\xea\x92\x65\x6c\x2d\x58\x52\xc7\xe5\x03\x5f\xd7\x71\x25\xf2\x4d\xbe\xae\x4a\x78\xda\x67\xf1\x43\x0d\x72\x87\x3c\x2b\xeb\x84\x6d\x58\x51\x27\x69\x19\x5f\x67\x2c\xa9\xb7\x69\x92\x30\x5e\xa7\xe5\x2e\xde\xd7\x59\x9e\xef\xeb\x5d\x95\x89\x74\x9f\xb1\x3a\xdf\x33\x5e\x17\x2c\x4e\x72\x9e\x3d\xd4\xfa\xa4\x9f\xd4\xe5\x3a\xdf\xb3\xc4\x23\xdf\x50\x2f\x5c\xad\xee\x9f\xcd\x56\x2b\xb1\x5a\x15\xab\x15\x5f\xad\x36\x91\x47\xde\x50\x0f\x2d\x83\xd5\x6a\xb5\x0a\x57\xab\x24\x9e\x6c\x5e\x4c\x5e\x47\x87\x39\xf9\xb4\xf1\xc6\xdf\x8c\xbd\x65\x0d\x9f\xde\xb7\x45\xea\x70\xb5\xba\x9b\x44\x75\xf8\x7e\x35\x9b\xac\x56\xf7\xff\xcf\x26\xc2\x63\x8f\xfc\x44\xbd\xd5\x2a\x84\x32\x4f\x91\x37\x7e\x33\xf6\x30\x5a\x06\xfa\x3d\x7c\xfa\xfe\x49\x3d\xfa\x4f\xb4\xa4\x58\xa7\x2c\x83\x8f\x90\x6e\x77\x2a\xab\x5a\xad\x56\x1f\x45\xf8\x29\xfe\xa8\x5e\x79\xfd\x0f\x2b\x4f\x7e\x59\x79\xb5\xae\x17\xd7\xba\x96\xd5\x2a\xf2\xc8\x6b\xea\x05\x6d\x83\xab\x15\x42\xe8\xbf\xaf\x1a\xd7\xfd\x2f\x08\x87\xab\x55\x14\xd5\xde\xf8\xa7\xb1\x87\x9f\xe2\x7a\xfa\x14\xaf\x56\xb2\x69\xf2\x05\x95\x80\xab\x36\x18\xfa\x66\xec\x8d\x3d\xe2\xdd\x78\x98\x3c\x71\xd3\xbd\xf7\xd0\xc7\x31\x54\xfc\x5e\x57\x1a\x61\xd3\x0a\x7e\xaa\xc6\x30\x7e\xa2\x0b\xff\x3a\x50\xf8\x29\x51\x3f\x1e\x26\x7f\x0c\x7d\x46\xe1\xe7\xe3\xff\xc8\x2e\x7e\x33\xf6\xb0\xcd\xfa\x63\xaf\x7b\xf5\xe7\x1e\x26\x3f\xbb\x89\xaf\x31\xf9\x57\xbf\xbe\x37\x63\xef\x89\x87\xc9\x97\xf4\xf0\xe6\x65\xd0\xf9\xf6\x37\x3d\xbb\x1e\x26\x97\x5f\xbf\xb8\xba\xea\x7e\x5d\xad\xa6\xed\xf7\x77\x2f\xbe\xec\x7e\x55\x9f\xea\xf0\x69\x24\x3f\xbf\x78\xf7\xee\x6d\xd0\x6b\xf7\x27\x4c\xbe\xbf\x7a\xf5\xe3\xcb\xef\xfa\x1f\x5e\x63\x72\xf9\xd5\x9b\xaf\x7b\x9d\x09\x10\x80\x37\x1c\x8f\x6a\x79\x00\xaa\xb9\xd8\xca\x7f\x13\xf9\x82\x27\x68\xbd\x4d\xb3\xa4\xce\x37\x13\x89\x6c\x35\x44\xe8\xd9\x92\x67\xa1\x3a\x4f\x92\x1a\xa1\x70\x3c\x89\x6a\x8c\x56\xab\xe4\x29\xe6\x75\x0b\x94\xfa\x83\x7e\x5f\xad\x92\x31\xae\xb1\x85\x36\x58\x7d\x2f\xf5\x30\x91\x4c\x79\x6f\xa4\x12\xd8\xdf\x8e\x3d\xfc\x44\x67\xe1\x8c\x25\xe5\x65\xce\x05\xbb\x17\xfd\xb1\xc9\xea\xd4\xda\x05\x6d\xaf\xd8\xef\xf5\x8d\xa8\x33\x35\xa2\x76\x80\xdd\x31\xa0\x65\x30\x59\xad\x12\xbc\x84\xae\x3b\x1d\x43\x4b\x1a\xbe\x9f\x44\xf5\x13\xdd\xc5\x86\xfc\x42\xcf\xbf\x7a\xf7\xcd\xd7\x4f\xce\x53\xf2\x03\x3d\x97\x1d\x4c\xf9\xbe\x12\x1a\xfb\xd4\xb2\x5f\x71\xc1\xe2\xfa\xba\x12\x22\xe7\x58\xe6\xfb\x07\x3d\x7f\xbf\x5d\x25\xf2\xf1\x9f\xf4\xfc\x7d\xf8\xfe\x10\x8d\x57\x87\x55\xf9\x74\x15\xf2\x58\xa4\xb7\xec\x6c\x75\x77\x4e\xfe\xad\x6a\xfb\x1b\x0a\x25\x22\x18\xe3\x1a\xad\xee\xc6\xb8\x5e\x4d\x4d\x02\x7e\x72\x4e\x18\xa3\xe7\xe1\xf8\x3f\xd1\x39\x11\xac\x03\x6b\x7f\x82\x6a\x90\x8b\x6b\xb0\xde\x1c\x9c\xd1\x21\x3e\xcb\x9b\xdd\x7b\x63\xa6\xb0\x35\x9a\xe3\xc9\xa7\x9f\x7c\xf2\xfc\x53\x7b\x44\xac\x6b\xc4\x2f\x66\x4b\x45\x23\xa7\x9b\x22\xdf\x5d\x6e\xe3\xe2\x32\x4f\x18\xe2\x63\xc8\x8a\x83\xc1\x8f\x9f\x7f\x3e\x9f\xd5\x9f\x7c\xf2\xec\xb3\x4f\xc9\x7c\xf6\xec\xb9\xcf\xeb\x4f\x3e\x7d\xfe\x6c\x26\x8f\xab\x05\xa3\xe7\x28\x94\x88\xef\x7e\xbe\x01\xdc\x57\xbf\x9f\x2c\x57\x09\xae\xdf\x4f\x9e\x68\x94\xa8\xbf\x4c\x56\xd5\xeb\xd7\xaf\x5f\xcb\x19\x39\xbf\x21\x69\x7f\x04\xa6\x97\x4b\x6f\x35\xf3\x28\xa5\x6c\xe9\xad\xaa\xcd\x66\x93\x78\x81\x19\xd1\x8c\x4c\xe6\x78\xec\xad\x56\x72\x90\x6b\xdd\xbd\x17\x02\x19\xca\x33\x99\x63\x2b\x9a\x44\xf3\x4f\xf1\xd8\x3b\xf3\x02\x95\xbd\x21\x39\x73\x0f\xa2\xef\xe4\x89\x36\x66\xf4\x9a\xa1\x63\xa9\xc8\x68\x06\xb2\x45\x43\x64\x7c\xdf\xdb\xa4\x2c\x4b\x4a\x26\xa0\x63\x20\xa2\xfc\x36\xde\xb1\x1e\x23\x40\x0e\x49\x5a\x04\x5e\x2b\xa8\xf3\x08\x97\xb0\xee\x65\xec\x86\xf1\xc4\x6b\xf0\x42\x14\x0f\x87\xaf\x8c\x8c\x83\x7e\xa7\x98\xd2\xfd\x14\xf6\xa8\x2c\x51\x62\xd2\x7d\x13\xa1\xfb\x6e\xa4\x45\xad\x90\x74\x1d\x8b\xf5\x56\xf6\xfc\x2b\x7a\x80\x6a\x03\xc3\xbb\x2e\xbb\xd3\xfb\xb5\x6e\x95\x11\xdd\xaa\xc0\x1d\x79\x71\x0b\x44\xcc\x61\x7e\x17\x77\xdb\x34\x63\x92\x8c\x6b\x7e\x77\x3c\x8e\xf0\xc2\xf2\xba\x92\x8e\x37\xad\xfc\xb1\x64\x8a\xc1\x26\x85\xaa\x0b\x4e\xf8\xa4\x04\xbe\x67\x4d\x36\x20\xb5\x9d\xe6\x77\x9c\x15\x2f\x0d\x6f\xb3\xa7\x6c\xd9\xca\x7c\x83\xcf\x24\xbf\x0a\x92\xd7\x30\xb2\xe7\x00\x2b\x1c\x16\x75\x3d\x12\x75\x3d\x1f\x51\xba\xf7\xfd\xcf\xd4\xcf\x1c\x5e\x5b\x06\x43\x9e\x5a\xe4\xe9\xf6\x1d\x62\x98\x30\xca\xea\xfa\x92\xbc\xc2\xa0\x11\x98\xeb\x92\xa8\xa2\xff\x9e\xb2\x7b\xb6\x96\x93\x20\xd9\x94\x94\x56\xe1\x3c\x82\x3c\x9f\x51\x59\x1b\xe8\x0f\x50\x4c\xd9\xf4\x86\x09\x2d\xfb\xfd\xe2\xe1\x4d\x82\x52\x8c\x3b\x4d\xc5\xd3\x34\xa1\x94\xa6\x36\x51\xf1\xc1\xb1\x3c\x9e\x00\xeb\x9c\x6e\xd0\x06\x44\x0b\x9b\x81\xaa\x7c\x5f\x2e\x48\x0c\xfc\xf3\xe3\xf5\xc8\x0e\x55\xe1\xb3\xc8\x7c\x37\x40\xc4\x89\xdb\xc5\xf2\x8b\x87\x77\xf1\x8d\x04\x4d\x39\x32\x02\x3d\x84\xc1\x3d\x8f\xb0\xef\x27\xdd\x9c\x97\x59\x5c\x96\x32\xaf\x5c\x95\xe1\x2f\x7f\xda\x9a\xcd\x29\x47\x43\x78\x93\x6e\x50\x32\xfd\xbd\x8c\x7d\x7f\xf4\x6d\x28\xe4\xfe\x8b\xe4\x21\xfc\xb6\xae\x47\xb7\x53\xc1\x4a\x21\xfb\xe5\xfb\x08\x16\xa2\x15\x30\x8f\x4e\xef\x2a\xb5\x72\x6b\x2a\x24\xfc\x10\x79\x1c\x95\x0b\xf8\xa3\xa9\xac\xae\xff\xb0\xf5\xe2\x03\xda\x50\xc6\xcc\xbb\xef\x3f\x30\xc4\x1c\xb9\x39\xae\x6b\x26\x8f\xef\x4c\x4e\x05\xb0\x81\x75\x8d\x50\xa9\x16\xb9\x95\xc1\x7b\x69\xe2\x61\xbc\x2c\x69\x69\x25\x1c\x05\x23\x29\xc3\x12\x0f\xf5\x33\x92\x92\x5e\x61\x4c\x72\x8a\x32\xba\x95\x9d\x30\x4c\xb0\xda\x38\xf9\x64\x82\xb3\x30\x8f\x28\x2a\x97\xde\xdf\xbc\x71\x19\x78\x01\xb4\xec\x01\x72\x1a\xdf\x33\x24\x3f\xe3\xc5\x9a\x66\xd3\xdf\xf2\x94\x23\x8f\x78\xb8\x91\x68\xe2\x68\xea\x37\x53\x10\x57\x5f\x01\xb5\xca\x8b\x17\x59\x86\xd6\x30\xe9\x16\x07\x7c\x8b\x04\x19\xcd\x70\xb3\x49\x79\x9c\x65\x0f\x87\x92\x52\x7a\x25\x57\x57\x29\x0c\x7a\x43\x6c\x9a\xc6\x9e\xd5\x84\x1d\xea\x13\xe2\x3d\x99\x7b\x58\x6f\xe3\x76\x6f\xcb\x53\xc6\xc1\x9c\x5e\x0d\x49\xb1\x5f\xe5\xc6\x6f\xcf\xdd\xfa\xbc\x0a\xeb\x8f\x3f\xbf\x9e\xae\xe3\xf5\x96\x7d\x0d\xf3\xe2\xfb\x09\xcb\x98\x60\x67\x2c\x2c\xa6\xe5\x36\xdd\x08\x84\x23\xc2\x34\xac\x50\xee\x60\x13\x89\x77\xda\x83\x4c\x78\x15\xd1\xd1\x8c\xb0\xf6\xfb\x9a\xb5\x02\xd2\xcb\xbe\x9a\xc6\x22\x6c\x85\x73\x35\x5e\x1f\xc9\x7d\xd1\xce\x97\x11\xcc\xd8\x09\x13\x0e\xb4\xf8\xbe\x38\xa5\x73\x11\x98\x08\x2a\x0f\xc2\x4e\x6f\x37\xac\x8b\x43\xf5\x91\xb2\xf6\x30\x29\x28\xef\x42\x45\x31\x99\xe0\xeb\x69\x2c\x44\xf1\x55\xcc\x93\x8c\x85\x3c\x2c\xa2\x88\x8a\xb6\xb6\x7d\xa7\x36\xe1\xfb\x4c\xd6\xe2\xfb\x73\x4b\x7f\x24\xba\x54\xef\xc2\x79\x67\xd3\x32\xaf\x8a\x35\x7b\xc3\x13\x76\x3f\x11\xee\x9b\xc4\x05\x85\xd9\xd0\x05\xe0\x59\xac\xba\xc3\x29\x9f\x4a\x42\x75\x95\x5e\x67\x29\xbf\x01\x91\xa7\x73\x68\x9b\xcc\xad\x8c\x63\x39\x0f\x26\xf3\xb6\x97\x89\x9c\xce\x43\x0f\x16\x1c\x95\x1f\xb0\x57\x8f\x91\x4c\xd9\x61\x50\xc5\x50\x2a\x9c\xb9\xdc\x32\x47\xf5\x70\x2c\x0d\x3f\x55\x9b\xee\x26\x6a\xdb\x15\x75\xed\x29\x6e\x0e\xde\xdc\xf6\x5c\x48\xbb\xf9\x93\x71\x6c\xf2\x62\x07\x0a\xaa\x25\xeb\x00\xc8\x68\xde\xe1\x13\x96\x5e\x16\x5f\xb3\x4c\xe5\x74\x9e\x9d\x32\x9d\x0a\x6c\x41\xd9\xb7\xe0\xe8\x35\x2d\x5f\x3a\x09\x75\xed\xa6\x8c\x28\x1d\x09\xdf\x8f\xe5\x16\x18\x2a\xed\xb4\x2e\xc7\xec\x7e\x73\xc6\x7d\xcb\x50\x6c\xc7\x9d\x39\x9c\x50\x6e\x53\x73\x3a\xce\x89\xfb\xa9\x23\x75\x8c\x41\x9d\x6c\xf8\x85\x1c\x93\x94\x16\x5d\x50\x4f\x27\x13\xcc\x42\x4e\x8b\x30\x8d\x24\x29\x00\x81\xc0\x08\x09\xf9\x23\x9f\x31\x6e\xe4\xff\xb6\x4b\x0f\x9d\x4d\xef\xfb\x43\x9a\xf6\x61\x8a\xe7\xfb\xac\xd9\xe4\x05\x62\x67\x29\x3f\x4b\x68\xc9\xa6\x5a\xea\x44\x41\x24\x5e\xca\xe9\xfb\xf9\x9b\xaf\xe9\x20\x3c\xc5\x3b\x56\xee\xe3\x35\xfb\xf1\xed\x1b\xc2\x29\xea\x71\x29\x92\x6e\x58\x71\x8c\x6e\xd8\x08\x73\x7f\xd1\xe4\xa6\xae\xb9\xef\x73\x0b\x99\x75\xed\xc9\xb3\x86\x3c\x76\xbc\x83\xbe\x30\x61\x6a\x3b\xee\x81\x44\xb5\xc0\x07\xf5\x5b\x0d\xf6\x56\xdc\x37\xa2\x97\xbe\x2f\x99\x93\xc2\xd9\xee\x45\xbf\x57\xc0\x69\xa0\x4b\x5a\x1c\xf5\x97\xbc\xa2\xa3\x14\x5d\x62\xb2\x87\x9a\x10\xa7\x97\xd3\x84\x6d\xe2\x2a\x13\xff\x4a\xd9\x1d\x96\x9d\x17\xf9\x7e\x44\x25\x9a\x41\x7c\x1a\x27\xc9\xab\x5b\xc6\xc5\xd7\x69\x29\x18\x67\xc5\xf2\x38\x09\x79\x15\xcf\xf2\x38\xf1\x48\xce\xc8\x68\x8e\x03\x2e\x71\x5a\xbc\xde\x42\x2e\x59\xa1\xf3\x8a\xbc\x9c\xb7\xd9\x31\x26\x9a\x04\xd3\xf5\x10\x07\x7e\x16\x77\xd4\xdf\x0c\x77\x5e\x8f\xb0\x7d\x92\xde\x7a\x18\x93\x61\x60\xe9\x53\x4d\xdf\x1f\x1d\x27\x22\x4d\x97\xcf\x0c\xe1\x38\x83\x3a\x35\x30\x37\xb2\xbb\xb1\x21\x9f\xe5\x89\x3e\xb3\xe9\xda\xb0\x43\xd4\x4b\x3d\x32\xea\x33\x16\xf6\xb3\x87\xa1\xc6\x21\x30\x3e\x59\xf7\xd0\x04\x5c\xe6\x3b\x35\x01\x72\xf4\xa3\x13\x9c\xa0\xf7\xb4\x3b\x8e\x61\x06\x8e\xfe\x53\x01\xf2\xe5\x29\x56\x50\x95\x94\x9c\xeb\x5f\x5d\xb2\x34\xa1\x57\x64\xd4\xab\x50\x6d\x8e\xa1\x54\x74\xd5\xef\xa6\x6c\x6c\x89\xae\xa7\x9b\x34\x13\xac\x98\xbe\x79\x39\xb8\x79\x0d\xe7\x22\x18\xe1\xad\x16\x7c\x70\x0e\x8f\xf9\x3c\x85\x11\x89\x6c\x83\x27\xdd\x16\x24\xa2\x4b\x37\x83\xb6\x3e\xa2\xc7\xcb\xfb\xfe\x2b\x4b\xab\xfb\x6c\x7e\xdb\x25\xbe\x0c\x79\x14\x84\x51\xd3\xe0\xe0\xd1\x51\xf1\xbf\x34\x2a\x35\xfe\x93\x08\xd2\x0e\x54\xd1\xaa\xe3\x34\x35\x01\x56\x3a\x20\xf9\x9d\xdb\x38\xab\x34\x71\xfc\xbf\x37\x25\x4a\xd5\x3b\x38\x31\xe9\x46\x92\x1a\x79\x48\xe1\x34\x3f\xd1\x41\xc0\x4c\xa6\x63\xe6\x44\x12\xe6\xd1\x22\xed\x54\x69\x80\x88\x61\xe7\xdc\x9a\xd3\x54\x1d\x59\xff\xb7\x26\x34\x7f\x0c\x2b\x66\xe6\xe3\xdd\x8b\x2f\xe9\xf0\xce\x5d\x0e\xc9\x33\xfe\x6c\xaa\x9c\xe2\xc3\xc9\x88\xe1\x00\x8e\x54\x4b\x71\x8c\xb4\x98\xd1\xe8\x0e\x9e\xe4\x89\xa3\x68\x3a\x59\xb9\x5c\x03\xef\x29\x30\x69\xf8\x60\xf8\xc1\x1c\xf4\x5b\x58\xb2\x37\xbc\x43\x6e\x80\xaf\xe7\x8e\x12\xca\xb0\x09\x16\x5e\x40\x22\xda\x9f\x21\xe7\xa8\xf9\x5f\x03\x53\xb7\xf8\x2b\x6c\xad\x5c\x4e\x1c\x44\x19\x6e\x48\x29\x07\x7e\x2b\xff\xa8\xe3\x68\x8b\xdc\xfa\x53\x08\xa7\xd1\x1e\x3e\x53\x0a\xdc\x63\x74\xc6\x39\x2b\x24\x51\xa7\xde\x45\x7c\x96\x26\xf4\x23\x6f\x7c\x35\xf6\x3e\xfa\xfc\xe2\x3c\xfe\xfc\x42\x09\x11\xdb\xe4\xc9\xaa\x58\xad\x3e\x3a\xdb\x95\x71\x96\xe5\x77\xeb\x78\x2f\xaa\x82\xd1\x8f\x3e\xfa\xfc\x22\xdf\x6b\x61\x89\xd2\x79\x40\xda\xb9\x4a\xfc\xfc\xe2\x5c\x25\x7f\xee\x91\x21\x1a\x15\x76\xab\x7b\x4f\x3f\xfa\x28\xb2\xc8\xdd\xf7\x6f\xd5\xfa\x78\xe1\xd3\xf7\x4f\x22\xda\x2a\x16\x3e\xaa\x57\xde\x0a\xe4\xd1\x83\x95\x9a\x9e\xb4\x55\xd5\xb5\xa9\xaa\x55\x61\x2c\x03\xd8\x21\xb5\x12\xea\x9e\xaa\x2b\x4d\xfe\x43\xd5\xf8\x87\x6a\xfb\x0f\xf5\x30\x41\x03\xc7\x35\xc5\xb1\x63\xdc\x3b\x60\x4b\xbe\xcc\x03\xcb\x82\x2e\xfd\x13\x27\x5a\x97\xf9\x3b\x73\x32\x30\x10\xa8\x13\x9e\xfe\xf2\x0c\x05\x5a\x4f\x35\x50\x6d\xfb\x69\xb0\x64\xfc\x37\x98\x8c\xf1\xd3\x81\xa2\xd3\xbf\x4d\xc7\xe1\xf8\x3f\xd1\x89\xa2\xab\xd5\x6a\xe3\x61\x62\xd7\xd4\xd1\x51\x49\xee\xa1\x07\xb3\xac\x07\x9e\xdb\x82\x6d\xe8\x47\x1f\x9d\x59\xce\xff\x23\xf3\xd4\x85\xd7\xc1\xef\x0a\x18\xcf\x1d\x68\x5c\x9c\x38\x66\xeb\x75\x5b\x88\xde\xc2\xc9\x7d\xec\x11\x4f\x69\xe7\x06\x96\x6f\x78\x9d\x5f\x9e\x82\x2a\x58\xd7\x64\x08\xd4\xdb\xd5\x6c\x55\x6a\x1e\x26\xcf\x40\xa2\x34\xb0\x92\x8c\xc3\x20\x07\x6a\xb2\x9f\x88\x17\x98\xb9\xf0\x30\x39\x42\x03\x76\xc6\x46\xb3\xd3\xcd\xb4\x15\xfc\xd5\x76\x86\xaa\x79\x4a\x82\x7b\x07\x04\xc8\xf4\x69\x20\xd7\x1e\x4b\xac\xb6\x8b\xc5\x7a\xcb\x4a\x93\xdf\x60\xb8\x35\x8d\xcd\xa7\xba\x8e\xa7\x77\xec\xfa\x43\x2a\xbe\xe9\xe6\x95\x1f\x76\xf9\x1f\x03\xa9\xf9\x50\xce\xb2\x97\x28\x51\x66\x0f\xfa\x12\x39\x2b\xeb\x9c\x73\xc0\x23\x90\x9f\xae\x8d\x0d\x20\xe8\xe0\xda\xb7\xb0\x1c\xc9\x2d\x0a\x23\x2b\xf5\xc8\x46\xd4\x23\xaf\x25\x54\xdf\xd2\x5b\x3b\x61\x8e\x8e\xe4\x56\xcb\xc6\x6a\xc9\xe7\x96\xb4\x1c\xca\x53\xba\x79\x84\x99\x8f\x78\xba\xce\x77\xf2\xc8\x6d\x4e\x55\xdf\xe7\x65\x2a\xbb\x8d\xc9\x83\x3c\x54\x3b\xd9\xb8\x88\x53\x5e\xe2\xe5\x90\x4c\xfc\xb3\x8e\xdc\x65\xc9\xfa\xa7\xab\x80\x91\x82\x8a\xae\xc8\x68\xe1\xe8\xe0\x8b\xba\x1e\xa1\x51\xa1\x64\xd7\xed\x09\x4e\xa6\x72\xdb\xf4\xb2\x7d\x44\x05\x0e\xd8\xa9\xae\xfb\xfe\xfc\x53\xff\xe4\x57\x30\x20\xeb\xf3\x03\xe9\x06\x09\x2d\xed\x11\xd4\xed\xa4\xe4\x8c\x84\xc3\xf5\x8c\x66\x0b\x2b\x15\x23\x2f\xa9\x58\x1e\xd5\xc3\x5c\x7d\x7e\x26\x77\xc1\x6c\xa1\x26\x69\x74\xb2\x4f\x93\x91\x38\xf5\xc9\x32\xc7\x75\x8d\xe6\xf2\x58\x3a\x74\xf8\xa6\x14\x89\x7e\xaa\xc0\xcb\xd3\x73\x20\x70\x30\xc7\x75\x3d\x4a\xc0\x4e\xf1\x25\x93\xc7\x50\x96\x28\xab\xae\xe1\x12\x20\x47\xe1\x4b\x46\xe9\x65\x5d\xf7\xba\x00\x32\xe7\x07\xb4\x27\x0c\x2f\x27\xf3\x40\x40\x1e\x71\x22\x8f\xc0\xcb\x79\x50\x2d\xbf\x47\x15\x61\x78\x22\x7f\x04\x0e\x66\xc1\xc7\x3e\x97\x65\xe7\x43\x4b\x73\x72\x4a\xad\xfd\x51\xbb\x60\xc0\xcb\x39\xaf\x31\x0d\x59\x24\x19\x1e\x01\xb6\x3e\xa3\xb4\xae\x47\x39\x6e\x41\xef\xd2\xf4\x78\x39\x0f\x52\xf9\x9c\x0f\x75\x6f\x01\x4a\x10\x4a\x6d\x49\x2d\x80\x5c\x70\xca\x16\xad\x94\xd0\x81\x9b\x78\x5a\x71\x25\xbf\xe5\x32\x97\x18\xce\x55\xba\xb9\x54\x8e\x38\x2c\x22\x4a\x69\x19\x16\x11\x2e\xc6\x63\xcb\x4a\x2e\xf7\xea\x1b\x81\x2f\x81\xca\xb6\x97\x3d\x2e\xf5\xe3\x3c\x98\x35\x98\x5c\x36\xa4\x64\x06\xc7\x0d\xeb\x10\x4b\xd9\x79\x5e\x65\x99\xfa\x23\xb0\x5b\xc4\x62\xcc\xa3\x65\x00\x8d\xd1\x11\x66\xf5\xfd\x57\x3d\x6d\x46\x59\xd7\xa3\xd2\xd5\x66\xf4\xf4\x1b\x58\x14\x0f\x1a\x6f\x58\xb4\x27\x80\xd1\xe6\x75\x3d\x80\x2a\x25\xbc\x19\x7c\xa2\xf5\x59\x6d\x82\xc5\x15\x56\x33\x74\x2c\xef\xd7\x5f\x66\x17\xa0\x80\xbb\x54\xa3\x0e\x59\x64\xcf\xd3\x72\xf8\x06\xb5\x0c\x4e\xd9\xd0\xa6\x03\x39\x11\xcc\xc9\x83\x32\xe2\x97\xb5\xc4\x42\xf4\x67\xee\xd1\xb2\x1a\x35\x74\xa4\xdd\x3d\x03\xaa\x48\x89\xb6\x7f\x53\x53\xe5\xe6\x24\xbd\x9c\x78\xa9\xec\xdc\x46\xaf\xcc\xb9\xc7\x40\x4f\x6b\xd7\xba\x2c\x02\x57\x54\x53\xd7\xa3\x57\xcb\xde\xc1\x5f\xe0\x00\x4c\xe1\x8e\x0e\x83\xb0\x9a\xc5\xb4\xdc\xb3\x75\xba\x49\x59\xb2\x2c\xd4\xa9\x30\x00\x59\xbf\x1c\x3e\x2b\xd7\xf1\x9e\x0d\xdc\x4b\x41\x6c\xec\x79\xb8\xa7\x30\x52\x45\x8a\xa2\x03\x6c\xc7\x86\xb0\xde\xd5\x03\x17\xf1\xfd\x19\xe4\x24\x67\x15\x2f\xd8\x3a\xbf\xe1\xe9\x1f\x2c\x39\x63\xf7\xfb\x82\x95\x65\x9a\xf3\xe0\xcc\x1b\xeb\x2a\x2b\x9e\xfe\x5e\xb1\xab\xbc\x18\x94\x25\xaa\x5b\x45\x12\x6f\xc0\xb6\xce\xe8\x28\x99\x26\x4c\xb0\xb5\x78\x59\xed\xb3\x74\x1d\x0b\x56\x92\x8a\x6a\xdc\x78\x25\x24\x07\x02\x9a\x03\xa5\x63\x97\xac\x88\xfc\x80\x5e\x62\x92\x99\x23\xa1\xa0\xca\xe4\x11\x03\xad\x08\x53\xb9\x0f\x0a\xca\x8d\xd1\x1f\x76\x14\x1b\x4c\x1b\x83\x23\x2e\x37\xf3\xdc\x42\x67\x05\x1a\x13\xc2\x1a\x92\xd3\x12\x26\xff\x1d\xbb\x1f\x1e\x80\xe7\x59\xc4\x67\xa0\x1f\x10\x94\x52\xe2\x52\x4a\xd3\xba\xfe\x4c\xfd\xcc\xe1\x55\x1d\x24\x8f\xcc\x46\xe1\x7a\x0e\x58\x9c\x70\x8b\x5e\x3b\x89\x60\xa5\xcb\x28\x9b\x82\x75\x09\xb0\x78\x0b\xb6\x90\x09\xae\x3e\x84\x8f\x69\x2e\x8f\x95\x46\x9f\xfb\x5c\x35\xfd\xb1\xab\xaf\x55\x3d\xfd\x97\x84\x16\x95\xaf\x9d\x37\x10\x40\x40\x1d\xa2\x15\x05\x35\x04\x5d\x2b\xb9\xb0\xc2\x32\x25\x3d\x38\x5a\xb2\xe0\x93\x19\x51\x9c\xf6\xf7\x25\xab\x92\x3c\xc8\x18\x01\xb4\x14\x7c\x49\xda\xed\x11\x1c\x1a\x22\xcf\xdc\xf2\xb7\x60\x19\xd8\xa3\x04\x07\xef\x73\x2f\x38\x36\x44\x50\xd7\x27\x46\xb3\x86\x78\x67\x03\xdf\x1b\xe2\x8d\x6d\x72\xc1\x6e\xd3\xbc\x2a\xf5\xf0\x3b\x65\xff\x73\x2a\x53\xd3\x90\x7d\xc1\x5e\x83\x48\x2b\x38\x80\x5d\xd3\x90\x04\x2e\x9c\x47\x54\xfe\xe9\x89\xb7\x08\x0b\x9f\x47\x14\xc9\xbf\x75\xcd\xc2\x8f\xe1\xef\x27\x51\x5d\xbb\x7b\x4a\x67\x95\x87\x48\x00\xc2\x67\x4a\x9f\xf0\x3c\xa2\x9e\xdc\x1a\xe1\xf3\x08\xf4\x8d\xa4\xb5\x16\xf9\x18\x37\xda\x64\xea\xd1\xbe\x74\x70\x0c\xf1\xb8\xd8\xaa\x06\xe6\x91\xad\xe9\x39\x5e\xea\xde\x99\x1d\x8d\x58\x38\x8b\x64\xc7\x3f\x8e\xe8\x18\xc9\x9f\xa5\xec\xb2\x7c\xfc\x34\xaa\xeb\x39\x0e\x9e\x3d\x45\x1e\xbb\x65\x5c\x55\xf6\x1c\xee\x53\x25\x89\x79\xc3\xb2\xec\x27\xaa\xec\xff\x13\x8d\x59\xf8\xff\x1e\x65\x08\xe4\x8f\xef\xf7\x5b\x6c\x8c\x7d\xd8\xd0\xd6\x19\xc9\xe6\x7d\x5f\xce\x8e\x81\xb5\x2f\xa7\x30\x07\x8a\x3c\x41\x1d\x4b\xb9\x13\x03\x18\xd0\x52\xe6\xa4\xdd\x29\x0f\xb8\xef\xff\xac\xb2\x73\x49\xde\x04\xdd\x22\x2e\x09\x8d\x7a\xe1\xe6\xbe\x20\xf2\xb0\x47\x8c\x6a\x73\x22\xf0\xc4\x3c\x63\x58\x98\x99\xac\x77\xd6\xce\xa1\x3c\xb4\xcb\xc6\xb8\x93\xe2\xae\xd6\x73\x8c\x1b\x09\xd0\x0a\x84\xde\xbd\xf8\x72\xe0\x22\x4c\x5f\x2e\x3a\xa8\x00\xd4\xe2\xac\xe5\xd1\x3d\x97\xd1\x6c\xf0\x86\x64\xab\x4f\x94\x68\x70\x58\xb7\xa8\xe5\xc4\xca\xde\xef\xb8\x5f\xbb\x90\x01\x7b\xe0\xda\x5a\x89\x8e\x95\x17\x7a\x6f\xcd\x12\xd9\xd8\x53\xd6\x6b\xf5\x13\x0c\xc2\xc7\x1d\x62\x64\xf0\xe6\x26\xac\xc1\x00\x5e\x5b\xbb\xa6\x1b\xf6\xa5\xae\xff\x5c\x18\xdc\x17\x04\x6b\xa5\x84\x87\x61\xaf\x35\xb8\x21\xdd\xbd\x0b\xd2\xdb\x47\x74\xb1\x9a\x25\x90\xfc\x16\x5e\xf4\xcc\xee\xe5\xb1\x4e\x9e\x7d\x02\x79\xf0\x41\x62\x2c\xf1\xba\xa7\x92\x96\x92\x8e\xa4\x81\xc9\xb1\x14\x23\x78\x7d\xaf\x5f\x53\xdf\x87\x7b\x7d\x16\xd2\x52\x1c\x78\x4f\xdb\x8f\x93\xf9\x45\xf7\xdb\x93\xf6\x9b\x36\x56\x46\x93\xd4\x40\xa3\x6a\xea\x3f\x3a\xcb\x64\x7e\x81\x24\xc2\x68\x4d\x1e\xbe\x90\x38\x11\xec\x31\x70\xa7\xd2\x5a\x95\x00\xa0\x07\x8c\x2f\x2c\xac\x9a\xba\xc7\x73\xa8\x7d\xec\x4d\x3c\x80\xde\x1e\xb6\xd9\x12\xc9\xae\xdc\x90\x5b\x35\x5d\x0f\x14\x90\xcb\x88\xd2\xad\x03\xf5\x64\x47\xbd\x2c\x2e\x85\x9b\x3e\xf9\x18\x93\x7b\xea\x69\xab\x4d\x00\x67\x33\xbb\x92\xe0\xdd\xa8\xf9\xb9\x1d\xb8\x12\x3c\x1a\xb9\xa7\x85\xe6\xf4\x05\x01\x63\x99\x45\x1f\x46\x94\xee\x96\x9e\x43\xf1\xbc\x01\x22\xb0\xee\x9e\x42\x36\xf4\xfe\xf4\x66\x21\x7b\x3a\xe2\xbe\x3f\xba\x27\x09\x1d\xcd\x25\xe9\x5e\x03\x85\x7e\x30\xec\x44\x86\x0f\xb1\x3d\x58\xc4\x34\x0e\x33\x10\xd1\xdf\x2f\xe3\xd3\xdb\x6f\x13\xc8\x91\xc7\x7d\x7e\x78\x34\x5f\x54\x34\xa3\x5e\xce\x33\xb8\x12\xba\xf5\xfd\x51\xe5\xfb\x9d\xe1\x34\x76\xfb\xa7\x1b\x54\xd1\x70\xb7\x5c\x3b\x14\x3f\x58\x4f\xe5\xf4\xc3\x73\x44\x76\xbe\xbf\xc7\x87\x84\xa2\x92\xa2\x82\xa2\x94\xa2\x9c\xa2\x98\xae\x71\x78\x15\xd5\x35\x8a\xc3\xab\x88\x1e\x1a\x8c\xc3\x58\xb3\x61\x6f\x5e\xca\xf4\xdc\x7d\x57\x19\xb6\x51\x5d\x87\x11\x96\x78\x90\xd2\x0f\xbe\x5f\x84\xf3\x48\xf2\x97\xe1\xb3\x88\xc4\xb4\xf4\xfd\xb5\x63\xd9\x17\x96\x91\x9d\x8e\xf1\xb8\xf4\xfd\xd8\xf7\xe5\xb4\xd4\x35\x4a\x68\x49\x67\xb8\xae\xab\xe9\x3e\xdf\x23\xb0\x57\xeb\xce\x84\xef\x8f\xc7\x89\xef\xc7\x4a\x86\x9f\x86\xdb\x88\x86\x1f\x48\x49\x92\x68\xa1\x2e\xf6\x58\xce\x65\xef\xfb\x50\x9d\x3b\x32\xf6\x7f\x69\x64\x04\xac\x21\x12\xfc\xd7\x47\xf1\x5f\xae\xb7\x1e\x26\x0c\x42\xf5\x3e\xfe\x1f\x7a\x2e\xa7\x26\x89\x30\x51\xb3\xd5\xb9\xc7\x84\x92\x09\xbd\x95\x4d\xdf\xd4\x75\xf2\xf7\x1b\x4a\x67\xbe\x3f\xbb\xa0\xc9\xf9\x4d\xd3\x0c\x10\x5d\x92\x1b\xb2\x1b\xd3\xeb\xe9\x1e\x18\xb5\x32\x64\x51\x5d\x5f\x4f\x4b\x26\x14\x2f\x54\x86\xbd\x91\xb9\x2c\x84\x57\x71\x6d\xa3\xc0\x92\x33\x55\x81\xe2\xf2\xed\x8d\xbc\xf0\x2a\x5a\xc6\x28\xc7\xc1\xfc\x22\x36\x76\x9d\x48\xd0\x90\x11\x46\x3c\x8f\xe4\x11\x71\xdb\xea\x5d\xec\x40\x7d\x53\xba\xe5\x23\x86\x1c\xec\x51\xf3\x8d\xef\x11\x23\x45\x98\x46\xd8\x1a\x6f\xc0\x5b\x83\x87\xe8\xa9\xac\x4c\x12\xf7\x06\x07\xb1\xe4\x0b\xd5\xcc\x04\x07\x9e\x8b\x20\x3b\x56\xb5\x68\x2d\x55\x18\x91\x92\x6e\x10\xeb\x5b\xa2\xd9\xc9\x28\xe5\x64\xf4\x46\xd0\xb1\x35\xa5\xa5\x39\xf6\x17\x24\x84\x25\x66\xdd\xd1\xc4\x93\x09\x46\x29\xcd\xc3\x38\x52\x2c\x4a\xac\x86\x13\x47\x34\xc5\xdd\xc1\x74\xee\x91\x15\xc0\xcb\x90\x12\x15\x5a\xaa\x40\x52\x4c\x20\x11\x5e\x47\xa9\x82\xe9\xa6\xc1\x64\x1b\x97\x9d\x31\x3e\x66\x57\x64\x0e\xec\xcc\x9e\xd3\x1b\x4c\xcc\x31\xfd\x44\x2d\x82\x8a\x3e\x43\x7c\x5c\xb1\x24\x71\x9d\x73\x4e\x5d\xcb\x03\x4c\x4b\xdd\x04\xf4\x35\x8b\xf9\x4d\xa7\x99\x76\xc4\xff\xd2\xec\x1f\x70\x05\xa7\x20\x16\xca\x9f\x79\x63\x8e\x09\xa7\xfc\x51\xce\x8c\x1c\xeb\xd7\x92\x1c\xa4\x92\x54\x1e\xcf\xa1\xa6\x3e\x63\x72\xbf\xcb\x02\xf9\x41\x76\xa0\xff\x4d\xa5\x63\x73\x19\xbb\x7f\x27\x0b\x3b\xbe\x01\xec\xa0\x39\x50\xe9\x46\x81\x02\x9c\xfa\x1c\x41\x55\xdf\xb4\x0e\xb7\x62\xd0\x06\x13\x11\x17\xfd\x3b\xfe\x8a\xfd\xe1\xd3\x2c\x5f\xc7\x4a\x28\xdb\x3e\xcb\x7d\xb8\xed\x28\xd6\x8d\x45\x3e\xb4\x91\x26\x0d\x29\xf2\x7c\xd0\x67\x00\x93\x38\xaf\x21\x70\xfb\xe9\xd4\xf7\xcb\x69\xbc\x96\x67\xbd\xd6\xe6\x67\x74\x29\x9b\x7c\x0d\x57\xa6\xea\xf6\x19\x49\xe6\x72\x34\x42\xca\xe8\x4d\xce\xe2\xb6\x60\x9b\xba\xfe\x0f\x9b\x8a\xf8\x1a\xac\x02\xe1\x4a\x38\xe8\x20\x82\x1b\x86\x46\x73\x4c\x8c\x4e\x02\xde\x67\x98\x68\x05\xd7\x20\x33\xfe\xa8\x1d\x9e\x63\x86\x27\x7b\xc1\xa6\xe6\xb6\x57\xed\x29\x05\x93\xf3\xc9\xa8\x20\x1b\x62\x9e\x86\x19\x75\xd7\xfa\xae\x63\x4a\x67\x8a\xc1\xa0\x88\x36\xe0\x6f\x6b\x65\xbb\xbd\x78\xe8\x54\xf9\x97\x4e\xfe\xa9\xc4\x47\x06\x24\x2e\x3e\x1d\xba\xc9\xab\xfa\x30\xd0\xdb\x91\xa5\x09\x53\x68\x1d\x14\xd3\x5b\x16\x27\xac\x18\x1a\xdb\x3f\xf4\xf9\xcc\xce\x29\x6e\x08\x4c\xe0\x50\xe6\x1f\x06\x32\x2b\x3b\xc7\xff\xc3\x65\x72\xac\x25\x0d\xd0\xb8\x06\x94\x0d\x81\xcb\x3b\xc7\x9b\xf9\xaf\x1b\x7c\x7a\xb2\x86\xb6\x7e\xdf\x47\xea\xb8\x80\xc4\x91\x1d\x36\xb0\xbe\x70\x73\xdb\x94\xe9\x6f\x73\xe3\x16\xe2\xd6\x41\x62\x66\x92\xc2\x59\x04\x38\xae\xf7\xd9\x11\x7a\x86\x62\x32\x97\x79\xd8\xef\xfd\x1c\x2d\xee\x0f\xf9\xc5\x6c\xc9\xc7\x22\xe0\x90\xf3\x96\xf1\xe3\xda\x9c\x6b\x90\x0b\x7e\x21\x16\x7c\x4c\x9f\x61\xd6\xb7\x95\x60\x0d\x06\x57\x11\x8f\x14\x9f\xff\x49\xf1\xec\x68\x28\xdd\x6b\xc5\xa6\xaf\xe2\x82\x2f\x45\xc0\x17\xb3\x0b\x3a\x99\x14\x0b\x53\x59\xd1\xa9\xec\xe6\x2f\x56\xc6\x17\xe3\x71\x71\x21\x86\x6b\x69\x1a\x6c\xa1\x9c\x8b\x2d\x75\x60\xfe\x77\x72\x28\xe2\x24\xcd\x83\xd1\x4c\xe1\x90\xeb\xfc\x5e\x3e\x6f\x52\xf0\xbe\x43\xf6\x71\x59\xde\xe5\x45\x22\x9f\xd3\x5d\x7c\x03\x2e\x79\xb0\xcb\x48\xd1\x04\x0c\x54\x8c\x51\xe7\xa1\xac\xae\x77\xa9\x90\xf9\x0b\x56\x32\x71\x9c\x7f\xab\xf2\x1b\x5b\xd2\x1d\x43\xf8\xd0\x9a\x96\xde\x33\xb3\xef\xd5\xbe\x98\x91\xce\x5d\x17\xcf\x5b\x88\x0b\xbe\x10\xe3\x31\x2e\xc6\xe0\xcf\x41\x09\x7f\x5b\x5b\x17\x5b\xd3\x35\x43\x25\xb1\xfc\x53\x05\x26\xc0\x05\xc9\x34\xf2\x20\x6b\x9a\xd5\x75\x45\x36\xb0\xa1\x1c\x21\x1b\xa5\x74\x4d\xf6\xd4\x51\x7a\x68\xf4\xb3\xec\xaf\x82\xbe\x75\x43\x59\x58\x45\x86\xdf\x67\x8e\xd6\x70\x63\xc4\x8e\xa5\x2e\xd1\x52\xab\xc7\x0e\x7c\x92\xf7\xdd\x47\xca\xf4\xfb\xa8\x8d\x81\x46\x7c\xdf\xd4\x6f\xb5\x83\xae\x70\xf3\xb1\xfe\x81\x3e\x09\xe5\x94\x29\x16\x9d\x59\x16\x9d\xf5\x58\x74\xd6\x65\xd1\x49\xe6\xfb\xd9\x23\x08\x04\xab\x46\xeb\x9a\x2d\xcc\xb5\x18\x54\xd0\x34\x5c\xab\xa3\x95\x7b\x22\xa1\xce\xb5\xa0\x38\x7c\x26\x59\xd6\x67\x91\xba\x11\x13\xae\x23\x1a\x63\x99\x76\x3c\xc0\x96\xee\xdb\xf5\xbe\x63\xa8\x95\x81\xcc\x2f\xd2\xa1\x1b\x56\x76\xaa\x69\x7a\x6c\xec\x0f\x8a\xb9\xb0\x88\x7a\x8d\x39\x74\x24\x48\x25\xbe\xb2\x2d\xbe\x63\xc8\xba\x49\x69\x61\x16\x96\x50\xb2\xc9\x33\x52\xb5\xa0\x9b\x51\x75\x27\x5f\x58\x9f\x25\x30\xef\x25\xf0\xb8\xf2\x18\xce\x51\x0e\xf5\xc8\xa3\x92\xda\xc3\x39\xcc\xb3\xba\xdf\x8d\x4a\xec\xba\x00\xb1\x5d\xb8\x64\x28\x21\x5b\x72\x43\x6e\xc9\x03\x69\x49\xcf\xad\xef\x8f\x6e\xc3\xab\xc8\xf7\xd1\x2d\xbd\x64\xe8\x16\x63\xf2\xe0\xfb\xa3\x07\x95\xf6\x20\xd3\x1e\xc0\x3f\xc3\x63\xac\x3a\x89\x95\x8d\x56\x25\xff\x64\xd4\xfa\x5b\x58\x53\x09\x3d\x27\x71\xd2\x0c\xdc\x95\x59\x67\x0c\x29\x38\x63\x00\x6d\x9f\x08\x8b\xc8\x15\x41\x35\x68\x5b\xd7\xde\x53\x8f\xb4\xf6\x6b\x60\x7d\xc9\xe1\x64\xb0\xa1\xa3\xa4\xae\x47\xcc\xf7\xb7\xcb\x75\xf0\x8e\xa1\xb5\x3c\x2e\x43\x0f\xc9\x9e\xde\x2c\x1f\x24\xc8\x2e\x93\x20\xab\xeb\x5b\xf0\xb6\x22\x82\x8d\x84\x9c\x1b\xdf\xbf\x41\x1b\xb2\x57\x39\x6f\xf1\x21\xa5\xef\x18\xda\x93\x0a\x93\x5b\x94\x92\x30\x52\x1f\xf2\x3e\x0c\xe4\xf2\xe0\x11\xd3\x34\xcc\x61\x51\xf6\x61\x15\xe6\x91\x3c\x7b\x6c\xf4\x53\x8c\x71\x23\x99\x0d\x25\x26\xa9\xeb\xc4\xc8\x4b\xe0\x5c\x94\xd3\xfd\x60\x7d\x7b\x55\x5f\xaa\xd6\x71\x13\xe6\xb2\xa2\xc5\x03\x50\x54\xb2\x87\x63\x15\x29\x70\xf3\x27\xc5\xe5\x69\x21\xa5\x0f\xcb\xef\xe1\x2a\x5a\x50\xea\x4e\xb2\x30\x55\xa7\xa3\x54\x75\x4f\xed\xfc\x3d\x0c\x58\x92\xe2\xe5\xde\x28\x7a\x32\x62\xea\xc7\xc1\x1e\x93\x87\xa5\xee\x81\x20\x7b\x52\xe0\xc0\xde\x77\x24\xfb\x8e\xa9\xff\xab\x0e\x3e\x4e\x89\x36\x83\xb7\xb7\x09\xe8\xf5\xd4\x68\x35\x42\x10\x24\x4b\x7e\x20\x22\x31\xcd\xe5\x09\xdb\x7e\xf2\xce\x3c\xb9\x25\xf2\xe5\x3c\x90\xdb\x62\xf0\x42\x27\xb0\xcd\x69\x43\x62\x22\x39\xda\x6c\x38\xd3\x64\x7e\xf1\x3d\x4a\xc1\x0b\x96\xca\xb7\xa6\xe1\xf0\x0e\x1f\xe5\x72\x67\xd5\xb5\x18\x51\x7a\x27\xb7\x15\x4a\xa9\xc0\x2d\xa0\x55\x3a\x7b\x90\x99\x0d\x6f\xe0\x32\x55\x27\xc6\xa2\x89\x16\xe5\x45\x61\x1c\x0c\x89\xee\x50\x4b\x3d\x54\xbc\xa6\xe1\x35\x43\x77\x0c\xad\x31\x11\x38\x6a\x31\x9e\x2c\xa0\x04\xe5\x4e\x76\x73\x51\x0c\xb4\x6c\x32\x55\x2b\xb2\x31\x0e\xaf\x22\xe3\x16\x66\x3c\x2e\x5d\xff\x0c\x9d\x76\xb9\x69\xb7\xe3\xdc\xe5\x92\xa1\xf9\x45\xe9\xfb\xaa\x1b\xf0\x28\x29\xa9\x15\x60\x96\x93\x39\xd6\x2e\x06\xd1\x41\xa9\x4b\xbd\x33\xa5\xc4\x28\x27\xcf\x54\x95\x4b\xef\xa9\x17\x78\x5e\xe3\x38\x0d\x32\xf7\xcc\x04\x29\x2f\xb8\xef\xbf\x6a\xab\x2c\xe5\x84\x11\x7e\x51\xa8\x54\x6a\xd2\x6d\x2a\x10\x72\xdc\xac\xf5\x2d\x33\xab\x61\x84\x1e\x9a\x97\x1d\x73\x3c\xbd\x99\xd9\x2a\x5b\x06\xa5\x23\x38\x01\x49\xfd\x8e\x91\x2d\x2d\x25\xbd\xf9\xc0\x78\xfa\xc7\xe0\x0d\x6b\xd2\x15\x9d\xde\x1b\xb1\x7f\xba\x41\x99\xb5\x4c\x5d\xce\x82\xcc\x6a\x53\x17\x31\x65\x06\xd7\x5d\x4f\xad\x8e\xcc\x48\x24\xd4\xba\x80\x6f\x15\x89\xaa\x51\x41\x7f\x55\x37\x53\x63\xc9\xf8\x22\x70\xd3\x44\x63\x5d\x9b\xa4\x6f\x66\xa7\xd5\x75\x6c\xed\xa7\x24\x92\x90\x93\x43\x47\x73\x82\x0a\xfa\x87\xad\x01\xee\x79\xd8\x7b\x76\x44\x23\x0a\xbd\x4a\x9c\x80\x93\x44\xa8\xd4\x59\x95\x33\x30\x2f\x6c\x1b\xb5\x4a\x1d\x65\x02\x2d\x3b\x8f\x65\x3f\xbf\x0c\xf3\xc8\xe9\xaa\xc4\x63\x6a\x00\xf2\x09\x15\xd0\xfd\x3f\x6d\x3c\x27\x1a\x48\x83\xe2\x44\xa3\x60\xd4\xc2\xb5\x87\x22\x3b\xc3\x46\x18\x16\xc4\xcb\x56\x3d\x86\x83\x7b\xc4\x48\x89\xed\xdc\x37\x64\x43\x4b\x65\x24\x94\x66\xc3\xeb\x29\x89\xdb\x8e\xdc\xcb\x75\x55\x98\x36\x94\x18\xe6\x85\xb3\xae\xa3\x18\x1f\x94\x3a\x67\x8b\xc0\xed\x50\x4b\x81\xb4\xc9\x8b\xc2\xa6\xaf\x18\x08\xc6\x60\xb7\x2d\x53\x73\x7d\x37\xc8\xcd\xd3\x02\xc5\xf4\x05\x62\x04\xdd\xd2\x9c\xec\xe8\xec\x02\x3d\xd0\xd4\x48\x7e\xc8\x3d\x9d\x5d\xdc\xb6\xcc\x68\x9f\x70\x4a\x2e\x40\x73\x00\x12\xf4\xe8\x8c\x64\xd4\x9b\x81\x54\xde\xf7\xc3\x88\x6c\x64\xbf\xf7\xf4\x8e\x24\x92\x80\xde\xfb\x7e\x6b\xad\x8e\x24\x15\x4c\x31\xd9\xd2\x0f\x63\xaa\xce\x5a\xfb\xe5\x3c\xe8\xf8\xf2\xaa\xeb\xe9\x9c\xdc\xd0\xc4\x0c\x4c\xc2\x64\xea\xfb\xe8\x8e\x6a\x5b\xa7\xba\x4e\xf1\x22\x1b\x81\xe6\x41\x7b\x00\xca\x69\x12\x66\x11\x5e\x64\xe3\x31\x10\xab\x7b\xdf\xcf\xf1\x21\xa6\x33\x22\xea\x3a\xef\x1b\x47\x5d\xd6\x35\x7a\x27\xf9\x0e\x4e\x47\xaf\x8c\xb9\x40\x49\x6f\xc3\x58\x9b\xe7\x97\x28\x97\x05\x2f\xe5\xe6\x3f\x14\x86\x4d\xd1\x02\x6c\xd9\x97\x0f\x74\x8b\x9b\x9d\xef\x23\x94\xd3\x51\x29\x1b\xf3\xfd\x6a\x32\x21\xcc\xf7\xd7\x26\x3b\x10\xd1\x6a\x4c\x33\xb2\xf3\x7d\xd9\xdd\x0a\x7a\x64\x9b\x7b\x50\xcd\x95\x68\x4d\x36\x8a\x6f\xb6\x44\x77\x76\x51\x69\xd1\x75\x36\x99\xe0\x35\x08\xad\x37\x4a\x74\x2d\x7f\xe8\xef\xca\x3c\xa5\xc0\x78\xb1\x91\x34\x70\x83\x1b\x43\xd8\x0a\xb2\xc1\x24\xf5\x7d\xc9\x4f\xcc\x2e\x36\xd6\x38\x71\x7e\x51\x8d\x1f\xec\x5b\xc7\x6e\x03\x15\x16\x51\xe9\xb1\x91\x3b\xba\xc7\x64\xdd\x90\xdd\x52\x32\x8d\x38\x28\x30\x98\x43\x6b\x63\x25\xd6\x58\x0e\x8d\xdc\xb4\x86\x03\x47\x80\x72\x74\xf1\x9e\x0e\x3b\x5e\x65\x64\x4d\x47\x85\xef\x6f\x11\xa3\x99\x6d\xa6\xae\xd5\x85\x00\x73\x03\x5f\xf2\xf5\x6b\xb3\x15\xe5\x2c\x3d\xbb\x40\x39\x5d\x4b\x36\x7b\xed\xa8\x76\x71\x6b\xe5\xea\xbd\x79\x29\x71\x3f\x8a\x69\x1e\xce\x22\xac\xcf\xf8\x9f\xf5\xae\xa9\xbe\x92\x00\x6a\x29\x4f\x0e\x4a\x78\xa0\x3c\xea\xde\xbd\xa0\xc8\xde\x3e\x41\xd6\x9e\xd5\xc5\x53\x5a\xf4\x29\xb0\x51\x44\x38\xb7\xf2\x33\x50\xd8\x75\x8c\x1c\x49\x4b\x45\x72\x83\x90\xd4\xe9\xce\x0c\xae\x49\xe9\x97\x53\xd7\x43\x89\x96\xb0\xe0\xe5\x2c\xc8\x8f\x65\xe2\xb2\x9f\x72\x88\x69\x44\x9c\x81\x94\x34\xee\x50\x50\x49\xaa\x2b\xaa\x86\xa2\xf9\xf1\x82\x56\x8f\x8e\xc8\x5c\x5f\xcf\x0d\xc3\xa3\xae\xb1\x8b\xee\x35\x76\xa1\xaf\xc5\xe7\x86\x05\x4b\xc9\x1c\x93\x11\x62\x56\x7e\x0f\x54\x32\x6f\x9d\x15\xb4\xd7\xc8\x0b\x4c\xb8\xd1\x0b\x69\xa0\x42\x59\x5d\x6f\x10\x23\x6b\x8c\x51\x01\xf6\x55\x84\x93\x91\xa8\x6b\xd3\x9b\x53\xbd\x20\xbc\x21\xae\x19\x11\xbd\x32\xf7\x9e\x3d\x6c\x8c\x88\xb4\x59\x2e\x5c\xb5\xba\x22\xc7\xa6\x48\x74\x34\xca\xc8\x3b\x84\x49\xd7\x56\xf3\xc4\x25\xb3\xf9\x23\x86\xaf\x8f\x5c\x02\x1f\xb0\x98\xb7\x47\xf0\x21\xc3\xf9\xbf\x29\x2b\x79\x8f\x78\x7f\x53\xb2\xaa\x56\x4c\xd8\x13\x52\xc9\xfc\x92\x62\xd6\xf5\x46\x8b\xac\x6a\x10\xb2\x6e\x59\x7a\xb3\x15\xf5\x5d\x9a\x88\xad\x47\xfa\x7c\xa4\x22\x6a\xc3\xf7\xd2\x04\xf1\x8c\xd2\xb7\x27\xef\x5a\xce\x83\x67\xb8\x77\x17\xf1\xc8\x16\x7b\x70\x5c\x20\x98\x3b\x87\x5b\x25\xce\x48\xba\x46\xf8\xb0\x1f\xd4\x6d\x0b\xef\x4f\x06\xad\xb2\xda\x51\xeb\x92\x83\x83\xf4\xfd\x3f\x97\x0a\xb6\x13\x61\x6e\xa4\x82\x1d\xd5\xa9\x25\xd3\x7e\x75\x7b\x7d\x6a\x6d\xe9\x75\xb7\xde\x1e\x75\x08\xb8\xf7\x85\x3b\xf7\x4a\x50\x1c\x8a\x68\xd9\x9b\xea\xff\xc9\x42\x10\x93\x92\x35\xe8\x12\x2f\xae\x60\xcb\xd3\x04\xfc\x69\xee\x0b\x9a\xb4\x76\x5e\x3a\x29\xf4\x02\x4f\xf9\xe7\xdc\x17\x96\x25\xbd\x72\x2d\xfb\xcc\x0b\x4d\x9c\x54\x72\xa5\x5c\x4e\x27\xc6\x7e\x8e\x5c\xa9\x6b\xcd\x2f\xf3\x35\x4d\xd4\x23\xb9\x6a\x6d\x3d\x13\xfb\x28\xdb\x05\xe3\x45\x6b\xff\x9a\xe8\x04\x30\xd1\xdc\xd2\xe1\xa3\x0e\xa8\xe6\xac\x75\x25\x5f\xb4\xda\x93\x50\x48\x84\xf6\xd9\xa8\xa3\x35\x39\x92\x05\x01\x14\xa4\xbe\x7f\x05\x37\xa8\x4a\xc9\xc4\xeb\xd3\x85\xf6\x69\x68\xe9\x60\xd1\x90\x77\x27\xfd\xcb\x85\xd1\x80\x74\xbe\xef\x0c\x81\x29\xa7\xab\xdc\xd4\xec\x18\xdb\x7d\x30\x53\x0d\x98\xb7\x83\xe8\x5b\x79\xe1\x8b\xae\xeb\xbc\xbf\x68\x15\xd4\x73\x02\x24\xfb\xfb\x2d\x3d\x7f\x7f\x81\xc2\x78\xf2\x47\x14\xbe\x5f\x9d\xaf\x66\x9f\x07\xe0\x68\x4e\xac\x8a\x15\x5f\x6d\xa2\xa7\x38\xec\xbe\xaf\xce\x97\x9f\xa3\x65\x70\xb1\x3a\x5f\xcd\x3f\xaf\xf1\x93\xf3\xb4\xed\xd5\x4b\xa4\x3d\xea\x98\x83\x0d\xe2\x78\xa9\xdd\x09\xb3\x41\x5f\xc2\xa3\x51\xc7\xff\xf2\x88\xd2\xa2\xc1\x81\x23\x08\x19\x28\xdd\x39\x29\x73\x5d\xe4\xc8\x01\x0f\x7f\xac\xe8\x64\x7e\x91\xb6\xfe\x39\x75\x15\x57\xfa\xc8\x20\xd3\x48\x01\x4e\xb8\xe1\xfd\x04\xb8\x89\x70\xd6\xfa\x09\xf5\x7d\xc4\xa8\x17\xf0\x5c\x20\x30\x9a\xc2\x1e\x26\xca\xe1\x85\xe5\xb0\x3a\xf7\xe1\x97\x6a\xdb\xf5\x0d\xb8\x51\x41\x18\x5e\x86\x45\x14\x84\x51\xd0\xcd\x82\x18\x31\x8e\x99\x87\xe6\xa2\x0b\x60\xe0\x9e\xd9\xf1\x6b\x8c\x0e\x60\x7c\x39\x7c\x9b\xdf\xf5\xd8\x9c\xc2\xdb\xc2\x31\x51\x6d\x8d\xb3\xec\xa1\xb1\xe7\x2e\x5a\x6e\x17\x3d\x73\x8e\x66\x03\x9c\xca\xd2\xd9\x42\x5c\x14\x20\xa8\x4e\x37\xa8\xdd\xec\x28\x0d\x45\x44\xc0\xcb\x78\x2b\xcd\xc4\x4a\x7e\xce\x69\xaf\x81\x30\xc2\xc4\xad\x49\xcd\x0b\x62\x04\x2a\x69\x05\x69\xf3\x8b\x62\xe9\xa2\x25\xc4\x71\xc0\xad\x95\xde\x90\xd1\x5a\xb7\x9d\x97\xda\xb5\x38\xb0\x93\xa3\x39\x06\x9f\xbf\x83\x3a\xad\x47\x0b\x82\xaf\xb1\x74\x48\x23\x3a\x1a\xe9\x9c\xc7\x66\x72\xbe\xff\xc1\x72\x71\x72\x42\x03\xdb\x8b\x56\xdf\x0e\xc8\xef\x37\xf2\xbb\xf2\xe0\xb6\x2a\x9f\xa2\x8b\x70\x75\xb7\xfa\x29\x1a\x7f\x8e\xc3\xf7\x9f\x47\x4f\xeb\xbf\x39\x4e\xdc\x16\xc8\xfa\xb5\x1f\x06\x60\x92\x02\x79\xe9\x2c\xab\x65\xa8\x7f\x1b\xe8\xa3\xe6\x78\x0b\xea\x5d\x28\x99\xc9\x2c\xf2\x7d\xef\x73\xf5\xdc\xfa\x35\x8b\x7c\xff\xf9\x85\x95\x8d\x2d\x43\x25\xe4\x01\x6b\x84\x28\xf8\x5d\x1d\xc3\xc1\xc9\xf1\xa8\x08\x65\x66\x63\xee\x2c\x99\x38\x31\x55\x7e\xee\x97\xe0\xa4\x02\xeb\x85\xc6\xc1\x91\x8f\x6f\x61\xbf\x81\xaf\x18\xe3\x11\x4b\x50\x71\x96\xf2\x52\xc4\x7c\x0d\xce\x5a\x97\x72\x93\x06\x92\xf2\xb4\xce\xe8\xc9\x95\x64\x0d\x4b\x26\xd9\x0d\x28\x49\xb4\xef\x62\xbd\x33\x8f\x6f\xef\x04\xaf\x60\x55\xc9\xb7\x6a\x89\xb4\x71\x54\xdf\xa5\xb5\xc0\x6d\x64\x05\x81\x77\xd0\x56\x58\x44\x78\xa9\x1f\x90\x80\xcb\x22\x30\x14\xb0\x43\x2c\x40\x12\xdc\x71\x8b\x6e\x98\xdc\x94\xbe\xea\x5f\x41\x2f\xc2\x67\x91\xb2\x6a\x95\xd5\xcd\x22\x9a\x12\x67\xe3\xd2\x39\x26\x4e\x05\x4e\x6c\x8a\xa5\x2d\xc0\xba\x05\xd4\xf6\x0b\x76\x12\xe4\x5a\xaa\x39\x2d\x58\x9c\x3c\x2c\xf5\x2f\x40\x22\xba\x92\xb8\xd1\x7a\x4d\x46\xaa\x1e\xdc\x60\x47\x6a\x25\x61\x8d\xfc\x46\xaf\xd0\x2b\x05\xa6\x5f\x2b\x20\x55\x3c\x78\x59\xef\x0b\x76\x8b\x96\xc1\x8f\x5c\xa4\x59\x0d\x57\x99\xcf\xc9\x57\xf4\x00\x36\x65\x05\xe3\xa0\x77\x53\xe6\x1f\x25\x44\xbe\x60\xf7\xa0\x3b\x93\xc5\xba\xd1\x2f\xbe\x53\xc4\xa3\x4f\xda\xe7\xa3\x21\x83\x88\x33\xd6\x74\x70\xe0\x36\x2e\x87\x02\x15\x98\x01\xb9\xe2\x12\x77\xa3\x0f\xe3\x36\x70\x9b\x4b\x67\x0b\x76\xc1\x17\xec\x08\xbf\xa9\x58\x06\x21\x8b\x5c\xfc\xd6\x90\x75\x96\x97\xcc\x75\xfc\xdf\x75\x8c\xad\xd1\x6f\x2b\x56\x06\x09\xcf\x31\x26\x56\x3c\x0a\x6c\x5f\x8b\x36\x00\xf8\xac\xa2\xa1\x45\xa4\x61\x11\x2d\xb8\xef\x4b\x3a\x29\x16\xbd\x2b\x4f\x72\xb7\xb7\x36\x03\xf3\xb9\xef\xa3\x78\x39\x99\x5f\xc4\xca\x10\x45\x22\xd0\xfe\xbd\xfa\x13\x74\x0b\xdc\x5c\xe3\x43\x6e\x55\xc1\x5d\x21\x58\x17\x5f\xce\x2f\xcc\x31\xb5\x8b\xaf\x73\x1c\xe4\x60\x4a\x90\xb0\xfb\x41\x9b\x8a\xe5\x80\xbb\x6d\x4d\xc7\xe5\x84\x10\x0d\xe9\xd8\xba\xd0\x06\xb4\x6c\x70\x8a\x44\x58\x81\x46\x26\x80\xbb\xf4\x83\xeb\xf3\x48\x2f\x78\x51\xca\x53\xb7\x04\xbf\x17\x59\x86\x0c\x0e\x0e\x26\xf3\x86\xc4\x6e\x08\x85\x8e\x37\xc8\x7e\x14\x05\x67\x64\x9d\x60\x18\x37\x4c\x20\x4c\x00\xec\x30\x96\xc4\x22\x4e\x92\x2f\xfa\x41\x34\xdc\x4a\xe3\x24\x41\x26\x40\x47\x2f\xfc\x41\xd0\x7b\x37\xc0\xca\x30\x98\x4d\x69\xd7\xd3\x87\x01\xcb\x0f\x63\x70\x71\x7c\x09\xd4\x5c\xec\x72\x71\xa2\xbe\x56\xa4\xf7\xf3\x50\x4f\xb7\x88\x11\x57\x83\x8c\x6d\x6e\xd8\xf5\xa7\xec\xd5\xfa\xc5\xc0\xe5\x39\xef\x5b\x6e\xe8\xcc\x72\xf7\x77\xac\x65\x71\xa3\x70\xc4\xa9\xbc\x7d\xd3\x60\x5d\xf7\x8b\x2c\x3b\x39\x84\x81\xea\x1f\xcb\x7e\xa2\x85\x3f\x1f\xb3\xdb\x0e\x0c\x5a\xd6\xf4\x17\xa6\xaa\x6f\xec\x2c\x8b\x96\xea\x65\x70\x5d\xde\xa1\x8e\x63\xc1\xba\x3e\x34\xd8\x39\x2d\x83\x0e\xc9\xe2\xe1\xc1\xf2\xee\xe1\x5a\x66\x36\x88\xfa\xc4\x71\x77\x44\xd5\x05\x3e\xc6\xad\x1b\x29\xdf\x2f\xd0\x51\xa2\xba\x13\xdb\x49\x0a\x90\x3c\xd7\x78\x82\xed\xf6\x59\x2c\x98\x07\xba\xbd\xb6\xba\xba\x66\xd8\x92\x72\xf0\xe6\xe5\xb8\x1f\x85\x0b\x19\xa6\x47\x20\x84\x06\x0f\xed\x45\x34\xe8\x7d\xd6\x89\x0a\x93\xb6\xf1\x68\x3c\x98\x7f\x0f\xee\x3d\x6b\xe3\xf6\x4f\xd4\x45\x12\x89\x5c\x7c\xff\x08\xfd\x08\xd0\x5a\xd8\x83\x03\xe8\xcf\xc8\xfc\xc2\x41\xe2\xbe\x8f\xbe\x82\x08\x4b\x3d\xce\x94\x7c\xad\x99\x09\x70\xe8\x52\xb0\x5b\x56\x80\x78\x81\xf4\xd0\x08\xc7\x86\xf3\xfb\x9e\x9e\x87\xef\x3b\x67\xb1\xf1\xf9\x4d\x4b\x19\xdf\xba\x88\xb2\xd5\x5c\x7e\xd3\xde\xe2\x73\x52\xdf\xf4\x64\xb0\xe0\x78\x90\xf9\xfe\x0e\xc1\x0d\xde\x22\xdf\xa5\x25\xc3\x06\xb7\x82\x47\x31\xce\x80\xe9\x8a\xd3\x4c\x92\x05\x9b\x57\x6c\x19\x6f\x33\x2a\x55\xa2\x89\xdf\xa5\xb8\x0a\x12\x32\x23\x7d\x2d\xb0\xe3\xd1\x90\x1f\xe5\xc2\x4d\x73\x35\xbd\x8c\xb3\xec\x3a\x5e\x7f\x70\x2e\x7f\x16\xc6\x49\x3d\x5f\x14\xf4\x68\x0d\x8a\x25\x62\xb4\x50\x01\xc1\x34\xbe\xd3\x17\x68\xd1\xf7\x20\x73\x3d\xf2\x93\x2f\x22\x2a\xc9\xb1\xec\x6a\x1b\x44\xa4\x21\x85\x9a\xe7\x94\x88\x23\xa5\xff\x64\x4e\xd6\xb4\xc7\x00\xc4\x34\xae\xeb\x62\x9a\xf3\x35\x23\x39\x4d\xe9\x68\xb6\xa8\x0c\xfb\x20\x4b\xe0\x83\xa0\x95\x91\xe0\x6a\x61\xc4\x78\x9c\x5d\x18\xc8\xc0\x60\x84\x5e\x86\x99\xd1\x86\x4a\x5e\x95\x08\x6d\x79\x3f\x2d\x45\xbe\xff\x8e\xbf\x8e\xb3\x92\x81\x53\x7c\xcb\x15\x08\x3a\x9a\xe3\xa6\x98\xee\xd8\x2e\x2f\x1e\x40\xdb\x33\x9a\x63\x1d\x49\xc5\xf7\x51\x49\xc5\x32\x8c\x02\xcf\x03\x9d\xd2\x21\x1e\x0c\xf9\x53\x4a\xa8\xf6\xfd\x51\xda\xa9\x7b\x32\x27\x95\xd1\x54\xb6\x76\xb0\x67\xb0\xc3\xcd\xd4\xf6\x66\x73\x87\x04\x5e\x16\x1a\xb6\x7d\x7f\x33\xdd\xc6\x25\xf8\x3a\x2d\x4d\x45\x2a\x34\x88\x15\xba\x5b\x66\x86\xde\x81\xe3\x53\x8e\x04\x6e\x70\x83\xda\x08\x4a\x44\x77\x6c\x6d\xb6\x43\x43\x94\x47\xcb\x81\x71\xe8\x5e\xd9\xc2\x64\x60\xb3\xeb\xb9\x9f\xcc\x2f\x60\xaf\xea\x40\x1c\x48\x10\xd0\xde\xe2\xd2\x5e\x02\x25\x73\x4c\xf8\x05\xcd\x7c\x3f\x9b\x4c\x1a\xd3\x76\x9f\x6b\xb4\xcc\xc8\x64\x7e\xd1\xd6\xc6\x48\x89\x83\x99\x5d\xdc\x23\x33\xce\xce\xcc\x4b\xd0\x32\xd5\x6b\x59\xe0\x40\xce\x98\x56\xca\x84\x46\x50\xcf\xeb\xe6\x1e\x58\xd2\x51\xd9\x90\x2c\x77\xb9\x88\x7e\x45\xa2\xae\xd3\xba\x46\xaa\x3e\xd3\xbc\x2c\x32\x58\xdd\x28\x06\x8b\x45\xf6\x53\x2a\xfa\x81\x5c\x4c\xb5\x00\x7b\x21\x23\xf2\xd8\x05\xca\x0d\xb5\xcd\x97\xc6\x86\x18\x07\x22\x6a\x01\x8a\xa4\x75\xed\x2c\xa9\xac\x7b\xa0\xaf\x9b\xa9\x69\xb4\x1f\x58\xcb\x29\x37\xd8\xdf\xbc\x69\xac\xeb\x31\x37\x3a\xd0\x4b\xb6\x61\x45\x31\x60\x15\x9c\xd3\x30\xf4\x78\x2e\xd2\xcd\x83\x27\x09\x6b\x7e\x53\xb0\xb2\xf4\x88\x83\x83\x90\xa7\x76\x99\x87\x4f\xa4\x3e\x8b\x48\xe8\x15\xac\xcc\xb3\x5b\xe6\x11\x4f\xa2\xc9\x5e\x05\x12\x3f\x9c\x0d\xd7\xd2\xfd\x34\x23\xa6\xa2\xc4\x53\xb5\x82\xbf\x61\xe2\x49\x9c\xfb\xbf\x56\x3a\x27\xba\x1e\x59\x69\x44\x52\xea\xed\x19\x4f\x80\x71\x88\xe9\xa1\x14\xb1\x18\x5a\x84\xb4\x21\x71\x76\x17\x3f\x94\x83\xe1\xe4\x80\x16\xb4\xeb\xa2\x68\xc2\xd1\x3a\x79\x80\xe8\xbd\xc1\x4b\x17\x40\x35\xb4\xf5\x87\xe4\x7c\xd2\x7d\xa7\x17\x80\x85\xdb\x08\x56\x0b\xbb\xd7\xcd\x52\x22\x97\x34\x68\x14\x90\x0f\x6d\x7d\xba\x43\x69\x28\xc2\x8f\x23\xb0\x3d\x52\x4f\x8b\x32\x94\x48\x36\x42\xbd\x16\x19\x84\x21\x1b\x0e\xea\xb6\x00\x7a\xe7\x50\x46\xfb\x08\xc7\x04\x05\x39\xa8\x98\x2a\x68\xd2\xe4\xb2\x98\xea\xf5\xd4\x53\x24\xdf\x21\xf2\x64\x50\x84\x12\xd7\x8f\x3d\x09\xe6\x5e\xa4\x1a\xe3\x10\x38\xa8\x6d\xb2\xc1\x8d\x44\xea\x4a\x58\xdf\xb6\xd6\x10\x39\x77\xed\x6c\x39\x54\xbc\xa2\xb3\x96\x1d\xc8\x90\x56\xac\x1e\x5f\xea\xb0\xee\xff\x64\xb3\x45\x3b\xcf\x84\x0d\x84\x3f\x83\x43\x26\x4a\x2f\x2a\xa5\xc5\x43\x8c\xc6\x8e\x7a\x0e\x53\x4a\xf3\xb6\x73\x4e\xec\x52\x79\x6c\xd0\x2e\x03\xde\x6d\x95\xd9\xfe\x59\xc9\xb2\xcd\x04\xe6\xa4\x02\x25\x2f\x5e\x08\x88\xad\xf4\x57\x43\x3e\x2a\x9f\xb8\x5b\xc6\x09\x50\x9d\x72\x69\xa2\x3d\x91\x0c\x55\x24\x27\x6f\x49\x89\xf5\xe3\x37\xa4\xc4\x38\x40\xd5\x78\x4c\x1e\xcf\x64\x53\x73\xbd\x78\x72\x4d\xb0\x2c\x1b\x8f\x28\x7d\x0b\xfc\x9d\xe6\x50\x0a\x2a\x79\x14\x82\xca\xba\xce\xcd\xd2\x42\x6e\x35\x15\x4d\x43\x04\x2d\x97\x1d\x48\x06\xb6\x0a\x39\x4c\x4f\x0b\xc3\x53\x76\xbf\x66\x70\xb7\xe0\xab\x3c\xff\x20\x0f\xd6\xc3\x5f\x24\x34\x4f\x4b\xc9\x0b\xbe\x2b\xe2\x35\xc3\xa4\xba\xa0\xe9\x18\x8e\xea\x23\x4a\xbf\x19\xe8\x60\xae\xe1\x0c\x90\xa8\xee\xda\x22\x5d\x0a\x84\x03\xe4\xb4\x72\xc3\x04\xb0\x98\xaa\x79\xe4\x36\x42\x4f\x64\x93\xd8\xfb\x72\x5a\x32\xf1\x2e\xdd\xb1\xbc\x02\x99\x97\xf5\xcc\x3d\xb4\x3d\x19\x3e\xe4\xe1\x2c\x0a\x9f\x47\x70\x88\xcd\xd0\x8c\x30\xb2\x43\x05\x5e\x16\xc1\x5b\xc2\x3a\x53\x4e\xf2\x70\x7e\x94\x53\xe0\xa5\x08\xde\xc2\xc7\x67\x47\x1f\x21\x88\xdc\x37\x18\x77\xf7\x87\x7e\x7c\xe4\x78\xb2\xb4\xc4\x01\xac\x08\xe3\xa6\x21\x25\x3d\x34\x8b\x2e\x4f\x31\x8c\x50\x44\xf8\x2c\x22\x05\x15\xe1\x27\xd1\x22\x56\x88\x84\x82\xbb\x59\x52\x00\xf6\x48\x12\x17\xaf\xa4\xb4\x68\x48\x1e\x3e\x9f\xb0\x28\x7c\x16\x19\x7f\x5c\x26\xe5\xb9\x9b\x32\x83\x1c\x92\x1c\x13\x33\x65\xf2\x05\x13\x55\xa9\x90\x09\x92\xf6\x61\x52\x02\xf6\x88\xe8\x00\x6e\x3e\xc6\x2b\x92\xc5\xd4\xe2\xbd\x60\x98\xa0\x76\x0b\x51\x6e\x09\x70\x83\x49\x6c\x27\xb6\xc4\x44\xdd\xe0\x96\x7b\xa9\x94\x1b\xa7\x6c\xc8\xdd\x96\x1d\xdf\xe2\xe0\xc7\x01\x11\x05\xe5\xa4\xa0\x9a\xed\x92\x58\x4d\x87\x19\x75\xfa\x92\x3b\x30\x87\x30\x89\xe9\x9f\x5d\x4b\x93\x5c\xbc\x3a\xbf\xc9\xa7\xf9\x45\xbf\xd1\xe5\x51\x1b\x01\x23\x93\x09\xef\x6d\x5e\x38\x2a\xca\xfd\xb1\x41\xfc\x82\xca\x6d\x25\xcf\x46\xb9\x26\x72\xe0\x25\x5f\xe7\xb6\xfb\x8a\x8c\x38\x26\x96\x8e\x02\x06\x04\x42\x8a\x70\x5d\x03\xbd\x89\x80\xd6\x44\xea\x6c\x64\x35\xc6\xb9\xa2\x7a\xe6\x28\x20\x26\x13\xfc\x46\xe9\x41\x64\x33\xb6\x76\x2b\xbc\x74\xf0\xaa\x39\x02\xfe\x44\xcf\xdf\xa3\x57\xb7\x71\x56\xbf\xe1\x82\x15\x3c\xce\xea\xb7\x31\xbf\x61\xf5\x5b\x39\x73\x8c\xaf\x59\xad\xfc\xb3\xd4\x60\xdb\xfe\xe3\xdb\x37\x18\x70\xf0\x93\xf3\xc5\x29\xf4\xd2\x3b\x1d\x5f\x82\x94\x3d\xcf\x98\xef\xdb\xc7\xe9\x5d\x5c\x70\xdf\x67\xbe\xff\x93\xbd\xcb\x13\xef\x24\x36\xee\x66\x31\x91\xaa\x6d\x4b\x67\xb6\x25\xb8\x2a\x3a\xdd\xb1\xb2\x8c\x6f\x18\x61\x0a\xd5\x80\x9f\x9e\x2b\x25\x68\x7e\x65\x72\x76\x9c\xac\x74\x70\x8d\x8b\x56\xf5\x79\x16\x37\x30\x2d\xaf\x3b\xb0\xd3\xd2\xc0\x2f\x10\x3e\xbc\xd2\xde\xf0\x7b\xde\xa0\x5f\x7e\xf7\x8d\xbe\x6f\xf8\x75\x1e\x27\x2c\xf1\xc8\x17\x12\xb5\x0d\xe6\x55\x8e\xa0\xbf\xc0\xa6\xaf\x48\xc5\xe7\x55\x2f\x43\x71\x9f\x5f\xab\x95\x66\x38\xd4\x4c\x50\xd4\xc1\x88\xfd\x21\x23\x86\xed\x61\xa3\x65\x5b\x6d\x7c\xca\x39\x81\xec\x3f\xc5\xa9\x08\xf4\x73\x67\xcf\x21\x65\x18\xb0\x9c\x4c\x74\xc5\x90\xf3\x6a\xaa\x2b\xc0\x75\x8d\xec\x0b\x1d\xcd\xf0\x08\xa2\x4a\xcc\x2e\x3a\xf9\xeb\xfa\x75\x67\x57\xbc\x22\xe1\x55\xa4\x45\x88\x90\x09\x86\x44\xd5\xc8\x88\xb7\xce\x77\xfb\x8c\x09\x30\xfc\x78\xa5\x32\x5c\xc9\x2d\x50\xd7\x30\x5b\xfa\x80\xe7\x7e\xf1\xfd\xd1\xab\xbe\x27\xba\x69\x92\x5f\xad\x8b\x3c\xcb\x96\x9d\x85\xd6\x2d\xe2\x00\xbd\x1a\xf0\xe3\x7d\x62\xe5\x8e\x33\x9a\x65\x53\x5b\xe7\xc9\x80\x9d\xa2\x64\x90\x14\xce\x1a\xbc\xa6\x40\x29\x04\x25\x69\xb9\x13\x7a\x87\xb8\x92\xb3\x97\x67\x29\x3f\x93\x47\x7e\xc2\xf1\x13\xa8\xb0\x24\x3c\x2c\x23\x32\x9a\x41\xa5\x0b\x73\x8b\xbd\x13\xc4\x14\x0a\xec\x54\x28\xd5\x18\xa2\xdc\x65\x20\x71\x47\x96\x45\x29\x4c\xb4\x06\x1c\xa0\x8c\x0a\x72\xac\xba\xd3\x20\x96\x39\x52\x6f\x0e\x7e\x16\xb5\xfa\xc9\x5e\xac\x10\x88\xc9\x0e\x71\x12\x2f\x8b\xa0\x30\x61\x31\xcb\x88\x94\xc4\x7c\x72\x2e\x53\xa4\x4b\x16\x64\x96\x9f\xc2\x41\xb5\x54\xfe\x57\x08\xc7\x41\xde\x90\x5f\xe9\xf9\xfb\xc9\xae\x9c\x9c\x93\x3f\xe8\xf9\x44\x99\x0b\x60\x57\xfa\xf4\x63\x57\x14\x3e\x15\xf9\x8f\xfb\xbd\x35\x34\xb0\xd9\x7e\xee\x58\xfd\x18\x7b\xb2\x5f\x89\xb7\x2b\x27\x8e\xfb\x9c\x3f\xc8\x8f\xca\x3a\xe1\x5f\x43\xdb\xab\x7f\x83\xe7\xb3\xde\xfb\x68\xec\x28\xc2\xdb\x2e\x7e\x09\x88\x23\x2d\xa7\x3a\x5c\xac\x32\xb3\x90\x4f\xe3\x2f\xa7\x55\x9a\x8c\xc7\x0d\xfc\xd2\x39\xf9\xd2\x8d\xbc\x0d\xbe\x8e\x86\x44\xe7\xa1\x5b\x5b\xcf\x9d\x8a\x96\xc6\x2b\x23\x2f\x38\xe9\x60\xf2\x2f\x15\x12\xdc\xf5\xcd\xd8\xad\x82\x8a\x40\x97\x53\x9e\x51\xda\xcb\xf1\xc4\xcd\x47\xb4\x5d\xb2\x20\xeb\x9c\x6f\xd2\x9b\xaa\x00\x01\x02\x68\xd0\x31\x11\x0d\x29\x99\x38\x75\xb5\x4a\xe9\x97\x60\x48\xc6\xa1\xf2\x91\x4c\x13\xa7\xe1\xcf\x48\xe0\x88\xf2\x45\x37\xcc\xaa\xfa\x52\xe0\x6e\x34\xd1\xb4\x1f\x54\xdc\x01\x04\x05\xfe\x70\x05\xa3\xd3\x70\xd0\x1b\xb9\xef\xf7\x12\x54\x0f\x1a\x12\xaf\xd7\xac\x2c\x4f\x49\xc4\xdb\xea\xeb\xfa\x84\x78\xd6\x66\xe1\x4b\xab\x7c\x91\x3d\x0c\x94\x2e\xa6\x54\xaf\x84\x63\xd2\xea\x40\x97\x3c\x10\xf8\x58\xe8\xd4\xd1\xd5\xf5\x57\xbf\xb3\xd7\xe1\xa8\x64\x5f\x05\x3e\x70\x8a\x44\x2f\x76\xb2\xe4\x6c\x41\x08\xfd\xb3\xec\x0b\x95\xe3\xc5\x29\x3f\x2b\x96\xa1\x88\x02\xd1\x11\x60\xe2\x63\x23\x6e\x1d\x99\x46\x1e\x24\x79\x14\x35\xc8\x9d\x09\x89\xed\x9d\x80\xbf\x2a\x78\xff\x63\x60\xa7\xd9\x43\x1b\xed\xa6\xf3\x55\x9e\x6b\xb6\x71\xf9\x32\x16\xf1\x5f\xdf\x04\xed\xd8\x7d\x7f\xd4\xef\x8f\x90\xfc\x96\x2c\xfe\x0b\xdc\x65\xf8\x92\xfc\xa0\x7f\xff\xa1\x2d\x1b\x0e\xca\xac\xe1\xe9\xaa\xa9\x57\xa1\x79\x8e\xf0\x93\x73\xf2\x4f\x7a\x1e\xbe\x98\xfc\x3b\x72\x51\xcf\xbf\x07\xac\x1a\xda\x55\x3f\xba\x2c\x9f\x6e\x50\x41\xbd\x24\x16\xf1\xc4\x75\xac\xf3\x4f\xe2\x4d\x9e\xf8\x5e\xdf\x17\x40\x1f\xa4\x20\x5a\x71\xc7\x98\xaf\xc0\x58\x9d\xf3\x38\xf5\x44\x51\x01\x49\x44\x29\xe5\x10\xc5\x39\xce\x4a\x26\x29\x61\x2a\x4f\xb9\x12\x0b\xc8\xaf\xa9\xf2\x69\x95\x52\x4a\xc7\xe9\xd8\xf3\x96\xe3\x34\xd0\x57\xaa\x53\xbc\xfc\xc7\xd5\x77\xdf\x2a\x03\x05\x94\xe2\x20\x75\xce\x8e\xcd\x0f\x0e\xb8\xaa\x2b\x4e\xe6\xe8\xd7\x9a\x8f\x5d\xb9\xda\xee\xa3\x45\xb3\x77\xb2\xf5\x47\xc4\x70\x5d\xff\xe2\xbc\x35\x24\xe9\x96\xe9\xec\xb7\x1f\xa6\x6a\x3f\x9a\x3e\xe8\x2d\xf2\xb2\x5f\x04\x1f\x7e\xd0\xac\x94\xf6\xc6\xf8\xeb\x63\xb5\xfe\xd2\xaf\xf5\xd7\x93\xd5\xfe\xd2\xa9\x16\xb8\x13\x47\xbf\xdf\x6d\x84\x13\x6b\xe5\xa4\xbd\xfa\x2b\x75\x2f\x89\x69\xee\xfb\xb9\x63\x97\xda\x85\x18\x65\x48\xd2\xd1\xe0\xa4\xf4\x07\x40\x1c\xb9\x32\xea\xca\x1d\x7d\xf8\xe8\x17\xf5\x85\x78\x7a\x12\x25\x64\x94\x1e\x00\x05\x8d\xbb\x1b\x57\xb2\xfc\x31\x1c\x0f\x64\x43\xa8\x80\xb8\xe9\x8a\x97\x6e\xfd\x94\x29\xc8\x54\xf6\xd7\x3f\x23\xa3\x87\xfa\x04\x63\xf2\x6f\x75\x37\x12\x62\x5a\x2f\x7e\x01\x58\xe8\x37\xeb\xba\xd8\x4c\xf5\xc3\x91\x74\x45\x63\x42\x38\xe4\x3a\x4c\xb5\x82\x2e\x25\x8b\xc2\x0d\x0e\x9e\xa8\xe7\xa3\x3d\x0f\x91\x10\x1c\xc4\x6a\x0d\x88\xec\xa6\x47\xc2\xcc\x97\xe4\x31\x96\x22\x70\xbf\xfc\xbb\x97\xba\xf8\xd3\xce\x10\x06\xce\xbe\xb4\x1d\xd1\xf1\x49\x4f\x7d\x91\x23\x1f\x86\xc7\xae\x32\xfd\xb8\x25\x0d\x52\xca\x58\x00\x37\x46\x71\xae\x81\xea\xf7\x8a\x55\x6c\x98\x9c\xaa\x1b\x19\xa6\x72\x8a\x84\xdc\xf2\xf7\x1e\x1e\x7b\x50\xc8\x23\x05\xfd\xc5\x12\x1c\xc2\x7d\x1f\xdc\x2a\x1f\x45\xc8\x97\xb9\x9c\x1d\xe0\x9a\xda\x70\x8c\x03\x1b\xc9\x00\x93\x42\x52\x83\x86\x24\xec\xb8\x53\x12\xdc\x74\xfb\x0b\xa3\xe2\x84\x5c\xaa\xf1\x36\xae\x17\x49\x29\xb7\x17\x9d\x24\x13\xf4\x2b\x64\x93\x67\xc1\x52\x39\x7f\xf5\x52\x6e\x85\xe1\x54\xe1\x2e\xb7\x4c\x31\x99\xc0\x15\x12\x24\xdb\xa2\xda\x8c\xd5\xb8\xce\x75\xcb\x62\xa2\x29\x4a\x0e\xca\x2c\x62\x95\x84\xce\xec\x5f\x4d\xf5\x60\x34\xa2\xc8\x31\x26\xa3\xc2\xf7\x61\x87\x82\x0a\x05\xc4\x11\x48\x62\x85\xb6\x9f\xc3\x81\xdb\xf5\xb4\x43\x0e\x6f\x61\x91\x8b\x5a\x00\x0e\x88\xce\x4e\x33\x27\x07\xa5\xa0\x39\x2d\x3b\xef\xcb\x72\x1c\xdc\x13\x0a\xbb\xc4\x3c\x52\x51\xa1\xfa\xb8\xa8\xb7\x42\x16\x68\x18\x7d\x66\x94\xcd\x47\x21\x23\x41\x96\x27\x99\x7e\x39\xb3\x84\xc9\x79\xee\xc3\xfa\x05\x5b\x9a\x75\x35\xe8\x4c\x18\x07\xb3\x96\xc9\x09\x06\x01\x5d\xb5\xee\x96\x56\xd7\x8a\xba\x10\xa0\xd2\x31\x69\x17\xd7\x5d\xd2\x91\x31\xfb\x6b\xd7\x4d\x17\x90\x3b\xf4\x18\x2e\x1f\xdf\x7a\xbd\x4a\xd4\x36\x5f\x67\x2c\x2e\x7e\x78\xb4\x1e\x0d\x30\x0a\xda\x49\x18\x0d\x0a\xfd\x5c\x66\x6d\x4e\xd2\xae\x78\x49\x11\x03\x12\x77\xcc\xad\x4a\x57\xa2\x36\x99\x14\x75\x9d\x76\xce\xc4\x39\x09\x25\x3b\xb4\x18\xb2\xc7\x42\x82\x32\xc2\x34\x35\xd6\xb1\x3c\x61\x2f\x3a\xde\x9c\xb8\xc6\x06\x79\x18\x47\x84\x75\xa0\x55\x85\x75\x01\x88\x94\x88\x7f\x3c\x26\xfa\x0d\x80\xb0\x74\x1c\x4b\xa9\xdb\x89\x5a\x30\x24\xac\x64\x48\x45\xec\x9d\x44\x4b\xc9\x3f\x25\x4f\x57\xd3\x1a\xaf\x92\x31\x5a\x06\x21\x7b\x15\xc1\x87\x55\x32\xae\xf1\xb9\x8e\xb2\xd7\x8f\xeb\xfb\xde\x84\x4f\xc6\xb4\xc6\xc8\x1b\x33\x36\xf6\x30\x1c\xf3\xfe\x1e\x3d\x75\xa2\x22\xd3\xd0\x7b\x97\xef\x3d\xe2\xbd\x4d\x6f\xb6\xc2\x23\xde\x17\xb9\x10\xf9\xce\x23\xde\xd7\x6c\x23\xbc\x88\x14\x8c\x1e\x1d\xf3\xbb\xf1\x73\x1d\xd5\xad\xb5\x96\xeb\x47\x5a\x95\x7c\x48\x2e\x8f\x5e\xf9\x6e\x9f\x97\x2c\x01\x1b\xc0\x02\x18\xaf\xb7\x79\xae\x7d\xea\xa0\xff\xa1\x5a\xed\x9d\xc9\x54\x82\x72\x15\x64\xb3\x9b\x4f\x4f\x69\x3c\x1c\xf5\xd7\xe3\x39\x57\x4c\x1e\xa3\x2a\xda\x5a\x29\x1e\x32\x88\x5b\x07\xd1\xdf\x6b\x7d\x21\xa5\x93\xea\xfb\x29\x83\xd3\x9f\x2d\x7d\x35\x5d\x03\x22\xf2\x74\x0e\x0f\x3b\x47\xd5\x92\x0d\xdc\x91\xa3\xcf\x66\xa4\xa4\xc5\xb1\xab\xd0\xb3\x62\xba\xae\x0a\xe4\x7a\x6b\x77\x67\x43\x93\x15\xb0\x07\xa8\xa8\x04\xa0\x0c\x34\x5d\xe0\xe6\x15\x41\x86\x6f\xab\xdd\x35\x2b\x42\x11\x2d\x3d\x2f\xf0\xf6\xf7\x1e\x06\x1f\x8a\x2d\x97\xd3\xcb\x56\xd7\x32\xd3\x88\xd2\xcc\xf7\xc7\x15\xf6\x7d\xc1\x94\x5d\xaf\x6d\x4e\x5d\x86\x5d\xfb\xfe\x3a\x7c\x1e\xc9\x8c\xf8\x50\x9d\xd3\x67\x24\xa3\x59\x5d\xcb\x34\xb2\xa6\xe3\xaa\xae\xe7\xce\x06\xb9\x52\x73\x06\xbd\x5d\x8f\x33\x4c\xd0\x7c\x92\xe3\xa7\x68\x3e\x41\xb9\xec\xf7\x79\x55\xd7\xd3\x4f\x30\xbe\xa0\x33\xb8\x6a\x3c\xc3\x64\x7d\x4e\xf3\xc5\xfa\x29\x7d\x46\x8e\x0a\xeb\x7b\x81\x8d\x63\xa1\xbf\xa6\xe3\x75\x5d\xcb\x66\x67\x92\x0a\x86\xf3\x68\xb9\x1e\x23\xf9\x3b\x9e\xe3\xa7\x3c\x7c\x16\x05\x63\x0e\xf2\x7d\xb9\x09\xa7\x15\x4f\x05\xcd\x48\x31\x2d\x45\x5c\x08\xba\x26\xc5\x94\xf1\x84\xa6\x18\x93\x14\xa4\x13\x15\xa3\x07\x67\xd5\x32\xd6\xbb\x0a\xd2\xbb\x81\x1d\xca\x41\xcf\xc8\xa6\x75\xf5\xb6\xbe\xd8\x2c\xd6\xe3\x31\x46\xf2\x3c\xb9\x8e\x34\x28\x99\x9b\xd0\x2e\x00\x11\xb1\x44\x16\x76\xe4\x58\xb2\x70\x1d\x69\x7c\x52\x38\x40\x54\xd7\xc0\x0c\xc9\xaf\x75\x8d\x7a\x95\x50\x88\xbd\x06\xf0\x59\xf4\xe1\x33\x66\x60\x8a\xa4\xea\x45\x15\x8d\x69\x6e\xd4\x4a\xb1\x3c\xcf\x14\xb8\xb7\x99\x4a\x9a\xda\x9b\x26\x04\x55\xb4\x02\x37\x1e\x75\x8d\x72\x1a\x4f\xaf\xf3\xe4\xa1\x13\x8c\x24\xee\xdd\x77\x2b\x31\x26\x95\xde\x04\xb9\xd3\x7f\x92\x9f\x0a\x64\x9a\x63\x62\x27\xa0\x82\xb8\xc8\xde\x75\x96\xaf\x3f\x78\x98\x40\xd3\xb4\xc2\x18\xe3\x40\xe5\x19\x39\x93\xa4\x52\x88\x62\x98\x9d\xb9\x52\xf2\x2f\xb9\x58\x6b\x3a\xb3\x4b\xa1\x54\x44\xb2\x20\xf8\x95\x58\x47\xbd\x29\x94\x5f\x4e\xd9\x17\x97\xdb\xfc\x6e\x60\x0f\x66\x9a\xbe\x01\x87\xba\x4d\x93\x21\x8d\xbb\xce\x83\x1b\x22\xf2\x9b\x9b\x6c\x88\xf6\x79\xd7\x79\x9e\xb1\xd8\x55\x88\x2e\xb5\x3d\xa8\x6c\x18\x69\xd3\x72\xd9\x80\x79\xee\x13\xdc\x58\xb7\xb2\xbc\x52\xbf\xa6\xa0\x79\x55\x65\x1b\x4b\x55\xd6\x8c\x6c\x18\xd9\x33\x75\x2e\x37\x9e\x91\x6a\xf0\x95\x04\x31\xe7\x13\x46\xcf\xbb\xb7\x87\x7a\x97\x87\xce\x53\xb2\x95\xc5\x9f\xd4\xef\x77\x79\x52\x65\xec\x49\xbd\x3a\x47\xcb\xe0\xb7\xf8\x36\xae\xd9\x7a\x17\xe3\x72\x5d\xa4\x7b\x71\x9e\x2e\xd6\x92\x74\x28\x28\x31\x40\xf6\xba\x88\x6f\x00\x5c\xba\x31\x15\x5f\x9d\x88\xa9\x88\x36\x6d\x15\x7f\x16\xae\x49\x47\xfd\x81\xa1\x78\x98\x6c\xfa\xf1\x92\x4d\xac\x24\xe2\xb5\x51\x93\x8e\x32\xe9\x58\x40\x42\xe2\xcb\x6e\xd8\xa0\x0d\xc3\xe4\x41\x79\x91\xbb\xcc\x72\xce\xe8\x9a\x4d\xd7\xf2\x01\xc8\xce\x68\x86\x7b\x6f\xd6\xab\xab\xf1\x3c\x27\x2b\x74\x6f\x45\x9a\x88\xff\x9f\xdf\x5f\x9c\xdb\x67\x8f\x3c\x4c\x79\x0e\x0d\x5c\xaa\x62\x74\x34\x3a\x6a\xa9\xad\xdb\xbd\xb2\xd8\x6f\xc0\x46\xf5\xd2\x0f\xb2\x6e\xf5\xa8\xea\xb4\xb5\x00\x64\xdc\x30\x7a\x10\x5b\x16\x27\x41\x38\x27\xde\x05\xdc\xa8\xfd\xdc\x23\xde\xc5\xb9\x7e\x8c\xc8\x3a\xcf\x82\xf0\x99\xfd\x78\xb1\xce\xb3\x9b\x22\xaf\xf6\x2a\x9b\x7d\x73\x4a\x88\xa2\x53\x40\x48\x2c\xa2\x2b\x85\x47\x37\x6b\x12\x84\xcf\xfb\x59\x2f\x44\xa1\xb3\x17\x9f\x0f\x94\xf9\x55\x0f\x3f\x08\x67\xc4\xf3\x88\xe7\x45\x0e\xf2\xbe\x75\xa3\x18\x5b\x71\xca\xe9\x90\x85\xc7\x31\xf1\x4e\x05\x37\x07\xdf\x3e\x38\xf8\x6b\x01\x3f\x97\x03\xb1\x95\x4c\x0d\x61\x44\x7a\x02\x4f\x75\x0b\x70\x69\x4d\x62\x19\xc8\xeb\x79\x37\x44\x6d\xcf\xed\x9b\xe3\xb7\xc6\x7a\x57\x51\xb8\x91\x85\x3c\x22\xde\x4d\x96\x5f\xc7\xd9\xab\xdb\x38\xf3\xe0\x5e\xb5\xa2\x31\xa2\xff\x0d\xe3\xe6\x86\x4d\x61\x8e\xa9\x7c\xd8\xe4\xb9\x90\x0f\x66\x5d\xe1\x39\x56\xf0\x73\x03\x56\x1b\x71\x42\xe0\x01\x5e\x13\x0b\x5d\x75\x8d\x6e\x98\x7c\xb6\xc5\x34\xd4\x01\x60\xe9\xd0\x5f\xbb\x2a\x13\xe9\x3e\x63\xf4\x23\xf3\xf4\x91\x5a\x69\x13\xf4\x2b\x52\x08\x6b\x27\xf1\x51\xed\xff\x6d\xb9\xba\x1b\x2f\xce\xdb\xd5\xbd\x3f\xe5\xa3\xca\x89\xf8\x2f\x4e\x22\x1f\xe5\x9f\x28\xa1\x33\xb2\x6d\xe7\x2e\xb9\xd8\x2e\x12\x75\xef\x03\x7c\x58\x25\x92\xf8\xcd\x20\x2e\x4d\x5f\x69\x94\x63\x6c\x96\x68\x4f\x72\xc7\xc9\x53\x1e\x05\x79\xab\x2b\xda\x99\xfb\xf4\x18\x1f\xc0\xb8\x74\xd3\x8d\x44\x76\x02\xeb\x95\x14\x25\x9a\xfd\xca\x71\x5d\x87\x0a\xb4\xf1\x71\xb4\x80\x8a\xde\x48\x42\x59\xd7\x37\x6c\x6a\xf6\x02\x89\x1d\x24\x50\x49\x4e\xe8\x6a\xba\x15\xbb\xec\xfb\x82\x69\x9b\xe6\x1c\x8f\x2b\xc9\x13\xad\x69\x15\xce\x8c\xe3\xe7\xf5\x64\x82\x63\x1a\x3b\x48\xa1\x1d\x60\xec\x5a\x65\x13\x14\xd3\x8d\x6b\x3f\xee\xba\x7a\xa5\x9e\xa7\x3d\x35\x69\x1b\x41\x3d\xc2\x77\xec\x5e\xb3\xe7\x92\x40\xf7\x4a\xc8\x75\xb0\x21\x33\xf7\x61\xa2\x7d\x72\x14\xe0\x1c\xaa\xb5\xc7\xcc\x49\x81\x71\x6a\x1d\x4e\x39\xd3\x9c\xd1\x54\xd6\x4c\x62\x7a\xcb\x50\x77\x8a\x25\x8f\xa1\xe8\x91\x07\xba\xb9\x07\x86\x62\x2c\x4f\xee\x6b\xa7\xcd\x38\x5c\xcb\x36\xb7\x66\xb5\x8c\xef\x49\x0f\xdb\xfb\xbc\xb9\x15\xc2\x6d\x80\x51\xbc\x96\x24\xf0\x03\x7b\x38\x27\x77\x9a\x96\xee\xf2\xaa\x64\xf5\x3e\x4f\xb9\x60\x45\xbd\x56\xd7\x7b\x77\x8c\x57\x75\x52\xc4\x37\x75\x52\xe4\x7b\x5c\xaf\xb3\x74\xfd\xe1\x9c\xbc\x83\x32\xe1\xfb\x69\xf4\x14\xcb\xe3\xdd\x14\x4d\xc7\xb8\xc6\x0e\x78\x5f\x32\x37\x6e\x80\x4d\x7e\xe5\x24\x3b\xa1\xd0\xaf\x58\xf7\xf2\x30\xa5\xb4\x67\xb2\xa4\xbf\xbc\xea\x3a\x6f\x75\x24\xd1\x0d\xc2\x94\x22\x0f\x5c\xbf\xaa\x70\xe5\x6d\xf5\x1f\x98\xab\x61\x55\x18\x35\x26\x65\x57\x95\x6a\x75\x4d\x07\xa3\x4e\x3d\xbe\xc0\x0b\x22\xd0\xa2\xae\x39\xe1\xf6\x60\x2d\x30\x54\x5f\x42\xf5\x22\x2c\x23\x92\x3b\xdc\x58\xba\xd1\xf7\x64\x0a\xe5\xfa\x85\xd2\x74\x89\x52\x30\x3e\xb1\x55\x04\xfa\x83\xef\x1f\xab\xbe\xb8\xcc\x5d\x90\xc2\xe6\xd5\xaf\x4e\x0f\xb4\xef\xf0\x14\xa7\xf4\x15\xb3\x30\x35\x6a\x83\xab\xb8\xbe\xef\x73\x38\xa7\xa4\x04\xa5\x83\x27\x55\x84\xa7\xf9\x66\x83\x98\x8e\xdc\x77\x6c\x76\xd8\xe0\xe9\x4d\x95\x26\x34\x86\x1f\xf0\x89\x07\xef\x57\xf0\x33\x1e\x43\x4c\x8a\x63\xa9\x0a\xbb\x65\x5c\x28\xab\x21\x25\xe5\x49\x49\x01\x32\xdd\x76\x91\x5e\xc8\x59\x84\xe5\xc9\x97\x48\xa3\x7f\x92\x92\xd1\x1c\x44\x9f\xb6\xbc\x4c\x3b\xd8\x88\xe3\xc1\x68\x4e\xb6\x10\xce\xa5\x38\x71\x95\x58\x13\x0b\x30\xcb\x81\x13\xe0\xdc\x67\xd3\xb4\x7c\x57\xa4\x37\x37\xac\xd0\x37\xae\x52\x75\x57\xd3\xb8\xff\xc0\xc8\xb4\x08\xae\x0a\xe2\x2c\x4c\x23\x75\x4b\x25\x61\x19\xbb\x91\xf8\x40\x5d\x99\x07\x29\xe2\xf7\x45\xbe\x8f\x6f\x62\x35\x56\x3b\xff\xc5\x80\x45\xd1\x2f\xad\x08\x39\x55\x8a\xf5\xdc\xf4\x8c\xe8\x7e\x20\x4c\x8a\x11\xa5\x56\x32\xa3\x3f\xe3\xba\x16\xcb\x4e\x71\x88\x18\x4e\x0f\x0d\x64\x77\x9c\x61\xc8\x1e\xbd\xd9\xed\x58\x92\xc6\x82\x75\xba\x46\x18\xdc\xca\x62\x5c\xbc\x54\x98\x16\x61\xa2\x03\xf7\x2a\x9c\xd7\x7a\x3f\x41\x9d\xa6\xb4\x72\xd7\xcc\x89\x50\x53\x87\xac\x40\xba\x08\x67\x11\xb9\x9a\x82\xb1\x43\xab\xa6\xc6\xa4\xb0\x8e\x9b\xcd\xf5\x4c\xf2\x58\xff\x24\x8f\xef\x08\x0e\x8d\x98\x34\x85\x8b\xad\x5d\x00\xb8\x64\xb8\xd1\x69\xf4\xa0\x58\x80\xe0\xd0\xbb\x08\x27\x08\x1b\xf0\xfd\xa4\x28\x2b\xd9\x13\xed\x9d\xd1\x4c\x33\x80\xc6\xbf\x90\xc0\xf8\xc0\xa7\x1a\xa2\xe0\xd4\x8b\x72\xca\xb1\x49\x21\x29\xcd\xad\x33\x0a\x10\x39\x9f\xba\x34\x2f\xfb\x4d\xb8\xd9\x24\xbc\xb7\x49\xe4\xe9\xf4\x56\xf5\xbf\x94\x07\xd4\xf6\x6d\x48\x4d\x0f\x24\xeb\x56\xf7\x41\x59\x6a\x98\xb7\x81\x4d\x3c\xc4\xd5\x5d\xb5\x53\xa8\x57\x8f\x25\x23\xe3\x44\x78\x69\x3e\xc9\x03\x25\x38\x78\x30\x1e\x07\x1d\x43\x35\x1d\x28\x19\x93\x8c\x22\x46\x91\xa2\x2e\xae\x4a\x58\x12\xf8\xae\x6e\x29\x9b\x4c\x70\x42\x6f\x28\x2a\xe9\x3b\xcd\x0d\xb0\x30\x8b\xb4\xd3\xa1\x79\x44\xb6\x14\x95\xe1\x33\x1d\xa7\x48\x7b\xbe\x99\x1a\xd7\x37\x98\x24\xbe\x8f\x36\xb4\xbf\x13\x13\xd8\x89\x24\xa1\x28\x5d\x6e\x3a\xfb\x31\xd8\x4c\xaf\x53\x9e\x80\x4a\xb5\xae\x13\x72\xb2\xec\x9a\xb6\xba\x14\xf0\xa3\x96\x90\xbc\x48\x6f\xa0\x8e\x1b\xa5\x6d\x2c\x2c\x56\xe1\x44\xae\x59\xa0\x56\x90\x98\xb5\x0f\x52\xe2\x7a\xc1\x08\x00\x12\x4e\xb8\xc8\x30\x7a\x54\xd2\x62\xad\xad\x76\xeb\x33\xf5\x40\xc1\x40\xd0\x9e\x56\x8a\x5d\x43\xfa\x91\x86\x51\x8b\x6d\x2e\xf3\x8a\x0b\x3a\x23\x1b\xb9\x2b\xab\xbd\xef\x8f\xe6\x23\x4a\xf5\x9b\xbe\x57\x4a\x0a\xb2\x25\xb1\xc4\x13\x47\x86\x47\xbe\x7f\x9c\x86\x12\x12\x63\x4c\x36\xf2\x83\x9c\x67\xf9\x6b\x6a\x5a\x63\xb2\x36\x10\x6f\x20\xb8\x9b\x40\xd5\x74\x60\x4c\xd2\xd6\x91\xe5\xbe\xdb\xdf\xf1\x98\xcc\xc8\x1a\x07\x9a\x93\x5a\xb7\x68\x5c\x6d\x58\x39\xc8\xd1\x0c\x37\x83\x56\x0d\x7f\x6d\xe7\xb6\x4a\x62\xdf\xd7\xe8\x02\xf6\xf1\x2d\x08\x63\xec\x06\xc3\x87\x8c\x22\xad\x0c\xfb\x2b\x40\x9b\x6e\x50\x0f\x6e\xc5\x7f\x05\xb7\xf8\x70\x12\xf4\x60\x71\x29\x2a\x1e\x07\x5d\x08\x10\x42\x4a\x5a\x42\x94\xae\x5e\x1c\xa4\xd5\x6a\x8a\xbd\xb1\x81\xa0\xd5\x6a\x8a\x96\xc1\xf4\xe9\x6a\x35\xad\xb1\x87\xc7\x1e\x92\x4f\x4f\xb0\x27\xb9\xc9\x41\xd7\xa5\x6b\xf0\x5c\x4a\x46\xa9\xef\xdf\x8c\x28\x5d\x4f\x0d\xec\xd7\x35\xdc\x36\x90\x0b\x0b\xe9\x6a\xe5\x4b\xdf\x37\xe1\x1a\xd7\x53\x0b\xc1\xb8\xae\x0b\xdf\x2f\x20\x5f\x69\x43\x3d\x22\xef\xe9\x53\xb8\xaa\x58\xd7\xa3\x36\x5d\x42\xb5\x05\x92\x9c\xcc\x25\x74\xb5\x65\x7a\x50\x33\x99\x90\x8d\x16\xb2\xf9\xbe\x79\x32\x5a\xba\x35\xc6\x8b\xd8\xf7\x47\xfb\x96\x50\x49\x5e\x3c\x2e\x92\xfc\x8e\xdb\x5d\x61\x12\x4c\xa9\x2d\x71\x70\xe7\x95\x6b\x50\x89\x18\x49\xda\x8f\x46\x37\x08\x3b\xb1\xb1\x76\x46\xc9\x59\xca\xcf\x2a\x6c\x16\xd4\x6a\xdc\x92\xb1\x84\x0a\x00\xd4\xd1\x0c\x2f\xfa\x26\x25\x15\xc0\xa4\xcd\xed\xa9\x46\xce\x14\x48\x7a\x12\xec\x0d\xba\x1d\x66\x5c\x8c\x9c\x16\x94\x22\xea\x00\xd1\xd7\xbc\x29\x79\xa5\xea\xd6\x26\xbd\x97\x5c\x5b\x46\x91\xc3\x37\x78\xa6\xb5\xba\x1e\x22\x2b\x61\xa5\xfc\xad\x01\xb4\xad\x8f\x40\xd6\x7e\x3d\x34\x20\x93\x04\x8f\x0d\x15\x11\x74\xbe\x10\x47\x1a\x6f\x70\x83\x52\x86\x22\x6a\x4d\xad\x75\x4c\xd5\xaa\x85\x74\x88\x03\xa1\xf4\x5c\xa3\xb5\x64\x46\x5e\xea\x29\xa8\x6b\x58\xbb\x4e\x9a\x73\x5f\xbe\x82\xe3\xa7\xe9\x9f\x46\x44\xa5\x9b\x81\x64\xca\x21\x8b\xf6\xc2\x90\xd2\x38\x14\xf2\x48\xe4\xfb\xa3\x6a\x9a\x96\x0e\x9f\x71\x25\xf2\xfd\x9e\x25\x08\xe3\x43\x35\x5d\x57\x45\xc1\xb8\xd0\x1d\x4b\xa7\x2c\x63\x3b\xc2\xdb\x7a\x72\x9a\xda\xe6\x42\xee\x54\x38\xc4\xc1\xb4\x35\x57\xd3\xc2\xee\x14\x0d\x96\xf9\xd4\x4d\x71\x33\x98\x33\x9b\xbb\xb7\x50\xa5\x9b\xfd\xee\xfa\x37\x9a\x93\x6a\x2a\x89\x12\xcd\xe1\xa7\xb5\x0a\x43\x05\x45\x47\x9c\x6a\x6e\xf7\xb3\x66\x59\x55\x45\x75\x9d\x9b\x91\x60\x4d\xdf\xf5\x70\x4b\x08\x73\x21\xcf\x06\xa8\x9a\x16\xac\xac\x32\x41\x41\xee\x5e\x1d\xb3\x8b\xd5\x31\xc3\x8b\xed\xc1\x72\x3d\xdd\xe7\xa5\x30\xcb\x07\x7e\x25\x9d\xf7\xce\x72\x12\xd3\x12\x58\x72\xa9\xf9\x1d\x56\x94\x92\x8e\xbb\x6b\xd1\x45\x16\xe0\x34\x5e\x45\x17\x01\x48\xf3\xfd\xcc\xb5\x83\x41\x1e\x1c\x57\xdd\x70\x09\xf3\x0b\xca\xa6\x2a\x24\x83\x36\x4e\xcd\x46\x54\x39\x18\xca\x68\xd6\xb9\x94\x0e\x2c\xab\xf6\xc8\xe5\x56\x6b\x6a\x1d\xb5\x41\x1e\x46\x72\x35\x32\x1b\xdb\x1c\x6b\xb7\xb4\xca\x57\xc6\xa1\x21\x2a\xb4\x41\x05\x82\x2d\xcb\xdf\xc6\x61\x2a\x57\x10\xbc\x9e\x5a\x7c\x68\xa2\xe4\xc6\x61\x1a\xd1\xa2\xc3\x46\xc0\xe5\x4e\xa4\x5c\xac\x68\xe3\x1c\x94\x61\xed\x92\x49\xa7\xeb\xd8\xb5\x99\xa5\x6a\x98\xc4\x10\x6e\x34\xb7\xd1\x07\xf2\xd6\xa5\xa6\x76\x29\x2b\xa1\x20\xc8\xda\x75\xc8\x1b\xbb\xa4\x99\xda\xac\xd5\x85\xf8\xd3\x52\xe6\x86\x65\x25\xd9\xfc\x12\x78\x71\x09\x27\x1d\x7e\x1c\x1f\x86\x8d\x49\x8f\xce\x0e\x44\x90\x03\xe3\xd5\x8e\x19\x3b\xd2\xbe\x5d\x29\xd8\x77\x82\x9f\x18\xf7\x6a\x8b\x36\x92\x92\x1b\x20\xe5\x71\x06\x95\xda\x93\xd1\xd0\xb7\x8e\x7e\xf2\xd1\xe2\xc7\x5f\x42\x11\xf5\xed\x5a\x4f\x8d\x4f\x9f\x79\xff\x64\x48\x77\x45\x2a\xcc\xb3\x3a\x71\xa9\x10\x11\x0d\xd9\xa4\xc3\xce\x47\x42\x6b\x2f\x1c\x2d\x59\x20\x09\x85\x9e\x49\x30\x9b\xd3\x18\x21\x38\x64\x79\x9c\x04\x07\x9e\x7f\x51\x5d\x6b\xab\x5c\x02\x20\x1c\x1c\x80\x81\x1c\xb0\xa1\x94\x1d\xae\x6b\x2b\x38\xd8\x6b\x24\x25\x8c\x4f\x4d\x31\x85\x0a\x7c\xff\x05\x12\xc4\xe8\x33\x7c\xff\x05\xb8\x5f\x54\xdb\x43\x9e\xd1\xc8\x68\xde\x10\x7d\xe0\xf8\xff\xa6\x15\x4c\xe4\x68\xac\x18\x7d\xc0\x1a\xd4\xe0\x87\xff\xb2\x11\x4d\x45\x6d\x3b\x75\x0d\xdf\x63\xa0\xdc\xd7\x6c\x93\x17\xac\xe2\x6a\x62\x5d\x2c\xd7\xed\x81\x41\xd4\x4c\x63\x3b\xdf\x67\x5d\x18\x02\x23\xd8\x4e\xca\x54\xf5\x13\xf4\x21\xb6\x1c\x6e\x9a\x46\xdd\x4b\xb1\xac\xcb\x91\x15\x3e\x1b\xba\x29\x22\x1b\x1c\xba\x40\xa2\x8c\x1a\x35\xb0\x1c\x87\xf2\x1e\x01\xc4\x76\xdc\x56\xa9\xac\xad\x9f\x58\x17\xd6\x88\x80\xdb\xa8\xfa\x34\x39\xb0\x89\x8c\x9f\x27\xb0\x5e\x57\xd9\x54\x42\x5a\x6a\xda\xf2\xbd\xa2\x34\x2c\xa1\xd6\x8b\xa5\x4d\xaa\xeb\xd6\xb0\xef\xe8\xa3\x26\x5d\xcc\x9d\xb7\xe5\x25\x0b\x5e\x99\x26\x15\x69\x37\x60\xe0\xfb\xcf\x15\x35\x80\x37\xc7\xfe\xd8\xa4\xb4\x14\x20\x30\x69\xaa\xa2\x2e\xab\xc0\xba\xef\x2a\x0b\x78\xb2\x65\x89\xcd\xd2\x79\xd7\xfa\x4f\x35\x05\x44\xa8\xf3\x22\x9c\x41\x8d\x7d\x93\xfa\x9e\xee\xd8\x95\x88\x77\x7b\xaa\x66\xd4\xbc\xd6\xf5\xcb\x58\xb0\x29\xcf\xef\x90\x96\x15\xb5\x7b\x9f\xca\x3d\x70\x84\x43\xe9\xc1\xf1\x4e\x16\xe8\xcf\xe4\x78\xc6\xe5\x54\x0d\x71\x48\x2a\xfd\x11\x46\x47\x65\xb8\x4a\x77\x15\x0c\x33\x18\xcd\x49\x97\x61\xe8\x5f\xa0\x66\xf4\x18\x34\x16\xa7\xe0\xe0\x92\x11\x49\xc3\xf5\x67\xdb\x0a\x04\xae\xea\xb1\x25\x0d\xe9\x71\x25\xff\x4d\xc3\xc7\xe3\x7a\xac\xe9\x23\xf6\x47\xb5\x3d\x34\x4b\xff\x4d\x27\x1e\x99\xe5\x3f\xeb\xcd\x09\x59\x9f\x52\xc2\x1f\xf5\xd6\xfa\x23\x39\xc4\x99\xf8\x27\x7b\x90\xb4\xe6\x1a\xc8\x02\x78\x39\x5b\xcb\xed\x9e\x59\x02\xb5\x8d\xf9\x0d\x4b\xde\xe5\x15\xf8\x98\x97\x29\xa2\xc8\x74\xa9\x84\x89\x38\xcd\xe4\x13\x2c\xc6\xf7\xdb\xb8\x84\x42\x3b\x26\x62\x9d\x65\x1f\xdf\xb0\x9f\xcd\xc3\x2f\xf2\x01\x2c\x32\xf5\xd7\xdb\x94\xdd\xc9\x5f\x6f\xbd\x8d\x0b\x4f\x11\xc4\xc4\xb4\x5b\x5c\xea\xe7\x0f\x2a\xf3\x07\xf6\x60\x52\x74\xa4\x2e\xfb\xa4\x3a\x96\xa5\x8c\x8b\x9f\xdb\x47\x68\x2e\xdf\x6c\x4a\xa6\x52\xd5\x23\xa4\x6a\x15\xc7\x9b\xc4\x79\x81\x43\xb8\xec\xe0\xba\x60\x8c\xff\xdc\x3e\x42\x09\x85\x07\x9c\x79\x10\xb9\x56\x40\xa8\x17\x9b\x7e\xb7\x4d\x87\xce\x73\x96\xe7\x5c\xf4\x7c\xf0\x42\x7e\xdf\xbf\x36\x8e\xa2\x15\x51\x5a\x5a\x9f\x45\x7a\x22\x96\xed\x63\xc0\xa6\x76\x2e\x6c\x79\xf7\x6e\xc3\x5d\xaf\xae\xb9\x2f\x96\xf3\xe0\x99\x2f\x96\xcf\x83\x8f\x7d\xb1\x7c\x16\xcc\x02\x5d\x50\x41\x83\x11\xac\x4a\x40\x69\xdd\x73\xa9\x10\x7a\x4a\x9d\x92\x72\x8f\x5c\x67\x55\xa1\x5f\xf3\x4a\x78\x4d\xef\x26\x72\xff\x14\xc2\x22\xda\x67\x2e\x2c\xdb\xf2\xc2\x18\x57\x92\xab\x53\x2c\xc2\x71\x5e\x45\xe8\x3b\x32\x13\xe1\xba\x13\x03\xed\x95\xc4\x1c\x45\xe0\xc1\x73\x7e\xcb\x0a\x8f\xc0\x63\xc6\xe2\x5b\x66\x92\x2b\xe1\x99\x45\xd7\xd9\xf5\x9b\x2a\xa0\x5f\x74\x11\xf3\xa9\x3f\xe2\x74\x78\xc4\x9d\xee\xa5\xc4\x88\x74\x82\x54\xb3\xc9\x83\x31\xc7\x7b\x74\x02\x94\xe1\xf6\xf0\xe7\x7a\x73\xe5\x94\x6a\x96\xa9\xef\xd5\x8f\x43\xb8\x08\xb5\xe2\xb4\xb0\x07\x40\x22\x68\x61\xc5\x76\x83\xda\x1c\xa2\xcb\xa4\x98\x88\xe6\xc8\x60\xb8\x13\x0f\xcf\x18\xff\xe9\x0e\x7d\xb0\x8b\xa8\xd2\x1b\x92\xf3\x63\x11\xde\xa9\xec\x64\x2e\x0b\x6c\x36\xa7\xee\x84\x81\x19\xfb\x31\xaa\x97\x29\x76\x6a\x0c\x2b\xd2\x99\x2f\x72\x85\x58\x4f\xde\xa0\x34\x5a\x45\x7b\xbe\x5e\xb6\x33\x34\xf6\xa6\xde\xd8\xf9\x14\x38\x93\x57\xd8\x43\x19\xb1\xb3\xa8\xf0\xea\xa0\xde\x50\x07\xe3\x49\xcf\x52\x7e\xc6\xb0\x42\xf5\x9b\x8d\x3c\x97\x11\x16\xa6\x83\x3e\x35\x41\x30\x20\x7c\xbf\x75\x2c\xd1\x1a\x5e\x43\xf8\x0f\x41\x84\x55\x33\x02\x9b\xa3\xc0\xe0\x95\xf6\x2b\x78\x52\xcf\xd6\xb9\x3e\x40\xb8\xb2\x85\xd6\x06\x54\xdf\x32\x7a\x7e\xa1\x34\xca\xf5\x05\x18\x92\xd5\x17\x59\xca\x3f\x9c\xa7\xe4\x25\xa3\xe7\xda\xd6\x67\x55\x3e\x45\xcb\x20\x7c\x4f\xa3\x9a\xae\xca\xa7\xc6\x04\x68\x8a\xcf\x53\xf2\x1b\xa3\xe7\xef\x57\xe5\xd3\x8b\x11\x5a\x06\xab\xf0\xf2\xe5\x8b\x77\x2f\x56\x61\x3d\x99\xe0\x5a\x26\x44\xab\x48\x3e\x7f\xbe\x2a\x9f\x3e\x71\x2f\x45\xfd\xde\xd5\xf1\x2a\xb7\x6a\x92\xd4\x00\x4f\x8f\x8e\xfd\xfb\x09\xd7\x27\x9c\x27\x0a\x99\x0f\x3c\xfb\x1a\xdf\x70\xc8\x03\x63\x0f\x0f\x87\xb3\xa8\xae\x1d\x5f\x62\x5f\xb3\xce\xa5\x4e\x00\x71\xa4\x90\xea\xa9\x30\x89\x63\xef\xdc\x1b\x6b\xd6\xd4\xa9\xe9\x2b\xa7\x26\xb8\x4b\x75\xae\xec\x6c\x5b\x0d\xbb\x8d\xe4\xf3\x09\x5e\x32\x97\xc3\xb5\xd7\x64\x02\xc3\x83\x1f\xb5\xea\xb6\xf4\x1d\x1b\x94\x7b\x2c\xb4\x04\x42\x74\x7d\x82\x77\x65\xdf\xa8\x34\xda\x32\x6c\x65\xde\x16\x18\xad\x10\x52\x1c\x09\x21\x49\xa9\xbd\x72\xce\x48\x41\xcb\x30\x8d\xfa\x56\x38\x1d\xc5\x2d\x49\x89\xcc\x13\xf2\x08\x2f\x7e\xe8\xb6\x9f\xd3\xf6\x1e\x16\x26\x31\x75\x7d\x98\xe5\x98\xe8\xab\x33\x04\x02\x61\xd9\x11\x7f\xcf\x90\xd5\xc8\x17\xf4\x06\x69\x67\x67\x12\x13\x58\x81\x3f\x18\xa7\xda\x7b\x22\x7b\xba\x99\xcc\x49\x42\x41\xe1\xb8\xa5\x3b\x94\x80\xb8\x7f\x5b\xd7\xf3\x8b\xcd\xc0\x65\x4b\x79\x3a\x70\x4d\xde\x7c\xff\xa5\xa6\x8e\x49\x7b\x92\xe9\xed\x22\x27\x38\x2d\xfb\x1d\x31\xbc\xd8\xfa\x3e\x68\x38\x69\xe2\x7a\xf0\x24\x02\x8c\x52\x10\xc6\x98\x7c\xcf\x90\xbe\xd0\x85\x1b\xe8\xd0\x06\xac\xef\x11\xa3\xf7\x0c\x15\x84\x87\xb3\xa8\x67\xa9\x3a\x9a\x13\x4e\x72\xdc\xf1\x7a\xa8\x8e\x31\xad\xa1\x4a\x2b\xe3\x66\x54\x9e\x0e\xea\x3a\xd7\x82\xa5\x92\xa2\x58\xbb\x0b\x54\xb2\x65\x6b\x20\xf2\x35\xb3\xc1\x44\xac\xf9\x68\x45\x19\x59\x8f\x28\xdd\x83\x52\xe4\x4a\x59\xe2\xa1\x8a\x8c\x66\x10\xa6\xab\x94\x27\x11\x65\x28\x13\x93\x5b\xf9\xc1\x56\x87\xb1\xb9\x20\xc3\xc3\x75\x44\x2a\xb2\x86\xd1\x29\xa0\xc9\x68\x1c\xc6\xad\x87\xe5\xde\x00\x55\xef\x62\xf2\x15\xc3\x44\xd9\xb2\x96\xba\x33\xb1\xac\xca\x58\xaa\x54\xae\xa5\xca\xc8\x5e\x86\xa9\xba\x76\x5d\xb2\x87\x96\xe0\x65\xa4\x52\xc2\xc9\xb2\x58\xfb\xbe\xa7\x4c\x38\xbd\x11\x48\x2f\xdb\x4d\xd9\x0d\xfc\x70\x35\xfd\x95\xdd\xc6\xd9\x8f\x45\x06\xb2\x57\x9e\x7f\x03\xa5\x64\xbd\xe6\x83\xaa\x90\x1c\x78\xce\xd7\x2c\x90\x79\xf8\x9a\xd5\x75\xd5\xc3\x16\x90\xec\xe1\x86\x64\x38\xb8\x96\x2d\xb6\x86\x40\xf6\xde\xe6\x6f\x0c\xa2\x40\x54\x24\x6b\x65\xa3\x8e\x01\xdc\x5b\x76\x14\x99\x8f\xa4\x54\x2c\x1d\x97\x8d\x0c\x07\x8c\xe4\x74\xb6\xd0\xc1\x82\x0a\x15\xfb\x6e\x91\x8f\xc7\x98\xd7\xf5\x7c\xe4\xfa\x6d\x07\x76\x20\x63\x31\x87\xed\x78\x0b\xd7\x3f\x49\xd1\x89\xf5\x8b\x38\x58\xfb\x17\x2a\x0e\x89\xcc\xe2\x2c\x72\x27\x6f\xc7\xbe\xb9\xc0\x1d\xb3\x62\x7b\x8b\xd3\x35\xc6\x1a\x94\x4b\x81\x57\xe1\x23\x76\xa0\x13\x4c\xd3\x6e\xf0\x9e\x69\x28\xd9\xd0\xd4\xdc\x03\x1f\xa1\xbe\x2d\xa9\x1a\xbb\x7b\x0d\x60\xde\x4d\x50\x57\x8d\x55\x44\x07\xc4\xb0\x42\x83\x60\x56\xb5\xc6\xda\x9d\x31\xca\xe5\xab\xb3\x51\x6c\x24\x44\x9a\x87\x45\x44\x24\x88\x16\xc6\xae\x91\xb4\xe1\x37\x50\x46\xab\x53\x11\x38\x7c\xdf\xc8\x95\x4a\xcd\x76\x57\x86\x64\xd2\xd2\x3c\x05\xba\x2e\x75\x49\xc1\x33\x26\xb3\xf0\x0e\x22\x7f\xd7\x16\x96\x96\x9d\x57\x98\x0f\x01\xde\x91\xb1\x92\x2d\xe7\x75\x0d\xc3\x20\x60\x97\xe7\x0e\x30\xef\x0f\xec\x3b\x86\x60\x64\x31\xf8\xf6\x06\xc5\x16\x50\x9b\xb5\x5d\xde\xd9\x85\x9e\x24\x07\x2e\x2c\xfe\x79\x90\x98\x61\xb4\xf1\xfd\x2e\xb2\x81\x70\x4b\x16\xf0\x8e\xa2\x43\x3b\x8a\xac\xbe\x66\x09\x40\xbb\xd5\x62\x70\xca\x2c\x74\x83\x11\x06\xc7\xda\x73\x3a\x0f\x7f\x69\x2f\x7d\x43\x92\x21\x6f\xad\x03\x00\x93\x92\x86\x45\xb4\xec\x31\x40\x92\x03\x0d\xba\x1a\x3f\x30\xd2\x32\x1a\xbf\x85\xdb\x80\xe6\xb4\x1a\x1e\xfe\xe0\x38\x01\x40\xee\xab\x61\xc6\x8e\x59\xe5\x04\xe2\xee\x0c\x6d\x86\xb7\x96\x0f\x73\xae\x83\x3e\x9a\x11\x0f\xc4\x89\xd6\x79\x06\x2e\xc0\xf6\xfd\x0e\xb0\xa5\x0a\x72\xa2\xec\xe7\xb5\xd1\x3d\x44\xd0\xc6\x47\xfc\xe2\x5c\xeb\x3e\xfa\xfb\xa9\x97\xf6\x59\x3f\xa9\xae\x95\x90\xcf\x35\x83\xec\xdc\x88\x3d\xd2\x54\x36\x44\x19\x35\x0e\x1c\xf1\xbe\x67\xbd\x53\x49\x67\x78\xff\x7b\x17\x7f\xb7\xf3\xd9\x31\xa8\x54\xfd\xdc\x17\xec\x7f\xea\x8e\xe1\xc6\xba\x4d\xcd\x07\xd2\x3e\xeb\x27\x19\xbe\xa2\xed\xd7\x42\x4c\x53\x5e\xb2\x42\x7c\x01\xf2\x64\x70\xab\xe6\xfa\x35\x96\x1d\x55\xa2\xe6\xff\xba\x9f\xd0\xb2\x4b\x02\x7a\x09\x47\x0d\x2b\xfb\xac\x86\xc4\x1b\x31\x78\x10\xff\xbf\xdf\x5c\x27\x18\x8d\x6c\xfa\xc8\x3d\xa9\xf5\x69\x0f\xaa\x5d\x4d\x0b\x95\x18\x2d\x14\x11\x06\x95\x73\x3f\x8a\x0d\xea\x11\x43\x06\x61\x33\xe4\x39\xb7\x63\xb2\xdb\x3d\x8e\x0d\x90\x2b\xc7\x16\x55\x4b\x63\x7c\x9f\x69\x4f\x38\x94\x8a\x25\x0b\xb4\xd0\x57\xf2\x39\x83\x97\xdc\x80\xcd\x32\xcc\x22\x0c\x50\x12\xce\xbf\xb8\xab\x5b\x05\x09\x9c\x6d\x94\x0e\xb1\x1b\x18\xa5\xe3\x22\x80\x29\xa7\x12\xce\x29\xc1\xfa\xbd\xb1\xc6\xd4\x83\xae\x55\x98\xef\x8f\xbe\x75\xe2\x94\x8d\x6e\x58\x68\x8d\xb7\xd9\x63\xc6\xdb\x11\x3e\x30\xda\x37\xcd\x96\x40\x5d\x3c\xc0\xca\xd9\x43\x04\xa8\x96\xf5\x60\xb8\x56\x4a\x9f\x5e\x30\xa1\x16\xcc\xe9\x37\x95\x95\xd2\x99\x6b\xeb\x2b\x34\x84\x19\xc4\xa6\x36\x38\x68\xbd\x4e\x63\x20\xcd\x9f\x75\xbd\xc7\x9a\xab\xda\xa1\x75\x14\xf2\x38\xa4\xb7\x0b\xe3\xba\xa9\x77\x5c\xf8\x2a\x79\xcc\xc5\x6c\x60\x64\x10\x5b\x46\x85\xf6\xd0\x7d\xd1\x28\x49\x87\x9d\x69\x08\xef\xb8\xc8\x57\xa3\x7a\x97\x07\x9e\x7a\xf2\x0c\xda\x92\x49\xfa\xd1\x23\xee\xd6\x0a\x3c\x85\x2f\x4c\xea\x0b\xd8\xcd\x1e\x6c\x6a\xcf\x4c\xc0\x8b\x2c\x0b\x3c\x67\x32\xba\xa2\xad\x58\x7b\x29\x67\x11\x3d\x41\xd2\x69\x18\x91\x82\x82\x9f\xa7\xd4\x46\xcc\x9b\xcc\x81\xaa\xe7\x17\x34\x05\x42\x2e\x68\x0e\x7e\x45\xda\xcb\xdf\x6a\x43\x48\x16\xef\x0a\x15\x92\xe0\x87\x71\x84\x04\x26\x95\x75\xde\x29\x54\x1c\x82\xce\xde\x1c\xf4\x3b\xfe\x4d\xff\xaa\xb0\xb9\x1e\xbc\x1c\xed\xef\xb1\xba\x23\x3c\x36\x57\x84\xdf\x74\x8d\x24\x8d\x40\xb6\x73\x5e\xb1\xbc\x56\xca\xee\x9c\x98\x03\x62\x9a\xef\x19\x67\x05\xf8\x4f\xba\xc4\xaa\x83\x97\xf9\x6e\x5f\x09\x96\x5c\xa9\xcb\x9d\xb8\x21\x3f\xb1\x53\xe1\x6c\x48\x4e\xb5\xf1\x4c\xaa\xbc\x15\xe5\x61\x1a\x99\x9b\xb8\x61\x1a\x91\xf6\x91\x8a\x30\x8d\xda\xac\x05\x35\xf6\x4b\x98\x08\xec\x64\x93\x35\xb4\x41\xf5\xc9\xeb\xce\x54\x70\xa6\xcd\xc2\x6a\x0f\xc3\xe8\x1d\xcf\x73\x6c\x90\x0b\x37\x9d\xd1\x55\xaa\x50\x3b\x6f\x80\x3f\xf6\x7d\xe4\xc1\xc1\x2a\xa6\x5c\x0e\xdc\xa8\xb3\x81\x21\x05\x87\xda\x5c\xa2\xe1\xba\x06\x86\x1d\xcc\x52\x9d\x2b\xaf\x18\x93\xd1\xc3\x74\x9f\xde\xb3\xec\x8b\xfc\x1e\x26\xab\x44\xd8\xf7\xbf\xd1\xc8\x26\xc6\xbe\xff\xda\x28\x63\x95\x6f\x91\x72\x0a\xf1\xfe\xc0\x19\xe3\x2e\xe5\x3f\xc1\x4b\x2e\x5f\xe2\x7b\xf5\xd2\xa6\x3b\xa9\xa6\x1c\x8d\x89\xec\xe9\x9d\xce\xa9\xd2\x0a\xb7\x4c\x4a\x9c\x52\x39\x76\x1c\x2c\xc5\xcb\x78\xec\x79\x81\x13\xc0\xfd\x49\x47\x5c\x75\xe8\xf8\x93\x52\x4a\xd2\x36\xf4\x9e\x0d\xa2\x41\x05\x3e\xe1\xad\x57\xdb\x96\x99\x8c\x4d\xd3\x8c\x5c\x4a\x67\x5a\x65\xaa\xee\x0c\x1f\x2a\x7d\xcb\x73\x5d\x96\xef\xd8\xbd\xa0\xde\x5e\x07\x6a\x0c\xe2\x6b\x70\x57\xcb\x16\x19\xdb\x88\x60\x32\x97\xff\xed\xef\x17\x30\xde\xe0\xd3\xd9\xfe\x7e\xb1\x8b\x8b\x9b\x94\x4f\x44\xbe\x0f\xe4\x97\x7d\x9c\x24\x29\xbf\x09\x66\x8b\xeb\xbc\x48\x58\x11\xcc\x3c\x92\x9d\xac\xde\xc4\xe3\x5c\xe8\xfb\xa5\x01\xdc\x69\x5d\x5c\xe7\xf7\x93\x32\xfd\x43\xd6\xa3\x6a\x99\x5c\xe7\xf7\x8b\xfc\x96\x15\x9b\x2c\xbf\x0b\x4a\xf0\x9a\xa7\x5b\x0e\xe2\x4a\xe4\xa6\x31\xb7\x07\x6e\x3f\xff\xbe\x80\xfe\xfd\x5d\xe2\xa5\x0e\x87\x56\x75\x19\xb6\x4c\x8b\x85\xe8\xe5\xf1\xee\xcb\xf0\x82\x53\x6f\xfe\x77\x6d\x8c\x93\xef\x49\x49\xe7\xcf\x24\x21\x04\x87\xfb\xb2\x2f\x5f\xb3\x8d\xc0\x76\xb8\x45\x7a\xb3\x15\xd4\xfb\x74\xf6\x77\x8f\xe4\xf4\xf9\xa7\x3a\x2b\x24\xcb\xf3\x93\x4d\x81\x5e\xb6\xe5\xcc\xec\x50\xcf\xcc\xbe\x47\x52\xd3\x54\x36\x55\xda\x25\x80\xab\xf3\xe7\x58\x0e\xc8\x3d\x47\x57\x58\xbb\xef\x73\x84\x5f\xc2\xa1\xff\x2a\x98\x70\x5e\xf1\x04\x81\x97\xa5\xd7\x59\x1e\x43\xfc\x9c\xe6\xe8\xce\xf6\xf1\x65\x52\xb8\x72\x45\xb2\x13\x1f\x16\x99\xbd\xc0\x6d\x86\x72\x1d\xaf\x3f\xdc\x40\x6b\x97\x59\xba\xa7\x9e\x8e\x64\x21\x97\x53\x82\x45\xf7\xa2\xe6\x70\x11\x8f\x3c\x00\x69\x2b\xe0\x6c\x0e\x4b\xd1\xad\x07\x4c\xa6\x86\xca\xb6\x5e\x6c\x1e\xc8\xe1\x3a\xbf\xbf\x02\x88\x7a\xcb\xb2\xf4\x84\xc7\x79\x86\x30\x29\x1a\xd2\xc5\x23\x27\xf2\xe5\x3a\x9f\x09\x69\x7a\x22\x1b\x97\xac\x80\x6a\xf0\x1b\x0b\x22\x27\xf2\x96\x0d\x51\x90\xad\xfa\x7a\xaa\x87\x69\x5b\xe5\xbb\xe2\x65\xba\x63\xbc\x4c\x73\x5e\x1e\xa9\x80\x95\xf6\xa3\xab\x05\x8c\x41\xc2\x77\xb4\x7c\x5a\x34\x4e\xc4\xc0\xa7\xc2\xc3\x84\x9f\x02\x05\xf6\x5f\x22\x0e\x0f\x9c\x39\xcb\x12\x2a\xe8\x2a\xf5\x20\x91\xf7\x12\x3f\x93\x89\xbd\x9d\xda\x3b\x5a\x89\xee\x2b\x97\x1b\x6a\x60\xd3\x0a\x4c\x62\xfa\xfc\x02\x40\xfd\x0d\x17\xa8\xd0\x6d\x1c\xed\x1b\x86\x31\x89\x9b\x06\xe3\x06\x29\x1c\xf0\x2b\xa3\xa1\xf7\x13\xbb\xfe\x90\x0a\x8f\x78\xdf\xe4\x7f\x78\xc4\xdb\x95\x5e\x44\xfe\x18\x98\x40\x98\x0d\x35\x08\xf2\x63\xd7\x2d\xc2\xcf\xcc\x89\xb5\x25\x27\x4a\x92\xb6\x32\x64\x51\x5d\xff\xc8\x42\xd6\x71\x9c\xc8\x24\x35\xfe\x83\x2d\x59\x00\x9f\x86\x78\x09\x08\x36\xec\x7a\x97\x1c\xb3\xf6\xe6\x0b\xa7\xbf\xb2\x63\x67\x79\xca\x6f\xf9\xaf\x2c\xe4\xd1\x58\x60\x68\xc1\x1a\xaa\x35\x40\x4d\x99\x76\x37\x09\x37\xed\x78\xce\x59\x0d\x10\x81\x96\xa3\xc9\x3a\x64\x71\x84\xa7\x63\x7c\x4e\xbe\x94\x9f\x27\x93\x73\xf2\x0b\xa3\x07\xbb\xd0\x0e\x92\xba\x4d\xcb\xf4\x3a\xcd\x52\xf1\x10\x78\xdb\x34\x49\x18\xf7\x88\x41\xec\xda\x5b\x41\x43\x7e\x60\xf4\x90\x31\x21\x58\x71\xb5\x8f\xd7\x12\x51\x7b\x33\x8f\x6c\x72\x2e\x7e\x82\x95\x09\xbc\x8f\x67\x33\xcf\x99\xc0\x7f\xb0\x5e\xe0\x49\x63\x27\x6f\x79\xb7\x62\x09\x58\x6d\x17\xdf\xa3\x19\x29\xc2\x67\xd1\x04\xf1\xba\x9e\x61\x3c\x46\x05\xb8\xf9\x00\x9f\x1e\x81\x68\x31\xe2\x3f\x87\x2e\xe9\x51\x4f\x85\x00\x06\x7f\x8d\xf3\x60\x46\x94\x5b\xd4\x99\x8a\x0a\x48\x29\x2a\x96\x9e\xa2\x33\x5e\x60\x30\x90\x67\x65\xfb\x33\xe0\xa7\x16\xf1\xc5\xc7\x8b\x78\x4c\x9f\x61\x4f\x91\x04\xe3\xb0\xa2\x1a\x5b\x9f\x27\x7c\xcc\x59\x18\x83\xb3\xd4\x14\x63\x52\x2c\x91\xad\xcd\x64\x9e\xb4\x0e\x52\x34\x39\xf3\xba\x85\x4c\xed\xa3\xe3\x02\xba\x8b\x2a\xff\xd8\xfb\x49\x85\x35\x56\xe5\xc0\x27\xfc\xe3\x75\xb7\xa9\xe0\x0b\xd2\xcd\xfe\x48\xcd\x41\xf9\xd7\xf2\x99\x35\x1b\x15\xbe\x3f\xbb\x80\x1b\x82\xd5\x98\x3a\xcb\x07\x8f\x6b\x96\x66\x88\x85\x9e\x22\x75\xde\x58\x1c\x43\xbd\xb0\x50\x1f\x4d\xf2\x49\x35\x29\x27\xd3\x4f\x30\x96\xab\x4e\xaa\x76\x9d\xff\xdd\x83\x1d\x60\x36\x49\x4a\xd1\xe8\x61\x7a\x44\x11\x90\xe4\x32\xb1\xef\x7b\x2d\xcf\xd1\x71\x55\x63\x0b\x78\x64\x34\x27\x05\x26\x39\x4d\x49\x4c\x35\xb3\x5b\x60\x52\xd2\xbf\xd6\x63\x09\x50\x2d\x6b\xda\x0b\x31\x1d\x2f\x62\xea\x49\x9e\xc6\x33\xd1\x10\x87\xfb\xea\xfb\x69\x5d\x8f\x1e\xa6\x43\xb4\x00\x61\x75\x39\x1e\xb0\x77\x5d\xab\xea\x28\xa5\x71\x5d\x8f\x1c\xaa\x2f\xd9\x62\x2f\xe5\x59\x7a\xc2\x27\x8f\x1a\x26\x84\x1d\x90\x88\x15\x6c\x5d\xde\xb2\xb5\x28\x11\x76\x9d\x03\xfe\xe5\xf9\x42\x39\x2d\x95\xca\x1a\x2e\x86\x82\xc7\x14\xb8\x6f\xd6\xe9\x93\x5c\xc3\xb1\xd9\xa0\x75\x8d\xd2\xa1\x5d\x47\x72\x52\x90\x18\x8f\xe5\xce\x6e\x97\xdb\xb8\x87\x54\xf7\x79\x1c\xf3\x41\xe6\xd8\xaa\x41\x4c\x50\x27\x9f\xa3\x6d\x58\x97\xa5\x72\xb0\x76\xc8\x25\x6e\x12\x0f\xc1\xe1\xd8\xb7\x2b\x08\xc7\xf5\x49\x1e\xd6\xde\xd3\x99\xad\xa0\x07\x5c\xcc\xf0\xa5\x37\xf7\x02\x0e\xd6\x94\xd6\x79\x50\x70\x88\x79\xba\x03\x03\xa9\x37\x82\x15\xf0\x00\xd6\xe5\xca\x24\x29\xab\x76\xed\xeb\x26\xcd\xb2\xef\x74\x37\xe4\x6b\xc6\xee\xbf\x2c\xf2\x3b\xf3\x7c\xb5\x2d\x52\xfe\x01\xde\x5a\xdc\x39\x9a\x91\x9b\x22\x4d\x5e\x14\x2c\x36\xcf\x97\x50\x6b\xf7\xed\x15\x4f\xba\x09\x57\x22\x2e\x6c\xe9\xb7\xaa\x11\xfd\xe8\xe4\x7d\x9b\xdf\xd9\x8c\x12\x68\xbe\xb2\x8d\xe6\x6d\x3f\x15\x23\x0e\x0f\xfb\x6d\xac\x2c\xa6\xee\xd2\x24\xbf\x83\xa7\x3f\xde\x40\x74\x43\xf9\x94\xe7\x3b\x65\x1e\xac\x49\x62\x70\x68\x08\x50\xd0\x01\xcb\x0e\x65\xa2\xf1\xbc\xa7\x8f\xf9\x7f\x7b\xef\x9a\x1b\x71\x9c\x46\x91\x12\x3c\xcb\x92\x8a\x7e\x69\x8f\x7f\x60\xc8\xaf\xce\xa1\xe9\x06\x55\x70\xde\xfe\x99\x81\x4b\x9e\x58\x01\x2f\xc0\x00\xf8\x79\x72\x5e\x4b\xc7\xfd\x44\xbb\x59\x7d\xdf\xbb\x61\xc2\x4b\xe1\xb1\x55\x33\xa4\x34\xd6\x37\x4a\xd5\x16\x5a\xa6\x41\x16\x8a\x68\xd1\x8a\xc4\x28\xca\xed\xb5\x6b\x0c\xdb\xc8\xd0\x35\x8e\x21\x58\xcb\x1c\x14\x02\x54\xfb\xc2\x4a\x25\xb6\xf1\x38\x00\x91\x64\xc8\x40\x4c\xc8\x7d\x9f\x2b\xfc\x6f\xbe\x8c\x28\xcd\xeb\x5a\x8e\x89\x8f\x69\x2a\xab\x39\xf2\x72\x55\xb6\x5e\xae\xf0\x31\x6b\x5d\xd7\x70\x0c\x97\xe4\x13\x4c\x24\xac\x5f\xce\x96\xb5\x96\x18\x05\xc9\xd1\x50\x2f\xe5\x5b\x56\xa4\x72\x3b\xca\x89\x28\x7b\x13\x41\x41\xdf\x12\xeb\xdb\xd5\x10\x89\xa3\xae\x51\xb5\xcc\x64\x4a\x6b\xaf\x4e\x38\x86\xc9\xa1\x1c\x82\x88\xac\x8f\xfc\x1d\x77\xdc\x80\xe9\x15\x35\xa4\xbf\x5d\x56\x77\x1d\xd1\xe3\x0b\x89\x3b\xab\xe6\x2e\xd6\x0c\x22\xd8\xd9\xee\x2b\xdf\x8f\x16\xc1\x83\x0b\xa6\x62\x17\x67\xda\x2f\xa4\x90\xc8\xec\x07\xa6\x3c\xa4\x42\x28\x56\xe5\x5d\x8a\xd7\x35\x5f\xa2\xdc\x45\x6b\x29\x26\xe0\xa7\x9e\xd7\x75\x5a\xbe\x96\x18\x88\xa1\x1c\x2f\xf3\xba\x9e\x05\x29\x0e\x52\x47\x14\x17\x7a\x8a\x45\xf5\x88\xe6\x47\x3a\x11\xdc\x2a\x7c\x70\xc6\x52\x45\xf4\x08\x43\xe9\x78\xfe\x36\xae\xf0\xbf\xf4\x14\x1d\xbb\x5c\x33\xfe\xe0\x86\x31\x3b\x7c\xfa\x42\xae\x78\xca\x6f\xda\x2c\x08\xab\xf3\xea\x12\x68\x6b\x25\x57\xef\x27\xf9\xf4\x4b\xc7\xb1\xa5\x5e\x1e\x9b\xa7\xc1\x8f\xfb\xe5\x56\x84\x39\xa7\xa3\x87\x69\xe7\x0c\x24\x29\x59\xcb\x61\xca\x69\xb7\xc7\x63\x12\x53\x94\xff\x37\x14\x3b\x95\x14\x9a\x2f\xff\xa9\xfb\x44\x62\xc9\xb7\x58\xdf\xc1\x31\x78\xdd\x44\xe5\x84\x0e\xb2\x20\xd5\x31\x41\xaf\x1c\x16\xc4\x5d\xea\xb0\x8a\xf0\x44\xb7\x62\x48\x97\x6a\x1f\x78\x14\x52\x82\x00\xaa\x65\x63\xe5\x00\x94\x3f\x39\x97\x5d\x05\x73\x7d\x25\x89\xab\x22\xb0\xce\x32\xc3\xaa\x30\x26\xff\x60\x68\x46\x04\x29\x8d\x7a\xd0\x40\x84\x23\x88\xa0\x4f\x18\x6a\xd9\x83\xf6\xf4\x49\x06\xc8\x99\xe6\x34\x9c\x51\x28\xca\xd6\xd6\xd6\x42\xcb\x20\x48\xc8\x53\xde\x04\xe0\xe0\xd0\x96\x09\x66\xcd\x00\x4c\x3c\x5e\x49\x83\x35\x51\x77\xcc\x2d\x95\x9c\xc7\xf3\x88\x11\xed\x78\x1e\xd1\x02\x1f\xcd\x5c\x3a\xed\x00\x3f\xef\x6c\x91\x74\x9c\x47\xf4\xa0\xb4\xaa\xc3\x8a\x63\x3a\x53\xd1\x13\x07\x82\x2b\xb2\x25\x33\x97\x6e\xcf\x3c\x1c\xc8\xe3\x9a\xb8\xf8\x18\x94\x41\x3c\x4c\x25\x83\x2b\x22\x59\xbf\xf2\x0a\x58\x84\x62\xf2\x0c\x7e\x9d\xd0\xf8\x4d\xe3\x32\xeb\xa9\x71\x26\xd8\x76\x4e\x62\x43\xfa\x0f\x08\x82\xd1\x51\xf3\xf6\x11\xe1\x69\x15\xce\xb1\x18\x98\xc4\xea\xd8\xd2\xf7\xb9\xae\x46\xdd\xf2\xc1\x36\xe0\x73\x7c\x91\x2e\xe2\xf1\x18\xe7\xa1\x08\xe3\x28\xb2\xb0\x26\xe0\x5c\x20\x69\x98\x8d\xcb\xd2\xf4\xfd\x1d\xf3\xa5\xeb\x7d\x10\xa2\x4a\x1a\x37\x88\x0d\x18\x61\x1e\xfb\x2c\x06\xd5\x03\x42\x57\xd3\x77\x77\x8c\x71\xca\x04\x3e\x75\x97\x80\x09\x22\xb1\xe5\xc0\x85\x6d\xb9\xce\x4a\x31\x93\xb1\x9d\xb9\xf5\xb1\x2f\xf2\x3d\xe5\xc6\x62\xb1\x4c\xf9\x0d\x4d\x25\xf6\x57\xcf\xad\xdf\x1f\x65\x33\x09\x9e\x96\x4a\x2a\x8c\x05\x7b\x5c\x08\xa3\x47\xbd\xa3\xe6\x26\x86\x31\x70\x67\x3c\xa1\x85\x7a\x04\xd7\x88\x79\x8f\xb0\xf2\x96\xb0\x36\x64\x5d\x15\xc7\x36\xf9\x8a\x0b\xdd\x6b\xaa\x64\xba\x6b\x41\x85\x69\x9c\xab\x5c\x69\x69\x9d\xba\x5b\xc6\x76\xbf\xfd\xde\x90\xa2\x3a\x8e\x41\x04\xa6\xbe\x8f\x37\xe6\x4e\xc0\x34\xa9\x14\x2b\xaa\xc3\x2b\xe7\x25\x95\xd8\x46\xcd\x59\xe8\xcc\x65\x64\xd4\xa9\xfd\x82\x4f\x19\x99\x91\xf9\xf0\x37\x6d\x17\xa0\x6a\x35\xea\xd8\xfc\x8e\x22\x33\xab\x93\x76\xf6\xf1\x53\x31\x6e\xdf\xba\xf5\x95\x82\xed\xb5\x2a\xce\x4d\x6a\x0d\xe5\xd4\x15\x53\x53\xbf\x09\x6a\xee\xfb\x5c\xee\xb0\x25\xb7\x5e\x46\x4e\x4d\xaa\xfd\xae\x82\xd1\x34\x18\x4e\x0a\x0e\x60\xba\xa7\x08\x82\xdc\x4a\xe8\xc1\x5e\x0b\xeb\xd1\x63\xe3\x35\xdc\xb8\xc5\x01\x96\x55\x76\xd4\x51\xdf\x1b\x13\x7c\x99\x1c\x32\xb5\x4e\xc6\x83\x8f\xce\xac\x08\x81\xfe\xb6\xec\x66\x0d\x90\xa5\x0d\x6a\x0a\x54\x3a\xf1\xc0\xaf\xae\x3a\xfc\x8d\x20\x06\x85\x44\xc8\xfd\x5b\x84\x57\xd3\xcd\x3d\x4c\xa4\xad\xfd\x28\x05\x31\x1c\x0c\x76\x7c\xe4\xa0\xb2\xc7\xfa\xfd\x33\x53\xc1\x03\xf7\xb8\xdf\x77\xe0\xdf\xef\x02\x8b\x40\x3a\x03\x80\x6f\x63\x06\xdb\x0d\x08\x9d\xe6\x0d\xde\xe5\xfb\x0e\x78\xeb\x64\x20\x7a\x87\xfe\xf8\x7a\x9d\x96\x7b\x0c\x12\x3a\x36\x6b\x43\x9d\x32\x17\x58\x00\x89\x1c\xe4\x79\x27\x3e\x65\x81\x56\xde\x49\xaa\x74\xfc\x6d\xfa\xc9\x44\x31\x13\x79\x89\xd8\x53\x78\xfc\xfe\x0d\x3e\x7f\xe6\xdc\x22\xf4\xa0\xac\x27\x9b\xda\xdc\xd3\xa3\x73\x2a\xb1\x8b\x41\x0f\x2a\x6a\x84\x10\x84\x0b\x52\x08\x92\x0a\x92\x0b\xe5\x4e\x4b\x39\xcd\xac\xcb\x6d\x7e\x57\x6f\xd3\x84\xe1\x27\xe7\x24\x16\xf4\xbc\x75\xb1\xfc\xc4\x71\x97\x55\x0a\x84\x0f\x70\x1f\x10\xec\xbc\x5f\x4d\x95\xac\xce\xf7\x2f\xa7\x05\xfb\xbd\x62\xa5\x78\x61\x0e\xa9\xaf\x8b\x78\xc7\x96\x27\xd2\x51\x29\x70\xd0\x09\x5d\x54\xea\xfe\xc2\x45\x86\xdb\x38\xc3\xea\x55\xa4\xeb\x0f\x08\x3b\xee\x97\x2a\xd1\xb2\x03\x27\x83\x5c\x19\x73\xf4\x06\x13\x21\x68\x7b\x23\xad\xad\x26\x13\x5d\x3f\xd7\x33\x92\xd2\x83\x62\x9e\x03\xa6\x54\xa1\x42\x89\xf2\x16\xc5\xc5\xc7\x8b\x62\x4c\x9f\x4d\x04\x4e\x43\x43\x8f\xc7\x88\x53\xce\xc2\x22\xc2\x11\x4d\x43\x47\x1a\x16\x51\x37\x1a\x3c\x4a\xa7\xfa\x7c\x4b\x53\xad\xe9\x93\xc4\xb3\xed\xc7\x5a\x0c\x59\x59\xa2\x8d\x98\x0a\x49\xde\x58\xa1\xce\x20\x61\x84\xff\xff\xbc\x7d\xff\x77\xdb\x36\xb6\xe7\xef\xfb\x57\x48\xd8\x2c\x0f\x10\xc1\xb2\x9c\xf6\xec\x79\x4b\x05\xc3\x93\x71\x93\x69\xe7\x34\x49\xa7\x76\x3b\x99\x23\x73\x7a\x68\x09\xb2\xd9\x52\xa4\x86\x84\x64\xbb\xa6\xfe\xf7\x3d\xb8\x17\x00\x01\x8a\x4a\x33\xef\xed\xbe\x1f\x12\x8b\x20\x08\x82\xf8\x72\x71\x71\x71\xef\xe7\x33\x5d\x56\xe5\x32\x53\xc1\x2d\xf2\x92\xa4\x5a\xf5\x9d\xf1\x4c\xe4\x76\x3d\xae\x5e\x67\xd6\x47\x0d\x1d\x32\x8d\x6f\x2c\x57\x5c\x3a\x93\x63\xdd\x55\x61\xad\x68\xc5\xbd\xc6\xc8\x4c\x73\xac\xf5\x80\x32\x0e\x13\x1e\xd2\xb7\x8f\x06\x3e\x45\xae\x53\xbf\xed\x2d\x38\x05\xcc\x8a\x83\xde\x3e\x87\xc7\x91\x99\xdd\x5b\x5c\xcc\x9d\xdf\x8c\x50\xaa\x6d\x75\xc7\x72\xe5\xdb\xf3\x0a\x14\xe5\xba\x83\x27\x85\x5b\x13\xce\x24\xe3\xa5\xb8\x38\xa3\xea\xbc\x4b\x04\xe3\x1d\x56\xbb\xc0\xe6\x69\xfa\xde\x85\x36\x7d\x51\xa7\xd3\x7a\x57\xd2\xb2\x43\x06\xf7\xc8\x14\x69\xc5\x17\x05\x2f\xb9\xde\x90\x95\xaf\x2f\xa2\x28\x4f\x54\x4c\xf3\xb6\x3d\xce\x74\xc1\x67\x29\xe3\x4d\x1f\xe8\xbc\x48\x19\x1f\x5f\xb0\x03\x2f\x44\xe3\xe0\xc6\x31\x0c\xbd\xe2\x5b\xb0\x56\xf8\x6e\xe7\x7a\xeb\xb2\x55\x5e\xda\x78\xc6\x9f\x8d\x03\xe2\x5b\x10\x20\xb1\xce\x85\xbf\x8e\x94\x91\x03\x57\x8c\xdb\x50\x3d\xb3\x2f\xce\x65\x13\x4b\x97\xf8\x11\xd7\xbb\x58\x71\xd7\x98\xb1\x6b\x6e\xdb\x7c\xb1\x72\x2d\xc9\xb1\x95\xe2\x45\xca\x0d\xa4\xa0\xbe\x1e\xa4\x0d\x30\x2a\x18\xad\x78\xa1\x97\x55\x8c\x9a\xc1\x9f\xd3\xe0\x0b\xe0\xc4\xc2\xdc\xc0\x0f\x70\x6d\xef\x7a\xcb\x30\x35\xf0\x12\x23\x15\x07\x82\xd3\xb4\xaa\x2d\x93\x5e\xf7\xc6\xa0\xab\x66\x7e\xf8\xfb\x1c\x7d\x69\xc7\xb3\xb9\x7a\x5d\x82\xbe\xed\xba\x5e\x61\xd7\x5f\x74\xfe\xc2\x09\xfd\xf2\x8e\xe5\x32\x65\x2c\x6e\x7c\x8e\x50\x9b\x6c\x97\x7d\xbe\x14\x05\x2c\x04\x58\x8b\xf1\x67\xb0\x22\x20\x43\x89\x36\xcd\x7c\x4d\x73\xa1\x16\xb5\xf8\x44\x4b\x96\xf2\x4a\x00\xa0\x68\xa8\x81\x57\x68\xea\xa9\x16\x17\x36\x83\xa8\x16\xba\xa2\xa5\xe1\x48\xd3\xd2\x48\x54\xdc\x71\x11\x95\x69\xdf\x9a\x51\x83\xf9\x02\xf7\x33\x60\xc1\x60\xae\x0e\x95\xc8\x8c\xfb\x28\xad\x58\x57\x46\x9d\xf2\x8a\x61\x25\xdb\x96\x9a\x97\x96\x29\x57\xfa\x57\x6e\x9c\x74\x95\x7e\x71\x7e\xa0\xcb\xc1\xce\x67\x6e\x06\xc2\x59\x48\x20\x55\xf4\x5c\x04\xe1\x54\xf0\x8a\xdb\xc7\x9d\x8c\xda\xd0\x12\x42\x43\x19\x6c\x7c\x7c\xaa\x85\x02\xd7\x7a\xf3\x3a\xb8\xc1\x20\xab\xc0\x27\x00\xa5\x08\x78\x3f\xca\x8e\x9a\x74\x93\x6d\xe9\x92\x2f\x15\x2f\x18\xdf\x50\x5b\x55\x50\x1d\xa3\xc8\xbf\xc4\x2a\x55\x3a\x5f\xd1\x51\x14\x9b\x1c\xf6\xda\x30\x15\x9b\x54\xfd\xdb\x56\xc7\x32\xfc\x19\xee\x62\x93\xaa\x7f\x3b\x79\x69\xd2\xf0\xca\xad\x74\x1b\x1f\xac\x6e\xc7\xad\xcc\xc8\xca\x7c\x13\x17\x1c\x09\x22\xfc\x4f\x3e\x30\xc6\x8b\xc3\xd5\xd4\x2d\xad\x5d\x3c\xcb\x5a\xf1\x67\xbb\x4a\xc4\xcf\xe4\x25\x89\x17\x43\x33\x18\xf7\x29\xdd\x34\xc7\x18\x79\x2b\x16\x25\x2d\x8d\x4e\xc5\x3b\x8b\x03\x87\x39\x9a\x1e\xb8\x29\xbe\x27\x19\x00\xeb\xc2\x50\x3a\xe0\xf2\x14\x4b\x21\x1d\x96\xd5\xdc\x43\x78\x07\x69\x2d\xfb\x62\xba\x14\x30\xea\xfc\x55\xae\x4c\x45\x78\x09\x40\x40\x61\x92\xa3\x51\x51\xe8\x35\x6b\x06\x58\xf8\xd9\x27\x7c\xfb\xf9\xda\x1e\xdf\xe5\x70\x96\x6a\x8d\x68\xfa\x8a\x6f\x11\x5a\x64\xa5\x77\xc6\xf7\xd6\xfa\xcb\xef\x02\xe3\x71\x06\x5b\xe2\xbd\x83\x02\x24\xeb\x47\xad\x4f\x11\xfc\x5c\xf0\xff\x2e\xb1\xcb\xda\xd6\xc0\x6c\xc2\xc4\x0c\xf9\x63\x80\x00\x87\x4d\x77\x25\xa4\xae\xa2\x88\x66\xee\x42\xcc\x78\xa3\x67\xa8\xa3\x75\xe1\xfe\x85\xbf\xc4\x76\xcf\xb4\x6d\x43\x19\x30\xd1\xda\x94\xc9\x84\x6f\x07\x96\xec\xa1\xb4\xee\xa1\xb3\x33\xde\xf1\xe1\x40\x1d\x4d\x97\xb5\x6d\x16\xf2\xcc\x18\x32\x45\x2b\xcc\x52\x5e\x39\x4c\x39\x58\xfa\xad\x6f\x11\xdc\xd2\x7b\x60\x82\xca\x27\xd8\xe6\x78\x2e\x84\xa0\x77\x09\xd1\x4a\x28\x89\x09\x36\x20\x3c\x87\xbf\xc7\x42\x6f\xc7\xc7\x7b\x0f\x66\x61\xaf\x25\xda\xb2\x2a\x55\x5e\xee\xe4\xfc\x4e\x8c\x67\x87\x95\x96\x45\xfb\x28\xd2\xb7\xf4\xe6\xdd\x1a\x17\x6a\x76\xc8\xd7\x94\xee\xc4\x00\xa7\x1a\x83\xdd\x48\x98\xba\x62\x9d\xef\xfe\xba\xcf\x84\x16\x45\xb4\x9c\x5a\x97\x22\xb1\xb8\x77\xbf\x79\xf7\xf3\x93\xf7\xfb\x1f\x29\x37\xbd\x5e\x40\xdd\x2c\x24\x3e\xb0\x06\x74\xa3\xa6\x33\xae\x76\x78\xfd\x74\x39\xc0\x77\x01\xcf\x25\x4b\x51\xc4\xb4\x40\xec\x6a\x60\xc4\xec\x53\x67\xb4\x6d\xc1\x87\x1e\xe7\xf8\x10\x63\x8c\x53\xef\x0c\x6f\xd9\xb6\xe6\xea\x0c\x0f\xdc\x75\x1a\xee\xc9\xc6\xa2\x18\x64\xe0\x58\x17\x55\x06\x30\x24\x70\x16\xb2\x45\x91\xe8\x8d\xa2\xfb\x0e\xfc\xff\xc0\x4c\x1b\x14\x40\x27\xe1\xee\xf0\x42\xb8\x72\x97\x09\x21\xf1\x92\x31\xde\x3d\x17\xd6\x48\x0b\x74\xd7\xaa\x51\x44\xbb\x26\x16\xce\x6b\x60\x68\x34\x7b\xf9\xba\xe7\x21\x38\xaf\xeb\x2f\xff\xce\x85\x7f\xe7\x1f\xfe\x9d\x57\xe9\x01\xf8\x17\xc6\x17\x7c\xc5\xf4\x47\xef\x13\xfb\xe6\xbc\x1c\xed\xa3\x88\xde\x89\xbd\xd9\x15\xb1\x78\xef\xf3\x53\x59\xa9\xc0\x9f\xad\x63\x83\x6e\x94\x2a\x8a\xa8\x7d\x40\x8c\xef\x18\xbf\x8b\x22\xaf\x53\x8f\xdb\xd4\x0d\xcb\xbb\xb6\x35\x1d\xc9\x7d\x00\x37\x2b\x7b\xf8\xca\xa3\x05\xa9\xb9\x9e\x18\x0c\xeb\xbe\x54\xf4\x2e\xd1\x13\x24\x9e\xf1\x9a\x6f\x19\x87\xe2\xf6\xfa\x63\xf4\xec\xd9\x19\x0b\xca\x1d\x84\xaf\xc9\x72\xe5\x52\xcc\x5f\x31\x63\xec\x90\x76\x52\xb6\xcf\xa6\x95\x84\x3b\x07\x2b\x99\x25\x8b\xc3\x1b\xa0\xf2\x49\xe3\x4a\xdc\x6c\xa5\x5c\x0d\xfb\xa7\x0a\x19\x45\xc7\x71\xcc\x49\xa8\x45\xc7\xcf\x76\xdd\x8d\xcb\xb6\x1d\x97\x51\xa4\xda\x76\x03\xbe\xe2\xb2\xd3\x73\xa5\xd5\xa4\xf1\xbe\x8a\xa2\xf1\x06\xdc\x3a\x95\xc7\x61\xbe\x7e\x9c\x56\xeb\x75\x52\x3b\x9d\x58\xcc\xe2\xee\x94\xcc\xbc\xbf\xbb\x0b\x8c\x27\xf6\x42\xb7\x24\xee\xbb\xf5\xf7\x34\x7e\x21\x5e\xf2\xa2\x4b\x4e\xe3\xe1\x2c\x4e\xc5\xb7\x27\x76\x35\x0a\xe1\x28\x02\x14\xaf\xda\xad\x27\xe6\x17\x30\x5f\x31\x5e\x4f\xab\x62\x25\x6a\xa7\x84\xf0\xee\xa7\xbf\x4a\x6c\x28\x64\x64\x51\x04\x7f\x3b\x43\x98\x2e\xc1\xbc\xa7\xc7\x31\x65\xd2\xd9\x81\xd7\x87\xd0\xda\xbc\xce\x56\xf2\xba\x3a\x1d\x54\x0f\x5a\x86\x71\xbc\xcf\x24\x03\xe1\xe1\x0e\xbe\xf9\xcc\x72\x69\xe8\xa1\xa6\xb7\x94\xa0\xcd\x48\xea\xce\xd1\xd5\x01\x11\x72\xd9\x81\x9b\x7b\x47\xe0\xb9\xe6\x90\x4f\x1c\xcb\x76\xe0\x69\x83\x16\x35\xe7\x88\x3e\x3f\xba\x35\xae\xae\x0d\x0e\xa1\x3f\xa2\xf4\xa3\x6c\xae\x77\x7e\x3e\x50\xe1\x3a\x2f\xf3\xe6\x9e\xa0\x63\x83\xd6\x34\xe9\x78\xc6\xdc\xd0\xc9\xa6\x78\x5f\x64\x5c\x2f\x55\x48\x78\x08\xad\xe6\xf1\x06\x66\xc6\xa8\x89\x4d\x6b\xee\xf3\x8c\xf5\xf7\x3d\x39\x97\x9d\x7b\xd1\x90\x67\xb8\xce\x6e\xfd\x75\xf1\x8a\x2b\x5a\xb9\xda\x1c\xa1\x82\xe7\x10\x00\xad\x15\x33\xbd\xd8\x3a\xbe\x2d\x63\x17\xc5\xea\xe4\x1d\x33\xd8\x70\xe8\x3e\x36\xd8\x78\x66\x42\x4c\xc6\x70\x52\x1c\x10\x72\x71\x3d\x8c\x41\x99\x6d\x02\x58\x6b\x13\x1a\x58\x03\x8b\xa3\xfe\x1f\xaa\x1c\x45\x19\xad\x21\x4a\xc6\x01\x59\xc2\xd1\x68\x3d\x90\x51\x75\x5e\xd8\xf6\x21\xb4\xd3\x94\x0e\xdc\xf1\xec\x6c\xce\x4a\xfd\x88\xd6\x5b\xc7\x16\x87\xc2\xd5\x14\x6e\x41\x5d\x51\x9b\xa0\x90\xa0\x47\x15\x76\x66\xc5\xb8\xd4\xa2\xbd\xb4\x30\xa0\x8a\x5f\x30\x36\x1f\xcb\x28\xaa\xb4\x36\x11\x4c\x88\x9c\x21\xe6\x99\xee\xf1\xae\xdb\xb2\x0e\x37\x7e\x8c\x4e\x93\x10\xf8\x88\xb3\xf3\x74\x93\x72\xe5\x37\x15\x2f\x85\x5a\x64\x96\x29\x2f\xe5\xb5\x77\x89\xad\x9c\x42\xb8\xa2\x69\xe6\x4a\x94\x49\xd9\x6d\x88\xa1\x51\xec\x50\x1c\xcf\x78\x40\x5c\x97\x41\xdf\xd6\x7a\xe2\x63\xb3\xe2\x5f\x2f\x66\x7c\x0c\x2c\x6c\xce\x9c\x24\x75\x9b\xe6\x0b\x89\x6d\x6a\xa2\xc5\xa2\x08\x52\x50\xf2\xe0\x67\x42\x42\xd7\x94\xba\x94\xdc\x36\xa3\x84\x66\xd4\xf5\x92\x62\x36\x97\xaf\xab\xb9\x84\x63\x30\x99\xea\x3e\x91\xa9\xa9\x6c\x70\xe1\xc9\x24\xe7\x95\x6e\x6e\x1d\x58\x70\xe6\x6d\xb4\x48\x8e\x7a\x22\x47\x0d\x32\x38\xf9\xf6\x04\xc4\xba\x5c\xd4\xe9\xdc\xfc\x3d\xc5\x11\x6e\xec\xd0\x6d\x3b\xc4\x1c\x94\x0f\xbb\xce\xe3\xac\xb6\xd2\xab\x50\xb4\xc6\x96\x44\x66\x56\xef\x4c\xb2\x29\xf2\x95\xfc\xa6\x7a\x28\xe3\x42\x19\xdd\x96\x71\x48\xfc\x69\x0b\x49\x50\x7f\x93\x74\x8d\x9c\x46\x3a\xd9\x7c\x26\xe3\x5a\xde\x7e\x57\x76\x8e\x46\x58\xc6\x01\xd2\x3f\xee\x94\x77\x03\x4a\xc2\x1b\xa6\xa0\xee\x9e\x29\xee\x70\xe8\x35\xd4\x71\x54\x4d\xd0\x34\xc1\x57\xd6\xc1\xe7\xe1\x68\x14\x8b\xb4\x33\xdd\x1e\xc9\x5a\x8e\x76\x1c\x9b\x19\xc7\xaa\x6f\xa2\x9d\xab\xd7\xa5\x8f\xd5\x4a\xa5\x80\xf0\x0d\x6a\xe2\x38\xc6\xd0\x2f\xdd\x04\x3d\x3b\xe3\x17\x6c\x5e\xba\x3d\x89\x31\x7a\x57\x5b\x0a\xb6\x5f\x63\x07\xf6\xb6\xd8\x22\x3c\xc1\xc0\x7a\x58\x5d\xc4\xda\xcc\xb3\x1a\xf0\xba\x02\x8b\xb4\xb8\xf8\xca\xbb\xed\x7f\x59\x09\x30\x28\x4a\xcf\xb5\x46\x51\x66\x1f\x04\x83\x44\x90\x0d\xbd\xeb\xb9\xb7\xcc\x8b\xe7\xa6\xa8\x1e\xe2\xff\x3d\x9b\xf1\x75\xd6\xa8\xf8\xd5\x6c\xd6\x19\xf8\xbf\x9e\xcd\xcc\x52\xbb\x92\x5a\x19\x76\x65\xd5\xbc\x3b\x43\xa8\x41\x6b\x00\x84\xf7\x4e\xbd\x48\xdb\xb6\xee\xa8\x14\xb9\x27\xe1\x25\x1f\x32\x04\x04\x96\x74\x3d\x0c\xe6\xea\xa8\xfa\x97\xe8\xf0\x63\x73\x95\x18\xf8\x59\x0f\x38\x7e\x1b\x74\x42\x9e\x0f\xdc\x43\xb0\x1a\xf2\x07\xb4\x54\x78\x4a\x07\x51\xff\x88\x80\x28\x88\xe5\xd0\x22\x96\x1d\xea\x63\x29\xc0\xe1\xa8\x56\x48\x0e\x80\xbc\x38\x08\x6d\x2f\x57\x22\x57\x06\x18\x47\xae\x38\xfd\x4c\x2d\x19\x3e\x2d\x88\x22\xdd\xcb\x90\xdc\x8a\x3f\x4d\xe1\xc7\xcf\x36\x83\xe8\xde\x06\x07\x2a\x5b\xc5\x57\x4a\x18\x44\xf5\x4c\xa9\xfa\x5b\x08\xd8\x9e\x07\xea\x91\x4e\xff\xec\x69\xfc\x15\x3c\x7a\xf2\xb8\x9b\x77\xa8\x2c\xff\x06\x3f\x68\xf7\xd0\x29\x7a\xde\xa3\x7a\x85\x9e\x00\xdd\x76\x57\x2f\xdc\x5f\x8d\x81\x93\xe3\x3f\xf0\xcf\x2b\xfd\x87\x1d\xe1\xf8\x8b\x80\xe7\xc9\xc1\x51\x24\x57\x60\x12\xb5\x47\xfc\xd4\xf0\x7b\x04\x08\x08\x6d\x4b\xb5\x74\x86\x36\xc4\x63\xe7\x5e\x14\x27\x9c\x98\x7b\xc8\xf5\x5a\x30\x5b\x7d\x20\xd9\x5a\x4a\x64\x16\x92\xd1\x83\x18\x17\x65\x02\x69\x41\x9b\x00\x91\x7d\xde\x79\x9e\xe5\xbe\x0b\x5e\x2d\x72\xe7\x79\xa6\x18\x4b\xea\x98\xf6\xf8\xcb\x14\x2f\x27\x84\x30\xfd\x39\x79\xe7\x11\x96\xdb\xdd\x32\x16\x61\xf9\x8b\x75\x01\x66\xff\x0f\x93\x35\x2f\x57\xf0\xa1\xe6\xa6\xe1\x90\x07\xfd\xd6\x7e\x7e\x8c\x80\xff\xcf\x7d\xbf\x27\x74\xf8\xf5\x87\x65\x14\x99\xc1\x8a\x94\xb3\xe0\xba\x6b\x47\xb6\x99\xdc\xd2\x8c\xd8\x8e\x7b\x63\x80\xcf\xcd\xd0\x2c\x9b\xbc\xa2\x44\xa4\xad\x13\x83\xaf\x7f\x72\x06\x31\x88\xce\xc6\x97\xaf\x69\x7e\x44\x1e\x6f\x62\x0a\x44\xbe\xa8\x27\x93\x94\x1d\x63\x0d\xe1\x2a\xb2\x3d\x3a\x86\xf5\x57\x1f\x50\xa9\x55\xd2\xeb\xc9\x92\xc5\xbd\x6f\x2a\xd1\x4a\xe9\x50\x04\x8f\x47\x0e\x92\xb9\x9a\x3a\x9f\xdf\x3c\x4c\xce\xef\xd8\x80\x64\xcc\xc4\x4a\x19\x27\x40\xd7\x6d\x73\x48\xfa\x4c\x28\x65\x6f\xe8\x3a\x77\x1e\x18\xe3\x2b\xb5\xa8\x52\x0e\xff\x23\x41\x0e\x0c\x98\xcc\x94\x92\x54\x30\x52\xcc\xfd\x9c\xf1\xda\xc6\x92\xde\x9b\xf3\x5a\xe8\xdb\x16\x25\x5b\x6b\xb1\x39\x5a\x03\x15\xfd\xe2\x3c\xe7\x77\x26\x63\xd6\xea\x3b\x3a\xc9\xa3\x6a\xf3\xc2\xb9\xa8\xf4\x19\x06\x52\x66\x22\x32\x47\xc4\x3b\x25\x7d\x52\x01\x40\x95\x3f\xa9\x8d\xc3\x89\xcf\xfb\x57\x64\x0d\x60\xb8\x13\xcf\xad\x7a\xe3\x97\x10\x1e\x68\x48\x96\xc8\x78\x28\xd0\x3b\xac\x58\x48\x14\xb9\x0d\xb0\x9a\x07\x85\x29\x9e\xff\x7f\x5e\x98\x86\x90\xcf\x7f\x20\x4c\xbd\x98\xc8\x05\x16\xff\x2e\x7f\x84\x33\x2d\x99\xf6\x85\xea\x51\xfd\xfe\x73\x42\x75\x74\x42\x46\xea\xc5\xc6\x56\x40\x0f\x4b\x05\xdb\x00\xcf\x59\x27\x0d\x04\xe0\x97\x0b\x38\x09\x5e\xb4\x5f\x28\xcc\x24\x60\x4a\xbb\xb7\xc6\xcf\x2a\xbb\x45\xe7\xec\x61\x0f\x96\x9e\xd0\x23\x2a\xbb\x05\xe7\x60\x0f\xde\x20\x71\x61\x56\x8a\x5f\xcc\x58\x7c\xaf\x2c\x3c\xa4\x85\xb2\x61\x6d\x7b\x77\x9c\x08\x50\x7b\xb5\x5c\x27\xb3\xf8\xec\x42\xcb\x2b\xd3\x3a\xf1\x33\x59\x57\x35\x89\xc9\xbd\xda\x14\xef\xaa\x9a\x70\x33\x3e\x63\xfc\xab\x1f\x26\xba\xeb\x02\xa5\x01\x16\x19\xcf\x37\xc4\xea\x12\x27\x3e\x4b\xfa\xb1\xf5\x7e\x38\x76\x00\x31\xe1\xe3\x4b\xd8\x12\xa1\xb5\x38\x6a\x83\x7d\xaf\x93\x81\xb2\x55\x14\x51\xd5\x7b\xf8\x4b\xdf\xd2\xdb\x2b\x99\x9e\x22\x9c\xd4\x32\x5b\x7d\x2c\x8b\x27\xc2\xc9\x26\x7b\xfc\x1e\x26\x88\x6e\x26\x59\x14\x26\xbc\xca\x5c\xfd\x60\x9c\x1b\x38\xa9\xab\x87\xab\x6d\x56\xea\xf4\xaa\x30\xbf\x76\x8d\x7c\x9f\x6d\x09\x27\xeb\x3a\xdb\xc8\x3f\x1b\x9f\x55\x1b\x6e\xf1\x76\x85\x60\xe1\xfe\x7e\x4c\xab\x27\x6e\x10\x03\x3e\x4b\xb0\xd2\xc3\x06\xb3\xef\xd1\x98\xad\x56\x97\xba\xdf\x3c\xd3\x8f\xdd\x51\x84\x81\xa7\x70\x1e\xbc\xa1\x1d\x04\xf4\xc0\x94\xd6\x8a\xbf\xe1\x6d\xb5\xe5\x52\x15\xa0\xa6\x3d\x99\x8d\x38\x33\x48\x69\x54\x8a\x0d\x1c\x15\x58\x41\x62\x97\x33\x10\x0a\x3b\xc3\xa4\x97\x8b\x27\x85\xe1\x84\x00\x82\xe8\x9d\x17\x90\x11\x99\xec\x15\xcd\xd9\x44\x0b\xd8\xe7\xcc\x23\xc5\x93\x8b\x4c\x3f\x5e\x77\xfe\xf2\x23\x32\xa9\x20\x1f\xa0\x33\xd4\x13\x81\x57\xf3\x5c\xcf\xc5\x46\xec\x15\xad\x91\xf5\xbc\x19\x90\xbf\xbc\x71\x60\x5e\x88\x19\x62\x22\x15\xff\x7f\x34\x9e\x57\xf4\x1f\xb4\xdf\xf8\x48\x12\x07\xdb\x49\x2d\x17\x6c\xfd\x09\xf9\x6f\x6a\x71\xbc\x3c\xbb\x78\x3d\xd4\xf4\xac\x16\xb5\x43\x4a\x73\xc9\xfc\xbf\xd0\x0f\xb8\xdf\xee\xf5\x43\x6e\x15\x0d\x17\xd1\x91\xf3\xcc\xf3\x25\x16\x55\xdb\x86\xab\x66\xee\x22\x85\x8e\x4c\x13\x2a\x8a\xb2\x44\xa1\xa9\xd1\x8d\xeb\xdc\x18\x26\xfc\xbe\xca\x59\xbc\xa1\x39\x4b\x3e\xdf\xbb\x5e\x85\x69\x3e\xd8\xbb\x80\x06\xce\x0e\x27\x28\x93\xfd\x48\x62\xf0\xd1\x78\x36\x7b\x7f\x6b\x68\xd6\x1d\x9c\x33\xd3\x2d\x52\xd4\x48\x85\x52\x4e\xef\xb3\x06\xdf\x2a\x59\x52\x06\x15\x97\x2c\x2e\xbb\x4f\x93\x86\xfd\xc6\xad\x6b\x39\xb8\xf3\x63\xab\x60\x38\x8b\x1e\x46\x6e\x2c\x46\x91\x47\x17\x47\x7e\xf9\xc5\x2d\x04\xbf\xfc\x42\xb8\xc5\x2a\x6d\x02\x1d\xe7\x28\xc9\x75\xaf\x34\x06\xde\x3c\x21\x24\xf6\x4d\xc4\x61\xb9\xa0\x0e\x31\x84\xd5\x31\x9f\x75\x82\x00\x70\x36\x57\x42\x0f\x34\xa9\x07\xda\x3c\x18\xed\xb5\x19\xed\xfd\x31\x7e\x76\xf1\x9a\x9a\x71\x0e\xd3\x00\xc7\xba\x1b\xcd\x6e\x1a\x8f\x6d\xa4\xc2\xf8\xc2\xaa\x93\x8f\x4a\x9c\xdf\xd4\xe7\x77\xe1\x56\x75\x9f\x79\xc0\x3f\x4e\x71\x91\x3c\xe7\x0e\xe4\xc7\xd9\xba\x7b\x13\x3a\xa1\xb9\xd8\xe8\xa9\x38\x3c\xa8\xd0\x93\xf5\x08\x7f\x2a\x8a\xec\x79\xb8\x12\x79\x52\x06\xa3\xcc\x8e\xc3\x7d\x56\x50\xc6\xe2\x92\x25\x4a\x10\xe2\x4e\x62\xba\x61\x9f\xa8\x89\xbe\xd1\x77\x58\x07\x70\x4b\x74\xfb\x50\x43\x50\x64\xc6\xc8\xa7\xfb\x4f\x4e\x08\x39\x30\xc6\x61\x7f\xb6\xcf\x0a\xcf\xf3\xd9\x70\x0b\xf5\x93\x87\x01\xf6\xc0\xbf\xc6\x28\x5c\xb5\xa7\x70\xd5\xdd\xb8\x53\x9c\xc0\x0e\x0b\x42\xa1\xa0\x28\xdc\x70\x29\x3d\x48\x58\xac\x92\x5e\x1d\x86\x2a\xf0\xb9\xb7\xdf\x1d\xbf\x5d\xcf\x2d\x4b\x13\x61\xde\x3d\xa4\x7a\x53\x29\x8c\x6d\x83\x25\xd2\xc9\xbe\x47\xa5\x25\x72\xec\x37\x96\x25\xd9\x0b\x14\x5f\x5b\xbb\xf8\x19\x6d\x37\x5f\xa8\x0a\x9a\xfa\xf8\x50\x03\x63\x70\x37\xde\x2b\x6a\x00\xe2\x24\xc4\x76\xa1\x4e\x73\xa2\x54\x83\xdf\x67\x09\x90\x1b\xd0\xb4\x43\x75\x49\x4b\x55\x48\x38\x33\x87\xcd\x06\x44\xb7\x11\x19\xd8\x09\x62\x20\xee\xc9\x92\x6a\x72\x11\x3b\xdb\x37\x46\x3c\x54\xaf\x67\xc9\x2e\xce\x92\x0a\x9c\x41\x77\xd6\x97\x89\xe2\x6e\xd6\xb1\xe2\x68\xf5\xb1\x06\x16\xe3\x28\x1a\x97\x8e\x65\x27\x8a\xe8\xb8\xf4\xb5\x33\x7b\xa3\x6d\xc7\x6f\xa8\x7f\x87\x13\xcb\xe5\x4c\x98\x85\x16\xbc\xa2\xa5\x99\x01\xbc\x73\x72\x9b\x1b\x7b\xa5\x72\x4b\x4c\x73\x1c\x22\xe5\xb9\x9b\x05\x0d\xa3\x67\xc4\x6f\xd2\x4e\x12\xdf\x71\x14\x65\x4e\x76\x76\xc6\x28\x78\x8e\x66\xde\xa7\x89\x80\x22\xb8\x1b\x8c\xa6\x60\x18\x5e\x35\xe3\x15\xf8\x26\x94\x62\x3c\x0b\xb6\xbd\xbd\xce\x10\x67\x17\x8c\x57\x87\x43\xa0\x99\x1a\x93\x5b\x67\xe7\xeb\x69\x8c\xc1\xfc\x4b\x8f\xad\x04\xd0\x60\x47\x41\x2b\x6e\xef\x6a\x61\x2e\xc3\xef\xa0\xd2\xb6\xae\xd2\x83\xcc\x59\x16\x61\x23\x10\xbe\x11\x70\x73\x4e\x8a\x91\x23\xbc\x66\x33\xb0\x13\x52\x95\x24\x36\x56\x95\x03\x83\x0d\x87\x01\xab\x17\xa4\x2a\x2d\x6e\x7d\x5e\x8e\x2e\x41\x2e\xdf\x9a\xdd\xbb\xb9\x01\x7f\x5a\x0b\x67\x7f\x5b\xec\x6a\xf6\xe2\x9c\x3f\x84\x15\x19\xa2\x7b\x98\xbb\x99\x69\xb0\x26\xf9\xf3\x31\xc1\xcd\x40\x84\x64\xc7\x5f\x28\x16\x65\xdb\xbe\x4d\xf9\x4a\xec\x2d\x43\x9d\x81\x83\x36\xf8\xd1\xb1\xe4\xf7\xde\x3d\x07\x4e\x0e\x19\x3a\xda\xb0\x8e\x78\x30\x5e\x00\xd1\x5a\x25\xd6\x22\x13\x00\xe0\xf4\x96\xeb\x2d\x70\xd9\x8b\xcb\xf5\xaf\xc7\xb7\x66\xcf\xb7\x9a\x1c\x31\x83\xea\xa1\x76\x76\xf1\x7a\xd5\xa9\x6f\x53\xf0\x45\x59\x09\x7a\x2f\x56\xde\x8b\xd9\x14\x3d\x10\x18\xbf\x37\xe4\x87\x8c\xef\x84\xf7\x5c\x8c\xba\xb6\xee\xab\xc9\x8a\x53\x29\x3e\x43\x59\xb4\xe2\xc7\xbe\x08\x51\x24\x19\xeb\xd8\x7a\x45\x9d\xbc\x8a\xbf\xe2\x5e\x2b\x08\x8f\x49\x93\x4b\x8f\x55\x4d\x78\x99\x92\xff\x24\x83\x22\x9a\x8c\x2c\x09\x8f\x39\xf2\xe0\x96\x16\x06\x11\xf7\x91\xeb\x45\x2f\xcf\x0e\x1a\x70\x21\xd3\x38\x10\x06\x1c\x7c\x49\x8e\x09\xf6\x0c\x27\x24\xb2\x25\x9a\xd6\x77\x4c\x78\xe6\xba\x03\x47\x33\xa2\x6b\x5c\x47\xd1\x78\x39\xb5\x6c\x4e\x51\x34\x7e\x04\xc0\x54\x04\x86\x5e\x06\xb4\x92\x6d\xbb\xe2\xb6\x9f\x9b\xc9\x4a\xaf\x8c\x95\xa8\x3c\xc9\xc8\xe6\xd5\xbc\x97\xb2\xb5\x7c\xe1\x3c\x13\xd5\x3c\x83\x80\xe1\x10\x2c\xad\x6d\xdf\xb2\x28\x32\xf9\x32\x1f\x3a\xad\x6d\x33\x53\xd4\xdf\xf3\x72\x55\x3d\xb4\xed\x25\x3b\xe4\x3e\x9d\xde\x76\x91\x1b\x16\x3d\x79\x8a\x96\x6f\x2d\x2a\x4b\x4b\x70\xf1\x3a\x4f\x9a\x78\xe9\xb8\x31\xf5\xf7\x50\x47\x71\x58\xfd\x21\xbf\x21\x16\x93\x5a\x36\xa7\xca\x02\xa0\x83\x9f\x41\x61\x9a\xb6\xd2\xda\x36\x2d\xc4\x2e\x8a\xaa\xc5\x2e\xed\xee\x44\xd1\xcf\xe8\x1c\xec\x46\x40\xf0\x88\xe3\x1d\xb2\xcc\x4e\x7d\x5a\x9a\xce\x19\x1a\xbf\x66\xa5\x7b\x5a\x0e\x70\xdd\x50\xd6\xb6\x4b\xe7\x97\x62\x08\x03\xbb\x04\xf3\xd2\xed\x74\x8b\x87\x6f\xac\x6d\xc7\x3f\xd3\x92\xb5\xed\x2e\x8a\x36\xb4\x5c\xac\xa0\x41\xf5\x30\x88\x22\x4a\x33\x51\xe2\x67\x50\xfd\x17\x46\x65\x47\xbd\xea\xe6\xb8\x58\xf1\x53\x3d\x10\x45\xeb\x21\xba\xd8\x07\xc5\xb8\x7e\x17\x10\x49\x9f\x7e\x72\x88\x6e\x0a\x1f\x3e\xae\x83\x99\x51\x99\xad\x6b\x06\x48\x9d\x8e\x19\xb0\x31\x5c\x37\xc3\x76\xbf\xce\x29\xd7\x93\x22\xbc\xe4\xcf\x46\x86\x06\xd4\x44\xb3\x03\x9b\xf7\xf9\xab\x6b\xc4\x8a\x54\xec\x08\xcd\x77\x48\xa2\xff\xd1\xb9\x50\x58\xb6\xae\xa8\xb2\x98\xaa\x26\xf1\xdb\x23\x9e\xf2\xd0\x61\x58\x6f\x02\x00\xe0\xd9\x39\x4c\x1d\x97\x59\x02\x8a\xb0\xbf\xda\x61\x24\xe5\xbf\x47\xd9\xe2\x79\xf6\x84\x87\xb6\x46\x3e\x99\x76\xa3\xb5\x13\x76\x3c\xe4\x19\xc5\x75\x30\x10\x66\xf5\x10\xe3\x8b\xcf\x7b\x14\x8a\x10\x48\x5b\x05\x97\xe0\xaa\xe1\xbc\xfa\x6a\x36\x57\x7a\xba\x1c\x8d\xc4\x92\xe7\xe0\x00\xe0\xe7\xe5\x54\x01\x44\xc9\x05\x60\x27\x23\xfd\xeb\xff\xb3\x7a\x9c\x5d\xcc\x55\x12\xbc\x4d\xb1\x98\x0e\x13\xab\x75\x95\x73\x8e\x83\x35\x83\x38\x39\xd0\x42\xae\x95\xb8\x9c\x16\xd5\x12\x23\x42\x2e\x95\x78\x06\x72\x69\x2f\x90\x8a\xbf\xd5\x1b\xc8\xe4\x7c\x7e\x35\x05\xcb\xed\xa7\xf7\xdf\x1f\x3b\x29\x81\xe5\x47\xb6\xed\x91\x2b\x92\x03\x91\xd2\x23\x1b\x90\x58\x95\x80\xe9\x71\x39\xfd\xe6\xe3\xfb\x1f\x74\x81\x35\xc3\x82\xdf\xd5\xd5\xe6\x0a\x1e\x07\x05\x44\x3e\xaa\xf3\xc7\x4d\x41\x58\x07\xb3\xea\x0e\xf9\x3b\x0b\xec\x18\xc2\x5c\xcd\x49\x6f\xf3\xe7\xa7\xeb\xec\x4e\x6f\x97\x28\x81\x22\x6b\x59\xd7\x55\xed\xf9\x31\x5f\x4d\x21\x85\x92\xef\xca\x7d\x56\xe4\xab\xd1\xa7\xf7\xdf\xc7\x7a\x2b\xce\xb8\xc2\xc8\xb9\x2b\xfd\xb5\x8b\x9b\xf4\xc5\x39\xff\x0d\x76\xce\xc9\x4d\x79\x7e\xc7\xdf\x18\x6d\xad\xd9\xdd\x6e\x72\x65\x4e\x61\xda\x7c\x93\xdd\xc9\xb6\x96\x8d\x54\xed\x3a\x2f\x24\x1c\xcb\x7c\xf8\xec\xf9\xcd\x6f\xf2\xe9\x4e\x96\xcc\x3f\xab\xf9\x46\xd1\x92\xcb\x8e\x5e\x5a\x1d\x07\x65\x4b\xc6\xcc\xa4\xea\x9f\xea\xd7\x6d\x7b\x65\x16\xd4\x92\x25\x39\xac\xcb\xb1\x2e\x71\x42\x16\x64\x72\xcc\x0a\xa3\xac\xb1\x5f\xe9\x8d\xa1\xd6\x2e\x52\xc2\x15\x62\xdc\x18\xd7\xac\x7c\x4d\xeb\xb6\xb5\x4f\x8e\x85\x78\xd0\xef\xd7\x45\xcb\xbe\xf3\x96\x64\xee\x55\x0a\x4a\x92\x0b\x95\x5a\xc0\x9c\x6d\x56\x67\x1b\x31\x7c\x96\xb8\x48\x79\x3e\x74\x4b\x6c\xa8\x62\x89\xa2\x2c\x56\xf3\x7a\x61\xb1\x5c\x53\x21\xcb\x65\xb5\x92\x3f\xfd\xf8\xdd\x65\xb5\xd9\x56\x25\x32\x4a\x4e\x88\x20\x93\x81\x3b\xa8\xf7\x94\x7a\x0b\x5b\xb2\x03\x88\x30\xdc\xd4\xda\x83\x6c\x32\xd4\xc2\x7a\x6e\xff\xfa\xaf\x9d\xac\x9f\xa2\x08\xbc\xc4\x7f\x28\xb2\xbc\x34\xfe\x85\x83\x1d\xc0\x9e\x73\xdc\xd8\x6b\xc5\x8e\x77\x5b\x7c\xd7\x92\x5e\xe0\x0f\x76\x32\x44\xd4\xf0\xbc\x03\x25\x33\x2a\x5f\x44\x58\xcf\xd5\xb2\x91\x75\x9e\x15\xc3\x00\x7f\xa6\x69\xa9\xb1\x59\x99\x8c\xf8\x1d\x0c\x30\x34\xfc\xa4\x81\x02\xd4\x00\x4e\x34\x4a\x24\x73\x80\x8f\x06\x2e\x69\xa6\x15\xf1\xa2\xa8\x7c\x3d\x52\xa2\x3d\xf0\xc0\xac\xcf\xe7\xb0\x80\xd3\x23\x2f\x88\x28\xd7\xcd\xa5\xdb\xd8\x98\x7d\xf2\x86\x92\xd8\xee\x95\xb5\x5e\xff\xc1\xfa\xff\xf9\xf6\x17\xad\x51\xbc\x51\x1d\x2e\x34\xde\x5d\x5a\x1a\x86\xf1\xd6\x61\x46\xb3\x03\x0b\x3f\xce\x8f\x64\xf3\x4d\x4d\x21\xec\x21\x7a\x11\xf4\x8c\x4b\x25\x4b\xd0\xb0\x54\x0e\x18\x96\x9e\xf5\x87\xc4\x0a\xbb\xdf\x10\xa4\x3a\x73\xca\x6f\x8a\x93\x9b\xfa\xa6\x24\x7a\x75\x8c\x07\xb2\x96\xc3\x59\x11\x72\xd8\xca\xe7\x5f\x95\x38\xff\x5f\xaf\x66\xe7\x77\xfc\x5f\x4a\x9c\xff\xcf\xe9\xcb\x17\xe7\xfc\x7b\x25\xce\xe9\x22\x89\x52\xf6\x8b\x58\xfc\x33\x4a\x5f\x9e\xf3\x6f\x41\xe6\x4c\x5f\x26\x2c\x5e\x8c\x6e\x54\xfa\x92\x2e\xfe\xa9\x4b\x4c\x5f\xb2\x17\xe7\x77\x1b\xfe\xd1\xc8\xa4\xbf\xbc\xbd\x6e\xbf\x7d\xfb\xe6\x1b\xbd\xb7\xfc\x41\xa7\xdd\x9c\xdf\x9c\x9f\xf3\x1f\x95\x78\x3e\xf0\xf7\xf0\xff\x77\x4a\x90\x97\xe7\xc4\x06\xa1\x92\x97\x84\xf1\xbf\x0f\x38\xd5\x64\x3e\x96\xef\x3b\x45\x2b\x37\xba\xc2\x76\x3f\x5e\x12\xc0\x5c\x27\xb9\x14\xba\xec\x79\x18\x23\x14\x98\xb9\x82\xd3\x61\x77\x60\xd1\xf3\x2f\x20\x13\x40\xd3\x59\xcc\xd2\x84\x96\xa2\x74\x70\x2b\x6d\x4b\x5e\x12\x4e\x2b\x1b\xc9\x86\x47\xdf\x5d\xf0\x10\x8b\xfb\xf7\xac\xa5\xa5\x3b\xd3\xfe\xb3\x02\x92\xa1\x8a\x67\x38\x7e\x1a\xdd\x40\x3b\xa1\x84\x10\xef\x55\xf7\xf5\x85\x5d\x07\x1d\x90\x66\xb3\x90\x29\x3a\x64\x82\xcc\x50\x0b\xc3\x69\x3e\xa8\x69\x51\x7c\xc3\x29\x6f\xde\x12\xb0\x9a\x9a\x45\x99\x26\xbb\x64\x4c\x6b\x51\x32\x63\x97\x8b\x69\x0e\x04\xdc\x7a\x27\xd2\x79\xdf\x97\x8c\x17\xfa\xbf\xf1\x05\x3b\x30\x5e\x3b\xe6\x64\x3f\xf3\x62\x96\x6a\xa5\x1d\xe3\x8a\xa3\xa8\x80\x6e\xf6\xa0\x86\x55\xdf\xae\x74\x35\xcd\x7e\xcd\x1e\xaf\xa4\x52\x79\x79\xd7\x4c\xd7\x45\xa6\x4c\xbc\xa9\x63\x63\x2f\x11\x50\xba\xa3\xfe\x5b\x94\xa9\x56\xff\x73\x5d\x73\x19\xd7\x6d\x4b\x6b\xf1\x7c\x60\x4c\xb7\x3a\x90\x4c\x3b\x29\xe8\x71\x8f\x8e\x67\x7a\x29\x64\x5c\x1e\xfe\xae\xe0\xbc\x57\x5c\xe3\x5f\xdf\x9f\x69\xa9\xf2\xbd\x8c\x67\xbc\xc8\x1a\xf5\xbe\x5a\xe5\xeb\x5c\xae\x20\x78\x56\x65\x10\x44\xeb\xd7\x35\x7e\xde\xd5\x45\x6c\x0b\x01\x55\x9c\xfc\xe5\xed\x35\xe1\x79\xf3\x7d\xb5\xcc\x8a\x18\x7d\x28\x6e\xab\x9d\x6a\xb3\xed\x56\xff\x3b\x6b\x54\x55\xeb\x95\x7d\x3a\x39\x83\x77\x36\x79\x55\xc2\x02\xaf\xd7\xfa\xf6\x21\x5f\x01\x7d\xea\x8b\x73\x94\x38\xd7\x26\x1e\x7f\x59\x15\x8c\x23\x4d\x10\x10\x39\xd6\x95\xd6\xcf\x80\x8b\x64\x3c\xe3\x59\xf3\x54\x2e\x0d\xcb\xb2\x92\xa5\x02\x1e\x3e\xa2\x77\x52\x39\x6a\x5f\xe7\x8f\x67\x0f\x0f\x0f\x67\xeb\xaa\xde\x9c\xed\xea\x02\xd7\xb5\xd5\x7c\xb4\xbc\xd7\xaa\x8c\x12\x3f\x5d\xbf\x3b\xfb\x0f\xc2\xb5\xd6\xb7\x55\x26\xd6\xef\x3b\x85\xcc\x1c\xa8\x2e\x6d\xf5\x82\x45\x10\xd5\x1f\x53\xf4\x4f\xc2\x1f\xf5\x75\xf0\xa6\x4d\xc1\x47\x4e\xc3\xe2\xbf\x36\x00\xd1\xe9\x65\xd0\x29\x26\xc7\xaf\xd9\x3e\x33\x0c\x2b\x07\x5b\xf7\x26\x7e\xd6\x65\x9e\xdf\xdc\x3e\x6e\x8a\x9b\xdb\x73\x7c\xe5\xf9\xcd\xad\xfe\x7b\x8e\xe5\x9d\xdf\xdc\xea\xbf\x37\xb7\xe7\x07\x5e\xcb\x66\x5b\x95\x8d\x7c\x97\xcb\x62\x65\x1e\x26\x36\xf1\xd3\xfb\xef\x89\xf9\x0a\x9b\x74\x2d\x1f\x95\xad\x96\x4d\xfb\xeb\xd5\xc7\x0f\x58\x83\xbd\xac\x95\x89\x76\x84\x2a\x92\x18\xd5\x46\x54\x1a\x47\xf0\xcd\xc0\xe3\x09\x97\xba\x14\x12\xeb\xa7\x51\xcd\x34\xc9\xfa\xc3\xe3\x4e\xa5\x3d\x70\x6f\x48\xe3\x90\xb1\x5d\xf5\xa8\xf4\x6e\xcd\x0d\xaa\xdd\x09\xaf\x14\x95\xbc\x50\x14\x26\x4e\x38\x57\xf4\xfe\x38\x7e\xa1\x68\x98\x0a\xa4\x2a\x3a\xa1\xe3\x2d\x7a\xa7\xe8\x8f\x8a\x41\xe2\x75\x9d\x95\xcd\xb6\xaa\x95\x4e\x7c\x6f\x12\x7b\xaf\x1d\xb2\x4d\x19\xb9\x6a\x3d\xfe\x95\x50\x30\x3b\xf5\x34\x06\x4b\x1f\x2f\xf9\x8a\xd7\xfc\x9e\xdf\x81\x54\xdb\x77\xd3\x7a\xb7\x35\xa1\x10\x4f\x62\x3f\x35\x9f\xdd\xb6\x7b\xbe\xe9\x2e\xa3\x08\xd8\x8f\x2c\xac\xc7\x93\x51\x96\x58\x72\x45\x9f\x58\x6c\x8d\x8f\x8f\x01\x6c\x00\xbf\x15\x57\xd3\xcb\xac\x28\x6e\xb3\xe5\x6f\x0d\x25\x55\xb9\x94\xa3\x8d\xdc\x54\xf5\x13\x61\xfc\x41\xec\xa7\x8d\xca\xd4\xae\xb9\x04\x82\x7b\x80\x24\x7a\x3e\x70\x23\x66\x09\x92\xbf\xca\x15\xe1\xd7\xe2\xb9\x96\xd9\xea\xe9\x4a\xe9\xdd\x37\x90\xad\xff\x68\xc6\xc5\xb7\x32\x5b\x0d\x91\x79\x03\x0f\x9b\x85\xcd\x7c\x2e\xc5\xf3\xc1\x18\x7d\x94\xf8\x56\x61\x8c\xeb\x96\xb1\x72\xa1\x8e\x78\x24\x80\xf2\x5e\xd0\x93\xb7\x02\x90\x06\xb5\x78\x95\xb2\x83\x12\xe5\x42\x0e\x64\x3d\x04\x1a\x86\x42\x0d\x43\x19\xa5\x8f\x8f\xb4\xd6\x77\x27\xd5\x9b\xa2\x08\xbf\x66\x08\x4f\xfa\x3e\xd9\xc6\xce\x8d\xe4\x47\x84\xda\x38\xfa\x76\x6f\x3c\xe2\x2b\x91\xad\xad\xe9\x57\x2e\x1d\x48\x6a\x5b\xc9\x33\xbd\x6e\x19\xe6\xe7\x03\xaf\xf6\xb2\xae\xf3\x95\x7c\x9f\x6f\x90\x41\xf4\xa4\x51\xfc\x1e\x62\xdb\x36\x26\x9f\x90\xb6\x84\xae\x77\x87\x3b\x08\x02\xe2\xef\xd9\xb5\x8d\xe4\x93\x8b\x6b\x33\x22\x8e\xe2\x44\x24\x7b\x58\xa8\x54\x2c\xf4\xff\xb0\xcd\x48\x43\xc6\x94\xec\x56\xcf\x97\x01\xf7\x9a\xb6\xdd\xd9\x9c\xcb\x28\x5a\x4e\x21\x23\x40\x3c\xd2\x99\x65\xb9\x3e\xc0\x2e\xe1\xd1\xa1\x38\x5c\x33\xbe\x9f\xee\xea\x42\x50\x2a\xdb\x16\x7e\xb6\xad\x59\x43\xd8\x84\x10\xe6\x74\xb7\x1f\x14\xf7\xe4\xff\x84\x9c\x9f\x13\xfd\x2c\xd8\xd7\xd4\x74\x23\xd5\x7d\xb5\x6a\x5b\x65\x98\xe0\xf6\x2e\x05\xb3\xf0\x7d\xb7\x26\x0b\xda\x5d\x80\xf2\xc2\x4e\x6b\x43\x84\xd8\x40\xd3\xfd\x74\x59\x57\x4d\xf3\x4d\xb5\xc9\xf2\x92\x3d\xd7\xc3\x8a\x9a\xde\x78\xd7\xb8\x9c\xc2\xc7\x70\x73\x81\x7f\x78\x50\x88\xf8\x7b\xef\x7b\x26\x7a\x25\xae\x1a\x35\x16\x75\xef\x46\x0d\xe9\xdd\x06\x3d\x2c\x47\x4b\xcd\x7c\x6d\xbe\x2a\x8a\xf6\x53\x6f\x45\xec\xb8\x11\x9d\x9e\x63\xf3\x99\x07\x84\xdd\xe5\xe0\xa5\x6e\xd3\x3a\x5b\x01\xa8\x5f\x56\x30\xc6\xff\xac\xc5\x25\xdf\x73\xc5\xaf\x19\x77\x5e\x26\xd7\x8e\xb0\x82\xde\x59\xf3\xb6\x7e\x35\x2e\xcb\x2c\x8a\x66\x42\x0b\x3d\x50\x20\x26\x13\xd0\x3b\x02\x93\x16\x01\x79\xa8\xb2\x5a\x75\xdd\x88\x7f\x42\x5c\x3f\xbe\x07\xe7\x05\x43\xdf\x33\xfe\x68\x36\x26\x98\x95\x71\xd3\xcc\x6e\x94\xfc\x0b\xce\x56\x83\x87\x92\x13\xed\x02\x88\x98\x46\xe8\xa2\x96\x80\x04\x82\xee\x08\xe3\x0f\x55\x06\x38\x1a\x31\x8d\x88\x7f\x3a\x26\x40\xc5\xc9\x84\x80\xee\x6b\x6a\x88\xea\xf2\xda\xfa\xde\x70\xaf\x17\xbc\x6a\x75\x96\x1d\x11\x76\x97\x7e\xd5\x7a\x22\xe8\x5b\xd3\x00\x6b\x96\x90\x88\xc4\x24\x21\x6c\x62\x3a\xce\x38\x55\x9a\xfc\x68\xa5\xde\x4f\x97\xd9\xf2\x5e\xaf\x58\x6b\xb1\x76\xb5\xfb\x5e\x71\xf2\xe2\x82\x30\x5e\x0d\x17\x48\x7e\x11\x64\x72\xa9\xa6\x77\xbb\x7c\x35\x99\x4c\x2a\x3b\x49\xd7\xf8\x33\x5f\x5b\x5d\x10\x60\x24\x7c\xe5\x70\xb1\x4e\xa3\xe8\x7a\xda\x97\x9c\x94\x7c\xb7\x3e\xb3\x79\xce\xae\xf2\x72\x29\x09\x3f\x7a\x12\x0c\xc5\x2a\xbb\xfb\x5c\x21\x1f\xaa\x52\x9e\xbd\xd7\xf3\x80\x74\xb9\x19\xe3\xde\xe8\xef\xba\xde\x18\xd4\x7b\x9d\xac\xfc\x4b\x36\xfc\x26\x53\xc0\xd9\x35\x78\x72\x07\x05\x30\x3e\xf4\xc0\x1b\xd0\x16\x89\x2f\x67\x16\xb3\x54\x57\xc7\xe8\x91\x8b\xf0\x4e\x9a\x9c\xbc\x33\xd1\x9b\x04\xa8\xb6\x9f\x9c\xe8\x65\x6c\xf2\x9d\x9a\x90\xf9\xe8\x5f\x62\x36\x9d\x5d\x90\x98\x10\x16\x77\xc5\x20\x74\xd1\x7e\x7a\x8f\x4b\x1b\x1b\xa8\x66\xde\xdd\x06\x66\x62\x90\x1a\x48\x1c\x74\x25\xcb\x95\x05\xa1\xf2\xd3\xf0\x34\xf2\x89\x5f\xf3\x3d\x6b\xdb\x7b\x77\xfe\x7b\x6d\xe4\x3b\x14\xb2\x13\x04\xae\x08\xbf\x05\xc6\xd8\x7d\x07\xd9\xc1\xaf\x31\xde\x7a\x3f\x6d\x76\x60\x47\xd5\x29\x00\xe3\xb1\x47\x1b\x21\xe3\x4b\xf1\x67\xad\x7d\x19\x19\x03\xaa\xc4\xf5\xb4\x53\x43\xc4\x05\xbf\x8b\xa2\x4d\x4f\x74\x00\x03\xd2\xe2\x9a\xef\xd3\x40\x2a\xed\xa7\xa0\xff\x47\xd1\xec\xf5\x1e\x22\x91\xaa\x9d\x82\x03\xcc\x53\xc8\x56\xf6\x3b\x88\xc9\xac\x55\x05\xf7\x24\x43\x89\x7e\x2f\xc6\x17\x7c\x39\x6d\xf4\xa6\x28\xe3\x85\x67\x29\x85\x55\x55\xdd\xd7\xd5\xc3\x48\xce\x0b\x7a\x76\xa1\xf5\x4d\xf4\xa1\x82\x2b\xf2\xa1\x1a\x39\x25\xd3\xdf\xc8\x17\x27\xcf\x8a\x85\x9a\xdf\xb7\x2d\x85\x38\xc3\x55\x14\xf5\x62\x84\x56\xba\xb9\xcc\xe9\xc9\x56\xd4\x5a\x64\xf1\xa0\xb1\x66\xaf\x65\xf2\x75\xac\x37\xf9\xaf\x66\xb3\xd7\x40\x5e\xf6\xfa\xab\xd9\xac\x6d\xbf\x9a\x7d\x2d\x84\x90\x10\x93\xd0\x9c\xf6\xb5\x37\xd4\x40\x76\x03\xc2\x77\x42\x76\xe3\xd0\x68\x76\xe4\x25\x11\x42\xec\xf4\xe6\x76\xe7\x0e\x82\x1d\x86\x44\x0d\x88\xaa\xd2\x69\x29\x7a\xc6\x1d\xe9\x91\xbd\x29\xc6\x60\x18\xd5\x1d\x77\x71\xa3\x15\x16\x3d\x48\xa3\x08\xe8\x89\x41\x46\xd5\x8c\x3d\xef\xdc\xfe\x3b\x67\xf3\xdb\x5a\x66\xbf\xe9\xb5\x4f\xd7\x25\x2f\x47\x25\xab\xa0\x5a\xa0\xd2\x74\xac\xdc\x88\xc1\x3b\xde\x21\x5b\xf4\xb4\xdb\xda\x2c\x72\xad\x3d\x02\x9c\x6c\xca\x9e\x2b\x91\x9b\x12\x33\xe0\x34\xca\xd9\x01\x40\x35\x32\xfd\x06\xe7\x47\x5e\x8d\xf1\xd3\xa3\xa8\xab\x4a\xc5\x78\xb9\xa8\xd2\x03\xdd\xf3\x6b\x00\x2d\x1e\xe7\xe0\x4b\xd6\xf9\x45\x58\xf2\x4c\x5f\x40\xe0\xf2\xe1\xd5\x06\x77\x4c\x26\x67\xea\x47\x8a\x1d\x18\xef\xf7\xd9\xd0\xd0\x79\x3e\x00\xaf\x6a\x67\xab\xc0\x55\x07\x1a\x77\xb9\xb8\x48\x91\x14\x15\xb4\x3c\xef\xbd\xac\x58\x64\x7d\xb5\x35\x68\xa5\x2c\x9d\x57\x62\x69\x7b\xda\x7a\x7d\xea\x1e\x82\x33\x3b\x6f\xcb\xb9\x30\xcc\x99\x03\xe9\xa0\xef\x8e\x77\x51\x54\x47\x11\x56\xf1\x1d\xec\xc7\x70\x37\xe5\x25\x50\xc5\xbb\x4f\x00\xbf\x82\x8a\x7b\xaf\xd7\xaf\xc5\x01\x58\xe9\xde\x76\xa6\x74\x14\x9a\xbb\x28\xda\x81\xd7\x3f\xf4\x38\xcd\x44\xb1\xd8\x41\x1f\x57\x69\xdb\x16\x0b\xf2\x12\x7e\x7a\x24\xd9\x05\x38\x1e\x35\x22\xf7\xa0\x65\xd9\xe2\x22\xc5\x68\x01\xaf\x00\x90\xcd\xae\x0c\xb8\x62\xec\x19\x70\xa4\xb3\x44\x67\xcb\xd3\x18\x80\x04\x0a\x18\xb5\xb4\x12\x3a\x0f\x5f\xba\x41\xd2\xe8\x0e\xf0\xc6\x2c\x64\xce\xf4\xeb\xb3\x28\x92\x0b\x02\x62\xa4\x21\x29\x53\x22\xa3\xca\x22\x41\xc1\x49\x8e\xbe\xee\x84\x8e\x31\x8a\x36\xb0\x47\x0b\x0e\x60\x38\xfc\x89\xb3\x44\xc6\x5a\xf2\x60\x17\x36\x00\x49\x57\x57\x1b\x3d\xd2\x27\x64\xa4\x2a\xdd\x06\x87\xc3\x21\x2c\xc7\x88\x67\xc2\x75\xd3\xc7\xea\xa0\x07\x73\xc3\xaf\x79\xce\x78\x9e\xd0\xde\xaa\x4f\x77\xe2\x7a\x68\x52\x7f\x9f\x35\xca\x2d\xf4\x08\xab\x72\xb4\xcc\x8b\x1d\xe3\xa7\x9e\xd7\x0b\xba\x7d\xcc\x2c\xee\x62\xc7\x18\x7f\x85\xc2\xab\x6d\xc9\xb7\x6f\xdf\x7c\x43\x60\x8d\xd2\xfa\x51\x02\x58\x27\x96\x88\x20\x36\x32\x0e\x53\xd5\xc6\xd6\x23\xa6\x85\x00\x24\x2a\x25\x81\x55\x0c\xd4\xa5\x5c\xe8\xe1\xd1\x98\x45\x48\xab\x6a\x99\x28\xf8\x58\x46\x51\xd1\xb6\xb4\x10\xc4\x36\x29\xf8\x8c\x4b\x31\x63\x0c\x96\x7e\xd8\x35\x09\xe9\x7e\x02\xd5\x0e\x55\x6d\x5b\xe8\x0d\x0b\xcf\x93\xc7\x00\xe6\xec\x89\x2f\x2a\x5e\xf0\xeb\x94\xc5\x8f\x3e\xce\xd9\x93\x5e\xbc\x0a\x9e\xa5\x5d\xa1\x7a\xfb\x46\x1f\x60\xbb\x8e\x02\x3e\x58\xf6\xf2\x04\x17\x3e\xd3\x4d\x31\x5c\xbd\xc5\x3a\xea\x75\x90\xe7\x49\x15\xeb\xe2\x6e\x01\x3d\xc8\x7b\x49\x0a\x10\x28\xb4\xb7\x82\x5e\x9a\x15\xda\xad\xa2\x67\x67\x56\x61\x87\xf3\xbb\x21\x75\xbd\x02\x3f\x3a\xbb\xd9\xbe\x86\x4d\xf5\x5f\xaf\x3e\x7e\x38\x11\x5c\x36\xba\xb2\x41\x2e\xbc\xe4\x04\x0c\x44\xb8\x11\xbf\x02\x11\x37\xbc\x9f\xb6\xcf\x98\x36\x50\x1d\xef\x70\xe0\xdc\x76\x27\x15\xe1\x64\x5b\x35\x2a\x0c\x4c\xcf\xd9\xf3\xd5\x22\xef\x07\x93\x79\xd8\x19\x1b\x4b\x3a\x57\xb7\x6d\xc9\x4b\x00\xf3\xb6\x86\x1c\x34\xd3\x74\x90\x61\x60\x9f\x92\x68\xcc\xcc\xb9\x95\x49\x71\x6d\xe6\x08\x37\x73\x26\x2e\x0f\xfc\xf8\x20\x0b\x5c\x98\xb0\xce\x81\x01\x6a\xc0\x8b\xb7\xdb\x7c\x3b\xed\xcd\xb1\x6a\x81\x87\x18\x30\x7c\x06\x22\x1a\xbc\x53\x3c\xb5\x54\xb8\x47\x21\x8c\x89\x10\x84\xb0\xb6\x2c\xe7\xa7\x82\xcf\xcd\x17\xfb\x1f\x8a\x56\x5b\xf7\xb1\x6e\xe5\x82\x9d\x84\x67\x61\xbd\x70\x36\xd8\x8b\xd0\x5a\xe8\xaf\x62\xbe\x81\xe5\x70\xe0\x9d\x94\xef\xc1\xde\x76\xac\xef\xd4\x05\xc0\xf7\x4e\xea\x1e\xea\x6c\xfb\xa6\x28\x4e\xc3\xf9\x1a\x57\x0a\x3d\xd4\xf1\xe4\x4a\x37\x8a\xf3\x7f\xd6\xda\x0a\xe3\x4a\x5c\x19\xd8\xe4\x23\x6e\x7e\x36\x95\xff\xa2\x33\xe6\xd1\x55\xda\x6c\x61\x58\x50\xc0\x68\x6b\x4b\xe6\x6a\xf8\x9c\x0f\xe0\x13\x8d\x3f\x3e\x52\xfc\x1a\x7b\x01\x32\xfd\xea\x1a\x1e\xa5\x76\xd4\xeb\x8e\xdf\x54\x19\x06\x51\xb0\xc0\xe8\x86\xf8\xae\x0c\x90\xe2\x4a\x6f\x78\x97\x7f\x14\x86\xe0\x9e\xa7\x81\x7b\x38\xfb\x7c\xdc\x81\x8b\x32\x50\x9e\x7a\x48\xd9\xdc\xa2\x96\x27\x6a\x6a\x7a\x88\x42\xf8\xa8\xa9\x39\xb2\x0d\xe8\x3b\x47\xb1\x32\x78\x08\x3d\xff\xa2\xc0\x18\x57\x74\x12\x84\xc5\xb0\x18\x09\x76\x77\x65\xf8\x86\x5e\xfc\x21\x76\x20\x95\x6c\x5a\x56\x8a\x92\xdb\x6a\xf5\x44\x8e\x49\xb1\xbb\x20\x1c\xc7\x90\x6a\x0f\x3f\xf3\x62\xa5\xbb\xbf\xd1\x93\xca\x02\x53\x9a\x10\xd8\x6d\x23\x77\xab\xaa\xb1\x80\x53\xc7\x55\x18\xf7\x32\x02\x31\x97\x21\x10\x1d\xbe\x35\x54\xc8\x98\x4a\x9f\x6c\x50\xeb\xb1\x78\x89\xbc\x2f\x9f\x21\x8f\x80\xd7\x04\xa7\x4a\x8f\xf7\xb5\xaf\x5c\x82\xd1\xaa\xa3\xe7\xb9\x9c\x7e\x7a\xff\xfd\xb7\x4a\x6d\xcd\xde\xd1\xa7\xdf\x45\x32\x36\x25\x9e\x67\x80\xab\x70\xf1\xea\xd5\x57\xf1\xab\xd9\xd7\x07\xfe\xbb\xea\x1f\x5d\x3d\xde\xd7\x94\xcd\x9f\xa6\xcb\xaa\x6e\xc4\x78\xfc\xbb\x8a\x22\xf2\x90\xab\xfb\xcb\x5a\xae\x64\xa9\xf2\xac\x68\x48\x5e\x8e\x7e\x57\xfc\x09\x1e\x14\xbf\x2b\xc8\x66\x2a\xeb\x76\x4d\x5d\x0f\x19\xb7\x8d\x8a\x67\x5a\x9f\xc5\x92\xdb\x56\x17\x3c\xce\x03\xeb\x9c\x55\x6c\x02\x9e\xef\xc0\x2d\x22\x37\xd5\xd3\x9b\x0e\xa0\x7a\xa5\x39\xda\x09\x73\xb0\xda\xe5\xb8\x8b\xd4\x57\x8d\x04\xd7\x52\x9e\x4f\xb7\x59\xd3\x3c\x54\xf5\x8a\x71\x78\x1a\x15\xdb\x0e\xef\xd3\x4f\xac\x01\xcc\xb3\x4b\x58\x94\xe9\xdc\xcb\x68\x77\x46\x80\x15\xd5\xb3\xfd\x0e\xa5\xd1\xee\x11\xfd\x72\xef\x53\xdb\x56\x2e\xc8\xa7\x33\xd3\x53\x72\x75\x06\xb4\xbe\x29\x20\x8b\x0e\xa4\x0b\x12\x76\x2d\x61\x5c\xb2\xfa\xd8\x4e\x80\x1e\x14\x6c\x5e\x0d\xb9\x67\x7b\x23\xa7\x02\x3d\x37\x13\xf5\xb4\x2a\x8b\x2a\x5b\xc1\x0f\xd0\x9b\xe0\x17\xec\xac\xe1\x97\xd9\x4f\xc3\x6f\xd8\xac\x82\x32\xb6\xbc\xcf\xca\x3b\xa4\xd9\xe6\xc6\x80\x00\xea\x5b\x6d\x6d\x0b\xb1\x51\xc2\x20\x75\x00\x30\x0c\xf5\xa6\x44\xd1\x19\x37\x39\x59\xac\xa8\x4d\xe7\xb5\xa7\xa2\xe9\x1b\xbf\xa8\x85\x4d\x4a\xdb\x76\x30\x1b\x9e\x5a\x21\xfd\x87\xdb\xc3\x18\xe3\x20\xdc\x61\x03\xce\x57\x5e\x4e\xf9\xa8\x92\xe7\xdb\xbc\xcc\xea\xa7\xb8\x4b\x3e\xc4\xcf\x70\xbe\x15\x66\x3c\x70\x08\x22\x39\x3e\x95\xa0\x0c\x02\x34\x5c\xab\x56\x94\xf1\xac\xd7\xb6\xb6\x45\x2b\x6a\xbf\x9c\x7b\xc1\x31\xa6\xed\x93\xae\x17\xb2\x78\xb0\xed\xbd\xce\xd4\xaa\x73\xed\x99\x12\xa2\xe8\x94\xcd\xa4\x8a\xa2\x0c\xd0\x29\x79\xa5\xdf\x8f\x3d\x67\x8d\xdf\x60\x25\xc9\x03\x2b\x1c\x1e\x88\x23\x6a\x54\x68\x3c\xa9\xac\xf1\xe4\x70\x74\xb0\x00\xaf\xa9\xa8\xe5\x54\x39\xad\x42\x49\x7f\x42\xf8\x6a\x11\x40\xd1\xe7\x5b\x25\xf0\x84\x3e\x38\x83\x73\xa7\xbb\x98\xc5\x1c\xe3\x76\x67\xb0\x7c\x14\x1c\xd3\x9e\x48\x97\xcb\xcd\x60\xfa\xe3\x59\x77\x27\x38\xcd\x35\x6f\x3b\xbf\xb9\xa5\x49\xac\x4b\x6d\x75\x46\x86\xc9\x70\x84\xfb\x05\x9a\x94\xf4\x75\x65\x4f\x6f\x62\x5c\x0e\x36\x96\xd3\xe0\x02\xcd\xc9\x11\xc8\x3b\x13\xb1\xf9\xa5\x9b\x8b\x1f\x37\x2a\xc2\xb8\x68\xdd\xb0\x6b\xcc\x4e\x48\x1f\xbf\xa3\x33\x2a\x81\x63\x58\x28\xb5\x4a\xd3\x35\x6f\x94\xaa\x9b\xcf\xc8\xeb\x5a\x5c\x51\xf2\x1a\xf3\xfe\x89\x30\x0c\x72\x0a\x1e\x46\x56\x79\x70\xa6\x7a\x36\x27\xf8\xb1\xcd\x70\x89\xd7\xbc\xa9\x97\x71\xa9\x05\xfb\x81\x4d\xab\x92\x12\x3d\xa9\x46\x66\x7b\x17\x3a\xc2\xd6\xd6\x7b\x93\xf1\x1c\xe5\x92\x56\xf9\xa8\x27\x86\x70\xdb\xf9\xf5\xec\x6b\x58\x00\xf1\x52\x37\xc8\x5b\x50\xbf\x03\x0c\x9e\x5a\x2b\x86\x03\xe3\x3a\x8f\xa2\x9c\x76\xae\xa1\x3f\x29\xfe\x49\x89\x45\xca\x7f\x56\xe2\x9c\x0a\x76\x93\xd0\x44\x44\xed\x0b\xd6\xde\x24\xe8\x0f\xea\x8d\x5b\xbd\x89\xda\xc6\x64\x69\x8e\x7a\xf1\xf0\x7e\x6b\x4f\x7e\x8f\x3d\x5f\x3f\x29\x74\x1e\x87\x2d\x1d\x86\x5f\x4c\xc8\x2f\x9e\x75\x3f\x50\x9e\xd1\x99\x46\x0e\x0e\x22\xfd\x22\x38\xe4\xdf\x92\xd3\x6c\x37\x3c\x13\x63\x24\xa7\x80\x9c\x51\x44\x7f\x76\x08\x03\xbb\xba\x60\x09\xd9\xd5\x05\x19\xc0\xa8\x30\xd6\x7b\x38\x94\x91\xff\xd5\x43\x99\xee\x9d\xe6\xe8\x84\xe8\xbf\x18\x05\x9d\xb5\x2d\xc1\xaf\x80\xde\x0c\x3c\x75\x1c\xfe\x93\xa9\xbe\x6d\x56\xb1\xa1\xbd\x14\x96\xf4\x12\xa8\x56\x79\x83\x14\x9e\x25\x72\x91\xa5\x42\xff\xe7\x4e\x5e\x7e\xc6\x93\x97\x49\xcd\xe2\x5e\x3b\x41\xfb\x78\x07\x3c\xb6\xbd\xec\x99\x8c\xc9\x09\xae\x98\x35\xcc\x4f\xcf\x6e\x88\xc3\x1d\x5d\x30\x02\xbb\xa1\xb5\x59\x76\x1e\xb9\xf5\x84\x8c\x1e\xb2\x66\x54\x56\x6a\xa4\x47\x91\x6e\x31\x5e\x2d\x66\xe9\x81\x87\xad\x21\x70\xc3\xce\x73\x71\xb9\xa8\x53\x7e\x19\x80\xbb\xb1\xe7\x4a\xb8\x78\xd5\x03\x2f\x07\x10\x62\x3b\xde\xb6\xe4\x8a\x5e\xda\xd0\xf6\x1f\xf4\x44\xad\x59\x0c\xc5\xe5\x5c\x2e\xea\x14\x3e\x3e\x6c\x6f\xd5\x6b\x4a\x3d\x8a\x77\xcd\x3d\xad\x19\xc0\xbb\x6e\x68\xce\xf4\x1c\x42\xb4\xf6\x4a\xe4\x1d\x39\x85\x95\x43\xe0\x28\x8f\x07\xb4\xdf\x5e\x03\xdc\x07\xd4\x55\x50\xfa\x93\x12\x6f\xa7\xf9\x66\x8b\x1b\x2e\x18\x49\x03\x19\xa9\x1e\x75\x7a\x9f\xa0\xc7\x5e\x29\x6b\x7d\x4f\x90\xd7\x7a\xb0\xfd\xe9\xf5\x39\xfe\xf1\x2f\x08\x7f\x25\x84\xf8\x49\x79\x7b\x05\x77\xd4\x67\xbc\x5f\xa0\x88\xe1\x6d\xf8\xb1\xef\x5e\xb2\x48\x63\x3a\x18\x90\x4e\xd1\x64\xa1\x85\xb4\x6a\x5b\x3a\xf4\x95\x09\xa5\xb5\xa0\x5f\xfc\x9d\xac\x7f\x92\x7d\x9b\x35\x52\x27\xc3\xd1\xf5\x5b\xe7\xb6\x6e\x3c\xbb\x06\x04\x1d\x63\xb1\x12\x6f\x81\x32\xae\x8c\xa2\x45\xca\x69\x2e\x3e\xa0\xef\x87\x64\x2c\x59\xa8\xde\x1b\xf2\xc5\x45\xca\xd2\x98\xe6\xe2\x11\x81\x79\x15\xaf\xa0\x67\x2b\x47\x78\x77\x45\x2b\xd6\x09\xe3\xab\xe9\x46\xd6\x77\x92\x2e\x52\xad\xff\x76\xdb\x31\x86\x22\x14\x64\x8f\x31\x17\x80\xc6\xf4\x39\x01\x05\x3b\xc7\x46\x48\x1f\xa3\xc0\xee\x42\xcf\x2e\x5e\x23\x21\xdc\x5e\xcf\x40\xb4\x9e\xeb\x8d\xb7\xde\xa7\xe3\xd5\x8c\xeb\x6b\xf0\x9e\xa6\x81\xf1\x28\x56\x03\x98\xba\x0a\x39\x59\x7f\xf8\x78\x75\x4d\x18\x9f\xbd\xce\xba\xef\x3b\x36\xbc\xe4\x6d\xdb\xb7\xbd\xa0\x5f\x99\xb1\xc8\xb2\x1e\x72\xb1\x0c\x66\x21\xcf\xa6\x3a\x37\xad\x13\xbd\x64\xae\xf2\xfd\x9f\x1c\x24\x1c\xf5\x46\xa0\xee\x10\x08\x18\xd6\xb3\x50\xaf\x5c\x76\xea\x96\x51\x14\xae\xbd\xd9\xd1\x06\xb9\xf4\x71\x1a\xab\xb6\xf5\xcc\xfc\xa0\x3b\x2b\x2e\x53\x00\x2d\x37\x86\x8a\xde\xee\xd6\x60\x1c\x7a\xbd\x13\x58\xfd\x6a\xb9\xa5\x0e\x80\x73\x68\x27\x2f\x2c\x91\xd1\xc1\x6e\x6d\xf5\x2b\x70\x17\x0c\x21\x28\x1f\xe1\xe7\x69\xb0\x20\x77\x4e\xd2\x71\x2e\x1b\xfa\x42\x02\x51\x7a\x14\x3c\x0a\x9e\x0f\x73\xa2\x55\xe4\x7c\x09\x6c\xf6\x1d\xf5\x9f\x23\x3b\x14\xa4\x96\x45\xa6\xf2\x3d\x80\x4a\x8a\xa5\xa9\x03\x45\x6c\x5c\x53\x34\x18\x4b\xf9\xae\x4b\x28\x80\xb8\x8f\xd3\x80\x41\xb1\x68\x5b\xb2\xce\x1f\x01\xea\x0d\x20\xc1\xcf\x2e\x5e\xd3\x6a\xb2\xf3\x97\xbc\x9d\xaa\x08\x4b\x68\x26\x68\x2d\x96\xae\x12\x94\xb1\xa9\xaa\xb6\x3c\x17\x35\x70\xf5\x81\x01\xdb\xe3\x0c\xac\x58\xdb\xce\x78\xee\x27\xed\x90\x92\x79\x63\x43\xf9\x95\x0d\x35\x2d\x03\xa0\x5e\x3d\xad\x0c\x44\xb2\x9a\x02\xa2\x29\x5d\xeb\xbf\x78\x75\xd6\xe8\xff\x27\x59\x97\x45\xbf\x1d\xf2\xe8\x1f\xe6\xfa\xac\x81\x3f\x93\x9c\x71\xb2\x6b\xb4\x6c\xcb\xcb\x91\x4a\xd4\x14\x2e\xec\x7b\xd7\x2c\xa6\x47\xe8\x03\x6b\xff\x9d\x13\x01\x1c\x6e\x7c\x20\x57\xf0\x5a\x9b\x6f\x09\xad\xbd\x66\xc8\x17\xe5\x59\x0f\xab\xde\xd8\xc0\xe8\xe6\x53\x20\x2a\x6e\xf1\x42\xf0\x8f\x21\xb3\x18\x98\x2d\xb1\xd4\xa9\x1b\x7b\x16\x91\x00\x42\x13\x1c\x1e\x4c\x1f\xe9\xa1\x4e\xea\x53\xc6\x9a\xc4\x42\x0b\x0c\x71\x32\xf2\x52\x6f\xed\x7c\x9b\xa5\x1f\x83\xc9\x9f\x55\xb5\x8d\x25\xb4\x5a\x39\xdd\x66\x77\xf2\x1f\x58\x29\x0e\xac\xff\x12\xdb\x09\xef\x7c\xc2\x3b\x07\x16\xc3\x43\x33\xcc\x32\x3b\x58\x20\x02\xee\x18\xe5\x7d\xbd\x75\xed\xcc\x9d\x3e\x14\x89\xfd\x3a\x9e\x8b\xb0\x30\xad\x6e\x75\x83\x1b\xe7\x41\xed\xcf\x39\xa6\x4e\x7f\x2b\x1e\xe1\x1a\x06\x40\x37\xbf\x8e\x1a\x80\xeb\xe6\xc2\xdb\x3f\x80\x91\x4f\xef\x2d\x6c\x54\x97\x59\x6e\xac\xfd\x15\x2c\xc2\x42\x94\xb0\xae\xb7\x2d\xfe\xee\xe5\x05\xb8\x09\x37\xf9\x07\xe4\x04\x98\x6c\x3d\x20\x29\x19\x45\x12\xe9\x62\x8e\x18\x0d\x68\x0e\x22\xc5\xd5\x9e\xe1\x80\xee\x31\xb3\x5f\x57\x5b\xc7\xc9\xce\x78\x6e\x46\x73\x2f\xd3\xf7\x72\xad\xba\x5c\xf6\x04\x06\x9a\x1b\x27\x65\x0e\xff\xbb\x36\x46\x4e\xad\xeb\x6a\x8b\xa5\x42\x87\x98\x89\x89\x6f\xe8\x67\x05\x56\x51\x0c\x31\x3c\x70\xbf\x3d\xff\xad\xa8\x16\xaf\xb3\xf0\xe9\xae\xe9\xbf\xa0\x55\x83\x07\xad\x0d\xbc\x6d\x6b\x79\x08\xd1\x7e\x1d\xbf\x5c\x4c\xbc\xb1\x4c\xb8\xe3\xa3\xc3\x74\x33\xfa\xfd\xf0\x47\x65\x43\xbf\x2a\x11\x64\xd1\x5a\x2a\x22\x18\x07\x30\x84\x5f\x44\xf2\x09\x0e\x8d\x54\xb2\xa4\x16\x32\xfe\x3f\xfd\x31\xa0\xf7\x12\xde\x1c\x65\x03\xb4\xd5\x75\x52\x2f\xf2\x14\x20\xe0\xe6\x5a\x32\xd8\xcf\xa0\x55\x52\xfb\x93\x35\x2e\x79\x95\x94\x71\xed\x4f\x6d\x66\x60\xe6\x0e\x5a\xe6\xf0\x41\x62\x4f\x0f\xd4\x79\x4b\xcc\x2a\x14\x9c\x98\x95\x01\x43\x6b\x99\x22\x55\xed\x36\x7f\x94\xc5\x0f\x96\xdd\xf7\x08\x16\x42\x39\xe8\x0c\x64\x64\x2e\x19\x7f\xef\xd8\x9f\x13\x18\xf6\xdd\x42\xb5\x28\x53\xa0\x91\xd5\x3a\x8c\xd7\x91\x86\xb1\xdc\x31\x2c\xc3\x00\x8f\x0d\x71\x8c\xd7\x6b\x19\x6f\x20\x44\x15\x1e\x72\xac\xb3\xa0\x96\x93\x49\x66\xad\x2b\x71\xc3\x09\x89\x49\xb5\x53\x90\xec\x3d\x5f\x23\x09\xed\xba\x5c\x54\xe9\x60\x2c\x5c\xbf\xdd\x74\xbf\x79\x48\xd5\x5e\x90\xa5\x5e\x6d\xdb\x96\xc2\xa9\xbf\x6c\xdb\x31\x2e\x11\x96\xc2\x2e\xb6\x04\xc3\xee\x50\xe3\xb3\x03\xc7\xe4\x81\xc1\x33\x03\x64\x7b\xb7\xe6\xe3\x57\xb0\x44\x2e\xdc\x77\xa6\xb1\x74\xc2\xaa\x2f\xb5\x16\x64\x09\xa2\x13\xb2\x85\x63\x30\xc1\x21\x18\xe6\xe7\x8e\x13\x4e\x82\x30\x84\x1d\x64\x55\x14\xfa\x79\x5e\x07\x57\x36\x83\xa5\x5e\xc6\x0c\xe1\x55\xf7\x72\x66\x43\x66\x04\x32\xd1\x1a\xea\x59\x9e\xb3\x38\xa0\xa5\xe5\x39\x3b\xf0\x86\x97\x89\x85\xbe\x31\x27\x7e\xde\x70\xed\x1c\x44\x79\x77\xfa\xcc\x7b\x47\xd7\xfe\x21\x78\x70\x3c\xce\x3b\x2f\xb1\x7e\x34\xd0\x67\xe6\x39\xca\x2f\x20\x41\x38\x8e\x0d\xbf\xcd\x7b\xe6\xa9\x3e\x86\x37\xce\x26\x88\x2c\xd7\x9f\xc3\x77\xe5\xd1\x23\xbd\x07\xd6\x6b\xf7\x04\x3b\x70\x0b\xe0\xf0\x07\xbc\x0f\x1e\x49\x83\x7e\xc7\x89\xa7\xdc\x33\x7a\x59\x3a\x82\x96\xf2\x5e\x4f\x5e\xbe\x24\xe6\xdc\x4f\x27\x28\x0e\x4e\xd1\x2f\x09\x7c\xc2\x7d\xb5\xff\x6c\x34\xfc\xa6\xda\x35\x52\x96\x4a\xd6\x7a\xc6\xc3\x55\x21\xb3\xbd\xa4\xaa\x6d\xa5\x2f\x7e\xc8\x6d\xb1\xab\x47\x10\x92\x3e\x32\x71\xea\x23\x1b\xa0\x3e\xaa\x65\x93\xff\x2e\x47\x38\xea\x46\xcb\x22\x5f\xfe\x36\x5a\xdd\x16\xf8\x03\x0a\x5d\x55\x0f\x25\xfe\xda\x6d\xf1\xaf\xde\x18\xe2\x2f\x5d\x45\xf3\x6b\xa7\x46\x5d\x8d\x46\x5d\x75\x46\x68\xed\x1e\x61\x90\xf0\x08\x83\x8b\x47\xbf\xc9\x27\x28\xf7\x37\xf9\xb4\xad\x65\xd3\xe8\x1f\xbb\xed\xc8\x84\x61\x6c\x64\xb9\x23\x9e\x53\xd0\x91\xc8\x5c\x97\xc0\xa3\x35\xd4\x36\xb3\x23\x9c\xd4\xc4\x76\x5d\x89\xfd\x0d\x68\xc9\x18\xb5\x69\x5c\x2c\x4a\x17\x8b\xf8\x17\x25\xce\xff\xb9\xb8\x69\x6e\x76\xef\xde\xbe\x7b\x77\xf3\xf8\x66\x96\x4e\xda\xde\xf5\x0b\x00\x1a\xdb\xd6\xd5\xe3\xd3\x70\xe4\x2f\x9a\x5d\x8f\x0c\x6d\x68\x40\x80\xe8\x61\x8c\x61\x29\xf5\x7e\xc0\x63\xb1\x14\x0d\x2a\xe7\xdd\xbe\xf2\x15\xd3\xdb\xf9\x63\x35\x40\xda\xdd\xa0\x09\x9e\xaf\x6d\xa8\x46\xbf\x04\xc0\x2c\x04\x73\xa3\x90\xfe\x9f\xb6\xbd\x32\x46\x48\x9e\x6b\x6d\xfd\xbe\x2a\x56\x3f\xca\x6c\xf5\x14\x62\xf1\x00\x38\x71\xb6\x7a\xfa\x7b\x96\xab\xc9\x24\x36\x57\x40\x13\x02\x5e\x17\xe0\x60\x27\x82\x70\x52\x6b\x72\xf9\xeb\xd5\xc7\x0f\xc2\x0b\x49\xba\x72\x51\xae\xe2\x0d\x3c\xfb\xce\xbc\x48\x6c\xe0\x12\xc1\x4b\xc4\x23\xbf\x9a\x2e\xb3\x8d\x2c\x2e\xb3\x46\x8a\x4f\xfc\x0a\x8d\xdf\x0f\xf0\xfc\x83\x83\xd6\x87\x47\x3e\xec\x36\xb2\xce\x97\x03\x7c\x22\xf8\x14\x95\x76\x31\xf0\x76\x3a\x42\xf9\x8e\xde\x42\x6b\x9d\xe3\xbc\xf9\x90\x7d\xa0\xd2\x27\xaf\x97\x08\x7c\xaf\xea\x7c\x73\x1a\x27\x09\x10\xc4\xa8\x0c\x82\x25\xfe\x02\x6e\xf0\x07\x4e\xec\x53\xdd\x00\x40\x64\xf1\x28\xc2\xbf\xd3\x6c\xb3\xb2\xbf\x29\xc1\x40\x23\xc2\x17\xe9\x00\x53\xfc\x95\x19\x9d\xff\x50\xe2\x72\xfa\xeb\xdf\x74\x4e\xfe\x37\xfd\xfb\x45\xc7\xf3\x53\x56\x97\x55\xb9\x2e\xf2\xe5\x20\xae\xd3\xe5\xf4\x85\xd6\xfe\xa2\x88\xea\x5f\x7f\x53\x40\x95\x62\xcb\x72\x77\xcc\xe5\x3f\x14\xe3\x57\x07\x3e\x88\x85\xee\xe7\xd3\x45\x5d\xe9\xac\x6c\xfe\x3f\xfe\x6f\x00\x00\x00\xff\xff\xc8\xdd\x9a\x28\x95\x5d\x01\x00") -func pkgUiStaticVendorJsJquery331MinJsBytes() ([]byte, error) { +func pkgUiStaticVendorJsJquery350MinJsBytes() ([]byte, error) { return bindataRead( - _pkgUiStaticVendorJsJquery331MinJs, - "pkg/ui/static/vendor/js/jquery-3.3.1.min.js", + _pkgUiStaticVendorJsJquery350MinJs, + "pkg/ui/static/vendor/js/jquery-3.5.0.min.js", ) } -func pkgUiStaticVendorJsJquery331MinJs() (*asset, error) { - bytes, err := pkgUiStaticVendorJsJquery331MinJsBytes() +func pkgUiStaticVendorJsJquery350MinJs() (*asset, error) { + bytes, err := pkgUiStaticVendorJsJquery350MinJsBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/js/jquery-3.3.1.min.js", size: 86927, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/js/jquery-3.5.0.min.js", size: 89493, mode: os.FileMode(436), modTime: time.Unix(1588865307, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1320,27 +1571,7 @@ func pkgUiStaticVendorJsJqueryHotkeysJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/js/jquery.hotkeys.js", size: 4490, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _pkgUiStaticVendorJsJqueryMinJs = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\xbd\x7d\x93\xa3\x36\xd6\x28\xfe\xff\xad\xba\xdf\xa1\xcd\xce\x43\x50\x5b\xa6\xed\x49\xb2\xf7\x09\x6e\x0d\x35\xc9\x64\x76\xb3\x9b\xb7\xcd\x4c\x5e\xf6\xc1\x4c\x4a\x80\xc0\xb8\x31\xb8\x01\x77\xf7\xc4\xb0\x9f\xfd\x57\x3a\x92\x40\x60\x3c\xc9\x3e\xcf\xef\x56\xdd\x9a\x9a\x36\xa0\x77\xe9\xe8\xe8\x9c\xa3\xf3\x72\x73\x3d\xbb\xda\xfd\xe3\xc8\xca\xf7\x57\x0f\x1f\xdb\xcf\xed\xd5\x55\x73\x65\x85\xe8\xea\x6f\x6f\xae\x5e\x17\xc7\x3c\xa2\x75\x5a\xe4\x57\x34\x8f\xae\x8a\x7a\xcb\xca\xab\xb0\xc8\xeb\x32\x0d\x8e\x75\x51\x56\x57\xcd\xd5\xee\x9e\x17\xb5\x8b\x32\xb9\xc9\xd2\x90\xe5\x15\xbb\xba\xbe\xf9\xdf\xff\x6b\x16\x1f\xf3\x90\x97\xb4\x28\x0e\xd0\xc9\x38\x56\xec\xaa\xaa\xcb\x34\xac\x8d\xb5\x51\x04\x3b\x16\xd6\x06\x21\xf5\xfb\x03\x2b\xe2\xab\x7d\x11\x1d\x33\x66\x9a\x17\x12\x6c\xf6\x74\x28\xca\xba\x72\x87\xaf\x84\xda\x51\x11\x1e\xf7\x2c\xaf\xdd\xc0\xa2\x78\xb6\x44\x4e\xdf\x2a\x3a\xa5\xb1\x35\xeb\xb3\xa0\x7a\x5b\x16\x8f\x57\x39\x7b\xbc\xfa\xb2\x2c\x8b\xd2\x32\xe4\xa0\x4b\x76\x7f\x4c\x4b\x56\x5d\xd1\xab\xc7\x34\x8f\x8a\xc7\xab\xc7\xb4\xde\x5e\xd1\x2b\x55\xd2\x40\xeb\x92\xd5\xc7\x32\xbf\x0a\x2c\x8a\x5a\x07\xfe\x5a\xc6\x31\x8f\x58\x9c\xe6\x2c\x32\x66\xaa\xbb\xa2\xbc\x2b\x7e\x9c\x7a\x9b\x56\xf8\x03\xd3\xf0\x40\xcb\xab\x90\x78\x3e\x8e\xb4\x91\x60\x46\xbe\x83\x49\xb0\x13\x56\x7f\x5f\x16\x75\xc1\xeb\xfe\x2e\xc6\x31\x09\xed\x8a\xcf\x30\x4e\x48\x68\x87\x45\x1e\xd2\x1a\x6f\x49\x68\x1f\x8e\xd5\x16\xa7\x24\xb4\xd3\x3c\x62\x4f\xdf\xc5\x78\x47\x4e\x2d\xbe\x23\x3b\xbb\x2e\xde\xd4\x65\x9a\x27\x38\x23\x3b\x7b\x4b\xab\xef\x1e\xf3\xef\xcb\xe2\xc0\xca\xfa\x3d\xde\x93\xac\x4f\xcf\xc9\xde\x0e\x69\x96\x59\xa2\x69\x84\x0b\x72\x6a\xd7\xaa\xeb\x57\x07\xd1\xf9\x80\x04\x4d\x13\xc9\x6e\x07\x76\x58\x32\x5a\xb3\x2f\x33\xc6\xbb\x6d\x19\x55\x58\xa6\x07\x3e\x57\xa1\x5d\xb3\xa7\x9a\x50\x1c\xd8\x5b\x46\x23\x9b\x1e\x0e\x2c\x8f\xbe\xd8\xa6\x59\x64\x85\xc8\x3e\xd0\x92\xe5\xf5\xb7\x45\xc4\xec\x92\xed\x8b\x07\xa6\x52\x5a\x5e\xf1\x3d\x31\x00\x06\x0d\x5c\x92\xe1\xd4\xc9\x25\xe0\xeb\x57\xda\x71\x6e\xa7\x79\x5a\x43\x4a\x8b\x2b\x72\xf3\xce\xdb\x54\x9b\xe3\xeb\x2f\x5f\xbf\xde\x3c\xbd\x5c\xfa\xf3\x66\xf4\xfe\xec\x26\xc1\x35\xb9\x79\xb7\xd8\x57\x8b\x1b\x7c\x24\x37\x0b\xcb\xa3\x8b\xdf\x7c\x74\x93\xe0\x87\xe9\x96\x02\xbb\x2e\x7e\x3c\x1c\x58\xf9\x05\xad\x98\x85\xda\x35\x6f\x96\x94\xf6\x41\x2d\x0a\x39\x09\xd8\x77\xee\x71\x58\xe4\x55\x5d\x1e\xc3\xba\x28\x9d\x12\x67\x2c\x4f\xea\xad\xb3\xc4\x75\xf1\xb2\x2c\xe9\xfb\x1e\x2a\xbb\xca\x63\x31\xdf\x1c\x44\x50\x8b\x13\x56\x0f\x20\x57\x8d\xf5\x98\x65\x84\x50\x57\xcf\xec\xd0\xdb\xa5\xcb\x9f\x3c\x3a\xe7\x3f\xb6\x68\xcc\x77\xc4\x37\xbf\xc5\x1c\x1e\xde\xd4\x34\xbc\x1b\x54\xc9\x27\x37\x20\xa5\xbd\x67\x65\xc2\xa0\x2a\x5b\xeb\xb4\x85\x30\xed\xa1\xdc\x3e\x94\xec\x41\x80\x02\x01\x20\x0e\x5a\xcc\x68\xb8\x9d\xea\x63\x69\xf3\x14\xa8\x10\x53\xd4\xe2\x3d\x3d\x4c\x65\x83\x06\xbb\x9e\x59\xa5\xbd\xa7\x07\x6b\xb8\x41\x02\x1c\x76\xd9\xa9\x18\x71\x80\x43\xbe\xc0\x88\xaf\x31\x07\xfd\x89\x89\x1c\x55\x1c\x73\x70\xcb\xde\xcb\xfe\x94\x09\xec\xa9\x8a\x57\x10\xa7\x65\x55\x5f\xaa\x80\xdd\x5b\x4b\xd4\xe2\x8c\x7e\x30\xcb\x62\x85\x5a\xcc\xee\x27\xe6\x55\x5b\x09\x1c\x92\x39\x9d\x5b\x7c\x99\x02\x67\xd9\x4d\xea\xa8\x9f\xe1\x0b\xb2\x34\xcd\xf0\x36\x70\x3d\x58\xb8\xd0\xf7\x1d\xcf\xe7\xd5\xe7\xd1\xc5\x51\x76\xab\xd2\x34\xe7\x0b\x28\x16\xde\xd9\xe2\xaa\x28\x6b\x27\xb4\xf9\x0f\xae\x0e\x30\x6d\xa1\x2d\x1e\x5a\x5c\xda\xec\xa9\x66\x79\x44\x60\x0f\xc9\x67\xad\x3d\x3e\x1c\x8a\xf9\xbc\x47\x98\xe1\x18\x27\xa4\x9b\x44\x6f\xe9\x37\xcd\xa9\xc5\x5b\xb2\xc2\x69\xff\x59\x0d\x7b\x47\x66\xab\x75\xcc\xf1\x6a\x50\x14\x19\xa3\x79\x8f\xc5\x13\xd3\xb4\x76\x24\x19\x54\xb6\x95\x95\xcd\xe7\x08\x9f\xa1\xfd\xa4\x69\x4a\x3b\xad\x5e\xab\x7e\x25\xa8\x69\xac\x84\x9c\x5a\x84\xb7\x84\x90\xd4\x34\xad\x44\x40\xe6\x76\xb1\x40\xeb\xed\x6d\xba\xe6\x15\xa5\xb1\xc5\xb7\xcc\x8c\x58\x74\xd0\x12\x42\xbc\x5f\xc1\x55\x9a\x5f\x51\x14\x92\xc4\x0b\x00\xe7\xf2\x9f\x64\x46\x48\xc4\xbb\x67\x9a\xfc\x87\xb7\xfa\x7d\x46\xd3\x5c\xcc\xb3\x15\xf1\x86\x19\x81\x5d\x6c\xa7\x15\xfc\x5a\x11\x42\xc8\xb5\x98\x6b\x31\x32\x5b\x71\xbc\x6c\x9a\xc3\x0c\x21\x72\x43\xbe\x9a\x0e\xa4\x8d\xeb\x84\xd4\x53\x8b\x79\x37\x88\x5a\x0f\x6b\x87\x63\x1c\x21\xe4\x3c\x14\x69\x74\xb5\x94\xbd\x82\x2c\x11\xea\x80\x28\xe9\x17\xd0\x3a\xb1\xa7\x03\xcd\xa3\xc2\x91\xe7\x98\x31\xb7\xee\xe7\xdf\xd0\x7a\x6b\x97\xfc\xf3\xde\x42\xc8\x2e\xd9\x21\xa3\x21\xb3\x6e\x36\xaf\x6e\x12\x6c\x18\x08\xa7\xd5\x0f\x8c\x46\xef\x9d\xd9\x12\x33\x7e\x0a\x0e\x60\x79\x7c\x42\xf2\xfd\x9c\x17\xc5\x41\x07\xc8\x16\xf7\xeb\x32\xb1\xd1\x0d\xf5\xc9\x20\x84\x94\x36\x5f\x4f\xa8\x26\xad\x7e\x16\x87\xe2\x05\x34\x37\x23\xd4\x34\x29\x21\x84\xda\xe2\xf4\xe4\x45\xbe\x3d\xee\x59\x99\x86\x93\x78\x4c\xd6\x2c\x67\xc6\x32\xf2\xe3\x3e\x60\x25\x6f\x35\x68\x1a\xa3\x82\x73\x0d\xde\x90\x69\xce\xd2\xea\x5b\xfa\xad\x45\x17\x07\x5a\x56\xec\x75\x56\xd0\xda\xa2\x08\x7a\xa5\x2d\xcc\x79\x33\x38\x94\xd5\xcf\xac\x19\x6d\x1a\xc3\x13\x70\x7a\x25\xf2\xfb\xc6\x8c\x90\x3b\x81\xa8\x28\x42\xa6\x69\xcd\xac\x80\xf0\x4e\x71\xa0\x09\x49\xa6\x70\x98\xa1\xed\x53\x03\x99\x66\xa0\x6f\x5c\xac\xcf\x98\x04\xff\xd0\x34\xe5\x79\x1c\x22\x42\x48\x2e\xba\xfa\xe5\xfe\x50\xbf\xbf\xd4\xd5\xb5\x06\xe1\xb2\xcf\x2b\xd5\xf9\x65\x8b\x79\xc5\x1f\x3a\x61\xe8\xdc\x30\x9c\xb3\x6d\xc8\xc7\x7c\xde\x3b\xea\xee\xbc\x6e\xd8\x7e\xd3\xa8\x62\x8e\x4a\x6f\x71\x92\x15\x01\xcd\xbe\x7c\xa0\xd9\xa0\xd1\x03\x80\x42\x48\xf7\x2c\xe3\x67\xea\x54\x87\x68\x07\xb3\x35\x36\xf6\xd5\xc2\xe8\x81\xf8\x88\x1f\xd0\xd9\x39\xc4\xcf\x6b\x20\x48\x70\x44\x96\xeb\x34\xb6\x1e\xf9\xfc\x9f\xf8\x6c\x84\x84\x4a\xdc\xb4\x8e\x6e\xc3\x75\x24\x10\x44\x20\x7b\xee\x45\x3e\x8e\x30\xff\xe1\x53\x3c\x5b\xa1\xa0\x64\xf4\xae\x65\x59\xc5\xae\x78\xe9\x48\xcc\xe5\xef\x96\x50\x5b\x93\xb6\xb8\x2e\xd3\xfd\x87\x26\xd9\x30\x1c\x8b\x4f\x74\x3f\xa4\x8a\xef\x49\x7e\x66\xde\xb1\x11\xa1\xd0\x0f\x8c\xc3\xb3\xe7\xaf\xc7\x7b\xc5\x7a\x94\xc4\x1a\x1f\xaf\xab\xce\xf5\x10\xf7\xa0\xdf\x2d\x97\x47\x7d\x87\x22\x67\x2b\x41\x0a\x53\x84\x70\xd8\xe2\x34\x3f\x6f\x53\x3b\x82\x45\xaf\x03\x77\xb1\x72\x52\x05\xc9\x14\x87\xbc\xbb\xbc\xa9\x51\x57\xf9\x94\x89\xee\xce\x03\x75\x22\x44\x64\x89\xd9\xf9\x22\x50\x8f\xcd\xe7\x3e\x09\xbc\xa8\x1b\x95\xca\x43\x18\xe6\xd0\x53\xb2\xc3\x59\xaf\x54\x03\x11\x66\x9c\x64\x8e\xc9\x92\x1f\x27\xaa\xa9\x2d\x99\x85\xeb\xf8\x36\x59\xc7\xf3\x39\x8a\xc8\x2c\xb0\xa8\x17\xfb\x38\x46\x38\x9a\x11\xb2\x35\x4d\x06\x67\x2f\x7c\xed\xb0\x29\x1b\x53\x2b\xa2\x25\xd9\x0a\x34\xb1\x25\x9e\xdf\x41\x15\x80\x45\x3f\x9e\xf8\x36\x82\xe6\x18\x51\xad\xe1\x10\x61\xb1\x40\xcc\x34\xb7\xa2\x45\x86\xd6\x1d\x4c\xc5\x02\xa6\x7e\xb7\x80\xc2\xf6\x92\x96\xf1\x7c\xbc\xe5\x44\xe2\x31\x8d\x9c\x15\x3e\x94\xc5\xd3\x24\xa0\xf0\x13\x9b\xf7\xf5\x0c\x02\x02\xd3\xe4\x9b\x81\x1f\x77\x01\xa1\x98\x92\x10\xe1\xc1\xf1\x4a\x91\xc4\x19\x57\x11\x91\xb4\x66\x77\x7c\xe2\xe7\x08\x33\x72\x4e\x91\x50\xd9\xb9\x40\xd0\x22\x38\x92\x2c\x89\x35\xae\x00\x71\xec\xc5\x6c\xde\x7b\x42\xf5\x1f\x7e\xc6\xf3\xdf\xf9\x1c\x33\x7e\xce\x3c\x3a\xaf\x68\xcd\xec\xbc\x78\xc4\xd5\xf1\xc0\x39\x3c\xa7\x68\xd1\x14\x7e\x7c\xf3\x7e\x1f\x14\x19\x1c\xd7\x71\xee\x89\x37\x3b\xad\x59\x49\xeb\xa2\xf4\x49\x78\xf6\x89\x8f\x17\xc8\x54\xe3\x73\x41\x9b\x5c\x7d\x0b\xc7\xc5\x95\xe0\x7f\xae\xd4\x4c\x5c\xc1\x8e\xb8\xe2\xfd\xb8\xfa\x81\x25\x5f\x3e\x1d\x24\xae\x17\x07\xa2\x6c\xd8\x00\x6a\xaa\xb6\x8c\x2b\x03\x8d\xf8\xbb\x9d\xd7\x1d\x12\xc6\x3c\x98\x1b\xbe\xe1\x13\xce\x47\x7c\x5d\x3c\x76\x7c\x04\xea\x19\xab\xc7\xfe\x44\x9b\xcd\xa8\x69\x1a\x02\xb4\x0c\x0e\x26\xa6\x49\x7b\x8a\x72\x7c\xde\xf5\x93\x32\x23\x9c\xc6\x98\xf1\xf5\x14\x27\xac\x45\xf9\x51\x64\x50\x3e\x12\x7e\x00\x86\x4d\xb3\x94\xa7\x62\x77\x46\xf6\x80\x11\xbc\x58\x9a\x66\xb0\x58\x09\xc8\x04\x16\xec\x89\x4c\x1c\x84\x8a\x1c\xc4\x5b\x9c\xe2\x1d\xbe\xc3\x19\xde\xe3\x1c\x17\xf8\x80\xef\x71\x89\x2b\x5c\xe3\x23\x31\xaa\xf4\xb7\xdf\x32\x66\xcc\x57\xd7\x9c\x88\xe0\xd3\x88\x1f\x74\xde\xf6\x91\x2c\xf1\x13\x59\xe2\xf7\x64\x4b\x2d\x84\x7f\x13\x3f\x2f\xc5\xcf\xe7\xd3\x6c\x18\x27\x0a\x38\x04\x67\x64\xb6\x44\x78\xd9\xe2\x2f\xc8\xa9\x1d\x73\xb3\xaf\x38\x4e\xf8\x92\xbc\xb2\x0f\xc5\x01\xbf\xe6\xbf\x9c\x29\xfe\x8b\x7a\xf8\x2b\x79\x25\x79\xe7\xaf\xc8\x25\xbc\xb5\xc4\xda\xde\x0e\x6f\xa3\x75\x28\x0e\x0c\xea\x85\x3e\xd0\x11\xb2\x3f\x8a\x26\x58\xac\x5a\xfc\x37\x62\x84\x5b\x16\xde\xb1\xa8\xa9\x58\xc6\xc2\x9a\x45\x0d\xad\xde\xe7\x61\x43\x8f\x75\x11\x17\xe1\xb1\x82\xa7\x43\x46\xdf\x37\x20\x37\x29\xb2\xaa\x89\x58\xcc\xca\x26\x4a\x2b\x1a\x64\x2c\x6a\xb6\x69\x14\xb1\xbc\x49\xab\x3d\x3d\x34\x59\x51\x1c\x9a\xfd\x31\xab\xd3\x43\xc6\x9a\xe2\xc0\xf2\xa6\x64\x34\x2a\xf2\xec\x7d\x23\x05\x15\x51\x53\x85\xc5\x81\x45\x06\xfe\x3b\x31\xbc\xcd\xe6\xe9\xf9\x72\xb3\xa9\x37\x9b\x72\xb3\xc9\x37\x9b\xd8\x37\xf0\xd7\xc4\xb0\x5c\x67\xb3\xd9\x6c\xec\xc6\xdb\x6c\x1e\x17\x7e\xe3\xbd\xdb\x2c\x17\x9b\xcd\x13\x5d\xfa\x68\x6e\xe0\x6f\x88\xb1\xd9\x78\xc6\xfc\xef\x73\xe3\xda\x32\xe6\x5f\xcf\x0d\x64\xb9\x8e\x7c\xf7\xae\xdf\x3d\x6b\x66\xff\xf2\x5d\x82\xe4\x17\xd7\xf9\xc8\xea\x6b\x7c\xc7\x7f\x3f\xf2\xd1\x35\xfa\xa8\xd9\x18\xe3\x84\x8d\xc1\x53\x36\x46\x23\xeb\x45\x8d\xac\x65\xb3\xf1\x0d\xfc\x2d\x31\x9c\xbe\xc1\xcd\xc6\xb2\xac\x7f\xbf\x6a\xd4\x8c\x53\x2c\xe4\x6d\x36\xbe\xdf\x18\xf3\x6f\xe6\x06\xba\x46\x8d\x7d\x8d\x36\x1b\xde\x34\xfe\x8e\x70\x58\x14\xbb\xd9\xfa\xfb\xdc\x98\x1b\xd8\x48\x0c\x84\xbf\xd7\xbf\x1b\xef\xa0\x8f\x73\xa8\xf8\x9d\xac\xd4\x47\xaa\x15\x74\x2d\xc6\x30\x7f\x26\x0b\xff\x63\xa2\xf0\x35\x16\x3f\x06\xc2\x3f\x4c\x25\x5b\xde\x8b\xf9\xbf\x78\x17\xff\x3e\x37\x50\x97\xf5\xcd\x20\x2b\x51\x59\xdf\x6d\x36\xfe\x47\x1b\xc3\xbf\x76\xf5\xd9\x83\xb6\xdf\xea\x25\xbe\x45\xf8\xc7\x71\x63\x5f\xcf\x8d\x67\x06\xc2\x3f\x91\xd3\x57\xaf\x9c\x41\xda\x9f\xe4\xd4\x1b\x08\x7f\xf1\xf5\xcb\x37\x6f\x86\xa9\x9b\x8d\xdd\xa7\xbf\x7d\xf9\x97\x61\xaa\x48\x6a\xbc\x6b\x9f\x27\xbf\x7c\xfb\xf6\x07\x67\xd4\xee\x37\x08\x7f\xff\xe6\xcb\x1f\x5f\x7d\x37\x4e\xf8\x16\xe1\x2f\xfe\xfa\xd5\xd7\xa3\xce\x38\x16\x40\x35\xf0\xe5\x0d\xe7\xbc\x9b\xbc\xde\xf2\xff\x0b\xfe\x82\x16\x56\xb8\x4d\xb3\xa8\x29\xe2\x05\x47\x57\x12\x5c\xe4\xfc\xb0\x07\x96\x37\x45\x14\x35\x96\xe5\xcd\x17\x7e\x83\xac\xcd\x26\xba\x46\x79\xd3\x43\xac\x4c\x90\xef\x9b\x4d\x34\x47\x0d\xea\x26\x13\x40\xc3\x48\x0d\x84\x39\xb7\x3a\x1a\x29\xdf\x09\x7f\x9b\x1b\xe8\x99\xcc\x92\x33\x16\x55\x5f\x14\x79\xcd\x9e\xea\xf1\xd8\x78\x75\x62\x61\x9d\xbe\x57\xec\xbe\x49\xea\x26\x13\x23\xea\x07\x38\x1c\x83\xe5\x3a\x8b\xcd\x26\x42\x2e\x74\x5d\xeb\x98\xe5\x12\xef\xdd\xc2\x6f\x9e\xc9\x2e\xb6\xf8\x67\x72\xc3\x7b\x95\xe6\x87\x63\x2d\x31\x4d\xc3\x3b\x43\x4b\x46\x9b\xe0\x58\xd7\x45\x8e\x9e\xdd\xa4\xf8\x17\x72\xf3\x6e\xbb\x89\xf8\xe3\x3f\xc9\xcd\x3b\xef\xdd\xc9\x9f\x6f\x4e\x9b\xea\x7a\xe3\xe5\xb4\x4e\x1f\xd8\xd5\xe6\xf1\x06\xff\x97\xa8\xed\x4f\x96\xc7\x51\xc3\x1c\x35\xd6\xe6\x71\x8e\x9a\x8d\xad\x3e\xa0\x67\x37\xf8\x19\xb9\xf1\xe6\xff\xf2\x6f\xf0\xaf\x03\xf0\x82\xcd\xe6\x6d\x36\x11\x5d\xc4\xfe\x69\x85\xff\xdc\x42\xc7\xdd\x46\x8c\x0a\x35\x36\x74\x9a\xc3\x29\xa5\x64\x92\xb4\x22\xc6\xf2\xc9\x98\x07\x8b\x3f\x7f\xfa\xe9\xc7\x7f\x56\xb4\x0e\x27\xd3\xa2\xa6\x09\xdd\xc0\x89\x6e\x97\xae\x38\x97\xed\xb8\x2c\xf6\x5f\x6c\x69\xf9\x45\x11\x31\x2b\x9a\x43\x09\xe4\x4c\x26\xbe\x78\xb1\x5a\x36\x9f\x7e\xfa\xfc\xb3\x3f\xe3\xd5\xf2\xf9\xc7\x66\xd4\x7c\xfa\xe7\x8f\x9f\x2f\x51\x8b\x03\x4a\x6e\x2c\x8f\xa3\xbf\xa7\x55\xbc\x79\xfa\x3f\xb1\xdf\xbc\x5b\xb8\x9b\x08\x35\xef\x16\xcf\x24\x62\x94\x29\x8b\xcd\xf1\xf5\xeb\xd7\xaf\xf9\x2c\xdc\x24\x38\xa4\x17\x04\x83\xae\xb1\x59\xf2\xa3\x95\xba\xc6\xe6\x18\xc7\x71\x64\x38\x54\x9c\x2f\xd6\x12\x2f\x56\x68\x6e\x6c\x36\xc6\x9c\xda\xa1\xec\xdd\xcb\xda\x52\x27\xcb\x62\x85\x3a\xb1\xab\xb5\xfa\x33\x9a\x1b\x57\x86\x23\xb2\xb7\x38\xa2\x3a\xa1\xb5\xb7\x80\xdd\x21\x35\xb5\x26\x19\x25\x75\x80\x70\x66\x64\xc9\x8f\xfc\xb8\x28\xf7\x40\x3a\x34\x8d\x91\xd1\x80\x65\x86\x38\xd4\xf1\x29\x4a\x4b\xc7\xe8\x05\xaf\x06\xce\x39\x24\x1b\x19\x4b\x58\x1e\x19\x2d\x5a\xd7\xe5\xfb\xd3\x5f\x24\x45\xf7\x8a\xfc\x55\x90\x70\x0f\x36\xec\x40\x5e\xa2\x42\x78\xf8\xf6\xca\xd3\xdf\x95\x10\xd2\xce\x8b\x88\xbd\x7d\x7f\x60\x6d\x48\xeb\x70\x6b\xc5\x14\x9d\xfe\x42\x4e\x50\xaf\xf3\x4a\xe6\x72\x87\x93\xfa\x5a\x36\x4b\xb1\x6c\x36\x40\xa8\x9d\x64\x84\xa8\xc6\x58\xac\x1f\xb7\x69\xc6\xf8\xe1\x2c\x79\x89\xf9\xdc\x47\xeb\x8e\x8f\x08\x17\xab\xb6\x6d\x3b\x3a\x2b\xa1\x00\x81\x11\x66\xa2\xae\x18\x6f\x25\x11\x53\x70\xe2\x85\xd3\x17\x81\x5d\x3c\xe6\xac\x7c\xd5\x93\x2a\x81\x1b\x74\xe3\x71\x3e\xe3\x94\x75\xc4\x41\xd4\xf3\x3b\x1e\x6b\xa6\x31\xca\x33\xda\x34\xab\x19\x21\x8f\xa6\xf9\x99\xf8\x59\xc1\x6b\x47\x59\xf3\x0a\x66\xcc\x34\x2d\x8b\x57\x3c\x68\xac\x69\x02\xe7\x01\xcd\x08\xc9\x4d\x73\x6f\x05\x08\x83\xa4\x3d\xc7\x07\x04\x97\x18\x2b\x59\xaf\x95\x91\xff\xb2\xd9\x13\x0b\x39\xc1\xce\x49\x93\x98\x64\xde\xca\x87\x3c\x9f\x11\xde\x16\x5c\x79\x58\x3b\x12\xd8\x09\xab\xa5\x64\xfe\xf3\xf7\x5f\x45\x56\x8c\xd0\xa0\x23\x3b\x3b\xe5\x70\x13\x77\x1f\x05\xef\xb1\x43\x38\x12\x2c\x70\x1a\x5b\x15\x48\xed\xaa\x89\xaa\x4c\xb3\xb6\x02\xbc\x43\xa6\xf9\x7b\xf5\xf0\x0e\x65\xde\x73\x5f\xa5\x2b\x18\x8b\xb0\xde\xc5\xea\xf3\xf7\x6f\x69\xf2\x2d\xdd\x83\xf0\x04\x43\x0f\x61\x70\x1f\xfb\xc8\x34\xc3\x61\xce\x2f\x32\x5a\x55\x3c\x2f\x5f\xb3\xe9\x94\xdf\x6d\xad\xcb\xc9\x47\x83\xa3\x36\x8d\xad\xd0\xbe\xaf\xa8\x69\xce\x5e\x7a\x94\xef\x49\xdf\x34\xad\xd9\x7d\xd3\xcc\xee\xed\x9a\x55\xc0\x64\x8b\xb5\x80\x35\xad\x48\x80\x4b\x42\xd7\x6a\xaa\x94\x08\x64\x46\x88\x80\x19\x5e\xf7\x90\xec\x47\x27\xeb\x4e\xac\xcb\xcb\x5a\x5c\x9f\x31\xcb\x48\x23\x03\x21\xf7\x8e\xdc\x75\x12\x81\x80\xe2\x90\x22\x27\xb0\xab\x71\x46\x7c\x47\x8e\x08\x17\x24\xb1\x28\xc2\x5b\x52\x28\x52\x55\x6c\x84\xed\x62\x81\x0a\x6f\xeb\x13\xe3\x4f\xc6\xfc\x8e\x8f\x60\x5e\x51\x8b\x7f\x41\xeb\x92\x14\xf6\xae\x48\x73\xcb\xc0\x06\xc2\x15\x79\xa6\x86\x64\x9a\xf7\xd4\x0a\xb4\x1b\x19\xd4\x34\x01\x9f\x8c\x12\x71\x84\x70\x36\x8b\x95\x0d\xf7\x1d\x6f\xe0\x00\x2a\xca\x97\x59\x66\x95\x30\x7f\x62\xb7\x3f\xa1\x53\x1b\xa7\x39\xcd\xb2\xf7\xa7\x3b\x42\xc8\x91\xaf\x90\xb8\xe3\x19\x8d\xb9\x6d\x5b\x59\x79\x6a\xf5\x12\x9f\xef\xb1\xf1\x6c\xc5\x4f\x64\xd8\xa8\xfd\xee\xe5\xdc\x81\x10\x4c\x73\x6e\xbc\xfb\x1c\x58\x21\xdf\xcf\x1d\x3e\x04\xc8\x0b\xf9\xd0\xd1\x8b\xc8\x0e\x69\xb8\x65\x5f\xc3\x14\x99\x66\xc4\x32\x56\xb3\xab\xc0\xa3\x76\xb5\x4d\xe3\xda\x42\x3e\x0e\x3c\xc8\xeb\x13\xa6\xfa\x12\xf4\x4d\xa6\x54\x47\xb5\xde\xd1\x27\xb3\x25\xa6\x7d\xfa\x8e\xf6\x9c\x5b\x3e\xbe\x09\x8b\x53\x96\x45\x15\xab\x0d\x81\x57\xa5\x14\x6e\x46\xad\x00\xc9\x99\xea\xa4\x2c\xb3\x55\x37\x63\xfa\x3a\xf0\x89\xbb\x70\x4f\x06\xd8\x21\x3f\x66\x99\x86\xde\xee\xe8\x10\x4d\x4a\xf6\xb4\x31\x38\xeb\x1e\x0e\x01\x85\x2d\x16\x28\xb2\x69\x5d\x97\x7f\xa5\x79\x94\x31\x2f\xf4\x98\xef\x13\x6d\xec\xd9\xa0\xb6\xc0\x34\x29\x8e\x38\x8f\xb9\x02\xe9\xac\xc2\x88\xe2\x3d\xd0\xde\xa9\x5d\x15\xc7\x32\x64\x5f\xe5\x11\x7b\x5a\x04\xfa\x1b\x20\xcf\x01\x02\x0a\x91\xe8\x4e\x48\x42\x9b\x1f\x46\x6f\xd2\x20\x4b\xf3\x84\x63\xb5\x50\xe3\xb6\x16\xab\x4e\x44\xe4\xae\x9c\xc5\xaa\xef\xe5\x5e\x5f\xa1\xfe\x0e\xa9\xeb\xf6\x85\x6d\xa8\xf8\x67\x20\xa5\x80\x3d\xe6\x73\x0d\xb7\x79\x84\x50\x6d\x4e\xf3\xff\x51\xfd\x96\xd6\x40\xd3\x18\x82\x44\x83\x37\x74\xa1\xbd\xe2\x52\x7b\x8a\xe1\x97\x87\x3b\x3f\x3c\x86\x80\xa2\xd3\x01\x2b\xb7\x3f\xf9\x03\xfd\x59\x2b\x33\xa8\x40\x2f\x4d\x9d\x60\xfc\x9a\x56\xaf\xb4\x0f\x4d\xa3\x7f\x99\x11\x32\xa3\xa6\xc9\x38\x5c\x4f\x95\xd6\x5a\x1f\x75\x53\x1f\xf7\x41\x1f\x77\xaa\x91\x3a\x1a\xbd\x45\xe6\x01\xd6\x93\x42\x1c\x89\x75\x60\x38\x26\xd4\xf2\x7c\xac\x80\x1c\x07\x08\x27\x24\x1e\x82\x7c\xb2\x58\xa0\xd0\x63\x24\xf6\x12\x9f\xe3\x75\x0e\xf1\x64\x66\x45\xfc\x87\x3f\x23\xd4\xf2\x7f\x5d\x97\xee\x07\x9b\xdf\x34\xa7\x6e\xfa\xe9\xe4\xf1\x65\x9a\xb4\x0d\x49\x42\x6d\x29\xc0\x22\xa7\x16\xc7\xfc\x3d\xad\x7e\xf9\xe6\xeb\x73\xb9\x0a\x08\x72\xe9\x98\x18\xa0\xa8\x93\x98\xc8\x16\x94\x24\x7f\x16\x98\xa6\xf1\xd7\xb7\xdf\x7c\x3d\x3c\x69\x5a\xbc\x87\x46\x59\xad\x2a\x99\x10\xe1\x30\x9c\x10\xea\x9e\x37\xe6\x3c\x74\xf2\x46\x41\x81\x70\x52\x22\xd1\xf6\x75\x32\xee\x8d\x6b\xe5\x24\xc1\x05\xc9\xc7\x09\xf8\x40\x66\xb1\x95\x23\xfc\x20\x6a\xb2\x18\xcf\xc3\x62\x7a\xcc\xea\x9f\x52\xf6\x88\x4c\x93\x6f\x97\xc3\x8c\x10\x4e\x08\x31\x9b\x46\xd1\x97\x0f\x2c\xaf\xbf\x4e\xab\x9a\xe5\xac\x74\xcf\x3f\x59\xc6\x31\xcf\x0a\x1a\x19\x38\xa2\x78\xb6\x42\x0e\xe3\xc8\x8b\x86\x5b\xc8\xc5\x2b\xd4\x5e\x2d\xa3\xc8\xfb\xec\x08\xe1\x10\x30\x1d\x9c\x3c\x15\xd9\x5d\x20\xa4\x43\x45\x0d\x10\x23\x35\xf0\x8c\x8e\x0e\xe9\x2e\xd9\x40\x2d\xaf\x71\x6a\xe1\x2f\xd6\xad\x2b\x3f\xa8\x83\xe2\x8b\x62\x2f\x0e\x0a\x03\x21\xd9\xdc\x39\x21\x64\x5c\x1b\x48\x82\xf1\x79\xab\x1d\xfd\x42\xfe\x29\xce\xf2\xfc\x12\x25\x24\x4a\x72\xc2\xed\x42\x17\x8b\x41\x17\x29\xe2\x04\xdd\x11\xcf\x46\x15\xf2\xba\x9a\x66\xea\xab\x75\x1c\x77\x93\x37\xe6\x5a\x91\x1d\xa7\x59\xcd\x4a\xfb\xab\x57\x53\x70\xdf\x1d\xfa\xbf\x62\xda\x6b\x1e\x4c\x4e\xe1\x39\xc9\xc4\x0f\x88\xb6\xc5\xbc\x89\x3c\x1a\x36\xc0\x0f\x2e\x4e\x90\x4d\x6c\xd9\x31\x51\x6c\x9a\x87\x1e\x9b\x8f\x88\xdc\xbe\x4b\xa1\xeb\x85\xbe\xe3\xf9\x6d\x8b\x9c\xff\xf9\xa0\x44\x73\x17\x11\x4a\x37\x4e\x81\xdb\xcf\xbf\x89\xf1\x77\x7d\xe3\xc4\xf1\x03\xcd\x8e\xec\xff\xef\x19\x11\xe2\xde\xc9\x79\xe1\x7c\x07\xd4\x18\x92\xf8\x42\xff\xf0\xa0\x63\xea\x42\xd2\x8b\xfd\x35\x23\xc1\x04\x08\x51\xa4\xb1\x74\x31\x61\x82\x9b\xfb\xef\x35\x21\x89\x39\x58\x30\x35\x1f\x6f\x5f\xfe\x85\x4c\xef\x5b\x77\x8a\xc1\xff\xbd\xa9\xd2\x8a\x5f\xe4\x62\x1c\xe0\x27\xdc\xe0\x9c\x62\xa6\xea\x8e\x7f\x92\xc9\xc5\x11\xf1\x7c\xcc\xc8\x72\x34\xfb\x83\xca\xe1\x96\xe7\x1a\x24\x10\xe8\xa4\xe8\xa8\x18\xae\xd5\x10\xa7\xca\x42\x0d\x7b\x4b\x8e\x2c\xec\x80\x26\x52\xe4\x6e\xdc\xc1\x0b\xc8\x02\xc7\x33\xa4\xf1\x59\xff\x36\x30\x0d\x8b\x1f\x50\xa7\x58\x74\x81\x0b\xa3\xa8\xc5\x25\x1f\xf8\x3d\xff\x23\x78\xb1\x1e\xb5\x8d\xa7\x10\xee\xda\x47\xd8\xec\x1c\x8d\xe5\x39\x2b\xf9\x51\x49\x8c\x5b\x7a\x95\x46\xe4\x23\x63\x7e\x9c\x1b\x1f\xbd\xb8\xbd\xa1\x2f\x6e\x85\x0c\xad\xff\xbc\xd8\x94\x9b\xcd\x47\x57\xfb\x8a\x66\x59\xf1\x18\xd2\x43\x7d\x2c\x19\xf9\xe8\xa3\x17\xb7\xc5\x01\x68\x02\x25\xde\x87\x6f\x37\xe2\xe3\x8b\xdb\x1b\xf1\xf9\x85\x81\xe9\xf9\x42\x1b\xde\xb0\xba\x77\xe4\xa3\x8f\xfc\x0e\xa9\x9b\xe6\xbd\x58\x19\xc3\xbb\x7e\xf7\xcc\x27\xbd\xa4\xfd\xa3\x66\x63\x6c\x40\x06\x3b\x59\xa9\xea\x49\x5f\x55\xd3\xa8\xaa\x7a\x99\xbe\xeb\xc0\xde\x68\x84\x20\xf3\x52\x5d\x69\xf4\x2f\x22\xc6\x3f\x55\xdb\xbf\xc8\x85\x72\x8e\xbc\xf4\x98\x28\xd3\x27\x4d\x96\xa4\x7f\x82\xe6\xe6\xd7\x13\x45\xed\x3f\xd9\x73\x6f\xfe\x2f\x1f\x8e\xd9\xd1\xf2\xd2\xd1\x7a\x6e\x4b\x16\x93\x8f\x3e\xba\xea\x88\xca\x8f\xd4\xd3\x70\x81\x27\xd3\xc5\xea\xdd\x68\xcb\xb7\xbe\xc0\xc9\x09\x22\x1e\xad\xc7\xec\x38\x07\x79\x03\x1b\xe2\xe6\x06\x86\xaa\x43\x5f\x80\x46\xd9\x73\x4e\x3c\x60\xe3\xd5\xa5\x65\xe0\xe9\x24\x9a\x82\x0d\x28\x29\x64\xcc\xdd\xa5\x8c\x81\xf0\xf3\x19\x67\xc5\x26\x16\x86\xe5\x30\xc8\x89\x9a\xba\x24\x6c\x38\x6a\x2e\x0c\x84\xcf\xf6\x4d\x37\x63\xb3\xe5\xe5\x66\xfa\x0a\xfe\x68\x3b\x53\xd5\x5c\x63\xe7\xc9\x40\x58\x95\xc4\xf6\xb5\xc3\xd7\x1e\x71\x04\xb0\xe7\x7c\x32\xab\x54\x7e\x85\x0c\x2a\x52\xa8\xa4\xa6\x29\xec\x47\x16\xdc\xa5\xf5\x37\xc3\xbc\x3c\x61\x5f\xfc\x36\xf1\xb5\x98\xca\x59\x8d\x3e\x72\xec\x32\x82\xbe\x90\xcf\x4a\x58\xe4\x39\x6c\x3c\xc8\x4f\x2a\x79\xcd\x8d\xe1\x16\xa7\x7f\xf3\xaa\x19\xdf\xe7\x30\xb2\x52\x8e\x6c\x46\x0c\xfc\x2d\x87\xea\x7b\x72\xdf\x4d\x98\x26\x55\xbf\x97\xe2\x99\x86\x13\x84\x25\x29\xa7\xf2\x94\x7a\x9e\x40\xcd\x47\x61\x87\xc5\x9e\x73\x73\x8a\xa0\xff\xbe\xa8\x52\xde\x6d\x84\x6b\x12\x34\x8d\x96\x2d\xaf\x69\x9a\x57\xc8\x9d\x92\xac\x7e\x36\x60\xed\x5d\x3a\x26\xec\x1d\x8a\x23\x21\x24\xed\x39\xc7\xb5\x76\x3f\x1b\x35\xcd\xcc\x9a\x45\x42\x02\x1a\x75\x15\xf1\xaf\x61\xd7\xb4\xdb\x3f\x5a\x11\x72\xe8\xa5\xae\x9b\xe6\xea\xcf\xe6\xc5\x54\xd0\xbe\x1b\x1f\x9d\x69\x6c\x05\x52\xa0\x10\x90\x81\x40\x8b\xa7\x68\x04\xc2\x6c\xb9\xee\x04\x2f\xf8\x73\x12\xb8\x67\xf5\x50\xfd\xae\x37\xe3\xbb\x60\xb9\x16\xd7\x16\xb3\x8b\x7d\x5a\xcc\x82\x4b\x49\xdd\xa9\xeb\x46\x8e\x15\x91\x29\x66\x8f\x10\x62\x9d\x0b\x84\x91\x7b\x79\x0a\x02\xe4\xac\xf0\xca\xe4\xb3\x2e\xf4\x3c\x5f\x31\xce\x02\xb1\x48\xe8\x96\x4d\x17\x82\x86\x22\x97\x8f\x2f\x6f\x9a\x51\x3f\x08\x21\x0f\xa6\x59\x5b\x0f\x98\x22\x77\xb1\x72\x02\x91\x2b\xb8\x94\x2b\x40\xee\xca\xb9\x73\xbf\xb2\xee\x30\x45\x0b\xfe\x13\x20\x67\xe9\x7c\x62\x46\xbc\xf4\x6a\x6a\x81\x2e\x4d\x6c\xd8\xe9\x09\xf5\xcb\x06\xc4\x8f\xf6\x9a\x10\x8f\xfa\x78\x4b\xbc\xc0\x17\x62\xf4\xa6\x99\x75\x32\x67\x18\x51\xd7\x69\x77\xe5\x30\xfe\x12\x4f\x75\x90\x17\x66\xba\xbc\x5a\xca\xba\xd6\x21\xa1\xeb\x5e\x20\xa5\xc1\x4f\x62\x1f\x73\x21\x32\x0c\x79\xae\x60\x3a\xd7\x56\xcf\x25\x85\x0e\x5e\xe4\x13\x42\xb6\x5e\xe4\xa3\x68\x3e\xef\xe1\x20\xa3\x90\x86\x21\xc5\x91\xd9\x1e\x78\x97\xb7\xea\x79\xe5\x2c\x5b\x9c\x23\x27\x6f\x71\x42\x15\xbe\x9b\xbe\x8b\x82\x9b\x8d\xfc\x98\x65\xe2\x4f\x80\xf4\x22\x1d\xf6\x3c\x5b\x8c\x29\x38\x54\xf7\x0f\x14\xee\x1f\x3a\x5e\xe6\x0d\x36\xc8\x47\xcf\x56\x9c\x74\xc1\x67\x78\xd9\x34\x0f\x20\x33\x0f\x3a\x99\x79\xd9\x34\xb3\x52\x60\x9d\x40\x28\x45\x6a\x52\xf4\x00\x21\x90\x2c\x8b\x0d\xd5\x21\xcd\x00\x28\xda\xa8\x69\x26\x10\x2d\x07\x55\x85\x8d\xe4\x9d\x4a\xff\xa1\xc3\x34\x9d\x6c\x51\x0a\x58\x19\x3a\xb5\xfd\x0c\x05\x38\x17\xd3\xe3\x51\x5f\x9d\x58\x2f\x96\x30\x53\x0a\x23\x4d\xce\xee\xef\xcc\x92\x32\x3f\x48\x28\x48\x19\x46\x55\x7c\xb8\x30\x80\x3e\x23\x03\x49\xec\x48\x51\xc8\xc7\x31\x61\xa6\xf9\x85\x98\x25\x3d\x27\x1e\xe5\x44\x2e\x83\xfb\xad\xd9\x41\xf1\x16\x0a\xdc\x3a\x6d\xe2\xd8\x8d\x1d\x5d\x18\xd2\x34\xb3\x83\x3b\xe2\xad\x03\xe4\x58\x31\x99\x60\x3a\x61\x21\x63\xbb\x3a\xb0\x30\x8d\x53\x16\xb9\xb1\xe0\xbc\x1c\x90\x43\xf3\xf1\xb3\x2a\xa4\x07\x46\xce\xf9\xf7\x91\xc2\xa3\xb8\xde\x10\x45\xca\x72\x00\x99\xe7\xea\xc7\xc6\x9b\xf7\x79\x4d\x9f\xae\x20\x27\xbe\x3a\xe6\x25\x0b\x8b\x24\x4f\x7f\x63\xd1\x15\x7b\x3a\x94\xac\xaa\xd2\x22\x77\xae\x8c\xb9\xac\xf2\x98\xa7\xf7\x47\xf6\xa6\x28\xa7\xe4\x5f\x1a\x63\x05\x78\x20\x23\xb3\xd0\x8e\x58\xcd\xc2\xfa\xd5\xf1\x90\xa5\x21\xad\x59\x85\xef\x88\x44\xa9\x6f\x6a\x4e\xba\x80\x54\x5b\x5c\xec\x72\x1a\x86\x27\x58\x9f\x23\x9c\x29\xb6\x2b\x20\xd4\x8b\x39\xdb\x05\x87\x8c\x17\xfb\x20\xf4\x92\x3c\x57\x8c\x90\x26\x74\xa7\x52\x07\x1f\xe4\x8e\x78\x85\x14\x7c\xde\x81\x34\x1f\xd3\x16\x33\x92\xc0\xe4\xbf\x65\x4f\x53\x03\x08\x89\x61\x00\xae\x8c\xb5\xb3\xba\x67\xc7\x39\xe3\x17\x37\xcd\x67\xe2\x67\x05\xaf\x82\x59\x3b\xd3\x08\x05\x03\x1d\xd0\x67\xc8\xeb\x0e\x8b\xea\x1f\x41\x9b\x98\x12\x6a\x83\xee\x02\xd0\x86\x6b\xba\xe6\x1f\x74\x59\x7d\x38\x07\x6d\xe7\xee\xc2\xf0\x63\xd1\xf4\x27\x3a\x82\x15\x3d\xfd\x89\x43\x8b\xc8\xd7\xcf\x1b\x30\xf9\x50\x47\xd0\x4b\x34\x5a\x1c\x09\x51\xa6\xc0\x2f\x15\x39\x69\x17\x39\xce\xa7\x4b\x2c\x28\xf4\xef\x2b\x76\x8c\x0a\x27\xa5\x18\x10\x92\xf3\x13\xee\x77\x87\x73\x6a\x31\x67\x6b\xf9\x6f\xc9\x32\xd0\x7b\x70\x4e\xc6\x0b\xc3\x39\xbf\x07\x17\x46\x21\xb3\x65\x8b\x8d\xab\x89\xf4\x16\x1b\xf3\xee\x73\xc9\x1e\xd2\xe2\x58\xc9\xd1\x0f\xca\xfe\xeb\x52\xa6\xb6\xc5\x87\x92\xbd\x06\xa1\x91\x73\x02\xa5\x99\x29\x19\x97\xb7\xf2\x09\xff\x33\x14\x20\x61\xea\x7d\xec\x13\x8b\xff\x6d\x1a\xea\x7d\x02\x7f\x3f\xf5\x9b\x46\xdf\x51\x22\x27\xe7\xd5\x00\x02\x9f\x73\x08\x84\x72\x06\xdf\x17\xde\xc7\x3e\x5c\x88\xe1\x5e\x3f\xe1\x13\xd4\x4a\x6d\x9c\x0f\xf6\x64\x80\x60\xb0\x91\xd7\x5b\xd1\xc0\xca\xef\x6a\xfa\x18\xb9\xb2\x73\x6a\x3b\x5b\xd4\x5b\xfa\xbc\xdf\x9f\xf8\x64\x6e\xf1\x1f\x97\xf7\x98\x3f\xfe\xd9\x6f\x9a\x15\x72\x9e\x5f\x5b\x06\x7b\x60\xb9\xa8\xec\x63\x50\x1f\x8f\x22\xf5\x86\x78\xd9\x4f\x45\xd9\xff\xe3\xcf\xa9\xf7\x9f\x67\x19\x1c\xfe\x63\x9a\xe3\x16\x5b\xa5\x7a\x34\xb5\x6f\x66\xbc\x79\xd3\xe4\xb3\xa3\x00\xed\x27\x1b\xe6\x40\xde\x84\xf2\x3a\x5c\xbe\x0d\x1d\x18\x90\xcb\x73\x92\xe1\x8c\x3b\xa1\x69\xbe\x15\xd9\x43\x7e\xac\x05\x24\xb1\x42\x3c\x5b\x22\xf1\xd2\x59\xdf\x59\x06\x32\xba\xeb\x88\x45\x80\x16\xea\x19\xc1\xc2\x2c\x79\xbd\xcb\x7e\x0e\x03\x3e\xe2\xe7\xbe\xb2\xed\x83\x2f\xfa\x6a\x7d\x8c\x50\xcb\xc1\x59\x00\xd0\xdb\x97\x7f\x99\x30\x86\x18\xc9\x1d\xa7\x2f\xbc\x84\xb8\xc8\x3d\x53\xe4\x9d\x0d\xe4\x50\x9a\xd8\x55\x5d\x2e\x70\x14\x38\x7d\xd7\x25\x85\x8e\x42\x93\xec\xbc\x5b\xef\xe5\x4d\x7a\x67\x56\xd6\x34\x56\x30\x50\x26\xb2\xde\x75\xda\x70\x74\x6e\x08\x0d\xa2\xe6\x19\x32\xf8\x9c\xbe\xb7\x28\x9e\xe8\x57\x20\x96\x60\x02\xa7\x85\xbd\xc0\x49\x7b\x69\x9a\xdf\x17\xb6\x8e\x05\xad\x52\xe4\x6f\x20\xd8\x69\x2d\x6a\xf1\x68\xe3\x0e\xf4\xe4\xbb\xcf\xea\x4e\x8a\x48\x7a\xc0\x8a\x34\x9b\x3a\xa1\x4d\xcf\x5c\xce\x0b\xf2\x79\x73\x66\x7c\x3a\xd8\x9c\xe3\x74\x43\x7c\x72\x39\x65\x1a\x3a\x2a\x87\xcb\x66\xf0\xfa\x4e\xbe\x86\xa6\xb9\x24\x84\xb0\x0e\xd0\x42\xe4\x18\xd7\x7d\xa2\x9e\xf0\x62\xb1\x72\x8c\x67\x7a\x9a\x80\xa7\x1e\x18\x45\x53\xff\x92\x59\x2c\x8e\x2c\x58\x07\x46\xdf\x71\x6c\x08\xaa\x49\x68\x5c\x69\x23\x4a\xc0\x31\x07\x77\x9b\xac\x03\x55\x55\xf7\x7c\x05\xb5\xcf\x8d\x85\x01\xc0\x3b\x46\x36\xca\xba\x4c\xaa\xe2\x10\xc0\x2d\x40\xd6\xf5\x40\x8f\x13\x62\x64\xb4\xaa\xf5\xef\x8b\x4f\x10\xde\x12\x43\xea\x03\x42\x37\xd4\xec\xf2\xc3\x2e\x92\xf3\xe3\x9e\x43\xcd\x6c\xa6\x33\x17\x1a\xbc\xf3\x9e\xa4\xa2\x1f\x03\x9d\x66\x12\xcf\x08\x49\x5c\x43\x3b\xed\x8c\x89\x13\xe0\x7e\xc8\xa5\x94\x64\xcb\x19\xb0\xe9\xcd\x82\x2b\x32\x4b\x4d\x73\xb6\xc5\x35\x99\xad\xf8\xb1\x7d\x0f\xa7\x73\xac\x48\x89\x03\x3a\xed\x3b\xfe\x62\x4f\xf6\xde\x01\x44\xe0\x5b\x77\x7f\x79\xfb\x95\x0e\x1f\xf9\x7e\x4c\x06\xcf\x56\xeb\x82\x1c\x88\x51\xe4\x19\xa8\x80\x53\xd3\x9c\x15\xa6\x39\x18\x4e\xdb\x6d\xff\x34\xb6\x0a\xe2\x25\xee\xbd\x76\xda\x3b\xf7\x36\x9f\x7e\x78\xf6\x71\x62\x9a\x15\xef\xdd\x3d\xce\xc8\xde\x3b\xfa\x4d\x63\xf1\x1f\xb0\xc7\xbb\x23\x99\xb7\x97\x94\xd7\x57\xaf\x78\xd2\xe0\x1d\xf2\xec\xc8\x9d\x47\x7d\x50\x9d\xca\xc9\x8e\xe3\x40\xd0\x67\xda\x79\x2b\x1f\xd7\x9c\x22\xde\x79\xcf\x7d\xbc\xe7\x4f\xf7\x9a\x56\x99\x97\xfb\xdd\x74\xcc\xe7\x9c\x70\x36\x4d\x3e\x2d\x4d\x63\xd5\x24\x27\x4b\xd4\x34\x85\x7d\x28\x0e\x16\x28\x43\x0d\x67\xc2\x34\xe7\xf3\xda\x34\xf7\xc0\x74\x9e\x78\xf3\xc4\x7b\xc4\x39\xae\xfd\xb5\x30\xf4\x19\xa8\x39\xed\x49\xf0\x7f\x67\x68\x08\xd7\xc2\x56\xe8\x8f\x8f\xe3\xdf\x5c\x71\x39\x50\x18\xc6\x7f\x6f\x08\x6a\x72\x6a\x1f\x61\x31\x5f\x43\xcb\xa6\x7a\x41\x18\x0c\x23\x6a\x9a\xfa\x3f\x22\x42\xc8\xd2\x34\xeb\x9b\xe8\x05\x59\xb6\xed\xc4\xb9\xdb\xdf\x65\x00\x25\x0c\x94\x5a\x05\x93\x14\xd9\x15\xab\x05\x31\x54\x79\x74\xc4\xed\x68\x54\x84\x71\xcc\xe5\x05\x3a\x8b\xae\x44\x05\x82\xca\xef\x2c\x77\xbc\xa3\xef\x02\xc3\xc2\x14\x3b\xb7\x72\xad\x90\x78\x14\x53\x6c\x18\x38\xf0\xb1\xde\xd6\xc8\x5a\xc0\xa2\x63\xf6\x49\x57\x2e\xa0\xbd\x0d\x50\x4c\x80\xaf\xba\xa0\x52\x10\x91\xaf\xf8\x19\xe5\x25\x40\xf1\x44\x3e\x99\x59\x21\xff\x81\x2f\x2d\x9a\x3a\x55\x79\x75\x4b\x1c\xf2\x54\xc6\x49\x43\x31\x37\xce\x29\x2f\x6a\x27\x1d\xca\x1c\xc5\x19\xea\xf9\x58\x7a\x08\xd8\x9e\x2b\x4a\xf5\x57\x3a\x7c\x3a\x86\x63\xe0\x98\xad\x53\x76\x4c\x48\xa4\xa4\x04\x0c\x7b\x3e\x47\xa3\xf4\x5c\x7d\xcc\x8a\x49\xe2\x6d\x7d\x41\xa7\x6c\xf9\x70\x02\xfe\x13\xa3\xe1\x60\x30\xc3\x71\x7f\x1c\x03\x41\x83\x23\xce\x62\xf3\xea\xc1\xa2\x09\x3e\xc2\xeb\x2c\x14\x70\xdd\xb6\x08\x6f\x69\x35\x1e\xe3\x45\x6d\x17\xa9\xb0\xa9\xf1\xea\x2d\xc2\x8a\x55\xbf\x50\x0b\x1d\xd3\x41\xf8\xbc\x5e\x2b\xd0\xb9\x1c\x50\x67\xc9\x73\x56\x72\x86\xab\x69\x80\xcf\xed\xce\x3b\xca\xcf\x3b\xde\x6c\x46\xf3\xe4\x42\x93\x3f\x4a\xf2\x11\xe8\x84\x4b\xf0\x0b\xe5\x01\x7a\xf1\x59\x17\x47\x47\xc4\x99\x9a\xd1\x3a\x2a\xae\xe0\x1a\xf4\xe0\x06\x36\x54\x34\xd6\x20\x7c\xda\x67\x0e\x4f\xe0\xed\x8f\xd3\xc4\xf7\xce\x6e\x85\x84\xa3\xe6\x42\xa1\xd3\xb3\x84\x1b\xc3\x6e\xdc\x70\x6e\x4b\xb0\x18\x4b\x53\xc7\x4a\x5f\xa8\x97\xa6\xb6\x08\xd7\xb4\x1c\x38\x32\xd0\x15\x77\x8b\x90\x0a\xd9\x6e\xff\xcc\x77\xe5\x76\x70\x95\x2d\xce\x79\x20\x1f\x02\x3b\x8d\x5a\x5c\x16\xc5\xa4\x63\x04\x4a\x08\x29\x5a\x0c\x06\x36\x97\xd2\x73\x9b\x86\x9c\xf5\x93\x22\x6c\xd3\xb4\x66\xd0\xe4\x6b\xb0\xca\x69\xfa\x67\x8b\x93\x9b\xb3\x19\xc7\x0a\x20\xb3\xa6\xf6\xb6\x64\x71\xd3\xfc\x8b\xda\x35\x0d\x40\x7f\x0d\xec\xf2\xe1\x2a\xc3\x29\xa8\x35\x5b\x21\xac\xae\x36\xe0\x7d\x89\xb0\xbc\xf6\x9a\xa4\xce\xff\xa0\x26\x5a\xc0\x7b\x41\x6d\x65\x50\xd4\x18\xe2\x9e\x4a\x4b\x52\x57\x7f\x2d\x56\x4f\xd3\xa4\xbb\xae\x1f\xa6\xbf\x75\x15\xc0\xa0\x70\x5f\x21\xa8\x90\xb7\x98\xed\x0f\xf5\xfb\x41\x95\x7f\x48\x0e\x90\xc6\x56\x2f\x90\xb8\xfd\xf3\x94\xfd\xb1\xe8\xc3\x44\x6f\x67\xdd\x09\x61\x43\xeb\x70\x15\xbc\x65\x34\x62\xe5\xd4\xd8\x7e\x91\x3b\xae\x9b\x53\xd4\x62\x98\xc0\xa9\xcc\x3f\x4f\x64\x16\x9a\x78\xff\xc3\x65\xd2\xf4\xf9\x14\xd0\x68\x9f\x82\x16\x83\xa1\xc8\xb9\x8d\xf6\xb8\xaa\x4b\x6d\x9a\xa6\xc1\x6b\xe8\xeb\x37\x4d\x4b\x30\x10\x56\x40\xc6\xbc\x0a\x10\xc3\x88\xf3\x2a\xaa\xcc\x58\x3a\xa8\x7c\x5f\x1c\x34\x24\xa6\x26\xc9\x5b\xfa\x80\xe3\x46\xc9\x9a\x10\xd4\x0b\x16\x2b\x9e\x87\xdd\x8f\x73\xf4\x4c\x90\x17\xde\x2e\xdd\x70\x1e\x38\x21\xe4\x7c\x60\xf9\x79\x6d\x9a\xa5\xdd\x3a\xbc\x0d\xd6\xe1\x9c\x3c\x47\x74\xac\x9d\x40\x5b\x84\x8b\x28\xfa\x50\xf1\xd5\xef\x14\xcf\xce\x86\x32\xb0\x1f\x26\x5d\x5f\xd7\x8b\x05\x27\x62\xd6\xaa\x9a\x68\x50\x4d\xf2\x87\xab\x99\xcf\xa3\xdb\x60\xba\x16\xd0\xc9\x51\x00\x9e\xd7\x5b\xa2\x81\xfb\x7d\x67\xb3\x7f\x2a\x69\x94\x16\xce\x6c\x29\xd0\x48\x50\x3c\xf1\xe7\x38\xcd\x18\xff\x3d\xd0\xaa\x7a\x2c\xca\x88\x3f\xa7\x7b\x9a\xf0\x8f\x2d\xea\x29\xab\xc0\x27\x7b\x6a\x05\xa8\xaf\xae\x3a\x06\xfb\xb4\xe6\xf9\x4b\x56\xb1\xfa\x3c\x7f\x2e\xf2\x2b\x85\xc7\x92\x5a\xe8\xd4\x96\x54\x73\x6d\xa3\x34\x9d\xaa\xbe\xc7\x03\x92\x0a\xf8\xf8\x92\xe2\x84\x73\xbb\x75\x71\xc7\xf2\xf4\x37\x46\x26\x89\x40\xdd\x6c\x94\xfc\xa6\x84\x02\x69\x6c\xdd\x75\x7a\x21\xee\xd2\xb9\xeb\xe4\xac\xeb\x2d\xa1\x38\xe5\x54\xcf\x8e\x37\xae\xc4\x67\x8a\x52\x41\xa7\xd0\x34\x67\x16\x23\xff\x10\xb6\x10\x5b\x70\xb7\xc0\xb7\xc8\x96\x6c\x65\x25\xcc\x5b\xfa\x8a\xd3\x6d\x9a\x2d\xc2\xa9\x94\xc8\x12\xcf\x47\xfc\xe0\x9b\xad\xb0\xc5\xc8\x0f\x5d\x0d\x60\x21\xcd\x94\x72\x38\x8e\x45\xf6\x93\x90\x72\x87\xc2\x7d\x02\x54\xaa\x91\x60\x57\xa0\xa8\xd0\x37\xda\xf1\xd6\x62\x25\x92\xab\x34\xbf\x52\xd3\x88\x78\x87\x7f\xf2\x12\x5f\xeb\xf3\xce\x4b\x7c\x31\x12\xfe\x64\x31\xe9\x36\xe2\x77\x7a\x91\x60\x79\x05\xe3\xb0\x4b\xad\xa7\xb1\x35\x0b\xa5\x3f\x83\x6e\x86\xb7\x32\xdd\xd9\xba\xbd\xec\x0c\x39\xbf\x59\x14\xa7\xa8\x9b\x7b\xcd\xe9\x53\x45\xd5\x01\x20\x10\xe4\x12\x0f\x2c\x70\x0c\x63\x1d\xdc\x86\xeb\x60\x3e\x47\xd1\x1c\x8c\xcb\xc5\x9d\x40\xaf\x66\xd4\xd5\x54\xd3\xa1\xfd\x57\x60\x47\x69\x89\x19\xa7\x23\xd8\x53\xcd\xa9\xec\xa6\x89\x70\x42\x42\xd3\xd4\x85\xaf\x84\x90\x18\x6f\xc9\x53\x7f\x79\x16\x88\x73\xc8\x1d\xf0\xef\xac\x97\xc5\x07\x5e\xe4\x2b\x56\x30\xd0\x6e\xa1\x93\x4e\x1a\x2d\x4b\xf4\x64\xcb\x87\x64\x01\x9c\x29\xda\x02\xa4\xa6\xe7\x6d\x4c\x34\x62\x9a\x54\xd6\xd2\xdd\x36\x0f\x65\xde\x97\xfb\x07\xf7\x11\x81\x60\xde\x02\x9d\x79\x0b\x46\xcc\x5b\x30\x62\xde\x98\x69\x32\xf2\x01\xab\x13\xd1\x68\xd3\x04\x6b\x65\x8e\x63\x71\x96\x35\xe6\x64\xfe\x90\x5d\x25\x84\x6c\xd5\x3c\xed\xbd\xe7\x3e\xe1\x4c\x39\x6c\x53\x2f\xf6\xc9\x1e\xc3\xb7\xf3\x01\xf6\x04\x60\xb7\xde\xc7\x81\xfe\x74\xcf\xa0\x0d\xa6\xba\x93\x96\xd1\x73\xfb\x04\x70\xdc\xe6\x31\x5f\x66\x9c\x20\x28\x1c\xca\x0f\xae\xae\xc5\x07\x7a\x8e\x9f\x97\x00\x61\x9d\xef\x09\x06\xbe\x27\x04\x5f\xe1\x45\x3e\x0e\xb5\x3b\x87\xde\x1e\x9f\xea\xe2\x29\x55\x17\x67\xa0\x3c\x1f\x6f\xc9\x12\xa7\xfd\x16\xd8\x11\xe1\xb9\x21\xe8\xdc\x0f\x59\x31\xa1\x92\x81\xe2\x28\x2a\xb4\x62\xa8\xa7\x69\xac\x44\x5d\x08\xe1\x1d\x28\x51\xf0\x97\x2d\xd2\xfd\xfa\x74\x5d\x78\xd2\xba\xa0\x31\x5a\x91\x69\xce\x38\x9b\x67\x9a\x56\x44\x9e\xa8\x15\x21\x58\xfb\x19\x13\xdf\x18\xff\xc6\xf3\xa3\x81\xa2\xbc\xc4\xbc\x23\xa8\xf6\x71\xce\xff\x14\x24\x51\x63\x39\x90\xb8\x69\x1e\xa8\x15\x34\x8d\x71\x6d\xe0\x6d\xaf\x0a\xe2\x6d\x7d\x67\x0b\x3c\xe3\x3d\x99\xd1\xa6\x99\xc5\xa6\x19\xb8\x07\xe7\x91\x5a\x07\xbc\xc7\x14\xaa\xc7\x25\x09\x5d\xd6\x34\x56\xec\x52\xa7\x68\x9a\x08\xb9\x9e\xef\x24\xce\x3d\x58\x7a\x98\x66\x68\xdd\xe3\x52\xe4\x8c\xd0\x69\x47\x1e\xa9\x55\xe2\x1c\xe1\xc8\xda\x61\x3e\xb1\x3c\xe1\x8e\xec\x86\x80\x70\xc7\x59\xd2\x8c\xec\xbc\x3b\x98\xd1\xd2\xcb\xbd\x3b\x9f\x73\xa5\xf7\xf2\x29\x43\xa8\xed\x6e\xbf\x38\xdd\x2e\x1e\x78\x03\x9e\x8f\xef\x3a\x35\x9a\x61\x7d\xa5\xa8\x6f\x27\x16\xe1\xde\xbb\xe3\x15\xad\x19\xd0\x57\x42\x07\x71\x87\x53\xd4\xfe\x4e\x71\x6b\x47\x98\xfb\x95\x15\xe3\x0c\x39\x7b\xfe\xe9\xc5\x62\x65\x9a\x56\xec\xed\x78\x0f\x13\xfe\xc3\xbb\x27\xb6\x7f\x09\x03\x26\x84\x24\x6e\xa9\x2e\x01\x0b\xac\xea\x47\x4e\x89\x30\x73\x65\x0f\x12\x5c\xe2\x14\x39\xca\xe6\x2a\xc1\xe5\xc0\x34\xe1\xfd\x10\x29\x63\x38\x5e\x7b\x98\x4c\x48\x64\xab\x2b\x2f\x0f\xee\x19\xf8\x99\xc1\x41\x37\x69\x1a\x2d\x89\x9f\xc0\x38\x25\x89\xbb\x72\x96\xf8\xee\x92\x85\xa9\xa0\x65\xb7\x98\xf3\x37\xd9\x85\x4c\x5f\x59\x01\x16\xac\xb2\xcc\xb8\x27\x9e\x2e\x4a\xe9\xf7\xf9\x2c\xe1\xb0\xdb\x34\xe1\x8c\x90\x1d\xdf\x14\x56\x40\x42\xd4\x43\xda\x9d\xcc\xee\x64\xf2\xa1\xf7\x47\x27\x84\x09\xac\xf5\xd7\xe9\x6d\xbc\x4e\x85\x5f\x86\x70\x38\xd6\x54\x8e\x15\xed\x89\x57\x53\xeb\x48\xad\x3d\xc2\x21\xf2\x3b\xbc\x17\x76\x34\x8d\x96\x5b\x4e\xb3\xb8\x81\xe5\x5f\xe5\xe1\x8a\x70\xe8\x1d\x7d\x31\xd3\x8c\xcc\xe7\xe9\x9a\xdd\xc6\x6b\x26\x5a\x1e\xb4\xcb\x54\xbb\x03\x99\xd9\x13\xb5\xd2\x17\x2b\xd3\x14\xdd\x80\x47\x7e\x9e\x76\x12\xee\x74\xb1\x42\xca\x61\x8a\x3c\xdf\x8d\x2b\x71\xc9\x95\x2e\x9e\x8b\x2a\x5d\xe3\xda\x70\x0c\xa3\xd5\xfc\x78\x29\x0b\xb9\x10\xa7\xb7\xcc\x34\xdf\xf7\x55\xa6\x98\x71\x8c\x70\x1b\x8b\xaf\x9d\xd0\xbc\xfb\x0a\xc7\x39\x6a\xf7\x8a\x62\x56\x94\x01\xf4\xb0\x07\xb0\xdf\x86\xc6\x5f\x9d\x00\x46\x73\xe4\xf3\x62\x89\x63\x32\x46\x31\xf8\x4e\x94\xc9\x70\x81\xef\x71\x49\x96\xb8\x22\xc6\xd2\xc0\x35\x89\x4d\xd3\xf3\xf1\x91\xef\xac\x07\xb2\xc3\x4f\x1c\xd5\x80\x5e\xb2\x52\xcd\xb6\x38\xca\xb9\x43\xf8\x3d\x79\x9c\x13\xc1\xe6\x3c\xb8\x2b\x67\xe0\xca\xac\x69\xec\x15\xfe\x8d\x3c\x75\xbe\x77\x8a\xd2\xba\x13\x5e\xe5\x84\xa6\x52\xd2\x34\x77\x68\x5d\xcd\x08\xf9\xcd\x34\xa5\x13\xb8\x8c\x3c\x79\x95\x8f\xd6\xd5\x7c\x2e\x50\x83\x69\x66\xe8\x54\x90\x25\x4e\x9a\x26\x3b\x53\x6d\xca\x9b\xc6\xda\x5b\x19\x27\xaa\x66\x07\x25\x01\xb9\x27\xd4\x2b\xa4\x36\xfa\xbd\x95\xf1\x92\x39\xde\x22\x74\x92\x14\x65\x86\xa4\x3c\x99\xf7\xe6\x91\xbc\x47\x6d\x68\x9a\x96\x95\x91\xd9\x3d\x6f\xcd\x34\xcb\xc5\x02\xc7\xa6\x59\xab\xec\x80\xb3\xca\x39\xa9\x70\x68\x9a\xbc\xbf\x25\x74\xa9\x6b\x2e\x10\xcd\xdd\x5b\x35\x3e\xf2\xa9\xd5\x14\xee\xcb\x17\x4b\x29\x47\xae\x16\x0b\x54\x7b\x95\xdf\x34\x47\xf8\x6b\xf1\x1f\xf2\xa5\xd0\x14\x49\x11\x5a\x1f\x39\xca\x39\xa2\x56\xe1\x91\x14\x1f\x11\xbe\x33\x4d\x8e\xbe\x8f\xdd\x3a\x9a\x66\xd9\x79\x6b\xe2\x20\x3a\x50\xa1\xb0\xd2\x5e\x45\x41\x8c\x0d\xef\xc8\x03\xc2\x75\xdb\x9b\x46\xf0\xb3\x06\x39\xb1\xca\xb7\x25\x89\x50\x5a\x4b\xb3\x69\x5e\x40\xea\x60\x80\xff\xa6\x97\x1a\x27\x30\x8b\xd1\x49\x5c\x0f\x26\x60\x01\xdc\x43\x9e\xd2\xb7\x5a\x2c\x50\x4c\xde\x53\x2b\xf0\x42\x1f\xe1\xd8\x3b\xfa\x6e\xa7\x65\xe1\x30\xf5\xb4\x8e\xc9\x4b\x8b\xe2\xdf\xf8\x59\xc8\x4f\xc8\xb8\x53\x24\x20\x54\x53\x7b\x4f\x7b\x15\x03\x72\x49\x66\xda\x79\xb9\x21\x53\x2e\xd0\x4c\x93\xe2\x9c\xcc\x98\x69\x26\x16\x25\xfb\xae\x19\x7e\x0a\xc1\xa1\x47\x42\xb8\x13\x58\x81\x20\x4a\x22\x7a\xbe\x86\x29\xc9\x41\x3a\xaa\xdd\x01\x73\xee\x44\xae\xc1\x73\xd3\x34\xbe\x7a\xc5\xf1\x80\xb5\x23\xa9\xb7\xf4\x91\x64\xff\x3f\x1b\xd9\x5a\x1e\xf8\x06\xea\xb0\x50\x0a\x17\xf6\x80\x85\x40\x15\x92\x58\x9d\x21\x88\xb5\x53\x28\x4d\xe7\x5e\x84\x7c\x34\x40\xbc\x8f\xc8\x5b\xfa\x78\xa6\xb9\xb7\xd9\xc3\x85\xf6\x40\xee\x87\x7b\x84\x92\x2a\xf6\x44\x90\xfb\x6a\x6c\x6d\x4c\x7e\xb2\x75\x3f\x19\xca\xc6\xd8\x5d\x3a\xe9\x70\x2d\xe3\xc5\x02\xba\xc9\x47\x18\xfb\x58\x1b\x07\xf8\xac\xd5\x90\x29\xa7\x56\x33\x22\xc6\x22\xcf\x5d\x46\xb2\x0f\x0d\x49\x9a\x36\xa7\xea\xe8\x9b\x36\x71\x96\xb6\xdc\xa9\x3a\x8c\x63\xbc\xe2\x43\x64\x9d\xde\x6d\x45\xad\x14\xe1\x19\x1d\x1b\x92\x73\xf8\xc0\xa1\xba\x41\x92\x10\x65\xed\x9b\x66\x6b\x51\x9c\x23\x64\x31\xd0\xc2\xc2\x21\x9e\x05\x4d\xf3\x61\x3b\x6b\xf0\xc1\xa6\xeb\x1a\x91\xa3\x32\xdc\x35\x90\xd2\x34\x92\x4a\xbf\x60\xf2\x74\xc4\xe7\xfa\x4a\x64\x36\xcb\xf0\xde\x42\x78\xa8\x07\x7a\xc1\xd6\x6b\xf5\x01\xb5\xda\x0f\x58\x31\x4f\xe8\xe3\x77\xc4\xfd\x94\x5a\xfe\x9f\x84\x0e\xbe\x81\x8d\x3f\x09\x11\x56\x2f\x3d\x1c\xc9\xae\x78\x7e\xce\x45\x37\xcd\x1d\x15\x92\xac\x06\x64\xaf\x5b\x96\x26\xdb\xba\x79\x4c\xa3\x7a\x6b\xe0\xb1\x0c\x46\xf0\xb7\xd3\xf6\x61\x01\x36\xba\xdb\xe1\x21\x2b\xe4\xae\x9c\xe7\xc2\x80\xaf\xd7\x82\x3b\xd3\xf4\x9e\x1c\x17\xc8\xeb\x6e\xc0\xc8\x43\x1b\xc9\x50\xc5\x1f\x36\x83\x01\x2e\x36\x8d\xdf\x19\xb4\xc8\xda\x8d\x5a\x96\x9c\x1c\xa4\x69\xfe\xbe\xb0\xb0\x9f\x08\x65\x69\x09\xca\x56\x97\x96\x4c\x3a\x23\x1c\xf5\xa9\xd7\xd4\x97\xdd\xfa\xdb\x59\x87\x80\xab\x5a\x0f\xe7\xde\x0b\x7c\x10\x1d\xbb\xa3\xb9\x76\xc0\x4f\xde\xb4\x1e\x61\xa4\xe9\x11\x46\xba\x1e\x21\xc2\x09\x6d\xc1\xf2\x0e\x36\x3c\x79\x02\x5f\xa7\x87\x92\x3c\xf5\xea\x60\xf2\x93\x67\x38\x86\xf0\x9d\x7a\x28\x3b\xf1\x54\xa9\xeb\xff\xa9\x17\xf2\xa4\x7d\xc5\xa5\x70\x4d\xfd\xa4\xb4\xec\xc0\x0d\xde\x2f\xdf\x7c\xfd\xaa\x08\xc9\x93\x78\xc4\x65\xaf\x13\xfa\xd4\x3d\xf2\x76\x41\xc5\xb1\x53\xa9\x7d\x92\x1f\x40\x91\xf3\xfd\x05\x4f\x37\x70\xda\x75\x3a\x98\xa1\xba\x55\xa1\x20\x2f\x41\xc2\x53\x48\x2f\x3a\x57\xa2\x01\xed\x8b\x24\x5b\x4a\xb0\x68\xaa\xac\x50\x5d\xcd\xca\xb3\x8f\x76\x47\x74\xd4\xe2\xdf\x2e\xba\x36\xf3\xfc\x09\xa9\xfd\xd8\x9c\x9f\xce\x40\xb6\x1d\xaa\x9a\x35\x95\xbc\x97\x6a\xaa\x01\xef\x0e\xd0\x7c\x2f\x2f\xfa\x7c\xe8\xb5\xed\x0f\xea\x0f\x8d\x7c\xe3\xf1\xfe\x7e\x41\x6e\xde\xdd\x0a\xef\xdc\xde\xbb\xcd\xcd\x66\xf9\xc2\x01\x1f\x67\xf5\xa6\xdc\xe4\x9b\xd8\xbf\x46\xde\xf0\x7d\x73\xe3\xbe\xb0\x5c\xe7\x76\x73\xb3\x59\xbd\x68\xc0\x11\xd2\x2b\x72\xf3\xce\xf6\xde\x39\x7f\xda\x78\x1b\x1b\xfb\xd7\xcf\x6e\xfa\x8e\x7e\x39\x52\xe0\x19\xb8\x42\x0c\x90\x5b\xda\x49\xc9\x0e\x03\xf5\x23\xce\xc5\x74\x26\xd8\x4a\x6b\x39\xc2\xa0\xd0\x1b\xb6\xc8\xe9\x8f\xe6\xa9\xd2\x43\x8e\x4a\x16\x39\xf3\x21\x13\x7c\xb0\x68\xef\x82\x93\x33\x5b\xb2\x8e\x57\x4a\xab\xda\x2d\x25\x6b\x23\x7d\x74\x3a\x56\x40\xf4\x4f\x08\xff\x7b\x75\x8f\x9d\x3d\xb4\x08\xb5\xaa\xbe\x0b\xa0\x1e\x78\x4b\x5f\xbb\xcc\xb3\x28\x31\x9c\xbc\xa8\x2d\x50\xed\x42\x06\xc2\x42\xe8\xa5\x4e\x58\xd0\xd8\xd1\x67\x0d\xe8\x95\x91\x76\x39\x68\x50\xb9\x5e\xe4\x3b\x9e\xef\x0c\xb3\x58\x54\x0d\x29\x98\x1a\xd2\x79\xf7\xb1\xe6\xf0\xda\x3a\x81\x7e\xe8\x84\xaa\x20\x8e\x06\xae\xbc\x19\xbc\xe9\x4e\x35\x7b\x15\x32\x85\x04\xc7\x9e\xcd\xf9\x56\x95\x33\xaf\xdd\xb6\x80\x6c\x9e\x2c\xd7\xc1\x6d\x04\x32\x53\x4e\xce\xf7\xe6\x30\xcc\x0b\x7c\x0c\xee\xdd\x7b\xc1\x9a\x14\x23\x87\x64\xd4\x80\xe7\x23\xac\xd7\x24\xe6\xc5\xa2\x18\x2a\xd1\xec\x3c\x5f\xac\x5c\x1d\x25\x5a\x21\x72\xc2\x4e\x95\x70\x62\xce\x46\xed\x7c\x29\x7d\xa8\x03\x1d\x3b\x5b\x21\xf0\x05\x3d\x79\xcf\xf6\xc1\x82\x4b\xe1\xbc\x78\xea\xea\x6f\x26\x73\x9e\x2b\xf3\x99\xe6\xcb\x8e\x7e\x04\x31\x75\xd7\x0b\x65\x6b\xde\x0a\x0d\xfa\xd7\xf8\x2f\xc2\x99\xd9\xa6\xba\xb6\x6e\xbd\xcd\xe3\xe6\x67\x7f\xfe\x02\x79\xef\x5e\xf8\xd7\xcd\x9f\x74\x7f\x66\x7f\x25\x5d\xd4\x80\x49\x08\x66\x38\x86\xc3\x6d\xb0\xae\x1d\x29\xff\x7a\xa2\x93\x02\x39\x13\xe3\x56\xf0\xed\x4b\xdf\x34\x8d\x17\xe2\xb9\xf7\xf6\xe5\xf7\x6e\x3c\x5f\x90\x8f\x5d\x4f\x48\x1a\x40\x59\xc2\x77\xfe\xa2\xbc\x39\x61\xb0\x68\x61\x1e\xcf\xae\x28\x71\x4e\x41\x06\xb6\x88\x30\xe0\x5a\x41\xd3\x84\x48\xae\x34\x72\xce\xbc\xbf\x07\x5d\x1a\x98\xb8\x28\xaf\x50\x01\x09\xae\xd2\xbc\xaa\x69\x1e\xf2\x2e\x97\x2e\xdf\xa5\x4e\x80\xf5\x30\x00\xb8\xb4\xc1\x2d\x36\x27\x76\xa0\x24\x0e\x94\x16\x1b\x6c\xcd\x09\x5f\x55\x11\x2c\x2b\xfe\x42\xac\x11\xb4\x76\xee\xe6\x3c\x10\x0e\x73\xd9\x55\x9a\x5f\x05\x68\x80\x64\xc1\xe3\x3d\xf3\x91\x2b\x1f\xac\x80\xbf\x89\x51\x81\xe6\x24\xc3\xf0\x45\xf7\x9d\xdf\xb1\x6f\x24\x1a\x1b\xa5\x33\xef\x39\xe7\x09\x4d\x53\x54\xbc\xf4\x49\x8c\xb5\x5d\x4c\x56\x08\xeb\x35\x68\x86\x6e\x5d\x01\x3a\x2c\x20\xf6\xa2\x33\x72\x92\xeb\xf6\x27\xb9\x5d\x32\x1a\xbd\x77\xe5\x2f\x40\xa8\x55\xf2\x02\x9d\x2b\x67\x4b\x54\x89\xda\xf5\x5f\xb5\x6b\x35\x0e\x83\xf8\x35\x29\xad\x48\xc0\xef\x57\x02\x7a\x05\x67\x50\x35\x87\x92\x3d\x58\xae\xf3\x63\x5e\xa7\x59\x03\x96\xce\x37\xf8\x6f\xe4\x04\x2a\x71\x25\xcb\xe1\x86\x50\xe8\xae\x54\xfc\x19\xbc\xb8\xcd\x96\x98\x17\x73\x66\x4b\x11\xa1\xa2\xc3\x71\x5b\x5a\x4d\x79\x4e\x57\x1d\xd3\x99\x6c\x7d\x23\x4f\xe3\x2e\xe1\x7e\x69\xb9\xa6\xb7\xe1\x9a\x9e\xe1\x2f\x11\x24\xc2\xa3\xbe\x8e\xbf\x5a\x1c\x66\x45\xc5\xf4\x88\x0a\x43\x77\xdd\x12\xbd\x2a\x64\x1b\x73\x72\x29\x21\xe7\x98\x56\xd0\x3f\xb0\x3b\x3b\xb4\x00\xb0\xd5\x89\xf5\x7b\x44\xe9\x45\xfe\x3a\x34\xcd\x90\x13\x33\xeb\x91\x95\x16\x78\xf9\xea\xf4\x14\x56\x2b\xd3\xb4\x12\x37\x11\x9a\x2f\x52\xbf\x75\x6c\x3d\x7f\xe1\x5c\x02\x1f\xda\xe8\x14\x77\xd7\xcf\x83\xcb\xb6\xb3\x90\x14\xdd\x0d\xc8\x00\x1f\xc7\xc8\x89\x41\x7d\x21\x62\x4f\x93\x7a\x1c\xee\x84\x2f\x6f\x79\x56\x97\x60\x7f\x24\x80\x17\x29\xff\xdc\x02\xed\x2a\x94\xc1\x31\x92\x23\x71\x05\x20\x27\xf9\xa0\x7b\x02\x92\x0b\x5e\x56\x9c\x9f\xe7\x50\xf4\x32\xcb\x2c\x85\x63\x9d\xc5\xaa\xc5\x34\x8a\x9c\x49\xc3\xb3\xb3\x80\x1e\xda\xc8\x06\x51\x46\x12\x56\x5b\x08\x97\x50\x18\x7c\x41\xd3\x28\xfa\x7c\x1c\x9d\x44\xaf\x94\x46\x91\xa5\x5c\xa6\x8f\xe2\x5e\x38\xa3\x77\x05\xac\x14\xa1\x56\xf7\xab\xfc\x77\xd1\xd5\x31\xb9\xbd\x1a\x92\xdb\xfd\x3d\xbd\xf4\x0e\x7d\x9a\x50\x53\x51\xda\x21\xe7\x86\xaf\x81\x34\x47\xd3\x71\xa5\xb4\x88\x92\xfb\x79\x6a\x88\x1c\x31\xe8\xb7\x9c\xa8\xcb\x0d\xbb\xfe\x92\x96\xf9\xb8\x18\x38\x62\xcf\xc7\x6a\x26\x32\x33\x1f\xfe\x40\xd9\x17\xb5\x02\x47\x5c\xca\x3b\xd6\x6c\x96\x75\xbf\xcc\xb2\x8b\x43\x98\xa8\xfe\x43\xd9\x2f\xb4\xf0\xfb\x63\xd6\xdb\x81\x41\xf3\x9a\xfe\xc0\x54\x8d\x75\xb5\x79\xd1\x4a\xbc\x4c\xae\xcb\x6f\x96\xa5\x2f\x72\xd3\x9c\x5a\xa4\xf1\xf0\x10\xdb\xa6\xc3\xc3\x93\xe5\x75\x96\x9f\x67\x56\x88\x7a\x22\x33\xe7\x95\x8c\x34\x2e\xc1\xa9\x90\x2b\xac\x10\x59\xde\x79\x6f\x72\x2c\xc8\x50\xb3\xfd\x21\xa3\x35\x33\x40\x25\x93\x74\xd9\x9a\x06\x08\x7a\xb1\xc7\x3c\x1f\x53\xdd\x33\x27\x98\x8b\x0c\x37\xac\x1d\xe7\x1e\xf5\x7b\xaa\x47\xbb\x94\xd1\xe2\xf0\x04\x3d\xed\x68\xc0\xfc\x0e\x74\xef\x3f\x45\x70\xf3\x18\x22\x1c\x99\xe6\x19\x5e\x8a\x40\x32\xd7\x71\x1c\x11\x5c\x46\x68\xb8\xfd\x05\xc7\xb5\x7f\x03\x1d\xe0\x01\xa2\x60\x08\x7f\xd5\x0b\xc9\x98\x5d\xb2\x07\x56\x82\x50\x03\x8f\xf0\x0b\x43\x8a\xe4\xfb\x9a\xdc\x78\xef\x06\x0c\xe0\xfc\x26\xe9\xb7\xfe\x37\xfd\xa6\x3d\x75\x92\x6a\xb9\xbf\xa5\x61\xac\xf5\x35\x08\x3e\xf1\x50\xe5\x37\xf0\x42\x9f\xf0\x73\x0b\x07\x6d\x69\x7f\x41\xb3\x2c\xa0\xe1\x5d\x35\x30\xc4\xa3\x64\x02\x25\xf3\x16\x9d\x3e\x2c\x4b\x8b\xa5\x75\x67\x77\x89\x2b\xce\x35\xb8\x41\x5e\xac\x70\x4a\x46\x47\x2b\x23\xa0\x74\x58\xe4\x21\xc3\x11\x09\xc8\x6c\xb9\x56\x17\xb3\x6b\x5e\x02\x9d\x42\x92\x28\xa9\xab\x14\x21\xcc\xe7\xdb\x5b\x75\xae\xa0\xd8\xdb\xaa\x8b\xac\xd0\x5b\xfa\x38\xe4\x04\x19\xa8\x9d\x83\xf9\x62\x5d\x1c\xbe\xcb\x5f\xd3\xac\x12\x3a\x32\x71\xef\x55\x7e\xb6\x42\x2d\xb5\xf7\x6c\x5f\x94\xef\x41\xf7\x64\xb6\xe2\xbc\xc5\x6c\x85\x79\xd6\x98\x84\xae\xe7\x3b\x10\xa1\x62\x47\x4e\x83\x93\xa0\xd7\xdd\x95\x97\xdd\xc1\xa0\xee\xc5\x0a\x27\xea\x6c\xec\xd5\x5a\xaf\x22\xd0\xc4\x15\x6b\x11\x8c\x03\x3f\xe9\xb4\x56\xc8\x37\x85\x80\x13\xd3\x84\xd0\x65\x56\x88\x9a\xa6\x3b\x6f\x1d\x50\x17\x55\xbc\x64\x4f\x31\x28\x3f\xf9\x21\x32\x4d\x08\x29\x86\x5a\x2d\x10\x01\x96\x1d\x4d\x15\x7c\xb5\x58\x78\x56\x9c\x18\x97\x82\x98\x2e\x0c\xc2\x04\x0d\xa3\xc4\x39\x21\x29\x6d\x19\x4c\x83\x0f\x0b\x87\x88\xd3\x12\x28\x56\xe2\xe5\x10\xaf\x10\x0e\x6f\xc9\xd6\x34\xb7\x8b\x45\xab\xda\x1e\xd3\x67\xdd\xb1\xdf\xd7\x46\x71\x0c\x64\x49\xac\x19\x2d\x8f\x94\x34\x07\x2b\x01\xfa\x4d\xb2\x7a\x29\xd2\x9b\xc8\xc9\x48\x22\xae\x60\xc0\xa2\x74\x90\x7b\x62\x89\x67\x71\x8b\xb3\x42\x3f\xaf\xc7\x15\x85\x4d\x13\x34\x8d\x25\xea\x53\xcd\xf3\x22\x93\xd5\xcd\x18\xe8\x23\xb2\x9f\xd3\x7a\x10\xc8\xa5\x47\xe0\x0c\x60\x51\x5c\xa0\x80\x4e\xbf\xd4\x0c\x76\x95\x86\x30\x72\x42\xbf\x07\x30\x1c\x34\x8d\xb6\xa4\xbc\xee\x89\xbe\xee\x6c\xd5\xe8\x38\x36\x98\x56\x6e\xb2\xbf\x51\xdb\xe1\x91\x9d\xa6\x1f\xf5\xad\xbe\x66\xfd\x05\xea\x77\xbd\x25\xb3\xf6\xf5\x7b\xa5\xd4\x21\x11\x2f\x38\x06\xa5\x82\x69\xea\xa0\x1e\x7c\x20\x94\xc5\x3e\xad\x18\x72\x99\x8a\xb0\x63\x47\x45\xce\x80\xc1\xa3\x69\xc6\x61\x7f\xaa\x58\xbd\x65\x79\x5f\x06\x70\xb9\x13\x48\x9c\x20\xb8\x16\xec\x51\x75\xe3\x14\x21\xe5\x87\x14\x7c\x9b\x8c\x73\xa1\xb6\xed\xb1\xd9\x2b\x16\xb3\x72\x30\x31\xdd\xe5\xb0\xe7\x19\x79\x51\xa7\xf1\x7b\x83\x1f\xb7\x45\x52\xb2\xaa\x32\xb0\x86\x3a\x2d\x43\xa0\x16\xf0\x84\x32\xf5\xf5\xb9\x8f\x3d\xa3\x64\x55\x91\x3d\x30\x03\x1b\x7c\xa0\xa3\x0a\x38\x52\xbc\x9a\xae\x65\x98\xb4\xc4\xaa\xa2\xc8\x10\xb5\x82\x43\x5e\x6c\xf0\x59\xfb\xef\x56\xba\xc2\xb2\x1e\x5e\xa9\x8f\x23\x62\x1c\x58\x1e\x01\x39\xc1\xc8\xa9\xaa\x69\x3d\x05\x69\x51\x8b\x69\xf6\x48\xdf\x57\x93\x61\xff\x60\x35\x7b\xe0\x13\xab\x7a\x06\x8c\x06\xac\x8f\x31\x69\x43\x02\x8b\x2d\x55\x16\x38\x3d\x94\x1e\x06\xbd\x10\x9c\x5a\x57\x63\x7f\x04\xaa\xa5\x1c\xba\xd8\x14\x78\x2e\xc4\xd3\xd4\x81\xce\xff\x7a\x91\xf7\x89\xcf\xc9\x68\xf9\xb4\x8e\xbd\xc8\x5b\xf9\xbe\x75\xd6\x38\x03\xb7\x8c\x53\x71\xf8\xd6\x63\xe0\xd5\x20\xbe\x7b\x04\x5e\x44\xc0\x93\xc5\x89\x6b\x0e\x63\x6a\x1b\xd8\x72\x95\xe5\xc4\xf1\x77\x88\x58\xe9\x04\x5e\xe4\x2d\xfd\xb9\xc1\x77\xb8\xe1\x8b\x76\x99\x08\x7d\xd4\xb5\xde\xa2\x16\x61\x2a\xbc\xe7\xa2\xbe\xb5\x16\xf3\x19\xd5\x35\x01\x35\xeb\xc4\x65\xbf\xe3\x13\xab\x53\x0d\x1b\x5b\xae\x88\xdc\x5b\x11\x93\x4e\x0b\x8e\x87\x77\xe7\xc1\xf5\x76\xc0\xc9\x5a\xc1\x6d\x8c\xa4\x63\x94\x48\x4e\x16\x28\x42\x51\x60\x41\xbb\xce\x69\x61\x4b\x39\x8b\x21\x3d\x23\xbc\xdd\x0a\x7b\x84\xab\x8a\x65\xf1\x02\xe6\xe4\x08\x57\xd4\x68\xbd\x03\xa7\xa2\x7f\x34\x96\x17\x5f\x4e\x00\xa8\x61\x44\xa0\x1d\x72\x99\xbb\x53\xe8\x24\xb1\x62\x1c\xe2\x6f\x31\x43\xf2\xf1\x3b\x4e\xe0\x39\x56\x3c\x9f\xe3\x0f\x67\xea\xbe\x86\x72\x1d\xf9\xf2\x20\x5e\x36\x9a\x11\xf2\x2d\x10\x0d\x12\xf3\xa4\x84\xe3\x1e\x6c\xb1\xa6\x09\xd5\x2a\x43\x6e\x98\x16\x4e\xd6\xde\x11\xe6\xee\x74\x50\xe7\x48\x74\x67\x69\xc8\xac\x07\x72\x9b\x3d\x85\x0c\xec\x27\xfe\x5a\x14\x77\x1c\xe8\xa6\x53\x2c\x8a\xef\xec\x8a\x93\x98\x6f\x4b\x1a\x32\x84\x83\xf9\xea\x05\xe1\x67\x29\xef\xe0\x77\x13\x1d\x0c\x25\xc8\xc1\x51\x22\xbb\xb6\x0e\xdc\x3b\x0b\x39\x96\xd6\x4a\xc2\x6a\xa0\x5c\x45\xf3\x96\xde\x08\xb9\x90\xcd\x12\x96\xdf\xac\x7e\x9b\xee\x59\x71\xac\xad\x3b\x5e\xf7\x07\xf6\x2f\x47\xdf\xde\xd2\xf7\x3e\xf6\x81\x69\x4e\xac\x25\xa6\xc3\x75\xe4\x07\x89\xf3\x2d\xa6\x83\xd9\x07\x02\xf1\x03\x85\x02\xe4\x06\xce\xb7\x90\xef\xf9\x87\xf2\x45\xc8\x8d\x9c\xef\x10\x1a\xee\x25\xf9\xf8\x81\x40\x7f\x6e\x77\xbc\x50\xcc\x84\x25\x5c\x7c\x4e\xac\x87\x13\x24\x57\x42\x02\xef\x39\xa7\xa3\x03\xef\x53\x7f\xcd\xbc\x80\xe3\x1f\x92\xf0\x0e\xe2\xad\x69\xc2\x83\x8e\x8e\x22\xb2\x6d\x71\xe8\x7d\xbc\xa0\xbe\xf7\xdc\x57\xbe\xcd\x30\x4c\xda\x73\xdf\xe6\x34\x0a\xc2\xa2\x54\xc0\x07\xca\x69\x00\x84\x63\x2f\xf0\x96\xbe\x3f\x11\xf4\x4a\xa4\x0c\x90\x0c\x21\x24\x96\x82\x41\xe7\x02\x61\x31\x28\x44\x92\x8e\x10\x69\x11\x66\xdd\xcc\xc5\x48\xc8\x5d\x61\x37\xc5\x38\x46\x38\x6e\xf1\xe3\x96\x4d\xda\xaa\x8c\x63\x6f\x86\x24\xc0\x11\x51\xc1\x27\x31\x3b\x8b\xe2\x85\x70\xa2\x41\x9d\x85\xf0\x76\xc2\x57\x4b\x8f\xce\x42\x74\x8a\x38\xcb\x28\xb0\x28\x7f\x1a\x37\xf9\x62\xe5\x9e\xb5\xe1\x84\x78\xb1\x08\x9a\x26\xd1\xb7\x2f\x30\x83\x6d\xcb\x71\x5e\x70\x4b\x38\x1f\xc8\x69\xa1\x44\xa0\x73\xe0\x0f\x54\x6e\x9c\xc8\x9d\x85\x67\x01\xc2\xdd\x51\x0b\xde\x88\xe1\xac\xb5\xd0\x28\x2c\x28\xf3\x42\xdf\x34\xf9\x5f\x41\x00\x75\x77\xe1\x89\x38\x23\x91\xa6\x3d\xf4\x3d\xe4\xc6\x40\x30\xaa\x86\xb4\x48\x6b\x3d\x00\x4b\x36\xf3\x1f\xe4\xe6\x9d\xf5\xe5\x03\xcd\x9a\xaf\xf2\x9a\x95\x39\xcd\x9a\x1f\x68\x9e\xb0\xe6\x07\x3e\x89\x2c\x0f\x59\x23\xdc\xd3\x34\xa0\xc3\xfd\xe3\x0f\x5f\x21\xc0\xcd\xcf\x6e\xd6\x97\x70\x0d\x19\x72\x3c\xc0\xcf\x57\x85\x70\x32\x23\x1f\xed\x47\x5a\xe6\xa6\x19\x98\xe6\x3f\xe4\xdd\x9e\x9d\xd3\x3d\x43\xe3\x2c\x2a\x78\x75\xd7\xd2\x55\xd7\x92\x73\x65\xcc\x03\x7b\xcf\xaa\x8a\x26\x0c\x07\x02\xef\x80\xf8\xa3\x14\xd2\xea\x2f\x55\x4e\xa2\x13\x02\x03\xc4\xa3\xe3\x58\x38\x7e\x82\x16\xb5\x30\x2d\x3f\x0c\xc0\x48\x08\x9c\xa1\xd6\x29\x78\xfa\x41\x2c\x03\x45\x9e\xa4\x67\xfc\xa1\x46\xc2\xa8\x3f\x16\x45\x1d\x73\xd4\x53\xa0\x5d\xc4\xd2\x15\x86\xec\x3f\xd3\xb4\x76\xe4\xf3\x60\x6f\x80\x87\xb1\xd9\xd2\x5d\x2c\x64\xc5\x90\x93\x03\x0c\x54\x80\x9a\xc6\xea\x5e\xc0\x9d\xff\x4c\x04\x4e\x19\xe4\x7f\xb1\x6c\x9a\x1f\x46\xf0\xeb\x95\x3e\xc8\x17\xd5\x04\xc2\xa8\x88\x18\x5c\x4f\x1d\xbc\xe1\xf8\x46\xba\xea\x1f\x79\xb0\x7e\xf5\xdd\x37\xd2\xe4\xf4\xeb\x82\x46\x2c\x32\xf0\x1b\x84\xff\xf7\xff\xba\xba\xba\x82\x78\x97\x13\x25\x84\x0b\xeb\x37\x5d\x93\x16\x6a\x8d\xb0\xd8\x1f\x32\x56\x83\x6e\x4b\x24\x3e\xbf\xe1\xdb\xa2\x69\x20\xbb\xe4\x80\xf5\x14\xd3\x9c\x45\x63\x57\x7e\x76\x54\xbc\x09\xcb\x22\xcb\xdc\xc1\x8a\xcb\x76\xc0\xc7\xf1\xb9\x0b\xee\xc9\x01\xd0\x89\x8c\xaa\xdf\x62\x0f\xbd\x1d\x6b\xd7\xc9\x20\x72\x8a\x5a\x9a\xd0\xa7\x27\x24\x5c\x6b\x01\x35\x88\xc6\xd2\xa3\x13\x23\xb3\x25\x5c\x8a\x6e\xaf\xd2\xfc\x2a\x44\x6f\xa1\xda\x2d\x0e\xbd\xad\x8f\x67\x4b\xa8\xba\xb3\xeb\x1f\x04\xd2\xe5\x25\xc7\x87\x17\x84\x14\x9e\x2d\x41\x27\xdf\x4a\x5c\xab\xbf\xd8\x57\x21\x16\x90\x63\xed\x48\x80\x83\xb3\x0b\xc3\x8e\xa7\xec\x85\xf1\x21\x78\xae\x94\x97\x5e\x9d\x49\x40\x00\xa6\xd4\x38\xc4\x89\x1b\x39\x91\x0a\x24\xba\xf5\xf1\x16\xab\x24\xcd\x0c\x80\xb9\xd4\xd9\xb9\xaa\x1f\xc8\x49\xdd\x00\x5c\xc6\x70\x6e\x2e\x6e\xf1\x8f\x53\x7b\x6c\x78\xd3\x2d\xfc\x3f\xe9\xef\xb3\xb9\x76\x0f\xde\x43\xeb\x4f\xb0\xb5\xd3\xca\x96\x51\x84\x85\x86\x07\x7f\x9a\xff\x64\x43\x50\xc6\x16\x7e\xc9\x0a\xff\xa4\x47\x3c\x07\x6f\x4c\x53\x47\x92\xa7\xd7\x36\xf2\xf9\x72\x6a\xf1\x8f\x22\x2c\xa1\xee\x64\x72\x58\x82\x04\x8e\x94\xe9\x0b\x6f\x2d\xbd\xb1\x3e\xd6\xf3\x61\xa9\x2d\x1d\xe0\xb0\xc8\xe3\x34\x39\x96\x20\xe4\x80\xfb\x72\x84\x83\x16\x57\xac\xbe\x14\xd1\x53\xdc\x36\xc1\x08\x94\x13\xe5\xb3\x50\x99\x88\x79\xa5\xdd\x45\xa8\xb5\x02\xe4\x93\x70\x3d\x0c\x0a\x3b\xce\x13\xa1\x61\x30\x53\x36\x8e\xe7\xae\xdd\x9a\x08\xa0\x04\x9f\x2b\x83\xce\x38\xa3\xd9\xe0\x4c\xd6\xe0\xc3\xb8\x57\x2d\xa6\x61\xc8\xaa\xea\x92\x10\xbc\x6f\xa8\x69\x82\x09\x89\x6d\x60\x9a\x5d\x96\xd0\xed\x2e\x6a\x78\x5f\x1d\x71\x6f\x53\x89\x57\x1c\x22\xdc\xdf\x7b\xba\xa1\x13\xa0\x73\xb1\xd9\xe0\x5e\x6f\x0c\x0a\x83\xbd\x08\x1c\x4f\xf7\x1a\xa0\xd3\x30\x72\x36\x27\x3d\x49\x00\x42\x69\x6d\xc0\x52\x9f\x45\x9f\x00\x2c\xae\xb6\xaf\x22\xd7\x0b\x7c\x27\x18\x08\x76\x2f\xe8\x0f\xcb\x20\x30\x91\x17\x78\xa1\xef\xb7\x96\x3e\x45\x1c\x35\x68\xf1\x95\xad\x08\xfd\x0e\xb4\x4a\x8a\x4f\xd6\x39\x4a\xe5\xcc\xca\x96\x56\xaf\x68\x4d\xff\xf8\x56\xe9\x27\x45\x86\xf3\xd4\xfb\x13\x70\x12\x8a\x17\xff\x19\x0c\x2f\x7f\xc2\xbf\xc8\xdf\x7f\x4a\xf5\x87\x93\xd0\x7d\xb8\xde\xb4\xcd\xc6\x53\xcf\x3e\x7a\x06\xd1\xde\xbc\x97\x8b\xff\xf2\x75\x21\xf9\x33\x2d\x60\x77\x5d\x1e\xe1\x48\x01\x06\x91\x66\x15\x03\xb9\x3f\x67\x21\x39\x0a\x14\x5e\xa3\xc0\x35\x16\x3f\x5e\xe7\x74\x6e\x18\xee\x9c\x3a\xff\xec\xf4\x33\xfe\xf6\xe6\xbb\x6f\x85\x06\x01\xc0\xb1\x66\x4b\xf0\xeb\x99\xea\x60\x0f\x72\x63\x0d\x23\xb0\xab\x20\x46\x44\x6b\xba\xe0\xf4\x8b\x52\xeb\xfd\x2f\x6c\x2c\x9e\x99\xc6\xd8\x53\x42\x38\xd6\x60\x8c\xd0\xb9\x86\x46\x28\x38\xc4\x90\x3c\xb3\x42\xa4\x39\x86\xfc\x45\x83\x6d\x71\x5c\x84\x64\xe8\x36\x31\xd4\x24\x60\x53\x0b\xd9\x59\xa3\xcb\x44\x8b\xa2\xa6\xf9\x59\x7b\x6b\x71\x34\x2c\x33\xd8\x9c\xbf\xd8\x62\xf3\xaa\x3e\xc8\xfd\xf4\x6a\x5c\x04\x9d\x7e\x91\xe4\x81\xf4\x34\xf9\xeb\x87\x6a\xfd\x79\x5c\xeb\xaf\x17\xab\xfd\x79\x50\x2d\x50\x36\x9a\xe2\xc0\x59\x23\xc3\xa0\x00\xf2\x1e\x19\x27\x9c\x4d\x8e\x35\x6d\xda\xc1\x0a\x0b\xf5\x18\xed\x0e\x08\x4e\xe1\x5f\x00\xcb\xc4\x42\x1b\x2c\xd6\x2e\xda\x67\x3f\x8b\x14\x6c\xc8\x49\xe4\x4b\x5b\x19\x08\x89\xdb\x8f\xb3\xcd\x9c\x00\xe9\x6f\x45\x84\x3f\x00\x8d\x8c\x97\x40\x17\x75\x6e\xd8\x04\x28\x89\x6b\xab\x01\xba\x96\x52\xd0\x4f\x11\xc2\xbf\x0a\x13\x3d\x2f\xf2\xf9\x29\xfc\x33\xc0\xc5\xb8\x0b\x78\xb6\xec\xb4\x2c\x55\xa8\xa8\x73\xe9\x8a\x40\xa1\xc0\xb8\x6a\xc4\xb3\x80\x34\xc1\x16\xa2\x16\x39\x6f\xc5\xf3\x99\x2c\x15\x6c\x3c\x34\x8c\x1c\xc8\x00\x0b\x72\xba\x30\xd5\x71\x70\xaf\xa9\x0f\x79\x7e\xbd\x98\x2e\x60\xfb\x77\x3b\xc6\x41\x00\xb5\xd2\x7f\x2c\x3e\x67\xf4\x44\x0a\x9f\x85\x69\x38\x1d\xde\xde\x9f\xb7\x24\x41\xad\x9b\x05\x01\x6f\x0a\xd8\xee\x8f\xec\xc8\xa6\x4f\x6c\x3e\xbe\x4e\x1d\x2b\x20\x60\x9d\x18\x3f\x19\x68\x6e\x40\x21\x03\x47\xe4\xe7\xee\xd4\xc2\xa1\x69\x82\x0b\xea\xe1\x81\x12\x22\x97\xe7\xd2\x76\x86\xae\xa3\x13\x22\xe4\x44\xfd\x45\x15\x44\xf7\x6b\x71\xc4\xce\x3b\x85\x4e\x10\x93\x8f\xb7\x2f\xbc\x16\x93\xd2\x86\x5c\xa2\xf1\xa8\x0b\xb3\x05\x11\xb7\x3a\x0b\x6e\x52\xda\xbf\x42\x36\xce\xff\x55\x9d\x33\x21\x4d\xb0\x60\xcb\xd6\xc4\x56\x5c\x1b\x69\xde\xc9\xd2\x89\x0c\x93\xa3\x55\x18\x2d\x16\x60\xf7\x69\xf1\x8e\x10\xa9\xb0\xab\x7c\x0f\xeb\x65\x11\x96\x47\x53\x0c\x17\x80\xb8\xbb\x1a\x48\xc0\x48\x74\x16\x99\x26\xec\x5e\xb8\x4d\x02\x89\x84\xc5\x31\x46\xdf\xd7\xe9\x50\xf4\x72\xea\x21\x87\xb1\xee\x10\x8f\x58\x84\x10\x90\x60\x37\xd5\x21\x3e\x89\xbb\xaa\xcb\x12\xf6\xb1\xbc\x46\xc3\x4b\x5e\xd0\x2d\x73\xe8\x8b\x00\x4d\x63\x3c\x35\xb5\x4a\xa2\x9f\xcf\xd5\x45\xf6\x84\x2e\x91\x25\x62\xa0\xf3\x09\xc4\x1c\x93\x9c\x41\xfc\x6d\xe8\xaa\xb5\x55\xa8\xae\x8b\xd9\xd1\x51\x6e\xce\x24\xb0\x0f\x21\xa3\xdb\x5e\xeb\x21\x14\xc8\x9d\x80\xe5\x1a\x52\xa1\xe5\xaf\x56\x8e\x6f\x61\xd0\xd7\xe9\x41\xa3\xdf\x3a\x13\xb0\xf9\xe1\xed\x37\x59\x49\x98\x31\x5a\xfe\xe3\x83\xf5\x48\x98\x14\x10\x8f\x3d\x7f\x52\xb0\xa7\x53\x7d\x2b\xcc\x86\x12\x26\x71\x50\xe0\x64\xa0\xe3\xb5\xd5\x61\x7f\xb1\x88\x9a\x86\x0d\x98\xed\x18\x7b\xb1\xcf\xb7\xc1\xe5\x85\x13\x0b\x01\x26\x49\x72\x3f\x6a\x51\xbe\x24\x42\x88\xbd\xc4\xc7\x74\x00\xac\x32\x62\x0c\x40\x24\x3f\x13\xe6\x73\x2c\xdf\x00\x08\xb7\x3d\x17\xb6\xb5\x74\xb9\x5c\xd0\x49\x84\x28\x25\x37\xde\x7c\xe1\xbb\x9c\xde\x8a\xae\x37\x76\x83\x36\xd1\xdc\x72\x1d\x8f\x7d\xe9\x43\xc2\x26\x9a\x37\xe8\x46\x06\xbe\xc3\x01\x25\xe3\xb0\xc2\x10\x93\x18\x91\x06\x59\xc6\x9c\xd2\xb9\x81\x40\xcd\xfd\x3f\xfc\xeb\x2e\xd4\x70\x48\x89\x67\xbc\x2d\x0e\x06\x36\x7e\x48\x93\x6d\x6d\x60\xe3\xf3\xa2\xae\x8b\xbd\x81\x8d\xaf\x59\x5c\x1b\xfe\x20\x4a\xec\x30\x50\x7a\xd0\x34\x14\x1b\x79\x91\x0b\x82\xce\xae\xea\xf7\x19\x44\x78\x83\xf8\xe3\x8d\x31\xf1\x95\x83\x59\xa7\xc6\x37\xf2\x58\x8d\x39\xcb\xd6\x55\x57\xda\x21\x6c\x6b\x43\x96\x34\x44\x74\xda\x31\x87\xdf\x69\xd3\xe2\x84\x9c\x5a\xe0\xd6\x63\xc1\x35\x25\x5e\xec\xab\xe6\xbd\xd8\xc7\xfd\x23\x09\x44\x6c\xa0\xb0\x0b\x05\x0b\x98\x18\xe9\xa5\xb5\xdc\xbc\xa2\x9e\xd9\xea\xa9\xda\x98\x9e\x75\x82\xac\x70\x42\x9e\x2f\xf1\x96\x44\xe7\xae\x4f\xaf\x22\x3b\x3c\x96\x96\xee\xac\x5e\xbb\xff\x0f\xe5\x79\x01\xfa\x0f\x29\xe1\x50\xb1\xe3\x74\x6b\x08\x5e\x6b\x2d\xc8\xf0\x2d\x04\xd4\xf7\x02\xdf\x35\x0c\xc7\x38\x3c\x19\x08\xdf\x91\x51\x52\xd3\xf0\x84\x19\x21\x3b\xd3\x9c\xa7\xc8\x34\x03\x2a\xd4\x7e\xbb\x26\x84\xcb\x8e\x3b\xd3\xbc\xf3\x3e\xf6\xc1\x3a\xfa\xb4\x23\xbb\xa6\xe1\xaf\x58\x5d\x84\xdf\x91\x79\xda\x34\xab\x75\x54\x5c\xc5\x24\x6e\x1a\xc3\xfe\xd4\xc0\x77\x37\x24\xc6\xa5\x98\x19\xe8\xec\xdd\x7c\xa7\x84\x9e\xf1\x8c\x10\x2b\xe6\xfd\xbe\x49\xa5\xee\x5b\x6c\x9a\x8b\x45\xd2\x51\x33\xfc\xc4\xbc\x23\xf3\xbb\xa6\xe1\x55\x2f\xf9\xc9\xe5\xad\x7c\xf7\x6e\x6e\xf1\xdf\xf9\x0a\x5d\x87\xde\x73\xdf\x99\xf3\xbf\x38\xe2\x9b\xc6\x3e\xe6\x69\x4d\x76\x38\xb2\xab\x9a\x96\x35\xb9\xc3\x91\xcd\xf2\x88\x80\x95\x31\x18\x6f\x24\x14\x56\x5d\x2d\xc9\x96\xea\x7e\x78\xc7\xf0\x15\x69\x46\x4d\xe0\xfd\x5a\xe7\xa2\x5d\xe6\x80\x5f\xdd\xa0\x88\xde\x0f\x82\x94\x84\x23\x4b\x35\x70\x85\x20\xc1\x33\xd0\xc0\x13\x7f\x28\x86\x66\x07\xd6\xe2\x84\x35\x82\xac\x08\xef\x0c\x84\xa1\x0f\x84\x0d\xe2\x8f\xa6\x74\x64\x50\xc3\x69\x46\xa1\x41\xb1\xc4\x49\xef\xc0\x22\xbe\x4d\xd6\xf1\x7c\x8e\x22\xf0\x04\x0e\x93\xf4\x3e\x63\xe0\x5a\x26\x1a\xee\x3a\x1c\xb8\x56\xd7\x03\xbe\x0c\x00\xd7\x02\x77\x45\xda\x10\x9a\x46\x58\xbe\x7b\x31\x07\xb9\x51\x25\x04\xe2\xc7\x19\x42\x1c\x38\xda\xd4\x11\xb5\x22\xa4\xea\xdd\x82\xbb\x08\xe4\x88\x16\x67\x5a\x8b\xe2\x0b\x16\x84\xaf\xd6\xb0\x90\x4a\xc1\xee\x23\xcb\x6e\x5c\xe2\xfa\x86\x09\x2f\xe7\x7c\x88\xa3\xfe\xf0\x94\x81\x52\xa5\x76\x56\x57\xdb\xe2\x71\x62\x9b\xa5\x54\x9c\x4b\x40\x5d\x6e\xd3\x68\xea\x3e\x5d\xe6\x41\x2d\xae\x8b\x24\xc9\xa6\xce\x2c\x23\x28\x8a\x8c\x51\xfd\x62\xd3\x95\x24\x39\x6f\xd8\x92\xba\xe5\xbc\x01\xf5\x3c\x3e\x28\x23\xd9\x8a\x5b\x8a\x5f\x55\x50\xbd\x8a\xb2\x6d\x77\x1a\xec\xa8\xe0\xbc\x95\xc7\xa6\x06\x7c\x38\x81\xf1\xd1\x1d\x25\x37\x43\x03\xa6\xa1\xba\x1a\xba\x49\x71\xc6\x8b\x3f\x6b\x36\x37\x96\xeb\xec\xe8\x03\x6d\x58\xb8\xa7\xa8\x0a\xcb\xf4\x50\xdf\xa4\x78\x4f\xc9\x49\xb8\x7f\x73\xbc\x15\x36\x54\x38\xa3\xfd\x31\xab\xd3\x43\xc6\xc8\x47\xea\xe9\xa3\x17\x06\x36\xfa\x40\x46\x3e\xae\xb7\x8c\x46\xa2\x10\x58\x95\x8a\x74\xf9\xe8\xe3\xb0\xc8\x1c\xef\x79\x97\x78\x1b\x16\x59\x52\x16\xc7\x83\xc8\xd6\xbd\x69\x25\xea\x72\x50\xa0\xe6\xfb\x51\x56\x0a\x8f\x7a\xd6\xc8\xf1\x3e\x1e\x67\xbd\xad\x4b\x99\xbd\x7c\x31\x51\xe6\x57\x69\xb5\xe8\x78\x4b\x6c\x18\xd8\x30\xfc\x76\xbd\xa7\x76\x71\xa8\xa1\x27\x44\x3c\xa7\x45\x8e\xf7\xd4\x86\xd2\xfc\x53\x1d\x17\x45\xcd\x1f\x54\x8f\xe1\x99\x8a\x6b\x8d\x3d\xdc\x68\xd3\x08\x4a\x6c\xe1\x35\xea\x51\x52\xae\x7b\x38\xe8\x18\xfe\xcb\x31\xf9\xce\x83\xbe\x5d\x88\xd8\x28\x9c\xa7\x20\x67\xba\xa6\x71\xf8\x23\x77\x22\x22\x92\xaa\xc1\xf3\xf1\x48\x7e\x27\x8c\xeb\xdc\x4e\xe9\x93\x82\x4c\x38\x1c\x86\x8f\x1d\x79\x59\x03\xf4\x2a\x51\x53\x78\x1b\xad\xc3\xf9\x1c\x89\x9d\x4e\xbd\xd0\xc7\x46\x92\x15\x01\xcd\xbe\x7c\xa0\x99\x01\xe6\xca\x02\xfd\x04\xe3\x34\x24\xac\xf2\x0e\x1c\xa8\x1b\xf3\x4f\xee\xe6\x71\xbe\xd6\xac\xe9\xee\x2f\xb9\xcc\x51\x2e\xbf\x70\x46\x02\x89\xb1\x15\xe2\x7f\x5d\xd2\x04\x50\x37\x52\xee\x68\x96\xb8\xe8\x3b\x9b\xdf\x16\xeb\x5c\xd8\x18\xc4\x84\x7a\xb9\x8f\x63\xe1\xa5\x32\x46\x93\x57\x03\x31\x42\x6a\x62\xf6\x38\xd6\x7c\xd7\xc4\xbe\x13\xa3\x2e\x48\xf7\x81\x0a\x99\x55\x8c\xd0\x29\x21\xe0\x02\x62\x10\xb5\x6b\x6c\x00\x1d\xa5\x0f\x1c\xc1\x6e\x89\x75\x27\x4f\xec\x18\x35\x8d\x27\x80\x14\x9d\xfb\xc8\x4f\xc9\x9e\x7a\x5b\xbf\x69\xf6\xd4\x56\x50\x8d\x13\xcd\x92\x38\xe5\xa7\x6a\x69\x6f\xeb\x7d\xf6\x7d\xc9\x94\x9d\x05\x9a\xa7\xfc\x7c\xbd\x03\x7b\x7f\xcd\xd9\x4c\x42\x92\xde\x07\xf3\xba\x1f\x60\x32\x88\xc3\x9f\x90\x4c\xd7\x52\x4e\x74\xff\xa6\xc4\x30\x84\x08\x40\x3a\xfd\x50\x23\x7c\xcb\x9e\xe0\x4c\x84\x00\x15\xd9\xa8\x04\x5f\x8c\x2e\x12\xe3\xde\xcb\xa5\xef\x8b\x08\xf4\x76\xa4\x5a\x62\x8c\x23\xd0\x70\x04\x3d\x1f\xe5\x7a\x41\x4d\xf3\x8e\x68\x14\x65\x3c\x3a\xf1\x63\xde\xe3\x9c\x5a\xc3\xa9\x8f\x11\x36\x04\xea\x33\xe0\x36\xa6\xa0\x56\x82\x70\x88\x4e\x77\x5a\x5f\x12\xef\x8e\xf7\x25\x53\xab\xa8\x1c\x2f\x1a\xa8\x33\x5a\x8d\x3b\xd2\x26\x6b\x67\x67\x5a\x49\xd1\x65\x28\x0c\xc8\x30\x82\x5b\x74\x01\x16\x42\x72\x96\xa2\x42\xc4\x85\xd3\x21\xe2\xe0\x54\x80\xc8\x39\xc3\x64\x15\x26\x0f\x1b\x7d\xc0\xbc\x71\x1e\x19\x36\xae\x06\x52\x66\x40\x01\x21\x5c\x08\x3f\xa1\x5f\x64\x45\xce\xf8\xfe\xe2\xbf\xb0\xa6\xb3\x25\x1a\xbd\x75\x40\xa4\x5c\x8b\xe2\x60\x60\xde\xce\xd7\x9f\x96\x8c\xbe\x78\xba\xbd\xe9\x9e\x0d\x5c\xd8\x79\x01\xd5\x7f\x21\x4a\x11\x30\x7d\xbd\x50\xf3\xc0\xf4\xdc\x12\x27\x64\xc9\xa7\x7c\x1c\x21\xb8\xe2\xe7\xde\x1d\x7b\x7f\x83\x6b\x79\x80\xee\x8b\x63\xc5\x9a\x43\x91\xe6\x35\x2b\x9b\x50\x98\x15\xef\x59\x7e\x6c\xa2\x92\x26\x4d\x54\x16\x07\xd4\x84\x59\x1a\xde\xdd\xe0\x23\x94\xf1\xde\xd9\xfe\x35\xe2\x5c\x98\x6d\xd9\x73\xd4\x20\x0d\x1d\x3d\x50\x3d\xb2\x41\xf7\xf9\x51\xfb\xbc\x1a\x38\xdb\x12\x32\xe2\x8e\x21\x18\xf8\x8c\xed\x15\x8b\xda\xa1\x0b\x26\xdd\x41\x17\x50\xbd\x78\x3b\xbc\xb5\xec\xae\x93\x4e\x67\x9c\x6c\x08\x12\xc9\xa8\x69\x42\xac\xc4\xce\xa8\xbf\xd4\x0c\x10\xd4\xbf\x85\xfa\x03\x6f\xeb\xe3\x58\x23\xa9\xd2\x58\x5a\xc6\x44\xc2\xc9\x0d\x21\xcc\xb5\x18\xe1\xfc\x77\x57\x97\x23\x13\x4c\xf3\xfc\x7a\x2b\xe4\xb9\x23\x1c\x75\x79\xe5\xab\xd6\x15\x4e\x4b\x83\xc7\x72\x46\x1e\x69\xb7\xa9\x67\x5d\x84\x25\xaa\xfb\xdc\x8f\x4d\xd3\x4a\x38\xb5\x3c\x75\x33\x59\x5a\xc8\x2e\xe2\xd8\xa2\xa0\x62\x33\xa5\x0d\xd8\x62\x66\x27\xc7\x34\x22\x09\xfc\x80\xa3\x34\x78\x2f\xe1\x67\x3e\x07\x85\xa8\x73\x91\x06\x7b\x60\x79\x0d\x6c\xbb\xb4\x5c\x60\x38\x82\x0b\xd8\x56\xa6\x91\x93\x38\xc0\x9c\xd3\xb9\x05\xd3\x20\xf8\x80\x7e\x4c\x29\xe7\xff\xf8\x5e\x89\x15\x91\x74\xd3\x1f\xda\x5b\x88\x2c\x53\x0a\xad\x78\x1c\x92\x58\x7d\x01\x5d\x1b\xe5\x9e\x00\x44\x73\x17\x4c\xc6\x4a\x8a\x45\x34\x66\x31\xd0\x70\x34\x50\x6c\xa5\xe4\x5e\x74\xbe\x42\x4d\xa3\xbd\x81\x9b\x3f\x2b\x21\xf7\xb2\x49\x71\x6f\xad\xde\x06\x3a\x1c\x92\x18\x9e\xa0\x3f\x4a\xde\x2f\x31\x6d\x75\x99\x26\x09\x2b\x21\x7e\xbb\x88\x44\xef\xaa\x24\x4e\xc8\x83\x85\xbf\x62\xc3\x35\xdd\x1e\x19\xb3\x96\xe3\x4a\xa0\x53\x0c\xa4\xdf\xb9\x19\x86\x8f\x77\xe3\x4b\xb7\xdd\x62\x81\xb6\xe4\x28\x0f\xcf\xc0\xdb\xf9\x48\x3a\xca\x3f\x90\xad\xb7\xf2\x71\x41\xac\xad\xf7\x5c\x06\xb4\x91\xbe\x4f\x6c\xe5\xfc\x04\xe1\x1c\x5c\xda\xab\xce\x81\xd7\x08\x9a\x79\xb9\xdf\x34\xa7\x16\xe7\xc4\x62\x6e\x66\x47\x2c\x63\x09\x3f\xd3\xde\x1f\x98\x93\xd9\x41\x9a\x47\x70\x9d\xd4\x34\x39\xbe\x58\xf6\x8e\xf4\xf2\x67\x70\xaa\x99\xe3\xa2\x4c\x13\xa8\xe3\x20\x6e\x6e\x22\x2c\x17\xd8\x09\x31\x5f\x22\x47\x2c\x18\x56\x4b\xed\x30\xac\xbb\x41\x70\x60\xe1\x2f\xf8\x48\x90\x66\xb2\x08\x73\x84\x5e\x1d\x68\xc8\x9c\x42\x3a\x76\xb1\x0d\xd4\xf2\x43\xd1\xda\x93\xd4\xcb\xf9\xfc\xc8\x27\x4e\x16\xed\xbb\xd1\x7d\x51\x1c\xf3\x9a\x2c\x71\xc6\x4f\x88\xe3\xc1\x34\xe5\x43\xef\x8a\xa0\xc0\x09\x9a\xf1\x7d\xdb\x34\xe7\x7a\x19\xa6\x39\xa1\xab\x91\xe3\x04\x21\x9c\xf1\x04\x3e\xcf\xfc\x57\x55\x77\x87\xf0\x9d\x02\x70\x05\xb0\xc3\x0f\x44\x4c\x07\xc7\x16\xee\x5e\xd9\x39\x8c\xfa\x3b\x9f\xe3\x25\xbe\x43\x8e\xa4\x3e\xee\x40\xea\x0f\xcb\x21\x36\x27\x1f\x25\xe7\xfb\x26\xaf\x93\xff\xd8\x2e\xed\x2f\xdc\x4c\x73\xb0\x67\x4d\x53\xdf\x4f\xe8\xf4\xef\x01\x6d\x1a\x5b\xff\x23\xb8\x45\xa7\x0f\x81\x6d\xf4\x3b\x60\x2b\x00\x00\x5a\xdc\x92\x2d\x44\x74\x1a\x05\xcd\xd9\x6c\x6c\x64\xcc\x15\x0c\x6d\x36\xb6\xe5\x3a\xf6\xf5\x66\x63\x37\xc8\x40\x73\xc3\xe2\x4f\xcf\x90\x01\x57\x0d\x64\x7f\xee\x7d\xe9\x8e\xec\xbd\xd8\xc7\x33\x66\x9a\x87\x19\x21\x77\xb6\x82\xfe\xa6\x01\x21\x29\x5f\x5a\xf8\x2e\xd6\x7e\x6b\x9a\xb3\xad\x00\xe2\x3b\xbb\x83\x61\xd4\x34\x91\x69\x8a\x7c\x55\x17\x0e\xd0\x32\xae\xaf\x41\x0d\xa9\x69\x66\xfd\x77\x80\xeb\x81\xb7\x25\xbd\xcc\x08\x6e\x16\x0b\x9c\x49\x71\x0d\x07\x74\xf1\xd4\x83\x26\x5a\x27\xa6\x39\xdb\xf7\xb7\x8a\x9c\x82\xa5\x65\x54\x3c\xe6\x3c\xbb\x7a\x56\x05\x0a\xdc\x21\x4e\xb9\x3f\x4a\x5d\xe5\xca\xa2\x38\xef\x73\xa8\x4b\x13\xd8\x8b\x6d\xa7\xf6\x91\xf3\x93\x39\x45\x6a\x49\xbb\x3b\x8a\x7c\xce\x81\x03\x40\x75\xb6\x44\xeb\xf1\xa5\x7d\x0a\x50\xd9\xe5\x36\x44\x23\x57\x02\x28\x0d\xf0\x0d\x2d\x11\xee\x94\x9d\xb6\x6c\x2c\x4e\x9f\x40\xbd\x48\xe9\x4e\xf1\x9d\x00\x72\x65\x69\x21\x34\xba\xbc\x40\x78\x47\x2c\xb1\x15\x84\x6f\x05\xd5\x1a\x18\x34\x7a\x02\xe1\xfb\x52\xa2\x38\x86\xd1\x2e\x55\x0a\x6e\x39\x47\x42\x02\x2c\x5c\x6e\x8f\x5b\x02\x7e\x32\xf5\x42\x4d\x37\xd4\x0b\x41\xdb\x23\xe8\xc1\x1b\x22\x02\x88\x8b\x80\xd9\x9d\x7d\x28\xd9\x2b\x39\xe2\xa6\x19\xbc\x6a\x06\xcc\x81\x58\x27\x74\xda\x76\xfd\x93\x98\xa7\xd2\x73\xe1\x1d\x27\xc7\x15\x7b\x60\xc5\x64\xeb\x85\x9c\x3f\x30\xcd\x59\x60\xa7\xd5\xf7\x65\x71\xa0\x09\xc4\x19\x78\x53\x17\x87\x03\x8b\x2c\x8e\x06\xec\xf0\x58\x96\x2c\xaf\x65\xc7\x62\x9b\x65\x6c\xaf\x05\x9f\xb7\x92\xfe\x68\xaf\x44\x84\x3a\x59\xe1\x57\xfb\x3d\x8b\x52\x5a\xb3\xc9\x9a\x03\xbb\xec\x36\x06\x14\xe8\x5f\xc5\xc6\x49\x06\x1b\xc7\x0a\x64\x23\xdf\x05\x3b\x92\xe0\xc0\xe6\x67\x0e\x49\xe0\x07\x33\x62\x59\xe3\x95\x49\xba\x2d\xea\x0b\xcb\x54\x51\xbc\x69\x12\xd5\x5b\x24\x0f\x6d\x39\xa4\x54\xbb\x11\xe6\xa4\x20\x18\x4e\x1c\xb3\x9a\x30\x65\x19\x68\x05\x60\x48\xcd\xf2\xfa\x95\x20\xde\x39\x1f\x04\x97\x85\xda\x08\x2d\x84\x7a\x2f\x80\xf6\xa1\xa8\x6a\xb5\x62\xa6\x39\x7c\x1f\xac\x20\x56\xcd\x81\x22\x8c\x98\xcd\xcb\x1a\x05\x1c\xa8\xf9\x79\x97\x92\x60\x88\x09\xf0\x8e\x50\x5b\x44\x95\x00\x2f\xcc\xa6\xb9\xd3\x55\x06\x2c\x03\xd8\x02\xdd\x4d\x3e\xb5\x85\x1f\xfe\x17\x64\x25\x35\xf1\x76\x33\x22\x9c\xb8\xec\xc8\x6e\x60\xdf\x0b\x62\x3d\xe9\x71\x49\xaf\x56\xd5\x3a\xeb\x9d\xfb\xef\xba\xa8\xd8\xa0\x32\x8a\x84\x9c\x43\xda\x75\x9e\x5a\x2c\x5c\xda\xa7\xb0\x23\x22\x02\x12\x14\x46\xa2\x0e\xc3\xcd\x8d\x2b\xa3\x17\xe8\x24\x1e\xf3\x39\xd9\xec\x31\x9f\x44\x03\x3a\xc1\x2d\x2d\x26\x7c\x33\x48\x9f\x04\x3b\x30\xfe\x93\x0e\x5e\x44\x92\x8c\x63\xba\xeb\xe2\x98\x22\x2c\x2a\x8c\x3b\xef\xf3\x71\x87\x1a\xb7\xd2\x81\x38\x87\x08\x67\xa7\xad\x44\xdb\x2d\xea\x4e\x9a\xac\xdc\x06\xbf\x5b\x2a\x50\x1e\x00\xc1\xed\x39\x10\xd6\x1c\x52\x46\xeb\x3a\xad\xc4\x57\xda\x80\x6d\x7b\x4d\x42\x4c\xf1\x89\xe5\xc7\x3d\x53\xfa\x7b\x63\x7d\x3e\xd0\xa1\x1b\x9b\x25\x68\x5c\x80\x52\x2e\xe1\xfb\x22\xcd\x69\x06\xf5\x77\xca\x02\x53\x69\x83\x6b\x9e\x0f\x16\x3f\x4f\xf1\xa8\x3f\x52\x2d\xbc\x38\x54\x79\xeb\xfb\x3b\xa3\x7b\x2c\xd3\x5a\x3d\x4b\x8d\x46\x90\x2d\xb7\x38\x4e\xa7\xbd\x41\x78\x9d\x86\xa6\xef\x52\x07\xdc\xef\xdb\xf2\x08\x43\x2d\x96\x88\xc2\x39\x65\x05\x8d\x9c\x53\x5e\x7c\x7e\x0c\xa4\x62\xa4\x0c\x93\x72\x92\x84\xff\xc4\x2c\xcc\x08\xe1\x9c\xb0\x70\x11\x61\x43\xf6\xc1\x54\xc4\x22\x4c\x0a\x9e\xad\x5a\x3c\xa0\x5c\x0c\x48\x49\x73\xa3\xc5\x41\x76\x2c\x3f\xd4\x06\x19\xb4\xc1\x73\x0f\x9a\xe0\x1f\x2e\xb7\x50\x1c\x6b\xa3\xc5\xb0\x2f\x2f\xb5\x61\x28\x41\x3c\x47\x07\x50\xa5\xc0\x08\x42\xcd\x92\x97\x34\xcd\xcf\xe5\x99\x28\x65\x36\x83\x0e\x40\x16\xd9\x83\x4e\x26\x3d\x6d\xba\x2f\x51\x12\x36\x28\x1c\xe2\x01\x8b\x8b\x92\x1d\x73\x31\xf3\x3a\x4e\x1c\x1e\xeb\x0a\x1d\x53\x89\x1b\x39\xb6\x1a\x00\x19\x68\x1c\x0e\xbe\xd8\xa2\x51\x10\xab\x74\xe5\x50\xdb\xb6\x42\x99\xbf\xa3\x62\xce\x14\x94\x27\xd5\xca\x79\x83\x53\xda\xe6\x52\x07\xcd\x3e\xaf\x6a\xa0\x13\x30\xf0\x24\x24\x32\xbb\x16\x05\xfb\xb1\xce\x97\xce\xb0\xfb\xca\xad\x0e\xa8\x0e\x8b\x6c\xe2\x43\x5a\xc9\x33\xe7\x7b\x71\x02\xb1\x88\x74\xee\x0b\xbb\x4f\x4d\xd3\x2b\x93\x9d\x25\x8a\xb1\xf4\x93\xc3\xcf\x34\xf7\x81\x3a\x8f\xaa\x49\x71\xc0\xab\xb5\x32\xcd\x8f\xc5\x29\x01\x6f\x7a\xa4\x7b\xf9\xa5\x3f\x19\x9c\x6e\x7d\x05\x5c\x0c\x08\x06\x3a\x7c\x17\x59\xc0\x7f\x29\x8b\xba\x2c\x83\x77\x79\xdd\x24\xa6\x00\x07\x82\x4d\x04\xd6\x53\x9d\x95\x22\x3d\xdd\xb3\x37\x35\xdd\x1f\x88\x98\x51\xf5\xca\xc9\xd5\xbc\x78\xb4\xc4\x71\x2e\x14\x52\x7a\x44\x00\x87\xd1\x10\x17\x80\x9e\xe0\x19\xba\x25\x27\xcd\x5b\x94\x23\x93\xf1\xf9\x32\xf0\xf9\x9b\x22\x9e\xc4\xf7\x0f\xd0\x40\x22\xc3\x9b\x74\x7f\x84\xb1\x3b\xb3\x15\x1e\x52\x17\xe7\x26\xaa\xe7\xf0\xb2\xbe\x04\x1c\x0f\x14\x53\xd3\x9c\xc9\xe4\xae\x15\x88\x6e\x34\xa2\x61\x5a\x3c\x22\x61\xfe\x9d\x86\xcf\xc7\xf5\xa1\xa6\xcf\x68\x25\xd1\xf6\xd4\x2c\xfd\x3b\x9d\xf8\xc0\x2c\xff\x5e\x6f\xa6\x8a\x5a\x12\xc2\xce\x7b\x0b\x56\x36\xe0\xf7\x86\x66\xf5\xdf\xd9\x7b\x7e\x16\x05\x70\x6c\x80\x77\xa9\x90\xef\xf5\xac\x3b\xc0\xb6\x34\x4f\x58\xf4\xb6\x38\x42\xf0\x11\xfe\xa5\x2e\x33\x59\x2a\x62\x35\x4d\x33\xfe\x04\x8b\xf1\xfd\x96\x56\x50\x68\xcf\x6a\x2a\xb3\x1c\x68\xc2\x7e\x51\x0f\xff\xe4\x0f\xa0\xb4\x26\x53\x1f\x52\xf6\xc8\x7f\x8d\x70\x4b\x4b\x43\xb6\x57\x7e\xc1\xb7\xe3\x6c\x89\xef\x44\xa6\x3b\xf6\x5e\x7d\x91\x61\x9c\xba\x27\xd1\xa1\x2c\x65\x79\xfd\x4b\xff\x08\xcd\x14\x71\x5c\x31\xf1\x55\x3c\xc2\x57\x29\x6f\xfe\x2a\xd2\x5e\xe0\xc0\xe1\x1d\x0b\x4b\xc6\xf2\x5f\xfa\x47\x28\x21\x90\x82\x36\xfe\xba\x90\x62\x62\xf1\xd2\x7d\x7f\xdc\xa6\x93\x1c\x9d\xa2\x4d\xd7\x23\x4f\xac\x90\xdf\x34\x2b\xaa\xc2\x55\x81\xe3\x62\x57\x1a\x4b\xda\x6a\x22\xdc\xfe\xd1\xa1\x76\x37\x17\x5d\x79\x5d\x7f\xbc\x1e\xd5\xb5\x32\x03\x77\xe5\x3c\x37\x03\xf7\x63\xe7\x13\x33\x70\x9f\x3b\x4b\x47\x16\x14\x50\xa0\x04\xaa\x1c\x40\x50\x07\x16\x20\x9a\xe7\x3b\xb0\x74\x0c\x78\x2e\x1e\x58\x69\x60\x78\xcc\x18\x7d\x60\xea\xf3\xb1\x36\xd4\x24\xca\xec\xf2\x4d\x14\x90\x2f\xb2\x88\x4a\x82\x33\x7d\x74\xda\x8c\xd8\x1e\xea\x93\xd3\x80\x1c\x08\xb0\x12\x95\x38\x81\xa4\x4c\xcf\x66\x5a\x39\x71\xc4\x6c\x8c\x8b\x21\x54\x42\xc7\x78\x75\x9a\x26\x32\x98\x6d\xc4\x71\x6d\x77\x73\x05\x3e\x6c\x9a\x46\x4e\x21\x89\x3b\x06\x4c\x97\xfe\x4e\x8b\xb5\xb1\x2c\x03\x2e\x9e\xcf\xb4\x16\x07\xd1\xc7\x94\xba\x92\x72\x5d\x44\x3b\xa5\x41\xf8\xde\xe2\x22\x3f\x97\x8b\x5d\xca\x8e\x57\xbc\x40\x1c\x5f\xb2\x7f\x01\x7d\xda\x73\x9c\xc9\xbf\x74\x93\xa2\x68\xa2\x48\x9f\x29\x5c\x5a\x74\xc4\xd3\x0b\xd1\x7e\xd4\x73\xb5\x6e\xd4\xcd\xd0\xdc\xb0\x8d\xb9\x96\xe4\xf4\x49\xb8\xe7\x8a\x70\xd4\xb1\xae\x80\xa0\x26\x2f\x50\x64\xb0\x0b\x70\x22\x48\x91\xc0\x99\x71\x0c\x6e\xb6\xe9\x25\x0f\x81\xc1\x4c\x30\xb8\xbd\xb9\x7b\xef\x63\x15\x3c\x8b\x04\x38\xe8\xb4\x08\x43\xc5\x0d\x87\xe4\x51\xba\x54\xbb\x78\xe1\x30\x50\x64\xc6\xa1\xd0\x9b\x96\xea\x20\xbf\x81\xce\x87\x3b\xa3\x25\xa3\x4d\x50\x36\x61\x91\x35\x6c\x1f\xb0\xa8\xd9\x96\x4d\xba\x4f\x1a\xa0\x39\x9b\x2c\xcd\xef\x1a\x8e\x15\x9b\x03\x2d\xe9\x1e\x59\x97\xd5\x44\xae\x85\x17\x4b\xb4\xb9\x79\x71\x93\xa4\xf8\x25\x6f\x40\x5c\x92\x36\xb7\xa0\x77\xd3\xdc\xf2\xda\x6e\x52\xfc\x39\x25\x37\xf2\x6a\x6f\x53\x5d\x5b\xae\xe3\xbd\x23\x7e\x43\x36\xd5\xb5\xba\xf1\xb3\xd1\x4d\x8a\xbf\xa0\xe4\xe6\x5d\x5d\x1e\xd9\xe6\xc6\xb2\xaf\xd1\x0d\x7e\xc5\x3f\x6c\xaa\xeb\xdb\x99\xe5\x3a\x1b\xef\x8b\x57\x2f\xdf\xbe\xdc\x78\xcd\x62\x81\x1a\xfe\xc1\xdf\xf8\xfc\xf9\xc5\xa6\xba\x7e\xa6\x1b\x8f\x7c\x49\x07\xa4\xa1\x70\x55\xc5\x8f\x09\x03\x71\x12\xfb\xdc\x27\x5a\xa0\xdf\x50\x1b\x75\x69\x20\xb7\xb4\x8c\x17\xa0\xcc\x61\x60\x8a\xbc\xa5\xdf\x34\xd4\xd1\xdc\xa5\xbc\x1e\x46\x10\x82\xdd\x64\x09\x84\x78\x29\xfe\xdd\xdc\xb8\x31\xe6\x92\xc6\xd4\x6a\xfa\x4b\xaf\x80\x46\xbe\x90\x12\x5d\x89\x15\x3b\x1b\x35\x57\xed\x57\x6f\xe5\x3b\x8a\x44\x3e\x6b\x41\xaf\xf5\xaf\x74\x52\x88\x81\x53\xe1\xdc\x61\x14\x24\x93\xb3\x27\x43\x59\xb5\x15\x6b\x3a\xe9\x08\x27\x44\xe8\x65\x04\x38\x46\x78\x47\xe2\x5e\x6e\x2d\xe5\x91\x4a\xca\x83\x93\xfe\x52\x68\xdd\x6d\x8c\x9d\xf4\x7f\xb8\xc4\x11\xd9\x79\xcc\x1f\x2b\x7d\xe8\x17\x66\x01\x66\x98\xe7\xf1\x42\x1f\xb5\xbf\x0c\x3b\xb5\x25\xbf\x68\x9d\x4a\x89\xee\xd3\x6a\x8b\xf0\x2f\xb2\x8f\xe0\xf1\xa0\x9b\x8a\xaf\x46\x01\x43\x2e\x44\x51\xec\xfd\x98\x87\xa6\xb9\x1b\x1d\x4f\x81\x82\x53\xd2\x85\xbf\x74\x64\x01\xa1\xad\x66\xa8\x7b\x69\x78\x07\xf9\x99\x7e\xe3\x4c\x86\xbe\xcf\x35\xd5\xbd\xbf\x69\x2a\xa1\x01\x51\xd7\x90\x9e\x8f\x03\xb1\x6d\xf9\xc2\xf5\x7a\x2a\x4b\xbc\xef\xed\x51\x73\xb2\x5f\xac\xf0\x3d\x38\x36\xc6\xd5\xd0\x17\xca\x3d\xdc\x32\x54\x4d\xb3\x7f\xb1\x9a\x30\xae\xbb\x37\xcd\x99\x7e\x41\x6f\x9a\x9f\xcb\x11\xdf\x6b\xee\xda\x87\x68\xa6\x73\x38\x42\x6d\x76\x6f\x31\xb4\xae\x4c\xd3\x82\x48\xba\xf7\x9a\x68\x8d\xe1\x18\xf4\x47\x2c\x84\x10\xfe\x1b\xb5\x62\x75\x50\x40\x87\xf6\x70\x92\xdd\x53\x8b\x63\xc7\xa5\x3f\xd2\xbd\x98\xad\x30\xd8\xb6\xc6\x84\xe9\x1b\x72\x05\x41\xe5\x7b\x9d\x12\xdd\x5c\x27\x46\x38\x6e\x9a\x48\x0a\xbc\xb6\xd2\x5d\x5c\x4e\x2d\xa6\x29\x6c\xbc\x06\x60\x51\xf1\xe5\xd6\xd9\xed\x7e\x9d\xcd\xe7\x68\x47\x18\xe6\xfb\x35\x87\x30\x2d\xa5\x50\x1d\xb0\x76\x78\xb6\x84\x38\x41\x29\xe7\x84\x84\x4e\xcb\x16\xe7\xd4\xda\xf5\x35\x22\x84\x43\x65\x2a\x9b\xf9\x78\x87\x33\x24\x82\xb0\x41\xd4\x17\xb2\xf5\xb6\xbd\x7b\xdd\xd1\x18\x45\x07\xb7\xf8\x2f\x14\xf1\xf5\x5c\x67\xb7\xa9\xec\xcc\x96\x57\xa5\x94\x47\x76\xba\xf2\xc8\xac\xdb\x8a\xbb\xa1\xe2\xd3\x40\x37\xfa\x0e\xef\x20\xee\x93\x5d\x95\xa1\x5b\xda\xbf\xb2\x07\x9a\xfd\x58\x66\x3c\x8f\x7a\x16\x89\xc8\x39\xf0\xfa\x7b\xa5\x9a\xce\x96\xed\x15\x85\xf8\x00\x77\xbd\x48\x55\x43\x29\x7f\x3f\x0f\x61\x86\x19\x09\x06\x9e\xbd\x91\x43\x71\x4c\x96\x6b\x19\xdf\x26\x92\x1a\x97\xf1\x7c\x8e\xc2\xa6\x59\xcd\x74\x97\xda\x40\xcc\x64\x8c\xe6\xb0\xbf\x73\x11\x31\x2c\x1a\x84\x86\xb5\xc2\xc1\x08\xa3\xb1\x76\x2e\x02\x4d\x1c\x5e\x54\x5b\x9b\x41\x1d\x03\xad\x5a\x2d\x62\x13\xd5\xed\xe7\x74\x75\xa7\xe9\x78\xb5\x6a\x82\x7e\xa3\xd8\xb8\x7d\xb6\x7a\x71\x7b\xf3\xec\xf9\x0b\x43\x38\x90\x3d\xa3\x7f\x3a\x72\x46\x0a\x8e\xe9\x50\x29\x05\xf0\xd6\x07\x34\xda\x85\xf3\x9d\xb1\x72\x8b\x98\x3d\xdd\x1d\xfe\x6a\xf8\x41\x98\x88\x8a\x50\x01\x16\x45\x42\xb8\x0c\xaa\x4c\x5b\xbe\xa3\x72\x8e\x42\xa5\x4f\xdb\x78\x1c\x74\xee\x2b\x6a\xc5\x5e\xe4\xe3\xc4\x8b\x7c\x68\x3f\x00\x57\xb4\x48\x08\x91\xe3\xa6\x11\xa5\x41\x27\x4d\x54\x78\xa1\xa2\xbf\x0e\x2a\x82\xeb\x29\x38\x89\xb6\xbd\x23\x0b\xe8\x91\xb6\x39\x13\x2d\xd8\x4f\x41\xad\x04\xcf\x52\xd3\x04\x15\x48\x6d\x49\xb7\xc2\x24\x24\x3f\x33\xec\xd2\x03\x8d\x45\xa0\x64\x3d\xa0\xcf\x01\x18\x3b\xbe\xc3\x0a\x41\xef\x59\xc0\x63\x1a\x5b\x3f\x82\xcd\x3e\x78\xa1\x0e\xbd\x9f\x7b\xe3\x58\xf8\xa4\x8e\xb8\xde\xaa\x5a\x7d\x61\x5e\xe4\xbb\x23\x92\x0b\xe2\x82\x0d\xef\xed\x40\x3f\x46\xdd\xdb\xad\xf5\x06\x24\x6d\xd7\x86\xde\x2f\x9a\x3d\xb5\xa5\xbf\x2a\xf2\xef\x9c\x3a\x8f\x20\x82\xca\xa4\xa3\xd4\x8e\xd8\xd6\x4c\xe1\x3e\x98\x11\x4d\x04\x02\x96\x79\xc6\x86\x80\xf4\xdc\x70\x9b\xba\x22\x5a\x85\xd0\x3f\x96\x4a\xcb\x10\x22\x19\x9d\x51\xa8\x2b\x79\xc9\x31\x86\xdf\xd1\xb7\xcf\xc6\x9f\x9a\x46\x48\xed\x74\x15\x40\xda\x5b\x03\xd2\x33\xdb\x28\xd4\x62\xa1\x88\x36\xa1\xa7\xfd\x37\x3a\x62\x84\x06\xc3\x93\x64\xd1\xa8\xf9\xd5\xc4\xb7\xcf\xc6\x9f\x14\xfd\xf6\x65\x37\xb1\xeb\xa1\x3e\x1c\x15\x92\xf3\x43\xc9\xfe\x9f\xe8\x5a\x9a\x57\xac\xac\x3f\x07\xb1\x30\xc7\x59\x03\xbf\xb0\xbc\xa3\x42\x62\xfc\x6f\xf7\x13\x5a\xd6\x11\xf8\xe8\xc3\xb8\x61\xa1\x35\xcf\x97\x2c\xae\x87\xf2\xf2\xff\x6b\xcd\x0d\x22\x8c\xf0\xa6\xcf\xbc\x55\x76\xce\xc4\x21\x88\x81\x3c\xc9\x84\x38\xcc\x0b\x7c\x04\x21\x0d\xc6\xa1\x49\xac\xd1\x51\x46\x21\x1e\x01\x67\xb3\x07\xaa\xab\x43\x6e\x70\xe2\xf0\xd0\x4c\xa5\xa4\x74\xc5\x34\xa9\xf4\xf5\x41\x48\xe0\x52\x27\x10\xa3\xe0\x44\xc4\xa4\x4d\x10\xd0\x30\x03\xb3\x59\x7e\xbc\xfd\xc1\x1d\x2e\x40\x45\xda\x14\x82\x36\x88\xa0\xd9\x35\x03\xb9\xa1\x09\xf5\x59\xb8\x7d\xc5\xb1\xf4\xfa\x9b\x93\x5e\x2c\xa8\x69\xce\x5e\xd2\xde\xb1\xee\x6c\x4f\xbd\x4e\x89\x99\x7e\x48\x89\xd9\x47\x27\x4a\xc6\x2a\xca\x14\x81\xbb\x4a\xb8\x4e\x55\x3c\x85\x1c\x47\x28\xc6\xb1\x1a\x85\x27\x1b\x2f\x58\x20\x16\x4c\xd7\x3b\xe5\x3b\x85\x2c\x35\xab\xfc\x36\x90\x10\xa6\x90\x9c\xd8\xe1\x70\xbb\x75\x19\x1b\x49\xd2\x61\xe8\x4c\x54\xc9\x58\xbd\xce\x9a\xe8\x03\x90\xde\xf1\x2e\x23\xf0\x5e\xf7\xfa\xce\x72\x6b\xdf\x2e\xcf\x47\x06\x7b\x4c\xda\x16\xca\xbe\x48\x75\x72\x19\xcf\xa3\xc5\x54\x59\x3c\x0b\x51\x2b\x8c\xea\x6d\xe1\x18\xe2\xc9\x50\x68\x8b\x7f\x92\x8f\x06\xd6\xb7\x96\x63\x08\x7c\xa1\xbe\xbe\x84\xdd\x6c\xc0\xa6\x36\xd4\x04\xbc\xcc\x32\xc7\xd0\x26\x63\x42\xb4\x36\xf2\x02\x4d\x07\x06\x4d\x22\x54\x11\x78\xb2\x89\xbb\x40\x68\x8b\x15\x4e\xc8\x72\x9d\xdc\x92\x78\x9d\x70\x22\x13\xa2\x2d\xc6\x9a\x01\xac\xd8\x10\x9c\xec\x2a\x2d\xe6\x25\x3e\xf2\x02\xdf\x0a\x11\x56\x2a\x84\x11\x0e\x85\x03\xf8\xc1\xde\xd4\xfc\x3a\x47\xbd\x5f\x67\x4a\x6e\xde\xed\x69\x99\xa4\xf9\x0d\xfe\x66\x6c\x3b\xa9\xec\x25\xdd\xd9\xe1\x09\x09\xa3\xc9\xb9\xb2\x99\xfc\x96\x92\xf3\xd5\x1c\x85\xad\xe8\x18\xc4\x94\x3d\x6a\x61\x6a\x42\xbb\x38\xb0\x9c\x95\x20\x17\xa2\x48\xf4\xf6\x8b\x62\x7f\x38\xd6\x2c\x7a\x03\x66\x75\x01\x6a\xd7\xba\x32\x79\x47\xb1\x07\xe2\xe2\x31\x45\xa7\x54\x1a\x42\x85\x55\xf5\x96\x3d\xd5\xc4\x08\x8a\xa7\x45\x95\xfe\x96\xe6\x89\x13\x14\x65\xc4\xca\x45\x50\x3c\xad\x0f\x32\xd6\x9a\xa3\x02\xde\xad\xa5\xe5\x94\x03\xd6\x67\x6b\x31\x78\x87\x1e\xeb\x62\x2d\x8a\x39\xab\xc3\xd3\xfa\x40\xa3\x88\xd7\xc4\x9f\xeb\xe2\xe0\xac\xfe\x63\x0d\x81\xd1\x9c\x4f\x97\xff\x61\xe0\x54\xd7\xe5\x36\x70\x39\x54\x64\xdf\x4a\x57\xd4\x42\x6a\x32\x1c\x58\x8a\xd6\x21\x31\x56\xff\x61\x08\x45\xd0\xe2\x80\x13\x62\x3c\x3f\x08\xbb\x72\x5b\x74\xe6\x6b\x16\xd7\x98\x11\xe3\x13\xf5\x19\x5a\xc6\x6a\xc0\x22\x13\x18\xaa\x12\x03\xba\x13\x6b\x79\xb5\x54\xde\x2f\x9d\x57\xd8\x72\x3a\x1d\xfc\x70\xb6\x83\x28\xf1\xe7\xfa\xf5\xa0\x79\x8f\xd3\x0b\x09\xeb\xb4\x33\xb2\x53\x7d\x0a\x68\x78\x97\x94\xc5\x31\x8f\xbe\xc8\xd2\x03\x31\xa4\xd3\x74\xbe\x02\x7c\xb6\x86\x1a\xec\xd3\x45\x0c\x5c\xc0\x2e\x2f\x81\x45\x80\xd9\x1a\xd6\x43\x08\x99\x6e\x0e\x6f\xcf\x41\x01\x16\x72\x29\xd7\xec\x3f\x0f\x4f\x6b\x11\xdd\xce\x59\xc2\x6a\x2e\xd7\x19\x8b\x6b\x67\xf1\xd9\x67\x9f\x7d\xa6\x2d\xf6\x52\x42\xc3\x02\x56\xfc\xa0\x01\x0f\x0d\xc0\xd9\x27\x33\xc4\x26\xeb\x96\x3a\xd5\xbc\x2a\x14\xf8\x74\x48\x9f\x58\xa6\xa2\xfb\x4d\x9c\xfd\x81\x05\x01\x08\x83\xe2\xe9\x0d\x00\xea\x0f\x2c\x4b\x2f\xf8\x8b\xe6\x59\x59\x8b\xa1\xc6\x6f\xfa\x35\xbd\x90\x33\xe6\x48\x59\xd4\xf5\x4d\x07\x43\x17\xf2\x26\x6d\x8b\x50\x6b\x69\x91\x1b\xbe\xa3\x97\xb8\x3c\x98\xd7\xde\x5e\x2b\x6c\x9a\x6f\x81\x6d\x0a\x41\x07\x1d\x36\xae\xd2\xc1\x00\x29\x90\x15\xa0\xa6\x09\xbd\xc0\xc7\x06\x87\xf0\x64\x20\xdd\x3f\xe7\x0b\x41\xab\x5a\x33\xa5\x45\x08\xcf\x0a\x7b\x3c\x66\x0b\x99\xe6\x37\xf2\x64\x4d\x90\x69\x7e\x4d\x55\x08\x2e\xd0\xea\xdf\xca\xfd\xc1\xc8\xd6\xde\xa7\xf9\xcf\xf0\x12\xf3\x17\xfa\x24\x5e\xfa\xef\xda\x57\x55\x8e\x24\x98\x8f\xe4\x51\xe6\x14\xdf\x22\xbd\x0c\xc3\x5a\xa9\x18\x69\x4a\x5e\x89\x9b\xcc\x0d\xc3\xd1\x22\x89\x7f\x3f\x90\xd3\x9e\x06\x3e\xa9\x7a\x4a\xc8\x92\x61\x6d\xa4\xa4\xb1\x96\x9e\xa0\x9c\x2e\x78\x07\x09\xd0\x05\xed\x7d\xb1\x77\xff\x01\x36\x19\x79\x91\xb3\x06\xa4\xc0\x96\x3b\x5b\x84\x1e\xa3\x3e\xb2\xe7\xe8\x06\xff\xc0\x93\x17\x8b\x1b\xfc\x86\x92\x53\x07\xc4\x46\x0f\xc5\x0f\x69\x95\x06\x69\x96\xd6\xef\x1d\x63\x9b\x46\x11\xcb\x0d\xac\xf0\xa2\x34\xcb\x6d\xf1\x5b\x4a\x4e\x19\xab\x6b\x56\xbe\x39\xd0\x90\x6f\x10\x63\x69\xe0\xb8\xc8\xeb\x9f\xc5\x66\x32\x3e\x59\x2e\x8d\x16\xff\x48\x89\x67\xfc\xcc\x82\xbb\xb4\x36\xb0\xf1\x4d\xf1\x9b\x81\x8d\x7d\x65\xf8\xf8\x27\x7a\x01\x83\x48\xb8\xea\x66\xed\x67\x2a\x59\x02\xca\xb9\xd2\x9f\x68\x6f\xf7\xa0\xbc\x37\x2d\x39\xcd\xf4\xe3\xe1\xa0\x68\xa6\xb9\x0a\x92\xb0\x42\x38\x24\x3f\xd2\x73\x67\x35\xe0\xe4\xf7\x47\xea\x85\xfe\x3c\xc0\xe3\x7a\xfb\x05\xfb\x85\xea\xea\x9f\x61\x05\xd7\xd1\x95\x47\x47\xde\xd4\x06\x49\xe4\x67\xe1\x7c\x88\x22\x1c\xf4\x35\xfd\x93\x8e\x82\xb3\x29\x5d\xe6\x3e\x3a\x98\x0b\xf1\x95\xf7\xf4\xc9\x5a\xe2\xc8\x7b\xee\x2f\xac\xb0\x69\x96\x08\xcd\xad\x08\x0c\xdc\xc1\x9a\xdd\xd1\xea\xfc\x2f\x3a\xa1\x97\x4d\x96\xd2\x4a\x38\x24\x84\x58\x91\x2b\xd1\x9d\xe1\x28\x74\x69\x20\xf7\x13\xc7\x10\x81\x3c\xc1\x79\xc6\xca\x59\xae\xe3\xdb\x4f\xd6\xf1\x9c\x3c\x47\x86\x40\x72\xca\x0a\x3a\x99\x77\x5e\x06\xc2\x79\x08\x46\xd4\xb3\x25\xc4\x92\x88\x5c\xab\xab\x51\x65\x5e\xf4\x2e\x09\x24\xd6\x34\x86\x85\x54\xed\xb3\xf3\x02\xb2\x9b\x22\xff\xdc\xf8\x59\x04\x1a\x15\xe5\x90\xa3\x77\x64\xb2\xee\xfe\xeb\xec\xac\xe7\x1f\xae\x7b\x22\xe2\xff\xb3\x31\xca\x23\x02\xb1\xc5\x44\x22\x43\x86\xf8\xc9\xdc\x13\x12\x03\x6f\x0c\x1d\x02\x37\xf0\x6c\x85\xfb\x5b\x8d\x6f\x3a\x6b\x47\x37\x76\xac\x88\x24\xa6\x69\x15\xf6\x19\xba\xb7\x50\xd3\xc4\xbd\x5b\x08\xce\x82\x61\x83\x53\x20\x86\x34\xef\x89\x09\xf5\x0c\x71\x71\x6e\xcc\x83\x73\xe0\x0f\x3a\xe0\xf7\x79\x97\xc1\x11\xd8\xeb\xac\xa0\x35\x58\x4b\x2e\x71\x3c\x57\x80\xc3\x31\xec\x14\x80\x00\x40\xcd\x01\xde\x34\xb1\x61\x58\x55\xc2\x0f\xcd\xa9\xe0\x3b\xbe\x7e\xef\x9c\xce\xbd\xea\x81\x2c\x4d\x12\x7c\x30\x59\x86\xcc\xdc\xf1\x82\x60\x1e\x1f\xba\xc6\xca\x70\x42\xd0\x9b\xea\x5c\x33\x38\x27\x9a\xa7\x7b\xd0\x85\xf8\xaa\x66\x25\x3c\x80\xd6\xa9\x50\xd7\xcb\x8e\xfb\xfe\x35\x4e\xb3\xec\x3b\xd9\x0d\xfe\x9a\xb1\xa7\xbf\x94\xc5\xa3\x7a\x7e\xb3\x2d\xd3\xfc\x0e\xde\x7a\x8c\x34\x5b\xe2\x2c\xcd\xd9\x5f\xbb\xb7\xa2\xaf\x40\xd0\x04\xf0\x70\xd8\x52\xa1\xbd\xf0\x98\x46\xc5\x23\x3c\xfd\xf6\x15\x84\x84\xe2\x4f\x45\xb1\x07\x15\x3e\xb5\xe3\x9d\x93\x11\xf3\xc9\xe5\xf3\x57\x55\x30\xcf\x46\x8b\x61\xe9\x26\xae\x89\xc5\x7d\xef\xc7\x23\xc9\xe6\x7f\x8e\xde\xe5\xd2\x6b\x8e\x3b\xf0\x76\xec\x6d\x2f\x25\x3f\x74\x27\x1d\x68\xe5\x0e\x4e\xe3\x14\xf0\xd2\x2f\xd4\xda\x22\xe1\x68\x58\x2d\x1e\xb8\xbf\xd0\x5e\xb7\x9a\x61\x73\xe8\x26\xa6\x69\x24\xac\x36\xd2\xfc\x2a\xd1\xf4\x17\x2c\x46\x12\xe9\x51\x68\xb6\xc2\x11\x42\x2e\x73\x76\x5e\xe0\x3b\x56\xdc\xd9\xb1\x69\xce\xde\x00\x4a\x59\x87\xe2\x42\x84\x4c\x53\x44\xd2\xb3\x42\x12\x77\x3b\x28\x26\x46\x0e\xeb\x6e\x20\x2c\x98\x7f\x4e\xfe\x4b\x5c\xa2\x92\x64\x6d\xe1\x1c\x5c\xd8\x9f\x3b\xfa\xd8\xf6\x8e\x3e\xd0\x39\x8d\xd8\x34\x86\xbc\x9f\x02\x35\x8c\xde\x15\x59\x4f\x23\x1a\x9c\xce\xe0\x83\x21\x46\x9a\x6f\x59\x99\x82\x8c\xd6\x34\x8d\x6a\x34\x0f\x04\xe4\xa9\x89\xf4\x54\xc7\x57\x13\xac\xc2\xdc\x1d\xff\xd2\xe9\x9a\x42\x9c\x07\xa8\x2e\xec\x68\x01\x24\x80\x7c\x02\x1c\xfe\xe0\xfa\xfe\x77\x56\x75\xb8\x94\xfa\x0a\x2e\x71\xdf\xb5\xce\xdd\x86\x44\x6c\x11\x02\x47\x1c\xe5\x9e\x66\xd2\x15\x07\xf8\x74\x7c\x4b\x21\xd3\x5b\x2a\xb0\x11\xec\xe0\xa6\x09\x5d\x6b\x80\x5e\x98\xbc\xbc\x5f\x36\x4d\x5a\xbd\x4e\xf3\xb4\x66\x80\xec\x9a\x66\xe9\x08\xaf\xe2\x1d\xd3\xed\x19\x82\xe4\x36\xb0\x3c\x89\xfc\x33\xe6\x58\x1b\x1b\x19\x23\x1a\xb5\x97\x94\x67\xb5\xd9\x3f\xe4\x5c\x9d\xbb\xc4\xe1\x27\x31\x70\x5a\xa0\x7f\xf4\x03\x0b\xeb\xaa\x8b\xa7\xc6\x77\x5a\xc2\xea\xcf\x39\x1c\xa4\x79\xd2\x67\xb1\x90\x20\xf5\xdc\x67\x6a\x5a\x1c\xc6\x9f\xde\x68\xd1\x5a\x3b\x82\xad\xcb\xd3\xa2\x33\x67\xa7\x03\xcf\x37\x91\x69\x7e\x2b\xef\x15\x22\xd3\x94\x48\x38\xc2\x7f\xec\x1c\x89\x91\x66\x77\x9a\x9c\x6f\x30\xe9\xd2\xc6\x62\x3d\xad\x00\xda\xab\xea\x10\x01\x23\x49\xcd\xc1\x0d\x06\x8a\x24\xc4\x89\x12\xb9\xab\xf9\xd6\xf8\x4c\xf2\x3d\xb5\x0a\xfb\x9c\x77\xc0\x13\x38\x5f\xf4\xcc\xd2\xc0\x41\xa0\xff\xbe\xb6\x7e\x2d\x26\x27\x9c\x33\x5d\x0b\x98\xe5\x53\x5f\xc6\x59\xb6\x13\x33\xfe\xe1\x4a\x5a\x24\xce\x2e\x4d\xc4\x23\xf9\x78\xc3\xc0\x8a\x9b\x33\x0c\x2c\xf9\x40\x49\x0e\x9c\x4b\x67\x3a\x00\xa4\x73\x0e\x82\xe2\xa6\xa2\x5f\x5c\xfd\x5e\x10\x2e\x87\x4e\x2d\x47\x69\xe7\x06\xbe\xa1\x32\x48\xbb\x32\x90\xe3\x85\xfe\x3a\xba\xfd\x04\x2e\x8f\x98\x47\x39\x49\x12\xf9\xbc\xfe\xd8\x8b\xfc\xa6\x89\xbd\x68\xf1\x1c\x7e\x97\x9a\x43\xa5\x16\x7f\xdd\xc9\x0e\x15\xfe\xeb\xbb\xc6\xf1\x0f\xf9\x27\x78\xea\x1e\x5c\x9c\x8c\x51\xce\x65\x41\xe8\x88\xbd\xe3\x23\xe1\x74\x64\x1a\x5b\x63\x5f\xb0\x62\xcc\x91\xa4\x87\x58\x6f\xaa\x97\xdc\x32\x10\x48\xc5\x5e\xe0\x25\xbe\xdf\x43\x9a\x97\xf8\xe2\xd0\x50\xc3\x89\xdb\xb1\x7b\xd5\xd0\xd5\x1d\x26\x85\xc8\xe9\xc1\xb4\x05\x4d\xaa\x73\x0f\x88\xc3\xe0\x82\xbf\x0e\x08\x61\xa5\xcc\xc7\x1e\xaf\x7e\xa5\xbd\xc2\x2d\x04\x9a\xd5\xf2\xb5\xa5\xfd\xf6\x91\xb1\x9c\xfc\x4a\xb1\x9e\x6f\xa8\x98\xfb\x2b\xc5\xbc\xdc\x84\x25\x24\x8e\x95\xbf\xe6\x8c\xed\x95\x5e\xf5\xa1\x2c\x0e\x24\x54\x4a\x4b\x55\x9a\x27\x04\x2e\x2a\xc5\x73\xef\x84\x42\xe8\x4d\x81\x73\x94\x8a\x04\x4a\x1d\x94\x96\xb5\xba\xcc\x78\x24\x4a\xd7\x59\x69\x8b\xb2\x3c\x22\x91\x78\x04\x9f\x4f\xf1\xe8\x24\x0c\xfb\x93\xb0\xc5\xe1\xb1\x3c\x17\xbe\x8a\x51\x1e\x04\xe4\x74\xdd\xed\xe0\x8c\x4a\x74\x28\xbc\xa9\xc8\x4b\x2e\xbd\x4c\xd7\xfd\x3e\xbd\xc5\xe5\x71\x22\x1e\x02\x0e\x7f\xaf\x31\x7d\x02\xec\xe8\x28\x88\x3d\x19\x5c\xb2\xa8\x08\x58\xdb\xc1\x9c\x79\xda\x5c\xfa\xea\x4e\x63\x5c\xf0\x9a\xe2\x25\x5e\x4d\xa7\xc9\x8b\x3a\x51\xab\xba\x13\x29\x1e\x89\xa5\x66\x75\xd1\xcf\x3e\xba\x0e\xe6\xfd\xdb\xb0\xbe\xaa\x66\x07\x29\x0f\xd7\x3f\xf5\xaa\x20\xc2\xcc\x4b\xd5\xaf\x42\xba\x9a\x26\x38\x91\x70\xc3\xce\xbf\xe7\xa5\x49\xed\xd2\x85\xc3\xfd\x16\x9f\x41\xaf\x06\xa4\x7a\x1a\xd6\xeb\x23\xa7\xce\x56\x62\x74\x6a\xca\xb5\xe9\xbc\x05\x00\xd1\xc9\xfb\xac\x5d\xa7\x29\x15\x57\xfe\xd9\x13\xb5\xfa\xca\xb1\x81\xcc\x2c\x0e\x14\x99\xe6\x0e\xb3\x3a\x8a\x19\xb6\xc4\x77\x2c\xbe\x83\x92\x45\x60\x9a\x82\x8d\xe1\x94\x98\x1b\x38\xcb\xb3\xd3\x12\x44\xe2\x4f\x30\xab\x5d\xfd\x67\x5f\x2c\x8a\x9c\x8b\x5d\x1f\x75\x52\xe7\xcb\x45\x69\x1f\x3c\x39\xf7\xe8\x73\x72\x14\x40\x8b\x3f\x3a\x1d\x52\x1a\x0c\x05\xd2\xe6\x10\x0b\x0f\xec\x3e\x06\x93\x6f\x57\xe0\xc8\xff\x6d\x71\x20\x13\x9f\xe1\x48\x3d\x8d\xc7\x3c\x1a\x08\xdf\x84\xf0\x61\xa0\x17\x32\xd5\x41\xa5\x2e\x0e\x58\xe6\xc4\x39\x1b\x3a\xad\xcd\xd1\xe2\xea\x91\x9f\x79\xe7\x69\xf6\xa7\x0b\x10\x3a\x84\x45\x65\xd1\x6b\x78\xfc\xfe\x2b\x74\xf3\x5c\x33\xb8\x31\xa0\xac\x01\xd1\xda\x9f\xc8\x19\x48\xe2\x6e\x81\xc8\x49\xf8\xc3\xa6\x01\x0e\x02\x1c\x06\xc2\x97\x88\x70\x10\xd6\x54\xdb\xe2\xb1\xd9\xa6\x11\x43\xcf\x6e\x70\x14\x90\x9b\xde\x0f\xe4\x33\xcd\x57\x08\x0b\x2c\x74\x0a\x02\x70\x6c\x27\x24\x4f\x5d\xd0\xc4\x92\xdd\x1f\x59\x55\xbf\x54\x1c\xe2\xeb\x52\x38\x7e\x9a\xfc\x6e\xb1\x00\x39\x83\x68\x0a\x2c\x10\x3d\x05\x45\xe7\x07\x9a\x21\xf1\x5a\x83\x89\x91\xa6\x9e\x16\x07\x3a\x99\x31\x1d\x80\x83\x2a\x65\xd5\x16\x61\xca\x01\x1e\xcc\x41\xfa\x3a\x92\xe0\x3c\xac\xf2\x49\x8a\x98\xa9\xd0\x12\x0c\xa4\xdc\x45\x90\x02\xe4\xf9\x22\x40\x21\x01\x5a\x00\x33\x4f\x49\x49\xe6\xa1\x4f\x98\xa7\x89\x3b\x7c\x42\xb5\x50\xb7\x16\xb3\x25\x03\x4b\x98\x94\x4c\xf2\x33\xb9\xef\xc7\x36\x98\x52\x60\xb2\xee\x02\xbb\xe6\x07\x1f\x2b\x05\xdf\xe0\xf9\xc8\x0e\x8b\x3c\xa4\xf5\x20\xc9\xb8\x36\x40\x7e\xb0\xc4\x49\x77\xfd\xd4\x39\x9e\x03\xdf\xe0\xcc\x8b\x7d\x81\xfe\x42\x7e\x48\x77\x8a\x74\x91\xe6\xa8\x2f\x98\x14\x1e\x77\xfa\x7d\x92\xfa\x4f\x41\x92\xa6\x78\x02\xfe\x86\xf7\x42\x63\x3c\xe7\xc4\x48\xa1\xd8\x5b\x7c\x18\xf0\xc9\x11\x50\x21\x9d\x73\x10\x6c\xc4\x4f\x1c\xd0\xc0\xf7\x0f\x00\x98\x14\x21\x0f\x1d\xfe\x82\xc7\x62\x2c\xd0\x45\x62\x1f\x73\x48\x8c\x4c\xd3\xea\x5f\xc8\x12\x6f\x49\xa2\xb9\xe2\xc5\xfa\x8b\xee\x31\xb5\x2f\xd3\x34\x5b\x8b\xd3\x60\xfd\x97\xf9\x1c\xef\x6d\x11\x78\x4e\x07\x9f\xa9\x6f\x7d\xa1\xc5\x02\xf7\x7e\x8c\xa1\xab\x72\xee\x9b\x26\x19\xfa\x06\x46\xad\xf4\x08\x28\x63\x20\x40\xec\xfb\x80\x83\x50\x18\x28\x07\x17\x40\x9c\x4b\x41\x32\x24\x09\x4f\x95\x62\x57\x02\x87\x07\xce\x65\xac\x83\x6b\xf0\xdd\x69\x38\x86\x98\x40\x61\xc0\x07\xcf\x33\xc2\x49\x98\xd9\xbd\x66\xfc\x75\xef\x45\x3e\x0a\x8b\xbc\x4e\xf3\x23\x5b\x1f\xc8\x6c\xd9\xe6\x5e\xe4\x93\x7b\xd3\xbc\x07\x32\xb6\xa7\xe7\x22\xd4\xa6\xb1\x95\x92\x09\xff\xf9\x38\x6d\x9a\xb3\xcf\x39\x42\xa7\x6c\xec\x8a\xde\x34\xad\xd0\x2e\x1e\x58\x19\x67\xc5\x23\xf1\x8a\xee\x19\xf7\x8f\xbf\x68\xcf\xff\xf4\xf1\x0e\x3a\xd3\x79\x77\x14\xab\xbd\x03\xc5\xc7\x0e\x5a\x7a\x1e\x11\x2c\xef\xc7\x9c\x63\xef\x91\xf2\x8e\x97\x73\xef\xc8\xce\xb1\x52\x0a\xae\xde\x20\x48\xc9\xb9\x3f\xd7\xdd\x74\x45\xa2\x10\x42\x08\x5b\x46\x9a\x73\x4c\x0d\xb5\x36\x8d\x7c\x5b\x08\xa1\xba\x68\x49\x1c\xc1\xbb\x49\x47\xaf\x42\xd2\xc4\x19\xbb\x14\xfc\x37\x40\xc8\x26\x0d\x8c\x8a\xce\xf3\xe3\xae\x45\xda\xa0\xef\x48\x97\x82\x77\xa4\x1f\x17\xa7\x18\xef\x40\x70\xd2\x79\xb0\x1c\xf4\x08\xf4\x3e\xd5\xac\x82\xb8\xb2\x5b\x85\xee\x66\x60\x0a\x9c\xb5\x7c\x7d\x79\x6f\xe9\xeb\xeb\xa5\xa7\xac\xf4\x94\x7f\xea\x29\xcf\xfd\x16\x21\x9c\x92\xd9\xaa\x07\xf5\x1c\xf1\xd1\xdf\xbb\xaa\x0b\x69\x7e\x75\x6f\x9a\xd6\x81\xdc\xcb\x43\x03\x39\xf7\xba\x87\x71\x85\x16\xf0\x49\xdd\x62\xf0\xd9\x89\x4d\xd3\x52\x05\xc8\xec\x80\xfe\x3f\xe2\xde\xb5\xc9\x6d\x63\x49\x13\xfe\xfe\x46\xbc\xff\x81\xac\xd5\x22\x50\x62\x35\x9b\x2d\x3b\x36\x66\x40\x97\x11\xb2\x2c\x1f\xfb\x1c\xc9\xf2\xb1\xe4\x63\x6f\x40\x18\x07\x0a\x17\x12\x6c\x92\xa0\x40\xf6\xcd\x0d\xfe\xf7\x8d\xca\xac\x2b\x80\x96\x3d\x33\xb1\xb1\x1f\xa4\x26\x0a\x40\x01\xa8\x4b\x56\x66\x56\xe6\xf3\xb0\x43\x10\x38\xbd\x3b\x6c\xdc\x43\xd7\xa9\x8e\x64\x2e\x86\x84\x91\x39\xce\xfb\x39\xe3\x9f\xc9\x99\x41\xf1\x23\xd6\x22\x3c\xc4\x72\x86\x44\x0b\x56\xb0\x1d\x65\x70\xf9\x27\xf9\x31\x72\xfa\xd4\x4a\xed\x3c\xc0\xde\xa9\xd4\xf7\x75\x89\xfa\xcb\x17\x5e\xa0\xf7\x46\x8c\xc4\xbc\xc3\x6b\xe4\x98\x9d\x01\x52\xda\xf5\x2b\x01\x13\x99\x92\x03\x00\x39\xe8\xdb\x77\x15\xc5\x18\x63\xd9\x1f\x78\x01\x97\x86\x28\x65\xb9\x22\xed\x01\x28\xd6\x8a\x19\x8e\x8d\x3c\xed\xf9\xa1\x0a\x74\x3c\xa1\xad\x0c\xbe\x27\xfa\x58\x49\x49\x0a\x05\x61\x45\xed\xbd\x45\x6a\x5f\xb5\xa2\xf8\xc6\x5d\x17\xaa\xa7\xe6\x29\x03\xfa\xe7\x52\x81\x7e\x08\x00\x81\xb5\xdf\x7e\x3d\x5c\x58\x60\xa5\xba\x06\x0c\x05\x0c\x93\x71\x30\xae\x5d\x1c\xec\x91\xf1\xaa\x41\x46\x40\xcb\x3a\x53\x9f\x11\x5a\xca\x55\xed\x67\xc2\x51\xa8\xf6\x9d\x44\xd7\x55\xb0\x69\xcb\x9d\x9d\x9b\x0d\x76\x95\x54\x1b\x66\x1b\x63\x84\x5c\x20\x22\xfd\xa5\x2d\x01\x4f\x3c\xbf\xba\x28\xa4\xa9\xcd\x6a\xbe\xc1\x95\xf7\x68\x0d\xea\x1a\x0c\x6a\x5d\x9e\xac\xd2\x79\x7b\xb3\x0f\xad\x13\x68\xed\x50\x08\x86\x19\x4b\x36\xac\x62\xb2\x43\xaa\xaf\xae\x82\xa0\x8e\xf3\x48\x0a\x89\xe1\x45\x57\x4c\xf6\xe8\xda\x03\xf9\xce\x00\xbf\x80\x4d\xaf\x80\x58\x7a\x6d\xa0\xb6\x11\x71\x20\x63\x07\xf0\x74\xbb\xd9\x07\x82\xb2\xe6\x70\x72\xca\xa6\x0b\xf6\xa8\x82\x50\x5f\x83\x4a\x1a\x3d\x9e\x19\x2a\xa7\xd1\xc0\xfe\x3d\xb3\x9c\x32\x9d\x6a\xa9\x7c\xa7\x75\x79\x8c\x84\x29\x7c\x87\x26\x56\x94\x33\xd3\x9c\x91\x69\x70\xdd\x86\x51\x6e\x9a\x93\x61\x2b\x45\x49\xca\x14\xa4\xa2\x3c\x76\x19\x44\xcd\xd6\x9b\xb2\xfb\xc3\x8c\x6d\xa4\x25\x07\x3c\xeb\xea\xe7\xdc\xfb\x02\xd0\x8e\xd4\x09\xfc\x00\xd3\xf6\xa6\xb7\x14\xc4\x03\x2b\x30\xd3\x74\x84\x94\x77\xc1\x0a\x2e\xe2\x5e\xf7\x46\xe0\x5d\x29\xdd\x7c\x77\xcc\x1e\xe1\xd3\x85\x89\xe8\x32\x5d\x9f\x63\xd7\x5f\x39\x09\x32\xe1\x5f\xef\x58\x26\x52\x4a\xa3\xb5\x4b\x92\xa9\x8b\x95\xa5\x29\xd7\xbf\x0d\x98\x16\xf8\x16\x1b\x11\x5e\x8f\xb6\x08\xf5\x15\x40\x6f\xb2\x19\x65\x70\xc3\x32\xa6\x6f\x37\x3a\xa1\xcf\xf4\x05\xa9\xaf\x14\x62\xb7\x5c\xdd\x6c\x83\x96\x96\x7a\x32\x9c\xa0\x70\x29\x6f\xe5\xdb\xdd\x3f\xa8\x3b\xc1\x4d\x5d\x58\x76\xca\x5d\x76\x08\xaf\xd9\x1a\x10\x68\x7c\xd2\x54\xf5\x0d\x60\xdb\x07\x81\x7b\xa8\xd1\x88\x36\x94\x6d\x2c\xb9\xad\xba\x42\x1f\x2b\x8e\x5b\x55\x2a\x7f\xeb\x97\xd3\xd4\x6f\x8a\xf5\x56\x95\xca\xdf\x46\xbe\xa8\x32\x3c\x32\xf6\xc6\xae\x6c\x43\x33\x69\x6a\xa6\x67\x58\xb6\xaf\x77\xd1\x86\x21\x95\x80\xdb\x00\x72\xe5\xd8\x9c\xdb\xb9\x31\x70\x6c\x12\xd0\xb5\x60\x8f\x5a\x5d\x8f\x1e\xc9\x73\x12\x25\x23\x88\x2e\xca\x91\x64\x27\x45\x88\x04\x08\xca\x1b\x97\x85\xb9\xb2\x6f\x99\xdd\x93\x96\xd3\x33\x3f\xa7\x67\xa6\xaa\xef\xfb\x11\x3d\xbe\x60\x1a\x2b\x1e\x00\x34\x19\xa2\x8c\x5b\x56\xff\xa5\x1b\xd0\xb6\x80\xfc\xcf\x5e\x04\x7d\xce\xc1\xea\x71\x2d\x8f\x3c\xe5\xfe\x21\x82\x23\x79\x45\x86\x62\x43\x60\x98\xb1\x1a\x84\x51\x52\x8b\xd4\x1e\xf7\x09\x43\x62\x7f\x79\xd0\x75\x64\x34\xf2\x4f\xc0\xac\xd6\x51\x82\xc7\x43\x59\x16\x03\x3c\x07\x94\x25\x59\x10\x8c\x30\xcf\xb8\x82\x32\xa3\xd1\xa3\x1e\x2c\x51\xde\x75\xd3\x3c\x08\x44\x8f\x35\x13\x38\x7f\xad\x54\xcb\xb4\xdc\xc4\x4b\x35\xfb\x94\x03\xbb\x12\x04\xc2\x21\x67\xad\xee\xe7\x4d\x55\xc5\x85\x11\x86\x7c\x11\xe9\xfd\x33\x93\x68\x69\xcf\x82\x75\xad\x0f\xe4\xb2\x8b\x26\xbc\xfc\xca\xa3\x5b\x89\x53\x9c\xd8\xe2\x34\x1a\xbf\xc4\xc8\x76\xbd\x99\x57\xe0\xf8\x0d\x02\xf5\x63\x8a\x3b\x43\xa1\x3a\xe4\x68\x86\x15\xf3\x66\x5b\xf0\xc2\xcc\x27\x66\x7f\xfa\xa4\x2c\x9e\xf8\x68\xb6\x05\x95\x15\x37\xdb\xc2\xfa\xdf\x64\x65\xea\x91\x3d\x8e\x0d\x55\x4e\xcf\x52\x4c\x7b\x3e\xf2\x2a\x2b\xca\x0f\xcd\xd3\xf9\xbc\x08\xb6\x82\x41\xb7\x45\x46\x41\x0f\x37\x3b\xda\x6c\xa1\x31\xc9\xa5\xb2\x26\x15\x0b\x98\xa3\x65\x68\x36\xc8\xc5\x99\x65\x2a\x6d\x58\x9d\x7b\x6a\x13\x90\xf7\x0d\xa1\x0c\xb9\x6a\xa0\x71\x91\xe5\xba\xc7\x53\x83\x4a\xc8\x35\x02\xeb\x30\x7f\xc8\xb1\x8a\x2e\xc3\x52\x03\x48\x23\xc4\x4a\x55\xef\xeb\xe3\x9a\x50\x39\x78\x40\x8a\x86\xd3\x05\x3d\x5b\xbe\x55\x3c\xcf\x57\xac\xec\xba\x4a\xf5\x11\x60\x78\xd8\x0c\xdc\x95\xf2\xa5\x62\xd3\xaa\x8b\xd8\x8a\xf6\xd7\x3e\x6f\x8a\x8c\xa5\xdd\xcb\xcb\x97\x5a\x13\x44\x91\x2e\xc2\xdc\xbc\xcd\x28\xd7\x08\x66\x09\xbb\x7c\x23\x22\x08\x32\x95\x59\x7c\x1a\x65\x48\x19\x4f\x1e\xc6\x97\x98\x4a\x69\x64\x63\xce\x3d\x66\x12\x68\x79\x10\xd5\x47\xc8\x04\x35\xee\x6e\x5c\xb4\x11\xde\x49\xfe\x0f\xaf\x1e\x04\x05\x60\x47\x51\xcb\x4a\x08\x49\xa0\xab\x91\x0b\x8d\x61\x6e\x6f\xc2\x65\xdf\x64\x16\x95\x17\x17\x4b\x5a\xc9\x5b\xa4\x54\x56\xe9\x21\xc6\x31\x1b\x04\x70\x4a\x4f\x28\xa9\x30\x43\x81\x1c\x5d\xd8\xa9\x39\x65\x82\x4f\xaf\x58\xa5\xc1\xfd\x4a\x76\x45\xe9\x72\x2a\x82\x20\x97\x62\x67\x84\x7c\x06\x7b\x7e\xd4\x75\xa8\x9a\x37\x34\xd4\x2e\x9f\x6b\x53\x96\xbb\x6d\x25\xf5\xdd\x44\xb7\x2b\x49\x81\xcb\xc2\x6f\xe6\xd4\x6f\xe7\x22\x2e\xac\x76\x04\xa6\x81\x1e\x93\xc0\x14\xea\x31\xf8\xc8\xce\x05\xac\x6b\x6c\x57\xfc\xeb\x64\x65\x4a\x0b\x4e\xd8\x46\x15\xd8\xa8\x02\x1b\x55\xa5\x8c\xc8\xb6\x14\xa9\x19\xe9\x72\x8c\x41\x81\x6d\x4b\x59\x8b\x69\x47\x01\xed\x88\xce\xbb\xc5\x52\x7c\xb5\x82\xc4\x88\x22\x11\x69\x10\xc8\xff\xd5\xcb\x7a\x07\x8e\x70\xd2\xc3\x5d\x7f\xd4\x99\x7a\xdb\xe1\xca\x23\xc3\xd0\xe7\xc2\xd0\x1b\xd3\xdf\x14\xd7\x64\x46\xd5\x3e\x11\xe9\x52\xfd\x75\x57\x26\x6f\xff\x0b\xfd\xe1\x5d\x37\x46\xc5\x90\x8f\x07\x10\xe2\xf4\xd6\x62\x6c\x25\x42\x01\x2d\x89\x15\xbb\x31\xf3\xc7\x6d\x5d\x94\xdf\x36\x77\xfb\x68\x25\x94\x9f\x88\x32\x28\xfc\xe5\x00\x45\xf0\xfe\xaa\xe8\x03\x92\x44\xc8\x62\xf5\x99\x94\x49\xc1\xfb\xc3\xde\x86\x12\x61\x1d\x67\x28\x7f\x77\x73\x72\x4e\x40\x4d\x78\x42\x55\x64\xcf\xa9\xea\xce\x7f\x1e\x5a\x3f\x94\xea\xfa\x2b\x85\x16\xd1\xf0\x79\x38\x1a\x79\x92\x5a\xff\x70\x5f\xe8\x42\x9e\x0c\x6c\xa6\xe3\xc5\x30\x26\xac\x1f\x78\x29\xbe\xca\xcd\xb8\x9b\xcd\x68\xc6\x21\xe4\x35\x0b\x55\xf0\x2b\x4e\xdb\xdc\x0c\xab\x8b\x0b\x76\x45\x97\xb9\xf1\xf2\x29\x87\x7a\x73\x08\xc1\xbb\xac\x3c\xcd\x8e\xfa\xe8\x23\x3b\xab\x97\xd0\x2a\x8b\xf6\xc7\x67\x2d\x20\xef\x78\x3e\x6f\x7e\xf5\x85\x73\xda\xfd\x2c\x01\x71\x8c\x28\x14\x45\x48\xf5\x8d\xa0\x7a\x7b\x97\x61\x84\x38\x73\xd6\x7d\xfe\x78\xdc\x36\x77\xd1\xff\x5a\x2c\x58\x95\x1d\x4f\xd1\x8b\xc5\xc2\x6e\x1e\x7c\xb9\x58\xa8\x05\xb7\x28\xb7\xd9\x43\x8f\x6e\xdb\xf0\xc8\xc9\xea\x62\x57\xdd\x90\x86\x97\x88\x04\x52\xed\x80\x34\x77\x04\xbc\x43\x43\xef\xac\x9f\x9e\xb3\x3e\x97\x1a\x6e\x31\x78\xff\x0c\xe3\x83\xcc\x9e\x80\x82\x77\xeb\xef\x93\x3e\x85\x28\xcf\xc4\xf0\x14\x62\x67\x10\x24\x38\xfd\x2c\x60\x3d\x6e\x1a\x12\x4a\x97\x0a\xdc\xc0\xe2\xa3\x69\xec\xf8\x77\x7b\x4e\x10\xe5\x10\x00\xe8\x58\x23\xed\x00\xc4\xab\x2e\x0b\x9e\x2b\xa0\x8e\xb2\x60\x9f\x79\x47\x75\x2f\x27\x27\xa2\x51\x4f\x14\xe4\x3d\x6b\xe6\xf0\xe3\x5f\xfa\x3c\x37\x4f\xd2\x00\xf1\x5b\xc1\x76\x82\x2b\xd8\xe4\xec\x74\x6a\xbf\x87\x6c\xce\xa5\xa7\x33\xc9\xf2\xcf\x06\x16\xe0\xad\x4f\xee\xdc\x33\x0b\xe7\xf0\x9f\x20\x4d\xb3\x37\x3d\xc5\x5b\x38\x78\x2f\xdf\x3b\x64\xdd\xc9\x72\x15\xff\x02\xc9\x97\xfe\x0d\xff\xbc\x90\x7f\xe8\x00\xac\x9b\x7b\xb4\x23\x06\x7f\x22\x06\x6b\xf4\xa0\xa3\x15\x42\x85\xbb\xee\xa5\x23\x77\x5d\x28\x75\x3a\x68\x43\x8c\x62\xea\xa5\x75\xc1\xee\xbd\x03\x4f\x2d\x85\xb4\x8e\xf7\x8a\xb7\x22\x32\xe0\xef\x4e\x98\x04\x8a\x74\x9e\x63\x7c\xb8\xd7\x26\x40\x13\x5c\xda\xb0\xb5\xd2\x0d\xdf\x2b\x78\x69\xc2\xd6\x04\xa5\x71\x11\x85\x99\xcf\x6c\x20\x58\x3e\x23\x72\x14\x63\x25\x2b\x53\x89\x82\xf8\x80\x2a\x34\xb1\x23\x54\x50\x70\x05\xab\x9e\xe9\xc7\x2b\xfe\x74\x05\x87\x1f\x6b\x3e\x5e\x48\xb8\xd2\xcd\x10\x21\xba\xf7\x63\x9f\x13\x1a\xbc\x6c\x53\x77\x80\x06\x81\x1a\xb6\xc8\xa9\x08\x98\x26\x1a\x25\x50\x2d\x84\x6a\xf0\x2e\xdd\xed\xba\x01\xdf\x83\xe2\xa1\xd4\xd3\x42\xaa\x47\x88\xd6\x37\x36\x08\xfb\xbb\x76\x42\xea\xca\xc6\x96\x95\xca\xdf\x80\x25\x57\xc5\x94\xf3\x12\xb1\x69\x87\x60\x25\x39\x0c\xd3\xad\xe8\xef\xfc\x32\x5f\x06\x82\xaa\xdd\xeb\xd2\x5c\x6d\x62\x3a\x95\xa1\x65\x6e\x70\xc2\x86\x43\x08\xa9\xee\xd4\x4b\x5f\x7e\xbc\x9b\x5d\xae\xe8\xa8\x1a\xb1\x13\x2a\x6a\xd0\xf4\xe2\x12\x8a\x7c\x4b\xd7\x63\x8f\xeb\x8d\x61\x13\xb9\x2e\xb5\x50\x59\xdf\x2a\x65\xf0\x3f\xec\x2a\xa9\x90\x4e\x55\x4b\xbc\x02\x16\x04\x75\xbe\xa2\xac\xd4\x59\x66\x7b\xb5\x53\x8c\x70\x3c\x28\xe2\x3a\x8d\x2e\xd2\x21\x40\x17\x90\x38\x35\xea\xc2\xac\x93\x67\x64\x91\x2f\x97\x0e\x43\xe8\xd3\xbe\x5c\xc2\x1d\xfc\xcf\xcb\xa5\x1e\x82\xea\xe7\xe5\x92\x93\xa3\x91\x60\xf5\xdf\xd5\xf7\x49\x96\x76\x5d\x96\xf6\xe5\xd3\xe0\xfd\xfe\x6b\xf2\x69\xf2\x84\xb8\x11\xdc\xbe\x00\xac\x9f\x80\x0e\x60\x63\x70\x44\xea\xc9\x92\xbf\x2e\x2b\x32\x88\x1e\xfc\x8b\x72\x41\x5e\x0c\xc4\x94\x07\x3d\xdf\x33\x81\xc1\xd3\xe3\xd1\x28\x3d\x29\x42\x4e\x99\x80\x20\x5d\xe2\xf8\x3a\x21\xa6\xf0\x87\xfd\x49\xaa\xe0\x0b\x1a\xed\x85\xc6\xaa\xd1\xc8\x36\xb4\xeb\x9a\x61\x21\xa0\x68\xb5\x65\x15\x2f\xa2\x8b\x2b\x39\xe5\x55\xeb\x44\x8f\xa4\x6a\x5a\x12\x91\xf5\x69\xb7\xfd\xae\x69\x09\x23\xf9\x36\x3b\x1e\x49\x84\x7f\xe5\xcd\x44\x76\x9d\xb7\xfc\x82\xbc\x76\x22\x3a\xf4\xaa\xfc\xc4\x67\x65\x5e\xde\xaa\xd9\xb3\x17\x5e\x58\x87\x47\x87\xa7\x6b\x84\xd6\x62\xa8\x67\xf5\x63\x45\x46\xea\x16\x80\x1b\xed\xdf\xfc\x57\x9f\xd2\x33\x41\x54\x4f\x11\x46\xda\x32\x2b\xde\xed\xb7\x0f\x84\x91\x5d\x76\xff\x06\xa6\x88\x6c\xa6\x72\xbb\x55\xd9\x3e\xea\xe8\x27\x15\x9b\xc0\x48\xdb\xdc\xbd\x3f\x64\x7b\x59\xde\x6c\xd5\xaf\x9b\x63\xf9\x36\x3b\x10\x46\xaa\x36\xdb\x95\xdf\x60\x9e\x01\xd3\x79\x06\xaf\x0b\x04\xdc\x75\xcd\x1c\xb9\xd2\xeb\x41\x8c\x38\x08\xde\xa2\x09\x76\x9b\x1b\xf9\x77\x10\x6e\xb3\xb8\x94\xf3\xa6\xd1\x15\x26\xff\x84\x38\x11\x1a\x9f\x84\x87\x76\xe2\x2e\xee\x2a\x08\xce\x25\x06\x82\xc1\x41\xbb\x8e\x10\x9f\x41\x2f\x2b\x8a\x57\xf2\xdc\x58\xfc\x9b\x07\x0e\x0f\xce\xfe\x9e\xc7\x8f\x3e\x2d\x56\xa4\xe0\x52\x1c\x77\xfa\x11\x61\xe6\x21\xad\x7f\x12\x2a\xcd\x59\xc1\x0c\x8d\xe5\x9b\x67\xf4\x71\xd0\x26\x7a\xb1\x02\x79\x55\x2b\x22\xa9\x92\x7f\x12\x61\x2e\xed\x75\x29\x59\x72\x67\xd7\x9d\x4c\xc8\xec\x20\xc2\x92\xce\x64\xf3\x3d\xae\x1c\xee\x27\x91\xac\xe4\xed\x0e\xbb\xf7\x84\xcc\x2a\xb8\x0e\x92\xb2\x8b\x19\xc7\xa3\xe5\x9a\x1f\x44\x58\x50\x56\x4e\x39\x5f\xab\x68\xb8\x41\xeb\xb2\x35\x3d\x9f\x3d\xac\x00\x95\x9b\xfa\x7f\xb9\x7d\x9d\xa7\xfc\x49\x13\x4f\x07\xa9\xee\x9e\x31\x29\xc5\x97\xfe\x16\x42\xfe\xdf\x76\x0a\x1e\x8e\x75\xcd\xd7\x17\x57\xb4\xe0\x85\x81\xf7\x31\x67\xd8\x7f\xa7\xab\xd0\x0a\xef\x77\x95\xb3\x01\xa1\x3e\x7f\xf9\x14\x35\xa4\x70\x11\xbb\x78\x1e\x23\xa1\xb3\x33\xf8\x95\x63\xc2\xeb\x2d\x1a\xf5\xb7\x21\x46\xba\x3a\xb7\x5d\xed\xbc\xa5\xd7\xd5\xb9\xe9\x6a\x80\xc9\xa7\xe7\x27\xe8\x28\x71\xe0\xc1\xb0\xf3\x7b\x97\xe7\xf4\x11\xd5\x45\xf5\x28\x58\xcc\x47\xba\x58\xf0\x0a\x95\xc4\x72\xbe\xce\x8e\xf8\x26\x82\xc6\xa5\xf7\x5d\x52\x8d\xb7\x5f\x2e\xd4\xf6\xb7\x85\xaa\x0e\x02\xd3\x7e\x1a\x79\x8d\xdb\x0f\x08\x82\x5f\x2d\x8f\x3c\xf9\xfd\x77\xb3\xa0\xfd\xfe\x3b\x31\xc8\xc6\x47\x4f\xdc\x0d\x8a\x4c\x47\x8b\xae\xcb\x50\x2f\x25\x24\x72\x5d\xc9\x7e\xbd\x20\x19\x29\x42\x6f\xa8\xcf\x1a\x9f\xb1\x7c\xb1\x14\x5c\x0e\xb9\x4c\x0e\x39\x7f\xdc\x17\x6a\xdc\xf7\x47\x7b\xa8\x86\x3b\xcc\x06\x1c\xf2\x66\x5c\x0b\x18\xcf\x9a\x5a\x6c\x69\xc8\xc4\x94\x62\xd9\x0a\x7e\xf9\xb1\xbd\x5c\xf9\x5a\xe2\x6d\xb6\x7d\x4a\x9e\x68\x20\x90\x25\xa4\x69\x3d\x31\xdd\x0b\xde\x1b\x76\x63\x0e\x51\xa5\xd8\x95\xcb\x01\x62\x0d\x04\x58\x14\xb1\x3f\x00\xf5\x10\xbd\xcd\xb6\x21\xa5\x51\xc6\x34\x93\x58\xc9\x09\x89\x6c\x2a\x94\x9a\x2e\x65\x5c\xce\xe4\x09\x3f\x78\xa3\xc4\xe0\x0d\xdc\x0d\x2d\xc7\x80\x8c\x94\x47\x50\xf6\x66\x36\x23\xe4\x4c\x29\x93\xfa\xd7\x6d\xb6\x75\xa2\xb4\x15\xdf\x48\xbf\x78\x1c\x44\x30\x85\xa8\x5e\xa5\x46\x0a\x17\xf1\xd6\x8e\xc2\x92\x11\x30\xbd\x20\xd1\x0a\xea\x42\x4b\xac\xd4\x92\xd5\x82\xa8\xb8\x2f\x53\x8e\xbc\x49\xf9\xd9\xd7\x58\x0d\x5f\x23\xcc\xb9\x80\x71\x6b\x5f\x82\xc6\x79\x24\xcd\x35\xe5\x62\x19\xcd\xd7\xd0\xe2\xb1\x05\xae\x69\x45\xdf\x96\xcb\x76\xcb\x75\xb6\x8c\x33\x9c\x4c\x52\x24\x6c\xde\xfd\x35\x35\x57\xbd\x8c\x0b\x3c\x3c\x85\xa8\xe8\x83\x08\x15\xc8\x54\x46\xe9\xf9\xac\xd8\xad\x9e\xa8\x55\x0d\x5b\xcd\xc7\x7a\x04\xc1\xe3\xab\x82\x2b\xae\x5c\x54\x17\x86\x83\x1c\x42\xc6\xd7\x7c\x05\xee\x84\x08\x58\x3e\x56\x71\x35\xbb\x8a\x6c\x94\x27\xe4\x78\x54\x5f\x2d\xe2\x3a\x5a\xc5\x15\xc4\xa9\xd6\xb0\x5b\x5b\x57\x68\xea\xa6\x2c\xb4\xee\xa8\xae\x2b\x80\x0a\x34\x08\xa6\xb9\xe1\xe5\x08\x82\x70\x9a\xbb\x9a\xa7\x3e\xd1\x75\xd3\x6f\x42\xf7\x0c\x23\x9a\x5a\x96\x50\x0d\x4f\xd6\x86\xb9\x9a\x0e\x6c\x65\x86\xc7\x52\xf1\x60\x08\x83\xd6\xb7\x1e\x24\x5c\xb9\xe1\x50\x5e\xc3\xc8\x79\x71\x5d\xea\x3c\x16\x37\xa6\xd5\x92\xd5\x17\xbc\x94\x36\x6c\x58\x58\xf5\xde\x42\xce\xd8\x71\xa8\x6a\x45\x6e\x68\xca\x2a\x10\x43\xb0\x43\x05\x9c\x43\x0a\x0f\x01\x90\x8a\xbd\xce\xe0\x17\x57\x94\x55\xe7\xb3\xa7\x75\x2b\xdf\x9c\x75\x06\xf6\xb4\x61\x6f\x1a\xa6\x43\x27\x02\x34\xd8\x20\x4d\xc7\xa8\xb6\x1a\xc6\xd3\xf9\x8e\x30\xd3\x4d\x0b\x02\xf4\x7c\xb6\xee\x47\x30\x72\xfc\x27\x02\xe0\xc0\x93\xc2\x64\x80\xfd\xaa\x06\x76\x4c\x9a\x3d\x89\xb4\x77\x91\x2a\x89\x7c\x54\x16\xbc\xe2\xa8\x80\x3f\x9d\xa6\x93\x00\x02\x8a\x67\x97\x4b\x33\xb7\x14\xe2\x1c\x1b\xd2\x4b\xc8\x81\xef\x32\x3d\xaa\x70\x62\xe0\x21\xe3\x49\xd9\x75\x45\xca\x0e\x7c\x8b\x32\x56\x30\x05\x17\x1b\x23\x99\x52\x24\xd8\x27\xe7\x9c\xc1\x44\x86\x0b\x2c\x47\x90\x25\x11\x8b\x12\xe0\x50\x5a\xf3\x9a\x97\x5c\x56\xce\xa4\x71\x5e\xf6\xf2\x77\xdd\xe3\xe9\x51\x59\xa3\x87\xd9\x80\xe3\x4f\x0e\x94\x83\x55\xcd\xe6\xa0\x94\x05\x41\xf8\x89\x1f\x9c\x67\xb2\x03\xff\x34\xc7\xe0\x04\xca\x3e\x29\x1a\x33\xca\xae\xb9\x73\x6b\x84\xaa\xb6\x6c\xe9\xd9\x81\x09\x2e\x5c\x3e\x12\xe1\x71\x10\x1c\xd8\x90\x08\x33\x08\x80\x15\xa8\x3e\x7e\xc0\x57\xe3\x55\xfc\x22\xfa\x82\x39\x6d\xc0\x3f\x59\x4e\x3c\xe6\x12\x28\x71\xe7\xa2\x78\x94\x09\xed\xd3\x9f\x32\xa1\xa1\x3b\xc8\x90\x20\xa1\xc8\x66\x42\x31\x3d\x00\xa0\xac\x62\x8c\x80\xb4\x52\x2d\x83\x13\x91\x46\xee\x54\xce\x19\x38\x36\xf6\x03\xe6\xac\x03\xe2\x60\x55\x5d\x37\xdd\xeb\xd6\xef\x3a\xf3\x53\xed\x7f\x95\x2c\x57\xe4\x56\xe8\x81\xac\x82\x60\xba\x9f\x6b\xae\x16\x15\x78\xf1\x6b\xbd\x2f\x9a\x3b\x88\xa6\x86\xe8\x28\xbe\xf7\xd8\xe2\xba\xee\xc0\x74\x87\x6f\x66\x07\xb9\xcc\xad\xf9\xda\x11\x70\x74\xb9\x5e\xf6\x4a\x1a\x94\x64\x00\xba\xb3\x5e\xd6\x9c\xf3\xb0\xf4\x01\x50\xba\x0e\xd0\x3e\xf1\xba\xda\x05\x4b\xea\xba\x5a\x55\x85\x2f\xd6\x75\x19\x3d\x5b\x33\x20\x5c\xf3\x06\xed\x80\xcf\x11\x6f\xe1\x5c\xe0\xab\xaf\xaf\xe2\x4d\xb4\x37\x74\x77\xf2\x5b\x76\x9a\xae\x6c\xfd\x04\x57\x99\x66\xf6\x5b\x6b\x02\x35\x42\xd9\x2e\x08\x76\xaa\x4d\xd7\x2c\xa7\x6c\xc7\xaf\x83\x60\x9d\x5c\xa7\xce\x99\x20\xf8\x25\x5c\x53\x97\xfa\xca\xbb\xc5\x94\xe2\x9e\xf3\x90\x0c\xcb\xba\x84\xf0\xe5\x0f\xb2\x77\xc5\x08\x3b\x45\x48\x65\x4f\xeb\x5d\xa8\x20\xb0\xbf\xd5\xf3\x9a\xf9\x01\xf6\xd7\x72\xcd\x40\x37\xfd\x25\x2c\x69\xd7\x5d\xa3\x5b\xcd\x68\x77\x65\x72\x80\x66\xf4\x46\x01\x30\x19\x96\xf2\xd3\x6a\x60\xed\xbf\x4e\x61\x74\x5a\x32\x45\x33\xd7\xf9\x81\xc9\x1a\xc2\xb1\x53\x6a\xc0\x9b\x2a\x6a\xea\x71\x74\x1d\x15\x91\xc4\x13\x41\x15\x46\x48\x3a\xb3\x9c\xe5\x0c\xbd\xeb\x3d\xde\x8f\xc5\x99\x2e\x7b\xcf\x0f\x0b\x04\x70\x13\x74\x00\xb7\x39\x10\xb6\x7d\xd2\x99\x27\xc1\xd8\x75\xdd\xf2\x45\x4f\x1a\xe8\x50\x15\x7e\xaf\xa8\x3b\x9f\x8a\x4f\x93\x5a\xb7\x93\xcf\x3d\x19\xab\x33\x07\x98\x4f\xbb\x76\x12\xb9\x62\x4c\x60\xf9\x98\xa8\x15\x65\xa2\x17\x93\x49\x5b\x1e\xeb\x3f\xca\x09\x26\x5e\x4d\x80\x4a\x68\x52\x88\x2d\xfe\x00\x8a\x84\xa2\xb9\xdb\xe3\xaf\x9b\x03\xfe\x95\x46\xd8\xc4\xb0\x2a\x4c\x34\x91\xc2\xc4\x92\x2e\x4c\x2c\xd1\xc2\x04\xe9\x37\x26\xb8\xc2\x4f\x8e\x37\x62\x57\x9f\x26\xd7\xe5\x03\xd4\x7b\x5d\x3e\x1c\xda\xf2\x78\x94\x3f\x6e\x0e\x13\x87\x43\x99\x38\xd9\xc0\x63\xbb\xd6\xbe\x03\xde\xee\x10\x0c\x3c\xd6\x0b\xb4\x77\x61\x39\x54\x68\x7c\xb9\xa6\xb6\x51\xad\x36\xd2\xbd\x6b\xf9\x69\x9f\xe9\x5c\xfb\xad\x52\x4d\xb0\x9f\x1b\x0a\x10\x33\xe0\x15\x55\x8d\xcd\x49\xb3\xd7\x6c\x53\xf5\x7e\x92\xd9\x33\x98\xf1\x9a\xaf\xc3\x47\x24\xba\x32\xa4\x54\xc8\x49\xe5\x32\x48\x8d\x0d\x08\x7f\x7f\x5b\x89\x75\x35\x9e\x43\xc1\x0c\x1b\x90\x4f\xc8\x48\xcf\xcb\x01\x7b\x22\xea\x4b\x37\x87\x7e\x2e\xac\x42\x78\xec\x09\x5c\x34\x57\x6c\xe6\x40\xc1\x04\x5d\xca\x05\x7f\x48\xd5\x9a\xe1\x68\x64\xee\xb5\x2c\x2c\xbb\x6e\x41\x67\x57\x80\x32\x8b\x9c\x97\xff\xf5\x07\x5f\x5c\x2d\xcb\xd8\xab\xbe\xa4\x51\x58\x8c\xd2\x45\xd9\xb7\x51\x69\x09\xb2\x02\xb0\x54\x40\xed\x3a\x09\x9e\xcd\xb7\x4d\x8e\x81\xd2\x37\x26\x52\x81\xdd\x4a\x0b\x39\x96\x2a\x17\xb8\xd8\x7f\x7b\xfb\x66\x08\xdb\x07\xbe\x2f\xd1\x75\x83\x98\x2c\x9d\xf2\x0f\x9a\x20\xc0\x51\xe6\x1c\xc4\x51\x36\xff\xf6\xdd\xdb\x9f\x64\x85\x2d\xc5\x8a\xbf\x6b\x9b\xdd\x7b\xb8\x1d\xb4\xb1\xf2\xfe\x74\x79\xbf\xdb\x12\xaa\xb0\x26\x0b\xfa\xa8\xc9\xae\xcf\x16\x08\x70\x0a\x00\x62\x6a\x7f\xfb\xf8\xcd\xc3\x87\x6c\x25\x2d\xbf\x90\x40\x95\x6d\xd9\xb6\x4d\xeb\x24\x47\xb5\x73\x28\x09\xc9\x0f\xfb\xdb\x6c\x5b\x17\x93\xdf\xde\xbe\x89\x26\x64\x06\x94\x1f\xd0\x0c\x77\xf2\x6b\x93\x8f\xe9\xb3\x4b\x76\x0f\xae\x81\xf8\xe3\xfe\x72\xc5\x1e\x94\x52\x8a\x33\x58\x6d\x38\x75\xf5\x2e\x5b\x95\x5d\x5b\x1e\xcb\x53\x57\xd5\xdb\x12\x76\xa0\xfe\xf8\xec\x56\xd5\x75\xf9\xb0\x2a\xf7\xf4\xb2\xb6\xee\xe9\x97\xa2\x17\xe6\x37\x9a\x53\xaf\x26\x8b\x70\x10\x30\x59\x49\x1f\xf3\xae\xbb\xd3\xbb\x1a\x34\x2e\xc2\x4c\x8e\x00\x59\xe3\x8c\x24\x64\x36\x64\xe6\x30\xbb\x32\x65\x2c\x22\x22\x95\xad\x94\xb0\x52\x83\xd1\x6b\xde\xf0\xbc\xeb\xf4\x9d\x53\xce\x5b\x58\x49\xe5\x4b\x14\x18\x16\xec\x87\xb0\x09\x6a\x9e\x57\x42\x75\x22\x29\x53\xac\x11\xc6\x4c\xb6\xe3\xe3\x9b\xa7\x80\x5d\x39\x1e\xbc\xe4\xf3\x07\x8a\x90\x46\x62\x59\x24\x3a\xf4\x2b\xe5\xe5\x3e\x6f\x8a\xf2\x97\x9f\x7f\x78\xd5\xec\x0e\xcd\x1e\xe9\xf4\x66\x84\x93\xd9\xc8\x19\xdf\x34\x1f\xb6\x2e\x00\x71\xcd\x37\x9f\x6e\xca\xf6\x41\xad\xe3\x3f\x6d\xb3\x7a\x6f\x82\x2c\x75\xe3\x7b\xc0\x1e\x18\x66\x06\x3a\x2e\xb3\x1e\x0b\xd3\x8a\x4e\x86\xcd\x4b\x11\xe6\x0c\x32\x69\x84\x83\xf4\x54\x28\xed\x37\x20\xb4\x17\x6f\x7a\x2c\xdb\x3a\xdb\xd6\x7f\x8c\x81\xfa\xa9\x16\x0d\x95\x43\x4e\x5d\x88\xdf\x41\x21\x59\xda\x2d\x1a\xa9\xe0\x34\x02\x94\x8b\x11\x2d\x2a\x60\x01\xbd\x77\xa5\x9a\x52\xd6\xfd\x90\xc5\xae\x4a\xad\xbc\xad\x67\xaa\x03\x5f\x07\xd5\x19\x47\x91\x97\xcd\x2f\x9b\x4b\xb6\xb1\x72\x66\xd5\xc7\x90\x44\xda\xe8\x27\x34\x08\xfe\x50\x83\xd9\xf3\x27\x49\xed\xea\x41\x58\x60\x5c\x3c\x9b\x6b\x0c\xf8\xa9\x21\xa6\xa0\xf4\x4c\xfd\x8f\x73\x47\x95\xeb\x40\xf3\xd9\x9c\x30\x6a\xa2\xe7\x2b\xcb\x69\x8c\x7e\xb2\x7c\xc4\x4f\xf6\x28\x3f\x24\x42\x13\x47\x31\x41\x5a\x40\xfc\x7b\xc1\xc8\xc7\xf6\xe3\x9e\xc8\xb5\x30\x1a\xb9\x34\x1f\xbf\x14\x31\x57\xb5\x44\xfe\x46\xf0\xcb\xff\xf9\x62\x71\xb9\x62\xaf\x04\xbf\xfc\x1f\xf3\xe7\xcf\x2e\xd9\xb7\x82\x5f\x86\x49\x1c\xa4\xf4\x77\x9e\xfc\x47\x90\x3e\xbf\x64\xaf\x41\xde\xcc\x9f\xc7\x34\x4a\x26\x1f\x4f\xe9\xf3\x30\xf9\x0f\x59\x63\xfa\x9c\x3e\xbb\x5c\xed\xd8\x77\x7a\x47\x5c\x34\x37\xa7\x2e\x3b\x1c\xe4\xbf\x8b\xe3\xa9\x69\xa5\xf0\x9a\xcf\x2e\x60\xd8\x1d\xeb\x66\x0f\x32\x4c\x8a\xb3\xee\xae\x2e\x80\x03\xef\xd9\x25\xfb\x9b\xba\xfd\x6f\xaf\x3f\x74\xdf\xbf\x7e\xf9\x2d\x7d\x76\xc9\xbe\x97\x65\x1f\x2f\x3f\x5e\x5e\xb2\x1f\x04\x7f\x3c\xb3\xbf\xc3\xff\xff\x10\x9c\x3c\xbf\x24\x3a\x4f\x98\x3c\x27\x94\xbd\x19\x09\x87\xca\x08\x5d\xbe\x11\xb0\xed\xca\x4f\xf8\xd7\x4a\xc3\xb7\xee\xae\x9b\x1f\x0a\x36\x5c\x5d\x4c\xc4\xaf\x7c\xd6\x52\x27\x2f\x2f\x58\xd5\x8f\x42\xf0\x3d\xed\xfd\x8d\xa0\x9c\xea\xed\x10\x5e\x25\xa5\xb4\x8a\xc8\x8c\x70\xce\x8b\x64\x91\xc6\x61\xc1\x0b\x03\x96\xd6\x75\xe4\x39\x61\x98\xe2\x96\x41\x16\x6b\x92\x52\x93\x22\x90\x53\x1a\xf5\xcf\x81\x69\x96\xbb\x19\x79\x3f\xf6\xe5\x3d\x82\xc2\x64\x9c\xf3\xbf\x0b\xdb\x10\xab\x70\x8d\xe7\x6b\x83\xf1\x92\xac\x53\x0c\x73\x45\x69\x94\xac\x31\xe9\xc1\x19\xec\xea\x96\x0d\x5f\xab\x70\xf0\xa7\x82\xa5\x37\x5d\x57\x75\x5d\x99\x6c\xd2\xb8\x8a\xa7\x61\xcd\x37\x54\x45\x13\x45\x21\xf2\x1a\x4b\x4b\xcf\x66\x3f\x6c\x28\x5b\xc9\xff\xa6\x57\xf4\x4c\x59\xad\x97\xe0\x95\x7b\x71\xb2\x48\x69\xd7\x4d\x4b\x48\xf1\x08\x82\x15\x8c\x00\xfb\xdd\xef\xfa\x99\x88\xbc\x9d\x67\x9b\xec\xfe\x7d\x79\x3a\xd5\xfb\xd5\x71\x5e\x6d\xb3\x93\x4a\xe9\x32\x5c\xd6\x39\xae\x30\xd6\x67\x9c\xe4\x69\x10\x84\x61\x99\xe4\x69\x9c\x45\x45\xd7\x85\x05\x7f\x3c\x53\x9a\xe4\x29\x9c\xb4\xf2\xd5\xe1\x6c\x9c\x2e\x90\x43\xc5\x41\x6d\xfc\x69\x3c\xe9\x9c\x67\x73\xb5\xf3\x7c\x64\x35\xcf\xec\xc7\x29\xc3\x99\x3c\x07\x14\x59\xf9\xa9\xb5\xf1\xbd\x98\x9c\xe7\x02\xe0\x44\xb3\xf9\xae\xde\x29\xab\x1f\x3c\xcb\x3f\x97\xc7\x43\xb3\x3f\x96\xdf\x97\x59\x51\xb6\x21\x51\xd8\xe7\x17\x1f\x90\x03\x49\x8e\xc7\x82\x9a\xf5\x74\x0d\x44\xf6\x10\x15\x2e\xff\x47\xd1\x56\x50\xfa\x58\x9b\xde\x28\xe9\x52\xb4\x65\x76\x0d\x69\xd3\xc9\x22\xad\xf7\x93\x9c\x56\xf0\x5a\xb0\xfa\x58\xf6\xad\x1c\x5d\x16\x35\x92\x35\xc9\x6f\xbb\x2d\x5b\xc8\xc4\x2a\x67\x64\x42\x66\xf2\x44\x4a\x1f\x2b\x5e\xaa\x1a\x57\x90\x0e\x5f\xd2\x33\x24\x81\xaf\xe4\x13\x4c\x50\x49\x35\xc5\x4f\x0f\x02\xfb\x2a\x15\x65\x79\x52\xa5\xb6\x61\xff\xd9\x1f\xde\x36\x9b\x5f\x0e\xf4\x6b\xb7\x51\xd5\xbc\x82\x16\xb8\x4e\xae\x52\xa4\xe7\x80\x55\xd3\x79\x55\xba\x49\x56\xfd\x3d\x7e\xef\x53\x56\xe9\xb2\xe2\xd7\xba\x3b\xf4\x4e\x27\xe0\x77\x4a\x63\x19\xda\xfe\xbb\xba\xdc\x16\xc7\xa4\x42\x4e\x89\x91\xf2\x94\x0b\x0a\x34\x1b\x40\xcb\x28\x5f\xf1\x3b\x58\xd9\x82\x20\x14\xdc\x2d\x00\xeb\x42\x7f\x02\xa4\xec\x56\xcc\x79\xbc\x7c\x2c\x8e\x92\x4a\x76\x89\xd1\xa9\x08\x10\xec\xd7\x41\x50\x43\x9c\x8e\xec\x96\x15\xdf\x24\x35\x74\x43\x95\x76\xdd\x26\x21\xcf\xe1\x27\x9b\xae\xa8\xc3\x12\x05\x6e\xc5\xd2\xb5\x08\xd7\xc9\x55\xaa\x30\xef\x6c\x15\x6b\xd9\x93\xa6\x16\x38\xa2\xf4\x71\x05\x58\x6b\xf1\x0a\x18\xa6\x22\xf9\x1f\xa4\xd8\x00\x42\xa4\xbc\x86\x5d\x9b\x9e\x94\xb5\x52\x67\x60\xad\x90\x35\x5b\xfe\x0a\x82\x2c\x21\xa7\x75\xdb\xdc\x1d\x49\x4a\x05\x5f\x85\x5a\x0b\x94\x2a\x3d\x1e\x2b\x3d\x7d\x6b\x56\xc8\xe3\x29\x3b\x95\x91\xa7\x89\x33\xf8\x13\xad\xe2\x6d\x44\x7e\x6c\x26\xd8\x85\x47\x80\xd4\x68\x9b\x9d\x1c\x8e\x33\x32\x39\x35\xb2\x15\xce\x7a\xff\x58\xd7\x73\xbc\x01\x2b\x87\x30\xd9\xf4\x91\x38\x3b\xa0\x93\x59\x7e\xaa\x6f\xcb\x68\xc1\xb6\xd9\xf1\xf4\xb6\x29\xea\xaa\x2e\x0b\x48\x2d\x3d\x65\x90\x62\xea\x8a\x99\xe8\xf1\xa6\xdd\x46\x6a\xdd\x61\xe0\x0b\x21\x7f\x7b\xfd\x81\xb0\xfa\xf8\xa6\xc9\xb3\x6d\xf4\x9d\x56\x41\x04\xc2\x98\xe4\xcd\x96\x32\x24\x18\x02\xd6\xc9\xb6\x91\xef\x01\xa4\x2b\x52\xae\x1c\x1f\xf6\xb9\xa2\x8a\x96\x93\x1a\xe9\x8f\xb3\xc3\x61\x5b\xa3\x2d\x75\x79\x7f\x71\x77\x77\x77\x51\x35\xed\xee\xe2\xa6\xdd\xa2\x7e\x5a\x2c\x27\xf9\x5a\x36\xcc\x89\xff\xf2\xe1\xbb\x8b\x7f\x23\x4c\xda\x70\x87\x93\x4a\xd1\xfb\x87\x40\x0a\x12\x34\x83\x0e\x52\x19\x25\x48\x59\x80\x25\xf2\x27\x61\xf7\xf2\xd8\x7b\xd2\x6e\xcb\x26\xc6\x72\x62\x9b\x23\x40\xf6\x3a\x17\xc8\x12\x75\xc5\x26\xbb\xcd\x14\x95\xcc\x59\xbf\xfb\x31\x7a\x94\x75\x5e\x7e\x14\xf7\xbb\xed\x47\x71\x89\x8f\xbc\xfc\x28\xe4\xdf\x4b\xac\xef\xf2\xa3\x90\x7f\x3f\x8a\xcb\x33\xf3\xe7\x10\xde\x4c\x74\xe1\x6f\x6f\xdf\x10\xf5\x15\xba\xe8\x43\x79\x7f\xd2\xaf\xa5\xcb\xfe\xfe\xfe\xdd\x8f\xf8\x06\x6a\x36\xcb\x16\x80\x57\x24\x11\x9a\x83\x68\x0c\x4e\xe0\x9b\x81\x6c\x14\x0e\x65\x2d\x24\x92\x77\xa3\xf9\xa8\x8a\xe5\x87\x47\xd6\x54\x3d\x33\x67\x51\xc1\x9e\xd7\x5d\x75\x7f\x8a\xa6\x8b\xb3\x19\x1b\x37\x4f\x84\x05\x8a\xf8\x9d\x08\x61\xe9\xf2\x57\x2b\xca\x04\x8d\xde\x89\xd0\x2f\x05\xf6\x18\x59\x60\xa9\x93\xde\x8a\xf0\x07\x41\xa1\xf0\x43\x9b\xed\x8f\x87\xa6\x3d\xc9\xc2\xbf\xab\xc2\x5e\xfa\xf1\x98\x0f\x7e\x40\x7e\x98\xc3\xfa\xd8\x93\xae\xec\x9a\x6d\xd5\xf6\x86\x79\xa9\x9b\x43\xf8\x08\x79\xd4\x07\xde\xcc\xd5\x67\x77\x5d\xc3\x3e\xd9\x43\xd8\x6a\xb0\x08\x49\x07\x65\x08\xd1\xb8\x0d\x0f\x34\xd2\xfb\x2b\x47\x2f\x3b\x9e\x9d\x78\x3b\x7f\x95\x6d\xb7\x22\xcb\xaf\x8f\x21\x69\xf6\x79\x39\xd9\x95\xbb\xa6\x7d\x20\x94\xdd\xf0\x66\x2e\x27\xed\xcd\xf1\x15\x50\xf6\x3f\x9e\xd9\xad\x14\xfd\x77\xf2\xbf\x7b\x4e\x90\xa1\xb6\x2c\x08\x7b\xe0\x8f\x6d\x99\x15\x0f\xef\x61\x8a\x03\x79\xbc\xbf\x56\x8e\x20\x53\xc9\xa5\x02\x17\xb5\x35\x7d\x5c\xf3\xc7\xb3\x09\x9c\x78\x2d\x30\x35\x75\x45\xe9\x3a\x11\x43\x92\x0c\x2e\x92\x17\xe9\x59\xf0\x75\x92\xf5\xce\x9c\x3d\x6b\x40\xa0\x35\x20\xce\xf2\x7d\x5e\x6e\xb7\xfe\x2b\x1d\x47\x8c\xaa\x6b\x15\xb9\x0a\x3b\x8d\x3f\x23\xd8\xd0\xe0\x03\x9c\x41\x85\xcf\xb9\x86\x9c\xa9\xbb\xc1\xdb\x8c\x14\x75\x5d\xc6\x6e\x93\x0c\xd6\x28\x8c\xa7\x69\x6e\xcb\xb6\xad\x8b\xf2\xad\x52\x35\xc6\xa2\x51\xed\x63\x1a\xa3\x92\xf0\x4c\xd7\x60\xbb\x68\xbc\x95\x01\x1a\xe2\x9a\x3e\xe8\x54\xe5\x2c\x79\x50\xdd\xea\x66\xb1\x09\xb4\x71\x6f\x12\x91\xf2\xe4\x06\x92\x58\x12\x91\xa6\x3e\xa7\x4b\x26\xe4\xa0\x1f\x09\x52\xec\xba\x7b\x87\xcf\xb5\x9c\xc3\x85\xa1\xa0\xec\x65\xb8\xd0\xa1\x28\x67\x30\xd9\x8f\x06\x6f\xe0\x81\xb2\x66\x7e\xd3\x6e\x79\x18\x8a\xae\x83\x9f\x5d\xa7\xe4\x39\x9d\x11\x42\x8d\x71\xf5\xbd\x60\x8e\x10\x9f\x91\xcb\x4b\x22\xef\x85\x7d\x81\x7c\xbe\x2b\x4f\xeb\xa6\xe8\xba\x5c\xb1\xca\x35\xa6\x04\x2f\x61\x8d\x55\x54\x78\x68\x0f\xc0\x06\xa0\x4f\xdb\x17\x84\xa4\x2a\x36\xa3\x99\xe7\x6d\x73\x3c\x7e\xdb\xec\xb2\x7a\x4f\x1f\x37\xe3\xa6\x90\x5c\x42\x37\x68\x0d\xc1\xc7\x30\x75\x80\x7f\x98\x57\x09\x7f\xd3\xfb\x9e\x99\x34\xa4\x9a\xe3\x69\x8a\xb9\xf9\xce\x89\x0d\x94\xab\x55\xf9\x0f\xfa\xe8\xd7\x23\x45\x5f\x5d\xa9\xaf\x82\x2d\x24\xbb\xac\xd9\x40\x2b\x63\x2e\xe8\xeb\xd4\x0d\x5c\xbb\x21\xf0\x50\xb6\x69\x9b\x15\x80\x11\x9f\x6d\x29\x65\x3f\x4a\x99\xc7\x1a\x96\xb3\x07\xca\xae\xb5\xfa\xf8\xb0\xdc\xea\x1d\x38\xf9\x44\x5c\x52\xd9\x36\x08\x16\x00\x5f\x83\xab\xf8\x6c\x06\x7a\xbb\xe7\xd8\x27\x20\xcd\x4e\x59\x7b\xb2\xfd\x87\x7f\x7c\x54\x6b\xd6\x40\xcc\x94\x62\x16\x9a\xfe\x4d\x2d\xe4\x78\x29\x65\xaa\x7d\xcd\xf0\x78\x05\x91\x1b\xde\x4d\xf1\x13\x0d\x02\xc0\xbe\xcd\xdc\x59\xe3\x21\x9e\xc9\xee\xb3\xfe\xe9\x82\x0f\x80\x3c\xaa\xf5\xf0\x8f\x79\x8f\x6f\x04\x23\x33\x22\x6d\xc7\xbd\x7a\x43\x54\x8b\x75\x66\x22\x65\xa6\xf9\xab\x19\x0f\x6f\x85\x81\x08\x27\x01\x89\x48\x4c\xe8\x4c\xf5\x83\x8a\x34\xc7\x23\x80\x3a\xce\xf2\x75\xa9\xb9\x72\x2b\x5e\x59\x52\x43\xc1\xc8\xb3\x2b\x42\xd9\x7e\xbc\x42\xf2\x3b\x27\xb3\x1b\x31\x9b\x4d\x66\x7b\x3d\xdf\x2a\xfc\x59\x57\x5a\xc5\x02\x6c\x06\x57\xe7\x02\xf5\xfa\x61\xde\x17\x82\x21\xf9\xa1\xba\xd0\xd7\x5c\xbc\xaf\xf7\x79\x49\xd8\xe0\x4e\xd8\xb3\x39\x65\xab\xcf\x55\xf2\x63\xb3\x2f\x2f\xde\xca\x21\x4d\xec\xd5\x94\x32\x67\x20\xdb\xce\x94\x47\x4e\x8f\xa9\x5d\xbc\xdc\x2d\xa3\xe3\x4f\xf2\x0c\x34\xe6\xd5\x42\xd9\xd8\x0d\x2f\x41\x7b\x23\xae\xc8\x00\x3b\xa9\x99\x2b\xbd\x2e\xf1\xcf\xa4\xf1\x93\x67\x66\xca\x52\xf0\x8b\x63\xc2\x26\x64\xf6\x0f\x31\x23\xcb\xc9\x27\xbe\x98\x2f\xae\x48\x44\x08\x8d\x6c\x35\x80\xab\x00\x36\xf3\x4e\x8a\xe4\x66\xbe\xc6\xe5\x8a\x8e\xbc\xef\x8e\x99\xd3\xc9\x0e\xc9\x0d\x9b\x39\xd2\x15\xbd\x2f\xf7\x05\x62\xce\x9b\x43\x0c\x83\x38\xb0\x07\xd6\x50\x8e\x8d\x78\x6d\xa2\x47\x1e\x94\xcc\x86\x4a\xee\x39\x81\x23\xc2\x90\xb6\xb6\xb1\x10\x18\xec\x01\x61\x32\x9a\xb9\x52\xe4\x65\x09\xc0\x62\x34\xe8\x94\xa7\xac\xe4\x3f\x4a\xb5\x48\xc9\x0d\x58\xe3\x1f\xe6\x56\x3f\xe0\x57\x52\x56\x7c\xea\x49\x05\xe0\x5d\x4a\x1e\x58\x93\x7a\x92\xa6\x99\x83\x62\x2e\x7b\xe0\x84\x99\x7c\x5f\x2f\x60\x4f\xf6\x29\xbc\x3e\xfd\x1d\x44\x5d\x4e\xe8\x99\x99\x7b\x29\x4a\xe9\x6b\x3e\xbd\x62\xe5\xfc\x28\x8d\x8e\x5b\xf6\x92\x5a\xe1\x0a\x2b\x25\x18\x48\x93\x3f\x96\x2f\xc3\x8b\x2b\xf6\x07\x3d\x63\x54\x26\x1c\x49\x6b\xc7\x68\x7f\xc4\x89\x4d\x7f\x89\x7e\x1a\xe3\xb8\x01\x05\xee\x96\xdd\xb1\x7b\x9e\x2f\xaf\xbb\x2e\xbc\xe6\x53\xd8\x00\xee\xa5\x25\xd6\xb2\xb9\xd4\xf6\xf0\x8a\xaf\xa5\x34\x62\x5e\x63\x89\xaf\x17\xf1\x97\xd1\x82\x6d\xb8\xf8\x9a\xbf\x58\x2c\x82\x40\x7c\xf5\xc5\x62\xd1\x75\x5f\x2c\xbe\xe4\x9c\x0b\x26\x7b\xf9\x96\xff\x24\xc2\x86\x3d\x00\x56\xca\x2d\xff\xa7\x3c\xb8\x65\x0f\x80\x77\x12\x87\xbd\xa9\x7e\xc7\x1f\xc6\x9c\x19\x6f\xb2\xe3\xc9\x4c\x6e\x42\xd9\xdd\x98\x54\xe0\x77\x94\x3d\x71\xbf\x9c\xc4\xe6\x36\x35\xa3\xf9\x1d\xa5\xec\x05\xbe\x68\xd7\x91\xef\x5f\xbf\xfc\x56\x1a\xd4\x28\xc8\xe3\x7b\x4e\xf6\x8d\xe6\x21\x88\xd4\xf7\x60\xe9\x69\xa7\x5f\x24\x0a\xef\xf9\x2d\xe8\x2b\x25\xdb\xf1\x5b\x94\x8f\x7b\x7e\x8b\x83\x8d\x6d\xf8\x74\x8f\x12\xf7\x9e\x4d\x45\x10\xdc\x77\x9d\x1c\xbd\xca\x4c\x15\x10\x9e\x2e\xf8\x82\x52\x98\xef\xa0\xf5\x70\x61\x7e\x02\x47\x50\x98\x77\xdd\xbd\x54\x38\xd8\x26\x3e\x7a\x80\x3a\x07\x96\xec\xd8\x3d\x7b\x48\x69\x74\x74\x11\x75\x0e\x72\xa0\xde\xb3\x7d\x6a\x2b\x95\xea\x57\x78\x23\x75\x66\xd5\x99\xde\x10\xdf\xc4\x38\xc8\x95\xe9\x1b\xc1\xd1\x6b\x7c\x47\x39\xe6\xd9\x26\xde\x45\xb2\xba\x13\xe0\xfd\x39\x0f\x49\xa9\xac\x29\xec\xcd\x96\x57\x6a\x36\x9a\x19\x73\x71\xa1\xd7\x5d\xd8\x1c\x1b\x5b\x75\x1b\x88\xb8\xd3\x1a\xf2\x03\x28\xc5\xd2\xec\x7a\x2a\x4b\xad\xd5\xa9\x3e\x2c\x67\x04\xac\x34\x0a\xf7\xbc\x07\x63\x73\x5c\x1f\xd6\xf7\xe8\x00\x1f\xcb\x72\xea\x85\xc1\xad\xca\x13\x61\xe4\xd0\x1c\x4f\x43\x28\xf8\xfe\x9e\xb8\x97\xe6\xde\xf3\xf6\x42\x0c\x2c\x04\x69\x15\x80\x78\xae\x0d\x2b\x34\x9b\x2c\xf2\x0e\xd8\x8b\x19\x53\x01\x61\x5a\x1c\x47\x25\xba\x20\x72\xa6\x24\x59\x04\x80\x21\xfd\x4d\xa3\x20\x80\xe0\x4c\x59\xab\x66\x1a\x1e\x0b\x91\x53\xcf\x74\x1f\x85\xee\x08\xf3\x38\xdd\x16\x0c\x16\x73\xc7\xe7\x70\x65\xbc\x12\x57\x4c\x7b\x67\x20\x92\xa3\xb7\x9f\x74\xd7\x66\x87\x97\xdb\x91\x88\x66\x57\x49\x87\xe5\xaa\x9f\x1f\x81\xa0\x0e\x36\x0c\x39\x59\xa4\x18\x0f\xac\x30\x96\x07\x6c\xd5\x74\x5e\x7e\x0a\x17\xd4\x21\x98\xd3\x97\xf9\xc9\x46\x1e\x07\xa5\xae\x99\x89\xf1\x8d\x29\x00\xbe\x42\x23\x2f\x43\x52\x4e\xa5\x3f\x23\x37\xa7\x7c\xc3\x41\xa9\xa5\x34\x36\x8c\x84\x98\xa9\xa1\x8c\x1f\xd9\x26\x3f\xec\xf7\xe3\xd4\xc6\x7f\x21\x67\xc0\x49\x0f\x31\x55\xf9\xc9\x21\xf4\xf3\x49\x02\x26\x0f\x20\xe7\xc2\xb8\x9c\x43\x9b\xe3\x1f\xe7\x73\xd5\x6f\x61\x46\x23\xe1\xd0\x2a\x52\x7c\xfb\xd1\xf8\x61\xef\xbd\x97\x4f\x07\xe4\xe4\xfe\xeb\xcb\xa7\x08\x3f\xde\x9c\x46\xf8\xa8\x9b\xfd\xe0\x61\x1e\x25\x20\x74\x6b\x98\xd1\xf9\xbe\x39\x85\x44\x34\xc5\x03\x19\x12\xdd\xda\x4c\x1a\xc3\x74\xa8\xf7\xf0\x34\x7f\x39\x3d\x5b\xa0\x31\x95\xb0\x7a\x38\x96\x37\x45\x73\xd4\xf0\x8b\xc3\x57\x98\xf6\x2e\x04\x4e\x2a\x39\x4a\x60\x06\x8c\x9d\x1a\xab\x64\x1a\x66\x73\x64\xca\x01\x90\xff\xae\xd3\x87\xc8\x01\xf3\x19\x6a\x08\x78\x8c\xb7\x85\x71\xbf\x6e\x5d\x2c\x01\xa9\x34\x38\x48\xf3\xd9\xfc\xb7\xb7\x6f\xbe\x3f\x9d\x0e\x4a\x1b\x53\xfa\x83\xa0\x8f\x67\xf4\xe6\xfc\x2c\xf8\xe3\x02\xd0\x11\xae\x5e\xbc\xf8\x22\x7a\xb1\xf8\xf2\xcc\xde\x8b\xfe\x3e\xc9\xfd\xba\x0d\xe9\x52\xea\x56\xed\x91\x4f\xa7\xef\x45\x10\x90\xbb\xfa\xb4\x7e\xd5\x96\x45\xb9\x3f\xd5\xd9\xf6\x48\xea\xfd\xe4\xbd\x60\x0d\xdc\xc8\xdf\x0b\xb8\x4c\xbd\xac\xd1\x43\xc2\x41\x1c\x07\x2b\x50\x15\x94\x35\x77\x9d\xac\x78\x2a\x3c\x1b\x56\xbb\x64\x3d\xbe\x5e\x37\xca\x96\x0b\xf5\x7a\x75\x15\xae\x81\xa5\x31\xc4\x40\x3c\x26\xc0\xb6\x15\xa8\x97\xc9\xa3\x63\x09\xc1\xa2\x90\x88\x78\x3c\xde\x35\x6d\x21\x25\xc0\xfd\xba\x45\x77\xa2\xdd\x0b\x70\x0b\xd7\xc9\x2a\xe5\x4e\x41\xb2\x4a\x97\xc2\x38\x37\x82\x60\x3d\xef\x3b\x46\xc6\xca\x42\x7b\x8b\x7c\xa6\xf3\x85\x5d\x57\x26\xe4\xb7\x0b\xd5\x41\x65\x71\x01\xac\x9c\x69\xd7\x85\xa3\xe5\x9c\xf8\x3d\xaa\x10\x3e\xe1\xb5\x4b\xba\x1e\x6a\xde\x2b\x06\x7c\x9b\xcb\x7c\x6c\x2d\x70\x46\x4e\x0e\x5e\xbf\x82\xaf\xe7\xcd\x7e\xdb\x64\xf8\x03\xb4\x13\xf8\x05\xba\x2a\xfc\x02\x95\x0f\xd4\x1c\x8c\x35\x83\x30\x43\xa6\xd4\x70\xe0\xa3\x5e\x6b\x0d\x3d\x52\xea\x0d\x94\x0e\xb0\xbf\xd6\x4a\x23\x89\xab\x70\xc1\xd4\x95\x34\x92\xbd\x88\xe5\x6c\xed\x28\x3f\xf2\xc4\xcf\x22\xd1\x45\x69\xd7\x8d\x5e\x86\x4e\x59\xa0\x1c\x59\x9b\x1d\x17\x65\x3d\xc3\x19\x3a\x12\x33\xe4\x5c\x59\xde\x9f\xe2\x47\x51\xef\xb3\xf6\x21\xb2\xc5\xe7\xe8\x11\xdc\xb7\xfe\x85\x67\xb6\x9e\x8f\xfa\xeb\x42\x0a\x49\x12\xa6\x25\xf3\x90\x32\xb7\x3d\xf3\x50\x7f\xad\x4d\x7d\x36\x6d\x1c\xdb\xd6\x2e\xa2\xd1\xf6\x76\x3a\x4d\x2a\xa2\x6b\x47\x09\x07\x92\xa6\x51\x6b\x23\x0f\x82\x02\xd0\x99\x59\x2e\x9f\x8f\xbd\x85\x46\xc6\x1a\xed\x0b\xe1\x19\xb2\xb8\xcb\x8a\x08\x4f\xda\xec\xa8\x15\xbb\x0d\x9a\x1d\xf5\x79\xe0\x66\x83\xc7\xe4\xa1\xce\x46\xf1\xdc\xd2\xa1\x3b\xfc\x32\x77\x06\x00\x0e\x82\x5e\x90\xe6\xa8\x7b\x70\xdc\xf6\xf5\xdc\xca\x66\xc3\x02\x2f\x51\x3b\x13\x76\x5b\x81\x4d\xbc\x9d\x87\x27\xca\xcb\x7c\x37\x5a\x7e\x7f\x61\xcf\x78\x1b\x14\xea\x69\x97\x1f\x45\x18\x47\xb2\xd6\x4e\x5e\x48\xb1\x18\x76\x25\xbc\xad\x04\xd8\x14\x50\xd5\x8c\x2f\xf5\xa8\x43\xbd\xbe\xcd\xe4\x42\xcb\xb2\xd1\xc6\x32\x2a\x98\xb7\xe6\x1a\xc2\x67\x74\xb3\x60\xc3\x81\xc3\x65\x7a\x45\xd9\xb0\x51\x11\x67\x45\x2a\x77\xb6\x31\xad\x30\x1e\x7d\x06\x6c\x61\x7a\x4e\x44\x95\xd3\xb3\x7c\x5a\x12\x4b\xd5\x82\x7c\x85\xb5\x7d\x4d\x28\x46\xf5\x3c\xaa\xed\xa6\x28\x53\x5d\xfa\x0a\x8f\xd9\xb1\xcd\xa3\x4c\x8a\xe6\x33\x9d\x37\xfb\x90\xc8\x29\x32\x51\x66\x90\x2f\xa4\x84\x0e\x1c\xd4\xa1\xf6\x2c\x0b\x82\x2a\x74\x84\x0a\x9a\x67\x5f\x2e\xbe\x84\x25\x0c\x0f\xe5\xa7\x16\xe0\x6c\xf0\x90\x6f\x84\x54\xf8\x3e\x37\x62\x55\x10\xcc\x07\xc1\x93\x94\xfd\x22\xf8\x65\xc8\xe9\xc7\x38\x8c\x79\xd0\x3d\xa3\xdd\xc7\x18\x43\x12\x9d\xf1\x28\x4d\x8d\x43\x44\x72\xb5\x2b\x81\xfb\x4c\x07\xbd\x49\x31\x24\x3a\xf9\x20\x30\xbe\x1b\x0c\x1f\xcc\x88\x98\x91\xdf\xd1\xe9\xe5\x29\xc6\x19\x04\x5d\x64\xa3\xe3\x42\x3e\x03\xb6\xa2\x0e\x84\x79\x99\x27\x3d\xde\x2e\x31\x87\x8b\x34\x52\xda\x2f\xca\xe3\x06\x6b\x22\x8d\xc9\x4d\xbb\x25\xd1\x20\xcb\x4c\x28\x9f\x16\x38\x1f\xc5\x7f\xd7\xf9\x68\x9f\x09\xce\xc1\x20\x20\xf2\x2f\x66\x21\xaf\xbb\x8e\xe0\x57\x00\x03\xb0\x17\xd1\xa1\xdd\xf3\xfa\x1b\x74\x8b\xf6\xa2\xf4\xfc\x93\x34\xee\x15\x84\x52\x87\xf5\x4a\xd8\x3a\x16\xc9\x3a\xe5\xf2\x3f\xe3\x96\xfc\x05\xdd\x92\xb3\xd2\x5c\xae\x9b\x0c\x9a\xca\xf1\x7e\xea\xa6\xd3\x0e\x4b\x75\x39\xc6\x00\xc2\xa2\x6e\xe3\x03\xd4\xd4\xc2\x3d\xc3\x94\x0f\xf7\x6f\x56\x36\x34\xb4\x9c\x91\xc9\x5d\x76\x9c\xec\x9b\xd3\x44\x8e\x25\xf0\x69\xac\x92\x45\x7a\x66\x7e\xc3\x70\x34\x6e\x01\x03\xbb\x4c\x99\xfc\xcf\xc3\xfc\xe7\x26\x18\xfb\xcc\x8a\x11\x38\x69\x23\x3e\xaa\x18\xc2\xa8\x2d\xb0\x48\x58\xd2\x08\xab\x83\x50\x4a\xf8\x78\xbf\xe9\xf3\x5e\x53\xca\xb1\x7c\x73\x5c\x87\x25\x05\x5a\x3a\xaf\x67\x2a\x2a\x67\xe9\x0a\x0c\xac\x15\xaf\x2c\x2b\x85\x16\x38\x10\xae\x8d\xfb\x12\xdf\x7f\x00\xac\x10\x78\xed\x01\xa2\x19\x2f\xe6\xf5\xee\x80\x36\x16\x8c\xb5\x91\x9b\x42\x39\x2e\xa5\x11\x60\xf1\x76\x1c\x9e\xeb\xaf\xe4\xb0\xfc\xfa\xab\x4b\xfc\xe3\x1e\x10\xf6\x02\x05\xa9\xb1\x07\x94\x8a\x7d\x86\xbc\x08\xd8\xce\x85\x3a\xfa\x4e\x07\x27\xc9\xda\x02\x41\xaa\x31\x9b\xa4\xcb\xd1\x34\x72\xb5\x9d\x3a\xbd\xa2\x76\x0b\xd5\xe5\x6a\x1d\x6b\x8d\x38\x14\x7f\xf5\xfb\x81\xf1\xaa\xb7\xcf\x23\xb2\x63\x29\xcf\xe0\xce\x4e\x61\x02\xad\x71\x8b\x47\x0c\xe5\x63\x49\x69\x24\x78\x41\x59\xc5\x5f\xe1\xae\x26\x50\xc2\x4d\xf3\x20\x48\x52\x56\xc5\x49\xff\x11\x55\x72\x95\x52\x20\x5b\xfc\x84\xf8\xf4\x82\xad\x60\x30\xac\x0c\x8f\x5d\x1b\xae\xa8\x95\xe1\xed\x7c\x57\xb6\xab\x32\x94\xd5\xb9\x76\x98\xf6\x1e\x80\xae\xf4\x24\x12\x0d\x5b\x21\xf5\xc6\x9a\x67\x2e\x84\x80\xc5\x1d\xc7\x84\xb5\x82\x1f\x44\xa8\x89\x76\xd7\x94\x32\x69\xac\xe3\xd1\x82\xc9\xe3\x7e\xa8\xaf\xbf\xd5\x1d\x89\x11\xe8\x5c\x60\x35\xe1\xe4\xa7\x77\xef\x3f\xc8\xa9\x69\x52\x1d\xe4\xb8\x1f\xf8\x52\xa4\xa8\xec\xb9\x53\x30\x78\x42\x45\x91\xd0\x1e\x82\x7f\x46\x1f\x2b\x3b\x73\xd9\x6a\x2e\xaf\x0e\x8b\x58\x2e\xa9\x45\x7d\x2b\xd7\x53\x65\x89\x3b\xa3\x32\xcc\x28\x85\xd4\xdd\xb0\x40\xb3\x59\x4f\xf7\x3c\x08\x7c\x37\xd5\x6a\x60\x1a\x7b\x20\x8b\x55\xd7\x39\xa1\x49\xa0\x41\x0b\x96\xa5\x40\xe3\xa1\x1c\x17\xc6\x19\x66\xf7\xc4\x98\xf5\xd4\xb1\x9e\x9b\xcf\x75\x18\x7a\xae\x44\x66\xbd\xe7\x43\x56\xc5\x7e\x86\x89\x6f\xf2\xc3\x0a\x97\xd1\x11\x43\x5d\xa1\x25\x16\xe3\x7e\xae\x55\x5b\x1e\x42\x03\xe5\xe9\x79\x52\x94\xac\x80\xc5\x07\xd1\xf5\xf5\xf4\x67\xad\x32\xc6\x21\x49\xe3\x1d\xfc\x7c\x1a\x1f\xc9\x86\x42\x38\x44\xc0\x8a\xbc\x9a\x50\xb6\xe5\x52\xd2\xb2\x1d\x7f\x3c\x2f\x89\xd4\xe1\xeb\x5c\x33\x77\x68\x96\x0e\x7d\x35\x27\x9a\xed\x9f\x50\xb6\xe6\x5b\xf5\x16\x21\x02\xee\xaa\xaa\xc1\x37\xca\x6a\x5b\xb0\x05\x06\x43\xb6\xe1\xa1\x65\xca\x56\x24\x1e\x55\x7d\x0f\x60\x71\xfc\x9a\xc2\x3e\x5e\xed\xae\xdf\x37\xa7\x06\x52\x3c\xd9\x26\x0e\x0b\xbe\x35\x6f\x11\x02\x0d\x24\x90\xfc\x97\x52\x6a\x94\xd5\x89\x46\xe1\x6a\x48\xd7\x5b\xba\x45\xb5\x2c\x1a\x4c\x2d\x70\x68\x0b\x8d\x68\x9e\x7b\x60\xc0\x6b\x4a\x35\x22\xb3\x98\x03\x58\x6a\xb8\x93\x7f\xf1\xe8\x62\x2d\xff\x9f\xad\xec\x25\xf2\x45\xe0\x1a\xf9\x43\x1d\x5f\xac\xe1\x8f\x5c\x7c\xc9\xcd\x51\x0a\x64\x69\xba\xc7\xd2\xd0\xaf\xf7\x2b\xfd\xdc\x1d\x8d\xb6\xd0\x5a\x3b\x64\xa6\x72\xdc\x94\x4d\xbf\x73\xe9\xe7\x20\x16\xac\xf6\x0d\xee\xb9\x31\x4f\x1b\x8c\x65\xac\x75\x6e\x06\x8f\x06\x87\x15\x3a\xdf\xd8\xe0\xc4\xb8\x39\x66\x36\xe4\xf1\x29\xdf\x8f\xec\xa8\xea\x29\x8a\x49\x80\x95\xf5\xa9\xea\x73\xa9\x57\xa9\x03\x25\xb3\x61\xa1\x70\x72\x36\xd9\xe3\xa9\x39\x44\xd0\xdd\xb3\x72\x7e\xc8\x56\xe5\xff\xc6\x77\xbe\xc8\xe7\x39\xd4\xfe\xa1\x39\x30\xd9\xc8\x51\xa1\xda\x1a\xae\xfa\xad\x77\xd5\x1b\xe0\xb7\x8c\xa0\xb6\x05\x5e\xbf\x38\x9f\x99\x61\x71\x77\xa4\x4f\x5d\x19\xef\xab\x86\x2d\x65\x26\xd9\x8e\x15\xdc\xaf\x43\x07\x13\x9b\xb1\x8c\x03\x3f\x77\x27\x59\x2c\x90\xd4\x7f\xac\x59\xa2\x50\xa5\x05\x60\xa7\xfc\x84\xbe\x43\xd9\x5a\x4e\x69\x48\xd9\x37\x61\x26\x1f\x8f\x92\x9a\x42\x88\x6f\x66\xce\x52\xfd\x5a\xd8\x50\x6a\xee\xc1\xf5\x48\xd6\xf9\xa1\x39\x18\xf2\x6e\xea\x35\xd7\xf0\x5a\xd9\x54\xf6\xe2\x33\xc5\x2e\xc0\x51\x0f\xf5\x5f\x98\x4f\x44\xbe\xad\x0f\x52\xc8\x9a\x7a\xd5\xc8\xc7\xea\xfb\x97\x02\x9d\x29\xa6\x23\x9e\x99\xfb\xc5\xff\xa9\xac\x8c\x41\x7b\x69\x4f\x38\x44\x69\x68\x11\x36\x22\xed\xc0\x2f\xee\xdd\xa8\xc5\x6c\xd7\xb5\xd9\xd9\x47\xea\x35\xd4\x73\x11\x71\x46\x14\x61\x86\xaa\x0e\xcb\xd5\x78\x7c\x22\x25\xcf\xbb\x44\xca\xf2\xe5\x00\x62\xb7\xf8\x0c\xbf\xa8\x25\xa8\x5f\x3a\x7e\x78\x95\x51\x9b\xd1\xb8\xe2\x59\xf4\xef\x7d\xca\xa7\x8a\x67\xee\x14\x72\x29\x8b\xe3\x2a\xae\x12\x91\x46\x59\x52\xa4\x10\xdb\x1e\x56\x71\x65\xc8\xf7\xc2\x3c\xae\xdc\xd9\x13\x95\x2c\x8f\xcb\xa8\x72\xe7\x1d\x85\x7b\x79\x09\x0c\xa3\xc5\x00\x0f\xb0\x0f\xce\x2c\x97\x5f\x58\x01\x3e\xcf\x53\x0c\x7c\xb9\x87\xfa\xbe\xdc\xfe\xa4\x3a\x8b\xf9\xc9\x9c\x6e\x8e\xab\x22\x48\x17\x94\x69\x66\xf8\x9c\xa2\xbd\x60\xd7\x88\x44\xa4\xc0\x65\x1b\xe5\x67\xea\x74\xaa\xa2\x30\x37\x24\xca\x30\xce\x35\xa9\xff\x10\x0c\x19\x6f\x32\xd4\xb7\xa0\xb6\x93\x59\xa6\x5d\x2f\x91\x60\x84\x44\xa4\xb9\x39\x41\xf1\xb9\x87\xaf\x0b\x3d\x5d\x38\x3d\x6d\x9d\xc2\xbc\xdf\x6e\x52\x03\x77\x10\xa7\x8d\xde\x5e\xca\x95\x36\x07\x50\x54\xa4\x01\xa8\x30\x78\x59\x53\xdd\x45\x9a\x85\xde\x68\x99\xfd\x41\x04\x98\x0f\x4f\x0f\x22\x41\x63\x88\xd2\xb7\x2b\x2f\x7e\x0e\x8d\x45\x62\x3e\x38\x8d\xac\xa0\xee\x4b\xec\x84\xa0\x84\x85\xcb\xfe\x1d\xd4\x15\x3d\x16\xe3\xb0\x1a\x91\xf0\x86\xf3\x47\x80\x55\x04\x96\x68\xb3\xdd\xca\xfb\x59\xe5\x1d\xe9\x0b\x34\x67\x3f\x5e\xe0\x1f\xd9\x87\x53\x9d\xad\x01\x03\x1d\x67\xbf\xfc\xf8\x35\x35\x8c\x94\x88\x7f\xb1\xa6\x67\x69\x09\xc4\x65\xa4\x83\x05\x00\xcf\xb8\x97\xf0\x2b\x6a\xd7\x8b\xe4\xef\xe7\x6a\x9d\x2f\x53\xd9\xe0\x2c\x87\x5d\xa1\xc1\x2d\xbd\x1b\xaa\xca\xdc\x41\xcf\x4c\x43\x21\xfc\x09\x89\x02\xaa\x96\x8a\x0c\xe1\x66\xff\xc4\x5d\xe6\x1e\x40\x59\xed\x0d\xae\xd8\x79\x3c\x79\xfe\x9c\xa8\x3d\x38\x59\x20\x58\xd6\x75\xb2\x8c\xe5\x6a\xea\xae\x9b\x6d\xf1\x73\x99\x15\x0f\x9e\xc6\x9a\x01\xc4\x6a\x56\x3c\xfc\x9a\xd5\xa7\xd9\x2c\x52\x47\x40\x85\x00\x5a\x15\xe4\x87\x71\x2f\x5b\x4c\x1b\xa9\x7f\x7f\xff\xee\x47\xee\x44\x25\xb7\x26\x89\x8d\x7f\xc3\x88\x7e\x8a\x35\x66\x10\x45\x38\x08\xf0\xef\x3c\xdb\x15\xfa\x77\x48\x30\x10\x97\xb0\x24\x1d\xa1\xb7\x6e\x95\xfa\xf2\x2f\xc1\xb3\xf9\xe6\x9f\xf2\x4a\xf6\xab\xfc\xfd\xcc\x0e\xfc\x7d\xf3\xaa\xd9\x57\xdb\x3a\x3f\xf1\x31\x75\x7b\xfe\x4c\xae\x1c\xa0\xfc\x3e\xe3\xbf\x0a\xe4\x4a\x50\x75\x99\x33\xea\xf0\x5f\x82\xb2\xf6\xcc\x04\x00\xd6\xa8\x32\x79\x5b\x2b\x8b\xe9\xf2\xff\xff\xff\xfe\x4f\x00\x00\x00\xff\xff\xfc\xd2\x6a\x08\x8f\x52\x01\x00") - -func pkgUiStaticVendorJsJqueryMinJsBytes() ([]byte, error) { - return bindataRead( - _pkgUiStaticVendorJsJqueryMinJs, - "pkg/ui/static/vendor/js/jquery.min.js", - ) -} - -func pkgUiStaticVendorJsJqueryMinJs() (*asset, error) { - bytes, err := pkgUiStaticVendorJsJqueryMinJsBytes() - if err != nil { - return nil, err - } - - info := bindataFileInfo{name: "pkg/ui/static/vendor/js/jquery.min.js", size: 86671, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/js/jquery.hotkeys.js", size: 4490, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1360,7 +1591,7 @@ func pkgUiStaticVendorJsJquerySelectionJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/js/jquery.selection.js", size: 12881, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/js/jquery.selection.js", size: 12881, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1380,7 +1611,7 @@ func pkgUiStaticVendorJsPopperMinJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/js/popper.min.js", size: 19236, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/js/popper.min.js", size: 19236, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1400,7 +1631,7 @@ func pkgUiStaticVendorMomentMomentTimezoneWithDataMinJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/moment/moment-timezone-with-data.min.js", size: 184495, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/moment/moment-timezone-with-data.min.js", size: 184495, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1420,7 +1651,7 @@ func pkgUiStaticVendorMomentMomentMinJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/moment/moment.min.js", size: 51825, mode: os.FileMode(420), modTime: time.Unix(1582229186, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/moment/moment.min.js", size: 51825, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1440,7 +1671,7 @@ func pkgUiStaticVendorMustacheMustacheMinJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/mustache/mustache.min.js", size: 9528, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/mustache/mustache.min.js", size: 9528, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1460,7 +1691,7 @@ func pkgUiStaticVendorRickshawRickshawMinCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/rickshaw/rickshaw.min.css", size: 6102, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/rickshaw/rickshaw.min.css", size: 6102, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1480,7 +1711,7 @@ func pkgUiStaticVendorRickshawRickshawMinJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/rickshaw/rickshaw.min.js", size: 76322, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/rickshaw/rickshaw.min.js", size: 76322, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1500,7 +1731,7 @@ func pkgUiStaticVendorRickshawVendorD3LayoutMinJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/rickshaw/vendor/d3.layout.min.js", size: 17514, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/rickshaw/vendor/d3.layout.min.js", size: 17514, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1520,7 +1751,7 @@ func pkgUiStaticVendorRickshawVendorD3V3Js() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "pkg/ui/static/vendor/rickshaw/vendor/d3.v3.js", size: 144718, mode: os.FileMode(420), modTime: time.Unix(1582228803, 0)} + info := bindataFileInfo{name: "pkg/ui/static/vendor/rickshaw/vendor/d3.v3.js", size: 144718, mode: os.FileMode(420), modTime: time.Unix(1583953499, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1597,6 +1828,18 @@ var _bindata = map[string]func() (*asset, error){ "pkg/ui/static/js/bucket.js": pkgUiStaticJsBucketJs, "pkg/ui/static/js/graph.js": pkgUiStaticJsGraphJs, "pkg/ui/static/js/graph_template.handlebar": pkgUiStaticJsGraph_templateHandlebar, + "pkg/ui/static/react/asset-manifest.json": pkgUiStaticReactAssetManifestJson, + "pkg/ui/static/react/favicon.ico": pkgUiStaticReactFaviconIco, + "pkg/ui/static/react/index.html": pkgUiStaticReactIndexHtml, + "pkg/ui/static/react/manifest.json": pkgUiStaticReactManifestJson, + "pkg/ui/static/react/precache-manifest.5b38a4fc0bde14c6f31f0e40057889e9.js": pkgUiStaticReactPrecacheManifest5b38a4fc0bde14c6f31f0e40057889e9Js, + "pkg/ui/static/react/service-worker.js": pkgUiStaticReactServiceWorkerJs, + "pkg/ui/static/react/static/css/2.df42c974.chunk.css": pkgUiStaticReactStaticCss2Df42c974ChunkCss, + "pkg/ui/static/react/static/css/main.02392ede.chunk.css": pkgUiStaticReactStaticCssMain02392edeChunkCss, + "pkg/ui/static/react/static/js/2.b309ab18.chunk.js": pkgUiStaticReactStaticJs2B309ab18ChunkJs, + "pkg/ui/static/react/static/js/2.b309ab18.chunk.js.LICENSE.txt": pkgUiStaticReactStaticJs2B309ab18ChunkJsLicenseTxt, + "pkg/ui/static/react/static/js/main.bd8c49dc.chunk.js": pkgUiStaticReactStaticJsMainBd8c49dcChunkJs, + "pkg/ui/static/react/static/js/runtime-main.5db206b5.js": pkgUiStaticReactStaticJsRuntimeMain5db206b5Js, "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-grid.css": pkgUiStaticVendorBootstrap413CssBootstrapGridCss, "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-grid.min.css": pkgUiStaticVendorBootstrap413CssBootstrapGridMinCss, "pkg/ui/static/vendor/bootstrap-4.1.3/css/bootstrap-reboot.css": pkgUiStaticVendorBootstrap413CssBootstrapRebootCss, @@ -1634,9 +1877,8 @@ var _bindata = map[string]func() (*asset, error){ "pkg/ui/static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.css": pkgUiStaticVendorEonasdanBootstrapDatetimepickerBootstrapDatetimepickerMinCss, "pkg/ui/static/vendor/eonasdan-bootstrap-datetimepicker/bootstrap-datetimepicker.min.js": pkgUiStaticVendorEonasdanBootstrapDatetimepickerBootstrapDatetimepickerMinJs, "pkg/ui/static/vendor/fuzzy/fuzzy.js": pkgUiStaticVendorFuzzyFuzzyJs, - "pkg/ui/static/vendor/js/jquery-3.3.1.min.js": pkgUiStaticVendorJsJquery331MinJs, + "pkg/ui/static/vendor/js/jquery-3.5.0.min.js": pkgUiStaticVendorJsJquery350MinJs, "pkg/ui/static/vendor/js/jquery.hotkeys.js": pkgUiStaticVendorJsJqueryHotkeysJs, - "pkg/ui/static/vendor/js/jquery.min.js": pkgUiStaticVendorJsJqueryMinJs, "pkg/ui/static/vendor/js/jquery.selection.js": pkgUiStaticVendorJsJquerySelectionJs, "pkg/ui/static/vendor/js/popper.min.js": pkgUiStaticVendorJsPopperMinJs, "pkg/ui/static/vendor/moment/moment-timezone-with-data.min.js": pkgUiStaticVendorMomentMomentTimezoneWithDataMinJs, @@ -1708,6 +1950,26 @@ var _bintree = &bintree{nil, map[string]*bintree{ "graph.js": &bintree{pkgUiStaticJsGraphJs, map[string]*bintree{}}, "graph_template.handlebar": &bintree{pkgUiStaticJsGraph_templateHandlebar, map[string]*bintree{}}, }}, + "react": &bintree{nil, map[string]*bintree{ + "asset-manifest.json": &bintree{pkgUiStaticReactAssetManifestJson, map[string]*bintree{}}, + "favicon.ico": &bintree{pkgUiStaticReactFaviconIco, map[string]*bintree{}}, + "index.html": &bintree{pkgUiStaticReactIndexHtml, map[string]*bintree{}}, + "manifest.json": &bintree{pkgUiStaticReactManifestJson, map[string]*bintree{}}, + "precache-manifest.5b38a4fc0bde14c6f31f0e40057889e9.js": &bintree{pkgUiStaticReactPrecacheManifest5b38a4fc0bde14c6f31f0e40057889e9Js, map[string]*bintree{}}, + "service-worker.js": &bintree{pkgUiStaticReactServiceWorkerJs, map[string]*bintree{}}, + "static": &bintree{nil, map[string]*bintree{ + "css": &bintree{nil, map[string]*bintree{ + "2.df42c974.chunk.css": &bintree{pkgUiStaticReactStaticCss2Df42c974ChunkCss, map[string]*bintree{}}, + "main.02392ede.chunk.css": &bintree{pkgUiStaticReactStaticCssMain02392edeChunkCss, map[string]*bintree{}}, + }}, + "js": &bintree{nil, map[string]*bintree{ + "2.b309ab18.chunk.js": &bintree{pkgUiStaticReactStaticJs2B309ab18ChunkJs, map[string]*bintree{}}, + "2.b309ab18.chunk.js.LICENSE.txt": &bintree{pkgUiStaticReactStaticJs2B309ab18ChunkJsLicenseTxt, map[string]*bintree{}}, + "main.bd8c49dc.chunk.js": &bintree{pkgUiStaticReactStaticJsMainBd8c49dcChunkJs, map[string]*bintree{}}, + "runtime-main.5db206b5.js": &bintree{pkgUiStaticReactStaticJsRuntimeMain5db206b5Js, map[string]*bintree{}}, + }}, + }}, + }}, "vendor": &bintree{nil, map[string]*bintree{ "bootstrap-4.1.3": &bintree{nil, map[string]*bintree{ "css": &bintree{nil, map[string]*bintree{ @@ -1771,9 +2033,8 @@ var _bintree = &bintree{nil, map[string]*bintree{ "fuzzy.js": &bintree{pkgUiStaticVendorFuzzyFuzzyJs, map[string]*bintree{}}, }}, "js": &bintree{nil, map[string]*bintree{ - "jquery-3.3.1.min.js": &bintree{pkgUiStaticVendorJsJquery331MinJs, map[string]*bintree{}}, + "jquery-3.5.0.min.js": &bintree{pkgUiStaticVendorJsJquery350MinJs, map[string]*bintree{}}, "jquery.hotkeys.js": &bintree{pkgUiStaticVendorJsJqueryHotkeysJs, map[string]*bintree{}}, - "jquery.min.js": &bintree{pkgUiStaticVendorJsJqueryMinJs, map[string]*bintree{}}, "jquery.selection.js": &bintree{pkgUiStaticVendorJsJquerySelectionJs, map[string]*bintree{}}, "popper.min.js": &bintree{pkgUiStaticVendorJsPopperMinJs, map[string]*bintree{}}, }}, diff --git a/pkg/ui/bucket.go b/pkg/ui/bucket.go index 75e8c7b8b6..76e6591861 100644 --- a/pkg/ui/bucket.go +++ b/pkg/ui/bucket.go @@ -4,19 +4,24 @@ package ui import ( + "encoding/json" "html/template" "net/http" + "path" "time" "github.com/go-kit/kit/log" "github.com/prometheus/common/route" + "github.com/thanos-io/thanos/pkg/block/metadata" + "github.com/thanos-io/thanos/pkg/component" extpromhttp "github.com/thanos-io/thanos/pkg/extprom/http" ) // Bucket is a web UI representing state of buckets as a timeline. type Bucket struct { *BaseUI - flagsMap map[string]string + + externalPrefix, prefixHeader string // Unique Prometheus label that identifies each shard, used as the title. If // not present, all labels are displayed externally as a legend. Label string @@ -25,33 +30,54 @@ type Bucket struct { Err error } -func NewBucketUI(logger log.Logger, label string, flagsMap map[string]string) *Bucket { +func NewBucketUI(logger log.Logger, label, externalPrefix, prefixHeader string) *Bucket { return &Bucket{ - BaseUI: NewBaseUI(logger, "bucket_menu.html", queryTmplFuncs()), - Blocks: "[]", - Label: label, - flagsMap: flagsMap, + BaseUI: NewBaseUI(log.With(logger, "component", "bucketUI"), "bucket_menu.html", queryTmplFuncs(), externalPrefix, prefixHeader, component.Bucket), + Blocks: "[]", + Label: label, + externalPrefix: externalPrefix, + prefixHeader: prefixHeader, } } // Register registers http routes for bucket UI. func (b *Bucket) Register(r *route.Router, ins extpromhttp.InstrumentationMiddleware) { instrf := func(name string, next func(w http.ResponseWriter, r *http.Request)) http.HandlerFunc { - return ins.NewHandler(name, http.HandlerFunc(next)) + return ins.NewHandler(b.externalPrefix+name, http.HandlerFunc(next)) } - - r.Get("/", instrf("root", b.root)) - r.Get("/static/*filepath", instrf("static", b.serveStaticAsset)) + r.WithPrefix(b.externalPrefix).Get("/", instrf("root", b.root)) + r.WithPrefix(b.externalPrefix).Get("/static/*filepath", instrf("static", b.serveStaticAsset)) + // Make sure that "/new" is redirected to "/new/" and + // not just the naked "/new/", which would be the default behavior of the router + // with the "RedirectTrailingSlash" option (https://godoc.org/github.com/julienschmidt/httprouter#Router.RedirectTrailingSlash), + // and which breaks users with a --web.route-prefix that deviates from the path derived + // from the external URL. + r.WithPrefix(b.externalPrefix).Get("/new", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, path.Join(GetWebPrefix(b.logger, b.externalPrefix, b.prefixHeader, r), "new")+"/", http.StatusFound) + }) + r.WithPrefix(b.externalPrefix).Get("/new/*filepath", instrf("react-static", b.serveReactUI)) } // Handle / of bucket UIs. func (b *Bucket) root(w http.ResponseWriter, r *http.Request) { - prefix := GetWebPrefix(b.logger, b.flagsMap, r) - b.executeTemplate(w, "bucket.html", prefix, b) + b.executeTemplate(w, "bucket.html", GetWebPrefix(b.logger, b.externalPrefix, b.prefixHeader, r), b) } -func (b *Bucket) Set(data string, err error) { +func (b *Bucket) Set(blocks []metadata.Meta, err error) { + if err != nil { + // Last view is maintained. + b.RefreshedAt = time.Now() + b.Err = err + return + } + + data := "[]" + dataB, err := json.Marshal(blocks) + if err == nil { + data = string(dataB) + } + b.RefreshedAt = time.Now() - b.Blocks = template.JS(string(data)) + b.Blocks = template.JS(data) b.Err = err } diff --git a/pkg/ui/query.go b/pkg/ui/query.go index 37660c05bf..2231f99c8a 100644 --- a/pkg/ui/query.go +++ b/pkg/ui/query.go @@ -26,7 +26,7 @@ type Query struct { *BaseUI storeSet *query.StoreSet - flagsMap map[string]string + externalPrefix, prefixHeader string cwd string birth time.Time @@ -43,19 +43,20 @@ type thanosVersion struct { GoVersion string `json:"goVersion"` } -func NewQueryUI(logger log.Logger, reg prometheus.Registerer, storeSet *query.StoreSet, flagsMap map[string]string) *Query { +func NewQueryUI(logger log.Logger, reg prometheus.Registerer, storeSet *query.StoreSet, externalPrefix, prefixHeader string) *Query { cwd, err := os.Getwd() if err != nil { cwd = "" } return &Query{ - BaseUI: NewBaseUI(logger, "query_menu.html", queryTmplFuncs()), - storeSet: storeSet, - flagsMap: flagsMap, - cwd: cwd, - birth: time.Now(), - reg: reg, - now: model.Now, + BaseUI: NewBaseUI(logger, "query_menu.html", queryTmplFuncs(), externalPrefix, prefixHeader, component.Query), + storeSet: storeSet, + externalPrefix: externalPrefix, + prefixHeader: prefixHeader, + cwd: cwd, + birth: time.Now(), + reg: reg, + now: model.Now, } } @@ -83,6 +84,16 @@ func (q *Query) Register(r *route.Router, ins extpromhttp.InstrumentationMiddlew r.Get("/status", instrf("status", q.status)) r.Get("/static/*filepath", instrf("static", q.serveStaticAsset)) + // Make sure that "/new" is redirected to "/new/" and + // not just the naked "/new/", which would be the default behavior of the router + // with the "RedirectTrailingSlash" option (https://godoc.org/github.com/julienschmidt/httprouter#Router.RedirectTrailingSlash), + // and which breaks users with a --web.route-prefix that deviates from the path derived + // from the external URL. + r.Get("/new", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, path.Join(GetWebPrefix(q.logger, q.externalPrefix, q.prefixHeader, r), "new")+"/", http.StatusFound) + }) + r.Get("/new/*filepath", instrf("react-static", q.serveReactUI)) + // TODO(bplotka): Consider adding more Thanos related data e.g: // - What store nodes we see currently. // - What sidecars we see currently. @@ -90,19 +101,19 @@ func (q *Query) Register(r *route.Router, ins extpromhttp.InstrumentationMiddlew // Root redirects "/" requests to "/graph", taking into account the path prefix value. func (q *Query) root(w http.ResponseWriter, r *http.Request) { - prefix := GetWebPrefix(q.logger, q.flagsMap, r) + prefix := GetWebPrefix(q.logger, q.externalPrefix, q.prefixHeader, r) http.Redirect(w, r, path.Join(prefix, "/graph"), http.StatusFound) } func (q *Query) graph(w http.ResponseWriter, r *http.Request) { - prefix := GetWebPrefix(q.logger, q.flagsMap, r) + prefix := GetWebPrefix(q.logger, q.externalPrefix, q.prefixHeader, r) q.executeTemplate(w, "graph.html", prefix, nil) } func (q *Query) status(w http.ResponseWriter, r *http.Request) { - prefix := GetWebPrefix(q.logger, q.flagsMap, r) + prefix := GetWebPrefix(q.logger, q.externalPrefix, q.prefixHeader, r) q.executeTemplate(w, "status.html", prefix, struct { Birth time.Time @@ -123,7 +134,7 @@ func (q *Query) status(w http.ResponseWriter, r *http.Request) { } func (q *Query) stores(w http.ResponseWriter, r *http.Request) { - prefix := GetWebPrefix(q.logger, q.flagsMap, r) + prefix := GetWebPrefix(q.logger, q.externalPrefix, q.prefixHeader, r) statuses := make(map[component.StoreAPI][]query.StoreStatus) for _, status := range q.storeSet.GetStoreStatus() { statuses[status.StoreType] = append(statuses[status.StoreType], status) diff --git a/pkg/ui/react-app/.eslintrc.json b/pkg/ui/react-app/.eslintrc.json new file mode 100644 index 0000000000..395ca48af2 --- /dev/null +++ b/pkg/ui/react-app/.eslintrc.json @@ -0,0 +1,31 @@ +{ + "parser": "@typescript-eslint/parser", + "extends": [ + "react-app", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended" + ], + "rules": { + "@typescript-eslint/camelcase": "warn", + "eol-last": [ + "error", + "always" + ], + "object-curly-spacing": [ + "error", + "always" + ], + "prefer-const": "warn", + "comma-dangle": [ + "error", + { + "arrays": "always-multiline", + "objects": "always-multiline", + "imports": "always-multiline" + } + ] + }, + "plugins": [ + "prettier" + ] +} diff --git a/pkg/ui/react-app/.gitignore b/pkg/ui/react-app/.gitignore new file mode 100755 index 0000000000..4d29575de8 --- /dev/null +++ b/pkg/ui/react-app/.gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/pkg/ui/react-app/README.md b/pkg/ui/react-app/README.md new file mode 100755 index 0000000000..f9c67282cb --- /dev/null +++ b/pkg/ui/react-app/README.md @@ -0,0 +1,83 @@ +# Working with the React UI + +This file explains how to work with the React-based Thanos UI. + +## Introduction + +The [React-based](https://reactjs.org/) Thanos UI was was bootstrapped using [Create React App](https://github.com/facebook/create-react-app), a popular toolkit for generating React application setups. You can find general information about Create React App on [their documentation site](https://create-react-app.dev/). + +Instead of plain JavaScript, we use [TypeScript](https://www.typescriptlang.org/) to ensure typed code. + +## Development environment + +To work with the React UI code, you will need to have the following tools installed: + +* The [Node.js](https://nodejs.org/) JavaScript runtime. +* The [Yarn](https://yarnpkg.com/) package manager. +* *Recommended:* An editor with TypeScript, React, and [ESLint](https://eslint.org/) linting support. See e.g. [Create React App's editor setup instructions](https://create-react-app.dev/docs/setting-up-your-editor/). If you are not sure which editor to use, we recommend using [Visual Studio Code](https://code.visualstudio.com/docs/languages/typescript). Make sure that [the editor uses the project's TypeScript version rather than its own](https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-the-workspace-version-of-typescript). + +**NOTE**: When using Visual Studio Code, be sure to open the `pkg/ui/react-app` directory in the editor instead of the root of the repository. This way, the right ESLint and TypeScript configuration will be picked up from the React workspace. + +## Installing npm dependencies + +The React UI depends on a large number of [npm](https://www.npmjs.com/) packages. These are not checked in, so you will need to download and install them locally via the Yarn package manager: + + yarn + +Yarn consults the `package.json` and `yarn.lock` files for dependencies to install. It creates a `node_modules` directory with all installed dependencies. + +## Running a local development server + +You can start a development server for the React UI outside of a running Thanos server by running: + + yarn start + +This will open a browser window with the React app running on http://localhost:3000/. The page will reload if you make edits to the source code. You will also see any lint errors in the console. + +Due to a `"proxy": "http://localhost:10902"` setting in the `package.json` file, any API requests from the React UI are proxied to `localhost` on port `10902` by the development server. This allows you to run a normal Thanos Query server to handle API requests, while iterating separately on the UI. + + [browser] ----> [localhost:3000 (dev server)] --(proxy API requests)--> [localhost:10902 (Thanos)] + +## Running tests + +Create React App uses the [Jest](https://jestjs.io/) framework for running tests. To run tests in interactive watch mode: + + yarn test + +To generate an HTML-based test coverage report, run: + + CI=true yarn test --coverage + +This creates a `coverage` subdirectory with the generated report. Open `coverage/lcov-report/index.html` in the browser to view it. + +The `CI=true` environment variable prevents the tests from being run in interactive / watching mode. + +See the [Create React App documentation](https://create-react-app.dev/docs/running-tests/) for more information about running tests. + +## Linting + +We define linting rules for the [ESLint](https://eslint.org/) linter. We recommend integrating automated linting and fixing into your editor (e.g. upon save), but you can also run the linter separately from the command-line. + +To detect and automatically fix lint errors, run: + + yarn lint + +This is also available via the `react-app-lint-fix` target in the main Thanos `Makefile`. + +## Building the app for production + +To build a production-optimized version of the React app to a `build` subdirectory, run: + + yarn build + +**NOTE:** You will likely not need to do this directly. Instead, this is taken care of by the `assets` target in the main Thanos `Makefile` when building the full binary. + +## Integration into Thanos + +To build a Thanos binary that includes a compiled-in version of the production build of the React app, change to the root of the repository and run: + + make build + +This compiles in all web assets into the Thanos binary. + +Note that `make build` only compiles static assets using `bindata.go`, if you are working on React UI, make sure you run `make assets` to update `pkg/ui/bindata.go` diff --git a/pkg/ui/react-app/package.json b/pkg/ui/react-app/package.json new file mode 100644 index 0000000000..ccbec251d3 --- /dev/null +++ b/pkg/ui/react-app/package.json @@ -0,0 +1,96 @@ +{ + "name": "graph", + "version": "0.1.0", + "private": true, + "dependencies": { + "@fortawesome/fontawesome-svg-core": "^1.2.14", + "@fortawesome/free-solid-svg-icons": "^5.7.1", + "@fortawesome/react-fontawesome": "^0.1.4", + "@reach/router": "^1.2.1", + "@testing-library/react-hooks": "^3.1.1", + "@types/jest": "^24.0.20", + "@types/jquery": "^3.3.29", + "@types/node": "^12.11.1", + "@types/reach__router": "^1.2.6", + "@types/react": "^16.8.2", + "@types/react-copy-to-clipboard": "^4.3.0", + "@types/react-dom": "^16.8.0", + "@types/react-resize-detector": "^4.0.2", + "@types/sanitize-html": "^1.20.2", + "bootstrap": "^4.2.1", + "css.escape": "^1.5.1", + "downshift": "^3.2.2", + "enzyme-to-json": "^3.4.3", + "fuzzy": "^0.1.3", + "i": "^0.3.6", + "jest-fetch-mock": "^2.1.2", + "jquery": "^3.5.0", + "jquery.flot.tooltip": "^0.9.0", + "jsdom": "^15.2.0", + "moment": "^2.24.0", + "moment-timezone": "^0.5.23", + "popper.js": "^1.14.3", + "react": "^16.7.0", + "react-copy-to-clipboard": "^5.0.1", + "react-dom": "^16.7.0", + "react-resize-detector": "^4.2.1", + "react-scripts": "^3.4.0", + "react-test-renderer": "^16.9.0", + "reactstrap": "^8.0.1", + "sanitize-html": "^1.20.1", + "tempusdominus-bootstrap-4": "^5.1.2", + "tempusdominus-core": "^5.0.3", + "typescript": "^3.3.3" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test --runInBand", + "test:debug": "react-scripts --inspect-brk test --runInBand --no-cache", + "eject": "react-scripts eject", + "lint:ci": "eslint --quiet \"src/**/*.{ts,tsx}\"", + "lint": "eslint --fix \"src/**/*.{ts,tsx}\"" + }, + "prettier": { + "singleQuote": true, + "trailingComma": "es5", + "printWidth": 125 + }, + "browserslist": [ + ">0.2%", + "not dead", + "not ie <= 11", + "not op_mini all" + ], + "devDependencies": { + "@types/enzyme": "^3.10.3", + "@types/enzyme-adapter-react-16": "^1.0.5", + "@types/flot": "0.0.31", + "@types/moment-timezone": "^0.5.10", + "@types/reactstrap": "^8.0.5", + "@types/sinon": "^7.5.0", + "@typescript-eslint/eslint-plugin": "2.x", + "@typescript-eslint/parser": "2.x", + "babel-eslint": "10.x", + "enzyme": "^3.10.0", + "enzyme-adapter-react-16": "^1.15.1", + "eslint": "6.x", + "eslint-config-prettier": "^6.4.0", + "eslint-config-react-app": "^5.0.2", + "eslint-plugin-flowtype": "3.x", + "eslint-plugin-import": "2.x", + "eslint-plugin-jsx-a11y": "6.x", + "eslint-plugin-prettier": "^3.1.1", + "eslint-plugin-react": "7.x", + "eslint-plugin-react-hooks": "1.x", + "jest-fetch-mock": "^2.1.2", + "prettier": "^1.18.2", + "sinon": "^7.5.0" + }, + "proxy": "http://localhost:10902", + "jest": { + "snapshotSerializers": [ + "enzyme-to-json/serializer" + ] + } +} diff --git a/pkg/ui/react-app/public/favicon.ico b/pkg/ui/react-app/public/favicon.ico new file mode 100644 index 0000000000..265dd62bd2 Binary files /dev/null and b/pkg/ui/react-app/public/favicon.ico differ diff --git a/pkg/ui/react-app/public/index.html b/pkg/ui/react-app/public/index.html new file mode 100755 index 0000000000..7b9ec7e023 --- /dev/null +++ b/pkg/ui/react-app/public/index.html @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + Thanos Expression Browser + + + +
+ + + diff --git a/pkg/ui/react-app/public/manifest.json b/pkg/ui/react-app/public/manifest.json new file mode 100755 index 0000000000..67269d551a --- /dev/null +++ b/pkg/ui/react-app/public/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "Thanos", + "name": "Thanos web interface", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/pkg/ui/react-app/src/App.css b/pkg/ui/react-app/src/App.css new file mode 100644 index 0000000000..2e34f77a30 --- /dev/null +++ b/pkg/ui/react-app/src/App.css @@ -0,0 +1,253 @@ +.panel { + margin-bottom: 20px; +} + +input[type='checkbox']:checked + label { + color: #286090; +} + +.custom-control-label { + cursor: pointer; +} + +.togglers-wrapper .form-group { + margin-bottom: 0.5rem; +} + +[for$='-toggler'].custom-control-label::before, +[for$='-toggler'].custom-control-label::after { + top: 0.28rem; + left: -1.3rem; + width: 1.12rem; + height: 1.12rem; +} + +.capitalize-title::first-letter { + text-transform: capitalize; +} + +.expression-input { + margin-bottom: 10px; +} + +.expression-input textarea { + /* font-family: Menlo,Monaco,Consolas,'Courier New',monospace; */ + resize: none; + overflow: hidden; +} + +button.execute-btn { + width: 84px; +} + +.alert.alert-danger { + margin-bottom: 10px; +} + +.nav-tabs .nav-link { + cursor: pointer; +} + +.tab-content { + border-left: 1px solid #dee2e6; + border-right: 1px solid #dee2e6; + border-bottom: 1px solid #dee2e6; + padding: 10px; +} + +.tab-content .alert { + margin-bottom: 0; +} + +.data-table.table { + margin: 10px 0 2px 0; +} + +.data-table > tbody > tr > td { + padding: 5px 0 5px 8px; + font-size: 0.8em; + overflow: hidden; +} + +.autosuggest-dropdown { + position: absolute; + border: 1px solid #ced4da; + background-color: #fff; + color: #495057; + font-size: 1rem; + z-index: 1000; + left: 56px; + margin-top: -6px; +} + +.autosuggest-dropdown-list { + padding: 0; + margin: 0; + list-style: none; +} + +.autosuggest-dropdown-list li { + width: 100%; + padding: 0.25rem 1.5rem; + clear: both; + white-space: nowrap; + background-color: transparent; + border: 0; + display: block; +} + +.autosuggest-dropdown-list li.autosuggest-dropdown-header { + background-color: #bfdeff; + font-size: 10px; + line-height: 1.5; + text-transform: uppercase; + text-align: center; +} + +.graph-controls, +.table-controls { + margin-bottom: 10px; +} + +.graph-controls input, +.table-controls input { + text-align: center; +} + +.graph-controls .range-input input { + width: 50px; +} + +.time-input input { + border-right: none; +} + +.time-input { + width: 270px !important; +} + +.graph-controls input.resolution-input { + width: 90px; +} + +.graph-controls > :not(:first-child) { + margin-left: 20px; +} + +.graph-controls .clear-time-btn, +.table-controls .clear-time-btn { + background: #fff; + border-left: none; + border-top: 1px solid #ced4da; + border-bottom: 1px solid #ced4da; + color: #495057; +} + +.graph-legend { + margin: 15px 0 15px 55px; + font-size: 0.75em; + padding: 10px 5px; + display: inline-block; +} + +.legend-item { + cursor: pointer; + display: flex; + padding: 0 5px; + border-radius: 3px; + line-height: 1.7; +} +.legend-item div { + flex-wrap: wrap; +} + +.legend-swatch { + min-width: 7px; + height: 7px; + outline-offset: 1px; + outline: 1.5px solid #ccc; + margin: 6px 8px 2px 0; + display: inline-block; +} + +.legend-item:hover { + background: rgba(0, 0, 0, 0.18); +} + +.legend-metric-name { + margin-right: 1px; +} + +.legend-label-name { + font-weight: bold; +} + +.graph { + margin: 0 5px 0 5px; +} + +.graph-chart { + height: 500px; + width: 100%; + /* This is picked up by Flot's axis label font renderer, + which ignores "color" and uses "fill" instead. */ + fill: #495057; + font-size: 0.8em; +} + +.graph-chart .flot-overlay { + cursor: crosshair; +} + +.graph-tooltip { + background: rgba(0, 0, 0, 0.8); + color: #fff; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + white-space: nowrap; + padding: 8px; + border-radius: 3px; +} + +.graph-tooltip .labels { + font-size: 11px; + line-height: 11px; +} + +.graph-tooltip .detail-swatch { + display: inline-block; + width: 10px; + height: 10px; +} + +.add-panel-btn { + margin-bottom: 20px; +} + +.target-head { + font-weight: 700; + font-size: large; +} + +.group-info { + display: flex; + justify-content: space-between; + margin-bottom: 10px; + padding: 10px; +} + +.badges-wrapper > span { + margin-right: 5px; + max-height: 20px; +} + +.rules-head { + font-weight: 600; +} + +.rule_cell { + white-space: pre-wrap; + background-color: #f5f5f5; + display: block; + font-family: monospace; +} diff --git a/pkg/ui/react-app/src/App.test.tsx b/pkg/ui/react-app/src/App.test.tsx new file mode 100755 index 0000000000..6bc7434958 --- /dev/null +++ b/pkg/ui/react-app/src/App.test.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import App from './App'; +import Navigation from './thanos/Navbar'; +import { Container } from 'reactstrap'; +import { Router } from '@reach/router'; +import { Alerts, Config, Flags, Rules, ServiceDiscovery, Status, Targets, TSDBStatus, PanelList } from './pages'; + +describe('App', () => { + const app = shallow(); + + it('navigates', () => { + expect(app.find(Navigation)).toHaveLength(1); + }); + it('routes', () => { + [Alerts, Config, Flags, Rules, ServiceDiscovery, Status, Targets, TSDBStatus, PanelList].forEach(component => { + const c = app.find(component); + expect(c).toHaveLength(1); + expect(c.prop('pathPrefix')).toBe('/path/prefix'); + }); + expect(app.find(Router)).toHaveLength(1); + expect(app.find(Container)).toHaveLength(1); + }); +}); diff --git a/pkg/ui/react-app/src/App.tsx b/pkg/ui/react-app/src/App.tsx new file mode 100755 index 0000000000..81638cc0b5 --- /dev/null +++ b/pkg/ui/react-app/src/App.tsx @@ -0,0 +1,39 @@ +import React, { FC } from 'react'; +import { Container } from 'reactstrap'; +import { Router, Redirect } from '@reach/router'; + +import { Alerts, Config, Flags, Rules, ServiceDiscovery, Status, Targets, TSDBStatus, PanelList } from './pages'; +import PathPrefixProps from './types/PathPrefixProps'; +import ThanosComponentProps from './thanos/types/ThanosComponentProps'; +import Navigation from './thanos/Navbar'; + +import './App.css'; + +const App: FC = ({ pathPrefix, thanosComponent }) => { + return ( + <> + + + + + + {/* + NOTE: Any route added here needs to also be added to the list of + React-handled router paths ("reactRouterPaths") in /web/web.go. + */} + + + + + + + + + + + + + ); +}; + +export default App; diff --git a/pkg/ui/react-app/src/Navbar.test.tsx b/pkg/ui/react-app/src/Navbar.test.tsx new file mode 100644 index 0000000000..6a8a5b4cdf --- /dev/null +++ b/pkg/ui/react-app/src/Navbar.test.tsx @@ -0,0 +1,30 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import Navigation from './Navbar'; +import { NavItem, NavLink } from 'reactstrap'; + +describe('Navbar should contain console Link', () => { + it('with non-empty consoleslink', () => { + const app = shallow(); + expect( + app.contains( + + Consoles + + ) + ).toBeTruthy(); + }); +}); + +describe('Navbar should not contain consoles link', () => { + it('with empty string in consolesLink', () => { + const app = shallow(); + expect( + app.contains( + + Consoles + + ) + ).toBeFalsy(); + }); +}); diff --git a/pkg/ui/react-app/src/Navbar.tsx b/pkg/ui/react-app/src/Navbar.tsx new file mode 100644 index 0000000000..51c072add4 --- /dev/null +++ b/pkg/ui/react-app/src/Navbar.tsx @@ -0,0 +1,87 @@ +import React, { FC, useState } from 'react'; +import { Link } from '@reach/router'; +import { + Collapse, + Navbar, + NavbarToggler, + Nav, + NavItem, + NavLink, + UncontrolledDropdown, + DropdownToggle, + DropdownMenu, + DropdownItem, +} from 'reactstrap'; +import PathPrefixProps from './types/PathPrefixProps'; + +interface NavbarProps { + consolesLink: string | null; +} + +const Navigation: FC = ({ pathPrefix, consolesLink }) => { + const [isOpen, setIsOpen] = useState(false); + const toggle = () => setIsOpen(!isOpen); + return ( + + + + Prometheus + + + + + + ); +}; + +export default Navigation; diff --git a/pkg/ui/react-app/src/components/Checkbox.test.tsx b/pkg/ui/react-app/src/components/Checkbox.test.tsx new file mode 100755 index 0000000000..52258f72dd --- /dev/null +++ b/pkg/ui/react-app/src/components/Checkbox.test.tsx @@ -0,0 +1,65 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import Checkbox from './Checkbox'; +import { FormGroup, Label, Input } from 'reactstrap'; + +const MockCmp: React.FC = () =>
; + +describe('Checkbox', () => { + it('renders with subcomponents', () => { + const checkBox = shallow(); + [FormGroup, Input, Label].forEach(component => expect(checkBox.find(component)).toHaveLength(1)); + }); + + it('passes down the correct FormGroup props', () => { + const checkBoxProps = { wrapperStyles: { color: 'orange' } }; + const checkBox = shallow(); + const formGroup = checkBox.find(FormGroup); + expect(Object.keys(formGroup.props())).toHaveLength(4); + expect(formGroup.prop('className')).toEqual('custom-control custom-checkbox'); + expect(formGroup.prop('children')).toHaveLength(2); + expect(formGroup.prop('style')).toEqual({ color: 'orange' }); + expect(formGroup.prop('tag')).toEqual('div'); + }); + + it('passes down the correct FormGroup Input props', () => { + const results: string[] = []; + const checkBoxProps = { + onChange: (): void => { + results.push('clicked'); + }, + }; + const checkBox = shallow(); + const input = checkBox.find(Input); + expect(Object.keys(input.props())).toHaveLength(4); + expect(input.prop('className')).toEqual('custom-control-input'); + expect(input.prop('id')).toMatch('1'); + expect(input.prop('type')).toEqual('checkbox'); + input.simulate('change'); + expect(results).toHaveLength(1); + expect(results[0]).toEqual('clicked'); + }); + + it('passes down the correct Label props', () => { + const checkBox = shallow( + + + + ); + const label = checkBox.find(Label); + expect(Object.keys(label.props())).toHaveLength(6); + expect(label.prop('className')).toEqual('custom-control-label'); + expect(label.find(MockCmp)).toHaveLength(1); + expect(label.prop('for')).toMatch('1'); + expect(label.prop('style')).toEqual({ userSelect: 'none' }); + expect(label.prop('tag')).toEqual('label'); + }); + + it('shares checkbox `id` uuid with Input/Label subcomponents', () => { + const checkBox = shallow(); + const input = checkBox.find(Input); + const label = checkBox.find(Label); + expect(label.prop('for')).toBeDefined(); + expect(label.prop('for')).toEqual(input.prop('id')); + }); +}); diff --git a/pkg/ui/react-app/src/components/Checkbox.tsx b/pkg/ui/react-app/src/components/Checkbox.tsx new file mode 100644 index 0000000000..e988628f62 --- /dev/null +++ b/pkg/ui/react-app/src/components/Checkbox.tsx @@ -0,0 +1,19 @@ +import React, { FC, memo, CSSProperties } from 'react'; +import { FormGroup, Label, Input, InputProps } from 'reactstrap'; + +interface CheckboxProps extends InputProps { + wrapperStyles?: CSSProperties; +} + +const Checkbox: FC = ({ children, wrapperStyles, id, ...rest }) => { + return ( + + + + + ); +}; + +export default memo(Checkbox); diff --git a/pkg/ui/react-app/src/components/ToggleMoreLess.test.tsx b/pkg/ui/react-app/src/components/ToggleMoreLess.test.tsx new file mode 100644 index 0000000000..dc3c5a0f94 --- /dev/null +++ b/pkg/ui/react-app/src/components/ToggleMoreLess.test.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { Button } from 'reactstrap'; +import { ToggleMoreLess } from './ToggleMoreLess'; + +describe('ToggleMoreLess', () => { + const showMoreValue = false; + const defaultProps = { + event: (): void => { + tggleBtn.setProps({ showMore: !showMoreValue }); + }, + showMore: showMoreValue, + }; + const tggleBtn = shallow(); + + it('renders a show more btn at start', () => { + const btn = tggleBtn.find(Button); + expect(btn).toHaveLength(1); + expect(btn.prop('color')).toEqual('primary'); + expect(btn.prop('size')).toEqual('xs'); + expect(btn.render().text()).toEqual('show more'); + }); + + it('renders a show less btn if clicked', () => { + tggleBtn.find(Button).simulate('click'); + expect( + tggleBtn + .find(Button) + .render() + .text() + ).toEqual('show less'); + }); +}); diff --git a/pkg/ui/react-app/src/components/ToggleMoreLess.tsx b/pkg/ui/react-app/src/components/ToggleMoreLess.tsx new file mode 100644 index 0000000000..80abbcd1e9 --- /dev/null +++ b/pkg/ui/react-app/src/components/ToggleMoreLess.tsx @@ -0,0 +1,28 @@ +import React, { FC } from 'react'; +import { Button } from 'reactstrap'; + +interface ToggleMoreLessProps { + event(): void; + showMore: boolean; +} + +export const ToggleMoreLess: FC = ({ children, event, showMore }) => { + return ( +

+ {children} + +

+ ); +}; diff --git a/pkg/ui/react-app/src/components/withStatusIndicator.tsx b/pkg/ui/react-app/src/components/withStatusIndicator.tsx new file mode 100644 index 0000000000..b2d9f18b3d --- /dev/null +++ b/pkg/ui/react-app/src/components/withStatusIndicator.tsx @@ -0,0 +1,46 @@ +import React, { FC, ComponentType } from 'react'; +import { Alert } from 'reactstrap'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faSpinner } from '@fortawesome/free-solid-svg-icons'; + +interface StatusIndicatorProps { + error?: Error; + isLoading?: boolean; + customErrorMsg?: JSX.Element; + componentTitle?: string; +} + +export const withStatusIndicator = (Component: ComponentType): FC => ({ + error, + isLoading, + customErrorMsg, + componentTitle, + ...rest +}) => { + if (error) { + return ( + + {customErrorMsg ? ( + customErrorMsg + ) : ( + <> + Error: Error fetching {componentTitle || Component.displayName}: {error.message} + + )} + + ); + } + + if (isLoading) { + return ( + + ); + } + return ; +}; diff --git a/pkg/ui/react-app/src/globals.ts b/pkg/ui/react-app/src/globals.ts new file mode 100644 index 0000000000..58755cf86c --- /dev/null +++ b/pkg/ui/react-app/src/globals.ts @@ -0,0 +1,4 @@ +import jquery from 'jquery'; + +(window as any).jQuery = jquery; +(window as any).moment = require('moment'); diff --git a/pkg/ui/react-app/src/hooks/useFetch.ts b/pkg/ui/react-app/src/hooks/useFetch.ts new file mode 100644 index 0000000000..5f18b369a9 --- /dev/null +++ b/pkg/ui/react-app/src/hooks/useFetch.ts @@ -0,0 +1,34 @@ +import { useState, useEffect } from 'react'; + +export type APIResponse = { status: string; data: T }; + +export interface FetchState { + response: APIResponse; + error?: Error; + isLoading: boolean; +} + +export const useFetch = (url: string, options?: RequestInit): FetchState => { + const [response, setResponse] = useState>({ status: 'start fetching' } as any); + const [error, setError] = useState(); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + const fetchData = async () => { + setIsLoading(true); + try { + const res = await fetch(url, { cache: 'no-store', credentials: 'same-origin', ...options }); + if (!res.ok) { + throw new Error(res.statusText); + } + const json = (await res.json()) as APIResponse; + setResponse(json); + setIsLoading(false); + } catch (error) { + setError(error); + } + }; + fetchData(); + }, [url, options]); + return { response, error, isLoading }; +}; diff --git a/pkg/ui/react-app/src/hooks/useLocalStorage.test.tsx b/pkg/ui/react-app/src/hooks/useLocalStorage.test.tsx new file mode 100644 index 0000000000..680be78507 --- /dev/null +++ b/pkg/ui/react-app/src/hooks/useLocalStorage.test.tsx @@ -0,0 +1,27 @@ +import { useLocalStorage } from './useLocalStorage'; +import { renderHook, act } from '@testing-library/react-hooks'; + +describe('useLocalStorage', () => { + it('returns the initialState', () => { + const initialState = { a: 1, b: 2 }; + const { result } = renderHook(() => useLocalStorage('mystorage', initialState)); + expect(result.current[0]).toEqual(initialState); + }); + it('stores the initialState as serialized json in localstorage', () => { + const key = 'mystorage'; + const initialState = { a: 1, b: 2 }; + renderHook(() => useLocalStorage(key, initialState)); + expect(localStorage.getItem(key)).toEqual(JSON.stringify(initialState)); + }); + it('returns a setValue function that can reset local storage', () => { + const key = 'mystorage'; + const initialState = { a: 1, b: 2 }; + const { result } = renderHook(() => useLocalStorage(key, initialState)); + const newValue = { a: 2, b: 5 }; + act(() => { + result.current[1](newValue); + }); + expect(result.current[0]).toEqual(newValue); + expect(localStorage.getItem(key)).toEqual(JSON.stringify(newValue)); + }); +}); diff --git a/pkg/ui/react-app/src/hooks/useLocalStorage.tsx b/pkg/ui/react-app/src/hooks/useLocalStorage.tsx new file mode 100644 index 0000000000..75842e769d --- /dev/null +++ b/pkg/ui/react-app/src/hooks/useLocalStorage.tsx @@ -0,0 +1,13 @@ +import { Dispatch, SetStateAction, useEffect, useState } from 'react'; + +export function useLocalStorage(localStorageKey: string, initialState: S): [S, Dispatch>] { + const localStorageState = JSON.parse(localStorage.getItem(localStorageKey) || JSON.stringify(initialState)); + const [value, setValue] = useState(localStorageState); + + useEffect(() => { + const serializedState = JSON.stringify(value); + localStorage.setItem(localStorageKey, serializedState); + }, [localStorageKey, value]); + + return [value, setValue]; +} diff --git a/pkg/ui/react-app/src/index.tsx b/pkg/ui/react-app/src/index.tsx new file mode 100755 index 0000000000..f1133735e9 --- /dev/null +++ b/pkg/ui/react-app/src/index.tsx @@ -0,0 +1,25 @@ +import './globals'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; +import 'bootstrap/dist/css/bootstrap.min.css'; +import { isPresent } from './utils'; + +// Declared/defined in public/index.html, value replaced by Prometheus when serving bundle. +declare const GLOBAL_PATH_PREFIX: string; +declare const THANOS_COMPONENT: string; + +let prefix = GLOBAL_PATH_PREFIX; +if (GLOBAL_PATH_PREFIX === 'PATH_PREFIX_PLACEHOLDER' || GLOBAL_PATH_PREFIX === '/' || !isPresent(GLOBAL_PATH_PREFIX)) { + // Either we are running the app outside of Prometheus, so the placeholder value in + // the index.html didn't get replaced, or we have a '/' prefix, which we also need to + // normalize to '' to make concatenations work (prefixes like '/foo/bar/' already get + // their trailing slash stripped by Prometheus). + prefix = ''; +} +let thanosComponent = THANOS_COMPONENT; +if (THANOS_COMPONENT === '') { + thanosComponent = 'query'; +} + +ReactDOM.render(, document.getElementById('root')); diff --git a/pkg/ui/react-app/src/pages/alerts/AlertContents.tsx b/pkg/ui/react-app/src/pages/alerts/AlertContents.tsx new file mode 100644 index 0000000000..8f09e5f455 --- /dev/null +++ b/pkg/ui/react-app/src/pages/alerts/AlertContents.tsx @@ -0,0 +1,136 @@ +import React, { FC, useState, Fragment } from 'react'; +import { Badge } from 'reactstrap'; +import CollapsibleAlertPanel from './CollapsibleAlertPanel'; +import Checkbox from '../../components/Checkbox'; +import { isPresent } from '../../utils'; +import { Rule } from '../../types/types'; + +export type RuleState = keyof RuleStatus; + +export interface RuleStatus { + firing: T; + pending: T; + inactive: T; +} + +export interface AlertsProps { + groups?: RuleGroup[]; + statsCount: RuleStatus; +} + +export interface Alert { + labels: Record; + state: RuleState; + value: string; + annotations: Record; + activeAt: string; +} + +interface RuleGroup { + name: string; + file: string; + rules: Rule[]; + interval: number; +} + +const stateColorTuples: Array<[RuleState, 'success' | 'warning' | 'danger']> = [ + ['inactive', 'success'], + ['pending', 'warning'], + ['firing', 'danger'], +]; + +const AlertsContent: FC = ({ groups = [], statsCount }) => { + const [filter, setFilter] = useState>({ + firing: true, + pending: true, + inactive: true, + }); + const [showAnnotations, setShowAnnotations] = useState(false); + + const toggleFilter = (ruleState: RuleState) => () => { + setFilter({ + ...filter, + [ruleState]: !filter[ruleState], + }); + }; + + return ( + <> +
+ {stateColorTuples.map(([state, color]) => { + return ( + + + {state} ({statsCount[state]}) + + + ); + })} + setShowAnnotations(!showAnnotations)} + > + Show annotations + +
+ {groups.map((group, i) => { + const hasFilterOn = group.rules.some(rule => filter[rule.state]); + return hasFilterOn ? ( + + + {group.file} > {group.name} + + {group.rules.map((rule, j) => { + return ( + filter[rule.state] && ( + + ) + ); + })} + + ) : null; + })} + + ); +}; + +interface GroupInfoProps { + rules: Rule[]; +} + +export const GroupInfo: FC = ({ rules, children }) => { + const statesCounter = rules.reduce( + (acc, r) => { + return { + ...acc, + [r.state]: acc[r.state] + r.alerts.length, + }; + }, + { + firing: 0, + pending: 0, + } + ); + + return ( +
+ {children} +
+ {isPresent(statesCounter.inactive) && inactive} + {statesCounter.pending > 0 && pending ({statesCounter.pending})} + {statesCounter.firing > 0 && firing ({statesCounter.firing})} +
+
+ ); +}; + +AlertsContent.displayName = 'Alerts'; + +export default AlertsContent; diff --git a/pkg/ui/react-app/src/pages/alerts/Alerts.tsx b/pkg/ui/react-app/src/pages/alerts/Alerts.tsx new file mode 100644 index 0000000000..45e4ff1ffe --- /dev/null +++ b/pkg/ui/react-app/src/pages/alerts/Alerts.tsx @@ -0,0 +1,26 @@ +import React, { FC } from 'react'; +import { RouteComponentProps } from '@reach/router'; +import PathPrefixProps from '../../types/PathPrefixProps'; +import { useFetch } from '../../hooks/useFetch'; +import { withStatusIndicator } from '../../components/withStatusIndicator'; +import AlertsContent, { RuleStatus, AlertsProps } from './AlertContents'; + +const AlertsWithStatusIndicator = withStatusIndicator(AlertsContent); + +const Alerts: FC = ({ pathPrefix = '' }) => { + const { response, error, isLoading } = useFetch(`${pathPrefix}/api/v1/rules?type=alert`); + + const ruleStatsCount: RuleStatus = { + inactive: 0, + pending: 0, + firing: 0, + }; + + if (response.data && response.data.groups) { + response.data.groups.forEach(el => el.rules.forEach(r => ruleStatsCount[r.state]++)); + } + + return ; +}; + +export default Alerts; diff --git a/pkg/ui/react-app/src/pages/alerts/CollapsibleAlertPanel.tsx b/pkg/ui/react-app/src/pages/alerts/CollapsibleAlertPanel.tsx new file mode 100644 index 0000000000..02d700e3a9 --- /dev/null +++ b/pkg/ui/react-app/src/pages/alerts/CollapsibleAlertPanel.tsx @@ -0,0 +1,123 @@ +import React, { FC, useState, Fragment } from 'react'; +import { Link } from '@reach/router'; +import { Alert, Collapse, Table, Badge } from 'reactstrap'; +import { RuleStatus } from './AlertContents'; +import { Rule } from '../../types/types'; +import { faChevronDown, faChevronRight } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { createExpressionLink } from '../../utils/index'; + +interface CollapsibleAlertPanelProps { + rule: Rule; + showAnnotations: boolean; +} + +const alertColors: RuleStatus = { + firing: 'danger', + pending: 'warning', + inactive: 'success', +}; + +const CollapsibleAlertPanel: FC = ({ rule, showAnnotations }) => { + const [open, toggle] = useState(false); + + return ( + <> + toggle(!open)} color={alertColors[rule.state]} style={{ cursor: 'pointer' }}> + + {rule.name} ({`${rule.alerts.length} active`}) + + +
+          
+            
+ name: {rule.name} +
+
+ expr: {rule.query} +
+
+
labels:
+
severity: {rule.labels.severity}
+
+
+
annotations:
+
summary: {rule.annotations.summary}
+
+
+
+ {rule.alerts.length > 0 && ( + + + + + + + + + + + {rule.alerts.map((alert, i) => { + return ( + + + + + + + + {showAnnotations && } + + ); + })} + +
LabelsStateActive SinceValue
+ {Object.entries(alert.labels).map(([k, v], j) => { + return ( + + {k}={v} + + ); + })} + +
+ + {alert.state} + +
+
{alert.activeAt}{alert.value}
+ )} +
+ + ); +}; + +interface AnnotationsProps { + annotations: Record; +} + +export const Annotations: FC = ({ annotations }) => { + return ( + + + +
Annotations
+ + + + + {Object.entries(annotations).map(([k, v], i) => { + return ( +
+ {k} +
{v}
+
+ ); + })} + + +
+ ); +}; + +export default CollapsibleAlertPanel; diff --git a/pkg/ui/react-app/src/pages/config/Config.css b/pkg/ui/react-app/src/pages/config/Config.css new file mode 100644 index 0000000000..afe3aad7f1 --- /dev/null +++ b/pkg/ui/react-app/src/pages/config/Config.css @@ -0,0 +1,10 @@ +.config-yaml { + display: block; + padding: 10px; + font-size: 13px; + color: #333; + word-break: break-all; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} diff --git a/pkg/ui/react-app/src/pages/config/Config.tsx b/pkg/ui/react-app/src/pages/config/Config.tsx new file mode 100644 index 0000000000..1636668e6c --- /dev/null +++ b/pkg/ui/react-app/src/pages/config/Config.tsx @@ -0,0 +1,52 @@ +import React, { useState, FC } from 'react'; +import { RouteComponentProps } from '@reach/router'; +import { Button } from 'reactstrap'; +import CopyToClipboard from 'react-copy-to-clipboard'; +import PathPrefixProps from '../../types/PathPrefixProps'; + +import './Config.css'; +import { withStatusIndicator } from '../../components/withStatusIndicator'; +import { useFetch } from '../../hooks/useFetch'; + +type YamlConfig = { yaml?: string }; + +interface ConfigContentProps { + error?: Error; + data?: YamlConfig; +} + +const YamlContent = ({ yaml }: YamlConfig) =>
{yaml}
; +YamlContent.displayName = 'Config'; + +const ConfigWithStatusIndicator = withStatusIndicator(YamlContent); + +export const ConfigContent: FC = ({ error, data }) => { + const [copied, setCopied] = useState(false); + const config = data && data.yaml; + return ( + <> +

+ Configuration  + { + setCopied(result); + setTimeout(setCopied, 1500); + }} + > + + +

+ + + ); +}; + +const Config: FC = ({ pathPrefix }) => { + const { response, error } = useFetch(`${pathPrefix}/api/v1/status/config`); + return ; +}; + +export default Config; diff --git a/pkg/ui/react-app/src/pages/flags/Flags.test.tsx b/pkg/ui/react-app/src/pages/flags/Flags.test.tsx new file mode 100644 index 0000000000..6c8c254c76 --- /dev/null +++ b/pkg/ui/react-app/src/pages/flags/Flags.test.tsx @@ -0,0 +1,65 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import { FlagsContent } from './Flags'; +import { Table } from 'reactstrap'; +import toJson from 'enzyme-to-json'; + +const sampleFlagsResponse = { + 'alertmanager.notification-queue-capacity': '10000', + 'alertmanager.timeout': '10s', + 'config.file': './documentation/examples/prometheus.yml', + 'log.format': 'logfmt', + 'log.level': 'info', + 'query.lookback-delta': '5m', + 'query.max-concurrency': '20', + 'query.max-samples': '50000000', + 'query.timeout': '2m', + 'rules.alert.for-grace-period': '10m', + 'rules.alert.for-outage-tolerance': '1h', + 'rules.alert.resend-delay': '1m', + 'storage.remote.flush-deadline': '1m', + 'storage.remote.read-concurrent-limit': '10', + 'storage.remote.read-max-bytes-in-frame': '1048576', + 'storage.remote.read-sample-limit': '50000000', + 'storage.tsdb.allow-overlapping-blocks': 'false', + 'storage.tsdb.max-block-duration': '36h', + 'storage.tsdb.min-block-duration': '2h', + 'storage.tsdb.no-lockfile': 'false', + 'storage.tsdb.path': 'data/', + 'storage.tsdb.retention': '0s', + 'storage.tsdb.retention.size': '0B', + 'storage.tsdb.retention.time': '0s', + 'storage.tsdb.wal-compression': 'false', + 'storage.tsdb.wal-segment-size': '0B', + 'web.console.libraries': 'console_libraries', + 'web.console.templates': 'consoles', + 'web.cors.origin': '.*', + 'web.enable-admin-api': 'false', + 'web.enable-lifecycle': 'false', + 'web.external-url': '', + 'web.listen-address': '0.0.0.0:9090', + 'web.max-connections': '512', + 'web.page-title': 'Prometheus Time Series Collection and Processing Server', + 'web.read-timeout': '5m', + 'web.route-prefix': '/', + 'web.user-assets': '', +}; + +describe('Flags', () => { + it('renders a table with properly configured props', () => { + const w = shallow(); + const table = w.find(Table); + expect(table.props()).toMatchObject({ + bordered: true, + size: 'sm', + striped: true, + }); + }); + it('should not fail if data is missing', () => { + expect(shallow()).toHaveLength(1); + }); + it('should match snapshot', () => { + const w = shallow(); + expect(toJson(w)).toMatchSnapshot(); + }); +}); diff --git a/pkg/ui/react-app/src/pages/flags/Flags.tsx b/pkg/ui/react-app/src/pages/flags/Flags.tsx new file mode 100644 index 0000000000..5f0a409650 --- /dev/null +++ b/pkg/ui/react-app/src/pages/flags/Flags.tsx @@ -0,0 +1,42 @@ +import React, { FC } from 'react'; +import { RouteComponentProps } from '@reach/router'; +import { Table } from 'reactstrap'; +import { withStatusIndicator } from '../../components/withStatusIndicator'; +import { useFetch } from '../../hooks/useFetch'; +import PathPrefixProps from '../../types/PathPrefixProps'; + +interface FlagMap { + [key: string]: string; +} + +interface FlagsProps { + data?: FlagMap; +} + +export const FlagsContent: FC = ({ data = {} }) => { + return ( + <> +

Command-Line Flags

+ + + {Object.keys(data).map(key => ( + + + + + ))} + +
{key}{data[key]}
+ + ); +}; +const FlagsWithStatusIndicator = withStatusIndicator(FlagsContent); + +FlagsContent.displayName = 'Flags'; + +const Flags: FC = ({ pathPrefix = '' }) => { + const { response, error, isLoading } = useFetch(`${pathPrefix}/api/v1/status/flags`); + return ; +}; + +export default Flags; diff --git a/pkg/ui/react-app/src/pages/flags/__snapshots__/Flags.test.tsx.snap b/pkg/ui/react-app/src/pages/flags/__snapshots__/Flags.test.tsx.snap new file mode 100644 index 0000000000..ae38259866 --- /dev/null +++ b/pkg/ui/react-app/src/pages/flags/__snapshots__/Flags.test.tsx.snap @@ -0,0 +1,395 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Flags should match snapshot 1`] = ` + +

+ Command-Line Flags +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ alertmanager.notification-queue-capacity + + 10000 +
+ alertmanager.timeout + + 10s +
+ config.file + + ./documentation/examples/prometheus.yml +
+ log.format + + logfmt +
+ log.level + + info +
+ query.lookback-delta + + 5m +
+ query.max-concurrency + + 20 +
+ query.max-samples + + 50000000 +
+ query.timeout + + 2m +
+ rules.alert.for-grace-period + + 10m +
+ rules.alert.for-outage-tolerance + + 1h +
+ rules.alert.resend-delay + + 1m +
+ storage.remote.flush-deadline + + 1m +
+ storage.remote.read-concurrent-limit + + 10 +
+ storage.remote.read-max-bytes-in-frame + + 1048576 +
+ storage.remote.read-sample-limit + + 50000000 +
+ storage.tsdb.allow-overlapping-blocks + + false +
+ storage.tsdb.max-block-duration + + 36h +
+ storage.tsdb.min-block-duration + + 2h +
+ storage.tsdb.no-lockfile + + false +
+ storage.tsdb.path + + data/ +
+ storage.tsdb.retention + + 0s +
+ storage.tsdb.retention.size + + 0B +
+ storage.tsdb.retention.time + + 0s +
+ storage.tsdb.wal-compression + + false +
+ storage.tsdb.wal-segment-size + + 0B +
+ web.console.libraries + + console_libraries +
+ web.console.templates + + consoles +
+ web.cors.origin + + .* +
+ web.enable-admin-api + + false +
+ web.enable-lifecycle + + false +
+ web.external-url + +
+ web.listen-address + + 0.0.0.0:9090 +
+ web.max-connections + + 512 +
+ web.page-title + + Prometheus Time Series Collection and Processing Server +
+ web.read-timeout + + 5m +
+ web.route-prefix + + / +
+ web.user-assets + +
+
+`; diff --git a/pkg/ui/react-app/src/pages/graph/DataTable.test.tsx b/pkg/ui/react-app/src/pages/graph/DataTable.test.tsx new file mode 100755 index 0000000000..1e4fbd4609 --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/DataTable.test.tsx @@ -0,0 +1,301 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import DataTable, { QueryResult } from './DataTable'; +import { Alert, Table } from 'reactstrap'; +import SeriesName from './SeriesName'; + +describe('DataTable', () => { + describe('when data is null', () => { + it('renders an alert', () => { + const table = shallow(); + const alert = table.find(Alert); + expect(Object.keys(alert.props())).toHaveLength(7); + expect(alert.prop('color')).toEqual('light'); + expect(alert.prop('children')).toEqual('No data queried yet'); + }); + }); + + describe('when data.result is empty', () => { + it('renders an alert', () => { + const dataTableProps: QueryResult = { + data: { + resultType: 'vector', + result: [], + }, + }; + const table = shallow(); + const alert = table.find(Alert); + expect(Object.keys(alert.props())).toHaveLength(7); + expect(alert.prop('color')).toEqual('secondary'); + expect(alert.prop('children')).toEqual('Empty query result'); + }); + }); + + describe('when resultType is a vector with values', () => { + const dataTableProps: QueryResult = { + data: { + resultType: 'vector', + result: [ + { + metric: { + __name__: 'metric_name_1', + label1: 'value_1', + labeln: 'value_n', + }, + value: [1572098246.599, '0'], + }, + { + metric: { + __name__: 'metric_name_2', + label1: 'value_1', + labeln: 'value_n', + }, + value: [1572098246.599, '1'], + }, + ], + }, + }; + const dataTable = shallow(); + + it('renders a table', () => { + const table = dataTable.find(Table); + expect(table.prop('hover')).toBe(true); + expect(table.prop('size')).toEqual('sm'); + expect(table.prop('className')).toEqual('data-table'); + expect(table.find('tbody')).toHaveLength(1); + }); + + it('renders rows', () => { + const table = dataTable.find(Table); + table.find('tr').forEach((row, idx) => { + expect(row.find(SeriesName)).toHaveLength(1); + expect( + row + .find('td') + .at(1) + .text() + ).toEqual(`${idx}`); + }); + }); + }); + + describe('when resultType is a vector with too many values', () => { + const dataTableProps: QueryResult = { + data: { + resultType: 'vector', + result: Array.from(Array(10001).keys()).map(i => { + return { + metric: { + __name__: `metric_name_${i}`, + label1: 'value_1', + labeln: 'value_n', + }, + value: [1572098246.599, `${i}`], + }; + }), + }, + }; + const dataTable = shallow(); + + it('renders limited rows', () => { + const table = dataTable.find(Table); + expect(table.find('tr')).toHaveLength(10000); + }); + + it('renders a warning', () => { + const alerts = dataTable.find(Alert); + expect( + alerts + .first() + .render() + .text() + ).toEqual('Warning: Fetched 10001 metrics, only displaying first 10000.'); + }); + }); + + describe('when resultType is vector and size is more than maximum limit of formatting', () => { + const dataTableProps: QueryResult = { + data: { + resultType: 'vector', + result: Array.from(Array(1001).keys()).map(i => { + return { + metric: { + __name__: `metric_name_${i}`, + label1: 'value_1', + labeln: 'value_n', + }, + value: [1572098246.599, `${i}`], + }; + }), + }, + }; + const dataTable = shallow(); + + it('renders a warning', () => { + const alerts = dataTable.find(Alert); + expect( + alerts + .first() + .render() + .text() + ).toEqual('Notice: Showing more than 1000 series, turning off label formatting for performance reasons.'); + }); + }); + + describe('when result type is a matrix', () => { + const dataTableProps: QueryResult = { + data: { + resultType: 'matrix', + result: [ + { + metric: { + __name__: 'promhttp_metric_handler_requests_total', + code: '200', + instance: 'localhost:9090', + job: 'prometheus', + }, + values: [ + [1572097950.93, '9'], + [1572097965.931, '10'], + [1572097980.929, '11'], + [1572097995.931, '12'], + [1572098010.932, '13'], + [1572098025.933, '14'], + [1572098040.93, '15'], + [1572098055.93, '16'], + [1572098070.93, '17'], + [1572098085.936, '18'], + [1572098100.936, '19'], + [1572098115.933, '20'], + [1572098130.932, '21'], + [1572098145.932, '22'], + [1572098160.933, '23'], + [1572098175.934, '24'], + [1572098190.937, '25'], + [1572098205.934, '26'], + [1572098220.933, '27'], + [1572098235.934, '28'], + ], + }, + { + metric: { + __name__: 'promhttp_metric_handler_requests_total', + code: '500', + instance: 'localhost:9090', + job: 'prometheus', + }, + values: [ + [1572097950.93, '0'], + [1572097965.931, '0'], + [1572097980.929, '0'], + [1572097995.931, '0'], + [1572098010.932, '0'], + [1572098025.933, '0'], + [1572098040.93, '0'], + [1572098055.93, '0'], + [1572098070.93, '0'], + [1572098085.936, '0'], + [1572098100.936, '0'], + [1572098115.933, '0'], + [1572098130.932, '0'], + [1572098145.932, '0'], + [1572098160.933, '0'], + [1572098175.934, '0'], + [1572098190.937, '0'], + [1572098205.934, '0'], + [1572098220.933, '0'], + [1572098235.934, '0'], + ], + }, + { + metric: { + __name__: 'promhttp_metric_handler_requests_total', + code: '503', + instance: 'localhost:9090', + job: 'prometheus', + }, + values: [ + [1572097950.93, '0'], + [1572097965.931, '0'], + [1572097980.929, '0'], + [1572097995.931, '0'], + [1572098010.932, '0'], + [1572098025.933, '0'], + [1572098040.93, '0'], + [1572098055.93, '0'], + [1572098070.93, '0'], + [1572098085.936, '0'], + [1572098100.936, '0'], + [1572098115.933, '0'], + [1572098130.932, '0'], + [1572098145.932, '0'], + [1572098160.933, '0'], + [1572098175.934, '0'], + [1572098190.937, '0'], + [1572098205.934, '0'], + [1572098220.933, '0'], + [1572098235.934, '0'], + ], + }, + ], + }, + }; + const dataTable = shallow(); + it('renders rows', () => { + const table = dataTable.find(Table); + const rows = table.find('tr'); + expect(table.find('tr')).toHaveLength(3); + const row = rows.at(0); + expect(row.text()).toEqual(`9 @1572097950.93 +10 @1572097965.931 +11 @1572097980.929 +12 @1572097995.931 +13 @1572098010.932 +14 @1572098025.933 +15 @1572098040.93 +16 @1572098055.93 +17 @1572098070.93 +18 @1572098085.936 +19 @1572098100.936 +20 @1572098115.933 +21 @1572098130.932 +22 @1572098145.932 +23 @1572098160.933 +24 @1572098175.934 +25 @1572098190.937 +26 @1572098205.934 +27 @1572098220.933 +28 @1572098235.934`); + }); + }); + + describe('when resultType is a scalar', () => { + const dataTableProps: QueryResult = { + data: { + resultType: 'scalar', + result: [1572098246.599, '5'], + }, + }; + const dataTable = shallow(); + it('renders a scalar row', () => { + const table = dataTable.find(Table); + const rows = table.find('tr'); + expect(rows.text()).toEqual('scalar5'); + }); + }); + + describe('when resultType is a string', () => { + const dataTableProps: QueryResult = { + data: { + resultType: 'string', + result: 'string', + }, + }; + const dataTable = shallow(); + it('renders a string row', () => { + const table = dataTable.find(Table); + const rows = table.find('tr'); + expect(rows.text()).toEqual('stringt'); + }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/graph/DataTable.tsx b/pkg/ui/react-app/src/pages/graph/DataTable.tsx new file mode 100644 index 0000000000..592135e0ef --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/DataTable.tsx @@ -0,0 +1,137 @@ +import React, { FC, ReactNode } from 'react'; + +import { Alert, Table } from 'reactstrap'; + +import SeriesName from './SeriesName'; +import { Metric } from '../../types/types'; + +export interface QueryResult { + data: + | null + | { + resultType: 'vector'; + result: InstantSample[]; + } + | { + resultType: 'matrix'; + result: RangeSamples[]; + } + | { + resultType: 'scalar'; + result: SampleValue; + } + | { + resultType: 'string'; + result: string; + }; +} + +interface InstantSample { + metric: Metric; + value: SampleValue; +} + +interface RangeSamples { + metric: Metric; + values: SampleValue[]; +} + +type SampleValue = [number, string]; + +const limitSeries = (series: S[]): S[] => { + const maxSeries = 10000; + + if (series.length > maxSeries) { + return series.slice(0, maxSeries); + } + return series; +}; + +const DataTable: FC = ({ data }) => { + if (data === null) { + return No data queried yet; + } + + if (data.result === null || data.result.length === 0) { + return Empty query result; + } + + const maxFormattableSize = 1000; + let rows: ReactNode[] = []; + let limited = false; + const doFormat = data.result.length <= maxFormattableSize; + switch (data.resultType) { + case 'vector': + rows = (limitSeries(data.result) as InstantSample[]).map( + (s: InstantSample, index: number): ReactNode => { + return ( + + + + + {s.value[1]} + + ); + } + ); + limited = rows.length !== data.result.length; + break; + case 'matrix': + rows = (limitSeries(data.result) as RangeSamples[]).map((s, index) => { + const valueText = s.values + .map(v => { + return v[1] + ' @' + v[0]; + }) + .join('\n'); + return ( + + + + + {valueText} + + ); + }); + limited = rows.length !== data.result.length; + break; + case 'scalar': + rows.push( + + scalar + {data.result[1]} + + ); + break; + case 'string': + rows.push( + + string + {data.result[1]} + + ); + break; + default: + return Unsupported result value type; + } + + return ( + <> + {limited && ( + + Warning: Fetched {data.result.length} metrics, only displaying first {rows.length}. + + )} + {!doFormat && ( + + Notice: Showing more than {maxFormattableSize} series, turning off label formatting for + performance reasons. + + )} + + {rows} +
+ + ); +}; + +export default DataTable; diff --git a/pkg/ui/react-app/src/pages/graph/ExpressionInput.test.tsx b/pkg/ui/react-app/src/pages/graph/ExpressionInput.test.tsx new file mode 100644 index 0000000000..4b058416e2 --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/ExpressionInput.test.tsx @@ -0,0 +1,252 @@ +import * as React from 'react'; +import { mount, ReactWrapper } from 'enzyme'; +import ExpressionInput from './ExpressionInput'; +import Downshift from 'downshift'; +import { Button, InputGroup, InputGroupAddon, Input } from 'reactstrap'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faSearch, faSpinner } from '@fortawesome/free-solid-svg-icons'; + +const getKeyEvent = (key: string): React.KeyboardEvent => + ({ + key, + nativeEvent: {}, + preventDefault: () => { + // Do nothing. + }, + } as React.KeyboardEvent); + +describe('ExpressionInput', () => { + const metricNames = ['instance:node_cpu_utilisation:rate1m', 'node_cpu_guest_seconds_total', 'node_cpu_seconds_total']; + const expressionInputProps = { + value: 'node_cpu', + autocompleteSections: { + 'Query History': [], + 'Metric Names': metricNames, + }, + executeQuery: (): void => { + // Do nothing. + }, + onExpressionChange: (): void => { + // Do nothing. + }, + loading: false, + }; + + let expressionInput: ReactWrapper; + beforeEach(() => { + expressionInput = mount(); + }); + + it('renders a downshift component', () => { + const downshift = expressionInput.find(Downshift); + expect(downshift).toHaveLength(1); + }); + + it('renders an InputGroup', () => { + const inputGroup = expressionInput.find(InputGroup); + expect(inputGroup.prop('className')).toEqual('expression-input'); + }); + + it('renders a search icon when it is not loading', () => { + const addon = expressionInput.find(InputGroupAddon).filterWhere(addon => addon.prop('addonType') === 'prepend'); + const icon = addon.find(FontAwesomeIcon); + expect(icon.prop('icon')).toEqual(faSearch); + }); + + it('renders a loading icon when it is loading', () => { + const expressionInput = mount(); + const addon = expressionInput.find(InputGroupAddon).filterWhere(addon => addon.prop('addonType') === 'prepend'); + const icon = addon.find(FontAwesomeIcon); + expect(icon.prop('icon')).toEqual(faSpinner); + expect(icon.prop('spin')).toBe(true); + }); + + it('renders an Input', () => { + const input = expressionInput.find(Input); + expect(input.prop('style')).toEqual({ height: 0 }); + expect(input.prop('autoFocus')).toEqual(true); + expect(input.prop('type')).toEqual('textarea'); + expect(input.prop('rows')).toEqual('1'); + expect(input.prop('placeholder')).toEqual('Expression (press Shift+Enter for newlines)'); + expect(input.prop('value')).toEqual('node_cpu'); + }); + + describe('when autosuggest is closed', () => { + it('prevents Downshift default on Home, End, Arrows', () => { + const downshift = expressionInput.find(Downshift); + const input = downshift.find(Input); + downshift.setState({ isOpen: false }); + ['Home', 'End', 'ArrowUp', 'ArrowDown'].forEach(key => { + const event = getKeyEvent(key); + input.simulate('keydown', event); + const nativeEvent = event.nativeEvent as any; + expect(nativeEvent.preventDownshiftDefault).toBe(true); + }); + }); + + it('does not render an autosuggest', () => { + const downshift = expressionInput.find(Downshift); + downshift.setState({ isOpen: false }); + const ul = downshift.find('ul'); + expect(ul).toHaveLength(0); + }); + }); + + describe('handleInput', () => { + it('should call setState', () => { + const instance: any = expressionInput.instance(); + const stateSpy = jest.spyOn(instance, 'setState'); + instance.handleInput(); + expect(stateSpy).toHaveBeenCalled(); + }); + it('should call onExpressionChange', () => { + const spyOnExpressionChange = jest.fn(); + const props = { ...expressionInputProps, onExpressionChange: spyOnExpressionChange }; + const wrapper = mount(); + const input = wrapper.find(Input); + input.simulate('input', { target: { value: 'prometheus_engine_' } }); + expect(spyOnExpressionChange).toHaveBeenCalledTimes(1); + }); + }); + + describe('onSelect', () => { + it('should call setState with selected value', () => { + const instance: any = expressionInput.instance(); + const stateSpy = jest.spyOn(instance, 'setState'); + instance.setValue('foo'); + expect(stateSpy).toHaveBeenCalledWith({ height: 'auto' }, expect.anything()); + }); + }); + + describe('onClick', () => { + it('executes the query', () => { + const spyExecuteQuery = jest.fn(); + const props = { ...expressionInputProps, executeQuery: spyExecuteQuery }; + const wrapper = mount(); + const btn = wrapper.find(Button).filterWhere(btn => btn.hasClass('execute-btn')); + btn.simulate('click'); + expect(spyExecuteQuery).toHaveBeenCalledTimes(1); + }); + }); + + describe('handleKeyPress', () => { + it('should call executeQuery on Enter key pressed', () => { + const spyExecuteQuery = jest.fn(); + const input = mount(); + const instance: any = input.instance(); + instance.handleKeyPress({ preventDefault: jest.fn, key: 'Enter' }); + expect(spyExecuteQuery).toHaveBeenCalled(); + }); + it('should NOT call executeQuery on Enter + Shift', () => { + const spyExecuteQuery = jest.fn(); + const input = mount(); + const instance: any = input.instance(); + instance.handleKeyPress({ preventDefault: jest.fn, key: 'Enter', shiftKey: true }); + expect(spyExecuteQuery).not.toHaveBeenCalled(); + }); + }); + + describe('getSearchMatches', () => { + it('should return matched value', () => { + const instance: any = expressionInput.instance(); + expect(instance.getSearchMatches('foo', ['barfoobaz', 'bazasdbaz'])).toHaveLength(1); + }); + it('should return empty array if no match found', () => { + const instance: any = expressionInput.instance(); + expect(instance.getSearchMatches('foo', ['barbaz', 'bazasdbaz'])).toHaveLength(0); + }); + }); + + describe('createAutocompleteSection', () => { + it('should close menu if no matches found', () => { + const input = mount(); + const instance: any = input.instance(); + const spyCloseMenu = jest.fn(); + instance.createAutocompleteSection({ inputValue: 'qqqqqq', closeMenu: spyCloseMenu }); + setTimeout(() => { + expect(spyCloseMenu).toHaveBeenCalled(); + }); + }); + it('should not render lsit if inputValue not exist', () => { + const input = mount(); + const instance: any = input.instance(); + const spyCloseMenu = jest.fn(); + instance.createAutocompleteSection({ closeMenu: spyCloseMenu }); + setTimeout(() => expect(spyCloseMenu).toHaveBeenCalled()); + }); + it('should render autosuggest-dropdown', () => { + const input = mount(); + const instance: any = input.instance(); + const spyGetMenuProps = jest.fn(); + const sections = instance.createAutocompleteSection({ + inputValue: 'foo', + highlightedIndex: 0, + getMenuProps: spyGetMenuProps, + getItemProps: jest.fn, + }); + expect(sections.props.className).toEqual('autosuggest-dropdown'); + }); + }); + + describe('when downshift is open', () => { + it('closes the menu on "Enter"', () => { + const downshift = expressionInput.find(Downshift); + const input = downshift.find(Input); + downshift.setState({ isOpen: true }); + const event = getKeyEvent('Enter'); + input.simulate('keydown', event); + expect(downshift.state('isOpen')).toBe(false); + }); + + it('should blur input on escape', () => { + const downshift = expressionInput.find(Downshift); + const instance: any = expressionInput.instance(); + const spyBlur = jest.spyOn(instance.exprInputRef.current, 'blur'); + const input = downshift.find(Input); + downshift.setState({ isOpen: false }); + const event = getKeyEvent('Escape'); + input.simulate('keydown', event); + expect(spyBlur).toHaveBeenCalled(); + }); + + it('noops on ArrowUp or ArrowDown', () => { + const downshift = expressionInput.find(Downshift); + const input = downshift.find(Input); + downshift.setState({ isOpen: true }); + ['ArrowUp', 'ArrowDown'].forEach(key => { + const event = getKeyEvent(key); + input.simulate('keydown', event); + const nativeEvent = event.nativeEvent as any; + expect(nativeEvent.preventDownshiftDefault).toBeUndefined(); + }); + }); + + it('does not render an autosuggest if there are no matches', () => { + const downshift = expressionInput.find(Downshift); + downshift.setState({ isOpen: true }); + const ul = downshift.find('ul'); + expect(ul).toHaveLength(0); + }); + + it('renders an autosuggest if there are matches', () => { + const downshift = expressionInput.find(Downshift); + downshift.setState({ isOpen: true }); + setTimeout(() => { + const ul = downshift.find('ul'); + expect(ul.prop('className')).toEqual('card list-group'); + const items = ul.find('li'); + expect(items.map(item => item.text()).join(', ')).toEqual( + 'node_cpu_guest_seconds_total, node_cpu_seconds_total, instance:node_cpu_utilisation:rate1m' + ); + }); + }); + }); + + it('renders an execute Button', () => { + const addon = expressionInput.find(InputGroupAddon).filterWhere(addon => addon.prop('addonType') === 'append'); + const button = addon.find(Button); + expect(button.prop('className')).toEqual('execute-btn'); + expect(button.prop('color')).toEqual('primary'); + expect(button.text()).toEqual('Execute'); + }); +}); diff --git a/pkg/ui/react-app/src/pages/graph/ExpressionInput.tsx b/pkg/ui/react-app/src/pages/graph/ExpressionInput.tsx new file mode 100644 index 0000000000..7d2622abb0 --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/ExpressionInput.tsx @@ -0,0 +1,191 @@ +import React, { Component } from 'react'; +import { Button, InputGroup, InputGroupAddon, InputGroupText, Input } from 'reactstrap'; + +import Downshift, { ControllerStateAndHelpers } from 'downshift'; +import fuzzy from 'fuzzy'; +import sanitizeHTML from 'sanitize-html'; + +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faSearch, faSpinner } from '@fortawesome/free-solid-svg-icons'; + +interface ExpressionInputProps { + value: string; + onExpressionChange: (expr: string) => void; + autocompleteSections: { [key: string]: string[] }; + executeQuery: () => void; + loading: boolean; +} + +interface ExpressionInputState { + height: number | string; +} + +class ExpressionInput extends Component { + private exprInputRef = React.createRef(); + + constructor(props: ExpressionInputProps) { + super(props); + this.state = { + height: 'auto', + }; + } + + componentDidMount() { + this.setHeight(); + } + + setHeight = () => { + const { offsetHeight, clientHeight, scrollHeight } = this.exprInputRef.current!; + const offset = offsetHeight - clientHeight; // Needed in order for the height to be more accurate. + this.setState({ height: scrollHeight + offset }); + }; + + handleInput = () => { + this.setValue(this.exprInputRef.current!.value); + }; + + setValue = (value: string) => { + const { onExpressionChange } = this.props; + onExpressionChange(value); + this.setState({ height: 'auto' }, this.setHeight); + }; + + componentDidUpdate(prevProps: ExpressionInputProps) { + const { value } = this.props; + if (value !== prevProps.value) { + this.setValue(value); + } + } + + handleKeyPress = (event: React.KeyboardEvent) => { + const { executeQuery } = this.props; + if (event.key === 'Enter' && !event.shiftKey) { + executeQuery(); + event.preventDefault(); + } + }; + + getSearchMatches = (input: string, expressions: string[]) => { + return fuzzy.filter(input.replace(/ /g, ''), expressions, { + pre: '', + post: '', + }); + }; + + createAutocompleteSection = (downshift: ControllerStateAndHelpers) => { + const { inputValue = '', closeMenu, highlightedIndex } = downshift; + const { autocompleteSections } = this.props; + let index = 0; + const sections = inputValue!.length + ? Object.entries(autocompleteSections).reduce((acc, [title, items]) => { + const matches = this.getSearchMatches(inputValue!, items); + return !matches.length + ? acc + : [ + ...acc, +
    +
  • {title}
  • + {matches + .slice(0, 100) // Limit DOM rendering to 100 results, as DOM rendering is sloooow. + .map(({ original, string: text }) => { + const itemProps = downshift.getItemProps({ + key: original, + index, + item: original, + style: { + backgroundColor: highlightedIndex === index++ ? 'lightgray' : 'white', + }, + }); + return ( +
  • + ); + })} +
, + ]; + }, [] as JSX.Element[]) + : []; + + if (!sections.length) { + // This is ugly but is needed in order to sync state updates. + // This way we force downshift to wait React render call to complete before closeMenu to be triggered. + setTimeout(closeMenu); + return null; + } + + return ( +
+ {sections} +
+ ); + }; + + render() { + const { executeQuery, value } = this.props; + const { height } = this.state; + return ( + + {downshift => ( +
+ + + + {this.props.loading ? : } + + + { + switch (event.key) { + case 'Home': + case 'End': + // We want to be able to jump to the beginning/end of the input field. + // By default, Downshift otherwise jumps to the first/last suggestion item instead. + (event.nativeEvent as any).preventDownshiftDefault = true; + break; + case 'ArrowUp': + case 'ArrowDown': + if (!downshift.isOpen) { + (event.nativeEvent as any).preventDownshiftDefault = true; + } + break; + case 'Enter': + downshift.closeMenu(); + break; + case 'Escape': + if (!downshift.isOpen) { + this.exprInputRef.current!.blur(); + } + break; + default: + } + }, + } as any)} + value={value} + /> + + + + + {downshift.isOpen && this.createAutocompleteSection(downshift)} +
+ )} +
+ ); + } +} + +export default ExpressionInput; diff --git a/pkg/ui/react-app/src/pages/graph/Graph.test.tsx b/pkg/ui/react-app/src/pages/graph/Graph.test.tsx new file mode 100644 index 0000000000..bddd639462 --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/Graph.test.tsx @@ -0,0 +1,274 @@ +import * as React from 'react'; +import $ from 'jquery'; +import { shallow, mount } from 'enzyme'; +import Graph from './Graph'; +import ReactResizeDetector from 'react-resize-detector'; +import { Legend } from './Legend'; + +describe('Graph', () => { + beforeAll(() => { + jest.spyOn(window, 'requestAnimationFrame').mockImplementation((cb: any) => cb()); + }); + describe('data is returned', () => { + const props: any = { + queryParams: { + startTime: 1572128592, + endTime: 1572130692, + resolution: 28, + }, + stacked: false, + data: { + resultType: 'matrix', + result: [ + { + metric: { + code: '200', + handler: '/graph', + instance: 'localhost:9090', + job: 'prometheus', + }, + values: [ + [1572128592, '23'], + [1572128620, '2'], + [1572128648, '4'], + [1572128676, '1'], + [1572128704, '2'], + [1572128732, '12'], + [1572128760, '1'], + [1572128788, '0'], + [1572128816, '0'], + [1572128844, '2'], + [1572128872, '5'], + [1572130384, '6'], + [1572130412, '7'], + [1572130440, '19'], + [1572130468, '33'], + [1572130496, '14'], + [1572130524, '7'], + [1572130552, '6'], + [1572130580, '0'], + [1572130608, '0'], + [1572130636, '0'], + [1572130664, '0'], + [1572130692, '0'], + ], + }, + ], + }, + }; + it('renders a graph with props', () => { + const graph = shallow(); + const div = graph.find('div').filterWhere(elem => elem.prop('className') === 'graph'); + const resize = div.find(ReactResizeDetector); + const innerdiv = div.find('div').filterWhere(elem => elem.prop('className') === 'graph-chart'); + expect(resize.prop('handleWidth')).toBe(true); + expect(div).toHaveLength(1); + expect(innerdiv).toHaveLength(1); + }); + describe('Legend', () => { + it('renders a legend', () => { + const graph = shallow(); + expect(graph.find(Legend)).toHaveLength(1); + }); + }); + }); + describe('on component update', () => { + let graph: any; + let spyState: any; + let mockPlot: any; + beforeEach(() => { + mockPlot = jest.spyOn($, 'plot').mockReturnValue({ setData: jest.fn(), draw: jest.fn(), destroy: jest.fn() } as any); + graph = mount( + + ); + spyState = jest.spyOn(graph.instance(), 'setState'); + }); + afterEach(() => { + spyState.mockReset(); + mockPlot.mockReset(); + }); + it('should trigger state update when new data is received', () => { + graph.setProps({ data: { result: [{ values: [{}], metric: {} }] } }); + expect(spyState).toHaveBeenCalledWith( + { + chartData: [ + { + color: 'rgb(237,194,64)', + data: [[1572128592000, null]], + index: 0, + labels: {}, + }, + ], + }, + expect.anything() + ); + }); + it('should trigger state update when stacked prop is changed', () => { + graph.setProps({ stacked: false }); + expect(spyState).toHaveBeenCalledWith( + { + chartData: [ + { + color: 'rgb(237,194,64)', + data: [[1572128592000, null]], + index: 0, + labels: {}, + }, + ], + }, + expect.anything() + ); + }); + }); + describe('on unmount', () => { + it('should call destroy plot', () => { + const graph = mount( + + ); + const spyPlotDestroy = jest.spyOn(graph.instance(), 'componentWillUnmount'); + graph.unmount(); + expect(spyPlotDestroy).toHaveBeenCalledTimes(1); + spyPlotDestroy.mockReset(); + }); + }); + + describe('plot', () => { + it('should not call jquery.plot if chartRef not exist', () => { + const mockSetData = jest.fn(); + jest.spyOn($, 'plot').mockReturnValue({ setData: mockSetData, draw: jest.fn(), destroy: jest.fn() } as any); + const graph = shallow( + + ); + (graph.instance() as any).plot(); + expect(mockSetData).not.toBeCalled(); + }); + it('should call jquery.plot if chartRef exist', () => { + const mockPlot = jest + .spyOn($, 'plot') + .mockReturnValue({ setData: jest.fn(), draw: jest.fn(), destroy: jest.fn() } as any); + const graph = mount( + + ); + (graph.instance() as any).plot(); + expect(mockPlot).toBeCalled(); + }); + it('should destroy plot', () => { + const mockDestroy = jest.fn(); + jest.spyOn($, 'plot').mockReturnValue({ setData: jest.fn(), draw: jest.fn(), destroy: mockDestroy } as any); + const graph = mount( + + ); + (graph.instance() as any).plot(); + (graph.instance() as any).destroyPlot(); + expect(mockDestroy).toHaveBeenCalledTimes(2); + }); + }); + describe('plotSetAndDraw', () => { + it('should call spyPlotSetAndDraw on legend hover', () => { + jest.spyOn($, 'plot').mockReturnValue({ setData: jest.fn(), draw: jest.fn(), destroy: jest.fn() } as any); + const graph = mount( + + ); + (graph.instance() as any).plot(); // create chart + const spyPlotSetAndDraw = jest.spyOn(graph.instance() as any, 'plotSetAndDraw'); + graph + .find('.legend-item') + .at(0) + .simulate('mouseover'); + expect(spyPlotSetAndDraw).toHaveBeenCalledTimes(1); + }); + it('should call spyPlotSetAndDraw with chartDate from state as default value', () => { + const mockSetData = jest.fn(); + const spyPlot = jest + .spyOn($, 'plot') + .mockReturnValue({ setData: mockSetData, draw: jest.fn(), destroy: jest.fn() } as any); + const graph: any = mount( + + ); + (graph.instance() as any).plot(); // create chart + graph.find('.graph-legend').simulate('mouseout'); + expect(mockSetData).toHaveBeenCalledWith(graph.state().chartData); + spyPlot.mockReset(); + }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/graph/Graph.tsx b/pkg/ui/react-app/src/pages/graph/Graph.tsx new file mode 100644 index 0000000000..09b15c8252 --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/Graph.tsx @@ -0,0 +1,145 @@ +import $ from 'jquery'; +import React, { PureComponent } from 'react'; +import ReactResizeDetector from 'react-resize-detector'; + +import { Legend } from './Legend'; +import { Metric, QueryParams } from '../../types/types'; +import { isPresent } from '../../utils'; +import { normalizeData, getOptions, toHoverColor } from './GraphHelpers'; + +require('../../vendor/flot/jquery.flot'); +require('../../vendor/flot/jquery.flot.stack'); +require('../../vendor/flot/jquery.flot.time'); +require('../../vendor/flot/jquery.flot.crosshair'); +require('jquery.flot.tooltip'); + +export interface GraphProps { + data: { + resultType: string; + result: Array<{ metric: Metric; values: [number, string][] }>; + }; + stacked: boolean; + useLocalTime: boolean; + queryParams: QueryParams | null; +} + +export interface GraphSeries { + labels: { [key: string]: string }; + color: string; + data: (number | null)[][]; // [x,y][] + index: number; +} + +interface GraphState { + chartData: GraphSeries[]; +} + +class Graph extends PureComponent { + private chartRef = React.createRef(); + private $chart?: jquery.flot.plot; + private rafID = 0; + private selectedSeriesIndexes: number[] = []; + + state = { + chartData: normalizeData(this.props), + }; + + componentDidUpdate(prevProps: GraphProps) { + const { data, stacked, useLocalTime } = this.props; + if (prevProps.data !== data) { + this.selectedSeriesIndexes = []; + this.setState({ chartData: normalizeData(this.props) }, this.plot); + } else if (prevProps.stacked !== stacked) { + this.setState({ chartData: normalizeData(this.props) }, () => { + if (this.selectedSeriesIndexes.length === 0) { + this.plot(); + } else { + this.plot(this.state.chartData.filter((_, i) => this.selectedSeriesIndexes.includes(i))); + } + }); + } + + if (prevProps.useLocalTime !== useLocalTime) { + this.plot(); + } + } + + componentDidMount() { + this.plot(); + } + + componentWillUnmount() { + this.destroyPlot(); + } + + plot = (data: GraphSeries[] = this.state.chartData) => { + if (!this.chartRef.current) { + return; + } + this.destroyPlot(); + + this.$chart = $.plot($(this.chartRef.current), data, getOptions(this.props.stacked, this.props.useLocalTime)); + }; + + destroyPlot = () => { + if (isPresent(this.$chart)) { + this.$chart.destroy(); + } + }; + + plotSetAndDraw(data: GraphSeries[] = this.state.chartData) { + if (isPresent(this.$chart)) { + this.$chart.setData(data); + this.$chart.draw(); + } + } + + handleSeriesSelect = (selected: number[], selectedIndex: number) => { + const { chartData } = this.state; + this.plot( + this.selectedSeriesIndexes.length === 1 && this.selectedSeriesIndexes.includes(selectedIndex) + ? chartData.map(toHoverColor(selectedIndex, this.props.stacked)) + : chartData.filter((_, i) => selected.includes(i)) // draw only selected + ); + this.selectedSeriesIndexes = selected; + }; + + handleSeriesHover = (index: number) => () => { + if (this.rafID) { + cancelAnimationFrame(this.rafID); + } + this.rafID = requestAnimationFrame(() => { + this.plotSetAndDraw(this.state.chartData.map(toHoverColor(index, this.props.stacked))); + }); + }; + + handleLegendMouseOut = () => { + cancelAnimationFrame(this.rafID); + this.plotSetAndDraw(); + }; + + handleResize = () => { + if (isPresent(this.$chart)) { + this.plot(this.$chart.getData() as GraphSeries[]); + } + }; + + render() { + const { chartData } = this.state; + return ( +
+ +
+ +
+ ); + } +} + +export default Graph; diff --git a/pkg/ui/react-app/src/pages/graph/GraphControls.test.tsx b/pkg/ui/react-app/src/pages/graph/GraphControls.test.tsx new file mode 100755 index 0000000000..c81f61d15a --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/GraphControls.test.tsx @@ -0,0 +1,173 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import GraphControls from './GraphControls'; +import { Button, ButtonGroup, Form, InputGroup, InputGroupAddon, Input } from 'reactstrap'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faPlus, faMinus, faChartArea, faChartLine } from '@fortawesome/free-solid-svg-icons'; +import TimeInput from './TimeInput'; + +const defaultGraphControlProps = { + range: 60 * 60 * 24, + endTime: 1572100217898, + resolution: 10, + stacked: false, + + onChangeRange: (): void => { + // Do nothing. + }, + onChangeEndTime: (): void => { + // Do nothing. + }, + onChangeResolution: (): void => { + // Do nothing. + }, + onChangeStacking: (): void => { + // Do nothing. + }, +}; + +describe('GraphControls', () => { + it('renders a form', () => { + const controls = shallow(); + const form = controls.find(Form); + expect(form).toHaveLength(1); + expect(form.prop('className')).toEqual('graph-controls'); + expect(form.prop('inline')).toBe(true); + }); + + it('renders an Input Group for range', () => { + const controls = shallow(); + const form = controls.find(InputGroup); + expect(form).toHaveLength(1); + expect(form.prop('className')).toEqual('range-input'); + expect(form.prop('size')).toBe('sm'); + }); + + it('renders a decrease/increase range buttons', () => { + [ + { + position: 'prepend', + title: 'Decrease range', + icon: faMinus, + }, + { + position: 'append', + title: 'Increase range', + icon: faPlus, + }, + ].forEach(testCase => { + const controls = shallow(); + const addon = controls.find(InputGroupAddon).filterWhere(addon => addon.prop('addonType') === testCase.position); + const button = addon.find(Button); + const icon = button.find(FontAwesomeIcon); + expect(button.prop('title')).toEqual(testCase.title); + expect(icon).toHaveLength(1); + expect(icon.prop('icon')).toEqual(testCase.icon); + expect(icon.prop('fixedWidth')).toBe(true); + }); + }); + + it('renders an Input for range', () => { + const controls = shallow(); + const form = controls.find(InputGroup); + const input = form.find(Input); + expect(input).toHaveLength(1); + expect(input.prop('defaultValue')).toEqual('1d'); + expect(input.prop('innerRef')).toEqual({ current: null }); + }); + + it('renders a TimeInput with props', () => { + const controls = shallow(); + const timeInput = controls.find(TimeInput); + expect(timeInput).toHaveLength(1); + expect(timeInput.prop('time')).toEqual(1572100217898); + expect(timeInput.prop('range')).toEqual(86400); + expect(timeInput.prop('placeholder')).toEqual('End time'); + }); + + it('renders a TimeInput with a callback', () => { + const results: (number | null)[] = []; + const onChange = (endTime: number | null): void => { + results.push(endTime); + }; + const controls = shallow(); + const timeInput = controls.find(TimeInput); + const onChangeTime = timeInput.prop('onChangeTime'); + if (onChangeTime) { + onChangeTime(5); + expect(results).toHaveLength(1); + expect(results[0]).toEqual(5); + results.pop(); + } else { + fail('Expected onChangeTime to be defined but it was not'); + } + }); + + it('renders a resolution Input with props', () => { + const controls = shallow(); + const input = controls.find(Input).filterWhere(input => input.prop('className') === 'resolution-input'); + expect(input.prop('placeholder')).toEqual('Res. (s)'); + expect(input.prop('defaultValue')).toEqual('10'); + expect(input.prop('innerRef')).toEqual({ current: null }); + expect(input.prop('bsSize')).toEqual('sm'); + }); + + it('renders a button group', () => { + const controls = shallow(); + const group = controls.find(ButtonGroup); + expect(group.prop('className')).toEqual('stacked-input'); + expect(group.prop('size')).toEqual('sm'); + }); + + it('renders buttons inside the button group', () => { + [ + { + title: 'Show unstacked line graph', + icon: faChartLine, + active: true, + }, + { + title: 'Show stacked graph', + icon: faChartArea, + active: false, + }, + ].forEach(testCase => { + const controls = shallow(); + const group = controls.find(ButtonGroup); + const btn = group.find(Button).filterWhere(btn => btn.prop('title') === testCase.title); + expect(btn.prop('active')).toEqual(testCase.active); + const icon = btn.find(FontAwesomeIcon); + expect(icon.prop('icon')).toEqual(testCase.icon); + }); + }); + + it('renders buttons with callbacks', () => { + [ + { + title: 'Show unstacked line graph', + active: true, + }, + { + title: 'Show stacked graph', + active: false, + }, + ].forEach(testCase => { + const results: boolean[] = []; + const onChange = (stacked: boolean): void => { + results.push(stacked); + }; + const controls = shallow(); + const group = controls.find(ButtonGroup); + const btn = group.find(Button).filterWhere(btn => btn.prop('title') === testCase.title); + const onClick = btn.prop('onClick'); + if (onClick) { + onClick({} as React.MouseEvent); + expect(results).toHaveLength(1); + expect(results[0]).toBe(!testCase.active); + results.pop(); + } else { + fail('Expected onClick to be defined but it was not'); + } + }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/graph/GraphControls.tsx b/pkg/ui/react-app/src/pages/graph/GraphControls.tsx new file mode 100644 index 0000000000..dd75fb149b --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/GraphControls.tsx @@ -0,0 +1,150 @@ +import React, { Component } from 'react'; +import { Button, ButtonGroup, Form, InputGroup, InputGroupAddon, Input } from 'reactstrap'; + +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faPlus, faMinus, faChartArea, faChartLine } from '@fortawesome/free-solid-svg-icons'; + +import TimeInput from './TimeInput'; +import { parseRange, formatRange } from '../../utils'; + +interface GraphControlsProps { + range: number; + endTime: number | null; + useLocalTime: boolean; + resolution: number | null; + stacked: boolean; + + onChangeRange: (range: number) => void; + onChangeEndTime: (endTime: number | null) => void; + onChangeResolution: (resolution: number | null) => void; + onChangeStacking: (stacked: boolean) => void; +} + +class GraphControls extends Component { + private rangeRef = React.createRef(); + private resolutionRef = React.createRef(); + + rangeSteps = [ + 1, + 10, + 60, + 5 * 60, + 15 * 60, + 30 * 60, + 60 * 60, + 2 * 60 * 60, + 6 * 60 * 60, + 12 * 60 * 60, + 24 * 60 * 60, + 48 * 60 * 60, + 7 * 24 * 60 * 60, + 14 * 24 * 60 * 60, + 28 * 24 * 60 * 60, + 56 * 24 * 60 * 60, + 365 * 24 * 60 * 60, + 730 * 24 * 60 * 60, + ]; + + onChangeRangeInput = (rangeText: string): void => { + const range = parseRange(rangeText); + if (range === null) { + this.changeRangeInput(this.props.range); + } else { + this.props.onChangeRange(range); + } + }; + + changeRangeInput = (range: number): void => { + this.rangeRef.current!.value = formatRange(range); + }; + + increaseRange = (): void => { + for (const range of this.rangeSteps) { + if (this.props.range < range) { + this.changeRangeInput(range); + this.props.onChangeRange(range); + return; + } + } + }; + + decreaseRange = (): void => { + for (const range of this.rangeSteps.slice().reverse()) { + if (this.props.range > range) { + this.changeRangeInput(range); + this.props.onChangeRange(range); + return; + } + } + }; + + componentDidUpdate(prevProps: GraphControlsProps) { + if (prevProps.range !== this.props.range) { + this.changeRangeInput(this.props.range); + } + if (prevProps.resolution !== this.props.resolution) { + this.resolutionRef.current!.value = this.props.resolution !== null ? this.props.resolution.toString() : ''; + } + } + + render() { + return ( +
e.preventDefault()}> + + + + + + this.onChangeRangeInput(this.rangeRef.current!.value)} + /> + + + + + + + + + { + const res = parseInt(this.resolutionRef.current!.value); + this.props.onChangeResolution(res ? res : null); + }} + bsSize="sm" + /> + + + + + + + ); + } +} + +export default GraphControls; diff --git a/pkg/ui/react-app/src/pages/graph/GraphHelpers.test.ts b/pkg/ui/react-app/src/pages/graph/GraphHelpers.test.ts new file mode 100644 index 0000000000..a8ecd30fe4 --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/GraphHelpers.test.ts @@ -0,0 +1,206 @@ +import { formatValue, getColors, parseValue, getOptions } from './GraphHelpers'; +import moment from 'moment'; +require('../../vendor/flot/jquery.flot'); // need for $.colors + +describe('GraphHelpers', () => { + describe('formatValue', () => { + it('formats tick values correctly', () => { + [ + { input: null, output: 'null' }, + { input: 0, output: '0.00' }, + { input: 2e24, output: '2.00Y' }, + { input: 2e23, output: '200.00Z' }, + { input: 2e22, output: '20.00Z' }, + { input: 2e21, output: '2.00Z' }, + { input: 2e19, output: '20.00E' }, + { input: 2e18, output: '2.00E' }, + { input: 2e17, output: '200.00P' }, + { input: 2e16, output: '20.00P' }, + { input: 2e15, output: '2.00P' }, + { input: 1e15, output: '1.00P' }, + { input: 2e14, output: '200.00T' }, + { input: 2e13, output: '20.00T' }, + { input: 2e12, output: '2.00T' }, + { input: 2e11, output: '200.00G' }, + { input: 2e10, output: '20.00G' }, + { input: 2e9, output: '2.00G' }, + { input: 2e8, output: '200.00M' }, + { input: 2e7, output: '20.00M' }, + { input: 2e6, output: '2.00M' }, + { input: 2e5, output: '200.00k' }, + { input: 2e4, output: '20.00k' }, + { input: 2e3, output: '2.00k' }, + { input: 2e2, output: '200.00' }, + { input: 2e1, output: '20.00' }, + { input: 2, output: '2.00' }, + { input: 2e-1, output: '0.20' }, + { input: 2e-2, output: '0.02' }, + { input: 2e-3, output: '2.00m' }, + { input: 2e-4, output: '0.20m' }, + { input: 2e-5, output: '0.02m' }, + { input: 2e-6, output: '2.00µ' }, + { input: 2e-7, output: '0.20µ' }, + { input: 2e-8, output: '0.02µ' }, + { input: 2e-9, output: '2.00n' }, + { input: 2e-10, output: '0.20n' }, + { input: 2e-11, output: '0.02n' }, + { input: 2e-12, output: '2.00p' }, + { input: 2e-13, output: '0.20p' }, + { input: 2e-14, output: '0.02p' }, + { input: 2e-15, output: '2.00f' }, + { input: 2e-16, output: '0.20f' }, + { input: 2e-17, output: '0.02f' }, + { input: 2e-18, output: '2.00a' }, + { input: 2e-19, output: '0.20a' }, + { input: 2e-20, output: '0.02a' }, + { input: 1e-21, output: '1.00z' }, + { input: 2e-21, output: '2.00z' }, + { input: 2e-22, output: '0.20z' }, + { input: 2e-23, output: '0.02z' }, + { input: 2e-24, output: '2.00y' }, + { input: 2e-25, output: '0.20y' }, + { input: 2e-26, output: '0.02y' }, + ].map(t => { + expect(formatValue(t.input)).toBe(t.output); + }); + }); + it('should throw error if no match', () => { + try { + formatValue(undefined as any); + } catch (error) { + expect(error.message).toEqual("couldn't format a value, this is a bug"); + } + }); + }); + describe('getColors', () => { + it('should generate proper colors', () => { + const data: any = { + resultType: 'matrix', + result: [{}, {}, {}, {}, {}, {}, {}], + }; + expect( + getColors(data) + .map(c => c.toString()) + .join(',') + ).toEqual( + 'rgb(237,194,64),rgb(175,216,248),rgb(203,75,75),rgb(77,167,77),rgb(148,64,237),rgb(189,155,51),rgb(140,172,198)' + ); + }); + }); + describe('parseValue', () => { + it('should parse number properly', () => { + expect(parseValue('12.3e')).toEqual(12.3); + }); + it('should return 0 if value is NaN and stacked prop is true', () => { + expect(parseValue('asd')).toEqual(null); + }); + it('should return null if value is NaN and stacked prop is false', () => { + expect(parseValue('asd')).toBeNull(); + }); + }); + describe('Plot options', () => { + it('should configure options properly if stacked prop is true', () => { + expect(getOptions(true, false)).toMatchObject({ + series: { + stack: true, + lines: { lineWidth: 1, steps: false, fill: true }, + shadowSize: 0, + }, + }); + }); + it('should configure options properly if stacked prop is false', () => { + expect(getOptions(false, false)).toMatchObject({ + series: { + stack: false, + lines: { lineWidth: 2, steps: false, fill: false }, + shadowSize: 0, + }, + }); + }); + it('should configure options properly if useLocalTime prop is true', () => { + expect(getOptions(true, true)).toMatchObject({ + xaxis: { + mode: 'time', + showTicks: true, + showMinorTicks: true, + timeBase: 'milliseconds', + timezone: 'browser', + }, + }); + }); + it('should configure options properly if useLocalTime prop is false', () => { + expect(getOptions(false, false)).toMatchObject({ + xaxis: { + mode: 'time', + showTicks: true, + showMinorTicks: true, + timeBase: 'milliseconds', + }, + }); + }); + it('should return proper tooltip html from options', () => { + expect( + getOptions(true, false).tooltip.content('', 1572128592, 1572128592, { + series: { labels: { foo: '1', bar: '2' }, color: '' }, + } as any) + ).toEqual(` +
1970-01-19 04:42:08 +00:00
+
+ + value: 1572128592 +
+
+
foo: 1
bar: 2
+
+ `); + }); + it('should return proper tooltip html from options with local time', () => { + moment.tz.setDefault('America/New_York'); + expect( + getOptions(true, true).tooltip.content('', 1572128592, 1572128592, { + series: { labels: { foo: '1', bar: '2' }, color: '' }, + } as any) + ).toEqual(` +
1970-01-18 23:42:08 -05:00
+
+ + value: 1572128592 +
+
+
foo: 1
bar: 2
+
+ `); + }); + it('should render Plot with proper options', () => { + expect(getOptions(true, false)).toEqual({ + grid: { + hoverable: true, + clickable: true, + autoHighlight: true, + mouseActiveRadius: 100, + }, + legend: { show: false }, + xaxis: { + mode: 'time', + showTicks: true, + showMinorTicks: true, + timeBase: 'milliseconds', + }, + yaxis: { tickFormatter: expect.anything() }, + crosshair: { mode: 'xy', color: '#bbb' }, + tooltip: { + show: true, + cssClass: 'graph-tooltip', + content: expect.anything(), + defaultTheme: false, + lines: true, + }, + series: { + stack: true, + lines: { lineWidth: 1, steps: false, fill: true }, + shadowSize: 0, + }, + }); + }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/graph/GraphHelpers.ts b/pkg/ui/react-app/src/pages/graph/GraphHelpers.ts new file mode 100644 index 0000000000..4bd2f24426 --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/GraphHelpers.ts @@ -0,0 +1,197 @@ +import $ from 'jquery'; + +import { escapeHTML } from '../../utils'; +import { Metric } from '../../types/types'; +import { GraphProps, GraphSeries } from './Graph'; +import moment from 'moment-timezone'; + +export const formatValue = (y: number | null): string => { + if (y === null) { + return 'null'; + } + const absY = Math.abs(y); + + if (absY >= 1e24) { + return (y / 1e24).toFixed(2) + 'Y'; + } else if (absY >= 1e21) { + return (y / 1e21).toFixed(2) + 'Z'; + } else if (absY >= 1e18) { + return (y / 1e18).toFixed(2) + 'E'; + } else if (absY >= 1e15) { + return (y / 1e15).toFixed(2) + 'P'; + } else if (absY >= 1e12) { + return (y / 1e12).toFixed(2) + 'T'; + } else if (absY >= 1e9) { + return (y / 1e9).toFixed(2) + 'G'; + } else if (absY >= 1e6) { + return (y / 1e6).toFixed(2) + 'M'; + } else if (absY >= 1e3) { + return (y / 1e3).toFixed(2) + 'k'; + } else if (absY >= 1) { + return y.toFixed(2); + } else if (absY === 0) { + return y.toFixed(2); + } else if (absY < 1e-23) { + return (y / 1e-24).toFixed(2) + 'y'; + } else if (absY < 1e-20) { + return (y / 1e-21).toFixed(2) + 'z'; + } else if (absY < 1e-17) { + return (y / 1e-18).toFixed(2) + 'a'; + } else if (absY < 1e-14) { + return (y / 1e-15).toFixed(2) + 'f'; + } else if (absY < 1e-11) { + return (y / 1e-12).toFixed(2) + 'p'; + } else if (absY < 1e-8) { + return (y / 1e-9).toFixed(2) + 'n'; + } else if (absY < 1e-5) { + return (y / 1e-6).toFixed(2) + 'µ'; + } else if (absY < 1e-2) { + return (y / 1e-3).toFixed(2) + 'm'; + } else if (absY <= 1) { + return y.toFixed(2); + } + throw Error("couldn't format a value, this is a bug"); +}; + +export const getHoverColor = (color: string, opacity: number, stacked: boolean) => { + const { r, g, b } = $.color.parse(color); + if (!stacked) { + return `rgba(${r}, ${g}, ${b}, ${opacity})`; + } + /* + Unfortunately flot doesn't take into consideration + the alpha value when adjusting the color on the stacked series. + TODO: find better way to set the opacity. + */ + const base = (1 - opacity) * 255; + return `rgb(${Math.round(base + opacity * r)},${Math.round(base + opacity * g)},${Math.round(base + opacity * b)})`; +}; + +export const toHoverColor = (index: number, stacked: boolean) => (series: GraphSeries, i: number) => ({ + ...series, + color: getHoverColor(series.color, i !== index ? 0.3 : 1, stacked), +}); + +export const getOptions = (stacked: boolean, useLocalTime: boolean): jquery.flot.plotOptions => { + return { + grid: { + hoverable: true, + clickable: true, + autoHighlight: true, + mouseActiveRadius: 100, + }, + legend: { + show: false, + }, + xaxis: { + mode: 'time', + showTicks: true, + showMinorTicks: true, + timeBase: 'milliseconds', + timezone: useLocalTime ? 'browser' : undefined, + }, + yaxis: { + tickFormatter: formatValue, + }, + crosshair: { + mode: 'xy', + color: '#bbb', + }, + tooltip: { + show: true, + cssClass: 'graph-tooltip', + content: (_, xval, yval, { series }): string => { + const { labels, color } = series; + let dateTime = moment(xval); + if (!useLocalTime) { + dateTime = dateTime.utc(); + } + return ` +
${dateTime.format('YYYY-MM-DD HH:mm:ss Z')}
+
+ + ${labels.__name__ || 'value'}: ${yval} +
+
+ ${Object.keys(labels) + .map(k => + k !== '__name__' ? `
${k}: ${escapeHTML(labels[k])}
` : '' + ) + .join('')} +
+ `; + }, + defaultTheme: false, + lines: true, + }, + series: { + stack: stacked, + lines: { + lineWidth: stacked ? 1 : 2, + steps: false, + fill: stacked, + }, + shadowSize: 0, + }, + }; +}; + +// This was adapted from Flot's color generation code. +export const getColors = (data: { resultType: string; result: Array<{ metric: Metric; values: [number, string][] }> }) => { + const colorPool = ['#edc240', '#afd8f8', '#cb4b4b', '#4da74d', '#9440ed']; + const colorPoolSize = colorPool.length; + let variation = 0; + return data.result.map((_, i) => { + // Each time we exhaust the colors in the pool we adjust + // a scaling factor used to produce more variations on + // those colors. The factor alternates negative/positive + // to produce lighter/darker colors. + + // Reset the variation after every few cycles, or else + // it will end up producing only white or black colors. + + if (i % colorPoolSize === 0 && i) { + if (variation >= 0) { + variation = variation < 0.5 ? -variation - 0.2 : 0; + } else { + variation = -variation; + } + } + return $.color.parse(colorPool[i % colorPoolSize] || '#666').scale('rgb', 1 + variation); + }); +}; + +export const normalizeData = ({ queryParams, data }: GraphProps): GraphSeries[] => { + const colors = getColors(data); + const { startTime, endTime, resolution } = queryParams!; + return data.result.map(({ values, metric }, index) => { + // Insert nulls for all missing steps. + const data = []; + let pos = 0; + + for (let t = startTime; t <= endTime; t += resolution) { + // Allow for floating point inaccuracy. + const currentValue = values[pos]; + if (values.length > pos && currentValue[0] < t + resolution / 100) { + data.push([currentValue[0] * 1000, parseValue(currentValue[1])]); + pos++; + } else { + data.push([t * 1000, null]); + } + } + + return { + labels: metric !== null ? metric : {}, + color: colors[index].toString(), + data, + index, + }; + }); +}; + +export const parseValue = (value: string) => { + const val = parseFloat(value); + // "+Inf", "-Inf", "+Inf" will be parsed into NaN by parseFloat(). They + // can't be graphed, so show them as gaps (null). + return isNaN(val) ? null : val; +}; diff --git a/pkg/ui/react-app/src/pages/graph/GraphTabContent.test.tsx b/pkg/ui/react-app/src/pages/graph/GraphTabContent.test.tsx new file mode 100644 index 0000000000..591ab6eafa --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/GraphTabContent.test.tsx @@ -0,0 +1,45 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import { Alert } from 'reactstrap'; +import { GraphTabContent } from './GraphTabContent'; + +describe('GraphTabContent', () => { + it('renders an alert if data result type is different than "matrix"', () => { + const props: any = { + data: { resultType: 'invalid', result: [{}] }, + stacked: false, + queryParams: { + startTime: 1572100210000, + endTime: 1572100217898, + resolution: 10, + }, + color: 'danger', + children: `Query result is of wrong type '`, + }; + const graph = shallow(); + const alert = graph.find(Alert); + expect(alert.prop('color')).toEqual(props.color); + expect(alert.childAt(0).text()).toEqual(props.children); + }); + + it('renders an alert if data result empty', () => { + const props: any = { + data: { + resultType: 'matrix', + result: [], + }, + color: 'secondary', + children: 'Empty query result', + stacked: false, + queryParams: { + startTime: 1572100210000, + endTime: 1572100217898, + resolution: 10, + }, + }; + const graph = shallow(); + const alert = graph.find(Alert); + expect(alert.prop('color')).toEqual(props.color); + expect(alert.childAt(0).text()).toEqual(props.children); + }); +}); diff --git a/pkg/ui/react-app/src/pages/graph/GraphTabContent.tsx b/pkg/ui/react-app/src/pages/graph/GraphTabContent.tsx new file mode 100644 index 0000000000..2350cb117e --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/GraphTabContent.tsx @@ -0,0 +1,27 @@ +import React, { FC } from 'react'; +import { Alert } from 'reactstrap'; +import Graph from './Graph'; +import { QueryParams } from '../../types/types'; +import { isPresent } from '../../utils'; + +interface GraphTabContentProps { + data: any; + stacked: boolean; + useLocalTime: boolean; + lastQueryParams: QueryParams | null; +} + +export const GraphTabContent: FC = ({ data, stacked, useLocalTime, lastQueryParams }) => { + if (!isPresent(data)) { + return No data queried yet; + } + if (data.result.length === 0) { + return Empty query result; + } + if (data.resultType !== 'matrix') { + return ( + Query result is of wrong type '{data.resultType}', should be 'matrix' (range vector). + ); + } + return ; +}; diff --git a/pkg/ui/react-app/src/pages/graph/Legend.tsx b/pkg/ui/react-app/src/pages/graph/Legend.tsx new file mode 100644 index 0000000000..8a4068897a --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/Legend.tsx @@ -0,0 +1,77 @@ +import React, { PureComponent, SyntheticEvent } from 'react'; +import SeriesName from './SeriesName'; +import { GraphSeries } from './Graph'; + +interface LegendProps { + chartData: GraphSeries[]; + shouldReset: boolean; + onLegendMouseOut: (ev: SyntheticEvent) => void; + onSeriesToggle: (selected: number[], index: number) => void; + onHover: (index: number) => (ev: SyntheticEvent) => void; +} + +interface LegendState { + selectedIndexes: number[]; +} + +export class Legend extends PureComponent { + state = { + selectedIndexes: [] as number[], + }; + componentDidUpdate(prevProps: LegendProps) { + if (this.props.shouldReset && prevProps.shouldReset !== this.props.shouldReset) { + this.setState({ selectedIndexes: [] }); + } + } + handleSeriesSelect = (index: number) => (ev: React.MouseEvent) => { + // TODO: add proper event type + const { selectedIndexes } = this.state; + + let selected = [index]; + if (ev.ctrlKey || ev.metaKey) { + const { chartData } = this.props; + if (selectedIndexes.includes(index)) { + selected = selectedIndexes.filter(idx => idx !== index); + } else { + selected = + // Flip the logic - In case none is selected ctrl + click should deselect clicked series. + selectedIndexes.length === 0 + ? chartData.reduce((acc, _, i) => (i === index ? acc : [...acc, i]), []) + : [...selectedIndexes, index]; // Select multiple. + } + } else if (selectedIndexes.length === 1 && selectedIndexes.includes(index)) { + selected = []; + } + + this.setState({ selectedIndexes: selected }); + this.props.onSeriesToggle(selected, index); + }; + + render() { + const { chartData, onLegendMouseOut, onHover } = this.props; + const { selectedIndexes } = this.state; + const canUseHover = chartData.length > 1 && selectedIndexes.length === 0; + + return ( +
+ {chartData.map(({ index, color, labels }) => ( +
1 ? this.handleSeriesSelect(index) : undefined} + onMouseOver={canUseHover ? onHover(index) : undefined} + key={index} + className="legend-item" + > + + +
+ ))} + {chartData.length > 1 && ( +
+ Click: select series, {navigator.platform.includes('Mac') ? 'CMD' : 'CTRL'} + click: toggle multiple series +
+ )} +
+ ); + } +} diff --git a/pkg/ui/react-app/src/pages/graph/Panel.test.tsx b/pkg/ui/react-app/src/pages/graph/Panel.test.tsx new file mode 100644 index 0000000000..6aad61e78e --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/Panel.test.tsx @@ -0,0 +1,142 @@ +import * as React from 'react'; +import { mount, shallow } from 'enzyme'; +import Panel, { PanelOptions, PanelType } from './Panel'; +import ExpressionInput from './ExpressionInput'; +import GraphControls from './GraphControls'; +import { NavLink, TabPane } from 'reactstrap'; +import TimeInput from './TimeInput'; +import DataTable from './DataTable'; +import { GraphTabContent } from './GraphTabContent'; + +const defaultProps = { + useLocalTime: false, + useDeduplication: true, + usePartialResponse: false, + options: { + expr: 'prometheus_engine', + type: PanelType.Table, + range: 10, + endTime: 1572100217898, + resolution: 28, + stacked: false, + }, + onOptionsChanged: (): void => { + // Do nothing. + }, + pastQueries: [], + metricNames: [ + 'prometheus_engine_queries', + 'prometheus_engine_queries_concurrent_max', + 'prometheus_engine_query_duration_seconds', + ], + removePanel: (): void => { + // Do nothing. + }, + onExecuteQuery: (): void => { + // Do nothing. + }, +}; + +describe('Panel', () => { + const panel = shallow(); + + it('renders an ExpressionInput', () => { + const input = panel.find(ExpressionInput); + expect(input.prop('value')).toEqual('prometheus_engine'); + expect(input.prop('autocompleteSections')).toEqual({ + 'Metric Names': [ + 'prometheus_engine_queries', + 'prometheus_engine_queries_concurrent_max', + 'prometheus_engine_query_duration_seconds', + ], + 'Query History': [], + }); + }); + + it('renders NavLinks', () => { + const results: PanelOptions[] = []; + const onOptionsChanged = (opts: PanelOptions): void => { + results.push(opts); + }; + const panel = shallow(); + const links = panel.find(NavLink); + [ + { panelType: 'Table', active: true }, + { panelType: 'Graph', active: false }, + ].forEach((tc: { panelType: string; active: boolean }, i: number) => { + const link = links.at(i); + const className = tc.active ? 'active' : ''; + expect(link.prop('className')).toEqual(className); + link.simulate('click'); + expect(results).toHaveLength(1); + expect(results[0].type).toEqual(tc.panelType.toLowerCase()); + results.pop(); + }); + }); + + it('renders a TabPane with a TimeInput and a DataTable when in table mode', () => { + const tab = panel.find(TabPane).filterWhere(tab => tab.prop('tabId') === 'table'); + const timeInput = tab.find(TimeInput); + expect(timeInput.prop('time')).toEqual(defaultProps.options.endTime); + expect(timeInput.prop('range')).toEqual(defaultProps.options.range); + expect(timeInput.prop('placeholder')).toEqual('Evaluation time'); + expect(tab.find(DataTable)).toHaveLength(1); + }); + + it('renders a TabPane with a Graph and GraphControls when in graph mode', () => { + const options = { + expr: 'prometheus_engine', + type: PanelType.Graph, + range: 10, + endTime: 1572100217898, + resolution: 28, + stacked: false, + }; + const graphPanel = mount(); + const controls = graphPanel.find(GraphControls); + graphPanel.setState({ data: { resultType: 'matrix', result: [] } }); + const graph = graphPanel.find(GraphTabContent); + expect(controls.prop('endTime')).toEqual(options.endTime); + expect(controls.prop('range')).toEqual(options.range); + expect(controls.prop('resolution')).toEqual(options.resolution); + expect(controls.prop('stacked')).toEqual(options.stacked); + expect(graph.prop('stacked')).toEqual(options.stacked); + }); + + describe('when switching between modes', () => { + [ + { from: PanelType.Table, to: PanelType.Graph }, + { from: PanelType.Graph, to: PanelType.Table }, + ].forEach(({ from, to }: { from: PanelType; to: PanelType }) => { + it(`${from} -> ${to} nulls out data`, () => { + const props = { + ...defaultProps, + options: { ...defaultProps.options, type: from }, + }; + const panel = shallow(); + const instance: any = panel.instance(); + panel.setState({ data: 'somedata' }); + expect(panel.state('data')).toEqual('somedata'); + instance.handleChangeType(to); + expect(panel.state('data')).toBeNull(); + }); + }); + }); + + describe('when changing query then time', () => { + it('executes the new query', () => { + const initialExpr = 'time()'; + const newExpr = 'time() - time()'; + const panel = shallow(); + const instance: any = panel.instance(); + instance.executeQuery(); + const executeQuerySpy = jest.spyOn(instance, 'executeQuery'); + //change query without executing + panel.setProps({ options: { ...defaultProps.options, expr: newExpr } }); + expect(executeQuerySpy).toHaveBeenCalledTimes(0); + //execute query implicitly with time change + panel.setProps({ options: { ...defaultProps.options, expr: newExpr, endTime: 1575744840 } }); + expect(executeQuerySpy).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/graph/Panel.tsx b/pkg/ui/react-app/src/pages/graph/Panel.tsx new file mode 100644 index 0000000000..4675dbf475 --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/Panel.tsx @@ -0,0 +1,322 @@ +import React, { Component } from 'react'; + +import { Alert, Button, Col, Nav, NavItem, NavLink, Row, TabContent, TabPane } from 'reactstrap'; + +import moment from 'moment-timezone'; + +import ExpressionInput from './ExpressionInput'; +import GraphControls from './GraphControls'; +import { GraphTabContent } from './GraphTabContent'; +import DataTable from './DataTable'; +import TimeInput from './TimeInput'; +import QueryStatsView, { QueryStats } from './QueryStatsView'; +import PathPrefixProps from '../../types/PathPrefixProps'; +import { QueryParams } from '../../types/types'; + +interface PanelProps { + options: PanelOptions; + onOptionsChanged: (opts: PanelOptions) => void; + useLocalTime: boolean; + useDeduplication: boolean; + usePartialResponse: boolean; + pastQueries: string[]; + metricNames: string[]; + removePanel: () => void; + onExecuteQuery: (query: string) => void; +} + +interface PanelState { + data: any; // TODO: Type data. + lastQueryParams: QueryParams | null; + loading: boolean; + error: string | null; + stats: QueryStats | null; + exprInputValue: string; +} + +export interface PanelOptions { + expr: string; + type: PanelType; + range: number; // Range in seconds. + endTime: number | null; // Timestamp in milliseconds. + resolution: number | null; // Resolution in seconds. + stacked: boolean; +} + +export enum PanelType { + Graph = 'graph', + Table = 'table', +} + +export const PanelDefaultOptions: PanelOptions = { + type: PanelType.Table, + expr: '', + range: 3600, + endTime: null, + resolution: null, + stacked: false, +}; + +class Panel extends Component { + private abortInFlightFetch: (() => void) | null = null; + + constructor(props: PanelProps) { + super(props); + + this.state = { + data: null, + lastQueryParams: null, + loading: false, + error: null, + stats: null, + exprInputValue: props.options.expr, + }; + } + + componentDidUpdate({ options: prevOpts }: PanelProps) { + const { endTime, range, resolution, type } = this.props.options; + if ( + prevOpts.endTime !== endTime || + prevOpts.range !== range || + prevOpts.resolution !== resolution || + prevOpts.type !== type + ) { + this.executeQuery(); + } + } + + componentDidMount() { + this.executeQuery(); + } + + executeQuery = (): void => { + const { exprInputValue: expr } = this.state; + const queryStart = Date.now(); + this.props.onExecuteQuery(expr); + if (this.props.options.expr !== expr) { + this.setOptions({ expr }); + } + if (expr === '') { + return; + } + + if (this.abortInFlightFetch) { + this.abortInFlightFetch(); + this.abortInFlightFetch = null; + } + + const abortController = new AbortController(); + this.abortInFlightFetch = () => abortController.abort(); + this.setState({ loading: true }); + + const endTime = this.getEndTime().valueOf() / 1000; // TODO: shouldn't valueof only work when it's a moment? + const startTime = endTime - this.props.options.range; + const resolution = this.props.options.resolution || Math.max(Math.floor(this.props.options.range / 250), 1); + const params: URLSearchParams = new URLSearchParams({ + query: expr, + dedup: this.props.useDeduplication.toString(), + partial_response: this.props.useDeduplication.toString(), + }); + + let path: string; + switch (this.props.options.type) { + case 'graph': + path = '/api/v1/query_range'; + params.append('start', startTime.toString()); + params.append('end', endTime.toString()); + params.append('step', resolution.toString()); + // TODO path prefix here and elsewhere. + break; + case 'table': + path = '/api/v1/query'; + params.append('time', endTime.toString()); + break; + default: + throw new Error('Invalid panel type "' + this.props.options.type + '"'); + } + + fetch(`${this.props.pathPrefix}${path}?${params}`, { + cache: 'no-store', + credentials: 'same-origin', + signal: abortController.signal, + }) + .then(resp => resp.json()) + .then(json => { + if (json.status !== 'success') { + throw new Error(json.error || 'invalid response JSON'); + } + + let resultSeries = 0; + if (json.data) { + const { resultType, result } = json.data; + if (resultType === 'scalar') { + resultSeries = 1; + } else if (result && result.length > 0) { + resultSeries = result.length; + } + } + + this.setState({ + error: null, + data: json.data, + lastQueryParams: { + startTime, + endTime, + resolution, + }, + stats: { + loadTime: Date.now() - queryStart, + resolution, + resultSeries, + }, + loading: false, + }); + this.abortInFlightFetch = null; + }) + .catch(error => { + if (error.name === 'AbortError') { + // Aborts are expected, don't show an error for them. + return; + } + this.setState({ + error: 'Error executing query: ' + error.message, + loading: false, + }); + }); + }; + + setOptions(opts: object): void { + const newOpts = { ...this.props.options, ...opts }; + this.props.onOptionsChanged(newOpts); + } + + handleExpressionChange = (expr: string): void => { + this.setState({ exprInputValue: expr }); + }; + + handleChangeRange = (range: number): void => { + this.setOptions({ range: range }); + }; + + getEndTime = (): number | moment.Moment => { + if (this.props.options.endTime === null) { + return moment(); + } + return this.props.options.endTime; + }; + + handleChangeEndTime = (endTime: number | null) => { + this.setOptions({ endTime: endTime }); + }; + + handleChangeResolution = (resolution: number | null) => { + this.setOptions({ resolution: resolution }); + }; + + handleChangeType = (type: PanelType) => { + this.setState({ data: null }); + this.setOptions({ type: type }); + }; + + handleChangeStacking = (stacked: boolean) => { + this.setOptions({ stacked: stacked }); + }; + + render() { + const { pastQueries, metricNames, options } = this.props; + return ( +
+ + + + + + + {this.state.error && {this.state.error}} + + + + + + + {options.type === 'table' && ( + <> +
+ +
+ + + )} +
+ + {this.props.options.type === 'graph' && ( + <> + + + + )} + +
+ +
+ + + + + +
+ ); + } +} + +export default Panel; diff --git a/pkg/ui/react-app/src/pages/graph/PanelList.test.tsx b/pkg/ui/react-app/src/pages/graph/PanelList.test.tsx new file mode 100755 index 0000000000..833921ef02 --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/PanelList.test.tsx @@ -0,0 +1,34 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import PanelList, { PanelListContent } from './PanelList'; +import Checkbox from '../../components/Checkbox'; +import { Button } from 'reactstrap'; +import Panel from './Panel'; + +describe('PanelList', () => { + it('renders query history and local time checkboxes', () => { + [ + { id: 'query-history-checkbox', label: 'Enable query history' }, + { id: 'use-local-time-checkbox', label: 'Use local time' }, + ].forEach((cb, idx) => { + const panelList = shallow(); + const checkbox = panelList.find(Checkbox).at(idx); + expect(checkbox.prop('id')).toEqual(cb.id); + expect(checkbox.prop('defaultChecked')).toBe(false); + expect(checkbox.children().text()).toBe(cb.label); + }); + }); + + it('renders panels', () => { + const panelList = shallow(); + const panels = panelList.find(Panel); + expect(panels.length).toBeGreaterThan(0); + }); + + it('renders a button to add a panel', () => { + const panelList = shallow(); + const btn = panelList.find(Button); + expect(btn.prop('color')).toEqual('primary'); + expect(btn.children().text()).toEqual('Add Panel'); + }); +}); diff --git a/pkg/ui/react-app/src/pages/graph/PanelList.tsx b/pkg/ui/react-app/src/pages/graph/PanelList.tsx new file mode 100644 index 0000000000..8fb22dbe44 --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/PanelList.tsx @@ -0,0 +1,202 @@ +import React, { FC, useState, useEffect } from 'react'; +import { RouteComponentProps } from '@reach/router'; +import { Alert, Button } from 'reactstrap'; + +import Panel, { PanelOptions, PanelDefaultOptions } from './Panel'; +import Checkbox from '../../components/Checkbox'; +import PathPrefixProps from '../../types/PathPrefixProps'; +import { generateID, decodePanelOptionsFromQueryString, encodePanelOptionsToQueryString, callAll } from '../../utils'; +import { useFetch } from '../../hooks/useFetch'; +import { useLocalStorage } from '../../hooks/useLocalStorage'; + +export type PanelMeta = { key: string; options: PanelOptions; id: string }; + +export const updateURL = (nextPanels: PanelMeta[]) => { + const query = encodePanelOptionsToQueryString(nextPanels); + window.history.pushState({}, '', query); +}; + +interface PanelListProps extends PathPrefixProps, RouteComponentProps { + panels: PanelMeta[]; + metrics: string[]; + useLocalTime: boolean; + queryHistoryEnabled: boolean; + useDeduplication: boolean; + usePartialResponse: boolean; +} + +export const PanelListContent: FC = ({ + metrics = [], + useLocalTime, + useDeduplication, + usePartialResponse, + pathPrefix, + queryHistoryEnabled, + ...rest +}) => { + const [panels, setPanels] = useState(rest.panels); + const [historyItems, setLocalStorageHistoryItems] = useLocalStorage('history', []); + + useEffect(() => { + !panels.length && addPanel(); + window.onpopstate = () => { + const panels = decodePanelOptionsFromQueryString(window.location.search); + if (panels.length > 0) { + setPanels(panels); + } + }; + // We want useEffect to act only as componentDidMount, but react still complains about the empty dependencies list. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const handleExecuteQuery = (query: string) => { + const isSimpleMetric = metrics.indexOf(query) !== -1; + if (isSimpleMetric || !query.length) { + return; + } + const extendedItems = historyItems.reduce( + (acc, metric) => { + return metric === query ? acc : [...acc, metric]; // Prevent adding query twice. + }, + [query] + ); + setLocalStorageHistoryItems(extendedItems.slice(0, 50)); + }; + + const addPanel = () => { + callAll( + setPanels, + updateURL + )([ + ...panels, + { + id: generateID(), + key: `${panels.length}`, + options: PanelDefaultOptions, + }, + ]); + }; + + return ( + <> + {panels.map(({ id, options }) => ( + + callAll(setPanels, updateURL)(panels.map(p => (id === p.id ? { ...p, options: opts } : p))) + } + removePanel={() => + callAll( + setPanels, + updateURL + )( + panels.reduce( + (acc, panel) => (panel.id !== id ? [...acc, { ...panel, key: `${acc.length}` }] : acc), + [] + ) + ) + } + useLocalTime={useLocalTime} + useDeduplication={useDeduplication} + usePartialResponse={usePartialResponse} + metricNames={metrics} + pastQueries={queryHistoryEnabled ? historyItems : []} + pathPrefix={pathPrefix} + /> + ))} + + + ); +}; + +const PanelList: FC = ({ pathPrefix = '' }) => { + const [delta, setDelta] = useState(0); + const [useLocalTime, setUseLocalTime] = useLocalStorage('use-local-time', false); + const [enableQueryHistory, setEnableQueryHistory] = useLocalStorage('enable-query-history', false); + const [useDeduplication, setUseDeduplication] = useLocalStorage('use-deduplication', true); + const [usePartialResponse, setUsePartialResponse] = useLocalStorage('use-partial-response', false); + + const { response: metricsRes, error: metricsErr } = useFetch(`${pathPrefix}/api/v1/label/__name__/values`); + + const browserTime = new Date().getTime() / 1000; + const { response: timeRes, error: timeErr } = useFetch<{ result: number[] }>(`${pathPrefix}/api/v1/query?query=time()`); + + useEffect(() => { + if (timeRes.data) { + const serverTime = timeRes.data.result[0]; + setDelta(Math.abs(browserTime - serverTime)); + } + /** + * React wants to include browserTime to useEffect dependencies list which will cause a delta change on every re-render + * Basically it's not recommended to disable this rule, but this is the only way to take control over the useEffect + * dependencies and to not include the browserTime variable. + **/ + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [timeRes.data]); + + return ( + <> + setEnableQueryHistory(target.checked)} + defaultChecked={enableQueryHistory} + > + Enable query history + + setUseLocalTime(target.checked)} + defaultChecked={useLocalTime} + > + Use local time + + setUseDeduplication(target.checked)} + defaultChecked={useDeduplication} + > + Use Deduplication + + setUsePartialResponse(target.checked)} + defaultChecked={usePartialResponse} + > + Use Partial Response + + {(delta > 30 || timeErr) && ( + + Warning: + {timeErr && `Unexpected response status when fetching server time: ${timeErr.message}`} + {delta >= 30 && + `Error fetching server time: Detected ${delta} seconds time difference between your browser and the server. Thanos relies on accurate time and time drift might cause unexpected query results.`} + + )} + {metricsErr && ( + + Warning: + Error fetching metrics list: Unexpected response status when fetching metric names: {metricsErr.message} + + )} + + + ); +}; + +export default PanelList; diff --git a/pkg/ui/react-app/src/pages/graph/QueryStatsView.css b/pkg/ui/react-app/src/pages/graph/QueryStatsView.css new file mode 100644 index 0000000000..4484eb1c1e --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/QueryStatsView.css @@ -0,0 +1,5 @@ +.query-stats{ + flex-grow: 1; + font-size: 0.7rem; + color: #71808e; +} diff --git a/pkg/ui/react-app/src/pages/graph/QueryStatsView.test.tsx b/pkg/ui/react-app/src/pages/graph/QueryStatsView.test.tsx new file mode 100755 index 0000000000..e04c914e1a --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/QueryStatsView.test.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import QueryStatsView from './QueryStatsView'; + +describe('QueryStatsView', () => { + it('renders props as query stats', () => { + const queryStatsProps = { + loadTime: 100, + resolution: 5, + resultSeries: 10000, + }; + const queryStatsView = shallow(); + expect(queryStatsView.prop('className')).toEqual('query-stats'); + expect(queryStatsView.children().prop('className')).toEqual('float-right'); + expect(queryStatsView.children().text()).toEqual('Load time: 100ms   Resolution: 5s   Result series: 10000'); + }); +}); diff --git a/pkg/ui/react-app/src/pages/graph/QueryStatsView.tsx b/pkg/ui/react-app/src/pages/graph/QueryStatsView.tsx new file mode 100644 index 0000000000..ba6db013cd --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/QueryStatsView.tsx @@ -0,0 +1,22 @@ +import React, { FC } from 'react'; +import './QueryStatsView.css'; + +export interface QueryStats { + loadTime: number; + resolution: number; + resultSeries: number; +} + +const QueryStatsView: FC = props => { + const { loadTime, resolution, resultSeries } = props; + + return ( +
+ + Load time: {loadTime}ms   Resolution: {resolution}s   Result series: {resultSeries} + +
+ ); +}; + +export default QueryStatsView; diff --git a/pkg/ui/react-app/src/pages/graph/SeriesName.test.tsx b/pkg/ui/react-app/src/pages/graph/SeriesName.test.tsx new file mode 100755 index 0000000000..4eaf68105c --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/SeriesName.test.tsx @@ -0,0 +1,81 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import SeriesName from './SeriesName'; + +describe('SeriesName', () => { + describe('with labels=null', () => { + const seriesNameProps = { + labels: null, + format: false, + }; + const seriesName = shallow(); + it('renders the string "scalar"', () => { + expect(seriesName.text()).toEqual('scalar'); + }); + }); + + describe('with labels defined and format false', () => { + const seriesNameProps = { + labels: { + __name__: 'metric_name', + label1: 'value_1', + label2: 'value_2', + label3: 'value_3', + }, + format: false, + }; + const seriesName = shallow(); + it('renders the series name as a string', () => { + expect(seriesName.text()).toEqual('metric_name{label1="value_1", label2="value_2", label3="value_3"}'); + }); + }); + + describe('with labels defined and format true', () => { + const seriesNameProps = { + labels: { + __name__: 'metric_name', + label1: 'value_1', + label2: 'value_2', + label3: 'value_3', + }, + format: true, + }; + const seriesName = shallow(); + it('renders the series name as a series of spans', () => { + expect(seriesName.children()).toHaveLength(6); + const testCases = [ + { name: 'metric_name', className: 'legend-metric-name' }, + { name: '{', className: 'legend-label-brace' }, + { name: 'label1', value: 'value_1', className: 'legend-label-name' }, + { name: 'label2', value: 'value_2', className: 'legend-label-name' }, + { name: 'label3', value: 'value_3', className: 'legend-label-name' }, + { name: '}', className: 'legend-label-brace' }, + ]; + testCases.forEach((tc, i) => { + const child = seriesName.childAt(i); + const text = child + .children() + .map(ch => ch.text()) + .join(''); + switch (child.children().length) { + case 1: + expect(text).toEqual(tc.name); + expect(child.prop('className')).toEqual(tc.className); + break; + case 3: + expect(text).toEqual(`${tc.name}="${tc.value}"`); + expect(child.childAt(0).prop('className')).toEqual('legend-label-name'); + expect(child.childAt(2).prop('className')).toEqual('legend-label-value'); + break; + case 4: + expect(text).toEqual(`, ${tc.name}="${tc.value}"`); + expect(child.childAt(1).prop('className')).toEqual('legend-label-name'); + expect(child.childAt(3).prop('className')).toEqual('legend-label-value'); + break; + default: + fail('incorrect number of children: ' + child.children().length); + } + }); + }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/graph/SeriesName.tsx b/pkg/ui/react-app/src/pages/graph/SeriesName.tsx new file mode 100644 index 0000000000..0fb8bd285b --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/SeriesName.tsx @@ -0,0 +1,52 @@ +import React, { FC } from 'react'; +import { metricToSeriesName } from '../../utils'; + +interface SeriesNameProps { + labels: { [key: string]: string } | null; + format: boolean; +} + +const SeriesName: FC = ({ labels, format }) => { + const renderFormatted = (): React.ReactElement => { + const labelNodes: React.ReactElement[] = []; + let first = true; + for (const label in labels) { + if (label === '__name__') { + continue; + } + + labelNodes.push( + + {!first && ', '} + {label}="{labels[label]}" + + ); + + if (first) { + first = false; + } + } + + return ( +
+ {labels!.__name__ || ''} + {'{'} + {labelNodes} + {'}'} +
+ ); + }; + + if (labels === null) { + return <>scalar; + } + + if (format) { + return renderFormatted(); + } + // Return a simple text node. This is much faster to scroll through + // for longer lists (hundreds of items). + return <>{metricToSeriesName(labels!)}; +}; + +export default SeriesName; diff --git a/pkg/ui/react-app/src/pages/graph/TimeInput.test.tsx b/pkg/ui/react-app/src/pages/graph/TimeInput.test.tsx new file mode 100644 index 0000000000..9c59c8014c --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/TimeInput.test.tsx @@ -0,0 +1,60 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import sinon from 'sinon'; +import TimeInput from './TimeInput'; +import { Button, InputGroup, InputGroupAddon, Input } from 'reactstrap'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faChevronLeft, faChevronRight, faTimes } from '@fortawesome/free-solid-svg-icons'; + +describe('TimeInput', () => { + const timeInputProps = { + time: 1572102237932, + range: 60 * 60 * 7, + placeholder: 'time input', + onChangeTime: (): void => { + // Do nothing. + }, + }; + const timeInput = shallow(); + it('renders the string "scalar"', () => { + const inputGroup = timeInput.find(InputGroup); + expect(inputGroup.prop('className')).toEqual('time-input'); + expect(inputGroup.prop('size')).toEqual('sm'); + }); + + it('renders buttons to adjust time', () => { + [ + { + position: 'prepend', + title: 'Decrease time', + icon: faChevronLeft, + }, + { + position: 'append', + title: 'Clear time', + icon: faTimes, + }, + { + position: 'append', + title: 'Increase time', + icon: faChevronRight, + }, + ].forEach(button => { + const onChangeTime = sinon.spy(); + const timeInput = shallow(); + const addon = timeInput.find(InputGroupAddon).filterWhere(addon => addon.prop('addonType') === button.position); + const btn = addon.find(Button).filterWhere(btn => btn.prop('title') === button.title); + const icon = btn.find(FontAwesomeIcon); + expect(icon.prop('icon')).toEqual(button.icon); + expect(icon.prop('fixedWidth')).toBe(true); + btn.simulate('click'); + expect(onChangeTime.calledOnce).toBe(true); + }); + }); + + it('renders an Input', () => { + const input = timeInput.find(Input); + expect(input.prop('placeholder')).toEqual(timeInputProps.placeholder); + expect(input.prop('innerRef')).toEqual({ current: null }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/graph/TimeInput.tsx b/pkg/ui/react-app/src/pages/graph/TimeInput.tsx new file mode 100644 index 0000000000..6f502abe70 --- /dev/null +++ b/pkg/ui/react-app/src/pages/graph/TimeInput.tsx @@ -0,0 +1,139 @@ +import $ from 'jquery'; +import React, { Component } from 'react'; +import { Button, InputGroup, InputGroupAddon, Input } from 'reactstrap'; + +import moment from 'moment-timezone'; + +import 'tempusdominus-core'; +import 'tempusdominus-bootstrap-4'; +import '../../../node_modules/tempusdominus-bootstrap-4/build/css/tempusdominus-bootstrap-4.min.css'; + +import { dom, library } from '@fortawesome/fontawesome-svg-core'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { + faChevronLeft, + faChevronRight, + faCalendarCheck, + faArrowUp, + faArrowDown, + faTimes, +} from '@fortawesome/free-solid-svg-icons'; + +library.add(faChevronLeft, faChevronRight, faCalendarCheck, faArrowUp, faArrowDown, faTimes); +// Sadly needed to also replace within the date picker, since it's not a React component. +dom.watch(); + +interface TimeInputProps { + time: number | null; // Timestamp in milliseconds. + useLocalTime: boolean; + range: number; // Range in seconds. + placeholder: string; + onChangeTime: (time: number | null) => void; +} + +class TimeInput extends Component { + private timeInputRef = React.createRef(); + private $time: any = null; + + getBaseTime = (): number => { + return this.props.time || moment().valueOf(); + }; + + calcShiftRange = () => (this.props.range * 1000) / 2; + + increaseTime = (): void => { + const time = this.getBaseTime() + this.calcShiftRange(); + this.props.onChangeTime(time); + }; + + decreaseTime = (): void => { + const time = this.getBaseTime() - this.calcShiftRange(); + this.props.onChangeTime(time); + }; + + clearTime = (): void => { + this.props.onChangeTime(null); + }; + + timezone = (): string => { + return this.props.useLocalTime ? moment.tz.guess() : 'UTC'; + }; + + componentDidMount() { + this.$time = $(this.timeInputRef.current!); + + this.$time.datetimepicker({ + icons: { + today: 'fas fa-calendar-check', + }, + buttons: { + //showClear: true, + showClose: true, + showToday: true, + }, + sideBySide: true, + format: 'YYYY-MM-DD HH:mm:ss', + locale: 'en', + timeZone: this.timezone(), + defaultDate: this.props.time, + }); + + this.$time.on('change.datetimepicker', (e: any) => { + if (e.date) { + this.props.onChangeTime(e.date.valueOf()); + } + }); + } + + componentWillUnmount() { + this.$time.datetimepicker('destroy'); + } + + componentDidUpdate(prevProps: TimeInputProps) { + const { time, useLocalTime } = this.props; + if (prevProps.time !== time) { + this.$time.datetimepicker('date', time ? moment(time) : null); + } + if (prevProps.useLocalTime !== useLocalTime) { + this.$time.datetimepicker('options', { timeZone: this.timezone(), defaultDate: null }); + } + } + + render() { + return ( + + + + + + this.$time.datetimepicker('show')} + onBlur={() => this.$time.datetimepicker('hide')} + onKeyDown={e => ['Escape', 'Enter'].includes(e.key) && this.$time.datetimepicker('hide')} + /> + + {/* CAUTION: While the datetimepicker also has an option to show a 'clear' button, + that functionality is broken, so we create an external solution instead. */} + {this.props.time && ( + + + + )} + + + + + + ); + } +} + +export default TimeInput; diff --git a/pkg/ui/react-app/src/pages/index.ts b/pkg/ui/react-app/src/pages/index.ts new file mode 100644 index 0000000000..d6f07d798d --- /dev/null +++ b/pkg/ui/react-app/src/pages/index.ts @@ -0,0 +1,11 @@ +import Alerts from './alerts/Alerts'; +import Config from './config/Config'; +import Flags from './flags/Flags'; +import Rules from './rules/Rules'; +import ServiceDiscovery from './serviceDiscovery/Services'; +import Status from './status/Status'; +import Targets from './targets/Targets'; +import PanelList from './graph/PanelList'; +import TSDBStatus from './tsdbStatus/TSDBStatus'; + +export { Alerts, Config, Flags, Rules, ServiceDiscovery, Status, Targets, TSDBStatus, PanelList }; diff --git a/pkg/ui/react-app/src/pages/rules/Rules.tsx b/pkg/ui/react-app/src/pages/rules/Rules.tsx new file mode 100644 index 0000000000..a44a721f53 --- /dev/null +++ b/pkg/ui/react-app/src/pages/rules/Rules.tsx @@ -0,0 +1,16 @@ +import React, { FC } from 'react'; +import { RouteComponentProps } from '@reach/router'; +import PathPrefixProps from '../../types/PathPrefixProps'; +import { useFetch } from '../../hooks/useFetch'; +import { withStatusIndicator } from '../../components/withStatusIndicator'; +import { RulesMap, RulesContent } from './RulesContent'; + +const RulesWithStatusIndicator = withStatusIndicator(RulesContent); + +const Rules: FC = ({ pathPrefix }) => { + const { response, error, isLoading } = useFetch(`${pathPrefix}/api/v1/rules`); + + return ; +}; + +export default Rules; diff --git a/pkg/ui/react-app/src/pages/rules/RulesContent.tsx b/pkg/ui/react-app/src/pages/rules/RulesContent.tsx new file mode 100644 index 0000000000..1144e43517 --- /dev/null +++ b/pkg/ui/react-app/src/pages/rules/RulesContent.tsx @@ -0,0 +1,131 @@ +import React, { FC } from 'react'; +import { RouteComponentProps } from '@reach/router'; +import { APIResponse } from '../../hooks/useFetch'; +import { Alert, Table, Badge } from 'reactstrap'; +import { Link } from '@reach/router'; +import { formatRelative, createExpressionLink, humanizeDuration } from '../../utils'; +import { Rule } from '../../types/types'; +import { now } from 'moment'; + +interface RulesContentProps { + response: APIResponse; +} + +interface RuleGroup { + name: string; + file: string; + rules: Rule[]; + evaluationTime: string; + lastEvaluation: string; +} + +export interface RulesMap { + groups: RuleGroup[]; +} + +const GraphExpressionLink: FC<{ expr: string; title: string }> = props => { + return ( + <> + {props.title}: + + {props.expr} + +
+ + ); +}; + +export const RulesContent: FC = ({ response }) => { + const getBadgeColor = (state: string) => { + switch (state) { + case 'ok': + return 'success'; + + case 'err': + return 'danger'; + + case 'unknown': + return 'warning'; + } + }; + + if (response.data) { + const groups: RuleGroup[] = response.data.groups; + return ( + <> +

Rules

+ {groups.map((g, i) => { + return ( + + + + + + + + + + + + + + + + + {g.rules.map((r, i) => { + return ( + + {r.alerts ? ( + + ) : ( + + )} + + + + + + ); + })} + +
+ +

{g.name}

+
+
+

{formatRelative(g.lastEvaluation, now())} ago

+
+

{humanizeDuration(parseFloat(g.evaluationTime) * 1000)}

+
RuleStateErrorLast EvaluationEvaluation Time
+ + +
+ labels: + {Object.entries(r.labels).map(([key, value]) => ( +
+ {key}: {value} +
+ ))} +
+
+ annotations: + {Object.entries(r.annotations).map(([key, value]) => ( +
+ {key}: {value} +
+ ))} +
+
+ + + + {r.health.toUpperCase()} + {r.lastError ? {r.lastError} : null}{formatRelative(r.lastEvaluation, now())} ago{humanizeDuration(parseFloat(r.evaluationTime) * 1000)}
+ ); + })} + + ); + } + + return null; +}; diff --git a/pkg/ui/react-app/src/pages/serviceDiscovery/LabelsTable.tsx b/pkg/ui/react-app/src/pages/serviceDiscovery/LabelsTable.tsx new file mode 100644 index 0000000000..b621df1005 --- /dev/null +++ b/pkg/ui/react-app/src/pages/serviceDiscovery/LabelsTable.tsx @@ -0,0 +1,65 @@ +import React, { FC, useState } from 'react'; +import { RouteComponentProps } from '@reach/router'; +import { Badge, Table } from 'reactstrap'; +import { TargetLabels } from './Services'; +import { ToggleMoreLess } from '../../components/ToggleMoreLess'; + +interface LabelProps { + value: TargetLabels[]; + name: string; +} + +const formatLabels = (labels: Record | string) => { + return Object.entries(labels).map(([key, value]) => { + return ( +
+ + {`${key}="${value}"`} + +
+ ); + }); +}; + +export const LabelsTable: FC = ({ value, name }) => { + const [showMore, setShowMore] = useState(false); + + return ( + <> +
+ { + setShowMore(!showMore); + }} + showMore={showMore} + > + {name} + +
+ {showMore ? ( + + + + + + + + + {value.map((_, i) => { + return ( + + + {value[i].isDropped ? ( + + ) : ( + + )} + + ); + })} + +
Discovered LabelsTarget Labels
{formatLabels(value[i].discoveredLabels)}Dropped{formatLabels(value[i].labels)}
+ ) : null} + + ); +}; diff --git a/pkg/ui/react-app/src/pages/serviceDiscovery/Services.tsx b/pkg/ui/react-app/src/pages/serviceDiscovery/Services.tsx new file mode 100644 index 0000000000..87aabb17ad --- /dev/null +++ b/pkg/ui/react-app/src/pages/serviceDiscovery/Services.tsx @@ -0,0 +1,120 @@ +import React, { FC } from 'react'; +import { RouteComponentProps } from '@reach/router'; +import PathPrefixProps from '../../types/PathPrefixProps'; +import { useFetch } from '../../hooks/useFetch'; +import { LabelsTable } from './LabelsTable'; +import { Target, Labels, DroppedTarget } from '../targets/target'; + +import { withStatusIndicator } from '../../components/withStatusIndicator'; +import { mapObjEntries } from '../../utils'; + +interface ServiceMap { + activeTargets: Target[]; + droppedTargets: DroppedTarget[]; +} + +export interface TargetLabels { + discoveredLabels: Labels; + labels: Labels; + isDropped: boolean; +} + +export const processSummary = (activeTargets: Target[], droppedTargets: DroppedTarget[]) => { + const targets: Record = {}; + + // Get targets of each type along with the total and active end points + for (const target of activeTargets) { + const { scrapePool: name } = target; + if (!targets[name]) { + targets[name] = { + total: 0, + active: 0, + }; + } + targets[name].total++; + targets[name].active++; + } + for (const target of droppedTargets) { + const { job: name } = target.discoveredLabels; + if (!targets[name]) { + targets[name] = { + total: 0, + active: 0, + }; + } + targets[name].total++; + } + + return targets; +}; + +export const processTargets = (activeTargets: Target[], droppedTargets: DroppedTarget[]) => { + const labels: Record = {}; + + for (const target of activeTargets) { + const name = target.scrapePool; + if (!labels[name]) { + labels[name] = []; + } + labels[name].push({ + discoveredLabels: target.discoveredLabels, + labels: target.labels, + isDropped: false, + }); + } + + for (const target of droppedTargets) { + const { job: name } = target.discoveredLabels; + if (!labels[name]) { + labels[name] = []; + } + labels[name].push({ + discoveredLabels: target.discoveredLabels, + isDropped: true, + labels: {}, + }); + } + + return labels; +}; + +export const ServiceDiscoveryContent: FC = ({ activeTargets, droppedTargets }) => { + const targets = processSummary(activeTargets, droppedTargets); + const labels = processTargets(activeTargets, droppedTargets); + + return ( + <> +

Service Discovery

+ +
+ {mapObjEntries(labels, ([k, v]) => { + return ; + })} + + ); +}; +ServiceDiscoveryContent.displayName = 'ServiceDiscoveryContent'; + +const ServicesWithStatusIndicator = withStatusIndicator(ServiceDiscoveryContent); + +const ServiceDiscovery: FC = ({ pathPrefix }) => { + const { response, error, isLoading } = useFetch(`${pathPrefix}/api/v1/targets`); + return ( + + ); +}; + +export default ServiceDiscovery; diff --git a/pkg/ui/react-app/src/pages/status/Status.test.tsx b/pkg/ui/react-app/src/pages/status/Status.test.tsx new file mode 100644 index 0000000000..72c442af28 --- /dev/null +++ b/pkg/ui/react-app/src/pages/status/Status.test.tsx @@ -0,0 +1,49 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import toJson from 'enzyme-to-json'; +import { StatusContent } from './Status'; + +describe('Status', () => { + describe('Snapshot testing', () => { + const response: any = [ + { + startTime: '2019-10-30T22:03:23.247913868+02:00', + CWD: '/home/boyskila/Desktop/prometheus', + reloadConfigSuccess: true, + lastConfigTime: '2019-10-30T22:03:23+02:00', + chunkCount: 1383, + timeSeriesCount: 461, + corruptionCount: 0, + goroutineCount: 37, + GOMAXPROCS: 4, + GOGC: '', + GODEBUG: '', + storageRetention: '15d', + }, + { + version: '', + revision: '', + branch: '', + buildUser: '', + buildDate: '', + goVersion: 'go1.13.3', + }, + { + activeAlertmanagers: [ + { url: 'https://1.2.3.4:9093/api/v1/alerts' }, + { url: 'https://1.2.3.5:9093/api/v1/alerts' }, + { url: 'https://1.2.3.6:9093/api/v1/alerts' }, + { url: 'https://1.2.3.7:9093/api/v1/alerts' }, + { url: 'https://1.2.3.8:9093/api/v1/alerts' }, + { url: 'https://1.2.3.9:9093/api/v1/alerts' }, + ], + droppedAlertmanagers: [], + }, + ]; + it('should match table snapshot', () => { + const wrapper = shallow(); + expect(toJson(wrapper)).toMatchSnapshot(); + jest.restoreAllMocks(); + }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/status/Status.tsx b/pkg/ui/react-app/src/pages/status/Status.tsx new file mode 100644 index 0000000000..b2c06cd4dc --- /dev/null +++ b/pkg/ui/react-app/src/pages/status/Status.tsx @@ -0,0 +1,112 @@ +import React, { Fragment, FC } from 'react'; +import { RouteComponentProps } from '@reach/router'; +import { Table } from 'reactstrap'; +import { withStatusIndicator } from '../../components/withStatusIndicator'; +import { useFetch } from '../../hooks/useFetch'; +import PathPrefixProps from '../../types/PathPrefixProps'; + +interface StatusPageProps { + data: Record; + title: string; +} + +export const statusConfig: Record< + string, + { title?: string; customizeValue?: (v: any, key: string) => any; customRow?: boolean; skip?: boolean } +> = { + startTime: { title: 'Start time', customizeValue: (v: string) => new Date(v).toUTCString() }, + CWD: { title: 'Working directory' }, + reloadConfigSuccess: { + title: 'Configuration reload', + customizeValue: (v: boolean) => (v ? 'Successful' : 'Unsuccessful'), + }, + lastConfigTime: { title: 'Last successful configuration reload' }, + chunkCount: { title: 'Head chunks' }, + timeSeriesCount: { title: 'Head time series' }, + corruptionCount: { title: 'WAL corruptions' }, + goroutineCount: { title: 'Goroutines' }, + storageRetention: { title: 'Storage retention' }, + activeAlertmanagers: { + customRow: true, + customizeValue: (alertMgrs: { url: string }[], key) => { + return ( + + + Endpoint + + {alertMgrs.map(({ url }) => { + const { origin, pathname } = new URL(url); + return ( + + + {origin} + {pathname} + + + ); + })} + + ); + }, + }, + droppedAlertmanagers: { skip: true }, +}; + +export const StatusContent: FC = ({ data, title }) => { + return ( + <> +

{title}

+ + + {Object.entries(data).map(([k, v]) => { + const { title = k, customizeValue = (val: any) => val, customRow, skip } = statusConfig[k] || {}; + if (skip) { + return null; + } + if (customRow) { + return customizeValue(v, k); + } + return ( + + + + + ); + })} + +
+ {title} + {customizeValue(v, title)}
+ + ); +}; +const StatusWithStatusIndicator = withStatusIndicator(StatusContent); + +StatusContent.displayName = 'Status'; + +const Status: FC = ({ pathPrefix = '' }) => { + const path = `${pathPrefix}/api/v1`; + + return ( + <> + {[ + { fetchResult: useFetch>(`${path}/status/runtimeinfo`), title: 'Runtime Information' }, + { fetchResult: useFetch>(`${path}/status/buildinfo`), title: 'Build Information' }, + { fetchResult: useFetch>(`${path}/alertmanagers`), title: 'Alertmanagers' }, + ].map(({ fetchResult, title }) => { + const { response, isLoading, error } = fetchResult; + return ( + + ); + })} + + ); +}; + +export default Status; diff --git a/pkg/ui/react-app/src/pages/status/__snapshots__/Status.test.tsx.snap b/pkg/ui/react-app/src/pages/status/__snapshots__/Status.test.tsx.snap new file mode 100644 index 0000000000..fb6eef17d8 --- /dev/null +++ b/pkg/ui/react-app/src/pages/status/__snapshots__/Status.test.tsx.snap @@ -0,0 +1,77 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Status Snapshot testing should match table snapshot 1`] = ` + +

+ Foo +

+ + + + + + + + + + + + + + + +
+ 0 + + +
+ 1 + + +
+ 2 + + +
+
+`; diff --git a/pkg/ui/react-app/src/pages/targets/EndpointLink.test.tsx b/pkg/ui/react-app/src/pages/targets/EndpointLink.test.tsx new file mode 100644 index 0000000000..d89326f73a --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/EndpointLink.test.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { Badge, Alert } from 'reactstrap'; +import EndpointLink from './EndpointLink'; + +describe('EndpointLink', () => { + it('renders a simple anchor if the endpoint has no query params', () => { + const endpoint = 'http://100.104.208.71:15090/stats/prometheus'; + const globalURL = 'http://100.104.208.71:15090/stats/prometheus'; + const endpointLink = shallow(); + const anchor = endpointLink.find('a'); + expect(anchor.prop('href')).toEqual(globalURL); + expect(anchor.children().text()).toEqual(endpoint); + expect(endpointLink.find('br')).toHaveLength(0); + }); + + it('renders an anchor targeting endpoint but with query param labels if the endpoint has query params', () => { + const endpoint = 'http://100.99.128.71:9115/probe?module=http_2xx&target=http://some-service'; + const globalURL = 'http://100.99.128.71:9115/probe?module=http_2xx&target=http://some-service'; + const endpointLink = shallow(); + const anchor = endpointLink.find('a'); + const badges = endpointLink.find(Badge); + expect(anchor.prop('href')).toEqual(globalURL); + expect(anchor.children().text()).toEqual('http://100.99.128.71:9115/probe'); + expect(endpointLink.find('br')).toHaveLength(1); + expect(badges).toHaveLength(2); + const moduleLabel = badges.filterWhere(badge => badge.hasClass('module')); + expect(moduleLabel.children().text()).toEqual('module="http_2xx"'); + const targetLabel = badges.filterWhere(badge => badge.hasClass('target')); + expect(targetLabel.children().text()).toEqual('target="http://some-service"'); + }); + + it('renders an alert if url is invalid', () => { + const endpointLink = shallow(); + const err = endpointLink.find(Alert); + expect(err.render().text()).toEqual('Error: Invalid URL'); + }); +}); diff --git a/pkg/ui/react-app/src/pages/targets/EndpointLink.tsx b/pkg/ui/react-app/src/pages/targets/EndpointLink.tsx new file mode 100644 index 0000000000..3f524658be --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/EndpointLink.tsx @@ -0,0 +1,39 @@ +import React, { FC } from 'react'; +import { Badge, Alert } from 'reactstrap'; + +export interface EndpointLinkProps { + endpoint: string; + globalUrl: string; +} + +const EndpointLink: FC = ({ endpoint, globalUrl }) => { + let url: URL; + try { + url = new URL(endpoint); + } catch (e) { + return ( + + Error: {e.message} + + ); + } + + const { host, pathname, protocol, searchParams }: URL = url; + const params = Array.from(searchParams.entries()); + + return ( + <> + {`${protocol}//${host}${pathname}`} + {params.length > 0 ?
: null} + {params.map(([labelName, labelValue]: [string, string]) => { + return ( + + {`${labelName}="${labelValue}"`} + + ); + })} + + ); +}; + +export default EndpointLink; diff --git a/pkg/ui/react-app/src/pages/targets/Filter.module.css b/pkg/ui/react-app/src/pages/targets/Filter.module.css new file mode 100644 index 0000000000..6cc9adbe23 --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/Filter.module.css @@ -0,0 +1,4 @@ +.btn { + margin-top: 0.6em; + margin-bottom: 15px; +} diff --git a/pkg/ui/react-app/src/pages/targets/Filter.test.tsx b/pkg/ui/react-app/src/pages/targets/Filter.test.tsx new file mode 100644 index 0000000000..79d444ff3e --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/Filter.test.tsx @@ -0,0 +1,45 @@ +import React, { Component } from 'react'; +import { shallow, ShallowWrapper } from 'enzyme'; +import { Button, ButtonGroup } from 'reactstrap'; +import Filter, { FilterData, FilterProps } from './Filter'; +import sinon, { SinonSpy } from 'sinon'; + +describe('Filter', () => { + const initialState: FilterData = { showHealthy: true, showUnhealthy: true }; + let setFilter: SinonSpy; + let filterWrapper: ShallowWrapper, Component<{}, {}, Component>>; + beforeEach(() => { + setFilter = sinon.spy(); + filterWrapper = shallow(); + }); + + it('renders a button group', () => { + expect(filterWrapper.find(ButtonGroup)).toHaveLength(1); + }); + + it('renders an all filter button that is active by default', () => { + const btn = filterWrapper.find(Button).filterWhere((btn): boolean => btn.hasClass('all')); + expect(btn.prop('active')).toBe(true); + expect(btn.prop('color')).toBe('primary'); + }); + + it('renders an unhealthy filter button that is inactive by default', () => { + const btn = filterWrapper.find(Button).filterWhere((btn): boolean => btn.hasClass('unhealthy')); + expect(btn.prop('active')).toBe(false); + expect(btn.prop('color')).toBe('primary'); + }); + + it('renders an all filter button which shows all targets', () => { + const btn = filterWrapper.find(Button).filterWhere((btn): boolean => btn.hasClass('all')); + btn.simulate('click'); + expect(setFilter.calledOnce).toBe(true); + expect(setFilter.getCall(0).args[0]).toEqual({ showHealthy: true, showUnhealthy: true }); + }); + + it('renders an unhealthy filter button which filters targets', () => { + const btn = filterWrapper.find(Button).filterWhere((btn): boolean => btn.hasClass('unhealthy')); + btn.simulate('click'); + expect(setFilter.calledOnce).toBe(true); + expect(setFilter.getCall(0).args[0]).toEqual({ showHealthy: false, showUnhealthy: true }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/targets/Filter.tsx b/pkg/ui/react-app/src/pages/targets/Filter.tsx new file mode 100644 index 0000000000..900a6d5b0d --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/Filter.tsx @@ -0,0 +1,39 @@ +import React, { Dispatch, FC, SetStateAction } from 'react'; +import { Button, ButtonGroup } from 'reactstrap'; +import styles from './Filter.module.css'; + +export interface FilterData { + showHealthy: boolean; + showUnhealthy: boolean; +} + +export interface FilterProps { + filter: FilterData; + setFilter: Dispatch>; +} + +const Filter: FC = ({ filter, setFilter }) => { + const { showHealthy } = filter; + const btnProps = { + all: { + active: showHealthy, + className: `all ${styles.btn}`, + color: 'primary', + onClick: (): void => setFilter({ ...filter, showHealthy: true }), + }, + unhealthy: { + active: !showHealthy, + className: `unhealthy ${styles.btn}`, + color: 'primary', + onClick: (): void => setFilter({ ...filter, showHealthy: false }), + }, + }; + return ( + + + + + ); +}; + +export default Filter; diff --git a/pkg/ui/react-app/src/pages/targets/ScrapePoolList.test.tsx b/pkg/ui/react-app/src/pages/targets/ScrapePoolList.test.tsx new file mode 100644 index 0000000000..be57f4c8a1 --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/ScrapePoolList.test.tsx @@ -0,0 +1,83 @@ +import * as React from 'react'; +import { mount, ReactWrapper } from 'enzyme'; +import { act } from 'react-dom/test-utils'; +import { Alert } from 'reactstrap'; +import { sampleApiResponse } from './__testdata__/testdata'; +import ScrapePoolList from './ScrapePoolList'; +import ScrapePoolPanel from './ScrapePoolPanel'; +import { Target } from './target'; +import { FetchMock } from 'jest-fetch-mock/types'; + +describe('ScrapePoolList', () => { + const defaultProps = { + filter: { showHealthy: true, showUnhealthy: true }, + pathPrefix: '..', + }; + + beforeEach(() => { + fetchMock.resetMocks(); + }); + + describe('when data is returned', () => { + let scrapePoolList: ReactWrapper; + let mock: FetchMock; + beforeEach(() => { + //Tooltip requires DOM elements to exist. They do not in enzyme rendering so we must manually create them. + const scrapePools: { [key: string]: number } = { blackbox: 3, node_exporter: 1, 'prometheus/test': 1 }; + Object.keys(scrapePools).forEach((pool: string): void => { + Array.from(Array(scrapePools[pool]).keys()).forEach((idx: number): void => { + const div = document.createElement('div'); + div.id = `series-labels-${pool}-${idx}`; + document.body.appendChild(div); + }); + }); + mock = fetchMock.mockResponse(JSON.stringify(sampleApiResponse)); + }); + + it('renders a table', async () => { + await act(async () => { + scrapePoolList = mount(); + }); + scrapePoolList.update(); + expect(mock).toHaveBeenCalledWith('../api/v1/targets?state=active', { cache: 'no-store', credentials: 'same-origin' }); + const panels = scrapePoolList.find(ScrapePoolPanel); + expect(panels).toHaveLength(3); + const activeTargets: Target[] = sampleApiResponse.data.activeTargets as Target[]; + activeTargets.forEach(({ scrapePool }: Target) => { + const panel = scrapePoolList.find(ScrapePoolPanel).filterWhere(panel => panel.prop('scrapePool') === scrapePool); + expect(panel).toHaveLength(1); + }); + }); + + it('filters by health', async () => { + const props = { + ...defaultProps, + filter: { showHealthy: false, showUnhealthy: true }, + }; + await act(async () => { + scrapePoolList = mount(); + }); + scrapePoolList.update(); + expect(mock).toHaveBeenCalledWith('../api/v1/targets?state=active', { cache: 'no-store', credentials: 'same-origin' }); + const panels = scrapePoolList.find(ScrapePoolPanel); + expect(panels).toHaveLength(0); + }); + }); + + describe('when an error is returned', () => { + it('displays an alert', async () => { + const mock = fetchMock.mockReject(new Error('Error fetching targets')); + + let scrapePoolList: any; + await act(async () => { + scrapePoolList = mount(); + }); + scrapePoolList.update(); + + expect(mock).toHaveBeenCalledWith('../api/v1/targets?state=active', { cache: 'no-store', credentials: 'same-origin' }); + const alert = scrapePoolList.find(Alert); + expect(alert.prop('color')).toBe('danger'); + expect(alert.text()).toContain('Error fetching targets'); + }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/targets/ScrapePoolList.tsx b/pkg/ui/react-app/src/pages/targets/ScrapePoolList.tsx new file mode 100644 index 0000000000..7be82f1fce --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/ScrapePoolList.tsx @@ -0,0 +1,48 @@ +import React, { FC } from 'react'; +import { FilterData } from './Filter'; +import { useFetch } from '../../hooks/useFetch'; +import { groupTargets, Target } from './target'; +import ScrapePoolPanel from './ScrapePoolPanel'; +import PathPrefixProps from '../../types/PathPrefixProps'; +import { withStatusIndicator } from '../../components/withStatusIndicator'; + +interface ScrapePoolListProps { + filter: FilterData; + activeTargets: Target[]; +} + +export const ScrapePoolContent: FC = ({ filter, activeTargets }) => { + const targetGroups = groupTargets(activeTargets); + const { showHealthy, showUnhealthy } = filter; + return ( + <> + {Object.keys(targetGroups).reduce((panels, scrapePool) => { + const targetGroup = targetGroups[scrapePool]; + const isHealthy = targetGroup.upCount === targetGroup.targets.length; + return (isHealthy && showHealthy) || (!isHealthy && showUnhealthy) + ? [...panels, ] + : panels; + }, [])} + + ); +}; +ScrapePoolContent.displayName = 'ScrapePoolContent'; + +const ScrapePoolListWithStatusIndicator = withStatusIndicator(ScrapePoolContent); + +const ScrapePoolList: FC<{ filter: FilterData } & PathPrefixProps> = ({ pathPrefix, filter }) => { + const { response, error, isLoading } = useFetch(`${pathPrefix}/api/v1/targets?state=active`); + const { status: responseStatus } = response; + const badResponse = responseStatus !== 'success' && responseStatus !== 'start fetching'; + return ( + + ); +}; + +export default ScrapePoolList; diff --git a/pkg/ui/react-app/src/pages/targets/ScrapePoolPanel.module.css b/pkg/ui/react-app/src/pages/targets/ScrapePoolPanel.module.css new file mode 100644 index 0000000000..a5b5f9ac5b --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/ScrapePoolPanel.module.css @@ -0,0 +1,43 @@ +.container { + margin-top: -12px; +} + +.title { + font-size: 20px; + font-weight: bold; + cursor: pointer; +} + +.normal { + composes: title; +} + +.danger { + composes: title; + color: rgb(242, 65, 65); +} + +.table { + width: 100%; +} + +.cell { + height: auto; + word-wrap: break-word; + word-break: break-all; +} + +.endpoint, .labels { + composes: cell; + width: 25%; +} + +.state, .last-scrape { + composes: cell; + width: 10%; +} + +.errors { + composes: cell; + width: 30%; +} diff --git a/pkg/ui/react-app/src/pages/targets/ScrapePoolPanel.test.tsx b/pkg/ui/react-app/src/pages/targets/ScrapePoolPanel.test.tsx new file mode 100644 index 0000000000..c14a531a79 --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/ScrapePoolPanel.test.tsx @@ -0,0 +1,129 @@ +import React from 'react'; +import { mount, shallow } from 'enzyme'; +import { targetGroups } from './__testdata__/testdata'; +import ScrapePoolPanel, { columns } from './ScrapePoolPanel'; +import { Button, Collapse, Table, Badge } from 'reactstrap'; +import { Target, getColor } from './target'; +import EndpointLink from './EndpointLink'; +import TargetLabels from './TargetLabels'; + +describe('ScrapePoolPanel', () => { + const defaultProps = { + scrapePool: 'blackbox', + targetGroup: targetGroups.blackbox, + }; + const scrapePoolPanel = shallow(); + + it('renders a container', () => { + const div = scrapePoolPanel.find('div').filterWhere(elem => elem.hasClass('container')); + expect(div).toHaveLength(1); + }); + + describe('Header', () => { + it('renders an anchor with up count and danger color if upCount < targetsCount', () => { + const anchor = scrapePoolPanel.find('a'); + expect(anchor).toHaveLength(1); + expect(anchor.prop('id')).toEqual('pool-blackbox'); + expect(anchor.prop('href')).toEqual('#pool-blackbox'); + expect(anchor.text()).toEqual('blackbox (2/3 up)'); + expect(anchor.prop('className')).toEqual('danger'); + }); + + it('renders an anchor with up count and normal color if upCount == targetsCount', () => { + const props = { + scrapePool: 'prometheus', + targetGroup: targetGroups.prometheus, + }; + const scrapePoolPanel = shallow(); + const anchor = scrapePoolPanel.find('a'); + expect(anchor).toHaveLength(1); + expect(anchor.prop('id')).toEqual('pool-prometheus'); + expect(anchor.prop('href')).toEqual('#pool-prometheus'); + expect(anchor.text()).toEqual('prometheus (1/1 up)'); + expect(anchor.prop('className')).toEqual('normal'); + }); + + it('renders a show more btn if collapsed', () => { + const props = { + scrapePool: 'prometheus', + targetGroup: targetGroups.prometheus, + }; + const div = document.createElement('div'); + div.id = `series-labels-prometheus-0`; + document.body.appendChild(div); + const scrapePoolPanel = mount(); + + const btn = scrapePoolPanel.find(Button); + btn.simulate('click'); + const collapse = scrapePoolPanel.find(Collapse); + expect(collapse.prop('isOpen')).toBe(false); + }); + }); + + it('renders a Collapse component', () => { + const collapse = scrapePoolPanel.find(Collapse); + expect(collapse.prop('isOpen')).toBe(true); + }); + + describe('Table', () => { + it('renders a table', () => { + const table = scrapePoolPanel.find(Table); + const headers = table.find('th'); + expect(table).toHaveLength(1); + expect(headers).toHaveLength(6); + columns.forEach(col => { + expect(headers.contains(col)); + }); + }); + + describe('for each target', () => { + const table = scrapePoolPanel.find(Table); + defaultProps.targetGroup.targets.forEach( + ({ discoveredLabels, labels, scrapeUrl, lastError, health }: Target, idx: number) => { + const row = table.find('tr').at(idx + 1); + + it('renders an EndpointLink with the scrapeUrl', () => { + const link = row.find(EndpointLink); + expect(link).toHaveLength(1); + expect(link.prop('endpoint')).toEqual(scrapeUrl); + }); + + it('renders a badge for health', () => { + const td = row.find('td').filterWhere(elem => Boolean(elem.hasClass('state'))); + const badge = td.find(Badge); + expect(badge).toHaveLength(1); + expect(badge.prop('color')).toEqual(getColor(health)); + expect(badge.children().text()).toEqual(health.toUpperCase()); + }); + + it('renders series labels', () => { + const targetLabels = row.find(TargetLabels); + expect(targetLabels).toHaveLength(1); + expect(targetLabels.prop('discoveredLabels')).toEqual(discoveredLabels); + expect(targetLabels.prop('labels')).toEqual(labels); + }); + + it('renders last scrape time', () => { + const lastScrapeCell = row.find('td').filterWhere(elem => Boolean(elem.hasClass('last-scrape'))); + expect(lastScrapeCell).toHaveLength(1); + }); + + it('renders last scrape duration', () => { + const lastScrapeCell = row.find('td').filterWhere(elem => Boolean(elem.hasClass('scrape-duration'))); + expect(lastScrapeCell).toHaveLength(1); + }); + + it('renders a badge for Errors', () => { + const td = row.find('td').filterWhere(elem => Boolean(elem.hasClass('errors'))); + const badge = td.find(Badge); + expect(badge).toHaveLength(lastError ? 1 : 0); + if (lastError) { + expect(badge.prop('color')).toEqual('danger'); + expect(badge.children().text()).toEqual(lastError); + } + }); + } + ); + }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/targets/ScrapePoolPanel.tsx b/pkg/ui/react-app/src/pages/targets/ScrapePoolPanel.tsx new file mode 100644 index 0000000000..390fe3da9c --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/ScrapePoolPanel.tsx @@ -0,0 +1,84 @@ +import React, { FC } from 'react'; +import { ScrapePool, getColor } from './target'; +import { Collapse, Table, Badge } from 'reactstrap'; +import styles from './ScrapePoolPanel.module.css'; +import { Target } from './target'; +import EndpointLink from './EndpointLink'; +import TargetLabels from './TargetLabels'; +import { now } from 'moment'; +import { useLocalStorage } from '../../hooks/useLocalStorage'; +import { ToggleMoreLess } from '../../components/ToggleMoreLess'; +import { formatRelative, humanizeDuration } from '../../utils'; + +interface PanelProps { + scrapePool: string; + targetGroup: ScrapePool; +} + +export const columns = ['Endpoint', 'State', 'Labels', 'Last Scrape', 'Scrape Duration', 'Error']; + +const ScrapePoolPanel: FC = ({ scrapePool, targetGroup }) => { + const [{ expanded }, setOptions] = useLocalStorage(`targets-${scrapePool}-expanded`, { expanded: true }); + const modifier = targetGroup.upCount < targetGroup.targets.length ? 'danger' : 'normal'; + const id = `pool-${scrapePool}`; + const anchorProps = { + href: `#${id}`, + id, + }; + + return ( +
+ setOptions({ expanded: !expanded })} showMore={expanded}> + + {`${scrapePool} (${targetGroup.upCount}/${targetGroup.targets.length} up)`} + + + + + + + {columns.map(column => ( + + ))} + + + + {targetGroup.targets.map((target: Target, idx: number) => { + const { + discoveredLabels, + labels, + scrapePool, + scrapeUrl, + globalUrl, + lastError, + lastScrape, + lastScrapeDuration, + health, + } = target; + const color = getColor(health); + + return ( + + + + + + + + + ); + })} + +
{column}
+ + + {health.toUpperCase()} + + + {formatRelative(lastScrape, now())}{humanizeDuration(lastScrapeDuration * 1000)}{lastError ? {lastError} : null}
+
+
+ ); +}; + +export default ScrapePoolPanel; diff --git a/pkg/ui/react-app/src/pages/targets/TargetLabels.module.css b/pkg/ui/react-app/src/pages/targets/TargetLabels.module.css new file mode 100644 index 0000000000..9c3768818e --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/TargetLabels.module.css @@ -0,0 +1,3 @@ +.discovered { + white-space: nowrap; +} diff --git a/pkg/ui/react-app/src/pages/targets/TargetLabels.test.tsx b/pkg/ui/react-app/src/pages/targets/TargetLabels.test.tsx new file mode 100644 index 0000000000..e71d311b92 --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/TargetLabels.test.tsx @@ -0,0 +1,50 @@ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import TargetLabels from './TargetLabels'; +import { Tooltip, Badge } from 'reactstrap'; +import toJson from 'enzyme-to-json'; + +describe('targetLabels', () => { + const defaultProps = { + discoveredLabels: { + __address__: 'localhost:9100', + __metrics_path__: '/metrics', + __scheme__: 'http', + job: 'node_exporter', + }, + labels: { + instance: 'localhost:9100', + job: 'node_exporter', + foo: 'bar', + }, + idx: 1, + scrapePool: 'cortex/node-exporter_group/0', + }; + const targetLabels = shallow(); + + it('renders a div of series labels', () => { + const div = targetLabels.find('div').filterWhere(elem => elem.hasClass('series-labels-container')); + expect(div).toHaveLength(1); + expect(div.prop('id')).toEqual('series-labels-cortex/node-exporter_group/0-1'); + }); + + it('wraps each label in a label badge', () => { + const l: { [key: string]: string } = defaultProps.labels; + Object.keys(l).forEach((labelName: string): void => { + const badge = targetLabels.find(Badge).filterWhere(badge => badge.hasClass(labelName)); + expect(badge.children().text()).toEqual(`${labelName}="${l[labelName]}"`); + }); + expect(targetLabels.find(Badge)).toHaveLength(3); + }); + + it('renders a tooltip for discovered labels', () => { + const tooltip = targetLabels.find(Tooltip); + expect(tooltip).toHaveLength(1); + expect(tooltip.prop('isOpen')).toBe(false); + expect(tooltip.prop('target')).toEqual('series-labels-cortex\\/node-exporter_group\\/0-1'); + }); + + it('renders discovered labels', () => { + expect(toJson(targetLabels)).toMatchSnapshot(); + }); +}); diff --git a/pkg/ui/react-app/src/pages/targets/TargetLabels.tsx b/pkg/ui/react-app/src/pages/targets/TargetLabels.tsx new file mode 100644 index 0000000000..45376a1825 --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/TargetLabels.tsx @@ -0,0 +1,49 @@ +import React, { FC, Fragment, useState } from 'react'; +import { Badge, Tooltip } from 'reactstrap'; +import 'css.escape'; +import styles from './TargetLabels.module.css'; + +interface Labels { + [key: string]: string; +} + +export interface TargetLabelsProps { + discoveredLabels: Labels; + labels: Labels; + idx: number; + scrapePool: string; +} + +const formatLabels = (labels: Labels): string[] => Object.keys(labels).map(key => `${key}="${labels[key]}"`); + +const TargetLabels: FC = ({ discoveredLabels, labels, idx, scrapePool }) => { + const [tooltipOpen, setTooltipOpen] = useState(false); + + const toggle = (): void => setTooltipOpen(!tooltipOpen); + const id = `series-labels-${scrapePool}-${idx}`; + + return ( + <> +
+ {Object.keys(labels).map(labelName => { + return ( + + {`${labelName}="${labels[labelName]}"`} + + ); + })} +
+ + Before relabeling: + {formatLabels(discoveredLabels).map((s: string, idx: number) => ( + +
+ {s} +
+ ))} +
+ + ); +}; + +export default TargetLabels; diff --git a/pkg/ui/react-app/src/pages/targets/Targets.test.tsx b/pkg/ui/react-app/src/pages/targets/Targets.test.tsx new file mode 100644 index 0000000000..866c35b095 --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/Targets.test.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import Targets from './Targets'; +import Filter from './Filter'; +import ScrapePoolList from './ScrapePoolList'; + +describe('Targets', () => { + const defaultProps = { + pathPrefix: '..', + }; + const targets = shallow(); + describe('Header', () => { + const h2 = targets.find('h2'); + it('renders a header', () => { + expect(h2.text()).toEqual('Targets'); + }); + it('renders exactly one header', () => { + const h2 = targets.find('h2'); + expect(h2).toHaveLength(1); + }); + }); + it('renders a filter', () => { + const filter = targets.find(Filter); + expect(filter).toHaveLength(1); + expect(filter.prop('filter')).toEqual({ showHealthy: true, showUnhealthy: true }); + }); + it('renders a scrape pool list', () => { + const scrapePoolList = targets.find(ScrapePoolList); + expect(scrapePoolList).toHaveLength(1); + expect(scrapePoolList.prop('filter')).toEqual({ showHealthy: true, showUnhealthy: true }); + expect(scrapePoolList.prop('pathPrefix')).toEqual(defaultProps.pathPrefix); + }); +}); diff --git a/pkg/ui/react-app/src/pages/targets/Targets.tsx b/pkg/ui/react-app/src/pages/targets/Targets.tsx new file mode 100644 index 0000000000..5f4737196e --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/Targets.tsx @@ -0,0 +1,22 @@ +import React, { FC } from 'react'; +import { RouteComponentProps } from '@reach/router'; +import Filter from './Filter'; +import ScrapePoolList from './ScrapePoolList'; +import PathPrefixProps from '../../types/PathPrefixProps'; +import { useLocalStorage } from '../../hooks/useLocalStorage'; + +const Targets: FC = ({ pathPrefix }) => { + const [filter, setFilter] = useLocalStorage('targets-page-filter', { showHealthy: true, showUnhealthy: true }); + const filterProps = { filter, setFilter }; + const scrapePoolListProps = { filter, pathPrefix }; + + return ( + <> +

Targets

+ + + + ); +}; + +export default Targets; diff --git a/pkg/ui/react-app/src/pages/targets/__snapshots__/TargetLabels.test.tsx.snap b/pkg/ui/react-app/src/pages/targets/__snapshots__/TargetLabels.test.tsx.snap new file mode 100644 index 0000000000..7613249cba --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/__snapshots__/TargetLabels.test.tsx.snap @@ -0,0 +1,81 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`targetLabels renders discovered labels 1`] = ` + +
+ + instance="localhost:9100" + + + job="node_exporter" + + + foo="bar" + +
+ + + Before relabeling: + +
+ + __address__="localhost:9100" + +
+ + __metrics_path__="/metrics" + +
+ + __scheme__="http" + +
+ + job="node_exporter" + +
+
+`; diff --git a/pkg/ui/react-app/src/pages/targets/__testdata__/testdata.ts b/pkg/ui/react-app/src/pages/targets/__testdata__/testdata.ts new file mode 100644 index 0000000000..53f6a7e48d --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/__testdata__/testdata.ts @@ -0,0 +1,220 @@ +/* eslint @typescript-eslint/camelcase: 0 */ + +import { ScrapePools } from '../target'; + +export const targetGroups: ScrapePools = Object.freeze({ + blackbox: { + upCount: 2, + targets: [ + { + discoveredLabels: { + __address__: 'http://prometheus.io', + __metrics_path__: '/probe', + __param_module: 'http_2xx', + __scheme__: 'http', + job: 'blackbox', + }, + labels: { + instance: 'http://prometheus.io', + job: 'blackbox', + }, + scrapePool: 'blackbox', + scrapeUrl: 'http://127.0.0.1:9115/probe?module=http_2xx&target=http%3A%2F%2Fprometheus.io', + globalUrl: 'http://localhost.localdomain:9115/probe?module=http_2xx&target=http%3A%2F%2Fprometheus.io', + lastError: '', + lastScrape: '2019-11-04T11:52:14.759299-07:00', + lastScrapeDuration: 36560147, + health: 'up', + }, + { + discoveredLabels: { + __address__: 'https://prometheus.io', + __metrics_path__: '/probe', + __param_module: 'http_2xx', + __scheme__: 'http', + job: 'blackbox', + }, + labels: { + instance: 'https://prometheus.io', + job: 'blackbox', + }, + scrapePool: 'blackbox', + scrapeUrl: 'http://127.0.0.1:9115/probe?module=http_2xx&target=https%3A%2F%2Fprometheus.io', + globalUrl: 'http://localhost.localdomain:9115/probe?module=http_2xx&target=https%3A%2F%2Fprometheus.io', + lastError: '', + lastScrape: '2019-11-04T11:52:24.731096-07:00', + lastScrapeDuration: 49448763, + health: 'up', + }, + { + discoveredLabels: { + __address__: 'http://example.com:8080', + __metrics_path__: '/probe', + __param_module: 'http_2xx', + __scheme__: 'http', + job: 'blackbox', + }, + labels: { + instance: 'http://example.com:8080', + job: 'blackbox', + }, + scrapePool: 'blackbox', + scrapeUrl: 'http://127.0.0.1:9115/probe?module=http_2xx&target=http%3A%2F%2Fexample.com%3A8080', + globalUrl: 'http://localhost.localdomain:9115/probe?module=http_2xx&target=http%3A%2F%2Fexample.com%3A8080', + lastError: '', + lastScrape: '2019-11-04T11:52:13.516654-07:00', + lastScrapeDuration: 120916592, + health: 'down', + }, + ], + }, + node_exporter: { + upCount: 1, + targets: [ + { + discoveredLabels: { + __address__: 'localhost:9100', + __metrics_path__: '/metrics', + __scheme__: 'http', + job: 'node_exporter', + }, + labels: { + instance: 'localhost:9100', + job: 'node_exporter', + }, + scrapePool: 'node_exporter', + scrapeUrl: 'http://localhost:9100/metrics', + globalUrl: 'http://localhost.localdomain:9100/metrics', + lastError: '', + lastScrape: '2019-11-04T11:52:14.145703-07:00', + lastScrapeDuration: 3842307, + health: 'up', + }, + ], + }, + prometheus: { + upCount: 1, + targets: [ + { + discoveredLabels: { + __address__: 'localhost:9090', + __metrics_path__: '/metrics', + __scheme__: 'http', + job: 'prometheus', + }, + labels: { + instance: 'localhost:9090', + job: 'prometheus', + }, + scrapePool: 'prometheus', + scrapeUrl: 'http://localhost:9090/metrics', + globalUrl: 'http://localhost.localdomain:9000/metrics', + lastError: '', + lastScrape: '2019-11-04T11:52:18.479731-07:00', + lastScrapeDuration: 4050976, + health: 'up', + }, + ], + }, +}); + +export const sampleApiResponse = Object.freeze({ + status: 'success', + data: { + activeTargets: [ + { + discoveredLabels: { + __address__: 'http://prometheus.io', + __metrics_path__: '/probe', + __param_module: 'http_2xx', + __scheme__: 'http', + job: 'blackbox', + }, + labels: { + instance: 'http://prometheus.io', + job: 'blackbox', + }, + scrapePool: 'blackbox', + scrapeUrl: 'http://127.0.0.1:9115/probe?module=http_2xx&target=http%3A%2F%2Fprometheus.io', + lastError: '', + lastScrape: '2019-11-04T11:52:14.759299-07:00', + lastScrapeDuration: 36560147, + health: 'up', + }, + { + discoveredLabels: { + __address__: 'https://prometheus.io', + __metrics_path__: '/probe', + __param_module: 'http_2xx', + __scheme__: 'http', + job: 'blackbox', + }, + labels: { + instance: 'https://prometheus.io', + job: 'blackbox', + }, + scrapePool: 'blackbox', + scrapeUrl: 'http://127.0.0.1:9115/probe?module=http_2xx&target=https%3A%2F%2Fprometheus.io', + lastError: '', + lastScrape: '2019-11-04T11:52:24.731096-07:00', + lastScrapeDuration: 49448763, + health: 'up', + }, + { + discoveredLabels: { + __address__: 'http://example.com:8080', + __metrics_path__: '/probe', + __param_module: 'http_2xx', + __scheme__: 'http', + job: 'blackbox', + }, + labels: { + instance: 'http://example.com:8080', + job: 'blackbox', + }, + scrapePool: 'blackbox', + scrapeUrl: 'http://127.0.0.1:9115/probe?module=http_2xx&target=http%3A%2F%2Fexample.com%3A8080', + lastError: '', + lastScrape: '2019-11-04T11:52:13.516654-07:00', + lastScrapeDuration: 120916592, + health: 'up', + }, + { + discoveredLabels: { + __address__: 'localhost:9100', + __metrics_path__: '/metrics', + __scheme__: 'http', + job: 'node_exporter', + }, + labels: { + instance: 'localhost:9100', + job: 'node_exporter', + }, + scrapePool: 'node_exporter', + scrapeUrl: 'http://localhost:9100/metrics', + lastError: '', + lastScrape: '2019-11-04T11:52:14.145703-07:00', + lastScrapeDuration: 3842307, + health: 'up', + }, + { + discoveredLabels: { + __address__: 'localhost:9090', + __metrics_path__: '/metrics', + __scheme__: 'http', + job: 'prometheus/test', + }, + labels: { + instance: 'localhost:9090', + job: 'prometheus/test', + }, + scrapePool: 'prometheus/test', + scrapeUrl: 'http://localhost:9090/metrics', + lastError: '', + lastScrape: '2019-11-04T11:52:18.479731-07:00', + lastScrapeDuration: 4050976, + health: 'up', + }, + ], + }, +}); diff --git a/pkg/ui/react-app/src/pages/targets/target.test.ts b/pkg/ui/react-app/src/pages/targets/target.test.ts new file mode 100644 index 0000000000..e17ab59e77 --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/target.test.ts @@ -0,0 +1,44 @@ +/* eslint @typescript-eslint/camelcase: 0 */ + +import { sampleApiResponse } from './__testdata__/testdata'; +import { groupTargets, Target, ScrapePools, getColor } from './target'; + +describe('groupTargets', () => { + const targets: Target[] = sampleApiResponse.data.activeTargets as Target[]; + const targetGroups: ScrapePools = groupTargets(targets); + + it('groups a list of targets by scrape job', () => { + ['blackbox', 'prometheus/test', 'node_exporter'].forEach(scrapePool => { + expect(Object.keys(targetGroups)).toContain(scrapePool); + }); + Object.keys(targetGroups).forEach((scrapePool: string): void => { + const ts: Target[] = targetGroups[scrapePool].targets; + ts.forEach((t: Target) => { + expect(t.scrapePool).toEqual(scrapePool); + }); + }); + }); + + it('adds upCount during aggregation', () => { + const testCases: { [key: string]: number } = { blackbox: 3, 'prometheus/test': 1, node_exporter: 1 }; + Object.keys(testCases).forEach((scrapePool: string): void => { + expect(targetGroups[scrapePool].upCount).toEqual(testCases[scrapePool]); + }); + }); +}); + +describe('getColor', () => { + const testCases: { color: string; status: string }[] = [ + { color: 'danger', status: 'down' }, + { color: 'danger', status: 'DOWN' }, + { color: 'warning', status: 'unknown' }, + { color: 'warning', status: 'foo' }, + { color: 'success', status: 'up' }, + { color: 'success', status: 'Up' }, + ]; + testCases.forEach(({ color, status }) => { + it(`returns ${color} for ${status} status`, () => { + expect(getColor(status)).toEqual(color); + }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/targets/target.ts b/pkg/ui/react-app/src/pages/targets/target.ts new file mode 100644 index 0000000000..909c67e7b6 --- /dev/null +++ b/pkg/ui/react-app/src/pages/targets/target.ts @@ -0,0 +1,54 @@ +export interface Labels { + [key: string]: string; +} + +export interface Target { + discoveredLabels: Labels; + labels: Labels; + scrapePool: string; + scrapeUrl: string; + globalUrl: string; + lastError: string; + lastScrape: string; + lastScrapeDuration: number; + health: string; +} + +export interface DroppedTarget { + discoveredLabels: Labels; +} + +export interface ScrapePool { + upCount: number; + targets: Target[]; +} + +export interface ScrapePools { + [scrapePool: string]: ScrapePool; +} + +export const groupTargets = (targets: Target[]): ScrapePools => + targets.reduce((pools: ScrapePools, target: Target) => { + const { health, scrapePool } = target; + const up = health.toLowerCase() === 'up' ? 1 : 0; + if (!pools[scrapePool]) { + pools[scrapePool] = { + upCount: 0, + targets: [], + }; + } + pools[scrapePool].targets.push(target); + pools[scrapePool].upCount += up; + return pools; + }, {}); + +export const getColor = (health: string): string => { + switch (health.toLowerCase()) { + case 'up': + return 'success'; + case 'down': + return 'danger'; + default: + return 'warning'; + } +}; diff --git a/pkg/ui/react-app/src/pages/tsdbStatus/TSDBStatus.test.tsx b/pkg/ui/react-app/src/pages/tsdbStatus/TSDBStatus.test.tsx new file mode 100644 index 0000000000..828c3054df --- /dev/null +++ b/pkg/ui/react-app/src/pages/tsdbStatus/TSDBStatus.test.tsx @@ -0,0 +1,103 @@ +import * as React from 'react'; +import { mount, ReactWrapper } from 'enzyme'; +import { act } from 'react-dom/test-utils'; +import { Table } from 'reactstrap'; + +import TSDBStatus from './TSDBStatus'; +import { TSDBMap } from './TSDBStatus'; + +const fakeTSDBStatusResponse: { + status: string; + data: TSDBMap; +} = { + status: 'success', + data: { + labelValueCountByLabelName: [ + { + name: '__name__', + value: 5, + }, + ], + seriesCountByMetricName: [ + { + name: 'scrape_duration_seconds', + value: 1, + }, + { + name: 'scrape_samples_scraped', + value: 1, + }, + ], + memoryInBytesByLabelName: [ + { + name: '__name__', + value: 103, + }, + ], + seriesCountByLabelValuePair: [ + { + name: 'instance=localhost:9100', + value: 5, + }, + ], + }, +}; + +describe('TSDB Stats', () => { + beforeEach(() => { + fetchMock.resetMocks(); + }); + + describe('Table Data Validation', () => { + it('Table Test', async () => { + const tables = [ + { + data: fakeTSDBStatusResponse.data.labelValueCountByLabelName, + table_index: 0, + }, + { + data: fakeTSDBStatusResponse.data.seriesCountByMetricName, + table_index: 1, + }, + { + data: fakeTSDBStatusResponse.data.memoryInBytesByLabelName, + table_index: 2, + }, + { + data: fakeTSDBStatusResponse.data.seriesCountByLabelValuePair, + table_index: 3, + }, + ]; + + const mock = fetchMock.mockResponse(JSON.stringify(fakeTSDBStatusResponse)); + let page: any; + await act(async () => { + page = mount(); + }); + page.update(); + + expect(mock).toHaveBeenCalledWith('/path/prefix/api/v1/status/tsdb', { + cache: 'no-store', + credentials: 'same-origin', + }); + + for (let i = 0; i < tables.length; i++) { + const data = tables[i].data; + const table = page + .find(Table) + .at(tables[i].table_index) + .find('tbody'); + const rows = table.find('tr'); + for (let i = 0; i < data.length; i++) { + const firstRowColumns = rows + .at(i) + .find('td') + .map((column: ReactWrapper) => column.text()); + expect(rows.length).toBe(data.length); + expect(firstRowColumns[0]).toBe(data[i].name); + expect(firstRowColumns[1]).toBe(data[i].value.toString()); + } + } + }); + }); +}); diff --git a/pkg/ui/react-app/src/pages/tsdbStatus/TSDBStatus.tsx b/pkg/ui/react-app/src/pages/tsdbStatus/TSDBStatus.tsx new file mode 100644 index 0000000000..111787f967 --- /dev/null +++ b/pkg/ui/react-app/src/pages/tsdbStatus/TSDBStatus.tsx @@ -0,0 +1,81 @@ +import React, { FC } from 'react'; +import { RouteComponentProps } from '@reach/router'; +import { Table } from 'reactstrap'; + +import { useFetch } from '../../hooks/useFetch'; +import PathPrefixProps from '../../types/PathPrefixProps'; +import { withStatusIndicator } from '../../components/withStatusIndicator'; + +interface Stats { + name: string; + value: number; +} + +export interface TSDBMap { + seriesCountByMetricName: Stats[]; + labelValueCountByLabelName: Stats[]; + memoryInBytesByLabelName: Stats[]; + seriesCountByLabelValuePair: Stats[]; +} + +export const TSDBStatusContent: FC = ({ + labelValueCountByLabelName, + seriesCountByMetricName, + memoryInBytesByLabelName, + seriesCountByLabelValuePair, +}) => { + return ( +
+

TSDB Status

+

Head Cardinality Stats

+ {[ + { title: 'Top 10 label names with value count', stats: labelValueCountByLabelName }, + { title: 'Top 10 series count by metric names', stats: seriesCountByMetricName }, + { title: 'Top 10 label names with high memory usage', unit: 'Bytes', stats: memoryInBytesByLabelName }, + { title: 'Top 10 series count by label value pairs', stats: seriesCountByLabelValuePair }, + ].map(({ title, unit = 'Count', stats }) => { + return ( +
+

{title}

+ + + + + + + + + {stats.map(({ name, value }) => { + return ( + + + + + ); + })} + +
Name{unit}
{name}{value}
+
+ ); + })} +
+ ); +}; +TSDBStatusContent.displayName = 'TSDBStatusContent'; + +const TSDBStatusContentWithStatusIndicator = withStatusIndicator(TSDBStatusContent); + +const TSDBStatus: FC = ({ pathPrefix }) => { + const { response, error, isLoading } = useFetch(`${pathPrefix}/api/v1/status/tsdb`); + + return ( + + ); +}; + +export default TSDBStatus; diff --git a/pkg/ui/react-app/src/react-app-env.d.ts b/pkg/ui/react-app/src/react-app-env.d.ts new file mode 100644 index 0000000000..6431bc5fc6 --- /dev/null +++ b/pkg/ui/react-app/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/pkg/ui/react-app/src/setupTests.ts b/pkg/ui/react-app/src/setupTests.ts new file mode 100644 index 0000000000..962ec1c821 --- /dev/null +++ b/pkg/ui/react-app/src/setupTests.ts @@ -0,0 +1,9 @@ +import { configure } from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; +import { GlobalWithFetchMock } from 'jest-fetch-mock'; +import './globals'; + +configure({ adapter: new Adapter() }); +const customGlobal: GlobalWithFetchMock = global as GlobalWithFetchMock; +customGlobal.fetch = require('jest-fetch-mock'); +customGlobal.fetchMock = customGlobal.fetch; diff --git a/pkg/ui/react-app/src/thanos/Navbar.tsx b/pkg/ui/react-app/src/thanos/Navbar.tsx new file mode 100644 index 0000000000..5a923c05b7 --- /dev/null +++ b/pkg/ui/react-app/src/thanos/Navbar.tsx @@ -0,0 +1,49 @@ +import React, { FC, useState } from 'react'; +import { Link } from '@reach/router'; +import { Collapse, Navbar, NavbarToggler, Nav, NavItem, NavLink } from 'reactstrap'; +import PathPrefixProps from '../types/PathPrefixProps'; +import ThanosComponentProps from './types/ThanosComponentProps'; + +interface NavConfig { + name: string; + uri: string; +} + +const navConfig: { [component: string]: NavConfig[] } = { + query: [{ name: 'Graph', uri: '/new/graph' }], +}; + +const Navigation: FC = ({ pathPrefix, thanosComponent }) => { + const [isOpen, setIsOpen] = useState(false); + const toggle = () => setIsOpen(!isOpen); + return ( + + + + Thanos - {thanosComponent[0].toUpperCase()} + {thanosComponent.substr(1, thanosComponent.length)} + + + + + + ); +}; + +export default Navigation; diff --git a/pkg/ui/react-app/src/thanos/pages/index.tsx b/pkg/ui/react-app/src/thanos/pages/index.tsx new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/pkg/ui/react-app/src/thanos/pages/index.tsx @@ -0,0 +1 @@ +export {}; diff --git a/pkg/ui/react-app/src/thanos/types/ThanosComponentProps.ts b/pkg/ui/react-app/src/thanos/types/ThanosComponentProps.ts new file mode 100644 index 0000000000..c9f93a520e --- /dev/null +++ b/pkg/ui/react-app/src/thanos/types/ThanosComponentProps.ts @@ -0,0 +1,5 @@ +interface ThanosComponentProps { + thanosComponent: string; +} + +export default ThanosComponentProps; diff --git a/pkg/ui/react-app/src/types/PathPrefixProps.ts b/pkg/ui/react-app/src/types/PathPrefixProps.ts new file mode 100644 index 0000000000..34bf6d5396 --- /dev/null +++ b/pkg/ui/react-app/src/types/PathPrefixProps.ts @@ -0,0 +1,5 @@ +interface PathPrefixProps { + pathPrefix?: string; +} + +export default PathPrefixProps; diff --git a/pkg/ui/react-app/src/types/index.d.ts b/pkg/ui/react-app/src/types/index.d.ts new file mode 100644 index 0000000000..565069002d --- /dev/null +++ b/pkg/ui/react-app/src/types/index.d.ts @@ -0,0 +1,68 @@ +declare namespace jquery.flot { + // eslint-disable-next-line @typescript-eslint/class-name-casing + interface plot extends jquery.flot.plot { + destroy: () => void; + } + // eslint-disable-next-line @typescript-eslint/class-name-casing + interface plotOptions extends jquery.flot.plotOptions { + tooltip: { + show?: boolean; + cssClass?: string; + content: ( + label: string, + xval: number, + yval: number, + flotItem: jquery.flot.item & { + series: { + labels: { [key: string]: string }; + color: string; + data: (number | null)[][]; // [x,y][] + index: number; + }; + } + ) => string | string; + xDateFormat?: string; + yDateFormat?: string; + monthNames?: string; + dayNames?: string; + shifts?: { + x: number; + y: number; + }; + defaultTheme?: boolean; + lines?: boolean; + onHover?: () => string; + $compat?: boolean; + }; + crosshair: Partial; + xaxis: { [K in keyof jquery.flot.axisOptions]: jquery.flot.axisOptions[K] } & { + showTicks: boolean; + showMinorTicks: boolean; + timeBase: 'milliseconds'; + }; + series: { [K in keyof jquery.flot.seriesOptions]: jq.flot.seriesOptions[K] } & { + stack: boolean; + }; + } +} + +interface Color { + r: number; + g: number; + b: number; + a: number; + add: (c: string, d: number) => Color; + scale: (c: string, f: number) => Color; + toString: () => string; + normalize: () => Color; + clone: () => Color; +} + +interface JQueryStatic { + color: { + extract: (el: JQuery, css?: CSSStyleDeclaration) => Color; + make: (r?: number, g?: number, b?: number, a?: number) => Color; + parse: (c: string) => Color; + scale: () => Color; + }; +} diff --git a/pkg/ui/react-app/src/types/types.ts b/pkg/ui/react-app/src/types/types.ts new file mode 100644 index 0000000000..a30e64107a --- /dev/null +++ b/pkg/ui/react-app/src/types/types.ts @@ -0,0 +1,26 @@ +import { Alert, RuleState } from '../pages/alerts/AlertContents'; + +export interface Metric { + [key: string]: string; +} + +export interface QueryParams { + startTime: number; + endTime: number; + resolution: number; +} + +export interface Rule { + alerts: Alert[]; + annotations: Record; + duration: number; + evaluationTime: string; + health: string; + labels: Record; + lastError?: string; + lastEvaluation: string; + name: string; + query: string; + state: RuleState; + type: string; +} diff --git a/pkg/ui/react-app/src/utils/index.ts b/pkg/ui/react-app/src/utils/index.ts new file mode 100644 index 0000000000..ebcf1b6243 --- /dev/null +++ b/pkg/ui/react-app/src/utils/index.ts @@ -0,0 +1,212 @@ +import moment from 'moment-timezone'; + +import { PanelOptions, PanelType, PanelDefaultOptions } from '../pages/graph/Panel'; +import { PanelMeta } from '../pages/graph/PanelList'; + +export const generateID = () => { + return `_${Math.random() + .toString(36) + .substr(2, 9)}`; +}; + +export const byEmptyString = (p: string) => p.length > 0; + +export const isPresent = (obj: T): obj is NonNullable => obj !== null && obj !== undefined; + +export const escapeHTML = (str: string): string => { + const entityMap: { [key: string]: string } = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/', + }; + + return String(str).replace(/[&<>"'/]/g, function(s) { + return entityMap[s]; + }); +}; + +export const metricToSeriesName = (labels: { [key: string]: string }) => { + if (labels === null) { + return 'scalar'; + } + let tsName = (labels.__name__ || '') + '{'; + const labelStrings: string[] = []; + for (const label in labels) { + if (label !== '__name__') { + labelStrings.push(label + '="' + labels[label] + '"'); + } + } + tsName += labelStrings.join(', ') + '}'; + return tsName; +}; + +const rangeUnits: { [unit: string]: number } = { + y: 60 * 60 * 24 * 365, + w: 60 * 60 * 24 * 7, + d: 60 * 60 * 24, + h: 60 * 60, + m: 60, + s: 1, +}; + +export function parseRange(rangeText: string): number | null { + const rangeRE = new RegExp('^([0-9]+)([ywdhms]+)$'); + const matches = rangeText.match(rangeRE); + if (!matches || matches.length !== 3) { + return null; + } + const value = parseInt(matches[1]); + const unit = matches[2]; + return value * rangeUnits[unit]; +} + +export function formatRange(range: number): string { + for (const unit of Object.keys(rangeUnits)) { + if (range % rangeUnits[unit] === 0) { + return range / rangeUnits[unit] + unit; + } + } + return range + 's'; +} + +export function parseTime(timeText: string): number { + return moment.utc(timeText).valueOf(); +} + +export function formatTime(time: number): string { + return moment.utc(time).format('YYYY-MM-DD HH:mm:ss'); +} + +export const now = (): number => moment().valueOf(); + +export const humanizeDuration = (milliseconds: number): string => { + const sign = milliseconds < 0 ? '-' : ''; + const unsignedMillis = milliseconds < 0 ? -1 * milliseconds : milliseconds; + const duration = moment.duration(unsignedMillis, 'ms'); + const ms = Math.floor(duration.milliseconds()); + const s = Math.floor(duration.seconds()); + const m = Math.floor(duration.minutes()); + const h = Math.floor(duration.hours()); + const d = Math.floor(duration.asDays()); + if (d !== 0) { + return `${sign}${d}d ${h}h ${m}m ${s}s`; + } + if (h !== 0) { + return `${sign}${h}h ${m}m ${s}s`; + } + if (m !== 0) { + return `${sign}${m}m ${s}s`; + } + if (s !== 0) { + return `${sign}${s}.${ms}s`; + } + if (unsignedMillis > 0) { + return `${sign}${unsignedMillis.toFixed(3)}ms`; + } + return '0s'; +}; + +export const formatRelative = (startStr: string, end: number): string => { + const start = parseTime(startStr); + if (start < 0) { + return 'Never'; + } + return humanizeDuration(end - start); +}; + +const paramFormat = /^g\d+\..+=.+$/; + +export const decodePanelOptionsFromQueryString = (query: string): PanelMeta[] => { + if (query === '') { + return []; + } + const urlParams = query.substring(1).split('&'); + + return urlParams.reduce((panels, urlParam, i) => { + const panelsCount = panels.length; + const prefix = `g${panelsCount}.`; + if (urlParam.startsWith(`${prefix}expr=`)) { + const prefixLen = prefix.length; + return [ + ...panels, + { + id: generateID(), + key: `${panelsCount}`, + options: urlParams.slice(i).reduce((opts, param) => { + return param.startsWith(prefix) && paramFormat.test(param) + ? { ...opts, ...parseOption(param.substring(prefixLen)) } + : opts; + }, PanelDefaultOptions), + }, + ]; + } + return panels; + }, []); +}; + +export const parseOption = (param: string): Partial => { + const [opt, val] = param.split('='); + const decodedValue = decodeURIComponent(val.replace(/\+/g, ' ')); + switch (opt) { + case 'expr': + return { expr: decodedValue }; + + case 'tab': + return { type: decodedValue === '0' ? PanelType.Graph : PanelType.Table }; + + case 'stacked': + return { stacked: decodedValue === '1' }; + + case 'range_input': + const range = parseRange(decodedValue); + return isPresent(range) ? { range } : {}; + + case 'end_input': + case 'moment_input': + return { endTime: parseTime(decodedValue) }; + + case 'step_input': + const resolution = parseInt(decodedValue); + return resolution > 0 ? { resolution } : {}; + } + return {}; +}; + +export const formatParam = (key: string) => (paramName: string, value: number | string | boolean) => { + return `g${key}.${paramName}=${encodeURIComponent(value)}`; +}; + +export const toQueryString = ({ key, options }: PanelMeta) => { + const formatWithKey = formatParam(key); + const { expr, type, stacked, range, endTime, resolution } = options; + const time = isPresent(endTime) ? formatTime(endTime) : false; + const urlParams = [ + formatWithKey('expr', expr), + formatWithKey('tab', type === PanelType.Graph ? 0 : 1), + formatWithKey('stacked', stacked ? 1 : 0), + formatWithKey('range_input', formatRange(range)), + time ? `${formatWithKey('end_input', time)}&${formatWithKey('moment_input', time)}` : '', + isPresent(resolution) ? formatWithKey('step_input', resolution) : '', + ]; + return urlParams.filter(byEmptyString).join('&'); +}; + +export const encodePanelOptionsToQueryString = (panels: PanelMeta[]) => { + return `?${panels.map(toQueryString).join('&')}`; +}; + +export const createExpressionLink = (expr: string) => { + return `../graph?g0.expr=${encodeURIComponent(expr)}&g0.tab=1&g0.stacked=0&g0.range_input=1h`; +}; +export const mapObjEntries = ( + o: T, + cb: ([k, v]: [string, T[key]], i: number, arr: [string, T[key]][]) => Z +) => Object.entries(o).map(cb); + +export const callAll = (...fns: Array<(...args: any) => void>) => (...args: any) => { + // eslint-disable-next-line prefer-spread + fns.filter(Boolean).forEach(fn => fn.apply(null, args)); +}; diff --git a/pkg/ui/react-app/src/utils/utils.test.ts b/pkg/ui/react-app/src/utils/utils.test.ts new file mode 100644 index 0000000000..a59f3373d5 --- /dev/null +++ b/pkg/ui/react-app/src/utils/utils.test.ts @@ -0,0 +1,241 @@ +import moment from 'moment'; + +import { + escapeHTML, + metricToSeriesName, + formatTime, + parseTime, + formatRange, + parseRange, + humanizeDuration, + formatRelative, + now, + toQueryString, + encodePanelOptionsToQueryString, + parseOption, + decodePanelOptionsFromQueryString, +} from '.'; +import { PanelType } from '../pages/graph/Panel'; + +describe('Utils', () => { + describe('escapeHTML', (): void => { + it('escapes html sequences', () => { + expect(escapeHTML(`'example'&"another/example"`)).toEqual( + '<strong>'example'&"another/example"</strong>' + ); + }); + }); + + describe('metricToSeriesName', () => { + it('returns "{}" if labels is empty', () => { + const labels = {}; + expect(metricToSeriesName(labels)).toEqual('{}'); + }); + it('returns "metric_name{}" if labels only contains __name__', () => { + const labels = { __name__: 'metric_name' }; + expect(metricToSeriesName(labels)).toEqual('metric_name{}'); + }); + it('returns "{label1=value_1, ..., labeln=value_n} if there are many labels and no name', () => { + const labels = { label1: 'value_1', label2: 'value_2', label3: 'value_3' }; + expect(metricToSeriesName(labels)).toEqual('{label1="value_1", label2="value_2", label3="value_3"}'); + }); + it('returns "metric_name{label1=value_1, ... ,labeln=value_n}" if there are many labels and a name', () => { + const labels = { + __name__: 'metric_name', + label1: 'value_1', + label2: 'value_2', + label3: 'value_3', + }; + expect(metricToSeriesName(labels)).toEqual('metric_name{label1="value_1", label2="value_2", label3="value_3"}'); + }); + }); + + describe('Time format', () => { + describe('formatTime', () => { + it('returns a time string representing the time in seconds', () => { + expect(formatTime(1572049380000)).toEqual('2019-10-26 00:23:00'); + expect(formatTime(0)).toEqual('1970-01-01 00:00:00'); + }); + }); + + describe('parseTime', () => { + it('returns a time string representing the time in seconds', () => { + expect(parseTime('2019-10-26 00:23')).toEqual(1572049380000); + expect(parseTime('1970-01-01 00:00')).toEqual(0); + expect(parseTime('0001-01-01T00:00:00Z')).toEqual(-62135596800000); + }); + }); + + describe('formatRange', () => { + it('returns a time string representing the time in seconds in one unit', () => { + expect(formatRange(60 * 60 * 24 * 365)).toEqual('1y'); + expect(formatRange(60 * 60 * 24 * 7)).toEqual('1w'); + expect(formatRange(2 * 60 * 60 * 24)).toEqual('2d'); + expect(formatRange(60 * 60)).toEqual('1h'); + expect(formatRange(7 * 60)).toEqual('7m'); + expect(formatRange(63)).toEqual('63s'); + }); + }); + + describe('parseRange', () => { + it('returns a time string representing the time in seconds in one unit', () => { + expect(parseRange('1y')).toEqual(60 * 60 * 24 * 365); + expect(parseRange('1w')).toEqual(60 * 60 * 24 * 7); + expect(parseRange('2d')).toEqual(2 * 60 * 60 * 24); + expect(parseRange('1h')).toEqual(60 * 60); + expect(parseRange('7m')).toEqual(7 * 60); + expect(parseRange('63s')).toEqual(63); + }); + }); + + describe('humanizeDuration', () => { + it('humanizes zero', () => { + expect(humanizeDuration(0)).toEqual('0s'); + }); + it('humanizes milliseconds', () => { + expect(humanizeDuration(1.234567)).toEqual('1.235ms'); + expect(humanizeDuration(12.34567)).toEqual('12.346ms'); + expect(humanizeDuration(123.45678)).toEqual('123.457ms'); + expect(humanizeDuration(123)).toEqual('123.000ms'); + }); + it('humanizes seconds', () => { + expect(humanizeDuration(12340)).toEqual('12.340s'); + }); + it('humanizes minutes', () => { + expect(humanizeDuration(1234567)).toEqual('20m 34s'); + }); + + it('humanizes hours', () => { + expect(humanizeDuration(12345678)).toEqual('3h 25m 45s'); + }); + + it('humanizes days', () => { + expect(humanizeDuration(123456789)).toEqual('1d 10h 17m 36s'); + expect(humanizeDuration(123456789000)).toEqual('1428d 21h 33m 9s'); + }); + it('takes sign into account', () => { + expect(humanizeDuration(-123456789000)).toEqual('-1428d 21h 33m 9s'); + }); + }); + + describe('formatRelative', () => { + it('renders never for pre-beginning-of-time strings', () => { + expect(formatRelative('0001-01-01T00:00:00Z', now())).toEqual('Never'); + }); + it('renders a humanized duration for sane durations', () => { + expect(formatRelative('2019-11-04T09:15:29.578701-07:00', parseTime('2019-11-04T09:15:35.8701-07:00'))).toEqual( + '6.292s' + ); + expect(formatRelative('2019-11-04T09:15:35.8701-07:00', parseTime('2019-11-04T09:15:29.578701-07:00'))).toEqual( + '-6.292s' + ); + }); + }); + }); + + describe('URL Params', () => { + const panels: any = [ + { + key: '0', + options: { + endTime: 1572046620000, + expr: 'rate(node_cpu_seconds_total{mode="system"}[1m])', + range: 3600, + resolution: null, + stacked: false, + type: PanelType.Graph, + }, + }, + { + key: '1', + options: { + endTime: null, + expr: 'node_filesystem_avail_bytes', + range: 3600, + resolution: null, + stacked: false, + type: PanelType.Table, + }, + }, + ]; + const query = + '?g0.expr=rate(node_cpu_seconds_total%7Bmode%3D%22system%22%7D%5B1m%5D)&g0.tab=0&g0.stacked=0&g0.range_input=1h&g0.end_input=2019-10-25%2023%3A37%3A00&g0.moment_input=2019-10-25%2023%3A37%3A00&g1.expr=node_filesystem_avail_bytes&g1.tab=1&g1.stacked=0&g1.range_input=1h'; + + describe('decodePanelOptionsFromQueryString', () => { + it('returns [] when query is empty', () => { + expect(decodePanelOptionsFromQueryString('')).toEqual([]); + }); + it('returns and array of parsed params when query string is non-empty', () => { + expect(decodePanelOptionsFromQueryString(query)).toMatchObject(panels); + }); + }); + + describe('parseOption', () => { + it('should return empty object for invalid param', () => { + expect(parseOption('invalid_prop=foo')).toEqual({}); + }); + it('should parse expr param', () => { + expect(parseOption('expr=foo')).toEqual({ expr: 'foo' }); + }); + it('should parse stacked', () => { + expect(parseOption('stacked=1')).toEqual({ stacked: true }); + }); + it('should parse end_input', () => { + expect(parseOption('end_input=2019-10-25%2023%3A37')).toEqual({ endTime: moment.utc('2019-10-25 23:37').valueOf() }); + }); + it('should parse moment_input', () => { + expect(parseOption('moment_input=2019-10-25%2023%3A37')).toEqual({ + endTime: moment.utc('2019-10-25 23:37').valueOf(), + }); + }); + + describe('step_input', () => { + it('should return step_input parsed if > 0', () => { + expect(parseOption('step_input=2')).toEqual({ resolution: 2 }); + }); + it('should return empty object if step is equal 0', () => { + expect(parseOption('step_input=0')).toEqual({}); + }); + }); + + describe('range_input', () => { + it('should return range parsed if its not null', () => { + expect(parseOption('range_input=2h')).toEqual({ range: 7200 }); + }); + it('should return empty object for invalid value', () => { + expect(parseOption('range_input=h')).toEqual({}); + }); + }); + + describe('Parse type param', () => { + it('should return panel type "graph" if tab=0', () => { + expect(parseOption('tab=0')).toEqual({ type: PanelType.Graph }); + }); + it('should return panel type "table" if tab=1', () => { + expect(parseOption('tab=1')).toEqual({ type: PanelType.Table }); + }); + }); + }); + + describe('toQueryString', () => { + it('should generate query string from panel options', () => { + expect( + toQueryString({ + id: 'asdf', + key: '0', + options: { expr: 'foo', type: PanelType.Graph, stacked: true, range: 0, endTime: null, resolution: 1 }, + }) + ).toEqual('g0.expr=foo&g0.tab=0&g0.stacked=1&g0.range_input=0y&g0.step_input=1'); + }); + }); + + describe('encodePanelOptionsToQueryString', () => { + it('returns ? when panels is empty', () => { + expect(encodePanelOptionsToQueryString([])).toEqual('?'); + }); + it('returns an encoded query string otherwise', () => { + expect(encodePanelOptionsToQueryString(panels)).toEqual(query); + }); + }); + }); +}); diff --git a/pkg/ui/react-app/src/vendor/flot/jquery.flot.crosshair.js b/pkg/ui/react-app/src/vendor/flot/jquery.flot.crosshair.js new file mode 100644 index 0000000000..d1dec264fd --- /dev/null +++ b/pkg/ui/react-app/src/vendor/flot/jquery.flot.crosshair.js @@ -0,0 +1,191 @@ +/** + * + * THIS FILE WAS COPIED INTO THANOS FROM GRAFANA'S VENDORED FORK OF FLOT + * (LIVING AT https://github.com/grafana/grafana/tree/master/public/vendor/flot), + * WHICH CONTAINS FIXES FOR DISPLAYING NULL VALUES IN STACKED GRAPHS. THE ORIGINAL + * FLOT CODE WAS LICENSED UNDER THE MIT LICENSE AS STATED BELOW. ADDITIONAL + * CHANGES HAVE BEEN CONTRIBUTED TO THE GRAFANA FORK UNDER AN APACHE 2 LICENSE, SEE + * https://github.com/grafana/grafana/blob/master/license. + * + */ + +/* eslint-disable prefer-spread */ +/* eslint-disable no-loop-func */ +/* eslint-disable @typescript-eslint/no-this-alias */ +/* eslint-disable no-redeclare */ +/* eslint-disable no-useless-escape */ +/* eslint-disable prefer-const */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-use-before-define */ +/* eslint-disable eqeqeq */ +/* eslint-disable no-var */ +/* Flot plugin for showing crosshairs when the mouse hovers over the plot. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +The plugin supports these options: + + crosshair: { + mode: null or "x" or "y" or "xy" + color: color + lineWidth: number + } + +Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical +crosshair that lets you trace the values on the x axis, "y" enables a +horizontal crosshair and "xy" enables them both. "color" is the color of the +crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of +the drawn lines (default is 1). + +The plugin also adds four public methods: + + - setCrosshair( pos ) + + Set the position of the crosshair. Note that this is cleared if the user + moves the mouse. "pos" is in coordinates of the plot and should be on the + form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple + axes), which is coincidentally the same format as what you get from a + "plothover" event. If "pos" is null, the crosshair is cleared. + + - clearCrosshair() + + Clear the crosshair. + + - lockCrosshair(pos) + + Cause the crosshair to lock to the current location, no longer updating if + the user moves the mouse. Optionally supply a position (passed on to + setCrosshair()) to move it to. + + Example usage: + + var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } }; + $("#graph").bind( "plothover", function ( evt, position, item ) { + if ( item ) { + // Lock the crosshair to the data point being hovered + myFlot.lockCrosshair({ + x: item.datapoint[ 0 ], + y: item.datapoint[ 1 ] + }); + } else { + // Return normal crosshair operation + myFlot.unlockCrosshair(); + } + }); + + - unlockCrosshair() + + Free the crosshair to move again after locking it. +*/ + +(function($) { + const options = { + crosshair: { + mode: null, // one of null, "x", "y" or "xy", + color: 'rgba(170, 0, 0, 0.80)', + lineWidth: 1, + }, + }; + + function init(plot) { + // position of crosshair in pixels + const crosshair = { x: -1, y: -1, locked: false }; + + plot.setCrosshair = function setCrosshair(pos) { + if (!pos) crosshair.x = -1; + else { + const o = plot.p2c(pos); + crosshair.x = Math.max(0, Math.min(o.left, plot.width())); + crosshair.y = Math.max(0, Math.min(o.top, plot.height())); + } + + plot.triggerRedrawOverlay(); + }; + + plot.clearCrosshair = plot.setCrosshair; // passes null for pos + + plot.lockCrosshair = function lockCrosshair(pos) { + if (pos) plot.setCrosshair(pos); + crosshair.locked = true; + }; + + plot.unlockCrosshair = function unlockCrosshair() { + crosshair.locked = false; + }; + + function onMouseOut() { + if (crosshair.locked) return; + + if (crosshair.x != -1) { + crosshair.x = -1; + plot.triggerRedrawOverlay(); + } + } + + function onMouseMove(e) { + if (crosshair.locked) return; + + if (plot.getSelection && plot.getSelection()) { + crosshair.x = -1; // hide the crosshair while selecting + return; + } + + const offset = plot.offset(); + crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width())); + crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height())); + plot.triggerRedrawOverlay(); + } + + plot.hooks.bindEvents.push(function(plot, eventHolder) { + if (!plot.getOptions().crosshair.mode) return; + + eventHolder.mouseout(onMouseOut); + eventHolder.mousemove(onMouseMove); + }); + + plot.hooks.drawOverlay.push(function(plot, ctx) { + const c = plot.getOptions().crosshair; + if (!c.mode) return; + + const plotOffset = plot.getPlotOffset(); + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + if (crosshair.x != -1) { + const adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0; + + ctx.strokeStyle = c.color; + ctx.lineWidth = c.lineWidth; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + if (c.mode.indexOf('x') != -1) { + const drawX = Math.floor(crosshair.x) + adj; + ctx.moveTo(drawX, 0); + ctx.lineTo(drawX, plot.height()); + } + if (c.mode.indexOf('y') != -1) { + const drawY = Math.floor(crosshair.y) + adj; + ctx.moveTo(0, drawY); + ctx.lineTo(plot.width(), drawY); + } + ctx.stroke(); + } + ctx.restore(); + }); + + plot.hooks.shutdown.push(function(plot, eventHolder) { + eventHolder.unbind('mouseout', onMouseOut); + eventHolder.unbind('mousemove', onMouseMove); + }); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'crosshair', + version: '1.0', + }); +})(window.jQuery); diff --git a/pkg/ui/react-app/src/vendor/flot/jquery.flot.js b/pkg/ui/react-app/src/vendor/flot/jquery.flot.js new file mode 100644 index 0000000000..136e64d7fa --- /dev/null +++ b/pkg/ui/react-app/src/vendor/flot/jquery.flot.js @@ -0,0 +1,3412 @@ +/** + * + * THIS FILE WAS COPIED INTO THANOS FROM GRAFANA'S VENDORED FORK OF FLOT + * (LIVING AT https://github.com/grafana/grafana/tree/master/public/vendor/flot), + * WHICH CONTAINS FIXES FOR DISPLAYING NULL VALUES IN STACKED GRAPHS. THE ORIGINAL + * FLOT CODE WAS LICENSED UNDER THE MIT LICENSE AS STATED BELOW. ADDITIONAL + * CHANGES HAVE BEEN CONTRIBUTED TO THE GRAFANA FORK UNDER AN APACHE 2 LICENSE, SEE + * https://github.com/grafana/grafana/blob/master/license. + * + */ + +/* eslint-disable prefer-spread */ +/* eslint-disable no-loop-func */ +/* eslint-disable @typescript-eslint/no-this-alias */ +/* eslint-disable no-redeclare */ +/* eslint-disable no-useless-escape */ +/* eslint-disable prefer-const */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-use-before-define */ +/* eslint-disable eqeqeq */ +/* eslint-disable no-var */ +/* Javascript plotting library for jQuery, version 0.8.3. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +*/ + +// first an inline dependency, jquery.colorhelpers.js, we inline it here +// for convenience + +/* Plugin for jQuery for working with colors. + * + * Version 1.1. + * + * Inspiration from jQuery color animation plugin by John Resig. + * + * Released under the MIT license by Ole Laursen, October 2009. + * + * Examples: + * + * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() + * var c = $.color.extract($("#mydiv"), 'background-color'); + * console.log(c.r, c.g, c.b, c.a); + * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" + * + * Note that .scale() and .add() return the same modified object + * instead of making a new one. + * + * V. 1.1: Fix error handling so e.g. parsing an empty string does + * produce a color rather than just crashing. + */ + +(function($) { + $.color = {}; + $.color.make = function(r, g, b, a) { + var o = {}; + o.r = r || 0; + o.g = g || 0; + o.b = b || 0; + o.a = a != null ? a : 1; + o.add = function(c, d) { + for (var i = 0; i < c.length; ++i) o[c.charAt(i)] += d; + return o.normalize(); + }; + o.scale = function(c, f) { + for (var i = 0; i < c.length; ++i) o[c.charAt(i)] *= f; + return o.normalize(); + }; + o.toString = function() { + if (o.a >= 1) { + return 'rgb(' + [o.r, o.g, o.b].join(',') + ')'; + } else { + return 'rgba(' + [o.r, o.g, o.b, o.a].join(',') + ')'; + } + }; + o.normalize = function() { + function clamp(min, value, max) { + return value < min ? min : value > max ? max : value; + } + o.r = clamp(0, parseInt(o.r), 255); + o.g = clamp(0, parseInt(o.g), 255); + o.b = clamp(0, parseInt(o.b), 255); + o.a = clamp(0, o.a, 1); + return o; + }; + o.clone = function() { + return $.color.make(o.r, o.b, o.g, o.a); + }; + return o.normalize(); + }; + $.color.extract = function(elem, css) { + var c; + do { + c = elem.css(css).toLowerCase(); + if (c != '' && c != 'transparent') break; + elem = elem.parent(); + } while (elem.length && !$.nodeName(elem.get(0), 'body')); + if (c == 'rgba(0, 0, 0, 0)') c = 'transparent'; + return $.color.parse(c); + }; + $.color.parse = function(str) { + var res, + m = $.color.make; + if ((res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))) + return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10)); + if ((res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))) + return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4])); + if ((res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))) + return m(parseFloat(res[1]) * 2.55, parseFloat(res[2]) * 2.55, parseFloat(res[3]) * 2.55); + if ( + (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec( + str + )) + ) + return m(parseFloat(res[1]) * 2.55, parseFloat(res[2]) * 2.55, parseFloat(res[3]) * 2.55, parseFloat(res[4])); + if ((res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))) + return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16)); + if ((res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))) + return m(parseInt(res[1] + res[1], 16), parseInt(res[2] + res[2], 16), parseInt(res[3] + res[3], 16)); + var name = $.trim(str).toLowerCase(); + if (name == 'transparent') return m(255, 255, 255, 0); + else { + res = lookupColors[name] || [0, 0, 0]; + return m(res[0], res[1], res[2]); + } + }; + var lookupColors = { + aqua: [0, 255, 255], + azure: [240, 255, 255], + beige: [245, 245, 220], + black: [0, 0, 0], + blue: [0, 0, 255], + brown: [165, 42, 42], + cyan: [0, 255, 255], + darkblue: [0, 0, 139], + darkcyan: [0, 139, 139], + darkgrey: [169, 169, 169], + darkgreen: [0, 100, 0], + darkkhaki: [189, 183, 107], + darkmagenta: [139, 0, 139], + darkolivegreen: [85, 107, 47], + darkorange: [255, 140, 0], + darkorchid: [153, 50, 204], + darkred: [139, 0, 0], + darksalmon: [233, 150, 122], + darkviolet: [148, 0, 211], + fuchsia: [255, 0, 255], + gold: [255, 215, 0], + green: [0, 128, 0], + indigo: [75, 0, 130], + khaki: [240, 230, 140], + lightblue: [173, 216, 230], + lightcyan: [224, 255, 255], + lightgreen: [144, 238, 144], + lightgrey: [211, 211, 211], + lightpink: [255, 182, 193], + lightyellow: [255, 255, 224], + lime: [0, 255, 0], + magenta: [255, 0, 255], + maroon: [128, 0, 0], + navy: [0, 0, 128], + olive: [128, 128, 0], + orange: [255, 165, 0], + pink: [255, 192, 203], + purple: [128, 0, 128], + violet: [128, 0, 128], + red: [255, 0, 0], + silver: [192, 192, 192], + white: [255, 255, 255], + yellow: [255, 255, 0], + }; +})(window.jQuery); + +// the actual Flot code +(function($) { + // Cache the prototype hasOwnProperty for faster access + + let hasOwnProperty = Object.prototype.hasOwnProperty; + + // A shim to provide 'detach' to jQuery versions prior to 1.4. Using a DOM + // operation produces the same effect as detach, i.e. removing the element + // without touching its jQuery data. + + // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+. + + if (!$.fn.detach) { + $.fn.detach = function() { + return this.each(function() { + if (this.parentNode) { + this.parentNode.removeChild(this); + } + }); + }; + } + + /////////////////////////////////////////////////////////////////////////// + // The Canvas object is a wrapper around an HTML5 tag. + // + // @constructor + // @param {string} cls List of classes to apply to the canvas. + // @param {element} container Element onto which to append the canvas. + // + // Requiring a container is a little iffy, but unfortunately canvas + // operations don't work unless the canvas is attached to the DOM. + + function Canvas(cls, container) { + var element = container.children('.' + cls)[0]; + + if (element == null) { + element = document.createElement('canvas'); + element.className = cls; + + $(element) + .css({ direction: 'ltr', position: 'absolute', left: 0, top: 0 }) + .appendTo(container); + + // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas + + if (!element.getContext) { + if (window.G_vmlCanvasManager) { + element = window.G_vmlCanvasManager.initElement(element); + } else { + throw new Error( + "Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode." + ); + } + } + } + + this.element = element; + + var context = (this.context = element.getContext('2d')); + + // Determine the screen's ratio of physical to device-independent + // pixels. This is the ratio between the canvas width that the browser + // advertises and the number of pixels actually present in that space. + + // The iPhone 4, for example, has a device-independent width of 320px, + // but its screen is actually 640px wide. It therefore has a pixel + // ratio of 2, while most normal devices have a ratio of 1. + + let devicePixelRatio = window.devicePixelRatio || 1, + backingStoreRatio = + context.webkitBackingStorePixelRatio || + context.mozBackingStorePixelRatio || + context.msBackingStorePixelRatio || + context.oBackingStorePixelRatio || + context.backingStorePixelRatio || + 1; + + this.pixelRatio = devicePixelRatio / backingStoreRatio; + + // Size the canvas to match the internal dimensions of its container + + this.resize(container.width(), container.height()); + + // Collection of HTML div layers for text overlaid onto the canvas + + this.textContainer = null; + this.text = {}; + + // Cache of text fragments and metrics, so we can avoid expensively + // re-calculating them when the plot is re-rendered in a loop. + + this._textCache = {}; + this._textSizeCache = window.flotTextSizeCache = window.flotTextSizeCache || {}; + } + + // Resizes the canvas to the given dimensions. + // + // @param {number} width New width of the canvas, in pixels. + // @param {number} width New height of the canvas, in pixels. + + Canvas.prototype.resize = function(width, height) { + if (width <= 0 || height <= 0) { + throw new Error('Invalid dimensions for plot, width = ' + width + ', height = ' + height); + } + + let element = this.element, + context = this.context, + pixelRatio = this.pixelRatio; + + // Resize the canvas, increasing its density based on the display's + // pixel ratio; basically giving it more pixels without increasing the + // size of its element, to take advantage of the fact that retina + // displays have that many more pixels in the same advertised space. + + // Resizing should reset the state (excanvas seems to be buggy though) + + if (this.width != width) { + element.width = width * pixelRatio; + element.style.width = width + 'px'; + this.width = width; + } + + if (this.height != height) { + element.height = height * pixelRatio; + element.style.height = height + 'px'; + this.height = height; + } + + // Save the context, so we can reset in case we get replotted. The + // restore ensure that we're really back at the initial state, and + // should be safe even if we haven't saved the initial state yet. + + context.restore(); + context.save(); + + // Scale the coordinate space to match the display density; so even though we + // may have twice as many pixels, we still want lines and other drawing to + // appear at the same size; the extra pixels will just make them crisper. + + context.scale(pixelRatio, pixelRatio); + }; + + // Clears the entire canvas area, not including any overlaid HTML text + + Canvas.prototype.clear = function() { + this.context.clearRect(0, 0, this.width, this.height); + }; + + // Finishes rendering the canvas, including managing the text overlay. + + Canvas.prototype.render = function() { + let cache = this._textCache; + + // For each text layer, add elements marked as active that haven't + // already been rendered, and remove those that are no longer active. + + for (let layerKey in cache) { + if (hasOwnProperty.call(cache, layerKey)) { + let layer = this.getTextLayer(layerKey), + layerCache = cache[layerKey]; + + layer.hide(); + + for (let styleKey in layerCache) { + if (hasOwnProperty.call(layerCache, styleKey)) { + let styleCache = layerCache[styleKey]; + for (let key in styleCache) { + if (hasOwnProperty.call(styleCache, key)) { + let positions = styleCache[key].positions; + + for (var i = 0, position; (position = positions[i]); i++) { + if (position.active) { + if (!position.rendered) { + layer.append(position.element); + position.rendered = true; + } + } else { + positions.splice(i--, 1); + if (position.rendered) { + position.element.detach(); + } + } + } + + if (positions.length == 0) { + delete styleCache[key]; + } + } + } + } + } + + layer.show(); + } + } + }; + + // Creates (if necessary) and returns the text overlay container. + // + // @param {string} classes String of space-separated CSS classes used to + // uniquely identify the text layer. + // @return {object} The jQuery-wrapped text-layer div. + + Canvas.prototype.getTextLayer = function(classes) { + let layer = this.text[classes]; + + // Create the text layer if it doesn't exist + + if (layer == null) { + // Create the text layer container, if it doesn't exist + + if (this.textContainer == null) { + this.textContainer = $("
") + .css({ + position: 'absolute', + top: 0, + left: 0, + bottom: 0, + right: 0, + 'font-size': 'smaller', + color: '#545454', + }) + .insertAfter(this.element); + } + + layer = this.text[classes] = $('
') + .addClass(classes) + .css({ + position: 'absolute', + top: 0, + left: 0, + bottom: 0, + right: 0, + }) + .appendTo(this.textContainer); + } + + return layer; + }; + + // Creates (if necessary) and returns a text info object. + // + // The object looks like this: + // + // { + // width: Width of the text's wrapper div. + // height: Height of the text's wrapper div. + // element: The jQuery-wrapped HTML div containing the text. + // positions: Array of positions at which this text is drawn. + // } + // + // The positions array contains objects that look like this: + // + // { + // active: Flag indicating whether the text should be visible. + // rendered: Flag indicating whether the text is currently visible. + // element: The jQuery-wrapped HTML div containing the text. + // x: X coordinate at which to draw the text. + // y: Y coordinate at which to draw the text. + // } + // + // Each position after the first receives a clone of the original element. + // + // The idea is that that the width, height, and general 'identity' of the + // text is constant no matter where it is placed; the placements are a + // secondary property. + // + // Canvas maintains a cache of recently-used text info objects; getTextInfo + // either returns the cached element or creates a new entry. + // + // @param {string} layer A string of space-separated CSS classes uniquely + // identifying the layer containing this text. + // @param {string} text Text string to retrieve info for. + // @param {(string|object)=} font Either a string of space-separated CSS + // classes or a font-spec object, defining the text's font and style. + // @param {number=} angle Angle at which to rotate the text, in degrees. + // Angle is currently unused, it will be implemented in the future. + // @param {number=} width Maximum width of the text before it wraps. + // @return {object} a text info object. + + Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) { + let textStyle, layerCache, styleCache, info; + + // Cast the value to a string, in case we were given a number or such + + text = '' + text; + + // If the font is a font-spec object, generate a CSS font definition + + if (typeof font === 'object') { + textStyle = + font.style + + ' ' + + font.variant + + ' ' + + font.weight + + ' ' + + font.size + + 'px/' + + font.lineHeight + + 'px ' + + font.family; + } else { + textStyle = font; + } + + // Retrieve (or create) the cache for the text's layer and styles + + layerCache = this._textCache[layer]; + + if (layerCache == null) { + layerCache = this._textCache[layer] = {}; + } + + styleCache = layerCache[textStyle]; + + if (styleCache == null) { + styleCache = layerCache[textStyle] = {}; + } + + info = styleCache[text]; + + // If we can't find a matching element in our cache, create a new one + + if (info == null) { + var element = $('
') + .html(text) + .css({ + position: 'absolute', + 'max-width': width, + top: -9999, + }) + .appendTo(this.getTextLayer(layer)); + + if (typeof font === 'object') { + element.css({ + font: textStyle, + color: font.color, + }); + } else if (typeof font === 'string') { + element.addClass(font); + } + + info = styleCache[text] = { element: element, positions: [] }; + + let size = this._textSizeCache[text]; + if (size) { + info.width = size.width; + info.height = size.height; + } else { + info.width = element.outerWidth(true); + info.height = element.outerHeight(true); + this._textSizeCache[text] = { width: info.width, height: info.height }; + } + element.detach(); + } + + return info; + }; + + // Adds a text string to the canvas text overlay. + // + // The text isn't drawn immediately; it is marked as rendering, which will + // result in its addition to the canvas on the next render pass. + // + // @param {string} layer A string of space-separated CSS classes uniquely + // identifying the layer containing this text. + // @param {number} x X coordinate at which to draw the text. + // @param {number} y Y coordinate at which to draw the text. + // @param {string} text Text string to draw. + // @param {(string|object)=} font Either a string of space-separated CSS + // classes or a font-spec object, defining the text's font and style. + // @param {number=} angle Angle at which to rotate the text, in degrees. + // Angle is currently unused, it will be implemented in the future. + // @param {number=} width Maximum width of the text before it wraps. + // @param {string=} halign Horizontal alignment of the text; either "left", + // "center" or "right". + // @param {string=} valign Vertical alignment of the text; either "top", + // "middle" or "bottom". + + Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) { + let info = this.getTextInfo(layer, text, font, angle, width), + positions = info.positions; + + // Tweak the div's position to match the text's alignment + + if (halign == 'center') { + x -= info.width / 2; + } else if (halign == 'right') { + x -= info.width; + } + + if (valign == 'middle') { + y -= info.height / 2; + } else if (valign == 'bottom') { + y -= info.height; + } + + // Determine whether this text already exists at this position. + // If so, mark it for inclusion in the next render pass. + + for (var i = 0, position; (position = positions[i]); i++) { + if (position.x == x && position.y == y) { + position.active = true; + return; + } + } + + // If the text doesn't exist at this position, create a new entry + + // For the very first position we'll re-use the original element, + // while for subsequent ones we'll clone it. + + position = { + active: true, + rendered: false, + element: positions.length ? info.element.clone() : info.element, + x: x, + y: y, + }; + + positions.push(position); + + // Move the element to its final position within the container + + position.element.css({ + top: Math.round(y), + left: Math.round(x), + 'text-align': halign, // In case the text wraps + }); + }; + + // Removes one or more text strings from the canvas text overlay. + // + // If no parameters are given, all text within the layer is removed. + // + // Note that the text is not immediately removed; it is simply marked as + // inactive, which will result in its removal on the next render pass. + // This avoids the performance penalty for 'clear and redraw' behavior, + // where we potentially get rid of all text on a layer, but will likely + // add back most or all of it later, as when redrawing axes, for example. + // + // @param {string} layer A string of space-separated CSS classes uniquely + // identifying the layer containing this text. + // @param {number=} x X coordinate of the text. + // @param {number=} y Y coordinate of the text. + // @param {string=} text Text string to remove. + // @param {(string|object)=} font Either a string of space-separated CSS + // classes or a font-spec object, defining the text's font and style. + // @param {number=} angle Angle at which the text is rotated, in degrees. + // Angle is currently unused, it will be implemented in the future. + + Canvas.prototype.removeText = function(layer, x, y, text, font, angle) { + if (text == null) { + let layerCache = this._textCache[layer]; + if (layerCache != null) { + for (let styleKey in layerCache) { + if (hasOwnProperty.call(layerCache, styleKey)) { + let styleCache = layerCache[styleKey]; + for (let key in styleCache) { + if (hasOwnProperty.call(styleCache, key)) { + var positions = styleCache[key].positions; + for (var i = 0, position; (position = positions[i]); i++) { + position.active = false; + } + } + } + } + } + } + } else { + var positions = this.getTextInfo(layer, text, font, angle).positions; + for (var i = 0, position; (position = positions[i]); i++) { + if (position.x == x && position.y == y) { + position.active = false; + } + } + } + }; + + /////////////////////////////////////////////////////////////////////////// + // The top-level container for the entire plot. + + function Plot(placeholder, data_, options_, plugins) { + // data is on the form: + // [ series1, series2 ... ] + // where series is either just the data as [ [x1, y1], [x2, y2], ... ] + // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... } + + let series = [], + options = { + // the color theme used for graphs + colors: ['#edc240', '#afd8f8', '#cb4b4b', '#4da74d', '#9440ed'], + legend: { + show: true, + noColumns: 1, // number of colums in legend table + labelFormatter: null, // fn: string -> string + labelBoxBorderColor: '#ccc', // border color for the little label boxes + container: null, // container (as jQuery object) to put legend in, null means default on top of graph + position: 'ne', // position of default legend container within plot + margin: 5, // distance from grid edge to default legend container within plot + backgroundColor: null, // null means auto-detect + backgroundOpacity: 0.85, // set to 0 to avoid background + sorted: null, // default to no legend sorting + }, + xaxis: { + show: null, // null = auto-detect, true = always, false = never + position: 'bottom', // or "top" + mode: null, // null or "time" + font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" } + color: null, // base color, labels, ticks + tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)" + transform: null, // null or f: number -> number to transform axis + inverseTransform: null, // if transform is set, this should be the inverse function + min: null, // min. value to show, null means set automatically + max: null, // max. value to show, null means set automatically + autoscaleMargin: null, // margin in % to add if auto-setting min/max + ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks + tickFormatter: null, // fn: number -> string + labelWidth: null, // size of tick labels in pixels + labelHeight: null, + reserveSpace: null, // whether to reserve space even if axis isn't shown + tickLength: null, // size in pixels of ticks, or "full" for whole line + alignTicksWithAxis: null, // axis number or null for no sync + tickDecimals: null, // no. of decimals, null means auto + tickSize: null, // number or [number, "unit"] + minTickSize: null, // number or [number, "unit"] + }, + yaxis: { + autoscaleMargin: 0.02, + position: 'left', // or "right" + }, + xaxes: [], + yaxes: [], + series: { + points: { + show: false, + radius: 3, + lineWidth: 2, // in pixels + fill: true, + fillColor: '#ffffff', + symbol: 'circle', // or callback + }, + lines: { + // we don't put in show: false so we can see + // whether lines were actively disabled + lineWidth: 2, // in pixels + fill: false, + fillColor: null, + steps: false, + // Omit 'zero', so we can later default its value to + // match that of the 'fill' option. + }, + bars: { + show: false, + lineWidth: 2, // in pixels + barWidth: 1, // in units of the x axis + fill: true, + fillColor: null, + align: 'left', // "left", "right", or "center" + horizontal: false, + zero: true, + }, + shadowSize: 3, + highlightColor: null, + }, + grid: { + show: true, + aboveData: false, + color: '#545454', // primary color used for outline and labels + backgroundColor: null, // null for transparent, else color + borderColor: null, // set if different from the grid color + tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)" + margin: 0, // distance from the canvas edge to the grid + labelMargin: 5, // in pixels + eventSectionHeight: 0, // space for event section + axisMargin: 8, // in pixels + borderWidth: 2, // in pixels + minBorderMargin: null, // in pixels, null means taken from points radius + markings: null, // array of ranges or fn: axes -> array of ranges + markingsColor: '#f4f4f4', + markingsLineWidth: 2, + // interactive stuff + clickable: false, + hoverable: false, + autoHighlight: true, // highlight in case mouse is near + mouseActiveRadius: 10, // how far the mouse can be away to activate an item + }, + interaction: { + redrawOverlayInterval: 1000 / 60, // time between updates, -1 means in same flow + }, + hooks: {}, + }, + surface = null, // the canvas for the plot itself + overlay = null, // canvas for interactive stuff on top of plot + eventHolder = null, // jQuery object that events should be bound to + ctx = null, + octx = null, + xaxes = [], + yaxes = [], + plotOffset = { left: 0, right: 0, top: 0, bottom: 0 }, + plotWidth = 0, + plotHeight = 0, + hooks = { + processOptions: [], + processRawData: [], + processDatapoints: [], + processOffset: [], + processRange: [], + drawBackground: [], + drawSeries: [], + draw: [], + bindEvents: [], + drawOverlay: [], + shutdown: [], + }, + plot = this; + + // public functions + plot.setData = setData; + plot.setupGrid = setupGrid; + plot.draw = draw; + plot.getPlaceholder = function() { + return placeholder; + }; + plot.getCanvas = function() { + return surface.element; + }; + plot.getPlotOffset = function() { + return plotOffset; + }; + plot.width = function() { + return plotWidth; + }; + plot.height = function() { + return plotHeight; + }; + plot.offset = function() { + let o = eventHolder.offset(); + o.left += plotOffset.left; + o.top += plotOffset.top; + return o; + }; + plot.getData = function() { + return series; + }; + plot.getAxes = function() { + var res = {}; + $.each(xaxes.concat(yaxes), function(_, axis) { + if (axis) res[axis.direction + (axis.n != 1 ? axis.n : '') + 'axis'] = axis; + }); + return res; + }; + plot.getXAxes = function() { + return xaxes; + }; + plot.getYAxes = function() { + return yaxes; + }; + plot.c2p = canvasToAxisCoords; + plot.p2c = axisToCanvasCoords; + plot.getOptions = function() { + return options; + }; + plot.highlight = highlight; + plot.unhighlight = unhighlight; + plot.triggerRedrawOverlay = triggerRedrawOverlay; + plot.pointOffset = function(point) { + return { + left: parseInt(xaxes[axisNumber(point, 'x') - 1].p2c(+point.x) + plotOffset.left, 10), + top: parseInt(yaxes[axisNumber(point, 'y') - 1].p2c(+point.y) + plotOffset.top, 10), + }; + }; + plot.shutdown = shutdown; + plot.destroy = function() { + shutdown(); + placeholder.removeData('plot').empty(); + + series = []; + options = null; + surface = null; + overlay = null; + eventHolder = null; + ctx = null; + octx = null; + xaxes = []; + yaxes = []; + hooks = null; + highlights = []; + plot = null; + }; + plot.resize = function() { + let width = placeholder.width(), + height = placeholder.height(); + surface.resize(width, height); + overlay.resize(width, height); + }; + + // public attributes + plot.hooks = hooks; + + // initialize + initPlugins(plot); + parseOptions(options_); + setupCanvases(); + setData(data_); + setupGrid(); + draw(); + bindEvents(); + + function executeHooks(hook, args) { + args = [plot].concat(args); + for (var i = 0; i < hook.length; ++i) hook[i].apply(this, args); + } + + function initPlugins() { + // References to key classes, allowing plugins to modify them + + let classes = { + Canvas: Canvas, + }; + + for (let i = 0; i < plugins.length; ++i) { + let p = plugins[i]; + p.init(plot, classes); + if (p.options) $.extend(true, options, p.options); + } + } + + function parseOptions(opts) { + $.extend(true, options, opts); + + // $.extend merges arrays, rather than replacing them. When less + // colors are provided than the size of the default palette, we + // end up with those colors plus the remaining defaults, which is + // not expected behavior; avoid it by replacing them here. + + if (opts && opts.colors) { + options.colors = opts.colors; + } + + if (options.xaxis.color == null) + options.xaxis.color = $.color + .parse(options.grid.color) + .scale('a', 0.22) + .toString(); + if (options.yaxis.color == null) + options.yaxis.color = $.color + .parse(options.grid.color) + .scale('a', 0.22) + .toString(); + + if (options.xaxis.tickColor == null) + // grid.tickColor for back-compatibility + options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color; + if (options.yaxis.tickColor == null) + // grid.tickColor for back-compatibility + options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color; + + if (options.grid.borderColor == null) options.grid.borderColor = options.grid.color; + if (options.grid.tickColor == null) + options.grid.tickColor = $.color + .parse(options.grid.color) + .scale('a', 0.22) + .toString(); + + // Fill in defaults for axis options, including any unspecified + // font-spec fields, if a font-spec was provided. + + // If no x/y axis options were provided, create one of each anyway, + // since the rest of the code assumes that they exist. + + var i, + axisOptions, + axisCount, + fontSize = placeholder.css('font-size'), + fontSizeDefault = fontSize ? +fontSize.replace('px', '') : 13, + fontDefaults = { + style: placeholder.css('font-style'), + size: Math.round(0.8 * fontSizeDefault), + variant: placeholder.css('font-variant'), + weight: placeholder.css('font-weight'), + family: placeholder.css('font-family'), + }; + + axisCount = options.xaxes.length || 1; + for (i = 0; i < axisCount; ++i) { + axisOptions = options.xaxes[i]; + if (axisOptions && !axisOptions.tickColor) { + axisOptions.tickColor = axisOptions.color; + } + + axisOptions = $.extend(true, {}, options.xaxis, axisOptions); + options.xaxes[i] = axisOptions; + + if (axisOptions.font) { + axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); + if (!axisOptions.font.color) { + axisOptions.font.color = axisOptions.color; + } + if (!axisOptions.font.lineHeight) { + axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); + } + } + } + + axisCount = options.yaxes.length || 1; + for (i = 0; i < axisCount; ++i) { + axisOptions = options.yaxes[i]; + if (axisOptions && !axisOptions.tickColor) { + axisOptions.tickColor = axisOptions.color; + } + + axisOptions = $.extend(true, {}, options.yaxis, axisOptions); + options.yaxes[i] = axisOptions; + + if (axisOptions.font) { + axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); + if (!axisOptions.font.color) { + axisOptions.font.color = axisOptions.color; + } + if (!axisOptions.font.lineHeight) { + axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); + } + } + } + + // backwards compatibility, to be removed in future + if (options.xaxis.noTicks && options.xaxis.ticks == null) options.xaxis.ticks = options.xaxis.noTicks; + if (options.yaxis.noTicks && options.yaxis.ticks == null) options.yaxis.ticks = options.yaxis.noTicks; + if (options.x2axis) { + options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis); + options.xaxes[1].position = 'top'; + // Override the inherit to allow the axis to auto-scale + if (options.x2axis.min == null) { + options.xaxes[1].min = null; + } + if (options.x2axis.max == null) { + options.xaxes[1].max = null; + } + } + if (options.y2axis) { + options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis); + options.yaxes[1].position = 'right'; + // Override the inherit to allow the axis to auto-scale + if (options.y2axis.min == null) { + options.yaxes[1].min = null; + } + if (options.y2axis.max == null) { + options.yaxes[1].max = null; + } + } + if (options.grid.coloredAreas) options.grid.markings = options.grid.coloredAreas; + if (options.grid.coloredAreasColor) options.grid.markingsColor = options.grid.coloredAreasColor; + if (options.lines) $.extend(true, options.series.lines, options.lines); + if (options.points) $.extend(true, options.series.points, options.points); + if (options.bars) $.extend(true, options.series.bars, options.bars); + if (options.shadowSize != null) options.series.shadowSize = options.shadowSize; + if (options.highlightColor != null) options.series.highlightColor = options.highlightColor; + + // save options on axes for future reference + for (i = 0; i < options.xaxes.length; ++i) getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i]; + for (i = 0; i < options.yaxes.length; ++i) getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i]; + + // add hooks from options + for (var n in hooks) if (options.hooks[n] && options.hooks[n].length) hooks[n] = hooks[n].concat(options.hooks[n]); + + executeHooks(hooks.processOptions, [options]); + } + + function setData(d) { + series = parseData(d); + fillInSeriesOptions(); + processData(); + } + + function parseData(d) { + let res = []; + for (let i = 0; i < d.length; ++i) { + let s = $.extend(true, {}, options.series); + + if (d[i].data != null) { + s.data = d[i].data; // move the data instead of deep-copy + delete d[i].data; + + $.extend(true, s, d[i]); + + d[i].data = s.data; + } else s.data = d[i]; + res.push(s); + } + + return res; + } + + function axisNumber(obj, coord) { + var a = obj[coord + 'axis']; + if (typeof a == 'object') + // if we got a real axis, extract number + a = a.n; + if (typeof a != 'number') a = 1; // default to first axis + return a; + } + + function allAxes() { + // return flat array without annoying null entries + return $.grep(xaxes.concat(yaxes), function(a) { + return a; + }); + } + + function canvasToAxisCoords(pos) { + // return an object with x/y corresponding to all used axes + var res = {}, + i, + axis; + for (i = 0; i < xaxes.length; ++i) { + axis = xaxes[i]; + if (axis) res['x' + axis.n] = axis.c2p(pos.left); + } + + for (i = 0; i < yaxes.length; ++i) { + axis = yaxes[i]; + if (axis) res['y' + axis.n] = axis.c2p(pos.top); + } + + if (res.x1 !== undefined) res.x = res.x1; + if (res.y1 !== undefined) res.y = res.y1; + + return res; + } + + function axisToCanvasCoords(pos) { + // get canvas coords from the first pair of x/y found in pos + var res = {}, + i, + axis, + key; + + for (i = 0; i < xaxes.length; ++i) { + axis = xaxes[i]; + if (axis && axis.used) { + key = 'x' + axis.n; + if (pos[key] == null && axis.n == 1) key = 'x'; + + if (pos[key] != null) { + res.left = axis.p2c(pos[key]); + break; + } + } + } + + for (i = 0; i < yaxes.length; ++i) { + axis = yaxes[i]; + if (axis && axis.used) { + key = 'y' + axis.n; + if (pos[key] == null && axis.n == 1) key = 'y'; + + if (pos[key] != null) { + res.top = axis.p2c(pos[key]); + break; + } + } + } + + return res; + } + + function getOrCreateAxis(axes, number) { + if (!axes[number - 1]) + axes[number - 1] = { + n: number, // save the number for future reference + direction: axes == xaxes ? 'x' : 'y', + options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis), + }; + + return axes[number - 1]; + } + + function fillInSeriesOptions() { + var neededColors = series.length, + maxIndex = -1, + i; + + // Subtract the number of series that already have fixed colors or + // color indexes from the number that we still need to generate. + + for (i = 0; i < series.length; ++i) { + let sc = series[i].color; + if (sc != null) { + neededColors--; + if (typeof sc == 'number' && sc > maxIndex) { + maxIndex = sc; + } + } + } + + // If any of the series have fixed color indexes, then we need to + // generate at least as many colors as the highest index. + + if (neededColors <= maxIndex) { + neededColors = maxIndex + 1; + } + + // Generate all the colors, using first the option colors and then + // variations on those colors once they're exhausted. + + var c, + colors = [], + colorPool = options.colors, + colorPoolSize = colorPool.length, + variation = 0; + + for (i = 0; i < neededColors; i++) { + c = $.color.parse(colorPool[i % colorPoolSize] || '#666'); + + // Each time we exhaust the colors in the pool we adjust + // a scaling factor used to produce more variations on + // those colors. The factor alternates negative/positive + // to produce lighter/darker colors. + + // Reset the variation after every few cycles, or else + // it will end up producing only white or black colors. + + if (i % colorPoolSize == 0 && i) { + if (variation >= 0) { + if (variation < 0.5) { + variation = -variation - 0.2; + } else variation = 0; + } else variation = -variation; + } + + colors[i] = c.scale('rgb', 1 + variation); + } + + // Finalize the series options, filling in their colors + + var colori = 0, + s; + for (i = 0; i < series.length; ++i) { + s = series[i]; + + // assign colors + if (s.color == null) { + s.color = colors[colori].toString(); + ++colori; + } else if (typeof s.color == 'number') s.color = colors[s.color].toString(); + + // turn on lines automatically in case nothing is set + if (s.lines.show == null) { + var v, + show = true; + for (v in s) + if (s[v] && s[v].show) { + show = false; + break; + } + if (show) s.lines.show = true; + } + + // If nothing was provided for lines.zero, default it to match + // lines.fill, since areas by default should extend to zero. + + if (s.lines.zero == null) { + s.lines.zero = !!s.lines.fill; + } + + // setup axes + s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, 'x')); + s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, 'y')); + } + } + + function processData() { + let topSentry = Number.POSITIVE_INFINITY, + bottomSentry = Number.NEGATIVE_INFINITY, + fakeInfinity = Number.MAX_VALUE, + i, + j, + k, + m, + s, + points, + ps, + val, + f, + p, + data, + format; + + function updateAxis(axis, min, max) { + if (min < axis.datamin && min != -fakeInfinity) axis.datamin = min; + if (max > axis.datamax && max != fakeInfinity) axis.datamax = max; + } + + $.each(allAxes(), function(_, axis) { + // init axis + axis.datamin = topSentry; + axis.datamax = bottomSentry; + axis.used = false; + }); + + for (i = 0; i < series.length; ++i) { + s = series[i]; + s.datapoints = { points: [] }; + + executeHooks(hooks.processRawData, [s, s.data, s.datapoints]); + } + + // first pass: clean and copy data + for (i = 0; i < series.length; ++i) { + s = series[i]; + + data = s.data; + format = s.datapoints.format; + + if (!format) { + format = []; + // find out how to copy + format.push({ x: true, number: true, required: true }); + format.push({ y: true, number: true, required: true }); + + if (s.stack || s.bars.show || (s.lines.show && s.lines.fill)) { + let autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); + format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); + if (s.bars.horizontal) { + delete format[format.length - 1].y; + format[format.length - 1].x = true; + } + } + + s.datapoints.format = format; + } + + if (s.datapoints.pointsize != null) continue; // already filled in + + s.datapoints.pointsize = format.length; + + ps = s.datapoints.pointsize; + points = s.datapoints.points; + + let insertSteps = s.lines.show && s.lines.steps; + s.xaxis.used = s.yaxis.used = true; + + for (j = k = 0; j < data.length; ++j, k += ps) { + p = data[j]; + + let nullify = p == null; + if (!nullify) { + for (m = 0; m < ps; ++m) { + val = p[m]; + f = format[m]; + + if (f) { + if (f.number && val != null) { + val = +val; // convert to number + if (isNaN(val)) val = null; + else if (val == Infinity) val = fakeInfinity; + else if (val == -Infinity) val = -fakeInfinity; + } + + if (val == null) { + if (f.required) nullify = true; + + if (f.defaultValue != null) val = f.defaultValue; + } + } + + points[k + m] = val; + } + } + + if (nullify) { + for (m = 0; m < ps; ++m) { + val = points[k + m]; + if (val != null) { + f = format[m]; + // extract min/max info + if (f.autoscale !== false) { + if (f.x) { + updateAxis(s.xaxis, val, val); + } + if (f.y) { + updateAxis(s.yaxis, val, val); + } + } + } + points[k + m] = null; + } + } + + if (insertSteps && k > 0 && (!nullify || points[k - ps] != null)) { + // copy the point to make room for a middle point + for (m = 0; m < ps; ++m) points[k + ps + m] = points[k + m]; + + // middle point has same y + points[k + 1] = points[k - ps + 1] || 0; + + // if series has null values, let's give the last !null value a nice step + if (nullify) points[k] = p[0]; + + // we've added a point, better reflect that + k += ps; + } + } + } + + // give the hooks a chance to run + for (i = 0; i < series.length; ++i) { + s = series[i]; + points = s.datapoints.points; + ps = s.datapoints.pointsize; + + // grafana + if (s.transform === 'negative-Y') { + for (j = 0; j < points.length; j += ps) { + if (points[j] == null) continue; + + val = points[j + 1]; + points[j + 1] = -val; + } + } + + executeHooks(hooks.processDatapoints, [s, s.datapoints]); + } + + // second pass: find datamax/datamin for auto-scaling + for (i = 0; i < series.length; ++i) { + s = series[i]; + points = s.datapoints.points; + ps = s.datapoints.pointsize; + format = s.datapoints.format; + + var xmin = topSentry, + ymin = topSentry, + xmax = bottomSentry, + ymax = bottomSentry; + + for (j = 0; j < points.length; j += ps) { + if (points[j] == null) continue; + + for (m = 0; m < ps; ++m) { + val = points[j + m]; + f = format[m]; + if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity) continue; + + if (f.x) { + if (val < xmin) xmin = val; + if (val > xmax) xmax = val; + } + if (f.y) { + if (val < ymin) ymin = val; + if (val > ymax) ymax = val; + } + } + } + + if (s.bars.show) { + // make sure we got room for the bar on the dancing floor + var delta; + + switch (s.bars.align) { + case 'left': + delta = 0; + break; + case 'right': + delta = -s.bars.barWidth; + break; + default: + delta = -s.bars.barWidth / 2; + } + + if (s.bars.horizontal) { + ymin += delta; + ymax += delta + s.bars.barWidth; + } else { + xmin += delta; + xmax += delta + s.bars.barWidth; + } + } + + updateAxis(s.xaxis, xmin, xmax); + updateAxis(s.yaxis, ymin, ymax); + } + + $.each(allAxes(), function(_, axis) { + if (axis.datamin == topSentry) axis.datamin = null; + if (axis.datamax == bottomSentry) axis.datamax = null; + }); + } + + function setupCanvases() { + // Make sure the placeholder is clear of everything except canvases + // from a previous plot in this container that we'll try to re-use. + + placeholder.find('.flot-temp-elem').remove(); + + if (placeholder.css('position') == 'static') placeholder.css('position', 'relative'); // for positioning labels and overlay + + surface = new Canvas('flot-base', placeholder); + overlay = new Canvas('flot-overlay', placeholder); // overlay canvas for interactive features + + ctx = surface.context; + octx = overlay.context; + + // define which element we're listening for events on + eventHolder = $(overlay.element).unbind(); + + // If we're re-using a plot object, shut down the old one + + var existing = placeholder.data('plot'); + + if (existing) { + existing.shutdown(); + overlay.clear(); + } + + // save in case we get replotted + placeholder.data('plot', plot); + } + + function bindEvents() { + // bind events + if (options.grid.hoverable) { + eventHolder.mousemove(onMouseMove); + + // Use bind, rather than .mouseleave, because we officially + // still support jQuery 1.2.6, which doesn't define a shortcut + // for mouseenter or mouseleave. This was a bug/oversight that + // was fixed somewhere around 1.3.x. We can return to using + // .mouseleave when we drop support for 1.2.6. + + eventHolder.bind('mouseleave', onMouseLeave); + } + + if (options.grid.clickable) eventHolder.click(onClick); + + executeHooks(hooks.bindEvents, [eventHolder]); + } + + function shutdown() { + if (redrawTimeout) clearTimeout(redrawTimeout); + + eventHolder.unbind('mousemove', onMouseMove); + eventHolder.unbind('mouseleave', onMouseLeave); + eventHolder.unbind('click', onClick); + + executeHooks(hooks.shutdown, [eventHolder]); + } + + function setTransformationHelpers(axis) { + // set helper functions on the axis, assumes plot area + // has been computed already + + function identity(x) { + return x; + } + + var s, + m, + t = axis.options.transform || identity, + it = axis.options.inverseTransform; + + // precompute how much the axis is scaling a point + // in canvas space + if (axis.direction == 'x') { + s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min)); + m = Math.min(t(axis.max), t(axis.min)); + } else { + s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min)); + s = -s; + m = Math.max(t(axis.max), t(axis.min)); + } + + // data point to canvas coordinate + if (t == identity) + // slight optimization + axis.p2c = function(p) { + return (p - m) * s; + }; + else + axis.p2c = function(p) { + return (t(p) - m) * s; + }; + // canvas coordinate to data point + if (!it) + axis.c2p = function(c) { + return m + c / s; + }; + else + axis.c2p = function(c) { + return it(m + c / s); + }; + } + + function measureTickLabels(axis) { + let opts = axis.options, + ticks = axis.ticks || [], + labelWidth = opts.labelWidth || 0, + labelHeight = opts.labelHeight || 0, + maxWidth = labelWidth || (axis.direction == 'x' ? Math.floor(surface.width / (ticks.length || 1)) : null), + legacyStyles = axis.direction + 'Axis ' + axis.direction + axis.n + 'Axis', + layer = 'flot-' + axis.direction + '-axis flot-' + axis.direction + axis.n + '-axis ' + legacyStyles, + font = opts.font || 'flot-tick-label tickLabel'; + + for (let i = 0; i < ticks.length; ++i) { + let t = ticks[i]; + + if (!t.label) continue; + + let info = surface.getTextInfo(layer, t.label, font, null, maxWidth); + + /// Grafana fix, add +1 to label width + labelWidth = Math.max(labelWidth, info.width + 1); + labelHeight = Math.max(labelHeight, info.height); + } + + axis.labelWidth = opts.labelWidth || labelWidth; + axis.labelHeight = opts.labelHeight || labelHeight; + } + + function allocateAxisBoxFirstPhase(axis) { + // find the bounding box of the axis by looking at label + // widths/heights and ticks, make room by diminishing the + // plotOffset; this first phase only looks at one + // dimension per axis, the other dimension depends on the + // other axes so will have to wait + + let lw = axis.labelWidth, + lh = axis.labelHeight, + pos = axis.options.position, + isXAxis = axis.direction === 'x', + tickLength = axis.options.tickLength, + axisMargin = options.grid.axisMargin, + padding = options.grid.labelMargin, + eventSectionPadding = options.grid.eventSectionHeight, + innermost = true, + outermost = true, + first = true, + found = false; + + // Determine the axis's position in its direction and on its side + + $.each(isXAxis ? xaxes : yaxes, function(i, a) { + if (a && (a.show || a.reserveSpace)) { + if (a === axis) { + found = true; + } else if (a.options.position === pos) { + if (found) { + outermost = false; + } else { + innermost = false; + } + } + if (!found) { + first = false; + } + } + }); + + // The outermost axis on each side has no margin + + if (outermost) { + axisMargin = 0; + } + + // The ticks for the first axis in each direction stretch across + + if (tickLength == null) { + tickLength = first ? 'full' : 5; + } + + if (!isNaN(+tickLength)) padding += +tickLength; + + if (isXAxis) { + // Add space for event section + lh += padding; + lh += eventSectionPadding; + + if (pos == 'bottom') { + plotOffset.bottom += lh + axisMargin; + axis.box = { top: surface.height - plotOffset.bottom, height: lh }; + } else { + axis.box = { top: plotOffset.top + axisMargin, height: lh }; + plotOffset.top += lh + axisMargin; + } + } else { + lw += padding; + + if (pos == 'left') { + axis.box = { left: plotOffset.left + axisMargin, width: lw }; + plotOffset.left += lw + axisMargin; + } else { + plotOffset.right += lw + axisMargin; + axis.box = { left: surface.width - plotOffset.right, width: lw }; + } + } + + // save for future reference + axis.position = pos; + axis.tickLength = tickLength; + axis.box.padding = padding; + axis.box.eventSectionPadding = eventSectionPadding; + axis.innermost = innermost; + } + + function allocateAxisBoxSecondPhase(axis) { + // now that all axis boxes have been placed in one + // dimension, we can set the remaining dimension coordinates + if (axis.direction == 'x') { + axis.box.left = plotOffset.left - axis.labelWidth / 2; + axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth; + } else { + axis.box.top = plotOffset.top - axis.labelHeight / 2; + axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight; + } + } + + function adjustLayoutForThingsStickingOut() { + // possibly adjust plot offset to ensure everything stays + // inside the canvas and isn't clipped off + + let minMargin = options.grid.minBorderMargin, + i; + + // check stuff from the plot (FIXME: this should just read + // a value from the series, otherwise it's impossible to + // customize) + if (minMargin == null) { + minMargin = 0; + for (i = 0; i < series.length; ++i) + minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth / 2)); + } + + let margins = { + left: minMargin, + right: minMargin, + top: minMargin, + bottom: minMargin, + }; + + // check axis labels, note we don't check the actual + // labels but instead use the overall width/height to not + // jump as much around with replots + $.each(allAxes(), function(_, axis) { + if (axis.reserveSpace && axis.ticks && axis.ticks.length) { + if (axis.direction === 'x') { + margins.left = Math.max(margins.left, axis.labelWidth / 2); + margins.right = Math.max(margins.right, axis.labelWidth / 2); + } else { + margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2); + margins.top = Math.max(margins.top, axis.labelHeight / 2); + } + } + }); + + plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left)); + plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right)); + plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top)); + plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom)); + } + + function setupGrid() { + var i, + axes = allAxes(), + showGrid = options.grid.show; + + // Initialize the plot's offset from the edge of the canvas + + for (var a in plotOffset) { + let margin = options.grid.margin || 0; + plotOffset[a] = typeof margin == 'number' ? margin : margin[a] || 0; + } + + executeHooks(hooks.processOffset, [plotOffset]); + + // If the grid is visible, add its border width to the offset + + for (var a in plotOffset) { + if (typeof options.grid.borderWidth == 'object') { + plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0; + } else { + plotOffset[a] += showGrid ? options.grid.borderWidth : 0; + } + } + + $.each(axes, function(_, axis) { + let axisOpts = axis.options; + axis.show = axisOpts.show == null ? axis.used : axisOpts.show; + axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace; + setRange(axis); + }); + + executeHooks(hooks.processRange, []); + + if (showGrid) { + var allocatedAxes = $.grep(axes, function(axis) { + return axis.show || axis.reserveSpace; + }); + + let snaped = false; + for (var i = 0; i < 2; i++) { + $.each(allocatedAxes, function(_, axis) { + // make the ticks + setupTickGeneration(axis); + setTicks(axis); + snaped = snapRangeToTicks(axis, axis.ticks) || snaped; + // find labelWidth/Height for axis + measureTickLabels(axis); + }); + + if (snaped && hooks.processRange.length > 0) { + executeHooks(hooks.processRange, []); + snaped = false; + } else { + break; + } + } + + // with all dimensions calculated, we can compute the + // axis bounding boxes, start from the outside + // (reverse order) + for (i = allocatedAxes.length - 1; i >= 0; --i) allocateAxisBoxFirstPhase(allocatedAxes[i]); + + // make sure we've got enough space for things that + // might stick out + adjustLayoutForThingsStickingOut(); + + $.each(allocatedAxes, function(_, axis) { + allocateAxisBoxSecondPhase(axis); + }); + } + + plotWidth = surface.width - plotOffset.left - plotOffset.right; + plotHeight = surface.height - plotOffset.bottom - plotOffset.top; + + // now we got the proper plot dimensions, we can compute the scaling + $.each(axes, function(_, axis) { + setTransformationHelpers(axis); + }); + + if (showGrid) { + drawAxisLabels(); + } + + insertLegend(); + } + + function setRange(axis) { + let opts = axis.options, + min = +(opts.min != null ? opts.min : axis.datamin), + max = +(opts.max != null ? opts.max : axis.datamax), + delta = max - min; + + if (delta == 0.0) { + // Grafana fix: wide Y min and max using increased wideFactor + // when all series values are the same + let wideFactor = 0.25; + let widen = Math.abs(max == 0 ? 1 : max * wideFactor); + + if (opts.min == null) { + min -= widen; + } + // always widen max if we couldn't widen min to ensure we + // don't fall into min == max which doesn't work + if (opts.max == null || opts.min != null) { + max += widen; + } + } else { + // consider autoscaling + let margin = opts.autoscaleMargin; + if (margin != null) { + if (opts.min == null) { + min -= delta * margin; + // make sure we don't go below zero if all values + // are positive + if (min < 0 && axis.datamin != null && axis.datamin >= 0) min = 0; + } + if (opts.max == null) { + max += delta * margin; + if (max > 0 && axis.datamax != null && axis.datamax <= 0) max = 0; + } + } + } + axis.min = min; + axis.max = max; + } + + function setupTickGeneration(axis) { + let opts = axis.options; + + // estimate number of ticks + let noTicks; + if (typeof opts.ticks == 'number' && opts.ticks > 0) noTicks = opts.ticks; + // heuristic based on the model a*sqrt(x) fitted to + // some data points that seemed reasonable + else noTicks = 0.3 * Math.sqrt(axis.direction == 'x' ? surface.width : surface.height); + + let delta = (axis.max - axis.min) / noTicks, + dec = -Math.floor(Math.log(delta) / Math.LN10), + maxDec = opts.tickDecimals; + + if (maxDec != null && dec > maxDec) { + dec = maxDec; + } + + let magn = Math.pow(10, -dec), + norm = delta / magn, // norm is between 1.0 and 10.0 + size; + + if (norm < 1.5) { + size = 1; + } else if (norm < 3) { + size = 2; + // special case for 2.5, requires an extra decimal + if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { + size = 2.5; + ++dec; + } + } else if (norm < 7.5) { + size = 5; + } else { + size = 10; + } + + size *= magn; + + if (opts.minTickSize != null && size < opts.minTickSize) { + size = opts.minTickSize; + } + + axis.delta = delta; + axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec); + axis.tickSize = opts.tickSize || size; + + // grafana addition + if (opts.tickDecimals === null || opts.tickDecimals === undefined) { + axis.scaledDecimals = axis.tickDecimals + dec; + } + + // Time mode was moved to a plug-in in 0.8, and since so many people use it + // we'll add an especially friendly reminder to make sure they included it. + + if (opts.mode == 'time' && !axis.tickGenerator) { + throw new Error('Time mode requires the flot.time plugin.'); + } + + // Flot supports base-10 axes; any other mode else is handled by a plug-in, + // like flot.time.js. + + if (!axis.tickGenerator) { + axis.tickGenerator = function(axis) { + let ticks = [], + start = floorInBase(axis.min, axis.tickSize), + i = 0, + v = Number.NaN, + prev; + + do { + prev = v; + v = start + i * axis.tickSize; + ticks.push(v); + ++i; + } while (v < axis.max && v != prev); + return ticks; + }; + + axis.tickFormatter = function(value, axis) { + let factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1; + var formatted = '' + Math.round(value * factor) / factor; + + // If tickDecimals was specified, ensure that we have exactly that + // much precision; otherwise default to the value's own precision. + + if (axis.tickDecimals != null) { + var decimal = formatted.indexOf('.'); + let precision = decimal == -1 ? 0 : formatted.length - decimal - 1; + if (precision < axis.tickDecimals) { + return (precision ? formatted : formatted + '.') + ('' + factor).substr(1, axis.tickDecimals - precision); + } + } + + return formatted; + }; + } + + if ($.isFunction(opts.tickFormatter)) + axis.tickFormatter = function(v, axis) { + return '' + opts.tickFormatter(v, axis); + }; + + if (opts.alignTicksWithAxis != null) { + var otherAxis = (axis.direction == 'x' ? xaxes : yaxes)[opts.alignTicksWithAxis - 1]; + if (otherAxis && otherAxis.used && otherAxis != axis) { + // consider snapping min/max to outermost nice ticks + let niceTicks = axis.tickGenerator(axis); + if (niceTicks.length > 0) { + if (opts.min == null) axis.min = Math.min(axis.min, niceTicks[0]); + if (opts.max == null && niceTicks.length > 1) axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]); + } + + axis.tickGenerator = function(axis) { + // copy ticks, scaled to this axis + var ticks = [], + v, + i; + for (i = 0; i < otherAxis.ticks.length; ++i) { + v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min); + v = axis.min + v * (axis.max - axis.min); + ticks.push(v); + } + return ticks; + }; + + // we might need an extra decimal since forced + // ticks don't necessarily fit naturally + if (!axis.mode && opts.tickDecimals == null) { + let extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1), + ts = axis.tickGenerator(axis); + + // only proceed if the tick interval rounded + // with an extra decimal doesn't give us a + // zero at end + if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec)))) axis.tickDecimals = extraDec; + } + } + } + } + + function setTicks(axis) { + var oticks = axis.options.ticks, + ticks = []; + if (oticks == null || (typeof oticks == 'number' && oticks > 0)) ticks = axis.tickGenerator(axis); + else if (oticks) { + if ($.isFunction(oticks)) + // generate the ticks + ticks = oticks(axis); + else ticks = oticks; + } + + // clean up/labelify the supplied ticks, copy them over + let i, v; + axis.ticks = []; + for (i = 0; i < ticks.length; ++i) { + let label = null; + let t = ticks[i]; + if (typeof t == 'object') { + v = +t[0]; + if (t.length > 1) label = t[1]; + } else v = +t; + if (label == null) label = axis.tickFormatter(v, axis); + if (!isNaN(v)) axis.ticks.push({ v: v, label: label }); + } + } + + function snapRangeToTicks(axis, ticks) { + let changed = false; + if (axis.options.autoscaleMargin && ticks.length > 0) { + // snap to ticks + if (axis.options.min == null) { + axis.min = Math.min(axis.min, ticks[0].v); + changed = true; + } + if (axis.options.max == null && ticks.length > 1) { + axis.max = Math.max(axis.max, ticks[ticks.length - 1].v); + changed = true; + } + } + return changed; + } + + function draw() { + surface.clear(); + + executeHooks(hooks.drawBackground, [ctx]); + + let grid = options.grid; + + // draw background, if any + if (grid.show && grid.backgroundColor) drawBackground(); + + if (grid.show && !grid.aboveData) { + drawGrid(); + } + + for (let i = 0; i < series.length; ++i) { + executeHooks(hooks.drawSeries, [ctx, series[i]]); + drawSeries(series[i]); + } + + executeHooks(hooks.draw, [ctx]); + + if (grid.show && grid.aboveData) { + drawGrid(); + } + + surface.render(); + + // A draw implies that either the axes or data have changed, so we + // should probably update the overlay highlights as well. + + triggerRedrawOverlay(); + } + + function extractRange(ranges, coord) { + var axis, + from, + to, + key, + axes = allAxes(); + + for (let i = 0; i < axes.length; ++i) { + axis = axes[i]; + if (axis.direction == coord) { + key = coord + axis.n + 'axis'; + if (!ranges[key] && axis.n == 1) key = coord + 'axis'; // support x1axis as xaxis + if (ranges[key]) { + from = ranges[key].from; + to = ranges[key].to; + break; + } + } + } + + // backwards-compat stuff - to be removed in future + if (!ranges[key]) { + axis = coord == 'x' ? xaxes[0] : yaxes[0]; + from = ranges[coord + '1']; + to = ranges[coord + '2']; + } + + // auto-reverse as an added bonus + if (from != null && to != null && from > to) { + let tmp = from; + from = to; + to = tmp; + } + + return { from: from, to: to, axis: axis }; + } + + function drawBackground() { + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, 'rgba(255, 255, 255, 0)'); + ctx.fillRect(0, 0, plotWidth, plotHeight); + ctx.restore(); + } + + function drawGrid() { + let i, axes, bw, bc; + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + // draw markings + let markings = options.grid.markings; + if (markings) { + if ($.isFunction(markings)) { + axes = plot.getAxes(); + // xmin etc. is backwards compatibility, to be + // removed in the future + axes.xmin = axes.xaxis.min; + axes.xmax = axes.xaxis.max; + axes.ymin = axes.yaxis.min; + axes.ymax = axes.yaxis.max; + + markings = markings(axes); + } + + for (i = 0; i < markings.length; ++i) { + let m = markings[i], + xrange = extractRange(m, 'x'), + yrange = extractRange(m, 'y'); + + // fill in missing + if (xrange.from == null) xrange.from = xrange.axis.min; + if (xrange.to == null) xrange.to = xrange.axis.max; + if (yrange.from == null) yrange.from = yrange.axis.min; + if (yrange.to == null) yrange.to = yrange.axis.max; + + // clip + if ( + xrange.to < xrange.axis.min || + xrange.from > xrange.axis.max || + yrange.to < yrange.axis.min || + yrange.from > yrange.axis.max + ) + continue; + + xrange.from = Math.max(xrange.from, xrange.axis.min); + xrange.to = Math.min(xrange.to, xrange.axis.max); + yrange.from = Math.max(yrange.from, yrange.axis.min); + yrange.to = Math.min(yrange.to, yrange.axis.max); + + let xequal = xrange.from === xrange.to, + yequal = yrange.from === yrange.to; + + if (xequal && yequal) { + continue; + } + + // then draw + xrange.from = Math.floor(xrange.axis.p2c(xrange.from)); + xrange.to = Math.floor(xrange.axis.p2c(xrange.to)); + yrange.from = Math.floor(yrange.axis.p2c(yrange.from)); + yrange.to = Math.floor(yrange.axis.p2c(yrange.to)); + + if (xequal || yequal) { + let lineWidth = m.lineWidth || options.grid.markingsLineWidth, + subPixel = lineWidth % 2 ? 0.5 : 0; + ctx.beginPath(); + ctx.strokeStyle = m.color || options.grid.markingsColor; + ctx.lineWidth = lineWidth; + if (xequal) { + ctx.moveTo(xrange.to + subPixel, yrange.from); + ctx.lineTo(xrange.to + subPixel, yrange.to); + } else { + ctx.moveTo(xrange.from, yrange.to + subPixel); + ctx.lineTo(xrange.to, yrange.to + subPixel); + } + ctx.stroke(); + } else { + ctx.fillStyle = m.color || options.grid.markingsColor; + ctx.fillRect(xrange.from, yrange.to, xrange.to - xrange.from, yrange.from - yrange.to); + } + } + } + + // draw the ticks + axes = allAxes(); + bw = options.grid.borderWidth; + + for (let j = 0; j < axes.length; ++j) { + var axis = axes[j], + box = axis.box, + t = axis.tickLength, + x, + y, + xoff, + yoff; + if (!axis.show || axis.ticks.length == 0) continue; + + ctx.lineWidth = 1; + + // find the edges + if (axis.direction == 'x') { + x = 0; + if (t == 'full') y = axis.position == 'top' ? 0 : plotHeight; + else y = box.top - plotOffset.top + (axis.position == 'top' ? box.height : 0); + } else { + y = 0; + if (t == 'full') x = axis.position == 'left' ? 0 : plotWidth; + else x = box.left - plotOffset.left + (axis.position == 'left' ? box.width : 0); + } + + // draw tick bar + if (!axis.innermost) { + ctx.strokeStyle = axis.options.color; + ctx.beginPath(); + xoff = yoff = 0; + if (axis.direction == 'x') xoff = plotWidth + 1; + else yoff = plotHeight + 1; + + if (ctx.lineWidth == 1) { + if (axis.direction == 'x') { + y = Math.floor(y) + 0.5; + } else { + x = Math.floor(x) + 0.5; + } + } + + ctx.moveTo(x, y); + ctx.lineTo(x + xoff, y + yoff); + ctx.stroke(); + } + + // draw ticks + + ctx.strokeStyle = axis.options.tickColor; + + ctx.beginPath(); + for (i = 0; i < axis.ticks.length; ++i) { + let v = axis.ticks[i].v; + + xoff = yoff = 0; + + if ( + isNaN(v) || + v < axis.min || + v > axis.max || + // skip those lying on the axes if we got a border + (t == 'full' && ((typeof bw == 'object' && bw[axis.position] > 0) || bw > 0) && (v == axis.min || v == axis.max)) + ) + continue; + + if (axis.direction == 'x') { + x = axis.p2c(v); + yoff = t == 'full' ? -plotHeight : t; + + if (axis.position == 'top') yoff = -yoff; + } else { + y = axis.p2c(v); + xoff = t == 'full' ? -plotWidth : t; + + if (axis.position == 'left') xoff = -xoff; + } + + if (ctx.lineWidth == 1) { + if (axis.direction == 'x') x = Math.floor(x) + 0.5; + else y = Math.floor(y) + 0.5; + } + + ctx.moveTo(x, y); + ctx.lineTo(x + xoff, y + yoff); + } + + ctx.stroke(); + } + + // draw border + if (bw) { + // If either borderWidth or borderColor is an object, then draw the border + // line by line instead of as one rectangle + bc = options.grid.borderColor; + if (typeof bw == 'object' || typeof bc == 'object') { + if (typeof bw !== 'object') { + bw = { top: bw, right: bw, bottom: bw, left: bw }; + } + if (typeof bc !== 'object') { + bc = { top: bc, right: bc, bottom: bc, left: bc }; + } + + if (bw.top > 0) { + ctx.strokeStyle = bc.top; + ctx.lineWidth = bw.top; + ctx.beginPath(); + ctx.moveTo(0 - bw.left, 0 - bw.top / 2); + ctx.lineTo(plotWidth, 0 - bw.top / 2); + ctx.stroke(); + } + + if (bw.right > 0) { + ctx.strokeStyle = bc.right; + ctx.lineWidth = bw.right; + ctx.beginPath(); + ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top); + ctx.lineTo(plotWidth + bw.right / 2, plotHeight); + ctx.stroke(); + } + + if (bw.bottom > 0) { + ctx.strokeStyle = bc.bottom; + ctx.lineWidth = bw.bottom; + ctx.beginPath(); + ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2); + ctx.lineTo(0, plotHeight + bw.bottom / 2); + ctx.stroke(); + } + + if (bw.left > 0) { + ctx.strokeStyle = bc.left; + ctx.lineWidth = bw.left; + ctx.beginPath(); + ctx.moveTo(0 - bw.left / 2, plotHeight + bw.bottom); + ctx.lineTo(0 - bw.left / 2, 0); + ctx.stroke(); + } + } else { + ctx.lineWidth = bw; + ctx.strokeStyle = options.grid.borderColor; + ctx.strokeRect(-bw / 2, -bw / 2, plotWidth + bw, plotHeight + bw); + } + } + + ctx.restore(); + } + + function drawAxisLabels() { + $.each(allAxes(), function(_, axis) { + let box = axis.box, + legacyStyles = axis.direction + 'Axis ' + axis.direction + axis.n + 'Axis', + layer = 'flot-' + axis.direction + '-axis flot-' + axis.direction + axis.n + '-axis ' + legacyStyles, + font = axis.options.font || 'flot-tick-label tickLabel', + tick, + x, + y, + halign, + valign; + + // Remove text before checking for axis.show and ticks.length; + // otherwise plugins, like flot-tickrotor, that draw their own + // tick labels will end up with both theirs and the defaults. + + surface.removeText(layer); + + if (!axis.show || axis.ticks.length == 0) return; + + for (let i = 0; i < axis.ticks.length; ++i) { + tick = axis.ticks[i]; + if (!tick.label || tick.v < axis.min || tick.v > axis.max) continue; + + if (axis.direction == 'x') { + halign = 'center'; + x = plotOffset.left + axis.p2c(tick.v); + if (axis.position == 'bottom') { + y = box.top + box.padding + box.eventSectionPadding; + } else { + y = box.top + box.height - box.padding; + valign = 'bottom'; + } + } else { + valign = 'middle'; + y = plotOffset.top + axis.p2c(tick.v); + if (axis.position == 'left') { + x = box.left + box.width - box.padding; + halign = 'right'; + } else { + x = box.left + box.padding; + } + } + + surface.addText(layer, x, y, tick.label, font, null, null, halign, valign); + } + }); + } + + function drawOrphanedPoints(series) { + /* Filters series data for points with no neighbors before or after + * and plots single 0.5 radius points for them so that they are displayed. + */ + let abandonedPoints = []; + let beforeX = null; + let afterX = null; + let datapoints = series.datapoints; + // find any points with no neighbors before or after + let emptyPoints = []; + for (let j = 0; j < datapoints.pointsize - 2; j++) { + emptyPoints.push(0); + } + for (let i = 0; i < datapoints.points.length; i += datapoints.pointsize) { + var x = datapoints.points[i], + y = datapoints.points[i + 1]; + if (i === datapoints.points.length - datapoints.pointsize) { + afterX = null; + } else { + afterX = datapoints.points[i + datapoints.pointsize]; + } + if (x !== null && y !== null && beforeX === null && afterX === null) { + abandonedPoints.push(x); + abandonedPoints.push(y); + abandonedPoints.push.apply(abandonedPoints, emptyPoints); + } + beforeX = x; + } + var olddatapoints = datapoints.points; + datapoints.points = abandonedPoints; + + series.points.radius = series.lines.lineWidth / 2; + // plot the orphan points with a radius of lineWidth/2 + drawSeriesPoints(series); + // reset old info + datapoints.points = olddatapoints; + } + + function drawSeries(series) { + if (series.lines.show) { + drawSeriesLines(series); + if (!series.points.show && !series.bars.show) { + // not necessary if user wants points displayed for everything + drawOrphanedPoints(series); + } + } + if (series.bars.show) drawSeriesBars(series); + if (series.points.show) drawSeriesPoints(series); + } + + function drawSeriesLines(series) { + function plotLine(datapoints, xoffset, yoffset, axisx, axisy) { + let points = datapoints.points, + ps = datapoints.pointsize, + prevx = null, + prevy = null; + + ctx.beginPath(); + for (let i = ps; i < points.length; i += ps) { + var x1 = points[i - ps], + y1 = points[i - ps + 1], + x2 = points[i], + y2 = points[i + 1]; + + if (x1 == null || x2 == null) continue; + + // clip with ymin + if (y1 <= y2 && y1 < axisy.min) { + if (y2 < axisy.min) continue; // line segment is outside + // compute new intersection point + x1 = ((axisy.min - y1) / (y2 - y1)) * (x2 - x1) + x1; + y1 = axisy.min; + } else if (y2 <= y1 && y2 < axisy.min) { + if (y1 < axisy.min) continue; + x2 = ((axisy.min - y1) / (y2 - y1)) * (x2 - x1) + x1; + y2 = axisy.min; + } + + // clip with ymax + if (y1 >= y2 && y1 > axisy.max) { + if (y2 > axisy.max) continue; + x1 = ((axisy.max - y1) / (y2 - y1)) * (x2 - x1) + x1; + y1 = axisy.max; + } else if (y2 >= y1 && y2 > axisy.max) { + if (y1 > axisy.max) continue; + x2 = ((axisy.max - y1) / (y2 - y1)) * (x2 - x1) + x1; + y2 = axisy.max; + } + + // clip with xmin + if (x1 <= x2 && x1 < axisx.min) { + if (x2 < axisx.min) continue; + y1 = ((axisx.min - x1) / (x2 - x1)) * (y2 - y1) + y1; + x1 = axisx.min; + } else if (x2 <= x1 && x2 < axisx.min) { + if (x1 < axisx.min) continue; + y2 = ((axisx.min - x1) / (x2 - x1)) * (y2 - y1) + y1; + x2 = axisx.min; + } + + // clip with xmax + if (x1 >= x2 && x1 > axisx.max) { + if (x2 > axisx.max) continue; + y1 = ((axisx.max - x1) / (x2 - x1)) * (y2 - y1) + y1; + x1 = axisx.max; + } else if (x2 >= x1 && x2 > axisx.max) { + if (x1 > axisx.max) continue; + y2 = ((axisx.max - x1) / (x2 - x1)) * (y2 - y1) + y1; + x2 = axisx.max; + } + + if (x1 != prevx || y1 != prevy) ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); + + prevx = x2; + prevy = y2; + ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset); + } + ctx.stroke(); + } + + function plotLineArea(datapoints, axisx, axisy) { + let points = datapoints.points, + ps = datapoints.pointsize, + bottom = Math.min(Math.max(0, axisy.min), axisy.max), + i = 0, + areaOpen = false, + ypos = 1, + segmentStart = 0, + segmentEnd = 0; + + // we process each segment in two turns, first forward + // direction to sketch out top, then once we hit the + // end we go backwards to sketch the bottom + while (true) { + if (ps > 0 && i > points.length + ps) break; + + i += ps; // ps is negative if going backwards + + let x1 = points[i - ps], + y1 = points[i - ps + ypos], + x2 = points[i], + y2 = points[i + ypos]; + + if (areaOpen) { + if (ps > 0 && x1 != null && x2 == null) { + // at turning point + segmentEnd = i; + ps = -ps; + ypos = 2; + continue; + } + + if (ps < 0 && i == segmentStart + ps) { + // done with the reverse sweep + ctx.fill(); + areaOpen = false; + ps = -ps; + ypos = 1; + i = segmentStart = segmentEnd + ps; + continue; + } + } + + if (x1 == null || x2 == null) continue; + + // clip x values + + // clip with xmin + if (x1 <= x2 && x1 < axisx.min) { + if (x2 < axisx.min) continue; + y1 = ((axisx.min - x1) / (x2 - x1)) * (y2 - y1) + y1; + x1 = axisx.min; + } else if (x2 <= x1 && x2 < axisx.min) { + if (x1 < axisx.min) continue; + y2 = ((axisx.min - x1) / (x2 - x1)) * (y2 - y1) + y1; + x2 = axisx.min; + } + + // clip with xmax + if (x1 >= x2 && x1 > axisx.max) { + if (x2 > axisx.max) continue; + y1 = ((axisx.max - x1) / (x2 - x1)) * (y2 - y1) + y1; + x1 = axisx.max; + } else if (x2 >= x1 && x2 > axisx.max) { + if (x1 > axisx.max) continue; + y2 = ((axisx.max - x1) / (x2 - x1)) * (y2 - y1) + y1; + x2 = axisx.max; + } + + if (!areaOpen) { + // open area + ctx.beginPath(); + ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom)); + areaOpen = true; + } + + // now first check the case where both is outside + if (y1 >= axisy.max && y2 >= axisy.max) { + ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max)); + continue; + } else if (y1 <= axisy.min && y2 <= axisy.min) { + ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min)); + continue; + } + + // else it's a bit more complicated, there might + // be a flat maxed out rectangle first, then a + // triangular cutout or reverse; to find these + // keep track of the current x values + var x1old = x1, + x2old = x2; + + // clip the y values, without shortcutting, we + // go through all cases in turn + + // clip with ymin + if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) { + x1 = ((axisy.min - y1) / (y2 - y1)) * (x2 - x1) + x1; + y1 = axisy.min; + } else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) { + x2 = ((axisy.min - y1) / (y2 - y1)) * (x2 - x1) + x1; + y2 = axisy.min; + } + + // clip with ymax + if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) { + x1 = ((axisy.max - y1) / (y2 - y1)) * (x2 - x1) + x1; + y1 = axisy.max; + } else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) { + x2 = ((axisy.max - y1) / (y2 - y1)) * (x2 - x1) + x1; + y2 = axisy.max; + } + + // if the x value was changed we got a rectangle + // to fill + if (x1 != x1old) { + ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1)); + // it goes to (x1, y1), but we fill that below + } + + // fill triangular section, this sometimes result + // in redundant points if (x1, y1) hasn't changed + // from previous line to, but we just ignore that + ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); + + // fill the other rectangle if it's there + if (x2 != x2old) { + ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); + ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2)); + } + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + ctx.lineJoin = 'round'; + + let lw = series.lines.lineWidth, + sw = series.shadowSize; + // FIXME: consider another form of shadow when filling is turned on + if (lw > 0 && sw > 0) { + // draw shadow as a thick and thin line with transparency + ctx.lineWidth = sw; + ctx.strokeStyle = 'rgba(0,0,0,0.1)'; + // position shadow at angle from the mid of line + var angle = Math.PI / 18; + plotLine( + series.datapoints, + Math.sin(angle) * (lw / 2 + sw / 2), + Math.cos(angle) * (lw / 2 + sw / 2), + series.xaxis, + series.yaxis + ); + ctx.lineWidth = sw / 2; + plotLine( + series.datapoints, + Math.sin(angle) * (lw / 2 + sw / 4), + Math.cos(angle) * (lw / 2 + sw / 4), + series.xaxis, + series.yaxis + ); + } + + ctx.lineWidth = lw; + ctx.strokeStyle = series.color; + let fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight); + if (fillStyle) { + ctx.fillStyle = fillStyle; + plotLineArea(series.datapoints, series.xaxis, series.yaxis); + } + + if (lw > 0) plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis); + ctx.restore(); + } + + function drawSeriesPoints(series) { + function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) { + var points = datapoints.points, + ps = datapoints.pointsize; + + for (let i = 0; i < points.length; i += ps) { + var x = points[i], + y = points[i + 1]; + if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) continue; + + ctx.beginPath(); + x = axisx.p2c(x); + y = axisy.p2c(y) + offset; + if (symbol == 'circle') ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false); + else symbol(ctx, x, y, radius, shadow); + ctx.closePath(); + + if (fillStyle) { + ctx.fillStyle = fillStyle; + ctx.fill(); + } + ctx.stroke(); + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + let lw = series.points.lineWidth, + sw = series.shadowSize, + radius = series.points.radius, + symbol = series.points.symbol; + + // If the user sets the line width to 0, we change it to a very + // small value. A line width of 0 seems to force the default of 1. + // Doing the conditional here allows the shadow setting to still be + // optional even with a lineWidth of 0. + + if (lw == 0) lw = 0.0001; + + if (lw > 0 && sw > 0) { + // draw shadow in two steps + let w = sw / 2; + ctx.lineWidth = w; + ctx.strokeStyle = 'rgba(0,0,0,0.1)'; + plotPoints(series.datapoints, radius, null, w + w / 2, true, series.xaxis, series.yaxis, symbol); + + ctx.strokeStyle = 'rgba(0,0,0,0.2)'; + plotPoints(series.datapoints, radius, null, w / 2, true, series.xaxis, series.yaxis, symbol); + } + + ctx.lineWidth = lw; + ctx.strokeStyle = series.color; + plotPoints( + series.datapoints, + radius, + getFillStyle(series.points, series.color), + 0, + false, + series.xaxis, + series.yaxis, + symbol + ); + ctx.restore(); + } + + function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) { + var left, right, bottom, top, drawLeft, drawRight, drawTop, drawBottom, tmp; + + // in horizontal mode, we start the bar from the left + // instead of from the bottom so it appears to be + // horizontal rather than vertical + if (horizontal) { + drawBottom = drawRight = drawTop = true; + drawLeft = false; + left = b; + right = x; + top = y + barLeft; + bottom = y + barRight; + + // account for negative bars + if (right < left) { + tmp = right; + right = left; + left = tmp; + drawLeft = true; + drawRight = false; + } + } else { + drawLeft = drawRight = drawTop = true; + drawBottom = false; + left = x + barLeft; + right = x + barRight; + bottom = b; + top = y; + + // account for negative bars + if (top < bottom) { + tmp = top; + top = bottom; + bottom = tmp; + drawBottom = true; + drawTop = false; + } + } + + // clip + if (right < axisx.min || left > axisx.max || top < axisy.min || bottom > axisy.max) return; + + if (left < axisx.min) { + left = axisx.min; + drawLeft = false; + } + + if (right > axisx.max) { + right = axisx.max; + drawRight = false; + } + + if (bottom < axisy.min) { + bottom = axisy.min; + drawBottom = false; + } + + if (top > axisy.max) { + top = axisy.max; + drawTop = false; + } + + left = axisx.p2c(left); + bottom = axisy.p2c(bottom); + right = axisx.p2c(right); + top = axisy.p2c(top); + + // fill the bar + if (fillStyleCallback) { + c.fillStyle = fillStyleCallback(bottom, top); + c.fillRect(left, top, right - left, bottom - top); + } + + // draw outline + if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) { + c.beginPath(); + + // FIXME: inline moveTo is buggy with excanvas + c.moveTo(left, bottom); + if (drawLeft) c.lineTo(left, top); + else c.moveTo(left, top); + if (drawTop) c.lineTo(right, top); + else c.moveTo(right, top); + if (drawRight) c.lineTo(right, bottom); + else c.moveTo(right, bottom); + if (drawBottom) c.lineTo(left, bottom); + else c.moveTo(left, bottom); + c.stroke(); + } + } + + function drawSeriesBars(series) { + function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) { + var points = datapoints.points, + ps = datapoints.pointsize; + + for (let i = 0; i < points.length; i += ps) { + if (points[i] == null) continue; + drawBar( + points[i], + points[i + 1], + points[i + 2], + barLeft, + barRight, + fillStyleCallback, + axisx, + axisy, + ctx, + series.bars.horizontal, + series.bars.lineWidth + ); + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + // FIXME: figure out a way to add shadows (for instance along the right edge) + ctx.lineWidth = series.bars.lineWidth; + ctx.strokeStyle = series.color; + + let barLeft; + + switch (series.bars.align) { + case 'left': + barLeft = 0; + break; + case 'right': + barLeft = -series.bars.barWidth; + break; + default: + barLeft = -series.bars.barWidth / 2; + } + + var fillStyleCallback = series.bars.fill + ? function(bottom, top) { + return getFillStyle(series.bars, series.color, bottom, top); + } + : null; + plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis); + ctx.restore(); + } + + function getFillStyle(filloptions, seriesColor, bottom, top) { + let fill = filloptions.fill; + if (!fill) return null; + + if (filloptions.fillColor) return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor); + + let c = $.color.parse(seriesColor); + c.a = typeof fill == 'number' ? fill : 0.4; + c.normalize(); + return c.toString(); + } + + function insertLegend() { + if (options.legend.container != null) { + $(options.legend.container).html(''); + } else { + placeholder.find('.legend').remove(); + } + + if (!options.legend.show) { + return; + } + + var fragments = [], + entries = [], + rowStarted = false, + lf = options.legend.labelFormatter, + s, + label; + + // Build a list of legend entries, with each having a label and a color + + for (var i = 0; i < series.length; ++i) { + s = series[i]; + if (s.label) { + label = lf ? lf(s.label, s) : s.label; + if (label) { + entries.push({ + label: label, + color: s.color, + }); + } + } + } + + // Sort the legend using either the default or a custom comparator + + if (options.legend.sorted) { + if ($.isFunction(options.legend.sorted)) { + entries.sort(options.legend.sorted); + } else if (options.legend.sorted == 'reverse') { + entries.reverse(); + } else { + var ascending = options.legend.sorted != 'descending'; + entries.sort(function(a, b) { + // eslint-disable-next-line + return a.label == b.label ? 0 : a.label < b.label != ascending ? 1 : -1; // Logical XOR + }); + } + } + + // Generate markup for the list of entries, in their final order + + for (var i = 0; i < entries.length; ++i) { + let entry = entries[i]; + + if (i % options.legend.noColumns == 0) { + if (rowStarted) fragments.push(''); + fragments.push(''); + rowStarted = true; + } + + fragments.push( + '
' + + '' + + entry.label + + '' + ); + } + + if (rowStarted) fragments.push(''); + + if (fragments.length == 0) return; + + var table = '' + fragments.join('') + '
'; + if (options.legend.container != null) $(options.legend.container).html(table); + else { + var pos = '', + p = options.legend.position, + m = options.legend.margin; + if (m[0] == null) m = [m, m]; + if (p.charAt(0) == 'n') pos += 'top:' + (m[1] + plotOffset.top) + 'px;'; + else if (p.charAt(0) == 's') pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;'; + if (p.charAt(1) == 'e') pos += 'right:' + (m[0] + plotOffset.right) + 'px;'; + else if (p.charAt(1) == 'w') pos += 'left:' + (m[0] + plotOffset.left) + 'px;'; + var legend = $( + '
' + table.replace('style="', 'style="position:absolute;' + pos + ';') + '
' + ).appendTo(placeholder); + if (options.legend.backgroundOpacity != 0.0) { + // put in the transparent background + // separately to avoid blended labels and + // label boxes + let c = options.legend.backgroundColor; + if (c == null) { + c = options.grid.backgroundColor; + if (c && typeof c == 'string') c = $.color.parse(c); + else c = $.color.extract(legend, 'background-color'); + c.a = 1; + c = c.toString(); + } + let div = legend.children(); + $( + '
' + ) + .prependTo(legend) + .css('opacity', options.legend.backgroundOpacity); + } + } + } + + // interactive features + + var highlights = [], + redrawTimeout = null; + + // returns the data item the mouse is over, or null if none is found + function findNearbyItem(mouseX, mouseY, seriesFilter) { + let maxDistance = options.grid.mouseActiveRadius, + smallestDistance = maxDistance * maxDistance + 1, + item = null, + i, + j, + ps; + + for (i = series.length - 1; i >= 0; --i) { + if (!seriesFilter(series[i])) continue; + + let s = series[i], + axisx = s.xaxis, + axisy = s.yaxis, + points = s.datapoints.points, + mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster + my = axisy.c2p(mouseY), + maxx = maxDistance / axisx.scale, + maxy = maxDistance / axisy.scale; + + ps = s.datapoints.pointsize; + // with inverse transforms, we can't use the maxx/maxy + // optimization, sadly + if (axisx.options.inverseTransform) maxx = Number.MAX_VALUE; + if (axisy.options.inverseTransform) maxy = Number.MAX_VALUE; + + if (s.lines.show || s.points.show) { + for (j = 0; j < points.length; j += ps) { + var x = points[j], + y = points[j + 1]; + if (x == null) continue; + + // For points and lines, the cursor must be within a + // certain distance to the data point + if (x - mx > maxx || x - mx < -maxx || y - my > maxy || y - my < -maxy) continue; + + // We have to calculate distances in pixels, not in + // data units, because the scales of the axes may be different + let dx = Math.abs(axisx.p2c(x) - mouseX), + dy = Math.abs(axisy.p2c(y) - mouseY), + dist = dx * dx + dy * dy; // we save the sqrt + + // use <= to ensure last point takes precedence + // (last generally means on top of) + if (dist < smallestDistance) { + smallestDistance = dist; + item = [i, j / ps]; + } + } + } + + if (s.bars.show && !item) { + // no other point can be nearby + + var barLeft, barRight; + + switch (s.bars.align) { + case 'left': + barLeft = 0; + break; + case 'right': + barLeft = -s.bars.barWidth; + break; + default: + barLeft = -s.bars.barWidth / 2; + } + + barRight = barLeft + s.bars.barWidth; + + for (j = 0; j < points.length; j += ps) { + var x = points[j], + y = points[j + 1], + b = points[j + 2]; + if (x == null) continue; + + // for a bar graph, the cursor must be inside the bar + if ( + series[i].bars.horizontal + ? mx <= Math.max(b, x) && mx >= Math.min(b, x) && my >= y + barLeft && my <= y + barRight + : mx >= x + barLeft && mx <= x + barRight && my >= Math.min(b, y) && my <= Math.max(b, y) + ) + item = [i, j / ps]; + } + } + } + + if (item) { + i = item[0]; + j = item[1]; + ps = series[i].datapoints.pointsize; + + return { + datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps), + dataIndex: j, + series: series[i], + seriesIndex: i, + }; + } + + return null; + } + + function onMouseMove(e) { + if (options.grid.hoverable) + triggerClickHoverEvent('plothover', e, function(s) { + return s['hoverable'] != false; + }); + } + + function onMouseLeave(e) { + if (options.grid.hoverable) + triggerClickHoverEvent('plothover', e, function() { + return false; + }); + } + + function onClick(e) { + if (plot.isSelecting) { + return; + } + + triggerClickHoverEvent('plotclick', e, function(s) { + return s['clickable'] != false; + }); + } + + // trigger click or hover event (they send the same parameters + // so we share their code) + function triggerClickHoverEvent(eventname, event, seriesFilter) { + let offset = eventHolder.offset(), + canvasX = event.pageX - offset.left - plotOffset.left, + canvasY = event.pageY - offset.top - plotOffset.top, + pos = canvasToAxisCoords({ left: canvasX, top: canvasY }); + + pos.pageX = event.pageX; + pos.pageY = event.pageY; + + // Add ctrlKey and metaKey to event + pos.ctrlKey = event.ctrlKey; + pos.metaKey = event.metaKey; + + let item = findNearbyItem(canvasX, canvasY, seriesFilter); + + if (item) { + // fill in mouse pos for any listeners out there + item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10); + item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10); + } + + if (options.grid.autoHighlight) { + // clear auto-highlights + for (let i = 0; i < highlights.length; ++i) { + let h = highlights[i]; + if ( + h.auto == eventname && + !(item && h.series == item.series && h.point[0] == item.datapoint[0] && h.point[1] == item.datapoint[1]) + ) + unhighlight(h.series, h.point); + } + + if (item) highlight(item.series, item.datapoint, eventname); + } + + placeholder.trigger(eventname, [pos, item]); + } + + function triggerRedrawOverlay() { + let t = options.interaction.redrawOverlayInterval; + if (t == -1) { + // skip event queue + drawOverlay(); + return; + } + + if (!redrawTimeout) redrawTimeout = setTimeout(drawOverlay, t); + } + + function drawOverlay() { + redrawTimeout = null; + + // draw highlights + octx.save(); + overlay.clear(); + octx.translate(plotOffset.left, plotOffset.top); + + let i, hi; + for (i = 0; i < highlights.length; ++i) { + hi = highlights[i]; + + if (hi.series.bars.show) drawBarHighlight(hi.series, hi.point); + else drawPointHighlight(hi.series, hi.point); + } + octx.restore(); + + executeHooks(hooks.drawOverlay, [octx]); + } + + function highlight(s, point, auto) { + if (typeof s == 'number') s = series[s]; + + if (typeof point == 'number') { + let ps = s.datapoints.pointsize; + point = s.datapoints.points.slice(ps * point, ps * (point + 1)); + } + + let i = indexOfHighlight(s, point); + if (i == -1) { + highlights.push({ series: s, point: point, auto: auto }); + + triggerRedrawOverlay(); + } else if (!auto) highlights[i].auto = false; + } + + function unhighlight(s, point) { + if (s == null && point == null) { + highlights = []; + triggerRedrawOverlay(); + return; + } + + if (typeof s == 'number') s = series[s]; + + if (typeof point == 'number') { + let ps = s.datapoints.pointsize; + point = s.datapoints.points.slice(ps * point, ps * (point + 1)); + } + + let i = indexOfHighlight(s, point); + if (i != -1) { + highlights.splice(i, 1); + + triggerRedrawOverlay(); + } + } + + function indexOfHighlight(s, p) { + for (let i = 0; i < highlights.length; ++i) { + let h = highlights[i]; + if (h.series == s && h.point[0] == p[0] && h.point[1] == p[1]) return i; + } + return -1; + } + + function drawPointHighlight(series, point) { + var x = point[0], + y = point[1], + axisx = series.xaxis, + axisy = series.yaxis, + highlightColor = + typeof series.highlightColor === 'string' + ? series.highlightColor + : $.color + .parse(series.color) + .scale('a', 0.5) + .toString(); + + if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) return; + + let pointRadius = series.points.radius + series.points.lineWidth / 2; + octx.lineWidth = pointRadius; + octx.strokeStyle = highlightColor; + let radius = 1.5 * pointRadius; + x = axisx.p2c(x); + y = axisy.p2c(y); + + octx.beginPath(); + if (series.points.symbol == 'circle') octx.arc(x, y, radius, 0, 2 * Math.PI, false); + else series.points.symbol(octx, x, y, radius, false); + octx.closePath(); + octx.stroke(); + } + + function drawBarHighlight(series, point) { + var highlightColor = + typeof series.highlightColor === 'string' + ? series.highlightColor + : $.color + .parse(series.color) + .scale('a', 0.5) + .toString(), + fillStyle = highlightColor, + barLeft; + + switch (series.bars.align) { + case 'left': + barLeft = 0; + break; + case 'right': + barLeft = -series.bars.barWidth; + break; + default: + barLeft = -series.bars.barWidth / 2; + } + + octx.lineWidth = series.bars.lineWidth; + octx.strokeStyle = highlightColor; + + drawBar( + point[0], + point[1], + point[2] || 0, + barLeft, + barLeft + series.bars.barWidth, + function() { + return fillStyle; + }, + series.xaxis, + series.yaxis, + octx, + series.bars.horizontal, + series.bars.lineWidth + ); + } + + function getColorOrGradient(spec, bottom, top, defaultColor) { + if (typeof spec == 'string') return spec; + else { + // assume this is a gradient spec; IE currently only + // supports a simple vertical gradient properly, so that's + // what we support too + let gradient = ctx.createLinearGradient(0, top, 0, bottom); + + for (let i = 0, l = spec.colors.length; i < l; ++i) { + let c = spec.colors[i]; + if (typeof c != 'string') { + let co = $.color.parse(defaultColor); + if (c.brightness != null) co = co.scale('rgb', c.brightness); + if (c.opacity != null) co.a *= c.opacity; + c = co.toString(); + } + gradient.addColorStop(i / (l - 1), c); + } + + return gradient; + } + } + } + + // Add the plot function to the top level of the jQuery object + + $.plot = function(placeholder, data, options) { + //var t0 = new Date(); + let plot = new Plot($(placeholder), data, options, $.plot.plugins); + //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime())); + return plot; + }; + + $.plot.version = '0.8.3'; + + $.plot.plugins = []; + + // Also add the plot function as a chainable property + + $.fn.plot = function(data, options) { + return this.each(function() { + $.plot(this, data, options); + }); + }; + + // round to nearby lower multiple of base + function floorInBase(n, base) { + return base * Math.floor(n / base); + } +})(window.jQuery); diff --git a/pkg/ui/react-app/src/vendor/flot/jquery.flot.stack.js b/pkg/ui/react-app/src/vendor/flot/jquery.flot.stack.js new file mode 100644 index 0000000000..b721606cc7 --- /dev/null +++ b/pkg/ui/react-app/src/vendor/flot/jquery.flot.stack.js @@ -0,0 +1,205 @@ +/** + * + * THIS FILE WAS COPIED INTO THANOS FROM GRAFANA'S VENDORED FORK OF FLOT + * (LIVING AT https://github.com/grafana/grafana/tree/master/public/vendor/flot), + * WHICH CONTAINS FIXES FOR DISPLAYING NULL VALUES IN STACKED GRAPHS. THE ORIGINAL + * FLOT CODE WAS LICENSED UNDER THE MIT LICENSE AS STATED BELOW. ADDITIONAL + * CHANGES HAVE BEEN CONTRIBUTED TO THE GRAFANA FORK UNDER AN APACHE 2 LICENSE, SEE + * https://github.com/grafana/grafana/blob/master/license. + * + */ + +/* eslint-disable prefer-spread */ +/* eslint-disable no-loop-func */ +/* eslint-disable @typescript-eslint/no-this-alias */ +/* eslint-disable no-redeclare */ +/* eslint-disable no-useless-escape */ +/* eslint-disable prefer-const */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-use-before-define */ +/* eslint-disable eqeqeq */ +/* eslint-disable no-var */ + +/* Flot plugin for stacking data sets rather than overlyaing them. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +The plugin assumes the data is sorted on x (or y if stacking horizontally). +For line charts, it is assumed that if a line has an undefined gap (from a +null point), then the line above it should have the same gap - insert zeros +instead of "null" if you want another behaviour. This also holds for the start +and end of the chart. Note that stacking a mix of positive and negative values +in most instances doesn't make sense (so it looks weird). + +Two or more series are stacked when their "stack" attribute is set to the same +key (which can be any number or string or just "true"). To specify the default +stack, you can set the stack option like this: + + series: { + stack: null/false, true, or a key (number/string) + } + +You can also specify it for a single series, like this: + + $.plot( $("#placeholder"), [{ + data: [ ... ], + stack: true + }]) + +The stacking order is determined by the order of the data series in the array +(later series end up on top of the previous). + +Internally, the plugin modifies the datapoints in each series, adding an +offset to the y value. For line series, extra data points are inserted through +interpolation. If there's a second y value, it's also adjusted (e.g for bar +charts or filled areas). + +*/ + +(function($) { + const options = { + series: { stack: null }, // or number/string + }; + + function init(plot) { + function findMatchingSeries(s, allseries) { + let res = null; + for (let i = 0; i < allseries.length; ++i) { + if (s == allseries[i]) break; + + if (allseries[i].stack == s.stack) res = allseries[i]; + } + + return res; + } + + function stackData(plot, s, datapoints) { + if (s.stack == null || s.stack === false) return; + + const other = findMatchingSeries(s, plot.getData()); + if (!other) return; + + let ps = datapoints.pointsize, + points = datapoints.points, + otherps = other.datapoints.pointsize, + otherpoints = other.datapoints.points, + newpoints = [], + px, + py, + intery, + qx, + qy, + bottom, + withlines = s.lines.show, + horizontal = s.bars.horizontal, + withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y), + withsteps = withlines && s.lines.steps, + keyOffset = horizontal ? 1 : 0, + accumulateOffset = horizontal ? 0 : 1, + i = 0, + j = 0, + l, + m; + + while (true) { + if (i >= points.length && j >= otherpoints.length) break; + + l = newpoints.length; + + if (i < points.length && points[i] == null) { + // copy gaps + for (m = 0; m < ps; ++m) newpoints.push(points[i + m]); + i += ps; + } else if (i >= points.length) { + // take the remaining points from the previous series + for (m = 0; m < ps; ++m) newpoints.push(otherpoints[j + m]); + if (withbottom) newpoints[l + 2] = otherpoints[j + accumulateOffset]; + j += otherps; + } else if (j >= otherpoints.length) { + // take the remaining points from the current series + for (m = 0; m < ps; ++m) newpoints.push(points[i + m]); + i += ps; + } else if (j < otherpoints.length && otherpoints[j] == null) { + // ignore point + j += otherps; + } else { + // cases where we actually got two points + px = points[i + keyOffset]; + py = points[i + accumulateOffset]; + qx = otherpoints[j + keyOffset]; + qy = otherpoints[j + accumulateOffset]; + bottom = 0; + + if (px == qx) { + for (m = 0; m < ps; ++m) newpoints.push(points[i + m]); + + newpoints[l + accumulateOffset] += qy; + bottom = qy; + + i += ps; + j += otherps; + } else if (px > qx) { + // take the point from the previous series so that next series will correctly stack + if (i == 0) { + for (m = 0; m < ps; ++m) newpoints.push(otherpoints[j + m]); + bottom = qy; + } + // we got past point below, might need to + // insert interpolated extra point + if (i > 0 && points[i - ps] != null) { + intery = py + ((points[i - ps + accumulateOffset] - py) * (qx - px)) / (points[i - ps + keyOffset] - px); + newpoints.push(qx); + newpoints.push(intery + qy); + for (m = 2; m < ps; ++m) newpoints.push(points[i + m]); + bottom = qy; + } + + j += otherps; + } else { + // px < qx + for (m = 0; m < ps; ++m) newpoints.push(points[i + m]); + + // we might be able to interpolate a point below, + // this can give us a better y + if (j > 0 && otherpoints[j - otherps] != null) + bottom = + qy + + ((otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx)) / + (otherpoints[j - otherps + keyOffset] - qx); + + newpoints[l + accumulateOffset] += bottom; + + i += ps; + } + + if (l != newpoints.length && withbottom) newpoints[l + 2] = bottom; + } + + // maintain the line steps invariant + if ( + withsteps && + l != newpoints.length && + l > 0 && + newpoints[l] != null && + newpoints[l] != newpoints[l - ps] && + newpoints[l + 1] != newpoints[l - ps + 1] + ) { + for (m = 0; m < ps; ++m) newpoints[l + ps + m] = newpoints[l + m]; + newpoints[l + 1] = newpoints[l - ps + 1]; + } + } + + datapoints.points = newpoints; + } + + plot.hooks.processDatapoints.push(stackData); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'stack', + version: '1.2', + }); +})(window.jQuery); diff --git a/pkg/ui/react-app/src/vendor/flot/jquery.flot.time.js b/pkg/ui/react-app/src/vendor/flot/jquery.flot.time.js new file mode 100644 index 0000000000..0b01c59fa3 --- /dev/null +++ b/pkg/ui/react-app/src/vendor/flot/jquery.flot.time.js @@ -0,0 +1,482 @@ +/** + * + * THIS FILE WAS COPIED INTO THANOS FROM GRAFANA'S VENDORED FORK OF FLOT + * (LIVING AT https://github.com/grafana/grafana/tree/master/public/vendor/flot), + * WHICH CONTAINS FIXES FOR DISPLAYING NULL VALUES IN STACKED GRAPHS. THE ORIGINAL + * FLOT CODE WAS LICENSED UNDER THE MIT LICENSE AS STATED BELOW. ADDITIONAL + * CHANGES HAVE BEEN CONTRIBUTED TO THE GRAFANA FORK UNDER AN APACHE 2 LICENSE, SEE + * https://github.com/grafana/grafana/blob/master/license. + * + */ + +/* eslint-disable prefer-rest-params */ +/* eslint-disable no-useless-concat */ +/* eslint-disable default-case */ +/* eslint-disable prefer-spread */ +/* eslint-disable no-loop-func */ +/* eslint-disable @typescript-eslint/no-this-alias */ +/* eslint-disable no-redeclare */ +/* eslint-disable no-useless-escape */ +/* eslint-disable prefer-const */ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +/* eslint-disable @typescript-eslint/no-use-before-define */ +/* eslint-disable eqeqeq */ +/* eslint-disable no-var */ + +/* Pretty handling of time axes. + +Copyright (c) 2007-2013 IOLA and Ole Laursen. +Licensed under the MIT license. + +Set axis.mode to "time" to enable. See the section "Time series data" in +API.txt for details. + +*/ + +(function($) { + const options = { + xaxis: { + timezone: null, // "browser" for local to the client or timezone for timezone-js + timeformat: null, // format string to use + twelveHourClock: false, // 12 or 24 time in time mode + monthNames: null, // list of names of months + }, + }; + + // round to nearby lower multiple of base + + function floorInBase(n, base) { + return base * Math.floor(n / base); + } + + // Returns a string with the date d formatted according to fmt. + // A subset of the Open Group's strftime format is supported. + + function formatDate(d, fmt, monthNames, dayNames) { + if (typeof d.strftime == 'function') { + return d.strftime(fmt); + } + + const leftPad = function(n, pad) { + n = '' + n; + pad = '' + (pad == null ? '0' : pad); + return n.length == 1 ? pad + n : n; + }; + + const r = []; + let escape = false; + const hours = d.getHours(); + const isAM = hours < 12; + + if (monthNames == null) { + monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + } + + if (dayNames == null) { + dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; + } + + let hours12; + + if (hours > 12) { + hours12 = hours - 12; + } else if (hours == 0) { + hours12 = 12; + } else { + hours12 = hours; + } + + for (let i = 0; i < fmt.length; ++i) { + let c = fmt.charAt(i); + + if (escape) { + switch (c) { + case 'a': + c = '' + dayNames[d.getDay()]; + break; + case 'b': + c = '' + monthNames[d.getMonth()]; + break; + case 'd': + c = leftPad(d.getDate(), ''); + break; + case 'e': + c = leftPad(d.getDate(), ' '); + break; + case 'h': // For back-compat with 0.7; remove in 1.0 + case 'H': + c = leftPad(hours); + break; + case 'I': + c = leftPad(hours12); + break; + case 'l': + c = leftPad(hours12, ' '); + break; + case 'm': + c = leftPad(d.getMonth() + 1, ''); + break; + case 'M': + c = leftPad(d.getMinutes()); + break; + // quarters not in Open Group's strftime specification + case 'q': + c = '' + (Math.floor(d.getMonth() / 3) + 1); + break; + case 'S': + c = leftPad(d.getSeconds()); + break; + case 'y': + c = leftPad(d.getFullYear() % 100); + break; + case 'Y': + c = '' + d.getFullYear(); + break; + case 'p': + c = isAM ? '' + 'am' : '' + 'pm'; + break; + case 'P': + c = isAM ? '' + 'AM' : '' + 'PM'; + break; + case 'w': + c = '' + d.getDay(); + break; + } + r.push(c); + escape = false; + } else { + if (c == '%') { + escape = true; + } else { + r.push(c); + } + } + } + + return r.join(''); + } + + // To have a consistent view of time-based data independent of which time + // zone the client happens to be in we need a date-like object independent + // of time zones. This is done through a wrapper that only calls the UTC + // versions of the accessor methods. + + function makeUtcWrapper(d) { + function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) { + sourceObj[sourceMethod] = function() { + return targetObj[targetMethod].apply(targetObj, arguments); + }; + } + + const utc = { + date: d, + }; + + // support strftime, if found + + if (d.strftime != undefined) { + addProxyMethod(utc, 'strftime', d, 'strftime'); + } + + addProxyMethod(utc, 'getTime', d, 'getTime'); + addProxyMethod(utc, 'setTime', d, 'setTime'); + + const props = ['Date', 'Day', 'FullYear', 'Hours', 'Milliseconds', 'Minutes', 'Month', 'Seconds']; + + for (let p = 0; p < props.length; p++) { + addProxyMethod(utc, 'get' + props[p], d, 'getUTC' + props[p]); + addProxyMethod(utc, 'set' + props[p], d, 'setUTC' + props[p]); + } + + return utc; + } + + // select time zone strategy. This returns a date-like object tied to the + // desired timezone + + function dateGenerator(ts, opts) { + if (opts.timezone == 'browser') { + return new Date(ts); + } else if (!opts.timezone || opts.timezone == 'utc') { + return makeUtcWrapper(new Date(ts)); + } + // } else if (typeof timezoneJS != 'undefined' && typeof timezoneJS.Date != 'undefined') { + // const d = new timezoneJS.Date(); + // // timezone-js is fickle, so be sure to set the time zone before + // // setting the time. + // d.setTimezone(opts.timezone); + // d.setTime(ts); + // return d; + // } + return makeUtcWrapper(new Date(ts)); + } + + // map of app. size of time units in milliseconds + + const timeUnitSize = { + second: 1000, + minute: 60 * 1000, + hour: 60 * 60 * 1000, + day: 24 * 60 * 60 * 1000, + month: 30 * 24 * 60 * 60 * 1000, + quarter: 3 * 30 * 24 * 60 * 60 * 1000, + year: 365.2425 * 24 * 60 * 60 * 1000, + }; + + // the allowed tick sizes, after 1 year we use + // an integer algorithm + + const baseSpec = [ + [1, 'second'], + [2, 'second'], + [5, 'second'], + [10, 'second'], + [30, 'second'], + [1, 'minute'], + [2, 'minute'], + [5, 'minute'], + [10, 'minute'], + [30, 'minute'], + [1, 'hour'], + [2, 'hour'], + [4, 'hour'], + [8, 'hour'], + [12, 'hour'], + [1, 'day'], + [2, 'day'], + [3, 'day'], + [0.25, 'month'], + [0.5, 'month'], + [1, 'month'], + [2, 'month'], + ]; + + // we don't know which variant(s) we'll need yet, but generating both is + // cheap + + const specMonths = baseSpec.concat([[3, 'month'], [6, 'month'], [1, 'year']]); + const specQuarters = baseSpec.concat([[1, 'quarter'], [2, 'quarter'], [1, 'year']]); + + function init(plot) { + plot.hooks.processOptions.push(function(plot) { + $.each(plot.getAxes(), function(axisName, axis) { + const opts = axis.options; + + if (opts.mode == 'time') { + axis.tickGenerator = function(axis) { + const ticks = []; + const d = dateGenerator(axis.min, opts); + let minSize = 0; + + // make quarter use a possibility if quarters are + // mentioned in either of these options + + const spec = + (opts.tickSize && opts.tickSize[1] === 'quarter') || (opts.minTickSize && opts.minTickSize[1] === 'quarter') + ? specQuarters + : specMonths; + + if (opts.minTickSize != null) { + if (typeof opts.tickSize == 'number') { + minSize = opts.tickSize; + } else { + minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]]; + } + } + + for (var i = 0; i < spec.length - 1; ++i) { + if ( + axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]] + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 && + spec[i][0] * timeUnitSize[spec[i][1]] >= minSize + ) { + break; + } + } + + let size = spec[i][0]; + let unit = spec[i][1]; + + // special-case the possibility of several years + + if (unit == 'year') { + // if given a minTickSize in years, just use it, + // ensuring that it's an integer + + if (opts.minTickSize != null && opts.minTickSize[1] == 'year') { + size = Math.floor(opts.minTickSize[0]); + } else { + const magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10)); + const norm = axis.delta / timeUnitSize.year / magn; + + if (norm < 1.5) { + size = 1; + } else if (norm < 3) { + size = 2; + } else if (norm < 7.5) { + size = 5; + } else { + size = 10; + } + + size *= magn; + } + + // minimum size for years is 1 + + if (size < 1) { + size = 1; + } + } + + axis.tickSize = opts.tickSize || [size, unit]; + const tickSize = axis.tickSize[0]; + unit = axis.tickSize[1]; + + const step = tickSize * timeUnitSize[unit]; + + if (unit == 'second') { + d.setSeconds(floorInBase(d.getSeconds(), tickSize)); + } else if (unit == 'minute') { + d.setMinutes(floorInBase(d.getMinutes(), tickSize)); + } else if (unit == 'hour') { + d.setHours(floorInBase(d.getHours(), tickSize)); + } else if (unit == 'month') { + d.setMonth(floorInBase(d.getMonth(), tickSize)); + } else if (unit == 'quarter') { + d.setMonth(3 * floorInBase(d.getMonth() / 3, tickSize)); + } else if (unit == 'year') { + d.setFullYear(floorInBase(d.getFullYear(), tickSize)); + } + + // reset smaller components + + d.setMilliseconds(0); + + if (step >= timeUnitSize.minute) { + d.setSeconds(0); + } + if (step >= timeUnitSize.hour) { + d.setMinutes(0); + } + if (step >= timeUnitSize.day) { + d.setHours(0); + } + if (step >= timeUnitSize.day * 4) { + d.setDate(1); + } + if (step >= timeUnitSize.month * 2) { + d.setMonth(floorInBase(d.getMonth(), 3)); + } + if (step >= timeUnitSize.quarter * 2) { + d.setMonth(floorInBase(d.getMonth(), 6)); + } + if (step >= timeUnitSize.year) { + d.setMonth(0); + } + + let carry = 0; + let v = Number.NaN; + let prev; + + do { + prev = v; + v = d.getTime(); + ticks.push(v); + + if (unit == 'month' || unit == 'quarter') { + if (tickSize < 1) { + // a bit complicated - we'll divide the + // month/quarter up but we need to take + // care of fractions so we don't end up in + // the middle of a day + + d.setDate(1); + const start = d.getTime(); + d.setMonth(d.getMonth() + (unit == 'quarter' ? 3 : 1)); + const end = d.getTime(); + d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); + carry = d.getHours(); + d.setHours(0); + } else { + d.setMonth(d.getMonth() + tickSize * (unit == 'quarter' ? 3 : 1)); + } + } else if (unit == 'year') { + d.setFullYear(d.getFullYear() + tickSize); + } else { + d.setTime(v + step); + } + } while (v < axis.max && v != prev); + + return ticks; + }; + + axis.tickFormatter = function(v, axis) { + const d = dateGenerator(v, axis.options); + + // first check global format + + if (opts.timeformat != null) { + return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames); + } + + // possibly use quarters if quarters are mentioned in + // any of these places + + const useQuarters = + (axis.options.tickSize && axis.options.tickSize[1] == 'quarter') || + (axis.options.minTickSize && axis.options.minTickSize[1] == 'quarter'); + + const t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; + const span = axis.max - axis.min; + const suffix = opts.twelveHourClock ? ' %p' : ''; + const hourCode = opts.twelveHourClock ? '%I' : '%H'; + let fmt; + + if (t < timeUnitSize.minute) { + fmt = hourCode + ':%M:%S' + suffix; + } else if (t < timeUnitSize.day) { + if (span < 2 * timeUnitSize.day) { + fmt = hourCode + ':%M' + suffix; + } else { + fmt = '%b %d ' + hourCode + ':%M' + suffix; + } + } else if (t < timeUnitSize.month) { + fmt = '%b %d'; + } else if ((useQuarters && t < timeUnitSize.quarter) || (!useQuarters && t < timeUnitSize.year)) { + if (span < timeUnitSize.year) { + fmt = '%b'; + } else { + fmt = '%b %Y'; + } + } else if (useQuarters && t < timeUnitSize.year) { + if (span < timeUnitSize.year) { + fmt = 'Q%q'; + } else { + fmt = 'Q%q %Y'; + } + } else { + fmt = '%Y'; + } + + const rt = formatDate(d, fmt, opts.monthNames, opts.dayNames); + + return rt; + }; + } + }); + }); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'time', + version: '1.0', + }); + + // Time-axis support used to be in Flot core, which exposed the + // formatDate function on the plot object. Various plugins depend + // on the function, so we need to re-expose it here. + + $.plot.formatDate = formatDate; +})(window.jQuery); diff --git a/pkg/ui/react-app/tsconfig.json b/pkg/ui/react-app/tsconfig.json new file mode 100644 index 0000000000..15dc86f99b --- /dev/null +++ b/pkg/ui/react-app/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve" + }, + "include": [ + "src", "test", "react-app-env.d.ts" + ] +} diff --git a/pkg/ui/react-app/yarn.lock b/pkg/ui/react-app/yarn.lock new file mode 100644 index 0000000000..491cd472bc --- /dev/null +++ b/pkg/ui/react-app/yarn.lock @@ -0,0 +1,11523 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.8.3", "@babel/code-frame@^7.0.0", "@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/compat-data@^7.8.6", "@babel/compat-data@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.9.0.tgz#04815556fc90b0c174abd2c0c1bb966faa036a6c" + integrity sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g== + dependencies: + browserslist "^4.9.1" + invariant "^2.2.4" + semver "^5.5.0" + +"@babel/core@7.9.0", "@babel/core@^7.1.0", "@babel/core@^7.4.5": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" + integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.0" + "@babel/parser" "^7.9.0" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + 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.4.0", "@babel/generator@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.0.tgz#0f67adea4ec39dad6e63345f70eec33014d78c89" + integrity sha512-onl4Oy46oGCzymOXtKMQpI7VXtCbTSHK1kqBydZ6AmzuNcacEVqGk9tZtAS+48IA9IstZcDCgIg8hQKnb7suRw== + dependencies: + "@babel/types" "^7.9.0" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz#60bc0bc657f63a0924ff9a4b4a0b24a13cf4deee" + integrity sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz#c84097a427a061ac56a1c30ebf54b7b22d241503" + integrity sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-builder-react-jsx-experimental@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.9.0.tgz#066d80262ade488f9c1b1823ce5db88a4cedaa43" + integrity sha512-3xJEiyuYU4Q/Ar9BsHisgdxZsRlsShMe90URZ0e6przL26CCs8NJbDoxH94kKT17PcxlMhsCAwZd90evCo26VQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-module-imports" "^7.8.3" + "@babel/types" "^7.9.0" + +"@babel/helper-builder-react-jsx@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.9.0.tgz#16bf391990b57732700a3278d4d9a81231ea8d32" + integrity sha512-weiIo4gaoGgnhff54GQ3P5wsUQmnSwpkvU0r6ZHq6TzoSzKy4JxHEgnxNytaKbov2a9z/CVNyzliuCOUPEX3Jw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/types" "^7.9.0" + +"@babel/helper-call-delegate@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.8.7.tgz#28a279c2e6c622a6233da548127f980751324cab" + integrity sha512-doAA5LAKhsFCR0LAFIf+r2RSMmC+m8f/oQ+URnUET/rWeEzC0yTRmAGyWkD4sSu3xwbS7MYQ2u+xlt1V5R56KQ== + dependencies: + "@babel/helper-hoist-variables" "^7.8.3" + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.7" + +"@babel/helper-compilation-targets@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz#dac1eea159c0e4bd46e309b5a1b04a66b53c1dde" + integrity sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw== + dependencies: + "@babel/compat-data" "^7.8.6" + browserslist "^4.9.1" + invariant "^2.2.4" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/helper-create-class-features-plugin@^7.8.3": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.6.tgz#243a5b46e2f8f0f674dc1387631eb6b28b851de0" + integrity sha512-klTBDdsr+VFFqaDHm5rR69OpEQtO2Qv8ECxHS1mNhJJvaHArR6a1xTf5K/eZW7eZpJbhCx3NW1Yt/sKsLXLblg== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-split-export-declaration" "^7.8.3" + +"@babel/helper-create-regexp-features-plugin@^7.8.3", "@babel/helper-create-regexp-features-plugin@^7.8.8": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz#5d84180b588f560b7864efaeea89243e58312087" + integrity sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-regex" "^7.8.3" + regexpu-core "^4.7.0" + +"@babel/helper-define-map@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz#a0655cad5451c3760b726eba875f1cd8faa02c15" + integrity sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/types" "^7.8.3" + lodash "^4.17.13" + +"@babel/helper-explode-assignable-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz#a728dc5b4e89e30fc2dfc7d04fa28a930653f982" + integrity sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw== + dependencies: + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@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-hoist-variables@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz#1dbe9b6b55d78c9b4183fc8cdc6e30ceb83b7134" + integrity sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-member-expression-to-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" + integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-imports@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" + integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-transforms@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" + integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-simple-access" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/template" "^7.8.6" + "@babel/types" "^7.9.0" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9" + integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" + integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== + +"@babel/helper-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.8.3.tgz#139772607d51b93f23effe72105b319d2a4c6965" + integrity sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ== + dependencies: + lodash "^4.17.13" + +"@babel/helper-remap-async-to-generator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz#273c600d8b9bf5006142c1e35887d555c12edd86" + integrity sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-wrap-function" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-replace-supers@^7.8.3", "@babel/helper-replace-supers@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" + integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/helper-simple-access@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae" + integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw== + dependencies: + "@babel/template" "^7.8.3" + "@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/helper-validator-identifier@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed" + integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw== + +"@babel/helper-wrap-function@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz#9dbdb2bb55ef14aaa01fe8c99b629bd5352d8610" + integrity sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helpers@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" + integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== + dependencies: + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + +"@babel/highlight@^7.8.3": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.2.tgz#4e767f424b479c514077544484d1f9bdba7f1158" + integrity sha512-2jyvKdoOS1aWAFL2rjJZmamyDDkPCx/AAz4/Wh1Dfxvw8qqnOvek/ZlHQ2noO/o8JpnXa/WiUUFOv48meBKkpA== + +"@babel/plugin-proposal-async-generator-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz#bad329c670b382589721b27540c7d288601c6e6f" + integrity sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-remap-async-to-generator" "^7.8.3" + "@babel/plugin-syntax-async-generators" "^7.8.0" + +"@babel/plugin-proposal-class-properties@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz#5e06654af5cd04b608915aada9b2a6788004464e" + integrity sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-proposal-decorators@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz#2156860ab65c5abf068c3f67042184041066543e" + integrity sha512-e3RvdvS4qPJVTe288DlXjwKflpfy1hr0j5dz5WpIYYeP7vQZg2WfAEIp8k5/Lwis/m5REXEteIz6rrcDtXXG7w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-decorators" "^7.8.3" + +"@babel/plugin-proposal-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz#38c4fe555744826e97e2ae930b0fb4cc07e66054" + integrity sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + +"@babel/plugin-proposal-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz#da5216b238a98b58a1e05d6852104b10f9a70d6b" + integrity sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.0" + +"@babel/plugin-proposal-nullish-coalescing-operator@7.8.3", "@babel/plugin-proposal-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz#e4572253fdeed65cddeecfdab3f928afeb2fd5d2" + integrity sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + +"@babel/plugin-proposal-numeric-separator@7.8.3", "@babel/plugin-proposal-numeric-separator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz#5d6769409699ec9b3b68684cd8116cedff93bad8" + integrity sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + +"@babel/plugin-proposal-object-rest-spread@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz#a28993699fc13df165995362693962ba6b061d6f" + integrity sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz#9dee96ab1650eed88646ae9734ca167ac4a9c5c9" + integrity sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + +"@babel/plugin-proposal-optional-chaining@7.9.0", "@babel/plugin-proposal-optional-chaining@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz#31db16b154c39d6b8a645292472b98394c292a58" + integrity sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.4.4", "@babel/plugin-proposal-unicode-property-regex@^7.8.3": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz#ee3a95e90cdc04fe8cd92ec3279fa017d68a0d1d" + integrity sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.8" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-async-generators@^7.8.0": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-decorators@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.8.3.tgz#8d2c15a9f1af624b0025f961682a9d53d3001bda" + integrity sha512-8Hg4dNNT9/LcA1zQlfwuKR8BUc/if7Q7NkTam9sGTcJphLwpf2g4S42uhspQrIrR+dpzE0dtTqBVFoHl8GtnnQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-dynamic-import@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-flow@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.8.3.tgz#f2c883bd61a6316f2c89380ae5122f923ba4527f" + integrity sha512-innAx3bUbA0KSYj2E2MNFSn9hiCeowOFLxlsuhXzw8hMQnzkDomUr9QCD7E9VF60NmnG1sNTuuv6Qf4f8INYsg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-json-strings@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz#521b06c83c40480f1e58b4fd33b92eceb1d6ea94" + integrity sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.0", "@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz#0e3fb63e09bea1b11e96467271c8308007e7c41f" + integrity sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz#3acdece695e6b13aaf57fc291d1a800950c71391" + integrity sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-typescript@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.8.3.tgz#c1f659dda97711a569cef75275f7e15dcaa6cabc" + integrity sha512-GO1MQ/SGGGoiEXY0e0bSpHimJvxqB7lktLLIq2pv8xG7WZ8IMEle74jIe1FhprHBWjwjZtXHkycDLZXIWM5Wfg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-arrow-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz#82776c2ed0cd9e1a49956daeb896024c9473b8b6" + integrity sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-async-to-generator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz#4308fad0d9409d71eafb9b1a6ee35f9d64b64086" + integrity sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-remap-async-to-generator" "^7.8.3" + +"@babel/plugin-transform-block-scoped-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz#437eec5b799b5852072084b3ae5ef66e8349e8a3" + integrity sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-block-scoping@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz#97d35dab66857a437c166358b91d09050c868f3a" + integrity sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + lodash "^4.17.13" + +"@babel/plugin-transform-classes@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz#8603fc3cc449e31fdbdbc257f67717536a11af8d" + integrity sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-define-map" "^7.8.3" + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-split-export-declaration" "^7.8.3" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz#96d0d28b7f7ce4eb5b120bb2e0e943343c86f81b" + integrity sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-destructuring@^7.8.3": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz#fadb2bc8e90ccaf5658de6f8d4d22ff6272a2f4b" + integrity sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-dotall-regex@^7.4.4", "@babel/plugin-transform-dotall-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz#c3c6ec5ee6125c6993c5cbca20dc8621a9ea7a6e" + integrity sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-duplicate-keys@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz#8d12df309aa537f272899c565ea1768e286e21f1" + integrity sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-exponentiation-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz#581a6d7f56970e06bf51560cd64f5e947b70d7b7" + integrity sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-flow-strip-types@7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.9.0.tgz#8a3538aa40434e000b8f44a3c5c9ac7229bd2392" + integrity sha512-7Qfg0lKQhEHs93FChxVLAvhBshOPQDtJUTVHr/ZwQNRccCm4O9D79r9tVSoV8iNwjP1YgfD+e/fgHcPkN1qEQg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-flow" "^7.8.3" + +"@babel/plugin-transform-for-of@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz#0f260e27d3e29cd1bb3128da5e76c761aa6c108e" + integrity sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-function-name@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz#279373cb27322aaad67c2683e776dfc47196ed8b" + integrity sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz#aef239823d91994ec7b68e55193525d76dbd5dc1" + integrity sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-member-expression-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz#963fed4b620ac7cbf6029c755424029fa3a40410" + integrity sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-modules-amd@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz#19755ee721912cf5bb04c07d50280af3484efef4" + integrity sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-commonjs@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz#e3e72f4cbc9b4a260e30be0ea59bdf5a39748940" + integrity sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-simple-access" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-systemjs@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz#e9fd46a296fc91e009b64e07ddaa86d6f0edeb90" + integrity sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ== + dependencies: + "@babel/helper-hoist-variables" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-umd@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz#e909acae276fec280f9b821a5f38e1f08b480697" + integrity sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz#a2a72bffa202ac0e2d0506afd0939c5ecbc48c6c" + integrity sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + +"@babel/plugin-transform-new-target@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz#60cc2ae66d85c95ab540eb34babb6434d4c70c43" + integrity sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-object-super@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz#ebb6a1e7a86ffa96858bd6ac0102d65944261725" + integrity sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.8.7": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.8.tgz#0381de466c85d5404565243660c4496459525daf" + integrity sha512-hC4Ld/Ulpf1psQciWWwdnUspQoQco2bMzSrwU6TmzRlvoYQe4rQFy9vnCZDTlVeCQj0JPfL+1RX0V8hCJvkgBA== + dependencies: + "@babel/helper-call-delegate" "^7.8.7" + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-property-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz#33194300d8539c1ed28c62ad5087ba3807b98263" + integrity sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-react-constant-elements@^7.0.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.9.0.tgz#a75abc936a3819edec42d3386d9f1c93f28d9d9e" + integrity sha512-wXMXsToAUOxJuBBEHajqKLFWcCkOSLshTI2ChCFFj1zDd7od4IOxiwLCOObNUvOpkxLpjIuaIdBMmNt6ocCPAw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-react-display-name@7.8.3", "@babel/plugin-transform-react-display-name@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz#70ded987c91609f78353dd76d2fb2a0bb991e8e5" + integrity sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-react-jsx-development@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.9.0.tgz#3c2a130727caf00c2a293f0aed24520825dbf754" + integrity sha512-tK8hWKrQncVvrhvtOiPpKrQjfNX3DtkNLSX4ObuGcpS9p0QrGetKmlySIGR07y48Zft8WVgPakqd/bk46JrMSw== + dependencies: + "@babel/helper-builder-react-jsx-experimental" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-jsx" "^7.8.3" + +"@babel/plugin-transform-react-jsx-self@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.9.0.tgz#f4f26a325820205239bb915bad8e06fcadabb49b" + integrity sha512-K2ObbWPKT7KUTAoyjCsFilOkEgMvFG+y0FqOl6Lezd0/13kMkkjHskVsZvblRPj1PHA44PrToaZANrryppzTvQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-jsx" "^7.8.3" + +"@babel/plugin-transform-react-jsx-source@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.9.0.tgz#89ef93025240dd5d17d3122294a093e5e0183de0" + integrity sha512-K6m3LlSnTSfRkM6FcRk8saNEeaeyG5k7AVkBU2bZK3+1zdkSED3qNdsWrUgQBeTVD2Tp3VMmerxVO2yM5iITmw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-jsx" "^7.8.3" + +"@babel/plugin-transform-react-jsx@^7.9.1": + version "7.9.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.9.1.tgz#d03af29396a6dc51bfa24eefd8005a9fd381152a" + integrity sha512-+xIZ6fPoix7h57CNO/ZeYADchg1tFyX9NDsnmNFFua8e1JNPln156mzS+8AQe1On2X2GLlANHJWHIXbMCqWDkQ== + dependencies: + "@babel/helper-builder-react-jsx" "^7.9.0" + "@babel/helper-builder-react-jsx-experimental" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-jsx" "^7.8.3" + +"@babel/plugin-transform-regenerator@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz#5e46a0dca2bee1ad8285eb0527e6abc9c37672f8" + integrity sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz#9a0635ac4e665d29b162837dd3cc50745dfdf1f5" + integrity sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-runtime@7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz#45468c0ae74cc13204e1d3b1f4ce6ee83258af0b" + integrity sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + resolve "^1.8.1" + semver "^5.5.1" + +"@babel/plugin-transform-shorthand-properties@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz#28545216e023a832d4d3a1185ed492bcfeac08c8" + integrity sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz#9c8ffe8170fdfb88b114ecb920b82fb6e95fe5e8" + integrity sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-sticky-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz#be7a1290f81dae767475452199e1f76d6175b100" + integrity sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-regex" "^7.8.3" + +"@babel/plugin-transform-template-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz#7bfa4732b455ea6a43130adc0ba767ec0e402a80" + integrity sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-typeof-symbol@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz#ede4062315ce0aaf8a657a920858f1a2f35fc412" + integrity sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-typescript@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.9.0.tgz#8b52649c81cb7dee117f760952ab46675a258836" + integrity sha512-GRffJyCu16H3tEhbt9Q4buVFFBqrgS8FzTuhqSxlXNgmqD8aw2xmwtRwrvWXXlw7gHs664uqacsJymHJ9SUE/Q== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-typescript" "^7.8.3" + +"@babel/plugin-transform-unicode-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz#0cef36e3ba73e5c57273effb182f46b91a1ecaad" + integrity sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/preset-env@7.9.0", "@babel/preset-env@^7.4.5": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.9.0.tgz#a5fc42480e950ae8f5d9f8f2bbc03f52722df3a8" + integrity sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ== + dependencies: + "@babel/compat-data" "^7.9.0" + "@babel/helper-compilation-targets" "^7.8.7" + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-proposal-async-generator-functions" "^7.8.3" + "@babel/plugin-proposal-dynamic-import" "^7.8.3" + "@babel/plugin-proposal-json-strings" "^7.8.3" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-proposal-numeric-separator" "^7.8.3" + "@babel/plugin-proposal-object-rest-spread" "^7.9.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.8.3" + "@babel/plugin-proposal-optional-chaining" "^7.9.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.8.3" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.8.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.8.3" + "@babel/plugin-transform-async-to-generator" "^7.8.3" + "@babel/plugin-transform-block-scoped-functions" "^7.8.3" + "@babel/plugin-transform-block-scoping" "^7.8.3" + "@babel/plugin-transform-classes" "^7.9.0" + "@babel/plugin-transform-computed-properties" "^7.8.3" + "@babel/plugin-transform-destructuring" "^7.8.3" + "@babel/plugin-transform-dotall-regex" "^7.8.3" + "@babel/plugin-transform-duplicate-keys" "^7.8.3" + "@babel/plugin-transform-exponentiation-operator" "^7.8.3" + "@babel/plugin-transform-for-of" "^7.9.0" + "@babel/plugin-transform-function-name" "^7.8.3" + "@babel/plugin-transform-literals" "^7.8.3" + "@babel/plugin-transform-member-expression-literals" "^7.8.3" + "@babel/plugin-transform-modules-amd" "^7.9.0" + "@babel/plugin-transform-modules-commonjs" "^7.9.0" + "@babel/plugin-transform-modules-systemjs" "^7.9.0" + "@babel/plugin-transform-modules-umd" "^7.9.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3" + "@babel/plugin-transform-new-target" "^7.8.3" + "@babel/plugin-transform-object-super" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.8.7" + "@babel/plugin-transform-property-literals" "^7.8.3" + "@babel/plugin-transform-regenerator" "^7.8.7" + "@babel/plugin-transform-reserved-words" "^7.8.3" + "@babel/plugin-transform-shorthand-properties" "^7.8.3" + "@babel/plugin-transform-spread" "^7.8.3" + "@babel/plugin-transform-sticky-regex" "^7.8.3" + "@babel/plugin-transform-template-literals" "^7.8.3" + "@babel/plugin-transform-typeof-symbol" "^7.8.4" + "@babel/plugin-transform-unicode-regex" "^7.8.3" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.9.0" + browserslist "^4.9.1" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/preset-modules@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" + integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-react@7.9.1", "@babel/preset-react@^7.0.0": + version "7.9.1" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.9.1.tgz#b346403c36d58c3bb544148272a0cefd9c28677a" + integrity sha512-aJBYF23MPj0RNdp/4bHnAP0NVqqZRr9kl0NAOP4nJCex6OYVio59+dnQzsAWFuogdLyeaKA1hmfUIVZkY5J+TQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-transform-react-display-name" "^7.8.3" + "@babel/plugin-transform-react-jsx" "^7.9.1" + "@babel/plugin-transform-react-jsx-development" "^7.9.0" + "@babel/plugin-transform-react-jsx-self" "^7.9.0" + "@babel/plugin-transform-react-jsx-source" "^7.9.0" + +"@babel/preset-typescript@7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.9.0.tgz#87705a72b1f0d59df21c179f7c3d2ef4b16ce192" + integrity sha512-S4cueFnGrIbvYJgwsVFKdvOmpiL0XGw9MFW9D0vgRys5g36PBhZRL8NX8Gr2akz8XRtzq6HuDXPD/1nniagNUg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-transform-typescript" "^7.9.0" + +"@babel/runtime-corejs3@^7.8.3": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.9.2.tgz#26fe4aa77e9f1ecef9b776559bbb8e84d34284b7" + integrity sha512-HHxmgxbIzOfFlZ+tdeRKtaxWOMUoCG5Mu3wKeUmOxjYrwb3AAHgnmtCUbPPK11/raIWLIBK250t8E2BPO0p7jA== + dependencies: + core-js-pure "^3.0.0" + regenerator-runtime "^0.13.4" + +"@babel/runtime@7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.0.tgz#337eda67401f5b066a6f205a3113d4ac18ba495b" + integrity sha512-cTIudHnzuWLS56ik4DnRnqqNf8MkdUzV4iFFI1h7Jo9xvrpQROYaAnaSd2mHLQAzzZAPfATynX5ord6YlNYNMA== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.4", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.4.0", "@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.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.0.tgz#d3882c2830e513f4fe4cec9fe76ea1cc78747892" + integrity sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.9.0" + "@babel/types" "^7.9.0" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.8.7", "@babel/types@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5" + integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@cnakazawa/watch@^1.0.3": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" + integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.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== + +"@csstools/normalize.css@^10.1.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18" + integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg== + +"@fortawesome/fontawesome-common-types@^0.2.27": + version "0.2.27" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.27.tgz#19706345859fc46adf3684ed01d11b40903b87e9" + integrity sha512-97GaByGaXDGMkzcJX7VmR/jRJd8h1mfhtA7RsxDBN61GnWE/PPCZhOdwG/8OZYktiRUF0CvFOr+VgRkJrt6TWg== + +"@fortawesome/fontawesome-svg-core@^1.2.14": + version "1.2.27" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.27.tgz#e4db8e3be81a40988213507c3e3d0c158a6641a3" + integrity sha512-sOD3DKynocnHYpuw2sLPnTunDj7rLk91LYhi2axUYwuGe9cPCw7Bsu9EWtVdNJP+IYgTCZIbyARKXuy5K/nv+Q== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.27" + +"@fortawesome/free-solid-svg-icons@^5.7.1": + version "5.12.1" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.12.1.tgz#76b6f958a3471821ff146f8f955e6d7cfe87147c" + integrity sha512-k3MwRFFUhyL4cuCJSaHDA0YNYMELDXX0h8JKtWYxO5XD3Dn+maXOMrVAAiNGooUyM2v/wz/TOaM0jxYVKeXX7g== + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.27" + +"@fortawesome/react-fontawesome@^0.1.4": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.9.tgz#c865b9286c707407effcec99958043711367cd02" + integrity sha512-49V3WNysLZU5fZ3sqSuys4nGRytsrxJktbv3vuaXkEoxv22C6T7TEG0TW6+nqVjMnkfCQd5xOnmJoZHMF78tOw== + dependencies: + prop-types "^15.7.2" + +"@hapi/address@2.x.x": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" + integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ== + +"@hapi/bourne@1.x.x": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" + integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== + +"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": + version "8.5.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" + integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow== + +"@hapi/joi@^15.0.0": + version "15.1.1" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" + integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== + dependencies: + "@hapi/address" "2.x.x" + "@hapi/bourne" "1.x.x" + "@hapi/hoek" "8.x.x" + "@hapi/topo" "3.x.x" + +"@hapi/topo@3.x.x": + version "3.1.6" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" + integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ== + dependencies: + "@hapi/hoek" "^8.3.0" + +"@jest/console@^24.7.1", "@jest/console@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" + integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== + dependencies: + "@jest/source-map" "^24.9.0" + chalk "^2.0.1" + slash "^2.0.0" + +"@jest/core@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" + integrity sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A== + dependencies: + "@jest/console" "^24.7.1" + "@jest/reporters" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-changed-files "^24.9.0" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-resolve-dependencies "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + jest-watcher "^24.9.0" + micromatch "^3.1.10" + p-each-series "^1.0.0" + realpath-native "^1.1.0" + rimraf "^2.5.4" + slash "^2.0.0" + strip-ansi "^5.0.0" + +"@jest/environment@^24.3.0", "@jest/environment@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" + integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ== + dependencies: + "@jest/fake-timers" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + +"@jest/fake-timers@^24.3.0", "@jest/fake-timers@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" + integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== + dependencies: + "@jest/types" "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + +"@jest/reporters@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" + integrity sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + istanbul-lib-coverage "^2.0.2" + istanbul-lib-instrument "^3.0.1" + istanbul-lib-report "^2.0.4" + istanbul-lib-source-maps "^3.0.1" + istanbul-reports "^2.2.6" + jest-haste-map "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.6.0" + node-notifier "^5.4.2" + slash "^2.0.0" + source-map "^0.6.0" + string-length "^2.0.0" + +"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" + integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.1.15" + source-map "^0.6.0" + +"@jest/test-result@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" + integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== + dependencies: + "@jest/console" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/istanbul-lib-coverage" "^2.0.0" + +"@jest/test-sequencer@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" + integrity sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A== + dependencies: + "@jest/test-result" "^24.9.0" + jest-haste-map "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + +"@jest/transform@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" + integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^24.9.0" + babel-plugin-istanbul "^5.1.0" + chalk "^2.0.1" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.15" + jest-haste-map "^24.9.0" + jest-regex-util "^24.9.0" + jest-util "^24.9.0" + micromatch "^3.1.10" + pirates "^4.0.1" + realpath-native "^1.1.0" + slash "^2.0.0" + source-map "^0.6.1" + write-file-atomic "2.4.1" + +"@jest/types@^24.3.0", "@jest/types@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" + integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^13.0.0" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@reach/router@^1.2.1": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.3.3.tgz#58162860dce6c9449d49be86b0561b5ef46d80db" + integrity sha512-gOIAiFhWdiVGSVjukKeNKkCRBLmnORoTPyBihI/jLunICPgxdP30DroAvPQuf1eVfQbfGJQDJkwhJXsNPMnVWw== + dependencies: + create-react-context "0.3.0" + invariant "^2.2.3" + prop-types "^15.6.1" + react-lifecycles-compat "^3.0.4" + +"@sinonjs/commons@^1", "@sinonjs/commons@^1.3.0", "@sinonjs/commons@^1.4.0", "@sinonjs/commons@^1.7.0": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.1.tgz#da5fd19a5f71177a53778073978873964f49acf1" + integrity sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/formatio@^3.2.1": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.2.2.tgz#771c60dfa75ea7f2d68e3b94c7e888a78781372c" + integrity sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ== + dependencies: + "@sinonjs/commons" "^1" + "@sinonjs/samsam" "^3.1.0" + +"@sinonjs/samsam@^3.1.0", "@sinonjs/samsam@^3.3.3": + version "3.3.3" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.3.3.tgz#46682efd9967b259b81136b9f120fd54585feb4a" + integrity sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ== + dependencies: + "@sinonjs/commons" "^1.3.0" + array-from "^2.1.1" + lodash "^4.17.15" + +"@sinonjs/text-encoding@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" + integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== + +"@svgr/babel-plugin-add-jsx-attribute@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1" + integrity sha512-j7KnilGyZzYr/jhcrSYS3FGWMZVaqyCG0vzMCwzvei0coIkczuYMcniK07nI0aHJINciujjH11T72ICW5eL5Ig== + +"@svgr/babel-plugin-remove-jsx-attribute@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-4.2.0.tgz#297550b9a8c0c7337bea12bdfc8a80bb66f85abc" + integrity sha512-3XHLtJ+HbRCH4n28S7y/yZoEQnRpl0tvTZQsHqvaeNXPra+6vE5tbRliH3ox1yZYPCxrlqaJT/Mg+75GpDKlvQ== + +"@svgr/babel-plugin-remove-jsx-empty-expression@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-4.2.0.tgz#c196302f3e68eab6a05e98af9ca8570bc13131c7" + integrity sha512-yTr2iLdf6oEuUE9MsRdvt0NmdpMBAkgK8Bjhl6epb+eQWk6abBaX3d65UZ3E3FWaOwePyUgNyNCMVG61gGCQ7w== + +"@svgr/babel-plugin-replace-jsx-attribute-value@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-4.2.0.tgz#310ec0775de808a6a2e4fd4268c245fd734c1165" + integrity sha512-U9m870Kqm0ko8beHawRXLGLvSi/ZMrl89gJ5BNcT452fAjtF2p4uRzXkdzvGJJJYBgx7BmqlDjBN/eCp5AAX2w== + +"@svgr/babel-plugin-svg-dynamic-title@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-4.3.3.tgz#2cdedd747e5b1b29ed4c241e46256aac8110dd93" + integrity sha512-w3Be6xUNdwgParsvxkkeZb545VhXEwjGMwExMVBIdPQJeyMQHqm9Msnb2a1teHBqUYL66qtwfhNkbj1iarCG7w== + +"@svgr/babel-plugin-svg-em-dimensions@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-4.2.0.tgz#9a94791c9a288108d20a9d2cc64cac820f141391" + integrity sha512-C0Uy+BHolCHGOZ8Dnr1zXy/KgpBOkEUYY9kI/HseHVPeMbluaX3CijJr7D4C5uR8zrc1T64nnq/k63ydQuGt4w== + +"@svgr/babel-plugin-transform-react-native-svg@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-4.2.0.tgz#151487322843359a1ca86b21a3815fd21a88b717" + integrity sha512-7YvynOpZDpCOUoIVlaaOUU87J4Z6RdD6spYN4eUb5tfPoKGSF9OG2NuhgYnq4jSkAxcpMaXWPf1cePkzmqTPNw== + +"@svgr/babel-plugin-transform-svg-component@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-4.2.0.tgz#5f1e2f886b2c85c67e76da42f0f6be1b1767b697" + integrity sha512-hYfYuZhQPCBVotABsXKSCfel2slf/yvJY8heTVX1PCTaq/IgASq1IyxPPKJ0chWREEKewIU/JMSsIGBtK1KKxw== + +"@svgr/babel-preset@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-4.3.3.tgz#a75d8c2f202ac0e5774e6bfc165d028b39a1316c" + integrity sha512-6PG80tdz4eAlYUN3g5GZiUjg2FMcp+Wn6rtnz5WJG9ITGEF1pmFdzq02597Hn0OmnQuCVaBYQE1OVFAnwOl+0A== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "^4.2.0" + "@svgr/babel-plugin-remove-jsx-attribute" "^4.2.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "^4.2.0" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^4.2.0" + "@svgr/babel-plugin-svg-dynamic-title" "^4.3.3" + "@svgr/babel-plugin-svg-em-dimensions" "^4.2.0" + "@svgr/babel-plugin-transform-react-native-svg" "^4.2.0" + "@svgr/babel-plugin-transform-svg-component" "^4.2.0" + +"@svgr/core@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-4.3.3.tgz#b37b89d5b757dc66e8c74156d00c368338d24293" + integrity sha512-qNuGF1QON1626UCaZamWt5yedpgOytvLj5BQZe2j1k1B8DUG4OyugZyfEwBeXozCUwhLEpsrgPrE+eCu4fY17w== + dependencies: + "@svgr/plugin-jsx" "^4.3.3" + camelcase "^5.3.1" + cosmiconfig "^5.2.1" + +"@svgr/hast-util-to-babel-ast@^4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-4.3.2.tgz#1d5a082f7b929ef8f1f578950238f630e14532b8" + integrity sha512-JioXclZGhFIDL3ddn4Kiq8qEqYM2PyDKV0aYno8+IXTLuYt6TOgHUbUAAFvqtb0Xn37NwP0BTHglejFoYr8RZg== + dependencies: + "@babel/types" "^7.4.4" + +"@svgr/plugin-jsx@^4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-4.3.3.tgz#e2ba913dbdfbe85252a34db101abc7ebd50992fa" + integrity sha512-cLOCSpNWQnDB1/v+SUENHH7a0XY09bfuMKdq9+gYvtuwzC2rU4I0wKGFEp1i24holdQdwodCtDQdFtJiTCWc+w== + dependencies: + "@babel/core" "^7.4.5" + "@svgr/babel-preset" "^4.3.3" + "@svgr/hast-util-to-babel-ast" "^4.3.2" + svg-parser "^2.0.0" + +"@svgr/plugin-svgo@^4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-4.3.1.tgz#daac0a3d872e3f55935c6588dd370336865e9e32" + integrity sha512-PrMtEDUWjX3Ea65JsVCwTIXuSqa3CG9px+DluF1/eo9mlDrgrtFE7NE/DjdhjJgSM9wenlVBzkzneSIUgfUI/w== + dependencies: + cosmiconfig "^5.2.1" + merge-deep "^3.0.2" + svgo "^1.2.2" + +"@svgr/webpack@4.3.3": + version "4.3.3" + resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-4.3.3.tgz#13cc2423bf3dff2d494f16b17eb7eacb86895017" + integrity sha512-bjnWolZ6KVsHhgyCoYRFmbd26p8XVbulCzSG53BDQqAr+JOAderYK7CuYrB3bDjHJuF6LJ7Wrr42+goLRV9qIg== + dependencies: + "@babel/core" "^7.4.5" + "@babel/plugin-transform-react-constant-elements" "^7.0.0" + "@babel/preset-env" "^7.4.5" + "@babel/preset-react" "^7.0.0" + "@svgr/core" "^4.3.3" + "@svgr/plugin-jsx" "^4.3.3" + "@svgr/plugin-svgo" "^4.3.1" + loader-utils "^1.2.3" + +"@testing-library/react-hooks@^3.1.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-3.2.1.tgz#19b6caa048ef15faa69d439c469033873ea01294" + integrity sha512-1OB6Ksvlk6BCJA1xpj8/WWz0XVd1qRcgqdaFAq+xeC6l61Ucj0P6QpA5u+Db/x9gU4DCX8ziR5b66Mlfg0M2RA== + dependencies: + "@babel/runtime" "^7.5.4" + "@types/testing-library__react-hooks" "^3.0.0" + +"@types/babel__core@^7.1.0": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.6.tgz#16ff42a5ae203c9af1c6e190ed1f30f83207b610" + integrity sha512-tTnhWszAqvXnhW7m5jQU9PomXSiKXk2sFxpahXvI20SZKu9ylPi8WtIxueZ6ehDWikPT0jeFujMj3X4ZHuf3Tg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.1" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04" + integrity sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" + integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.9.tgz#be82fab304b141c3eee81a4ce3b034d0eba1590a" + integrity sha512-jEFQ8L1tuvPjOI8lnpaf73oCJe+aoxL6ygqSy6c8LcW98zaC+4mzWuQIRCEvKeCOu+lbqdXcg4Uqmm1S8AP1tw== + dependencies: + "@babel/types" "^7.3.0" + +"@types/cheerio@*": + version "0.22.17" + resolved "https://registry.yarnpkg.com/@types/cheerio/-/cheerio-0.22.17.tgz#e54f71c3135f71ebc16c8dc62edad533872c9e72" + integrity sha512-izlm+hbqWN9csuB9GSMfCnAyd3/57XZi3rfz1B0C4QBGVMp+9xQ7+9KYnep+ySfUrCWql4lGzkLf0XmprXcz9g== + dependencies: + "@types/node" "*" + +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/domhandler@*": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@types/domhandler/-/domhandler-2.4.1.tgz#7b3b347f7762180fbcb1ece1ce3dd0ebbb8c64cf" + integrity sha512-cfBw6q6tT5sa1gSPFSRKzF/xxYrrmeiut7E0TxNBObiLSBTuFEHibcfEe3waQPEDbqBsq+ql/TOniw65EyDFMA== + +"@types/domutils@*": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@types/domutils/-/domutils-1.7.2.tgz#89422e579c165994ad5c09ce90325da596cc105d" + integrity sha512-Nnwy1Ztwq42SSNSZSh9EXBJGrOZPR+PQ2sRT4VZy8hnsFXfCil7YlKO2hd2360HyrtFz2qwnKQ13ENrgXNxJbw== + dependencies: + "@types/domhandler" "*" + +"@types/enzyme-adapter-react-16@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.0.6.tgz#8aca7ae2fd6c7137d869b6616e696d21bb8b0cec" + integrity sha512-VonDkZ15jzqDWL8mPFIQnnLtjwebuL9YnDkqeCDYnB4IVgwUm0mwKkqhrxLL6mb05xm7qqa3IE95m8CZE9imCg== + dependencies: + "@types/enzyme" "*" + +"@types/enzyme@*", "@types/enzyme@^3.10.3": + version "3.10.5" + resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.5.tgz#fe7eeba3550369eed20e7fb565bfb74eec44f1f0" + integrity sha512-R+phe509UuUYy9Tk0YlSbipRpfVtIzb/9BHn5pTEtjJTF5LXvUjrIQcZvNyANNEyFrd2YGs196PniNT1fgvOQA== + dependencies: + "@types/cheerio" "*" + "@types/react" "*" + +"@types/eslint-visitor-keys@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" + integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== + +"@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/flot@0.0.31": + version "0.0.31" + resolved "https://registry.yarnpkg.com/@types/flot/-/flot-0.0.31.tgz#0daca37c6c855b69a0a7e2e37dd0f84b3db8c8c1" + integrity sha512-X+RcMQCqPlQo8zPT6cUFTd/PoYBShMQlHUeOXf05jWlfYnvLuRmluB9z+2EsOKFgUzqzZve5brx+gnFxBaHEUw== + dependencies: + "@types/jquery" "*" + +"@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/htmlparser2@*": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@types/htmlparser2/-/htmlparser2-3.10.1.tgz#1e65ba81401d53f425c1e2ba5a3d05c90ab742c7" + integrity sha512-fCxmHS4ryCUCfV9+CJZY1UjkbR+6Al/EQdX5Jh03qBj9gdlPG5q+7uNoDgE/ZNXb3XNWSAQgqKIWnbRCbOyyWA== + dependencies: + "@types/domhandler" "*" + "@types/domutils" "*" + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" + integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a" + integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA== + dependencies: + "@types/istanbul-lib-coverage" "*" + "@types/istanbul-lib-report" "*" + +"@types/jest@^24.0.20": + version "24.9.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.9.1.tgz#02baf9573c78f1b9974a5f36778b366aa77bd534" + integrity sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q== + dependencies: + jest-diff "^24.3.0" + +"@types/jquery@*", "@types/jquery@^3.3.29": + version "3.3.33" + resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.33.tgz#61d9cbd4004ffcdf6cf7e34720a87a5625a7d8e9" + integrity sha512-U6IdXYGkfUI42SR79vB2Spj+h1Ly3J3UZjpd8mi943lh126TK7CB+HZOxGh2nM3IySor7wqVQdemD/xtydsBKA== + dependencies: + "@types/sizzle" "*" + +"@types/json-schema@^7.0.3": + version "7.0.4" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" + integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== + +"@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/moment-timezone@^0.5.10": + version "0.5.12" + resolved "https://registry.yarnpkg.com/@types/moment-timezone/-/moment-timezone-0.5.12.tgz#0fb680c03db194fe8ff4551eaeb1eec8d3d80e9f" + integrity sha512-hnHH2+Efg2vExr/dSz+IX860nSiyk9Sk4pJF2EmS11lRpMcNXeB4KBW5xcgw2QPsb9amTXdsVNEe5IoJXiT0uw== + dependencies: + moment ">=2.14.0" + +"@types/node@*": + version "13.9.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.2.tgz#ace1880c03594cc3e80206d96847157d8e7fa349" + integrity sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg== + +"@types/node@^12.11.1": + version "12.12.30" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.30.tgz#3501e6f09b954de9c404671cefdbcc5d9d7c45f6" + integrity sha512-sz9MF/zk6qVr3pAnM0BSQvYIBK44tS75QC5N+VbWSE4DjCV/pJ+UzCW/F+vVnl7TkOPcuwQureKNtSSwjBTaMg== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@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/reach__router@^1.2.6": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.3.1.tgz#ca8b431acb12bb897d2b806f6fdd815f056d6d02" + integrity sha512-E51ntVeunnxofXmOoPFiOvElHWf+jBEs3B56gGx7XhPHOkJdjWxWDY4V1AsUiwhtOCXPM7atFy30wj7glyv2Fg== + dependencies: + "@types/history" "*" + "@types/react" "*" + +"@types/react-copy-to-clipboard@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@types/react-copy-to-clipboard/-/react-copy-to-clipboard-4.3.0.tgz#8e07becb4f11cfced4bd36038cb5bdf5c2658be5" + integrity sha512-iideNPRyroENqsOFh1i2Dv3zkviYS9r/9qD9Uh3Z9NNoAAqqa2x53i7iGndGNnJFIo20wIu7Hgh77tx1io8bgw== + dependencies: + "@types/react" "*" + +"@types/react-dom@^16.8.0": + 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-resize-detector@^4.0.2": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@types/react-resize-detector/-/react-resize-detector-4.2.0.tgz#ee8802e25cfb34439aa7f52626932ea62dc5792e" + integrity sha512-y5PPThHUrBGxMhLDNn0BRWglKr84y+gQHvzkyKxF8aW3pox4IySC33V8AOu7ReS0JR1X1dKQgWeF8IOkGrbeBg== + dependencies: + "@types/react" "*" + +"@types/react-test-renderer@*": + version "16.9.2" + resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-16.9.2.tgz#e1c408831e8183e5ad748fdece02214a7c2ab6c5" + integrity sha512-4eJr1JFLIAlWhzDkBCkhrOIWOvOxcCAfQh+jiKg7l/nNZcCIL2MHl2dZhogIFKyHzedVWHaVP1Yydq/Ruu4agw== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^16.8.2": + version "16.9.25" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.25.tgz#6ae2159b40138c792058a23c3c04fd3db49e929e" + integrity sha512-Dlj2V72cfYLPNscIG3/SMUOzhzj7GK3bpSrfefwt2YT9GLynvLCCZjbhyF6VsT0q0+aRACRX03TDJGb7cA0cqg== + dependencies: + "@types/prop-types" "*" + csstype "^2.2.0" + +"@types/reactstrap@^8.0.5": + version "8.4.2" + resolved "https://registry.yarnpkg.com/@types/reactstrap/-/reactstrap-8.4.2.tgz#e7066d0e67e2924dab0a52c6aedcf922f2be53b6" + integrity sha512-ag4hfFqBZaeoNSSTKjCtedvdcO68QqqlBrFd3obg94JSmhgNTmHz50BvNJkf9NjSzx1yGTW4l/OyP/khLPKqww== + dependencies: + "@types/react" "*" + popper.js "^1.14.1" + +"@types/sanitize-html@^1.20.2": + version "1.22.0" + resolved "https://registry.yarnpkg.com/@types/sanitize-html/-/sanitize-html-1.22.0.tgz#9bf3a13aeab6e38d130d8ba34bb443956b75bc3d" + integrity sha512-zRtkG+Z9ikdEyIQL6ZouqZIPWnzoioJxgxAUFOc91f+nC8yB4GOMzGpy9V3WYfmkjaVNL4zlsycwHWykFq1HNg== + dependencies: + "@types/htmlparser2" "*" + +"@types/sinon@^7.5.0": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.5.2.tgz#5e2f1d120f07b9cda07e5dedd4f3bf8888fccdb9" + integrity sha512-T+m89VdXj/eidZyejvmoP9jivXgBDdkOSBVQjU9kF349NEx10QdPNGxHeZUaj1IlJ32/ewdyXJjnJxyxJroYwg== + +"@types/sizzle@*": + version "2.3.2" + resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" + integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg== + +"@types/stack-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" + integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== + +"@types/testing-library__react-hooks@^3.0.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/testing-library__react-hooks/-/testing-library__react-hooks-3.2.0.tgz#52f3a109bef06080e3b1e3ae7ea1c014ce859897" + integrity sha512-dE8iMTuR5lzB+MqnxlzORlXzXyCL0EKfzH0w/lau20OpkHD37EaWjZDz0iNG8b71iEtxT4XKGmSKAGVEqk46mw== + dependencies: + "@types/react" "*" + "@types/react-test-renderer" "*" + +"@types/yargs-parser@*": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" + integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== + +"@types/yargs@^13.0.0": + version "13.0.8" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.8.tgz#a38c22def2f1c2068f8971acb3ea734eb3c64a99" + integrity sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA== + dependencies: + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@2.x", "@typescript-eslint/eslint-plugin@^2.10.0": + version "2.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.24.0.tgz#a86cf618c965a462cddf3601f594544b134d6d68" + integrity sha512-wJRBeaMeT7RLQ27UQkDFOu25MqFOBus8PtOa9KaT5ZuxC1kAsd7JEHqWt4YXuY9eancX0GK9C68i5OROnlIzBA== + dependencies: + "@typescript-eslint/experimental-utils" "2.24.0" + eslint-utils "^1.4.3" + functional-red-black-tree "^1.0.1" + regexpp "^3.0.0" + tsutils "^3.17.1" + +"@typescript-eslint/experimental-utils@2.24.0": + version "2.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.24.0.tgz#a5cb2ed89fedf8b59638dc83484eb0c8c35e1143" + integrity sha512-DXrwuXTdVh3ycNCMYmWhUzn/gfqu9N0VzNnahjiDJvcyhfBy4gb59ncVZVxdp5XzBC77dCncu0daQgOkbvPwBw== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/typescript-estree" "2.24.0" + eslint-scope "^5.0.0" + +"@typescript-eslint/parser@2.x", "@typescript-eslint/parser@^2.10.0": + version "2.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.24.0.tgz#2cf0eae6e6dd44d162486ad949c126b887f11eb8" + integrity sha512-H2Y7uacwSSg8IbVxdYExSI3T7uM1DzmOn2COGtCahCC3g8YtM1xYAPi2MAHyfPs61VKxP/J/UiSctcRgw4G8aw== + dependencies: + "@types/eslint-visitor-keys" "^1.0.0" + "@typescript-eslint/experimental-utils" "2.24.0" + "@typescript-eslint/typescript-estree" "2.24.0" + eslint-visitor-keys "^1.1.0" + +"@typescript-eslint/typescript-estree@2.24.0": + version "2.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.24.0.tgz#38bbc8bb479790d2f324797ffbcdb346d897c62a" + integrity sha512-RJ0yMe5owMSix55qX7Mi9V6z2FDuuDpN6eR5fzRJrp+8in9UF41IGNQHbg5aMK4/PjVaEQksLvz0IA8n+Mr/FA== + dependencies: + debug "^4.1.1" + eslint-visitor-keys "^1.1.0" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^6.3.0" + tsutils "^3.17.1" + +"@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== + +abab@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" + integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== + +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-globals@^4.1.0, acorn-globals@^4.3.0, acorn-globals@^4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" + integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + +acorn-jsx@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" + integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== + +acorn-walk@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" + integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== + +acorn@^5.5.3: + version "5.7.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" + integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== + +acorn@^6.0.1, acorn@^6.0.4, acorn@^6.2.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + +acorn@^7.1.0, acorn@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" + integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== + +address@1.1.2, address@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + +adjust-sourcemap-loader@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz#6471143af75ec02334b219f54bc7970c52fb29a4" + integrity sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA== + dependencies: + assert "1.4.1" + camelcase "5.0.0" + loader-utils "1.2.3" + object-path "0.11.4" + regex-parser "2.2.10" + +aggregate-error@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" + integrity sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +airbnb-prop-types@^2.15.0: + version "2.15.0" + resolved "https://registry.yarnpkg.com/airbnb-prop-types/-/airbnb-prop-types-2.15.0.tgz#5287820043af1eb469f5b0af0d6f70da6c52aaef" + integrity sha512-jUh2/hfKsRjNFC4XONQrxo/n/3GG4Tn6Hl0WlFQN5PY9OMC9loSCoAYKnZsWaP8wEfd5xcrPloK0Zg6iS1xwVA== + dependencies: + array.prototype.find "^2.1.0" + function.prototype.name "^1.1.1" + has "^1.0.3" + is-regex "^1.0.4" + object-is "^1.0.1" + object.assign "^4.1.0" + object.entries "^1.1.0" + prop-types "^15.7.2" + prop-types-exact "^1.2.0" + react-is "^16.9.0" + +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.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.0: + 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-escapes@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-escapes@^4.2.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" + integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + dependencies: + type-fest "^0.11.0" + +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.0.0, 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-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +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" + +ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +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.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +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" + +aria-query@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc" + integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w= + dependencies: + ast-types-flow "0.0.7" + commander "^2.11.0" + +arity-n@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/arity-n/-/arity-n-1.0.4.tgz#d9e76b11733e08569c0847ae7b39b2860b30b745" + integrity sha1-2edrEXM+CFacCEeuezmyhgswt0U= + +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-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + +array-filter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" + integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= + +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-from@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" + integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU= + +array-includes@^3.0.3, array-includes@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" + integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0" + is-string "^1.0.5" + +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= + +array.prototype.find@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.1.1.tgz#3baca26108ca7affb08db06bf0be6cb3115a969c" + integrity sha512-mi+MYNJYLTx2eNYy+Yh6raoQacCsNeeMUaspFPh9Y141lFSsWxxB8V9mM2ye+eqiRs917J6/pJ4M9ZPzenWckA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.4" + +array.prototype.flat@^1.2.1, array.prototype.flat@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" + integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asap@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +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.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + dependencies: + util "0.10.3" + +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= + +ast-types-flow@0.0.7, ast-types-flow@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +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== + +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== + +axobject-query@^2.0.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799" + integrity sha512-ICt34ZmrVt8UQnvPl6TVyDTkmhXmAyAT4Jh5ugfGUX4MOrZ+U/ZY6/sdylRw3qGNr9Ub5AJsaHeDMzNLehRdOQ== + +babel-code-frame@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-eslint@10.1.0, babel-eslint@10.x: + version "10.1.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" + integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" + +babel-extract-comments@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz#0a2aedf81417ed391b85e18b4614e693a0351a21" + integrity sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ== + dependencies: + babylon "^6.18.0" + +babel-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" + integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== + dependencies: + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/babel__core" "^7.1.0" + babel-plugin-istanbul "^5.1.0" + babel-preset-jest "^24.9.0" + chalk "^2.4.2" + slash "^2.0.0" + +babel-loader@8.1.0: + 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" + +babel-plugin-dynamic-import-node@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" + integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-istanbul@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" + integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + find-up "^3.0.0" + istanbul-lib-instrument "^3.3.0" + test-exclude "^5.2.3" + +babel-plugin-jest-hoist@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" + integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== + dependencies: + "@types/babel__traverse" "^7.0.6" + +babel-plugin-macros@2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" + integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== + dependencies: + "@babel/runtime" "^7.7.2" + cosmiconfig "^6.0.0" + resolve "^1.12.0" + +babel-plugin-named-asset-import@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz#c9750a1b38d85112c9e166bf3ef7c5dbc605f4be" + integrity sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA== + +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= + +babel-plugin-transform-object-rest-spread@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + integrity sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-react-remove-prop-types@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" + integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== + +babel-preset-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" + integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== + dependencies: + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + babel-plugin-jest-hoist "^24.9.0" + +babel-preset-react-app@^9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-9.1.2.tgz#54775d976588a8a6d1a99201a702befecaf48030" + integrity sha512-k58RtQOKH21NyKtzptoAvtAODuAJJs3ZhqBMl456/GnXEQ/0La92pNmwgWoMn5pBTrsvk3YYXdY7zpY4e3UIxA== + dependencies: + "@babel/core" "7.9.0" + "@babel/plugin-proposal-class-properties" "7.8.3" + "@babel/plugin-proposal-decorators" "7.8.3" + "@babel/plugin-proposal-nullish-coalescing-operator" "7.8.3" + "@babel/plugin-proposal-numeric-separator" "7.8.3" + "@babel/plugin-proposal-optional-chaining" "7.9.0" + "@babel/plugin-transform-flow-strip-types" "7.9.0" + "@babel/plugin-transform-react-display-name" "7.8.3" + "@babel/plugin-transform-runtime" "7.9.0" + "@babel/preset-env" "7.9.0" + "@babel/preset-react" "7.9.1" + "@babel/preset-typescript" "7.9.0" + "@babel/runtime" "7.9.0" + babel-plugin-macros "2.8.0" + babel-plugin-transform-react-remove-prop-types "0.4.24" + +babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +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" + +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.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.1.2, bootstrap@^4.2.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.4.1.tgz#8582960eea0c5cd2bede84d8b0baf3789c3e8b01" + integrity sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA== + +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.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= + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +browser-resolve@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== + dependencies: + resolve "1.1.7" + +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@4.10.0, browserslist@^4.0.0, browserslist@^4.6.2, browserslist@^4.6.4, browserslist@^4.8.3, browserslist@^4.9.1: + version "4.10.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.10.0.tgz#f179737913eaf0d2b98e4926ac1ca6a15cbcc6a9" + integrity sha512-TpfK0TDgv71dzuTsEAlQiHeWQ/tiPqgNZVdv046fvNtBZrjbv2O3TsWCDU0AWGJJKCF/KsjNdLzR9hXOsh/CfA== + dependencies: + caniuse-lite "^1.0.30001035" + electron-to-chromium "^1.3.378" + node-releases "^1.1.52" + pkg-up "^3.1.0" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +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.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" + +cacache@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-13.0.1.tgz#a8000c21697089082f85287a1aec6e382024a71c" + integrity sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w== + dependencies: + chownr "^1.1.2" + figgy-pudding "^3.5.1" + fs-minipass "^2.0.0" + glob "^7.1.4" + graceful-fs "^4.2.2" + infer-owner "^1.0.4" + lru-cache "^5.1.1" + minipass "^3.0.0" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + p-map "^3.0.0" + promise-inflight "^1.0.1" + rimraf "^2.7.1" + ssri "^7.0.0" + unique-filename "^1.1.1" + +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" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +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= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +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@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" + integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + +camelcase@5.3.1, 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== + +caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001035: + version "1.0.30001035" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz#2bb53b8aa4716b2ed08e088d4dc816a5fe089a1e" + integrity sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ== + +capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== + dependencies: + rsvp "^4.8.4" + +case-sensitive-paths-webpack-plugin@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz#23ac613cc9a856e4f88ff8bb73bbb5e989825cf7" + integrity sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ== + +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.1.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" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +cheerio@^1.0.0-rc.3: + version "1.0.0-rc.3" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6" + integrity sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA== + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.1" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash "^4.15.0" + parse5 "^3.0.1" + +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" + +chokidar@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" + integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== + 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.3.0" + optionalDependencies: + fsevents "~2.1.2" + +chownr@^1.1.1, chownr@^1.1.2: + 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" + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +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" + +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.3: + 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" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +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-deep@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.2.4.tgz#4e73dd09e9fb971cc38670c5dced9c1896481cc6" + integrity sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY= + dependencies: + for-own "^0.1.3" + is-plain-object "^2.0.1" + kind-of "^3.0.2" + lazy-cache "^1.0.3" + shallow-clone "^0.1.2" + +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= + +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" + +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, color-convert@^1.9.1: + 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-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +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, color-name@~1.1.4: + 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@^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@^3.0.0: + 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" + +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.11.0, 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@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +common-tags@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" + integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw== + +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== + +compose-function@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/compose-function/-/compose-function-3.0.3.tgz#9ed675f13cc54501d30950a486ff6a7ba3ab185f" + integrity sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8= + dependencies: + arity-n "^1.0.4" + +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" + +compute-scroll-into-view@^1.0.9: + version "1.0.13" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.13.tgz#be1b1663b0e3f56cd5f7713082549f562a3477e2" + integrity sha512-o+w9w7A98aAFi/GjK8cxSV+CdASuPa2rR5UWs3+yHkJzWqaKoBEufFNWYaXInCSmUfDCVhesG+v9MTWqOjsxFg== + +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" + +confusing-browser-globals@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd" + integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw== + +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== + +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= + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +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, convert-source-map@^1.4.0, 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" + +convert-source-map@^0.3.3: + version "0.3.5" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190" + integrity sha1-8dgClQr33SYxof6+BZZVDIarMZA= + +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= + +copy-to-clipboard@^3: + version "3.3.1" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae" + integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw== + dependencies: + toggle-selection "^1.0.6" + +core-js-compat@^3.6.2: + version "3.6.4" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.4.tgz#938476569ebb6cda80d339bcf199fae4f16fff17" + integrity sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA== + dependencies: + browserslist "^4.8.3" + semver "7.0.0" + +core-js-pure@^3.0.0: + version "3.6.4" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a" + integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw== + +core-js@^2.4.0: + version "2.6.11" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" + integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== + +core-js@^3.5.0: + 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, cosmiconfig@^5.2.1: + 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" + +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + +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" + +create-react-context@0.3.0, create-react-context@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/create-react-context/-/create-react-context-0.3.0.tgz#546dede9dc422def0d3fc2fe03afe0bc0f4f7d8c" + integrity sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw== + dependencies: + gud "^1.0.0" + warning "^4.0.3" + +cross-fetch@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.3.tgz#e8a0b3c54598136e037f8650f8e823ccdfac198e" + integrity sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw== + dependencies: + node-fetch "2.1.2" + whatwg-fetch "2.0.4" + +cross-spawn@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" + integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +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-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, 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-declaration-sorter@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz#c198940f63a76d7e36c1e71018b001721054cb22" + integrity sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA== + dependencies: + postcss "^7.0.1" + timsort "^0.3.0" + +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@3.4.2: + version "3.4.2" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.4.2.tgz#d3fdb3358b43f233b78501c5ed7b1c6da6133202" + integrity sha512-jYq4zdZT0oS0Iykt+fqnzVLRIeiPWhka+7BqPn+oSIpWJAHak5tmB/WZrJ2a21JhCeFyNnnlroSl8c+MtVndzA== + 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.23" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.1.1" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.0.2" + schema-utils "^2.6.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, css-select@~1.2.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== + +css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= + +css@^2.0.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + +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-preset-default@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" + integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== + dependencies: + css-declaration-sorter "^4.0.1" + cssnano-util-raw-cache "^4.0.1" + postcss "^7.0.0" + postcss-calc "^7.0.1" + postcss-colormin "^4.0.3" + postcss-convert-values "^4.0.1" + postcss-discard-comments "^4.0.2" + postcss-discard-duplicates "^4.0.2" + postcss-discard-empty "^4.0.1" + postcss-discard-overridden "^4.0.1" + postcss-merge-longhand "^4.0.11" + postcss-merge-rules "^4.0.3" + postcss-minify-font-values "^4.0.2" + postcss-minify-gradients "^4.0.2" + postcss-minify-params "^4.0.2" + postcss-minify-selectors "^4.0.2" + postcss-normalize-charset "^4.0.1" + postcss-normalize-display-values "^4.0.2" + postcss-normalize-positions "^4.0.2" + postcss-normalize-repeat-style "^4.0.2" + postcss-normalize-string "^4.0.2" + postcss-normalize-timing-functions "^4.0.2" + postcss-normalize-unicode "^4.0.1" + postcss-normalize-url "^4.0.1" + postcss-normalize-whitespace "^4.0.2" + postcss-ordered-values "^4.1.2" + postcss-reduce-initial "^4.0.3" + postcss-reduce-transforms "^4.0.2" + postcss-svgo "^4.0.2" + postcss-unique-selectors "^4.0.1" + +cssnano-util-get-arguments@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz#ed3a08299f21d75741b20f3b81f194ed49cc150f" + integrity sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8= + +cssnano-util-get-match@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz#c0e4ca07f5386bb17ec5e52250b4f5961365156d" + integrity sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0= + +cssnano-util-raw-cache@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz#b26d5fd5f72a11dfe7a7846fb4c67260f96bf282" + integrity sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA== + dependencies: + postcss "^7.0.0" + +cssnano-util-same-parent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz#574082fb2859d2db433855835d9a8456ea18bbf3" + integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== + +cssnano@^4.1.10: + version "4.1.10" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" + integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== + dependencies: + cosmiconfig "^5.0.0" + cssnano-preset-default "^4.0.7" + is-resolvable "^1.0.0" + postcss "^7.0.0" + +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" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@^0.3.4, cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssom@^0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + +cssstyle@^1.0.0, cssstyle@^1.1.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" + integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== + dependencies: + cssom "0.3.x" + +cssstyle@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.2.0.tgz#e4c44debccd6b7911ed617a4395e5754bba59992" + integrity sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA== + dependencies: + cssom "~0.3.6" + +csstype@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" + integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== + +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" + +damerau-levenshtein@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz#143c1641cb3d85c60c32329e26899adea8701791" + integrity sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug== + +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" + +data-urls@^1.0.0, data-urls@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: + 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.0.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.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, deep-equal@^1.1.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= + +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-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= + +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== + +detect-port-alt@1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" + integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +diff-sequences@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" + integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== + +diff@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +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" + +dir-glob@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +discontinuous-range@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" + integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo= + +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.5.0: + 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" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +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@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" + +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-serializer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + dependencies: + domelementtype "^1.3.0" + entities "^1.1.1" + +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.0, 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== + +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + +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, 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" + +domutils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.0.0.tgz#15b8278e37bfa8468d157478c58c367718133c08" + integrity sha512-n5SelJ1axbO636c2yUtOGia/IcJtVtlhQbFiVDBZHKV5ReJO1ViX7sFEemtuyoAnBxk5meNSYgA8V4s0271efg== + 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" + +dot-prop@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" + integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A== + dependencies: + is-obj "^2.0.0" + +dotenv-expand@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv@8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + +downshift@^3.2.2: + version "3.4.8" + resolved "https://registry.yarnpkg.com/downshift/-/downshift-3.4.8.tgz#06b7ad9e9c423a58e8a9049b2a00a5d19c7ef954" + integrity sha512-dZL3iNL/LbpHNzUQAaVq/eTD1ocnGKKjbAl/848Q0KEp6t81LJbS37w3f93oD6gqqAnjdgM7Use36qZSipHXBw== + dependencies: + "@babel/runtime" "^7.4.5" + compute-scroll-into-view "^1.0.9" + prop-types "^15.7.2" + react-is "^16.9.0" + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +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.3.378: + version "1.3.380" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.380.tgz#1e1f07091b42b54bccd0ad6d3a14f2b73b60dc9d" + integrity sha512-2jhQxJKcjcSpVOQm0NAfuLq8o+130blrcawoumdXT6411xG/xIAOyZodO/y7WTaYlz/NHe3sCCAe/cJLnDsqTw== + +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, emoji-regex@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +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: + 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.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, 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== + +enzyme-adapter-react-16@^1.15.1: + version "1.15.2" + resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.2.tgz#b16db2f0ea424d58a808f9df86ab6212895a4501" + integrity sha512-SkvDrb8xU3lSxID8Qic9rB8pvevDbLybxPK6D/vW7PrT0s2Cl/zJYuXvsd1EBTz0q4o3iqG3FJhpYz3nUNpM2Q== + dependencies: + enzyme-adapter-utils "^1.13.0" + enzyme-shallow-equal "^1.0.1" + has "^1.0.3" + object.assign "^4.1.0" + object.values "^1.1.1" + prop-types "^15.7.2" + react-is "^16.12.0" + react-test-renderer "^16.0.0-0" + semver "^5.7.0" + +enzyme-adapter-utils@^1.13.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.13.0.tgz#01c885dde2114b4690bf741f8dc94cee3060eb78" + integrity sha512-YuEtfQp76Lj5TG1NvtP2eGJnFKogk/zT70fyYHXK2j3v6CtuHqc8YmgH/vaiBfL8K1SgVVbQXtTcgQZFwzTVyQ== + dependencies: + airbnb-prop-types "^2.15.0" + function.prototype.name "^1.1.2" + object.assign "^4.1.0" + object.fromentries "^2.0.2" + prop-types "^15.7.2" + semver "^5.7.1" + +enzyme-shallow-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.1.tgz#7afe03db3801c9b76de8440694096412a8d9d49e" + integrity sha512-hGA3i1so8OrYOZSM9whlkNmVHOicJpsjgTzC+wn2JMJXhq1oO4kA4bJ5MsfzSIcC71aLDKzJ6gZpIxrqt3QTAQ== + dependencies: + has "^1.0.3" + object-is "^1.0.2" + +enzyme-to-json@^3.4.3: + version "3.4.4" + resolved "https://registry.yarnpkg.com/enzyme-to-json/-/enzyme-to-json-3.4.4.tgz#b30726c59091d273521b6568c859e8831e94d00e" + integrity sha512-50LELP/SCPJJGic5rAARvU7pgE3m1YaNj7JLM+Qkhl5t7PAs6fiyc8xzc50RnkKPFQCv0EeFVjEWdIFRGPWMsA== + dependencies: + lodash "^4.17.15" + react-is "^16.12.0" + +enzyme@^3.10.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.11.0.tgz#71d680c580fe9349f6f5ac6c775bc3e6b7a79c28" + integrity sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw== + dependencies: + array.prototype.flat "^1.2.3" + cheerio "^1.0.0-rc.3" + enzyme-shallow-equal "^1.0.1" + function.prototype.name "^1.1.2" + has "^1.0.3" + html-element-map "^1.2.0" + is-boolean-object "^1.0.1" + is-callable "^1.1.5" + is-number-object "^1.0.4" + is-regex "^1.0.5" + is-string "^1.0.5" + is-subset "^0.1.1" + lodash.escape "^4.0.1" + lodash.isequal "^4.5.0" + object-inspect "^1.7.0" + object-is "^1.0.2" + object.assign "^4.1.0" + object.entries "^1.1.1" + object.values "^1.1.1" + raf "^3.4.1" + rst-selector-parser "^2.2.3" + string.prototype.trim "^1.2.1" + +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, 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, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4: + 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" + +es5-ext@^0.10.35, es5-ext@^0.10.50: + 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.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-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" + +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@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +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= + +escodegen@^1.11.0, escodegen@^1.11.1, escodegen@^1.9.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457" + integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-config-prettier@^6.4.0: + version "6.10.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.10.0.tgz#7b15e303bf9c956875c948f6b21500e48ded6a7f" + integrity sha512-AtndijGte1rPILInUdHjvKEGbIV06NuvPrqlIEaEaWtbtvJh464mDeyGMdZEQMsGvC0ZVkiex1fSNcC4HAbRGg== + dependencies: + get-stdin "^6.0.0" + +eslint-config-react-app@^5.0.2, eslint-config-react-app@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-5.2.1.tgz#698bf7aeee27f0cea0139eaef261c7bf7dd623df" + integrity sha512-pGIZ8t0mFLcV+6ZirRgYK6RVqUIKRIi9MmgzUEmrIknsn3AdO0I32asO86dJgloHq+9ZPl8UIg8mYrvgP5u2wQ== + dependencies: + confusing-browser-globals "^1.0.9" + +eslint-import-resolver-node@^0.3.2: + version "0.3.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404" + integrity sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg== + dependencies: + debug "^2.6.9" + resolve "^1.13.1" + +eslint-loader@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-3.0.3.tgz#e018e3d2722381d982b1201adb56819c73b480ca" + integrity sha512-+YRqB95PnNvxNp1HEjQmvf9KNvCin5HXYYseOXVC2U0KEcw4IkQ2IQEBG46j7+gW39bMzeu0GsUhVbBY3Votpw== + dependencies: + fs-extra "^8.1.0" + loader-fs-cache "^1.0.2" + loader-utils "^1.2.3" + object-hash "^2.0.1" + schema-utils "^2.6.1" + +eslint-module-utils@^2.4.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz#7878f7504824e1b857dd2505b59a8e5eda26a708" + integrity sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q== + dependencies: + debug "^2.6.9" + pkg-dir "^2.0.0" + +eslint-plugin-flowtype@3.x: + version "3.13.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-3.13.0.tgz#e241ebd39c0ce519345a3f074ec1ebde4cf80f2c" + integrity sha512-bhewp36P+t7cEV0b6OdmoRWJCBYRiHFlqPZAG1oS3SF+Y0LQkeDvFSM4oxoxvczD1OdONCXMlJfQFiWLcV9urw== + dependencies: + lodash "^4.17.15" + +eslint-plugin-flowtype@4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.6.0.tgz#82b2bd6f21770e0e5deede0228e456cb35308451" + integrity sha512-W5hLjpFfZyZsXfo5anlu7HM970JBDqbEshAJUkeczP6BFCIfJXuiIBQXyberLRtOStT0OGPF8efeTbxlHk4LpQ== + dependencies: + lodash "^4.17.15" + +eslint-plugin-import@2.20.1, eslint-plugin-import@2.x: + version "2.20.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz#802423196dcb11d9ce8435a5fc02a6d3b46939b3" + integrity sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw== + dependencies: + array-includes "^3.0.3" + array.prototype.flat "^1.2.1" + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.4.1" + has "^1.0.3" + minimatch "^3.0.4" + object.values "^1.1.0" + read-pkg-up "^2.0.0" + resolve "^1.12.0" + +eslint-plugin-jsx-a11y@6.2.3, eslint-plugin-jsx-a11y@6.x: + version "6.2.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz#b872a09d5de51af70a97db1eea7dc933043708aa" + integrity sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg== + dependencies: + "@babel/runtime" "^7.4.5" + aria-query "^3.0.0" + array-includes "^3.0.3" + ast-types-flow "^0.0.7" + axobject-query "^2.0.2" + damerau-levenshtein "^1.0.4" + emoji-regex "^7.0.2" + has "^1.0.3" + jsx-ast-utils "^2.2.1" + +eslint-plugin-prettier@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.2.tgz#432e5a667666ab84ce72f945c72f77d996a5c9ba" + integrity sha512-GlolCC9y3XZfv3RQfwGew7NnuFDKsfI4lbvRK+PIIo23SFH+LemGs4cKwzAaRa+Mdb+lQO/STaIayno8T5sJJA== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-plugin-react-hooks@1.x, eslint-plugin-react-hooks@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" + integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== + +eslint-plugin-react@7.19.0, eslint-plugin-react@7.x: + version "7.19.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.19.0.tgz#6d08f9673628aa69c5559d33489e855d83551666" + integrity sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ== + dependencies: + array-includes "^3.1.1" + doctrine "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.2.3" + object.entries "^1.1.1" + object.fromentries "^2.0.2" + object.values "^1.1.1" + prop-types "^15.7.2" + resolve "^1.15.1" + semver "^6.3.0" + string.prototype.matchall "^4.0.2" + xregexp "^4.3.0" + +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-scope@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" + integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@6.x, eslint@^6.6.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" + integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.10.0" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^5.0.0" + eslint-utils "^1.4.3" + eslint-visitor-keys "^1.1.0" + espree "^6.1.2" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^7.0.0" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.3" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^6.1.2: + version "6.2.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" + integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== + dependencies: + acorn "^7.1.1" + acorn-jsx "^5.2.0" + eslint-visitor-keys "^1.1.0" + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.1.0.tgz#c5c0b66f383e7656404f86b31334d72524eddb48" + integrity sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q== + dependencies: + estraverse "^4.0.0" + +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.0.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= + +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" + +exec-sh@^0.3.2: + version "0.3.4" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" + integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== + +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@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +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" + +expect@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" + integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== + dependencies: + "@jest/types" "^24.9.0" + ansi-styles "^3.2.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.9.0" + +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== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +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-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^2.0.2: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +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= + +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" + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.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== + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-loader@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-4.3.0.tgz#780f040f729b3d18019f20605f723e844b8a58af" + integrity sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA== + dependencies: + loader-utils "^1.2.3" + schema-utils "^2.5.0" + +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== + +filesize@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.0.1.tgz#f850b509909c7c86f7e450ea19006c31c2ed3d2f" + integrity sha512-u4AYWPgbI5GBhs6id1KdImZWn5yfyFrrQ8OWZdN7ZMfA8Bf4HcO0BGo9bmUIEV8yrp8I1xVfJ/dn90GtFNNJcg== + +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@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + integrity sha1-yN765XyKUqinhPnjHFfHQumToLk= + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^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-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-up@4.1.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" + +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@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^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" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" + integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== + +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@^0.1.3: + version "0.1.8" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" + integrity sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE= + +for-in@^1.0.1, 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= + +for-own@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +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= + +fork-ts-checker-webpack-plugin@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz#a1642c0d3e65f50c2cc1742e9c0a80f441f86b19" + integrity sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ== + dependencies: + babel-code-frame "^6.22.0" + chalk "^2.4.1" + chokidar "^3.3.0" + micromatch "^3.1.10" + minimatch "^3.0.4" + semver "^5.6.0" + tapable "^1.0.0" + worker-rpc "^0.1.0" + +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-extra@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +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@2.1.2, fsevents@~2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" + integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== + +fsevents@^1.2.7: + version "1.2.12" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.12.tgz#db7e0d8ec3b0b45724fd4d83d43554a8f1f0de5c" + integrity sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q== + 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== + +function.prototype.name@^1.1.1, function.prototype.name@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.2.tgz#5cdf79d7c05db401591dfde83e3b70c5123e9a45" + integrity sha512-C8A+LlHBJjB2AdcRPorc5JvJ5VUoWlXdEHLOJdCI7kjHEtGTpHQUiqMvCIKUwIsGwZX2jZJy761AXsn356bJQg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + functions-have-names "^1.2.0" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +functions-have-names@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.1.tgz#a981ac397fa0c9964551402cdc5533d7a4d52f91" + integrity sha512-j48B/ZI7VKs3sgeI2cZp7WXWmZXu7Iq5pl5/vptV5N2mq+DGFuS/ulaDjtaoLpYzuD6u8UgrUKHfgo7fDTSiBA== + +fuzzy@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/fuzzy/-/fuzzy-0.1.3.tgz#4c76ec2ff0ac1a36a9dccf9a00df8623078d4ed8" + integrity sha1-THbsL/CsGjap3M+aAN+GIweNTtg= + +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-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + +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" + +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.0.0, glob-parent@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" + integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + 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-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" + +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@^12.1.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== + dependencies: + type-fest "^0.8.1" + +globby@8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" + integrity sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w== + dependencies: + array-union "^1.0.1" + dir-glob "2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +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, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.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== + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + +gud@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" + integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== + +gzip-size@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" + integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== + dependencies: + duplexer "^0.1.1" + pify "^4.0.1" + +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" + +harmony-reflect@^1.4.6: + version "1.6.1" + resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.1.tgz#c108d4f2bb451efef7a37861fdbdae72c9bdefa9" + integrity sha512-WJTeyp0JzGtHcuMsi7rw2VwtkvLa+JyfEKJCFyfcS0+CDkjQ5lHPu7zEhFZP+PDSRrEgXa5Ah0l1MbgbE41XjA== + +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-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +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-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.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.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.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hex-color-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" + integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== + +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" + +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" + +hsl-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" + integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= + +hsla-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" + integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= + +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-element-map@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/html-element-map/-/html-element-map-1.2.0.tgz#dfbb09efe882806af63d990cf6db37993f099f22" + integrity sha512-0uXq8HsuG1v2TmQ8QkIhzbrqeskE4kn52Q18QJ9iAA/SnHoEKXWiUxHQtclRsCFWEUD2So34X+0+pZZu862nnw== + dependencies: + array-filter "^1.0.0" + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + +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-escaper@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.1.tgz#beed86b5d2b921e92533aa11bce6d8e3b583dee7" + integrity sha512-hNX23TjWwD3q56HpWjUHOKj1+4KKlnjv9PcmBUYKVpga+2cnb9nDx/B1o0yO4n+RZXZdiNxzx6B24C9aNMTkkQ== + +html-minifier-terser@^5.0.1: + version "5.0.4" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.0.4.tgz#e8cc02748acb983bd7912ea9660bd31c0702ec32" + integrity sha512-fHwmKQ+GzhlqdxEtwrqLT7MSuheiA+rif5/dZgbz3GjoMXJzcRzy1L9NXoiiyxrnap+q5guSiv8Tz5lrh9g42g== + 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.0.0-beta.11: + version "4.0.0-beta.11" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz#3059a69144b5aecef97708196ca32f9e68677715" + integrity sha512-4Xzepf0qWxf8CGg7/WQM5qBB2Lc/NFI7MhU59eUDTkuQp3skZczH4UA1d6oQyDEIoMDgERVhRyTdtUPZ5s5HBg== + dependencies: + 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, htmlparser2@^3.9.1: + 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.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= + +i@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d" + integrity sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0= + +iconv-lite@0.4.24, 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" + +identity-obj-proxy@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14" + integrity sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ= + dependencies: + harmony-reflect "^1.4.6" + +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.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +immer@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d" + integrity sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg== + +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-fresh@^3.0.0, import-fresh@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.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: + 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= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +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, infer-owner@^1.0.4: + 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.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703" + integrity sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ== + dependencies: + ansi-escapes "^4.2.1" + chalk "^2.4.2" + cli-cursor "^3.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" + run-async "^2.2.0" + rxjs "^6.5.3" + string-width "^4.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +inquirer@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.1.0.tgz#1298a01859883e17c7264b82870ae1034f92dd29" + integrity sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^3.0.0" + cli-cursor "^3.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.5.3" + string-width "^4.1.0" + strip-ansi "^6.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" + +internal-slot@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.2.tgz#9c2e9fb3cd8e5e4256c6f45fe310067fcfa378a3" + integrity sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g== + dependencies: + es-abstract "^1.17.0-next.1" + has "^1.0.3" + side-channel "^1.0.2" + +invariant@^2.2.2, invariant@^2.2.3, 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@^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-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-boolean-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e" + integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ== + +is-buffer@^1.0.2, 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-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-color-stop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" + integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= + dependencies: + css-color-names "^0.0.4" + hex-color-regex "^1.1.0" + hsl-regex "^1.0.0" + hsla-regex "^1.0.0" + rgb-regex "^1.0.1" + rgba-regex "^1.0.0" + +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-docker@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b" + integrity sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ== + +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-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +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-number-object@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" + integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== + +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-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +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.1, 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-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +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-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + +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-root@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" + integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== + +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-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + +is-subset@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" + integrity sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY= + +is-svg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" + integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== + 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.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= + +is-wsl@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d" + integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog== + +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= + +istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" + integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== + +istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" + integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== + dependencies: + "@babel/generator" "^7.4.0" + "@babel/parser" "^7.4.3" + "@babel/template" "^7.4.0" + "@babel/traverse" "^7.4.3" + "@babel/types" "^7.4.0" + istanbul-lib-coverage "^2.0.5" + semver "^6.0.0" + +istanbul-lib-report@^2.0.4: + version "2.0.8" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" + integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== + dependencies: + istanbul-lib-coverage "^2.0.5" + make-dir "^2.1.0" + supports-color "^6.1.0" + +istanbul-lib-source-maps@^3.0.1: + version "3.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" + integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^2.0.5" + make-dir "^2.1.0" + rimraf "^2.6.3" + source-map "^0.6.1" + +istanbul-reports@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.7.tgz#5d939f6237d7b48393cc0959eab40cd4fd056931" + integrity sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg== + dependencies: + html-escaper "^2.0.0" + +jest-changed-files@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" + integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== + dependencies: + "@jest/types" "^24.9.0" + execa "^1.0.0" + throat "^4.0.0" + +jest-cli@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" + integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== + dependencies: + "@jest/core" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + exit "^0.1.2" + import-local "^2.0.0" + is-ci "^2.0.0" + jest-config "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + prompts "^2.0.1" + realpath-native "^1.1.0" + yargs "^13.3.0" + +jest-config@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" + integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/test-sequencer" "^24.9.0" + "@jest/types" "^24.9.0" + babel-jest "^24.9.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^24.9.0" + jest-environment-node "^24.9.0" + jest-get-type "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + micromatch "^3.1.10" + pretty-format "^24.9.0" + realpath-native "^1.1.0" + +jest-diff@^24.3.0, jest-diff@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" + integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== + dependencies: + chalk "^2.0.1" + diff-sequences "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-docblock@^24.3.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" + integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== + dependencies: + detect-newline "^2.1.0" + +jest-each@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" + integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== + dependencies: + "@jest/types" "^24.9.0" + chalk "^2.0.1" + jest-get-type "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + +jest-environment-jsdom-fourteen@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-1.0.1.tgz#4cd0042f58b4ab666950d96532ecb2fc188f96fb" + integrity sha512-DojMX1sY+at5Ep+O9yME34CdidZnO3/zfPh8UW+918C5fIZET5vCjfkegixmsi7AtdYfkr4bPlIzmWnlvQkP7Q== + dependencies: + "@jest/environment" "^24.3.0" + "@jest/fake-timers" "^24.3.0" + "@jest/types" "^24.3.0" + jest-mock "^24.0.0" + jest-util "^24.0.0" + jsdom "^14.1.0" + +jest-environment-jsdom@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" + integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" + jsdom "^11.5.1" + +jest-environment-node@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" + integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" + +jest-fetch-mock@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/jest-fetch-mock/-/jest-fetch-mock-2.1.2.tgz#1260b347918e3931c4ec743ceaf60433da661bd0" + integrity sha512-tcSR4Lh2bWLe1+0w/IwvNxeDocMI/6yIA2bijZ0fyWxC4kQ18lckQ1n7Yd40NKuisGmcGBRFPandRXrW/ti/Bw== + dependencies: + cross-fetch "^2.2.2" + promise-polyfill "^7.1.1" + +jest-get-type@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" + integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== + +jest-haste-map@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" + integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== + dependencies: + "@jest/types" "^24.9.0" + anymatch "^2.0.0" + fb-watchman "^2.0.0" + graceful-fs "^4.1.15" + invariant "^2.2.4" + jest-serializer "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.9.0" + micromatch "^3.1.10" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^1.2.7" + +jest-jasmine2@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" + integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== + dependencies: + "@babel/traverse" "^7.1.0" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^24.9.0" + is-generator-fn "^2.0.0" + jest-each "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + throat "^4.0.0" + +jest-leak-detector@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" + integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== + dependencies: + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-matcher-utils@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" + integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== + dependencies: + chalk "^2.0.1" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-message-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" + integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/stack-utils" "^1.0.1" + chalk "^2.0.1" + micromatch "^3.1.10" + slash "^2.0.0" + stack-utils "^1.0.1" + +jest-mock@^24.0.0, jest-mock@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" + integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== + dependencies: + "@jest/types" "^24.9.0" + +jest-pnp-resolver@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" + integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== + +jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" + integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== + +jest-resolve-dependencies@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" + integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== + dependencies: + "@jest/types" "^24.9.0" + jest-regex-util "^24.3.0" + jest-snapshot "^24.9.0" + +jest-resolve@24.9.0, jest-resolve@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" + integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== + dependencies: + "@jest/types" "^24.9.0" + browser-resolve "^1.11.3" + chalk "^2.0.1" + jest-pnp-resolver "^1.2.1" + realpath-native "^1.1.0" + +jest-runner@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" + integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.4.2" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-config "^24.9.0" + jest-docblock "^24.3.0" + jest-haste-map "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-leak-detector "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.6.0" + source-map-support "^0.5.6" + throat "^4.0.0" + +jest-runtime@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" + integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.9.0" + "@jest/source-map" "^24.3.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.1.15" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + realpath-native "^1.1.0" + slash "^2.0.0" + strip-bom "^3.0.0" + yargs "^13.3.0" + +jest-serializer@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" + integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== + +jest-snapshot@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" + integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== + dependencies: + "@babel/types" "^7.0.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + expect "^24.9.0" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^24.9.0" + semver "^6.2.0" + +jest-util@^24.0.0, jest-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" + integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== + dependencies: + "@jest/console" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/source-map" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + callsites "^3.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.15" + is-ci "^2.0.0" + mkdirp "^0.5.1" + slash "^2.0.0" + source-map "^0.6.0" + +jest-validate@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" + integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== + dependencies: + "@jest/types" "^24.9.0" + camelcase "^5.3.1" + chalk "^2.0.1" + jest-get-type "^24.9.0" + leven "^3.1.0" + pretty-format "^24.9.0" + +jest-watch-typeahead@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz#e5be959698a7fa2302229a5082c488c3c8780a4a" + integrity sha512-f7VpLebTdaXs81rg/oj4Vg/ObZy2QtGzAmGLNsqUS5G5KtSN68tFcIsbvNODfNyQxU78g7D8x77o3bgfBTR+2Q== + dependencies: + ansi-escapes "^4.2.1" + chalk "^2.4.1" + jest-regex-util "^24.9.0" + jest-watcher "^24.3.0" + slash "^3.0.0" + string-length "^3.1.0" + strip-ansi "^5.0.0" + +jest-watcher@^24.3.0, jest-watcher@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" + integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== + dependencies: + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + jest-util "^24.9.0" + string-length "^2.0.0" + +jest-worker@^24.6.0, jest-worker@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" + integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== + dependencies: + merge-stream "^2.0.0" + supports-color "^6.1.0" + +jest-worker@^25.1.0: + version "25.1.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.1.0.tgz#75d038bad6fdf58eba0d2ec1835856c497e3907a" + integrity sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg== + dependencies: + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest@24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" + integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== + dependencies: + import-local "^2.0.0" + jest-cli "^24.9.0" + +jquery.flot.tooltip@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/jquery.flot.tooltip/-/jquery.flot.tooltip-0.9.0.tgz#ae16bf94b26c2ed9ab4db167bba52dfdb615c1df" + integrity sha1-rha/lLJsLtmrTbFnu6Ut/bYVwd8= + +jquery@^3.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2" + integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw== + +jquery@^3.5.0: + version "3.5.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.1.tgz#d7b4d08e1bfdb86ad2f1a3d039ea17304717abb5" + integrity sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg== + +"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-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-yaml@^3.13.1: + 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= + +jsdom@^11.5.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + +jsdom@^14.1.0: + version "14.1.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-14.1.0.tgz#916463b6094956b0a6c1782c94e380cd30e1981b" + integrity sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng== + dependencies: + abab "^2.0.0" + acorn "^6.0.4" + acorn-globals "^4.3.0" + array-equal "^1.0.0" + cssom "^0.3.4" + cssstyle "^1.1.1" + data-urls "^1.1.0" + domexception "^1.0.1" + escodegen "^1.11.0" + html-encoding-sniffer "^1.0.2" + nwsapi "^2.1.3" + parse5 "5.1.0" + pn "^1.1.0" + request "^2.88.0" + request-promise-native "^1.0.5" + saxes "^3.1.9" + symbol-tree "^3.2.2" + tough-cookie "^2.5.0" + w3c-hr-time "^1.0.1" + w3c-xmlserializer "^1.1.2" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^7.0.0" + ws "^6.1.2" + xml-name-validator "^3.0.0" + +jsdom@^15.2.0: + version "15.2.1" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-15.2.1.tgz#d2feb1aef7183f86be521b8c6833ff5296d07ec5" + integrity sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g== + dependencies: + abab "^2.0.0" + acorn "^7.1.0" + acorn-globals "^4.3.2" + array-equal "^1.0.0" + cssom "^0.4.1" + cssstyle "^2.0.0" + data-urls "^1.1.0" + domexception "^1.0.1" + escodegen "^1.11.1" + html-encoding-sniffer "^1.0.2" + nwsapi "^2.2.0" + parse5 "5.1.0" + pn "^1.1.0" + request "^2.88.0" + request-promise-native "^1.0.7" + saxes "^3.1.9" + symbol-tree "^3.2.2" + tough-cookie "^3.0.1" + w3c-hr-time "^1.0.1" + w3c-xmlserializer "^1.1.2" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^7.0.0" + ws "^7.0.0" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +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-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +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.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.2.tgz#43ef1f0af9835dd624751a6b7fa48874fb2d608e" + integrity sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ== + dependencies: + minimist "^1.2.5" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + 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= + +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" + +jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f" + integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA== + dependencies: + array-includes "^3.0.3" + object.assign "^4.1.0" + +just-extend@^4.0.2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.0.tgz#7278a4027d889601640ee0ce0e5a00b992467da4" + integrity sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA== + +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@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" + integrity sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU= + dependencies: + is-buffer "^1.0.2" + +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== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +last-call-webpack-plugin@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz#9742df0e10e3cf46e5c0381c2de90d3a7a2d7555" + integrity sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w== + dependencies: + lodash "^4.17.5" + webpack-sources "^1.1.0" + +lazy-cache@^0.2.3: + version "0.2.7" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" + integrity sha1-f+3fLctu23fRHvHRF6tf/fCrG2U= + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= + +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" + +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levenary@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" + integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== + dependencies: + leven "^3.1.0" + +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" + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +loader-fs-cache@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz#f08657646d607078be2f0a032f8bd69dd6f277d9" + integrity sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA== + dependencies: + find-cache-dir "^0.1.1" + mkdirp "^0.5.1" + +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@^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" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +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-es@^4.17.15: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" + integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== + +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.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.escape@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" + integrity sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg= + +lodash.escaperegexp@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" + integrity sha1-ZHYsSGGAglGKw99Mz11YhtriA0c= + +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= + +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= + +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.mergewith@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.template@^4.4.0, 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.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@>=3.5 <5", lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.5: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +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== + +lolex@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-4.2.0.tgz#ddbd7f6213ca1ea5826901ab1222b65d714b3cd7" + integrity sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg== + +lolex@^5.0.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" + integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== + dependencies: + "@sinonjs/commons" "^1.7.0" + +loose-envify@^1.0.0, loose-envify@^1.1.0, 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@^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@^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, make-dir@^2.1.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" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" + +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" + +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.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-deep@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/merge-deep/-/merge-deep-3.0.2.tgz#f39fa100a4f1bd34ff29f7d2bf4508fbb8d83ad2" + integrity sha512-T7qC8kg4Zoti1cFd8Cr0M+qaZfOwjlPDEdZIIPPB2JZctjaPM4fX+i7HOId69tAti2fvO6X5ldfYUONDODsrkA== + dependencies: + arr-union "^3.1.0" + clone-deep "^0.2.4" + kind-of "^3.0.2" + +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-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.2.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" + integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +microevent.ts@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" + integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== + +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: + 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.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" + integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + +mimic-fn@^2.0.0, mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mini-css-extract-plugin@0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e" + integrity sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A== + dependencies: + loader-utils "^1.1.0" + normalize-url "1.9.1" + 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.4, 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@^1.1.1, 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-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz#3dcb6bb4a546e32969c7ad710f2c79a86abba93a" + integrity sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.1: + 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" + +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" + +mixin-object@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e" + integrity sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4= + dependencies: + for-in "^0.1.3" + is-extendable "^0.1.1" + +mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.3.tgz#5a514b7179259287952881e94410ec5465659f8c" + integrity sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg== + dependencies: + minimist "^1.2.5" + +moment-timezone@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.4.1.tgz#81f598c3ad5e22cdad796b67ecd8d88d0f5baa06" + integrity sha1-gfWYw61eIs2teWtn7NjYjQ9bqgY= + dependencies: + moment ">= 2.6.0" + +moment-timezone@^0.5.11, moment-timezone@^0.5.23: + version "0.5.28" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.28.tgz#f093d789d091ed7b055d82aa81a82467f72e4338" + integrity sha512-TDJkZvAyKIVWg5EtVqRzU97w0Rb0YVbfpqyjgu6GwXCAohVRqwZjf4fOzDE6p1Ch98Sro/8hQQi65WDXW5STPw== + dependencies: + moment ">= 2.9.0" + +"moment@>= 2.6.0", "moment@>= 2.9.0", moment@>=2.14.0, moment@^2.22.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== + +moo@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.1.tgz#7aae7f384b9b09f620b6abf6f74ebbcd1b65dbc4" + integrity sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w== + +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.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nan@^2.12.1: + 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" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +nearley@^2.7.10: + version "2.19.1" + resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.19.1.tgz#4af4006e16645ff800e9f993c3af039857d9dbdc" + integrity sha512-xq47GIUGXxU9vQg7g/y1o1xuKnkO7ev4nRWqftmQrLkfnE/FjRqDaGOUakM8XHPn/6pW3bGjU2wgoJyId90rqg== + dependencies: + commander "^2.19.0" + moo "^0.5.0" + railroad-diagrams "^1.0.0" + randexp "0.4.6" + semver "^5.4.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= + +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== + +nise@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/nise/-/nise-1.5.3.tgz#9d2cfe37d44f57317766c6e9408a359c5d3ac1f7" + integrity sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ== + dependencies: + "@sinonjs/formatio" "^3.2.1" + "@sinonjs/text-encoding" "^0.7.1" + just-extend "^4.0.2" + lolex "^5.0.1" + path-to-regexp "^1.7.0" + +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-fetch@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= + +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-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +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-modules-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" + integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= + +node-notifier@^5.4.2: + version "5.4.3" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" + integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== + dependencies: + growly "^1.3.0" + is-wsl "^1.1.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + +node-releases@^1.1.52: + 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" + +normalize-package-data@^2.3.2: + 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== + +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.9.1: + 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" + +normalize-url@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== + +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" + +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= + +nwsapi@^2.0.7, nwsapi@^2.1.3, nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +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-hash@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea" + integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg== + +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, object-is@^1.0.2: + 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-path@0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" + integrity sha1-NwrnUvvzfePqcKhhwju6iRVpGUk= + +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.entries@^1.1.0, object.entries@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.1.tgz#ee1cf04153de02bb093fec33683900f57ce5399b" + integrity sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +object.fromentries@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9" + integrity sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + has "^1.0.3" + +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, object.values@^1.1.1: + 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== + +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@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + dependencies: + mimic-fn "^2.1.0" + +open@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/open/-/open-7.0.3.tgz#db551a1af9c7ab4c7af664139930826138531c48" + integrity sha512-sP2ru2v0P290WFfv49Ap8MF6PkzGNnGlAwHweB4WR4mr5d2d0woiCluUeJ218w7/+PmoBy9JmYgD5A4mLcWOFA== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.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" + +optimize-css-assets-webpack-plugin@5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz#e2f1d4d94ad8c0af8967ebd7cf138dcb1ef14572" + integrity sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA== + dependencies: + cssnano "^4.1.10" + last-call-webpack-plugin "^3.0.0" + +optionator@^0.8.1, optionator@^0.8.3: + 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-locale@^3.0.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" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +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-each-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" + integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= + dependencies: + p-reduce "^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-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@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.2: + 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@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.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-map@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" + integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== + dependencies: + aggregate-error "^3.0.0" + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + +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@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +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" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.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-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-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-json@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" + integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + lines-and-columns "^1.1.6" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== + +parse5@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" + integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== + +parse5@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" + integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== + dependencies: + "@types/node" "*" + +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-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-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +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@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +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= + +picomatch@^2.0.4, picomatch@^2.0.7: + 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@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +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= + +pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== + dependencies: + node-modules-regexp "^1.0.0" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= + dependencies: + find-up "^1.0.0" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.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" + +pkg-up@3.1.0, pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + +pnp-webpack-plugin@1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== + dependencies: + ts-pnp "^1.1.6" + +popper.js@^1.14.1, popper.js@^1.14.3, popper.js@^1.14.4: + 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-comments@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-browser-comments/-/postcss-browser-comments-3.0.0.tgz#1248d2d935fb72053c8e1f61a84a57292d9f65e9" + integrity sha512-qfVjLfq7HFd2e0HW4s1dvU8X080OZdG46fFbIBFjW7US7YPDcWfRvdElvwMJr2LI6hMmD+7LnH2HcmXTs+uOig== + dependencies: + postcss "^7" + +postcss-calc@^7.0.1: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.2.tgz#504efcd008ca0273120568b0792b16cdcde8aac1" + integrity sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ== + dependencies: + postcss "^7.0.27" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.0.2" + +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@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-4.0.3.tgz#ae060bce93ed794ac71264f08132d550956bd381" + integrity sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw== + dependencies: + browserslist "^4.0.0" + color "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-convert-values@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f" + integrity sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +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@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz#1fbabd2c246bff6aaad7997b2b0918f4d7af4033" + integrity sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg== + dependencies: + postcss "^7.0.0" + +postcss-discard-duplicates@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz#3fe133cd3c82282e550fc9b239176a9207b784eb" + integrity sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ== + dependencies: + postcss "^7.0.0" + +postcss-discard-empty@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz#c8c951e9f73ed9428019458444a02ad90bb9f765" + integrity sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w== + dependencies: + postcss "^7.0.0" + +postcss-discard-overridden@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz#652aef8a96726f029f5e3e00146ee7a4e755ff57" + integrity sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg== + dependencies: + postcss "^7.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-flexbugs-fixes@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.1.0.tgz#e094a9df1783e2200b7b19f875dcad3b3aff8b20" + integrity sha512-jr1LHxQvStNNAHlgco6PzY308zvLklh7SJVYuWUwyUQncofaAlD2l+P/gxKHOdqWKe7xJSkVLFF/2Tp+JqMSZA== + dependencies: + postcss "^7.0.0" + +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-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-longhand@^4.0.11: + version "4.0.11" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz#62f49a13e4a0ee04e7b98f42bb16062ca2549e24" + integrity sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw== + dependencies: + css-color-names "0.0.4" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + stylehacks "^4.0.0" + +postcss-merge-rules@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz#362bea4ff5a1f98e4075a713c6cb25aefef9a650" + integrity sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + cssnano-util-same-parent "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.0.0" + vendors "^1.0.0" + +postcss-minify-font-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz#cd4c344cce474343fac5d82206ab2cbcb8afd5a6" + integrity sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-gradients@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz#93b29c2ff5099c535eecda56c4aa6e665a663471" + integrity sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + is-color-stop "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-minify-params@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz#6b9cef030c11e35261f95f618c90036d680db874" + integrity sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg== + dependencies: + alphanum-sort "^1.0.0" + browserslist "^4.0.0" + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + uniqs "^2.0.0" + +postcss-minify-selectors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz#e2e5eb40bfee500d0cd9243500f5f8ea4262fbd8" + integrity sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g== + dependencies: + alphanum-sort "^1.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-selector-parser "^3.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@^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.1.1: + 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-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@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz#8b35add3aee83a136b0471e0d59be58a50285dd4" + integrity sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g== + dependencies: + postcss "^7.0.0" + +postcss-normalize-display-values@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz#0dbe04a4ce9063d4667ed2be476bb830c825935a" + integrity sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-positions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz#05f757f84f260437378368a91f8932d4b102917f" + integrity sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA== + dependencies: + cssnano-util-get-arguments "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-repeat-style@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz#c4ebbc289f3991a028d44751cbdd11918b17910c" + integrity sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q== + dependencies: + cssnano-util-get-arguments "^4.0.0" + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-string@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz#cd44c40ab07a0c7a36dc5e99aace1eca4ec2690c" + integrity sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA== + dependencies: + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-timing-functions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz#8e009ca2a3949cdaf8ad23e6b6ab99cb5e7d28d9" + integrity sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A== + dependencies: + cssnano-util-get-match "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-unicode@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz#841bd48fdcf3019ad4baa7493a3d363b52ae1cfb" + integrity sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-url@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz#10e437f86bc7c7e58f7b9652ed878daaa95faae1" + integrity sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA== + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize-whitespace@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz#bf1d4070fe4fcea87d1348e825d8cc0c5faa7d82" + integrity sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA== + dependencies: + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +postcss-normalize@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize/-/postcss-normalize-8.0.1.tgz#90e80a7763d7fdf2da6f2f0f82be832ce4f66776" + integrity sha512-rt9JMS/m9FHIRroDDBGSMsyW1c0fkvOJPy62ggxSHUldJO7B195TqFMqIf+lY5ezpDcYOV4j86aUp3/XbxzCCQ== + dependencies: + "@csstools/normalize.css" "^10.1.0" + browserslist "^4.6.2" + postcss "^7.0.17" + postcss-browser-comments "^3.0.0" + sanitize.css "^10.0.0" + +postcss-ordered-values@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz#0cf75c820ec7d5c4d280189559e0b571ebac0eee" + integrity sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw== + dependencies: + cssnano-util-get-arguments "^4.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +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.7.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-initial@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz#7fd42ebea5e9c814609639e2c2e84ae270ba48df" + integrity sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA== + dependencies: + browserslist "^4.0.0" + caniuse-api "^3.0.0" + has "^1.0.0" + postcss "^7.0.0" + +postcss-reduce-transforms@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz#17efa405eacc6e07be3414a5ca2d1074681d4e29" + integrity sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg== + dependencies: + cssnano-util-get-match "^4.0.0" + has "^1.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + +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-safe-parser@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-4.0.1.tgz#8756d9e4c36fdce2c72b091bbc8ca176ab1fcdea" + integrity sha512-xZsFA3uX8MO3yAda03QrG3/Eg1LN3EPfjjf07vke/46HERLZyHrTsQ9E1r1w1W//fWEhtYNndo2hQplN2cVpCQ== + dependencies: + postcss "^7.0.0" + +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@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz#b310f5c4c0fdaf76f94902bbaa30db6aa84f5270" + integrity sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA== + dependencies: + dot-prop "^5.2.0" + 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@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" + integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== + dependencies: + is-svg "^3.0.0" + postcss "^7.0.0" + postcss-value-parser "^3.0.0" + svgo "^1.0.0" + +postcss-unique-selectors@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz#9446911f3289bfd64c6d680f073c03b1f9ee4bac" + integrity sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg== + dependencies: + alphanum-sort "^1.0.0" + postcss "^7.0.0" + uniqs "^2.0.0" + +postcss-value-parser@^3.0.0: + 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.0, 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@7.0.21: + version "7.0.21" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.21.tgz#06bb07824c19c2021c5d056d5b10c35b989f7e17" + integrity sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.23, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6: + 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" + +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= + +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-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^1.18.2: + version "1.19.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" + integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== + +pretty-bytes@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" + integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== + +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" + +pretty-format@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" + integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== + dependencies: + "@jest/types" "^24.9.0" + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + react-is "^16.8.4" + +private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +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@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +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= + +promise-polyfill@^7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-7.1.2.tgz#ab05301d8c28536301622d69227632269a70ca3b" + integrity sha512-FuEc12/eKqqoRYIGBrUptCBRhobL19PS2U31vMNTfyck1FxPyMfgsXyW4Mav85y/ZN1hop3hOwRlUDok23oYfQ== + +promise@^8.0.3: + version "8.1.0" + resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e" + integrity sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q== + dependencies: + asap "~2.0.6" + +prompts@^2.0.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.2.tgz#480572d89ecf39566d2bd3fe2c9fccb7c4c0b068" + integrity sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.4" + +prop-types-exact@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/prop-types-exact/-/prop-types-exact-1.2.0.tgz#825d6be46094663848237e3925a98c6e944e9869" + integrity sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA== + dependencies: + has "^1.0.3" + object.assign "^4.1.0" + reflect.ownkeys "^0.2.0" + +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: + 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== + +raf-schd@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.2.tgz#bd44c708188f2e84c810bf55fcea9231bcaed8a0" + integrity sha512-VhlMZmGy6A6hrkJWHLNTGl5gtgMUm+xfGza6wbwnE914yeQ5Ybm18vgM734RZhMgfw4tacUrWseGZlpUrrakEQ== + +raf@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== + dependencies: + performance-now "^2.1.0" + +railroad-diagrams@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e" + integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234= + +randexp@0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3" + integrity sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ== + dependencies: + discontinuous-range "1.0.0" + ret "~0.1.10" + +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" + +react-app-polyfill@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-1.0.6.tgz#890f8d7f2842ce6073f030b117de9130a5f385f0" + integrity sha512-OfBnObtnGgLGfweORmdZbyEz+3dgVePQBb3zipiaDsMHV1NpWm0rDFYIVXFV/AK+x4VIIfWHhrdMIeoTLyRr2g== + dependencies: + core-js "^3.5.0" + object-assign "^4.1.1" + promise "^8.0.3" + raf "^3.4.1" + regenerator-runtime "^0.13.3" + whatwg-fetch "^3.0.0" + +react-copy-to-clipboard@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.2.tgz#d82a437e081e68dfca3761fbd57dbf2abdda1316" + integrity sha512-/2t5mLMMPuN5GmdXo6TebFa8IoFxZ+KTDDqYhcDm0PhkgEzSxVvIX26G20s1EB02A4h2UZgwtfymZ3lGJm0OLg== + dependencies: + copy-to-clipboard "^3" + prop-types "^15.5.8" + +react-dev-utils@^10.2.1: + version "10.2.1" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19" + integrity sha512-XxTbgJnYZmxuPtY3y/UV0D8/65NKkmaia4rXzViknVnZeVlklSh8u6TnaEYPfAi/Gh1TP4mEOXHI6jQOPbeakQ== + dependencies: + "@babel/code-frame" "7.8.3" + address "1.1.2" + browserslist "4.10.0" + chalk "2.4.2" + cross-spawn "7.0.1" + detect-port-alt "1.1.6" + escape-string-regexp "2.0.0" + filesize "6.0.1" + find-up "4.1.0" + fork-ts-checker-webpack-plugin "3.1.1" + global-modules "2.0.0" + globby "8.0.2" + gzip-size "5.1.1" + immer "1.10.0" + inquirer "7.0.4" + is-root "2.1.0" + loader-utils "1.2.3" + open "^7.0.2" + pkg-up "3.1.0" + react-error-overlay "^6.0.7" + recursive-readdir "2.2.2" + shell-quote "1.7.2" + strip-ansi "6.0.0" + text-table "0.2.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-error-overlay@^6.0.7: + version "6.0.7" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108" + integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA== + +react-is@^16.12.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: + 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-popper@^1.3.6: + version "1.3.7" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.7.tgz#f6a3471362ef1f0d10a4963673789de1baca2324" + integrity sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww== + dependencies: + "@babel/runtime" "^7.1.2" + create-react-context "^0.3.0" + deep-equal "^1.1.1" + popper.js "^1.14.4" + prop-types "^15.6.1" + typed-styles "^0.0.7" + warning "^4.0.2" + +react-resize-detector@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-4.2.1.tgz#8982b74c3e1cf949afaa3c41050458c87b033982" + integrity sha512-ZfPMBPxXi0o3xox42MIEtz84tPSVMW9GgwLHYvjVXlFM+OkNzbeEtpVSV+mSTJmk4Znwomolzt35zHN9LNBQMQ== + dependencies: + lodash "^4.17.15" + lodash-es "^4.17.15" + prop-types "^15.7.2" + raf-schd "^4.0.2" + resize-observer-polyfill "^1.5.1" + +react-scripts@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-3.4.1.tgz#f551298b5c71985cc491b9acf3c8e8c0ae3ada0a" + integrity sha512-JpTdi/0Sfd31mZA6Ukx+lq5j1JoKItX7qqEK4OiACjVQletM1P38g49d9/D0yTxp9FrSF+xpJFStkGgKEIRjlQ== + dependencies: + "@babel/core" "7.9.0" + "@svgr/webpack" "4.3.3" + "@typescript-eslint/eslint-plugin" "^2.10.0" + "@typescript-eslint/parser" "^2.10.0" + babel-eslint "10.1.0" + babel-jest "^24.9.0" + babel-loader "8.1.0" + babel-plugin-named-asset-import "^0.3.6" + babel-preset-react-app "^9.1.2" + camelcase "^5.3.1" + case-sensitive-paths-webpack-plugin "2.3.0" + css-loader "3.4.2" + dotenv "8.2.0" + dotenv-expand "5.1.0" + eslint "^6.6.0" + eslint-config-react-app "^5.2.1" + eslint-loader "3.0.3" + eslint-plugin-flowtype "4.6.0" + eslint-plugin-import "2.20.1" + eslint-plugin-jsx-a11y "6.2.3" + eslint-plugin-react "7.19.0" + eslint-plugin-react-hooks "^1.6.1" + file-loader "4.3.0" + fs-extra "^8.1.0" + html-webpack-plugin "4.0.0-beta.11" + identity-obj-proxy "3.0.0" + jest "24.9.0" + jest-environment-jsdom-fourteen "1.0.1" + jest-resolve "24.9.0" + jest-watch-typeahead "0.4.2" + mini-css-extract-plugin "0.9.0" + optimize-css-assets-webpack-plugin "5.0.3" + pnp-webpack-plugin "1.6.4" + postcss-flexbugs-fixes "4.1.0" + postcss-loader "3.0.0" + postcss-normalize "8.0.1" + postcss-preset-env "6.7.0" + postcss-safe-parser "4.0.1" + react-app-polyfill "^1.0.6" + react-dev-utils "^10.2.1" + resolve "1.15.0" + resolve-url-loader "3.1.1" + sass-loader "8.0.2" + semver "6.3.0" + style-loader "0.23.1" + terser-webpack-plugin "2.3.5" + ts-pnp "1.1.6" + url-loader "2.3.0" + webpack "4.42.0" + webpack-dev-server "3.10.3" + webpack-manifest-plugin "2.2.0" + workbox-webpack-plugin "4.3.1" + optionalDependencies: + fsevents "2.1.2" + +react-test-renderer@^16.0.0-0, react-test-renderer@^16.9.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.13.1.tgz#de25ea358d9012606de51e012d9742e7f0deabc1" + integrity sha512-Sn2VRyOK2YJJldOqoh8Tn/lWQ+ZiKhyZTPtaO0Q6yNj+QDbmRkVFap6pZPy3YQk8DScRDfyqm/KxKYP9gCMRiQ== + dependencies: + object-assign "^4.1.1" + prop-types "^15.6.2" + react-is "^16.8.6" + scheduler "^0.19.1" + +react-transition-group@^2.3.1: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== + dependencies: + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" + +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" + +reactstrap@^8.0.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-8.4.1.tgz#c7f63b9057f58b52833061711ebe235b9ec4e3e5" + integrity sha512-oAjp9PYYUGKl7SLXwrQ1oRIrYw0MqfO2mUqYgGapFKHG2uwjEtLip5rYxtMujkGx3COjH5FX1WtcfNU4oqpH0Q== + dependencies: + "@babel/runtime" "^7.2.0" + classnames "^2.2.3" + prop-types "^15.5.8" + react-lifecycles-compat "^3.0.4" + react-popper "^1.3.6" + react-transition-group "^2.3.1" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, 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: + 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.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17" + integrity sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ== + dependencies: + picomatch "^2.0.7" + +realpath-native@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" + integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== + dependencies: + util.promisify "^1.0.0" + +recursive-readdir@2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + dependencies: + minimatch "3.0.4" + +reflect.ownkeys@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460" + integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA= + +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +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== + +regenerator-transform@^0.14.2: + version "0.14.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7" + integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw== + dependencies: + "@babel/runtime" "^7.8.4" + private "^0.1.8" + +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" + +regex-parser@2.2.10: + version "2.2.10" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.10.tgz#9e66a8f73d89a107616e63b39d4deddfee912b37" + integrity sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA== + +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.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" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpp@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.0.0.tgz#dd63982ee3300e67b41c1956f850aa680d9d330e" + integrity sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g== + +regexpu-core@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" + integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.2.0" + +regjsgen@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" + integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== + +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + dependencies: + jsesc "~0.5.0" + +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= + +request-promise-core@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" + integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== + dependencies: + lodash "^4.17.15" + +request-promise-native@^1.0.5, request-promise-native@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" + integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== + dependencies: + request-promise-core "1.1.3" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +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@^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-observer-polyfill@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + +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-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-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-url-loader@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz#28931895fa1eab9be0647d3b2958c100ae3c0bf0" + integrity sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ== + dependencies: + adjust-sourcemap-loader "2.0.0" + camelcase "5.3.1" + compose-function "3.0.3" + convert-source-map "1.7.0" + es6-iterator "2.0.3" + loader-utils "1.2.3" + postcss "7.0.21" + rework "1.0.1" + rework-visit "1.0.0" + source-map "0.6.1" + +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: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +resolve@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.0.tgz#1b7ca96073ebb52e741ffd799f6b39ea462c67f5" + integrity sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw== + dependencies: + path-parse "^1.0.6" + +resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.8.1: + 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" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +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= + +rework-visit@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a" + integrity sha1-mUWygD8hni96ygCtuLyfZA+ELJo= + +rework@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rework/-/rework-1.0.1.tgz#30806a841342b54510aa4110850cd48534144aa7" + integrity sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc= + dependencies: + convert-source-map "^0.3.3" + css "^2.0.0" + +rgb-regex@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" + integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= + +rgba-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" + integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= + +rimraf@2.6.3: + 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" + +rimraf@^2.5.4, rimraf@^2.6.3, rimraf@^2.7.1: + 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" + +rst-selector-parser@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91" + integrity sha1-gbIw6i/MYGbInjRy3nlChdmwPZE= + dependencies: + lodash.flattendeep "^4.4.0" + nearley "^2.7.10" + +rsvp@^4.8.4: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + +run-async@^2.2.0, run-async@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.0.tgz#e59054a5b86876cfae07f431d18cbaddc594f1e8" + integrity sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg== + dependencies: + is-promise "^2.1.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" + +rxjs@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" + integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== + dependencies: + tslib "^1.9.0" + +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== + +sane@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + +sanitize-html@^1.20.1: + version "1.22.1" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.22.1.tgz#5b36c92ab27917ddd2775396815c2bc1a6268310" + integrity sha512-++IMC00KfMQc45UWZJlhWOlS9eMrME38sFG9GXfR+k6oBo9JXSYQgTOZCl9j3v/smFTRNT9XNwz5DseFdMY+2Q== + dependencies: + chalk "^2.4.1" + htmlparser2 "^4.1.0" + lodash.clonedeep "^4.5.0" + lodash.escaperegexp "^4.1.2" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.mergewith "^4.6.2" + postcss "^7.0.27" + srcset "^2.0.1" + xtend "^4.0.1" + +sanitize.css@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-10.0.0.tgz#b5cb2547e96d8629a60947544665243b1dc3657a" + integrity sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg== + +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" + +sax@^1.2.4, 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== + +saxes@^3.1.9: + version "3.1.11" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" + integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== + dependencies: + xmlchars "^2.1.1" + +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.5.0, schema-utils@^2.6.0, schema-utils@^2.6.1, schema-utils@^2.6.4, schema-utils@^2.6.5: + 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@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@6.3.0, semver@^6.0.0, semver@^6.1.2, semver@^6.2.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@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +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: + 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@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060" + integrity sha1-WQnodLp3EG1zrEFM/sH/yofZcGA= + dependencies: + is-extendable "^0.1.1" + kind-of "^2.0.1" + lazy-cache "^0.2.3" + mixin-object "^2.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" + +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-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.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= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + +side-channel@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947" + integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA== + dependencies: + es-abstract "^1.17.0-next.1" + object-inspect "^1.7.0" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +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" + +sinon@^7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-7.5.0.tgz#e9488ea466070ea908fd44a3d6478fd4923c67ec" + integrity sha512-AoD0oJWerp0/rY9czP/D6hDTTUYGpObhZjMpd7Cl/A6+j0xBE+ayL/ldfggkBXUs0IkvIiM1ljM8+WkOc5k78Q== + dependencies: + "@sinonjs/commons" "^1.4.0" + "@sinonjs/formatio" "^3.2.1" + "@sinonjs/samsam" "^3.3.3" + diff "^3.5.0" + lolex "^4.2.0" + nise "^1.5.2" + supports-color "^5.5.0" + +sisteransi@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +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, source-map-resolve@^0.5.2: + 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.6, 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.6.1, 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.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= + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + 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.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= + +srcset@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/srcset/-/srcset-2.0.1.tgz#8f842d357487eb797f413d9c309de7a5149df5ac" + integrity sha512-00kZI87TdRKwt+P8jj8UZxbfp7mK2ufxcIMWvhAOZNJTRROimpHeruWrGvCZneiuVDLqdyHefVp748ECTnyUBQ== + +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" + +ssri@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-7.1.0.tgz#92c241bf6de82365b5c7fb4bd76e975522e1294d" + integrity sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g== + dependencies: + figgy-pudding "^3.5.1" + minipass "^3.1.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== + +stack-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" + integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== + +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= + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + +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== + +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-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + +string-length@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" + integrity sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA== + dependencies: + astral-regex "^1.0.0" + strip-ansi "^5.2.0" + +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@^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-width@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.matchall@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz#48bb510326fb9fdeb6a33ceaa81a6ea04ef7648e" + integrity sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0" + has-symbols "^1.0.1" + internal-slot "^1.0.2" + regexp.prototype.flags "^1.3.0" + side-channel "^1.0.2" + +string.prototype.trim@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz#141233dff32c82bfad80684d7e5f0869ee0fb782" + integrity sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + +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" + +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@6.0.0, strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.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@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-comments@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-1.0.2.tgz#82b9c45e7f05873bee53f37168af930aa368679d" + integrity sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw== + dependencies: + babel-extract-comments "^1.0.0" + babel-plugin-transform-object-rest-spread "^6.26.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@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + +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" + +stylehacks@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5" + integrity sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g== + dependencies: + browserslist "^4.0.0" + postcss "^7.0.0" + postcss-selector-parser "^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@^5.3.0, supports-color@^5.5.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" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + +svg-parser@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + +svgo@^1.0.0, svgo@^1.2.2: + 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" + +symbol-tree@^3.2.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.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== + +tempusdominus-bootstrap-4@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/tempusdominus-bootstrap-4/-/tempusdominus-bootstrap-4-5.1.2.tgz#3c9906ca6e5d563faa0b81b2fdc6aa79cad9c0be" + integrity sha512-ksD8qc4wOJeE19wvryXmEpRzMUSZu4wSOdG6zKSn8l4ccad16249KOX1j0CccyZpuuES/n4FLqLAUB+Dd1LTBA== + dependencies: + bootstrap ">=4.1.2" + jquery "^3.0" + moment "^2.22.2" + moment-timezone "^0.5.11" + popper.js "^1.14.3" + +tempusdominus-core@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/tempusdominus-core/-/tempusdominus-core-5.0.3.tgz#808642e47a83f45d7ef18c1597fd7b1d413d69e5" + integrity sha512-52lClmU33gb6J6I/S9uGDrgQwccq3Yw9SlZerTgGLOzOB3Sc9pgIVBirfPMsMcx8nPsg6mA5ItFAH/5BZiQThg== + dependencies: + jquery "^3.0" + moment "^2.22.2" + moment-timezone "^0.4.0" + +terser-webpack-plugin@2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.3.5.tgz#5ad971acce5c517440ba873ea4f09687de2f4a81" + integrity sha512-WlWksUoq+E4+JlJ+h+U+QUzXpcsMSSNXkDy9lBVkSqDn1w23Gg29L/ary9GeJVYCGiNJJX7LnVc4bwL1N3/g1w== + dependencies: + cacache "^13.0.1" + find-cache-dir "^3.2.0" + jest-worker "^25.1.0" + p-limit "^2.2.2" + schema-utils "^2.6.4" + serialize-javascript "^2.1.2" + source-map "^0.6.1" + terser "^4.4.3" + webpack-sources "^1.4.3" + +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@^4.1.2, terser@^4.4.3, terser@^4.6.3: + version "4.6.7" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.7.tgz#478d7f9394ec1907f0e488c5f6a6a9a2bad55e72" + integrity sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +test-exclude@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" + integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + read-pkg-up "^4.0.0" + require-main-filename "^2.0.0" + +text-table@0.2.0, 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= + +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= + +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" + +timsort@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" + integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + +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" + +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI= + +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.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0, 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" + +tough-cookie@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" + integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== + dependencies: + ip-regex "^2.1.0" + psl "^1.1.28" + punycode "^2.1.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +ts-pnp@1.1.6, ts-pnp@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.6.tgz#389a24396d425a0d3162e96d2b4638900fdc289a" + integrity sha512-CrG5GqAAzMT7144Cl+UIFP7mz/iIhiy+xQ6GGcnjTezhALT02uPMRw7tgDSESgB5MsfKt55+GPWw4ir1kVtMIQ== + +tslib@^1.10.0, tslib@^1.8.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== + +tsutils@^3.17.1: + version "3.17.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== + dependencies: + tslib "^1.8.1" + +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-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" + integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +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== + +typed-styles@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" + integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== + +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.3.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== + +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" + +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= + +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== + +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@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-2.3.0.tgz#e0e2ef658f003efb8ca41b0f3ffbf76bab88658b" + integrity sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog== + dependencies: + loader-utils "^1.2.3" + mime "^2.4.4" + schema-utils "^2.5.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@^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== + +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, 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.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== + +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" + +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" + +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== + +w3c-hr-time@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" + integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== + dependencies: + domexception "^1.0.1" + webidl-conversions "^4.0.2" + xml-name-validator "^3.0.0" + +walker@^1.0.7, walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + +warning@^4.0.2, 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" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +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.10.3: + 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-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-manifest-plugin@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz#19ca69b435b0baec7e29fbe90fb4015de2de4f16" + integrity sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ== + dependencies: + fs-extra "^7.0.0" + lodash ">=3.5 <5" + object.entries "^1.1.0" + tapable "^1.0.0" + +webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: + 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.42.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== + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3, whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-fetch@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + +whatwg-fetch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== + +whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +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.2.9, which@^1.3.0, 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" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +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== + +workbox-background-sync@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz#26821b9bf16e9e37fd1d640289edddc08afd1950" + integrity sha512-1uFkvU8JXi7L7fCHVBEEnc3asPpiAL33kO495UMcD5+arew9IbKW2rV5lpzhoWcm/qhGB89YfO4PmB/0hQwPRg== + dependencies: + workbox-core "^4.3.1" + +workbox-broadcast-update@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-4.3.1.tgz#e2c0280b149e3a504983b757606ad041f332c35b" + integrity sha512-MTSfgzIljpKLTBPROo4IpKjESD86pPFlZwlvVG32Kb70hW+aob4Jxpblud8EhNb1/L5m43DUM4q7C+W6eQMMbA== + dependencies: + workbox-core "^4.3.1" + +workbox-build@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-4.3.1.tgz#414f70fb4d6de47f6538608b80ec52412d233e64" + integrity sha512-UHdwrN3FrDvicM3AqJS/J07X0KXj67R8Cg0waq1MKEOqzo89ap6zh6LmaLnRAjpB+bDIz+7OlPye9iii9KBnxw== + dependencies: + "@babel/runtime" "^7.3.4" + "@hapi/joi" "^15.0.0" + common-tags "^1.8.0" + fs-extra "^4.0.2" + glob "^7.1.3" + lodash.template "^4.4.0" + pretty-bytes "^5.1.0" + stringify-object "^3.3.0" + strip-comments "^1.0.2" + workbox-background-sync "^4.3.1" + workbox-broadcast-update "^4.3.1" + workbox-cacheable-response "^4.3.1" + workbox-core "^4.3.1" + workbox-expiration "^4.3.1" + workbox-google-analytics "^4.3.1" + workbox-navigation-preload "^4.3.1" + workbox-precaching "^4.3.1" + workbox-range-requests "^4.3.1" + workbox-routing "^4.3.1" + workbox-strategies "^4.3.1" + workbox-streams "^4.3.1" + workbox-sw "^4.3.1" + workbox-window "^4.3.1" + +workbox-cacheable-response@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-4.3.1.tgz#f53e079179c095a3f19e5313b284975c91428c91" + integrity sha512-Rp5qlzm6z8IOvnQNkCdO9qrDgDpoPNguovs0H8C+wswLuPgSzSp9p2afb5maUt9R1uTIwOXrVQMmPfPypv+npw== + dependencies: + workbox-core "^4.3.1" + +workbox-core@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-4.3.1.tgz#005d2c6a06a171437afd6ca2904a5727ecd73be6" + integrity sha512-I3C9jlLmMKPxAC1t0ExCq+QoAMd0vAAHULEgRZ7kieCdUd919n53WC0AfvokHNwqRhGn+tIIj7vcb5duCjs2Kg== + +workbox-expiration@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-4.3.1.tgz#d790433562029e56837f341d7f553c4a78ebe921" + integrity sha512-vsJLhgQsQouv9m0rpbXubT5jw0jMQdjpkum0uT+d9tTwhXcEZks7qLfQ9dGSaufTD2eimxbUOJfWLbNQpIDMPw== + dependencies: + workbox-core "^4.3.1" + +workbox-google-analytics@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-4.3.1.tgz#9eda0183b103890b5c256e6f4ea15a1f1548519a" + integrity sha512-xzCjAoKuOb55CBSwQrbyWBKqp35yg1vw9ohIlU2wTy06ZrYfJ8rKochb1MSGlnoBfXGWss3UPzxR5QL5guIFdg== + dependencies: + workbox-background-sync "^4.3.1" + workbox-core "^4.3.1" + workbox-routing "^4.3.1" + workbox-strategies "^4.3.1" + +workbox-navigation-preload@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-4.3.1.tgz#29c8e4db5843803b34cd96dc155f9ebd9afa453d" + integrity sha512-K076n3oFHYp16/C+F8CwrRqD25GitA6Rkd6+qAmLmMv1QHPI2jfDwYqrytOfKfYq42bYtW8Pr21ejZX7GvALOw== + dependencies: + workbox-core "^4.3.1" + +workbox-precaching@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-4.3.1.tgz#9fc45ed122d94bbe1f0ea9584ff5940960771cba" + integrity sha512-piSg/2csPoIi/vPpp48t1q5JLYjMkmg5gsXBQkh/QYapCdVwwmKlU9mHdmy52KsDGIjVaqEUMFvEzn2LRaigqQ== + dependencies: + workbox-core "^4.3.1" + +workbox-range-requests@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-4.3.1.tgz#f8a470188922145cbf0c09a9a2d5e35645244e74" + integrity sha512-S+HhL9+iTFypJZ/yQSl/x2Bf5pWnbXdd3j57xnb0V60FW1LVn9LRZkPtneODklzYuFZv7qK6riZ5BNyc0R0jZA== + dependencies: + workbox-core "^4.3.1" + +workbox-routing@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-4.3.1.tgz#a675841af623e0bb0c67ce4ed8e724ac0bed0cda" + integrity sha512-FkbtrODA4Imsi0p7TW9u9MXuQ5P4pVs1sWHK4dJMMChVROsbEltuE79fBoIk/BCztvOJ7yUpErMKa4z3uQLX+g== + dependencies: + workbox-core "^4.3.1" + +workbox-strategies@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-4.3.1.tgz#d2be03c4ef214c115e1ab29c9c759c9fe3e9e646" + integrity sha512-F/+E57BmVG8dX6dCCopBlkDvvhg/zj6VDs0PigYwSN23L8hseSRwljrceU2WzTvk/+BSYICsWmRq5qHS2UYzhw== + dependencies: + workbox-core "^4.3.1" + +workbox-streams@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-4.3.1.tgz#0b57da70e982572de09c8742dd0cb40a6b7c2cc3" + integrity sha512-4Kisis1f/y0ihf4l3u/+ndMkJkIT4/6UOacU3A4BwZSAC9pQ9vSvJpIi/WFGQRH/uPXvuVjF5c2RfIPQFSS2uA== + dependencies: + workbox-core "^4.3.1" + +workbox-sw@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-4.3.1.tgz#df69e395c479ef4d14499372bcd84c0f5e246164" + integrity sha512-0jXdusCL2uC5gM3yYFT6QMBzKfBr2XTk0g5TPAV4y8IZDyVNDyj1a8uSXy3/XrvkVTmQvLN4O5k3JawGReXr9w== + +workbox-webpack-plugin@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-4.3.1.tgz#47ff5ea1cc074b6c40fb5a86108863a24120d4bd" + integrity sha512-gJ9jd8Mb8wHLbRz9ZvGN57IAmknOipD3W4XNE/Lk/4lqs5Htw4WOQgakQy/o/4CoXQlMCYldaqUg+EJ35l9MEQ== + dependencies: + "@babel/runtime" "^7.0.0" + json-stable-stringify "^1.0.1" + workbox-build "^4.3.1" + +workbox-window@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-4.3.1.tgz#ee6051bf10f06afa5483c9b8dfa0531994ede0f3" + integrity sha512-C5gWKh6I58w3GeSc0wp2Ne+rqVw8qwcmZnQGpjiek8A2wpbxSJb1FdCoQVO+jDJs35bFgo/WETgl1fqgsxN0Hg== + dependencies: + workbox-core "^4.3.1" + +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" + +worker-rpc@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" + integrity sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg== + dependencies: + microevent.ts "~0.1.1" + +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= + +write-file-atomic@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" + integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== + dependencies: + async-limiter "~1.0.0" + +ws@^6.1.2, 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" + +ws@^7.0.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" + integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xmlchars@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +xregexp@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.3.0.tgz#7e92e73d9174a99a59743f67a4ce879a04b5ae50" + integrity sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g== + dependencies: + "@babel/runtime-corejs3" "^7.8.3" + +xtend@^4.0.0, xtend@^4.0.1, 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@^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== + +yaml@^1.7.2: + version "1.8.3" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.8.3.tgz#2f420fca58b68ce3a332d0ca64be1d191dd3f87a" + integrity sha512-X/v7VDnK+sxbQ2Imq4Jt2PRUsRsP7UcpSl3Llg6+NRRqWLIvxkMFYtH1FmvwNGYRKKPa+EPA4qDBlI9WVG1UKw== + dependencies: + "@babel/runtime" "^7.8.7" + +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.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@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.3.0: + 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/pkg/ui/rule.go b/pkg/ui/rule.go index 22ab0f3ba6..5f54415b3f 100644 --- a/pkg/ui/rule.go +++ b/pkg/ui/rule.go @@ -16,6 +16,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/route" "github.com/prometheus/prometheus/rules" + "github.com/thanos-io/thanos/pkg/component" extpromhttp "github.com/thanos-io/thanos/pkg/extprom/http" thanosrule "github.com/thanos-io/thanos/pkg/rule" ) @@ -23,20 +24,21 @@ import ( type Rule struct { *BaseUI - flagsMap map[string]string + externalPrefix, prefixHeader string ruleManager *thanosrule.Manager queryURL string reg prometheus.Registerer } -func NewRuleUI(logger log.Logger, reg prometheus.Registerer, ruleManager *thanosrule.Manager, queryURL string, flagsMap map[string]string) *Rule { +func NewRuleUI(logger log.Logger, reg prometheus.Registerer, ruleManager *thanosrule.Manager, queryURL string, externalPrefix, prefixHeader string) *Rule { return &Rule{ - BaseUI: NewBaseUI(logger, "rule_menu.html", ruleTmplFuncs(queryURL)), - flagsMap: flagsMap, - ruleManager: ruleManager, - queryURL: queryURL, - reg: reg, + BaseUI: NewBaseUI(logger, "rule_menu.html", ruleTmplFuncs(queryURL), externalPrefix, prefixHeader, component.Rule), + externalPrefix: externalPrefix, + prefixHeader: prefixHeader, + ruleManager: ruleManager, + queryURL: queryURL, + reg: reg, } } @@ -133,14 +135,14 @@ func (ru *Rule) alerts(w http.ResponseWriter, r *http.Request) { Counts: alertCounts(groups), } - prefix := GetWebPrefix(ru.logger, ru.flagsMap, r) + prefix := GetWebPrefix(ru.logger, ru.externalPrefix, ru.prefixHeader, r) // TODO(bwplotka): Update HTML to include partial response. ru.executeTemplate(w, "alerts.html", prefix, alertStatus) } func (ru *Rule) rules(w http.ResponseWriter, r *http.Request) { - prefix := GetWebPrefix(ru.logger, ru.flagsMap, r) + prefix := GetWebPrefix(ru.logger, ru.externalPrefix, ru.prefixHeader, r) // TODO(bwplotka): Update HTML to include partial response. ru.executeTemplate(w, "rules.html", prefix, ru.ruleManager) @@ -148,7 +150,7 @@ func (ru *Rule) rules(w http.ResponseWriter, r *http.Request) { // Root redirects / requests to /graph, taking into account the path prefix value. func (ru *Rule) root(w http.ResponseWriter, r *http.Request) { - prefix := GetWebPrefix(ru.logger, ru.flagsMap, r) + prefix := GetWebPrefix(ru.logger, ru.externalPrefix, ru.prefixHeader, r) http.Redirect(w, r, path.Join(prefix, "/alerts"), http.StatusFound) } @@ -163,6 +165,15 @@ func (ru *Rule) Register(r *route.Router, ins extpromhttp.InstrumentationMiddlew r.Get("/rules", instrf("rules", ru.rules)) r.Get("/static/*filepath", instrf("static", ru.serveStaticAsset)) + // Make sure that "/new" is redirected to "/new/" and + // not just the naked "/new/", which would be the default behavior of the router + // with the "RedirectTrailingSlash" option (https://godoc.org/github.com/julienschmidt/httprouter#Router.RedirectTrailingSlash), + // and which breaks users with a --web.route-prefix that deviates from the path derived + // from the external URL. + r.Get("/new", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, path.Join(GetWebPrefix(ru.logger, ru.externalPrefix, ru.prefixHeader, r), "new")+"/", http.StatusFound) + }) + r.Get("/new/*filepath", instrf("react-static", ru.serveReactUI)) } // AlertStatus bundles alerting rules and the mapping of alert states to row classes. diff --git a/pkg/ui/static/js/bucket.js b/pkg/ui/static/js/bucket.js index e33b057ef0..15fd9bc217 100644 --- a/pkg/ui/static/js/bucket.js +++ b/pkg/ui/static/js/bucket.js @@ -7,6 +7,9 @@ function draw() { if (thanos.refreshedAt == "0001-01-01T00:00:00Z") { thanos.err = "Synchronizing blocks from remote storage"; } + else if (!thanos.err && thanos.blocks.length == 0) { + thanos.err = "No blocks are currently loaded"; + } if (thanos.err != null) { $("#err").show().find('.alert').text(JSON.stringify(thanos.err, null, 4)); @@ -29,20 +32,18 @@ function draw() { dataTable.addColumn({type: 'date', id: 'End'}); dataTable.addRows(thanos.blocks + .sort((a, b) => a.thanos.downsample.resolution - b.thanos.downsample.resolution) .map(function(d) { // Title is the first column of the timeline. // // A unique Prometheus label that identifies each shard is used - // as the title if present, otherwise all labels are displayed + // as the title if present, otherwise labels are displayed // externally as a legend. title = function() { - if (thanos.label != "") { - var key = d.thanos.labels[thanos.label]; - if (key == undefined) { - throw `Label ${thanos.label} not found in ${Object.keys(d.thanos.labels)}`; - } else { - return key; - } + var key = thanos.label != "" && d.thanos.labels[thanos.label]; + + if (key) { + return key; } else { title = titles[stringify(d.thanos.labels)]; if (title == undefined) { diff --git a/pkg/ui/static/vendor/js/jquery-3.3.1.min.js b/pkg/ui/static/vendor/js/jquery-3.3.1.min.js deleted file mode 100644 index 4d9b3a2587..0000000000 --- a/pkg/ui/static/vendor/js/jquery-3.3.1.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w(" + diff --git a/pkg/ui/templates/query_menu.html b/pkg/ui/templates/query_menu.html index 0497d3b3d4..a968dcc898 100644 --- a/pkg/ui/templates/query_menu.html +++ b/pkg/ui/templates/query_menu.html @@ -18,6 +18,9 @@ +
diff --git a/pkg/ui/templates/stores.html b/pkg/ui/templates/stores.html index c4cb297493..e6b0d61756 100644 --- a/pkg/ui/templates/stores.html +++ b/pkg/ui/templates/stores.html @@ -18,7 +18,7 @@

Unknown Type

Announced LabelSets Min Time Max Time - Last Health Check + Last Successful Health Check Last Message diff --git a/pkg/ui/ui.go b/pkg/ui/ui.go index 1114b8774e..4ceb7a7c98 100644 --- a/pkg/ui/ui.go +++ b/pkg/ui/ui.go @@ -5,68 +5,131 @@ package ui import ( "bytes" - "fmt" "html/template" - "io" "net/http" "net/url" + "os" "path" "path/filepath" "strings" "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" + "github.com/pkg/errors" "github.com/prometheus/common/route" "github.com/prometheus/common/version" + "github.com/thanos-io/thanos/pkg/component" +) + +var ( + reactAppPaths = []string{ + "/", + "/alerts", + "/config", + "/flags", + "/graph", + "/rules", + "/service-discovery", + "/status", + "/targets", + "/tsdb-status", + "/version", + } ) type BaseUI struct { - logger log.Logger - menuTmpl string - tmplFuncs template.FuncMap + logger log.Logger + menuTmpl string + tmplFuncs template.FuncMap + externalPrefix, prefixHeader string + component component.Component } -func NewBaseUI(logger log.Logger, menuTmpl string, funcMap template.FuncMap) *BaseUI { +func NewBaseUI(logger log.Logger, menuTmpl string, funcMap template.FuncMap, externalPrefix, prefixHeader string, component component.Component) *BaseUI { funcMap["pathPrefix"] = func() string { return "" } funcMap["buildVersion"] = func() string { return version.Revision } - return &BaseUI{logger: logger, menuTmpl: menuTmpl, tmplFuncs: funcMap} + return &BaseUI{logger: logger, menuTmpl: menuTmpl, tmplFuncs: funcMap, externalPrefix: externalPrefix, prefixHeader: prefixHeader, component: component} } - func (bu *BaseUI) serveStaticAsset(w http.ResponseWriter, req *http.Request) { fp := route.Param(req.Context(), "filepath") fp = filepath.Join("pkg/ui/static", fp) + bu.serveAsset(fp, w, req) +} - info, err := AssetInfo(fp) +func (bu *BaseUI) serveReactUI(w http.ResponseWriter, req *http.Request) { + fp := route.Param(req.Context(), "filepath") + for _, rp := range reactAppPaths { + if fp != rp { + continue + } + bu.serveReactIndex("pkg/ui/static/react/index.html", w, req) + return + } + fp = filepath.Join("pkg/ui/static/react/", fp) + bu.serveAsset(fp, w, req) +} + +func (bu *BaseUI) serveReactIndex(index string, w http.ResponseWriter, req *http.Request) { + _, file, err := bu.getAssetFile(index) if err != nil { - level.Warn(bu.logger).Log("msg", "Could not get file info", "err", err, "file", fp) + level.Warn(bu.logger).Log("msg", "Could not get file", "err", err, "file", index) w.WriteHeader(http.StatusNotFound) return } - file, err := Asset(fp) + prefix := GetWebPrefix(bu.logger, bu.externalPrefix, bu.prefixHeader, req) + + tmpl, err := template.New("").Funcs(bu.tmplFuncs). + Funcs(template.FuncMap{"pathPrefix": func() string { return prefix }}). + Parse(string(file)) + if err != nil { - if err != io.EOF { - level.Warn(bu.logger).Log("msg", "Could not get file", "err", err, "file", fp) - } - w.WriteHeader(http.StatusNotFound) + http.Error(w, err.Error(), http.StatusInternalServerError) return } + if err := tmpl.Execute(w, struct { + Component string + }{ + Component: bu.component.String(), + }); err != nil { + level.Warn(bu.logger).Log("msg", "template expansion failed", "err", err) + } +} +func (bu *BaseUI) getAssetFile(filename string) (os.FileInfo, []byte, error) { + info, err := AssetInfo(filename) + if err != nil { + return nil, nil, err + } + file, err := Asset(filename) + if err != nil { + return nil, nil, err + } + return info, file, nil +} + +func (bu *BaseUI) serveAsset(fp string, w http.ResponseWriter, req *http.Request) { + info, file, err := bu.getAssetFile(fp) + if err != nil { + level.Warn(bu.logger).Log("msg", "Could not get file", "err", err, "file", fp) + w.WriteHeader(http.StatusNotFound) + return + } http.ServeContent(w, req, info.Name(), info.ModTime(), bytes.NewReader(file)) } func (bu *BaseUI) getTemplate(name string) (string, error) { baseTmpl, err := Asset("pkg/ui/templates/_base.html") if err != nil { - return "", fmt.Errorf("error reading base template: %s", err) + return "", errors.Errorf("error reading base template: %s", err) } menuTmpl, err := Asset(filepath.Join("pkg/ui/templates", bu.menuTmpl)) if err != nil { - return "", fmt.Errorf("error reading menu template %s: %s", bu.menuTmpl, err) + return "", errors.Errorf("error reading menu template %s: %s", bu.menuTmpl, err) } pageTmpl, err := Asset(filepath.Join("pkg/ui/templates", name)) if err != nil { - return "", fmt.Errorf("error reading page template %s: %s", name, err) + return "", errors.Errorf("error reading page template %s: %s", name, err) } return string(baseTmpl) + string(menuTmpl) + string(pageTmpl), nil } @@ -92,13 +155,13 @@ func (bu *BaseUI) executeTemplate(w http.ResponseWriter, name string, prefix str // GetWebPrefix sanitizes an external URL path prefix value. // A value provided by web.external-prefix flag is preferred over the one supplied through an HTTP header. -func GetWebPrefix(logger log.Logger, flagsMap map[string]string, r *http.Request) string { +func GetWebPrefix(logger log.Logger, externalPrefix, prefixHeader string, r *http.Request) string { // Ignore web.prefix-header value if web.external-prefix is defined. - if len(flagsMap["web.external-prefix"]) > 0 { - return flagsMap["web.external-prefix"] + if len(externalPrefix) > 0 { + return externalPrefix } - prefix := r.Header.Get(flagsMap["web.prefix-header"]) + prefix := r.Header.Get(prefixHeader) // Even if rfc2616 suggests that Location header "value consists of a single absolute URI", browsers // support relative location too. So for extra security, scheme and host parts are stripped from a dynamic prefix. diff --git a/pkg/verifier/duplicated_compaction.go b/pkg/verifier/duplicated_compaction.go index c7cd94b4a7..d5ccdb73c2 100644 --- a/pkg/verifier/duplicated_compaction.go +++ b/pkg/verifier/duplicated_compaction.go @@ -27,14 +27,14 @@ const DuplicatedCompactionIssueID = "duplicated_compaction" // until sync-delay passes. // The expected print of this are same overlapped blocks with exactly the same sources, time ranges and stats. // If repair is enabled, all but one duplicates are safely deleted. -func DuplicatedCompactionIssue(ctx context.Context, logger log.Logger, bkt objstore.Bucket, backupBkt objstore.Bucket, repair bool, idMatcher func(ulid.ULID) bool, fetcher *block.MetaFetcher) error { +func DuplicatedCompactionIssue(ctx context.Context, logger log.Logger, bkt objstore.Bucket, backupBkt objstore.Bucket, repair bool, idMatcher func(ulid.ULID) bool, fetcher block.MetadataFetcher, deleteDelay time.Duration, metrics *verifierMetrics) error { if idMatcher != nil { return errors.Errorf("id matching is not supported by issue %s verifier", DuplicatedCompactionIssueID) } level.Info(logger).Log("msg", "started verifying issue", "with-repair", repair, "issue", DuplicatedCompactionIssueID) - overlaps, err := fetchOverlaps(ctx, logger, bkt, fetcher) + overlaps, err := fetchOverlaps(ctx, fetcher) if err != nil { return errors.Wrap(err, DuplicatedCompactionIssueID) } @@ -84,7 +84,7 @@ func DuplicatedCompactionIssue(ctx context.Context, logger log.Logger, bkt objst } for i, id := range toKill { - if err := BackupAndDelete(ctx, logger, bkt, backupBkt, id); err != nil { + if err := BackupAndDelete(ctx, logger, bkt, backupBkt, id, deleteDelay, metrics.blocksMarkedForDeletion); err != nil { return err } level.Info(logger).Log("msg", "Removed duplicated block", "id", id, "to-be-removed", len(toKill)-(i+1), "removed", i+1, "issue", DuplicatedCompactionIssueID) diff --git a/pkg/verifier/index_issue.go b/pkg/verifier/index_issue.go index 828be21444..a6a5035ebe 100644 --- a/pkg/verifier/index_issue.go +++ b/pkg/verifier/index_issue.go @@ -10,6 +10,7 @@ import ( "os" "path" "path/filepath" + "time" "github.com/thanos-io/thanos/pkg/block/metadata" @@ -28,7 +29,7 @@ const IndexIssueID = "index_issue" // If the replacement was created successfully it is uploaded to the bucket and the input // block is deleted. // NOTE: This also verifies all indexes against chunks mismatches and duplicates. -func IndexIssue(ctx context.Context, logger log.Logger, bkt objstore.Bucket, backupBkt objstore.Bucket, repair bool, idMatcher func(ulid.ULID) bool, fetcher *block.MetaFetcher) error { +func IndexIssue(ctx context.Context, logger log.Logger, bkt objstore.Bucket, backupBkt objstore.Bucket, repair bool, idMatcher func(ulid.ULID) bool, fetcher block.MetadataFetcher, deleteDelay time.Duration, metrics *verifierMetrics) error { level.Info(logger).Log("msg", "started verifying issue", "with-repair", repair, "issue", IndexIssueID) metas, _, err := fetcher.Fetch(ctx) @@ -115,7 +116,7 @@ func IndexIssue(ctx context.Context, logger log.Logger, bkt objstore.Bucket, bac } level.Info(logger).Log("msg", "safe deleting broken block", "id", id, "issue", IndexIssueID) - if err := BackupAndDeleteDownloaded(ctx, logger, filepath.Join(tmpdir, id.String()), bkt, backupBkt, id); err != nil { + if err := BackupAndDeleteDownloaded(ctx, logger, filepath.Join(tmpdir, id.String()), bkt, backupBkt, id, deleteDelay, metrics.blocksMarkedForDeletion); err != nil { return errors.Wrapf(err, "safe deleting old block %s failed", id) } level.Info(logger).Log("msg", "all good, continuing", "id", id, "issue", IndexIssueID) diff --git a/pkg/verifier/overlapped_blocks.go b/pkg/verifier/overlapped_blocks.go index 61e291ac78..ac76734878 100644 --- a/pkg/verifier/overlapped_blocks.go +++ b/pkg/verifier/overlapped_blocks.go @@ -6,6 +6,7 @@ package verifier import ( "context" "sort" + "time" "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" @@ -21,14 +22,14 @@ const OverlappedBlocksIssueID = "overlapped_blocks" // OverlappedBlocksIssue checks bucket for blocks with overlapped time ranges. // No repair is available for this issue. -func OverlappedBlocksIssue(ctx context.Context, logger log.Logger, bkt objstore.Bucket, _ objstore.Bucket, repair bool, idMatcher func(ulid.ULID) bool, fetcher *block.MetaFetcher) error { +func OverlappedBlocksIssue(ctx context.Context, logger log.Logger, _ objstore.Bucket, _ objstore.Bucket, repair bool, idMatcher func(ulid.ULID) bool, fetcher block.MetadataFetcher, _ time.Duration, _ *verifierMetrics) error { if idMatcher != nil { return errors.Errorf("id matching is not supported by issue %s verifier", OverlappedBlocksIssueID) } level.Info(logger).Log("msg", "started verifying issue", "with-repair", repair, "issue", OverlappedBlocksIssueID) - overlaps, err := fetchOverlaps(ctx, logger, bkt, fetcher) + overlaps, err := fetchOverlaps(ctx, fetcher) if err != nil { return errors.Wrap(err, OverlappedBlocksIssueID) } @@ -48,7 +49,7 @@ func OverlappedBlocksIssue(ctx context.Context, logger log.Logger, bkt objstore. return nil } -func fetchOverlaps(ctx context.Context, logger log.Logger, bkt objstore.Bucket, fetcher *block.MetaFetcher) (map[string]tsdb.Overlaps, error) { +func fetchOverlaps(ctx context.Context, fetcher block.MetadataFetcher) (map[string]tsdb.Overlaps, error) { metas, _, err := fetcher.Fetch(ctx) if err != nil { return nil, err diff --git a/pkg/verifier/safe_delete.go b/pkg/verifier/safe_delete.go index b6c882cbc9..5e5e5e5316 100644 --- a/pkg/verifier/safe_delete.go +++ b/pkg/verifier/safe_delete.go @@ -9,11 +9,13 @@ import ( "io/ioutil" "os" "path/filepath" + "time" "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "github.com/oklog/ulid" "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" "github.com/thanos-io/thanos/pkg/block" "github.com/thanos-io/thanos/pkg/objstore" ) @@ -32,10 +34,12 @@ func TSDBBlockExistsInBucket(ctx context.Context, bkt objstore.Bucket, id ulid.U } // BackupAndDelete moves a TSDB block to a backup bucket and on success removes -// it from the source bucket. It returns error if block dir already exists in +// it from the source bucket. If deleteDelay is zero, block is removed from source bucket. +// else the block is marked for deletion. +// It returns error if block dir already exists in // the backup bucket (blocks should be immutable) or if any of the operations // fail. -func BackupAndDelete(ctx context.Context, logger log.Logger, bkt, backupBkt objstore.Bucket, id ulid.ULID) error { +func BackupAndDelete(ctx context.Context, logger log.Logger, bkt, backupBkt objstore.Bucket, id ulid.ULID, deleteDelay time.Duration, blocksMarkedForDeletion prometheus.Counter) error { // Does this TSDB block exist in backupBkt already? found, err := TSDBBlockExistsInBucket(ctx, backupBkt, id) if err != nil { @@ -68,20 +72,27 @@ func BackupAndDelete(ctx context.Context, logger log.Logger, bkt, backupBkt objs } // Block uploaded, so we are ok to remove from src bucket. - level.Info(logger).Log("msg", "Deleting block", "id", id.String()) - if err := block.Delete(ctx, logger, bkt, id); err != nil { - return errors.Wrap(err, "delete from source") + if deleteDelay.Seconds() == 0 { + level.Info(logger).Log("msg", "Deleting block", "id", id.String()) + if err := block.Delete(ctx, logger, bkt, id); err != nil { + return errors.Wrap(err, "delete from source") + } } + level.Info(logger).Log("msg", "Marking block as deleted", "id", id.String()) + if err := block.MarkForDeletion(ctx, logger, bkt, id, blocksMarkedForDeletion); err != nil { + return errors.Wrap(err, "marking delete from source") + } return nil } // BackupAndDeleteDownloaded works much like BackupAndDelete in that it will -// move a TSDB block from a bucket to a backup bucket. The bdir parameter +// move a TSDB block from a bucket to a backup bucket. If deleteDelay param is zero, block is removed from source bucket. +// else the block is marked for deletion. The bdir parameter // points to the location on disk where the TSDB block was previously // downloaded allowing this function to avoid downloading the TSDB block from // the source bucket again. An error is returned if any operation fails. -func BackupAndDeleteDownloaded(ctx context.Context, logger log.Logger, bdir string, bkt, backupBkt objstore.Bucket, id ulid.ULID) error { +func BackupAndDeleteDownloaded(ctx context.Context, logger log.Logger, bdir string, bkt, backupBkt objstore.Bucket, id ulid.ULID, deleteDelay time.Duration, blocksMarkedForDeletion prometheus.Counter) error { // Does this TSDB block exist in backupBkt already? found, err := TSDBBlockExistsInBucket(ctx, backupBkt, id) if err != nil { @@ -97,11 +108,18 @@ func BackupAndDeleteDownloaded(ctx context.Context, logger log.Logger, bdir stri } // Block uploaded, so we are ok to remove from src bucket. - level.Info(logger).Log("msg", "Deleting block", "id", id.String()) - if err := block.Delete(ctx, logger, bkt, id); err != nil { - return errors.Wrap(err, "delete from source") + if deleteDelay.Seconds() == 0 { + level.Info(logger).Log("msg", "Deleting block", "id", id.String()) + if err := block.Delete(ctx, logger, bkt, id); err != nil { + return errors.Wrap(err, "delete from source") + } + return nil } + level.Info(logger).Log("msg", "Marking block as deleted", "id", id.String()) + if err := block.MarkForDeletion(ctx, logger, bkt, id, blocksMarkedForDeletion); err != nil { + return errors.Wrap(err, "marking delete from source") + } return nil } diff --git a/pkg/verifier/verify.go b/pkg/verifier/verify.go index 06f54f97d3..6149a6450b 100644 --- a/pkg/verifier/verify.go +++ b/pkg/verifier/verify.go @@ -5,6 +5,7 @@ package verifier import ( "context" + "time" "github.com/thanos-io/thanos/pkg/block" @@ -12,43 +13,66 @@ import ( "github.com/go-kit/kit/log/level" "github.com/oklog/ulid" "github.com/pkg/errors" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/thanos-io/thanos/pkg/objstore" ) +type verifierMetrics struct { + blocksMarkedForDeletion prometheus.Counter +} + +func newVerifierMetrics(reg prometheus.Registerer) *verifierMetrics { + var m verifierMetrics + + m.blocksMarkedForDeletion = promauto.With(reg).NewCounter(prometheus.CounterOpts{ + Name: "thanos_verify_blocks_marked_for_deletion_total", + Help: "Total number of blocks marked for deletion by verify.", + }) + + return &m +} + // Issue is an function that does verification and repair only if repair arg is true. // It should log affected blocks using warn level logs. It should be safe for issue to run on healthy bucket. -type Issue func(ctx context.Context, logger log.Logger, bkt objstore.Bucket, backupBkt objstore.Bucket, repair bool, idMatcher func(ulid.ULID) bool, fetcher *block.MetaFetcher) error +type Issue func(ctx context.Context, logger log.Logger, bkt objstore.Bucket, backupBkt objstore.Bucket, repair bool, idMatcher func(ulid.ULID) bool, fetcher block.MetadataFetcher, deleteDelay time.Duration, metrics *verifierMetrics) error // Verifier runs given issues to verify if bucket is healthy. type Verifier struct { - logger log.Logger - bkt objstore.Bucket - backupBkt objstore.Bucket - issues []Issue - repair bool - fetcher *block.MetaFetcher + logger log.Logger + bkt objstore.Bucket + backupBkt objstore.Bucket + issues []Issue + repair bool + fetcher block.MetadataFetcher + deleteDelay time.Duration + metrics *verifierMetrics } // New returns verifier that only logs affected blocks. -func New(logger log.Logger, bkt objstore.Bucket, fetcher *block.MetaFetcher, issues []Issue) *Verifier { +func New(logger log.Logger, reg prometheus.Registerer, bkt objstore.Bucket, fetcher block.MetadataFetcher, deleteDelay time.Duration, issues []Issue) *Verifier { return &Verifier{ - logger: logger, - bkt: bkt, - issues: issues, - fetcher: fetcher, - repair: false, + logger: logger, + bkt: bkt, + issues: issues, + fetcher: fetcher, + repair: false, + deleteDelay: deleteDelay, + metrics: newVerifierMetrics(reg), } } // NewWithRepair returns verifier that logs affected blocks and attempts to repair them. -func NewWithRepair(logger log.Logger, bkt objstore.Bucket, backupBkt objstore.Bucket, fetcher *block.MetaFetcher, issues []Issue) *Verifier { +func NewWithRepair(logger log.Logger, reg prometheus.Registerer, bkt objstore.Bucket, backupBkt objstore.Bucket, fetcher block.MetadataFetcher, deleteDelay time.Duration, issues []Issue) *Verifier { return &Verifier{ - logger: logger, - bkt: bkt, - backupBkt: backupBkt, - issues: issues, - fetcher: fetcher, - repair: true, + logger: logger, + bkt: bkt, + backupBkt: backupBkt, + issues: issues, + fetcher: fetcher, + repair: true, + deleteDelay: deleteDelay, + metrics: newVerifierMetrics(reg), } } @@ -67,7 +91,7 @@ func (v *Verifier) Verify(ctx context.Context, idMatcher func(ulid.ULID) bool) e // TODO(blotka): Wrap bucket with BucketWithMetrics and print metrics after each issue (e.g how many blocks where touched). // TODO(bplotka): Implement disk "bucket" to allow this verify to work on local disk space as well. for _, issueFn := range v.issues { - err := issueFn(ctx, v.logger, v.bkt, v.backupBkt, v.repair, idMatcher, v.fetcher) + err := issueFn(ctx, v.logger, v.bkt, v.backupBkt, v.repair, idMatcher, v.fetcher, v.deleteDelay, v.metrics) if err != nil { return errors.Wrap(err, "verify") } diff --git a/scripts/build-react-app.sh b/scripts/build-react-app.sh new file mode 100755 index 0000000000..101ee30e9c --- /dev/null +++ b/scripts/build-react-app.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# +# Build React web UI. +# Run from repository root. +set -e +set -u + +if ! [[ "$0" =~ "scripts/build-react-app.sh" ]]; then + echo "must be run from repository root" + exit 255 +fi + +cd pkg/ui/react-app + +PUBLIC_URL=. yarn build +rm -rf ../static/react +mv build ../static/react \ No newline at end of file diff --git a/scripts/cfggen/main.go b/scripts/cfggen/main.go index e48be1e7a8..1f764eaad1 100644 --- a/scripts/cfggen/main.go +++ b/scripts/cfggen/main.go @@ -92,14 +92,14 @@ func main() { } alertmgrCfg := alert.DefaultAlertmanagerConfig() - alertmgrCfg.EndpointsConfig.FileSDConfigs = []http_util.FileSDConfig{http_util.FileSDConfig{}} + alertmgrCfg.EndpointsConfig.FileSDConfigs = []http_util.FileSDConfig{{}} if err := generate(alert.AlertingConfig{Alertmanagers: []alert.AlertmanagerConfig{alertmgrCfg}}, "rule_alerting", *outputDir); err != nil { level.Error(logger).Log("msg", "failed to generate", "type", "rule_alerting", "err", err) os.Exit(1) } queryCfg := query.DefaultConfig() - queryCfg.EndpointsConfig.FileSDConfigs = []http_util.FileSDConfig{http_util.FileSDConfig{}} + queryCfg.EndpointsConfig.FileSDConfigs = []http_util.FileSDConfig{{}} if err := generate([]query.Config{queryCfg}, "rule_query", *outputDir); err != nil { level.Error(logger).Log("msg", "failed to generate", "type", "rule_query", "err", err) os.Exit(1) diff --git a/scripts/genflagdocs.sh b/scripts/genflagdocs.sh index 9583934f42..108f8920f0 100755 --- a/scripts/genflagdocs.sh +++ b/scripts/genflagdocs.sh @@ -6,9 +6,10 @@ set -u EMBEDMD_BIN=${EMBEDMD_BIN:-embedmd} SED_BIN=${SED_BIN:-sed} +THANOS_BIN=${THANOS_BIN:-${GOBIN}/thanos} function docs { -# if check arg was passed, instead of the docs generation verifies if docs coincide with the codebase +# If check arg was passed, instead of the docs generation verifies if docs coincide with the codebase. if [[ "${CHECK}" == "check" ]]; then set +e DIFF=$(${EMBEDMD_BIN} -d *.md) @@ -34,25 +35,27 @@ fi CHECK=${1:-} -commands=("compact" "query" "rule" "sidecar" "store" "bucket" "check") +# Auto update flags. +commands=("compact" "query" "rule" "sidecar" "store" "tools") for x in "${commands[@]}"; do - ./thanos "${x}" --help &> "docs/components/flags/${x}.txt" + ${THANOS_BIN} "${x}" --help &> "docs/components/flags/${x}.txt" done -bucketCommands=("verify" "ls" "inspect" "web" "replicate") -for x in "${bucketCommands[@]}"; do - ./thanos bucket "${x}" --help &> "docs/components/flags/bucket_${x}.txt" +toolsCommands=("bucket" "rules-check") +for x in "${toolsCommands[@]}"; do + ${THANOS_BIN} tools "${x}" --help &> "docs/components/flags/tools_${x}.txt" done -checkCommands=("rules") -for x in "${checkCommands[@]}"; do - ./thanos check "${x}" --help &> "docs/components/flags/check_${x}.txt" +toolsBucketCommands=("verify" "ls" "inspect" "web" "replicate" "downsample") +for x in "${toolsBucketCommands[@]}"; do + ${THANOS_BIN} tools bucket "${x}" --help &> "docs/components/flags/tools_bucket_${x}.txt" done -# remove white noise +# Remove white noise. ${SED_BIN} -i -e 's/[ \t]*$//' docs/components/flags/*.txt +# Auto update configuration. go run scripts/cfggen/main.go --output-dir=docs/flags # Change dir so embedmd understand the local references made in our markdown doc. diff --git a/scripts/genproto.sh b/scripts/genproto.sh index 1311ee8d76..2661133b39 100755 --- a/scripts/genproto.sh +++ b/scripts/genproto.sh @@ -24,15 +24,17 @@ GO111MODULE=on go install "github.com/gogo/protobuf/protoc-gen-gogofast" GOGOPROTO_ROOT="$(GO111MODULE=on go list -f '{{ .Dir }}' -m github.com/gogo/protobuf)" GOGOPROTO_PATH="${GOGOPROTO_ROOT}:${GOGOPROTO_ROOT}/protobuf" -DIRS="pkg/store/storepb" +DIRS="pkg/store/storepb pkg/store/storepb/prompb pkg/store/hintspb" echo "generating code" for dir in ${DIRS}; do pushd ${dir} - ${PROTOC_BIN} --gogofast_out=plugins=grpc:. \ + ${PROTOC_BIN} --gogofast_out=\ +Mgoogle/protobuf/any.proto=github.com/gogo/protobuf/types,\ +Mprompb/types.proto=github.com/thanos-io/thanos/pkg/store/storepb/prompb,\ +plugins=grpc:. \ -I=. \ -I="${GOGOPROTO_PATH}" \ - -I="../../../vendor" \ *.proto sed -i.bak -E 's/import _ \"gogoproto\"//g' *.pb.go diff --git a/scripts/insecure_grpcurl_series.sh b/scripts/insecure_grpcurl_series.sh new file mode 100755 index 0000000000..2e6ad269fc --- /dev/null +++ b/scripts/insecure_grpcurl_series.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +HELP=' +insecure_grpcurl_series.sh allows you to use call StoreAPI.Series gRPC method and receive streamed series in JSON format. + +Usage: + # Start some example Thanos component that exposes gRPC or use existing one. To start example one run: `thanos query &` + bash scripts/insecure_grpcurl_series.sh localhost:10901 '"'"'[{"type": 0, "name": "__name__", "value":"go_goroutines"}]'"'"' 0 10 +' + +STORE_API_HOSTPORT=$1 +if [ -z "${STORE_API_HOSTPORT}" ]; then + echo "\$1 is missing (STORE_API_HOSTPORT). Expected host:port string for the target StoreAPI to grpcurl against, e.g. localhost:10901" + echo "${HELP}" + exit 1 +fi + +REQUESTED_MATCHERS=$2 +if [ -z "${REQUESTED_MATCHERS}" ]; then + echo '$2 is missing (REQUESTED_MATCHERS). Expected matchers in form of JSON matchers: e.g [{"type": 0, "name": "__name__", "value":"go_goroutines"}]' + echo "${HELP}" + exit 1 +fi + +REQUESTED_MIN_TIME=$3 +if [ -z "${REQUESTED_MIN_TIME}" ]; then + echo '$3 is missing (REQUESTED_MIN_TIME). Expected min time in unix_timestamp.' + echo "${HELP}" + exit 1 +fi + +REQUESTED_MAX_TIME=$4 +if [ -z "${REQUESTED_MAX_TIME}" ]; then + echo '$4 is missing (REQUESTED_MAX_TIME). Expected max time in unix_timestamp.' + echo "${HELP}" + exit 1 +fi + +go install github.com/fullstorydev/grpcurl/cmd/grpcurl + +SERIES_REQUEST='{ + "min_time": '${REQUESTED_MIN_TIME}', + "max_time": '${REQUESTED_MAX_TIME}', + "matchers": '${REQUESTED_MATCHERS}', + "max_resolution_window": 0, + "aggregates": [], + "partial_response_strategy": 0, + "skip_chunks": false +}' + +GOGOPROTO_ROOT="$(GO111MODULE=on go list -f '{{ .Dir }}' -m github.com/gogo/protobuf)" + +pushd ${DIR}/../pkg/store/storepb/ +grpcurl \ + -import-path="${GOGOPROTO_ROOT}" \ + -import-path=. \ + -proto=rpc.proto \ + -plaintext \ + -d="${SERIES_REQUEST}" "${STORE_API_HOSTPORT}" thanos.Store/Series +popd diff --git a/scripts/quickstart.sh b/scripts/quickstart.sh index 0c26831e09..de98dab72f 100755 --- a/scripts/quickstart.sh +++ b/scripts/quickstart.sh @@ -84,6 +84,9 @@ scrape_configs: static_configs: - targets: - "localhost:909${i}" + - "localhost:5909${i}" + - "localhost:5909${i}" + - "localhost:5909${i}" - job_name: thanos-sidecar scrape_interval: 5s static_configs: @@ -99,6 +102,8 @@ scrape_configs: static_configs: - targets: - "localhost:10909" + - "localhost:11909" + - "localhost:12909" - job_name: thanos-query scrape_interval: 5s static_configs: @@ -163,38 +168,57 @@ fi sleep 0.5 if [ -n "${REMOTE_WRITE_ENABLED}" ]; then + +cat <<-EOF > ./data/hashring.json +[{"endpoints":["127.0.0.1:10907","127.0.0.1:11907","127.0.0.1:12907"]}] +EOF + +for i in $(seq 0 1 2); do ${THANOS_EXECUTABLE} receive \ - --debug.name receive \ + --debug.name receive${i} \ --log.level debug \ - --log.level debug \ - --tsdb.path "./data/remote-write-receive-data" \ - --grpc-address 0.0.0.0:10907 \ + --tsdb.path "./data/remote-write-receive-${i}-data" \ + --grpc-address 0.0.0.0:1${i}907 \ --grpc-grace-period 1s \ - --http-address 0.0.0.0:10909 \ + --http-address 0.0.0.0:1${i}909 \ --http-grace-period 1s \ - --label "receive=\"true\"" \ + --receive.replication-factor 1 \ + --tsdb.min-block-duration 5m \ + --tsdb.max-block-duration 5m \ + --label "receive_replica=\"${i}\"" \ + --receive.local-endpoint 127.0.0.1:1${i}907 \ + --receive.hashrings-file ./data/hashring.json \ ${OBJSTORECFG} \ - --remote-write.address 0.0.0.0:10908 & + --remote-write.address 0.0.0.0:1${i}908 & + + STORES="${STORES} --store 127.0.0.1:1${i}907" +done - mkdir -p "data/local-prometheus-data/" - cat <data/local-prometheus-data/prometheus.yml +for i in $(seq 0 1 2); do + mkdir -p "data/local-prometheus-${i}-data/" + cat <data/local-prometheus-${i}-data/prometheus.yml +global: + external_labels: + prometheus: prom${i} + replica: 1 # When the Thanos remote-write-receive component is started, # this is an example configuration of a Prometheus server that # would scrape a local node-exporter and replicate its data to # the remote write endpoint. scrape_configs: - - job_name: node + - job_name: test scrape_interval: 1s static_configs: - - targets: ['localhost:9100'] + - targets: + - fake remote_write: -- url: http://localhost:10908/api/v1/receive +- url: http://localhost:1${i}908/api/v1/receive EOF ${PROMETHEUS_EXECUTABLE} \ - --config.file data/local-prometheus-data/prometheus.yml \ - --storage.tsdb.path "data/local-prometheus-data/" & - - STORES="${STORES} --store 127.0.0.1:10907" + --web.listen-address ":5909${i}" \ + --config.file data/local-prometheus-${i}-data/prometheus.yml \ + --storage.tsdb.path "data/local-prometheus-${i}-data/" & +done fi sleep 0.5 @@ -219,13 +243,14 @@ for i in $(seq 0 1); do --http-grace-period 1s \ --query.replica-label prometheus \ --tracing.config="${QUERIER_JAEGER_CONFIG}" \ + --query.replica-label receive_replica \ ${STORES} & done sleep 0.5 if [ -n "${GCS_BUCKET}" -o -n "${S3_ENDPOINT}" ]; then - ${THANOS_EXECUTABLE} bucket web \ + ${THANOS_EXECUTABLE} tools bucket web \ --debug.name bucket-web \ --log.level debug \ --http-address 0.0.0.0:10933 \ diff --git a/scripts/websitepreprocess.sh b/scripts/websitepreprocess.sh index c4bc395498..1ecb22a81b 100755 --- a/scripts/websitepreprocess.sh +++ b/scripts/websitepreprocess.sh @@ -94,5 +94,8 @@ perl -pi -e 's/]\(\//]\(https:\/\/github.com\/thanos-io\/thanos\/tree\/'${COMMIT perl -pi -e 's/]\((?!http)/]\(..\//g' ${ALL_DOC_CONTENT_FILES} # All the relative links in src= needs to have ../ as well. perl -pi -e 's/src=\"(?!http)/src=\"..\//g' ${ALL_DOC_CONTENT_FILES} +# "Mask" bug in blackfriday that does not generate code snippets in tables. +perl -pi -e 's/```([a-z]+)/{{< highlight $1 >}}/g' ${OUTPUT_CONTENT_DIR}/contributing/coding-style-guide.md +perl -pi -e 's/```/{{< \/highlight >}}/g' ${OUTPUT_CONTENT_DIR}/contributing/coding-style-guide.md diff --git a/test/e2e/compact_test.go b/test/e2e/compact_test.go new file mode 100644 index 0000000000..b4593094d3 --- /dev/null +++ b/test/e2e/compact_test.go @@ -0,0 +1,602 @@ +// Copyright (c) The Thanos Authors. +// Licensed under the Apache License 2.0. + +package e2e_test + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + "os" + "path" + "path/filepath" + "testing" + "time" + + "github.com/cortexproject/cortex/integration/e2e" + e2edb "github.com/cortexproject/cortex/integration/e2e/db" + "github.com/go-kit/kit/log" + "github.com/oklog/ulid" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/pkg/timestamp" + "github.com/thanos-io/thanos/pkg/block" + "github.com/thanos-io/thanos/pkg/block/metadata" + "github.com/thanos-io/thanos/pkg/objstore" + "github.com/thanos-io/thanos/pkg/objstore/client" + "github.com/thanos-io/thanos/pkg/objstore/s3" + "github.com/thanos-io/thanos/pkg/promclient" + "github.com/thanos-io/thanos/pkg/testutil" + "github.com/thanos-io/thanos/pkg/testutil/e2eutil" + "github.com/thanos-io/thanos/test/e2e/e2ethanos" +) + +type blockDesc struct { + series []labels.Labels + extLset labels.Labels + mint int64 + maxt int64 +} + +func (b *blockDesc) Create(ctx context.Context, dir string, delay time.Duration) (ulid.ULID, error) { + if delay == 0*time.Second { + return e2eutil.CreateBlock(ctx, dir, b.series, 120, b.mint, b.maxt, b.extLset, 0) + } + return e2eutil.CreateBlockWithBlockDelay(ctx, dir, b.series, 120, b.mint, b.maxt, delay, b.extLset, 0) +} + +func TestCompactWithStoreGateway(t *testing.T) { + t.Parallel() + + logger := log.NewLogfmtLogger(os.Stdout) + + justAfterConsistencyDelay := 30 * time.Minute + // Make sure to take realistic timestamp for start. This is to align blocks as if they would be aligned on Prometheus. + // To have deterministic compaction, let's have fixed date: + now, err := time.Parse(time.RFC3339, "2020-03-24T08:00:00Z") + testutil.Ok(t, err) + + // Simulate real scenario, including more complex cases like overlaps if needed. + // TODO(bwplotka): Add blocks to downsample and test delayed delete. + blocks := []blockDesc{ + // Non overlapping blocks, not ready for compaction. + { + series: []labels.Labels{labels.FromStrings("a", "1", "b", "2")}, + extLset: labels.FromStrings("case", "no-compaction", "replica", "1"), + mint: timestamp.FromTime(now), + maxt: timestamp.FromTime(now.Add(2 * time.Hour)), + }, + { + series: []labels.Labels{labels.FromStrings("a", "1", "b", "2")}, + extLset: labels.FromStrings("case", "no-compaction", "replica", "1"), + mint: timestamp.FromTime(now.Add(2 * time.Hour)), + maxt: timestamp.FromTime(now.Add(4 * time.Hour)), + }, + { + series: []labels.Labels{labels.FromStrings("a", "1", "b", "2")}, + extLset: labels.FromStrings("case", "no-compaction", "replica", "1"), + mint: timestamp.FromTime(now.Add(4 * time.Hour)), + maxt: timestamp.FromTime(now.Add(6 * time.Hour)), + }, + } + blocks = append(blocks, + // Non overlapping blocks, ready for compaction. + blockDesc{ + series: []labels.Labels{labels.FromStrings("a", "1", "b", "2")}, + extLset: labels.FromStrings("case", "compaction-ready", "replica", "1"), + mint: timestamp.FromTime(now), + maxt: timestamp.FromTime(now.Add(2 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{labels.FromStrings("a", "1", "b", "3")}, + extLset: labels.FromStrings("case", "compaction-ready", "replica", "1"), + mint: timestamp.FromTime(now.Add(2 * time.Hour)), + maxt: timestamp.FromTime(now.Add(4 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{labels.FromStrings("a", "1", "b", "4")}, + extLset: labels.FromStrings("case", "compaction-ready", "replica", "1"), + mint: timestamp.FromTime(now.Add(4 * time.Hour)), + maxt: timestamp.FromTime(now.Add(6 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{labels.FromStrings("a", "1", "b", "5")}, + extLset: labels.FromStrings("case", "compaction-ready", "replica", "1"), + mint: timestamp.FromTime(now.Add(6 * time.Hour)), + maxt: timestamp.FromTime(now.Add(8 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{labels.FromStrings("a", "1", "b", "6")}, + extLset: labels.FromStrings("case", "compaction-ready", "replica", "1"), + mint: timestamp.FromTime(now.Add(8 * time.Hour)), + maxt: timestamp.FromTime(now.Add(10 * time.Hour)), + }, + + // Non overlapping blocks, ready for compaction, only after deduplication. + blockDesc{ + series: []labels.Labels{labels.FromStrings("a", "1", "b", "2")}, + extLset: labels.FromStrings("case", "compaction-ready-after-dedup", "replica", "1"), + mint: timestamp.FromTime(now), + maxt: timestamp.FromTime(now.Add(2 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{labels.FromStrings("a", "1", "b", "3")}, + extLset: labels.FromStrings("case", "compaction-ready-after-dedup", "replica", "1"), + mint: timestamp.FromTime(now.Add(2 * time.Hour)), + maxt: timestamp.FromTime(now.Add(4 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{labels.FromStrings("a", "1", "b", "4")}, + extLset: labels.FromStrings("case", "compaction-ready-after-dedup", "replica", "1"), + mint: timestamp.FromTime(now.Add(4 * time.Hour)), + maxt: timestamp.FromTime(now.Add(6 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{labels.FromStrings("a", "1", "b", "5")}, + extLset: labels.FromStrings("case", "compaction-ready-after-dedup", "replica", "2"), + mint: timestamp.FromTime(now.Add(6 * time.Hour)), + maxt: timestamp.FromTime(now.Add(8 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{labels.FromStrings("a", "1", "b", "6")}, + extLset: labels.FromStrings("case", "compaction-ready-after-dedup", "replica", "1"), + mint: timestamp.FromTime(now.Add(8 * time.Hour)), + maxt: timestamp.FromTime(now.Add(10 * time.Hour)), + }, + + // Replica partial overlapping blocks, not ready for compaction, among no-overlapping blocks. + // NOTE: We put a- in front to make sure this will be compacted as first one (: + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "1"), + labels.FromStrings("a", "1", "b", "2"), + }, + extLset: labels.FromStrings("case", "a-partial-overlap-dedup-ready", "replica", "1"), + mint: timestamp.FromTime(now), + maxt: timestamp.FromTime(now.Add(2 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "2"), + labels.FromStrings("a", "1", "b", "3"), + }, + extLset: labels.FromStrings("case", "a-partial-overlap-dedup-ready", "replica", "2"), + mint: timestamp.FromTime(now.Add(1 * time.Hour)), + maxt: timestamp.FromTime(now.Add(4 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "2"), + labels.FromStrings("a", "1", "b", "4"), + }, + extLset: labels.FromStrings("case", "a-partial-overlap-dedup-ready", "replica", "3"), + mint: timestamp.FromTime(now.Add(3 * time.Hour)), + maxt: timestamp.FromTime(now.Add(4 * time.Hour)), + }, + // Extra. + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "2"), + labels.FromStrings("a", "1", "b", "5"), + }, + extLset: labels.FromStrings("case", "a-partial-overlap-dedup-ready", "replica", "1"), + mint: timestamp.FromTime(now.Add(4 * time.Hour)), + maxt: timestamp.FromTime(now.Add(6 * time.Hour)), + }, + + // Multi-Replica partial overlapping blocks, not ready for compaction, among no-overlapping blocks. + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "1"), + labels.FromStrings("a", "1", "b", "2"), + }, + extLset: labels.FromStrings("case", "partial-multi-replica-overlap-dedup-ready", "rule_replica", "1", "replica", "1"), + mint: timestamp.FromTime(now), + maxt: timestamp.FromTime(now.Add(2 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "2"), + labels.FromStrings("a", "1", "b", "3"), + }, + extLset: labels.FromStrings("case", "partial-multi-replica-overlap-dedup-ready", "rule_replica", "2", "replica", "1"), + mint: timestamp.FromTime(now.Add(1 * time.Hour)), + maxt: timestamp.FromTime(now.Add(4 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "2"), + labels.FromStrings("a", "1", "b", "4"), + }, + // TODO(bwplotka): This is wrong, but let's fix in next PR. We should error out in this case as we should + // never support overlaps before we modify dedup labels. This probably means another check in fetcher. + extLset: labels.FromStrings("case", "partial-multi-replica-overlap-dedup-ready", "rule_replica", "1", "replica", "1"), + mint: timestamp.FromTime(now.Add(1 * time.Hour)), + maxt: timestamp.FromTime(now.Add(4 * time.Hour)), + }, + // Extra. + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "2"), + labels.FromStrings("a", "1", "b", "5"), + }, + extLset: labels.FromStrings("case", "partial-multi-replica-overlap-dedup-ready", "rule_replica", "1", "replica", "1"), + mint: timestamp.FromTime(now.Add(4 * time.Hour)), + maxt: timestamp.FromTime(now.Add(6 * time.Hour)), + }, + + // Replica full overlapping blocks, not ready for compaction, among no-overlapping blocks. + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "1"), + labels.FromStrings("a", "1", "b", "2"), + }, + extLset: labels.FromStrings("case", "full-replica-overlap-dedup-ready", "replica", "1"), + mint: timestamp.FromTime(now), + maxt: timestamp.FromTime(now.Add(2 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "2"), + labels.FromStrings("a", "1", "b", "3"), + }, + extLset: labels.FromStrings("case", "full-replica-overlap-dedup-ready", "replica", "2"), + mint: timestamp.FromTime(now), + maxt: timestamp.FromTime(now.Add(2 * time.Hour)), + }, + // Extra. + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "2"), + labels.FromStrings("a", "1", "b", "4"), + }, + extLset: labels.FromStrings("case", "full-replica-overlap-dedup-ready", "replica", "1"), + mint: timestamp.FromTime(now.Add(2 * time.Hour)), + maxt: timestamp.FromTime(now.Add(4 * time.Hour)), + }, + blockDesc{ + series: []labels.Labels{ + labels.FromStrings("a", "1", "b", "2"), + labels.FromStrings("a", "1", "b", "5"), + }, + extLset: labels.FromStrings("case", "full-replica-overlap-dedup-ready", "replica", "1"), + mint: timestamp.FromTime(now.Add(4 * time.Hour)), + maxt: timestamp.FromTime(now.Add(6 * time.Hour)), + }, + ) + + s, err := e2e.NewScenario("e2e_test_compact") + testutil.Ok(t, err) + defer s.Close() // TODO(kakkoyun): Change with t.CleanUp after go 1.14 update. + + dir := filepath.Join(s.SharedDir(), "tmp") + testutil.Ok(t, os.MkdirAll(dir, os.ModePerm)) + + const bucket = "compact_test" + m := e2edb.NewMinio(8080, bucket) + testutil.Ok(t, s.StartAndWaitReady(m)) + + bkt, err := s3.NewBucketWithConfig(logger, s3.Config{ + Bucket: bucket, + AccessKey: e2edb.MinioAccessKey, + SecretKey: e2edb.MinioSecretKey, + Endpoint: m.HTTPEndpoint(), // We need separate client config, when connecting to minio from outside. + Insecure: true, + }, "test-feed") + testutil.Ok(t, err) + + ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second) + defer cancel() // TODO(kakkoyun): Change with t.CleanUp after go 1.14 update. + + rawBlockIDs := map[ulid.ULID]struct{}{} + for _, b := range blocks { + id, err := b.Create(ctx, dir, justAfterConsistencyDelay) + testutil.Ok(t, err) + testutil.Ok(t, objstore.UploadDir(ctx, logger, bkt, path.Join(dir, id.String()), id.String())) + rawBlockIDs[id] = struct{}{} + } + { + // On top of that, add couple of other tricky cases with different meta. + malformedBase := blockDesc{ + series: []labels.Labels{labels.FromStrings("a", "1", "b", "2")}, + extLset: labels.FromStrings("case", "malformed-things", "replica", "101"), + mint: timestamp.FromTime(now), + maxt: timestamp.FromTime(now.Add(2 * time.Hour)), + } + + // New Partial block. + id, err := malformedBase.Create(ctx, dir, 0*time.Second) + testutil.Ok(t, err) + testutil.Ok(t, os.Remove(path.Join(dir, id.String(), metadata.MetaFilename))) + testutil.Ok(t, objstore.UploadDir(ctx, logger, bkt, path.Join(dir, id.String()), id.String())) + + // New Partial block + deletion mark. + id, err = malformedBase.Create(ctx, dir, 0*time.Second) + testutil.Ok(t, err) + testutil.Ok(t, os.Remove(path.Join(dir, id.String(), metadata.MetaFilename))) + testutil.Ok(t, block.MarkForDeletion(ctx, logger, bkt, id, promauto.With(nil).NewCounter(prometheus.CounterOpts{}))) + testutil.Ok(t, objstore.UploadDir(ctx, logger, bkt, path.Join(dir, id.String()), id.String())) + + // Partial block after consistency delay. + id, err = malformedBase.Create(ctx, dir, justAfterConsistencyDelay) + testutil.Ok(t, err) + testutil.Ok(t, os.Remove(path.Join(dir, id.String(), metadata.MetaFilename))) + testutil.Ok(t, objstore.UploadDir(ctx, logger, bkt, path.Join(dir, id.String()), id.String())) + + // Partial block after consistency delay + deletion mark. + id, err = malformedBase.Create(ctx, dir, justAfterConsistencyDelay) + testutil.Ok(t, err) + testutil.Ok(t, os.Remove(path.Join(dir, id.String(), metadata.MetaFilename))) + testutil.Ok(t, block.MarkForDeletion(ctx, logger, bkt, id, promauto.With(nil).NewCounter(prometheus.CounterOpts{}))) + testutil.Ok(t, objstore.UploadDir(ctx, logger, bkt, path.Join(dir, id.String()), id.String())) + + // Partial block after consistency delay + old deletion mark ready to be deleted. + id, err = malformedBase.Create(ctx, dir, justAfterConsistencyDelay) + testutil.Ok(t, err) + testutil.Ok(t, os.Remove(path.Join(dir, id.String(), metadata.MetaFilename))) + deletionMark, err := json.Marshal(metadata.DeletionMark{ + ID: id, + // Deletion threshold is usually 2 days. + DeletionTime: time.Now().Add(-50 * time.Hour).Unix(), + Version: metadata.DeletionMarkVersion1, + }) + testutil.Ok(t, err) + testutil.Ok(t, bkt.Upload(ctx, path.Join(id.String(), metadata.DeletionMarkFilename), bytes.NewBuffer(deletionMark))) + testutil.Ok(t, objstore.UploadDir(ctx, logger, bkt, path.Join(dir, id.String()), id.String())) + + // Partial block after delete threshold. + id, err = malformedBase.Create(ctx, dir, 50*time.Hour) + testutil.Ok(t, err) + testutil.Ok(t, os.Remove(path.Join(dir, id.String(), metadata.MetaFilename))) + testutil.Ok(t, objstore.UploadDir(ctx, logger, bkt, path.Join(dir, id.String()), id.String())) + + // Partial block after delete threshold + deletion mark. + id, err = malformedBase.Create(ctx, dir, 50*time.Hour) + testutil.Ok(t, err) + testutil.Ok(t, os.Remove(path.Join(dir, id.String(), metadata.MetaFilename))) + testutil.Ok(t, block.MarkForDeletion(ctx, logger, bkt, id, promauto.With(nil).NewCounter(prometheus.CounterOpts{}))) + testutil.Ok(t, objstore.UploadDir(ctx, logger, bkt, path.Join(dir, id.String()), id.String())) + } + + svcConfig := client.BucketConfig{ + Type: client.S3, + Config: s3.Config{ + Bucket: bucket, + AccessKey: e2edb.MinioAccessKey, + SecretKey: e2edb.MinioSecretKey, + Endpoint: m.NetworkHTTPEndpoint(), + Insecure: true, + }, + } + str, err := e2ethanos.NewStoreGW(s.SharedDir(), "1", svcConfig) + testutil.Ok(t, err) + testutil.Ok(t, s.StartAndWaitReady(str)) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(float64(len(rawBlockIDs)+7)), "thanos_blocks_meta_synced")) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_sync_failures_total")) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_modified")) + + q, err := e2ethanos.NewQuerier(s.SharedDir(), "1", []string{str.GRPCNetworkEndpoint()}, nil, nil) + testutil.Ok(t, err) + testutil.Ok(t, s.StartAndWaitReady(q)) + + ctx, cancel = context.WithTimeout(context.Background(), 3*time.Minute) + defer cancel() + + // Check if query detects current series, even if overlapped. + queryAndAssert(t, ctx, q.HTTPEndpoint(), + fmt.Sprintf(`count_over_time({a="1"}[13h] offset %ds)`, int64(time.Since(now.Add(12*time.Hour)).Seconds())), + promclient.QueryOptions{ + Deduplicate: false, // This should be false, so that we can be sure deduplication was offline. + }, + model.Vector{ + {Value: 360, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "no-compaction", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "compaction-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "3", "case": "compaction-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "4", "case": "compaction-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "5", "case": "compaction-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "6", "case": "compaction-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "compaction-ready-after-dedup", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "3", "case": "compaction-ready-after-dedup", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "4", "case": "compaction-ready-after-dedup", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "5", "case": "compaction-ready-after-dedup", "replica": "2"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "6", "case": "compaction-ready-after-dedup", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "1", "case": "a-partial-overlap-dedup-ready", "replica": "1"}}, + {Value: 240, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "a-partial-overlap-dedup-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "5", "case": "a-partial-overlap-dedup-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "a-partial-overlap-dedup-ready", "replica": "2"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "3", "case": "a-partial-overlap-dedup-ready", "replica": "2"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "a-partial-overlap-dedup-ready", "replica": "3"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "4", "case": "a-partial-overlap-dedup-ready", "replica": "3"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "1", "case": "partial-multi-replica-overlap-dedup-ready", "replica": "1", "rule_replica": "1"}}, + {Value: 320, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "partial-multi-replica-overlap-dedup-ready", "replica": "1", "rule_replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "4", "case": "partial-multi-replica-overlap-dedup-ready", "replica": "1", "rule_replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "5", "case": "partial-multi-replica-overlap-dedup-ready", "replica": "1", "rule_replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "partial-multi-replica-overlap-dedup-ready", "replica": "1", "rule_replica": "2"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "3", "case": "partial-multi-replica-overlap-dedup-ready", "replica": "1", "rule_replica": "2"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "1", "case": "full-replica-overlap-dedup-ready", "replica": "1"}}, + {Value: 360, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "full-replica-overlap-dedup-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "full-replica-overlap-dedup-ready", "replica": "2"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "3", "case": "full-replica-overlap-dedup-ready", "replica": "2"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "4", "case": "full-replica-overlap-dedup-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "5", "case": "full-replica-overlap-dedup-ready", "replica": "1"}}, + }, + ) + // Store view: + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(float64(len(rawBlockIDs)+7)), "thanos_blocks_meta_synced")) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_sync_failures_total")) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_modified")) + + expectedEndVector := model.Vector{ + // NOTE(bwplotka): Even after deduplication some series has still replica labels. This is because those blocks did not overlap yet with anything. + // This is fine as querier deduplication will remove it if needed. + {Value: 360, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "no-compaction", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "compaction-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "3", "case": "compaction-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "4", "case": "compaction-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "5", "case": "compaction-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "6", "case": "compaction-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "compaction-ready-after-dedup"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "3", "case": "compaction-ready-after-dedup"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "4", "case": "compaction-ready-after-dedup"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "5", "case": "compaction-ready-after-dedup"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "6", "case": "compaction-ready-after-dedup", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "1", "case": "a-partial-overlap-dedup-ready"}}, + {Value: 360, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "a-partial-overlap-dedup-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "a-partial-overlap-dedup-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "3", "case": "a-partial-overlap-dedup-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "4", "case": "a-partial-overlap-dedup-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "5", "case": "a-partial-overlap-dedup-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "1", "case": "partial-multi-replica-overlap-dedup-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "partial-multi-replica-overlap-dedup-ready", "replica": "1", "rule_replica": "1"}}, + {Value: 240, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "partial-multi-replica-overlap-dedup-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "3", "case": "partial-multi-replica-overlap-dedup-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "4", "case": "partial-multi-replica-overlap-dedup-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "5", "case": "partial-multi-replica-overlap-dedup-ready", "replica": "1", "rule_replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "1", "case": "full-replica-overlap-dedup-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "full-replica-overlap-dedup-ready"}}, + {Value: 240, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "2", "case": "full-replica-overlap-dedup-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "3", "case": "full-replica-overlap-dedup-ready"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "4", "case": "full-replica-overlap-dedup-ready", "replica": "1"}}, + {Value: 120, Metric: map[model.LabelName]model.LabelValue{"a": "1", "b": "5", "case": "full-replica-overlap-dedup-ready", "replica": "1"}}, + } + + t.Run("no replica label with overlaps should halt compactor", func(t *testing.T) { + c, err := e2ethanos.NewCompactor(s.SharedDir(), "expect-to-halt", svcConfig, nil) + testutil.Ok(t, err) + testutil.Ok(t, s.StartAndWaitReady(c)) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(float64(len(rawBlockIDs)+7)), "thanos_blocks_meta_synced")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_sync_failures_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_modified")) + + // Expect compactor halted. + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(1), "thanos_compactor_halted")) + + // We expect no ops. + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compactor_iterations_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compactor_blocks_cleaned_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compactor_block_cleanup_failures_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compactor_blocks_marked_for_deletion_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compactor_aborted_partial_uploads_deletion_attempts_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_group_compactions_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_group_vertical_compactions_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(1), "thanos_compact_group_compactions_failures_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(3), "thanos_compact_group_compaction_runs_started_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(2), "thanos_compact_group_compaction_runs_completed_total")) + + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_downsample_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_downsample_failures_total")) + + // Ensure bucket UI. + ensureGETStatusCode(t, http.StatusOK, "http://"+path.Join(c.HTTPEndpoint(), "global")) + ensureGETStatusCode(t, http.StatusOK, "http://"+path.Join(c.HTTPEndpoint(), "loaded")) + + testutil.Ok(t, s.Stop(c)) + }) + t.Run("dedup enabled; compactor should work as expected", func(t *testing.T) { + // We expect 2x 4-block compaction, 2-block vertical compaction, 2x 3-block compaction. + c, err := e2ethanos.NewCompactor(s.SharedDir(), "working", svcConfig, nil, "--deduplication.replica-label=replica", "--deduplication.replica-label=rule_replica") + testutil.Ok(t, err) + testutil.Ok(t, s.StartAndWaitReady(c)) + + // NOTE: We cannot assert on intermediate `thanos_blocks_meta_` metrics as those are gauge and change dynamically due to many + // compaction groups. Wait for at least first compaction iteration (next is in 5m). + testutil.Ok(t, c.WaitSumMetrics(e2e.Greater(0), "thanos_compactor_iterations_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(2), "thanos_compactor_blocks_cleaned_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compactor_block_cleanup_failures_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(2*4+2+2*3), "thanos_compactor_blocks_marked_for_deletion_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(2), "thanos_compactor_aborted_partial_uploads_deletion_attempts_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(5), "thanos_compact_group_compactions_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(3), "thanos_compact_group_vertical_compactions_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_group_compactions_failures_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(12), "thanos_compact_group_compaction_runs_started_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(12), "thanos_compact_group_compaction_runs_completed_total")) + + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_downsample_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_downsample_failures_total")) + + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(float64( + len(rawBlockIDs)+7+ + 5+ // 5 compactions, 5 newly added blocks. + -2, // Partial block removed. + )), "thanos_blocks_meta_synced")) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_sync_failures_total")) + + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compactor_halted")) + // Make sure compactor does not modify anything else over time. + testutil.Ok(t, s.Stop(c)) + + ctx, cancel = context.WithTimeout(context.Background(), 3*time.Minute) + defer cancel() + + // Check if query detects new blocks. + queryAndAssert(t, ctx, q.HTTPEndpoint(), + fmt.Sprintf(`count_over_time({a="1"}[13h] offset %ds)`, int64(time.Since(now.Add(12*time.Hour)).Seconds())), + promclient.QueryOptions{ + Deduplicate: false, // This should be false, so that we can be sure deduplication was offline. + }, + expectedEndVector, + ) + // Store view: + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(float64(len(rawBlockIDs)+7+5-2)), "thanos_blocks_meta_synced")) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_sync_failures_total")) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_modified")) + }) + + t.Run("dedup enabled; no delete delay; compactor should work and remove things as expected", func(t *testing.T) { + c, err := e2ethanos.NewCompactor(s.SharedDir(), "working", svcConfig, nil, "--deduplication.replica-label=replica", "--deduplication.replica-label=rule_replica", "--delete-delay=0s") + testutil.Ok(t, err) + testutil.Ok(t, s.StartAndWaitReady(c)) + + // NOTE: We cannot assert on intermediate `thanos_blocks_meta_` metrics as those are gauge and change dynamically due to many + // compaction groups. Wait for at least first compaction iteration (next is in 5m). + testutil.Ok(t, c.WaitSumMetrics(e2e.Greater(0), "thanos_compactor_iterations_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(16), "thanos_compactor_blocks_cleaned_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compactor_block_cleanup_failures_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compactor_blocks_marked_for_deletion_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compactor_aborted_partial_uploads_deletion_attempts_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_group_compactions_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_group_vertical_compactions_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_group_compactions_failures_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(6), "thanos_compact_group_compaction_runs_started_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(6), "thanos_compact_group_compaction_runs_completed_total")) + + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_downsample_total")) + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compact_downsample_failures_total")) + + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(float64(len(rawBlockIDs)+7+5-16-2)), "thanos_blocks_meta_synced")) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_sync_failures_total")) + + testutil.Ok(t, c.WaitSumMetrics(e2e.Equals(0), "thanos_compactor_halted")) + // Make sure compactor does not modify anything else over time. + testutil.Ok(t, s.Stop(c)) + + ctx, cancel = context.WithTimeout(context.Background(), 3*time.Minute) + defer cancel() + + // Check if query detects new blocks. + queryAndAssert(t, ctx, q.HTTPEndpoint(), + fmt.Sprintf(`count_over_time({a="1"}[13h] offset %ds)`, int64(time.Since(now.Add(12*time.Hour)).Seconds())), + promclient.QueryOptions{ + Deduplicate: false, // This should be false, so that we can be sure deduplication was offline. + }, + expectedEndVector, + ) + + // Store view: + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(float64(len(rawBlockIDs)+7-16+5-2)), "thanos_blocks_meta_synced")) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_sync_failures_total")) + testutil.Ok(t, str.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_modified")) + }) +} + +func ensureGETStatusCode(t testing.TB, code int, url string) { + t.Helper() + + r, err := http.Get(url) + testutil.Ok(t, err) + testutil.Equals(t, code, r.StatusCode) +} diff --git a/test/e2e/e2ethanos/services.go b/test/e2e/e2ethanos/services.go index 46a8d067ca..ff3424bb35 100644 --- a/test/e2e/e2ethanos/services.go +++ b/test/e2e/e2ethanos/services.go @@ -10,8 +10,10 @@ import ( "os" "path/filepath" "strconv" + "time" "github.com/cortexproject/cortex/integration/e2e" + "github.com/cortexproject/cortex/pkg/util" "github.com/pkg/errors" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/discovery/targetgroup" @@ -25,6 +27,13 @@ import ( const logLevel = "info" +// Same as default for now. +var defaultBackoffConfig = util.BackoffConfig{ + MinBackoff: 300 * time.Millisecond, + MaxBackoff: 600 * time.Millisecond, + MaxRetries: 50, +} + // TODO(bwplotka): Run against multiple? func DefaultPrometheusImage() string { return "quay.io/prometheus/prometheus:v2.16.0" @@ -69,6 +78,7 @@ func NewPrometheus(sharedDir string, name string, config, promImage string) (*e2 9090, ) prom.SetUser("root") + prom.SetBackoff(defaultBackoffConfig) return prom, container, nil } @@ -78,6 +88,7 @@ func NewPrometheusWithSidecar(sharedDir string, netName string, name string, con if err != nil { return nil, nil, err } + prom.SetBackoff(defaultBackoffConfig) sidecar := NewService( fmt.Sprintf("sidecar-%s", name), @@ -95,6 +106,8 @@ func NewPrometheusWithSidecar(sharedDir string, netName string, name string, con 80, 9091, ) + sidecar.SetBackoff(defaultBackoffConfig) + return prom, sidecar, nil } @@ -109,6 +122,7 @@ func NewQuerier(sharedDir string, name string, storeAddresses, fileSDStoreAddres "--query.replica-label": replicaLabel, "--store.sd-dns-interval": "5s", "--log.level": logLevel, + "--query.max-concurrent": "1", "--store.sd-interval": "5s", }) for _, addr := range storeAddresses { @@ -143,14 +157,17 @@ func NewQuerier(sharedDir string, name string, storeAddresses, fileSDStoreAddres args = append(args, "--store.sd-files="+filepath.Join(container, "filesd.yaml")) } - return NewService( + querier := NewService( fmt.Sprintf("querier-%v", name), DefaultImage(), e2e.NewCommand("query", args...), e2e.NewReadinessProbe(80, "/-/ready", 200), 80, 9091, - ), nil + ) + querier.SetBackoff(defaultBackoffConfig) + + return querier, nil } func RemoteWriteEndpoint(addr string) string { return fmt.Sprintf("http://%s/api/v1/receive", addr) } @@ -162,8 +179,9 @@ func NewReceiver(sharedDir string, networkName string, name string, replicationF } dir := filepath.Join(sharedDir, "data", "receive", name) + dataDir := filepath.Join(dir, "data") container := filepath.Join(e2e.ContainerSharedDir, "data", "receive", name) - if err := os.MkdirAll(dir, 0777); err != nil { + if err := os.MkdirAll(dataDir, 0777); err != nil { return nil, errors.Wrap(err, "create receive dir") } b, err := json.Marshal(hashring) @@ -175,7 +193,7 @@ func NewReceiver(sharedDir string, networkName string, name string, replicationF return nil, errors.Wrap(err, "creating receive config") } - return NewService( + receiver := NewService( fmt.Sprintf("receive-%v", name), DefaultImage(), // TODO(bwplotka): BuildArgs should be interface. @@ -186,7 +204,7 @@ func NewReceiver(sharedDir string, networkName string, name string, replicationF "--http-address": ":80", "--remote-write.address": ":81", "--label": fmt.Sprintf(`receive="%s"`, name), - "--tsdb.path": container, + "--tsdb.path": filepath.Join(container, "data"), "--log.level": logLevel, "--receive.replication-factor": strconv.Itoa(replicationFactor), "--receive.local-endpoint": localEndpoint, @@ -197,7 +215,10 @@ func NewReceiver(sharedDir string, networkName string, name string, replicationF 80, 9091, 81, - ), nil + ) + receiver.SetBackoff(defaultBackoffConfig) + + return receiver, nil } func NewRuler(sharedDir string, name string, ruleSubDir string, amCfg []alert.AlertmanagerConfig, queryCfg []query.Config) (*Service, error) { @@ -219,7 +240,7 @@ func NewRuler(sharedDir string, name string, ruleSubDir string, amCfg []alert.Al return nil, errors.Wrapf(err, "generate query file: %v", queryCfg) } - return NewService( + ruler := NewService( fmt.Sprintf("rule-%v", name), DefaultImage(), e2e.NewCommand("rule", e2e.BuildArgs(map[string]string{ @@ -230,7 +251,7 @@ func NewRuler(sharedDir string, name string, ruleSubDir string, amCfg []alert.Al "--label": fmt.Sprintf(`replica="%s"`, name), "--data-dir": container, "--rule-file": filepath.Join(e2e.ContainerSharedDir, ruleSubDir, "*.yaml"), - "--eval-interval": "1s", + "--eval-interval": "3s", "--alertmanagers.config": string(amCfgBytes), "--alertmanagers.sd-dns-interval": "1s", "--log.level": logLevel, @@ -241,7 +262,10 @@ func NewRuler(sharedDir string, name string, ruleSubDir string, amCfg []alert.Al e2e.NewReadinessProbe(80, "/-/ready", 200), 80, 9091, - ), nil + ) + ruler.SetBackoff(defaultBackoffConfig) + + return ruler, nil } func NewAlertmanager(sharedDir string, name string) (*e2e.HTTPService, error) { @@ -267,15 +291,19 @@ receivers: fmt.Sprintf("alertmanager-%v", name), DefaultAlertmanagerImage(), e2e.NewCommandWithoutEntrypoint("/bin/alertmanager", e2e.BuildArgs(map[string]string{ - "--config.file": filepath.Join(container, "config.yaml"), - "--web.listen-address": "0.0.0.0:80", - "--log.level": logLevel, - "--storage.path": container, + "--config.file": filepath.Join(container, "config.yaml"), + "--web.listen-address": "0.0.0.0:80", + "--log.level": logLevel, + "--storage.path": container, + "--web.get-concurrency": "1", + "--web.timeout": "2m", })...), e2e.NewReadinessProbe(80, "/-/ready", 200), 80, ) s.SetUser("root") + s.SetBackoff(defaultBackoffConfig) + return s, nil } @@ -296,10 +324,10 @@ func NewStoreGW(sharedDir string, name string, bucketConfig client.BucketConfig, return nil, errors.Wrapf(err, "generate store relabel file: %v", relabelConfig) } - return NewService( + store := NewService( fmt.Sprintf("store-gw-%v", name), DefaultImage(), - e2e.NewCommand("store", append(e2e.BuildArgs(map[string]string{ + e2e.NewCommand("store", e2e.BuildArgs(map[string]string{ "--debug.name": fmt.Sprintf("store-gw-%v", name), "--grpc-address": ":9091", "--grpc-grace-period": "0s", @@ -308,12 +336,56 @@ func NewStoreGW(sharedDir string, name string, bucketConfig client.BucketConfig, "--data-dir": container, "--objstore.config": string(bktConfigBytes), // Accelerated sync time for quicker test (3m by default). - "--sync-block-duration": "1s", - "--selector.relabel-config": string(relabelConfigBytes), - "--consistency-delay": "30m", - }), "--experimental.enable-index-header")...), + "--sync-block-duration": "3s", + "--block-sync-concurrency": "1", + "--store.grpc.series-max-concurrency": "1", + "--selector.relabel-config": string(relabelConfigBytes), + "--consistency-delay": "30m", + })...), e2e.NewReadinessProbe(80, "/-/ready", 200), 80, 9091, - ), nil + ) + store.SetBackoff(defaultBackoffConfig) + + return store, nil +} + +func NewCompactor(sharedDir string, name string, bucketConfig client.BucketConfig, relabelConfig []relabel.Config, extArgs ...string) (*e2e.HTTPService, error) { + dir := filepath.Join(sharedDir, "data", "compact", name) + container := filepath.Join(e2e.ContainerSharedDir, "data", "compact", name) + + if err := os.MkdirAll(dir, 0777); err != nil { + return nil, errors.Wrap(err, "create compact dir") + } + + bktConfigBytes, err := yaml.Marshal(bucketConfig) + if err != nil { + return nil, errors.Wrapf(err, "generate compact config file: %v", bucketConfig) + } + + relabelConfigBytes, err := yaml.Marshal(relabelConfig) + if err != nil { + return nil, errors.Wrapf(err, "generate compact relabel file: %v", relabelConfig) + } + + compactor := e2e.NewHTTPService( + fmt.Sprintf("compact-%s", name), + DefaultImage(), + e2e.NewCommand("compact", append(e2e.BuildArgs(map[string]string{ + "--debug.name": fmt.Sprintf("compact-%s", name), + "--log.level": logLevel, + "--data-dir": container, + "--objstore.config": string(bktConfigBytes), + "--http-address": ":80", + "--block-sync-concurrency": "20", + "--selector.relabel-config": string(relabelConfigBytes), + "--wait": "", + }), extArgs...)...), + e2e.NewReadinessProbe(80, "/-/ready", 200), + 80, + ) + compactor.SetBackoff(defaultBackoffConfig) + + return compactor, nil } diff --git a/test/e2e/query_test.go b/test/e2e/query_test.go index f3dc60e1af..59e776d719 100644 --- a/test/e2e/query_test.go +++ b/test/e2e/query_test.go @@ -16,6 +16,7 @@ import ( "github.com/thanos-io/thanos/pkg/store/storepb" "github.com/cortexproject/cortex/integration/e2e" + "github.com/go-kit/kit/log" "github.com/pkg/errors" "github.com/prometheus/common/model" "github.com/thanos-io/thanos/pkg/promclient" @@ -111,7 +112,7 @@ func TestQuery(t *testing.T) { testutil.Ok(t, q.WaitSumMetrics(e2e.Equals(5), "thanos_store_nodes_grpc_connections")) - queryAndAssert(t, ctx, q.HTTPEndpoint(), queryUpWithoutInstance, promclient.QueryOptions{ + queryAndAssertSeries(t, ctx, q.HTTPEndpoint(), queryUpWithoutInstance, promclient.QueryOptions{ Deduplicate: false, }, []model.Metric{ { @@ -124,6 +125,7 @@ func TestQuery(t *testing.T) { "prometheus": "prom-both-remote-write-and-sidecar", "receive": "1", "replica": "1234", + "tenant_id": "default-tenant", }, { "job": "myself", @@ -143,7 +145,7 @@ func TestQuery(t *testing.T) { }) // With deduplication. - queryAndAssert(t, ctx, q.HTTPEndpoint(), queryUpWithoutInstance, promclient.QueryOptions{ + queryAndAssertSeries(t, ctx, q.HTTPEndpoint(), queryUpWithoutInstance, promclient.QueryOptions{ Deduplicate: true, }, []model.Metric{ { @@ -154,6 +156,7 @@ func TestQuery(t *testing.T) { "job": "myself", "prometheus": "prom-both-remote-write-and-sidecar", "receive": "1", + "tenant_id": "default-tenant", }, { "job": "myself", @@ -206,34 +209,37 @@ func urlParse(t *testing.T, addr string) *url.URL { return u } -func queryAndAssert(t *testing.T, ctx context.Context, addr string, query string, opts promclient.QueryOptions, expected []model.Metric) { +func instantQuery(t *testing.T, ctx context.Context, addr string, q string, opts promclient.QueryOptions, expectedSeriesLen int) model.Vector { t.Helper() - fmt.Println("queryAndAssert: Waiting for", len(expected), "results for query", query) + fmt.Println("queryAndAssert: Waiting for", expectedSeriesLen, "results for query", q) var result model.Vector - testutil.Ok(t, runutil.Retry(time.Second, ctx.Done(), func() error { - res, warnings, err := promclient.NewDefaultClient().QueryInstant(ctx, urlParse(t, "http://"+addr), query, time.Now(), opts) + logger := log.NewLogfmtLogger(os.Stdout) + logger = log.With(logger, "ts", log.DefaultTimestampUTC) + testutil.Ok(t, runutil.RetryWithLog(logger, time.Second, ctx.Done(), func() error { + res, warnings, err := promclient.NewDefaultClient().QueryInstant(ctx, urlParse(t, "http://"+addr), q, time.Now(), opts) if err != nil { return err } if len(warnings) > 0 { - // we don't expect warnings. return errors.Errorf("unexpected warnings %s", warnings) } - if len(result) != len(res) { - fmt.Println("queryAndAssert: New result:", res) - } - - if len(res) != len(expected) { - return errors.Errorf("unexpected result size, expected %d; result: %v", len(expected), res) + if len(res) != expectedSeriesLen { + return errors.Errorf("unexpected result size, expected %d; result %d: %v", expectedSeriesLen, len(res), res) } result = res return nil })) - sortResults(result) + return result +} + +func queryAndAssertSeries(t *testing.T, ctx context.Context, addr string, q string, opts promclient.QueryOptions, expected []model.Metric) { + t.Helper() + + result := instantQuery(t, ctx, addr, q, opts, len(expected)) for i, exp := range expected { testutil.Equals(t, exp, result[i].Metric) } @@ -261,3 +267,14 @@ func ruleAndAssert(t *testing.T, ctx context.Context, addr string, typ string, e return nil })) } + +func queryAndAssert(t *testing.T, ctx context.Context, addr string, q string, opts promclient.QueryOptions, expected model.Vector) { + t.Helper() + + sortResults(expected) + result := instantQuery(t, ctx, addr, q, opts, len(expected)) + for _, r := range result { + r.Timestamp = 0 // Does not matter for us. + } + testutil.Equals(t, expected, result) +} diff --git a/test/e2e/receive_test.go b/test/e2e/receive_test.go index 29cbd49667..8386b454e6 100644 --- a/test/e2e/receive_test.go +++ b/test/e2e/receive_test.go @@ -73,7 +73,7 @@ func TestReceive(t *testing.T) { testutil.Ok(t, q.WaitSumMetrics(e2e.Equals(3), "thanos_store_nodes_grpc_connections")) - queryAndAssert(t, ctx, q.HTTPEndpoint(), queryUpWithoutInstance, promclient.QueryOptions{ + queryAndAssertSeries(t, ctx, q.HTTPEndpoint(), queryUpWithoutInstance, promclient.QueryOptions{ Deduplicate: false, }, []model.Metric{ { @@ -81,18 +81,21 @@ func TestReceive(t *testing.T) { "prometheus": "prom1", "receive": "2", "replica": "0", + "tenant_id": "default-tenant", }, { "job": "myself", "prometheus": "prom2", "receive": "1", "replica": "0", + "tenant_id": "default-tenant", }, { "job": "myself", "prometheus": "prom3", - "receive": "3", + "receive": "2", "replica": "0", + "tenant_id": "default-tenant", }, }) }) @@ -145,7 +148,7 @@ func TestReceive(t *testing.T) { testutil.Ok(t, q.WaitSumMetrics(e2e.Equals(3), "thanos_store_nodes_grpc_connections")) - queryAndAssert(t, ctx, q.HTTPEndpoint(), queryUpWithoutInstance, promclient.QueryOptions{ + queryAndAssertSeries(t, ctx, q.HTTPEndpoint(), queryUpWithoutInstance, promclient.QueryOptions{ Deduplicate: false, }, []model.Metric{ { @@ -153,18 +156,21 @@ func TestReceive(t *testing.T) { "prometheus": "prom1", "receive": "1", "replica": "0", + "tenant_id": "default-tenant", }, { "job": "myself", "prometheus": "prom1", "receive": "2", "replica": "0", + "tenant_id": "default-tenant", }, { "job": "myself", "prometheus": "prom1", "receive": "3", "replica": "0", + "tenant_id": "default-tenant", }, }) }) @@ -214,7 +220,7 @@ func TestReceive(t *testing.T) { testutil.Ok(t, q.WaitSumMetrics(e2e.Equals(2), "thanos_store_nodes_grpc_connections")) - queryAndAssert(t, ctx, q.HTTPEndpoint(), queryUpWithoutInstance, promclient.QueryOptions{ + queryAndAssertSeries(t, ctx, q.HTTPEndpoint(), queryUpWithoutInstance, promclient.QueryOptions{ Deduplicate: false, }, []model.Metric{ { @@ -222,12 +228,14 @@ func TestReceive(t *testing.T) { "prometheus": "prom1", "receive": "1", "replica": "0", + "tenant_id": "default-tenant", }, { "job": "myself", "prometheus": "prom1", "receive": "2", "replica": "0", + "tenant_id": "default-tenant", }, }) }) diff --git a/test/e2e/rule_test.go b/test/e2e/rule_test.go index 813ab20b27..12ac05297c 100644 --- a/test/e2e/rule_test.go +++ b/test/e2e/rule_test.go @@ -59,18 +59,44 @@ groups: severity: page annotations: summary: "I always complain and allow partial response in query." +` + testAlertRuleAddedLaterWebHandler = ` +groups: +- name: example + partial_response_strategy: "WARN" + rules: + - alert: TestAlert_HasBeenLoadedViaWebHandler + # It must be based on actual metric, otherwise call to StoreAPI would be not involved. + expr: absent(some_metric) + labels: + severity: page + annotations: + summary: "I always complain and I have been loaded via /-/reload." ` ) +func createRuleFile(t *testing.T, path, content string) { + t.Helper() + err := ioutil.WriteFile(path, []byte(content), 0666) + testutil.Ok(t, err) +} + func createRuleFiles(t *testing.T, dir string) { t.Helper() for i, rule := range []string{testAlertRuleAbortOnPartialResponse, testAlertRuleWarnOnPartialResponse} { - err := ioutil.WriteFile(filepath.Join(dir, fmt.Sprintf("rules-%d.yaml", i)), []byte(rule), 0666) - testutil.Ok(t, err) + createRuleFile(t, filepath.Join(dir, fmt.Sprintf("rules-%d.yaml", i)), rule) } } +func reloadRulesHTTP(t *testing.T, ctx context.Context, endpoint string) { + req, err := http.NewRequestWithContext(ctx, "POST", "http://"+endpoint+"/-/reload", ioutil.NopCloser(bytes.NewReader(nil))) + testutil.Ok(t, err) + resp, err := http.DefaultClient.Do(req) + testutil.Ok(t, err) + testutil.Equals(t, 200, resp.StatusCode) +} + func writeTargets(t *testing.T, path string, addrs ...string) { t.Helper() @@ -179,8 +205,6 @@ func (m *mockAlertmanager) ServeHTTP(resp http.ResponseWriter, req *http.Request func TestRule_AlertmanagerHTTPClient(t *testing.T) { t.Skip("TODO: Allow HTTP ports from binaries running on host to be accessible.") - t.Parallel() - s, err := e2e.NewScenario("e2e_test_rule_am_http_client") testutil.Ok(t, err) defer s.Close() @@ -271,10 +295,14 @@ func TestRule(t *testing.T) { testutil.Ok(t, err) defer s.Close() + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute) + defer cancel() + // Prepare work dirs. rulesSubDir := filepath.Join("rules") - testutil.Ok(t, os.MkdirAll(filepath.Join(s.SharedDir(), rulesSubDir), os.ModePerm)) - createRuleFiles(t, filepath.Join(s.SharedDir(), rulesSubDir)) + rulesPath := filepath.Join(s.SharedDir(), rulesSubDir) + testutil.Ok(t, os.MkdirAll(rulesPath, os.ModePerm)) + createRuleFiles(t, rulesPath) amTargetsSubDir := filepath.Join("rules_am_targets") testutil.Ok(t, os.MkdirAll(filepath.Join(s.SharedDir(), amTargetsSubDir), os.ModePerm)) queryTargetsSubDir := filepath.Join("rules_query_targets") @@ -312,7 +340,7 @@ func TestRule(t *testing.T) { { // FileSD which will be used to register discover dynamically q. Files: []string{filepath.Join(e2e.ContainerSharedDir, queryTargetsSubDir, "*.yaml")}, - RefreshInterval: model.Duration(time.Hour), + RefreshInterval: model.Duration(time.Second), }, }, Scheme: "http", @@ -435,10 +463,15 @@ func TestRule(t *testing.T) { testutil.Ok(t, r.WaitSumMetrics(e2e.Equals(1), "thanos_ruler_alertmanagers_dns_provider_results")) }) - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) - defer cancel() + t.Run("reload works", func(t *testing.T) { + // Add a new rule via /-/reload. + // TODO(GiedriusS): add a test for reloading via SIGHUP. Need to extend e2e framework to expose PIDs. - queryAndAssert(t, ctx, q.HTTPEndpoint(), "ALERTS", promclient.QueryOptions{ + createRuleFile(t, fmt.Sprintf("%s/newrule.yaml", rulesPath), testAlertRuleAddedLaterWebHandler) + reloadRulesHTTP(t, ctx, r.HTTPEndpoint()) + }) + + queryAndAssertSeries(t, ctx, q.HTTPEndpoint(), "ALERTS", promclient.QueryOptions{ Deduplicate: false, }, []model.Metric{ { @@ -448,6 +481,13 @@ func TestRule(t *testing.T) { "alertstate": "firing", "replica": "1", }, + { + "__name__": "ALERTS", + "severity": "page", + "alertname": "TestAlert_HasBeenLoadedViaWebHandler", + "alertstate": "firing", + "replica": "1", + }, { "__name__": "ALERTS", "severity": "page", @@ -463,6 +503,11 @@ func TestRule(t *testing.T) { "alertname": "TestAlert_AbortOnPartialResponse", "replica": "1", }, + { + "severity": "page", + "alertname": "TestAlert_HasBeenLoadedViaWebHandler", + "replica": "1", + }, { "severity": "page", "alertname": "TestAlert_WarnOnPartialResponse", diff --git a/test/e2e/store_gateway_test.go b/test/e2e/store_gateway_test.go index 00b8cf8d3d..55d3b7ef81 100644 --- a/test/e2e/store_gateway_test.go +++ b/test/e2e/store_gateway_test.go @@ -5,6 +5,7 @@ package e2e_test import ( "context" + "net/http" "os" "path" "path/filepath" @@ -56,6 +57,8 @@ func TestStoreGateway(t *testing.T) { }) testutil.Ok(t, err) testutil.Ok(t, s.StartAndWaitReady(s1)) + // Ensure bucket UI. + ensureGETStatusCode(t, http.StatusOK, "http://"+path.Join(s1.HTTPEndpoint(), "loaded")) q, err := e2ethanos.NewQuerier(s.SharedDir(), "1", []string{s1.GRPCNetworkEndpoint()}, nil, nil) testutil.Ok(t, err) @@ -100,14 +103,14 @@ func TestStoreGateway(t *testing.T) { // Wait for store to sync blocks. // thanos_blocks_meta_synced: 2x loadedMeta 1x labelExcludedMeta 1x TooFreshMeta. testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(4), "thanos_blocks_meta_synced")) - testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_thanos_blocks_meta_sync_failures_total")) + testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(0), "thanos_blocks_meta_sync_failures_total")) testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(2), "thanos_bucket_store_blocks_loaded")) testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(0), "thanos_bucket_store_block_drops_total")) testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(0), "thanos_bucket_store_block_load_failures_total")) t.Run("query works", func(t *testing.T) { - queryAndAssert(t, ctx, q.HTTPEndpoint(), "{a=\"1\"}", + queryAndAssertSeries(t, ctx, q.HTTPEndpoint(), "{a=\"1\"}", promclient.QueryOptions{ Deduplicate: false, }, @@ -132,7 +135,7 @@ func TestStoreGateway(t *testing.T) { testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(6), "thanos_bucket_store_series_data_fetched")) testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(2), "thanos_bucket_store_series_blocks_queried")) - queryAndAssert(t, ctx, q.HTTPEndpoint(), "{a=\"1\"}", + queryAndAssertSeries(t, ctx, q.HTTPEndpoint(), "{a=\"1\"}", promclient.QueryOptions{ Deduplicate: true, }, @@ -162,7 +165,7 @@ func TestStoreGateway(t *testing.T) { testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(0), "thanos_bucket_store_block_load_failures_total")) // TODO(bwplotka): Entries are still in LRU cache. - queryAndAssert(t, ctx, q.HTTPEndpoint(), "{a=\"1\"}", + queryAndAssertSeries(t, ctx, q.HTTPEndpoint(), "{a=\"1\"}", promclient.QueryOptions{ Deduplicate: false, }, @@ -191,7 +194,7 @@ func TestStoreGateway(t *testing.T) { testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(1), "thanos_bucket_store_block_drops_total")) testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(0), "thanos_bucket_store_block_load_failures_total")) - queryAndAssert(t, ctx, q.HTTPEndpoint(), "{a=\"1\"}", + queryAndAssertSeries(t, ctx, q.HTTPEndpoint(), "{a=\"1\"}", promclient.QueryOptions{ Deduplicate: false, }, @@ -224,7 +227,7 @@ func TestStoreGateway(t *testing.T) { testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(1+1), "thanos_bucket_store_block_drops_total")) testutil.Ok(t, s1.WaitSumMetrics(e2e.Equals(0), "thanos_bucket_store_block_load_failures_total")) - queryAndAssert(t, ctx, q.HTTPEndpoint(), "{a=\"1\"}", + queryAndAssertSeries(t, ctx, q.HTTPEndpoint(), "{a=\"1\"}", promclient.QueryOptions{ Deduplicate: false, }, diff --git a/tutorials/katacoda/thanos/1-globalview/courseBase.sh b/tutorials/katacoda/thanos/1-globalview/courseBase.sh index 6bda9cb811..50febd39ec 100644 --- a/tutorials/katacoda/thanos/1-globalview/courseBase.sh +++ b/tutorials/katacoda/thanos/1-globalview/courseBase.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash -docker pull quay.io/prometheus/prometheus:v2.14.0 -docker pull quay.io/thanos/thanos:v0.10.0 +docker pull quay.io/prometheus/prometheus:v2.16.0 +docker pull quay.io/thanos/thanos:v0.12.2 diff --git a/tutorials/katacoda/thanos/1-globalview/step2.md b/tutorials/katacoda/thanos/1-globalview/step2.md index 4982909dfe..053f081e7b 100644 --- a/tutorials/katacoda/thanos/1-globalview/step2.md +++ b/tutorials/katacoda/thanos/1-globalview/step2.md @@ -10,7 +10,7 @@ component and can be invoked in a single command. Let's take a look at all the Thanos commands: ``` -docker run --rm quay.io/thanos/thanos:v0.10.0 --help +docker run --rm quay.io/thanos/thanos:v0.12.2 --help ```{{execute}} You should see multiple commands that solves different purposes. @@ -53,7 +53,7 @@ docker run -d --net=host --rm \ -v $(pwd)/prometheus0_eu1.yml:/etc/prometheus/prometheus.yml \ --name prometheus-0-sidecar-eu1 \ -u root \ - quay.io/thanos/thanos:v0.10.0 \ + quay.io/thanos/thanos:v0.12.2 \ sidecar \ --http-address 0.0.0.0:19090 \ --grpc-address 0.0.0.0:19190 \ @@ -68,7 +68,7 @@ docker run -d --net=host --rm \ -v $(pwd)/prometheus0_us1.yml:/etc/prometheus/prometheus.yml \ --name prometheus-0-sidecar-us1 \ -u root \ - quay.io/thanos/thanos:v0.10.0 \ + quay.io/thanos/thanos:v0.12.2 \ sidecar \ --http-address 0.0.0.0:19091 \ --grpc-address 0.0.0.0:19191 \ @@ -81,7 +81,7 @@ docker run -d --net=host --rm \ -v $(pwd)/prometheus1_us1.yml:/etc/prometheus/prometheus.yml \ --name prometheus-1-sidecar-us1 \ -u root \ - quay.io/thanos/thanos:v0.10.0 \ + quay.io/thanos/thanos:v0.12.2 \ sidecar \ --http-address 0.0.0.0:19092 \ --grpc-address 0.0.0.0:19192 \ diff --git a/tutorials/katacoda/thanos/1-globalview/step3.md b/tutorials/katacoda/thanos/1-globalview/step3.md index cbe7d5f192..3f46d86bc1 100644 --- a/tutorials/katacoda/thanos/1-globalview/step3.md +++ b/tutorials/katacoda/thanos/1-globalview/step3.md @@ -28,7 +28,7 @@ Click below snippet to start the Querier. ``` docker run -d --net=host --rm \ --name querier \ - quay.io/thanos/thanos:v0.10.0 \ + quay.io/thanos/thanos:v0.12.2 \ query \ --http-address 0.0.0.0:29090 \ --query.replica-label replica \ @@ -55,7 +55,7 @@ It's just enough to query Querier for `sum(prometheus_tsdb_head_series)` +Try to query the same query as before: `prometheus_tsdb_head_series` Now turn off deduplication (`deduplication` button on Querier UI) and hit `Execute` again. Now you should see 5 results: diff --git a/website/data/adopters.yml b/website/data/adopters.yml index c0a498564a..2c472181c6 100644 --- a/website/data/adopters.yml +++ b/website/data/adopters.yml @@ -3,8 +3,8 @@ adopters: - name: Monzo url: https://www.monzo.com logo: monzo.png -- name: Utility Warehouse - url: https://www.utilitywarehouse.co.uk +- name: UW + url: https://uw.co.uk/ logo: utilitywarehouse.png - name: Adform url: https://site.adform.com @@ -15,7 +15,7 @@ adopters: - name: tiket.com url: https://www.tiket.com logo: tiket.png -- name: uSwitch +- name: Uswitch url: https://www.uswitch.com logo: uswitch.png - name: Qonto @@ -90,3 +90,12 @@ adopters: - name: Ozon url: https://www.ozon.ru logo: ozon.png +- name: MALL Group + url: https://www.mallgroup.com/ + logo: mallgroup.png +- name: leboncoin + url: https://www.leboncoin.fr/ + logo: leboncoin.png +- name: Workfront + url: https://www.workfront.com/ + logo: workfront.png \ No newline at end of file diff --git a/website/layouts/_default/list.html b/website/layouts/_default/list.html new file mode 100644 index 0000000000..792dcb15af --- /dev/null +++ b/website/layouts/_default/list.html @@ -0,0 +1,21 @@ +{{ define "main" }} +
+
+
+ {{ partial "_default/sidemenu.html" . }} +
+
+

{{ .Title }}

+
    + + {{ range .Pages }} +
  • +

    {{.Title}}

    +
  • + {{ end }} +
+ {{ replace .Content "" "
" | safeHTML }} + + + +{{ end }} diff --git a/website/layouts/index.html b/website/layouts/index.html index ffb4d7f183..9767ab6dac 100644 --- a/website/layouts/index.html +++ b/website/layouts/index.html @@ -14,6 +14,11 @@

Open source, highly available Prometheus setup with long term s Getting Started +
  • + + Community + +
  • Download @@ -102,9 +107,14 @@

    Used By

    -

    Join the community !

    +

    Join the community !

    Join users and companies that are using Thanos in production.

      +
    • + + Community Meetings + +
    • Slack diff --git a/website/layouts/partials/_default/sidemenu.html b/website/layouts/partials/_default/sidemenu.html index bf45f265ff..8c9e373922 100644 --- a/website/layouts/partials/_default/sidemenu.html +++ b/website/layouts/partials/_default/sidemenu.html @@ -5,34 +5,64 @@ \ No newline at end of file + diff --git a/website/static/expand.svg b/website/static/expand.svg new file mode 100644 index 0000000000..e98e7b97f0 --- /dev/null +++ b/website/static/expand.svg @@ -0,0 +1,4 @@ + + + + diff --git a/website/static/logos/leboncoin.png b/website/static/logos/leboncoin.png new file mode 100755 index 0000000000..04469dd76b Binary files /dev/null and b/website/static/logos/leboncoin.png differ diff --git a/website/static/logos/mallgroup.png b/website/static/logos/mallgroup.png new file mode 100644 index 0000000000..82d47b2ed2 Binary files /dev/null and b/website/static/logos/mallgroup.png differ diff --git a/website/static/logos/uswitch.png b/website/static/logos/uswitch.png index c3dedbedd1..68434837f3 100644 Binary files a/website/static/logos/uswitch.png and b/website/static/logos/uswitch.png differ diff --git a/website/static/logos/utilitywarehouse.png b/website/static/logos/utilitywarehouse.png index cc2a1a5bda..6c63094f9e 100644 Binary files a/website/static/logos/utilitywarehouse.png and b/website/static/logos/utilitywarehouse.png differ diff --git a/website/static/logos/workfront.png b/website/static/logos/workfront.png new file mode 100644 index 0000000000..a0ad765f91 Binary files /dev/null and b/website/static/logos/workfront.png differ diff --git a/website/static/main.css b/website/static/main.css index 3124bd995e..3d39d261be 100644 --- a/website/static/main.css +++ b/website/static/main.css @@ -70,4 +70,36 @@ pre { } .header-anchor { font-size: 100%; visibility: hidden;} -h1:hover a, h2:hover a, h3:hover a, h4:hover a { visibility: visible} \ No newline at end of file +h1:hover a, h2:hover a, h3:hover a, h4:hover a { visibility: visible} + +/* SideMenu Collapse */ +.menuinput { + display: none; +} + +.menulabel-thanos { + cursor: pointer; + display: flex; + align-items: center; +} + +.caret-expand { + width: 16px; + margin-left: 8px; + margin-bottom: 0.2rem; + transition: transform 0.2s ease-out; +} + +.menuinput:checked + label .caret-expand { + transform: rotateX(180deg); +} + +.sidemenu-thanos .list-group { + transform: scaleY(0); + height: 0; +} + +.menuinput:checked ~ .list-group { + transform: scaleY(1); + height: auto; +}