pax_global_header00006660000000000000000000000064147335572620014530gustar00rootroot0000000000000052 comment=dd965dce22e5278d4935bea923441ecde31b5325 python-msgspec-0.19.0/000077500000000000000000000000001473355726200145775ustar00rootroot00000000000000python-msgspec-0.19.0/.codecov.yml000066400000000000000000000001721473355726200170220ustar00rootroot00000000000000comment: false coverage: status: project: default: target: auto threshold: 1% patch: off python-msgspec-0.19.0/.gitattributes000066400000000000000000000000411473355726200174650ustar00rootroot00000000000000msgspec/_version.py export-subst python-msgspec-0.19.0/.github/000077500000000000000000000000001473355726200161375ustar00rootroot00000000000000python-msgspec-0.19.0/.github/CODE_OF_CONDUCT.md000066400000000000000000000062121473355726200207370ustar00rootroot00000000000000# Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jcristharif@gmail.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ python-msgspec-0.19.0/.github/CONTRIBUTING.md000066400000000000000000000060451473355726200203750ustar00rootroot00000000000000# How to Contribute Thank you for taking the time to contribute to `msgspec`! Here we document some contribution guidelines to help you ensure that your contribution is at its best. ## Setting up your Development Environment Before getting started, you will need to already have installed: - Python (3.8+ only), with development headers installed - A C compiler (`gcc`, `clang`, and `msvc` are all tested) - `git` Once you have those installed, you're ready to: - Clone the repository - Install all development dependencies - Build a development version of `msgspec` - Install the `pre-commit` hooks ```bash # Clone the repository git clone https://github.com/jcrist/msgspec.git # cd into the repo root directory cd msgspec/ # Build and install msgspec & all dev dependencies pip install -e ".[dev]" # Install the pre-commit hooks pre-commit install ``` ## Editing and Rebuilding You now have a "development" build of `msgspec` installed. This means that you can make changes to the `.py` files and test them without requiring a rebuild of msgspec's C extension. Edit away! If you do make changes to a `.c` file, you'll need to recompile. You can do this by running ```bash pip install -e . ``` By default `msgspec` is built in release mode, with optimizations enabled. To build a debug build instead (for use with e.g. `gdb` or `lldb`) define the `MSGSPEC_DEBUG` environment variable before building. ```bash MSGSPEC_DEBUG=1 pip install -e . ``` ## Testing Tests are located in the `tests/` directory. Any code changes should include additional tests to ensure correctness. The tests are broken into various `test_*.py` files specific to the functionality that they're testing. The tests can be run using `pytest` as follows: ```bash pytest ``` If you want to run a specific test file, you may specify that file explicitly: ```bash pytest tests/test_json.py ``` ## Linting We use `pre-commit` to automatically run a few code linters before every commit. If you followed the development setup above, you should already have `pre-commit` and all the commit hooks installed. These hooks will run whenever you try to commit changes. ```bash git commit # linters will run automatically here ``` If you wish to run the linters manually without committing, you can run: ```bash pre-commit run ``` ## Documentation The source of the documentation can be found under `docs/source/`. They are built using `Sphinx` and can be built locally by running the following steps: ```bash cd docs/ # Make sure we are in the docs/ folder make html # Build the html # Output can now be found under docs/build/html and can be viewed in the browser ``` ## Continuous Integration (CI) We use GitHub Actions to provide "continuous integration" testing for all Pull Requests (PRs). When submitting a PR, please check to see that all tests pass, and fix any issues that come up. ## Code of Conduct ``msgspec`` has a code of conduct that must be followed by all contributors to the project. You may read the code of conduct [here](https://github.com/jcrist/msgspec/blob/main/CODE_OF_CONDUCT.md). python-msgspec-0.19.0/.github/ISSUE_TEMPLATE/000077500000000000000000000000001473355726200203225ustar00rootroot00000000000000python-msgspec-0.19.0/.github/ISSUE_TEMPLATE/bug.yml000066400000000000000000000015231473355726200216230ustar00rootroot00000000000000name: 🪲 Bug Report description: Report a bug or unexpected behavior in msgspec body: - type: markdown attributes: value: Thanks for taking the time to fill out a bug report! - type: textarea id: description attributes: label: Description description: > Describe the bug. What happened? What did you expect to happen? When possible, please also include a [minimal, complete, verifiable example](https://stackoverflow.com/help/minimal-reproducible-example). Ideally this should be code that can be run without modification to demonstrate the problem. When including errors and tracebacks, please include the _full traceback_ as well as the code that generated the error (or at least the line that caused it). validations: required: true python-msgspec-0.19.0/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000000331473355726200223060ustar00rootroot00000000000000blank_issues_enabled: true python-msgspec-0.19.0/.github/ISSUE_TEMPLATE/feature.yml000066400000000000000000000014041473355726200224770ustar00rootroot00000000000000name: 🙌 Feature Request description: Suggest a new feature or change to msgspec body: - type: markdown attributes: value: Thanks for taking the time to fill out a feature request! - type: textarea id: description attributes: label: Description description: > Describe the feature. What problems does it solve? If the feature is to related to a problem, please describe in detail your use case. What would this new feature help you do that you couldn't do before? Why is this useful? When relevant, please also include example code making use of your proposed feature. How would you use this feature? What would code using it look like? validations: required: true python-msgspec-0.19.0/.github/ISSUE_TEMPLATE/question.yml000066400000000000000000000007031473355726200227140ustar00rootroot00000000000000name: ❓ Question description: Ask a question body: - type: markdown attributes: value: Thanks for taking the time to ask a question! - type: textarea id: description attributes: label: Question description: > Ask your question here. Please search through existing and closed issues first to ensure your question hasn't already been answered elsewhere. validations: required: true python-msgspec-0.19.0/.github/SECURITY.md000066400000000000000000000012331473355726200177270ustar00rootroot00000000000000# Security Policy If you believe you have found a security-related bug with `msgspec`, **do not open a public GitHub issue**. Instead, please email jcristharif@gmail.com. Please include as much detail as you would for a normal issue in your report. In particular, including a minimal reproducible example will help the maintainers diagnose and resolve the issue quickly and efficiently. After the issue is resolved, we will make a release and announce the security fix through our normal communication channels. When it makes sense we may also obtain a CVE ID. If you would like to be credited with the report, please include your name and any links in the email. python-msgspec-0.19.0/.github/workflows/000077500000000000000000000000001473355726200201745ustar00rootroot00000000000000python-msgspec-0.19.0/.github/workflows/ci.yml000066400000000000000000000076611473355726200213240ustar00rootroot00000000000000name: Build and Test on: push: branches: [main] pull_request: branches: [main] paths-ignore: - "docs/**" - "benchmarks/**" - "examples/**" - ".github/**" - "README.rst" release: types: [published] jobs: lint: name: Lint and ruff code runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Build msgspec and install dependencies run: | pip install -e ".[dev]" - name: Run pre-commit hooks uses: pre-commit/action@v3.0.0 - name: mypy run: pytest tests/test_mypy.py - name: pyright run: pytest tests/test_pyright.py - name: doctests run: pytest --doctest-modules msgspec - name: Rebuild with sanitizers & coverage env: MSGSPEC_SANITIZE: "true" MSGSPEC_COVERAGE: "true" run: | python setup.py clean --all # I know this is deprecated, but I can't find a way to keep the build # directory around anymore on new versions of setuptools python setup.py develop - name: Run tests with sanitizers env: PYTHONMALLOC: "malloc" ASAN_OPTIONS: "detect_leaks=0" run: | LD_PRELOAD=`gcc -print-file-name=libasan.so` coverage run -m pytest -s -m "not mypy and not pyright" - name: Generate coverage files run: | coverage xml gcov -abcu `find build/ -name *.o` - name: Upload Codecov uses: codecov/codecov-action@v3 with: files: coverage.xml,_core.c.gcov,atof.h.gcov,ryu.h.gcov build_wheels: name: Build wheels on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-13, windows-latest] env: CIBW_TEST_EXTRAS: "test" CIBW_TEST_COMMAND: "pytest {project}/tests" CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-* cp313-*" CIBW_SKIP: "*-win32 *_i686 *_s390x *_ppc64le" CIBW_ARCHS_MACOS: "x86_64 arm64" CIBW_ARCHS_LINUX: "x86_64 aarch64" CIBW_TEST_SKIP: "*_arm64 *-musllinux_*" CIBW_ENVIRONMENT: "CFLAGS=-g0" steps: - uses: actions/checkout@v4 - name: Set up QEMU if: runner.os == 'Linux' uses: docker/setup-qemu-action@v1 with: platforms: all - name: Set up Environment if: github.event_name != 'release' run: | echo "CIBW_SKIP=${CIBW_SKIP} *-musllinux_* cp39-*_aarch64 cp311-*_aarch64 cp312-*_aarch64 cp313-*_aarch64" >> $GITHUB_ENV - name: Build & Test Wheels uses: pypa/cibuildwheel@v2.22.0 - name: Upload artifact uses: actions/upload-artifact@v4 if: github.event_name == 'release' && github.event.action == 'published' with: name: artifact-wheels-${{ matrix.os }} path: ./wheelhouse/*.whl build_sdist: name: Build Source Distribution runs-on: ubuntu-latest if: github.event_name == 'release' && github.event.action == 'published' steps: - uses: actions/checkout@v4 - name: Install Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Build source distribution run: python setup.py sdist - name: Upload artifact uses: actions/upload-artifact@v4 with: name: artifact-sdist path: dist/*.tar.gz upload_pypi: needs: [build_wheels, build_sdist] runs-on: ubuntu-latest permissions: id-token: write if: github.event_name == 'release' && github.event.action == 'published' steps: - uses: actions/download-artifact@v4 with: merge-multiple: true path: dist pattern: artifact-* - name: Publish package distributions to PyPI uses: pypa/gh-action-pypi-publish@release/v1 python-msgspec-0.19.0/.github/workflows/docs.yml000066400000000000000000000012661473355726200216540ustar00rootroot00000000000000name: documentation on: push: branches: [main] pull_request: null jobs: build-docs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install Python uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install msgspec and dependencies run: | pip install -e ".[doc]" - name: Build Docs run: | pushd docs make html popd - name: Deploy uses: peaceiris/actions-gh-pages@v3 if: github.ref == 'refs/heads/main' with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./docs/build/html python-msgspec-0.19.0/.gitignore000066400000000000000000000010201473355726200165600ustar00rootroot00000000000000# Editor config folders ## Vscode .settings/ .project .vscode/ .vs/ ## PyCharm/IntelliJ-generated files *.iml .idea/ # Python cached sources __pycache__/ *.pyc # Virtual environments .venv*/ venv*/ # Pytest and coverage .coverage .pytest/ .pytest_cache/ htmlcov/ # Mypy Cache .mypy_cache/ # Docs build docs/build/ # Benchmark outputs benchmarks/*.html benchmarks/*.json # Setuptools/twine-generated files, compiled sources. build/ dist/ *.egg-info/ pip-wheel-metadata/ *.so *.o *.pyd # Misc *.pem out/ .cache/ .DS_Store python-msgspec-0.19.0/.pre-commit-config.yaml000066400000000000000000000004471473355726200210650ustar00rootroot00000000000000repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.7.1 hooks: - id: ruff args: [ --fix ] - id: ruff-format - repo: https://github.com/codespell-project/codespell rev: v2.2.2 hooks: - id: codespell language_version: python3 python-msgspec-0.19.0/LICENSE000066400000000000000000000027321473355726200156100ustar00rootroot00000000000000Copyright (c) 2021, Jim Crist-Harif All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. python-msgspec-0.19.0/MANIFEST.in000066400000000000000000000003111473355726200163300ustar00rootroot00000000000000include msgspec/*.c include msgspec/*.h include msgspec/*.py include msgspec/*.pyi include msgspec/py.typed include setup.py include versioneer.py include README.md include LICENSE include MANIFEST.in python-msgspec-0.19.0/README.md000066400000000000000000000105111473355726200160540ustar00rootroot00000000000000

msgspec

`msgspec` is a *fast* serialization and validation library, with builtin support for [JSON](https://json.org), [MessagePack](https://msgpack.org), [YAML](https://yaml.org), and [TOML](https://toml.io). It features: - 🚀 **High performance encoders/decoders** for common protocols. The JSON and MessagePack implementations regularly [benchmark](https://jcristharif.com/msgspec/benchmarks.html) as the fastest options for Python. - 🎉 **Support for a wide variety of Python types**. Additional types may be supported through [extensions](https://jcristharif.com/msgspec/extending.html). - 🔍 **Zero-cost schema validation** using familiar Python type annotations. In [benchmarks](https://jcristharif.com/msgspec/benchmarks.html) `msgspec` decodes *and* validates JSON faster than [orjson](https://github.com/ijl/orjson) can decode it alone. - ✨ **A speedy Struct type** for representing structured data. If you already use [dataclasses](https://docs.python.org/3/library/dataclasses.html) or [attrs](https://www.attrs.org), [structs](https://jcristharif.com/msgspec/structs.html) should feel familiar. However, they're [5-60x faster](https://jcristharif.com/msgspec/benchmarks.html#benchmark-structs>) for common operations. All of this is included in a [lightweight library](https://jcristharif.com/msgspec/benchmarks.html#benchmark-library-size) with no required dependencies. --- `msgspec` may be used for serialization alone, as a faster JSON or MessagePack library. For the greatest benefit though, we recommend using `msgspec` to handle the full serialization & validation workflow: **Define** your message schemas using standard Python type annotations. ```python >>> import msgspec >>> class User(msgspec.Struct): ... """A new type describing a User""" ... name: str ... groups: set[str] = set() ... email: str | None = None ``` **Encode** messages as JSON, or one of the many other supported protocols. ```python >>> alice = User("alice", groups={"admin", "engineering"}) >>> alice User(name='alice', groups={"admin", "engineering"}, email=None) >>> msg = msgspec.json.encode(alice) >>> msg b'{"name":"alice","groups":["admin","engineering"],"email":null}' ``` **Decode** messages back into Python objects, with optional schema validation. ```python >>> msgspec.json.decode(msg, type=User) User(name='alice', groups={"admin", "engineering"}, email=None) >>> msgspec.json.decode(b'{"name":"bob","groups":[123]}', type=User) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str`, got `int` - at `$.groups[0]` ``` `msgspec` is designed to be as performant as possible, while retaining some of the nicities of validation libraries like [pydantic](https://pydantic-docs.helpmanual.io/). For supported types, encoding/decoding a message with `msgspec` can be [~10-80x faster than alternative libraries](https://jcristharif.com/msgspec/benchmarks.html).

See [the documentation](https://jcristharif.com/msgspec/) for more information. ## LICENSE New BSD. See the [License File](https://github.com/jcrist/msgspec/blob/main/LICENSE). python-msgspec-0.19.0/benchmarks/000077500000000000000000000000001473355726200167145ustar00rootroot00000000000000python-msgspec-0.19.0/benchmarks/__init__.py000066400000000000000000000000001473355726200210130ustar00rootroot00000000000000python-msgspec-0.19.0/benchmarks/bench_encodings.py000066400000000000000000000130351473355726200224000ustar00rootroot00000000000000from __future__ import annotations import sys import dataclasses import json import timeit import importlib.metadata from typing import Any, Literal, Callable from .generate_data import make_filesystem_data import msgspec class File(msgspec.Struct, kw_only=True, omit_defaults=True, tag="file"): name: str created_by: str created_at: str updated_by: str | None = None updated_at: str | None = None nbytes: int permissions: Literal["READ", "WRITE", "READ_WRITE"] class Directory(msgspec.Struct, kw_only=True, omit_defaults=True, tag="directory"): name: str created_by: str created_at: str updated_by: str | None = None updated_at: str | None = None contents: list[File | Directory] @dataclasses.dataclass class Benchmark: label: str version: str encode: Callable decode: Callable schema: Any = None def run(self, data: bytes) -> dict: if self.schema is not None: data = msgspec.convert(data, self.schema) timer = timeit.Timer("func(data)", globals={"func": self.encode, "data": data}) n, t = timer.autorange() encode_time = t / n data = self.encode(data) timer = timeit.Timer("func(data)", globals={"func": self.decode, "data": data}) n, t = timer.autorange() decode_time = t / n return { "label": self.label, "encode": encode_time, "decode": decode_time, } def json_benchmarks(): import orjson import ujson import rapidjson import simdjson simdjson_ver = importlib.metadata.version("pysimdjson") rj_dumps = rapidjson.Encoder() rj_loads = rapidjson.Decoder() def uj_dumps(obj): return ujson.dumps(obj) enc = msgspec.json.Encoder() dec = msgspec.json.Decoder(Directory) dec2 = msgspec.json.Decoder() return [ Benchmark("msgspec structs", None, enc.encode, dec.decode, Directory), Benchmark("msgspec", msgspec.__version__, enc.encode, dec2.decode), Benchmark("json", None, json.dumps, json.loads), Benchmark("orjson", orjson.__version__, orjson.dumps, orjson.loads), Benchmark("ujson", ujson.__version__, uj_dumps, ujson.loads), Benchmark("rapidjson", rapidjson.__version__, rj_dumps, rj_loads), Benchmark("simdjson", simdjson_ver, simdjson.dumps, simdjson.loads), ] def msgpack_benchmarks(): import msgpack import ormsgpack enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Directory) dec2 = msgspec.msgpack.Decoder() return [ Benchmark("msgspec structs", None, enc.encode, dec.decode, Directory), Benchmark("msgspec", msgspec.__version__, enc.encode, dec2.decode), Benchmark("msgpack", msgpack.__version__, msgpack.dumps, msgpack.loads), Benchmark( "ormsgpack", ormsgpack.__version__, ormsgpack.packb, ormsgpack.unpackb ), ] def main(): import argparse parser = argparse.ArgumentParser( description="Benchmark different python serialization libraries" ) parser.add_argument( "--versions", action="store_true", help="Output library version info, and exit immediately", ) parser.add_argument( "-n", type=int, help="The number of objects in the generated data, defaults to 1000", default=1000, ) parser.add_argument( "-p", "--protocol", choices=["json", "msgpack"], default="json", help="The protocol to benchmark, defaults to JSON", ) parser.add_argument( "--json", action="store_true", help="whether to output the results as json", ) args = parser.parse_args() benchmarks = json_benchmarks() if args.protocol == "json" else msgpack_benchmarks() if args.versions: for bench in benchmarks: if bench.version is not None: print(f"- {bench.label}: {bench.version}") sys.exit(0) data = make_filesystem_data(args.n) results = [benchmark.run(data) for benchmark in benchmarks] if args.json: for line in results: print(json.dumps(line)) else: # Compose the results table results.sort(key=lambda row: row["encode"] + row["decode"]) best_et = results[0]["encode"] best_dt = results[0]["decode"] best_tt = best_et + best_dt columns = ( "", "encode (μs)", "vs.", "decode (μs)", "vs.", "total (μs)", "vs.", ) rows = [ ( r["label"], f"{1_000_000 * r['encode']:.1f}", f"{r['encode'] / best_et:.1f}", f"{1_000_000 * r['decode']:.1f}", f"{r['decode'] / best_dt:.1f}", f"{1_000_000 * (r['encode'] + r['decode']):.1f}", f"{(r['encode'] + r['decode']) / best_tt:.1f}", ) for r in results ] widths = tuple( max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns) ) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) print("\n".join(parts)) if __name__ == "__main__": main() python-msgspec-0.19.0/benchmarks/bench_gc.py000066400000000000000000000053751473355726200210300ustar00rootroot00000000000000"""This file benchmarks GC collection time for a large number of tiny dataclass-like instances. For each type, the following is measured: - Time for a single full GC pass over all the data. - Amount of memory used to hold all the data """ import gc import sys import time import msgspec def sizeof(x, _seen=None): """Get the recursive sizeof for an object (memoized). Not generic, works on types used in this benchmark. """ if _seen is None: _seen = set() _id = id(x) if _id in _seen: return 0 _seen.add(_id) size = sys.getsizeof(x) if isinstance(x, dict): for k, v in x.items(): size += sizeof(k, _seen) size += sizeof(v, _seen) if hasattr(x, "__dict__"): size += sizeof(x.__dict__, _seen) if hasattr(x, "__slots__"): for k in x.__slots__: size += sizeof(k, _seen) size += sizeof(getattr(x, k), _seen) return size class Point(msgspec.Struct): x: int y: int z: int class PointGCFalse(msgspec.Struct, gc=False): x: int y: int z: int class PointClass: def __init__(self, x, y, z): self.x = x self.y = y self.z = z class PointClassSlots: __slots__ = ("x", "y", "z") def __init__(self, x, y, z): self.x = x self.y = y self.z = z def bench_gc(cls): # Allocate a dict of structs data = {i: cls(i, i, i) for i in range(1_000_000)} # Run a full collection start = time.perf_counter() gc.collect() stop = time.perf_counter() gc_time = (stop - start) * 1e3 mibytes = sizeof(data) / (2**20) return gc_time, mibytes def format_table(results): columns = ("", "GC time (ms)", "Memory Used (MiB)") rows = [] for name, t, mem in results: rows.append((f"**{name}**", f"{t:.2f}", f"{mem:.2f}")) widths = tuple(max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns)) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) return "\n".join(parts) def main(): results = [] for name, cls in [ ("standard class", PointClass), ("standard class with __slots__", PointClassSlots), ("msgspec struct", Point), ("msgspec struct with gc=False", PointGCFalse), ]: print(f"Benchmarking {name}...") gc_time, mibytes = bench_gc(cls) results.append((name, gc_time, mibytes)) print(format_table(results)) if __name__ == "__main__": main() python-msgspec-0.19.0/benchmarks/bench_large_json.py000066400000000000000000000101141473355726200225450ustar00rootroot00000000000000import subprocess import sys import tempfile import requests TEMPLATE = """ import resource import time with open({path!r}, "rb") as f: data = f.read() initial_rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss {setup} start = time.perf_counter() for _ in range(5): decode(data) stop = time.perf_counter() max_rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss # mem_mib = (max_rss * 1024 - len(data)) / (1024 * 1024) mem_mib = (max_rss - initial_rss) / 1024 time_ms = ((stop - start) / 5) * 1000 print([mem_mib, time_ms]) """ JSON = """ import json decode = json.loads """ UJSON = """ import ujson decode = ujson.loads """ ORJSON = """ import orjson decode = orjson.loads """ RAPIDJSON = """ import rapidjson decode = rapidjson.loads """ SIMDJSON = """ import simdjson decode = simdjson.loads """ MSGSPEC = """ import msgspec decode = msgspec.json.decode """ MSGSPEC_STRUCTS = """ import msgspec from typing import Union class Package(msgspec.Struct, gc=False): build: str build_number: int depends: tuple[str, ...] md5: str name: str sha256: str subdir: str version: str license: str = "" noarch: Union[str, bool, None] = None size: int = 0 timestamp: int = 0 class RepoData(msgspec.Struct, gc=False): repodata_version: int info: dict packages: dict[str, Package] removed: tuple[str, ...] decode = msgspec.json.Decoder(RepoData).decode """ def main(): import argparse parser = argparse.ArgumentParser( description="Benchmark decoding a large JSON message using various JSON libraries" ) parser.add_argument( "--versions", action="store_true", help="Output library version info, and exit immediately", ) args = parser.parse_args() benchmarks = [ ("json", None, JSON), ("ujson", "ujson", UJSON), ("orjson", "orjson", ORJSON), ("rapidjson", "python-rapidjson", RAPIDJSON), ("simdjson", "pysimdjson", SIMDJSON), ("msgspec", "msgspec", MSGSPEC), ("msgspec structs", None, MSGSPEC_STRUCTS), ] if args.versions: import importlib.metadata for _, lib, _ in benchmarks: if lib is not None: version = importlib.metadata.version(lib) print(f"- {lib}: {version}") sys.exit(0) with tempfile.NamedTemporaryFile() as f: # Download the repodata.json resp = requests.get( "https://conda.anaconda.org/conda-forge/noarch/repodata.json" ) resp.raise_for_status() f.write(resp.content) # Run the benchmark for each library results = {} import ast for lib, _, setup in benchmarks: script = TEMPLATE.format(path=f.name, setup=setup) # We execute each script in a subprocess to isolate their memory usage output = subprocess.check_output([sys.executable, "-c", script]) results[lib] = ast.literal_eval(output.decode()) # Compose the results table best_mem, best_time = results["msgspec structs"] columns = ( "", "memory (MiB)", "vs.", "time (ms)", "vs.", ) rows = [ ( f"**{lib}**", f"{mem:.1f}", f"{mem / best_mem:.1f}x", f"{time:.1f}", f"{time / best_time:.1f}x", ) for lib, (mem, time) in results.items() ] rows.sort(key=lambda x: float(x[1])) widths = tuple( max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns) ) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) print("\n".join(parts)) if __name__ == "__main__": main() python-msgspec-0.19.0/benchmarks/bench_library_size.py000066400000000000000000000064661473355726200231370ustar00rootroot00000000000000""" This benchmark compares the installed library size between msgspec and pydantic in a Python 3.10 x86 environment. """ import io import zipfile import requests def get_latest_noarch_wheel_size(library): """Get the total uncompressed size of the latest noarch wheel""" resp = requests.get(f"https://pypi.org/pypi/{library}/json").json() version = resp["info"]["version"] files = {} for file_info in resp["releases"][version]: name = file_info["filename"] url = file_info["url"] if name.endswith(".whl"): files[name] = url if len(files) != 1: raise ValueError( f"Expected to find only 1 matching file for {library}, got {list(files)}" ) url = list(files.values())[0] resp = requests.get(url) fil = io.BytesIO(resp.content) zfil = zipfile.ZipFile(fil) size = sum(f.file_size for f in zfil.filelist) return version, size def get_latest_manylinux_wheel_size(library): """Get the total uncompressed size of the latest Python 3.10 manylinux x86_64 wheel for the library""" resp = requests.get(f"https://pypi.org/pypi/{library}/json").json() version = resp["info"]["version"] files = {} for file_info in resp["releases"][version]: name = file_info["filename"] url = file_info["url"] if "310" in name and "manylinux_2_17_x86_64" in name and "pp73" not in name: files[name] = url if len(files) != 1: raise ValueError( f"Expected to find only 1 matching file for {library}, got {list(files)}" ) url = list(files.values())[0] resp = requests.get(url) fil = io.BytesIO(resp.content) zfil = zipfile.ZipFile(fil) size = sum(f.file_size for f in zfil.filelist) return version, size def main(): msgspec_version, msgspec_size = get_latest_manylinux_wheel_size("msgspec") pydantic_version, pydantic_size = get_latest_noarch_wheel_size("pydantic") _, pydantic_core_size = get_latest_manylinux_wheel_size("pydantic-core") _, typing_extensions_size = get_latest_noarch_wheel_size("typing-extensions") _, annotated_types_size = get_latest_noarch_wheel_size("annotated-types") data = [ ("msgspec", msgspec_version, msgspec_size), ( "pydantic", pydantic_version, pydantic_size + pydantic_core_size + typing_extensions_size + annotated_types_size, ), ] data.sort(key=lambda x: x[2]) msgspec_size = next(s for l, _, s in data if l == "msgspec") columns = ("", "version", "size (MiB)", "vs. msgspec") rows = [ ( f"**{lib}**", version, f"{size / (1024 * 1024):.2f}", f"{size / msgspec_size:.2f}x", ) for lib, version, size in data ] widths = tuple(max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns)) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) print("\n".join(parts)) if __name__ == "__main__": main() python-msgspec-0.19.0/benchmarks/bench_structs.py000066400000000000000000000122601473355726200221350ustar00rootroot00000000000000"""This file benchmarks dataclass-like libraries. It measures the following operations: - Time to import a new class definition - Time to create an instance of that class - Time to compare an instance of that class with another instance. """ from time import perf_counter order_template = """ def __{method}__(self, other): if type(self) is not type(other): return NotImplemented return ( (self.a, self.b, self.c, self.d, self.e) {op} (other.a, other.b, other.c, other.d, other.e) ) """ classes_template = """ import reprlib class C{n}: def __init__(self, a, b, c, d, e): self.a = a self.b = b self.c = c self.d = d self.e = e @reprlib.recursive_repr() def __repr__(self): return ( f"{{type(self).__name__}}(a={{self.a!r}}, b={{self.b!r}}, " f"c={{self.c!r}}, d={{self.d!r}}, e={{self.e!r}})" ) def __eq__(self, other): if type(self) is not type(other): return NotImplemented return ( self.a == other.a and self.b == other.b and self.c == other.c and self.d == other.d and self.e == other.e ) """ + "".join( [ order_template.format(method="lt", op="<"), order_template.format(method="le", op="<="), order_template.format(method="gt", op=">"), order_template.format(method="ge", op=">="), ] ) attrs_template = """ from attr import define @define(order=True) class C{n}: a: int b: int c: int d: int e: int """ dataclasses_template = """ from dataclasses import dataclass @dataclass(order=True) class C{n}: a: int b: int c: int d: int e: int """ pydantic_template = """ from pydantic import BaseModel class C{n}(BaseModel): a: int b: int c: int d: int e: int """ msgspec_template = """ from msgspec import Struct class C{n}(Struct, order=True): a: int b: int c: int d: int e: int """ BENCHMARKS = [ ("msgspec", "msgspec", msgspec_template), ("standard classes", None, classes_template), ("attrs", "attrs", attrs_template), ("dataclasses", None, dataclasses_template), ("pydantic", "pydantic", pydantic_template), ] def bench(name, template): N_classes = 100 source = "\n".join(template.format(n=i) for i in range(N_classes)) code_obj = compile(source, "__main__", "exec") # Benchmark defining new types N = 200 start = perf_counter() for _ in range(N): ns = {} exec(code_obj, ns) end = perf_counter() define_time = ((end - start) / (N * N_classes)) * 1e6 C = ns["C0"] # Benchmark creating new instances N = 1000 M = 1000 start = perf_counter() for _ in range(N): [C(a=i, b=i, c=i, d=i, e=i) for i in range(M)] end = perf_counter() init_time = ((end - start) / (N * M)) * 1e6 # Benchmark equality N = 1000 M = 1000 val = M - 1 needle = C(a=val, b=val, c=val, d=val, e=val) haystack = [C(a=i, b=i, c=i, d=i, e=i) for i in range(M)] start = perf_counter() for _ in range(N): haystack.index(needle) end = perf_counter() equality_time = ((end - start) / (N * M)) * 1e6 # Benchmark order try: needle < needle except TypeError: order_time = None else: start = perf_counter() for _ in range(N): for obj in haystack: if obj >= needle: break end = perf_counter() order_time = ((end - start) / (N * M)) * 1e6 return (name, define_time, init_time, equality_time, order_time) def format_table(results): columns = ( "", "import (μs)", "create (μs)", "equality (μs)", "order (μs)", ) def f(n): return "N/A" if n is None else f"{n:.2f}" rows = [] for name, *times in results: rows.append((f"**{name}**", *(f(t) for t in times))) widths = tuple(max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns)) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) return "\n".join(parts) def main(): import argparse parser = argparse.ArgumentParser(description="Benchmark msgspec Struct operations") parser.add_argument( "--versions", action="store_true", help="Output library version info, and exit immediately", ) args = parser.parse_args() if args.versions: import sys import importlib.metadata for _, lib, _ in BENCHMARKS: if lib is not None: version = importlib.metadata.version(lib) print(f"- {lib}: {version}") sys.exit(0) results = [] for name, _, source in BENCHMARKS: results.append(bench(name, source)) print(format_table(results)) if __name__ == "__main__": main() python-msgspec-0.19.0/benchmarks/bench_validation/000077500000000000000000000000001473355726200222055ustar00rootroot00000000000000python-msgspec-0.19.0/benchmarks/bench_validation/__init__.py000066400000000000000000000000001473355726200243040ustar00rootroot00000000000000python-msgspec-0.19.0/benchmarks/bench_validation/__main__.py000066400000000000000000000060201473355726200242750ustar00rootroot00000000000000import argparse import json import tempfile from ..generate_data import make_filesystem_data import sys import subprocess LIBRARIES = ["msgspec", "mashumaro", "cattrs", "pydantic"] def parse_list(value): libs = [lib.strip() for lib in value.split(",")] for lib in libs: if lib not in LIBRARIES: print(f"{lib!r} is not a supported library, choose from {LIBRARIES}") sys.exit(1) return libs parser = argparse.ArgumentParser( description="Benchmark different python validation libraries" ) parser.add_argument( "--json", action="store_true", help="Whether to output the results as json", ) parser.add_argument( "-n", type=int, help="The number of objects in the generated data, defaults to 1000", default=1000, ) parser.add_argument( "--libs", type=parse_list, help="A comma-separated list of libraries to benchmark. Defaults to all.", default=LIBRARIES, ) parser.add_argument( "--versions", action="store_true", help="Output library version info, and exit immediately", ) args = parser.parse_args() if args.versions: import importlib.metadata for lib in args.libs: version = importlib.metadata.version(lib) print(f"- {lib}: {version}") sys.exit(0) data = json.dumps(make_filesystem_data(args.n)).encode("utf-8") results = [] with tempfile.NamedTemporaryFile() as f: f.write(data) f.flush() for lib in args.libs: res = subprocess.check_output( [sys.executable, "-m", "benchmarks.bench_validation.runner", lib, f.name] ) results.append(json.loads(res)) if args.json: for line in results: print(json.dumps(line)) else: # Compose the results table results.sort(key=lambda row: row["encode"] + row["decode"]) best_et = results[0]["encode"] best_dt = results[0]["decode"] best_tt = best_et + best_dt best_mem = results[0]["memory"] columns = ( "", "encode (μs)", "vs.", "decode (μs)", "vs.", "total (μs)", "vs.", "memory (MiB)", "vs.", ) rows = [ ( r["label"], f"{1_000_000 * r['encode']:.1f}", f"{r['encode'] / best_et:.1f}", f"{1_000_000 * r['decode']:.1f}", f"{r['decode'] / best_dt:.1f}", f"{1_000_000 * (r['encode'] + r['decode']):.1f}", f"{(r['encode'] + r['decode']) / best_tt:.1f}", f"{r['memory']:.1f}", f"{r['memory'] / best_mem:.1f}", ) for r in results ] widths = tuple(max(max(map(len, x)), len(c)) for x, c in zip(zip(*rows), columns)) row_template = ("|" + (" %%-%ds |" * len(columns))) % widths header = row_template % tuple(columns) bar_underline = "+%s+" % "+".join("=" * (w + 2) for w in widths) bar = "+%s+" % "+".join("-" * (w + 2) for w in widths) parts = [bar, header, bar_underline] for r in rows: parts.append(row_template % r) parts.append(bar) print("\n".join(parts)) python-msgspec-0.19.0/benchmarks/bench_validation/bench_cattrs.py000066400000000000000000000017361473355726200252250ustar00rootroot00000000000000from __future__ import annotations import enum import datetime from typing import Literal import attrs import cattrs.preconf.orjson class Permissions(enum.Enum): READ = "READ" WRITE = "WRITE" READ_WRITE = "READ_WRITE" @attrs.define(kw_only=True) class File: name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None nbytes: int permissions: Permissions type: Literal["file"] = "file" @attrs.define(kw_only=True) class Directory: name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None contents: list[File | Directory] type: Literal["directory"] = "directory" converter = cattrs.preconf.orjson.make_converter(omit_if_default=True) def encode(obj): return converter.dumps(obj) def decode(msg): return converter.loads(msg, Directory) label = "cattrs" python-msgspec-0.19.0/benchmarks/bench_validation/bench_mashumaro.py000066400000000000000000000022041473355726200257100ustar00rootroot00000000000000from __future__ import annotations import enum import dataclasses import datetime from typing import Literal from mashumaro.mixins.orjson import DataClassORJSONMixin class Permissions(enum.Enum): READ = "READ" WRITE = "WRITE" READ_WRITE = "READ_WRITE" @dataclasses.dataclass(kw_only=True) class File(DataClassORJSONMixin): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None nbytes: int permissions: Permissions type: Literal["file"] = "file" class Config: omit_default = True lazy_compilation = True @dataclasses.dataclass(kw_only=True) class Directory(DataClassORJSONMixin): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None contents: list[File | Directory] type: Literal["directory"] = "directory" class Config: omit_default = True lazy_compilation = True label = "mashumaro" def encode(x): return x.to_json() def decode(msg): return Directory.from_json(msg) python-msgspec-0.19.0/benchmarks/bench_validation/bench_msgspec.py000066400000000000000000000015241473355726200253610ustar00rootroot00000000000000from __future__ import annotations import enum import datetime import msgspec class Permissions(enum.Enum): READ = "READ" WRITE = "WRITE" READ_WRITE = "READ_WRITE" class File(msgspec.Struct, kw_only=True, omit_defaults=True, tag="file"): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None nbytes: int permissions: Permissions class Directory(msgspec.Struct, kw_only=True, omit_defaults=True, tag="directory"): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None contents: list[File | Directory] enc = msgspec.json.Encoder() dec = msgspec.json.Decoder(Directory) label = "msgspec" encode = enc.encode decode = dec.decode python-msgspec-0.19.0/benchmarks/bench_validation/bench_pydantic.py000066400000000000000000000022451473355726200255340ustar00rootroot00000000000000from __future__ import annotations import enum import datetime from typing import Literal, Annotated import pydantic class Permissions(enum.Enum): READ = "READ" WRITE = "WRITE" READ_WRITE = "READ_WRITE" class File(pydantic.BaseModel): type: Literal["file"] = "file" name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None nbytes: int permissions: Permissions class Directory(pydantic.BaseModel): type: Literal["directory"] = "directory" name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None contents: list[Annotated[File | Directory, pydantic.Field(discriminator="type")]] if pydantic.__version__.startswith("2."): label = "pydantic v2" def encode(obj): return obj.model_dump_json(exclude_defaults=True) def decode(msg): return Directory.model_validate_json(msg) else: label = "pydantic v1" def encode(obj): return obj.json(exclude_defaults=True) def decode(msg): return Directory.parse_raw(msg) python-msgspec-0.19.0/benchmarks/bench_validation/runner.py000066400000000000000000000016131473355726200240710ustar00rootroot00000000000000import importlib import json import timeit import resource import sys import gc library, path = sys.argv[1:3] with open(path, "rb") as f: json_data = f.read() initial_rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss mod = importlib.import_module(f"benchmarks.bench_validation.bench_{library}") msg = mod.decode(json_data) gc.collect() timer = timeit.Timer("func(data)", setup="", globals={"func": mod.encode, "data": msg}) n, t = timer.autorange() encode_time = t / n del msg gc.collect() timer = timeit.Timer( "func(data)", setup="", globals={"func": mod.decode, "data": json_data} ) n, t = timer.autorange() decode_time = t / n max_rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss report = json.dumps( { "label": mod.label, "encode": encode_time, "decode": decode_time, "memory": (max_rss - initial_rss) / 1024, } ) print(report) python-msgspec-0.19.0/benchmarks/generate_data.py000066400000000000000000000052201473355726200220500ustar00rootroot00000000000000import datetime import random import string class Generator: UTC = datetime.timezone.utc DATE_2018 = datetime.datetime(2018, 1, 1, tzinfo=UTC) DATE_2023 = datetime.datetime(2023, 1, 1, tzinfo=UTC) PERMISSIONS = ["READ", "WRITE", "READ_WRITE"] NAMES = [ "alice", "ben", "carol", "daniel", "esther", "franklin", "genevieve", "harold", "ilana", "jerome", "katelyn", "leonard", "monique", "nathan", "ora", "patrick", "quinn", "ronald", "stephanie", "thomas", "uma", "vince", "wendy", "xavier", "yitzchak", "zahra", ] def __init__(self, capacity, seed=42): self.capacity = capacity self.random = random.Random(seed) def randdt(self, min, max): ts = self.random.randint(min.timestamp(), max.timestamp()) return datetime.datetime.fromtimestamp(ts).replace(tzinfo=self.UTC) def randstr(self, min=None, max=None): if max is not None: min = self.random.randint(min, max) return "".join(self.random.choices(string.ascii_letters, k=min)) def make(self, is_dir): name = self.randstr(4, 30) created_by = self.random.choice(self.NAMES) created_at = self.randdt(self.DATE_2018, self.DATE_2023) data = { "type": "directory" if is_dir else "file", "name": name, "created_by": created_by, "created_at": created_at.isoformat(), } if self.random.random() > 0.75: updated_by = self.random.choice(self.NAMES) updated_at = self.randdt(created_at, self.DATE_2023) data.update( updated_by=updated_by, updated_at=updated_at.isoformat(), ) if is_dir: n = min(self.random.randint(0, 30), self.capacity) self.capacity -= n data["contents"] = [self.make_node() for _ in range(n)] else: data["nbytes"] = self.random.randint(0, 1000000) data["permissions"] = self.random.choice(self.PERMISSIONS) return data def make_node(self): return self.make(self.random.random() > 0.8) def generate(self): self.capacity -= 1 if self.capacity == 0: out = self.make(False) else: out = self.make(True) while self.capacity: self.capacity -= 1 out["contents"].append(self.make_node()) return out def make_filesystem_data(n): return Generator(n).generate() python-msgspec-0.19.0/docs/000077500000000000000000000000001473355726200155275ustar00rootroot00000000000000python-msgspec-0.19.0/docs/Makefile000066400000000000000000000012161473355726200171670ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= -W --keep-going SPHINXBUILD ?= sphinx-build SOURCEDIR = source BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) python-msgspec-0.19.0/docs/make.bat000066400000000000000000000014371473355726200171410ustar00rootroot00000000000000@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set SOURCEDIR=source set BUILDDIR=build if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end popd python-msgspec-0.19.0/docs/source/000077500000000000000000000000001473355726200170275ustar00rootroot00000000000000python-msgspec-0.19.0/docs/source/_static/000077500000000000000000000000001473355726200204555ustar00rootroot00000000000000python-msgspec-0.19.0/docs/source/_static/anywidget.png000066400000000000000000000351361473355726200231660ustar00rootroot00000000000000PNG  IHDRDHiCCPICC profile(}=HPOS";8dNq*BZu0y4iHZ\ׂ?Ug]\AIEJ/)}wQf4jq1]"&3˘$'0ď\W\~\pX!3'V:Mx8j: U[r_+\5 "PBUDhIKRU#* ;~?=[+tqŶ?ƀ.Ьm7O3p0Izm⺭){0dȦH~ZB>7e[o͝[@fe{snr?bKGD pHYs B(xtIME7,N| IDATxy@ṴA@%P8)=NiCfNijGRxHM͉qYAQAQA6c k~*E׵ֺneUU -zw ;p@w p@w;p@ ;pw ;p@w ;@w;p@w ;pw ;p@DI@,*uⲲ²²Ҋ2"LWUP(K++TF*R044774472252250014410076VT;P**rrs2 czulbfNnV[Y(JOYUUEЀ23Srs\ڞ'ѺT}5VV&GҴ~!- 65mkkjccoiikanwH*=7^ffLz=5i]SsccJ.%++>#ZZZxJrٖbիNN]7`;'NFƵv%$-- O52ť)A_ȸ|sr(H kkր'/AC *ލ"%ȈpG(jo>xp޽] YOo˫m܆z22N%$V*?hͭCf<wԉԜn[/k]]h4yv;^^VeiiTeK-\mmwܼkk;Օ Q#Z.:1חs.xmߺᎧ+.+xkܱׄ O5iXv͚+w.3?͛ƍhjx+wqs320 eAvvxt41yS (%+koL;qqB| o߾;( w]Fʕ(ן;P;,ѣ/.HJr;v l׎RUP˵koR 14ӳ>k&ׯϺv-EjnA.]7IbU\VvƍWVVR L;]j4;DEݽYVAB5pu׭ZM)w@bf7g~N)LjyN۷g"pprJ;P ¢N޺5y:8Ⅽnbt׮Vffp de}qĚLJi`[^[, `qq&&p ˛lJA`je>-i*I$'O:~v&Rk !QS11(nF󖏏 eeߜ81=JQfk8 ܜRK)YY= *VjkK)wѴ) E^Fư.lӼaa1ͭdV{UUfgJK;!%r;пkGGJARңG#ujִiO6زs[=YVQ ]d8Yj*P(j}'-[z4m66ku{~_TX7Cßlڸ1 Elɑ#\[Ь DNwÓw|6 xM?C2l&ݝ/ JbO11_gfʳ qA@OUU F^*M76֮6̪e8P(h(z%93%RQKa|L.J?uJ>˫K|;yyzu۲zj'Eݻ#"DDqwmޜGjNΎKOH)ߝHE'% =rD\ļ >ݦ!0.13s KRR䰱 j' wɊOOS$K2/۴iijʎk@|q\ox+!!&t]ccvב\\uQѭl|gwJ}a 13gOܢ-QQ3f.]v&*`3$R]Ν\,d %W E,xo{H W]mm/WZQWHu ʬ .bE^aNܥKJO=""߻ $uׄHf9]Wa+_@m[Y-ۅ vq*)/!*j[ܺo^&EQͮ]8fED.)ަ] dYm]*uMN%X*?ּ(EE"#>x 14Jw]ܪv?kstϯ5NwI{.z^\-$yxޥ TNKyb)mTOOv..zn8}ֿ7MRai-*Z!U|J允[5i%EL||Pdd-~dmi``c.塢gߒ*`C6w)K5{Ȉʉ[=}#؜W q Zk'}~+nRygT$ltp5dX??)v;U5bkQ]:ܷm[j(s-, %pKӚ`ZF f<-$nnnoOXVɓK`[]:l5Ns`d?Wk'mR/ZBˈAzZe 'kk*'v==z{y}Cv w3c㏃VVfaTc.]ľӯ^}(Ee w114i}F[Zߊ1x;y+nCTPJnӓnOBD<ܩ8HQo•ǕPsHv<͑=D >͝Uܥiߕ+_:h=M <{VPFTPZ66xaueN9]>i#uS"|N#jH?Ν{D@Oo'}d}T3̄;WfMiX_+ wpi~/ЂTVGEU6; 67_?7.1;{Aӹ'Ƒ<-#HYIt]Pu.p^yJvTzzw~vsuݥK<6C]5歹1;@uڵ[ܴƼe^X%TJW_md$1y35p423[.ٯMx6OWZр t 30Ogfl͢R]Zm||<-P]\j\,<@QUUՖ-[oPszѓ3ur}Io߾' 6B01YڽXF3?_D7O:5dȐ=|Sx-Z̰5܍ƆO"""N#gtv^bbva!. 222={̛7+2Zy]geeO?.++7sgoQ u,WΞ=СC|f͚JR|ܹ(}NNңGd駛7o~WΞ={ӦMtߦ qZ~%u:7|lٲ~ɓ T`([r[;[.cǎYf=?>|xDD'0Pn-ZL8OwYCFO>QQQ_QMP#ŋ<$$@5:4k6Q kJ+*w9r| Յ$1<6WYNKAZZڸq^- yL8%&;mڴӧOw 9Wo}˝;Zټ"p/))裏jYyq&Oxjyl>K0ܵZ+֭[W[d ?SMj^㼐DRUUզM.\XG?_zVfoC5ѣE Ow,!p 1gfjdA۶Ty|8 ߩ ~2vwΟ?۶m 8OiBU`UUV]j՚5k|$4'}''!pCvv6kWUUmٲ壏>xΝKs~G(UU8q6liN(M :^33 w9uTHH_МP(FF\]< R_uO|[?h!Q.0{rr a?Js@PvttW;Av6.YYYovtt:bĈcǎqzCΌ &GxOTEg>tXpYpș\O?t*!ChN9swrL< N[nݲeDW ^~n@&&Ӛ4 fǎ3gi}ccc'L@sV/a<#ơCF%GFFeK=^u 7G)B?nNPZZYQ6k&]n{ZZڸq$v+Ύۿ{=͝6mӧWsnܸQqC>Z vl):ݣ]S^RR`={H@2e3{K^Zn.^Z+֮]+c0<'VUUpB94'tL*^'O,Ý7[[DcJGDDK{]9Zc G111C 9A[ Դ0vp} $43EFFN<vv[op̜4i̧;w\@Zvlم{m*((x=qqEќLR|`½lҥ۶mlʕ4'9XZ vl-Zvʕ_|Gќfmf&رej˖-}M2姟~Fҹr8q"_=z#G5Je/$JiӧOpW/00̙3j'_Rllk!^AAA׮]g{lecpONN=ztFFxM1Z()ܳ~˗/s|\\\ܛoJiP ٳg:tyEEEM:H B(*+#ܟOyy~yfwYfɶL^R^N?Nnݺe˖qX[~4']2%P}.;v9s&[rNs!.pF][-Za@ Lv125t`5uT@RJ]~Ν#Gr(ׅѣG>|:@s`EL}ɓ:tx1ZP6--:g\RR2{krFs͛S ۩}L0޽G~Zj+V M\\ܨQhN_AѮ]'{{UUpBS}9^=Cutnuk''O~{1c bkE{ҫU/~o1`SC.++ի`rphZZ/3RԳQ_oZgv^6cbbW.ٳ=zP uJR(?0{(xàAVu#^*==!R @RٹiSÇ'߫*΁< yݲmxݻw sEEEjժ93x1%uGNAAMz h Fq(C,L f3u޽!@v355XjK#3P:K-["/[ AABm%jcqvjs)(YORԢ\\Q;ԪIpԞvv3%^W*++9!^^nnG}|{bq`qt;܍zqq15Do۶4'xI h{w|%rdCB:uN^F>8ҲA~‚pRۣǪ-(R+?fgPw vlߐW_H)~_.. 8eJ^^7P_~~4nL)jhWǎZn1p^WXCR9R;{H  ő=6t wԩS dՏ-k'̱>ܭ;ݻwaҦӛҫ<|:[7p[ j?ppֻJ>ܭ~%:))gbh_?40ZNIDAT'mi_?#a4+p700 nݺř9Os_ Rxͬcǎۉ'8!냂<}=< p?ZI`Ƕ{N{Ȅ펠 76'S*,'¾S}yȇI]}Hr~k$J!<ׯsCV\])KZnP n#OIl"߻A\cB3FۺukNNg;fpNK9{1=z(]PCËT(1oN0nJ%-[]Ʃzܜ`xnB> Ł|S""ٳG/P_^@l!ײ!/P(zSyœۙ/kT ro%rnbb2a!ҥK-KS5 wj}E wBM7@l-,Is_}};{W^.T i kָܩӫ[K ˜ސ97'X ʻW w{{!pݜۀ`,jt^V~+A y۶mcfP9d*d,Μŋ؀B` djd$ K*܅?i&Vˉ >}۶jUak}PPPpYgw Ҝ 'ýQFaÆJNiwܜ`M˖o a IPݻۜ[sNN}}򲒌½]v$oi:nN0zn>/Rz +++N<)q&&&6k֌xBDllS;23bmn.2J]R=Z_8?ww]`]PL]W ƍIOOdPUU̙7n7S*# h(Ir4M71 &WJk9^??Y%d` rrr8dS5'8ح[-dW@nX=?ȔcǎqOU+ Ѷm;Ju4wܓu˖-+((4Ӡ1+wWJvyĉ?˗/߿s+jAA/М`t??<&ͧey`Vm1 |U^^ïې VLʿ4MHHǙc^N?ְ9rNv_+_~eСjBB+0PkGTZ]eQXQGׯ/ZupqS$~Μ9cbb8"Uۜ`^i$pW(PW^ONo?S>r N:By戈Jߴjڹ3Q|bmXXXFF%ӛڻ,jtRϞ|YIP(+&$$|YI_zm͜>}U*jGJ… .]*ў;wK.3+ ]\+w}4jԔdu{xx 4H,عs'G'  ߺuUVrNϞ=D4%Kp ܫcaah" ~8Frww׃/_ԩG*. ŬYrss9R2djժJV_rtt5K۷@)e;wZl)aGGG{rw\H-.\(aϘ1#;;Cƌ#1GDD,Z3/^,Ͷ255=v옸}ƍwڕ֦mwٔMq[`` .jv˝W^-Ƒ>ڵkrtF#~suuK1<...,,,++#Æ ><{l@?'|"o޼yܹ G!Ν;ׯ_/\bu` |rΝ;+VL>]__] +PYYy ȑ#^^^zzzM\DQߟ\z)S~\\\֭['M>}~Kw:`Qo»W_UTT7Q|@ˈɒ%KľҥKKJJءxcǎ&''S iѤI1v|‰'}|| ٧]eemBCCSRR_`nnNYwhժՁ233EQQQYYY>>>&&&S(k׆=߄;wԔH2OjܸU$!6l;vlJJ EEEY{:ujNN].\]]KJJΜ9# ;~xϞ=٭1k֬uƍTccc %1|W$-jz޽~~~V0aBTTT5_3y/waZilKAAuٳr ??]P|w~!$i+TTT:uJsrooo>AYY͛CCCjϟt={ g]Je>CilӧccctbmmΝ;yOSNvޝI0ܟW^R"Zk׮@I҅ &O|˗/5k\K_f,,,9"-*//:vhdd.Ҟݶm^;vqt*yՈ͛%ioVXXXbb"{Y,XP"O8qǎ\1-#}?agg^VVƎ V{NEpbo^1cdz/))iƌsT:t3.^zI?#F,PJKK?a„\2""̹K}q 2̙3:=.˗/1bD=//>zrÕؼy $[hop6mZhQC @V?~ۛ}AKYEEܹs֭[7rH:4ݻwO8Gbggw1vh>dgg qvvޱcG~~>ߞ׿.#͍xZF4|<==W\\̮k֭ww;wxZF.]%M3gN޽8j]IIɩS-[!Az{{޽ŅŴ>>8u떔^cZFt:ݦMyehnݚa2233m&)tv.eK,_p. V\VECBB233ٕM2ES|oƑ#Grss9WPPp_];_gvps r'>ݸqcڵnnnRcƌ7:.q= ! 駟޽+et:]RRҎ; IAQZoDFFR?͚̾5m:.11ҥKw%fOLLL8p} O1bg˖-ݻrΝ;/.Zy w)}(S9;;ݺuh4NNN*JԛSUUv֭3gά_^dɒspu֭_7o޼I&vEEŃD>3gS |{7Zhlkk+HIIw^tt]eOf͚)S?cǎnnnVVVjZT-..LOOONNqFxx[׆ &L 焻ݾ}^B7o޾QF5077711100000066600FVju:]iiiIIIIIIqqqqqq^^^fffZZZRRҹs.\@_?0jԨzM ½!}ĈR@8}T WUUuqѥB0|e˖Q 7P*}=wĉַ~uV+wԦ[Q ?__UVyyyQ uܹs3f̈7}YXXXF(:~9sP 5OO/ח wԇgΘ1Qw,X0}tJA^_~ܹ{Ŋ\hKs22rѢE-A=zק;ȑ# ,8gΜ={P rQ\\|̙UV:tjHjwٳ1 w9*//tnJ5$ 44tɾFFFTUVVl߾}ʕTC&O>ѣVJHH 1vؿ]t133 JKK_~Sdgg7gΜ֭[3&++ŋ;wdM2%44‚jpGJMMz꯿wQ<~ݻ;99Q ?Gp-3fL׮][hR(w4[n]tiǎO / mR777UaLNN=qĺu ILѬY3AC߿֭ӧOoܸ]nFѵk6mXYYQ߾}ի;vFnժ# !5ZÇqqqN梁}iӦ#wACFJKK>|_~}޽m4h\\\5j( NHMMs/>W^qrrrrrwsss=ztƍzX644M6NNN666Et@](Ғj EqqqEES677733311155566 wpa;p@ ;p@S ;pw ;p@w ;@w;p@w ;pw ;p@w ;@w p@w ;@?d6IENDB`python-msgspec-0.19.0/docs/source/_static/bench-1.png000066400000000000000000000447251473355726200224140ustar00rootroot00000000000000PNG  IHDRF: IDATx^ 1EH.SJQB*)IMJҝ8*['۸ݤP3Tt2#N% KRҿ:3{Z{g ?ZvRbEϢEG5kHȖB۽++W>̜n:֩S')U̚5n38p9_.3f0L7 7碣zhHղ kɲedԩ&(oܸ 7,w qgyf3ϘtQ;9yd뮻DG?9q "O=yꩧ;cMC^Æ 34tjs=ȿo2fF2Eۢ]vf\obbq_?;" @  n^,X`5X%$$ĉwrUW.ƍ3_j\z&|Rti3jaKeMfǫ[tIuYf ~nݺɏ?hq=\~|7ੁKR 53O^ڵM5 }b,u^0!WCѣ[fͤlٲ&*U bʕ-:o>ݻwo zzznm۶O>Y^ySZi@}}_.ȄhW3 Z7.;vھ}{N6m*5jʀ@@  /f͚fQ`~<֑9Y` SL=z3">Sp2Wd|RCNj*S8p@:dF+5Ͽ+7ASC>ꈧ^zfXGno M6u$7`u;{饗L@}?luΙ3W7 Ls|!0AUÚAimzO^e&k gUݒ%KLymRG`un~TۨQ#3ʫS .? >)s X  u [Nj/,oܹ :S9H}   uPËmذA|#]=::vZyL+@XŒLjwQپ}0RK 5hRîzGG}dׯ_pH$O&ky :PH{ u\En)l#::t N{ JmD&H}HG{uĺ[HNUP65 ?Cfb)|jgC@J4R}ШhѢ&|jdC@l6zQPVriz4z\  @z1Bq*0HY{VS6@@FiGY@@ 1\2  `#@ѣ,  lt.@ @Q@AH]2}f D]%y (k]͆ @@! sΕD.5@y… 2}l  !wIR2_9fRtmi6@@YԪU+ٽ{w\]…eԨQreEg Ĩ@-"ժU#F[nrJ iii&Xf9СC6 xG bo7qF#>>^k2ÇzG3A@rY$=>B_,˗/g ksꫯ>Ո'N7իeΝҹsgyGȑ#ҳgO夓NO>Gf%Kʌ3̌Ç,֨Qü-gժU&q_SL"::HW+IA@pH[}].ٰaL6MOn`y盟O:U ţGJѢEͳ#Ivd2n8^l"cǎ5'9slL`h"d8: @@T&@H>hY[ ۷o~I&/y]w5\޼y)R3ϔ}INHo_}YG4g6mO??:$}@m)fͼi8dȐK/٫Wgmt * ڱcG3ݭS /^Ro<5y  M\n|駟JҥeR|ysdNRWC}DjC?uS$=z n袋~0S|yYԥ˕+dMO @@ 6R8~xi%|H]7ڤK\\,^X;&]tK2e}UTo5k:r)ҧO":@OP @U6@z@@ jh:^F@@?  %@ @@@@ TkBݳܯo߾ҼysiٲeD|r9.J @@[lO -# @lO1?ѣܹSJ,)3f̐xQWQYzժUݏ͗_~) )Sus AJ@@&@֦K/Tƌc[|Gfj>j"/$11K :t[n%c%qɂ 矗-[رce&$Of%ʀLzH2  &Apǎ㏛ՑVZIjդ~R7]35\quUV5>32:u2:}UC`K!?:I S0  M$sKzzřm]tK2edԩRJϿY z)bh y5o[f[)_J}'P  DN6@F>2#y+on;I=T  @F>H:  !`!1!&U! g@@! ɢ%-Эetyiذ_(=ۇ81@A Ё%>7tS%K̒ 6H߾}ծH}?E]_`/ uݻw˰a*Ѹԃ @l䯿*͛77K+}tNX w}'J25K0s @ڵkefoF }92 l=#ӧO+¼ .0YiΝ杏3f̐:K5kf<$I@&y!KͨcBn֭[gLaO0Ad&D@ѣ:E ]ԏ@YF2}yǁ)h @6RkիyEڵkK.]dRL:uTREtpN]}Hٲee֭Fgtթt%I=  s1BrHעԇ  @R7 B  bF 7=y {@ҡ>!&U! g@@HMCtIU  Yæ!@:Ĥ*@a bR xVi1 @<+@t4HT  @:lCLB@  6 !&U! g@@HMCtIU  Yæ!@:Ĥ*@a bR xVi1 @<+@t4HT  @:lCLB@  6 !&U! g@@HMCtIU  Ydi߾ٳGN;ӥ_~r)WRBPÇzRO@@@ܹs%11Qm&+V -[&˗s=Wƌ#;v쐑#G (>x@@@w}'JuJjjjR͛'/^xIt˩@ ,@βVZy[oUz%]w鴃S x2e,]T^~\{ 7>5" h\h5Jϟ/qqq矖fF-nL+f.SO-[hdXA@y ܁ ! ! @:E1 @<+@t4HT  @:lCLB@  6 !&U! g@@HMCtIU  Yæ!@:Ĥ*@a bR xVi1 @<+@t4HT  @:lCLB@  6 !&U! g@@HMCtIU  Yæ!@:Ĥ*@a bR xVi1 @<+@t4HT  @:lCLB@  6 !&U! g@@HMCtIU  Ydi߾ٳGN;=*]ttX̙3Gʖ-j2p@B =< 8Y;w$&&ʶmdŊn/ʴid2j(rԼT YTRRn]IMM ;u$={ƍˡC^zvZd ۖ9ᅫwR  @! ժU+ٴiS0aT^ZjUٺu+2$)@C bYf2v،ygΝ; HOXR  D,@v]2k׮-7n4'fF-n]By|HGiMH D6@=$[Sm @!vMt%zm @d?;?J# .F ?. ׹pF #փ @ȷ@Rٳe̙a^ .nI+*U)H F+:%@Fgq 'klԨ|'\yR\9_/EɁdrW\r&@H ٣G6lTX1[e[RH^PoP G~dۀ3@@ ܿ.]Է}vo^zRP@dFOWBtpr d ܹUW]%<2rȰQ F #Fρ@J YX1Yp?,?+̘1Clv&@EGYdtg @@3ΐ֭[SOƍo6Adب#v d90 A  {)/+2zhټysPٙie N% H}/jժI%dƍrQ&H uD=F@ (ĉsW^Afg^t%@FG;q  sz]OСCa$@:b"@F# @@2555R}'/(^x3&Lыh'@dV&]n~)lȰQG@Ȉs`@(@:4Ǐ{'wK;&d'3pgdPQ2SG)d Kj F 7&@z8 @(@G}O(7d(uQ7Y  @7ސno|ڵKtPoP G~dۀ3@@ \dҥsΑΝ;˕W^)ʕLj K- IDATd2{l:ut1cYC⋊Ȩh&N@5@ܹSyё_~Zjɐ!CM6aa$@9!@F# @@@9rD֬Y#{SN9żbŊŎHޮ@  õ}vi׮ݻW6m*in}!yBB|w5@'OK.i*Cl@bW dSNҪU+i۶tՄɖ-[fH?Rpa0`,^X&M$f"@)P|Șlv.@  G"E0eӦMRhQYp$%%3vGQdΜ9tR׿E$@Zb5[Q   ?sҥ]V+?  {J*Ɏ;W^mV7o^F}ȹs駟N$@uF&@r(@6ht >LnH[ժUe֭RNNN}ժUJ^d„ һwoi߾}ZZfznN`?;?J# .deٲeҤI3m6i֬o~ϳz83 o[ku@zNфKD8sd@(@VR<3c >}u=(MݥyҢE III1k}F+h:U`[DQ;'~v~F@ \)SHϞ=vt;餓^3OV֭[{5j$ӦM3S_ݳrJN{!;&#F03@NO9YHHT @ zzߣnG7흍8PLa CR;J" N-[dz 6 ۹ F #Fρ@J y= /bߔvPG|EQ1d5 %J5;"qߦ F tC=GF@ y'O?t{9} $[һmÙ! Y 9{lCRdɌpmpIG8sd@(@p Y7 ߗƑZ@@@Rܹ{ /P_F@:b"@߶̮JRI=T Pp 76/ק# #% 4 @H]pRfM)]tF}QGܓi  @v@(@VT)upmpIG8 ;{( @@2B'2t^dQ@ p\˥ZjvklҤIGܓi  @v@5@*UJxyGs%V_p\3o @vQ@ p\@vڲdɒk;?垌@ZNj/S%Hעԇ O ymI߾}aÆ$@F [mBV{p6 @A5@*THfΜi^"MdUF3M= ;N\&@>@|@j/αO>6Ydب>2`H 3AS ܔ #Ho[ Y 9j(3 Ӧ d?2ppI 2@P<$@Qb)bd}#{ éͱ@5@{M*Tq%F #N6!@z=8@ DR魮HV{   PB o.ڵ{JӦM%11Qۇ~(ǏK~k׮~^7$@zMj(! :uVZI۶mM00ٲe ]v`pBZj<¾2l@,/6mE$Ǐϰ3frK ); ʝy #J*Ɏ;i^Z*8ݻKʕ%55U .,.e j1TEtH  ,@֭[3!C$999nH1B֯_/ݺu+Wߧ`u!4l; FЁ1 ի˚5k$..Laϙ3@F 3 $=4~v~K ]R S@tNjU!Ҋ A0]cu 8@r @: H;XS^Z@  X @@:< @:Ĥ*@F OҍZ$@ /F  @.g4ҵ(! @:tyVAtIU   tb٩1ڏ@ @nwX @@:<`!&U!0Uh|*n]Bt%I= y 0Pg2\vU?; E@A߈ CLBU頃 cNH~ԇ 2p+{jbAqX#1 @Ȭ>^6m$E JRR?+={]VtGHO܎1Z쮒 6! *U;vs[z :T͛qo^,X ={;Ie%1餹@ ! UV[f!CHrrr%vM/_~tޝ @vb*>m* W*A,YzuYfř)9sit;|T\YJ(ao>o4h@$555x+1f.RE @d޽06o\Zh!)))ҦML<1f/62{ikQC,?nڌ.6jHM&֭Yr%2^E~vWItG} [! ykQ3uiF ]Rde%;DpSƑZ@ 6ڙd~vnJ 8R ĆA;NMiGjA @:hg"~ )MtH- HLC?;7 nbC頝 @vg'4ҍ# @l 3?ܔ&@q vVeUM=Ў?;?ץ vx].S'P V7Zrp"Iϴ'@:$@:@tX?;?J#mH-FC?^ZԮ>~vF ;Z#aH"@!⇟Mvgw@s]N?(mH--H F b:d~v6#@!FU2u} ;Qt  X F 4*t*"~ P:Zi-~vWk?DN&@tbk}~g,fH'*!Q⇟MvņU4?JS,e@vņUf/ONl/ ;N+MOid~F ֦`a҅*XN AC/62{ikQ@ ؕ42?j@2ioi~d9%@/pJS:drҮ];ٻw4mTPB瘞.Hr_ *ÇKUs8Sv?;?ץ E ?;?;YԩjJڶm+]v5ae˖l2)_{2fٱc9@Ӗy!I.Mt-jW_ ؕtd||lڴI-* .$?~|8o_vg'! *U2^Z*snVի\wuH THqZҎ?;?ץ vtdժUe֭rȐ!L"K._~94e@v.Mui(~v~)YzuYfř)9si2o-QF~---MRSS]䧉 @B5ȱهV}s]d'_~J,@<}t]7o.-ZiӦZJ/ ,%Ky@I;Db*&ى⇟]iJ J$~#g' ڐd_l]%?v HmHC/6쮒k Di6$!~/݅U[Knlj~vvv~^(Mt  ;D F `"~ Di6$!_0`Ks?;/MtІ ;D FҍVZvy4A+/d0ZH8[r'~v~^(Mt  ;D F V$!KJRv~K ]>s"~#L/!@i42ơ>ҁ0? @}_pS1 /P0ZH#vuikGt`NC`h vWz˷?8輊gzN8#Z ?? @E$@ZZd~ "@ ~n b-HJC`h @v?7~V%!_0` X A/d0ZH]ύ_AU @v2-$ȮƯ BtЪ ;D Fd_sWk!@:hU"~#@ FI/+ *? @E$ZB o.ڵ{JӦM%11Q *axQҥKŊeΜ9RlYÇ:i/?,%/~+݂އ4Y/٩S'iժmVvjd˖-3@5P^Z^|E6m_^FES}/Fʾ/~#E˾! i&)Z,\Pd.0{)7CIzdڵHgiG~ " J,@VTIvaUG*˸v֞0aT^jժuV$A#`h vKC 3B C ko֬;6#@}ٲsN4IMM=TR?z.ҰaCiРcdrV]]i~vv]?nHY\fř)l}HF{mݻw)ڵkƍ+ř! ޽{! ͛7-ZHJJiFf͚%y楗^˗ĉi@@ ,@[}IF֭̓3+WcǎXB*T o/_\  @$  SY0ەB@B&@ -# SY0ەB@B&@ -# SY0ەB@B&@/t)\pȰ8x}7@_8 K8e@ 57|#+W.KI?v@'SR_`Oʼy?rWʭ**U}өS'9|?~\-Z$%K~'|"9Rnr.k}:ޝ;wG}4jֆ drI'ɦM[n1ע}])WYY/]F-^{<oi|ҲeK+D}3ϔ_ݼ0^0 4瞓g_1ywe]&}:c^~3/0`ZZje>믿>5裏bŊrmݻw˄ 3}n̙RP!{ϗzHJ*e/"Fq_}RûŃ~ꫯ駟Og߫~v-~vU%@;ք˯*rL4I>shv%7J`>}y狆ŋGe/s[ m/|wSO=%EoQ{1^K-H#GVZϛaQܘ1cL0+5P]7]+D˖-bŊM2H ۶mqE]~H\s5&ԫWE/@"P/l!oJZZ ,0EMR?7ҨסCo Yϳ>پ}{y_zn}H"5 ~ Vide3z0cٲenu5u>۷O?m~ޤIWJE{au [oe'K\à~A(Z͚5%11ь=㦜֡嫣H4|>k::©? z.}JNN6#z~m:u'l ':rxui` cZiق:KziD~)kֿ5hm utR§2{}R}]7lܸ{~v~vU:UdذaS:06N3ٿ/Ydr]wețn|}mȐ!RG%u 77 2}5S#z=/_nuӑ r~gM#˄GGuV9嫯;ݶm[SB֨QXNUf :{1M3#FbiFds,ׯ1N+y梷vZY2SzO}gޟYMnٵ ~ V ڴ:OiQ  5=3rꩧBtZUӀd:HÌ,Z/S %!RVҟ;w1S;Hԣרu*[5[4:vL|\C~^S:::k֬}:[oGX퇁|CY::<#]yA\}ȜͩOC3~ m' zG>S^k1 5o/nVGnuZ|H00dxN}2wc ~ DOim}Oud}ŋh$(pOaVYԇtQ7!שmiOfW/}OK⇟@tS:{::2rg}Qs_GY}]7ka`NWM# }W>}dvEvvv~*2R@Vd@ n;@A^G@hϐZ_jG nx`V[$aG QU,j Aq3xEw/IWѥ 9y+yf]^W1cyPN͋\}TAX>H;ћ煣 -w*H^zi>/װk5@3ʔP5՗ۊR7r_tYЇzH]J߭P9sr~ fy#GHZ_| QpZn̘1f }>+F+ s}uWua:}>P @& \_"S"p}.yfBz:R׵o֬J^AX>H u_(XWo KXI j7`Y;vXVпinkfPb5~d^2VAk 9hȂӖ\ 1%u<{5+(ҥK;Hu uQ\4@zBn4u%}x[=@gKo)HϘ=O 2iϦLꦫixrZ^օ*>QY%n̙֭/v׿TS6wHwԄa}ֻC_tEf{wuɤeﮃ?w 5 -KuQu!jRLz*Ub>@}o_y&Zs@XQ&h }@LS{&Xd90Wu+koI _ ;pD 8C+ V{wۆ3C@<)@dpR U@_/%2d֗a{{vv]9iGa@|kj{< 9S"@Z@YEw.Aѷ y8p'O7{N*ω&  CN@.o}e73cǎfQ7]OZ׫WNܹYZ\l /@v,3ǫ_\z饦?`U  Co@<,9+d< {0ћoid¼f$_5+47oޜQo)kFڴi#'t3H +V𰞘V}Xb&@;vƳ:Kƍ'{n@#ͨȑ#ARjU;wԩSG~')Z96;d9 ?lٲuV3W԰7l0s%\b[^dղ|lWC4k׮vIzz.pxK ^Rk\H 1" /Lz6d(T@ ftPu9>>>f{W.h X@ߨmڵy[pɽ   @  8e@@ Hsl@@ Qh2  I;/wIENDB`python-msgspec-0.19.0/docs/source/_static/bench-1.svg000066400000000000000000000535541473355726200224270ustar00rootroot000000000000000.00.20.40.60.81.01.21.41.6Time (μs)ujsonmsgpackorjsonmsgspecjsonmsgspecmsgpackmsgspecjsonarray-likemsgspecmsgpackarray-likeencodedecodetotalBenchmark - 1 Objectpython-msgspec-0.19.0/docs/source/_static/bench-validation.svg000066400000000000000000000513741473355726200244170ustar00rootroot00000000000000msgspecmashumarocattrspydantic v2pydantic v102468101214161820222426283032343638404244Time (ms)encodedecodetotalBenchmark - JSON Serialization & Validationpython-msgspec-0.19.0/docs/source/_static/converters-dark.svg000066400000000000000000000313351473355726200243140ustar00rootroot00000000000000 Point(x=1,y=2)b'{"x":1,"y":2}'{'x':1,'y':2}convertloads{'x':1,'y':2}to_builtinsdumpspython-msgspec-0.19.0/docs/source/_static/converters-light.svg000066400000000000000000000312651473355726200245040ustar00rootroot00000000000000 Point(x=1,y=2)b'{"x":1,"y":2}'{'x':1,'y':2}convertloads{'x':1,'y':2}to_builtinsdumpspython-msgspec-0.19.0/docs/source/_static/custom.css000066400000000000000000000004651473355726200225060ustar00rootroot00000000000000body[data-theme]:not([data-theme="dark"]) .highlight .gp, .highlight .gh { color: #808080; font-weight: normal; } body[data-theme]:not([data-theme="dark"]) .highlight .go { color: #203060; } body[data-theme="dark"] .highlight .gh, .highlight .gp { color: #aaaaaa; font-weight: normal; } python-msgspec-0.19.0/docs/source/_static/edgedb.svg000066400000000000000000000036021473355726200224110ustar00rootroot00000000000000 python-msgspec-0.19.0/docs/source/_static/esmerald.png000066400000000000000000000420711473355726200227630ustar00rootroot00000000000000PNG  IHDRqq IDATx^|VOK)PV)([2eoA\,'Ky( FDA*l }sR(}$II?|rNo8V )@  ĵM K8MR 4V tR 4HRX#IR  HR@c;L'HR Ns H k<2 H8R 4V tR 4HRX#IR  HR@c;L'HR Ns H k<2 H8R 4V tR 4HRX#IR PV37p sv?"c"!~4ރ½ؘ߃{_??MϾdfҥL i1UHB?R@5yaDD_[g4g3~rJ@H̠=W\3]%A~uq.(#gn\YPRH 3 S cț!0< vjzݰn8zkuԒ/C^ "Av*O<;+,g&,RHj/~0s =|2"(Je)`*f jWqbHQz$8NP!L=c)`yPP09y$qN7sj!T:?64WJA2v{8FMPVЭ|W@SAܺvs̓i{{ U'@hPQTeKΙp5A 5,>ċ*)@ Ъ G$Da`ӹjSRHyH {({Y? \=aMz @ azj$ =R%f}ރZ()@ x@ЖTS Npݼn0\f z *>(juG#W Ș(7GHRe>+_A<n9>4 e&R@LaX6eZkA Zsf-2"j4Tȕ.'|\}8}**@ObVql|3)Yd~ Y*`Z&f)ppX!P c~+ ≦?Of$!HKAk|*h=&N[(LBD2(ȕ>'Ռ} kW^ l`i`I ʘ!G& XL6G)KS*(U !xTqD ,+Vpk;8xתN=0BliX"Ϙ*t;۞jFϓb ,alE,A8NJ~bS!H TYz?jum9⸅[)TV^޺lo13ɢu=X*D alT[>UgV;noE^tYz~bb`؆υUS ӁY0s,qݖJɪ]v+e8>c Z< >hox^)Guau{׵"qq:F)`I0xvCG@̭НDW饎 WXr/ ^?VD,X= 3Ċ-Ny1Mp7T.>YYzhal=d7E߇~TghNg2n nE5}U 0{eYݏZ%p?@&A,X֧'y5H_]uwo:S(_+*,O#&(V;/2a8\P"sqRVx[{^]o,VӺ"u.dpAcR1Z SQy3@}cE ~ape/w z8F&|np% }riNs i^/Έyb ćg/ypB1s)de*łBh-Q# bj$)WbX(VG٫?URHeS]{_|HKZ6NƟCh(Ll]zG9=8!^qzX" )"v eba9C#h qLI^NƏ+99/~>քs:,7~+n'H )0E[ɿuԜͯ}(x5DVdP:/}?v:|VN-!~!ץ'W6Nvcǎ' &Zk_u+ZB_] VnZsWnf6^S%(n\d9;9@ײ]AZM9 >b^¶5g֪nTJSjv N=m)0UFOy !f;ٙʌM0;;wCӂ)oLT(P=g5tOKr{Y$%u:}ג쨤oOC'AeW\U-O`ՖV˺A- kƾaUVc$dNRVrC=͖絁#c-r.|7d <<;*Y5G~g J zRSE2a)$]7@eÉ'x\uԆYRo췧RɫU0@.oVKh|z\Lu-ۧqPxXZ_ 헼 ˉRJЯRoKCO OܒWrN? CnfFD_}K;Y,AIn:~9k|1:!_^LU+ ّQ?+E+9fȘ!!&ŤExۗ`vK:zZM48pvI{J~]eTxikoG8GiwfB 7 L[cϷ KOi&,px*<x "O4-]}t4g$zce:Ց p\Qa8Rw:z7qig%m R}\\Sy5_8`.O  mtp;aHqeI"f_,LN(ެ:0 fLA?h?rrvP4'g;GYׇu!`pp;Vr_hq%!v|>-T a dL9~?f>FJZhEnUP9+VJ~BIO5](Y 5g+ƋɝBqG\8yg0z\O eU>qI<^xRmaQGH;vW&KvM \ ꋪoݻo,jk*\gdl[ZowY jNvR$4(Ԓ x3_(rltb ?|eې}!,E-7rF_Zq?ՆZ'!mXr+K ?4-N /huogY(CTgK_\eIVlxh 풵˼ M 4*)qc>e<{V£޸{~?j t@[)܎ŭDQΌx =G!&Z,;$g Mf )`X2z~ 0LM`*Q(oƹ a"“@oRX 1F3B$Vf 4Ne\sh.LjA>m!銎i}o,7Rc p<5}`pu'|h*&',챉׹pO˕>=r3A^+wMQZBO}畀'doJcYp`c){BZ_kI?6iS1/ZP-zӨcݔS(v_\,{Eg@빲'8WN+rd>ܷ`vjooN[18t,YWZ*+1z XBi ȽS``APkwxYvZ?aQtB9ҥL'E:p4☔DwU/Ul8NeعK*SyYQώrօ%L[!n%n^&l❋N &=ӎb+v[Oe1BDC?WЇN۸GegzI0.=q[Lo^tg1׹8j1)7u,۝ rz$,c6O-K;w1e5H[(v^?WS+}hkE#c U+C`B#\6XeR La,)8+Oq[{+m?]Cz@|=7:YǷx΋<<ρ L 9Pu,ִ_l Xjd5ɀ8q, s k5t][*!BuZ&j /RU&+3@gMwRB^DC}3l)Wõgctw#1&-Q>l[킍[Wv(I_}f bvog)z$boh߅Ǘ3UDi{(ߏȾT1[1NȲj]Hi禳R7Qפ)g֝]6%=A\yZj$em6Z)xWfG ǃ𨡌" W0"GSTxr0 MdU#2].q ߋ/ؗ)E? leB3v|-0bH3+99ufek/a[Z)$;mFyxcj[Mx §ﺴpE@' _zJ>|4M@cKJ 6:hnU9\ףN< GyjYk1L[m0 BBi@V o-bwz^bhA[B+p9QyE3~702%sŴ8 ӣBw&7l'2~xDt˂h^yh^yО4|ãg0x  -#ۿL~=oEwAlSh㹍 #<~VD:q]3ςO.{17! ?c~ؼ!o\aTM+!"/ ea7BP(⁄ǓNO_OYweGF0oxvJR- 5?_}'3m$}~>8Ǖ$&qxC=q!jPC8_^•ƴb5YP7oHBp!ZnT41s/GX>q܉/yIܫP~Z%fO xpu߾>$skCq*(m.K2u?ʣf Ʌږ|˽-<%aFX0K**@<^,/x6Wua_7ꉯQe $A(%7xr =!`p=l)ǽh,8ܣvʨ%B^̢q5@`Z1+<; q/fD*B!y,9V;bhuy2䁰gGz|ah,ZxCܝsh97ǧ&{ώ6 JW⦞G', {_Graa?p ߪܵCڹ( zc0,EWYcamĕpc zL7OQAcO7CJIW 5 E3q\/RL-qS=Ǹz)5fu|D; IDAT >` qq~Ji1AM1! ą*oa(A_] VPQl7鈡ԯo:bF Z%=(A6c2c'z@r7\ěΗ:Oh7霸LmÎCM.WY10Mc#d9^+ֆB ~%G~ 'sԠ =KGo<Չ5B nvwcUj 7g A\?WY z=ݓB :y wcUj 7g A\? .ë/⋎/vLOe,&{ =]8wI7X c~X{<~@|a܍UAJp-q|.cbr qcl?6:'_S-K?7{7b sh.wcUj7霸JUZO]%[qQ EFo q nQNE\d3!/kqr- Gո(@"F7 Rg/AܢqQ5. Ĺ(oLbhCK('AܢpTq.2Jo:B yK('AܢpTq.2JoZcp`! ?Ofs5TxCΉasj')jbA\}?r5TxCΉaIʺOj™ s5^S|P#gCߟ)Y E]wMirmĕs "~jSC}D)kq=?א-m6 _'O5F+q<,{z{Z)9uf +ᓭZcq<,{z77P!_sv-mnZKA)mGꩲV8wSxz̥s",|W YᄐX qZ]m>Jl!Pq[>o[j ;g A\? M|ɻըk&Ulq}B䃗}x!8h6޶*A\)w8~./\Wp!G+[,l1Q VA*pq^=W5U'wÅAҷ❋ VA*pqޤ@c\m xш VA*pqަX+hڊ >p~q;wUi 'iA\?*W㼋0O),;ʴGW4 >*pa,wUi 'iA\?O  ,paU8M-qS=Ǹz)ҦLpaî1=A\=P X <ˮ?=Mx!34M"x+E ql__ظXvZBcB UX?*Ҿ8ZkHAMyB͠CvB q GaiM,qϘ -X4+B_ 1FyCBQzkPP!Bcnw*C9խ_ݦsͳ[Z @ 0eTэvZAy~yVY c||>!"Ar B!nr6?4Z}2hi}z S%9 . )-uxi][wv= g +Oq[۶<@Nl8UBֽ[Dnk@ݨ@CxKPH*νxoYgêӫ!}yZ)V2K Y}{[xJ({( oiµQOhn>0Zm3A=+:qSqwc~;9C+r &UD<ɗ#/ÜsϓALlL!'+끮e߅C|i0LSlJM7՛w2pNaR7IA͕q5àH"=l)_~j%6ijWq;M Wgx‘_-zlE{s!O pw~ςijW ǽ;/m@Mx)/>rZΫIj UnYn޽ ] ,d0)!nG[,lHR!ʻ~i^r9/%kxR"~;!nC =qE ćl[o9mx\Y?T7mHZ"-ni[Mnq ?D)[xФ0goC}hk[(*ioL}WG yC\G[+ިt]WbF_SM\RĖ7\`dv˳T"Z‡@< j _Ux\ՠWŞez=)+qcrz@du ޳̆\j̩3{-Ƚ?ð #\6.1Tp+&]A|٥#}!Wg G+Oz$.o\ nܽ!M{:n[:ykC4O= d/|JRT8{ց]q0':Α!{8E<9y@WI Mgz8#=. ᕅ܊`m(rkqwP%9♋jC-MVJxR#C[ZkeK&AFgg./1=xB|^>\s ޣBw{˧Bo{M&Qn_6YvrGC^Qr SK'y}vE˶M8n"H>8{6P$)!¥(Rg/cz0 'JP*qTo-nWHdC0x/z坔&rQ0`tV-bMD-KW;&㋥ PTG ?fǕ2pŕ%{U^'5Z߉9[r)ö&CBO$Z緸.#^DC|p,>TTQώ=B^ϱg.^bb/1SyG<d&AK͒I6 76E'E~CxeA+%{.rO4_~͞4#mv|p1|; _R|T eB g/'7-e>FdѰh#|@ mXW^-'vAq ) !-Gl 0rh~%!axZ9C ^tI&OfKf6p76$2Eҗ ȭx:<nBUxj2V}q;RP;[ m kήES~%;&`*ky\3m֊;cv3S(v\ [u\bV+qJi5T:~ԶY^pQ{nL.V&lf*X4:I,ܺw m<~3]Y}24ӥwp̓m5wـϚڮRe wI iFTGvq rEEvi5;# qt%^d<2&ҕ|@ ׋5cW☲ SP#c[+i Ge3g2f:!Q__{H޶qƢE擭l~So4$JFrf3T|j*^f;q&\OB]+rYAXVhQ& Sxl=FشsvF|3G#y:@ G)N~P/a'. "H7_){;.! -4):yBMkU -@S ׶G YƟ,I``Qm`xJ|[h^yh_>MՃ>> 5I8מi؜iiwQ⋏//wSCXcG=ǶGpdblݻFgz)0|RsTֈ#aMJ (@Npe+q䰪C੬eT^GicV.'\U:P-C[kXk5hN)~>~0ѷ*!{7:%)~V-Q(^Zբ4Qcaٵ.UA*<?߁sKdoxWᲊ6 nZ9 pJQ _yz:)8Ys_.~JZVU;G7~qS^70{-pkJ 5l!mFl m|l]%I=e 7;ArYLK߆*k6 ǘ5 ~m֡,o٩0aۧP W| YXFtOKRqJZ{n:~9iqtF7(N+vW =- 헼 #/{Zը]˾kiLx1 /H%=*?|[-j{Np5ѽ zp+VӋ/”x'˛IxOP8jtn#FM;soq ['Br]Y4l#\diJOG `:C48"ObRgb3'u(ZA82Oʓ&`791ʝ;%0W t*Q{gq¦saFuoȜ)rj?_g:^8:b J}~9i+}}|Sv+3/GdB1 1.yO'&|Գ#Ynj&UE f7"/ZTSjFAuzlS,$  #ٓbiԫE.`R1i{CLWc!{%)D\!1ݚ,K*g$cbc!kTR嶽3.TyTVv6HH$Vx\h^(03Xp2]30: Њ@Կ>hH q؜CsatAȭ*v=Nf}QS!al>TZܒlV"?LVsJc.qJڛp2hǎCMpFO8O9f5BPb!S0DDǘ 1GgB Њ\@+tp)VmLӱZ(67{TV@׌ ?_>(H"^ZAl^J (@6'ӬObr$Q)_,*J R@pOd dگ 9(az@6EpPp+ʼn+w84fR@{|`xP"sqbu8yj>B (OTB jq+2& >Z_?v,)@ ب@{Bl@ ݛsG~+\ ϐ)]˾ #j5v2w)RCRyAGڜCsa,Ԥ*)y2aU@PL$ =+7˜-(E)P bXFC G]l R^o[Ma_T)YЦX+H"Pfqe\!qy }INSLpiRȑ6ӆx re* kϮSJ2dJU4yZ _=yZkD풖-yfqPqwPy|0lt43UTФ@#xK?Cpq\tS3ߩl.l /~୲cA\3%\=Ӵ͢7;_jx@xȋwA\?=bke~g8u!Pݤ@cxe'xP\\qqJoyץ0ȯ6}Sz(GjuցT)0|q'%m^~j%s*zL]pIDAT}Q1G9|d$ףKNy TY4y0<3 ׇFu?>-ݗ8`bH@VWTC '; xy>nݻћ;\_W@ebAAN@B:; Z dg`<!4a{;BVmbe;TZQwd(H,JK34-rH \wk10I 'Br6G pHYs.#.#x?vEiTXtXML:com.adobe.xmpUTF-8XML:com.adobe.xmp8Tn@)VaOx1 rFmXz\veK&~H}.`P)'og0(m!FO}(װ+5<o_}CQS2&؂4ϣۻJ SFa>UzKfa#XSHCGV,uP1]P2Tm'D2F.)4u2ejO(li!hūVUΘp / . E,37f`orҗ? ?Yo[Ц֢؃4mf&qxkJYHPMppi- N h*y!AjFԀ!B1E@h۩lWGkOmNQ2VyCyeGC^XX?Jo4&SUv IDATxux$ A uR*-mo߽R-uqJ)P]";v~ i!Dvwfy@- s{ޗv BHBb}B:! !N!tB!(B!.@Bq B P@'B\:! !N!tB!(B!.@Bq B P@'B\:! !N!tB!(B!.@Bq B P@'B\:! !N!tB!(B!.@Bq B P@'B\:! !N!tB!(B!.@Bq B P@'B\:! !N!tB!(B!.@Bq B P@'B\:! !N!tB!X_!K`@fUjTcU! C4jRR ?Dn9 IG9G90q$ǡA-?9!eNK) Zԯ3D pzH`r4'96ǎ&7eC9 3K a,' EB >Y=- hQ_@ w&2j5MX_I& !N49:5Ѯu(rPpα0Ǫn2tG)袀Nȭ-W+紒д^qc&1rE*6 !QSDo/[s uXB,G 8o10sE 8F0:!Qi$i%v&vZ(se`"3W8V+":!9wqA' u3I>"9ktLXcF+":!$b>0IhHtMR[&Ǿq}Gi&N [ WqY/ i,s$sh0oOgX:!$$ ;Il-b`4r<9tBH0\[E 9Ǧ=&e: "/(BJ%0}c{y}ǿHGQ0WCb:!,-k-)'m 7ٚR|NC,;)GLαjb&(B>2ҼsRU|}b2- I\_m~Vnr85J7(zZB^}>O1aW~Rg7Nթk<9ktBǚ&jL.%f:Y [I8w4/X!C(bڊxjjVbOrZE:Vl5.E;j7ޛ"U'N "p +WmqjLJ ǧD\KF_s% C⡀N 0:KxZOe5V7M=ȣ! \SudΨ9 t;%r I0ٙ EӺѫ9ĤE:Ďb0;8q;qL\dj @lݣ0o'1Nq:! $ÛPĨK߫x<. p(fp5X ZDo. }ڈ8zc. :! "7|`9Ǣ{# uJĠcdw-t8OtH"ЪQpCV"s9(rj1z33 LR/Tv>qm lmb~w5[_@"F'qzN\VCa W j0ۇY x|l VYF]ASTc* $98,PClWt{ OrL8H.Q G/G,fe14܇z5㷕:xɟCդ jΌmoh:^ ^.oj<مE$Ш /EN~*{?']:-?Mgw1K2 h3dxM?q#3 ":e"SNM]WY:1th"7x"7!-' +;E3 dg$޲{ ܵ&)*F&M[I j 3kbDj d3:J|ѯI*F$~m[J"C[vOًZV3L'xk\ j< Y"9k zǏckc m\+F$(C/UСsLT1vo`zq\4=kfy/|s"3Ewh&'{Q@' g@+2_4ʧڕzsGNY<=*~FʒL`9ӗ>mD\@7jΒJ.W%e[ TXs3wvҽ5iۜ٘>DAf |Ķ$6kAъ4gA:ea,d znFTLdx*jTGf5$C'L Vnw&wh,8VV?k\9 1ėTY&/O}{6/SԇA:0Zr's`r=X[c ~Xi82ѫ+:ys th,"}f$-[]83皹A*rQ@T}G9|37j8ăosv92ui|L꒮buth"";ҷN7gS# _Aב/GNNbB3'k5?v;1ƏmfR*ðG  n9z?VrhΙյGD-&nzi0c44M 4|V:vp /}vJ+S,5kw3%&8fsÍ tsE> O8QXx)Amr[yuwA Z(rjHCdIGN4Ձ*) \ IV8 u6˷{-qe 6Qid" VE8E?Zgf .xUi "DDtNּu֙YNm>X y}ԑ&¤ u!8u`+m&m͘1,.}$>q3KN~H"p`I݊JEԨJY[e;Uud%y=;, $zn-wk!V~.ִVl5\ZjE,53UIaזMYNoW9vz`Eѭ#qCcUe3] ;~xnܬcSW9ذ;;L嘼XMFׁNDQBih:Χ-ձʡ0ɠgK1s`lo}8%h-_G]vD!ө-j8zIa֚Efbge hKCfyfCcѽ1Dۦ9enYN_Vo ] LRֹ; 7X[A**ƀhٽ"dgX.E!ᢀNRFjV+9:'>x$7W!M7.!ë؛7dR+I,W0pϿX +[ )p09s;Ȭ% $. hW9[m_jVb3p1`i>gzg0WDZ.(tl""5oGX3i>~miXgi(ۛWM-{ Ncs&st?omqI%̓P+Gdwf)9$]ԝLE瘰Å8VӺZ GM<5.?]~gA Ɋ:!hPi{ dp =n\sl[q&,C>ЮT 60m&EP@'$}H29L4·r`h%mti&ut.1X-b͗^-E*2Sz!$v9)Ggsu&WоG_;_Ό XW:(U`#^XN-ϭ_|Z7MŴWM/q7ke*Ɍ:!aJZ혻FGA J2LK٫t\yN' Ъiٽ4 CflX*@pf<8}$Al--+U~-%/ V0 GN s?Vlu.x.d z؟1NMD eNHZ5"Źs~vEkV,i3Do1#^"t` w IRp[(XnHT`( TR&"Zs/ #$ mr:3 UNհlu4'nR,U^%:4= ǧjf`^&9h^OLEJE0ak A x{cXʙih NJɓx*(Kl4Ш6]!$D^hl*`vR5;L ?(SPyĮCɁɋx}~ՏIncdQ6"N{Ʉ !![!=%el9Vo^2O@>~,ݔ,¨W٧ΤӗkJwUNY@6CttW QN-cGܲĽA9\䘿ޝ/GO~ı{N8Vm9hZ6KC5g/!n~ETUՁO|OD+)sTq\DZ ZT˲foSٮFtK Qw&F2Dd7{#%AhV IDATm__S?ig_==Ϲ>XM{9ذcs ذDŽ9_S 3vLP@'$ @PzrGfaO^EFBBW@㜃 vZbP_C`,=Y=a5)9&/AT..BGOraO\Af뫷;EUTg6paW \#&4o?`m⨞-E*W;C,E>7QG Y6: :Gĝ6vضcaC'8N Pxe` v`9:|wDG,tG.!K3)δ7K:p$]u§ރG:u9ǜ5:nyuT.ȷw^/F3ݶ^-^@?cO ۭ/Zu{1l Q> *2)%=d6uc J,jW@&-vO t"2ZrMbE*SE49'@[l.w{5(9 w `(Z&z<cGЪɱO|Մ;A9l\?}!ЉCZn/tvIG [{Ѐ&k@"È |.20</zz/v.aɮZ*Q@'yn- ތ1 lHVHG@KVo7q~?Es$ޫ01H;#}h(9xp 5 8瘲DLjWز/+=ʙ%'DUF"jT=uNk %9+%: 9^ň1~lL&|"޸χ{.Rzl,vUxO"/0F )w ĶJo+Z Cd Z5j:ke?NQ:0vuN?/% l/>4~ ӵ//vH3ӹC*WΝFK)G,]3V1|83[o-خODB"#PrF1]n]=P@'n([ vJp1 +´02iKq{q&n{^cϑ//66?'S%Kкewjwp$Er.'5g?bBwK۽eoTx !ŋ:,Y3Cm`6 7 ݋9-V089cЮڃUۇ{ L~C"W_@?B[KbUzzq0/ r`̀n#Еx%jy׺j{bPvgآ _5adV/x~_{52:5ŮxU"c h*tr(2m+a\v7M{䲀~i ^W,x/x=?&p^20˵Oq &`"̈́YgrPC*Kz-ZLlw =A$x6`{^sO0M{LlϳecI'Hh~&'QumdбUN-w QluW*iVR5ݚGz]K'<}G>y7y(oD)LL^K9nj:6c/ި<:L9iʈϏZxz&r}ݯ0g{ O 8xŦ<010kr.< 65n?(Cbs\K53"1?.70/L8l39X8"8@?{_k j&ײ{ZϞ#=  BG9(4:|2qJ_{dz5b3`p9Cj78ϹBkxtm^#{ѤΟ+>*x~ZԳ?,,f I"{ira&HIjVch=>Oޢ pie3<;̃ǯ^!ؼWXw /#W*ZD(n.^0>W{p pKIJؚy#9qKN*3O4Ȭ3u+7V">xZVk٫ů$*3vT Tjp6zר0z7+C^>È ޼߇&6^Vm3j[//FUfJ\PFIQI{gę f SǯV]ވ3Mfx9мUnJȫ+9nsc\sch+b('C 4enye{[?~h^tRt3kHeM[ k H9xAhH'peg9"VF^G|h(=5>ˊlK2wwG8;9u%l{g~3tR^-R3ҡI,8h l)fk <zGS째61~0~>Ƭjo<=\y(T2+]<_ ;O&}e'0]FB`8Hbl(Jc(,sy4/Эyb `r[;6q~#7[yqE 0eIs,l~#%+kr kF6l;`U=vkpU֋MI^K|=򤐖+z&Yq0cF\(tl,!#-XU4fb`V E<18;:40 Gt ǛU|1S}ֻs3\e9..(R _wk }r:pB;':R,EGJE3(F$F/C2 aOpk~lg}8&.q袐Z]VM:%H U 6Z̦Z5cW<|.yv&kxѪ3vc4/ury1:4>r\nM u!.30s>kviŽT.}dbo`{k { )!S<@ϼ_F7ȻA-uƹǽ1n L_'h6fk8aޭĬɶ,qn|ُE#! p2>CHa'gv' j0~gWsee/`P lf&x< ٬bkbxV=1qz)@f1<]"J5:nzΏfAT՟Tu'0qZ)Uc*LTH GFp -;_ ]XΓQ-rqjx5̃fyEAk9gYİ"WcxLA6"{ML\KC{a`aHW5ksUlVJ\> m]ú5Z&c;)azqB7*,aY4qK~ԃ[YUύôfw3ǂ ޛb#"H>DA &l sZm+! rk;G^9歳ƀ;JxЎAgaO}(^F 8 Ӵ*aFW1"m90upT~5bV2睃lwk WaXՀGQp}{3f97O8t? 6w Qp9 |i>kާ}GM4*C_[_Li:aǖU LFC4m|?Ǔy[Wa99o1#TD*N"N ɁIui='§ Tձtq4,Xپ^,*A0J~ijtsy G}n0V뙰59Qdg6UԲ?[e|=[]'zPkaN6,' ݢ0Ԩk=ڹ ߧAO]e,jbP$+Ok1+Y;650[ 7_LΗ1\ndrٶɡ@`}zp|٪ x"VM\"W N%& ˶xvU#\ LWe=exD%sLf as9~[_N.E \"?u3\Wƅd9ǚ&ĒM- VAhXjYs jFoާ`j WmߏK+(;m#C{h̬ܖ .tMv q9V01`Gf :IHs8M?Y t`h\'z d tk:^,Z{ȄΤKi~bD m*Ǵ f>mD3& l 2SC'L;IzHIo- q@tX@nUH)+Q;rSENQlE. Ra+7nW2KڶT\G>eÚg ذ;F!.4PAbN5:Sd GBl׼('B9r95Oj{Eg}1096[^(=*z"Tgq_1q /[|MRb IDATsԨV `/T8Àv"#0kus Fu:V0X7 *9Х,[x{֕_+Ń]YǓ8x<~o+ ]^2.!!Jqn^jOʰ^w9& ?/UXak&uJ97^"׳5:|0hQ_@w9,/c[5VN= ɬxDN-ϵ߀49ޙHېvP@'#@wʟz+'ar[k୉*4H@\[KVD*zqαǗ40Wj2UAֱP;ǹQ]Y{ݿҷMӵgЇMnXAxs3VO@Ӻ(*}UIwnt hZWS+N9GAXAڝ&jVexr[6EAku|3[ÒMf|3Ҁqα|? `oǣj{ /)*:;>zOX;(SVYAa;]a~ym uv@٥Q4m/O[:Q?3Kh'ᝉ**Ό(.WΕ(Mラ 8:{Uv"zй ~:Id( r,Xom1bZlGK[Q~ќ5l/=ypI錚u3th,b;6~67{{\N,tj*G ET~"Y ʊO' o+t<~u F{҃qpKptud6m+]"jeX?ǖ&.Rb8"iK{oã73+ٸ w ]W{+PjBrPJbE<wOVf~,Y $y}҄=3}wΜ=فmc/,Gc_'W@&""E8&!5GBQ`䅆V x"E2JDtP aеrԈmLHJ51Zb o/,Ga=,Zv)Z}@oc%,B?:22MЪML1qjo(i2gHGvRF$z"D4 (Q!"xy0*,q [#ф,/VF Ju^{=jzo/| 'aWCo&7h&O;Sxe+'#=OBF3%( 1zy  ,@Q@xo~3mfd\ʒ 8z^BN\sP5jiisˑpXB^]c3 [^N$4m[ǯ j vJN撣Um}YaQ7,)W,#XFarseV$CI߲lrg8״ S$?Ox:߹t /̩uz4j[ơdYƚ}F:A"5j<̯V=/ji,tS˃TA PP-a007J:M|o똍0/ar9Wd޺;YN#: :ZGFy8%2T\W}/t.dJx2* ᛵ ":*J0:#qmp=ҩDHLJyf'(CFjE:aBL;v;ZA5F6UؗdrL%Uc}:x;v%Kxnv9N2kE$`{mPo&bPG5N8MxM},RA+ap t"f0ۏ!Z65 jSTćУ'U(f :0MBDC]У T8x2uJ&ͻut p9(G1Nt% t:Ll=jDS\ph5s%z:ap{ ԑ()rl;0w5 t:l>bD"9z%OC,Bđs'*=䉘kT*.œr:0wE\NT4;пidYF~W.#ﭻVQ"^9vr$ rY7ɼS_fSOE!w"7п M@s)]Me\̒1o Z5-wpJ$ϽF|:C:4PdYƹt?mc#8pmw;eh3e| 6j@'r#0f_Oe$gXYUn'Aň2HmT5䀹. +E t"7GFi'L]MedXÀۍ)K`@G5& Р]F֯v əU t"7շ _,(vy;{4\^ǪW?+|F|!8: ]٦&2.dX׀5H͑YA \GR[$_*A:S{kH-]^L8^/0Љ3U?ilWR.c=~h`վzND*KkT3zz+vr^1ЉtZ`bo AD ݕUdl8hwki;0] c{ sq"o3kUYMGXɀɬOW0ЉjЮjGVD W,a>#~I0B_DFtnmN2܍,8&aN#V3 {DND64CX r8* 2tϘ``u7B4Wa\/5wRCS 6YqU{XB42 t"r8_O`Hswiý*FK266b^Τl@'" Z1 -Ud R$l9jĶ&I UND5[thB6*ĵVa/{{qϘ Ϛ˗]r<: Q41Z"#D &1+)+DcM8|VLD2|<{o*C -zeټ[ZsiNJ8qQ4o&o@'"~ *a@a"|<zby2.eKHΔp1Kƹt &U$@as&&˿U}ʽu||<x{ҙ[h5|IJ+d2rdd/6?J*dN^#@':h2?J+dd0iُNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDDDDnNDDԵ"r.F@ 22Z$I@aa23sܜ<vH!=޻oxk(++wbly<p)vث\/6i1e(j9<<+|Tc狊D^'ڵFxx  ۙL&س n݅#GQ^^<)4nЩpf|?o&Qx' ?`󽑨H<)3e FWTYHKMǩ琚B7{ҁ0F x]2j5 새0lٺӦs;+HSFaC)}%+~-I&[׎R| J`#63>v.^Lk/+Er_9ߙ;f8G $aػ{/FJUc4McX~W{DuJ1ñbwп_O¼chڴyB<)9dF#u JQݡVz7^5٧ou]DuX&0ާtj?i_<1hP"Cht@.oeS] 9b/}z85ȯ&4BKHmaꨨHt=Z-LW.@Nu%{kg[R_F>gZ#tȱA1r,w 7j:QsCIDUw9/xY6-ѼySo>w.|}}GoթK+$C7w? Ǐ+c D%B3Î.<EU\Un|:r ZW= "j+Fnʘ~Lwwg rS t:⑇BӦ $ 99y8w.IIgpyddd`0u`Ȳ+ykv'44'Mi`0`]ϿCo0@$Foo Æ @!UlgQHIIWvejA IDAT Qz>z<=X|5/\yvZc<^ğ78؎d2I=edV~jefPmXmW%33Ͽ&>$IQ?G Qt# adA M&RSŗeNEn% s: @˖).. m:,vΏXtvm۶M礛;f7v.\BQZ 69Kضmݺvr t"eVǥ[\K$;E;Rjl̮Rռ0xP_/2>b.֮luRd~=*jjйVc0ػtȹSSӱs~EmE5pȹZ):,**{v&Eqq]lK_mZ:Gc8[f8n}C$U)-&sQdddaCɵNgފ>XNٛ,w"'w;r…aV?@0&\``aeYƚEرs?ƍn(]= 9seVٲ_8-)--CiiCE߯'lXVV~͒5k7*Zީs;4jR.)**V\|CD..##Kq#cN dIDZZ;)a~XFL&EmزYD..--%%xxh1еK'jJxx(b{t,cuH c>!ƎvNE:Wj( ND..3+l(O~gL:lS01`0`Ƅ|}eڶmf͚X(0_q!#5NL&զZwMkVY@q1OP͑'z[v* y`Ա-<<<H|mcWFqquGaݚEqNjNÆɚ5z~~!v))0r`ծ{(b\Ϝ8gSu])e/ƹsvX;)4q7n #2p {3QV;J'CU4"I֮:`ڍ2n[ &&'OM]1dp_$I8z줓zd?:K (zaڵsѯobbr<hhܸ!7nCa2Cak.lٺ[r>Q?j6ǎĥK՗ݰ!zZƪi1sv+(WPXc.r'# ̳AnWTȑ1Wn"K;\ѶdƍSvT7^)?v+v1|o\>0̦16n^wBWDuH$೘;cW^^;{uGFF ~fjᡵ$c +Y -Z4G]z:("<<[ǠOXď0o[x{X t:x5kuX#kA@DD$~.|7XruT*F)nOL7_׆xVD=e]Rh9h4xCu'v:qȝJIM]w??ZQ0{ 3|?SD5s'͢}Vڬk L&ž}{F I ,,GhhV!a_@>.5NTG||/~^ܮemJ >}z`oѽ[;o}?rei I:+=eYдi#oZQw!2|#>^]):QW_{܍ϿΟxKH[5 Ƿ8IT*IIgpV ];G7m_̭nXN&/OA01o"ӝf[Cel۶ϿLYY9vڏ]CV#"2 ݺvDϸnҵE7Z?|޿q=O¡Ǯof2IX~sH뷠G#+ޭ3vܫ\u$IXO9e/:K,cHjIgHaSG2x1/b5h4 Allg:!:1D.]:`[y?; lh HJ:\6nË/<nc s@{+V[5Е0Щ~/زegmwF !%% ˗ZB8FMƺ ؽXx9שۨKRrءsTjeI(ی1?-\9MDhBr%` ~X5w݆ɓ&WBC1b ,[zƎ1|@w ~ׯ'6nV#I?&:'ŋx0lĝXr-$I wh0b k+YPzcjw,(--Cqq J~}+t",<HIIMO lwKE\. n}]kL&xٛxGp}wZ}\A cu"ЉJ$Ͽ!5jFuDgEׂwb1UtvZaN EjTT?Хs{ۘ뾇"++apw^tμֶА`MQ|os|2^ðh y&|2k6QKp1'q8N mv逥KbV8>!{W! _Q[v:eG}#+;GQז[vbxhxGmߠ'nߨQRGAk\ q_3fP|e^-y?#+K2=_<;C@'cz=|C<+H{ֲ,#++/&xTT0̕hԸ!:ujg_ϖq#@;/VqCM1;ԝ>]c-?~tsk%%;^XCuI!k sʆkų[FV-#iot)MQoo/#9zeYƅ W?.+6;V.ekdȂBعWQl6m=gѭ[''v.]X&==V2mwi2k~Z_1-]֙c~Z<'*ض}t:ZÍe:99y71+4i{GlgoW˲8y BBn;wZ߱cݹ '+88陊Z)d*[W%%غuѺ:IBqqTg?н['e`#MřMjx#:1"C??_hZh5jM&TTQRR\df2nNDDx 0Љ 0Љ 0Љ 0Љ 0Љ 0Љ 0Љ 0Љ 0Љ 0Љ܀;@h4 `c{lA@DD(TL&#JKQXXdcmCpPtȲxyy"(0yaQ >JBxx(DTI",4F V?_EDDBDrjEhȕԪ*0o0 VfBCѪesDE5z=22p9?)csdYFEEO% Jt壴̡}$0]LVͱE"xb(L&IQ;o,[y L&clذѦZkcG|~b?ϨiϷmߋG} .p|>}jj T""=,[UmǏx {mO_C V* {v//Oz'ceJIg$IF^/"!a~] /}~t{7**{s6r |ᛖקIx.bDAT*xh6`tV= F`HLL´Ŀm:t3z5}ebS]R]s}bѼyS9sޮN| <=Wkϩ( VGLL4OX_kگoO w[bb zaOŪA[<.vg׹+jv^^.GƜ~¬O@a-W{3>MxzzΞ~ 9݅INd2Y p(PTϡfZ@BBk  =?lɯӵKDG7k#G [?rNm|a17k^;W28q" F'YY9ϓ 2 g\7p!i//Otl !!Aνa[@,o߱׮ k۶%aF\HN$@CLh::MaYxb/+l>UKt?. ooo.SO>ƍ o(GvWY<55=R2jts tf4qO`uV0~$o}/p((p FYD%I(ưbZ*W_ϯ 5nu <"3/p9`(//'BмyS>}m6m ¯( Xö~h׮50x¶6q㆘G07MXnoL""pה[p߽wZ3OCaaVhs?;'?V{xhѭ['<&j8p~XaÏ>/zN6IK|Ǧ2UrӦp=O X㯐e `x:>(qcG8G#55g\*v|6zvж ;m[APybvv.N:`^'XBA4mҨڶ .m{lN灇by|1-.OI/Сc̿[[g@ˣ0zL{ylsdKҠכxA^=Wx%ذ1rZq#:"p瓱f&a;n}# ??/Z>ִZFHBBѢE֪esx< /FFllC>>ء-];ma޵Kh 9f֦7U+V 3k4rco-Y u9T*fLfd0ꏿr>r:M$Ջ G,ڳ RS3j7mnrnٲڷk]O-2?'Y;C6YdQHUc~F}޽[F'v9 [v^ | /!CYm۾ FdCt{]Z7'qxI‡}E;Nv N(/@iuUn|SUT_0n#\={vmh|:77[]|ˋ6h4asMsTV3f8==ÇҿڐmѩS*>>|2~].5ïW9Mk@(i 38w.EE!7xJ$IDAT[nSȲcO::/𸥾oQP:t&Znau;Wjժ9J ѿ6$h v!/ګݻ =# ah qq]iv["lC6Ա-VCϯ\1ϿЃS &@/((Ī?["L冁޹s{\%++kmvJ*aO_[|YѮ6"2m߃;nJ=#Я^g+zغm&M`~^X̛ݯ̞O:uY6SYo*ՙ Fh4jt>>(..ٸ\ 5uL&C}rVbUxzp>7`)\D?ǂuyf0]$Iظq Va;{jWHO3grWz]~O$!),Zj 3ػ'&Nܹ @a8˒ߝҟUؖzWصk? 4 ڵm??_ʃ?m[~~!MD-+#KM&v=+*Z[[ vݡF}ѧOk2f& w32r!oߋ)'_|Ǐ}K:.h4ެZ֐es.׳w،@6s_JVƍįrP,yr Q1 7o?5~Hx;0strZnn>;GHH0bbqr]-Wrֵ#T*s]@+WQ^2x{{S_o{Z9ryvKt)9/̙ i]&MoCNUzw9?7 rC[A_$U5YЭ[G4is֟m޼鈊jݫ;mrVq\S $IŽйs{^=Y[ >_}=۽UViY9rAмYS$'|!3I0`U[o{2I(&&;/IIIÖ- *<=uލ?ſ̫׈u757ۿ|MljD(RJY( ^fM "^z |ާ}{+LZ->l/+qFj O?0t7iU=VW\\'w!KNeMp閉a„+6nfwի;z~lmo;[mef/b+W/eukT*L{I0Xf}FQQ1f>$޽X#./˯̴Afz1&z2ۡ};u͛5`dgV}5r5ˋm}735@!8!җx2v {-ovuė_Ϸ,jYOlr3(ǨʲYͱ(-V\'T{v:P…Kx,5{gyFM1fkm!WA϶YǏ޳ٲueVPP @u$Il*""65}9B%$_]V`.~ru Fd,oo/wQSEN>>k!޷oZa@̘> O?H;t5+s-b7U=֭߂_wa5v~lf4ɬ0]~lܸ!rb~W^um\ljĉIJZzyyYfwUBQ[NjG.jlݲ xUJRmH/+WØ CHp bc cko9|}}7U`0`[fބݸ~!GO /WJ& o_G(q#1n LQVǪ;_z995WLKXWPTÃL'W!((o{#<^]L& >޼t,((7>W{^y \;wLj ^姅]3nfd^>MApL g")Umss|u@[q)Ϯ4:K˲\L1xde;gks6n2wh0b ^~m˭]:iO:|m<َW.&7/K 0M5Yo0`ժ|<3`:z$} bbt:z"55K~5ܶG?w>҇հ>z$BB-srU쑝kd49dz_lvD?e΄`ѣ'үl۾cރ^cҹ="h Isqؼy;֭ⰺNf"cCϝ?mriZ=#Ng)"~> #>˅SҊP c:z#|OC?/7 I1cJ_ H?41 y1u1gq3XR觬|lK? ?92??ϊ~wP?}[ݱ.NU/Ja卿+ 90 }^a/b\1o+)YÍ-S'=n;rn;Kcb_{ !+29}ed$ܯ&2Xe $H/щ>z0uBĭ J[c@(%nsJ[+-(W#7#Ms~Z,RJ-2ʬZj gK-VZm6^z>q$@:c9ʓߞ`N,[qVYasQ>+j;mcvct)vg^J&w-vw~g+Y _Y/Szam%(g$,xS (訜rʜrJdE9A#Xn;?UWys-f)u3sϲECeӅ Ot\g~w??\(#$,Rn4nq)z^2ֳ7i7=&qCVtPB ynTcXρoG0)5 CEk~$~UBQ)#l~*[~tm$;4궦k(KBB՘[Q |vhVu*=.yv&*%C'x Y+Rʫخ(Y_Rx@zj4dQW-Y omO[ SA:QŕİF.X/]'ߧlNS}"74 RY꿞oz} ĎoPSSKT%V+qY,k7 +'-NsMTukJƢ,m@s:pTai=˷NyMu_E"=ܙd\WKBٍo‘>ah4R: j&H(CZ5L1Cic4Pt\Ev+ɵmC'cSk:mS–&<J_ nx]G]\ \SML37eEJi.vBP$_bhܯ2ҐF,Q1dLgXs 1ҡ@Rzb&gEnOMc@?; |:ݑV >(,ݢ',|1uګP8wA-TIq>kh@ >RD'&4}mVhMSȊ~0H HT8F"N(ڤ  i>ڹd}EEtgᤆ qme]")Ty^z0-(_Z5yyWbI<ˡEvXW\"P H:^%l*Lj{{a1xWCՍDcyë gWeMT z}~.TvyA2(uʘCW %J%oMx'&BkeDInj3@\tXV ,ՐDa_ۄבWqҒ6F1 jBkIeRB477}qjn }Pu loShŁ *-c/թqzumb> aHIXOQ'@+q˂E9 2IeFA|UmC:;W%8 @]rn'8fT/\uS?C_xD%L%y֥SErV*Q-+ݔY0Yb*1F{֊ ]I,"D4̈|+u!nid.MH LX/2KmpowS'HunTmڥLq1Jʆ"l88HsÈ8j3!ùI ov)9y(~w/=FޓDQƏK#_X-U>sTLuפ +F}h((d w ]JՇ8:D΅8@%9.O@/tp1.jB T1R؈t4jM2T8 drXitpc X [&Rzhu)Ge H/p7ڧ+slv Uf.HPyH6Y Ė2JYFOwdĢtАn>qarFT(Ƞ@R%%PU++ ^:%b,rxl< N-4G3yllߣtrt"iߌÒ{x !ND2-L"T'{Պ-^s Ml/"L;gkP(@wE;1!2BS0 :Vir4ЄT )+'OuͲEWL8C{~͋-dJcoNKԆ)e" )t JJJt@pFjNq&u@(2Лk[R^]$4R!crڭdO'TQ!,hpHU@ R5LiI-z)4C{PfƁRA>C%bʗb#{Dd ?L*yW/iay@;mJiJh4Wh`4wi7Oy~d߉k[%5Y"j3,xտ7*,oGPܹ{ȉIHeфUs?Wja1%:%'!gwjȮ!ěXMLoCiwZ"@u6OFҤ⯆u@ NcIPnC %t V'2L@OS52S{5Ⱦct}pE H3v EkxsaDFV'ߴ-f%r%^=r`M#E6Z`òJR*̃ܩЈoMUNw_bOSަ\f\H{F-(/uЈ+x#<`v0>O3@0_Ui #o&43t˚qjshM3{;|CTzȑ ɣ6[| ;}>A^ 嶸{Vt@H?Bb1) D,`iEWIwuP xLJ+(WhD/`$B D~lPڠmC0@C!I֋4`pi0=[=$ݚSh^H2iwژ/ vo@+3jc(YMp~w.f)koyAJӐQ.mk#Euc81y~YGlJDP". y4jnS,ZHNdz>D}+Dlp!b5Myy 0 q `w.4KL35mT+T:mO3npʅ~ &tM5u-T]Fj<xԣ190Vۙ+k؈ צ [j؍<~VOy?r$H+I=L5j@?N*,:VF He"<)Cy٦~ *A9*}6Q,ڭ .]d/y{<v`a4e>U vȮ= #h[ߵ;}nBxT5mpM#h#b 羁3mB4QY318}v tv z MޠIoجwGLE!lm *q$" Z,3$bkXtxQ|/ N.qBi|Ÿ(Dr&& gcB+L%]5x QAv<5mos kk.}ۛh#c,[a˻:k"+P"Kb i5.̀°y{a0㨀cL6a!j[hH&@̅NRM+` :97 L5Зg5[Jh4݂OA`;> `[7B9L p?n.8'z4M^ ,#ĥ` Gnvf N2ӉHN-D`|1:Oe>)!d.$E N)]`651QBmt(!Cc(j @2ˤDI]nRK2mjl;a5hy.xa$4[F6R#H:lTn:"#$[^>b$k֟y"2ROrT&ԡל/7`' }mvg#VBD;|^ܵ@s0+U4\$S &RsL~Wh&@5ѣ%CZǃ):&Gku;񾳠}D)((R)]^3^ եDAZ=2j~=؜^|젥΋#5ڠ\|1d$Ā @V(- WXO͛7\?)݄xDh7эڊ%em& A4hxdpaᯛXYGԂ vf:BH{F`?G_kD\@n,r_b,`uisGL?毣̼ ~ԡ %pG8nb2xwa+Eh8[j\%$/tJt8W:#KPD^4­+!ܢ;r>cp cT(_&GHh 3&>)8O=7a]mJs::$xbʵ{`zpyI[)s')Vk,h9B/LUB@ty!I9MLHvS0^G&Zbl@ve{<0g~Fwe Ƥ='"rH2qTw6Y ֪s-^}G3C2(òq,5T;DE?M܁lCnM.R@&`&y+,&SatSܩ7oi  "#ϏE&!*uB|,#ctJxx3Y9$ߵXuG!ěOԕ!j4:ZWκ/u(Ne:X=O6X5Ox^6bH=_xf*^:fh* 9}{$KTLͥ aj7u힅2aƾw.<4[pQDmCglԝBSGdC\DU]_?vn*m=!w:riꏼQ; ]Ytm&gf"ե2tSkշKMiCrh-7hH45Mj[B IV+-TSoĄ iMvYB騼ec;'1O֕B~ŧ,}>1a𶡮N^ lE&DaWԅuFzyӋKRBoR:]ڻgcbаU"yw֏ƳwUIS-H5$_wH)][ḌFtMg6t $f1=%3PuXqs.Ȫv/5h.Tvb0u? ؄~ހH<+'@01(S$Z] 'U ,-TOSd)]tBNNA U41<|pҙH/u7УcD\ 8|-:$+ehUٝI\kP^ϐd 8ڕӑK[b~{djjr1v-s[⢽uގ_/ҡ3"T~' މH7Vpފ<{[:{gAޫc zˈN5ͤw-VұKocO "k<0:_7w?1.p}7 !ܿ 3FR:|^C9ytXꈞD k4Cy؅BNm354CCZW.֜XTi:޹JiR;N֛/fSUknK>[GwB!oiCCPICC profilex}=H@_["-AD!Cu *U(BP+`r4iHR\ׂUg]\AIEJ_Rhq?{ܽ*S͞q@,#J a(9]gys@ xf>Iot.;\OdH/3<8}U88FK=<1r iTXtXML:com.adobe.xmp ) pHYs  tIME*j! IDATxw`\iy.~hFS5EV²%Z ra7 %_7 ! ?BX , !aYkmYeԥg9+h3EKsw S  @+@5 @ @ Pj @@ A5 @ @ P @ Pj @@ A5 @U|>/ȋ x<h2LRABQT** JԤVD?#`a8VHNvg2b>/L&fSTA@}.tFN ~܇uk8ط0 Y0 [Vݎa*PG&yf$wEz}SSJR(" d2 "@ r|``@0jPÈbSSS{^oRf2P6770 F Fp"vlaH_ $ӹ8yb@ j D|^?}48$I:-&;  n 6^N鿴wwwn{nn^3(;wNT T!n߾䅮.Vx <44D#AܸqćT^mii` C?sY[[n@ A,--ѿ^֏bZV+f*n@ ;;;t4 N:j2HJR3I PEQ'NP( EQNZ|S`0H(8qÙL&:7AQ@ ̗l6bNpKKˁG P*B(bRG4Lt,#H>@ DDjbZA@j5Ghjj: *}ry,9A@U ?rގ+<5 0C|01[9j'J^ }>f'x 49V&onnX,LkB@ C8| |B2 H2\]]][[jh4 Z5qp;;;tGJlDYӰgKVwtt\.  afYN$Ir RlZ 踽MLXr\jZ=D"Nt*Jp\h  \. 1fY3|f'.oFD&a6 2I$+++MMM6h4 PC zޝHRY,|#(sE"f들(YSTvwwwuuaBP(b ȎC0t>d2YֆC#x (б 5ahyt:chT9jm{VA &-T*/\9ߺunX,NbP`n[]Ff_xsJÍiZ~L$5-t:~?IK3o޼x ܕJ%oVl6[ss0_Sd2r\.aA{PkH$\B?Ӯ.viׁ < `lGGP3_ѬP(,ba70??t:<]cML&sz4Z>{,1Pt:{C@ 8DQvAM1abpqZE,={E|>?11A[0 ;wOjl6+@*XN sYiJQVDr4n }6fĵWH400 d2+M&`e2SjǞz!ׯG"_N8UBQ2R,?CiL&rYSSl6L!PCu9[!+x/_#4RiGGb)|{tAQ3gXq0hB@ }[!+ŭ-V閗3L+d&K$$Í ĦC"X##^Z^wdgW[~'}/daC3ݒK2qYwY9J 'KkJn݃-`Zt]2-~ii >_iG3D@L ?<(}nтBխk۽?K<;$]b xR+5_ŞI% CNJ?fMq^UXp`6]YYJ5hM{&kFn|UvH]bsߏsԁQ5L #Q02|\c q/HXDzR277rjfyDoc7:RЩPa 3YҿKC8qgz۫yC;5G87oD=#h%{oS&Gm-eN{{tI>NV܍չ.EQW^>>fFceO$jk`: .+$#O]t+R1;mxC + O~;|5$o~&* ğxƤ)O?jR}J\cccCќ={VacNOί n>dS'>4JZ *cףL^xՖ 컵x>%EOU(R `4u:]>gjLD"ѷ'UL^rx wjk$A~L2v=}Cx&O60t_%wx&rx\VRpKK ZUne>1~O+ ,. IA39vœPc/}<@W4~E$ !:#o~X_)!Tmge_鱯nL|3)/(}?NR|]M#~CSy[r8 |+'h^_K:/@ǿv=(诿HWjFg' QeQ"Kю d$].xDM~Q&[twљfQ7~[MLد\}lX6Qӄ\MڼM ȓs?2XuK  =;U({Jsx~v+։275Y]]=D0 _a6fVQ0 0J<6ywヽas@͛7cuuuii_)jP8[EOܱ|I z~&]0\@#]ZZ"Ih4քT{{;^7d,=wQفoP]Qja{S=uED"χhWWWMT*moo haa֥gV o湞 ,kRֽvvS'KtlW'EQ2ooo!M6\H$NgMSsʠՀ55Y,15$UHa}#Oxnnhom'Ht\R^R Av;A+++59$ Qm3WAǬszd2Q>vDRA+n\XZ?%鼻RkF lR^)SwkM(Z<X\-Pa~p}If tr2b~ԖēRpBJL rnr2ԻEinD ̾d[dT:5*DLlmm Ly: οVNPTR{VHz5# y#ͥ;pXl~~~qq.U AϻNosN-&| `ASL+5hJTE2[D6OѺtXd^fg8xfhӣt5?u妯-ߑ:1z5#|^0L6LLRrڮ)r\Z⣀ԕonn>paG9~aËGQ!5 wJhjBÝv#/PȠHFB.BP(d2l6Jv9 tz'Np\Db{{kǁfAHZKzYs/$!yai2^tG3o)0/"d>_O}{ P750,ˍFcKK\.ft?^qBFPi0 d2dzkZY$I|>ñ T*mii9uT{{{ccciEfw{6Op^vkK5|j x wl[WȸH=nP*KlEFF`%t: ( Exvv6vttT| wP(xq㰾>77vS FOӕɳ" jrN4}a;." Op<}gTe:QywIA_"M&;*ъdRVC|>_΍┣1!{c}}:{=W|[xGSZ9-j* OGpO b.vyTn٬ift`OE3 ZbFngDnmEAn~*z: jlfM(dx#ćQFs1AM\`0nPͺzNg,vgf@)tePdnB MkIUw? STK&~GANRw$?8hk^=RyUvsf@+$"Hd2*ܥ(O>܎ #'o(O}':?_\`&I}3m:])_;*+fNP?sq͈>Μ9S_6\N$g# =Utf0ϵg­[<H軾 0}7=(/&NK Ky Lm7UR.Q:G}[+!HJ:+=qz#tt$֫NI?v'&&Z(C1׮](j``x tct:XX,/}accc +{^#~\dS?;K6rg2ݽÝxg&RS?rM47r1 #P*Cy#q`B._[o&HRjzll,]=` hnnN,_tVeE.|2===d Y>7&Q}˷3]zLİY%B,xw=| To*J&Ahq#A*:~z&9yjZa(2۷u UO/2 ###MMMJed:WaUE_-\U2(?L31Q<>"{d2ڪ} "kkkTȊ+aZtt{5F俍'r] )ȠRtY"BeWٙܚOC ꐜKd}Y- hnnBXSSf3 5'Z pVTe .^(Hj( ][N-gW~W,یPx[rW"U_|='q"!o糱nۙyC\.dܯV Rt<4zl6rui@ `W6|WIXrQ)V+}#TvVԙhjvn`=6.8 B @T2 {NѠ(*LV1Ia0TP(J%b0DbXB!)TnؐkoiQ5͛챥}C:pEdrww$)r`ǽ^?`0477cۗp tJ^۷JΏ///+JDk)5О3gD0!IVMDq=HD`X׷ݫJ*ˁqEQ===3}r^A;|.R`n|v(jii mj[``kK7L|~rr2H qVF8IVX__px$SSSDatt|v:x\.VU-PAr0|i^妦a^'N^g2fDns_d2I 4qv b R~'n>_]]>$6rykk+EQ,ljjҒ W'VJ⺟G*6773^+7 B$Jccc+++\N͘:Q]4eeHZd27oެd~8p8,JϞ=J6H8N˩`bG8>t:]h 8,F2L<TеAp9z4K@ggNc1DQTKK w6j(f1&* "htṫtb [ݥ4P8B/_/bB t@ U:Q%\.;̧p=d#̊J$IAPWWW p25$Irű^AᇙLak?, v:|qq ~nE}>s[p:SSSE.D"0 KfvÙ}HUc~~ʋl6 מVZo J"K`0y g_<+#9Tlll\.+\Ft#5@&A>ů0 )N;,-|63m(>K}*Xбv*-rA j`>vM܆1Hx܁(7~#pJP{d>H0|)ֳC5 G׮J522a:$ޮj M1}~>4#[zvEB.\pw޾{(*^j%6ZFQtgggcc@bbf%XCL݊MP(D+X'hڋ1oj DɲaZ]=LG:nLJF1◉l6 2Pkx<@!`0_555UOJPH$q<s <Ax:@ߍN1:6☎CU]/3OazVvbI1<=@U@ 5 B+yr`0]An}x8RRAQ⨲u,{饗8= @^>jt,[ q'7o\XXp\ئ&$IM'aj74uvܩ8F kc<&"4.34<X,|[,׸kAqHr8ʞ0'2d&''٬Vy1.* v`D:Ī?̈bZ_R* ׯ_OfxxA<޷G\ H -7K ~, A333~fa[-[[[sssWa688Xq VGGGD<|>f"L.^0P}\J @t2W`HRRfUA^t:w8aNWr ۷o3 aTzA rD"RlE^#ReQÓKGIܳsZ(0_|1 lii9>z+t:`W2yֿ||uT)e2q Μ9nT*ϟ?ςq|qq뺠Ќ._ᶶFSSS8[֓'Or;,,,q˭[ndQFccI&(Z2-^PA](v"{V+ID恁f /J5zKu'R_BG4]\\DdxxTj8lKRFVk *a) @VD" `w-Ԍ^lb8ۓJ---'Oqd2Z7(.AYi#Y^+++D8MG:7l{{{̰((h4H$8^ VVV0 /REQd2vD"&syP-l6!W4O$(HiZbvV=Z.744xp8 Faa ð#Yy(( wwwHv\NS*VjC5TDʕ+=Qux7L`[jZ.=??x6pҥ===(z<Rn5-H8 hL&HhHd8q~A23VWWrD2s7kB;̛q|rr2I{2w G^.Jc8ǹ!IA8>55H$i5qW)P(4;;Kdkk+q\.l/XlggGHX p0vU.DKKKbr|tt}@{^=U[AXV^N`0'@¯X pfFhÞV./eK LB$Ŕ8)t:+at({X|x@ 0 onn BVaf<T*={l4b&:BAȚYAZxv^f^ u {077r É'w`T H /Ϝ9S.Ggςrt:-JyڊD"ׯ_G$IJuܹSa1 @4/jº0 UTdTyC$-5^RV@ X,ݻ@0R0ðz DQRǧٝ r4.쏌 >FV|`aaaggQLP Q\%9y8Ѩ߫9j \AYT$6ENNN޺u+ 9sF&z|EQ[TlBu/@]`t@oXYY@dppAJc 8OOO' B\l(\.T*mkky0;reN}sssmm^Y/455s[@&rϣnp_YY n( ԜHdw@ ueJ#ZZZ\`2 OdJ%|oVWWJ[ Pv&/)p q嘸KFS/T`Vmž444`r9=T*]B*y~jy`g0Gvqq 6=Zt1EU*edfbxll^-j\wvv8рjSJ7ו/ZW78s(paFGMRT*(eBQh4677Va2?mFD AD$~0Bl;H$Nι=Dq}}HA:;; 4JcZvppa0@p,o5͍LfccCx#jZZZUhL&SjG@ O @KWnmm%I\g(s j@P,~ ql< %ϣ+XuCVjI렻\vlޞ"HΖko [nVVV 껁Cnj(kkktZRY,?y/2TT;lnn0\f6uCcd2zLwWEQPTG!H`w zN:UHFnEFp%I4=cM "ݚBuT&e9EKES3i,[U[f7Eݸq#pH qǹ#;W #}嗷Vt!Faw I1== ?_H ZOd6[~S; & jZD#]Sm"z ~M7FFFTZ $)d8Vtbb5H[ܽ܇eggp e!&YΆa ~w+Ll[~ ȣC_::D"PTB*^ _A٩QR>ɻ_k9) ?E͹nH466R1 8sLie333~jȨ&hnn.;t\/bںH$@^nG"ćWJ.앎v{m$9jۏS+3ɌPǕ5GloZ@:A@`bbٳz"P:tsqE/\PX@ 0==-.^I (jz)s+LvGdXL8A]Y~W0FGb*EQ׮],=Ϗr!N͢*꼤(jff&utt n<jq{B! R|W/o‰Loj@-Vu'v$I{(/2^-MLh4dOO;;;NS* yz((bf;V+܀(`B;;;{|Q:/t2W%G,^HU\G pV}yKo}~5( *+A]_ǁ'Swl6RI8Ah Ekk8zR>`tQQQc~ޮ$_k 8p wͲl8@CZmk P,Veie Bk"Wg_ÅwB{ߠb~'РwWM&G}LG$ɭ=nCz@k)s.-x~&­K|OZ+_O=WFd:)c} L} U Gh4\f&G'Oٷ\tN 4 Tf>-EF]D"QWWR(6%.+ХJF0|?Q;IPChP߉pK?ZGWWH$ B5z Puq؀\hllXw H^_{U݁\{ɴ/Z&E\NY`k 5<$G)hA"H8ԕ^[T an#Mw'OPNVlvN.bPq:>R)jI®Bb+8 /Ϗ4Jn.CoT<;U1jX^^ga?'Y6pHVgL[[L&b.+(hQȺ uVXƪ;﯄On8 vQ7|j |`0QaE7M]tD hpP9ug5Zh}7F3<< pc ]ˏ)5$ L]]]5ZWV܅v1o Ý ='V uARZE9jtZTGo R@>wWS:klgkChU^Gtuua@ z=6-?ZRx|L݇<5|xM:0$s%@N;Kj]!JYۓ8Z™Mi[!')V֨0Z^F [[[x\."xTУe} j1y9̈;W<ӹ/叺v;Hduh(r Q}Zz Hyn !M-X6=OM(.X̮Rf3I7\pyNVSeC0vT-J6 j3r4-G 133m{>/ P3a]I&`d ]@|BGo5><#HRr]h4/455& 5]B,:Kd 5EF8.%pRh:m]ұ kDr`őFedx<^FRG`:8x`!&ݗ#Pa;iޝȩp8[ɓn) p't,N'=L)GhT  F?Z セ&rrv`e>eT N[ʀn׷ZenJhNGH͠\v"`%Tr#mkOo3t4l==:G"QS\9};Jݺur+++ qaR ÉD(GQT p8?\w<ét2C Eؑu9/GT'o9rma\-;vb ±axznw$lZi'>Jyͨ'Qοx+~76$~餛R)829beeemmMR;w} [aX97ox>Nٳg-F''' Z'O,K28AH C._p4rȥLlnn.--*ɤq\ᦦ&l229 \ǍkFeF 9Ѩv݀oXZm񇛝|r#A%ws-//x@nfq--nܸF0GH \H$v;Ȅ}>vBlX ƈ޵T,uXܠ6Iþs(^xE" lEgggiA\|9 _/Pau6CCCy2$m(CEQW^n6۷oKҋ/'P==k׮(z…Phzz9p=~;A*f0OYX%GjՈ5G@xX&]xA*_wCw^/źXQ XNP*z;-XZ>Z" B.f566h ي 5jP󱕁|*_*Nt2*|HiT/@d2}0AkUuOШ4**j婗얟M7@ȦÆ:g%NI:2YIGqñvA$ l6:[H$eZ H (?: R#;[s0d֢C풱nNj_iG3D8L ?<(}n%x|bb7-ͺe)1m['St:}>}ڸhr+ DSF,d:(v1Iɯ?gyQ/B|bϤɒNK'xʦJ_f PI`v3EϜ9]sW#NNN2K677>d0<<< % ?L{x#F$E*7oc\aȨFT&(oFDO>|f2ׯiV;22R +AVk6777www!oR盝D~з|+P 0>R:j֢21ap&KwIw',@o{=ohcqxGdHr۔QskKF$xF!^h4؛T4|u$K/R>Dx,,,Э'{ȣò}vJwOV#tz*'5Vv|!K«ʇOˊ) s227!OےAZ=::Z vi|AfwAɽdo\)8~Ýz#[=E$IVX_a… G "Gt4z].l*P8EA_x6g_:^*>Q)O>$&!Y.KQbi= (tq5"!loomnnF`J^7l*/ 7nHmmm&H0FڪI$T*loo' øVp+,r 풐4s$$ydz1>+[E_|ݢQ!ڳcDϮUƩY;99 \9X|ҥ2cer#~~-ͦǾ92񿟎D拧> ojGw!-{c8N/K'mv{<ĕ+W :<0tӧYT*!|$3񧞻cP+BP;WMߝfM---4JPfB!GrJnl @@"L&zߙk|sP9[#حS'ķ6rL(& HJyh aٗto‘5o +bT5ឞɵ5n(jii / 4k uvI>#(0^3*u `b9[0({Ӛ8#a栙EZf;Z`˧NjގrRZcX,s8jY2?@7r$ \G ̉<N ]A<@e1]===nii)*wST*nfzǛ 4_Ux*Ky"JRC8Nҡ]7tyblnv8֜\#?ܥb-20XCUubL&l\_____fN6{j ^odT|& Zaq(fKr@E"p: R')JiX,6??JsJ)R|L\\PC*[$WKR!-Aם)4>~DEAPA *"zzz`}JU{8///C]7?[}$i/|tKxk/ zC :ĿBc=3? Hw7W'׳,ȹ͝Ӄr: KAc]_^]?wIԠSox_A$?J|\W3APn0 י(L - H(@kb:8~Y`0`&&J4mV%JVM!}*Ui*jR5RU8$rmy!T^NNePWXv|1.gBvmC!N_f%℟. ް<٨9w7̠ RnAMQ?J=󫕬xD9jsQ0N;?~쮚2KS_[ca1}u"]D1V8 ۾}Jc'_]i\_xmt[ /mʃ`%Ar9?k_rٴON.F^|'0,ROwtAVɲ24da \Jxonn.[-..NLLLLLW[7`@,5 ~†[lL6QI2ksx>خʤ߁Ocx֬,aь3)Xf)Svĉ~Qe6;VJy( Ֆx6pqhbqK'ԙ8Aqa4#V#Ƴ:,lN,)Hsⰲ^QOɾ'C͖Xb~7zng$byWz:J"6g9}I0sw¾) g6w!Wb( BGW?['rt*nUJ"hBX pbI1j%lJ)Y9kЀ)[?f<cHP+IYQ2$ ]R!#_tܶI7a_twE|]#zkZ0?Cr@ +Ȗ+WrӧWgӆPhBxkDb|I8̼e} /Ƚiob8wxN 56wp__Iy>~{{{cXSSS18Gz(I`'@ԳX$kU=~@$)ӉojsɃJAdw+R?{zԋG@tB-wȈZmmm|ߙiV{"Zv$(ECIN 1<O N'{͑BNZeuc]J$Hü%^ JҨrA^/˲A4]QQt:Ş(L,{i<8&(NT$qn+ŒZu" 4j MI^B"-//\.l өR$~𳳳SSS>AD"H$,+PI г;ɖN<h4X]]ncEӴ`9`n ȇi2bTVV]%H|vNJˢE7nW$-Kmm`H;3P^gQA"ZTWW766ߤRi˵mX>W ׮]cԩSӊ:$i(b0K-//4 ^W (ART4 x|(СC,&#Gv\bO$4H0>>~Ml0fffR*++m6m*cZ%~fcfnn`0tvvJ$p(g"3=+FS__o2/@ׯ_sq*5e/e/ .qh3g$P %.sr$4P*Fq/3 ݍ% pQ1ڿ/jѣGfY˫7yع,z;<~doo/eR*Yܴ8>á Ii%9JՌN43xfd~G0pVHeR)߿~LmJQUUcҀ o_Og!Ih4B+$H*$flfY,r\ҳ,+.Fly8Z0 j8. m_hwfs+$T44;02t:xo}}}jjjzzz˽P(cCNM>Ʉ`0MZ!QMB4Y@onnNUMMmmm94%L(h6zF28e#:21 ZmkkVs ={x!Iɀ4%|YXX@v* V @ ‚[av{UUش4whBH$FQiU*FfY@6:6@i@i@i@@i@i@(B B6MpIENDB`python-msgspec-0.19.0/docs/source/_static/msgspec-logo-dark.svg000066400000000000000000000066501473355726200245230ustar00rootroot00000000000000 msgspecpython-msgspec-0.19.0/docs/source/_static/msgspec-logo-light.svg000066400000000000000000000066001473355726200247040ustar00rootroot00000000000000 msgspecpython-msgspec-0.19.0/docs/source/_static/nautilus-trader.png000066400000000000000000004043131473355726200243130ustar00rootroot00000000000000PNG  IHDRx-zTXtRaw profile type exifxڵi\7rc@,9ށ"R*q@ G-zKj-[} >?ߟ?D~>{~?\?.Q҈4}/XZo}y>N_l I1kJ$N. sϟskH;&W?cDWCͿ|W+j~qr$a ׫7w[Gn{fbTCx'^7nCp~:QX헟Z[\77}s<.V1ag,Y?~g-[ϱw[˽u/{ !sW/i1+/cENjyӺ&Vh"%f -tⅅt m/q`ȀXJB`"; 4zL9NV 79[Kcs(X,V΅iCK)ҋQS͵Z[(ZvZ^zn}Xh֬sp/cƙf:Xʫq ~8J'ri;j7oۯsվOƪŷRzaj5cˁoZ:j|9G̛PDYf;hX|B,7X;?+_kwݕsZrnZ-Zo>YI5#!@wgw?^.13ek~h%J[XLܴkugݛeN5[{L,ie!o-kyڝ.byμ](,HV]N,k:jgp 1iqi{tA8sCow{ $; 3==a* CnbL9!{ܢ {3+V- ynfi^5PݮW(qyFf&X= ˰:_|7X |7]fKkJ!5CcΜ_u.Ab$扒X-A3!f*mmY'WW+ * jDG`)ABrl1s3:/.if~"uH-{Int&!2cˋܓIL߸rvR# c#!`)rKe.o?zdm~$AfwJj;L& K G &FO$4=UErЂ9 ă" S 0ﴛB "*u`3^\,!:v|d]0{XVpTdǃߤMy  umFNPY R3hNh4Qy`31\ggȊ}J0n>)&i8KpɫOHk|+ 휖I X!]C+P'7#9:~i&;5'A 7T: 7ȠRIXND U`> @JYDd1ȸ 1mѲp1܏(YSE''63!'팩\Xw|SEDTGe_Zvevm1lheFA„b\Vx 7ghdT0uHD :lfBj GdR`F<9X{lNŤf(oh0+S昶vT97c%@V;$ (#Ob ef X?wBv MJbnAdOEj҅WJ^3 rukA2g @c$o%#;Xp$ {\R<KOU2| 6Hqh4zC;/g2s0$ ;>W/"=ׄ+:[ʚ#iA<  DH$K,_v%zb~]"|:ECU7U ʻZ7[p6@"d8zp2k9B`Qlf\6IM)xf'(U3L(,9'{*hoJݜVKRXU^SOutӁ`R~mdc\ᨴtr.mMEbk*2nBk/G2Ng( o;M%/77O(wjJ*yPR:d5ɦfJ ĵ1 #R% T P_[$f/q$R+KH*M!tz#Zy մth ,Ek`c'5f<tgIm!ىMn6h &e'DЈ)bQʅcRQ(SÐ G')W!M޳J;wK(;Y{t/mB;!&6c>B17 'XT<(֯vBvVOJޖ-F8JJߠxdiVpDNcD%DbX23Qhz= RN3;͹K'^kƶ+*fɆBZ@&sG&=4&s-^1. Rd5az=z~+TH'K\0g& ~'YK+~e.V\&6xsK$罩{s\k1-Li)x#`#k'Iza5GA7V|(X`mLmE>\B0Krc*ݸNn{,b} |AC,k#1˷+i!`&:c˃:1o x0bx|X?-k۫*5A] يLZG̓1Lq y5;&Уd/y&H*R߈m}pEb/P2@o`"k)"Yoihi H|s'ɸ½ .aoI0 RK(Ŭ~LYTX2b&P U%b7.7C$*9#yf xMΝb:ڲ7&ٻ~"@B5U[d+ 'ʬ*@A &x#>W(֮c<2 t"8gdjxvba>wVxԄ!*v ,=W #ijx.7T.Ŵ[B8BDSi|HYHYViMȟ< ů{^Y/p1a"{ˠPU(*s{0evI3sToDI@dKRxȈ'/T CR YrR -D0?Ⴡ)ÀXk$ИyВYyGihwt8io~ӼRyYf@$"bX3yR37C0@?m=mkXZ_G U舔y^WN_a '¦8e[ @Ϗ!.E CBGiaL_9Y^!- ,5q,0\e@3WNJANbO,U ,#T;TXz|.x-U n&':T4eQi8 WZϚ0y9EdbDob ,`?g4Ik%;Gbd XکFЦDž_3þrJrAO^"ǽ銼4-s<#BWGB@>bTI.^ UVyքvPS;¨Œo@O5pˋPHk`6j#B8ќi^%C/= e + (U$ 8m5.ض:Vkse\F^mw|[J=Ͳ{#M=Sgg|_騉-|p`"aU d(JHc.6 \H-Yb]ظޞ`lg-ik󓦂۬]DJ DpjLV͸E"߸PB,Yr)Ǵ=8{'8Ⲥn0 @x,CpЇ0ҙy1gq>Y=.pG ֆHfaJx*ۑtq6ql(46$nT##0Aƥ"I-0ٌ>^yPe<\_"霑5v 9yQMыT"F~"y,?`с'h_/ n?y0}ysXb2& 6(e+S]vo|Hɳr"y = i#$6I2>{1x"&coP\U3QXb ,GbhMTj| L[^hW@n`amn]q&dγk-?rz$s$ @KjfY9zyB[xy$pV30?h jT;"ד/ ~"/i5틁k玪d:6Lۚ*B'\ۖAUe[ IyO$AڐEbeoh,w:TkHgݏE!`/} 'F EbǚY9ήVOU&$%TBE[D!ba"YLdvU@Yi #~/#>L9D,Wᄼ!$$"5ڳ-x00i ?[$.Z{%,'Bd"D4}tA8Ӧi%L1JJ5 I[B/kW@+zh}3,%8?=@̱DUl{UPxQdoOpRZLjɛ;ιL;pbKN! s_ '"֬ ~" oJZbtpx_5J\,׃c&9f^U~AV&alSYxHVQ lxaiG}*٬X]V |tʨ8.b$+*>ƨ.ICqxD)NНp"} GU! |b8+!)!DD BgL"ĦjG@cT6H˷|*sY~C\m㓪)Jl, WX?WmǮ}يTf.\Ku$2o} ^]U^WEʱ!zg/XJM }tFEL4#', I2K2Tzu5#oUhn8J`Y)j@8TO#"T@8V4 Vơŀ?|4LJ[c ~B,ag !|qIyd!I}z ";I9vю\/\Z 1^$eI=^1J fȴu^wgfRP9=%P~$\Հjn]|rerhNڨNǑđ4@ mݓjD;9਽J ̞d* l!e{H)i3Mڧ qS_GhZ59k3#&{=B1ы:&f2 }!!kN<2R[@{&FͨtA@hFzGeqQE>("Z,W-Z{Y P%;Q-زtyA HEFK6{OP +' qE{O οտ -GQS@M.u:嵃^P!dȃ6N)8Bl'{*'cI?4-r+ވ8n0}n f1UhP*%Q~Aectaڪ1qr <+r%X /mȫ'ju H `w?qh[ng-JɈR5>tԱ]ySZȈlUĉ1ŹuFɌ$b{U,NNdc aҵ)̗7rh(n!Rgq=P8(`ΟI8O\h1+5B14KiVY_P5PkX'Z"攭UU3R5D@dçn&'T3no&U|2z%k(tčĔLz* ;Bﭶ2R֯%vL(^pL(N u\ Hn-!x r%bBUC4TJTuy('Dz:YhOpGŒ򾞢,eB{ x<$+nKYWN NGz*2Š?mӯՔPcJwl s?6CyAL9*M5q5o6'\mz[JN yI)v)ӫh{TlI~ Lsv28!WyLحJGHn"=̇Z bN0^ڤxGE[ø JQ8EB!šX޸>Ė6P2fFO!!E8[ ɍ[R Dp^Uf[{&UP6mI;q*G?maŃrd8$nB PI5 ~Ŵfs'uB`edjGxbWcI9&(/<A!y}ל-s*壂i7 +!ӾgB%N+w΂C_G piI^b(jgšj!Kz ì削WA+ZvĈ,r)_ K,ufsEo*s7aT3&a޹YwLAKl^i{J!Ǣ,53^*eYx؏[J j֯H`_y^ r>ӀGbn@O]|+θA:d""xŖΈQx!"qtCY"?a WsFfX ԊInr9ռ(P㞁&;6}{SgfۧK,fJ,(1\!.l rG\51zX: U8sJۥĨ7H4KXW7Eq; L>cFkPUP9R[wLz*PLx՝{܏ `Dž\6TPS:`;7@|zec9\/A͡icqy>LG^ /Z܄Ig : t'z_nM[jL9.V4YlCC Xul"]<ڇ_zi!\ٕx d%soN񔂑{Y?c4CĹƂ{N788>}Gۜ %opI{-x>/Xh>=b-6'7EFxKW;*qy\2jAŤ[y\ﷲɣFV}աt:EEeHw!OyEf<՞]Z"Gm\I4G\ucYe`ɥ9:!-m階 A :R?7jx1\BmUkjM8@[) #7qXA]1@4_[cͥ.QK{ R鎶EuHmPitN(|~fւ6vH=sZăI, M:TO 3z[Qrк;:jɨHTI ȭ?Y.㙱 v/+ Ou+oOud`ù'R>$#!Ԫ]s&[@CH{T |ŧli;# V UFn H"J;* :& 녂ŝk]xg,i up@ ob} mk]2wV,!F?ԉ, mcjӜ5@Fb5bEmnZKNJZbʪ)cQKgyH؂TEuTO8(ZvbS% c^V9O%mV8ק@zy\c ((M3jP/۠Љ*C`!Ve 6ښMPX}ex$O6 fh #/φ,ů JIy'#V0V:)OϬ@5E;JKfܛ6g@jq5AљM{i[ x)q S?ĵS]ƉG4|:r!EB?倢MΪ 1aЬwLJMx(c ىL񍡠rFUF/ѝ`]Rσz[>ʞ/qGUxA:jpgV~I+鴇 h坃5_8|Լ t"ϟshAMP$R7e9'O VG4^;<: ա=:hgehaPAKcw˧u ^՛(40*ݺ=Ѧŵ>!OPM#[==|\@D*Җ IJp#=RέU'N^nQ.%i^.U*S@O02ه ܕNn7)X~ fEU 㒋 4@⦊'0’tln{P[. fI 8ÚSXn;ͻ!CTPzjEU)4.,#ҫ}TU}LPcY_dt6(Ј#V_J|>a"4߆-DǴh7Lݛ-uCd&^/;dtzz`z>H8^hEr-P@vNT ߌGe|QMq_pL,#AQiWjGTkiW`tj *'L-GbKdd|fY85ZU $:Y-L+A< 8шf>d KotNҢV{W!:n~}б# 9xL) "IH,j'Yg k ykJNn_;GVӣUH.#ۆ`\ny˵e^]!KM[:M(Oٮs_Ap vFD!:lMrpP1J1bI'o>: \lVL ү}>WGEz7 רGWgTu@KmRY*nHx2(|:NN)B]jc\ 9 =WۣvyuޮAZW#NFMI`S6\.]C"?so]g6> =yΨ2fFum?rY;G0^"엶FӇQX6nKACвMc}UA]pD{hD&Ljeg*݀~yE'}L Nn0WM.sr{51:R:zd T?}/,"dZ:x"Q°<NwM[Yzq[ ikT'͒fؙJkh)*^nZ ?Ku~ړ*Od;rRcYI.1ծkC@֨}? u՛UA~uPim@ŧYK,'\3 qIPՉGuQ,|d?d@hws:>*L VW>e:wS]3)oU<B_j0ZᛴW؇V>!ըٝU2RD(Up>.?|OviY}tQ맘_N {_qO iCCPICC profilex}=HPO[*3:dNDE EjVL^#4iHR\ׂ?Ug]\AIEJ/)}w`4m tL%b&"_ tCf1+II=uSxߟգ,Df6:Ԧmp'XQVωGM #8\LLbJ OGUM`cgTa{Fri !,Bl1uR,<prmceh]?"qq>.P:O3p70IzEm⺩){dȦJ!Z|x?o}@79N4*y#^ywgir. iTXtXML:com.adobe.xmp 7 bKGDR pHYs&?tIME IDATxyt}՛.x6` ,!dB 93L^22CI n6,ލyѾwKwm)eٖZ>j֪뺗~                                                                                                           rS@D lu!ɌC5!Hldta׬L&X À8"qxf$8d~iPUx\õﳅyHT<͒9 @qcѺ9?kX>cXQ<) B!.0 h6&k1ʯ]DQ,|d2d1 a6yeϏe`#Rfg }t ʍ`0eY^Jڞ/E6{p<njDޫ<σ8hF A EQF{=)EQRXF{<)R{K1 %I( 2A0di~4ǹQ|hLñ4{x5^8ǎ@2AoDQJhz}n 6X]'K5(V=~1C <] Xl6;t5vUXh6z?VB4D @ı@eNUR#|/"9"ύ{>>v=4y~ĽNϓOI$Ĥ@n߫s?ǎ6SPqjjj)SpXe={v.%IP(D"yʔ)RUUKR>]%DQYuQuA4 PH$Z<H$D"$I%HD"700PrfT*q_͏}[{x2 @(_Q/KMs/&~QC I7}tV9sTUU%W644DpϘ2ep8BH$,,~ID]}d8yxAL~/ܱndY-EI>Eu_QtvvF8+(G!즏h 1 (J){*Ny}K,r)/9sfd…3~u8^ f83TUUUx8x/zvlyg huQu#mГdzppGӴT*u$LWUСCM6Eݛ }s40 @Q9kK"y~qsf̘!.]vɒ%̙3{ܹ+H$2GDQW|9"{3R#ɨ&E?dZ{zz;x`ޮ~Gj2-j( @ &@oAK|ܢE|~Պ+" -Y fBP($zb7Qc2^t:>00^4=޾OS믿1 3N+Z@ ]lQDVSS#]6|GΝ;ԩCH$2WH$En6~<ϱHBꥑϫzh,SDZ8ꙗ_~'|I4Ge?[ocvF&"_XFvlO\.H$zD;tE԰ AL7(r"Ɍkgyy.+rɼyխ 3|>_PI@Byۉ53Edl |3;P UU:.Ͽ k۠ ALhX%z"EV䭏/\w5ל|b֬YF"EPh 0؉]ME$)===l6+#zSo}=G &"$q8(/"+++믿~%\r?Q__jUUTa:v|q}BE'C߱6N`4[4`׮]>}:O6+n!2db| ` nc "{<O_y3<̵+V8//eZ$Xoekd%lm JoXfYtwwcǎeT IL6?L&Cf Aخ{E>Q~1᷻/+riΨ\VUUUiN iwω f;::d*cy`];d A0X}aݱH"˟g^ܩS6m@ [knQY譢&NbdOn(PU\H&1fm@ g_b}hk"a͛']r%S.5-nY( W'C0>r9hUUǡ( [`]o6?>8B!.L@h};qwa[onX;s̵gTVVDlbzn' x1d Jj,r\!_8ZM* @'!1~};! W]uUg>S,Yv֬Yk,yvv;EzR峚)e+Vjʔ)EQ"0|};>8 `l6L&l6 EQo3nIɌ cQt&K$|;Y~;wp81Occ+DVwSXS3 iZW8~Z @ ldt{$ŋ>ϟy%p\AFUDTva, N>]!eĨa ~%N\N>7W\yԩSenXX4E& J$HӅQ,$|>5 2z*7 ;cڧ>+/_~YUUSYYYgL:5M+QG]L̬ ğ Aߥk}guV讻p͚5_i(ż\߷vk6kd&o;4MC4fua3I 6/%_l`/Z=nݺ/0 ѝE`5$zd:C0V+ˡl\.AD݃$d(rFGof:˼_E u~koGG`h 388h4d2L&UU|[6M:Dcv)@ _`R n/}i7xӒ%KkD͉8gv0 +IfLboA d22d _Dy}?n+W |߾~7B*NeEQѹ9̺,UQttt```dlF:a|6,nx} A8/_Jeb衇κ˿nȞY7$I\^I2r9tvvb``085o("dH0H$Ƣ5o'WW~?Ȣ!ǖTu^|oN G>qtww2uLþd O/HQtڼg~Lj~^K5553ID$ztn+]]]E</gUU"$ό6A$F#~/~{[~饗n={6 <[`UUG7D΍S܌~qdYpg(($ s_Qv7ꫯy7,[`t?~OT/&z>Ef2d CC_ L @L6$IXq_,귋^ VTTHξK0mڴSX3xswomOQџr<7 i6{|>84d2u[SѤ ^{m=E}&Eم5B,Q0eEc@EQ󼦪j{$eeֽ^S^l>O뮻~ _~ XHKqEQl#*8LcGQ9r}}}0  Dѝ&-GS eˏu)kGDE_s9`0b;A5gM;Edh33V wb& &<ϗ{0v ~EE(}ݷkyyhݖk sA&YL&}Xг6ѿ$dqv)kogٳgD*ݢ~v?2G{tSߏlNXlEJ^#d 2hi`W_}u7񍻖/_W |3i$S`! Cpb2-&]r[===Sy`j ( 2D9Co'Ladw~??.iԩs~ e}vir2T28ƚ˯GGGك6 H$^5 n1N⣁ 2DF7(_>8gΜ~k9眛`$8ר s$LcsnXI?[ivڅC\}^L; ;' @LTwYj=tWV|[K, >}V0/d L4\ge/`۶m8|0bEUW P-ѾS3MHv4~//x\sӧO_j^SLc}n+_XnwݻRswk}e'aY 1Aſ>NR_ Κ5'o(bRL'JO` 1d+Yi&lٲB2dqUWSTNeI0#@bUᏡzGSNZey^]cO`|ǽfWU >ǫ MDnKa' 2dxMqyMݺ>_7,Xp]ʿXd2T2`iUUN<ؽ{7da dL&A ~=_bm_ek_n;SN y/D&YEn&wmUU( ˤ)"ń@b"818)~n)a7Ağ} `Y/&ń`2"642b=0 Ȳ7w߅ MMMY"~CnIP b#Ihֽ~Ygַuyw:)v!gc}K<!0ϼy~XHӅ~alٲ@lli}|+ vm!@0s4o6Ϯʕ+?-"qdY.D/zd.DuğeȬLa``O>${=B46HR[8𜪪98팀kd@(7/sO"]tQXh~vs.ɾ܌Ju 1[;4$IBGG6n܈ÇcPUx?g5MD*ܛݦ3L߭_s_}_w'C~H_TѤ!(ׁy 7)\.T*p8ݻwGE<( >ܴ{ <b?g#%HַNްa}ӦMmxC ~XR/y|>̟?ldLFݳgOݻ_7 &7(`/MROO8tM[U%"qҝw޹rÆ &dp4җ c:`~s?\.t: 㠪*~/ 1m4q$I܎;:wڵ>ۭ8@b<8Dѫ[mS_b]uUWQYY8>:FN~d:'IHB!߿O>$9+W" Dh4K/ 7@dq&6R~Rmmooׯ_P(`)Mz?co&)(u}Rl_:F&A0[o'|~k׮04/Lwy)[Eߩk_H$ IDAT{]8SOrNeEGt; GYQ'6A*p.e`c '5b0rJ}w˺u><'DQdHl@RJȟ9d2HR/~ b͚53gӃ͛{o>2V,]"O(@_ /?Λ7/~y͚5W If#/iɸ e`  bxG!֮] 9rhTokkK^h5E%Wl2Nne `TD 96t_|l-[V^N`r;f~$i.~ !HfoK/Oit:6en[oe hϋ[-`x_uF@d Z쇡Ѿu{֬YI珩! D>n$~`Q?KKx<~ʕ+Ѐ^_=v,#>g#^Ŀ؊k\ J!N?<~_#`ժUuhh4iӦ]vi:1׉kCj}: oJ & ,<<3\z9%'t?f2'gL&i*++c=̙H^ziGCKl_qsd[WE$I(deKCuiƍKJ;DG2Ku]/4%{dƍx70|L:lDB߷o_of1 bh5k3 \l@<9B4y ˲\o/ "0ӿpDTdC`\o,~a{Xl***000T*~0n u1D@ 8i?e'ي?__+ϓe|0lG?v"?Et"C=,/2ҥKJŲ[l;p@G[C}r._sSϮ럢vVX//_+V˲KTh09F͓AiZş ى8p,Xbbޖ.cx~/o76!@g~?6qqwjTs=k~M/3e~#Jxb g`ÖR)Aľ}0|]? dLuЏfHӅ26mTUE2DOOO|ǎ3'W$[WJmZKO8nO?^⊋[Vg^v iV2(cf^7 >eD"hxnmWVVO~sϭcf?x L  ""J?<6n܈L&`0xÇ0 q($rvwxIEN;CO8M@isC }G/:"-3NL\s2eFcش?4 ywضm[a`.ӳhtEs6K.?PO'}w}⋧);/ELM,'C`wv[a?O?46mڄh4ZW(Kh:=~/?xAyx_4O믿ooITg} X5id/X EQԄͅNf̍7|n(Œ=(}oA?NnڭQI)@Hln.s~sߚo۫/Hx "UM3,LjrL+n~?СC /麞{׿-?%~ H'RD 1 8nngM,Rƣ!,&qX/ GݻX(_zzz=DźRniHʟuYD@%d|+q"֯_߾  ,im()r.J#7@۷oǻヒEqGGvO5i%m_$ZGDa_)DP׾b֬Y>0Jzx[qwϚ;wҘցǺ!25O uR]o>:tkZϫ[_}= $Ju:9_go nw^%[ @vAy]:::o<򷽹ywM}Ú4ğ 0qϭ y /NynDM4L)DQ,L3F9r,4JuF/" $_˗yG0D</{$C0>Ş$I*0s}FYGٳkvCUU:,Sf9r}}},7Ey[UJoX " @E^.7o^_TI 2kD X9g tff)w2qK^we7&lJa@e>@gggFec?&@u xǺ%*fpq/DQ$I(u'2EQ(5Sl)MlNխZ{ pG|=f.^Idi&a``4/u~A'qF0}`>UW]U#I~è=!(7Sp o}wu](âid~z }]EBfL&EQ ;;,Ca.M3$!Nc8|0٬yǿfݰ, 0k?M*\$Bŗp8KF s7>m<s[|6b>"τ\4:,4J~@Qr9DQtuu!"AUՂ3su˲:@e̚5 ,L c5T mmm, u}[79Ml xǥo6GG'Xtuׅ9*Aض'$4ve^'IҰ8nvbZQB$! X ]]]صkz{{Ődey6Oߏ `X|9B ~32 *++!Ir$Iz.{Wunr?f?? ! R@+ B<{&!fE$}'ѷ >s\!fzzzp!8p 1c ,\gq0D k,2 [&A&A6&gqE~2e b ,[ +V(g{:t~4Ock 0A/.ѿ[) X `ޅ^_re]?2HE.cVӴB]eb1{hjj¶mߏ9s`…k0e̙3SL$I#"N#H "!a``D 撀uue[a˲a`03g3D 4B0"6u+_7aً:ʛ @L9gxom@ ۰aC] ~DΉ.,fjN<4)>{o6$jkkq[oܹs1e̜9s9udd5-jZ*B&鴞J\.gE4c zypC(2 n]?tޮ555GQX,d2%I#\8qL(,WUUI”)SD"+"q;s ۪Ujڵwpkc? 2Y޵17GqnݺH(Yo|2ѣrcbMu_Vg5\.L&`N;`ӦMغu+ ."\wuXx1jjjFlc֦޽[ٹs{nuݻ IV!43l եoe٘7o?g.CrJ, ޜgkC$IObǎXf ֯_+V~iSݹsg_g_Nw"];cae}ҥ^+~gi[_5 #Xn㹦G J2,_,Cn/~QN*i_r49citXs,j\b ?uՈbxw? 83O} +WDEEň1XL۹sg_n޼YyWu5^RNWjkkb AݖIQC%qE q/_^)"***JKG[ɠ\Mɀ a?kyH_~,ӟ4֭[3f }UUn&g}Vٷoaz_kF5 YTUh7I&v&ެ);_P?A`b#n n8wwD@ #u-Xg (id2WUԎ8`۶mx衇}v,[ wVZYGD7o7I jGG]Z^0yAX_yv+eJ m]rdyZXp *_Эt f݅ E&8@EEEjժ AƼָOYl $IPXS'I*l߾> vލkN:L&cر#?9딮6 RFnMqR}7j :kS IDAT `F-sG ed-x3 BW_>},2dY QD7t"H$ݻw#كٳ5 oFP{{{YGD^(:{w [^<)[ɛ)v3^6&?Ǖd('L4\RN5s m 5իWW~. AQ*LϮ>5pt?j#<͛7c͚5я~ "~0p[o~dz/f# R|ߛ,>N{YngľX% `V1|>[Vw[-7C?A`9xJEن*'zj&<Y Q?abϖr9Y={9yUV~6MMM٧z*0H$D? C~L.X,5Z0\Lu>uF @sE5`(} UUU l45 g9r<},Ata6>f766'@(7 Y@#H=SGy$b1L:[ |ϭ3*F?YeD 0bÀܖAgDQO?$I0ir,HCFs (guT* ԄB4M7݄kע\===غukgI>@aRZp*-&"C_, 5o8: A`"E.Q5PP`&nٲe3fئ-NX!0Gb`{:B_,??PzK?"f48O+e_-CS2bff!/SN}>$I*: Ayφ%~ttӦM֭[qF_*֮]^hjj>^{MS4i~mTDΫ qlcv~!c+^E<&-F~T_,J :6Ge=4.C"(D"x'˖-ߎjhnnv9>R= Gi^WW'ik8NN>䊓N:EY>$]uEQrLFI$h4dxH['TwM2|MJp.>_ϝ={67w\$"fxpQ `FggyO?4͛38ى[o躮0# MSa_wk׆>Ϯ\bŹ3fX(J-o>ӟ垞Q&htMs/K,9wʔ)S}>ĦZgGP0t)!3]fvq]U՘a|ԴeΝv>|X{i!qP~I'20}ʕ+eA~„\3eY N'IH]_ qꩧbbG{{{wމ߿_ ~ڤGnQ$I⋧mذ%K^SS3܌?0>_8ֽ~ \sUg>6{~A+@{a$I S y.okSkkk?w^wu;cؖWΝ;Mƹet]\0i2AX =}0oLe߿jժ  j*աDB߷o_^H뺞P?>/X$~wg}~CCUUU2>@ccc_~ǎ{y _~WtIB!\Hq\aʡƫaSUp0C`63!'I IfTTT\;&G,53es$"VJ]G`fjT \SL͛@/'e˖,{1?Zw?ys΅fZxR)466^֭[3;wF_Ј Wp7y杒OCE8,y @ cE)f|?hnnFkk+ŐNfjeYF]]Ν>}z˪UZj&iݻw殭[߿?sСI Űq$!?Á LIC CLcoΜ9b0CШ!;O&_QL>ӟ# f͂(HRFggg_AJ4… }vے?/3g,ûヒF.VW.p5Ct&AǑd0|fx㍭`:{K/s~_b"L'"dY4 BQ!"MMMػw/ߏf$I;74Mrx2键jj. 5U|6};1M&iK`fA& #@g"fm7r\ \8ieƯ!`$=x cԩH$H&zSSSta C"~&Nƺu*nK:묋|͈lV׶~`h( ?O=$cJ ~I Q14m;e<#N7oԄ?oD"L&a͐7S] ]1W5rߺQgy+Kd20` 8 bˏ7.L0ɤg28_uAoXɠo6mڄ6 6HK$$l,K DsCwCU*OpN~ Fͫ,8a1|eSF%eDQd2'H(O1:g4!8_HXͿ0ԩD<G2Զo ?-jE|;gѢE+EQ,{<Çx $IzW_}J^o^O|b}(A@2,̰6e2Bhgënga(FZQ.ulqtvNg[8cojjkZdZm. (KBB䜜}{y9' V\Wpw D8P5Rz J%IGoL1·P(@QG5k xH$dуEOɄ~>^{Rd2xSOaΝU/F*~cW^y%nȲT*e^ f#zk@04 tLMb1?BE\.L6 @@{|R@k Q{ynǩ8EQ$Ii,˲(ic%0 ORUP]8b6r c6=0 ډ'gh@u\`sD"Xf ֬Yc' dYc{(Q13lFG3X!Oϗf4ưa^s\pޗ}>f|_Q&ܛ?Y av@ɲL&\.YԄ|ǖ-[i"0LvM!Ӡߥgix⊖?ܹsnw|>f#M45KT*)b,[n=oۼyP,ˀ(&c P}@u 'bP![% {,24ۙ=ATN,8$ rUP] pt+WƆH Q)} n,X,X,"W^O> YJfq*4eq]wv 7}8r2Z$a޽ضm̽h4IY~/Yl=V2(S݄,t7ĿۿСCF|rwwhGGGQSDߋ;&_}7x|˲* =9,˱,lP(:s˗,Y]===}u/b4H(S hvhL&Cm˫ C&?=z_:V˲p8cH By?G*B(22ޞޭz5JJ?eY<裗\tE׹nCOoRUؽ{7FQ%IZN T: /0$2t>Q@l6Po;}}}`YH v='$@i2Oj8u]M+W|_|?xB Á|>_UP]ǻ*l=&f& !h4MuSL8 F$ B(p`ll ?0:;;d044ӳ%AW>o`0(?e˖]ꩭ(>8| *&Lusd2ƎJ)ɓ-x5 Omny޽n|tZK$ўW5M_b4wG?λeYB}YOrѨ1F2/f_~>UUɉUA&S/Ixwq `ۡ(J#BaJ `0>ַk(B2Vjfԯ3o '?C5BȲbe 0<Ͽs=|s{wKWhJ @ () "h+Cu7`W%f5kiH&}>tS: hJȹ\θf>O=6lA IRtB/&q=|sOkXhkFFFJ(P$I$2F9۝Pd2'n/h Fxa>P(Ei(lzs2?^p}>8|/ZRF(v ZK,T <<ri|666~zɒ%gwرX528Zj>t*Џ0@YeTf|OED"+Xv-,A\$x51_}{7_tER d0QRj3::X,fat~WWW]tEnI4L IDATe,?]\=?AQÇ( ;QrL\p~-Z4pAz;.S]{w+$p0xxX-!,àuƀ9țUP+aL}& {MIE8i8A EQ c׮]x1<< AH$励X\.GZ*eOߟYjy,RflQH$ŐNiI#-,`y91Co]^x:::z0D12s_gϞ19l6USelyqL%q5tqp\HR`ommL$9sڵk3όaհ Q'P5vI&9P.̈́TBt:f6Sʏ, C~gN'<|I8p,OK/}X?ח˯s2l6۸g L J!HabG4 ԧ\,]Pv5:shڻw/x d2 A=f[w.ihhe RTITh[AmfFD v&Fa>34p8vH$066ư,{UW]B[[{ᇟx 8RPʰ %Ւ))8y2lL ELEC~yO4(LJy,48N#fYcÆ H&(Jlttp?QZ.  kjjl8NCoZ?p,P(Jս9ȍ7{^Pz饗i&J)RVO~򓋚#or14}R<ѱωXB\>---zy}뮻zӟt~]2Lr{UP]^F4J-\~RI$x^FD|؛ VqPJ~Ç ;VM\$ept_he@{ŋ=:љr4( Q (tm$1bqJ(a^]]]XnFFFk5IvR1k|kמ;gΜqG9Ƈh9IQ477~mhh8 _׶rIA9M< NIJld hx?S) ,> NA/~ |A\Ih69vO![Y-~RO?ɵ^1g4[k:N+b1͛'l6 N DHT$GMA@$v:cb]3(:RT_ߢDZi7Ѓ@ rP"P(SN@z2گnEnxg6nʍQ"5 *YZW]uUh.JSޒ (Tx,NŢ#:@CCx|YxXrشi KUՁK] ̽k8Y QYZ4F:83?Gl6hIP, 0VnOev D"H$jy睯ݻҞ2{[T_a'$_{QXjob19<##A双#y=8nu43rF0]v-:;;fZ(/%ɸ%O6ড়⟠Dǟq\D@z7*fq\XTXp!IRD *e]]]ؾ};L"C-wɲ`歷ZsYgفR?V>NH͢BA+43 !LB9:555-3f%K+Wco8d V_͚$OSS$Mtww:tuuKreYn#x̙ݴi@D܅+Q.EɆov91\&ۛ10Fi^Gd2IDQ4@r$Iذaz{{ e!yhqAH6=JsS Zhж}vX(%A fd088Qeaٌ@evHRxvʕnP6¬z?E](aF~H>7 o+`9`<7!r_6-T%\-\P sMEITiA}( [oa֭ؽ{7\Ax^HF*`D҂ `֬YB Jdڴi?W`V @0PGi4yT a'"fcyUWWYlo ?seA ddL.kܐSAQ;㟢(y_N5Irlo ʛ\1-rіG76Ϡ$[1BVOA.7.5r5X%T(xde)z>\.A6\s-\.D" _ڵko>-pP7?n8N`k,K $!#NΝ;1sLa޼yzmjj;{w~erˤ]6胢 N?Y}Syew\򕯜~뭷rC(9o';c0i%X@<K/Çuxa|~i}#C7͏x[AI nx< ph9q8ՙLy0 3Po(R(~n<( j*&A'y.PӬ|>|>p8 χz >,^{5d2x^̟?3f9spBeYeppPڱcGCܹst!uppPOPˬ(eJBl6ޒ9$IfƤ?صkFFF}hh0&7tSݲe~oL^"uuuva` f4&p8ltz܉F( 8͎&̪ !g@aMhfZGgqRSG?&(t:md\N---ػw/(D"8ӱ`yhkk$IΝ; aݺur'D]/FEFh4oV0(EF+Nћl?Ln/nA8ʦo޽%\ 1$Ie& +IbX,8`ƶrt$P.Eu H$OWFFFd̛7K,iԾOO.۱cf腥8uuul6kx^x<0qOd}2t ,k-cÆ رcr qcx|K*Կ9mmm{V\ic(@IJ,p8L' kav8lQd2\.éT])zBL&c;|>/TF"8Nvppʞf쿾\wB;w.f͚)n޼9aQe U@I+ hMxS131L&y?t:*JTXjmelB$ SuU)EOF[y UUrRv6me^T*e>R81iڦMr]vKe6cdd>~&k"]C@W?˅>K1!D$*m_3eqh3 dY8_W^D"Þ={r׵0[z`4 x\ B,=7"!DfQ(ƍ%VZdYc"q?:a ٬1ǡO 6nc1co߾+RܷoV&dP2ȸo * BTBfYMӜ9P*!L(xX $iÇ_8~ ⁁[DQ<ٓEeqVopS BpZ&apf!r-?Ma @76CFlssWEtv#  % hx<ln(gA{{AdTvSPp-_rx< ( En`p8rʵfTr2 :RmyddP(h1/EQ,6=PE022Bx(h7n8[L&l6 aP__~wuzzz 0w\j\.~]́Pу|IS0lkmmu}ٞӧ;vzfEs\.$r\rttt7Ⱦ{+(GX4&{A̲ef}g XHUP ?P3B2\,yRdڴi_`{wM~N ={Ntxv(\.֎{0?Lp2^/X(F$ 555Xv-on|_gq|\.Wg @ޚlnn cccZ&PRS^WD"F[ڱȥaYrV^i…q$ N#:rGq&|RQ}DH42QrOђYJ獡;ӟ}ÈD"3g^wƍL&C(F_^o,XtR9s3f̈444fq6Yb=}pzSTw[lIprWxA*f; /pqTz,W D Xr🊿?30vfs D<όK/w~ ( O<$)]]]3g !\xoa,kۻtO?[pafDq57I&3Qx(q:fÇ PE^/dH$TD8U<&D`>S5ۤ%fXsjylNv? ͆?8B^}T*RQQ^@ | ^|-ZRWWggYPE .z,TKEV4J dk[ZZN[tis5k6?SEQd$ @t }|,V0! PT_CX,EQQUXb6mVoiL|>i (hKW0D]]xC246яzfJ`tB?{1f!LBep?<<^$GUgSuf|nnXX$>+.addp;QmXTv D  @b1~CTG(*gfm 4AӟqJ?QIX"LaMC&1/zcccxL&sL9灂:N8+f̘qޅ^gyׯjAJ$0DK`G T N?Y/(W0 XDQ4|444,+\v:ާSzA'˲ۛjnniFY46tMNkeA^/l6AgYȲbۍag?þ}xJZ=FL&(o;C[b\.ez9+{tau``@ff3XZ>s~? h4:fņeYDQtt~9Z:lEL?lbaY|,Bqɂh|O$?㭷}g`0t:]غukRQ=:o_LPgEAP(J<)<СDt8B s9o̙+W>q}=544`9Jz^M{ Y]bDP'I oR\.P>qǼL8޽{.4b á4(\.p("n߾}Tz {f˿~z zPL0M^0>)rsE1\].\.} g/_|NP}Dg21TxDVTo%-{嗇n7zty|!zGI}TKӒ!>L "P@=ړ r.US?:vctt>(ۇp8 YJ夑^\91(YC[mmm-`dppp {@"98AfYp(rykoo[o<Wetl2wKW엲axth4+IR P(Λ7(@^''  n M"@[[>f_KK  fcZjXeT*%*e6}̂<TrL{Kt:xEQl66e$cɒ%0%2UUsW4ޞl6ہh믿yl6z (I8P < \UUq.ĚTlQ6v˶ /^~'IeGihTf$ZПlU>̚5@U[[ ANƆݻwL&T+!񳼁R٬p8슢H$2p8ZD bѨKdlٲ<(MfIJ٬rT9+ǘ \p>ChȲ,jkk100O+8"dP5559 yf \(VHeIGGu$I$ 'Iڲe˜v}39Į]x_tP"xxsWh_o_TSS=LSF2-Hz^_O&{V5MCXq#띷p¹o߾&TTd 8K bb+2 1sLBL&JfAAMM n7٬lܸ.#(qElܮ(&,MQbp3 <lR43 (*zFok=M. 7 ~_Ce̘1dJĮ?a_No]6Z!7lmmuP!d2w}7^ @(T ( O~2D0}t:5n'4<߳sΤHd"c7m$IQEy&2EݚL&aPSS3nS¸l`~7S,#Nr DQD>$Mx3mmm0OY*z$:jc^ӟzjtzk.K _}ͷB!eRv-6lZd-c Ix ,X.޽;Q3 OR(Up*J.$?g&z ꪫśf~^蔹iӦAUUpL/ߟOA:ab"igS84MCccQYf,\{RTO[" bϞ=xk.,ZPnٲ-8_\"gqsʕAE(OeYƍB8"%N9tF=a5kIn7;::*Fѣ^TJ,˲:A㞢h2@:6|oooFq  1 6J2eÀt i5<<|rTϮ ^"He(\9Q .}>|>roرc 0YЯ8+P';LWϙb3\}ՑVB0222nneEf͂(_sÔ_Kl@&x>^,EQdYB`xEQd2q:sYn'2S9=4@B7b EQ⩧˲Xr%,X@'i틿}###[џ5z8\~\uUE3(p{www{Lח@l'UO 0Uއֲ۷o/3dx,[gy7@f@e*j]iFdrhiisG( BP@KauK/48FEQ?Y`Aӏ%x^CCb>G40[safQp8dj  -voڵ+Q?:nR5 @H0D{ 0W_}u TqMedd҂l6wygXbZ>;ӳ,˲fTUe#O0<< w.v%DcK'GL3H'Tm6?ŶmpgnܹsQ,166&oٲ%f͚L& fTiDO@n`]]r|Mx<ܳgGƽfs:Y%pF;sZ!,Y 2<o߾h\Nr:vs~px*Rer9P$y_1שTJ5kt2~,ݴ"F_F_h4:` 饗^/mEfO)!"NCӴP8 `SWWW֒OyZ! N*ma)Xgs/G}Yk&ڊbD"1Ξ>$dxx`555DźH$"ܹs@4{8+$I-f !lX4qx+mvX3VY(eLin6G۾DQ4QxQ,Ak׮m݆o3f@.Cwww瞋YfPUշQ}&*el"4MSlftr^{m0 q555,H&r\{{,f'EQkhh\. ~fX)j3x<^? ʲ( `ePI>ugޤ2UU=~Vo ' ֯_!BO& BrjywqGm(bEQD24 GX'~X %zd2hhhhhd21AД ˲*/BDp2`)83Ǒ+28gB{9B At: !m6N:ąI54|>_8elt 7ͽWsmPT3@k҇R!uTFvk4S4`|o#LS>cŰeYwx7lC}_l> `ժUN;R 1UUf͚YYqP{{{&^b(ՙ=8zr"0 ݎd2t:!"NCeX,滻fZSSeYB"=V(M/"0(oݺU)H$ `$Pj65!0gպ<@$IR{zzDM6p8nA< dYi&Q-No-G1.m_׃7tZE[۬#i[@mm-8aYmÛ7oJXejSL ,iBpWϟϙ@%+S3d2í~?{TF[.4+ K( p ðԏ=H c``H$B^Q-nt9 4Y\Ak ,2ZcB+:fx |W\q N/roO>Y-R{&?]vϿ8G4O~Ue4?Ȋ+묳w}`f`DɰM qv444 H03fx7&ǔ @C>UgdJ%bAD(i,and2O,Na( x`Ŵ`[V|>/ńw\.'!  bll CCC͛tR,[ Թ\oAJ^ZMdB_gvK3|>dY;# 6`׮]?hllҶk׮k[n%/}}r( SYiƈaB$I WKK @OOOq\.~#R汹p\BPUx$ʟdO?tٛX,J###H$ q% !N555!#! ,y3.Λ7Ų,IH$H&d2n P;o{#4Dn&[KK@:nJ1| y袋W^à ٿfbA|tnhU 8G4+iMi6`A j޼y(\}}1aWB7|>/iZbcܹ`<Ϗs43i-yr)V{T2_>(6l؀p8n _W|rCY/2/?L?Cf۶m2$wPRKl}<_Wjkks:~ 4ꫯ466ӧOnQwm?~;,S=-сn~2,GL$GtV Rv _8JJJ`0wkN̦"H~|x'O4`04d2魩8~xKӳDBO0#YI,&چH>ۭy[HHYFQ^W`;9sf;sUz^&q\^ЗHD  zzzpBdYJ-ze4{P3qNoB?$yOn,$IḥgFƎ`ɒ%`xW^VZZވF < 7@>ǽK|y>kٌ6BOR/ uuu?>f̘zX,fa'R; R)`Xz5fΜy{:ɓ'_|'===${WY]?'Sz뭵7tu3gl "&[:ζMicyQ˲4,<:˲pH^EQ薖ɓ' y"RbKK Vf0d24%>x0p8TMfNWIII{^v"pDRTJx٫oۗ\ve\.~&:::۷o\~,Yha(d2y\[˥cA`Yzuz޽rtEQdS @ rC&A2k{'LDJoicw3x(MLtNp8.v:p X2DII *++p8L&v k֬x㍼h;G"0 JJJ4*i%6*[SP [r%5k,.C)o?z`SDpR)!CqE?dҥH^z~rB-Kv-4TRYi(:p8,H J_o/:_6A4(btt0 hlo}F44Sh?%IbX*Vb93 2$:tH;NBmk ɆV+jjji&bƌ(--EEEE100 f|%U3w4Poٳg7,KW2gNs=&D+BNrGy</d"x4'D"A\ y@E/1sL(9!x\2 g'1 ޼yp$o&GGGYIP(!]SSc={njjQQQedPP(q߾}ZƠә(C,(\., h&m @pX:MƎ' B g2ga'M?Qr@Ϝ@GLH/%\EQ>}nѣGdySpHZπ*:$iMy.Xb8%IRCie+ HX̘1nvm={d("p@- ' d2a6͜b1R4Mj>}荁fEEEaZO8]ED"Oh4jbrWUCKK $~U?7ߔhy-[lL1h_ y-555A<G4XӉRHh4TϙdEl6sxh-~2h| ;q$]zd2rn%*dRr4Ξ=+ ;wۥD"LpM?Sڵk]_W\r1zL}#h4{СCE!B2;3h,$ ,I|IR뮻&uA:F#d47L"`͚5"Mhj1=aX ڲeuɒ%={$~xQޮ| _wW\q%AT$|>0 c^jUzݳtttZZZ<EQْ-ͦY.qx -[ y{~&lނyEO%(:H$&@_^ C\.,YMCBHf,Qjt00Lssw}wuW=@i`ݲ addDy^&<5BQx<d29͋-syB:Q&w! UP9Ѐ(J2Tɤ<00 Ө=l, eZi/T偁exx<+00@N[Pݧ1JYS/X~vƍ;ɱrd27ӧOkzFGGI6:g1<?J8N'c8Nd@$q$6Q\~hhh8MJzBz/+0  zڹ|r;/rfddnĆ Rwqn:SIImdd>tFFF0$2HiK(hJ(j,T6 _k\z50 C.KUE}zo jX1<<6#; LX4Çj*X,?_:tHĭgA8MwLlOajEeFS5v+ԑbll . >1sVXq/Ѯ.&yH=*tv!M/"cP 577͛gزeo߾SO=|E]]v/~񋶲~FFFrSVȲ,( $(ҎQ$1LԲxy^Z$BS dV>lݎ<`8z(BF&L$  ӗ lR^ {,C8F?4a̝;VU^zVQ-p`ppXd ?hW_}hź&e;0pf@RzC<nP(z$ AG>+Wl9zh+ҵwި:f}*+P 9=A.LLLFT@M/0I7od͘1eY fڂ^mɲX,X,Ia(0y ϣdYH}Ϸfho"e7_5k@ Hj2TJ8{,O^(--̃fHP#'-ٝ.2 ʸkƽyfG[[[ѣ;wNqX,V(˲Ph6q6͖N$˖N˲t:MB!4el$I!׺<^/#֚w> US(iяN`Yغu+8qF8N̛7(//GII \.6r[Wɤ<鴢QE-#P P~2qY$Fv_{5TVVbΜ9hnnFUU\.Cw, :}4dYƲeK.ZBT&( (AYii&s"U555l6̜9`fZVVfŊ-oV3>l>vڵ+ںvu|hTBz>*TTgP/ݓ< uپ9QΓk4M͝;| 74^~-.5l6PX,~◯1=fC<ϋReH˖^iOcoȿUEaW_v\|0گEQBPyX98mtt`gϞšC/uuuhhh@SSV+<6W(iB!B! c||\C<ɴ?Б\¾jI<º9r],,x+D>}:RK,FkCMy)lIo@hS%⴨( L&#駟F … xb,[ ---zd2J z-᭷>ڣpt l6sL"D2@)```ըÌ3P[[r8MdFqkjjBm|~H əLFbY!Y^~m,# eY8Nx^B!L&æMY[o A\.Yk׮ņ PWWYǏ O=Tf7LA@ HQTl636d0, ðP5;B!m.C0̙3QWW ͆!tttp\~W>?qp8;ا4@yLN=%dNSOQ0 N'\.YYY1o޼뮻nm__OرWQD]?Q?|<}&niiqlٲ~555ѤB(h4XbTD&0g7RS{dY}(.ԳZ$Ye)u"#7eGXɒ%Kl?zιeYbD"u8&U,$HQ@/IF766LC>Sg,Rh$9=44uq"fU]iOj"WKB1RMX,1 b}DŽƜ9sLnvk)<ł3gbϞ=xqI8N[6l_׋@ >c/ٽ{Jd S( " Fdi$ p cccØ;w|L&A$On}+d we* wzdSÅ`OO"X__Պp8)/$M$ dt:g^wuXk7;qxFY .,iv3]tsʕWQYYu8a(&s+ ĭ8$Bι}!64Mk DR`08Zuu*`>00 gYn30Nl6_d!#`̙̳>",ˈD"x!Drjq qR#=z; v̭'YqT(yZ=[n~ 0 u.M _=6l_ǎ+\yR,K4ML&eY QWg^^^ `WdYV|>3wN9rDf{ǓT*ח$I>$GGGӱXLLRR6eYVF#eXɖ[*++V>c OEEf9v8im$`I>T"uZBG~3 ())FɒYz?y:Q( ?T244$TWWm65Ao=|!&|G_ʸk׮~Ȅ7,22EQ:8QaZm SȢ(JHDAa|<>>.uvv*}}}S9kL1`(xEQ%I3臑Fl88vL&#X,jgZJKKO<`ŊXr% GyD8yd&xÅbiZ&&8RKyZ$IdYfTKcWY$9DV`0DIe4ohz-˲#4L꟰ߑ6~zWo|"|"7BqThm]$3ZJT@/h420Ŏ[h:@HVHxF5ra'{15F2= ':q-DF&ɤ $r5wO?tꓟd2YFp8t#`@כf͚eꫳ{{lGG5|*S}r~1gEᡇbŊnZt㭷ٴiS-[j<Of3d21=zt駟6ZEՌ8;h4yb&Ν;_>gFss3f͚ٜ}ᇓ?C9-qL#U^z{ʕ% r~~?_r/} HDcǎ o۶M+rH$2eZ=(2$II$0^e˯FNAZe"6⽰Dަ+ _@*Oٙ ^pAa`.HD"o bdI1pRx'I'TwQX&k2 L @:4OR٩dRFNg~ԩS*DQ̈́0"+1e믿ްi&ĉ={dڔcǎMfI\k14nXP⽢l~}sJdF/~y.ˢgIhƦM2_|A K }nmTPDZ80\pLx饗uVD"477z)ԩSb9mCo555_^|y j+**lV!lL x*0i)Vf+++?~ƍo9ۿ۶m^'εc$IR<d2 Tl6(boh\`ɓ'u,vT{),t QAʬYz'Nh}դ C0'wl nCs8Y~R)P@`xȒ$?Ov!+!'b ]}:HW_M|srGa||.KkQ~'Lp6l6lؠa!CCC/y饗Q`ThLz^aƍ΋.ȭ(ʼ_u۶mqL옉o|M7]qQQ;|=eƍuW^y6^~Q ŋ6l _q[ot2򭬉"| N:V8qEaѢEd|7AcLwqGڵkg֖F[r2lNNhy!WIhr[N馛Ǐw?|#]oEQcǎ[ZZÓdDx]WWɓ/'s-͞Ow!ٿ~}9uQ}۷/s뭷ʥ EQ)f5C@b) L& ?MZOtdfEOc^l!?_p$-mll PD#`ӟ4ܜbYBvnP^n~mx< +Pn/Fű1!ˑHDH&b&*"((J8Nlp\VTTT:OYY=s>nmm=o߾gM6y`M[,^{7oqFu%6izʕ=oogyF*BE"QǤ,344. Z/ աl%H('O,\z1::9We ة&D Z&J0d/)MUA| X `ttTlZHq .@nݚNqgG Дd<HT@Yb[<ÇֆSN/nՔE1>{zku: s/ -Sʲgfvz;ہ\]S^r]w^hќM===^N8!hBT*H$.tvv"`ʕqI>D"E1 /_n;lܸqgXfDORht}@yY ">˜l68v;f̘|aIvYRezMww&i4PL ,~-a O?O(ǵv}R?6(e7x!u Y % VED0Fe]{ҥKͤbnjj">a?<`طoN>D"qOLXh޴i;>>.@:gy9mV}w)//, 4Q)0IK D`[?LG"ЀlN'?/馛I؂ M!&Yy}<9Ӳ,3,nfYEQiL<(X_ _$0\[Iӓ-))1 $ qbP(ޏ oz`;>>)Bc>ϻnᆙ[l9:Aȇ\\]+555IeӞdbZrlf][oadd_WE O#׆TקjW]u󷴴Xwo?7/]xI ٳg+'׿\s\N>,ZiȲ\z饨֭[wX 82:,}?^rW7L4yhT DG|+ ipR  \8&V׉DNrg͟?_޽{ͅH4Yfev}qeeepp0z`:O]L]k)5@2D{{{ꪫ2l6kgj?'f D[1H_xnyGkkV!&*_4Ү_~9s޼y۷#.B(RG/\Дd1M AFVTTi$ mr&&Aعs'<(%,Kτ *$ @@KKo6Q]@@9p@b8tꡇ >w}_ @Y,bUVV6cݺu#gAзM  ڴL&`0͆:,}>844ԍ"=txѢEF"mPH ,M"&\sEfL&bE-\3}[~gl IzW:eYWyy7''A{Mw J'D)Dυ;lAβ4"8N޼y%H}}}~ 1Q(6_X>}4n݊SN!X UeXVnv:{ ?*[~_ll6b1-nfղ{n4|>z-<ضm!hK###@΍ 9Z@lV.2^{5OSHD9|`2?cod?U)<KBw !&>gΜ/> d|A8YtEE$IaR)l6ǿ/ #7|#Xf2(ۍd2Iea00+4w'OnX3A@QL&rL7oEC @Q)$x?RRRXj0CCCΓ K8 9'a%DTօ"hvww7ZvN:QA6 L?l%믿`ppT)E?3L_qeMfԩSGEI5E#: Jd2>C"$3n?ĈFC[[݋Gy2MXPzp)D"HUWWyqtt_[So}k߾;'Y?p-qR6e2 t$ի؈x`Hӂf3'˲Q=;00 ҋf-ܲvsNtD"/$}ͳb i ph4!Wmyȹ\/ORqWLx!:cj(f͚%\.s((y`d~/Aqpݚ?h\.:u >,B]T*R"(`cEp%rI ɤ`0Dp.nɳv9k׮Uv!$4͊hb#@YE`oywqRtjb>Z_d@@###())qTeeeuEEέ[ rAlL&J7bd ȵ 544XR< o |mO2T*D"M^{' ߯794<<|9"A_\tEVt:!bo~ĉF5[֯_l6klX]]qٲetm۶̛7Ohnn.FT`0PMMMu֙Sp!1dWXa64 ǩ($I)EQ"<sUs5",?̥3})~m6[ycc㙇zhzu.L6Qx>BN5zh^K`6ldf%k5ы̇gd"ngjp xGpMo|SE7;ӹb ޿PT&bđ-7Rsij%\_~9+NFidHE__$Qlk̑ltȹēO>{/FFF EJ"BAYOC\r%7W,^Q;v=rEn[fB)mjXtPѣgh.d2y#r+VCod].h"s*8 9gt:M(mLLA Ҟuegw}.]j!bK]hhdnFEee%\.Wi0|ȑ#gT&H 4Pm,Ru"}z >`l6& r<ykrih4T*EQzSO_pH$֥jJKK}{nX,p^RR:̚5 555XxqI&9r9*5R@jƍsf(TVV׬Y;v,5IwNm;D4ىǏ PHsu#LF\?{$GYtww6{l6!MH "1$܏ 7AA-OYu< jux@]w]wkϟt:z5M3^~{ilSB~|yz^'IQdYFKKgƍݿ£mĖo>2|>ߤ0 pGs9D"lٲj*rHhttZ*J$`F#3pӦM~ҒN-O}V}Kg={FQ0 8N_wwx?jw<u?]N)§+Tg`Pia0 dY]E2mVkL$|>|>UU܌7x[lɓ',XrPx9U˫R|}[z eYȊM  zp8xG"pay4M#k֬'NLaRI4Mu:i, p [رcmۆ?Oغu+^z%<կ~_;wbhhbqJ2B"H+GE`4{キK_Ҧ&(Jq 066m۶CCC )i^0/bvx^qZZZ0o<زe %I״MU( ,_b#}gsӟJDB(FJP(JRlc&Wo<_< xXZb7q-(b||mmm8x<]۷ozddD{`8gIaVd3 U[PvP2:󡡡~RqKP@j5/σ{^r9?Ci(,ɲ,o~niiOUU  `xxؚ^-9Tlq h4Yqzaf](:W'EQ4Qp (fH$N>ӧOcddvDjCe)LfŢ&pq߿ord vR X [n/;vСC8yt:hי.LBz-ãQb1g4-xxyޞͭ9MM7S C&RԆ^4в tZAy0 cg*74M[PQ'믿EQ`S.IR8|ŷn:OKK @"r2FFFp) رcصk8'Obll TRC2q7K,ax,G#G`޽HT8viuٲen,@QDQD>$I`Y_Rb#5P(Ee@,`W86C &EMtQ^h)s麮˲\b&)ŲiN bZi6m ?/_p8zSe9rD"fPUU{q@cc#o|Cr͇8;x<I<200IId(,H(HRT&1v}v $y <_.su=`?뮻˲,~?zВ0uz>/;d_ i5bv-=( Z}F~&$jRfeyZfi*w:8z(袋֙{f:u5|<`۸hxw lNhsl0FGGáig 4 χKZ |l:$=As2;iIW 8r{1D"466ZfXòIR՟0 JeUeε3j.ܳET$K|7o>=Tut:l6k,I,(,, b՝M Åh49rDeYx<0{0af}>'Hjnn.1Gý_C`&>z,p\.[zUU}6ȭغRyw:pֈf2]{`LnqhmmKO s[5u?Ài@.Tjð MӴ\ggg=$^p:d2(J5^DPP qDi5`O?Q466Z,ˑL^(ӟt0k]}H"n<aa9˲M5}G6F'Ni~d;3 8n&ʕ+K>hqǎIzdqT~ak_t.RM˘$I+$擶 ef$ ^j#O4ԪU^zdN+:F$k/,"'Lʆa : `%K\A$ɚ8\.kZ탭jJɜXeY8N{PUղy&,  G>޶meQ s[,NRu,GEQT$IFن4yɜqc4<σ8K_ `S'2e,xT`BB!?)0o<4M#Gld2*,M7pn:!M; 0 ӹdɒЁ#GD(A,Y-'˲ڵk}}}޽{^~u>^*Iڨ믿/^pVZuo+AER)d2y MӒG[[( E<S -޽{s9rZj3SAuf C|9| J[(~_`hhEt"Hf{ҥ7$"H$RZU)!ɀiWkkkǁ@`ҨYMSNeYm8v@-U9 ? ܟԧJꫯ'N,n4˲ٮ.eŊ /{ʕmmmMu a*ԻIa:FP ټ(J ejooN'E}q#Wr:;u)aJr59% Bpׄ'uzz!$'@]-`*`L)roCcXYh%$IE F^ cM011YUUx*g*9YFMY ZhET bJ4Mӂ R$;*(شiz{{'"*|HVYdJ~2 vXi+3"ߧc=h4.82@F>v_N>=*dLϭ]p3 L[F`fYvP0#?U{(A 8f՞5kxnP<<躎D"ae$F N# A4qqJ%c߾} BDԼ=nA Յe˖!`V !qv$#B 8luai8NJ%EQaԢϭ9pf/BC΢ (d{_- $sOGj*H&y] d29hҍ7bŊ9PhnnF\vrCp$AnC$kMIO0Glٲ4M㬳βT亮Gy88 IDATѣ'Q쇬;}GW`2riȲ <E1wս@t6 Ye,\RBz}}}+Vaj X(At{Y={R Y8-<mΦNP(Xjǔ4MTU5dYAɞ1 z$I"^sXg?| 狢0P*D011xȲBbhe$ 3"2PO2x4 @u<ؾ};0:::P.I:t]===͛7|>R3eY(eYOsssppp0 m*FCJ$ebb"OӴ2H: ecliWLnFCl0 |>2 (FFFDT*%=tvv:dYJg$jwL?eybM @0m:s'n Ť~>>>Ç  Ŵ:hn?"$IvN144ݻw8B!tww㢋.š5k`|iQ䳿@vQ"~|Cq%\I`| Ҷ_ (xǸŵaz:. #IEliI JtvvNLHSSDQ)̤!>0I6A2fwUUo?0E˲hkk;#z dVBww7R'ܹ}mQ/@#MxPOOz'e8!0%giMMMqTE.D"qN=XJ%,_ |f3_̀,&x< "Hl6olZx1ÎYٿ[Np:8E @H>yg=@*V>믣X$E˲PVbCӴ4MUU54M3seRx""FGG{n~bK>HU߳ZAi%?#|W0 CͨhLꙤF)`?t:j1`=Bm_Ш|+.Lf2j P( `ll 6l } aX*90p吀CTvUqOt."& Eou]Gkk+~`ǎhiiwމ`0AWںu@~T y& _BhժU< l/lIu]FI0dfPec1::8Ω:Kr,X){qᰵoJ>'ObttoCW\A4M=; 7I H~f2rD8GeYdY$IOJ!ꪞɮ?O82 )`ؾ};N>m=4M[5z2[= $IeQD" #h$Q,#i2 f(iE<8|at\X,T*#Ggy睇}cY"m¤KVI`@DnE4<FAp0>52_Ч l@\b  T. ~eYI011aM[o. ˗/GCChW6ZDj$ +`Շ b:3${ i`駟֭[gp4m3<=yaTN7лqO~C|>DIl/ ʤg:nwyGTRMϼ\u)@4mtt4ޠiC ̟?MMMqLl ж~rIͽV?9~Ǟ={pQd2?L&Sa\~圢(S"'@0Slt:馦&^>Jӈbf4 (s0/3\rWE$I 7={fd΍(,IRyppPD"Z"0<*e#I 2DFw3^/ AXAXȲL&A.0v؁UVkʕ+-ȾGn7hfeLT% މ \7?5M)`:Q^Ge MTse5e<ǹt]c2.T$:z= 0d|g.C,ӧcŊЇ>%KuREj^j-Rì.3cP0 qkӟ]q5`4ubbB~/EYqN%|+===,~S䀛 ЩVqDjEܕ^FBKk*piH4Q -KzCcȵp'd215RU\#NΝ;qqt:mGh %H$j1(2k|Sr2˲V,V_,˧DQm@ EQŋ=###ɓ';`ttԞ늢Ȳ,ˑH\.l6Bf rJ5͝dY6@(J|N'K4i5ibbe]|#蘴7H`6 ^γ3IDk\ts_Baj'~%5:لJ(*@$n݊cǎYYj8=22rP5\C]}>Rw^ʗ qŋ9"d:It]/s"?-"{Q:tbtEQʥRIEQVU՘a h{'UTO "гG@6-gYeYrn0 ].P(Űo>\y啸 &xEQhʹO?,\.19C9ǤLF_$WjzvpFiK5AL&<>O Qh1{? `ժUXhZ[[UU|-gcv\魷Ÿgϱb ~ժUp8njj͛DZ,sq\aAmajbQr\.IǵCa׮]l$L PEK$rPHbFGGqW`V71t"g}˅R4kCop5>,@=1 ]Z޺ogկsNR,2>XFE(Ԡ'bXEQ)4簒0RA2A @SSzzz,ۍyYck4.-JEL&0 v-ZnT:'rlb1m׮]OOXD"88 4M˲F$ @ww76m"m8|0 Z&ygdd$c &aCGFFʺ bO$Tcc#dג%K/^joouuu~?]Q P|7{HerleX,*h80073۷og~md ru|>M9a<֮]kt3D@J; pZ? 2-կ~{7{[oݻwPFN `!LeJ}[. 2˲r\.aœr,bq)S,\I $jP(]===Accc̀O~G6߯ G}TJR֚@L'1o:^W׿qÆ n~DšDW/_]'%q3+KM^ *bU.`0"D?::>|{ rJX4>6IŇ޽Hb:#p}u]ַD"5$IHRӧ IQ˧O.>O;V\tPU;wؘ<|bG6Um~+A?aǬ͛k׮m]|yG{{{O#ndvB NrT ڸƍooǷlْ~]&\NEQmll8srX~ ukgZc 4o P0j&`RIG|s{u7=Cmo=Lc5$Tښ(j2,PUt\ i8Ajy\.K\F;!@8aJcc#͛P(p8lk5J+La~9,>M/3eK, NvJL;Ujl祪@@[Ղ'1bQe9 ǹ(dYF<G*0^/݋_~4 ߏIt©SF-3({i rZX,d2a U}w3BU)\.#H8qd0 Z[[io}DBzMwH#NٳUYU bUdTĵϳ~k׶uY :::!ݮ7JM2Nz/b&n~|ޞ Զm2==>>.؞@@UU-C/f2E]f,kU~6Y)ϊ4z6@=ܚg" `ԩuJXT$Q_/ ng %RO2`V0fbJRT*iN'>4(ʡ:E@Ozt'V^~^D Gd$tZ#ڵKy饗TͩF^6 y(6oym] TjJ𯶾}ÍmĴ:SRrXIi@@dx6j^a9I08Įwnݵc}F$xA*s kx|p7,F-#N8'O"y,_`0m6ig?YOSSTx<~z߾}*JJuG>J⿐4y^n]e]v֚5kh^ImEW$|jzp\hiiqpoooE]ꩧbO?; B##Lh~ߓh4jT(š5kmaSiyUIQk3f8:%Zl@'Оx͛-]S [/^|g?_xᅬʣ2Nx, tf2#`>$I$Ij4VyF̂hY)e)eQ*\.gf)y'7 P1hݻw۶m^Hكx 3:ͯ/ 1W\}|2R8Xk5o}$'Z6@ S\1Luިu(-ynp84;E =բ F2=;(jJ### 82ca}/rgAyk1fZ8pVXK/W.w}#B{nݺIvDnݺMUb^QדI… ]W\qEW-\R>^Cf v{z>L!8B!yӂ 4ϟ?k>s5@.5MC7hbhoo~v #s/L[s],T2OS@o{,E3wݫ~iwٿۿu-\هzn.e{6kSBUUd2'INo3 c{2]d XBY*Ul𖟎=)?a^Y~?x9,dYuH23fؕf6'u?MQ d2L70d\v98e"(mQL^z]? `C̖X Կ뿶q\./Q bbb'Oq|3Ԥ׿/>Opr|*i'{w ("Ptܤ-[W_~y8wAJ%LLLL@dPV֞Z@_$dFq BA9j:N~.ȲXA&6 IDATNbz. H$}@ z gTB}5~V|ZtV^y|Mv꫅}q囃 qp \rgy~\4Q }VQΈlt 13fn~7=ܳlӦM577B5 dL uZ=ըZ:0 '?800ַuX,0fyu]/ B 9UUթi( cȡoEC/˒$I޽{AD,M|rQW]uUwy… Ê?ֵE###8z(Q*yflڴ mmC^x=ܓ[}dXI;vΝ;1V ci6n~HIe /Bkl/>)Tgek]3@$Bhoo ^lٲe?_}0*#J%%Hy:[̗xbcN$'qWML0 Cc VUսiӦ!x}d2of9*)wUUL&g2ipP &>t*br9-f[ `er+kY途(8uP(p`Æ hoo˲uxO~8iڒo+V8@e-[}R*22 [@ }6n8o>w @D`r 8\7I;%ɌkM̬(Rr^P<ǵ?O@ PRTtz H$0::@ AL}MLdYM7S<+β Tw:@Ge pyךe7~*7b1a4 vѢE}SOqq{=t D|;f?w 5(#c}gŋ{{2˱,`0IL&-C"B:>huJ(p8,>0 T*ӰatrG.{衇կ>;66rKLcf?y;F\岞Ngs/-&&-s饗.hp:tMQD"ˮWu]֭CCCuE1^|OIRot|>mvʕ+qcxwg3HN8ΛFx9gTUdL0쫹}-Bw2&if** ~E"p"@SS%fzp8^x^__߲xڵ+[oA1KMF PNbŃL2E3f/m} IO4vZM7ݴvK}>0 ~5dЮ^&& umt$•݈i85ur7?j^vFV]g/nذaCϪUᰗeٺqi$ AlܸK.E d#裏}ߝJuֹlRxgW^yE1} ʨ0z9|l+.]t NB|>\.r9g'aF,Fz\6˟-d߃3EBhlle[[[kwy؉'Z1EK.q:|>X,׋@ ߏ\.G@&9Ⱦ6?w*˟I7 wU={е`puXu֎;wꫛ(D,re8?׷?x׮]1S#`AhL$Q1<`.^,J$ >O|}}}}}Eyx^l6keĤd{0OFQ)YEQJ7RMkc }ݎlV6*UD0PM(*]{g]x---ag+: &&&0<<1ȲV?3zzzt0 O.?#~{ P􌍍1sOrZ?b~)i韄[ornNsa LN75޺XK~{v`:^$---TSSӂ7C7o8qƳkCu\l6E,(~?X%&M-$29<5؍f{0y_רK.]illKr;s9wppԡC>s#U ӷ(]x1Ex>Ot/[l z^(uX:*;_C%MZ A0LRO_~P(K԰{oٲ忏?^2(*AT ̉p]G-X*Gaҥ76Zw644p1r8~8FFF "n7/^/K.qSk4vQ뮻RT0_q9%?eYu_z5.˛q|x|-^7W2B58e(bxx---8:쳻]w]ԩSͨ1}\.냃Y "NF ӧO˶̽` LF)S7o]r kllt;N5п$FQ abbB. @mmmXf 6l;)L&;{aP,2L`9j-|s/oNޛ4LJuR)d2k } @eF?+ :u*x ?%SE5448—]vY{wwwKCCCK8mI??q#x<<\hjj\.,q"$T*Y&eYY[so:,@?ww,v w}TnnEyI߄B!EsYy 7(H$26111wt!ŢZ^NL4MSihhp.[̷h"y[ZZڂ`0 mWk$0 c` fV9?*jc!qfYheKNtnybi޾;G}tK<lSSd~˲#pS,UUeeYf9%zԄ@ A mn><< 'OTvܩlݺ߯* PЍt힧<# .֬Ys H$bv( DP,0 Af!,ۮq ּBeL( ̴N'TUÇtR|>_nhIϪp>KEC5D$ fٝQ7 ?r9 0]VL^o"[XKx G?Qtݺurihkkw.JN77WfJ1 \pa… ;u]_.J%qbb"3h4F|>_(J$IFTE14M3H8vݔNz{zz ,ps BM^)\.֮&'t7a0(BXF:Ɏd%4MC$k~=ϖ@o.V8MZTJ(L677."E~<6ӳꦛnJ=ؘ_ @Ei7EQE4p8h8q4 iNUUUUMtRd:uJct;сJK߄Yg`4;p@8(l&(b"RJuO2 gu,X0ũ^r9 ҅Iy(φ W_{03r*nj3 glʰQ@%qBE5imٲt: @+IDQDP0d/uZC8zp8&oȲKivEQ`\.v$+P#Q9פd 80i@]Wv}Qna1d% d2 H]p8L<&[ZZ<:@ Ԅ1 NSK.p7f~o*3Z ai:јEK9ȡҾxz?ݻw;wޭHqٲe]$y6Z@E$ CB!455l^xaդMv#!)IXevy{^|Łݻw7Ws]ܼy8Y|>o}JҤ*SC3uF=VpYKXlYLVRɋ4*u0*b~_> Ðb"b8LiZAX2 vf2ieid2 " CV^v`aϞ= MÑHdWUDR:>.R9" Ð$ |,ZYkP@\|>O0>djmg&Cb*JWoFFG*Y+MB1>>bAr3s;{,:˶lll12QB1T%䏐R$Tb*1T B`,0>%-KcW{}}O3;+ CS$I4MS PA4R|>T*sW_0fT9qmB@N׊_aP0??D"h4ٵkM~% ~D0haarK X,ЮBN6=yzWV/(2+ u%`D.V\e=.T*e IJךZ=Y-jT*mB)DP[J-N؜VUeY6 DL?"JR[خ1D$i ^3gjJb8kX#L{kݺuH&FKK4M͛I9L&oT*n9M~W2+Sk)s/ZVve?8Ow`Ll6ZVjUYEEQ񠬟W^G>^~e8q("LMwK?*l~/ 155(*_WUe||G\?8(&R(@QTh|VUJ>~(Z=2t/lbUUK/8E%24j!zܸIJkJ h)cયCO -hZ:3T5MPEahr8w\,\.V!W_O?7M;dM0 Ҝ^ @@H 2 =M6d$ŰT*RT~GEɸ- s\ =y mIUPpњ46궬giiI=w\nxxxPEd2<6o%Dnq+i[72NI[.&FN7b޳V*=l]l(f˲ju뭷#3::Zv 𲾶(8umF[?xod>Tڪy3W%L|/n ]D@XJ'TU՚ͦl6%5<TeT*,//ظq#xBuppm8g^4M/(-hgDdKu@NNW4: Xq|r99r@Y[ejfc nحn֯AI0ufZz~ffN]?bm@u=zGpIQBpa#L%w];w6lюZAJ[lAPɼK V: e5EQ$+hf_D~dP4j*k]ˮY0@ ZF uK Ps*e^ $I}c Ȳ 2?<#L^\I#F(ei</^L Ka 388ݻwchh.\,٬NQSB߭rDo+Ћy6/i.^w8a^5ioA Ȟ8e/d## _}V2=uڄL}B$?\쟠(JWak~Ѳ07lE"ӸƬd\^(ms=}قCe:*W_KLl4 H"E& @K,J :FU040qUf$J cc?Zx@ 8ij:e,,,8x ֯_v],h4j֊! ׭GXDX˲W=(t19|nx\'J wml,+YQG.xVP8+ +aNsHRekv֠d-pj7˵Vo„N?,fff̱9ajz}!2h3H$QO4E^8apB!޽ oǙ3gZ( jEyv{f??~ Cc=z2+WUU7EQ.M b|:Zce6 IDAT  YˊdY|}yy9d'O]|76Ja= =3(*(V\.W= yyhfdYF&ixq# }&L @uN$ ^)\P}~~²``EJD: R:@n,eqõ}tDjiSKRU(+JxgϞ޽{sNȲ =ؙ=:t|;qįx][GY޻wo# nP]V&˥(iVՄjZ+l6?~vҥZ @+(kn[B^iQP `ttdhF(2{Vk@uy/8ѭ VPi[rϧ:M2kD000Ӗu)z.K~go[)_N~~B af׋e?j445'zNњggh[na.NLA޼y3hf5MK>}b`q+7{@i* 7nܸ}߾};7o\|yT*=kc'Na@UU۹7\.eY#hh(iӦ ۷o߾wozӛny[:2>>WU!W #I"JRUUk4(RUFj\W\m .lOrN@ߦhPE^}Ռ{`jjJy[h68qQ[ŋ/U'{5ZPUOuɮ5vl=RY簉QjWUy166aNrn j H |-zbvvcbJ6=␁%LG"6l4MI ]ZZ$<OlppE||2 4QcǎH<l6|-wq]vjZzqq{Yڮm~~b j1ZiP!vDoy|%8cp`hhho;zMwy˒$jb̢`jP$05 QueYEQ$I똛$I7MH$I9|)2kt]rJY9cX8 хBǎCXΜ9t@ew(n¿ -!QF(*,2.cxRА dP"6|~B&/23??8}4"$IOJu 51?u֡X,^W4qjKRB"DR|&G202&q`` BM@Ee[GGGB!e@5J-x<4+eٜQæ<ɰIJЊh~|>sPc6lڿmDQ ̘15bL  na(1Eu$I~^NE1U@u5MY8gl6h4tN^-\4S}]4MS[`%^u:њ׾&si4qSZwUUJon7cwLf=?0#~˗r lҿ$@hMt |$n:W(BT>jBEQ0<x}.bzz$c#220%xI,˦+1,t:Zax<t: Yq|ř3g@J%oђuw}wu֙s$eqT0///hdh)%k0Q.Gy" `0޼y={Rebt M7S. 6>h`۶m4q;s ;UUM*'%IkS'?j(v#ٸ;c˞={dYU5MTXUn (2qnM(Fl6Q.L& c& Hkl6!IST+K<88rz,,,|6Ћǃ~|k+y [66!8˲,ni!O$qA4 of\Nnz7m/x<qB!ht: ALo|xl0󋋋.-r(G?޼y{ttt, ]MI,,⪰}DZaYA4(nY6DёHdhw[NYVM ّ#GT#8p( 㩧B.k{zxuiwܱ{ÍϗE@V&@eME񰺮V AF͆@+F@aOJL*N|>[ѣGY( ^yʦ-د9Щ7QƜKeh\EiLznqq@:FV(k<1MBVaIM+{Q1_FnYEa``P ÇQ. $p\M1pSSSH&æaq޺wޝ_xbYu8 19gyF.͙Ç/;jSÂِmԩtC_DR$ sv(*o߾;S8;;[4Vvk@ (y^uHM{hkkߤdA 񏇷lE6ᬐGEQP*PT~zv3~A'mw8χ|>eyT*(p8d2i7o޷n:ɓ'/GL5eѣ j\yӧG{hdpprfvK4u,--! LRp8/}7hթouϣlBmڴ)o> ٳ5h6&Kb ={l4mҥKsƆDPy_rERU(%-MӦ:XZuʥqɵo1]:H$8NӴtYZM Aziՠk5 ky[&h4IKB8UN x\bXk>h7 ҍrJ^ `׍ vA q e5i4( CCCf}]m\z=07a``f$ 0<<'~F. :w6G0Dx֭!i33\E#E>G\$ɓNOOiֹ)8ٷoUTpi<*!CCCh6ugΜ9g\?I84@~ad*.kSӵp=׏(jix<,r7nJ&ꫯ$IDT0zYahk"% ףJvfQ.~ IEڈ t]4MA`=>]=88@56G4F$m\.re͍r-nfSi8@4J٬9!144z BH֫J.?cw0*%.IP.( \\/~&ђ̵O~2Y,..٫qP(@6>>^={)Ah\xUUEQ~hbMD)ͩCEj5D"b1ѩ)vvv6U.mqY5EQ@ iWCsZkK@Eeyd2Ӊh^m%aFV{i|s "GQdYd2 SHW E|h05Ip?ӋZ!;eS,% ƈqHd֢GGGM&qkM?7 XGFF *2 J\8c!N#s$]xW(J]-6/:N{+NNvuPD%3i ]2LfeYؘkh6@fw0?`ttǡl"ɠZdd'R)<`ŋV.k+PA;>H"02Ma8H(( $psbŋh؈wx{ӦMl6A Vb.Hicjj Qn{tΝ .fl7A6^,r $^o(a(PT|tllt|\V Fg$ipͲ,E<~(Z>bP QבNۦ;  |r$Ekb-׭ J;J%  n9kF4MAxwSŐ̇7 b,F# ( prF!q4JbJЊEQ099Y| _@:(IR}ffrf`s$Ԕ{``l4mξ9oc.Ν]+S6<󘟟&k3(4˙@,ػwWr\t,kE@'9˲ăǵ,zRJߏAJ%x//J` z^: v8x^5 A\.u,,,`qq\R f- h :X4 `_׭{Q?jrݫ nD%JwtͦxXILI|>T*!ᶍl$,˶ k¯ I022EQdLi&&&pI| _@PԔIJ$OOO?=333es#CO~򓉻ۗH$L#qH9bR rLϜ9sCkw ?Ft]+"~S(044aj{m?-Uՠӵ_z<֚\.S~0=JFI#tZ*2<=}ٶ~ @$bxx8u7 nѐѨt)b ۦ Vӹg\^(T<(jٳu:tB(cgdfcBPE\pf&iR4gnW./:  -ISlͦr(eDVZڛ5;MZ7}5Ȱ#HeYj5R) Y!" &(Lڿhǎ;vhWu4S6߿~D4L֚&rN^}(L>h(Z>/i`ßɟ8cL\g(9RɁծ,:Mz0H)x0X>/0H{xx8yܹlV5dٸ]մM6LkefLPLدP(d^wzgϞܜ dYVM6a_\n:tXy):88ooccc( h6u xq3") \שJ!sKY&kezG|9(r IfffF[FO8جZՔH$q a:׺iLb۱c|F@ܶ"2:99Kd2<:~a zߕJ%:ud1`IU'r!ڹyشS~w *JNLqmd).\uk[ ȚMQ(^,1== ۍA3 #lD, cJ4\.x `xxx^X,"N_Q3/~ |_FV]w݅7BE4MdOә\.w zJb&nav?æ[rHY A yneMٙ IDAT|>ofwD@ųrh6\h WJumo{kƍlw#Т(ʕ+D"îoWRemu]$IxY[~-ؓ^ HӘD"T'|(@RгO8@oI`Ckf?˲D"m=KKK&rκV*~(bӁp;5JGQ>F?vr]nvhA#N5AV $)h4Ȳ[Qs(X\\K/wݘ08r&(nhhT]SUZ*վшgY. @H ժGl Pqv#Jn:S%̀V84˲ v5vEr$Ӿ^r! aii =.LLLD܇?aYu- b>on^X,"!@5j~?,N$XŇ>!s=333$I} ?K(1@]F?;P`&lpQ/2HLqtMuf5]Q(,z<AR)<رc;~#]\\lDQ(48*fj){,"`nnx###H&g_ r 3 z\.Y⋸g"4dܚ v E6AG@(&h4 V$,!_W7f|=6o Ap9d2?aСCU',De oxCyB!,..BUUSdxe 84yh ;;D6 TUb1&WPMH8z(0ww~s,f%LSXD,ݜO{ǃ^z X wuw>/F`W7rhVh6fYj5ݎ~].~[|^;n#dcF~w˲vkݡ;Tbpyجµm@Z6ͦ |<EQL\.cyyϟ8Nu]fђdhѷQics{{w\d" ?<*7ԔY׮jO?]yZi)t51W8[ߟzFX\\4ÚVb3Trlo65ϝ :kE;h$j60dkIGm1H {g~i7fggd8VQ\qn矔* >{p8ww0zNy[o>)XXkqx=5 Z t 4 E)FLl [~Tߛ%˲NQ7/ie<`;Z^S)EQ|>_|R0\.db.\O>۷㮻–-[099 BykunS\HPR .]s={{?͛75={V|+,HǙ055?޽{yG4%=m,Gz3lGL{^o3B@zmז(n$0Y;i+J( yٳgO_r`$L&#(V(& <ת~=^/fff055q۷o$ w*2=8X^J*!21a_Ǐ7m0Fsپ;akJa@ŕJv9y'0RwYp-EhIغgT*k yXFfЫ*4_ʔݶmFGGi&pd2io4M,`Yl u|\x'N,:pw oxv܉p88X*g}//zJ52Kh@%8K߻\.}{{7b\bq-uCiI ˲0#cZާ4 s>(G>GZ0Ԇ /r^Uai4jP'."8[Q[FHRxWpjmܸ܅ 4A*wN:R)iƍnr kwbV"|2r:y>]Ӵt]{eVCoT @ù/qo @sh2.RŊ(B0L# bbbsssHӦmX4<7;w֭[MPa8s3kG%AiWu;-Pԧv<w8˗);evj-d&"iEi؂M24a:g\h5C%,@\& cccWfgghg6GGG9Il6M{C M1EQ8u1>>>|}/\P0d6u@UU_|Q?S?~%-Ibnn\GbtCv+5}_J+3ݡ$kvӍwetb說b^*^z93FF$֦$g2,--ub1ڵ dU-پ>;;+?·mܹsM=wm2~g֭8l6N dq$`r2ue3P e8 EY*nh5K%~nrz&&&")< VV+<+D"_g`=e;6,Kq,9nbKX F ØֵhɌarٔJH$<67 H_9FEdll=;;[Amŋm+ˆzn@c,9vN Poٲ%633BKB7Z+]/2E$Ifz+(D"f&Qe ^h>:}ڿk%r(!!SCue=Zん#2JMӴJ"U*(aB!* hb,q%I2G,t]J/..zyɓj.m^&u^~Gw>C#rall Jl'=$:of0" = 3u=(!맬˲4jIVSV `esEZ#Y(LQCFH?H'G<TUEPg0 H 6b{1q߾}7ȹvw]MT*EX gΜ+Er <(CX:I;5Z(8oA q늢 ϓةixa|*eulWxϚ엌cP(D]Zb~?L/H ƉFE^Dey,{d2Ia˵&jQ/%s79Y+pP՛&''9UUA4j_&β,J4Mq uՆF U˅p8t:mivcGE8n!^QDR1'tJiJ+G}al6@}9HX)+WF`ΌQp)838#S=ՌldP9jD7#|; CX¾\ja'ڽn7hFREQd2.JY#2K˚(:1jXE43 z(Jя~K._2t:w 0i~Zi|>Fԭzeza׻juKEm0V6nWMhhtC85#׍̪b-w|0 ݻw|>oafXO9fcA5>WVӽ^/h4ωN_ XsPw3ɓ'}K_Z8{b3 idn5 4 Pۂ?尹FF/TN( p{GoM4z Zsqfcu,˶,C d"V]@@'&@lſ{ǦM>#\t//˅{NARF*MډnUKf$6NiLMMۗؽ{HdnH̠Iw4q{z|qɔ%mNZhhF(2eY65N8ytɠS|>)sǎl,͎l#6 TU S[3/~ ZFφմحZ ,CUՐE! }4 z]#2؝!ҀL&x( B&Sܹsfoqʕ+nK:0>}]z]wݔ/٨j׽ JGy}{M6ݳo߾;v,;v'Μ9S~WZMVUCȊΒ0l۶799F>xPבJ@ χ@ AP*Lv+v=H$^L&D"\.#G JVE, Vm[n]'wƵ @Guff`~T,S ;NS#Z;NM@ )q7*h44ǃp8b뉨<MӐAXD"o}[8z(*,jav:u`P Bܡq]Yٳ__|ONNx<͛u~V(R)Ns ~:wܹrVS@&WkjrKظqc8F@, xɦFM?˙6ѣf( zo7Y+|5eY$ p]בNƷcǎazzl)-,,\y`8ND.3'2^ς2ie~EQr5Q/JE#5>,"?bZ $!Lĉ_R)4l6j s>.KUN yߏ8S"Z3 <䓵˿??2;&&&dhD"ڵ >Zl6[n6RTi4j*uQEQUUYu jb x<X,z^Ǔz^Ȧ/ҹ"M+o]^[,h5|hL<77n۶ OnXZ;JKuXis%cfY4`cIH$b}kتuL&s!ߋG@p Z)lNhfl2)o(߳}. ZdL&(%W:n?U0u=K4yaN2jjɣF@L' `[Vizz޿o߾݉D̮zPUMa)|OI(ߑ!zB[7fN2}֬E?c% f7_v#B4,--A$$ \rO>$\bJޯjf7 3;wAZVݞAʒh-:U(4 GZ36vv\gn")wX^/r 9AFg5__Pl4_mh 9f~A'puzI%ˢ7`رc}co{b{ܳgnV|>LMM+Yl)bt*dYF4ne&cYP~%Nuue4kj^+@@xEdh4ipsε54NO{6éĄkttL Z,\DgZ? 4M \u˪(exOI?MV_b>eUE,&I\.HT*A I&''_? AR!O3̒C֯9dZjZA'{;gvC2b>`o<o&W*={6Сnvl߾y@ܜEQ4pZ5P XDx_=e6+h4PVQ tfⵠWI&( By/Ksqp8 AY l5TJ*y3 x<}Ȏ5xBd c[.A$(jhh:~P('@0;;{@VG; e?TP\Nen`s-cro^ˠ9w?jʼ,3ZC$;vI$122h4r-Vƃ x$IdY) NOO3$o?881lڴ zgn"Uck`8^\.$7N#S{; 188AP*0;;Wuq|'O~qt:~'C{w"Ȫ%S"GH^+ɧfQ`H$(u"{@s(lҩ˥8qP*PۋE|("*Ffvv'J!l ?w xgZiz<3jq"@pBىyYp8WŵjB|>uaxxX/l3.QUUu%1 c_(xXMY[ 9\N\H^/*fggQT( 6oތ}CR5jژW} rT-DgpEUպ+u$S,EQT3w~ϝ acZ̋52~~B/2em|5 R"j8Vd%rvaa+JN/sUoX*(d4 +`&~ƺ391DT*dY#Hr+ h4t{T^|b*Z]o,\D}9cPto4k{"JX,;tw= ~:PZ k҅"r\HCQ,.s sh)$%SzENƒ7FvzJ cɞlFy_p ߵSlvV *(~"r1)` ú 5Nj0jYVdr'&12JJFGG%n5!Xp\|A #2-HR[tw@s &_H*?k,3L`pp544L&Ry9;X j5ehT VF@A)Jz%o]r<ƶkI<q0m8ק|XLfjH<__pq$ ȲLtm~~d2y4 NDo5Hd UاX/M"_9-pZ$IR2LFQdYf(B?Bxo¿}%Rߏ@ rYJ%a<8}4B.Yd2ϖZ 5E;vA}p}-^7"t( -ZV7}^e XY9p9]0Fj&kZ%nFr^iF0[h#A׾5?~zwKVk?a#ɾڵD_zw SN:>sP0t:j@eY\.czz|\\[nm F]9d|$0xGX>t9|[?π ktT*Fu@3u``@?P$acWY=N ? T*0LT*Ma8c 9t-I3Sdƅѽ`ZoGGG![*V.muxx?N(dYFTB\GZ]%=oC@eQ(033G^===_sR 6&waf _BtttTFzZv^78 z*z7 ytKQ#"˲, i\ (Fh4L&uRՈjoaveY,//L$2r7MR)U¨T*SSSOZdPe@TP| `Vŀƹ~c*hNVՒd2D<S.133Rl6r|شiSXWAFFQױXK\DX bii drAEa|K/H$K&**\tƠY;v333-R_N_TbJ3 Z^bժm+Z 2Ǽ d$IR,*fnn5j4X\\9 cȿ199vs99"|򙤠-ZfNvd0 94-@ YT*@ fYk4\.ӧO;]wݵ2SdžDZWJXkA`1E$aff\N_=zF|O?4H+JNVUU[X[o~aۍLLLN=T h"LP(譎,*z}ye ],DjBj5it4E{j 088Ȍ!˲>tBdY$I:u :͛Qt_?;77}kGadTPaR 0;U\tV hW狕Jyޭ*2尰G(onyQwF"]$@F0 '}X >_K/-j?U7mg> IRJ^s u݀L64gfft`˥Ri$V DBrY Fy~'<H$P(L&h: y("H u|hhl7pqlذ~XѣGRUZh4z jdv@XZ@ I,--!d(|P(>33*l4fffZZޟ. B+<$r.^\.W!O͝=uJ~i?( xߍP(SNX,"W>|aaa9ShnnR *(ނp悰n\;'9ȿ-5{oAPrBTFѰҠ9,//#Lⷿ-vލHD–eYḠaur9d2}-9bXFqjNsi4`6m©SV+vSffff_~h[8{??l޺u;Ce,..%8݊2lKq}ҝ\TZOJEs~kx)_wy'^/~#!NL lm88 uMTP-`H\vpd0 )c;8S#)LYiL&99rsN3 `0߯&tr^c@ؼR6đ7xP(eY=d2b" 088z?0^/oHN\9}̡CX@K_رC 8w.Nw{zzV<>33id2rsϩǘعs_c'nH,0* Ν;L&fFS$yf)FϟGZŇ?ap կ077-8p`^?`R#E,RD*(ކ0U;YV;v.2FUi'M0rUUJR (adYF6EXD28*q1<<\.T*E}={88TUER$IX^^F nf3zu{[n®Eo(J[B,bݺur򗿌_cccضm~^Zꫯ.>|03dt2gWn0$PUrA}n.T>L&x~"mhh)'Ѭ\NsX `-.g2(`0y^ 1]x饗w\s FGGlRvxd{0 ˲ZBAУ79bon#oXx<׋bϞ=Vx;ށ 6k BW^I;vY wzΝ;c Ӑ$I߷es媋 3#.:jn7 ;d2,j6Q|v7l b/.p"^^}U,,,UUl\eYٺur Ll{H$ɓ'{n'ewRg*?oa 7S/CBsQʾz4s0rAUrRCWErd2e+شi6n܈l6\.O#08veDЋ,$I Fb5/*A$ٳgg_;wRTUv!lڴI ,bvv7|NP ^Ԅ3!qBu 'HTۥ,ŀ(xCY&grrY[9 p-^\(J6-Ū}>eY&B`ffG p-n(ѧ{chۭ5%0}o!{uƉD>Ǐ~w]p8s Ţ|3I;Иu>ϿEdoрn!+ R˲̙/.."#n%I:V(*UD3㘝;wzHGƥLy}}}z&RWK/abbtZ%3̂I8p èwz^<.^͛7c5W/hr:@5ipLA V@oV/<8%$F4-EI dR\(^F(P(`~~'N@"u];v`֭X~=*Ţ[5ZX0f.3ÈF(8uy>d2?w۝=g"׈PoVUTL&Nq" (w3_WJh –l[YzAS@BZ5KX9$gmЉn@yi4ioLhR `0une9lo~DQ⪫¦M~zb10 ";,tl5`d IDAT6J'Nx-{W^y%>|ыzܹ;+q$2sr"ya,//#͂aDQ<8uRt d t<箹O<G&YFe!"t{qq$SSS8pfff0 Jr\uF+[odnn7tFFFp<~0/u;MZkKĥPm@ ~W w}jwYf,8T*w\EQ7'WqE/~1{fP ~+_j# kS:Y #)"kcm]1=fgUf М$(X.rX2 øn:_׹zVU " TP(>`˖-b-Q$IV‚rĉ{ho]ЎEY?8c> }mÆ !Hra||\'0ǣGղ,u V#P+1@~0(dYܜ=ܹsO~iFTYJ_c<{n;o?Hz"p!{#~?XŃ>qr^xj2TМ{q9ߪ pZy?CuZV*h@k[ +6/ oLC{U Hu$iO)m* C|^@몶L7_8%ќV7&+R*6lw}ۯkCOEBe& hZO)tj,"`ddPz/^ԇ-|>|[‘#G= j.4;;hH6O a``\O@ hN四CZE^0Þ={o>}m6ZZ$ . uW^ywɓ'4+ ؒ\r6MoS dg/&1`,D!`'.B拖Bp IhOgѬ0u mŀ0`V>m8V-^az>]u7nD"=nFHR( "tȜ-rkYG BFGG!"ժ7׊G/k-:J~$󡷷?0y}S6%T* >{9U܂Iϲ0 w } khtxG\?TX:FtJ }_!yQK[t1v7]14 hAоj7F$z+ٶ~k~{]Y܂ 0}}}H&DQ9Vba}|>dY> Pk%C6;|sUڱ;?H<g"Μ9rn ~BLfźfIpa7 rY_U* ǎ{6^>Gf@>OOYCk[S_L$FJTPPPn7Sլnq.:Mj% Ā97?k!6hh,7r}͇o\̻nUW]ݺukrP(#qCzI?Jabb'|H;Y9L-orA썫EQ"GQ<EQPTt:B À!~"tyW^,9<7~===pn,k,B 47e2y],׏eY$ T*|ѣGqbӦMX\\$IRt')[}oUlNtq*߮ϒה?M@ƁUP7t5=nU,2EM N0B NBm޼ٽk׮[o5y@ t|RҒn{^x<d2?~j[NXܝ-Ɯ>icdYV/|p\DQFjKKKX^^FRωۍQLLL??pYlذsHR^xPX\ }?O֭C:nymkhNQn "cii JA\G}C4ŧ>) W^! /0h4^6Im{T(k eUVj>m[`uݻ]{qD"}@ xxY˄B!-"&''ëI; [q\~#@r^{HjZZǁ ,~3\.\}C^G.SΞ=yǏj P#T~7?u7ovayyTv188زu$Iz{{rpQ[nBsԥgΜQUEIֿ2FimiO PExLe\NL xG$ѣx+5 P*uj%@,ˢP*كsa˖-رcIqz…>zN)&mӦM!T*ϲ,zzzD,e,ˢ> ~!{>!cjj =fgggy8%4;;.D읢}s-`=4utr"wv·sn7WI ǹyI]d-zYAa}=ɜRROH$'GL'?y8r~̙3w܁w݈FǩSG}M87!o|_}Ձa\.?Vx<[===T*#~׋X,xg,#n@$;wVϝ;W}/bMϡYg;]$DHɐOQ@Aftv{)FtrH瀏aP$d87˲ Ra B"B uV/$IXXX V+b`̯b1b1dYf? # ~k_+ vV06mAE x===£>gy //qw"aTU:u SO=/~Q^\\ќneN{vYZ)xsBs 0;L|\Z<9L(fẃB>4g5A0 <|>sM<>>O'`0>lٲ;wԷ)\.l6|>o `GVRG EQ=qQ<8~88m݆}+UT'|77/N_kG7oK_+ R?z(-d0L y<կ~Y\wu?;w";ҁ {-:uJќhQXito׎WtK7WL u{"B[ò,xGq晋H*cccXn6n܈H$^B!o 2j{c'5d~A2D22Ο?ӧOٳ8^{-bƍ"+q̙oWJqy`,L=3|mbp#188?jG3338<>^z Pz׻p-`ttEȲIiGyO˒$hl~ vv$oFۮvJ еTPP='i+!:pq  V-<'aAEQ=8(HYCfAOcccz BA^/@~^VCZg,//cyyz(b``smۆM6!UUѣG{-}{߫---U\@s6h}s_~7Ce8qbqsAJoo/ޥp)?=&''!.޽W]u =P{^ܹs*h.y ͉QjE}jk쮊(Ӌ0śŴEߎ,CZqN[AKR~J \.<eY<ƢF6̋~rx122cpp۶mC8F,k)Z4P((G?5h=r\qWk㎛^aiLMMNej|BA?H<(nvr-P!=qDu߾}{ /98$/*3Ud뷋?J_*((ނnVK`o>|hE,vL{<= vDȞ|-@]Rc@&ɁV'O8q~aRh~۶mv \RP4[3 JJL&B088oG:Ty'j+j5cp%=މl@7y~;7FJ?o= {!Щ>%p*6f1 uY"uyv](A<vBFA`n-]AQh(rYrұc?O'OTLH˖l >]wFEQP.>I1;; .`ffF_#bn&l޼XnnT^WO=C C;9vΧᬽopVٿ>Gc}:  ¡}.=`- ؆f f$Ǣ@vs^x$ }:00x<V'&&'O:tH>vbF"viCo<v;7GNz!~P<3othqD[sBj^4 b)3 |IID5'<xێ;!N177LOO#dzF垞˵Zvd28r䈔d\HJ"f ,5Xܗt Q vQ}G~h4(SP@F\J:AD NA@d1fS ϋ3.6tM[EYFJ7Qk0t޽]2-..byyY%g&$I5TUU岪e~'ufW`}O \7; ϐvk(,#ZmM')ۍ1f, ʹ 54qDnV9jY8FdYށf[ԄBɲFz]ɡЉ;WCp\$?Ю@7bJEZn@Ōj.ZTӨ5fV͕d!)-/||soRZ.)S⧠.@NŁ\@7S)3mHJ+hߒ&9z4 U?)ޓ~e4yE@'_nCv}q ; ^/2% *( strq8tvg$ Mp3c BH==Fx@Vo&*ki߮*'*%~ GP>ØL\ַِcel. /}""emm1n!Lۉvn\Xl`f"CR|X"o/vs.{[_f;]k:&m#$!|EQPV<u((@EVٹt \"N9N?|u߽چT;=fut# _ D:l&#r*_q@?0ZFTPP|> }8$fA˯9Fc~n达γ_!r VIoK 7z@Ţ5DDڍhGNNѺY n#~N'ɭ[c'>7\\$& 6D@h )G҇èSNؑlӉ}TPPНtk'Q~~c_ f':k$;WamwNv#EJ?ś006XڝF _Ko1щYMԏ._' V*+^?e( % *((ݮvzws7Dm-NujhN(tW3 ʟ \=tjAQs7N]N]$M4.)DG)x{8! d &rfVMuTb5@'vq Ө ') C$8JNR1DSԍXiЩn:H4OA,2 9!N޷%n'גnM;;q. pVяNO~ *((~vzNmx}5MVFX\D\J>MSP@A ȲܭDrדKq2~^Qī@-@j㡫y)Cv$j{;;MW8]Pۥ:Ε/)iF5NcĿn\*:vّǃbHɟ V[BwJ}]Nպ<,˂yߧ{\.FW8p/A|t3[ #uy}ar> *(((,2T2&}w;& n ݐ>0 7nZv. +\jqbĝXާ Qzzp-!*\*wSC 2%| *(((zeFPVr>  aח^sV%8z>jaz :QUr)ڂypt.sWюgƎIENDB`python-msgspec-0.19.0/docs/source/_static/pioreactor.png000066400000000000000000000535221473355726200233410ustar00rootroot00000000000000PNG  IHDR4KgAMA a cHRMz&u0`:pQ<leXIfMM*>FiNHHcС pHYs  iTXtXML:com.adobe.xmp 72 72 1 498 1 499 5 @IDATx]Wy?隢)ݖ-rqtLKH!)$|nH#jl `ll㊋\%˲%YH3O?wmq$M9m7}^]ϻwU5̉ g !@&S @@w Cs @q|@bN 8N1w܁@@̩  ;!@9u 8qb> @1@';@̇  @s Ĝ:@pb1 S @@w Cs @q|@bN 8N1w܁@@̩  ;!@9u 8qb> @1@';@̇  @s Ĝ:@pb1 S @@w Cs @q|@bN 8N1w܁@@̩  ;!@9u 8qb> @1@';@̇  @s Ĝ:@pb1 S @@w Cs @q|@bN 8N1w܁@@̩  ;!@9u 8qb> @1@';@̇  @s Ĝ:@pb1 S @@w Cs @q|@bN 8N1w܁@@̩  ;!@9u 8qb> @1@';@̇  @s Ĝ:@pb1 S @@w Cs @q|@bN 8N1w܁@@̩  ;!@9u 8qb> @1@';@̇  @s Ĝ:@pb1 S @@w Cs @q|@bN 8N1w܁@@̩  ;!@9u 8qb> @1@';@̇  @s Ĝ:@pb1 S @@w Cs @q|@bN 8N1w܁@@̩  ;!@9u 8qb> @1@';@̇  @ۏAb~EkP8S:DVSS'2wvw*sԘ@ ˓ |RSKH]ˣZgK9эYP@O Py;kjnIK6tKGԕk03] u?ÌgH^߯mg4W ,<Ȃ-9bLg6!Obا_fE;Bԅ_ۨ7KOc X5u]V]xezzӯLsypqL2/d 5Ԍͨ+@$kkϯ\1$& rƱ62/t+/6]Z"zf ؏?w.\fnaRؼ(qq 惪"`CVvfZA}0Ȃ.hY>z`@AsAdVVFs gi9zv錗5)tJ틣LyX}{@(^s=5MͧeI/N76b_U򤖿Z:xgHn *9#(٦|d>]iڨNmEd>N:g#1}۩ޠFy J.?| KBDZO*Nֶ=hH+^Ryi5"R/6:ϑI l+_Ӯj7^s b\z7 䞹@ƭwوٟN`R >RV#9^׮4E3.'ez]%Z$6Ws&|Z}˫ŏT&aJ[5W1/!d3#6Y&2δl|BZ:|{PY;z>J3UvO6.+ ]⍝jX|qD׷O,g _y[#}f5$3男'AK/O(Vcf,řz'kM4OBgWWL V5ϕb>WrE/3j^j?-@i|ZqUJ!ɃFЩEd&3s%z;^ݣW/)НTMQ| /"ܟ.3BE:7g$̍aM6GW7LTrhYi~YJf巪ó(y9'̧ZVJuyI'`O;IuZaFb^HjO΢y5 +ަ2M9 CtL8NrY]&}3+igǡT_|y^VSC8 0?TwSj0S\ZيNȴ",~YItp̟@Dy#s5+k>ަ -YY3H,4ekQݡe,~Jyx6tXDF۾fEfs;ڽ"T@-x v$_gn/t\NF{5ҧo]N9_X#V/rG˶묔/v~<>y>S/_j׫ԥ&&̏p[׷V?^9qļӼ7ebDp5J٤ljȱZE6çUצt8*?e::?738N{ o͟ioRso|sQwZAx}殕{pz lʙ 2j\f"6[s&cmY5-{.:w`> u2~ (WYo|"/*yҩPOgn6A+Kib^Fd+]<l>5(DLUs}DVW_ۤ~`-69@(צWrϿ9Y׼+|;vvj1gڱxfw :f}S˴l f #r#?3nKؙ 8Dtmb??pz 8l0yͩteZvNs ݹ5Oo\' %9A1+씙mF=8V0BUU>,rumա|q\ Ef1S֘oz,zjs 1'(S #[h\қ?Щ3^[(sּB1/4)anv$ҔU a2@kB nyc )߱V\MiMnfVq@ еVx´x $2~Cz "KYT<2ey9yx]Tf^^y۳/b>{fÈ[ ^ly ̍@6 _ժy;[ gBZ+fP/oҩ1~Yٽ;s>r00V3 gy̋ϜU4B}NՅKRR15R<^"`W׻?ݡ=^ 1/lzde?tO{:aefr0-D :qD;3*>Wt%0ԫ@ج~YzhT6 e߬[>yo.^5p] B -aq*mWpνbovz|<ا4Wyj9U31inJs{ļLE?`܃-cvD_I+԰20&1ڹ4j{^MQYyԾF)kE.oMSͧe'gzJYM 3&Pֻ3 B1/'s70=+gwxڈ&*7@iD`:%;/ 1//RO7#oĜoe]d]CzןwSW2z6I\m hx:E*c k̞@8שg6hJNϞwxp7mh|%sӊ9,CgᬭM&:ҝPGӊdzOd4e~fzX,H_Q38)ΥQ7k೸_'Kwj&@xѹvචV6`yvF}47m >miώ @oRvٶք#>uhyL+hù ZF#! :u Ը"u4leWMuqZuQckBhͥs҄ib2p8M)wgX{wLFlgO%s:/1a}_.UFϾI%TsmtOtCM8n. rO@+EV [goiݵ)܊7C+FɆkXOO=2a6!>VA&dF[~iɉ+&;{GoܡګD:S#̭O8OsyQbʃk cs6q&Qm10Gh7kܷCDSfJ=ܴal ^Zb׮cw?_q3=rqα/?:V~eZWԕhѡüڋϖX {|zo`״k?wГ%"i|av_)䆈19Xcwݥ)qPöl,ZVKqI?uļ>kĤ?Y4i8G":xrbPn|4}[_x>+mYn}?ijvK7=[5N3%yΊg.&="t[7_[9QR;*3JLФl9 ҷO{eɑ@eVT+_~k9;W\oAx8~/MC/C<4m~Bݮ5y v}e8{: Z}jf(9׷|@?~կ2~-;'5k٪ZsoӐѩv?/#{?/9OnNlEkIQ*YݏkeXž$N~#XzXo}2y<+fwtaUJO'N8;SFm4M ߽>S+}p@LjN3*Ŗ?ؒO2;o>RDn%=rgF}ٹuJ%x当[W@ }zB?{ ~c3,:ؓҭ7\cףu"ls&3(F̽IQƆ}_GU+Ax~qKFM?bι4{:G)OUx~]}j:r>tu?>sAbdE:21#^<MRU?2'23%or^EѬnސs05v2kӵJ{<=)|1bb]LIq K!0M`S,fN{.=~ϸ|D:}ITP_W08Twb-|}esRLtԓC'*> ZE f-woV8c;{zeXNO<8=;{PȯugApϮUՈy k?;1kpfp.$Mzr[uGv%էט~s|ƉKs'܄'cȘ] ۚgc:/>$8mwOf5B>}zфO2 ApbJ3Ey_ p#c =ӄ"(s'`7a9xRqrNߧECʰ||n^'4#Potɪ'T1LWMғA17`NLHw\<16٧NU2/\Rz_hfV[ܸ 1wOXYXBļU!Lz<mQXD!F C`lb>\'d|kJ;=`6\Y(bF8pb0 $5q Vlyb2k!قRBvo֎sv\[T;mϓq.$*/G"fA7[ M]cPQ3)Gp^ȪU`'S̜@_\{+ҌϜɯ H;SE_^V6^s='06[ _^P_'S´#ڻ. @1/tl$i(@ypVS %VۖcD{1w݃ivBIc3:ghb~e}ժ,i"eNѴ r%`F;GbfbCs]HL`b<,S78񡬉ΫSldn<[2EWH1/u '3K+h9 OonZ@V3w.^&Ng7\͊JU1OꝝWW%9@MƳ8 Ogd]bS8j KL1/1plX1O&P+:E `ޑ3[l3{hIxD7A`V\b̜62*s  (Kl>zS#l2Y>e"sZًS'>L:͚1ӣى̋SJ*b^J@ؗpG3{d s%}( f1Z i]k( 3+:K_:Uda-fBoFL䔫V 5%)h̦+xz0%s}H mD|ZO P5`",+2vÍR!My(TB[䔍9\'tRf¾#ZTShLQ6d.D.TMK6k>×ҫ5575W}[d7[P]Cu> sFmNs׫;ﶗ\kiGkc(V2 7եSKsrK3௲ jA[@e3óg~7UF zUSpk\CoׂЈ9ce}vm`k kcNQRvM.}/ޮ|jM;TQDMչctdnt5pM1wݯ.i|B6=DJ`:vӓu:l1 | z _fM^5MEj~OG&4UmLsG\iwv] *9fΡHyx~HPv5g4+Ǡey"Kթ{paEFer~5tm/=P‘E+giOց+j3.DRV\ vȚUׇռ VL6 ^=v|p|6IY٧YcuEP_(s~yqFkij妨}PғҢ!u.)TΥ5J)`sM1`Meq5iff̔ 5m#4lF 3_QMA =їӢa-YQyDNl IA1/9w{Ɋ6~jnZ7:G Db~/*jVfж}ővLgW=8&P6 ꍭ *oRԫZnR8M赩>կ(eEs̟@&SƐZ[wMY"xHR2ߛ` ViuNƺ|cΘVDkah&"ףV~fD x Ǽ au,y;̻:UDyE9#fXj~P5iZ?T.yOlo}1M~^H^1ϘG2{R@+v0Y̬ 1ŇTF/oYΌ7K"5ũPv;~yF:"ӛ;AGd;R1wԅ/11 1jɯi}'?bpelb_hud"V!ojoi>zG[~vZZB5T1" ۼ~JV 7HeB [ҚݪW\ ;zE5܍χmr$U"Zn>8׻LK<8@̋wIg|6LeKgTVEMt~]maz5bSр֟Ye;ݒ +Rށ)vsv3rhz23k )}B- V3߸ty.H&ib43 _P%gKPJc#evsfۘQQ\Tgo 8RߋWDu+0޲bϬځouZyjuOJ$ڽ}RϙbļN}kw@{`]=hqͳQ:ۦr-Yڠ>R|69m:SWwTn6$`6uœeΔsaQQvѧR+OyW6js8yo>tƅuZV78RY= ~1/{l_61v7oveEj-W-ˮSb|&SS9bfr篱s̷4 #=kļL{*2z;j6$W͈ adxQ-qLKY17QygA֑ͅ0b[eBҊU :MJ`쬹2u6VJj>eY<Vӻy+2ϙ%GC}f4SԊXN;Qo`|fp3r8i;벷.K.ILO&ڹuJ5 )!7SB䷔iZo V?iq<CY]F|W9;'aMvO1/;ʨ10eZCNI5S.MŬbMA]6.$s{ui>1gN^ѡf׏Ou 1(OFF+vuf sAaྠ[*g+5Pam f*!]6r&SюVTVOl7Gx7b^7mgڽIgKP6mn;?ծ=+ yf]rw'uDKy㵙YGgƩWajeݫǾ.cAż=Mo\nL MUNx½Y2]_Qɫϝ>#p){O9gٸe,C9A-!]|Eν^a/]WWu2zطkJv~y17kφlUr/U9kPJEvC::GKГ9ӵ]6y'3z#jns WHEzDsڨD=xt.2-<:Jus]&zCmK9WCR77#%iYcL:+\؊۔ِd"}0VJ*fsNM&G+_xpƟsz;>RW֦ǫkv~tByeu&rW/T&3~3\:DYB2 <6k͖'9(Z_er|Lodj+y6zϋv!AV߾-k޻T.M=c;l92;M~xl99O OT:ǧ'xL x"d,LQlzcX"W-kˇ? YbuK ==Υu.Z҇z?Cgᝩn̠j0̢Us)y]]ZۧP`Ȼ_R;VYjm:I7}W\7IӧV^ˤsj0"~Zuś+rrswDbx:!e7t|^ܠ#^8FN`:ffG+٧ E?X֮Q#VCF;ԥɉ~5}.\1/lS_!3rhR?tt%ړh2m 1/cq zǖ v须u#.,Zvz,3zٵ mtAiZ5cGsv';:ӕwL1y|S\n] L8n_LRv1?#*/sK6m?N[=ڻcJɄYe#lf1V7i%M9O|u,(o)b^`MR͘ۆNכ yЗЖs;d:[*օJ~[K>miώ @oR,m6 Pl+o0kXWHfBr2Հ6"f[!~Z]ظS:-!QD&7?]cW@hle?G z&4>Vr̼U(.ʀ ʋK2SI\~HfwWꎡ)n6e)ಠt}w{hƫYUH`xDd3h+BrBj?2GM-C'@ol[asWE4`j}, sf kkFeΛZ.g &/VhY"_g@:\Eevx^6=Rzݝl]/7&܁JUC cgxQy8"?pz]䕺{djޢձ=fy(&f=mZWOO7B`‡4zM 7"91`Dv ٢~Q7n.aE|cgO E# xHJ?W=;Zp&Q<!泀UILD/ޥo,RٜeC3ZWWK= >5+S}&H6iO|b0(J.@dLK"d+5#ļR=3ClXN9Ci69IiQF҂ИIAkY%!BHc ԟj2}fP[KiN e"0ԟпA-\k) [&/TNybޖ(:mۈp@$0ame\ M'ϲT%0. PNԽo\n2r@81S>Se攟Z>T5%'0ԟ>{Dqt;΂'A(O?M4všnw}@mlDjcZx}vDgNj!@lpqUC!9 S!#3>fO^}5`f%FgƉ @RnzdBZp(C!gajĸ5Q#C)}߻ݯ< ̪ԐYb@onZ폗r-)Q#J^5gw43QavuwXq.[naOZ+Qfb^a@J^=@2$06_wH_CjA= 1/[R@A MkkxUVm{diX uwA ,@W1POu{odVnWȽڒ1/j2@auuǿ 'YDIlFSֿǬ]38@̯N Lw|zӻ#\ /uow\Gx*wgYGˊ!0wMg?M.V['>wlScڣji$-5{>DUDt}w(QE%wDV['.۩[ʊ1(w` fOq_O7~A=a^}(Б?%hf{)\h43ʚ۷wEΔsHBn Grg抡+N@㺀~<{pV;|\ v/m ?_# կ`[)W[4W) @m޷KwҧLpէ޲SSI"4^1w)[U}Lշ_CPBAn5?z>՘,BECK(yMtthI]KTKᑾ7~P7}_5~K@̫ b-~=zטnۭ"]VCDFbP_n &bCG1GsM]>Hk7{-J|*GuxHwO)lϷ](%ļ e"`kCu(۟٬׿S]Kcel>0voW?-H1wk 9} tuϏ׵GL&/tGq+('O(7'3wy6+Z$aӷnэ_{FOGǻ(%ļ F M/cڗtk+^Ӫe Iۇuۍ}zq6med{RIqS*~9QDz.}C.E틽۾ON[Od7B 0Oz1wybh᤾CDŴFmANu=ɩ`B7bFh62V ܴ2v4+f"B@ M 1vZ[19Rm]Pk7qoЙ7jدDR3%Q=~|xLG&eDIDAT= ѿ W x ;!P!~&3F(v:-]K PJy)i!lΧXdJߩkwi݊M':`oܳ\[̖/ZD7 b^v̀Tگ]tE[锧 '斐iigݫ= -jr*j^ fŜ-F@|>po&WsÐr&Bm9s&"_p@yݍz{{.COT2U? C1/ ǢbcIsnZ75| '/.D&TWې>9w]'v/n~/N/ΝCl 泡UkɀN[Gzjn5Vߠt&UK~~߫;7kdfi ̄b>Jefb2^Eo.Ɣ3qdQ?WkSUf\  p,X"wd<Ӈv?aEr Q$tTgaZݟ_mOA?)!@\X4\OTZ³0B4W'"?L&e] گlXF @RA~C>{ne; dgpGi/fZP֛.\߯T2^4JK Tļr|1mHP^m\]`¬{Lg먮zka t @KM'tԳdFШ|΄u]zyuL[CO b^4K8mVt[~H|f9֡vt.:.]z5=Hovs /@+ě}~M戉rK&[62b6r@uL"+/zJ;(o'>= ! nnq@@ c}ܜFrze&:LI6ܡ֌p~ PLy1 ɩ^fC \=l_y,7Qe2D! e]mj4\Qgә=^_=l7 W eTlr{̠=< jESjk}e\d Tļ³w)w>*?1iǵkdB7 "@̋ x( 3ˮ } }=ss H1/ $2ĜzmN\x@ 4;1\'ɃO617Q\.ζgղ iK%,*b^&ħ|Z1dOVEԣ4C| qԈO_9 +ٜ_͍GT_1i@ 'SX]R 5q^(xxྚjc|!b^(H''0{QQ 9 MCL;z P y1$M+n55v:VAOR F8L3t$l;,t>Ğ~n PTyQO)?gF嗖>, R𲚔2T^ƟU:6xs;WC("{t}FƇ#=pgrM#o] P2xȊ[*xY!{.Su+_ YB8!'ScROi^te58ҦщYx I#&DkrbGJ1 'Ӷꮇ(7ӷOgAoU!̈b>#LŹ(ltor3ELQ+NLrzZhb/%|b^f7,[d<҃O\'w5(b2W-b^fgG|i:Է,}ڹm}W= @̏t4Hٚ7`pBmLw5t m3}?Z,7k:z -a- Dօ}{hxX(p&tïO5(v q?f@|^ ws D|lq=m^;Qly)v,)A(>ļgC4?cn|X=ٺ5 {:/KW\𘮾j1_}{j~|ץf[tL?j~E1ϴ9ݧ>K7?r‹z0Ҏ=ˍ_t) T6  Psǜ72Q}KuggnUcؼtJ٥ mr%R7;̅ Pvk6=ȼaݱ5ջtZw-k8S0쯪 ;F"*::*cf}jWGˀ:i4'ħ> +kdVGu7+cU@UDfv96Ï?;/X( #1p !ga* @ <A";,L #9@Cs ||T8@pb0 b @@rB@Q @!CT@@>y>* 8D1wY @G1Gs  9 S!@ p !ga* @ <A";,L #9@Cs ||T8@pb0 b @@rB@Q @!CT@@>y>* 8D1wY @G1Gs  9 S!@ p !ga* @ <A";,L #9@Cs ||T8@pb0 b @@rB@Q @!CT@@>y>* 8D1wY @G1Gs  9 S!@ p !ga* @ <A";,L #9@Cs ||T8@pb0 b @@rB@Q @!CT@@>y>* 8D1wY @G1Gs  9 S!@ p !ga* @ <A";,L #9@Cs ||T8@pb0 b @@rB@Q @!CT@@>y>* 8D1wY @G1Gs  9 S!@ p !ga* @ <A";,L #9@Cs ||T8@pb0 b @@rB@Q @!CT@@>y>* 8D1wY @G1Gs  9 S!@ p !ga* @ <A";,L #9@Cs ||T8@p@gS!@8B rtIENDB`python-msgspec-0.19.0/docs/source/_static/sanic.png000066400000000000000000000464501473355726200222710ustar00rootroot00000000000000PNG  IHDRxsBIT|d pHYsxxtEXtSoftwarewww.inkscape.org< IDATxw\UnΦ@ti"5~ i *׎iEI%$7=?&!=sx#dw{vv|9"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""eH4/jhL #$"I7:qeC! p0n08j~@p`ulȬ h\2 p+ X~,<\n˯iBR cX,cV 0G` \9HIS DžW;±7l;Jwa,1Xj m+^5nPؕڋH FbnwR=qc`{%ˀ u̞# ^{+_3pӉ "PhO1/no' %Wp"=Eˈ״hQwT9fC!Isf=8( ٍC$ p5SGXvƏ,0xqԣCđ ܠ > XpG|gxqT?[ErTHIss';g"w,Nia*RR3kh98X$^-ܣ`Tf~w &<8 2ߙ$\x J&u]w"BR Eɥeǹ 9}R3I7 o$o*hsA NJ_dm1hW-H$TH!< ?ѕx?cݷZ+}'-8O@e}gU3IIɖͦu7$ IA0DCOH8w)s7Z/ES کc+HIh{\[A/%UMEl,"5w7=j'O*;lE2wC#%f}W'""q%Lm}'(! kF""KcMW;DC@ pUI?oi<\E:nF K@sIǾHbFl^D G@r`MO="\#˜#u;$0Ukj$_*KO$ED[/XsHhAXqAp?E$l$dr驗N""[_QYDع?vt@H8W7ug\x3,"R"̽q;Hi \ݔpS(9(aKOV r`~AE〟wRW7XDHiݥ;H)R1r .+Ϊ|g ot)})5Z!ф@,""1Ӆ>gMW;HP .wX2N`-3q\pٚVة(0W3i_Fhk/A r)0wdqpi-^X(N0HYDDX8Qn,Wuhu""}Ep;J1@s=ɗ7p[e*[P/"Oa]})&*1- ~=p,""%1MV/ſNCDh9>Gzɏ}(Z.=<g!"R\pt*M9 V;HB9kw$S ZYDDJL3apֿ;HR%W5yIw=p^ v""I/I5M9nEH܄Xp5;HR!W7ug\i05S{FW=ศ IH Ĺuf@Ϩt `?1DDd+l|H[~8w)@H qVT#fMw)*8vK}ɗ[CSь FR=gUH2:fWkw|(H8*Im1(F܀ǐ;EDDZ'#^ }Ud3?S/fPW)^k ]VA&l{S;nd3Eohv#Ty_{:soM .v,X{ ŧr=ڙ;H_%~M}8Fy T,~P2̠[w0v(l?!N`ٯۚ+vۇWCmEϷ 46XhhuH+[aE 4aeCh逬uVM=oXWwuEV@meϚVBTݎ | o8^[  l||Go\Z n{qE/sH*`\G8z몠*rAꫥ~)HW^P6}u)Kxz}x]GG{;RЕ]o[3r#-=h|3Ƙk3v\v+SvJ֚g%zDvX"E lp8cc`Ʈ# s%O mv8!;%4~1:NJµѿ<8#=/8*DzȚ,N.W N KO+sHGGa0wv|}ȫ <N1ߡBPnӔDO+S5/=U1JZɾCVb_]\͹I]G4}ٴ-pwk+k1>l?;m{-f~8q_ 9N"t;ZkbAz#_S_$:%So0~wn|c?>}W N仑i\1#WSg}꧌ulu\[x%weB8L}?*93!Nd+nkKod[%s%*&i<`q6?73 ?wcB".VQP`c|ǐ %GQWj'BXދSv= 0˭ݹűO>,ij`p۷Iػ+}'(.>+:x9dten':u#w^gN{eε(u+b_l]P?Sx=[$:_ |(&|wu ӻϛ8WxѪʞb^Ǻ#v>rA聾ӭr>Y,R89{y(EvvaSlI T& )ڸovu[L@R0yxn{!ْs}Gؒ.}`;GI=n>-I†}6xWރ?>շO>.Z-$ԏ_A|#;}ŶwP"PU?yAm-6ޑW8:3[>]C;O;ErTl| ?;BI],8߽9  ~9^䮐GNjxx<xqR|'؜X¡8EmzW˚˳KX*_R9[q~'ҕ?O_YnA]\'˚r?C˚OWk GCҹS=m@Cc*|Chkه=/v/n8.+ g<"H;dqy:3Wj sCMNܾ:u꜔ Tk9wuo1w4MDz%wxlnvKnxx"EXpU玦l]XP#K.7HdX|Y#^#:M>bwt3ttiXD+,sp kīpJNe9A [K`!Ǧ`=bUj;_;w3~?A?<82u"RDP7pb)ֈM@hmY`}/v|o)r2#|X#>e4 L߹{ODM_+n1e?ZOED8w51P3i4jNjw K)c#}mts!FǾHd;g}'(9`:DDJ P9J'v.q+մ 츳8x'#q\v:)E~c;N`{p*|7sOi ~ C0jvvEDb)z+3k5j+ow x 9WFZ_F{_ODd}4ո){1$g#"S Uп*6ZwoWD$^ Ǵ>.yko0vED\=?#5K{iԥ+osI@}tMusTl9/)LySX}""IG~ Ү@y*6[;tXKyuZ36EDJd`1`"oWr|lƓ""5U;:Fe΢2nǫ*M$)/|åY-~~vI  /L D氺I#6}@$"fOGZ8.vM@c{mR "9&hGw#=kP]m$K95Cvh i{ƶHK.5۬(GF߮HHȈGܸHۓ} ̀nF\#6&d#}Gy9RD$AllE\h +Ӷw IDAT[~cțIQ6YFD՞lѷY4捊VFc"mO6 >njHQ5]-2#;T "9 rae ^~yjM rQɏ-ْ0o ' @DdS, TE@wIM +ᱹ+rt3 iDDrI"`P46w]֋H)όp^u|;Z; ۾ ƀjiDD3#*ΐ^Ȅ0! 8x{mVN$"0>,Fz0K7K'S^#R.~r+ޫ}u074haC T,Vmp5o;$Q؇& JpӜUgkàbW֝)t/ʚT8!,D#H㆖c穥KAYY $,/ ΂R,_$:ԏ(Vڊ``Q R   {nJKӌQ}W# VPj,S~&Ǫ6i$Ξ~b[g$T]\%#@@i(q/i@E@ Iǧ {$ӢUwW/KqTnb@Ɣ-G,u{^~O?Ok\rk qRR;  n ^[、 yZMqR$,>3{0C;ANJ߉ć9}:|JCkq>* )b4ZiCEJ OY{Z 7*}+ Il̃K!_cbɤP?=w#El?&Qċf @4{IhNxtc@5컽hq`tpp\rlio#v,nDz˱*f"LڭV#sY/^; 5ƐZT[m Xܽ1T'c#vhhvGi:heM% 1vʋc=_O;^[cKŦ|D7+[d\D@ H>8B^ zC5!`cǡ0fp1C27] V:,yarܱa㎾g~_aN``ze_9+/'_8f/Qӯ`iexDrzTIER͈غo)TcXVC]]iɄкzx;6X r+C^͹]1Uޣ`Q#aa0n1&?6w|n~۹͡ -/9| .ÍQ?;WuvCGfݎ tѿ2h{1G_j\{%$+hHެlͽ=3 oPaѿ*bUcq.W,it,oݟ-s_ :v 'k1nh_~;XNI 樦VV^c[%P N!^_ݎ0vtx8_qh3d9Ba$""q1rYW;ohcCYEgFTکCD:i5oÌC|mό.Hqkqpl&i֪(8EIPD#*-Ch7a^{K{˜h]@𸿶EDbf`bm<}@DdkZWT>Y u.+qoqY;8("RQci兎?mskЇHl컽]w:8xgM{w1@w]Ӷ@ټZ "Z~Fyi}7f "e^v|G_nDD9?W+[s5yA""c}3 {w-o$$.8O~}q\ G"Rb8xOza6 HTONw5ߧ0(u!"<9O/xLycg-1)po)s3pR;1*|SDD {?U M__~@[RHqAƬ'w:)/{w5bSMt:p?տgwXW""y1z \y߮߷na] k7ښJD_L=x;;E2b]07ғ($O`~?7w }')mƃ43c+^SnP7k`hlmXQk?_ A]T2Puݨ̽oC#1[ҕu֋fҙ޴2cE+,XZq4o:ҕF utCds4u_}X~kWn跩p%_8HcӬO:u1F6`1VBFc2 gu+[hܙk?ՙ1{K=ٮ?q8w{c쐍˶(^66hhvGCk$VX֒ [+rV6\[Ltv37!0X8cI5TNvepbCpus;BX߼1fpA;A,z+7 uGZ:\qљ}#6tgk솎ڿgڙk+ѵhQ_TW.`ƧvCv 捎Vךg;ņy?S%3h>^Zlk7ߞEq@wLp~[o\!ѝ{?-̦XWCm% 5F ,Py-ǟQ C\ i uRG^Ԗ /paW遺 זz{7\gmX}ؔXZ8$+)AItkp(\e~:q¿xpYձ<{9fU3;I*_ (OkԟiThK<ljXݷ[8:8p\\ohpGߞ )o--x0N*{^[}(Z/|t;5&~6 `W|a`e+uuHb0w͉m@E)0Dߎ/#񅃌d$KG7{My}'ؒx-oQtm;)5*ǩeCD7bKb]8k}(:;A0HW 7'HO'm/h?v*V:@]+]IGD18ng;Յsbkb_XUK;G3xkݷ}>n(UR?ܰPGf-35/0-̛Q|'__JWqfU#D2 a[;FQPg)ْٰsW<:G|ͣqCD" cZ (tg1N4,9D6穷*E5ƴ>\QD'Y9M7aSe`FU3˛}'-r2wSTb k|H+rZ.BY_qɟݺ=X̅cT^,3^|Wzu! -"s+~r+}M׾lDT,wۋ/vr@K,o8NJi#4i)E wӳSCw۩^բ,G4/ϩLM+7-p}zxXsyv!_Ay"4wm wK Αx?xk~w{hVzଫNwk4k_%ֿu%.s/+\;??ӱhU߿N&̍$Կ8ιq/BU?;ɶ),l6fΑxo/)wtm^]gVtg 㞗s%J* g $Ͽ|+_Ì))uc6)2mىNKO ;GQ5<8`l&ɷg]hֿ[r PՅpˎ^r&Sof3icV_\]! h|vo $BvGkuS4DzIOeto;z'&ߩ lk W(t-󝣨ؘ\1pƸ$3cs»ѵ'dXBw+; 鱴9׹*77h{dWYISE_܀c:wUYvfUmSQ ( *WPUBy*PYU_Y|WWi3kl&*ro ^_x= 6; 5>+=ڨek"6"0uA,) rHnRw6j6GC+mUjut[cqM!7E] 5^5wH|Sf;w9F!ic`"(@A"k]vWwݹ3 s{tvCcڻ: { 5,1uTov92;UmM2H4zky}U; b|y%""gtН_(}}6d Ÿw)rfCER  hNDD h/f6w)ZWZUEsJ9Ֆ[ 1N@Xs`CDk-3fQ TK!"RDӈK}(*y.'|g)B,cZ;HPGu~o""RD^iuPj(xw{lv"AF g.,< YDDx Yu@a""@K cu_( k&ED$9*o-NRTx wsMXXk$N@i3""cmkwR "\t""C]X0Zf<;HP!kq?ؿ"@Dd]*p,7wRpĥ| ¿""I .8Z1Bw0w5`v5xwR3W;iED$"KXk L=Y,""xO@ X9;H#s}MĊ: w<{ X̅HFbZʏED$aE@Xe4Oq UY+|Gi u/q,""Nˈi(1{,0kwZ:ԡ (P4*UQ#/-h39Œ/ ڷt6< 1׹".?r ^[$tOWQY> bZ.J+Px7QCtIs?ucy]|}Mbt͍tĖ4KHEtŋ^ٷQj`II6ņ;Khzr%Huե{$OCu#/X?&9ls&%]JH/$0Eåc49]r}s!N,"9k 1%jYy8 8tԹ^1KzaɪyO|{2HpÃ?:!rdAr*SGjc#D|Fxz`tZ@&~g+=R#>9ctsBbDJ=R .Y/NO~-g,fZf2&876?Z:FnO!OQG6C^I_Q{shϾ32!y"7B\Nķ-@Sn3͓> سtTNBk9TLr,m>̳ ?COxl`Cu&KVU}DFQ{&WдVy:ɇFi4[1[9MKٽlO3B} _iF?9ҋ94%*?22fn^8=tP+PǠ^ ty4~@֗h?KHW,SOwT&"Ҝ17d i{8r/JsqJ7C^Oĕ4k"Z@mcg&xh\EO=Wp-ϼ >e >AT!ĕ~WdFQ2?q( 襍yu/9Qrsw<8`M* Z&=}u:Z_uc *ݤ)' nZ5w:@*lI~> 4>=xEt^F9yomxB0]$7Sq;xzUtQ< 02v+F &?36VvPgb"!D&Sw.2oa{/4ɶ|?QDR5}DqTqCkb/M4g2UiTCu"E$ҍS < \G:gyo0lRa3p/U."Q"}EÇ u$RUQ?yrH- 9zz7^^{^܍l @[z+=gq` l"iA R 0 QG'os8 zϗ~[$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$IU@\9(IENDB`python-msgspec-0.19.0/docs/source/_static/zero.png000066400000000000000000001570021473355726200221470ustar00rootroot00000000000000PNG  IHDRDH!zTXtRaw profile type exifx͛i9s4+7)V`JUYw-o12\_cxKk{q?} >~ ?} {T~?Eϟ~׍Va]](_ cڭ|s2|ύ}R'K. ~| p5MJ8}+Zj~~V_/I~߻P~{{<ȕPׯ('^7nmUptU(헟YHnan8 %x\lR=-ҞSnrnƝw1p[7ܫVXl+/##~?k"EQVt;?% Ktⅅ m]qbZH%[-i$hrd 79Jn,ּX"v0#j䦧Ar.OF J.Ҋ^FM5RkmU8ZjٵjkZoÒe+VYcOf鵷n1ʃw^0ƌ3ӎ~ƥnjok=k_i?2Y㷭}D匄EoJ3o!)gDY12OosQe?ʛkſ9a5o O*>}fD__ҰeC}~[{轄LyW ;*Pm ?k5!-љB{Hǩߞ)$ћ;kjszICj22rc_6HwsZe[["󞐋v.#ukzee]%p:c ?gɻNnwQOvְ<[i{N,JwgPfk(+Yf^}-pAK-ʆƠQ;;~sq(x}SnYl\ݙ.r5f謝rz)[1(}vXF5A_T:O\\abw7]c30l[2qn x|G+v4 )5"DרDkh9 -̶S8 Ua!!ei`TQ^IΨ 4cwx,yjATbdI[=ƙs5PQ#g?mgA @DU݁@J[#RLIt&TTfEonz*72j-VB@[CNB!ƺTYLU@]ǜdaI!5iR8.R6IDA j,qdͪ3ѻͧY2Ƚk-H<]k `gښ D¥7"y2&:%7`{'Țፊۼ}KD .`[hw٪cmy3 })4'Z.2h;,>[f;fxuS2OvtL%e[Y`RO Lz{HT}ҩW$;Bӂ{P3ܮWi%R:I\\V/Z-)\}I-fsTОe0(A҅Lb#oJ61}''Ze` 7}Aǃyr"|szS\^e؋|3ɨ᡹+} CY_wd?)WDŋ0Z`DݥEش+N^Iv]iPdYF(%:y^8}#W@(wLO]LP O٢``A'MҩԀQ: 9Cݨg 3Q O`d#qNqCy w(q f@dGё` K7N!t 8cA@oqY`8@6u.y<W0ł|<hooQ:.%n$C1C/ukGU=,_qJ9bS-tq; F4Pv:hv4ܭ˙M7Iz2]ȅW;~`X^(AP)n!i Q%ἊrǠPp5r[((iIG@u &Lf DS0 +J]tJBLc K%% nwk/!aJ>J^_*06ZgVAH+r$1;Y/Y|Px/ O&B,c1n~ j<xh(A z>4J(hX$Sz!@+k`:End*r"- ,MXRЦ f%pBbW08 0Ӱ_f6ܛW}u-XdceT?Ƨ皆jX]#@K@2ZbQI{u11Y&3JYEћ4wfI8c"9I Z-Hoyʪ>o aAE?C`bjY/|I@Ӛ(?hMjV1aag$5pgvz#șCiMJvCA3TT#9بygljd~; `8?F"vnu =h7 t(v@N^+lI=&Rhбi9GE09lk#sT z@ yu.YƓUtىnNF0h1AL:dB/<*o Ҍ~x9~JJ'(iz`*=Kw !8MQ(=4b9F(A.C9k@"lPhJK}L O\\td,}I4Iy[q¦+_+0Z&Cʼn)-B:pÓ:=%^qR(cRďhyh$DF98|-dd9ZiBڭI!@Pr*mvBI֦-ˆN [Vl"Oh"\+@{z {"O< 7^@'Aq 67ttͩ% h8jj:֑[<+w5&J`Jɀ+*K%'w"ϲ}DxP""bΟ0N \ÑV3>Td"Ͻ19 m.ZцKY qmiW)YCnZvXhS\8U *Ĝ@}m"EI"r_4+P0'ʧfK8$uUԱ\;DAxG 쳇BZѡɚSoMh xBzHE BTQ xQTdT/BI}N[4Zz'Gk[S;ePrGBL#y|f0\ 64G_j@-zA;^^tb$i@/Tq}K57¤ (o&D q&&(%8u4FYa'KFڇ3<в%=msxt9{ aIol= 7Ags =; ڨ<8" WgeI m2GqTHڲ_XuȆOr۠48^wafTzѐ߀dR q 5H#Y}GBzPNR mߵ}*MI%ﹰ읗F͘oQ7Sso?θa~S/=ȃ7'> Հnt(tl.!DŽ'JQ@7L*"Q= ⡷M;:>(<817F/N7lhx94aЮ#4ڠh4!F[t' k&~ =; >dlOV>¥uw 3tWK=eޭh\m?!!H6T"pi&{jphǝ ·W0Rh9рIo~(u}*LWA(E$0kzڬ8=*Q UMttJ+40j_g)r>Nx= .Ub5͛ I\=#&ْuu"Q7_jR!^ЦnJW⺳R[B̠AY5!9%?dm7 '/6(K4nߢk;whs4Ec1k} MBFMhfƒ6))r h_~^# sC{}@TdSI7J<~cԶJk!o5UR;!%P1t랺)IQ;$8{dF qH7Al*ibx i7ƒY3in )v 9x "x5e:#ЕH_CevmygxlD;CG$zǃ$9PK}JaTO$EF\a2PЋAQU\95T  ~ -:\ҵ;M[B8koײ*[R0Rgܚq "Ou0iӳS5ٝQu梙W~$)xȿkpb@x'FIRDPHCR#о(8" JK|1(T6׮!ATЬ\X mn٤Qiv]093$w +޹*?Q츔4j@ަJ0WwtV<"H@jŮ(gSD:imP5/r~bMW(ТꂜpFIY K?w3?26Ocsϩ+Akr+;H{J9E{: AV miꠐO}3,[?._)ҏ7,tࣲw #UeΐqeH]=XKH٘0 cOT_bP:?!80)cM3z;HiC#]2c J')̊$=8Z*N:}* x!~@uN<ĈrJ+hQK%7֨CNq$I1)+=_M CgEՌ&=FOqi?}Ɋ!Ze n{nQW9:FptVeQZ@1O򃃤I0rQbB%ss`l+Oɑ]@Fv$@M{r V;obE@9L; ̢hZ~jK\ q"QH:4}`MuZsۃzvǛMOPvt* 5U{Yb:&5u:-pZS0t OB :7J\AF́X$}f)q?]0T2 Oz:(bԽs{@;S' 'yˍ1EHbmϴ.2MP+D9@)0p}A[Sc R wBH ѹ#Ba>0umYs=c\l`A/mIk[&G-6, i,մ\jt:}Nx93_;:n̏;:I j"+@# #z[['Bt_'vT' |䤣Y_Y;,zmVk1ɳX8*"l5qEx.Kϫ V2kuTsٛ,ouzԩlhOUL17TMRDh3 "ztڝGZbxST^IB=5@b0kB3AU u:g%{V(P 7=kCځz$w/~.,xc=\K!dt_%6=^R6Lo{Jf &V~vpP)^m(&kDT슎Vz-*h/ LM̫F0"/]@gL8"msQ'#QҐQt{ &2$ʐ*CHxԜh Rܾ [{0JT[G5%޺ОFbjtr,GP7J'W߉nqUð0M_< G}ұY\E>f>BqAJ &T 8)^+UZ d-;b~DYdI }p&ոZDh{QAB<1 ӌ?|~Idmr:)>P8ިf4Ӝ$WHGA]{>-=Q^:k/[AH}2@tЧ 5]^ {bBSǣ=DױרQڋ\ ժ[!ic#%߈ cy?]y ģ٣p }!X =H9 p= |H_5iCCPICC profilex}=H@_S- ␡:Yq*BZu0 4$).kŪ "%/)=B4ktL%b&*^у~GHf1'IIt_.Ƴ:sԜH< & ޴ VUs1.Hu71өyXhcYԈSXY+WYuH`K BA%a#FN;\D.\%0r, Z /)_c|;N?Wz_3ZZ.[\Olʮ)}S}k^o}>i*y^=rt6 iTXtXML:com.adobe.xmp 3bKGDR pHYs+tIME 07y8 IDATx}uו}<H3шmٲ#ǎcǎp`dC8Зld7nvÎcd3 335wUQ F{t?^wypiAC@ D@ r';@  @N D@ r';@  @N D@ r';@  @N "w@ r';@  @N "w@ r';@  @N "w@ ;@  @N "w@ ;@  @N "w@ ȝ@  @N "w@ ȝ@  @N "w@ ȝ@ D@N "w@ ȝ@ D@N "w@ ȝ@ D@ r'Scȉ:q"@ P9 uݟy<: DF$4 ~œ!LZd&"wp"|p6" "OLCN .2(*y]~#" X=1:HDALV8JpPQ!"pUEl:PD""zv:VTsŽ}e Um=cOPPDD@t?稱⢴tЈ ԅ'^9ܵy,SwDGorNv"w0#Cu}j!յr\@y)Q$;@bF9ٷT_HEDrQ(4:Da UN6 <Թ3927Gr+I(ȝ@ L <~~,f5!GMzη-GǓȝ@ \Hp殱Wv8Rq/TT]ads(l'r' Pu\0AJFDQUTud>e@ N TL8Zcv0xa7m,MM%."r'1Em?pb1/IYd:g"wp0kyp (0g&r'𮓽/ b#̮򘢊Y@~R:D#$\7BEUa%caL3hϳmA@p@\VT@;ŽysK .;9h0a4EFǢQ5VdDrD</7EuJNMbԌt_J^zfvJzfJzVJzfZzFrZfjz<jzfHs a:>ߴe|"w¥ sXd08 tZCP+!U p9\9"IS 䡅bnʤ\)9#ɗ!%I+.5mzvAQf̼_r/I }611UNƇQ9?;"bp?466X5_[Q\30 Ѹmxb5Qie ϙ xn9yYYiɗZ׷HLV;T[ " 2Df*ǘjz'kHka! 5 vW uFcATDճpDUȊ69bq`)Qvu(31HI ,-,+ϟ9+(ٗ|QXS?BޡhT5r7oHhPc!ӎ̎tAdbw'! ZN ncSl"w”"{Zn km1CDgL7o1+3gzjq3̞~~dG3}`J聮CO[=s7)LO\UTjcѴQ6%g M0B'' [>DoN $Ne酷ݲtIAfnwY}vg';V9dĕ-#\33[,*:Fcʿ_{Ş^9j-]$lJ`V~stj:즙 *!5APK }Ŭm˦%qkԛPXOr߂jCJ D y3Gj\3;0 RZ,meҨ#g̃'ۧ=G^G1[Vj<\ F! ǚla9 KRʗ^lUxX'ܓ:/W)p|P`w#= [(ZYcˏ-ۼۉ c#/՟znDUvJ+h1)xي16s`%)JZd^ e{C$x]ʗ\N8fxOοjsѲw @C ytELIhr5K z8$?By2D pS5v1!~GP ocq;9" bp}hz +OߍUOVMq2 gIn,-69Pk م wDгP[FQt+±Vi\;Q~GDՐ Ng6vź!c{Ka<fAiVlilr!t}eU{WJO>̀yպRP9V{§+}VE r'76d;ρUCJTxW2 j m S)n^cLЩ=ݝ=vEiP(BQcbV/r `MELg&i_3M`h2f/BW,r5vTՒ..{6dՕE9)f{sHq?a^kU$A G?29 gq^yN|(r'L5:|ϑ/*[0nnͷr9pA7pvE^]^5RM__Bu1J3BGʘ>^VY,[_-7=.ͺm 7Zʜ{>XMs'8xj+G&cZ4\M%_|xet&QYXdžl4w0$KQqmLP*4^C#p6k`a3l:/r+ >ڿ$i &l&>R-ҍA>sҋƕ$u6yCofNX"wg5xAI>?Sgj 8]6j̲_t>M c'9+Q;J=| p?遶Ff;sX{1״„9>1@z+nk^dt p$s?R[V3FҬ z+ (ȝ0)h[=ަrM`"Y;BLUJ Y3`k=Ľ_ v1;\uf|!јϘJwTҴ^gn㻹pIN~G~G=Gއcz=[snh2>c]G$sa@NSON p^ize7Z[ FjXUtc=D`̈́ŽRC3[1o↪wq1a$&Zƍhe.MqK9qo³]?jklV"=v6\,M%|iO'dCX?=CaFbr%r'$Xcmo #+*UA"Gc< ">L=*ir^ B;dckMbv*T|%pՈJ=s3&^Z w} &[v_<: t4+ecir2u&r'$ݣy`1W=ľ3;bXU\q 6{f0#.f^vy1[ 9|c,~I41Pgd4m ]?BAgҎEG<_]H"f3&gs/mf%N#;!a8!꺳n#S/~׈êәݩ-rz{$8c=V{TB@r+璡 2cÆF45`;u+~%/~*m{3jfhՊkUu33z$r'$*[rD@UGn:aC<[rª]v~GwJ=fNs lhZ r0sD l<DDnƘĘI"Ѩ\EDpc9GH'8 uaw'aN}[sx4^4uwKS~6GB?vuI4xYKNcozm1jѶ83t8̕{̩y3Sx[i$ߋ*2se//SPW<)$Pp?160n (u~N߭ö ~eݭzO#e $r'g#"pݱI=Ո=UC0%p;تL+Y[|[JV\X8$;//#k܁̹3?H(1:P7yj4quN -5m%K?<[Szyі1CriT4@21zu1jz;91rDFy9y!"P )1a  aL`[q%ٕi̬m˗O+HIMMhYUFtB!_бgt v-h%_y+S/ ;"j&bhiSAn:]Dsg=x"0O sDUtHri 1Ԙ`2S,ϾHXrE~ɖYs+KJ'IAKDun<<к{[ϒmYD(Re+ \wCQQ;'|{['d(CN87?{?`kkogrUuuFw|L`6i!@7VNE/yEחU5 3{JGTv=q!2*U]?bY[s[<?|7$wRB+(Hytȝpn@Ѻ R+tO~Q(7 !s9$#Bg.E4.wf5okyŬK&SZN۩]u-E߷e%9b{HsQx= C2ׂtn-+ďT_(l'r'[o{ (N҃wԥv.sٓJT16 ^d~!Tط ϯ,)J4XD jxA܃frZ}(|sL<Pz Kr-A);Ǿ#'! n1eMjgw3 ' y/6~u`6r|]lV޴T~9[CoPPiAjƤYpMW$v4=Z݆͍˝QQϞ8ǪaՒz76RT͉" IDAT#:q"z3w[Uk |cWgy38-EW/,ɻNMJRY V̜ၮ=[;N7͛ R^v++h /'<$w3n'ֈYX64F)3w4ȹW7gj@́hJpdR2rޢ˽\{t=vU+Q)LJцT$ؼs=uIwT$X{?튨nD.J6dҥJN8fOTn7N.|Xm DZ:,2 xTJHqL)Yj=Q#;U3 4wZP#?X3HZGV4M+g|u9Y 6UUWN3_3O)F67?.zj﬚¹=7CĠ*AӐ{ѥ0#7+*!'I׶V[vmxT>?oӭ\}*<ġ)w}xe™|>mN=7ܜt)r'uDZZ?W2{1k;GQd{DU,9s  _Xj܅t&p}n9$s7/O?S^MΕMo㷇zc̤SLN(ZF`LF>o< #'+GYZMc=gGV+Ρs̓+J$xtc'z#mW3bh3 qKa~CVF*_eP0CUչT+)R3l^ DAT G[bQpU_*[5Vm9Cbl~ai'=/59j:`mf&w%ci2JК̕6(0}ref[7%IS>keRomͣn^>W-8?^cI^x,C uvqm1V1.\ G({SW=*,JMTC8"?J{pEyַ>v26QOiYt.(r'LG:{h1v?mMuEqys6#G2XZI[ifM9 ~䉗kG%i_@>ABX7a-M*F{)Ȉ71eU's/겻67XKuSݣrkG?sSo|hYIa< G~|SNHB[V~+&gAfU#깉U&*cƞ,<~Zh~esitWu$wn[\/p~57"W޾N=;!xhЊjDvceh(l+Q)EoBmay9x5O4!?*]ՠս-𩀝ӓX`N6\oІ"siMVUU}}R\*3xԸhUZBVھUo[!qO R}y1#k Ķ\ 9}jڹ E /~ z sFf&ˆ/U+~#oQ?.[zMEGi羺zKb]UZHUOPqo_ZKW8yf0jyUQiPN8slmgL1bsKb`Ю 9^^\U4DBջ~oт.Գaچ9#~|ŇoIMNIG#_^wo╙ľuKEEy1xhO[g\-D2t=.ߺ;th{w)xͪ#IR`2Jg}ddNkN%}u閫H8<S'_}ҿv]yp~c6#ڝ^Ȍ>B>:wYYVn& "w7bT}'@m[z97ƐQ[%~p΅NLڻh|~$:B;&L/\;O7U7lzLC F( 4b?R?vRz;'?pu۰;B%6zG*zmXͭs1Zp0r9۔;k믛W:VϏ Esͼܴ4))ޅBgS ?}[ 1B+" hǔ{Gu3CvK/"U=-Y7\U-/_0݋|Ii}INc08fcC-'(0DpSqmH7K%_eIfzzKh0$x{Qt|'P!r'8qs&u15`Kt( eɶzf ;"F5n=AˁLϫV,9i0Tu_n9jT/ߜHLyFTOO}CJO D^ۣA1ѓŦ0bٸʒE4f B1~SC.0Q^[ڛKӶnI6+1+MN:;56oVɤ,ߺmR=Rǯ HsKcT}oV6l[ؑWN^wU v c1SDBw@q%`]6~GAw`MYw[DסNS'OGMd6ﭹf7P/K@syͺG_7hs VBӚ"r's-B({\uz;=ƹNN-Ȣݽh`]8uY! Ӿa̼i DD.NLoˈV1~ꝺY!rP7pk+RQd23 F4!/?wo7DslNj!'믞=R=S'8]d'mٓG$U {:ci$'n]<`Ȭ*Vh:;Ά7n (eQѫŒǿ $n"LT/\̊˥Œ?XcͩpMM[}rΟ2;_^jq_*Kk1%x1~Nab1]m!:,7oY{ / v؜rUաØ UZTQtfpTñޖ뫪C!-Z@I }|GVlHOIN4>f=&vUEy47ǹt;'~/>]3xv~_P[Eo;{ l3V/ȡ־%t_@]]+Q|B}l xn-_8R6S9?x}a^W.Mpi`Ǐ::7]ś\iXuRDJmࡰɌޣ״sA73DD:GC!Do=+ZB5 6T1` 0X(U)JMoϽ'Q.|"23绛Oyo +gIȲWϙc1jcRՃު Ht~ON i"KU}~AlA{{]_1 E~W&%ymo5'_PG&7MºYy_kg#@V/,y npgm7uW=Q=}90g,/eT`ݞZm;@a8h-z[2c]2R9o!] {c*[ѕ2})OtĪOSmnr_;oCU戳`gƩ\ƣmDD8zѦ"f[ZB7!/ߵy27g/qG:;Tqz(f@s|T"ۧcoyvkEvZWYm \_Xu[\}D^n4o,ȉ'n9pazng =#_u3C~iq(mSg5R '\r` Y0=J tbh.yݦf5dO̙Sʊ{ 7/7+/ FGޭxx$9%y{j~oIiFPbpq`v̯t5_*388xJP]A몒[v~Wוϸ±ػ-Ն`g ;;I]~}YQz?fwgUE;6$`Sm[/̞fWǸϰm;t5ն2זe nt0&bZ8Y8 GE rVbVEtXB؞?6Gbwp.t۫r~¢~ODnק:9 ~q1-/{C_%"ӆ1|뼚: vE\YB8!?t苄iDG2:`3g壊vՂm0]lbZnaє#*o7fϥ߯/, }omCtYanHO} N/-O,>g _DT3k5pi ܉/)p8 \ ș?D2VV2r=ccOΒߝSe[&#i=9%i7n(̋=&?w߾Px5|kx[WZfanEJ}G79dv!4eլ)Xq:.:[>h*Dۣctk5tT{w^ IDAT\@Ws'vMsq(;^U:,'r}WZ]Y.w0da{˩ۖ!_:=1N8 xN #on!jM>X9E5D{0L{QR׬[;{NbW-=?[;|٫nwzn_6XməeřiMWg/~7c#BnD=U"Kcn\8.iW 2w# \3g*V7>#t}4ꬬomT>-SM#>ZW|q"Sq~2,/z ug*zznY v} Bၱ\"K-QmK`c QOkjw*c2BL_-C5=-[p38}Ǵ/oXSs/7x9vaqj[S e'jdlH47m;Lfo66l@r$r'rtP31r s<:H/G=WƑF*USrĞQUOwXa 0>Gr>:kg'4&i9UX]Wfk67G ,V6a̔d$B5lwmW#N r*j:NV0~(攸8'-yJQΚG:GUnl3qQ{U IVV&Y}:zUCUiVn=&0z}aHNb낢ܳXE!_]$_" 9^JF4nyeiWO| h2MOwdQ»mG#kIiPW׾G$ό=F/>znT뮛?-{/dܕ[PC< h қO[H̚`4{D GW={;J"1CZ绕ef"'ʦ]Hs | mbT ǔ&MY %;ɚxws[U;Э5[My,_<3`p:A>0[m``,DN~I{@v6@Ug|̰-3#0anj*L GinS}KsT*Ίv5_ߴ0;+ߟ#>󟯵 Ԅk|'6zGgr3'l*m7 &Y!)mul(PHbD1i&LdFAuVxK|05jh^1L`ω'1铥>fUfj"#>qTQ r?z+4 9ƵSrSgfi_jdqB 8P%/nD>de_eh$׏caf#X UΫo0PmۑPȶbgh=S}mT&%t FzӣC5<+,L <jv>+d߬#Aa?[XIZpBɴ' c D=²:܉Zm8*1=7;?YUu?RӲ{,'~,;i>֬PӁ<]'`xZk7/*ȍR Q-_?_IfO;)8+Jl=ct$O b|TYL0Sj,YEpk]HٌMϙ #f_]7OKd""ֶ8{MaE(Fq YI4rCq ^ ֕$rQ9kCQw]]ra <\zh? մҬ+kļtV}0QP{lcQ%9%"HDu@}Sͅ,qn->?gπ!be^$^R9|0zd|nɌ1kkW&|t sL|zMɵfǹۉ6~[[?a;dd 0C6~pct"C^9L:d}fKΣP9o~!.Ԯ eJ쮊\˿/4IEV $reyi)YۃYw:mi%ډCD+q8NۖbA]}IZrI`FO5?=4UĜv,ݲwWipue?vu{VN}χؘ%ɾ{qYdg TPY= EM8o: A6z|QKg g [Ğw*uGF?١8Iv~QwU% >_7z#jblnmeYy#=-~;W26^0%l9dk߭)hE@#_0UFlN#\[gN1nPĘ!*`zrRzʹ)D F^kW6\߁ qqxJ\"+-ۧ>7{*Oie >'UotPMwEKJ/ԸːvKq{!0|8=ǂ$_P9(V ^mE1&pCp{A/\77~_էUWx 0ط+w񂔤DP]U ڒkG7}23V9u>[dfs$6 !<ٖ&ϬR#0DN~1#"s;cCvg&;[s؃"$ɾ{ϗr,ow<]*V]̀tv;|_WUn7'>#_<_fW'0?[{^ys| V/6-#uΟ@ ʌlXxZ8"w2'tMqo\==cQiII 8n32a7s>Z^EVd/NXdJ'g'ObB MDV>Xy LJguӪ >EwO썎233~SE^vIGʼn\pEqiYх̂`O;2wBnmR “F"EX\\׾;tꔀIBmȃ{ܚIltcwwջGWw]Ә>{c|RNen2΍ L}S՝iocVR+•$v{*Jfnj`0$%0vt/MI rLNKO! r(8 Tc^ LJxyi zc7F`oa ?|_Ф7-(-=FVu=25MZeTv Tq80ޥ/Zeq[ܡb Fj,l<ƒ5h[<3e ;#gKV/2/ۧ_j{ ~e{y ⛯V՞۲T WgNO]<8-;F ENv2ubykӛS$IvD4.P[JLΒFYJ%x6vκ:ggo_]' ފ^Sn|65NjFμ:s;+ӆ@~)  2vWsFQ ,I$`feF sgБ?\M˧f%2~D[7ۺ"|Y]9/~myZh5eN!ln3xFS6&ϩ/fV:s(2WM( |V{q}U@RǏ%`w*9鉬>UT_ )J{;{G|b~`Fv- ?{EoږM !{`az w"SφAEQ@"%@BI ;3ݝlHv7.|q);oyyy#p慎I<`grjr6Pc{3!MM;yuw(PpHdTވ>sݼ>(mW,XbC34Vmm Of"KW$UA`Ϟjr1FP!(A|@20Rta]bjl7.vw Q5Z80;VoUYSs B/yaʒJ+@c"8ω"s͊uiUU)(~BArfxwrR g~m +'׋ߑBW;UTDb=<_ߌ0Oly#e6OwuH?=ohq. [F\VP!LUg̥Xg׏BT)V5UHG#N,3W-_w@y:f:| GD$9w_wTV7j]Ow雝Sg6TԺuGw˨ԩCB~BC;ݶBo[YIir"v[]E#AVk]*~fir^h҅ŷҝ,7Is3õ/(;PZS\|a-Ë:5V;nK/T@,(]!pŔYEkx+ΌHM |1Fu]F1=UMi;!4#WVE(b4tǣ2cDTwNf^00+ӆVk돮=i({~K*mm/>@1jK9?{? 9C^_gE!Ʀ ?rbLaz} P}#h (߽-=ƃ6`a~>n}|v] SCmxV:a?/,dGmkk?2;6NU6 CbLG1 @ChOROĬ}n*hi Bu߁^Ue>LO0y\vT,kxfcI'ߝqwO#A@&8 X./ZQ E);RX:34/%N=AA*S]1G06N ጏh X w/X7@l*+2SAD_86^[GOG|B;͏/붹ц4b~%P/ ?rfr@*#;')*Vl}u FZU&U^1rI 孏&f0BQKY}r9@tpєS? |rXL&_S GWUzS{>o+D×ŊZ=fl~T(8ޤ( w i)y=1-"N=0ex=C%kEm?˰N K#>=60ǘ5O;G0)t>TU5l#<%}nuUn:9#ayvlx = rk ci\UoATolQX o1jR1MO^fGv񾯏'0X8>_f6e§28(jĂ=f[k az; )گZ_GhDg2b=AFQ}ExW)35 4eh(sqN_Վ2rݞ%;kn߫mڏC=lPb;>;99jdEP6^"e[սeh& fAr?CfQKB2L|2.W, IDATOɪ x_qCra-`9[+SڄzyFޡ ˛j!v:72WK406?w#dfV}K[:fhHS |ͮi8D@r 뵞*~KhDZ.񻤿 i}2kdu誓q`#YK("z((NQ|r?oMTSR*?Y[C[8{Gk@dN΄5}bs?Dv N+ ÕpMII߁JON6 ]Kx]fP1NL*م;RRJ(JBr'8= UT8i1ڇ_܂ۑzȍ 4$[֨a@?1.@%v*v{ S5*cP)!e-;kt<1~WEh}hs=ܽRYh{-떡 ɡ@0(A$$TA@qB)3L)bZXY_f10(ۑ9-gUʼnsDžA.=TJQT~xP;g! )0tHNtOy`WGEފUT@Iz@ WHKEd$r?Ӑrt:N '.e]DI:nLxefmca>]uMvjFM3 B"jt!s4A&Z 8.ʮCxp/baY R* 5@-9/6>!P!3 )L2GUD%7<ъMS+ݞ8ir{ qUtv:'] i8s Bu55?Yujtkl߁ʑrό)➝ g_x;MC@$䜢$/YGS-W{>$8E3#^fo?ơH8,\8wFR-|zMCL">iF~+7ltƆFuZ}+ZҮ\@~q:Bg&Fv_ ! 85,E{w'/-1G: kOkBYz>\IXࡊ6u߁߳b͈ewO{VJ@!f9wC,,C$, G)3 YfpDmمr{%SD>vt wL/-BvVl]3p-!uD  وٱR56T ;k(!+SNE,G gk񨙻 BkZ71YGg&5}*ےVʣH)8w\^E} ">ӤXz[ zG_dz=XOڹ@ar9u*VW4Zq ]{a$cXG_˥M"399|ӴpT|/)[be8mr>DY.M}X*4EP|10߮w d%qcvGP+HS.?8~Zk|l㱕Uaf9qP-_ڝwT&G\]\v h$ F є LDaJJnLr GFmXB=tἈu9za4YPՍzW@B~̐c\nsw]'{3L mkNCh&1hY,G}Ni8,;x:}^ߋCr ߎ6kKaQ'١'YSM6:ob^֟jݳZ&tlf\9AP0%EHmz'I ek?@J!MxH5C&$^fDux"Q<%"eG={Aμ[i<yzHyrMǙc(WKA5ŶhK!Ȣʸ@SRPOWe.&42⯑44haNTe6x ]h8!xM~E |y bc}-+N"]Uppԯz45z@{>~xFrR`xr?;o'@Fa2aǛ\wlŲw*0C}vllmӃT@Nb=)7_n-?QiEJ Z~Wc(Jw3FM,(! ,GRף?JIo)~_?8"d)HO ~r 9|3>nI&[CnUU5}u8EIʕ 09mhI1"xĂh]xnH<٣d:78ȄT|WKM@ܾ9xx ee56.)&&~U|{⨬h ].~/SHC*;_?,14b*Rc&RI~V3PV^; evF,:ojoںRhO2b1$;Go?H ,[T!!0 DY~IW*zK5Xm>$MΥjK| :Q#M}ol{JkqCܿWK/%g7&w9!l2ƕ+K9T/̎e(#/|ZcjC~&&%&ŒKDgY^\uЄ3*kJ<`<4#t<6dc'?XuR ư4/H4JǫZۡ:<|:}b?cz'G2u+O_QAC Sfh{pcNȝ+k4.?f_;+>y_a< xYcBv9d_-(Q|I9 be8ytv݆jV|7GP%@GL^#_.W>)@0ev!q":%ې25/,1m(/#| y}Ɨ{3+EQ&Dfkokjvr} 'j>wEb%4 0~f\ ‰7KNxe4e7#tw5?"uLPmE6Vp *@NX%EbhQBvF|T,Vv(]VY> B`2殮̋r~Ĭ/Q=}& W"!wA/ǭohv\@9j3_HV#X7p-NW;My}.'ؽVmEWw)cSoncs"l\?py@&74Y 9S؎(1 /~]E݃pfnyNJCFFkqb͈aRcU|l}qBPp8UDޘТ(q:>ڱ@Zq83 m)ID)V N;=#\ qc Ǖ0@Ǵ#. YZDl}.oɳٱ|q[-M”< ^1ަɍvʒ5J&=B#G zft}MjyҵDȝ 7+edUYⵒJAs׌eC{'|NJ|2FnU%~0(%9!r U)Cy Gq Gcy ȅ \ S 3ef ?Z#V5XM,c1r eGX{g=Ǭn?_W)΂Ξ"oWJT NEQ}d])KׁESЌv*3BgOՏTr'ǀ i.A(>Tr!5TZM[K:@/j)ſhՃ3C)@j_~6,5x^7wST;bH3TL h!P tߥwB5/&Tr'&l\q9*(PV8J03Q)9ELj_|fߑQj{AZ7j`zƤV/v }` oP`db,MSҢr:xB50W  , /o)0R q?M*Q=`_yPȱvS<82mtQ"B?ի#C!ҕYoR]IySY⌑WT6?muU"Pfh`7I}SQs.)]( RBODBGn /Wj@ti YC` [Ưvaƒ#&#h%83r@d_cWKY^a8[;S4YyH1sJ(ZOs3kO@=PjWG}5Fծko2>zr!,aqIvBw9rM'}xAe eA? ~R%rL*kiu,tj5z@@  L\ehM*}؁4KCJXK[,fr1 *U;W-~-K_ZU^$W㔁 &f t!ȓz;Jx30U*I4 ()YDO.L= ȲchJHu4-@ MCB4 9('7\z , /xzj_Gјqtg0H4'QOtZ] 齒B;wjs#z*s$B٣3͑[m5n^CwFah(gM XoU4EX q㳇'St b Im?Ut%O(!G}*&k-PDSTs{L) >ɍ#y싂H.49ɆE=`ߖ͹& q}.\([v6e EOo'L'ZfQr?q=M6y%l.!DAx IDAT |q3: > 7Xpdމvn9֊lSrJj:.3Gdrl _?m)Cih4,i?vYui߁SdZ1BPJ  t/4@|yo Ȩ"njH2]-D!2gPj;5|VRw`bܪt2j3쮟_q!-*MAxFPCy3̀fi+{}fr +/bB=ٱWeG5,Y*}"jOCx\Hb!?9xt&(tSh]_} ^2 HA0}xfO=B5sxE%2r30k T:]ӫb4Ų4Tޖ7 s/꟞O.1B=[\y®xV2gC?Cb~~o*f] 7?>̅Njn:aEpBT|UB30'Oc _//;&'a(uueF#eHnaY M:Q DË'Z=2$ x5jTZ42L ՉXQm!*t)V Y׶b9*ް+n:P4e`i(JU($x)KSdY)%d! =<8^1 ݸ*iCzO5D jW>DY(JuJڞv$xK[@jjy#Pj3 jȶ^yح%44 g)Hyymn$ Fa( ]FN+q v9a97>IgT4SfM+bYK]v7lip@"R{?_?"C$=Kƥ=F?|-"9=5ã(Fn0$rʐM+4fL;W(TQO}y'mt Y}ڶ]X@QRWfER1xUuIAhO Eɣ3'':; 1aIMjR] TZaWY"?O Evmr+Q-42mOCVYz)-P R=& L E5:O5ُWWY9<4Mř8 B~B?麪PHvRǰ, )l"`:3'C;A4;sФ-Oy?q5һ'^7-1lj볉3qFN8[lnA‘b'1-=(TvY?Q풺PuO|Jm9z̑Vƍ5Q m@Œ!W/ǭ\T~~G ZqY!$"t-6B "~hNkN]oT"0Wު}G,)f' ~F#8fYU"?!)7^eTaծ.cU@9ݼ:#{^: ^py[pGt>ڙ<~(HCCYiBP ~TN19} ![APcپk$̌ <XG8y# Rpzi9!u D$E//򂈐[!Щ+&C()2EKS4 oB*JBHG :Rgϝ+)D6!wpuvǭ{ݸjMQYB!a}F5gT F D!{6^0@ B!Ei|tLHrcZ󻁡 O> Tr'38~t30# tXi+gƉ`Zk^ 2r!)#3 Q l2לLfE(f7#w4 %@^|Go z"aJJ~GNvm fͭw}rbHO!+;A_5E-Pڈ2,},$Z' N3#M]u.fjo;n3UM qu쏹+ԥ8;Cp~4  'e9.B= 5ֻkB}~׺(W;PG :.U]1N: M#C%eĒ:B^@u6]wAJmDa!8HWo/\*O$~^kl1R#;A!`u 卮ܭʮ[@mF֮5#U5vY}]Q4`❚ ^mwMaVaH +Rn;A4Vϑ&V EU1^ ҉zX8 N}~܁RB(\`$N@ȝ y/VzGۼÐ1R^H_[OHK:Ff U1qԠ,saflFr'8œ-Fwz<3xZ]kv^*~zS[OD;Tl"&_ p8<)]78Ep.H֑ޢwM}>_14̱Src:!w n?Ɵl8xQ%cEvbuRfw}N;bih1ҽ9IdIN@ȝG-NX:+]BmEŪh5#2 sTr f%cYK K^]BA(jSlZ%ŲFc)r' "VZ]BChq N-"<Z\A*Bk9X8 @`fLB gc 4 t1݋#"ܼ#݂[Atx X,EK R mb),Cq arBJ& N@@@@pr' N@@@@@ȝ;!wB r' N@@@@ȝB r' N@@@@ȝ;!wCNA;hiiillljjjmmu.-%%q9Wd\.; ! zst:{dccc!ay7|x"RE4MÞᨯ߿o߾sݮ}q Ǝ;h޽{[, e"g!شi?k ~'xw;++kɒ%ܖp+W [4m2bccbcSSRR,KT,]A?/lܸᆱ }ƌuN0l7i㏛23/Zty+];FACă_~o tСGy+ ;pwUW]lٲ6ÇdYwM7ݴLw{cǍ_ Mw){۷ @V!wp駟NNN&kn;v_?zC?|t_6u_}X ӳɃ?//OCV]]o߾k~jU{y!\?}fϜqE;0>>^[S]]wUVH MOk/bbb̙sW<oݺ ^UTT⋡={1}z;],͘1cn(Q~/^a#O.r/++ANSINJ\s?xVVVg#ht?ef_lY7tur' ֬Y 1}5\C f͚V'b%G}Kn0LA_3gG\ZZJV!3eeeO>Tp=Aa"11qnV M',˃06 /\y j*3zTVԮ\%)$~+&/|ƍ#1tОz۸qcpj޼o׿om&@||, Ǐ{mvzxjii/0/7g5|܋S>d0uM/BV!3 K, B1/&֏s]u59)1!Yn^= \w&bիWeyݟl bn~F/CIczcG0?ME7xckWMM Ylڴ酥Kp@~{/~1;%9Y)u^E!~fFzg78tYH!=9S!y衇mWښed2F˧899ڒV'LuMiii7x?l6޽{g̘A{te˖m޲%mx;.))ۺq睷w ---Zg8qBv'j!ZÜb֬Y%wÇN'y%عs翞}jt؞xwu{:(QQz zMG⟮oi]=\83#b%%rDsyX'|287~s!@mݺ}zرT nQO<[mݶ-! >`ϛd+XEXWW[o]xA4BU IDAT bn(7AlBV Lc޽jOy9 ,HHH G"tӉr8MMMUUUl꯷nĻ=j̙!ޤ=Op#]l;Aj.YBp;$֏݌od6(:NAVkeeeӈ'T\O$l+ $A&Ϟ9'֏݌?[o袋BDQ9w_E&tDs1AlpѢrgXx1)! ~n+%{:s=L?h]keggJ…F 5ֽAl8?tSS=;nҥzͫ Bw\Qcf;g38yx cg~j 4pѢE~LLLߖ {[[[ӻEQ7No6m9QI_}~93"P]]zTp:Ǐbn($N6l޼b͛7<99΂˧LҥoZl٭FC"wBQڿ}t wZk"C]rssc6mܸoҲ#G=٭Fa2:"BA}os̉6l+4Dİ7w&~5kV7^pjϞܮ۱M?VEEE]hFȝ S ;K/Q0v;n٭^vo̘1_l jPi{1`YdrtڵG büܜG}TF ޷smM - ΒS(..1}Z>裍A 7%\B:G:Z[[_y}&0PTTtwtvJ_nwb{`=% Δ<A &F=!ʕ+XE^p޹W]uUt4M_yC 솯ߥ!9sFa }֬Y#bXo[pI  {A/>`Gtɏ?xgO>dyyy[aa_Ć M~? qjjj{챵~̹MJ;w.iG4N/c>2zhr#SN ko^|:mu !#?qyem~ܹ {!z> rǼo& HFLL̂ r;7Yzuq;۷#=ܶG]u5Zsssgx{嗃sbI!K^x;ۼ~Ŋa߫3fE߱cOu!jAA=sw؂k_gk֬={]6lذ\ah\ S[JKK׮]jժ dp;[n!# G4n+a!wboNӧu7 ۓ'Oꪫh sݰa}/7+\UC7.'''1!i޽ZNNJ_ZL@ȽP]] C]Ξ3K~nώ9ѸxJSaמ]{JLu]3g$+* 0?lHNYĄ{7l%{_jmm}uquq{D_}⩧y80jԨ?λ9 }/駟7{Gy$!!,$B ̟??Їy p:>pYfFz1G-]4?YE#>}K~ qBA|u7pCr'sl/Bg T,$'سgO7b7og~z?tGuȠ/ȑ#HBс5kּakjq !:t?y>o=S+V, Y!ܣOv%222^\4m~ fyڴi˗/_^fiR١޽{ r ?oNeed help?

Open an issue in the issue tracker.

python-msgspec-0.19.0/docs/source/api.rst000066400000000000000000000055571473355726200203460ustar00rootroot00000000000000API Docs ======== Structs ------- .. currentmodule:: msgspec .. autoclass:: Struct .. autofunction:: field .. autofunction:: defstruct .. autofunction:: msgspec.structs.replace .. autofunction:: msgspec.structs.asdict .. autofunction:: msgspec.structs.astuple .. autofunction:: msgspec.structs.force_setattr .. autofunction:: msgspec.structs.fields .. autoclass:: msgspec.structs.FieldInfo .. autoclass:: msgspec.structs.StructConfig .. autodata:: NODEFAULT :no-value: Meta ---- .. autoclass:: Meta :members: Raw --- .. currentmodule:: msgspec .. autoclass:: Raw :members: Unset ----- .. autodata:: UNSET :no-value: .. autoclass:: UnsetType JSON ---- .. currentmodule:: msgspec.json .. autoclass:: Encoder :members: encode, encode_lines, encode_into .. autoclass:: Decoder :members: decode, decode_lines .. autofunction:: encode .. autofunction:: decode .. autofunction:: format MessagePack ----------- .. currentmodule:: msgspec.msgpack .. autoclass:: Encoder :members: encode, encode_into .. autoclass:: Decoder :members: decode .. autoclass:: Ext :members: .. autofunction:: encode .. autofunction:: decode YAML ---- .. currentmodule:: msgspec.yaml .. autofunction:: encode .. autofunction:: decode TOML ---- .. currentmodule:: msgspec.toml .. autofunction:: encode .. autofunction:: decode JSON Schema ----------- .. currentmodule:: msgspec.json .. autofunction:: schema .. autofunction:: schema_components .. _inspect-api: Converters ---------- .. currentmodule:: msgspec .. autofunction:: convert .. autofunction:: to_builtins Inspect ------- .. currentmodule:: msgspec.inspect .. autofunction:: type_info .. autofunction:: multi_type_info .. autoclass:: Type .. autoclass:: Metadata .. autoclass:: AnyType .. autoclass:: NoneType .. autoclass:: BoolType .. autoclass:: IntType .. autoclass:: FloatType .. autoclass:: StrType .. autoclass:: BytesType .. autoclass:: ByteArrayType .. autoclass:: MemoryViewType .. autoclass:: DateTimeType .. autoclass:: TimeType .. autoclass:: DateType .. autoclass:: TimeDeltaType .. autoclass:: UUIDType .. autoclass:: DecimalType .. autoclass:: ExtType .. autoclass:: RawType .. autoclass:: EnumType .. autoclass:: LiteralType .. autoclass:: CustomType .. autoclass:: UnionType :members: .. autoclass:: CollectionType .. autoclass:: ListType .. autoclass:: SetType .. autoclass:: FrozenSetType .. autoclass:: VarTupleType .. autoclass:: TupleType .. autoclass:: DictType .. autoclass:: Field .. autoclass:: TypedDictType .. autoclass:: NamedTupleType .. autoclass:: DataclassType .. autoclass:: StructType Exceptions ---------- .. currentmodule:: msgspec .. autoexception:: MsgspecError :show-inheritance: .. autoexception:: EncodeError :show-inheritance: .. autoexception:: DecodeError :show-inheritance: .. autoexception:: ValidationError :show-inheritance: python-msgspec-0.19.0/docs/source/benchmarks.rst000066400000000000000000000536401473355726200217060ustar00rootroot00000000000000Benchmarks ========== .. note:: Benchmarks are *hard*. Repeatedly calling the same function in a tight loop will lead to the instruction cache staying hot and branches being highly predictable. That's not representative of real world access patterns. It's also hard to write a nonbiased benchmark. I wrote msgspec, naturally whatever benchmark I publish it's going to perform well in. Even so, people like to see benchmarks. I've tried to be as nonbiased as I can be, and the results hopefully indicate a few tradeoffs you make when you choose different serialization formats. I encourage you to write your own benchmarks before making these decisions. In all cases benchmarks were run on my local development machine (a ~2020 x86 Linux laptop) using CPython 3.11. JSON Serialization & Validation ------------------------------- This benchmark covers the common case when working with ``msgspec`` or other validation libraries. It measures two things: - Decoding some JSON input, validating it against a schema, and converting it into user-friendly python objects. - Encoding these same python objects back into JSON. The data we're working with has the following schema (defined here using `msgspec.Struct` types): .. code-block:: python import enum import datetime import msgspec class Permissions(enum.Enum): READ = "READ" WRITE = "WRITE" READ_WRITE = "READ_WRITE" class File(msgspec.Struct, kw_only=True, tag="file"): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None nbytes: int permissions: Permissions class Directory(msgspec.Struct, kw_only=True, tag="directory"): name: str created_by: str created_at: datetime.datetime updated_by: str | None = None updated_at: datetime.datetime | None = None contents: list[File | Directory] The libraries we're comparing are the following: - msgspec_ (0.18.5) - mashumaro_ (3.11) - pydantic_ (both 1.10.13 and 2.5.2) - cattrs_ (23.2.3) Each benchmark creates a message containing one or more ``File``/``Directory`` instances, then then serializes, deserializes, and validates it in a loop. The full benchmark source can be found `here `__. .. raw:: html
In this benchmark ``msgspec`` is ~6x faster than ``mashumaro``, ~10x faster than ``cattrs``, and ~12x faster than ``pydantic`` V2, and ~85x faster than ``pydantic`` V1. This plot shows the performance benefit of performing type validation during message decoding (as done by ``msgspec``) rather than as a secondary step with a third-party library like cattrs_ or pydantic_ V1. Validating after decoding is slower for two reasons: - It requires traversing over the entire output structure a second time (which can be slow due to pointer chasing) - It may require converting some python objects to their desired output types (e.g. converting a decoded `dict` to a pydantic_ model), resulting in allocating many temporary python objects. In contrast, libraries like ``msgspec`` that validate during decoding have none of these issues. Only a single pass over the decoded data is taken, and the specified output types are created correctly the first time, avoiding the need for additional unnecessary allocations. This benefit also shows up in the memory usage for the same benchmark: .. raw:: html
Here we compare the peak increase in memory usage (RSS) after loading the schemas and data. ``msgspec``'s small library size, schema representation, and in-memory state means it uses a fraction of the memory of other tools. .. _json-benchmark: JSON Serialization ------------------ ``msgspec`` includes its own high performance JSON library, which may be used by itself as a replacement for the standard library's `json.dumps`/`json.loads` functions. Here we compare msgspec's JSON implementation against several other popular Python JSON libraries. - msgspec_ (0.18.5) - orjson_ (3.9.10) - ujson_ (5.9.0) - rapidjson_ (1.13) - simdjson_ (5.0.2) - json_ (standard library) The full benchmark source can be found `here `__. .. raw:: html
In this case ``msgspec structs`` (which measures ``msgspec`` with ``msgspec.Struct`` schemas pre-defined) is the fastest. When used without schemas, ``msgspec`` is on-par with ``orjson`` (the next fastest JSON library). This shows that ``msgspec`` is able to decode JSON faster when a schema is provided. Due to a more efficient in memory representation, JSON decoding AND schema validation with ``msgspec`` than just JSON decoding alone. .. _msgpack-benchmark: MessagePack Serialization ------------------------- Likewise, ``msgspec`` includes its own high performance MessagePack_ library, which may be used by itself without requiring usage of any of msgspec's validation machinery. Here we compare msgspec's MessagePack implementation against several other popular Python MessagePack libraries. - msgspec_ (0.18.5) - msgpack_ (1.0.7) - ormsgpack_ (1.4.1) .. raw:: html
As with the JSON benchmark above, ``msgspec`` with a schema provided (``msgspec structs``) is faster than ``msgspec`` with no schema. In both cases though ``msgspec`` is measurably faster than other Python MessagePack libraries like ``msgpack`` or ``ormsgpack``. JSON Serialization - Large Data ------------------------------- Here we benchmark loading a `large JSON file `__ (~77 MiB) containing information on all the ``noarch`` packages in conda-forge_. We compare the following libraries: - msgspec_ (0.18.5) - orjson_ (3.9.10) - ujson_ (5.9.0) - rapidjson_ (1.13) - simdjson_ (5.0.2) - json_ (standard library) For each library, we measure both the peak increase in memory usage (RSS) and the time to JSON decode the file. The full benchmark source can be found `here `__. **Results (smaller is better):** +---------------------+--------------+------+-----------+------+ | | memory (MiB) | vs. | time (ms) | vs. | +=====================+==============+======+===========+======+ | **msgspec structs** | 67.6 | 1.0x | 176.8 | 1.0x | +---------------------+--------------+------+-----------+------+ | **msgspec** | 218.3 | 3.2x | 630.5 | 3.6x | +---------------------+--------------+------+-----------+------+ | **json** | 295.0 | 4.4x | 868.6 | 4.9x | +---------------------+--------------+------+-----------+------+ | **ujson** | 349.1 | 5.2x | 1087.0 | 6.1x | +---------------------+--------------+------+-----------+------+ | **rapidjson** | 375.0 | 5.6x | 1004.0 | 5.7x | +---------------------+--------------+------+-----------+------+ | **orjson** | 406.3 | 6.0x | 691.7 | 3.9x | +---------------------+--------------+------+-----------+------+ | **simdjson** | 603.2 | 8.9x | 1053.0 | 6.0x | +---------------------+--------------+------+-----------+------+ - ``msgspec`` decoding into :doc:`Struct ` types uses the least amount of memory, and is also the fastest to decode. This makes sense; ``Struct`` types are cheaper to allocate and more memory efficient than ``dict`` types, and for large messages these differences can really add up. - ``msgspec`` decoding without a schema is the second best option for both memory usage and speed. When decoding without a schema, ``msgspec`` makes the assumption that the underlying message probably still has some structure; short dict keys are temporarily cached to be reused later on, rather than reallocated every time. This means that instead of allocating 10,000 copies of the string ``"name"``, only a single copy is allocated and reused. For large messages this can lead to significant memory savings. ``json`` and ``orjson`` also use similar optimizations, but not as effectively. - ``orjson`` and ``simdjson`` use 6-9x more memory than ``msgspec`` in this benchmark. In addition to the reasons above, both of these decoders require copying the original message into a temporary buffer. In this case, the extra copy adds an extra 77 MiB of overhead! .. _struct-benchmark: Structs ------- Here we benchmark common `msgspec.Struct` operations, comparing their performance against other similar libraries. The cases compared are: - Standard Python classes - dataclasses_ - msgspec_ (0.18.5) - attrs_ (23.1.0) - pydantic_ (2.5.2) For each library, the following operations are benchmarked: - Time to define a new class. Many libraries that abstract away class boilerplate add overhead when defining classes, slowing import times for libraries that make use of these classes. - Time to create an instance of that class. - Time to compare two instances for equality (``==``/``!=``). - Time to compare two instances for order (``<``/``>``/``<=``/``>=``) The full benchmark source can be found `here `__. **Results (smaller is better):** +----------------------+-------------+-------------+---------------+------------+ | | import (μs) | create (μs) | equality (μs) | order (μs) | +======================+=============+=============+===============+============+ | **msgspec** | 12.51 | 0.09 | 0.02 | 0.03 | +----------------------+-------------+-------------+---------------+------------+ | **standard classes** | 7.88 | 0.35 | 0.08 | 0.16 | +----------------------+-------------+-------------+---------------+------------+ | **attrs** | 483.10 | 0.37 | 0.14 | 1.87 | +----------------------+-------------+-------------+---------------+------------+ | **dataclasses** | 506.09 | 0.36 | 0.14 | 0.16 | +----------------------+-------------+-------------+---------------+------------+ | **pydantic** | 673.47 | 1.54 | 0.60 | N/A | +----------------------+-------------+-------------+---------------+------------+ - Standard Python classes are the fastest to import (any library can only add overhead here). Still, ``msgspec`` isn't *that* much slower, especially compared to other options. - Structs are optimized to be cheap to create, and that shows for the creation benchmark. They're roughly 4x faster than standard classes/``attrs``/``dataclasses``, and 17x faster than ``pydantic``. - For equality comparison, msgspec Structs are roughly 4x to 30x faster than the alternatives. - For order comparison, msgspec Structs are roughly 5x to 60x faster than the alternatives. .. _struct-gc-benchmark: Garbage Collection ------------------ `msgspec.Struct` instances implement several optimizations for reducing garbage collection (GC) pressure and decreasing memory usage. Here we benchmark structs (with and without :ref:`gc=False `) against standard Python classes (with and without `__slots__ `__). For each option we create a large dictionary containing many simple instances of the benchmarked type, then measure: - The amount of time it takes to do a full garbage collection (gc) pass - The total amount of memory used by this data structure The full benchmark source can be found `here `__. **Results (smaller is better):** +-----------------------------------+--------------+-------------------+ | | GC time (ms) | Memory Used (MiB) | +===================================+==============+===================+ | **standard class** | 80.46 | 211.66 | +-----------------------------------+--------------+-------------------+ | **standard class with __slots__** | 80.06 | 120.11 | +-----------------------------------+--------------+-------------------+ | **msgspec struct** | 13.96 | 120.11 | +-----------------------------------+--------------+-------------------+ | **msgspec struct with gc=False** | 1.07 | 104.85 | +-----------------------------------+--------------+-------------------+ - Standard Python classes are the most memory hungry (since all data is stored in an instance dict). They also result in the largest GC pause, as the GC has to traverse the entire outer dict, each class instance, and each instance dict. All that pointer chasing has a cost. - Standard classes with ``__slots__`` are less memory hungry, but still results in an equivalent GC pauses. - `msgspec.Struct` instances have the same memory layout as a class with ``__slots__`` (and thus have the same memory usage), but due to deferred GC tracking a full GC pass completes in a fraction of the time. - `msgspec.Struct` instances with ``gc=False`` have the lowest memory usage (lack of GC reduces memory by 16 bytes per instance). They also have the lowest GC pause (75x faster than standard classes!) since the entire composing dict can be skipped during GC traversal. .. _benchmark-library-size: Library Size ------------ Here we compare the on-disk size of ``msgspec`` and ``pydantic``, its closest equivalent. The full benchmark source can be found `here `__. **Results (smaller is better)** +--------------+---------+------------+-------------+ | | version | size (MiB) | vs. msgspec | +==============+=========+============+=============+ | **msgspec** | 0.18.4 | 0.46 | 1.00x | +--------------+---------+------------+-------------+ | **pydantic** | 2.5.2 | 6.71 | 14.66x | +--------------+---------+------------+-------------+ For applications where dependency size matters, ``msgspec`` is roughly 15x smaller on disk. .. raw:: html .. raw:: html .. _msgspec: https://jcristharif.com/msgspec/ .. _msgpack: https://github.com/msgpack/msgpack-python .. _ormsgpack: https://github.com/aviramha/ormsgpack .. _MessagePack: https://msgpack.org .. _orjson: https://github.com/ijl/orjson .. _json: https://docs.python.org/3/library/json.html .. _simdjson: https://github.com/TkTech/pysimdjson .. _ujson: https://github.com/ultrajson/ultrajson .. _rapidjson: https://github.com/python-rapidjson/python-rapidjson .. _attrs: https://www.attrs.org .. _dataclasses: https://docs.python.org/3/library/dataclasses.html .. _pydantic: https://pydantic-docs.helpmanual.io/ .. _cattrs: https://catt.rs/en/latest/ .. _mashumaro: https://github.com/Fatal1ty/mashumaro .. _conda-forge: https://conda-forge.org/ python-msgspec-0.19.0/docs/source/changelog.rst000066400000000000000000000632421473355726200215170ustar00rootroot00000000000000Changelog ========= .. currentmodule:: msgspec Version 0.19.0 (2024-12-27) --------------------------- - Improve JSON encoding performance by up to 40% (:pr:`647`). - Ensure `tuple` and `frozenset` default values are treated identically whether specified by value or ``default_factory`` (:pr:`653`). - Fix memory leak of ``match_args`` in ``StructConfig`` object (:pr:`684`). - Fix memory leak in ``Raw.copy()`` (:pr:`709`). - Update ``decode`` signatures for PEP 688 (:pr:`740`). - Generate ``__replace__`` method on ``Struct`` types, for use with `copy.replace` (:pr:`747`). - Fix incorrect decoding of certain > 64 bit integers (:pr:`751`). - Call ``__post_init__`` when converting from an object to a Struct (:pr:`752`). - **BREAKING**: Expand buffer when ``encode_into`` is passed a buffer smaller than ``offset`` (:pr:`753`). - Support `Raw` objects as inputs to `convert` (:pr:`754`). - Error nicely when a dataclass *type* (instead of an *instance*) is passed to ``encode`` (:pr:`755`). - Drop support for Python 3.8 (:pr:`756`, :pr:`763`). - Add support for Python 3.13 (:pr:`711`). - Remove deprecated ``from_builtins`` (:pr:`761`). - Support encoding any ``Enum`` type whose ``.value`` is a supported type (:pr:`757`). - Don't fail eagerly when processing generic types with unsupported ``__parameters__`` (:pr:`772`). - Use ``eval_type_backport`` to backport type annotations to Python 3.9 (:pr:`773`). Version 0.18.6 (2024-01-21) --------------------------- - Support coercing integral floats to ints when ``strict=False`` (:pr:`619`). - Preserve leading ``_`` when renaming fields to camel or pascal case (:pr:`620`). - Support zero-copy decoding binary fields to a ``memoryview`` (:pr:`624`). - Fix a bug when inheriting from the same ``Generic`` base class multiple times (:pr:`626`). - Add an ``order`` option to all encoders for enforcing deterministic/sorted ordering when encoding. This can help provide a more consistent or human readable output (:pr:`627`). - Support inheriting from any slots-class when defining a new ``Struct`` type with ``gc=False`` (:pr:`635`). - Automatically infer the input field naming convention when converting non-dict mappings or arbitrary objects to ``Struct`` types in ``msgspec.convert`` (:pr:`636`). Version 0.18.5 (2023-12-12) --------------------------- - Support unhashable ``Annotated`` metadata in `msgspec.inspect.type_info` (:pr:`566`). - Fix bug preventing decoding dataclasses/attrs types with default values and ``slots=True, frozen=True`` (:pr:`569`). - Support passing parametrized generic struct types to `msgspec.structs.fields` (:pr:`571`). - Validate ``str`` constraints on dict keys when decoding msgpack (:pr:`577`). - Support ``UUID`` subclasses as inputs to `msgspec.convert` (:pr:`592`). - Call ``__eq__`` from generated ``__ne__`` if user defines manual ``__eq__`` method on a ``Struct`` type (:pr:`593`). - Include the ``Struct`` type in the generated hash (:pr:`595`). - Add a ``cache_hash`` struct option (:pr:`596`). - Fix a bug around caching of dataclass type info when dealing with subclasses of dataclasses (:pr:`599`). - Add `msgspec.structs.force_setattr` (:pr:`600`). - Support custom dict key types in JSON encoder and decoder (:pr:`602`). - Include ``dict`` key constraints in generated JSON schema via the ``propertyNames`` field (:pr:`604`). - Add a ``schema_hook`` for generating JSON schemas for custom types (:pr:`605`). - Add support for Python 3.12's ``type`` aliases (:pr:`606`). Version 0.18.4 (2023-10-04) --------------------------- - Resolve an issue leading to periodic segfaults when importing ``msgspec`` on CPython 3.12 (:pr:`561`) Version 0.18.3 (2023-10-03) --------------------------- - Improve type annotation for ``Struct.__rich_repr__`` (:pr:`557`) - Add pre-built wheels for Python 3.12 (:pr:`558`) Version 0.18.2 (2023-08-26) --------------------------- - Support ``Enum._missing_`` hooks for handling unknown enum values (:pr:`532`). - Fix JSON encoding of `datetime.datetime` objects with `zoneinfo.ZoneInfo` timezone components (:pr:`534`). - Add support for ``attrs`` `validators `__ (:pr:`538`). - Relax datetime/time parsing format to allow some RFC3339 extensions from ISO8601 (:pr:`539`). Version 0.18.1 (2023-08-16) --------------------------- - Support custom ``builtin_types`` in `msgspec.to_builtins` (:pr:`517`). - Try ``getattr`` before ``getitem`` when converting with ``from_attributes=True`` (:pr:`519`). - More efficient module state access in top-level functions (:pr:`521`). Version 0.18.0 (2023-08-10) --------------------------- - Add a new `msgspec.json.Decoder.decode_lines` method for decoding newline-delimited JSON into a list of values (:pr:`485`). - Support for decoding UUIDs from binary values (:pr:`499`). - Support for encoding UUIDs in alternate formats (:pr:`499`). - Overhaul how dataclasses are encoded to support more dataclass-like objects (:pr:`501`). - Encode all declared fields on a dataclass (:pr:`501`). - Support encoding ``edgedb.Object`` instances as dataclass-like objects (:pr:`501`). - Improve performance when json decoding ``float`` values (:pr:`510`). - Support for JSON encoding dicts with ``float`` keys (:pr:`510`). - Support for JSON decoding dicts with ``float`` keys (:pr:`510`). - Add ``float_hook`` to `msgspec.json.Decoder` to support changing the default for how JSON floats are decoded (:pr:`511`). Version 0.17.0 (2023-07-11) --------------------------- - Ensure ``None`` may be explicitly passed to `defstruct` for ``module``/``namespace``/``bases`` (:pr:`445`). - Support decoding `datetime.datetime` values from ``int``/``float`` values (interpreted as seconds since the Unix epoch) when ``strict=False`` (:pr:`452`). - Support subclasses of collection types (``list``, ``dict``, ...) as inputs to `convert` (:pr:`453`). - Support ``str`` subclasses as keys in `to_builtins` and all protocol ``encode`` methods (:pr:`454`). - Improved performance when JSON encoding `decimal.Decimal` values (:pr:`455`). - Improved performance when JSON encoding ``int``/``float`` values (:pr:`458`). - Improved performance when JSON encoding ``str`` values (:pr:`459`). - Wrap errors in ``dec_hook`` with a `ValidationError` (:pr:`460`). - Support decoding `decimal.Decimal` values from numeric values (:pr:`463`) - Support encoding `decimal.Decimal` values as numeric values (:pr:`465`). - Support converting `decimal.Decimal` values to ``float`` in `convert` (:pr:`466`). - Preliminary support for CPython 3.12 beta releases (:pr:`467`). - Support decoding integers that don't fit into an ``int64``/``uint64`` (:pr:`469`). - Add a new optional ``__post_init__`` method for `Struct` types (:pr:`470`). - Support decoding ``0``/``1`` into ``bool`` types when ``strict=False`` (:pr:`471`). - Wrap errors raised in ``__post_init__``/``__attrs_post_init__`` in a `ValidationError` when decoding (:pr:`472`). - Add native support for encoding/decoding `datetime.timedelta` types (:pr:`475`). - Add a new `msgspec.json.Encoder.encode_lines` method for encoding an iterable of values as newline-delimited JSON (:pr:`479`). Version 0.16.0 (2023-06-12) --------------------------- - Deprecate ``msgspec.from_builtins`` in favor of `msgspec.convert`. The new ``convert`` function provides a superset of the functionality available in the old ``from_builtins`` function (:pr:`431`). - Add a ``from_attributes`` argument to `msgspec.convert` for allowing conversion between object types with matching attribute names. One use case for this is converting ORM objects to `Struct` or `dataclasses` types (:pr:`419`). - Support passing generic ``Mapping`` objects as inputs to `msgspec.convert`. These may be coerced to `dict`/`Struct`/`dataclasses`/`attrs` types (:pr:`427`). - Add a new ``strict`` keyword argument to all ``decode`` functions, ``Decoder`` classes, as well as `msgspec.convert`. This defaults to ``True``, setting it to false enables a wider set of coercion rules (e.g. coercing a `str` input to an `int`). See :ref:`strict-vs-lax` for more information (:pr:`434`). - Support all :doc:`supported-types` as inputs to `msgspec.convert` (:pr:`431`, :pr:`418`). - Passthrough input unchanged when coercing to `typing.Any` type in `msgspec.convert` (:pr:`435`). - Support parametrizing ``Decoder`` types at runtime (:pr:`415`). - Support encoding subclasses of ``UUID`` (:pr:`429`). Version 0.15.1 (2023-05-19) --------------------------- - Fix a reference counting bug introduced in 0.15.0 when decoding naive (no timezone) ``datetime``/``time`` objects in both the ``msgpack`` and ``json`` decoders (:pr:`409`). - Work around an upstream bug in CPython to properly support `typing.Required`/`typing.NotRequired` in `typing.TypedDict` when ``__future__.annotations`` is enabled (:pr:`410`). Version 0.15.0 (2023-05-10) --------------------------- - Add support for Generic `Struct` types (:pr:`386`, :pr:`393`). - Add support for Generic `dataclasses` and `attrs `__ types (:pr:`396`). - Add support for Generic `typing.TypedDict` and `typing.NamedTuple` types (:pr:`398`). - **BREAKING**: No longer normalize timezones to UTC when decoding `datetime` objects from JSON (:pr:`391`). - Support decoding unhyphenated UUIDs (:pr:`392`). - A few type annotation fixups (:pr:`383`, :pr:`387`). - Dedent docstrings for descriptions when generating JSON schemas (:pr:`397`). - Use a variant of ``__qualname__`` when auto-generating Struct tags rather than ``__name__`` (:pr:`399`). - Fix bug when handling `typing.Literal` types containing a literal ``None`` (:pr:`400`). - Make all ``Encoder``/``Decoder`` methods threadsafe (:pr:`402`). - **BREAKING**: Drop the ``write_buffer_size`` kwarg to ``Encoder`` (:pr:`402`). Version 0.14.2 (2023-04-19) --------------------------- - Remove ``__del__`` trashcan usage for structs with ``gc=False`` (:pr:`369`). - Support overriding ``__setattr__`` in Struct types (:pr:`376`). - Support encoding large integers in JSON (:pr:`378`). - Fix a memory leak when msgpack decoding variable length tuples with more than 16 elements (:pr:`380`). - Remove JSON compatibility checks when constructing a ``msgspec.json.Decoder``. Trying to decode messages into types that JSON doesn't support will now error at decode time, rather than when the decoder is constructed (:pr:`381`). Version 0.14.1 (2023-04-07) --------------------------- - Further optimize decoding of JSON arrays into lists (:pr:`363`). - Fix a bug preventing using structs configured with ``dict=True`` on Python 3.11 (:pr:`365`). - Avoid preallocating large lists/tuples in the msgpack decoder (:pr:`367`). Version 0.14.0 (2023-04-02) --------------------------- - Support encoding and decoding `attrs `__ types (:pr:`323`). - Add ``repr_omit_defaults`` configuration option for omitting struct default values in the ``repr`` (:pr:`322`). - Expose a struct's configuration through a ``__struct_config__`` attribute (:pr:`328`). - Add `msgspec.structs.fields` utility function for inspecting the fields configured on a Struct (:pr:`330`). - Add a ``dict`` configuration option for adding a ``__dict__`` attribute to a Struct (:pr:`331`). - Allow non-struct mixins to be used with struct types (:pr:`332`). - Fix a bug when defining both ``lt`` and ``gt`` constraints on an integer type (:pr:`335`). - Fix a bug supporting fields defined with `msgspec.field()` with no arguments (:pr:`343`). - Allow arbitrary input types to `msgspec.from_builtins` (:pr:`346`). - Support decoding into subclasses of ``int`` & ``bytes`` in `msgspec.from_builtins` (:pr:`346`). - Add `msgspec.UNSET` and `msgspec.UnsetType` for tracking unset fields. See the :ref:`docs ` for more information (:pr:`350`). - **BREAKING**: In the unlikely event you were using the previous ``msgspec.UNSET`` singleton to explicitly indicate no default value on struct types, you should now make use of `msgspec.NODEFAULT` instead (:pr:`350`). - Improve struct type annotations now that ``mypy`` supports `typing.dataclass_transform` (:pr:`352`). - Support `typing.Final` annotations for indicating that an object field should be treated as immutable (:pr:`354`). - Add a ``name`` keyword option to `msgspec.field` for renaming a single field (:pr:`356`). - **BREAKING**: The rules around class inheritance and a struct's ``rename`` option have changed. See :pr:`356` for more information. Version 0.13.1 (2023-02-09) --------------------------- - Fix a memory leak in the JSON decoder introduced in 0.13.0, caused by a reference counting bug when decoding into ``Struct`` types (:pr:`312`). Version 0.13.0 (2023-02-08) --------------------------- - Add `to_builtins` function for converting messages composed of any supported type to ones composed of only simple builtin types commonly supported by Python serialization libraries (:pr:`258`). - Add `from_builtins` function for converting and validating messages composed of simple builtin types to ones composed of any type msgspec supports (:pr:`266`, :pr:`302`). - Add `msgspec.yaml` module for encoding/decoding YAML (:pr:`267`). - Add `msgspec.toml` module for encoding/decoding TOML (:pr:`268`). - Add `msgspec.structs.replace` function for creating a copy of an existing `Struct` with some changes applied (:pr:`262`). - Add `msgspec.structs.asdict` and `msgspec.structs.astuple` functions for converting a struct instance to a `dict` or `tuple` respectively (:pr:`300`). - Support arbitrarily nested `typing.NewType`/`typing.Annotated` types (:pr:`272`). - Improve error message for invalid keyword arguments passed to ``Struct.__init__`` (:pr:`273`). - Support ``default_factory`` configuration for `Struct` fields (:pr:`274`). - **BREAKING**: With the exception of empty builtin collections (``[]``, ``{}``, ``set()``, ``bytearray()``), mutable default values in Struct types are no longer deepcopied when used. If a different mutable default value is needed, please configure a ``default_factory`` instead (:pr:`274`). - Improve performance of creating Structs with default parameters (:pr:`274`). - Support `typing.ClassVar` annotations of `Struct` types (:pr:`281`). - Support encoding/decoding `decimal.Decimal` types (:pr:`288`). - Support "abstract" type annotations like `collections.abc.MutableMapping`/`typing.MutableMapping` in decoders (:pr:`290`). - Support any string-like or int-like type as a ``dict`` key when encoding or decoding JSON (:pr:`292`). - Improved performance encoding large collections in JSON and MessagePack encoders (:pr:`294`, :pr:`298`). Version 0.12.0 (2023-01-05) --------------------------- - Support encoding ``set`` and ``frozenset`` subclasses (:pr:`249`). - Support encoding/decoding `typing.NewType` types (:pr:`251`). - Allow creating a `msgspec.Raw` object from a ``str`` (:pr:`252`). - Add new experimental ``msgspec.inspect`` module for inspecting type annotations. This is intended to be used for building downstream tooling based on msgspec-compatible types. See :doc:`the docs ` for more information (:pr:`253`). - Add new ``extra`` field to `msgspec.Meta`, for storing arbitrary user-defined metadata (:pr:`255`). - Improved performance for JSON encoding strings (:pr:`256`). Version 0.11.0 (2022-12-19) --------------------------- - Improve performance of constructors for `Struct` types when using keyword arguments (:pr:`237`). - Support :doc:`constraints` on dict keys for JSON (:pr:`239`). - Add support for keyword-only arguments in `Struct` types, matching the behavior of ``kw_only`` for `dataclasses` (:pr:`242`). - **BREAKING**: Change the parameter ordering rules used by `Struct` types to match the behavior of `dataclasses`. For most users this change shouldn't break anything. However, if your struct definitions have required fields after optional fields, you'll now get an error on import. This error can be fixed by either: - Reordering your fields so all required fields are before all optional fields - Using keyword-only parameters (by passing the ``kw_only=True`` option). See :ref:`struct-field-ordering` for more information (:pr:`242`). - Support encoding/decoding dictionaries with integer keys for JSON (:pr:`243`). Version 0.10.1 (2022-12-08) --------------------------- - Ignore attributes with leading underscores (``"_"``) when encoding `dataclasses` (:pr:`234`) Version 0.10.0 (2022-12-07) --------------------------- - Add ``forbid_unknown_fields`` configuration option to `Struct` types (:pr:`210`) - **BREAKING**: Encode all `enum` types by value, rather than name (:pr:`211`) - Fix a bug in the JSON encoder when base64 encoding binary objects (:pr:`217`) - Add support for encoding/decoding `dataclasses` (:pr:`218`) - Add support for encoding/decoding `datetime.date` objects (:pr:`221`) - Add support for encoding/decoding `uuid.UUID` objects (:pr:`222`) - **BREAKING**: support encoding/decoding `datetime.datetime` values without timezones by default (:pr:`224`). - Add a ``tz`` :doc:`constraint ` to require aware or naive datetime/time objects when decoding (:pr:`224`). - Add support for encoding/decoding `datetime.time` objects (:pr:`225`) - Add a `msgspec.json.format` utility for efficiently pretty-printing already encoded JSON documents (:pr:`226`). - Support decoding JSON from strings instead of just bytes-like objects (:pr:`229`) Version 0.9.1 (2022-10-27) -------------------------- - Enable Python 3.11 builds (:pr:`205`) - Support greater than microsecond resolution when parsing JSON timestamps (:pr:`201`) - Work around a limitation in mypy for typed decoders (:pr:`191`) Version 0.9.0 (2022-09-13) -------------------------- - Support for :doc:`constraints ` during validation. For example, this allows ensuring a field is an integer >= 0. (:pr:`176`) - New utilities for generating :doc:`JSON Schemas ` from type definitions (:pr:`181`) - Support for pretty printing using `rich `_ (:pr:`183`) - Improve integer encoding performance (:pr:`170`) - Builtin support for renaming fields using kebab-case (:pr:`175`) - Support for passing a mapping when renaming fields (:pr:`185`) Version 0.8.0 (2022-08-01) -------------------------- - Support integer tag values when using :ref:`tagged unions ` (:pr:`135`). - Support decoding into `typing.TypedDict` types (:pr:`142`). - Support encoding/decoding `typing.NamedTuple` types (:pr:`161`). - Test against CPython 3.11 prelease builds (:pr:`146`). - Add `ValidationError` (a subclass of `DecodeError`) to allow differentiating between errors due to a message not matching the schema from those due to the message being invalid JSON (:pr:`155`). - Support encoding subclasses of `list`/`dict` (:pr:`160`). - Fix a bug preventing decoding custom types wrapped in a `typing.Optional` (:pr:`162`). Version 0.7.1 (2022-06-27) -------------------------- - Further reduce the size of packaged wheels (:pr:`130`). - Add `weakref` support for `Struct` types through a new ``weakref`` configuration option (:pr:`131`). - Fix a couple unlikely (but possible) bugs in the deallocation routine for Struct types (:pr:`131`). Version 0.7.0 (2022-06-20) -------------------------- - Dramatically speedup JSON string decoding, up to 2x speedup in some cases (:pr:`118`). - Adds a cache for decoding short (< 32 character) ASCII dict keys. This results in up to a 40% speedup when decoding many dicts with common keys using an untyped decoder. It's still recommended to define `Struct` types when your messages have a common structure, but in cases where no type is provided decoding is now much more performant (:pr:`120`, :pr:`121`). - Adds ``order`` and ``eq`` configuration options for `Struct` types, mirroring the ``dataclasses`` options of the same name. Order comparisons for Struct types are very performant, roughly `10x to 70x faster `__ than alternative libraries (:pr:`122`). - Speedup `Struct` decoding for both JSON and MessagePack, on average 20% faster (:pr:`119`). - Various additional performance improvements, mostly to the JSON implementation (:pr:`100`, :pr:`101`, :pr:`102`). - Add `defstruct` method for dynamically defining new `Struct` types at runtime (:pr:`105`). - Fix ARM support and publish ARM wheels for Linux and Mac (:pr:`104`). - Reduce published wheel sizes by stripping debug symbols (:pr:`113`). - Fix a memory leak in ``Struct.__reduce__`` (:pr:`117`). - **BREAKING**: Rename ``nogc`` struct option to ``gc``. To disable GC on a Struct instance you now want to specify ``gc=False`` instead of ``nogc=True`` (:pr:`124`). Version 0.6.0 (2022-04-06) -------------------------- - Add a new `msgspec.Raw `__ type for delayed decoding of message fields / serializing already encoded fields (:pr:`92`). - Add ``omit_defaults`` option to ``Struct`` types (`docs `__). If enabled, fields containing their respective default value will be omitted from serialized message. This improves both encode and decode performance (:pr:`94`). - Add ``rename`` option to ``Struct`` types (`docs `__) for altering the field names used for encoding. A major use of this is supporting ``camelCase`` JSON field names, while letting Python code use the more standard ``snake_case`` field names (:pr:`98`). - Improve performance of ``nogc=True`` structs (`docs `__). GC is now avoided in more cases, and ``nogc=True`` structs use 16 fewer bytes per instance. Also added a `benchmark `__ for how ``msgspec`` can interact with application GC usage (:pr:`93`). - Cache creation of `tagged union `__ lookup tables, reducing memory usage for applications making heavy use of tagged unions (:pr:`91`). - Support encoding and decoding ``frozenset`` instances (:pr:`95`). - A smattering of other performance improvements. Version 0.5.0 (2022-03-09) -------------------------- - Support `tagged unions `__ for encoding/decoding a ``Union`` of ``msgspec.Struct`` types (:pr:`83`). - Further improve encoding performance of ``enum.Enum`` instances by 20-30% (:pr:`84`). - Reduce overhead of calling ``msgspec.json.decode``/``msgspec.msgpack.decode`` with ``type=SomeStructType``. It's still faster to create a ``Decoder`` once and call ``decoder.decode`` multiple times, but for struct types the overhead of calling the top-level function is decreased significantly (:pr:`77`, :pr:`88`). - **BREAKING**: Rename the Struct option ``asarray`` to ``array_like`` (:pr:`85`). Version 0.4.2 (2022-02-28) -------------------------- - Support ``typing.Literal`` string types as dict keys in JSON (:pr:`78`). - Support Python 3.10 style unions (for example, ``int | float | None``) (:pr:`75`). - Publish Python 3.10 wheels (:pr:`80`). Version 0.4.1 (2022-02-23) -------------------------- - Optimize decoding of ``Enum`` types, on average ~10x faster (:pr:`69`). - Optimize decoding of ``IntEnum`` types, on average ~12x faster (:pr:`68`). - Support decoding ``typing.Literal`` types (:pr:`71`). - Add ``nogc`` option for ``Struct`` types, disabling the cyclic garbage collector for their instances (:pr:`72`). Version 0.4.0 (2022-02-08) -------------------------- - Moved MessagePack support to the ``msgspec.msgpack`` submodule (:pr:`56`). - New JSON support available in ``msgspec.json`` (:pr:`56`). - Improved error message generation to provide full path to the mistyped values (:pr:`56`). - Renamed the ``immutable`` kwarg in ``msgspec.Struct`` to ``frozen`` to better match python conventions (:pr:`60`). - Renamed ``EncodingError`` to ``EncodeError``/``DecodingError`` to ``DecodeError`` to better match python conventions (:pr:`61`). - Improved ``pyright`` support, allowing more errors to be statically caught by their type checker (:pr:`60`). - Adds support for Python 3.10 pattern matching on ``msgspec.Struct`` types (:pr:`53`). - Adds support for decoding into ``typing.Union`` types (with a few restrictions) (:pr:`54`). - General performance improvements across all encoders/decoders. Version 0.3.2 (2021-07-23) -------------------------- - Faster float encoding and decoding (:pr:`47`). - General micro-optimizations for MessagePack encode/decode. This is most visible for large messages (:pr:`48`, :pr:`50`). Version 0.3.1 (2021-07-12) -------------------------- - Use a freelist for small structs to improve struct allocation time (:pr:`44`). - Small performance improvements for struct serialization (:pr:`45`). Version 0.3.0 (2021-07-07) -------------------------- - Add ``Encoder.encode_into`` api, for encoding into an existing buffer without copying (:pr:`34`). - Add support for encoding/decoding MessagePack extensions (:pr:`31`). - Add support for encoding/decoding ``datetime`` objects (:pr:`36`). - Add support for encoding/decoding custom objects without relying on MessagePack extensions (:pr:`32`, :pr:`33`). - Add support for marking ``Struct`` types as hashable (:pr:`39`). - Add support for serializing ``Struct`` types as MessagePack ``array`` objects rather than ``map`` objects (:pr:`39`). - Several performance improvements. On average 50% faster encoding and 30% faster decoding. Version 0.2.0 (2021-02-25) -------------------------- - Add ``default`` callback to ``encode``/``Encoder`` (:pr:`21`). - Fix bug in ``Encoder`` dealloc (:pr:`21`). Version 0.1.0 (2021-02-23) -------------------------- - Initial Release python-msgspec-0.19.0/docs/source/conf.py000066400000000000000000000072651473355726200203400ustar00rootroot00000000000000# We want to document both the UNSET singleton, and the UnsetType class, but we # don't want them to have the same docstring. I couldn't find an easy way to # do this in sphinx. For now, we patch the UnsetType object when building types # to override the docstring handling. try: import msgspec class UnsetType: """The type of `UNSET`. See Also -------- UNSET """ msgspec.UnsetType = UnsetType except ImportError: pass project = "msgspec" copyright = "Jim Crist-Harif" author = "Jim Crist-Harif" GITHUB_LOGO = """ """.strip() html_theme = "furo" html_title = "" templates_path = ["_templates"] html_static_path = ["_static"] html_css_files = ["custom.css"] pygments_style = "default" _link_color_light = "#024bb0" _link_color_dark = "#5192d2" html_theme_options = { "light_logo": "msgspec-logo-light.svg", "dark_logo": "msgspec-logo-dark.svg", "light_css_variables": { "color-brand-primary": "black", "color-brand-content": _link_color_light, "color-foreground-muted": "#808080", "color-highlight-on-target": "inherit", "color-highlighted-background": "#ffffcc", "color-sidebar-link-text": "black", "color-sidebar-link-text--top-level": "black", "color-link": _link_color_light, "color-link--hover": _link_color_light, "color-link-underline": "transparent", "color-link-underline--hover": _link_color_light, }, "dark_css_variables": { "color-brand-primary": "#ffffff", "color-brand-content": _link_color_dark, "color-highlight-on-target": "inherit", "color-highlighted-background": "#333300", "color-sidebar-link-text": "#ffffffcc", "color-sidebar-link-text--top-level": "#ffffffcc", "color-link": _link_color_dark, "color-link--hover": _link_color_dark, "color-link-underline": "transparent", "color-link-underline--hover": _link_color_dark, }, "sidebar_hide_name": True, "footer_icons": [ { "name": "GitHub", "url": "https://github.com/jcrist/msgspec", "html": GITHUB_LOGO, "class": "", }, ], } extensions = [ "sphinx.ext.autodoc", "sphinx.ext.napoleon", "sphinx.ext.extlinks", "sphinx.ext.intersphinx", "sphinx_copybutton", "sphinx_design", "IPython.sphinxext.ipython_console_highlighting", ] intersphinx_mapping = { "python": ("https://docs.python.org/3", None), "attrs": ("https://www.attrs.org/en/stable/", None), } autodoc_typehints = "none" napoleon_numpy_docstring = True napoleon_google_docstring = False napoleon_use_rtype = False napoleon_custom_sections = [("Configuration", "params_style")] default_role = "obj" extlinks = { "issue": ("https://github.com/jcrist/msgspec/issues/%s", "Issue #%s"), "pr": ("https://github.com/jcrist/msgspec/pull/%s", "PR #%s"), } copybutton_prompt_text = r">>> |\.\.\. |\$ |In \[\d*\]: | {2,5}\.\.\.: " copybutton_prompt_is_regexp = True python-msgspec-0.19.0/docs/source/constraints.rst000066400000000000000000000167411473355726200221410ustar00rootroot00000000000000Constraints =========== When using :ref:`typed-decoding` ``msgspec`` will ensure decoded messages match the specified types. For example, to decode a list of integers from JSON: .. code-block:: python >>> import msgspec >>> msgspec.json.decode(b"[1, 2, 3]", type=list[int]) [1, 2, 3] >>> msgspec.json.decode(b'[1, 2, "oops"]', type=list[int]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[2]` Often this is sufficient, but sometimes you also need to impose constraints on the *values* (rather than the *types*) found in the message. Constraints in ``msgspec`` are specified by wrapping a type with `typing.Annotated`, and adding a `msgspec.Meta` annotation. For example, to constrain the list to positive integers (``> 0``), you'd make use of the ``gt`` (greater-than) constraint: .. code-block:: python >>> from typing import Annotated >>> PositiveInt = Annotated[int, msgspec.Meta(gt=0)] >>> msgspec.json.decode(b'[1, 2, 3]', type=list[PositiveInt]) [1, 2, 3] >>> msgspec.json.decode(b'[1, 2, -1]', type=list[PositiveInt]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int` >= 1 - at `$[2]` Constraints can be combined to enforce complex requirements. Here's a more complete example enforcing the following constraints on a ``User`` struct: - ``name`` is a ``str`` with ``1 <= length <= 32`` matching the regular expression ``"^[a-z_][a-z0-9_-]*$"``. - ``groups`` is a ``set`` of at most 16 strings, each with the same constraints as ``name`` above, defaulting to the empty ``set``. - ``cpu_limit`` is a ``float`` with a value ``>= 0.1`` and ``<= 8``, defaulting to 1. - ``mem_limit`` is an ``int`` with a value ``>= 256`` and ``<= 8192``, defaulting to 1024. .. code-block:: python from typing import Annotated from msgspec import Struct, Meta UnixName = Annotated[ str, Meta(min_length=1, max_length=32, pattern="^[a-z_][a-z0-9_-]*$") ] class User(Struct): name: UnixName groups: Annotated[set[UnixName], Meta(max_length=16)] = set() cpu_limit: Annotated[float, Meta(ge=0.1, le=8)] = 1 mem_limit: Annotated[int, Meta(ge=256, le=8192)] = 1024 As shown above, ``Annotated`` types can applied inline, or used to create type aliases and then reused elsewhere (as done with ``UnixName``). The following constraints are supported: Numeric Constraints ------------------- These constraints are valid on `int` or `float` types: - ``ge``: The value must be greater than or equal to ``ge``. - ``gt``: The value must be greater than ``gt``. - ``le``: The value must be less than or equal to ``le``. - ``lt``: The value must be less than ``lt``. - ``multiple_of``: The value must be a multiple of ``multiple_of``. .. code-block:: python >>> import msgspec >>> from typing import Annotated >>> msgspec.json.decode(b'-1', type=Annotated[int, msgspec.Meta(ge=0)]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int` >= 0 .. warning:: While ``multiple_of`` works on ``float`` types, we don't recommend specifying *non-integral* ``multiple_of`` constraints, as they may be erroneously marked as invalid due to floating point precision issues. For example, annotating a ``float`` type with ``multiple_of=10`` is fine, but ``multiple_of=0.1`` may lead to issues. See `this GitHub issue `_ for more details. String Constraints ------------------ These constraints are valid on `str` types: - ``min_length``: The minimum valid length, inclusive. - ``max_length``: The maximum valid length, inclusive. - ``pattern``: A regular expression pattern that the value must match. Note that patterns are treated as *unanchored*. This means that the pattern "es" matches not just "es" but also "expression". If required, you must explicitly anchor the pattern by adding a "^" prefix and "$" suffix. For example, the pattern "^es$" only matches the string "es" .. code-block:: python >>> import msgspec >>> from typing import Annotated >>> msgspec.json.decode( ... b'"invalid username"', ... type=Annotated[str, msgspec.Meta(pattern="^[a-z0-9_]*$")] ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str` matching regex '^[a-z0-9_]*$' .. _datetime-constraints: Datetime Constraints -------------------- These constraints are valid on `datetime.datetime` and `datetime.time` types: - ``tz``: Whether the annotated type is required to be timezone-aware_. Set to ``True`` to require timezone-aware values, or ``False`` to require timezone-naive values. The default is ``None``, which accepts either timezone-aware or timezone-naive values. .. code-block:: python >>> import msgspec >>> from datetime import datetime >>> from typing import Annotated >>> msgspec.json.decode( ... b'"2022-04-02T18:18:10"', ... type=Annotated[datetime, msgspec.Meta(tz=True)] # require timezone aware ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `datetime` with a timezone component >>> msgspec.json.decode( ... b'"2022-04-02T18:18:10-06:00"', ... type=Annotated[datetime, msgspec.Meta(tz=False)] # require timezone naive ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `datetime` with no timezone component Bytes Constraints ----------------- These constraints are valid on `bytes` and `bytearray` types: - ``min_length``: The minimum valid length, inclusive. - ``max_length``: The maximum valid length, inclusive. .. code-block:: python >>> import msgspec >>> from typing import Annotated >>> msgspec.json.decode( ... b'"ZXhhbXBsZQ=="', ... type=Annotated[bytes, msgspec.Meta(min_length=10)] ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `bytes` of length >= 10 Sequence Constraints -------------------- These constraints are valid on `list`, `tuple`, `set`, and `frozenset` types: - ``min_length``: The minimum valid length, inclusive. - ``max_length``: The maximum valid length, inclusive. .. code-block:: python >>> import msgspec >>> from typing import Annotated >>> msgspec.json.decode( ... b'[1, 2, 3, 4]', ... type=Annotated[list[int], msgspec.Meta(max_length=3)] ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `array` of length <= 3 Mapping Constraints ------------------- These constraints are valid on `dict` types: - ``min_length``: The minimum valid length, inclusive. - ``max_length``: The maximum valid length, inclusive. .. code-block:: python >>> import msgspec >>> from typing import Annotated >>> msgspec.json.decode( ... b'{"a": 1, "b": 2, "c": 3, "d": 4}', ... type=Annotated[dict[str, int], msgspec.Meta(max_length=3)] ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `object` of length <= 3 .. _timezone-aware: https://docs.python.org/3/library/datetime.html#aware-and-naive-objects python-msgspec-0.19.0/docs/source/converters.rst000066400000000000000000000114501473355726200217540ustar00rootroot00000000000000Converters ========== .. currentmodule:: msgspec ``msgspec`` provides builtin support for several common protocols (``json``, ``msgpack``, ``yaml``, and ``toml``). Support for additional protocols may be added by combining a serialization library with msgspec's *converter functions*: `msgspec.to_builtins` and `msgspec.convert`. - `msgspec.to_builtins`: takes an object composed of any :doc:`supported type ` and converts it into one composed of only simple builtin types typically supported by Python serialization libraries. - `msgspec.convert`: takes an object composed of any :doc:`supported type `, and converts it to match a specified schema (validating along the way). If the conversion fails due to a schema mismatch, a nice error message is raised. These functions are designed to be paired with a Python serialization library as pre/post processors for typical ``dumps`` and ``loads`` functions. .. image:: _static/converters-light.svg :align: center :class: only-light .. image:: _static/converters-dark.svg :align: center :class: only-dark For example, if ``msgspec`` didn't already provide support for ``json``, you could add support by wrapping the standard library's `json` module as follows: .. code-block:: ipython In [1]: import json ...: from typing import Any ...: ...: import msgspec In [2]: def encode(obj): ...: return json.dumps(msgspec.to_builtins(obj)) In [3]: def decode(msg, type=Any): ...: return msgspec.convert(json.loads(msg), type=type) In [4]: class Point(msgspec.Struct): ...: x: int ...: y: int In [5]: x = Point(1, 2) In [6]: msg = encode(x) # Encoding a high-level type works In [7]: msg '{"x": 1, "y": 2}' In [8]: decode(msg, type=Point) # Decoding a high-level type works Point(x=1, y=2) In [9]: decode('{"x": "oops", "y": 2}', type=Point) # Schema mismatches error --------------------------------------------------------------------------- ValidationError Traceback (most recent call last) Cell In[9], line 1 ----> 1 decode('{"x": "oops", "y": 2}', type=Point) # Schema mismatches error Cell In[3], line 2, in decode(msg, type) 1 def decode(msg, type=Any): ---> 2 return msgspec.convert(json.loads(msg), type=type) ValidationError: Expected `int`, got `str` - at `$.x` Since all protocols are different, `to_builtins` and `convert` have a few configuration options: - ``builtin_types``: an iterable of additional types to treat as builtin types, beyond the standard `dict`, `list`, `tuple`, `set`, `frozenset`, `str`, `int`, `float`, `bool`, and `None`. - ``str_keys``: whether the wrapped protocol only supports strings for object keys, rather than any hashable type. - ``strict``: `convert` only. Whether type coercion rules should be strict. Defaults is True, setting to False enables a wider set of coercion rules from string to non-string types for all values. Among other uses, this may be used to handle completely untyped protocols like URL querystrings, where only string values exist. See :ref:`strict-vs-lax` for more information. - ``from_attributes``: `convert` only. If True, input objects may be coerced to ``Struct``/``dataclass``/``attrs`` types by extracting attributes from the input matching fields in the output type. One use case is converting database query results (ORM or otherwise) to msgspec structured types. The default is False. - ``enc_hook``/``dec_hook``: the standard keyword arguments used for :doc:`extending` msgspec to support additional types. ----- Taking a look at another protocol - TOML_. This protocol - Includes native support for `datetime.datetime`, `datetime.date`, and `datetime.time` types. - Only supports strings for object keys. If ``msgspec`` didn't already provide support for ``toml``, you could add support by wrapping the standard library's `tomllib` module as follows: .. code-block:: python import datetime import tomllib from typing import Any import msgspec def decode(msg, *, type=Any, dec_hook=None): return msgspec.convert( toml.loads(msg), type, builtin_types=(datetime.datetime, datetime.date, datetime.time), str_keys=True, dec_hook=dec_hook, ) ``msgspec`` uses these APIs to implement ``toml`` and ``yaml`` support, wrapping external serialization libraries: - ``msgspec.toml`` (`code `__) - ``msgspec.yaml`` (`code `__) The implementation in ``msgspec.toml`` is *almost* identical to the one above, with some additional code for error handling. .. _TOML: https://toml.io python-msgspec-0.19.0/docs/source/examples/000077500000000000000000000000001473355726200206455ustar00rootroot00000000000000python-msgspec-0.19.0/docs/source/examples/asyncio-kv.rst000066400000000000000000000035131473355726200234640ustar00rootroot00000000000000Asyncio TCP Key-Value Server ============================ This example demonstrates writing a small TCP server and client using `asyncio` and ``msgspec``. The server defines a few operations: - ``get(key: str) -> str | None``: get the value for a single key from the store if it exists. - ``put(key: str, val: str) -> None``: add a new key-value pair to the store. - ``delete(key: str) -> None``: delete a key-value pair from the store if it exists. - ``list_keys() -> list[str]``: list all the keys currently set in the store. Each operation has a corresponding request type defined as a :doc:`Struct <../structs>` type. Note that these structs are :ref:`tagged ` so they can be part of a ``Union`` of all request types the server handles. `msgspec.msgpack` is used to handle the encoding/decoding of the various messages. The length of each message is prefixed to each message (`Length-prefix framing `__) to make it easier to efficiently determine message boundaries. The full example source can be found `here `__. .. literalinclude:: ../../../examples/asyncio-kv/kv.py :language: python An example usage session: **Server** .. code-block:: shell $ python kv.py Serving on tcp://127.0.0.1:8888... Connection opened Connection closed **Client** .. code-block:: ipython3 In [1]: from kv import Client In [2]: client = await Client.create() In [3]: await client.put("foo", "bar") In [4]: await client.put("fizz", "buzz") In [5]: await client.get("foo") Out[5]: 'bar' In [6]: await client.list_keys() Out[6]: ['fizz', 'foo'] In [7]: await client.delete("fizz") In [8]: await client.list_keys() Out[8]: ['foo'] python-msgspec-0.19.0/docs/source/examples/conda-repodata.rst000066400000000000000000000105631473355726200242650ustar00rootroot00000000000000Conda Repodata ============== This example benchmarks using different JSON libraries to parse and query the `current_repodata.json`_ file from conda-forge_. This is a medium-sized (~14 MiB) JSON file containing nested metadata about every package on conda-forge. The following libraries are compared: - json_ - ujson_ - orjson_ - simdjson_ - msgspec_ This benchmark measures how long it takes each library to decode the ``current_repodata.json`` file, extract the name and size of each package, and determine the top 10 packages by file size. **Results** .. raw:: html
.. code-block:: text $ python query_repodata.py json: 139.14 ms ujson: 124.91 ms orjson: 91.69 ms simdjson: 66.40 ms msgspec: 25.73 ms **Commentary** - All of these are fairly quick, library choice likely doesn't matter at all for simple scripts on small- to medium-sized data. - While ``orjson`` is faster than ``json``, the difference between them is only ~30%. Creating python objects dominates the execution time of any well optimized decoding library. How fast the underlying JSON parser is matters, but JSON optimizations can only get you so far if you're still creating a new Python object for every node in the JSON object. - ``simdjson`` is much more performant. This is partly due to the SIMD optimizations it uses, but mostly it's due to not creating so many Python objects. ``simdjson`` first parses a JSON blob into a proxy object. It then lazily creates Python objects as needed as different fields are accessed. This means you only pay the cost of creating Python objects for the fields you use; a query that only accesses a few fields runs much faster since not as many Python objects are created. The downside is every attribute access results in some indirection as new objects are created - ``msgspec`` is the fastest option tested. It relies on defining a known schema beforehand. We don't define the schema for the entire structure, only for the fields we access. Only fields that are part of the schema are decoded, with a new Python object created for each. This allocates the same number of objects as ``simdjson``, but does it all at once, avoiding indirection costs later on during use. See :ref:`this performance tip ` for more information. **Source** The full example source can be found `here `__. .. literalinclude:: ../../../examples/conda-repodata/query_repodata.py :language: python .. raw:: html .. _conda-forge: https://conda-forge.org/ .. _current_repodata.json: https://conda.anaconda.org/conda-forge/noarch/current_repodata.json .. _json: https://docs.python.org/3/library/json.html .. _ujson: https://github.com/ultrajson/ultrajson .. _msgspec: https://jcristharif.com/msgspec/ .. _orjson: https://github.com/ijl/orjson .. _simdjson: https://github.com/TkTech/pysimdjson python-msgspec-0.19.0/docs/source/examples/edgedb.rst000066400000000000000000000151471473355726200226210ustar00rootroot00000000000000Usage with EdgeDB ================= .. image:: ../_static/edgedb.svg :width: 60% :align: center `EdgeDB `__ is an interesting new `graph-relational database `__ system. It includes a powerful and ergonomic query language `"EdgeQL" `__, along with client libraries that integrate well with their respective language ecosystems. In this example we demonstrate a few ways of integrating EdgeDB's `Python client library `__ with ``msgspec``. Setup ----- This is not intended to be a complete EdgeDB tutorial; for that we recommend going through the `official EdgeDB quickstart `__. This example assumes you already have the EdgeDB CLI and Python library installed. After cloning the ``msgspec`` repo, navigate to the ``edgedb`` example directory `here `__. Then initialize a new ``edgedb`` project. .. code-block:: bash $ edgedb project init --server-instance edgedb-msgspec-example --non-interactive This will setup a new instance and apply the example schema: .. literalinclude:: ../../../examples/edgedb/dbschema/default.esdl We then need to insert some records. This is done with the following EdgeQL query: .. literalinclude:: ../../../examples/edgedb/insert_data.edgeql To run this, execute the following: .. code-block:: bash $ edgedb query -f insert_data.edgeql JSON Encoding Query Results --------------------------- The EdgeDB Python library returns objects as ``edgedb.Object`` instances (`docs `__). Here we query the movie "Dune" that we inserted above, requesting the movie title and actors' names. .. code-block:: python >>> import edgedb >>> import msgspec >>> client = edgedb.create_client() >>> dune = client.query_single( ... """ ... SELECT Movie { ... title, ... actors: { ... name ... } ... } ... FILTER .title = 'Dune' ... LIMIT 1 ... """ ... ) >>> dune Object{title := 'Dune', actors := [Object{name := 'Timothée Chalamet'}, Object{name := 'Zendaya'}]} >>> type(dune) edgedb.Object These ``edgedb.Object`` instances are duck-type compatible with `dataclasses`, which means ``msgspec`` already knows how to JSON encode them. .. code-block:: python >>> json = msgspec.json.encode(dune) >>> print(msgspec.json.format(json.decode())) # pretty-print the JSON { "id": "b21913c4-3b68-11ee-89b0-2f0b6819503d", "title": "Dune", "actors": [ { "id": "b219195a-3b68-11ee-89b0-5b3794805cc7", "name": "Timothée Chalamet" }, { "id": "b2192058-3b68-11ee-89b0-f7d83b95fb13", "name": "Zendaya" } ] } Note that if you're immediately JSON encoding the results you may be better served by using EdgeDB's ``query_json``/``query_single_json`` methods, which return JSON strings directly (but strip the ``id`` fields). .. code-block:: python >>> edgedb_json = client.query_single_json( ... """ ... SELECT Movie { ... title, ... actors: { ... name ... } ... } ... FILTER .title = 'Dune' ... LIMIT 1 ... """ ... ) >>> edgedb_json '{"title" : "Dune", "actors" : [{"name" : "Timothée Chalamet"},{"name" : "Zendaya"}]}' If needed, this JSON string may be efficiently composed into a larger JSON object using `msgspec.Raw`. Here we add some additional outer structure wrapping the query result: .. code-block:: python >>> import datetime >>> msg = { ... "timestamp": datetime.datetime.now(datetime.timezone.utc), ... "server_version": "3.2", ... "query_result": msgspec.Raw(edgedb_json), ... } >>> json = msgspec.json.encode(msg) >>> print(msgspec.json.format(json.decode())) # pretty-print the JSON { "timestamp": "2023-08-15T14:37:12.733731Z", "server_version": "3.2", "query_result": { "title": "Dune", "actors": [ { "name": "Timothée Chalamet" }, { "name": "Zendaya" } ] } } Supporting Other EdgeDB Types ----------------------------- Besides ``edgedb.Object``, ``msgspec`` also includes builtin support for JSON encoding ``edgedb.NamedTuple`` types. There are a few remaining ``edgedb`` types that ``msgspec`` doesn't support out-of-the-box: - ``edgedb.DateDuration`` (`docs `__) - ``edgedb.RelativeDuration`` (`docs `__) JSON encoding support for these may be added through the use of :doc:`extensions <../extending>`. .. code-block:: python >>> def enc_hook(obj): ... if isinstance(obj, (edgedb.DateDuration, edgedb.RelativeDuration)): ... # The str representation of these types are ISO8601 durations, ... return str(obj) ... # Raise a NotImplementedError for unsupported types ... raise NotImplementedError >>> duration = client.query_single('SELECT "1 year 2 days"') >>> duration >>> msgspec.json.encode(duration, enc_hook=enc_hook) b'"P1Y2D"' Converting Results to Structs ----------------------------- If your application contains complex server-side logic, you may wish to convert the query results into some other application-specific structured type. ``msgspec`` supports automatic conversion to other types `msgspec.convert`. Here we'll define two `msgspec.Struct` types mirroring our Schema above: .. code-block:: python >>> class Person(msgspec.Struct): ... name: str >>> class Movie(msgspec.Struct): ... title: str ... actors: list[Person] We can then convert the ``edgedb.Object`` results into our ``Struct`` types using `msgspec.convert`. Note that the same conversion process would work if ``Person`` or ``Movie`` were defined as `dataclasses` or `attrs` types instead. .. code-block:: python >>> msgspec.convert(dune, Movie, from_attributes=True) Movie(title='Dune', actors=[Person(name='Timothée Chalamet'), Person(name='Zendaya')]) These structs may then be used to implement application logic (mutating/combining them as needed) before serializing the output to JSON. python-msgspec-0.19.0/docs/source/examples/geojson.rst000066400000000000000000000054561473355726200230550ustar00rootroot00000000000000GeoJSON ======= `GeoJSON `__ is a popular format for encoding geographic data. Its specification_ describes nine different types a message may take (seven "geometry" types, plus two "feature" types). Here we provide one way of implementing that specification using ``msgspec`` to handle the parsing and validation. The ``loads`` and ``dumps`` methods defined below work similar to the standard library's ``json.loads``/``json.dumps``, but: - Will result in high-level `msgspec.Struct` objects representing GeoJSON types - Will error nicely if a field is missing or the wrong type - Will fill in default values for optional fields - Decodes and encodes *significantly faster* than the `json` module (as well as most other ``json`` implementations in Python). This example makes use `msgspec.Struct` types to define the different GeoJSON types, and :ref:`struct-tagged-unions` to differentiate between them. See the relevant docs for more information. The full example source can be found `here `__. .. literalinclude:: ../../../examples/geojson/msgspec_geojson.py :language: python Here we use the ``loads`` method defined above to read some `example GeoJSON`_. .. code-block:: ipython3 In [1]: import msgspec_geojson In [2]: with open("canada.json", "rb") as f: ...: data = f.read() In [3]: canada = msgspec_geojson.loads(data) In [4]: type(canada) # loaded as high-level, validated object Out[4]: msgspec_geojson.FeatureCollection In [5]: canada.features[0].properties Out[5]: {'name': 'Canada'} Comparing performance to: - orjson_ - `json` - geojson_ (another validating Python implementation) .. code-block:: ipython3 In [6]: %timeit msgspec_geojson.loads(data) # benchmark msgspec 6.15 ms ± 13.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) In [7]: %timeit orjson.loads(data) # benchmark orjson 8.67 ms ± 20.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) In [8]: %timeit json.loads(data) # benchmark json 27.6 ms ± 102 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) In [9]: %timeit geojson.loads(data) # benchmark geojson 93.9 ms ± 88.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) This shows that the readable ``msgspec`` implementation above is 1.4x faster than `orjson` (on this data), while also ensuring the loaded data is valid GeoJSON. Compared to geojson_ (another validating geojson library for python), loading the data using ``msgspec`` was **15.3x faster**. .. _specification: https://datatracker.ietf.org/doc/html/rfc7946 .. _example GeoJSON: https://github.com/jcrist/msgspec/blob/main/examples/geojson/canada.json .. _orjson: https://github.com/ijl/orjson .. _geojson: https://github.com/jazzband/geojson python-msgspec-0.19.0/docs/source/examples/index.rst000066400000000000000000000003411473355726200225040ustar00rootroot00000000000000Examples ======== Here we provide a few examples using ``msgspec`` to accomplish various tasks. .. toctree:: :maxdepth: 1 geojson.rst asyncio-kv.rst conda-repodata.rst pyproject-toml.rst edgedb.rst python-msgspec-0.19.0/docs/source/examples/pyproject-toml.rst000066400000000000000000000103231473355726200243660ustar00rootroot00000000000000Parsing ``pyproject.toml`` ========================== `PEP 518`_ defined a new ``pyproject.toml`` configuration file Python projects can use for configuring: - Metadata (name, version, ...) - Dependencies - Build systems - Additional development tools (black_, mypy_, pytest_, ... all support ``pyproject.toml`` files for configuration). The format was defined in a series of Python Enhancement Proposals (PEPs), which also serve as the main documentation for the file schema. - `PEP 517`_: A build-system independent format for source trees - `PEP 518`_: Specifying minimum build system requirements for Python projects - `PEP 621`_: Storing project metadata in pyproject.toml Here we define a msgspec schema for parsing and validating a ``pyproject.toml`` file. This includes full schema definitions for all fields in the ``build-system`` and ``project`` tables, as well as an untyped table under ``tool``. The full example source can be found `here `__. .. literalinclude:: ../../../examples/pyproject-toml/pyproject.py :language: python Here we use it to load the `pyproject.toml for Starlette `__: .. code-block:: ipython3 In [1]: import pyproject In [2]: import urllib.request In [3]: url = "https://raw.githubusercontent.com/encode/starlette/master/pyproject.toml" In [4]: with urllib.request.urlopen(url) as f: ...: data = f.read() In [5]: result = pyproject.decode(data) # decode the pyproject.toml In [6]: result.build_system Out[6]: BuildSystem(requires=['hatchling'], build_backend='hatchling.build', backend_path=[]) In [7]: result.project.name Out[7]: 'starlette' Note that this only validates that fields are of the proper type. It doesn't check: - Whether strings like URLs or `dependency specifiers`_ are valid. Some of these could be handled using msgspec's existing :doc:`../constraints` system, but not all of them. - Mutually exclusive field restrictions (for example, you can't set both ``project.license.file`` and ``project.license.text``). ``msgspec`` currently has no way of declaring these restrictions. Even with these caveats, the schemas here are still useful: - Since ``forbid_unknown_fields=True`` is configured, any extra fields will raise a nice error message. This is very useful for catching typos in configuration files, as the misspelled field names won't be silently ignored. - Type errors for fields will also be caught, with a nice error raised. - Any downstream consumers of ``decode`` have a nice high-level object to work with, complete with type annotations. This plays well with tab-completion and tools like mypy_ or pyright_, improving usability. For example, here's an invalid ``pyproject.toml``. .. code-block:: toml [build-system] requires = "hatchling" build-backend = "hatchling.build" [project] name = "myproject" version = "0.1.0" description = "a super great library" authors = [ {name = "alice shmalice", email = "alice@company.com"} ] Can you spot the error? Using the schemas defined above, ``msgpspec`` can detect schema issues like this, and raise a nice error message. In this case the issue is that ``build-system.requires`` should be an array of strings, not a single string: .. code-block:: ipython In [1]: import pyproject In [2]: with open("pyproject.toml", "rb") as f: ...: invalid = f.read() In [3]: pyproject.decode(invalid) --------------------------------------------------------------------------- ValidationError Traceback (most recent call last) Cell In [3], line 1 ----> 1 pyproject.decode(invalid) ValidationError: Expected `array`, got `str` - at `$.build-system.requires` .. _PEP 517: https://peps.python.org/pep-0517/ .. _PEP 518: https://peps.python.org/pep-0518/ .. _PEP 621: https://peps.python.org/pep-0621/ .. _black: https://black.readthedocs.io .. _mypy: https://mypy.readthedocs.io .. _pyright: https://github.com/microsoft/pyright .. _pytest: https://docs.pytest.org .. _dependency specifiers: https://packaging.python.org/en/latest/specifications/dependency-specifiers/ python-msgspec-0.19.0/docs/source/extending.rst000066400000000000000000000214331473355726200215510ustar00rootroot00000000000000Extending ========= To allow encoding/decoding types other than those :doc:`natively supported `, ``msgspec`` provides a few callbacks to ``Encoder``/``Decoder``. - ``enc_hook``, for transforming custom types into values that ``msgspec``:doc:`natively supports `. - ``dec_hook``, for converting natively supported types back into a custom type when using :ref:`typed decoding `. - ``ext_hook`` (MessagePack only), for converting `MessagePack extensions`_ back into custom types. These should have the following signatures: .. code-block:: python def enc_hook(obj: Any) -> Any: """Given an object that msgspec doesn't know how to serialize by default, convert it into an object that it does know how to serialize""" pass def dec_hook(type: Type, obj: Any) -> Any: """Given a type in a schema, convert ``obj`` (composed of natively supported objects) into an object of type ``type``. Any `TypeError` or `ValueError` exceptions raised by this method will be considered "user facing" and converted into a `ValidationError` with additional context. All other exceptions will be raised directly. """ pass def ext_hook(code: int, data: memoryview) -> Any: """MessagePack only. Given an extension type code and data buffer, deserialize whatever custom object the extension type represents""" pass These can be composed together to form complex behaviors as needed. However, most use cases follow one of these patterns: - Mapping a custom type to/from natively supported types via ``enc_hook`` and ``dec_hook`` callbacks. - Defining a custom `MessagePack extension`_ to represent your type, then mapping to/from that extension via ``enc_hook`` and ``ext_hook`` callbacks. Both methods are illustrated below. Mapping to/from native types ---------------------------- This method uses messages composed only of natively supported types. During encoding, custom types are mapped to natively supported types, which are then serialized. This process is then reversed during decoding. .. code-block:: custom type -> native types -> encoded message -> native types -> custom type This means that :ref:`typed decoding ` is required to roundtrip a message, since no custom type info is sent as part of the message. This method works best for types that are similar to a natively supported type (e.g. a `collections.deque` is similar to a `list`). This can be accomplished by defining two callback functions: - ``enc_hook`` in ``Encoder``, for transforming custom types into values that ``msgspec`` already knows how to serialize. - ``dec_hook`` in ``Decoder``, for converting natively supported types back into a custom type when using :ref:`typed decoding `. Here we define ``enc_hook`` and ``dec_hook`` callbacks to convert `complex` objects to/from objects, which are then natively handled by ``msgspec``. .. code-block:: python import msgspec from typing import Any, Type def enc_hook(obj: Any) -> Any: if isinstance(obj, complex): # convert the complex to a tuple of real, imag return (obj.real, obj.imag) else: # Raise a NotImplementedError for other types raise NotImplementedError(f"Objects of type {type(obj)} are not supported") def dec_hook(type: Type, obj: Any) -> Any: # `type` here is the value of the custom type annotation being decoded. if type is complex: # Convert ``obj`` (which should be a ``tuple``) to a complex real, imag = obj return complex(real, imag) else: # Raise a NotImplementedError for other types raise NotImplementedError(f"Objects of type {type} are not supported") # Define a message that contains a complex type class MyMessage(msgspec.Struct): field_1: str field_2: complex # Create an encoder and a decoder using the custom callbacks. # Note that typed deserialization is required for successful # roundtripping here, so we pass `MyMessage` to `Decoder`. enc = msgspec.json.Encoder(enc_hook=enc_hook) dec = msgspec.json.Decoder(MyMessage, dec_hook=dec_hook) # An example message msg = MyMessage("some string", complex(1, 2)) # Encode and decode the message to show that things work buf = enc.encode(msg) msg2 = dec.decode(buf) assert msg == msg2 # True .. _defining-extensions: Defining a custom extension (MessagePack only) ---------------------------------------------- The MessagePack specification provides support for defining custom Extensions_. Extensions consist of: - An integer code (between 0 and 127, inclusive) representing the "type" of the extension. - An arbitrary byte buffer of data (up to ``(2^32) - 1`` in length). By default extensions are serialized to/from `msgspec.msgpack.Ext` objects. .. code-block:: python >>> ext = msgspec.msgpack.Ext(1, b"some data") # an extension object, with type code 1 >>> msg = msgspec.msgpack.encode(ext) >>> ext2 = msgspec.msgpack.decode(msg) >>> ext == ext2 # deserializes as an Ext object True While manually creating `Ext` objects from buffers can be useful, usually the user wants to map extension types to/from their own custom objects. This can be accomplished by defining two callback functions: - ``enc_hook`` in `msgspec.msgpack.Encoder`, for transforming custom types into values that ``msgspec`` already knows how to serialize. - ``ext_hook`` in `msgspec.msgpack.Decoder`, for converting extensions back into those custom types. This method defines a new extension type, and sends this type information along as part of the message. This means that when properly configured, custom types can be deserialized even when using untyped deserialization. However, if you're communicating with MessagePack libraries other than ``msgspec``, you'd have to ensure your extension type was supported by those libraries as well. For example, perhaps you wanted to serialize `complex` number objects as an extension type. These objects can be represented as tuples of two floats (one "real" and one "imaginary"). If we represent each float as 8 bytes (a "double"), then any complex number can be fully represented by a 16 byte buffer. .. code-block:: +---------+---------+ | real | imag | +---------+---------+ 8 bytes 8 bytes Here we define ``enc_hook`` and ``ext_hook`` callbacks to convert `complex` objects to/from this binary representation as a MessagePack extension. .. code-block:: python import msgspec import struct from typing import Any # All extension types need a unique integer designator so the decoder knows # which type they're decoding. Here we arbitrarily choose 1, but any integer # between 0 and 127 (inclusive) would work. COMPLEX_TYPE_CODE = 1 def enc_hook(obj: Any) -> Any: if isinstance(obj, complex): # encode the complex number into a 16 byte buffer data = struct.pack('dd', obj.real, obj.imag) # Return an `Ext` object so msgspec serializes it as an extension type. return msgspec.msgpack.Ext(COMPLEX_TYPE_CODE, data) else: # Raise a NotImplementedError for other types raise NotImplementedError(f"Objects of type {type(obj)} are not supported") def ext_hook(code: int, data: memoryview) -> Any: if code == COMPLEX_TYPE_CODE: # This extension type represents a complex number, decode the data # buffer accordingly. real, imag = struct.unpack('dd', data) return complex(real, imag) else: # Raise a NotImplementedError for other extension type codes raise NotImplementedError(f"Extension type code {code} is not supported") # Create an encoder and a decoder using the custom callbacks enc = msgspec.msgpack.Encoder(enc_hook=enc_hook) dec = msgspec.msgpack.Decoder(ext_hook=ext_hook) # Define a message that contains complex numbers msg = {"roots": [0, 0.75, 1 + 0.5j, 1 - 0.5j]} # Encode and decode the message to show that things work buf = enc.encode(msg) msg2 = dec.decode(buf) assert msg == msg2 # True .. note:: Note that the ``data`` argument to ``ext_hook`` is a `memoryview`. This view is attached to the larger buffer containing the complete message being decoded. As such, you'll want to ensure that you don't keep a reference to the underlying buffer, otherwise you may accidentally persist the larger message buffer around for longer than necessary, resulting in increased memory usage. .. _extensions: .. _MessagePack extensions: .. _MessagePack extension: https://github.com/msgpack/msgpack/blob/master/spec.md#extension-types python-msgspec-0.19.0/docs/source/index.rst000066400000000000000000000133251473355726200206740ustar00rootroot00000000000000msgspec ======= ``msgspec`` is a *fast* serialization and validation library, with builtin support for JSON_, MessagePack_, YAML_, and TOML_. It features: - 🚀 **High performance encoders/decoders** for common protocols. The JSON and MessagePack implementations regularly :doc:`benchmark ` as the fastest options for Python. - 🎉 **Support for a wide variety of Python types**. Additional types may be supported through :doc:`extensions `. - 🔍 **Zero-cost schema validation** using familiar Python type annotations. In :doc:`benchmarks ` ``msgspec`` decodes *and* validates JSON faster than orjson_ can decode it alone. - ✨ **A speedy Struct type** for representing structured data. If you already use dataclasses_ or attrs_, :doc:`structs` should feel familiar. However, they're :ref:`5-60x ` faster for common operations. All of this is included in a :ref:`lightweight library ` with no required dependencies. ----- ``msgspec`` may be used for serialization alone, as a faster JSON or MessagePack library. For the greatest benefit though, we recommend using ``msgspec`` to handle the full serialization & validation workflow: **Define** your message schemas using standard Python type annotations. .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct): ... """A new type describing a User""" ... name: str ... groups: set[str] = set() ... email: str | None = None **Encode** messages as JSON, or one of the many other supported protocols. .. code-block:: python >>> alice = User("alice", groups={"admin", "engineering"}) >>> alice User(name='alice', groups={"admin", "engineering"}, email=None) >>> msg = msgspec.json.encode(alice) >>> msg b'{"name":"alice","groups":["admin","engineering"],"email":null}' **Decode** messages back into Python objects, with optional schema validation. .. code-block:: python >>> msgspec.json.decode(msg, type=User) User(name='alice', groups={"admin", "engineering"}, email=None) >>> msgspec.json.decode(b'{"name":"bob","groups":[123]}', type=User) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str`, got `int` - at `$.groups[0]` ``msgspec`` is designed to be as performant as possible, while retaining some of the nicities of validation libraries like pydantic_. For supported types, encoding/decoding a message with ``msgspec`` can be :doc:`~10-80x faster than alternative libraries `. Highlights ---------- - ``msgspec`` is **fast**. It :doc:`benchmarks ` as the fastest serialization library for Python, outperforming all other JSON/MessagePack libraries compared. - ``msgspec`` is **friendly**. Through use of Python's type annotations, messages are :ref:`validated ` during deserialization in a declarative way. ``msgspec`` also works well with other type-checking tooling like mypy_ and pyright_, providing excellent editor integration. - ``msgspec`` is **flexible**. It natively supports a :doc:`wide range of Python builtin types `. Support for additional types can also be added through :doc:`extensions `. - ``msgspec`` is **lightweight**. It has no required dependencies, and the binary size is :ref:`a fraction of that of comparable libraries `. - ``msgspec`` is **correct**. The encoders/decoders implemented are strictly compliant with their respective specifications, providing stronger guarantees of compatibility with other systems. Used By ------- ``msgspec`` is used by many organizations and `open source projects `__, here we highlight a few: .. grid:: 2 2 4 4 .. grid-item-card:: NautilusTrader :link: https://nautilustrader.io/ .. image:: _static/nautilus-trader.png .. grid-item-card:: Litestar :link: https://litestar.dev/ .. image:: _static/litestar.png .. grid-item-card:: Sanic :link: https://sanic.dev/en/ .. image:: _static/sanic.png .. grid-item-card:: Mosec :link: https://mosecorg.github.io/mosec/ .. image:: _static/mosec.png .. grid-item-card:: Pioreactor :link: https://pioreactor.com/ .. image:: _static/pioreactor.png .. grid-item-card:: Zero :link: https://github.com/Ananto30/zero .. image:: _static/zero.png .. grid-item-card:: anywidget :link: https://anywidget.dev/ .. image:: _static/anywidget.png .. grid-item-card:: esmerald :link: https://esmerald.dev/ .. image:: _static/esmerald.png .. _type annotations: https://docs.python.org/3/library/typing.html .. _JSON: https://json.org .. _MessagePack: https://msgpack.org .. _YAML: https://yaml.org .. _TOML: https://toml.io .. _attrs: https://www.attrs.org .. _dataclasses: https://docs.python.org/3/library/dataclasses.html .. _orjson: https://github.com/ijl/orjson .. _pydantic: https://pydantic-docs.helpmanual.io/ .. _mypy: https://mypy.readthedocs.io .. _pyright: https://github.com/microsoft/pyright .. toctree:: :hidden: :maxdepth: 2 :caption: Overview why.rst install.rst benchmarks.rst .. toctree:: :hidden: :maxdepth: 2 :caption: User Guide usage.rst supported-types.rst structs.rst constraints.rst converters.rst jsonschema.rst schema-evolution.rst .. toctree:: :hidden: :maxdepth: 2 :caption: Advanced extending.rst inspect.rst perf-tips.rst .. toctree:: :hidden: :maxdepth: 2 :caption: Reference api.rst examples/index.rst changelog.rst python-msgspec-0.19.0/docs/source/inspect.rst000066400000000000000000000112531473355726200212300ustar00rootroot00000000000000Inspecting Types ---------------- .. currentmodule:: msgspec.inspect .. warning:: This module is experimental. While we don't expect any breaking changes, we also don't promise not to break things between releases while this interface stabilizes. ``msgspec`` provides type-introspection support, which can be used to build tooling on top of msgspec-compatible types. Possible use cases include: - Generating OpenAPI_ specifications from msgspec-compatible types (note that the builtin :doc:`jsonschema` support may be a better starting point for this). - Generating example instances of types for testing or documentation purposes - Integration with hypothesis_ for testing The main function here is `msgspec.inspect.type_info` for converting a type annotation into a corresponding `msgspec.inspect.Type` object. There's also `msgspec.inspect.multi_type_info` which converts an iterable of annotations; this function is more efficient than calling `type_info` in a loop. .. code-block:: python >>> import msgspec >>> msgspec.inspect.type_info(bool) BoolType() >>> msgspec.inspect.type_info(int) IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None) >>> msgspec.inspect.type_info(list[int]) # nested types are traversed ListType( item_type=IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None), min_length=None, max_length=None ) >>> msgspec.inspect.multi_type_info([bool, int]) # inspect multiple types (BoolType(), IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None)) Types with :doc:`constraints` will include the constraint information as well: .. code-block:: python >>> from typing import Annotated >>> from msgspec import Meta >>> PositiveInt = Annotated[int, Meta(gt=0)] >>> msgspec.inspect.type_info(PositiveInt) IntType(gt=0, ge=None, lt=None, le=None, multiple_of=None) Compound types like :doc:`structs` are also supported: .. code-block:: python >>> class User(msgspec.Struct): ... name: str ... groups: list[str] = [] ... email: str | None = None >>> msgspec.inspect.type_info(User) StructType( cls=User, fields=( Field( name='name', encode_name='name', type=StrType(min_length=None, max_length=None, pattern=None), required=True, default=UNSET, default_factory=UNSET ), Field( name='groups', encode_name='groups', type=ListType( item_type=StrType(min_length=None, max_length=None, pattern=None), min_length=None, max_length=None ), required=False, default=[], default_factory=UNSET ), Field( name='email', encode_name='email', type=UnionType( types=( StrType(min_length=None, max_length=None, pattern=None), NoneType() ) ), required=False, default=None, default_factory=UNSET ) ), tag_field=None, tag=None, array_like=False, forbid_unknown_fields=False ) Types with additional metadata like ``extra_json_schema`` or ``title`` will be wrapped in a `msgspec.inspect.Metadata` object. Note that all JSON schema specific fields are merged into a single ``extra_json_schema`` dict. .. code-block:: python >>> UnixName = Annotated[ ... str, ... Meta( ... min_length=1, ... max_length=32, ... pattern="^[a-z_][a-z0-9_-]*$", ... description="A valid UNIX username" ... ) ... ] >>> msgspec.inspect.type_info(UnixName) Metadata( type=StrType( min_length=1, max_length=32, pattern='^[a-z_][a-z0-9_-]*$' ), extra_json_schema={'description': 'A valid UNIX username'} ) Every type supported by ``msgspec`` has a corresponding `msgspec.inspect.Type` subclass. See the :ref:`API docs ` for a complete list of types. For an example of using these functions, you might find our builtin :doc:`jsonschema` generator implementation useful - the code for this can be found `here `__. In particular, take a look at the large if-else statement in ``_to_schema``. .. _OpenAPI: https://www.openapis.org/ .. _hypothesis: https://hypothesis.readthedocs.io/en/latest/ python-msgspec-0.19.0/docs/source/install.rst000066400000000000000000000033171473355726200212330ustar00rootroot00000000000000Installation ============ ``msgspec`` may be installed via ``pip`` or ``conda``. Note that Python >= 3.8 is required. The basic install has no required dependencies. **pip** .. code-block:: shell pip install msgspec **conda** .. code-block:: shell conda install msgspec -c conda-forge Optional Dependencies --------------------- Depending on your platform, the base install of ``msgspec`` may not support TOML_ or YAML_ without additional dependencies. TOML ~~~~ The TOML_ protocol requires: - Python < 3.11: `tomli`_ and `tomli_w`_ for reading and writing TOML. - Python >= 3.11: `tomli_w`_ for writing TOML. Reading TOML is done using the standard library's `tomllib` and requires no additional dependencies. You may either install these dependencies manually, or depend on the ``toml`` extra: **pip** .. code-block:: shell pip install "msgspec[toml]" **conda** .. code-block:: shell conda install msgspec-toml -c conda-forge YAML ~~~~ The YAML_ protocol requires PyYAML_ on all platforms. You may either install this dependency manually, or depend on the ``yaml`` extra: **pip** .. code-block:: shell pip install "msgspec[yaml]" **conda** .. code-block:: shell conda install msgspec-yaml -c conda-forge Installing from GitHub ---------------------- If you want wish to use a feature that hasn't been released yet, you may install from the `development branch on GitHub `__ using ``pip``: .. code-block:: shell pip install git+https://github.com/jcrist/msgspec.git .. _YAML: https://yaml.org .. _TOML: https://toml.io .. _PyYAML: https://pyyaml.org/ .. _tomli: https://github.com/hukkin/tomli .. _tomli_w: https://github.com/hukkin/tomli-w python-msgspec-0.19.0/docs/source/jsonschema.rst000066400000000000000000000052711473355726200217200ustar00rootroot00000000000000JSON Schema =========== ``msgspec`` provides a few utilities for generating `JSON Schema`_ specifications from msgspec-compatible :doc:`types ` and :doc:`constraints `. - `msgspec.json.schema`: generates a complete JSON Schema for a single type. - `msgspec.json.schema_components`: generates JSON schemas for multiple types, along with a corresponding ``components`` mapping. This is mainly useful when generating multiple schemas to include in a larger specification like OpenAPI_. The generated schemas are compatible with `JSON Schema`_ 2020-12 and OpenAPI_ 3.1. Example ------- .. code-block:: python import msgspec from msgspec import Struct, Meta from typing import Annotated, Optional # A float constrained to values > 0 PositiveFloat = Annotated[float, Meta(gt=0)] class Dimensions(Struct): """Dimensions for a product, all measurements in centimeters""" length: PositiveFloat width: PositiveFloat height: PositiveFloat class Product(Struct): """A product in a catalog""" id: int name: str price: PositiveFloat tags: set[str] = set() dimensions: Optional[Dimensions] = None # Generate a schema for a list of products schema = msgspec.json.schema(list[Product]) # Print out that schema as JSON print(msgspec.json.encode(schema)) .. code-block:: json { "type": "array", "items": {"$ref": "#/$defs/Product"}, "$defs": { "Dimensions": { "title": "Dimensions", "description": "Dimensions for a product, all measurements in centimeters", "type": "object", "properties": { "length": {"type": "number", "exclusiveMinimum": 0}, "width": {"type": "number", "exclusiveMinimum": 0}, "height": {"type": "number", "exclusiveMinimum": 0} }, "required": ["length", "width", "height"] }, "Product": { "title": "Product", "description": "A product in a catalog", "type": "object", "properties": { "id": {"type": "integer"}, "name": {"type": "string"}, "price": {"type": "number", "exclusiveMinimum": 0}, "tags": { "type": "array", "items": {"type": "string"}, "default": [], }, "dimensions": { "anyOf": [{"type": "null"}, {"$ref": "#/$defs/Dimensions"}], "default": null, } }, "required": ["id", "name", "price"] } } } .. _JSON Schema: https://json-schema.org/ .. _OpenAPI: https://www.openapis.org/ python-msgspec-0.19.0/docs/source/perf-tips.rst000066400000000000000000000242321473355726200214750ustar00rootroot00000000000000Performance Tips ================ Here we present a few tips and tricks for squeezing maximum performance out of ``msgspec``. They're presented in order from "sane, definitely a good idea" to "fast, but you may not want to do this". Reuse Encoders/Decoders ----------------------- Every call to a top-level ``encode`` function like `msgspec.json.encode` allocates some temporary internal state used for encoding. While fine for normal use, for maximum performance you'll want to create an ``Encoder`` (e.g. `msgspec.json.Encoder`) once and reuse it for all encoding calls, avoiding paying that setup cost for every call. .. code-block:: python >>> import msgspec >>> encoder = msgspec.json.Encoder() # Create once >>> for msg in msgs: ... data = encoder.encode(msg) # reuse multiple times The same goes for decoding. If you're making multiple ``decode`` calls in a performance-sensitive code path, you'll want to create a ``Decoder`` (e.g. `msgspec.json.Decoder`) once and reuse it for each call. Since decoders are typed, you may need to create multiple decoders, one for each type. .. code-block:: python >>> import msgspec >>> decoder = msgspec.json.Decoder(list[int]) # Create once >>> for data in input_buffers: ... msg = decoder.decode(data) # reuse multiple times Use Structs ----------- :doc:`structs` are msgspec's native way of expressing user-defined types. They're :ref:`fast to encode/decode ` and :ref:`fast to use `. If you have data with a known schema, we recommend defining a `msgspec.Struct` type (or types) for your schema and preferring that over other types like `dict`/`dataclasses`/... Avoid Encoding Default Values ----------------------------- By default, ``msgspec`` encodes all fields in a Struct type, including optional fields (those configured with a default value). If the default values are known on the decoding end (making serializing them redundant), it may be beneficial to omit default values from the encoded message. This can be done by configuring ``omit_defaults=True`` as part of the Struct definition Omitting defaults reduces the size of the encoded message, and often also improves encoding and decoding performance (since there's less work to do). For more information, see :ref:`omit_defaults`. .. _avoid-decoding-unused-fields: Avoid Decoding Unused Fields ---------------------------- When decoding large inputs, sometimes you're only interested in a few specific fields. Since decoding large objects is inherently allocation heavy, it may be beneficial to define a smaller `msgspec.Struct` type that only has the fields you require. For example, say you're interested in decoding some JSON from the `Twitter API `__. A ``Tweet`` object has many nested fields on it - perhaps you only care about the tweet text, the user name, and the number of favorites. By defining struct types with only those fields, ``msgspec`` can avoid doing unnecessary work decoding fields that are never used. .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct): ... name: str >>> class Tweet(msgspec.Struct): ... user: User ... full_text: str ... favorite_count: int We can then use these types to decode the `example tweet json `__: .. code-block:: python >>> tweet = msgspec.json.decode(example_json, type=Tweet) >>> tweet.user.name 'Twitter Dev' >>> tweet.user.favorite_count 70 Of course there are downsides to defining smaller "view" types, but if decoding performance is a bottleneck in your workflow, you may benefit from this technique. For a more in-depth example of this technique, see the :doc:`examples/conda-repodata` example. Reduce Allocations ------------------ Every call to ``encode``/``Encoder.encode`` allocates a new `bytes` object for the output. ``msgspec`` exposes an alternative ``Encoder.encode_into`` (e.g. `msgspec.json.Encoder.encode_into`) that writes into a pre-allocated `bytearray` instead (possibly reallocating to increase capacity). This has a few uses: Reusing an output buffer ^^^^^^^^^^^^^^^^^^^^^^^^ If you're encoding and writing messages to a socket/file in a hot loop, you *may* benefit from allocating a single `bytearray` buffer once and reusing it for every message. For example: .. code-block:: python encoder = msgspec.msgpack.Encoder() # Allocate a single shared buffer buffer = bytearray() for msg in msgs: # Encode a message into the buffer at the start of the buffer. # Note that this overwrites any previous contents. encoder.encode_into(msg, buffer) # Write the buffer to the socket socket.sendall(buffer) A few caveats: - ``Encoder.encode_into`` will expand the capacity of ``buffer`` as needed to fit the message size. This means that if a large message is encountered the buffer will be expanded to be equally large, but won't be reduced back to normal afterwards (possibly bloating memory usage). You can use `sys.getsizeof` (or call `bytearray.__sizeof__`) directly to determine the actual capacity of the buffer, since ``len(buffer)`` will only reflect the part of the buffer that is written to. - Small messages (for some definition of "small") likely won't see a performance improvement from using this method, and may instead see a slowdown. We recommend using a realistic benchmark to determine if this method can benefit your workload. Line-Delimited JSON ^^^^^^^^^^^^^^^^^^^ Some protocols require appending a suffix to an encoded message. One place where this comes up is when encoding `line-delimited JSON`_, where every payload contains a JSON message followed by ``b"\n"``. This *could* be handled in python as: .. code-block:: python import msgspec json_msg = msgspec.json.encode(["my", "message"]) full_payload = json_msg + b'\n' However, this results in an unnecessary copy of ``json_msg``, which can be avoided by using `msgspec.json.Encoder.encode_into`. .. code-block:: python import msgspec encoder = msgspec.json.Encoder() # Allocate a buffer. We recommend using a small non-empty buffer to # avoid reallocating for small messages. Choose something larger than # your common message size, but not excessively large. buffer = bytearray(64) # Encode into the existing buffer. encoder.encode_into(["my", "message"], buffer) # Append a newline character without copying buffer.extend(b"\n") # Write the full buffer to a socket/file/etc... socket.sendall(buffer) Length-Prefix Framing ^^^^^^^^^^^^^^^^^^^^^ Some protocols require prepending a prefix to an encoded message. This comes up in `Length-prefix framing `__ , where every message is prefixed by its length stored as a fixed-width integer (e.g. a big-endian uint32). Like line-delimited JSON above, this is more efficient to do using ``Encoder.encode_into`` to avoid excessive copying. .. code-block:: python import msgspec encoder = msgspec.msgpack.Encoder() # Allocate a buffer. We recommend using a small non-empty buffer to # avoid reallocating for small messages. Choose something larger than # your common message size, but not excessively large. buffer = bytearray(64) # Encode into the existing buffer, offset by 4 bytes at the front to # store the length prefix. encoder.encode_into(msg, buffer, 4) # Encode the message length as a 4 byte big-endian integer, and # prefix the message with it (without copying). n = len(msg) - 4 buffer[:4] = n.to_bytes(4, "big") # Write the buffer to a socket/file/etc... socket.sendall(buffer) Use MessagePack --------------- ``msgspec`` supports both JSON_ and MessagePack_ protocols. The latter is less commonly used, but :ref:`can be more performant `. If performance is an issue (and MessagePack is an acceptable solution), you may benefit from using it instead of JSON. And since ``msgspec`` supports both protocols with a consistent interface, switching from ``msgspec.json`` to ``msgspec.msgpack`` should be fairly painless. Use ``gc=False`` ----------------- Python processes with a large number of long-lived objects, or operations that allocate a large number of objects at once may suffer reduced performance due to Python's garbage collector (GC). By default, `msgspec.Struct` types implement a few optimizations to reduce the load on the GC (and thus reduce the frequency and duration of a GC pause). If you find that GC is still a problem, and **are certain** that your Struct types may never participate in a reference cycle, then you **may** benefit from setting ``gc=False`` on your Struct types. Depending on workload, this can result in a measurable decrease in pause time and frequency due to GC passes. See :ref:`struct-gc` for more details. Use ``array_like=True`` ----------------------- One touted benefit of JSON_ and MessagePack_ is that they're "self-describing" protocols. JSON objects serialize their field names along with their values. If both ends of a connection already know the field names though, serializing them may be an unnecessary cost. If you need higher performance (at the cost of more inscrutable message encoding), you can set ``array_like=True`` on a struct definition. Structs with this option enabled are encoded/decoded like array types, removing the field names from the encoded message. This can provide on average another ~2x speedup for decoding (and ~1.5x speedup for encoding). .. code-block:: python >>> class Example(msgspec.Struct, array_like=True): ... my_first_field: str ... my_second_field: int >>> x = Example("some string", 2) >>> msg = msgspec.json.encode(x) >>> msg b'["some string",2]' >>> msgspec.json.decode(msg, type=Example) Example(my_first_field="some string", my_second_field=2) .. _JSON: https://json.org .. _MessagePack: https://msgpack.org .. _line-delimited JSON: https://en.wikipedia.org/wiki/JSON_streaming#Line-delimited_JSON python-msgspec-0.19.0/docs/source/schema-evolution.rst000066400000000000000000000053361473355726200230520ustar00rootroot00000000000000Schema Evolution ================ ``msgspec`` includes support for "schema evolution", meaning that: - Messages serialized with an older version of a schema will be deserializable using a newer version of the schema. - Messages serialized with a newer version of the schema will be deserializable using an older version of the schema. This can be useful if, for example, you have clients and servers with mismatched versions. For schema evolution to work smoothly, you need to follow a few guidelines: 1. Any new fields on a `msgspec.Struct` must specify default values. 2. Structs with ``array_like=True`` must not reorder fields, and any new fields must be appended to the end (and have defaults). 3. Don't change the type annotations for existing messages or fields. 4. Don't change the type codes or implementations for any defined :ref:`extensions ` (MessagePack only). For example, suppose we had a `msgspec.Struct` type representing a user: .. code-block:: python >>> import msgspec >>> from typing import Set, Optional >>> class User(msgspec.Struct): ... """A struct representing a user""" ... name: str ... groups: Set[str] = set() ... email: Optional[str] = None Then suppose we wanted to add a new ``phone`` field to this struct in a way that wouldn't break clients/servers still using the prior definition. To accomplish this, we add ``phone`` as an _optional_ field (defaulting to ``None``), at the end of the struct. .. code-block:: python >>> class User2(msgspec.Struct): ... """An updated version of the User struct, now with a phone number""" ... name: str ... groups: Set[str] = set() ... email: Optional[str] = None ... phone : Optional[str] = None Messages serialized using both the old and new schemas can still be exchanged without error. If an old message is deserialized using the new schema, the missing fields all have default values that will be used. Likewise, if a new message is deserialized with the old schema the unknown new fields will be efficiently skipped without decoding. .. code-block:: python >>> old_dec = msgspec.json.Decoder(User) >>> new_dec = msgspec.json.Decoder(User2) >>> new_msg = msgspec.json.encode( ... User2("bob", groups={"finance"}, phone="512-867-5309") ... ) >>> old_dec.decode(new_msg) # deserializing a new msg with an older decoder User(name='bob', groups={'finance'}, email=None) >>> old_msg = msgspec.json.encode( ... User("alice", groups={"admin", "engineering"}) ... ) >>> new_dec.decode(old_msg) # deserializing an old msg with a new decoder User2(name="alice", groups={"admin", "engineering"}, email=None, phone=None) python-msgspec-0.19.0/docs/source/structs.rst000066400000000000000000001033051473355726200212720ustar00rootroot00000000000000Structs ======= Structs are the preferred way of defining structured data types in ``msgspec``. They're written in C and are quite speedy and lightweight (:doc:`measurably faster ` to create/compare/encode/decode than similar options like dataclasses_, attrs_, or pydantic_). They're great for representing structured data both for serialization and for use in an application. Structs are defined by subclassing from `msgspec.Struct` and annotating the types of individual fields. Default values can also be provided for any optional arguments. Here we define a struct representing a user, with one required field and two optional fields. .. code-block:: python >>> import msgspec >>> from typing import Set, Optional >>> class User(msgspec.Struct): ... """A struct describing a user""" ... name : str ... email : Optional[str] = None ... groups : Set[str] = set() - ``name`` is a *required* field expecting a `str` - ``email`` is an *optional* field expecting a `str` or `None`, defaulting to `None` if no value is provided. - ``groups`` is an *optional* field expecting a `set` of `str`. If no value is provided, it defaults to the empty set. Struct types automatically generate a few methods based on the provided type annotations: - ``__init__`` - ``__repr__`` - ``__copy__`` - ``__replace__`` - ``__eq__`` & ``__ne__`` - ``__match_args__`` (for Python 3.10+'s `pattern matching`_) - ``__rich_repr__`` (for pretty printing support with rich_) .. code-block:: python >>> alice = User("alice", groups={"admin", "engineering"}) >>> alice User(name='alice', email=None, groups={'admin', 'engineering'}) >>> bob = User("bob", email="bob@company.com") >>> bob User(name='bob', email='bob@company.com', groups=set()) >>> alice.name "alice" >>> bob.groups set() >>> alice == bob False >>> alice == User("alice", groups={"admin", "engineering"}) True Note that it is forbidden to override ``__init__``/``__new__`` in a struct definition, but other methods can be overridden or added as needed. If you need to customize the generated ``__init__``, see :ref:`struct-post-init`. The struct fields are available via the ``__struct_fields__`` attribute (a tuple of the fields in argument order ) if you need them. Here we add a method for converting a struct to a dict. .. code-block:: python >>> class Point(msgspec.Struct): ... """A point in 2D space""" ... x : float ... y : float ... ... def to_dict(self): ... return {f: getattr(self, f) for f in self.__struct_fields__} ... >>> p = Point(1.0, 2.0) >>> p.to_dict() {"x": 1.0, "y": 2.0} Default Values -------------- Struct fields may be given default values, which are used if no value is provided to ``__init__``, or when decoding a message. Default values are configured as part of a Struct definition by assigning them after a field's type annotation. .. code-block:: python >>> from msgspec import Struct, field >>> import uuid >>> class Example(Struct): ... a: int = 1 ... b: uuid.UUID = field(default_factory=uuid.uuid4) ... c: list[int] = [] >>> Example() Example(a=1, b=UUID('f63219d5-e9ca-4ae8-afd0-cba30e84222d'), c=[]) >>> Example(a=2) Example(a=2, b=UUID('319a6c0f-2841-4439-8bc8-2c1daf7d77a2'), c=[]) >>> Example().c is Example().c # new list instance used each time False Default values may be one of 3 kinds: - A "static" default value. Here the same default value is used for all instances. These are specified by assigning the default value itself as part of the field definition (as in ``a`` above). Most default values will be of this variety. - A "dynamic" default value. Here a new default value is used for every instance. These are specified by passing a 0-argument callable to the ``default_factory`` argument of `msgspec.field` (as in ``b`` above). This function will be called as needed to create a new default value per instance. These are mainly useful for occasions where you need dynamic defaults, or when a default value is a mutable object that you don't want to share between all instances of the struct (a `common gotcha `_ in Python). Note that since the ``default_factory`` callables take no arguments, you might need to make use of a lambda_ or `functools.partial` to forward any additional parameters needed to the default factory. - Builtin *empty* mutable collections (``[]``, ``{}``, ``set()``, and ``bytearray()``) may be used as default values (as in ``c`` above). Since defaults of these types are so common, these are "syntactic sugar" for specifying the corresponding ``default_factory`` (to avoid accidental sharing of mutable values). A default of ``[]`` is identical to a default of ``field(default_factory=list)``, with a new list instance used each time. Specifying a non-empty mutable collection (e.g. ``[1, 2, 3]``) as a default value will cause the struct definition to error (you should manually define a ``default_factory`` in this case). .. _struct-post-init: Post-Init Processing -------------------- If a struct type defines a ``__post_init__(self)`` method, this will be called at the end of the generated ``__init__`` method. It has the same semantics as the ``dataclasses`` method `of the same name `__. This method may be useful for adding additional logic to the init (such as custom validation). In addition to in ``__init__``, the ``__post_init__`` hook is also called when: - Decoding into a struct type (e.g. ``msgspec.json.decode(..., type=MyStruct)``) - Converting into a struct type (e.g. ``msgspec.convert(..., type=MyStruct)``) In these cases any `TypeError` or `ValueError` exceptions raised by this method will be considered "user facing" and converted into a `msgspec.ValidationError` with additional context. All other exceptions will be raised directly. .. code-block:: python >>> import msgspec >>> class Interval(msgspec.Struct): ... low: float ... high: float ... ... def __post_init__(self): ... if self.low > self.high: ... raise ValueError("`low` may not be greater than `high`") >>> Interval(1, 2) # valid interval Interval(low=1, high=2) >>> Interval(2, 1) # invalid interval Traceback (most recent call last): File "", line 1, in File "", line 6, in __post_init__ ValueError: `low` may not be greater than `high` >>> msgspec.json.decode(b'{"low": 2, "high": 1}', type=Interval) # invalid interval from JSON Traceback (most recent call last): File "", line 6, in __post_init__ ValueError: `low` may not be greater than `high` The above exception was the direct cause of the following exception: Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: `low` may not be greater than `high` .. _struct-field-ordering: Field Ordering -------------- When defining a new struct type, fields are stored in the order they're defined (keyword-only fields excluded, more on this later). This is nice for readability since the generated ``__init__`` matches the field order. .. code-block:: python class Example(msgspec.Struct): a: str b: int = 0 The generated ``__init__()`` for ``User`` looks like: .. code-block:: python def __init__(self, a: str, b: int = 0): One consequence of this is that you can't put fields without defaults after fields with defaults, since the Python VM doesn't allow keyword arguments before positional arguments. The following struct definition will error: .. code-block:: python >>> class Invalid(msgspec.Struct): ... a: str = "" ... b: int # oop, no default! Traceback (most recent call last): File "", line 1, in TypeError: Required field 'b' cannot follow optional fields. Either reorder the struct fields, or set `kw_only=True` in the struct definition. Thankfully the error message includes some solutions: - Reorder the struct fields, putting all required fields before all optional fields. - Set ``kw_only=True`` in the struct definition. This option makes all fields defined on the struct `keyword-only parameters`_. Keyword-only parameters have no such restriction; required and optional parameters can be mixed in any order. .. code-block:: python >>> class Example(msgspec.Struct, kw_only=True): ... a: str = "" ... b: int # this is fine with kw_only=True >>> Example(a="example", b=123) Example(a='example', b=123) Note that the ``kw_only`` setting only affects fields defined on that class, *not* those defined on base or subclasses. This means you can define keyword-only parameters on a base class then add positional parameters in a subclass. All keyword-only parameters are reordered to go after all positional fields. .. code-block:: python >>> class Base(msgspec.Struct, kw_only=True): ... a: str = "" ... b: int >>> class Subclass(Base): ... c: float ... d: bytes = b"" The generated ``__init__()`` for ``Subclass`` looks like: .. code-block:: python def __init__(self, c: float, d: bytes = b"", * a: str, b: int = 0): The field ordering rules for ``Struct`` types are identical to those for `dataclasses`, see the `dataclasses docs `_ for more information. Class Variables --------------- Like `dataclasses`, `msgspec.Struct` types will exclude any attribute annotations wrapped in `typing.ClassVar` from their fields. .. code-block:: python >>> import msgspec >>> from typing import ClassVar >>> class Example(msgspec.Struct): ... x: int ... a_class_variable: ClassVar[int] = 2 >>> Example.a_class_variable 2 >>> Example(1) # only `x` is counted as a field Example(x=1) Note that if using `PEP 563`_ "postponed evaluation of annotations" (e.g. ``from __future__ import annotations``) only the following spellings will work: - ``ClassVar`` or ``ClassVar[]`` - ``typing.ClassVar`` or ``typing.ClassVar[]`` Importing ``ClassVar`` or ``typing`` under an aliased name (e.g. ``import typing as typ`` or ``from typing import ClassVar as CV``) will not be properly detected. Type Validation --------------- Unlike some other libraries (e.g. pydantic_), the type annotations on a `msgspec.Struct` class are not checked at runtime during normal use. Types are only checked when *decoding* a serialized message when using a `typed decoder `. .. code-block:: python >>> import msgspec >>> class Point(msgspec.Struct): ... x: float ... y: float >>> # Improper types in *your* code aren't checked at runtime ... Point(x=1, y="oops") Point(x=1, y='oops') >>> # Improper types when decoding *are* checked at runtime ... msgspec.json.decode(b'{"x": 1.0, "y": "oops"}', type=Point) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `float`, got `str` - at `$.y` This is intentional. Static type checkers like mypy_/pyright_ work well with ``msgspec``, and can be used to catch bugs without ever running your code. When possible, static tools or unit tests should be preferred over adding expensive runtime checks which slow down every ``__init__`` call. The input(s) to your programs however cannot be checked statically, as they aren't known until runtime. As such, ``msgspec`` does perform type validation when decoding messages (provided an expected decode type is provided). This validation is fast enough that it is *negligible in cost* - there is no added performance benefit when not using it. In fact, in most cases it's faster to decode a message into a type validated `msgspec.Struct` than into an untyped `dict`. Pattern Matching ---------------- If using Python 3.10+, `msgspec.Struct` types can be used in `pattern matching`_ blocks. Replicating an example from `PEP 636`_: .. code-block:: python # NOTE: this example requires Python 3.10+ >>> import msgspec >>> class Point(msgspec.Struct): ... x: float ... y: float >>> def where_is(point): ... match point: ... case Point(0, 0): ... print("Origin") ... case Point(0, y): ... print(f"Y={y}") ... case Point(x, 0): ... print(f"X={x}") ... case Point(): ... print("Somewhere else") ... case _: ... print("Not a point") >>> where_is(Point(0, 6)) "Y=6" Equality and Order ------------------ By default struct types define an ``__eq__`` method based on the type definition. This enables support for equality comparisons. Additionally, you may configure ``order=True`` to make a struct type *orderable* through generation of ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` methods. These methods compare and order instances of a struct type the same as if they were tuples of their field values (in definition order). .. code-block:: python >>> class Point(msgspec.Struct, order=True): ... x: float ... y: float >>> Point(1, 2) == Point(1, 2) True >>> Point(1, 2) < Point(3, 4) True In *rare* instances you may opt to disable generation of the ``__eq__`` method by configuring ``eq=False``. Equality checks will then fall back to *identity comparisons*, where the only value a struct instance of that type will compare equal to is itself. .. code-block:: python >>> class Point(msgspec.Struct, eq=False): ... x: float ... y: float >>> p = Point(1, 2) >>> p == Point(1, 2) False >>> p == p # identity comparison only True Frozen Instances ---------------- A struct type can optionally be marked as "frozen" by specifying ``frozen=True``. This disables modifying attributes after initialization, and adds a ``__hash__`` method to the class definition. Note that for the ``__hash__`` to work, all fields on the struct must also be hashable. .. code-block:: python >>> class Point(msgspec.Struct, frozen=True): ... """This struct is immutable & hashable""" ... x: float ... y: float ... >>> p = Point(1.0, 2.0) >>> {p: 1} # frozen structs are hashable, and can be keys in dicts {Point(1.0, 2.0): 1} >>> p.x = 2.0 # frozen structs cannot be modified after creation Traceback (most recent call last): ... AttributeError: immutable type: 'Point' .. _struct-tagged-unions: Tagged Unions ------------- By default a serialized struct only contains information on the *values* present in the struct instance - no information is serialized noting which struct type corresponds to the message. Instead, the user is expected to know the type the message corresponds to, and pass that information appropriately to the decoder. .. code-block:: python >>> import msgspec >>> class Get(msgspec.Struct): ... key: str >>> msg = msgspec.json.encode(Get("my key")) >>> msg # No type information present in the message b'{"key":"my key"}' >>> msgspec.json.decode(msg, type=Get) Get(key='my key') In most cases this works well - schemas are often simple and each value may only correspond to at most one Struct type. However, sometimes you may have a message (or a field in a message) that may contain one of a number of different structured types. In this case we need some way to determine the type of the message from the message itself! ``msgspec`` handles this through the use of `Tagged Unions`_. A new field (the "tag field") is added to the serialized representation of all struct types in the union. Each struct type associates a different value (the "tag") with this field. When the decoder encounters a tagged union it decodes the tag first and uses it to determine the type to use when decoding the rest of the object. This process is efficient and makes determining the type of a serialized message unambiguous. The quickest way to enable tagged unions is to set ``tag=True`` when defining every struct type in the union. In this case ``tag_field`` defaults to ``"type"``, and ``tag`` defaults to the struct class name (e.g. ``"Get"``). .. code-block:: python >>> import msgspec >>> from typing import Union >>> # Pass in ``tag=True`` to tag the structs using the default configuration ... class Get(msgspec.Struct, tag=True): ... key: str >>> class Put(msgspec.Struct, tag=True): ... key: str ... val: str >>> msg = msgspec.json.encode(Get("my key")) >>> msg # "type" is the tag field, "Get" is the tag b'{"type":"Get","key":"my key"}' >>> # Create a decoder for decoding either Get or Put ... dec = msgspec.json.Decoder(Union[Get, Put]) >>> # The tag value is used to determine the message type ... dec.decode(b'{"type": "Put", "key": "my key", "val": "my val"}') Put(key='my key', val='my val') >>> dec.decode(b'{"type": "Get", "key": "my key"}') Get(key='my key') >>> # A tagged union can also contain non-struct types. ... msgspec.json.decode( ... b'123', ... type=Union[Get, Put, int] ... ) 123 If you want to change this behavior to use a different tag field and/or value, you can further configure things through the ``tag_field`` and ``tag`` kwargs. A struct's tagging configuration is determined as follows. - If ``tag`` and ``tag_field`` are ``None`` (the default), or ``tag=False``, then the struct is considered "untagged". The struct is serialized with only its standard fields, and cannot participate in ``Union`` types with other structs. - If either ``tag`` or ``tag_field`` are non-None, then the struct is considered "tagged". The struct is serialized with an additional field (the ``tag_field``) mapping to its corresponding ``tag`` value. It can participate in ``Union`` types with other structs, provided they all share the same ``tag_field`` and have unique ``tag`` values. - If a struct is tagged, ``tag_field`` defaults to ``"type"`` if not provided or inherited. This can be overridden by passing a tag field explicitly (e.g. ``tag_field="kind"``). Note that ``tag_field`` must not conflict with any other field names in the struct, and must be the same for all struct types in a union. - If a struct is tagged, ``tag`` defaults to the class name (e.g. ``"Get"``) if not provided or inherited. This can be overridden by passing a string (or less commonly an integer) value explicitly (e.g. ``tag="get"``). ``tag`` can also be passed a callable that takes the class qualname and returns a valid tag value (e.g. ``tag=str.lower``). Note that tag values must be unique for all struct types in a union, and ``str`` and ``int`` tag types cannot both be used within the same union. If you like subclassing, both ``tag_field`` and ``tag`` are inheritable by subclasses, allowing configuration to be set once on a base class and reused for all struct types you wish to tag. .. code-block:: python >>> import msgspec >>> from typing import Union >>> # Create a base class for tagged structs, where: ... # - the tag field is "op" ... # - the tag is the class name lowercased ... class TaggedBase(msgspec.Struct, tag_field="op", tag=str.lower): ... pass >>> # Use the base class to pass on the configuration ... class Get(TaggedBase): ... key: str >>> class Put(TaggedBase): ... key: str ... val: str >>> msg = msgspec.json.encode(Get("my key")) >>> msg # "op" is the tag field, "get" is the tag b'{"op":"get","key":"my key"}' >>> # Create a decoder for decoding either Get or Put ... dec = msgspec.json.Decoder(Union[Get, Put]) >>> # The tag value is used to determine the message type ... dec.decode(b'{"op": "put", "key": "my key", "val": "my val"}') Put(key='my key', val='my val') >>> dec.decode(b'{"op": "get", "key": "my key"}') Get(key='my key') .. _omit_defaults: Omitting Default Values ----------------------- By default, ``msgspec`` encodes all fields in a Struct type, including optional fields (those configured with a default value). .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct): ... name : str ... email : Optional[str] = None ... groups : Set[str] = set() >>> alice = User("alice") >>> alice # email & groups are using the default values User(name='alice', email=None, groups=set()) >>> msgspec.json.encode(alice) # default values are present in encoded message b'{"name":"alice","email":null,"groups":[]}' If the default values are known on the decoding end (making serializing them redundant), it may be beneficial and desired to omit default values from the encoded message. This can be done by configuring ``omit_defaults=True`` as part of the Struct definition: .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct, omit_defaults=True): ... name : str ... email : Optional[str] = None ... groups : Set[str] = set() >>> alice = User("alice") >>> msgspec.json.encode(alice) # default values are omitted b'{"name":"alice"}' >>> bob = User("bob", email="bob@company.com") >>> msgspec.json.encode(bob) b'{"name":"bob","email":"bob@company.com"}' Omitting defaults reduces the size of the encoded message, and often also improves encoding and decoding performance (since there's less work to do). Note that detection of default values is optimized for performance; in certain situations a default value may still be encoded. For the curious, the current detection logic is as follows: .. code-block:: python >>> def matches_default(value: Any, default: Any) -> bool: ... """Whether a value matches the default for a field""" ... if value is default: ... return True ... if type(value) != type(default): ... return False ... if type(value) in (list, set, dict) and (len(value) == len(default) == 0): ... return True ... return False .. _forbid-unknown-fields: Forbidding Unknown Fields ------------------------- By default ``msgspec`` will skip unknown fields encountered when decoding into ``Struct`` types. This is normally desired, as it allows for :doc:`schema-evolution` and more flexible decoding. One downside is that typos may go unnoticed when decoding ``Struct`` types with optional fields. For example: .. code-block:: python >>> class Example(msgspec.Struct): ... field_one: int ... field_two: bool = False >>> msgspec.json.decode( ... b'{"field_one": 1, "field_twoo": true}', # oops, a typo ... type=Example ... ) Example(field_one=1, field_two=False) In this example, the misspelled ``"field_twoo"`` is ignored since no field with that name exists. Since ``field_two`` has a default value, the default is used and no error is raised for a missing field. To prevent typos like this, you can configure ``forbid_unknown_fields=True`` as part of the struct definition. If this option is enabled, any unknown fields encountered will result in an error. .. code-block:: python >>> class Example(msgspec.Struct, forbid_unknown_fields=True): ... field_one: int ... field_two: bool = False >>> msgspec.json.decode( ... b'{"field_one": 1, "field_twoo": true}', # oops, a typo ... type=Example ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Object contains unknown field `field_twoo` Renaming Fields --------------- Sometimes you want the field name used in the encoded message to differ from the name used by your Python code. Perhaps you want a ``camelCase`` naming convention in your JSON messages, but to use ``snake_case`` field names in Python. ``msgspec`` supports two places for configuring a field's name used for encoding/decoding: **On the field definition** If you're only renaming a few fields, you might find configuring the new names as part of the field definition to be the simplest option. To do this you can use the ``name`` argument in `msgspec.field`. Any fields declared with this option will use the new name for encoding/decoding. .. code-block:: python >>> import msgspec >>> class Example(msgspec.Struct): ... x: int ... y: int ... z: int = msgspec.field(name="field_z") # renamed to "field_z" >>> # Python code uses the original field names ... ex = Example(x=1, y=2, z=3) >>> # Encoded messages use the renamed field names ... msgspec.json.encode(ex) b'{"x":1,"y":2,"field_z":3}' >>> # Decoding also uses the renamed field names ... msgspec.json.decode(b'{"x": 1, "y": 2, "field_z": 3}', type=Example) Example(x=1, y=2, z=3) **On the struct definition** If you're renaming lots of fields (especially if you're renaming them with a naming convention like ``camelCase``), you may wish to make use of the ``rename`` configuration option in the `Struct` definition instead. This can take a few different values: - ``None``: the default, no field renaming (``example_field``) - ``"lower"``: lowercase all fields (``example_field``) - ``"upper"``: uppercase all fields (``EXAMPLE_FIELD``) - ``"camel"``: camelCase all fields (``exampleField``) - ``"pascal"``: PascalCase all fields (``ExampleField``) - A mapping from field names to the renamed names. Field names missing from the mapping will not be renamed. - A callable (signature ``rename(name: str) -> Optional[str]``) to use to rename all field names. Note that ``None`` for a return value indicates the original field name should be used. The renamed field names are used for encoding and decoding only, any python code will still refer to them using their original names. .. code-block:: python >>> import msgspec >>> class Example(msgspec.Struct, rename="camel"): ... """A struct with fields renamed using camelCase""" ... field_one: int ... field_two: str >>> # Python code uses the original field names ... ex = Example(1, field_two="two") >>> # Encoded messages use the renamed field names ... msgspec.json.encode(ex) b'{"fieldOne":1,"fieldTwo":"two"}' >>> # Decoding uses the renamed field names ... msgspec.json.decode(b'{"fieldOne": 3, "fieldTwo": "four"}', type=Example) Example(field_one=3, field_two='four') >>> # Decoding errors also use the renamed field names ... msgspec.json.decode(b'{"fieldOne": 5}', type=Example) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Object missing required field `fieldTwo` If renaming to camelCase, you may run into issues if your field names contain acronyms (e.g. ``FQDN`` in ``setHostnameAsFQDN``). Some JSON style guides prefer to fully-uppercase these components (``FQDN``), but ``msgspec`` has no way to know if a component is an acroynm or not (and so will result in ``Fqdn``). As such, we recommend using an explicit dict mapping for renaming if generating `Struct` types to match an existing API. .. code-block:: python # https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podspec-v1-core # An explicit mapping from python name -> JSON field name v1podspec_names = { ... "service_account_name": "serviceAccountName", "set_hostname_as_fqdn": "setHostnameAsFQDN", ... } # Pass the mapping to `rename` to explicitly rename all fields class V1PodSpec(msgspec.Struct, rename=v1podspec_names): ... service_account_name: str = "" set_hostname_as_fqdn: bool = False ... Note that if both the ``rename`` configuration option and the ``name`` arg to `msgspec.field` are used, names set explicitly via `msgspec.field` take precedence. .. code-block:: python >>> import msgspec >>> class Example(msgspec.Struct, rename="camel"): ... field_x: int ... field_y: int = msgspec.field(name="y") # set explicitly >>> msgspec.json.encode(Example(1, 2)) b'{"fieldX":1,"y":2}' Encoding/Decoding as Arrays --------------------------- By default Struct objects encode the same dicts, with both the keys and values present in the message. .. code-block:: python >>> import msgspec >>> class Point(msgspec.Struct): ... x: int ... y: int >>> msgspec.json.encode(Point(1, 2)) b'{"x":1,"y":2}' If you need higher performance (at the cost of more inscrutable message encoding), you can set ``array_like=True`` on a struct definition. Structs with this option enabled are encoded/decoded as array-like types, removing the field names from the encoded message. This can provide on average another ~2x speedup for decoding (and ~1.5x speedup for encoding). .. code-block:: python >>> class Point2(msgspec.Struct, array_like=True): ... x: int ... y: int >>> msgspec.json.encode(Point2(1, 2)) b'[1,2]' >>> msgspec.json.decode(b'[3,4]', type=Point2) Point2(x=3, y=4) Note that :ref:`struct-tagged-unions` also work with structs with ``array_like=True``. In this case the tag is encoded as the first item in the array, and is used to determine which type in the union to use when decoding. .. code-block:: python >>> import msgspec >>> from typing import Union >>> class Get(msgspec.Struct, tag=True, array_like=True): ... key: str >>> class Put(msgspec.Struct, tag=True, array_like=True): ... key: str ... val: str >>> msgspec.json.encode(Get("my key")) b'["Get","my key"]' >>> msgspec.json.decode( ... b'["Put", "my key", "my val"]', ... type=Union[Get, Put] ... ) Put(key='my key', val='my val') Runtime Definition ------------------ In some cases it can be useful to dynamically generate `msgspec.Struct` classes at runtime. This can be handled through the use of `msgspec.defstruct`, which has a signature similar to `dataclasses.make_dataclass`. See `msgspec.defstruct` for more information. .. code-block:: python >>> import msgspec >>> Point = msgspec.defstruct("Point", [("x", float), ("y", float)]) >>> p = Point(1.0, 2.0) >>> p Point(x=1.0, y=2.0) .. _struct-gc: Disabling Garbage Collection (Advanced) --------------------------------------- .. warning:: This is an advanced optimization, and only recommended for users who fully understand the implications of disabling the GC. Python uses `reference counting`_ to detect when memory can be freed, with a periodic `cyclic garbage collector`_ pass to detect and free cyclic references. Garbage collection (GC) is triggered by the number of uncollected GC-enabled (objects that contain other objects) objects passing a certain threshold. This design means that garbage collection passes often run during code that creates a lot of objects (for example, deserializing a large message). By default, `msgspec.Struct` types will only be tracked if they contain a reference to a tracked object themselves. This means that structs referencing only scalar values (ints, strings, bools, ...) won't contribute to GC load, but structs referencing containers (lists, dicts, structs, ...) will. .. code-block:: python >>> import msgspec >>> from typing import Any >>> import gc >>> class Example(msgspec.Struct): ... x: Any ... y: Any >>> ex1 = Example(1, "two") >>> # ex1 is untracked, since it only references untracked objects ... gc.is_tracked(ex1) False >>> ex2 = Example([1, 2, 3], (4, 5, 6)) >>> # ex2 is tracked, since it references tracked objects ... gc.is_tracked(ex2) True If you *are certain* that your struct types can *never* participate in a reference cycle, you *may* find a :ref:`performance boost ` from setting ``gc=False`` on a struct definition. This boost is tricky to measure in isolation, since it should only result in the garbage collector not running as frequently - an integration benchmark is recommended to determine if this is worthwhile for your workload. A workload is likely to benefit from this optimization in the following situations: - You're allocating a lot of struct objects at once (for example, decoding a large object). Setting ``gc=False`` on these types will reduce the likelihood of a GC pass occurring while decoding, improving application latency. - You have a large number of long-lived struct objects. Setting ``gc=False`` on these types will reduce the load on the GC during collection cycles of later generations. Struct types with ``gc=False`` will never be tracked, even if they reference container types. It is your responsibility to ensure cycles with these objects don't occur, as a cycle containing only ``gc=False`` structs will *never* be collected (leading to a memory leak). .. _type annotations: https://docs.python.org/3/library/typing.html .. _pattern matching: https://docs.python.org/3/reference/compound_stmts.html#the-match-statement .. _PEP 636: https://peps.python.org/pep-0636/ .. _PEP 563: https://peps.python.org/pep-0563/ .. _dataclasses: https://docs.python.org/3/library/dataclasses.html .. _attrs: https://www.attrs.org/en/stable/index.html .. _pydantic: https://pydantic-docs.helpmanual.io/ .. _mypy: https://mypy.readthedocs.io/en/stable/ .. _pyright: https://github.com/microsoft/pyright .. _reference counting: https://en.wikipedia.org/wiki/Reference_counting .. _cyclic garbage collector: https://devguide.python.org/garbage_collector/ .. _tagged unions: https://en.wikipedia.org/wiki/Tagged_union .. _rich: https://rich.readthedocs.io/en/stable/pretty.html .. _keyword-only parameters: https://docs.python.org/3/glossary.html#term-parameter .. _lambda: https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions python-msgspec-0.19.0/docs/source/supported-types.rst000066400000000000000000001441241473355726200227560ustar00rootroot00000000000000Supported Types =============== ``msgspec`` uses Python `type annotations`_ to describe the expected types. Most combinations of the following types are supported (with a few restrictions): **Builtin Types** - `None` - `bool` - `int` - `float` - `str` - `bytes` - `bytearray` - `tuple` / `typing.Tuple` - `list` / `typing.List` - `dict` / `typing.Dict` - `set` / `typing.Set` - `frozenset` / `typing.FrozenSet` **Msgspec types** - `msgspec.msgpack.Ext` - `msgspec.Raw` - `msgspec.UNSET` - `msgspec.Struct` types **Standard Library Types** - `datetime.datetime` - `datetime.date` - `datetime.time` - `datetime.timedelta` - `uuid.UUID` - `decimal.Decimal` - `enum.Enum` types - `enum.IntEnum` types - `enum.StrEnum` types - `enum.Flag` types - `enum.IntFlag` types - `dataclasses.dataclass` types **Typing module types** - `typing.Any` - `typing.Optional` - `typing.Union` - `typing.Literal` - `typing.NewType` - `typing.Final` - `typing.TypeAliasType` - `typing.TypeAlias` - `typing.NamedTuple` / `collections.namedtuple` - `typing.TypedDict` - `typing.Generic` - `typing.TypeVar` **Abstract types** - `collections.abc.Collection` / `typing.Collection` - `collections.abc.Sequence` / `typing.Sequence` - `collections.abc.MutableSequence` / `typing.MutableSequence` - `collections.abc.Set` / `typing.AbstractSet` - `collections.abc.MutableSet` / `typing.MutableSet` - `collections.abc.Mapping` / `typing.Mapping` - `collections.abc.MutableMapping` / `typing.MutableMapping` **Third-Party Libraries** - attrs_ types Additional types may be supported through :doc:`extensions `. Note that except where explicitly stated, subclasses of these types are not supported by default (see :doc:`extending` for how to add support yourself). Here we document how msgspec maps Python objects to/from the various supported protocols. ``None`` -------- `None` maps to the ``null`` value in all supported protocols. Note that TOML_ lacks a ``null`` value, attempted to encode a message containing ``None`` to ``TOML`` will result in an error. .. code-block:: python >>> msgspec.json.encode(None) b'null' >>> msgspec.json.decode(b'null') None If ``strict=False`` is specified, a string value of ``"null"`` (case insensitive) may also be coerced to ``None``. See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b'"null"', type=None, strict=False) None ``bool`` -------- Booleans map to their corresponding ``true``/``false`` values in both all supported protocols. .. code-block:: python >>> msgspec.json.encode(True) b'true' >>> msgspec.json.decode(b'true') True If ``strict=False`` is specified, values of ``"true"``/``"1"``/``1`` or ``"false"``/``"0"``/``0`` (case insensitive for strings) may also be coerced to ``True``/``False`` respectively. See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b'"false"', type=bool, strict=False) False >>> msgspec.json.decode(b'"TRUE"', type=bool, strict=False) True >>> msgspec.json.decode(b'1', type=bool, strict=False) True ``int`` ------- Integers map to integers in all supported protocols. Support for large integers varies by protocol: - ``msgpack`` only supports encoding/decoding integers within ``[-2**63, 2**64 - 1]``, inclusive. - ``json``, ``yaml``, and ``toml`` have no restrictions on encode or decode. .. code-block:: python >>> msgspec.json.encode(123) b"123" >>> msgspec.json.decode(b"123", type=int) 123 If ``strict=False`` is specified, string values may also be coerced to integers, following the same restrictions as above. Likewise floats that have an exact integer representation (i.e. no decimal component) may also be coerced as integers. See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b'"123"', type=int, strict=False) 123 >>> msgspec.json.decode(b'123.0', type=int, strict=False) 123 ``float`` --------- Floats map to floats in all supported protocols. Note that per RFC8259_, JSON doesn't support nonfinite numbers (``nan``, ``infinity``, ``-infinity``); ``msgspec.json`` handles this by encoding these values as ``null``. The ``msgpack``, ``toml``, and ``yaml`` protocols lack this restriction, and can accurately roundtrip any IEEE754 64 bit floating point value. For all protocols, if a `float` type is specified and an `int` value is provided, the `int` will be automatically converted. .. code-block:: python >>> msgspec.json.encode(123.0) b"123.0" >>> # JSON doesn't support nonfinite values, these serialize as null ... msgspec.json.encode(float("nan")) b"null" >>> msgspec.json.decode(b"123.0", type=float) 123.0 >>> # Ints are automatically converted to floats ... msgspec.json.decode(b"123", type=float) 123.0 If ``strict=False`` is specified, string values may also be coerced to floats. Note that in this case the strings ``"nan"``, ``"inf"``/``"infinity"``, ``"-inf"``/``"-infinity"`` (case insensitive) will coerce to ``nan``/``inf``/``-inf``. See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b'"123.45"', type=float, strict=False) 123.45 >>> msgspec.json.decode(b'"-inf"', type=float, strict=False) -inf ``str`` ------- Strings map to strings in all supported protocols. Note that for JSON, only the characters required by RFC8259_ are escaped to ascii; unicode characters (e.g. ``"𝄞"``) are *not* escaped and are serialized directly as UTF-8 bytes. .. code-block:: python >>> msgspec.json.encode("Hello, world!") b'"Hello, world!"' >>> msgspec.json.encode("𝄞 is not escaped") b'"\xf0\x9d\x84\x9e is not escaped"' >>> msgspec.json.decode(b'"Hello, world!"') "Hello, world!" ``bytes`` / ``bytearray`` / ``memoryview`` ------------------------------------------ Bytes-like objects map to base64-encoded strings in JSON, YAML, and TOML. The ``bin`` type is used for MessagePack. .. code-block:: python >>> msg = msgspec.json.encode(b"\xf0\x9d\x84\x9e") >>> msg b'"85+Eng=="' >>> msgspec.json.decode(msg, type=bytes) b'\xf0\x9d\x84\x9e' >>> msgspec.json.decode(msg, type=bytearray) bytearray(b'\xf0\x9d\x84\x9e') .. note:: For the ``msgpack`` protocol, `memoryview` objects will be decoded as direct views into the larger buffer containing the input message being decoded. This may be useful for implementing efficient zero-copy handling of large binary messages, but is also a potential footgun. As long as a decoded ``memoryview`` remains in memory, the input message buffer will also be persisted, potentially resulting in unnecessarily large memory usage. The usage of ``memoryview`` types in this manner is considered an advanced topic, and should only be used when you know their usage will result in a performance benefit. For all other protocols `memoryview` objects will still result in a copy, and will likely be slightly slower than decoding into a `bytes` object ``datetime`` ------------ The encoding used for `datetime.datetime` objects depends on both the protocol and whether these objects are timezone-aware_ or timezone-naive: - **JSON**: Timezone-aware datetimes are encoded as RFC3339_ compatible strings. Timezone-naive datetimes are encoded the same, but lack the timezone component (making them not strictly RFC3339_ compatible, but still ISO8601_ compatible). - **MessagePack**: Timezone-aware datetimes are encoded using the `timestamp extension`. Timezone-naive datetimes are encoded the same, but lack the timezone component (making them not strictly RFC3339_ compatible, but still ISO8601_ compatible). During decoding, both string and timestamp-extension values are supported for flexibility. - **YAML**: Datetimes are encoded using YAML's native datetime type. Both timezone-aware and timezone-naive datetimes are supported. - **TOML**: Datetimes are encoded using TOML's native datetime type. Both timezone-aware and timezone-naive datetimes are supported. Note that you can require a `datetime.datetime` object to be timezone-aware or timezone-naive by specifying a ``tz`` constraint (see :ref:`datetime-constraints` for more information). .. code-block:: python >>> import datetime >>> tz = datetime.timezone(datetime.timedelta(hours=6)) >>> tz_aware = datetime.datetime(2021, 4, 2, 18, 18, 10, 123, tzinfo=tz) >>> msg = msgspec.json.encode(tz_aware) >>> msg b'"2021-04-02T18:18:10.000123+06:00"' >>> msgspec.json.decode(msg, type=datetime.datetime) datetime.datetime(2021, 4, 2, 18, 18, 10, 123, tzinfo=datetime.timezone(datetime.timedelta(seconds=21600))) >>> tz_naive = datetime.datetime(2021, 4, 2, 18, 18, 10, 123) >>> msg = msgspec.json.encode(tz_naive) >>> msg b'"2021-04-02T18:18:10.000123"' >>> msgspec.json.decode(msg, type=datetime.datetime) datetime.datetime(2021, 4, 2, 18, 18, 10, 123) >>> msgspec.json.decode(b'"oops"', type=datetime.datetime) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid RFC3339 encoded datetime Additionally, if ``strict=False`` is specified, all protocols will decode ints, floats, or strings containing ints/floats as timezone-aware datetimes, interpreting the value as seconds since the epoch in UTC (a `Unix Timestamp `__). See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b"1617405490.000123", type=datetime.datetime) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `datetime`, got `float` >>> msgspec.json.decode(b"1617405490.000123", type=datetime.datetime, strict=False) datetime.datetime(2021, 4, 2, 18, 18, 10, 123, tzinfo=datetime.timezone.utc) ``date`` -------- `datetime.date` values map to: - **JSON**: RFC3339_ encoded strings - **MessagePack**: RFC3339_ encoded strings - **YAML**: YAML's native date type - **TOML** TOML's native date type .. code-block:: python >>> import datetime >>> date = datetime.date(2021, 4, 2) >>> msg = msgspec.json.encode(date) >>> msg b'"2021-04-02"' >>> msgspec.json.decode(msg, type=datetime.date) datetime.date(2021, 4, 2) >>> msgspec.json.decode(b'"oops"', type=datetime.date) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid RFC3339 encoded date ``time`` -------- The encoding used for `datetime.time` objects is dependent on both the protocol and whether these objects are timezone-aware_ or timezone-naive: - **JSON**, **MessagePack**, and **YAML**: Timezone-aware times are encoded as RFC3339_ compatible strings. Timezone-naive times are encoded the same, but lack the timezone component (making them not strictly RFC3339_ compatible, but still ISO8601_ compatible). - **TOML**: Timezone-naive times are encoded using TOML's native time type. Timezone-aware times aren't supported. Note that you can require a `datetime.time` object to be timezone-aware or timezone-naive by specifying a ``tz`` constraint (see :ref:`datetime-constraints` for more information). .. code-block:: python >>> import datetime >>> tz = datetime.timezone(datetime.timedelta(hours=6)) >>> tz_aware = datetime.time(18, 18, 10, 123, tzinfo=tz) >>> msg = msgspec.json.encode(tz_aware) >>> msg b'"18:18:10.000123+06:00"' >>> msgspec.json.decode(msg, type=datetime.time) datetime.time(18, 18, 10, 123, tzinfo=datetime.timezone(datetime.timedelta(seconds=21600))) >>> tz_naive = datetime.time(18, 18, 10, 123) >>> msg = msgspec.json.encode(tz_naive) >>> msg b'"18:18:10.000123"' >>> msgspec.json.decode(msg, type=datetime.time) datetime.time(18, 18, 10, 123) >>> msgspec.json.decode(b'"oops"', type=datetime.time) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid RFC3339 encoded time ``timedelta`` ------------- `datetime.timedelta` values map to extended `ISO 8601 duration strings`_ in all protocols. The format as described in the ISO specification is fairly lax and a bit underspecified, leading most real-world implementations to implement a stricter subset. The duration format used here is as follows: .. code-block:: text [+/-]P[#D][T[#H][#M][#S]] - The format starts with an optional sign (``-`` or ``+``). If negative, the whole duration is negated. - The letter ``P`` follows (case insensitive) - There are then four segments, each consisting of a number and unit. The units are ``D``, ``H``, ``M``, ``S`` (case insensitive) for days, hours, minutes, and seconds respectively. These segments must occur in this order. - If a segment would have a 0 value it may be omitted, with the caveat that at least one segment must be present. - If a time (hour, minute, or second) segment is present then the letter ``T`` (case insensitive) must precede the first time segment. Likewise if a ``T`` is present, there must be at least 1 segment after the ``T``. - Each segment is composed of 1 or more digits, followed by the unit. Leading 0s are accepted. The *final* segment may include a decimal component if needed. A few examples: .. code-block:: python "P0D" # 0 days "P1D" # 1 Day "PT1H30S" # 1 Hour and 30 minutes "PT1.5H" # 1 Hour and 30 minutes "-PT1M30S" # -90 seconds "PT1H30M25.5S" # 1 Hour, 30 minutes, and 25.5 seconds While msgspec will decode duration strings making use of the ``H`` (hour) or ``M`` (minute) units, durations encoded by msgspec will only consist of ``D`` (day) and ``S`` (second) segments. The implementation in ``msgspec`` is compatible with the ones in: - Java's ``time.Duration.parse`` (`docs `__) - Javascript's proposed ``Temporal.Duration`` standard API (`docs `__) - Python libraries like pendulum_ or pydantic_. Duration strings produced by msgspec should be interchangeable with these libraries, as well as similar ones in other language ecosystems. .. code-block:: python >>> from datetime import timedelta >>> msgspec.json.encode(timedelta(seconds=123)) b'"PT123S"' >>> msgspec.json.encode(timedelta(days=1, seconds=30, microseconds=123)) b'"P1DT30.000123S"' >>> msgspec.json.decode(b'"PT123S"', type=timedelta) datetime.timedelta(seconds=123) >>> msgspec.json.decode(b'"PT1.5M"', type=timedelta) datetime.timedelta(seconds=90) >>> msgspec.json.decode(b'"oops"', type=datetime.timedelta) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid ISO8601 duration Additionally, if ``strict=False`` is specified, all protocols will decode ints, floats, or strings containing ints/floats as timedeltas, interpreting the value as total seconds. See :ref:`strict-vs-lax` for more information. .. code-block:: python >>> msgspec.json.decode(b"123.4", type=datetime.timedelta) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `duration`, got `float` >>> msgspec.json.decode(b"123.4", type=datetime.timedelta, strict=False) datetime.timedelta(seconds=123, microseconds=400000) ``uuid`` -------- `uuid.UUID` values are serialized as RFC4122_ encoded canonical strings in all protocols by default. Subclasses of `uuid.UUID` are also supported for encoding only. .. code-block:: python >>> import uuid >>> u = uuid.UUID("c4524ac0-e81e-4aa8-a595-0aec605a659a") >>> msgspec.json.encode(u) b'"c4524ac0-e81e-4aa8-a595-0aec605a659a"' >>> msgspec.json.decode(b'"c4524ac0-e81e-4aa8-a595-0aec605a659a"', type=uuid.UUID) UUID('c4524ac0-e81e-4aa8-a595-0aec605a659a') >>> msgspec.json.decode(b'"oops"', type=uuid.UUID) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid UUID Alternative formats are also supported by the JSON and MessagePack encoders. The format may be selected by passing it to ``uuid_format`` when creating an ``Encoder``. The following options are supported: - ``canonical``: UUIDs are encoded as RFC4122_ canonical strings (same as ``str(uuid)``). This is the default. - ``hex``: UUIDs are encoded as RFC4122_ hex strings (same as ``uuid.hex``). - ``bytes``: UUIDs are encoded as binary values of the uuid's big-endian 128-bit integer representation (same as ``uuid.bytes``). This is only supported by the MessagePack encoder. When decoding, any of the above formats are accepted. .. code-block:: python >>> enc = msgspec.json.Encoder(uuid_format="hex") >>> uuid_hex = enc.encode(u) >>> uuid_hex b'"c4524ac0e81e4aa8a5950aec605a659a"' >>> msgspec.json.decode(uuid_hex, type=uuid.UUID) UUID('c4524ac0-e81e-4aa8-a595-0aec605a659a') >>> enc = msgspec.msgpack.Encoder(uuid_format="bytes") >>> uuid_bytes = enc.encode(u) >>> msgspec.msgpack.decode(uuid_bytes, type=uuid.UUID) UUID('c4524ac0-e81e-4aa8-a595-0aec605a659a') ``decimal`` ----------- `decimal.Decimal` values are encoded as their string representation in all protocols by default. This ensures no precision loss during serialization, as would happen with a float representation. .. code-block:: python >>> import decimal >>> x = decimal.Decimal("1.2345") >>> msg = msgspec.json.encode(x) >>> msg b'"1.2345"' >>> msgspec.json.decode(msg, type=decimal.Decimal) Decimal('1.2345') >>> msgspec.json.decode(b'"oops"', type=decimal.Decimal) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid decimal string For JSON and MessagePack you may instead encode decimal values the same as numbers by creating a ``Encoder`` and specifying ``decimal_format='number'``. .. code-block:: python >>> encoder = msgspec.json.Encoder(decimal_format="number") >>> encoder.encode(x) b'1.2345' This setting is not yet supported for YAML or TOML - if this option is important for you please `open an issue`_. All protocols will also decode `decimal.Decimal` values from ``int`` or ``float`` inputs. For JSON the value is parsed directly from the serialized bytes, avoiding any precision loss: .. code-block:: python >>> msgspec.json.decode(b"1.3", type=decimal.Decimal) Decimal('1.3') >>> msgspec.json.decode(b"1.300", type=decimal.Decimal) Decimal('1.300') >>> msgspec.json.decode(b"0.1234567891234567811", type=decimal.Decimal) Decimal('0.1234567891234567811') Other protocols will coerce float inputs to the shortest decimal value that roundtrips back to the corresponding IEEE754 float representation (this is effectively equivalent to ``decimal.Decimal(str(float_val))``). This may result in precision loss for some inputs! In general we recommend avoiding parsing `decimal.Decimal` values from anything but strings. .. code-block:: python >>> msgspec.yaml.decode(b"1.3", type=decimal.Decimal) Decimal('1.3') >>> msgspec.yaml.decode(b"1.300", type=decimal.Decimal) # trailing 0s truncated! Decimal('1.3') >>> msgspec.yaml.decode(b"0.1234567891234567811", type=decimal.Decimal) # precision loss! Decimal('0.12345678912345678') ``list`` / ``tuple`` / ``set`` / ``frozenset`` ---------------------------------------------- `list`, `tuple`, `set`, and `frozenset` objects map to arrays in all protocols. An error is raised if the elements don't match the specified element type (if provided). Subclasses of these types are also supported for encoding only. To decode into a ``list`` subclass you'll need to implement a ``dec_hook`` (see :doc:`extending`). .. code-block:: python >>> msgspec.json.encode([1, 2, 3]) b'[1,2,3]' >>> msgspec.json.encode({1, 2, 3}) b'[1,2,3]' >>> msgspec.json.decode(b'[1,2,3]', type=set) {1, 2, 3} >>> from typing import Set >>> # Decode as a set of ints ... msgspec.json.decode(b'[1, 2, 3]', type=Set[int]) {1, 2, 3} >>> # Oops, all elements should be ints ... msgspec.json.decode(b'[1, 2, "oops"]', type=Set[int]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[2]` ``NamedTuple`` -------------- `typing.NamedTuple` types map to arrays in all protocols. An error is raised during decoding if the type doesn't match or if any required fields are missing. Note that ``msgspec`` supports both `typing.NamedTuple` and `collections.namedtuple`, although the latter lacks a way to specify field types. When possible we recommend using `msgspec.Struct` (possibly with ``array_like=True`` and ``frozen=True``) instead of ``NamedTuple`` for specifying schemas - :doc:`structs` are faster, more ergonomic, and support additional features. Still, you may want to use a ``NamedTuple`` if you're already using them elsewhere, or if you have downstream code that requires a ``tuple`` instead of an object. .. code-block:: python >>> from typing import NamedTuple >>> class Person(NamedTuple): ... name: str ... age: int >>> ben = Person("ben", 25) >>> msg = msgspec.json.encode(ben) >>> msgspec.json.decode(msg, type=Person) Person(name='ben', age=25) >>> wrong_type = b'["chad", "twenty"]' >>> msgspec.json.decode(wrong_type, type=Person) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[1]` Other types that duck-type as ``NamedTuple`` (for example `edgedb NamedTuples `__) are also supported. .. code-block:: python >>> import edgedb >>> client = edgedb.create_client() >>> alice = client.query_single( ... "SELECT (name := 'Alice', dob := '1984-03-01')" ... ) >>> alice (name := 'Alice', dob := datetime.date(1984, 3, 1)) >>> msgspec.json.encode(alice) b'["Alice","1984-03-01"]' ``dict`` -------- Dicts encode/decode as objects/maps in all protocols. Dict subclasses (`collections.OrderedDict`, for example) are also supported for encoding only. To decode into a ``dict`` subclass you'll need to implement a ``dec_hook`` (see :doc:`extending`). JSON and TOML only support key types that encode as strings or numbers (for example `str`, `int`, `float`, `enum.Enum`, `datetime.datetime`, `uuid.UUID`, ...). MessagePack and YAML support any hashable for the key type. An error is raised during decoding if the keys or values don't match their respective types (if specified). .. code-block:: python >>> msgspec.json.encode({"x": 1, "y": 2}) b'{"x":1,"y":2}' >>> from typing import Dict >>> # Decode as a Dict of str -> int ... msgspec.json.decode(b'{"x":1,"y":2}', type=Dict[str, int]) {"x": 1, "y": 2} >>> # Oops, there's a mistyped value ... msgspec.json.decode(b'{"x":1,"y":"oops"}', type=Dict[str, int]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[...]` ``TypedDict`` ------------- `typing.TypedDict` provides a way to specify different types for different values in a ``dict``, rather than a single value type (the ``int`` in ``Dict[str, int]``, for example). At runtime these are just standard ``dict`` types, the ``TypedDict`` type is only there to provide the schema information during decoding. Note that ``msgspec`` supports both `typing.TypedDict` and ``typing_extensions.TypedDict`` (a backport). `typing.TypedDict` types map to objects/maps in all protocols. During decoding, any extra fields are ignored. An error is raised during decoding if the type doesn't match or if any required fields are missing. When possible we recommend using `msgspec.Struct` instead of ``TypedDict`` for specifying schemas - :doc:`structs` are faster, more ergonomic, and support additional features. Still, you may want to use a ``TypedDict`` if you're already using them elsewhere, or if you have downstream code that requires a ``dict`` instead of an object. .. code-block:: python >>> from typing import TypedDict >>> class Person(TypedDict): ... name: str ... age: int >>> ben = {"name": "ben", "age": 25} >>> msg = msgspec.json.encode(ben) >>> msgspec.json.decode(msg, type=Person) {'name': 'ben', 'age': 25} >>> wrong_type = b'{"name": "chad", "age": "twenty"}' >>> msgspec.json.decode(wrong_type, type=Person) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$.age` ``dataclasses`` --------------- `dataclasses` map to objects/maps in all protocols. During decoding, any extra fields are ignored. An error is raised if a field's type doesn't match or if any required fields are missing. If a ``__post_init__`` method is defined on the dataclass, it is called after the object is decoded. Note that `"Init-only parameters" `__ (i.e. ``InitVar`` fields) are _not_ supported. When possible we recommend using `msgspec.Struct` instead of dataclasses for specifying schemas - :doc:`structs` are faster, more ergonomic, and support additional features. .. code-block:: python >>> from dataclasses import dataclass >>> @dataclass ... class Person: ... name: str ... age: int >>> carol = Person(name="carol", age=32) >>> msg = msgspec.json.encode(carol) >>> msgspec.json.decode(msg, type=Person) Person(name='carol', age=32) >>> wrong_type = b'{"name": "doug", "age": "thirty"}' >>> msgspec.json.decode(wrong_type, type=Person) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$.age` Other types that duck-type as ``dataclasses`` (for example `edgedb Objects `__ or `pydantic dataclasses `__) are also supported. .. code-block:: python >>> import edgedb >>> client = edgedb.create_client() >>> alice = client.query_single( ... "SELECT User {name, dob} FILTER .name = $name LIMIT 1", ... name="Alice" ... ) >>> alice Object{name := 'Alice', dob := datetime.date(1984, 3, 1)} >>> msgspec.json.encode(alice) b'{"id":"a6b951cc-2d00-11ee-91aa-b3f17e9898ce","name":"Alice","dob":"1984-03-01"}' For a more complete example using EdgeDB, see :doc:`examples/edgedb`. ``attrs`` --------- attrs_ types map to objects/maps in all protocols. During encoding, all attributes without a leading underscore (``"_"``) are encoded. During decoding, any extra fields are ignored. An error is raised if a field's type doesn't match or if any required fields are missing. If the ``__attrs_pre_init__`` or ``__attrs_post_init__`` methods are defined on the class, they are called as part of the decoding process. Likewise, if a class makes use of attrs' `validators `__, the validators will be called, and a `msgspec.ValidationError` raised on error. Note that attrs' `converters `__ are not currently supported. When possible we recommend using `msgspec.Struct` instead of attrs_ types for specifying schemas - :doc:`structs` are faster, more ergonomic, and support additional features. .. code-block:: python >>> from attrs import define >>> @define ... class Person: ... name: str ... age: int >>> carol = Person(name="carol", age=32) >>> msg = msgspec.json.encode(carol) >>> msgspec.json.decode(msg, type=Person) Person(name='carol', age=32) >>> wrong_type = b'{"name": "doug", "age": "thirty"}' >>> msgspec.json.decode(wrong_type, type=Person) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$.age` ``Struct`` ---------- Structs are the preferred way of defining structured data types in ``msgspec``. You can think of them as similar to dataclasses_/attrs_/pydantic_, but much faster to create/compare/encode/decode. For more information, see the :doc:`structs` page. By default `msgspec.Struct` types map to objects/maps in all protocols. During decoding, any unknown fields are ignored (this can be disabled, see :ref:`forbid-unknown-fields`), and any missing optional fields have their default values applied. An error is raised during decoding if the type doesn't match or if any required fields are missing. .. code-block:: python >>> from typing import Set, Optional >>> class User(msgspec.Struct): ... name: str ... groups: Set[str] = set() ... email: Optional[str] = None >>> alice = User("alice", groups={"admin", "engineering"}) >>> msgspec.json.encode(alice) b'{"name":"alice","groups":["admin","engineering"],"email":null}' >>> msg = b""" ... { ... "name": "bob", ... "email": "bob@company.com", ... "unknown_field": [1, 2, 3] ... } ... """ >>> msgspec.json.decode(msg, type=User) User(name='bob', groups=[], email="bob@company.com") >>> wrong_type = b""" ... { ... "name": "bob", ... "groups": ["engineering", 123] ... } ... """ >>> msgspec.json.decode(wrong_type, type=User) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str`, got `int` - at `$.groups[1]` If you pass ``array_like=True`` when defining the struct type, they're instead treated as array types during encoding/decoding. In this case fields are serialized in their :ref:`field order `. This can further improve performance at the cost of less human readable messaging. Like ``array_like=False`` (the default) structs, extra (trailing) fields are ignored during decoding, and any missing optional fields have their defaults applied. Type checking also still applies. .. code-block:: python >>> from typing import Set, Optional >>> class User(msgspec.Struct, array_like=True): ... name: str ... groups: Set[str] = set() ... email: Optional[str] = None >>> alice = User("alice", groups={"admin", "engineering"}) >>> msgspec.json.encode(alice) b'["alice",["admin","engineering"],null]' >>> msgspec.json.decode(b'["bob"]', type=User) User(name="bob", groups=[], email=None) >>> msgspec.json.decode(b'["carol", ["admin"], null, ["extra", "field"]]', type=User) User(name="carol", groups=["admin"], email=None) >>> msgspec.json.decode(b'["david", ["finance", 123]]') Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str`, got `int` - at `$[1][1]` .. _unset-type: ``UNSET`` --------- `msgspec.UNSET` is a singleton object used to indicate that a field has no set value. This is useful for cases where you need to differentiate between a message where a field is missing and a message where the field is explicitly ``None``. .. code-block:: python >>> from msgspec import Struct, UnsetType, UNSET, json >>> class Example(Struct): ... x: int ... y: int | None | UnsetType = UNSET # a field, defaulting to UNSET During encoding, any field containing ``UNSET`` is omitted from the message. .. code-block:: python >>> json.encode(Example(1)) # y is UNSET b'{"x":1}' >>> json.encode(Example(1, UNSET)) # y is UNSET b'{"x":1}' >>> json.encode(Example(1, None)) # y is None b'{"x":1,"y":null}' >>> json.encode(Example(1, 2)) # y is 2 b'{"x":1,"y":2}' During decoding, if a field isn't explicitly set in the message, the default value of ``UNSET`` will be set instead. This lets downstream consumers determine whether a field was left unset, or explicitly set to ``None`` .. code-block:: python >>> json.decode(b'{"x": 1}', type=Example) # y defaults to UNSET Example(x=1, y=UNSET) >>> json.decode(b'{"x": 1, "y": null}', type=Example) # y is None Example(x=1, y=None) >>> json.decode(b'{"x": 1, "y": 2}', type=Example) # y is 2 Example(x=1, y=2) ``UNSET`` fields are supported for `msgspec.Struct`, `dataclasses`, and attrs_ types. It is an error to use `msgspec.UNSET` or `msgspec.UnsetType` anywhere other than a field for one of these types. ``Enum`` / ``IntEnum`` / ``StrEnum`` ------------------------------------ Enum types (`enum.Enum`, `enum.IntEnum`, `enum.StrEnum`, ...) encode as their member *values* in all protocols. Any enum whose *value* is a supported type may be encoded, but only enums composed of all string or all integer values may be decoded. An error is raised during decoding if the value isn't the proper type, or doesn't match any valid member. .. code-block:: python >>> import enum >>> class Fruit(enum.Enum): ... APPLE = "apple" ... BANANA = "banana" >>> msgspec.json.encode(Fruit.APPLE) b'"apple"' >>> msgspec.json.decode(b'"apple"', type=Fruit) >>> msgspec.json.decode(b'"grape"', type=Fruit) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid enum value 'grape' >>> class JobState(enum.IntEnum): ... CREATED = 0 ... RUNNING = 1 ... SUCCEEDED = 2 ... FAILED = 3 >>> msgspec.json.encode(JobState.RUNNING) b'1' >>> msgspec.json.decode(b'2', type=JobState) >>> msgspec.json.decode(b'4', type=JobState) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid enum value 4 If the enum type includes a ``_missing_`` method (`docs `__), this method will be called to handle any missing values. It should return a valid enum member, or ``None`` if the value is invalid. One potential use case of this is supporting case-insensitive enums: .. code-block:: python >>> import enum >>> class Fruit(enum.Enum): ... APPLE = "apple" ... BANANA = "banana" ... ... @classmethod ... def _missing_(cls, name): ... """Called to handle missing enum values""" ... # Normalize value to lowercase ... value = name.lower() ... # Return valid enum value, or None if invalid ... return cls._value2member_map_.get(value) >>> msgspec.json.decode(b'"apple"', type=Fruit) >>> msgspec.json.decode(b'"ApPlE"', type=Fruit) >>> msgspec.json.decode(b'"grape"', type=Fruit) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid enum value 'grape' ``Literal`` ----------- `typing.Literal` types can be used to ensure that a decoded object is within a set of valid values. An `enum.Enum` or `enum.IntEnum` can be used for the same purpose, but with a `typing.Literal` the decoded values are literal `int` or `str` instances rather than `enum` objects. A literal can be composed of any of the following objects: - `None` - `int` values - `str` values - Nested `typing.Literal` types An error is raised during decoding if the value isn't in the set of valid values, or doesn't match any of their component types. .. code-block:: python >>> from typing import Literal >>> msgspec.json.decode(b'1', type=Literal[1, 2, 3]) 1 >>> msgspec.json.decode(b'"one"', type=Literal["one", "two", "three"]) 'one' >>> msgspec.json.decode(b'4', type=Literal[1, 2, 3]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Invalid enum value 4 >>> msgspec.json.decode(b'"bad"', type=Literal[1, 2, 3]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` ``NewType`` ----------- `typing.NewType` types are treated identically to their base type. Their support here is purely to aid static analysis tools like mypy_ or pyright_. .. code-block:: python >>> from typing import NewType >>> UserId = NewType("UserId", int) >>> msgspec.json.encode(UserId(1234)) b'1234' >>> msgspec.json.decode(b'1234', type=UserId) 1234 >>> msgspec.json.decode(b'"oops"', type=UserId) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` Type Aliases ------------ For complex types, sometimes it can be nice to write the type once so you can reuse it later. .. code-block:: python Point = tuple[float, float] Here ``Point`` is a "type alias" for ``tuple[float, float]`` - ``msgspec`` will substitute in ``tuple[float, float]`` whenever the ``Point`` type is used in an annotation. ``msgspec`` supports the following equivalent forms: .. code-block:: python # Using variable assignment Point = tuple[float, float] # Using variable assignment, annotated as a `TypeAlias` Point: TypeAlias = tuple[float, float] # Using Python 3.12's new `type` statement. This only works on Python 3.12+ type Point = tuple[float, float] To learn more about Type Aliases, see Python's `Type Alias docs here `__. Generic Types ------------- ``msgspec`` supports generic types, including `user-defined generic types`_ based on any of the following types: - `msgspec.Struct` - `dataclasses` - `attrs` - `typing.TypedDict` - `typing.NamedTuple` Generic types may be useful for reusing common message structures. To define a generic type: - Define one or more type variables (`typing.TypeVar`) to parametrize your type with. - Add `typing.Generic` as a base class when defining your type, parametrizing it by the relevant type variables. - When annotating the field types, use the relevant type variables instead of "concrete" types anywhere you want to be generic. For example, here we define a generic ``Paginated`` struct type for storing extra pagination information in an API response. .. code-block:: python import msgspec from typing import Generic, TypeVar # A type variable for the item type T = TypeVar("T") class Paginated(msgspec.Struct, Generic[T]): """A generic paginated API wrapper, parametrized by the item type.""" page: int # The current page number per_page: int # Number of items per page total: int # The total number of items found items: list[T] # Items returned, up to `per_page` in length This type is generic over the type of item contained in ``Paginated.items``. This ``Paginated`` wrapper may then be used to decode a message containing a specific item type by parametrizing it with that type. When processing a generic type, the parametrized types are substituted for the type variables. Here we define a ``User`` type, then use it to decode a paginated API response containing a list of users: .. code-block:: python class User(msgspec.Struct): """A user model""" name: str groups: list[str] = [] json_str = """ { "page": 1, "per_page": 5, "total": 252, "items": [ {"name": "alice", "groups": ["admin"]}, {"name": "ben"}, {"name": "carol", "groups": ["engineering"]}, {"name": "dan", "groups": ["hr"]}, {"name": "ellen", "groups": ["engineering"]} ] } """ # Decode a paginated response containing a list of users msg = msgspec.json.decode(json_str, type=Paginated[User]) print(msg) #> Paginated( #> page=1, per_page=5, total=252, #> items=[ #> User(name='alice', groups=['admin']), #> User(name='ben', groups=[]), #> User(name='carol', groups=['engineering']), #> User(name='dan', groups=['hr']), #> User(name='ellen', groups=['engineering']) #> ] #> ) If instead we wanted to decode a paginated response of another type (say ``Team``), we could do this by parametrizing ``Paginated`` with a different type. .. code-block:: python # Decode a paginated response containing a list of teams msgspec.json.decode(some_other_message, type=Paginated[Team]) Any unparametrized type variables will be treated as `typing.Any` when decoding. .. code-block:: python # These are equivalent. # The unparametrized version substitutes in `Any` for `T` msgspec.json.decode(some_other_message, type=Paginated) msgspec.json.decode(some_other_message, type=Paginated[Any]) However, if an unparametrized type variable has a ``bound`` (`docs `__), then the bound type will be used instead. .. code-block:: python from collections.abc import Sequence S = TypeVar("S", bound=Sequence) # Can be any sequence type class Example(msgspec.Struct, Generic[S]): value: S msg = b'{"value": [1, 2, 3]}' # These are equivalent. # The unparametrized version substitutes in `Sequence` for `S` msgspec.json.decode(some_other_message, type=Example) msgspec.json.decode(some_other_message, type=Example[Sequence]) See the official Python docs on `generic types`_ and the `corresponding PEP `__ for more information. Abstract Types -------------- ``msgspec`` supports several "abstract" types, decoding them as instances of their most common concrete type. **Decoded as lists** - `collections.abc.Collection` / `typing.Collection` - `collections.abc.Sequence` / `typing.Sequence` - `collections.abc.MutableSequence` / `typing.MutableSequence` **Decoded as sets** - `collections.abc.Set` / `typing.AbstractSet` - `collections.abc.MutableSet` / `typing.MutableSet` **Decoded as dicts** - `collections.abc.Mapping` / `typing.Mapping` - `collections.abc.MutableMapping` / `typing.MutableMapping` .. code-block:: python >>> from typing import MutableMapping >>> msgspec.json.decode(b'{"x": 1}', type=MutableMapping[str, int]) {"x": 1} >>> msgspec.json.decode(b'{"x": "oops"}', type=MutableMapping[str, int]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[...]` ``Union`` / ``Optional`` ------------------------- Type unions are supported, with a few restrictions. These restrictions are in place to remove any ambiguity during decoding - given an encoded value there must always be a single type in a given `typing.Union` that can decode that value. Union restrictions are as follows: - Unions may contain at most one type that encodes to an integer (`int`, `enum.IntEnum`) - Unions may contain at most one type that encodes to a string (`str`, `enum.Enum`, `bytes`, `bytearray`, `datetime.datetime`, `datetime.date`, `datetime.time`, `uuid.UUID`, `decimal.Decimal`). Note that this restriction is fixable with some work, if this is a feature you need please `open an issue`_. - Unions may contain at most one type that encodes to an object (`dict`, `typing.TypedDict`, dataclasses_, attrs_, `Struct` with ``array_like=False``) - Unions may contain at most one type that encodes to an array (`list`, `tuple`, `set`, `frozenset`, `typing.NamedTuple`, `Struct` with ``array_like=True``). - Unions may contain at most one *untagged* `Struct` type. Unions containing multiple struct types are only supported through :ref:`struct-tagged-unions`. - Unions with custom types are unsupported beyond optionality (i.e. ``Optional[CustomType]``) .. code-block:: python >>> from typing import Union, List >>> # A decoder expecting either an int, a str, or a list of strings ... decoder = msgspec.json.Decoder(Union[int, str, List[str]]) >>> decoder.decode(b'1') 1 >>> decoder.decode(b'"two"') "two" >>> decoder.decode(b'["three", "four"]') ["three", "four"] >>> decoder.decode(b'false') Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int | str | array`, got `bool` ``Raw`` ------- `msgspec.Raw` is a buffer-like type containing an already encoded messages. They have two common uses: **1. Avoiding unnecessary encoding cost** Wrapping an already encoded buffer in `msgspec.Raw` lets the encoder avoid re-encoding the message, instead it will simply be copied to the output buffer. This can be useful when part of a message already exists in an encoded format (e.g. reading JSON bytes from a database and returning them as part of a larger message). .. code-block:: python >>> import msgspec >>> # Create a new `Raw` object wrapping a pre-encoded message ... fragment = msgspec.Raw(b'{"x": 1, "y": 2}') >>> # Compose a larger message containing the pre-encoded fragment ... msg = {"a": 1, "b": fragment} >>> # During encoding, the raw message is efficiently copied into ... # the output buffer, avoiding any extra encoding cost ... msgspec.json.encode(msg) b'{"a":1,"b":{"x": 1, "y": 2}}' **2. Delaying decoding of part of a message** Sometimes the type of a serialized value depends on the value of other fields in a message. ``msgspec`` provides an optimized version of one common pattern (:ref:`struct-tagged-unions`), but if you need to do something more complicated you may find using `msgspec.Raw` useful here. For example, here we demonstrate how to decode a message where the type of one field (``point``) depends on the value of another (``dimensions``). .. code-block:: python >>> import msgspec >>> from typing import Union >>> class Point1D(msgspec.Struct): ... x: int >>> class Point2D(msgspec.Struct): ... x: int ... y: int >>> class Point3D(msgspec.Struct): ... x: int ... y: int ... z: int >>> class Model(msgspec.Struct): ... dimensions: int ... point: msgspec.Raw # use msgspec.Raw to delay decoding the point field >>> def decode_point(msg: bytes) -> Union[Point1D, Point2D, Point3D]: ... """A function for efficiently decoding the `point` field""" ... # First decode the outer `Model` struct. Decoding of the `point` ... # field is delayed, with the composite bytes stored as a `Raw` object ... # on `point`. ... model = msgspec.json.decode(msg, type=Model) ... ... # Based on the value of `dimensions`, determine which type to use ... # when decoding the `point` field ... if model.dimensions == 1: ... point_type = Point1D ... elif model.dimensions == 2: ... point_type = Point2D ... elif model.dimensions == 3: ... point_type = Point3D ... else: ... raise ValueError("Too many dimensions!") ... ... # Now that we know the type of `point`, we can finish decoding it. ... # Note that `Raw` objects are buffer-like, and can be passed ... # directly to the `decode` method. ... return msgspec.json.decode(model.point, type=point_type) >>> decode_point(b'{"dimensions": 2, "point": {"x": 1, "y": 2}}') Point2D(x=1, y=2) >>> decode_point(b'{"dimensions": 3, "point": {"x": 1, "y": 2, "z": 3}}') Point3D(x=1, y=2, z=3) ``Any`` ------- When decoding a message with `Any` type (or no type specified), encoded types map to Python types in a protocol specific manner. **JSON** JSON_ types are decoded to Python types as follows: - ``null``: `None` - ``bool``: `bool` - ``string``: `str` - ``number``: `int` or `float` [#number_json]_ - ``array``: `list` - ``object``: `dict` .. [#number_json] Numbers are decoded as integers if they contain no decimal or exponent components (e.g. ``1`` but not ``1.0`` or ``1e10``). All other numbers decode as floats. **MessagePack** MessagePack_ types are decoded to Python types as follows: - ``nil``: `None` - ``bool``: `bool` - ``int``: `int` - ``float``: `float` - ``str``: `str` - ``bin``: `bytes` - ``array``: `list` or `tuple` [#tuple]_ - ``map``: `dict` - ``ext``: `msgspec.msgpack.Ext`, `datetime.datetime`, or a custom type .. [#tuple] Tuples are only used when the array type must be hashable (e.g. keys in a ``dict`` or ``set``). All other array types are deserialized as lists by default. **YAML** YAML_ types are decoded to Python types as follows: - ``null``: `None` - ``bool``: `bool` - ``string``: `str` - ``int``: `int` - ``float``: `float` - ``array``: `list` - ``object``: `dict` - ``timestamp``: `datetime.datetime` - ``date``: `datetime.date` **TOML** TOML_ types are decoded to Python types as follows: - ``bool``: `bool` - ``string``: `str` - ``int``: `int` - ``float``: `float` - ``array``: `list` - ``table``: `dict` - ``datetime``: `datetime.datetime` - ``date``: `datetime.date` - ``time``: `datetime.time` .. _type annotations: https://docs.python.org/3/library/typing.html .. _JSON: https://json.org .. _MessagePack: https://msgpack.org .. _YAML: https://yaml.org .. _TOML: https://toml.io .. _pydantic: https://pydantic-docs.helpmanual.io/ .. _pendulum: https://pendulum.eustace.io/ .. _RFC8259: https://datatracker.ietf.org/doc/html/rfc8259 .. _RFC3339: https://datatracker.ietf.org/doc/html/rfc3339 .. _RFC4122: https://datatracker.ietf.org/doc/html/rfc4122 .. _ISO8601: https://en.wikipedia.org/wiki/ISO_8601 .. _timestamp extension: https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type .. _dataclasses: https://docs.python.org/3/library/dataclasses.html .. _attrs: https://www.attrs.org/en/stable/index.html .. _timezone-aware: https://docs.python.org/3/library/datetime.html#aware-and-naive-objects .. _mypy: https://mypy.readthedocs.io .. _pyright: https://github.com/microsoft/pyright .. _generic types: .. _user-defined generic types: https://docs.python.org/3/library/typing.html#user-defined-generic-types .. _open an issue: https://github.com/jcrist/msgspec/issues> .. _ISO 8601 duration strings: https://en.wikipedia.org/wiki/ISO_8601#Durations python-msgspec-0.19.0/docs/source/usage.rst000066400000000000000000000115751473355726200206760ustar00rootroot00000000000000Usage ===== ``msgspec`` supports multiple serialization protocols, accessed through separate submodules: - ``msgspec.json`` (JSON_) - ``msgspec.msgpack`` (MessagePack_) - ``msgspec.yaml`` (YAML_) - ``msgspec.toml`` (TOML_) Each supports a consistent interface, making it simple to switch between protocols as needed. Encoding -------- Each submodule has an ``encode`` method for encoding Python objects using the respective protocol. .. code-block:: python >>> import msgspec >>> # Encode as JSON ... msgspec.json.encode({"hello": "world"}) b'{"hello":"world"}' >>> # Encode as msgpack ... msgspec.msgpack.encode({"hello": "world"}) b'\x81\xa5hello\xa5world' Note that if you're making multiple calls to ``encode``, it's more efficient to create an ``Encoder`` once and use the ``Encoder.encode`` method instead. .. code-block:: python >>> import msgspec >>> # Create a JSON encoder ... encoder = msgspec.json.Encoder() >>> # Encode as JSON using the encoder ... encoder.encode({"hello": "world"}) b'{"hello":"world"}' Decoding -------- Each submodule has ``decode`` method for decoding messages using the respective protocol. .. code-block:: python >>> import msgspec >>> # Decode JSON ... msgspec.json.decode(b'{"hello":"world"}') {'hello': 'world'} >>> # Decode msgpack ... msgspec.msgpack.decode(b'\x81\xa5hello\xa5world') {'hello': 'world'} Note that if you're making multiple calls to ``decode``, it's more efficient to create a ``Decoder`` once and use the ``Decoder.decode`` method instead. .. code-block:: python >>> import msgspec >>> # Create a JSON decoder ... decoder = msgspec.json.Decoder() >>> # Decode JSON using the decoder ... decoder.decode(b'{"hello":"world"}') {'hello': 'world'} .. _typed-decoding: Typed Decoding -------------- ``msgspec`` optionally supports specifying the expected output types during decoding. This serves a few purposes: - Often serialized data has a fixed schema (e.g. a request handler in a REST api expects a certain JSON structure). Specifying the expected types allows ``msgspec`` to perform validation during decoding, with *no* added runtime cost. - Python has a much richer type system than serialization protocols like JSON_ or MessagePack_. Specifying the output types lets ``msgspec`` decode messages into types other than the defaults described above (e.g. decoding JSON objects into a :doc:`Struct ` instead of the default `dict`). - The `type annotations`_ used to describe the expected types are compatible with tools like mypy_ or pyright_, providing excellent editor integration. ``msgspec`` uses Python `type annotations`_ to describe the expected types. A :doc:`wide variety of builtin types are supported `. Here we define a user schema as a :doc:`Struct ` type. We then pass the type to ``decode`` via the ``type`` keyword argument: .. code-block:: python >>> import msgspec >>> class User(msgspec.Struct): ... name: str ... groups: set[str] = set() ... email: str | None = None >>> msgspec.json.decode( ... b'{"name": "alice", "groups": ["admin", "engineering"]}', ... type=User ... ) User(name='alice', groups={'admin', 'engineering'}, email=None) If a message doesn't match the expected type, an error is raised. .. code-block:: python >>> msgspec.json.decode( ... b'{"name": "bill", "groups": ["devops", 123]}', ... type=User ... ) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `str`, got `int` - at `$.groups[1]` .. _strict-vs-lax: "Strict" vs "Lax" Mode ~~~~~~~~~~~~~~~~~~~~~~ Unlike some other libraries (e.g. pydantic_), ``msgspec`` won't perform any unsafe implicit conversion by default ("strict" mode). For example, if an integer is specified and a string is provided instead, an error is raised rather than attempting to cast the string to an int. .. code-block:: python >>> msgspec.json.decode(b'[1, 2, "3"]', type=list[int]) Traceback (most recent call last): File "", line 1, in msgspec.ValidationError: Expected `int`, got `str` - at `$[2]` For cases where you'd like a more lax set of conversion rules, you can pass ``strict=False`` to any ``decode`` function or ``Decoder`` class ("lax" mode). See :doc:`supported-types` for information on how this affects individual types. .. code-block:: python >>> msgspec.json.decode(b'[1, 2, "3"]', type=list[int], strict=False) [1, 2, 3] .. _JSON: https://json.org .. _MessagePack: https://msgpack.org .. _YAML: https://yaml.org .. _TOML: https://toml.io .. _type annotations: https://docs.python.org/3/library/typing.html .. _pydantic: https://pydantic-docs.helpmanual.io/ .. _mypy: https://mypy.readthedocs.io .. _pyright: https://github.com/microsoft/pyright python-msgspec-0.19.0/docs/source/why.rst000066400000000000000000000041121473355726200203660ustar00rootroot00000000000000Why msgspec? ------------ If you're writing a networked application, you'll need some agreed upon protocol that your clients and servers can use to communicate. JSON is a decent choice here (though there are many other options). It's ubiquitous, and Python has many libraries for parsing it into builtin types (``json``, ``ujson``, ``orjson``, ...). *However, servers don't just parse JSON, they also need to do something with it*. ``msgspec`` goes above and beyond other Python JSON libraries to help with the following: - **Validation** If a field is missing from a request or has the wrong type, you probably want to raise a nice error message rather than just throwing a 500 error. ``msgspec`` lets you describe your schema via type annotations, and will efficiently :ref:`validate ` messages against this schema while decoding. It also integrates well with static analysis tools like mypy_ and pyright_, helping you avoid whole classes of runtime errors. - **Application Logic** What your application actually does! While builtin types like dicts are fine for writing application logic, they aren't as ergonomic as custom classes (no attribute access, poor type checking, ...). ``msgspec`` supports a :doc:`wide variety of types `, letting you decouple the objects your application logic uses from those that JSON natively supports. - **Future Flexibility** Application needs change; you'll want to make sure your clients/servers won't break if the JSON schema evolves over time. To handle this, ``msgspec`` supports :doc:`"schema evolution" `. Messages can be sent between clients with different schemas without error, allowing systems to evolve over time. While there are other tools in this space, ``msgspec`` should be an :doc:`order of magnitude faster ` than other options. We also hope that it's quick to learn and friendly to use, letting you focus less on serialization and more on your application code. .. _mypy: https://mypy.readthedocs.io .. _pyright: https://github.com/microsoft/pyright python-msgspec-0.19.0/examples/000077500000000000000000000000001473355726200164155ustar00rootroot00000000000000python-msgspec-0.19.0/examples/asyncio-kv/000077500000000000000000000000001473355726200205005ustar00rootroot00000000000000python-msgspec-0.19.0/examples/asyncio-kv/kv.py000066400000000000000000000130251473355726200214730ustar00rootroot00000000000000from __future__ import annotations import asyncio import msgspec from typing import Any # Some utilities for writing and reading length-prefix framed messages. Using # length-prefixed framing makes it easier for the reader to determine the # boundaries of each message before passing it to msgspec to be decoded. async def prefixed_send(stream: asyncio.StreamWriter, buffer: bytes) -> None: """Write a length-prefixed buffer to the stream""" # Encode the message length as a 4 byte big-endian integer. prefix = len(buffer).to_bytes(4, "big") # Write the prefix and buffer to the stream. stream.write(prefix) stream.write(buffer) await stream.drain() async def prefixed_recv(stream: asyncio.StreamReader) -> bytes: """Read a length-prefixed buffer from the stream""" # Read the next 4 byte prefix prefix = await stream.readexactly(4) # Convert the prefix back into an integer for the next message length n = int.from_bytes(prefix, "big") # Read in the full message buffer return await stream.readexactly(n) # Define some request types. We set `tag=True` on each type so they can be used # in a "tagged-union" defining the request types. class Get(msgspec.Struct, tag=True): key: str class Put(msgspec.Struct, tag=True): key: str val: str class Del(msgspec.Struct, tag=True): key: str class ListKeys(msgspec.Struct, tag=True): pass # A union of all valid request types Request = Get | Put | Del | ListKeys class Server: """An example TCP key-value server using asyncio and msgspec""" def __init__(self, host: str = "127.0.0.1", port: int = 8888): self.host = host self.port = port self.kv: dict[str, str] = {} # A msgpack encoder for encoding responses self.encoder = msgspec.msgpack.Encoder() # A *typed* msgpack decoder for decoding requests. If a request doesn't # match the specified types, a nice error will be raised. self.decoder = msgspec.msgpack.Decoder(Request) async def handle_connection( self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter ): """Handle the full lifetime of a single connection""" print("Connection opened") while True: try: # Receive and decode a request buffer = await prefixed_recv(reader) req = self.decoder.decode(buffer) # Process the request resp = await self.handle_request(req) # Encode and write the response buffer = self.encoder.encode(resp) await prefixed_send(writer, buffer) except EOFError: print("Connection closed") return async def handle_request(self, req: Request) -> Any: """Handle a single request and return the result (if any)""" # We use pattern matching here to branch on the different message types. # You could just as well use an if-else statement, but pattern matching # works pretty well here. match req: case Get(key): # Return the value for a key, or None if missing return self.kv.get(key) case Put(key, val): # Add a new key-value pair self.kv[key] = val return None case Del(key): # Remove a key-value pair if it exists self.kv.pop(key, None) return None case ListKeys(): # Return a list of all keys in the store return sorted(self.kv) async def serve_forever(self) -> None: server = await asyncio.start_server( self.handle_connection, self.host, self.port ) print(f"Serving on tcp://{self.host}:{self.port}...") async with server: await server.serve_forever() def run(self) -> None: """Run the server until ctrl-C""" asyncio.run(self.serve_forever()) class Client: """An example TCP key-value client using asyncio and msgspec.""" def __init__(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter): self.reader = reader self.writer = writer @classmethod async def create(cls, host: str = "127.0.0.1", port: int = 8888): """Create a new client""" reader, writer = await asyncio.open_connection(host, port) return cls(reader, writer) async def close(self) -> None: """Close the client.""" self.writer.close() await self.writer.wait_closed() async def request(self, req): """Send a request and await the response""" # Encode and send the request buffer = msgspec.msgpack.encode(req) await prefixed_send(self.writer, buffer) # Receive and decode the response buffer = await prefixed_recv(self.reader) return msgspec.msgpack.decode(buffer) async def get(self, key: str) -> str | None: """Get a key from the KV store, returning None if not present""" return await self.request(Get(key)) async def put(self, key: str, val: str) -> None: """Put a key-val pair in the KV store""" return await self.request(Put(key, val)) async def delete(self, key: str) -> None: """Delete a key-val pair from the KV store""" return await self.request(Del(key)) async def list_keys(self) -> list[str]: """List all keys in the KV store""" return await self.request(ListKeys()) if __name__ == "__main__": Server().run() python-msgspec-0.19.0/examples/conda-repodata/000077500000000000000000000000001473355726200212765ustar00rootroot00000000000000python-msgspec-0.19.0/examples/conda-repodata/query_repodata.py000066400000000000000000000040651473355726200247010ustar00rootroot00000000000000import json import time import orjson import requests import simdjson import ujson import msgspec def query_msgspec(data: bytes) -> list[tuple[int, str]]: # Use Struct types to define the JSON schema. For efficiency we only define # the fields we actually need. class Package(msgspec.Struct): name: str size: int class RepoData(msgspec.Struct): packages: dict[str, Package] # Decode the data as a `RepoData` type repo_data = msgspec.json.decode(data, type=RepoData) # Sort packages by `size`, and return the top 10 return sorted( ((p.size, p.name) for p in repo_data.packages.values()), reverse=True )[:10] def query_orjson(data: bytes) -> list[tuple[int, str]]: repo_data = orjson.loads(data) return sorted( ((p["size"], p["name"]) for p in repo_data["packages"].values()), reverse=True )[:10] def query_json(data: bytes) -> list[tuple[int, str]]: repo_data = json.loads(data) return sorted( ((p["size"], p["name"]) for p in repo_data["packages"].values()), reverse=True )[:10] def query_ujson(data: bytes) -> list[tuple[int, str]]: repo_data = ujson.loads(data) return sorted( ((p["size"], p["name"]) for p in repo_data["packages"].values()), reverse=True )[:10] def query_simdjson(data: bytes) -> list[tuple[int, str]]: repo_data = simdjson.Parser().parse(data) return sorted( ((p["size"], p["name"]) for p in repo_data["packages"].values()), reverse=True )[:10] # Download the current_repodata.json file resp = requests.get( "https://conda.anaconda.org/conda-forge/noarch/current_repodata.json" ) resp.raise_for_status() data = resp.content libraries = [ ("json", query_json), ("ujson", query_ujson), ("orjson", query_orjson), ("simdjson", query_simdjson), ("msgspec", query_msgspec), ] # Run the query with each JSON library, timing the execution for lib, func in libraries: start = time.perf_counter() func(data) stop = time.perf_counter() print(f"{lib}: {(stop - start) * 1000:.2f} ms") python-msgspec-0.19.0/examples/edgedb/000077500000000000000000000000001473355726200176275ustar00rootroot00000000000000python-msgspec-0.19.0/examples/edgedb/dbschema/000077500000000000000000000000001473355726200213755ustar00rootroot00000000000000python-msgspec-0.19.0/examples/edgedb/dbschema/default.esdl000066400000000000000000000002071473355726200236710ustar00rootroot00000000000000module default { type Person { required name: str; } type Movie { required title: str; multi actors: Person; } }; python-msgspec-0.19.0/examples/edgedb/dbschema/migrations/000077500000000000000000000000001473355726200235515ustar00rootroot00000000000000python-msgspec-0.19.0/examples/edgedb/dbschema/migrations/00001.edgeql000066400000000000000000000004671473355726200254030ustar00rootroot00000000000000CREATE MIGRATION m1vegpxb3odf7j6rsioor2j5zcassvioypuixdcfujquycuufa3k2a ONTO initial { CREATE TYPE default::Person { CREATE REQUIRED PROPERTY name: std::str; }; CREATE TYPE default::Movie { CREATE MULTI LINK actors: default::Person; CREATE REQUIRED PROPERTY title: std::str; }; }; python-msgspec-0.19.0/examples/edgedb/edgedb.toml000066400000000000000000000000401473355726200217300ustar00rootroot00000000000000[edgedb] server-version = "3.2" python-msgspec-0.19.0/examples/edgedb/insert_data.edgeql000066400000000000000000000002271473355726200233100ustar00rootroot00000000000000INSERT Movie { title := "Dune", actors := { (INSERT Person { name := "Timothée Chalamet" }), (INSERT Person { name := "Zendaya" }) } }; python-msgspec-0.19.0/examples/geojson/000077500000000000000000000000001473355726200200615ustar00rootroot00000000000000python-msgspec-0.19.0/examples/geojson/canada.json000066400000000000000000077623721473355726200222130ustar00rootroot00000000000000{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"Canada"},"geometry":{"type":"Polygon","coordinates":[[[-65.61361699999998,43.42027300000001],[-65.61972000000003,43.418052999999986],[-65.625,43.42137900000006],[-65.63612399999988,43.44971499999997],[-65.63305699999995,43.47470900000013],[-65.61138900000003,43.51305400000007],[-65.60583500000001,43.51610599999998],[-65.598343,43.515830999999935],[-65.566101,43.508331000000055],[-65.561935,43.50443999999999],[-65.55999799999995,43.49971800000009],[-65.57333399999999,43.476379000000065],[-65.59361299999995,43.44415300000003],[-65.61361699999998,43.42027300000001]],[[-59.81694799999991,43.92832899999996],[-59.84166700000003,43.91860200000002],[-59.86639399999996,43.909988],[-59.879722999999956,43.906654],[-59.895835999999974,43.90416000000005],[-59.91944899999993,43.901099999999985],[-59.95333099999999,43.898604999999975],[-60.01361799999995,43.90332000000001],[-60.02860999999996,43.905548000000124],[-60.078338999999914,43.91749600000003],[-60.10388899999998,43.92665900000003],[-60.121666000000005,43.934990000000084],[-60.129997,43.94193300000006],[-60.124168,43.94526700000006],[-60.09500099999997,43.93943000000013],[-60.017776000000026,43.92582700000008],[-59.975554999999986,43.92193600000002],[-59.96694200000002,43.92193600000002],[-59.91500099999996,43.925552000000096],[-59.86194599999999,43.93443300000001],[-59.841385,43.93888099999998],[-59.80972300000002,43.950829],[-59.793334999999956,43.9594350000001],[-59.77722199999994,43.96804800000007],[-59.75527999999997,43.97943100000009],[-59.724716,43.99110400000012],[-59.72777599999995,43.98638200000005],[-59.73638900000003,43.9791560000001],[-59.753615999999965,43.964995999999985],[-59.76250499999992,43.95777100000009],[-59.782501000000025,43.944435],[-59.79305999999997,43.93832400000008],[-59.81694799999991,43.92832899999996]],[[-66.28277599999996,44.289719000000105],[-66.314438,44.25054899999998],[-66.32223499999998,44.252777000000094],[-66.32444800000002,44.25750000000005],[-66.32389799999999,44.26332900000011],[-66.310272,44.28999300000004],[-66.30305499999992,44.30054500000006],[-66.29472399999992,44.310272],[-66.22833300000002,44.38582600000001],[-66.21945199999999,44.394713999999965],[-66.214447,44.39777400000003],[-66.20638999999994,44.39527100000004],[-66.20472699999993,44.384995],[-66.20527599999997,44.37943300000006],[-66.20805399999995,44.37276500000007],[-66.21472199999994,44.36360900000011],[-66.24972500000001,44.32721700000013],[-66.28277599999996,44.289719000000105]],[[-66.886124,44.614441],[-66.900284,44.61332699999997],[-66.90417499999995,44.61804999999998],[-66.904449,44.62248999999997],[-66.88473499999998,44.68332700000002],[-66.85861199999994,44.74305000000004],[-66.83778399999994,44.770827999999995],[-66.83332799999994,44.77499400000005],[-66.80332900000002,44.79888199999999],[-66.79804999999993,44.80249000000009],[-66.78666699999985,44.80804400000011],[-66.77972399999993,44.80915800000008],[-66.77250700000002,44.80915800000008],[-66.76722699999993,44.80554999999998],[-66.764725,44.801102000000014],[-66.75778199999996,44.792496000000085],[-66.73472600000002,44.7291560000001],[-66.73693800000001,44.71720900000014],[-66.74027999999993,44.70777099999998],[-66.761124,44.67610200000013],[-66.765015,44.671378999999945],[-66.87527499999993,44.61943800000006],[-66.886124,44.614441]],[[-61.199996999999996,45.55832700000008],[-61.20472000000001,45.55526700000007],[-61.21277599999996,45.55665600000003],[-61.219993999999986,45.55999000000003],[-61.22416700000002,45.56415600000014],[-61.222220999999934,45.569443000000035],[-61.21416499999998,45.568886000000134],[-61.20861099999996,45.56721500000009],[-61.20249899999999,45.56332400000002],[-61.199996999999996,45.55832700000008]],[[-60.993889000000024,45.45777099999998],[-61.00028199999997,45.455826],[-61.00778199999996,45.45721400000008],[-61.01944699999996,45.46388200000007],[-61.101943999999946,45.52304800000002],[-61.10583500000001,45.526939000000084],[-61.108337000000006,45.54083300000002],[-61.10444599999994,45.54638700000004],[-61.09860999999995,45.549164000000076],[-61.023612999999955,45.57499700000005],[-61.01722000000001,45.57527200000004],[-60.936942999999985,45.57665999999995],[-60.908051,45.576103000000046],[-60.900275999999906,45.575554000000125],[-60.879996999999946,45.5605470000001],[-60.87860899999987,45.55582400000014],[-60.88388800000001,45.55054499999994],[-60.889167999999984,45.548332000000016],[-60.91027799999995,45.54610400000007],[-60.93611099999998,45.539161999999976],[-60.947495,45.533607000000075],[-60.95249899999993,45.529990999999995],[-60.962501999999915,45.519989000000066],[-60.96305799999999,45.51499899999999],[-60.96166999999991,45.51027700000009],[-60.95861100000002,45.50582900000012],[-60.950553999999954,45.497772],[-60.993889000000024,45.45777099999998]],[[-63.24639100000002,46.43554700000004],[-63.25389100000001,46.43526500000013],[-63.26167299999986,46.43637800000005],[-63.26944699999996,46.4397130000001],[-63.285004000000015,46.450829000000056],[-63.27055399999989,46.450271999999984],[-63.245834,46.442764000000125],[-63.240837,46.438599000000124],[-63.24639100000002,46.43554700000004]],[[-71.11111499999998,46.850548],[-71.118607,46.850273000000016],[-71.12748699999992,46.85166200000003],[-71.13027999999991,46.85610200000002],[-71.12832600000002,46.86221300000011],[-71.12138399999998,46.87416100000013],[-71.09889199999998,46.89804800000002],[-71.07833900000003,46.913605000000075],[-70.936935,46.992493000000024],[-70.89666699999987,47.013329000000056],[-70.87222300000002,47.02416200000005],[-70.86000100000001,47.02777100000003],[-70.84527600000001,47.02916000000005],[-70.83639499999998,47.02777100000003],[-70.818893,47.02276599999999],[-70.81361400000003,47.019440000000145],[-70.80915800000002,47.01527400000009],[-70.80749500000002,47.00999500000006],[-70.80943299999996,47.00443999999999],[-70.814438,46.998329000000126],[-70.87721299999998,46.93110700000011],[-70.88751200000002,46.923607000000004],[-70.90417499999995,46.913605000000075],[-71.00917099999992,46.87110100000007],[-71.03332499999993,46.86249499999997],[-71.04083299999996,46.86054999999999],[-71.08222999999992,46.8533250000001],[-71.11111499999998,46.850548]],[[-60.44527399999998,46.86166400000013],[-60.436942999999985,46.86110700000006],[-60.35278299999999,46.86166400000013],[-60.34583299999986,46.86249499999997],[-60.33444199999997,46.8688810000001],[-60.32611099999997,46.86832399999997],[-60.32083899999998,46.864441000000056],[-60.309440999999936,46.85110500000013],[-60.302223000000026,46.837493999999936],[-60.30139200000002,46.831940000000145],[-60.304442999999935,46.815269000000114],[-60.32277699999992,46.73638200000005],[-60.327224999999885,46.724991000000045],[-60.47888199999994,46.38999200000006],[-60.53527799999995,46.32166300000006],[-60.58943899999986,46.25499700000006],[-60.60916900000001,46.201934999999935],[-60.59033199999993,46.20782100000008],[-60.587001999999984,46.209488000000135],[-60.57150299999995,46.22865300000012],[-60.55332900000002,46.24887800000005],[-60.551391999999964,46.25499700000006],[-60.54333500000001,46.26666300000005],[-60.528053,46.27860299999992],[-60.479720999999984,46.31110400000006],[-60.46805599999999,46.316666],[-60.44388600000002,46.32694200000009],[-60.43055700000002,46.33138299999996],[-60.424171,46.331665000000044],[-60.41638899999987,46.32804900000002],[-60.412216,46.31888600000002],[-60.41777799999994,46.28582799999998],[-60.419997999999964,46.27999100000005],[-60.42472099999992,46.27526899999998],[-60.43804899999992,46.27082800000005],[-60.45471999999995,46.26221500000008],[-60.47055099999994,46.25110599999999],[-60.53583100000003,46.19243600000004],[-60.59027900000001,46.1386030000001],[-60.60028099999994,46.13027199999999],[-60.61611199999993,46.12082700000013],[-60.64583600000003,46.10610200000002],[-60.687774999999874,46.08832600000005],[-60.70111099999991,46.08526599999999],[-60.788895000000025,46.066666000000055],[-60.86333499999995,46.052490000000034],[-60.98611499999993,45.982491000000095],[-61.02388799999994,45.96943700000003],[-61.08028399999995,45.951660000000004],[-61.08777600000002,45.95138500000013],[-61.09583299999997,45.952217000000076],[-61.10500300000001,45.954712000000086],[-61.113059999999905,45.95526899999999],[-61.11777499999994,45.950829],[-61.12694499999998,45.92832900000013],[-61.12555699999996,45.92360700000006],[-61.11833200000001,45.92304999999993],[-61.05699900000002,45.93121699999995],[-61.05283400000002,45.93188100000003],[-61.01749799999999,45.940712000000076],[-61.014835000000005,45.94338200000004],[-60.989165999999955,45.95638300000013],[-60.987777999999935,45.96249400000005],[-60.98416899999995,45.96749099999994],[-60.957221999999945,45.984992999999974],[-60.94055199999991,45.99443800000006],[-60.892776000000026,46.01527400000009],[-60.853057999999976,46.03138000000007],[-60.77083599999992,46.057495000000074],[-60.75750699999992,46.060546999999985],[-60.743056999999965,46.061661000000015],[-60.73555799999991,46.05804400000005],[-60.73416900000001,46.05332199999998],[-60.73416900000001,46.047493000000145],[-60.807503,45.93110700000011],[-60.87027699999999,45.91082000000006],[-60.898056,45.90665400000012],[-60.956947000000014,45.90304600000002],[-61.042888999999946,45.8913270000001],[-61.047053999999946,45.890659000000085],[-61.05055599999997,45.88899199999997],[-61.053390999999976,45.88616200000013],[-61.096663999999976,45.860275],[-61.09777799999995,45.85471300000006],[-61.094719,45.850273000000016],[-61.08777600000002,45.847488],[-61.07972699999999,45.84693900000002],[-61.073059,45.84804500000007],[-61.06082900000001,45.852776000000006],[-61.04944599999999,45.858330000000024],[-61.026107999999965,45.86971299999999],[-60.98999799999996,45.881935],[-60.96805599999999,45.883331000000055],[-60.96028100000001,45.88027200000005],[-60.919448999999986,45.85749800000008],[-60.91583300000002,45.852776000000006],[-60.91777799999994,45.847488],[-60.93527199999994,45.825271999999984],[-60.94055199999991,45.821663],[-60.947495,45.82054900000003],[-61.01944699999996,45.80998999999997],[-61.06750499999998,45.79166399999997],[-61.079169999999976,45.78611000000001],[-61.11805700000002,45.763611000000026],[-61.12777699999998,45.75527199999999],[-61.147223999999994,45.704994],[-61.14917000000003,45.699715000000026],[-61.14250199999992,45.69638100000003],[-61.07749899999993,45.68888099999998],[-61.07083899999998,45.68998700000003],[-61.041945999999996,45.704162999999994],[-61.012778999999966,45.71888000000001],[-60.99639100000002,45.72776799999997],[-60.97277100000002,45.738045],[-60.95471999999995,45.74554399999994],[-60.93582900000001,45.751389000000074],[-60.92222599999991,45.75360900000004],[-60.914443999999946,45.75360900000004],[-60.890556000000004,45.75166300000001],[-60.88194299999992,45.75000000000006],[-60.8641659999999,45.744438000000116],[-60.84416199999998,45.735268000000076],[-60.816666,45.72248800000011],[-60.80999800000001,45.71915400000012],[-60.800835000000006,45.71166199999999],[-60.72943899999996,45.77860300000003],[-60.719719,45.78832999999997],[-60.516944999999964,45.92083000000014],[-60.49194299999988,45.92943600000007],[-60.46694200000002,45.938041999999996],[-60.409163999999976,45.979987999999935],[-60.40416699999997,45.98443600000007],[-60.395835999999974,45.99610100000001],[-60.40166499999998,45.994713000000104],[-60.55500000000001,45.9469380000001],[-60.611671,45.92499500000014],[-60.6297229999999,45.91749600000014],[-60.63999899999999,45.91027100000008],[-60.644721999999945,45.905548000000124],[-60.655272999999966,45.898330999999985],[-60.66111000000001,45.89527099999992],[-60.6733319999999,45.89054900000002],[-60.686110999999926,45.88694000000004],[-60.69388600000002,45.88610799999992],[-60.708892999999875,45.887215000000026],[-60.72332799999998,45.893326000000116],[-60.78833799999995,45.92943600000007],[-60.78972599999997,45.934433000000126],[-60.788895000000025,45.939986999999974],[-60.785278000000005,45.94638100000003],[-60.78055599999999,45.950829],[-60.69138299999997,46.00193799999994],[-60.679168999999945,46.00666000000001],[-60.601395000000025,46.039719000000105],[-60.54111499999999,46.0655440000001],[-60.523612999999955,46.07555400000001],[-60.49083699999994,46.094437000000084],[-60.30999799999995,46.206939999999975],[-60.30499999999995,46.210548000000074],[-60.29999499999997,46.21499600000004],[-60.295279999999934,46.22693600000014],[-60.295279999999934,46.23220800000007],[-60.304169,46.233878999999945],[-60.36555499999997,46.22499099999999],[-60.372772,46.223320000000115],[-60.39611100000002,46.213051000000064],[-60.40193899999991,46.21027399999997],[-60.41833500000001,46.199996999999996],[-60.428054999999915,46.19249000000008],[-60.442497,46.17943600000001],[-60.46333299999992,46.16387900000012],[-60.47916399999991,46.15277100000014],[-60.528053,46.12165800000014],[-60.60583500000001,46.07471500000008],[-60.629997,46.065269000000114],[-60.64416499999999,46.06304900000009],[-60.65193899999997,46.06388099999998],[-60.65610499999997,46.06777200000005],[-60.65638699999994,46.07305100000002],[-60.652495999999985,46.079436999999984],[-60.63833599999987,46.093048000000124],[-60.45610799999997,46.24137900000005],[-60.404998999999975,46.27999100000005],[-60.399726999999984,46.28388200000012],[-60.388892999999996,46.291106999999954],[-60.35972599999997,46.30499300000014],[-60.347778000000005,46.310546999999985],[-60.285278000000005,46.32138100000003],[-60.205558999999994,46.240273],[-60.13805400000001,46.246658000000025],[-60.13194299999992,46.248604000000114],[-60.124168,46.248604000000114],[-60.09999799999997,46.24638400000009],[-60.091666999999916,46.24471300000005],[-59.9505539999999,46.20138500000007],[-59.873054999999965,46.17582699999997],[-59.808608999999876,46.111938000000066],[-59.80972300000002,46.10638400000005],[-59.81944999999996,46.09721400000001],[-59.83416699999998,46.08471700000001],[-59.853888999999924,46.00249500000001],[-59.840553,45.93832400000002],[-59.95861099999996,45.90165700000006],[-60.13027999999997,45.86776700000013],[-60.13611599999996,45.86499799999996],[-60.155272999999966,45.84665699999999],[-60.15943899999996,45.841102999999976],[-60.160552999999936,45.835548000000074],[-60.17444599999999,45.76388500000013],[-60.22916399999997,45.70555100000013],[-60.233886999999925,45.70110299999993],[-60.245834,45.69499200000007],[-60.37972300000001,45.644997000000046],[-60.39222699999999,45.64110599999998],[-60.411666999999966,45.636940000000095],[-60.49888599999997,45.62026999999995],[-60.513061999999934,45.61888099999999],[-60.55750299999994,45.61804999999998],[-60.765556000000004,45.5949940000001],[-60.96083099999993,45.59943399999992],[-61.101669000000015,45.564437999999996],[-61.14833799999991,45.55526700000007],[-61.168334999999956,45.5513840000001],[-61.19691799999998,45.58374000000009],[-61.21869699999996,45.5807880000001],[-61.237521999999956,45.58152800000005],[-61.273056,45.561935000000005],[-61.336945000000014,45.57332600000001],[-61.37557599999991,45.62213100000014],[-61.430556999999965,45.66554300000007],[-61.45471999999995,45.70555100000013],[-61.45750399999997,45.71527100000003],[-61.478049999999996,45.80387900000011],[-61.49472000000003,45.84638199999995],[-61.527495999999985,45.98943300000002],[-61.455558999999994,46.13749700000005],[-61.447776999999974,46.14943699999998],[-61.43888899999996,46.159430999999984],[-61.41277299999996,46.178329000000076],[-61.39083900000003,46.191376000000105],[-61.37388599999997,46.20082900000011],[-61.34332999999992,46.21249399999999],[-61.30555700000002,46.22499099999999],[-61.29389200000003,46.230819999999994],[-61.28333299999997,46.23888400000004],[-61.09722099999999,46.44609800000012],[-61.08943899999991,46.45804600000014],[-61.035278000000005,46.55554999999998],[-61.033057999999926,46.56166100000007],[-61.031113000000005,46.57276900000005],[-61.032501000000025,46.57749200000006],[-60.99694799999992,46.63472000000007],[-60.89222699999999,46.77388000000002],[-60.87361099999987,46.79305299999993],[-60.86361699999992,46.80138400000004],[-60.84027900000001,46.81360599999999],[-60.833884999999896,46.81554399999993],[-60.80555700000002,46.82027399999998],[-60.79389200000003,46.825271999999984],[-60.724716,46.874992000000134],[-60.714721999999995,46.88249200000007],[-60.70444499999991,46.89138000000003],[-60.69527399999993,46.901657],[-60.68666099999996,46.912491000000045],[-60.67833699999994,46.93082400000014],[-60.67055499999998,46.953606000000036],[-60.664444,46.96610300000003],[-60.65694400000001,46.97860000000003],[-60.64028200000001,47],[-60.60916900000001,47.02443700000009],[-60.59777799999989,47.031105000000025],[-60.59194200000002,47.03333300000003],[-60.58332799999994,47.031661999999926],[-60.46083099999987,46.999161000000015],[-60.427498000000014,46.96582799999999],[-60.493889000000024,46.90221400000007],[-60.49805500000002,46.89666000000011],[-60.45222499999994,46.864441000000056],[-60.44527399999998,46.86166400000013]],[[-64.03971899999999,46.74332400000009],[-64.031677,46.742767000000015],[-64.01640299999991,46.743607000000054],[-64.00917099999998,46.74415600000003],[-64.00500499999998,46.74971800000014],[-63.99999999999994,46.75360900000004],[-63.991668999999945,46.75305200000014],[-63.97916399999991,46.74638399999998],[-63.974715999999944,46.74249300000008],[-63.83250399999997,46.61721000000006],[-63.83167300000002,46.61193800000012],[-63.86500499999988,46.537498000000085],[-63.86888899999997,46.531937000000084],[-63.840836000000024,46.46443899999991],[-63.82833900000003,46.45804600000014],[-63.780281,46.44499200000007],[-63.74222600000002,46.43943000000013],[-63.73305499999998,46.43888100000004],[-63.709442000000024,46.43749200000002],[-63.703888000000006,46.4405440000001],[-63.698050999999964,46.45638300000007],[-63.69860799999998,46.46166200000005],[-63.70027900000002,46.466385],[-63.72277100000002,46.48054500000012],[-63.73805199999998,46.491378999999995],[-63.739998000000014,46.49610100000007],[-63.723327999999924,46.54361000000006],[-63.716110000000015,46.55387900000011],[-63.709723999999994,46.55609900000013],[-63.676391999999964,46.56415600000008],[-63.662216,46.56638299999997],[-63.64722399999988,46.56721500000009],[-63.618889000000024,46.561104],[-63.49777999999998,46.52777100000014],[-63.315001999999936,46.48860200000007],[-63.27197999999993,46.426926000000094],[-63.240661999999986,46.420456],[-63.21639299999998,46.41220900000013],[-62.94277199999988,46.42694100000011],[-62.862777999999935,46.4347150000001],[-62.69860799999998,46.45249200000001],[-62.692497,46.456100000000106],[-62.686385999999914,46.457497000000046],[-62.66583300000002,46.461104999999975],[-62.595001000000025,46.47082500000005],[-62.47721899999999,46.477768000000026],[-62.455558999999994,46.47860000000014],[-62.182503,46.48582499999998],[-62.16638899999998,46.48610700000006],[-62.13333099999994,46.482764999999915],[-62.058051999999975,46.472762999999986],[-62.01472499999994,46.46527100000003],[-61.979720999999984,46.45915999999994],[-61.970551,46.456940000000145],[-61.965003999999965,46.45332300000001],[-61.968886999999995,46.447768999999994],[-61.97360999999995,46.44304700000009],[-62.01306199999999,46.42110400000013],[-62.101112,46.37971500000003],[-62.17333199999996,46.349433999999974],[-62.21555299999994,46.34360500000014],[-62.27972399999993,46.33804300000003],[-62.309166000000005,46.349998000000085],[-62.326392999999996,46.354996000000085],[-62.34277300000002,46.356102000000135],[-62.357779999999934,46.35582700000009],[-62.355834999999956,46.35083000000003],[-62.34805299999999,46.33221400000002],[-62.334723999999994,46.31193500000006],[-62.36194599999993,46.27665700000006],[-62.419448999999986,46.21998600000012],[-62.42472099999998,46.215546000000074],[-62.453888000000006,46.21443899999997],[-62.50750699999992,46.214157000000114],[-62.603888999999924,46.18249500000013],[-62.603888999999924,46.17721599999999],[-62.54222900000002,46.12249000000003],[-62.50750699999992,46.118881000000044],[-62.5,46.11915600000009],[-62.47833300000002,46.12082700000013],[-62.47721899999999,46.126380999999924],[-62.478882,46.13193500000011],[-62.481667000000016,46.13638300000008],[-62.489998000000014,46.138329],[-62.49722299999996,46.13804600000003],[-62.506110999999976,46.139717000000076],[-62.513892999999996,46.142220000000066],[-62.509727,46.14860500000003],[-62.504448000000025,46.150825999999995],[-62.48916600000001,46.151382000000126],[-62.47305299999999,46.150269000000094],[-62.468886999999995,46.14610299999998],[-62.44916499999994,46.100548],[-62.44749499999995,46.095543000000134],[-62.44694500000003,46.09054600000002],[-62.45472000000001,46.01888300000007],[-62.45916699999998,46.00638600000008],[-62.47360999999995,45.994713000000104],[-62.496947999999975,45.983879],[-62.51000199999993,45.979156000000046],[-62.54167199999995,45.97054300000008],[-62.54861499999993,45.96943700000003],[-62.59166700000003,45.9649960000001],[-62.613891999999964,45.96276900000004],[-62.65027600000002,45.96027400000003],[-62.76111599999996,45.95416299999994],[-62.83777600000002,45.96749099999994],[-62.856667000000016,45.977486000000056],[-62.88277399999998,45.99554400000011],[-62.93028300000003,46.037215999999944],[-62.97083299999997,46.07416500000005],[-62.922500999999954,46.09249100000005],[-62.917220999999984,46.09638200000012],[-62.87527499999993,46.134995],[-62.871940999999936,46.14360799999997],[-62.885276999999974,46.155823000000055],[-62.89083900000003,46.159430999999984],[-63.02527600000002,46.18915600000008],[-63.10361499999999,46.201934999999935],[-63.11277799999999,46.20416300000011],[-63.11944599999987,46.207214000000135],[-63.12222300000002,46.2116620000001],[-63.12027699999999,46.2177660000001],[-63.11583699999994,46.222488],[-63.038895000000025,46.28027300000008],[-63.02416999999997,46.29027599999995],[-63.017776000000026,46.29249600000014],[-63.01028400000001,46.292770000000075],[-63.002228,46.28999299999998],[-62.99610899999999,46.292220999999984],[-62.97943899999996,46.30165899999997],[-62.96916199999998,46.309432999999956],[-62.96472199999988,46.31415600000014],[-62.96277599999996,46.31999200000001],[-62.96944399999995,46.31888600000002],[-63.03527799999989,46.30165899999997],[-63.04138899999998,46.299721000000034],[-63.05277999999993,46.29388400000005],[-63.05860899999993,46.29083300000002],[-63.090836000000024,46.26915699999995],[-63.16500100000002,46.210548000000074],[-63.143332999999984,46.20166000000012],[-63.139167999999984,46.19776900000005],[-63.13861099999991,46.19249000000008],[-63.140556000000004,46.186378000000104],[-63.22444200000001,46.139717000000076],[-63.23860899999994,46.13804600000003],[-63.253615999999965,46.13749700000005],[-63.26167299999986,46.13804600000003],[-63.289169000000015,46.14388299999996],[-63.40916399999992,46.176941],[-63.519722,46.206099999999935],[-63.59194200000002,46.21193700000009],[-63.64277599999991,46.22499099999999],[-63.64972699999993,46.22804300000007],[-63.69972200000001,46.25943799999999],[-63.700553999999954,46.269989000000066],[-63.702225,46.27526899999998],[-63.70666499999993,46.27860299999992],[-63.741942999999935,46.30443600000007],[-63.75444799999997,46.310822000000144],[-63.811110999999926,46.32749200000012],[-63.77222399999994,46.36082500000009],[-63.73694599999993,46.35388200000011],[-63.72916399999997,46.35277600000006],[-63.714721999999995,46.354164000000026],[-63.73916600000001,46.391106000000036],[-63.745003,46.394714000000135],[-63.75444799999997,46.39638500000001],[-63.76167299999992,46.39666],[-63.84110999999996,46.39888000000002],[-63.963615000000004,46.40110000000004],[-63.981941000000006,46.39388300000013],[-63.9891659999999,46.393608000000086],[-64.12193300000001,46.404709000000025],[-64.12998999999996,46.40721100000013],[-64.13305700000001,46.4116590000001],[-64.13500999999991,46.416382000000056],[-64.13305700000001,46.43332700000002],[-64.11582899999996,46.52304800000002],[-64.11332699999997,46.53472099999999],[-64.11000099999995,46.541107000000125],[-64.10555999999997,46.54583000000008],[-64.10028099999988,46.54972099999998],[-64.09416199999993,46.551659000000086],[-64.10555999999997,46.618050000000096],[-64.27389499999998,46.62332200000003],[-64.38751199999996,46.62082700000002],[-64.39195299999994,46.624709999999936],[-64.41389500000002,46.6658250000001],[-64.41555800000003,46.670547],[-64.41665599999993,46.68110699999994],[-64.41471899999999,46.69776900000011],[-64.41027799999995,46.71110500000009],[-64.40028399999994,46.72748600000011],[-64.38249200000001,46.74665800000008],[-64.34695399999998,46.77360500000003],[-64.32389799999993,46.786384999999996],[-64.29638699999998,46.80165900000003],[-64.28611799999993,46.80943300000007],[-64.27305599999994,46.82360799999998],[-64.24972499999996,46.86805000000004],[-64.24777199999994,46.87416100000013],[-64.2472229999999,46.879714999999976],[-64.24388099999999,46.88610800000009],[-64.23638900000003,46.897491000000116],[-64.22694399999995,46.906097000000045],[-64.18277,46.945541000000105],[-64.16861,46.956657000000064],[-64.02084400000001,47.03860500000013],[-63.99500299999994,46.984161000000086],[-63.969993999999986,46.901657],[-63.96749899999986,46.891662999999994],[-64.041382,46.82249500000006],[-64.06610099999995,46.80443600000012],[-64.07640100000003,46.79888199999999],[-64.09167499999995,46.77860300000003],[-64.07749899999993,46.756386000000134],[-64.07444800000002,46.75222000000002],[-64.06750499999993,46.74916100000007],[-64.03971899999999,46.74332400000009]],[[-55.87610599999999,47.26055100000002],[-55.96832999999987,47.25777399999993],[-55.94638800000001,47.27332300000006],[-55.934440999999936,47.279434000000094],[-55.89500399999997,47.29083300000002],[-55.888053999999954,47.29249600000014],[-55.881110999999976,47.29332699999998],[-55.872772,47.2922210000001],[-55.865836999999885,47.28777300000013],[-55.85500300000001,47.26971400000002],[-55.87610599999999,47.26055100000002]],[[-61.38055400000002,47.62027000000012],[-61.49305700000002,47.55249000000009],[-61.498610999999926,47.55027000000007],[-61.53556099999997,47.54583000000008],[-61.54222900000002,47.54554700000011],[-61.54778299999987,47.549164000000076],[-61.54944599999999,47.55387900000011],[-61.54527999999999,47.55943300000007],[-61.520279000000016,47.56916000000001],[-61.51389299999994,47.57249500000012],[-61.477492999999924,47.60054800000006],[-61.47361000000001,47.6055530000001],[-61.471382000000006,47.611382000000106],[-61.470551,47.61693600000012],[-61.47916399999997,47.61859900000002],[-61.534447,47.6188810000001],[-61.541945999999996,47.61721000000006],[-61.55944099999999,47.60916100000003],[-61.653610000000015,47.54999500000008],[-61.85555999999997,47.41721300000006],[-61.84972399999998,47.41360500000013],[-61.84166700000003,47.410820000000115],[-61.83361100000002,47.409988],[-61.789169000000015,47.42582700000008],[-61.777221999999995,47.43166400000007],[-61.76666299999994,47.439156000000025],[-61.71444700000001,47.48998999999998],[-61.69138299999997,47.515548999999965],[-61.70139299999994,47.49193600000007],[-61.74083699999994,47.44499200000007],[-61.84332999999992,47.388603000000046],[-61.90589099999994,47.35493500000001],[-61.92527799999999,47.34360500000014],[-61.93332700000002,47.33332799999994],[-61.96277600000002,47.2816620000001],[-61.965003999999965,47.27555100000001],[-61.964721999999995,47.27027100000009],[-61.961945000000014,47.26610600000009],[-61.95750399999997,47.26194000000004],[-61.93860599999999,47.257217000000026],[-61.82778200000001,47.23416100000003],[-61.81945000000002,47.233330000000024],[-61.80777699999999,47.23915900000003],[-61.79944599999999,47.25027499999993],[-61.79472399999992,47.254714999999976],[-61.78305799999987,47.26055100000002],[-61.782775999999956,47.25527200000005],[-61.789725999999916,47.242493000000024],[-61.79389200000003,47.23693800000012],[-61.79944599999999,47.23276499999997],[-61.81027999999998,47.22665400000005],[-61.816948000000025,47.224709000000075],[-61.84444400000001,47.21943699999997],[-61.85944399999988,47.21804799999995],[-61.955276000000026,47.21166200000005],[-61.97999599999997,47.213608000000136],[-61.9963909999999,47.21499600000004],[-62.004722999999956,47.2177660000001],[-62.01000199999987,47.22137500000008],[-62.01306199999999,47.225821999999994],[-62.01472499999994,47.23054500000012],[-62.01500699999991,47.235825000000034],[-62.01306199999999,47.24166100000008],[-61.94860799999998,47.37943299999995],[-61.94166599999994,47.39221999999995],[-61.93749999999994,47.39777400000014],[-61.92805499999997,47.407211000000075],[-61.92222599999997,47.409988],[-61.90888999999993,47.413879000000065],[-61.736114999999984,47.50721699999997],[-61.705832999999984,47.5324940000001],[-61.684440999999936,47.547492999999974],[-61.662216,47.56166100000007],[-61.61694299999999,47.588042999999914],[-61.57111400000002,47.613609],[-61.55361199999999,47.623046999999985],[-61.53583500000002,47.631659999999954],[-61.52916700000003,47.63360600000004],[-61.52111099999996,47.63443799999999],[-61.42527799999999,47.642769000000044],[-61.407775999999956,47.64110599999992],[-61.388892999999996,47.637771999999984],[-61.38194299999992,47.63443799999999],[-61.377776999999924,47.63110399999999],[-61.37610599999999,47.62638099999998],[-61.38055400000002,47.62027000000012]],[[-54.261391,47.39027400000009],[-54.26889,47.38971700000002],[-54.29305999999997,47.39166300000005],[-54.341385,47.398048000000074],[-54.35805499999998,47.403046000000074],[-54.36444899999998,47.406654],[-54.365554999999915,47.41165900000004],[-54.35972600000002,47.41666400000008],[-54.326392999999996,47.436653000000035],[-54.29527999999999,47.44999700000011],[-54.278053,47.46082300000006],[-54.26722000000001,47.469437000000084],[-54.26222200000001,47.47470900000002],[-54.25778199999996,47.48082000000011],[-54.230552999999986,47.52360500000003],[-54.22999600000003,47.55027000000007],[-54.20471999999995,47.59360500000008],[-54.13527699999986,47.66805300000004],[-54.12888299999997,47.670547],[-54.122772,47.66693900000007],[-54.12194099999999,47.66193400000003],[-54.12222299999996,47.656937000000084],[-54.12499999999994,47.640831000000105],[-54.16082799999998,47.534996000000035],[-54.23889200000002,47.40387700000008],[-54.24333199999995,47.39943700000009],[-54.25500499999998,47.3927690000001],[-54.261391,47.39027400000009]],[[-54.07749899999999,47.47943100000009],[-54.08306099999993,47.4749910000001],[-54.09305599999993,47.483047],[-54.096663999999976,47.487213000000054],[-54.101112,47.496384000000035],[-54.101944,47.501389000000074],[-54.099723999999924,47.55888399999998],[-54.09833500000002,47.589714000000015],[-54.097220999999934,47.60527000000013],[-54.09332999999998,47.631659999999954],[-54.08361099999996,47.67971799999992],[-54.07861299999996,47.68499000000003],[-54.07138800000001,47.68554699999993],[-54.06750499999998,47.68110700000011],[-54.06055500000002,47.651099999999985],[-54.078056000000004,47.56388100000004],[-54.05972300000002,47.53221100000013],[-54.05889100000002,47.52721400000007],[-54.07749899999999,47.47943100000009]],[[-55.90193899999986,47.60249300000004],[-55.92305799999991,47.59943400000009],[-55.947220000000016,47.60193600000014],[-56.01333599999998,47.61166400000002],[-56.097778000000005,47.62748700000003],[-56.105559999999855,47.630821000000026],[-56.10916900000001,47.63499500000006],[-56.11361699999998,47.64471400000002],[-56.11222099999998,47.64971900000012],[-56.10666699999996,47.65470900000014],[-56.10028099999994,47.65721100000002],[-56.00583599999999,47.680274999999995],[-55.94110899999998,47.68915600000014],[-55.93388399999998,47.68832400000002],[-55.92861199999993,47.684432999999956],[-55.927498000000014,47.67665899999997],[-55.934440999999936,47.65888200000012],[-55.934440999999936,47.65387700000002],[-55.932503,47.64388300000002],[-55.93000000000001,47.63943500000005],[-55.92639200000002,47.635268999999994],[-55.914161999999976,47.628326000000015],[-55.88944200000003,47.6188810000001],[-55.87638899999996,47.61166400000002],[-55.882499999999936,47.60777300000012],[-55.90193899999986,47.60249300000004]],[[-64.48277300000001,47.91777000000002],[-64.50167799999997,47.85638400000005],[-64.50361599999991,47.850273000000016],[-64.514725,47.832497000000046],[-64.523056,47.822220000000016],[-64.54110699999995,47.80332199999998],[-64.60499599999997,47.748329000000126],[-64.61054999999999,47.745270000000005],[-64.63583399999999,47.73582500000009],[-64.64750700000002,47.733879],[-64.69055199999997,47.75305200000014],[-64.69332899999995,47.75804900000003],[-64.70278899999994,47.82360799999998],[-64.697769,47.83610499999992],[-64.68554699999999,47.85221900000005],[-64.66749600000003,47.86693600000007],[-64.66221599999994,47.87082700000013],[-64.62416099999996,47.88471999999996],[-64.61776700000001,47.886658000000125],[-64.60916099999997,47.88693999999998],[-64.58416699999992,47.884995],[-64.50805700000001,47.90387700000002],[-64.48277300000001,47.91777000000002]],[[-64.56750499999993,47.89943699999998],[-64.57444800000002,47.89804799999996],[-64.58361799999989,47.89943699999998],[-64.589447,47.90277100000014],[-64.593887,47.90665400000006],[-64.59445199999993,47.911933999999974],[-64.59361299999989,47.918052999999986],[-64.531677,48.01610599999998],[-64.52694699999995,48.02165999999994],[-64.52278099999995,48.02555100000001],[-64.51695299999994,48.028602999999976],[-64.50973499999992,48.02999100000005],[-64.50111400000003,48.027488999999946],[-64.49554399999994,48.02388000000013],[-64.4908289999999,48.019989000000066],[-64.48582499999992,48.01305400000001],[-64.48277300000001,48.00860600000004],[-64.46972699999998,47.96971100000013],[-64.46916199999987,47.96443899999997],[-64.47055099999994,47.95332300000007],[-64.47444200000001,47.94776900000005],[-64.49638399999998,47.933876],[-64.51390100000003,47.924713],[-64.56750499999993,47.89943699999998]],[[-53.71277599999996,48.14888000000002],[-53.68972000000002,48.147217000000126],[-53.682503,48.14777400000003],[-53.66750300000001,48.15054299999997],[-53.64778100000001,48.155265999999926],[-53.615554999999915,48.16749600000003],[-53.583327999999995,48.18082400000003],[-53.57111399999991,48.186104000000114],[-53.56416299999995,48.19054399999993],[-53.55305499999997,48.19915800000001],[-53.539444,48.20221700000013],[-53.53167000000002,48.20277400000003],[-53.516395999999986,48.201935000000105],[-53.50972699999994,48.198326000000066],[-53.50917099999987,48.193321000000026],[-53.51083399999999,48.15082600000011],[-53.51250499999992,48.14527100000004],[-53.53082999999992,48.09777100000002],[-53.53639199999998,48.093323000000055],[-53.54944599999999,48.0886000000001],[-53.56361400000003,48.084991000000116],[-53.598884999999996,48.0794370000001],[-53.634170999999924,48.0752720000001],[-53.82333399999993,48.09276599999998],[-53.83943899999997,48.094437000000084],[-53.85611,48.098044999999956],[-53.871940999999936,48.10471300000012],[-53.87666300000001,48.108604000000014],[-53.93250299999994,48.17276799999996],[-53.93582900000001,48.18249500000013],[-53.93277699999999,48.198326000000066],[-53.929168999999945,48.209434999999985],[-53.92222599999997,48.212493999999936],[-53.90638699999994,48.21027400000014],[-53.89888799999994,48.20665700000001],[-53.860000999999954,48.17443800000012],[-53.85555999999997,48.169991000000095],[-53.71277599999996,48.14888000000002]],[[-123.47444200000001,48.709160000000054],[-123.48277300000001,48.70832800000011],[-123.48999000000003,48.70943500000004],[-123.51306199999993,48.716385000000116],[-123.52471899999989,48.722488000000055],[-123.54943800000001,48.74665800000008],[-123.551941,48.75222000000002],[-123.59277299999991,48.8983310000001],[-123.595551,48.90971400000012],[-123.59612299999998,48.928329000000076],[-123.59665699999994,48.946938000000046],[-123.59361299999995,48.94721199999998],[-123.58056599999992,48.93554700000004],[-123.57721699999996,48.929161000000136],[-123.53611799999999,48.914993000000095],[-123.53028899999998,48.911933999999974],[-123.45749699999993,48.86305200000004],[-123.43388400000003,48.844437000000084],[-123.37027,48.768326],[-123.36888099999993,48.762771999999984],[-123.37165800000002,48.75750000000005],[-123.37638900000002,48.75360899999998],[-123.43195300000002,48.72109999999998],[-123.47444200000001,48.709160000000054]],[[-58.34222399999999,49.06610100000012],[-58.349166999999966,49.064437999999996],[-58.356109999999944,49.06582600000013],[-58.35194399999989,49.0719380000001],[-58.341385,49.07638500000013],[-58.33361100000002,49.07777399999998],[-58.330558999999994,49.07332600000001],[-58.33583099999993,49.068885999999964],[-58.34222399999999,49.06610100000012]],[[-123.32277699999997,48.861107000000004],[-123.3705369999999,48.85638400000005],[-123.37888299999997,48.85694100000012],[-123.38474299999996,48.85999300000003],[-123.54055799999998,48.94499200000013],[-123.66251399999999,49.03527100000008],[-123.703888,49.09526800000003],[-123.70527599999997,49.10027300000007],[-123.70249899999999,49.105552999999986],[-123.695831,49.10804700000011],[-123.686394,49.106659000000036],[-123.68055700000002,49.10360700000007],[-123.674713,49.09304800000007],[-123.65943900000002,49.073608000000036],[-123.60444599999994,49.01471700000013],[-123.58640300000002,49.00054900000009],[-123.52166699999998,48.96027400000014],[-123.49916099999996,48.94721199999998],[-123.487503,48.94110100000006],[-123.45973200000003,48.93054999999998],[-123.43639399999995,48.92443800000001],[-123.42027299999995,48.92054700000011],[-123.38194299999992,48.910819999999944],[-123.32833900000003,48.89582799999994],[-123.32250999999991,48.89276899999999],[-123.31777999999997,48.88888500000013],[-123.31276700000001,48.87276500000007],[-123.3125,48.86805000000004],[-123.31639100000001,48.86332700000003],[-123.32277699999997,48.861107000000004]],[[-125.816101,49.12582400000014],[-125.82028200000002,49.12470999999999],[-125.86028299999998,49.134438000000046],[-125.906387,49.160820000000115],[-125.910278,49.16554300000007],[-125.92582699999991,49.190826000000015],[-125.93360899999993,49.21110499999992],[-125.93306000000001,49.218048000000124],[-125.93055700000002,49.21998600000006],[-125.92610200000001,49.22332000000006],[-125.87888299999992,49.23582499999998],[-125.86749299999997,49.23333000000014],[-125.82917800000001,49.22637900000001],[-125.81806899999987,49.220543000000134],[-125.79915599999998,49.20832800000005],[-125.78888699999993,49.17276800000013],[-125.79583699999995,49.1519320000001],[-125.79833999999994,49.14638500000001],[-125.81249999999994,49.12915800000013],[-125.816101,49.12582400000014]],[[-126.13194299999992,49.393325999999945],[-126.126938,49.39027400000003],[-126.12471,49.39027400000003],[-126.12053699999996,49.38860299999999],[-126.11054999999999,49.38221000000004],[-126.10665899999992,49.378601],[-126.09612300000003,49.368599000000074],[-126.08640300000002,49.35860400000013],[-126.07277699999997,49.34304800000001],[-126.0497279999999,49.265548999999965],[-126.0511019999999,49.260550999999964],[-126.05583200000001,49.25610400000011],[-126.06471299999987,49.250832],[-126.071121,49.24832900000001],[-126.07972699999999,49.24665800000014],[-126.0891719999999,49.24610100000007],[-126.09638999999999,49.24721500000004],[-126.18666100000002,49.263329],[-126.19167299999992,49.265548999999965],[-126.22332799999992,49.27971600000012],[-126.22944599999994,49.28249399999993],[-126.23916600000001,49.28971899999999],[-126.23473399999995,49.374161000000015],[-126.229172,49.378601],[-126.22138999999999,49.38054700000009],[-126.141388,49.39415699999995],[-126.13194299999992,49.393325999999945]],[[-123.37943999999999,49.326941999999974],[-123.39222699999999,49.326103000000046],[-123.41027799999995,49.33416],[-123.42194399999994,49.339714000000015],[-123.42666600000001,49.344154],[-123.42804699999999,49.348877000000016],[-123.42027299999995,49.38166000000001],[-123.41332999999997,49.38610799999998],[-123.3600009999999,49.411658999999986],[-123.35472099999998,49.41332200000011],[-123.327789,49.41666400000008],[-123.31696299999999,49.41749600000014],[-123.31221,49.41499299999998],[-123.30943300000001,49.41137700000013],[-123.31027199999994,49.40526600000004],[-123.31194299999993,49.401932000000045],[-123.327789,49.363052000000096],[-123.33112299999999,49.35499600000003],[-123.34472699999998,49.34193400000004],[-123.36833199999995,49.33027599999997],[-123.37943999999999,49.326941999999974]],[[-54.705276000000026,49.400543000000084],[-54.71277600000002,49.398330999999985],[-54.730278,49.40304600000002],[-54.73555799999997,49.40721100000002],[-54.75972699999994,49.43249500000002],[-54.75917099999998,49.43776699999995],[-54.75472300000001,49.44387800000004],[-54.74944299999993,49.449158000000125],[-54.73833499999995,49.45777100000009],[-54.68055699999991,49.49193600000001],[-54.67305799999991,49.49249300000008],[-54.66500100000002,49.489159000000086],[-54.64416499999999,49.47332],[-54.64028199999996,49.46915400000006],[-54.64083899999997,49.463881999999955],[-54.65471600000001,49.460823000000005],[-54.68444099999999,49.420547],[-54.699164999999994,49.40387700000008],[-54.705276000000026,49.400543000000084]],[[-124.179169,49.44110100000012],[-124.18554699999999,49.439986999999974],[-124.313606,49.45609999999999],[-124.32668299999995,49.460823000000005],[-124.36000099999995,49.474433999999974],[-124.36609599999997,49.477486000000056],[-124.37082699999996,49.481102000000135],[-124.37165799999997,49.48304700000011],[-124.38054699999998,49.506943000000035],[-124.38110399999994,49.511940000000095],[-124.37832599999996,49.51583099999999],[-124.37165799999997,49.518326],[-124.361107,49.519157000000064],[-124.35500299999995,49.51749400000011],[-124.34889199999998,49.51444200000003],[-124.30471799999992,49.51221499999997],[-124.24471999999997,49.50138900000002],[-124.23750299999995,49.498329000000126],[-124.22138999999993,49.49137900000011],[-124.1875,49.474433999999974],[-124.181671,49.47137500000002],[-124.17388900000003,49.45638299999996],[-124.17194399999994,49.446655000000135],[-124.17223399999989,49.444153000000085],[-124.179169,49.44110100000012]],[[-123.33277899999996,49.44110100000012],[-123.36028299999987,49.43305199999992],[-123.37499999999994,49.43332700000013],[-123.442207,49.43859900000007],[-123.448036,49.44165800000002],[-123.45944199999997,49.46720900000008],[-123.45973200000003,49.47054300000008],[-123.45305599999995,49.49554400000011],[-123.44526699999994,49.51527400000009],[-123.43666100000002,49.52221700000007],[-123.38082899999995,49.53611000000012],[-123.37000299999994,49.53611000000012],[-123.360817,49.53499599999998],[-123.3550029999999,49.53193699999997],[-123.33833300000003,49.50610400000005],[-123.33167999999995,49.500832000000116],[-123.32805599999995,49.49638399999998],[-123.32389799999993,49.488602000000014],[-123.319458,49.47470899999996],[-123.31777999999997,49.464157],[-123.319458,49.45193499999999],[-123.32224300000001,49.448043999999925],[-123.32695000000001,49.444153000000085],[-123.33277899999996,49.44110100000012]],[[-55.69554899999997,49.506943000000035],[-55.72582999999997,49.50555400000002],[-55.732497999999964,49.509163],[-55.73500100000001,49.51361099999997],[-55.736114999999984,49.518599999999935],[-55.735832000000016,49.52388000000002],[-55.73027799999994,49.545547000000056],[-55.72277100000002,49.55777000000012],[-55.716110000000015,49.560272],[-55.68499800000001,49.561104000000114],[-55.67694899999998,49.561104000000114],[-55.65833299999997,49.559158000000025],[-55.653052999999886,49.55526700000013],[-55.65222199999994,49.55027000000007],[-55.653885,49.54471600000005],[-55.66138499999994,49.529716000000064],[-55.664444,49.52388000000002],[-55.68111399999998,49.51082600000012],[-55.68749999999994,49.50804900000003],[-55.69554899999997,49.506943000000035]],[[-124.68943799999994,49.48027000000002],[-124.69611399999997,49.47776799999997],[-124.70221700000002,49.47804299999996],[-124.74137899999994,49.48804500000011],[-124.75361599999991,49.49137900000011],[-124.82362399999994,49.53943599999997],[-124.83666999999997,49.554993000000024],[-124.84111000000001,49.56276700000001],[-124.84249899999992,49.57860599999998],[-124.84194899999989,49.58415999999994],[-124.83416699999992,49.607773000000066],[-124.83168,49.61054999999999],[-124.82749899999993,49.60888700000004],[-124.81054699999993,49.58971400000013],[-124.80888400000003,49.58665500000001],[-124.80583200000001,49.58582300000006],[-124.77887699999997,49.56888600000008],[-124.68804899999986,49.483604000000014],[-124.68943799999994,49.48027000000002]],[[-55.69305399999996,49.56749700000006],[-55.70916699999998,49.56638300000009],[-55.71665999999993,49.567214999999976],[-55.72083299999997,49.57138100000009],[-55.72305299999999,49.57610299999999],[-55.72277100000002,49.58138300000007],[-55.70583299999993,49.613883999999985],[-55.68499800000001,49.624992000000134],[-55.673888999999974,49.630547000000035],[-55.659720999999934,49.63555100000002],[-55.653052999999886,49.63638300000008],[-55.572776999999974,49.603882],[-55.567504999999926,49.59999800000014],[-55.573058999999944,49.595543000000134],[-55.58638799999994,49.59137700000008],[-55.60805499999998,49.586104999999975],[-55.67166900000001,49.57138100000009],[-55.69305399999996,49.56749700000006]],[[-54.576667999999984,49.558601000000124],[-54.77305599999994,49.49388099999999],[-54.80944099999999,49.48804500000011],[-54.83916499999998,49.48443600000013],[-54.85583500000001,49.48443600000013],[-54.86306000000002,49.48526800000002],[-54.871940999999936,49.48749500000008],[-54.87305500000002,49.49221800000009],[-54.89361600000001,49.58055100000013],[-54.894447000000014,49.58526599999999],[-54.89194500000002,49.590546000000074],[-54.885276999999974,49.593048000000124],[-54.805556999999965,49.59582500000005],[-54.79222899999996,49.572768999999994],[-54.79333500000001,49.56693999999999],[-54.79167199999989,49.56249200000002],[-54.78833800000001,49.55777000000012],[-54.78417200000001,49.554161000000136],[-54.76860799999997,49.54666100000003],[-54.760001999999986,49.545547000000056],[-54.743889000000024,49.544998000000135],[-54.729720999999984,49.548050000000046],[-54.70861100000002,49.55443600000012],[-54.61472299999997,49.60610200000002],[-54.57472200000001,49.63526900000011],[-54.56194299999993,49.65360300000009],[-54.54888900000003,49.659988000000055],[-54.53611799999993,49.664153999999996],[-54.52972399999999,49.63388100000003],[-54.53166999999996,49.62221500000004],[-54.538054999999986,49.587494000000106],[-54.543334999999956,49.582497000000046],[-54.57055700000001,49.562209999999936],[-54.576667999999984,49.558601000000124]],[[-54.004448000000025,49.647491000000116],[-54.25778199999996,49.566666000000055],[-54.26583900000003,49.56693999999999],[-54.274719000000005,49.56916000000001],[-54.289444,49.57610299999999],[-54.29333500000001,49.58055100000013],[-54.29888899999992,49.60999300000009],[-54.29778299999998,49.6511000000001],[-54.28805499999993,49.71138000000002],[-54.282775999999956,49.716660000000104],[-54.26999699999999,49.722488],[-54.14194500000002,49.75],[-54.10222599999997,49.75027499999999],[-54.09388699999994,49.74887800000005],[-54.085830999999985,49.74554400000005],[-54.08111599999995,49.736381999999935],[-54.04000099999996,49.68998700000009],[-54.00305899999995,49.659988000000055],[-54.004448000000025,49.647491000000116]],[[-124.129707,49.650825999999995],[-124.139183,49.65054300000003],[-124.15361000000001,49.65554800000007],[-124.18694299999993,49.66888399999999],[-124.196663,49.676941],[-124.20195000000001,49.70193499999999],[-124.19943199999989,49.70609999999999],[-124.14750699999996,49.746658000000025],[-124.14277600000003,49.75],[-124.13722199999995,49.752219999999966],[-124.09166699999997,49.7677690000001],[-124.03611799999999,49.77721400000013],[-124.029449,49.7783280000001],[-124.021118,49.77777100000003],[-124.01611299999996,49.77555100000001],[-124.01862299999999,49.77165999999994],[-124.02555799999993,49.7677690000001],[-124.046112,49.75638600000008],[-124.06054699999999,49.74499500000013],[-124.07472200000001,49.733330000000024],[-124.090843,49.71554600000013],[-124.10109699999992,49.70027200000004],[-124.10555999999991,49.689430000000016],[-124.10722399999992,49.67721599999999],[-124.11081699999994,49.664992999999924],[-124.11361699999998,49.65971399999995],[-124.12304699999993,49.65193199999999],[-124.129707,49.650825999999995]],[[-56.80361199999993,49.763329000000056],[-56.82749899999999,49.76110799999998],[-56.83555599999994,49.762771999999984],[-56.83805099999995,49.767494000000056],[-56.832779000000016,49.771934999999985],[-56.826667999999984,49.77526899999998],[-56.79250300000001,49.78555299999999],[-56.782219,49.78694200000001],[-56.78194400000001,49.78082299999994],[-56.79084,49.768326],[-56.79666900000001,49.764999000000046],[-56.80361199999993,49.763329000000056]],[[-124.44611399999991,49.723320000000115],[-124.43749999999994,49.72304500000013],[-124.42887899999994,49.723877000000016],[-124.41000400000001,49.72304500000013],[-124.38137799999998,49.71332600000011],[-124.35138699999999,49.698044000000095],[-124.33277900000002,49.68332700000008],[-124.13474300000001,49.52526900000004],[-124.13221699999991,49.52027100000004],[-124.12416100000002,49.49916100000007],[-124.122772,49.493607000000054],[-124.12748699999997,49.48971599999999],[-124.13417099999992,49.48749500000008],[-124.14167799999996,49.48582500000009],[-124.14916999999997,49.486107000000004],[-124.15527299999985,49.488602000000014],[-124.281387,49.54666100000003],[-124.40583800000002,49.60582699999998],[-124.43804899999998,49.62887599999999],[-124.44220699999994,49.63804600000003],[-124.47666900000002,49.67193600000013],[-124.5396649999999,49.692768],[-124.55249799999996,49.69710500000002],[-124.56167599999998,49.69993599999992],[-124.61416600000001,49.713607999999965],[-124.62721299999993,49.71915400000006],[-124.65416699999997,49.73610700000012],[-124.66082799999992,49.74276700000013],[-124.65666199999993,49.79694399999994],[-124.65110800000002,49.79999500000014],[-124.61945300000002,49.79721800000004],[-124.604446,49.78943600000014],[-124.59944199999995,49.78443900000002],[-124.59028599999999,49.77165999999994],[-124.56234,49.753326000000015],[-124.55933399999998,49.751495000000034],[-124.49472000000003,49.733330000000024],[-124.44611399999991,49.723320000000115]],[[-126.67610199999996,49.58360300000004],[-126.68138099999993,49.58305400000012],[-126.68888899999996,49.583878000000084],[-126.69722000000002,49.585548000000074],[-126.78971899999999,49.61221300000011],[-126.80803699999996,49.61971299999999],[-126.81416299999995,49.62276500000007],[-126.90556300000003,49.6855470000001],[-126.96528599999999,49.72693599999997],[-126.96945199999999,49.73110200000008],[-126.97416699999991,49.740273],[-126.97556299999997,49.75],[-126.94055200000003,49.83138300000002],[-126.890556,49.84777100000008],[-126.79915599999993,49.87609900000001],[-126.77749599999993,49.87971500000009],[-126.76872299999997,49.87861600000008],[-126.74944299999999,49.85694100000012],[-126.73416099999997,49.84804500000001],[-126.67804699999994,49.8252720000001],[-126.64472999999992,49.77416200000005],[-126.636124,49.75943799999999],[-126.63445300000001,49.75388300000009],[-126.61332699999997,49.648330999999985],[-126.61609599999997,49.62443500000006],[-126.62053699999996,49.60610200000002],[-126.62416099999996,49.60138699999999],[-126.63305700000001,49.596100000000035],[-126.66861,49.585548000000074],[-126.67610199999996,49.58360300000004]],[[-62.08972199999988,49.38638300000014],[-62.08139,49.38555100000008],[-62.051665999999955,49.39027400000003],[-62.04361699999993,49.39054900000008],[-62.02527600000002,49.38749700000011],[-61.892226999999934,49.351387000000045],[-61.875557000000015,49.34499400000004],[-61.825835999999924,49.31220999999999],[-61.82111400000002,49.30888399999998],[-61.66332999999992,49.14916200000005],[-61.661666999999966,49.144439999999975],[-61.670837000000006,49.134163],[-61.70222499999994,49.111107000000004],[-61.73555799999997,49.09609999999998],[-61.79611199999994,49.078048999999965],[-62.01999699999999,49.069443000000035],[-62.02916700000003,49.069443000000035],[-62.19554900000003,49.07499700000005],[-62.36805700000002,49.0991590000001],[-62.72610500000002,49.154709000000025],[-62.782218999999884,49.165824999999984],[-62.946662999999944,49.19887499999999],[-63.089995999999985,49.228043000000014],[-63.097778000000005,49.23054500000012],[-63.209442000000024,49.270827999999995],[-63.23082699999992,49.28027300000002],[-63.24277499999994,49.287498000000085],[-63.25305900000001,49.294997999999964],[-63.26999699999999,49.311104],[-63.27583299999998,49.31471299999998],[-63.283332999999914,49.317771999999934],[-63.38722199999995,49.34388000000007],[-63.41694599999988,49.35082999999997],[-63.501296999999965,49.370384000000115],[-63.53722399999987,49.379714999999976],[-63.573058999999944,49.39666000000011],[-63.61611199999993,49.4469380000001],[-63.62194099999988,49.45555100000007],[-63.620833999999945,49.46110500000009],[-63.61666099999991,49.46665999999999],[-63.61333499999995,49.473044999999956],[-63.61250299999995,49.47887399999996],[-63.61611199999993,49.48832700000003],[-63.61972000000003,49.492767000000015],[-63.66277299999996,49.533051],[-63.67888599999992,49.54471600000005],[-63.71444699999989,49.56638300000009],[-63.84194199999996,49.639160000000004],[-63.88194299999998,49.65915700000005],[-63.918334999999956,49.67443800000001],[-64.01556399999987,49.70249200000006],[-64.30694599999993,49.777489],[-64.38221699999997,49.78943600000014],[-64.38999899999993,49.789719000000105],[-64.41833500000001,49.80165899999997],[-64.511124,49.858604000000014],[-64.51390100000003,49.863609000000054],[-64.51028399999996,49.86859900000013],[-64.50111400000003,49.87804399999999],[-64.49610899999988,49.883049000000085],[-64.4908289999999,49.886939999999925],[-64.472778,49.89582800000011],[-64.458618,49.90082600000011],[-64.44554099999999,49.90443400000004],[-64.22694399999995,49.948326000000066],[-64.20361300000002,49.950271999999984],[-64.14277599999997,49.94804400000004],[-64.13305700000001,49.94721200000009],[-64.12388599999997,49.945267000000115],[-64.02917500000001,49.92443800000012],[-63.95889299999993,49.89804800000013],[-63.61583699999994,49.849158999999986],[-63.545006,49.84332300000011],[-63.49222599999996,49.840828000000045],[-63.47527299999996,49.84054600000002],[-63.34694699999994,49.8202740000001],[-63.30972299999996,49.81388099999998],[-63.13611599999996,49.78082299999994],[-63.07444799999996,49.76416000000006],[-62.99610899999999,49.736656000000096],[-62.78666700000002,49.6763840000001],[-62.71055599999994,49.66082],[-62.54555499999998,49.59999800000014],[-62.44361099999992,49.5472180000001],[-62.340553,49.48693800000001],[-62.21221899999995,49.41443600000008],[-62.205832999999984,49.41137700000013],[-62.18888900000002,49.40582300000011],[-62.16916699999996,49.401099999999985],[-62.09916700000002,49.387771999999984],[-62.08972199999988,49.38638300000014]],[[-124.92415599999998,50.05860100000001],[-124.96861299999995,50.03582799999998],[-125.00055699999996,50.05665600000003],[-125.06304899999998,50.103324999999984],[-125.06696299999999,50.107498000000135],[-125.066101,50.11388400000004],[-125.0625,50.11832400000009],[-125.03971899999999,50.13054699999992],[-124.991669,50.16832700000003],[-124.98222399999992,50.17610200000013],[-124.98055999999991,50.18221299999999],[-124.98332199999999,50.225548],[-124.93138099999993,50.17110400000013],[-124.92859599999997,50.16610000000014],[-124.91528299999999,50.14138000000008],[-124.89778100000001,50.07749200000006],[-124.92415599999998,50.05860100000001]],[[-63.859443999999996,50.19776899999994],[-63.87361099999998,50.194435],[-63.89028200000001,50.194709999999986],[-63.899993999999936,50.19609800000006],[-63.90860700000002,50.19860100000005],[-63.91610700000001,50.201660000000004],[-63.920837000000006,50.20555100000007],[-63.93055700000002,50.218597000000045],[-63.931389000000024,50.22387700000007],[-63.93055700000002,50.22943100000009],[-63.92694899999992,50.236107000000004],[-63.92277499999989,50.24166100000002],[-63.91666399999997,50.244713000000104],[-63.90999599999992,50.24665800000014],[-63.90193899999997,50.24721500000004],[-63.889725,50.24221800000009],[-63.865554999999915,50.22832500000004],[-63.859443999999996,50.22470900000002],[-63.85472099999993,50.22082499999999],[-63.85278299999999,50.21610300000009],[-63.85361499999999,50.21054800000002],[-63.85583500000001,50.2044370000001],[-63.859443999999996,50.19776899999994]],[[-125.16777000000002,49.98081999999994],[-125.16999800000002,49.98081999999994],[-125.17111199999994,49.98165900000009],[-125.18582199999997,50.004166],[-125.20722999999998,50.04499800000002],[-125.21417199999996,50.06999200000001],[-125.28167699999989,50.11332700000014],[-125.31777999999986,50.13610799999998],[-125.32362399999994,50.143326],[-125.33999599999993,50.20304900000002],[-125.34916699999997,50.24249300000014],[-125.34973100000002,50.25777400000004],[-125.348343,50.26166500000011],[-125.34554299999996,50.26390100000003],[-125.33999599999993,50.26888300000013],[-125.31082200000003,50.28138000000013],[-125.26334400000002,50.29388399999999],[-125.25472999999988,50.29361000000006],[-125.24638399999998,50.290549999999996],[-125.24333199999995,50.28832999999997],[-125.16722099999987,50.21360800000008],[-125.16111799999999,50.2002720000001],[-125.16000400000001,50.1905440000001],[-125.18666100000002,50.14166300000005],[-125.1536099999999,50.00610399999994],[-125.15416699999997,50.000832],[-125.16416900000002,49.98526800000013],[-125.16777000000002,49.98081999999994]],[[-124.8125,50.11138199999999],[-124.821121,50.11110700000012],[-124.82749899999993,50.11193799999995],[-124.83361799999989,50.11444100000011],[-124.86110699999989,50.13638300000002],[-124.93916299999995,50.20777100000009],[-124.96305799999999,50.23638200000005],[-124.96610999999996,50.246941000000106],[-124.96556099999992,50.25166300000001],[-124.92304999999993,50.29638699999998],[-124.91832699999986,50.29972099999992],[-124.91082799999998,50.29999500000008],[-124.90249599999999,50.29833200000013],[-124.89862099999999,50.29388399999999],[-124.87581599999993,50.28472099999999],[-124.82167099999992,50.239716000000044],[-124.75666799999999,50.17832899999996],[-124.75250199999999,50.16777000000013],[-124.752228,50.16137699999996],[-124.75499699999995,50.1560970000001],[-124.80695300000002,50.11388400000004],[-124.8125,50.11138199999999]],[[-124.73082699999992,50.30221599999999],[-124.72693599999997,50.29916400000002],[-124.72471599999994,50.29916400000002],[-124.69554099999999,50.28943600000002],[-124.68331899999993,50.283333000000084],[-124.67250100000001,50.27610000000004],[-124.66860999999994,50.27249100000006],[-124.66111799999993,50.263054000000125],[-124.65943900000002,50.25833099999994],[-124.65750099999997,50.24777200000011],[-124.65611299999989,50.23137700000001],[-124.65834000000001,50.21221200000002],[-124.66000399999996,50.20749699999999],[-124.66251399999999,50.203323000000125],[-124.695831,50.15749400000004],[-124.70195000000001,50.15860000000009],[-124.70805399999995,50.16137699999996],[-124.79222099999993,50.22526600000009],[-124.79499800000002,50.22887400000002],[-124.78083800000002,50.26944000000003],[-124.77778599999999,50.27748900000006],[-124.74500299999994,50.29943799999995],[-124.74054699999994,50.30193300000002],[-124.73082699999992,50.30221599999999]],[[-125.54387700000001,50.39388300000002],[-125.63583399999999,50.379714999999976],[-125.693604,50.383331],[-125.70333899999991,50.384163000000115],[-125.75527999999997,50.391662999999994],[-125.762787,50.39415700000012],[-125.76363400000002,50.397491000000116],[-125.75527999999997,50.40554800000007],[-125.74416399999996,50.40776800000009],[-125.59528399999999,50.43305200000009],[-125.58640300000002,50.43415800000014],[-125.52390300000002,50.434433000000126],[-125.51889,50.431381000000044],[-125.51806599999998,50.42860400000012],[-125.51777600000003,50.40943100000004],[-125.520554,50.40332000000012],[-125.52500899999995,50.400825999999995],[-125.53639199999998,50.395827999999995],[-125.54387700000001,50.39388300000002]],[[-125.16555800000003,50.37443500000006],[-125.061394,50.24054700000005],[-125.05194099999989,50.226653999999996],[-125.05027799999993,50.22165700000011],[-125.048607,50.20777100000009],[-125.04915599999993,50.19332099999997],[-125.05166599999995,50.19082600000013],[-125.11638599999998,50.13665800000001],[-125.12917299999998,50.126098999999954],[-125.13390400000003,50.12276499999996],[-125.14028899999994,50.121658000000025],[-125.14472999999987,50.12193300000007],[-125.15083299999998,50.12499200000002],[-125.15416699999997,50.133331000000055],[-125.13971699999996,50.1594310000001],[-125.15611299999995,50.23915899999997],[-125.21083099999993,50.31304899999992],[-125.21362299999993,50.316666000000055],[-125.22000099999991,50.318329000000006],[-125.26363400000002,50.32360799999998],[-125.27194199999997,50.32388300000002],[-125.31555199999997,50.31805400000002],[-125.32112099999989,50.31693999999999],[-125.32695000000001,50.31388100000004],[-125.33306900000002,50.30443599999995],[-125.33473200000003,50.29972099999992],[-125.3394469999999,50.29583000000008],[-125.35610999999994,50.29027600000006],[-125.37222300000002,50.28943600000002],[-125.38527699999997,50.289993000000095],[-125.390289,50.29222100000004],[-125.39306599999998,50.29583000000008],[-125.39917000000003,50.311104000000114],[-125.400284,50.320831000000055],[-125.39943699999998,50.331108000000086],[-125.39806399999998,50.333878000000084],[-125.391953,50.340546000000074],[-125.291946,50.433876000000055],[-125.28443899999996,50.435822000000144],[-125.27500900000001,50.43332700000013],[-125.27306399999992,50.43110700000011],[-125.23665599999993,50.4158250000001],[-125.21640000000002,50.40470900000014],[-125.16555800000003,50.37443500000006]],[[-125.42610200000001,50.3555530000001],[-125.45777899999996,50.34943400000009],[-125.46749899999998,50.350273000000016],[-125.52610800000002,50.37887599999999],[-125.52806099999998,50.381660000000124],[-125.51862299999993,50.39027400000003],[-125.47749299999998,50.42416400000013],[-125.471657,50.42748999999998],[-125.465012,50.42999300000014],[-125.37998999999996,50.460823000000005],[-125.37165799999997,50.45777100000004],[-125.37082699999996,50.45582600000006],[-125.36665299999993,50.45416299999994],[-125.34306300000003,50.44165800000002],[-125.33194700000001,50.4355470000001],[-125.33000199999998,50.43082400000014],[-125.33056599999986,50.425270000000125],[-125.33693700000003,50.416664000000026],[-125.38583399999999,50.36971299999999],[-125.39835399999998,50.36415900000003],[-125.42610200000001,50.3555530000001]],[[-125.80721999999997,50.413605000000075],[-125.90695199999993,50.40971400000001],[-125.92194399999988,50.41027100000008],[-125.92804699999999,50.411658999999986],[-125.93110699999988,50.41387900000001],[-125.95111099999997,50.433876000000055],[-125.93943799999988,50.443047000000035],[-125.90583799999996,50.45638300000013],[-125.81416299999995,50.46804800000001],[-125.80777,50.46776599999998],[-125.80359599999997,50.46554600000013],[-125.79055799999998,50.45694000000003],[-125.74109599999997,50.43166400000001],[-125.73805199999998,50.42804700000005],[-125.73805199999998,50.42665899999997],[-125.74276700000001,50.42416400000013],[-125.75834700000001,50.41999099999998],[-125.79110700000001,50.41499299999998],[-125.80721999999997,50.413605000000075]],[[-126.22582999999997,50.55526700000013],[-126.30888399999998,50.52832799999999],[-126.33640299999996,50.52166],[-126.35056299999997,50.52027099999998],[-126.486107,50.51554900000008],[-126.58805799999999,50.521378000000084],[-126.60417199999995,50.52526899999998],[-126.623894,50.53388199999995],[-126.60417199999995,50.539719000000105],[-126.57444800000002,50.546387000000095],[-126.55695300000002,50.54860700000012],[-126.54194599999994,50.54943800000012],[-126.52667200000002,50.548882000000106],[-126.48860200000001,50.55332199999992],[-126.381104,50.574715000000026],[-126.28611799999999,50.59832799999998],[-126.28278399999999,50.59748800000011],[-126.22609699999998,50.564156000000025],[-126.223053,50.560546999999985],[-126.224716,50.55665599999992],[-126.22582999999997,50.55526700000013]],[[-126.46639999999996,50.575829000000056],[-126.47501399999993,50.57555400000001],[-126.47917199999995,50.576385000000016],[-126.535553,50.59054600000002],[-126.54915599999998,50.59638200000006],[-126.55222300000003,50.598602000000085],[-126.554169,50.60277600000012],[-126.55248999999998,50.60749800000002],[-126.55027799999999,50.60860400000007],[-126.54360999999994,50.61138200000005],[-126.52916699999997,50.61499800000013],[-126.45361299999996,50.626937999999996],[-126.40499899999992,50.62609900000007],[-126.385559,50.625549000000035],[-126.37721299999993,50.623877999999934],[-126.364441,50.619438000000116],[-126.36138900000003,50.61582900000013],[-126.36165599999998,50.61305200000004],[-126.36971999999992,50.60582699999998],[-126.38027999999997,50.598602000000085],[-126.38474300000001,50.596100000000035],[-126.39138799999995,50.59276600000004],[-126.39806399999998,50.59110300000009],[-126.46639999999996,50.575829000000056]],[[-59.34583299999997,50.53388199999995],[-59.353888999999924,50.53388199999995],[-59.358337000000006,50.537773000000016],[-59.384170999999924,50.633049000000085],[-59.384170999999924,50.638329],[-59.38277399999998,50.64388300000013],[-59.37805199999991,50.64916199999993],[-59.37194099999999,50.65277100000014],[-59.36444899999998,50.653876999999966],[-59.35500300000001,50.65221400000007],[-59.337775999999906,50.64083100000005],[-59.333610999999905,50.636108000000036],[-59.32167099999998,50.618881000000044],[-59.305556999999965,50.59165999999999],[-59.30027799999999,50.58194000000009],[-59.29833999999994,50.57249500000006],[-59.29833999999994,50.56193500000012],[-59.30889100000002,50.553047000000106],[-59.32055700000001,50.545830000000024],[-59.33306099999987,50.53943600000014],[-59.34583299999997,50.53388199999995]],[[-126.87332200000003,50.66332200000005],[-126.83416699999998,50.63416300000006],[-126.83112299999999,50.62915800000002],[-126.83583099999998,50.62526700000012],[-126.90249599999993,50.61388399999993],[-126.91251399999999,50.61360900000011],[-127.016663,50.638329],[-127.025284,50.63999200000006],[-127.04276999999996,50.63749700000005],[-127.05832700000002,50.63249200000001],[-127.10193600000002,50.627486999999974],[-127.12249800000001,50.62721300000004],[-127.13221699999991,50.62832600000013],[-127.14055599999995,50.62971500000009],[-127.14472999999998,50.63388100000003],[-127.14334100000002,50.63888500000013],[-127.13166799999999,50.65221400000007],[-127.12721299999998,50.65609699999999],[-127.10916099999997,50.66526799999997],[-127.093887,50.669159000000036],[-127.08640300000002,50.66971600000011],[-126.89028899999994,50.66721300000012],[-126.87970699999994,50.66610000000003],[-126.87332200000003,50.66332200000005]],[[-126.64388999999994,50.691933000000006],[-126.65249599999999,50.691376000000105],[-126.65888999999993,50.694435000000055],[-126.662781,50.69860099999994],[-126.66583300000002,50.70332300000001],[-126.69027699999998,50.75499700000006],[-126.68554699999993,50.75888800000013],[-126.66832699999998,50.759163000000115],[-126.60221899999999,50.77082800000005],[-126.58277900000002,50.76971400000002],[-126.54387700000001,50.765831000000105],[-126.53639199999992,50.76361100000008],[-126.53582799999998,50.75860600000004],[-126.63806199999993,50.69499200000013],[-126.64388999999994,50.691933000000006]],[[-55.56472000000002,50.69971499999991],[-55.58000199999992,50.69832600000012],[-55.58888999999999,50.699431999999945],[-55.64527899999996,50.71888000000007],[-55.65166499999998,50.72304500000007],[-55.653052999999886,50.72721100000001],[-55.62943999999993,50.78082300000011],[-55.62471800000003,50.78721600000006],[-55.619163999999955,50.791382],[-55.46277599999996,50.80582400000014],[-55.454444999999964,50.80248999999998],[-55.45055400000001,50.798332000000016],[-55.44972200000001,50.792770000000075],[-55.45472000000001,50.788048],[-55.46694199999996,50.784163999999976],[-55.512504999999976,50.72276300000004],[-55.52500199999997,50.71582799999999],[-55.55139200000002,50.70332300000001],[-55.557503,50.70138500000007],[-55.56472000000002,50.69971499999991]],[[-126.27306399999998,50.65277100000014],[-126.46333300000003,50.64166299999994],[-126.56806899999998,50.6483310000001],[-126.58416699999992,50.65026900000004],[-126.59889199999998,50.65415999999993],[-126.60637699999995,50.65721100000013],[-126.612503,50.659988000000055],[-126.61749299999997,50.664993000000095],[-126.61749299999997,50.66777000000002],[-126.545837,50.72609699999998],[-126.43721,50.78388200000012],[-126.38971699999996,50.806381000000044],[-126.38221699999997,50.808043999999995],[-126.28056299999997,50.82833100000005],[-126.26640299999997,50.82777399999998],[-126.25805699999995,50.824715000000026],[-126.2538909999999,50.8219380000001],[-126.25171699999987,50.818932000000075],[-126.23832699999997,50.81110400000006],[-126.22944599999994,50.803322000000094],[-126.17832900000002,50.75083200000006],[-126.17722299999997,50.748604000000114],[-126.17666600000001,50.7438810000001],[-126.25305200000003,50.69964600000009],[-126.25611900000001,50.66137700000007],[-126.26083399999999,50.65721100000013],[-126.26640299999997,50.65470900000008],[-126.27306399999998,50.65277100000014]],[[-126.73137700000001,50.771934999999985],[-126.79778299999992,50.76888300000002],[-126.807503,50.769989000000066],[-126.85333300000002,50.78276799999992],[-126.86472299999997,50.78943600000008],[-126.90583799999996,50.82276900000011],[-126.90139799999992,50.8252720000001],[-126.88806199999999,50.829162999999994],[-126.88137799999993,50.830276000000026],[-126.64862099999999,50.84721400000012],[-126.64334100000002,50.846939000000134],[-126.63583399999999,50.84526800000003],[-126.62943999999993,50.842490999999995],[-126.58860800000002,50.82138100000003],[-126.56806899999998,50.80777000000006],[-126.56304899999992,50.79999500000014],[-126.56861900000001,50.79749300000009],[-126.73137700000001,50.771934999999985]],[[-127.22693599999991,50.636108000000036],[-126.975281,50.57694200000009],[-126.85472099999993,50.55443600000012],[-126.77639799999997,50.54610400000013],[-126.76806599999998,50.544441000000006],[-126.72138999999999,50.53193699999997],[-126.70527600000003,50.527489],[-126.63999899999999,50.50777399999998],[-126.62332199999992,50.498329000000126],[-126.56388899999996,50.483604000000014],[-126.49388099999993,50.481934000000024],[-126.39472999999998,50.48165899999998],[-126.38694800000002,50.48276500000003],[-126.35582699999998,50.48333000000008],[-126.327789,50.48082000000005],[-126.22112299999998,50.46859699999999],[-126.20500199999992,50.466660000000104],[-126.15471600000001,50.45943500000004],[-126.06916799999999,50.43859900000007],[-126.04611199999994,50.43249500000002],[-126.031387,50.427773000000116],[-126.01889,50.42193600000013],[-125.97609699999992,50.39499699999999],[-125.96250900000001,50.388885000000016],[-125.94776899999994,50.38499500000006],[-125.92859599999997,50.382209999999986],[-125.81696299999999,50.3780440000001],[-125.58000199999987,50.36582899999996],[-125.56416300000001,50.363883999999985],[-125.54860699999989,50.35916100000003],[-125.46305799999993,50.32971999999995],[-125.44972200000001,50.32360799999998],[-125.44055200000003,50.318329000000006],[-125.43554699999999,50.31471299999998],[-125.431671,50.31054700000004],[-125.42887899999994,50.30554999999998],[-125.42722300000003,50.29999500000008],[-125.42666599999995,50.29388399999999],[-125.42722300000003,50.287498000000085],[-125.41500899999994,50.26166500000011],[-125.39362299999999,50.21554600000002],[-125.37777699999998,50.17971799999998],[-125.36277799999993,50.13804600000009],[-125.33084099999996,50.11388400000004],[-125.28694199999995,50.08138300000013],[-125.229446,50.026657],[-125.221657,50.01805100000007],[-125.21611000000001,50.001389000000074],[-125.21417199999996,49.976379000000065],[-125.212784,49.97082500000005],[-125.20722999999998,49.96166200000005],[-125.16860999999994,49.91276600000003],[-125.11221299999994,49.86832400000009],[-124.99305699999991,49.78833000000009],[-124.89806399999998,49.73165899999998],[-124.89138799999989,49.66471100000007],[-124.91639700000002,49.631660000000124],[-124.86028299999992,49.54166399999997],[-124.85305800000003,49.5324940000001],[-124.83306900000002,49.51082600000012],[-124.78943599999991,49.464157],[-124.579453,49.38749700000011],[-124.55110200000001,49.3780440000001],[-124.535553,49.37387800000005],[-124.51917300000002,49.37027000000012],[-124.26083399999993,49.315269],[-124.12193299999996,49.27027100000009],[-123.94304699999992,49.21110499999992],[-123.85637699999995,49.14916200000005],[-123.86028299999992,49.153046000000074],[-123.86638599999998,49.160820000000115],[-123.86805700000002,49.16443600000014],[-123.87110899999988,49.17360700000012],[-123.87138399999998,49.181107],[-123.86638599999998,49.18637800000005],[-123.86165599999993,49.18888099999998],[-123.84999099999999,49.191658000000075],[-123.82444800000002,49.192764000000125],[-123.82055699999995,49.1905440000001],[-123.80722000000003,49.18027500000005],[-123.79444899999993,49.173325000000034],[-123.78859699999998,49.17027300000012],[-123.76944700000001,49.16304800000006],[-123.73805199999993,49.15443399999998],[-123.71112099999999,49.14999399999999],[-123.70417800000001,49.147491],[-123.699432,49.14388300000007],[-123.696663,49.14027400000009],[-123.69638099999997,49.13555100000008],[-123.69915799999995,49.130272000000105],[-123.703888,49.12638100000004],[-123.73137700000001,49.11749300000008],[-123.74166899999989,49.11804999999998],[-123.83750899999995,49.14138000000014],[-123.85056299999997,49.145546000000024],[-123.81027199999994,49.115829000000076],[-123.75195300000001,49.04083300000002],[-123.74944299999999,49.03527100000008],[-123.7502899999999,49.02915999999999],[-123.75695799999994,48.98693800000012],[-123.75862099999989,48.980819999999994],[-123.76334399999996,48.97693600000014],[-123.69193999999993,48.908325000000104],[-123.68222000000003,48.90221400000007],[-123.5911099999999,48.83998900000012],[-123.58277900000002,48.83194000000009],[-123.56555199999997,48.789719000000105],[-123.56304899999998,48.77832799999999],[-123.56471299999993,48.74971800000009],[-123.50945300000001,48.58749399999999],[-123.47666899999996,48.631660000000124],[-123.47083999999995,48.67332499999998],[-123.46916199999993,48.67943600000001],[-123.464447,48.68332700000008],[-123.45973200000003,48.685822000000144],[-123.45140100000003,48.68665299999998],[-123.44193999999999,48.68665299999998],[-123.41639699999996,48.684433000000126],[-123.40110800000002,48.681381000000044],[-123.39639299999999,48.677773000000116],[-123.34973099999996,48.54777500000006],[-123.34834299999994,48.535828000000095],[-123.29527300000001,48.48471800000004],[-123.291672,48.48082000000011],[-123.27861000000001,48.45610000000005],[-123.27610800000002,48.4511030000001],[-123.276947,48.44554099999999],[-123.28694200000001,48.41860200000002],[-123.28971899999999,48.41332199999994],[-123.29444899999993,48.409714000000065],[-123.30082699999997,48.406654],[-123.3205569999999,48.399437000000034],[-123.33640299999996,48.396942000000024],[-123.36028299999987,48.39721700000007],[-123.41665599999999,48.423882000000106],[-123.42138699999992,48.427490000000034],[-123.425003,48.431938],[-123.45973200000003,48.41193400000003],[-123.51334400000002,48.37470999999999],[-123.53694200000001,48.33832600000011],[-123.54250300000001,48.31249200000008],[-123.546112,48.307770000000005],[-123.55166600000001,48.304710000000114],[-123.55915800000002,48.30304700000005],[-123.58332799999994,48.301102000000014],[-123.598343,48.31166100000007],[-123.71444699999995,48.34804500000013],[-123.76251199999996,48.36166400000002],[-123.77166699999998,48.36166400000002],[-123.77999899999998,48.360550000000046],[-123.79499799999996,48.357498000000135],[-123.80888400000003,48.353324999999984],[-123.817497,48.352493000000095],[-123.823624,48.35277600000006],[-123.91610699999995,48.36415900000003],[-123.92415599999998,48.366104000000064],[-123.97609699999998,48.381935],[-124.26363399999997,48.46888000000001],[-124.423607,48.51693700000004],[-124.609444,48.56054700000004],[-124.6885989999999,48.57833099999999],[-124.72083999999995,48.58665500000001],[-124.75917099999998,48.6055530000001],[-124.77111799999994,48.61166399999996],[-124.79499800000002,48.629989999999964],[-124.81777999999997,48.64888000000013],[-124.82277699999997,48.65248900000012],[-124.9225009999999,48.67999300000014],[-125.02887699999997,48.70888500000001],[-125.0625,48.7149960000001],[-125.09500100000002,48.721930999999984],[-125.10221899999993,48.72443399999992],[-125.11389199999996,48.73110200000008],[-125.18443299999996,48.79610400000013],[-125.18499800000001,48.80082700000008],[-125.01722699999999,48.92054700000011],[-124.90862300000003,48.969154],[-124.90306099999998,48.97137500000008],[-124.84750399999996,49.011664999999994],[-124.84277299999985,49.01554900000002],[-124.83556399999998,49.02416199999999],[-124.78083800000002,49.131377999999984],[-124.77944899999994,49.144439999999975],[-124.78083800000002,49.150542999999914],[-124.79695099999998,49.2158280000001],[-124.79972799999996,49.22693600000008],[-124.80499299999997,49.236938000000066],[-124.80776999999995,49.24054700000005],[-124.81555199999997,49.238045],[-124.818893,49.23471800000004],[-124.82444800000002,49.224158999999986],[-124.82501199999996,49.21720900000014],[-124.82333399999993,49.20555100000013],[-124.81723,49.18332700000002],[-124.81610099999995,49.16471100000001],[-124.81806899999998,49.146103000000096],[-124.82611099999997,49.12248999999997],[-124.83139,49.11249500000008],[-124.87832599999996,49.02526899999992],[-124.88194299999998,49.02054600000014],[-124.89472999999998,49.00888800000013],[-124.90055799999993,49.00499700000006],[-124.906113,49.00193800000005],[-124.93694299999999,48.98804500000006],[-124.94999699999994,48.983330000000024],[-124.96278399999994,48.98110200000002],[-125.06916799999999,48.98443600000002],[-125.126938,48.99110400000001],[-125.19888300000002,48.96276899999998],[-125.21000699999996,48.955826],[-125.21665999999988,48.95332300000001],[-125.22416699999991,48.95166000000012],[-125.23137699999995,48.951103000000046],[-125.24194299999988,48.95166000000012],[-125.318893,48.96443899999997],[-125.32721699999996,48.966102999999976],[-125.45722999999992,48.918052999999986],[-125.46472199999988,48.91638200000011],[-125.483612,48.91582500000004],[-125.502228,48.91777000000002],[-125.50723299999999,48.92027300000001],[-125.75110599999994,49.05526700000007],[-125.76806599999998,49.09860200000003],[-125.73805199999998,49.105552999999986],[-125.69304699999992,49.12860100000006],[-125.64167800000001,49.16304800000006],[-125.63722200000001,49.16693900000013],[-125.60888699999998,49.19804399999998],[-125.60582699999992,49.210274000000084],[-125.60749800000002,49.2158280000001],[-125.611107,49.22026799999992],[-125.61638599999998,49.21971100000002],[-125.66443599999991,49.18998700000003],[-125.72083999999995,49.157767999999976],[-125.74694799999997,49.148604999999975],[-125.75334199999998,49.147491],[-125.75611899999996,49.151657000000114],[-125.779449,49.24166100000002],[-125.79666099999992,49.310272000000055],[-125.86609599999991,49.27443699999998],[-125.952789,49.230270000000075],[-125.96501199999989,49.22526599999992],[-125.97028399999999,49.22470900000002],[-125.97444199999995,49.2249910000001],[-125.98137700000001,49.227211000000125],[-125.98750299999989,49.230270000000075],[-126.020554,49.263054000000125],[-126.02333099999993,49.26805100000007],[-126.02223200000003,49.280823000000055],[-126.01862299999993,49.28555300000011],[-126.01306199999999,49.2888870000001],[-126.00666799999993,49.290549999999996],[-125.98029300000002,49.292496000000085],[-125.97361799999999,49.294997999999964],[-125.96916199999998,49.29749300000003],[-125.950287,49.311935000000005],[-125.94554099999999,49.31666600000011],[-125.89750699999996,49.41027100000008],[-125.89584399999995,49.416382],[-125.89695699999993,49.42804700000005],[-125.89972699999998,49.43360100000007],[-125.90471599999995,49.435822000000144],[-125.90915699999988,49.431938000000116],[-125.94722000000002,49.39554600000014],[-125.96250900000001,49.37748700000003],[-125.96501199999989,49.373604000000114],[-125.96528599999999,49.367493000000024],[-125.962219,49.3555530000001],[-125.962784,49.35027300000007],[-125.96610999999996,49.34554300000002],[-125.99527,49.324440000000095],[-126.00195300000001,49.321938000000046],[-126.0094529999999,49.321663],[-126.03916900000002,49.33027599999997],[-126.04638699999987,49.33332800000011],[-126.06111099999998,49.344154],[-126.06500199999999,49.34832800000004],[-126.07556199999999,49.38638300000014],[-126.07389799999999,49.392494000000056],[-126.120003,49.42304999999999],[-126.22556299999991,49.41027100000008],[-126.26390099999998,49.38943500000005],[-126.36527999999998,49.40165700000006],[-126.45916699999998,49.401932000000045],[-126.46167000000003,49.382767000000115],[-126.46611000000001,49.38027200000005],[-126.52667200000002,49.37193300000001],[-126.54222099999993,49.37443500000012],[-126.54723399999995,49.3780440000001],[-126.57778899999988,49.40776799999992],[-126.579453,49.41332200000011],[-126.57917799999996,49.41944099999995],[-126.56973299999999,49.57638500000007],[-126.56610099999995,49.584434999999985],[-126.47028399999999,49.63555100000002],[-126.46167000000003,49.636658000000125],[-126.40416699999997,49.6377720000001],[-126.38417099999992,49.63638300000008],[-126.36749299999997,49.633049000000085],[-126.36028299999998,49.63082099999997],[-126.34137699999997,49.62887599999999],[-126.28472899999997,49.6344380000001],[-126.22389199999998,49.64054900000002],[-126.13417099999998,49.64999400000005],[-126.09445199999988,49.65554800000007],[-126.08693699999998,49.65721100000002],[-126.08750899999995,49.66220900000002],[-126.09028599999999,49.66638200000011],[-126.09416199999993,49.671104000000014],[-126.10305799999998,49.67916100000002],[-126.11028299999992,49.68138099999999],[-126.11972000000003,49.681107000000054],[-126.20944199999991,49.67388199999999],[-126.23444399999994,49.669159000000036],[-126.24638400000003,49.66471100000007],[-126.283073,49.654990999999995],[-126.29833999999994,49.65221400000007],[-126.340843,49.64860500000009],[-126.43110699999994,49.662491000000045],[-126.43831599999993,49.664153999999996],[-126.58500699999996,49.701103000000046],[-126.59028599999994,49.70443700000004],[-126.63027999999997,49.79499800000008],[-126.67971799999998,49.878876000000105],[-126.80444299999988,49.90915699999999],[-126.83917200000002,49.88472000000013],[-126.84555099999989,49.8822100000001],[-126.85221899999993,49.87971500000009],[-126.87609899999995,49.87332200000009],[-126.93943799999994,49.862770000000125],[-126.99416399999996,49.85527000000002],[-127.12111699999997,49.85228699999999],[-127.13249200000001,49.85694100000012],[-127.17749000000003,49.88888500000013],[-127.18554699999999,49.89749100000006],[-127.22444199999995,49.940269000000114],[-127.241379,49.961937000000034],[-127.23889199999996,49.96720899999997],[-127.234444,49.97137500000008],[-127.17999299999991,50.02137800000003],[-127.18277,50.03166200000004],[-127.18360899999999,50.051102000000014],[-127.17666599999995,50.061104],[-127.172234,50.06499500000007],[-127.13027999999997,50.084717000000126],[-127.15833999999995,50.096382000000006],[-127.27055399999995,50.0991590000001],[-127.27500899999995,50.05999000000003],[-127.27749599999993,50.055267000000015],[-127.28388999999999,50.052216000000044],[-127.33000199999998,50.03388200000006],[-127.34500100000002,50.03027300000008],[-127.38054699999998,50.0261000000001],[-127.38999899999993,50.02860300000009],[-127.42331699999994,50.0422210000001],[-127.45195000000001,50.06971699999997],[-127.46916199999993,50.08804299999997],[-127.47193900000002,50.09276599999998],[-127.54804999999993,50.130272000000105],[-127.63276699999994,50.12999000000002],[-127.78028899999993,50.084160000000054],[-127.781387,50.084160000000054],[-127.78362299999998,50.084160000000054],[-127.890556,50.10694100000006],[-127.89584400000001,50.108886999999925],[-127.90083299999998,50.112495000000024],[-127.90695199999999,50.12082700000002],[-127.90666199999998,50.127769000000114],[-127.903343,50.13249200000013],[-127.89222699999988,50.13916000000006],[-127.87917299999998,50.144440000000145],[-127.86805700000002,50.151099999999985],[-127.83721899999995,50.17249300000009],[-127.82833900000003,50.180550000000096],[-127.78888699999999,50.22221400000001],[-127.79915599999993,50.317772000000105],[-127.80444299999994,50.32138099999992],[-127.86389200000002,50.33693700000009],[-127.87138399999998,50.33776899999998],[-127.881104,50.33721200000008],[-127.895554,50.32638500000007],[-127.90778399999999,50.31971700000008],[-127.92166099999997,50.316666000000055],[-127.93138099999993,50.31610100000006],[-127.94833399999993,50.32193799999999],[-127.95249899999993,50.32471500000008],[-127.97860700000001,50.34249100000005],[-127.97944599999994,50.347214000000065],[-127.92610199999996,50.45999100000006],[-127.92388900000003,50.46276900000004],[-127.91722099999993,50.46415699999994],[-127.75666799999993,50.48638199999999],[-127.708054,50.491661000000136],[-127.70028699999995,50.49221800000004],[-127.58416699999998,50.48693800000001],[-127.576683,50.48471799999999],[-127.57140400000003,50.481934000000024],[-127.56331599999999,50.4741590000001],[-127.53278399999999,50.439986999999974],[-127.50750700000003,50.40915700000011],[-127.49527,50.395827999999995],[-127.47444200000001,50.381660000000124],[-127.46193699999998,50.37582400000008],[-127.454453,50.37360400000006],[-127.44695300000001,50.37276500000013],[-127.446663,50.379714999999976],[-127.45249899999988,50.388885000000016],[-127.48665599999993,50.437492000000134],[-127.50583599999999,50.45860299999998],[-127.52027899999996,50.46971100000013],[-127.53083800000002,50.47693600000002],[-127.54750100000001,50.48693800000001],[-127.56388899999996,50.50222000000002],[-127.57000699999998,50.51221499999991],[-127.56749699999995,50.51610599999998],[-127.55027799999999,50.53832999999992],[-127.54472399999997,50.54166400000008],[-127.50361599999997,50.56221000000011],[-127.49694799999992,50.56526900000006],[-127.49027999999993,50.56805400000013],[-127.47501399999999,50.571663000000115],[-127.443604,50.571663000000115],[-127.41972399999992,50.57388300000014],[-127.41416900000002,50.575829000000056],[-127.41166699999997,50.58138300000002],[-127.41139199999992,50.587494000000106],[-127.41944899999999,50.59665700000011],[-127.58168,50.59388000000001],[-127.69138299999997,50.60665900000009],[-127.87332200000003,50.623877999999934],[-127.87666299999995,50.62165800000014],[-127.87361099999993,50.61693600000007],[-127.854446,50.60833000000014],[-127.80055199999998,50.587494000000106],[-127.78666699999997,50.58221400000002],[-127.76834099999996,50.579994000000056],[-127.751106,50.58110800000003],[-127.72501399999993,50.58443499999993],[-127.708618,50.584991000000116],[-127.66251399999999,50.58138300000002],[-127.63445300000001,50.57804900000002],[-127.61028299999998,50.56582599999996],[-127.595551,50.55582400000003],[-127.59166699999997,50.55165900000003],[-127.589722,50.54610400000013],[-127.595551,50.53665900000004],[-127.60109699999998,50.53333300000003],[-127.60888699999987,50.53138000000007],[-128.05142199999995,50.44669300000004],[-128.13363599999997,50.47470900000013],[-128.224152,50.53110500000008],[-128.319458,50.60860400000007],[-128.37527499999993,50.678604000000064],[-128.406952,50.738883999999985],[-128.41473399999995,50.762771999999984],[-128.416656,50.76915699999995],[-128.41305499999993,50.77388000000013],[-128.40863000000002,50.77777100000003],[-128.35583499999996,50.799721000000034],[-128.349152,50.80165899999997],[-128.10693400000002,50.8605500000001],[-128.05307,50.87193300000007],[-127.91832699999998,50.87221499999998],[-127.90972899999991,50.871376],[-127.882767,50.86554699999999],[-127.833328,50.85416399999997],[-127.67749000000003,50.817497],[-127.51471700000002,50.774437000000034],[-127.50723299999993,50.77221700000001],[-127.49582699999996,50.765831000000105],[-127.48750299999995,50.75721700000008],[-127.45916699999992,50.718323],[-127.354446,50.676102000000014],[-127.22693599999991,50.636108000000036]],[[-127.65471599999995,50.837769000000094],[-127.66139199999998,50.83499100000006],[-127.67027300000001,50.835266000000104],[-127.75306699999999,50.85277600000006],[-127.833328,50.87971500000003],[-127.83860799999997,50.88166000000007],[-127.83306899999997,50.88499500000012],[-127.73500100000001,50.909988],[-127.72638699999993,50.90860000000009],[-127.71665999999999,50.90554800000001],[-127.71028099999995,50.9019320000001],[-127.69138299999997,50.88721499999997],[-127.67083699999995,50.86693600000001],[-127.65833999999995,50.85416399999997],[-127.65527299999997,50.849433999999974],[-127.65334299999995,50.84388000000013],[-127.65471599999995,50.837769000000094]],[[-55.55555700000002,50.88638300000002],[-55.56388899999996,50.88499500000012],[-55.571670999999924,50.88582600000012],[-55.58111600000001,50.888046000000145],[-55.604720999999984,50.898048000000074],[-55.61555499999997,50.9060970000001],[-55.61972000000003,50.91027100000014],[-55.63611599999996,50.950829000000056],[-55.63527699999992,50.96138000000013],[-55.62943999999993,50.96554600000002],[-55.565552000000025,50.983047],[-55.558334,50.98443600000002],[-55.550551999999925,50.985268000000076],[-55.54222900000002,50.98499300000009],[-55.53527799999995,50.98137700000001],[-55.531386999999995,50.977211000000125],[-55.52972399999999,50.96832300000011],[-55.549995000000024,50.89083099999999],[-55.55555700000002,50.88638300000002]],[[-55.993889000000024,51.2002720000001],[-55.99999999999994,51.196655000000135],[-56.00111400000003,51.201660000000004],[-55.99805500000002,51.20749699999999],[-55.992774999999995,51.212769000000094],[-55.981383999999935,51.22165700000005],[-55.975554999999986,51.22582200000005],[-55.967772999999966,51.226653999999996],[-55.96832999999987,51.22137500000002],[-55.97055099999994,51.218323000000055],[-55.98249800000002,51.208885000000066],[-55.993889000000024,51.2002720000001]],[[-58.41332999999992,51.2388840000001],[-58.462219000000005,51.21610300000009],[-58.56361399999997,51.22832500000004],[-58.56500199999999,51.23333000000008],[-58.56194299999993,51.239159000000086],[-58.55583199999995,51.242767000000015],[-58.513335999999924,51.2649990000001],[-58.506392999999946,51.26832600000006],[-58.419448999999986,51.274712000000136],[-58.412773000000016,51.26721200000003],[-58.40916399999992,51.256943000000035],[-58.41332999999992,51.2388840000001]],[[-53.756366999999955,48.50326200000012],[-53.99749800000001,48.42555200000004],[-54.011116000000015,48.42166099999997],[-54.025001999999915,48.41860200000002],[-54.04888900000003,48.420547],[-54.05722000000003,48.42193600000002],[-54.07277699999992,48.42860400000001],[-54.08111599999995,48.42999299999997],[-54.09444399999995,48.42582700000008],[-54.10055499999993,48.42249300000009],[-54.147223999999994,48.39138000000008],[-54.13805400000001,48.35916100000003],[-54.134727,48.35443899999996],[-54.12749500000001,48.353324999999984],[-54.118607,48.364998000000014],[-54.088607999999965,48.39554599999997],[-54.075561999999934,48.4019320000001],[-54.06944999999996,48.40387700000008],[-54.054442999999935,48.40416000000005],[-54.04555499999998,48.4019320000001],[-54.02916700000003,48.399437000000034],[-54.02111100000002,48.39916200000005],[-53.998885999999914,48.40082600000005],[-53.99222599999996,48.402489],[-53.97972099999987,48.408042999999964],[-53.91305499999993,48.444153000000085],[-53.756366999999955,48.50326200000012],[-53.67444599999993,48.53416400000009],[-53.647223999999994,48.54110700000007],[-53.63194299999998,48.541382000000056],[-53.623054999999965,48.53916200000009],[-53.586388,48.52526900000004],[-53.57472200000001,48.50721699999997],[-53.558051999999975,48.47470900000002],[-53.58805100000001,48.428047000000106],[-53.56221799999997,48.43915599999997],[-53.533889999999985,48.45193500000005],[-53.48860899999994,48.50721699999997],[-53.461945000000014,48.55526699999996],[-53.46527900000001,48.56860399999999],[-53.46583599999997,48.57416500000005],[-53.465003999999965,48.579436999999984],[-53.43721799999997,48.619987000000094],[-53.42444599999999,48.625549000000035],[-53.345832999999914,48.61582899999996],[-53.33805099999995,48.61249499999997],[-53.31305699999996,48.595267999999976],[-53.30583200000001,48.58665500000001],[-53.30332900000002,48.581940000000145],[-53.22638699999993,48.555549999999926],[-53.216392999999925,48.56693999999999],[-53.153884999999946,48.628601],[-53.07972699999999,48.6988750000001],[-53.07277699999992,48.70027200000004],[-53.067779999999914,48.696380999999974],[-53.02305599999994,48.66082],[-53.01888999999994,48.65638000000001],[-52.978049999999996,48.60443900000013],[-52.97638699999999,48.59915900000004],[-52.976944,48.59388000000007],[-52.98722099999998,48.548050000000046],[-53.05388599999998,48.44276400000007],[-53.07556199999999,48.42249300000009],[-53.09749599999998,48.4052660000001],[-53.1875,48.35082999999997],[-53.194159999999954,48.34860200000003],[-53.201941999999974,48.347488000000055],[-53.20972399999994,48.34777100000002],[-53.21805599999993,48.3491590000001],[-53.24888599999997,48.36277000000007],[-53.261391,48.37082700000002],[-53.266395999999986,48.37499200000002],[-53.345001000000025,48.36027500000006],[-53.38889299999988,48.30387900000011],[-53.615279999999984,48.178046999999935],[-53.62138399999992,48.174713],[-53.634170999999924,48.169991000000095],[-53.662216,48.163321999999994],[-53.668609999999944,48.16249099999999],[-53.67694899999998,48.163879000000065],[-53.69471699999991,48.16915899999998],[-53.71055599999994,48.17582700000014],[-53.89250199999998,48.22693600000014],[-53.901389999999935,48.2291560000001],[-53.93416599999995,48.23333000000014],[-53.94055199999997,48.23081999999994],[-53.94527399999998,48.17887900000005],[-53.9441599999999,48.163879000000065],[-53.917778,48.08804300000003],[-53.91249800000003,48.084160000000054],[-53.90416700000003,48.08194000000009],[-53.823616000000015,48.07443999999998],[-53.79333500000001,48.07360800000009],[-53.77027899999996,48.07332600000001],[-53.733611999999994,48.0761030000001],[-53.71860499999997,48.07804900000002],[-53.69694499999997,48.079162999999994],[-53.68916300000001,48.07888000000003],[-53.69288599999987,48.067993],[-53.68838900000003,48.06599],[-53.68521900000002,48.06366000000014],[-53.68388700000003,48.060822000000144],[-53.68422299999992,48.057822999999985],[-53.68788899999993,48.05482500000011],[-53.691055000000006,48.052658000000065],[-53.69888300000002,48.049328],[-53.73694599999999,48.032767999999976],[-53.76333599999998,48.02638200000001],[-53.79944599999999,48.02165999999994],[-53.83666199999993,48.02221700000001],[-53.85222599999997,48.023048000000074],[-53.87638900000002,48.02582600000005],[-53.89388999999994,48.02999100000005],[-53.90166499999998,48.033607000000075],[-53.90943899999996,48.03388200000012],[-53.91666399999991,48.03333299999997],[-53.923614999999984,48.0316620000001],[-53.924170999999944,48.02665700000006],[-53.919167000000016,48.022490999999945],[-53.91138499999994,48.01915700000001],[-53.89305899999994,48.014442000000145],[-53.794448999999986,47.99638400000009],[-53.77916699999997,47.996658000000025],[-53.69538899999992,48.01821899999999],[-53.69138700000002,48.019215000000145],[-53.668724,48.02988099999999],[-53.65021899999999,48.03788400000013],[-53.60777999999999,48.05110200000007],[-53.60583500000001,48.04638700000004],[-53.61916400000001,47.99887800000005],[-53.62249800000001,47.993050000000096],[-53.72361000000001,47.84388000000001],[-53.73777799999999,47.82666000000006],[-53.78750600000001,47.773048000000074],[-53.79333500000001,47.768599999999935],[-53.801391999999964,47.76998900000012],[-53.807503,47.773604999999975],[-53.82556199999999,47.79499800000008],[-53.85250099999996,47.78527100000014],[-53.850554999999986,47.760551000000135],[-53.837501999999915,47.69943200000006],[-53.760283999999956,47.609993000000145],[-53.631110999999976,47.54332700000009],[-53.55055199999998,47.52915999999993],[-53.54527999999999,47.534439000000134],[-53.542502999999954,47.55027000000007],[-53.54111499999999,47.58526600000005],[-53.49777999999998,47.73471799999999],[-53.495834,47.74027300000006],[-53.46111300000001,47.806655999999975],[-53.43499800000001,47.83776899999998],[-53.30610699999994,47.98416100000003],[-53.29084,47.99943500000012],[-53.274445000000014,48.013329000000056],[-53.17055499999998,48.05360399999995],[-53.11000100000001,48.03943600000008],[-53.101943999999946,48.038048],[-53.095001000000025,48.03943600000008],[-53.05332900000002,48.049721000000034],[-53.041945999999996,48.05582400000014],[-52.996947999999975,48.08638000000008],[-52.974716,48.11638599999998],[-52.959723999999994,48.143051000000014],[-52.95639,48.14860500000003],[-52.92694899999998,48.169991000000095],[-52.91999800000002,48.171379],[-52.902221999999995,48.16304800000006],[-52.88611599999996,48.15110000000004],[-52.88194299999992,48.14749100000006],[-52.83555599999994,48.10638399999999],[-52.83138999999994,48.10166199999992],[-52.832779000000016,48.096939000000134],[-52.838889999999935,48.09360500000014],[-52.87194099999999,48.08221400000002],[-52.880279999999914,48.083327999999995],[-52.898056,48.09054600000002],[-52.90416700000003,48.08971400000007],[-52.911384999999996,48.08804300000003],[-52.91750300000001,48.084716999999955],[-52.928337,48.075553999999954],[-53.058051999999975,47.92249300000003],[-53.05999799999995,47.91693900000001],[-53.05944099999999,47.886658000000125],[-53.07583599999998,47.85083000000009],[-53.15860700000002,47.68305200000009],[-53.178337,47.65138200000001],[-53.18360899999993,47.64638500000012],[-53.201667999999984,47.63638300000014],[-53.22110699999996,47.628601],[-53.24083699999994,47.622489999999914],[-53.259727,47.61582900000002],[-53.26500699999997,47.61166400000002],[-53.26722000000001,47.60610200000008],[-53.26167299999997,47.54638699999998],[-53.17556000000002,47.4313810000001],[-53.128333999999995,47.41110200000014],[-53.12194099999999,47.413321999999994],[-53.11194599999999,47.42360700000012],[-53.08306099999999,47.458327999999995],[-53.06583399999994,47.46998600000006],[-53.013061999999934,47.501389000000074],[-52.995003,47.51138300000008],[-52.95166799999993,47.530823000000055],[-52.919167000000016,47.54166399999997],[-52.907219,47.54833200000013],[-52.89694999999995,47.55860100000001],[-52.84916700000002,47.621101000000124],[-52.84249899999992,47.632767000000115],[-52.84055299999994,47.638329000000056],[-52.837501999999915,47.65415999999999],[-52.838889999999935,47.66387900000001],[-52.841110000000015,47.66860200000002],[-52.84166700000003,47.67332499999998],[-52.84055299999994,47.683876000000055],[-52.79888900000003,47.78416400000003],[-52.79138899999998,47.795547000000056],[-52.78556100000003,47.79972100000009],[-52.77944200000002,47.803047000000106],[-52.770554000000004,47.79972100000009],[-52.704169999999976,47.75388299999997],[-52.70055400000001,47.749435000000005],[-52.65777600000001,47.657493999999986],[-52.61444899999998,47.51666299999994],[-52.62027699999999,47.5002750000001],[-52.625832,47.48915899999997],[-52.65332799999999,47.43776700000001],[-52.71805599999993,47.364998000000014],[-52.78750600000001,47.30804399999994],[-52.818610999999976,47.22415900000004],[-52.84972399999998,47.1616590000001],[-52.84527600000001,47.14249399999994],[-52.843613000000005,47.06388099999998],[-52.84416199999998,47.05860100000007],[-52.85278299999999,47.022491],[-52.88417099999998,46.9741590000001],[-52.90999599999998,46.911658999999986],[-52.92972599999996,46.85166200000003],[-52.93277699999999,46.82555400000007],[-52.93499800000001,46.804993000000024],[-52.938332,46.78916200000009],[-53.090836000000024,46.643326],[-53.10250100000002,46.63665800000001],[-53.16111000000001,46.61998699999998],[-53.16916699999996,46.61971300000005],[-53.192497,46.62332200000003],[-53.20722199999989,46.630272000000105],[-53.21333299999998,46.63388100000009],[-53.315552000000025,46.694709999999986],[-53.35417199999995,46.73693800000001],[-53.36194599999993,46.73749500000008],[-53.38417099999998,46.72137500000002],[-53.410552999999936,46.700829],[-53.426391999999964,46.68721000000011],[-53.451392999999996,46.66137700000013],[-53.46361499999995,46.65416000000005],[-53.52111100000002,46.62082700000002],[-53.53277600000001,46.61415900000003],[-53.56166799999994,46.61277000000007],[-53.56944999999996,46.61415900000003],[-53.577225,46.617493000000024],[-53.60777999999999,46.63610799999998],[-53.613891999999964,46.64027400000003],[-53.617774999999995,46.64415700000001],[-53.63500199999993,46.68082399999997],[-53.643058999999994,46.7044370000001],[-53.64416499999993,46.70916000000011],[-53.648056,46.79666100000003],[-53.64778100000001,46.80193299999996],[-53.645279000000016,46.81249200000002],[-53.639725,46.82916300000005],[-53.636391,46.83471700000007],[-53.594719,46.9447100000001],[-53.64166999999992,46.983879],[-53.63361400000002,47.00110599999999],[-53.57778199999996,47.08526599999993],[-53.55083499999995,47.106659000000036],[-53.539444,47.11415899999997],[-53.591385,47.15609699999999],[-53.64639299999999,47.105270000000075],[-53.70361299999996,47.053047000000106],[-53.823059,46.956657000000064],[-53.89416499999999,46.899994000000106],[-53.94583099999994,46.85888700000004],[-54.05332899999996,46.794998000000135],[-54.097220999999934,46.79943800000012],[-54.17888599999992,46.81610100000006],[-54.18777499999999,46.81916000000001],[-54.18999500000001,46.82360799999998],[-54.190833999999995,46.82860599999998],[-54.196387999999956,46.86249499999997],[-54.196663,46.883331],[-54.193329000000006,46.89360799999997],[-54.16082799999998,46.981934000000024],[-54.13194299999998,47.012496999999996],[-54.11500499999994,47.039719000000105],[-54.092498999999975,47.0794370000001],[-54.066666,47.13110400000011],[-53.993889000000024,47.26527400000003],[-53.964721999999995,47.299721000000034],[-53.92861199999999,47.302773000000116],[-53.921943999999996,47.30416100000002],[-53.879997,47.34804500000013],[-53.875557000000015,47.35416399999997],[-53.86750000000001,47.40277100000009],[-53.87943999999993,47.43082400000003],[-53.90027599999996,47.48610700000006],[-53.891669999999976,47.524711999999965],[-53.885558999999944,47.576941999999974],[-53.894721999999945,47.6055530000001],[-53.896950000000004,47.609993000000145],[-53.983886999999925,47.75777400000004],[-54.003333999999995,47.778877000000136],[-54.033332999999914,47.79666100000003],[-54.19527399999998,47.85749800000002],[-54.19499999999999,47.843048000000124],[-54.1972199999999,47.83221400000008],[-54.21277600000002,47.77777100000009],[-54.219161999999926,47.766106000000036],[-54.22388499999994,47.75999500000012],[-54.25917099999998,47.71527100000014],[-54.33777600000002,47.621658000000025],[-54.435272,47.505554000000075],[-54.468605000000025,47.441658000000075],[-54.47749299999998,47.40499100000005],[-54.47249599999998,47.401099999999985],[-54.47749299999998,47.39582800000005],[-54.48277299999995,47.39166300000005],[-54.511116000000015,47.372765000000015],[-54.51721999999995,47.36943800000006],[-54.60139499999997,47.34526800000003],[-54.611388999999974,47.353049999999996],[-54.61306000000002,47.35833000000008],[-54.61333499999995,47.36277000000007],[-54.606948999999986,47.37443499999995],[-54.601944,47.37971500000003],[-54.59666399999986,47.38388099999992],[-54.55999800000001,47.413879000000065],[-54.52916699999997,47.442214999999976],[-54.489998000000014,47.48638200000005],[-54.417220999999984,47.583603000000096],[-54.41082799999987,47.59499400000004],[-54.41332999999992,47.599715999999944],[-54.418334999999956,47.60360700000001],[-54.43055700000002,47.59777100000014],[-54.44083399999994,47.58693700000009],[-54.50861400000002,47.513329],[-54.53194400000001,47.47998799999999],[-54.539444,47.468048000000124],[-54.56361399999997,47.43998700000003],[-54.57888799999989,47.423882000000106],[-54.604720999999984,47.4019320000001],[-54.62138399999998,47.38999200000001],[-54.70027900000002,47.35777300000001],[-54.71999399999993,47.35221899999999],[-54.72721899999999,47.351387000000045],[-54.81861099999986,47.363609000000054],[-54.81945000000002,47.368599000000074],[-54.80305499999997,47.38054699999998],[-54.79361699999998,47.391936999999984],[-54.78666700000002,47.413879000000065],[-54.78750600000001,47.418884000000105],[-54.796111999999994,47.420830000000024],[-54.85639200000003,47.39054900000008],[-54.98055299999993,47.285552999999936],[-55.039169000000015,47.225821999999994],[-55.04389200000003,47.22082500000005],[-55.04555499999998,47.21527100000009],[-55.04333500000001,47.210548000000074],[-55.05361199999993,47.15082600000011],[-55.065833999999995,47.09332300000011],[-55.06945000000002,47.08221400000002],[-55.100280999999995,47.05471],[-55.14944499999996,47.01221500000008],[-55.15471600000001,47.00804900000003],[-55.193329000000006,46.984993000000145],[-55.22582999999997,46.934433000000126],[-55.23027799999994,46.928329000000076],[-55.23694599999993,46.923607000000004],[-55.246947999999975,46.91693900000001],[-55.258613999999966,46.91027100000008],[-55.358337000000006,46.87416100000013],[-55.384170999999924,46.86582900000013],[-55.399993999999936,46.86582900000013],[-55.45666499999999,46.87471000000011],[-55.463615000000004,46.877486999999974],[-55.46860499999997,46.881660000000124],[-55.47193899999996,46.88638300000014],[-55.62694499999992,46.8688810000001],[-55.63417099999998,46.86666100000008],[-55.689719999999966,46.85832999999997],[-55.80332899999996,46.86054999999999],[-55.84583299999997,46.86971299999999],[-55.91500099999996,46.88749700000011],[-55.92361499999993,46.889717000000076],[-55.931389000000024,46.892769000000044],[-55.946663,46.89943699999998],[-55.966110000000015,46.90998800000011],[-55.98082699999992,46.932213000000104],[-55.98277300000001,46.93665299999998],[-55.98416899999995,46.94165800000002],[-55.98305499999998,46.95249200000006],[-55.980552999999986,46.95777100000004],[-55.96665999999999,46.98137700000012],[-55.95249899999999,46.99638399999992],[-55.88694800000002,47.05609900000002],[-55.87110899999999,47.069160000000124],[-55.86555499999997,47.07276899999994],[-55.77527600000002,47.10193600000008],[-55.76860799999997,47.10332500000004],[-55.74555199999992,47.10443900000007],[-55.73889200000002,47.10443900000007],[-55.72360999999995,47.104164000000026],[-55.715553,47.10305000000005],[-55.698050999999964,47.09804500000001],[-55.68250299999994,47.09137700000002],[-55.67444599999999,47.09027099999997],[-55.586945000000014,47.110275000000115],[-55.573616000000015,47.11360900000011],[-55.493331999999896,47.133880999999974],[-55.48777799999999,47.13721499999997],[-55.32944500000002,47.242493000000024],[-55.29833999999994,47.26721199999997],[-55.290557999999976,47.2783280000001],[-55.285278000000005,47.29499800000002],[-55.28583500000002,47.31027200000011],[-55.28694899999999,47.31499500000007],[-55.28611799999999,47.325554000000125],[-55.269721999999945,47.39083099999999],[-55.266662999999994,47.39666],[-55.262221999999895,47.40277100000009],[-55.25694999999996,47.407211000000075],[-55.202225,47.44609800000012],[-55.179169,47.46054800000002],[-55.17250100000001,47.46388200000001],[-55.10777999999999,47.48360400000007],[-55.100554999999986,47.48416099999997],[-55.08361100000002,47.481101999999964],[-55.07583599999987,47.48082000000011],[-55.04028299999993,47.48499300000003],[-54.95139299999988,47.504997],[-54.86805700000002,47.54388399999999],[-54.84583299999997,47.55693800000006],[-54.84166699999997,47.56332400000014],[-54.841385,47.583603000000096],[-54.845551,47.63388100000009],[-54.949439999999925,47.599715999999944],[-54.95639,47.59804500000007],[-54.97083299999997,47.59665699999999],[-55.019278999999926,47.621101000000124],[-55.02827799999989,47.62076600000012],[-55.033278999999936,47.62160100000011],[-55.036109999999894,47.623936000000015],[-55.03761299999991,47.62660199999999],[-55.03744099999989,47.62977200000006],[-55.03561000000002,47.63326999999998],[-55.02961299999993,47.639598999999976],[-55.013779,47.65310299999993],[-55.00777800000003,47.65943500000003],[-54.95639,47.74137900000011],[-54.94749499999995,47.75360900000004],[-54.93804899999998,47.771103000000096],[-54.936110999999926,47.78166199999998],[-54.94305400000002,47.78110500000008],[-54.94860799999992,47.776657000000114],[-55.011391,47.721374999999966],[-55.021942000000024,47.71166199999993],[-55.02527600000002,47.70526899999999],[-55.027221999999995,47.69526700000006],[-55.03055599999999,47.68415800000014],[-55.03361499999994,47.67832900000013],[-55.119114000000025,47.61693600000012],[-55.122443999999916,47.61426900000009],[-55.12628199999995,47.612774],[-55.130774999999915,47.61193800000012],[-55.13577700000002,47.61360500000001],[-55.262778999999966,47.650543000000084],[-55.34916700000002,47.7044370000001],[-55.34833500000002,47.71027400000003],[-55.357506,47.726097000000095],[-55.365005,47.72637900000012],[-55.379722999999956,47.724991000000045],[-55.42749799999996,47.71166199999993],[-55.432503,47.70638299999996],[-55.46194499999996,47.64610300000004],[-55.46472199999994,47.64027400000003],[-55.467498999999975,47.61915599999992],[-55.46665999999999,47.61415900000003],[-55.46138799999994,47.610275],[-55.454444999999964,47.61110700000012],[-55.446663,47.623046999999985],[-55.436110999999926,47.631659999999954],[-55.43000000000001,47.634163000000115],[-55.42305799999997,47.635826000000066],[-55.415276000000006,47.63249200000007],[-55.40777600000001,47.624161000000015],[-55.40027600000002,47.615547000000106],[-55.39833799999997,47.610275],[-55.389725,47.58638000000002],[-55.40027600000002,47.514717000000076],[-55.406661999999926,47.49305000000004],[-55.40972099999999,47.487213000000054],[-55.41416199999992,47.481101999999964],[-55.42972600000002,47.46720900000014],[-55.43638599999997,47.46554600000002],[-55.49861099999998,47.45388000000003],[-55.50583599999993,47.453322999999955],[-55.52610800000002,47.45443699999993],[-55.55527499999994,47.44026900000006],[-55.56055500000002,47.43610400000006],[-55.56500199999999,47.429993000000024],[-55.58777600000002,47.398604999999975],[-55.625,47.46360800000008],[-55.65416700000003,47.49527000000006],[-55.79527999999999,47.49276700000007],[-55.914443999999946,47.43776700000001],[-55.920279999999934,47.43526500000013],[-55.92556000000002,47.439156000000025],[-55.92388900000003,47.444709999999986],[-55.91972399999986,47.450829000000056],[-55.83167300000002,47.517212000000086],[-55.788895000000025,47.551102000000014],[-55.745834,47.58526600000005],[-55.77305599999994,47.57972000000001],[-55.82417299999997,47.56638299999997],[-55.89222699999999,47.5366590000001],[-55.98777799999999,47.500549000000035],[-56.104172000000005,47.46360800000008],[-56.110557999999855,47.462494000000106],[-56.11860699999994,47.46360800000008],[-56.15888999999993,47.48471800000004],[-56.169167000000016,47.49249300000014],[-56.1725009999999,47.49721500000004],[-56.1725009999999,47.50166300000001],[-56.16805999999997,47.50721699999997],[-56.16249800000003,47.51138300000008],[-56.12027699999993,47.519157000000064],[-56.044448999999986,47.53527100000002],[-55.94193999999993,47.56166100000007],[-55.88999899999993,47.57833099999999],[-55.63999899999999,47.66805300000004],[-55.633331,47.67110400000007],[-55.628333999999995,47.674713000000054],[-55.635001999999986,47.67832900000013],[-55.64250199999998,47.67860400000012],[-55.64999399999999,47.677773000000116],[-55.66388699999993,47.67555200000004],[-55.704169999999976,47.66499299999998],[-55.75,47.649437000000034],[-55.756110999999976,47.646942000000024],[-55.77471899999995,47.638329000000056],[-55.80471799999998,47.62443500000012],[-55.82444799999996,47.61859900000002],[-55.838889999999935,47.61721000000006],[-55.85583500000001,47.62027000000012],[-55.90332799999993,47.64527099999992],[-55.913611999999944,47.65304600000002],[-55.91750300000001,47.657493999999986],[-55.91944899999993,47.667213000000004],[-55.918609999999944,47.67304999999999],[-55.91638899999998,47.67832900000013],[-55.91194200000001,47.684432999999956],[-55.90138999999999,47.693047000000035],[-55.895554000000004,47.696655000000135],[-55.86639399999996,47.713882000000126],[-55.83277899999996,47.74249300000008],[-55.81500199999999,47.772491],[-55.799445999999875,47.79916400000002],[-55.74222600000002,47.92332500000009],[-55.746947999999975,47.93249499999996],[-55.75444799999997,47.94110100000006],[-55.76721999999995,47.95332300000007],[-55.77361300000001,47.95694000000003],[-55.78055599999999,47.95526899999993],[-55.81750499999998,47.88693999999998],[-55.83527399999991,47.85083000000009],[-55.835556,47.845543000000134],[-55.847220999999934,47.806938],[-55.84999800000003,47.80110200000013],[-55.854445999999996,47.79471600000005],[-55.865279999999984,47.78611000000012],[-55.877219999999966,47.778602999999976],[-55.888892999999996,47.773048000000074],[-56.04972799999996,47.69943200000006],[-56.08750199999997,47.73693800000001],[-56.08111600000001,47.73971599999999],[-56.05361199999999,47.77388000000002],[-56.057503,47.77832799999999],[-56.06416300000001,47.776657000000114],[-56.111671,47.76361099999997],[-56.125,47.75721699999997],[-56.185272,47.680274999999995],[-56.160278000000005,47.64222000000012],[-56.15499899999986,47.638329000000056],[-56.16138499999994,47.634163000000115],[-56.173332000000016,47.629714999999976],[-56.18749999999994,47.6272130000001],[-56.35833699999989,47.603324999999984],[-56.394722,47.60110500000013],[-56.41027799999995,47.601387000000045],[-56.41889200000003,47.60193600000014],[-56.443053999999904,47.60582700000003],[-56.54695099999998,47.613883999999985],[-56.615554999999915,47.61332700000008],[-56.64416499999999,47.59610000000009],[-56.64111300000002,47.592216000000064],[-56.63999899999999,47.58721200000008],[-56.64416499999999,47.581108000000086],[-56.65055099999995,47.57833099999999],[-56.774719000000005,47.53193700000003],[-56.840836000000024,47.52137799999997],[-56.902221999999995,47.55249000000009],[-56.92444599999999,47.56220999999999],[-56.95610799999997,47.574996999999996],[-56.96527900000001,47.57777400000009],[-56.99250000000001,47.58387800000014],[-56.99972500000001,47.58471700000007],[-57.01472499999994,47.58387800000014],[-57.096663999999976,47.56610100000006],[-57.11833200000001,47.56388100000004],[-57.12610599999999,47.56388100000004],[-57.13444500000003,47.56638299999997],[-57.15027600000002,47.57276900000005],[-57.16332999999992,47.57972000000001],[-57.20472000000001,47.59304800000001],[-57.53082999999987,47.630821000000026],[-57.65777600000001,47.60305000000011],[-57.779441999999904,47.62748700000003],[-57.88249999999999,47.65138200000001],[-58.02749599999993,47.69415300000003],[-58.03639199999998,47.69609800000006],[-58.35944399999994,47.64721700000001],[-58.690552000000025,47.598877000000016],[-58.77111099999996,47.59137700000008],[-58.86194599999993,47.589157000000114],[-58.88500199999987,47.5927660000001],[-58.89416499999987,47.59388000000007],[-58.93749999999994,47.589989],[-59.076667999999984,47.571663],[-59.10213099999993,47.56425100000013],[-59.11361699999992,47.55832700000008],[-59.118889000000024,47.554710000000114],[-59.135559,47.55638099999999],[-59.161941999999954,47.56166100000007],[-59.29778299999987,47.60665899999998],[-59.30444299999999,47.609993000000145],[-59.30583199999995,47.614998000000014],[-59.30944099999999,47.661102000000085],[-59.30944099999999,47.67137900000006],[-59.30499999999995,47.724991000000045],[-59.3024979999999,47.736107000000004],[-59.32556199999999,47.80721300000005],[-59.32972699999999,47.81638300000009],[-59.36916400000001,47.85277599999995],[-59.40193899999997,47.88027199999999],[-59.40694400000001,47.889717000000076],[-59.40471599999995,47.900269000000094],[-59.40083299999992,47.90665400000006],[-59.39166999999992,47.916664000000026],[-59.37805199999991,47.92249300000003],[-59.365554999999915,47.92499500000008],[-59.328612999999905,47.92887900000011],[-59.32194500000003,47.93054999999998],[-59.31639100000001,47.93415800000008],[-59.31138599999997,47.938881000000094],[-59.26777599999997,47.98220800000007],[-59.26500699999991,47.98804500000006],[-59.262778999999966,47.99943500000012],[-59.246947999999975,48.01194000000004],[-59.23027799999994,48.02276599999999],[-59.218605000000025,48.02916000000005],[-59.091384999999946,48.09027100000014],[-59.05388599999986,48.105552999999986],[-59.041114999999934,48.11027500000006],[-59.020554000000004,48.11638599999998],[-58.958054000000004,48.14999399999999],[-58.75,48.287498000000085],[-58.701392999999996,48.31971699999997],[-58.69110899999998,48.32888000000014],[-58.686385999999914,48.334160000000054],[-58.682503,48.34054600000013],[-58.678337,48.35193600000002],[-58.675835000000006,48.363051999999925],[-58.67027999999999,48.37499200000002],[-58.59888499999994,48.423325000000034],[-58.58777599999996,48.43055000000004],[-58.56889299999989,48.43859900000007],[-58.55583199999995,48.443047000000035],[-58.514725,48.45277399999998],[-58.50055699999996,48.45555100000007],[-58.492774999999995,48.45555100000007],[-58.492774999999995,48.4502720000001],[-58.49777999999998,48.44582400000013],[-58.51889,48.44137599999999],[-58.52610800000002,48.4405440000001],[-58.54639400000002,48.434990000000084],[-58.55889100000002,48.42971799999998],[-58.588889999999935,48.412765999999976],[-58.59999800000003,48.405823],[-58.601112,48.40082600000005],[-58.59194199999996,48.39887999999996],[-58.483611999999994,48.427773],[-58.47083299999997,48.43221299999999],[-58.464721999999995,48.43637799999999],[-58.449439999999925,48.449158000000125],[-58.4183349999999,48.48665599999998],[-58.42027999999999,48.508049000000085],[-58.56944999999996,48.53860500000002],[-58.673614999999984,48.55471000000006],[-58.682503,48.554993000000024],[-58.69721999999996,48.55304699999999],[-58.732215999999994,48.545830000000024],[-58.765556000000004,48.535828000000095],[-58.778052999999886,48.53193700000003],[-58.81249999999994,48.52388000000002],[-58.857506,48.51859999999999],[-58.931389000000024,48.51193999999998],[-58.95472000000001,48.51082599999995],[-58.97916399999997,48.51249700000005],[-58.988335000000006,48.51444200000003],[-59.004722999999956,48.52027100000004],[-59.013335999999924,48.522217000000126],[-59.09166700000003,48.50833100000011],[-59.10555999999997,48.50471500000009],[-59.118889000000024,48.50110600000005],[-59.146392999999875,48.49304999999998],[-59.19277199999999,48.47776799999997],[-59.232497999999964,48.468597000000045],[-59.246947999999975,48.46665999999999],[-59.25527999999997,48.467490999999995],[-59.260558999999944,48.47193100000004],[-59.26111599999996,48.476653999999996],[-59.23277300000001,48.52304800000013],[-59.228882,48.529160000000104],[-59.215003999999965,48.545547000000056],[-59.209998999999925,48.549995000000024],[-59.137504999999976,48.59887699999996],[-59.084166999999866,48.62638099999998],[-59.07778200000001,48.629158000000075],[-59.050277999999935,48.63555100000002],[-59.03055599999999,48.6419370000001],[-59.02416999999997,48.64471400000002],[-58.908889999999985,48.70193499999999],[-58.828888000000006,48.750832000000116],[-58.81166799999994,48.76166500000005],[-58.79972799999996,48.76805099999996],[-58.774719000000005,48.77887700000008],[-58.76777599999997,48.775551000000064],[-58.77249899999998,48.76998900000012],[-58.815001999999936,48.73582500000009],[-58.84972399999987,48.7149960000001],[-58.873885999999914,48.70165999999995],[-58.89111300000002,48.69082600000007],[-58.912773000000016,48.674713000000054],[-58.93860599999988,48.65360300000009],[-58.94777699999992,48.642769000000044],[-58.955832999999984,48.63027200000005],[-58.95861099999996,48.62416100000013],[-58.95861099999996,48.613883999999985],[-58.955832999999984,48.60943600000002],[-58.94749499999995,48.60110500000013],[-58.896950000000004,48.55193300000002],[-58.888335999999924,48.55110199999996],[-58.74305700000002,48.56082200000009],[-58.728332999999964,48.56249200000002],[-58.72138199999995,48.56443800000011],[-58.715003999999965,48.56721500000003],[-58.709442000000024,48.570831000000055],[-58.70444500000002,48.575271999999984],[-58.69554900000003,48.58693700000009],[-58.68332700000002,48.60582700000003],[-58.67666600000001,48.618050000000096],[-58.67250100000001,48.62943300000006],[-58.66999800000002,48.640831000000105],[-58.671386999999925,48.650825999999995],[-58.674171,48.65526600000004],[-58.67944299999999,48.66944100000012],[-58.68083200000001,48.68471500000004],[-58.658051,48.74304999999998],[-58.618331999999896,48.779716000000064],[-58.54389200000003,48.86082499999998],[-58.53583499999996,48.87860100000012],[-58.506667999999934,48.949431999999945],[-58.506667999999934,48.98054499999995],[-58.503333999999995,48.997490000000084],[-58.50083899999993,49.003608999999926],[-58.400832999999864,49.12748700000009],[-58.39611099999996,49.131377999999984],[-58.35194399999989,49.15026899999998],[-58.348884999999996,49.14582800000011],[-58.342967999999985,49.10020100000003],[-58.365635,49.07992200000007],[-58.368019000000004,49.061428000000035],[-58.35370299999994,49.05665600000003],[-58.31075299999992,49.068584000000044],[-58.29285799999997,49.07276200000007],[-58.24055499999997,49.0702740000001],[-58.17832199999998,49.063217000000066],[-58.143726000000015,49.04174000000012],[-58.09833500000002,48.99221799999998],[-58.08472399999994,48.98526800000013],[-58.07778199999996,48.98193400000014],[-58.06027999999992,48.97609699999998],[-58.05055199999998,48.973320000000115],[-57.99610899999999,48.96138000000002],[-57.961388,48.95665700000001],[-57.93860599999999,48.95832800000005],[-57.90166499999998,48.96276899999998],[-57.88805400000001,48.966102999999976],[-57.88166799999999,48.96888000000007],[-57.892226999999934,48.98165899999992],[-57.90055100000001,48.9847180000001],[-57.92944299999999,48.978874000000076],[-57.95861100000002,48.97609699999998],[-57.974716,48.97609699999998],[-58.00922399999996,48.98041500000005],[-58.02777900000001,48.98554999999999],[-58.03583499999996,48.98860200000013],[-58.05055199999998,48.99582700000002],[-58.09332999999998,49.025825999999995],[-58.103888999999924,49.033607000000075],[-58.10805499999992,49.03777299999996],[-58.135276999999974,49.08277100000004],[-58.144447000000014,49.12193300000007],[-58.122612000000004,49.124931000000004],[-58.119282,49.127102000000036],[-58.11560800000001,49.12910500000004],[-58.111110999999994,49.129771999999946],[-58.09477599999997,49.124603000000036],[-58.078776999999945,49.12176900000003],[-58.04944599999993,49.120270000000005],[-57.92555999999996,49.12304700000004],[-57.91861,49.12470999999999],[-57.91332999999997,49.12915800000013],[-57.88277399999993,49.157767999999976],[-57.87888299999997,49.17027300000012],[-57.89805599999994,49.15860000000009],[-57.912215999999944,49.15277100000009],[-57.92583499999989,49.14833100000004],[-57.939437999999996,49.144997000000046],[-57.94749499999995,49.144997000000046],[-58.05722000000003,49.144997000000046],[-58.075558,49.153271000000075],[-58.08105499999999,49.15443800000014],[-58.08605599999993,49.15626900000012],[-58.092555999999945,49.16093400000011],[-58.09589399999993,49.16627100000011],[-58.064055999999994,49.18335000000013],[-58.063057000000015,49.18545199999994],[-58.06545599999998,49.19041400000003],[-58.060622999999964,49.18858300000005],[-58.05495499999995,49.18758399999996],[-58.034957999999904,49.185749000000044],[-58.02545900000001,49.185749000000044],[-58.011292000000026,49.186252999999965],[-58.00245699999999,49.18825100000009],[-57.99562100000003,49.19207800000004],[-57.98878500000001,49.19724700000012],[-57.93221999999997,49.23416099999997],[-57.92805499999997,49.240273000000116],[-57.93638599999997,49.239716000000044],[-57.99516299999999,49.236885000000086],[-58.003330000000005,49.234215000000006],[-58.011662,49.23071299999998],[-58.031001999999944,49.22454800000003],[-58.03566399999994,49.22371300000003],[-58.049331999999936,49.222717000000046],[-58.05882999999994,49.223049],[-58.19193999999993,49.23638200000005],[-58.20083599999987,49.239716000000044],[-58.211945000000014,49.24721500000004],[-58.23388699999998,49.27304799999996],[-58.236663999999905,49.27748900000006],[-58.24083699999994,49.28694200000007],[-58.24194299999999,49.29166399999997],[-58.24194299999999,49.30221599999999],[-58.223327999999924,49.39027400000003],[-58.21639299999998,49.402488999999946],[-58.192497,49.42943600000007],[-58.15777600000001,49.46443900000003],[-58.152221999999995,49.468879999999956],[-58.04389200000003,49.541382000000056],[-58.03221899999994,49.54833200000007],[-58.01916499999987,49.55387900000005],[-57.99833699999999,49.559158000000025],[-57.97110700000002,49.554993000000024],[-57.91511200000002,49.532047000000034],[-57.91060999999996,49.53021600000005],[-57.903445999999974,49.525551000000064],[-57.861445999999944,49.505885999999975],[-57.74694799999992,49.45360600000009],[-57.71500400000002,49.454712000000086],[-57.707503999999915,49.45555100000007],[-57.70111099999997,49.458327999999995],[-57.69638800000001,49.46360800000002],[-57.69888300000002,49.468323000000055],[-57.705832999999984,49.47165700000005],[-57.788895000000025,49.500832000000116],[-57.86422299999998,49.534939000000065],[-57.86938900000001,49.53543900000005],[-57.87271900000002,49.53777300000007],[-57.94222300000001,49.60305000000011],[-57.94471699999997,49.60749800000008],[-57.95111099999991,49.65277100000014],[-57.95111099999991,49.65776800000009],[-57.94833399999993,49.674164000000076],[-57.935272,49.708602999999925],[-57.926391999999964,49.726379000000065],[-57.89999399999999,49.76221500000008],[-57.82916999999992,49.84554300000008],[-57.67111199999994,50.084160000000054],[-57.631667999999934,50.14471400000008],[-57.543334999999956,50.29833200000013],[-57.524445000000014,50.33416],[-57.52138499999995,50.345267999999976],[-57.52111100000002,50.35054800000006],[-57.51555599999995,50.37360400000006],[-57.50722499999995,50.390831000000105],[-57.49833699999999,50.408600000000035],[-57.490837,50.42083000000014],[-57.44860799999998,50.48610699999995],[-57.37722000000002,50.58443499999993],[-57.37249799999995,50.5908280000001],[-57.36111499999993,50.598602000000085],[-57.34166700000003,50.60749800000002],[-57.310059000000024,50.60894000000013],[-57.300220000000024,50.60977600000007],[-57.295559000000026,50.60927200000009],[-57.291225,50.60710500000005],[-57.27622200000002,50.60144000000008],[-57.24527699999999,50.59638200000006],[-57.22804999999994,50.594437000000084],[-57.204444999999964,50.596100000000035],[-57.17361499999993,50.60083000000003],[-57.166945999999996,50.6033250000001],[-57.161384999999996,50.60638400000005],[-57.15083299999992,50.61610400000012],[-57.148056,50.621933000000126],[-57.15471599999995,50.625549000000035],[-57.171943999999996,50.624992000000134],[-57.276442999999915,50.64071700000005],[-57.378608999999926,50.687767000000065],[-57.33416699999992,50.71193700000009],[-57.32500499999992,50.71166200000005],[-57.23694599999999,50.72721100000001],[-57.16249800000003,50.75110599999999],[-57.14833799999991,50.75610399999999],[-57.08943899999991,50.780548000000124],[-57.072501999999986,50.79388400000005],[-56.98305499999998,50.86832400000009],[-56.927498000000014,50.915824999999984],[-56.898056,51.01944000000009],[-56.89917000000003,51.02443699999998],[-56.90332799999999,51.02860300000009],[-56.90999599999998,51.03276800000009],[-56.927223000000026,51.03860500000002],[-56.964721999999995,51.04332700000009],[-56.92166900000001,51.0513840000001],[-56.89222699999999,51.060272000000055],[-56.879996999999946,51.06554399999999],[-56.78444699999994,51.137771999999984],[-56.781386999999995,51.14360800000003],[-56.78194400000001,51.14916200000005],[-56.785278000000005,51.153046000000074],[-56.793334999999956,51.16137700000013],[-56.80972300000002,51.18360100000007],[-56.79389200000003,51.23998999999992],[-56.74416400000001,51.29305299999993],[-56.738609,51.298881999999935],[-56.733330000000024,51.302773],[-56.68250299999994,51.3394320000001],[-56.623885999999914,51.366386000000034],[-56.616942999999935,51.368881000000044],[-56.512504999999976,51.40221400000007],[-56.47666199999992,51.411658999999986],[-56.461945000000014,51.41499299999998],[-56.45416999999992,51.415543000000014],[-56.27138499999995,51.47165699999999],[-56.110557999999855,51.52387999999996],[-56.011391,51.56638300000003],[-55.99833699999999,51.572220000000016],[-55.96028100000001,51.59388000000001],[-55.943329000000006,51.60638400000005],[-55.918609999999944,51.62110100000001],[-55.90555599999999,51.626937999999996],[-55.898056,51.62860100000012],[-55.89028200000001,51.629433000000006],[-55.83777599999996,51.621376000000055],[-55.84638999999993,51.60193600000008],[-55.85777999999999,51.59332300000011],[-55.88500199999993,51.562492000000134],[-55.88666499999994,51.556938],[-55.88694800000002,51.55193300000013],[-55.88722200000001,51.50027499999999],[-55.886116000000015,51.49527000000012],[-55.87777699999998,51.49221800000004],[-55.69444299999998,51.48110200000008],[-55.63999899999999,51.481934000000024],[-55.648612999999955,51.48526799999996],[-55.68360899999999,51.5],[-55.729720999999984,51.54332700000003],[-55.737503000000004,51.552490000000034],[-55.73916600000001,51.55665600000009],[-55.73860899999994,51.567214999999976],[-55.735274999999945,51.57305100000002],[-55.724716,51.58360300000004],[-55.718605000000025,51.58721200000002],[-55.65332799999999,51.59054600000002],[-55.63166799999999,51.569717000000026],[-55.625,51.5655440000001],[-55.59861000000001,51.56137799999999],[-55.589721999999995,51.56027199999994],[-55.58138999999994,51.56027199999994],[-55.57444800000002,51.56276700000001],[-55.54750100000001,51.584991000000116],[-55.51583899999997,51.60221900000005],[-55.45861099999996,51.59221600000001],[-55.41111000000001,51.580826000000116],[-55.40555599999999,51.57694200000009],[-55.40444200000002,51.5719380000001],[-55.40527300000002,51.56166100000013],[-55.40694400000001,51.55609900000002],[-55.454444999999964,51.45526899999999],[-55.49222600000002,51.37776900000006],[-55.50805700000001,51.36332700000008],[-55.597778000000005,51.303604000000064],[-55.612777999999935,51.30110200000013],[-55.62222300000002,51.30332199999998],[-55.70278200000001,51.32804900000008],[-55.82055700000001,51.35083000000009],[-56.030555999999876,51.37860099999995],[-56.07833899999997,51.36971299999999],[-56.085556,51.36832399999997],[-56.096389999999985,51.318329000000006],[-56.025557999999876,51.23832700000003],[-56.01225299999999,51.21233700000005],[-55.99256100000002,51.17657500000013],[-55.95944199999997,51.19748700000008],[-55.85139499999997,51.22693600000002],[-55.83777599999996,51.23054500000006],[-55.76916499999999,51.216934000000094],[-55.76083399999999,51.213881999999955],[-55.72610500000002,51.190544000000045],[-55.71277600000002,51.17804700000005],[-55.70999899999998,51.17360700000006],[-55.71916199999998,51.12304700000004],[-55.732497999999964,51.07999400000011],[-55.73555799999991,51.07416500000011],[-55.75111399999997,51.05832700000008],[-55.75695000000002,51.05387900000011],[-55.796111999999994,51.03916200000009],[-55.80555700000002,51.00916300000006],[-55.85916900000001,50.94249000000002],[-55.99944299999987,50.788605000000075],[-56.068893,50.72443400000009],[-56.09227800000002,50.72571600000009],[-56.097279000000015,50.72588000000002],[-56.10127999999992,50.72804599999995],[-56.125832,50.754166000000055],[-56.130829000000006,50.763329000000056],[-56.133331,50.77304800000002],[-56.128052000000025,50.84638200000006],[-56.12222300000002,50.8638840000001],[-56.11972000000003,50.86915600000003],[-56.116394000000014,50.87499200000008],[-56.107223999999974,50.88721499999997],[-56.10388899999998,50.893326],[-56.10388899999998,50.89833100000004],[-56.107779999999934,50.90277100000009],[-56.12222300000002,50.89943700000009],[-56.14305899999994,50.89249400000011],[-56.155272999999966,50.885551000000135],[-56.1725009999999,50.85582700000009],[-56.15721899999994,50.69082600000007],[-56.141272999999956,50.6710470000001],[-56.13577699999996,50.66988400000014],[-56.16332999999992,50.61776700000007],[-56.25861400000002,50.502777000000094],[-56.32361599999996,50.446380999999974],[-56.42305799999991,50.352776000000006],[-56.42194399999994,50.34777100000014],[-56.42222600000002,50.34249100000005],[-56.423614999999984,50.33693700000009],[-56.42666600000001,50.331108000000086],[-56.462501999999915,50.272217000000126],[-56.50194499999992,50.214439000000084],[-56.51194799999996,50.20360600000009],[-56.55583200000001,50.16749600000003],[-56.635276999999974,50.10638399999999],[-56.743056999999965,50.022766000000104],[-56.76750199999992,49.96221200000008],[-56.778610000000015,49.933876],[-56.78194400000001,49.91749600000003],[-56.77500199999997,49.91915899999998],[-56.726661999999976,49.91610000000003],[-56.75984599999998,49.837275999999974],[-56.82790399999999,49.78500000000008],[-56.86686300000002,49.777603],[-56.90533099999999,49.74752000000012],[-56.82099900000003,49.74209600000006],[-56.78400799999997,49.731243000000006],[-56.78277600000001,49.69082600000007],[-56.815552000000025,49.59499400000004],[-56.818610999999976,49.58888200000001],[-56.84888499999994,49.544441000000006],[-56.84305599999993,49.548050000000046],[-56.826667999999984,49.56276700000001],[-56.78277600000001,49.60999300000009],[-56.76306199999999,49.63137800000004],[-56.749167999999884,49.64916199999999],[-56.73555799999997,49.66693900000001],[-56.71250199999997,49.696380999999974],[-56.67777999999993,49.73360400000013],[-56.598609999999894,49.81193500000006],[-56.56138599999997,49.84221599999995],[-56.477776000000006,49.89222000000001],[-56.46416499999992,49.89638500000001],[-56.43194599999998,49.890549000000135],[-56.412216,49.90971400000012],[-56.38805400000001,49.94304700000009],[-56.38500199999993,49.94915800000001],[-56.330284000000006,50.024994000000106],[-56.32417299999997,50.029990999999995],[-56.23777799999999,50.10027300000007],[-56.22083299999997,50.112495000000024],[-56.20889299999999,50.12027000000012],[-56.160278000000005,50.148048000000074],[-56.153884999999946,50.150543000000084],[-56.13249999999999,50.155548000000124],[-56.12471800000003,50.15638000000007],[-56.116660999999965,50.153046000000074],[-56.067222999999956,50.096382000000006],[-56.065001999999936,50.091377000000136],[-56.00500499999998,50.03138000000001],[-55.938605999999936,50.03638500000005],[-55.90527300000002,50.03388200000006],[-55.89611100000002,50.031937000000084],[-55.881110999999976,50.024994000000106],[-55.853888999999924,50.005554000000075],[-55.84610699999996,49.996940999999936],[-55.845275999999956,49.99221799999998],[-55.845551,49.986938000000066],[-55.84416199999998,49.98193400000014],[-55.840836000000024,49.977211000000125],[-55.83000199999998,49.969154],[-55.75500499999987,49.92416400000002],[-55.74610899999993,49.923050000000046],[-55.58721899999995,49.96415700000006],[-55.55610699999994,49.98027000000013],[-55.54389200000003,49.98721300000011],[-55.527221999999995,50.0002750000001],[-55.49169899999998,50.00730900000002],[-55.46333299999998,49.96693399999998],[-55.460830999999985,49.96221200000008],[-55.45972399999994,49.957497000000046],[-55.46028100000001,49.95221699999996],[-55.46500400000002,49.940826000000015],[-55.47527299999996,49.93027500000011],[-55.49222600000002,49.91721300000006],[-55.511391,49.908882000000006],[-55.659163999999976,49.84777100000008],[-55.84305599999993,49.78833000000009],[-55.98611499999987,49.74694099999999],[-56.11527999999993,49.63999200000012],[-56.124168,49.61332700000008],[-56.050551999999925,49.66638200000011],[-56.044448999999986,49.669990999999925],[-55.963889999999935,49.698601],[-55.957779000000016,49.70027200000004],[-55.89389,49.714157000000114],[-55.833327999999995,49.68665299999992],[-55.88027999999997,49.584990999999945],[-55.93544399999996,49.54399100000012],[-55.94544199999996,49.536159999999995],[-55.95344499999999,49.533660999999995],[-55.971607000000006,49.531826000000024],[-55.980278,49.53049500000003],[-56.03527799999995,49.50666000000007],[-56.08000199999992,49.48693800000001],[-56.12749500000001,49.43110700000011],[-56.129166,49.42555200000004],[-56.12277199999994,49.421379000000115],[-56.073891,49.434432999999956],[-56.06221800000003,49.440544000000045],[-56.02527599999996,49.46110500000009],[-56.02027899999996,49.46499599999993],[-56.005279999999914,49.48082000000005],[-55.99972500000001,49.48526800000002],[-55.96305499999994,49.496155000000044],[-55.91705300000001,49.50749600000012],[-55.87471799999997,49.51721200000003],[-55.82778199999996,49.5241620000001],[-55.783332999999914,49.511940000000095],[-55.775001999999915,49.50860599999993],[-55.72499799999997,49.47943100000009],[-55.72083299999997,49.47582200000005],[-55.725554999999986,49.47054300000008],[-55.72277100000002,49.45388000000003],[-55.67833699999994,49.38694000000004],[-55.67305799999997,49.38304900000014],[-55.664444,49.381935],[-55.65638699999994,49.38221000000004],[-55.65027599999996,49.384162999999944],[-55.639167999999984,49.392769000000044],[-55.63611599999996,49.39860499999992],[-55.637778999999966,49.40915700000011],[-55.637778999999966,49.413605000000075],[-55.63611599999996,49.41915900000009],[-55.58916499999992,49.46249400000005],[-55.56027999999998,49.482490999999925],[-55.55388599999992,49.48499300000003],[-55.54695099999998,49.48638199999999],[-55.53167000000002,49.487770000000125],[-55.523056,49.486655999999925],[-55.522223999999994,49.481934000000024],[-55.56639099999995,49.40915700000011],[-55.572776999999974,49.376656000000025],[-55.573058999999944,49.371658000000025],[-55.57055699999995,49.36693600000012],[-55.566666,49.36277000000001],[-55.55999800000001,49.365273],[-55.55471799999992,49.36971300000005],[-55.539443999999946,49.38555100000008],[-55.52972399999999,49.396942000000024],[-55.528053,49.402488999999946],[-55.528885,49.408043000000134],[-55.52916699999997,49.42332499999998],[-55.52638999999999,49.42860399999995],[-55.49610899999999,49.45388000000003],[-55.441666,49.491104000000064],[-55.430282999999974,49.498878000000104],[-55.37749500000001,49.50360900000004],[-55.36944599999998,49.50332600000007],[-55.34927699999997,49.468159000000014],[-55.33294699999993,49.41648900000013],[-55.33577699999995,49.388161000000025],[-55.333610999999905,49.35916100000003],[-55.33860800000002,49.35527000000013],[-55.336112999999955,49.35082999999997],[-55.315276999999924,49.31443799999994],[-55.31099699999993,49.35593799999998],[-55.30683099999993,49.356772999999976],[-55.274834,49.385605000000055],[-55.26750199999998,49.39660300000003],[-55.2645,49.40343500000006],[-55.264336000000014,49.406441000000086],[-55.26666999999986,49.40910300000007],[-55.269833000000006,49.41143800000003],[-55.28083800000002,49.41443600000008],[-55.28317299999992,49.41693500000008],[-55.31000099999994,49.48477200000002],[-55.310832999999946,49.487770000000125],[-55.30555700000002,49.53443900000008],[-55.261390999999946,49.54110700000007],[-55.14972699999993,49.546387000000095],[-55.14111299999996,49.54527300000012],[-55.13722200000001,49.540833000000134],[-55.123328999999956,49.49694100000005],[-55.12471799999997,49.46527100000014],[-55.22110700000002,49.26193999999998],[-55.231109999999944,49.251389000000074],[-55.23722099999998,49.24804699999993],[-55.29639400000002,49.22637900000001],[-55.315001999999936,49.216933999999924],[-55.365837,49.16526800000008],[-55.36916400000001,49.1594310000001],[-55.36944599999998,49.15416000000005],[-55.36000100000001,49.15138200000007],[-55.34749599999998,49.157211000000075],[-55.339721999999995,49.15860000000009],[-55.33167300000002,49.156654],[-55.32361599999996,49.153602999999976],[-55.319449999999904,49.14916200000005],[-55.30721999999997,49.104996000000085],[-55.30777699999999,49.0991590000001],[-55.31750499999998,49.08776900000004],[-55.323059,49.08332799999994],[-55.383331,49.04083300000002],[-55.345551,49.05777000000006],[-55.27222399999994,49.099998000000085],[-55.277495999999985,49.10388200000011],[-55.282501000000025,49.11305199999998],[-55.283332999999914,49.11804999999998],[-55.288054999999986,49.182495000000074],[-55.288054999999986,49.18721000000011],[-55.285004000000015,49.19304700000009],[-55.28055599999993,49.199157999999954],[-55.27527599999996,49.204436999999984],[-55.148056,49.259995],[-55.08111600000001,49.28388200000006],[-55.08167300000002,49.345825000000104],[-55.08138999999994,49.35110500000013],[-55.07805599999995,49.356941000000006],[-55.06945000000002,49.3555530000001],[-55.01028400000001,49.32388300000002],[-54.989998000000014,49.28694200000007],[-54.99055499999997,49.28166200000004],[-54.82444800000002,49.269157000000064],[-54.817779999999914,49.271660000000054],[-54.78750600000001,49.28860500000002],[-54.78194400000001,49.29277000000002],[-54.67972599999996,49.37999000000002],[-54.65833299999997,49.39916200000005],[-54.648056,49.40943100000004],[-54.641388000000006,49.42110400000007],[-54.64389,49.42582700000008],[-54.579726999999934,49.494713000000104],[-54.541114999999934,49.526657000000114],[-54.528885,49.53333300000003],[-54.52111100000002,49.533882000000006],[-54.474716,49.53499599999998],[-54.431945999999925,49.47082499999999],[-54.43083199999995,49.465828000000045],[-54.45055400000001,49.427773000000116],[-54.483330000000024,49.36193800000012],[-54.49361399999998,49.26805100000007],[-54.49250000000001,49.263611000000026],[-54.48694599999999,49.25971999999996],[-54.48055299999993,49.262215000000026],[-54.474716,49.266662999999994],[-54.40638699999994,49.32083100000011],[-54.40083299999992,49.32527200000004],[-54.39917000000003,49.330551000000014],[-54.410278000000005,49.34360500000008],[-54.412773000000016,49.34804500000007],[-54.413612,49.35304999999994],[-54.407501000000025,49.37471000000011],[-54.40416700000003,49.38054700000009],[-54.395003999999915,49.392769000000044],[-54.38027999999997,49.40888200000012],[-54.36999499999996,49.41915900000009],[-54.36416600000001,49.42360700000006],[-54.35805499999998,49.426941000000056],[-54.32527900000002,49.42388200000005],[-54.24888599999997,49.397490999999945],[-54.186661000000015,49.371101000000124],[-54.17888599999992,49.37082700000002],[-54.1661069999999,49.3780440000001],[-54.1619419999999,49.38360600000004],[-54.15582999999998,49.40526600000004],[-54.15332799999993,49.416100000000085],[-54.15193899999991,49.427216000000044],[-54.14833799999997,49.437492000000134],[-54.145279000000016,49.44332099999997],[-54.13999899999993,49.44860100000005],[-54.13388800000001,49.45193499999999],[-54.04888900000003,49.47943100000009],[-54.04167199999995,49.48082000000005],[-53.91999800000002,49.44776900000011],[-53.77500199999997,49.39610300000004],[-53.67333199999996,49.34304800000001],[-53.511116000000015,49.27721400000007],[-53.48860899999994,49.220543000000134],[-53.58833299999998,49.04083300000002],[-53.593886999999995,49.03555299999999],[-53.66194200000001,49.03221100000002],[-53.71472199999994,49.02915999999999],[-53.80444299999999,49.02221700000001],[-53.78527799999995,49.01110799999992],[-53.731667000000016,49.013329000000056],[-53.725273000000016,49.009720000000016],[-53.73666400000002,49.00110599999999],[-53.742774999999995,48.997772],[-53.74916799999994,48.99527000000012],[-53.77027899999996,48.98943300000013],[-53.80361199999999,48.97804300000007],[-53.81305699999996,48.93888100000004],[-53.974441999999954,48.84777100000008],[-54.02138499999995,48.833327999999995],[-54.09610699999996,48.81221000000011],[-53.92027999999999,48.834991000000116],[-53.89917000000003,48.83804300000003],[-53.875557000000015,48.836937000000034],[-53.82944500000002,48.83138300000002],[-53.82055699999995,48.82943699999993],[-53.800835000000006,48.81276700000001],[-53.802223000000026,48.80777000000006],[-53.84527600000001,48.766936999999984],[-53.86777499999994,48.75],[-53.89055599999989,48.733604000000014],[-53.89722399999994,48.73137700000012],[-53.93221999999997,48.71393599999999],[-53.95055400000001,48.67083000000014],[-53.93250299999994,48.62471000000011],[-53.92444599999999,48.62443500000006],[-53.91722099999993,48.62499199999996],[-53.88861099999997,48.631660000000124],[-53.88277399999993,48.63360600000004],[-53.869163999999955,48.638885000000016],[-53.857223999999974,48.64415700000012],[-53.79555499999992,48.67582700000003],[-53.79000100000002,48.67999300000014],[-53.79888900000003,48.682213000000104],[-53.81777999999997,48.67388200000005],[-53.83139,48.66999099999998],[-53.85278299999993,48.66638199999994],[-53.896950000000004,48.66220900000002],[-53.91305499999993,48.663605000000075],[-53.92083699999995,48.667213000000004],[-53.92444599999999,48.67137900000006],[-53.892058999999904,48.68293800000009],[-53.88722599999994,48.690102000000024],[-53.884052,48.69310000000013],[-53.88055400000002,48.69509900000014],[-53.85755899999998,48.70493700000003],[-53.75917099999998,48.71415699999994],[-53.618056999999965,48.69443500000011],[-53.61000100000001,48.69304699999998],[-53.601943999999946,48.68971300000004],[-53.599723999999924,48.68499000000003],[-53.603888999999924,48.674164000000076],[-53.61000100000001,48.668602000000135],[-53.645835999999974,48.648330999999985],[-53.65860700000002,48.6419370000001],[-53.67194399999994,48.63860299999993],[-53.72888199999994,48.62943300000006],[-53.779998999999975,48.62360400000006],[-53.787780999999995,48.622490000000084],[-53.92833699999994,48.575829000000056],[-53.93332700000002,48.57222000000007],[-53.951392999999996,48.549995000000024],[-53.956107999999915,48.54388399999999],[-53.95249899999993,48.53943600000002],[-53.9441599999999,48.53971899999999],[-53.93221999999997,48.544998000000135],[-53.91999800000002,48.551659000000086],[-53.914444,48.55582400000009],[-53.908332999999914,48.559158000000025],[-53.901389999999935,48.56220999999999],[-53.89500399999986,48.56304899999992],[-53.804169,48.56805399999996],[-53.78805499999993,48.56638300000009],[-53.74639100000002,48.55860099999995],[-53.74694799999992,48.52332299999995],[-53.74888599999997,48.51332900000011],[-53.750838999999985,48.50777400000004],[-53.756366999999955,48.50326200000012]],[[-127.91443599999991,51.41082],[-127.92443799999995,51.41027100000008],[-128.06527700000004,51.464157000000114],[-128.07583599999998,51.47054300000002],[-128.08111599999995,51.47470900000013],[-128.15307599999988,51.601661999999976],[-128.15417499999995,51.60582699999998],[-128.15280199999995,51.638046000000145],[-128.15249600000004,51.64193700000004],[-128.15029899999996,51.64749100000006],[-128.14556900000002,51.65360300000003],[-128.136414,51.6616590000001],[-128.01306199999993,51.72137500000008],[-128.00527999999997,51.72332000000006],[-128,51.720542999999964],[-127.99694799999997,51.71415700000006],[-127.99804699999999,51.71166200000005],[-127.995003,51.7052690000001],[-127.98388699999998,51.68249500000013],[-127.96749899999992,51.65193199999999],[-127.951683,51.633880999999974],[-127.93776699999995,51.621933000000126],[-127.92639199999996,51.60888699999998],[-127.91999800000002,51.60054799999995],[-127.90556300000003,51.55971500000004],[-127.87361099999993,51.46443900000003],[-127.87193300000001,51.45193499999999],[-127.87332200000003,51.44776900000005],[-127.87666299999995,51.44304699999998],[-127.90444899999994,51.41471100000007],[-127.91443599999991,51.41082]],[[-55.36750000000001,51.874161000000015],[-55.37471800000003,51.87387800000005],[-55.38221699999991,51.875267000000065],[-55.42888599999998,51.884163],[-55.43000000000001,51.88582600000012],[-55.43111399999992,51.887771999999984],[-55.43055700000002,51.89666],[-55.42610899999994,51.905823],[-55.42333199999996,51.9094310000001],[-55.38777900000002,51.942764000000125],[-55.35361499999999,51.96360800000008],[-55.30139200000002,51.99305000000004],[-55.283889999999985,52.001389000000074],[-55.27722199999994,52.00249500000007],[-55.26999699999999,52.000549000000035],[-55.26888999999994,51.998604],[-55.26750199999998,51.993881000000044],[-55.27417000000003,51.97693600000008],[-55.27417000000003,51.975548],[-55.28194400000001,51.961937000000034],[-55.295005999999944,51.943321000000026],[-55.30222299999997,51.93332699999996],[-55.33250399999997,51.89638499999995],[-55.342223999999874,51.88638300000002],[-55.35472099999993,51.87804399999999],[-55.36000100000001,51.87582400000014],[-55.36750000000001,51.874161000000015]],[[-128.053894,51.7536090000001],[-128.11972000000003,51.74166100000008],[-128.13192699999996,51.7438810000001],[-128.13613899999996,51.74665799999997],[-128.25445599999995,51.86582900000002],[-128.25308199999995,51.87221499999998],[-128.22222899999997,51.953323000000125],[-128.21749899999998,51.962769000000094],[-128.177795,52.00833099999994],[-128.150848,52.03527100000002],[-128.14529400000004,52.03860500000002],[-128.107758,52.051659000000086],[-128.06082200000003,52.05638099999999],[-127.99582699999996,52.062767000000065],[-127.98332199999993,52.06193499999995],[-127.96028100000001,52.05554999999998],[-127.95472699999999,52.05332199999998],[-127.95121799999998,52.04691300000013],[-127.95140100000003,52.03054800000001],[-127.95472699999999,51.981101999999964],[-128.00723299999993,51.782493999999986],[-128.00946,51.7783280000001],[-128.01306199999993,51.77360500000009],[-128.018616,51.77027100000009],[-128.03582800000004,51.760826000000066],[-128.053894,51.7536090000001]],[[-79.252792,52.07138099999992],[-79.31973299999999,51.96998600000006],[-79.36444099999994,51.942214999999976],[-79.370544,51.938599000000124],[-79.37666300000001,51.93610400000006],[-79.38583399999999,51.935546999999985],[-79.42361499999987,51.93693500000006],[-79.43331899999987,51.93832400000008],[-79.45056199999988,51.942214999999976],[-79.50111400000003,51.942489999999964],[-79.56834400000002,51.935546999999985],[-79.57667500000002,51.934158000000025],[-79.591949,51.92276800000013],[-79.604446,51.91666400000008],[-79.61166400000002,51.91443600000014],[-79.61776700000001,51.91777000000013],[-79.62138399999998,51.9222180000001],[-79.65278599999999,51.981101999999964],[-79.65417500000001,51.98665599999998],[-79.65083299999998,51.99193600000007],[-79.633896,52.01749399999994],[-79.62943999999999,52.022217000000126],[-79.62332200000003,52.02526900000004],[-79.61471599999993,52.02304800000013],[-79.608612,52.01998900000001],[-79.60388199999994,52.016106000000036],[-79.596115,52.013611000000026],[-79.58528100000001,52.01277200000004],[-79.56777999999997,52.0149990000001],[-79.53832999999997,52.023323000000005],[-79.40888999999999,52.071938000000046],[-79.39666699999987,52.07721700000002],[-79.38389599999994,52.09082799999999],[-79.345551,52.10860400000013],[-79.33833299999998,52.110275],[-79.29722599999997,52.09193399999998],[-79.27722199999988,52.090546000000074],[-79.26972999999992,52.08776899999998],[-79.26362599999999,52.083878000000084],[-79.252792,52.07138099999992]],[[-131.01889,51.94609800000006],[-131.02166699999998,51.94082599999996],[-131.029175,51.94137599999999],[-131.03695700000003,51.944435],[-131.04861499999998,51.951385000000016],[-131.074158,51.970543000000134],[-131.09500099999997,51.98998999999998],[-131.10165399999994,52.00277699999998],[-131.120544,52.05554999999998],[-131.12719699999997,52.09554300000002],[-131.126373,52.106941000000006],[-131.122498,52.12471000000011],[-131.116394,52.14804800000002],[-131.11026000000004,52.15109999999993],[-131.10192899999998,52.151932000000045],[-131.0836179999999,52.15138200000001],[-131.07720900000004,52.15026899999992],[-131.00946,52.102776000000006],[-130.9924929999999,52.06082200000009],[-131.00473,52.00582900000006],[-131.01889,51.94609800000006]],[[-127.96278399999989,52.07471499999991],[-128.05111699999992,52.07416500000005],[-128.062225,52.074996999999996],[-128.07638499999996,52.07999400000011],[-128.09387199999998,52.090546000000074],[-128.105835,52.100273000000016],[-128.10888699999992,52.10527000000013],[-128.12081899999998,52.14193699999993],[-128.11471599999987,52.14916199999999],[-128.10693400000002,52.15248900000012],[-128.03167699999995,52.163292000000126],[-128.01583900000003,52.164711000000125],[-127.89111299999996,52.17166099999997],[-127.881104,52.17221800000004],[-127.87917299999998,52.166664000000026],[-127.88971700000002,52.13110399999999],[-127.89334100000002,52.12693800000005],[-127.943604,52.07916300000005],[-127.94721999999996,52.07582900000011],[-127.96278399999989,52.07471499999991]],[[-128.21194499999996,52.015549000000135],[-128.220825,52.01444200000003],[-128.23858599999994,52.014717000000076],[-128.2463679999999,52.01666299999994],[-128.25308199999995,52.019714000000135],[-128.29110699999995,52.10193600000014],[-128.29415899999998,52.113609],[-128.29168700000002,52.1188810000001],[-128.25280799999996,52.17137900000006],[-128.24444600000004,52.17999300000014],[-128.23971599999993,52.18415800000014],[-128.23193399999997,52.187492000000134],[-128.18804899999998,52.19360400000011],[-128.16223100000002,52.196655000000135],[-128.15307599999988,52.195267],[-128.14779699999997,52.19165800000002],[-128.14584399999995,52.186104],[-128.1480709999999,52.18332700000013],[-128.154724,52.15943100000004],[-128.15612799999997,52.15332000000012],[-128.15862999999996,52.11971299999999],[-128.154449,52.10860400000013],[-128.15139799999997,52.103882000000056],[-128.14752199999998,52.0927660000001],[-128.15112299999993,52.081108000000086],[-128.206116,52.01888300000013],[-128.21194499999996,52.015549000000135]],[[-128.42834499999992,52.13749700000011],[-128.44415300000003,52.134163000000115],[-128.44638099999997,52.13499500000006],[-128.50472999999994,52.16027100000008],[-128.50918599999994,52.16443600000008],[-128.51113899999996,52.16999099999998],[-128.50863600000002,52.17555200000004],[-128.50527999999997,52.180274999999995],[-128.50058,52.18415800000014],[-128.45138499999996,52.21720900000008],[-128.448059,52.21915400000006],[-128.43331899999998,52.22332],[-128.41641200000004,52.22637900000012],[-128.40972899999997,52.224991000000045],[-128.40640299999995,52.2227630000001],[-128.40527299999997,52.21859699999999],[-128.4100039999999,52.21471400000007],[-128.40777599999996,52.15277100000003],[-128.408905,52.149437000000034],[-128.41363499999994,52.14527099999992],[-128.42834499999992,52.13749700000011]],[[-128.29998799999998,52.13360600000004],[-128.308044,52.12887599999999],[-128.313629,52.129714999999976],[-128.36499000000003,52.1624910000001],[-128.37304699999999,52.18526500000007],[-128.378601,52.21360800000002],[-128.37832599999996,52.22026800000003],[-128.3771969999999,52.22387700000007],[-128.37027,52.22860000000003],[-128.35665900000004,52.23582500000009],[-128.345276,52.238602000000014],[-128.29724099999999,52.237213],[-128.23721299999994,52.222488000000055],[-128.22943099999998,52.22026800000003],[-128.22720300000003,52.21888000000013],[-128.22610499999996,52.21693400000004],[-128.22747799999996,52.21276900000004],[-128.22997999999995,52.2094350000001],[-128.29998799999998,52.13360600000004]],[[-81.476944,52.24916100000007],[-81.48582499999992,52.248329000000126],[-81.646118,52.25138900000002],[-81.68749999999994,52.25499700000012],[-81.70611599999995,52.25804900000003],[-81.71000700000002,52.262496999999996],[-81.69583099999994,52.26721200000003],[-81.57806399999998,52.29471600000005],[-81.55166600000001,52.298050000000046],[-81.541672,52.29666100000003],[-81.49305700000002,52.28388199999995],[-81.48055999999997,52.277489],[-81.475281,52.27388000000002],[-81.47166400000003,52.268051000000014],[-81.46806300000003,52.26305400000007],[-81.46777299999997,52.25694299999998],[-81.47083999999995,52.25222000000002],[-81.476944,52.24916100000007]],[[-127.924713,52.17416400000013],[-127.93360899999999,52.17304999999993],[-128.036407,52.17748999999998],[-128.05416899999994,52.18055000000004],[-128.07971199999997,52.186377999999934],[-128.08639500000004,52.18859900000007],[-128.0927729999999,52.19221500000009],[-128.16696199999996,52.244713000000104],[-128.17001299999998,52.24971800000014],[-128.15862999999996,52.25638600000008],[-128.06945799999994,52.29471600000005],[-128.0477909999999,52.30054500000006],[-128.04000899999994,52.30165900000003],[-127.97944599999994,52.29666100000003],[-127.972778,52.29527300000012],[-127.96193700000003,52.28943600000014],[-127.95861799999989,52.28749800000003],[-127.95111099999997,52.279716000000064],[-127.90943899999996,52.21027400000003],[-127.90750100000002,52.204712000000086],[-127.90666199999998,52.198601],[-127.91055299999988,52.186377999999934],[-127.91776999999996,52.176941],[-127.924713,52.17416400000013]],[[-128.18444799999992,52.278602999999976],[-128.20361299999996,52.277489],[-128.21026599999993,52.27832799999999],[-128.21362299999998,52.279716000000064],[-128.18917799999986,52.330826000000116],[-128.18307499999997,52.33971400000013],[-128.11471599999987,52.41832700000009],[-128.11111499999998,52.421661000000086],[-128.10443099999992,52.421379],[-128.0999759999999,52.418602000000135],[-128.093597,52.41165899999993],[-128.09249899999998,52.408324999999934],[-128.085266,52.396385000000066],[-128.05917399999998,52.35221900000005],[-128.05694600000004,52.346100000000035],[-128.05526699999996,52.334991000000116],[-128.05667099999994,52.32888000000008],[-128.061401,52.32471500000008],[-128.151947,52.282211000000075],[-128.18444799999992,52.278602999999976]],[[-127.72444199999995,51.97693600000008],[-127.8708269999999,51.944709999999986],[-127.87970699999994,51.94499200000007],[-127.886124,51.947768999999994],[-127.89167800000001,51.951385000000016],[-127.89472999999992,51.95610000000005],[-127.89943700000003,51.97332],[-127.90110799999991,51.98582499999998],[-127.90055799999988,51.999435000000005],[-127.881104,52.07888000000008],[-127.87361099999993,52.09499400000004],[-127.85138699999999,52.14138000000003],[-127.82833900000003,52.17582700000003],[-127.817497,52.191375999999934],[-127.79750100000001,52.213882000000126],[-127.78916899999996,52.221930999999984],[-127.75334199999998,52.24582700000008],[-127.74527,52.247772000000055],[-127.699997,52.25721699999991],[-127.68083199999995,52.25888800000001],[-127.65943900000002,52.259163],[-127.65055799999999,52.260276999999974],[-127.58640300000002,52.28110500000008],[-127.516663,52.30443600000012],[-127.51000999999985,52.306938],[-127.46056399999998,52.34582499999999],[-127.45694700000001,52.350548],[-127.45612299999988,52.362213000000054],[-127.45694700000001,52.36832400000014],[-127.45333900000003,52.37304699999993],[-127.4177699999999,52.38526900000011],[-127.36277799999999,52.403876999999966],[-127.26390100000003,52.43665300000009],[-127.25945300000001,52.435265000000015],[-127.23473399999995,52.41693900000001],[-127.20777899999996,52.34471100000002],[-127.21056399999992,52.33526599999999],[-127.218887,52.325829000000056],[-127.23222399999992,52.31304900000009],[-127.24749800000001,52.30193300000013],[-127.27084399999995,52.28860500000013],[-127.28916899999996,52.27943399999998],[-127.30304699999999,52.27416200000005],[-127.30999800000001,52.27166],[-127.32584400000002,52.268051000000014],[-127.36193800000001,52.26471700000002],[-127.42582699999997,52.24610100000001],[-127.43971299999993,52.240829000000076],[-127.44526699999994,52.23832699999997],[-127.57972699999999,52.177216000000044],[-127.58444199999991,52.17332499999998],[-127.58805799999999,52.167770000000075],[-127.59631300000001,52.151793999999995],[-127.65416700000003,52.12387799999999],[-127.68694299999993,52.074440000000095],[-127.69193999999993,52.06360600000005],[-127.70111099999991,52.04110700000007],[-127.703888,52.028877000000136],[-127.699997,52.01776899999999],[-127.69915799999995,52.01138300000008],[-127.699432,52.00471500000009],[-127.70194999999995,51.998604],[-127.708054,51.98832700000003],[-127.71749899999998,51.980270000000075],[-127.72444199999995,51.97693600000008]],[[-128.66860999999994,52.26638800000006],[-128.67556799999994,52.26638800000006],[-128.72055099999994,52.306938],[-128.724152,52.31137800000005],[-128.72637899999995,52.316101],[-128.74832200000003,52.36915600000009],[-128.76196299999998,52.41832700000009],[-128.76251200000002,52.42332500000009],[-128.76196299999998,52.429160999999965],[-128.759186,52.449432],[-128.75280799999996,52.4677660000001],[-128.74722299999996,52.47165699999999],[-128.6813959999999,52.48220800000007],[-128.674438,52.48220800000007],[-128.65029899999996,52.47443400000009],[-128.63696299999992,52.4685970000001],[-128.624146,52.4616620000001],[-128.61914099999996,52.45777100000004],[-128.615814,52.453606000000036],[-128.61608899999993,52.44860099999994],[-128.61331199999995,52.364441000000056],[-128.61471599999993,52.3533250000001],[-128.61776699999996,52.329994000000056],[-128.61999500000002,52.32388300000014],[-128.62554899999992,52.31137800000005],[-128.62997399999995,52.305550000000096],[-128.66860999999994,52.26638800000006]],[[-128.471924,52.49276700000013],[-128.4677729999999,52.483047000000056],[-128.46499599999993,52.47304500000007],[-128.46417199999996,52.46804800000001],[-128.46499599999993,52.462212000000136],[-128.467224,52.456099999999935],[-128.47082499999993,52.44971499999997],[-128.4805599999999,52.440269],[-128.4869379999999,52.43720999999999],[-128.494141,52.43498999999997],[-128.50946,52.432213000000104],[-128.51806599999998,52.43193800000006],[-128.59553499999998,52.46014000000008],[-128.66314699999987,52.49192799999997],[-128.75500499999998,52.48777000000001],[-128.77557399999995,52.49332400000003],[-128.7847289999999,52.496101000000124],[-128.80944799999997,52.51554900000008],[-128.81304899999992,52.519989000000066],[-128.81390399999998,52.524994000000106],[-128.811127,52.536941999999954],[-128.808899,52.54305300000004],[-128.73889199999996,52.58749400000005],[-128.732483,52.59054599999996],[-128.72470099999998,52.59165999999999],[-128.5781859999999,52.5936430000001],[-128.56750499999998,52.62249000000003],[-128.535278,52.64721700000007],[-128.53167699999995,52.62110100000001],[-128.52890000000002,52.611107000000004],[-128.52194199999997,52.59137700000002],[-128.50085399999995,52.543610000000115],[-128.4888919999999,52.52027099999998],[-128.48526000000004,52.515831000000105],[-128.47970599999996,52.50666000000001],[-128.471924,52.49276700000013]],[[-131.464447,52.62748700000009],[-131.58554099999998,52.585266000000104],[-131.593597,52.585823000000005],[-131.601379,52.5886000000001],[-131.6119379999999,52.59609999999998],[-131.62359600000002,52.60888699999998],[-131.709717,52.705269000000044],[-131.691101,52.7249910000001],[-131.68499799999995,52.728043000000014],[-131.65945399999993,52.730270000000075],[-131.48471099999995,52.736938000000066],[-131.475281,52.73665599999998],[-131.468597,52.73333000000014],[-131.46887200000003,52.73054500000012],[-131.44943199999994,52.71499600000004],[-131.44027699999998,52.706940000000145],[-131.4391779999999,52.70166000000006],[-131.441376,52.684158000000025],[-131.45443699999998,52.63638300000002],[-131.45834399999995,52.63082100000008],[-131.464447,52.62748700000009]],[[-128.43029799999994,52.36805000000004],[-128.44168099999996,52.36805000000004],[-128.4561159999999,52.37304699999993],[-128.460266,52.37721300000004],[-128.46664399999986,52.38693999999998],[-128.4677729999999,52.39305100000007],[-128.437775,52.543610000000115],[-128.44973800000002,52.62082700000008],[-128.450562,52.626937999999996],[-128.44168099999996,52.746941000000106],[-128.43917799999997,52.75222000000008],[-128.43582200000003,52.75694300000009],[-128.390015,52.79749300000003],[-128.383331,52.79749300000003],[-128.37332200000003,52.791107000000125],[-128.36276199999998,52.740272999999945],[-128.35861199999988,52.7291560000001],[-128.32138099999992,52.63472000000013],[-128.275848,52.496101000000124],[-128.27502400000003,52.489990000000034],[-128.28640699999994,52.45777100000004],[-128.311401,52.42388199999999],[-128.365814,52.38220999999993],[-128.371643,52.37887599999999],[-128.386414,52.374992000000134],[-128.40335099999993,52.37165800000014],[-128.43029799999994,52.36805000000004]],[[-128.974426,52.45332300000007],[-128.982758,52.453049000000135],[-129.11471599999993,52.55665600000009],[-129.21081499999997,52.64888000000002],[-129.26333599999998,52.710548000000074],[-129.27056899999997,52.719153999999946],[-129.291962,52.761664999999994],[-129.29278599999998,52.7669370000001],[-129.28140299999995,52.81721500000009],[-129.27722199999988,52.823051000000135],[-129.270844,52.826103000000046],[-129.26223799999997,52.82666000000012],[-129.252228,52.82527200000004],[-129.23111,52.81610100000006],[-129.218323,52.80915800000008],[-129.104156,52.74110399999995],[-129.066101,52.71471400000013],[-128.94695999999993,52.626381000000094],[-128.926941,52.61082500000009],[-128.92333999999994,52.606659000000036],[-128.919739,52.60221899999999],[-128.91861,52.527488999999946],[-128.92251599999997,52.51527400000003],[-128.936401,52.480545000000006],[-128.943604,52.469711000000075],[-128.9491579999999,52.465546000000074],[-128.96166999999997,52.45943500000004],[-128.974426,52.45332300000007]],[[-128.26974499999994,52.596939000000134],[-128.27416999999997,52.59554300000008],[-128.27890000000002,52.59582499999999],[-128.28445399999998,52.59860200000003],[-128.287506,52.60277600000006],[-128.28973399999995,52.60833000000008],[-128.29269399999993,52.661549000000036],[-128.32305899999994,52.74110399999995],[-128.32638499999996,52.77137800000003],[-128.32501199999996,52.7761000000001],[-128.26322900000002,52.784645000000125],[-128.21063200000003,52.79851500000001],[-128.18582199999992,52.82694200000003],[-128.177795,52.826103000000046],[-128.17334,52.82332600000012],[-128.17028799999997,52.81777199999999],[-128.175842,52.78777300000013],[-128.17861899999997,52.7761000000001],[-128.20776399999994,52.704436999999984],[-128.21026599999993,52.698875000000044],[-128.24722299999996,52.62054400000011],[-128.249725,52.616660999999965],[-128.26141399999995,52.60443900000001],[-128.26974499999994,52.596939000000134]],[[-131.63973999999996,52.828049000000135],[-131.64666699999992,52.82582900000011],[-131.64889499999998,52.826103000000046],[-131.669739,52.81916000000007],[-131.708344,52.811378000000104],[-131.72387700000002,52.80832700000008],[-131.73306299999996,52.80860100000001],[-131.81332399999997,52.82027400000004],[-131.82388300000002,52.82777400000009],[-131.83138999999994,52.84193400000004],[-131.830292,52.84665699999999],[-131.8225099999999,52.84804500000013],[-131.74859599999996,52.853324999999984],[-131.72860699999995,52.851387000000045],[-131.644745,52.83554800000013],[-131.636414,52.8324970000001],[-131.63973999999996,52.828049000000135]],[[-128.50527999999997,52.641106000000036],[-128.5125119999999,52.641106000000036],[-128.51611300000002,52.64527100000004],[-128.52029400000004,52.65499100000011],[-128.54000899999994,52.70332300000001],[-128.53500399999996,52.758049000000085],[-128.53362999999996,52.76915700000012],[-128.513916,52.860825000000034],[-128.510284,52.867493000000024],[-128.50613399999992,52.87304700000004],[-128.498871,52.87082700000002],[-128.49194299999994,52.868599000000074],[-128.48553499999997,52.865273],[-128.471924,52.853049999999996],[-128.46832299999994,52.84860200000003],[-128.45083599999992,52.805267000000015],[-128.45361300000002,52.782493999999986],[-128.45443699999998,52.776939000000084],[-128.5016779999999,52.647491],[-128.50527999999997,52.641106000000036]],[[-129.61053500000003,52.954994],[-129.618317,52.95360600000009],[-129.62222299999996,52.95804600000008],[-129.65139799999992,53.01332900000011],[-129.650848,53.01888300000013],[-129.62441999999993,53.02388000000002],[-129.615814,53.02443699999992],[-129.607208,53.02276600000005],[-129.5705569999999,53.013611000000026],[-129.5625,53.010551000000135],[-129.55749499999996,53.00666000000007],[-129.556671,53.00138900000002],[-129.558624,52.99749000000003],[-129.55334500000004,52.98499300000003],[-129.561127,52.97054300000008],[-129.5963749999999,52.9594350000001],[-129.61053500000003,52.954994]],[[-129.531677,53.010551000000135],[-129.53890999999993,53.008049000000085],[-129.546967,53.00888800000001],[-129.58859299999995,53.0241620000001],[-129.640015,53.04415899999998],[-129.63391099999996,53.056099000000074],[-129.56277499999993,53.05304699999999],[-129.52444500000001,53.03360699999996],[-129.51779199999993,53.02999100000011],[-129.517242,53.02499399999999],[-129.52056900000002,53.01832600000006],[-129.531677,53.010551000000135]],[[-55.76306199999999,53.02943400000004],[-55.85333300000002,53.01527399999992],[-55.86194599999999,53.015549000000135],[-55.870834,53.01859999999999],[-55.87638899999996,53.02748900000006],[-55.87610599999999,53.03276800000003],[-55.872772,53.04388399999999],[-55.86971999999997,53.04972100000009],[-55.85777999999999,53.06749700000006],[-55.854445999999996,53.071663],[-55.84860999999995,53.07610299999999],[-55.808333999999945,53.09137700000008],[-55.80055199999998,53.093605000000025],[-55.79222900000002,53.093048000000124],[-55.788612,53.08971400000013],[-55.78833799999995,53.08665500000001],[-55.749168,53.06916000000001],[-55.748885999999914,53.06471299999993],[-55.75500499999987,53.03860499999996],[-55.75666799999999,53.033051],[-55.76306199999999,53.02943400000004]],[[-129.60247799999996,53.05721300000005],[-129.61080899999996,53.056655999999975],[-129.69250499999993,53.075829000000056],[-129.701935,53.078330999999935],[-129.70834399999995,53.08166499999993],[-129.723053,53.09915900000004],[-129.73611500000004,53.12221500000004],[-129.738312,53.12721300000004],[-129.732758,53.13110399999994],[-129.716949,53.13388100000003],[-129.69973800000002,53.134995],[-129.6680599999999,53.13610800000009],[-129.662506,53.13555100000002],[-129.65444899999994,53.13276700000006],[-129.650848,53.130547000000035],[-129.644165,53.12721300000004],[-129.62081899999998,53.11249499999997],[-129.615814,53.10860400000007],[-129.5880429999999,53.08471700000007],[-129.58416699999998,53.08027600000014],[-129.58193999999997,53.07555400000007],[-129.586121,53.06999200000013],[-129.596649,53.061104000000114],[-129.60247799999996,53.05721300000005]],[[-79.90916400000003,53.081940000000145],[-79.91972399999997,53.081940000000145],[-79.92610200000001,53.084991],[-79.92971799999998,53.0894320000001],[-79.93222000000003,53.09443699999997],[-79.93859900000001,53.122490000000084],[-79.93859900000001,53.134995],[-79.93499799999995,53.147774000000084],[-79.93055700000002,53.15248900000012],[-79.906387,53.172768000000076],[-79.89778100000001,53.17443800000001],[-79.88751199999996,53.17443800000001],[-79.87748699999997,53.1730500000001],[-79.86639399999996,53.16944100000012],[-79.85888699999987,53.16693900000001],[-79.84611499999994,53.16054500000001],[-79.79583699999989,53.116386000000034],[-79.789444,53.106941000000006],[-79.78721599999994,53.10193600000014],[-79.789444,53.09582500000005],[-79.79695100000004,53.093605000000025],[-79.835556,53.083878000000084],[-79.843887,53.08221400000008],[-79.90916400000003,53.081940000000145]],[[-129.4324949999999,53.15138200000001],[-129.35278299999993,53.07222000000007],[-129.29000899999988,52.993607000000054],[-129.287506,52.978043000000014],[-129.28945899999985,52.971930999999984],[-129.295837,52.96888000000001],[-129.31222499999996,52.966934000000094],[-129.341095,52.97332],[-129.41418499999997,53.010551000000135],[-129.41915900000004,53.01444200000003],[-129.42138699999998,53.019157000000064],[-129.42471299999994,53.04027600000006],[-129.42916899999994,53.04972100000009],[-129.475281,53.10193600000014],[-129.50527999999997,53.12638099999998],[-129.51196300000004,53.129714999999976],[-129.52194199999985,53.13110399999994],[-129.537506,53.12832600000013],[-129.54473899999994,53.12832600000013],[-129.54724099999993,53.13304900000014],[-129.548065,53.14916199999999],[-129.546967,53.16027100000008],[-129.5386049999999,53.171660999999915],[-129.52166699999992,53.18360100000001],[-129.51446499999997,53.185822000000144],[-129.49859599999996,53.18859900000001],[-129.49026499999997,53.188881000000094],[-129.47997999999995,53.18776700000012],[-129.470551,53.185265000000015],[-129.46276899999992,53.17999300000008],[-129.4324949999999,53.15138200000001]],[[-81.10610999999989,53.19971499999997],[-81.08778399999989,53.17943600000001],[-81.04527299999995,53.14860500000009],[-80.97888199999994,53.11305200000004],[-80.97361799999999,53.10943600000002],[-80.80943300000001,52.97693600000008],[-80.77500899999995,52.94443499999994],[-80.76333599999992,52.931381000000044],[-80.66915899999998,52.776939000000084],[-80.66776999999996,52.7719350000001],[-80.66749600000003,52.7594380000001],[-80.67083699999989,52.74582700000013],[-80.67304999999993,52.74054700000005],[-80.69972200000001,52.69609800000012],[-80.70500199999998,52.692214999999976],[-80.71250900000001,52.689156000000025],[-80.720551,52.68832400000014],[-80.731674,52.68888100000004],[-80.73916600000001,52.69137600000005],[-80.74916100000002,52.698875000000044],[-80.75306699999999,52.70332300000001],[-80.76583900000003,52.70971700000001],[-80.79750099999995,52.719153999999946],[-80.81500199999999,52.72304500000001],[-80.86138899999992,52.73110200000002],[-80.89889499999998,52.73749500000014],[-80.91888399999999,52.740272999999945],[-80.99554399999994,52.74610100000007],[-81.01556399999993,52.74860400000006],[-81.02444499999996,52.750549000000035],[-81.13806199999993,52.78804800000012],[-81.15306099999998,52.793052999999986],[-81.19888299999997,52.81415600000008],[-81.21278399999994,52.81999199999996],[-81.25195300000001,52.8324970000001],[-81.287216,52.83998900000006],[-81.36915599999986,52.85610200000008],[-81.41722099999987,52.863052000000096],[-81.58444199999991,52.88916000000006],[-81.64917000000003,52.907211000000075],[-81.76362599999993,52.93776700000001],[-81.781387,52.941658000000075],[-81.81166099999996,52.94526700000006],[-81.83416699999987,52.94638100000003],[-81.88137799999998,52.954162999999994],[-81.91665599999999,52.96166199999999],[-81.93331899999998,52.965828000000045],[-81.94972199999995,52.97137500000002],[-81.96278399999989,52.97693600000008],[-82.04998799999998,53.01444200000003],[-82.05665599999986,53.01749400000011],[-82.06166100000002,53.021102999999925],[-82.06332399999991,53.026657000000114],[-82.060272,53.03193700000003],[-82.05332900000002,53.04193899999996],[-82.04916400000002,53.04666100000003],[-81.974716,53.113883999999985],[-81.96528599999994,53.12221500000004],[-81.95417799999996,53.129990000000134],[-81.91082799999998,53.15888200000006],[-81.89222699999999,53.16832699999998],[-81.864441,53.17860400000012],[-81.84805299999994,53.18166400000001],[-81.82611099999997,53.181381000000044],[-81.71472199999988,53.18859900000001],[-81.54305999999997,53.209160000000054],[-81.3852839999999,53.22499099999999],[-81.37499999999994,53.22499099999999],[-81.295547,53.21776599999998],[-81.11639400000001,53.20082900000011],[-81.10610999999989,53.19971499999997]],[[-131.76223800000002,53.19665500000008],[-131.6305539999999,53.08416],[-131.595551,53.04610399999996],[-131.593048,53.041382000000056],[-131.59472700000003,53.03527100000002],[-131.60165399999994,53.033051],[-131.61026000000004,53.03221100000013],[-131.628876,53.0324940000001],[-131.63973999999996,53.03443900000008],[-131.73666400000002,53.05387900000005],[-131.75558499999994,53.058601000000124],[-131.77444500000001,53.06888600000008],[-131.7839049999999,53.07138100000009],[-131.79473899999994,53.07305100000008],[-131.813629,53.07360799999998],[-131.82971199999992,53.07138100000009],[-131.943329,53.054993000000024],[-131.964722,53.046386999999925],[-131.91195700000003,53.00527199999999],[-131.9083559999999,53.011108000000036],[-131.89944499999996,53.019714000000135],[-131.888062,53.02693900000003],[-131.87027,53.03749800000003],[-131.85611,53.04222100000004],[-131.847778,53.04305299999993],[-131.831116,53.04305299999993],[-131.81167600000003,53.03971899999999],[-131.662781,53.00777400000004],[-131.644745,53.00388299999997],[-131.62860099999995,52.998328999999956],[-131.61498999999998,52.99166100000002],[-131.609711,52.98804500000011],[-131.598053,52.97526600000009],[-131.59582499999993,52.96471400000007],[-131.59750399999996,52.95860299999998],[-131.61554,52.920273000000066],[-131.662781,52.88221000000004],[-131.66805999999997,52.87804399999993],[-131.68057299999992,52.871658000000025],[-131.68749999999994,52.869155999999975],[-131.70443699999993,52.86776700000013],[-131.802216,52.86471599999993],[-131.808624,52.86582900000002],[-131.833618,52.88499500000006],[-131.849152,52.9019320000001],[-131.87027,52.922768000000076],[-131.88473499999992,52.93443300000001],[-131.890015,52.93832400000008],[-131.898346,52.94110099999995],[-131.906677,52.94026900000006],[-131.93859899999995,52.934990000000084],[-131.94473299999999,52.93166400000001],[-131.982483,52.87971500000003],[-131.978607,52.87554900000009],[-131.968597,52.87443500000012],[-131.95278899999988,52.875267000000065],[-131.94528200000002,52.87693800000011],[-131.93139599999995,52.88166000000001],[-131.85638399999993,52.85610200000008],[-131.7755739999999,52.71666000000005],[-131.767517,52.71388200000001],[-131.733612,52.69860100000011],[-131.72692900000004,52.69554100000005],[-131.72305299999988,52.691101],[-131.683899,52.64222000000001],[-131.681396,52.637496999999996],[-131.65945399999993,52.581665000000044],[-131.572784,52.52999100000005],[-131.56527700000004,52.5316620000001],[-131.55667099999994,52.53221100000002],[-131.545837,52.53027300000008],[-131.48193400000002,52.50777399999998],[-131.46749899999992,52.50138900000013],[-131.42361499999998,52.46082300000012],[-131.42748999999998,52.414993000000095],[-131.39849899999996,52.377827000000025],[-131.39533999999998,52.37549200000012],[-131.39016699999996,52.374660000000006],[-131.3674929999999,52.381827999999985],[-131.365494,52.384491000000025],[-131.36599699999988,52.390986999999996],[-131.36715700000002,52.39716000000004],[-131.357483,52.403320000000065],[-131.3583369999999,52.414153999999996],[-131.35305799999998,52.41832700000009],[-131.32833900000003,52.431107000000054],[-131.31304899999998,52.43415800000008],[-131.27252199999998,52.43888100000004],[-131.25558499999988,52.440269],[-131.23638900000003,52.43915600000008],[-131.23248299999995,52.43471499999998],[-131.247498,52.36582900000013],[-131.25085399999995,52.35916099999997],[-131.25836200000003,52.34777100000008],[-131.263062,52.34276600000004],[-131.30311599999993,52.332100000000025],[-131.31977799999993,52.33510600000005],[-131.330597,52.33277099999992],[-131.33248899999995,52.29361],[-131.32833900000003,52.28499599999998],[-131.3244319999999,52.280823],[-131.271393,52.27777100000009],[-131.259186,52.28416400000003],[-131.25613399999992,52.29083300000008],[-131.24832199999997,52.3022160000001],[-131.17971799999998,52.31777200000005],[-131.17193599999996,52.31944299999992],[-131.136414,52.31137800000005],[-131.09500099999997,52.28611000000012],[-131.015015,52.22554800000012],[-131.00750699999998,52.21720900000008],[-131.0052799999999,52.206657000000064],[-131.01168799999988,52.19360400000011],[-131.01556400000004,52.18776700000012],[-131.024719,52.17804700000005],[-131.030304,52.17388200000005],[-131.036407,52.17083000000014],[-131.0430599999999,52.16832699999998],[-131.11512799999997,52.168289000000016],[-131.166107,52.12554900000009],[-131.18057299999987,52.121658000000025],[-131.26473999999985,52.11971299999999],[-131.29888900000003,52.15026899999992],[-131.36025999999993,52.18915600000014],[-131.366943,52.192490000000134],[-131.38946499999997,52.20582600000006],[-131.41168200000004,52.22054300000008],[-131.55111699999998,52.333878000000084],[-131.57333399999993,52.36082499999998],[-131.58194000000003,52.379990000000134],[-131.582764,52.38526900000011],[-131.58056599999986,52.390548999999965],[-131.57778899999994,52.39360799999997],[-131.57083099999994,52.39610299999998],[-131.548065,52.40054300000003],[-131.53973399999995,52.4011000000001],[-131.52972399999993,52.400269000000094],[-131.52029400000004,52.39777400000003],[-131.561401,52.431664000000126],[-131.66168199999998,52.478324999999984],[-131.67916899999994,52.48360400000013],[-131.7094419999999,52.49110400000001],[-131.76223800000002,52.50499700000006],[-131.77529899999996,52.51166500000005],[-131.892792,52.58277100000009],[-132.01751699999994,52.677490000000034],[-132.08194000000003,52.72748599999994],[-132.084717,52.732208000000014],[-132.060272,52.75527200000005],[-132.01028399999996,52.775269000000094],[-132.002502,52.776939000000084],[-131.993042,52.77443699999998],[-131.973053,52.764717000000076],[-131.96389799999997,52.756660000000124],[-131.94445799999988,52.73554999999999],[-131.933624,52.728043000000014],[-131.92694099999994,52.724709000000075],[-131.91751099999988,52.72248799999994],[-131.91723599999995,52.72582200000011],[-131.93722499999996,52.76361100000008],[-131.93972799999995,52.768326000000116],[-131.95166,52.78110500000014],[-131.96221899999995,52.78860500000002],[-131.96887200000003,52.79193900000001],[-132.03417999999994,52.81276700000012],[-132.06167599999998,52.813881000000094],[-132.05804399999994,52.80416100000002],[-132.05557299999987,52.79361000000006],[-132.10247800000002,52.74943500000006],[-132.11026000000004,52.748046999999985],[-132.12026999999995,52.74887799999999],[-132.12747199999995,52.750832],[-132.2141719999999,52.804710000000114],[-132.219452,52.80832700000008],[-132.22888199999994,52.81638299999997],[-132.31640599999997,52.90221400000013],[-132.34414700000002,52.93166400000001],[-132.34695399999993,52.93637799999999],[-132.34304799999995,52.942214999999976],[-132.32971199999992,52.94582400000013],[-132.313629,52.94804399999998],[-132.25558499999994,52.954711999999915],[-132.24527,52.95388000000003],[-132.2380369999999,52.95193500000005],[-132.16778599999992,52.928047000000106],[-132.156403,52.958885000000066],[-132.11248799999998,52.987770000000125],[-132.11026000000004,52.99304999999998],[-132.11276199999992,52.997772000000055],[-132.11944599999998,53.00110600000005],[-132.25613399999997,53.028877000000136],[-132.26696799999996,53.030823000000055],[-132.29501300000004,53.03110500000008],[-132.41195700000003,53.03193700000003],[-132.47970599999996,53.027214000000015],[-132.4960939999999,53.03276800000003],[-132.50778199999996,53.040549999999996],[-132.51196300000004,53.04471600000005],[-132.55279499999995,53.08971400000013],[-132.55557299999992,53.09443699999997],[-132.563629,53.139160000000004],[-132.562225,53.14527100000009],[-132.55667099999994,53.14943699999998],[-132.5491639999999,53.1511000000001],[-132.5394589999999,53.14888000000008],[-132.52584799999994,53.142220000000066],[-132.50140399999998,53.13388100000003],[-132.48165899999998,53.13082099999997],[-132.45111099999986,53.1280440000001],[-132.41363499999989,53.127486999999974],[-132.378601,53.12943300000006],[-132.21081499999997,53.141662999999994],[-132.07083099999994,53.15387700000002],[-132.06390399999987,53.15638000000001],[-132.05777,53.15971400000001],[-132.030579,53.17999300000008],[-132.00750700000003,53.1947100000001],[-131.92834500000004,53.230545000000006],[-131.92138699999992,53.233047000000056],[-131.811127,53.25360899999998],[-131.80194099999994,53.253326000000015],[-131.794464,53.25138899999996],[-131.79055800000003,53.247214999999926],[-131.76223800000002,53.19665500000008]],[[-55.77805299999994,53.289719000000105],[-55.78666700000002,53.28833000000009],[-55.79444899999993,53.29110700000001],[-55.79722600000002,53.295547],[-55.793334999999956,53.300545],[-55.78500399999996,53.30360400000001],[-55.77610800000002,53.30027000000001],[-55.77638999999999,53.295273000000066],[-55.77805299999994,53.289719000000105]],[[-128.68945299999996,53.16443600000008],[-128.67944299999994,53.16304799999995],[-128.670837,53.163605000000075],[-128.652222,53.16276600000009],[-128.64196799999996,53.16137700000007],[-128.62469499999997,53.15554800000007],[-128.60555999999997,53.14527100000009],[-128.5761109999999,53.10527000000013],[-128.53167699999995,53.021102999999925],[-128.52890000000002,53.011108000000036],[-128.52056900000002,52.9594350000001],[-128.5183409999999,52.94360400000011],[-128.51779199999987,52.92748999999998],[-128.5183409999999,52.91110200000014],[-128.52002,52.89971900000012],[-128.5227969999999,52.88804600000009],[-128.57028199999996,52.69137600000005],[-128.57223499999992,52.68526500000013],[-128.57528699999995,52.679993000000024],[-128.59359699999993,52.65915699999999],[-128.58526599999988,52.6594310000001],[-128.57748400000003,52.65638000000007],[-128.5858149999999,52.6322100000001],[-128.59222399999993,52.6138840000001],[-128.5972289999999,52.609161000000086],[-128.60497999999995,52.60777300000001],[-128.74887099999995,52.59721400000012],[-128.75167799999997,52.60083000000003],[-128.74859600000002,52.74860400000006],[-128.74804699999999,52.754166],[-128.74444600000004,52.76082600000001],[-128.69250499999998,52.85610200000008],[-128.653351,52.8927690000001],[-128.648346,52.89777400000014],[-128.64474499999994,52.90416000000005],[-128.64334099999996,52.91554300000007],[-128.64196799999996,52.94860100000005],[-128.64334099999996,52.958885000000066],[-128.646973,52.963325999999995],[-128.653351,52.96665999999999],[-128.663635,52.96804800000007],[-128.67138699999998,52.96665999999999],[-128.67694099999994,52.962769000000094],[-128.67999299999997,52.95777100000009],[-128.751129,52.83582300000012],[-128.75390600000003,52.83082600000006],[-128.76223800000002,52.81082200000009],[-128.76446499999997,52.804710000000114],[-128.780579,52.73998999999998],[-128.78140299999995,52.73416099999997],[-128.77999899999998,52.72387700000013],[-128.777802,52.71888000000001],[-128.77111799999994,52.70471199999997],[-128.76556400000004,52.69554100000005],[-128.7788999999999,52.66415400000011],[-128.84637499999997,52.653320000000065],[-128.88446,52.64804800000013],[-128.89251699999994,52.64888000000002],[-129,52.69721200000009],[-129.032776,52.719711000000075],[-129.04779099999996,52.73137700000001],[-129.080292,52.772491000000116],[-129.108612,52.81276700000012],[-129.11080899999996,52.81749700000012],[-129.114441,52.821938000000046],[-129.11886600000003,52.83138300000013],[-129.12191799999994,52.852218999999934],[-129.12191799999994,52.863052000000096],[-129.11999500000002,52.869155999999975],[-129.11080899999996,52.87748700000003],[-129.10360699999995,52.87971500000003],[-129.09500100000002,52.880272000000105],[-129.08444199999997,52.87804399999993],[-129.0763849999999,52.87499200000002],[-129.02224699999988,52.905548000000124],[-128.95178199999992,52.97366000000005],[-128.86999499999996,53.02193500000004],[-128.85498,53.02526900000004],[-128.84082,53.02971600000012],[-128.83639499999998,53.03555300000005],[-128.843597,53.04415899999998],[-128.89556899999997,53.08277099999998],[-128.96389799999992,53.12165799999997],[-128.970551,53.124992000000134],[-129.00222799999995,53.13694000000004],[-129.011688,53.139717000000076],[-129.01583900000003,53.13388100000003],[-129.01501499999995,53.12887599999999],[-129.00473,53.10999300000009],[-128.99386599999997,53.097214000000065],[-128.98748799999998,53.09582500000005],[-128.98110999999994,53.09887700000013],[-128.97387700000002,53.10110500000013],[-128.96444699999995,53.100548],[-128.956665,53.09777100000014],[-128.912781,53.07305100000008],[-128.86444099999989,53.038887000000045],[-128.862213,53.03416400000009],[-129.05584699999997,52.90915699999994],[-129.06915299999991,52.90387700000008],[-129.09500100000002,52.902489],[-129.105835,52.90470899999997],[-129.15945399999998,52.919715999999994],[-129.16583299999996,52.92304999999999],[-129.169464,52.92748999999998],[-129.175293,52.93637799999999],[-129.18554700000004,52.955269000000044],[-129.18722499999996,52.96554600000002],[-129.191956,53.00777400000004],[-129.191376,53.01332900000011],[-129.18804899999992,53.0241620000001],[-129.16665599999993,53.06610100000006],[-129.16168200000004,53.0711060000001],[-129.154724,53.073326000000066],[-129.13165300000003,53.07804900000008],[-129.1180419999999,53.07916300000005],[-129.1174929999999,53.07388299999997],[-129.1180419999999,53.068329000000006],[-129.11499000000003,53.06471299999993],[-129.108612,53.067772000000105],[-129.08248899999995,53.089989],[-129.075287,53.10305000000011],[-129.073334,53.10916099999997],[-129.070557,53.131660000000124],[-129.05889899999988,53.23137700000012],[-129.06027199999988,53.241661000000136],[-129.064728,53.25110599999999],[-129.07193,53.25999500000006],[-129.08221400000002,53.2677690000001],[-129.08972199999994,53.287216000000114],[-129.086121,53.29361],[-129.07971199999997,53.29666100000003],[-129.06664999999992,53.30082700000008],[-129.04305999999997,53.30471],[-129.025848,53.305550000000096],[-129.018616,53.305550000000096],[-128.90084799999994,53.290276000000006],[-128.8913879999999,53.287773000000016],[-128.88137800000004,53.27999100000005],[-128.87777699999992,53.27582600000005],[-128.8638919999999,53.26361099999997],[-128.843597,53.24804700000004],[-128.83221399999996,53.24054699999999],[-128.77529900000002,53.20888500000001],[-128.71167000000003,53.17388200000005],[-128.7052609999999,53.17054699999994],[-128.68945299999996,53.16443600000008]],[[-129.15307599999994,53.09832800000004],[-129.16168200000004,53.09777100000014],[-129.25946,53.09804500000007],[-129.28945899999985,53.10193600000014],[-129.311401,53.11693600000007],[-129.3266599999999,53.128601],[-129.332489,53.13749700000011],[-129.33471699999996,53.142494],[-129.33639500000004,53.15277099999997],[-129.33889799999986,53.17916100000002],[-129.3383179999999,53.18499000000003],[-129.33639500000004,53.19110100000012],[-129.3252869999999,53.21610300000003],[-129.27389500000004,53.32804900000002],[-129.26806599999992,53.33194000000009],[-129.26028399999996,53.333327999999995],[-129.250854,53.33305400000006],[-129.22915599999988,53.32888000000003],[-129.22692899999998,53.32610299999993],[-129.208893,53.32193799999993],[-129.19415299999997,53.3155440000001],[-129.18112199999996,53.30860100000007],[-129.17611699999998,53.30471],[-129.16860999999994,53.29610400000013],[-129.14529399999998,53.22165700000005],[-129.132477,53.11859900000002],[-129.13192699999996,53.11360899999994],[-129.1339109999999,53.10749800000008],[-129.13891599999994,53.10249300000004],[-129.15307599999994,53.09832800000004]],[[-79.94276400000001,53.266936999999984],[-80.00917099999992,53.26388500000007],[-80.01806599999986,53.26583099999999],[-80.02444500000001,53.26888300000007],[-80.08167999999995,53.316101],[-80.08389299999999,53.32110600000004],[-80.08528100000001,53.32694200000009],[-80.07333399999999,53.34887700000007],[-80.06889299999995,53.35332500000004],[-80.06138599999991,53.35555300000004],[-79.99972499999996,53.364716000000044],[-79.94471699999997,53.36805000000004],[-79.95056199999993,53.34971600000006],[-79.95194999999995,53.34832799999998],[-79.91305499999999,53.29610400000013],[-79.91194200000001,53.29055000000011],[-79.91332999999992,53.283051000000114],[-79.92083699999995,53.273048000000074],[-79.92721599999999,53.27027099999998],[-79.94276400000001,53.266936999999984]],[[-129.358337,53.30416100000008],[-129.37442,53.301383999999985],[-129.38363600000002,53.30193300000013],[-129.3875119999999,53.30609900000002],[-129.43499799999995,53.378876000000105],[-129.43307500000003,53.38472000000013],[-129.39502,53.410819999999944],[-129.386414,53.40915700000005],[-129.3797,53.40554800000001],[-129.373871,53.40082600000011],[-129.3666379999999,53.39888000000008],[-129.32861300000002,53.377769],[-129.30557299999998,53.335823000000005],[-129.30334499999992,53.33110799999997],[-129.30749500000002,53.31888600000002],[-129.3124999999999,53.31388099999998],[-129.326935,53.3097150000001],[-129.358337,53.30416100000008]],[[-55.78750599999995,53.394157000000064],[-55.79305999999997,53.39166300000011],[-55.80139200000002,53.39249399999994],[-55.94943999999998,53.43027500000011],[-55.95805399999995,53.43415800000008],[-55.97166399999992,53.445824000000016],[-55.97888199999994,53.45471200000003],[-55.97916399999991,53.45916],[-55.97638699999999,53.463051000000064],[-55.95889299999993,53.472488],[-55.94554900000003,53.47860000000014],[-55.931670999999994,53.483879000000115],[-55.92388900000003,53.48554999999999],[-55.91638899999998,53.485825000000034],[-55.88305700000001,53.486382000000106],[-55.87805199999997,53.48665600000004],[-55.81194299999993,53.483879000000115],[-55.75722499999995,53.468323],[-55.740554999999915,53.46221200000008],[-55.72916399999997,53.4552690000001],[-55.72943900000001,53.450271999999984],[-55.78750599999995,53.394157000000064]],[[-128.94250499999998,53.317497],[-129.11138899999997,53.31582600000013],[-129.12222299999996,53.31805400000013],[-129.1258239999999,53.322495],[-129.13891599999994,53.33998900000012],[-129.14334099999996,53.34971600000006],[-129.14416499999993,53.35499600000014],[-129.14306599999986,53.36610400000012],[-129.14083899999997,53.37221500000004],[-129.13445999999993,53.383880999999974],[-129.08270299999998,53.42926],[-129.054062,53.45360199999999],[-129.05883799999998,53.487965000000145],[-129.051941,53.50499700000006],[-129.04779099999996,53.51055100000002],[-129.03778099999988,53.52027100000009],[-129.02194199999997,53.53388200000006],[-129.015289,53.536658999999986],[-128.99941999999987,53.53943600000008],[-128.988586,53.53721600000006],[-128.984711,53.53305100000006],[-128.98416099999997,53.52777100000003],[-128.98553499999997,53.52304800000002],[-128.98611499999998,53.51305400000001],[-128.98611499999998,53.502220000000136],[-128.9844359999999,53.49166100000008],[-128.97555499999987,53.472762999999986],[-128.95361300000002,53.44665500000002],[-128.94137599999993,53.43415800000008],[-128.93612699999994,53.43027500000011],[-128.90335099999993,53.39138000000014],[-128.90112299999998,53.38665800000007],[-128.90029900000002,53.38137800000004],[-128.91805999999997,53.33138300000002],[-128.92251599999997,53.325829],[-128.92807,53.321663000000115],[-128.94250499999998,53.317497]],[[-79.70973200000003,53.50804900000014],[-79.72027600000001,53.50749999999999],[-79.73055999999997,53.50888800000013],[-79.74694799999992,53.513329],[-79.76472499999994,53.52360500000009],[-79.76972999999992,53.52721400000013],[-79.77362099999999,53.5316620000001],[-79.77027899999996,53.536942000000124],[-79.76139799999993,53.54610400000007],[-79.75500499999998,53.54305300000004],[-79.70695499999988,53.51554900000002],[-79.70333899999991,53.51110800000009],[-79.70973200000003,53.50804900000014]],[[-129.93472299999985,53.48416100000003],[-129.9427799999999,53.48276499999997],[-129.95220899999998,53.483047000000056],[-130.01446499999997,53.50193800000005],[-130.02111799999994,53.50527200000005],[-129.98858599999988,53.52860300000009],[-129.94195599999995,53.55110200000007],[-129.93417399999998,53.55248999999998],[-129.92611699999992,53.55165899999997],[-129.8933409999999,53.545547],[-129.886688,53.5422210000001],[-129.88418599999994,53.53721600000006],[-129.88696300000004,53.534163999999976],[-129.894745,53.52193499999993],[-129.89889499999998,53.516388000000006],[-129.913635,53.50193800000005],[-129.92916899999994,53.48832700000008],[-129.93472299999985,53.48416100000003]],[[-129.8794249999999,53.39276899999999],[-129.72915599999993,53.21527100000009],[-129.73028599999992,53.20416300000011],[-129.73220799999996,53.198044000000095],[-129.74249299999997,53.178329000000076],[-129.7508539999999,53.16693900000001],[-129.75585899999993,53.16220900000002],[-129.76223799999997,53.15888200000006],[-129.864166,53.15304600000002],[-129.91223100000002,53.15638000000001],[-129.931671,53.15804300000008],[-129.93695099999997,53.161933999999974],[-130.0880429999999,53.28943600000014],[-130.11111500000004,53.32804900000002],[-130.16500899999988,53.35833000000014],[-130.20333899999997,53.378876000000105],[-130.24249299999997,53.38416300000006],[-130.261414,53.38472000000013],[-130.28695700000003,53.38137800000004],[-130.29638699999998,53.38166000000007],[-130.30584699999997,53.38416300000006],[-130.31640600000003,53.39193700000004],[-130.401947,53.47998800000005],[-130.527222,53.552216000000044],[-130.52999899999998,53.56777199999999],[-130.52944899999994,53.57332600000001],[-130.52224699999994,53.618599000000074],[-130.52029399999998,53.62470999999999],[-130.50836200000003,53.631935000000055],[-130.459991,53.637496999999996],[-130.450287,53.63499500000012],[-130.39584399999995,53.61943800000006],[-130.39111300000002,53.61693600000001],[-130.37554899999992,53.612213],[-130.27529900000002,53.580276000000026],[-130.20220900000004,53.55387899999994],[-130.14083900000003,53.52887700000002],[-129.97720300000003,53.45555099999996],[-129.94415299999991,53.438598999999954],[-129.93222000000003,53.43138099999999],[-129.92056300000002,53.42416400000002],[-129.88418599999994,53.397217000000126],[-129.8794249999999,53.39276899999999]],[[-129.08639500000004,53.44609799999995],[-129.15750099999997,53.39276899999999],[-129.16778599999998,53.59388000000013],[-129.16583299999996,53.61082500000009],[-129.16305499999999,53.62248999999997],[-129.16082799999998,53.62860100000006],[-129.15307599999994,53.638603000000046],[-129.14724699999994,53.64249400000011],[-129.14083899999997,53.645546000000024],[-129.05249000000003,53.681107],[-129.03860499999985,53.68637799999999],[-129.00805699999995,53.693321000000026],[-128.9833069999999,53.69665500000002],[-128.87554899999998,53.70943499999993],[-128.832764,53.712494000000106],[-128.82388299999997,53.71305100000001],[-128.81887800000004,53.70916000000011],[-128.821106,53.70304900000002],[-128.82360799999998,53.70054600000009],[-128.8722229999999,53.66110200000014],[-128.97970599999996,53.58387799999997],[-128.98638900000003,53.58082600000006],[-128.99221799999992,53.57694200000003],[-129.07556199999993,53.51471700000013],[-129.08554100000003,53.50499700000006],[-129.08999599999999,53.49943500000006],[-129.09359699999993,53.49276700000013],[-129.09414699999996,53.48721300000011],[-129.093323,53.48193400000014],[-129.08889799999997,53.472488],[-129.08526599999993,53.46804799999995],[-129.08306899999997,53.46332600000005],[-129.08221400000002,53.45832800000005],[-129.08276399999988,53.45249200000001],[-129.08639500000004,53.44609799999995]],[[-130.09109499999994,53.569443000000035],[-130.09832800000004,53.5669400000001],[-130.107758,53.567497],[-130.148621,53.5719380000001],[-130.21887199999992,53.587212000000136],[-130.22833299999996,53.58943199999999],[-130.32916299999994,53.61804999999998],[-130.34249899999998,53.62470999999999],[-130.39028899999988,53.66999100000004],[-130.403351,53.682495000000074],[-130.39111300000002,53.69943200000006],[-130.29888899999997,53.79694400000005],[-130.2836299999999,53.79833200000013],[-130.27194199999997,53.79777500000006],[-130.26168799999994,53.79638699999998],[-130.2466429999999,53.79027600000006],[-130.23330699999985,53.78360700000002],[-130.11944600000004,53.686653000000035],[-130.11721799999998,53.681938],[-130.09109499999994,53.569443000000035]],[[-56.86721799999998,53.76499899999993],[-56.94860799999998,53.75000000000006],[-56.98277300000001,53.75527199999999],[-57.01139099999989,53.78110500000014],[-57.01445000000001,53.78555300000011],[-57.01222200000001,53.79027600000006],[-57.00666799999999,53.79471600000011],[-57,53.79833200000013],[-56.98472600000002,53.80387900000011],[-56.96694200000002,53.80387900000011],[-56.86306000000002,53.7980500000001],[-56.84444400000001,53.792496000000085],[-56.84751899999998,53.78664400000014],[-56.86721799999998,53.76499899999993]],[[-129.8261109999999,53.724158999999986],[-129.59722899999997,53.550270000000125],[-129.51611300000002,53.48804500000006],[-129.42471299999994,53.411377000000016],[-129.43472299999996,53.40165699999994],[-129.45165999999995,53.37915800000002],[-129.45498699999996,53.37249000000003],[-129.47415199999995,53.28916200000003],[-129.47387700000002,53.23999000000009],[-129.50668299999995,53.216660000000104],[-129.56390399999998,53.2074970000001],[-129.72582999999992,53.34054600000002],[-129.800568,53.38054699999998],[-129.80721999999997,53.38416300000006],[-129.82223499999986,53.401382000000126],[-129.858337,53.45638300000007],[-129.87719699999997,53.50499700000006],[-129.87026999999995,53.51805100000013],[-129.86999500000002,53.53472100000005],[-129.87026999999995,53.545547],[-129.883911,53.57972000000001],[-129.91607699999992,53.60171500000001],[-129.9192349999999,53.60405000000014],[-129.924896,53.605545000000006],[-129.93022199999996,53.605213000000106],[-129.939728,53.603549999999984],[-129.94305399999985,53.601215000000025],[-129.94605999999987,53.59821699999998],[-129.945557,53.59521500000011],[-129.96139500000004,53.59471100000013],[-129.96554600000002,53.58915699999994],[-129.99941999999993,53.57471499999997],[-130.00750699999998,53.57332600000001],[-130.01611300000002,53.57276900000011],[-130.0269469999999,53.57471499999997],[-130.04028299999993,53.58138300000013],[-130.051666,53.59443700000003],[-130.05639599999995,53.60388200000011],[-130.05584699999991,53.60943600000007],[-130.051666,53.61527300000006],[-130.03085299999987,53.622765000000015],[-129.98288000000002,53.641605000000084],[-129.97805799999992,53.64243699999997],[-129.96240199999994,53.643436000000065],[-129.95622300000002,53.6427690000001],[-129.94955400000003,53.64143400000012],[-129.93505900000002,53.636272000000076],[-129.92938199999998,53.634765999999956],[-129.926895,53.636772000000065],[-129.92820699999993,53.639602999999966],[-129.93440199999992,53.644268000000125],[-129.94956999999994,53.646805000000086],[-129.95996100000002,53.64950199999993],[-129.96726999999993,53.65029900000002],[-129.98693799999995,53.65860000000009],[-130.01889,53.653046000000074],[-130.091949,53.6772160000001],[-130.156952,53.72137500000002],[-130.283905,53.83277099999998],[-130.286407,53.83749399999999],[-130.27917499999995,53.856384000000105],[-130.27029400000004,53.87554900000009],[-130.266418,53.8813780000001],[-130.25472999999994,53.88916000000006],[-130.20166,53.9124910000001],[-130.19445799999994,53.914711000000125],[-130.186401,53.916100000000085],[-130.10916099999992,53.88555100000002],[-129.96444699999995,53.80582400000009],[-129.83139,53.728043000000014],[-129.8261109999999,53.724158999999986]],[[-79.86416600000001,53.90638000000001],[-79.87388599999991,53.90415999999999],[-79.906113,53.91387900000001],[-79.91888399999999,53.920273000000066],[-79.922775,53.924713000000054],[-79.92527799999988,53.92971799999992],[-79.92639200000002,53.93526500000007],[-79.915009,53.933876000000055],[-79.86749299999997,53.919715999999994],[-79.862213,53.9158250000001],[-79.86000100000001,53.91082000000006],[-79.86416600000001,53.90638000000001]],[[-130.14974999999998,53.989159000000086],[-130.16805999999997,53.9888840000001],[-130.179169,53.990829000000076],[-130.19415300000003,53.99721499999998],[-130.20306400000004,54.005271999999934],[-130.21499600000004,54.029160000000104],[-130.21694899999994,54.03943600000014],[-130.21640000000002,54.04499800000008],[-130.21304299999997,54.05165900000003],[-130.20278899999994,54.06916000000001],[-130.193604,54.07972000000012],[-130.186401,54.081940000000145],[-130.17834500000004,54.08332800000005],[-130.16861,54.08305400000012],[-130.15917999999994,54.08055100000013],[-130.155579,54.07555400000001],[-130.14889500000004,54.072220000000016],[-130.14361599999995,54.06832899999995],[-130.13973999999996,54.064156000000025],[-130.132477,54.049995000000024],[-130.12249799999995,54.02499399999999],[-130.1213679999999,54.01998900000012],[-130.12249799999995,54.0086060000001],[-130.12442,54.00249500000007],[-130.13528399999996,53.993607000000054],[-130.14974999999998,53.989159000000086]],[[-130.25918599999994,54.00471500000003],[-130.237213,53.984161000000086],[-130.23330699999985,53.979987999999935],[-130.23083499999996,53.97526600000003],[-130.228882,53.96471400000007],[-130.22998,53.95360600000009],[-130.23330699999985,53.9469380000001],[-130.24249299999997,53.93637799999999],[-130.338593,53.839157000000114],[-130.344452,53.83526600000005],[-130.35220299999997,53.83387800000014],[-130.37860099999995,53.831939999999975],[-130.38723800000002,53.83138300000007],[-130.45016499999997,53.864326000000005],[-130.45433000000003,53.86632500000002],[-130.45849599999997,53.88215999999994],[-130.41278099999994,53.95860299999998],[-130.407776,53.963325999999995],[-130.400848,53.965828000000045],[-130.38165300000003,53.96527100000014],[-130.35055499999993,53.96166199999993],[-130.341095,53.96138000000008],[-130.3330689999999,53.962769000000094],[-130.32748400000003,53.966934000000094],[-130.34359699999987,53.98499300000003],[-130.35497999999995,53.99332400000009],[-130.42944299999994,53.98304700000011],[-130.4375,53.981659000000036],[-130.44387800000004,53.97860000000003],[-130.452789,53.96804800000007],[-130.47517400000004,53.94421399999993],[-130.47550999999993,53.940712000000076],[-130.47917199999995,53.926379999999995],[-130.48266599999988,53.915379000000144],[-130.48516799999993,53.91204800000003],[-130.4895019999999,53.910549],[-130.494659,53.910217000000046],[-130.500854,53.91088100000013],[-130.524338,53.914711000000125],[-130.54724099999999,53.90387700000002],[-130.55248999999998,53.90776799999992],[-130.55639599999995,53.91193400000003],[-130.56527699999998,53.92582700000003],[-130.57748400000003,53.93721000000005],[-130.591949,53.949158000000125],[-130.59722899999997,53.953048999999965],[-130.60278299999993,53.956657000000064],[-130.61080900000002,53.959717000000126],[-130.621918,53.96166199999993],[-130.6580509999999,53.96443900000003],[-130.666962,53.963882000000126],[-130.67251599999997,53.95999100000006],[-130.676666,53.954162999999994],[-130.69528200000002,53.91944100000012],[-130.698059,53.91415400000005],[-130.695557,53.90943100000004],[-130.6849979999999,53.901932000000045],[-130.66305499999993,53.89222000000012],[-130.64666699999998,53.886657999999954],[-130.633331,53.87999000000002],[-130.62777700000004,53.876099000000124],[-130.62249799999995,53.8722150000001],[-130.6177669999999,53.86277000000001],[-130.61804199999995,53.85721600000005],[-130.62136799999996,53.85054800000006],[-130.62554899999998,53.844711000000075],[-130.6305539999999,53.839989],[-130.64251699999994,53.83277099999998],[-130.65139799999997,53.83443500000004],[-130.69583099999994,53.84443699999997],[-130.70639,53.85193600000014],[-130.710266,53.856384000000105],[-130.71276899999998,53.86110700000012],[-130.723053,53.917213000000004],[-130.72277799999995,53.922768000000076],[-130.7202759999999,53.93471500000004],[-130.7177729999999,53.939986999999974],[-130.667236,53.98693800000001],[-130.66168200000004,53.990829000000076],[-130.595276,54.02638200000007],[-130.523346,54.059989999999914],[-130.411133,54.10083000000009],[-130.40249600000004,54.10138699999999],[-130.37081899999998,54.08721200000008],[-130.336121,54.06749700000006],[-130.3049929999999,54.04527300000012],[-130.25918599999994,54.00471500000003]],[[-58.51833299999993,54.05165900000003],[-58.52666499999992,54.05054500000006],[-58.536666999999966,54.05082700000014],[-58.54555499999998,54.0522160000001],[-58.556389000000024,54.05471000000006],[-58.56138599999997,54.05804400000005],[-58.56138599999997,54.06388099999998],[-58.55777699999993,54.06916000000001],[-58.55277999999993,54.07444000000004],[-58.53556100000003,54.08665499999995],[-58.50305899999995,54.10305000000005],[-58.468605000000025,54.114716000000044],[-58.45055400000001,54.11721],[-58.43777499999999,54.11554700000005],[-58.378608999999926,54.10665900000009],[-58.373885999999914,54.10416400000008],[-58.378052000000025,54.09999800000014],[-58.40717299999994,54.09056100000004],[-58.426109,54.070831000000055],[-58.43250299999994,54.067214999999976],[-58.44055199999997,54.0647130000001],[-58.45639,54.061661000000015],[-58.51833299999993,54.05165900000003]],[[-132.808044,54.12027000000006],[-132.78891,54.119987000000094],[-132.77999899999998,54.12082700000013],[-132.75723300000004,54.126380999999924],[-132.73580899999996,54.13388100000003],[-132.70306399999993,54.139160000000004],[-132.65835600000003,54.142220000000066],[-132.6480709999999,54.14138000000003],[-132.63946499999997,54.1386030000001],[-132.57528699999995,54.11554700000005],[-132.56973300000004,54.111938000000066],[-132.55777,54.088043000000084],[-132.558899,54.04833200000007],[-132.56054699999999,54.04222100000004],[-132.56664999999992,54.029160000000104],[-132.57583599999998,54.01915700000001],[-132.58139,54.0149990000001],[-132.59387199999998,54.0086060000001],[-132.62554899999992,54.00222000000002],[-132.63275099999993,53.99971800000014],[-132.66418499999997,53.98333000000008],[-132.67999299999997,53.958885000000066],[-132.681671,53.95277399999998],[-132.680298,53.94776900000011],[-132.6589049999999,53.93943000000007],[-132.57223499999992,53.976653999999996],[-132.55584699999997,53.989159000000086],[-132.55029299999995,53.99388099999999],[-132.5477909999999,53.99916100000007],[-132.54888899999997,54.00416600000011],[-132.55307,54.00833100000011],[-132.54833999999994,54.02693899999997],[-132.54528800000003,54.03360700000013],[-132.54055799999998,54.03832999999997],[-132.416656,54.096100000000035],[-132.40972899999997,54.098602000000085],[-132.40167199999985,54.09999800000014],[-132.30111699999998,54.11166400000013],[-132.29055800000003,54.11054999999999],[-132.28582799999998,54.107773000000066],[-132.25280799999996,54.08526599999999],[-132.22833300000002,54.065826000000015],[-132.15029899999996,53.992767000000015],[-132.142517,53.97860000000003],[-132.11111499999998,53.878326000000015],[-132.11721799999992,53.864998000000014],[-132.125,53.853324999999984],[-132.13445999999988,53.84360500000008],[-132.225006,53.78027300000002],[-132.23111,53.77693900000003],[-132.24527,53.772217000000126],[-132.474426,53.70749699999999],[-132.50500499999998,53.70027199999993],[-132.52084399999995,53.69721200000009],[-132.53805499999999,53.69582399999996],[-132.55721999999997,53.69582399999996],[-132.56832899999995,53.697768999999994],[-132.58889799999992,53.699715000000026],[-132.6069339999999,53.69887499999999],[-132.62441999999993,53.69748700000008],[-132.64724699999994,53.69193300000012],[-132.6589049999999,53.68443300000001],[-132.66332999999997,53.67943600000012],[-132.665009,53.673325000000034],[-132.46362299999993,53.61277000000007],[-132.41805999999997,53.60610200000008],[-132.32138099999992,53.66360500000013],[-132.31527699999998,53.66693900000013],[-132.308044,53.66915899999992],[-132.29943799999995,53.66999100000004],[-132.290009,53.66971600000005],[-132.27890000000002,53.6680530000001],[-132.24554399999994,53.66249099999999],[-132.156403,53.716385],[-132.15249600000004,53.81249200000008],[-132.08450299999998,53.87273800000003],[-132.106201,53.91788100000002],[-132.126373,53.979431000000034],[-132.07250999999997,54.02276600000005],[-132.0150149999999,54.02193500000004],[-131.98803699999996,54.023048000000074],[-131.97109999999998,54.02526900000004],[-131.87499999999994,54.052773],[-131.86053500000003,54.057495000000074],[-131.81777999999997,54.07193799999999],[-131.75473,54.094993999999986],[-131.727783,54.10610200000002],[-131.71499599999999,54.11249500000014],[-131.70361299999996,54.120543999999995],[-131.67193599999996,54.146660000000054],[-131.66305499999999,54.15221400000007],[-131.66000399999996,54.13110400000011],[-131.666656,54.079436999999984],[-131.67279099999996,54.04415899999998],[-131.67971799999998,54.019714000000135],[-131.70498699999996,53.966934000000094],[-131.720825,53.94387800000004],[-131.73889199999996,53.92332499999998],[-131.78640699999994,53.87443500000012],[-131.79666099999997,53.865273],[-131.82971199999992,53.841102999999976],[-131.85333300000002,53.81638299999997],[-131.86886600000003,53.79332700000009],[-131.87222299999996,53.78694200000007],[-131.93331899999998,53.61527300000006],[-131.934998,53.609161000000086],[-131.94000199999988,53.51971400000002],[-131.9391779999999,53.50888800000013],[-131.91778599999998,53.3991620000001],[-131.90863000000002,53.35749800000002],[-131.95916699999992,53.27638200000007],[-131.96832299999988,53.26638800000006],[-131.98220799999996,53.25166300000012],[-131.988586,53.248604000000114],[-132.00585899999993,53.247214999999926],[-132.036407,53.25],[-132.0561219999999,53.253326000000015],[-132.08331299999992,53.25305200000008],[-132.17138699999998,53.23832700000014],[-132.19500700000003,53.233879],[-132.21054100000003,53.230545000000006],[-132.21749899999998,53.228324999999984],[-132.27279699999997,53.21027400000003],[-132.27029399999998,53.205551000000014],[-132.26611300000002,53.20138500000013],[-132.25558499999994,53.193877999999984],[-132.23776199999998,53.188881000000094],[-132.22997999999995,53.190544000000045],[-132.21581999999995,53.195267],[-132.20361299999996,53.20165999999995],[-132.19415299999991,53.20165999999995],[-132.14502,53.19832599999995],[-132.133911,53.19665500000008],[-132.12441999999987,53.19415300000003],[-132.121918,53.189430000000016],[-132.158905,53.16999099999998],[-132.18695099999997,53.16054500000001],[-132.19473300000004,53.15888200000006],[-132.390289,53.142769000000044],[-132.40835599999997,53.142220000000066],[-132.4466549999999,53.14360799999997],[-132.457489,53.14527100000009],[-132.506958,53.161102000000085],[-132.53668199999998,53.17887900000011],[-132.56527700000004,53.21276900000004],[-132.57638499999996,53.23220800000013],[-132.58581500000003,53.24027300000006],[-132.59664899999996,53.24748999999997],[-132.61471599999993,53.252777000000094],[-132.64529399999992,53.25555399999996],[-132.664734,53.25638600000008],[-132.683624,53.25666000000001],[-132.675842,53.281661999999926],[-132.61944599999998,53.30027000000001],[-132.552216,53.308043999999995],[-132.54446399999995,53.30943300000001],[-132.539734,53.31443800000005],[-132.53695700000003,53.32110600000004],[-132.53918499999997,53.326385000000016],[-132.54333499999996,53.33055100000007],[-132.54998799999987,53.33387800000003],[-132.55835000000002,53.33665500000012],[-132.568604,53.337494000000106],[-132.67001300000004,53.32694200000009],[-132.72000100000002,53.320831],[-132.73388699999998,53.33721200000002],[-132.709991,53.370270000000005],[-132.70443699999993,53.374435000000005],[-132.6975099999999,53.376937999999996],[-132.52076699999998,53.340160000000026],[-132.51744099999996,53.337990000000104],[-132.41641200000004,53.2972180000001],[-132.41055299999994,53.294715999999994],[-132.406677,53.300545],[-132.40362500000003,53.30721299999999],[-132.40057399999995,53.31944300000009],[-132.40029900000002,53.330826000000116],[-132.402802,53.33554800000002],[-132.406677,53.33971400000007],[-132.41223099999996,53.34360499999997],[-132.52084399999995,53.41220900000013],[-132.54138199999994,53.41638200000011],[-132.73580899999996,53.45332300000001],[-132.857758,53.461104999999975],[-132.86749299999997,53.463608000000136],[-132.87277199999988,53.467209000000025],[-132.97250399999996,53.55582400000014],[-132.991669,53.583054000000004],[-132.9941409999999,53.58776900000004],[-132.9888919999999,53.59193400000004],[-132.96139500000004,53.60027300000007],[-132.95361300000002,53.60193600000002],[-132.94415300000003,53.60193600000002],[-132.93444799999986,53.599716],[-132.91805999999997,53.58860000000004],[-132.90972899999997,53.585823000000005],[-132.898621,53.584160000000054],[-132.89083900000003,53.58554800000013],[-132.88446,53.588882000000126],[-132.880829,53.59471100000013],[-132.8805539999999,53.60027300000007],[-132.88192700000002,53.605552999999986],[-132.8861389999999,53.60971799999999],[-132.92028800000003,53.63721499999991],[-132.935272,53.648604999999975],[-132.950562,53.654709000000025],[-133.00778200000002,53.676383999999985],[-132.95361300000002,53.68277000000012],[-132.95443699999998,53.70277400000003],[-132.9844359999999,53.74276700000007],[-133.02471899999995,53.751389000000074],[-133.03362999999996,53.75277699999998],[-133.09387200000003,53.77555100000012],[-133.10082999999997,53.77860300000003],[-133.10638399999993,53.7824940000001],[-133.10916099999997,53.78694200000007],[-133.13751199999996,53.87499200000002],[-133.13891599999994,53.88027200000005],[-133.140015,53.908043000000134],[-133.13833599999992,53.91415400000005],[-133.133911,53.91915900000009],[-133.11639399999996,53.93415800000014],[-133.09527599999996,53.94943200000006],[-133.09081999999995,53.954162999999994],[-133.041107,54.03166199999998],[-133.039734,54.03777300000007],[-133.04083299999996,54.0430530000001],[-133.05862399999995,54.07610299999999],[-133.079163,54.09777100000008],[-133.08193999999992,54.10249299999998],[-133.07165499999996,54.16888399999999],[-133.06722999999988,54.17388199999999],[-133.04083299999996,54.176102000000014],[-133.0311279999999,54.176102000000014],[-132.94027700000004,54.16137700000007],[-132.93029799999994,54.15915700000005],[-132.92001299999993,54.15248900000006],[-132.90335099999993,54.13582600000001],[-132.82748400000003,54.122490000000084],[-132.808044,54.12027000000006]],[[-130.19555699999995,54.11805000000004],[-130.21166999999997,54.115273000000116],[-130.22109999999998,54.11554700000005],[-130.23220799999996,54.11749300000014],[-130.24581899999993,54.12416100000013],[-130.251129,54.128044000000045],[-130.25500499999998,54.132209999999986],[-130.261414,54.14138000000003],[-130.26364099999995,54.14610299999998],[-130.26473999999996,54.151381999999955],[-130.26306199999993,54.16832700000009],[-130.2611389999999,54.174164000000076],[-130.25778199999996,54.18082400000009],[-130.2528079999999,54.1855470000001],[-130.239716,54.18971299999998],[-130.23083499999996,54.190269],[-130.20944199999985,54.18720999999999],[-130.2099909999999,54.18360100000001],[-130.20166,54.18305200000003],[-130.19223,54.18054999999998],[-130.17861900000003,54.173607000000004],[-130.161133,54.16276600000009],[-130.15585299999992,54.15888200000006],[-130.15194699999995,54.154434000000094],[-130.15112299999998,54.14943699999998],[-130.153076,54.14332600000006],[-130.158051,54.138329],[-130.169464,54.130547000000035],[-130.19555699999995,54.11805000000004]],[[-79.46972700000003,54.167496000000085],[-79.47721899999988,54.16582500000004],[-79.483612,54.169159000000036],[-79.48500100000001,54.174713],[-79.48110999999994,54.18749200000008],[-79.47555499999993,54.191376000000105],[-79.43472300000002,54.20027200000004],[-79.41305499999999,54.19165799999996],[-79.41861,54.18720999999999],[-79.42639200000002,54.18305200000003],[-79.46972700000003,54.167496000000085]],[[-130.648621,54.114441000000056],[-130.67138699999992,54.107773000000066],[-130.69055199999997,54.10833000000014],[-130.69888299999997,54.11110700000006],[-130.77417000000003,54.142220000000066],[-130.78500399999996,54.14999400000005],[-130.798065,54.16220899999996],[-130.800568,54.16693900000001],[-130.79861500000004,54.1730500000001],[-130.78167699999995,54.2116620000001],[-130.77444500000001,54.21388200000007],[-130.763916,54.21276900000004],[-130.75613399999992,54.20916],[-130.74636799999996,54.206657000000064],[-130.72582999999997,54.19665500000008],[-130.64889500000004,54.14971900000006],[-130.64501999999993,54.14527100000009],[-130.640015,54.13582600000001],[-130.63919099999993,54.13082099999997],[-130.63946499999997,54.124992000000134],[-130.642792,54.11859900000002],[-130.648621,54.114441000000056]],[[-130.3555599999999,54.25777399999998],[-130.3666379999999,54.24110400000001],[-130.375,54.244155999999975],[-130.38861099999997,54.25083200000006],[-130.400574,54.25804899999997],[-130.45556599999998,54.29583000000014],[-130.46639999999996,54.303322000000094],[-130.46722399999993,54.30860100000007],[-130.4475099999999,54.325829],[-130.440002,54.32804900000002],[-130.43112199999996,54.32860600000009],[-130.41778599999992,54.326385000000016],[-130.39196799999996,54.312492000000134],[-130.385284,54.308884000000035],[-130.37997399999995,54.30526700000007],[-130.37582399999997,54.30082700000008],[-130.35470599999996,54.26915700000001],[-130.35220299999997,54.264442000000145],[-130.3555599999999,54.25777399999998]],[[-130.266418,54.26055100000008],[-130.32528699999995,54.243050000000096],[-130.33416699999998,54.24471300000005],[-130.33804299999997,54.24887800000005],[-130.355255,54.282211000000075],[-130.354156,54.29332699999998],[-130.350281,54.30555000000004],[-130.344452,54.30971500000004],[-130.29000899999994,54.33221400000002],[-130.2727969999999,54.329720000000066],[-130.26751699999994,54.325829],[-130.25973499999998,54.317497],[-130.252502,54.30304700000005],[-130.25058,54.292770000000075],[-130.2516779999999,54.28138000000001],[-130.255585,54.269440000000145],[-130.25973499999998,54.26361099999991],[-130.266418,54.26055100000008]],[[-130.70416299999994,54.356659000000036],[-130.745544,54.35471300000012],[-130.754456,54.356102000000135],[-130.763916,54.364159000000086],[-130.767242,54.37416100000007],[-130.7683409999999,54.379433000000006],[-130.76779199999987,54.38499500000012],[-130.76446499999992,54.38943499999999],[-130.75805699999995,54.39249400000011],[-130.72943099999986,54.40277100000009],[-130.7222289999999,54.40499100000011],[-130.71417199999996,54.40638000000013],[-130.699432,54.40665400000006],[-130.68890399999998,54.39332600000006],[-130.68331899999998,54.3730470000001],[-130.685272,54.36693600000001],[-130.6894529999999,54.36138199999999],[-130.696106,54.35804700000011],[-130.70416299999994,54.356659000000036]],[[-57.32472199999995,54.49887799999999],[-57.34249899999992,54.49860400000006],[-57.35166899999996,54.5002750000001],[-57.35666699999996,54.50222000000008],[-57.36277799999999,54.50610400000011],[-57.365005,54.511664999999994],[-57.36555499999997,54.51638799999995],[-57.36250299999995,54.52748900000012],[-57.359443999999996,54.533332999999914],[-57.333327999999995,54.56554399999999],[-57.32778200000001,54.57083100000011],[-57.32111400000002,54.57499700000005],[-57.26722000000001,54.58554800000013],[-57.265556000000004,54.580551000000014],[-57.269722,54.57499700000005],[-57.27272800000003,54.57249500000012],[-57.239441,54.52221700000001],[-57.240279999999984,54.517769000000044],[-57.255004999999926,54.513329],[-57.29305999999991,54.5036090000001],[-57.30777699999999,54.500549000000035],[-57.32472199999995,54.49887799999999]],[[-130.95166,54.45471199999997],[-130.95944199999997,54.45332300000001],[-130.96499600000004,54.456940000000145],[-130.96749899999992,54.46166200000005],[-130.96609499999994,54.51082600000001],[-130.96472199999994,54.52777100000014],[-130.961121,54.53999299999998],[-130.93057299999998,54.61471599999993],[-130.92556799999994,54.61943800000006],[-130.88891599999994,54.62887600000005],[-130.88137800000004,54.62915800000013],[-130.754456,54.62943300000012],[-130.74777199999994,54.626099000000124],[-130.74664299999995,54.62082700000002],[-130.74694799999997,54.61527300000006],[-130.7441409999999,54.60166200000009],[-130.745544,54.584717000000126],[-130.74914599999994,54.57276900000005],[-130.752502,54.56610100000012],[-130.75613399999992,54.559433000000126],[-130.760834,54.554710000000114],[-130.766663,54.55054500000011],[-130.84915199999995,54.496941000000106],[-130.855835,54.493881000000044],[-130.93695099999997,54.459434999999985],[-130.95166,54.45471199999997]],[[-79.66722099999993,54.76388500000013],[-79.726944,54.75249500000007],[-79.71028100000001,54.76388500000013],[-79.70361300000002,54.76693700000004],[-79.61111499999998,54.79332700000009],[-79.58721899999995,54.79916400000002],[-79.624435,54.77971600000012],[-79.631104,54.776657000000114],[-79.63778699999995,54.77360500000003],[-79.65972899999991,54.766106000000036],[-79.66722099999993,54.76388500000013]],[[-130.2683409999999,54.714995999999985],[-130.370544,54.692214999999976],[-130.37887599999988,54.69526700000006],[-130.37609899999995,54.70054600000003],[-130.3710939999999,54.705269000000044],[-130.326935,54.739716000000044],[-130.32110599999987,54.743881000000044],[-130.2241519999999,54.80304699999999],[-130.21749899999998,54.80638099999999],[-130.20944199999985,54.80777000000012],[-130.20694000000003,54.80304699999999],[-130.19860800000004,54.78360700000002],[-130.200562,54.77748900000006],[-130.20971699999996,54.760551000000135],[-130.21362299999993,54.74832900000001],[-130.217224,54.74166100000002],[-130.22222899999986,54.73693800000001],[-130.23388699999998,54.72887400000002],[-130.2611389999999,54.71720900000014],[-130.2683409999999,54.714995999999985]],[[-130.51834099999996,54.70249200000012],[-130.527222,54.70193500000005],[-130.5386049999999,54.70388000000003],[-130.56750499999993,54.716934000000094],[-130.57443199999994,54.72026800000009],[-130.585266,54.72776799999997],[-130.60803199999992,54.74832900000001],[-130.6105349999999,54.75305200000014],[-130.61166399999996,54.758049000000085],[-130.60665900000004,54.763054000000125],[-130.4880369999999,54.80749500000013],[-130.47998,54.80888399999992],[-130.469452,54.80777000000012],[-130.458618,54.80027000000007],[-130.44665499999996,54.787216],[-130.44027699999992,54.77832799999999],[-130.43777499999993,54.77360500000003],[-130.43582199999997,54.76332900000011],[-130.4397279999999,54.75110600000005],[-130.4538879999999,54.71915400000012],[-130.457489,54.712769000000094],[-130.46331799999996,54.70860300000004],[-130.51834099999996,54.70249200000012]],[[-57.94083399999994,54.911933999999974],[-57.985832000000016,54.87082699999996],[-57.98860899999994,54.86721],[-57.991942999999935,54.833878000000084],[-57.98388699999987,54.80221599999999],[-57.98027799999994,54.79860700000012],[-57.971663999999976,54.798050000000046],[-57.965553,54.79943799999995],[-57.95889299999999,54.80304699999999],[-57.955558999999994,54.80582400000009],[-57.923888999999974,54.82332600000012],[-57.871666000000005,54.83166499999993],[-57.864723000000026,54.83221400000008],[-57.85972600000002,54.83027600000014],[-57.843613000000005,54.82054900000003],[-57.841110000000015,54.81693999999999],[-57.84166700000003,54.81249200000002],[-57.84833499999996,54.80693800000006],[-57.875,54.79332700000009],[-57.88194299999992,54.790549999999996],[-58.02277400000003,54.75555400000002],[-58.031386999999995,54.75388299999997],[-58.04000099999996,54.75277699999998],[-58.04999499999991,54.75305200000014],[-58.11999500000002,54.75555400000002],[-58.13916799999993,54.75721699999997],[-58.15943900000002,54.76138300000008],[-58.174171,54.76776899999999],[-58.17694899999998,54.77082800000011],[-58.17237899999998,54.797314000000085],[-58.184173999999985,54.80847199999994],[-58.21971899999994,54.825829000000056],[-58.22277100000002,54.83027600000014],[-58.224715999999944,54.83526599999999],[-58.225554999999986,54.850273000000016],[-58.225554999999986,54.86277000000001],[-58.22499800000003,54.86693600000007],[-58.21888699999994,54.87526700000001],[-58.215836000000024,54.8780440000001],[-58.20972399999994,54.87748700000003],[-58.04944599999993,54.893326000000116],[-57.96777300000002,54.919159000000036],[-57.94277199999999,54.92499500000014],[-57.94027699999998,54.923607000000004],[-57.93860599999999,54.918602000000135],[-57.94083399999994,54.911933999999974]],[[-79.12582399999991,54.89721700000001],[-79.13444500000003,54.895827999999995],[-79.23500099999995,54.89666000000011],[-79.51528899999994,54.840546000000074],[-79.66027799999995,54.805549999999926],[-79.76362599999999,54.771660000000054],[-79.77417000000003,54.77304800000013],[-79.776947,54.77804600000013],[-79.77333099999998,54.783333000000084],[-79.76888999999994,54.78777300000007],[-79.72555499999999,54.81888600000008],[-79.714722,54.82638500000007],[-79.68693499999995,54.83832600000005],[-79.65666199999998,54.84665699999999],[-79.46722399999993,54.888329],[-79.45861799999994,54.88999200000012],[-79.43055700000002,54.892769000000044],[-79.41944899999987,54.892769000000044],[-79.3394469999999,54.89694199999997],[-79.16416900000002,54.92555200000004],[-79.053879,54.94665500000008],[-79.04194599999988,54.94582400000007],[-79.01501499999995,54.93832400000002],[-79.01501499999995,54.932213000000104],[-79.027222,54.925270000000125],[-79.05749499999996,54.917770000000075],[-79.10278299999999,54.90387700000002],[-79.12582399999991,54.89721700000001]],[[-58.67527799999999,54.914153999999996],[-58.68360899999999,54.913048],[-58.75250199999999,54.91582500000004],[-58.757225000000005,54.916100000000085],[-58.76055899999989,54.92054699999994],[-58.75917099999998,54.92610200000007],[-58.75472300000001,54.93249500000002],[-58.70166799999993,54.999161000000015],[-58.697495,55.003326000000015],[-58.69110899999998,55.00694299999998],[-58.684722999999906,55.008331000000055],[-58.67639199999991,55.00943799999999],[-58.66027799999995,55.0086060000001],[-58.6536099999999,55.00555400000002],[-58.65277899999995,55.00110600000005],[-58.65750099999997,54.99610099999995],[-58.6627729999999,54.99221800000004],[-58.65833299999997,54.96249400000005],[-58.65666199999998,54.94221500000009],[-58.65860700000002,54.93249500000002],[-58.663054999999986,54.92249300000003],[-58.66889200000003,54.917770000000075],[-58.67527799999999,54.914153999999996]],[[-130.385284,54.76998899999995],[-130.39916999999997,54.76471700000002],[-130.40918,54.767212000000086],[-130.41445899999997,54.77082800000011],[-130.45556599999998,54.81332400000014],[-130.45944199999997,54.81749700000006],[-130.46194499999996,54.82222000000007],[-130.459991,54.82833099999999],[-130.41833499999996,54.85332499999993],[-130.385284,54.8688810000001],[-130.343048,54.89499699999999],[-130.27029400000004,54.95027200000004],[-130.25,54.96971100000013],[-130.22778299999993,54.99721499999998],[-130.2133179999999,55.012496999999996],[-130.20083599999992,55.01971400000008],[-130.184998,55.02332300000012],[-130.175293,55.023048000000074],[-130.168335,55.01971400000008],[-130.16500899999988,55.01416000000012],[-130.16027799999995,55.00443999999999],[-130.146973,54.97582200000005],[-130.14529399999998,54.96527100000014],[-130.14556899999997,54.959717000000126],[-130.14611799999994,54.95416300000011],[-130.14974999999998,54.947487000000024],[-130.16332999999997,54.931381000000044],[-130.27029400000004,54.830826],[-130.385284,54.76998899999995]],[[-82.964722,55.26361100000008],[-82.97000099999997,55.259720000000016],[-83.01445000000001,55.26971400000002],[-83.03195199999988,55.27388000000013],[-83.035278,55.27887700000002],[-83.02749599999993,55.28138000000001],[-83.016953,55.2816620000001],[-82.99027999999998,55.280548000000124],[-82.98083500000001,55.27887700000002],[-82.96333299999998,55.27388000000013],[-82.96166999999997,55.26915700000012],[-82.964722,55.26361100000008]],[[-77.59277299999991,55.43526500000013],[-77.633331,55.42443800000012],[-77.64416499999987,55.42582700000008],[-77.44943199999994,55.53388200000006],[-77.33612099999999,55.60443900000013],[-77.32305899999994,55.610550000000046],[-77.22138999999993,55.65360299999992],[-77.21389799999992,55.65526600000004],[-77.20527600000003,55.65387700000008],[-77.19999699999994,55.65026899999998],[-77.20111099999991,55.64415699999995],[-77.210556,55.63971700000013],[-77.25222799999995,55.618050000000096],[-77.38917499999997,55.54638699999998],[-77.45222499999994,55.5127720000001],[-77.47416699999997,55.49804699999993],[-77.48416099999992,55.48915899999997],[-77.49499499999996,55.48137700000001],[-77.50056499999994,55.4783250000001],[-77.55221599999993,55.45304900000002],[-77.59277299999991,55.43526500000013]],[[-60.970832999999914,55.869437999999946],[-60.98833499999995,55.86721],[-60.99833699999999,55.86776700000007],[-61.008895999999936,55.86915600000009],[-61.016944999999964,55.873046999999985],[-61.05166600000001,55.9011000000001],[-61.05666400000001,55.905823000000055],[-61.05916599999995,55.909988000000055],[-61.07055700000001,55.93859900000001],[-61.06555199999997,55.94415300000003],[-61.04778299999998,55.945541000000105],[-61.03694899999999,55.9447100000001],[-60.96805599999999,55.93665299999992],[-60.94860799999998,55.93054999999998],[-60.90833299999997,55.898330999999985],[-60.906386999999995,55.893326000000116],[-60.91110999999995,55.8877720000001],[-60.91750300000001,55.884163000000115],[-60.970832999999914,55.869437999999946]],[[-60.858611999999994,55.864716000000044],[-60.87610599999999,55.863883999999985],[-60.89250199999998,55.864441000000056],[-60.898612999999955,55.86721],[-60.902221999999995,55.87137600000011],[-60.90055100000001,55.87638099999998],[-60.87361099999987,55.94360400000005],[-60.86999500000002,55.949432],[-60.86500499999994,55.95277400000009],[-60.851944,55.95526899999993],[-60.748336999999935,55.94415300000003],[-60.74138599999992,55.94276400000001],[-60.74250000000001,55.93915600000008],[-60.74749800000001,55.931663999999955],[-60.691939999999875,55.925270000000125],[-60.68638599999997,55.92193600000013],[-60.68804899999998,55.91721300000012],[-60.69277199999999,55.911658999999986],[-60.70500199999998,55.90304600000002],[-60.71860499999991,55.896385000000066],[-60.756393,55.88027200000005],[-60.778610000000015,55.87609900000007],[-60.840836000000024,55.86610399999995],[-60.858611999999994,55.864716000000044]],[[-79.12304699999993,55.78999300000004],[-79.13055399999996,55.788887000000045],[-79.135559,55.78916200000003],[-79.13778699999995,55.79054999999994],[-79.13612399999994,55.79415899999998],[-79.13166799999993,55.799995000000024],[-79.12609900000001,55.80387900000005],[-79.12193299999996,55.808601000000124],[-79.10888699999992,55.82388300000014],[-79.10278299999999,55.83305400000012],[-79.03916899999996,55.95249200000006],[-79.03083799999996,55.96859699999993],[-79.027222,55.97693599999997],[-79.02223200000003,55.99638400000009],[-79.00935399999997,56.063614000000086],[-78.96000700000002,56.08305400000006],[-78.95750399999997,56.08360299999998],[-78.95278899999994,56.080826000000116],[-78.9491579999999,56.071663000000115],[-78.93971299999998,56.02526899999998],[-79.05444299999994,55.86554700000005],[-79.08999599999999,55.81693999999999],[-79.104446,55.80082700000014],[-79.11665299999999,55.79249600000003],[-79.12304699999993,55.78999300000004]],[[-60.943329000000006,56.00666000000001],[-61.040557999999976,56.005272000000105],[-61.0819469999999,56.01138299999997],[-61.14138799999995,56.02054599999997],[-61.17111199999988,56.028602999999976],[-61.18721800000003,56.03388200000012],[-61.215836000000024,56.04638700000004],[-61.22083299999997,56.05082700000008],[-61.22833300000002,56.06332400000008],[-61.23277299999995,56.07276900000011],[-61.233611999999994,56.08554800000002],[-61.23277299999995,56.09110300000009],[-61.226944,56.09804500000001],[-61.217498999999975,56.10054799999995],[-61.21167000000003,56.1013870000001],[-61.08916499999998,56.169991000000095],[-61.05916599999995,56.15971400000012],[-61.04583699999989,56.153877000000136],[-60.94444299999998,56.094993999999986],[-60.943610999999976,56.09027100000014],[-60.93444099999999,56.015830999999935],[-60.93472299999996,56.01138299999997],[-60.943329000000006,56.00666000000001]],[[-61.62361099999998,56.39999399999999],[-61.54666899999995,56.39083099999999],[-61.49305700000002,56.40499100000005],[-61.48277300000001,56.406654],[-61.474716,56.406654],[-61.46832999999992,56.40443399999998],[-61.41527599999995,56.376656000000025],[-61.41166700000002,56.372214999999926],[-61.41110999999995,56.36721000000006],[-61.412216,56.32665999999995],[-61.416106999999954,56.32222000000013],[-61.424171,56.32027400000004],[-61.48277300000001,56.30999000000003],[-61.569449999999904,56.320549000000085],[-61.57972699999999,56.32249499999995],[-61.599723999999924,56.32777399999992],[-61.68638599999986,56.35277600000006],[-61.719993999999986,56.36582900000002],[-61.788895000000025,56.405823],[-61.79333500000001,56.40888200000012],[-61.79611199999994,56.41304800000006],[-61.79055799999992,56.41582499999993],[-61.78388999999987,56.41582499999993],[-61.67777999999993,56.405548000000124],[-61.62361099999998,56.39999399999999]],[[-78.83999599999993,56.12999000000008],[-78.92749000000003,56.1138840000001],[-78.93331899999998,56.11554700000005],[-78.93055699999996,56.12860100000012],[-78.916946,56.172493000000145],[-78.9083399999999,56.18249500000013],[-78.90388499999995,56.18720999999999],[-78.883331,56.201935000000105],[-78.84638999999999,56.2347180000001],[-78.83029199999993,56.25332600000013],[-78.825287,56.2627720000001],[-78.81332399999997,56.30470999999994],[-78.80943299999996,56.338882000000126],[-78.81388899999996,56.343323000000055],[-78.83473200000003,56.34554300000002],[-78.83250399999991,56.35082999999997],[-78.76251200000002,56.42471300000011],[-78.75140399999992,56.432495000000074],[-78.73167399999994,56.4405440000001],[-78.69499200000001,56.4438780000001],[-78.68638599999991,56.44332099999997],[-78.66722099999998,56.4397130000001],[-78.66166699999997,56.43610400000006],[-78.66000399999996,56.430550000000096],[-78.65083299999992,56.289161999999976],[-78.65278599999994,56.24193600000007],[-78.65556300000003,56.22360200000014],[-78.67639200000002,56.181107],[-78.68859900000001,56.17276799999996],[-78.83999599999993,56.12999000000008]],[[-79.626938,56.26527399999998],[-79.63583399999999,56.26499899999999],[-79.63667299999997,56.266388000000006],[-79.63639799999987,56.26915700000012],[-79.60943600000002,56.31971699999997],[-79.53860500000002,56.433051999999975],[-79.53443900000002,56.43749199999996],[-79.52389499999998,56.44276400000007],[-79.51112399999994,56.44638100000003],[-79.49694799999997,56.44860100000005],[-79.49221799999992,56.44693799999993],[-79.49055499999992,56.44082600000013],[-79.51083399999993,56.397491],[-79.55776999999989,56.305267000000015],[-79.56111099999993,56.299164000000076],[-79.56555200000003,56.29388400000005],[-79.569458,56.28999299999998],[-79.61944599999987,56.26721199999997],[-79.626938,56.26527399999998]],[[-79.61999500000002,56.385268999999994],[-79.63806199999999,56.360550000000046],[-79.64944499999996,56.346382000000006],[-79.66332999999997,56.33387800000014],[-79.68249500000002,56.317496999999946],[-79.70111099999997,56.306381000000044],[-79.714447,56.29999500000008],[-79.90666199999993,56.227211000000125],[-79.92832899999996,56.219711000000075],[-79.98611499999998,56.19971500000008],[-80.01916499999993,56.19137600000005],[-80.06054699999999,56.18443300000007],[-80.08250399999991,56.18665300000009],[-80.09222399999999,56.18832400000014],[-80.10055499999999,56.19137600000005],[-80.10749799999991,56.19499200000013],[-80.10972600000002,56.197768999999994],[-80.110275,56.20332300000001],[-80.100281,56.23915899999997],[-80.09861799999987,56.24415600000009],[-80.05526700000001,56.30360400000012],[-80.04444899999993,56.310822000000144],[-80.04055800000003,56.31276700000012],[-80.02250699999996,56.31971699999997],[-79.86749299999997,56.357498000000135],[-79.79554699999994,56.366661000000136],[-79.75666799999999,56.36193799999995],[-79.72444200000001,56.36277000000007],[-79.69888299999991,56.36888099999999],[-79.679169,56.378326000000015],[-79.656387,56.3927690000001],[-79.64250199999998,56.40443399999998],[-79.61888099999993,56.426941000000056],[-79.614441,56.43166400000007],[-79.60417199999995,56.444153000000085],[-79.59805299999994,56.4544370000001],[-79.59138499999995,56.46915400000012],[-79.58833300000003,56.493881000000044],[-79.58528100000001,56.49916100000007],[-79.58250399999991,56.50166300000001],[-79.54972800000002,56.52526900000004],[-79.54333499999996,56.52777100000014],[-79.54277000000002,56.522217000000126],[-79.54943800000001,56.508049000000085],[-79.61389199999996,56.39527099999998],[-79.61999500000002,56.385268999999994]],[[-61.43582900000001,56.54138200000011],[-61.16805999999997,56.47470900000002],[-61.14999399999999,56.44554099999999],[-61.14888799999994,56.441101],[-61.15444200000002,56.43859900000007],[-61.163612,56.436653000000035],[-61.181945999999925,56.43526500000013],[-61.200278999999966,56.43526500000013],[-61.22083299999997,56.435546999999985],[-61.517501999999865,56.44693799999993],[-61.60916900000001,56.46166199999999],[-61.63055399999996,56.46527099999997],[-61.64222699999999,56.48638200000005],[-61.63722199999995,56.489716000000044],[-61.629997,56.49054700000005],[-61.54639400000002,56.48804499999994],[-61.538612,56.48582499999998],[-61.525832999999864,56.47887400000002],[-61.512778999999966,56.4749910000001],[-61.43804899999992,56.47637900000001],[-61.42305799999997,56.4791560000001],[-61.417778,56.48333000000014],[-61.41833500000001,56.48832700000003],[-61.42250100000001,56.49054700000005],[-61.455276000000026,56.49638399999998],[-61.496666000000005,56.50000000000006],[-61.52722199999994,56.50166300000001],[-61.624168,56.50388299999997],[-61.633331,56.506386000000134],[-61.63444500000003,56.51249700000005],[-61.63194299999998,56.51638800000012],[-61.602225999999916,56.55277300000006],[-61.59583299999997,56.55638099999999],[-61.58833299999998,56.55804400000005],[-61.576667999999984,56.55776999999995],[-61.56166799999994,56.554161000000136],[-61.558051999999975,56.55193300000002],[-61.52594799999997,56.550212999999985],[-61.45916699999992,56.54583000000008],[-61.43582900000001,56.54138200000011]],[[-79.02166699999992,56.426941000000056],[-79.00944500000003,56.426383999999985],[-78.98832699999997,56.426941000000056],[-78.9491579999999,56.43082400000003],[-78.94305400000002,56.430550000000096],[-78.93582200000003,56.428878999999995],[-78.92887899999994,56.42582700000008],[-78.92471299999994,56.419441000000006],[-78.922775,56.415268000000026],[-78.921112,56.409714000000065],[-78.92054699999994,56.40332000000001],[-78.92304999999993,56.386940000000095],[-78.93638599999997,56.317496999999946],[-78.94332899999995,56.284996000000035],[-78.94999699999994,56.282493999999986],[-78.95527600000003,56.27915999999999],[-78.96139499999987,56.27137800000003],[-79.02917499999995,56.172493000000145],[-79.06138599999997,56.124435000000005],[-79.07167099999998,56.104996000000085],[-79.08500700000002,56.07749200000012],[-79.09416199999998,56.05499300000014],[-79.12999000000002,55.98943299999996],[-79.17527799999993,55.92332499999992],[-79.19526699999994,55.8919370000001],[-79.20361300000002,55.89415700000012],[-79.166267,55.973881000000006],[-79.122116,56.046715000000006],[-79.061935,56.14860500000003],[-79.02278100000001,56.20249200000001],[-79.008896,56.22165699999994],[-78.99082900000002,56.261664999999994],[-78.98582499999998,56.27360500000009],[-78.97277799999995,56.30665600000003],[-78.97027599999996,56.31415600000008],[-78.96777299999991,56.323608000000036],[-78.9661099999999,56.33610500000003],[-78.97027599999996,56.37804399999999],[-78.97084000000001,56.3836060000001],[-78.97721899999999,56.38860299999999],[-78.98332199999999,56.38971699999996],[-78.99888599999991,56.384163],[-79.04333499999996,56.360550000000046],[-79.05526700000001,56.34443700000003],[-79.06221,56.32972000000001],[-79.08917200000002,56.267769000000044],[-79.09110999999996,56.26305400000001],[-79.09306299999997,56.25694300000009],[-79.09294899999998,56.231716000000006],[-79.09544399999999,56.2190480000001],[-79.09394800000001,56.21371799999997],[-79.092781,56.21155199999998],[-79.08911099999995,56.21188400000011],[-79.083328,56.17416400000002],[-79.212784,55.95416300000011],[-79.23611499999993,55.917496000000085],[-79.25944499999991,55.88610800000009],[-79.275284,55.87027000000006],[-79.28332499999999,55.864441000000056],[-79.28666699999985,55.86666100000008],[-79.28611799999999,55.869987000000094],[-79.27806099999992,55.88555100000002],[-79.26722699999993,55.90304600000002],[-79.22666899999996,55.96249399999999],[-79.18360899999993,56.03749799999997],[-79.13999899999993,56.115273000000116],[-79.133896,56.12665600000008],[-79.132721,56.17577000000006],[-79.13856499999986,56.2052690000001],[-79.139725,56.20776699999999],[-79.14356199999997,56.21126600000014],[-79.15055799999999,56.233047],[-79.160553,56.231377000000066],[-79.17027299999995,56.225548],[-79.20556599999998,56.190826000000015],[-79.24388099999999,56.15110000000004],[-79.256393,56.13110400000005],[-79.27084400000001,56.10471299999995],[-79.27749599999999,56.090828000000045],[-79.28416400000003,56.07804900000002],[-79.29972799999996,56.05165899999997],[-79.30915800000002,56.03638500000011],[-79.32362399999994,56.016936999999984],[-79.35861199999994,55.97443400000009],[-79.45249899999999,55.879990000000134],[-79.47999600000003,55.863883999999985],[-79.49305699999996,55.85888700000004],[-79.500565,55.85665900000009],[-79.510559,55.85555300000004],[-79.52027900000002,55.854713000000004],[-79.53250099999997,55.85499600000014],[-79.56777999999997,55.864716000000044],[-79.59388699999994,55.87443500000006],[-79.60499600000003,55.881660000000124],[-79.78195199999999,55.78804800000006],[-79.76306199999993,55.814156000000025],[-79.59805299999994,55.98165899999998],[-79.48693799999995,56.08721200000002],[-79.474716,56.09832799999998],[-79.47027599999996,56.10443900000001],[-79.470551,56.112770000000125],[-79.47250400000001,56.11693600000001],[-79.478882,56.12332200000009],[-79.49722299999996,56.133605999999986],[-79.51306199999999,56.13499500000012],[-79.523056,56.133880999999974],[-79.537216,56.12971500000009],[-79.55027799999993,56.12332200000009],[-79.56750499999998,56.112770000000125],[-79.59722899999997,56.09137700000002],[-79.64500399999997,56.050545],[-79.81945799999994,55.9011000000001],[-79.83168,55.88999200000012],[-79.84666399999998,55.87416100000013],[-79.858047,55.85999300000009],[-79.86389200000002,55.85083000000009],[-79.86582900000002,55.84721400000001],[-79.90916400000003,55.840546000000074],[-79.98582499999998,55.89804800000002],[-79.96194499999996,55.96027400000003],[-79.77444499999996,56.112213000000054],[-79.66805999999991,56.18998700000003],[-79.64862099999999,56.198326000000066],[-79.64222699999999,56.20138500000007],[-79.587784,56.23027000000013],[-79.53633099999996,56.295052000000055],[-79.52683999999999,56.304214000000115],[-79.51617399999998,56.319881000000066],[-79.49466699999999,56.36721400000005],[-79.48733500000003,56.40271400000012],[-79.45889299999988,56.464157],[-79.45861799999994,56.46832300000011],[-79.45861799999994,56.478600000000085],[-79.46610999999996,56.498878000000104],[-79.47444199999995,56.52110299999998],[-79.47138999999993,56.54444100000006],[-79.46610999999996,56.54833200000013],[-79.45666499999999,56.55332199999998],[-79.44888300000002,56.55443599999995],[-79.445267,56.553604000000064],[-79.44193999999987,56.55138400000004],[-79.43859900000001,56.54777500000006],[-79.41833499999996,56.490829000000076],[-79.41944899999987,56.44360399999994],[-79.44300099999998,56.39343600000001],[-79.47499800000003,56.32043800000014],[-79.531387,56.206940000000145],[-79.51445000000001,56.18637800000005],[-79.46167000000003,56.193321000000026],[-79.43888900000002,56.19721200000009],[-79.42721599999999,56.20304900000008],[-79.41639700000002,56.21221200000008],[-79.41305499999999,56.21666000000005],[-79.30999800000001,56.42416399999996],[-79.30110199999996,56.447212000000036],[-79.29804999999993,56.4594350000001],[-79.29333500000001,56.48804499999994],[-79.291672,56.498878000000104],[-79.28639199999992,56.57027399999998],[-79.13999899999993,56.54638699999998],[-79.13305700000001,56.54277000000002],[-79.12999000000002,56.53777300000007],[-79.12554899999998,56.51415999999995],[-79.12193299999996,56.49554399999994],[-79.11999500000002,56.48998999999998],[-79.11193800000001,56.47526600000009],[-79.09999099999999,56.46305100000001],[-79.09138499999989,56.4544370000001],[-79.07556199999993,56.444153000000085],[-79.05555700000002,56.43387600000011],[-79.03889500000002,56.428878999999995],[-79.02166699999992,56.426941000000056]],[[-79.14195299999994,56.61666100000008],[-79.15194699999995,56.61638600000009],[-79.26000999999997,56.6280440000001],[-79.26889,56.629158000000075],[-79.274719,56.632209999999986],[-79.27749599999999,56.637215000000026],[-79.27999899999998,56.64888000000013],[-79.28028899999998,56.654990999999995],[-79.27500900000001,56.667213000000004],[-79.27194199999997,56.67193600000013],[-79.25472999999988,56.67999300000014],[-79.24415599999992,56.68249500000002],[-79.21888699999994,56.68499000000003],[-79.20889299999999,56.683876000000055],[-79.19360399999994,56.67832900000013],[-79.16000400000001,56.65776800000009],[-79.15110800000002,56.649994000000106],[-79.14167800000001,56.635826000000066],[-79.13806199999999,56.626099000000124],[-79.13890100000003,56.619986999999924],[-79.14195299999994,56.61666100000008]],[[-61.1875,56.586104999999975],[-61.21167000000003,56.58166499999999],[-61.217498999999975,56.58277099999998],[-61.222770999999966,56.58888200000007],[-61.231667000000016,56.61166399999996],[-61.231941000000006,56.61971299999999],[-61.22610499999996,56.626656000000025],[-61.165832999999964,56.684433000000126],[-61.15916399999992,56.68832400000002],[-61.15027600000002,56.68943000000007],[-61.13194299999998,56.68721000000005],[-61.0819469999999,56.67887899999994],[-61.0777819999999,56.67499500000014],[-61.05777699999999,56.62887599999999],[-61.05944099999999,56.62638099999998],[-61.06361400000003,56.62416099999996],[-61.10388899999987,56.60665899999992],[-61.1875,56.586104999999975]],[[-79.56082199999997,56.61776700000013],[-79.56750499999998,56.615273],[-79.57333399999999,56.6188810000001],[-79.583618,56.64804800000002],[-79.58389299999993,56.65277100000003],[-79.58999599999999,56.768326],[-79.5875089999999,56.78888699999999],[-79.58167999999995,56.80721299999999],[-79.57833900000003,56.81249200000002],[-79.57417299999986,56.81582599999996],[-79.56750499999998,56.81777200000005],[-79.51666299999994,56.78555300000005],[-79.49638400000003,56.766936999999984],[-79.47694399999995,56.72165700000005],[-79.474716,56.68915600000014],[-79.48611499999998,56.658043000000134],[-79.48889199999996,56.65554800000007],[-79.56082199999997,56.61776700000013]],[[-79.88194299999998,56.743607000000054],[-79.88861099999997,56.741104000000064],[-79.90472399999999,56.741661000000136],[-79.92388900000003,56.75138900000002],[-79.93083199999995,56.75499700000012],[-79.941101,56.76361099999997],[-79.94444299999992,56.7677690000001],[-79.94749499999995,56.77332300000012],[-79.95722999999992,56.79916400000002],[-79.95889299999993,56.80526700000013],[-79.958618,56.81137799999999],[-79.95472699999993,56.82360799999992],[-79.945831,56.83360300000004],[-79.91915899999992,56.85833000000014],[-79.915009,56.86138200000005],[-79.86582900000002,56.86610400000012],[-79.858047,56.86582900000013],[-79.843887,56.85833000000014],[-79.83444199999991,56.85249299999998],[-79.81945799999994,56.84027100000003],[-79.81639100000001,56.83554800000002],[-79.81471299999993,56.829162999999994],[-79.81361400000003,56.81693999999999],[-79.83389299999999,56.79361],[-79.83805799999999,56.78888699999999],[-79.8722229999999,56.75222000000002],[-79.87666300000001,56.747772000000055],[-79.88194299999998,56.743607000000054]],[[-79.75056499999994,56.905823000000055],[-79.71749899999992,56.81360599999999],[-79.71833799999996,56.80721299999999],[-79.72111499999988,56.802773],[-79.72555499999999,56.79804999999999],[-79.73083499999996,56.79415899999992],[-79.74972500000001,56.78360700000013],[-79.75750700000003,56.78193699999997],[-79.781113,56.784721000000104],[-79.78832999999986,56.78582800000004],[-79.79355599999997,56.79579200000006],[-79.79437300000001,56.832947000000104],[-79.79314399999998,56.859890000000064],[-79.82376899999997,56.89500399999997],[-79.852753,56.885204000000044],[-79.89416499999987,56.88193500000011],[-79.89750699999996,56.884995],[-79.89805599999994,56.891106000000036],[-79.896118,56.897217000000126],[-79.89277600000003,56.90248900000006],[-79.85861199999994,56.93859900000001],[-79.85194399999995,56.940268999999944],[-79.80833399999995,56.94832600000012],[-79.79943800000001,56.949431999999945],[-79.79083300000002,56.94776900000005],[-79.78416400000003,56.94082600000007],[-79.75361599999997,56.91082],[-79.75056499999994,56.905823000000055]],[[-61.42921100000001,56.92970700000001],[-61.397204999999985,56.927715000000035],[-61.37261199999989,56.930972999999994],[-61.35488899999996,56.93639799999994],[-61.34331900000001,56.93422700000008],[-61.340785999999866,56.930248000000006],[-61.355278,56.91082],[-61.40027599999996,56.88472000000013],[-61.40471600000001,56.87971500000009],[-61.39944499999996,56.87582400000002],[-61.378052000000025,56.87165800000014],[-61.360282999999924,56.86610400000012],[-61.35222599999997,56.857773000000066],[-61.355834999999956,56.85277600000012],[-61.361670999999944,56.84804500000001],[-61.375831999999946,56.84054600000002],[-61.4431689999999,56.817719000000125],[-61.48966999999999,56.80754900000011],[-61.563331999999946,56.784721000000104],[-61.57028199999991,56.78166199999998],[-61.576949999999954,56.778046000000074],[-61.585556,56.76638800000006],[-61.58499899999998,56.76138300000002],[-61.58277899999996,56.75666000000001],[-61.57556199999999,56.75305200000008],[-61.56472000000002,56.75166300000012],[-61.55583199999995,56.752777000000094],[-61.540839999999946,56.75777399999998],[-61.526664999999866,56.76527400000009],[-61.51528200000001,56.77471200000008],[-61.497653999999955,56.78694200000001],[-61.48897599999992,56.78929500000004],[-61.476315,56.79019900000003],[-61.43400200000002,56.7836880000001],[-61.39331399999992,56.77898800000003],[-61.386626999999976,56.775913],[-61.38210700000002,56.7713930000001],[-61.373965999999996,56.74390800000009],[-61.36872499999998,56.695988],[-61.36863299999999,56.6857720000001],[-61.37080400000002,56.67528200000004],[-61.378399,56.63260700000001],[-61.37911999999994,56.626820000000066],[-61.39358900000002,56.61777900000004],[-61.40913799999993,56.61560800000001],[-61.44421799999998,56.61958700000008],[-61.48400099999998,56.64164700000009],[-61.52197599999994,56.66985700000009],[-61.56103499999995,56.68251399999997],[-61.588157999999964,56.70385399999998],[-61.60533499999997,56.713798999999995],[-61.63535300000001,56.73151800000005],[-61.64439399999998,56.734775999999954],[-61.64403199999987,56.73802900000004],[-61.634991000000014,56.770939],[-61.624866,56.82591200000013],[-61.63209899999998,56.85954700000008],[-61.58869899999996,56.89353900000009],[-61.534812999999986,56.901859],[-61.522517999999934,56.9148790000001],[-61.5261339999999,56.93332300000009],[-61.52396399999992,56.94019300000008],[-61.499371,56.952849999999955],[-61.47369400000002,56.95900000000006],[-61.46067399999998,56.955021000000045],[-61.446571000000006,56.935131000000126],[-61.42921100000001,56.92970700000001]],[[-76.62110899999993,57.075554000000125],[-76.64695699999999,57.073050999999964],[-76.660278,57.075829],[-76.67138699999992,57.083327999999995],[-76.67555199999993,57.087769000000094],[-76.681107,57.09777100000002],[-76.70973200000003,57.18221300000005],[-76.70861799999994,57.18832400000008],[-76.67832900000002,57.205269000000044],[-76.66999800000002,57.20249199999995],[-76.66749600000003,57.19554100000005],[-76.62609900000001,57.1427690000001],[-76.61888099999999,57.080276000000026],[-76.62110899999993,57.075554000000125]],[[-61.621666000000005,57.33554800000013],[-61.611114999999984,57.334991],[-61.60555999999991,57.33554800000013],[-61.59444399999995,57.33416],[-61.589995999999985,57.33027599999997],[-61.58943899999991,57.32527200000004],[-61.59194199999996,57.321380999999974],[-61.608337000000006,57.30832700000008],[-61.652221999999995,57.290549999999996],[-61.658051,57.29027600000006],[-61.73472599999997,57.29027600000006],[-61.739998000000014,57.29193900000001],[-61.75333399999994,57.30249000000009],[-61.76361799999995,57.31166100000007],[-61.76666299999994,57.315269],[-61.767776000000026,57.31971699999997],[-61.768607999999915,57.324996999999996],[-61.76750199999998,57.32833099999999],[-61.752228,57.360275],[-61.74888599999997,57.365546999999935],[-61.74500299999994,57.369155999999975],[-61.726944,57.37443500000012],[-61.70249899999999,57.37276500000013],[-61.693329000000006,57.368050000000096],[-61.67749799999996,57.35721600000005],[-61.63221699999991,57.33776900000004],[-61.621666000000005,57.33554800000013]],[[-76.715012,57.29277000000002],[-76.72972099999987,57.28971899999999],[-76.73472600000002,57.29138200000011],[-76.74027999999998,57.29444100000006],[-76.74444599999998,57.29943800000001],[-76.79305999999997,57.374709999999936],[-76.82194499999991,57.419715999999994],[-76.823624,57.42471300000011],[-76.82167099999998,57.42943600000007],[-76.81277499999993,57.42832900000013],[-76.78443900000002,57.41693900000007],[-76.76139799999999,57.40387700000008],[-76.73554999999999,57.38638300000014],[-76.73110999999994,57.381935],[-76.72555499999999,57.37276500000013],[-76.72111499999994,57.35665899999998],[-76.708054,57.29583000000008],[-76.715012,57.29277000000002]],[[-61.65527300000002,57.39138000000008],[-61.675003000000004,57.38999200000001],[-61.839721999999995,57.408043000000134],[-61.860000999999954,57.4124910000001],[-61.87749499999995,57.41860200000002],[-61.88999899999999,57.42610200000007],[-61.89444699999996,57.42971799999998],[-61.89778099999995,57.43332700000013],[-61.90027599999996,57.437492000000134],[-61.89749899999998,57.444153000000085],[-61.81300399999992,57.47370900000004],[-61.772738999999945,57.495097999999984],[-61.742774999999995,57.53499599999998],[-61.73722099999998,57.53694200000007],[-61.719993999999986,57.536384999999996],[-61.648056,57.530272999999966],[-61.64389,57.52276600000005],[-61.634727,57.509438000000046],[-61.61361699999998,57.41610000000014],[-61.615279999999984,57.40915700000011],[-61.634170999999924,57.39888000000013],[-61.64833799999997,57.39360800000003],[-61.65527300000002,57.39138000000008]],[[-61.878333999999995,57.46305099999995],[-61.92694899999998,57.45249200000012],[-61.93749999999994,57.45304900000002],[-61.94694500000003,57.454994],[-61.95583299999993,57.45804600000008],[-61.96277600000002,57.46221200000002],[-62.01250499999992,57.50833100000011],[-62.021942000000024,57.521102999999925],[-62.02305599999994,57.53416400000003],[-62.020279000000016,57.54027600000006],[-62.01445000000001,57.54943800000012],[-61.99250000000001,57.56916000000001],[-61.97499799999997,57.58138300000007],[-61.968886999999995,57.584434999999985],[-61.953056000000004,57.59027100000003],[-61.94444299999998,57.5908280000001],[-61.878052000000025,57.584991],[-61.855002999999954,57.58055100000013],[-61.833327999999995,57.57444000000004],[-61.817504999999926,57.56721500000003],[-61.78361499999994,57.55054500000006],[-61.781386999999995,57.548050000000046],[-61.778885,57.543883999999935],[-61.77694699999995,57.52388000000002],[-61.77777899999995,57.51832600000006],[-61.779441999999904,57.513611000000026],[-61.78305799999987,57.50833100000011],[-61.864165999999955,57.466385000000116],[-61.878333999999995,57.46305099999995]],[[-79.79750100000001,57.41888400000005],[-79.80166600000001,57.4158250000001],[-79.80555699999996,57.41805300000004],[-79.83583099999998,57.460274000000084],[-79.8269499999999,57.53804800000006],[-79.80888399999998,57.561661000000015],[-79.79276999999996,57.57888000000008],[-79.74916099999996,57.60971800000004],[-79.74082899999996,57.615547000000106],[-79.73416099999992,57.618881000000044],[-79.72778299999993,57.61721],[-79.723053,57.61277000000001],[-79.70611600000001,57.585548000000074],[-79.70666499999993,57.580826],[-79.70472699999999,57.57666000000006],[-79.69860799999998,57.56332400000014],[-79.695831,57.53166199999998],[-79.69860799999998,57.51998900000012],[-79.70500199999992,57.50860599999993],[-79.71250899999995,57.50054899999998],[-79.79750100000001,57.41888400000005]],[[-61.688605999999936,57.71305100000012],[-61.69610599999993,57.712212000000136],[-61.757506999999976,57.71554600000013],[-61.76889,57.71693400000004],[-61.89416499999999,57.754166000000055],[-61.896950000000004,57.758331000000055],[-61.89611099999996,57.76971400000008],[-61.891669999999976,57.77916000000005],[-61.865837,57.799721000000034],[-61.853614999999934,57.80832700000013],[-61.80889099999996,57.83693699999998],[-61.800551999999925,57.84137700000002],[-61.778885,57.84526800000009],[-61.773056,57.84554300000008],[-61.71111300000001,57.83416000000011],[-61.69860799999992,57.83027600000008],[-61.653610000000015,57.784721000000104],[-61.652221999999995,57.78249400000004],[-61.65166499999992,57.77943399999998],[-61.65249599999993,57.77582600000005],[-61.654166999999916,57.771103000000096],[-61.66860999999989,57.73888400000004],[-61.674171,57.72693600000002],[-61.684440999999936,57.7149960000001],[-61.688605999999936,57.71305100000012]],[[-61.94749499999995,57.787216000000114],[-61.957222,57.78694200000001],[-62.08916499999998,57.808043999999995],[-62.100280999999995,57.816101],[-62.108337000000006,57.824715000000026],[-62.109443999999996,57.8294370000001],[-62.10805499999992,57.837769000000094],[-62.099723999999924,57.84638200000006],[-62.09444399999995,57.85054799999995],[-62.065276999999924,57.87054400000011],[-62.028884999999946,57.89276899999999],[-62.009170999999924,57.90443400000004],[-61.995003,57.90915700000005],[-61.986114999999984,57.91027100000002],[-61.971663999999976,57.911377000000016],[-61.94110899999998,57.909988000000055],[-61.92833699999994,57.90859999999992],[-61.923332000000016,57.90609699999999],[-61.91889199999997,57.90248900000006],[-61.88444499999997,57.86693600000001],[-61.86777499999988,57.84276600000004],[-61.86777499999988,57.8386000000001],[-61.87943999999993,57.816666],[-61.88194299999992,57.81276700000001],[-61.88555899999989,57.80915799999997],[-61.88999899999999,57.8063810000001],[-61.94083399999994,57.78888699999999],[-61.94749499999995,57.787216000000114]],[[-77.67832899999996,58.23554999999993],[-77.68777499999993,58.235268000000076],[-77.702789,58.2388840000001],[-77.76112399999994,58.257499999999936],[-77.94638099999992,58.3211060000001],[-77.95083599999992,58.32416500000005],[-77.947495,58.32860599999998],[-77.94055199999997,58.330551000000014],[-77.93249500000002,58.33138300000007],[-77.91731299999992,58.32936900000004],[-77.82972699999993,58.31137800000005],[-77.80749499999996,58.305267000000015],[-77.80139200000002,58.30304699999999],[-77.702789,58.26027700000003],[-77.689438,58.25388299999997],[-77.67027300000001,58.24415600000003],[-77.66833499999996,58.24193600000007],[-77.66833499999996,58.24054700000005],[-77.67832899999996,58.23554999999993]],[[-67.596115,58.28416400000009],[-67.61639400000001,58.28416400000009],[-67.63778699999995,58.28472099999999],[-67.66610699999995,58.29277000000002],[-67.67388899999992,58.296104000000014],[-67.67666600000001,58.30138400000004],[-67.67582700000003,58.306099000000074],[-67.672775,58.31220999999999],[-67.624435,58.368050000000096],[-67.61999499999996,58.3722150000001],[-67.61082499999992,58.37387799999999],[-67.59916699999991,58.373046999999985],[-67.58056599999998,58.369986999999924],[-67.527222,58.34360500000008],[-67.52084400000001,58.339989],[-67.51750199999998,58.33526600000005],[-67.51916499999993,58.32971999999995],[-67.52444500000001,58.32416500000005],[-67.55110200000001,58.30221599999999],[-67.55722000000003,58.298050000000046],[-67.57167099999987,58.290833000000134],[-67.596115,58.28416400000009]],[[-78.453888,58.53999300000004],[-78.45556599999986,58.537215999999944],[-78.46333299999998,58.53749800000003],[-78.474716,58.541382000000056],[-78.64999399999994,58.60138699999999],[-78.67250100000001,58.61054999999999],[-78.68388400000003,58.62082700000013],[-78.697495,58.678329000000076],[-78.69860799999998,58.68859900000001],[-78.69694499999997,58.69054399999999],[-78.69276400000001,58.691933000000006],[-78.665009,58.67499500000008],[-78.65916399999998,58.669991000000095],[-78.63528400000001,58.61859899999996],[-78.63194299999998,58.616386000000034],[-78.62805199999997,58.61415899999997],[-78.56639100000001,58.58610499999992],[-78.51306199999993,58.56388099999998],[-78.45722999999998,58.54277000000013],[-78.453888,58.53999300000004]],[[-69.19444299999992,59.06471299999998],[-69.18638599999997,59.064437999999996],[-69.18083199999995,59.06721500000009],[-69.1783289999999,59.02971599999995],[-69.22721899999993,58.97193100000004],[-69.32028199999996,58.94638100000009],[-69.32749899999999,58.94499200000007],[-69.33889799999997,58.944435],[-69.350281,58.94638100000009],[-69.35555999999997,58.94971500000008],[-69.36000099999995,58.95860300000004],[-69.35722399999997,58.96471400000013],[-69.31834400000002,59.02555099999995],[-69.319458,59.09804500000013],[-69.35305799999998,59.1272130000001],[-69.35777300000001,59.13499500000006],[-69.35722399999997,59.13971700000013],[-69.34555099999994,59.14471400000008],[-69.339447,59.14610300000004],[-69.28222700000003,59.15443399999998],[-69.27528399999994,59.15499100000005],[-69.19860799999992,59.14527099999998],[-69.18638599999997,59.138329000000056],[-69.18249499999996,59.128601],[-69.19499199999996,59.09415400000006],[-69.199997,59.07721700000002],[-69.20056199999988,59.07249500000012],[-69.19860799999992,59.06721500000009],[-69.19444299999992,59.06471299999998]],[[-80.53443900000002,59.369438],[-80.54415899999998,59.365547000000106],[-80.55221599999987,59.36582900000013],[-80.55583200000001,59.369438],[-80.54943799999995,59.446938000000046],[-80.53750600000001,59.45526899999999],[-80.48805199999998,59.477486000000056],[-80.47555499999993,59.48110200000008],[-80.46501199999994,59.463882000000126],[-80.47138999999993,59.45499400000011],[-80.47721899999993,59.451103000000046],[-80.52084400000001,59.38276700000006],[-80.52528399999994,59.377486999999974],[-80.53443900000002,59.369438]],[[-80.27749599999999,59.61859900000013],[-80.31916799999999,59.612213000000054],[-80.32972699999999,59.61249500000014],[-80.34056099999992,59.61415899999997],[-80.343887,59.61915600000003],[-80.34083599999997,59.62526700000012],[-80.29527300000001,59.67832900000002],[-80.23277300000001,59.725265999999976],[-80.22222899999986,59.72360200000014],[-80.17138699999992,59.71527100000009],[-80.15417500000001,59.709991],[-80.14527899999996,59.70555099999996],[-80.15472399999993,59.68249500000013],[-80.15666199999998,59.67832900000002],[-80.170547,59.67388199999999],[-80.20584099999996,59.66526799999991],[-80.22277799999989,59.66027100000002],[-80.22972099999998,59.65638000000013],[-80.23306300000002,59.65110000000004],[-80.237213,59.63943499999999],[-80.24055499999986,59.63416300000006],[-80.24638400000003,59.62999000000008],[-80.26083399999999,59.623604],[-80.27749599999999,59.61859900000013]],[[-64.01972999999992,59.71471399999996],[-64.12416099999996,59.695267000000115],[-64.13417099999998,59.69554100000005],[-64.146118,59.69665500000002],[-64.15722699999998,59.69971500000008],[-64.16332999999986,59.70360599999998],[-64.20445299999994,59.73443600000002],[-64.19249000000002,59.76554900000002],[-64.12193300000001,59.849433999999974],[-64.11582899999996,59.85277600000006],[-64.10722399999997,59.854996000000085],[-64.06750499999993,59.86388400000004],[-64.06138599999991,59.86444099999994],[-64.05277999999998,59.859992999999974],[-64.04972799999996,59.85527000000002],[-64.04777499999994,59.849433999999974],[-64.05526699999996,59.835266000000104],[-64.05444299999999,59.82943700000004],[-64.0427699999999,59.78388200000006],[-64.0202789999999,59.78110499999997],[-64.00279199999994,59.77471200000002],[-63.95972399999994,59.75638600000002],[-63.95944199999997,59.752220000000136],[-63.99722300000002,59.72360200000014],[-64.01139799999987,59.71638500000006],[-64.01972999999992,59.71471399999996]],[[-80.08972199999994,59.75193800000005],[-80.166946,59.742493000000024],[-80.17777999999998,59.74415600000009],[-80.18415800000002,59.747772],[-80.18472299999996,59.75277700000004],[-80.12887599999999,59.82388300000008],[-80.11500499999994,59.83776900000004],[-80.10305799999998,59.8449940000001],[-80.015015,59.88499500000012],[-80.00778200000002,59.88610799999998],[-79.94694499999991,59.880272000000105],[-79.93777499999993,59.877768999999944],[-79.92999299999991,59.87360399999994],[-79.88417099999992,59.85833000000008],[-79.87887599999999,59.85471300000012],[-79.883621,59.849998000000085],[-79.90666199999993,59.828049000000135],[-79.92222600000002,59.815544000000045],[-79.92805499999997,59.81166100000007],[-80.02528399999994,59.76444200000009],[-80.08972199999994,59.75193800000005]],[[-64.42767300000003,60.37293200000005],[-64.452789,60.357215999999994],[-64.4427639999999,60.3097150000001],[-64.43832399999997,60.305550000000096],[-64.42361499999998,60.28249400000004],[-64.42944299999994,60.28193699999997],[-64.43804899999986,60.28249400000004],[-64.44860799999998,60.28416400000003],[-64.50111400000003,60.30193300000013],[-64.52171299999998,60.310730000000035],[-64.54110699999995,60.32444000000004],[-64.55721999999992,60.33138300000002],[-64.60194399999989,60.350273000000016],[-64.61000100000001,60.353606999999954],[-64.63221699999991,60.35749800000002],[-64.64388999999994,60.357773000000066],[-64.65556299999997,60.35749800000002],[-64.66610700000001,60.35694099999995],[-64.67555199999998,60.355270000000075],[-64.71000700000002,60.35833000000014],[-64.728882,60.36332700000008],[-64.79028299999993,60.39110600000009],[-64.81555200000003,60.40609699999999],[-64.83111600000001,60.419159000000036],[-64.86749299999991,60.45027200000004],[-64.868607,60.45332300000007],[-64.86805699999996,60.45888500000001],[-64.85611,60.473877000000016],[-64.84722899999997,60.47887400000013],[-64.837784,60.48249100000004],[-64.82305899999994,60.48526800000013],[-64.63999899999999,60.4847180000001],[-64.61860699999994,60.47721100000001],[-64.42694099999994,60.401381999999955],[-64.42388900000003,60.397216999999955],[-64.42250100000001,60.3919370000001],[-64.42388900000003,60.383049000000085],[-64.42767300000003,60.37293200000005]],[[-68.25140399999998,60.23082000000005],[-68.31054699999999,60.22304500000013],[-68.34028599999999,60.22332],[-68.36193799999995,60.22582200000005],[-68.376938,60.232491000000095],[-68.38722200000001,60.240829000000076],[-68.39306599999998,60.24916100000007],[-68.39472999999998,60.254440000000045],[-68.39500399999997,60.25999500000012],[-68.39306599999998,60.27610000000004],[-68.38417099999992,60.29972100000009],[-68.37777699999998,60.310272],[-68.314438,60.39027399999998],[-68.17527799999999,60.53443900000002],[-68.12943999999993,60.570549000000085],[-68.11915599999992,60.577217000000076],[-68.09222399999999,60.581665000000044],[-68.08167999999995,60.58249699999999],[-68.03527799999995,60.58110799999997],[-67.999435,60.57749200000012],[-67.95666499999999,60.56610099999995],[-67.94860799999992,60.56137799999999],[-67.88722199999995,60.50388300000009],[-67.862213,60.48804500000006],[-67.839722,60.47804300000007],[-67.83139,60.47499099999999],[-67.821396,60.472488],[-67.80804399999994,60.467209000000025],[-67.80305499999997,60.463051000000064],[-67.79861499999987,60.4574970000001],[-67.79499800000002,60.44776900000005],[-67.79554699999994,60.443877999999984],[-67.79861499999987,60.432213000000104],[-67.806107,60.417496000000085],[-67.81527699999992,60.40804300000008],[-67.83639499999992,60.3886030000001],[-67.841385,60.3844380000001],[-67.85333300000002,60.37526699999995],[-67.885559,60.353606999999954],[-67.898056,60.34526799999992],[-67.93443300000001,60.321662999999944],[-67.96528599999999,60.30832700000002],[-67.97222899999997,60.30582400000003],[-68.16749600000003,60.24554400000011],[-68.17721599999993,60.24304999999998],[-68.20527600000003,60.23804500000011],[-68.25140399999998,60.23082000000005]],[[-64.68998699999992,60.5844350000001],[-64.69722000000002,60.58221400000002],[-64.70445299999994,60.58249699999999],[-64.71278399999994,60.59027100000014],[-64.71389799999992,60.59526800000009],[-64.71305799999988,60.59887700000007],[-64.71083099999998,60.60277600000012],[-64.61555499999986,60.68166400000007],[-64.61027499999994,60.68526500000013],[-64.59916699999997,60.68943000000013],[-64.59277299999991,60.68554700000004],[-64.59083599999997,60.67665900000003],[-64.59249899999998,60.66693900000013],[-64.593887,60.6483310000001],[-64.59584000000001,60.64527100000004],[-64.620544,60.61666100000002],[-64.63166799999999,60.60833000000008],[-64.63806199999993,60.604996000000085],[-64.68998699999992,60.5844350000001]],[[-78.656387,60.70277400000003],[-78.66471899999999,60.70221700000013],[-78.67416399999996,60.70471199999997],[-78.68998699999997,60.71221200000008],[-78.69471699999991,60.71666000000005],[-78.69833399999999,60.72165699999994],[-78.69776899999994,60.72415900000004],[-78.61639399999996,60.7719350000001],[-78.573624,60.78416399999992],[-78.39999399999999,60.80999000000003],[-78.22389199999998,60.83082600000006],[-78.21945199999999,60.82388300000002],[-78.21916199999998,60.81749700000012],[-78.221115,60.81415600000008],[-78.22666900000002,60.80888399999998],[-78.277222,60.76915700000012],[-78.28500400000001,60.76610600000009],[-78.39723199999992,60.743881000000044],[-78.62332200000003,60.70555100000013],[-78.656387,60.70277400000003]],[[-69.97721899999999,60.933051999999975],[-69.98388699999998,60.93110699999994],[-69.99526999999995,60.9313810000001],[-70.00361599999997,60.93526500000007],[-70.00778199999996,60.93915599999997],[-70.02610799999997,60.99582700000008],[-70.02500899999995,61.001937999999996],[-70.02166699999987,61.008605999999986],[-70.016663,61.013611000000026],[-70.00917099999987,61.01776899999999],[-70.00334199999992,61.02082800000011],[-69.9827729999999,61.02832799999999],[-69.964722,61.03276800000003],[-69.95417799999996,61.033882000000006],[-69.943604,61.03138000000013],[-69.93138099999993,61.02027100000004],[-69.92999299999985,61.01666300000011],[-69.92971799999992,61.01082599999995],[-69.93083200000001,61.00471500000009],[-69.93388399999992,60.9980470000001],[-69.97721899999999,60.933051999999975]],[[-64.72389199999992,61.53833000000003],[-64.71665999999999,61.53582799999998],[-64.706955,61.536658999999986],[-64.68832399999991,61.53555299999999],[-64.68331899999987,61.531105000000025],[-64.67527799999999,61.50860600000004],[-64.67416400000002,61.50332599999996],[-64.686935,61.46582799999999],[-64.70527600000003,61.44415300000014],[-64.715012,61.43332700000008],[-64.82055700000001,61.355270000000075],[-64.86694299999999,61.324164999999994],[-64.87083399999995,61.32249500000006],[-64.87527499999999,61.32249500000006],[-64.88722200000001,61.324715000000026],[-64.97250399999996,61.34415400000012],[-64.97749299999992,61.34777100000008],[-64.98500099999995,61.36749300000014],[-65.17916899999994,61.46693399999998],[-65.18582200000003,61.47554800000006],[-65.18749999999994,61.48027000000013],[-65.19055200000003,61.494995000000074],[-65.195267,61.49916099999996],[-65.2952729999999,61.52887700000002],[-65.329453,61.531937000000084],[-65.35333300000002,61.53472100000005],[-65.37249799999995,61.53721600000006],[-65.381104,61.54055000000005],[-65.47444200000001,61.58693699999998],[-65.48110999999989,61.590828000000045],[-65.48777799999993,61.599433999999974],[-65.48693800000001,61.61082500000009],[-65.48500099999995,61.62193300000007],[-65.48222399999997,61.62860100000006],[-65.47222899999986,61.64027400000009],[-65.46640000000002,61.644997000000046],[-65.45944199999985,61.64916200000005],[-65.45306399999998,61.6519320000001],[-65.44915800000001,61.653602999999976],[-65.44137599999993,61.656654],[-65.43582200000003,61.65804300000002],[-65.33972199999994,61.670547000000056],[-65.24749800000001,61.68082400000003],[-65.17443800000001,61.68693500000012],[-65.06834399999997,61.69304700000009],[-65.03639199999992,61.69360399999999],[-65.01888999999989,61.69249000000002],[-65.01611299999996,61.692214999999976],[-64.99499499999996,61.68998700000003],[-64.73306299999996,61.659988],[-64.71916199999998,61.65804300000002],[-64.64639299999993,61.60388200000011],[-64.646118,61.599716],[-64.65083300000003,61.59443700000003],[-64.65972899999997,61.58804299999997],[-64.662781,61.58776900000004],[-64.71417200000002,61.556381000000044],[-64.72027599999996,61.55138399999993],[-64.72610499999996,61.54222099999993],[-64.72389199999992,61.53833000000003]],[[-65.69526699999989,61.776657],[-65.71945199999999,61.754166],[-65.80305499999992,61.755554000000075],[-65.82722499999994,61.758049000000085],[-65.891388,61.76638800000012],[-65.903885,61.76832600000006],[-65.931107,61.778328000000045],[-65.93916300000001,61.78221099999996],[-65.94444299999998,61.785828000000095],[-65.94804399999992,61.79027600000006],[-65.94749499999989,61.796104000000014],[-65.94387799999993,61.79972099999998],[-65.81834400000002,61.860825000000034],[-65.80943299999996,61.86332700000014],[-65.78999299999998,61.865547000000106],[-65.77806099999987,61.865547000000106],[-65.76750199999998,61.86277000000001],[-65.718613,61.841102999999976],[-65.71472199999994,61.83693700000009],[-65.71362299999998,61.82416500000011],[-65.69526699999989,61.776657]],[[-92.96389799999997,61.879158000000075],[-92.99527,61.85110500000013],[-93.00167799999997,61.847214000000065],[-93.05194099999994,61.82943700000004],[-93.07028200000002,61.82527200000004],[-93.07972699999999,61.826941999999974],[-93.08666999999991,61.82943700000004],[-93.11582899999996,61.860275],[-93.12027,61.86444100000011],[-93.12693799999988,61.868599000000074],[-93.13583399999999,61.872489999999914],[-93.14805599999994,61.87582400000008],[-93.17971799999992,61.87554900000009],[-93.189438,61.874161000000015],[-93.21112099999993,61.87526700000001],[-93.218887,61.87943300000012],[-93.22332799999998,61.888329000000056],[-93.22610500000002,61.90832500000005],[-93.22361799999993,61.913048],[-93.218887,61.91888400000005],[-93.20944199999991,61.92110400000007],[-93.07250999999991,61.92999300000014],[-93.06221,61.93055000000004],[-92.96945199999999,61.888329000000056],[-92.962784,61.884162999999944],[-92.96389799999997,61.879158000000075]],[[-64.91610699999995,61.719437000000084],[-64.92694099999994,61.71888000000001],[-64.95195000000001,61.72248800000011],[-65.14805599999994,61.78054800000007],[-65.15666199999993,61.78388200000006],[-65.21055599999988,61.816940000000045],[-65.21472199999988,61.821938000000046],[-65.25195300000001,61.86971300000005],[-65.25584399999997,61.88555100000008],[-65.25500499999993,61.90165700000006],[-65.249435,61.91027100000008],[-65.24527,61.914711000000125],[-65.18971299999998,61.94554099999999],[-65.17027300000001,61.94776900000011],[-65.15695199999988,61.9469380000001],[-65.08029199999993,61.93110700000011],[-65.07444800000002,61.92832900000013],[-65.06806899999998,61.92388200000005],[-65.03916900000002,61.89971900000012],[-64.98083499999996,61.885826000000066],[-64.89334100000002,61.82999400000011],[-64.88694800000002,61.82555400000007],[-64.82888799999989,61.766662999999994],[-64.82583599999998,61.76193999999998],[-64.825287,61.758331],[-64.82888799999989,61.75222000000008],[-64.83555599999994,61.74887799999999],[-64.85804699999994,61.73915899999997],[-64.88944999999995,61.72582200000011],[-64.90611299999995,61.721100000000035],[-64.91610699999995,61.719437000000084]],[[-65.85249299999992,62.08471700000001],[-65.86915599999992,62.07972000000012],[-65.88999899999999,62.08055100000013],[-65.91332999999997,62.084990999999945],[-66.00973499999998,62.11666100000008],[-66.016663,62.120543999999995],[-66.02027900000002,62.12443500000006],[-66.021118,62.12832600000013],[-66.02084399999995,62.131660000000124],[-66.01472499999994,62.136658000000125],[-65.99194299999994,62.14138000000003],[-65.92805499999997,62.151657],[-65.904449,62.15277100000014],[-65.85360700000001,62.13110400000011],[-65.84500099999991,62.124992000000134],[-65.83555599999994,62.115272999999945],[-65.83583099999993,62.099716000000114],[-65.843887,62.088599999999985],[-65.85249299999992,62.08471700000001]],[[-92.22361799999993,62.355552999999986],[-92.306107,62.35166199999992],[-92.339722,62.35471299999995],[-92.34973100000002,62.356659000000036],[-92.37193299999996,62.386939999999925],[-92.37249800000001,62.39193700000004],[-92.35444599999994,62.410820000000115],[-92.34777799999995,62.41443600000002],[-92.31945799999994,62.41526800000008],[-92.30833399999995,62.41443600000002],[-92.162216,62.402214000000015],[-92.139725,62.399719000000005],[-92.1411129999999,62.394714000000135],[-92.15834000000001,62.390549000000135],[-92.22361799999993,62.355552999999986]],[[-79.54055800000003,62.41110200000003],[-79.44999699999994,62.382767],[-79.44276400000001,62.37999000000008],[-79.43388399999998,62.371376000000055],[-79.42916899999994,62.361664000000076],[-79.42721599999999,62.356102000000135],[-79.42443800000001,62.34415400000012],[-79.42054699999994,62.33998900000012],[-79.35916099999997,62.29610400000007],[-79.34722899999991,62.28888699999999],[-79.32861300000002,62.28333299999997],[-79.27278099999995,62.26221500000008],[-79.26611299999996,62.25804899999997],[-79.26083399999999,62.25360899999998],[-79.256393,62.244438],[-79.25556899999992,62.23971599999993],[-79.26139799999993,62.16360500000002],[-79.26222200000001,62.15888200000006],[-79.32972699999999,62.01527400000009],[-79.353882,61.99971800000014],[-79.39639299999993,61.968879999999956],[-79.45722999999992,61.89388300000002],[-79.46194499999996,61.88166000000001],[-79.46556099999992,61.876099000000124],[-79.52444500000001,61.811378000000104],[-79.54132099999993,61.79978900000009],[-79.55277999999993,61.79638699999998],[-79.56834400000002,61.79027600000006],[-79.583618,61.783051],[-79.59666400000003,61.77443699999998],[-79.60526999999996,61.76527399999998],[-79.61111499999998,61.7544400000001],[-79.61277799999999,61.74276700000007],[-79.61193800000001,61.738045],[-79.60833699999995,61.732208000000014],[-79.60611,61.72665400000005],[-79.60555999999997,61.721100000000035],[-79.60749800000002,61.70888500000012],[-79.62887599999993,61.66915899999998],[-79.63221699999997,61.66499300000004],[-79.64222699999999,61.655823],[-79.65695199999999,61.64249400000011],[-79.74082899999996,61.5886000000001],[-79.75389100000001,61.580276000000026],[-79.76139799999993,61.57694200000003],[-79.779449,61.5719380000001],[-79.8058319999999,61.568054000000075],[-79.82778899999994,61.566666],[-79.84611499999994,61.56999200000001],[-79.87110899999999,61.60971799999999],[-79.95417800000001,61.683601000000124],[-80.06806899999998,61.74527000000006],[-80.079453,61.74777200000011],[-80.09222399999999,61.74804699999993],[-80.13861099999991,61.74860400000006],[-80.16194199999995,61.74860400000006],[-80.17332499999998,61.7502750000001],[-80.19166599999988,61.755554000000075],[-80.20527600000003,61.7627720000001],[-80.275284,61.80665600000003],[-80.27806099999998,61.810272000000055],[-80.27888499999995,61.81638299999997],[-80.29138199999994,61.92999300000014],[-80.29527300000001,61.983604000000014],[-80.26861600000001,62.107215999999994],[-80.266663,62.11138200000005],[-80.19860799999998,62.1988750000001],[-80.18028300000003,62.21749100000011],[-80.01750199999998,62.358604000000014],[-80.00944500000003,62.36249500000008],[-79.98138399999993,62.37416100000007],[-79.94722000000002,62.386108000000036],[-79.93804899999998,62.388603000000046],[-79.91972399999997,62.393051000000014],[-79.900284,62.39582800000011],[-79.84277299999991,62.40360300000003],[-79.83361799999994,62.404160000000104],[-79.73083499999996,62.3991620000001],[-79.60555999999997,62.41304800000006],[-79.58416699999998,62.41721300000006],[-79.56193499999989,62.41721300000006],[-79.54055800000003,62.41110200000003]],[[-92.41111799999993,62.39388300000013],[-92.42054699999994,62.39166300000011],[-92.43138099999999,62.39166300000011],[-92.44082599999996,62.393608000000086],[-92.52917500000001,62.37832600000007],[-92.53944399999995,62.37721299999998],[-92.56138599999991,62.37748699999992],[-92.58389299999999,62.37999000000008],[-92.59583999999995,62.38249199999996],[-92.60055499999999,62.386939999999925],[-92.600281,62.39249400000011],[-92.59695399999993,62.39777400000003],[-92.59277299999997,62.40248900000006],[-92.53999299999998,62.42832900000002],[-92.53111299999995,62.43138099999993],[-92.410278,62.408882000000006],[-92.40388499999995,62.404709000000025],[-92.40556300000003,62.39943699999992],[-92.41111799999993,62.39388300000013]],[[-64.65388499999995,62.54083300000002],[-64.58084099999996,62.538605000000075],[-64.55972299999996,62.55416100000002],[-64.55999800000001,62.55860100000001],[-64.55555699999996,62.560822000000144],[-64.54972799999996,62.56221000000005],[-64.39750699999996,62.53638500000005],[-64.389725,62.53388200000006],[-64.38528400000001,62.53110500000014],[-64.382767,62.525825999999995],[-64.382767,62.51138300000014],[-64.39416499999993,62.46137999999996],[-64.47721899999999,62.40804300000002],[-64.52860999999996,62.38665800000007],[-64.59056099999998,62.367210000000114],[-64.59889199999998,62.36638599999998],[-64.65361000000001,62.37249000000003],[-64.77278100000001,62.38638300000002],[-64.87110899999999,62.40638000000013],[-64.92666600000001,62.41832700000009],[-64.93721,62.42110399999996],[-64.945831,62.42443800000012],[-64.95249899999988,62.42832900000002],[-64.95388799999995,62.43138099999993],[-64.96583599999991,62.46582799999993],[-64.846115,62.555267000000015],[-64.81555200000003,62.55971499999998],[-64.79750099999995,62.561378000000104],[-64.766953,62.56276700000012],[-64.75306699999999,62.56249200000008],[-64.741669,62.560822000000144],[-64.65388499999995,62.54083300000002]],[[-78.00834700000001,62.59360500000008],[-77.86721799999998,62.589157000000114],[-77.85055499999999,62.58277100000004],[-77.84167499999995,62.56805400000002],[-77.837784,62.556938000000116],[-77.84083599999991,62.54999500000008],[-77.84472699999998,62.54471600000011],[-77.85278299999999,62.541664000000026],[-77.86221299999994,62.53943600000008],[-77.87304699999999,62.53777300000013],[-77.88500999999997,62.53749800000014],[-77.91305499999993,62.53943600000008],[-78.10333300000002,62.55915800000008],[-78.11305199999993,62.56221000000005],[-78.11444099999994,62.570549000000085],[-78.11166400000002,62.578049000000135],[-78.10777299999995,62.58277100000004],[-78.10583500000001,62.58332800000011],[-78.0475009999999,62.59193400000004],[-78.03083800000002,62.593323000000055],[-78.01916499999999,62.59193400000004],[-78.00834700000001,62.59360500000008]],[[-77.80526700000001,62.59249100000011],[-77.72721899999993,62.58582299999995],[-77.6658329999999,62.586655000000064],[-77.62805200000003,62.58832600000011],[-77.62138400000003,62.58443500000004],[-77.637787,62.57083100000011],[-77.65110800000002,62.563881000000094],[-77.65916400000003,62.560822000000144],[-77.73472599999997,62.53582799999998],[-77.74527,62.534163999999976],[-77.75862099999989,62.53555300000011],[-77.78028899999993,62.539161999999976],[-77.80860899999993,62.546660999999915],[-77.81361399999997,62.551102000000014],[-77.83111600000001,62.59027100000009],[-77.83167999999995,62.595825000000104],[-77.821121,62.59609999999992],[-77.80943300000001,62.59415400000006],[-77.80526700000001,62.59249100000011]],[[-64.98306300000002,62.52804600000002],[-65.00723299999993,62.52638200000001],[-65.09638999999999,62.534996000000035],[-65.11972000000003,62.53749800000014],[-65.13194299999998,62.53971900000005],[-65.13806199999999,62.542770000000075],[-65.14167799999996,62.54694400000011],[-65.137787,62.55054499999994],[-65.02250700000002,62.5949940000001],[-65.00306699999993,62.598877000000016],[-64.97250399999996,62.602493000000095],[-64.90916399999998,62.60443899999996],[-64.89250199999998,62.598877000000016],[-64.88473499999992,62.59415400000006],[-64.84388699999994,62.58277100000004],[-64.839447,62.57777399999992],[-64.86082499999986,62.561378000000104],[-64.866104,62.55804400000011],[-64.874435,62.55470999999994],[-64.96528599999988,62.53138000000001],[-64.972778,62.52971600000001],[-64.98306300000002,62.52804600000002]],[[-91.57278399999996,62.62748700000009],[-91.57861299999996,62.62193300000007],[-91.66805999999991,62.64916200000005],[-91.68305999999995,62.662209000000075],[-91.68554699999999,62.66693900000013],[-91.67582699999997,62.66915900000009],[-91.66332999999997,62.66554300000007],[-91.65527299999991,62.662209000000075],[-91.581955,62.64138000000008],[-91.57556199999993,62.63721500000008],[-91.571121,62.632767000000115],[-91.57278399999996,62.62748700000009]],[[-90.97999599999997,62.657767999999976],[-90.99027999999998,62.656654],[-91.00334199999992,62.657211000000075],[-91.09889199999992,62.65443399999998],[-91.24471999999997,62.66999100000004],[-91.256393,62.67193600000002],[-91.26695299999994,62.675552000000096],[-91.27111799999994,62.67999299999997],[-91.26722699999999,62.685546999999985],[-91.226944,62.691658000000075],[-91.17304999999999,62.69137599999999],[-91.08029199999999,62.68693500000006],[-91.056107,62.68166400000007],[-90.981674,62.66137699999996],[-90.97999599999997,62.657767999999976]],[[-74.347778,62.67943600000007],[-74.30999800000001,62.67916100000008],[-74.285553,62.67999299999997],[-74.25028999999995,62.682495000000074],[-74.21610999999996,62.684990000000084],[-74.181671,62.68888099999998],[-74.15888999999999,62.68888099999998],[-74.14584399999995,62.68776700000001],[-74.01583900000003,62.66499300000004],[-74.00917099999998,62.66249099999993],[-73.95973200000003,62.62082700000002],[-73.958054,62.616661000000136],[-73.958054,62.612495000000024],[-73.96250899999995,62.60777299999995],[-73.96972700000003,62.60416399999997],[-73.98860200000001,62.60221899999999],[-74.12887599999988,62.60082999999997],[-74.15444899999989,62.60110500000002],[-74.16915899999992,62.60221899999999],[-74.18360899999993,62.603882000000056],[-74.333618,62.62943300000012],[-74.54138199999994,62.66832700000003],[-74.55110200000001,62.67082999999997],[-74.58639499999992,62.683051999999975],[-74.61721799999992,62.69609800000006],[-74.639725,62.70638300000002],[-74.64973399999991,62.712769000000094],[-74.65139799999986,62.716934000000094],[-74.64584400000001,62.72082499999999],[-74.53721599999994,62.748878000000104],[-74.5266719999999,62.748878000000104],[-74.51916499999987,62.74777200000011],[-74.48277299999995,62.739716000000044],[-74.39222699999993,62.68721000000011],[-74.37998999999996,62.682495000000074],[-74.37416099999996,62.6813810000001],[-74.347778,62.67943600000007]],[[-70.71167000000003,62.81499500000001],[-70.65972899999991,62.79833200000013],[-70.587784,62.7741620000001],[-70.54750099999995,62.76527399999998],[-70.41555799999998,62.7291560000001],[-70.39695699999999,62.72304500000001],[-70.22610499999996,62.603049999999996],[-70.21777299999997,62.59443700000003],[-70.21221899999995,62.584160000000054],[-70.21112099999999,62.57916300000011],[-70.21194500000001,62.57777399999992],[-70.264725,62.55915800000008],[-70.28332499999999,62.55443600000001],[-70.37361099999993,62.533332999999914],[-70.39306599999998,62.53027300000008],[-70.414444,62.529434000000094],[-70.46665999999993,62.53166200000004],[-70.50111399999997,62.533607000000075],[-70.68638599999991,62.546104000000014],[-70.72389199999998,62.550270000000125],[-70.74638399999998,62.55470999999994],[-70.765015,62.5605470000001],[-70.77084400000001,62.56471299999998],[-70.81973299999999,62.60471300000012],[-70.82501199999996,62.61444100000011],[-70.85444599999994,62.71360800000008],[-70.84666399999998,62.766106000000036],[-70.94554099999993,62.798050000000046],[-71.01916499999993,62.81193499999995],[-71.03250099999997,62.81249200000002],[-71.04333499999996,62.81193499999995],[-71.05166599999995,62.81054700000004],[-71.10638399999993,62.80082700000014],[-71.14111300000002,62.794998000000135],[-71.14862099999993,62.794998000000135],[-71.15834000000001,62.79721799999999],[-71.17610199999996,62.80915800000008],[-71.24055499999997,62.87638099999998],[-71.241379,62.8813780000001],[-71.23638900000003,62.886658000000125],[-71.22944599999988,62.88804600000003],[-71.19110099999995,62.884720000000016],[-71.07389799999993,62.87193300000001],[-70.78805499999993,62.836104999999975],[-70.76028399999996,62.829994000000056],[-70.71167000000003,62.81499500000001]],[[-66.36833199999995,62.83526599999999],[-66.37388599999986,62.833603000000096],[-66.386124,62.834434999999985],[-66.49027999999998,62.85527000000013],[-66.50527999999997,62.861382000000106],[-66.60166900000002,62.90665400000012],[-66.59388699999994,62.91193400000003],[-66.57417299999997,62.913048],[-66.547775,62.91054500000001],[-66.54028299999993,62.907493999999986],[-66.44193999999999,62.871101000000124],[-66.37777699999992,62.843323],[-66.37027,62.83971399999996],[-66.36833199999995,62.83526599999999]],[[-81.87110899999999,62.92832900000013],[-81.86555499999997,62.92332499999998],[-81.86416599999995,62.91999099999998],[-81.90695199999999,62.86638600000009],[-81.92610199999996,62.74415600000003],[-81.924713,62.73915899999997],[-81.92388900000003,62.73304699999994],[-81.92416400000002,62.72832500000004],[-81.92610199999996,62.723602000000085],[-81.929169,62.719437000000084],[-81.93859899999995,62.709991000000116],[-81.95889299999999,62.69776899999994],[-81.973053,62.6897130000001],[-82.10221899999999,62.62915800000013],[-82.1875,62.59943399999992],[-82.27778599999994,62.584160000000054],[-82.2869419999999,62.58166499999999],[-82.31555200000003,62.57166300000006],[-82.36915599999992,62.54749300000003],[-82.38166799999999,62.53943600000008],[-82.38778699999995,62.53472100000005],[-82.40194699999995,62.52054600000014],[-82.40834000000001,62.509720000000016],[-82.40888999999993,62.49665799999997],[-82.414444,62.47804300000007],[-82.42581199999995,62.46998600000006],[-82.44221499999992,62.458603000000096],[-82.44972200000001,62.4552690000001],[-82.49943499999995,62.438599000000124],[-82.53388999999999,62.428604000000064],[-82.551941,62.42388199999999],[-82.58361799999994,62.41276600000003],[-82.62138400000003,62.39527100000004],[-82.64111300000002,62.38526900000005],[-82.64723200000003,62.38110400000005],[-82.67027300000001,62.35943600000013],[-82.68859900000001,62.34110300000009],[-82.71305799999993,62.32138100000003],[-82.73138399999993,62.309990000000084],[-82.743607,62.30248999999998],[-82.76916499999999,62.290276000000006],[-82.98554999999999,62.209717000000126],[-83.00195300000001,62.20443700000004],[-83.087784,62.17887900000011],[-83.12193299999996,62.1730500000001],[-83.13639799999999,62.1730500000001],[-83.14389,62.176659000000086],[-83.15083299999998,62.182770000000005],[-83.15943900000002,62.198601],[-83.16805999999991,62.2074970000001],[-83.17639200000002,62.213051000000064],[-83.19860799999998,62.222214000000065],[-83.249435,62.24082900000002],[-83.27583299999998,62.248604000000114],[-83.30804399999988,62.25277700000004],[-83.32278400000001,62.25305200000008],[-83.33778399999994,62.252219999999966],[-83.35972600000002,62.24971800000009],[-83.40556299999997,62.23888400000004],[-83.4719389999999,62.22276300000004],[-83.48083500000001,62.21998600000012],[-83.49888599999991,62.21332600000011],[-83.51333599999992,62.20638300000013],[-83.53999299999992,62.191933000000006],[-83.57417299999986,62.1763840000001],[-83.63917499999997,62.1511000000001],[-83.653885,62.145827999999995],[-83.67277499999994,62.14110600000009],[-83.68331899999998,62.139717000000076],[-83.70388799999995,62.141662999999994],[-83.70944199999997,62.14444000000009],[-83.71389799999997,62.147216999999955],[-83.71833799999996,62.15221400000007],[-83.722778,62.16027100000002],[-83.722778,62.16721300000012],[-83.71806300000003,62.17943600000001],[-83.71194500000001,62.217209000000025],[-83.71166999999991,62.235825000000034],[-83.72138999999999,62.2816620000001],[-83.722778,62.28638500000011],[-83.72582999999992,62.295273000000066],[-83.731674,62.30360400000001],[-83.73889200000002,62.306937999999946],[-83.75666799999999,62.312492000000134],[-83.78332499999999,62.31888600000002],[-83.80665599999998,62.326385000000016],[-83.82444800000002,62.33721200000002],[-83.90249599999987,62.38749700000005],[-83.91861,62.3991620000001],[-83.93360899999988,62.41220900000013],[-83.94248999999996,62.42166100000003],[-83.945267,62.42721599999993],[-83.94665499999996,62.434158000000025],[-83.94665499999996,62.440269000000114],[-83.945267,62.44721200000009],[-83.93916299999995,62.457497000000046],[-83.91416899999996,62.47860000000014],[-83.90833999999995,62.48276499999997],[-83.86944599999998,62.501105999999936],[-83.85305800000003,62.50804900000014],[-83.814438,62.52388000000008],[-83.741379,62.551658999999916],[-83.70417799999996,62.569443000000035],[-83.69804399999992,62.573051000000135],[-83.57000700000003,62.67527000000001],[-83.55943300000001,62.68415799999997],[-83.55027799999993,62.69999700000011],[-83.545547,62.71221200000002],[-83.545547,62.71776600000004],[-83.55139200000002,62.726653999999996],[-83.55583199999995,62.731659000000036],[-83.55888400000003,62.743881000000044],[-83.53361499999988,62.810272000000055],[-83.52749599999993,62.8211060000001],[-83.523056,62.825271999999984],[-83.516953,62.829994000000056],[-83.400284,62.897491000000116],[-83.37416099999996,62.906937000000084],[-83.31082200000003,62.924438000000066],[-83.29861499999998,62.92582700000003],[-83.21167000000003,62.913605000000075],[-83.20417799999996,62.91027100000008],[-83.19833399999999,62.90665400000012],[-83.19387799999998,62.901932000000045],[-83.18249500000002,62.8813780000001],[-83.17805499999992,62.87638099999998],[-83.15611299999995,62.86054999999999],[-83.14250199999998,62.85443900000013],[-83.12470999999994,62.84804500000007],[-83.108337,62.843323],[-83.08750900000001,62.84027100000009],[-83.061935,62.83749399999999],[-83.04110700000001,62.83721200000008],[-83.02139299999999,62.838599999999985],[-83.00167799999991,62.84249100000005],[-82.98222399999992,62.84777100000014],[-82.85749799999996,62.88999200000012],[-82.82556199999999,62.90277100000003],[-82.79333500000001,62.915543000000014],[-82.75973499999992,62.926941],[-82.7519529999999,62.92887899999994],[-82.69444299999998,62.93943000000007],[-82.652222,62.94387800000004],[-82.62470999999988,62.945540999999935],[-82.60665899999998,62.945540999999935],[-82.573624,62.94387800000004],[-82.54083300000002,62.93943000000007],[-82.50778199999996,62.93360100000007],[-82.46139499999998,62.92748999999998],[-82.43611099999998,62.925270000000125],[-82.420837,62.92499500000014],[-82.39805599999988,62.92748999999998],[-82.38137799999998,62.932770000000005],[-82.37805200000003,62.936377999999934],[-82.37638900000002,62.94110100000012],[-82.379166,62.946655000000135],[-82.38362099999995,62.95138500000013],[-82.37998999999996,62.9574970000001],[-82.37222300000002,62.96027400000003],[-82.29277000000002,62.98333000000008],[-82.26666299999994,62.989159000000086],[-82.239441,62.99027300000006],[-82.18582199999992,62.979988000000105],[-82.12193299999996,62.966660000000104],[-82.00805700000001,62.95499399999994],[-81.94027699999998,62.95387999999997],[-81.91166699999997,62.952217000000076],[-81.90583800000002,62.94999700000005],[-81.87110899999999,62.92832900000013]],[[-66.82556199999999,62.984161000000086],[-66.83139,62.98276500000003],[-66.87138400000003,62.98888400000004],[-66.88194299999998,62.991661000000136],[-66.88945000000001,62.99526999999995],[-67.069458,63.10749800000002],[-67.03277600000001,63.103882],[-66.96528599999999,63.08249699999999],[-66.952225,63.07804900000002],[-66.94610599999987,63.07499700000011],[-66.94444299999992,63.072768999999994],[-66.93055700000002,63.06693999999999],[-66.91749600000003,63.0597150000001],[-66.90750100000002,63.052773],[-66.83000199999992,62.99249300000008],[-66.82695000000001,62.98999000000009],[-66.82501199999996,62.985550000000046],[-66.82556199999999,62.984161000000086]],[[-67.76445000000001,63.162491000000045],[-67.77583300000003,63.1616590000001],[-67.78750599999995,63.16304800000012],[-67.79861499999987,63.16554300000013],[-67.80638099999999,63.168602000000135],[-67.85194399999995,63.191376000000105],[-67.86332700000003,63.19915800000001],[-67.87638899999996,63.21193700000009],[-67.876938,63.21693399999998],[-67.875,63.22304500000007],[-67.86639399999996,63.23249100000004],[-67.85221899999988,63.244438],[-67.84445199999999,63.2472150000001],[-67.839722,63.2472150000001],[-67.831955,63.24415599999992],[-67.82194500000003,63.23665600000004],[-67.82223499999992,63.233330000000024],[-67.816101,63.23054499999995],[-67.79167199999995,63.21499600000004],[-67.769455,63.19832600000012],[-67.74610899999993,63.17887900000011],[-67.74472000000003,63.1730500000001],[-67.74638400000003,63.16693900000001],[-67.76445000000001,63.162491000000045]],[[-67.925003,63.18332700000008],[-67.95611600000001,63.181107000000054],[-67.966949,63.183876],[-68.00083899999998,63.208046000000024],[-68.01722699999999,63.22054300000002],[-68.06138599999991,63.25777399999998],[-68.10583499999996,63.299438000000066],[-68.11166399999996,63.30915800000014],[-68.112213,63.31360600000011],[-68.10638399999999,63.31860400000011],[-68.09695399999993,63.318885999999964],[-68.085556,63.31610100000012],[-68.06916799999988,63.309432999999956],[-68.04888900000003,63.29749300000009],[-68.03222700000003,63.28499600000009],[-68.00028999999995,63.26027699999992],[-67.92582699999997,63.196098000000006],[-67.920547,63.191376000000105],[-67.91694599999994,63.18665300000009],[-67.925003,63.18332700000008]],[[-78.07972699999999,63.469436999999914],[-77.94610599999999,63.468048000000124],[-77.93777499999999,63.471100000000035],[-77.93055699999996,63.4749910000001],[-77.92416400000002,63.47693600000008],[-77.91194199999995,63.47637900000001],[-77.84500100000002,63.47221400000001],[-77.68055700000002,63.43443300000001],[-77.63667299999992,63.40277100000009],[-77.495834,63.274994000000106],[-77.49388099999999,63.269989000000066],[-77.49499499999996,63.265831000000105],[-77.50389100000001,63.25249499999995],[-77.57333399999993,63.200546000000145],[-77.641953,63.17193600000007],[-77.78527799999989,63.12165800000014],[-77.89889499999992,63.09276600000004],[-77.90666199999998,63.09165999999999],[-77.93138099999993,63.09054600000002],[-77.94665500000002,63.09110300000009],[-77.95834399999995,63.093048000000124],[-78.0250089999999,63.11721],[-78.12471,63.16582500000004],[-78.226944,63.22165699999999],[-78.295547,63.25999500000006],[-78.31138599999991,63.27221700000001],[-78.32223499999998,63.281105000000025],[-78.343613,63.29694400000011],[-78.354446,63.30360400000012],[-78.44665500000002,63.35027300000013],[-78.4869379999999,63.36499800000007],[-78.51972999999998,63.370270000000005],[-78.52389499999998,63.37248999999997],[-78.56249999999994,63.39582800000011],[-78.57223499999992,63.4347150000001],[-78.57278399999996,63.440269000000114],[-78.55166599999995,63.44499200000007],[-78.37998999999996,63.47637900000001],[-78.278885,63.489716000000044],[-78.214111,63.49653599999999],[-78.212784,63.49610100000007],[-78.15861499999988,63.482208000000014],[-78.09167500000001,63.470543000000134],[-78.07972699999999,63.469436999999914]],[[-90.65388499999995,63.441101],[-90.697495,63.4397130000001],[-90.70889299999993,63.4405440000001],[-90.71916199999998,63.44360399999999],[-90.72582999999986,63.44804399999998],[-90.75500499999998,63.489716000000044],[-90.75723299999999,63.494438000000116],[-90.74804699999993,63.49832900000001],[-90.73750299999995,63.49916100000013],[-90.64555399999995,63.48333000000014],[-90.62026999999995,63.47693600000008],[-90.60278299999999,63.46388200000001],[-90.598053,63.454436999999984],[-90.60221899999999,63.44915800000001],[-90.61193799999995,63.44609800000012],[-90.62193299999996,63.44415300000014],[-90.65388499999995,63.441101]],[[-78.55749499999996,63.457497000000046],[-78.60055499999993,63.45638300000002],[-78.60333300000002,63.45777099999998],[-78.56138599999997,63.502495000000124],[-78.54333499999996,63.51610600000009],[-78.51583900000003,63.53166200000004],[-78.50500499999987,63.53249399999993],[-78.49610899999993,63.529434000000094],[-78.47332799999998,63.51915700000012],[-78.46806300000003,63.51554900000002],[-78.46166999999997,63.50749999999999],[-78.45916699999998,63.47998800000005],[-78.46194500000001,63.47387700000013],[-78.46722399999999,63.469436999999914],[-78.47555499999999,63.46693399999998],[-78.531113,63.45860300000004],[-78.55749499999996,63.457497000000046]],[[-90.79360999999994,63.49415600000009],[-90.80444299999994,63.49332400000014],[-90.816956,63.49582700000013],[-90.87721299999998,63.514717000000076],[-90.93331899999998,63.53416400000009],[-90.96583599999997,63.54583000000008],[-90.96833799999996,63.550270000000125],[-90.95750399999997,63.5513840000001],[-90.77111799999994,63.55193300000002],[-90.74804699999993,63.550270000000125],[-90.72000100000002,63.543052999999986],[-90.70973199999997,63.539992999999924],[-90.70083599999998,63.53611000000001],[-90.68138099999999,63.52304799999996],[-90.67694099999989,63.51859999999999],[-90.674713,63.51388499999996],[-90.678604,63.508331],[-90.68888900000002,63.50638600000002],[-90.79360999999994,63.49415600000009]],[[-64.851944,63.38582600000012],[-64.85694899999999,63.38582600000012],[-64.88221699999997,63.395546000000024],[-64.90417500000001,63.40638000000007],[-64.91833500000001,63.413879000000065],[-64.94221500000003,63.43082400000003],[-64.95083599999992,63.439156000000025],[-65.02667200000002,63.51554900000002],[-65.035278,63.52443699999998],[-65.05305499999997,63.54833199999996],[-65.051941,63.55221599999999],[-64.97721899999999,63.56832900000006],[-64.96749899999992,63.56832900000006],[-64.95472699999999,63.55888399999998],[-64.95472699999999,63.55387900000011],[-64.93360899999999,63.54471600000011],[-64.912216,63.533333000000084],[-64.90916399999998,63.52860300000009],[-64.86749299999991,63.46166200000005],[-64.86082499999986,63.44721200000009],[-64.84750400000001,63.40749400000004],[-64.84472699999998,63.39694200000008],[-64.847778,63.387496999999996],[-64.851944,63.38582600000012]],[[-72.18249500000002,63.51998900000001],[-72.20750399999997,63.51998900000001],[-72.218887,63.52249100000006],[-72.22694399999995,63.525825999999995],[-72.2327729999999,63.53027300000002],[-72.28666699999991,63.58332800000011],[-72.27917499999995,63.58554800000013],[-72.23222399999992,63.586655000000064],[-72.23028599999998,63.587212000000136],[-72.20527600000003,63.583054000000004],[-72.18443299999996,63.57721700000002],[-72.135559,63.562767000000065],[-72.129166,63.55888399999998],[-72.12805200000003,63.55387900000011],[-72.14500399999997,63.53943600000002],[-72.16583300000002,63.526381999999955],[-72.17361499999998,63.522766000000104],[-72.18249500000002,63.51998900000001]],[[-91.32917799999996,63.55971499999998],[-91.401947,63.54943800000001],[-91.42443800000001,63.550270000000125],[-91.43638599999997,63.55193300000002],[-91.4619449999999,63.55832700000008],[-91.54028299999993,63.60166200000003],[-91.54055800000003,63.60665899999998],[-91.53416400000003,63.611381999999935],[-91.50111399999997,63.61193800000012],[-91.46389799999992,63.6097180000001],[-91.44082600000002,63.608047000000056],[-91.428604,63.606383999999935],[-91.41639699999996,63.60360700000007],[-91.362503,63.59027100000009],[-91.34944200000001,63.586655000000064],[-91.29972799999996,63.567771999999934],[-91.30888400000003,63.563881000000094],[-91.32917799999996,63.55971499999998]],[[-64.09249899999992,63.48165900000009],[-64.101944,63.47943099999992],[-64.10916099999992,63.483047],[-64.16944899999999,63.52360500000009],[-64.18055699999996,63.53305100000006],[-64.18415800000002,63.53721600000006],[-64.20916699999998,63.574996999999996],[-64.2161099999999,63.59526800000003],[-64.21694899999994,63.60110500000013],[-64.21528599999994,63.617493000000024],[-64.21278399999994,63.623604000000114],[-64.19972200000001,63.633331000000055],[-64.19193999999999,63.63721500000008],[-64.18249500000002,63.639435000000105],[-64.17193599999996,63.63360600000004],[-64.09333799999996,63.56832900000006],[-64.07833899999991,63.55054500000011],[-64.077225,63.54527300000001],[-64.07778899999988,63.53971899999999],[-64.08612099999993,63.49305000000004],[-64.08750899999995,63.48665599999998],[-64.09249899999992,63.48165900000009]],[[-68.65638699999994,63.62638100000004],[-68.71777299999991,63.624161000000015],[-68.73110999999994,63.62554900000009],[-68.81555200000003,63.64916200000005],[-68.82167099999998,63.652488999999946],[-68.82000700000003,63.65526600000004],[-68.79305999999997,63.66165900000004],[-68.71444699999995,63.67249300000009],[-68.69166599999994,63.67360700000006],[-68.676941,63.671379000000115],[-68.66888399999993,63.66832699999998],[-68.66639700000002,63.66387900000001],[-68.66625999999997,63.662581999999986],[-68.65527299999997,63.63443799999999],[-68.654449,63.630272000000105],[-68.65638699999994,63.62638100000004]],[[-64.06111099999998,63.27054600000014],[-64.07055699999995,63.268326000000116],[-64.07833899999991,63.26888300000002],[-64.18194599999998,63.29694400000011],[-64.25140399999998,63.320831],[-64.266953,63.32638499999996],[-64.34973099999996,63.39222000000001],[-64.35388199999989,63.39582800000011],[-64.42193600000002,63.47165700000011],[-64.49610899999988,63.6097180000001],[-64.49055499999997,63.62054400000005],[-64.47917199999995,63.63694000000004],[-64.47361799999987,63.64054900000008],[-64.38667299999997,63.67527000000001],[-64.37721299999993,63.67748999999998],[-64.36721799999992,63.67527000000001],[-64.36305199999993,63.67193600000002],[-64.328888,63.644440000000145],[-64.32556199999993,63.63749699999994],[-64.32556199999993,63.59804500000007],[-64.32444799999996,63.58804299999997],[-64.32167099999998,63.57749200000006],[-64.316101,63.56249200000008],[-64.26251199999996,63.42110400000013],[-64.23249800000002,63.38832900000011],[-64.22528099999994,63.384438000000046],[-64.20666499999993,63.384163],[-64.166946,63.36943800000006],[-64.14472999999992,63.355552999999986],[-64.09999099999993,63.32276900000011],[-64.05749500000002,63.27804600000002],[-64.05749500000002,63.27388000000013],[-64.06111099999998,63.27054600000014]],[[-71.79916400000002,63.615546999999935],[-71.80694599999987,63.61193800000012],[-71.84527599999996,63.613609],[-71.8552699999999,63.61582900000002],[-71.86332700000003,63.619438],[-71.86582900000002,63.62443500000012],[-71.86582900000002,63.63638300000014],[-71.86416600000001,63.66944099999995],[-71.83056599999992,63.69387800000004],[-71.82194500000003,63.69526700000006],[-71.789444,63.69137599999999],[-71.779449,63.68832400000008],[-71.775284,63.68305199999992],[-71.77722199999994,63.67083000000014],[-71.79110700000001,63.6272130000001],[-71.79916400000002,63.615546999999935]],[[-76.81054699999999,63.60110500000013],[-76.710556,63.56582600000007],[-76.67222599999997,63.52887700000002],[-76.67555199999993,63.49665800000014],[-76.68160999999998,63.48135400000007],[-76.61332699999997,63.473602000000085],[-76.56555199999991,63.46776600000004],[-76.546112,63.46471400000013],[-76.54194599999994,63.462494000000106],[-76.54388399999999,63.46110499999992],[-76.67500299999995,63.37470999999999],[-76.68221999999997,63.37082700000008],[-76.69221499999998,63.367767000000015],[-76.70333899999997,63.365829000000076],[-76.71278399999994,63.36554699999999],[-76.72610500000002,63.36693600000001],[-76.847778,63.38526900000005],[-76.98416099999992,63.40638000000007],[-77.03527799999995,63.423882000000106],[-77.03944399999995,63.42610200000013],[-77.046112,63.42971799999998],[-77.05139199999996,63.434158000000025],[-77.05360399999995,63.43693500000012],[-77.05555699999996,63.442764000000125],[-77.06138599999997,63.45054600000009],[-77.10583499999996,63.47665400000005],[-77.11166399999996,63.479713000000004],[-77.327789,63.57222000000013],[-77.36721799999998,63.583054000000004],[-77.391388,63.58554800000013],[-77.41166699999997,63.584991],[-77.42222600000002,63.586655000000064],[-77.42777999999998,63.589157000000114],[-77.43194599999998,63.59193400000004],[-77.44221500000003,63.608330000000024],[-77.45722999999998,63.643325999999945],[-77.45388799999995,63.65221400000013],[-77.44027699999998,63.665268000000026],[-77.41027799999995,63.68665299999998],[-77.40055799999999,63.68888099999998],[-77.37805199999997,63.69221499999992],[-77.34333800000002,63.69609800000006],[-77.11694299999994,63.68110700000011],[-77.10333299999996,63.67971799999998],[-77.06138599999997,63.672768000000076],[-77.02139299999993,63.66415400000005],[-76.81054699999999,63.60110500000013]],[[-72.59472700000003,63.642494000000056],[-72.60444599999994,63.64166300000005],[-72.78056300000003,63.65998799999994],[-72.78332499999988,63.66443600000008],[-72.77055399999995,63.669715999999994],[-72.75666799999988,63.672768000000076],[-72.723053,63.67860399999995],[-72.50666799999999,63.70721400000002],[-72.48388699999998,63.708885000000066],[-72.47416699999991,63.705826000000116],[-72.47083999999995,63.702217000000076],[-72.47138999999999,63.700829],[-72.46888699999994,63.699158000000125],[-72.46333300000003,63.68915600000014],[-72.45973199999997,63.67916100000008],[-72.46055599999994,63.672768000000076],[-72.46389799999997,63.66832699999998],[-72.58444199999997,63.644440000000145],[-72.59472700000003,63.642494000000056]],[[-64.03250100000002,63.68971300000004],[-64.16111799999999,63.674438000000066],[-64.181107,63.67582700000008],[-64.20028699999995,63.685546999999985],[-64.20834400000001,63.69748700000008],[-64.21166999999997,63.70638300000002],[-64.21250900000001,63.71221200000002],[-64.20889299999999,63.721930999999984],[-64.18028300000003,63.74221800000009],[-64.17471299999994,63.745270000000005],[-64.16665599999999,63.747772000000055],[-64.08306900000002,63.75833100000011],[-64.07806399999998,63.75833100000011],[-64.075287,63.75804900000003],[-64.07333399999993,63.756386000000134],[-64.05484000000001,63.73659500000008],[-64.04333500000001,63.734161000000086],[-64.03028899999998,63.72971300000012],[-64.02528399999994,63.70249200000012],[-64.02528399999994,63.69748700000008],[-64.02639799999992,63.69387800000004],[-64.03250100000002,63.68971300000004]],[[-72.66776999999996,63.69582400000013],[-72.6949919999999,63.69026900000006],[-72.70361300000002,63.692490000000134],[-72.73416099999997,63.710823000000005],[-72.73889199999991,63.714439000000084],[-72.741669,63.71971100000002],[-72.74388099999987,63.73027000000002],[-72.73998999999998,63.736107000000004],[-72.71972700000003,63.76388500000013],[-72.71556099999992,63.766106000000036],[-72.70584100000002,63.76749400000011],[-72.69387799999998,63.76583099999999],[-72.68249500000002,63.76221499999997],[-72.66471899999993,63.75555400000002],[-72.64222699999993,63.745270000000005],[-72.63583399999999,63.74137900000011],[-72.62666300000001,63.73220799999996],[-72.62582399999997,63.727486000000056],[-72.62638900000002,63.72109999999998],[-72.63417099999998,63.709160000000054],[-72.64999399999999,63.701385000000016],[-72.66776999999996,63.69582400000013]],[[-64.28443900000002,63.70860299999998],[-64.28639199999998,63.70804600000008],[-64.31111099999993,63.709991000000116],[-64.32917800000001,63.71665999999999],[-64.33639499999992,63.719986000000006],[-64.34861799999999,63.72804299999996],[-64.35694899999999,63.73693800000001],[-64.36361699999998,63.74638399999998],[-64.381104,63.80749500000013],[-64.35943599999996,63.80387900000005],[-64.33972199999994,63.796943999999996],[-64.331955,63.79166399999997],[-64.30277999999993,63.78054800000001],[-64.27861000000001,63.77082800000011],[-64.27500899999995,63.76666300000011],[-64.25527999999997,63.72971300000012],[-64.25500499999993,63.72526600000009],[-64.26083399999987,63.71971100000002],[-64.28443900000002,63.70860299999998]],[[-64.17027300000001,63.856384000000105],[-64.1808319999999,63.785270999999966],[-64.195267,63.77860300000003],[-64.20333899999997,63.776382000000126],[-64.2344359999999,63.77137800000014],[-64.245834,63.77137800000014],[-64.256958,63.7741620000001],[-64.32556199999993,63.80582400000003],[-64.398346,63.845543000000134],[-64.39916999999997,63.84943400000003],[-64.3977809999999,63.85138699999999],[-64.39611799999994,63.85193600000014],[-64.35388199999989,63.86110700000006],[-64.334091,63.852081000000055],[-64.32556199999993,63.850273000000016],[-64.31082200000003,63.84832800000004],[-64.26834099999991,63.846100000000035],[-64.215012,63.850273000000016],[-64.20834400000001,63.852776000000006],[-64.20028699999995,63.85971800000004],[-64.18666100000002,63.86721],[-64.17999299999991,63.865547000000106],[-64.17582700000003,63.861938000000066],[-64.17027300000001,63.856384000000105]],[[-92.95417800000001,63.87110100000007],[-92.96055599999994,63.866386000000034],[-92.972778,63.86776700000007],[-92.99861099999998,63.873046999999985],[-93.06861900000001,63.88804600000003],[-93.093887,63.89999400000005],[-93.09445199999993,63.904990999999995],[-93.087784,63.90888200000006],[-93.07000700000003,63.90971399999995],[-93.00279199999994,63.91137700000007],[-92.99082900000002,63.91082],[-92.97833300000002,63.90832499999999],[-92.97444200000001,63.901657],[-92.95527599999997,63.88082099999997],[-92.95249899999999,63.87609900000007],[-92.95417800000001,63.87110100000007]],[[-64.57611099999986,63.780823],[-64.52583299999998,63.77137800000014],[-64.46777299999997,63.77137800000014],[-64.46194500000001,63.774712000000136],[-64.45249899999999,63.777214000000015],[-64.43276999999995,63.77943400000004],[-64.42610200000001,63.77777100000009],[-64.39472999999998,63.74582700000008],[-64.38751199999996,63.73749500000008],[-64.38612399999994,63.73443600000013],[-64.38612399999994,63.701660000000004],[-64.38999899999993,63.69638100000003],[-64.40417500000001,63.687492000000134],[-64.41915899999998,63.67971799999998],[-64.43638599999991,63.67332499999998],[-64.45056199999993,63.67166099999997],[-64.45944199999997,63.672768000000076],[-64.47444200000001,63.67916100000008],[-64.49694799999992,63.69082600000013],[-64.66166699999991,63.75499700000012],[-64.80221599999999,63.76444200000003],[-64.81332399999997,63.76721200000003],[-64.89028899999994,63.78943599999997],[-64.90055799999999,63.793883999999935],[-64.906387,63.797493000000145],[-64.9163969999999,63.80638099999993],[-64.91833500000001,63.815269000000114],[-64.92027299999995,63.82471500000008],[-64.9177699999999,63.83110800000003],[-64.91027799999995,63.83721200000008],[-64.89639299999999,63.845267999999976],[-64.81166099999996,63.87721300000004],[-64.710556,63.90888200000006],[-64.6824949999999,63.91443600000008],[-64.660278,63.91638200000011],[-64.64723199999997,63.916100000000085],[-64.55721999999992,63.90998800000011],[-64.55305499999992,63.90638000000001],[-64.54943799999995,63.89527100000009],[-64.571121,63.87082700000013],[-64.585556,63.84499400000004],[-64.57611099999986,63.780823]],[[-77.74388099999993,63.926658999999916],[-77.75334199999998,63.92555199999998],[-77.94860799999998,63.95082900000011],[-77.95695499999994,63.95388000000014],[-77.96694899999989,63.959160000000054],[-77.978882,63.96915400000006],[-77.98249799999996,63.97554800000006],[-77.98249799999996,63.983047000000056],[-77.97610500000002,63.99027300000006],[-77.95750399999997,64.00471500000003],[-77.950287,64.00915500000002],[-77.943604,64.01110799999998],[-77.92388900000003,64.01499900000005],[-77.88999899999999,64.01998900000007],[-77.77444500000001,64.0316620000001],[-77.75389099999995,64.03276100000011],[-77.64862099999999,64.03248600000006],[-77.59111000000001,64.03027299999997],[-77.55721999999997,64.02804600000007],[-77.54972799999996,64.02554300000008],[-77.54444899999999,64.02192700000006],[-77.54527300000001,64.0186000000001],[-77.62361099999998,63.997214999999926],[-77.62388599999991,63.99582700000002],[-77.62805200000003,63.991104000000064],[-77.63945000000001,63.981934000000024],[-77.68638599999997,63.95443700000004],[-77.72860699999995,63.932213000000104],[-77.73721299999988,63.928329000000076],[-77.74388099999993,63.926658999999916]],[[-89.80888400000003,64.05636600000008],[-89.81722999999994,64.05470300000013],[-89.82888799999989,64.05581699999993],[-89.839447,64.05886800000013],[-89.847778,64.06303400000007],[-89.86111499999998,64.07165500000013],[-89.86999500000002,64.08082600000012],[-89.87193300000001,64.08554100000015],[-89.86776700000001,64.09582499999999],[-89.85749800000002,64.0977630000001],[-89.83167999999989,64.09109499999994],[-89.82806399999993,64.08831800000007],[-89.81973299999993,64.08027600000008],[-89.80471799999998,64.0619200000001],[-89.80888400000003,64.05636600000008]],[[-64.962784,64.11080900000007],[-64.94860799999998,64.10971099999995],[-64.9036099999999,64.11109900000008],[-64.87110899999999,64.09915200000012],[-64.86944599999998,64.09664900000013],[-64.86999500000002,64.09332300000011],[-64.87332200000003,64.09082000000012],[-64.88444500000003,64.08665500000012],[-64.90556300000003,64.08221400000002],[-64.94665500000002,64.07887299999999],[-64.98889200000002,64.08137500000004],[-65.002228,64.08387800000003],[-65.02305599999994,64.08943200000004],[-65.04554699999994,64.09942600000005],[-65.05555699999996,64.10859699999997],[-65.05749500000002,64.11303700000002],[-65.05638099999993,64.11720300000007],[-65.05221599999993,64.12109399999997],[-65.03971899999993,64.12498500000004],[-65.02500900000001,64.12747200000013],[-65.01556399999993,64.12692299999998],[-64.99527,64.12303199999991],[-64.98999000000003,64.11859099999998],[-64.98083499999996,64.11526500000014],[-64.962784,64.11080900000007]],[[-64.491104,64.10914600000012],[-64.49999999999994,64.10803199999998],[-64.51139799999993,64.10832199999999],[-64.58750899999995,64.14749100000006],[-64.59249899999998,64.15193199999999],[-64.59527600000001,64.15498400000007],[-64.59584000000001,64.15664700000002],[-64.56777999999997,64.16360500000002],[-64.554169,64.16693100000003],[-64.52444499999996,64.16720600000002],[-64.51811199999992,64.16621400000002],[-64.50111400000003,64.16331499999995],[-64.45333900000003,64.14694200000008],[-64.450287,64.13026400000001],[-64.491104,64.10914600000012]],[[-73.176941,64.20027199999998],[-73.28277600000001,64.14332600000006],[-73.29194599999994,64.14387499999998],[-73.38639799999987,64.15887499999997],[-73.39695699999999,64.16110200000003],[-73.40167200000002,64.16554300000013],[-73.39472999999992,64.18775900000009],[-73.39306599999992,64.19247400000012],[-73.385559,64.19636500000001],[-73.30943300000001,64.19497700000011],[-73.20666499999999,64.21388200000007],[-73.18998699999992,64.21220399999993],[-73.17805499999997,64.209991],[-73.17332499999992,64.20526100000012],[-73.176941,64.20027199999998]],[[-81.47138999999999,64.18887300000006],[-81.493607,64.18830900000012],[-81.51611299999996,64.19053600000001],[-81.52778599999999,64.19413799999995],[-81.53666699999985,64.2086030000001],[-81.53805499999993,64.21804800000012],[-81.53222699999992,64.22303800000003],[-81.47000099999991,64.2394260000001],[-81.458618,64.23887600000006],[-81.41332999999997,64.23332200000004],[-81.39028899999994,64.22915599999993],[-81.378601,64.22554000000008],[-81.37582399999991,64.22082500000005],[-81.37499999999994,64.21582000000001],[-81.37887599999993,64.21192900000011],[-81.38890100000003,64.20498700000002],[-81.40527299999991,64.19470200000012],[-81.47138999999999,64.18887300000006]],[[-64.52027899999996,64.22026100000011],[-64.57640100000003,64.21054100000003],[-64.60166899999996,64.21249399999999],[-64.61193800000001,64.21582000000001],[-64.61944599999993,64.21971100000007],[-64.64695699999999,64.24414100000013],[-64.64778100000001,64.25000000000011],[-64.64361600000001,64.25582900000012],[-64.63751200000002,64.259995],[-64.62971500000003,64.26165800000012],[-64.57167099999992,64.26499899999999],[-64.557526,64.26486200000005],[-64.55305499999992,64.26332100000008],[-64.55221599999993,64.26165800000012],[-64.55249000000003,64.25665300000009],[-64.46806299999997,64.24331699999993],[-64.46472199999994,64.240814],[-64.46221899999995,64.23748799999993],[-64.464447,64.234421],[-64.471115,64.23165900000009],[-64.52027899999996,64.22026100000011]],[[-75.55139200000002,64.30386399999998],[-75.69193999999999,64.30247500000013],[-75.702225,64.3058170000001],[-75.70889299999999,64.31526200000013],[-75.70584099999996,64.34193400000004],[-75.69665500000002,64.35108900000012],[-75.68638599999991,64.35331700000006],[-75.665009,64.35081500000001],[-75.57888799999995,64.34609999999998],[-75.57278400000001,64.34498599999995],[-75.50250199999994,64.31971699999997],[-75.493607,64.3163760000001],[-75.50111400000003,64.313309],[-75.51112399999994,64.31109600000008],[-75.55139200000002,64.30386399999998]],[[-64.93859899999995,64.23553500000003],[-64.98916599999995,64.20915200000002],[-65.00306699999993,64.21026599999999],[-65.04861499999998,64.218323],[-65.05277999999998,64.21943699999997],[-65.0599979999999,64.22331200000013],[-65.06555199999997,64.22747800000002],[-65.073059,64.24054000000007],[-65.10249299999998,64.29637100000014],[-65.10916099999997,64.31080600000007],[-65.11389200000002,64.32360800000004],[-65.11471599999999,64.32943700000004],[-65.11416600000001,64.33499100000006],[-65.112503,64.33970600000009],[-65.11000100000001,64.34359699999999],[-65.10166900000002,64.34637499999997],[-65.08944699999995,64.349716],[-65.02888499999989,64.36109900000002],[-65.02139299999993,64.36248799999998],[-65.01028399999996,64.36164900000006],[-65.006393,64.36053500000008],[-65.00195299999996,64.35693400000002],[-64.99888599999997,64.35443100000003],[-64.98222399999997,64.333054],[-64.88473499999992,64.28776600000009],[-64.88612399999994,64.28305100000006],[-64.89083899999997,64.27638200000001],[-64.92694099999994,64.24247700000006],[-64.93859899999995,64.23553500000003]],[[-73.87638900000002,64.301376],[-73.88362099999995,64.29887400000007],[-73.95167499999997,64.30497700000001],[-73.96556099999998,64.30664100000007],[-73.97250399999996,64.30970799999994],[-73.97444200000001,64.313309],[-73.96028100000001,64.36219799999998],[-73.95666499999993,64.36831700000005],[-73.95249899999993,64.3708190000001],[-73.94221499999992,64.37275700000004],[-73.93221999999992,64.37359600000002],[-73.91833500000001,64.37191800000005],[-73.90943899999996,64.36998000000011],[-73.88917500000002,64.35971100000012],[-73.87916599999994,64.35192899999998],[-73.87416099999996,64.34332300000005],[-73.87332200000003,64.30525200000005],[-73.87638900000002,64.301376]],[[-73.69776899999988,64.26998900000007],[-73.70472699999993,64.26887500000004],[-73.72084000000001,64.27276599999993],[-73.75389100000001,64.28276100000005],[-73.77667199999996,64.29470800000001],[-73.82333399999999,64.32470700000005],[-73.833618,64.33166500000004],[-73.781387,64.40554799999995],[-73.77610800000002,64.40748600000012],[-73.76556399999998,64.40942400000006],[-73.74916100000002,64.41026299999999],[-73.74444599999998,64.405823],[-73.73083500000001,64.38638300000002],[-73.729172,64.38610799999998],[-73.726944,64.38333100000006],[-73.72444199999995,64.37747200000007],[-73.70249899999999,64.32276900000011],[-73.69915799999995,64.31414799999999],[-73.69055200000003,64.27693200000004],[-73.691666,64.27360500000009],[-73.69444299999992,64.27110300000004],[-73.69776899999988,64.26998900000007]],[[-64.84973099999996,64.30748],[-64.86138899999997,64.30748],[-64.87721299999998,64.313309],[-64.88806199999999,64.32110599999999],[-64.93777499999999,64.36164900000006],[-64.94499200000001,64.37052900000009],[-64.95556599999998,64.38388099999992],[-64.95973200000003,64.39721700000007],[-64.958618,64.405823],[-64.95167499999991,64.41137699999996],[-64.94665500000002,64.41360500000013],[-64.93249500000002,64.41748000000013],[-64.92527799999999,64.4185940000001],[-64.91000400000001,64.41665599999999],[-64.90249599999999,64.41276600000015],[-64.89750700000002,64.40860000000009],[-64.82000700000003,64.37942500000003],[-64.77194199999997,64.34887700000002],[-64.77055399999995,64.3458250000001],[-64.773056,64.34248400000007],[-64.84973099999996,64.30748]],[[-74.27194199999991,64.41360500000013],[-74.28500400000001,64.41304000000008],[-74.35749799999996,64.42109700000009],[-74.37721299999998,64.4244230000001],[-74.42332499999998,64.44386300000008],[-74.43720999999994,64.45027199999993],[-74.439438,64.45332300000013],[-74.33860800000002,64.49470500000001],[-74.33167999999995,64.49693300000013],[-74.31040999999999,64.49884000000003],[-74.28527799999995,64.48165900000004],[-74.22860700000001,64.45109600000006],[-74.20584100000002,64.44747899999993],[-74.18306000000001,64.44303900000011],[-74.17332499999992,64.43914800000005],[-74.174713,64.43498199999999],[-74.17832899999996,64.43386799999996],[-74.27194199999991,64.41360500000013]],[[-73.74499500000002,64.42608600000005],[-73.75834699999996,64.42553700000008],[-73.77806099999998,64.428314],[-73.781387,64.43193100000013],[-73.78277600000001,64.43748499999992],[-73.78250099999997,64.44247400000006],[-73.77610800000002,64.49581899999998],[-73.77389499999998,64.501938],[-73.77333099999993,64.50332600000007],[-73.74691799999994,64.50851399999999],[-73.73666400000002,64.50721699999997],[-73.729172,64.50526400000007],[-73.72416699999985,64.50221300000004],[-73.67304999999999,64.46971100000002],[-73.66861,64.46443200000004],[-73.66833499999996,64.46026599999993],[-73.67193600000002,64.45582600000012],[-73.67971799999998,64.45220899999998],[-73.72721899999993,64.4310910000001],[-73.73500100000001,64.42804000000007],[-73.74499500000002,64.42608600000005]],[[-74.212784,64.483047],[-74.22332799999998,64.48027000000008],[-74.22917199999995,64.48136900000003],[-74.30749500000002,64.51609800000011],[-74.33111600000001,64.52665699999994],[-74.33750899999995,64.53109699999999],[-74.35777300000001,64.54693600000007],[-74.35777300000001,64.55108600000011],[-74.353882,64.55358900000004],[-74.34555099999994,64.555252],[-74.25306699999999,64.54803500000008],[-74.24055499999997,64.54637100000008],[-74.23611499999998,64.5455320000001],[-74.16972399999997,64.52388000000008],[-74.16944899999993,64.51971400000014],[-74.20666499999999,64.48637400000007],[-74.212784,64.483047]],[[-73.55749500000002,64.31275899999997],[-73.57778899999994,64.3099820000001],[-73.60166900000002,64.31025700000009],[-73.6263889999999,64.31275899999997],[-73.650284,64.31721500000009],[-73.65556300000003,64.320267],[-73.65833999999995,64.33499100000006],[-73.66953299999989,64.42684900000012],[-73.61044299999998,64.47048999999998],[-73.68249499999996,64.50972000000013],[-73.67999299999991,64.526093],[-73.67777999999993,64.53221100000013],[-73.66665599999988,64.53553800000009],[-73.577225,64.55998200000005],[-73.53721599999994,64.56776400000001],[-73.52778599999999,64.56694000000005],[-73.521118,64.56303400000013],[-73.50917099999998,64.55247500000007],[-73.50472999999994,64.54248000000001],[-73.50306699999993,64.53414900000007],[-73.48916599999995,64.46331800000007],[-73.48805199999998,64.453598],[-73.48832699999997,64.44386300000008],[-73.49027999999993,64.43914800000005],[-73.55526699999996,64.31469700000014],[-73.55749500000002,64.31275899999997]],[[-65.49276700000001,64.51776100000001],[-65.65833999999995,64.50972000000013],[-65.66944899999993,64.51026900000011],[-65.67971799999998,64.51220700000005],[-65.68611099999993,64.51527399999998],[-65.68971299999998,64.51998900000001],[-65.69027699999992,64.52415500000006],[-65.68971299999998,64.52998400000007],[-65.686935,64.53887900000012],[-65.67250099999995,64.56053200000008],[-65.660278,64.57388300000002],[-65.65110800000002,64.58055100000001],[-65.61582900000002,64.599152],[-65.56332399999991,64.61554000000007],[-65.55444299999999,64.6185910000001],[-65.54695100000004,64.62248199999999],[-65.44915800000001,64.67886399999998],[-65.44387799999993,64.684708],[-65.43582200000003,64.69636500000013],[-65.38194299999992,64.71693400000004],[-65.29249599999997,64.73553500000008],[-65.25695799999994,64.70999100000006],[-65.25250199999994,64.70637500000004],[-65.25805700000001,64.70082100000002],[-65.26640299999991,64.6933140000001],[-65.24999999999989,64.66360500000008],[-65.208054,64.63970899999998],[-65.208618,64.63136300000008],[-65.21389799999992,64.62608300000005],[-65.22805799999992,64.6202550000001],[-65.30943300000001,64.60054000000008],[-65.42027299999995,64.55442800000003],[-65.45278899999994,64.532761],[-65.45083599999992,64.52832000000006],[-65.45361300000002,64.524429],[-65.460556,64.52110299999998],[-65.468887,64.51915000000002],[-65.49276700000001,64.51776100000001]],[[-63.35333300000002,64.99498000000011],[-63.34916700000002,64.99165299999999],[-63.34722099999999,64.99192799999997],[-63.330558999999994,64.9869230000001],[-63.257506999999976,64.92942800000003],[-63.25639299999989,64.92637600000012],[-63.258895999999936,64.92109700000015],[-63.27305599999994,64.91804500000006],[-63.28138699999994,64.91832000000005],[-63.37777699999998,64.94081100000005],[-63.385276999999974,64.94413800000001],[-63.39388999999994,64.951096],[-63.417220999999984,64.97137499999991],[-63.420279999999934,64.97608900000006],[-63.420279999999934,64.978317],[-63.41889200000003,64.98248300000012],[-63.415549999999996,64.9869230000001],[-63.395279000000016,64.99552900000003],[-63.37610599999999,64.99887100000001],[-63.36361699999998,64.99720800000006],[-63.35333300000002,64.99498000000011]],[[-63.24361399999992,65.25499000000013],[-63.25139599999994,65.25387599999999],[-63.25666799999999,65.25610400000011],[-63.310554999999965,65.29054299999996],[-63.313331999999946,65.29386900000003],[-63.31166799999994,65.29803500000008],[-63.3066639999999,65.30247500000013],[-63.25778199999996,65.32083100000011],[-63.244445999999925,65.32276900000005],[-63.23666399999996,65.32165500000008],[-63.22721899999999,65.31387300000011],[-63.166388999999924,65.28610200000008],[-63.16583300000002,65.282486],[-63.16666399999997,65.27915999999999],[-63.23527499999989,65.25694300000009],[-63.24361399999992,65.25499000000013]],[[-66.92471299999994,65.28442400000012],[-66.93388399999998,65.28332499999999],[-66.96250900000001,65.28359999999998],[-66.97694399999995,65.28442400000012],[-66.98916600000001,65.28637700000007],[-66.99110399999995,65.28887899999995],[-67.01112399999994,65.31915300000003],[-67.01194800000002,65.3230440000001],[-67.010559,65.33332800000011],[-67.00500499999993,65.33970600000009],[-66.99221799999992,65.34610000000009],[-66.97444199999995,65.35054000000014],[-66.9324949999999,65.3580320000001],[-66.92027300000001,65.35859700000009],[-66.91082799999987,65.35693399999997],[-66.908615,65.355255],[-66.90805099999994,65.35108900000006],[-66.90943900000002,65.34610000000009],[-66.91194200000001,65.34220900000003],[-66.92027300000001,65.29443400000002],[-66.92138699999998,65.28970300000009],[-66.92471299999994,65.28442400000012]],[[-89.00556899999992,65.38554400000004],[-89.01750199999998,65.38554400000004],[-89.03028899999998,65.38749699999994],[-89.07611099999997,65.39471400000008],[-89.10028099999988,65.40081800000007],[-89.09999099999993,65.40582299999994],[-89.09167499999995,65.40832500000005],[-89.06806899999998,65.40832500000005],[-89.03195199999999,65.40721100000007],[-89.01861599999995,65.40332000000001],[-89.00944500000003,65.39915500000001],[-89.00527999999991,65.39553800000004],[-89.00306699999999,65.39054900000008],[-89.00556899999992,65.38554400000004]],[[-88.43028299999992,65.45526100000006],[-88.46501199999989,65.45359799999994],[-88.48999000000003,65.45665000000008],[-88.50361599999991,65.46054100000015],[-88.51028400000001,65.46499599999999],[-88.51222200000001,65.46971100000002],[-88.50750699999998,65.47499100000005],[-88.49638399999998,65.47692899999998],[-88.48500100000001,65.47776799999997],[-88.46112099999999,65.47747800000013],[-88.42416399999996,65.47442600000005],[-88.39862099999988,65.47026100000005],[-88.39416499999993,65.46582000000012],[-88.39973399999997,65.46138000000008],[-88.42138699999998,65.45694000000009],[-88.43028299999992,65.45526100000006]],[[-62.79500599999989,65.51998899999995],[-62.80444299999999,65.51915000000002],[-62.81945000000002,65.52415500000006],[-62.82695000000001,65.52804600000013],[-62.89388999999994,65.5811000000001],[-62.89555399999995,65.58554100000003],[-62.89555399999995,65.58998100000002],[-62.88972499999994,65.599152],[-62.88444499999997,65.60554500000012],[-62.87471800000003,65.61360200000007],[-62.8663939999999,65.61747700000006],[-62.85639200000003,65.61914100000007],[-62.84972399999998,65.61886600000008],[-62.84277300000002,65.616379],[-62.83805100000001,65.61360200000007],[-62.834998999999925,65.60664400000013],[-62.834998999999925,65.60470599999996],[-62.83000199999998,65.59304800000012],[-62.82444800000002,65.58526599999999],[-62.817504999999926,65.578598],[-62.81027999999998,65.57470699999993],[-62.78556099999997,65.5641480000001],[-62.76500699999997,65.55748000000011],[-62.750838999999985,65.55137600000006],[-62.78889499999997,65.52331500000003],[-62.79500599999989,65.51998899999995]],[[-83.88276699999994,65.66693100000009],[-83.89388999999994,65.66470300000015],[-83.90638699999994,65.66693100000009],[-83.93749999999994,65.67719999999991],[-83.94305400000002,65.68193100000008],[-83.94221499999998,65.68692000000004],[-83.93638599999997,65.69192500000008],[-83.92832899999996,65.69720500000011],[-83.896118,65.71026600000005],[-83.88473499999998,65.71276900000004],[-83.87277199999994,65.71220399999999],[-83.86444099999994,65.707764],[-83.86888099999999,65.69693000000012],[-83.87138400000003,65.68692000000004],[-83.87693799999994,65.67221099999995],[-83.88276699999994,65.66693100000009]],[[-67.47250400000001,65.70526100000001],[-67.55972300000002,65.7022090000001],[-67.58473199999997,65.70359800000011],[-67.64056399999993,65.69609100000014],[-67.69137599999993,65.68580600000001],[-67.70140100000003,65.68609600000008],[-67.70695499999994,65.68803400000002],[-67.71389799999986,65.69664000000012],[-67.71583599999997,65.70165999999995],[-67.71333299999992,65.70555100000001],[-67.69583099999988,65.7208250000001],[-67.658615,65.72526600000003],[-67.57749899999999,65.73165899999998],[-67.52917500000001,65.73498500000005],[-67.49999999999994,65.73498500000005],[-67.48971599999993,65.73498500000005],[-67.42443800000001,65.73526000000004],[-67.44694499999991,65.71859699999999],[-67.47250400000001,65.70526100000001]],[[-62.268332999999984,65.70165999999995],[-62.25944500000003,65.69970700000005],[-62.23805199999998,65.70248400000008],[-62.22110700000002,65.7080380000001],[-62.20416999999992,65.71165500000006],[-62.186385999999914,65.711929],[-62.16777799999994,65.70277399999992],[-62.131667999999934,65.67886399999998],[-62.12833399999994,65.67414900000011],[-62.13194299999998,65.65721100000002],[-62.135276999999974,65.65138200000001],[-62.14222699999999,65.64498900000001],[-62.19499999999999,65.61276200000003],[-62.20249899999999,65.61025999999998],[-62.21500400000002,65.60998499999994],[-62.22444200000001,65.61109899999997],[-62.29695099999998,65.6249850000001],[-62.45500199999998,65.65998800000011],[-62.46610999999996,65.66387900000001],[-62.483886999999925,65.72109999999992],[-62.48444399999994,65.72692899999998],[-62.483611999999994,65.73165899999998],[-62.48055299999987,65.73776199999992],[-62.47360999999995,65.74192800000003],[-62.46832999999998,65.74414099999996],[-62.46194499999996,65.74525499999999],[-62.28388999999993,65.74443100000002],[-62.27194199999991,65.74414099999996],[-62.260283999999956,65.74331699999999],[-62.25250199999999,65.74192800000003],[-62.251396,65.7391510000001],[-62.25861399999991,65.72859200000005],[-62.27027899999996,65.72303800000009],[-62.29750100000001,65.70860299999998],[-62.268332999999984,65.70165999999995]],[[-83.28388999999993,65.83415200000013],[-83.29222099999993,65.82887299999999],[-83.30360399999995,65.82638500000002],[-83.31555199999997,65.82609600000006],[-83.32749899999993,65.82748399999997],[-83.34777799999989,65.83248900000007],[-83.39527900000002,65.8316650000001],[-83.40666199999998,65.83027600000008],[-83.41805999999997,65.82777400000003],[-83.42916899999994,65.82443200000006],[-83.43998699999992,65.81915300000009],[-83.45639,65.80886799999996],[-83.47332799999998,65.80026200000003],[-83.48527499999994,65.80081200000006],[-83.49804699999993,65.80415299999993],[-83.52972399999999,65.81748999999996],[-83.55915799999997,65.83110000000005],[-83.57556199999993,65.83998099999997],[-83.58167999999989,65.84471100000002],[-83.58500700000002,65.84942600000005],[-83.58612099999999,65.8541560000001],[-83.58029199999999,65.85942099999994],[-83.57167099999998,65.86248800000004],[-83.56027199999994,65.86499000000015],[-83.52528399999989,65.8683170000001],[-83.47805800000003,65.87025500000004],[-83.44249000000002,65.87081899999998],[-83.36999499999996,65.86665300000004],[-83.345551,65.863876],[-83.33306900000002,65.8602600000001],[-83.29110699999995,65.84359700000005],[-83.28527799999995,65.83888200000001],[-83.28388999999993,65.83415200000013]],[[-65.64584399999995,65.81303400000007],[-65.656387,65.81275900000003],[-65.660278,65.81971700000003],[-65.65499899999992,65.86943100000008],[-65.65167199999996,65.87664799999999],[-65.64778100000001,65.879974],[-65.63612399999988,65.88638300000008],[-65.62388599999991,65.8913730000001],[-65.58306900000002,65.90277100000014],[-65.54276999999996,65.9080350000001],[-65.53167699999995,65.90887499999997],[-65.51611299999996,65.90637199999998],[-65.51139799999993,65.90304600000013],[-65.5122219999999,65.89444000000003],[-65.51333599999998,65.89054899999996],[-65.52806099999998,65.85942099999994],[-65.55943300000001,65.83471700000001],[-65.64584399999995,65.81303400000007]],[[-85.48055999999997,65.79193099999998],[-85.46806299999997,65.790817],[-85.45638999999994,65.79136700000004],[-85.44526699999994,65.79386900000009],[-85.42416400000002,65.8019260000001],[-85.41389500000002,65.80748000000006],[-85.40834000000001,65.8124850000001],[-85.40499899999998,65.81748999999996],[-85.40417500000001,65.822495],[-85.39306599999986,65.83276400000005],[-85.38194299999998,65.83526599999993],[-85.36999500000002,65.83499100000012],[-85.333328,65.83221400000002],[-85.31361399999992,65.83027600000008],[-85.28860500000002,65.82666],[-85.26306199999999,65.82110600000004],[-85.21362299999998,65.80802900000003],[-85.20278899999994,65.80358899999999],[-85.18582200000003,65.79470800000007],[-85.1625059999999,65.78137200000009],[-85.15638699999994,65.77665700000006],[-85.04916400000002,65.621643],[-85.04777499999994,65.61692800000014],[-85.04861499999998,65.6119230000001],[-85.05166600000001,65.60693400000014],[-85.06750499999993,65.59637500000008],[-85.08805799999999,65.58554100000003],[-85.12027,65.574997],[-85.14222699999993,65.56999200000013],[-85.17582700000003,65.56330900000012],[-85.23222399999992,65.55470300000002],[-85.24360699999994,65.55386400000009],[-85.26777600000003,65.555542],[-85.28056300000003,65.55802900000009],[-85.29194599999988,65.55720500000012],[-85.30249000000003,65.55276500000008],[-85.30777,65.54776000000004],[-85.31111099999993,65.54247999999995],[-85.311935,65.53776600000003],[-85.308044,65.533051],[-85.29583699999995,65.52388000000002],[-85.271118,65.51165800000007],[-85.24082900000002,65.49832200000009],[-85.20417800000001,65.48580900000002],[-85.16555799999998,65.47499100000005],[-85.12777699999992,65.46609500000011],[-85.08860800000002,65.45359799999994],[-85.04360999999994,65.43637100000012],[-85.02694699999995,65.42747500000002],[-85.015015,65.41831999999994],[-85.01112399999994,65.41360500000008],[-85.00279199999994,65.40138200000007],[-85.00140399999992,65.39665200000002],[-85.00500499999998,65.37692300000009],[-85.01167299999997,65.35220300000003],[-84.93055700000002,65.21415700000006],[-84.924713,65.20971700000001],[-84.912216,65.2063750000001],[-84.90028399999994,65.2061000000001],[-84.83250399999997,65.2124940000001],[-84.82139599999988,65.21388200000001],[-84.810272,65.216385],[-84.80027799999999,65.22164900000001],[-84.79249600000003,65.22692900000004],[-84.74804699999999,65.29275500000006],[-84.74694799999997,65.29748500000005],[-84.7497249999999,65.30720499999995],[-84.75500499999987,65.31666600000011],[-84.76222199999995,65.326096],[-84.761124,65.33109999999999],[-84.75805699999995,65.33610500000003],[-84.75472999999994,65.34109500000005],[-84.745834,65.35137900000007],[-84.74027999999998,65.35636899999997],[-84.59583999999995,65.47554000000002],[-84.58555599999994,65.48109399999998],[-84.573624,65.48165900000004],[-84.56193499999995,65.48109399999998],[-84.54943799999995,65.47886699999998],[-84.44027699999992,65.45665000000008],[-84.43222000000003,65.45332300000013],[-84.42639200000002,65.44859300000007],[-84.424713,65.44386300000008],[-84.42582699999997,65.438873],[-84.314438,65.38165300000014],[-84.291946,65.37692300000009],[-84.16139199999992,65.34193400000004],[-84.15110799999991,65.338593],[-84.14750700000002,65.33387800000014],[-84.15306099999992,65.32859800000006],[-84.19415300000003,65.29748500000005],[-84.20195000000001,65.29220600000008],[-84.22083999999995,65.28471399999995],[-84.228882,65.2794340000001],[-84.23083499999996,65.26944000000009],[-84.22972099999998,65.26470899999998],[-84.141388,65.21998600000006],[-84.08833300000003,65.20387300000004],[-83.89999399999999,65.16554300000007],[-83.87609899999995,65.16276600000003],[-83.85278299999993,65.161652],[-83.66694599999994,65.16081199999996],[-83.62054399999994,65.16081199999996],[-83.54028299999993,65.16415400000011],[-83.52806099999998,65.16192599999994],[-83.408615,65.1355440000001],[-83.38806199999993,65.12664799999993],[-83.37887599999999,65.11720300000007],[-83.33805799999999,65.07470700000005],[-83.33473200000003,65.06999200000001],[-83.33583099999993,65.06498699999997],[-83.339447,65.0599820000001],[-83.34306300000003,65.04525800000005],[-83.34083599999997,65.03553799999997],[-83.33084099999996,65.02137800000008],[-83.31945799999994,65.0122070000001],[-83.20805399999995,64.94552600000009],[-83.19804399999987,64.9410860000001],[-83.19055200000003,64.93942300000015],[-83.156387,64.93997200000007],[-83.00500499999993,64.91303999999997],[-82.9927669999999,64.90971400000012],[-82.86582899999996,64.87359600000008],[-82.85583499999996,64.86914100000007],[-82.848053,64.86442600000004],[-82.84249899999992,64.85998500000011],[-82.82972699999999,64.84081999999995],[-82.82861300000002,64.83610499999992],[-82.825287,64.8313750000001],[-82.81639099999995,64.82193000000001],[-82.80027799999999,64.80886800000002],[-82.77000399999997,64.79553200000004],[-82.75778200000002,64.79109200000005],[-82.70916699999998,64.77638200000007],[-82.69722000000002,64.77388000000002],[-82.56973299999993,64.76388500000007],[-82.36138899999997,64.76361099999997],[-82.34944200000001,64.76026900000005],[-82.21194499999996,64.71832300000005],[-82.20222499999988,64.71360800000002],[-82.20333900000003,64.70860299999998],[-82.20916699999998,64.70359800000011],[-82.21749899999998,64.69859300000007],[-82.20361299999996,64.684418],[-82.064438,64.64860500000009],[-81.93249500000002,64.58442700000006],[-81.76306199999999,64.50109900000007],[-81.75389099999995,64.48692300000005],[-81.75140399999998,64.47248800000011],[-81.75306699999999,64.35582000000005],[-81.76417499999997,64.34109500000011],[-81.77000399999997,64.33610500000003],[-81.777222,64.326096],[-81.778885,64.32110599999999],[-81.777222,64.31164600000011],[-81.77416999999997,64.30664100000007],[-81.74888599999997,64.27360500000009],[-81.72721899999993,64.258331],[-81.712784,64.25000000000011],[-81.702789,64.2452550000001],[-81.66972399999997,64.2327580000001],[-81.646118,64.22554000000008],[-81.62249800000001,64.21666000000005],[-81.61305199999998,64.21220399999993],[-81.60028099999994,64.20277400000009],[-81.59445199999993,64.19331399999999],[-81.59083599999997,64.18359400000008],[-81.58999599999993,64.17886400000009],[-81.60249299999998,64.129974],[-81.61082499999998,64.125809],[-81.71777299999997,64.09942600000005],[-81.758621,64.08943200000004],[-81.76916499999993,64.08804300000003],[-81.82444799999996,64.08638000000008],[-81.87916599999994,64.08082600000012],[-81.95584099999996,64.0619200000001],[-81.96417199999996,64.0577550000001],[-81.97000099999997,64.05276500000002],[-81.97361799999993,64.04775999999998],[-81.99916099999996,64.00332600000002],[-81.99638400000003,63.998604000000114],[-81.98693800000001,63.994155999999975],[-81.97500599999995,63.99054699999999],[-81.96389799999997,63.98888400000004],[-81.95249899999993,63.98832700000014],[-81.93055699999996,63.98804500000006],[-81.89750700000002,63.98999000000009],[-81.87582399999991,63.991661000000136],[-81.56082200000003,64.02943399999998],[-81.44027699999998,64.06776400000007],[-81.38362099999995,64.09054600000002],[-81.28778099999988,64.08027600000008],[-81.27639799999997,64.07748399999997],[-81.27000399999991,64.072495],[-81.26417499999997,64.06275900000003],[-81.256958,64.059143],[-81.245544,64.05554200000012],[-80.96472199999994,63.99193600000012],[-80.94248999999996,63.99054699999999],[-80.931671,63.99193600000012],[-80.920837,63.99499500000013],[-80.91027799999989,63.999161000000015],[-80.90666199999993,64.00416600000005],[-80.90333599999997,64.01388500000007],[-80.90916399999998,64.02331500000014],[-80.91416899999996,64.02804600000007],[-80.92582699999997,64.03276100000011],[-80.94860799999998,64.03887900000007],[-80.96749899999992,64.04803499999997],[-80.972778,64.05276500000002],[-80.97555499999999,64.0577550000001],[-80.97389199999998,64.0624850000001],[-80.93582199999997,64.11192300000005],[-80.89083899999997,64.11554000000001],[-80.81221,64.09109499999994],[-80.77749599999987,64.0794370000001],[-80.73472600000002,64.0541530000001],[-80.56610099999995,63.994155999999975],[-80.54333500000001,63.98777000000007],[-80.531677,63.983330000000024],[-80.52250700000002,63.97860000000003],[-80.51750199999998,63.973877000000016],[-80.48832700000003,63.91054500000001],[-80.49221799999998,63.90554800000007],[-80.50306699999999,63.90248900000012],[-80.56750499999993,63.88943500000005],[-80.45306399999993,63.85943600000002],[-80.36305199999993,63.841102999999976],[-80.21722399999999,63.80998999999997],[-80.194481,63.804474000000084],[-80.18998699999997,63.799995000000024],[-80.17471299999988,63.780823],[-80.17222599999997,63.77610000000004],[-80.17166099999997,63.771102999999925],[-80.17887899999988,63.75666000000007],[-80.18499800000001,63.75166300000012],[-80.19583099999988,63.748604],[-80.34695399999998,63.72804299999996],[-80.35777299999995,63.728600000000085],[-80.36915599999998,63.73333000000008],[-80.38027999999997,63.73499300000003],[-80.39138799999995,63.73499300000003],[-80.402222,63.73471799999999],[-80.43443300000001,63.731102000000135],[-80.45417800000001,63.72776799999997],[-80.485275,63.71554600000002],[-80.493607,63.710274000000084],[-80.50473,63.69082600000013],[-80.506393,63.685822000000144],[-80.51000999999997,63.68110700000011],[-80.52194199999991,63.67110400000007],[-80.587784,63.635826000000066],[-80.60888699999998,63.628326000000015],[-80.77444500000001,63.57332600000012],[-80.912216,63.526381999999955],[-80.92250100000001,63.52137800000003],[-80.93055700000002,63.51610600000009],[-80.93638599999991,63.51110800000009],[-80.93804899999986,63.50638600000002],[-80.9375,63.501389000000074],[-80.93443300000001,63.49665800000014],[-80.93055700000002,63.482208000000014],[-80.93028299999997,63.47748600000011],[-80.9375,63.46749100000005],[-80.95805399999995,63.45832800000005],[-80.968613,63.455269000000044],[-80.989441,63.450829000000056],[-81.011124,63.44915800000001],[-81.03277599999996,63.44860100000011],[-81.05444299999999,63.44915800000001],[-81.07640100000003,63.451385000000016],[-81.11000099999995,63.45832800000005],[-81.38612399999994,63.526381999999955],[-81.69415300000003,63.607498000000135],[-81.73416099999997,63.62554900000009],[-81.75723299999999,63.63472000000007],[-81.76889,63.63804600000009],[-81.77999899999998,63.63971700000013],[-81.80194099999994,63.64110599999998],[-81.823624,63.639435000000105],[-81.85527000000002,63.63249200000007],[-81.87666299999995,63.62999000000002],[-81.88751200000002,63.62943300000012],[-81.90972899999991,63.631935],[-81.99527,63.66110200000014],[-82.01167299999986,63.667213000000004],[-82.02639799999997,63.676383999999985],[-82.03138699999994,63.68110700000011],[-82.04110700000001,63.685822000000144],[-82.05249000000003,63.68915600000014],[-82.06361400000003,63.69082600000013],[-82.10777299999995,63.69221499999992],[-82.12943999999999,63.69165800000002],[-82.21417200000002,63.68776699999995],[-82.22471599999989,63.68637799999999],[-82.285553,63.67804700000005],[-82.29611199999994,63.67471300000011],[-82.29943799999995,63.669715999999994],[-82.29888900000003,63.66499299999998],[-82.30221599999999,63.65998799999994],[-82.30776999999995,63.65499100000005],[-82.31834400000002,63.65165700000006],[-82.32888799999995,63.65026899999998],[-82.33999599999987,63.65082600000005],[-82.35139500000002,63.65332000000001],[-82.47222899999991,63.68027500000005],[-82.48388699999998,63.68471500000004],[-82.4911039999999,63.68915600000014],[-82.535278,63.72637899999995],[-82.54583699999995,63.7355500000001],[-82.54972800000002,63.745270000000005],[-82.55082700000003,63.75000000000006],[-82.54695100000004,63.76471700000002],[-82.54333499999996,63.769714000000135],[-82.53222699999998,63.77999100000011],[-82.51445000000001,63.79027600000006],[-82.504456,63.795547000000056],[-82.48416099999997,63.804993000000024],[-82.47361799999993,63.80832700000002],[-82.43194599999998,63.82027399999998],[-82.420837,63.820831000000055],[-82.40972899999997,63.81916000000001],[-82.39805599999988,63.815826000000015],[-82.38667299999997,63.814156000000025],[-82.37638900000002,63.81749700000006],[-82.372772,63.82249500000006],[-82.35388199999994,63.852219000000105],[-82.35139500000002,63.861938000000066],[-82.35833699999995,63.90054300000003],[-82.36138899999997,63.90526599999998],[-82.36888099999999,63.90998800000011],[-82.37832599999996,63.91443600000008],[-82.41389499999997,63.926941],[-82.52583300000003,63.96610300000003],[-82.54888899999997,63.96915400000006],[-82.82861300000002,63.979431000000034],[-82.96722399999999,63.96554600000013],[-82.97805800000003,63.96305100000012],[-83.06416299999995,63.95193499999999],[-83.08694499999996,63.95499400000011],[-83.09889199999992,63.959160000000054],[-83.12388599999997,63.97276300000004],[-83.12916599999994,63.977486000000056],[-83.14527900000002,64.00109900000012],[-83.139725,64.006104],[-83.09555099999989,64.02832000000001],[-83.029449,64.0747070000001],[-83.01611300000002,64.08499100000012],[-82.99694799999997,64.10026600000009],[-82.98028599999998,64.11554000000001],[-82.97084000000001,64.12553400000002],[-82.9619449999999,64.13581800000003],[-82.960556,64.14054899999996],[-82.96166999999997,64.1455380000001],[-82.964722,64.15026900000004],[-83.00834699999996,64.18748499999998],[-83.01972999999998,64.18887300000006],[-83.07278399999996,64.18664600000005],[-83.10526999999996,64.18165599999998],[-83.12638899999996,64.17581199999995],[-83.15722700000003,64.16304000000014],[-83.339447,64.13472000000013],[-83.48832700000003,64.12248200000005],[-83.51972999999998,64.11442599999998],[-83.53028899999993,64.11109900000008],[-83.54834,64.10247800000013],[-83.67332499999998,64.01721200000003],[-83.68222000000003,64.00721700000008],[-83.68331899999998,64.00221299999993],[-83.67666600000001,63.99276699999996],[-83.66583300000002,63.98360399999996],[-83.64250199999998,63.96998600000012],[-83.62609900000001,63.95609999999999],[-83.608612,63.93749200000008],[-83.60555999999997,63.932770000000005],[-83.60417199999995,63.92804700000005],[-83.5958399999999,63.825829000000056],[-83.59666400000003,63.820831000000055],[-83.62304699999993,63.78166199999998],[-83.63194299999986,63.77166],[-83.63722200000001,63.76638800000006],[-83.64750700000002,63.763054000000125],[-83.65861499999994,63.763611000000026],[-83.67027299999995,63.76693700000004],[-83.69444299999998,63.77582600000011],[-83.718613,63.77999100000011],[-83.74055499999997,63.77999100000011],[-83.75083899999998,63.776657000000114],[-83.82417299999997,63.74749000000003],[-84.00723299999999,63.66805300000004],[-84.01278699999989,63.662765999999976],[-84.02111799999994,63.65277100000003],[-84.02749599999993,63.642769000000044],[-84.05027799999993,63.62693800000011],[-84.069458,63.61638600000009],[-84.079453,63.61193800000012],[-84.089447,63.60777300000012],[-84.09973100000002,63.60527000000013],[-84.11000099999995,63.60360700000007],[-84.12138399999998,63.60416399999997],[-84.132767,63.60665899999998],[-84.14472999999992,63.610825000000034],[-84.162216,63.61971300000005],[-84.17416400000002,63.62304700000004],[-84.19638099999992,63.62499200000002],[-84.261124,63.62082700000002],[-84.28611799999999,63.615546999999935],[-84.38806199999999,63.55915800000008],[-84.39527900000002,63.55387900000011],[-84.40055799999999,63.548607000000004],[-84.44638099999997,63.488045],[-84.44943199999989,63.483047],[-84.45222499999994,63.47248800000011],[-84.44722000000002,63.45332300000001],[-84.44915799999995,63.44360399999999],[-84.47749299999998,63.3836060000001],[-84.56332399999997,63.33749400000005],[-84.754456,63.26416000000006],[-84.77417000000003,63.25721700000008],[-84.79388399999999,63.25027499999999],[-84.823059,63.23721300000011],[-84.841949,63.22721100000001],[-84.870834,63.214157000000114],[-84.89056399999998,63.20721400000008],[-85.14334100000002,63.13999200000006],[-85.22416699999997,63.12082700000013],[-85.24499500000002,63.11859899999996],[-85.26640299999997,63.11749300000014],[-85.28805499999999,63.11832400000014],[-85.34333800000002,63.12276500000007],[-85.37582399999991,63.123877999999934],[-85.39695699999993,63.12276500000007],[-85.44915800000001,63.11666100000002],[-85.48222399999997,63.11859899999996],[-85.49333199999995,63.119987000000094],[-85.50500499999998,63.12304699999993],[-85.53639199999992,63.134995],[-85.54388399999993,63.138329],[-85.57778899999994,63.16554300000013],[-85.58917199999996,63.174713],[-85.59249899999998,63.17943600000001],[-85.63806199999993,63.244995000000074],[-85.63917500000002,63.24971800000009],[-85.64834599999995,63.33554799999996],[-85.65388499999995,63.408882000000006],[-85.65083300000003,63.42860400000001],[-85.644455,63.44360399999999],[-85.63583399999999,63.45860300000004],[-85.6260989999999,63.46888000000001],[-85.61805700000002,63.4791560000001],[-85.60722399999986,63.494438000000116],[-85.60499599999997,63.50916300000006],[-85.59111000000001,63.617493000000024],[-85.59333799999996,63.631935],[-85.59611499999994,63.64138000000008],[-85.60749799999996,63.665268000000026],[-85.61332699999997,63.669715999999994],[-85.71749899999998,63.71610300000009],[-85.87943999999999,63.704711999999915],[-85.98582499999992,63.69332099999997],[-86.01722699999993,63.68832400000008],[-86.18360899999993,63.653046000000074],[-86.22444199999995,63.642769000000044],[-86.24499500000002,63.639435000000105],[-86.26695299999994,63.63804600000009],[-86.30027799999993,63.63971700000013],[-86.346115,63.64554600000014],[-86.38137799999998,63.65221400000013],[-86.45028699999989,63.66054500000001],[-86.55277999999987,63.670273000000066],[-86.56361400000003,63.670547],[-86.59611499999994,63.66860200000002],[-86.626938,63.66165900000004],[-86.66639700000002,63.64833100000004],[-86.69444299999992,63.63360600000004],[-86.73388699999998,63.60665899999998],[-86.75917099999998,63.59027100000009],[-86.77806099999992,63.581108000000086],[-86.80749500000002,63.571380999999974],[-86.837784,63.563323999999966],[-86.847778,63.56082200000009],[-86.879166,63.55554999999998],[-86.92222599999997,63.55277300000006],[-87.05055199999998,63.54972099999998],[-87.083618,63.550270000000125],[-87.09527599999996,63.5513840000001],[-87.118607,63.55582400000009],[-87.141388,63.563881000000094],[-87.14973399999991,63.56832900000006],[-87.18804899999986,63.589989],[-87.21722399999999,63.6222150000001],[-87.222778,63.63166000000001],[-87.22639499999997,63.64110599999998],[-87.225281,63.651099999999985],[-87.22193900000002,63.6658250000001],[-87.21888699999994,63.67582700000008],[-87.21083099999998,63.69110099999995],[-87.20083599999987,63.70665700000012],[-87.18666100000002,63.72221399999995],[-87.16111799999993,63.743607000000054],[-86.94387799999993,63.90054300000003],[-86.93443299999996,63.906097000000045],[-86.91528299999999,63.91443600000008],[-86.87582399999997,63.92860400000012],[-86.78416399999998,63.95694000000003],[-86.76362599999999,63.962212000000136],[-86.700287,63.97221400000012],[-86.66860999999989,63.978324999999984],[-86.5038909999999,64.018326],[-86.41361999999998,64.04859899999997],[-86.25500499999993,64.07609600000006],[-86.233612,64.0794370000001],[-86.22332799999998,64.08194000000009],[-86.21333300000003,64.08554100000015],[-86.203888,64.09109499999994],[-86.18943799999988,64.101654],[-86.17832899999996,64.12191800000011],[-86.178879,64.13165300000003],[-86.18222000000003,64.1413730000001],[-86.212219,64.17858900000004],[-86.25306699999999,64.20054600000009],[-86.27389499999998,64.20887800000008],[-86.30055199999998,64.22192400000006],[-86.30888400000003,64.22637900000007],[-86.3125,64.23082],[-86.35472099999998,64.28997800000013],[-86.38417099999998,64.36442599999998],[-86.40167200000002,64.436646],[-86.40110799999997,64.44164999999992],[-86.38362099999995,64.56498700000009],[-86.36888099999999,64.62942499999997],[-86.31555200000003,64.70109600000006],[-86.27250699999996,64.76805100000001],[-86.24888599999997,64.79386899999992],[-86.23889199999996,64.80415299999999],[-86.23138399999993,64.80941800000005],[-86.221115,64.81303400000007],[-86.21028099999995,64.81469700000002],[-86.19860799999992,64.81442300000009],[-86.18721,64.81526200000002],[-86.17666599999995,64.81776400000012],[-86.17166099999992,64.82304399999998],[-86.15249599999993,64.91804500000006],[-86.151947,64.92303500000008],[-86.15333599999991,64.92776500000014],[-86.15722699999998,64.93248],[-86.181107,64.95555100000001],[-86.18721,64.959991],[-86.21250900000001,64.96638500000006],[-86.22084000000001,64.97053500000004],[-86.22639499999997,64.97998000000013],[-86.22778299999999,64.98387100000002],[-86.22582999999997,64.99859600000013],[-86.22500600000001,65.003601],[-86.212219,65.03387500000008],[-86.20638999999989,65.04386900000009],[-86.19833399999999,65.0541530000001],[-86.18998699999992,65.06442300000003],[-86.18472300000002,65.06971700000003],[-86.16528299999993,65.08055100000007],[-86.14472999999998,65.08859300000006],[-86.13833599999992,65.09443700000003],[-86.13806199999999,65.099426],[-86.13555899999994,65.1827550000001],[-86.13722199999995,65.19775399999997],[-86.141953,65.2122040000001],[-86.146118,65.21666000000005],[-86.15139799999997,65.22637900000001],[-86.16416899999996,65.25000000000011],[-86.17054699999994,65.26915000000008],[-86.17166099999992,65.27886999999998],[-86.15333599999991,65.38472000000007],[-86.14973399999997,65.39471400000008],[-86.11193799999995,65.49414100000001],[-86.09777799999995,65.5291600000001],[-86.01390099999998,65.70915200000007],[-86.01000999999991,65.7149960000001],[-85.99388099999999,65.730545],[-85.98277300000001,65.74081400000006],[-85.97528099999988,65.74609400000008],[-85.88833599999998,65.79998799999993],[-85.83250399999991,65.83248900000007],[-85.791382,65.85331700000012],[-85.770554,65.86219800000003],[-85.72833300000002,65.87942500000008],[-85.69665499999991,65.89193700000004],[-85.62110899999993,65.91748000000001],[-85.56527699999998,65.93026700000001],[-85.54249600000003,65.9333190000001],[-85.50666799999999,65.93441800000005],[-85.49388099999999,65.93220500000012],[-85.49101300000001,65.93106099999994],[-85.48277300000001,65.92776500000008],[-85.476944,65.92330900000002],[-85.46888699999994,65.91387900000012],[-85.46972699999998,65.90887499999997],[-85.47389199999998,65.89888000000008],[-85.48889200000002,65.8785860000001],[-85.511124,65.85775800000005],[-85.520554,65.84275800000006],[-85.52362099999999,65.82304399999998],[-85.520554,65.81330900000006],[-85.516663,65.80859400000003],[-85.510559,65.80415299999993],[-85.49333199999995,65.7952580000001],[-85.48055999999997,65.79193099999998]],[[-62.13666499999994,65.85137900000001],[-62.141669999999976,65.84971600000006],[-62.15444200000002,65.85081500000007],[-62.162216,65.8541560000001],[-62.210830999999985,65.88053900000006],[-62.29695099999998,65.92776500000008],[-62.29666900000001,65.93858300000005],[-62.281386999999995,65.94636500000001],[-62.26500699999997,65.94693000000007],[-62.230552999999986,65.94386299999996],[-62.167220999999984,65.93275499999999],[-62.13777900000002,65.92581199999995],[-62.139725,65.91304000000014],[-62.118607,65.88108799999998],[-62.12999699999989,65.85914600000012],[-62.13666499999994,65.85137900000001]],[[-67.13833599999998,65.92692599999998],[-67.14584400000001,65.92637600000012],[-67.15444899999994,65.92886400000009],[-67.16111799999999,65.93220500000012],[-67.18527199999994,65.94831799999997],[-67.20916699999992,65.97886700000004],[-67.21194500000001,65.9827580000001],[-67.20889299999999,65.98442100000005],[-67.19915800000001,65.98637399999996],[-67.18138099999987,65.98719800000009],[-67.16694599999994,65.984985],[-67.153885,65.97859199999999],[-67.15278599999999,65.97499099999999],[-67.15260299999989,65.970734],[-67.13444500000003,65.93304400000005],[-67.13473499999992,65.93026700000001],[-67.13833599999998,65.92692599999998]],[[-83.57695000000001,65.98304700000006],[-83.58860799999997,65.98165899999992],[-83.60082999999986,65.98332200000004],[-83.604446,65.98776200000009],[-83.60082999999986,65.99304200000012],[-83.58889799999997,66.00305200000003],[-83.57000700000003,66.01361100000008],[-83.54750099999995,66.01944000000009],[-83.51139799999999,66.01998900000007],[-83.49888599999991,66.01748699999996],[-83.49305699999996,66.01277199999993],[-83.50140399999998,66.00749200000007],[-83.51000999999997,66.00332599999996],[-83.55444299999994,65.98887600000006],[-83.57695000000001,65.98304700000006]],[[-84.72277799999995,65.54609700000009],[-84.73388699999998,65.54470800000013],[-84.74610899999993,65.5458220000001],[-84.78472899999997,65.55664099999996],[-84.803604,65.56553600000001],[-84.82861299999996,65.57887300000004],[-84.84083599999997,65.58804300000008],[-84.84805299999988,65.597488],[-84.85333300000002,65.60693400000014],[-84.85221899999993,65.6119230000001],[-84.85777299999995,65.645828],[-84.85888699999992,65.65081800000007],[-84.86639399999996,65.65998800000011],[-84.878601,65.66914400000007],[-84.90028399999994,65.67804000000001],[-85.02860999999996,65.71165500000006],[-85.06304899999992,65.72331200000002],[-85.07389799999999,65.72776800000008],[-85.08222999999998,65.73220800000013],[-85.10694899999993,65.75054899999992],[-85.11805700000002,65.76470900000004],[-85.18194599999998,65.94552600000009],[-85.17304999999993,65.99470500000007],[-85.14388999999994,66.02110300000004],[-85.13722200000001,66.02331500000008],[-85.08167999999995,66.026657],[-85.05749500000002,66.02609300000006],[-84.9375,66.01054399999998],[-84.924713,66.00804099999999],[-84.91027799999989,66.00000000000011],[-84.88722199999995,65.94552600000009],[-84.88333099999988,65.94081100000005],[-84.80777,65.89582800000011],[-84.75500499999987,65.85331700000012],[-84.71611000000001,65.81721500000015],[-84.71417199999996,65.80720500000007],[-84.71278399999994,65.80220000000003],[-84.70777900000002,65.79275500000011],[-84.63722200000001,65.71220399999999],[-84.59750399999996,65.69664000000012],[-84.58667000000003,65.69220000000007],[-84.57417299999992,65.63916],[-84.57611099999997,65.6291500000001],[-84.58500699999996,65.61914100000007],[-84.59861799999993,65.60859700000003],[-84.66776999999996,65.56053200000002],[-84.72277799999995,65.54609700000009]],[[-83.608612,66.04414400000007],[-83.64222699999999,66.03498800000011],[-83.652222,66.03665200000012],[-83.6536099999999,66.04136699999998],[-83.64750700000002,66.04664600000012],[-83.64416499999999,66.05165099999999],[-83.62609900000001,66.0669400000001],[-83.61805699999996,66.07222000000013],[-83.60722399999997,66.07748400000014],[-83.597778,66.0788730000001],[-83.583618,66.07054099999993],[-83.577789,66.06581100000011],[-83.57084700000001,66.05636600000003],[-83.57444799999996,66.051376],[-83.58555599999994,66.04803500000014],[-83.59722899999997,66.04664600000012],[-83.608612,66.04414400000007]],[[-85.01916499999999,66.05720500000001],[-85.13555899999994,66.04443400000008],[-85.14778100000001,66.04582199999999],[-85.14917000000003,66.05053700000002],[-85.10777300000001,66.08442700000012],[-85.09973100000002,66.08970600000009],[-85.06332399999997,66.08776900000004],[-85.03860499999996,66.08610500000003],[-85.0161129999999,66.07971200000009],[-85.00862099999995,66.07054099999993],[-85.00695799999994,66.06553600000007],[-85.01028399999996,66.06053199999997],[-85.01916499999999,66.05720500000001]],[[-83.6494449999999,66.08360299999998],[-83.66111799999999,66.08194000000003],[-83.67361499999998,66.08332799999994],[-83.69249000000002,66.0913700000001],[-83.69610599999999,66.09609999999998],[-83.68998699999997,66.11109900000002],[-83.68527199999994,66.12109399999991],[-83.678879,66.12525900000014],[-83.60665899999998,66.12414600000005],[-83.59388699999994,66.12164300000006],[-83.587784,66.11720300000007],[-83.5916749999999,66.11219799999998],[-83.604446,66.10582000000005],[-83.61054999999993,66.10165399999994],[-83.63806199999999,66.086929],[-83.6494449999999,66.08360299999998]],[[-83.92138699999998,66.00972000000002],[-83.73083499999996,65.94775400000003],[-83.70584099999996,65.93414300000006],[-83.69415299999997,65.92469799999998],[-83.68331899999998,65.91053800000009],[-83.68083200000001,65.901093],[-83.68916300000001,65.86665300000004],[-83.69972199999995,65.85137900000001],[-83.71389799999997,65.84109499999994],[-83.72471599999994,65.83692900000005],[-83.73582499999992,65.83360300000004],[-83.72749299999992,65.79971300000011],[-83.52500899999995,65.73776199999992],[-83.36000100000001,65.72747800000008],[-83.348053,65.72692899999998],[-83.25111400000003,65.71693400000004],[-83.226944,65.71415700000011],[-83.214447,65.71054100000009],[-83.21083099999987,65.70582600000006],[-83.25111400000003,65.65470900000014],[-83.25944500000003,65.64942900000005],[-83.28889499999997,65.63275099999998],[-83.29972799999996,65.62942499999997],[-83.31111099999998,65.62719699999997],[-83.34500099999997,65.62081900000004],[-83.379166,65.61554000000007],[-83.39138799999995,65.61720300000013],[-83.39917000000003,65.62081900000004],[-83.406113,65.63026400000007],[-83.41194200000001,65.63472000000002],[-83.41999800000002,65.63943500000005],[-83.43055700000002,65.64387500000004],[-83.44332899999995,65.64804100000015],[-83.46861299999995,65.65498400000013],[-83.49305699999996,65.65776100000005],[-83.50500499999993,65.65832499999999],[-83.52861000000001,65.65832499999999],[-83.59889199999998,65.65637200000003],[-83.66027799999995,65.64721700000001],[-83.82972699999999,65.64498900000001],[-83.84277299999991,65.64915500000012],[-83.84611499999994,65.65386999999998],[-83.84973100000002,65.66832000000011],[-83.84638999999999,65.67330900000007],[-83.84056099999987,65.6785890000001],[-83.79415899999998,65.71943700000003],[-83.78582799999998,65.72470099999998],[-83.77500900000001,65.72804300000013],[-83.74082899999996,65.7333220000001],[-83.69526699999994,65.74108900000004],[-83.68415800000002,65.74443100000002],[-83.68276999999995,65.74941999999999],[-83.68888899999996,65.75416600000005],[-83.785278,65.78887900000007],[-83.79750100000001,65.7894290000001],[-83.80888399999998,65.78804000000008],[-83.84973100000002,65.78054800000012],[-83.90583799999996,65.76748700000002],[-83.92749000000003,65.75972000000007],[-83.93804899999998,65.74443100000002],[-83.94860799999992,65.74026500000008],[-83.96000700000002,65.73776199999992],[-83.97166400000003,65.73719800000015],[-83.98388699999992,65.73858600000005],[-84.071121,65.75],[-84.12054399999994,65.75833100000006],[-84.13333099999994,65.76081799999997],[-84.14361599999995,65.76416000000006],[-84.14500399999997,65.76914999999997],[-84.141388,65.77415500000001],[-84.11721799999998,65.78970300000003],[-84.11138899999997,65.79498300000006],[-84.10333300000002,65.80998199999993],[-84.10110500000002,65.81971700000003],[-84.12361099999993,65.90026900000004],[-84.189438,65.968323],[-84.19804399999992,65.97303800000003],[-84.20861799999989,65.97720300000003],[-84.28639199999998,65.999146],[-84.29943800000001,66.00248700000003],[-84.31138599999997,66.00305200000003],[-84.32333399999999,66.00248700000003],[-84.358047,65.99775699999998],[-84.36999500000002,65.99720800000006],[-84.38276699999994,66.00054900000009],[-84.42416399999996,66.02804600000002],[-84.43611099999993,66.0372010000001],[-84.464447,66.06025700000009],[-84.46806299999997,66.06498699999997],[-84.46916199999998,66.06999200000001],[-84.47000100000002,66.08943199999999],[-84.471115,66.12831100000005],[-84.47027599999996,66.13333100000011],[-84.464447,66.13832100000013],[-84.45584100000002,66.14166300000005],[-84.43306000000001,66.13888500000007],[-84.381104,66.12914999999998],[-84.36805699999991,66.12580899999995],[-84.24027999999993,66.0983280000001],[-84.14639299999988,66.08109999999999],[-84.03944399999995,66.07693499999999],[-84.00167799999997,66.03360000000004],[-83.92138699999998,66.00972000000002]],[[-84.57972699999999,66.14137300000004],[-84.62748699999992,66.13916000000012],[-84.63999899999999,66.14054900000008],[-84.648346,66.14498900000012],[-84.654449,66.14942900000011],[-84.67582700000003,66.17303500000003],[-84.678604,66.18248000000006],[-84.66722099999993,66.18498199999999],[-84.61888099999999,66.17665100000005],[-84.59333799999996,66.17109700000009],[-84.589447,66.16638200000006],[-84.57444800000002,66.147491],[-84.57972699999999,66.14137300000004]],[[-84.265289,66.17776500000002],[-84.276947,66.17526200000009],[-84.28916900000002,66.17553700000008],[-84.30139199999996,66.1769260000001],[-84.31388900000002,66.17942800000014],[-84.35333300000002,66.19026200000002],[-84.36193799999995,66.19470200000006],[-84.36444099999994,66.20443699999993],[-84.36361699999998,66.209427],[-84.36000100000001,66.21443200000004],[-84.348343,66.21582000000012],[-84.33583099999998,66.21443200000004],[-84.30972300000002,66.20776400000005],[-84.29916400000002,66.20332299999995],[-84.27305599999994,66.19664],[-84.26445000000001,66.19219999999996],[-84.25834700000001,66.18775900000009],[-84.256958,66.1827550000001],[-84.265289,66.17776500000002]],[[-62.183883999999864,66.23719800000009],[-62.199164999999994,66.21693399999992],[-62.40499899999986,66.21859700000005],[-62.415276000000006,66.21914700000008],[-62.42166899999995,66.22221400000001],[-62.42999999999995,66.2291560000001],[-62.4266659999999,66.233047],[-62.419167000000016,66.23776200000003],[-62.31945000000002,66.26944000000003],[-62.301941,66.27499400000005],[-62.287223999999924,66.27804600000013],[-62.278336000000024,66.27970900000008],[-62.26167299999997,66.28027300000002],[-62.24888599999997,66.27859500000011],[-62.24305700000002,66.27693199999999],[-62.231383999999935,66.26944000000003],[-62.183883999999864,66.23719800000009]],[[-83.06722999999988,66.25555400000007],[-83.05499299999991,66.25499000000013],[-83.04305999999997,66.25526400000007],[-83.031113,66.25665300000003],[-83.019455,66.25915500000013],[-82.99694799999997,66.26582300000007],[-82.96083099999998,66.27249100000006],[-82.93720999999994,66.27526900000004],[-82.91332999999986,66.276093],[-82.90249599999999,66.27165200000013],[-82.90417500000001,66.26666299999994],[-82.910278,66.26165800000007],[-82.91861,66.25749200000001],[-82.92971799999998,66.25221300000004],[-82.93554699999993,66.25138900000007],[-82.99027999999998,66.203598],[-82.99638400000003,66.19859300000013],[-83.00778200000002,66.19525099999998],[-83.01972999999998,66.19497700000005],[-83.08029199999999,66.19664],[-83.09306299999997,66.19886800000012],[-83.26333599999998,66.247208],[-83.287216,66.25610400000011],[-83.29333500000001,66.2605440000001],[-83.29666099999997,66.26527399999998],[-83.297775,66.270264],[-83.29833999999988,66.31387300000011],[-83.28500400000001,66.32916300000011],[-83.273056,66.3394320000001],[-83.26417500000002,66.3435970000001],[-83.252228,66.34498600000012],[-83.226944,66.33998100000008],[-83.21611000000001,66.33554100000003],[-83.20472699999993,66.31666600000011],[-83.17388900000003,66.28858900000012],[-83.16805999999991,66.28387499999997],[-83.06722999999988,66.25555400000007]],[[-66.62332200000003,66.28082300000005],[-66.64195299999994,66.27943400000004],[-66.65695199999993,66.28027300000002],[-66.66749599999997,66.282761],[-66.678879,66.286926],[-66.70140099999998,66.29776000000004],[-66.74194299999988,66.3163760000001],[-66.84306300000003,66.36248799999998],[-66.9058379999999,66.37664800000005],[-66.91610700000001,66.37997400000012],[-66.94471699999997,66.39498900000007],[-66.95611599999995,66.40193200000004],[-66.95861799999994,66.40637200000009],[-66.95834400000001,66.41192600000005],[-66.95527600000003,66.41360500000008],[-66.94444299999992,66.41387900000001],[-66.85194399999995,66.40220599999998],[-66.82972699999999,66.39833099999998],[-66.823059,66.39276100000012],[-66.82084699999996,66.38804600000009],[-66.80110199999996,66.37553400000007],[-66.78222700000003,66.36914100000013],[-66.726944,66.35498000000013],[-66.70556599999998,66.34971599999994],[-66.67832900000002,66.34553500000004],[-66.662216,66.3435970000001],[-66.65028399999994,66.34304800000001],[-66.639725,66.34054600000007],[-66.62388599999997,66.33526600000005],[-66.58444199999997,66.3205410000001],[-66.57501200000002,66.31387300000011],[-66.573624,66.31080600000001],[-66.59167500000001,66.29359399999998],[-66.60526999999996,66.28665200000006],[-66.62332200000003,66.28082300000005]],[[-66.99833699999994,66.493042],[-66.99027999999998,66.48915099999994],[-66.97610499999996,66.48915099999994],[-66.96333299999998,66.48719800000003],[-66.87332199999997,66.46859699999999],[-66.86888099999999,66.46443199999999],[-66.87138400000003,66.46054100000009],[-66.87805200000003,66.458328],[-66.93611099999993,66.44552599999997],[-66.94888300000002,66.444702],[-66.987213,66.44525099999993],[-67.03028899999993,66.45248400000014],[-67.03666699999997,66.45609999999999],[-67.03832999999997,66.47248800000006],[-67.03805499999999,66.47804300000013],[-67.035278,66.48471100000012],[-67.02500899999995,66.48997500000013],[-67.00695799999988,66.493042],[-66.99833699999994,66.493042]],[[-107.92304999999993,66.85054000000002],[-107.9349979999999,66.84915200000012],[-107.94611399999991,66.85108900000012],[-107.94554099999993,66.85693400000002],[-107.837784,67.00387599999999],[-107.83029199999993,67.00860600000004],[-107.81696299999993,67.00915500000013],[-107.80666400000001,67.00582900000012],[-107.79499800000002,66.997208],[-107.79110699999995,66.98831200000006],[-107.78971899999999,66.98525999999998],[-107.79055800000003,66.97970599999996],[-107.82389799999999,66.901093],[-107.83000199999992,66.8955380000001],[-107.89499699999999,66.86080900000002],[-107.90360999999996,66.85693400000002],[-107.92304999999993,66.85054000000002]],[[-108.01445000000001,66.89776600000005],[-108.025284,66.8955380000001],[-108.03859699999998,66.89721700000013],[-108.04444899999993,66.90138200000013],[-108.09638999999993,66.96748400000001],[-108.097778,66.97276299999999],[-108.10659799999996,67.02600100000006],[-108.06360599999988,67.00109900000007],[-107.93831599999999,66.94693000000007],[-107.95944199999991,66.93165599999998],[-107.96665999999993,66.9266510000001],[-108.00583599999987,66.90193199999993],[-108.01445000000001,66.89776600000005]],[[-63.059166000000005,66.95776400000011],[-63.083327999999995,66.95498700000002],[-63.09555099999994,66.955826],[-63.11694299999999,66.96304300000008],[-63.136391,66.9747010000001],[-63.16305499999993,66.99525500000004],[-63.165549999999996,66.99914599999994],[-63.166106999999954,67.00499000000013],[-63.159163999999976,67.01554900000002],[-63.15416699999997,67.02137800000003],[-63.14444699999996,67.02886999999998],[-63.12749499999995,67.03359999999998],[-63.12305500000002,67.03471399999995],[-63.1108319999999,67.03387500000002],[-63.1016689999999,67.02970900000008],[-63.098052999999936,67.02720599999998],[-63.097778000000005,67.02331500000008],[-63.02111100000002,66.996643],[-63.01167299999997,66.99247700000006],[-63.00389099999995,66.988586],[-62.999999999999886,66.984421],[-62.999442999999985,66.97859199999999],[-63.002228,66.97554000000008],[-63.020835999999974,66.966385],[-63.04000099999996,66.96081500000014],[-63.059166000000005,66.95776400000011]],[[-62.918334999999956,67.00972000000002],[-62.93804899999998,67.00582900000012],[-62.97777599999995,67.00665300000009],[-63.009727,67.009995],[-63.03778099999994,67.01582300000013],[-63.06833599999999,67.02554300000003],[-63.092772999999966,67.03581200000008],[-63.12388599999997,67.04914900000011],[-63.135559,67.05470300000007],[-63.138892999999996,67.05941800000011],[-63.13805400000001,67.06526200000013],[-63.13583399999999,67.06971699999997],[-63.130279999999914,67.07415800000007],[-63.11721799999998,67.0788730000001],[-63.11055799999997,67.08027600000003],[-63.10008199999993,67.07971200000009],[-63.002228,67.06944300000004],[-62.97833300000002,67.06275900000014],[-62.961112999999955,67.05470300000007],[-62.941108999999926,67.04359399999998],[-62.922500999999954,67.03109700000005],[-62.914444,67.02304100000015],[-62.912215999999944,67.01470899999998],[-62.918334999999956,67.00972000000002]],[[-62.64416499999993,67.05748],[-62.64694999999995,67.04998800000004],[-62.65166499999998,67.04693600000013],[-62.75250199999999,67.01054399999998],[-62.764449999999954,67.00915500000013],[-62.782775999999956,67.00943000000001],[-62.81305699999996,67.0169370000001],[-62.832222,67.02442900000005],[-62.899445000000014,67.05831899999998],[-62.89459999999997,67.05911300000008],[-62.865005,67.05748],[-62.82028200000002,67.05581700000005],[-62.81027999999998,67.05693100000002],[-62.80666400000001,67.05914300000012],[-62.70286900000002,67.12868500000008],[-62.652221999999995,67.16609199999999],[-62.64194500000002,67.174149],[-62.631942999999865,67.17692600000004],[-62.547782999999924,67.18609600000013],[-62.533889999999985,67.18719500000009],[-62.42527799999999,67.19108599999998],[-62.41805999999997,67.19081099999994],[-62.37888299999986,67.16970800000007],[-62.37527499999993,67.165817],[-62.376105999999936,67.1644290000001],[-62.38805400000001,67.15748600000006],[-62.44361099999992,67.13581799999997],[-62.45194200000003,67.13275100000004],[-62.47249599999998,67.12608300000005],[-62.50417299999992,67.11943099999996],[-62.538612,67.11387600000006],[-62.56944999999996,67.10582],[-62.58000199999998,67.10220300000009],[-62.59610699999996,67.09220900000003],[-62.631667999999934,67.06999199999996],[-62.63861099999991,67.06387300000011],[-62.64416499999993,67.05748]],[[-107.40778399999999,67.083054],[-107.49054699999999,67.07138099999997],[-107.50639299999995,67.07249500000012],[-107.51750199999987,67.07470699999999],[-107.52778599999999,67.07804899999996],[-107.54972800000002,67.08998100000008],[-107.56500199999999,67.10331700000006],[-107.57444799999996,67.11219800000015],[-107.58389299999988,67.12136800000002],[-107.59110999999996,67.13081399999999],[-107.62917299999992,67.18331900000004],[-107.63054699999992,67.188583],[-107.62970699999988,67.19413800000007],[-107.62666300000001,67.2002720000001],[-107.62053700000001,67.20610000000005],[-107.608337,67.20748900000001],[-107.59777799999995,67.204163],[-107.58168,67.19636500000013],[-107.57584400000002,67.19220000000013],[-107.56194299999987,67.18386800000013],[-107.51000999999991,67.15637200000009],[-107.47778299999993,67.14082300000001],[-107.46193700000003,67.13333100000006],[-107.443604,67.12608300000005],[-107.412781,67.11581400000006],[-107.40055799999993,67.11303700000013],[-107.40778399999999,67.083054]],[[-95.36166399999996,67.19775400000015],[-95.37361099999993,67.19636500000013],[-95.40055799999993,67.197205],[-95.41528299999999,67.1997070000001],[-95.4308319999999,67.20277399999998],[-95.52749599999993,67.22303799999997],[-95.54333499999996,67.22637900000001],[-95.55139200000002,67.23027000000008],[-95.55277999999993,67.2352600000001],[-95.54222099999998,67.23858599999994],[-95.39111299999996,67.26304600000014],[-95.37777699999992,67.26277200000004],[-95.31723,67.25555400000002],[-95.30722000000003,67.25248699999992],[-95.30583200000001,67.24775700000009],[-95.30943299999996,67.24220300000007],[-95.31471299999993,67.23858599999994],[-95.33666999999991,67.2127690000001],[-95.34277299999997,67.20694000000009],[-95.36166399999996,67.19775400000015]],[[-107.66278099999994,67.22026100000005],[-107.675003,67.21887200000003],[-107.73029300000002,67.28997800000008],[-107.73306300000002,67.30026199999992],[-107.73029300000002,67.30636600000014],[-107.72501399999993,67.31303400000013],[-107.71083099999998,67.31915300000014],[-107.67777999999993,67.31191999999999],[-107.66944899999993,67.30802900000009],[-107.66000399999996,67.29887400000001],[-107.64472999999998,67.26915000000002],[-107.64028899999994,67.25360100000012],[-107.63945000000001,67.24275200000005],[-107.64250199999992,67.23664900000011],[-107.64778100000001,67.22998000000001],[-107.65416699999997,67.22442600000005],[-107.66278099999994,67.22026100000005]],[[-63.36639399999996,67.28776600000003],[-63.39611100000002,67.26998899999995],[-63.417778,67.26638800000012],[-63.45610799999997,67.26443499999999],[-63.507506999999976,67.26944000000003],[-63.54194599999994,67.27249100000006],[-63.55972300000002,67.27304100000009],[-63.57833900000003,67.27331500000003],[-63.62027699999993,67.26915000000002],[-63.76361800000001,67.27249100000006],[-63.81361400000003,67.2791600000001],[-63.82972699999988,67.28414900000007],[-63.81944999999996,67.28997800000008],[-63.79666899999995,67.29998799999998],[-63.68833199999989,67.34166000000005],[-63.66666399999997,67.34553500000004],[-63.64611099999996,67.34803800000003],[-63.60555999999997,67.35220300000003],[-63.58583099999987,67.353317],[-63.48500100000001,67.341095],[-63.36916400000001,67.30247500000007],[-63.35777999999999,67.29386899999997],[-63.36639399999996,67.28776600000003]],[[-107.91082799999998,67.31053200000002],[-107.93443300000001,67.30664099999996],[-107.94803599999995,67.3083190000001],[-108.08444199999997,67.38136300000008],[-108.076683,67.42469800000003],[-108.07389799999993,67.4308170000001],[-108.06861899999996,67.43748500000004],[-108.06111099999993,67.44220000000007],[-107.94748700000002,67.47998000000001],[-107.91776999999996,67.48942599999998],[-107.90306099999992,67.4891510000001],[-107.89472999999992,67.48553500000008],[-107.88722200000001,67.47608900000012],[-107.88276699999989,67.46249400000005],[-107.89806399999998,67.31971700000008],[-107.90110799999997,67.31359899999995],[-107.91082799999998,67.31053200000002]],[[-108.36833200000001,67.46720900000008],[-108.38194299999998,67.4666600000001],[-108.39806399999998,67.467758],[-108.43388399999998,67.47665400000011],[-108.44444299999992,67.47998000000001],[-108.45278899999994,67.48387100000008],[-108.45889299999988,67.48803700000013],[-108.49249299999997,67.51971400000008],[-108.49638400000003,67.52442900000011],[-108.49582700000002,67.52998400000001],[-108.491379,67.56303400000007],[-108.48137700000001,67.56637599999999],[-108.45777899999996,67.56805400000013],[-108.33583099999993,67.565811],[-108.29750100000001,67.55720500000007],[-108.28582799999998,67.54304500000012],[-108.28443899999996,67.53776600000015],[-108.29527299999995,67.49693300000007],[-108.30166600000001,67.49108900000004],[-108.35722399999986,67.46943700000003],[-108.36833200000001,67.46720900000008]],[[-108.14111300000002,67.44999700000005],[-108.16944899999993,67.44970700000005],[-108.23665599999993,67.45665000000002],[-108.25167799999997,67.45887800000014],[-108.26222200000001,67.46220400000004],[-108.26806599999992,67.4666600000001],[-108.27194199999991,67.47137499999997],[-108.275284,67.48165899999998],[-108.22556299999997,67.56553600000012],[-108.21916199999987,67.57110600000004],[-108.20638999999994,67.57054099999999],[-108.19833399999999,67.566666],[-108.17360699999995,67.55247500000002],[-108.1661069999999,67.54304500000012],[-108.13137799999993,67.48193400000002],[-108.12970699999994,67.47665400000011],[-108.12888299999997,67.46582000000006],[-108.12943999999999,67.46026600000005],[-108.13249200000001,67.45416300000011],[-108.14111300000002,67.44999700000005]],[[-108.32277699999997,67.58998099999997],[-108.32362399999994,67.58665500000012],[-108.339447,67.5877690000001],[-108.42027300000001,67.59942600000005],[-108.48222399999992,67.63136300000002],[-108.48388699999992,67.63665800000007],[-108.475281,67.64054899999996],[-108.46389799999992,67.64305100000007],[-108.44803599999995,67.64193700000004],[-108.41832699999992,67.63638300000008],[-108.40334299999995,67.63415500000013],[-108.390289,67.63108800000003],[-108.379707,67.62776200000013],[-108.37138400000003,67.62414600000011],[-108.33416699999992,67.6041560000001],[-108.32277699999997,67.58998099999997]],[[-63.88194299999998,67.50332600000002],[-63.93555500000002,67.50193800000011],[-63.97916399999991,67.50305200000008],[-63.99500299999994,67.50416600000005],[-64.00527999999991,67.50526399999995],[-64.02528399999994,67.51054400000004],[-64.02972399999987,67.51388500000007],[-64.031677,67.5186000000001],[-64.03472899999991,67.52887000000004],[-64.03805499999987,67.54275500000011],[-64.0344389999999,67.55859400000003],[-63.98111,67.64415000000002],[-63.976944,67.649429],[-63.969993999999986,67.65359500000011],[-63.96277599999996,67.65554800000001],[-63.95249899999999,67.65443400000004],[-63.94554900000003,67.65138200000013],[-63.93721800000003,67.645264],[-63.92639200000002,67.63333099999994],[-63.92222600000002,67.62498500000004],[-63.915549999999996,67.61720300000013],[-63.90444200000002,67.60803199999998],[-63.87555699999996,67.59304800000007],[-63.853888999999924,67.58554100000015],[-63.815276999999924,67.566666],[-63.78722399999998,67.55053700000008],[-63.76999699999999,67.53776600000015],[-63.76361800000001,67.52970900000003],[-63.75805699999995,67.52053800000004],[-63.76083399999999,67.51527400000009],[-63.769447000000014,67.51332100000013],[-63.81833599999999,67.5086060000001],[-63.84222399999993,67.50637799999998],[-63.88194299999998,67.50332600000002]],[[-108.05999799999995,67.47526600000003],[-108.08972199999994,67.46554600000013],[-108.10333300000002,67.46720900000008],[-108.109444,67.47137499999997],[-108.11332700000003,67.47608900000012],[-108.14389,67.53054799999995],[-108.14277600000003,67.54165599999999],[-108.13362099999989,67.62803600000007],[-108.13221699999997,67.63943499999999],[-108.11776699999996,67.66998299999995],[-108.11361699999998,67.67526199999998],[-108.10109699999992,67.6766510000001],[-108.087219,67.67498800000004],[-108.01418299999995,67.66249100000005],[-108.00361599999997,67.65914900000007],[-107.99553700000001,67.655258],[-107.98944099999994,67.651093],[-107.98332199999999,67.64471400000014],[-107.92832900000002,67.561646],[-107.92304999999993,67.55165100000005],[-107.92138699999992,67.54664600000001],[-107.922234,67.540817],[-107.92749000000003,67.53442400000006],[-108.05999799999995,67.47526600000003]],[[-97.50279199999994,67.62442000000004],[-97.51556399999993,67.62387100000007],[-97.53028899999998,67.62498500000004],[-97.541382,67.62886000000003],[-97.54943799999995,67.63804599999997],[-97.55139199999996,67.64276100000001],[-97.55305499999992,67.6477660000001],[-97.56054699999993,67.69274899999999],[-97.40055799999999,67.73165899999992],[-97.38778699999989,67.73220800000007],[-97.36000100000001,67.73165899999992],[-97.34638999999993,67.728317],[-97.337784,67.724152],[-97.337784,67.72110000000009],[-97.33277899999996,67.70637499999998],[-97.327225,67.68165599999998],[-97.33277899999996,67.67581200000001],[-97.34167500000001,67.6705320000001],[-97.37054399999988,67.657761],[-97.43360899999993,67.63749700000005],[-97.47888199999994,67.62747200000013],[-97.50279199999994,67.62442000000004]],[[-109.11221299999994,67.76332100000008],[-109.12581599999987,67.76249700000011],[-109.14111299999996,67.76499899999999],[-109.195267,67.77554300000003],[-109.20612299999993,67.77886999999998],[-109.20777900000002,67.78387500000002],[-109.16944899999999,67.79775999999993],[-109.15943899999996,67.801086],[-109.135559,67.80276499999997],[-109.0933379999999,67.80386399999998],[-109.07584400000002,67.80219999999997],[-109.06054699999999,67.79971300000005],[-109.03916899999996,67.79332000000011],[-109.04083299999996,67.78831500000007],[-109.05277999999993,67.78248600000006],[-109.08000199999987,67.77110300000004],[-109.08972199999994,67.76805100000013],[-109.11221299999994,67.76332100000008]],[[-96.170547,67.77304100000015],[-96.18276999999995,67.77165199999996],[-96.19249000000002,67.77360500000009],[-96.19638099999992,67.77804600000002],[-96.18582199999997,67.79470800000001],[-96.17999299999997,67.80026200000003],[-96.17138699999992,67.80636600000003],[-96.09861799999999,67.83221399999996],[-96.07722499999994,67.83888200000013],[-96.06555200000003,67.84109500000011],[-96.05332899999996,67.842758],[-96.04028299999993,67.84332300000005],[-96.02806099999998,67.84165999999993],[-95.99749800000001,67.820831],[-95.99638400000003,67.81581100000011],[-96.00473,67.809708],[-96.01611300000002,67.80748],[-96.04083299999996,67.80442800000009],[-96.170547,67.77304100000015]],[[-114.11501299999998,67.88388099999997],[-114.08222999999998,67.8830410000001],[-114.02223200000003,67.88415500000008],[-114.00583599999999,67.8836060000001],[-113.95500199999998,67.88136299999996],[-113.92138699999998,67.87803600000001],[-113.925003,67.87469499999997],[-113.94138299999986,67.87525900000014],[-113.98638899999997,67.87441999999999],[-113.99999999999994,67.87330600000001],[-114.01027699999992,67.87136800000007],[-114.05166600000001,67.87025499999999],[-114.08306900000002,67.87052900000009],[-114.195267,67.87248200000005],[-114.22972099999987,67.87414600000005],[-114.25250199999999,67.879974],[-114.29638699999998,67.89221200000003],[-114.29695100000004,67.89526399999994],[-114.27555799999999,67.90054299999991],[-114.25110599999994,67.90443399999998],[-114.21972700000003,67.90416000000005],[-114.20612299999993,67.9019320000001],[-114.17388899999997,67.89248700000007],[-114.14862099999999,67.88720699999999],[-114.13305700000001,67.88526900000005],[-114.11501299999998,67.88388099999997]],[[-97.85638399999993,67.85053999999997],[-97.86694299999999,67.84693900000013],[-97.92416400000002,67.84999100000005],[-97.954453,67.85636899999997],[-97.96333300000003,67.86026000000004],[-97.97000100000002,67.86442599999998],[-97.97416699999991,67.86914100000001],[-97.97332799999992,67.87414600000005],[-97.976944,67.88415500000008],[-97.97444200000001,67.90498400000001],[-97.96112099999999,67.90554800000001],[-97.93331899999998,67.89888000000002],[-97.92027299999995,67.8936000000001],[-97.91361999999998,67.88916000000012],[-97.895554,67.88136299999996],[-97.86221299999994,67.85998500000005],[-97.85804699999994,67.855255],[-97.85638399999993,67.85053999999997]],[[-108.64695699999999,67.86943100000002],[-108.66082799999998,67.86886599999997],[-108.66915899999998,67.87248200000005],[-108.64666699999998,67.88720699999999],[-108.58500700000002,67.91554300000007],[-108.56610099999989,67.92275999999998],[-108.54472399999997,67.928314],[-108.531113,67.92886400000003],[-108.38027999999997,67.922485],[-108.37082699999996,67.91970800000007],[-108.36444099999994,67.91554300000007],[-108.36110699999989,67.90525799999995],[-108.35944399999994,67.89999399999999],[-108.41221599999994,67.88581799999997],[-108.64695699999999,67.86943100000002]],[[-113.390289,67.89776600000005],[-113.46389799999997,67.89582800000011],[-113.52694699999995,67.89637800000014],[-113.55972300000002,67.897491],[-113.59416199999993,67.89942899999994],[-113.6033329999999,67.90304600000007],[-113.59750399999996,67.90664700000013],[-113.58528100000001,67.90860000000009],[-113.41972399999997,67.92526200000009],[-113.39111300000002,67.92665100000005],[-113.34750400000001,67.92804000000007],[-113.27390299999996,67.92997700000012],[-113.25723299999993,67.92942800000014],[-113.25029,67.92526200000009],[-113.24694799999997,67.9144290000001],[-113.25361599999997,67.90942400000006],[-113.27778599999999,67.905823],[-113.297234,67.90443399999998],[-113.33444199999991,67.90109299999995],[-113.390289,67.89776600000005]],[[-112.93055700000002,67.91665599999999],[-112.983612,67.91526800000008],[-112.99999999999989,67.91609200000005],[-113.06027199999994,67.91526800000008],[-113.131104,67.911652],[-113.14750700000002,67.91220099999998],[-113.14750700000002,67.915817],[-113.13806199999999,67.91914400000013],[-112.94304699999998,67.9310910000001],[-112.89639299999999,67.93081699999999],[-112.88722199999995,67.92720000000003],[-112.890289,67.92192100000005],[-112.90110800000002,67.91914400000013],[-112.93055700000002,67.91665599999999]],[[-111.07167099999998,67.84748800000006],[-111.08666999999997,67.84748800000006],[-111.0911099999999,67.85220300000009],[-111.08693700000003,67.85887100000008],[-111.07028200000002,67.86720300000007],[-110.84889199999998,67.95471199999997],[-110.83917200000002,67.95803799999999],[-110.82668299999995,67.95971700000001],[-110.81388900000002,67.95915200000002],[-110.80722000000003,67.95498700000002],[-110.80943300000001,67.94886799999995],[-110.81696299999999,67.94026200000002],[-110.86221299999994,67.89498900000012],[-110.86945300000002,67.88998400000008],[-110.88027999999991,67.887497],[-111.05943300000001,67.84915200000006],[-111.07167099999998,67.84748800000006]],[[-114.21916199999998,67.94525099999998],[-114.29583699999995,67.94470200000006],[-114.30999799999995,67.94581600000004],[-114.31722999999988,67.9497070000001],[-114.31082200000003,67.95471199999997],[-114.30027799999988,67.95748900000007],[-114.25446299999987,67.96331800000007],[-114.17138699999992,67.96914700000008],[-114.13999899999999,67.96887200000009],[-114.12416099999996,67.96720900000014],[-114.12110899999993,67.96192900000005],[-114.12332199999992,67.95803799999999],[-114.16332999999986,67.94914200000005],[-114.203888,67.94581600000004],[-114.21916199999998,67.94525099999998]],[[-108.13806199999999,67.87248200000005],[-108.15167199999996,67.87191800000011],[-108.24553699999996,67.87803600000001],[-108.25418100000002,67.88192700000008],[-108.25556899999992,67.88720699999999],[-108.23916599999995,67.9202580000001],[-108.236107,67.92637600000006],[-108.23111,67.93304400000005],[-108.22471599999994,67.93887300000006],[-108.198036,67.95082100000008],[-108.14723200000003,67.96665999999999],[-108.12581599999999,67.97221400000001],[-108.114441,67.97442600000005],[-108.10056299999997,67.9749910000001],[-108.08416699999998,67.97387700000013],[-108.07140399999992,67.97110000000004],[-108.06054699999999,67.96775800000012],[-108.05444299999988,67.96331800000007],[-108.05055199999998,67.95860300000004],[-108.048607,67.94914200000005],[-108.05139200000002,67.92665100000005],[-108.06331599999993,67.90220600000004],[-108.06833599999999,67.89553800000004],[-108.07501200000002,67.88970900000004],[-108.08249699999999,67.88499500000012],[-108.09137699999985,67.88081400000004],[-108.11277799999999,67.87553400000013],[-108.13806199999999,67.87248200000005]],[[-113.72000099999997,67.97331200000008],[-113.72778299999993,67.96914700000008],[-113.73998999999998,67.96720900000014],[-113.75361599999997,67.966095],[-113.79750099999995,67.96470599999998],[-113.99305699999996,67.96110499999992],[-113.99109599999997,67.96499599999999],[-113.98249800000002,67.96720900000014],[-113.97250400000001,67.96859700000005],[-113.91639700000002,67.97221400000001],[-113.88639799999999,67.97276299999999],[-113.83833299999998,67.971924],[-113.81111099999993,67.97387700000013],[-113.785278,67.97692900000004],[-113.77223199999997,67.98027000000008],[-113.74082899999996,67.97998000000007],[-113.72501399999999,67.97804300000001],[-113.72000099999997,67.97331200000008]],[[-109.195267,67.98997499999996],[-109.04998799999993,67.95832800000005],[-109.03028899999993,67.96693399999992],[-108.99082900000002,67.97637900000001],[-108.97693599999997,67.97692900000004],[-108.95111099999991,67.97331200000008],[-108.89723199999997,67.95694000000009],[-108.88445300000001,67.94859300000013],[-108.86554699999999,67.905823],[-108.86609599999991,67.90026899999998],[-108.87943999999999,67.87525900000014],[-108.88806199999999,67.87109399999997],[-108.90055799999999,67.86970500000012],[-108.916946,67.87052900000009],[-109.04888900000003,67.90387000000004],[-109.10305799999998,67.9202580000001],[-109.135559,67.93026700000013],[-109.16972399999992,67.94525099999998],[-109.18888899999996,67.95776400000005],[-109.195267,67.9622040000001],[-109.19888299999997,67.97248800000011],[-109.198036,67.98387100000014],[-109.195267,67.98997499999996]],[[-110.33444199999997,68.01165800000012],[-110.39362299999993,68.01110800000009],[-110.41000400000001,68.01193200000006],[-110.42111199999994,68.01499899999993],[-110.420837,68.020828],[-110.410553,68.02470400000004],[-110.32640099999992,68.0477600000001],[-110.317497,68.049713],[-110.31082199999992,68.0455320000001],[-110.30888400000003,68.03749100000005],[-110.316101,68.01915000000002],[-110.32333399999999,68.01416],[-110.33444199999997,68.01165800000012]],[[-98.95140100000003,67.97998000000007],[-98.96362299999993,67.97831700000012],[-98.97944599999994,67.98027000000008],[-99.00500499999998,67.98719800000009],[-99.01445000000001,67.99108899999999],[-99.02833599999991,67.99942000000004],[-99.0786129999999,68.045593],[-99.05139200000002,68.05581700000005],[-98.99055499999986,68.07832300000007],[-98.97555499999999,68.07720900000004],[-98.968887,68.07304400000004],[-98.964722,68.06498700000009],[-98.93443299999996,67.99664300000012],[-98.93499800000001,67.99136399999998],[-98.94276399999995,67.98525999999993],[-98.95140100000003,67.97998000000007]],[[-65.39723200000003,68.03997800000013],[-65.40916399999998,68.03942899999998],[-65.50029,68.04609700000015],[-65.51083399999999,68.04942299999999],[-65.516663,68.05442800000003],[-65.51972999999998,68.06749000000008],[-65.51806599999998,68.07222000000007],[-65.50527999999997,68.07638500000007],[-65.43582200000003,68.08804299999997],[-65.394455,68.08998100000008],[-65.38639799999993,68.08831800000013],[-65.390289,68.07832300000007],[-65.38305700000001,68.05331400000006],[-65.38333099999994,68.04859900000002],[-65.38722200000001,68.04332000000005],[-65.39723200000003,68.03997800000013]],[[-108.50611900000001,68.03471400000012],[-108.51862299999993,68.03332499999993],[-108.53388999999999,68.03553800000009],[-108.54028299999993,68.03997800000013],[-108.53751399999999,68.04609700000015],[-108.45472699999999,68.09054600000007],[-108.44748700000002,68.08776900000004],[-108.44583099999994,68.08248900000012],[-108.44611399999991,68.07470699999999],[-108.45140100000003,68.06805400000002],[-108.46665999999999,68.0583190000001],[-108.49722299999996,68.03887900000012],[-108.50611900000001,68.03471400000012]],[[-109.32167099999998,67.98109400000004],[-109.33556399999992,67.98027000000008],[-109.35193600000002,67.98136900000009],[-109.37805199999991,67.98692300000005],[-109.432503,68.00305200000003],[-109.49804699999993,68.0227660000001],[-109.50666799999993,68.02638200000013],[-109.53888699999999,68.04748500000005],[-109.54305999999991,68.05220000000008],[-109.50473,68.08888200000007],[-109.4974979999999,68.0935970000001],[-109.484734,68.09526099999994],[-109.44722000000002,68.09220900000003],[-109.410553,68.07193000000007],[-109.32167099999998,68.03997800000013],[-109.31527699999987,68.03581200000002],[-109.3116609999999,68.02554300000003],[-109.31111099999987,67.99775699999992],[-109.3116609999999,67.99192800000009],[-109.31416299999995,67.98580900000007],[-109.32167099999998,67.98109400000004]],[[-108.36054999999999,68.049713],[-108.37444299999993,68.04887400000007],[-108.38751200000002,68.05192599999998],[-108.40638699999994,68.06469700000008],[-108.40805099999994,68.06971699999997],[-108.40167200000002,68.07554600000014],[-108.38221699999991,68.092758],[-108.37444299999993,68.09553500000004],[-108.36193800000001,68.09693900000008],[-108.32000699999992,68.09887700000002],[-108.306107,68.09942599999994],[-108.29444899999999,68.09721400000006],[-108.297234,68.09109500000005],[-108.29778299999998,68.08554100000003],[-108.30082700000003,68.07943700000004],[-108.30860899999999,68.07470699999999],[-108.34916699999997,68.05192599999998],[-108.36054999999999,68.049713]],[[-110.21362299999998,68.03803999999997],[-110.23998999999998,68.03581200000002],[-110.25639299999995,68.03665200000006],[-110.258621,68.04193100000003],[-110.25,68.04609700000015],[-110.22165699999994,68.05664100000001],[-110.18195300000002,68.06971699999997],[-109.93276999999989,68.13192700000008],[-109.92166099999997,68.13415500000002],[-109.89639299999999,68.13749700000011],[-109.88583399999993,68.13638300000014],[-109.87721299999993,68.12692300000009],[-109.87748699999997,68.12136800000002],[-109.882767,68.1141510000001],[-109.88527699999997,68.10803200000004],[-109.88999899999993,68.10137900000007],[-109.89584399999995,68.09553500000004],[-109.903343,68.09054600000007],[-109.92111199999994,68.08166499999999],[-109.93222000000003,68.07916300000011],[-110.08721899999995,68.05331400000006],[-110.21362299999998,68.03803999999997]],[[-112.78056299999997,68.13108800000009],[-112.79276999999996,68.12942499999997],[-112.88999899999999,68.1372070000001],[-112.9058379999999,68.13916000000006],[-112.91722099999998,68.14221199999997],[-112.922234,68.14665200000002],[-112.91832699999992,68.153595],[-112.91306299999997,68.159424],[-112.90638699999994,68.16442900000004],[-112.89835399999998,68.16886900000009],[-112.88861099999997,68.172211],[-112.87638900000002,68.17387400000013],[-112.86110699999995,68.17414900000011],[-112.76722699999993,68.1666560000001],[-112.75167799999997,68.16470300000015],[-112.74973299999994,68.15803499999998],[-112.74472000000003,68.153595],[-112.74638399999998,68.14749099999995],[-112.75334199999998,68.14221199999997],[-112.76139799999993,68.13804600000009],[-112.78056299999997,68.13108800000009]],[[-74.21556099999998,68.11775199999994],[-74.16471899999999,68.06553600000007],[-73.974716,68.0410920000001],[-73.73638899999997,68.01361100000003],[-73.65547199999997,68.00770599999998],[-73.64334099999991,68.01220700000005],[-73.61999500000002,68.01499899999993],[-73.60888699999987,68.01554899999996],[-73.57806399999998,68.01443499999999],[-73.56750499999998,68.01304600000003],[-73.54388399999993,68.008331],[-73.43998699999997,67.98553500000014],[-73.42832900000002,67.98220800000001],[-73.41888399999999,67.97886699999998],[-73.41166699999997,67.9749910000001],[-73.40972899999991,67.97053499999998],[-73.34861799999999,67.82804899999996],[-73.36166400000002,67.81025700000009],[-73.37777699999987,67.79386900000003],[-73.38333099999994,67.78942900000004],[-73.40417500000001,67.7749940000001],[-73.41139199999992,67.77053799999999],[-73.41860999999994,67.766388],[-73.42944299999999,67.76277199999993],[-73.44943199999994,67.76249700000011],[-73.66416899999996,67.7747040000001],[-73.93221999999992,67.78637700000013],[-73.99305700000002,67.78804000000002],[-74.03832999999992,67.788589],[-74.08389299999988,67.78831500000007],[-74.11332700000003,67.7872010000001],[-74.16805999999985,67.78276100000005],[-74.22888199999994,67.77526899999992],[-74.2519529999999,67.77249100000012],[-74.26306199999999,67.77165199999996],[-74.30583200000001,67.76860000000005],[-74.32028200000002,67.7688750000001],[-74.38861099999997,67.77526899999992],[-74.40083300000003,67.77665700000006],[-74.48110999999994,67.78942900000004],[-74.535278,67.80470300000013],[-74.56416299999995,67.81442300000003],[-74.58168,67.82138100000003],[-74.59722899999997,67.82859800000011],[-74.64083899999997,67.85220300000009],[-74.65972899999991,67.86470000000008],[-74.68443300000001,67.88192700000008],[-74.758896,67.95027199999998],[-74.77223200000003,67.96331800000007],[-74.77555799999988,67.96914700000008],[-74.777222,67.97387700000013],[-74.77806099999992,68.00610400000011],[-74.77749599999999,68.01776100000006],[-74.773056,68.02998400000013],[-74.76000999999997,68.05442800000003],[-74.75418100000002,68.06053200000008],[-74.74861099999993,68.06553600000007],[-74.73194899999987,68.07083100000011],[-74.718613,68.07222000000007],[-74.62999000000002,68.07859800000006],[-74.61527999999998,68.07832300000007],[-74.43666100000002,68.097488],[-74.36389200000002,68.166382],[-74.35583499999996,68.17275999999998],[-74.34695399999993,68.176376],[-74.339447,68.17719999999997],[-74.32250999999991,68.17303500000014],[-74.26889,68.15498400000001],[-74.239441,68.14498900000007],[-74.23167399999994,68.14193699999998],[-74.21639999999996,68.13415500000002],[-74.21250900000001,68.13053899999994],[-74.21083099999998,68.12498499999998],[-74.21556099999998,68.11775199999994]],[[-65.64222699999999,68.159424],[-65.56639100000001,68.15220599999998],[-65.512787,68.15277100000003],[-65.502792,68.15109300000012],[-65.49777199999994,68.14776599999999],[-65.49444599999993,68.14248700000002],[-65.495544,68.128311],[-65.50083899999998,68.12191800000005],[-65.516953,68.11303700000008],[-65.525284,68.10971100000006],[-65.67555199999998,68.09610000000009],[-65.686935,68.0958250000001],[-65.69610599999993,68.09887700000002],[-65.70973199999997,68.1060940000001],[-65.71389799999997,68.11276200000009],[-65.72193899999996,68.16442900000004],[-65.716949,68.17581200000006],[-65.71167000000003,68.18026700000007],[-65.70140099999998,68.18136600000008],[-65.67582699999997,68.17997700000006],[-65.65666199999993,68.17526200000003],[-65.64834599999995,68.16859400000004],[-65.64666699999992,68.16360500000008],[-65.64222699999999,68.159424]],[[-107.47361799999993,68.14471400000008],[-107.48500100000001,68.14248700000002],[-107.50140399999998,68.14360000000005],[-107.55499299999991,68.16053799999997],[-107.55416899999994,68.16609199999999],[-107.54499800000002,68.16998300000006],[-107.5038909999999,68.18248000000006],[-107.49472000000003,68.18664600000011],[-107.48444399999994,68.18969700000014],[-107.46806300000003,68.188583],[-107.46193700000003,68.18414299999995],[-107.46028100000001,68.1791530000001],[-107.45935800000001,68.17562900000001],[-107.45667299999997,68.17442300000005],[-107.45527600000003,68.16914400000007],[-107.45584099999996,68.16360500000008],[-107.46694899999994,68.15026899999998],[-107.47361799999993,68.14471400000008]],[[-104.453056,68.10220300000003],[-104.48277299999995,68.07971200000003],[-104.497772,68.08027599999997],[-104.50334199999992,68.08471700000007],[-104.55304699999999,68.14027400000003],[-104.55610699999994,68.14526400000011],[-104.55695299999996,68.15026899999998],[-104.553879,68.16165199999995],[-104.54666099999997,68.16499299999998],[-104.42639200000002,68.19999700000005],[-104.41555799999998,68.20277399999998],[-104.391953,68.20694000000009],[-104.37721299999998,68.19970700000005],[-104.36860699999994,68.19053600000012],[-104.370003,68.1849820000001],[-104.37416100000002,68.17886399999998],[-104.40499899999992,68.13943500000005],[-104.453056,68.10220300000003]],[[-107.38890100000003,68.172211],[-107.40278599999999,68.17164599999995],[-107.41111799999999,68.17553700000002],[-107.44167299999992,68.19692999999995],[-107.445267,68.20166],[-107.43998699999997,68.208328],[-107.42944299999999,68.21138000000008],[-107.41443599999997,68.21110500000009],[-107.30972300000002,68.20915200000013],[-107.295547,68.20748900000001],[-107.291672,68.20277399999998],[-107.31054699999999,68.19609100000002],[-107.38890100000003,68.172211]],[[-111.833328,68.18193100000008],[-111.84722899999997,68.1808170000001],[-111.860817,68.18359400000003],[-111.86554699999999,68.18803400000002],[-111.83222999999998,68.20498700000013],[-111.81416300000001,68.21249400000005],[-111.79194599999994,68.21775800000006],[-111.77944899999994,68.21943700000003],[-111.764183,68.21943700000003],[-111.75499699999995,68.21582000000012],[-111.75945299999995,68.20915200000013],[-111.76666299999994,68.20637500000004],[-111.79194599999994,68.19358800000003],[-111.81111099999998,68.18692000000004],[-111.833328,68.18193100000008]],[[-98.650284,68.18026700000007],[-98.67443800000001,68.17387400000013],[-98.704453,68.176086],[-98.702789,68.1916500000001],[-98.69332899999995,68.21360800000002],[-98.68443300000001,68.21887200000003],[-98.67222600000002,68.22053499999993],[-98.65722699999998,68.21943700000003],[-98.64306599999998,68.21609500000011],[-98.63861099999997,68.21165500000012],[-98.63667299999992,68.20665000000002],[-98.64306599999998,68.20166],[-98.650284,68.18026700000007]],[[-74.06277499999999,68.15165700000006],[-74.07362399999994,68.15081800000007],[-74.13833599999992,68.17025800000005],[-74.16972399999997,68.19552599999997],[-74.17639200000002,68.204163],[-74.17138699999998,68.20860299999998],[-74.15583799999996,68.21748400000013],[-74.13806199999999,68.22581500000001],[-74.11721799999992,68.23220799999996],[-74.10583500000001,68.2352600000001],[-74.09722899999991,68.23664900000006],[-74.08694499999996,68.2352600000001],[-74.07972699999999,68.232483],[-74.07528699999995,68.22776799999997],[-74.073059,68.22387700000007],[-74.06332399999991,68.20304900000002],[-74.05555700000002,68.17248500000011],[-74.05444299999999,68.15998800000011],[-74.05721999999997,68.15498400000001],[-74.06277499999999,68.15165700000006]],[[-108.59028599999999,68.21443199999999],[-108.63944999999995,68.15138200000001],[-108.6499859999999,68.15248100000002],[-108.65862299999998,68.15609700000005],[-108.67748999999998,68.16886900000009],[-108.67360699999995,68.18637100000012],[-108.67194399999994,68.19108599999998],[-108.63500999999997,68.2285920000001],[-108.62748699999992,68.23359700000015],[-108.60555999999997,68.23692299999999],[-108.56610099999989,68.24054000000012],[-108.55972300000002,68.23609900000002],[-108.59028599999999,68.21443199999999]],[[-109.78388999999999,68.13749700000011],[-109.81166099999996,68.13610799999998],[-109.828056,68.13693200000012],[-109.84137699999997,68.13970899999998],[-109.84999099999999,68.14332599999994],[-109.85665899999998,68.14776599999999],[-109.854172,68.15386999999998],[-109.845551,68.15803499999998],[-109.77194199999997,68.18830900000006],[-109.676941,68.22415200000006],[-109.64417300000002,68.23220799999996],[-109.58889799999997,68.24525499999999],[-109.57749899999988,68.24748200000005],[-109.56806899999998,68.24720800000011],[-109.57055699999995,68.2410890000001],[-109.57695000000001,68.232483],[-109.58194700000001,68.22581500000001],[-109.59416199999993,68.21443199999999],[-109.67388899999997,68.17330900000007],[-109.7625119999999,68.14332599999994],[-109.7725069999999,68.13998400000003],[-109.78388999999999,68.13749700000011]],[[-66.31361400000003,68.14776599999999],[-66.32695000000001,68.14749099999995],[-66.35499599999997,68.15331999999995],[-66.38110399999994,68.15860000000004],[-66.39639299999993,68.16110200000008],[-66.46861299999995,68.17109700000003],[-66.52778599999988,68.17776500000002],[-66.57084700000001,68.18136600000008],[-66.601944,68.18248000000006],[-66.60722399999997,68.21720900000008],[-66.5,68.23970000000008],[-66.29943799999995,68.25444000000005],[-66.22193899999996,68.2410890000001],[-66.25666799999999,68.16360500000008],[-66.26972999999992,68.15860000000004],[-66.30139199999996,68.14915499999995],[-66.31361400000003,68.14776599999999]],[[-96.38417099999992,68.20082100000002],[-96.422775,68.19831800000009],[-96.436935,68.19859300000007],[-96.44860799999992,68.20248400000014],[-96.45472699999993,68.20665000000002],[-96.462784,68.21609500000011],[-96.45666499999999,68.22164900000013],[-96.375,68.25471500000003],[-96.36416600000001,68.2580410000001],[-96.35082999999997,68.25860599999993],[-96.34445199999993,68.25416600000011],[-96.31750499999993,68.23193400000002],[-96.32444800000002,68.22109999999998],[-96.33889799999992,68.21220400000004],[-96.34889199999986,68.20803799999999],[-96.36000100000001,68.20471200000009],[-96.38417099999992,68.20082100000002]],[[-78.57167099999998,68.2002720000001],[-78.65556300000003,68.18775900000003],[-78.662216,68.18914799999999],[-78.66027799999989,68.19636500000013],[-78.64306599999998,68.21832300000005],[-78.60722399999992,68.24832200000009],[-78.59388699999988,68.25555400000002],[-78.58111599999995,68.25888099999997],[-78.55027799999999,68.26361099999997],[-78.54804999999999,68.26304600000014],[-78.54527300000001,68.25],[-78.525284,68.23359700000015],[-78.51722699999993,68.22331200000002],[-78.5225069999999,68.21775800000006],[-78.53222699999998,68.21304300000003],[-78.55888399999998,68.20304900000002],[-78.57167099999998,68.2002720000001]],[[-86.42639199999996,68.06915299999997],[-86.39750700000002,68.02165200000013],[-86.37832599999996,67.9933170000001],[-86.37666299999995,67.988586],[-86.368607,67.95471199999997],[-86.37083399999995,67.93997200000001],[-86.39611799999994,67.85971100000012],[-86.40360999999996,67.84887700000007],[-86.465012,67.78665200000012],[-86.47084000000001,67.78137200000009],[-86.48998999999998,67.77053799999999],[-86.57194500000003,67.72886700000004],[-86.58361799999994,67.72526600000015],[-86.59666399999998,67.72554000000008],[-86.67666599999995,67.73165899999992],[-86.69055200000003,67.73387100000002],[-86.85833699999995,67.79693599999996],[-86.87943999999993,67.81025700000009],[-86.88389599999994,67.81498699999997],[-86.910278,67.8477630000001],[-86.91861,67.86192299999999],[-86.926941,67.87637300000011],[-86.94583099999994,67.90942400000006],[-86.9519499999999,67.92387400000001],[-86.94860799999998,67.92886400000003],[-86.94055199999997,67.93441800000005],[-86.92610199999996,67.93136600000008],[-86.91332999999997,67.93193100000013],[-86.85444599999988,67.95416300000005],[-86.84333799999996,67.95860300000004],[-86.83889799999997,67.98637400000013],[-86.83694500000001,68.00109900000007],[-86.84083599999991,68.01081800000003],[-86.84750399999996,68.020264],[-86.851944,68.02499400000005],[-86.86389200000002,68.02915999999993],[-86.87832599999996,68.03221099999996],[-86.90417500000001,68.03054800000007],[-86.93249500000002,68.03581200000002],[-86.94221499999998,68.04026799999997],[-86.98666400000002,68.06164600000005],[-86.9927669999999,68.06666600000011],[-86.99194299999994,68.07165500000008],[-86.98832699999997,68.08166499999999],[-86.978882,68.09693900000008],[-86.90638699999994,68.18026700000007],[-86.89805599999994,68.18553199999997],[-86.74249299999991,68.28276099999994],[-86.71194499999996,68.299149],[-86.70056199999993,68.30358900000004],[-86.675003,68.3060910000001],[-86.64666699999992,68.3016510000001],[-86.60278299999999,68.29136700000004],[-86.53860500000002,68.2705380000001],[-86.487503,68.24859600000002],[-86.45861799999989,68.23553500000008],[-86.41111799999999,68.20887800000003],[-86.40666199999998,68.204163],[-86.40278599999999,68.19442700000002],[-86.43499800000001,68.1624910000001],[-86.43388400000003,68.09860199999997],[-86.43249500000002,68.08888200000007],[-86.42639199999996,68.06915299999997]],[[-111.71028100000001,68.22053499999993],[-111.72556299999997,68.220261],[-111.74221799999998,68.22109999999998],[-111.75583599999993,68.22360200000003],[-111.76500699999997,68.22720300000009],[-111.77194199999991,68.23136900000003],[-111.77639799999992,68.23609900000002],[-111.77887699999997,68.2410890000001],[-111.77916699999997,68.24693300000013],[-111.777222,68.25305200000014],[-111.77166699999998,68.25888099999997],[-111.71501199999994,68.29693600000007],[-111.70388799999989,68.29942299999993],[-111.52887699999991,68.31080600000013],[-111.51363400000002,68.31109600000013],[-111.49944299999993,68.29693600000007],[-111.50446299999999,68.29248000000013],[-111.52861000000001,68.29054300000007],[-111.55777,68.2894290000001],[-111.58277899999996,68.28610199999997],[-111.60526999999996,68.28109699999993],[-111.61361699999998,68.27665700000011],[-111.62777699999998,68.26666300000011],[-111.633331,68.26081800000003],[-111.63305699999995,68.24971],[-111.63054699999992,68.24443100000002],[-111.63249200000001,68.23831200000001],[-111.63945000000001,68.23332199999993],[-111.64943700000003,68.22998000000001],[-111.67166099999997,68.22470100000004],[-111.696663,68.22137500000002],[-111.71028100000001,68.22053499999993]],[[-75.58277900000002,68.30026200000009],[-75.5625,68.29443399999997],[-75.453888,68.26666300000011],[-75.42971799999998,68.26220699999999],[-75.38667299999992,68.2580410000001],[-75.26306199999993,68.24720800000011],[-75.22888199999994,68.24552900000009],[-75.19915800000001,68.24552900000009],[-75.18305999999995,68.24386600000003],[-75.15861499999994,68.23997500000013],[-75.13473499999986,68.23471100000012],[-75.12193300000001,68.22915600000005],[-75.03056300000003,68.16720599999996],[-75.01194800000002,68.14776599999999],[-75.00306699999999,68.13220200000006],[-75,68.1196900000001],[-75.00222799999995,68.1144260000001],[-75.04916399999996,68.0413670000001],[-75.05249000000003,68.03665200000006],[-75.06332399999997,68.02720600000009],[-75.09167500000001,68.009995],[-75.148056,67.97442600000005],[-75.1536099999999,67.96943700000008],[-75.16444399999995,67.95416300000005],[-75.16444399999995,67.9494170000001],[-75.16278099999994,67.94386300000008],[-75.11389199999996,67.86192299999999],[-75.104446,67.84748800000006],[-75.06416299999995,67.78248600000006],[-75.02500899999995,67.62553400000002],[-75.025284,67.61943100000008],[-75.06889299999989,67.54275500000011],[-75.07194499999997,67.53887900000007],[-75.13362099999995,67.48165899999998],[-75.16111799999999,67.46388200000013],[-75.19860799999998,67.44331400000004],[-75.38806199999993,67.35470599999996],[-75.39584399999995,67.35304300000007],[-75.5536039999999,67.3336030000001],[-75.66250600000001,67.305252],[-75.84445199999999,67.26415999999995],[-75.94610599999993,67.251938],[-76.11665299999993,67.25555400000002],[-76.22694399999995,67.26081800000003],[-76.30860899999999,67.25360100000012],[-76.49082900000002,67.23637400000007],[-76.66361999999998,67.219986],[-76.69305399999996,67.22109999999998],[-76.97805799999998,67.24552900000015],[-77.02667200000002,67.25499000000008],[-77.04472399999992,67.2605440000001],[-77.05721999999992,67.26721200000009],[-77.07444800000002,67.28082300000005],[-77.10139500000002,67.30581699999999],[-77.24694799999997,67.45193499999999],[-77.24722299999996,67.45721400000014],[-77.23693799999995,67.49525499999999],[-77.22444199999995,67.53553800000003],[-77.22582999999997,67.54386900000009],[-77.23028599999998,67.55442800000014],[-77.24221799999992,67.56915300000009],[-77.27500899999995,67.61469999999997],[-77.31221,67.67637600000012],[-77.32084700000001,67.69164999999998],[-77.32250999999991,67.69802900000008],[-77.31916799999999,67.71138000000002],[-77.25834699999996,67.81637599999993],[-77.25195300000001,67.82638500000013],[-77.24333200000001,67.83749400000005],[-77.23306299999996,67.84887700000007],[-77.22833300000002,67.8538670000001],[-77.220551,67.86192299999999],[-77.203888,67.87637300000011],[-76.86555499999997,68.15776100000005],[-76.85888699999992,68.16165199999995],[-76.72610500000002,68.23887600000012],[-76.70249899999993,68.24859600000002],[-76.67388899999997,68.25915500000008],[-76.63500999999991,68.27192700000006],[-76.60694899999993,68.27943400000004],[-76.28195199999999,68.33276400000011],[-76.26722699999993,68.33276400000011],[-76.2583469999999,68.3316650000001],[-76.25195300000001,68.328598],[-76.25,68.32304400000004],[-76.25306699999993,68.31359900000012],[-76.24916100000002,68.30748000000011],[-76.23582499999998,68.303314],[-76.22166399999998,68.30137600000006],[-76.116104,68.29664600000007],[-76.083328,68.29525799999993],[-76.06054699999999,68.29693600000007],[-76.05277999999998,68.29859899999997],[-76.03222700000003,68.30470300000002],[-76.000565,68.31693999999999],[-75.98500100000001,68.32443200000012],[-75.96639999999996,68.3311000000001],[-75.95417800000001,68.33387800000008],[-75.93083199999995,68.33692900000011],[-75.91749599999991,68.33831800000007],[-75.88751199999996,68.33970599999998],[-75.81806899999987,68.33665500000001],[-75.75666799999999,68.33248900000007],[-75.72610500000002,68.33027600000014],[-75.69554099999988,68.3269350000001],[-75.66749600000003,68.322769],[-75.62249799999995,68.31303400000007],[-75.60249299999987,68.30748000000011],[-75.58277900000002,68.30026200000009]],[[-79.02055399999995,68.16914400000007],[-79.03250099999991,68.16526800000003],[-79.07501200000002,68.16832000000011],[-79.08972199999994,68.17025800000005],[-79.10166900000002,68.17526200000003],[-79.17138699999987,68.20526100000006],[-79.17694099999994,68.20942700000012],[-79.17999299999997,68.21554599999996],[-79.18832399999997,68.24720800000011],[-79.19110099999995,68.31944299999998],[-79.15167199999996,68.34664900000001],[-79.14195299999994,68.34887700000013],[-79.12554899999998,68.35026600000015],[-79.09944199999995,68.34860200000014],[-79.04499799999996,68.34332299999994],[-78.92999299999991,68.33888200000001],[-78.82611099999997,68.29553200000004],[-78.80999800000001,68.28749099999999],[-78.80471799999992,68.283051],[-78.80166600000001,68.2791600000001],[-78.80221599999993,68.272491],[-78.80526699999996,68.26666300000011],[-78.81555199999991,68.25555400000002],[-78.82333399999993,68.25054899999998],[-78.84194899999989,68.24054000000012],[-79.02055399999995,68.16914400000007]],[[-100.07472200000001,68.34971600000011],[-100.08640299999996,68.29609700000009],[-100.09166700000003,68.284988],[-100.09944200000001,68.27859500000005],[-100.11221299999994,68.27638200000007],[-100.12832600000002,68.27832000000006],[-100.14028899999994,68.28166199999998],[-100.16443600000002,68.28858900000006],[-100.20056199999999,68.299149],[-100.22693600000002,68.31608600000004],[-100.23082699999992,68.31971700000008],[-100.21556099999998,68.318604],[-100.20249899999988,68.31971700000008],[-100.19110099999995,68.32222000000007],[-100.1183319999999,68.34721400000001],[-100.11000100000001,68.35247800000002],[-100.08583099999998,68.36886600000008],[-100.07668299999989,68.359711],[-100.07444799999996,68.35498000000007],[-100.07472200000001,68.34971600000011]],[[-82.05999799999995,68.3060910000001],[-82.07250999999997,68.30304000000007],[-82.27111799999994,68.33859300000012],[-82.31277499999999,68.34915199999995],[-82.32667500000002,68.35359199999999],[-82.33805799999999,68.35832200000004],[-82.34445199999988,68.36276200000003],[-82.34555099999994,68.36775200000011],[-82.333328,68.371918],[-82.23055999999997,68.38554399999998],[-82.216949,68.38415500000013],[-82.13555899999994,68.37275699999998],[-82.01251200000002,68.35081500000007],[-82.00111399999997,68.34637500000008],[-81.99722300000002,68.34137000000004],[-82.01000999999991,68.33276400000011],[-82.05999799999995,68.3060910000001]],[[-111.11444099999994,68.40582300000005],[-111.12832600000002,68.40498400000013],[-111.13751199999996,68.40859999999998],[-111.141953,68.41331500000001],[-111.14890300000002,68.42886399999992],[-111.14917000000003,68.43997200000013],[-111.141953,68.444977],[-111.13054699999992,68.44747900000004],[-111.11527999999998,68.44775400000009],[-111.09861799999999,68.44693000000012],[-111.08249699999993,68.44470200000012],[-111.07611099999991,68.43691999999999],[-111.08416699999998,68.42498800000004],[-111.10582699999998,68.40998800000006],[-111.11444099999994,68.40582300000005]],[[-99.04527300000001,68.42387400000007],[-99.05499299999991,68.40832499999999],[-99.14778100000001,68.44220000000007],[-99.15472399999999,68.44636500000007],[-99.15916399999992,68.451096],[-99.14973399999985,68.45526100000001],[-99.12110899999999,68.45498700000007],[-99.10526999999996,68.45304899999996],[-99.087219,68.44941699999998],[-99.04527300000001,68.42387400000007]],[[-74.162216,68.24609399999997],[-74.19055200000003,68.24247700000001],[-74.20777899999996,68.24331700000005],[-74.221115,68.24720800000011],[-74.22888199999994,68.25082399999997],[-74.24415599999986,68.26138300000002],[-74.260559,68.27331499999997],[-74.38861099999997,68.39833099999998],[-74.39973399999997,68.42025799999999],[-74.40222199999994,68.42776500000014],[-74.400284,68.43414300000012],[-74.39306599999992,68.4452510000001],[-74.37693799999988,68.45971700000013],[-74.360275,68.46388200000013],[-74.34083599999991,68.46249399999999],[-74.30776999999995,68.46165500000006],[-74.29388399999999,68.46054100000009],[-74.27944899999994,68.45832800000011],[-74.26972999999987,68.45471200000003],[-74.21749899999986,68.42608600000011],[-74.19804399999998,68.41499299999992],[-74.07945299999994,68.33859300000012],[-74.07472200000001,68.33082599999994],[-74.07749899999999,68.32554600000009],[-74.14445499999994,68.25444000000005],[-74.14973399999985,68.25],[-74.162216,68.24609399999997]],[[-100.71056399999998,68.40248099999997],[-100.72416699999997,68.401657],[-100.78943599999997,68.40998800000006],[-100.88971699999996,68.45277400000009],[-100.88027999999997,68.45721400000014],[-100.84889199999992,68.4649960000001],[-100.83029199999999,68.46859699999993],[-100.79332699999986,68.46887200000015],[-100.78611799999999,68.46470600000009],[-100.71806300000003,68.41192600000005],[-100.71305799999999,68.407486],[-100.71056399999998,68.40248099999997]],[[-110.86250299999995,68.47415200000006],[-110.92610199999996,68.46582000000006],[-111.05444299999999,68.46971100000013],[-111.08833299999998,68.47331199999996],[-111.09750400000001,68.47720300000003],[-111.09750400000001,68.48275799999993],[-111.09249899999998,68.48719800000015],[-111.08528099999995,68.49220300000002],[-111.07528699999995,68.49552900000003],[-110.984734,68.51554900000008],[-110.82167099999998,68.54803499999997],[-110.80332899999996,68.54637100000014],[-110.79222099999998,68.54331999999994],[-110.76390100000003,68.53360000000004],[-110.74582700000002,68.52638200000007],[-110.69833399999999,68.49136400000003],[-110.69611399999991,68.48637400000001],[-110.70889299999988,68.48471100000006],[-110.72833300000002,68.48442100000005],[-110.79499799999996,68.47998000000013],[-110.86250299999995,68.47415200000006]],[[-110.58693700000003,68.52415500000001],[-110.625,68.51944000000015],[-110.6600039999999,68.521927],[-110.72112299999998,68.5310970000001],[-110.73249800000002,68.53414900000001],[-110.74610899999999,68.54248000000007],[-110.75974300000001,68.55664100000007],[-110.76194800000002,68.56164599999994],[-110.75473,68.566666],[-110.63861099999997,68.56944300000009],[-110.62832600000002,68.559143],[-110.52971600000001,68.54803499999997],[-110.520554,68.54414400000007],[-110.51834100000002,68.53915400000005],[-110.52722199999988,68.53498799999994],[-110.53859699999992,68.53248600000006],[-110.58693700000003,68.52415500000001]],[[-104.54527300000001,68.39610299999998],[-104.58667000000003,68.39444000000009],[-104.64666699999998,68.395828],[-104.693329,68.40248099999997],[-104.708618,68.40525800000006],[-104.75974299999996,68.41804500000006],[-104.88305699999995,68.449997],[-104.91915899999992,68.45999100000006],[-104.9375,68.46748400000007],[-105.08167999999995,68.54637100000014],[-105.04415899999998,68.56275900000003],[-105.024719,68.57054099999999],[-105.01390100000003,68.57331800000009],[-104.98999000000003,68.57748400000014],[-104.93859900000001,68.583328],[-104.91000399999996,68.58387800000003],[-104.76167299999997,68.58276400000005],[-104.74610899999993,68.58221400000002],[-104.71193699999998,68.57859799999994],[-104.682503,68.57388300000008],[-104.55332899999996,68.5372010000001],[-104.52999899999992,68.53054800000012],[-104.50917099999992,68.52331500000014],[-104.48277299999995,68.51165800000001],[-104.46916199999998,68.50332600000002],[-104.46362299999998,68.49887100000001],[-104.44915799999995,68.48526000000004],[-104.44055200000003,68.47608900000006],[-104.42777999999987,68.45694000000003],[-104.42527799999999,68.44136000000003],[-104.426941,68.43580600000001],[-104.43083199999995,68.42970300000007],[-104.43499799999995,68.42359900000002],[-104.44138299999997,68.41720600000008],[-104.45111099999991,68.41331500000001],[-104.48332199999999,68.40470900000008],[-104.51917299999997,68.39833099999998],[-104.54527300000001,68.39610299999998]],[[-105.139183,68.53637700000013],[-105.12609900000001,68.53332500000005],[-105.11305199999998,68.534424],[-105.10109699999998,68.536652],[-105.08693699999998,68.53692600000011],[-105.07861300000002,68.53305100000011],[-105.06639099999995,68.51914999999997],[-105.05972300000002,68.50943000000007],[-105.05888400000003,68.50416600000005],[-105.06833599999999,68.50027499999999],[-105.08612099999999,68.50277700000004],[-105.11193800000001,68.50888100000009],[-105.23361199999994,68.54109199999999],[-105.24416400000001,68.54470800000007],[-105.29110700000001,68.57693500000005],[-105.29222099999998,68.58221400000002],[-105.28138699999994,68.58499100000012],[-105.25611900000001,68.58831800000002],[-105.24305700000002,68.58970599999998],[-105.228882,68.58998099999997],[-105.21112099999993,68.5877690000001],[-105.18582200000003,68.58082600000012],[-105.18611099999998,68.57666],[-105.18167099999994,68.566666],[-105.17832900000002,68.56164599999994],[-105.139183,68.53637700000013]],[[-113.78611799999999,68.58276400000005],[-113.80166599999995,68.58248900000001],[-113.85249299999998,68.58415200000013],[-113.88945000000001,68.58692900000005],[-113.93138099999999,68.59387200000003],[-113.95259099999987,68.59738900000008],[-113.95966299999998,68.60319500000014],[-113.96611000000001,68.61109900000008],[-113.95667300000002,68.61469999999991],[-113.94248999999996,68.61581400000011],[-113.91388699999999,68.61581400000011],[-113.89972699999998,68.61692800000009],[-113.83693700000003,68.60887100000008],[-113.80027799999999,68.60609399999998],[-113.78611799999999,68.60386699999998],[-113.77667200000002,68.60026600000009],[-113.76194800000002,68.59220900000008],[-113.761124,68.58665500000012],[-113.77223199999997,68.58387800000003],[-113.78611799999999,68.58276400000005]],[[-100.74054699999999,68.59637500000002],[-100.78388999999993,68.59443700000008],[-100.86805699999991,68.60304300000001],[-100.88249200000001,68.61137400000007],[-100.87666300000001,68.61637900000011],[-100.86527999999998,68.61914100000001],[-100.85305800000003,68.62081899999998],[-100.839722,68.62164300000012],[-100.81388900000002,68.61914100000001],[-100.75556899999992,68.60775800000005],[-100.74082899999996,68.60470600000008],[-100.73361199999994,68.60054000000002],[-100.74054699999999,68.59637500000002]],[[-78.468887,68.563873],[-78.4744419999999,68.55831900000004],[-78.48222399999992,68.55331399999994],[-78.50306699999999,68.54553200000004],[-78.5308379999999,68.54109199999999],[-78.54583699999995,68.540817],[-78.56221,68.54193099999998],[-78.59922799999993,68.55064400000003],[-78.61455499999994,68.55365000000006],[-78.63890100000003,68.55802899999998],[-78.65472399999999,68.55859400000003],[-78.66888399999999,68.5541530000001],[-78.72471599999994,68.521927],[-78.71583599999991,68.51582300000001],[-78.69137599999999,68.50915500000002],[-78.67443800000001,68.50972000000007],[-78.65333599999997,68.51249699999994],[-78.63612399999994,68.51304600000009],[-78.62194799999997,68.50972000000007],[-78.617615,68.50721700000008],[-78.610275,68.5022130000001],[-78.61082499999998,68.49803200000002],[-78.61805699999996,68.49220300000002],[-78.70556599999998,68.45166000000012],[-78.71611000000001,68.44775400000009],[-78.74305700000002,68.44274899999999],[-78.77667200000002,68.43914799999999],[-78.79527299999995,68.43858300000011],[-78.81304899999992,68.43887300000011],[-78.82806399999998,68.44081100000005],[-78.86166399999996,68.44636500000007],[-78.87638900000002,68.45054600000014],[-78.95973200000003,68.47470099999998],[-78.94610599999999,68.50804100000005],[-78.94332899999995,68.51193200000012],[-78.936935,68.516388],[-78.82278400000001,68.54775999999998],[-78.80943299999996,68.55053700000008],[-78.791672,68.55026200000003],[-78.75917099999998,68.54803499999997],[-78.74388099999999,68.54609700000003],[-78.72389199999998,68.54748499999994],[-78.7041779999999,68.55470300000013],[-78.69888300000002,68.55802899999998],[-78.68888900000002,68.56469700000014],[-78.670837,68.57887299999999],[-78.66860999999994,68.583328],[-78.67277499999994,68.58859300000006],[-78.68055700000002,68.59332300000011],[-78.69305400000002,68.59693900000013],[-78.70584100000002,68.60054000000002],[-78.78416399999998,68.61859099999998],[-78.85139500000002,68.63415500000008],[-78.894455,68.64637800000014],[-78.89805599999994,68.64888000000002],[-78.88972499999994,68.65277100000009],[-78.86389200000002,68.65971400000012],[-78.83778399999989,68.66110200000003],[-78.72000100000002,68.65721100000013],[-78.68943799999994,68.65332000000006],[-78.495834,68.62776200000013],[-78.48194899999993,68.62498500000004],[-78.46945199999993,68.62109399999997],[-78.460556,68.61720300000007],[-78.46722399999999,68.56915300000009],[-78.468887,68.563873]],[[-74.76889,68.67387400000001],[-74.75666799999999,68.67276000000004],[-74.65583799999996,68.65498400000007],[-74.648346,68.65220600000009],[-74.52223199999997,68.56526200000002],[-74.51834099999991,68.55859400000003],[-74.53195199999988,68.55276500000002],[-74.55139200000002,68.55053700000008],[-74.58694499999996,68.54887400000013],[-74.7266689999999,68.55609100000004],[-74.74276700000001,68.55748000000006],[-74.80721999999992,68.56359900000007],[-74.82194500000003,68.56581099999994],[-74.83389299999999,68.56971700000003],[-74.84333799999996,68.57582100000008],[-74.870544,68.59887700000007],[-74.8830569999999,68.61303700000002],[-74.890289,68.62498500000004],[-74.80583200000001,68.66886899999997],[-74.796112,68.67164600000007],[-74.787216,68.67303500000003],[-74.77999899999998,68.67387400000001],[-74.77194199999991,68.67303500000003],[-74.76889,68.67387400000001]],[[-114.04723399999995,68.61360200000001],[-114.06139399999995,68.61248800000004],[-114.075287,68.61469999999991],[-114.10193600000002,68.625809],[-114.12666299999995,68.63720699999999],[-114.14890299999996,68.649429],[-114.16166699999991,68.6580350000001],[-114.18998699999986,68.68026699999996],[-114.186394,68.68359400000008],[-114.15387699999991,68.67970300000002],[-114.141953,68.67692599999992],[-114.14111299999996,68.67109700000009],[-114.05638099999987,68.63581800000003],[-114.04888900000003,68.63192700000013],[-114.041672,68.62776200000013],[-114.03778099999994,68.61692800000009],[-114.04723399999995,68.61360200000001]],[[-74.81138599999991,68.32054100000005],[-74.81750499999993,68.318604],[-75,68.33334400000012],[-75.00222799999995,68.33360300000004],[-75.00834699999996,68.3372040000001],[-75.01028400000001,68.34664900000001],[-75.00500499999993,68.35359199999999],[-75.002792,68.35914600000001],[-75.00140399999998,68.366379],[-75.01501499999995,68.37970000000013],[-75.02917499999995,68.39054900000002],[-75.03750599999995,68.39471400000002],[-75.08167999999989,68.40498400000013],[-75.10943599999996,68.40693700000008],[-75.13806199999999,68.40998800000006],[-75.15306099999987,68.41304000000002],[-75.241379,68.43637100000007],[-75.26390099999992,68.444977],[-75.29472399999997,68.457764],[-75.36999500000002,68.48970000000003],[-75.396118,68.503601],[-75.41639700000002,68.51805100000013],[-75.41639700000002,68.52442900000011],[-75.39695699999987,68.61109900000008],[-75.38917500000002,68.62303200000008],[-75.30777,68.69470200000006],[-75.29972799999996,68.70054600000009],[-75.28056299999997,68.70971700000007],[-75.25472999999988,68.71748400000001],[-75.239441,68.71804800000012],[-75.01445000000001,68.67720000000003],[-75,68.6722410000001],[-74.94276400000001,68.57609600000006],[-74.93832399999991,68.57165500000013],[-74.93138099999993,68.566666],[-74.83694500000001,68.51165800000001],[-74.801941,68.50109900000012],[-74.78500400000001,68.49470500000007],[-74.78028899999998,68.49026500000008],[-74.77223200000003,68.47998000000013],[-74.76834100000002,68.47331199999996],[-74.77639799999992,68.41053799999992],[-74.81138599999991,68.32054100000005]],[[-84.80804399999994,68.76388500000002],[-84.82139599999988,68.76361100000008],[-84.83583099999998,68.766663],[-84.93916300000001,68.79359400000004],[-84.90777600000001,68.8035890000001],[-84.89527900000002,68.80720500000001],[-84.88249200000001,68.80970799999994],[-84.85583500000001,68.81080600000001],[-84.841385,68.80748],[-84.837219,68.80276500000014],[-84.837784,68.79693600000013],[-84.80166599999995,68.76915000000008],[-84.80804399999994,68.76388500000002]],[[-68.110275,68.78276100000005],[-67.8074949999999,68.73359700000003],[-67.78167699999995,68.72915599999993],[-67.679169,68.71137999999996],[-67.66833500000001,68.70721400000008],[-67.66139199999992,68.7019350000001],[-67.662216,68.69831799999997],[-67.67666600000001,68.6958160000001],[-67.85055499999993,68.69775400000003],[-67.86972000000003,68.69859299999996],[-67.89778100000001,68.70498700000002],[-67.91860999999989,68.71249399999994],[-67.95140099999998,68.72164900000001],[-68.03916900000002,68.73803700000008],[-68.18832399999991,68.76388500000002],[-68.306107,68.7794340000001],[-68.323624,68.77998400000013],[-68.33999599999999,68.77859499999994],[-68.35249299999998,68.77554300000003],[-68.36749299999985,68.7749940000001],[-68.43360899999993,68.78109700000005],[-68.45140099999998,68.78387500000002],[-68.45777900000002,68.78581200000008],[-68.45944199999997,68.7910920000001],[-68.45527599999997,68.80219999999991],[-68.45083599999987,68.80720500000001],[-68.43916300000001,68.81248500000004],[-68.42832899999996,68.81303400000002],[-68.4188999999999,68.81025700000009],[-68.37554899999992,68.80802900000015],[-68.24194299999994,68.79887400000007],[-68.224716,68.79748500000011],[-68.110275,68.78276100000005]],[[-101.83112299999999,68.5669400000001],[-101.84555099999989,68.566666],[-101.86028299999998,68.56971700000003],[-101.88527699999986,68.57638500000002],[-101.90527299999991,68.58387800000003],[-102.00583599999999,68.61387599999995],[-102.112213,68.62359600000002],[-102.23000300000001,68.64027399999992],[-102.254997,68.64694200000008],[-102.31639100000001,68.67221100000006],[-102.3125,68.68858300000005],[-102.21665999999999,68.718323],[-102.14862099999999,68.73498499999994],[-102.13639799999993,68.7369230000001],[-102.11389200000002,68.74247700000006],[-102.09249899999998,68.74887100000012],[-102.073059,68.75694300000009],[-102.05638099999993,68.76805100000007],[-102.05166600000001,68.77388000000008],[-102.04943799999995,68.7794340000001],[-102.04972799999996,68.78471400000001],[-102.05555699999996,68.79443400000008],[-102.05555699999996,68.79971300000005],[-102.05082700000003,68.80554200000006],[-102.04276999999996,68.81109600000008],[-102.02306399999992,68.81944300000004],[-101.99833699999999,68.8230440000001],[-101.98500099999995,68.82415800000007],[-101.95612299999999,68.82415800000007],[-101.93943799999994,68.82249499999995],[-101.9119419999999,68.8160860000001],[-101.77861000000001,68.78387500000002],[-101.69387799999993,68.76805100000007],[-101.69999699999994,68.73776200000003],[-101.68055699999996,68.672485],[-101.68250299999994,68.66165200000006],[-101.701683,68.63777200000004],[-101.83112299999999,68.5669400000001]],[[-102.60082999999997,68.813309],[-102.60749799999996,68.80914300000012],[-102.69695299999995,68.81303400000002],[-102.70722999999992,68.81666600000011],[-102.68888900000002,68.83332800000011],[-102.67859599999997,68.836929],[-102.64055599999995,68.84193400000004],[-102.61277799999993,68.84304800000001],[-102.59889199999986,68.84109500000005],[-102.60221899999999,68.83415200000007],[-102.60082999999997,68.813309]],[[-89.94444299999998,68.66220099999998],[-89.95638999999994,68.66165200000006],[-89.97416699999997,68.705826],[-89.99916099999996,68.73081999999994],[-90.01722699999993,68.74054000000007],[-90.02250700000002,68.74581900000004],[-90.02749599999999,68.75248699999997],[-90.02778599999999,68.75860600000004],[-90.02555799999993,68.771927],[-90.00306699999993,68.80664100000001],[-89.958618,68.83804299999997],[-89.94444299999998,68.84748800000006],[-89.93194599999998,68.85220300000009],[-89.9219359999999,68.8538670000001],[-89.91444399999995,68.85304300000013],[-89.781677,68.766663],[-89.78416399999992,68.76081800000009],[-89.791382,68.75248699999997],[-89.80888400000003,68.73332200000004],[-89.85749800000002,68.70054600000009],[-89.87748699999992,68.690811],[-89.94444299999998,68.66220099999998]],[[-114.35082999999997,68.87164300000006],[-114.37917299999992,68.86943100000002],[-114.39639299999999,68.86970500000012],[-114.429169,68.87359600000002],[-114.45333900000003,68.87942500000003],[-114.46305799999999,68.88275100000004],[-114.468613,68.88720699999999],[-114.471657,68.89248700000002],[-114.46056399999998,68.89526400000011],[-114.44444299999998,68.8961030000001],[-114.424713,68.89694200000002],[-114.37609899999995,68.8936000000001],[-114.340843,68.89054900000008],[-114.328888,68.887497],[-114.32333399999999,68.88304100000005],[-114.32861299999996,68.87692300000009],[-114.33805799999993,68.87359600000002],[-114.35082999999997,68.87164300000006]],[[-67.84777799999995,68.85192899999998],[-67.86389199999996,68.849426],[-67.88305699999995,68.84999099999999],[-67.89723200000003,68.85304300000013],[-67.908051,68.85720800000013],[-67.95638999999994,68.91526800000003],[-67.96055599999994,68.922485],[-67.96055599999994,68.92997700000006],[-67.95472699999993,68.93580600000013],[-67.94665499999996,68.940811],[-67.93804899999998,68.94442700000002],[-67.92388900000003,68.94859300000013],[-67.89222699999999,68.95166],[-67.87638899999996,68.9494170000001],[-67.86944599999998,68.94413800000007],[-67.83944699999995,68.91192600000011],[-67.83139,68.87580900000012],[-67.83306899999991,68.86137400000001],[-67.83750900000001,68.85636899999997],[-67.84777799999995,68.85192899999998]],[[-85.34167500000001,68.98359699999997],[-85.35166900000002,68.98109400000004],[-85.37916599999994,68.98193400000008],[-85.40722700000003,68.98442099999994],[-85.43721,68.99192800000009],[-85.44694499999997,68.99636800000007],[-85.45140099999998,69.00109900000001],[-85.45306399999998,69.00582900000006],[-85.44387799999987,69.01026900000011],[-85.41888399999999,69.00943000000012],[-85.36999500000002,69.001938],[-85.35472099999993,68.99775700000009],[-85.34222399999993,68.9933170000001],[-85.337784,68.98858599999994],[-85.34167500000001,68.98359699999997]],[[-89.90834000000001,68.91775500000011],[-89.915009,68.91331500000013],[-89.95249899999988,68.92637600000006],[-89.97833299999996,68.93386799999996],[-90,68.93757599999998],[-90.03195199999999,68.94303900000011],[-90.07556199999999,68.94802899999996],[-90.07055700000001,68.98193400000008],[-89.94638099999992,69.01026900000011],[-89.93360899999999,69.01165800000007],[-89.920837,69.01026900000011],[-89.91416900000002,69.00694300000004],[-89.91027799999995,69.00305200000014],[-89.90666199999998,68.922485],[-89.90834000000001,68.91775500000011]],[[-100.17555199999987,68.79470800000001],[-100.22083999999995,68.76443500000005],[-100.25446299999999,68.76915000000008],[-100.26917300000002,68.77221700000001],[-100.28555299999994,68.77415500000012],[-100.29915599999998,68.77331500000008],[-100.30860899999999,68.76887500000004],[-100.31639100000001,68.76249700000011],[-100.35749799999996,68.71527100000003],[-100.36694299999994,68.71054100000003],[-100.40722699999998,68.70803800000004],[-100.423607,68.709991],[-100.61332700000003,68.75804099999999],[-100.62304699999999,68.76193200000006],[-100.62805199999997,68.766388],[-100.632767,68.77609300000006],[-100.62581599999999,68.91249099999993],[-100.59999099999999,69.00054899999998],[-100.56111099999993,69.02581800000002],[-100.54360999999994,69.03665200000006],[-100.52916699999997,69.03665200000006],[-100.497772,69.03471400000012],[-100.41610700000001,69.02638200000013],[-100.38110399999994,69.02082800000011],[-100.35082999999997,69.0147090000001],[-100.34111000000001,69.01081800000003],[-100.33361799999994,69.00665300000003],[-100.32861300000002,69.00221300000004],[-100.32362399999994,68.99609399999997],[-100.328888,68.98997500000013],[-100.33168,68.98442099999994],[-100.33168,68.97943100000009],[-100.326683,68.97470100000004],[-100.31276700000001,68.96582000000012],[-100.23889200000002,68.924149],[-100.22888199999994,68.9202580000001],[-100.21665999999988,68.91693099999998],[-100.20361300000002,68.91554300000007],[-100.16027799999995,68.91526800000003],[-100.14362299999993,68.91331500000013],[-100.131104,68.909988],[-100.12638899999996,68.90554800000012],[-100.17194399999994,68.79942300000005],[-100.17555199999987,68.79470800000001]],[[-85.11944599999993,69.0147090000001],[-85.13221699999986,69.01304599999997],[-85.16610700000001,69.03109699999999],[-85.17027300000001,69.03581200000002],[-85.15556299999997,69.05609099999998],[-85.14555399999989,69.0583190000001],[-85.095551,69.04803500000008],[-85.06834399999997,69.0413670000001],[-85.06138599999991,69.03665200000006],[-85.07583599999992,69.03109699999999],[-85.11944599999993,69.0147090000001]],[[-85.265289,69.07249500000012],[-85.34388699999994,69.06303400000013],[-85.35777300000001,69.06359899999995],[-85.37304699999993,69.06776399999995],[-85.39277600000003,69.07666000000012],[-85.39723200000003,69.08137499999992],[-85.39889499999998,69.08610499999998],[-85.39250199999998,69.09137000000004],[-85.38027999999991,69.09582500000005],[-85.30139200000002,69.10415599999999],[-85.28778099999988,69.10470600000002],[-85.258896,69.10026600000015],[-85.24888599999991,69.09582500000005],[-85.24194299999999,69.09137000000004],[-85.245544,69.08610499999998],[-85.24665800000002,69.08137499999992],[-85.25306699999999,69.07609599999995],[-85.265289,69.07249500000012]],[[-99.99943499999995,68.94358800000003],[-100.006958,68.93942300000003],[-100.021118,68.93969699999997],[-100.03778099999988,68.94136000000009],[-100.12000299999994,68.95082100000008],[-100.16166699999997,68.96138000000013],[-100.18138099999999,68.96887200000003],[-100.19860799999998,68.97692900000004],[-100.20612299999988,68.98109400000004],[-100.23693800000001,69.00860599999999],[-100.25666799999999,69.02665699999994],[-100.25890399999992,69.03166199999998],[-100.25862099999995,69.04193100000003],[-100.23693800000001,69.08137499999992],[-100.23194899999993,69.08720399999999],[-100.21333300000003,69.09721400000006],[-100.12970699999994,69.13026400000012],[-100.09555099999994,69.11747700000012],[-100.05304699999999,69.10247800000002],[-100.03333299999991,69.09471100000007],[-100.02834299999995,69.09027100000009],[-99.978882,69.01388500000013],[-99.97694399999995,69.0038760000001],[-99.99943499999995,68.94358800000003]],[[-90.12471,69.04942299999999],[-90.12721299999987,69.04498299999995],[-90.13806199999999,69.04525799999999],[-90.23194899999999,69.06553600000001],[-90.24749800000001,69.07026700000011],[-90.27917500000001,69.09832800000004],[-90.27639799999986,69.12580900000006],[-90.26333599999992,69.14193699999993],[-90.26251199999996,69.14276100000006],[-90.25389099999995,69.14276100000006],[-90.14723199999997,69.10359199999999],[-90.125,69.055542],[-90.12471,69.04942299999999]],[[-101.66416900000002,69.0836030000001],[-101.67749000000003,69.08276400000011],[-101.69027699999998,69.08610499999998],[-101.69554099999993,69.09054600000007],[-101.69833399999993,69.09526100000011],[-101.71806300000003,69.17858899999993],[-101.715843,69.18914799999999],[-101.71112099999993,69.1952510000001],[-101.70361300000002,69.20166],[-101.695267,69.20694000000003],[-101.68443300000001,69.21081500000003],[-101.65834000000001,69.21360800000002],[-101.60166899999996,69.21554600000013],[-101.55860899999999,69.2166600000001],[-101.53527799999995,69.20942700000012],[-101.5202789999999,69.1974790000001],[-101.497772,69.17025800000005],[-101.49500299999994,69.16554300000001],[-101.49500299999994,69.16026299999993],[-101.49999999999994,69.1544340000001],[-101.55555699999991,69.10525500000011],[-101.563606,69.09999099999999],[-101.65139799999997,69.08554100000003],[-101.66416900000002,69.0836030000001]],[[-90.51251200000002,69.20248400000014],[-90.57556199999999,69.19859300000007],[-90.61332700000003,69.207764],[-90.777222,69.272491],[-90.7786099999999,69.31721500000015],[-90.77583299999998,69.32998699999996],[-90.76251200000002,69.34553499999998],[-90.75723299999999,69.34942600000005],[-90.74082900000002,69.35748300000006],[-90.69221500000003,69.37164300000012],[-90.67332499999992,69.37387100000007],[-90.65527299999997,69.37469500000003],[-90.63861099999997,69.37387100000007],[-90.608047,69.36970500000001],[-90.59500100000002,69.36526499999997],[-90.58250399999997,69.359711],[-90.55943300000001,69.34721400000001],[-90.54861499999998,69.33998100000002],[-90.47193900000002,69.2810970000001],[-90.46083099999993,69.26748700000002],[-90.45556599999998,69.23471100000012],[-90.45445299999989,69.22637900000012],[-90.45750399999997,69.22276300000004],[-90.51251200000002,69.20248400000014]],[[-78.41221599999989,69.37970000000013],[-78.39639299999993,69.37776199999996],[-78.33860800000002,69.3808140000001],[-78.30583200000001,69.37776199999996],[-78.291382,69.3749850000001],[-78.27972399999999,69.37025500000004],[-78.27084400000001,69.36415099999999],[-78.21139499999992,69.29998799999998],[-78.21083099999998,69.29443400000014],[-78.214447,69.28831500000013],[-78.31834400000002,69.23831200000001],[-78.396118,69.21054100000009],[-78.47250400000001,69.19136000000003],[-78.55139200000002,69.08915700000006],[-78.55665599999992,69.0836030000001],[-78.57223499999992,69.07331799999997],[-78.60194399999995,69.06608600000004],[-78.62777699999998,69.05859399999991],[-78.70722999999998,69.0147090000001],[-78.71501199999994,69.00972000000013],[-78.71806299999997,69.00360100000012],[-78.71665999999999,68.99664300000012],[-78.712784,68.98498500000011],[-78.71611000000001,68.9791560000001],[-78.725281,68.96887200000003],[-78.73500099999995,68.96360800000008],[-78.83029199999993,68.91304000000008],[-78.84028599999994,68.90860000000009],[-78.86749299999997,68.90054300000008],[-78.93443300000001,68.88859600000012],[-78.978882,68.88247700000011],[-79.033615,68.87719700000002],[-79.09527599999996,68.87275700000004],[-79.18527199999994,68.85331700000006],[-79.19415299999997,68.849426],[-79.1972199999999,68.83915700000011],[-79.20472699999999,68.83387800000014],[-79.216949,68.82998700000007],[-79.23889200000002,68.82748400000008],[-79.287216,68.83137499999998],[-79.35333299999996,68.84414700000002],[-79.3661039999999,68.84776300000004],[-79.38694800000002,68.85609399999998],[-79.39250199999987,68.86053500000008],[-79.39639299999993,68.86499000000009],[-79.400284,68.87191800000005],[-79.40222199999994,68.92359899999997],[-79.37943999999993,68.93165600000009],[-79.353882,68.94386300000008],[-79.33056599999998,68.958328],[-79.30943299999996,68.97360200000008],[-79.30387899999994,68.97831700000012],[-79.29276999999996,68.99581899999998],[-79.28306599999996,69.01277200000004],[-79.23889200000002,69.06637600000005],[-79.22721899999999,69.07638500000007],[-79.216949,69.0811000000001],[-79.14611799999994,69.0935970000001],[-79.04943800000001,69.10220300000003],[-78.98582499999998,69.09999099999999],[-78.97444199999995,69.10026600000015],[-78.96028099999995,69.10247800000002],[-78.86416599999995,69.141098],[-78.85583499999996,69.14553799999999],[-78.7491609999999,69.26110799999998],[-78.72193899999996,69.31053200000002],[-78.7266689999999,69.318604],[-78.72471599999994,69.33110000000005],[-78.722778,69.33610500000009],[-78.71611000000001,69.34027100000003],[-78.60694899999999,69.37136800000013],[-78.57749899999999,69.37719700000014],[-78.56861899999996,69.37886000000003],[-78.48998999999998,69.39109800000011],[-78.47084000000001,69.39221200000009],[-78.45861799999994,69.38998400000014],[-78.41221599999989,69.37970000000013]],[[-135.28890999999993,69.30941800000005],[-135.29751599999997,69.30497700000012],[-135.33138999999989,69.322769],[-135.34805299999994,69.33055100000013],[-135.38613899999996,69.34498600000006],[-135.39779699999997,69.34803799999997],[-135.440002,69.35582000000011],[-135.486938,69.36219800000009],[-135.515015,69.36747700000006],[-135.52694699999995,69.37052900000015],[-135.559998,69.38026400000007],[-135.56527700000004,69.384995],[-135.56555199999997,69.39054899999996],[-135.559998,69.39665200000013],[-135.54998799999998,69.39999400000005],[-135.52444499999996,69.40359500000011],[-135.50723300000004,69.40304600000013],[-135.42028799999997,69.39749100000006],[-135.365814,69.39359999999999],[-135.33776899999992,69.38859600000006],[-135.32806400000004,69.384995],[-135.27224699999988,69.35832199999999],[-135.271393,69.34693899999996],[-135.277222,69.32832299999995],[-135.28332499999988,69.31526200000002],[-135.28890999999993,69.30941800000005]],[[-76.95083599999987,69.395264],[-76.92361499999998,69.39359999999999],[-76.902222,69.39471399999996],[-76.80416899999994,69.40026900000004],[-76.787781,69.40248099999997],[-76.77917499999995,69.4038700000001],[-76.76083399999987,69.40914900000007],[-76.75140399999998,69.41276600000003],[-76.74444599999998,69.41693100000003],[-76.73277299999995,69.42276000000004],[-76.72332799999998,69.42359900000002],[-76.71640000000002,69.42221100000012],[-76.70584099999996,69.41886899999997],[-76.65222199999994,69.38638300000008],[-76.64472999999992,69.38136300000002],[-76.64388999999994,69.37442000000004],[-76.64666699999998,69.33692900000005],[-76.64889499999992,69.33194000000009],[-76.67639199999996,69.3060910000001],[-76.70639,69.30358899999999],[-76.718887,69.30165100000005],[-76.73693799999995,69.29637100000002],[-76.79943800000001,69.272491],[-76.92639200000002,69.21748400000007],[-76.93360899999993,69.21388200000013],[-76.93998699999997,69.20915200000007],[-76.945831,69.20359800000011],[-76.94943199999994,69.1974790000001],[-76.95056199999993,69.1933140000001],[-76.95889299999999,69.14248699999996],[-77.11805700000002,69.11943100000013],[-77.137787,69.11665299999993],[-77.17166099999992,69.11720299999996],[-77.21362299999998,69.12580900000006],[-77.23860199999996,69.13275099999998],[-77.25778200000002,69.13998400000003],[-77.28582799999992,69.153595],[-77.30139200000002,69.164154],[-77.32028199999996,69.18136600000003],[-77.38194299999986,69.24748200000005],[-77.38417099999998,69.26361099999997],[-77.38333099999994,69.27053800000004],[-77.35972599999997,69.39276100000006],[-77.35638399999993,69.39665200000013],[-77.34834299999994,69.401657],[-77.28832999999992,69.417755],[-77.25917099999992,69.42469800000003],[-77.18916299999995,69.438309],[-77.15361000000001,69.44442700000008],[-77.12998999999996,69.44525100000004],[-77.11361699999998,69.44165000000004],[-77.07556199999999,69.42831400000006],[-77.04333500000001,69.41720600000008],[-77.006958,69.40637200000003],[-76.9783329999999,69.39999400000005],[-76.95083599999987,69.395264]],[[-90.329453,69.23580900000002],[-90.34722899999997,69.23471100000012],[-90.36138899999997,69.23831200000001],[-90.50639299999995,69.329163],[-90.51000999999991,69.33471700000001],[-90.51445000000001,69.363876],[-90.50111399999997,69.3724820000001],[-90.491669,69.37664799999999],[-90.30194099999994,69.43441800000011],[-90.20527599999991,69.4458160000001],[-90.20083599999998,69.44442700000008],[-90.19972200000001,69.4391480000001],[-90.195267,69.41693100000003],[-90.178604,69.40998800000006],[-90.14973399999997,69.37553400000002],[-90.14834599999995,69.37025500000004],[-90.15472399999999,69.35081500000007],[-90.15972899999997,69.34526100000005],[-90.27166699999992,69.25555400000002],[-90.28860500000002,69.24941999999999],[-90.329453,69.23580900000002]],[[-135.592224,69.48220800000007],[-135.574432,69.44664000000006],[-135.61999499999996,69.4685970000001],[-135.6294249999999,69.47221400000006],[-135.665283,69.48136899999992],[-135.693604,69.486649],[-135.74081399999994,69.49304199999995],[-135.778351,69.49609400000008],[-135.81054700000004,69.49775699999998],[-135.81555200000003,69.50248700000003],[-135.8125,69.50804100000005],[-135.79528799999997,69.51666300000005],[-135.785553,69.51998900000007],[-135.77389500000004,69.52276599999999],[-135.76113899999996,69.52442900000005],[-135.74526999999995,69.5247040000001],[-135.666107,69.50582899999995],[-135.599426,69.48609899999997],[-135.592224,69.48220800000007]],[[-101.05304699999999,69.50443999999999],[-101.00611900000001,69.4869230000001],[-101.00862099999995,69.45027200000004],[-101.12526700000001,69.40138200000013],[-101.21861299999989,69.37136800000013],[-101.23029299999996,69.36859100000004],[-101.24305700000002,69.371918],[-101.26888999999994,69.37886000000003],[-101.27916700000003,69.382477],[-101.271118,69.38581800000003],[-101.256958,69.38665800000007],[-101.24526999999995,69.38943499999999],[-101.2369379999999,69.39471399999996],[-101.23166699999996,69.40081800000002],[-101.18888899999996,69.46971100000007],[-101.186394,69.47526599999998],[-101.22749299999992,69.49552900000003],[-101.23805199999998,69.499146],[-101.2538909999999,69.50027499999999],[-101.266953,69.49832200000003],[-101.31749699999995,69.51110799999992],[-101.38445300000001,69.53276100000005],[-101.38722199999995,69.53776600000009],[-101.358337,69.5669400000001],[-101.34973099999996,69.572495],[-101.34056099999992,69.57470700000005],[-101.27555799999993,69.58082600000006],[-101.26167299999992,69.58166500000004],[-101.07305899999994,69.53498800000011],[-101.06276699999995,69.53137200000009],[-101.05999800000001,69.52638200000001],[-101.05304699999999,69.50443999999999]],[[-96.66305499999993,69.56971700000003],[-96.56332399999997,69.56414799999999],[-96.46112099999999,69.56414799999999],[-96.4016719999999,69.56275900000003],[-96.37361099999998,69.56080600000007],[-96.35888699999987,69.55720500000001],[-96.35194399999995,69.55304000000001],[-96.3452759999999,69.54859900000008],[-96.343887,69.54359400000004],[-96.335556,69.534424],[-96.32861300000002,69.52998399999996],[-96.31639100000001,69.52638200000001],[-96.29167199999989,69.53109700000005],[-96.21806300000003,69.54637100000014],[-96.20722999999998,69.55053700000002],[-96.19833399999987,69.55664100000007],[-96.19444299999998,69.56192000000004],[-96.18443299999996,69.56721500000009],[-96.16972399999992,69.5669400000001],[-96.152222,69.56359900000007],[-96.13999899999993,69.5599820000001],[-96.13333099999994,69.55554200000006],[-96.13444500000003,69.55026200000003],[-96.13639799999999,69.54609700000003],[-96.10417199999995,69.49832200000003],[-96.10110499999996,69.49304199999995],[-96.097778,69.48332200000004],[-96.096115,69.46804800000001],[-96.09861799999999,69.45776399999994],[-96.14306599999992,69.35137900000001],[-96.14666699999998,69.34582499999999],[-96.16332999999997,69.34803799999997],[-96.23388699999998,69.359711],[-96.24861099999993,69.36303700000002],[-96.27000399999997,69.37081899999998],[-96.28860499999996,69.37886000000003],[-96.30499299999991,69.38749700000005],[-96.32528699999995,69.40026900000004],[-96.33361799999994,69.40971400000012],[-96.348343,69.42303500000008],[-96.38221699999991,69.44470200000012],[-96.40110800000002,69.45304899999991],[-96.43055700000002,69.45971700000007],[-96.46194499999996,69.46249399999999],[-96.50723299999999,69.4644320000001],[-96.524719,69.46748400000001],[-96.54888900000003,69.47499099999999],[-96.63082899999995,69.5122070000001],[-96.65417500000001,69.5249940000001],[-96.73666399999996,69.57666],[-96.73554999999999,69.58194000000003],[-96.72166399999992,69.58248900000001],[-96.69166599999988,69.58194000000003],[-96.676941,69.57832300000013],[-96.66305499999993,69.56971700000003]],[[-67.31054699999993,69.54914900000011],[-67.32417299999997,69.53387500000002],[-67.33168,69.53137200000009],[-67.35110500000002,69.53082300000011],[-67.38861099999997,69.53305100000006],[-67.47305299999994,69.53387500000002],[-67.49276699999996,69.53305100000006],[-67.53083799999996,69.52915999999999],[-67.5452729999999,69.52581800000007],[-67.55248999999998,69.52304100000015],[-67.5494379999999,69.51971400000002],[-67.50723299999999,69.51499899999999],[-67.49999999999994,69.51283300000006],[-67.49888599999997,69.51249700000011],[-67.48999000000003,69.50860600000004],[-67.48167399999994,69.50000000000011],[-67.49249299999985,69.49552900000003],[-67.50778200000002,69.49498000000011],[-67.573624,69.50665300000009],[-67.58555599999994,69.50749200000007],[-67.59889199999998,69.5063780000001],[-67.62666299999995,69.50054900000009],[-67.64222699999988,69.50027499999999],[-67.73194899999993,69.51361100000008],[-67.74444599999993,69.51582299999995],[-67.74972500000001,69.52110300000004],[-67.73944099999994,69.54081700000012],[-67.73083499999996,69.54443400000008],[-67.723053,69.54525800000005],[-67.70722999999998,69.54443400000008],[-67.68666100000002,69.54109199999999],[-67.67471299999988,69.54026800000003],[-67.66332999999997,69.54193099999992],[-67.57806399999998,69.559708],[-67.55027799999993,69.56553600000012],[-67.541382,69.56915300000003],[-67.531387,69.57638499999996],[-67.527222,69.58194000000003],[-67.48443599999996,69.59027100000014],[-67.42500299999995,69.58888200000013],[-67.394455,69.58499100000006],[-67.36721799999992,69.57832300000013],[-67.321396,69.56053199999997],[-67.314438,69.55664100000007],[-67.30943300000001,69.55276500000002],[-67.31054699999993,69.54914900000011]],[[-96.76055899999994,69.54553199999998],[-96.77000399999991,69.54359400000004],[-96.78666699999991,69.54553199999998],[-96.86888099999987,69.5558170000001],[-96.883896,69.55914300000012],[-96.88806199999999,69.563873],[-96.902222,69.5977630000001],[-96.900284,69.60220300000009],[-96.870544,69.60137900000012],[-96.85139500000002,69.599426],[-96.84083599999997,69.59748800000006],[-96.81639100000001,69.59027100000014],[-96.80943300000001,69.58581500000003],[-96.76640299999997,69.55497700000006],[-96.76194799999996,69.55053700000002],[-96.76055899999994,69.54553199999998]],[[-91.11000100000001,69.54942300000005],[-91.11915599999998,69.54832499999998],[-91.14028899999994,69.56080600000007],[-91.14250199999992,69.56498699999997],[-91.13639799999999,69.57554600000003],[-91.12138400000003,69.59304800000007],[-91.10888699999992,69.60220300000009],[-91.03721599999994,69.61499000000009],[-90.96916199999993,69.61831700000005],[-90.95973200000003,69.61943100000002],[-90.93749999999994,69.61637900000011],[-90.92304999999993,69.61137400000007],[-90.92027299999995,69.6080320000001],[-90.91915899999998,69.60609399999998],[-90.93083200000001,69.59915200000006],[-91.11000100000001,69.54942300000005]],[[-133.93222000000003,69.56025699999992],[-133.948059,69.56025699999992],[-133.96304299999997,69.56137100000012],[-133.98611499999998,69.56553600000012],[-134.01196299999992,69.57138100000003],[-134.01666299999994,69.57609600000006],[-134.01419099999998,69.58248900000001],[-134.010284,69.58554100000009],[-133.94528199999996,69.61331200000001],[-133.93362399999995,69.6160890000001],[-133.89446999999996,69.62109399999997],[-133.87997399999995,69.62191800000011],[-133.86581399999994,69.61914100000001],[-133.84472700000003,69.60081500000001],[-133.84695399999998,69.58888200000013],[-133.868042,69.56721500000009],[-133.87719699999997,69.56526199999996],[-133.93222000000003,69.56025699999992]],[[-95.48889200000002,69.56553600000012],[-95.45249899999993,69.55026200000003],[-95.37554899999998,69.51776100000012],[-95.366104,69.51361100000008],[-95.35972600000002,69.50915500000002],[-95.362213,69.49887099999995],[-95.40249599999999,69.383331],[-95.51583900000003,69.33082600000012],[-95.527222,69.32748400000003],[-95.53971899999999,69.32527199999993],[-95.60638399999993,69.31915300000009],[-95.62027,69.318604],[-95.63417099999992,69.31832900000012],[-95.69248999999996,69.31915300000009],[-95.706955,69.31944299999992],[-95.722778,69.32083100000006],[-95.73693800000001,69.32443200000006],[-95.741104,69.329163],[-95.74166899999994,69.33471700000001],[-95.73167399999994,69.37303199999997],[-95.72778299999987,69.37858599999993],[-95.716949,69.38275099999993],[-95.69387799999998,69.38943499999999],[-95.66915899999998,69.39415000000002],[-95.65777600000001,69.39721700000013],[-95.648346,69.40332000000006],[-95.66639700000002,69.49775699999998],[-95.66915899999998,69.50749200000007],[-95.69444299999998,69.54026800000003],[-95.70805399999995,69.54887400000013],[-95.72000100000002,69.55276500000002],[-95.7366639999999,69.55497700000006],[-95.81582600000002,69.56275900000003],[-95.82749899999993,69.559708],[-95.83168,69.5541530000001],[-95.82278400000001,69.51443500000005],[-95.81750499999993,69.50499000000002],[-95.80943299999996,69.49552900000003],[-95.79722599999997,69.48165899999998],[-95.862213,69.34803799999997],[-95.87222300000002,69.34275800000006],[-95.89944500000001,69.34082000000012],[-95.96167000000003,69.34637500000002],[-95.978882,69.34942600000005],[-95.99082900000002,69.35331700000012],[-96.01112399999988,69.47804300000007],[-96.00973499999998,69.48304700000006],[-95.91999800000002,69.595261],[-95.90916400000003,69.599426],[-95.78944399999995,69.63415500000008],[-95.77389499999992,69.6327510000001],[-95.62554899999992,69.6160890000001],[-95.61221299999994,69.61442599999998],[-95.48889200000002,69.56553600000012]],[[-138.86721799999992,69.58831800000002],[-138.87332200000003,69.58305400000006],[-138.88305699999995,69.5794370000001],[-138.91000399999996,69.57609600000006],[-138.945831,69.57887299999993],[-138.97720300000003,69.58305400000006],[-138.99609399999997,69.58415200000013],[-139.02307099999996,69.58082600000006],[-139.03418,69.57804899999996],[-139.05307,69.57054099999999],[-139.12109399999997,69.52915999999999],[-139.137787,69.53082300000011],[-139.33248899999995,69.56608599999993],[-139.32998699999996,69.57165500000013],[-139.32223499999992,69.57609600000006],[-139.26779199999993,69.60582000000005],[-139.24221799999992,69.61831700000005],[-139.232758,69.62191800000011],[-139.19973800000002,69.630539],[-139.144165,69.64498900000012],[-139.133057,69.64776600000005],[-139.12027,69.64999399999999],[-139.10333299999996,69.64804100000003],[-139.02029399999998,69.63333100000011],[-138.956116,69.61970500000012],[-138.92111199999994,69.61053500000008],[-138.88055399999996,69.59693900000013],[-138.872772,69.59275800000006],[-138.86721799999992,69.58831800000002]],[[-135.51724199999995,69.56915300000003],[-135.54305999999997,69.56553600000012],[-135.55721999999997,69.56805400000007],[-135.57138099999997,69.57693499999999],[-135.581116,69.58055100000007],[-135.5883179999999,69.58471700000013],[-135.591095,69.58998099999997],[-135.5894469999999,69.59609999999998],[-135.58612099999993,69.601654],[-135.578888,69.60664400000002],[-135.55471799999992,69.62025499999999],[-135.51196299999998,69.64166300000011],[-135.50030500000003,69.64443999999997],[-135.43972799999995,69.65248100000008],[-135.42388900000003,69.65248100000008],[-135.4097289999999,69.64999399999999],[-135.39779699999997,69.64694200000008],[-135.40918,69.63499500000012],[-135.4655459999999,69.58554100000009],[-135.474152,69.58137500000004],[-135.505585,69.57165500000013],[-135.51724199999995,69.56915300000003]],[[-67.92027300000001,69.521927],[-67.93527199999994,69.5188750000001],[-68.002228,69.52665700000006],[-68.04943799999995,69.53387500000002],[-68.23889200000002,69.57026700000006],[-68.24888599999991,69.59664900000013],[-68.07833900000003,69.66526800000008],[-67.9708399999999,69.70193500000005],[-67.95973199999997,69.70498700000002],[-67.94638099999997,69.7063750000001],[-67.89555399999995,69.70860300000004],[-67.889725,69.70832800000005],[-67.86972000000003,69.70082100000008],[-67.82112099999995,69.67637600000006],[-67.83168,69.60192899999998],[-67.910278,69.52665700000006],[-67.92027300000001,69.521927]],[[-134.26058999999987,68.73353599999996],[-134.2324829999999,68.7061000000001],[-134.22778299999993,68.70138500000007],[-134.227264,68.69642600000009],[-134.23580900000002,68.69497700000011],[-134.267792,68.6958160000001],[-134.35693400000002,68.70304900000008],[-134.38861099999997,68.70721400000008],[-134.436127,68.71360800000014],[-134.45748899999995,68.71914700000013],[-134.46194499999996,68.72387700000013],[-134.49554399999994,68.75221300000004],[-134.53640699999994,68.78692600000005],[-134.6694639999999,68.89444000000015],[-134.741669,68.93553199999997],[-134.75500499999987,68.94442700000002],[-134.7669679999999,68.95332300000013],[-134.78306599999996,68.96535500000005],[-134.82583599999998,68.97886699999998],[-134.852783,68.97637900000001],[-134.892242,68.971924],[-134.904724,68.969986],[-134.914734,68.96665999999999],[-134.92028799999997,68.96081500000008],[-134.91973899999994,68.9494170000001],[-134.91723599999995,68.94413800000007],[-134.91641199999998,68.9269260000001],[-134.92028799999997,68.91470300000003],[-134.925842,68.90860000000009],[-134.93307499999997,68.903595],[-134.941376,68.89942900000011],[-134.961121,68.89248700000002],[-134.97500599999995,68.89166300000005],[-134.99999999999994,68.89208200000007],[-135.00750699999998,68.89221200000003],[-135.126099,68.89942900000011],[-135.14196800000002,68.90138200000007],[-135.167236,68.90721100000007],[-135.17083699999995,68.91110200000014],[-135.17807,68.92082200000004],[-135.18084699999997,68.926086],[-135.20165999999995,68.9327550000001],[-135.2333069999999,68.934708],[-135.262787,68.93359400000003],[-135.36111500000004,68.92665100000005],[-135.39196799999996,68.92665100000005],[-135.42138699999987,68.92886400000003],[-135.444458,68.93498199999993],[-135.45388799999995,68.938583],[-135.46081499999997,68.9427490000001],[-135.76916499999993,68.89637800000008],[-135.808044,68.89526400000011],[-135.843323,68.89721700000007],[-135.882477,68.90525800000012],[-135.90585299999992,68.91137699999996],[-135.94805899999994,68.92469800000009],[-135.99527,68.94247400000006],[-136.002502,68.94664],[-136.00527999999997,68.95193500000005],[-135.98916599999995,69.0291600000001],[-135.98525999999998,69.03581200000002],[-135.97833299999996,69.04081700000006],[-135.968597,69.04443400000002],[-135.95443699999998,69.0455320000001],[-135.8886109999999,69.026093],[-135.85012800000004,69.00740100000013],[-135.83389299999993,68.99832200000014],[-135.8288879999999,68.99359100000004],[-135.80248999999992,68.98942600000004],[-135.77002,68.98915099999999],[-135.64889499999998,68.99192800000009],[-135.63473499999998,68.99304200000006],[-135.57861300000002,69.00610400000011],[-135.52557399999995,69.02110299999998],[-135.517792,69.02388000000008],[-135.529449,69.02693199999999],[-135.720825,69.04609700000015],[-135.91583300000002,69.08831800000013],[-135.92748999999998,69.09137000000004],[-135.93472299999996,69.09553500000004],[-135.95138499999996,69.14276100000006],[-135.96582,69.19775400000009],[-135.967224,69.21470600000009],[-135.95944199999997,69.22831700000006],[-135.94695999999993,69.23942599999998],[-135.92611699999998,69.25471500000003],[-135.915009,69.25749200000013],[-135.898621,69.25555400000002],[-135.891388,69.25138900000002],[-135.82138099999986,69.21527100000014],[-135.75140399999998,69.17942800000009],[-135.741943,69.17581200000006],[-135.666107,69.14694199999997],[-135.65667699999995,69.14360000000005],[-135.56750499999993,69.11775200000011],[-135.5527949999999,69.11665299999993],[-135.486938,69.11331200000012],[-135.49581899999993,69.124146],[-135.60720799999996,69.14526400000005],[-135.6305539999999,69.15138200000001],[-135.64001499999995,69.15498400000013],[-135.81082199999997,69.242752],[-135.83999600000004,69.25943000000007],[-135.85220300000003,69.26805100000001],[-135.85498,69.27331500000014],[-135.8558349999999,69.28471400000006],[-135.854156,69.290817],[-135.84860199999997,69.29693600000002],[-135.8416749999999,69.3019260000001],[-135.83331299999998,69.30636600000008],[-135.803894,69.31666600000005],[-135.792511,69.31944299999992],[-135.57192999999995,69.33859300000006],[-135.5561219999999,69.33888200000001],[-135.48580900000002,69.33526599999999],[-135.44860799999998,69.33221400000002],[-135.41332999999997,69.32304399999998],[-135.39196799999996,69.30998199999999],[-135.38723800000002,69.30525200000011],[-135.379974,69.30108600000005],[-135.37027,69.297485],[-135.323334,69.28526299999999],[-135.25778200000002,69.27137800000008],[-135.24386599999997,69.2686000000001],[-135.22970599999996,69.26609800000006],[-135.18554699999993,69.25888099999992],[-135.17056300000002,69.25776699999994],[-135.16223099999996,69.26193199999994],[-135.15805099999994,69.2686000000001],[-135.15835599999997,69.27442900000011],[-135.16500899999994,69.27916000000005],[-135.174438,69.28305100000011],[-135.23971599999987,69.3316650000001],[-135.28695699999992,69.41360500000002],[-135.28723100000002,69.41914400000002],[-135.285278,69.42553700000013],[-135.278076,69.430542],[-135.26834099999996,69.43414300000006],[-135.16082800000004,69.47360200000014],[-135.15084799999994,69.4769290000001],[-135.137787,69.47859200000005],[-134.996643,69.48414600000001],[-134.91528299999993,69.48525999999998],[-134.69473300000004,69.48165899999998],[-134.67749000000003,69.48082],[-134.64251699999988,69.47720300000003],[-134.62832599999996,69.47442600000011],[-134.60861199999988,69.4685970000001],[-134.570831,69.45387300000004],[-134.55917399999987,69.45082100000013],[-134.53112799999997,69.44552600000009],[-134.49609399999997,69.44192500000003],[-134.48165900000004,69.44274899999999],[-134.46859699999993,69.44442700000008],[-134.43832399999997,69.45471200000003],[-134.42083699999995,69.46304299999991],[-134.413635,69.468323],[-134.407776,69.474152],[-134.40557899999993,69.48027000000013],[-134.40835600000003,69.49136400000003],[-134.41778599999992,69.50054900000009],[-134.43667600000003,69.50804100000005],[-134.448334,69.51110799999992],[-134.46887200000003,69.54275500000006],[-134.40167199999996,69.63832100000013],[-134.40249600000004,69.649719],[-134.406677,69.65443400000004],[-134.44277999999997,69.68081699999999],[-134.48580899999996,69.70610000000005],[-134.49054,69.71081500000008],[-134.49304199999995,69.71581999999995],[-134.49108899999993,69.72221400000001],[-134.476379,69.72303799999997],[-134.30972299999996,69.71581999999995],[-134.20388799999995,69.66886899999997],[-134.17748999999998,69.64027400000009],[-134.19638099999992,69.62109399999997],[-134.20388799999995,69.6160890000001],[-134.24026500000002,69.58581500000003],[-134.24472000000003,69.579163],[-134.24472000000003,69.57331800000003],[-134.24221799999998,69.56805400000007],[-134.113312,69.53887900000001],[-134.09860199999997,69.53997800000002],[-134.081116,69.54832499999998],[-134.06195099999997,69.5558170000001],[-134.037506,69.56025699999992],[-134.02002,69.559418],[-134.00836200000003,69.55609100000004],[-134.00140399999998,69.55192600000004],[-133.977783,69.528595],[-133.961121,69.50915500000002],[-133.94723499999992,69.5063780000001],[-133.91833499999996,69.50833100000006],[-133.87914999999998,69.51332100000008],[-133.86749299999997,69.51582299999995],[-133.86026000000004,69.52082800000005],[-133.82250999999997,69.55525200000005],[-133.823151,69.5600740000001],[-133.81973300000004,69.56498699999997],[-133.801941,69.57360800000009],[-133.79168699999997,69.57693499999999],[-133.77835099999993,69.57638499999996],[-133.75057999999996,69.54748500000011],[-133.74832199999992,69.54220599999996],[-133.79861500000004,69.4810940000001],[-133.81805399999996,69.46415700000011],[-133.85055499999999,69.4458160000001],[-133.87692300000003,69.43304400000011],[-133.92083699999995,69.41220100000004],[-133.941376,69.405258],[-133.96444699999995,69.40026900000004],[-134.08554100000003,69.34054600000002],[-134.21112099999993,69.27609299999995],[-134.21832299999988,69.2711030000001],[-134.275574,69.22608900000012],[-134.27999899999986,69.21943700000003],[-134.28222699999998,69.21331800000002],[-134.281952,69.20748900000001],[-134.27722199999994,69.20277399999998],[-134.27471899999995,69.19775400000009],[-134.27444500000001,69.18609600000008],[-134.28030399999994,69.18026700000007],[-134.287781,69.17526200000003],[-134.38363599999997,69.11831699999999],[-134.39779699999997,69.11747700000012],[-134.44888300000002,69.11970500000007],[-134.47720300000003,69.11804200000012],[-134.53112799999997,69.11276200000009],[-134.5680539999999,69.10664400000013],[-134.585266,69.09803800000003],[-134.67361500000004,69.01776100000001],[-134.67584199999993,69.01138300000008],[-134.675568,69.00582900000006],[-134.669739,68.9727630000001],[-134.67166099999997,68.966385],[-134.666656,68.95610000000005],[-134.652802,68.94775400000015],[-134.60665900000004,68.93525699999998],[-134.58831799999996,68.92804000000007],[-134.51419099999987,68.887497],[-134.50723300000004,68.88304100000005],[-134.48858599999994,68.87025499999999],[-134.47470099999998,68.85609399999998],[-134.4641719999999,68.84248400000007],[-134.45693999999997,68.82693499999999],[-134.4475099999999,68.81192000000004],[-134.44027700000004,68.80192599999998],[-134.43112199999996,68.79275500000006],[-134.417236,68.78442399999994],[-134.39889499999998,68.77720599999998],[-134.37609899999995,68.770828],[-134.3511049999999,68.76499899999999],[-134.29666099999992,68.7544400000001],[-134.28750599999995,68.75082400000008],[-134.280579,68.746643],[-134.26058999999987,68.73353599999996]],[[-102.14527900000002,69.64860499999998],[-102.160278,69.64833100000004],[-102.17832900000002,69.651093],[-102.21028099999995,69.66220099999998],[-102.22609699999992,69.6702580000001],[-102.23166700000002,69.67469800000015],[-102.24305699999996,69.69413800000012],[-102.243607,69.70443699999998],[-102.241379,69.71026599999999],[-102.23416099999997,69.71666000000005],[-102.22556299999991,69.721924],[-102.215843,69.72665400000005],[-102.15778399999999,69.73609900000008],[-102.13474300000001,69.7247010000001],[-102.12943999999993,69.72026100000005],[-102.12332199999997,69.71276899999998],[-102.12026999999989,69.70803800000004],[-102.11721799999998,69.69775399999997],[-102.11554699999999,69.66665599999999],[-102.11805700000002,69.66081200000013],[-102.12277199999994,69.65498400000007],[-102.13221699999991,69.65054299999997],[-102.14527900000002,69.64860499999998]],[[-77.94665500000002,69.64665200000007],[-77.94499200000001,69.63970900000004],[-77.94610599999999,69.63333100000011],[-77.96583599999997,69.62498500000004],[-78.07028200000002,69.59275800000006],[-78.16999799999996,69.57054099999999],[-78.31193499999995,69.54304500000012],[-78.39778099999995,69.52082800000005],[-78.50500499999987,69.48887600000006],[-78.57640100000003,69.50166300000006],[-78.58805799999993,69.506104],[-78.61138899999992,69.50943000000001],[-78.62609899999995,69.50999500000006],[-78.64611799999989,69.50999500000006],[-78.66444399999989,69.50749200000007],[-78.68527199999994,69.49832200000003],[-78.69804399999998,69.48915100000005],[-78.71888699999994,69.47998000000013],[-78.75695799999994,69.46748400000001],[-78.80194099999994,69.455826],[-78.81750499999993,69.45277400000009],[-78.83860800000002,69.45138500000007],[-78.85305800000003,69.45416300000011],[-78.86193800000001,69.45748900000012],[-78.86833199999995,69.46054100000003],[-78.87388599999986,69.46470600000004],[-78.88027999999997,69.4769290000001],[-78.87860099999989,69.47998000000013],[-78.87416099999996,69.4869230000001],[-78.865005,69.49498000000011],[-78.841385,69.50804100000005],[-78.82611099999997,69.51165799999995],[-78.80972299999996,69.51416000000006],[-78.78332499999999,69.52110300000004],[-78.76417500000002,69.52720599999998],[-78.71777299999997,69.54470800000001],[-78.69526699999994,69.55693100000008],[-78.67443800000001,69.56832900000006],[-78.65278599999994,69.58194000000003],[-78.62805199999997,69.60859700000015],[-78.61555499999992,69.61747700000001],[-78.58639499999992,69.63192700000013],[-78.57583599999998,69.63638300000002],[-78.5225069999999,69.64833100000004],[-78.4997249999999,69.65054299999997],[-78.4827729999999,69.64942899999994],[-78.400284,69.643326],[-78.26083399999993,69.659988],[-78.24527,69.66360500000013],[-78.229446,69.67164600000001],[-78.22805799999998,69.67747500000007],[-78.23693800000001,69.68858300000005],[-78.24499500000002,69.69331399999999],[-78.25695799999994,69.70582599999994],[-78.26362599999993,69.71360800000008],[-78.26916499999993,69.72804300000001],[-78.26861599999995,69.73220800000001],[-78.26583899999997,69.73387100000014],[-78.18055700000002,69.75221300000004],[-78.16416899999996,69.75248699999997],[-78.15417499999995,69.75054900000003],[-78.141953,69.74247700000006],[-78.08000199999998,69.72943099999992],[-78.01834100000002,69.70832800000005],[-77.99276700000001,69.6994170000001],[-77.98277300000001,69.69470200000006],[-77.97389199999998,69.68858300000005],[-77.96611000000001,69.68165599999998],[-77.95556599999998,69.66832],[-77.94665500000002,69.64665200000007]],[[-82.50778199999996,69.70498700000002],[-82.54277000000002,69.70416300000005],[-82.678879,69.72637900000001],[-82.72000100000002,69.73332199999999],[-82.865005,69.770828],[-82.87777699999992,69.77499400000005],[-82.87943999999993,69.77859500000011],[-82.85638399999999,69.80026199999998],[-82.84666400000003,69.80304000000012],[-82.83917199999996,69.80386400000009],[-82.81166100000002,69.80609099999998],[-82.80305499999992,69.80581700000005],[-82.796112,69.805252],[-82.77610800000002,69.80415300000004],[-82.67777999999993,69.79470799999996],[-82.62999000000002,69.789154],[-82.56388900000002,69.77859500000011],[-82.46028100000001,69.76165800000012],[-82.45306399999998,69.72053499999998],[-82.45500199999992,69.71443200000004],[-82.46722399999999,69.70999099999995],[-82.50778199999996,69.70498700000002]],[[-79.42304999999999,69.78498800000006],[-79.33168,69.71331800000007],[-79.32833899999997,69.70721400000008],[-79.32945299999994,69.70138500000002],[-79.33389299999999,69.69747899999999],[-79.35472099999998,69.68803400000007],[-79.48222399999992,69.6461030000001],[-79.54499799999996,69.62664799999993],[-79.57167099999998,69.61943100000002],[-79.600281,69.61276199999998],[-79.63166799999993,69.60887100000008],[-79.95750399999997,69.61998],[-79.96333300000003,69.62637300000011],[-79.97416699999985,69.63165299999997],[-79.99499500000002,69.638596],[-80.02194199999991,69.64359999999994],[-80.03805499999999,69.64526399999994],[-80.0594329999999,69.64387499999998],[-80.06555200000003,69.64166300000011],[-80.081955,69.630539],[-80.08277900000002,69.62692300000015],[-80.07888799999995,69.62220800000011],[-80.03277600000001,69.58720400000004],[-79.99137899999994,69.56887800000004],[-79.93777499999993,69.53193700000008],[-79.93554699999999,69.52720599999998],[-79.93638599999997,69.52360499999992],[-79.94027699999992,69.5188750000001],[-79.97444199999995,69.5022130000001],[-79.99388099999993,69.49443100000013],[-80.01194800000002,69.49165299999999],[-80.02111799999994,69.49275200000011],[-80.04611199999994,69.49775699999998],[-80.20056199999999,69.53082300000011],[-80.214722,69.58665500000006],[-80.35360699999995,69.61470000000008],[-80.46194499999996,69.65637200000015],[-80.49276700000001,69.66499300000004],[-80.577789,69.66748000000013],[-80.74360699999994,69.66609200000005],[-80.761124,69.66693099999998],[-80.79333499999996,69.6702580000001],[-80.80444299999988,69.67553700000008],[-80.80943300000001,69.68304400000005],[-80.80943300000001,69.68942300000009],[-80.80139200000002,69.70109600000012],[-80.73083500000001,69.74636800000013],[-80.72500600000001,69.74914600000011],[-80.7202759999999,69.75054900000003],[-80.64973399999997,69.74859600000008],[-80.52000399999997,69.72082500000005],[-80.49861099999998,69.75971999999996],[-80.50111400000003,69.76249700000005],[-80.50279199999994,69.76638800000012],[-80.50445599999995,69.77499400000005],[-80.50306699999999,69.77998400000013],[-80.49999999999994,69.78332499999999],[-80.49055499999997,69.78858900000012],[-80.46665999999999,69.79193100000009],[-80.38890100000003,69.79998800000004],[-80.37138400000003,69.79914900000006],[-80.34028599999999,69.79470799999996],[-80.33860799999991,69.79054299999996],[-80.34306300000003,69.78414900000013],[-80.34445199999999,69.77693199999999],[-80.32972699999999,69.77415500000012],[-80.31471299999998,69.77804599999996],[-80.289444,69.78665200000006],[-80.26417500000002,69.79525799999999],[-80.24665799999997,69.79859900000002],[-80.23277300000001,69.79942299999999],[-80.20666499999993,69.79803500000008],[-80.19166599999988,69.79525799999999],[-80.18276999999995,69.79275500000006],[-80.12916599999994,69.76554900000002],[-80.07305899999994,69.74971000000005],[-79.972778,69.72331200000008],[-79.86277799999993,69.74108899999999],[-79.76806599999998,69.75277699999998],[-79.75639299999989,69.77886999999993],[-79.75250199999999,69.78359999999998],[-79.74472000000003,69.78858900000012],[-79.68721,69.81469700000008],[-79.67832900000002,69.81442300000015],[-79.512787,69.80693100000002],[-79.47694399999995,69.8035890000001],[-79.453888,69.79887400000007],[-79.4424899999999,69.794983],[-79.43167099999994,69.78970300000009],[-79.42304999999999,69.78498800000006]],[[-83.67443799999995,69.71998600000006],[-83.68859899999995,69.71943699999991],[-83.71777299999997,69.72331200000008],[-83.776947,69.73275800000005],[-83.80694599999998,69.73942600000004],[-83.89889499999998,69.76443499999999],[-83.908615,69.76915000000002],[-83.91722099999998,69.77859500000011],[-83.91305499999999,69.79332000000005],[-83.90083300000003,69.80831899999993],[-83.88694800000002,69.81860400000005],[-83.87388599999991,69.8230440000001],[-83.86027499999994,69.824432],[-83.83250399999997,69.82527200000004],[-83.57749899999999,69.7977600000001],[-83.53332499999993,69.79136699999992],[-83.52917499999995,69.78665200000006],[-83.54222099999998,69.78332499999999],[-83.57667500000002,69.78082300000005],[-83.601944,69.77998400000013],[-83.695831,69.76388499999996],[-83.708618,69.75942999999995],[-83.712784,69.7544400000001],[-83.70584099999996,69.75000000000006],[-83.693329,69.74552900000015],[-83.66250600000001,69.73692300000005],[-83.65583800000002,69.73220800000001],[-83.65417500000001,69.72720300000015],[-83.66111799999999,69.72221400000001],[-83.67443799999995,69.71998600000006]],[[-82.42944299999999,69.78221099999996],[-82.44415300000003,69.77832000000012],[-82.470551,69.78137200000003],[-82.51333599999987,69.78831500000001],[-82.52610799999997,69.79054299999996],[-82.55139200000002,69.79664600000012],[-82.564438,69.80081200000001],[-82.68859900000001,69.85081500000013],[-82.67443800000001,69.87498499999998],[-82.67304999999999,69.87580900000012],[-82.660553,69.87608300000005],[-82.63639799999999,69.87109400000008],[-82.55583199999995,69.86080900000013],[-82.51722699999993,69.85415599999999],[-82.44610599999999,69.82222000000013],[-82.43666100000002,69.81749000000008],[-82.42887899999994,69.81219500000003],[-82.42666600000001,69.79998800000004],[-82.42582700000003,69.79304500000006],[-82.42610199999996,69.786926],[-82.42944299999999,69.78221099999996]],[[-91.52000399999991,69.73136900000009],[-91.535278,69.72692900000004],[-91.54943800000001,69.72720300000015],[-91.56027199999988,69.72831699999995],[-91.725281,69.78414900000013],[-91.73554999999999,69.789154],[-91.73332199999987,69.79193100000009],[-91.47582999999997,69.87553400000007],[-91.449432,69.87914999999998],[-91.43388399999998,69.88053899999994],[-91.41944899999999,69.87997400000012],[-91.40916400000003,69.87498499999998],[-91.45666499999999,69.77499400000005],[-91.46333299999998,69.76361100000003],[-91.470551,69.75555400000007],[-91.52000399999991,69.73136900000009]],[[-91.81916799999993,69.82165500000008],[-91.83389299999999,69.82110599999993],[-91.84472700000003,69.82222000000013],[-91.86000100000001,69.838593],[-91.86416600000001,69.84414699999996],[-91.86054999999999,69.84887700000002],[-91.84944200000001,69.85887100000002],[-91.82112099999989,69.868042],[-91.78250100000002,69.87776200000008],[-91.76390100000003,69.88026400000012],[-91.745544,69.88165300000014],[-91.72860700000001,69.88081399999999],[-91.71305799999999,69.878311],[-91.70111099999997,69.87525900000009],[-91.64445499999994,69.85942100000005],[-91.639725,69.85498000000013],[-91.65167199999996,69.85108900000006],[-91.66639700000002,69.847488],[-91.81916799999993,69.82165500000008]],[[-97.39778100000001,69.68553200000002],[-97.41194200000001,69.68470800000006],[-97.44193999999993,69.68553200000002],[-97.45584100000002,69.68470800000006],[-97.46833800000002,69.68248000000011],[-97.47972099999998,69.67886400000003],[-97.489441,69.67387400000001],[-97.49027999999987,69.6685940000001],[-97.476944,69.65470900000003],[-97.398346,69.59748800000006],[-97.391388,69.59332300000005],[-97.37887599999993,69.59248400000013],[-97.372772,69.5983280000001],[-97.35194399999995,69.63136299999996],[-97.35082999999997,69.63665800000007],[-97.34750400000001,69.64221200000003],[-97.32972699999988,69.66970800000007],[-97.31639100000001,69.686646],[-97.30387899999994,69.69831799999992],[-97.28916899999996,69.69802900000002],[-97.27389499999998,69.69470200000006],[-97.22639500000002,69.67553700000008],[-97.20695499999994,69.66748000000013],[-97.11389200000002,69.62220800000011],[-97.10694899999993,69.617752],[-97.10360700000001,69.61415099999994],[-97.101944,69.60914600000007],[-97.10278299999993,69.6038670000001],[-97.09944200000001,69.59414700000002],[-97.09056099999998,69.58499100000006],[-97.06443799999994,69.57276900000011],[-96.95556599999998,69.52331500000008],[-96.879166,69.49136400000003],[-96.86694299999999,69.48776200000009],[-96.63778699999995,69.43719499999997],[-96.50250199999994,69.40971400000012],[-96.32028200000002,69.35470599999996],[-96.30139199999996,69.34664899999996],[-96.20889299999999,69.30693100000013],[-96.20222499999994,69.30276500000002],[-96.18998699999997,69.28887900000007],[-96.17222600000002,69.26527400000009],[-96.170547,69.26054400000004],[-96.1719359999999,69.25526400000001],[-96.17555199999993,69.24971],[-96.193329,69.23748800000004],[-96.20333900000003,69.23248299999995],[-96.20973200000003,69.22665399999994],[-96.21305799999999,69.21110500000003],[-96.22361799999993,69.14193699999993],[-96.23500099999995,69.0641480000001],[-96.23361199999988,69.05941800000005],[-96.22972099999998,69.05470300000002],[-96.22555499999999,69.04998799999998],[-96.218887,69.0458220000001],[-96.19526699999994,69.03831500000001],[-96.1663969999999,69.03137199999998],[-96.1324919999999,69.02499400000005],[-96.11888099999993,69.02554299999997],[-96.11527999999998,69.03082300000005],[-96.11389199999996,69.03610200000003],[-96.12999000000002,69.05470300000002],[-96.152222,69.10304300000007],[-96.15695199999999,69.16331500000007],[-96.15583800000002,69.16859400000004],[-96.1494449999999,69.17442300000005],[-96.073624,69.23165899999998],[-96.05972300000002,69.23220800000013],[-96.04777499999989,69.22831700000006],[-96.04110700000001,69.22387700000007],[-95.95556599999992,69.14193699999993],[-95.95167500000002,69.13749700000011],[-95.92443800000001,69.0894320000001],[-95.92582700000003,69.08442700000006],[-95.93472300000002,69.07832300000001],[-95.9536129999999,69.06721500000003],[-95.97138999999993,69.05497699999995],[-95.97778299999999,69.04914900000006],[-95.978882,69.04386899999997],[-95.97084000000001,69.03471400000012],[-95.93859900000001,69.0038760000001],[-95.92555199999998,68.99525500000004],[-95.843887,68.92303500000003],[-95.82028200000002,68.87025499999999],[-95.770554,68.89109800000006],[-95.756958,68.89137300000004],[-95.74583399999995,68.88859600000012],[-95.67416399999996,68.86998000000011],[-95.6702729999999,68.86554000000012],[-95.66860999999994,68.86053500000008],[-95.66749599999997,68.855545],[-95.67138699999998,68.85026600000003],[-95.66722099999998,68.83526600000005],[-95.66332999999997,68.83082600000006],[-95.65417500000001,68.82665999999995],[-95.62609899999995,68.82665999999995],[-95.57583599999998,68.83027600000003],[-95.55027799999988,68.833054],[-95.52833599999991,68.84027100000009],[-95.51028400000001,68.85247800000008],[-95.48998999999998,68.86164900000006],[-95.44665500000002,68.87914999999998],[-95.42471299999994,68.88665800000001],[-95.38999899999999,68.89526400000011],[-95.37805200000003,68.89776599999999],[-95.365005,68.89915500000001],[-95.35139500000002,68.89942900000011],[-95.335556,68.89721700000007],[-95.321396,68.8936000000001],[-95.24027999999998,68.86692800000003],[-95.22888199999994,68.86303700000013],[-95.21055599999994,68.85470600000002],[-95.206955,68.85026600000003],[-95.21083099999998,68.84471100000013],[-95.26306199999999,68.80276500000014],[-95.273056,68.79748500000011],[-95.47639500000002,68.71192900000011],[-95.54361,68.70248400000003],[-95.53999299999992,68.70803800000004],[-95.53889500000002,68.71331800000013],[-95.53889500000002,68.72331200000013],[-95.54638699999998,68.73248300000006],[-95.55943300000001,68.74136400000003],[-95.56834400000002,68.74552900000003],[-95.59388699999994,68.75277700000004],[-95.60804699999989,68.75332600000013],[-95.62193299999996,68.75277700000004],[-95.79055800000003,68.73719800000009],[-95.80166600000001,68.73387099999997],[-95.848343,68.66998300000012],[-95.85972600000002,68.65332000000006],[-95.98889199999996,68.62164300000012],[-96.00083899999993,68.61943100000002],[-96.14973399999991,68.55720500000001],[-96.256393,68.50332600000002],[-96.26251200000002,68.49748199999999],[-96.26472499999988,68.48719800000015],[-96.27084400000001,68.48136899999997],[-96.29138199999994,68.47303800000003],[-96.30221599999993,68.46971100000013],[-96.31388899999996,68.46720900000003],[-96.50361599999991,68.44609100000014],[-96.53056300000003,68.444977],[-96.71749899999992,68.47499099999999],[-96.76834100000002,68.48526000000004],[-96.91389500000002,68.51805100000013],[-96.92832899999996,68.52137800000008],[-97.09445199999988,68.53915400000005],[-97.09555099999994,68.53414900000001],[-97.09889199999998,68.528595],[-97.11999499999996,68.52082800000005],[-97.13082899999995,68.51748700000002],[-97.14250199999998,68.51499900000005],[-97.15417500000001,68.51277199999998],[-97.181107,68.51138299999997],[-97.46000700000002,68.53414900000001],[-97.47500599999995,68.53553799999997],[-97.50611899999996,68.54193099999998],[-97.55332900000002,68.55664100000007],[-97.57417299999992,68.56414800000005],[-97.583618,68.56805400000007],[-97.66722099999993,68.60386699999998],[-97.72721899999999,68.63220199999995],[-97.91860999999994,68.67553700000013],[-98.020554,68.69358800000009],[-98.03555299999994,68.69470200000006],[-98.04998799999998,68.69497700000011],[-98.06277499999999,68.69358800000009],[-98.07833899999997,68.6833190000001],[-98.08389299999999,68.67747500000007],[-98.09333799999996,68.67221100000006],[-98.10499599999997,68.66970800000013],[-98.11999499999996,68.6708220000001],[-98.12971500000003,68.67469800000015],[-98.24027999999998,68.72082500000005],[-98.26112399999994,68.73359700000003],[-98.281677,68.74636800000013],[-98.29055800000003,68.75555400000007],[-98.29249599999997,68.76054399999998],[-98.29194599999994,68.76582300000013],[-98.28611799999993,68.77165200000013],[-98.26972999999998,68.78387500000002],[-98.26083399999993,68.789154],[-98.24916100000002,68.80081200000001],[-98.24305699999996,68.81192000000004],[-98.24415599999998,68.82222000000013],[-98.26306199999999,68.82998700000007],[-98.27528399999989,68.83360299999998],[-98.36971999999997,68.85748300000012],[-98.38333099999994,68.85998500000005],[-98.408051,68.85582000000005],[-98.41860999999994,68.85247800000008],[-98.425003,68.8413700000001],[-98.41528299999999,68.81526200000013],[-98.40194699999995,68.80165099999999],[-98.39361599999995,68.78720100000004],[-98.39472999999992,68.77693200000004],[-98.40028399999994,68.770828],[-98.40861499999994,68.76470899999998],[-98.41860999999994,68.76054399999998],[-98.45111099999997,68.75000000000011],[-98.47639500000002,68.74693300000001],[-98.48999000000003,68.74609400000003],[-98.519455,68.74748199999993],[-98.72471599999989,68.7910920000001],[-98.84722899999997,68.82554600000014],[-98.85943600000002,68.82916300000011],[-98.86639400000001,68.83332800000011],[-98.87554899999998,68.84248400000007],[-98.87971499999998,68.85220300000009],[-98.87916599999994,68.85748300000012],[-98.86999499999996,68.87414600000005],[-98.864441,68.87997400000012],[-98.85638399999999,68.88638300000002],[-98.84750399999996,68.89166300000005],[-98.82667500000002,68.89942900000011],[-98.81750499999987,68.90470900000003],[-98.81193499999995,68.91053800000003],[-98.81138599999991,68.915817],[-98.82055699999995,68.92498799999993],[-98.82749899999999,68.92915299999993],[-98.84944200000001,68.93359400000003],[-98.96583599999997,68.9494170000001],[-98.98110999999994,68.95054600000003],[-98.99305700000002,68.94775400000015],[-99.07749899999999,68.91832],[-99.09584000000001,68.89942900000011],[-99.07640100000003,68.89166300000005],[-99.06220999999994,68.88304100000005],[-99.04388399999993,68.86499000000009],[-99.04415899999987,68.85971100000012],[-99.17610200000001,68.82582100000002],[-99.18859900000001,68.82415800000007],[-99.21055599999994,68.83166499999999],[-99.23666400000002,68.84887700000002],[-99.24610899999999,68.85276800000008],[-99.26722699999999,68.85914600000007],[-99.31138599999991,68.86886600000014],[-99.41332999999997,68.88415500000002],[-99.42805499999997,68.88720699999999],[-99.43777499999999,68.89109800000006],[-99.44499200000001,68.89553800000004],[-99.44972200000001,68.89999399999999],[-99.45417800000001,68.90971400000006],[-99.45111099999991,68.91526800000003],[-99.447769,68.926086],[-99.44888299999997,68.936646],[-99.45083599999998,68.9416500000001],[-99.460556,68.95082100000008],[-99.48916600000001,68.96748400000013],[-99.52333099999987,68.98359699999997],[-99.56249999999994,68.99914600000011],[-99.58972199999988,69.01110800000004],[-99.59416199999998,69.01582300000007],[-99.59638999999993,69.0205380000001],[-99.596115,69.02581800000002],[-99.59333800000002,69.03137199999998],[-99.57988,69.04393000000005],[-99.51362599999987,69.1019290000001],[-99.49221799999987,69.1202550000001],[-99.48582499999998,69.12525900000003],[-99.47694399999995,69.13081399999993],[-99.46665999999993,69.13499500000006],[-99.31138599999991,69.15887500000002],[-99.29666099999997,69.15860000000004],[-99.23805199999998,69.14971900000006],[-99.16833499999996,69.13832100000008],[-99.035278,69.13581800000009],[-99.006958,69.13638300000014],[-98.79804999999999,69.17053199999998],[-98.77444500000001,69.17553700000002],[-98.73055999999997,69.18942300000003],[-98.72027599999996,69.19386300000002],[-98.71112099999999,69.199142],[-98.702789,69.20526100000001],[-98.69972200000001,69.21081500000003],[-98.70111099999997,69.2208250000001],[-98.70527599999997,69.23082000000005],[-98.61555499999992,69.29470800000007],[-98.53388999999993,69.29136700000004],[-98.44137599999988,69.29803500000003],[-98.41555800000003,69.30108600000005],[-98.40333599999997,69.30358899999999],[-98.39334100000002,69.30802900000003],[-98.38751200000002,69.31387300000006],[-98.38417099999998,69.31944299999992],[-98.38806199999999,69.329163],[-98.39723200000003,69.33831800000007],[-98.44027699999998,69.363876],[-98.45722999999998,69.371918],[-98.476944,69.37997400000006],[-98.48889200000002,69.38360599999999],[-98.52333099999998,69.38832100000002],[-98.53555299999994,69.3919370000001],[-98.55555699999996,69.39999400000005],[-98.56249999999994,69.40415999999993],[-98.598053,69.430542],[-98.61193799999995,69.44413800000001],[-98.60888699999987,69.44970699999999],[-98.59167500000001,69.46748400000001],[-98.585556,69.47331200000013],[-98.577225,69.47943099999998],[-98.56332399999991,69.47720300000003],[-98.55332900000002,69.47331200000013],[-98.54083300000002,69.46971100000007],[-98.50834700000001,69.46331800000013],[-98.47749299999992,69.46192899999994],[-98.447769,69.46165500000001],[-98.42250100000001,69.46582000000001],[-98.41944899999999,69.47137499999991],[-98.42416400000002,69.47581500000013],[-98.44888299999991,69.48304700000006],[-98.46389799999997,69.48637400000001],[-98.54943800000001,69.50138900000013],[-98.56471299999993,69.50471500000015],[-98.577225,69.50833100000006],[-98.5869449999999,69.5122070000001],[-98.60166900000002,69.52082800000005],[-98.60555999999991,69.53054800000012],[-98.60499599999997,69.53581200000008],[-98.60194399999995,69.54109199999999],[-98.59277299999991,69.55276500000002],[-98.57556199999999,69.57026700000006],[-98.56695599999995,69.57638499999996],[-98.55665599999986,69.58082600000006],[-98.53138699999994,69.58499100000006],[-98.50140399999992,69.58442700000012],[-98.48554999999999,69.583328],[-98.43331899999998,69.57554600000003],[-98.385559,69.56608599999993],[-98.35777300000001,69.55914300000012],[-98.35055499999993,69.55470300000013],[-98.33889799999997,69.54609700000003],[-98.33416699999998,69.54136699999998],[-98.32250999999991,69.53248600000006],[-98.31082199999997,69.52388000000013],[-98.28443900000002,69.5063780000001],[-98.24861099999998,69.484985],[-98.09249899999998,69.42498800000004],[-98.07861300000002,69.42276000000004],[-98.04972799999996,69.42303500000008],[-98.03666699999985,69.42469800000003],[-98.024719,69.42720000000008],[-98.00389100000001,69.43580600000001],[-97.997772,69.44165000000004],[-97.99722300000002,69.44693000000007],[-98.006958,69.45082100000013],[-98.071396,69.46887200000015],[-98.15722699999998,69.4994200000001],[-98.166946,69.50332600000002],[-98.18859900000001,69.516098],[-98.21139499999992,69.53887900000001],[-98.25584399999997,69.57470700000005],[-98.26306199999999,69.57887299999993],[-98.295837,69.5852660000001],[-98.33029199999999,69.59027100000014],[-98.36054999999993,69.59664900000013],[-98.36776700000001,69.60108900000012],[-98.32167099999998,69.71360800000008],[-98.31416300000001,69.72221400000001],[-98.28195199999993,69.75166300000001],[-98.23028599999998,69.78887900000012],[-98.21112099999999,69.79942299999999],[-98.19972200000001,69.80276500000014],[-98.18720999999994,69.805252],[-98.14388999999994,69.80636600000003],[-98.11805700000002,69.81053200000008],[-98.1077729999999,69.81469700000008],[-98.08860800000002,69.82527200000004],[-98.07972699999999,69.83137499999998],[-98.06166100000002,69.84887700000002],[-98.05833399999989,69.85443100000003],[-98.04916400000002,69.865814],[-98.04305999999997,69.871643],[-98.03416400000003,69.87803600000001],[-98.01222200000001,69.88581799999997],[-97.99972500000001,69.88804600000009],[-97.97416699999991,69.89221199999997],[-97.94554099999999,69.8936000000001],[-97.93055700000002,69.89332599999994],[-97.91332999999997,69.891098],[-97.88027999999991,69.88499500000006],[-97.75500499999993,69.85137900000007],[-97.691101,69.81999200000013],[-97.68916299999995,69.81526200000013],[-97.68221999999997,69.81080600000001],[-97.66000400000001,69.80331400000006],[-97.61000099999995,69.78858900000012],[-97.57972699999999,69.78193700000003],[-97.44915800000001,69.76026900000011],[-97.34110999999996,69.7063750000001],[-97.33944699999995,69.70138500000002],[-97.34805299999988,69.69525100000004],[-97.358612,69.690811],[-97.37110899999999,69.68858300000005],[-97.39778100000001,69.68553200000002]],[[-97.32501200000002,69.88916000000006],[-97.31527699999992,69.88804600000009],[-97.30166599999995,69.88970900000004],[-97.28999299999992,69.89305100000013],[-97.276947,69.89444000000015],[-97.26777599999997,69.89444000000015],[-97.25,69.89137300000004],[-97.237503,69.88777199999998],[-97.23055999999991,69.88333100000006],[-97.22694399999995,69.87359600000013],[-97.23055999999991,69.868042],[-97.2369379999999,69.86219800000015],[-97.24388099999999,69.85748300000012],[-97.26916499999999,69.85247800000008],[-97.28388999999999,69.85276800000008],[-97.2991639999999,69.8560940000001],[-97.30888399999998,69.86026000000004],[-97.31777999999991,69.86943100000013],[-97.41833499999996,69.8936000000001],[-97.44888300000002,69.89414999999991],[-97.46583599999991,69.89637800000008],[-97.48028599999992,69.89888000000013],[-97.48889200000002,69.90803500000004],[-97.49276700000001,69.91775500000011],[-97.48860200000001,69.94386300000008],[-97.48500099999995,69.94941700000004],[-97.47610500000002,69.95555100000007],[-97.46639999999996,69.96081500000008],[-97.45361299999996,69.96304300000003],[-97.4375,69.96192900000005],[-97.35082999999997,69.94941700000004],[-97.335556,69.94609100000002],[-97.32833900000003,69.9416500000001],[-97.32749899999999,69.93165600000009],[-97.346115,69.91720599999996],[-97.34973099999996,69.91165199999995],[-97.35166900000002,69.90138200000001],[-97.34722899999991,69.89665200000002],[-97.33750900000001,69.89276100000012],[-97.32501200000002,69.88916000000006]],[[-100.8497309999999,69.92553700000008],[-100.86389199999991,69.92469800000009],[-100.87444299999999,69.92858899999999],[-100.87999000000002,69.933044],[-100.87999000000002,69.93830900000006],[-100.85861199999994,69.97776799999997],[-100.85333300000002,69.98359700000015],[-100.84333800000002,69.98803700000002],[-100.83112299999993,69.99081400000006],[-100.81500199999994,69.98970000000008],[-100.80695300000002,69.98580900000002],[-100.80526700000001,69.98027000000002],[-100.80721999999997,69.97526600000009],[-100.80721999999997,69.969986],[-100.81249999999994,69.95887800000003],[-100.83112299999993,69.93553199999997],[-100.83999599999999,69.92997700000006],[-100.8497309999999,69.92553700000008]],[[-87.091385,70.1502690000001],[-87.06361400000003,70.1477660000001],[-87.05166599999995,70.1419370000001],[-87.02555799999999,70.13554399999998],[-87.02084399999995,70.13192700000002],[-87.02389499999998,70.12776200000002],[-87.02194199999997,70.12109400000003],[-87.00917099999992,70.116379],[-86.99415599999998,70.11360200000007],[-86.92250100000001,70.1041560000001],[-86.90556299999997,70.10304300000007],[-86.87388599999997,70.09887700000013],[-86.85665899999992,70.09776299999999],[-86.82583599999992,70.09275800000012],[-86.79888900000003,70.0872040000001],[-86.77806099999992,70.08970600000004],[-86.76112399999994,70.0935970000001],[-86.68859900000001,70.11526500000002],[-86.67027300000001,70.11804200000012],[-86.639725,70.1166530000001],[-86.61166400000002,70.1119230000001],[-86.59861799999999,70.10859700000003],[-86.58667000000003,70.10443099999998],[-86.54554699999994,70.0813750000001],[-86.54972800000002,70.07249500000006],[-86.55055199999998,70.06637600000005],[-86.53666699999991,70.06248499999998],[-86.511124,70.05304000000007],[-86.50500499999998,70.04803500000003],[-86.50361599999997,70.036926],[-86.50584400000002,70.02859500000005],[-86.50556899999998,70.02331500000003],[-86.50250199999999,70.02082800000011],[-86.487503,70.01776100000001],[-86.47193900000002,70.01582300000007],[-86.460556,70.01220699999999],[-86.45666499999993,70.00749199999996],[-86.46000699999996,70.00471500000009],[-86.468887,69.99971],[-86.48971599999999,69.98387100000008],[-86.502792,69.98054500000006],[-86.52362099999999,69.97804299999996],[-86.54249600000003,69.97747800000013],[-86.662216,69.96748400000013],[-86.714447,69.9669340000001],[-86.747772,69.96943700000008],[-86.76556399999987,69.96971100000002],[-86.83306900000002,69.97442600000005],[-86.864441,69.9785920000001],[-86.88137799999998,69.97970600000008],[-86.89805599999994,69.98220799999996],[-86.92639199999996,69.98915099999999],[-86.93859900000001,69.99331700000005],[-86.962219,70.00471500000009],[-86.98527499999994,70.01388500000013],[-87.00222799999995,70.0149990000001],[-87.01611300000002,70.0105440000001],[-87.02194199999997,70.00526400000001],[-87.029449,70.00082400000002],[-87.03721599999994,69.99664300000012],[-87.05027799999988,69.99165300000004],[-87.066666,69.98915099999999],[-87.08639499999992,69.98776199999998],[-87.104172,69.98776199999998],[-87.13500999999997,69.99275200000005],[-87.148056,69.99748200000005],[-87.16888399999999,70.00860599999993],[-87.18276999999995,70.01388500000013],[-87.195831,70.01721200000003],[-87.21362299999987,70.01748700000007],[-87.229446,70.01944000000003],[-87.2408289999999,70.02137800000014],[-87.25500499999998,70.02526900000004],[-87.27444499999996,70.034988],[-87.27749599999999,70.03887900000007],[-87.27694699999995,70.04498300000012],[-87.27362099999999,70.05081200000012],[-87.27250700000002,70.05470300000002],[-87.27278099999995,70.05998199999999],[-87.27833599999997,70.06749000000002],[-87.28832999999997,70.07331799999997],[-87.295837,70.07748400000003],[-87.30749500000002,70.080826],[-87.31945799999988,70.08332800000005],[-87.335556,70.08554100000003],[-87.34973100000002,70.08610499999998],[-87.36389200000002,70.08859300000012],[-87.37693799999994,70.09332299999994],[-87.37832599999996,70.09610000000004],[-87.37609900000001,70.09942600000011],[-87.37138400000003,70.10386700000004],[-87.35583499999996,70.10720800000007],[-87.34194899999989,70.10859700000003],[-87.30749500000002,70.10720800000007],[-87.27778599999999,70.11469999999997],[-87.26722699999988,70.11331200000006],[-87.26560999999992,70.11355600000002],[-87.25473,70.11219800000009],[-87.2225039999999,70.11137400000013],[-87.18777499999993,70.10832200000004],[-87.18055700000002,70.109421],[-87.17304999999999,70.11219800000009],[-87.16444399999995,70.11720300000013],[-87.15611299999989,70.11914100000007],[-87.130829,70.12025500000004],[-87.11833200000001,70.11914100000007],[-87.10278299999999,70.12081900000004],[-87.09973099999996,70.12359600000008],[-87.10055499999993,70.12553400000007],[-87.14306599999998,70.13943500000005],[-87.14527900000002,70.14276100000006],[-87.141388,70.14637800000003],[-87.12832600000002,70.14971900000006],[-87.11389199999996,70.14888000000008],[-87.091385,70.1502690000001]],[[-125.05695299999996,70.1183170000001],[-125.08500700000002,70.11633300000011],[-125.10221899999993,70.11807299999998],[-125.11971999999997,70.124954],[-125.122772,70.13006600000006],[-125.12332200000003,70.13546800000006],[-125.12110899999999,70.14137299999999],[-125.11277799999999,70.14697300000006],[-125.10333300000002,70.15168800000009],[-125.083328,70.1599730000001],[-125.07055700000001,70.16187999999994],[-125,70.16293300000007],[-124.97693600000002,70.16720600000008],[-124.96305799999999,70.16832000000005],[-124.95500199999998,70.164154],[-124.98832700000003,70.13443000000001],[-124.99777199999994,70.12997400000006],[-125.04415899999992,70.12031599999995],[-125.05695299999996,70.1183170000001]],[[-124.67944299999994,70.16165200000012],[-124.69444299999998,70.16137700000007],[-124.73750299999995,70.17414900000011],[-124.75361599999991,70.18248],[-124.75917099999998,70.18691999999999],[-124.76194799999996,70.19192500000008],[-124.75890400000003,70.19664000000012],[-124.74471999999997,70.19775400000009],[-124.55110200000001,70.20860299999993],[-124.53611799999987,70.20860299999993],[-124.51888999999994,70.20694000000003],[-124.51055899999994,70.20277399999992],[-124.50527999999997,70.19831800000003],[-124.50750700000003,70.19274900000005],[-124.53694200000001,70.18193100000002],[-124.67944299999994,70.16165200000012]],[[-112.65527299999991,70.266098],[-112.67223399999995,70.266098],[-112.69193999999999,70.26748700000002],[-112.72193900000002,70.272491],[-112.74722300000002,70.278595],[-112.75499699999995,70.28276100000011],[-112.76027699999992,70.2872010000001],[-112.76306199999993,70.29248000000007],[-112.76139799999993,70.29859899999997],[-112.75389100000001,70.30358899999999],[-112.73111,70.309708],[-112.71611000000001,70.31053199999997],[-112.699997,70.309418],[-112.6875,70.30636600000008],[-112.67971799999992,70.30247500000002],[-112.67859599999991,70.30081200000006],[-112.64334099999996,70.28137200000009],[-112.64277600000003,70.27581800000013],[-112.64472999999987,70.26971400000008],[-112.65527299999991,70.266098]],[[-112.96972700000003,70.28137200000009],[-113.00306699999999,70.2810970000001],[-113.104446,70.28193699999997],[-113.14083899999997,70.28332500000005],[-113.15834000000001,70.28526299999999],[-113.20361300000002,70.29248000000007],[-113.16972399999992,70.30693100000013],[-113.15750100000002,70.309708],[-113.12888299999997,70.3124850000001],[-113.11054999999993,70.3119200000001],[-112.993607,70.2994230000001],[-112.97609699999992,70.29748499999994],[-112.96362299999998,70.29443400000014],[-112.95333900000003,70.290817],[-112.94554099999999,70.286652],[-112.95612299999999,70.28332500000005],[-112.96972700000003,70.28137200000009]],[[-100.765289,70.25],[-100.78083800000002,70.25],[-100.7938769999999,70.25332600000002],[-100.84166699999997,70.27832000000001],[-100.86305199999993,70.29109199999999],[-100.86833200000001,70.29553200000004],[-100.85193600000002,70.32388300000014],[-100.83889799999992,70.32554600000003],[-100.80943300000001,70.32415800000012],[-100.77639799999997,70.322495],[-100.75890399999997,70.32054099999999],[-100.74804699999999,70.3169400000001],[-100.74082899999996,70.31053199999997],[-100.75890399999997,70.25499000000002],[-100.765289,70.25]],[[-116.80526699999996,70.50943000000001],[-116.78971899999993,70.50721700000003],[-116.75418100000002,70.50749200000007],[-116.63390400000003,70.4935910000001],[-116.60722399999997,70.48803700000008],[-116.59638999999993,70.484985],[-116.56833599999999,70.47387699999996],[-116.57305899999989,70.46775800000012],[-116.70111099999997,70.4685970000001],[-116.71916199999993,70.47026100000011],[-116.787781,70.48359700000003],[-116.814438,70.48887600000006],[-116.82055700000001,70.4935910000001],[-116.82861300000002,70.503601],[-116.82224300000001,70.50888100000003],[-116.80526699999996,70.50943000000001]],[[-116.287781,70.55331400000011],[-116.26027699999992,70.54998800000004],[-116.24333199999995,70.55026199999998],[-116.18943799999994,70.54553199999998],[-116.140556,70.538589],[-116.12748699999997,70.53581200000008],[-116.131104,70.532486],[-116.29110699999995,70.51554900000002],[-116.32333399999993,70.51361100000008],[-116.44611399999991,70.50888100000003],[-116.464722,70.50915499999996],[-116.47778299999999,70.51193200000006],[-116.495003,70.51998900000007],[-116.49582700000002,70.52276599999993],[-116.47000099999997,70.53804000000002],[-116.30304699999988,70.55219999999997],[-116.287781,70.55331400000011]],[[-116.56304899999998,70.534424],[-116.57833900000003,70.53305100000006],[-116.596947,70.53332499999999],[-116.75028999999995,70.539154],[-116.76363400000002,70.54193100000009],[-116.77443700000003,70.54525800000005],[-116.766953,70.54832499999998],[-116.75527999999991,70.55108599999994],[-116.72361799999987,70.55636600000003],[-116.71193699999998,70.55941799999994],[-116.681671,70.56192000000004],[-116.66471899999999,70.56248500000004],[-116.64611799999994,70.56219500000003],[-116.54305999999997,70.55970799999994],[-116.52278100000001,70.55859399999997],[-116.50945300000001,70.55609100000004],[-116.50778200000002,70.55026199999998],[-116.51806599999998,70.54664600000012],[-116.56304899999998,70.534424]],[[-115.92054699999989,70.54136699999998],[-115.95445299999994,70.54026799999997],[-115.99333200000001,70.5416560000001],[-116.051941,70.54553199999998],[-116.06111099999993,70.54832499999998],[-116.04250299999995,70.55219999999997],[-115.98388699999998,70.56080600000007],[-115.97222899999991,70.56359900000001],[-115.91972399999997,70.57249499999995],[-115.87917299999998,70.57859800000011],[-115.86389200000002,70.57998700000007],[-115.82501199999996,70.57832300000007],[-115.81416300000001,70.57499700000005],[-115.80803700000001,70.5705410000001],[-115.81082199999997,70.56498699999997],[-115.81916799999999,70.56080600000007],[-115.84111000000001,70.55415300000004],[-115.86638599999998,70.54942300000005],[-115.92054699999989,70.54136699999998]],[[-116.87943999999993,70.54748500000011],[-116.88945000000001,70.54386900000003],[-116.923317,70.54275500000006],[-117.03611799999993,70.54637100000014],[-117.18331899999998,70.5374910000001],[-117.20195000000001,70.53776600000009],[-117.22000099999997,70.539154],[-117.27555799999993,70.55026199999998],[-117.28888699999993,70.55304000000001],[-117.29778299999998,70.55693100000008],[-117.30166600000001,70.56192000000004],[-117.29778299999998,70.57138099999997],[-117.26083399999999,70.58471700000013],[-117.25140399999992,70.58720400000004],[-117.23805199999998,70.58915699999994],[-117.21640000000002,70.59109500000011],[-117.19943199999994,70.5916600000001],[-117.16332999999997,70.588593],[-116.89444700000001,70.55609100000004],[-116.883621,70.55276500000014],[-116.87943999999993,70.54748500000011]],[[-128.086121,70.605545],[-128.104156,70.5958250000001],[-128.1201779999999,70.59721400000012],[-128.11444099999994,70.59193400000004],[-128.11721799999992,70.58055100000001],[-128.123871,70.57388300000008],[-128.13275099999993,70.56915300000003],[-128.34054599999996,70.539154],[-128.34167499999995,70.54220599999991],[-128.252228,70.64637800000008],[-128.24581899999998,70.65304600000007],[-128.23416099999986,70.6560970000001],[-128.21639999999996,70.65470900000003],[-128.18832399999997,70.64860499999998],[-128.11498999999998,70.62803600000001],[-128.10360699999995,70.62441999999999],[-128.09472700000003,70.62052900000009],[-128.0883179999999,70.61608900000004],[-128.08499099999995,70.61109900000002],[-128.086121,70.605545]],[[-100.23082699999992,70.45166000000006],[-100.24333199999995,70.44914200000011],[-100.26000999999985,70.449997],[-100.27610799999997,70.45304900000008],[-100.47250400000001,70.49636799999996],[-100.49916100000002,70.50332600000013],[-100.63054699999998,70.54332000000011],[-100.662781,70.55470300000007],[-100.670837,70.55886800000007],[-100.67639199999996,70.563309],[-100.68138099999993,70.5730440000001],[-100.68138099999993,70.58360299999998],[-100.67832900000002,70.59414700000002],[-100.66443599999991,70.63777199999998],[-100.65194699999995,70.66970800000007],[-100.51194800000002,70.67637600000006],[-100.49500299999988,70.67526200000009],[-100.48000300000001,70.67330900000013],[-100.46916199999998,70.66943400000014],[-100.46112099999999,70.659988],[-100.451683,70.6519320000001],[-100.443604,70.64776599999999],[-100.34722899999991,70.6080320000001],[-100.33640300000002,70.60443100000003],[-100.31945799999994,70.60331700000006],[-100.21833799999996,70.56442299999998],[-100.22444200000001,70.45664999999997],[-100.23082699999992,70.45166000000006]],[[-103.17777999999993,70.62248200000005],[-103.19360399999994,70.62220800000011],[-103.24833699999994,70.62275700000004],[-103.26640299999991,70.62414600000005],[-103.27500900000001,70.62831100000005],[-103.28111299999995,70.63275100000004],[-103.281387,70.63804600000009],[-103.26834099999996,70.66638200000006],[-103.22582999999986,70.67637600000006],[-103.21000700000002,70.67665100000005],[-103.19415299999997,70.67303500000003],[-103.173607,70.6336060000001],[-103.17304999999999,70.62858600000004],[-103.17777999999993,70.62248200000005]],[[-103.35082999999992,70.68719500000009],[-103.36416599999995,70.68525699999998],[-103.38110399999988,70.68580600000013],[-103.39499699999999,70.68914800000005],[-103.42887899999994,70.69999700000011],[-103.43776700000001,70.70387299999999],[-103.44638099999997,70.70803799999999],[-103.45249899999993,70.7124940000001],[-103.45889299999999,70.72221400000001],[-103.46278399999994,70.73220800000001],[-103.45694700000001,70.73719800000003],[-103.443604,70.73915099999999],[-103.42777999999998,70.73942600000004],[-103.39917000000003,70.73719800000003],[-103.36361699999992,70.72776799999997],[-103.34111000000001,70.72026100000005],[-103.33500699999996,70.716095],[-103.33444199999997,70.71081500000008],[-103.33860800000002,70.6994170000001],[-103.34333799999996,70.69358800000009],[-103.35082999999992,70.68719500000009]],[[-71.47166400000003,71.01277200000004],[-71.428879,71.01220699999999],[-71.38917500000002,71.01388500000007],[-71.37110899999993,71.01193199999994],[-71.35749799999996,71.00972000000007],[-71.34472700000003,71.00555400000002],[-71.33917199999996,70.99832200000009],[-71.339722,70.99136400000009],[-71.34306300000003,70.98498500000005],[-71.38667299999992,70.92248500000011],[-71.39222699999999,70.9166560000001],[-71.40249599999987,70.91192600000005],[-71.41555799999998,70.90776100000005],[-71.43306000000001,70.90470900000014],[-71.45111099999991,70.90304600000002],[-71.47444199999995,70.90248100000002],[-71.49554399999994,70.90277100000003],[-71.65444899999994,70.89082299999995],[-71.73306300000002,70.87498499999992],[-71.93388400000003,70.83332800000005],[-71.93777499999993,70.82470699999999],[-71.94638099999997,70.82083100000011],[-71.95556599999998,70.818329],[-71.99166899999994,70.81469700000008],[-72.03860500000002,70.81137100000001],[-72.081955,70.80970800000011],[-72.09666400000003,70.80970800000011],[-72.112213,70.81137100000001],[-72.19860799999998,70.88275099999998],[-72.22332799999998,70.91693100000009],[-72.22528099999994,70.92442300000005],[-72.22639500000002,70.93054200000006],[-72.21389799999992,70.934708],[-72.202225,70.93664600000011],[-72.16665599999999,70.93803400000002],[-72.14889499999992,70.93637100000007],[-72.13667299999997,70.93359400000003],[-72.13362099999995,70.93165600000003],[-72.145554,70.926086],[-72.14917000000003,70.92109700000003],[-72.136124,70.91693100000009],[-72.11749299999991,70.91720599999996],[-72.097778,70.91970800000001],[-72.07833900000003,70.92359900000008],[-72.05776999999995,70.933044],[-72.04472399999992,70.94442699999996],[-72.03944399999995,70.9502720000001],[-72.03332499999993,70.96304299999997],[-72.02667200000002,70.98275799999999],[-72.01972999999987,71.03442400000006],[-72.02139299999999,71.04193099999998],[-72.00862099999995,71.04971300000011],[-71.91610700000001,71.06442300000009],[-71.88417099999992,71.0688780000001],[-71.85166900000002,71.07222000000002],[-71.83168,71.07110600000004],[-71.79472399999997,71.05304000000007],[-71.73083499999996,71.04553200000004],[-71.644455,71.034988],[-71.54695099999998,71.0186000000001],[-71.47166400000003,71.01277200000004]],[[-96.56332399999997,71.29220599999996],[-96.54695099999998,71.28915400000005],[-96.535553,71.28276100000005],[-96.47250400000001,71.23220800000007],[-96.47027599999996,71.22608900000006],[-96.48083500000001,71.20887800000014],[-96.487503,71.20359800000006],[-96.56111099999998,71.20832800000011],[-96.57806399999998,71.21054100000003],[-96.628601,71.22026099999994],[-96.63861099999991,71.22608900000006],[-96.64167800000001,71.23136899999997],[-96.64277600000003,71.23442100000005],[-96.65249599999999,71.2872010000001],[-96.64917000000003,71.29304500000012],[-96.61054999999999,71.29054300000001],[-96.58111600000001,71.29359400000004],[-96.56332399999997,71.29220599999996]],[[-98.895554,71.27777100000003],[-98.90834000000001,71.27304099999998],[-98.97444200000001,71.28471400000001],[-98.98971599999999,71.29054300000001],[-99.00029,71.297211],[-99.00556899999998,71.30192600000004],[-99.008621,71.30802900000015],[-99.00889599999994,71.313873],[-99.00306699999993,71.31944300000009],[-98.96362299999993,71.35220300000009],[-98.95584099999996,71.35220300000009],[-98.93028300000003,71.34220900000008],[-98.92332499999998,71.3377690000001],[-98.91444399999995,71.33166500000004],[-98.895554,71.27777100000003]],[[-73.120544,71.47970599999996],[-73.12943999999993,71.45082100000008],[-73.07749899999993,71.466385],[-73.04333500000001,71.47886699999998],[-73.03555299999994,71.48414600000001],[-73.01640299999997,71.50000000000011],[-73.00584400000002,71.51165800000012],[-72.99804699999999,71.51721199999992],[-72.985275,71.52137800000003],[-72.97222899999997,71.52137800000003],[-72.96250899999995,71.51998900000001],[-72.93415799999997,71.50915500000013],[-72.82749899999999,71.45498700000002],[-72.82028199999996,71.4497070000001],[-72.81750499999998,71.44497700000011],[-72.82333399999999,71.43969700000002],[-72.831955,71.43580600000013],[-72.84973099999996,71.4327550000001],[-72.8724979999999,71.43081699999999],[-72.92166099999997,71.428314],[-72.99276700000001,71.41943399999997],[-73.01000999999997,71.41554300000007],[-73.02278099999995,71.41110199999997],[-73.03111299999995,71.40664699999996],[-73.028885,71.39915500000006],[-73.00750700000003,71.35220300000009],[-72.97888199999994,71.32971200000009],[-72.97416699999991,71.32499700000005],[-72.97193900000002,71.31749000000013],[-72.97361799999987,71.31330900000006],[-72.98388699999998,71.30859400000003],[-72.99665799999991,71.3041530000001],[-73.025284,71.29748500000011],[-73.06054699999993,71.29470800000001],[-73.0894469999999,71.313873],[-73.16332999999992,71.33248900000001],[-73.19860799999992,71.33638000000008],[-73.24499500000002,71.34887700000007],[-73.26528899999994,71.357483],[-73.27250699999996,71.36192299999999],[-73.27500899999995,71.36581400000006],[-73.27639799999997,71.37915000000004],[-73.265015,71.39637800000014],[-73.25500499999993,71.40887499999997],[-73.25473,71.41526800000008],[-73.29360999999989,71.45471199999997],[-73.30139200000002,71.45971700000001],[-73.3205569999999,71.46971100000007],[-73.34750400000001,71.47776800000003],[-73.36250299999995,71.48109400000004],[-73.3741609999999,71.48580900000007],[-73.37999000000002,71.51971400000002],[-73.37721299999998,71.5227660000001],[-73.36694299999999,71.52748099999997],[-73.18998699999992,71.56553600000007],[-73.176941,71.5663760000001],[-73.14750700000002,71.56442300000015],[-73.13221699999991,71.56137100000007],[-73.09028599999994,71.54637100000008],[-73.08111600000001,71.54220600000008],[-73.07362399999994,71.53692600000005],[-73.07472200000001,71.53137200000003],[-73.11332699999997,71.48580900000007],[-73.120544,71.47970599999996]],[[-72.76083399999987,71.53193700000008],[-72.78639199999998,71.53027300000002],[-72.83084100000002,71.53109699999999],[-72.84889199999992,71.53221100000002],[-72.86749299999991,71.53387500000002],[-72.949997,71.54721100000012],[-72.98249799999991,71.5535890000001],[-73.00889599999988,71.56109600000002],[-73.020554,71.56581100000005],[-73.03056299999992,71.57165500000008],[-73.03527799999995,71.57554600000014],[-73.03999299999998,71.57998700000007],[-73.03750600000001,71.58720399999999],[-73.03416400000003,71.59220900000003],[-72.96806299999997,71.63665800000001],[-72.94860799999998,71.64471400000008],[-72.924713,71.64942900000011],[-72.80665599999992,71.65914900000001],[-72.781113,71.66081200000013],[-72.74526999999995,71.65998799999994],[-72.72666900000002,71.65832500000005],[-72.70916699999998,71.65525800000012],[-72.69583099999994,71.65109300000012],[-72.68443300000001,71.64276100000012],[-72.66221599999994,71.60443100000003],[-72.66055299999994,71.59803800000003],[-72.671112,71.58581500000003],[-72.68249500000002,71.57470699999999],[-72.70111099999991,71.55748],[-72.71278399999994,71.54721100000012],[-72.718887,71.54275500000006],[-72.72749299999998,71.53858900000012],[-72.74249299999997,71.53414900000013],[-72.76083399999987,71.53193700000008]],[[-73.37027,71.55442800000009],[-73.39445499999994,71.55442800000009],[-73.40666199999998,71.55636600000003],[-73.41833500000001,71.56109600000002],[-73.42860399999995,71.56694000000005],[-73.43693499999995,71.57331800000003],[-73.45056199999999,71.58415200000007],[-73.44972199999995,71.58998100000008],[-73.44804399999992,71.59414699999996],[-73.44193999999999,71.59887700000002],[-73.38861099999991,71.63415500000002],[-73.34834299999994,71.65832500000005],[-73.27610800000002,71.69192499999991],[-73.24333200000001,71.69663999999995],[-73.21333299999998,71.69859300000007],[-73.20916699999998,71.69886800000012],[-73.19055200000003,71.697205],[-73.16749600000003,71.69220000000013],[-73.15556299999997,71.68719500000009],[-73.14889499999998,71.67997700000006],[-73.14999399999999,71.6744230000001],[-73.17054699999994,71.66831999999994],[-73.221115,71.66026299999999],[-73.24943499999995,71.65248100000002],[-73.26251199999996,71.64804100000003],[-73.28277600000001,71.63777199999998],[-73.303604,71.62191800000005],[-73.32028199999996,71.605545],[-73.32501200000002,71.59915200000006],[-73.33167999999995,71.58804299999997],[-73.33860799999997,71.57110599999993],[-73.33972199999994,71.56526200000013],[-73.35249299999998,71.55748],[-73.37027,71.55442800000009]],[[-96.95889299999993,71.7044370000001],[-96.99888599999997,71.70109600000006],[-97.03639199999992,71.70138500000002],[-97.05027799999993,71.704163],[-97.0497279999999,71.70999100000012],[-97.04028299999999,71.72026100000005],[-97.02416999999997,71.73109399999998],[-96.99888599999997,71.74136399999992],[-96.99166899999994,71.74304200000006],[-96.99082900000002,71.74386600000003],[-96.96945199999999,71.74859600000002],[-96.96389799999997,71.75221299999998],[-96.92416399999996,71.75555400000002],[-96.88639799999999,71.75526400000001],[-96.86694299999999,71.75360100000012],[-96.85055499999987,71.74941999999999],[-96.84445199999999,71.74414100000001],[-96.8511049999999,71.73887599999995],[-96.86860699999994,71.7285920000001],[-96.88137799999993,71.72331200000008],[-96.89695699999993,71.71832300000011],[-96.91583299999996,71.71360800000008],[-96.95889299999993,71.7044370000001]],[[-95.33999599999993,71.73136900000003],[-95.39805599999994,71.72943100000009],[-95.43582200000003,71.72998000000001],[-95.47111499999994,71.73359700000015],[-95.4830629999999,71.73692300000005],[-95.48832699999997,71.74081400000011],[-95.48805199999987,71.74552900000015],[-95.45028699999995,71.81887799999993],[-95.44027699999998,71.82415800000001],[-95.42083699999989,71.82887300000004],[-95.38417099999998,71.83610499999998],[-95.34889199999998,71.84054600000007],[-95.32861300000002,71.84220899999997],[-95.30166600000001,71.84414700000013],[-95.28666699999997,71.84304800000012],[-95.27583299999998,71.84027100000003],[-95.26583899999997,71.83665500000001],[-95.26167299999997,71.83332800000005],[-95.25973499999992,71.82748400000003],[-95.31054699999993,71.73719800000003],[-95.32472199999995,71.73275800000005],[-95.33999599999993,71.73136900000003]],[[-134.49554399999994,68.75221300000004],[-134.4880369999999,68.736649],[-134.4880369999999,68.7310940000001],[-134.48306299999996,68.72053500000004],[-134.47387700000002,68.71137999999996],[-134.46472199999994,68.70748900000007],[-134.44638099999997,68.70027199999998],[-134.40112299999993,68.68775900000009],[-134.373871,68.68248000000011],[-134.33999599999999,68.67886400000009],[-134.30804399999994,68.67804000000012],[-134.282776,68.68136600000014],[-134.24636799999996,68.68748499999998],[-134.23071299999998,68.6928410000001],[-134.22692899999998,68.69413800000012],[-134.22332800000004,68.69970699999993],[-134.26058999999987,68.73353599999996],[-134.26251200000002,68.73637400000013],[-134.28750599999995,68.753601],[-134.30835000000002,68.76609799999994],[-134.32638499999996,68.77360500000009],[-134.423065,68.83166499999999],[-134.54168700000002,68.91970800000007],[-134.558044,68.933044],[-134.614441,68.98332199999999],[-134.62387099999995,68.99275200000005],[-134.628876,69.00305200000014],[-134.62914999999992,69.00888099999997],[-134.62469499999992,69.01554899999996],[-134.56222499999996,69.08276400000011],[-134.55499299999997,69.08776899999998],[-134.537506,69.09387200000009],[-134.491943,69.10415599999999],[-134.46362299999998,69.1060940000001],[-134.4480589999999,69.1060940000001],[-134.36303699999996,69.10220300000003],[-134.34887700000002,69.10304300000007],[-134.33889799999992,69.10636900000009],[-134.22747800000002,69.1749880000001],[-134.223053,69.18165600000003],[-134.22082499999993,69.18803400000002],[-134.22137499999997,69.21638500000012],[-134.2169489999999,69.22303800000009],[-134.162781,69.25471500000003],[-134.15389999999996,69.25888099999992],[-134.142517,69.26138300000002],[-134.12832599999996,69.26220699999999],[-134.06915299999997,69.26277199999998],[-134.05471799999998,69.26361099999997],[-134.029175,69.26693699999998],[-133.9286189999999,69.28221100000007],[-133.90557899999988,69.28749099999999],[-133.89529400000004,69.290817],[-133.886688,69.29498300000012],[-133.87914999999998,69.29998799999998],[-133.87332199999997,69.30581699999999],[-133.86859100000004,69.31248499999992],[-133.86886599999997,69.31832900000012],[-133.87332199999997,69.32304399999998],[-133.87582399999997,69.32832299999995],[-133.86972000000003,69.33415199999996],[-133.67028799999997,69.38665800000007],[-133.65863000000002,69.38916],[-133.55056799999994,69.40582300000005],[-133.407776,69.41470300000009],[-133.3722229999999,69.41220100000004],[-133.35583499999996,69.40998800000006],[-133.32806400000004,69.40470900000008],[-133.30972299999996,69.40277100000014],[-133.23443599999996,69.39721700000013],[-133.21749899999992,69.39637799999997],[-133.2058409999999,69.39888000000008],[-133.073059,69.43498200000005],[-132.99942,69.48193400000014],[-132.966095,69.51165799999995],[-132.95220899999998,69.56330900000006],[-132.951935,69.56915300000003],[-132.95666499999993,69.57388300000008],[-132.96581999999995,69.57748400000014],[-132.98638900000003,69.59027100000014],[-132.988586,69.595261],[-132.98361199999994,69.60220300000009],[-132.97747800000002,69.6080320000001],[-132.92251599999997,69.64221200000003],[-132.904449,69.65054299999997],[-132.89388999999994,69.65387000000004],[-132.864716,69.6583250000001],[-132.821106,69.66053800000003],[-132.78778099999994,69.65971400000006],[-132.66229199999998,69.651207],[-132.628784,69.64804800000007],[-132.62028499999997,69.64637800000014],[-132.6147919999999,69.64404300000001],[-132.606628,69.63904600000012],[-132.55279499999995,69.63136299999996],[-132.535278,69.63026400000001],[-132.41751099999993,69.63554400000004],[-132.39389,69.64027400000009],[-132.372772,69.64694200000008],[-132.345276,69.65942400000006],[-132.332489,69.67109700000009],[-132.32748399999997,69.67776500000008],[-132.333618,69.68248000000011],[-132.441101,69.70248400000003],[-132.457489,69.70471199999997],[-132.4677729999999,69.70138500000002],[-132.517792,69.68331900000004],[-132.54823299999998,69.68531000000013],[-132.55523700000003,69.68382300000002],[-132.57455400000003,69.68398300000013],[-132.582718,69.685654],[-132.586884,69.68814800000013],[-132.58673099999993,69.69164999999998],[-132.54833999999994,69.73580900000007],[-132.54055799999998,69.74081400000011],[-132.52749600000004,69.74247700000006],[-132.473053,69.74775699999992],[-132.39974999999998,69.75166300000001],[-132.28918499999992,69.7249910000001],[-132.21304299999997,69.690811],[-132.19888300000002,69.68803400000007],[-132.16305499999999,69.68525699999998],[-132.14697299999995,69.68525699999998],[-132.12304700000004,69.71360800000008],[-132.1166379999999,69.71943699999991],[-132.107208,69.72360200000008],[-132.08331299999992,69.72859199999999],[-131.95443699999998,69.75471500000009],[-131.87469499999992,69.76388499999996],[-131.858612,69.76361100000003],[-131.845276,69.76527399999998],[-131.8347169999999,69.76859999999999],[-131.76556400000004,69.79470799999996],[-131.758911,69.80053699999996],[-131.75836200000003,69.80636600000003],[-131.760284,69.81164600000005],[-131.7647399999999,69.8163760000001],[-131.76666299999994,69.82165500000008],[-131.76000999999997,69.82748400000008],[-131.75058,69.83137499999998],[-131.64502,69.86499000000003],[-131.62359600000002,69.87136800000002],[-131.447784,69.91859400000004],[-131.4263919999999,69.9474790000001],[-131.42111199999994,69.954163],[-131.41027799999995,69.95721400000002],[-131.34887700000002,69.95248400000014],[-131.26916499999993,69.93775900000003],[-131.2460939999999,69.93109100000004],[-131.237213,69.92719999999997],[-131.2305599999999,69.92303500000014],[-131.20916699999998,69.89915500000001],[-131.20333899999997,69.88916000000006],[-131.20138499999996,69.88388100000009],[-131.201935,69.87803600000001],[-131.2049869999999,69.87191800000005],[-131.21054099999998,69.86526500000008],[-131.21722399999987,69.85942100000005],[-131.22164899999996,69.85415599999999],[-131.2222289999999,69.84832800000004],[-131.220551,69.84304800000001],[-131.21194499999996,69.8336030000001],[-131.205261,69.82943700000004],[-131.19638099999997,69.82554600000014],[-131.18499799999995,69.82415800000007],[-131.08056599999998,69.88499500000006],[-131.07501199999996,69.89166300000005],[-131.03140299999995,69.94941700000004],[-131.01028399999996,69.98692299999999],[-131.01278699999995,70.02331500000003],[-131.01947,70.02777100000009],[-130.930298,70.08305400000012],[-130.892242,70.099152],[-130.74832199999997,70.08194000000015],[-130.6561279999999,70.10859700000003],[-130.554169,70.16526799999997],[-130.5430599999999,70.16832000000005],[-130.48721299999994,70.17330900000002],[-130.47222899999997,70.17387400000007],[-130.467712,70.17008999999996],[-130.47271699999993,70.16709900000012],[-130.48388699999998,70.16499299999998],[-130.51141399999995,70.16220100000004],[-130.52224699999994,70.15887500000002],[-130.54724099999999,70.12747200000001],[-130.54806499999995,70.121643],[-130.54638699999992,70.116379],[-130.54223599999995,70.11164899999994],[-130.535553,70.10748300000006],[-130.52416999999997,70.10386700000004],[-130.5102839999999,70.101089],[-130.49527,70.10165400000005],[-130.48416099999992,70.10470599999996],[-130.43237299999998,70.12587000000013],[-130.40722700000003,70.14053300000012],[-130.35360699999995,70.132202],[-130.33084099999996,70.11080900000007],[-130.32250999999997,70.10137900000001],[-130.18472299999996,70.05358900000004],[-130.16861,70.053314],[-129.97555499999993,70.06944299999998],[-129.96304299999997,70.07165500000002],[-129.92611699999992,70.078598],[-129.89083900000003,70.09275800000012],[-129.86444099999994,70.12692300000003],[-129.84609999999986,70.15498400000013],[-129.8324889999999,70.19552599999992],[-129.79000899999994,70.21998600000012],[-129.731384,70.25305200000008],[-129.697784,70.262497],[-129.68667600000003,70.26554900000008],[-129.67306499999995,70.26693699999998],[-129.647247,70.25166300000006],[-129.60916099999992,70.21304299999997],[-129.45916699999998,70.14749100000012],[-129.404724,70.12303199999997],[-129.403351,70.11775200000011],[-129.40527299999997,70.10636900000009],[-129.406403,70.10054000000008],[-129.4100039999999,70.09443699999997],[-129.433899,70.06805400000013],[-129.497498,70.0205380000001],[-129.57360799999998,69.99775700000009],[-129.59555099999994,69.99136399999992],[-129.88946499999992,69.91720599999996],[-129.9930419999999,69.89248700000002],[-130.22805800000003,69.84054600000013],[-130.49581899999998,69.78166200000004],[-130.559998,69.73719800000009],[-130.561401,69.72581500000007],[-130.56472799999995,69.71971100000002],[-130.57028200000002,69.71304300000008],[-130.57833900000003,69.70803800000004],[-130.62136799999996,69.69525100000004],[-130.6469729999999,69.69136000000015],[-130.70416299999994,69.68830900000012],[-130.75750700000003,69.68248000000011],[-130.78030399999994,69.6769260000001],[-130.789734,69.67276000000004],[-130.83639500000004,69.6336060000001],[-130.83944699999995,69.62747200000007],[-130.84081999999995,69.6160890000001],[-130.83667000000003,69.61109900000002],[-130.837494,69.60554500000006],[-130.84414699999996,69.599716],[-130.91915899999998,69.56721500000009],[-130.92861899999997,69.56330900000006],[-130.94473299999999,69.56553600000012],[-131.02667199999996,69.59304800000007],[-131.03973399999995,69.601654],[-131.04168699999997,69.60693400000002],[-131.04083300000002,69.61276199999998],[-131.05307,69.63720699999999],[-131.16332999999992,69.62776200000013],[-131.188599,69.62387100000007],[-131.32861299999996,69.57998700000013],[-131.40750099999997,69.58665500000006],[-131.58694500000001,69.56749000000013],[-131.69168100000002,69.55165099999999],[-131.70498699999996,69.56025699999992],[-131.71389799999992,69.563873],[-131.727783,69.5669400000001],[-131.74108899999993,69.56749000000013],[-131.755859,69.5669400000001],[-131.9972229999999,69.53137200000009],[-132.00640899999996,69.52720599999998],[-132.03891,69.50833100000006],[-132.04666099999992,69.50332600000002],[-132.0799869999999,69.48082],[-132.14169300000003,69.41276600000003],[-132.13305699999995,69.40332000000006],[-132.12164299999995,69.39999400000005],[-132.09750399999996,69.3960570000001],[-132.085266,69.39082300000007],[-132.08084099999996,69.38610800000004],[-132.078888,69.3808140000001],[-132.081665,69.37469500000003],[-132.09472700000003,69.36276200000003],[-132.1166379999999,69.35720800000001],[-132.329163,69.31442300000009],[-132.52417000000003,69.27777100000009],[-132.531952,69.28054799999995],[-132.54556300000002,69.28332500000005],[-132.56167599999998,69.28581200000013],[-132.57998699999996,69.28749099999999],[-132.59222399999993,69.28720099999998],[-132.706116,69.26887499999998],[-132.71777299999997,69.26638800000006],[-132.739441,69.26081799999997],[-132.76028399999996,69.25416600000011],[-132.767792,69.24914600000005],[-132.90722699999998,69.1244200000001],[-132.90722699999998,69.11886600000008],[-132.90527299999997,69.042755],[-132.946106,69.03749100000005],[-133.050842,69.05470300000002],[-133.10638399999993,69.05053700000013],[-133.1719359999999,69.04332000000005],[-133.18331899999998,69.04081700000006],[-133.193329,69.03749100000005],[-133.20083599999987,69.03248599999995],[-133.20556599999998,69.02581800000002],[-133.21499600000004,69.00665300000003],[-133.21664399999997,69.001938],[-133.214447,68.99664300000012],[-133.209991,68.99192800000009],[-133.20333900000003,68.98776199999998],[-133.19860799999998,68.98304699999994],[-133.19888300000002,68.97720300000015],[-133.2130429999999,68.93803400000007],[-133.22610499999996,68.91360500000013],[-133.233612,68.90860000000009],[-133.31332399999985,68.87191800000005],[-133.32333399999993,68.86859099999992],[-133.33471699999996,68.86608900000004],[-133.34887699999996,68.86526500000008],[-133.363312,68.86665299999999],[-133.37692300000003,68.86914099999996],[-133.385834,68.87303200000002],[-133.39944500000001,68.88136299999996],[-133.4016719999999,68.88665800000001],[-133.39529400000004,68.89027400000009],[-133.37969999999996,68.89027400000009],[-133.36694299999994,68.89193699999998],[-133.359711,68.89694200000002],[-133.353607,68.90277100000003],[-133.35803199999992,68.90748600000006],[-133.36944599999993,68.91053800000003],[-133.38275099999998,68.91110200000014],[-133.39556899999997,68.90942400000006],[-133.461121,68.89276100000012],[-133.466095,68.88832100000013],[-133.484711,68.85026600000003],[-133.493042,68.82665999999995],[-133.49081399999994,68.82165500000008],[-133.48416099999997,68.81164600000011],[-133.470825,68.79748500000011],[-133.46389799999992,68.79332000000011],[-133.4549869999999,68.78970300000015],[-133.405579,68.77221700000001],[-133.32138099999992,68.74636800000013],[-133.16418499999992,68.70721400000008],[-133.08999599999999,68.69497700000011],[-133.05416899999994,68.69136000000015],[-133.03750599999995,68.69053600000001],[-133.02334599999995,68.69136000000015],[-133.01083399999987,68.693039],[-132.98803699999996,68.69775400000003],[-132.95861799999994,68.69859299999996],[-132.94305399999996,68.69636500000001],[-132.918335,68.69026200000008],[-132.92056299999996,68.69552600000003],[-132.9336239999999,68.70971700000007],[-132.94250499999998,68.71331800000013],[-132.95471199999997,68.71527100000003],[-133.00723299999999,68.71971100000007],[-133.02252199999998,68.71971100000007],[-133.035278,68.71804800000012],[-133.04583699999995,68.71137999999996],[-133.11248799999998,68.71499600000004],[-133.142517,68.7185970000001],[-133.15249599999993,68.72082500000005],[-133.25500499999998,68.75860600000004],[-133.25946,68.76332100000008],[-133.26611299999996,68.77886999999998],[-133.26141399999995,68.78553799999997],[-133.24999999999994,68.78804000000002],[-133.23416099999992,68.78581200000008],[-133.225281,68.78221100000002],[-133.220825,68.77748099999997],[-133.220825,68.77165200000013],[-133.21664399999997,68.7669370000001],[-133.20306399999998,68.76416],[-133.16168200000004,68.75749200000007],[-133.14752199999998,68.758331],[-133.13891599999994,68.76249700000011],[-133.1397399999999,68.7669370000001],[-133.21139499999998,68.79081700000012],[-133.234985,68.79582199999999],[-133.250854,68.79803500000014],[-133.28178399999996,68.7944260000001],[-133.28863499999989,68.79309799999999],[-133.30145300000004,68.78942900000004],[-133.325562,68.78749100000005],[-133.33554099999992,68.78970300000015],[-133.34445199999993,68.79359400000004],[-133.35665899999992,68.80108599999994],[-133.35888699999998,68.80636600000003],[-133.35415599999993,68.83221400000014],[-133.332764,68.84387200000015],[-133.27722199999988,68.85693400000002],[-133.26583900000003,68.85942100000005],[-133.23776199999998,68.86109900000002],[-133.22192399999994,68.85887100000002],[-133.18804899999986,68.84915200000006],[-133.16778599999998,68.83665500000006],[-133.15918,68.8272090000001],[-133.152222,68.8230440000001],[-133.12191799999994,68.80581700000005],[-133.108337,68.80304000000001],[-133.091675,68.80219999999991],[-133.062225,68.80276500000014],[-133.00527999999997,68.81526200000013],[-132.95803799999993,68.83554100000009],[-132.962219,68.84609999999992],[-132.9619449999999,68.85165400000011],[-132.951935,68.85497999999995],[-132.93667599999998,68.85497999999995],[-132.86749299999997,68.84609999999992],[-132.85611,68.842758],[-132.78594999999996,68.8184280000001],[-132.75363199999998,68.80276500000014],[-132.49194299999994,68.80108599999994],[-132.4805599999999,68.8035890000001],[-132.470276,68.80693100000008],[-132.405579,68.842758],[-132.40029900000002,68.84721400000012],[-132.39529400000004,68.8538670000001],[-132.392792,68.85998500000005],[-132.396973,68.86470000000008],[-132.49249299999997,68.90637200000009],[-132.50363200000004,68.90971400000006],[-132.55334499999998,68.91609199999999],[-132.56750499999998,68.91526800000003],[-132.57638499999996,68.91110200000014],[-132.574432,68.9060970000001],[-132.5677799999999,68.90165700000006],[-132.54055799999998,68.8961030000001],[-132.55557299999992,68.87831100000005],[-132.66528299999993,68.84193400000004],[-132.67806999999993,68.84027100000009],[-132.69360399999994,68.84054600000013],[-132.76229899999998,68.8574910000001],[-132.77094999999997,68.85814700000003],[-132.777786,68.86015300000008],[-132.7802729999999,68.86298399999998],[-132.833618,68.91775500000011],[-132.85998499999988,68.98915099999999],[-132.868042,69.02137800000014],[-132.871918,69.05664100000001],[-132.86944600000004,69.06275900000009],[-132.86553999999995,69.068329],[-132.81527699999998,69.08638000000002],[-132.80526699999996,69.0894320000001],[-132.77111799999994,69.08554100000003],[-132.75418100000002,69.08471700000007],[-132.6891779999999,69.08248900000012],[-132.67501800000002,69.08332800000005],[-132.66332999999997,69.08581500000014],[-132.54083300000002,69.135269],[-132.46081500000003,69.12469500000009],[-132.464722,69.11914100000013],[-132.46749899999998,69.10720800000007],[-132.45916699999992,69.10803200000004],[-132.42861900000003,69.11775200000011],[-132.40777599999996,69.1244200000001],[-132.38500999999997,69.13916000000006],[-132.378876,69.14526400000005],[-132.36886600000003,69.15860000000004],[-132.36138899999997,69.17137100000014],[-132.343323,69.20332300000007],[-132.34249899999992,69.220261],[-132.33972199999994,69.22665399999994],[-132.33056599999998,69.23082000000005],[-132.32055699999995,69.23387100000008],[-132.30612199999996,69.23471100000012],[-132.22360199999997,69.21360800000002],[-132.2225039999999,69.141663],[-132.16805999999997,69.21388200000013],[-132.116943,69.24220300000007],[-132.05804399999994,69.24220300000007],[-131.99600199999998,69.25163299999991],[-131.96389799999997,69.25694299999998],[-131.875275,69.27970900000003],[-131.86499000000003,69.28305100000011],[-131.8052669999999,69.31637599999999],[-131.79751599999986,69.32138100000009],[-131.791107,69.32720899999998],[-131.71444699999995,69.3977660000001],[-131.72555499999993,69.401093],[-131.73416099999997,69.40054299999997],[-131.806671,69.39137299999993],[-131.950287,69.39582799999994],[-131.96499600000004,69.39721700000013],[-131.972778,69.40026900000004],[-131.97000099999997,69.40637200000003],[-131.65222199999994,69.47192400000006],[-131.63919099999998,69.47360200000014],[-131.60748299999995,69.47331200000013],[-131.59136999999993,69.47082500000005],[-131.458893,69.44914199999994],[-131.44528200000002,69.44636500000007],[-131.432953,69.43719499999997],[-131.42910799999993,69.43470000000013],[-131.43160999999998,69.43136599999997],[-131.43710299999992,69.42903100000007],[-131.451935,69.4205320000001],[-131.46221899999995,69.41720600000008],[-131.471649,69.41303999999997],[-131.47943099999998,69.4080350000001],[-131.48611500000004,69.40220600000009],[-131.53472899999997,69.333328],[-131.52584799999994,69.32943699999993],[-131.49942,69.33248900000007],[-131.420837,69.36164900000011],[-131.41278099999994,69.3666530000001],[-131.40750099999997,69.37330600000007],[-131.38989300000003,69.40415999999993],[-131.377228,69.42748300000005],[-131.32193,69.49331699999999],[-131.27166699999992,69.50109900000012],[-131.25723299999999,69.50166300000006],[-131.24581899999998,69.49832200000003],[-131.2333069999999,69.48414600000001],[-131.22387700000002,69.46360800000014],[-131.22027599999996,69.45332300000001],[-131.21664399999992,69.44274899999999],[-131.21276899999992,69.42220299999997],[-131.21093799999989,69.4125370000001],[-131.210266,69.40604400000007],[-131.21304299999997,69.38749700000005],[-131.22360200000003,69.38443000000012],[-131.2333069999999,69.38472000000013],[-131.24526999999995,69.382202],[-131.26641799999993,69.37580900000006],[-131.31777999999997,69.35887100000014],[-131.39529399999998,69.318604],[-131.40307599999994,69.31387300000006],[-131.415009,69.30137600000006],[-131.41445899999997,69.29693600000002],[-131.33526599999993,69.31666600000005],[-131.324707,69.31999200000007],[-131.19332899999995,69.36526499999997],[-131.188599,69.3683170000001],[-131.16650400000003,69.40493000000009],[-131.16223099999996,69.49054000000007],[-131.16418499999997,69.49552900000003],[-131.23123199999992,69.54389200000003],[-131.25385999999997,69.57184600000011],[-131.225464,69.5807190000001],[-131.20681799999994,69.55720500000001],[-131.15046699999994,69.51860000000005],[-131.13006599999994,69.516388],[-131.11053499999997,69.48532900000004],[-131.130157,69.4293750000001],[-131.14851399999992,69.40353400000004],[-131.1458439999999,69.37469500000003],[-131.135834,69.35998500000011],[-131.12832599999996,69.36192300000005],[-131.101227,69.39392100000009],[-131.08525099999991,69.44051400000001],[-131.06085199999995,69.47068800000011],[-131.06617699999993,69.49109600000008],[-131.06394999999998,69.51238999999998],[-131.08924899999994,69.53191400000014],[-131.10920699999997,69.54344900000012],[-131.127838,69.55454300000002],[-131.14781199999993,69.56119500000011],[-131.16599999999988,69.567856],[-131.1883239999999,69.57470700000005],[-131.19473300000004,69.57887299999993],[-131.1966549999999,69.58415200000013],[-131.196106,69.58998099999997],[-131.19055199999997,69.59664900000013],[-131.183899,69.60247800000013],[-131.17471299999994,69.60636900000003],[-131.13833599999998,69.61415099999994],[-131.12359600000002,69.61470000000008],[-131.1074829999999,69.61248800000004],[-131.093597,69.60942100000011],[-131.087219,69.605255],[-131.08306900000002,69.60053999999997],[-131.045776,69.52442900000005],[-131.02999899999998,69.48580900000013],[-131.027802,69.46388200000007],[-131.03390499999995,69.42915300000004],[-131.03695700000003,69.42303500000008],[-131.07028200000002,69.36747700000006],[-131.10803199999992,69.33526599999999],[-131.113312,69.328598],[-131.116394,69.32249500000006],[-131.10888699999998,69.32165500000002],[-131.09973100000002,69.32582100000008],[-131.05084199999993,69.35443100000009],[-131.02667199999996,69.38386500000013],[-130.98999000000003,69.44914199999994],[-130.99121099999996,69.50104500000009],[-130.9922029999999,69.50420399999996],[-130.99026500000002,69.53942900000004],[-130.98083499999996,69.54359400000004],[-130.96887200000003,69.54582199999999],[-130.952789,69.54332000000011],[-130.94638099999992,69.53915400000005],[-130.94222999999994,69.53414899999996],[-130.94055200000003,69.52915999999999],[-130.9244379999999,69.44859300000002],[-130.93971299999998,69.42148600000002],[-130.94154400000002,69.41781600000007],[-130.94555699999995,69.41431400000005],[-130.95039399999996,69.41132400000009],[-130.98580900000002,69.38304099999993],[-131.02583299999998,69.34787800000004],[-131.02984600000002,69.34436800000009],[-131.03317300000003,69.34037799999999],[-131.031998,69.33721200000002],[-131.03668200000004,69.31053200000002],[-131.027802,69.30664100000013],[-131.01696800000002,69.30748000000006],[-131.01419099999993,69.31387300000006],[-131.01333599999998,69.31944299999992],[-131.010559,69.32554600000009],[-131.00500499999998,69.33221400000002],[-130.99832200000003,69.33804300000003],[-130.95693999999997,69.371918],[-130.93194599999998,69.38348400000001],[-130.92710899999992,69.38649000000004],[-130.91844200000003,69.386818],[-130.91177400000004,69.384819],[-130.90928599999995,69.381981],[-130.89611799999994,69.38053900000006],[-130.89889500000004,69.35276800000003],[-130.90249600000004,69.34082000000012],[-130.906403,69.32887299999999],[-130.91427599999992,69.31831399999999],[-130.93194599999998,69.30497700000012],[-130.93972799999995,69.29998799999998],[-130.96362299999987,69.28526299999999],[-131.00057999999996,69.25665300000014],[-131.024719,69.20971700000013],[-131.01806599999992,69.14193699999993],[-131.01419099999993,69.13693200000006],[-130.99832200000003,69.13472000000002],[-130.9372249999999,69.13443000000001],[-130.92861899999997,69.14526400000005],[-130.93112199999996,69.22248800000006],[-130.93276999999995,69.22776799999991],[-130.9391779999999,69.23220800000013],[-130.9513849999999,69.24636800000007],[-130.950287,69.25776699999994],[-130.94723499999998,69.26416000000012],[-130.94168100000002,69.27053800000004],[-130.934998,69.27638200000007],[-130.82110599999993,69.37469500000003],[-130.81304899999998,69.37970000000013],[-130.771393,69.39888000000008],[-130.76055899999994,69.40220600000009],[-130.73165899999998,69.40332000000006],[-130.714722,69.40220600000009],[-130.70028699999995,69.40277100000014],[-130.689728,69.40609699999999],[-130.660278,69.42942800000003],[-130.65472399999993,69.43609600000002],[-130.64529400000004,69.45471200000003],[-130.652802,69.45776399999994],[-130.667236,69.45721400000008],[-130.74777199999994,69.44914199999994],[-130.71499599999993,69.46220399999999],[-130.52502400000003,69.54359400000004],[-130.50723300000004,69.55247499999996],[-130.478607,69.57470700000005],[-130.392517,69.64582800000011],[-130.385559,69.65165700000011],[-130.36248799999998,69.67387400000001],[-130.36608899999987,69.68637100000001],[-130.2811279999999,69.70027199999998],[-130.03308099999998,69.73193400000008],[-129.691956,69.78442400000012],[-129.67251599999992,69.79248000000001],[-129.65307599999994,69.80053699999996],[-129.624146,69.81248500000004],[-129.60220300000003,69.81887799999998],[-129.41332999999992,69.83804299999997],[-129.31555199999997,69.84664900000007],[-129.24276699999984,69.84999099999999],[-129.17999299999997,69.849152],[-129.14862099999993,69.84999099999999],[-129.09942599999994,69.85887100000002],[-129.05889899999988,69.87387100000001],[-129.04196199999996,69.88360600000004],[-129.027222,69.89526400000011],[-129.01501499999995,69.90832500000005],[-129.00058,69.933044],[-128.98831199999995,69.94609100000002],[-128.97360200000003,69.95748900000001],[-128.96527100000003,69.96249400000005],[-128.955261,69.96638500000012],[-128.94415300000003,69.96943700000008],[-128.93194600000004,69.97164900000013],[-128.90084799999994,69.97192400000012],[-128.88723799999997,69.96887200000003],[-128.864716,69.96165500000012],[-128.8561099999999,69.95776400000005],[-128.85470599999996,69.95471199999992],[-128.93444799999992,69.84414699999996],[-128.9466549999999,69.84193400000004],[-128.96417199999996,69.843323],[-129.03805499999999,69.8519290000001],[-129.08248899999995,69.85054000000014],[-129.1097109999999,69.84776300000004],[-129.134186,69.843323],[-129.14529399999998,69.84027100000009],[-129.15612799999997,69.836929],[-129.163635,69.83137499999998],[-129.169464,69.82470699999999],[-129.16027799999995,69.71581999999995],[-129.15390000000002,69.70027199999998],[-129.14999399999994,69.69552600000003],[-129.141388,69.69164999999998],[-129.1302799999999,69.68803400000007],[-128.97747800000002,69.67469800000015],[-128.96304299999997,69.67526200000009],[-128.92501799999997,69.68081699999999],[-128.786133,69.76081800000009],[-128.640015,69.84304800000001],[-128.544739,69.885269],[-128.4419559999999,69.921921],[-128.324158,69.94831800000009],[-128.31054700000004,69.958328],[-128.308624,70.0080410000001],[-128.31222499999996,70.01277200000004],[-128.349152,70.03915400000011],[-128.356384,70.04887400000001],[-128.36138900000003,70.05886800000002],[-128.36972000000003,70.09582500000005],[-128.36831699999988,70.10165400000005],[-128.361938,70.10832200000004],[-128.35333299999996,70.11303700000008],[-128.34304799999995,70.11692800000014],[-128.31054700000004,70.12692300000003],[-128.24414099999996,70.14637800000003],[-128.10916099999997,70.18220499999995],[-128.09414700000002,70.18248],[-128.05667099999994,70.17803999999995],[-128.01055899999994,70.17831400000011],[-127.99472000000003,70.17942800000009],[-127.96833799999996,70.18275499999999],[-127.84861799999999,70.20887800000014],[-127.61501299999992,70.2288670000001],[-127.58500699999996,70.22943100000003],[-127.54998799999998,70.22665400000011],[-127.51500699999985,70.22164900000007],[-127.51750199999998,70.22554000000014],[-127.55082700000003,70.23637400000001],[-127.578056,70.242752],[-127.61305199999987,70.24775700000004],[-127.71665999999999,70.25972000000007],[-127.73166700000002,70.26138299999997],[-127.79194599999994,70.25999500000006],[-127.85833699999995,70.26304600000009],[-127.87581599999987,70.2644350000001],[-128.02835099999993,70.28637700000013],[-128.03695700000003,70.29054300000007],[-128.06664999999987,70.30720500000007],[-128.0761109999999,70.34359700000005],[-128.07843000000003,70.3464360000001],[-128.07144199999988,70.34826700000008],[-128.0616149999999,70.34792300000004],[-128.05343599999998,70.34609200000006],[-128.04661599999986,70.3439330000001],[-128.02711499999998,70.34076699999997],[-127.98889200000002,70.34582499999999],[-127.97250399999996,70.34526100000005],[-127.96000699999996,70.34748800000011],[-127.94860799999998,70.35054000000002],[-127.94082600000002,70.35609400000004],[-127.90194699999995,70.39332600000006],[-127.91555800000003,70.39665200000007],[-127.93195300000002,70.39694200000008],[-127.95417799999996,70.39387499999998],[-127.97693600000002,70.38777200000004],[-127.987213,70.38388099999997],[-128.02166699999998,70.37469500000003],[-128.06500199999994,70.37731200000002],[-128.13833599999992,70.37598400000013],[-128.15183999999994,70.38031000000012],[-128.15933199999995,70.38548300000002],[-128.19665499999996,70.39193700000004],[-128.19888300000002,70.40248100000008],[-128.19055200000003,70.43664600000005],[-128.17749000000003,70.46081500000014],[-128.160553,70.49136400000003],[-128.15249600000004,70.503601],[-128.13583399999993,70.52304100000015],[-128.006958,70.588593],[-127.99665799999997,70.59054600000013],[-127.97138999999999,70.58387800000014],[-127.90360999999996,70.56248500000004],[-127.83556399999998,70.54081700000012],[-127.68028300000003,70.48609899999997],[-127.51583900000003,70.42608600000005],[-127.42859599999991,70.39332600000006],[-127.27471899999995,70.32609600000006],[-127.24889399999995,70.31414800000005],[-127.18831599999999,70.28054800000012],[-127.173607,70.27221700000007],[-127.125,70.23719800000015],[-127.07640100000003,70.19636500000007],[-127.05499299999997,70.17803999999995],[-127.03443899999996,70.14888000000008],[-126.89334099999996,70.00888099999997],[-126.87888299999997,70.00054899999998],[-126.81276700000001,69.91053799999997],[-126.81194299999993,69.90525800000012],[-126.80526700000001,69.89553800000004],[-126.74388099999999,69.81387300000011],[-126.714722,69.7752690000001],[-126.70584099999996,69.76609800000011],[-126.69999699999994,69.76138300000008],[-126.6808319999999,69.74803199999997],[-126.67250100000001,69.74386600000008],[-126.62053699999996,69.71998600000006],[-126.60166899999996,69.71247900000014],[-126.45944199999997,69.64414999999997],[-126.29055799999998,69.55859400000003],[-126.26777599999997,69.54081700000012],[-126.26722699999993,69.53553799999997],[-126.25583599999999,69.52665700000006],[-126.11221299999994,69.46943699999997],[-126.08860800000002,69.46249399999999],[-126.0497279999999,69.45277400000009],[-126.03666699999997,69.44970699999999],[-125.98889199999996,69.430542],[-125.96806299999997,69.42303500000008],[-125.95749699999999,69.41943400000002],[-125.910553,69.40554800000007],[-125.88474300000001,69.39915500000006],[-125.839722,69.38916],[-125.55110200000001,69.33718900000008],[-125.42639200000002,69.31218000000013],[-125.41528299999987,69.31301900000005],[-125.37249800000001,69.33580000000012],[-125.36554699999999,69.34246800000005],[-125.39083900000003,69.37051399999996],[-125.40110800000002,69.37413000000004],[-125.37748699999997,69.39608799999996],[-125.21000699999996,69.381912],[-125.16528299999999,69.38163800000007],[-125.14167800000001,69.38638300000008],[-125.13249200000001,69.39109800000011],[-125.12554899999998,69.39749100000006],[-125.11193800000001,69.41581700000006],[-125.089447,69.44970699999999],[-125.11277799999999,69.46415700000011],[-125.12304699999993,69.46803299999999],[-125.462784,69.45246900000006],[-125.53056300000003,69.43524200000007],[-125.609444,69.41525300000012],[-125.62249799999995,69.41859399999998],[-125.61805700000002,69.42442299999999],[-125.57805599999995,69.47164900000001],[-125.48832700000003,69.50749200000007],[-125.47721899999993,69.510269],[-125.46472199999988,69.5122070000001],[-125.449997,69.51249700000011],[-125.30695300000002,69.49998499999998],[-125.14723200000003,69.48551900000012],[-125.13166799999993,69.48469499999999],[-125.11805699999996,69.48579399999994],[-125.12082700000002,69.49079899999998],[-125.13137799999993,69.49441500000006],[-125.18554699999987,69.50720200000006],[-125.21640000000002,69.51303100000007],[-125.25499699999995,69.52302600000002],[-125.265556,69.52691700000008],[-125.41000399999996,69.62803600000007],[-125.41306299999997,69.6330410000001],[-125.41361999999992,69.63832100000013],[-125.41166699999991,69.64387499999998],[-125.37805200000003,69.67858900000004],[-125.36554699999999,69.69026200000008],[-125.35527000000002,69.69413800000012],[-125.079453,69.74275200000005],[-125.06555200000003,69.74359100000004],[-125.04972800000002,69.74304200000012],[-125.016953,69.74052400000011],[-125,69.73819000000009],[-124.98581699999994,69.734711],[-124.97528099999994,69.73082000000011],[-124.96749899999998,69.72692900000004],[-124.93554699999999,69.678314],[-124.92500299999995,69.64471400000014],[-124.90638699999994,69.65387000000004],[-124.88166799999999,69.67053200000004],[-124.82195300000001,69.71499599999999],[-124.82972699999999,69.71914700000008],[-124.86165599999993,69.73580900000007],[-124.88555899999994,69.74803199999997],[-124.89750700000002,69.75054900000003],[-125.01418299999995,69.75053400000002],[-125.22805799999998,69.75914000000012],[-125.241379,69.76025400000009],[-125.25890399999992,69.78410300000002],[-125.27639799999997,69.80824300000006],[-125.225281,69.83967600000005],[-125.20638999999994,69.84912099999997],[-125.19611399999997,69.853027],[-125.18443299999996,69.85580400000009],[-125.16750300000001,69.85414099999997],[-125.16194199999995,69.84970099999998],[-125.15722700000003,69.82356300000004],[-125.15666199999998,69.81828300000012],[-125.170837,69.80549600000012],[-125.170547,69.80021699999998],[-125.165009,69.79550200000011],[-125.15055799999999,69.793564],[-125.05666399999996,69.79524200000009],[-125.03222700000003,69.81720000000007],[-125.00945300000001,69.84552000000008],[-124.94748700000002,69.91053799999997],[-124.94027699999987,69.91693099999998],[-124.89334100000002,69.94026200000002],[-124.76444999999995,69.97082499999999],[-124.79527299999995,70.00888099999997],[-124.82695000000001,70.012497],[-124.88694799999996,70.011932],[-124.99027999999998,70.00610400000005],[-125.025284,69.99800099999999],[-125.04695100000004,69.98999000000009],[-125.08640299999996,69.96853599999992],[-125.10722399999997,69.95352200000008],[-125.10759699999994,69.9479750000001],[-125.11138899999997,69.9419400000001],[-125.123894,69.93995699999999],[-125.19082600000002,69.93243399999994],[-125.20667299999991,69.9332280000001],[-125.21721599999995,69.93690500000008],[-125.21777299999997,69.94233700000007],[-125.2022169999999,69.99858100000006],[-125.19748700000002,70.00450100000012],[-125.18831599999999,70.0090330000001],[-125.016953,70.0762180000001],[-125,70.07998700000002],[-124.98972300000003,70.078598],[-124.98166700000002,70.07443200000012],[-124.97556299999991,70.06469700000002],[-124.97528099999994,70.05941800000005],[-124.98194899999999,70.04776000000004],[-124.98665599999998,70.04165599999999],[-124.99610899999999,70.036926],[-124.99768799999998,70.036926],[-125,70.036926],[-125.03999299999992,70.02906800000011],[-125.04804999999999,70.02304100000009],[-125.04527300000001,70.01799000000011],[-125.03443900000002,70.01393100000001],[-125.01999699999993,70.01199300000007],[-124.90139799999997,70.02137800000014],[-124.86332699999997,70.02720600000009],[-124.85527000000002,70.03054800000001],[-124.86972000000003,70.032761],[-124.93916299999995,70.02748100000008],[-124.95500199999998,70.02832000000006],[-124.95694699999996,70.03221100000013],[-124.93916299999995,70.04248000000013],[-124.92859599999997,70.04609700000009],[-124.81416300000001,70.061646],[-124.714447,70.06915300000014],[-124.67527799999993,70.07193000000007],[-124.64527900000002,70.07193000000007],[-124.63474300000001,70.068329],[-124.63417099999992,70.05775499999993],[-124.60333300000002,70.01971400000014],[-124.59777799999995,70.01527400000009],[-124.58473199999992,70.011932],[-124.56861899999996,70.01110800000004],[-124.55583199999995,70.01304600000014],[-124.45754999999997,70.03570600000012],[-124.45172100000002,70.03837600000003],[-124.44672400000002,70.0417020000001],[-124.423607,70.05636600000014],[-124.44138299999997,70.07609600000012],[-124.449432,70.08027600000014],[-124.506958,70.10026600000015],[-124.51999699999999,70.10386700000004],[-124.54888899999997,70.10998499999994],[-124.58556399999992,70.11526500000002],[-124.59944199999995,70.11415100000005],[-124.62053700000001,70.10664400000007],[-124.63221699999997,70.10386700000004],[-124.68138099999999,70.09443699999997],[-124.71972699999998,70.08859300000012],[-124.735817,70.0894320000001],[-124.73889200000002,70.09443699999997],[-124.75195299999996,70.116379],[-124.75250199999999,70.121643],[-124.74388099999999,70.12719700000014],[-124.734444,70.13192700000002],[-124.70472699999993,70.14498900000001],[-124.69415299999997,70.14860500000009],[-124.68028299999997,70.14971900000006],[-124.43611099999998,70.15109300000006],[-124.391388,70.13415500000013],[-124.35861199999988,70.068604],[-124.36945299999996,70.034988],[-124.37193300000001,70.02943400000004],[-124.38394199999993,70.01776100000001],[-124.41776999999996,69.98942599999998],[-124.42610199999996,69.98387100000008],[-124.45944199999991,69.95637500000004],[-124.42971799999992,69.84942599999994],[-124.44249000000002,69.832764],[-124.45722999999998,69.81971699999997],[-124.47972099999998,69.8035890000001],[-124.50167799999991,69.78442400000012],[-124.50361599999997,69.73082000000011],[-124.5005569999999,69.72581500000007],[-124.49526999999995,69.72137500000008],[-124.487503,69.71720900000014],[-124.45916699999998,69.71081500000008],[-124.36138900000003,69.70109600000012],[-124.29499800000002,69.69525100000004],[-124.28111299999995,69.69609100000008],[-124.26862299999993,69.69802900000002],[-124.2433319999999,69.71470599999998],[-124.23388699999998,69.71914700000008],[-124.21305799999993,69.72665400000005],[-124.20140099999998,69.72943099999992],[-124.1875,69.73054500000012],[-124.06973299999987,69.72360200000008],[-124.04083300000002,69.70138500000002],[-124.05526700000001,69.67053200000004],[-124.21193699999998,69.58638000000008],[-124.24054699999994,69.55026200000003],[-124.24999999999994,69.54553199999998],[-124.28028899999998,69.53360000000004],[-124.33444199999997,69.51693699999998],[-124.37777699999992,69.49693300000001],[-124.39527899999996,69.4869230000001],[-124.51888999999994,69.40415999999993],[-124.51390099999998,69.399429],[-124.48000300000001,69.37803600000007],[-124.47222899999991,69.37414600000011],[-124.44666299999994,69.36720300000013],[-124.32584399999996,69.35192900000004],[-124.26363399999997,69.34860200000008],[-124.21888699999994,69.34776299999993],[-124.16194200000001,69.34915200000012],[-124.12026999999995,69.35137900000001],[-124.09528399999999,69.35498000000007],[-124.01640299999997,69.3791500000001],[-123.962219,69.38304099999993],[-123.83138999999994,69.38888500000013],[-123.81696299999999,69.38888500000013],[-123.73055999999997,69.37747200000013],[-123.702789,69.37109400000003],[-123.69776899999988,69.366379],[-123.69748699999997,69.36109900000008],[-123.69248999999996,69.35664400000007],[-123.67999299999991,69.35331700000012],[-123.66639700000002,69.3541560000001],[-123.502792,69.37719700000014],[-123.47778299999993,69.38108800000003],[-123.46611000000001,69.38388100000003],[-123.41915899999998,69.40443400000004],[-123.40750100000002,69.4160920000001],[-123.43276999999995,69.42303500000008],[-123.44027699999998,69.42720000000008],[-123.45084399999996,69.44693000000007],[-123.45084399999996,69.45220900000004],[-123.44833399999993,69.45776399999994],[-123.443329,69.46388200000007],[-123.43611099999998,69.47026100000011],[-123.42859599999991,69.47637900000007],[-123.39998599999996,69.49026500000008],[-123.36527999999998,69.49832200000003],[-123.33999599999999,69.5022130000001],[-123.30110200000001,69.50665300000009],[-123.27306399999998,69.50776700000011],[-123.26139799999999,69.50499000000002],[-123.26287799999994,69.50026700000001],[-123.25723299999999,69.49609400000008],[-123.19275699999997,69.490814],[-123.17999299999991,69.49247700000012],[-123.16861,69.4952550000001],[-123.16332999999992,69.50138900000013],[-123.13166799999999,69.559708],[-123.12666300000001,69.57110599999999],[-123.09638999999999,69.67053200000004],[-123.09612299999998,69.68637100000001],[-123.10637700000001,69.74304200000012],[-123.10888699999998,69.74775699999992],[-123.11665299999993,69.75221300000004],[-123.10527000000002,69.77915999999999],[-123.01583900000003,69.81832900000006],[-122.97083999999995,69.830826],[-122.95916699999992,69.8336030000001],[-122.943329,69.832764],[-122.90499899999998,69.82222000000013],[-122.876938,69.81025700000009],[-122.85388199999994,69.80304000000012],[-122.82584400000002,69.79637100000008],[-122.80803699999996,69.79359399999998],[-122.79332699999992,69.79359399999998],[-122.779449,69.79470799999996],[-122.766663,69.79637100000008],[-122.754997,69.79914900000006],[-122.74610899999999,69.80442800000003],[-122.66443599999997,69.81805400000002],[-122.61554699999999,69.81219500000003],[-122.58833300000003,69.80748],[-122.47778299999999,69.80276500000014],[-122.45805399999995,69.80247500000013],[-122.24333200000001,69.80220000000008],[-122.12777699999992,69.80247500000013],[-122.06221,69.813309],[-122.04415899999998,69.81359900000001],[-121.89639299999999,69.80554200000006],[-121.71916199999993,69.79582199999993],[-121.68388400000003,69.79359399999998],[-121.44304699999998,69.76554900000002],[-121.41639700000002,69.76081800000009],[-121.38054699999992,69.75221300000004],[-121.33332799999994,69.74081400000011],[-121.28611799999999,69.7291560000001],[-121.18305999999995,69.70248400000003],[-121.12027,69.6827550000001],[-121.08667000000003,69.67359899999997],[-121.035553,69.66331500000013],[-121.00890400000003,69.6583250000001],[-120.93415800000002,69.64860499999998],[-120.88110399999994,69.63888500000007],[-120.82556199999999,69.62359600000002],[-120.79638699999992,69.61303699999996],[-120.760559,69.5983280000001],[-120.73999000000003,69.5852660000001],[-120.73528299999992,69.58027600000003],[-120.72860700000001,69.57582100000002],[-120.70111099999997,69.55859400000003],[-120.67859599999991,69.54609700000003],[-120.61609599999997,69.52026400000005],[-120.39334100000002,69.43969700000008],[-120.27528399999994,69.40415999999993],[-120.23166700000002,69.39166299999994],[-119.98222399999986,69.34471100000002],[-119.93499800000001,69.33970599999998],[-119.91776999999996,69.33831800000007],[-119.63527699999997,69.315811],[-119.46140300000002,69.303314],[-119.33500700000002,69.3019260000001],[-119.31582599999996,69.30108600000005],[-119.23000300000001,69.29443400000014],[-118.94082600000002,69.25943000000007],[-118.85555999999997,69.25248700000009],[-118.84056099999992,69.25054899999998],[-118.79998799999993,69.24331700000005],[-118.693604,69.22360200000003],[-118.65527299999997,69.21582000000006],[-118.64472999999998,69.21249400000005],[-118.63639799999993,69.20887799999997],[-118.58168,69.18026700000007],[-118.55248999999998,69.16360500000008],[-118.53999299999998,69.15498400000013],[-118.502228,69.13472000000002],[-118.48554999999999,69.12692300000009],[-118.45777900000002,69.11747700000012],[-118.432503,69.11219800000009],[-118.18611099999998,69.06387300000011],[-118.08167999999995,69.03137199999998],[-118.035553,69.01971400000014],[-118.010559,69.01443499999999],[-117.87053700000001,68.98553500000014],[-117.83693700000003,68.982483],[-117.74221799999998,68.97804300000001],[-117.63390400000003,68.97360200000008],[-117.59612300000003,68.97164900000013],[-117.5625,68.96859700000005],[-117.41583299999996,68.953598],[-117.26917300000002,68.91526800000003],[-117.19110099999995,68.89387499999992],[-117.15387699999997,68.88554400000004],[-117.13667299999997,68.88554400000004],[-116.978882,68.89999399999999],[-116.96639999999996,68.90220600000004],[-116.96056399999992,68.90721100000007],[-116.93907899999994,68.91100300000011],[-116.88667299999992,68.90887500000008],[-116.74445299999996,68.880539],[-116.515289,68.8580320000001],[-116.50029,68.85720800000013],[-116.43611099999998,68.85859700000009],[-116.42054699999994,68.85914600000007],[-116.41111799999999,68.86276199999992],[-116.40666199999998,68.86859099999992],[-116.40943899999996,68.87997400000012],[-116.39862099999999,68.88275100000004],[-116.38137799999998,68.88247700000011],[-116.36472300000003,68.88081399999999],[-116.34028599999994,68.87525900000009],[-116.285553,68.85971100000012],[-116.22721899999993,68.83915700000011],[-116.22138999999999,68.83442700000012],[-116.21362299999998,68.83055100000001],[-116.12304699999993,68.81832900000006],[-116.10637700000001,68.81666600000011],[-115.99388099999999,68.80664100000001],[-115.96000699999996,68.80470300000007],[-115.94915800000001,68.80748],[-115.94138299999997,68.81192000000004],[-115.94471699999997,68.81694000000005],[-115.95249899999993,68.82083100000011],[-116.12193299999996,68.87248199999999],[-116.31639099999995,68.94747899999993],[-116.32417299999992,68.95166],[-116.33000199999992,68.95610000000005],[-116.325287,68.96192900000005],[-116.31610099999995,68.96554600000002],[-116.30526699999996,68.96859700000005],[-116.26139799999987,68.97998000000007],[-116.239441,68.98553500000014],[-116.20500199999987,68.98498500000011],[-116.19027699999998,68.98275800000005],[-116.068893,68.96054100000015],[-116.00750700000003,68.94636500000013],[-115.96833799999996,68.938583],[-115.88417099999998,68.92469800000009],[-115.86749299999991,68.92275999999998],[-115.77806099999987,68.93637100000012],[-115.76695299999994,68.93914800000005],[-115.77500900000001,68.94303900000011],[-115.80943299999996,68.95220899999998],[-115.833328,68.99247700000001],[-115.59306300000003,68.97164900000013],[-115.44638099999992,68.93775900000003],[-115.06471299999993,68.86747699999995],[-115.05055199999993,68.86886600000014],[-115.03500400000001,68.86914099999996],[-115.01640299999997,68.868042],[-114.98999000000003,68.86276199999992],[-114.97805800000003,68.85914600000007],[-114.82167099999998,68.80970799999994],[-114.79194599999994,68.79942300000005],[-114.77916699999992,68.77915999999999],[-114.77055399999995,68.76944000000009],[-114.74916100000002,68.75138900000007],[-114.729446,68.74443100000013],[-114.71528599999999,68.74220300000013],[-114.69666299999994,68.740814],[-114.66555799999998,68.7416530000001],[-114.57833899999997,68.72804300000007],[-114.54250300000001,68.71943699999997],[-114.44833399999999,68.68969700000002],[-114.44055200000003,68.68580599999996],[-114.46028100000001,68.6705320000001],[-114.46528599999999,68.66442899999993],[-114.46221899999995,68.65942400000006],[-114.45667300000002,68.65470900000003],[-114.40471600000001,68.61499000000015],[-114.39499699999993,68.61137400000007],[-114.30444299999988,68.58692900000005],[-114.23361199999994,68.56944300000009],[-114.12165799999997,68.51748700000002],[-114.10665899999992,68.50943000000007],[-114.08889799999997,68.49636800000002],[-114.07055699999995,68.47747800000008],[-114.064438,68.46720900000003],[-114.06054699999993,68.45665000000002],[-114.01112399999994,68.25027500000004],[-114.01390100000003,68.24498],[-114.02333099999998,68.24136400000009],[-114.03582799999998,68.23942599999998],[-114.28806299999997,68.22886699999992],[-114.32000700000003,68.22915600000005],[-114.33805799999993,68.23054500000006],[-114.35166900000002,68.23359700000015],[-114.37053700000001,68.24054000000012],[-114.37805199999997,68.24443100000002],[-114.38305700000001,68.24887100000007],[-114.390556,68.25305200000014],[-114.41166699999997,68.25943000000007],[-114.42555199999998,68.261932],[-114.44167299999987,68.26361099999997],[-114.47361799999987,68.26388500000013],[-114.70249899999999,68.25027500000004],[-114.75527999999997,68.18969700000014],[-114.76471699999996,68.18609600000008],[-114.861107,68.153595],[-114.87193300000001,68.15109300000012],[-114.89639299999999,68.14694200000002],[-114.92971799999992,68.14776599999999],[-114.97749299999992,68.15331999999995],[-115.00750700000003,68.15721100000002],[-115.076683,68.16886900000009],[-115.17054699999994,68.18054200000012],[-115.22501399999993,68.18414299999995],[-115.23721299999988,68.18220500000001],[-115.24194299999999,68.176376],[-115.24388099999993,68.0413670000001],[-115.24054699999994,68.03637700000007],[-115.23528299999998,68.03166200000004],[-115.220551,68.02388000000008],[-115.204453,68.02192700000012],[-115.17138699999998,68.02110299999998],[-115.15638699999994,68.02165200000013],[-115.12526699999995,68.020264],[-115.11389200000002,68.01748700000013],[-115.11054999999999,68.01220700000005],[-115.11665299999999,68.00721700000003],[-115.12581599999999,68.00360100000012],[-115.20472699999993,67.97804300000001],[-115.216949,67.976089],[-115.34221599999995,67.95803799999999],[-115.50334199999986,67.93441800000005],[-115.52749599999999,67.93026700000013],[-115.53639199999998,67.92665100000005],[-115.5425029999999,67.92164600000001],[-115.53694200000001,67.90525799999995],[-115.53388999999993,67.89999399999999],[-115.52834299999995,67.89553800000004],[-115.521118,67.89166300000011],[-115.50723299999993,67.8894350000001],[-115.281387,67.86637900000011],[-115.27610800000002,67.86164900000006],[-115.20028699999995,67.82193000000012],[-115.19082599999996,67.81832900000006],[-115.11361699999998,67.79859900000008],[-115.1036069999999,67.79664600000012],[-115.02887699999985,67.78665200000012],[-115.01251200000002,67.78637700000013],[-114.99916099999996,67.7874910000001],[-114.93611099999998,67.79553199999998],[-114.88667299999997,67.80276499999997],[-114.84916699999991,67.80775500000004],[-114.80999800000001,67.81219500000003],[-114.78307299999989,67.81442300000003],[-114.75334199999992,67.81498699999997],[-114.73693799999995,67.81469700000014],[-114.718887,67.81330900000006],[-114.70749699999999,67.81053199999997],[-114.6866609999999,67.8041530000001],[-114.67722299999997,67.80081200000006],[-114.65527299999997,67.78887900000001],[-114.64499699999999,67.77970900000014],[-114.637787,67.77554300000003],[-114.29778299999992,67.7185970000001],[-114.28362300000003,67.71748400000001],[-114.27139299999999,67.71943699999997],[-114.25029,67.72470099999998],[-114.24109599999991,67.728317],[-114.22000099999997,67.73387100000002],[-114.19583099999994,67.73776200000009],[-114.1808319999999,67.73803700000008],[-114.14835399999993,67.7369230000001],[-114.11472300000003,67.73387100000002],[-113.99694799999992,67.72303800000003],[-113.98332199999999,67.72053500000004],[-113.94943199999994,67.71165500000001],[-113.89250199999992,67.69693000000007],[-113.84584000000001,67.69135999999997],[-113.76862299999999,67.69108600000004],[-113.70889299999999,67.69192500000003],[-113.55082699999997,67.69802900000008],[-113.25583599999999,67.70443699999998],[-113.24082899999996,67.70443699999998],[-113.20694700000001,67.70248400000008],[-113.17804699999988,67.69802900000008],[-113.15556300000003,67.69220000000001],[-113.11916399999996,67.67804000000012],[-113.10777300000001,67.67498800000004],[-113.06777999999997,67.66748000000001],[-113.04998799999993,67.6660920000001],[-112.965012,67.66970800000013],[-112.73972300000003,67.66943400000002],[-112.3958439999999,67.67915300000004],[-112.370003,67.68193100000002],[-112.348343,67.68719499999997],[-112.34056099999998,67.69135999999997],[-112.33361799999989,67.69636500000001],[-112.18331899999993,67.72776800000008],[-111.912781,67.75416600000005],[-111.88305700000001,67.75443999999999],[-111.79972799999996,67.75082400000008],[-111.66000399999996,67.73332200000004],[-111.57277699999992,67.74443100000013],[-111.45861799999989,67.76304600000009],[-111.3708269999999,67.78109700000005],[-111.32250999999991,67.80693100000008],[-111.31276699999995,67.81053199999997],[-111.29083299999996,67.81553600000007],[-111.200287,67.83415200000013],[-111.17582699999991,67.83749400000005],[-111.15943900000002,67.83665500000006],[-111.14835399999998,67.83360299999998],[-111.14388999999994,67.82887299999993],[-111.146118,67.82276900000011],[-111.12082700000002,67.78082300000011],[-111.03443899999996,67.76416000000006],[-111.01834100000002,67.76332100000008],[-111.00583599999999,67.76499899999999],[-110.84056099999998,67.80026200000003],[-110.83222999999998,67.80442800000009],[-110.80972300000002,67.81860400000011],[-110.78859699999998,67.83360299999998],[-110.78278399999994,67.83943199999999],[-110.75890400000003,67.85276799999997],[-110.74221799999992,67.86109900000002],[-110.73249800000002,67.86442599999998],[-110.41443600000002,67.94775400000015],[-110.33999599999999,67.96554600000002],[-110.1991579999999,67.97221400000001],[-110.17999299999991,67.99443100000008],[-110.1725009999999,67.99942000000004],[-110.162781,68.00277699999998],[-110.15167200000002,68.00526400000007],[-110.13054699999998,68.00804099999999],[-110.11694299999994,68.00888100000003],[-110.08389299999999,68.00694300000009],[-110.07084699999996,68.004166],[-110.04888900000003,67.99775699999992],[-110.001106,67.97970599999996],[-109.979446,67.96748399999996],[-109.97083999999995,67.95803799999999],[-109.96888699999994,67.95304900000002],[-109.96749899999992,67.94136000000015],[-109.97028399999999,67.92970300000002],[-109.97749299999987,67.91137700000002],[-109.99166899999994,67.89137300000004],[-110.001106,67.87248200000005],[-110.00361599999991,67.86637900000011],[-110.00361599999991,67.86053500000008],[-109.99749799999995,67.85081500000001],[-109.98889200000002,67.8413700000001],[-109.98249800000002,67.83720400000004],[-109.97389199999998,67.83360299999998],[-109.96305799999993,67.83027600000003],[-109.948036,67.83027600000003],[-109.93554699999999,67.83194000000003],[-109.92582699999997,67.8352660000001],[-109.91722099999998,67.839157],[-109.91251399999999,67.84582499999993],[-109.912216,67.85165399999994],[-109.91639700000002,67.85609399999998],[-109.94888300000002,67.87719700000008],[-109.95305599999995,67.88192700000008],[-109.94193999999993,67.88443000000007],[-109.89028899999994,67.879974],[-109.86193799999995,67.87498500000004],[-109.823059,67.8660890000001],[-109.81416299999995,67.86219800000003],[-109.80777,67.8580320000001],[-109.76722699999993,67.82777399999998],[-109.73082699999998,67.79193100000009],[-109.729172,67.76776100000012],[-109.73581699999994,67.74275200000011],[-109.74553700000001,67.7394260000001],[-109.75167799999991,67.73359700000009],[-109.74973299999994,67.72859200000005],[-109.7369379999999,67.72026100000011],[-109.72609699999998,67.71693399999998],[-109.55222300000003,67.68775900000014],[-109.53472899999991,67.68580600000001],[-109.52250700000002,67.68748499999998],[-109.51139799999999,67.68969700000008],[-109.50279199999994,67.69386299999996],[-109.48805199999993,67.70387300000004],[-109.37026999999995,67.72915599999999],[-109.25361599999997,67.73193400000014],[-109.21028100000001,67.73220800000007],[-109.159157,67.72747800000002],[-109.06582600000002,67.71415700000011],[-109.05972300000002,67.709991],[-109.01471699999996,67.6766510000001],[-109.00279199999994,67.66249100000005],[-108.91915899999992,67.53581200000013],[-108.921944,67.52970900000003],[-108.953888,67.51193200000012],[-108.96362299999998,67.5086060000001],[-108.99665800000002,67.50138900000002],[-109.00119000000001,67.5],[-109.00666799999993,67.49832200000009],[-109.01528899999994,67.49414100000001],[-109.02139299999999,67.48831199999995],[-109.02528399999994,67.4833220000001],[-109.01806599999998,67.46249400000005],[-109.002228,67.44358799999998],[-108.98554999999993,67.43609600000008],[-108.84999099999993,67.38859600000006],[-108.83112299999993,67.35359199999999],[-108.82501200000002,67.34942600000011],[-108.81276700000001,67.34887699999996],[-108.80416899999994,67.35276800000003],[-108.79666099999986,67.3577580000001],[-108.79055799999998,67.36360200000013],[-108.76611299999996,67.39637800000003],[-108.75834700000001,67.40914900000013],[-108.75583599999999,67.41526799999997],[-108.74445299999996,67.44552599999997],[-108.74109599999997,67.45721400000014],[-108.73638900000003,67.48109399999998],[-108.735817,67.48664900000006],[-108.734734,67.54775999999998],[-108.735817,67.55859400000003],[-108.73777799999993,67.56387300000006],[-108.73889200000002,67.5747070000001],[-108.73916599999995,67.59693899999996],[-108.73638900000003,67.60304300000001],[-108.73000299999995,67.60859700000003],[-108.714722,67.61914100000007],[-108.70612299999988,67.62330600000007],[-108.69611399999997,67.626373],[-108.67027299999995,67.6285860000001],[-108.65527299999991,67.62831100000011],[-108.62053700000001,67.62469500000003],[-108.6100009999999,67.62109399999997],[-108.58500700000002,67.60998500000011],[-108.57888799999989,67.60554500000006],[-108.516953,67.49748200000005],[-108.51139799999999,67.48748799999998],[-108.510559,67.47665400000011],[-108.51334399999996,67.4705350000001],[-108.52333099999993,67.45748900000001],[-108.52390300000002,67.45165999999995],[-108.52278100000001,67.44081100000011],[-108.49804699999993,67.36303700000008],[-108.49027999999998,67.35359199999999],[-108.48416099999997,67.34942600000011],[-108.47138999999993,67.34664900000001],[-108.458054,67.34721400000006],[-108.43720999999994,67.35276800000003],[-108.42971799999998,67.35748300000006],[-108.42471299999994,67.36415100000005],[-108.421944,67.3702550000001],[-108.42944299999999,67.37970000000013],[-108.43554699999999,67.38388100000003],[-108.439438,67.38859600000006],[-108.44275699999997,67.39915500000012],[-108.43998699999992,67.42747500000013],[-108.43472300000002,67.43165600000003],[-108.39388999999994,67.44358799999998],[-108.38166799999999,67.4452510000001],[-108.36694299999994,67.444977],[-108.34361299999989,67.43858299999994],[-108.33556399999998,67.4349820000001],[-108.321121,67.42692600000004],[-108.30750299999988,67.41304000000002],[-108.301941,67.40332000000012],[-108.30027799999999,67.39804100000015],[-108.29666099999997,67.39332600000012],[-108.28832999999997,67.38943500000005],[-108.13417099999992,67.32916300000005],[-108.06360599999988,67.305252],[-108.02583300000003,67.29637100000002],[-108.015289,67.293045],[-107.98554999999999,67.27192700000012],[-107.94471699999997,67.23637400000007],[-107.94082600000002,67.23165900000004],[-107.875,67.14082300000001],[-107.87526700000001,67.05276500000014],[-107.88054699999998,67.04832499999992],[-107.89362299999999,67.0477600000001],[-107.90499899999998,67.04971300000005],[-107.95028699999995,67.06219500000003],[-108.00834699999996,67.07748400000008],[-108.02084399999995,67.08055100000001],[-108.03666699999991,67.08166499999999],[-108.14862099999993,67.07666000000012],[-108.15722700000003,67.07276900000005],[-108.18916300000001,67.05497700000001],[-108.19304699999986,67.04971300000005],[-108.192207,67.03887899999995],[-108.19082600000002,67.03359999999998],[-108.19138299999992,67.02804600000002],[-108.19526699999994,67.0227660000001],[-108.20388799999995,67.01887500000004],[-108.21611000000001,67.01721199999992],[-108.23277300000001,67.01915000000008],[-108.24527,67.02221700000001],[-108.45028699999995,67.08332800000011],[-108.46056399999992,67.086929],[-108.495003,67.10220300000009],[-108.51722699999999,67.11387600000006],[-108.541382,67.13081399999999],[-108.55555700000002,67.13888500000007],[-108.58029199999999,67.15026899999998],[-108.59056099999998,67.153595],[-108.6063769999999,67.15470899999997],[-108.61971999999997,67.15387000000004],[-108.622772,67.14999399999994],[-108.53028899999993,67.04248000000001],[-108.52416999999997,67.03831500000001],[-108.51611300000002,67.03442399999994],[-108.50140399999998,67.03221100000002],[-108.491669,67.0352630000001],[-108.48554999999988,67.0410920000001],[-108.48500100000001,67.04664600000012],[-108.48665599999998,67.05192599999998],[-108.49054699999988,67.05664100000001],[-108.48944099999994,67.06776400000001],[-108.48194899999999,67.07276900000005],[-108.468887,67.07331800000003],[-108.45612299999999,67.0705410000001],[-108.44193999999999,67.06248500000004],[-108.39222699999993,67.02886999999998],[-108.35637700000001,67.00332600000013],[-108.34665699999994,66.99443100000008],[-108.33056599999998,66.9869230000001],[-108.31806899999998,66.98387100000014],[-108.28971899999993,66.97998000000007],[-108.25862099999995,66.97776800000003],[-108.22860700000001,66.97665400000005],[-108.19695300000001,66.97221400000001],[-108.16639700000002,66.9622040000001],[-108.14998600000001,66.95443699999998],[-108.11472299999997,66.92886400000003],[-107.98528299999998,66.82859800000011],[-107.94138299999997,66.78831500000007],[-107.93831599999999,66.77804600000007],[-107.93971299999993,66.76666300000005],[-107.94193999999999,66.74970999999994],[-107.94471699999997,66.7435910000001],[-107.94803599999995,66.73193399999997],[-107.949432,66.7205350000001],[-107.94583099999994,66.71582000000006],[-107.89444699999996,66.67164600000012],[-107.88276699999989,66.66331500000001],[-107.87082699999996,66.66249100000005],[-107.86444099999989,66.66832000000005],[-107.86389200000002,66.67387400000007],[-107.86776700000001,66.71138000000002],[-107.88474299999996,66.75082399999991],[-107.88834400000002,66.75555400000013],[-107.88194299999992,66.75915500000002],[-107.86776700000001,66.75888100000009],[-107.85333299999996,66.7563780000001],[-107.829453,66.74498000000011],[-107.81777999999997,66.73637400000001],[-107.76500699999997,66.68691999999999],[-107.72416699999991,66.62970000000013],[-107.64750699999996,66.5747070000001],[-107.62805199999997,66.56219499999997],[-107.60082999999997,66.54609700000009],[-107.56945799999994,66.53054800000001],[-107.55721999999997,66.52777100000009],[-107.43305999999995,66.45359800000011],[-107.2911069999999,66.36831699999999],[-107.26027699999986,66.35304300000007],[-107.24804699999993,66.34999099999999],[-107.23500100000001,66.34860200000014],[-107.22222899999997,66.349152],[-107.21140299999996,66.35137900000007],[-107.203056,66.35525499999994],[-107.196663,66.36080900000013],[-107.195831,66.36637900000005],[-107.19722000000002,66.371643],[-107.20056199999993,66.37637300000006],[-107.23554999999993,66.40748600000006],[-107.34221599999995,66.46165500000006],[-107.43888899999996,66.51304600000014],[-107.56220999999994,66.59136999999998],[-107.56582599999996,66.59610000000004],[-107.56861899999996,66.60664400000007],[-107.56777999999991,66.61219800000009],[-107.56916799999999,66.61747700000006],[-107.57055700000001,66.6224820000001],[-107.57417299999997,66.62747199999995],[-107.62416100000002,66.66081200000002],[-107.64943700000003,66.69386299999996],[-107.69387799999998,66.755829],[-107.74665800000002,66.92276000000004],[-107.68861399999997,66.97709700000013],[-107.63806199999999,67.02442900000005],[-107.66665599999993,67.06303400000002],[-107.66805999999985,67.06832900000006],[-107.66166699999997,67.07388300000002],[-107.65083299999992,67.076096],[-107.63612399999994,67.07388300000002],[-107.60777299999995,67.063309],[-107.58361799999994,67.05165099999999],[-107.52390300000002,67.02026400000005],[-107.516663,67.01054399999998],[-107.48388699999998,66.924149],[-107.48473399999995,66.91859399999993],[-107.49694799999997,66.91720600000002],[-107.57972699999988,66.91638200000006],[-107.59445199999999,66.91886899999997],[-107.60221899999988,66.92276000000004],[-107.608047,66.9269260000001],[-107.62332200000003,66.94026200000008],[-107.626938,66.94497700000011],[-107.632767,66.9494170000001],[-107.64083899999997,66.95304900000008],[-107.647064,66.94271100000003],[-107.65521999999999,66.94371000000007],[-107.66238399999997,66.94287900000006],[-107.66754900000001,66.94037600000007],[-107.67138699999998,66.93703500000004],[-107.670387,66.93386800000002],[-107.63527699999997,66.89221200000003],[-107.5702819999999,66.8377690000001],[-107.564438,66.83360299999998],[-107.51306199999993,66.82222000000002],[-107.42832900000002,66.80470300000013],[-107.41610699999995,66.80609100000004],[-107.40888999999993,66.81109600000008],[-107.39111299999996,66.8913730000001],[-107.39584400000001,66.90138200000013],[-107.422234,66.93969700000002],[-107.42944299999999,66.94914200000011],[-107.43888899999996,66.95832800000005],[-107.44471699999997,66.96249399999994],[-107.44387799999993,66.96804800000012],[-107.435272,66.97221400000001],[-107.421944,66.97276299999999],[-107.40611299999995,66.97137500000008],[-107.37943999999993,66.966095],[-107.35916099999992,66.959427],[-107.23388699999992,66.90220600000009],[-107.21806299999997,66.89471400000014],[-107.21028099999995,66.89082300000007],[-107.1875,66.87359600000002],[-107.15750099999991,66.84693900000013],[-107.15055799999999,66.83749400000005],[-107.14916999999991,66.83221400000002],[-107.137787,66.82360800000009],[-107.12554899999992,66.82054099999999],[-107.09472700000003,66.81832900000012],[-107.08361799999994,66.82054099999999],[-107.15527299999997,66.899719],[-107.203888,66.94470200000006],[-107.22666900000002,66.96165500000001],[-107.24027999999998,66.96998600000006],[-107.29750100000001,67.00193800000005],[-107.3052669999999,67.00582900000012],[-107.31139399999995,67.12719700000002],[-107.38806199999993,67.14444000000015],[-107.43083200000001,67.15832500000005],[-107.44915800000001,67.16554300000007],[-107.47332799999992,67.17692600000004],[-107.48137700000001,67.18081699999993],[-107.50306699999993,67.1927490000001],[-107.53250100000002,67.214157],[-107.64862099999993,67.359985],[-107.57694999999995,67.47554000000014],[-107.57389799999993,67.48165899999998],[-107.57528699999995,67.48692299999999],[-107.578888,67.49165299999999],[-107.58277899999996,67.49636800000002],[-107.58860799999991,67.50082399999997],[-107.71833800000002,67.57331800000009],[-107.74054699999994,67.58526599999993],[-107.77362099999999,67.60054000000002],[-107.81331599999999,67.61442600000004],[-107.84472700000003,67.62442000000004],[-107.89055599999989,67.64248700000007],[-107.96916199999998,67.6766510000001],[-107.98972300000003,67.68887300000011],[-107.99944299999999,67.69802900000008],[-108.006958,67.70748900000012],[-108.01334399999996,67.728317],[-108.01445000000001,67.73414600000001],[-108.015289,67.74498000000006],[-108.01390099999998,67.756104],[-108.00805699999995,67.76832600000012],[-107.99249299999997,67.78804000000002],[-107.94833399999993,67.84109500000011],[-107.94193999999999,67.84693900000013],[-107.93415800000002,67.85165399999994],[-107.92278299999998,67.8538670000001],[-107.890289,67.85165399999994],[-107.87777699999992,67.85331700000006],[-107.85527000000002,67.85775799999999],[-107.75666799999993,67.88081400000004],[-107.71472199999994,67.89248700000007],[-107.70472699999993,67.89582800000011],[-107.674713,67.91609200000005],[-107.66166699999997,67.92747500000002],[-107.65110800000002,67.94053599999995],[-107.65499899999992,67.94525099999998],[-107.66555800000003,67.94859300000013],[-107.770508,67.96526300000005],[-107.81133999999992,67.97159600000003],[-107.910278,67.988586],[-107.91639699999996,67.99304200000006],[-107.91999800000002,67.99775699999992],[-107.89055599999989,68.08166499999999],[-107.88527699999997,68.08831800000013],[-107.87888299999997,68.09387200000015],[-107.86332699999997,68.10359200000005],[-107.85166899999996,68.1060940000001],[-107.837784,68.10443099999998],[-107.72112300000003,68.08276399999994],[-107.69943199999994,68.07582100000013],[-107.69360399999994,68.07165500000008],[-107.69776899999994,68.0663760000001],[-107.70667300000002,68.06248500000004],[-107.72721899999993,68.05609099999998],[-107.73860200000001,68.05386400000009],[-107.77250700000002,68.05693100000002],[-107.78778099999994,68.05720500000012],[-107.80027799999999,68.05581700000005],[-107.80943299999996,68.05165099999994],[-107.83332799999988,68.01304600000003],[-107.83389299999999,68.00721700000003],[-107.82778899999988,68.00305200000003],[-107.8038479999999,68.00426499999998],[-107.78733799999998,67.99759700000004],[-107.77900699999998,67.9967650000001],[-107.763847,67.99842800000005],[-107.75699599999996,67.99977100000012],[-107.75426500000003,68.00681299999997],[-107.73306300000002,68.020828],[-107.72501399999993,68.02581800000002],[-107.69027699999992,68.04248000000001],[-107.67999299999997,68.04582199999993],[-107.61028299999998,68.05859399999997],[-107.58583099999998,68.05998200000005],[-107.57084700000001,68.05970800000011],[-107.53806299999997,68.05748],[-107.45028699999989,68.04721100000012],[-107.38890100000003,68.04525799999999],[-107.36221299999994,68.04693600000013],[-107.34944200000001,68.04859900000002],[-107.32640099999998,68.05304000000012],[-107.28778099999994,68.06498700000009],[-107.25140399999998,68.080826],[-107.22638699999993,68.09443699999997],[-107.154449,68.12692300000009],[-107.141953,68.128311],[-107.11028299999998,68.12692300000009],[-107.10665899999998,68.12220800000006],[-107.11888099999987,68.08471700000007],[-106.96556099999998,68.11331200000012],[-106.95278899999988,68.11470000000003],[-106.85611,68.11692799999997],[-106.84111000000001,68.11637900000005],[-106.80194099999994,68.1974790000001],[-106.80943300000001,68.20721400000002],[-106.80610699999994,68.21304300000003],[-106.80027799999993,68.21748400000013],[-106.79110700000001,68.22137500000002],[-106.62748699999997,68.24664300000006],[-106.61444099999994,68.24803200000008],[-106.5994419999999,68.24748200000005],[-106.58860800000002,68.24414100000001],[-106.468613,68.19053600000012],[-106.45777900000002,68.176376],[-106.45417799999996,68.16081200000008],[-106.45056199999999,68.15582300000011],[-106.44471699999991,68.15165700000006],[-106.43195300000002,68.15304600000002],[-106.42138699999987,68.15609700000005],[-106.35056299999997,68.1791530000001],[-106.34472699999998,68.18331899999998],[-106.35056299999997,68.18775900000003],[-106.35888699999992,68.1916500000001],[-106.39277600000003,68.20166],[-106.420837,68.20721400000002],[-106.468887,68.21443199999999],[-106.48194899999993,68.21748400000013],[-106.48999000000003,68.22137500000002],[-106.49582699999996,68.22554000000002],[-106.49722300000002,68.23082000000005],[-106.46833799999996,68.32971199999997],[-106.46501199999994,68.33581500000014],[-106.45667299999991,68.34082000000001],[-106.44748700000002,68.34471100000007],[-106.42639200000002,68.35081500000007],[-106.25611900000001,68.3877720000001],[-106.24416400000001,68.38998400000014],[-106.21833800000002,68.39248700000013],[-106.203056,68.39221199999992],[-106.185272,68.38998400000014],[-106.17471299999994,68.38665800000012],[-106.16665599999999,68.38275099999998],[-106.1547159999999,68.37387100000012],[-105.79638699999998,68.42221100000012],[-105.79055799999998,68.41804500000006],[-105.78222699999998,68.41387899999995],[-105.76583900000003,68.41276600000009],[-105.75167799999991,68.41304000000002],[-105.73972300000003,68.41526799999997],[-105.73029300000002,68.41914400000002],[-105.723053,68.42469800000003],[-105.70111099999991,68.46971100000013],[-105.69721999999996,68.486649],[-105.69833399999993,68.49192800000003],[-105.70278899999994,68.50193800000011],[-105.71444699999995,68.51054400000004],[-105.74305700000002,68.56469700000014],[-105.724716,68.57415800000012],[-105.64499699999999,68.63388099999997],[-105.65083300000003,68.63804600000014],[-105.66639699999996,68.638596],[-105.902222,68.63526900000005],[-105.92832899999996,68.632477],[-106.02944899999994,68.61970499999995],[-106.041382,68.61747700000001],[-106.04972799999996,68.61276199999998],[-106.04750100000001,68.60220300000015],[-106.05332900000002,68.59582499999999],[-106.06416300000001,68.59275800000006],[-106.2077789999999,68.56776400000007],[-106.23638900000003,68.566666],[-106.37027,68.5452580000001],[-106.51083399999999,68.518326],[-106.54387700000001,68.51193200000012],[-106.62471,68.46748400000007],[-106.63166799999999,68.461929],[-106.62888299999992,68.45138500000013],[-106.62165799999997,68.44192500000003],[-106.61582899999996,68.43775900000014],[-106.59528399999994,68.42526199999998],[-106.58473200000003,68.42164600000012],[-106.57167099999992,68.41859399999998],[-106.55387899999994,68.41665600000005],[-106.52194199999997,68.41499299999992],[-106.50446299999999,68.41276600000009],[-106.493607,68.40942400000012],[-106.48777799999988,68.40498400000013],[-106.48055999999997,68.39553799999999],[-106.52722199999994,68.30081200000012],[-106.534157,68.29525799999993],[-106.54332699999998,68.29136700000004],[-106.556107,68.28997800000008],[-106.57277699999986,68.29109200000005],[-106.58444199999991,68.29332],[-106.59500099999997,68.29664600000007],[-106.60109699999998,68.30108600000005],[-106.6119379999999,68.31526200000008],[-106.6383439999999,68.34304800000012],[-106.64444700000001,68.34748799999994],[-106.77887699999997,68.40803499999998],[-106.78971899999999,68.41165200000012],[-106.80277999999993,68.41442899999998],[-107.01363400000002,68.36943100000008],[-107.02166699999998,68.36469999999997],[-107.02027899999996,68.359421],[-107.016663,68.35470599999996],[-107.01750199999998,68.34915199999995],[-107.03138699999994,68.33776899999998],[-107.13221699999991,68.2833250000001],[-107.24610899999999,68.26138300000002],[-107.25890400000003,68.25999500000012],[-107.26500699999997,68.26416000000012],[-107.274719,68.27331499999997],[-107.28611799999993,68.28749099999999],[-107.29611199999994,68.29664600000007],[-107.30194099999994,68.30081200000012],[-107.3272169999999,68.31248499999998],[-107.33805799999999,68.315811],[-107.54666099999992,68.34748799999994],[-107.56082200000003,68.34915199999995],[-107.81331599999999,68.34248400000001],[-107.82611099999997,68.341095],[-107.83640300000002,68.33804300000008],[-107.84973100000002,68.32638500000007],[-107.85500299999995,68.31999200000007],[-107.88527699999997,68.26887499999998],[-107.883621,68.26361099999997],[-107.879707,68.25888099999997],[-107.85417199999995,68.24748200000005],[-107.83029199999993,68.2410890000001],[-107.74194299999999,68.2169340000001],[-107.61332700000003,68.17858899999999],[-107.60249299999998,68.17526200000003],[-107.59861799999999,68.17053199999998],[-107.60305800000003,68.16526800000003],[-107.61582900000002,68.16387900000001],[-107.63221699999997,68.16499299999998],[-107.68998699999997,68.17442300000005],[-107.78639199999992,68.18386800000013],[-107.80027799999999,68.18331899999998],[-107.82584399999996,68.18054200000012],[-107.87193300000001,68.17137100000014],[-108.03388999999999,68.16859400000004],[-108.16139199999986,68.17275999999998],[-108.18694299999999,68.16998300000006],[-108.19695300000001,68.1666560000001],[-108.22028399999999,68.15220599999998],[-108.24944299999993,68.14166300000005],[-108.30055199999993,68.12580900000012],[-108.33222999999998,68.11720300000002],[-108.37026999999989,68.11276200000009],[-108.38555899999994,68.11303700000008],[-108.40306099999998,68.11499000000003],[-108.41388699999993,68.11831699999999],[-108.42250099999995,68.12220800000006],[-108.43277,68.13108800000009],[-108.43611099999987,68.14137300000004],[-108.43306000000001,68.14749099999995],[-108.42804699999994,68.15416000000005],[-108.40888999999999,68.16137700000013],[-108.39750700000002,68.16360500000008],[-108.36694299999994,68.16110200000008],[-108.36277799999993,68.15637200000009],[-108.36582899999996,68.15026899999998],[-108.37361099999993,68.14526400000011],[-108.37998999999996,68.13970899999998],[-108.37832599999996,68.13443000000001],[-108.36527999999993,68.13360600000004],[-108.34612299999998,68.14082300000001],[-108.33860800000002,68.14582800000005],[-108.33332799999994,68.15220599999998],[-108.33056599999998,68.15860000000004],[-108.32695000000001,68.17025800000005],[-108.32444800000002,68.19274900000005],[-108.32945299999989,68.208328],[-108.3958439999999,68.28997800000008],[-108.40222199999994,68.29414400000013],[-108.443604,68.30802900000003],[-108.46000700000002,68.309143],[-108.484444,68.30525199999994],[-108.504997,68.29887400000001],[-108.55999800000001,68.27554299999997],[-108.56500199999999,68.26887499999998],[-108.56806899999992,68.26277200000004],[-108.57444799999996,68.25721699999997],[-108.58444199999997,68.2538760000001],[-108.71556099999998,68.23136900000003],[-108.72944599999988,68.23082000000005],[-108.74610899999993,68.23193400000002],[-108.756958,68.2352600000001],[-108.765556,68.23887600000012],[-108.81527699999998,68.26220699999999],[-108.81916799999993,68.26666300000011],[-108.8141629999999,68.27331499999997],[-108.748894,68.33776899999998],[-108.74109599999997,68.34275800000012],[-108.71417199999996,68.35470599999996],[-108.70417799999996,68.35803199999998],[-108.69387799999993,68.36109899999991],[-108.670837,68.36581399999994],[-108.63999899999993,68.37553400000002],[-108.62082700000002,68.38275099999998],[-108.61193800000001,68.38665800000012],[-108.58112299999999,68.40637200000003],[-108.56667299999998,68.41693100000009],[-108.53443900000002,68.44552600000009],[-108.52916699999992,68.4522090000001],[-108.52278100000001,68.4580380000001],[-108.43167099999994,68.53831500000007],[-108.40416700000003,68.56025699999998],[-108.383331,68.57666],[-108.36888099999999,68.58720400000004],[-108.34528399999994,68.60192899999998],[-108.31416300000001,68.61137400000007],[-108.27916700000003,68.61831700000005],[-108.25195299999996,68.62052900000015],[-108.1702729999999,68.62664799999999],[-107.93331899999998,68.64027399999992],[-107.80499299999997,68.6455380000001],[-107.63834399999996,68.66554300000013],[-107.43167099999994,68.69053600000001],[-107.23137700000001,68.71887200000009],[-107.108337,68.74859600000013],[-106.96140300000002,68.78305100000006],[-106.93859899999995,68.78831500000001],[-106.82084700000001,68.81137100000007],[-106.79444899999993,68.81387299999994],[-106.765556,68.81498699999992],[-106.63500999999991,68.81832900000006],[-106.31555200000003,68.89276100000012],[-106.27250699999996,68.90470900000003],[-106.262787,68.90887500000008],[-106.25446299999993,68.91360500000013],[-106.24833699999988,68.91998300000006],[-106.24472000000003,68.926086],[-106.24360699999994,68.93165600000009],[-106.23998999999998,68.93775900000003],[-106.229172,68.940811],[-106.214722,68.94136000000009],[-106.20140100000003,68.94053600000012],[-106.14943699999998,68.93359400000003],[-106.08084099999996,68.91886900000009],[-105.81360599999988,68.88192700000008],[-105.79804999999999,68.87942500000003],[-105.77639799999997,68.87248199999999],[-105.71806300000003,68.84498599999995],[-105.48693800000001,68.72943099999998],[-105.475281,68.72053500000004],[-105.471657,68.71582000000001],[-105.47833300000002,68.69859299999996],[-105.48194899999999,68.69247400000012],[-105.4891659999999,68.68691999999993],[-105.498894,68.68304400000005],[-105.49944299999999,68.62136800000007],[-105.41443600000002,68.528595],[-105.380829,68.486649],[-105.40888999999999,68.49247700000012],[-105.42304999999999,68.49192800000003],[-105.43388400000003,68.4891510000001],[-105.44360399999994,68.48526000000004],[-105.52944899999994,68.45027200000004],[-105.53806299999991,68.44552600000009],[-105.54387700000001,68.43914799999999],[-105.54778299999998,68.43304400000011],[-105.54888900000003,68.42747500000013],[-105.54804999999999,68.42221100000012],[-105.54110699999995,68.41276600000009],[-105.53307299999994,68.40859999999998],[-105.51777600000003,68.40609699999999],[-105.41639700000002,68.40693700000008],[-105.39028899999988,68.40942400000012],[-105.34528399999999,68.38415500000013],[-105.34889199999992,68.37803600000012],[-105.350281,68.3724820000001],[-105.34472700000003,68.36804200000012],[-105.29499800000002,68.33915700000006],[-105.28694200000001,68.33526599999999],[-105.10082999999992,68.26609800000006],[-105.07305899999994,68.26026900000005],[-105.05555700000002,68.2580410000001],[-105.02639799999992,68.257767],[-105.00894900000003,68.26493800000003],[-105.00661500000001,68.26859999999994],[-105.00578300000001,68.27209499999992],[-105.00666799999993,68.27859500000005],[-105.01695299999994,68.28221100000013],[-105.02610800000002,68.30941800000005],[-104.88474300000001,68.33970599999998],[-104.86416600000001,68.33248900000007],[-104.848053,68.3247070000001],[-104.83917200000002,68.31553600000001],[-104.83583099999998,68.31080600000013],[-104.83416699999998,68.30026200000009],[-104.83944699999995,68.28858900000006],[-104.84584000000001,68.28221100000013],[-104.85305800000003,68.27665700000011],[-104.86277799999993,68.27276600000005],[-104.87332199999997,68.26971400000014],[-104.94554099999999,68.2580410000001],[-104.952789,68.25248700000009],[-104.95194999999995,68.24748200000005],[-104.94055200000003,68.23858600000011],[-104.924713,68.23054500000006],[-104.91443600000002,68.22720300000009],[-104.900284,68.22526600000009],[-104.88639799999999,68.22554000000002],[-104.87332199999997,68.22692899999998],[-104.79750100000001,68.24443100000002],[-104.73111,68.25027500000004],[-104.68776699999995,68.25027500000004],[-104.63999899999999,68.24693300000013],[-104.609734,68.24136400000009],[-104.59889199999998,68.232483],[-104.59722899999997,68.22221400000012],[-104.61277799999999,68.19802900000013],[-104.61888099999993,68.1916500000001],[-104.6324919999999,68.17942800000009],[-104.65471600000001,68.16276600000015],[-104.66722099999993,68.1499940000001],[-104.67027299999995,68.13859600000012],[-104.5922159999999,68.0836030000001],[-104.50778200000002,68.03581200000002],[-104.5,68.03193700000003],[-104.48638900000003,68.02998400000013],[-104.45722999999992,68.02970900000008],[-104.36694299999994,68.03414900000013],[-104.21472199999994,68.02415500000006],[-104.199997,68.02137800000003],[-104.16665599999993,68.01748700000013],[-104.12470999999994,68.01832600000006],[-104.11193800000001,68.01944000000003],[-104.06471299999998,68.02748099999997],[-104.01139799999999,68.04220600000008],[-103.99944299999999,68.04414400000002],[-103.98554999999999,68.04443400000002],[-103.97084000000001,68.04386900000003],[-103.94082600000002,68.03831500000001],[-103.92832900000002,68.03498800000006],[-103.89806399999998,68.02415500000006],[-103.883621,68.02137800000003],[-103.87082699999996,68.020264],[-103.84306300000003,68.020828],[-103.791382,68.0252690000001],[-103.76695299999994,68.02832000000006],[-103.55526700000001,68.05720500000012],[-103.54444899999987,68.05998200000005],[-103.53694200000001,68.06553600000007],[-103.53278399999999,68.07165500000008],[-103.53333299999991,68.07666000000012],[-103.53639199999998,68.08166499999999],[-103.54472399999997,68.09082000000001],[-103.55526700000001,68.09971599999994],[-103.55803699999996,68.10443099999998],[-103.55304699999999,68.10971100000006],[-103.52139299999999,68.13081399999999],[-103.50389099999995,68.14027400000003],[-103.49526999999995,68.14471400000008],[-103.46694899999994,68.15693699999991],[-103.45722999999998,68.16053799999997],[-103.42166099999997,68.1666560000001],[-103.40416700000003,68.16415400000005],[-103.38971700000002,68.16137700000013],[-103.38194299999992,68.15721100000002],[-103.36888099999999,68.14888000000013],[-103.34416199999993,68.12109400000008],[-103.34137699999991,68.11608900000004],[-103.34028599999988,68.10582],[-103.341949,68.10026599999998],[-103.37249799999995,68.06860400000005],[-103.36916399999996,68.01081800000003],[-103.36609599999997,68.00582900000006],[-103.25418100000002,67.966385],[-103.22084000000001,67.9622040000001],[-103.20612299999999,67.96138000000013],[-103.17832899999996,67.96192900000005],[-103.14943699999998,67.96138000000013],[-103.13694800000002,67.95803799999999],[-103.12943999999999,67.95387299999999],[-103.12416100000002,67.9497070000001],[-103.11277799999999,67.93026700000013],[-103.1052699999999,67.92608600000005],[-103.09306300000003,67.92303500000003],[-103.01471700000002,67.91360500000013],[-103.00083899999998,67.91387900000007],[-102.99082899999996,67.91748000000013],[-102.98222399999997,67.92221100000006],[-102.97250399999996,67.92581200000012],[-102.95944199999985,67.9269260000001],[-102.94972199999995,67.92330900000013],[-102.94444299999998,67.91886899999992],[-102.939438,67.9144290000001],[-102.921112,67.89637800000014],[-102.82972699999993,67.83194000000003],[-102.80027799999993,67.820831],[-102.686394,67.80470300000013],[-102.67054699999994,67.80304000000001],[-102.53611799999999,67.79525800000005],[-102.50446299999999,67.79193100000009],[-102.47083999999995,67.78692600000005],[-102.446663,67.78027300000008],[-102.39306599999992,67.76249700000011],[-102.33972199999994,67.74470500000007],[-102.251106,67.72526600000015],[-102.22444199999995,67.73387100000002],[-102.21556099999992,67.73831200000012],[-102.15139799999997,67.76554900000002],[-102.1416779999999,67.76915000000008],[-101.92610200000001,67.760269],[-101.7647169999999,67.72331200000013],[-101.671944,67.69164999999998],[-101.54250300000001,67.67942800000003],[-101.51500699999997,67.67942800000003],[-101.446663,67.73248300000012],[-101.43388400000003,67.73332200000004],[-101.10582699999992,67.74192800000014],[-101.09889199999998,67.73776200000009],[-101.01278699999995,67.74247700000012],[-100.99973299999999,67.74331699999999],[-100.92749000000003,67.75332599999996],[-100.90387699999991,67.75694299999992],[-100.89277600000003,67.75972000000002],[-100.811394,67.79470800000001],[-100.72028399999994,67.83442700000012],[-100.58167999999995,67.83415200000013],[-100.39555399999995,67.84748800000006],[-100.18415799999997,67.84304800000007],[-100.16832699999998,67.84109500000011],[-100.156387,67.83776900000004],[-100.14723200000003,67.82859800000011],[-100.135559,67.8252720000001],[-100.083618,67.81498699999997],[-99.82000699999992,67.79582199999999],[-99.618607,67.789154],[-99.60777299999995,67.79193100000009],[-99.58917200000002,67.80081200000006],[-99.577789,67.80331400000011],[-99.50056499999994,67.79971300000005],[-99.41221599999989,67.78831500000007],[-99.40306099999992,67.784424],[-99.39862099999999,67.77998399999996],[-99.39666699999998,67.7749940000001],[-99.387787,67.76582299999995],[-99.37832599999996,67.76193200000006],[-99.23611499999998,67.71360800000014],[-99.21055599999994,67.70694000000015],[-98.98693800000001,67.718323],[-98.81361399999997,67.74192800000014],[-98.52888499999989,67.77748100000002],[-98.38583399999999,67.78581200000008],[-98.36332700000003,67.79081700000012],[-98.354446,67.79609700000003],[-98.35804699999994,67.8058170000001],[-98.44249000000002,67.86137400000007],[-98.44943199999994,67.86581400000006],[-98.46333300000003,67.86886599999997],[-98.47555499999999,67.86720300000007],[-98.48611499999993,67.86387600000012],[-98.49888599999997,67.86331200000001],[-98.51472499999994,67.86526500000014],[-98.54028299999999,67.87220800000011],[-98.65583799999996,67.91638200000006],[-98.665009,67.9202580000001],[-98.69694499999991,67.936646],[-98.71972699999992,67.94886799999995],[-98.72416699999985,67.953598],[-98.74694799999997,68.0477600000001],[-98.73277299999995,68.070267],[-98.61555499999992,68.07470699999999],[-98.54499800000002,68.06137100000007],[-98.33694500000001,67.96026599999999],[-98.321121,67.95220899999998],[-98.26695299999989,67.92330900000013],[-98.23332199999999,67.9019320000001],[-98.171112,67.84332300000005],[-98.16915899999992,67.838593],[-98.12277199999994,67.78804000000002],[-98.09445199999993,67.766098],[-97.95666499999987,67.72776800000008],[-97.79943800000001,67.68553200000008],[-97.66194200000001,67.64305100000007],[-97.650284,67.63943499999999],[-97.63751200000002,67.6308140000001],[-97.62609900000001,67.61804200000006],[-97.61305199999998,67.609421],[-97.603882,67.60525500000006],[-97.59277299999985,67.601654],[-97.57667499999997,67.59860200000008],[-97.56138599999991,67.59664900000013],[-97.54750100000001,67.59637500000002],[-97.50973499999992,67.59915200000012],[-97.48582499999992,67.60220300000015],[-97.415009,67.61331200000006],[-97.39222699999999,67.61804200000006],[-97.38194299999998,67.62136800000013],[-97.35305800000003,67.63443000000012],[-97.33444199999991,67.64387500000004],[-97.31666599999994,67.65443400000004],[-97.29554699999994,67.66110200000003],[-97.28332499999999,67.66249100000005],[-97.16722099999993,67.67553700000013],[-97.13890099999992,67.67414900000006],[-97.11694299999988,67.77748100000002],[-97.11582899999996,67.78276100000005],[-97.11915599999992,67.79248000000007],[-97.12721299999998,67.80165099999999],[-97.24027999999998,67.92608600000005],[-97.2541809999999,67.92942800000014],[-97.26306199999993,67.924149],[-97.26888999999994,67.91832],[-97.27305599999994,67.90776100000011],[-97.27362099999999,67.90248100000008],[-97.27722199999994,67.89694200000008],[-97.28277600000001,67.89109800000006],[-97.29110700000001,67.88499500000012],[-97.30139200000002,67.88165299999997],[-97.32444799999996,67.8766480000001],[-97.33667000000003,67.87525900000014],[-97.362503,67.87387100000001],[-97.37638899999996,67.87414600000005],[-97.39222699999999,67.87637300000011],[-97.40333599999997,67.879974],[-97.412216,67.88415500000008],[-97.41639700000002,67.888596],[-97.41972399999986,67.89833100000004],[-97.42805499999986,67.90776100000011],[-97.43443300000001,67.91192600000011],[-97.449997,67.9202580000001],[-97.64361600000001,68.008331],[-97.65249599999999,68.01220700000005],[-97.68306000000001,68.01859999999999],[-97.695267,68.01721200000009],[-97.70500199999998,68.0127720000001],[-97.70834400000001,68.00721700000003],[-97.710556,67.9916530000001],[-97.87777699999998,67.96360800000008],[-97.99665799999991,67.95027199999998],[-98.00973499999992,67.9497070000001],[-98.02999899999998,67.94192499999997],[-98.045837,67.92942800000014],[-98.05139199999996,67.92359899999997],[-98.05749500000002,67.91249099999999],[-98.060272,67.89166300000011],[-98.06388899999996,67.82916299999994],[-98.07861300000002,67.83027600000003],[-98.09527600000001,67.83332799999994],[-98.10665899999998,67.836929],[-98.11582899999996,67.84082000000006],[-98.17639200000002,67.87387100000001],[-98.189438,67.88247699999994],[-98.19471699999997,67.89721700000007],[-98.20083599999998,67.90664700000013],[-98.21362299999998,67.92053200000004],[-98.224716,67.92942800000014],[-98.25140399999998,67.94636500000001],[-98.28332499999993,67.96276899999992],[-98.31973299999993,67.97859199999999],[-98.34056099999998,67.98609900000008],[-98.37805199999997,67.99636800000013],[-98.39862099999999,68.004166],[-98.412216,68.01249700000005],[-98.58111599999995,68.13998400000003],[-98.58750900000001,68.14942900000011],[-98.58444199999991,68.15498400000001],[-98.485275,68.184418],[-98.47389199999998,68.18692000000004],[-98.45973200000003,68.18359400000003],[-98.45056199999999,68.17970300000013],[-98.43249500000002,68.1666560000001],[-98.42805499999992,68.1622010000001],[-98.42443799999995,68.15220599999998],[-98.42555199999993,68.14193699999998],[-98.42832900000002,68.13638300000014],[-98.43415800000002,68.13053899999994],[-98.44027699999998,68.11943100000013],[-98.44110099999995,68.10914600000001],[-98.439438,68.10415599999999],[-98.43055699999991,68.09498600000012],[-98.41722099999993,68.08638000000002],[-98.408051,68.08248900000012],[-98.39389,68.07916300000011],[-98.37999000000002,68.07916300000011],[-98.36776700000001,68.08055100000001],[-98.35888699999998,68.08581499999997],[-98.35082999999992,68.09220900000003],[-98.33972199999994,68.10386700000004],[-98.32167099999998,68.13693200000012],[-98.31777999999997,68.14776599999999],[-98.31722999999994,68.15304600000002],[-98.31750499999998,68.1622010000001],[-98.32611099999997,68.17137100000014],[-98.33306899999997,68.17553700000002],[-98.34222399999993,68.17942800000009],[-98.37748699999992,68.19026200000002],[-98.40834000000001,68.19664000000012],[-98.43971299999993,68.20082100000002],[-98.46972700000003,68.20304900000002],[-98.485275,68.20498700000013],[-98.50111399999997,68.20860299999998],[-98.531113,68.22526600000009],[-98.537781,68.22943100000009],[-98.54222099999993,68.23414600000012],[-98.56111099999998,68.27388000000002],[-98.60777299999995,68.29332],[-98.70417800000001,68.35276800000003],[-98.71083099999998,68.35693400000008],[-98.71528599999999,68.36164899999994],[-98.71722399999993,68.366379],[-98.71444699999995,68.372208],[-98.70472699999993,68.376373],[-98.68055700000002,68.38053900000011],[-98.66749600000003,68.38136300000008],[-98.63722199999995,68.3791500000001],[-98.60638399999999,68.37275699999998],[-98.59416199999998,68.36914100000007],[-98.58056599999992,68.36080900000007],[-98.57167099999998,68.35165400000005],[-98.54861499999998,68.33915700000006],[-98.53250100000002,68.3311000000001],[-98.52139299999993,68.32832300000001],[-98.51139799999993,68.32971199999997],[-98.47083999999995,68.34832799999998],[-98.46221899999995,68.35359199999999],[-98.46139499999998,68.35887100000014],[-98.47138999999999,68.37359600000008],[-98.49194299999994,68.38638300000008],[-98.50361599999997,68.38998400000014],[-98.49499499999996,68.40942400000012],[-98.319458,68.35887100000014],[-98.30972300000002,68.35498000000007],[-98.29888900000003,68.34610000000004],[-98.29444899999993,68.34137000000004],[-98.29249599999997,68.33665500000001],[-98.28832999999997,68.33194000000015],[-98.281387,68.32777400000003],[-98.22555499999993,68.30415299999999],[-98.21389799999992,68.30053700000013],[-98.19972200000001,68.30026200000009],[-98.18749999999994,68.3019260000001],[-98.09666399999998,68.31776400000012],[-98.07389799999999,68.33499099999995],[-97.90583800000002,68.38415500000013],[-97.89411899999993,68.386459],[-97.86471599999993,68.384995],[-97.84916699999991,68.38304099999999],[-97.77778599999988,68.366379],[-97.761124,68.36331200000006],[-97.74888599999991,68.36469999999997],[-97.74305699999991,68.37052899999998],[-97.75140399999998,68.37970000000013],[-97.76417499999991,68.39360000000005],[-97.76861600000001,68.39804100000015],[-97.78195199999993,68.40664700000002],[-97.79611199999988,68.40998800000006],[-97.81138599999997,68.41137700000007],[-97.86971999999997,68.414154],[-97.885559,68.41638200000011],[-97.89999399999994,68.41970799999996],[-97.906387,68.42387400000007],[-98.00973499999992,68.49803200000002],[-98.01139799999993,68.50305200000008],[-98.01083399999999,68.50804100000005],[-97.99972500000001,68.53526299999999],[-97.99415599999992,68.54109199999999],[-97.85249299999998,68.54248000000007],[-97.83639499999992,68.54026800000003],[-97.72389199999992,68.52304100000003],[-97.69276400000001,68.51666300000005],[-97.66500899999994,68.50471500000003],[-97.6583399999999,68.50054900000009],[-97.6541749999999,68.49609400000008],[-97.65055799999993,68.48609899999997],[-97.65388499999995,68.480545],[-97.65527299999997,68.470261],[-97.650284,68.45555100000001],[-97.646118,68.45082099999996],[-97.63917500000002,68.44664000000006],[-97.61166399999996,68.43470800000011],[-97.537781,68.41832000000005],[-97.523056,68.41693100000009],[-97.51112399999994,68.41943400000002],[-97.502228,68.42469800000003],[-97.49888599999997,68.43026700000001],[-97.500565,68.43498200000005],[-97.50917099999998,68.44442700000013],[-97.520554,68.44802900000008],[-97.535553,68.449142],[-97.54750100000001,68.44664000000006],[-97.57333399999993,68.44442700000013],[-97.58917199999996,68.44664000000006],[-97.60333299999996,68.449997],[-97.615005,68.45359800000006],[-97.61915599999992,68.45832800000011],[-97.61776700000001,68.46249399999999],[-97.597778,68.48359700000009],[-97.57861300000002,68.493042],[-97.56777999999997,68.49636800000002],[-97.54444899999999,68.50138900000013],[-97.53111299999995,68.50193800000011],[-97.51695299999994,68.50166300000006],[-97.385559,68.49525499999993],[-97.35360699999995,68.49108900000004],[-97.28277600000001,68.47415200000006],[-97.25917099999987,68.4666600000001],[-97.160278,68.38943500000005],[-97.05332900000002,68.35331699999995],[-97.058334,68.30276500000008],[-97.07000700000003,68.30026200000009],[-97.07583599999992,68.29443399999997],[-97.09111000000001,68.26805100000001],[-97.089447,68.26332099999996],[-97.08029199999993,68.25915500000008],[-96.93916299999995,68.23970000000008],[-96.925003,68.23915099999999],[-96.91250599999995,68.24081400000006],[-96.81777999999991,68.25833100000011],[-96.80638099999993,68.26081800000003],[-96.79943800000001,68.26554899999996],[-96.76777599999997,68.270264],[-96.69387799999993,68.28027299999997],[-96.68055699999996,68.280823],[-96.66915899999998,68.27693199999993],[-96.62527499999987,68.25166300000012],[-96.55332899999996,68.27360500000003],[-96.53306600000002,68.28193699999997],[-96.47084000000001,68.305542],[-96.44888300000002,68.31219499999997],[-96.43721,68.31469700000002],[-96.42471299999994,68.31608600000004],[-96.410553,68.31553600000001],[-96.40417499999995,68.31137100000001],[-96.49694799999997,68.20776400000005],[-96.508896,68.19636500000013],[-96.52583299999998,68.18414299999995],[-96.62304699999999,68.11554000000007],[-96.69055199999997,68.07998700000007],[-96.702225,68.07748400000008],[-96.73028599999992,68.07832300000007],[-96.74305700000002,68.07777400000009],[-96.75556899999998,68.076096],[-96.77888499999995,68.07138099999997],[-96.79722599999997,68.06109600000002],[-96.80888399999998,68.04942299999999],[-96.81220999999994,68.04386900000003],[-96.81332399999991,68.03858900000012],[-96.8116609999999,68.03359999999998],[-96.801941,68.02581800000002],[-96.78916900000002,68.01721200000009],[-96.77305599999994,68.01388499999996],[-96.722778,68.00971999999996],[-96.70834399999995,68.00860599999999],[-96.67610199999996,68.01859999999999],[-96.55665599999998,68.03332499999993],[-96.54028299999993,68.03027300000002],[-96.52806099999998,68.03166200000004],[-96.46639999999996,68.03887900000012],[-96.45083599999998,68.05304000000012],[-96.47999600000003,68.09027100000009],[-96.49110399999995,68.09414700000013],[-96.50500499999993,68.09443699999997],[-96.51611300000002,68.09109500000005],[-96.53443900000002,68.080826],[-96.54695099999998,68.07943700000004],[-96.54834,68.08415200000007],[-96.54750100000001,68.0894320000001],[-96.53527799999989,68.10108900000006],[-96.51000999999997,68.11943100000013],[-96.48249800000002,68.13472000000002],[-96.46305799999993,68.14414999999991],[-96.43222000000003,68.15609700000005],[-96.31082200000003,68.19220000000013],[-96.28832999999997,68.19775400000009],[-96.17138699999992,68.22164900000013],[-96.13612399999994,68.2285920000001],[-95.98028599999998,68.25471500000003],[-95.96833800000002,68.23082000000005],[-96.04333499999996,68.17942800000009],[-96.06916799999999,68.16137700000013],[-96.07501200000002,68.15554800000012],[-96.07861299999996,68.1499940000001],[-96.07749899999999,68.14498900000007],[-96.073624,68.14027400000003],[-96.045837,68.13333100000006],[-96.03443900000002,68.12970000000001],[-96.02806099999998,68.12525900000009],[-96.02055399999995,68.11608900000004],[-96.01916499999993,68.11109899999997],[-96.02027900000002,68.1060940000001],[-96.083618,68.00221300000004],[-96.14416499999999,67.92359899999997],[-96.21166999999991,67.82916299999994],[-96.21528599999988,67.82360800000004],[-96.21722399999999,67.81330900000006],[-96.22138999999999,67.69775400000003],[-96.22000099999991,67.693039],[-96.21250899999995,67.68386800000007],[-96.20611600000001,67.67942800000003],[-96.19554099999999,67.68275499999999],[-96.18693499999995,67.68887300000011],[-96.17971799999992,67.69274899999999],[-96.16833500000001,67.69497700000011],[-96.16665599999999,67.69026200000008],[-96.174713,67.64305100000007],[-96.18527199999994,67.626373],[-96.19193999999999,67.62164300000012],[-96.20333900000003,67.61914100000007],[-96.21640000000002,67.61859100000004],[-96.23083499999996,67.61998],[-96.24665799999997,67.62330600000007],[-96.25778199999996,67.62692300000003],[-96.26640299999997,67.63108800000003],[-96.32972699999999,67.6102600000001],[-96.43777499999993,67.54136700000004],[-96.46139499999992,67.50888099999992],[-96.46472199999988,67.50332600000002],[-96.46916199999998,67.492752],[-96.46472199999988,67.47804300000013],[-96.46112099999999,67.47331200000002],[-96.45167500000002,67.47137499999997],[-96.44193999999993,67.47554000000014],[-96.36389200000002,67.47804300000013],[-96.29415899999998,67.444702],[-96.222778,67.42192099999994],[-96.21000699999996,67.41914400000007],[-96.19638099999992,67.41886900000003],[-96.18582199999997,67.422211],[-96.158051,67.43664600000011],[-96.141388,67.44886800000006],[-96.135559,67.45471200000009],[-96.11888099999993,67.4666600000001],[-96.10749800000002,67.46914700000002],[-96.09722899999997,67.46470600000009],[-96.069458,67.43359399999997],[-96.07028199999996,67.42831400000011],[-96.12416100000002,67.37719699999997],[-96.16665599999999,67.34166000000005],[-96.17721599999987,67.33692900000011],[-96.208618,67.3269350000001],[-96.218613,67.322769],[-96.226944,67.31666600000005],[-96.25111399999992,67.25277699999998],[-96.252228,67.24748200000005],[-96.24360699999988,67.24331700000005],[-96.12999000000002,67.21665999999999],[-96.114441,67.21331800000007],[-96.10249299999998,67.21470599999998],[-96.09138499999995,67.21720900000014],[-95.921112,67.27859500000005],[-95.81750499999993,67.33194000000015],[-95.756393,67.36747700000006],[-95.73999000000003,67.37664800000005],[-95.60305799999992,67.383331],[-95.58944699999995,67.38304099999999],[-95.57694999999995,67.38026400000007],[-95.56582599999996,67.37664800000005],[-95.54916399999996,67.36831699999993],[-95.53472899999997,67.359985],[-95.52861000000001,67.35554500000012],[-95.52500899999995,67.35108900000006],[-95.55332899999996,67.31330900000012],[-95.56166099999996,67.30720500000012],[-95.61805699999996,67.27832000000006],[-95.63806199999999,67.27082800000011],[-95.67748999999998,67.25416600000011],[-95.69665499999996,67.24498],[-95.76306199999988,67.2127690000001],[-95.80749500000002,67.18609600000013],[-95.82389799999999,67.174149],[-95.82972699999999,67.16831999999994],[-95.83332799999994,67.16276600000015],[-95.82167099999992,67.16110200000014],[-95.79695100000004,67.16304000000008],[-95.774719,67.16775500000011],[-95.74221799999998,67.17665100000005],[-95.71221899999995,67.18830900000006],[-95.65139799999992,67.19886800000012],[-95.568893,67.21054100000015],[-95.54415899999992,67.2124940000001],[-95.51583900000003,67.20971700000001],[-95.50111399999997,67.20748900000001],[-95.43554699999993,67.19386300000008],[-95.37943999999993,67.15470899999997],[-95.32611099999997,67.02720599999998],[-95.32861300000002,67.0169370000001],[-95.33721899999995,66.99054000000001],[-95.34333799999996,66.9747010000001],[-95.35028099999988,66.96388200000007],[-95.35777300000001,66.959991],[-95.41639699999996,66.9519350000001],[-95.53472899999997,66.94108600000004],[-95.597778,66.948868],[-95.61416600000001,66.97026100000011],[-95.721115,66.96470600000004],[-95.74333199999995,66.959991],[-95.83917199999996,66.94802900000002],[-95.87609900000001,66.94581600000004],[-95.90249599999999,66.94664],[-95.92805499999997,66.95248400000003],[-95.93638599999997,66.95664999999997],[-95.99027999999998,67.00499000000013],[-95.99388099999993,67.00972000000002],[-95.99055499999992,67.01499899999999],[-95.978882,67.026657],[-95.96112099999999,67.04386900000003],[-95.93638599999997,67.06526200000013],[-95.93221999999997,67.06971699999997],[-95.94694500000003,67.07222000000013],[-95.95834400000001,67.06971699999997],[-95.96777299999991,67.06553600000007],[-96.004456,67.04582199999999],[-96.04611199999994,67.01638799999995],[-96.05166599999995,67.01081800000009],[-96.053879,67.0002750000001],[-96.04666099999997,66.99108899999999],[-96.04055800000003,66.98664899999994],[-96.02362099999993,66.97859199999999],[-96.02500899999995,66.97331200000013],[-96.03306600000002,66.96748400000001],[-96.04277000000002,66.96304300000008],[-96.11054999999993,66.95082100000013],[-96.12332200000003,66.95027199999998],[-96.13861099999991,66.953598],[-96.24082899999996,66.98359700000003],[-96.26251200000002,66.99108899999999],[-96.27917500000001,66.99914599999994],[-96.285278,67.00360099999995],[-96.28694199999995,67.00860600000004],[-96.28582799999998,67.01361100000008],[-96.27417000000003,67.0252690000001],[-96.265289,67.03054800000007],[-96.26194799999996,67.03581200000008],[-96.261124,67.0410920000001],[-96.26362599999999,67.05108600000011],[-96.26888999999989,67.06053200000008],[-96.28805499999993,67.06832900000006],[-96.37721299999987,67.08471700000013],[-96.39222699999999,67.086929],[-96.40388499999995,67.08554100000009],[-96.45249899999999,67.06832900000006],[-96.46055599999988,67.06219500000003],[-96.45666499999999,67.05775499999999],[-96.40388499999995,67.008331],[-96.27362099999999,66.95027199999998],[-96.14639299999999,66.89471400000014],[-96.12805199999997,66.88165300000003],[-96.11721799999998,66.86775200000005],[-96.11582900000002,66.86276199999998],[-96.11721799999998,66.857483],[-96.11665299999999,66.84748800000006],[-96.11555499999997,66.84248400000013],[-96.1141659999999,66.83749400000005],[-96.10888699999998,66.83276400000005],[-96.10055499999993,66.82859800000011],[-96.00666799999993,66.79443400000008],[-95.98055999999991,66.7874910000001],[-95.95611599999995,66.78221100000007],[-95.91221599999994,66.77554300000008],[-95.883621,66.7688750000001],[-95.862213,66.76110799999998],[-95.848053,66.75277700000004],[-95.84194899999994,66.74832200000003],[-95.78472899999991,66.67414900000006],[-95.77749599999999,66.65498400000013],[-95.77722199999988,66.64471400000002],[-95.78083800000002,66.6291500000001],[-95.74137899999994,66.63804600000003],[-95.656387,66.6602630000001],[-95.64666699999998,66.66442899999998],[-95.62971499999998,66.67553699999996],[-95.62748699999997,66.68609600000002],[-95.64889499999998,66.724152],[-95.652222,66.72859200000005],[-95.660553,66.73275799999993],[-95.6744379999999,66.73414600000007],[-95.78472899999991,66.73719800000015],[-95.99305699999996,66.84275800000006],[-96.087784,66.90748600000012],[-96.0916749999999,66.911926],[-96.09277299999997,66.91693100000003],[-96.0916749999999,66.92221100000006],[-96.08555599999994,66.9269260000001],[-96.066956,66.93637100000001],[-96.04750099999995,66.94470200000006],[-96.037216,66.94802900000002],[-96.02610800000002,66.95027199999998],[-96.00029,66.95054600000009],[-95.90249599999999,66.94664],[-95.814438,66.94136000000015],[-95.78500400000001,66.93691999999993],[-95.77278099999995,66.93275499999993],[-95.766663,66.928314],[-95.76306199999988,66.92387400000001],[-95.760559,66.91387900000007],[-95.756958,66.90914900000007],[-95.75111400000003,66.90498400000007],[-95.73805199999998,66.90138200000013],[-95.72471599999994,66.90081799999996],[-95.516663,66.90220600000009],[-95.49305700000002,66.90498400000007],[-95.47222899999991,66.91165200000006],[-95.38917500000002,66.91110200000003],[-95.33666999999991,66.89305100000001],[-95.32362399999988,66.88943499999999],[-95.31138599999991,66.88998400000008],[-95.30082700000003,66.89332600000006],[-95.291672,66.8983310000001],[-95.26750199999998,66.91415400000011],[-95.25917099999998,66.92025799999993],[-95.2208399999999,66.96832299999994],[-95.21945199999999,66.97360200000014],[-95.22639499999997,66.9827580000001],[-95.23222399999997,66.98719800000009],[-95.28944399999995,67.02499400000005],[-95.34500099999997,67.08442700000012],[-95.35221899999999,67.14833100000004],[-95.34638999999999,67.15387000000004],[-95.2661129999999,67.2127690000001],[-95.16610700000001,67.27693199999999],[-95.162216,67.28221100000013],[-95.16332999999997,67.28720099999998],[-95.17193600000002,67.2913670000001],[-95.18249499999996,67.29525799999999],[-95.21722399999993,67.30636600000014],[-95.27972399999987,67.31944299999998],[-95.30638099999987,67.32666000000006],[-95.31471299999993,67.33055099999996],[-95.33277900000002,67.34387200000009],[-95.33639499999998,67.34832800000004],[-95.38417099999998,67.44413800000001],[-95.33999599999993,67.49971],[-95.33167999999995,67.505829],[-95.32417299999992,67.51666300000005],[-95.32167099999992,67.52720600000004],[-95.32305899999994,67.53193699999997],[-95.33000199999992,67.54136700000004],[-95.343613,67.55497700000012],[-95.34973100000002,67.559418],[-95.46640000000002,67.63720700000005],[-95.49249299999997,67.64332600000006],[-95.53500399999996,67.64665200000007],[-95.54834,67.64999400000005],[-95.69305400000002,67.70443699999998],[-95.70777900000002,67.72303800000003],[-95.70916699999992,67.72776800000008],[-95.70805399999995,67.73304700000006],[-95.704453,67.73858600000005],[-95.69833399999999,67.74443100000013],[-95.68110699999994,67.7563780000001],[-95.67193600000002,67.76165799999995],[-95.64973399999991,67.76721199999997],[-95.63751199999996,67.76860000000005],[-95.62638899999996,67.771927],[-95.57749899999999,67.7874910000001],[-95.55888399999998,67.79775999999993],[-95.55027799999988,67.80386399999998],[-95.54415899999992,67.809708],[-95.53443900000002,67.820831],[-95.52583300000003,67.836929],[-95.52223199999997,67.85276799999997],[-95.527222,67.87220800000011],[-95.452225,67.98109400000004],[-95.416946,68.02777100000014],[-95.42721599999993,68.032486],[-95.47193900000002,68.05497700000001],[-95.47528099999994,68.0583190000001],[-95.47277799999995,68.06053200000008],[-95.46139499999987,68.06387300000011],[-95.40417500000001,68.06944300000004],[-95.34973100000002,68.074432],[-95.34306300000003,68.074432],[-95.07556199999988,68.06887799999998],[-95.07112099999995,68.06359900000001],[-95.06527699999992,68.06025700000004],[-95.05499299999991,68.055252],[-95.04388399999993,68.05137600000012],[-95.02362099999999,68.04582199999993],[-95.00889599999994,68.04443400000002],[-94.86721799999998,68.03414900000013],[-94.83972199999994,68.03414900000013],[-94.78805499999999,68.04054300000013],[-94.72222899999997,68.05497700000001],[-94.71417200000002,68.05941800000011],[-94.70750399999997,68.06581100000005],[-94.69665499999996,68.07859800000006],[-94.69387799999998,68.08332800000011],[-94.60499599999997,68.13970899999998],[-94.37249799999995,68.22137500000002],[-94.210556,68.26277200000004],[-94.19915799999995,68.26776100000001],[-94.193604,68.27221700000007],[-94.19221499999998,68.27638200000007],[-94.19166599999994,68.28137200000015],[-94.1924899999999,68.29220600000002],[-94.193604,68.29832500000003],[-94.20527599999991,68.31330900000012],[-94.20916699999998,68.32360799999998],[-94.21028099999995,68.32804900000008],[-94.21083099999998,68.36137400000013],[-94.208054,68.36608899999999],[-94.203888,68.37025500000004],[-94.12304699999999,68.41693100000009],[-94.10472099999998,68.42414900000006],[-94.00028999999995,68.46081500000003],[-93.96806300000003,68.46859699999993],[-93.95361300000002,68.47192400000006],[-93.93666100000002,68.47470099999998],[-93.92277499999994,68.47554000000014],[-93.89361599999995,68.47470099999998],[-93.87582399999991,68.47720300000003],[-93.81138599999997,68.48803700000013],[-93.66139199999998,68.52082800000005],[-93.65666199999998,68.52331500000014],[-93.61915599999998,68.54414400000007],[-93.55332900000002,68.58638000000008],[-93.55972299999996,68.61164900000011],[-93.62193300000001,68.62441999999999],[-93.64750700000002,68.62692300000015],[-93.65306099999998,68.62637300000011],[-93.70527600000003,68.65721100000013],[-93.69722000000002,68.74914599999994],[-93.695267,68.75193800000005],[-93.63945000000001,68.78054800000007],[-93.57167099999992,68.83415200000007],[-93.56750499999993,68.83970600000009],[-93.56610099999995,68.849426],[-93.63444499999997,68.95915200000013],[-93.64222699999993,68.96388200000001],[-93.666946,68.97221400000001],[-93.73138399999999,68.9749910000001],[-93.92555199999987,68.97470100000004],[-94.03083800000002,68.9185940000001],[-94.03916900000002,68.91415400000005],[-94.05583200000001,68.9019320000001],[-94.068893,68.89109800000006],[-94.07972699999999,68.84748800000006],[-94.07112099999989,68.84359699999999],[-94.03416400000003,68.83332800000011],[-94.021118,68.83610500000003],[-93.93388400000003,68.855255],[-93.85249299999998,68.87914999999998],[-93.83860799999997,68.885269],[-93.837784,68.88638300000002],[-93.82472200000001,68.89137300000004],[-93.81388900000002,68.89305099999996],[-93.80999799999995,68.89054900000008],[-93.81388900000002,68.88499500000006],[-93.82972699999993,68.87608300000005],[-93.93415799999997,68.82499700000005],[-94.08500699999996,68.76110800000009],[-94.09527600000001,68.75804099999999],[-94.108047,68.75526400000007],[-94.15972899999997,68.74775699999998],[-94.385559,68.72915599999993],[-94.49082899999996,68.72886700000004],[-94.625,68.76138300000014],[-94.60888699999992,68.81944300000004],[-94.58889799999992,68.8413700000001],[-94.58332799999994,68.8458250000001],[-94.57084700000001,68.85026600000003],[-94.56166100000002,68.855255],[-94.556107,68.85998500000005],[-94.55305499999997,68.86442599999992],[-94.54527300000001,68.88472000000007],[-94.54804999999993,68.88888500000007],[-94.55749500000002,68.89305099999996],[-94.56945799999994,68.8936000000001],[-94.577225,68.89665200000002],[-94.585556,68.90304600000007],[-94.58999599999999,68.90832500000005],[-94.60583500000001,68.95109600000006],[-94.604172,68.96192900000005],[-94.59916699999997,68.96554600000002],[-94.587219,68.96887200000003],[-94.55332900000002,68.97387700000007],[-94.37388599999997,69.00305200000014],[-94.22416699999997,69.02777100000014],[-94.16305499999999,69.05220000000008],[-94.15139799999997,69.05720500000012],[-94.07278400000001,69.12664800000005],[-94.07250999999997,69.14498900000007],[-94.1375119999999,69.13192700000002],[-94.22084000000001,69.1202550000001],[-94.23500100000001,69.11943100000013],[-94.24833699999994,69.12052900000003],[-94.31221,69.14498900000007],[-94.32305899999994,69.1499940000001],[-94.32749899999999,69.15525800000006],[-94.3291779999999,69.16137700000013],[-94.30943300000001,69.29414400000013],[-94.30665599999998,69.30026200000009],[-94.30332899999996,69.30497700000012],[-94.291672,69.31387300000006],[-94.28416399999998,69.3188780000001],[-94.25917099999992,69.32666000000006],[-94.16665599999999,69.34248399999996],[-94.04333500000001,69.35748300000006],[-94.02500900000001,69.359711],[-93.95527600000003,69.36276200000003],[-93.73666400000002,69.39999400000005],[-93.62693799999994,69.43247999999994],[-93.57472199999995,69.44165000000004],[-93.56277499999999,69.44274899999999],[-93.52639799999992,69.438309],[-93.53250100000002,69.42997700000001],[-93.54777499999994,69.4205320000001],[-93.67971799999998,69.34776299999993],[-93.69166599999994,69.34275800000006],[-93.741379,69.32443200000006],[-93.75306699999999,69.32054099999999],[-93.76417499999997,69.32054099999999],[-93.82861299999996,69.26554900000008],[-93.85611,69.17692600000004],[-93.85665899999998,69.172211],[-93.84500100000002,69.16499299999998],[-93.83721899999989,69.16442900000004],[-93.63473499999998,69.25166300000012],[-93.46749899999992,69.31749000000002],[-93.45666499999999,69.32304399999998],[-93.36277799999999,69.37164300000012],[-93.36527999999998,69.376083],[-93.37943999999999,69.376373],[-93.45916699999987,69.359711],[-93.47000100000002,69.35664400000007],[-93.47805799999998,69.35331700000012],[-93.49804699999999,69.34915200000012],[-93.51194799999996,69.34942600000005],[-93.56500199999994,69.36775200000005],[-93.56054699999993,69.38388100000003],[-93.53805499999993,69.41053800000009],[-93.527222,69.42164600000007],[-93.51583900000003,69.42553700000013],[-93.50306699999987,69.42747500000007],[-93.48889200000002,69.43498200000005],[-93.43943799999994,69.47526599999998],[-93.44137599999999,69.48054499999995],[-93.48777799999999,69.50277700000004],[-93.50973499999992,69.51304600000009],[-93.53250100000002,69.52110300000004],[-93.54083300000002,69.52331500000008],[-93.587219,69.52804600000002],[-93.62193300000001,69.52720599999998],[-93.68388399999998,69.52221700000001],[-93.70973200000003,69.516098],[-93.80888400000003,69.48887600000006],[-93.86971999999997,69.45166000000012],[-94.04527299999995,69.4391480000001],[-94.27917500000001,69.44026200000008],[-94.29972800000002,69.443039],[-94.31304899999998,69.44664000000006],[-94.34388699999994,69.45915200000007],[-94.45167499999997,69.51860000000005],[-94.50250199999999,69.55636600000003],[-94.59194899999994,69.63720699999999],[-94.62943999999999,69.68304400000005],[-94.67027300000001,69.67747500000007],[-94.712784,69.67164600000001],[-94.749435,69.66360500000013],[-94.75500499999993,69.661652],[-94.76417499999997,69.65498400000007],[-94.76666299999994,69.651093],[-94.76222200000001,69.64471400000014],[-94.74221799999992,69.62831100000005],[-94.72444199999995,69.61442599999998],[-94.72555499999993,69.60859700000015],[-94.73083500000001,69.60276799999997],[-94.74027999999998,69.59748800000006],[-94.76972999999998,69.58305400000006],[-94.8011019999999,69.57221999999996],[-94.82000700000003,69.56721500000009],[-94.83111600000001,69.56581100000011],[-94.84666400000003,69.56553600000012],[-94.86277799999988,69.5669400000001],[-94.95195000000001,69.58442700000012],[-95.01055899999994,69.60304300000013],[-95,69.61886599999997],[-95.00944499999997,69.62164300000006],[-95.021118,69.62164300000006],[-95.07861299999996,69.61637900000011],[-95.16860999999989,69.630539],[-95.396118,69.67886400000003],[-95.40834000000001,69.68193100000013],[-95.42304999999993,69.68609600000013],[-95.54499799999996,69.72692900000004],[-95.648056,69.78027300000002],[-95.71556099999998,69.79136699999992],[-95.72471599999994,69.78997800000013],[-95.7283329999999,69.789154],[-95.73889200000002,69.78610200000003],[-95.75723299999993,69.77720599999992],[-95.75862099999995,69.7727660000001],[-95.86332699999997,69.77221699999996],[-95.96083099999998,69.77804599999996],[-95.97555499999993,69.78193700000003],[-96.02027900000002,69.80442800000003],[-96.03582799999992,69.81387300000011],[-96.07444799999996,69.84193400000004],[-96.087784,69.86914100000013],[-96.08222999999992,69.87359600000013],[-96.08500700000002,69.91137700000013],[-96.097778,69.94663999999995],[-96.116104,69.95387299999999],[-96.17721599999987,69.96470599999992],[-96.19554099999999,69.96554600000002],[-96.19860799999998,69.96499599999999],[-96.20944199999997,69.96165500000012],[-96.21722399999999,69.958328],[-96.22055099999994,69.95748900000001],[-96.23500099999995,69.95748900000001],[-96.24694799999992,69.95887800000003],[-96.25723299999993,69.96304300000003],[-96.27278099999995,69.97109999999998],[-96.38137799999987,70.02748100000008],[-96.40249599999987,70.03997800000008],[-96.45944199999997,70.07554600000009],[-96.50029,70.10137900000001],[-96.50917099999992,70.10859700000003],[-96.52528399999994,70.12275699999998],[-96.531677,70.13108800000003],[-96.55610699999994,70.19192500000008],[-96.56889299999995,70.224426],[-96.57167099999987,70.23442100000005],[-96.57028199999996,70.25109900000012],[-96.56861900000001,70.2686000000001],[-96.56277499999993,70.30026200000003],[-96.55860899999993,70.3119200000001],[-96.55555700000002,70.31749000000013],[-96.54834,70.32887299999999],[-96.53500399999996,70.34414700000008],[-96.29472399999997,70.52249100000012],[-96.23277300000001,70.56219500000003],[-96.07888799999989,70.58749400000005],[-96.06973299999993,70.58776900000004],[-96.04527300000001,70.58415200000007],[-96.04110700000001,70.57693499999999],[-96.03332499999993,70.57276900000011],[-95.99526999999995,70.55970799999994],[-95.93499799999995,70.54748500000011],[-95.92332499999992,70.54525800000005],[-95.806107,70.52886999999998],[-95.79722599999997,70.5294340000001],[-95.78944399999995,70.53665200000012],[-95.791382,70.54275500000006],[-95.79916400000002,70.54914900000011],[-95.85583499999996,70.55331400000011],[-95.9141689999999,70.55941799999994],[-95.93167099999994,70.56219500000003],[-95.96444699999995,70.56887800000004],[-96.000565,70.57998700000007],[-96.04998799999993,70.60026600000003],[-96.058334,70.60582000000005],[-96.06138599999986,70.61720300000002],[-96.05555700000002,70.64305099999996],[-96.04834,70.64694200000002],[-95.95249899999999,70.67970299999996],[-95.848343,70.70694000000009],[-95.81555199999997,70.70915199999996],[-95.81777999999997,70.71026599999993],[-95.901947,70.70776400000005],[-95.93277,70.70109600000006],[-96.11555499999997,70.6560970000001],[-96.13806199999999,70.64637800000008],[-96.14999399999994,70.63720699999999],[-96.15278599999994,70.63247700000011],[-96.15472399999999,70.62469499999997],[-96.153885,70.62164300000006],[-96.158051,70.61747699999995],[-96.16027799999995,70.61637900000005],[-96.16361999999998,70.61554000000012],[-96.202789,70.62164300000006],[-96.37609899999995,70.67303500000003],[-96.38528400000001,70.67776500000002],[-96.39472999999998,70.68359400000003],[-96.40110800000002,70.69053600000012],[-96.41000399999996,70.70248400000003],[-96.41555799999998,70.71527100000003],[-96.42250099999995,70.726089],[-96.43472300000002,70.73719800000003],[-96.44665499999996,70.74192800000009],[-96.53694200000001,70.76332100000002],[-96.58056599999998,70.77748099999991],[-96.60388199999994,70.78804000000014],[-96.61193800000001,70.79443400000002],[-96.61500499999994,70.80442800000003],[-96.61361699999992,70.8211060000001],[-96.601944,70.84999099999999],[-96.59167499999995,70.86692800000014],[-96.57861300000002,70.87803599999995],[-96.571121,70.88304099999999],[-96.5452729999999,70.90498399999996],[-96.53083799999996,70.92137100000014],[-96.52416999999997,70.93165600000003],[-96.51306199999999,70.94970700000005],[-96.51083399999993,70.95582600000006],[-96.50306699999999,70.99693300000007],[-96.49583399999989,71.04026800000008],[-96.48167399999988,71.04332],[-96.45028699999995,71.04498300000012],[-96.414444,71.05358900000004],[-96.40666199999993,71.05859400000008],[-96.36999500000002,71.08998100000002],[-96.37110899999993,71.09304800000012],[-96.37582399999997,71.09803799999997],[-96.40943900000002,71.11943100000008],[-96.41777000000002,71.11360200000007],[-96.42027300000001,71.10720800000001],[-96.41221599999994,71.09582499999999],[-96.41000399999996,71.08970599999998],[-96.41361999999992,71.08415200000002],[-96.421112,71.0816650000001],[-96.44082599999996,71.07916300000005],[-96.46139499999992,71.08055100000013],[-96.47666900000002,71.08526599999999],[-96.50556899999998,71.09721400000001],[-96.53832999999997,71.11303700000002],[-96.55221599999999,71.11998000000006],[-96.56054699999999,71.126373],[-96.55943300000001,71.1308140000001],[-96.553879,71.13693200000006],[-96.54861499999993,71.14054899999996],[-96.46722399999993,71.16526799999997],[-96.45799299999999,71.19556400000005],[-96.46220399999999,71.25550100000004],[-96.50445599999989,71.27609300000012],[-96.50389099999995,71.27720599999998],[-96.48889199999996,71.28610200000008],[-96.27806099999992,71.32638499999996],[-96.24499499999996,71.35386699999992],[-96.21833799999996,71.375809],[-96.193329,71.38998400000008],[-96.16833500000001,71.39999399999999],[-96.13417099999998,71.40971400000006],[-96.04638699999998,71.418045],[-96.02778599999994,71.417755],[-95.92639200000002,71.40054299999997],[-95.89388999999994,71.39082300000007],[-95.88276699999994,71.38415500000008],[-95.87887599999999,71.3785860000001],[-95.87805200000003,71.37303200000008],[-95.87887599999999,71.36720300000007],[-95.85916099999997,71.35498000000001],[-95.83000199999992,71.34304800000007],[-95.79222099999993,71.32804900000002],[-95.67304999999999,71.2874910000001],[-95.65888999999999,71.28553799999997],[-95.55110200000001,71.28997800000002],[-95.535278,71.29081699999995],[-95.45527600000003,71.367752],[-95.45140100000003,71.375809],[-95.547775,71.48776200000003],[-95.77999899999998,71.50387599999999],[-95.83277900000002,71.51582300000013],[-95.9366609999999,71.54664600000012],[-95.94305400000002,71.5535890000001],[-95.90833999999995,71.60054000000014],[-95.89500399999991,71.61053500000003],[-95.88999899999999,71.61331200000012],[-95.87721299999998,71.61831699999999],[-95.86389200000002,71.61943099999996],[-95.81220999999994,71.62191800000005],[-95.74471999999997,71.624146],[-95.678879,71.64637800000008],[-95.53971899999999,71.70359799999994],[-95.39973399999997,71.71859700000005],[-95.30162000000001,71.72109999999998],[-95.28944399999995,71.75360100000012],[-95.28944399999995,71.75749199999996],[-95.28805499999987,71.761932],[-95.28582799999998,71.76721200000009],[-95.239441,71.82249500000006],[-95.226944,71.82666000000006],[-95.073059,71.84137000000004],[-94.890289,71.84471100000007],[-94.85638399999999,71.843323],[-94.83889799999997,71.841095],[-94.79527299999995,71.83332800000005],[-94.74415599999998,71.82304400000004],[-94.73443599999996,71.82331799999997],[-94.71639999999996,71.82609600000012],[-94.65388499999995,71.84526100000011],[-94.612503,71.859711],[-94.60665899999998,71.86331200000006],[-94.60777299999995,71.866379],[-94.61527999999998,71.86886600000008],[-94.62971500000003,71.86692800000014],[-94.65583799999996,71.8619230000001],[-94.70611599999995,71.84803800000003],[-94.74305699999996,71.8394320000001],[-94.75695799999994,71.83749399999994],[-94.77528399999994,71.83888200000007],[-94.78306600000002,71.84137000000004],[-94.82611099999997,71.847488],[-94.85360700000001,71.84942600000011],[-94.903885,71.85026600000015],[-95.10249299999998,71.851089],[-95.11915599999998,71.85026600000015],[-95.15722700000003,71.84582500000005],[-95.17999299999997,71.84304800000012],[-95.18055700000002,71.84220899999997],[-95.19248999999996,71.84137000000004],[-95.21333300000003,71.84304800000012],[-95.23111,71.849152],[-95.24082900000002,71.85386700000004],[-95.25167799999997,71.86053499999997],[-95.25666799999993,71.86692800000014],[-95.25500499999998,71.89553799999999],[-95.222778,71.94220000000007],[-95.21749899999986,71.944977],[-95.20140099999998,71.94720500000011],[-94.97193900000002,71.97581499999995],[-94.741104,71.99192800000003],[-94.69804399999998,71.99359099999992],[-94.66166699999997,71.99498000000011],[-94.57972699999999,71.99693300000007],[-94.56361400000003,71.99693300000007],[-94.53028899999998,71.99443100000002],[-94.499435,71.98803700000013],[-94.487213,71.9833220000001],[-94.39361599999995,71.938309],[-94.38722200000001,71.93386800000007],[-94.38861099999991,71.92414900000011],[-94.460556,71.84942600000011],[-94.47222899999997,71.84721400000006],[-94.50666799999999,71.84776299999999],[-94.521118,71.84999099999993],[-94.539444,71.85137900000007],[-94.56249999999994,71.84999099999993],[-94.57444800000002,71.84693900000002],[-94.64416499999993,71.818329],[-94.61860699999994,71.75332600000007],[-94.61193799999995,71.74971000000005],[-94.5997309999999,71.74470499999995],[-94.59416199999998,71.74331700000005],[-94.56945799999994,71.74498],[-94.5558319999999,71.75000000000006],[-94.53860499999996,71.75833100000011],[-94.53639199999998,71.76110800000004],[-94.52860999999996,71.77137800000014],[-94.51972999999992,71.78915400000011],[-94.49749800000001,71.818329],[-94.48832699999997,71.82415800000001],[-94.48472600000002,71.82470699999993],[-94.39222699999999,71.81442300000009],[-94.366104,71.80247500000007],[-94.35665899999987,71.79637100000002],[-94.35472099999998,71.79247999999995],[-94.38999899999999,71.71775800000006],[-94.41944899999999,71.66720599999996],[-94.42388900000003,71.66137700000013],[-94.41833500000001,71.65998799999994],[-94.40695199999999,71.66081200000013],[-94.36888099999999,71.67526200000003],[-94.26722699999999,71.73082000000005],[-94.258896,71.74192800000009],[-94.25584399999997,71.7538760000001],[-94.24276699999996,71.77082800000011],[-94.22805800000003,71.78166199999998],[-94.20722999999992,71.78942899999993],[-94.19444299999992,71.79193100000003],[-94.181671,71.79193100000003],[-94.03694199999995,71.78720099999998],[-94.02362099999999,71.78581200000002],[-94.01472499999988,71.78109699999999],[-94.00834700000001,71.77499399999999],[-94.006393,71.76332100000002],[-93.99388099999999,71.75305200000014],[-93.97250399999996,71.74581899999998],[-93.94249000000002,71.74359099999998],[-93.90972899999991,71.74498],[-93.88806199999999,71.74832200000009],[-93.87138399999998,71.75305200000014],[-93.850281,71.76332100000002],[-93.83084100000002,71.77165200000007],[-93.81889299999989,71.77470399999999],[-93.80221599999999,71.77554299999997],[-93.78416400000003,71.77415500000006],[-93.74194299999999,71.76915000000002],[-93.72666900000002,71.76638800000012],[-93.71166999999997,71.76138300000002],[-93.70722999999992,71.75499000000008],[-93.69415300000003,71.71609500000011],[-93.69665500000002,71.71081500000008],[-93.70445299999994,71.70526100000006],[-93.73777799999999,71.68942300000003],[-93.764725,71.67970300000013],[-93.81111099999993,71.65748600000006],[-93.81861899999996,71.6519320000001],[-93.81138599999997,71.64553800000004],[-93.79722600000002,71.6394350000001],[-93.6583399999999,71.58194000000003],[-93.61805700000002,71.56860400000005],[-93.589447,71.56137100000007],[-93.51306199999988,71.54470799999996],[-93.4949949999999,71.54165600000005],[-93.476944,71.54026799999997],[-93.42832899999996,71.53414900000013],[-93.412216,71.53082300000005],[-93.23083500000001,71.47360200000014],[-93.21417199999996,71.46720900000014],[-93.20140100000003,71.46138000000013],[-93.18638599999997,71.43580600000013],[-93.18638599999997,71.43026700000013],[-93.18998699999986,71.42387400000001],[-93.19387799999993,71.41943399999997],[-93.19554099999993,71.41360500000013],[-93.19055199999997,71.4080350000001],[-93.18055699999996,71.401093],[-93.14250199999998,71.37498500000004],[-93.12887599999999,71.36886600000003],[-93.101944,71.36747700000001],[-93.06277499999999,71.36943100000002],[-93.04527299999995,71.367752],[-93.02917500000001,71.36442599999998],[-92.99722299999996,71.35386699999992],[-92.98582499999986,71.34887700000007],[-92.97721899999993,71.34387200000003],[-92.97389199999998,71.34082000000012],[-92.94193999999993,71.28887900000001],[-92.93859900000001,71.27053800000004],[-92.93611099999993,71.24748199999999],[-92.93194599999993,71.22053500000004],[-92.93083199999995,71.2144320000001],[-92.92388900000003,71.20776399999994],[-92.854446,71.15138200000013],[-92.86277799999999,71.13943499999999],[-92.86915599999998,71.12803600000012],[-92.88861099999997,71.0747070000001],[-92.88999899999993,71.065811],[-92.90695199999993,70.9124910000001],[-93.03083800000002,70.87886000000009],[-93.04083300000002,70.87776200000002],[-93.04834,70.87387099999995],[-93.04611199999994,70.86720300000002],[-93.0427699999999,70.86387600000006],[-93.02749599999999,70.85276800000008],[-92.98249800000002,70.82554600000014],[-92.958618,70.81749000000008],[-92.92832899999996,70.81137100000001],[-92.91139199999998,70.80998200000005],[-92.81304899999998,70.80581700000005],[-92.68859899999995,70.77554299999997],[-92.67666600000001,70.77165200000007],[-92.64111299999996,70.71527100000003],[-92.63944999999995,70.70999100000012],[-92.64250199999998,70.7063750000001],[-92.62193300000001,70.68359400000003],[-92.59277299999997,70.68580600000013],[-92.43055700000002,70.66609199999999],[-92.41805999999997,70.66304000000008],[-92.20805399999995,70.61026000000004],[-92.19915800000001,70.60664400000002],[-92.16915899999998,70.59027100000014],[-92.15916399999998,70.58415200000007],[-92.15750100000002,70.57916300000011],[-92.15666199999998,70.5730440000001],[-92.16833500000001,70.56999200000001],[-92.19610599999999,70.57110599999999],[-92.22860700000001,70.57360800000004],[-92.245544,70.57138099999997],[-92.25,70.56971699999997],[-92.26501499999989,70.55192600000004],[-92.26501499999989,70.54803500000014],[-92.25,70.50138900000013],[-92.23805199999998,70.48719800000009],[-92.11665299999999,70.47082500000005],[-92.1100009999999,70.468323],[-91.99694799999997,70.39082300000007],[-91.98777799999999,70.35582000000011],[-91.99249299999997,70.32054099999999],[-91.99526999999995,70.316666],[-91.98554999999993,70.28970300000003],[-91.95973200000003,70.2586060000001],[-91.952225,70.25526400000012],[-91.94694500000003,70.25804100000005],[-91.94221499999998,70.26361099999997],[-91.92027300000001,70.29637099999997],[-91.900284,70.33082600000012],[-91.90361000000001,70.33720400000004],[-91.904449,70.34332300000011],[-91.89805599999994,70.34915200000012],[-91.890289,70.35443100000009],[-91.87805200000003,70.35832199999999],[-91.86749299999997,70.3602600000001],[-91.85305800000003,70.36137400000007],[-91.73721299999994,70.35859699999997],[-91.72972099999998,70.35693400000008],[-91.70388799999995,70.34526100000005],[-91.69888300000002,70.34248400000013],[-91.69387799999987,70.33638000000008],[-91.63612399999994,70.23165899999998],[-91.56527699999992,70.20054600000014],[-91.52416999999991,70.17915300000004],[-91.51362599999993,70.16720600000008],[-91.51194800000002,70.15887500000002],[-91.51139799999999,70.15277100000014],[-91.516953,70.14637800000003],[-91.52917499999995,70.14248700000013],[-91.54249599999991,70.14082300000013],[-91.57806399999993,70.13749700000011],[-91.91665599999999,70.11998000000006],[-91.95333900000003,70.1183170000001],[-91.97222899999991,70.11859100000004],[-92.00389099999995,70.12136800000013],[-92.02139299999999,70.12359600000008],[-92.03611799999993,70.12692300000003],[-92.04943800000001,70.132202],[-92.05749499999996,70.13693200000006],[-92.23443600000002,70.21220399999999],[-92.26834100000002,70.20887800000014],[-92.39306599999998,70.15054300000003],[-92.450287,70.0711060000001],[-92.43222000000003,70.07554600000009],[-92.285278,70.08970600000004],[-92.26834100000002,70.09054600000007],[-92.17748999999998,70.08831800000007],[-92.12999000000002,70.084991],[-92.0875089999999,70.07971199999997],[-92.02639799999997,70.06637600000005],[-91.99305699999996,70.05859400000008],[-91.98527499999994,70.05386400000003],[-91.93971299999998,70.020264],[-91.94665499999991,70.01582300000007],[-92.114441,69.95637500000004],[-92.14889499999992,69.94663999999995],[-92.20388799999995,69.92053199999998],[-92.36944599999998,69.84776300000004],[-92.54333500000001,69.78054800000007],[-92.658615,69.76110800000009],[-92.77861000000001,69.72221400000001],[-92.775284,69.7063750000001],[-92.56555200000003,69.71276899999998],[-92.55139200000002,69.7124940000001],[-92.53500400000001,69.709427],[-92.53527799999995,69.70526100000012],[-92.70973200000003,69.67387400000001],[-92.728882,69.67164600000001],[-92.74380500000001,69.67195100000004],[-92.77722199999994,69.67608600000005],[-92.858047,69.6827550000001],[-92.87138400000003,69.68248000000011],[-92.90888999999999,69.68054199999995],[-92.92277499999989,69.67942799999997],[-92.92361499999993,69.678314],[-92.92027300000001,69.66970800000007],[-92.89750699999996,69.66554300000007],[-92.83612099999999,69.655823],[-92.82749899999999,69.655823],[-92.69444299999998,69.65637200000015],[-92.634727,69.67108899999994],[-92.62937899999997,69.6735920000001],[-92.619057,69.67575800000009],[-92.5625,69.68748499999998],[-92.52362099999993,69.6927490000001],[-92.50695799999994,69.69358800000009],[-92.34083599999997,69.69413800000012],[-92.3058319999999,69.665817],[-92.20527600000003,69.6455380000001],[-92.09111000000001,69.62469500000003],[-92.08833300000003,69.62303200000008],[-92.08860799999997,69.61886599999997],[-92.09083599999991,69.6160890000001],[-92.11054999999993,69.61303699999996],[-92.122772,69.61219800000003],[-92.13417099999998,69.61248800000004],[-92.24360699999988,69.63026400000001],[-92.28195199999999,69.63998400000008],[-92.29110700000001,69.6413730000001],[-92.30055199999993,69.64166300000011],[-92.29750100000001,69.636932],[-92.12470999999994,69.55497700000006],[-92.08416699999998,69.54470800000001],[-91.93832399999991,69.51776100000012],[-91.80332900000002,69.49887099999995],[-91.80416899999989,69.50499000000002],[-91.79833999999994,69.51388500000002],[-91.49749800000001,69.65860000000009],[-91.48500100000001,69.66331500000013],[-91.47528099999994,69.6644290000001],[-91.45083599999998,69.65887499999991],[-91.41888399999993,69.65554800000001],[-91.31416300000001,69.65277100000009],[-91.221115,69.65332000000001],[-91.20222499999994,69.655258],[-91.18859900000001,69.65387000000004],[-91.09777799999995,69.63832100000013],[-91.09416199999998,69.63610800000004],[-91.091949,69.63165299999997],[-91.09527599999996,69.62664799999993],[-91.10194399999995,69.6208190000001],[-91.10583500000001,69.61914100000001],[-91.33444199999997,69.55276500000002],[-91.36082499999992,69.54553199999998],[-91.38055400000002,69.54248000000007],[-91.396118,69.54109199999999],[-91.460556,69.53970300000015],[-91.49472000000003,69.5372010000001],[-91.51445000000001,69.53414899999996],[-91.56277499999993,69.52249100000012],[-91.57028199999996,69.52026400000005],[-91.56639100000001,69.51470899999998],[-91.55777,69.50804100000005],[-91.553879,69.50555400000013],[-91.40222199999994,69.52221700000001],[-91.333618,69.53498800000011],[-91.32167099999992,69.53887900000001],[-91.19221500000003,69.56275900000003],[-91.17971799999998,69.55886800000013],[-91.16027799999989,69.54609700000003],[-91.15055799999999,69.5372010000001],[-91.14666699999992,69.5316620000001],[-91.14361600000001,69.52526899999992],[-91.13861099999986,69.51915000000008],[-91.12832600000002,69.51416000000006],[-91.11416600000001,69.51081799999992],[-91.10278299999999,69.50888100000009],[-90.96972700000003,69.51138300000014],[-90.83000199999992,69.484985],[-90.75862099999995,69.4827580000001],[-90.75195300000001,69.48719800000015],[-90.75140399999987,69.49275200000011],[-90.75805700000001,69.50138900000013],[-90.75584399999997,69.50721700000008],[-90.75418100000002,69.50915500000002],[-90.71610999999996,69.53942900000004],[-90.69860799999992,69.53942900000004],[-90.65110800000002,69.534424],[-90.53666699999991,69.51388500000002],[-90.49333200000001,69.50416600000005],[-90.43666100000002,69.48970000000003],[-90.31861900000001,69.45443700000004],[-90.30776999999995,69.45027200000004],[-90.30776999999995,69.44720500000011],[-90.319458,69.44053600000001],[-90.34445199999999,69.43220500000012],[-90.35804699999994,69.42970300000007],[-90.39639299999988,69.4285890000001],[-90.41139199999992,69.43136599999997],[-90.42748999999998,69.44081100000005],[-90.43360899999999,69.44497699999994],[-90.43832399999997,69.44802900000008],[-90.45056199999999,69.45027200000004],[-90.46333299999992,69.44859300000002],[-90.49333200000001,69.44081100000005],[-90.55555699999996,69.42248500000005],[-90.61389199999991,69.451096],[-90.62193299999996,69.45332300000001],[-90.70361299999996,69.45359800000006],[-90.704453,69.45138500000007],[-90.69860799999992,69.44609100000014],[-90.63694800000002,69.42970300000007],[-90.58583099999998,69.41914400000002],[-90.58222999999992,69.41693100000003],[-90.58473200000003,69.41415399999994],[-90.60082999999997,69.40859999999998],[-90.69499199999996,69.3897090000001],[-90.70527599999997,69.3877720000001],[-90.718613,69.3877720000001],[-90.74137899999994,69.38275099999993],[-90.79028299999999,69.36276200000003],[-90.80943299999996,69.34220900000014],[-90.81304899999992,69.33831800000007],[-90.81582600000002,69.333328],[-90.81861900000001,69.29859899999997],[-90.81500199999999,69.29332],[-90.80860899999999,69.28749099999999],[-90.80555700000002,69.28276100000011],[-90.803879,69.25972000000007],[-90.80471799999992,69.255829],[-90.80943299999996,69.25332600000002],[-90.82223499999998,69.25166300000012],[-90.903885,69.24636800000007],[-90.920837,69.24636800000007],[-90.93138099999993,69.24748200000005],[-91.08111599999995,69.26693699999998],[-91.21472199999994,69.29026800000008],[-91.29638699999992,69.3119200000001],[-91.34527600000001,69.32804900000002],[-91.35583499999996,69.33221400000002],[-91.42639199999996,69.35054000000002],[-91.43859900000001,69.35276800000003],[-91.44722000000002,69.35276800000003],[-91.44665500000002,69.34971600000006],[-91.43194599999998,69.33859300000006],[-91.33528100000001,69.30442800000014],[-91.13055399999996,69.24192800000003],[-91.03138699999994,69.21832300000005],[-90.91888399999993,69.16081200000008],[-90.89500399999997,69.15081800000007],[-90.81500199999999,69.13360600000004],[-90.66471899999999,69.08332800000005],[-90.65499899999992,69.07804900000008],[-90.65417499999995,69.07609599999995],[-90.654449,69.07054100000005],[-90.660553,69.05998200000005],[-90.66944899999993,69.04998799999998],[-90.58389299999999,68.92886400000003],[-90.54499800000002,68.91110200000014],[-90.52888499999995,68.90860000000009],[-90.47444200000001,68.89054900000008],[-90.43638599999991,68.87441999999999],[-90.41944899999999,68.84082000000006],[-90.44610599999999,68.77970900000014],[-90.44915800000001,68.77609300000006],[-90.45417799999996,68.77360500000009],[-90.464722,68.770828],[-90.47833299999996,68.76832600000012],[-90.49249299999997,68.76776100000006],[-90.49749800000001,68.76832600000012],[-90.50111399999997,68.770828],[-90.51390099999998,68.75915500000013],[-90.52667200000002,68.74443100000013],[-90.52778599999999,68.736649],[-90.52250700000002,68.72998000000007],[-90.506958,68.72499099999993],[-90.48028599999992,68.70776400000011],[-90.479172,68.705826],[-90.47444200000001,68.53082299999994],[-90.50973499999998,68.49525499999993],[-90.519455,68.48748799999998],[-90.52833599999991,68.4833220000001],[-90.55777,68.47470099999998],[-90.58473200000003,68.46554600000013],[-90.603882,68.45582600000006],[-90.60777299999995,68.451096],[-90.60665899999998,68.44609100000014],[-90.603882,68.43969700000008],[-90.60139500000002,68.43637100000007],[-90.55999799999995,68.42359900000002],[-90.52389499999998,68.41442899999998],[-90.46694899999989,68.40386999999998],[-90.36193800000001,68.38415500000013],[-90.33277900000002,68.37803600000012],[-90.31750499999998,68.37330600000007],[-90.31500199999999,68.36998000000006],[-90.31916799999999,68.3683170000001],[-90.34388699999994,68.36526500000002],[-90.36749299999991,68.34526100000011],[-90.27139299999999,68.23887600000012],[-90.25500499999993,68.23275799999999],[-90.23277299999995,68.23027000000002],[-90.20722999999992,68.23109399999998],[-90.178604,68.23580900000002],[-90.144455,68.24386600000003],[-90.13221699999991,68.24859600000002],[-90.12277199999994,68.25360100000006],[-90.11972000000003,68.25721699999997],[-90.11805700000002,68.26220699999999],[-90.03860499999996,68.35220299999997],[-89.985275,68.39610299999998],[-89.912216,68.46720900000003],[-89.89306599999992,68.54331999999994],[-89.91166699999997,68.54748499999994],[-89.91999800000002,68.55358899999999],[-89.92777999999998,68.56359900000007],[-89.94860799999998,68.59942600000005],[-89.95056199999999,68.60386699999998],[-89.94972199999995,68.60775800000005],[-89.89472999999987,68.65248100000008],[-89.80972300000002,68.71026599999999],[-89.80248999999992,68.71220399999993],[-89.78916899999996,68.71026599999999],[-89.78056300000003,68.705826],[-89.76333599999992,68.69053600000001],[-89.75750700000003,68.68470800000006],[-89.74694799999997,68.66970800000013],[-89.729172,68.69914200000011],[-89.69332899999995,68.76388500000002],[-89.68472300000002,68.81025700000009],[-89.68749999999994,68.81971699999997],[-89.68998699999992,68.82470700000005],[-89.714722,68.84693900000008],[-89.73388699999992,68.88165300000014],[-89.73916600000001,68.89276100000012],[-89.75695799999988,68.93997200000001],[-89.75556899999998,68.954163],[-89.75306699999999,68.958328],[-89.71665999999999,69.00610400000011],[-89.70722999999992,69.0147090000001],[-89.70056199999999,69.01915000000002],[-89.68443300000001,69.0288700000001],[-89.66610700000001,69.03831500000001],[-89.64416499999999,69.04832500000009],[-89.58277900000002,69.06860400000005],[-89.56082200000003,69.07720900000004],[-89.52935799999995,69.09060699999998],[-89.48999000000003,69.11053500000003],[-89.48249799999991,69.11554000000007],[-89.458618,69.13360600000004],[-89.402222,69.17886399999998],[-89.39862099999993,69.18248],[-89.39445499999994,69.19303900000006],[-89.39445499999994,69.199142],[-89.39695699999993,69.20860299999998],[-89.39445499999994,69.21443199999999],[-89.38999899999993,69.21914700000002],[-89.32223499999992,69.24720800000011],[-89.30665599999992,69.25138900000002],[-89.258621,69.25999500000012],[-89.220551,69.26666300000005],[-89.17416400000002,69.27331500000014],[-89.13417099999998,69.27554299999991],[-89.11444099999989,69.27526899999998],[-89.09056099999998,69.27192700000006],[-89.04998799999998,69.2644350000001],[-89.03805499999987,69.26193199999994],[-88.999435,69.25138900000002],[-88.96888699999994,69.24136400000009],[-88.94248999999996,69.22998000000001],[-88.93804899999998,69.22692899999998],[-88.93554699999999,69.22221400000012],[-88.93472300000002,69.219986],[-88.9375,69.21415699999994],[-88.93666099999996,69.20915200000007],[-88.92999299999997,69.19802900000013],[-88.87026999999995,69.14860500000009],[-88.85943599999996,69.14221199999997],[-88.78250100000002,69.10304300000007],[-88.77250700000002,69.09887699999996],[-88.62388599999997,69.042755],[-88.48028599999998,68.99887100000007],[-88.45722999999992,68.99275200000005],[-88.406113,68.98275800000005],[-88.27084400000001,68.93498199999993],[-88.208618,68.911652],[-88.197769,68.90664700000013],[-88.11582900000002,68.86053500000008],[-88.08222999999998,68.8413700000001],[-88.05221599999999,68.8230440000001],[-88.03832999999997,68.81414799999999],[-87.97166400000003,68.76609799999994],[-87.96444699999995,68.76054399999998],[-87.947769,68.73165900000009],[-87.92166099999992,68.67303500000003],[-87.91665599999999,68.65637200000015],[-87.91749600000003,68.64749100000006],[-87.92500299999995,68.632477],[-87.93499799999995,68.61943100000002],[-87.9424899999999,68.61080900000002],[-87.947769,68.60525500000006],[-87.93388399999998,68.57693500000005],[-87.9241639999999,68.559708],[-87.883621,68.49443099999996],[-87.88137799999998,68.49108900000004],[-87.84167500000001,68.43248],[-87.835556,68.42442299999999],[-87.81750499999993,68.41720600000008],[-87.79861499999998,68.40525800000006],[-87.791672,68.39833099999998],[-87.78971899999993,68.3919370000001],[-87.789444,68.38665800000012],[-87.79222099999993,68.334427],[-87.80055199999993,68.3119200000001],[-87.84527600000001,68.24775700000009],[-87.84889199999986,68.24414100000001],[-87.92916899999994,68.197205],[-87.93582200000003,68.19581599999998],[-87.94694500000003,68.19859300000007],[-88.10665899999987,68.242752],[-88.22193900000002,68.36554000000001],[-88.38444500000003,68.29109200000005],[-88.39222699999999,68.28749099999999],[-88.39555399999995,68.28526300000004],[-88.40167199999996,68.28027299999997],[-88.40333599999991,68.27554299999997],[-88.40278599999988,68.270264],[-88.39834599999995,68.2605440000001],[-88.380829,68.24552900000009],[-88.36193799999995,68.23387100000008],[-88.34249899999998,68.22360200000003],[-88.33473200000003,68.21748400000013],[-88.33084100000002,68.21304300000003],[-88.27972399999993,68.11804199999995],[-88.27749599999999,68.111649],[-88.27778599999999,68.105545],[-88.28306599999996,68.09999099999999],[-88.31555199999997,68.08610499999998],[-88.33168,68.07638500000007],[-88.33833299999998,68.0705410000001],[-88.3411099999999,68.06498700000009],[-88.34777799999995,68.03720100000004],[-88.36694299999999,68.03166200000004],[-88.381104,68.0252690000001],[-88.37277199999994,67.96887200000009],[-88.370834,67.95915200000002],[-88.36860699999994,67.95443699999998],[-88.285278,67.81721500000009],[-88.27639799999997,67.80304000000001],[-88.26916499999999,67.79359400000004],[-88.160553,67.68247999999994],[-88.15110799999991,67.67330900000002],[-88.13944999999995,67.66442899999998],[-88.12499999999994,67.65554800000001],[-88.09583999999995,67.64248700000007],[-88.06610099999995,67.63472000000013],[-88.00917099999992,67.62275700000009],[-87.97999600000003,67.61581400000011],[-87.96528599999999,67.61164900000011],[-87.95584100000002,67.607483],[-87.88137799999998,67.56805400000013],[-87.841385,67.53610200000014],[-87.827225,67.52720600000004],[-87.78916900000002,67.50526399999995],[-87.62304699999993,67.4124910000001],[-87.60638399999993,67.40386999999998],[-87.58500700000002,67.39526400000005],[-87.53694200000001,67.37886000000009],[-87.46083099999998,67.34414700000013],[-87.35777300000001,67.26220700000005],[-87.35916099999997,67.24748200000005],[-87.36193800000001,67.24220300000007],[-87.42916899999994,67.20860300000004],[-87.44055199999997,67.20498700000013],[-87.48666400000002,67.19413800000007],[-87.49777199999994,67.19053600000012],[-87.50556899999998,67.18525699999998],[-87.51139799999999,67.1749880000001],[-87.51194800000002,67.16998300000006],[-87.516953,67.11554000000012],[-87.51028400000001,67.11219800000015],[-87.49749800000001,67.11526500000008],[-87.32278400000001,67.16276600000015],[-87.2408289999999,67.21609499999994],[-87.11776699999996,67.2127690000001],[-87.06973299999993,67.21943700000008],[-86.96861299999995,67.24525500000004],[-86.96305799999999,67.25054899999998],[-86.96749899999998,67.25526400000001],[-87.00889599999994,67.28221100000013],[-87.07556199999993,67.32720900000004],[-87.08667000000003,67.33637999999996],[-87.09056099999992,67.34582500000005],[-87.08999599999999,67.35081500000013],[-87.08139,67.35443099999998],[-86.874435,67.40498400000013],[-86.804169,67.42082199999999],[-86.79222099999987,67.42248500000011],[-86.77917500000001,67.422211],[-86.76528899999994,67.41914400000007],[-86.70973199999997,67.38804600000003],[-86.68916300000001,67.3744200000001],[-86.68472300000002,67.36998000000006],[-86.67555199999998,67.36554000000007],[-86.64723200000003,67.35832200000004],[-86.59249899999998,67.34526100000011],[-86.57972699999999,67.34498600000006],[-86.54388399999993,67.34498600000006],[-86.53195199999999,67.34664900000001],[-86.52362099999999,67.35220300000003],[-86.51806599999998,67.35720800000007],[-86.50917099999998,67.36775200000011],[-86.50306699999993,67.37776200000002],[-86.47389199999998,67.46859699999999],[-86.47277799999989,67.47859200000005],[-86.47444200000001,67.4833220000001],[-86.49499499999996,67.49693300000007],[-86.48500100000001,67.51693699999998],[-86.452225,67.59248400000013],[-86.45140100000003,67.59748800000011],[-86.45584099999996,67.60192900000004],[-86.46528599999994,67.60636900000003],[-86.47972099999998,67.61053500000014],[-86.48889200000002,67.61469999999997],[-86.52139299999993,67.67192100000011],[-86.525284,67.68136600000014],[-86.5080569999999,67.69720500000011],[-86.35916099999992,67.82777399999998],[-86.35055499999999,67.83332799999994],[-86.2869419999999,67.86997999999994],[-86.098053,67.97804300000001],[-86.04138199999994,68.00054900000003],[-86.02972399999993,68.00499000000013],[-86.00500499999998,68.008331],[-85.99221799999998,68.00915500000013],[-85.97999599999991,68.01165800000012],[-85.898346,68.04609700000015],[-85.89250199999998,68.05137600000012],[-85.89083899999997,68.06137100000007],[-85.91250600000001,68.08471700000007],[-85.91639699999996,68.09414700000013],[-85.91444399999995,68.10415599999999],[-85.88806199999999,68.18969700000014],[-85.84277299999997,68.31721499999998],[-85.83917200000002,68.32138100000009],[-85.71278399999994,68.41165200000012],[-85.72694399999995,68.48637400000001],[-85.73332199999999,68.59860200000008],[-85.67527799999999,68.71110499999998],[-85.66361999999992,68.7269290000001],[-85.64584399999995,68.7374880000001],[-85.63389599999994,68.74192800000014],[-85.62026999999995,68.7416530000001],[-85.60638399999999,68.74026500000002],[-85.59167500000001,68.73719800000009],[-85.56945799999994,68.728317],[-85.55804399999994,68.726089],[-85.49444599999993,68.7369230000001],[-85.48194899999993,68.73942600000004],[-85.46617100000003,68.74999200000013],[-85.46416499999992,68.75299100000012],[-85.46472199999994,68.75972000000002],[-85.50778199999996,68.766663],[-85.55082700000003,68.77331500000008],[-85.56277499999999,68.776657],[-85.55360399999995,68.78109700000005],[-85.54083300000002,68.78276100000005],[-85.51417500000002,68.78387500000002],[-85.45805399999995,68.77777099999997],[-85.415009,68.770828],[-85.37138399999998,68.7622070000001],[-85.36166400000002,68.75776700000006],[-85.36805699999996,68.75248699999997],[-85.37943999999999,68.747208],[-85.38833599999998,68.74192800000014],[-85.38417099999998,68.73719800000009],[-85.32861299999996,68.72499099999993],[-85.31416299999995,68.72276299999999],[-85.228882,68.71026599999999],[-85.21583599999997,68.71081500000014],[-85.20916699999998,68.71499600000004],[-85.21083099999998,68.71971100000007],[-85.21945199999999,68.72915599999993],[-85.22666900000002,68.73359700000003],[-85.14834599999995,68.75000000000011],[-85.06750499999993,68.7497100000001],[-84.91278099999994,68.74693300000001],[-84.898056,68.74247700000006],[-84.883896,68.74026500000002],[-84.80110200000001,68.73414600000001],[-84.78721599999994,68.73359700000003],[-84.775284,68.73719800000009],[-84.76750199999992,68.747208],[-84.76000999999991,68.75721700000003],[-84.752792,68.76748700000013],[-84.7541809999999,68.77221700000001],[-84.761124,68.77693200000004],[-84.83473200000003,68.8205410000001],[-84.84666400000003,68.82388300000008],[-84.86082499999998,68.82527200000004],[-84.89999399999994,68.8205410000001],[-84.912216,68.81805400000002],[-84.976944,68.80941800000011],[-85.00361599999991,68.80831899999998],[-85.031677,68.81080600000001],[-85.13194299999992,68.82693499999999],[-85.14388999999994,68.83027600000003],[-85.16305499999993,68.83915700000011],[-85.17721599999993,68.8483280000001],[-85.18415800000002,68.85304300000013],[-85.19276400000001,68.86219800000015],[-85.19444299999986,68.86720300000002],[-85.19082600000002,68.87220800000006],[-85.17777999999998,68.87359600000002],[-85.15306099999998,68.87303200000002],[-85.125,68.87025499999999],[-85.05332900000002,68.85887100000002],[-85.03999299999998,68.85942100000005],[-85.00556899999992,68.87747200000007],[-85.00195299999996,68.88247700000011],[-84.99749799999995,68.92581200000006],[-85.00723299999987,68.93026700000013],[-85.02111799999994,68.93165600000009],[-85.04666099999997,68.92665100000005],[-85.05999800000001,68.92581200000006],[-85.08805799999999,68.92858899999999],[-85.11694299999994,68.93331900000004],[-85.12943999999993,68.9374850000001],[-85.136124,68.94220000000013],[-85.14056399999993,68.94664],[-85.13694799999996,68.95193500000005],[-85.12777699999992,68.95610000000005],[-85.115005,68.95860300000004],[-85.08750899999995,68.95803799999999],[-84.97378500000002,68.9468690000001],[-84.91471899999999,68.93803400000007],[-84.818893,68.92776500000002],[-84.80583199999995,68.92915299999993],[-84.79638699999998,68.93359400000003],[-84.79138199999994,68.94331399999993],[-84.79333499999996,68.94831800000009],[-84.79998799999987,68.95277400000003],[-84.80943300000001,68.95721400000002],[-84.82194500000003,68.96165500000012],[-84.837219,68.96582000000012],[-84.85139499999997,68.96832300000011],[-84.86555499999992,68.96971100000002],[-84.90695199999993,68.97164900000013],[-84.92138699999998,68.97387700000007],[-84.93611099999993,68.97720300000015],[-84.98692299999993,68.99951199999998],[-84.98167399999994,69.00749200000001],[-84.95777900000002,69.01748700000007],[-84.94444299999998,69.01805100000001],[-84.83639499999992,69.01277200000004],[-84.72000099999997,69.00694300000004],[-84.59167499999995,68.99443100000008],[-84.57806399999998,68.99386600000003],[-84.56555200000003,68.9974820000001],[-84.541382,69.00721699999997],[-84.53222700000003,69.01249700000005],[-84.52833599999997,69.01748700000007],[-84.53527799999995,69.02221700000013],[-84.56361399999997,69.02581800000002],[-84.745544,69.03970300000009],[-84.95388799999995,69.08581500000014],[-85.108337,69.11331200000012],[-85.020554,69.16026299999993],[-85.00695799999994,69.16081200000008],[-84.99415599999992,69.16331500000007],[-84.98750299999995,69.16859400000004],[-84.99471999999997,69.17303500000014],[-85.008896,69.17442300000005],[-85.06471299999993,69.17692600000004],[-85.14377599999995,69.16709100000003],[-85.15177899999998,69.16609199999994],[-85.159111,69.16410100000007],[-85.163277,69.16159800000008],[-85.15527299999997,69.15310700000009],[-85.1766659999999,69.14360000000005],[-85.19749499999995,69.13275099999998],[-85.210556,69.13026400000012],[-85.22361799999999,69.12886000000009],[-85.23693799999995,69.12803600000012],[-85.25140399999998,69.13026400000012],[-85.266663,69.13360600000004],[-85.308334,69.14360000000005],[-85.31555200000003,69.14804100000015],[-85.31750499999998,69.15277100000003],[-85.308044,69.15803499999998],[-85.29611199999988,69.1624910000001],[-85.28332499999988,69.16526799999997],[-85.23500100000001,69.17469800000003],[-85.22750100000002,69.176872],[-85.22683699999999,69.17987099999999],[-85.23116299999998,69.18254100000007],[-85.24082900000002,69.192474],[-85.25473,69.19274900000005],[-85.337784,69.19386300000002],[-85.38305700000001,69.20555100000007],[-85.39277600000003,69.20999100000006],[-85.47332799999992,69.27192700000006],[-85.47778299999987,69.27638200000007],[-85.50306699999993,69.31442300000009],[-85.50805700000001,69.395264],[-85.506958,69.40026900000004],[-85.50334199999998,69.405258],[-85.49415599999992,69.41081200000002],[-85.48194899999993,69.41526799999997],[-85.46749899999992,69.41720600000008],[-85.45333900000003,69.41693100000003],[-85.42443799999995,69.41331500000001],[-85.39611799999994,69.41165200000006],[-85.38333099999994,69.41526799999997],[-85.33917200000002,69.43887300000011],[-85.343613,69.44358799999998],[-85.35360699999995,69.44802900000008],[-85.37887599999993,69.45664999999997],[-85.39416499999993,69.46081500000014],[-85.42277499999994,69.46249399999999],[-85.43638599999991,69.46081500000014],[-85.445831,69.45637499999998],[-85.46501199999994,69.44081100000005],[-85.47721899999999,69.43637100000001],[-85.491379,69.43664600000005],[-85.50083899999998,69.4391480000001],[-85.51083399999999,69.44358799999998],[-85.525284,69.45277400000009],[-85.53889499999997,69.46693399999998],[-85.54249600000003,69.47637900000007],[-85.547775,69.64721700000007],[-85.54695100000004,69.65220600000004],[-85.514725,69.76805100000007],[-85.450287,69.78471400000012],[-85.42332499999998,69.78887900000012],[-85.40916399999998,69.78858900000012],[-85.39389,69.7852630000001],[-85.38917499999997,69.78054800000007],[-85.38999899999993,69.77581800000002],[-85.39416499999993,69.77053799999999],[-85.40695199999993,69.76026900000011],[-85.41082799999998,69.75526400000007],[-85.406387,69.75054900000003],[-85.39195299999994,69.7502750000001],[-85.37916599999994,69.75360100000012],[-85.36665299999999,69.75804099999999],[-85.34249899999998,69.76887500000004],[-85.33306899999997,69.77415500000012],[-85.331955,69.77915999999999],[-85.34445199999999,69.81303399999996],[-85.34916699999991,69.81749000000008],[-85.36193800000001,69.82193000000007],[-85.37721299999993,69.82415800000007],[-85.43360899999993,69.82360800000004],[-85.46139499999998,69.82249500000012],[-85.48999000000003,69.8230440000001],[-85.51861599999995,69.82360800000004],[-85.56138599999997,69.82470699999999],[-85.58639499999998,69.82693499999993],[-85.58222999999998,69.8458250000001],[-85.57861300000002,69.85081500000013],[-85.57194500000003,69.8560940000001],[-85.561935,69.85942100000005],[-85.54804999999993,69.859985],[-85.37721299999993,69.85108900000006],[-85.36193800000001,69.84887700000002],[-85.31555200000003,69.83804299999997],[-85.27416999999991,69.82527200000004],[-85.22250400000001,69.80802900000009],[-85.21250900000001,69.8035890000001],[-85.199432,69.79914900000006],[-85.17083699999995,69.79054299999996],[-85.093887,69.77331500000003],[-85.07917799999996,69.77110299999998],[-85.064438,69.76998900000001],[-84.87165800000002,69.8160860000001],[-84.86471599999993,69.82110599999993],[-84.854172,69.83137499999998],[-84.57417299999992,69.85748300000012],[-84.54638699999987,69.85942100000005],[-84.47666900000002,69.86219800000015],[-84.43360899999993,69.86109899999997],[-84.37582399999997,69.85748300000012],[-84.34666399999998,69.85470600000002],[-84.33168,69.85220300000003],[-84.16944899999999,69.82222000000013],[-84.12582399999991,69.80941800000011],[-84.118607,69.80470300000007],[-84.11416599999995,69.79998800000004],[-84.11222099999998,69.79359399999998],[-84.10417199999995,69.78581200000002],[-84.09167499999995,69.78137200000003],[-83.97193899999996,69.74971000000005],[-83.941666,69.74304200000012],[-83.74861099999993,69.70887800000008],[-83.73388699999998,69.70664999999991],[-83.70500199999992,69.703598],[-83.60388199999994,69.69358800000009],[-83.589447,69.69220000000001],[-83.36054999999999,69.67637600000006],[-83.34638999999999,69.67608600000005],[-83.33306900000002,69.678314],[-83.30638099999993,69.69386299999991],[-83.29361,69.69914200000011],[-83.28056299999992,69.70248400000003],[-83.25334199999998,69.70526100000012],[-83.23889200000002,69.70471199999997],[-83.18055700000002,69.69497700000011],[-83.122772,69.68914800000005],[-83.02194199999997,69.67970300000002],[-83.00805699999995,69.67915299999999],[-82.82695000000001,69.68887300000006],[-82.69665499999996,69.69581600000004],[-82.54100799999998,69.67447700000014],[-82.53967299999994,69.67159300000009],[-82.53616299999987,69.66882300000003],[-82.52732800000001,69.66615300000012],[-82.50950599999987,69.66197999999997],[-82.50067100000001,69.66049199999998],[-82.48332999999997,69.6579900000001],[-82.45750399999997,69.655327],[-82.291672,69.63998400000008],[-82.26333599999998,69.63804600000014],[-82.25473,69.63638300000002],[-82.30749500000002,69.62220800000011],[-82.33473199999997,69.61943100000002],[-82.390289,69.61886599999997],[-82.47066499999994,69.62303200000008],[-82.47633399999995,69.62587000000008],[-82.48366499999997,69.62853999999999],[-82.4925,69.630043],[-82.55233799999996,69.63537600000001],[-82.56083699999999,69.63570400000015],[-82.56899999999996,69.63487200000009],[-82.57700299999999,69.63287400000013],[-82.653885,69.62303200000008],[-82.65472399999999,69.56860400000011],[-82.612503,69.5669400000001],[-82.600281,69.5624850000001],[-82.535278,69.53498800000011],[-82.48998999999998,69.50721700000008],[-82.47666899999996,69.49775699999998],[-82.4869379999999,69.4935910000001],[-82.50056499999994,69.49220300000002],[-82.52888499999995,69.4952550000001],[-82.74221799999998,69.50999500000006],[-82.89750700000002,69.5188750000001],[-82.93971299999993,69.52137800000008],[-82.98222399999992,69.52415499999995],[-83.06777999999991,69.53305100000006],[-83.12554899999992,69.53997800000002],[-83.15417500000001,69.54386900000009],[-83.22805799999998,69.538589],[-83.08250399999997,69.51416000000006],[-83.025284,69.50804100000005],[-82.95472699999999,69.503601],[-82.87027,69.50027499999999],[-82.85665899999992,69.50082400000008],[-82.84249899999992,69.50027499999999],[-82.78527799999995,69.49414100000013],[-82.68472300000002,69.47970600000002],[-82.32417299999992,69.41886899999997],[-82.29527299999995,69.41387900000012],[-82.23721299999994,69.40081800000002],[-82.225281,69.39637799999997],[-82.22138999999993,69.39166299999994],[-82.23167399999994,69.38749700000005],[-82.28971899999999,69.25166300000012],[-82.291382,69.24664300000006],[-82.273056,69.23748800000004],[-82.25862099999995,69.23387100000008],[-82.24499500000002,69.2333220000001],[-82.21722399999993,69.23304700000011],[-82.20361299999996,69.23359700000015],[-82.05444299999999,69.24136400000009],[-82.04110700000001,69.242752],[-82.02778599999999,69.24497999999994],[-81.99129499999998,69.25470700000011],[-81.91471899999988,69.26944000000015],[-81.70777899999996,69.26470900000004],[-81.69387799999998,69.26304600000014],[-81.67971799999998,69.26054400000004],[-81.650284,69.25166300000012],[-81.51222200000001,69.20138500000013],[-81.4163969999999,69.2080380000001],[-81.402222,69.20721400000014],[-81.38833599999998,69.20471200000009],[-81.35972599999997,69.19664000000012],[-81.347778,69.19192500000008],[-81.33889799999997,69.18748500000004],[-81.33250399999986,69.18248],[-81.29943800000001,69.1202550000001],[-81.33084100000002,69.09526100000011],[-81.57028200000002,68.99247700000001],[-81.59584000000001,68.98414600000012],[-81.71665999999999,68.94914200000005],[-81.75556899999998,68.94136000000009],[-81.80943300000001,68.9327550000001],[-81.88806199999999,68.91914400000013],[-81.91416900000002,68.9144290000001],[-81.96611000000001,68.90443399999998],[-82.00500499999998,68.89553800000004],[-82.04305999999997,68.88388100000009],[-82.05555699999996,68.87858600000004],[-82.05721999999997,68.87387100000001],[-82.04333500000001,68.87220800000006],[-82.00306699999993,68.87414600000005],[-81.97721899999999,68.87970000000001],[-81.83306899999997,68.90721100000007],[-81.819458,68.90860000000009],[-81.68638599999997,68.90525800000012],[-81.67304999999999,68.90443399999998],[-81.66194200000001,68.90277100000003],[-81.650284,68.89915500000001],[-81.58805799999999,68.86970500000012],[-81.58195499999994,68.86499000000009],[-81.43832399999997,68.87498499999998],[-81.424713,68.87553400000013],[-81.382767,68.86665299999999],[-81.35417199999989,68.85748300000012],[-81.23805199999993,68.77470400000004],[-81.23443599999996,68.76998900000001],[-81.23277299999995,68.76026899999994],[-81.25222799999995,68.65304600000013],[-81.25584399999991,68.64305100000001],[-81.26055899999994,68.63804600000014],[-81.26750199999992,68.6330410000001],[-81.35777300000001,68.59915200000012],[-81.560272,68.5416560000001],[-81.68721,68.50943000000007],[-81.79888900000003,68.48970000000003],[-81.8163909999999,68.46971100000013],[-81.83029199999999,68.45971700000013],[-81.84249899999992,68.45555100000001],[-81.95805399999995,68.42330900000002],[-81.97083999999995,68.42109700000015],[-81.99777199999994,68.42303500000008],[-82.01194799999996,68.42776500000014],[-82.02444499999996,68.43691999999999],[-82.02778599999999,68.44165000000004],[-82.02888499999995,68.44664000000006],[-82.03332499999999,68.45609999999999],[-82.03805499999993,68.46582000000006],[-82.04167199999995,68.4705350000001],[-82.06220999999994,68.49443099999996],[-82.0686189999999,68.499146],[-82.07749899999993,68.503601],[-82.09167500000001,68.50721700000008],[-82.229446,68.5316620000001],[-82.256393,68.53360000000004],[-82.26945499999994,68.53248600000006],[-82.27111799999994,68.52748100000002],[-82.26722699999999,68.52276599999999],[-82.25473,68.51332100000013],[-82.24305699999996,68.50888100000009],[-82.22917199999989,68.50526400000012],[-82.1875,68.4958190000001],[-82.17582699999991,68.49136400000003],[-82.17332499999992,68.48580899999996],[-82.17500299999995,68.48109399999993],[-82.179169,68.47608900000006],[-82.18360899999993,68.47110000000009],[-82.19055200000003,68.46609500000005],[-82.20249899999999,68.46081500000003],[-82.21501199999989,68.45748900000012],[-82.22805799999998,68.45526100000001],[-82.25418099999996,68.45443700000004],[-82.382767,68.46693400000004],[-82.39389,68.468323],[-82.44888299999997,68.47859200000005],[-82.47694399999995,68.48553500000003],[-82.50029,68.49443099999996],[-82.53250100000002,68.50804100000005],[-82.54527300000001,68.51748700000002],[-82.5491639999999,68.52221700000007],[-82.55777,68.5269320000001],[-82.571396,68.52638200000007],[-82.58389299999988,68.52415500000001],[-82.60888699999992,68.51748700000002],[-82.62110899999999,68.51220699999993],[-82.63473499999998,68.5022130000001],[-82.63890100000003,68.49720800000006],[-82.63528400000001,68.49220300000002],[-82.4911039999999,68.4538730000001],[-82.49055499999992,68.40220599999992],[-82.36305199999998,68.35054000000008],[-82.35665899999992,68.34582500000005],[-82.35305799999998,68.341095],[-82.35110500000002,68.3313750000001],[-82.35249299999992,68.32666000000006],[-82.35665899999992,68.32165500000002],[-82.36944599999993,68.318329],[-82.38194299999992,68.31693999999999],[-82.39527899999996,68.31666600000005],[-82.42222599999997,68.318604],[-82.44860799999998,68.32083100000006],[-82.47500600000001,68.32110600000004],[-82.50083899999998,68.31749000000002],[-82.50778199999996,68.31330900000012],[-82.50140399999998,68.30859400000008],[-82.48361199999994,68.29942299999993],[-82.42610199999996,68.27665700000011],[-82.40055799999993,68.26887499999998],[-82.38694799999996,68.26638800000006],[-82.37388599999997,68.26554899999996],[-82.36082499999992,68.26693700000004],[-82.31166100000002,68.283051],[-82.2869419999999,68.28970300000003],[-82.27333099999993,68.28887900000007],[-82.264725,68.28442400000006],[-82.26000999999997,68.27499399999999],[-82.25917099999998,68.26998900000012],[-82.25862099999995,68.25555400000002],[-82.2644499999999,68.24552900000009],[-82.27027900000002,68.23553500000008],[-82.27861000000001,68.22554000000002],[-82.28944399999995,68.21554599999996],[-82.30055199999987,68.20555100000007],[-82.321121,68.19026200000002],[-82.33029199999987,68.18525699999992],[-82.33721899999995,68.18026700000007],[-82.34555099999994,68.17025800000005],[-82.34722899999997,68.16526800000003],[-82.34583999999995,68.16053799999997],[-82.33721899999995,68.15582300000011],[-82.31443799999994,68.14665200000002],[-82.27250699999996,68.13333100000006],[-82.23083500000001,68.12191800000005],[-82.20611599999995,68.115814],[-82.19248999999996,68.11248799999998],[-82.179169,68.111649],[-82.16639700000002,68.1141510000001],[-82.145782,68.12548800000002],[-82.09916699999997,68.15498400000001],[-82.08056599999992,68.17970300000013],[-82.06361400000003,68.19970700000005],[-82.05694599999998,68.20471200000009],[-82.0475009999999,68.20971699999996],[-82.0375059999999,68.21388199999996],[-82.02500900000001,68.21609500000011],[-82.01167299999986,68.21470599999992],[-81.99777199999994,68.21110500000009],[-81.98889200000002,68.20665000000002],[-81.98554999999999,68.20166],[-81.98472600000002,68.19692999999995],[-81.99305700000002,68.17248500000011],[-82.00889599999994,68.14776599999999],[-82.01916499999999,68.13275100000004],[-82.02722199999994,68.12275699999998],[-82.03416400000003,68.11775199999994],[-82.04361,68.11276200000009],[-82.056107,68.10942100000005],[-82.11450200000002,68.08287000000001],[-82.17388900000003,68.00248699999997],[-82.17555199999998,67.9974820000001],[-82.10278299999999,67.90721100000007],[-82.09666399999998,67.90248100000008],[-82.07945299999994,67.893326],[-82.07055700000001,67.888596],[-81.837784,67.78387500000002],[-81.72721899999993,67.740814],[-81.70750399999997,67.73165899999992],[-81.69055200000003,67.722488],[-81.6783289999999,67.71304299999991],[-81.66639700000002,67.70359800000006],[-81.65972899999997,67.69413800000001],[-81.65388499999995,67.68942300000015],[-81.63667299999992,67.67997700000001],[-81.59249899999998,67.66165200000006],[-81.53832999999997,67.64359999999999],[-81.49804699999999,67.63192700000013],[-81.45777900000002,67.62052900000015],[-81.43305999999995,67.61137400000007],[-81.4163969999999,67.60192900000004],[-81.24888599999991,67.47970600000008],[-81.24305699999991,67.47499100000005],[-81.23971599999987,67.470261],[-81.237213,67.45555100000001],[-81.237503,67.4410860000001],[-81.23916600000001,67.43609600000008],[-81.24526999999995,67.426376],[-81.25639299999995,67.41638199999994],[-81.29361,67.39610300000004],[-81.30055199999998,67.391098],[-81.30471799999998,67.38610800000009],[-81.347778,67.292755],[-81.36639400000001,67.23887599999995],[-81.37361099999998,67.20471199999997],[-81.37609900000001,67.18997200000001],[-81.37527499999999,67.18525699999998],[-81.38027999999991,67.17053200000004],[-81.41389500000002,67.0913700000001],[-81.43222000000003,67.06666600000011],[-81.49665799999991,67.00471500000015],[-81.50306699999993,66.9997100000001],[-81.51251200000002,66.99470500000001],[-81.52417000000003,66.99054000000001],[-81.53611799999999,66.98831200000006],[-81.69972200000001,66.97026100000011],[-81.71194499999996,66.96998600000006],[-81.75083899999993,66.97859199999999],[-81.76390100000003,66.983047],[-81.77223200000003,66.98776200000003],[-81.78306600000002,66.99247700000006],[-81.79611199999994,66.99693300000001],[-81.80915799999997,66.99832199999997],[-81.833618,66.99775699999998],[-81.92971799999992,66.97859199999999],[-81.95249899999993,66.96804800000012],[-81.98889200000002,66.94970699999993],[-82.026947,66.92608600000005],[-82.17999299999997,66.7688750000001],[-82.18388400000003,66.76416000000006],[-82.36972000000003,66.72581500000013],[-82.48110999999994,66.66970799999996],[-82.55638099999999,66.62387100000012],[-82.56277499999987,66.61886600000008],[-82.56666599999994,66.613876],[-82.57167099999998,66.60386699999998],[-82.57749899999999,66.584427],[-82.57667500000002,66.57943699999998],[-82.57945299999994,66.56971700000008],[-82.585556,66.56469700000002],[-82.59695399999998,66.56025699999998],[-82.69444299999998,66.55802900000003],[-82.78195199999999,66.56666600000005],[-82.86999499999996,66.56749000000002],[-83.01806599999998,66.53997800000008],[-83.012787,66.51582300000007],[-83.015289,66.50610400000005],[-83.01916499999987,66.50109900000001],[-83.025284,66.4958190000001],[-83.04998799999993,66.47553999999997],[-83.05860899999993,66.470261],[-83.35749799999996,66.35304300000007],[-83.36833200000001,66.34887700000002],[-83.40222199999994,66.347488],[-83.45056199999999,66.34664900000001],[-83.51528899999988,66.35386700000004],[-83.56750499999998,66.36747700000012],[-83.65278599999994,66.40776100000005],[-83.65417500000001,66.4124910000001],[-83.63944999999995,66.43719500000009],[-83.63082899999995,66.44220000000013],[-83.6183319999999,66.44081100000011],[-83.60777300000001,66.43637100000012],[-83.597778,66.42692600000004],[-83.60166900000002,66.4122010000001],[-83.597778,66.40748600000006],[-83.54527300000001,66.38136300000008],[-83.53472899999997,66.37803599999995],[-83.57972699999993,66.43165600000009],[-83.67250100000001,66.5205380000001],[-83.68110699999994,66.52499399999999],[-83.70695499999988,66.530823],[-83.73249799999996,66.53471400000006],[-83.79527300000001,66.54193099999998],[-83.82028200000002,66.54275499999994],[-83.83222999999998,66.54220600000002],[-83.85749799999996,66.54414400000013],[-83.96888699999988,66.57748400000003],[-83.97749299999998,66.58221400000008],[-83.98500100000001,66.59166000000005],[-84.01139799999999,66.66360500000002],[-84.01417499999997,66.67330900000002],[-84.01556399999998,66.68775900000014],[-84.01445000000001,66.69274899999999],[-84.00611900000001,66.69802900000008],[-83.99471999999997,66.70138500000013],[-83.98277299999995,66.70277400000009],[-83.94554099999999,66.70248400000008],[-83.89111300000002,66.8041530000001],[-83.886124,66.813873],[-83.88389599999994,66.82388300000008],[-83.88417099999992,66.83360299999998],[-83.890289,66.85775799999999],[-83.9016719999999,66.87191800000011],[-83.90777600000001,66.87664799999999],[-83.91639700000002,66.88108799999998],[-83.928879,66.86303700000002],[-83.93832399999991,66.82360800000009],[-83.94554099999999,66.81359900000007],[-84.10499600000003,66.70832800000011],[-84.11639400000001,66.70498700000007],[-84.140289,66.70193499999993],[-84.15278599999999,66.70248400000008],[-84.16555800000003,66.7038730000001],[-84.26028400000001,66.71638500000006],[-84.27305599999994,66.71859699999993],[-84.28666699999991,66.72303800000003],[-84.29527300000001,66.72747800000008],[-84.43638599999997,66.81832900000012],[-84.42777999999993,66.96110499999998],[-84.415009,66.96081500000014],[-84.39028899999988,66.96192900000011],[-84.37860099999995,66.96415700000006],[-84.36749299999997,66.9685970000001],[-84.370834,66.97137500000008],[-84.43611099999993,66.98136900000009],[-84.48805199999993,66.988876],[-84.61805700000002,67.00637800000004],[-84.69415300000003,67.00972000000002],[-84.73306300000002,67.01470899999998],[-84.837784,67.0294340000001],[-84.85082999999997,67.03166200000004],[-84.87332200000003,67.03942899999998],[-84.88194299999998,67.04386900000003],[-84.88612399999994,67.04859900000008],[-84.89250199999992,67.05331400000011],[-84.90139799999986,67.05775499999999],[-84.915009,67.06080600000001],[-84.92694099999994,67.05941800000011],[-84.93611099999993,67.05609099999998],[-84.88027999999997,66.98942600000004],[-84.87165800000002,66.98498499999994],[-84.85777299999995,66.98165900000009],[-84.84584000000001,66.98220800000007],[-84.83389299999993,66.984711],[-84.81111099999993,66.9916530000001],[-84.789444,67.00248699999997],[-84.77833599999991,67.00665300000009],[-84.76556399999998,67.00637800000004],[-84.69999699999994,66.99581900000004],[-84.64584400000001,66.98165900000009],[-84.63972499999988,66.97804300000007],[-84.65139799999997,66.97554000000008],[-84.71278399999994,66.97276299999999],[-84.88583399999993,66.96666000000005],[-84.96000700000002,66.96415700000006],[-85.01000999999997,66.96470600000004],[-85.04834,66.96331800000007],[-85.05972299999996,66.95971700000007],[-85.14277599999997,66.93026700000013],[-85.22833300000002,66.87831100000005],[-85.228882,66.87330600000001],[-85.22277799999995,66.86886600000003],[-85.19610599999999,66.85525500000006],[-85.18443300000001,66.85108900000012],[-85.146118,66.83943199999999],[-85.13305700000001,66.83692900000005],[-85.11999499999996,66.83554100000015],[-84.94860799999998,66.85859700000015],[-84.94027699999998,66.86387600000012],[-84.90455600000001,66.8972020000001],[-84.90105399999999,66.90037500000011],[-84.90489200000002,66.90303799999998],[-84.91288800000001,66.90504499999997],[-84.920547,66.90537300000011],[-84.93522599999989,66.904541],[-84.94306199999994,66.90537300000011],[-84.95105000000001,66.90737899999999],[-84.95788600000003,66.909874],[-84.96173099999999,66.91270400000002],[-84.95638999999994,66.91536700000012],[-84.86233500000003,66.93983500000007],[-84.855164,66.94066600000008],[-84.76777599999997,66.95220900000004],[-84.75527999999997,66.95166000000006],[-84.60221899999999,66.93580600000013],[-84.56221,66.90138200000013],[-84.57389799999999,66.89888000000002],[-84.61082499999992,66.89387499999998],[-84.62332200000003,66.89332600000006],[-84.650284,66.90081799999996],[-84.67582700000003,66.90277100000009],[-84.68832399999991,66.90304600000013],[-84.74638400000003,66.89749100000006],[-84.70639,66.888596],[-84.58555599999994,66.85887100000008],[-84.558334,66.85054000000002],[-84.52333099999998,66.83692900000005],[-84.50584399999997,66.82777399999998],[-84.50473,66.82304399999998],[-84.51611300000002,66.82054099999999],[-84.541382,66.82138100000003],[-84.58056599999998,66.82832300000013],[-84.63417099999998,66.84165999999999],[-84.660278,66.84637500000002],[-84.67250100000001,66.84582499999999],[-84.68443299999996,66.84414700000002],[-84.69055199999997,66.83998099999997],[-84.68443299999996,66.8352660000001],[-84.67555199999993,66.83082600000012],[-84.664444,66.82748400000014],[-84.65110799999997,66.82415800000012],[-84.466949,66.78776600000015],[-84.43443300000001,66.72554000000014],[-84.44526699999989,66.72026099999994],[-84.44860799999992,66.71527100000009],[-84.44248999999996,66.71081499999997],[-84.42944299999994,66.70832800000011],[-84.40417499999995,66.70555100000001],[-84.34306300000003,66.69941699999998],[-84.20388799999995,66.69136000000003],[-84.15306099999992,66.68580600000001],[-84.144455,66.68136600000003],[-84.13667299999997,66.66220100000004],[-84.13806199999988,66.65721099999996],[-84.14250199999998,66.64721699999996],[-84.14611799999994,66.64221200000009],[-84.18055699999996,66.60664400000007],[-84.18638599999991,66.60137900000001],[-84.12832599999996,66.55470300000002],[-83.96722399999993,66.47387700000007],[-83.91639700000002,66.44664000000012],[-83.89805599999994,66.43275500000004],[-83.88806199999999,66.42359900000008],[-83.87110899999993,66.39498900000007],[-83.86749299999997,66.38053900000011],[-83.80471799999992,66.30720500000012],[-83.77362099999999,66.28970300000009],[-83.774719,66.27526900000004],[-83.77223199999997,66.26554899999996],[-83.76861599999995,66.26081800000003],[-83.762787,66.25610400000011],[-83.728882,66.23803700000002],[-83.71833799999996,66.23359700000003],[-83.6847229999999,66.21554600000002],[-83.68110699999994,66.21081500000008],[-83.67860399999995,66.20109600000012],[-83.68443299999996,66.19609100000002],[-83.69305399999996,66.190811],[-83.76789899999994,66.16863999999998],[-83.78971899999993,66.16331500000013],[-83.83583099999993,66.15470900000003],[-83.84777799999995,66.15332000000001],[-83.85555999999991,66.155823],[-83.97778299999999,66.1994170000001],[-84.11805700000002,66.25471500000009],[-84.13528399999996,66.26388500000013],[-84.14111299999996,66.26832600000006],[-84.14862099999999,66.27777100000014],[-84.14999399999999,66.282761],[-84.15028399999994,66.29248000000001],[-84.14889499999992,66.29748500000005],[-84.15249599999999,66.30220000000008],[-84.158615,66.30664100000001],[-84.16722099999993,66.31109600000002],[-84.17832900000002,66.31553600000001],[-84.19082600000002,66.31805400000002],[-84.21640000000002,66.32165500000008],[-84.22833299999996,66.3211060000001],[-84.31723,66.299713],[-84.42694099999989,66.36303700000008],[-84.44193999999993,66.37220800000006],[-84.506393,66.40220599999998],[-84.51695299999994,66.40470900000014],[-84.528885,66.40415999999999],[-84.55055199999987,66.39444000000009],[-84.55888400000003,66.38916000000006],[-84.61915599999992,66.34971599999994],[-84.62693799999988,66.3435970000001],[-84.635559,66.334991],[-84.636124,66.32887300000004],[-84.625,66.31915299999997],[-84.527222,66.27859500000011],[-84.42443800000001,66.2247010000001],[-84.40750099999997,66.21554600000002],[-84.40139799999997,66.21110500000009],[-84.38999899999993,66.19693000000001],[-84.38639799999999,66.19219999999996],[-84.37777699999998,66.17804000000007],[-84.37249800000001,66.16832],[-84.37471,66.15860000000009],[-84.44860799999992,66.15860000000009],[-84.46055599999994,66.15914900000001],[-84.47332799999998,66.16137700000002],[-84.48388699999992,66.16470300000003],[-84.50944500000003,66.178314],[-84.64111299999996,66.216095],[-84.86915599999998,66.26666299999994],[-84.88194299999998,66.26805100000007],[-84.90583799999996,66.2669370000001],[-84.92748999999998,66.25888100000003],[-84.94387799999998,66.24832200000014],[-84.95472699999993,66.24386600000003],[-84.96665999999999,66.24443100000008],[-84.97972099999998,66.24664300000012],[-85.00167799999997,66.25526400000007],[-85.13194299999992,66.29193100000003],[-85.17832900000002,66.26220700000005],[-85.19027699999987,66.2605440000001],[-85.20249899999993,66.26081800000003],[-85.214722,66.26220700000005],[-85.22778299999999,66.26443499999999],[-85.25222799999995,66.27304100000009],[-85.26972999999998,66.28193700000003],[-85.30139200000002,66.30470300000007],[-85.30665599999992,66.3141480000001],[-85.33972199999994,66.39915499999995],[-85.34555099999989,66.44775400000009],[-85.346115,66.45748900000001],[-85.34167500000001,66.48220800000013],[-85.34333800000002,66.48692299999999],[-85.35139499999997,66.49609399999997],[-85.45750399999991,66.57388300000014],[-85.46640000000002,66.57832300000001],[-85.47972099999998,66.5813750000001],[-85.49194299999988,66.58194000000015],[-85.55221599999993,66.57777400000003],[-85.57556199999999,66.5747070000001],[-85.59861799999993,66.56944299999998],[-85.710556,66.53610199999997],[-85.84527600000001,66.49941999999999],[-85.85777300000001,66.49971],[-85.86888099999993,66.50416600000011],[-85.87554899999998,66.5086060000001],[-85.88890100000003,66.511932],[-85.995544,66.5080410000001],[-86.00750700000003,66.50721699999997],[-86.078888,66.49693300000007],[-86.10333300000002,66.49664300000006],[-86.12832600000002,66.49803200000008],[-86.14111300000002,66.49941999999999],[-86.25666799999993,66.51332100000013],[-86.28332499999993,66.51859999999994],[-86.578888,66.53027299999997],[-86.58000199999998,66.5205380000001],[-86.58778399999994,66.51527400000009],[-86.59973099999996,66.51110800000004],[-86.61138900000003,66.50833100000011],[-86.622772,66.50665299999997],[-86.63500999999997,66.50610400000005],[-86.65972899999997,66.50637799999998],[-86.67250099999995,66.507767],[-86.68554699999999,66.50972000000007],[-86.69888300000002,66.51304600000014],[-86.726944,66.5211030000001],[-86.73805199999998,66.52526900000004],[-86.75167799999997,66.52832000000001],[-86.76417499999997,66.52859500000005],[-86.77528399999994,66.526093],[-86.78083800000002,66.52082800000011],[-86.781387,66.51582300000007],[-86.777222,66.51110800000004],[-86.74388099999993,66.48858600000011],[-86.70111099999997,66.46665999999993],[-86.66278099999994,66.44941700000004],[-86.63999899999993,66.44108599999993],[-86.633621,66.43637100000012],[-86.64167799999996,66.43193100000008],[-86.678604,66.43275500000004],[-86.73055999999997,66.43692000000004],[-86.75695799999994,66.44136000000009],[-86.78361499999994,66.4474790000001],[-86.79638699999992,66.44859300000007],[-86.80749500000002,66.44609100000002],[-86.81111099999998,66.44192500000008],[-86.80915800000002,66.43719500000009],[-86.80499299999997,66.43248000000006],[-86.65167199999996,66.32415800000001],[-86.63833599999992,66.31526200000008],[-86.61277799999999,66.31164600000005],[-86.49722300000002,66.29942299999999],[-86.39611799999994,66.28970300000009],[-86.30610699999994,66.27638200000013],[-86.14222699999999,66.23969999999997],[-86.07611099999991,66.22387700000013],[-85.92748999999998,66.18637099999995],[-85.91389500000002,66.18220500000007],[-85.90110800000002,66.17303500000003],[-85.89723200000003,66.16832],[-85.97749299999992,66.07777399999998],[-85.97582999999992,66.0730440000001],[-85.97389199999998,66.03887900000001],[-85.974716,66.03387500000002],[-85.97999599999991,66.028595],[-85.99055499999997,66.02415500000012],[-86.077225,65.99581900000004],[-86.12138400000003,65.98442100000005],[-86.21749899999998,65.95748900000012],[-86.22084000000001,65.95220900000004],[-86.23138399999993,65.94192500000003],[-86.23916600000001,65.93664600000005],[-86.249435,65.93193100000002],[-86.32640099999998,65.90498400000007],[-86.34861799999987,65.899719],[-86.360275,65.89915500000006],[-86.42027299999995,65.89248700000007],[-86.47222899999986,65.83998099999997],[-86.49694799999997,65.80802900000003],[-86.49499499999996,65.803314],[-86.48638900000003,65.799149],[-86.46417199999996,65.79054300000007],[-86.45527600000003,65.78610200000014],[-86.453888,65.78137200000009],[-86.45111099999986,65.74720800000006],[-86.45417799999996,65.74220300000002],[-86.53028899999987,65.69552599999992],[-86.71610999999996,65.61747700000006],[-86.819458,65.56053200000002],[-86.82972699999999,65.55581699999999],[-86.84056099999998,65.55331400000006],[-86.85278299999993,65.55442800000003],[-86.86582899999996,65.55748000000011],[-86.87805200000003,65.55775499999993],[-86.88861099999997,65.555252],[-86.953888,65.53915400000011],[-86.97277799999995,65.520264],[-87.01722699999999,65.48692300000005],[-87.02444500000001,65.48165900000004],[-87.035278,65.47915600000005],[-87.05471799999998,65.48664900000011],[-87.06750499999998,65.48887599999995],[-87.077789,65.48498500000005],[-87.087784,65.47943100000009],[-87.09500100000002,65.47415200000012],[-87.110275,65.45860299999998],[-87.118607,65.4433140000001],[-87.11915599999998,65.43830900000006],[-87.11500499999994,65.43359400000003],[-87.101944,65.42970300000013],[-87.11166400000002,65.39027400000003],[-87.35110500000002,65.3272090000001],[-87.36193800000001,65.324432],[-87.37277199999994,65.32276900000005],[-87.3958439999999,65.32138099999997],[-87.43083199999995,65.32083100000011],[-87.83332799999994,65.32388300000002],[-87.86915599999998,65.32527200000004],[-87.89306599999998,65.32666000000012],[-87.94193999999987,65.33082600000006],[-87.96665999999999,65.333054],[-88.004456,65.33915700000011],[-88.03028899999993,65.345261],[-88.07028199999996,65.35609399999993],[-88.09445199999999,65.36331200000012],[-88.21278399999989,65.40277100000003],[-88.22138999999999,65.40721100000007],[-88.23472600000002,65.41609199999999],[-88.24333199999995,65.42526200000003],[-88.24527,65.42997700000006],[-88.25389100000001,65.43914800000005],[-88.31361400000003,65.47915600000005],[-88.33361799999994,65.49247700000001],[-88.54861499999998,65.58276400000011],[-88.55972300000002,65.58692900000011],[-88.57305899999994,65.58970600000004],[-88.58555599999994,65.59082000000001],[-88.633331,65.591095],[-88.645554,65.59220899999997],[-88.65888999999993,65.59498600000006],[-88.68582200000003,65.6019290000001],[-88.82972699999988,65.64137299999999],[-88.828888,65.64415000000008],[-88.75666799999999,65.64276100000006],[-88.62249799999995,65.6372070000001],[-88.49888599999997,65.62692300000003],[-88.51333599999998,65.64444000000009],[-88.77972399999999,65.67608599999994],[-88.9497219999999,65.68664600000011],[-88.962784,65.68858300000011],[-89.00083899999998,65.69859300000002],[-89.09944200000001,65.72526600000003],[-89.124435,65.7333220000001],[-89.13389599999994,65.73748799999998],[-89.14056399999993,65.74192800000003],[-89.14527899999996,65.74636800000002],[-89.14750700000002,65.75138899999996],[-89.14723199999997,65.76110799999998],[-89.14944499999996,65.76582300000001],[-89.15638699999994,65.77026400000011],[-89.17443800000001,65.778595],[-89.37999000000002,65.84637500000002],[-89.525284,65.886932],[-89.59722899999986,65.91081200000002],[-89.66471899999993,65.93498200000005],[-89.67166099999992,65.93942300000015],[-89.70944199999991,65.94220000000001],[-89.96722399999999,65.94859300000002],[-89.991104,65.94747899999999],[-90,65.94435900000013],[-89.96417199999996,65.93691999999999],[-89.93916300000001,65.93609600000002],[-89.92639199999991,65.93414300000006],[-89.89916999999997,65.92858900000004],[-89.87110899999999,65.92109700000015],[-89.83416699999998,65.91026300000004],[-89.79943800000001,65.8983310000001],[-89.74082900000002,65.87330600000007],[-89.731674,65.86914100000007],[-89.72694399999995,65.83998099999997],[-89.729172,65.83471700000001],[-89.73638900000003,65.829163],[-89.74694799999997,65.82638500000002],[-89.76916499999993,65.822495],[-89.79333499999996,65.822495],[-89.81889299999989,65.82554600000003],[-89.83222999999992,65.82832300000013],[-89.84388699999994,65.83221400000002],[-89.89056399999987,65.85304300000001],[-89.902222,65.85720800000001],[-90.04861499999998,65.88832100000002],[-90.07362399999994,65.89027399999998],[-90.085556,65.88915999999995],[-90.11999500000002,65.88388099999997],[-90.162781,65.87220799999994],[-90.20722999999992,65.86442600000004],[-90.24194299999999,65.86137400000007],[-90.26583899999997,65.86053500000014],[-90.31500199999999,65.86219800000003],[-90.40444899999994,65.87109399999997],[-90.41833500000001,65.87414600000011],[-90.42748999999998,65.87803600000007],[-90.43249500000002,65.8827510000001],[-90.42555199999993,65.88832100000002],[-90.39306599999992,65.89610299999998],[-90.35777300000001,65.89804100000009],[-90.333328,65.89721700000013],[-90.27278100000001,65.89749100000006],[-90.22555499999993,65.90054299999997],[-90.21556099999992,65.90443400000004],[-90.21333300000003,65.90942400000012],[-90.21333300000003,65.91442899999998],[-90.220551,65.91886899999997],[-90.23472599999997,65.92248500000005],[-90.258896,65.92248500000005],[-90.29333500000001,65.91859399999998],[-90.360275,65.907761],[-90.41888399999988,65.901093],[-90.57417299999997,65.89665200000007],[-90.59611499999994,65.89665200000007],[-90.708618,65.90248099999991],[-90.73388699999992,65.9041600000001],[-90.850281,65.91526799999991],[-91.06834400000002,65.94026200000008],[-91.31639099999995,65.96998600000012],[-91.32861300000002,65.96998600000012],[-91.34028599999994,65.96887200000009],[-91.42916899999994,65.95109599999995],[-91.44444299999986,65.93081700000005],[-91.36277799999993,65.89359999999999],[-91.35333299999996,65.88943499999999],[-91.341385,65.88581800000003],[-91.32806399999998,65.88388099999997],[-91.18943799999994,65.85304300000001],[-91.06082200000003,65.81330900000006],[-91.04666099999992,65.809418],[-91.02055399999995,65.8060910000001],[-91.008621,65.8060910000001],[-91.0041809999999,65.81137100000012],[-91.01390099999998,65.82054099999999],[-91.05471799999998,65.84664900000013],[-91.108337,65.8913730000001],[-91.12304699999993,65.90470900000008],[-91.12582399999985,65.90971400000012],[-91.12138400000003,65.9149930000001],[-91.09973099999996,65.91998299999995],[-91.08805799999993,65.92109700000015],[-91.06388900000002,65.92109700000015],[-90.99027999999998,65.91998299999995],[-90.97694399999995,65.918045],[-90.94860799999998,65.91081200000002],[-90.92138699999992,65.905258],[-90.90834000000001,65.90359500000011],[-90.74194299999999,65.88777200000004],[-90.69248999999996,65.88610800000004],[-90.53167699999995,65.88053900000006],[-90.07806399999998,65.8124850000001],[-90.01390099999992,65.80026200000003],[-90,65.79740099999992],[-89.98693800000001,65.79470800000007],[-89.96000699999996,65.78887900000007],[-89.93222000000003,65.78137200000009],[-89.74499500000002,65.72470099999998],[-89.72027599999996,65.71304299999997],[-89.660278,65.68331899999998],[-89.65333599999991,65.67886399999998],[-89.42832899999996,65.52943400000004],[-89.30888399999998,65.46943700000008],[-89.146118,65.40054300000008],[-89.06555199999991,65.333054],[-89.05444299999999,65.3288730000001],[-89.04444899999999,65.32777400000009],[-88.771118,65.30775499999999],[-88.73388699999998,65.30609099999998],[-88.71028100000001,65.30609099999998],[-88.69860799999998,65.30693100000002],[-88.676941,65.31053200000008],[-88.60694899999993,65.30693100000002],[-88.49027999999998,65.29332000000005],[-88.38917499999991,65.27720599999992],[-88.36471599999987,65.27499400000005],[-88.215012,65.27720599999992],[-88.13333099999994,65.27832000000012],[-88.10972599999997,65.27804600000002],[-88.09666400000003,65.27499400000005],[-88.06166099999996,65.25888100000003],[-88.02111799999989,65.27470400000004],[-88.01112399999994,65.27832000000012],[-87.97805800000003,65.28359999999998],[-87.943604,65.28610200000008],[-87.73138399999999,65.29026799999997],[-87.67304999999999,65.29136699999992],[-87.60221899999993,65.29054299999996],[-87.35777300000001,65.270828],[-87.21055599999994,65.254166],[-87.07501200000002,65.23664899999994],[-86.95777900000002,65.165817],[-86.94499200000001,65.15693699999997],[-86.936935,65.14776600000005],[-86.93331899999998,65.13804600000014],[-86.96749899999998,65.059418],[-86.9702759999999,65.05442800000009],[-86.97749299999998,65.04887400000013],[-86.99777199999994,65.04081699999995],[-87.04055799999998,65.03109700000005],[-87.11000100000001,64.999146],[-87.43028300000003,64.711929],[-87.52166699999992,64.62109400000008],[-87.57194499999997,64.57360799999998],[-87.57917800000001,64.56805400000002],[-87.58612099999999,64.56275900000014],[-87.59555099999994,64.55720500000012],[-87.69804399999992,64.52720600000009],[-87.76441999999997,64.52090499999991],[-87.78639199999992,64.51998900000001],[-87.79722599999997,64.51805100000007],[-87.80721999999997,64.51443499999999],[-87.85527000000002,64.43942300000009],[-87.85583500000001,64.42942800000014],[-87.86361699999998,64.37970000000001],[-87.8663939999999,64.36970500000012],[-87.98388699999992,64.19108600000004],[-87.99082900000002,64.18580599999996],[-88.11332700000003,64.13610800000004],[-88.12332200000003,64.13360599999999],[-88.28555299999994,64.10636900000003],[-88.55166600000001,64.02554300000008],[-88.553879,64.02053800000004],[-88.67443799999995,63.98026999999996],[-88.68443299999996,63.977486000000056],[-88.73666399999996,63.968323000000055],[-88.75944499999997,63.96943700000003],[-88.99388099999993,63.998604000000114],[-89.07778899999988,64.02609300000012],[-89.11000099999995,64.03804000000008],[-89.12721299999998,64.04664600000001],[-89.15083300000003,64.059418],[-89.18277,64.08137500000004],[-89.19804399999998,64.09471100000002],[-89.202225,64.09942600000005],[-89.20861799999994,64.10887100000008],[-89.210556,64.11831700000005],[-89.210556,64.12330600000001],[-89.21278399999994,64.12803600000007],[-89.22084000000001,64.13720700000005],[-89.24472000000003,64.15498400000007],[-89.25111399999997,64.15942400000012],[-89.26083399999987,64.16053800000009],[-89.28416400000003,64.14193700000004],[-89.28639199999998,64.13665800000007],[-89.18249500000002,64.036652],[-89.09666400000003,63.973877000000016],[-89.06166100000002,63.96082300000012],[-89.05110199999996,63.96193699999992],[-89.04083300000002,63.958602999999925],[-89.02362099999999,63.95027200000004],[-89.02860999999996,63.946098000000006],[-89.03944399999995,63.94499199999996],[-89.05055199999993,63.94499199999996],[-89.24665799999997,63.959717000000126],[-89.25472999999994,63.96305100000012],[-89.32139599999994,63.996658000000025],[-89.39611799999994,64.038589],[-89.50723299999993,64.07054099999999],[-89.55110199999996,64.07748399999997],[-89.55860899999999,64.07388300000014],[-89.56082200000003,64.06887800000004],[-89.56527699999998,64.01914999999997],[-89.56332399999985,64.00943000000007],[-89.55444299999999,64.00027499999999],[-89.54804999999993,63.996101000000124],[-89.53083800000002,63.98777000000007],[-89.51777599999991,63.97887400000013],[-89.48999000000003,63.956657000000064],[-89.48554999999999,63.95193499999999],[-89.48332199999987,63.94721199999998],[-89.48554999999999,63.94221500000009],[-89.49722300000002,63.94304699999998],[-89.52111799999994,63.95582600000006],[-89.52749599999999,63.96027400000003],[-89.577225,63.99554400000005],[-89.585556,64.00443999999999],[-89.58999599999993,64.01416000000006],[-89.59416199999993,64.0186000000001],[-89.637787,64.0494230000001],[-89.64416499999999,64.05386400000003],[-89.69972200000001,64.07638500000002],[-89.712219,64.0794370000001],[-89.71916199999998,64.0747070000001],[-89.72694399999995,64.04748499999994],[-89.785553,64.07693500000005],[-89.81806899999992,64.09860200000008],[-89.82250999999991,64.10331700000012],[-89.82278399999996,64.10803199999998],[-89.82055700000001,64.11331200000001],[-89.80972300000002,64.12886000000003],[-89.80221599999999,64.132477],[-89.78056300000003,64.13443000000012],[-89.75750700000003,64.13360599999999],[-89.74694799999997,64.1355440000001],[-89.73805199999993,64.14027399999992],[-89.73582499999998,64.145264],[-89.75111400000003,64.21804800000012],[-89.75556899999998,64.22747800000002],[-89.76000999999997,64.23220800000007],[-89.773056,64.240814],[-89.78416399999992,64.24470500000007],[-89.79415899999992,64.24192800000014],[-89.80110200000001,64.23748799999993],[-89.80555700000002,64.22720300000003],[-89.80332899999996,64.222488],[-89.80305499999997,64.20277400000009],[-89.81639100000001,64.14804100000009],[-89.823624,64.14444000000003],[-89.84555099999994,64.14276100000001],[-89.87943999999999,64.14248700000007],[-89.89222699999999,64.1455380000001],[-89.90972899999991,64.15859999999992],[-89.92250100000001,64.16137700000002],[-89.96749899999992,64.16137700000002],[-89.98693800000001,64.15971400000012],[-90.12416100000002,64.1285860000001],[-90.11805700000002,64.12525900000014],[-90.10499599999997,64.12136800000007],[-90.05860899999999,64.10971099999995],[-89.95056199999999,64.08692900000005],[-89.94610599999999,64.05748000000006],[-89.90417500000001,64.01582300000001],[-89.86694299999999,63.98971599999993],[-89.8416749999999,63.983879],[-89.83111600000001,63.979988000000105],[-89.82444799999996,63.97554800000006],[-89.82028199999996,63.97109999999992],[-89.81361399999997,63.946938000000046],[-89.81361399999997,63.93721000000005],[-89.81555200000003,63.931938000000116],[-89.82194499999997,63.9263840000001],[-89.82861299999996,63.921104000000014],[-89.83805799999993,63.91721299999995],[-89.93888899999996,63.90971399999995],[-89.95140099999998,63.912491000000045],[-89.989441,63.92193600000013],[-89.99833699999999,63.926102000000014],[-89.99527,63.92916100000002],[-89.97471599999994,63.93305200000009],[-89.964722,63.93582200000009],[-89.95527600000003,63.93971299999998],[-89.94860799999998,63.945267],[-89.94665500000002,63.950546000000145],[-89.94665500000002,63.96027400000003],[-89.94665500000002,63.96527100000009],[-89.94888299999991,63.96998600000012],[-89.95556599999998,63.9741590000001],[-89.968613,63.97804300000013],[-90,63.98404300000004],[-90.18249499999996,64.0086060000001],[-90.19415300000003,64.00943000000007],[-90.249435,64.00749200000013],[-90.27139299999999,64.00637799999993],[-90.27917500000001,64.00360100000006],[-90.27500900000001,63.999161000000015],[-90.26278699999989,63.997214999999926],[-90.22749299999998,63.99443800000006],[-90.21472199999988,63.99082900000002],[-90.19694499999991,63.982491000000095],[-90.11389200000002,63.93082400000009],[-89.97500599999995,63.825829000000056],[-89.96640000000002,63.81693999999999],[-89.96417199999996,63.81193500000012],[-89.96417199999996,63.80221599999993],[-89.96611000000001,63.79222100000004],[-89.96833799999996,63.78221100000013],[-89.97250399999996,63.776657000000114],[-89.981674,63.77304800000013],[-90.05777,63.74443800000006],[-90.08999599999993,63.69887499999999],[-90.14889499999998,63.629158000000075],[-90.15638699999994,63.626656000000025],[-90.20527599999991,63.61221299999994],[-90.23638899999992,63.60721600000005],[-90.25862099999989,63.60721600000005],[-90.42944299999999,63.61582900000002],[-90.46139499999998,63.64054900000008],[-90.468613,63.652309],[-90.48805199999998,63.67249300000009],[-90.50111399999997,63.676383999999985],[-90.61193799999995,63.70249200000012],[-90.62388599999991,63.704162999999994],[-90.63444500000003,63.70304900000002],[-90.64416499999993,63.7002720000001],[-90.70140099999998,63.662209000000075],[-90.69915799999995,63.65749400000004],[-90.68666099999996,63.65470900000014],[-90.67777999999993,63.65443399999998],[-90.65556300000003,63.65470900000014],[-90.62361099999998,63.657767999999976],[-90.61389199999991,63.66054500000001],[-90.60972599999991,63.6658250000001],[-90.61000100000001,63.67582700000008],[-90.60278299999999,63.67943600000007],[-90.59028599999999,63.67665899999997],[-90.55972300000002,63.65971400000001],[-90.55555699999996,63.65526600000004],[-90.55332900000002,63.650543000000084],[-90.54138199999994,63.61721000000006],[-90.54138199999994,63.61221299999994],[-90.54527300000001,63.606941000000006],[-90.55139199999996,63.601387000000045],[-90.56082200000003,63.597488],[-90.57112099999995,63.59554300000002],[-90.73388699999992,63.57388300000002],[-90.82806399999998,63.56166100000007],[-90.84944200000001,63.55971499999998],[-90.93055699999996,63.56415600000008],[-90.94276399999995,63.56666600000011],[-90.978882,63.576103000000046],[-90.98944099999994,63.57999400000011],[-91.03500399999996,63.5991590000001],[-91.13778699999989,63.630821000000026],[-91.158051,63.63555100000008],[-91.18859900000001,63.62943300000012],[-91.19888300000002,63.628601],[-91.21028100000001,63.628326000000015],[-91.23332199999999,63.62999000000002],[-91.37582399999997,63.65915700000011],[-91.39973399999997,63.66666400000008],[-91.40638699999994,63.67110400000007],[-91.40666199999998,63.67610200000007],[-91.40278599999999,63.681381000000044],[-91.39361600000001,63.68526500000007],[-91.37138400000003,63.685546999999985],[-91.34973100000002,63.677772999999945],[-91.33694500000001,63.67527000000001],[-91.329453,63.677772999999945],[-91.33389299999999,63.68249500000002],[-91.34056099999998,63.68665299999998],[-91.34944200000001,63.69082600000013],[-91.362503,63.69443500000011],[-91.41166699999991,63.70721400000002],[-91.52917499999995,63.72998799999999],[-91.54055800000003,63.73082000000005],[-91.55139200000002,63.72971300000012],[-91.56082199999992,63.726653999999996],[-91.569458,63.721930999999984],[-91.57556199999993,63.716385000000116],[-91.58416699999998,63.71138000000008],[-91.59555099999989,63.71138000000008],[-91.91055299999994,63.74054699999999],[-92.06639100000001,63.74193600000001],[-92.13612399999994,63.74554400000011],[-92.14862099999999,63.7480470000001],[-92.175003,63.75527199999999],[-92.18611099999998,63.75888800000001],[-92.43443300000001,63.804993000000024],[-92.48277299999995,63.81193500000012],[-92.47166400000003,63.80832700000002],[-92.43777499999993,63.79222100000004],[-92.42832899999996,63.783051],[-92.42555199999998,63.77860300000003],[-92.42250099999995,63.748878000000104],[-92.41583299999996,63.744713000000104],[-92.40666199999993,63.74054699999999],[-92.39555399999995,63.73693800000001],[-92.38276699999994,63.734161000000086],[-92.34889199999992,63.73387900000006],[-92.30638099999993,63.738602000000014],[-92.26306199999993,63.74137900000011],[-92.25111399999997,63.74054699999999],[-92.148056,63.716934000000094],[-92.10388199999994,63.701660000000004],[-92.10166900000002,63.6969380000001],[-92.10555999999997,63.69165800000002],[-92.20417799999996,63.63804600000009],[-92.25250199999999,63.62387800000005],[-92.26251200000002,63.62193300000007],[-92.38500999999991,63.59249100000011],[-92.48971599999993,63.56721500000003],[-92.49305699999996,63.540832999999964],[-92.48083500000001,63.52721400000007],[-92.42916899999994,63.54694400000005],[-92.33639499999987,63.55693800000006],[-92.27999899999998,63.55609900000013],[-92.20666499999993,63.60610200000008],[-92.20278899999988,63.611381999999935],[-92.19387799999993,63.615273],[-92.16528299999999,63.62443500000012],[-91.971115,63.67999300000014],[-91.83029199999993,63.71221200000002],[-91.82000699999998,63.714157],[-91.80943299999996,63.71527100000014],[-91.77610799999997,63.715828000000045],[-91.76333599999998,63.713325999999995],[-91.69526699999994,63.690544000000045],[-91.670837,63.67804700000005],[-91.61749299999991,63.64888000000013],[-91.61305199999993,63.644440000000145],[-91.61138899999997,63.63916000000006],[-91.61250299999989,63.629158000000075],[-91.61805699999996,63.613609],[-91.61721799999992,63.603882000000056],[-91.60749800000002,63.584991],[-91.60082999999997,63.580551000000014],[-91.39805599999994,63.52499400000005],[-91.27417000000003,63.502495000000124],[-91.13305699999995,63.478043000000014],[-90.94554099999993,63.440269000000114],[-90.85472099999998,63.40860000000009],[-90.91555799999992,63.41054500000007],[-90.93277,63.41860200000008],[-90.94554099999993,63.422493000000145],[-90.95695499999994,63.423325000000034],[-90.96833799999996,63.423050000000046],[-90.97500600000001,63.419441000000006],[-90.97277799999995,63.41471100000001],[-90.95750399999997,63.40138200000007],[-90.94221499999998,63.393051000000014],[-90.93138099999993,63.38916000000012],[-90.91888399999993,63.38638300000002],[-90.816666,63.36915600000003],[-90.74194299999999,63.36082500000009],[-90.69082599999996,63.228324999999984],[-90.62748699999997,63.05943300000001],[-90.64916999999991,63.03638500000011],[-90.73999000000003,62.962212000000136],[-90.77583299999998,62.941933000000006],[-90.78500400000001,62.93804199999994],[-90.79499800000002,62.936104],[-90.82583599999992,62.93305200000009],[-90.847778,62.932770000000005],[-90.87027,62.934433000000126],[-90.92944299999999,62.94443500000011],[-90.94055199999997,62.945267],[-91.01722699999993,62.946380999999974],[-91.03832999999992,62.94415300000003],[-91.04804999999999,62.94221500000009],[-91.17304999999999,62.908600000000035],[-91.18249499999996,62.90582300000011],[-91.19082599999996,62.900825999999995],[-91.19665499999996,62.89527100000009],[-91.20056199999993,62.88999200000012],[-91.1997219999999,62.87027000000006],[-91.20722999999998,62.8597180000001],[-91.21333300000003,62.85416400000008],[-91.35638399999999,62.78860500000002],[-91.36665299999993,62.787498000000085],[-91.44027699999987,62.78276800000003],[-91.46166999999997,62.7824940000001],[-91.57917800000001,62.79999500000008],[-91.84028599999994,62.82638500000007],[-91.99027999999998,62.84693900000002],[-92.0875089999999,62.81888600000008],[-92.214722,62.82471500000008],[-92.223053,62.82888000000008],[-92.23611499999993,62.83221400000008],[-92.33999599999999,62.843605000000025],[-92.36193799999995,62.844154],[-92.38276699999994,62.84166000000005],[-92.39250199999992,62.83971399999996],[-92.402222,62.83749399999999],[-92.42083699999995,62.83138300000007],[-92.43832399999997,62.82360799999998],[-92.45527599999997,62.81471299999998],[-92.45944199999997,62.810272000000055],[-92.458618,62.80027000000007],[-92.45584100000002,62.79583000000008],[-92.45140099999992,62.79110700000007],[-92.33361799999994,62.709991000000116],[-92.23277300000001,62.67304999999999],[-92.18859899999995,62.65915699999999],[-92.17832900000002,62.65638000000007],[-92.06777999999997,62.65165700000006],[-92.03472899999986,62.65026899999998],[-91.97138999999993,62.65332000000001],[-91.94888300000002,62.6519320000001],[-91.92582700000003,62.644440000000145],[-91.908615,62.63638300000002],[-91.88276699999994,62.624161000000015],[-91.88055400000002,62.61943800000006],[-91.883331,62.60443899999996],[-91.88500999999991,62.5991590000001],[-91.890289,62.58860000000004],[-91.94137599999999,62.534996000000035],[-91.94804399999998,62.53138000000001],[-92.05332899999996,62.526657],[-92.15306099999992,62.59804500000013],[-92.16332999999997,62.60082999999997],[-92.18611099999998,62.603324999999984],[-92.19665500000002,62.603049999999996],[-92.26611299999996,62.59526800000003],[-92.27500900000001,62.591377000000136],[-92.27139999999997,62.578049000000135],[-92.27555799999993,62.56027200000011],[-92.32556199999999,62.54083300000002],[-92.365005,62.533332999999914],[-92.38473499999998,62.529990999999995],[-92.396118,62.53082300000011],[-92.43083199999995,62.53582799999998],[-92.46806299999997,62.54444100000012],[-92.53916900000002,62.532493999999986],[-92.60611,62.46499600000004],[-92.61776700000001,62.46666000000005],[-92.71000699999996,62.46582799999993],[-92.72610500000002,62.44415300000014],[-92.72972099999998,62.438599000000124],[-92.73110999999994,62.433601000000124],[-92.73083499999996,62.428604000000064],[-92.724716,62.358604000000014],[-92.714722,62.34388000000001],[-92.66583300000002,62.33277100000009],[-92.62805200000003,62.322220000000016],[-92.60665899999992,62.31471300000004],[-92.59805299999994,62.31082199999997],[-92.5850069999999,62.302216000000044],[-92.58444199999997,62.29749300000009],[-92.58583099999987,62.292220999999984],[-92.60166899999996,62.26554900000008],[-92.610275,62.26138299999997],[-92.60399599999994,62.23632400000014],[-92.57305899999994,62.196098000000006],[-92.56861900000001,62.19165799999996],[-92.56193499999995,62.18749200000008],[-92.53666699999997,62.17555199999998],[-92.48638899999997,62.16137700000007],[-92.47805799999992,62.157493999999986],[-92.47001599999993,62.146614],[-92.47778299999999,62.14388300000002],[-92.48721299999994,62.14415700000012],[-92.59222399999999,62.154990999999995],[-92.60388199999994,62.156379999999956],[-92.62582399999991,62.19165799999996],[-92.64044199999995,62.209098999999924],[-92.63843500000002,62.21227300000004],[-92.63827500000002,62.215103000000056],[-92.63993800000003,62.21777000000009],[-92.70056199999999,62.26554900000008],[-92.7411039999999,62.28694200000001],[-92.74749800000001,62.28999300000004],[-92.845551,62.30943300000001],[-93.07556199999999,62.33221400000002],[-93.12222300000002,62.334991000000116],[-92.90417499999995,62.26221500000008],[-92.89222699999999,62.25972000000007],[-92.86639399999996,62.26305400000007],[-92.83999599999999,62.260276999999974],[-92.8286129999999,62.25721700000008],[-92.78028899999987,62.23693800000012],[-92.765289,62.22443400000009],[-92.76472499999994,62.21943700000003],[-92.79028299999999,62.17748999999992],[-92.79583699999995,62.17276800000002],[-92.80096399999996,62.172905000000014],[-92.84028599999999,62.17443800000001],[-92.85194399999995,62.17582700000003],[-92.862503,62.17943600000001],[-92.954453,62.19276400000001],[-93.06806899999998,62.17499500000008],[-93.07667499999991,62.17193600000013],[-93.11000099999995,62.15665400000012],[-93.114441,62.15415999999999],[-93.11972000000003,62.148330999999985],[-93.12693799999988,62.13249200000001],[-93.12416099999996,62.128044000000045],[-93.11944599999993,62.12360400000006],[-93.08138999999994,62.10443900000007],[-93.06916799999988,62.10360700000001],[-93.0597229999999,62.10582699999998],[-93.03750600000001,62.12165800000014],[-93.028885,62.12471000000005],[-93.01916499999999,62.12609900000007],[-93.00805700000001,62.125549000000035],[-92.94055200000003,62.11554700000005],[-92.93306000000001,62.11360900000011],[-92.93055700000002,62.10916099999997],[-92.93138099999999,62.10416400000008],[-92.936935,62.09915900000004],[-92.96833800000002,62.07721700000013],[-92.991104,62.067772000000105],[-93.14083900000003,62.00972000000013],[-93.237213,62.02693899999997],[-93.24638400000003,62.03333300000003],[-93.27749599999987,62.04277000000013],[-93.30277999999993,62.04943800000012],[-93.32528699999995,62.05138400000004],[-93.41139199999998,62.03138000000007],[-93.41305499999999,62.025551000000064],[-93.39416499999993,62.01361099999997],[-93.385559,62.00999500000012],[-93.37361099999998,62.00750000000011],[-93.36193799999995,62.00610400000005],[-93.34222399999993,62.00499700000012],[-93.318893,61.9980470000001],[-93.24444599999998,61.96943700000003],[-93.23554999999999,61.96554599999996],[-93.22222899999991,61.95749699999999],[-93.21833800000002,61.95249200000012],[-93.21722399999999,61.94776900000011],[-93.28195199999988,61.89138000000008],[-93.29972800000002,61.885826000000066],[-93.30915799999991,61.88360600000004],[-93.33056599999992,61.88638300000014],[-93.44248999999996,61.915268000000026],[-93.46167000000003,61.92249300000009],[-93.616104,61.939986999999974],[-93.60028099999994,61.879158000000075],[-93.61721799999998,61.86193800000012],[-93.55694599999998,61.84777100000014],[-93.43582199999997,61.80888399999998],[-93.28277600000001,61.7888870000001],[-93.24861099999998,61.78472099999999],[-93.23777799999993,61.77721400000007],[-93.24249299999997,61.767494],[-93.25556899999998,61.74249300000014],[-93.35694899999999,61.70721400000002],[-93.44943199999994,61.68221300000005],[-93.54276999999996,61.663321999999994],[-93.59416199999993,61.648048000000074],[-93.65499899999986,61.62915800000013],[-93.85665899999998,61.54916400000013],[-93.98472600000002,61.456100000000106],[-93.985275,61.45416300000005],[-93.968613,61.396660000000054],[-93.93249500000002,61.38721499999997],[-93.9219359999999,61.38526900000011],[-93.91166699999997,61.38582600000001],[-93.906387,61.38749700000005],[-93.89500399999997,61.389160000000004],[-93.88473499999986,61.389717000000076],[-93.86805699999996,61.389160000000004],[-93.85749800000002,61.385551000000135],[-93.82028199999996,61.35582699999998],[-93.81750499999998,61.35138699999993],[-93.81916799999999,61.34721400000001],[-93.839447,61.31944300000009],[-93.84445199999999,61.316101],[-93.85804699999994,61.31276700000001],[-93.93222000000003,61.29666100000003],[-93.94055200000003,61.29499800000008],[-94.05721999999997,61.178329000000076],[-94.14805599999994,61.04361000000006],[-94.22694399999995,60.94276400000007],[-94.34916699999991,60.85860399999996],[-94.35333300000002,60.85360700000007],[-94.3911129999999,60.79888200000005],[-94.41528299999999,60.762215000000026],[-94.415009,60.756660000000124],[-94.45167499999997,60.67110400000013],[-94.50500499999998,60.54999500000014],[-94.50944499999997,60.54415900000009],[-94.56304899999998,60.52221700000001],[-94.57583599999998,60.52027099999998],[-94.61138900000003,60.52777100000003],[-94.67332499999992,60.522490999999945],[-94.67166099999992,60.46610300000003],[-94.62943999999999,60.41832700000009],[-94.62638899999996,60.41360500000002],[-94.61471599999987,60.38999200000012],[-94.61389199999991,60.380547000000035],[-94.615005,60.37526699999995],[-94.620834,60.363883999999985],[-94.68194599999993,60.22415899999993],[-94.67361499999993,60.19110100000012],[-94.70472699999993,60.09193399999998],[-94.70750399999997,60.083603000000096],[-94.71139499999992,60.07833099999999],[-94.71472199999994,60.07527200000004],[-94.72833300000002,60.071380999999974],[-94.74665800000002,60.06999200000013],[-94.75279199999994,60.06860400000005],[-94.76640299999991,60.061378000000104],[-94.77111799999994,60.05554999999998],[-94.803879,60.008331],[-94.803879,60.0036090000001],[-94.80043,59.99956500000013],[-94.81916799999999,59.96471400000013],[-94.82167099999992,59.95916000000011],[-94.82250999999991,59.954162999999994],[-94.82055699999995,59.944435],[-94.80332900000002,59.877768999999944],[-94.80332900000002,59.711104999999975],[-94.81916799999999,59.63638300000008],[-94.78860500000002,59.51527400000009],[-94.735275,59.4263840000001],[-94.68055700000002,59.357215999999994],[-94.71528599999999,59.323326000000066],[-94.77000399999997,59.29833200000013],[-94.77500900000001,59.29332700000009],[-94.781387,59.263611000000026],[-94.78222700000003,59.25833100000011],[-94.78971899999999,59.092216000000064],[-94.681671,58.97582200000011],[-94.67999299999997,58.97137500000008],[-94.67639200000002,58.93443300000007],[-94.59777799999995,58.87832600000007],[-94.58639499999987,58.87499200000008],[-94.48693800000001,58.81526900000006],[-94.48222399999997,58.81110400000006],[-94.47778299999993,58.80665600000009],[-94.474716,58.802216000000044],[-94.45750399999991,58.77416200000005],[-94.45333899999991,58.76527400000003],[-94.45278899999988,58.759720000000016],[-94.45333899999991,58.75054900000009],[-94.44860799999998,58.736382000000106],[-94.44610599999999,58.73165899999998],[-94.43720999999988,58.72304500000007],[-94.42166099999997,58.71638500000006],[-94.410553,58.714157000000114],[-94.36138899999997,58.71276900000004],[-94.343613,58.715546000000074],[-94.32695000000001,58.72165699999999],[-94.29110700000001,58.743607],[-94.27917500000001,58.77110300000004],[-94.228882,58.78499600000009],[-94.23472599999997,58.714714000000015],[-94.252228,58.64999400000005],[-94.28527799999989,58.512496999999996],[-94.287216,58.438041999999996],[-94.28916899999996,58.427773000000116],[-94.291672,58.42221800000004],[-94.29666099999997,58.4158250000001],[-94.32640099999998,58.34915900000004],[-94.34861799999999,58.2866590000001],[-94.3516689999999,58.27665699999994],[-94.36389200000002,58.22387700000013],[-94.36332700000003,58.21888000000001],[-94.360275,58.220543000000134],[-94.3558349999999,58.226097000000095],[-94.25944500000003,58.35138699999999],[-94.23111,58.39054900000002],[-94.22860699999995,58.39610300000004],[-94.22694399999995,58.40638000000001],[-94.23111,58.43082400000014],[-94.23889199999996,58.494155999999975],[-94.24610899999999,58.576385000000016],[-94.24610899999999,58.58665499999995],[-94.24526999999995,58.59165999999999],[-94.24276699999996,58.59721400000001],[-94.14388999999994,58.76361099999991],[-94.11389200000002,58.76221500000008],[-93.99583399999995,58.760826000000066],[-93.94915800000001,58.76249700000011],[-93.84388699999994,58.767769000000044],[-93.79861499999993,58.77360499999992],[-93.72805800000003,58.78388200000012],[-93.70973200000003,58.78582799999998],[-93.67304999999993,58.78082300000011],[-93.57556199999999,58.763885000000016],[-93.47555499999999,58.73249100000004],[-93.35055499999993,58.74582700000002],[-93.34388699999988,58.75083200000006],[-93.327789,58.75721700000008],[-93.31916799999999,58.75860600000004],[-93.23666400000002,58.766936999999984],[-93.21665999999993,58.76416000000006],[-93.19638099999997,58.758331000000055],[-93.15556299999997,58.740273],[-93.15222199999994,58.73777000000001],[-93.14111299999996,58.691933000000006],[-93.13972499999988,58.653876999999966],[-93.12693799999988,58.53249400000004],[-93.12609900000001,58.52777100000009],[-93.11805700000002,58.50888800000001],[-93.09527600000001,58.46720900000008],[-93.03527799999995,58.37082700000002],[-92.96472199999994,58.261108000000036],[-92.93110699999994,58.21166199999999],[-92.86888099999993,58.14305099999996],[-92.8116609999999,58.07166300000006],[-92.80332900000002,58.057213000000104],[-92.79998799999998,58.0422210000001],[-92.80555700000002,58.01194000000004],[-92.80555700000002,58.00638600000002],[-92.80471799999998,57.997490000000084],[-92.79527300000001,57.96888000000007],[-92.75361599999997,57.85083000000003],[-92.724716,57.801383999999985],[-92.67250100000001,57.733047000000056],[-92.62110899999988,57.67054700000011],[-92.45083599999998,57.442490000000134],[-92.44638099999997,57.43305199999992],[-92.41888399999999,57.33749399999999],[-92.41833499999996,57.3324970000001],[-92.41888399999999,57.32332600000012],[-92.42721599999999,57.263053999999954],[-92.43028300000003,57.25222000000008],[-92.441101,57.23054500000012],[-92.5494379999999,57.08554799999996],[-92.56388900000002,57.068885999999964],[-92.57640099999998,57.056938000000116],[-92.695267,56.96166200000005],[-92.70861799999989,56.95166000000012],[-92.71583599999997,56.94748700000014],[-92.72332799999992,56.944435000000055],[-92.73832699999997,56.94110100000006],[-92.77139299999993,56.93804200000011],[-92.837219,56.92443800000001],[-92.86805699999996,56.91415399999994],[-92.87721299999993,56.90915700000005],[-92.87609899999995,56.9074940000001],[-92.86833200000001,56.90665400000006],[-92.85055499999993,56.90721100000013],[-92.83168,56.90859999999998],[-92.79055799999998,56.91387900000012],[-92.756958,56.918602000000135],[-92.73138399999999,56.922492999999974],[-92.691101,56.93360100000001],[-92.66027799999995,56.945266999999944],[-92.65222199999988,56.94915800000001],[-92.61721799999998,56.96888000000007],[-92.61000099999995,56.974709000000075],[-92.5891719999999,56.986382000000106],[-92.55277999999998,57.004714999999976],[-92.51445000000001,57.02360499999992],[-92.49221799999992,57.032493999999986],[-92.475281,57.03749800000014],[-92.44305400000002,57.044715999999994],[-92.40055799999999,57.052216000000044],[-92.37609899999995,57.056381000000044],[-92.25361599999997,57.065544000000045],[-92.23554999999999,57.06610100000012],[-92.22610500000002,57.065544000000045],[-92.21722399999999,57.063049000000035],[-92.21221899999995,57.058043999999995],[-92.21893299999999,57.052779999999984],[-92.33750900000001,56.981377000000066],[-92.34472700000003,56.977486],[-92.35221899999999,56.97415900000004],[-92.36833200000001,56.969711000000075],[-92.38555899999994,56.967209000000025],[-92.394455,56.96693399999998],[-92.41861,56.96193700000009],[-92.43222000000003,56.955826],[-92.46945199999999,56.93498999999997],[-92.46639999999996,56.93249500000013],[-92.375,56.94971499999991],[-92.30305499999997,56.96749100000011],[-92.28721599999994,56.97443400000009],[-92.281113,56.978874000000076],[-92.26861600000001,56.99082900000002],[-92.26194799999996,56.99582700000002],[-92.235275,57.012771999999984],[-92.22027600000001,57.01888300000002],[-92.204453,57.02416199999999],[-92.18028299999997,57.03082300000011],[-92.15527299999991,57.036658999999986],[-92.14666699999998,57.03777299999996],[-92.12916599999994,57.03943600000008],[-92.09306299999997,57.04083300000002],[-92.05776999999989,57.04388400000005],[-92.031677,57.04666099999997],[-91.987503,57.05248999999998],[-91.952225,57.05721299999999],[-91.828888,57.087211999999965],[-91.77999899999998,57.10027300000013],[-91.241104,57.22221400000001],[-91.15583799999996,57.23998999999998],[-91.08944699999995,57.25110600000011],[-91.05471799999998,57.25610400000011],[-91.03639199999998,57.258049000000085],[-91.00167799999991,57.26138300000008],[-90.99276700000001,57.26138300000008],[-90.83416699999992,57.257217000000026],[-90.81527699999998,57.25582900000012],[-90.795547,57.24971800000003],[-90.77917500000001,57.24332400000014],[-90.758896,57.237769999999955],[-90.73805199999993,57.23249099999998],[-90.71945199999999,57.228043000000014],[-90.70944199999997,57.22637900000001],[-90.56332399999991,57.21221200000008],[-90.45111099999997,57.1938780000001],[-90.408615,57.18166400000007],[-90.39167800000001,57.17610200000013],[-90.38778699999995,57.171378999999945],[-90.31082199999997,57.13499500000012],[-90.22555499999993,57.10443900000001],[-90.02500900000001,57.03138000000001],[-90.00500499999998,57.01915699999995],[-90,57.016369000000054],[-89.99055499999997,57.01110799999992],[-89.97027600000001,57.004166000000055],[-89.83306899999997,56.978324999999984],[-89.71528599999999,56.95721400000008],[-89.52139299999993,56.92943600000001],[-89.43916300000001,56.92388199999999],[-89.13294199999996,56.86485299999998],[-89.06806899999998,56.85221900000005],[-89.01528899999994,56.84777100000008],[-88.950287,56.843048000000124],[-88.94261199999994,56.844269000000054],[-88.81500199999999,56.82444000000004],[-88.74276700000001,56.764442000000145],[-88.67193599999996,56.70943500000004],[-88.65472399999993,56.696380999999974],[-88.63999899999999,56.68859900000007],[-88.63137799999998,56.68471500000004],[-88.58416699999992,56.670547],[-88.44055200000003,56.60360700000001],[-88.415009,56.58638000000002],[-88.36582900000002,56.561661000000015],[-88.32417299999997,56.54277000000002],[-88.218887,56.504440000000045],[-88.14944499999996,56.48693800000001],[-88.10305799999998,56.476097000000095],[-88.06973299999993,56.46888000000001],[-88.04888900000003,56.46554600000002],[-88.028885,56.459991000000116],[-88.01861600000001,56.45610000000005],[-87.98277299999995,56.441658000000075],[-87.97555499999993,56.43749199999996],[-87.84111000000001,56.315269],[-87.72389199999998,56.20388000000008],[-87.71916199999993,56.198875000000044],[-87.71501199999994,56.18998700000003],[-87.71556099999998,56.16971600000005],[-87.71389799999997,56.164993000000095],[-87.70805399999995,56.15609699999999],[-87.702789,56.15193199999999],[-87.54861499999993,56.04999500000014],[-87.478882,56.02916000000005],[-87.36888099999999,56.00083200000006],[-87.35194399999989,55.99276700000013],[-87.34527600000001,55.98860200000013],[-87.343613,55.983879],[-87.348343,55.973320000000115],[-87.35527000000002,55.96276900000004],[-87.19833399999999,55.940269],[-87.11000100000001,55.92943600000001],[-87.09167500000001,55.92748999999992],[-87.05722000000003,55.926941],[-87.03167699999995,55.92971800000009],[-86.99694799999997,55.931663999999955],[-86.97944599999994,55.931663999999955],[-86.97000099999997,55.92971800000009],[-86.88194299999992,55.90721100000002],[-86.837784,55.89138000000003],[-86.61694299999999,55.83888200000001],[-86.57278399999996,55.83027600000014],[-86.54444899999999,55.82444000000004],[-86.48666399999996,55.81137800000005],[-86.47778299999993,55.80888400000009],[-86.44860799999998,55.799995000000024],[-86.39862099999999,55.78416400000003],[-86.372772,55.77499399999999],[-86.346115,55.76305400000007],[-86.33277900000002,55.75471500000003],[-86.32194499999997,55.74554400000011],[-86.31527699999998,55.741104000000064],[-86.277222,55.72887399999996],[-86.26777600000003,55.72693600000002],[-85.86721799999998,55.657493999999986],[-85.74082900000002,55.63804600000009],[-85.731674,55.63694000000004],[-85.71444699999995,55.63166000000001],[-85.56945799999994,55.55860100000001],[-85.55665599999998,55.55027000000007],[-85.53222700000003,55.52804599999996],[-85.52583300000003,55.51888299999996],[-85.516663,55.50000000000006],[-85.515015,55.49527000000006],[-85.515289,55.490273000000116],[-85.50917099999998,55.48110200000002],[-85.499435,55.47221400000001],[-85.47416699999991,55.45471199999997],[-85.39334099999996,55.40888199999995],[-85.38362099999995,55.40499100000011],[-85.27223200000003,55.37470999999999],[-85.23472600000002,55.36471599999999],[-85.224716,55.364159000000086],[-85.20861799999994,55.36527300000006],[-85.18221999999997,55.36527300000006],[-85.164444,55.361664000000076],[-85.146118,55.354996000000085],[-85.12887599999999,55.346382000000006],[-85.12388599999986,55.34193400000004],[-85.12193300000001,55.33776900000004],[-85.11665299999993,55.323050999999964],[-85.11639400000001,55.31360600000011],[-85.11833199999995,55.30860100000007],[-85.12193300000001,55.303322000000094],[-85.129166,55.297775000000115],[-85.14416499999999,55.29027600000012],[-85.21528599999994,55.26860000000005],[-85.275284,55.21666000000005],[-85.398056,55.10083000000003],[-85.39999399999994,55.09582499999999],[-85.39750699999996,55.09054600000002],[-85.38362099999995,55.06749700000006],[-85.398056,55.0472180000001],[-85.41944899999999,55.01082600000012],[-85.425003,55.00027499999999],[-85.425003,54.99554400000005],[-85.42388900000003,54.99054699999999],[-85.41444399999995,54.991104000000064],[-85.40750099999997,54.99332400000009],[-85.40028399999994,54.997772000000055],[-85.38612399999994,55.00804900000003],[-85.37054399999994,55.02443700000009],[-85.36694299999999,55.029716000000064],[-85.36250299999989,55.04055000000011],[-85.347778,55.080826000000116],[-85.33555599999994,55.101661999999976],[-85.31834400000002,55.127486999999974],[-85.31304899999998,55.132767],[-85.22027599999996,55.22443400000009],[-85.19415300000003,55.24415599999992],[-85.17971799999998,55.253608999999926],[-85.156113,55.26416000000006],[-85.13999899999999,55.27027099999992],[-85.11665299999993,55.27665700000006],[-85.06806899999998,55.28749800000014],[-85.04388399999988,55.292770000000075],[-85.00195299999996,55.29666099999997],[-84.97471599999994,55.29583000000014],[-84.86944599999998,55.27971600000001],[-84.75140399999998,55.25610399999999],[-84.72361799999993,55.24971800000009],[-84.71278399999994,55.247772],[-84.68804899999992,55.24527000000012],[-84.635559,55.24221799999998],[-84.59916699999991,55.24166100000008],[-84.56639099999995,55.24415599999992],[-84.541382,55.247490000000084],[-84.44471699999986,55.267769000000044],[-84.428879,55.27304800000002],[-84.38861099999997,55.282493999999986],[-84.32278399999996,55.28999299999998],[-84.20695499999994,55.295547],[-84.19860799999998,55.295273000000066],[-84.189438,55.29415900000009],[-84.170837,55.28305100000006],[-84.15943899999996,55.2783280000001],[-84.14917000000003,55.27555100000001],[-84.12222300000002,55.27221700000001],[-84.11389200000002,55.27193499999993],[-84.09222399999999,55.27166000000011],[-84.07611099999997,55.27609999999993],[-84.04998799999993,55.286110000000065],[-84.006393,55.30138399999993],[-83.96888699999988,55.313881000000094],[-83.95167500000002,55.317497],[-83.93249499999996,55.319443000000035],[-83.92027300000001,55.31916000000007],[-83.8975069999999,55.3169400000001],[-83.65838600000001,55.23732400000006],[-83.65439600000002,55.235493000000076],[-83.65173299999992,55.23298599999998],[-83.57028199999996,55.18804200000011],[-83.56722999999994,55.18305200000003],[-83.57000700000003,55.17777300000006],[-83.58555599999994,55.16610000000003],[-83.5916749999999,55.15443400000004],[-83.58972199999994,55.149719000000005],[-83.57444799999996,55.138045999999974],[-83.561935,55.13082099999997],[-83.55665599999992,55.13416300000006],[-83.55665599999992,55.17943600000001],[-83.55860899999993,55.18498999999997],[-83.57950599999987,55.221157000000005],[-83.58805799999993,55.233330000000024],[-83.59388699999994,55.23693800000012],[-83.60082999999986,55.239990000000034],[-83.62083399999995,55.24276700000013],[-83.64389,55.24276700000013],[-83.65444899999994,55.2438810000001],[-83.670837,55.24860400000006],[-83.68443299999996,55.25443999999999],[-83.69610599999999,55.261664999999994],[-83.70611600000001,55.26971400000002],[-83.70889299999999,55.274437000000034],[-83.70611600000001,55.279990999999995],[-83.69860799999998,55.28305100000006],[-83.68888899999996,55.281937000000084],[-83.57417299999986,55.262215000000026],[-83.53332499999993,55.25054900000009],[-83.51945499999994,55.2438810000001],[-83.49888599999991,55.23554999999999],[-83.48944099999994,55.233879000000115],[-83.17971799999987,55.19721199999998],[-83.16860999999994,55.19748700000014],[-83.15028399999994,55.200271999999984],[-83.12805199999997,55.207497000000046],[-83.12027,55.21082300000012],[-83.08972199999994,55.22665400000005],[-83.07444799999996,55.23165899999992],[-83.03750599999995,55.23832700000008],[-83.02917499999995,55.238883999999985],[-83.00639299999995,55.23860200000013],[-82.98500100000001,55.236382000000106],[-82.964722,55.23360400000013],[-82.94860799999987,55.228874000000076],[-82.94166599999994,55.225821999999994],[-82.93055699999996,55.218323],[-82.91332999999986,55.20138500000007],[-82.906113,55.19193299999995],[-82.89695699999999,55.17721599999999],[-82.874435,55.15443400000004],[-82.83833300000003,55.146660000000054],[-82.80999800000001,55.14222000000001],[-82.78611799999999,55.141106000000036],[-82.77528399999994,55.14137999999997],[-82.76556399999987,55.14249399999994],[-82.73971599999993,55.14749100000006],[-82.708618,55.15638000000013],[-82.70083599999998,55.15971400000012],[-82.66972399999997,55.168052999999986],[-82.66111799999993,55.16971600000011],[-82.65028399999989,55.16971600000011],[-82.5083469999999,55.15277100000014],[-82.449432,55.133049000000085],[-82.41250600000001,55.112770000000125],[-82.40972899999997,55.108047],[-82.40083300000003,55.08277100000009],[-82.33555599999994,55.07101400000005],[-82.30749500000002,55.11582900000013],[-82.308044,55.121933000000126],[-82.3094329999999,55.127486999999974],[-82.3125,55.13249200000001],[-82.323624,55.13999200000006],[-82.33721899999995,55.14610299999998],[-82.34527600000001,55.1483310000001],[-82.35555999999997,55.162491000000045],[-82.34999099999987,55.16638200000011],[-82.34056099999998,55.16471100000001],[-82.333618,55.1616590000001],[-82.30776999999995,55.14888000000008],[-82.25418099999996,55.11138200000005],[-82.24583399999995,55.10277600000012],[-82.24499500000002,55.09027100000003],[-82.24694799999986,55.08416000000011],[-82.25334199999998,55.07360800000009],[-82.25778200000002,55.06888600000002],[-82.27362099999993,55.05721299999999],[-82.28222700000003,55.04804999999999],[-82.28527799999995,55.04277000000013],[-82.287216,55.03665900000004],[-82.287216,55.030273000000136],[-82.27084400000001,54.931381000000044],[-82.26722699999999,54.92027300000001],[-82.25527999999991,54.89415700000012],[-82.24694799999986,54.87943300000006],[-82.24137899999994,54.87499199999996],[-82.23194899999999,54.87387799999999],[-82.221115,54.787498000000085],[-82.32084699999996,54.571380999999974],[-82.403885,54.410820000000115],[-82.41915899999998,54.38416300000006],[-82.43167099999994,54.370270000000005],[-82.436935,54.36638599999998],[-82.441101,54.361664000000076],[-82.44166599999994,54.330826000000116],[-82.43415800000002,54.20943500000004],[-82.42166099999997,54.19721199999998],[-82.38999899999999,54.16832700000009],[-82.36277799999988,54.14360799999997],[-82.30139200000002,54.10305000000005],[-82.28388999999999,54.09249100000005],[-82.25334199999998,54.07610299999999],[-82.24804699999993,54.072220000000016],[-82.24388099999993,54.06805400000013],[-82.23832700000003,54.057495000000074],[-82.160278,53.89888000000013],[-82.13194299999998,53.817772000000105],[-82.13055399999996,53.793052999999986],[-82.12971500000003,53.77443699999998],[-82.13055399999996,53.767494],[-82.13667299999992,53.74916100000013],[-82.14889499999998,53.727768000000026],[-82.18998699999992,53.67416400000002],[-82.19415299999991,53.669441000000006],[-82.20306399999993,53.65332000000001],[-82.20834400000001,53.641936999999984],[-82.212784,53.622765000000015],[-82.21665999999999,53.60388200000011],[-82.21194499999996,53.536110000000065],[-82.208618,53.524994000000106],[-82.19888300000002,53.504714999999976],[-82.19055200000003,53.4897160000001],[-82.17250099999995,53.460548000000074],[-82.16555800000003,53.45138500000007],[-82.158615,53.44221500000003],[-82.14778100000001,53.421661000000086],[-82.13806199999999,53.38888500000013],[-82.12582399999997,53.34415400000012],[-82.11944599999998,53.31582600000013],[-82.11582900000002,53.29833200000007],[-82.11389199999991,53.28665900000004],[-82.11389199999991,53.280273000000136],[-82.11471599999987,53.273604999999975],[-82.11776699999996,53.26805099999996],[-82.12193299999996,53.26361099999997],[-82.14138799999995,53.25471500000003],[-82.21055599999994,53.22026800000003],[-82.24833699999994,53.193877999999984],[-82.26945499999994,53.16387900000001],[-82.27555799999999,53.15332000000012],[-82.27944899999994,53.14110600000009],[-82.30027799999993,53.060272],[-82.30139200000002,53.05332199999998],[-82.30166600000001,53.04166399999997],[-82.29666099999997,53.01859999999999],[-82.27389499999998,52.95638300000002],[-82.26139799999999,52.93721000000011],[-82.25750699999998,52.93277000000006],[-82.23582499999998,52.92416400000013],[-82.19638099999997,52.91332199999994],[-82.136124,52.89471400000008],[-82.120544,52.88971700000013],[-82.10166900000002,52.87999000000002],[-82.05055199999998,52.84304800000001],[-82.02583300000003,52.82388300000002],[-82.00111399999997,52.804710000000114],[-81.97778299999993,52.784996000000035],[-81.97361799999993,52.78054800000007],[-81.95140100000003,52.736938000000066],[-81.733612,52.54999500000014],[-81.71916199999998,52.53833000000009],[-81.71417200000002,52.53472100000005],[-81.69749499999995,52.52416200000005],[-81.63917500000002,52.490547000000106],[-81.62138400000003,52.480819999999994],[-81.60749799999996,52.475265999999976],[-81.577225,52.46527100000009],[-81.56945799999994,52.462212000000136],[-81.55804399999994,52.456099999999935],[-81.55416899999989,52.45166000000012],[-81.55139199999996,52.44665500000008],[-81.54998799999998,52.44110100000006],[-81.54249600000003,52.33888200000001],[-81.56138599999997,52.31638300000009],[-81.66305499999999,52.292220999999984],[-81.82250999999991,52.254440000000045],[-81.85082999999992,52.24499500000013],[-81.86305199999998,52.23888400000004],[-81.86582900000002,52.23333000000008],[-81.88362099999995,52.187492000000134],[-81.8741609999999,52.18832400000002],[-81.841949,52.19499200000001],[-81.82695000000001,52.19887499999993],[-81.80555700000002,52.20609999999999],[-81.795547,52.213882000000126],[-81.79249599999997,52.21915400000006],[-81.78860500000002,52.22387700000007],[-81.77944899999994,52.23220800000013],[-81.765015,52.23777000000007],[-81.75834699999996,52.23943300000002],[-81.74888599999997,52.24027300000006],[-81.71888699999988,52.240829000000076],[-81.55499299999985,52.23749500000008],[-81.52139299999993,52.23582500000009],[-81.50167799999997,52.23333000000008],[-81.47888199999994,52.22582200000005],[-81.472778,52.221930999999984],[-81.46000699999996,52.21027400000003],[-81.44360399999994,52.19276400000007],[-81.44055200000003,52.18859900000007],[-81.43443299999996,52.17916100000002],[-81.431671,52.17416400000013],[-81.43055700000002,52.16805300000004],[-81.41833500000001,52.149437000000034],[-81.41444399999995,52.14499699999999],[-81.40583800000002,52.13694000000004],[-81.36527999999998,52.10721600000005],[-81.35278299999999,52.10110500000013],[-81.337784,52.09610000000009],[-81.31054699999999,52.091102999999976],[-81.29083299999996,52.088599999999985],[-81.264725,52.08277099999998],[-81.21250900000001,52.06554399999999],[-81.18611099999987,52.053604000000064],[-81.16749600000003,52.04415899999998],[-81.11805700000002,52.04554700000011],[-80.99444599999993,52.01138300000008],[-80.98832700000003,52.008049000000085],[-80.97833300000002,52.000832],[-80.97444200000001,51.996384000000035],[-80.97305299999994,51.99082900000013],[-80.972778,51.9783250000001],[-80.92999299999997,51.92416399999996],[-80.91860999999994,51.91027100000014],[-80.89999399999994,51.89527099999998],[-80.89472999999998,51.89166300000005],[-80.80972300000002,51.857498000000135],[-80.69860799999998,51.79471599999994],[-80.61527999999993,51.73027000000013],[-80.610275,51.726379000000065],[-80.58917199999996,51.69971500000008],[-80.58917199999996,51.693321000000026],[-80.59028599999988,51.68665300000009],[-80.58999599999993,51.67416400000002],[-80.58612099999988,51.66360500000002],[-80.57888799999995,51.64860500000003],[-80.571396,51.633605999999986],[-80.515015,51.524437000000034],[-80.50750699999998,51.515830999999935],[-80.497772,51.508331000000055],[-80.46221899999989,51.48860199999996],[-80.45722999999992,51.484993000000145],[-80.44248999999996,51.47360200000003],[-80.43888900000002,51.46915400000006],[-80.43638599999986,51.464157000000114],[-80.43499800000001,51.458602999999925],[-80.42443800000001,51.36360899999994],[-80.42639200000002,51.35888700000004],[-80.43055700000002,51.35416400000008],[-80.44248999999996,51.34804500000007],[-80.47166400000003,51.33971400000013],[-80.50279199999994,51.331940000000145],[-80.54055800000003,51.323326000000066],[-80.56861900000001,51.314156000000025],[-80.65249599999999,51.27832799999999],[-80.69193999999999,51.24749000000003],[-80.70695499999994,51.2355500000001],[-80.83168,51.15582299999994],[-80.95249899999999,51.07972000000001],[-80.95944199999997,51.07749200000006],[-80.96528599999999,51.074440000000095],[-80.98111,51.06360600000005],[-80.9949949999999,51.0513840000001],[-81.00418100000002,51.043052999999986],[-81.01222200000001,51.03388200000006],[-81.015015,51.028328000000045],[-81.00527999999991,51.02860300000009],[-80.92805499999992,51.04583000000008],[-80.88833599999992,51.08277100000004],[-80.87527499999999,51.103324999999984],[-80.86221299999988,51.11610400000001],[-80.850281,51.12248999999997],[-80.83528099999995,51.12693800000011],[-80.82055700000001,51.130272000000105],[-80.79361,51.132767000000115],[-80.76501499999995,51.13360600000004],[-80.74804699999999,51.13665800000001],[-80.74082900000002,51.13888500000007],[-80.69444299999998,51.156097000000045],[-80.68859900000001,51.15915700000011],[-80.61000099999995,51.214157],[-80.56777999999997,51.25833100000011],[-80.56277499999999,51.26221499999997],[-80.541382,51.276657000000114],[-80.53056300000003,51.28360699999996],[-80.51251200000002,51.29276999999996],[-80.48028599999986,51.30721300000005],[-80.414444,51.332497000000046],[-80.40028399999989,51.33721200000008],[-80.39222699999999,51.338599999999985],[-80.37165800000002,51.33665500000001],[-80.33029199999999,51.32638500000007],[-80.21972700000003,51.30165900000003],[-80.19055199999997,51.297493000000145],[-80.1299899999999,51.297775],[-80.12027,51.296387000000095],[-80.01695299999994,51.263054000000125],[-79.99638399999992,51.25471500000009],[-79.80027799999999,51.156097000000045],[-79.78805499999993,51.14971900000012],[-79.741104,51.123604000000114],[-79.73638900000003,51.11971300000005],[-79.72917199999995,51.110825000000034],[-79.71651500000002,51.08171500000003],[-79.68510399999997,51.045361000000014],[-79.61277799999999,51.008049000000085],[-79.53761299999991,50.95839700000005],[-79.51972999999998,50.929993000000024],[-79.51611300000002,50.92638400000004],[-79.46610999999996,50.889434999999935],[-79.45056199999988,50.87860100000006],[-79.43859900000001,50.87221499999998],[-79.41500899999994,50.846939000000134],[-79.41139199999998,50.842490999999995],[-79.35278299999993,50.74832900000007],[-79.35028099999994,50.73693800000012],[-79.348053,50.73193400000014],[-79.34361299999989,50.728324999999984],[-79.33750900000001,50.72499099999999],[-79.33222999999998,50.723877000000016],[-79.33000199999992,50.758331000000055],[-79.33000199999992,50.76444200000009],[-79.33222999999998,50.77582600000005],[-79.42083699999995,50.87971500000003],[-79.43998699999992,50.8949970000001],[-79.464722,50.913321999999994],[-79.515015,50.95665699999995],[-79.537354,50.98376500000006],[-79.571121,51.00277699999998],[-79.66000400000001,51.04527300000001],[-79.67304999999988,51.05082700000003],[-79.67805499999992,51.054710000000114],[-79.69833399999993,51.07555400000007],[-79.70527600000003,51.08443500000004],[-79.749435,51.16832699999998],[-79.75195299999996,51.178878999999995],[-79.75222799999989,51.18443300000001],[-79.75111399999997,51.19748700000008],[-79.745544,51.208885000000066],[-79.74249299999997,51.214157],[-79.720551,51.243607000000054],[-79.70388799999995,51.26166500000011],[-79.69943199999994,51.26693700000004],[-79.68888899999996,51.28193700000003],[-79.68249500000002,51.29249600000003],[-79.68055699999991,51.298050000000046],[-79.67944299999999,51.30471000000006],[-79.66860999999994,51.39860500000009],[-79.59388699999994,51.44915800000007],[-79.58167999999995,51.45526899999999],[-79.5747219999999,51.4574970000001],[-79.54710399999988,51.46012900000011],[-79.53361499999994,51.50499700000006],[-79.47416699999997,51.579162999999994],[-79.37638900000002,51.64249400000011],[-79.353882,51.65609699999999],[-79.33168,51.66193399999992],[-79.32223499999998,51.66276600000003],[-79.23971599999999,51.63499499999995],[-79.23611499999993,51.63082099999991],[-79.23500099999995,51.62499200000008],[-79.23721299999994,51.61915600000003],[-79.25195299999996,51.60694100000012],[-79.275284,51.57777399999998],[-79.28527799999995,51.562492000000134],[-79.28527799999995,51.5563810000001],[-79.274719,51.530548000000124],[-79.271118,51.525551000000064],[-79.26722699999993,51.52166],[-79.20249899999999,51.51888300000007],[-79.18331899999998,51.51971400000008],[-79.17527799999993,51.521103000000096],[-79.16111799999993,51.525551000000064],[-79.15499899999998,51.528602999999976],[-79.14445499999994,51.536110000000065],[-79.13751200000002,51.53833000000009],[-79.12748699999986,51.538048],[-79.12027,51.53555299999999],[-79.02444500000001,51.47637900000012],[-79.02055399999995,51.473320000000115],[-79.01222199999995,51.4649960000001],[-79.00500499999993,51.44999700000005],[-78.96333299999998,51.3533250000001],[-78.95028699999995,51.29222100000004],[-78.95527600000003,51.25666000000007],[-78.95944199999991,51.25222000000002],[-78.96278399999994,51.24694100000005],[-78.96278399999994,51.24054699999999],[-78.95834400000001,51.23054500000006],[-78.95140100000003,51.21554600000002],[-78.93720999999994,51.19776900000011],[-78.92887899999994,51.18971300000004],[-78.92416400000002,51.185822000000144],[-78.91221599999994,51.17943600000007],[-78.906113,51.17665899999997],[-78.85333299999996,51.165543000000014],[-78.91471899999993,51.22165700000005],[-78.91833500000001,51.226097000000095],[-78.92054699999994,51.231102000000135],[-78.92166099999992,51.23749500000008],[-78.92027300000001,51.24971800000014],[-78.89056399999993,51.39054900000002],[-78.88833599999998,51.39666000000011],[-78.88305700000001,51.4011000000001],[-78.83222999999998,51.43859900000001],[-78.77917500000001,51.47499099999999],[-78.82028200000002,51.51305400000007],[-78.82389799999999,51.517494000000056],[-78.82611099999997,51.522491],[-78.82444800000002,51.54166400000008],[-78.82084699999996,51.55443600000007],[-78.80860899999999,51.576385000000016],[-78.791672,51.60388199999994],[-78.79638699999992,51.608604000000014],[-78.85916099999997,51.63416300000006],[-78.94415300000003,51.670547000000056],[-79.03472899999997,51.76471700000013],[-79.035553,51.77027100000009],[-79.03332499999988,51.77638200000001],[-79.02917499999995,51.78138000000001],[-79.00834699999996,51.79583000000014],[-78.995834,51.80165899999997],[-78.98582499999998,51.80165899999997],[-78.9761049999999,51.79972099999998],[-78.96139499999987,51.79499800000002],[-78.94444299999986,51.79083300000002],[-78.91805999999997,51.79444100000012],[-78.91082799999998,51.79666099999997],[-78.90360999999996,51.79943800000001],[-78.87998999999996,51.811378000000104],[-78.851944,51.828606000000036],[-78.84638999999999,51.8324970000001],[-78.83694500000001,51.841377000000136],[-78.833618,51.845825000000104],[-78.83222999999998,51.85277600000006],[-78.83444199999997,51.85777299999995],[-78.84167499999995,51.866661000000136],[-78.84638999999999,51.87026999999995],[-78.85861199999994,51.87693800000011],[-78.86361699999992,51.88082100000008],[-78.89555399999989,51.92665900000003],[-78.89639299999993,51.932495000000074],[-78.89416499999999,51.93832400000008],[-78.88194299999992,51.944435],[-78.86027499999989,51.95110299999993],[-78.851944,51.95249200000012],[-78.81054699999993,51.958885000000066],[-78.769455,51.96610300000009],[-78.747772,51.97332],[-78.73666400000002,51.97943100000009],[-78.695831,52.008049000000085],[-78.57945299999994,52.111382000000106],[-78.53750599999995,52.18082400000014],[-78.50111399999997,52.255829000000006],[-78.52444500000001,52.311104000000114],[-78.516953,52.36776700000007],[-78.50723299999999,52.45443700000004],[-78.506958,52.460548000000074],[-78.54527300000001,52.51471700000013],[-78.56471299999998,52.53027300000008],[-78.577225,52.536658999999986],[-78.585556,52.538605000000075],[-78.59584000000001,52.53888699999999],[-78.65444899999994,52.54694400000011],[-78.68443300000001,52.551383999999985],[-78.76333599999998,52.56443800000005],[-78.76112399999994,52.570549000000085],[-78.75556899999992,52.574164999999994],[-78.721115,52.58665500000012],[-78.69193999999993,52.59609999999998],[-78.71333300000003,52.628876000000105],[-78.75306699999987,52.68387599999994],[-78.79083300000002,52.73749500000014],[-78.79695099999998,52.77388000000008],[-78.765015,52.77748900000012],[-78.73194899999999,52.783333000000084],[-78.72471599999994,52.78555300000011],[-78.7225039999999,52.791664000000026],[-78.72555499999999,52.819443000000035],[-78.73832700000003,52.8722150000001],[-78.79444899999999,52.861381999999935],[-78.85610999999989,52.877769000000114],[-78.880829,52.896942000000024],[-78.88194299999992,52.90277100000003],[-78.87860099999989,52.908043000000134],[-78.86471599999999,52.96360800000008],[-78.91583300000002,53.00000000000006],[-78.92304999999993,53.06888600000008],[-78.88806199999993,53.22470900000013],[-78.894455,53.25972000000007],[-78.89584400000001,53.26527400000009],[-78.94249000000002,53.38499499999995],[-78.94972200000001,53.39999400000005],[-78.99172199999992,53.43404800000002],[-78.99472000000003,53.43637800000005],[-79.00455499999993,53.43921699999993],[-79.00955199999993,53.43821300000002],[-79.04472399999997,53.439430000000016],[-79.05305499999997,53.43804200000005],[-79.06332399999997,53.439430000000016],[-79.06806899999992,53.44332100000008],[-79.09028599999999,53.47054300000002],[-79.09306299999997,53.474709000000075],[-79.10777300000001,53.4972150000001],[-79.110275,53.502495000000124],[-79.10360699999995,53.51305400000001],[-79.08416699999998,53.522491000000116],[-79.05444299999994,53.53138000000001],[-79.035553,53.53276800000009],[-79.012787,53.53110499999997],[-79.031387,53.52971600000001],[-79.03805499999999,53.526657],[-79.04333499999996,53.52304800000002],[-79.04249599999991,53.51110800000009],[-79.041382,53.50555400000013],[-79.03639199999998,53.501663000000065],[-79.01483899999994,53.498940000000005],[-79.01100200000002,53.496937],[-79.00567599999994,53.49577000000005],[-79.00067899999993,53.496609000000035],[-78.96278399999994,53.50888800000013],[-78.91915899999998,53.55526700000007],[-78.91583300000002,53.5605470000001],[-78.91833500000001,53.565544000000045],[-78.92193599999996,53.56999200000001],[-78.95056199999999,53.599716],[-79.00334199999992,53.64166300000005],[-79.08972199999994,53.691658000000075],[-79.14500399999997,53.70166000000006],[-79.15139799999992,53.704994000000056],[-79.152222,53.71054800000002],[-79.05249000000003,53.831939999999975],[-79.04695100000004,53.835548000000074],[-79.039444,53.83776899999998],[-79.02972399999999,53.839157000000114],[-79.011124,53.839989],[-78.98889199999991,53.83888200000007],[-78.97999599999997,53.836104999999975],[-78.9661099999999,53.83027600000014],[-78.94833399999993,53.82083100000011],[-78.93277,53.81554399999999],[-78.91082799999998,53.81443799999994],[-78.90139799999997,53.815268999999944],[-78.90222199999994,53.821380999999974],[-78.90638699999994,53.82527200000004],[-78.91776999999996,53.83221400000008],[-78.92416400000002,53.835548000000074],[-78.96972700000003,53.851387000000045],[-78.98889199999991,53.85471300000006],[-79.01194800000002,53.85665899999998],[-79.05665599999992,53.873046999999985],[-79.10110499999996,53.90165700000006],[-79.10611,53.905548000000124],[-79.07250999999985,53.99916100000007],[-79.066956,54.002777000000094],[-79.05110200000001,54.00666000000007],[-79.041382,54.00777400000004],[-79.03167699999995,54.00777400000004],[-79.02139299999999,54.006386000000134],[-79.00109899999995,53.99999200000008],[-78.96495099999993,53.99716200000006],[-78.96162399999997,53.99999200000008],[-78.96028099999995,54.00138900000002],[-78.96278399999994,54.006386000000134],[-78.96665999999993,54.01082600000012],[-78.97666900000002,54.018326],[-78.98416099999997,54.02166],[-79.11944599999998,54.07860599999998],[-79.11639399999996,54.10305000000005],[-79.10638399999993,54.11138200000005],[-79.04638699999998,54.178329000000076],[-79.04888900000003,54.18332700000008],[-79.06054699999999,54.18415800000008],[-79.17332499999998,54.17499500000008],[-79.191666,54.17276800000002],[-79.19804399999987,54.16971600000011],[-79.19694499999997,54.16360500000002],[-79.19833399999999,54.15721099999996],[-79.20584099999991,54.154990999999995],[-79.23805199999998,54.15888200000006],[-79.27639799999992,54.16693900000001],[-79.34527600000001,54.199432],[-79.41999800000002,54.274437000000034],[-79.43055700000002,54.29027599999995],[-79.47666900000002,54.36859900000013],[-79.50500499999993,54.42582700000014],[-79.48805199999993,54.45221700000013],[-79.48805199999993,54.45860300000004],[-79.52139299999999,54.587212000000136],[-79.52528399999989,54.591377000000136],[-79.531677,54.59471100000013],[-79.56555200000003,54.609993000000145],[-79.61888099999993,54.62387800000005],[-79.67555199999993,54.62582400000014],[-79.68611099999998,54.62721299999993],[-79.76083399999999,54.648048000000074],[-79.76444999999995,54.65221400000013],[-79.761124,54.65832500000005],[-79.63166799999993,54.70277399999998],[-79.49415599999998,54.744713000000104],[-79.46362299999998,54.75360900000004],[-79.45722999999992,54.750275000000045],[-79.44749499999995,54.75110600000005],[-79.33778399999994,54.77249100000006],[-79.31582600000002,54.77999100000011],[-79.10110499999996,54.82721699999996],[-78.97666900000002,54.843048000000124],[-78.968887,54.845267999999976],[-78.95666499999999,54.85193600000014],[-78.94554099999993,54.85943600000002],[-78.9125059999999,54.884163000000115],[-78.83860800000002,54.91443600000008],[-78.73277300000001,54.93110700000011],[-78.56111099999993,54.97776799999991],[-78.37388599999997,55.030273000000136],[-78.2561189999999,55.08221400000002],[-78.207672,55.11165599999998],[-78.18222000000003,55.12526700000012],[-78.11944599999998,55.14999400000005],[-77.972778,55.20499400000011],[-77.87249799999995,55.243607],[-77.74861099999998,55.30082700000003],[-77.62222300000002,55.382766999999944],[-77.41665599999999,55.48610700000006],[-77.22582999999997,55.58832600000011],[-77.214722,55.595267999999976],[-77.1372219999999,55.65416000000005],[-77.11527999999993,55.67416400000013],[-77.10472099999998,55.683876000000055],[-77.08833299999992,55.69943200000006],[-77.08612099999993,55.70555100000007],[-77.085556,55.70804600000008],[-77.08778399999994,55.709716999999955],[-77.06834399999997,55.75471500000003],[-77.01306199999988,55.803046999999935],[-76.81138599999997,55.97110000000009],[-76.75195300000001,55.997772],[-76.737503,56.001663000000065],[-76.718887,56.00804899999997],[-76.70249899999993,56.017494000000056],[-76.6891629999999,56.027489],[-76.68194599999998,56.03388200000012],[-76.67721599999993,56.038605000000075],[-76.67083699999989,56.04583000000014],[-76.65805099999994,56.06082199999997],[-76.65083300000003,56.0719380000001],[-76.62666299999995,56.11804999999998],[-76.53832999999997,56.297775000000115],[-76.53222700000003,56.315269],[-76.53111299999995,56.32222000000013],[-76.51889,56.4060970000001],[-76.51750199999998,56.423325000000034],[-76.51750199999998,56.43582200000003],[-76.51916499999999,56.46471400000007],[-76.52583299999998,56.49276700000007],[-76.527222,56.50305200000014],[-76.52639799999992,56.60582700000003],[-76.50695799999994,56.710823000000005],[-76.50500499999998,56.733879],[-76.50445599999995,56.771934999999985],[-76.50556899999992,56.78499599999992],[-76.50527999999991,56.791382000000056],[-76.50556899999992,56.803047000000106],[-76.50944500000003,56.819717000000026],[-76.53083800000002,56.90665400000006],[-76.55444299999999,57.00582899999995],[-76.55471799999992,57.010826000000066],[-76.55583200000001,57.03499600000009],[-76.55332900000002,57.053322000000094],[-76.54916400000002,57.06221000000005],[-76.54527299999995,57.068885999999964],[-76.535553,57.07777399999998],[-76.53111299999995,57.087211999999965],[-76.52917500000001,57.09665700000005],[-76.52972399999987,57.10582700000009],[-76.564438,57.20721400000008],[-76.59138499999995,57.27443699999998],[-76.59999099999993,57.29361000000006],[-76.60444599999988,57.30277300000006],[-76.65306099999992,57.40138200000001],[-76.65834000000001,57.406653999999946],[-76.68804899999998,57.43055000000004],[-76.73222399999992,57.49027300000006],[-76.74082900000002,57.50332600000007],[-76.81138599999997,57.62471000000011],[-76.80943300000001,57.634720000000016],[-76.80777,57.641662999999994],[-76.80555700000002,57.647774000000084],[-76.86193799999995,57.71915400000006],[-76.92304999999999,57.786110000000065],[-77.14723199999997,58.02276599999993],[-77.24665800000002,58.07388300000008],[-77.27972399999999,58.08443500000004],[-77.31750499999998,58.09193400000004],[-77.34944200000001,58.10193600000002],[-77.44444299999998,58.152489],[-77.45111099999997,58.171379000000115],[-77.44665500000002,58.173882000000106],[-77.44110099999995,58.18277000000006],[-77.44415299999997,58.18776700000001],[-77.454453,58.19638100000003],[-77.46722399999999,58.203323000000125],[-77.48777799999993,58.212769000000094],[-77.57167099999998,58.2480470000001],[-77.64584399999995,58.27860300000003],[-77.81527699999998,58.32721700000002],[-77.851944,58.334991],[-77.883896,58.339989],[-77.91444399999995,58.34554300000002],[-77.93916300000001,58.35305000000011],[-77.95527600000003,58.35860400000013],[-78.01251200000002,58.378601],[-78.02444500000001,58.384163000000115],[-78.02806099999998,58.38694000000004],[-78.03138699999994,58.39138000000003],[-78.06268299999999,58.4173090000001],[-78.13055399999996,58.46276900000004],[-78.35555999999997,58.601661999999976],[-78.39723199999992,58.62082700000013],[-78.41999800000002,58.62721300000004],[-78.42527799999999,58.62609900000007],[-78.42832900000002,58.62360400000006],[-78.42777999999998,58.61110700000006],[-78.42610199999996,58.60610200000002],[-78.347778,58.53665900000004],[-78.38972499999988,58.54471600000005],[-78.5491639999999,58.603882],[-78.56388900000002,58.60999300000009],[-78.56861899999996,58.614441000000056],[-78.57389799999993,58.630547000000035],[-78.57472200000001,58.63526900000011],[-78.57000699999998,58.6730500000001],[-78.56388900000002,58.676941],[-78.55583199999995,58.67777300000006],[-78.54388399999999,58.67804699999999],[-78.51472499999994,58.67943600000001],[-78.46972700000003,58.695541000000105],[-78.46722399999999,58.70166000000012],[-78.48832699999997,58.78638500000005],[-78.50556899999998,58.835266000000104],[-78.51167299999992,58.839157],[-78.51640299999997,58.843323000000055],[-78.53860500000002,58.886940000000095],[-78.57139599999988,58.95721400000008],[-78.57055700000001,58.96138000000013],[-78.561935,58.9658280000001],[-78.55221599999999,58.968048000000124],[-78.39639299999993,58.96471400000013],[-78.36166399999996,58.95860300000004],[-78.35249299999992,58.95665700000001],[-78.34638999999999,58.95360599999998],[-78.34445199999988,58.949432000000115],[-78.34472699999998,58.94665500000002],[-78.34527600000001,58.94471000000004],[-78.34834299999994,58.942214999999976],[-78.36639400000001,58.92027300000012],[-78.36389200000002,58.91249099999999],[-78.35777300000001,58.910270999999966],[-78.34583999999995,58.909714000000065],[-78.33833300000003,58.91276600000003],[-78.31082199999997,58.9272160000001],[-78.30471799999992,58.931107],[-78.20556599999998,59.05054500000011],[-78.12748699999997,59.108330000000024],[-78.08666999999997,59.156654],[-78.093887,59.193047000000035],[-78.09861799999999,59.196655000000135],[-78.10194399999995,59.200829],[-78.103882,59.205826000000116],[-78.09277299999991,59.214995999999985],[-77.96112099999993,59.25833100000011],[-77.94972199999995,59.261939999999925],[-77.93028300000003,59.26527399999992],[-77.88444500000003,59.27193500000004],[-77.86000099999995,59.272217000000126],[-77.843613,59.27555100000012],[-77.82888799999995,59.28110500000008],[-77.82444800000002,59.28360699999996],[-77.68499799999995,59.393326000000116],[-77.67721599999999,59.399994000000106],[-77.67832899999996,59.401932000000045],[-77.77917500000001,59.426102000000014],[-77.787216,59.426658999999916],[-77.79804999999999,59.4263840000001],[-77.83138999999994,59.41471100000007],[-77.88027999999991,59.39916199999999],[-77.88751200000002,59.397491000000116],[-77.89695699999999,59.39721700000001],[-77.902222,59.39888000000008],[-77.90583800000002,59.4011000000001],[-77.91027799999995,59.40554800000007],[-77.91250600000001,59.41526799999997],[-77.91055299999988,59.42555199999998],[-77.872772,59.49193599999995],[-77.86749299999991,59.5],[-77.86111499999987,59.50388300000009],[-77.84056099999998,59.51305400000007],[-77.79888900000003,59.52499399999999],[-77.77917500000001,59.52887700000008],[-77.76945499999994,59.52916000000005],[-77.74999999999989,59.532211000000075],[-77.72138999999993,59.539719000000105],[-77.724716,59.59388000000001],[-77.75500499999993,59.62832600000007],[-77.76278699999989,59.63137800000004],[-77.76750199999992,59.63499499999995],[-77.79777499999994,59.67027299999995],[-77.80110200000001,59.67527000000007],[-77.79861499999993,59.67999300000008],[-77.77389499999998,59.70971700000007],[-77.76167299999997,59.709991],[-77.73194899999999,59.70777099999998],[-77.71055599999988,59.70471200000003],[-77.58522800000003,59.66921200000013],[-77.53988599999991,59.65338100000014],[-77.53539299999994,59.65137900000008],[-77.52439099999992,59.644714000000135],[-77.51888999999989,59.63938100000013],[-77.51322900000002,59.63054699999998],[-77.51372500000002,59.62021599999997],[-77.51489300000003,59.614044000000035],[-77.464722,59.58721200000002],[-77.46000699999996,59.58277100000009],[-77.45417799999996,59.579162999999994],[-77.44499200000001,59.576385000000016],[-77.42694099999994,59.57138100000003],[-77.35360700000001,59.563605999999936],[-77.32250999999991,59.56276700000001],[-77.31388900000002,59.564995000000124],[-77.311935,59.56693999999993],[-77.316956,59.56999200000007],[-77.34416199999998,59.57694200000009],[-77.42799400000001,59.619049000000075],[-77.433334,59.62054399999994],[-77.441666,59.62471799999997],[-77.50233500000002,59.67821500000002],[-77.54249600000003,59.747490000000084],[-77.541946,59.75027499999993],[-77.53306599999996,59.754714999999976],[-77.43276999999995,59.784163999999976],[-77.41278099999994,59.78777300000013],[-77.38944999999995,59.78888699999993],[-77.333618,59.78527100000008],[-77.31166099999996,59.785552999999936],[-77.30471799999998,59.78721600000006],[-77.29888900000003,59.78971900000005],[-77.29360999999989,59.793610000000115],[-77.29611199999994,59.801933000000076],[-77.30139200000002,59.811104],[-77.36361699999986,59.89083099999999],[-77.36805699999996,59.89471400000008],[-77.37805199999997,59.90138200000007],[-77.385559,59.90443399999998],[-77.42748999999998,59.914710999999954],[-77.206955,60.04277000000002],[-77.07000699999992,60.06415600000008],[-76.84805299999994,60.09915900000004],[-76.77583300000003,60.131659999999954],[-76.77084399999995,60.13638300000014],[-76.758896,60.15915700000011],[-76.80860899999993,60.15971400000001],[-76.82833900000003,60.157493999999986],[-76.846115,60.15221400000013],[-76.85249299999998,60.148330999999985],[-76.85777299999995,60.14388300000002],[-76.86054999999993,60.137771999999984],[-76.85749800000002,60.132767000000115],[-76.854172,60.121658000000025],[-76.85943599999996,60.11693600000012],[-76.86694299999999,60.113883999999985],[-76.889725,60.112495000000024],[-76.9244379999999,60.11166400000002],[-76.95056199999993,60.11221300000011],[-76.962784,60.113609],[-77.00389100000001,60.12193300000001],[-77.03138699999988,60.129714999999976],[-77.05555699999996,60.13860299999999],[-77.07417299999997,60.142769000000044],[-77.11193800000001,60.146942000000024],[-77.17388899999997,60.15026899999992],[-77.18749999999994,60.15082600000005],[-77.19999699999994,60.15082600000005],[-77.19972200000001,60.14527099999992],[-77.19471699999997,60.129158000000075],[-77.23249800000002,60.05387900000011],[-77.27278100000001,60.039993000000095],[-77.31582599999996,60.03054800000007],[-77.51916499999999,60.044159000000036],[-77.54028299999999,60.0480500000001],[-77.55721999999997,60.05277300000006],[-77.59222399999999,60.06415600000008],[-77.60028099999994,60.10860400000013],[-77.5952759999999,60.112495000000024],[-77.58168,60.1188810000001],[-77.55804399999994,60.126656000000025],[-77.54916400000002,60.129158000000075],[-77.49694799999992,60.156097000000045],[-77.47027600000001,60.213325999999995],[-77.47361799999993,60.216934000000094],[-77.60278299999993,60.329994000000056],[-77.63972499999994,60.362213000000054],[-77.6475069999999,60.365273000000116],[-77.65833999999995,60.36805000000004],[-77.68306000000001,60.36776700000007],[-77.69248999999996,60.369438000000116],[-77.70834400000001,60.37582400000002],[-77.743607,60.39332600000006],[-77.74722299999996,60.39694200000014],[-77.74775699999992,60.40813400000013],[-77.74082900000002,60.423607000000004],[-77.73693799999995,60.42887900000011],[-77.71945199999999,60.44721199999998],[-77.69193999999993,60.466660000000104],[-77.56750499999993,60.52971600000001],[-77.47999599999991,60.54055000000011],[-77.43083200000001,60.54027599999995],[-77.41972399999992,60.54110700000001],[-77.41332999999997,60.54415900000009],[-77.43638599999991,60.55443600000007],[-77.464447,60.56193500000006],[-77.48611499999993,60.56638300000003],[-77.52166699999998,60.5702740000001],[-77.54943800000001,60.57138100000003],[-77.57362399999994,60.570549000000085],[-77.59861799999993,60.56360600000011],[-77.63194299999998,60.551933000000076],[-77.64056399999998,60.55027000000001],[-77.65055799999999,60.54888200000005],[-77.67027300000001,60.549721000000034],[-77.68083199999995,60.552216000000044],[-77.704453,60.56166100000013],[-77.787216,60.59665700000005],[-77.829453,60.63360599999993],[-77.83389299999993,60.63943499999999],[-77.83167999999995,60.644714000000135],[-77.82167099999987,60.65193199999993],[-77.77583299999998,60.67110400000013],[-77.72250400000001,60.69193300000012],[-77.71639999999996,60.694435],[-77.61000100000001,60.755554000000075],[-77.51583900000003,60.830551000000014],[-77.51251200000002,60.833602999999925],[-77.51167299999997,60.83638000000002],[-77.53195199999999,60.83526600000005],[-77.57167099999998,60.82833099999999],[-77.708054,60.79554700000011],[-77.85638399999993,60.76444200000009],[-77.920547,60.79138200000011],[-77.903885,60.81249200000008],[-77.88999899999999,60.818886000000134],[-77.88333099999994,60.82332599999995],[-77.88722200000001,60.82582900000011],[-77.89639299999988,60.828049000000135],[-77.90916399999998,60.82888000000014],[-77.97528099999994,60.82276900000005],[-78.0786129999999,60.80609900000013],[-78.11694299999999,60.7980500000001],[-78.12582399999997,60.79554700000011],[-78.17250099999995,60.78721600000006],[-78.17971799999998,60.786942000000124],[-78.18638599999997,60.78804799999995],[-78.19055200000003,60.7888870000001],[-78.19276400000001,60.79083300000002],[-78.17166099999992,60.85471300000006],[-78.15943900000002,60.86721000000006],[-77.95472699999999,61.000831999999946],[-77.92555199999993,61.01888300000013],[-77.88917500000002,61.03804800000012],[-77.87361099999993,61.045547000000056],[-77.85804699999994,61.05110199999996],[-77.85388199999994,61.05221599999999],[-77.84666400000003,61.05249000000009],[-77.70167500000002,61.21749100000011],[-77.72444199999995,61.25443999999999],[-77.73999000000003,61.29860700000006],[-77.74665800000002,61.337494000000106],[-77.76112399999994,61.41027100000002],[-77.678879,61.461104999999975],[-77.620834,61.46249399999999],[-77.56361400000003,61.46666000000005],[-77.56054699999993,61.46804799999995],[-77.54249600000003,61.47943099999998],[-77.54333500000001,61.483047000000056],[-77.54833999999994,61.48610700000012],[-77.61389200000002,61.504166000000055],[-77.59611499999994,61.55582400000014],[-77.57278400000001,61.54999500000014],[-77.51722699999993,61.53971900000005],[-77.47860700000001,61.53638500000005],[-77.47500599999995,61.539161999999976],[-77.47471599999994,61.541664000000026],[-77.48028599999992,61.54888200000005],[-77.58139,61.60054800000012],[-77.58917199999996,61.60443900000001],[-77.61650099999997,61.60632700000008],[-77.62799799999999,61.60599500000012],[-77.66749600000003,61.603049999999996],[-77.69082599999996,61.60221899999999],[-77.70249899999999,61.60277600000006],[-77.71055599999988,61.60582700000009],[-77.74415599999998,61.64027400000009],[-77.816666,61.684989999999914],[-77.88444500000003,61.68582200000003],[-77.89889499999992,61.68637800000005],[-77.93138099999993,61.69193300000012],[-77.97582999999997,61.70277400000003],[-77.98222399999997,61.70665699999995],[-77.99249299999997,61.71471400000013],[-78.00306699999993,61.7283250000001],[-78.00611900000001,61.733047],[-78.01194799999996,61.74860400000006],[-78.0744479999999,61.917213000000004],[-78.07749899999999,61.940544000000045],[-78.08139,61.9511030000001],[-78.09167500000001,61.96527100000014],[-78.11000100000001,61.984161000000086],[-78.12026999999995,61.99193600000001],[-78.137787,62.009163],[-78.14138799999995,62.020546000000024],[-78.14361600000001,62.03138000000007],[-78.15943900000002,62.14999400000005],[-78.16166699999997,62.169159000000036],[-78.15777600000001,62.267494000000056],[-78.15583799999996,62.2783280000001],[-78.14973399999997,62.287216000000114],[-78.10305800000003,62.33749400000005],[-78.08500700000002,62.35332500000004],[-78.02389499999998,62.39332600000006],[-78.01640299999997,62.39388300000013],[-78.0080569999999,62.390549000000135],[-77.99665799999997,62.388046000000145],[-77.98306300000002,62.38832900000011],[-77.96305799999999,62.39276899999999],[-77.71139499999992,62.468048000000124],[-77.68721,62.47665400000005],[-77.55555699999996,62.53611000000001],[-77.535278,62.54694400000011],[-77.50834700000001,62.56166100000007],[-77.35499600000003,62.55804400000011],[-77.07362399999994,62.534163999999976],[-76.92582699999997,62.52638200000001],[-76.756958,62.50694300000009],[-76.74694799999997,62.504997],[-76.65556299999997,62.46998600000006],[-76.49861099999987,62.44110100000006],[-76.401947,62.42749000000009],[-76.31777999999991,62.41220900000013],[-76.14306599999992,62.37915800000002],[-75.70973200000003,62.29638700000004],[-75.71921499999996,62.242493000000024],[-75.73956299999992,62.23616000000004],[-75.819885,62.20565799999997],[-75.87887599999999,62.168602000000135],[-75.89111300000002,62.161933999999974],[-75.89500399999991,62.15859999999998],[-75.89083900000003,62.156937000000084],[-75.83583099999998,62.15804300000008],[-75.82694999999995,62.15888200000006],[-75.77239999999995,62.17721599999999],[-75.77072099999992,62.180049999999994],[-75.76505299999991,62.18471899999997],[-75.76088700000003,62.18705000000011],[-75.75605799999988,62.18871300000001],[-75.705063,62.203216999999995],[-75.656883,62.216544999999996],[-75.5791779999999,62.24221800000004],[-75.57389799999993,62.244155999999975],[-75.55694599999993,62.25277700000004],[-75.55277999999993,62.25666000000001],[-75.55027799999993,62.260826000000066],[-75.53944399999989,62.268326],[-75.493607,62.29332699999998],[-75.48693799999995,62.29638700000004],[-75.478882,62.29860700000006],[-75.47277799999995,62.299438000000066],[-75.40222199999994,62.306381000000044],[-75.35638399999999,62.310546999999985],[-75.32194500000003,62.31110400000006],[-75.30749500000002,62.31027199999994],[-75.18443299999996,62.292220999999984],[-75.01556399999998,62.264999000000046],[-75,62.262245000000064],[-74.93832399999991,62.25027499999999],[-74.91861,62.24554400000005],[-74.89805599999994,62.240273],[-74.88999899999999,62.237495000000024],[-74.88221699999991,62.23360400000013],[-74.87388599999986,62.22609700000004],[-74.76722699999988,62.161102000000085],[-74.70083599999987,62.13110400000011],[-74.69305400000002,62.12776900000006],[-74.66888399999999,62.11915600000009],[-74.62083399999989,62.107215999999994],[-74.59805299999994,62.10416400000008],[-74.57167099999998,62.10305000000011],[-74.55638099999999,62.104713000000004],[-74.55305499999997,62.10610200000002],[-74.553879,62.108047],[-74.55860899999988,62.111938000000066],[-74.61888099999993,62.13249200000001],[-74.662216,62.146660000000054],[-74.68611099999998,62.155823000000055],[-74.700287,62.16276600000009],[-74.75111400000003,62.19110100000006],[-74.758896,62.19915800000007],[-74.75973499999992,62.20138500000013],[-74.75973499999992,62.20638300000013],[-74.756393,62.212212000000136],[-74.72582999999992,62.24499500000013],[-74.71749899999992,62.247772],[-74.700287,62.25083200000006],[-74.67832899999996,62.25360899999998],[-74.64584400000001,62.25360899999998],[-74.579453,62.25193800000011],[-74.52583300000003,62.24694099999999],[-74.47361799999993,62.24332400000003],[-74.46139499999998,62.24388099999993],[-74.42887899999994,62.247772],[-74.41000400000001,62.25138900000013],[-74.38389599999994,62.2586060000001],[-74.14167799999996,62.326660000000004],[-73.98138399999999,62.377769],[-73.97444200000001,62.386108000000036],[-73.96972700000003,62.39083099999999],[-73.94027699999998,62.41220900000013],[-73.88890100000003,62.44054399999993],[-73.83805799999999,62.457497000000046],[-73.68804899999998,62.47998800000005],[-73.678879,62.47998800000005],[-73.65972899999997,62.475265999999976],[-73.64834599999995,62.468323],[-73.64250199999992,62.463608000000136],[-73.502792,62.38665800000007],[-73.36999500000002,62.363609000000054],[-73.22721899999988,62.318054000000075],[-73.21139499999992,62.31276700000001],[-73.20666499999999,62.308884000000035],[-73.20417800000001,62.303878999999995],[-73.202789,62.298882000000106],[-73.20722999999992,62.28582800000004],[-73.21028099999995,62.28193699999997],[-73.21083099999998,62.27582600000005],[-73.20973200000003,62.27082800000005],[-73.20417800000001,62.26138299999997],[-73.19193999999987,62.25360899999998],[-73.17805499999997,62.246101000000124],[-73.13194299999998,62.22526600000003],[-73.07000699999998,62.197487000000024],[-72.89944500000001,62.138329],[-72.72389199999992,62.142220000000066],[-72.62666300000001,62.11554700000005],[-72.61721799999998,62.10860400000007],[-72.59611499999988,62.04916400000002],[-72.61871300000001,61.97421299999996],[-72.619888,61.97087899999997],[-72.66571799999991,61.928383],[-72.68998699999992,61.891936999999984],[-72.74861099999998,61.856384000000105],[-72.724716,61.845267999999976],[-72.612503,61.80499300000008],[-72.60278299999993,61.804160999999965],[-72.59611499999988,61.80554999999998],[-72.59167499999995,61.80998999999997],[-72.58778399999989,61.82027400000004],[-72.62277199999994,61.861382000000106],[-72.62887599999999,61.87304700000004],[-72.60955799999999,61.88771400000013],[-72.61089300000003,61.893714999999986],[-72.61139700000001,61.900047000000086],[-72.61022200000002,61.90538000000009],[-72.607552,61.910049000000015],[-72.59754899999996,61.92021199999999],[-72.593887,61.92321400000003],[-72.58722699999998,61.92437699999999],[-72.58122299999997,61.92337800000013],[-72.51972999999992,61.920547],[-72.44860799999998,61.90138200000001],[-72.39666699999992,61.88943500000005],[-72.38694800000002,61.887771999999984],[-72.345551,61.88443799999999],[-72.32194500000003,61.88388100000009],[-72.256958,61.87693800000011],[-72.23500100000001,61.8722150000001],[-72.20584099999996,61.86332700000014],[-72.20083599999992,61.860275],[-72.041382,61.72248800000011],[-72.01005600000002,61.67527000000001],[-72.03805499999999,61.62470999999999],[-72.08056599999998,61.60193600000002],[-72.087784,61.59887700000007],[-72.09583999999995,61.59609999999998],[-72.11389200000002,61.59554300000008],[-72.12388599999997,61.596382000000006],[-72.16000400000001,61.60527000000002],[-72.19415300000003,61.615829000000076],[-72.22749299999998,61.61998700000004],[-72.23666399999996,61.61943800000006],[-72.254456,61.61554699999999],[-72.271118,61.609161000000086],[-72.3033289999999,61.570831],[-72.30387899999994,61.568885999999964],[-72.3033289999999,61.56721500000009],[-72.083618,61.58249699999993],[-72.05722000000003,61.586655000000064],[-71.98028599999998,61.599998000000085],[-71.97833300000002,61.6013870000001],[-71.96777299999997,61.60943600000007],[-71.94082599999996,61.64833100000004],[-71.93666099999996,61.65554800000001],[-71.93360899999993,61.66360500000013],[-71.93306000000001,61.66860200000008],[-71.93388400000003,61.67416400000002],[-71.93666099999996,61.677773],[-71.94137599999999,61.681107],[-71.94688400000001,61.68838099999999],[-71.95038599999987,61.68871300000012],[-71.953888,61.69071600000012],[-71.95655799999992,61.69304700000009],[-71.95688599999988,61.69421399999999],[-71.95605499999994,61.69888300000014],[-71.95054600000003,61.7012180000001],[-71.94888300000002,61.70155],[-71.945221,61.701714000000095],[-71.928879,61.705826000000116],[-71.81945799999994,61.688599000000124],[-71.79527300000001,61.68221300000005],[-71.64472999999992,61.639435000000105],[-71.5750119999999,61.608604000000014],[-71.57167099999987,61.605552999999986],[-71.545547,61.5719380000001],[-71.54611199999994,61.5669400000001],[-71.5494379999999,61.558884000000035],[-71.56027199999994,61.55721299999993],[-71.62971499999998,61.54860700000006],[-71.63500999999997,61.54583000000014],[-71.652222,61.54305300000004],[-71.66305499999993,61.54193900000007],[-71.75111399999997,61.538048],[-71.789444,61.52193499999993],[-71.74638400000003,61.47137500000008],[-71.74694799999997,61.46582799999999],[-71.80277999999998,61.446938000000046],[-71.81750499999998,61.44276400000001],[-71.87554899999992,61.43610399999994],[-71.88555899999994,61.43276999999995],[-71.887787,61.43082400000009],[-71.88751199999996,61.42804699999999],[-71.87943999999999,61.422492999999974],[-71.87304699999993,61.41971600000011],[-71.85333300000002,61.41443600000002],[-71.70056199999999,61.405823000000055],[-71.68472299999996,61.40499099999994],[-71.67610199999996,61.37221500000004],[-71.67193599999996,61.33055100000013],[-71.59889199999998,61.254166000000055],[-71.53083799999996,61.21360800000002],[-71.38999899999999,61.1377720000001],[-71.29583699999989,61.14860500000009],[-71.28666699999991,61.14971900000006],[-71.27917500000001,61.1511000000001],[-71.174713,61.13999200000012],[-71.01139799999999,61.12165799999997],[-70.96694899999994,61.113883999999985],[-70.94583099999994,61.108887000000095],[-70.92832900000002,61.10249300000004],[-70.92193600000002,61.09693900000002],[-70.92138699999998,61.09137700000008],[-70.77333099999998,61.08166499999993],[-70.656387,61.05054500000006],[-70.55305499999997,61.02499400000005],[-70.53971899999999,61.05582400000009],[-70.535278,61.05943300000007],[-70.41999800000002,61.08526599999999],[-70.41361999999998,61.08665500000001],[-70.31555199999991,61.09499400000004],[-70.165009,61.088043000000084],[-70.14611799999989,61.08471700000007],[-70.14138799999995,61.08277099999998],[-70.10722399999992,61.06443800000011],[-70.08583099999998,60.954994],[-70.08805799999988,60.89777400000014],[-69.92749000000003,60.807770000000005],[-69.914444,60.80860100000001],[-69.90110799999997,60.81221000000005],[-69.88806199999993,60.81916000000007],[-69.85638399999999,60.83832600000011],[-69.85055499999999,60.84193400000004],[-69.84973100000002,60.84665699999999],[-69.85139500000002,60.849716],[-69.85888699999998,60.85193600000002],[-69.86944599999993,60.85082999999997],[-69.88362099999995,60.84526800000003],[-69.89472999999992,60.85555299999993],[-69.833328,60.88999200000001],[-69.82611099999997,60.893326],[-69.778885,60.91137700000013],[-69.75695799999994,60.918884000000105],[-69.75083899999993,60.919715999999994],[-69.741104,60.9180530000001],[-69.73805199999993,60.91554300000007],[-69.74333200000001,60.90693699999997],[-69.75140399999998,60.89887999999996],[-69.750565,60.894440000000145],[-69.74610899999999,60.88472000000007],[-69.74055499999997,60.88137799999993],[-69.71055599999994,60.87387800000005],[-69.68859900000001,60.871658000000025],[-69.67721599999999,60.871101000000124],[-69.658615,60.87693800000011],[-69.64999399999988,60.8836060000001],[-69.64584399999995,60.89305100000013],[-69.64388999999994,60.90332000000001],[-69.64916999999991,60.913879000000065],[-69.65556300000003,60.9222180000001],[-69.67166099999992,60.93443300000001],[-69.68083199999995,60.943047000000035],[-69.68859900000001,60.951660000000004],[-69.68943799999988,60.95610000000005],[-69.68971299999998,60.96166199999999],[-69.68055700000002,61.01415999999995],[-69.67944299999994,61.01944000000003],[-69.67666599999995,61.02555100000012],[-69.65666199999993,61.053604000000064],[-69.65388499999995,61.05693800000006],[-69.61305199999993,61.07916300000005],[-69.59999099999999,61.081940000000145],[-69.55416899999994,61.08055099999996],[-69.52860999999996,61.07638500000007],[-69.51972999999992,61.07332600000012],[-69.51445000000001,61.06944299999998],[-69.51139799999993,61.06610100000006],[-69.50834700000001,61.06082200000009],[-69.49276700000001,61.03193700000003],[-69.468887,60.99499500000002],[-69.46528599999994,60.990273000000116],[-69.45361300000002,60.974991000000045],[-69.36805700000002,60.903046000000074],[-69.368607,60.811104],[-69.37193300000001,60.80443600000001],[-69.38055400000002,60.79471600000011],[-69.38667299999997,60.79055000000005],[-69.40444899999994,60.783332999999914],[-69.42138699999992,60.77804600000002],[-69.43859899999995,60.77499400000005],[-69.49665799999997,60.76444200000009],[-69.53306599999996,60.757217000000026],[-69.59167500000001,60.73915899999997],[-69.61582900000002,60.730270000000075],[-69.708618,60.68693500000012],[-69.71610999999996,60.68277000000012],[-69.71055599999994,60.67527000000007],[-69.70500199999998,60.67193600000007],[-69.695831,60.663879000000065],[-69.656387,60.59554300000008],[-69.65417499999995,60.584991000000116],[-69.65417499999995,60.58138300000002],[-69.65695199999993,60.574715000000026],[-69.6875,60.551383999999985],[-69.69360399999994,60.54694400000011],[-69.70222499999988,60.54444099999995],[-69.74861099999998,60.53971900000005],[-69.79777499999994,60.53443900000002],[-69.8138889999999,60.530548000000124],[-69.82223499999998,60.52777100000003],[-69.82611099999997,60.52555100000001],[-69.82444800000002,60.522490999999945],[-69.78750600000001,60.480545000000006],[-69.78443900000002,60.47804300000007],[-69.77833599999997,60.47526600000003],[-69.76222200000001,60.47026800000003],[-69.74888599999997,60.4616620000001],[-69.72166400000003,60.368881000000044],[-69.72250400000001,60.36415899999997],[-69.72778299999999,60.35193600000008],[-69.74444599999998,60.34054600000002],[-69.75195300000001,60.33638000000013],[-69.75666799999993,60.331940000000145],[-69.764725,60.32360799999998],[-69.76695299999994,60.31832899999995],[-69.76806599999986,60.31221000000011],[-69.764725,60.307495000000074],[-69.758896,60.30471000000006],[-69.69638099999997,60.278877000000136],[-69.60638399999999,60.23276500000003],[-69.6052699999999,60.2227630000001],[-69.60583500000001,60.21859699999999],[-69.61000100000001,60.208327999999995],[-69.61416600000001,60.20249200000006],[-69.636978,60.179047000000025],[-69.60194399999995,60.18305200000009],[-69.59416199999998,60.18082400000014],[-69.593887,60.17582700000003],[-69.60360699999995,60.10305000000011],[-69.62471,60.06749700000012],[-69.63694800000002,60.065268999999944],[-69.70666499999999,60.05749500000013],[-69.83721899999995,60.019713999999965],[-69.89222699999993,59.99971800000003],[-70.21722399999993,60.00721699999997],[-70.2963939999999,60.01119600000004],[-70.33612099999993,60.0044400000001],[-70.48805199999987,59.99360700000011],[-70.50500499999993,59.99249300000014],[-70.53472899999997,59.99193600000007],[-70.55694599999993,59.99276700000007],[-70.57972699999993,59.99471299999993],[-70.59306299999997,59.99665800000014],[-70.77084400000001,60.02804600000013],[-70.94583099999994,60.06304899999998],[-70.900284,60.04027600000006],[-70.631104,59.98582499999998],[-70.61054999999993,59.98082000000011],[-70.58500700000002,59.97193100000004],[-70.56695599999995,59.968597000000045],[-70.50723299999999,59.96665999999999],[-70.47582999999997,59.96832300000011],[-70.33805799999999,59.97637900000001],[-70.23693800000001,59.986938000000066],[-70.22721899999993,59.98665599999998],[-70.218613,59.98416099999997],[-70.197495,59.974158999999986],[-70.16471899999999,59.962494000000106],[-70.112503,59.949715000000026],[-70.08612099999999,59.94638100000009],[-70.06138599999997,59.94499200000007],[-70.04998799999987,59.94526700000006],[-70.0308379999999,59.94804399999998],[-69.947769,59.95888500000012],[-69.758896,59.96776600000004],[-69.726944,59.96360800000008],[-69.71888699999994,59.95971700000001],[-69.60055499999987,59.833054000000004],[-69.60555999999991,59.77721400000013],[-69.61000100000001,59.72860000000014],[-69.54083300000002,59.671104000000014],[-69.60499599999997,59.588325999999995],[-69.61332699999997,59.588325999999995],[-69.62777699999998,59.58387800000003],[-69.65888999999999,59.572495],[-69.67944299999994,59.563605999999936],[-69.69804399999998,59.553047000000106],[-69.718613,59.537773000000016],[-69.72972099999993,59.52777100000003],[-69.74833699999994,59.50999500000006],[-69.75944500000003,59.49388099999999],[-69.76112399999994,59.484161000000086],[-69.75944500000003,59.48110200000008],[-69.756393,59.47860000000003],[-69.72833300000002,59.47971300000012],[-69.703888,59.481934000000024],[-69.69860799999992,59.48137700000012],[-69.697495,59.480545000000006],[-69.66944899999993,59.455551000000014],[-69.66583299999996,59.45165999999995],[-69.64944500000001,59.42887900000011],[-69.64527900000002,59.419159000000036],[-69.63166799999988,59.37776900000006],[-69.63137799999993,59.374992000000134],[-69.63999899999988,59.36110700000006],[-69.64639299999999,59.35888700000004],[-69.67777999999993,59.356941000000006],[-69.73666400000002,59.345267999999976],[-69.74415599999998,59.343323],[-69.75778200000002,59.330826],[-69.75834700000001,59.32027399999998],[-69.75111400000003,59.311104000000114],[-69.74694799999986,59.30777000000012],[-69.73860199999996,59.30526699999996],[-69.64500399999991,59.29833200000013],[-69.631104,59.29888199999999],[-69.62666300000001,59.29972100000009],[-69.61639399999996,59.30443600000012],[-69.55027799999999,59.32972000000012],[-69.445831,59.35443900000007],[-69.43582200000003,59.3555530000001],[-69.41250600000001,59.35499599999997],[-69.25944500000003,59.32666000000006],[-69.24972499999996,59.32360799999998],[-69.23832700000003,59.25972000000013],[-69.23500100000001,59.23943300000002],[-69.23472599999997,59.23387900000006],[-69.23805199999993,59.22943100000009],[-69.24444599999998,59.224433999999974],[-69.28582799999992,59.208327999999995],[-69.36639400000001,59.19082600000013],[-69.37388599999997,59.18943000000007],[-69.40499899999998,59.19026900000006],[-69.41915899999998,59.192490000000134],[-69.42027299999995,59.19609800000006],[-69.41749600000003,59.202217000000076],[-69.41444399999995,59.21249400000005],[-69.41665599999999,59.21971100000002],[-69.420837,59.22304500000001],[-69.42971799999992,59.22470900000002],[-69.439438,59.224433999999974],[-69.44860799999998,59.2227630000001],[-69.47027600000001,59.21388200000001],[-69.51222200000001,59.19276400000007],[-69.53056299999997,59.18221299999999],[-69.5375059999999,59.17249300000009],[-69.54028299999999,59.166382],[-69.54110700000001,59.16165900000004],[-69.53721599999994,59.12304700000004],[-69.53306599999996,59.110825000000034],[-69.52778599999999,59.10665899999998],[-69.52055399999989,59.10443900000013],[-69.51139799999993,59.103324999999984],[-69.50556899999992,59.10416399999997],[-69.49499499999996,59.109993000000145],[-69.48443600000002,59.121376],[-69.474716,59.12804399999993],[-69.46305799999999,59.12943300000012],[-69.45388799999995,59.128326000000015],[-69.38417099999998,59.11888099999993],[-69.36749299999991,59.11638600000009],[-69.35972599999997,59.11277000000007],[-69.34916699999991,59.10499600000003],[-69.34527600000001,59.09554300000002],[-69.34416199999998,59.09110300000003],[-69.35278299999999,59.08082600000006],[-69.43194599999998,59.025269000000094],[-69.46611000000001,59.044159000000036],[-69.49333199999995,59.037498000000085],[-69.47528099999994,58.97193100000004],[-69.45750399999991,58.915824999999984],[-69.45472699999999,58.90638000000007],[-69.45388799999995,58.89582800000011],[-69.45417799999996,58.89222000000001],[-69.45639,58.884163],[-69.46000699999996,58.878876000000105],[-69.5475009999999,58.808043999999995],[-69.55749500000002,58.80360399999995],[-69.58778399999994,58.79666099999997],[-69.61111499999998,58.792220999999984],[-69.656387,58.787773000000016],[-69.67083699999995,58.792220999999984],[-69.68083199999995,58.800269999999955],[-69.71194499999996,58.84887700000007],[-69.71472199999994,58.85833000000008],[-69.71610999999996,58.86471599999999],[-69.702789,58.876381000000094],[-69.67222600000002,58.89138000000014],[-69.66861,58.89943700000009],[-69.66833499999996,58.90277100000009],[-69.66833499999996,58.92582700000014],[-69.67166099999992,58.930550000000096],[-69.70944199999997,58.972762999999986],[-69.84834299999994,59.04721799999999],[-69.86527999999993,59.05277300000006],[-69.86915599999992,59.05304699999999],[-69.872772,59.05082700000003],[-69.87388599999997,59.041107000000125],[-69.87416099999996,59.03416399999992],[-69.87388599999997,59.02915999999999],[-69.86555499999997,58.977768000000026],[-69.83277900000002,58.95166000000006],[-69.81582600000002,58.82388300000008],[-69.97277799999989,58.80860100000007],[-70.15361000000001,58.777488999999946],[-70.15888999999999,58.76110799999998],[-70.04972800000002,58.743607],[-69.974716,58.75555400000013],[-69.931107,58.733047000000056],[-69.91055299999994,58.68804200000011],[-69.864441,58.61749300000014],[-69.86166399999996,58.61499800000013],[-69.81889299999995,58.588599999999985],[-69.81304899999992,58.58915700000006],[-69.79943799999995,58.59887700000013],[-69.79333500000001,58.603882],[-69.72444199999995,58.66888399999999],[-69.625,58.7438810000001],[-69.608047,58.754714999999976],[-69.58168,58.765831000000105],[-69.57084700000001,58.769440000000145],[-69.54472399999997,58.77332300000006],[-69.50750700000003,58.77471200000008],[-69.49888599999986,58.77860299999992],[-69.44554099999988,58.80832700000013],[-69.41888399999988,58.825553999999954],[-69.41166699999997,58.830276000000026],[-69.41027799999995,58.83998900000006],[-69.40583800000002,58.85027300000013],[-69.39472999999992,58.856659000000036],[-69.38194299999992,58.86138199999999],[-69.34889199999998,58.87165800000008],[-69.27917500000001,58.888046000000145],[-69.15388499999995,58.89999399999999],[-69.12998999999996,58.901657000000114],[-69.098343,58.8991620000001],[-69.03167699999989,58.893326],[-68.99221799999998,58.883880999999974],[-68.84167500000001,58.891106000000036],[-68.756958,58.91249099999999],[-68.65638699999994,58.90026900000004],[-68.63751200000002,58.89666],[-68.60166899999996,58.88582600000012],[-68.39639299999999,58.81610100000012],[-68.39068600000002,58.81170700000001],[-68.36054999999993,58.781936999999914],[-68.35583500000001,58.774437000000034],[-68.35777299999995,58.76471700000013],[-68.360275,58.75943799999999],[-68.36639399999996,58.68749200000008],[-68.34584000000001,58.626937999999996],[-68.323059,58.58526599999999],[-68.2908329999999,58.54110700000001],[-68.21665999999993,58.490829000000076],[-68.20973200000003,58.46249400000005],[-68.20472699999999,58.45332300000007],[-68.20306399999998,58.44165800000002],[-68.20417800000001,58.43693500000006],[-68.22694399999995,58.37638099999998],[-68.24472000000003,58.33776899999998],[-68.25666799999999,58.32360799999998],[-68.28582799999992,58.294998000000135],[-68.28999299999992,58.28916200000009],[-68.30915799999991,58.25332600000007],[-68.32250999999997,58.22693600000008],[-68.34584000000001,58.16999100000004],[-68.34805299999994,58.159714000000065],[-68.34777799999995,58.15387700000008],[-68.34416199999998,58.14166300000005],[-68.341385,58.133331000000055],[-68.34416199999998,58.12748700000009],[-68.35055499999993,58.12193300000007],[-68.46665999999999,58.04554699999994],[-68.47721899999993,58.03999299999998],[-68.50361599999991,58.03138000000001],[-68.52860999999996,58.029434000000094],[-68.72988900000001,57.99971800000003],[-68.87416100000002,57.969154],[-69.12721299999998,57.89943699999992],[-69.13500999999991,57.89694200000008],[-69.18138099999999,57.878044000000045],[-69.20249899999999,57.86859900000013],[-69.22138999999993,57.85888699999998],[-69.26251199999996,57.83360300000004],[-69.35777300000001,57.77416200000005],[-69.36904899999996,57.76525100000009],[-69.36389200000002,57.765830999999935],[-69.33972199999994,57.77332300000006],[-69.30499299999997,57.78665900000004],[-69.29834,57.78943600000014],[-69.21028099999995,57.8294370000001],[-69.19082599999996,57.84054600000002],[-69.172775,57.851661999999976],[-69.1119379999999,57.88582599999995],[-68.96528599999988,57.933876],[-68.90417500000001,57.94971500000008],[-68.69572399999998,57.9877130000001],[-68.67889400000001,57.9897160000001],[-68.66738899999996,57.99038300000001],[-68.63472000000002,57.988879999999995],[-68.62239099999988,57.98937999999998],[-68.54527299999995,58.000549000000035],[-68.49583399999995,58.013329],[-68.41694599999994,58.034439000000134],[-68.40417500000001,58.03971900000005],[-68.31361400000003,58.103049999999996],[-68.30888399999998,58.10804700000011],[-68.30499299999991,58.11388400000004],[-68.30249000000003,58.119155999999975],[-68.29998799999993,58.12748700000009],[-68.30027799999988,58.13249200000013],[-68.30471799999998,58.14638499999995],[-68.30555700000002,58.14999399999999],[-68.30722000000003,58.16443600000014],[-68.306107,58.181107],[-68.30526700000001,58.18610400000006],[-68.30110200000001,58.19804399999998],[-68.29527300000001,58.209991000000116],[-68.28416400000003,58.21998600000006],[-68.23083500000001,58.26888300000013],[-68.18582200000003,58.36054999999999],[-68.16833500000001,58.414711000000125],[-68.16665599999999,58.424438000000066],[-68.166946,58.435822000000144],[-68.16999800000002,58.446655000000135],[-68.172775,58.454994],[-68.17805499999997,58.46971100000013],[-68.17832900000002,58.48027000000002],[-68.17138699999992,58.48999000000009],[-68.13917500000002,58.521103000000096],[-68.13500999999985,58.52416200000005],[-68.01306199999999,58.57360799999992],[-68.00334199999998,58.576385000000016],[-67.98332199999999,58.57305100000002],[-67.96916199999998,58.565826000000015],[-67.95916699999998,58.55804400000005],[-67.896118,58.50054899999998],[-67.89389,58.49665800000008],[-67.89222699999999,58.49137900000011],[-67.891953,58.483604000000014],[-67.89500399999991,58.47693600000002],[-67.90110800000002,58.46720900000008],[-67.908051,58.45804600000008],[-67.914444,58.45332300000007],[-67.91944899999993,58.445540999999935],[-67.920837,58.43943000000007],[-67.92416399999996,58.41276600000009],[-67.92332499999992,58.40304600000002],[-67.90833999999995,58.360825000000034],[-67.906113,58.356941000000006],[-67.90361000000001,58.35360700000001],[-67.89334099999996,58.34665699999999],[-67.86805699999996,58.33221400000008],[-67.86416600000001,58.32888000000008],[-67.85749800000002,58.32027399999998],[-67.89450099999993,58.28716300000008],[-67.89665999999988,58.28115800000006],[-67.90449499999994,58.26766200000003],[-67.91332999999992,58.25616100000002],[-67.91934199999997,58.250159999999994],[-67.92633099999995,58.245491000000015],[-67.93482999999998,58.241161000000034],[-67.946999,58.235992000000124],[-67.97499099999999,58.22099300000002],[-68.04750100000001,58.170547000000056],[-68.06582600000002,58.1594310000001],[-68.09583999999995,58.13860299999999],[-68.10110500000002,58.13304900000003],[-68.12748699999992,58.084717000000126],[-68.12998999999996,58.07888000000014],[-68.12832599999996,58.073608000000036],[-68.12554899999998,58.071105999999986],[-68.11582899999996,58.071938000000046],[-68.10110500000002,58.07777399999998],[-68.00666799999993,58.131935000000055],[-67.99166899999994,58.146103000000096],[-67.97833300000002,58.16360500000013],[-67.87694499999998,58.24305000000004],[-67.80139200000002,58.296661000000086],[-67.81555199999997,58.30888399999998],[-67.82389799999987,58.31721500000003],[-67.82917800000001,58.32638500000007],[-67.83056599999992,58.33138300000007],[-67.828888,58.349716000000114],[-67.81973299999987,58.39360800000003],[-67.81723,58.40526600000004],[-67.81332399999991,58.416100000000085],[-67.78750599999995,58.46443900000003],[-67.78306600000002,58.46804800000007],[-67.7750089999999,58.47109999999998],[-67.76445000000001,58.47054300000008],[-67.72389199999998,58.458885000000066],[-67.66944899999999,58.431938000000116],[-67.66749600000003,58.42748999999998],[-67.66999800000002,58.42193599999996],[-67.67999299999997,58.41276600000009],[-67.69193999999999,58.404433999999924],[-67.69694500000003,58.399437000000034],[-67.70472699999999,58.38916000000006],[-67.737213,58.326942000000145],[-67.73889200000002,58.32083100000011],[-67.737213,58.31554399999999],[-67.73249799999996,58.311661000000015],[-67.69804399999992,58.28499599999998],[-67.66082799999998,58.26444200000003],[-67.64611799999994,58.25332600000007],[-67.64277599999991,58.248604],[-67.65249599999999,58.21471400000013],[-67.65417500000001,58.21054800000002],[-67.72860700000001,57.97665400000005],[-67.71389799999986,57.923050000000046],[-67.71028100000001,57.97554800000006],[-67.70834399999995,57.98249100000004],[-67.65943899999996,58.11027500000006],[-67.65360999999996,58.122765000000015],[-67.64527899999996,58.13443799999999],[-67.591949,58.200829],[-67.57833900000003,58.21527100000003],[-67.56610099999995,58.223602000000085],[-67.48138399999993,58.27388000000008],[-67.46665999999999,58.27971600000012],[-67.33277900000002,58.31610100000006],[-67.17222599999991,58.37638099999998],[-67.16860999999994,58.3780440000001],[-67.15194699999995,58.376656000000025],[-67.13751200000002,58.373046999999985],[-67.11665299999999,58.36332700000008],[-67.10694899999999,58.3555530000001],[-67.09555099999994,58.348877000000016],[-67.09056099999998,58.35054800000006],[-66.995834,58.43943000000007],[-66.991669,58.445267],[-66.98998999999998,58.45138500000013],[-66.98666400000002,58.45804600000008],[-66.978882,58.468323000000055],[-66.95140100000003,58.49860399999994],[-66.94415300000003,58.50193799999994],[-66.92805499999997,58.50166300000012],[-66.88722199999995,58.4855500000001],[-66.87693799999994,58.479156000000046],[-66.87554899999986,58.47387700000007],[-66.87805200000003,58.46859699999999],[-66.80110199999996,58.47360200000003],[-66.62971499999998,58.50360900000004],[-66.65167199999996,58.54277000000013],[-66.551941,58.71138000000002],[-66.46972700000003,58.81638300000003],[-66.465012,58.81999200000001],[-66.38861099999997,58.85054800000012],[-66.36665299999993,58.848044999999956],[-66.35777300000001,58.84609999999998],[-66.34999099999993,58.84304800000007],[-66.35028099999994,58.83721200000002],[-66.34889199999998,58.83194000000009],[-66.34416199999993,58.82777399999998],[-66.11471599999993,58.69971499999997],[-66.10611,58.68498999999997],[-66.077225,58.654434000000094],[-66.07223499999992,58.650825999999995],[-66.06777999999991,58.64888000000008],[-66.05416899999994,58.64610299999998],[-65.94554099999993,58.61693600000007],[-65.93888899999996,58.61388399999993],[-65.93582200000003,58.60971800000004],[-65.93582200000003,58.604713000000004],[-65.93859899999995,58.594437000000084],[-65.94193999999999,58.58277099999992],[-66.02194199999997,58.48693800000001],[-66.08944699999995,58.365273],[-66.091385,58.358887000000095],[-66.091385,58.35416400000008],[-66.073059,58.32721700000002],[-66.06555200000003,58.32027399999998],[-66.05888399999998,58.32027399999998],[-66.05277999999993,58.34693900000002],[-66.05139200000002,58.35249300000004],[-66.04554699999994,58.363052000000096],[-66.04167199999995,58.368050000000096],[-66.03056299999997,58.37638099999998],[-66.02305599999994,58.379714999999976],[-66.01501499999995,58.381935],[-65.98805199999998,58.38443799999999],[-65.979172,58.38610799999992],[-65.97277799999995,58.38804600000009],[-65.965012,58.39193699999993],[-65.9602809999999,58.39610300000004],[-65.92027299999995,58.44582400000013],[-65.920837,58.449432],[-65.92666600000001,58.45609999999999],[-65.93221999999997,58.458885000000066],[-65.94027699999998,58.46166199999993],[-65.96166999999997,58.46471400000007],[-65.98055999999991,58.47026800000003],[-65.98249799999996,58.4741590000001],[-65.98194899999993,58.480545000000006],[-65.98055999999991,58.48304700000011],[-65.88751200000002,58.57777400000003],[-65.88417099999998,58.580826000000116],[-65.87693799999988,58.58194000000009],[-65.87998999999996,58.62721300000004],[-65.94554099999993,58.66526799999997],[-66.03222699999998,58.710548000000074],[-66.10139499999997,58.77110300000004],[-66.103882,58.77360499999992],[-66.081955,58.80971500000004],[-66.03721599999994,58.85166200000009],[-65.99011199999995,58.85266100000001],[-65.98495499999996,58.85149400000006],[-65.95227799999986,58.83682299999998],[-65.84583999999995,58.826660000000004],[-65.839722,58.827217000000076],[-65.79750100000001,58.847488000000055],[-65.79277000000002,58.85332500000004],[-65.79028299999999,58.85777300000001],[-65.78944399999995,58.86193800000001],[-65.791382,58.865829000000076],[-65.79499800000002,58.86693600000001],[-65.80610699999994,58.866660999999965],[-65.833328,58.86471599999999],[-65.86193800000001,58.86332700000003],[-65.88027999999991,58.864441],[-65.94044500000001,58.87910500000004],[-65.952606,58.88126799999992],[-65.95811500000002,58.88293500000003],[-65.96477500000003,58.88744000000008],[-65.96827699999989,58.893440000000055],[-65.98860200000001,58.90360300000003],[-65.885559,59.00193800000005],[-65.77749599999999,59.029990999999995],[-65.69526699999989,59.04361000000006],[-65.67304999999999,59.046104000000014],[-65.660278,59.044159000000036],[-65.65417499999995,59.042496000000085],[-65.6346739999999,59.03321799999998],[-65.63249200000001,59.031216000000086],[-65.61416600000001,59.01944000000009],[-65.56500199999994,58.99360700000011],[-65.51445000000001,58.98471800000004],[-65.5,58.98333000000014],[-65.49499499999996,58.98471800000004],[-65.49333200000001,58.98749500000014],[-65.49499499999996,58.99193600000007],[-65.50944499999997,59.008331],[-65.51640299999997,59.01082600000001],[-65.533615,59.014717000000076],[-65.54305999999997,59.01554900000002],[-65.55305499999997,59.017494],[-65.56082200000003,59.020827999999995],[-65.57138800000001,59.03910800000011],[-65.57289100000003,59.04410600000011],[-65.570221,59.045773],[-65.56805400000002,59.04677600000002],[-65.53277600000001,59.063881000000094],[-65.51861600000001,59.06666600000011],[-65.51028400000001,59.066940000000045],[-65.50639299999995,59.06638299999997],[-65.49249299999997,59.061378000000104],[-65.45472699999999,59.0422210000001],[-65.34028599999999,59.03833000000003],[-65.33056599999998,59.03804800000012],[-65.32472199999995,59.0388870000001],[-65.31750499999998,59.04138200000011],[-65.31973299999999,59.04721799999999],[-65.333618,59.05999000000003],[-65.34472699999998,59.06471299999998],[-65.35417199999995,59.06749700000012],[-65.53355399999992,59.07766300000014],[-65.53687999999994,59.074665000000095],[-65.54672199999999,59.07183100000009],[-65.56438399999996,59.07016399999998],[-65.57705699999997,59.06999600000012],[-65.58406100000002,59.07099900000014],[-65.58656300000001,59.072159000000056],[-65.651947,59.07916300000011],[-65.71501199999994,59.14833100000004],[-65.71806299999997,59.153046000000074],[-65.74082900000002,59.21471400000007],[-65.74249299999991,59.219437000000084],[-65.74305699999996,59.228043000000014],[-65.74499500000002,59.25972000000013],[-65.74471999999997,59.263054000000125],[-65.74305699999996,59.26583099999999],[-65.73194899999999,59.26906600000001],[-65.70666499999999,59.26832600000006],[-65.68527199999988,59.26444200000003],[-65.67610200000001,59.261108000000036],[-65.646118,59.244713000000104],[-65.58750900000001,59.20249200000012],[-65.612503,59.23749500000008],[-65.61471599999987,59.243607000000054],[-65.61416600000001,59.24694100000005],[-65.58168,59.37721300000004],[-65.57250999999997,59.378601],[-65.57000699999998,59.37832600000013],[-65.551941,59.37276500000007],[-65.49916099999996,59.352219000000105],[-65.48332199999993,59.345542999999964],[-65.47610500000002,59.33888200000007],[-65.47111499999994,59.32749200000001],[-65.45333899999997,59.31693999999999],[-65.383896,59.28166199999998],[-65.372772,59.276657000000114],[-65.36665299999987,59.27499399999999],[-65.36111499999987,59.274712000000136],[-65.35722399999997,59.277214000000015],[-65.35665899999992,59.28276800000003],[-65.43777499999999,59.39388300000002],[-65.49526999999989,59.433876000000055],[-65.55943300000001,59.48165899999998],[-65.56138599999997,59.48610700000012],[-65.55749500000002,59.48777000000007],[-65.54943800000001,59.48943300000002],[-65.54222099999998,59.48999000000009],[-65.36000099999995,59.48165899999998],[-65.347778,59.48082000000005],[-65.260559,59.466385000000116],[-65.19766199999998,59.45049300000005],[-65.195831,59.447659000000044],[-65.176941,59.440269],[-65.17027300000001,59.434433000000126],[-65.141953,59.41582500000004],[-65.12666300000001,59.40776800000009],[-65.11999500000002,59.40526600000004],[-65.060272,59.3844380000001],[-65.04138199999994,59.378601],[-65.01777599999997,59.373046999999985],[-65.00584400000002,59.37193300000001],[-64.995544,59.372490000000084],[-64.98332199999993,59.37638099999998],[-65.03138699999994,59.392769000000044],[-65.07583599999998,59.40804300000008],[-65.11111499999998,59.42054699999994],[-65.11888099999999,59.42388200000005],[-65.14111300000002,59.434433000000126],[-65.14723199999997,59.43804200000011],[-65.15139799999997,59.44304699999998],[-65.15638699999994,59.45165999999995],[-65.15899699999989,59.46082700000011],[-65.16194200000001,59.466660000000104],[-65.16805999999997,59.47054300000002],[-65.22084000000001,59.48832700000014],[-65.29083299999996,59.50666000000001],[-65.30860899999993,59.50999500000006],[-65.33000199999987,59.50943799999999],[-65.38890100000003,59.50750000000005],[-65.41166699999997,59.50943799999999],[-65.41999800000002,59.516936999999984],[-65.46278399999989,59.57804900000002],[-65.49415599999998,59.626937999999996],[-65.50167799999991,59.63888500000013],[-65.52778599999999,59.71693399999998],[-65.50195299999996,59.7472150000001],[-65.43331899999998,59.79804999999993],[-65.37499999999994,59.828049000000135],[-65.33555599999994,59.84665700000005],[-65.33389299999993,59.84721400000012],[-65.323624,59.84554300000008],[-65.23611499999998,59.81938199999996],[-65.21945199999999,59.81437700000009],[-65.20594799999998,59.80854800000009],[-65.20344499999993,59.80688100000003],[-65.19877599999995,59.80287900000002],[-65.19528199999996,59.79721800000004],[-65.158615,59.78221100000002],[-65.15278599999999,59.779990999999995],[-65.136124,59.776657],[-65.05305499999997,59.76361100000008],[-65.03306599999996,59.76138300000014],[-65.00666799999999,59.76027700000009],[-64.98860200000001,59.76194000000004],[-64.98388699999998,59.76277199999993],[-64.98306300000002,59.76416000000006],[-64.98916599999995,59.765831000000105],[-65.05555699999996,59.7783280000001],[-65.13276699999994,59.79694400000011],[-65.16139199999998,59.817490000000134],[-65.19939399999993,59.83565900000008],[-65.20271300000002,59.83732600000002],[-65.20605499999999,59.8404920000001],[-65.23083500000001,59.88054699999998],[-65.23194899999999,59.88582600000012],[-65.22610499999996,59.888603000000046],[-65.20639,59.888603000000046],[-65.14334099999991,59.94999700000011],[-65.12609899999995,60.011108000000036],[-65.11000100000001,60.043052999999986],[-65.02972399999993,60.07721700000002],[-64.92111199999994,60.19499200000001],[-64.83416699999998,60.32305100000008],[-64.83222999999992,60.32860599999998],[-64.83444199999997,60.334434999999985],[-64.84638999999993,60.345543000000134],[-64.85833699999995,60.35249299999998],[-64.85722399999997,60.35943600000002],[-64.854446,60.36110700000006],[-64.846115,60.362769999999955],[-64.83555599999994,60.36332700000008],[-64.65306099999998,60.34693900000002],[-64.6416779999999,60.34471100000002],[-64.61027499999994,60.33638000000013],[-64.57667499999997,60.322768999999994],[-64.53324900000001,60.302498000000014],[-64.47560099999998,60.281609],[-64.46691900000002,60.278602999999976],[-64.43109099999998,60.25810599999994],[-64.432594,60.25560800000005],[-64.43460099999993,60.255108000000064],[-64.44609100000002,60.254771999999946],[-64.45309399999991,60.25627100000003],[-64.46242499999994,60.25927399999995],[-64.47759199999996,60.26560999999998],[-64.47721899999999,60.260551000000135],[-64.55749500000002,60.28110500000008],[-64.58029199999993,60.28611000000012],[-64.61305199999998,60.28943600000014],[-64.64306599999998,60.28749800000003],[-64.72111499999994,60.261108000000036],[-64.72582999999997,60.25833100000011],[-64.75805699999995,60.23582500000009],[-64.75944500000003,60.231102000000135],[-64.75250199999988,60.22860000000003],[-64.74526999999995,60.22832500000004],[-64.73693799999995,60.23054500000006],[-64.68554699999999,60.250832000000116],[-64.646118,60.26583099999999],[-64.63417099999998,60.26888300000007],[-64.59638999999999,60.26693700000004],[-64.57444800000002,60.2649990000001],[-64.554169,60.26277200000004],[-64.53639199999992,60.2586060000001],[-64.42167699999999,60.215656000000024],[-64.41950199999997,60.213661],[-64.376938,60.16054500000001],[-64.46501199999994,60.084991],[-64.46916199999987,60.08277099999998],[-64.476944,60.07972000000001],[-64.49137899999994,60.07471499999991],[-64.50445599999995,60.07249500000012],[-64.515015,60.071938000000046],[-64.65499899999992,60.053604000000064],[-64.80471799999998,60.00721699999997],[-64.8125,60.004166],[-64.82333399999999,59.99777200000011],[-64.82667500000002,59.99471299999993],[-64.82749899999999,59.98638200000005],[-64.82000700000003,59.97943100000009],[-64.811935,59.9783250000001],[-64.79666099999997,59.980270000000075],[-64.73527499999994,60.00110600000011],[-64.4908289999999,60.05943300000007],[-64.41027799999995,60.11110700000012],[-64.39639299999999,60.12193300000001],[-64.39222699999999,60.124161000000015],[-64.38583399999993,60.12526700000001],[-64.37999000000002,60.12526700000001],[-64.37388599999997,60.123604000000114],[-64.36776699999996,60.11971300000005],[-64.366104,60.117493000000024],[-64.36500499999994,60.109993000000145],[-64.37461100000002,60.03382900000008],[-64.37528199999986,60.028324000000055],[-64.39472999999998,59.941658000000075],[-64.39695699999993,59.93776700000001],[-64.40888999999999,59.932495000000074],[-64.45056199999993,59.92527000000001],[-64.46221899999995,59.92249300000009],[-64.49194299999999,59.91360500000013],[-64.506958,59.907211000000075],[-64.514725,59.9019320000001],[-64.51390100000003,59.896103000000096],[-64.506393,59.891936999999984],[-64.499435,59.89166300000005],[-64.48194899999987,59.89471400000008],[-64.37609899999995,59.9180530000001],[-64.36776699999996,59.92027300000012],[-64.36332700000003,59.92249300000009],[-64.36054999999993,59.924995000000024],[-64.32028199999996,60.004107999999974],[-64.32211299999994,60.006439000000114],[-64.32412,60.01160400000009],[-64.32428699999997,60.014107000000024],[-64.32211299999994,60.02460500000001],[-64.32044999999994,60.027270999999985],[-64.31744399999991,60.028103000000044],[-64.26501499999995,60.0480500000001],[-64.21665999999993,60.039993000000095],[-64.17361499999998,60.028328000000045],[-64.166946,60.02499400000005],[-64.16082799999998,60.01638800000012],[-64.150284,59.985268000000076],[-64.150284,59.982208000000014],[-64.16583300000002,59.85054800000012],[-64.17721599999993,59.785552999999936],[-64.1808319999999,59.7816620000001],[-64.19305399999996,59.775825999999995],[-64.20249899999993,59.77416199999999],[-64.22000099999997,59.77416199999999],[-64.23666400000002,59.77971600000001],[-64.24472000000003,59.784996000000035],[-64.25140399999998,59.78749800000014],[-64.25750700000003,59.78943600000008],[-64.26194800000002,59.789161999999976],[-64.26445000000001,59.78749800000014],[-64.266663,59.77915999999999],[-64.261124,59.76471700000013],[-64.25500499999993,59.756660000000124],[-64.21305799999999,59.7177660000001],[-64.197769,59.7052690000001],[-64.17388899999997,59.688598999999954],[-64.16389499999997,59.68415800000008],[-64.15167200000002,59.68082400000009],[-64.12998999999996,59.676659000000086],[-64.05776999999995,59.62526700000012],[-64.11694299999994,59.517494000000056],[-64.04750100000001,59.549721000000034],[-64.04083300000002,59.55360400000001],[-64.03332499999999,59.56388099999998],[-64.0344389999999,59.57360800000009],[-64.0344389999999,59.58277100000009],[-64.02972399999987,59.599433999999974],[-64.024719,59.60999300000003],[-64.01945499999994,59.61859900000013],[-64.01112399999994,59.62499200000008],[-64.00473,59.626381000000094],[-63.99722300000002,59.62665600000014],[-63.90055099999995,59.61998700000004],[-63.885559,59.618881000000044],[-63.87610599999999,59.615829000000076],[-63.865554999999915,59.60999300000003],[-63.73166699999996,59.526099999999985],[-63.724166999999966,59.5177690000001],[-63.72249599999998,59.51388500000007],[-63.723884999999996,59.50666000000001],[-63.785278000000005,59.426102000000014],[-63.80783799999995,59.420437000000106],[-63.81017299999996,59.41944100000012],[-63.814502999999945,59.418101999999976],[-63.86639399999996,59.421104000000014],[-63.90694400000001,59.421660999999915],[-63.947776999999974,59.41971600000011],[-64.000565,59.41443600000008],[-64.01834100000002,59.41054500000001],[-64.03332499999999,59.40665400000012],[-64.05027799999999,59.399994000000106],[-64.06111099999998,59.39388300000002],[-64.06582600000002,59.38804600000003],[-64.06221,59.38249200000007],[-64.05277999999998,59.37943300000006],[-63.805167999999924,59.36816400000009],[-63.79014599999999,59.370293000000004],[-63.786652000000004,59.371792000000084],[-63.78264999999999,59.3741260000001],[-63.75139599999994,59.37582400000008],[-63.748111999999935,59.333878000000084],[-63.75644699999998,59.30838],[-63.768280000000004,59.28788000000003],[-63.77044699999999,59.284381999999994],[-63.77344499999998,59.28221500000012],[-63.780944999999974,59.27821399999999],[-63.81416299999995,59.249435000000005],[-63.82472200000001,59.24610100000001],[-63.82549999999998,59.24437700000004],[-63.82527899999991,59.24332400000009],[-63.81388900000002,59.240829000000076],[-63.77794299999999,59.26393899999999],[-63.76677699999999,59.264275000000055],[-63.760940999999946,59.26543400000003],[-63.755942999999945,59.266773],[-63.739112999999975,59.27360500000003],[-63.730441999999925,59.28076900000002],[-63.723777999999925,59.287436999999954],[-63.71877699999993,59.293941000000075],[-63.71611399999989,59.3009340000001],[-63.71527900000001,59.303768000000105],[-63.71527900000001,59.30643800000007],[-63.71594199999987,59.30943700000006],[-63.713775999999996,59.315605000000005],[-63.71060899999986,59.318107999999995],[-63.65833299999997,59.358047],[-63.64999399999999,59.36249499999997],[-63.54305999999991,59.34804500000007],[-63.53527799999995,59.34443699999997],[-63.39333299999993,59.2649990000001],[-63.357506,59.20804600000008],[-63.35639200000003,59.204994],[-63.35805499999992,59.19804399999998],[-63.36666100000002,59.18637799999999],[-63.412773000000016,59.135826000000066],[-63.42556000000002,59.12638100000004],[-63.441108999999926,59.119438],[-63.476944,59.10443900000013],[-63.56361399999997,59.07332600000012],[-63.58000199999992,59.06749700000012],[-63.58972199999994,59.06554399999999],[-63.73139200000003,59.05627099999998],[-63.74105500000002,59.05577099999999],[-63.74872199999993,59.056934000000126],[-63.753890999999896,59.058266],[-63.76022299999994,59.06276700000012],[-63.81221799999997,59.06582600000007],[-63.934440999999936,59.081108000000086],[-63.94833399999999,59.07888000000014],[-63.966110000000015,59.07471499999997],[-63.98833499999995,59.06832900000006],[-64.045547,59.02416199999999],[-64.04722599999991,59.01944000000009],[-64.04388399999999,59.01527399999998],[-64.03944399999995,59.013885000000016],[-63.912216,59.000549000000035],[-63.80171999999999,59.013992000000144],[-63.798388999999986,59.01132999999999],[-63.766395999999986,59.0127720000001],[-63.75944499999997,59.01249700000005],[-63.73444399999994,59.01499899999999],[-63.50805700000001,59.05277300000006],[-63.38166799999988,59.09804500000013],[-63.37277199999994,59.10110499999996],[-63.365554999999915,59.10110499999996],[-63.30944099999999,59.09415400000006],[-63.29333500000001,59.091377000000136],[-63.13417099999998,59.05832700000008],[-63.12499999999994,59.055267000000015],[-63.12194099999999,59.0513840000001],[-63.122772,59.04554700000011],[-63.12694499999992,59.04138200000011],[-63.13333099999994,59.03804800000012],[-63.15943899999991,59.029990999999995],[-63.17527799999999,59.026939000000084],[-63.185272,59.026381999999955],[-63.21694200000002,59.02748900000012],[-63.23889200000002,59.03054800000007],[-63.32333399999993,59.02777100000014],[-63.336112999999955,59.02499400000005],[-63.335556,59.0219350000001],[-63.26445000000001,58.98554999999999],[-63.21388999999999,58.977211000000125],[-63.19527399999998,58.979713000000004],[-63.185272,58.980270000000075],[-63.17305799999991,58.979713000000004],[-63.16750300000001,58.97082500000005],[-63.16055299999999,58.92638400000004],[-63.16305499999993,58.92027300000012],[-63.23638900000003,58.876937999999996],[-63.313331999999946,58.861107000000004],[-63.325004999999976,58.85582700000009],[-63.31277499999999,58.853049999999996],[-63.294723999999974,58.85083000000003],[-63.19027699999998,58.854996000000085],[-63.11277799999999,58.87804399999999],[-63.03333299999997,58.873878000000104],[-62.924170999999944,58.82138100000003],[-62.918334999999956,58.817497],[-62.90694400000001,58.80471],[-62.90416700000003,58.79999500000014],[-62.84749599999998,58.69054399999999],[-62.84527600000001,58.68498999999997],[-62.84222399999999,58.669991000000095],[-62.84361299999995,58.659430999999984],[-62.84777799999995,58.65304599999996],[-62.91583299999991,58.60027299999996],[-62.97499800000003,58.57666000000006],[-63.169167000000016,58.50305200000014],[-63.334109999999896,58.455768999999975],[-63.33460999999994,58.45227100000011],[-63.33710899999994,58.448437000000126],[-63.373444000000006,58.41743500000007],[-63.38528100000002,58.41027100000008],[-63.39910900000001,58.40527300000008],[-63.486388999999974,58.37082700000002],[-63.52249899999998,58.36110700000012],[-63.53750600000001,58.35416400000008],[-63.58306099999999,58.31137800000005],[-63.58777600000002,58.30554999999998],[-63.58943899999997,58.30082700000014],[-63.584998999999925,58.29888199999999],[-63.57972699999999,58.29860699999995],[-63.571670999999924,58.29999500000008],[-63.55527499999994,58.305267000000015],[-63.53305799999998,58.31443800000011],[-63.428223,58.36904900000013],[-63.39238699999993,58.38838199999998],[-63.37855899999994,58.399044],[-63.36421999999993,58.410049000000015],[-63.35155500000002,58.41871600000002],[-63.28639199999998,58.456657000000064],[-63.28082999999998,58.459160000000054],[-63.26472499999994,58.46305100000012],[-63.241669,58.466385000000116],[-63.213615000000004,58.46943700000003],[-63.148612999999955,58.47637900000012],[-63.13277399999987,58.47721100000007],[-63.12444299999987,58.47526600000003],[-63.096947,58.46193699999998],[-63.08972199999994,58.45832799999994],[-63.08611300000001,58.454994],[-63.03750600000001,58.453048999999965],[-62.76333599999998,58.48082000000005],[-62.63666499999994,58.50138900000002],[-62.620551999999975,58.50499700000012],[-62.61000100000001,58.50388299999997],[-62.58943899999997,58.49971800000014],[-62.57361599999996,58.49388099999999],[-62.566108999999926,58.49054699999999],[-62.56138599999997,58.48749500000008],[-62.557503,58.482491000000095],[-62.556389000000024,58.47804300000013],[-62.61971999999997,58.37693800000005],[-62.61944599999998,58.310272000000055],[-62.623054999999965,58.30443600000001],[-62.63417099999998,58.29777500000006],[-62.70861100000002,58.27610000000004],[-62.77666499999998,58.26859999999999],[-62.828056000000004,58.25222000000008],[-62.661666999999966,58.26998900000001],[-62.65860700000002,58.27027100000004],[-62.65444200000002,58.27027100000004],[-62.60972599999997,58.25666000000007],[-62.597778000000005,58.25166300000001],[-62.592772999999966,58.248604],[-62.58250399999986,58.23443600000013],[-62.58111600000001,58.22193100000004],[-62.58277899999996,58.216934000000094],[-62.58444199999997,58.214439000000084],[-62.631942999999865,58.18526500000013],[-62.63805400000001,58.181938],[-62.653053,58.17527000000001],[-62.661384999999996,58.17304999999999],[-62.68916300000001,58.16999100000004],[-62.71971899999994,58.169715999999994],[-62.74027999999993,58.17193600000002],[-62.773887999999886,58.176941000000056],[-62.78388999999993,58.17665900000003],[-62.822227,58.17471300000011],[-62.84166699999997,58.1722180000001],[-62.96500400000002,58.15387700000008],[-63.01222199999995,58.13555100000008],[-63.01666299999994,58.126098999999954],[-63.023888,58.11888099999999],[-63.045279999999934,58.10888699999998],[-63.12694499999992,58.08693699999998],[-63.205558999999994,58.06582600000007],[-63.21166999999997,58.06249200000008],[-63.211388,58.06027200000011],[-63.20889299999999,58.057770000000005],[-63.19027699999998,58.05304700000005],[-63.14083899999997,58.04888200000005],[-63.146998999999994,58.03683100000001],[-63.15582999999998,58.026939000000084],[-63.16777799999994,58.02110300000004],[-63.193329000000006,58.01471700000013],[-63.26722000000001,58.007217000000026],[-63.27527599999996,58.00555400000013],[-63.30471799999998,57.996940999999936],[-63.34166699999997,57.98110200000002],[-63.34083599999997,57.97998800000005],[-63.32972699999999,57.98027000000013],[-63.15166499999998,57.993607],[-63.12888299999997,57.997772],[-63.10777999999999,58.0077740000001],[-63.101944,58.01249700000011],[-63.09888499999994,58.017769000000044],[-63.097778000000005,58.01971400000002],[-63.09833500000002,58.026939000000084],[-63.09999800000003,58.03305100000006],[-63.101944,58.036942000000124],[-63.1016689999999,58.044159000000036],[-63.097778000000005,58.052216000000044],[-63.09471899999994,58.05749500000002],[-63.089164999999866,58.06221000000005],[-62.946662999999944,58.124161000000015],[-62.940276999999924,58.12582400000014],[-62.886390999999946,58.137496999999996],[-62.83805100000001,58.144997000000046],[-62.832222,58.14527099999998],[-62.82944500000002,58.143326],[-62.77277399999997,58.12915800000013],[-62.652221999999995,58.118599000000074],[-62.64611100000002,58.119155999999975],[-62.643058999999994,58.11998699999998],[-62.61250299999995,58.137771999999984],[-62.59944200000001,58.145546000000024],[-62.560828999999956,58.156654],[-62.515838999999914,58.16915899999992],[-62.49194299999999,58.17416399999996],[-62.46665999999999,58.175552000000096],[-62.45278199999996,58.17527000000001],[-62.44805100000002,58.1722180000001],[-62.44638800000001,58.16832700000003],[-62.44777699999992,58.16415400000005],[-62.46300099999996,58.15104700000006],[-62.46966600000002,58.145718000000045],[-62.47833300000002,58.14121200000005],[-62.48616800000002,58.136547000000064],[-62.50389099999995,58.123604000000114],[-62.519447000000014,58.11193799999995],[-62.529166999999916,58.10277600000006],[-62.531386999999995,58.09526800000003],[-62.51445000000001,58.05749500000002],[-62.506392999999946,58.05526700000007],[-62.49805499999991,58.057213000000104],[-62.49138599999992,58.061378000000104],[-62.48666400000002,58.066940000000045],[-62.48444399999994,58.07222000000013],[-62.48555799999991,58.081107999999915],[-62.488051999999925,58.08610500000003],[-62.48889199999991,58.09110300000003],[-62.488051999999925,58.09665700000005],[-62.48277299999995,58.10027300000007],[-62.444827999999916,58.10672000000005],[-62.41305499999993,58.11082500000009],[-62.375,58.11277000000007],[-62.368889000000024,58.11166400000002],[-62.36389200000002,58.108604000000014],[-62.31777999999997,58.05248999999998],[-62.30750299999988,58.039161999999976],[-62.30694599999998,58.03110499999997],[-62.30972299999996,58.02860300000009],[-62.38144699999998,58.008327000000065],[-62.39411200000001,58.00365800000009],[-62.40628099999998,58.00282700000008],[-62.41311300000001,58.00365800000009],[-62.43761399999988,58.0101590000001],[-62.45044300000001,58.01199300000013],[-62.50083899999993,58.00804900000014],[-62.51916499999993,58.00694300000009],[-62.52833599999997,58.00555400000013],[-62.545279999999934,58.000549000000035],[-62.648056,57.95832800000005],[-62.65527300000002,57.95360599999998],[-62.65972099999999,57.94860100000011],[-62.672774999999945,57.929993000000024],[-62.664443999999946,57.928604000000064],[-62.65527300000002,57.929993000000024],[-62.64083899999997,57.93526499999996],[-62.636116000000015,57.938598999999954],[-62.620833999999945,57.94748700000014],[-62.611670999999944,57.95166000000006],[-62.57749899999999,57.96221200000008],[-62.53778099999988,57.97110000000009],[-62.51250499999992,57.972488],[-62.45516599999996,57.96821200000005],[-62.448001999999974,57.96770899999996],[-62.32500499999992,57.956100000000106],[-62.268332999999984,57.948875000000044],[-62.200278999999966,57.93582200000009],[-62.148888,57.97499099999993],[-62.145279000000016,57.97415900000004],[-62.12749500000001,57.968048000000124],[-62.11611199999999,57.96249399999999],[-62.08361099999996,57.94499200000013],[-62.079726999999934,57.942763999999954],[-62.072227,57.931107000000054],[-62.05972300000002,57.89777400000003],[-62.060828999999956,57.88999200000006],[-62.06277499999993,57.88665800000007],[-62.115279999999984,57.854164000000026],[-62.13194299999998,57.84276600000004],[-62.138053999999954,57.835823000000005],[-62.13916799999993,57.83194000000009],[-62.12527499999999,57.806938],[-62.12083399999989,57.80082700000008],[-62.11999500000002,57.79999499999997],[-62.10777999999999,57.789719000000105],[-62.08916499999998,57.780548000000124],[-62.085830999999985,57.77943399999998],[-62.079169999999976,57.77943399999998],[-62.061110999999926,57.78193699999997],[-62.04639400000002,57.78582800000004],[-62.033332999999914,57.787216000000114],[-62.01805899999994,57.78360700000013],[-61.996666000000005,57.77221700000007],[-61.99138599999992,57.7677690000001],[-61.88999899999999,57.66638200000011],[-61.883331,57.64554600000008],[-61.88305700000001,57.63749700000011],[-61.88444499999997,57.62693800000005],[-61.88861099999997,57.622490000000084],[-61.89805599999994,57.616386000000034],[-62.07167099999998,57.56360599999999],[-62.1922229999999,57.535828000000095],[-62.30860899999999,57.49054699999999],[-62.42138699999998,57.48220799999996],[-62.43194599999987,57.48471799999999],[-62.531113000000005,57.506943000000035],[-62.54138899999998,57.50750000000011],[-62.544723999999974,57.504440000000045],[-62.545279999999934,57.50110600000005],[-62.533332999999914,57.49221800000009],[-62.52055399999995,57.48499300000003],[-62.46444699999995,57.4544370000001],[-62.457222,57.4511030000001],[-62.37722000000002,57.42193600000002],[-62.36527999999993,57.419715999999994],[-62.35388899999998,57.41832699999998],[-62.33583099999993,57.41944099999995],[-62.230552999999986,57.44360400000011],[-62.17333199999996,57.46360800000002],[-62.167220999999984,57.464439000000084],[-62.060828999999956,57.45638300000002],[-62.03972599999997,57.453323000000125],[-61.891388000000006,57.41193400000003],[-61.816948000000025,57.37693800000011],[-61.803054999999915,57.369155999999975],[-61.80139199999991,57.363052000000096],[-61.803054999999915,57.358887000000095],[-61.86389200000002,57.28555300000011],[-61.89416499999999,57.26944000000009],[-61.93749999999994,57.25222000000008],[-61.944999999999936,57.250832],[-61.953888000000006,57.24943500000006],[-61.99777999999998,57.25638600000002],[-62.01721999999995,57.25694300000009],[-62.02638999999999,57.25582900000012],[-62.02361300000001,57.25166300000001],[-62.01583900000003,57.24305000000004],[-62.00500499999987,57.23665599999998],[-61.85889400000002,57.16777000000013],[-61.85250099999996,57.16526800000008],[-61.664444,57.14388300000007],[-61.65555599999999,57.143051000000014],[-61.56555199999997,57.149719000000005],[-61.51555599999995,57.15638000000007],[-61.490837,57.1594310000001],[-61.478882,57.1594310000001],[-61.45889299999999,57.154709000000025],[-61.441665999999884,57.148604999999975],[-61.39305899999988,57.12470999999999],[-61.380279999999914,57.117210000000114],[-61.36389200000002,57.09721400000012],[-61.35833699999995,57.08749400000005],[-61.35555999999997,57.016388000000006],[-61.370833999999945,56.97860000000014],[-61.378052000000025,56.98220800000007],[-61.393332999999984,56.983047000000056],[-61.479720999999984,56.98360400000013],[-61.487777999999935,56.98165899999998],[-61.49555199999986,56.97943099999998],[-61.51639599999993,56.970267999999976],[-61.53556099999997,56.961104999999975],[-61.54666899999995,56.95443700000004],[-61.63999899999993,56.88388100000003],[-61.645003999999915,56.87832600000013],[-61.64833799999997,56.87304699999993],[-61.65083299999992,56.86693600000007],[-61.65277900000001,56.85582699999998],[-61.65277900000001,56.845543000000134],[-61.65055099999995,56.8408280000001],[-61.64611100000002,56.82694200000009],[-61.64611100000002,56.82110600000004],[-61.65027600000002,56.816666000000055],[-61.661384999999996,56.80943300000001],[-61.67639200000002,56.802773],[-61.78239100000002,56.794441000000006],[-61.79922499999992,56.79293799999999],[-61.81688699999995,56.79361],[-61.82355899999999,56.794441000000006],[-61.83455699999996,56.79610800000012],[-61.844559000000004,56.79894300000001],[-61.892226999999934,56.79860700000012],[-61.90638699999994,56.79527300000012],[-61.90860699999996,56.78916200000003],[-61.90222199999994,56.71415699999994],[-61.89999399999999,56.707214000000135],[-61.89722399999994,56.703049000000135],[-61.88999899999999,56.698044000000095],[-61.88611599999996,56.698044000000095],[-61.877776999999924,56.71305100000012],[-61.87027699999993,56.72693600000002],[-61.83366799999993,56.74199300000009],[-61.83083299999993,56.74532700000009],[-61.824996999999996,56.74682600000011],[-61.81150400000001,56.74682600000011],[-61.79333500000001,56.74682600000011],[-61.78049899999996,56.74565899999999],[-61.772834999999986,56.744160000000136],[-61.76266899999996,56.741325000000074],[-61.716392999999925,56.73804500000011],[-61.70249899999999,56.73082000000005],[-61.69694499999997,56.72470900000013],[-61.701667999999984,56.71332599999994],[-61.71055599999994,56.70555100000007],[-61.72110699999996,56.7011030000001],[-61.734443999999996,56.697212000000036],[-61.75417299999998,56.697487000000024],[-61.76500699999997,56.6988750000001],[-61.773056,56.7011030000001],[-61.798339999999996,56.710823000000005],[-61.808334,56.712212000000136],[-61.821670999999924,56.709717000000126],[-61.82500499999992,56.706657000000064],[-61.821670999999924,56.701660000000004],[-61.799171,56.682770000000005],[-61.79250300000001,56.68082400000014],[-61.73221599999994,56.66332200000011],[-61.681670999999994,56.65360300000009],[-61.67444599999993,56.65304600000002],[-61.658889999999985,56.647774000000084],[-61.649726999999984,56.641662999999994],[-61.649993999999936,56.635268999999994],[-61.65860700000002,56.62748700000003],[-61.672500999999954,56.619986999999924],[-61.68055700000002,56.618050000000096],[-61.68888900000002,56.61721000000006],[-61.699164999999994,56.61776700000013],[-61.835556,56.631660000000124],[-61.91166700000002,56.642769000000044],[-61.99277499999994,56.66027100000008],[-62.01000199999987,56.664153999999996],[-62.06694799999991,56.67860400000012],[-62.31111099999998,56.735550000000046],[-62.47999599999997,56.77388000000002],[-62.498885999999914,56.779716000000064],[-62.504448000000025,56.78360700000013],[-62.505004999999926,56.78888699999999],[-62.50194499999998,56.79193900000013],[-62.486114999999984,56.79610400000013],[-62.468886999999995,56.79860700000012],[-62.326392999999996,56.81276700000001],[-62.22749299999987,56.816666000000055],[-62.18999500000001,56.81332400000008],[-62.138335999999924,56.81082200000003],[-62.06833599999999,56.817214999999976],[-62.05944099999988,56.81860399999999],[-62.051665999999955,56.82054900000014],[-62.042502999999954,56.82694200000009],[-62.043334999999956,56.829994000000056],[-62.049445999999875,56.83249699999999],[-62.06694799999991,56.83443499999993],[-62.23472600000002,56.836937000000034],[-62.38166799999999,56.83027600000008],[-62.478606999999954,56.84665700000011],[-62.48889199999991,56.84943400000003],[-62.498885999999914,56.850548],[-62.50833899999992,56.84999800000014],[-62.51721999999995,56.84804500000001],[-62.53194400000001,56.843605000000025],[-62.54389200000003,56.83721200000002],[-62.54695099999992,56.83471700000001],[-62.57028199999996,56.79860700000012],[-62.57389099999989,56.79277000000013],[-62.53833799999995,56.775551000000064],[-62.50305899999995,56.76221499999991],[-62.35610999999989,56.72221400000012],[-62.162773000000016,56.672768000000076],[-62.02277399999997,56.62748700000003],[-62.00527999999997,56.61693600000012],[-62.11750000000001,56.623046999999985],[-62.175003000000004,56.62387799999999],[-62.23555799999997,56.62360400000006],[-62.24111199999987,56.62332200000003],[-62.23972299999997,56.61721000000006],[-62.224715999999944,56.60916100000003],[-62.1922229999999,56.60249300000004],[-62.10500300000001,56.59693900000002],[-62.04639400000002,56.59582500000005],[-62.036117999999874,56.595267999999976],[-61.901389999999935,56.58776899999998],[-61.72943900000001,56.574440000000095],[-61.71500400000002,56.57222000000007],[-61.70805399999989,56.56888600000008],[-61.70111099999997,56.56082200000009],[-61.690833999999995,56.548050000000046],[-61.66666399999997,56.540549999999996],[-61.65833299999997,56.537498000000085],[-61.65527300000002,56.533882000000006],[-61.65332799999993,56.53054800000001],[-61.652221999999995,56.52610000000004],[-61.65332799999993,56.52054600000008],[-61.656661999999926,56.51082600000001],[-61.662216,56.50610400000011],[-61.680282999999974,56.49665800000014],[-61.68916300000001,56.494713000000104],[-61.75472300000001,56.48499300000003],[-61.773056,56.48471800000004],[-61.80388599999992,56.487770000000125],[-61.878052000000025,56.49777200000011],[-61.95194200000003,56.505554000000075],[-62.038612,56.50527199999999],[-62.04695099999992,56.50471500000009],[-62.05471799999998,56.50249500000007],[-62.061668,56.499435000000005],[-62.075561999999934,56.49193600000001],[-62.08306099999993,56.48693800000001],[-62.08527399999991,56.48304699999994],[-62.082222,56.481659000000036],[-62.076667999999984,56.47998799999999],[-62.07083899999998,56.481102000000135],[-62.02417000000003,56.48443600000013],[-61.97638699999999,56.48333000000014],[-61.965278999999896,56.48193400000008],[-61.952225,56.47582200000011],[-61.94694500000003,56.471100000000035],[-61.95616499999994,56.46405000000004],[-61.95883199999997,56.461048000000005],[-61.961333999999965,56.45971700000001],[-61.966003,56.458549000000005],[-61.97983599999998,56.45555100000007],[-61.999724999999955,56.44999700000011],[-62.01028400000001,56.44999700000011],[-62.01999699999999,56.45110299999993],[-62.048888999999974,56.45721400000002],[-62.05972300000002,56.45860300000004],[-62.06999999999999,56.45916000000011],[-62.124999999999886,56.45721400000002],[-62.13999899999993,56.45221700000013],[-62.143058999999994,56.449158000000125],[-62.13916799999993,56.444709999999986],[-62.124999999999886,56.43832400000008],[-62.11750000000001,56.435546999999985],[-62.083327999999995,56.423325000000034],[-62.073059,56.420547],[-61.98472600000002,56.415268000000026],[-61.96371799999997,56.41565700000007],[-61.95688999999999,56.41782399999994],[-61.909720999999934,56.413879000000065],[-61.79805799999991,56.39527099999998],[-61.79084,56.392494000000056],[-61.661384999999996,56.27027100000009],[-61.67833299999995,56.26916100000011],[-61.679169,56.26799399999999],[-61.68683599999997,56.26699400000001],[-61.70283499999999,56.26532700000013],[-61.74999999999994,56.26132999999999],[-61.76066599999996,56.261662000000115],[-61.77216699999997,56.263493000000096],[-61.77716799999996,56.26532700000013],[-61.77967100000001,56.267494],[-61.77833599999997,56.26866100000012],[-61.77500199999997,56.268826000000104],[-61.76516699999996,56.26816200000002],[-61.756667999999934,56.26699400000001],[-61.74600199999992,56.267494],[-61.741000999999926,56.26916100000011],[-61.75361600000002,56.27304800000002],[-61.75305900000001,56.27777099999997],[-61.76999699999993,56.284163999999976],[-61.800835000000006,56.28943600000008],[-61.878608999999926,56.298607000000004],[-61.88861099999997,56.299164000000076],[-62.02972399999999,56.305267000000015],[-62.07444799999996,56.29638699999998],[-62.08000199999998,56.293610000000115],[-62.080832999999984,56.29249600000014],[-62.07611099999991,56.284996000000035],[-62.016395999999986,56.238883999999985],[-62.01167299999992,56.235825000000034],[-62.00389099999995,56.23360400000007],[-61.956947000000014,56.22082500000005],[-61.938331999999946,56.21582799999993],[-61.919448999999986,56.21221200000008],[-61.910278000000005,56.212493999999936],[-61.80205499999994,56.21638100000007],[-61.769889999999975,56.218048000000124],[-61.575004999999976,56.21693399999998],[-61.57556199999999,56.211937000000034],[-61.578612999999905,56.206940000000145],[-61.57972699999999,56.19915800000001],[-61.57527900000002,56.19609800000012],[-61.56027999999992,56.194435],[-61.53583500000002,56.19638100000009],[-61.450553999999954,56.204994000000056],[-61.411941999999954,56.21471400000013],[-61.40444199999996,56.21749100000005],[-61.380279999999914,56.22304500000007],[-61.361670999999944,56.22360200000014],[-61.35083799999995,56.222214000000065],[-61.34555099999994,56.218323],[-61.33083299999987,56.18193800000006],[-61.330284000000006,56.17665900000003],[-61.33555599999994,56.17276799999996],[-61.34332999999992,56.170547000000056],[-61.37722000000002,56.16860200000008],[-61.38361399999991,56.16471100000001],[-61.39722399999988,56.155823000000055],[-61.40610499999991,56.146102999999925],[-61.45249899999993,56.06276700000001],[-61.452225,56.056937999999946],[-61.44860799999998,56.052772999999945],[-61.41388699999993,56.037773000000016],[-61.41138499999988,56.03749799999997],[-61.39749899999998,56.04110700000001],[-61.38277399999993,56.04749300000009],[-61.35639199999997,56.05832700000013],[-61.34666399999992,56.06137799999999],[-61.34027900000001,56.063049000000035],[-61.32472199999995,56.06526900000006],[-61.315552000000025,56.065544000000045],[-61.24361399999998,56.04749300000009],[-61.23972299999997,56.045273000000066],[-61.23750299999989,56.042770000000075],[-61.24055499999997,56.040276000000006],[-61.26583899999997,56.02276599999999],[-61.27361300000001,56.02082800000005],[-61.28250099999997,56.01971400000008],[-61.31027999999998,56.018600000000106],[-61.357223999999974,56.018600000000106],[-61.38861099999991,56.021934999999985],[-61.419167000000016,56.02721400000013],[-61.43860599999999,56.027489],[-61.48999799999996,56.02027099999998],[-61.50139599999994,56.014442000000145],[-61.503890999999896,56.01055100000008],[-61.503615999999965,56.00694299999998],[-61.421943999999996,55.963882000000126],[-61.41500100000002,55.96027400000003],[-61.39917000000003,55.958602999999925],[-61.38999899999999,55.95888500000001],[-61.38138600000002,55.96027400000003],[-61.32805599999995,55.964157000000114],[-61.254722999999956,55.96749100000011],[-61.15444200000002,55.97137500000014],[-61.14361600000001,55.97054300000002],[-61.12555699999996,55.96859699999993],[-61.11777499999994,55.96610300000003],[-61.11361699999998,55.96249399999999],[-61.07444800000002,55.928329000000076],[-61.073891,55.9230500000001],[-61.076667999999984,55.906937000000084],[-61.09411199999994,55.895606999999984],[-61.156386999999995,55.8919370000001],[-61.165276000000006,55.892220000000066],[-61.181670999999994,55.89916199999999],[-61.19499999999999,55.892220000000066],[-61.201667999999984,55.884163000000115],[-61.19860799999992,55.87638099999998],[-61.192771999999934,55.869437999999946],[-61.10444599999994,55.845543000000134],[-61.0952759999999,55.84388000000001],[-61.08527400000003,55.84332299999994],[-61.077225,55.84388000000001],[-61.068062,55.845543000000134],[-61.039665000000014,55.850937000000044],[-61.035999000000004,55.85327100000006],[-61.02716800000002,55.85727300000008],[-60.946105999999986,55.86582900000013],[-60.91722099999993,55.864441000000056],[-60.78250099999997,55.85416400000008],[-60.76222199999995,55.85138699999999],[-60.755562,55.84943400000003],[-60.741669,55.843048000000124],[-60.72972099999993,55.829436999999984],[-60.72916399999997,55.82444000000004],[-60.73082699999998,55.80804400000005],[-60.734443999999996,55.80121200000002],[-60.736942,55.79738200000003],[-60.74222599999996,55.79054999999994],[-60.774719000000005,55.772491],[-60.80777699999993,55.755271999999934],[-60.88055400000002,55.74916100000007],[-60.87943999999999,55.73276500000003],[-60.76500699999997,55.72804299999996],[-60.756393,55.72943100000009],[-60.746947999999975,55.731659000000036],[-60.740279999999984,55.734161000000086],[-60.72721899999988,55.73999000000009],[-60.721663999999976,55.744713000000104],[-60.7016109999999,55.76344300000011],[-60.66889199999997,55.795830000000024],[-60.65638699999994,55.81276700000001],[-60.64722399999994,55.822768999999994],[-60.63999899999999,55.82555400000001],[-60.63166799999999,55.82666000000006],[-60.623885999999914,55.82499699999994],[-60.61527999999993,55.82193799999999],[-60.601943999999946,55.8147130000001],[-60.59777799999989,55.80943300000007],[-60.59805299999999,55.80443600000012],[-60.60583500000001,55.73387900000006],[-60.615837,55.68693500000006],[-60.6297229999999,55.638329000000056],[-60.66805999999997,55.5894320000001],[-60.65555599999993,55.58443500000004],[-60.606109999999944,55.622489999999914],[-60.60222599999986,55.626656000000025],[-60.59027900000001,55.64471400000008],[-60.544167000000016,55.72693600000002],[-60.52722199999988,55.760551000000135],[-60.527495999999985,55.76583099999999],[-60.52555799999993,55.77693899999997],[-60.51944699999996,55.78804800000006],[-60.514449999999954,55.79361],[-60.50305900000001,55.803046999999935],[-60.48777799999988,55.808601000000124],[-60.483611999999994,55.809158000000025],[-60.339995999999985,55.78638499999994],[-60.33499899999998,55.78443900000008],[-60.328888000000006,55.78166199999998],[-60.327224999999885,55.77276600000005],[-60.329444999999964,55.76138300000002],[-60.33777599999996,55.748604],[-60.38055399999996,55.69193300000006],[-60.406386999999995,55.674713000000054],[-60.463218999999924,55.66604600000011],[-60.47272099999998,55.6632120000001],[-60.493889000000024,55.658043000000134],[-60.49999999999994,55.65416000000005],[-60.50389100000001,55.648330999999985],[-60.52500199999997,55.610550000000046],[-60.53111299999995,55.597214000000065],[-60.532218999999884,55.591660000000104],[-60.53185999999994,55.58819599999998],[-60.51500699999997,55.599715999999944],[-60.50611099999992,55.61166400000002],[-60.495003,55.621101000000124],[-60.48138399999999,55.627769000000114],[-60.44033400000001,55.620216000000084],[-60.42616700000002,55.61821700000007],[-60.420334000000025,55.61637900000005],[-60.415501000000006,55.61454800000007],[-60.32277699999992,55.57833099999999],[-60.31639100000001,55.57388300000002],[-60.31639100000001,55.57027400000004],[-60.31944999999996,55.530823000000055],[-60.32167099999998,55.509995],[-60.42631899999998,55.44820400000009],[-60.442210999999986,55.427696000000026],[-60.43777499999999,55.39943700000009],[-60.47833299999991,55.347488000000055],[-60.47277100000002,55.34777100000002],[-60.45139299999994,55.35721600000011],[-60.42610899999994,55.37665600000008],[-60.420837000000006,55.38221000000004],[-60.41833500000001,55.38610799999998],[-60.41527599999995,55.39471400000008],[-60.41777799999994,55.40277100000009],[-60.42250100000001,55.407211000000075],[-60.425003000000004,55.411377000000016],[-60.423614999999984,55.421378999999945],[-60.41833500000001,55.427490000000034],[-60.413054999999986,55.43166400000007],[-60.34916700000002,55.47582200000011],[-60.33167300000002,55.48665599999998],[-60.31944999999996,55.491378999999995],[-60.26860799999997,55.502495000000124],[-60.25389099999995,55.503052000000025],[-60.21388999999999,55.489433000000076],[-60.20361300000002,55.48360400000007],[-60.201667999999984,55.478600000000085],[-60.19554899999997,55.4313810000001],[-60.26583900000003,55.40915699999999],[-60.27416999999991,55.40804300000002],[-60.284171999999955,55.40860000000009],[-60.295279999999934,55.41110200000014],[-60.30527499999988,55.41165900000004],[-60.313332,55.41110200000014],[-60.35472099999993,55.394997000000046],[-60.46888699999994,55.28582799999998],[-60.49888599999997,55.25332599999996],[-60.53805499999993,55.200546000000145],[-60.49999999999994,55.21804799999995],[-60.48889200000002,55.227210999999954],[-60.482215999999994,55.23165899999992],[-60.47638699999999,55.2347180000001],[-60.46832999999992,55.237495000000024],[-60.37388599999997,55.26055100000002],[-60.36583699999994,55.260826000000066],[-60.355278,55.25943799999999],[-60.34861000000001,55.25582900000012],[-60.348052999999936,55.25054900000009],[-60.353057999999976,55.244995000000074],[-60.51222200000001,55.12054399999994],[-60.58777600000002,55.08859999999993],[-60.616660999999965,55.07721700000013],[-60.636116000000015,55.066666],[-60.67055499999998,55.044715999999994],[-60.68111399999992,55.00471500000003],[-60.683326999999906,54.99499500000013],[-60.59277300000002,55.05888400000009],[-60.475273000000016,55.124435000000005],[-60.266395999999986,55.240547000000106],[-60.259170999999924,55.24415599999992],[-60.25250199999999,55.24638400000009],[-60.176109,55.270827999999995],[-60.079781000000025,55.24960299999998],[-60.07377600000001,55.24794000000003],[-60.072776999999974,55.24510600000002],[-60.11077899999992,55.199268000000075],[-60.123610999999926,55.15638000000013],[-60.14639299999993,55.13721499999997],[-60.15721899999994,55.12860100000012],[-60.18721799999997,55.108047],[-60.20444500000002,55.10749800000002],[-60.21277600000002,55.10860400000007],[-60.220551,55.10638400000005],[-60.28277600000001,55.05777000000006],[-60.28833799999995,55.05332199999992],[-60.295006,55.041382000000056],[-60.29695099999992,55.03443900000002],[-60.29666899999995,55.02499399999999],[-60.29389200000003,55.019440000000145],[-60.284171999999955,55.02443700000009],[-60.152495999999985,55.10277600000012],[-60.12444299999993,55.120270000000005],[-60.09944200000001,55.13665800000007],[-60.08833299999992,55.14582799999994],[-60.08388499999995,55.15221400000007],[-60.051223999999934,55.182381000000134],[-60.04571900000002,55.19304699999998],[-60.04472399999992,55.19671199999999],[-60.04272100000003,55.199883],[-60.03971899999988,55.203213000000005],[-60.03605700000003,55.20638300000007],[-60.02188899999999,55.21854799999994],[-60.01522399999999,55.221546000000046],[-60.00922400000002,55.22121400000009],[-59.96472199999994,55.23554999999999],[-59.93943799999994,55.233047000000056],[-59.922774999999945,55.233047000000056],[-59.91694599999994,55.233879000000115],[-59.91249799999997,55.238883999999985],[-59.89083899999997,55.26554900000002],[-59.86833200000001,55.291382],[-59.863891999999964,55.29610400000007],[-59.85139499999997,55.30304700000005],[-59.80750299999994,55.32416499999994],[-59.79527999999999,55.32749200000006],[-59.77916700000003,55.329720000000066],[-59.77610800000002,55.32916299999994],[-59.715003999999965,55.27609999999993],[-59.711945000000014,55.26971400000002],[-59.71333299999998,55.25610399999999],[-59.72943900000001,55.2052690000001],[-59.732497999999964,55.19721199999998],[-59.735832000000016,55.19415300000014],[-59.74277499999994,55.19137600000005],[-59.83139,55.162491000000045],[-59.84749599999998,55.15804300000008],[-59.863891999999964,55.154160000000104],[-59.89778100000001,55.151382000000126],[-59.918334999999956,55.15526599999998],[-59.94027699999998,55.16276600000003],[-59.9505539999999,55.16443600000002],[-59.96277599999996,55.16110200000003],[-59.96721599999995,55.15859999999998],[-59.970832999999914,55.15554800000001],[-59.97332799999987,55.14749100000006],[-59.96805599999993,55.11915600000003],[-59.963615000000004,55.110275000000115],[-59.80083499999995,55.10888700000004],[-59.79527999999999,55.10916099999997],[-59.615837,55.13638300000008],[-59.57028200000002,55.159988000000055],[-59.531386999999995,55.18138099999999],[-59.48777799999999,55.18138099999999],[-59.43055700000002,55.15193199999999],[-59.428337,55.149719000000005],[-59.427223000000026,55.13999200000006],[-59.42777999999993,55.13582600000001],[-59.431945999999925,55.129433000000006],[-59.438605999999936,55.123604],[-59.49610899999999,55.078331000000105],[-59.539169000000015,55.04916399999996],[-59.593886999999995,55.02082800000005],[-59.61083199999996,55.012771999999984],[-59.71665999999993,54.95582600000006],[-59.80216599999994,54.887268000000006],[-59.82399699999996,54.85110500000013],[-59.93916300000001,54.75888800000001],[-59.94416000000001,54.75555400000002],[-59.94554900000003,54.75305200000014],[-59.94416000000001,54.74971800000014],[-59.938605999999936,54.74638399999998],[-59.91916699999996,54.74137900000011],[-59.90943900000002,54.740829000000076],[-59.888610999999855,54.74332400000014],[-59.882499999999936,54.74499500000002],[-59.797500999999954,54.78166199999998],[-59.79111499999999,54.78555300000005],[-59.788612,54.78943600000002],[-59.790282999999874,54.79415899999998],[-59.79099999999994,54.82265899999999],[-59.79416699999996,54.82815900000014],[-59.79466599999995,54.83099400000003],[-59.7938309999999,54.83999299999999],[-59.79099999999994,54.846825000000024],[-59.78433999999993,54.857658000000015],[-59.77200299999993,54.86949200000004],[-59.7547229999999,54.897491000000116],[-59.72999599999997,54.907493999999986],[-59.703888000000006,54.91054500000001],[-59.68888899999996,54.913605000000075],[-59.67444599999999,54.91999099999998],[-59.61833199999995,54.948601],[-59.41111000000001,55.0563810000001],[-59.29389199999997,55.16971600000011],[-59.16527599999995,55.23499300000009],[-59.161384999999996,55.23693800000012],[-59.15471600000001,55.23554999999999],[-59.14416499999999,55.22804300000007],[-59.13944200000003,55.223877000000016],[-59.13111099999992,55.215546000000074],[-59.12749499999995,55.205826],[-59.12499999999994,55.19638099999992],[-59.12444299999987,55.18610399999994],[-59.14944099999991,55.16182699999996],[-59.15060799999992,55.15899299999995],[-59.155276999999955,55.15215699999993],[-59.16127799999998,55.146823999999924],[-59.168609999999944,55.141827000000035],[-59.176608999999985,55.13798900000006],[-59.205276000000026,55.13116100000002],[-59.20911000000001,55.12982200000005],[-59.24027999999993,55.11138200000005],[-59.25278499999996,55.10249299999998],[-59.363335000000006,55.01583099999999],[-59.37471800000003,55.00638600000008],[-59.38305699999995,54.99804700000004],[-59.386390999999946,54.99304999999998],[-59.39111300000002,54.98220800000013],[-59.39138799999995,54.98027000000002],[-59.38861099999997,54.97665400000011],[-59.384170999999924,54.973319999999944],[-59.37471800000003,54.97276300000004],[-59.36916400000001,54.97526600000003],[-59.275001999999915,55.02166],[-59.26250499999986,55.02832799999999],[-59.250838999999985,55.03582800000004],[-59.23722099999998,55.04833200000007],[-59.24250000000001,55.06110400000006],[-59.24305700000002,55.06638300000003],[-59.240837,55.07110600000004],[-59.23666399999996,55.07749200000012],[-59.13333099999994,55.120491000000015],[-59.05166600000001,55.153320000000065],[-59.03527799999989,55.15693700000003],[-59.02361300000001,55.15665400000006],[-58.96055599999988,55.134995],[-58.956107999999915,55.13027199999999],[-58.955832999999984,55.126381000000094],[-58.955832999999984,55.10083000000003],[-58.95833600000003,55.09165999999999],[-58.96167000000003,55.08526599999993],[-58.97110699999996,55.07110600000004],[-58.980278,55.059990000000084],[-59.005562,55.032767999999976],[-59.00194499999998,55.0177690000001],[-58.97249599999998,54.99554400000005],[-58.947220000000016,54.985550000000046],[-58.90721899999994,54.963882000000126],[-58.896950000000004,54.95638300000013],[-58.89416499999987,54.95277399999998],[-58.895279000000016,54.94776900000011],[-58.90055099999995,54.94387800000004],[-58.90694400000001,54.940269],[-58.96472199999988,54.91749600000014],[-59.01306199999999,54.89610300000004],[-59.015556000000004,54.892220000000066],[-59.01361800000001,54.88971700000013],[-58.90416700000003,54.844711000000075],[-58.83833299999998,54.832497000000046],[-58.83250399999997,54.831940000000145],[-58.82417299999997,54.834434999999985],[-58.69444299999998,54.82054900000003],[-58.68527199999994,54.81554399999999],[-58.560828999999956,54.77610000000004],[-58.44361099999992,54.77388000000002],[-58.39888799999994,54.78472099999999],[-58.391944999999964,54.787498000000085],[-58.379997,54.789993000000095],[-58.328056000000004,54.792496000000085],[-58.24333199999995,54.79471600000005],[-58.196663,54.79527299999995],[-58.19110899999998,54.79415899999998],[-58.188332,54.792496000000085],[-58.18721800000003,54.78860500000002],[-58.188605999999936,54.783051],[-58.19388600000002,54.77777100000009],[-58.19694499999997,54.77332299999995],[-58.19860799999998,54.76776899999999],[-58.184166000000005,54.75166299999995],[-58.173332000000016,54.74554400000011],[-58.145554000000004,54.739716000000044],[-58.11000100000001,54.737213000000054],[-58.00139599999994,54.73333000000008],[-57.94554899999997,54.73998999999998],[-57.935554999999965,54.74110400000012],[-57.910552999999936,54.74193600000001],[-57.855002999999954,54.73749500000008],[-57.84749599999992,54.7355500000001],[-57.84249899999992,54.73137700000001],[-57.831947000000014,54.71776600000004],[-57.789725999999916,54.68221299999999],[-57.78556100000003,54.67916100000008],[-57.71305799999993,54.64305100000013],[-57.70083599999998,54.63721500000008],[-57.693610999999976,54.63472000000007],[-57.67639200000002,54.630272000000105],[-57.660278000000005,54.62804399999993],[-57.64222699999999,54.62804399999993],[-57.62638899999996,54.62999000000002],[-57.57778199999996,54.63888500000007],[-57.57417299999997,54.64027400000003],[-57.569725000000005,54.644440000000145],[-57.56722300000001,54.64833100000004],[-57.55916599999995,54.655823],[-57.54583699999995,54.66165900000004],[-57.5391689999999,54.662209000000075],[-57.45639,54.65082600000005],[-57.450553999999954,54.649993999999936],[-57.44471699999997,54.64721700000007],[-57.355834999999956,54.59027100000009],[-57.352782999999874,54.58749399999999],[-57.34749599999992,54.57943700000004],[-57.346947,54.57471499999997],[-57.34861000000001,54.566940000000045],[-57.38082899999995,54.50749999999999],[-57.38527699999992,54.50332600000013],[-57.39694999999995,54.49582700000013],[-57.42722299999997,54.48777000000001],[-57.48472600000002,54.48249100000004],[-57.49305700000002,54.48333000000014],[-57.519447000000014,54.483879000000115],[-57.590836000000024,54.48416099999997],[-57.618056999999965,54.48360400000007],[-57.67277499999989,54.47998800000005],[-57.69499999999999,54.475548],[-57.70222499999994,54.47304500000007],[-57.704169999999976,54.470543000000134],[-57.70527599999997,54.46693399999998],[-57.70055400000001,54.45915999999994],[-57.68694299999993,54.45888500000012],[-57.65833299999997,54.46305100000001],[-57.58777599999996,54.46720899999997],[-57.487777999999935,54.47304500000007],[-57.47222099999999,54.47360200000014],[-57.44999699999994,54.46749100000005],[-57.442497,54.46499600000004],[-57.42527799999999,54.45915999999994],[-57.421111999999994,54.455826],[-57.42166900000001,54.45360599999998],[-57.523330999999985,54.41721300000006],[-57.621666000000005,54.38360599999993],[-57.62943999999999,54.38166000000007],[-57.660827999999924,54.376937999999996],[-57.678337,54.37526700000012],[-57.69527399999993,54.37499200000008],[-57.71555299999994,54.376937999999996],[-57.743056999999965,54.38082100000008],[-57.78333299999997,54.38832900000011],[-57.79722600000002,54.38888500000013],[-57.876105999999936,54.38665800000007],[-57.910278000000005,54.38526900000005],[-58.05027799999988,54.37748700000009],[-58.14639299999999,54.36527300000006],[-58.15416699999997,54.36332700000003],[-58.17250100000001,54.35749800000002],[-58.18527199999994,54.35166199999992],[-58.24805500000002,54.3202740000001],[-58.259727,54.31276699999995],[-58.26194799999996,54.31110400000006],[-58.25917099999998,54.30971500000004],[-58.253333999999995,54.308884000000035],[-58.22110700000002,54.31166100000013],[-58.197495,54.31638300000003],[-58.108337000000006,54.32804900000002],[-58.09860999999995,54.327217000000076],[-58.09583299999997,54.325829],[-58.23388699999998,54.254166000000055],[-58.24722300000002,54.25277700000004],[-58.344161999999926,54.244438],[-58.383056999999894,54.24110400000001],[-58.410278000000005,54.241661000000136],[-58.417220999999984,54.242493000000024],[-58.43138899999997,54.24221800000004],[-58.453888000000006,54.23721299999994],[-58.566108999999926,54.20416300000011],[-58.579169999999976,54.199996999999996],[-58.60139499999997,54.186104],[-58.61194599999999,54.178329000000076],[-58.62888299999997,54.16971600000011],[-58.6444469999999,54.16526799999997],[-58.69277199999999,54.151657],[-58.724715999999944,54.14527100000009],[-58.75694999999996,54.14110600000009],[-58.77111099999996,54.13999200000012],[-58.79778299999998,54.139717000000076],[-58.83361100000002,54.145827999999995],[-58.84277300000002,54.145827999999995],[-58.86000100000001,54.14471400000002],[-58.915276000000006,54.1386030000001],[-58.92833699999994,54.13638300000008],[-59.114165999999955,54.103882],[-59.19055199999997,54.08721200000008],[-59.24833699999999,54.07193799999999],[-59.27944199999996,54.06443800000011],[-59.37610599999999,54.046943999999996],[-59.434440999999936,54.0472180000001],[-59.470275999999956,54.05165900000003],[-59.51000199999993,54.05943300000001],[-59.53444699999994,54.05832700000002],[-59.561385999999914,54.05332199999998],[-59.57556199999999,54.04943800000012],[-59.582221999999945,54.046387000000095],[-59.586945000000014,54.0430530000001],[-59.58860800000002,54.04054999999994],[-59.584723999999994,54.03527100000014],[-59.51722000000001,53.99721499999998],[-59.509727,53.99554400000011],[-59.49444599999998,53.99638399999998],[-59.26583900000003,54.023048000000074],[-59.04944599999993,54.057495000000074],[-58.87722000000002,54.094993999999986],[-58.70305599999995,54.12416100000013],[-58.43111399999992,54.217209000000025],[-58.42639200000002,54.2219310000001],[-58.417502999999954,54.22804300000007],[-58.40638699999994,54.22971300000006],[-58.37943999999993,54.229988000000105],[-58.371940999999936,54.22804300000007],[-58.37444299999993,54.22443400000009],[-58.44972200000001,54.154434000000094],[-58.60500300000001,54.04415899999998],[-58.61028299999998,54.04166399999991],[-58.632499999999936,54.03527100000014],[-58.654998999999975,54.03166199999998],[-58.678054999999915,54.029160000000104],[-58.70444500000002,54.027214000000015],[-58.72166399999992,54.027489],[-58.749168,54.03110500000008],[-58.75917099999998,54.032767999999976],[-58.76805899999994,54.03499599999998],[-58.77972399999993,54.03777300000007],[-58.80750299999994,54.04332700000003],[-58.83583099999993,54.0472180000001],[-58.879997,54.04499800000008],[-58.93749999999994,54.04166399999991],[-59.002501999999936,54.03249400000004],[-59.038611999999944,54.02693899999997],[-59.04138899999998,54.02610000000004],[-59.04277799999994,54.02276600000005],[-59.04055799999986,54.02175100000005],[-59.00695000000002,54.018051000000014],[-58.95194200000003,54.01471700000002],[-58.944159999999954,54.01527400000009],[-58.92583499999995,54.01471700000002],[-58.922500999999954,54.01388500000007],[-58.91944899999993,54.01082600000012],[-58.92305799999997,54.00721699999997],[-58.954169999999976,53.983879],[-58.96305799999993,53.97776799999997],[-58.98082699999998,53.966385000000116],[-59.00833899999992,53.95526899999999],[-59.01583899999997,53.953323000000125],[-59.04778299999998,53.94832600000001],[-59.07222699999994,53.947487000000024],[-59.11527999999987,53.94638100000003],[-59.12222300000002,53.94526700000006],[-59.172774999999945,53.93499000000003],[-59.201392999999996,53.92748999999998],[-59.33194699999996,53.888329000000056],[-59.345551,53.88304900000014],[-59.36389199999991,53.8722150000001],[-59.36944599999998,53.867493000000024],[-59.39361600000001,53.8555530000001],[-59.43638599999997,53.83749399999999],[-59.46333299999998,53.830551000000014],[-59.480278,53.82777400000009],[-59.527221999999995,53.82249500000012],[-59.54389200000003,53.8211060000001],[-59.59610700000002,53.81916000000001],[-59.62388599999997,53.82027400000004],[-59.63583399999999,53.82083100000011],[-59.69860799999998,53.82943700000004],[-59.71665999999993,53.831939999999975],[-59.728049999999996,53.83526600000005],[-59.75556199999994,53.83860000000004],[-59.79833999999994,53.843323],[-59.807776999999874,53.84388000000007],[-59.82583599999998,53.8427660000001],[-59.85278299999999,53.8394320000001],[-59.87249800000001,53.833603000000096],[-59.877219999999966,53.83027600000014],[-59.88055399999996,53.82527200000004],[-59.989165999999955,53.77971600000012],[-60.082779000000016,53.76249700000005],[-60.12110899999993,53.625267000000065],[-60.11999499999996,53.61138199999999],[-60.11361699999992,53.602493000000095],[-60.110000999999954,53.59887700000007],[-60.105002999999954,53.59471100000013],[-60.087501999999915,53.58360299999998],[-60.068062,53.57332600000001],[-60.06444499999998,53.56971699999997],[-60.063332,53.56582600000007],[-60.06444499999998,53.56027200000011],[-60.06972499999995,53.55555000000004],[-60.07500499999992,53.55304700000005],[-60.13388800000001,53.5283280000001],[-60.13833599999998,53.52860300000009],[-60.34749599999998,53.62693800000011],[-60.358611999999994,53.634438000000046],[-60.361670999999944,53.63971700000002],[-60.36444899999998,53.64833100000004],[-60.368056999999965,53.65277100000009],[-60.382499999999936,53.66249099999999],[-60.390556000000004,53.66554300000007],[-60.50305900000001,53.705826000000116],[-60.51111599999996,53.708327999999995],[-60.56027999999998,53.71832300000011],[-60.64861300000001,53.73737699999998],[-60.670612000000006,53.74004700000006],[-60.705115999999975,53.74488100000002],[-60.75894900000003,53.76171899999997],[-60.76994300000001,53.765381000000104],[-60.856948999999986,53.79277000000002],[-60.88722200000001,53.751389000000074],[-60.880279999999914,53.71305100000001],[-60.83472399999994,53.72137500000002],[-60.75772499999999,53.713768000000016],[-60.74722299999996,53.71276499999999],[-60.65489199999996,53.69876899999991],[-60.64422599999995,53.69693799999999],[-60.537223999999924,53.67832900000002],[-60.51194799999996,53.66971600000005],[-60.44656399999997,53.64485200000013],[-60.431670999999994,53.63916000000012],[-60.36028299999998,53.60665899999998],[-60.354445999999996,53.60388200000011],[-60.34222399999993,53.59609999999998],[-60.33416699999998,53.58915699999994],[-60.32333399999999,53.581665000000044],[-60.29861499999993,53.568054000000075],[-60.278884999999946,53.55860100000007],[-60.25361600000002,53.54999500000014],[-60.103614999999934,53.50054900000009],[-60.10639200000003,53.457497000000046],[-60.123328999999956,53.456100000000106],[-60.13805400000001,53.45360599999998],[-60.202225,53.43360099999995],[-60.40582999999998,53.36415899999997],[-60.41332999999997,53.35777300000001],[-60.412216,53.34971600000006],[-60.404998999999975,53.33416000000011],[-60.395835999999974,53.33138300000002],[-60.39111300000002,53.33110799999997],[-60.30139200000002,53.33638000000013],[-60.23082699999998,53.34332300000011],[-60.2161099999999,53.34582499999999],[-60.203888000000006,53.34971600000006],[-60.198607999999865,53.350548],[-60.18860599999999,53.350548],[-60.18332700000002,53.349433999999974],[-60.1766659999999,53.34638200000006],[-60.17500299999995,53.34304800000007],[-60.17472099999998,53.33804300000003],[-60.180831999999896,53.329994],[-60.19083399999994,53.32193799999993],[-60.202225,53.313605999999936],[-60.20889299999999,53.310546999999985],[-60.283332999999914,53.28943600000014],[-60.29583699999995,53.28665900000004],[-60.33388500000001,53.280548000000124],[-60.36721799999992,53.27777100000003],[-60.389725,53.27693899999997],[-60.41833500000001,53.269440000000145],[-60.41666399999997,53.268326],[-60.398056,53.26554900000008],[-60.316108999999926,53.26416000000006],[-60.289444,53.26388500000007],[-60.133613999999966,53.28360700000013],[-60.024719000000005,53.35499600000014],[-59.95388799999995,53.40693700000003],[-59.931945999999925,53.42582700000014],[-59.84194199999996,53.476379000000065],[-59.82167099999998,53.47165699999999],[-59.806107,53.47110000000009],[-59.79805799999997,53.472214000000065],[-59.78916899999996,53.47443400000009],[-59.78500399999996,53.477210999999954],[-59.783615,53.48110200000002],[-59.78472899999997,53.48526800000013],[-59.799170999999944,53.491378999999995],[-59.82361599999996,53.49332400000003],[-59.858611999999994,53.496101000000124],[-59.89916999999997,53.51693699999993],[-59.90110800000002,53.51971400000002],[-59.89833799999997,53.52416199999999],[-59.893058999999994,53.52860300000009],[-59.87555699999996,53.534996000000035],[-59.85583500000001,53.536942000000124],[-59.84749599999998,53.536658999999986],[-59.80999799999995,53.52971600000001],[-59.77361300000001,53.517769000000044],[-59.763061999999934,53.51527400000003],[-59.75556199999994,53.51499899999999],[-59.740279999999984,53.515831000000105],[-59.62110899999993,53.52721400000013],[-59.605834999999956,53.52971600000001],[-59.56082900000001,53.54055000000005],[-59.53082999999998,53.54888200000005],[-59.51750199999998,53.55387899999994],[-59.47833300000002,53.57276900000011],[-59.32972699999999,53.65387700000008],[-59.162216,53.671379000000115],[-59.079726999999934,53.680550000000096],[-59.07417299999992,53.683051999999975],[-59.023888,53.71388200000001],[-59.01916499999993,53.71915400000012],[-59.01083399999993,53.744438000000116],[-59.010559,53.74665800000014],[-59.01889,53.74916100000013],[-59.03500399999996,53.74721500000004],[-59.04138899999998,53.748604],[-59.04611199999994,53.75277699999998],[-59.06527699999998,53.79110700000007],[-59.066390999999896,53.794998000000135],[-59.058334,53.80332200000004],[-59.04944599999993,53.81082200000009],[-59.04277799999994,53.81499500000001],[-58.87027699999999,53.90470900000014],[-58.550277999999935,54.009163],[-58.32611099999997,54.04627199999999],[-58.21694200000002,54.07177000000013],[-58.204612999999995,54.074604000000136],[-58.19377499999996,54.07593900000006],[-58.18044699999996,54.075436000000025],[-58.156780000000026,54.07143400000001],[-58.15060799999992,54.06943899999999],[-58.028610000000015,54.07972000000012],[-57.95194200000003,54.070831000000055],[-57.93860599999999,54.07027399999998],[-57.815552000000025,54.066101],[-57.79750100000001,54.066101],[-57.789443999999946,54.06860399999999],[-57.78639199999992,54.071662999999944],[-57.78611799999999,54.075271999999984],[-57.789443999999946,54.07972000000012],[-57.80555699999991,54.08665499999995],[-57.85166899999996,54.100273000000016],[-57.86972000000003,54.10305000000005],[-58.07650000000001,54.124489000000096],[-58.15249599999993,54.12915800000002],[-58.16716399999996,54.127827000000025],[-58.18150300000002,54.124660000000006],[-58.195831,54.120159000000115],[-58.21083499999992,54.1139950000001],[-58.21466800000002,54.111828],[-58.216995,54.110493000000076],[-58.22300000000001,54.10399200000006],[-58.22683299999994,54.101826000000074],[-58.22983199999993,54.10082200000011],[-58.23683499999993,54.09932700000007],[-58.24516699999998,54.099158999999986],[-58.254332999999974,54.101322000000096],[-58.415276000000006,54.13526900000011],[-58.4183349999999,54.139717000000076],[-58.417220999999984,54.14305100000007],[-58.383613999999966,54.18971299999998],[-58.37943999999993,54.193877999999984],[-58.373885999999914,54.19832600000012],[-58.36750000000001,54.201934999999935],[-58.35555999999991,54.20638300000013],[-58.20361300000002,54.23416100000003],[-58.177779999999984,54.23693800000012],[-58.03082999999992,54.235550000000046],[-58.00305899999995,54.233879],[-57.99361399999998,54.230819999999994],[-57.97360999999995,54.22165699999999],[-57.9611129999999,54.2177660000001],[-57.935272,54.2116620000001],[-57.866660999999965,54.19776900000005],[-57.85639200000003,54.196098000000006],[-57.65916399999992,54.199432],[-57.46832999999992,54.193877999999984],[-57.428336999999885,54.18249499999996],[-57.38417099999998,54.15054300000003],[-57.385559,54.145827999999995],[-57.38999899999999,54.14110600000009],[-57.383613999999966,54.12887599999999],[-57.370833999999945,54.10638400000005],[-57.367774999999995,54.10193600000008],[-57.32333399999999,54.039719000000105],[-57.22110699999996,53.91832699999998],[-57.115279999999984,53.83860000000004],[-57.09277300000002,53.83166499999999],[-57.08361100000002,53.82860599999998],[-57.07972699999999,53.82666000000012],[-57.076392999999996,53.82305100000008],[-57.07749899999993,53.81944299999998],[-57.15138999999999,53.73582499999998],[-57.302498000000014,53.67916100000008],[-57.31472000000002,53.676383999999985],[-57.387504999999976,53.65832500000005],[-57.429169,53.647491],[-57.48416900000001,53.63166000000001],[-57.49111199999993,53.62887600000005],[-57.52305599999994,53.61249500000008],[-57.53889499999997,53.60221899999999],[-57.544448999999986,53.59777100000002],[-57.549995000000024,53.59193400000004],[-57.55055199999998,53.58749400000005],[-57.54527999999999,53.584717000000126],[-57.54111499999999,53.585266000000104],[-57.533332999999914,53.58749400000005],[-57.52777900000001,53.591377000000136],[-57.49361399999998,53.60943600000007],[-57.479720999999984,53.61332700000014],[-57.458054000000004,53.61749300000008],[-57.44471699999997,53.618599000000074],[-57.373610999999926,53.60665899999998],[-57.316666,53.57972000000001],[-57.31361399999997,53.573608000000036],[-57.303054999999915,53.53082300000011],[-57.302498000000014,53.52638200000001],[-57.30332900000002,53.50943799999993],[-57.30555700000002,53.49971800000003],[-57.30666400000001,53.49638400000009],[-57.31777999999997,53.47554800000006],[-57.32888799999995,53.46193700000009],[-57.332503999999915,53.45832800000005],[-57.345832999999914,53.45054600000009],[-57.336945000000014,53.440269000000114],[-57.31639099999995,53.43582200000009],[-57.30332900000002,53.43332700000002],[-57.29750100000001,53.43305200000003],[-57.289169000000015,53.433876],[-57.28333299999997,53.438598999999954],[-57.29361699999998,53.4677660000001],[-57.28527799999995,53.477486],[-57.281386999999995,53.47943099999998],[-57.24861099999998,53.49415600000009],[-57.23750299999989,53.49860400000006],[-57.13027999999997,53.59388000000013],[-57.11138900000003,53.62165800000008],[-57.06138599999997,53.671379000000115],[-57.01472499999994,53.71138000000013],[-56.97361000000001,53.72443400000003],[-56.959442000000024,53.7283250000001],[-56.926391999999964,53.730270000000075],[-56.91666399999997,53.728600000000085],[-56.860832000000016,53.72248800000011],[-56.79722600000002,53.71998600000006],[-56.660827999999924,53.720543000000134],[-56.62222300000002,53.73360400000007],[-56.62860899999998,53.74193600000007],[-56.628333999999995,53.74415600000003],[-56.626105999999936,53.74582700000013],[-56.603332999999964,53.75916300000006],[-56.483611999999994,53.7824940000001],[-56.464691000000016,53.782272000000034],[-56.44833399999999,53.77777100000014],[-56.431670999999994,53.76444200000003],[-56.42694899999998,53.75721699999997],[-56.41388699999999,53.727768000000026],[-56.414443999999946,53.72193100000004],[-56.41527599999995,53.720543000000134],[-56.42166900000001,53.716933999999924],[-56.429169,53.71527100000003],[-56.43804899999992,53.71527100000003],[-56.44694499999997,53.716933999999924],[-56.48277300000001,53.718048000000124],[-56.506393,53.716933999999924],[-56.52166699999998,53.71471400000013],[-56.544448999999986,53.70971700000001],[-56.662215999999944,53.679993000000024],[-56.68028300000003,53.67276800000013],[-56.62722000000002,53.65082600000005],[-56.61805700000002,53.647491],[-56.34055299999994,53.58832599999994],[-56.32028199999996,53.585266000000104],[-56.22555499999987,53.577217000000076],[-56.21665999999999,53.577217000000076],[-56.205832999999984,53.581665000000044],[-56.15582999999998,53.591660000000104],[-56.07861300000002,53.58387799999997],[-56.069167999999934,53.58277100000004],[-56.031386999999995,53.57638500000013],[-56.027221999999995,53.57527200000004],[-55.99138599999998,53.552216000000044],[-55.97888199999994,53.5422210000001],[-55.99083699999994,53.51027700000009],[-55.99694799999992,53.50527200000005],[-56.00878099999994,53.50366600000007],[-56.01294699999994,53.50399399999998],[-56.01744499999995,53.50599699999998],[-56.01861199999996,53.508495000000096],[-56.02111099999996,53.51305400000001],[-56.02249899999998,53.516388000000006],[-56.04750100000001,53.533607000000075],[-56.063332,53.54083300000002],[-56.14583600000003,53.55304700000005],[-56.20889299999999,53.559433000000126],[-56.24250000000001,53.55999000000003],[-56.25833899999992,53.55915800000014],[-56.264725,53.55555000000004],[-56.26611300000002,53.54999500000014],[-56.263335999999924,53.54027600000012],[-56.259170999999924,53.53777300000013],[-56.14555399999995,53.500000000000114],[-56.11527999999993,53.49193600000012],[-56.07749899999993,53.483330000000024],[-56.037780999999995,53.46165500000001],[-56.02744299999995,53.45432699999998],[-55.96555299999994,53.40915700000005],[-55.965836000000024,53.40554800000001],[-55.96944400000001,53.40054299999997],[-56.00417299999998,53.388045999999974],[-56.02527599999996,53.37971500000009],[-56.03167000000002,53.37609900000001],[-56.03833800000001,53.36749300000014],[-56.029998999999975,53.365273000000116],[-56.020835999999974,53.36415899999997],[-56.01306199999999,53.364441],[-56.001396,53.36666100000002],[-55.98805199999998,53.369713000000104],[-55.981383999999935,53.3730470000001],[-55.969497999999874,53.38077500000003],[-55.95972399999994,53.39027399999998],[-55.95313299999992,53.39244100000002],[-55.938605999999936,53.39527100000004],[-55.92511699999994,53.396133000000134],[-55.912216,53.3949970000001],[-55.89361600000001,53.389717000000076],[-55.881385999999964,53.382767],[-55.808051999999975,53.34054600000002],[-55.80745699999994,53.28496600000011],[-55.745834,53.24943500000012],[-55.74749800000001,53.14360799999997],[-55.749442999999985,53.139717000000076],[-55.75417299999992,53.134995],[-55.83331299999992,53.09793100000002],[-55.87985600000002,53.07379500000002],[-55.91194200000001,53.02832799999999],[-55.92666600000001,53.02332300000012],[-55.934440999999936,53.021660000000054],[-55.943329000000006,53.021102999999925],[-55.96444700000001,53.021660000000054],[-55.99083699999994,53.0241620000001],[-56.00833899999998,53.02748900000006],[-56.02500199999997,53.03360699999996],[-56.03417200000001,53.03611000000012],[-56.056107,53.03832999999997],[-56.160278000000005,53.03360699999996],[-56.16583300000002,53.03276800000003],[-56.166945999999996,53.02943400000004],[-56.165276000000006,53.02499399999999],[-56.04084,53.00582900000006],[-55.95861100000002,52.99610100000001],[-55.94943999999998,52.99499500000002],[-55.88944200000003,52.96915400000012],[-55.885276999999974,52.966384999999946],[-55.83416699999998,52.92193600000002],[-55.80471799999998,52.8772130000001],[-55.80332899999996,52.83943199999993],[-55.80388599999998,52.83194000000003],[-55.808051999999975,52.82638500000013],[-55.84110999999996,52.82721700000002],[-55.87916599999994,52.82416500000011],[-55.97361000000001,52.8105470000001],[-55.98777799999999,52.80609900000013],[-56.06082900000001,52.76610600000009],[-55.96472199999994,52.68166400000007],[-55.96055599999994,52.679161000000136],[-55.9505539999999,52.6772160000001],[-55.93360899999993,52.675552000000096],[-55.91833500000001,52.677490000000034],[-55.87471799999997,52.68332700000002],[-55.78694899999999,52.683601000000124],[-55.77916700000003,52.682495000000074],[-55.77305599999994,52.679161000000136],[-55.76888999999994,52.674995000000024],[-55.740837,52.64638500000001],[-55.73860899999994,52.64276899999993],[-55.739998000000014,52.639434999999935],[-55.75750699999992,52.614441],[-55.769447000000014,52.60804700000011],[-55.792778,52.60166200000009],[-55.888892999999996,52.60804700000011],[-55.89861300000001,52.60999300000003],[-55.939940999999976,52.62826899999999],[-55.958777999999995,52.63560499999994],[-56.032775999999956,52.654709000000025],[-56.04888900000003,52.65609699999993],[-56.07500499999992,52.655823],[-56.10861199999994,52.6552660000001],[-56.12277199999994,52.65110000000004],[-56.12388599999986,52.647491],[-56.11972000000003,52.643326],[-56.112007000000006,52.64103699999998],[-56.09906000000001,52.64100600000012],[-56.07194500000003,52.644714000000135],[-56.06361400000003,52.644714000000135],[-56.05444299999999,52.643608000000086],[-55.98277300000001,52.62249000000003],[-55.97499800000003,52.619713000000104],[-55.970832999999914,52.61554699999999],[-55.972770999999966,52.61082500000009],[-55.985275,52.60221899999999],[-56.039169000000015,52.58499100000006],[-56.155777,52.557438000000104],[-56.17261100000002,52.55360800000011],[-56.18611099999998,52.55093800000003],[-56.20077900000001,52.55093800000003],[-56.25305899999995,52.54388400000005],[-56.297500999999954,52.56360600000011],[-56.315552000000025,52.57221999999996],[-56.322501999999986,52.574715000000026],[-56.333327999999995,52.57694200000009],[-56.35639199999997,52.580276000000026],[-56.45638999999994,52.59276599999998],[-56.47860700000001,52.59443700000003],[-56.49687199999994,52.59414700000002],[-56.45278200000001,52.56888600000002],[-56.44416000000001,52.56582600000013],[-56.28055599999999,52.53499600000009],[-56.26222199999995,52.5316620000001],[-56.19755600000002,52.52510500000005],[-56.15355699999992,52.52610399999992],[-55.98889200000002,52.50638600000008],[-55.829726999999934,52.51249700000011],[-55.761390999999946,52.49887800000005],[-55.75139599999994,52.496101000000124],[-55.746947999999975,52.4938810000001],[-55.74305700000002,52.49082900000002],[-55.73500100000001,52.47859999999997],[-55.73416900000001,52.474709000000075],[-55.735832000000016,52.469154],[-55.76445000000001,52.45388000000014],[-55.76750199999992,52.451103000000046],[-55.766395999999986,52.44776900000005],[-55.73277299999995,52.44221500000003],[-55.706107999999915,52.44165800000013],[-55.67666600000001,52.44165800000013],[-55.65666199999998,52.441933000000006],[-55.648612999999955,52.43971299999998],[-55.645554000000004,52.43749200000008],[-55.64277599999997,52.432770000000005],[-55.64277599999997,52.42777300000006],[-55.641669999999976,52.368881000000044],[-55.641944999999964,52.36388399999993],[-55.643332999999984,52.35833000000014],[-55.64778099999995,52.354164000000026],[-55.65444199999996,52.351661999999976],[-55.782501000000025,52.33416000000011],[-55.825004999999976,52.343048000000124],[-55.92861199999993,52.369438000000116],[-56.06833599999993,52.40721099999996],[-56.173614999999984,52.43888100000004],[-56.180556999999965,52.44082600000007],[-56.19444299999992,52.44221500000003],[-56.19694500000003,52.43998700000009],[-56.19527399999998,52.43582200000009],[-56.19138299999997,52.431107000000054],[-56.18138899999997,52.4230500000001],[-56.169448999999986,52.41610000000003],[-55.95666499999999,52.35027299999996],[-55.85777999999999,52.325271999999984],[-55.707222,52.248329000000126],[-55.67722299999997,52.20832799999994],[-55.68638599999997,52.10943600000002],[-55.69694500000003,52.08832600000005],[-55.70166799999993,52.08221400000008],[-55.89666699999992,51.950829],[-56.023330999999985,51.9019320000001],[-56.203330999999935,51.79332699999998],[-56.209723999999994,51.78971900000005],[-56.235832000000016,51.783607000000075],[-56.346663999999976,51.759720000000016],[-56.468886999999995,51.709434999999985],[-56.68972000000002,51.59221600000001],[-56.76445000000001,51.54860700000006],[-56.804169,51.50777399999998],[-56.80583200000001,51.502219999999966],[-56.80889100000002,51.49638400000009],[-56.81361399999997,51.491661000000136],[-56.94277199999999,51.42748999999992],[-56.94972199999995,51.424713000000054],[-56.956947000000014,51.4230500000001],[-57.00556199999994,51.41944100000012],[-57.078056000000004,51.41443600000008],[-57.10423999999995,51.412674000000095],[-57.14222699999999,51.424164000000076],[-57.23221599999994,51.498604000000114],[-57.23777799999999,51.502219999999966],[-57.24722299999996,51.504166000000055],[-57.255562,51.50443999999999],[-57.263617999999894,51.50360899999998],[-57.421386999999925,51.480545000000006],[-57.43777499999999,51.46110500000003],[-57.43638599999997,51.45638300000013],[-57.44083399999994,51.44999700000005],[-57.447495,51.447487000000024],[-57.45472000000001,51.445541000000105],[-57.58666199999999,51.42971800000009],[-57.602225999999916,51.42804700000005],[-57.676665999999955,51.42999300000008],[-57.685828999999956,51.43082400000009],[-57.688605999999936,51.4355470000001],[-57.692497,51.45526899999999],[-57.69193999999993,51.46110500000003],[-57.68943799999994,51.46638500000006],[-57.70527599999997,51.46943700000003],[-57.73082699999986,51.47109999999992],[-57.748054999999965,51.47221400000012],[-57.88388800000001,51.392494],[-57.88999899999999,51.388885000000016],[-57.94277199999999,51.35610200000002],[-57.95472000000001,51.34804500000007],[-57.966110000000015,51.338599999999985],[-57.975554999999986,51.328330999999935],[-57.98666400000002,51.31944299999998],[-58.00695000000002,51.31249200000002],[-58.02138499999995,51.30888400000009],[-58.21138799999994,51.27166],[-58.29722599999997,51.26859999999999],[-58.305556999999965,51.26859999999999],[-58.32444800000002,51.272217000000126],[-58.40777600000001,51.295547000000056],[-58.620551999999975,51.277214000000015],[-58.62805199999997,51.275551000000064],[-58.675003000000004,51.25527199999999],[-58.68000000000001,51.25000000000006],[-58.68055699999991,51.24415600000003],[-58.68000000000001,51.234161000000086],[-58.678337,51.22943100000009],[-58.675559999999905,51.224991000000045],[-58.67111199999994,51.22082499999999],[-58.665549999999996,51.216934000000094],[-58.63583399999993,51.19776900000011],[-58.62138399999998,51.19110099999995],[-58.59222399999993,51.18471500000004],[-58.61333499999995,51.15749400000004],[-58.618607,51.153046000000074],[-58.63055400000002,51.14582800000005],[-58.713615000000004,51.10610200000008],[-58.726944,51.09999800000003],[-58.73332999999997,51.09804500000007],[-58.785278000000005,51.08804299999997],[-58.91471899999999,51.05249000000009],[-58.92805499999997,51.048607000000004],[-58.990836999999885,51.0219350000001],[-59.00333399999994,51.01554900000002],[-59.006110999999976,51.00971999999996],[-59.00361600000002,51.0044400000001],[-58.99888599999997,51.00110600000011],[-58.990279999999984,50.998046999999985],[-58.981383999999935,50.99721500000004],[-58.97527299999996,51.000832],[-58.96832999999998,51.002495000000124],[-58.95944199999997,51.00166300000001],[-58.95472000000001,50.99665800000014],[-58.95249899999999,50.99249300000014],[-58.946662999999944,50.83387800000003],[-58.94805100000002,50.82833100000005],[-59.010559,50.754166000000055],[-59.01528200000001,50.748604000000114],[-59.041672000000005,50.75138900000013],[-59.061385999999914,50.75555400000013],[-59.06833599999999,50.759163000000115],[-59.08721899999995,50.77526899999992],[-59.09305599999993,50.78943600000008],[-59.09444400000001,50.799438000000066],[-59.09471899999994,50.81526900000006],[-59.118889000000024,50.80360400000012],[-59.15582999999998,50.77110300000004],[-59.186385999999914,50.74221799999998],[-59.228882,50.73832700000008],[-59.397223999999994,50.65721100000013],[-59.454444999999964,50.621933000000126],[-59.45972399999994,50.61721],[-59.51916499999993,50.552773],[-59.57055699999995,50.493607000000054],[-59.58000199999992,50.48276500000003],[-59.58527400000003,50.47804300000013],[-59.59166700000003,50.47526600000003],[-59.59861000000001,50.47360200000003],[-59.73361199999994,50.44499200000001],[-59.778336000000024,50.438881000000094],[-59.80388599999998,50.438881000000094],[-59.81055500000002,50.437492000000134],[-59.816108999999926,50.433876000000055],[-59.82167099999998,50.42943600000007],[-59.87222299999996,50.38110399999999],[-59.881667999999934,50.371658000000025],[-59.881667999999934,50.36638600000009],[-59.858893999999964,50.329436999999984],[-59.853888999999924,50.32610299999999],[-59.844719,50.324440000000095],[-59.83777599999996,50.32610299999999],[-59.83472399999988,50.338043000000084],[-59.83499899999998,50.343323],[-59.830832999999984,50.34943400000009],[-59.82472200000001,50.35166200000003],[-59.81500199999999,50.34915900000004],[-59.813331999999946,50.344154],[-59.81722300000001,50.33277099999998],[-59.82749899999999,50.32360799999998],[-59.83388500000001,50.31916000000001],[-59.86028299999998,50.31054700000004],[-59.90527300000002,50.29110700000007],[-60.00500499999998,50.248878000000104],[-60.11444899999992,50.23304699999994],[-60.14778100000001,50.2741620000001],[-60.18444099999999,50.27971600000012],[-60.23694599999999,50.268051000000014],[-60.29167199999995,50.245270000000005],[-60.29861499999993,50.24332400000014],[-60.32444799999996,50.244713000000104],[-60.36000100000001,50.250831999999946],[-60.40444200000002,50.251389000000074],[-60.45889299999999,50.25110600000011],[-60.48332999999991,50.250831999999946],[-60.491668999999945,50.25054899999998],[-60.498610999999926,50.248604],[-60.51167299999997,50.24249300000014],[-60.52222399999988,50.23471800000004],[-60.52694699999995,50.2291560000001],[-60.58361100000002,50.208327999999995],[-60.59166699999997,50.20804600000014],[-60.67444599999999,50.219986000000006],[-60.710556,50.2227630000001],[-60.838607999999965,50.214995999999985],[-61.05222299999997,50.21554600000002],[-61.289443999999946,50.199158000000125],[-61.427779999999984,50.171379000000115],[-61.50556199999994,50.152489],[-61.583610999999905,50.13249200000013],[-61.65083299999992,50.109993000000145],[-61.720832999999914,50.09193400000004],[-61.73161299999998,50.10193600000002],[-61.742106999999976,50.10527000000002],[-61.74627700000002,50.10726900000003],[-61.74828000000002,50.10994000000005],[-61.71210499999995,50.12226899999996],[-61.70378099999999,50.12477100000007],[-61.69944399999997,50.125435000000095],[-61.69444299999992,50.125435000000095],[-61.67138699999998,50.136940000000095],[-61.62055199999992,50.147491],[-61.593055999999876,50.1552660000001],[-61.57972699999999,50.16082000000006],[-61.574447999999904,50.16554300000007],[-61.57194500000003,50.17166100000003],[-61.573891,50.18166400000007],[-61.577225,50.18610400000006],[-61.58916499999998,50.18888099999998],[-61.59361299999995,50.185546999999985],[-61.602225999999916,50.174438000000066],[-61.60777999999999,50.17082999999997],[-61.62222299999996,50.16610000000014],[-61.731833999999935,50.144268000000125],[-61.746997999999905,50.144431999999995],[-61.75750399999998,50.14527099999998],[-61.76183299999997,50.14726999999999],[-61.76366399999995,50.14976899999999],[-61.76299999999998,50.15327100000002],[-61.76066599999996,50.15709700000008],[-61.794448999999986,50.1594310000001],[-61.79527999999999,50.16999100000004],[-61.79695099999998,50.17471300000011],[-61.80444299999999,50.18332699999996],[-61.848884999999996,50.22248800000011],[-61.864723000000026,50.228600000000085],[-61.898338000000024,50.23360400000007],[-61.90721899999994,50.23416099999997],[-61.96333299999998,50.236107000000004],[-61.97721899999999,50.23193400000008],[-61.989723000000026,50.22637900000001],[-61.996666000000005,50.224158999999986],[-62.00417299999992,50.22304500000001],[-62.20249899999999,50.23443600000013],[-62.26889,50.25972000000013],[-62.31777999999997,50.28138000000013],[-62.328056000000004,50.283882000000006],[-62.39749899999998,50.29444100000006],[-62.40416700000003,50.29222100000004],[-62.41554999999994,50.28472099999999],[-62.42556000000002,50.27526900000004],[-62.42999999999995,50.269714000000135],[-62.43999499999995,50.260551000000135],[-62.446105999999986,50.25750000000011],[-62.57222699999994,50.274712000000136],[-62.74694799999992,50.28472099999999],[-63.11250299999995,50.29138200000011],[-63.15833299999997,50.26027700000003],[-63.159163999999976,50.25471500000009],[-63.22860700000001,50.23471800000004],[-63.23666399999996,50.23443600000013],[-63.37194099999999,50.23665599999998],[-63.46944399999995,50.25721699999997],[-63.565552000000025,50.26415999999995],[-63.61666099999991,50.26666300000011],[-63.64972699999993,50.27276600000005],[-63.687499999999886,50.2824940000001],[-63.693885999999964,50.29193900000001],[-63.69860799999998,50.29527299999995],[-63.70750399999997,50.29777500000006],[-63.803328999999906,50.311661000000015],[-63.82138800000001,50.31220999999999],[-63.97610499999996,50.30554999999998],[-64.06723,50.29222100000004],[-64.12777699999992,50.27193500000004],[-64.14056399999993,50.26693700000004],[-64.15417500000001,50.26249700000005],[-64.16221599999994,50.26221499999997],[-64.21528599999994,50.2649990000001],[-64.23472600000002,50.26693700000004],[-64.262787,50.271660000000054],[-64.36527999999998,50.29222100000004],[-64.37388599999997,50.294998000000135],[-64.402222,50.30749500000013],[-64.41777000000002,50.31304899999992],[-64.43666100000002,50.317772000000105],[-64.44610599999999,50.31916000000001],[-64.45500199999992,50.31944299999998],[-64.46305799999999,50.31916000000001],[-64.47083999999995,50.317772000000105],[-64.51000999999997,50.30304699999999],[-64.61193800000001,50.28138000000013],[-64.62805200000003,50.279160000000104],[-64.65943899999996,50.277214000000015],[-64.72500600000001,50.27443699999998],[-64.89999399999994,50.27082800000011],[-65.18055700000002,50.28555300000005],[-65.18998699999992,50.2866590000001],[-65.22277799999995,50.29777500000006],[-65.237503,50.30387900000005],[-65.24249299999985,50.30776999999995],[-65.27500900000001,50.30804400000005],[-65.464447,50.29943799999995],[-65.48666399999996,50.29527299999995],[-65.52166699999998,50.285828000000095],[-65.58999599999999,50.27526900000004],[-65.69055200000003,50.261108000000036],[-65.747772,50.256943000000035],[-65.829453,50.25332600000007],[-65.84583999999995,50.25888800000001],[-65.864441,50.26888300000013],[-65.87638900000002,50.276382000000126],[-65.89805599999988,50.28499599999998],[-65.91805999999997,50.28832999999997],[-65.95249899999993,50.288887000000045],[-65.97416699999997,50.283882000000006],[-65.9869379999999,50.278328000000045],[-65.99305700000002,50.27526900000004],[-66.0041809999999,50.26832600000006],[-66.02471899999995,50.251389000000074],[-66.04333499999996,50.22221400000001],[-66.083328,50.19360399999994],[-66.08972199999988,50.19137599999999],[-66.16332999999997,50.197212000000036],[-66.31416300000001,50.20971700000001],[-66.40638699999994,50.23998999999998],[-66.40695199999999,50.245270000000005],[-66.41221599999994,50.260551000000135],[-66.416946,50.26444200000003],[-66.42304999999993,50.26776899999999],[-66.43331899999998,50.269714000000135],[-66.44166599999994,50.269157000000064],[-66.45639,50.26638800000012],[-66.46972700000003,50.26193999999998],[-66.49472000000003,50.249435000000005],[-66.51194800000002,50.23915899999997],[-66.70083599999992,50.102493000000095],[-66.72332799999992,50.07833100000005],[-66.8619379999999,50.022491000000116],[-66.88249200000001,50.016662999999994],[-66.896118,50.01194000000004],[-66.92027300000001,50.0002750000001],[-66.9424899999999,49.985825000000034],[-66.95861799999994,49.974709000000075],[-66.96362299999998,49.969154],[-66.96639999999996,49.96332600000005],[-66.975281,49.94360399999999],[-66.97582999999997,49.937767000000065],[-66.96556099999992,49.91944100000006],[-66.96333299999998,49.91471100000001],[-67.01640299999985,49.85471299999995],[-67.06138599999986,49.84137700000002],[-67.06527699999992,49.84554300000008],[-67.07389799999993,49.84804500000001],[-67.0958399999999,49.84360500000014],[-67.11582900000002,49.83665500000012],[-67.12165800000002,49.833327999999995],[-67.13722200000001,49.82138100000003],[-67.14666699999998,49.812492000000134],[-67.15139799999992,49.806937999999946],[-67.162216,49.79055000000011],[-67.17416400000002,49.76471700000013],[-67.23889200000002,49.590546000000074],[-67.24082899999996,49.57888000000008],[-67.241379,49.56749700000006],[-67.24082899999996,49.556655999999975],[-67.23999000000003,49.55165900000003],[-67.23500099999995,49.53555300000005],[-67.228882,49.51027700000003],[-67.22917199999995,49.48304700000011],[-67.23083499999996,49.47693600000002],[-67.23388699999998,49.47026800000009],[-67.36915599999998,49.33277100000004],[-67.375,49.32721700000002],[-67.386124,49.32222000000007],[-67.40278599999988,49.3211060000001],[-67.42027300000001,49.321663],[-67.43859900000001,49.324440000000095],[-67.47361799999999,49.32666000000012],[-67.56973299999999,49.32999400000011],[-67.57749899999999,49.32916300000011],[-67.70639,49.312767000000065],[-67.93916300000001,49.28777300000013],[-67.975281,49.284996000000035],[-68.11972000000003,49.271660000000054],[-68.12721299999998,49.26944000000003],[-68.13194299999992,49.26610600000009],[-68.13639799999993,49.260550999999964],[-68.13890099999992,49.25471500000009],[-68.14056399999993,49.24860400000006],[-68.14388999999989,49.23054500000012],[-68.18083200000001,49.12193300000007],[-68.1849979999999,49.116104000000064],[-68.18971299999993,49.112213],[-68.19499200000001,49.10833000000008],[-68.20111099999991,49.105552999999986],[-68.22166399999998,49.10027300000007],[-68.36944599999998,49.069443000000035],[-68.44248999999996,49.09554300000008],[-68.571396,49.061104],[-68.59056099999998,49.05416100000002],[-68.60694899999993,49.04249600000014],[-68.62609900000001,49.02388000000013],[-68.69638099999997,48.93998700000009],[-68.876938,48.85193600000008],[-69.047775,48.773048000000074],[-69.06082200000003,48.767494000000056],[-69.064438,48.762496999999996],[-69.08473200000003,48.72165700000005],[-69.0894469999999,48.70943500000004],[-69.09361299999995,48.691933000000006],[-69.09611499999994,48.67499500000014],[-69.0994419999999,48.66332200000011],[-69.10610999999994,48.64499699999999],[-69.1119379999999,48.63249200000007],[-69.12388599999991,48.6147160000001],[-69.14250199999992,48.59499400000004],[-69.14805599999994,48.591102999999976],[-69.15972899999997,48.58526599999999],[-69.16639700000002,48.58332800000005],[-69.18415800000002,48.58471700000007],[-69.20167500000002,48.588599999999985],[-69.21861299999995,48.58971399999996],[-69.22666900000002,48.58888200000007],[-69.23138399999993,48.585548000000074],[-69.23638899999992,48.58110800000003],[-69.26528899999994,48.54166399999997],[-69.27944899999994,48.51583100000005],[-69.28277600000001,48.50416600000011],[-69.28332499999993,48.49304999999998],[-69.28250099999997,48.48249099999998],[-69.29277000000002,48.45777100000009],[-69.30110200000001,48.446655000000135],[-69.43276999999995,48.307770000000005],[-69.43777499999999,48.30304700000005],[-69.45472699999999,48.29193900000001],[-69.59777799999995,48.207497000000046],[-69.672775,48.14388300000013],[-69.68388400000003,48.13777200000004],[-69.69137599999999,48.137496999999996],[-69.80082699999997,48.15360300000003],[-69.81027199999994,48.155823],[-69.73472599999997,48.113609000000054],[-69.73028599999998,48.10943600000013],[-69.73249800000002,48.103607000000125],[-69.78639199999986,47.99471300000005],[-69.839447,47.90721099999996],[-69.92582700000003,47.773048000000074],[-69.93582200000003,47.764441999999974],[-70.00222799999995,47.71193699999998],[-70.01556399999998,47.70277399999998],[-70.07194500000003,47.674713000000054],[-70.07749899999999,47.67249300000009],[-70.09110999999996,47.66915900000009],[-70.132767,47.64499699999999],[-70.17999299999997,47.608330000000024],[-70.19027699999992,47.59915900000004],[-70.20249899999999,47.58305399999995],[-70.20611600000001,47.57666000000012],[-70.2083439999999,47.57054900000003],[-70.20944199999997,47.55387900000011],[-70.20750399999991,47.533051],[-70.208618,47.52721400000007],[-70.21722399999993,47.508331],[-70.22555499999993,47.496384000000035],[-70.2308349999999,47.49249300000014],[-70.29972799999996,47.466933999999924],[-70.34167499999995,47.46054800000002],[-70.4619449999999,47.429993000000024],[-70.50250199999999,47.39083099999999],[-70.55583199999995,47.32276900000011],[-70.56639100000001,47.30416100000002],[-70.56861899999996,47.29804999999993],[-70.57112099999995,47.28110499999997],[-70.57417299999997,47.274437000000034],[-70.58612099999999,47.25777399999993],[-70.69943199999994,47.12609900000001],[-70.72166400000003,47.1013870000001],[-70.73306300000002,47.095543000000134],[-70.79249600000003,47.06832900000012],[-70.81750499999993,47.058884000000035],[-70.82362399999994,47.056938],[-70.86694299999994,47.051383999999985],[-70.89334100000002,47.045273000000066],[-70.92304999999993,47.032211000000075],[-70.97361799999999,47.003326000000015],[-71.11361699999986,46.912491000000045],[-71.18249500000002,46.86415899999997],[-71.197495,46.85249300000004],[-71.19860799999998,46.84638200000012],[-71.29916400000002,46.74221800000009],[-71.291946,46.74415600000003],[-71.27972399999993,46.74916100000007],[-71.20944199999997,46.7824940000001],[-71.19888299999991,46.788887000000045],[-71.18888899999996,46.79666100000003],[-71.18443299999996,46.80277300000006],[-71.17832900000002,46.815269000000114],[-71.1663969999999,46.83110800000003],[-71.15611299999995,46.83888200000007],[-71.14999399999994,46.84249100000005],[-71.14361599999995,46.844711000000075],[-71.13055400000002,46.847488],[-71.11527999999998,46.84887700000013],[-71.100281,46.84887700000013],[-71.083328,46.847488],[-70.98693799999995,46.85416400000008],[-70.77223200000003,46.91582500000004],[-70.76640299999991,46.91888400000005],[-70.75500499999998,46.93665299999998],[-70.74444599999993,46.94332099999991],[-70.73750299999995,46.946098000000006],[-70.63806199999999,46.98165899999998],[-70.61888099999993,46.98804500000006],[-70.60499600000003,46.99027300000006],[-70.57501200000002,46.99332400000009],[-70.55332899999996,46.99804700000004],[-70.54138199999994,47.00249500000001],[-70.53028899999993,47.00777399999998],[-70.506958,47.02027099999998],[-70.48638900000003,47.03360700000013],[-70.46112099999993,47.05360400000001],[-70.33416699999992,47.15554800000001],[-70.31027199999994,47.176659000000086],[-70.273056,47.213608000000136],[-70.11111499999998,47.34054600000013],[-70.078888,47.36110699999995],[-70.04888899999997,47.38610799999998],[-70.04415899999992,47.39083099999999],[-70.04083300000002,47.39721700000007],[-70.03999299999987,47.40277100000009],[-69.96749899999998,47.50582900000006],[-69.90194699999995,47.537216],[-69.89639299999993,47.54110700000007],[-69.80583200000001,47.613052000000096],[-69.65943900000002,47.744713000000104],[-69.63999899999988,47.76277200000004],[-69.59306300000003,47.80888400000009],[-69.55665599999986,47.85638400000005],[-69.55638099999993,47.86666100000002],[-69.54415899999998,47.883605999999986],[-69.52667200000002,47.90415999999999],[-69.50805700000001,47.92443800000001],[-69.49888599999986,47.933876],[-69.46972700000003,47.96193700000009],[-69.45056199999999,47.97915599999999],[-69.429169,47.99527000000012],[-69.41833500000001,48.00138900000013],[-69.41166699999997,48.003326000000015],[-69.27528399999994,48.06777200000005],[-69.11610399999995,48.178604000000064],[-69.10194399999995,48.192764000000125],[-69.08666999999997,48.204994000000056],[-69.05416899999989,48.22860000000014],[-69.01640299999997,48.254166],[-68.968613,48.279990999999995],[-68.94055200000003,48.29499800000002],[-68.83167999999989,48.34471100000013],[-68.695267,48.39638500000012],[-68.541382,48.451385000000016],[-68.52944899999994,48.45721400000002],[-68.51916499999999,48.464157],[-68.51306199999988,48.469437000000084],[-68.49694799999992,48.490273000000116],[-68.47389199999998,48.515549000000135],[-68.46916199999987,48.52027100000004],[-68.45361300000002,48.5324940000001],[-68.43443300000001,48.54166399999997],[-68.42250100000001,48.54527299999995],[-68.40777600000001,48.548050000000046],[-68.37582399999985,48.546386999999925],[-68.368607,48.547493000000145],[-68.354446,48.55138400000004],[-68.34834299999989,48.554161000000136],[-68.33667000000003,48.561661000000015],[-68.28332499999999,48.600273000000016],[-68.23693799999995,48.625549000000035],[-68.21112099999993,48.636658000000125],[-68.19332899999989,48.64305100000007],[-68.17916899999994,48.64666000000011],[-68.15695199999999,48.64916199999999],[-68.12554899999998,48.648330999999985],[-68.11193800000001,48.65138200000001],[-67.97361799999999,48.695541000000105],[-67.70944199999985,48.793884000000105],[-67.531387,48.85916099999997],[-67.20973200000003,48.93582200000009],[-67.087784,48.96082300000012],[-67.06750499999998,48.96693399999998],[-67.01583899999997,48.98693800000012],[-66.991669,48.99916099999996],[-66.96083099999998,49.01194000000004],[-66.922775,49.02665700000006],[-66.91639700000002,49.02887700000002],[-66.72250399999996,49.08998900000006],[-66.42166099999992,49.162765999999976],[-66.306107,49.18693500000012],[-66.22500599999995,49.200829000000056],[-66.08917200000002,49.218597000000045],[-66.07417299999997,49.21971100000002],[-65.83250399999991,49.23137700000001],[-65.67832899999996,49.245543999999995],[-65.49694799999997,49.261664999999994],[-65.44721999999996,49.262215000000026],[-65.394455,49.25971999999996],[-65.35972600000002,49.256660000000124],[-64.99694799999992,49.22026799999992],[-64.91665599999999,49.20665699999995],[-64.82556199999993,49.18776700000001],[-64.80583199999995,49.18332700000002],[-64.79527300000001,49.17610200000013],[-64.79194599999994,49.17166100000003],[-64.77471899999995,49.159988],[-64.76333599999992,49.15416000000005],[-64.74888599999991,49.148048000000074],[-64.73194899999999,49.14222000000001],[-64.66082799999987,49.12304700000004],[-64.64111299999996,49.11888099999999],[-64.60665899999992,49.117210000000114],[-64.58805799999999,49.112213],[-64.37638899999996,48.997772],[-64.23554999999999,48.91027100000002],[-64.22166399999998,48.8983310000001],[-64.21444699999995,48.88943499999999],[-64.20889299999999,48.880547000000035],[-64.15222199999994,48.764999000000046],[-64.15249599999999,48.75999500000012],[-64.15805099999994,48.75610400000005],[-64.16776999999996,48.758331000000055],[-64.20889299999999,48.782767999999976],[-64.21333299999998,48.78665900000004],[-64.22999599999997,48.79749300000009],[-64.24415599999998,48.80360400000001],[-64.29028299999993,48.82110600000004],[-64.29888900000003,48.82388300000014],[-64.31555200000003,48.82888000000003],[-64.37721299999993,48.84638200000006],[-64.39584400000001,48.851105000000075],[-64.51222200000001,48.87471000000005],[-64.53056299999992,48.87721300000004],[-64.54888899999992,48.87832600000007],[-64.54333500000001,48.873604],[-64.53277599999996,48.86693600000007],[-64.464447,48.82444000000004],[-64.37416100000002,48.787773000000016],[-64.266663,48.71332600000011],[-64.256958,48.70609999999999],[-64.17304999999993,48.63943500000005],[-64.16194200000001,48.62748700000003],[-64.16000400000001,48.62276500000013],[-64.166946,48.62137600000011],[-64.19305399999996,48.62360400000006],[-64.24110399999995,48.6222150000001],[-64.25500499999993,48.61859900000002],[-64.26083399999987,48.61582899999996],[-64.265289,48.610825000000034],[-64.26972999999998,48.60471300000006],[-64.27471899999995,48.5927660000001],[-64.28056300000003,48.575271999999984],[-64.28250099999991,48.56916000000001],[-64.28332499999988,48.56360599999999],[-64.27917499999995,48.554161000000136],[-64.27333099999993,48.55054500000006],[-64.26417499999991,48.54916400000002],[-64.245834,48.546661000000086],[-64.21916199999998,48.52832799999999],[-64.24638400000003,48.48804499999994],[-64.32250999999985,48.43721000000011],[-64.42639200000002,48.40416000000005],[-64.49305700000002,48.394440000000145],[-64.50666799999999,48.39166300000005],[-64.58694500000001,48.36832400000003],[-64.68638599999997,48.33832600000011],[-64.73138399999988,48.27471200000002],[-64.75029,48.24582700000013],[-64.75389099999995,48.23998999999998],[-64.760559,48.227211000000125],[-64.76806599999998,48.20277400000003],[-64.77139299999999,48.19638100000009],[-64.77861000000001,48.19499200000007],[-64.87332200000003,48.180550000000096],[-64.931671,48.17166100000003],[-64.97250399999996,48.13526900000005],[-65.15306099999998,48.052216000000044],[-65.19665499999996,48.033607000000075],[-65.202789,48.03138000000001],[-65.27000399999997,48.012771999999984],[-65.30583200000001,48.00555400000013],[-65.32695000000001,48.002220000000136],[-65.45556599999998,48.00027499999999],[-65.46389799999997,48.00277700000004],[-65.472778,48.01138300000014],[-65.47860700000001,48.01971400000008],[-65.48472600000002,48.03388200000012],[-65.491104,48.04249600000014],[-65.50418100000002,48.04888200000005],[-65.68916299999995,48.093879999999956],[-65.7644499999999,48.10999300000003],[-65.88890099999992,48.19915800000001],[-65.90417500000001,48.205826],[-65.94999699999994,48.191101],[-65.95639,48.18888100000004],[-66.006958,48.15915699999999],[-66.02471899999995,48.13916000000012],[-66.12971499999992,48.10721600000011],[-66.24276700000001,48.109161000000086],[-66.39639299999993,48.11499800000007],[-66.40638699999994,48.11638599999998],[-66.43249500000002,48.11859900000013],[-66.47084000000001,48.11943800000006],[-66.47778299999999,48.11804999999998],[-66.48416099999997,48.11554699999999],[-66.495544,48.10943600000013],[-66.50639299999995,48.10221899999999],[-66.52555799999999,48.08554800000002],[-66.52999899999992,48.08055100000007],[-66.66722099999998,48.0283280000001],[-66.67361499999998,48.026099999999985],[-66.76371799999998,48.00622599999997],[-66.84370399999995,47.996650999999986],[-66.84249899999998,47.99221800000004],[-66.83666999999997,47.98888400000004],[-66.828888,47.98721299999994],[-66.74999999999994,47.979988000000105],[-66.72888199999994,47.98443600000007],[-66.61082499999998,48.01110799999998],[-66.58473199999997,48.019440000000145],[-66.57333399999999,48.02582600000005],[-66.54055800000003,48.03638500000011],[-66.43443300000001,48.067497],[-66.42027300000001,48.070549000000085],[-66.36416599999995,48.07332600000001],[-66.35665899999992,48.07332600000001],[-66.35082999999992,48.069717000000026],[-66.34999099999993,48.06471300000004],[-66.25917099999998,47.99943500000012],[-66.04222099999998,47.93582200000009],[-65.98889200000002,47.92388199999999],[-65.97027600000001,47.92083000000008],[-65.936935,47.92083000000008],[-65.92222599999997,47.92276800000002],[-65.90695199999999,47.92332500000009],[-65.88027999999991,47.92054700000011],[-65.843887,47.91137700000007],[-65.81861900000001,47.90387700000002],[-65.81138599999991,47.900825999999995],[-65.79360999999994,47.89083100000005],[-65.77278099999995,47.876380999999924],[-65.75750699999998,47.865273000000116],[-65.74638399999998,47.85277599999995],[-65.7250059999999,47.82749199999995],[-65.718613,47.81888600000008],[-65.714447,47.80943300000001],[-65.71362299999998,47.80416100000008],[-65.69694499999997,47.73304700000011],[-65.67193600000002,47.64582800000005],[-65.66777000000002,47.64138000000008],[-65.63473499999998,47.62082700000002],[-65.62832600000002,47.623046999999985],[-65.38999899999999,47.736107000000004],[-65.33277900000002,47.76693700000004],[-65.25389099999995,47.80165900000003],[-65.24082900000002,47.806655999999975],[-65.202789,47.81860399999999],[-65.16749600000003,47.825271999999984],[-65.04472399999997,47.844436999999914],[-65.02084400000001,47.844993999999986],[-64.98500099999995,47.84137700000008],[-64.81555200000003,47.811104000000114],[-64.80555700000002,47.80888400000009],[-64.79722600000002,47.8063810000001],[-64.71916199999998,47.764441999999974],[-64.71333299999998,47.761108000000036],[-64.67666599999995,47.7355500000001],[-64.67027300000001,47.72693600000002],[-64.67332499999992,47.72026800000003],[-64.67944299999999,47.71665999999993],[-64.7036129999999,47.70694000000003],[-64.80332899999996,47.63054700000009],[-64.85972599999997,47.57666000000012],[-64.870094,47.53629300000006],[-64.87110899999999,47.51583100000005],[-64.87027,47.51082600000001],[-64.87554899999998,47.46082300000006],[-64.88082899999995,47.432495000000074],[-64.88639799999999,47.41415400000005],[-64.91000400000001,47.353049999999996],[-65.13806199999999,47.19221500000003],[-65.226944,47.14083100000005],[-65.23832700000003,47.13472000000013],[-65.26333599999992,47.124435000000005],[-65.33972199999994,47.099433999999974],[-65.36416599999995,47.08971400000007],[-65.3699949999999,47.08665500000012],[-65.36527999999987,47.08277100000009],[-65.21888699999988,47.05360400000001],[-65.10110500000002,47.07694200000009],[-65.01722699999993,47.09137700000002],[-64.80555700000002,47.08305400000006],[-64.79861499999993,47.079994],[-64.80277999999993,46.993049999999926],[-64.80332899999996,46.987495000000024],[-64.80722000000003,46.98165899999998],[-64.81221,46.97776800000008],[-64.81806899999992,46.9741590000001],[-64.83583099999998,46.96582799999999],[-64.85722399999997,46.95277399999992],[-64.87193300000001,46.939430000000016],[-64.88027999999991,46.93054999999998],[-64.89222699999999,46.91443600000008],[-64.89611799999994,46.90888200000006],[-64.89916999999997,46.90248900000012],[-64.90499899999998,46.88360600000004],[-64.906387,46.872490000000084],[-64.90499899999998,46.85110500000013],[-64.9036099999999,46.84082799999993],[-64.87721299999998,46.79110700000007],[-64.86389199999996,46.77443699999992],[-64.81806899999992,46.72165700000005],[-64.74861099999998,46.70277399999998],[-64.74027999999998,46.70249200000012],[-64.72639499999991,46.69638100000003],[-64.72084000000001,46.693047000000035],[-64.71333299999998,46.68415800000014],[-64.71112099999999,46.67999300000014],[-64.70861799999994,46.66999100000004],[-64.70500199999998,46.638329000000056],[-64.67332499999992,46.500832],[-64.66194200000001,46.468048000000124],[-64.65083300000003,46.460548000000074],[-64.62193300000001,46.4272160000001],[-64.61361699999998,46.41443599999997],[-64.61193800000001,46.409714000000065],[-64.615005,46.39249400000011],[-64.61305199999998,46.366104000000064],[-64.50418100000002,46.240273],[-64.402222,46.233047000000056],[-64.237503,46.22915599999999],[-64.11694299999994,46.18193800000006],[-64.035553,46.182213000000104],[-63.970832999999914,46.18054999999998],[-63.954444999999964,46.17804699999999],[-63.83028399999995,46.146385000000066],[-63.822227,46.14388299999996],[-63.776389999999935,46.12110100000007],[-63.77305599999994,46.11749300000014],[-63.77111100000002,46.112769999999955],[-63.77249899999987,46.108047],[-63.77694700000001,46.1033250000001],[-63.78305799999998,46.09971600000006],[-63.79944599999999,46.09137700000002],[-63.80555700000002,46.08915700000006],[-63.886391,46.06082200000003],[-63.89250199999992,46.05888400000009],[-63.91944899999993,46.053047000000106],[-63.92694899999992,46.052490000000034],[-63.988609,46.05193300000013],[-64.02333099999998,46.057495000000074],[-64.06806899999998,46.05943300000001],[-64.07250999999997,46.05471000000006],[-64.093887,46.02166],[-64.06500199999988,46.00471500000003],[-64.04278599999998,45.99189800000005],[-64.01251200000002,46.005829000000006],[-64.00527999999991,46.00555400000002],[-63.913054999999986,45.979987999999935],[-63.86416600000001,45.96110500000003],[-63.859443999999996,45.95193499999999],[-63.86138900000003,45.94582400000013],[-63.84610699999996,45.93082400000014],[-63.714721999999995,45.840546000000074],[-63.66999800000002,45.81805400000002],[-63.664161999999976,45.815268999999944],[-63.64583600000003,45.83332800000005],[-63.63166799999999,45.85943600000002],[-63.600280999999995,45.869986999999924],[-63.58055899999994,45.87443500000012],[-63.48249800000002,45.8772130000001],[-63.474441999999954,45.87693800000005],[-63.45722199999989,45.87416099999996],[-63.420279999999934,45.86499799999996],[-63.406661999999926,45.858887000000095],[-63.403884999999946,45.85443900000013],[-63.42861199999993,45.82360799999998],[-63.434440999999936,45.82083100000011],[-63.441108999999926,45.81944299999998],[-63.45610799999997,45.81888600000008],[-63.488051999999925,45.82083100000011],[-63.51333599999998,45.82416500000005],[-63.520835999999974,45.82388300000002],[-63.52583299999998,45.81999200000013],[-63.52666499999998,45.81443800000011],[-63.5236129999999,45.80998999999997],[-63.515556000000004,45.80721300000005],[-63.50695000000002,45.80582400000009],[-63.43360899999993,45.79943800000001],[-63.42556000000002,45.799164000000076],[-63.34332999999998,45.797492999999974],[-63.32833899999997,45.79833200000013],[-63.28722399999998,45.80554999999998],[-63.281113000000005,45.80776999999995],[-63.27417000000003,45.80888399999998],[-63.25111399999997,45.80971499999998],[-63.235000999999954,45.80860100000001],[-63.22943900000001,45.80499300000008],[-63.23332999999997,45.79943800000001],[-63.23889200000002,45.79638699999998],[-63.31388900000002,45.76944000000003],[-63.319725000000005,45.76805100000007],[-63.35583500000001,45.76444200000003],[-63.372222999999906,45.76638800000012],[-63.379997,45.766106000000036],[-63.38194299999998,45.759995],[-63.37666300000001,45.75582900000006],[-63.361114999999984,45.74554399999994],[-63.35444599999994,45.74249300000014],[-63.31361400000003,45.736938000000066],[-63.282501000000025,45.73333000000014],[-63.189719999999966,45.73443600000013],[-63.120833999999945,45.7594380000001],[-63.09055299999994,45.79027600000006],[-63.082779000000016,45.80332199999998],[-62.99388899999997,45.79638699999998],[-62.985275,45.794998000000135],[-62.95833600000003,45.788887000000045],[-62.72361000000001,45.764160000000004],[-62.677779999999984,45.764160000000004],[-62.55722000000003,45.67471300000011],[-62.50389099999995,45.62748700000009],[-62.46194499999996,45.61249500000008],[-62.25028199999991,45.708327999999995],[-62.092772999999966,45.78110500000014],[-62.03500399999996,45.82083100000011],[-62.01500699999991,45.83665500000001],[-61.97332799999998,45.86721000000006],[-61.93138899999997,45.884720000000016],[-61.92555999999996,45.88610799999992],[-61.91750300000001,45.88555100000002],[-61.903052999999886,45.87943300000012],[-61.89805599999994,45.87526700000001],[-61.89611099999996,45.871101000000124],[-61.89805599999994,45.865273],[-61.90332799999999,45.861382000000106],[-61.914718999999934,45.8555530000001],[-61.919448999999986,45.85110500000013],[-61.923332000000016,45.84554300000002],[-61.92555999999996,45.8394320000001],[-61.92527799999999,45.834434999999985],[-61.88999899999999,45.701385000000016],[-61.88555899999989,45.6905440000001],[-61.88138600000002,45.686653000000035],[-61.79222899999991,45.63916000000012],[-61.78333299999997,45.63665800000001],[-61.7350009999999,45.62332200000009],[-61.72499800000003,45.62082700000002],[-61.618056999999965,45.610550000000046],[-61.603888999999924,45.63526900000005],[-61.569999999999936,45.66999100000004],[-61.565001999999936,45.673882000000106],[-61.55916599999995,45.67665900000003],[-61.546111999999994,45.681107],[-61.526107999999965,45.68526500000013],[-61.50444799999997,45.68693500000006],[-61.48889200000002,45.68693500000006],[-61.471382000000006,45.682495000000074],[-61.466110000000015,45.678878999999995],[-61.39639299999993,45.62665600000008],[-61.38694799999996,45.61888099999999],[-61.35342799999995,45.56971400000009],[-61.316146999999944,45.53317300000003],[-61.26000199999993,45.51027700000009],[-61.23235699999998,45.46119299999998],[-61.294167000000016,45.434714999999926],[-61.36500499999994,45.404160000000104],[-61.36805700000002,45.41387900000012],[-61.37471799999997,45.41693899999996],[-61.38861099999991,45.41415400000011],[-61.40083299999998,45.410820000000115],[-61.41332999999997,45.40693700000003],[-61.462219000000005,45.384438000000046],[-61.477492999999924,45.3730470000001],[-61.48166699999996,45.367767000000015],[-61.478882,45.36332700000003],[-61.46388999999999,45.346939000000134],[-61.457222,45.34360500000014],[-61.22638699999993,45.34415400000012],[-61.153327999999874,45.34832799999998],[-61.139441999999974,45.34887700000007],[-61.13166799999999,45.34832799999998],[-61.04722599999997,45.33554800000002],[-60.99639100000002,45.32749200000012],[-60.980552999999986,45.32444000000004],[-60.970551,45.321663000000115],[-60.966110000000015,45.31832900000012],[-60.964721999999995,45.313049000000035],[-60.96527900000001,45.295547],[-60.97027600000001,45.26971400000008],[-61.05083499999989,45.23110200000008],[-61.0777819999999,45.21943700000003],[-61.09027899999995,45.21554600000013],[-61.10972600000002,45.21082300000012],[-61.12332900000001,45.208602999999925],[-61.13972499999994,45.21082300000012],[-61.14222699999999,45.21527100000009],[-61.222220999999934,45.23832700000014],[-61.26750199999998,45.24638400000009],[-61.3130569999999,45.24276699999996],[-61.323890999999946,45.23610700000012],[-61.360000999999954,45.20999100000006],[-61.373610999999926,45.196380999999974],[-61.373328999999956,45.19110100000012],[-61.36555499999997,45.18832400000002],[-61.34972399999998,45.186935000000005],[-61.340836000000024,45.184433000000126],[-61.34416199999987,45.17804700000005],[-61.34944200000001,45.17443800000001],[-61.355002999999954,45.171660999999915],[-61.38444500000003,45.15915700000005],[-61.39749899999998,45.156097000000045],[-61.450835999999924,45.14554600000008],[-61.45861100000002,45.14471400000002],[-61.54389199999997,45.141662999999994],[-61.638053999999954,45.12027000000006],[-61.724715999999944,45.09166000000005],[-61.898338000000024,45.02499399999999],[-62.02666499999992,44.98471799999999],[-62.08777599999996,44.97026800000009],[-62.28639199999992,44.92804700000005],[-62.391944999999964,44.90832500000005],[-62.476386999999875,44.89554600000014],[-62.521942000000024,44.85082999999997],[-62.54611199999994,44.821663],[-62.641388000000006,44.80915800000008],[-62.79500599999989,44.78054800000007],[-62.801109,44.77860300000009],[-62.81388899999996,44.750832],[-62.80999800000001,44.73471800000004],[-62.851111999999944,44.71832300000011],[-62.92861199999987,44.733879000000115],[-63.01277900000002,44.773323000000005],[-63.020554000000004,44.77388000000008],[-63.05555700000002,44.772766000000104],[-63.0625,44.77137800000003],[-63.06194299999993,44.76638800000012],[-63.06027999999998,44.761664999999994],[-63.057503,44.757217000000026],[-63.04361699999993,44.73998999999998],[-63.017776000000026,44.72248800000011],[-63.01250499999992,44.71332600000005],[-63.01194800000002,44.70804600000014],[-63.01361800000001,44.70277400000003],[-63.01833299999993,44.69748700000008],[-63.048339999999996,44.67610200000013],[-63.05471799999998,44.673325000000034],[-63.104445999999996,44.74665800000014],[-63.11527999999987,44.73137700000001],[-63.11833199999995,44.7249910000001],[-63.13833599999998,44.69304700000009],[-63.142776000000026,44.688599000000124],[-63.283057999999926,44.62721299999998],[-63.43999499999995,44.590828000000045],[-63.44888300000002,44.59304800000007],[-63.49500299999994,44.61471599999999],[-63.526336999999955,44.63610099999994],[-63.535168,44.6427690000001],[-63.545334000000025,44.65210700000006],[-63.55699900000002,44.66160600000012],[-63.61583699999994,44.70249199999995],[-63.635001999999986,44.71138000000013],[-63.64277599999991,44.71415700000006],[-63.651107999999965,44.71554600000002],[-63.65833299999997,44.714995999999985],[-63.660552999999936,44.70832800000005],[-63.64944499999996,44.686104000000114],[-63.640556000000004,44.673050000000046],[-63.635559,44.668884000000105],[-63.627776999999924,44.666382000000056],[-63.60611,44.668884000000105],[-63.59861000000001,44.66777000000013],[-63.59194200000002,44.66471100000001],[-63.58361100000002,44.65693699999997],[-63.56422399999991,44.62076999999999],[-63.558220000000006,44.613266000000124],[-63.555388999999934,44.60776900000002],[-63.546059000000014,44.58860400000003],[-63.520835999999974,44.512771999999984],[-63.520279000000016,44.50777399999998],[-63.52527600000002,44.49527000000012],[-63.53333299999997,44.484993000000145],[-63.54277799999994,44.476379000000065],[-63.553054999999915,44.469711000000075],[-63.57083899999992,44.46193700000009],[-63.63111099999992,44.43582200000009],[-63.63861099999991,44.436935000000005],[-63.90694400000001,44.49527000000012],[-63.91361199999989,44.498604000000114],[-63.924171,44.50610399999999],[-63.932503,44.513329000000056],[-63.93555500000002,44.517494000000056],[-63.94388600000002,44.536110000000065],[-63.938605999999936,44.616104000000064],[-63.93777499999993,44.62165800000008],[-63.92805499999986,44.64222000000001],[-63.91916699999996,44.651657000000114],[-63.91444399999989,44.65554800000001],[-63.90860700000002,44.678047000000106],[-64.00834700000001,44.647491],[-64.04527299999995,44.63582600000012],[-64.05526699999996,44.61943800000006],[-64.06555199999991,44.59526800000003],[-64.06388899999996,44.59054599999996],[-64.05915800000002,44.581665000000044],[-64.05499299999997,44.57777399999998],[-64.03944399999995,44.572495],[-64.03361499999994,44.563049000000035],[-64.00917099999998,44.513329000000056],[-64.01000999999997,44.50777399999998],[-64.08306900000002,44.46666000000005],[-64.091949,44.46888000000007],[-64.11054999999999,44.478324999999984],[-64.12165799999997,44.48526800000013],[-64.12554899999998,44.51055100000002],[-64.12361099999993,44.52748900000012],[-64.11972000000003,44.53943600000008],[-64.12165799999997,44.54415900000009],[-64.12748699999992,44.552773000000116],[-64.13583399999999,44.56054699999993],[-64.146118,44.56832900000006],[-64.17027300000001,44.58610500000003],[-64.20083599999998,44.57638499999996],[-64.30526700000001,44.53333299999997],[-64.33750900000001,44.411933999999974],[-64.34666400000003,44.36249500000014],[-64.346115,44.357215999999994],[-64.32972699999993,44.32888000000003],[-64.31111099999993,44.319159999999954],[-64.30332899999996,44.316666000000055],[-64.29527300000001,44.316101],[-64.29055799999998,44.31999200000007],[-64.29222099999998,44.324715000000026],[-64.29998799999993,44.32749200000012],[-64.30555700000002,44.330826000000116],[-64.30943300000001,44.33554800000002],[-64.30777,44.3408280000001],[-64.30110200000001,44.341933999999924],[-64.27362099999988,44.33027600000008],[-64.26055899999994,44.324164999999994],[-64.23944099999994,44.29415899999992],[-64.25334199999992,44.27526899999998],[-64.25805699999995,44.26998900000012],[-64.28332499999988,44.25305200000008],[-64.319458,44.26471700000002],[-64.35583500000001,44.27332300000012],[-64.39111300000002,44.253326000000015],[-64.42805499999992,44.22832500000004],[-64.43222000000003,44.22360200000003],[-64.44471699999991,44.190269],[-64.61639400000001,44.13304900000014],[-64.61860699999994,44.07193799999999],[-64.66639700000002,43.990273000000116],[-64.67138699999998,43.98638200000005],[-64.73222399999992,43.951660000000004],[-64.73805199999993,43.94943200000006],[-64.74526999999995,43.94887499999999],[-64.77639799999997,43.950829],[-64.80610699999994,43.95054600000003],[-64.81277499999993,43.94943200000006],[-64.81806899999992,43.94638100000003],[-64.83222999999992,43.92610200000013],[-64.881104,43.838882000000126],[-64.906387,43.80054499999994],[-65.03056299999997,43.70416300000005],[-65.06666599999994,43.69638100000009],[-65.24221799999992,43.679161000000136],[-65.32583599999987,43.674995000000024],[-65.37527499999987,43.5752720000001],[-65.44915800000001,43.55971500000004],[-65.45333899999997,43.55499300000014],[-65.47582999999997,43.505829000000006],[-65.48138399999999,43.46443900000003],[-65.49694799999997,43.49082900000002],[-65.54804999999993,43.55609900000002],[-65.55943300000001,43.568054000000075],[-65.56861899999996,43.5702740000001],[-65.57556199999999,43.569717000000026],[-65.58473200000003,43.56027199999994],[-65.591385,43.549721000000034],[-65.603882,43.534721000000104],[-65.612213,43.526099999999985],[-65.61749299999997,43.523604999999975],[-65.646118,43.51194000000004],[-65.67332499999992,43.50610399999999],[-65.712784,43.498604000000114],[-65.72055099999994,43.499161000000015],[-65.72582999999986,43.50249500000001],[-65.777222,43.562492000000134],[-65.78332499999993,43.57110600000004],[-65.78388999999999,43.576385000000016],[-65.78195199999993,43.587769000000094],[-65.778885,43.599998000000085],[-65.773056,43.612770000000125],[-65.77111799999994,43.624435000000005],[-65.76945499999994,43.64138000000014],[-65.76806599999992,43.65804300000002],[-65.76834099999996,43.66888399999999],[-65.76972999999987,43.679161000000136],[-65.77555799999999,43.68832400000014],[-65.86888099999999,43.78638500000005],[-65.90777599999996,43.82166300000006],[-65.91221599999989,43.82527200000004],[-65.91861,43.82833100000005],[-65.93277,43.82721700000002],[-65.93888899999996,43.82499700000005],[-65.94249000000002,43.819443000000035],[-65.9561159999999,43.7761000000001],[-65.968887,43.71943699999997],[-65.97166399999998,43.71276899999998],[-65.97500600000001,43.70721400000008],[-65.98306300000002,43.697768999999994],[-66.01333599999987,43.69165800000013],[-66.02055399999995,43.69110100000006],[-66.029449,43.73165900000009],[-66.03056299999997,43.73610700000006],[-66.033615,43.740273],[-66.04222099999998,43.748046999999985],[-66.08084100000002,43.76805100000007],[-66.08860799999997,43.768326000000116],[-66.09445199999999,43.76610600000009],[-66.10777299999995,43.75332600000013],[-66.12165800000002,43.762215000000026],[-66.135559,43.78943600000008],[-66.16694599999994,43.85860399999996],[-66.16805999999991,43.863051999999925],[-66.16805999999991,43.895546000000024],[-66.16749599999997,43.90138200000007],[-66.16583299999996,43.907211000000075],[-66.151947,43.91915900000009],[-66.15028399999994,43.92527000000001],[-66.14999399999994,43.93082400000003],[-66.14916999999997,44.00110600000011],[-66.14973399999991,44.011108000000036],[-66.18194599999993,44.06749700000012],[-66.204453,44.08665500000001],[-66.19055200000003,44.15054300000003],[-66.18777499999993,44.16193400000003],[-66.118607,44.33804300000003],[-66.09388699999988,44.36749300000014],[-66.08999599999999,44.37165800000014],[-66.03750599999995,44.42332500000009],[-65.97694399999995,44.477486],[-65.96722399999999,44.48610700000012],[-65.95666499999993,44.49166100000008],[-65.95028699999995,44.493050000000096],[-65.94444299999998,44.4897160000001],[-65.93804899999992,44.49110400000001],[-65.86582899999996,44.53888699999999],[-65.84167499999995,44.56860400000011],[-65.84138499999995,44.574164999999994],[-65.84445199999988,44.57833100000005],[-65.84889199999998,44.582213999999965],[-65.85527000000002,44.585823000000005],[-65.86277799999988,44.58693699999998],[-65.931107,44.582213999999965],[-65.94305399999996,44.57777399999998],[-65.95861799999994,44.567497],[-66.004456,44.53582799999998],[-66.03472899999997,44.51471700000013],[-66.12332200000003,44.448875000000044],[-66.17777999999993,44.396660000000054],[-66.18582199999997,44.38721499999997],[-66.19055200000003,44.383331],[-66.19722000000002,44.386108000000036],[-66.19860799999998,44.41276600000003],[-66.19110099999995,44.42332500000009],[-66.10305800000003,44.500000000000114],[-66.06806899999992,44.524994000000106],[-65.97166399999998,44.591934000000094],[-65.82022099999995,44.65443400000004],[-65.81672699999996,44.655768999999964],[-65.80872299999993,44.65193600000009],[-65.80289500000003,44.64460400000007],[-65.79639400000002,44.62426800000003],[-65.79689799999994,44.617603000000145],[-65.79789700000003,44.61393700000002],[-65.75695799999994,44.61527300000006],[-65.756393,44.60999300000003],[-65.75306699999999,44.60582700000009],[-65.74527,44.605552999999986],[-65.69722000000002,44.61249500000008],[-65.69027699999992,44.614441],[-65.68499799999995,44.61693600000001],[-65.62527499999999,44.658882000000006],[-65.52250700000002,44.737769999999955],[-65.54861499999998,44.733879000000115],[-65.68261699999994,44.69315699999993],[-65.68627899999996,44.691825999999935],[-65.69027699999992,44.69116200000008],[-65.69544199999996,44.691825999999935],[-65.704117,44.69499200000007],[-65.70611600000001,44.697655],[-65.70711499999999,44.700489000000005],[-65.70745099999999,44.70348700000005],[-65.70594799999998,44.707489000000066],[-65.70094299999994,44.713157999999964],[-65.69793700000002,44.71549200000004],[-65.71777299999997,44.72193100000004],[-65.65833999999995,44.758605999999986],[-65.64695699999993,44.76527399999998],[-65.29998799999993,44.92832900000013],[-65.20249899999999,44.97387700000007],[-65.11416600000001,45.01166500000011],[-64.93415800000002,45.100273000000016],[-64.91805999999991,45.11110700000006],[-64.87943999999999,45.13082099999997],[-64.86193800000001,45.139717000000076],[-64.81471299999998,45.15804300000008],[-64.80860899999993,45.16027100000008],[-64.777222,45.16999099999998],[-64.74499500000002,45.178329000000076],[-64.71083099999998,45.183876000000055],[-64.59028599999994,45.208046000000024],[-64.55055199999993,45.216660000000104],[-64.46888699999994,45.24276699999996],[-64.45140099999998,45.24943500000012],[-64.4344329999999,45.25750000000005],[-64.41777000000002,45.26666300000005],[-64.39750699999996,45.281105000000025],[-64.39389,45.28694200000001],[-64.39195299999994,45.29277000000013],[-64.39111300000002,45.29833200000007],[-64.39306599999986,45.303322000000094],[-64.40167199999996,45.31110400000006],[-64.40695199999993,45.31443800000005],[-64.41389500000002,45.317497],[-64.43083200000001,45.322220000000016],[-64.45472699999993,45.32360800000009],[-64.46221899999995,45.32305100000002],[-64.47083999999995,45.32444000000004],[-64.48805199999998,45.329162999999994],[-64.49471999999997,45.33221400000002],[-64.48916599999995,45.335266000000104],[-64.46583599999991,45.33471700000001],[-64.44055200000003,45.331665000000044],[-64.35305799999992,45.316101],[-64.33833300000003,45.31027199999994],[-64.32749899999999,45.303322000000094],[-64.32139599999994,45.294715999999994],[-64.31777999999991,45.28527100000014],[-64.31722999999988,45.280273000000136],[-64.31777999999991,45.274437000000034],[-64.32194499999991,45.26971400000008],[-64.32749899999999,45.266936999999984],[-64.34306299999997,45.25610399999999],[-64.35333300000002,45.23915900000003],[-64.38583399999993,45.14554600000008],[-64.38027999999986,45.13110400000011],[-64.36389199999996,45.10138699999999],[-64.35972599999997,45.09748799999994],[-64.35221899999993,45.09804500000007],[-64.34695399999998,45.101105000000075],[-64.337219,45.10860400000007],[-64.33389299999993,45.115272999999945],[-64.33444199999997,45.12027000000006],[-64.333328,45.131660000000124],[-64.32917800000001,45.13638300000008],[-64.324387,45.13934300000005],[-64.31138599999997,45.14138000000003],[-64.29583699999995,45.14138000000003],[-64.24415599999998,45.12387799999999],[-64.22111499999994,45.11054999999999],[-64.21028099999995,45.10360700000001],[-64.15722699999998,45.056938],[-64.14695699999999,45.04444100000006],[-64.14555399999989,45.034720999999934],[-64.154449,44.98443600000013],[-64.15638699999994,44.97832500000004],[-64.11694299999994,45.00916300000006],[-64.11416599999995,45.04666100000003],[-64.12193300000001,45.05804400000005],[-64.13639799999993,45.07444000000004],[-64.14167800000001,45.07860599999998],[-64.1625059999999,45.09221600000001],[-64.18832399999991,45.104713000000004],[-64.19249000000002,45.10860400000007],[-64.19860799999987,45.11721],[-64.19888299999997,45.122490000000084],[-64.19583099999994,45.15054300000003],[-64.16361999999998,45.185265000000015],[-64.15278599999999,45.19276400000001],[-64.11833199999995,45.20888500000001],[-64.10611,45.21332600000011],[-64.09999099999993,45.21527100000009],[-64.06582600000002,45.22221400000012],[-64.00805700000001,45.23638199999999],[-63.98221599999994,45.243049999999926],[-63.95666499999999,45.25138899999996],[-63.80583199999995,45.30193300000013],[-63.59610700000002,45.3155440000001],[-63.47083299999986,45.321663000000115],[-63.384170999999924,45.35083000000003],[-63.37194099999999,45.35499600000014],[-63.365554999999915,45.35777300000001],[-63.360832000000016,45.36082499999998],[-63.36860699999994,45.36360900000011],[-63.73889200000002,45.396660000000054],[-63.75556199999994,45.39804800000013],[-63.79722600000002,45.39276899999999],[-63.83777599999996,45.385551000000135],[-63.98805199999998,45.384438000000046],[-64.04055800000003,45.40110000000004],[-64.04499800000002,45.40443400000004],[-64.06111099999998,45.40971400000012],[-64.06973299999999,45.41027100000002],[-64.083618,45.409430999999984],[-64.16332999999986,45.403877000000136],[-64.214722,45.399719000000005],[-64.31277499999993,45.39138000000014],[-64.35777299999995,45.38110400000005],[-64.52999899999998,45.40804300000002],[-64.67416400000002,45.383049000000085],[-64.81582599999996,45.348602000000085],[-64.92944299999999,45.32444000000004],[-64.93721,45.32694200000009],[-64.93804899999992,45.33221400000002],[-64.93666100000002,45.34332300000011],[-64.93331899999998,45.35555300000004],[-64.9177699999999,45.40859999999992],[-64.90916399999998,45.418052999999986],[-64.83138999999994,45.47915599999993],[-64.76556399999998,45.50555400000013],[-64.69915799999995,45.53110499999997],[-64.568893,45.60416399999997],[-64.47055099999994,45.67027300000012],[-64.43028299999997,45.71554600000002],[-64.33222999999992,45.76888300000013],[-64.33168,45.763611000000026],[-64.32611099999997,45.749435000000005],[-64.29666099999992,45.76332899999994],[-64.28306600000002,45.77665699999994],[-64.27555799999999,45.79999500000008],[-64.27305599999994,45.811661000000015],[-64.27000399999991,45.82888000000008],[-64.27293399999996,45.835754000000065],[-64.27362099999988,45.838599999999985],[-64.27667199999996,45.8427660000001],[-64.32472200000001,45.87999000000002],[-64.33277899999996,45.88276700000006],[-64.347778,45.881935],[-64.36138899999997,45.879158000000075],[-64.36694299999999,45.87638099999998],[-64.36776699999996,45.87054400000005],[-64.36332700000003,45.86666100000008],[-64.35472099999993,45.865547000000106],[-64.35749800000002,45.85110500000013],[-64.41805999999991,45.796104000000014],[-64.4783329999999,45.750549000000035],[-64.49722300000002,45.783882000000006],[-64.48999000000003,45.794998000000135],[-64.48805199999998,45.801102000000014],[-64.48916599999995,45.81137800000005],[-64.49221799999998,45.81554399999999],[-64.59733599999998,45.92210400000005],[-64.68194599999987,46.02166],[-64.686935,46.041382000000056],[-64.69055199999997,46.05082700000008],[-64.69499199999996,46.05471000000006],[-64.73693799999995,46.083878000000084],[-64.74749800000001,46.09054600000002],[-64.754456,46.08915700000006],[-64.76445000000001,46.08305400000012],[-64.70639,45.994713000000104],[-64.70194999999995,45.990829000000076],[-64.64800999999994,45.93304799999993],[-64.63117199999999,45.92271800000003],[-64.62899800000002,45.92038300000007],[-64.601181,45.88155000000012],[-64.601181,45.877384000000006],[-64.60134099999999,45.87388199999998],[-64.602844,45.86721399999999],[-64.60450700000001,45.863552000000084],[-64.58306900000002,45.826942000000145],[-64.75639299999995,45.62248999999997],[-64.77250699999996,45.609993000000145],[-64.77833599999997,45.60721600000005],[-64.78582799999992,45.61027500000006],[-64.791382,45.613609000000054],[-64.79666099999997,45.62248999999997],[-64.80166599999995,45.62638100000004],[-64.808334,45.62971500000003],[-64.81722999999994,45.63249200000013],[-64.825287,45.633331000000055],[-64.84750400000001,45.633331000000055],[-64.88444500000003,45.63166000000001],[-64.90417500000001,45.627769000000114],[-64.94137599999999,45.60221899999999],[-64.94721999999996,45.59804500000013],[-64.96194500000001,45.58610500000003],[-64.97639500000002,45.57249499999995],[-64.98666399999996,45.564437999999996],[-64.99722300000002,45.557213000000104],[-65.015015,45.54888200000005],[-65.04750100000001,45.539161999999976],[-65.10444599999994,45.524994000000106],[-65.13833599999992,45.517769000000044],[-65.15222199999994,45.51610600000009],[-65.164444,45.51305400000001],[-65.220551,45.4938810000001],[-65.32667500000002,45.457497000000046],[-65.339447,45.45221699999996],[-65.36805700000002,45.437767000000065],[-65.394455,45.41944100000006],[-65.42138699999992,45.40277100000009],[-65.53195199999999,45.342490999999995],[-65.88362099999995,45.209160000000054],[-65.88999899999999,45.2074970000001],[-65.90360999999996,45.205551000000014],[-65.91082799999998,45.20526899999999],[-65.91888399999993,45.20609999999999],[-65.98332199999993,45.21971100000013],[-65.98998999999998,45.22304500000013],[-66.09060699999992,45.295657999999946],[-66.09294099999994,45.297989000000086],[-66.09461199999998,45.30065900000005],[-66.09160599999996,45.30382499999996],[-66.08389299999993,45.34276600000004],[-66.07806399999993,45.34554300000008],[-66.05749499999996,45.348602000000085],[-66.04527300000001,45.35332500000004],[-66.029449,45.364158999999916],[-66.015289,45.377769],[-66.00306699999999,45.3949970000001],[-66.00083899999998,45.40110000000004],[-65.99722300000002,45.41777000000002],[-65.99444599999998,45.45555099999996],[-65.99444599999998,45.46082300000006],[-66.00250199999999,45.46166200000005],[-66.0083469999999,45.45888500000012],[-66.19027699999998,45.339432000000045],[-66.193329,45.33360300000004],[-66.193329,45.328331000000105],[-66.19055200000003,45.32388300000014],[-66.179169,45.30582399999997],[-66.17610200000001,45.30193300000013],[-66.14527900000002,45.27916000000005],[-66.14166999999992,45.259769000000006],[-66.13700099999994,45.25927000000013],[-66.11399799999998,45.25877400000013],[-66.1135099999999,45.23777000000007],[-66.14723200000003,45.19221500000009],[-66.20556599999998,45.16387899999995],[-66.21665999999999,45.15915700000005],[-66.42777999999998,45.084991],[-66.45973200000003,45.10610200000002],[-66.45973200000003,45.111382000000106],[-66.46112099999993,45.11610400000001],[-66.46806300000003,45.129714999999976],[-66.48889199999991,45.14999400000005],[-66.49638400000003,45.14971900000006],[-66.531387,45.14721700000001],[-66.53750599999995,45.14527100000009],[-66.55999799999995,45.133331],[-66.57139599999994,45.12665600000014],[-66.58612099999999,45.11693600000007],[-66.60804699999994,45.10416400000008],[-66.64222699999999,45.08638000000013],[-66.648056,45.08360300000004],[-66.75472999999988,45.055550000000096],[-66.79249600000003,45.05526700000013],[-66.77694699999995,45.08638000000013],[-66.77610799999997,45.09137700000008],[-66.77778599999999,45.096100000000035],[-66.78306599999996,45.099716000000114],[-66.96556099999992,45.17943600000001],[-67.02194199999985,45.17027300000001],[-67.027222,45.168052999999986],[-67.04638699999998,45.12693800000005],[-67.12943999999999,45.17221799999999],[-67.18693499999995,45.19221500000009],[-67.2065429999999,45.18303700000007],[-67.23611499999993,45.193877999999984],[-67.25306699999993,45.199432],[-67.261124,45.201103000000046],[-67.26777599999997,45.200546000000145],[-67.27500900000001,45.1988750000001],[-67.28721599999994,45.19415300000003],[-67.29055799999998,45.182770000000005],[-67.29028299999999,45.17748999999992],[-67.29222099999993,45.166100000000085],[-67.29638699999992,45.16082],[-67.30139199999996,45.156937000000084],[-67.30665599999986,45.15332000000012],[-67.318893,45.14860500000009],[-67.32556199999999,45.147491000000116],[-67.33306900000002,45.147491000000116],[-67.34194899999994,45.14999400000005],[-67.354172,45.156097000000045],[-67.40388499999995,45.194435000000055],[-67.40805099999994,45.19832599999995],[-67.42250099999995,45.2149960000001],[-67.45527599999997,45.26305400000007],[-67.462784,45.276099999999985],[-67.46501199999989,45.281105000000025],[-67.46528599999999,45.28638500000011],[-67.46417200000002,45.29193900000007],[-67.45056199999993,45.33305400000006],[-67.48500100000001,45.48915900000003],[-67.485275,45.494438],[-67.48277299999995,45.50027499999993],[-67.47888199999989,45.50443999999993],[-67.46777299999997,45.510826000000066],[-67.43638599999997,45.52137800000003],[-67.42193600000002,45.523323000000005],[-67.41583299999996,45.525269000000094],[-67.41082799999992,45.529990999999995],[-67.40695199999988,45.578049000000135],[-67.40888999999999,45.582214000000135],[-67.41250599999995,45.58693699999998],[-67.42416399999996,45.59471100000013],[-67.453888,45.61249500000008],[-67.462219,45.61471599999999],[-67.46945199999999,45.61305199999998],[-67.48611499999998,45.60360700000007],[-67.49999999999994,45.60166200000009],[-67.515015,45.60110500000002],[-67.57389799999999,45.61166400000002],[-67.65666199999998,45.63054699999992],[-67.66444399999995,45.6336060000001],[-67.79110700000001,45.69304700000009],[-67.79666099999992,45.69609800000006],[-67.79916400000002,45.70110299999993],[-67.80444299999999,45.73137700000001],[-67.80638099999999,45.78472099999999],[-67.78666699999991,45.888329000000056],[-67.77250700000002,45.95749699999993],[-67.77917499999995,46.28333299999997],[-67.78889499999997,46.78777300000007],[-67.79167199999995,46.92137900000006],[-67.79499800000002,47.06999200000007],[-67.85972599999991,47.09748800000011],[-67.87416100000002,47.103607000000125],[-67.89222699999999,47.114441],[-67.94860799999992,47.16638200000011],[-67.95140099999998,47.17083000000008],[-67.95584100000002,47.17999300000008],[-67.95722999999992,47.18498999999997],[-67.96194499999996,47.19415300000014],[-67.96888699999994,47.20277400000009],[-68.18582200000003,47.33277100000004],[-68.20861799999994,47.341660000000104],[-68.24499500000002,47.35193600000002],[-68.30665599999992,47.36444099999994],[-68.323059,47.365829000000076],[-68.337219,47.363609000000054],[-68.34889199999992,47.359992999999974],[-68.36776699999996,47.35110500000002],[-68.37304699999993,47.34721400000012],[-68.56471299999993,47.28971900000005],[-68.76194800000002,47.23276499999997],[-68.78750599999995,47.224709000000075],[-68.83167999999989,47.20888499999995],[-68.88778699999995,47.18804200000005],[-68.89527900000002,47.18998700000009],[-68.958618,47.217209000000025],[-68.96528599999988,47.22054300000002],[-69.02389499999992,47.25027499999993],[-69.03611799999999,47.257217000000026],[-69.04499800000002,47.26444200000009],[-69.04916400000002,47.274437000000034],[-69.05305499999997,47.28943600000008],[-69.05358899999993,47.29377700000009],[-69.05499299999985,47.299438000000066],[-69.05526699999996,47.30471],[-69.056107,47.336655000000064],[-69.05555699999996,47.347488000000055],[-69.05249000000003,47.38054699999998],[-69.04943799999995,47.39221999999995],[-69.045837,47.398604999999975],[-69.04361,47.404709000000025],[-69.039444,47.41693900000013],[-69.03832999999997,47.42249300000009],[-69.03999299999998,47.427490000000034],[-69.04861499999998,47.435546999999985],[-69.05555699999996,47.438599000000124],[-69.12388599999991,47.458327999999995],[-69.13276699999994,47.459991000000116],[-69.23249800000002,47.47137500000002],[-69.23962399999999,47.46441300000009],[-69.30526700000001,47.40026899999998],[-69.42361499999998,47.28333299999997],[-69.65388499999995,47.05526700000013],[-69.71250900000001,46.99694099999999],[-69.84722899999997,46.86221300000011],[-69.99276700000001,46.715828000000045],[-70.00917099999987,46.69804399999998],[-70.026947,46.58749399999999],[-70.03860500000002,46.509995],[-70.04415899999992,46.4749910000001],[-70.047775,46.45388000000008],[-70.05055199999998,46.438599000000124],[-70.06361400000003,46.42416400000002],[-70.068893,46.41971600000005],[-70.07528699999995,46.41777000000013],[-70.08139,46.41777000000013],[-70.08805799999988,46.41499300000004],[-70.11915599999998,46.393608000000086],[-70.200287,46.33638000000008],[-70.24249299999991,46.27916000000005],[-70.28778099999994,46.203049000000135],[-70.30555699999991,46.07888000000008],[-70.3125,45.98582500000009],[-70.30972299999996,45.98082000000005],[-70.30332900000002,45.97776799999997],[-70.29388399999999,45.97554800000012],[-70.27833599999997,45.97526600000003],[-70.260559,45.971374999999966],[-70.25361599999991,45.968323000000055],[-70.24833699999994,45.96471400000007],[-70.23971599999993,45.956657000000064],[-70.23805199999998,45.95193499999999],[-70.25500499999998,45.913048],[-70.258896,45.907493999999986],[-70.26333599999998,45.90277100000003],[-70.39388999999994,45.77804600000013],[-70.46665999999993,45.711937000000034],[-70.55526700000001,45.67276800000013],[-70.57694999999995,45.66082000000006],[-70.63194299999998,45.627769000000114],[-70.69305400000002,45.571938000000046],[-70.72027600000001,45.5283280000001],[-70.725281,45.49971800000003],[-70.72471599999994,45.49471299999999],[-70.712784,45.477768000000026],[-70.70472699999993,45.469154],[-70.68943799999994,45.458046000000024],[-70.86860699999994,45.246101000000124],[-70.87304699999999,45.24137900000005],[-70.87860099999995,45.23860199999996],[-70.886124,45.23804500000006],[-71.021118,45.326660000000004],[-71.085129,45.30770899999999],[-71.13999899999993,45.25305200000008],[-71.14639299999999,45.25249500000001],[-71.17027299999995,45.25388300000009],[-71.18916300000001,45.25777399999998],[-71.21166999999991,45.26610599999998],[-71.23306300000002,45.274993999999936],[-71.23971599999999,45.278046000000074],[-71.26444999999995,45.29083300000008],[-71.28056299999997,45.30193300000013],[-71.28860499999996,45.30443600000007],[-71.30277999999998,45.303047000000106],[-71.31471299999993,45.299438000000066],[-71.32749899999993,45.294441000000006],[-71.42443800000001,45.25],[-71.408615,45.22304500000013],[-71.40222199999994,45.21915400000006],[-71.39889499999998,45.21554600000013],[-71.396118,45.21054800000013],[-71.39584399999995,45.20526899999999],[-71.39862099999999,45.199432],[-71.43249499999996,45.13027200000005],[-71.43611099999993,45.12526700000001],[-71.45916699999998,45.102776000000006],[-71.48277299999995,45.083878000000084],[-71.49305699999996,45.075271999999984],[-71.49638399999992,45.06888600000008],[-71.49888599999997,45.05721300000005],[-71.49722299999996,45.04166399999997],[-71.49415599999998,45.020546000000024],[-71.55471799999998,45.01998900000012],[-71.89277600000003,45.019157000000064],[-72.04998799999998,45.01944000000003],[-72.27165200000002,45.018775999999946],[-72.45916699999987,45.01749400000011],[-72.51028399999996,45.01721200000003],[-72.77888499999995,45.02082800000011],[-72.95638999999994,45.01832600000006],[-73.337173,45.01186400000006],[-73.346115,45.01138300000002],[-73.35299700000002,45.00942199999997],[-73.35926799999999,45.01006300000006],[-73.37666299999995,45.011108000000036],[-73.62277199999994,45.00666000000007],[-73.91164399999991,45.00000000000006],[-74.24916100000002,44.99221800000009],[-74.6820219999999,45.0067140000001],[-74.75111400000003,45.00222000000002],[-74.76972999999992,45.006386000000134],[-74.78582799999998,45.01138300000002],[-74.81220999999988,45.01776899999993],[-74.82888799999995,45.019157000000064],[-74.85028099999994,45.01666300000011],[-74.99082900000002,44.986655999999925],[-75.00140399999998,44.98054500000006],[-75.170547,44.898604999999975],[-75.27806099999992,44.85721600000005],[-75.30166600000001,44.84665699999999],[-75.31777999999986,44.837212000000136],[-75.39584399999995,44.785827999999924],[-75.537216,44.69137600000005],[-75.5625,44.673882000000106],[-75.61805700000002,44.63499500000012],[-75.62805199999997,44.627769],[-75.68249500000002,44.58804300000003],[-75.73611499999993,44.54638700000004],[-75.801941,44.49110400000001],[-75.81138599999997,44.483047000000056],[-75.82055700000001,44.47499099999999],[-75.82472200000001,44.46998600000012],[-75.82833899999997,44.44665500000008],[-75.83416699999998,44.43443300000007],[-75.8411099999999,44.4230500000001],[-75.84944199999995,44.41471100000007],[-75.86416600000001,44.40277100000014],[-75.87999000000002,44.39332600000006],[-75.904449,44.384995],[-75.96610999999996,44.36415899999997],[-75.98217799999992,44.358864000000096],[-75.997772,44.355270000000075],[-76.01945499999994,44.3533250000001],[-76.03472899999991,44.35305000000005],[-76.04695099999998,44.34971600000006],[-76.05776999999995,44.344993999999986],[-76.06443799999994,44.34137700000002],[-76.36337300000002,44.15099299999997],[-76.410278,44.121101000000124],[-76.43472300000002,44.10471300000006],[-76.43998699999997,44.09943400000009],[-76.531387,43.98304699999994],[-76.569458,43.93415799999997],[-76.583618,43.91582499999993],[-76.69749499999995,43.76860000000005],[-76.801941,43.633605999999986],[-76.81695599999995,43.633049000000085],[-76.97416699999991,43.634438000000046],[-77.28832999999992,43.63665800000007],[-77.58277900000002,43.638603000000046],[-77.72999600000003,43.63916000000012],[-77.85777300000001,43.63943499999999],[-77.88722200000001,43.63943499999999],[-78.38806199999993,43.63832900000011],[-78.66305499999999,43.63749700000005],[-78.72471599999994,43.629433000000006],[-78.93832399999991,43.553878999999995],[-79.02806099999998,43.521934999999985],[-79.09527599999996,43.497772],[-79.18472300000002,43.46554600000013],[-79.13221699999997,43.38249200000001],[-79.06678799999997,43.27940000000007],[-79.054169,43.262496999999996],[-79.05332899999996,43.25666000000007],[-79.04499799999996,43.165543000000014],[-79.04472399999997,43.16054500000001],[-79.04583699999995,43.14888000000013],[-79.04943800000001,43.14388300000002],[-79.05972300000002,43.13721500000008],[-79.06361399999992,43.13221000000004],[-79.08111599999995,43.085548000000074],[-79.04333499999996,43.011664999999994],[-79.04083299999996,43.0077740000001],[-79.02166699999992,42.987213000000054],[-79.00584399999991,42.977211000000125],[-78.97860699999995,42.96138000000013],[-78.97193900000002,42.95804600000014],[-78.96278399999994,42.95638300000002],[-78.94665500000002,42.95555100000013],[-78.93859900000001,42.953322999999955],[-78.93277,42.950829000000056],[-78.92749000000003,42.94693799999999],[-78.92027300000001,42.939156000000025],[-78.91833500000001,42.9347150000001],[-78.91528299999999,42.92416400000002],[-78.91722099999993,42.90499100000011],[-78.91833500000001,42.89888000000002],[-78.9266659999999,42.88054699999998],[-78.93221999999997,42.86832400000009],[-78.935272,42.86249500000008],[-78.94249000000002,42.852493000000095],[-78.96583599999997,42.83360299999998],[-78.98693799999995,42.81999200000001],[-79.12110899999999,42.76915700000012],[-79.15444899999994,42.757217000000026],[-79.29943799999995,42.70249200000001],[-79.56645199999997,42.600708000000054],[-79.76342799999992,42.524703999999986],[-79.77667200000002,42.52027099999998],[-80.08612099999999,42.399994000000106],[-80.09695399999993,42.396385000000066],[-80.5102839999999,42.32916300000005],[-80.528549,42.326617999999996],[-80.86915599999998,42.279160000000104],[-81.24916100000002,42.224991000000045],[-81.42443799999995,42.144997000000046],[-81.62361099999998,42.052773000000116],[-81.82223499999998,41.96027400000014],[-82.21806299999997,41.774437000000034],[-82.23889199999996,41.76388500000007],[-82.42527799999999,41.67555199999998],[-82.46278399999994,41.676102000000014],[-82.64999399999994,41.68193800000006],[-82.69665499999996,41.683876],[-83.07194499999991,41.85971799999999],[-83.08084100000002,41.87499200000008],[-83.11741599999988,41.94619400000005],[-83.13082899999989,41.970543000000134],[-83.15028399999994,42.008331],[-83.16860999999994,42.046104000000014],[-83.16833500000001,42.0480500000001],[-83.13722200000001,42.201385000000016],[-83.13249200000001,42.22082499999999],[-83.12332200000003,42.24582700000008],[-83.11805699999996,42.25777400000004],[-83.10777299999995,42.27276600000005],[-83.08695999999998,42.30054500000006],[-83.06221,42.31860399999999],[-83.051941,42.32471500000008],[-83.027222,42.331940000000145],[-83.00222799999995,42.33915700000006],[-82.97582999999997,42.344711000000075],[-82.94055199999997,42.35749800000008],[-82.84138499999995,42.39694199999997],[-82.80888400000003,42.41332200000011],[-82.79360999999994,42.422768000000076],[-82.77528399999994,42.43721000000005],[-82.76306199999999,42.448601],[-82.72999600000003,42.48333000000008],[-82.704453,42.508331000000055],[-82.67027300000001,42.53999300000004],[-82.66528299999993,42.54415899999992],[-82.65910300000002,42.54819500000008],[-82.65075699999994,42.55364200000014],[-82.64497399999999,42.556411999999966],[-82.63055399999996,42.557495000000074],[-82.62222299999996,42.55665600000009],[-82.61416600000001,42.55471000000006],[-82.60583500000001,42.55416100000008],[-82.58639499999992,42.558601000000124],[-82.57167099999998,42.56888600000002],[-82.53582799999987,42.59943400000003],[-82.52139299999993,42.618881000000044],[-82.51333599999987,42.63638300000008],[-82.48472600000002,42.719154],[-82.474716,42.751663000000065],[-82.47111499999994,42.769989000000066],[-82.470551,42.782493999999986],[-82.47193900000002,42.79305300000004],[-82.47332799999992,42.79749300000003],[-82.48055999999991,42.812492000000134],[-82.48194899999993,42.82332600000001],[-82.48110999999994,42.8294370000001],[-82.4644469999999,42.898048000000074],[-82.46250900000001,42.904709000000025],[-82.41877699999998,43.018639000000064],[-82.40417500000001,43.049164000000076],[-82.32223499999998,43.21054799999996],[-82.25279199999994,43.34638200000012],[-82.22888199999994,43.39138000000003],[-82.146118,43.553047000000106],[-82.13027999999997,43.585266000000104],[-82.214447,43.95221700000013],[-82.33167999999995,44.46082300000012],[-82.43055699999996,44.882767000000115],[-82.54305999999997,45.35582699999998],[-82.62999000000002,45.39610299999998],[-82.665009,45.41193399999992],[-82.95417800000001,45.54193900000007],[-83.05082699999991,45.58526600000005],[-83.11221299999994,45.61277000000007],[-83.27084400000001,45.68332699999996],[-83.50029,45.78499599999998],[-83.597778,45.82721700000002],[-83.52389499999998,45.91805300000004],[-83.48777799999999,45.96166199999993],[-83.447769,46.011940000000095],[-83.474716,46.03638500000011],[-83.48332199999999,46.043884000000105],[-83.566666,46.098602000000085],[-83.57749899999999,46.105270000000075],[-83.596115,46.11415899999997],[-83.61054999999993,46.11915600000009],[-83.62777699999987,46.12304699999993],[-83.66305499999987,46.12609900000007],[-83.83056599999986,46.12609900000007],[-83.84611499999994,46.124992000000134],[-83.88389599999994,46.10277600000012],[-83.88803100000001,46.09616100000011],[-83.89225799999991,46.092346000000134],[-83.89800999999994,46.08718900000008],[-83.91799899999995,46.073303000000124],[-83.92300399999993,46.070250999999985],[-83.93600499999997,46.065383999999995],[-83.94284099999999,46.066101],[-83.952789,46.06860399999999],[-83.95889299999993,46.071663000000115],[-83.962784,46.07555400000001],[-84.07667500000002,46.203049000000135],[-84.08972199999994,46.220267999999976],[-84.09916699999991,46.23276499999997],[-84.10583499999996,46.247772],[-84.15695199999999,46.39166300000011],[-84.15834000000001,46.39666],[-84.16027799999995,46.424995000000024],[-84.15444899999994,46.445267000000115],[-84.14917000000003,46.45721400000008],[-84.13999899999999,46.47415900000004],[-84.12193300000001,46.49887799999999],[-84.11805700000002,46.51249700000005],[-84.11833199999995,46.51805100000007],[-84.1199949999999,46.523323000000005],[-84.12249799999995,46.52777100000014],[-84.12638900000002,46.531937000000084],[-84.13249199999996,46.53472099999999],[-84.19276399999995,46.546661000000086],[-84.40861499999988,46.508605999999986],[-84.42832899999996,46.503052000000025],[-84.43443300000001,46.5002750000001],[-84.454453,46.486938000000066],[-84.45944199999997,46.482764999999915],[-84.46389799999997,46.4783250000001],[-84.47471599999994,46.46360800000008],[-84.47999600000003,46.46027400000014],[-84.48638899999997,46.45888500000012],[-84.49471999999997,46.45804600000014],[-84.51251200000002,46.45915999999994],[-84.52999899999998,46.46138000000013],[-84.56500199999999,46.466385],[-84.77500899999995,46.653046000000074],[-84.787781,46.68971300000004],[-84.80694599999993,46.748328999999956],[-84.82556199999988,46.80693800000006],[-84.83277899999996,46.82916300000005],[-84.85694899999999,46.90221400000007],[-84.87222299999996,46.90943100000004],[-84.91749599999997,46.92860400000012],[-85.354446,47.111664000000076],[-85.4641719999999,47.15721100000013],[-85.73889199999996,47.270827999999995],[-85.83972199999994,47.31221000000005],[-86.01472499999994,47.38388099999992],[-86.05139199999996,47.39888000000002],[-86.46665999999993,47.56721500000003],[-86.568893,47.608330000000024],[-86.88444499999997,47.73471799999999],[-87.20140099999998,47.860275000000115],[-87.34167499999995,47.91554299999996],[-87.44471699999997,47.955826],[-88.18832399999997,48.24415600000009],[-88.36805699999991,48.31221000000005],[-88.645554,48.264160000000004],[-88.69166599999994,48.255554000000075],[-88.97416699999991,48.13916000000012],[-89.32333399999999,47.993050000000096],[-89.35665899999998,47.97971300000006],[-89.44776899999994,48.003326000000015],[-89.49312599999996,48.00316600000008],[-89.55665599999998,48.00138900000013],[-89.573059,48.001663000000065],[-89.57887299999993,48.00262500000008],[-89.58306900000002,48.003326000000015],[-89.59861799999993,48.00666000000001],[-89.603882,48.00999500000006],[-89.608337,48.01416000000006],[-89.61471599999999,48.01666300000005],[-89.750565,48.02916000000005],[-89.760559,48.02999100000005],[-89.83889799999997,48.01166500000005],[-89.86250299999995,48.00083200000006],[-89.88806199999999,47.99193600000012],[-89.895554,47.989990000000034],[-89.903885,47.98915900000003],[-89.91166699999997,47.99137900000005],[-89.98222399999997,48.01610599999998],[-89.99305700000002,48.02276599999999],[-90,48.03020499999997],[-90.00083899999998,48.031105000000025],[-90.03277599999996,48.069717000000026],[-90.056107,48.10054800000012],[-90.05943299999996,48.104996000000085],[-90.06500199999994,48.10833000000008],[-90.08168,48.11193800000001],[-90.12721299999987,48.11915600000003],[-90.146118,48.12165800000008],[-90.15638699999994,48.12249000000003],[-90.27999899999998,48.11305199999998],[-90.74082900000002,48.090828000000045],[-90.758896,48.09471100000002],[-90.76945499999994,48.099998000000085],[-90.77833599999997,48.10749800000002],[-90.83860800000002,48.184158000000025],[-90.84167499999995,48.19165800000013],[-90.84306300000003,48.205826],[-90.83805799999999,48.20860300000004],[-90.83362599999992,48.209099000000094],[-90.82972699999999,48.212493999999936],[-90.82919299999998,48.21463800000009],[-90.82888799999995,48.22165699999994],[-90.83029199999993,48.225548],[-90.83250399999991,48.227211000000125],[-90.84916699999991,48.233879000000115],[-90.868607,48.23749500000014],[-90.89805599999988,48.23665600000004],[-90.92832900000002,48.22860000000014],[-90.96916199999993,48.21471400000013],[-91.12609899999995,48.15499100000011],[-91.14916999999997,48.144157000000064],[-91.19248999999996,48.11499800000007],[-91.23222399999997,48.087769000000094],[-91.24888599999997,48.0794370000001],[-91.269455,48.07388300000008],[-91.28332499999999,48.07138100000003],[-91.31166100000002,48.069160000000124],[-91.32556199999999,48.069717000000026],[-91.34722899999997,48.068054000000075],[-91.38137799999998,48.06166100000013],[-91.39222699999993,48.05609900000002],[-91.41833500000001,48.04110700000001],[-91.46278399999994,48.05777000000006],[-91.573624,48.09304800000007],[-91.64514200000002,48.09834300000011],[-91.6875,48.144714000000135],[-91.72972099999998,48.187209999999936],[-91.73416099999992,48.19054399999993],[-91.73971599999999,48.193321000000026],[-91.756958,48.194435],[-91.77610799999997,48.19415300000014],[-91.791672,48.195267000000115],[-91.85055499999999,48.20388000000008],[-91.94027699999992,48.23054500000012],[-91.95658900000001,48.23663300000004],[-91.97084000000001,48.244437999999946],[-91.98582499999998,48.25582900000012],[-91.997772,48.266662999999994],[-92.00723299999999,48.27915999999999],[-92.008896,48.28276800000009],[-92.01112399999994,48.292496000000085],[-92.01167299999992,48.29749300000003],[-92.01333599999992,48.30499300000008],[-92.020554,48.32276900000005],[-92.02806099999998,48.33610500000003],[-92.035553,48.34360500000008],[-92.04194599999994,48.34777100000002],[-92.05194099999994,48.353882000000056],[-92.14167800000001,48.35721600000005],[-92.162216,48.35665899999998],[-92.25723299999993,48.34693900000008],[-92.26501499999989,48.34360500000008],[-92.27610799999997,48.33749399999999],[-92.28028899999998,48.33277100000004],[-92.28582799999998,48.326103000000046],[-92.30055199999993,48.30499300000008],[-92.30082700000003,48.2980500000001],[-92.29722599999997,48.28943600000008],[-92.28860499999996,48.2761000000001],[-92.283615,48.263885000000016],[-92.28306599999996,48.256660000000124],[-92.28555299999994,48.250549000000035],[-92.29028299999999,48.24665800000014],[-92.30671699999994,48.241592000000026],[-92.33168,48.23416099999997],[-92.35194399999995,48.2283250000001],[-92.35665899999998,48.22860000000014],[-92.36166400000002,48.23110200000002],[-92.36915599999998,48.238883999999985],[-92.42639200000002,48.31166100000007],[-92.45527599999997,48.39415700000001],[-92.58222999999998,48.44137599999999],[-92.697769,48.485268000000076],[-92.71528599999994,48.541382000000056],[-92.94305400000002,48.62110100000007],[-92.95306399999993,48.62332200000003],[-92.96610999999996,48.62499199999996],[-93.24499500000002,48.64054900000002],[-93.30888399999998,48.63027200000005],[-93.32250999999997,48.6280440000001],[-93.40834000000001,48.60860400000013],[-93.449997,48.597214000000065],[-93.45666499999999,48.59499400000004],[-93.458618,48.59249100000005],[-93.458618,48.5894320000001],[-93.45611600000001,48.58305400000012],[-93.452789,48.579436999999984],[-93.44972199999995,48.57054900000003],[-93.449997,48.56749700000006],[-93.4541779999999,48.559714999999926],[-93.46055599999994,48.55332199999998],[-93.46583599999991,48.54972099999992],[-93.47639499999997,48.54415899999998],[-93.489441,48.53971899999999],[-93.50306699999987,48.537498000000085],[-93.65695199999999,48.51527399999992],[-93.664444,48.5149990000001],[-93.72416699999997,48.51388500000013],[-93.77861000000001,48.51638800000012],[-93.79305999999997,48.51776899999999],[-93.80027799999993,48.52027100000004],[-93.803604,48.524712000000136],[-93.80555700000002,48.53221100000013],[-93.80972300000002,48.55027000000007],[-93.81777999999997,48.581940000000145],[-93.82000700000003,48.590546000000074],[-93.83000199999998,48.61277000000001],[-93.833328,48.616386000000034],[-93.84249899999998,48.62360400000006],[-93.851944,48.62693800000005],[-93.86555499999997,48.63027200000005],[-93.88055399999996,48.63027200000005],[-93.8852839999999,48.63027200000005],[-94.06388899999996,48.63804600000003],[-94.1119379999999,48.64110600000009],[-94.13417099999987,48.642769000000044],[-94.235275,48.65304600000002],[-94.250565,48.656097000000045],[-94.25279199999989,48.65776800000009],[-94.25418099999996,48.66054500000001],[-94.252228,48.67137900000006],[-94.252228,48.67999300000014],[-94.25666799999993,48.68776700000012],[-94.26306199999999,48.69415300000003],[-94.27111799999989,48.69915800000007],[-94.27861000000001,48.70249200000006],[-94.29110700000001,48.70609999999999],[-94.30583200000001,48.70832800000011],[-94.39056399999993,48.71110500000003],[-94.40611299999995,48.71110500000003],[-94.41416900000002,48.70999100000006],[-94.43331899999998,48.70193499999999],[-94.45361300000002,48.69582400000007],[-94.460556,48.69443500000011],[-94.47639500000002,48.69387800000004],[-94.50083899999998,48.696938000000046],[-94.52389499999992,48.70193499999999],[-94.60583500000001,48.72443399999992],[-94.63722199999995,48.739159000000086],[-94.64361600000001,48.74304999999998],[-94.68998699999992,48.77471200000008],[-94.699997,48.782767999999976],[-94.70666499999999,48.79055000000011],[-94.70944199999997,48.803047000000106],[-94.71112099999999,48.84638200000006],[-94.71000700000002,48.855270000000075],[-94.70907599999998,48.857948000000135],[-94.70500199999998,48.862770000000125],[-94.700287,48.868881000000044],[-94.69972200000001,48.87110100000007],[-94.700287,48.89527100000004],[-94.70167500000002,48.90971400000012],[-94.70417800000001,48.92443800000001],[-94.70750399999997,48.94193299999995],[-94.71665999999999,48.97054300000002],[-94.72055099999989,48.978874000000076],[-94.72721899999993,48.99221799999998],[-94.73277300000001,49.001663000000065],[-94.74527,49.02860300000009],[-94.76695299999994,49.075554000000125],[-94.79777499999994,49.155823],[-94.79888900000003,49.15915699999999],[-94.80471799999987,49.17971799999998],[-94.80665599999998,49.19360399999999],[-94.81527699999998,49.29332700000009],[-94.81555200000003,49.30609900000013],[-94.81834400000002,49.30998999999997],[-94.82194499999997,49.312767000000065],[-94.922775,49.35582700000003],[-94.93592799999993,49.36029799999994],[-94.94638099999997,49.36221299999994],[-94.95861799999994,49.36166400000002],[-94.96556099999998,49.360275],[-94.99861099999998,49.35749800000008],[-95.02583300000003,49.35749800000008],[-95.07806399999993,49.35916100000003],[-95.08566299999995,49.360023000000126],[-95.120834,49.364998000000014],[-95.14250199999992,49.371658000000025],[-95.15278599999994,49.376656000000025],[-95.15417499999995,49.36638600000009],[-95.15444899999989,49.33332800000011],[-95.15396099999998,49.17333200000007],[-95.15417499999995,48.99943500000012],[-95.26655599999998,48.999977],[-97.21994000000001,48.99971800000009],[-97.50279199999994,48.99943500000012],[-97.63583399999999,48.99943500000012],[-97.801941,49.000000000000114],[-97.96916199999993,49.00027499999999],[-98.26916499999993,49.00027499999999],[-98.50222799999989,48.99943500000012],[-98.868607,49.000000000000114],[-99.335556,48.99943500000012],[-99.835556,49.000000000000114],[-100.00222799999995,49.000000000000114],[-100.50195300000001,48.99971800000009],[-101.06916799999999,49.000000000000114],[-101.30222299999997,49.00027499999999],[-101.367233,48.99878700000011],[-101.46888699999994,48.99943500000012],[-102.16887699999995,49.000000000000114],[-102.33556399999998,48.99943500000012],[-102.53555299999994,49.00027499999999],[-102.76834099999996,48.99943500000012],[-103.035278,48.99943500000012],[-103.16832699999992,48.99943500000012],[-103.26889,49.000000000000114],[-103.43554699999993,49.00027499999999],[-103.535278,48.99943500000012],[-103.73528299999987,48.99943500000012],[-104.033096,49.00025199999999],[-104.13527699999986,48.99971800000009],[-104.33500699999996,48.99943500000012],[-104.83500700000002,48.99943500000012],[-105.00140399999998,48.99943500000012],[-105.26834100000002,49.000000000000114],[-105.70221699999996,48.99943500000012],[-105.93554699999999,48.99943500000012],[-106.03472899999991,48.99943500000012],[-106.13527699999997,48.99943500000012],[-106.26862299999993,48.99943500000012],[-106.46806300000003,48.99943500000012],[-106.73554999999993,48.99943500000012],[-107.33528100000001,49.000000000000114],[-107.43499800000001,49.000000000000114],[-107.63474300000001,48.99943500000012],[-107.73554999999993,48.99943500000012],[-107.80110199999996,48.99943500000012],[-108.16887700000001,48.99943500000012],[-108.33500699999996,48.99943500000012],[-108.53472899999997,48.99943500000012],[-108.6677699999999,48.99943500000012],[-108.83473200000003,48.99943500000012],[-109.33473200000003,48.99943500000012],[-109.63474299999996,48.99943500000012],[-109.801941,48.99943500000012],[-109.96777299999997,48.99971800000009],[-109.99965700000001,49.000603000000126],[-110.10138699999999,48.99943500000012],[-110.20111099999991,48.99943500000012],[-110.30166599999995,49.000000000000114],[-110.36776699999996,49.000000000000114],[-110.50110599999988,49.000000000000114],[-110.66777000000002,49.000000000000114],[-110.76862299999993,48.99943500000012],[-111.36833199999995,48.99943500000012],[-111.80110199999996,48.99943500000012],[-112.03472899999997,48.99943500000012],[-112.16832699999998,48.99943500000012],[-112.234734,49.000000000000114],[-112.33500699999996,49.000000000000114],[-112.43499799999995,49.000000000000114],[-112.53500399999996,49.000000000000114],[-112.60166900000002,49.000000000000114],[-112.93472300000002,49.000000000000114],[-113.03443900000002,49.000000000000114],[-113.23416099999997,48.99943500000012],[-113.36833200000001,48.99943500000012],[-113.567497,48.99943500000012],[-114.0344389999999,48.99943500000012],[-114.05985999999996,49.000603000000126],[-114.33500700000002,48.99943500000012],[-114.46749899999992,48.99943500000012],[-114.53472899999991,49.000000000000114],[-114.63390399999997,49.000000000000114],[-114.90110800000002,48.99943500000012],[-115.034157,48.99943500000012],[-115.16750299999995,48.99943500000012],[-115.36805700000002,49.000000000000114],[-115.46806300000003,49.000000000000114],[-115.56723,49.000000000000114],[-115.60138699999987,48.99943500000012],[-115.734444,48.99943500000012],[-116.04833999999994,48.99971800000009],[-117.00140399999998,48.99971800000009],[-117.03662099999997,49.00312800000012],[-117.06722999999994,48.99971800000009],[-117.20084399999996,48.99943500000012],[-117.234734,49.000000000000114],[-117.30055199999993,49.000000000000114],[-117.567497,49.000000000000114],[-117.83444199999991,49.000000000000114],[-117.86749299999997,48.99943500000012],[-118.00083899999998,48.99943500000012],[-118.13417099999998,48.99943500000012],[-118.36805699999996,48.99943500000012],[-118.76777600000003,48.99943500000012],[-118.96749899999992,48.99943500000012],[-119.13417099999987,48.99943500000012],[-119.26722699999999,48.99943500000012],[-119.46777299999985,48.99943500000012],[-119.86749299999991,48.99943500000012],[-119.93415800000002,48.99943500000012],[-120.034157,48.99943500000012],[-120.53472899999997,48.99943500000012],[-121.08497599999993,48.99971800000009],[-122.10056299999997,49.000000000000114],[-122.33389299999993,49.000000000000114],[-122.43360899999993,49.000000000000114],[-122.56667299999992,49.000000000000114],[-122.69999699999994,49.000000000000114],[-122.76030000000003,48.99943500000012],[-122.81360599999994,49.00527200000005],[-122.83112299999999,49.00860600000004],[-122.86250299999989,49.02221700000001],[-122.87777699999998,49.03221100000002],[-122.87970699999994,49.03443899999996],[-122.881104,49.038605000000075],[-122.87748699999986,49.049438000000066],[-122.87609900000001,49.05138399999993],[-122.8724979999999,49.05443600000007],[-122.86416600000001,49.06166100000013],[-122.85888699999992,49.067497],[-122.85804699999994,49.07276900000011],[-122.859444,49.077217000000076],[-122.86638599999998,49.08110799999997],[-122.87444299999999,49.08360299999998],[-122.89998600000001,49.087211999999965],[-122.91887700000001,49.087211999999965],[-122.94167299999992,49.08249699999993],[-123.02194199999997,49.05165899999997],[-123.03916900000002,49.04249600000014],[-123.04666099999997,49.03333299999997],[-123.048607,49.02721400000013],[-123.04833999999994,49.022491000000116],[-123.04778299999998,49.018326000000116],[-123.03916900000002,49.00527200000005],[-123.03431699999999,48.99943500000012],[-123.09374999999994,48.99943500000012],[-123.11332699999997,49.036658999999986],[-123.13890099999998,49.10721600000011],[-123.14835399999998,49.10833000000008],[-123.20500199999998,49.12360399999994],[-123.20973200000003,49.12721299999998],[-123.247772,49.26527399999998],[-123.24889399999995,49.27360500000003],[-123.24749800000001,49.27555100000012],[-123.09449799999993,49.283938999999975],[-123.00933800000001,49.28194400000007],[-122.943329,49.28416400000009],[-122.92360699999995,49.28833000000003],[-122.91251399999999,49.29332700000009],[-122.87917299999998,49.339157000000114],[-122.87499999999994,49.351387000000045],[-122.85388199999994,49.42999300000014],[-122.85278299999999,49.43610400000006],[-122.85333300000002,49.438880999999924],[-122.86054999999993,49.447487000000024],[-122.87082700000002,49.45721400000002],[-122.87638899999996,49.45555100000007],[-122.87832600000002,49.44943200000006],[-122.876938,49.42999300000014],[-122.87721299999993,49.41499299999998],[-122.881104,49.40277100000003],[-122.88583399999993,49.391936999999984],[-122.90139799999992,49.360550000000046],[-122.91555800000003,49.342216000000064],[-122.93138099999999,49.328049000000135],[-123.00538599999999,49.31954999999999],[-123.03671999999989,49.31321700000001],[-123.04521899999992,49.312550000000044],[-123.06339299999996,49.31321700000001],[-123.08023100000003,49.31554799999998],[-123.23638900000003,49.33888200000007],[-123.25418099999996,49.384720000000016],[-123.25666799999993,49.51277200000004],[-123.25334199999992,49.52304800000013],[-123.24722299999996,49.53499599999998],[-123.20162199999999,49.61571500000014],[-123.1558379999999,49.676102000000014],[-123.15416700000003,49.67943600000001],[-123.15222199999994,49.6855470000001],[-123.15361000000001,49.690269],[-123.15972899999997,49.69915800000007],[-123.16471899999993,49.70221700000002],[-123.16777000000002,49.70221700000002],[-123.17027300000001,49.701103000000046],[-123.24194299999999,49.660544999999956],[-123.24804699999993,49.64860500000009],[-123.24804699999993,49.639717000000076],[-123.26677699999999,49.61737800000003],[-123.26594499999999,49.61038200000013],[-123.265106,49.60788000000002],[-123.26494600000001,49.60371399999997],[-123.26576999999997,49.59838100000013],[-123.26812000000001,49.595551000000114],[-123.27095799999995,49.593215999999984],[-123.27977799999991,49.59005000000002],[-123.34333800000002,49.56137800000005],[-123.381104,49.556655999999975],[-123.39444699999996,49.55193300000013],[-123.43028299999997,49.53832999999997],[-123.48306300000002,49.51666300000011],[-123.49249299999997,49.50972000000013],[-123.495003,49.506943000000035],[-123.49610899999993,49.500275000000045],[-123.49416399999996,49.46859699999999],[-123.491669,49.46360800000002],[-123.48777799999993,49.46054799999996],[-123.47778299999993,49.45526899999999],[-123.47416699999997,49.450829],[-123.47332799999992,49.44110100000012],[-123.47609699999998,49.42193600000002],[-123.47666899999996,49.41915900000009],[-123.48194899999993,49.40998800000011],[-123.48665599999993,49.406097000000045],[-123.506958,49.38943500000005],[-123.512787,49.38638300000014],[-123.51944699999996,49.38388100000009],[-123.526947,49.38221000000004],[-123.53555299999994,49.3813780000001],[-123.54499800000002,49.383331000000055],[-123.60109699999987,49.397490999999945],[-123.60610999999994,49.399994000000106],[-123.67555199999998,49.425269999999955],[-123.77500900000001,49.458327999999995],[-123.85500299999995,49.468879999999956],[-123.86165599999993,49.46665999999999],[-123.88082899999995,49.466385000000116],[-123.88890100000003,49.46804800000007],[-123.89611799999994,49.47054300000008],[-123.95973200000003,49.510551000000135],[-123.96362299999993,49.51332900000011],[-123.98860200000001,49.54166399999997],[-124.06806899999992,49.63388100000003],[-124.07055700000001,49.63804600000003],[-124.07112099999995,49.64444000000009],[-124.0702819999999,49.64971900000006],[-124.05915800000002,49.671104000000014],[-124.03250100000002,49.713882000000126],[-124.02861000000001,49.71915400000006],[-124.021118,49.726379000000065],[-124.00527999999997,49.735825000000034],[-123.99833699999999,49.73888400000004],[-123.987213,49.743050000000096],[-123.97528099999994,49.74527000000012],[-123.95694700000001,49.746101000000124],[-123.94748700000002,49.74499500000013],[-123.94055199999997,49.742493000000024],[-123.93443299999996,49.73943299999996],[-123.92971799999992,49.735825000000034],[-123.876938,49.68332700000008],[-123.83306900000002,49.627486999999974],[-123.82917799999996,49.61693600000007],[-123.82444800000002,49.59582500000005],[-123.82277699999997,49.585548000000074],[-123.82333399999999,49.58138300000007],[-123.82224300000001,49.57305100000008],[-123.79972800000002,49.51944000000003],[-123.79444899999993,49.51027700000003],[-123.78971899999999,49.50666000000007],[-123.78250099999997,49.50416600000011],[-123.77639799999992,49.50388299999997],[-123.76972999999998,49.50471500000003],[-123.76640299999991,49.50666000000007],[-123.76390100000003,49.509438000000046],[-123.76139799999999,49.51332900000011],[-123.75389100000001,49.53777300000007],[-123.76862299999993,49.56193500000012],[-123.77139299999999,49.57222000000007],[-123.77223200000003,49.581940000000145],[-123.77027900000002,49.588043000000084],[-123.74017300000003,49.602599999999995],[-123.73733500000003,49.605270000000075],[-123.73517599999991,49.606937000000016],[-123.69599899999997,49.62360400000006],[-123.68683599999997,49.62560300000007],[-123.67283599999996,49.62527100000011],[-123.63890099999998,49.634995],[-123.61501299999992,49.639160000000004],[-123.56331599999999,49.66721300000012],[-123.54695100000004,49.67721599999999],[-123.53751399999993,49.68499000000003],[-123.53362300000003,49.68971299999998],[-123.53167699999995,49.695541000000105],[-123.53222699999998,49.700546000000145],[-123.53388999999993,49.70193499999999],[-123.54167199999989,49.701103000000046],[-123.54998799999998,49.693877999999984],[-123.56054699999993,49.686935000000005],[-123.57195299999995,49.68082400000009],[-123.58556399999992,49.676102000000014],[-123.67578100000003,49.65304600000002],[-123.69061299999993,49.65105100000011],[-123.73978399999999,49.64588200000003],[-123.75010700000001,49.64521400000001],[-123.79666099999997,49.638329],[-123.803879,49.64083100000005],[-123.8125,49.647491000000116],[-123.93499800000001,49.768326],[-123.93749999999989,49.77276599999999],[-123.93582200000003,49.778046000000074],[-123.93055699999996,49.78527100000014],[-123.91999800000002,49.79249599999997],[-123.88890100000003,49.819717000000026],[-123.88500999999997,49.82360800000009],[-123.88249199999996,49.82749200000012],[-123.87970699999994,49.83277100000009],[-123.87638900000002,49.84221599999995],[-123.87332200000003,49.864158999999916],[-123.87249799999995,49.87110100000001],[-123.872772,49.87721299999998],[-123.88500999999997,49.914993000000095],[-123.889183,49.92276799999996],[-123.89417300000002,49.92721599999993],[-123.90139799999992,49.92887900000005],[-123.91082799999998,49.93027500000011],[-123.920547,49.928604000000064],[-123.92999299999997,49.92971800000004],[-123.93720999999994,49.93221300000005],[-123.94193999999999,49.936104000000114],[-123.94860799999998,49.94387799999993],[-123.95472699999999,49.95304900000008],[-123.95889299999999,49.96221200000008],[-123.929779,49.985321000000056],[-123.929283,49.98949399999998],[-123.92544599999997,49.99415600000009],[-123.92044099999998,49.99732599999999],[-123.88160700000003,50.01499600000011],[-123.87343599999986,50.018326000000116],[-123.860771,50.02166000000011],[-123.85294299999998,50.02299500000004],[-123.84310199999999,50.02365900000012],[-123.80832699999996,50.04027600000012],[-123.79611199999994,50.04444100000012],[-123.75334199999998,50.07638500000013],[-123.74861099999998,50.080276000000026],[-123.74445300000002,50.08693699999992],[-123.74944299999999,50.09665700000005],[-123.82140399999997,50.15221399999996],[-123.83056599999998,50.15693699999997],[-123.846947,50.163321999999994],[-123.97778299999993,50.21388200000001],[-123.98500100000001,50.21610300000009],[-123.99054699999999,50.2158280000001],[-123.99109599999986,50.21166199999999],[-123.98832699999997,50.20749699999999],[-123.96056399999998,50.180550000000096],[-123.94695300000001,50.169441000000006],[-123.93720999999994,50.163321999999994],[-123.92388899999992,50.15860000000009],[-123.90583800000002,50.15638000000007],[-123.88806199999988,50.152489],[-123.882767,50.15082600000005],[-123.87165800000002,50.145546000000024],[-123.80915799999997,50.099998000000085],[-123.8125,50.09054600000013],[-123.81639099999995,50.08610500000003],[-123.85716200000002,50.06688300000013],[-123.86933099999993,50.0580480000001],[-123.87499999999994,50.054214000000115],[-123.87899799999997,50.052380000000085],[-123.916,50.03988300000009],[-123.95465899999988,50.029217000000074],[-123.99526999999989,50.011664999999994],[-123.99916099999996,50.00638600000002],[-124,50.0002750000001],[-123.99916099999996,49.990547000000106],[-123.99526999999989,49.96166200000005],[-123.99249299999997,49.942764000000125],[-123.99109599999986,49.93720999999999],[-123.98860200000001,49.931664000000126],[-123.97972099999998,49.91666399999997],[-123.96721600000001,49.90638000000013],[-123.95140100000003,49.89582800000011],[-123.91972399999992,49.877769],[-123.91471899999993,49.873878000000104],[-123.91111799999999,49.869713000000104],[-123.922234,49.8344350000001],[-123.92639199999996,49.825829],[-123.97277799999989,49.80471],[-123.97833299999996,49.803047000000106],[-123.98581699999994,49.802772999999945],[-123.99194299999994,49.80443600000007],[-124.00418100000002,49.810546999999985],[-124.01012400000002,49.834602000000075],[-124.008621,49.841938000000084],[-124.00728600000002,49.85676999999998],[-124.01806599999998,49.90915699999999],[-124.02166699999987,49.91415400000011],[-124.029449,49.920547000000056],[-124.037781,49.922493000000145],[-124.04222099999998,49.921379],[-124.04472399999997,49.91749600000003],[-124.068893,49.878876000000105],[-124.07195299999995,49.87332200000009],[-124.0702819999999,49.86915600000003],[-124.06261399999988,49.84632899999991],[-124.05877700000002,49.84199100000001],[-124.05860899999999,49.838325999999995],[-124.06028000000003,49.835158999999976],[-124.08444199999991,49.79916400000013],[-124.09028599999999,49.79583000000014],[-124.14555399999995,49.77971600000001],[-124.17694099999989,49.773604999999975],[-124.18582199999997,49.77276599999999],[-124.2702789999999,49.76805100000013],[-124.40416700000003,49.763329000000056],[-124.41361999999998,49.76361099999997],[-124.42916899999994,49.766388000000006],[-124.436394,49.76888300000007],[-124.51194800000002,49.79610400000007],[-124.52166699999992,49.80416100000008],[-124.52443699999998,49.80832700000013],[-124.52583300000003,49.81388099999998],[-124.52583300000003,49.831665000000044],[-124.52749599999987,49.83721200000002],[-124.53278399999999,49.844437000000084],[-124.57195299999995,49.874435000000005],[-124.59137699999997,49.883049000000085],[-124.63221699999997,49.89943699999992],[-124.702789,49.93498999999997],[-124.74194299999999,49.95832800000005],[-124.77306399999992,49.985825000000034],[-124.80332900000002,50.02027100000009],[-124.82556199999999,50.0513840000001],[-124.82972699999999,50.061935000000005],[-124.828056,50.06666600000011],[-124.82140400000003,50.06916000000007],[-124.81304899999992,50.067496999999946],[-124.80695300000002,50.06360600000005],[-124.76722699999988,50.03638500000005],[-124.70333900000003,49.995543999999995],[-124.66805999999991,50.07027400000004],[-124.61694299999999,50.17916100000008],[-124.60193599999997,50.23499300000003],[-124.60138699999993,50.2388840000001],[-124.604172,50.243881000000044],[-124.631104,50.27971600000012],[-124.63890100000003,50.28694200000007],[-124.665009,50.30387900000005],[-124.708618,50.318329000000006],[-124.71362299999987,50.32193799999999],[-124.71501199999994,50.32749200000001],[-124.65778399999994,50.38610800000009],[-124.6519469999999,50.38916000000006],[-124.62609899999995,50.398330999999985],[-124.60193599999997,50.40277100000003],[-124.58055100000001,50.399990000000116],[-124.57555400000001,50.39899400000013],[-124.57122800000002,50.397495000000106],[-124.54998799999993,50.39388300000002],[-124.53362300000003,50.395827999999995],[-124.51999699999999,50.399994000000106],[-124.43415800000002,50.43166400000001],[-124.42054699999994,50.43721000000005],[-124.39862099999999,50.450545999999974],[-124.38305700000001,50.462212000000136],[-124.36138900000003,50.47971300000012],[-124.35193600000002,50.48749500000008],[-124.348053,50.49221800000004],[-124.34528399999988,50.49748999999997],[-124.347778,50.50249500000001],[-124.35527000000002,50.50499700000012],[-124.36389200000002,50.50388299999992],[-124.378601,50.499161000000015],[-124.38445299999995,50.49610100000001],[-124.39388999999989,50.48888400000004],[-124.39778099999995,50.484161000000086],[-124.40055799999993,50.47887400000013],[-124.404449,50.4741590000001],[-124.409157,50.47026800000003],[-124.42749000000003,50.462212000000136],[-124.51834099999991,50.43221299999993],[-124.58383199999997,50.41405100000003],[-124.58833300000003,50.41338300000001],[-124.59999800000003,50.413048],[-124.71167000000003,50.37554900000009],[-124.73916599999995,50.35193600000014],[-124.80332900000002,50.317772000000105],[-124.81582600000002,50.31220999999999],[-124.83000199999992,50.30943300000007],[-124.85056299999991,50.30971499999998],[-124.93916299999995,50.325271999999984],[-125.06388900000002,50.317772000000105],[-125.07224299999996,50.31944299999998],[-125.07833900000003,50.32249500000012],[-125.08416699999998,50.32971999999995],[-125.08889799999997,50.34638200000012],[-125.08750900000001,50.357215999999994],[-125.05666399999996,50.47693600000002],[-125.05194099999989,50.48082000000005],[-125.04499799999996,50.48333000000008],[-125.02667199999996,50.48304700000011],[-125.01806599999998,50.484161000000086],[-124.97112299999998,50.49804700000004],[-124.96528599999999,50.50110600000005],[-124.880829,50.560546999999985],[-124.85973399999989,50.58582300000006],[-124.858047,50.59054600000002],[-124.85444599999994,50.691376000000105],[-124.86888099999999,50.76499899999999],[-124.87805200000003,50.81137799999999],[-124.86749299999997,50.81777199999999],[-124.78943599999991,50.88110400000005],[-124.78694199999995,50.884438000000046],[-124.78751399999993,50.88916000000012],[-124.79998799999998,50.91304800000006],[-124.80277999999998,50.9180530000001],[-124.80583200000001,50.920830000000024],[-124.81916799999993,50.92638400000004],[-124.84999099999993,50.93526500000013],[-124.854172,50.93554700000004],[-124.86138900000003,50.92887900000005],[-124.92443800000001,50.834717000000126],[-124.9449919999999,50.77526899999992],[-124.91221599999994,50.699431999999945],[-124.90139799999997,50.63027199999999],[-124.901947,50.62471000000005],[-124.90361000000001,50.619987000000094],[-124.91111799999999,50.61138200000005],[-124.92887899999994,50.59638200000006],[-125.026947,50.54083300000008],[-125.09944200000001,50.5],[-125.10417199999989,50.49694100000005],[-125.11277799999999,50.48749500000008],[-125.11694299999999,50.47804300000013],[-125.118607,50.471930999999984],[-125.11193800000001,50.45249200000006],[-125.11138899999997,50.44776900000011],[-125.11221299999994,50.44221500000009],[-125.11472299999997,50.436935000000005],[-125.11945300000002,50.432770000000005],[-125.12526700000001,50.42971800000009],[-125.17027299999995,50.4124910000001],[-125.17777999999998,50.41137700000013],[-125.1875,50.4124910000001],[-125.195831,50.41471100000007],[-125.2022169999999,50.417213000000004],[-125.20722999999998,50.42083000000014],[-125.24610899999993,50.462212000000136],[-125.33612099999993,50.47971300000012],[-125.40361000000001,50.47360200000003],[-125.42166099999992,50.46527100000014],[-125.44275699999997,50.45943500000004],[-125.46028099999995,50.457214000000135],[-125.48832700000003,50.45638300000013],[-125.54444899999993,50.49037900000013],[-125.54811099999995,50.492050000000006],[-125.54928599999994,50.494549000000006],[-125.54961399999996,50.497547000000054],[-125.54911799999996,50.501545000000135],[-125.53222700000003,50.62721300000004],[-125.51944700000001,50.647217000000126],[-125.51194800000002,50.65721100000013],[-125.50723299999999,50.66110200000003],[-125.50055699999996,50.66304800000012],[-125.48194899999999,50.664993000000095],[-125.46749899999998,50.668602000000135],[-125.45612299999999,50.67499500000008],[-125.45140100000003,50.67887900000011],[-125.42804699999999,50.705551000000014],[-125.42555199999998,50.71082300000012],[-125.43277,50.71388200000007],[-125.443604,50.714157000000114],[-125.45889299999993,50.713608000000136],[-125.46639999999996,50.713051000000064],[-125.47332799999998,50.70916],[-125.53778099999994,50.669991000000095],[-125.54723399999995,50.661933999999974],[-125.55832699999996,50.64804800000013],[-125.56388900000002,50.63721499999997],[-125.56806899999998,50.62721300000004],[-125.57167099999998,50.61138200000005],[-125.57224300000001,50.605270000000075],[-125.5849,50.57132300000006],[-125.58206899999999,50.56582300000008],[-125.58039099999996,50.56365600000004],[-125.5800549999999,50.559994000000074],[-125.58623499999999,50.53665900000004],[-125.610229,50.48932600000006],[-125.61238900000001,50.486492000000055],[-125.63722200000001,50.445540999999935],[-125.65167200000002,50.441375999999934],[-125.69249000000002,50.42999300000014],[-125.700287,50.42804700000005],[-125.70584099999996,50.427773000000116],[-125.71611000000001,50.43221299999993],[-125.84665699999994,50.502777000000094],[-125.86472300000003,50.49526999999995],[-125.93028299999992,50.47360200000003],[-125.95221700000002,50.46888000000013],[-125.968613,50.46888000000013],[-126.06331599999999,50.470825000000104],[-126.159157,50.484992999999974],[-126.193329,50.49027300000006],[-126.26777599999997,50.50499700000012],[-126.27500899999995,50.50750000000005],[-126.27916700000003,50.51166500000005],[-126.2808379999999,50.51583099999999],[-126.279449,50.520546000000024],[-126.276947,50.52471200000008],[-126.22670699999998,50.53628500000002],[-126.18665299999998,50.54840500000006],[-126.18559999999997,50.566322000000014],[-126.23805199999998,50.59137700000002],[-126.25167799999991,50.60971800000004],[-126.26418299999995,50.61554700000005],[-126.27500899999995,50.627486999999974],[-126.27471899999995,50.63166000000007],[-126.266953,50.63472000000013],[-126.02006499999999,50.66188000000011],[-126.014725,50.66204800000014],[-125.90856200000002,50.66404699999998],[-125.73832699999997,50.682213000000104],[-125.69387799999993,50.70471200000003],[-125.62249799999995,50.750000000000114],[-125.61776700000001,50.754166000000055],[-125.54305999999991,50.8638840000001],[-125.53778099999994,50.87193300000007],[-125.51000999999997,50.92166100000003],[-125.50723299999999,50.92694100000011],[-125.50556899999998,50.93332700000002],[-125.50666799999993,50.94554100000005],[-125.50834699999996,50.95110299999999],[-125.55166600000001,51.0422210000001],[-125.56555200000003,51.05638099999999],[-125.58167999999995,51.07222000000013],[-125.59306299999997,51.07888000000014],[-125.610817,51.08776900000004],[-125.63390400000003,51.09693900000008],[-125.63722200000001,51.096382000000006],[-125.63890100000003,51.09027100000009],[-125.639183,51.07721700000002],[-125.63806199999999,51.06610100000006],[-125.583328,50.97470900000002],[-125.61028299999987,50.89888000000002],[-125.69110099999995,50.771378000000084],[-125.73110999999989,50.735550000000046],[-125.81527699999987,50.70721400000008],[-125.96383700000001,50.688660000000084],[-126.12516799999997,50.678989000000115],[-126.13100400000002,50.6786580000001],[-126.133667,50.678825000000074],[-126.13799999999998,50.681827999999996],[-126.13917500000002,50.68349500000011],[-126.22222899999991,50.69110100000006],[-126.21362299999993,50.70388000000014],[-126.20889299999999,50.70777099999998],[-126.20333899999997,50.711104999999975],[-126.11165599999993,50.75388300000009],[-126.19888299999997,50.85582700000009],[-126.26944700000001,50.85804700000011],[-126.37609899999995,50.85527000000002],[-126.39750699999996,50.84860200000003],[-126.40306099999998,50.84526800000003],[-126.42166099999997,50.8294370000001],[-126.42748999999992,50.8261030000001],[-126.43415799999997,50.82360800000009],[-126.44304699999998,50.82166300000006],[-126.49333199999995,50.81638300000003],[-126.55277999999998,50.834717000000126],[-126.55695300000002,50.838882000000126],[-126.55972299999996,50.84388000000013],[-126.557503,50.87665600000008],[-126.55359599999991,50.881377999999984],[-126.53611799999999,50.898048000000074],[-126.531387,50.9019320000001],[-126.501106,50.91609999999997],[-126.49445300000002,50.9180530000001],[-126.48332199999999,50.91915899999998],[-126.47471599999994,50.91749600000003],[-126.468613,50.91443600000014],[-126.464447,50.91027100000014],[-126.45805399999995,50.907211000000075],[-126.36833200000001,50.9019320000001],[-126.358337,50.90138200000007],[-126.24638400000003,50.898604999999975],[-126.22582999999997,50.898604999999975],[-126.21028100000001,50.90277100000009],[-126.20445299999994,50.90554800000001],[-126.18388399999992,50.91860200000008],[-126.17555199999993,50.92582700000014],[-126.17027299999995,50.936653000000035],[-126.17166099999997,50.94638100000009],[-126.17471299999988,50.95054600000009],[-126.17777999999998,50.951385000000016],[-126.181107,50.950829000000056],[-126.18888899999996,50.948875000000044],[-126.20028699999989,50.94249000000002],[-126.20500199999992,50.93832400000008],[-126.21556099999998,50.931107],[-126.228882,50.92610200000013],[-126.24553700000001,50.923325000000034],[-126.30860899999999,50.92527000000001],[-126.412216,50.936104000000114],[-126.42639200000002,50.938599000000124],[-126.5625,50.907767999999976],[-126.56833599999993,50.903877000000136],[-126.58084099999996,50.898604999999975],[-126.66139199999998,50.86804999999998],[-126.67777999999998,50.86638599999998],[-126.72165699999994,50.87609900000001],[-126.80638099999999,50.90915699999999],[-126.81916799999999,50.915824999999984],[-126.90261799999996,50.905098000000066],[-126.90595199999996,50.90410200000008],[-126.91711399999997,50.903439000000105],[-127.01471700000002,50.903877000000136],[-127.04804999999993,50.91027100000014],[-127.08556399999998,50.921378999999945],[-127.112213,50.931107],[-127.1641689999999,50.932495000000074],[-127.17639200000002,50.92916100000008],[-127.17999299999991,50.92582700000014],[-127.17804699999994,50.92027300000012],[-127.17166099999992,50.91749600000003],[-127.06276699999995,50.88526900000005],[-127.01883700000002,50.868267],[-127.00765999999993,50.867939000000035],[-126.976158,50.870438000000036],[-126.97166400000003,50.86993800000005],[-126.9691699999999,50.86910599999993],[-126.96599600000002,50.86693600000001],[-126.96681999999998,50.86410100000006],[-127.01471700000002,50.81944300000009],[-127.02250700000002,50.817497],[-127.03333299999997,50.81777199999999],[-127.047234,50.82166300000006],[-127.05776999999995,50.828048999999965],[-127.06166100000002,50.832213999999965],[-127.06696299999993,50.835823000000005],[-127.07333399999993,50.838882000000126],[-127.13276699999994,50.862213],[-127.243607,50.89666],[-127.33444199999997,50.90693699999997],[-127.39862099999993,50.92638400000004],[-127.43055699999991,50.9405440000001],[-127.535278,51.000549000000035],[-127.53832999999997,51.005554000000075],[-127.53806299999997,51.008331],[-127.502792,51.097488],[-127.495003,51.0991590000001],[-127.47749299999992,51.097488],[-127.43582199999997,51.08277100000004],[-127.40888999999987,51.071938000000046],[-127.39306599999992,51.06471299999998],[-127.38137799999998,51.05971499999998],[-127.3683319999999,51.055267000000015],[-127.354446,51.051659000000086],[-127.33056599999998,51.04833199999996],[-127.24249299999997,51.04138200000011],[-127.23610699999995,51.041107000000125],[-127.21861299999995,51.040832999999964],[-127.09612299999998,51.04388399999999],[-126.99873400000001,51.05888399999998],[-126.97956099999999,51.06288100000012],[-126.94840199999999,51.06705099999999],[-126.87339800000001,51.07288399999999],[-126.86672999999996,51.07271600000013],[-126.82656899999995,51.06705099999999],[-126.81689499999987,51.06471600000003],[-126.69167299999998,51.110550000000046],[-126.68694299999999,51.1147160000001],[-126.65278599999999,51.149994000000106],[-126.65139799999997,51.15332000000001],[-126.65110799999997,51.15749400000004],[-126.654449,51.185822000000144],[-126.65527299999997,51.18776699999995],[-126.65834000000001,51.19276400000007],[-126.66251399999993,51.19499200000001],[-126.67582700000003,51.19387800000004],[-126.67916899999994,51.19276400000007],[-126.68167099999994,51.18859900000007],[-126.68250299999994,51.176383999999985],[-126.68167099999994,51.172768000000076],[-126.68331899999998,51.165268000000026],[-126.68831599999999,51.157211000000075],[-126.69666299999994,51.14777400000014],[-126.71749899999998,51.132767000000115],[-126.84055299999989,51.094936000000075],[-126.84654999999992,51.093105000000094],[-126.85589599999997,51.09210200000007],[-126.927887,51.08493800000008],[-127.14111299999996,51.060272000000055],[-127.19249000000002,51.057213000000104],[-127.20667300000002,51.05638099999999],[-127.23832700000003,51.05693800000006],[-127.32668299999995,51.05971499999998],[-127.3408429999999,51.06082200000009],[-127.35916099999992,51.063323999999966],[-127.38861099999991,51.06805400000002],[-127.49273700000003,51.11488300000008],[-127.50985000000003,51.117359000000135],[-127.53376000000003,51.10808200000014],[-127.556107,51.09999800000003],[-127.63194299999998,51.09193400000004],[-127.64943699999998,51.092216000000064],[-127.66665599999988,51.09526800000003],[-127.67944299999988,51.10110500000013],[-127.78999299999992,51.165543000000014],[-127.79611199999994,51.197212000000036],[-127.795837,51.202217000000076],[-127.787216,51.226097000000095],[-127.78472899999991,51.23137699999995],[-127.76194800000002,51.249435000000005],[-127.59973100000002,51.28943599999997],[-127.59306300000003,51.290833000000134],[-127.56555199999997,51.29305299999993],[-127.53999299999998,51.29444100000006],[-127.45140099999998,51.29193900000013],[-127.4036099999999,51.2824940000001],[-127.37554899999998,51.27443700000009],[-127.36472299999997,51.2741620000001],[-127.23110999999994,51.28611000000012],[-127.22222899999991,51.287216],[-127.21444699999995,51.290549999999996],[-127.203888,51.29860700000012],[-127.14334100000002,51.318329000000006],[-127.1330569999999,51.32555400000007],[-127.12693799999994,51.334991],[-127.11776700000001,51.35749800000008],[-127.11110699999989,51.37721300000004],[-127.10973399999995,51.383331],[-127.11028299999992,51.389717000000076],[-127.11582899999996,51.391662999999994],[-127.12249800000001,51.389160000000004],[-127.13054699999998,51.38193499999994],[-127.13417099999998,51.37721300000004],[-127.14417300000002,51.358047],[-127.18250299999994,51.326942000000145],[-127.18804899999998,51.32360799999998],[-127.20834400000001,51.315826000000015],[-127.24749800000001,51.30638099999993],[-127.28056300000003,51.30110200000013],[-127.29055800000003,51.30054500000006],[-127.36749299999991,51.298881999999935],[-127.39584400000001,51.30221599999993],[-127.45221699999996,51.315826000000015],[-127.462784,51.34166000000005],[-127.55444299999999,51.332497000000046],[-127.57000699999998,51.32860599999998],[-127.75499699999989,51.31944299999998],[-127.76390100000003,51.31944299999998],[-127.77250699999996,51.3211060000001],[-127.77887699999997,51.32471500000008],[-127.78415699999994,51.33305400000012],[-127.78778099999994,51.34887700000013],[-127.78307299999994,51.356941000000006],[-127.778343,51.36110700000006],[-127.74109599999997,51.38027200000005],[-127.72749299999998,51.38555100000002],[-127.69332899999995,51.39083100000005],[-127.68443300000001,51.39083100000005],[-127.65055799999999,51.40804300000008],[-127.55166600000001,51.468323000000055],[-127.51583900000003,51.51915700000001],[-127.51306199999993,51.52999100000005],[-127.512787,51.53555299999999],[-127.515289,51.5472180000001],[-127.521118,51.56388099999998],[-127.51640299999997,51.587769000000094],[-127.51500699999985,51.59388000000001],[-127.50890399999997,51.60471299999995],[-127.50055700000001,51.61360900000011],[-127.48805199999998,51.619438000000116],[-127.44444299999998,51.62999000000008],[-127.37609900000001,51.6449970000001],[-127.32584400000002,51.651382000000126],[-127.23332199999999,51.66249099999999],[-127.09584000000001,51.668052999999986],[-126.95344499999999,51.658325000000104],[-126.94693799999993,51.65765799999997],[-126.93778199999997,51.65532700000006],[-126.88377400000002,51.64949400000006],[-126.708054,51.64193700000004],[-126.66332999999986,51.64888000000002],[-126.65527299999997,51.651382000000126],[-126.620003,51.679993000000024],[-126.60694899999993,51.706940000000145],[-126.60527000000002,51.713051000000064],[-126.60582699999992,51.71943699999997],[-126.60777300000001,51.72499099999993],[-126.63555899999989,51.76971400000002],[-126.63944999999995,51.77388000000013],[-126.660278,51.7922210000001],[-126.66528299999999,51.772491000000116],[-126.66665599999999,51.766388000000006],[-126.66251399999993,51.7472150000001],[-126.65387699999991,51.73249100000004],[-126.64362299999999,51.719154],[-126.63999899999999,51.709991],[-126.641388,51.7052690000001],[-126.64388999999994,51.70110299999999],[-126.64750700000002,51.697768999999994],[-126.69304699999998,51.66471100000001],[-126.703056,51.66443600000002],[-126.91521499999999,51.68243800000005],[-126.96421799999996,51.6866040000001],[-126.97788199999997,51.69060500000006],[-127.05387899999988,51.697768999999994],[-127.07501199999996,51.697768999999994],[-127.14055599999995,51.694435000000055],[-127.27416999999997,51.68332700000002],[-127.3999859999999,51.66971600000005],[-127.41583300000002,51.665824999999984],[-127.42582699999997,51.66666399999997],[-127.43222000000003,51.66832700000009],[-127.43554699999987,51.67110399999996],[-127.43971299999993,51.674713],[-127.44167299999992,51.68027500000011],[-127.42748999999998,51.73193400000014],[-127.364441,51.768326000000116],[-127.36193800000001,51.77166000000011],[-127.359444,51.77721400000007],[-127.33917200000002,51.83915699999994],[-127.33721899999989,51.851387000000045],[-127.33999599999999,51.86110699999995],[-127.34555099999994,51.864159000000086],[-127.35109699999992,51.863609000000054],[-127.35694899999999,51.86027500000006],[-127.44833399999987,51.77721400000007],[-127.5719529999999,51.706940000000145],[-127.58556399999986,51.67777300000006],[-127.54638699999992,51.62748699999992],[-127.55860899999999,51.543884000000105],[-127.56111099999998,51.53860500000013],[-127.57417299999997,51.51888300000007],[-127.58139,51.50943799999999],[-127.63583399999999,51.46054800000013],[-127.640289,51.458602999999925],[-127.659157,51.4574970000001],[-127.70639,51.45638300000013],[-127.71639999999996,51.457214000000135],[-127.72389199999992,51.45943500000004],[-127.73029300000002,51.46305100000012],[-127.75473,51.479988000000105],[-127.75917099999992,51.48416100000003],[-127.76083399999993,51.48971599999993],[-127.75974300000001,51.49443800000006],[-127.74416400000001,51.498329000000126],[-127.712784,51.50443999999999],[-127.787216,51.56027199999994],[-127.87416099999996,51.66332200000005],[-127.87805200000003,51.67388199999999],[-127.88999899999999,51.798332000000016],[-127.88944999999995,51.807770000000005],[-127.886124,51.85221899999999],[-127.88474299999996,51.858604000000014],[-127.86971999999997,51.89527099999998],[-127.86609599999997,51.89999399999999],[-127.86165599999987,51.90416000000005],[-127.83306899999997,51.91999100000004],[-127.82055699999995,51.92665900000003],[-127.79638699999998,51.938599000000124],[-127.78971899999999,51.941101],[-127.76611300000002,51.94693799999993],[-127.73805199999993,51.949715000000026],[-127.66443600000002,51.95388000000003],[-127.65527299999997,52.04027600000006],[-127.65387699999991,52.04638699999998],[-127.65139799999997,52.051659000000086],[-127.64527900000002,52.06193499999995],[-127.62943999999999,52.08832600000005],[-127.62581599999999,52.09304799999995],[-127.61749299999997,52.10193600000014],[-127.58029199999993,52.129158000000075],[-127.52555799999993,52.14721700000001],[-127.49944299999993,52.15165700000006],[-127.48055999999997,52.15109999999993],[-127.47721899999999,52.15054300000003],[-127.46528599999988,52.14388300000002],[-127.46140300000002,52.13304900000014],[-127.46250899999995,52.112495000000024],[-127.46611000000001,52.10777300000012],[-127.47556299999997,52.099716000000114],[-127.48249799999996,52.09693900000002],[-127.49833699999999,52.093323],[-127.50834700000001,52.093323],[-127.51834100000002,52.09443699999997],[-127.52722199999994,52.09582500000005],[-127.53500400000001,52.098877000000016],[-127.55277999999998,52.10110500000013],[-127.56276700000001,52.10082999999992],[-127.57167099999998,52.098877000000016],[-127.58444199999991,52.09360500000008],[-127.58889799999992,52.089714000000015],[-127.61416600000001,52.035828000000095],[-127.61332699999997,52.0324940000001],[-127.59416199999998,52.03555300000011],[-127.58612099999993,52.03804800000012],[-127.420837,52.12027000000012],[-127.43360899999999,52.131659999999954],[-127.45056199999999,52.16915900000009],[-127.45249899999988,52.17388200000005],[-127.45305599999995,52.17999300000014],[-127.44972199999995,52.18277000000006],[-127.37609900000001,52.21693400000004],[-127.35417199999995,52.22470900000013],[-127.33138999999994,52.23027000000002],[-127.30027799999993,52.22832500000004],[-127.29110700000001,52.229431000000034],[-127.28443900000002,52.231934000000024],[-127.24526999999995,52.248878000000104],[-127.23944099999994,52.25222000000002],[-127.19304699999998,52.29083300000008],[-127.18582200000003,52.30027000000001],[-127.17749000000003,52.3097150000001],[-127.17166099999992,52.31249200000002],[-127.16361999999987,52.314156000000025],[-127.04276999999996,52.309158000000025],[-127.01251200000002,52.3063810000001],[-127.00499699999995,52.30360400000001],[-126.99861099999993,52.29860700000012],[-126.964447,52.27166],[-126.94526699999994,52.25610400000005],[-126.93804899999986,52.24694100000005],[-126.93611099999998,52.24137900000011],[-126.93554699999999,52.23526800000002],[-126.82749899999999,52.1280440000001],[-126.75195300000001,52.07860599999998],[-126.71193700000003,52.04444100000006],[-126.69415300000003,52.028877000000136],[-126.691101,52.02388000000008],[-126.68388399999998,51.99971799999997],[-126.67804699999994,51.99054700000005],[-126.67388899999997,51.98638200000005],[-126.66944899999999,51.98360400000007],[-126.66832699999998,51.98554999999993],[-126.66776999999996,51.99110400000012],[-126.66583300000002,52.03138000000013],[-126.66665599999999,52.036384999999996],[-126.66972399999997,52.04193900000001],[-126.73805199999987,52.113052000000096],[-126.76363399999991,52.13249200000007],[-126.81722999999988,52.166100000000085],[-126.83112299999999,52.17193599999996],[-126.85555999999997,52.17804700000005],[-126.86305199999993,52.18110700000011],[-126.88027999999986,52.190544000000045],[-126.90055799999999,52.20526899999999],[-126.90666199999993,52.21527100000014],[-126.94082600000002,52.30387900000005],[-126.94027699999998,52.31082200000003],[-126.93611099999998,52.32249500000006],[-126.932503,52.32721700000013],[-126.920837,52.33360300000004],[-126.87361099999998,52.35083000000009],[-126.82084700000001,52.36388399999993],[-126.81416299999995,52.365273000000116],[-126.78888699999999,52.369987000000094],[-126.77667199999996,52.37027000000006],[-126.76194800000002,52.370543999999995],[-126.73638900000003,52.366386000000034],[-126.73166700000002,52.36776700000007],[-126.73249800000002,52.37387799999999],[-126.73665599999998,52.378044000000045],[-126.75167799999991,52.388329],[-126.76363399999991,52.39332600000006],[-126.79277000000002,52.39554600000008],[-126.91027799999995,52.37387799999999],[-126.92610200000001,52.37082700000013],[-126.94110099999995,52.366386000000034],[-126.948036,52.36388399999993],[-126.95973199999997,52.357215999999994],[-126.96972699999998,52.34165999999999],[-126.97444200000001,52.33776899999992],[-126.98137699999995,52.33526599999999],[-127.00279199999994,52.334991000000116],[-127.08249699999993,52.334991000000116],[-127.14111299999996,52.34804500000001],[-127.15778399999999,52.35249299999998],[-127.186394,52.38082099999997],[-127.22805800000003,52.453049000000135],[-127.23610699999995,52.50555400000013],[-127.23665599999998,52.51166500000005],[-127.23416099999997,52.51721199999997],[-127.19695299999995,52.54999500000014],[-127.186394,52.55777000000006],[-127.08112299999993,52.61305199999998],[-127.07417299999997,52.61638599999998],[-127.05915800000002,52.62082700000008],[-127.00446299999999,52.626937999999996],[-126.99638399999998,52.62860100000006],[-126.989441,52.631935000000055],[-126.97972099999998,52.639434999999935],[-126.97609699999998,52.64388300000013],[-126.924713,52.71471400000013],[-126.92223399999995,52.71888000000001],[-126.92166099999997,52.72582200000011],[-126.92250100000001,52.73110200000002],[-126.966949,52.828606000000036],[-126.97112300000003,52.83277100000004],[-126.975281,52.83554800000013],[-126.98332199999987,52.83776900000004],[-127.01777599999991,52.84554300000002],[-127.02139299999993,52.82777400000009],[-127.01834100000002,52.823608000000036],[-127.00778199999996,52.80888399999998],[-126.98082699999992,52.72443400000003],[-126.98111,52.71749100000005],[-126.98528299999992,52.707497000000046],[-127.04250300000001,52.64777399999997],[-127.04737899999992,52.643463],[-127.05561799999998,52.641815000000065],[-127.13445300000001,52.60943600000013],[-127.24054699999988,52.55777000000006],[-127.25723299999999,52.54583000000014],[-127.28083799999996,52.509162999999944],[-127.28222700000003,52.50305200000008],[-127.28028899999993,52.497489999999914],[-127.27610800000002,52.49332400000003],[-127.26528899999988,52.485550000000046],[-127.25805699999995,52.47721100000001],[-127.25834699999996,52.47304500000007],[-127.26194800000002,52.46749100000011],[-127.26666299999988,52.464157000000114],[-127.33345800000001,52.43389500000001],[-127.40082599999994,52.42443100000014],[-127.46541599999995,52.395477000000085],[-127.48935699999987,52.362072000000126],[-127.61165599999998,52.29471600000005],[-127.61833200000001,52.29193900000013],[-127.72138999999993,52.27471200000008],[-127.73055999999997,52.273604999999975],[-127.739441,52.27388000000002],[-127.74610899999999,52.276657000000114],[-127.75029,52.28166199999998],[-127.80471799999998,52.248878000000104],[-127.84277299999997,52.2241590000001],[-127.84528399999999,52.21943700000003],[-127.85249299999987,52.20999100000006],[-127.85833699999995,52.206657000000064],[-127.86389200000002,52.20749699999993],[-127.86916399999996,52.21110500000003],[-127.87110899999999,52.216385000000116],[-127.87304699999999,52.22332],[-127.90527299999991,52.27887700000008],[-127.86776700000001,52.494995000000074],[-127.86776700000001,52.50054900000009],[-127.86971999999997,52.50610399999999],[-127.87499999999994,52.51027699999992],[-127.88166799999999,52.51249700000011],[-127.89195299999994,52.513329000000056],[-127.89998599999996,52.50999500000006],[-127.92488899999995,52.443886000000134],[-127.92971799999992,52.427547000000004],[-127.92854299999999,52.42421300000001],[-127.92588,52.42121500000013],[-127.916718,52.4148790000001],[-127.90905800000002,52.40738299999998],[-127.90589099999988,52.401549999999986],[-127.90538800000002,52.39788400000009],[-127.95694700000001,52.32444000000004],[-127.96389799999997,52.321663000000115],[-127.972778,52.323326000000066],[-127.995003,52.33055100000013],[-128.0080569999999,52.336937000000034],[-128.01251200000002,52.34110299999992],[-128.05721999999997,52.394713999999965],[-128.05917399999998,52.400269000000094],[-128.06832899999995,52.44776900000005],[-128.06695599999995,52.45388000000014],[-128.05944799999992,52.470267999999976],[-128.05111699999992,52.478874000000076],[-128.0419619999999,52.48777000000001],[-128.03250100000002,52.49527000000012],[-128.00946,52.50860600000004],[-127.97721899999999,52.51971400000008],[-127.96916199999993,52.52166000000011],[-127.96140300000002,52.519440000000145],[-127.95612299999993,52.515831000000105],[-127.89611799999994,52.542220999999984],[-127.891388,52.54638700000004],[-127.88778699999995,52.55110200000007],[-127.8799899999999,52.574164999999994],[-127.87970699999994,52.579720000000066],[-127.88751200000002,52.57777399999998],[-128.0291749999999,52.54166400000008],[-128.04083300000002,52.53582799999998],[-128.0997309999999,52.50305200000008],[-128.1049349999999,52.49238200000008],[-128.118317,52.465546000000074],[-128.14834599999995,52.42221799999999],[-128.2250059999999,52.330826000000116],[-128.23330699999997,52.32193799999999],[-128.27862499999998,52.280823],[-128.28332499999993,52.276657000000114],[-128.28891,52.27332300000012],[-128.295837,52.27082800000011],[-128.30499299999997,52.269439999999975],[-128.39388999999989,52.291382000000056],[-128.32971199999992,52.38027199999999],[-128.29751599999992,52.40054300000003],[-128.29083300000002,52.401657],[-128.28085299999992,52.400825999999995],[-128.27416999999997,52.39804799999996],[-128.267517,52.396660000000054],[-128.260559,52.39916199999993],[-128.255859,52.403320000000065],[-128.22442599999994,52.45971700000007],[-128.2219239999999,52.46527100000009],[-128.22055099999994,52.47137500000014],[-128.22109999999992,52.48443600000007],[-128.228607,52.52304800000002],[-128.23055999999997,52.5283280000001],[-128.238312,52.536658999999986],[-128.24221799999998,52.547775000000115],[-128.241943,52.55471],[-128.239166,52.5669400000001],[-128.18527199999988,52.67110400000013],[-128.14584399999995,52.71998600000006],[-128.120544,52.757217000000026],[-128.13165300000003,52.87638100000004],[-128.17001299999998,52.85665899999998],[-128.17501800000002,52.85193599999997],[-128.22305299999994,52.81249200000008],[-128.22888199999994,52.80860100000001],[-128.23525999999993,52.80582400000009],[-128.249725,52.8013840000001],[-128.2744449999999,52.79943800000001],[-128.300293,52.800270000000125],[-128.33999600000004,52.80554999999998],[-128.42611699999998,52.81749700000012],[-128.43612699999994,52.818886000000134],[-128.441101,52.82276900000005],[-128.48776199999986,52.873604000000114],[-128.49359100000004,52.882767000000115],[-128.495544,52.88749699999994],[-128.498871,52.903602999999976],[-128.50640899999996,52.96305099999995],[-128.51556399999998,53.01998899999995],[-128.539734,53.13193499999994],[-128.62554899999992,53.20221700000002],[-128.66140699999994,53.20221700000002],[-128.66082799999992,53.196938000000046],[-128.66305499999999,53.19082600000007],[-128.66723599999995,53.18749200000008],[-128.676666,53.18776700000012],[-128.68527199999994,53.189430000000016],[-128.70111099999997,53.195541000000105],[-128.78832999999997,53.23971599999999],[-128.794739,53.24332400000009],[-128.84887699999996,53.27582600000005],[-128.85888699999998,53.28360700000013],[-128.866394,53.292220999999984],[-128.86944600000004,53.2972180000001],[-128.87832599999996,53.31638300000003],[-128.88558999999998,53.37437800000009],[-128.88798499999996,53.42496500000004],[-128.92186000000004,53.45360199999999],[-128.95916699999998,53.50277700000004],[-128.97332799999998,53.54749300000003],[-128.97277799999995,53.55304700000005],[-128.966095,53.55609900000013],[-128.80499299999997,53.56999200000001],[-128.79501300000004,53.56860400000011],[-128.78832999999997,53.56499500000007],[-128.783325,53.561104],[-128.77972399999987,53.556938000000116],[-128.69250499999998,53.48526800000013],[-128.55862399999995,53.41387900000012],[-128.523621,53.396660000000054],[-128.446014,53.413158000000124],[-128.44517499999995,53.41599300000007],[-128.4295039999999,53.429824999999994],[-128.1897279999999,53.459991],[-128.15945399999993,53.455826],[-128.14862099999993,53.45360599999998],[-128.13192699999996,53.448875000000044],[-128.105255,53.44054399999999],[-128.09387199999998,53.43305200000003],[-128.07081600000004,53.39411499999994],[-128.03488200000004,53.36928900000004],[-128.00598099999996,53.34705699999995],[-127.95195000000001,53.32610299999993],[-127.94999699999988,53.32138100000003],[-127.951683,53.309990000000084],[-127.95388799999995,53.30416100000008],[-127.95694700000001,53.28138000000007],[-127.95527600000003,53.26583099999999],[-127.95111099999997,53.25638600000008],[-127.94611399999985,53.25222000000002],[-127.87526700000001,53.22443399999992],[-127.87027,53.22276300000004],[-127.868607,53.233879],[-127.86776700000001,53.23971599999999],[-127.87138399999998,53.244155999999975],[-127.92259999999993,53.273685],[-127.93297599999994,53.29332399999993],[-127.92408,53.31815300000011],[-127.92593399999993,53.33075000000002],[-127.98805199999998,53.35388199999994],[-128.0716549999999,53.43138099999999],[-128.09387199999998,53.451935000000105],[-128.12692300000003,53.48110200000002],[-128.16528299999993,53.483879000000115],[-128.18331899999993,53.48416100000003],[-128.3013919999999,53.47832499999993],[-128.45187399999992,53.50332300000008],[-128.4534,53.49965699999996],[-128.45640600000002,53.496822000000066],[-128.48156700000004,53.487987999999916],[-128.49021900000002,53.485325000000046],[-128.53340100000003,53.47832499999993],[-128.54457100000002,53.47899200000006],[-128.54937699999994,53.48082399999993],[-128.81304899999992,53.619155999999975],[-128.81664999999998,53.62332200000009],[-128.81805399999996,53.64471400000008],[-128.81750499999993,53.65026899999998],[-128.81390399999998,53.65693699999997],[-128.808899,53.66165900000004],[-128.78417999999988,53.675552000000096],[-128.77279699999997,53.73333000000014],[-128.79388399999988,53.76499899999993],[-128.793335,53.77054600000008],[-128.79110699999995,53.776657],[-128.7705689999999,53.79583000000008],[-128.67767300000003,53.83977500000009],[-128.67384300000003,53.84160600000007],[-128.66551200000004,53.84460800000011],[-128.66067499999997,53.845439999999996],[-128.65583799999996,53.84360500000008],[-128.64482099999987,53.83710500000012],[-128.64166299999994,53.83477000000005],[-128.60360699999995,53.842216000000064],[-128.59387199999998,53.839714000000015],[-128.47720299999997,53.82860599999998],[-128.47137499999997,53.832497000000046],[-128.47555499999999,53.842216000000064],[-128.482758,53.85082999999992],[-128.48944099999994,53.85416399999991],[-128.498871,53.856941000000006],[-128.5100099999999,53.85916100000003],[-128.53030399999994,53.86166400000002],[-128.53832999999992,53.860275],[-128.54501299999998,53.85721600000005],[-128.55306999999988,53.85610200000008],[-128.61726399999992,53.868546000000094],[-128.65962199999996,53.8828850000001],[-128.662598,53.885216000000014],[-128.66461200000003,53.88821800000011],[-128.67903099999995,53.90752400000002],[-128.67869599999995,53.91085799999996],[-128.66686999999996,53.92285900000013],[-128.66072099999997,53.928524000000095],[-128.6480709999999,53.94943200000006],[-128.63946499999997,53.96054799999996],[-128.59832799999998,54.02693899999997],[-128.60055499999993,54.03166199999998],[-128.60916099999997,54.03138000000007],[-128.61663799999997,54.029160000000104],[-128.67861899999997,54.00360900000004],[-128.68527199999994,54.000832000000116],[-128.68890399999998,53.99415600000003],[-128.6955569999999,53.976097000000095],[-128.7228389999999,53.94404600000007],[-128.724991,53.94021600000008],[-128.727661,53.93671000000006],[-128.73100299999993,53.93354799999992],[-128.79943799999995,53.87499200000002],[-128.915283,53.787216],[-128.93194600000004,53.774711999999965],[-128.98361199999994,53.76221499999997],[-129.10497999999995,53.72026800000009],[-129.1180419999999,53.71415700000006],[-129.12359599999996,53.710274000000084],[-129.21749899999992,53.64027400000009],[-129.232483,53.62582400000014],[-129.2380369999999,53.61332700000014],[-129.239441,53.60193600000002],[-129.236938,53.53721600000006],[-129.231384,53.50083200000006],[-129.23443599999996,53.46193700000009],[-129.234985,53.456100000000106],[-129.23748799999993,53.43360099999995],[-129.27279699999997,53.37915800000002],[-129.30334499999992,53.38499499999995],[-129.333893,53.39749100000006],[-129.353607,53.40776800000003],[-129.518616,53.51499899999999],[-129.62914999999987,53.58776900000004],[-129.686127,53.630272000000105],[-129.83084099999996,53.74721500000004],[-129.86111499999998,53.76527399999998],[-129.912781,53.79833200000013],[-130.04501300000004,53.88304900000014],[-130.050293,53.88694000000004],[-130.099152,53.94193300000006],[-130.10137899999995,53.946655000000135],[-130.09136999999987,54.066101],[-130.09082,54.071662999999944],[-130.07693499999993,54.114441000000056],[-130.073334,54.12082700000013],[-130.065002,54.132209999999986],[-130.051666,54.14860500000009],[-130.04666099999997,54.15332000000012],[-129.86361699999998,54.213051000000064],[-129.84887700000002,54.21749100000011],[-129.83194000000003,54.21943699999997],[-129.78205899999995,54.21060199999994],[-129.72637899999995,54.20077100000009],[-129.69738799999993,54.194435000000055],[-129.68756099999996,54.19093300000003],[-129.644165,54.18193800000006],[-129.63333099999994,54.17999300000008],[-129.6141659999999,54.17891700000007],[-129.591949,54.18582200000009],[-129.470825,54.235825000000034],[-129.47000100000002,54.23721299999994],[-129.474426,54.239990000000034],[-129.48275799999988,54.243050000000096],[-129.5114139999999,54.244155999999975],[-129.51889,54.24193600000012],[-129.56140099999993,54.22693599999997],[-129.56777999999997,54.223877000000016],[-129.68238799999995,54.22160299999996],[-129.68823199999997,54.223099000000104],[-129.77654999999993,54.234767999999974],[-129.83666999999997,54.23832700000014],[-129.8549799999999,54.23804500000006],[-129.87136799999996,54.23526800000013],[-129.966949,54.20694000000003],[-129.97997999999995,54.20082900000011],[-129.9916689999999,54.19276400000001],[-130.037506,54.1730500000001],[-130.10443099999998,54.154434000000094],[-130.113312,54.15387700000002],[-130.122772,54.154434000000094],[-130.131104,54.15721099999996],[-130.19168099999996,54.19332100000008],[-130.22805800000003,54.25860600000004],[-130.238586,54.29499800000008],[-130.2611389999999,54.34276599999998],[-130.27584799999994,54.34971600000006],[-130.28250100000002,54.34638200000006],[-130.332764,54.329720000000066],[-130.34887700000002,54.32694200000009],[-130.39138799999995,54.33027600000008],[-130.45166,54.33665500000012],[-130.45916699999998,54.3386000000001],[-130.48111,54.36471599999999],[-130.48388699999998,54.401657000000114],[-130.4763789999999,54.430550000000096],[-130.47360199999997,54.43582200000003],[-130.433624,54.49665800000014],[-130.42999299999997,54.56249200000008],[-130.4397279999999,54.612213],[-130.44055200000003,54.617493000000024],[-130.438599,54.623604000000114],[-130.43277,54.62748700000003],[-130.42556799999994,54.62971500000003],[-130.41665599999993,54.630272000000105],[-130.40750099999997,54.62860100000006],[-130.39779699999997,54.62638100000004],[-130.38946499999992,54.62332200000003],[-130.37554899999992,54.616661000000136],[-130.33215299999995,54.578552],[-130.28167699999995,54.528381000000024],[-130.2227779999999,54.47193100000004],[-130.06304899999986,54.33998900000012],[-130.05776999999995,54.33610500000009],[-130.03723100000002,54.3261030000001],[-130.020844,54.31999200000001],[-129.9930419999999,54.31221000000005],[-129.98275799999993,54.31110400000006],[-129.96581999999995,54.313049000000035],[-129.95916699999998,54.31610099999995],[-129.95584099999985,54.322495],[-129.959717,54.32694200000009],[-129.96722399999993,54.32888000000003],[-129.98165900000004,54.32443999999998],[-129.99054,54.32388300000008],[-130.02362099999993,54.33554800000002],[-130.0386049999999,54.341934000000094],[-130.043884,54.34582499999999],[-130.14779699999997,54.44193300000012],[-130.31382799999994,54.58626900000007],[-130.36721799999992,54.635268999999994],[-130.37222299999996,54.64471400000008],[-130.374146,54.65499100000005],[-130.36859100000004,54.66777000000013],[-130.358612,54.677490000000034],[-130.352783,54.6813810000001],[-130.339722,54.687492000000134],[-130.32501200000002,54.692214999999976],[-130.24386599999997,54.70777100000009],[-130.23553499999997,54.70916000000011],[-130.22582999999997,54.708885000000066],[-130.17193599999996,54.70360600000009],[-130.16195700000003,54.7011030000001],[-130.15362500000003,54.69832600000001],[-130.10110499999996,54.67166099999997],[-130.075287,54.657767999999976],[-130.06887800000004,54.648604999999975],[-130.065002,54.644440000000145],[-130.054169,54.63665800000001],[-130.0269469999999,54.62304700000004],[-130.00058,54.61471599999993],[-129.980835,54.609993000000145],[-129.959991,54.607498000000135],[-129.910278,54.60555299999993],[-129.968323,54.62193300000007],[-130.0044559999999,54.632767000000115],[-130.02807599999994,54.641936999999984],[-130.19473299999999,54.72332],[-130.20166,54.72693600000008],[-130.20111099999986,54.73249099999998],[-130.17388899999992,54.84665699999999],[-130.171112,54.85166200000003],[-130.16583300000002,54.85665900000009],[-130.16082799999998,54.861382000000106],[-130.05835000000002,54.95277399999998],[-130.045837,54.95999100000006],[-130.03195199999993,54.96527100000014],[-129.94694499999991,54.9704900000001],[-129.9362789999999,54.97115300000007],[-129.92394999999993,54.97032200000007],[-129.91810599999985,54.96882600000009],[-129.90977499999997,54.96466100000009],[-129.90745500000003,54.9621580000001],[-129.65444899999994,54.980545000000006],[-129.646973,54.98276500000003],[-129.64028899999994,54.98582500000009],[-129.62249799999995,54.997772000000055],[-129.62499999999994,55.00249500000001],[-129.79998799999998,55.00694299999998],[-129.866089,55.00666000000001],[-129.875275,55.00610400000005],[-129.883331,55.00471500000003],[-129.90585299999998,54.997772000000055],[-129.91390999999993,54.99638399999992],[-129.964874,55.00343699999996],[-129.97171000000003,55.004608000000076],[-129.97905000000003,55.00893800000006],[-129.98138399999993,55.01160800000014],[-129.98104899999993,55.01493800000014],[-129.9963679999999,55.02416200000005],[-129.97555499999993,55.06693999999993],[-129.96139500000004,55.09332300000011],[-129.95638999999989,55.09804500000001],[-129.84750399999996,55.210548000000074],[-129.72665399999988,55.3386000000001],[-129.66300999999999,55.41221200000001],[-129.64334099999996,55.434158000000025],[-129.63723800000002,55.43804200000005],[-129.62222299999996,55.44249000000002],[-129.60525499999994,55.445267000000115],[-129.584717,55.4438780000001],[-129.541107,55.43804200000005],[-129.52389500000004,55.43998700000003],[-129.50863599999997,55.444435],[-129.48831199999995,55.45360599999992],[-129.47610499999996,55.46138000000013],[-129.47164899999996,55.46720900000014],[-129.47109999999992,55.472762999999986],[-129.475006,55.47693600000008],[-129.48416099999997,55.478600000000085],[-129.62027,55.459434999999985],[-129.63696299999998,55.45665699999995],[-129.679123,55.47315600000013],[-129.68611099999998,55.46749100000005],[-129.69662500000004,55.45399100000003],[-129.69979899999993,55.450993000000096],[-129.70428500000003,55.44966100000005],[-129.70979299999993,55.450657000000035],[-129.712112,55.453327000000115],[-129.71362299999993,55.45616100000012],[-129.78695700000003,55.56666600000011],[-129.78582800000004,55.50277699999998],[-129.779449,55.49360700000011],[-129.772247,55.47943099999992],[-129.78030399999994,55.35971799999999],[-129.78250100000002,55.35360700000007],[-129.81390399999987,55.28971900000005],[-129.81750499999998,55.28333299999997],[-129.90695199999988,55.168052999999986],[-129.911407,55.162491000000045],[-129.92083699999995,55.15193199999999],[-130.028351,55.03638500000011],[-130.068329,54.99694100000005],[-130.07443199999994,54.992767000000015],[-130.081665,54.99054699999999],[-130.09082,54.98999000000009],[-130.10055499999999,54.99054699999999],[-130.10833699999995,54.99249300000008],[-130.11361699999992,54.99638399999992],[-130.12777700000004,55.01388500000007],[-130.16027799999995,55.069717000000026],[-130.16223099999996,55.079994],[-130.1600039999999,55.08610500000009],[-130.11859099999998,55.14249399999994],[-130.11416599999995,55.1483310000001],[-130.0808409999999,55.18471499999998],[-130.06390399999998,55.195266999999944],[-130.04528799999997,55.20416300000005],[-130.03918499999992,55.208046000000024],[-129.948059,55.27638200000001],[-129.94387799999998,55.28221100000002],[-129.94473300000004,55.28721600000006],[-129.94888300000002,55.29583000000014],[-129.96054100000003,55.308884000000035],[-130.00863599999997,55.37082700000008],[-130.101654,55.55638099999999],[-130.103607,55.56666600000011],[-130.128876,55.72221400000012],[-130.12942499999997,55.73276500000003],[-130.128876,55.738602000000014],[-130.126099,55.750275000000045],[-130.12191799999994,55.762496999999996],[-130.116394,55.77499399999999],[-130.11276199999998,55.78166199999998],[-130.10833699999995,55.787216],[-130.09109499999994,55.799995000000024],[-130.079163,55.80804400000005],[-130.06722999999994,55.815826000000015],[-130.0552669999999,55.82388300000014],[-130.03945899999997,55.83832600000005],[-129.96664399999992,55.91220900000002],[-129.962219,55.91777000000002],[-129.9641719999999,55.928329000000076],[-129.97137499999985,55.931663999999955],[-129.97970599999985,55.932213000000104],[-129.99499500000002,55.92777300000006],[-130.0019529999999,55.924713000000054],[-130.00500499999993,55.921661000000086],[-130.01507600000002,55.90917999999999],[-130.01419099999998,56.02388000000013],[-130.0147399999999,56.02582600000005],[-130.0538939999999,56.07555400000001],[-130.08859299999995,56.11804999999998],[-130.22915599999993,56.09027100000014],[-130.3652649999999,56.123878000000104],[-130.4475099999999,56.20638300000007],[-130.46194499999996,56.23526800000013],[-130.48471099999995,56.23943300000013],[-130.53277599999996,56.246384000000035],[-130.5607149999999,56.250000000000114],[-130.62719699999997,56.25860600000004],[-130.720551,56.325554000000125],[-130.755859,56.353049999999996],[-130.77444500000001,56.366104000000064],[-130.84722899999997,56.37443500000012],[-130.92001300000004,56.38249200000013],[-131.05499299999997,56.398048000000074],[-131.07055699999995,56.403602999999976],[-131.12582399999997,56.42416399999996],[-131.1444699999999,56.4347150000001],[-131.164734,56.44526700000006],[-131.205261,56.4658280000001],[-131.22137499999997,56.47248800000011],[-131.290009,56.50054899999998],[-131.31445299999996,56.50999499999995],[-131.5394589999999,56.59665699999999],[-131.55777,56.602219000000105],[-131.578888,56.60332499999993],[-131.61111499999998,56.602219000000105],[-131.81610099999995,56.59499400000004],[-131.824158,56.59693900000002],[-131.82861299999996,56.60083000000009],[-131.85803199999987,56.71888000000013],[-131.86361699999992,56.78611000000012],[-131.86053500000003,56.797775],[-131.86138899999997,56.79972100000009],[-132.10305800000003,56.86666100000002],[-132.09194899999994,56.89360799999997],[-132.06195100000002,56.95971700000007],[-132.03668199999993,57.01305400000001],[-132.02749600000004,57.03638500000005],[-132.22109999999992,57.068054000000075],[-132.316956,57.08387800000003],[-132.33694500000001,57.088325999999995],[-132.32611099999997,57.10054800000012],[-132.26806599999986,57.16304800000006],[-132.25473,57.17471299999994],[-132.226654,57.20471199999997],[-132.35415599999988,57.35443900000013],[-132.36972000000003,57.37082700000002],[-132.37914999999992,57.37943300000012],[-132.45111099999986,57.43526500000007],[-132.471924,57.4511030000001],[-132.4927669999999,57.46665999999999],[-132.50363200000004,57.474158999999986],[-132.61944599999998,57.58332800000005],[-132.75250199999994,57.70943500000004],[-132.76113899999996,57.717765999999926],[-132.76889,57.72665400000011],[-132.78222700000003,57.74527000000012],[-132.79110699999995,57.7586060000001],[-132.795837,57.76888300000007],[-132.796112,57.77387999999996],[-132.80722000000003,57.787773000000016],[-132.81362899999988,57.795547],[-132.82138099999992,57.80443600000007],[-132.87304699999999,57.855270000000075],[-132.88165299999997,57.86360900000011],[-132.92861900000003,57.90554800000001],[-132.937775,57.91332200000005],[-132.964722,57.93332700000002],[-132.99499500000002,57.95166000000006],[-133.03332499999988,57.978874000000076],[-133.043884,57.986938000000066],[-133.05306999999993,57.99471299999999],[-133.058044,57.99943500000006],[-133.070831,58.012215000000026],[-133.087494,58.03333299999997],[-133.09500100000002,58.047775000000115],[-133.104156,58.073051000000135],[-133.107208,58.08332800000011],[-133.11111500000004,58.093323000000055],[-133.13696299999998,58.13582600000012],[-133.1847229999999,58.17610200000013],[-133.19500700000003,58.184158000000025],[-133.21139499999998,58.19638100000003],[-133.233612,58.21138000000013],[-133.3061219999999,58.25721699999997],[-133.36111499999993,58.28054800000001],[-133.43029799999994,58.35999300000009],[-133.408905,58.40026899999992],[-133.38790899999998,58.4120640000001],[-133.4299929999999,58.459160000000054],[-133.55889899999994,58.528046000000074],[-133.73580900000002,58.644713999999965],[-133.80834999999996,58.709991],[-133.826935,58.72609700000004],[-134.087494,58.80832700000013],[-134.2311099999999,58.85193600000002],[-134.245544,58.85694100000006],[-134.32000699999998,58.91609999999997],[-134.325562,58.920830000000024],[-134.33221400000002,58.92971800000004],[-134.33221400000002,58.93526500000013],[-134.325562,58.971100000000035],[-134.3794249999999,59.049164000000076],[-134.38613899999996,59.05804400000011],[-134.45556599999998,59.12248999999997],[-134.46139499999992,59.126656000000025],[-134.4750059999999,59.1336060000001],[-134.53222700000003,59.13221000000004],[-134.56640599999997,59.13054700000009],[-134.65084799999994,59.185546999999985],[-134.67166099999997,59.2002720000001],[-134.675293,59.21471400000007],[-134.68804899999992,59.24332400000009],[-134.7388919999999,59.250275000000045],[-134.95193499999993,59.27999100000011],[-135.09167499999995,59.426941],[-135.07971199999992,59.4447100000001],[-135.06332399999997,59.45804600000008],[-135.03973399999995,59.46693400000004],[-135.030579,59.46804800000001],[-135.02111799999994,59.47109999999992],[-135.017792,59.49887800000005],[-135.015015,59.54055000000011],[-135.01446499999997,59.567497],[-135.09722899999997,59.621376000000055],[-135.12027,59.62165800000014],[-135.13275099999998,59.62276500000007],[-135.1541749999999,59.62721300000004],[-135.17749000000003,59.63693999999998],[-135.336121,59.72665400000005],[-135.47360199999997,59.801933000000076],[-135.50613399999997,59.79388400000005],[-135.823334,59.70555099999996],[-135.949158,59.66915899999998],[-136.07138099999997,59.6574940000001],[-136.12081899999998,59.65165699999994],[-136.16000399999996,59.646660000000054],[-136.20776399999988,59.63943499999999],[-136.31054700000004,59.61249500000014],[-136.34387200000003,59.60277600000012],[-136.3463749999999,59.600548],[-136.29834,59.58360300000004],[-136.239166,59.56137799999999],[-136.23388699999992,59.52582600000005],[-136.2930599999999,59.47609700000004],[-136.29998799999993,59.47109999999992],[-136.371643,59.45249200000006],[-136.46362299999993,59.46971100000013],[-136.46417199999996,59.414153999999996],[-136.46249399999994,59.37221500000004],[-136.46249399999994,59.30249000000009],[-136.46276899999998,59.28943600000002],[-136.48083499999996,59.261939999999925],[-136.49221799999998,59.24971800000014],[-136.55835000000002,59.18637799999999],[-136.58389299999988,59.16332199999994],[-136.61138900000003,59.164711000000125],[-136.71972699999998,59.165268000000026],[-136.80889899999994,59.165268000000026],[-136.88833599999998,59.131935],[-136.94195599999995,59.10943600000007],[-136.96972700000003,59.098328000000095],[-137.03308100000004,59.07749200000006],[-137.25167799999997,59.00610400000011],[-137.296112,58.98998999999998],[-137.31417799999997,58.98110200000002],[-137.33889799999997,58.965546000000074],[-137.392792,58.92832900000002],[-137.42028800000003,58.91415400000011],[-137.42749000000003,58.911377000000016],[-137.44500699999998,58.9074940000001],[-137.46554600000002,58.90609699999993],[-137.47805800000003,58.90721100000013],[-137.48803699999996,58.90915699999999],[-137.49581899999998,58.91193400000009],[-137.5016779999999,58.916382000000056],[-137.50500499999993,58.92027300000012],[-137.50750700000003,58.925552000000096],[-137.50723299999999,58.93776700000001],[-137.50527999999997,58.94415300000014],[-137.49722299999996,58.96415700000006],[-137.48776199999992,58.98249099999998],[-137.47970599999996,58.998046999999985],[-137.49914599999994,59.04138200000011],[-137.54528799999997,59.14305100000013],[-137.566101,59.18693500000006],[-137.59082,59.238602000000014],[-137.910278,59.40804300000008],[-138.11776699999996,59.51666300000005],[-138.30361900000003,59.61305200000004],[-138.49108899999993,59.70832800000005],[-138.5386049999999,59.73220800000007],[-138.615814,59.77416199999999],[-138.647247,59.80555000000004],[-138.65472399999993,59.81471300000004],[-138.66363499999989,59.82916299999994],[-138.66610699999995,59.83443500000004],[-138.66915900000004,59.8449940000001],[-138.67501799999997,59.86693600000001],[-138.69027700000004,59.90693699999997],[-138.97192399999994,59.978600000000085],[-139.04779099999996,59.99749000000003],[-139.116394,60.04138200000011],[-139.161407,60.07027400000004],[-139.18890399999987,60.08888200000007],[-139.183899,60.102219000000105],[-139.15527299999997,60.15499100000005],[-139.13363600000002,60.19443500000011],[-139.12527499999993,60.20777100000009],[-139.08221399999996,60.28749800000003],[-139.06500199999988,60.33027600000008],[-139.06640600000003,60.344153999999946],[-139.06805399999996,60.35221900000005],[-139.51947,60.34471100000002],[-139.67666599999995,60.34054600000002],[-139.77166699999992,60.29249600000003],[-139.866394,60.24443800000006],[-139.91305499999987,60.220824999999934],[-139.97943099999998,60.18776700000012],[-140.005585,60.19387800000004],[-140.45083599999992,60.3097150000001],[-140.471924,60.283882000000006],[-140.493042,60.25777400000004],[-140.50195299999996,60.244713000000104],[-140.52139299999993,60.22221400000012],[-140.94638099999997,60.297775],[-140.995544,60.30721300000005],[-141.00058,60.36666100000002],[-141.001129,60.39943699999998],[-141.00030500000003,60.933051999999975],[-141.0016779999999,60.966384999999946],[-141.00030500000003,62.73304699999994],[-141.00140399999998,63.09999800000014],[-141.00195299999996,63.83277099999998],[-141.00030500000003,63.96638500000006],[-141.00030500000003,64.19970699999999],[-141.00195299999996,65.1327510000001],[-141.00030500000003,65.16609200000005],[-141.00030500000003,65.23275800000005],[-141.00195299999996,65.69941699999998],[-141.00195299999996,66.099426],[-141.0016779999999,66.49941999999999],[-141.00085399999995,66.66638200000011],[-141.00058,66.8660890000001],[-141.0016779999999,67.0663760000001],[-141.00222799999995,67.29914900000006],[-141.00058,67.53248600000012],[-141,67.7327580000001],[-141.00195299999996,67.86581400000006],[-141.00195299999996,68.06581100000005],[-141.00195299999996,68.23275799999999],[-141.0016779999999,68.53276100000011],[-141.00085399999995,68.96554600000002],[-141.00058,69.43247999999994],[-141.00085399999995,69.53221100000002],[-141.002991,69.6423650000001],[-140.982208,69.64276100000001],[-140.90945399999998,69.63916000000012],[-140.83306900000002,69.63526900000005],[-140.81610099999995,69.6336060000001],[-140.79528799999997,69.62719700000008],[-140.77002,69.62164300000006],[-140.738312,69.617752],[-140.61554,69.60832199999993],[-140.488312,69.599426],[-140.39611799999994,69.59609999999998],[-140.26141399999995,69.59664900000013],[-140.21887200000003,69.60081500000001],[-140.17944299999988,69.60636900000003],[-140.12914999999998,69.61499000000009],[-140.10055499999999,69.61747700000001],[-140.084717,69.618042],[-139.94387800000004,69.61886599999997],[-139.9263919999999,69.61859099999998],[-139.88833599999998,69.61665300000004],[-139.81054699999999,69.60664400000002],[-139.78112799999997,69.60220300000009],[-139.605255,69.57554600000003],[-139.57611099999986,69.570831],[-139.67001299999998,69.579163],[-139.68472299999996,69.58137500000004],[-139.77639799999997,69.599716],[-139.7647399999999,69.59082000000006],[-139.75668299999995,69.58665500000006],[-139.73165899999998,69.58109999999999],[-139.60665899999992,69.559418],[-139.573059,69.55609100000004],[-139.5350039999999,69.55386399999998],[-139.351654,69.53637700000013],[-139.14306599999998,69.51081799999992],[-139.116394,69.50555400000013],[-139.10833699999995,69.50166300000006],[-139.10137899999995,69.49136400000003],[-139.092224,69.48165899999998],[-139.069458,69.46331800000013],[-139.05584699999991,69.45498700000007],[-139.04806499999995,69.45082100000013],[-138.975281,69.4149930000001],[-138.957489,69.407486],[-138.93945299999996,69.39999400000005],[-138.88275099999993,69.38472000000013],[-138.83361799999994,69.37330600000007],[-138.7991639999999,69.36415099999999],[-138.769165,69.35386699999998],[-138.75140399999998,69.34637500000002],[-138.64389,69.29136700000004],[-138.621643,69.27304100000003],[-138.616394,69.268326],[-138.60720799999996,69.2586060000001],[-138.60498,69.24748200000005],[-138.44998199999992,69.22915600000005],[-138.269165,69.19636500000007],[-138.25390599999997,69.188309],[-138.21887200000003,69.17330900000007],[-138.17721599999993,69.15998800000011],[-138.14334099999996,69.15081800000007],[-138.06332399999997,69.12942499999997],[-138.03945899999997,69.12359600000013],[-138.00112899999993,69.11526500000002],[-137.69638099999992,69.049713],[-137.594452,69.02777100000014],[-137.41915900000004,68.988876],[-137.25500499999998,68.94831800000009],[-137.22610499999996,68.94497700000005],[-137.19222999999994,68.94386300000008],[-137.13027999999986,68.94497700000005],[-136.9786069999999,68.93193100000013],[-136.97332799999998,68.92720000000003],[-136.966095,68.92330900000013],[-136.95416299999994,68.9202580000001],[-136.78973399999995,68.88192700000008],[-136.74554399999994,68.87525900000009],[-136.68249499999996,68.87191800000005],[-136.65972899999997,68.87498499999998],[-136.64279199999993,68.87803600000001],[-136.63751199999996,68.88415500000002],[-136.630829,68.88916000000006],[-136.61999500000002,68.89193699999998],[-136.522247,68.90914900000001],[-136.50836199999998,68.91026299999999],[-136.47747800000002,68.91081200000013],[-136.42059299999994,68.9015500000001],[-136.39306599999992,68.89721700000007],[-136.358612,68.89387499999992],[-136.255859,68.8894350000001],[-136.14502,68.88581799999997],[-136.0972289999999,68.88220200000012],[-136.0278019999999,68.87303200000002],[-135.98666399999996,68.86499000000009],[-135.85879499999993,68.83897400000006],[-135.831665,68.83194000000003],[-135.54055799999992,68.75248699999997],[-135.519745,68.74581900000004],[-135.49194299999988,68.73525999999998],[-135.484985,68.7310940000001],[-135.45388799999995,68.70942700000006],[-135.40695199999993,68.67997700000012],[-135.36554,68.67581200000012],[-135.21054099999998,68.66137700000002],[-135.1600039999999,68.65721100000013],[-135.14752199999998,68.65887499999997],[-135.14639299999993,68.66387900000012],[-135.21444699999995,68.693039],[-135.25363200000004,68.70694000000015],[-135.34359699999993,68.73776200000003],[-135.48193400000002,68.80941800000011],[-135.50613399999997,68.83248899999995],[-135.500854,68.838593],[-135.48666399999996,68.83943199999999],[-135.45306399999998,68.83804299999997],[-135.4391779999999,68.83554100000009],[-135.40499899999998,68.83194000000003],[-135.341949,68.83166499999999],[-135.33804299999997,68.83499100000006],[-135.34973099999996,68.83804299999997],[-135.42166099999997,68.84887700000002],[-135.49472000000003,68.85497999999995],[-135.52835099999993,68.85636899999997],[-135.56054700000004,68.86026000000004],[-135.595276,68.86943100000002],[-135.60443099999998,68.87303200000002],[-135.61886599999997,68.88136299999996],[-135.62359600000002,68.88610799999998],[-135.6138919999999,68.8894350000001],[-135.33581499999997,68.91775500000011],[-135.241669,68.9269260000001],[-135.22720299999997,68.92553700000008],[-135.21554600000002,68.922485],[-135.20861799999994,68.91832],[-135.1966549999999,68.90971400000006],[-135.19168100000002,68.90498400000001],[-135.18695100000002,68.90026899999998],[-135.121918,68.893326],[-134.97747799999996,68.87831100000005],[-134.95111099999997,68.88108799999992],[-134.91723599999995,68.89804100000003],[-134.89474499999994,68.91249099999993],[-134.87777700000004,68.92082200000004],[-134.85803199999998,68.92776500000002],[-134.845551,68.92942800000014],[-134.81723,68.92581200000006],[-134.80334499999998,68.92303500000003],[-134.74581899999998,68.90748600000006],[-134.708893,68.89276100000012],[-134.6694639999999,68.87330599999996],[-134.64169299999992,68.85664400000002],[-134.49554399999994,68.75221300000004]],[[-93.51972999999992,63.8394320000001],[-93.33999599999999,63.80832700000002],[-93.32972699999993,63.8097150000001],[-93.21749899999998,63.838599999999985],[-93.21611000000001,63.843605000000025],[-93.22500600000001,63.84777100000014],[-93.23638900000003,63.84748799999994],[-93.26750199999992,63.84276600000004],[-93.27888499999995,63.84249100000005],[-93.29167199999995,63.84499400000004],[-93.33389299999993,63.85916099999997],[-93.34333800000002,63.86305200000004],[-93.35749800000002,63.87137600000011],[-93.44193999999993,63.921660999999915],[-93.44888300000002,63.92582700000003],[-93.44972199999995,63.93082400000009],[-93.45249899999999,63.95443700000004],[-93.45111099999997,63.959717000000126],[-93.443329,63.96554600000013],[-93.43388400000003,63.96859699999999],[-93.42361499999993,63.970825000000104],[-93.41305499999999,63.97193099999993],[-93.38999899999993,63.97165699999999],[-93.36471599999993,63.96749100000011],[-93.27305599999994,63.92804700000005],[-93.12222300000002,63.892494],[-92.96028100000001,63.85582699999998],[-92.84167500000001,63.83526599999999],[-92.65194699999995,63.78749800000003],[-92.54972800000002,63.81082200000003],[-92.54055800000003,63.8147130000001],[-92.53056300000003,63.81693999999999],[-92.50750699999998,63.81638300000009],[-92.58389299999999,63.829436999999984],[-92.60694899999987,63.82972000000012],[-92.61915599999992,63.83138300000007],[-92.66915899999998,63.839989],[-92.70695499999994,63.84665699999994],[-92.93554699999999,63.904990999999995],[-92.94248999999996,63.90915700000005],[-92.95611600000001,63.932770000000005],[-92.96528599999999,63.93665299999992],[-93.218887,63.979431000000034],[-93.26611300000002,63.981934000000024],[-93.27639799999997,63.97971300000006],[-93.28805499999999,63.980545000000006],[-93.30110200000001,63.983047000000056],[-93.43666100000002,64.01527400000003],[-93.612213,64.09304800000007],[-93.62721299999998,64.10636900000003],[-93.63500999999991,64.11526500000014],[-93.63583399999999,64.12025500000004],[-93.68998699999992,64.15609699999999],[-93.75167799999991,64.18887300000006],[-93.76112399999988,64.19274899999999],[-93.773056,64.19358799999992],[-93.77972399999999,64.18969700000002],[-93.776947,64.18498199999999],[-93.66500899999994,64.08720400000004],[-93.66000400000001,64.08305400000006],[-93.604172,64.04443400000014],[-93.65472399999993,63.992493000000024],[-93.731674,63.987213],[-93.75917099999992,63.98416100000003],[-93.77055399999995,63.95777100000004],[-93.654449,63.89666000000011],[-93.59973100000002,63.87027000000006],[-93.55360399999995,63.850548],[-93.53332499999999,63.84276600000004],[-93.51972999999992,63.8394320000001]],[[-70.78306599999996,48.38054700000009],[-70.78250100000002,48.34804500000013],[-70.76806599999992,48.35054800000006],[-70.54804999999999,48.35638399999999],[-70.49888599999991,48.353324999999984],[-70.46417200000002,48.3491590000001],[-70.38305700000001,48.331108000000086],[-70.33222999999998,48.31666600000011],[-70.27278099999995,48.298332000000016],[-70.23777799999999,48.282493999999986],[-70.21000700000002,48.26971400000002],[-70.19860799999998,48.26249700000011],[-70.06138599999997,48.23998999999998],[-70.04083300000002,48.244437999999946],[-70.02583300000003,48.24610100000007],[-70.01750199999987,48.24527000000006],[-69.995544,48.23998999999998],[-69.936935,48.22193100000004],[-69.92054699999989,48.216385],[-69.82833900000003,48.166382000000056],[-69.83833300000003,48.173881999999935],[-69.84722899999997,48.181938],[-69.86193800000001,48.198875000000044],[-69.87193300000001,48.212493999999936],[-69.87943999999993,48.22082500000005],[-69.88417099999998,48.22415900000004],[-69.95944199999991,48.26944000000009],[-69.97721899999999,48.27443699999998],[-69.98554999999999,48.27499400000005],[-69.99333200000001,48.27471200000002],[-70.04361,48.267211999999915],[-70.09999099999999,48.267211999999915],[-70.13194299999998,48.26971400000002],[-70.15110800000002,48.27443699999998],[-70.16777000000002,48.279990999999995],[-70.27250700000002,48.325554000000125],[-70.42027300000001,48.36138199999999],[-70.42777999999998,48.36110700000012],[-70.63500999999997,48.39054900000008],[-70.72778299999987,48.4158250000001],[-70.73916599999995,48.42304999999999],[-70.75195299999996,48.42849300000006],[-70.76139799999993,48.431938],[-70.77999899999998,48.435546999999985],[-70.95472699999999,48.45971700000001],[-70.98055999999991,48.46221200000002],[-71.01222199999995,48.46166199999999],[-71.02528399999989,48.45749699999999],[-71.04861499999993,48.44526700000006],[-71.04777499999989,48.44443499999994],[-71.031387,48.44332099999997],[-70.90638699999994,48.423325000000034],[-70.79998799999998,48.40165700000006],[-70.78555299999988,48.39582800000005],[-70.78138699999988,48.391936999999984],[-70.779449,48.386940000000095],[-70.78306599999996,48.38054700000009]],[[-108.13890100000003,71.98165899999998],[-108.15583799999996,71.98082000000005],[-108.17415599999998,71.9833220000001],[-108.18721,71.98664900000006],[-108.18916300000001,71.99192800000003],[-108.19972199999995,72.05053700000008],[-108.19027699999998,72.05554200000012],[-108.1702729999999,72.06442300000003],[-108.16027799999995,72.06275900000003],[-108.13417099999992,72.0560910000001],[-108.07444799999996,72.03414900000001],[-108.06416299999995,72.03027299999997],[-108.06221,72.02526899999998],[-108.06304899999998,72.01944000000015],[-108.069458,72.01304600000009],[-108.07721700000002,72.00721700000008],[-108.10526999999996,71.992752],[-108.12526700000001,71.98387100000002],[-108.13890100000003,71.98165899999998]],[[-85.84722899999997,72.29414400000007],[-85.83721899999995,72.28887900000001],[-85.83721899999995,72.26277199999993],[-85.85166900000002,72.24136400000003],[-85.87748699999992,72.22164900000001],[-85.88917500000002,72.21804799999995],[-85.90834000000001,72.21775800000012],[-85.98111,72.23637399999996],[-86.00584400000002,72.2435910000001],[-86.06111099999998,72.26165800000012],[-86.09638999999999,72.27638200000001],[-86.10722399999992,72.28387500000002],[-86.11000100000001,72.28970300000015],[-86.10139500000002,72.29359400000004],[-86.09333800000002,72.29470800000001],[-86.06723,72.29386900000003],[-86.00500499999998,72.29664600000012],[-85.86389199999996,72.297211],[-85.84722899999997,72.29414400000007]],[[-78.73500099999995,72.36554000000012],[-78.75389100000001,72.36331200000001],[-78.81220999999988,72.36526500000008],[-78.83084099999996,72.36499000000009],[-78.854172,72.36219799999998],[-78.874435,72.35887100000008],[-78.88945000000001,72.35470600000008],[-78.91332999999986,72.3455350000001],[-78.92083699999995,72.3413700000001],[-78.93499799999995,72.33638000000008],[-78.95028699999995,72.33499100000006],[-79.05305499999997,72.36080900000002],[-79.07556199999993,72.40304600000007],[-79.07501200000002,72.40971400000006],[-79.07084700000001,72.41499300000004],[-79.066666,72.4202580000001],[-79.04444899999993,72.42665100000005],[-79.00140399999998,72.43830900000012],[-78.97084000000001,72.44525099999998],[-78.95556599999992,72.44442700000002],[-78.95056199999999,72.44219999999996],[-78.94665500000002,72.44026200000002],[-78.93998699999992,72.43580600000013],[-78.84695399999993,72.41554300000007],[-78.83389299999999,72.41192600000011],[-78.74082900000002,72.37441999999999],[-78.73167399999994,72.36943100000002],[-78.73500099999995,72.36554000000012]],[[-79.50805699999995,72.34860200000003],[-79.53388999999999,72.34609999999998],[-79.55583200000001,72.34693900000008],[-79.57223499999998,72.34915200000006],[-79.581955,72.35165399999994],[-79.59445199999999,72.35693400000002],[-79.60943600000002,72.36692800000003],[-79.6241609999999,72.37942500000003],[-79.68331899999998,72.43054200000012],[-79.58612099999999,72.45387299999999],[-79.57667500000002,72.45610000000005],[-79.55248999999992,72.45109600000012],[-79.541382,72.44497700000005],[-79.52917499999995,72.43969700000002],[-79.50279199999989,72.42997700000012],[-79.46945199999999,72.42303500000003],[-79.43638599999997,72.41832],[-79.42971799999998,72.411652],[-79.44055200000003,72.37052900000009],[-79.44665499999991,72.36499000000009],[-79.45556599999992,72.35998500000005],[-79.47027599999996,72.355545],[-79.50805699999995,72.34860200000003]],[[-79.993607,72.41331500000013],[-80.00944500000003,72.41053800000003],[-80.02223200000003,72.41360500000013],[-80.124435,72.50665300000003],[-80.13055400000002,72.51249700000005],[-80.13333099999994,72.51944000000003],[-80.1299899999999,72.52304100000009],[-80.11999499999996,72.52693199999999],[-80.11250299999995,72.52693199999999],[-80.06361399999997,72.52388000000008],[-80.0369419999999,72.51638800000012],[-79.92193600000002,72.46331800000007],[-79.91639700000002,72.45803799999999],[-79.926941,72.44775400000015],[-79.93916299999995,72.436646],[-79.956955,72.42608600000005],[-79.97888199999989,72.41775500000011],[-79.993607,72.41331500000013]],[[-110.46916199999993,72.56915299999997],[-110.48137699999995,72.56581100000005],[-110.54415899999998,72.56915299999997],[-110.57195300000001,72.57554600000014],[-110.58833299999998,72.58387800000014],[-110.593887,72.58859299999995],[-110.593887,72.59414700000013],[-110.576683,72.59498600000012],[-110.53888699999993,72.59498600000012],[-110.516663,72.593323],[-110.50446299999999,72.59082000000001],[-110.48249799999991,72.5836030000001],[-110.47444200000001,72.57943700000004],[-110.46888699999994,72.57470699999999],[-110.46916199999993,72.56915299999997]],[[-110.35582699999998,72.6019290000001],[-110.37304699999993,72.60137900000007],[-110.39499699999993,72.60304300000007],[-110.4641719999999,72.61331200000012],[-110.49472000000003,72.61914100000013],[-110.46916199999993,72.62136800000002],[-110.450287,72.62136800000002],[-110.39862099999993,72.61804199999995],[-110.35888699999992,72.61499000000003],[-110.34500100000002,72.6119230000001],[-110.34500100000002,72.6060940000001],[-110.35582699999998,72.6019290000001]],[[-108.510559,72.60276800000008],[-108.51999699999993,72.59803800000003],[-108.53778099999994,72.59942600000011],[-108.593613,72.61775200000011],[-108.604446,72.621643],[-108.61221299999994,72.62580900000012],[-108.6141659999999,72.63108800000009],[-108.61361699999986,72.63665799999995],[-108.60388199999994,72.63943500000005],[-108.51722699999999,72.64248700000002],[-108.49665800000002,72.64137299999999],[-108.49194299999999,72.63665799999995],[-108.49416400000001,72.63192700000002],[-108.510559,72.60276800000008]],[[-110.30722000000003,72.63081399999999],[-110.36389199999996,72.63081399999999],[-110.39695699999993,72.63638300000014],[-110.41082799999998,72.63943500000005],[-110.40028399999994,72.64360000000005],[-110.36000100000001,72.64888000000013],[-110.31500199999999,72.65193200000004],[-110.28083799999996,72.64221199999997],[-110.281113,72.63638300000014],[-110.28999299999992,72.63165300000009],[-110.30722000000003,72.63081399999999]],[[-109.215012,72.79026800000008],[-109.22749299999992,72.78720099999998],[-109.24833699999999,72.78804000000014],[-109.37277199999994,72.8060910000001],[-109.41694599999988,72.81526200000008],[-109.41944899999993,72.82054100000005],[-109.37832600000002,72.828598],[-109.33389299999999,72.83499099999995],[-109.32028200000002,72.8316650000001],[-109.31220999999994,72.82748400000003],[-109.22444200000001,72.81109600000013],[-109.21056399999998,72.8077550000001],[-109.21166999999997,72.79637100000002],[-109.215012,72.79026800000008]],[[-95.73500099999995,72.79887400000001],[-95.75361599999991,72.79609700000009],[-95.77139299999993,72.799149],[-95.835556,72.83110000000005],[-95.854172,72.85359199999999],[-95.85082999999997,72.85832199999999],[-95.81054699999993,72.87664799999999],[-95.79110699999995,72.88026400000007],[-95.77417000000003,72.88026400000007],[-95.76916499999999,72.87803600000012],[-95.76306199999988,72.8724820000001],[-95.735275,72.85998500000011],[-95.72055099999994,72.84803799999997],[-95.716949,72.84387200000009],[-95.7141719999999,72.83859300000012],[-95.71362299999987,72.83221400000008],[-95.71888699999994,72.80941800000005],[-95.72500599999995,72.803314],[-95.73500099999995,72.79887400000001]],[[-96.75418100000002,72.72137499999997],[-96.77027899999996,72.71971099999996],[-96.95527599999997,72.73414600000007],[-96.96945199999999,72.73776199999998],[-96.97778299999999,72.74525499999999],[-97.01112399999994,72.77581800000013],[-97.0102839999999,72.77665700000011],[-96.92138699999998,72.83581500000008],[-96.91111799999993,72.841095],[-96.79861499999998,72.88136300000002],[-96.75723299999993,72.89276100000006],[-96.737213,72.89526400000005],[-96.72555499999999,72.89498900000001],[-96.71333299999992,72.89332600000006],[-96.68832399999997,72.883331],[-96.69221500000003,72.86276200000003],[-96.666946,72.81109600000013],[-96.65167200000002,72.80415299999999],[-96.64250199999998,72.79776000000004],[-96.63999899999999,72.79165599999999],[-96.63999899999999,72.786652],[-96.641388,72.78221100000007],[-96.72805800000003,72.73054500000006],[-96.741379,72.72553999999997],[-96.75418100000002,72.72137499999997]],[[-95.756958,72.89248700000013],[-95.77749599999999,72.8919370000001],[-95.79527299999995,72.89498900000001],[-95.808334,72.90721099999996],[-95.82472199999995,72.96527100000009],[-95.78666699999997,73.01249699999994],[-95.76167299999997,73.00471499999998],[-95.75723299999993,73.00166300000006],[-95.75611899999996,72.99859600000013],[-95.743607,72.98776200000009],[-95.70249899999999,72.93359399999997],[-95.70834399999995,72.91720600000008],[-95.73554999999999,72.90054300000003],[-95.74444599999993,72.895828],[-95.756958,72.89248700000013]],[[-95.73388699999998,73.12886000000003],[-95.71806299999997,73.11804200000006],[-95.71583599999991,73.11192299999999],[-95.71556099999998,73.10554500000006],[-95.71777299999997,73.10026600000009],[-95.72639500000002,73.08888199999996],[-95.72917199999995,73.07110599999999],[-95.72471599999994,73.05914299999995],[-95.7283329999999,73.05442800000014],[-95.74554399999994,73.04942300000005],[-95.775284,73.05525200000011],[-95.787216,73.06192000000004],[-95.79943799999995,73.07276900000011],[-95.82250999999997,73.08305400000006],[-95.85972600000002,73.09082000000012],[-95.89334100000002,73.09582499999999],[-95.89306599999998,73.10081500000001],[-95.89111299999996,73.10108900000012],[-95.88500999999991,73.10470600000008],[-95.88194299999998,73.10859700000015],[-95.87471,73.11415099999999],[-95.86527999999993,73.11998],[-95.86305199999998,73.12525900000014],[-95.86527999999993,73.13136300000002],[-95.86833200000001,73.13638300000002],[-95.86888099999999,73.14054899999996],[-95.85499599999997,73.14054899999996],[-95.84083599999997,73.13665800000007],[-95.828888,73.129974],[-95.82250999999997,73.12469500000003],[-95.81834399999997,73.12553399999996],[-95.81416300000001,73.13108799999998],[-95.80749500000002,73.1355440000001],[-95.79083300000002,73.13943499999999],[-95.77639799999992,73.14054899999996],[-95.76333599999998,73.1397090000001],[-95.74499499999996,73.13665800000007],[-95.73889200000002,73.13388099999997],[-95.73388699999998,73.12886000000003]],[[-96.80833399999995,72.92637600000012],[-96.91528299999993,72.91775500000006],[-96.95527599999997,72.92053199999992],[-96.96833800000002,72.92387400000007],[-96.99055499999997,72.93109099999998],[-97.01777600000003,72.94053600000007],[-97.03222700000003,72.94664000000006],[-97.06138599999991,72.96331800000013],[-97.089722,72.98165899999998],[-97.10583499999996,72.99832200000003],[-97.11193800000001,73.00471499999998],[-97.13694799999996,73.04582200000004],[-97.13972499999988,73.05192600000004],[-97.141953,73.06414800000005],[-97.14277599999997,73.0752720000001],[-97.14111299999996,73.08554100000015],[-97.12777699999992,73.09582499999999],[-97.06973299999999,73.136932],[-97.05943299999996,73.14221200000003],[-97.045547,73.14749100000006],[-97.00334199999998,73.15971400000006],[-96.94694499999997,73.172485],[-96.904449,73.17997700000012],[-96.848053,73.18748499999998],[-96.80943300000001,73.1891480000001],[-96.78639199999998,73.18803400000013],[-96.77194199999997,73.18165599999998],[-96.75527999999997,73.17581200000012],[-96.65306099999992,73.13638300000002],[-96.60221899999993,73.09915200000012],[-96.58084100000002,73.08110000000005],[-96.5750119999999,73.07499700000005],[-96.56861900000001,73.06219500000009],[-96.56582600000002,73.05609100000004],[-96.56471299999998,73.05053700000008],[-96.56555200000003,73.04470800000001],[-96.573624,73.03332500000005],[-96.63667299999997,72.96582000000006],[-96.64334100000002,72.96138000000002],[-96.65834000000001,72.95416300000011],[-96.69721999999996,72.94165000000004],[-96.74305700000002,72.93359399999997],[-96.76501499999995,72.93081700000005],[-96.80833399999995,72.92637600000012]],[[-96.90583799999996,73.22082500000005],[-96.924713,73.21804800000012],[-96.94499199999996,73.21832299999994],[-96.98472599999997,73.22053500000004],[-97.04083300000002,73.22859199999999],[-97.07917799999996,73.23525999999998],[-97.10694899999993,73.24220300000013],[-97.11776700000001,73.24914599999994],[-97.11527999999993,73.25305200000003],[-97.09028599999988,73.26193200000006],[-97.058044,73.26915000000008],[-97.03500400000001,73.2727660000001],[-96.97749299999998,73.27388000000008],[-96.96777299999997,73.27331500000008],[-96.96833800000002,73.26748700000013],[-96.95140099999998,73.23942600000004],[-96.90916400000003,73.23831200000006],[-96.896118,73.23776200000003],[-96.88667299999992,73.23109400000004],[-96.88917499999997,73.2249910000001],[-96.90583799999996,73.22082500000005]],[[-113.99749799999995,72.7994230000001],[-114.01112399999994,72.79664600000001],[-114.06806899999998,72.79582200000004],[-114.15167200000002,72.79803500000003],[-114.20861799999994,72.79693600000007],[-114.22416699999997,72.79498300000012],[-114.23581699999994,72.79165599999999],[-114.35138699999993,72.74748200000005],[-114.35749800000002,72.74136400000009],[-114.35637700000001,72.73580900000002],[-114.33444199999997,72.69358800000003],[-114.327789,72.688873],[-114.36582900000002,72.66276600000009],[-114.45168299999995,72.62303200000002],[-114.46501199999994,72.6202550000001],[-114.49553699999996,72.61637900000005],[-114.53138699999988,72.61499000000003],[-114.576683,72.60914600000001],[-114.58999599999993,72.60636899999992],[-114.60472099999998,72.60165400000011],[-114.55832700000002,72.56080600000001],[-114.42666600000001,72.55609099999998],[-114.38527699999986,72.555252],[-114.35138699999993,72.55747999999994],[-114.33999599999999,72.56080600000001],[-114.33029199999999,72.56526200000008],[-114.32584400000002,72.57193000000007],[-114.12805200000003,72.62608300000005],[-114.10305800000003,72.63220200000006],[-114.06276699999995,72.64027400000003],[-113.99027999999998,72.65138200000001],[-113.910278,72.65914899999996],[-113.89306599999998,72.66026299999999],[-113.88333099999988,72.65748600000006],[-113.89046499999995,72.64804800000002],[-113.89222699999999,72.64082299999995],[-113.88054699999992,72.6372070000001],[-113.858047,72.63581799999992],[-113.80666399999996,72.63916000000006],[-113.76222199999995,72.64610300000004],[-113.70834400000001,72.65693700000008],[-113.67138699999992,72.6666560000001],[-113.61277799999988,72.68386800000013],[-113.58750899999995,72.68997199999995],[-113.54666099999997,72.69802900000013],[-113.51611300000002,72.70193499999999],[-113.50611900000001,72.699142],[-113.52084400000001,72.68803400000002],[-113.55055199999987,72.67526200000003],[-113.57250999999991,72.66748000000007],[-113.61945299999996,72.653595],[-113.64277599999991,72.64665200000002],[-113.68776699999995,72.63192700000002],[-113.70944199999991,72.624146],[-113.729172,72.61554000000007],[-113.73082699999998,72.60942100000005],[-113.72193900000002,72.60554499999995],[-113.69972200000001,72.60415599999999],[-113.68443299999996,72.6060940000001],[-113.65750100000002,72.61137400000001],[-113.46639999999996,72.66526800000003],[-113.44275700000003,72.672211],[-113.436394,72.67804000000001],[-113.431671,72.684708],[-113.41000399999996,72.72943100000003],[-113.41332999999992,72.73471100000012],[-113.41972399999997,72.73915099999994],[-113.43138099999999,72.742752],[-113.44860799999992,72.74498],[-113.53527799999995,72.74887100000007],[-113.58029199999987,72.75166300000012],[-113.59750399999996,72.75416600000011],[-113.60637699999995,72.75833100000011],[-113.60804699999994,72.76943999999997],[-113.59889199999998,72.78276099999994],[-113.58249699999999,72.793045],[-113.38694800000002,72.907486],[-113.33139,72.93525700000009],[-113.30277999999998,72.94886800000006],[-113.26862299999999,72.96026600000005],[-113.14862099999999,72.99470500000007],[-113.0627669999999,73.00749200000007],[-113.02806099999998,73.00943000000001],[-113.00695799999994,73.00888100000009],[-112.823059,72.99887100000001],[-112.811394,72.9952550000001],[-112.79472399999997,72.98220800000007],[-112.78582799999998,72.978317],[-112.77139299999993,72.97526600000003],[-112.75418100000002,72.97276300000004],[-112.708618,72.96971100000013],[-112.64362299999993,72.96693400000004],[-112.60082999999986,72.96360799999997],[-112.56360599999994,72.95915200000007],[-112.51500699999991,72.951096],[-112.5,72.94792200000012],[-112.47165699999994,72.94192500000003],[-112.44583099999994,72.93525700000009],[-112.41388699999993,72.92414900000006],[-112.387787,72.91110200000003],[-112.37638900000002,72.907761],[-112.36193800000001,72.90470900000008],[-112.34472700000003,72.90220599999992],[-112.27944899999994,72.89694199999997],[-112.23777799999999,72.89553799999999],[-112.14195299999994,72.89637800000003],[-112.09834299999989,72.89415000000002],[-112.06166099999996,72.88943499999999],[-111.947769,72.87052900000015],[-111.78333299999997,72.83471700000001],[-111.67582699999997,72.81469700000002],[-111.65888999999999,72.8119200000001],[-111.59416199999998,72.80664100000013],[-111.54055799999998,72.7994230000001],[-111.52639799999997,72.79637100000002],[-111.23693799999995,72.72637900000012],[-111.22582999999997,72.7227630000001],[-111.22000100000002,72.71832300000005],[-111.20249899999999,72.67053199999998],[-111.20527599999997,72.66442900000004],[-111.26278699999995,72.57916300000011],[-111.2769469999999,72.56749000000008],[-111.45221699999996,72.47776800000003],[-111.52778599999999,72.44999700000011],[-111.65110800000002,72.40887500000008],[-111.675003,72.40220600000004],[-111.736107,72.39526400000011],[-111.76999699999993,72.3936000000001],[-111.78527799999995,72.39193699999998],[-111.81221,72.38665800000001],[-111.859734,72.37330600000001],[-111.890289,72.36053500000008],[-111.89890299999996,72.355545],[-111.90556299999997,72.349716],[-111.90167200000002,72.34609999999998],[-111.86250299999995,72.33055100000007],[-111.85138699999999,72.32693499999999],[-111.66388699999999,72.27638200000001],[-111.50446299999999,72.31192000000004],[-111.44499200000001,72.3288730000001],[-111.42443799999995,72.33720400000004],[-111.41915899999998,72.34387199999998],[-111.43305999999995,72.34693900000008],[-111.45140100000003,72.34693900000008],[-111.487213,72.33665500000006],[-111.51944700000001,72.33415200000007],[-111.5616609999999,72.33665500000006],[-111.578056,72.33915699999994],[-111.58917200000002,72.342758],[-111.60582699999998,72.35081500000001],[-111.61165599999998,72.36109900000002],[-111.609444,72.36720300000007],[-111.58833299999998,72.37637300000011],[-111.37444299999993,72.44664],[-111.350281,72.45332299999995],[-111.3094329999999,72.46081500000008],[-111.29387700000001,72.46276899999992],[-111.26583899999997,72.46554600000002],[-111.248894,72.466385],[-111.22860699999995,72.46554600000002],[-111.20249899999999,72.46026599999999],[-111.21333300000003,72.44693000000001],[-111.23277299999995,72.4369200000001],[-111.24500299999994,72.43359400000008],[-111.27223200000003,72.42858899999999],[-111.30139200000002,72.40416000000005],[-111.27749599999993,72.36997999999994],[-111.11277799999993,72.3352660000001],[-111.09528399999994,72.37970000000001],[-111.09137699999997,72.4019320000001],[-111.00446299999999,72.46527100000003],[-110.8691639999999,72.47331200000008],[-110.82444799999996,72.4791560000001],[-110.80304699999999,72.48525999999993],[-110.82501200000002,72.50387599999993],[-110.833328,72.51915000000002],[-110.827789,72.52581800000002],[-110.73805199999993,72.56553600000001],[-110.72749299999998,72.56971699999991],[-110.71528599999999,72.57304400000004],[-110.70140100000003,72.57554600000014],[-110.68083199999995,72.57470699999999],[-110.66610700000001,72.57304400000004],[-110.53527799999995,72.54664600000007],[-110.52639799999992,72.52693199999999],[-110.57501199999996,72.51388500000013],[-110.59445199999993,72.50471500000009],[-110.60166899999996,72.49887100000007],[-110.60193600000002,72.4933170000001],[-110.59361299999989,72.48915099999999],[-110.55249000000003,72.47387700000013],[-110.53083800000002,72.46665999999999],[-110.35056299999997,72.42804000000007],[-110.32861299999996,72.42608600000005],[-110.30999799999995,72.42608600000005],[-110.303879,72.43054200000012],[-110.31194299999993,72.43470800000006],[-110.41027799999995,72.4622040000001],[-110.50334199999998,72.48498500000011],[-110.514183,72.488586],[-110.52250700000002,72.49275200000005],[-110.52778599999999,72.4974820000001],[-110.53056299999992,72.50248699999997],[-110.52333099999998,72.508331],[-110.39639299999999,72.55220000000008],[-110.38417099999998,72.555542],[-110.36527999999998,72.555542],[-110.34333800000002,72.55386400000009],[-110.32389799999993,72.55165099999994],[-110.31304899999998,72.54776000000004],[-110.22028399999994,72.51388500000013],[-110.20140100000003,72.50582900000006],[-110.15527299999997,72.48027000000008],[-110.06139399999995,72.43748499999992],[-110.05055199999993,72.43386800000002],[-110.03999299999998,72.43803400000007],[-110.02194199999991,72.44775400000015],[-109.998894,72.45526100000012],[-109.97112300000003,72.46026599999999],[-109.95249899999999,72.45999100000012],[-109.91972399999986,72.45471199999997],[-109.81388900000002,72.428314],[-109.79666099999992,72.4269260000001],[-109.78278399999999,72.42942800000014],[-109.77806099999998,72.43470800000006],[-109.78582799999992,72.43887300000006],[-109.80583199999995,72.44552600000003],[-109.83029199999999,72.45220899999998],[-110.04250300000001,72.50471500000009],[-110.223053,72.5458220000001],[-110.23665599999998,72.54887400000007],[-110.24777199999994,72.55276500000014],[-110.25583599999987,72.55693100000002],[-110.252792,72.56303400000013],[-110.24221799999992,72.56694000000005],[-110.22165699999994,72.56608600000004],[-110.12082699999996,72.56025700000004],[-110.104172,72.55775499999999],[-110.09056099999998,72.55442800000003],[-110.06889299999995,72.54693600000007],[-110.03888699999987,72.53553800000009],[-110.02278099999995,72.52720600000009],[-110.00361599999991,72.51944000000003],[-109.97112300000003,72.508331],[-109.90499899999998,72.48719800000009],[-109.88861099999986,72.484711],[-109.80943300000001,72.4916530000001],[-109.79527300000001,72.49414100000007],[-109.78472899999997,72.49832200000014],[-109.78278399999999,72.50305199999997],[-109.94275700000003,72.60415599999999],[-109.95889299999993,72.61276200000009],[-110.09306300000003,72.65637200000009],[-110.11332699999997,72.65721100000002],[-110.171112,72.64833099999998],[-110.18666100000002,72.64665200000002],[-110.22112299999998,72.64526400000005],[-110.241669,72.64610300000004],[-110.25556899999998,72.64942900000005],[-110.266663,72.65304600000002],[-110.283073,72.66137700000013],[-110.28832999999992,72.66609199999999],[-110.29110700000001,72.67109700000003],[-110.20973200000003,72.71775800000006],[-110.20056199999999,72.7227630000001],[-110.18831599999999,72.72608900000012],[-110.17083699999995,72.72692899999998],[-110.078079,72.72706599999998],[-110.041672,72.72248800000006],[-110.03056300000003,72.71859699999999],[-109.99804699999999,72.70193499999999],[-109.98693800000001,72.69831800000003],[-109.85221899999993,72.66581700000012],[-109.83277899999996,72.66331500000007],[-109.81723,72.66499299999998],[-109.77084399999995,72.71638500000012],[-109.77027900000002,72.72221400000012],[-109.78138699999994,72.72581500000001],[-109.80082700000003,72.72804300000013],[-109.81973299999993,72.72804300000013],[-110.03111299999995,72.74775700000004],[-110.17887899999994,72.76914999999997],[-110.17138699999998,72.77499399999999],[-110.16832699999986,72.7810970000001],[-110.17083699999995,72.78610199999997],[-110.17639199999996,72.790817],[-110.21166999999997,72.81832899999995],[-110.24526999999995,72.82360799999998],[-110.32640099999992,72.82638500000002],[-110.36638599999998,72.82720899999998],[-110.47666899999996,72.83499099999995],[-110.493607,72.83776899999998],[-110.53555299999994,72.84721400000001],[-110.54666099999997,72.85081500000007],[-110.56331599999999,72.85914599999995],[-110.74276699999996,72.95721400000014],[-110.75389099999995,72.96638500000006],[-110.75666799999993,72.97137499999997],[-110.75389099999995,72.97776800000008],[-110.74804699999993,72.98442100000005],[-110.74082900000002,72.98997500000007],[-110.73166700000002,72.99498000000011],[-110.70834400000001,73.00248700000003],[-110.69415300000003,73.00499000000002],[-110.6783289999999,73.00665300000014],[-110.61860699999994,73.01138300000014],[-110.51139799999993,73.01527400000003],[-110.432503,73.0144350000001],[-110.39083899999997,73.01249699999994],[-110.16610700000001,72.99609400000008],[-110.05110199999996,72.98471100000006],[-109.91887700000001,72.96804800000001],[-109.65943899999996,72.92498800000004],[-109.63445299999995,72.91804500000006],[-109.61805700000002,72.90942400000012],[-109.618607,72.90386999999993],[-109.62943999999993,72.89971900000006],[-109.66111799999999,72.89665200000013],[-109.69471699999997,72.89444000000009],[-109.724716,72.89054900000002],[-109.73889200000002,72.88804600000003],[-109.75,72.88388100000003],[-109.75472999999994,72.87858599999998],[-109.74665799999997,72.87442000000004],[-109.65862300000003,72.84471100000002],[-109.379707,72.7705380000001],[-109.22778299999993,72.76165800000007],[-109.05110200000001,72.68026700000007],[-109.02999899999998,72.64721700000001],[-109.04915599999993,72.60415599999999],[-109.045547,72.57249500000012],[-109.04332699999998,72.56749000000008],[-109.02861000000001,72.56553600000001],[-108.88249200000001,72.56442300000015],[-108.86527999999998,72.56498700000009],[-108.85109699999998,72.56749000000008],[-108.84194899999994,72.57249500000012],[-108.81916799999993,72.59109500000005],[-108.722778,72.58276399999994],[-108.70361300000002,72.58027600000014],[-108.67666600000001,72.57388300000002],[-108.64472999999987,72.56248500000004],[-108.62138399999998,72.54998800000004],[-108.61638599999998,72.54525799999999],[-108.58805799999993,72.50555400000007],[-108.589447,72.49443100000008],[-108.59638999999993,72.48220800000001],[-108.60278299999999,72.47554000000002],[-108.61054999999993,72.46998600000006],[-108.62470999999994,72.45748900000007],[-108.63722200000001,72.44442700000002],[-108.64499699999993,72.42665100000005],[-108.65055799999999,72.40359500000005],[-108.66361999999998,72.36276199999998],[-108.66278099999994,72.34637499999997],[-108.65834000000001,72.33610500000003],[-108.52416999999997,72.19970699999999],[-108.45500199999998,72.15721100000013],[-108.44415300000003,72.16110200000003],[-108.42832900000002,72.1583250000001],[-108.41805999999997,72.15443400000004],[-108.404449,72.14694199999991],[-108.40222199999994,72.14166300000011],[-108.39890300000002,72.11360200000007],[-108.39472999999998,72.04275500000011],[-108.39527900000002,72.03692600000011],[-108.396118,72.03137200000009],[-108.31639099999995,71.98414600000007],[-108.20417799999996,71.96388200000013],[-108.19138299999992,71.96054100000009],[-108.18666100000002,71.95582600000006],[-108.18276999999995,71.94552599999992],[-108.18971299999998,71.93331899999998],[-108.19611399999997,71.92692599999998],[-108.233612,71.89971900000006],[-108.28639199999992,71.86080900000013],[-108.28278399999999,71.79220600000002],[-108.28083800000002,71.786926],[-108.24276700000001,71.71859700000005],[-108.23805199999998,71.71388200000001],[-108.23082699999992,71.70942699999995],[-108.22055099999994,71.70582600000012],[-108.20777900000002,71.70248400000014],[-108.19248999999996,71.69970700000005],[-108.17748999999998,71.70109600000006],[-108.14111300000002,71.71054100000015],[-108.13054699999992,71.71443200000004],[-108.10333300000002,71.71914700000008],[-108.08693700000003,71.71971100000002],[-108.066101,71.71775800000006],[-108.03639199999998,71.70582600000012],[-108.02194199999997,71.697205],[-107.98805199999987,71.67553700000008],[-107.97609699999987,71.666382],[-107.96694899999994,71.65693699999997],[-107.96777299999991,71.65138200000007],[-107.91583300000002,71.62498499999998],[-107.84528399999994,71.6038670000001],[-107.82888799999995,71.60443100000003],[-107.75334199999998,71.61026000000004],[-107.74109599999997,71.61331200000012],[-107.73194899999999,71.618042],[-107.72416699999991,71.62387100000001],[-107.72609699999998,71.62914999999998],[-107.74054699999994,71.63749699999994],[-107.75028999999995,71.64137300000004],[-107.77583299999998,71.64804100000003],[-107.82472199999995,71.67275999999998],[-107.83194700000001,71.67692600000004],[-107.83640300000002,71.68165600000009],[-107.83833300000003,71.68692000000004],[-107.83750899999995,71.69247400000006],[-107.82305899999994,71.7169340000001],[-107.81527699999998,71.7227630000001],[-107.80444299999999,71.726654],[-107.78943600000002,71.72804300000001],[-107.7519529999999,71.726654],[-107.73665599999998,71.72360200000008],[-107.63027999999997,71.73220800000001],[-107.49472000000003,71.78637700000002],[-107.451683,71.85748300000006],[-107.36361699999992,71.871918],[-107.34555099999994,71.871643],[-107.29695099999998,71.87414599999994],[-107.28333299999997,71.876373],[-107.27084400000001,71.87942499999997],[-107.26139799999999,71.88415500000013],[-107.25334199999998,71.88970899999998],[-107.25250199999994,71.89553799999999],[-107.25695799999994,71.9002690000001],[-107.264183,71.9044340000001],[-107.41805999999997,71.9538730000001],[-107.59638999999993,72.00443999999999],[-107.61389199999996,72.012497],[-107.62581599999999,72.02165200000002],[-107.63027999999997,72.02638200000007],[-107.65139799999997,72.06109600000013],[-107.653343,72.06637599999999],[-107.64943700000003,72.072495],[-107.63999899999993,72.07720899999998],[-107.62609899999995,72.0794370000001],[-107.61389199999996,72.08276400000005],[-107.61000100000001,72.08859300000006],[-107.61193799999995,72.09387200000003],[-107.63527699999997,72.12191799999994],[-107.68138099999999,72.13610800000004],[-107.699997,72.138596],[-107.729446,72.13720700000005],[-107.74333199999995,72.13499499999995],[-107.76027699999992,72.13443000000012],[-107.77887699999997,72.13665800000007],[-107.78083800000002,72.14193700000004],[-107.787216,72.18470800000011],[-107.77806099999992,72.20803800000004],[-107.843887,72.35415600000005],[-107.87748699999992,72.4244230000001],[-107.88639799999993,72.51971399999996],[-107.87693799999994,72.524429],[-107.87165799999997,72.52970900000008],[-107.87666299999995,72.56721500000003],[-107.88054699999998,72.57748400000008],[-107.88555899999989,72.58665500000001],[-107.91555799999998,72.59721400000006],[-107.92887899999994,72.60054000000008],[-107.99082900000002,72.61248799999998],[-108.00418099999996,72.615814],[-108.01194800000002,72.61998000000011],[-108.025284,72.66609199999999],[-108.02639799999997,72.67692600000004],[-108.02667199999996,72.719986],[-108.05110200000001,72.78137200000015],[-108.05803699999996,72.79109200000005],[-108.11193799999995,72.89082300000013],[-108.1519469999999,72.97110000000009],[-108.16528299999993,73.01081799999997],[-108.26363400000002,73.0919340000001],[-108.29361,73.12025499999999],[-108.29998799999998,73.1355440000001],[-108.295547,73.14749100000006],[-108.291946,73.15359500000005],[-108.28527799999995,73.159988],[-108.26862299999999,73.17137100000002],[-108.23029299999996,73.18748499999998],[-108.18110699999994,73.20166000000006],[-108.16639700000002,73.20387300000004],[-108.13390400000003,73.20694000000015],[-108.11582900000002,73.20748900000007],[-108.07389799999993,73.20526100000012],[-108.02390300000002,73.20109600000012],[-107.93443300000001,73.18748499999998],[-107.91471899999993,73.18498199999999],[-107.89388999999994,73.18386800000002],[-107.87416099999996,73.18359400000008],[-107.86416599999995,73.18858300000005],[-107.87222300000002,73.19274899999994],[-107.90471600000001,73.20416300000005],[-107.94611399999991,73.21415700000006],[-108.01027699999997,73.226089],[-108.05166599999995,73.23609899999991],[-108.08444199999997,73.2474820000001],[-108.11638599999992,73.26443500000005],[-108.15361000000001,73.30247500000013],[-108.08444199999997,73.34999099999999],[-108.07140399999992,73.35331700000006],[-108.05332899999996,73.3538670000001],[-107.99109599999991,73.35137900000012],[-107.94722000000002,73.3483280000001],[-107.77139299999999,73.32388300000002],[-107.675003,73.32331800000003],[-107.631104,73.31999199999996],[-107.614441,73.31721500000009],[-107.403343,73.27053799999999],[-107.33583099999987,73.24803199999997],[-107.24999999999994,73.21748400000001],[-107.21028099999995,73.20166000000006],[-107.18888900000002,73.19413800000012],[-107.172234,73.19108600000004],[-107.10582699999998,73.17942800000003],[-107.06973299999999,73.17387400000001],[-107.05027799999999,73.17359899999997],[-107.03694200000001,73.1766510000001],[-107.025284,73.180542],[-107.016663,73.18609599999996],[-107.01083399999999,73.19136000000015],[-107.02027899999996,73.20082100000013],[-107.05249000000003,73.21249399999994],[-107.09028599999994,73.22303799999997],[-107.11081699999994,73.23136900000009],[-107.11860699999994,73.23553499999997],[-107.12361099999998,73.24026500000002],[-107.11945300000002,73.24636800000013],[-107.03028899999998,73.29553199999998],[-107.01862299999999,73.29942300000005],[-106.88249199999996,73.31219500000003],[-106.86138899999997,73.31080600000001],[-106.76139799999999,73.29304500000006],[-106.75083899999993,73.289154],[-106.74610899999999,73.28442399999994],[-106.74109599999991,73.26887500000004],[-106.72721899999993,73.25471500000015],[-106.69666299999994,73.2374880000001],[-106.66471899999999,73.226089],[-106.65110800000002,73.22248799999994],[-106.63474300000001,73.21971100000007],[-106.60305800000003,73.21666000000005],[-106.58222999999998,73.21527100000003],[-106.39862099999993,73.14915500000006],[-106.24027999999998,73.08581500000008],[-106.06388899999996,73.04775999999998],[-106.04750100000001,73.04470800000001],[-106.028343,73.04443400000008],[-105.94888300000002,73.05331399999994],[-105.91027799999989,73.05886800000013],[-105.87638899999996,73.05831899999998],[-105.85555999999997,73.05693100000008],[-105.84221600000001,73.05358899999999],[-105.83194699999996,73.04971300000011],[-105.82472200000001,73.04525800000005],[-105.82195299999995,73.03498799999994],[-105.82333399999999,73.02943399999998],[-105.83249699999999,73.01721199999997],[-105.82972699999993,73.00694299999998],[-105.82224299999996,73.00248700000003],[-105.80471799999998,72.99443100000013],[-105.79444899999993,72.99026500000008],[-105.76083399999999,72.9769290000001],[-105.737503,72.96943699999997],[-105.697769,72.95915200000007],[-105.67859599999997,72.95637499999998],[-105.62917299999998,72.93997200000013],[-105.56221,72.91304000000002],[-105.445831,72.83831800000007],[-105.32611099999991,72.74636800000007],[-105.32195299999995,72.74165300000004],[-105.32055700000001,72.73664900000006],[-105.32528699999995,72.73054500000006],[-105.33693700000003,72.726654],[-105.35610999999994,72.72720300000009],[-105.37777699999998,72.72943100000003],[-105.39778100000001,72.73719800000003],[-105.41194200000001,72.7458190000001],[-105.41915899999992,72.75027500000004],[-105.42748999999992,72.75972000000007],[-105.43472300000002,72.76416000000012],[-105.46472199999994,72.77581800000013],[-105.47778299999999,72.77943400000004],[-105.49833699999994,72.780823],[-105.51000999999997,72.7769320000001],[-105.45722999999992,72.70277399999998],[-105.44722000000002,72.69886800000006],[-105.38249200000001,72.68136600000003],[-105.35665899999998,72.67442300000005],[-105.29472399999997,72.63192700000002],[-105.23110999999994,72.54332000000005],[-105.19583099999988,72.48248300000006],[-105.19972199999995,72.46054100000015],[-105.20140100000003,72.45471199999997],[-105.20612299999993,72.44886800000012],[-105.21777299999991,72.44497700000005],[-105.23194899999993,72.44720500000005],[-105.26167299999992,72.45887800000003],[-105.27722199999994,72.4622040000001],[-105.29305999999997,72.46081500000008],[-105.301941,72.45526100000012],[-105.29778299999987,72.45054600000009],[-105.241379,72.39971899999995],[-105.23029299999996,72.39054900000008],[-105.21665999999993,72.38192700000008],[-105.18998699999997,72.36970500000012],[-105.16055299999988,72.35775799999999],[-105.13999899999999,72.34471100000013],[-105.04415899999998,72.24803200000002],[-105.03639199999986,72.23858600000005],[-105.03362299999998,72.23471100000006],[-105.02443700000003,72.21998600000012],[-104.99166899999989,72.20332300000001],[-104.95749699999999,72.18136600000014],[-104.95527599999997,72.17109700000015],[-104.95722999999992,72.16554300000013],[-104.96167000000003,72.15942400000012],[-104.96916199999998,72.15304600000013],[-104.97805799999992,72.14749100000006],[-104.98805199999993,72.14276100000001],[-104.99973299999999,72.13888500000013],[-105.02999899999998,72.12469500000003],[-105.03751399999999,72.1183170000001],[-105.03639199999986,72.11303700000002],[-105.01862299999993,72.06693999999993],[-104.92944299999988,72.03414900000001],[-104.87193299999996,71.98997500000007],[-104.82917800000001,71.93719500000003],[-104.82444800000002,71.92747500000013],[-104.82028200000002,71.90664700000008],[-104.82556199999999,71.88970899999998],[-104.82250999999997,71.87414599999994],[-104.8186189999999,71.86914100000007],[-104.78999299999998,71.84137000000004],[-104.78333299999986,71.83692900000011],[-104.771118,71.8336030000001],[-104.70056199999999,71.82998700000002],[-104.68554699999993,71.8269350000001],[-104.67331699999994,71.82331799999997],[-104.66000400000001,71.81442300000009],[-104.53472899999986,71.71971100000002],[-104.37638900000002,71.59803800000003],[-104.36638600000003,71.58888200000013],[-104.35527000000002,71.574432],[-104.35916099999997,71.563309],[-104.36361699999998,71.55720499999995],[-104.37581599999993,71.54470799999996],[-104.383331,71.53831500000001],[-104.40167200000002,71.51443500000005],[-104.40361000000001,71.50860599999999],[-104.401947,71.49832200000014],[-104.34416199999993,71.41081199999996],[-104.33332799999994,71.39637800000014],[-104.35722399999986,71.357483],[-104.37165799999997,71.36080900000002],[-104.38918299999995,71.36360200000001],[-104.40805099999994,71.36499000000009],[-104.43804899999998,71.36276199999998],[-104.45056199999988,71.35971100000012],[-104.46167000000003,71.35582000000005],[-104.47138999999993,71.35108900000012],[-104.48860199999996,71.33998099999997],[-104.49333200000001,71.33415200000013],[-104.49694799999997,71.32276900000011],[-104.49500299999988,71.3124850000001],[-104.49137899999988,71.30748000000006],[-104.46250900000001,71.28109700000005],[-104.44972200000001,71.27221700000001],[-104.43888900000002,71.25776700000011],[-104.43971299999998,71.24693300000001],[-104.44055200000003,71.23609899999997],[-104.44444299999992,71.22499099999999],[-104.44888300000002,71.21887200000015],[-104.470551,71.19970699999999],[-104.49610899999999,71.18304400000011],[-104.52555799999999,71.16886900000003],[-104.55610699999994,71.15554800000007],[-104.57805599999995,71.14804100000009],[-104.59056099999998,71.145264],[-104.62361099999987,71.13360599999999],[-104.64862099999999,71.11914100000007],[-104.60472099999998,71.07971199999997],[-104.58583099999998,71.06666600000005],[-104.57028199999996,71.05831900000004],[-104.53666699999997,71.04414400000013],[-104.48916600000001,71.02470399999999],[-104.45667300000002,71.01361099999997],[-104.33778399999994,70.97970600000008],[-104.23805199999998,70.9649960000001],[-104.22389199999998,70.961929],[-104.122772,70.91470300000015],[-104.11665299999999,70.91026299999993],[-104.09999099999999,70.89137299999999],[-104.07640099999992,70.86303700000008],[-104.05277999999993,70.83442700000006],[-104.04583699999995,70.824997],[-104.04277000000002,70.80415300000004],[-104.02887699999991,70.78498800000006],[-104.01583900000003,70.77082799999994],[-104.00029,70.75721699999997],[-103.99416400000001,70.75277699999998],[-103.98528299999998,70.74887100000007],[-103.97138999999987,70.74552900000015],[-103.95472699999999,70.74275200000005],[-103.94027699999987,70.7416530000001],[-103.92443800000001,70.74192800000009],[-103.806107,70.72303799999997],[-103.73111,70.69164999999992],[-103.64083899999997,70.64665200000002],[-103.63417099999992,70.63720699999999],[-103.62470999999994,70.62803600000001],[-103.59889199999992,70.61581400000006],[-103.55638099999999,70.60081500000001],[-103.52333099999987,70.59304800000001],[-103.506958,70.59027100000014],[-103.49027999999998,70.58749400000005],[-103.473053,70.586929],[-103.44193999999999,70.58720400000004],[-103.39835399999993,70.59054600000013],[-103.34277299999997,70.59664900000007],[-103.3272169999999,70.59664900000007],[-103.30915799999997,70.595261],[-103.26500699999997,70.58166500000004],[-103.239441,70.56944300000004],[-103.20472699999993,70.54803500000014],[-103.14972699999998,70.51388500000002],[-103.13276699999994,70.50582900000012],[-103.12165800000002,70.50193800000005],[-103.095551,70.49803199999997],[-103.01194799999996,70.49220299999996],[-102.97693600000002,70.48997500000002],[-102.96056399999998,70.48915100000005],[-102.93055699999996,70.49054000000007],[-102.92027299999995,70.49498000000006],[-102.91443599999991,70.50000000000011],[-102.915009,70.50526400000007],[-102.91832699999998,70.51026899999994],[-102.92388900000003,70.51443500000005],[-102.93250299999988,70.51860000000005],[-102.95722999999998,70.52554300000003],[-102.97528099999994,70.52720599999998],[-103.03028899999998,70.53498800000011],[-103.05526700000001,70.54193100000009],[-103.0997309999999,70.55664100000007],[-103.108337,70.56053199999991],[-103.12609899999995,70.57388300000008],[-103.13999899999993,70.60942100000011],[-103.15556300000003,70.65498400000001],[-103.156113,70.659988],[-103.15387699999997,70.665817],[-103.14916999999991,70.67164600000001],[-103.13667299999992,70.6744230000001],[-103.12110899999999,70.67469800000009],[-103.104172,70.67387399999996],[-103.08583099999998,70.672485],[-103.06667299999998,70.66998300000006],[-103.0250089999999,70.66026299999999],[-103.00250199999999,70.65277100000009],[-102.85665899999992,70.59776300000004],[-102.84834299999994,70.59387199999998],[-102.84528399999999,70.58888200000013],[-102.83833300000003,70.57415800000007],[-102.83583099999998,70.54803500000014],[-102.74445300000002,70.49470500000007],[-102.61501299999992,70.46054100000003],[-102.60138699999999,70.45721400000008],[-102.52027899999996,70.43830900000012],[-102.45749699999988,70.42637600000012],[-102.40862299999998,70.41747999999995],[-102.333328,70.39776600000005],[-102.281387,70.38415500000008],[-102.11749299999997,70.33943200000004],[-101.99610899999988,70.2872010000001],[-101.97972099999998,70.27916000000005],[-101.92555199999998,70.26054400000004],[-101.89334099999996,70.25443999999999],[-101.87666300000001,70.25360100000006],[-101.86138899999997,70.25387600000005],[-101.84916699999985,70.25665300000014],[-101.83805799999993,70.260269],[-101.828056,70.26470900000004],[-101.82195299999995,70.26971400000008],[-101.81722999999988,70.2810970000001],[-101.81749699999995,70.28610200000014],[-101.80972300000002,70.29775999999998],[-101.79972800000002,70.30219999999997],[-101.714722,70.30886800000013],[-101.69803599999995,70.30802900000003],[-101.68195300000002,70.30497700000006],[-101.59944200000001,70.27581800000013],[-101.58860800000002,70.27192700000006],[-101.58029199999993,70.26776100000012],[-101.58029199999993,70.26277199999998],[-101.58556399999998,70.25665300000014],[-101.60555999999997,70.24775700000004],[-101.63417099999998,70.23304700000006],[-101.64306599999998,70.22776800000008],[-101.65083300000003,70.22137499999997],[-101.65055799999993,70.21081500000003],[-101.64222699999993,70.19636500000007],[-101.62249799999995,70.16249100000005],[-101.61416599999995,70.15304600000002],[-101.55999800000001,70.11360200000007],[-101.55194099999994,70.109421],[-101.53971899999999,70.10693400000014],[-101.52667200000002,70.10859700000003],[-101.39723200000003,70.13943500000005],[-101.39222699999999,70.15054300000003],[-101.37581599999999,70.17776500000014],[-101.358047,70.17608600000011],[-101.28666699999991,70.15248099999997],[-101.265289,70.14498900000001],[-101.25723299999999,70.14082300000013],[-101.25195300000001,70.13638300000008],[-101.23889200000002,70.13304099999999],[-101.22222899999991,70.13192700000002],[-101.14499699999999,70.15525800000006],[-101.13500999999997,70.15971399999995],[-101.12721299999998,70.1660920000001],[-101.12193300000001,70.17192100000011],[-101.11665299999993,70.18304400000011],[-101.12193300000001,70.19274900000005],[-101.11193800000001,70.19720500000011],[-101.09555099999994,70.19636500000007],[-101.03971899999999,70.18304400000011],[-100.99973299999999,70.1727600000001],[-100.98388699999992,70.16470300000015],[-100.97332799999998,70.15554800000007],[-100.97332799999998,70.14526400000005],[-100.97609699999992,70.13443000000001],[-100.96028099999995,70.05304000000007],[-100.92194399999988,69.96527100000014],[-100.88694800000002,69.88415500000002],[-100.870003,69.81442300000015],[-100.870003,69.78831500000001],[-100.87805200000003,69.77165200000013],[-100.89998600000001,69.75387599999999],[-100.92555199999998,69.72110000000004],[-100.92027300000001,69.71138000000013],[-100.92027300000001,69.70109600000012],[-100.92832899999996,69.684143],[-100.93859900000001,69.672485],[-100.94748699999997,69.66693099999998],[-100.95722999999992,69.66249099999999],[-100.96916199999998,69.65971400000006],[-101.06443799999994,69.64860499999998],[-101.28362300000003,69.66387900000007],[-101.31777999999991,69.66748000000013],[-101.32972699999988,69.66998300000012],[-101.34028599999999,69.67886400000003],[-101.43831599999993,69.76971400000002],[-101.45472699999993,69.79887400000007],[-101.46806299999997,69.8230440000001],[-101.47332799999998,69.832764],[-101.468613,69.83888200000007],[-101.458618,69.843323],[-101.43998699999997,69.853317],[-101.43472300000002,69.85914600000007],[-101.41610700000001,69.88693200000012],[-101.41860999999989,69.89193699999998],[-101.42944299999994,69.90609700000005],[-101.44526699999994,69.90914900000001],[-101.45638999999994,69.90554800000012],[-101.46888699999994,69.89305100000013],[-101.47917199999995,69.88136299999991],[-101.51972999999992,69.82832300000007],[-101.53999299999998,69.79942299999999],[-101.54750100000001,69.78776600000009],[-101.55972299999996,69.76499899999999],[-101.56221,69.754166],[-101.56194299999999,69.74914600000011],[-101.564438,69.7433170000001],[-101.569458,69.7374880000001],[-101.60777300000001,69.70582599999994],[-101.65249599999999,69.6827550000001],[-101.69193999999999,69.68026700000013],[-101.69722000000002,69.68470800000006],[-101.75805699999995,69.71775800000012],[-101.76611300000002,69.721924],[-101.77916700000003,69.72526600000015],[-101.85637700000001,69.74304200000012],[-101.87000299999994,69.74414100000007],[-101.88722200000001,69.73332199999999],[-101.89916999999997,69.73054500000012],[-101.91416900000002,69.73054500000012],[-101.92999299999997,69.73359700000003],[-101.94055200000003,69.73719800000009],[-101.94860799999998,69.74136399999998],[-101.962784,69.75305200000003],[-102.02306399999992,69.81776400000001],[-102.06555199999997,69.85054000000014],[-102.20667300000002,69.91304000000008],[-102.21749899999998,69.91693099999998],[-102.23029300000002,69.91720599999996],[-102.24082900000002,69.91331500000007],[-102.37581599999999,69.80941800000011],[-102.51027699999992,69.75804099999999],[-102.57640100000003,69.7374880000001],[-102.59249899999998,69.73831200000006],[-102.60582699999998,69.7416530000001],[-102.61638600000003,69.74525500000004],[-102.64890300000002,69.76165800000012],[-102.65972899999997,69.76527399999998],[-102.673317,69.76638800000012],[-102.68055700000002,69.759995],[-102.67443800000001,69.7502750000001],[-102.65805099999994,69.73692300000005],[-102.60028099999994,69.69802900000002],[-102.59221600000001,69.69386299999991],[-102.57640100000003,69.69108600000004],[-102.55943299999996,69.68942300000009],[-102.53138699999994,69.69136000000015],[-102.52084400000001,69.69525100000004],[-102.50917099999998,69.69802900000002],[-102.49194299999994,69.69636500000001],[-102.48361199999988,69.69220000000001],[-102.47805800000003,69.68248000000011],[-102.49777199999988,69.595261],[-102.50778199999996,69.56414799999999],[-102.51500699999985,69.5599820000001],[-102.525284,69.55636600000003],[-102.60305800000003,69.53831500000007],[-102.81304899999986,69.52970900000014],[-102.82861300000002,69.53276100000005],[-102.94387799999993,69.559418],[-103.08528099999995,69.59721400000012],[-103.18666099999996,69.62942500000003],[-103.20556599999998,69.636932],[-103.22471599999994,69.64471400000014],[-103.23277300000001,69.64860499999998],[-103.260559,69.66554300000007],[-103.27166699999998,69.6744230000001],[-103.32195300000001,69.69220000000001],[-103.41639699999996,69.7063750000001],[-103.43055699999996,69.70526100000012],[-103.47693600000002,69.69358800000009],[-103.48665599999998,69.68470800000006],[-103.50723299999999,69.617752],[-103.5041809999999,69.61303699999996],[-103.33528100000001,69.57499700000005],[-103.08917200000002,69.521927],[-103.07528699999995,69.52304100000015],[-103.05695300000002,69.52053799999999],[-103.04638699999998,69.51693699999998],[-103.03806299999997,69.51277199999998],[-103.03278399999999,69.50833100000006],[-103.02333099999998,69.49386600000008],[-103.01390099999998,69.474152],[-102.991379,69.42469800000003],[-102.99082899999996,69.41943400000002],[-103.00778199999996,69.32693500000005],[-103.01917300000002,69.28276100000011],[-103.02306399999998,69.27165200000002],[-103.04444899999999,69.25248700000009],[-103.07195299999995,69.23858600000011],[-103.11332700000003,69.22360200000003],[-103.12444299999999,69.2208250000001],[-103.16000399999996,69.21304299999997],[-103.17250099999995,69.21138000000008],[-103.19415299999997,69.20471200000009],[-103.204453,69.20082100000002],[-103.21140299999996,69.19442700000013],[-103.214447,69.18969700000014],[-103.21777299999997,69.1372070000001],[-103.208618,69.12275699999998],[-103.20305599999989,69.11831699999999],[-103.19499199999996,69.1144260000001],[-103.18222000000003,69.11109899999997],[-103.141953,69.15776100000005],[-103.13390400000003,69.16331500000007],[-103.12444299999999,69.16775500000006],[-103.10500300000001,69.176086],[-103.07417299999997,69.18748500000004],[-103.03721599999994,69.20582600000006],[-103.021118,69.21693400000004],[-103.00611900000001,69.2285920000001],[-102.9988939999999,69.23498500000005],[-102.98082699999992,69.25915500000008],[-102.96916199999993,69.27137800000008],[-102.95056199999999,69.29026800000008],[-102.943604,69.29664600000001],[-102.87249799999995,69.36053500000014],[-102.84084299999995,69.383331],[-102.829453,69.38610800000004],[-102.817497,69.38388100000003],[-102.80666400000001,69.37997400000006],[-102.79360999999994,69.37692300000003],[-102.76083399999993,69.37442000000004],[-102.74694799999997,69.37553400000002],[-102.72277799999995,69.38026400000007],[-102.51083399999999,69.43969700000008],[-102.508621,69.44552600000009],[-102.48972300000003,69.46943699999997],[-102.47193900000002,69.47943099999998],[-102.46028100000001,69.48220800000007],[-102.31304899999998,69.49832200000003],[-102.29804999999999,69.49859600000013],[-102.09306300000003,69.48776200000009],[-102.05750299999988,69.48359700000009],[-102.04750100000001,69.47998000000013],[-101.95527599999997,69.43553200000008],[-101.94748699999997,69.43136599999997],[-101.93694299999999,69.42248500000005],[-101.93138099999999,69.41276600000003],[-101.93110699999994,69.407486],[-101.93611099999998,69.401657],[-102.03527799999995,69.28720099999998],[-102.14890300000002,69.27026400000011],[-102.15943899999996,69.27388000000002],[-102.18776700000001,69.28027299999997],[-102.20140100000003,69.27916000000005],[-102.21278399999994,69.27638200000007],[-102.22972099999993,69.26554900000008],[-102.23194899999999,69.25972000000007],[-102.21721600000001,69.22526600000003],[-102.11972000000003,69.18304399999994],[-102.10665899999992,69.17970300000013],[-102.09361299999989,69.17858899999993],[-102.08112299999993,69.18026700000007],[-102.07167099999992,69.1849820000001],[-102.06416300000001,69.19136000000003],[-102.05943299999996,69.19720499999994],[-102.05721999999992,69.20277399999998],[-102.05750299999988,69.2080380000001],[-102.05444299999999,69.21443199999999],[-102.04499800000002,69.22608900000012],[-102.03666699999997,69.23165899999998],[-102.016663,69.23997500000007],[-102.00611899999996,69.24359099999998],[-101.96305799999999,69.25721699999991],[-101.95140099999998,69.25999500000012],[-101.9385989999999,69.26193199999994],[-101.92194399999994,69.26026900000005],[-101.78500399999996,69.19636500000007],[-101.77055399999995,69.18914799999999],[-101.75472999999994,69.17581200000006],[-101.75195300000001,69.16554300000001],[-101.75167799999991,69.16053799999997],[-101.75389099999995,69.14971900000006],[-101.80638099999999,69.0038760000001],[-101.80860899999993,68.99803199999991],[-101.81806899999992,68.99359100000004],[-101.85138699999993,68.98442099999994],[-101.89916999999997,68.97526600000009],[-101.94888300000002,68.96775800000006],[-101.962784,68.96665999999999],[-101.97693600000002,68.96665999999999],[-101.993607,68.96832300000011],[-102.00140399999992,68.97248800000011],[-102.02223200000003,68.99026500000014],[-102.03250100000002,68.99414100000007],[-102.04778299999998,68.99693300000013],[-102.06220999999994,68.99693300000013],[-102.09665699999994,68.98858599999994],[-102.11305199999998,68.97776799999997],[-102.12609900000001,68.966385],[-102.130829,68.96026599999993],[-102.14502699999997,68.94766199999998],[-102.15638699999994,68.94470200000006],[-102.16972399999997,68.94609100000002],[-102.323624,68.93719500000009],[-102.38612399999994,68.92553700000008],[-102.38583399999993,68.9202580000001],[-102.39028899999994,68.9144290000001],[-102.39835399999987,68.90887500000008],[-102.48554999999999,68.87136800000002],[-102.53582799999998,68.86442599999992],[-102.589722,68.86053500000008],[-102.604172,68.86026000000004],[-102.61972000000003,68.86109900000002],[-102.63500999999991,68.86387600000012],[-102.64527900000002,68.867752],[-102.76306199999999,68.87776200000008],[-102.81889299999995,68.83415200000007],[-102.89472999999992,68.79998800000004],[-102.99054699999999,68.79443400000008],[-103.00583599999999,68.79525800000005],[-103.047234,68.80970799999994],[-103.146118,68.84054600000013],[-103.16416899999996,68.84304800000001],[-103.19499199999996,68.84443700000003],[-103.208618,68.84359699999999],[-103.32084699999996,68.82971200000009],[-103.34111000000001,68.82222000000013],[-103.36000099999995,68.81387299999994],[-103.36805700000002,68.80831899999998],[-103.40306099999992,68.77720599999998],[-103.50917099999987,68.80137599999995],[-103.83583099999993,68.83638000000002],[-104.09472699999992,68.85664400000002],[-104.11028299999998,68.85942100000005],[-104.13834399999996,68.86554000000012],[-104.287781,68.9019320000001],[-104.40249599999999,68.9310910000001],[-104.43083199999995,68.9369200000001],[-104.445267,68.938873],[-104.45749699999999,68.936646],[-104.46167000000003,68.93054200000012],[-104.46305799999988,68.92498799999993],[-104.46250900000001,68.91970800000007],[-104.47444199999995,68.90165700000006],[-104.487503,68.88888500000007],[-104.50279199999989,68.87776200000008],[-104.51167299999992,68.87303200000002],[-104.52139299999999,68.86914099999996],[-104.54360999999989,68.86331199999995],[-104.583618,68.85971100000012],[-104.84999099999993,68.87025499999999],[-105.12917299999998,68.89637800000008],[-105.14472999999992,68.89915500000001],[-105.16610699999995,68.9060970000001],[-105.193329,68.91748000000013],[-105.2488939999999,68.94552600000003],[-105.18305999999995,68.98831200000001],[-105.173317,68.99192800000009],[-105.14666699999998,68.99247700000001],[-105.128601,68.98997500000013],[-105.06471299999998,68.98692300000005],[-105.03916900000002,68.99026500000014],[-104.936394,69.03054800000001],[-104.928879,69.03610200000003],[-104.91610700000001,69.04887400000001],[-104.91166699999991,69.06581100000005],[-104.915009,69.07054100000005],[-104.92304999999999,69.07470699999999],[-104.93388399999998,69.07832300000001],[-105.06500199999999,69.10415599999999],[-105.083328,69.10636900000009],[-105.096657,69.10525500000011],[-105.122772,69.09109500000005],[-105.16027799999995,69.07193000000007],[-105.47361799999999,69.10693400000014],[-105.48055999999997,69.11665299999993],[-105.49249299999991,69.12525900000003],[-105.50695799999994,69.13360600000004],[-105.51528899999994,69.13749700000011],[-105.553879,69.15248099999997],[-105.58056599999998,69.15637200000003],[-105.61694299999994,69.16081200000008],[-105.76806599999998,69.17137100000014],[-105.83029199999999,69.172211],[-105.87416100000002,69.17109700000003],[-105.902222,69.16914400000007],[-105.91443600000002,69.16720599999996],[-105.92555199999998,69.164154],[-106.03888699999993,69.15386999999998],[-106.17777999999998,69.14415000000008],[-106.193604,69.14471400000002],[-106.256958,69.15498400000013],[-106.28888699999999,69.16026299999993],[-106.39611799999994,69.17804000000001],[-106.40611299999995,69.18054200000006],[-106.41471899999999,69.18441799999994],[-106.41471899999999,69.1952510000001],[-106.41027799999995,69.217758],[-106.40666199999998,69.22387700000007],[-106.3944469999999,69.23692299999999],[-106.38612399999994,69.24165300000004],[-106.37638899999996,69.24552900000009],[-106.30777,69.26220699999999],[-106.28832999999992,69.26998900000012],[-106.27362099999993,69.28137200000015],[-106.26777600000003,69.29220600000002],[-106.26889,69.29721100000006],[-106.31639100000001,69.38665800000007],[-106.49527,69.47442600000011],[-106.52139299999993,69.48609899999997],[-106.54138199999989,69.49331699999999],[-106.55499299999985,69.49636800000002],[-106.57112099999989,69.49887099999995],[-106.60221899999999,69.49887099999995],[-106.61444099999994,69.496643],[-106.62554899999986,69.4935910000001],[-106.73306299999996,69.44165000000004],[-106.74027999999998,69.43580600000001],[-106.74388099999993,69.42970300000007],[-106.74553700000001,69.407761],[-106.86277799999999,69.36914100000007],[-106.93083200000001,69.36164900000011],[-106.95500199999992,69.35720800000001],[-106.96611000000001,69.3541560000001],[-106.98554999999999,69.34610000000004],[-106.99249299999997,69.34054600000002],[-106.99722300000002,69.33526599999999],[-106.99833699999999,69.32971199999997],[-106.99694799999997,69.32443200000006],[-106.96528599999994,69.30304000000007],[-106.95749699999993,69.29332],[-106.925003,69.23942599999998],[-106.92223399999995,69.2288670000001],[-106.929169,69.2166600000001],[-106.93611099999998,69.21110500000003],[-106.94444299999998,69.20637500000004],[-106.96362299999993,69.19831800000003],[-107.03999299999998,69.18109100000004],[-107.12832600000002,69.1544340000001],[-107.13806199999999,69.15054300000003],[-107.16221599999994,69.13443000000001],[-107.19167299999998,69.11248799999993],[-107.22666900000002,69.08415200000002],[-107.248894,69.06805400000002],[-107.264183,69.05748000000011],[-107.27944899999994,69.04693600000007],[-107.304169,69.03248599999995],[-107.31360599999994,69.02859500000011],[-107.34221599999995,69.01887499999998],[-107.37444299999993,69.00943000000012],[-107.43167099999994,68.99636800000007],[-107.50334199999992,68.98275800000005],[-107.55387899999994,68.97554000000002],[-107.64611799999989,68.96554600000002],[-107.67388900000003,68.96360800000008],[-107.74610899999999,68.96081500000008],[-107.93749999999994,68.93498199999993],[-107.95584099999996,68.9310460000001],[-107.97693600000002,68.93054200000012],[-108.17555199999998,68.9310910000001],[-108.20944199999997,68.93331900000004],[-108.26444999999995,68.93914800000005],[-108.29833999999988,68.94136000000009],[-108.42804699999994,68.94581600000004],[-108.49221799999992,68.94747899999993],[-108.521118,68.94636500000013],[-108.53443900000002,68.94470200000006],[-108.54611199999994,68.94247400000006],[-108.56331599999993,68.93359400000003],[-108.56388900000002,68.92776500000002],[-108.55082699999997,68.91943400000014],[-108.54194599999994,68.91554300000007],[-108.535553,68.91137699999996],[-108.531387,68.90664700000013],[-108.52971599999995,68.90138200000007],[-108.53028899999993,68.89582800000005],[-108.535553,68.88916000000006],[-108.55139200000002,68.87942500000003],[-108.59722899999997,68.85914600000007],[-108.67443799999995,68.82943700000004],[-108.926941,68.74443100000013],[-108.93749999999994,68.74108899999999],[-108.97250400000001,68.73387099999997],[-109.10472099999998,68.71054100000003],[-109.19138299999992,68.69720500000005],[-109.23416099999997,68.69497700000011],[-109.26390099999998,68.69442700000008],[-109.31194299999999,68.6958160000001],[-109.345551,68.69775400000003],[-109.37416100000002,68.69636500000001],[-109.39998600000001,68.69331399999999],[-109.43472300000002,68.68609599999996],[-109.49137899999994,68.67330899999996],[-109.52306399999992,68.6649930000001],[-109.55359599999991,68.655258],[-109.59722899999997,68.64387499999998],[-109.64362299999999,68.63443000000012],[-109.65638699999994,68.6327510000001],[-109.68331899999998,68.63053900000006],[-109.756958,68.6285860000001],[-109.97028399999999,68.62719700000008],[-110.12416099999996,68.62719700000008],[-110.16055299999994,68.63053900000006],[-110.19167299999998,68.63081400000004],[-110.22000099999997,68.62915000000004],[-110.24416400000001,68.62525900000014],[-110.26306199999999,68.61775200000005],[-110.27194199999997,68.61360200000001],[-110.27916700000003,68.60859700000015],[-110.295547,68.59942600000005],[-110.32917800000001,68.58221400000002],[-110.33917200000002,68.57887299999999],[-110.35082999999997,68.57638500000002],[-110.36361699999998,68.57470700000005],[-110.37777699999998,68.57415800000012],[-110.391388,68.57666],[-110.39806399999986,68.58082600000012],[-110.42027299999995,68.60415600000005],[-110.42722300000003,68.60832199999999],[-110.44082600000002,68.61109900000008],[-110.45889299999999,68.61276199999998],[-110.56111099999998,68.61665300000004],[-110.576683,68.61665300000004],[-110.5894469999999,68.61499000000015],[-110.60944399999994,68.60832199999999],[-110.61694299999994,68.6035920000001],[-110.63417099999987,68.59526100000005],[-110.65695199999999,68.59027100000014],[-110.68138099999999,68.58610500000009],[-110.89666699999998,68.55720500000001],[-110.92223399999995,68.55386399999998],[-110.950287,68.55192600000004],[-111.01363400000002,68.55276500000002],[-111.03195199999999,68.55442800000014],[-111.03859699999992,68.55859400000003],[-111.03500400000001,68.563873],[-110.98332199999993,68.57777399999998],[-110.97193900000002,68.58027600000008],[-110.95777900000002,68.58110000000005],[-110.92555199999993,68.58027600000008],[-110.89723200000003,68.58194000000009],[-110.87165800000002,68.5852660000001],[-110.86028299999987,68.5877690000001],[-110.850281,68.59109500000011],[-110.84306299999997,68.59609999999998],[-110.84306299999997,68.601654],[-110.84973099999996,68.60582000000005],[-110.86361699999992,68.60859700000015],[-111.01750199999998,68.59832799999998],[-111.03028899999998,68.59664900000013],[-111.05888399999998,68.58581500000008],[-111.068893,68.58248900000001],[-111.08029199999999,68.57998700000013],[-111.09306300000003,68.57832300000013],[-111.13527699999997,68.57582100000008],[-111.16639700000002,68.57582100000008],[-111.23249800000002,68.57804900000002],[-111.26750199999998,68.58055100000007],[-111.28362299999998,68.58276400000005],[-111.32000700000003,68.58581500000008],[-111.33693699999998,68.58665500000012],[-111.37917299999998,68.58415200000013],[-111.39195299999994,68.58248900000001],[-111.41166699999997,68.57554600000003],[-111.41665599999999,68.57110600000004],[-111.40527299999997,68.56805400000007],[-111.389183,68.56581099999994],[-111.29804999999999,68.55775500000004],[-111.2502899999999,68.55720500000001],[-111.23194899999999,68.55554200000012],[-111.21833800000002,68.55276500000002],[-111.20916699999998,68.54914899999994],[-111.204453,68.54470800000007],[-111.204453,68.53887900000001],[-111.21112099999999,68.52609300000012],[-111.21556099999992,68.51944000000015],[-111.22556299999997,68.516098],[-111.23805199999993,68.5144350000001],[-111.25361599999991,68.5144350000001],[-111.358612,68.52165200000002],[-111.37471,68.52360499999998],[-111.38834400000002,68.52638200000007],[-111.46806300000003,68.53692600000011],[-111.52278100000001,68.5416560000001],[-111.60056299999991,68.54359400000004],[-111.85109699999998,68.53414900000001],[-112.060272,68.52304100000003],[-112.21000700000002,68.51361099999997],[-112.23665599999987,68.51081799999997],[-112.35916099999997,68.50193800000011],[-112.40110799999997,68.499146],[-112.50917099999992,68.49803200000002],[-112.63527699999992,68.48304700000006],[-112.63694800000002,68.47692899999993],[-112.64527900000002,68.47276300000004],[-112.67027299999995,68.46914699999996],[-112.72749299999992,68.46582000000006],[-112.77390299999996,68.46554600000013],[-112.80750299999994,68.4666600000001],[-113.05166600000001,68.46415700000011],[-113.091949,68.46026600000005],[-113.220551,68.45277400000009],[-113.25140399999992,68.4522090000001],[-113.26944699999996,68.4538730000001],[-113.297234,68.45860299999993],[-113.30444299999999,68.46276900000004],[-113.30943300000001,68.46720900000003],[-113.310272,68.47303800000003],[-113.30638099999993,68.47970600000002],[-113.29972800000002,68.48471100000006],[-113.29138199999994,68.4891510000001],[-113.26944699999996,68.49443099999996],[-113.256958,68.49609400000008],[-113.193604,68.49636800000002],[-113.05166600000001,68.48748799999998],[-113.03778099999994,68.48831200000012],[-113.03388999999999,68.49498000000011],[-113.04360999999994,68.50416600000005],[-113.07250999999991,68.52053800000004],[-113.11805700000002,68.54443400000014],[-113.141388,68.55053700000008],[-113.19721999999996,68.56025699999998],[-113.21333300000003,68.56219500000009],[-113.26888999999994,68.57222000000002],[-113.33416699999998,68.58554100000015],[-113.35777299999995,68.59136999999998],[-113.36721799999992,68.594986],[-113.38166799999988,68.60304300000001],[-113.44304699999998,68.64054899999996],[-113.44833399999999,68.645264],[-113.45111099999997,68.65026900000004],[-113.45249899999999,68.66165200000006],[-113.45084400000002,68.667755],[-113.52443700000003,68.72499099999993],[-113.66665599999999,68.80219999999991],[-113.676941,68.81109600000008],[-113.67887899999994,68.89471400000008],[-113.67722299999997,68.90081800000013],[-113.671944,68.90664700000013],[-113.623894,68.93331900000004],[-113.60694899999993,68.94247400000006],[-113.58444199999997,68.94802899999996],[-113.57472199999995,68.95138500000002],[-113.569458,68.95721400000002],[-113.545837,69.043045],[-113.54499799999996,69.04803500000008],[-113.55471799999987,69.05137600000012],[-113.61501299999998,69.06637600000005],[-113.63221699999997,69.07388300000002],[-113.64723199999992,69.08194000000015],[-113.65778399999999,69.09109500000005],[-113.69611399999991,69.15470900000014],[-113.69220699999994,69.18942300000003],[-113.68083200000001,69.19192500000008],[-113.66583300000002,69.1910860000001],[-113.65583800000002,69.18748500000004],[-113.62193300000001,69.17804000000001],[-113.53888699999999,69.16859400000004],[-113.51972999999998,69.16720599999996],[-113.50862099999995,69.16970800000001],[-113.51363399999997,69.17442300000005],[-113.52111799999994,69.17858899999993],[-113.55359599999991,69.18719500000003],[-113.58000199999992,69.192474],[-113.62332200000003,69.19970700000005],[-113.90888999999999,69.24192800000003],[-114.27555799999999,69.28193699999997],[-114.311394,69.284988],[-114.328888,69.28553800000003],[-114.39277600000003,69.28414900000001],[-114.42138699999998,69.28193699999997],[-114.4472199999999,69.27804600000007],[-114.49249299999991,69.26721200000003],[-114.51834100000002,69.26332100000013],[-114.66972399999997,69.255829],[-114.764183,69.25221299999998],[-115.08889799999992,69.24470500000012],[-115.25361599999991,69.24525499999999],[-115.40083299999998,69.25694299999998],[-115.64472999999998,69.27331500000014],[-115.79527299999995,69.28276100000011],[-115.92138699999992,69.29026800000008],[-115.95584099999996,69.29220600000002],[-115.96833799999996,69.29498300000012],[-115.9786069999999,69.29859899999997],[-115.98665599999998,69.30247500000002],[-116.00029,69.31080600000013],[-116.00611900000001,69.31526200000002],[-116.016953,69.32222000000002],[-116.026947,69.32554600000009],[-116.05638099999999,69.32998699999996],[-116.17527799999993,69.34165999999999],[-116.21945199999999,69.34832799999998],[-116.52583300000003,69.407486],[-116.53859699999998,69.4102630000001],[-116.54888900000003,69.41360500000002],[-116.56527699999992,69.42137100000008],[-116.62970699999994,69.45887800000014],[-116.63137799999993,69.46470600000004],[-116.6266629999999,69.47053500000004],[-116.61888099999993,69.47499099999999],[-116.60777300000001,69.47804300000007],[-116.569458,69.48414600000001],[-116.561394,69.48858600000005],[-116.55860899999993,69.4952550000001],[-116.57556199999993,69.5558170000001],[-116.58138999999989,69.56053199999997],[-116.591949,69.563873],[-116.60472099999993,69.566666],[-116.63667299999997,69.57026700000006],[-116.73388699999998,69.57554600000003],[-116.74999999999994,69.57499700000005],[-116.75945299999995,69.57138100000003],[-116.76611299999996,69.56517799999995],[-116.78138699999988,69.55720500000001],[-116.89750700000002,69.58749400000005],[-116.88054699999986,69.60887100000008],[-116.85193600000002,69.61970500000012],[-116.84612299999998,69.64305100000001],[-116.84750399999996,69.64860499999998],[-116.858047,69.6519320000001],[-116.96193700000003,69.67942799999997],[-116.987503,69.68498199999999],[-117.01777600000003,69.68942300000009],[-117.03500399999996,69.690811],[-117.05027799999993,69.69303899999994],[-117.07584400000002,69.69859300000013],[-117.11805699999996,69.71165499999995],[-117.23889200000002,69.75305200000003],[-117.24749799999995,69.75694300000009],[-117.26917300000002,69.78166200000004],[-117.27278100000001,69.79275500000006],[-117.30777,69.84443699999997],[-117.36721799999992,69.91998300000006],[-117.42250099999995,69.97248800000006],[-117.43499799999995,69.98136900000003],[-117.43666099999996,69.98692299999999],[-117.43611099999993,69.99304200000006],[-117.41528299999993,70.00999500000012],[-117.38527699999997,70.02859500000005],[-117.35637700000001,70.03970300000003],[-117.32584400000002,70.04998799999998],[-117.28362300000003,70.06330900000012],[-117.25140399999992,70.072769],[-117.23999000000003,70.07582100000013],[-117.19444299999998,70.08749399999994],[-117.16999800000002,70.09248400000001],[-117.12082700000002,70.10247800000002],[-117.08167999999995,70.10887100000014],[-117.01083399999993,70.11692800000014],[-116.87721299999998,70.1291500000001],[-116.58306899999997,70.15693700000008],[-116.236107,70.19136000000003],[-116.16639700000002,70.19999700000005],[-116.09999099999999,70.21026600000005],[-116.07167099999998,70.21360800000002],[-115.90834000000001,70.2288670000001],[-115.80194099999994,70.23664900000006],[-115.69360399999994,70.24386600000014],[-115.64695699999993,70.24664300000006],[-115.49665799999997,70.25054900000009],[-115.44833399999993,70.25248700000003],[-115.31471299999998,70.26416000000006],[-115.30139200000002,70.26638800000006],[-115.229446,70.27387999999996],[-115.16750299999995,70.27777100000003],[-115.08389299999999,70.27970899999997],[-115.03028899999998,70.27998400000001],[-114.86721799999998,70.28387500000008],[-114.80194099999989,70.28610200000014],[-114.741379,70.290817],[-114.71305799999988,70.29386900000009],[-114.65888999999999,70.30165100000005],[-114.61694299999994,70.30664100000007],[-114.58833299999992,70.309708],[-114.54305999999997,70.31330900000006],[-114.511124,70.31469699999997],[-114.323624,70.316666],[-114.254997,70.31721500000015],[-114.21833800000002,70.31608599999998],[-114.17832900000002,70.31359900000007],[-114.16082799999998,70.31164599999994],[-114.13527699999997,70.30581699999993],[-114.111107,70.29386900000009],[-114.09028599999994,70.28692600000011],[-114.057503,70.28248600000006],[-113.84166700000003,70.26944000000015],[-113.68388399999992,70.26304600000009],[-113.65055799999993,70.26361099999997],[-113.59166700000003,70.2686000000001],[-113.54943799999995,70.27331500000014],[-113.50556899999998,70.27748100000002],[-113.46000700000002,70.28054800000012],[-113.42804699999999,70.2816620000001],[-113.39138799999995,70.28054800000012],[-113.33332799999994,70.27720600000004],[-113.296112,70.27387999999996],[-113.16832699999998,70.25915500000002],[-113.09084299999995,70.24748199999999],[-112.66665599999993,70.2038730000001],[-112.56471299999998,70.19831800000003],[-112.54804999999999,70.19859300000002],[-112.53278399999994,70.19941699999998],[-112.52084399999995,70.2022090000001],[-112.51722699999999,70.20748899999995],[-112.52749599999993,70.21110500000003],[-112.56304899999998,70.21360800000002],[-112.577789,70.21609500000005],[-112.58084100000002,70.22137499999997],[-112.57501200000002,70.22720300000009],[-112.56582599999996,70.23136899999997],[-112.55526700000001,70.234985],[-112.54332699999992,70.23748799999998],[-112.295547,70.26666300000005],[-112.212784,70.26582300000001],[-112.195831,70.26582300000001],[-112.16388699999999,70.26693699999998],[-112.13834399999996,70.27137800000008],[-112.14584400000001,70.27554300000008],[-112.16306299999991,70.27748100000002],[-112.24249299999991,70.28360000000004],[-112.29695099999998,70.28915400000005],[-112.30471799999992,70.29331999999994],[-112.29723399999995,70.29832500000003],[-112.28333299999997,70.2999880000001],[-112.266663,70.30026200000003],[-112.24833699999999,70.2994230000001],[-112.23111,70.29748499999994],[-112.10888699999992,70.27748100000002],[-111.92639199999996,70.25221299999993],[-111.91583300000002,70.25555399999996],[-111.90805099999989,70.26054400000004],[-111.89917000000003,70.26470900000004],[-111.88054699999998,70.27026400000011],[-111.86527999999993,70.27137800000008],[-111.84861799999993,70.27137800000008],[-111.743607,70.26944000000015],[-111.55555700000002,70.26971400000008],[-111.53888699999993,70.26998900000007],[-111.46806300000003,70.27832000000001],[-111.45445299999989,70.27998400000001],[-111.445267,70.28414900000001],[-111.44275699999992,70.29026800000003],[-111.487213,70.33692900000005],[-111.49472000000003,70.34109499999994],[-111.50723299999993,70.34414700000008],[-111.53694200000001,70.34942600000005],[-111.631104,70.35832199999999],[-111.66471899999999,70.35803199999998],[-111.69387799999998,70.35554500000006],[-111.73528299999998,70.35026600000009],[-111.75055700000001,70.34942600000005],[-111.803879,70.35081500000001],[-111.98055999999991,70.37081899999998],[-112.00083899999987,70.37803600000007],[-112.053879,70.401093],[-112.06166099999996,70.405258],[-112.06973299999993,70.4149930000001],[-112.07250999999997,70.42025799999999],[-112.073059,70.43165599999998],[-112.07584400000002,70.43664600000005],[-112.08917200000002,70.45109600000012],[-112.11527999999998,70.474152],[-112.14611799999994,70.49054000000007],[-112.156387,70.49414100000013],[-112.16915899999998,70.497208],[-112.19915800000001,70.5022130000001],[-112.42722299999997,70.52638200000001],[-112.49553700000001,70.51527400000003],[-112.5,70.51474000000007],[-112.50945300000001,70.51361100000008],[-112.52806099999998,70.51416],[-112.58612099999999,70.5249940000001],[-112.62193300000001,70.534424],[-112.65278599999994,70.54525800000005],[-112.670837,70.55276500000014],[-112.67859599999991,70.55693100000008],[-112.70973199999997,70.56749000000008],[-112.72805799999998,70.56832900000006],[-112.81471299999993,70.56805400000007],[-112.84861799999993,70.56776400000001],[-112.85610999999994,70.56275899999997],[-112.93749999999994,70.56721500000009],[-113.00083899999993,70.57665999999995],[-113.01611300000002,70.57916300000011],[-113.14222699999999,70.60609399999998],[-113.30304699999994,70.64193699999998],[-113.49221799999992,70.67720000000003],[-113.51112399999994,70.67776500000002],[-113.51999699999993,70.67359899999997],[-113.51917299999997,70.66775500000011],[-113.5227809999999,70.65554799999995],[-113.528343,70.64971900000012],[-113.54055800000003,70.64694200000002],[-113.55444299999994,70.64498900000012],[-113.57140399999997,70.64471400000008],[-113.59166700000003,70.6461030000001],[-113.60722399999997,70.64860499999998],[-113.63054699999998,70.65498400000001],[-113.64917000000003,70.66276600000015],[-113.66528299999999,70.67082200000004],[-113.68388399999992,70.678314],[-113.72860700000001,70.69164999999992],[-113.76194800000002,70.69609100000002],[-113.88221699999997,70.71026599999993],[-113.93831599999993,70.71527100000003],[-113.97416699999991,70.71554600000002],[-113.98972299999997,70.71443200000004],[-114.015556,70.70999100000012],[-114.06833599999993,70.69247400000006],[-114.089447,70.68525699999998],[-114.12082699999996,70.67469800000009],[-114.14362299999999,70.6685940000001],[-114.171112,70.66470300000003],[-114.20834400000001,70.665817],[-114.26194800000002,70.67137100000002],[-114.323059,70.67526200000009],[-114.37748699999997,70.67581200000012],[-114.40834000000001,70.67359899999997],[-114.4202729999999,70.67082200000004],[-114.43083200000001,70.66720600000002],[-114.44833399999999,70.65860000000009],[-114.45889299999999,70.65525800000012],[-114.49500299999994,70.64694200000002],[-114.54527299999995,70.63610799999998],[-114.571121,70.63136299999996],[-114.64111299999996,70.62248200000005],[-114.98916599999995,70.6038670000001],[-115.13694800000002,70.59803800000009],[-115.25250199999994,70.60137900000012],[-115.38054699999998,70.60470600000008],[-115.39943700000003,70.60498000000001],[-115.88971700000002,70.595261],[-115.921944,70.59359699999999],[-115.97609699999998,70.58526600000005],[-116.05555700000002,70.57222000000013],[-116.08556399999992,70.58776900000004],[-116.16251399999999,70.62303200000008],[-116.17111199999994,70.62692300000015],[-116.26363400000002,70.63472000000007],[-116.36389200000002,70.63916000000012],[-116.380829,70.63888500000007],[-116.52999899999992,70.63247700000011],[-116.63221699999997,70.61499000000009],[-116.65583800000002,70.60914600000007],[-116.66915899999998,70.60720800000013],[-116.71501199999994,70.60304300000013],[-116.90110799999997,70.59721400000012],[-116.91972399999997,70.59748800000006],[-117.05972300000002,70.60137900000012],[-117.10056299999997,70.60331700000006],[-117.34584000000001,70.61499000000009],[-117.34973100000002,70.61998000000011],[-117.35861199999994,70.62387100000001],[-117.37666300000001,70.62553400000013],[-117.50556899999998,70.61692800000003],[-117.51528899999994,70.61331199999995],[-117.51806599999986,70.60636899999997],[-117.51862299999993,70.60026600000003],[-117.52500900000001,70.59498599999995],[-117.54360999999994,70.595261],[-117.5594329999999,70.59721400000012],[-117.61305199999998,70.60859700000015],[-117.671112,70.62441999999999],[-117.70472699999999,70.63415500000002],[-117.724716,70.64137300000004],[-117.73777799999993,70.65026899999998],[-117.74194299999994,70.65525800000012],[-117.741669,70.66137699999996],[-117.73944099999994,70.66693099999998],[-117.73473399999995,70.67303500000003],[-117.72222899999986,70.68331900000004],[-117.71417199999996,70.68803400000007],[-117.70944199999985,70.69386300000008],[-117.71140300000002,70.6997070000001],[-117.71806300000003,70.70387299999999],[-117.73581699999994,70.71165500000012],[-117.74694799999997,70.71499599999999],[-117.89806399999998,70.75610400000011],[-117.94554099999999,70.76859999999999],[-118.00890400000003,70.783051],[-118.04750100000001,70.79165600000005],[-118.09277299999997,70.80470300000007],[-118.13583399999999,70.81805400000002],[-118.16750300000001,70.82859800000006],[-118.18776700000001,70.83610499999998],[-118.20584099999996,70.84387200000015],[-118.26445000000001,70.87191800000005],[-118.28028899999993,70.87997400000012],[-118.30972300000002,70.89721700000001],[-118.31639100000001,70.90165700000006],[-118.32972699999993,70.91053799999997],[-118.40862299999998,70.970261],[-118.41750300000001,70.98027000000002],[-118.41972399999986,70.98580900000002],[-118.41944899999993,70.99192800000003],[-118.415009,70.99803200000008],[-118.40862299999998,71.00332600000007],[-118.40055799999999,71.00776699999994],[-118.37082700000002,71.01914999999997],[-118.33944699999995,71.02943399999998],[-118.2725069999999,71.04887400000001],[-117.98055999999997,71.12442000000004],[-117.84973099999996,71.15693700000003],[-117.79666099999992,71.16638200000011],[-117.728882,71.16970800000013],[-117.69055199999997,71.16943400000002],[-117.640289,71.17192100000011],[-117.54305999999991,71.1785890000001],[-117.49445300000002,71.18193100000002],[-117.41665599999988,71.18887300000011],[-117.38722199999995,71.192474],[-117.28859699999992,71.20664999999997],[-116.98528299999998,71.23609899999997],[-116.83666999999997,71.26914999999991],[-116.83332799999994,71.27609300000012],[-116.82472200000001,71.28054800000012],[-116.80055199999993,71.28610200000008],[-116.71333300000003,71.297211],[-116.66972399999992,71.30276500000002],[-116.60166900000002,71.313873],[-116.51777600000003,71.32638499999996],[-116.40583800000002,71.34304800000007],[-116.20889299999993,71.36415099999999],[-116.17722300000003,71.36665300000004],[-116.14195299999989,71.367752],[-116.08556399999992,71.36747700000001],[-116.077789,71.36581400000006],[-116.05249000000003,71.35609399999998],[-115.81027199999994,71.36276199999998],[-115.77667200000002,71.36442599999998],[-115.76083399999993,71.36581400000006],[-115.74638399999998,71.36831700000005],[-115.73416099999986,71.37136800000007],[-115.72693599999997,71.37637300000011],[-115.72666900000002,71.38136299999996],[-115.73306299999996,71.38581800000003],[-115.74416400000001,71.38916000000012],[-115.75805700000001,71.39193700000004],[-115.79055800000003,71.39637800000014],[-115.84166700000003,71.39444000000003],[-115.85582699999992,71.39221200000003],[-115.885559,71.38916000000012],[-115.91915899999998,71.38720699999999],[-115.93360899999999,71.38888500000013],[-116.01777599999997,71.41110199999997],[-116.06471299999998,71.43858300000005],[-115.82805599999995,71.483047],[-115.76306199999999,71.49026500000002],[-115.62082700000002,71.49859600000008],[-115.60472099999993,71.49609400000003],[-115.58444199999991,71.488876],[-115.58416699999998,71.48525999999998],[-115.53555299999994,71.47026100000011],[-115.41555800000003,71.4497070000001],[-115.37832599999996,71.4497070000001],[-115.20028699999995,71.47943099999998],[-115.17527799999988,71.48498500000011],[-115.06667299999998,71.51860000000005],[-115.05750299999994,71.52304100000015],[-115.06194299999999,71.526657],[-115.08168,71.52720599999992],[-115.11361699999998,71.52470400000004],[-115.15638699999994,71.51887500000004],[-115.17054699999994,71.516663],[-115.24553700000001,71.50000000000011],[-115.26000999999997,71.49803199999997],[-115.32224300000001,71.49247700000006],[-115.44275699999992,71.48803700000008],[-115.45973200000003,71.48915100000005],[-115.53859699999998,71.50082400000008],[-115.54998799999998,71.5044400000001],[-115.55860899999999,71.508331],[-115.55583199999995,71.51361100000008],[-115.54332699999986,71.516663],[-115.53083800000002,71.51944000000009],[-115.516663,71.52137800000003],[-115.5122219999999,71.53776600000009],[-115.61888099999987,71.55525200000005],[-115.65499899999992,71.55802900000009],[-115.70638999999994,71.55581700000005],[-115.79194599999994,71.54359399999998],[-115.87638900000002,71.53276100000005],[-115.965012,71.52221699999996],[-116.16027799999989,71.49971000000005],[-116.20805399999995,71.49581899999998],[-116.28250100000002,71.49552899999998],[-116.33389299999999,71.4933170000001],[-116.41361999999998,71.48664899999994],[-116.443604,71.48332200000004],[-116.806107,71.43609600000013],[-116.98610699999995,71.42720000000003],[-117.17666600000001,71.40470900000003],[-117.20111099999997,71.3983310000001],[-117.21528599999994,71.39637800000014],[-117.328056,71.38610800000004],[-117.35944399999994,71.38333100000011],[-117.37721299999987,71.3827510000001],[-117.39835399999998,71.38388099999997],[-117.41221599999994,71.38638300000002],[-117.41665599999988,71.3913730000001],[-117.41610700000001,71.39776600000005],[-117.41306299999997,71.40443400000004],[-117.39083900000003,71.43525700000004],[-117.38110399999994,71.44720500000005],[-117.37832600000002,71.45416300000005],[-117.44776899999988,71.47387700000013],[-117.49445300000002,71.48692300000005],[-117.51750199999998,71.4933170000001],[-117.545837,71.49887100000012],[-117.56276699999995,71.49971000000005],[-117.628601,71.46775800000012],[-117.63333099999994,71.46192900000011],[-117.63166799999999,71.4563750000001],[-117.62471,71.4519350000001],[-117.61305199999998,71.44859300000013],[-117.596657,71.44636500000001],[-117.55583200000001,71.44525100000004],[-117.5369419999999,71.44386299999991],[-117.506393,71.4391480000001],[-117.48332199999999,71.43248000000011],[-117.47888199999989,71.42747500000007],[-117.48194899999999,71.42053200000004],[-117.51722699999999,71.37942500000003],[-117.52749599999993,71.375809],[-117.53943600000002,71.37275700000009],[-117.59416199999987,71.37164300000006],[-117.68138099999993,71.37970000000007],[-117.75666799999999,71.37608300000011],[-117.79444899999999,71.36804200000006],[-117.82749899999999,71.37220800000011],[-117.94833399999999,71.37776200000013],[-118.01500699999997,71.37303200000008],[-118.03278399999994,71.37248200000005],[-118.09084299999995,71.37275700000009],[-118.112213,71.37359600000002],[-118.18536399999999,71.37979100000013],[-118.24388099999999,71.38998400000008],[-118.25556899999998,71.393326],[-118.28362300000003,71.40470900000003],[-118.29750099999995,71.41360500000013],[-118.31111099999993,71.42858900000004],[-118.31527699999992,71.43969700000002],[-118.31471299999998,71.45220900000004],[-118.30943300000001,71.46582000000001],[-118.28999299999992,71.48165900000009],[-118.28195199999988,71.48609899999991],[-118.2633439999999,71.49414100000007],[-118.21250900000001,71.51304600000003],[-118.20221699999996,71.516663],[-118.19027699999998,71.51971400000002],[-118.17804699999994,71.5227660000001],[-118.12609900000001,71.53305100000006],[-118.08612099999988,71.54026799999997],[-118.05444299999999,71.54304500000006],[-117.83583099999998,71.55470300000007],[-117.70722999999998,71.54942299999999],[-117.68720999999994,71.54998800000004],[-117.675003,71.55276500000014],[-117.658051,71.56164600000005],[-117.65139799999992,71.56694000000005],[-117.65583800000002,71.57193000000012],[-117.66999800000002,71.57470699999999],[-117.87304699999993,71.611649],[-117.88722199999995,71.6141510000001],[-117.90888999999999,71.61499000000003],[-117.86361699999998,71.6394350000001],[-117.718887,71.65971400000001],[-117.70694700000001,71.6624910000001],[-117.69638099999992,71.66609199999999],[-117.70084399999996,71.67137100000014],[-117.715012,71.67387400000013],[-117.73665599999993,71.6749880000001],[-118.01000999999997,71.67248499999994],[-118.02778599999994,71.67164600000001],[-118.11665299999993,71.65277100000003],[-118.12693799999988,71.64888000000013],[-118.17278299999998,71.62803600000001],[-118.17749000000003,71.62191800000005],[-118.16388699999993,71.60693399999997],[-118.16639699999996,71.59999099999999],[-118.17666600000001,71.59637499999997],[-118.19082600000002,71.59414699999996],[-118.29998799999993,71.58332800000011],[-118.31777999999991,71.582764],[-118.33444199999997,71.58471700000013],[-118.36527999999998,71.58943199999993],[-118.38639799999999,71.61360200000013],[-118.38612399999994,71.61970500000007],[-118.45500199999987,71.65081800000007],[-118.485817,71.65554800000012],[-118.56639099999995,71.66276600000015],[-118.60527000000002,71.66415400000005],[-118.84166700000003,71.66470299999997],[-118.85555999999997,71.6624910000001],[-118.86389199999996,71.65803500000004],[-118.90387699999997,71.61470000000003],[-118.90387699999997,71.6083220000001],[-118.88971699999996,71.599716],[-118.88027999999991,71.5958250000001],[-118.86609599999997,71.586929],[-118.8683319999999,71.58027600000003],[-118.88054699999998,71.5772090000001],[-118.89778099999995,71.57777400000009],[-118.90972899999991,71.58109999999999],[-119.05027799999999,71.6266480000001],[-119.07472200000001,71.64414999999997],[-119.08416699999998,71.65416000000005],[-119.10582699999998,71.68580600000007],[-119.12471,71.73054500000006],[-119.13445300000001,71.76527399999992],[-119.13445300000001,71.78387499999997],[-119.10555999999991,71.87664800000005],[-119.10305800000003,71.883331],[-119.09194899999994,71.90220599999998],[-119.08750900000001,71.90832499999999],[-118.945831,71.99136400000009],[-118.929169,72.00054899999992],[-118.86694299999999,72.02387999999996],[-118.84249899999998,72.02970900000003],[-118.80166599999995,72.03720099999992],[-118.76471699999996,72.04637099999997],[-118.733612,72.05748000000006],[-118.72501399999987,72.0619200000001],[-118.71665999999999,72.066666],[-118.71028099999995,72.07193000000001],[-118.70556599999992,72.07777400000003],[-118.703056,72.08471700000001],[-118.70749699999999,72.09582499999999],[-118.715012,72.10026600000009],[-118.71972700000003,72.10525500000006],[-118.71945199999999,72.11137400000007],[-118.71749899999998,72.11692800000009],[-118.69193999999999,72.13053900000006],[-118.58860800000002,72.17608600000011],[-118.57640100000003,72.17915299999999],[-118.56194299999999,72.18136600000014],[-118.545547,72.18275499999999],[-118.44248999999996,72.18165599999998],[-118.40583799999996,72.18304400000005],[-118.38945000000001,72.18470800000011],[-118.15722699999992,72.21775800000012],[-118.12832599999996,72.22221400000006],[-118.11945299999996,72.22665400000005],[-118.11277799999993,72.23193400000014],[-118.108047,72.23776200000009],[-118.10527000000002,72.24470500000007],[-118.10417199999995,72.26332100000008],[-118.12138400000003,72.30802900000015],[-118.13082899999995,72.31805400000007],[-118.14527899999996,72.32693499999999],[-118.16471899999993,72.33442700000012],[-118.176941,72.33776900000004],[-118.19193999999999,72.34054600000013],[-118.20916699999998,72.34248400000007],[-118.25140399999998,72.34471100000013],[-118.27166699999992,72.34471100000013],[-118.28832999999992,72.34332300000005],[-118.32528699999995,72.34193400000004],[-118.36416600000001,72.3413700000001],[-118.40695199999993,72.34248400000007],[-118.446663,72.345261],[-118.49109599999997,72.35304300000013],[-118.52306399999992,72.36387600000012],[-118.55499299999997,72.38081400000004],[-118.56973299999999,72.38970900000004],[-118.58194700000001,72.39915500000001],[-118.58860800000002,72.41665599999999],[-118.58805799999999,72.43525699999998],[-118.58528100000001,72.44192499999997],[-118.573059,72.46081500000008],[-118.56833599999993,72.46665999999999],[-118.55027799999999,72.48332199999999],[-118.53694199999995,72.49386600000003],[-118.51972999999992,72.50277699999998],[-118.20722999999998,72.6185910000001],[-118.12554899999998,72.64248700000002],[-118.08306900000002,72.64971900000012],[-117.90361000000001,72.68969700000014],[-117.89083899999991,72.69274900000005],[-117.86888099999993,72.69999700000005],[-117.63305700000001,72.784988],[-117.60193600000002,72.79693600000007],[-117.51944700000001,72.82887300000004],[-117.48999000000003,72.84136999999998],[-117.48111,72.84582500000005],[-117.46472199999994,72.85554500000012],[-117.43611099999993,72.876373],[-117.42054699999994,72.89444000000009],[-117.402222,72.90332000000012],[-117.37999000000002,72.91053800000009],[-117.35360699999995,72.91638200000011],[-117.32333399999993,72.92082199999993],[-117.30638099999993,72.92192100000011],[-117.24916099999996,72.92387400000007],[-117.12721299999998,72.93248],[-116.95639,72.95416300000011],[-116.94138299999997,72.95637499999998],[-116.89972699999998,72.96415700000011],[-116.862503,72.97221400000006],[-116.83805799999999,72.97859200000005],[-116.775284,72.9952550000001],[-116.70722999999998,73.01721199999997],[-116.65972899999991,73.03109700000005],[-116.58750900000001,73.051376],[-116.57417299999997,73.0541530000001],[-116.54167199999995,73.05748000000006],[-116.52416999999991,73.05886800000013],[-116.31916799999993,73.09165999999999],[-116.24221799999998,73.1102600000001],[-116.20195000000001,73.11859099999998],[-116.15556300000003,73.12469500000003],[-115.90055799999993,73.1541600000001],[-115.60973399999995,73.19413800000012],[-115.44082600000002,73.22387700000013],[-115.34638999999999,73.25332600000013],[-115.32305899999994,73.26026900000011],[-115.30915799999997,73.26304600000003],[-115.14917000000003,73.28831500000001],[-115.10221899999999,73.29414400000002],[-115.01418299999989,73.29998800000004],[-114.95111099999997,73.30775499999999],[-114.89417299999997,73.31805400000002],[-114.86638599999998,73.32360800000004],[-114.83056599999998,73.33415200000007],[-114.81054699999999,73.342758],[-114.70722999999992,73.368042],[-114.67555199999998,73.37191800000005],[-114.65778399999999,73.37303200000002],[-114.56166100000002,73.37553400000013],[-114.54083300000002,73.37359599999996],[-114.50527999999991,73.36886600000014],[-114.337784,73.34332300000005],[-114.30499299999991,73.33804299999997],[-114.27500899999995,73.33221400000014],[-114.22609699999987,73.31832900000006],[-114.197769,73.30636600000003],[-114.16306299999997,73.28970300000015],[-114.11054999999999,73.26388500000002],[-114.05610699999994,73.23359700000003],[-114.01666299999994,73.2063750000001],[-113.96167000000003,73.15304600000013],[-113.95694700000001,73.14248700000007],[-113.95388799999989,73.12553399999996],[-113.95749699999999,73.11331200000001],[-113.99582700000002,73.07777399999998],[-114.00499699999995,73.06442300000003],[-114.035553,73.00499000000002],[-114.04750100000001,72.95498700000007],[-114.05499299999997,72.88360599999999],[-114.05277999999998,72.872208],[-114.04915599999998,72.86720300000013],[-114.0427699999999,72.86276200000003],[-114.027222,72.8541560000001],[-113.98166700000002,72.83415200000002],[-113.96888699999994,72.82499700000011],[-113.96777299999997,72.81944299999998],[-113.96945199999999,72.81303400000007],[-113.97582999999992,72.80720500000007],[-113.985817,72.80304000000007],[-113.99749799999995,72.7994230000001]],[[-95.66972399999992,73.60498000000013],[-95.6885989999999,73.603317],[-95.70249899999999,73.60554500000012],[-95.71167000000003,73.61219800000009],[-95.70388799999995,73.61747700000006],[-95.68415799999997,73.6202550000001],[-95.66999799999996,73.62052900000003],[-95.65556300000003,73.61665299999993],[-95.65499899999998,73.609985],[-95.66972399999992,73.60498000000013]],[[-107.89555399999989,73.5413670000001],[-107.93055699999996,73.53942899999998],[-107.9519499999999,73.54026800000008],[-107.97193900000002,73.542755],[-108.00917099999992,73.54803500000008],[-108.02306399999998,73.55137600000012],[-108.07472200000001,73.57638500000007],[-108.08277899999996,73.580826],[-108.08500700000002,73.58581500000014],[-108.083328,73.59721400000006],[-108.07640099999992,73.60359199999999],[-108.066101,73.60859700000003],[-108.05444299999988,73.61248799999993],[-108.04083299999996,73.61554000000007],[-108.00750700000003,73.6185910000001],[-107.89943699999992,73.62275699999998],[-107.86277799999993,73.624146],[-107.82444800000002,73.6244200000001],[-107.80444299999999,73.624146],[-107.68110699999994,73.62136799999996],[-107.61472299999991,73.61470000000003],[-107.60056299999997,73.61137400000013],[-107.58944699999995,73.6077580000001],[-107.58473200000003,73.60304300000007],[-107.58249699999999,73.59776299999999],[-107.58473200000003,73.58665500000001],[-107.59194899999994,73.57998700000002],[-107.60221899999988,73.57527199999998],[-107.64527900000002,73.57026700000011],[-107.65722700000003,73.568604],[-107.7491609999999,73.55581699999999],[-107.89555399999989,73.5413670000001]],[[-124.307503,73.55636600000014],[-124.33167999999995,73.55636600000014],[-124.343613,73.55998199999999],[-124.35193600000002,73.5711060000001],[-124.35861199999988,73.63026400000007],[-124.34612300000003,73.63360600000004],[-124.33138999999994,73.63638300000014],[-124.307503,73.63220200000006],[-124.30332900000002,73.62664800000005],[-124.29387700000001,73.62248199999993],[-124.28222700000003,73.61886600000008],[-124.26806599999992,73.61608899999999],[-124.21028100000001,73.61137400000013],[-124.19360399999994,73.60914600000001],[-124.17944299999994,73.60636900000009],[-124.16777000000002,73.60304300000007],[-124.14916999999997,73.59471100000007],[-124.12666300000001,73.580826],[-124.11972000000003,73.57582100000013],[-124.11554699999988,73.57054100000005],[-124.11389199999996,73.5641480000001],[-124.12638899999996,73.56080599999996],[-124.307503,73.55636600000014]],[[-124.58473199999992,73.67915300000004],[-124.59944199999995,73.676376],[-124.62361099999998,73.67665099999999],[-124.640556,73.67886399999998],[-124.70056199999993,73.68942299999998],[-124.72917199999995,73.694977],[-124.733612,73.70054599999997],[-124.72582999999992,73.70526100000001],[-124.71584299999995,73.70915200000007],[-124.70111099999997,73.711929],[-124.681671,73.71304299999997],[-124.66471899999999,73.71081500000003],[-124.66278099999994,73.70609999999999],[-124.64835399999998,73.70471200000009],[-124.61694299999999,73.69970700000005],[-124.57140399999992,73.69192500000008],[-124.564438,73.68719500000003],[-124.57224299999996,73.68248],[-124.58473199999992,73.67915300000004]],[[-105.089447,73.73526000000004],[-104.96028099999995,73.68858299999994],[-104.84306300000003,73.65081800000007],[-104.71140300000002,73.63081399999993],[-104.69167299999992,73.628311],[-104.675003,73.6249850000001],[-104.58084100000002,73.60026600000015],[-104.53056300000003,73.58137499999992],[-104.51306199999999,73.57304400000004],[-104.49445300000002,73.55941800000005],[-104.49027999999998,73.55470300000002],[-104.48528299999998,73.54470800000013],[-104.48306299999996,73.53442400000012],[-104.512787,73.49304200000006],[-104.55583200000001,73.40332000000001],[-104.56639100000001,73.33471700000013],[-104.56833599999999,73.32916300000011],[-104.57333399999999,73.3230440000001],[-104.58138999999994,73.31666600000011],[-104.60193599999997,73.30636600000003],[-104.64916999999997,73.28082300000011],[-104.69499200000001,73.25221300000004],[-104.76000999999991,73.20387300000004],[-104.76500699999985,73.19775400000003],[-104.76390099999998,73.19247400000012],[-104.79415899999998,73.168045],[-104.86805700000002,73.13665800000007],[-104.97556299999997,73.0852660000001],[-104.98332199999999,73.07887299999999],[-104.98805199999993,73.07304399999998],[-104.98388699999992,73.06805400000007],[-104.97749299999998,73.05304000000001],[-104.97361799999999,73.0316620000001],[-104.97860699999995,73.02554300000008],[-104.984734,73.02053800000004],[-104.99527,73.01582300000001],[-105.031677,73.00416600000005],[-105.0750119999999,72.99720800000006],[-105.08833300000003,72.99414100000013],[-105.13639799999993,72.97886700000004],[-105.14695699999999,72.974152],[-105.22582999999997,72.93304400000011],[-105.30304699999994,72.951096],[-105.31916799999999,72.95416300000011],[-105.339722,72.95555100000001],[-105.354446,72.95332300000007],[-105.35610999999994,72.94775400000003],[-105.33139,72.91053800000009],[-105.32417299999997,72.90609699999999],[-105.279449,72.88554399999992],[-105.25361599999997,72.87858599999998],[-105.237503,72.87553400000002],[-105.21140300000002,72.86859100000004],[-105.20417799999996,72.86415100000005],[-105.2622219999999,72.84860200000008],[-105.27555799999993,72.84553499999998],[-105.28999299999987,72.84776299999999],[-105.38305699999995,72.8666530000001],[-105.43611099999993,72.89665200000013],[-105.443329,72.90109300000006],[-105.45612299999999,72.91526799999997],[-105.458618,72.92553699999996],[-105.45694699999996,72.93136600000003],[-105.45834400000001,72.93637100000007],[-105.46250900000001,72.94136000000003],[-105.57472199999995,72.98442100000005],[-105.73277299999995,73.04775999999998],[-105.91388699999999,73.1455380000001],[-105.94638099999992,73.16026300000004],[-106.09249899999992,73.19970699999993],[-106.08194700000001,73.24108899999999],[-106.32195300000001,73.33888200000013],[-106.44776899999994,73.39305100000013],[-106.45556599999998,73.397491],[-106.46611000000001,73.40138200000007],[-106.72028399999999,73.44999700000011],[-106.88137799999998,73.46331800000007],[-106.89806399999992,73.46192900000005],[-106.91610699999995,73.46138000000008],[-106.9375,73.4624940000001],[-107,73.46971100000002],[-107.016953,73.4727630000001],[-107.02749599999999,73.47637900000001],[-107.03555299999994,73.48082000000011],[-107.034157,73.48637400000007],[-107.02583300000003,73.49859600000008],[-107.01834100000002,73.50499000000008],[-107.00974299999996,73.5105440000001],[-106.97112299999992,73.53166199999998],[-106.92944299999999,73.55053700000013],[-106.89334100000002,73.56248499999998],[-106.74526999999995,73.64804100000015],[-106.70028699999995,73.67608599999994],[-106.65805099999994,73.6952510000001],[-106.64584399999995,73.699142],[-106.61833200000001,73.70526100000001],[-106.57224300000001,73.711929],[-106.32721700000002,73.72665400000011],[-106.18554699999999,73.73359700000015],[-106.03916900000002,73.73136899999997],[-105.80055199999998,73.72692899999998],[-105.72666900000002,73.72859200000005],[-105.68028300000003,73.73498500000005],[-105.66639699999996,73.73776199999992],[-105.637787,73.74443100000002],[-105.61277799999993,73.75221299999998],[-105.58473200000003,73.75804100000005],[-105.569458,73.76026900000005],[-105.53527799999995,73.76277199999998],[-105.51666299999994,73.76332100000013],[-105.30387899999994,73.76220699999999],[-105.28388999999999,73.76165800000001],[-105.16999800000002,73.75555400000002],[-105.14862099999999,73.75416600000005],[-105.10749799999991,73.74359099999998],[-105.089447,73.73526000000004]],[[-80.14222699999988,73.69664000000012],[-80.108612,73.69386300000002],[-80.07444800000002,73.69747900000004],[-79.90139799999997,73.69831800000003],[-79.62554899999998,73.67082199999999],[-79.58612099999999,73.66276600000009],[-79.523056,73.64665200000013],[-79.49305699999996,73.6377720000001],[-79.47639499999991,73.63415499999996],[-79.45194999999995,73.63053900000011],[-79.37361099999998,73.63081399999993],[-78.96166999999997,73.63275099999998],[-78.94610599999999,73.63472000000002],[-78.93443300000001,73.63859600000006],[-78.931107,73.64248700000013],[-78.92887899999994,73.64749100000012],[-78.92416400000002,73.6502690000001],[-78.9125059999999,73.65386999999998],[-78.887787,73.65664700000008],[-78.86138900000003,73.65832499999999],[-78.64416499999993,73.65664700000008],[-78.40834000000001,73.66165200000012],[-78.20666499999999,73.66775500000006],[-78.16639700000002,73.66804500000006],[-78.12777699999998,73.66470300000015],[-78.11332700000003,73.66304000000002],[-78.064438,73.65193200000004],[-78.00973499999998,73.63749700000011],[-77.96528599999994,73.628311],[-77.82305899999994,73.60386700000004],[-77.73860199999996,73.59193399999998],[-77.608047,73.57415800000001],[-77.53500400000001,73.56553600000001],[-77.45388799999995,73.55970800000006],[-77.42443799999995,73.55470300000002],[-77.395554,73.5458220000001],[-77.37304699999993,73.52970900000008],[-77.36332700000003,73.52470399999999],[-77.35139499999997,73.51998899999995],[-77.33833300000003,73.51666300000011],[-77.29472399999997,73.51277200000004],[-77.237213,73.50999499999995],[-77.20306399999993,73.50555400000002],[-77.19193999999999,73.50138900000002],[-77.14862099999999,73.47637900000001],[-77.15361000000001,73.46804800000007],[-77.15722699999998,73.45860300000004],[-77.05526699999996,73.36637900000005],[-77.04888899999992,73.36192299999999],[-76.999435,73.3458250000001],[-76.96972699999998,73.33720399999999],[-76.91361999999998,73.324432],[-76.89334099999996,73.32110599999999],[-76.88417099999992,73.32165500000008],[-76.87887599999993,73.32415800000007],[-76.858612,73.32638500000013],[-76.837219,73.3272090000001],[-76.73638900000003,73.32470699999999],[-76.72193900000002,73.32249500000012],[-76.708054,73.31776400000001],[-76.57972699999999,73.21971100000007],[-76.57749899999993,73.20555100000013],[-76.58500699999996,73.19442700000008],[-76.601944,73.1833190000001],[-76.61972000000003,73.17581200000012],[-76.60527000000002,73.15914900000007],[-76.58694500000001,73.14637800000014],[-76.58222999999998,73.14387499999998],[-76.510559,73.12025499999999],[-76.49554399999994,73.11692800000009],[-76.48750299999995,73.1160890000001],[-76.38194299999998,73.10609399999998],[-76.31361400000003,73.10054000000002],[-76.31249999999994,73.06749000000013],[-76.31806899999992,73.06275900000003],[-76.31945799999994,73.05831899999998],[-76.33306899999991,72.96360799999997],[-76.323059,72.95721400000014],[-76.30943300000001,72.95248400000008],[-76.29167199999995,72.94886800000006],[-76.275284,72.94664000000006],[-76.21194500000001,72.94552600000009],[-76.162216,72.94636500000007],[-76.118607,72.94026200000013],[-76.10360700000001,72.93637100000007],[-76.07722499999994,72.92498800000004],[-76.07167099999992,72.92109700000015],[-76.06221,72.90693700000003],[-76.0594329999999,72.90081800000002],[-76.08639499999998,72.86360200000007],[-76.09388699999994,72.85803199999998],[-76.10388199999994,72.85304300000001],[-76.11527999999993,72.84942600000005],[-76.13110399999988,72.84553499999998],[-76.14999399999999,72.84220900000014],[-76.25140399999998,72.82638500000002],[-76.31555200000003,72.81721499999998],[-76.339722,72.81498700000003],[-76.5625,72.81248499999998],[-76.58167999999995,72.81248499999998],[-76.601944,72.81387300000006],[-76.61860699999988,72.81693999999999],[-76.63417099999998,72.82054100000005],[-76.662781,72.82916300000005],[-76.68138099999993,72.8313750000001],[-76.72193900000002,72.83387800000008],[-76.74082900000002,72.83387800000008],[-76.76750199999992,72.83387800000008],[-76.89195299999994,72.83082599999994],[-76.93721,72.83082599999994],[-77.08475499999997,72.83968400000015],[-77.10166899999996,72.84027100000003],[-77.14388999999994,72.84193399999998],[-77.22694399999995,72.84610000000004],[-77.26583899999991,72.84942600000005],[-77.31443799999994,72.85554500000012],[-77.36582900000002,72.86442600000004],[-77.40055799999999,72.87081899999998],[-77.41610699999995,72.87469500000009],[-77.44721999999996,72.87997400000006],[-77.52278099999995,72.88610800000009],[-77.70417800000001,72.89721699999996],[-77.72332799999998,72.89694199999997],[-77.86000099999995,72.89305100000007],[-77.90417500000001,72.891663],[-77.99777199999994,72.88832100000002],[-78.10722399999992,72.88638300000008],[-78.236359,72.89300500000002],[-78.273056,72.89054900000002],[-78.29722600000002,72.8877720000001],[-78.48611499999998,72.86554000000001],[-78.62388599999997,72.84803799999997],[-78.86582899999996,72.80442799999997],[-79.047775,72.77137800000014],[-79.1619419999999,72.75054899999998],[-79.20916699999992,72.74498],[-79.296112,72.73776199999998],[-79.35916099999997,72.73359700000015],[-79.38249200000001,72.73304700000011],[-79.400284,72.73359700000015],[-79.42916899999994,72.73580900000002],[-79.54333499999996,72.74859600000002],[-79.62388599999997,72.76332100000013],[-79.92777999999993,72.84248400000001],[-79.972778,72.85470599999996],[-79.99861099999998,72.86303700000002],[-80.00917099999992,72.87275699999992],[-80.12083399999995,72.97886700000004],[-80.15167200000002,73.01193200000012],[-80.18138099999993,73.04386900000009],[-80.181107,73.05026200000003],[-80.16416900000002,73.06192000000004],[-80.14723200000003,73.07138100000003],[-80.13473499999992,73.08471699999996],[-80.13166799999999,73.08859300000006],[-80.12887599999999,73.09526100000005],[-80.122772,73.11442599999998],[-80.11000099999995,73.17970300000002],[-80.114441,73.18637100000001],[-80.13444500000003,73.20915200000002],[-80.14306599999992,73.21693399999998],[-80.15194699999995,73.22248799999994],[-80.21694899999994,73.2433170000001],[-80.23805199999998,73.24414100000007],[-80.41528299999993,73.24414100000007],[-80.61999499999996,73.26416],[-80.76000999999991,73.27470400000004],[-80.79750099999995,73.27693200000004],[-80.87609899999995,73.32777399999992],[-80.87609899999995,73.338593],[-80.87249800000001,73.4249880000001],[-80.82028199999996,73.48915099999999],[-80.80999799999995,73.64444000000009],[-80.85777299999995,73.74192800000003],[-80.77166699999992,73.74971],[-80.68331899999998,73.755829],[-80.56054699999987,73.76776099999995],[-80.43499800000001,73.76609800000006],[-80.37332200000003,73.76165800000001],[-80.35305800000003,73.75972000000007],[-80.32084700000001,73.75387600000005],[-80.30860899999999,73.75],[-80.29861499999987,73.7458190000001],[-80.265289,73.73027000000002],[-80.22332799999992,73.71582000000006],[-80.19276399999995,73.70721400000014],[-80.15834000000001,73.69941700000004],[-80.14222699999988,73.69664000000012]],[[-73.35467499999993,68.32921599999997],[-73.328171,68.32820899999996],[-73.31617,68.32871200000005],[-73.30683099999999,68.33054400000009],[-73.21167000000003,68.37692300000003],[-73.23055999999991,68.38415500000013],[-73.25306699999999,68.39082300000013],[-73.27944899999989,68.39498900000001],[-73.30277999999993,68.39610299999998],[-73.31806899999998,68.39305100000007],[-73.35749800000002,68.37136800000013],[-73.35972599999997,68.36498999999998],[-73.35777300000001,68.35748300000006],[-73.35305799999998,68.35247800000002],[-73.34916699999991,68.34498600000006],[-73.34722899999997,68.3374940000001],[-73.34944200000001,68.3311000000001],[-73.35467499999993,68.32921599999997],[-73.50666799999999,68.29136700000004],[-73.589722,68.25471500000003],[-73.59777799999995,68.251938],[-73.620834,68.24609399999997],[-73.63221699999991,68.24664300000006],[-73.63972499999994,68.24971],[-73.85166899999996,68.34220900000014],[-73.85583499999996,68.34664900000001],[-73.89611799999994,68.39221199999992],[-73.88944999999995,68.44470200000012],[-73.87748699999992,68.48109399999993],[-73.87361099999993,68.48776200000009],[-73.86721799999998,68.493042],[-73.85611,68.49748199999999],[-73.823624,68.50332600000002],[-73.80665599999998,68.50387600000005],[-73.74999999999994,68.51081799999997],[-73.73889199999996,68.51499900000005],[-73.73028599999998,68.51998900000007],[-73.72582999999997,68.52581800000007],[-73.70472699999993,68.65664700000002],[-73.75389100000001,68.68359400000008],[-73.76139799999999,68.68637100000001],[-73.774719,68.68969700000002],[-73.8658289999999,68.705826],[-73.89389,68.70776400000011],[-74.09416199999998,68.71998600000006],[-74.10610999999994,68.69053600000001],[-73.99221799999998,68.62469500000003],[-73.88806199999988,68.56164599999994],[-73.88166799999999,68.55664100000007],[-73.88166799999999,68.54971300000011],[-73.90360999999996,68.52777100000003],[-73.92138699999992,68.51193200000012],[-73.94193999999999,68.50471500000003],[-73.99027999999993,68.492752],[-74.02833599999991,68.51361099999997],[-74.17166099999997,68.52165200000002],[-74.221115,68.52526899999998],[-74.35139500000002,68.53692600000011],[-74.366104,68.53915400000005],[-74.37943999999993,68.54220599999996],[-74.39111299999996,68.54637100000014],[-74.51417500000002,68.59999100000005],[-74.52639799999997,68.61080900000002],[-74.53277600000001,68.62164300000012],[-74.53167699999995,68.62637300000011],[-74.59889199999992,68.68193099999996],[-74.70195000000001,68.71887200000009],[-74.71221899999995,68.72303800000003],[-74.72610500000002,68.73027000000013],[-74.72833300000002,68.73719800000009],[-74.72471599999994,68.76609799999994],[-74.71945199999999,68.77053799999999],[-74.66416899999996,68.77415500000012],[-74.62083399999989,68.782486],[-74.591949,68.78887900000001],[-74.57694999999995,68.79304500000006],[-74.56527699999992,68.80219999999991],[-74.54638699999998,68.82249499999995],[-74.54804999999999,68.82859800000011],[-74.55139200000002,68.83055100000001],[-74.604172,68.8416600000001],[-74.63417099999992,68.84637499999997],[-74.648056,68.84721400000012],[-74.66665599999993,68.8458250000001],[-74.67832899999996,68.842758],[-74.68737799999997,68.83599100000004],[-74.71871899999996,68.82482100000004],[-74.72305299999994,68.822319],[-74.72122199999995,68.82115200000004],[-74.71421799999996,68.82098400000001],[-74.70522299999993,68.82165500000008],[-74.68943799999994,68.81971699999997],[-74.67166099999997,68.81887799999998],[-74.66027799999989,68.81581100000011],[-74.639725,68.80748],[-74.63333099999994,68.79693600000013],[-74.63500999999997,68.79332000000011],[-74.648056,68.78942900000004],[-74.66583299999996,68.78665200000012],[-74.77166699999998,68.77415500000012],[-74.91776999999996,68.80137599999995],[-74.91389499999997,68.81721500000009],[-74.83750899999995,68.84082000000006],[-74.787781,68.85443100000003],[-74.76416799999998,68.87204000000003],[-74.74017299999997,68.87271099999998],[-74.72222899999997,68.934143],[-74.86294599999991,68.95417800000001],[-74.87277999999998,68.95500199999998],[-74.88761099999999,68.95417800000001],[-74.89810899999998,68.95251500000006],[-74.92011300000001,68.94667100000004],[-74.935944,68.942001],[-75,68.93760700000007],[-75.00500499999993,68.92997700000006],[-75.03361499999988,68.926086],[-75.04277000000002,68.928314],[-75.04194599999988,68.93026700000013],[-75.021118,68.95304900000002],[-74.96234099999998,68.972824],[-74.95300299999997,68.97848499999998],[-74.91533700000002,68.99282100000005],[-74.90766899999988,68.993988],[-74.764725,69.01944000000003],[-74.74833699999999,69.02137800000014],[-74.73500099999995,69.02192700000012],[-74.729446,69.01944000000003],[-74.75805700000001,69.00888099999997],[-74.752228,69.00248699999997],[-74.675003,69.00694300000004],[-74.65834000000001,69.00833099999994],[-74.64277600000003,69.01165800000007],[-74.63806199999999,69.01609800000011],[-74.64111300000002,69.02137800000014],[-74.65249599999993,69.04026799999991],[-74.78582799999998,69.07638500000007],[-74.82084699999996,69.08221400000008],[-74.83416699999992,69.08166499999999],[-74.84583999999995,69.07859800000006],[-74.94860799999992,69.04887400000001],[-75.04333499999996,69.01332100000002],[-75.05194099999989,69.00860599999999],[-75.03611799999993,68.99220300000007],[-75.03778099999988,68.98580900000007],[-75.07139599999994,68.92109700000003],[-75.07556199999993,68.915817],[-75.10916099999986,68.89498900000012],[-75.11639400000001,68.89082300000001],[-75.12416100000002,68.88804600000009],[-75.139725,68.88472000000007],[-75.16999800000002,68.88638300000002],[-75.19249000000002,68.89166300000005],[-75.20195000000001,68.89444000000015],[-75.31582600000002,68.94220000000013],[-75.37388599999991,68.96887200000003],[-75.383331,68.97442600000005],[-75.400284,68.98553500000014],[-75.42250099999995,69.001938],[-75.44583099999994,69.01693700000004],[-75.45445299999994,69.02110299999998],[-75.46639999999996,69.02137800000014],[-75.478882,69.01971400000014],[-75.49415599999998,69.01638800000012],[-75.52833599999997,69.00582900000006],[-75.56555200000003,68.99359100000004],[-75.573624,68.98858599999994],[-75.57861299999996,68.98414600000012],[-75.58084100000002,68.97554000000002],[-75.57417299999992,68.96832300000011],[-75.53778099999994,68.95109600000006],[-75.50695799999994,68.93969699999997],[-75.49972499999996,68.934708],[-75.49499500000002,68.93026700000013],[-75.53416399999998,68.90387000000004],[-75.54277000000002,68.89887999999996],[-75.56527699999998,68.89137300000004],[-75.60388199999994,68.87970000000001],[-75.64778099999995,68.86914099999996],[-75.80915800000002,68.836929],[-75.97610499999996,68.7910920000001],[-75.979446,68.78720100000004],[-75.98500100000001,68.78387500000002],[-75.99554399999994,68.7794340000001],[-76.00862099999995,68.77554300000003],[-76.04943799999995,68.76443500000005],[-76.22721899999999,68.72110000000004],[-76.327225,68.69747899999999],[-76.37609899999995,68.68748499999998],[-76.420547,68.67915299999999],[-76.43638599999986,68.67720000000003],[-76.45666499999999,68.67526200000009],[-76.54028299999999,68.67330899999996],[-76.55943299999996,68.67303500000003],[-76.57556199999999,68.67414900000006],[-76.59056099999998,68.67637600000006],[-76.62887599999999,68.68691999999993],[-76.66082799999998,68.69941699999993],[-76.67416400000002,68.71026599999999],[-76.68028300000003,68.716095],[-76.68859900000001,68.73359700000003],[-76.689438,68.74054000000007],[-76.68804899999998,68.74693300000001],[-76.678604,68.758331],[-76.666946,68.76915000000008],[-76.63694799999996,68.78166200000004],[-76.60861199999994,68.79414400000007],[-76.57749899999993,68.80831899999998],[-76.56138599999991,68.81805400000002],[-76.546112,68.833054],[-76.537216,68.84220900000008],[-76.523056,68.86387600000012],[-76.52166699999998,68.87025499999999],[-76.52389499999992,68.87637300000006],[-76.53277599999996,68.880539],[-76.54415899999998,68.88304100000005],[-76.55943299999996,68.88499500000006],[-76.57667499999997,68.88499500000006],[-76.59333799999996,68.88333100000006],[-76.60665899999992,68.88304100000005],[-76.61000099999995,68.88472000000007],[-76.64416499999999,68.91110200000014],[-76.65556299999997,68.92469800000009],[-76.65556299999997,68.93054200000012],[-76.64277599999997,69.0038760000001],[-76.64056399999993,69.00915500000008],[-76.62554899999998,69.01832600000006],[-76.60360700000001,69.02581800000002],[-76.57833899999991,69.03221100000013],[-76.54333500000001,69.03831500000001],[-76.50140399999992,69.042755],[-76.42250099999995,69.05053700000013],[-76.368607,69.055252],[-76.34889199999992,69.05497699999995],[-76.33277899999996,69.05442800000003],[-76.24027999999993,69.04832500000009],[-76.208054,69.04414400000002],[-76.14056399999993,69.03471400000012],[-76.124435,69.03109699999999],[-76.11416599999995,69.02777100000014],[-76.09167499999995,69.01165800000007],[-76.08000199999992,69.00637800000004],[-76.06861900000001,69.0038760000001],[-75.99693299999996,69.00303600000007],[-75.96916199999998,69.01026900000011],[-75.90499899999992,69.036926],[-75.81388900000002,69.06776399999995],[-75.65583800000002,69.08055099999996],[-75.63778699999995,69.07998700000002],[-75.61915599999992,69.08137499999992],[-75.6058349999999,69.08526599999999],[-75.59889199999998,69.0894320000001],[-75.59388699999994,69.09971600000011],[-75.56973299999993,69.15277100000003],[-75.569458,69.15832499999999],[-75.571121,69.16387900000001],[-75.59167499999995,69.22164900000007],[-75.60305799999998,69.23887600000012],[-75.61971999999997,69.24941999999999],[-75.66972399999992,69.2711030000001],[-75.75973499999998,69.30497700000012],[-75.78332499999999,69.31359900000012],[-75.95638999999989,69.36608899999993],[-75.97027599999996,69.36914100000007],[-76.16861,69.41137700000007],[-76.20249899999993,69.41387900000012],[-76.24194299999994,69.41331500000001],[-76.29804999999999,69.407761],[-76.41777000000002,69.44720500000011],[-76.60749799999996,69.52970900000014],[-76.637787,69.54664599999995],[-76.64111299999996,69.5541530000001],[-76.64167800000001,69.55748000000006],[-76.62666299999995,69.58137500000004],[-76.61999499999996,69.58638000000008],[-76.61166399999996,69.59109500000011],[-76.4891659999999,69.64833100000004],[-76.47778299999999,69.65220600000004],[-76.45916699999998,69.65443400000004],[-76.44221500000003,69.65304600000007],[-76.34777799999995,69.64027400000009],[-76.26139799999999,69.62664799999993],[-76.22694399999995,69.63720699999999],[-76.18611099999998,69.65971400000006],[-76.18249500000002,69.66360500000013],[-76.18777499999999,69.66526800000008],[-76.22610500000002,69.66470300000003],[-76.29554699999994,69.66026300000004],[-76.37638899999996,69.67137100000002],[-76.38833599999992,69.67387400000001],[-76.39750699999996,69.67804000000007],[-76.39973399999985,69.684143],[-76.45056199999993,69.69026200000008],[-76.53778099999994,69.69609100000008],[-76.55166600000001,69.69552600000003],[-76.63417099999998,69.68359400000008],[-76.641953,69.67997700000012],[-76.63890099999998,69.67330900000013],[-76.63194299999992,69.66970800000007],[-76.61639400000001,69.66748000000013],[-76.58167999999995,69.66693099999998],[-76.55776999999995,69.67330900000013],[-76.5427699999999,69.67469800000015],[-76.53083800000002,69.67221100000006],[-76.51777600000003,69.66276599999998],[-76.52278099999995,69.65248100000008],[-76.53500400000001,69.638596],[-76.55332900000002,69.62525900000014],[-76.56166100000002,69.62025499999999],[-76.68388399999998,69.56581100000011],[-76.69193999999999,69.56303400000002],[-76.70750399999997,69.559418],[-76.73028599999998,69.56025699999992],[-76.84472699999992,69.57609600000006],[-77.13694799999996,69.62637300000011],[-77.18582200000003,69.637497],[-77.19166599999994,69.63970900000004],[-77.20056199999999,69.6461030000001],[-77.20056199999999,69.64888000000002],[-77.19444299999992,69.65721100000007],[-77.164444,69.67608600000005],[-77.15556299999997,69.68054199999995],[-77.144455,69.68220500000007],[-76.94943199999994,69.69552600000003],[-76.93943799999994,69.67970300000002],[-76.92999299999997,69.67776500000008],[-76.89666699999998,69.67915299999999],[-76.86805699999996,69.68470800000006],[-76.82972699999993,69.69581600000004],[-76.82028199999996,69.6994170000001],[-76.80471799999998,69.70860300000004],[-76.79388399999999,69.71859700000005],[-76.791946,69.72164900000001],[-76.781387,69.74304200000012],[-76.781387,69.74859600000008],[-76.83528099999995,69.81581100000005],[-76.851944,69.81359900000001],[-76.9330599999999,69.80970800000011],[-77.02667200000002,69.81191999999999],[-77.150284,69.8160860000001],[-77.29305999999985,69.8288730000001],[-77.30888400000003,69.830826],[-77.31054699999999,69.83581499999997],[-77.30777,69.84027100000009],[-77.29777499999989,69.85108900000006],[-77.28472899999997,69.86053500000003],[-77.25418099999996,69.87692300000009],[-77.24305699999996,69.88136299999991],[-77.20834400000001,69.88665800000001],[-77.11665299999993,69.90138200000001],[-76.99276700000001,69.92719999999997],[-76.98167399999994,69.93165600000009],[-76.97471599999994,69.93580600000007],[-76.98055999999997,69.93803400000002],[-76.99276700000001,69.94053600000012],[-77.00279199999994,69.94053600000012],[-77.12527499999993,69.92581200000006],[-77.14111299999996,69.92248500000011],[-77.164444,69.91526800000003],[-77.18832399999991,69.90609700000005],[-77.22694399999995,69.89498900000007],[-77.26028400000001,69.88749699999994],[-77.43804899999992,69.85720800000007],[-77.50834700000001,69.82666000000012],[-77.45556599999998,69.79832500000009],[-77.44444299999998,69.78942899999998],[-77.44915800000001,69.78471400000012],[-77.55139199999996,69.74775699999992],[-77.55915800000002,69.74498000000006],[-77.57472200000001,69.74136399999998],[-77.59777799999995,69.73915100000005],[-77.60861199999994,69.74026500000002],[-77.61582900000002,69.7416530000001],[-77.6263889999999,69.74498000000006],[-77.637787,69.75387599999999],[-77.64527900000002,69.76081800000009],[-77.64999399999999,69.76971400000002],[-77.66805999999997,69.83665500000006],[-77.69193999999993,69.96304300000003],[-77.695267,69.98803700000002],[-77.69444299999992,70.00027500000004],[-77.69305400000002,70.00610400000005],[-77.68582200000003,70.02304100000009],[-77.678604,70.034988],[-77.67250099999995,70.0455320000001],[-77.66972399999997,70.05220000000003],[-77.66722099999998,70.06219499999997],[-77.66500899999994,70.08804300000008],[-77.66555799999998,70.10693400000014],[-77.66833499999996,70.11303700000008],[-77.67388899999997,70.11970500000001],[-77.67193600000002,70.17719999999991],[-77.67250099999995,70.18054200000006],[-77.67832899999996,70.18775900000014],[-77.685272,70.19136000000003],[-77.81082199999997,70.24552900000009],[-77.88417099999998,70.2586060000001],[-77.89222699999988,70.25804100000005],[-78.133621,70.21527100000009],[-78.23916600000001,70.2038730000001],[-78.34500099999991,70.19720500000011],[-78.35139500000002,70.19747900000004],[-78.36471599999999,70.201096],[-78.40167200000002,70.21249399999999],[-78.40527299999997,70.21415700000011],[-78.48083500000001,70.288589],[-78.406113,70.32693500000005],[-78.396118,70.32804900000002],[-78.38917500000002,70.33221400000002],[-78.39889499999992,70.33638000000008],[-78.42582700000003,70.3477630000001],[-78.43666100000002,70.35108899999994],[-78.48638900000003,70.35693400000008],[-78.5041809999999,70.35803199999998],[-78.521118,70.35775800000005],[-78.53639199999998,70.35636900000003],[-78.55749499999996,70.35137900000001],[-78.573624,70.34553499999998],[-78.57972699999988,70.34304800000007],[-78.583328,70.33692900000005],[-78.58111599999995,70.33415200000013],[-78.56916799999999,70.32554600000003],[-78.56471299999998,70.32026700000006],[-78.56138599999997,70.31414800000005],[-78.56471299999998,70.31025699999998],[-78.578888,70.309708],[-78.65527299999991,70.34693900000013],[-78.66250600000001,70.35054000000002],[-78.70472699999993,70.37469500000003],[-78.74749799999995,70.43887300000006],[-78.858337,70.45387300000004],[-78.90333599999991,70.44941699999993],[-78.94444299999986,70.45027199999998],[-79.03195199999993,70.45498700000002],[-79.07055700000001,70.46971100000007],[-79.09555099999989,70.49304200000012],[-79.100281,70.49832200000003],[-79.08168,70.52998400000013],[-79.06806899999992,70.53637700000007],[-78.89361600000001,70.59054600000013],[-78.87998999999996,70.59471100000013],[-78.86027499999989,70.59664900000007],[-78.83277900000002,70.59443700000003],[-78.82194500000003,70.58970600000009],[-78.81555199999991,70.57748400000014],[-78.81610099999995,70.57331800000003],[-78.81500199999988,70.57193000000012],[-78.80665599999998,70.56498699999997],[-78.78805499999993,70.55609100000004],[-78.7661129999999,70.55026199999998],[-78.73332199999999,70.547211],[-78.71888699999994,70.5477600000001],[-78.72027600000001,70.54914900000011],[-78.84056099999998,70.63499500000012],[-78.851944,70.63804600000009],[-78.86193800000001,70.63720699999999],[-78.86833199999995,70.63220200000012],[-78.86749299999997,70.62858600000004],[-78.86805700000002,70.62441999999999],[-78.87193300000001,70.62191800000005],[-78.87998999999996,70.62109399999991],[-78.91221599999994,70.62136800000002],[-78.96528599999994,70.63275100000004],[-78.97694399999995,70.63581799999997],[-78.99415599999998,70.643326],[-78.99916100000002,70.65138200000007],[-79.00083899999993,70.66276600000015],[-78.99472000000003,70.672485],[-79.000565,70.6769260000001],[-79.00944500000003,70.67970299999996],[-79.025284,70.68026700000013],[-79.04110700000001,70.67858899999999],[-79.05722000000003,70.67275999999998],[-79.152222,70.62776200000008],[-79.158051,70.62220800000011],[-79.15583800000002,70.61747699999995],[-79.14973399999991,70.61303700000013],[-79.13694800000002,70.61080900000002],[-79.097778,70.61026000000004],[-79.06806899999992,70.61554000000012],[-79.14389,70.45387300000004],[-79.15972899999991,70.43803400000013],[-79.17416400000002,70.42804000000012],[-79.18472300000002,70.42359900000002],[-79.20973199999997,70.418045],[-79.22389199999998,70.41943400000002],[-79.23582499999992,70.42330900000002],[-79.26889,70.43637100000001],[-79.29110699999995,70.44693000000007],[-79.29055799999992,70.45359800000006],[-79.291946,70.45971700000007],[-79.30221599999993,70.47360200000014],[-79.30833399999989,70.48027000000013],[-79.38806199999993,70.49275200000011],[-79.40361000000001,70.49331699999993],[-79.412781,70.49165299999993],[-79.42054699999994,70.48887600000006],[-79.57556199999993,70.42942800000003],[-79.58555599999994,70.42137100000002],[-79.59111000000001,70.41360500000002],[-79.59138499999995,70.40914900000007],[-79.58889799999997,70.399429],[-79.57583599999998,70.38998400000008],[-79.56361399999997,70.3855440000001],[-79.42361499999987,70.35582000000011],[-79.42054699999994,70.35971099999995],[-79.41610700000001,70.36360200000001],[-79.40666199999987,70.36747700000001],[-79.38694800000002,70.37164300000012],[-79.37165799999997,70.37109399999997],[-79.3577729999999,70.36970500000001],[-79.31723,70.3602600000001],[-79.295837,70.35304300000001],[-79.28666699999985,70.34971600000006],[-79.26611299999996,70.34109499999994],[-79.252792,70.333328],[-79.24305700000002,70.3247070000001],[-79.23332199999987,70.31860399999994],[-79.22471599999994,70.31608599999998],[-79.20944199999997,70.31330900000006],[-79.12582399999991,70.30470300000013],[-79.10888699999992,70.30497700000006],[-79.09973099999996,70.30859400000003],[-79.08667000000003,70.31776400000007],[-79.08833300000003,70.3247070000001],[-79.09056099999992,70.3294370000001],[-79.08583099999998,70.33859300000006],[-79.07084700000001,70.34082000000012],[-79.05665599999992,70.34136999999998],[-79.03889500000002,70.34054600000002],[-79.027222,70.33943200000004],[-78.98832699999997,70.33137500000004],[-78.96665999999993,70.32331800000009],[-78.93916299999995,70.31109600000013],[-78.92166099999992,70.30081200000006],[-78.79055800000003,70.20555100000001],[-78.777222,70.194977],[-78.76306199999999,70.18359399999997],[-78.75306699999987,70.16943400000008],[-78.74888599999997,70.16220100000004],[-78.73750299999995,70.11498999999998],[-78.68859900000001,70.05497700000012],[-78.68306000000001,70.04637100000002],[-78.68028299999997,70.04026800000008],[-78.66416899999996,70.00416600000011],[-78.66250600000001,69.98304700000011],[-78.66250600000001,69.97303799999992],[-78.665009,69.96138000000008],[-78.67639200000002,69.94525099999998],[-78.68777499999993,69.934418],[-78.7041779999999,69.92414899999994],[-78.791946,69.891098],[-78.84973100000002,69.88610799999998],[-79.06639100000001,69.878311],[-79.17860399999995,69.88388100000009],[-79.200287,69.88443000000001],[-79.37777699999998,69.88610799999998],[-79.40805099999994,69.88499500000006],[-79.474716,69.87858600000004],[-79.526947,69.87191800000005],[-79.54083299999996,69.86886600000014],[-79.553604,69.86470000000003],[-79.56388900000002,69.859985],[-79.57695000000001,69.85582],[-79.60499600000003,69.84999099999999],[-79.63612399999994,69.84803800000003],[-79.68249500000002,69.84887700000002],[-79.69499200000001,69.85108900000006],[-79.70722999999998,69.855545],[-79.77362099999999,69.88554400000004],[-79.78028899999998,69.89054900000008],[-79.78639199999998,69.89721700000001],[-79.79638699999992,69.90832500000005],[-79.80110199999996,69.91554300000001],[-79.80027799999999,69.91720599999996],[-79.80332900000002,69.92747500000002],[-79.83361799999994,69.94941700000004],[-79.89138799999995,69.97387700000007],[-80.05305499999992,69.99720800000011],[-80.16805999999997,70.00637799999998],[-80.19694500000003,70.0080410000001],[-80.23249799999996,70.007767],[-80.26306199999993,70.00248700000009],[-80.27305599999994,69.99971],[-80.29249600000003,69.98692299999999],[-80.30777,69.98109399999998],[-80.31361400000003,69.98027000000002],[-80.32611099999991,69.98027000000002],[-80.33612099999999,69.98220799999996],[-80.43499800000001,70.00499000000008],[-80.45777899999996,70.01332099999996],[-80.46639999999996,70.01805100000001],[-80.47444200000001,70.024429],[-80.48554999999993,70.02943400000004],[-80.54777499999994,70.04414399999996],[-80.56111099999998,70.04693600000007],[-80.57749899999988,70.04887400000001],[-80.597778,70.04803500000003],[-80.65222199999994,70.03887900000007],[-80.66999800000002,70.03997800000008],[-80.78750599999995,70.05053700000013],[-80.906387,70.07083100000006],[-81.06220999999988,70.08554100000003],[-81.22582999999997,70.09693900000002],[-81.285553,70.09526100000011],[-81.37805199999997,70.09248400000001],[-81.42999299999997,70.0935970000001],[-81.46250899999995,70.09637500000008],[-81.60305800000003,70.113876],[-81.69860799999992,70.12858599999998],[-81.71167000000003,70.13053900000011],[-81.72833300000002,70.132202],[-81.745834,70.1308140000001],[-81.75611900000001,70.12831099999994],[-81.76333599999992,70.12303199999997],[-81.76194800000002,70.11747700000006],[-81.737503,70.0935970000001],[-81.71888699999988,70.07916300000005],[-81.70973200000003,70.07443200000012],[-81.68777499999987,70.06776400000012],[-81.67054699999994,70.06526200000008],[-81.62582399999997,70.06275900000009],[-81.55833399999989,70.05693099999996],[-81.53971899999993,70.053314],[-81.531113,70.05081200000012],[-81.464722,70.02470399999999],[-81.31361399999997,70.03221100000013],[-81.26222199999995,70.01638800000006],[-81.18859900000001,69.9910890000001],[-81.16972399999997,69.982483],[-81.15333599999991,69.969986],[-81.15306099999998,69.96360800000002],[-81.1541749999999,69.958328],[-81.150284,69.94581599999998],[-81.14277599999997,69.93803400000002],[-81.136124,69.933044],[-81.12638900000002,69.92776500000002],[-81.089722,69.91387900000001],[-81.02833599999997,69.8936000000001],[-80.99999999999994,69.88610799999998],[-80.93998699999997,69.86276200000009],[-80.79138199999994,69.79054299999996],[-80.76916499999987,69.77804599999996],[-80.76417500000002,69.77053799999999],[-80.76306199999999,69.76721200000009],[-80.76306199999999,69.76081800000009],[-80.77555799999999,69.75221300000004],[-80.82611099999991,69.73359700000003],[-80.83555599999988,69.73027000000008],[-80.84944199999995,69.72720300000015],[-80.93888900000002,69.71470599999998],[-80.95249899999999,69.71388200000001],[-80.95222499999994,69.73275800000005],[-80.95584100000002,69.734421],[-81.01444999999995,69.74552900000015],[-81.023056,69.74609400000003],[-81.03805499999993,69.74859600000008],[-81.07417299999992,69.75804099999999],[-81.09306300000003,69.76443499999999],[-81.10305800000003,69.76832600000006],[-81.11555499999986,69.77693199999999],[-81.12943999999993,69.7977600000001],[-81.1458439999999,69.81248500000004],[-81.166946,69.82138099999997],[-81.17887899999994,69.824997],[-81.21665999999999,69.8336030000001],[-81.354446,69.88026400000012],[-81.43305999999995,69.91304000000008],[-81.48055999999997,69.92692600000004],[-81.49194299999988,69.92970300000013],[-81.59889199999986,69.95248400000014],[-81.68249499999996,69.96443199999999],[-81.79527300000001,69.98858600000011],[-81.94554099999988,70.03997800000008],[-81.95388799999995,70.04386899999997],[-81.95722999999998,70.04721100000006],[-81.958618,70.05276500000008],[-81.96665999999993,70.06053200000002],[-82.06500199999994,70.09582500000005],[-82.1011049999999,70.10803200000004],[-82.214447,70.134995],[-82.36166399999996,70.16137700000007],[-82.44665500000002,70.17498800000004],[-82.47500600000001,70.17942800000009],[-82.61000100000001,70.20721400000014],[-82.7391659999999,70.23776200000009],[-82.91389499999997,70.28276100000011],[-82.93888899999996,70.29220599999996],[-82.952225,70.29637099999997],[-82.97778299999999,70.30192600000004],[-82.9927669999999,70.30358899999999],[-83.006958,70.30470300000013],[-83.04804999999999,70.30693100000013],[-82.89778100000001,70.24859599999996],[-82.82223499999998,70.2208250000001],[-82.68360899999993,70.18997200000013],[-82.573624,70.17164600000012],[-82.49388099999999,70.15887500000002],[-82.41528299999999,70.14305100000007],[-82.2997279999999,70.11886600000008],[-82.10305800000003,70.06526200000008],[-81.97639500000002,70.01220699999999],[-81.84167499999995,69.96331800000002],[-81.77333099999993,69.954163],[-81.75805699999995,69.95166],[-81.72500600000001,69.94413800000007],[-81.72000100000002,69.94108599999998],[-81.71083099999998,69.93414299999995],[-81.73832700000003,69.87608300000005],[-81.74137899999988,69.87275700000004],[-81.85417199999995,69.855545],[-81.88027999999991,69.85247800000008],[-81.96028100000001,69.84414699999996],[-81.96278399999989,69.84471100000013],[-81.96333300000003,69.847488],[-81.96250899999995,69.85276800000008],[-81.96333300000003,69.85775799999993],[-81.97250399999996,69.86248799999998],[-81.99527,69.87248199999999],[-82.00167799999986,69.87469499999997],[-82.011124,69.87580900000012],[-82.02000399999986,69.87387100000001],[-82.06166100000002,69.85942100000005],[-82.11888099999987,69.81469700000008],[-82.11860699999994,69.81053200000008],[-82.12609899999995,69.78498800000006],[-82.12971500000003,69.782486],[-82.14334099999996,69.78137200000003],[-82.18998699999992,69.79026799999997],[-82.243607,69.80165099999999],[-82.27139299999999,69.82638500000013],[-82.24166899999994,69.82804899999996],[-82.22444199999995,69.82360800000004],[-82.21028099999995,69.826096],[-82.20666499999999,69.82859800000006],[-82.21501199999989,69.832764],[-82.30305499999992,69.85664400000013],[-82.31416300000001,69.85748300000012],[-82.40360999999996,69.86026000000004],[-82.41776999999996,69.85775799999993],[-82.52639799999997,69.86080900000013],[-82.57501200000002,69.87081900000004],[-82.64416499999993,69.89248700000002],[-82.74137899999994,69.91024800000014],[-83.035278,69.98803700000002],[-83.04083299999996,69.99304200000006],[-83.04444899999993,70.00416600000011],[-83.05139200000002,70.00860599999993],[-83.066666,70.01081800000003],[-83.15028399999994,70.00972000000013],[-83.23889200000002,69.99887100000007],[-83.33917199999996,69.97943100000009],[-83.34527600000001,69.97720300000009],[-83.61389199999996,69.94886800000012],[-83.65417500000001,69.94636500000013],[-83.71528599999988,69.94775400000015],[-83.89862099999999,69.96081500000008],[-83.94471699999997,69.96582000000012],[-84.00167799999997,69.97415200000012],[-84.01083399999993,69.976654],[-84.041672,69.98136900000003],[-84.08277900000002,69.9852600000001],[-84.16166699999997,69.98498500000005],[-84.31416299999995,69.97970600000008],[-84.56054699999987,69.99386600000003],[-84.65695199999999,70.00248700000009],[-84.7286069999999,70.01026900000005],[-84.78388999999999,70.01887499999998],[-85.16305499999993,70.09137000000004],[-85.17610200000001,70.09304800000012],[-85.33528099999995,70.10247800000002],[-85.35388199999994,70.103317],[-85.36915599999998,70.10359199999999],[-85.66639700000002,70.10470599999996],[-85.71972700000003,70.10359199999999],[-85.75250199999994,70.10192900000004],[-85.84722899999997,70.08888200000007],[-85.86944599999987,70.08554100000003],[-85.87499999999994,70.08332800000005],[-85.87805199999997,70.0769350000001],[-85.87609900000001,70.07193000000007],[-85.85472099999998,70.04081700000006],[-85.85166900000002,70.03831500000013],[-85.83833300000003,70.04193100000003],[-85.82695000000001,70.04637100000002],[-85.80194099999994,70.05442800000003],[-85.785278,70.0583190000001],[-85.73277299999995,70.06693999999999],[-85.69166599999994,70.07054100000005],[-85.63639799999999,70.07193000000007],[-85.61805700000002,70.07083100000006],[-85.585556,70.06749000000002],[-85.4688339999999,70.04926300000005],[-85.376938,70.03221100000013],[-85.350281,70.02638200000013],[-85.25140399999998,69.99832200000009],[-85.24305699999991,69.99498],[-85.23611499999998,69.98915099999999],[-85.23944099999994,69.98664900000006],[-85.24499500000002,69.98442100000011],[-85.25778200000002,69.98387100000008],[-85.41339099999999,69.99742900000012],[-85.44123099999996,70.00093099999998],[-85.45122499999997,70.00176999999991],[-85.57749899999993,70.00999500000012],[-85.61389200000002,70.00999500000012],[-85.63500999999991,70.00749199999996],[-85.651947,70.00360100000006],[-85.6783289999999,69.99525499999999],[-85.695267,69.99136399999992],[-85.72694399999995,69.99053999999995],[-85.808334,69.99859600000002],[-85.82333399999999,70.00027500000004],[-85.851944,70.00555400000002],[-86.09306300000003,70.06248499999998],[-86.23083500000001,70.09860200000014],[-86.25500499999993,70.10554500000012],[-86.30194099999994,70.121643],[-86.32640099999998,70.132202],[-86.551941,70.234985],[-86.556107,70.24470500000012],[-86.58111599999995,70.35693400000008],[-86.577225,70.36554000000001],[-86.55860899999999,70.386932],[-86.541946,70.40138200000013],[-86.52417000000003,70.41165200000006],[-86.512787,70.41638200000006],[-86.48110999999994,70.42469800000015],[-86.44833399999993,70.43165599999998],[-86.37304699999999,70.4458160000001],[-86.31304899999986,70.46276899999998],[-86.29499799999996,70.47276299999999],[-86.28750600000001,70.484421],[-86.29777499999994,70.49414100000013],[-86.31388900000002,70.50277700000004],[-86.33444199999997,70.51165800000012],[-86.35360700000001,70.51944000000009],[-86.36221299999994,70.52276599999993],[-86.37471,70.5252690000001],[-86.39083900000003,70.52221700000001],[-86.38999899999999,70.51998900000007],[-86.38389599999988,70.51361100000008],[-86.37554899999998,70.50888100000003],[-86.36776700000001,70.50471500000015],[-86.350281,70.49832200000003],[-86.33972199999994,70.49165299999993],[-86.339447,70.48637400000013],[-86.34056099999998,70.48387099999997],[-86.36332700000003,70.474152],[-86.37388599999997,70.47026100000011],[-86.40750100000002,70.459991],[-86.51568599999996,70.43364000000003],[-86.56500199999994,70.42553700000013],[-86.57833899999997,70.42221100000012],[-86.589722,70.41747999999995],[-86.62777699999998,70.3955380000001],[-86.65139799999997,70.37469500000003],[-86.662216,70.36109900000008],[-86.65943900000002,70.35720800000001],[-86.63833599999992,70.32443200000006],[-86.64723200000003,70.31944300000009],[-86.65556300000003,70.31887800000004],[-86.839722,70.32026700000006],[-86.86193800000001,70.32222000000002],[-86.87609900000001,70.32609600000006],[-86.88110399999994,70.32971199999997],[-86.99055499999992,70.43165599999998],[-86.98889200000002,70.43553200000002],[-86.98249799999996,70.43887300000006],[-86.95361300000002,70.44247400000012],[-86.936935,70.44331399999999],[-86.92471299999994,70.44609100000008],[-86.922775,70.44775400000003],[-86.92138699999992,70.45166000000006],[-86.92193599999996,70.45555099999996],[-86.92832900000002,70.46054100000003],[-86.93720999999994,70.46360800000014],[-86.95333899999997,70.46720900000003],[-86.96777299999991,70.46804800000012],[-86.99638400000003,70.46748400000001],[-87.03416400000003,70.46415700000006],[-87.07250999999997,70.45748900000012],[-87.08944699999995,70.45332300000001],[-87.132767,70.4391480000001],[-87.14056399999998,70.43498199999999],[-87.18222000000003,70.399429],[-87.18499800000001,70.388596],[-87.05749499999996,70.38165300000003],[-87.04388399999999,70.379974],[-87.03167699999995,70.37747200000013],[-87.01055899999994,70.37164300000012],[-86.991379,70.36415099999999],[-86.98110999999994,70.35803199999998],[-86.97277799999995,70.35192900000004],[-86.97639500000002,70.28471400000006],[-86.98582499999998,70.2816620000001],[-86.99943499999995,70.28054800000012],[-87.00917099999992,70.2810970000001],[-87.10749800000002,70.28804000000008],[-87.18443300000001,70.29553200000004],[-87.25500499999998,70.30664100000007],[-87.5625,70.32276899999994],[-87.67361499999998,70.31915300000009],[-87.66999800000002,70.29859899999997],[-87.64389,70.29582200000004],[-87.628601,70.29304500000012],[-87.61721799999998,70.2894290000001],[-87.610275,70.28471400000006],[-87.61332700000003,70.28193699999997],[-87.62388599999997,70.27804600000007],[-87.70417799999996,70.25721700000008],[-87.77694699999995,70.24331699999999],[-87.79695100000004,70.24026500000008],[-87.83389299999999,70.23803700000013],[-87.8663939999999,70.23887600000006],[-87.914444,70.24136400000009],[-87.92304999999999,70.242752],[-87.93554699999999,70.24693300000007],[-88.01282500000002,70.27726700000011],[-88.088165,70.28509500000013],[-88.13861099999991,70.29609700000003],[-88.25056499999994,70.32138100000003],[-88.26306199999993,70.3252720000001],[-88.26472499999994,70.32804900000002],[-88.256958,70.33387800000003],[-88.21417199999996,70.35137900000001],[-88.20666499999993,70.35247800000013],[-88.06177499999995,70.32954400000006],[-88.05494699999997,70.32736999999997],[-88.0501099999999,70.325043],[-88.03828399999992,70.31553600000012],[-88.03078499999992,70.31403399999999],[-88.02427699999987,70.3132020000001],[-87.99444599999998,70.31203499999998],[-87.91639700000002,70.30192600000004],[-87.9016719999999,70.30442800000014],[-87.88861099999997,70.30802900000003],[-87.87998999999996,70.31137100000012],[-87.88249200000001,70.31637599999999],[-87.88999899999999,70.32193000000001],[-87.91471899999999,70.33166500000004],[-88.083618,70.37803600000007],[-88.11193800000001,70.38415500000008],[-88.166946,70.39444000000003],[-88.37443499999995,70.43220500000012],[-88.43998699999992,70.43858300000005],[-88.57917799999996,70.45027199999998],[-88.67027299999995,70.45359800000006],[-88.67944299999999,70.45359800000006],[-88.69305399999996,70.45526100000012],[-88.797775,70.48970000000003],[-88.89750699999996,70.53276100000005],[-88.91444399999989,70.54609699999997],[-88.98582499999986,70.6083220000001],[-89.00389100000001,70.62498499999998],[-89.00917099999998,70.63638300000002],[-88.99999999999994,70.64553800000004],[-88.99972500000001,70.65165700000006],[-89.00527999999991,70.65693699999997],[-89.07667499999997,70.69693000000001],[-89.10583499999996,70.70748900000007],[-89.11888099999999,70.71138000000013],[-89.14388999999994,70.71720900000014],[-89.203888,70.73719800000003],[-89.261124,70.75972000000013],[-89.285278,70.76971400000014],[-89.33056599999992,70.79193100000003],[-89.36971999999997,70.81469700000008],[-89.37416100000002,70.81915300000014],[-89.44833399999999,70.90248100000002],[-89.4472199999999,70.90664700000008],[-89.44360399999994,70.91026299999993],[-89.43249500000002,70.91526800000003],[-89.41639700000002,70.91859400000004],[-89.37165800000002,70.92581200000006],[-89.29861499999993,70.933044],[-89.22277799999995,70.93553199999997],[-89.20944199999991,70.93914799999999],[-89.20584099999996,70.94274900000005],[-89.18859900000001,70.96081500000003],[-89.195267,70.96832300000005],[-89.20556599999992,70.97360200000003],[-89.27027900000002,70.98359700000015],[-89.31527699999992,70.99165300000004],[-89.34056099999992,70.99748200000005],[-89.35472099999993,71.00193799999994],[-89.49499499999996,71.0577550000001],[-89.54972799999996,71.08859300000012],[-89.49137899999994,71.09220900000014],[-89.46972699999998,71.09193399999992],[-89.22833300000002,71.072769],[-89.21694899999994,71.06999200000007],[-89.20861799999994,71.06303400000007],[-89.21528599999994,71.05664100000013],[-89.21806300000003,71.05081200000012],[-89.21250900000001,71.04553200000004],[-89.20306399999998,71.03804000000008],[-89.19665500000002,71.03526300000004],[-89.178604,71.03137200000015],[-89.13444499999997,71.0269320000001],[-89.11776700000001,71.02665700000011],[-89.10082999999992,71.02777100000009],[-89.07611099999997,71.03027299999997],[-89.03944399999995,71.03526300000004],[-88.97999600000003,71.04109200000005],[-88.90472399999999,71.0452580000001],[-88.68916300000001,71.04693600000002],[-88.61776700000001,71.04443400000014],[-88.49027999999998,71.0310970000001],[-88.47888199999994,71.02970900000003],[-88.43249499999996,71.02192700000006],[-88.38027999999997,71.01193199999994],[-88.36915599999998,71.00749200000013],[-88.36582900000002,71.00193799999994],[-88.36332699999997,70.99552900000009],[-88.362503,70.99026500000014],[-88.36277799999999,70.98414600000007],[-88.36027499999994,70.97776799999997],[-88.35694899999999,70.97221400000012],[-88.34361299999995,70.96138000000008],[-88.33250399999997,70.95721399999996],[-88.3186189999999,70.95387299999993],[-88.28971899999993,70.9502720000001],[-88.26083399999999,70.94775400000009],[-88.02528399999994,70.93054200000006],[-87.99999999999989,70.9291530000001],[-87.96888699999988,70.92858899999993],[-87.93055700000002,70.92942800000009],[-87.912781,70.93136600000003],[-87.8577729999999,70.94136000000003],[-87.79804999999993,70.94970700000005],[-87.752792,70.95359800000011],[-87.699997,70.95555100000007],[-87.66444399999995,70.95471200000009],[-87.62748699999986,70.95138500000013],[-87.61054999999993,70.94941700000004],[-87.55943300000001,70.9474790000001],[-87.43582200000003,70.944977],[-87.371216,70.94472500000012],[-87.35360700000001,70.94525099999993],[-87.345551,70.94941700000004],[-87.34306300000003,70.95416299999994],[-87.343613,70.95942700000012],[-87.33778399999989,70.969986],[-87.32917799999996,70.980545],[-87.30860899999999,70.99552900000009],[-87.29888900000003,71],[-87.28611799999999,71.00416600000011],[-87.26722699999988,71.00694299999998],[-87.24694799999992,71.00915500000008],[-87.21250899999995,71.00749200000013],[-87.15139799999986,71],[-87.141388,70.99775700000004],[-87.11610399999995,70.99470500000012],[-87.05139200000002,70.98776199999998],[-87.033615,70.98664900000006],[-87.01750199999992,70.98664900000006],[-87.0041809999999,70.99026500000014],[-87.00306699999999,70.9910890000001],[-87.002792,70.99414100000001],[-87.00973499999998,70.99609399999997],[-87.039444,71.00082399999997],[-87.13500999999997,71.01138300000002],[-87.16639700000002,71.0144350000001],[-87.18443300000001,71.01527400000009],[-87.27917500000001,71.0269320000001],[-87.38583399999999,71.04193099999998],[-87.39472999999998,71.0435940000001],[-87.40472399999993,71.04721100000006],[-87.41082799999998,71.053314],[-87.47277799999995,71.07415799999995],[-87.57278399999996,71.09526100000005],[-87.70140099999998,71.12330600000007],[-87.712784,71.126083],[-87.76028399999996,71.14305100000007],[-87.84889199999986,71.18498200000005],[-87.85194399999995,71.19192500000003],[-87.85249299999998,71.19720500000011],[-87.848343,71.20220900000004],[-87.82528699999995,71.21720900000003],[-87.823059,71.22360199999997],[-87.81666599999994,71.25471499999998],[-87.82194500000003,71.25833100000006],[-87.82945299999994,71.26193200000012],[-87.84416199999993,71.26416000000006],[-87.900284,71.26860000000005],[-87.91166699999991,71.26693699999998],[-87.97193899999996,71.25027499999999],[-88.01972999999998,71.23609899999997],[-88.03416399999998,71.23165899999998],[-88.04194599999994,71.22886700000004],[-88.131104,71.21914700000013],[-88.32167099999998,71.22859200000005],[-88.583618,71.234985],[-88.70666499999993,71.24775699999998],[-88.84999099999999,71.25972000000002],[-89.058044,71.27638200000001],[-89.20666499999993,71.28332500000005],[-89.29916399999996,71.2874910000001],[-89.42860399999995,71.29443400000008],[-89.703888,71.31581100000011],[-89.816666,71.32499700000005],[-89.83000199999998,71.32887299999999],[-89.89973399999991,71.35137900000012],[-89.90722700000003,71.35470600000008],[-89.964722,71.41137700000002],[-89.968613,71.41693100000003],[-89.98306300000002,71.44693000000001],[-90.01055899999989,71.57777400000009],[-90.01306199999993,71.60026600000003],[-90.00472999999994,71.63081399999999],[-90.00306699999993,71.63581799999997],[-89.99722300000002,71.64137300000004],[-89.964722,71.65582299999994],[-89.93276999999995,71.66775500000011],[-89.89611799999994,71.67997700000006],[-89.88473499999992,71.684708],[-89.81750499999998,71.72470100000004],[-89.808334,71.74775700000009],[-89.82139599999994,71.76026900000005],[-89.83138999999994,71.76026900000005],[-89.83612099999999,71.76165800000007],[-89.84306299999997,71.76443499999999],[-89.89361599999995,71.78942899999993],[-89.954453,71.82054100000005],[-89.96028100000001,71.82415800000001],[-90.02667200000002,71.89276100000006],[-90.04861499999998,71.9538730000001],[-90.00111399999992,72.06303400000007],[-89.99305700000002,72.07054099999999],[-89.962784,72.07748399999997],[-89.81221,72.11192300000005],[-89.75083899999993,72.12303199999991],[-89.73889199999996,72.12498500000004],[-89.72582999999997,72.12469500000003],[-89.718887,72.12191799999994],[-89.71583599999997,72.11859100000004],[-89.70472699999999,72.11331200000001],[-89.69166599999994,72.10998500000011],[-89.6824949999999,72.11053500000014],[-89.66471899999993,72.11331200000001],[-89.59750399999996,72.1483310000001],[-89.57972699999999,72.15887499999997],[-89.57472199999995,72.16360500000002],[-89.57667499999997,72.16914400000002],[-89.58473200000003,72.17581199999995],[-89.59889199999998,72.17804000000012],[-89.61805700000002,72.17886400000009],[-89.67666599999995,72.17692599999998],[-89.70584100000002,72.17469799999998],[-89.724716,72.17248500000005],[-89.73889199999996,72.16859399999998],[-89.75944500000003,72.15998800000006],[-89.77055399999995,72.15748599999995],[-89.78056300000003,72.15748599999995],[-89.80248999999992,72.161926],[-89.89222699999999,72.18691999999999],[-89.89723200000003,72.18858300000005],[-89.90139799999992,72.19413799999995],[-89.93943799999994,72.26193200000006],[-89.95417799999996,72.30497700000006],[-89.95750399999991,72.3160860000001],[-89.95666499999993,72.32165500000013],[-89.91332999999997,72.42221100000006],[-89.90750099999997,72.43220500000007],[-89.89056399999987,72.44497700000005],[-89.87249799999995,72.44914200000005],[-89.860275,72.45109600000012],[-89.81361399999997,72.45665000000008],[-89.79943800000001,72.46026599999999],[-89.79360999999989,72.46276899999992],[-89.777222,72.49386600000003],[-89.77528399999989,72.49859600000008],[-89.77250699999996,72.51998900000001],[-89.77278100000001,72.526093],[-89.78666699999997,72.55998200000005],[-89.75389099999995,72.60554499999995],[-89.73693799999995,72.61665299999999],[-89.69999699999994,72.62525900000009],[-89.67832900000002,72.62942499999997],[-89.65695199999999,72.63026400000012],[-89.64361600000001,72.62692300000009],[-89.61471599999999,72.61608900000004],[-89.59750399999996,72.61470000000003],[-89.57278400000001,72.61692800000014],[-89.56054699999993,72.62191800000005],[-89.47055099999994,72.66609199999999],[-89.47361799999987,72.67248500000011],[-89.51194799999996,72.688873],[-89.525284,72.69386300000002],[-89.54916400000002,72.69108599999993],[-89.56750499999993,72.69303900000006],[-89.57472199999995,72.69886800000006],[-89.58000199999992,72.71110500000003],[-89.58139,72.71775800000006],[-89.57472199999995,72.78526300000004],[-89.56945799999994,72.78692599999994],[-89.479446,72.77970900000003],[-89.44638099999992,72.77554299999997],[-89.36471599999993,72.76220699999999],[-89.33056599999992,72.755829],[-89.29415899999992,72.79721100000006],[-89.333328,72.95054600000014],[-89.358337,72.96527100000009],[-89.36138899999997,72.99165299999999],[-89.30888399999998,73.04832499999998],[-89.22833300000002,73.125809],[-89.04333500000001,73.25248699999997],[-89.03582799999998,73.25749200000001],[-89.00028999999995,73.27832000000012],[-88.99055499999997,73.28359999999998],[-88.85694899999999,73.33610500000003],[-88.69583099999994,73.41192600000011],[-88.68360899999999,73.41748000000007],[-88.46806299999997,73.49192800000009],[-88.43331899999993,73.51415999999995],[-88.40916400000003,73.52360500000003],[-88.28639199999998,73.56693999999999],[-88.26306199999993,73.57388300000002],[-88.0747219999999,73.62776200000002],[-87.97444199999995,73.65470900000014],[-87.92332499999992,73.66775500000006],[-87.81723,73.69442700000013],[-87.78028899999998,73.70304899999996],[-87.73999000000003,73.71138000000008],[-87.539444,73.74664300000006],[-87.45666499999999,73.76026900000005],[-87.18360899999993,73.79275500000011],[-87.04943800000001,73.80831900000004],[-86.71665999999999,73.84082000000012],[-86.59666399999998,73.84526100000005],[-86.49305700000002,73.84443700000008],[-86.40139799999992,73.84582499999999],[-86.239441,73.84915200000012],[-86.208618,73.8499910000001],[-86.10916099999997,73.8499910000001],[-85.747772,73.83638000000013],[-85.70666499999999,73.83221400000002],[-85.55305499999997,73.820831],[-85.52000399999997,73.81999200000007],[-85.46250899999995,73.820831],[-85.42193600000002,73.82415800000012],[-85.30777,73.82110600000004],[-85.16332999999986,73.81330900000006],[-85.12110899999993,73.80998199999999],[-85.10499599999997,73.80802900000003],[-85.06945799999988,73.8019260000001],[-85.03472899999991,73.79470800000007],[-84.97000100000002,73.77777100000009],[-84.837784,73.74165299999999],[-84.84277299999997,73.73580900000002],[-84.86555499999992,73.71331800000002],[-84.92250100000001,73.68026700000007],[-84.93138099999999,73.67553700000002],[-84.95611600000001,73.66526799999997],[-84.98500099999995,73.65582300000011],[-85.34083599999985,73.55636600000014],[-85.59638999999999,73.48664900000011],[-85.76640299999985,73.42526200000003],[-85.85110499999996,73.391098],[-85.93028299999997,73.355255],[-86.04666099999986,73.28720100000004],[-86.137787,73.22886700000004],[-86.29222099999998,73.10331700000012],[-86.29638699999998,73.09748800000006],[-86.29444899999993,73.09109500000011],[-86.28889500000002,73.08720400000004],[-86.28443900000002,73.08248900000001],[-86.28416399999998,73.07720899999998],[-86.287216,73.072495],[-86.32833900000003,73.03665199999995],[-86.45445299999989,72.96360799999997],[-86.474716,72.95332300000007],[-86.49526999999989,72.94331400000004],[-86.50556899999998,72.938309],[-86.57112099999995,72.90887500000002],[-86.62721299999993,72.88360599999999],[-86.64750699999996,72.87330600000007],[-86.65361000000001,72.86886600000008],[-86.65833999999995,72.86360200000007],[-86.69554099999999,72.81915300000014],[-86.69665499999996,72.81666600000005],[-86.73277300000001,72.71609500000011],[-86.70333900000003,72.65914899999996],[-86.69833399999999,72.65220599999998],[-86.686935,72.64471400000002],[-86.662216,72.63165300000009],[-86.63833599999992,72.62052900000003],[-86.61138900000003,72.60914600000001],[-86.50418100000002,72.56860400000005],[-86.47972099999998,72.56053200000008],[-86.46611000000001,72.55636599999997],[-86.45140100000003,72.55304000000012],[-86.41444399999995,72.54165600000005],[-86.39723200000003,72.53498800000006],[-86.35305799999998,72.51165800000007],[-86.33805799999999,72.50305199999997],[-86.28306600000002,72.46832300000011],[-86.27583299999998,72.46331800000007],[-86.26777600000003,72.4563750000001],[-86.25500499999993,72.44358800000009],[-86.24082900000002,72.4202580000001],[-86.24082900000002,72.40664700000013],[-86.24610899999999,72.39498900000012],[-86.25805700000001,72.38443000000007],[-86.27528399999994,72.37387100000001],[-86.308044,72.35914600000007],[-86.35082999999992,72.33915699999994],[-86.37777699999992,72.32360800000004],[-86.39611799999994,72.30914300000012],[-86.42805499999992,72.28193700000008],[-86.43582200000003,72.27026400000005],[-86.45527600000003,72.20721400000008],[-86.43443299999996,72.04998799999993],[-86.43249500000002,72.04332],[-86.42582700000003,72.02499399999999],[-86.420547,72.01277199999998],[-86.33667000000003,71.95193499999999],[-86.16610700000001,71.824997],[-86.13276699999994,71.7958220000001],[-86.11054999999999,71.783051],[-86.07861300000002,71.77554299999997],[-86.05166600000001,71.77165200000007],[-86.02444499999996,71.76582300000007],[-85.94721999999996,71.72692899999998],[-85.90556300000003,71.69970700000005],[-85.87193300000001,71.67692600000004],[-85.50083899999998,71.51110800000009],[-85.39195299999994,71.48165900000009],[-85.37416100000002,71.47886699999998],[-85.22860699999995,71.46554600000007],[-84.94860799999998,71.42164600000007],[-84.93472300000002,71.41832],[-84.92999299999997,71.4144290000001],[-84.85916099999997,71.32110599999999],[-84.83805799999993,71.29193099999992],[-84.83416699999998,71.28526299999999],[-84.83277899999996,71.27886999999998],[-84.83389299999993,71.27415499999995],[-84.835556,71.27165200000002],[-84.848343,71.26944000000015],[-84.868607,71.2688750000001],[-84.92166099999997,71.27082800000005],[-85.041946,71.278595],[-85.1725009999999,71.27249099999995],[-85.17388899999997,71.26998900000007],[-85.17832900000002,71.266388],[-85.38999899999993,71.19664000000006],[-85.39999399999994,71.19386299999996],[-85.50028999999995,71.17720000000008],[-85.514725,71.17608600000011],[-85.53250100000002,71.17720000000008],[-85.66305499999999,71.19442700000013],[-85.76139799999999,71.19220000000007],[-85.83833300000003,71.18748500000004],[-85.93276999999995,71.17886400000009],[-85.96665999999993,71.17109700000015],[-86.17083699999995,71.10693400000008],[-86.21083099999998,71.09387200000009],[-86.21444699999995,71.08970599999998],[-86.206955,71.08387800000008],[-86.20611599999995,71.07804900000002],[-86.212784,71.072769],[-86.24888599999997,71.05859400000008],[-86.28860500000002,71.05220000000003],[-86.408051,71.03526300000004],[-86.45083599999992,71.03137200000015],[-86.51777599999997,71.03166199999998],[-86.64389,71.01943999999997],[-86.74999999999994,71.00776699999994],[-86.7702789999999,71.00416600000011],[-86.785553,71.00027500000004],[-86.79861499999998,70.99636800000007],[-86.81916799999988,70.98942599999998],[-86.82000700000003,70.98858600000011],[-86.80665599999998,70.98387100000008],[-86.75778200000002,70.97665399999994],[-86.71305799999993,70.97415200000006],[-86.60194399999995,70.97164900000007],[-86.54750099999995,70.9788670000001],[-86.43028300000003,70.98887600000012],[-86.29222099999998,71.00027500000004],[-86.27027900000002,71.0027770000001],[-86.22416699999985,71.0144350000001],[-86.026947,71.07138100000009],[-85.83250399999991,71.12719700000014],[-85.80221599999999,71.13581800000003],[-85.77917499999995,71.13916],[-85.67027300000001,71.14888000000008],[-85.650284,71.149429],[-85.50500499999998,71.15803499999993],[-85.41166699999997,71.17442299999999],[-85.39167800000001,71.17498800000004],[-85.28860500000002,71.15914900000013],[-85.27416999999991,71.15525800000006],[-85.11054999999999,71.16165200000006],[-85.04222099999993,71.18165600000003],[-85.037216,71.18304400000011],[-84.99888599999997,71.18748500000004],[-84.96167000000003,71.18858300000011],[-84.94415299999997,71.18719500000003],[-84.87527499999999,71.1727600000001],[-84.84999099999999,71.15470900000008],[-84.84584000000001,71.1477660000001],[-84.87110899999999,71.07360799999992],[-84.87582399999985,71.06999200000007],[-84.87971499999992,71.06944299999992],[-84.90417500000001,71.07804900000002],[-84.93582199999997,71.09248399999996],[-84.95056199999993,71.09693900000002],[-84.96611000000001,71.10026600000009],[-84.9808349999999,71.101089],[-85.00111400000003,71.10081500000007],[-85.14222699999993,71.08638000000013],[-85.14695699999999,71.08276400000005],[-85.11277799999993,71.07916300000005],[-85.06138599999991,71.07638500000002],[-84.99221799999998,71.07748400000003],[-84.9766689999999,71.07582100000008],[-84.96028100000001,71.07222000000002],[-84.92971799999998,71.00444000000005],[-84.92694099999994,70.98803700000013],[-84.93028299999997,70.98165900000004],[-84.94137599999999,70.9705350000001],[-84.95083599999998,70.96554600000013],[-84.96333300000003,70.95582600000006],[-84.975281,70.94525099999993],[-84.97610500000002,70.93331899999998],[-84.97083999999995,70.92747499999996],[-84.96472199999994,70.92248500000011],[-84.958618,70.91943400000008],[-84.94110099999995,70.91804500000006],[-84.81416299999995,70.91943400000008],[-84.79888899999997,70.92164600000012],[-84.79361,70.92665099999999],[-84.74833699999999,70.97553999999997],[-84.74804699999999,70.98803700000013],[-84.771118,71.03749099999999],[-84.803604,71.04721100000006],[-84.81916799999999,71.05748000000011],[-84.827789,71.06832899999995],[-84.82972699999988,71.07331799999992],[-84.828888,71.07998700000002],[-84.82667500000002,71.08554100000015],[-84.80139200000002,71.14860500000003],[-84.766663,71.19747900000004],[-84.77084399999995,71.25499000000002],[-84.78138699999994,71.26193200000012],[-84.78666699999991,71.26776100000012],[-84.79305999999997,71.27804600000002],[-84.79666099999992,71.29748500000011],[-84.79722600000002,71.30331400000011],[-84.7625119999999,71.40664699999996],[-84.74943499999995,71.41665599999999],[-84.73194899999993,71.42469800000015],[-84.720551,71.428314],[-84.69305399999996,71.434143],[-84.67832900000002,71.43525700000004],[-84.66000400000001,71.43165599999998],[-84.65306099999992,71.43193100000013],[-84.57167099999992,71.440811],[-84.55749500000002,71.44413800000012],[-84.54777499999994,71.44747899999999],[-84.53916900000002,71.45166000000006],[-84.53195199999993,71.45694000000015],[-84.52610800000002,71.46887200000009],[-84.52639799999992,71.47831699999995],[-84.53056300000003,71.49247700000006],[-84.53361499999994,71.50248699999997],[-84.54666099999997,71.52748099999997],[-84.55471799999992,71.5410920000001],[-84.56138599999991,71.54998800000004],[-84.56443799999994,71.55247500000013],[-84.610275,71.56275900000014],[-84.63639799999993,71.5705410000001],[-84.64862099999999,71.57638500000013],[-84.65834000000001,71.58387800000014],[-84.65499899999998,71.60887100000002],[-84.65306099999992,71.61276200000009],[-84.64250199999998,71.62275700000004],[-84.62554899999998,71.63304100000005],[-84.61054999999999,71.64166300000005],[-84.604446,71.64610300000004],[-84.60665899999992,71.64942900000011],[-84.625,71.665817],[-84.62805200000003,71.66831999999994],[-84.635559,71.6702580000001],[-84.64973399999997,71.672211],[-84.71083099999993,71.676086],[-84.77305599999994,71.67858899999999],[-84.78277600000001,71.67886399999998],[-84.82749899999999,71.67526200000003],[-84.86721799999992,71.66804500000012],[-84.88620000000003,71.6542510000001],[-84.92666600000001,71.63610799999998],[-84.975281,71.64444000000015],[-85.09750399999996,71.65525800000012],[-85.176941,71.65664700000013],[-85.19665500000002,71.65582299999994],[-85.23083500000001,71.65998799999994],[-85.26390099999998,71.66554300000007],[-85.27972399999999,71.66859400000004],[-85.291382,71.672211],[-85.57084699999996,71.77998400000007],[-85.57972699999999,71.78498800000006],[-85.57362399999994,71.79081700000006],[-85.55777,71.79525799999999],[-85.54388399999993,71.7955320000001],[-85.45889299999999,71.79414399999996],[-85.44972199999995,71.79609700000009],[-85.43693499999995,71.80081200000012],[-85.43276999999995,71.80636600000014],[-85.43194599999998,71.81469700000002],[-85.4344329999999,71.81805399999996],[-85.55166600000001,71.89637800000003],[-85.55972299999996,71.90054300000003],[-85.74499500000002,71.94136000000003],[-85.8458399999999,71.96249400000005],[-85.90083299999998,71.96914700000002],[-85.93998699999997,71.97303800000009],[-85.96333300000003,71.974426],[-86.00250199999999,71.97804300000013],[-86.02278100000001,71.980545],[-86.02667200000002,71.98165899999998],[-86.03916900000002,71.98887600000012],[-86.04361,71.99552900000009],[-86.05082700000003,72.01110799999998],[-86.04750100000001,72.01388500000007],[-85.98111,72.028595],[-85.778885,72.0269320000001],[-85.53832999999997,72.059143],[-85.50944499999991,72.06805400000013],[-85.49527,72.07887299999999],[-85.44055200000003,72.1327510000001],[-85.44915800000001,72.1583250000001],[-85.48194899999993,72.17330900000002],[-85.50167799999997,72.18414300000006],[-85.50250199999999,72.25166300000006],[-85.49749799999995,72.25526400000012],[-85.48721299999994,72.260269],[-85.29194599999988,72.25999500000006],[-85.27194199999997,72.25972000000002],[-85.02917500000001,72.25082400000008],[-85.01333599999998,72.25000000000011],[-84.93638599999991,72.23580900000013],[-84.91999799999996,72.2327580000001],[-84.86776699999996,72.22082500000005],[-84.86138899999992,72.21775800000012],[-84.84750400000001,72.20555099999996],[-84.83917200000002,72.19413799999995],[-84.81527699999992,72.18136600000014],[-84.8033289999999,72.17776500000008],[-84.710556,72.15165699999994],[-84.612213,72.14109800000011],[-84.59583999999995,72.13777200000004],[-84.51222200000001,72.11415099999999],[-84.28639199999998,72.028595],[-84.27555799999993,72.02387999999996],[-84.269455,72.02082800000005],[-84.261124,72.01609800000006],[-84.2580569999999,72.01193200000012],[-84.25,71.99832200000009],[-84.23998999999992,71.97387700000002],[-84.23638900000003,71.96165500000006],[-84.23055999999985,71.95138500000013],[-84.22500600000001,71.94552599999992],[-84.218887,71.94026200000013],[-84.20861799999989,71.93414300000012],[-84.19444299999998,71.93081700000005],[-84.18472299999996,71.93054200000006],[-84.17832900000002,71.93275500000004],[-84.17277499999994,71.93775900000014],[-84.16888399999988,71.94413800000001],[-84.158615,71.97720300000009],[-84.16471899999988,72.0211030000001],[-84.171112,72.02415500000001],[-84.21806300000003,72.04414400000013],[-84.27000399999991,72.051086],[-84.28582799999998,72.05415299999993],[-84.31973299999987,72.0619200000001],[-84.34666399999998,72.06971700000003],[-84.35777299999995,72.07638500000002],[-84.37999000000002,72.10832199999999],[-84.38055399999996,72.12359600000008],[-84.45611600000001,72.13360599999999],[-84.47332799999998,72.13581800000003],[-84.61332699999991,72.16360500000002],[-84.65222199999994,72.17886400000009],[-84.72193900000002,72.21304300000008],[-84.93331899999993,72.284424],[-84.93527199999994,72.28942900000004],[-84.91749599999997,72.29971300000005],[-84.82945299999994,72.3483280000001],[-84.816101,72.35276799999991],[-84.80139200000002,72.35470600000008],[-84.76972999999998,72.35636899999997],[-84.715012,72.35582000000005],[-84.66194199999995,72.35415600000005],[-84.56500199999999,72.34887700000007],[-84.52111799999994,72.35054000000014],[-84.50083899999993,72.3538670000001],[-84.48443599999996,72.3580320000001],[-84.43611099999993,72.37498499999998],[-84.43306000000001,72.37831100000005],[-84.44221500000003,72.38304100000005],[-84.45333900000003,72.38247700000011],[-84.47138999999993,72.37942500000003],[-84.57167099999992,72.36137400000001],[-84.86416600000001,72.36692800000003],[-84.872772,72.36943100000002],[-84.87609899999995,72.37220800000011],[-84.87554899999992,72.39498900000012],[-84.870834,72.40081800000013],[-84.85777299999995,72.40554799999995],[-84.83667000000003,72.40803500000004],[-84.81750499999998,72.40664700000013],[-84.80027799999999,72.40664700000013],[-84.78666699999991,72.40887500000008],[-84.76834100000002,72.44442700000002],[-84.76722699999993,72.44747899999999],[-84.76834100000002,72.45193500000005],[-84.771118,72.45748900000007],[-84.776947,72.458328],[-84.791946,72.45498699999996],[-84.91860999999994,72.42526200000009],[-85.00834700000001,72.39942900000011],[-85.02166699999998,72.39471400000008],[-85.14472999999992,72.35942100000011],[-85.33901999999995,72.40641800000003],[-85.37027,72.41470300000003],[-85.515289,72.45887800000003],[-85.53527799999995,72.46971100000002],[-85.61000100000001,72.53166200000004],[-85.61805700000002,72.54081700000006],[-85.61721799999998,72.5455320000001],[-85.61389200000002,72.55026199999998],[-85.59861799999993,72.555252],[-85.50834700000001,72.56137100000001],[-85.48611499999993,72.56498700000009],[-85.47805799999998,72.568329],[-85.473053,72.57193000000007],[-85.47555499999999,72.57527200000004],[-85.48111,72.57748400000008],[-85.49999999999994,72.58027600000014],[-85.55999800000001,72.58248900000012],[-85.62388599999991,72.58692899999994],[-85.641953,72.59275799999995],[-85.65417499999995,72.59803800000003],[-85.66471899999993,72.60554499999995],[-85.70306399999993,72.63415500000002],[-85.70527600000003,72.63777199999998],[-85.70777899999996,72.64637800000008],[-85.70944199999991,72.73692299999999],[-85.68804899999998,72.89359999999999],[-85.68472300000002,72.89833099999993],[-85.67944299999999,72.90359500000011],[-85.59222399999999,72.95915200000007],[-85.58168,72.96415700000011],[-85.57055700000001,72.96693400000004],[-85.54916400000002,72.96971100000013],[-85.49972500000001,72.974152],[-85.48194899999993,72.974152],[-85.37887599999993,72.97110000000009],[-85.28306600000002,72.96443199999993],[-85.25750700000003,72.96081499999997],[-85.12748699999997,72.94026200000013],[-85.07749899999993,72.92997700000001],[-85.015015,72.9160920000001],[-84.96665999999999,72.90498400000013],[-84.93249499999996,72.89637800000003],[-84.87443499999995,72.88554399999992],[-84.819458,72.88026400000007],[-84.70750399999997,72.86998000000006],[-84.66861,72.86747700000006],[-84.61082499999992,72.86164900000011],[-84.50445599999995,72.84610000000004],[-84.43721,72.83360300000004],[-84.40499899999992,72.82609600000012],[-84.38945000000001,72.82222000000002],[-84.32084700000001,72.80081200000012],[-84.29110700000001,72.79165599999999],[-84.25750700000003,72.78526300000004],[-84.18832399999997,72.77442899999994],[-83.99137899999994,72.7458190000001],[-83.97222899999997,72.74414100000001],[-83.958054,72.74664300000006],[-83.95527599999991,72.74832200000009],[-83.95306399999993,72.75248700000009],[-83.95639,72.75499000000008],[-83.989441,72.76887499999998],[-84.04083299999996,72.77748100000008],[-84.073624,72.78166199999998],[-84.10804699999994,72.78526300000004],[-84.218613,72.79498300000012],[-84.24694799999997,72.79971299999994],[-84.29138199999994,72.81248499999998],[-84.311935,72.82026700000011],[-84.33528099999995,72.82998700000002],[-84.41915899999992,72.85331699999995],[-84.528885,72.88247700000005],[-84.57722499999994,72.89221200000009],[-84.65249599999999,72.89942900000005],[-84.70639,72.90582300000005],[-84.74360699999994,72.91081200000002],[-84.76055899999994,72.914154],[-84.79110700000001,72.92137100000008],[-84.85583500000001,72.93748500000004],[-84.87026999999995,72.94220000000007],[-85.05999800000001,72.996643],[-85.22360999999995,73.01498400000003],[-85.51390100000003,73.01914999999991],[-85.53527799999995,73.021927],[-85.537216,73.02832000000001],[-85.47193900000002,73.09803799999992],[-85.44776899999994,73.12025499999999],[-85.44027699999998,73.12553399999996],[-85.42944299999994,73.13053900000006],[-85.41583299999996,73.13526900000005],[-85.40695199999993,73.13638300000002],[-85.395554,73.1355440000001],[-85.37999000000002,73.13360599999993],[-85.37332200000003,73.13081400000004],[-85.36999500000002,73.12831100000005],[-85.36389199999996,73.12081899999993],[-85.35943599999996,73.11387600000012],[-85.35804699999994,73.10971100000012],[-85.333618,73.09248400000013],[-85.30027799999993,73.07804900000002],[-85.25688899999994,73.0714870000001],[-85.24806199999995,73.06864900000011],[-85.24089100000003,73.06681800000013],[-85.18805700000001,73.05981400000007],[-85.17588799999999,73.0586550000001],[-85.16638899999998,73.06065400000011],[-85.17139399999996,73.06631500000009],[-85.15249599999999,73.07276900000011],[-85.186935,73.09693900000013],[-85.22694399999995,73.11581400000006],[-85.229172,73.12303200000008],[-85.22778299999999,73.12915000000004],[-85.223053,73.13472000000013],[-85.21362299999998,73.13888500000013],[-85.19193999999999,73.14166300000011],[-85.14834599999995,73.14166300000011],[-85.08917199999996,73.137497],[-85.05332900000002,73.13220200000012],[-85.00306699999987,73.12191800000011],[-84.98860200000001,73.11692800000009],[-84.92138699999998,73.09832799999992],[-84.90417500000001,73.09526100000005],[-84.82972699999988,73.08554100000015],[-84.77278100000001,73.08110000000005],[-84.55665599999998,73.06442300000003],[-84.21250899999995,73.04026800000003],[-84.07722499999994,73.03387500000008],[-83.92332499999992,73.03360000000004],[-83.8677669999999,73.02970900000014],[-83.84973100000002,73.02748100000002],[-83.83250399999997,73.02415500000001],[-83.76139799999993,73.0063780000001],[-83.718887,72.9891510000001],[-83.63444500000003,72.98248300000012],[-83.63333099999994,72.9833220000001],[-83.63444500000003,72.98637400000001],[-83.648346,72.99136400000003],[-83.69249000000002,73.00555400000013],[-83.77667200000002,73.03109700000005],[-83.87971500000003,73.05192600000004],[-83.91361999999992,73.05831899999998],[-83.93472300000002,73.06109600000008],[-83.95584100000002,73.06164600000011],[-83.974716,73.06080600000007],[-84.03971899999999,73.05636600000008],[-84.05972300000002,73.05636600000008],[-84.09500100000002,73.05831899999998],[-84.197495,73.06860400000011],[-84.23693800000001,73.08110000000005],[-84.24804699999999,73.083328],[-84.275284,73.08692900000005],[-84.43388400000003,73.10609399999998],[-84.53111299999995,73.1102600000001],[-84.54750100000001,73.11137400000007],[-84.58444199999997,73.11581400000006],[-84.73638900000003,73.13720699999999],[-84.789444,73.14582800000011],[-84.86500499999988,73.16360499999996],[-84.91278099999994,73.17553700000013],[-84.94221500000003,73.18165599999998],[-84.985275,73.19053600000001],[-85.02000399999997,73.19693000000007],[-85.058334,73.20054600000009],[-85.10055499999999,73.20138500000007],[-85.13806199999993,73.20443699999998],[-85.17054699999994,73.21081500000014],[-85.17721599999993,73.21388200000007],[-85.18443300000001,73.21887200000009],[-85.18859900000001,73.22360200000014],[-85.18859900000001,73.22886700000004],[-85.13890099999998,73.29998800000004],[-85.13417099999998,73.30554200000006],[-85.11582899999996,73.31442300000015],[-85.07778899999988,73.32943700000004],[-85.01722699999999,73.3483280000001],[-84.97999600000003,73.35664399999996],[-84.80804399999994,73.38832100000013],[-84.78694200000001,73.38804600000009],[-84.75639299999995,73.38108800000009],[-84.741669,73.37608300000005],[-84.72193900000002,73.36219800000015],[-84.71278399999994,73.34860200000003],[-84.69499200000001,73.32693499999999],[-84.685272,73.31999199999996],[-84.65499899999998,73.30554200000006],[-84.424713,73.23248300000006],[-84.40888999999999,73.22859199999999],[-84.39250199999992,73.226089],[-84.37721299999993,73.224152],[-84.3552699999999,73.22303799999997],[-84.33944699999995,73.226089],[-84.34777799999995,73.23248300000006],[-84.41305499999999,73.27221700000001],[-84.45111099999997,73.28858899999994],[-84.46083099999998,73.29193100000009],[-84.48971599999993,73.29971300000005],[-84.56361399999997,73.31387300000011],[-84.57667499999991,73.31776400000001],[-84.58694500000001,73.3230440000001],[-84.597778,73.33082600000006],[-84.65360999999996,73.38720699999993],[-84.656113,73.39054900000008],[-84.65222199999994,73.393326],[-84.64222699999993,73.39721700000007],[-84.625,73.40138200000007],[-84.58389299999999,73.40914900000001],[-84.43415799999997,73.43525699999998],[-84.28443899999996,73.46110500000009],[-84.229172,73.47026100000005],[-84.19444299999998,73.47470100000004],[-84.17138699999992,73.47526600000009],[-84.11389200000002,73.46914700000008],[-83.75192300000003,73.42749000000003],[-83.72471599999994,73.41304000000008],[-83.71777299999997,73.405823],[-83.71972699999998,73.39971900000012],[-83.72471599999994,73.3938750000001],[-83.72805800000003,73.38108800000009],[-83.72055099999994,73.36581400000006],[-83.71221899999995,73.35192899999993],[-83.70249899999988,73.33915700000011],[-83.68943799999994,73.32360800000004],[-83.66583300000002,73.30775499999999],[-83.65750099999997,73.3035890000001],[-83.648056,73.30026199999998],[-83.63082899999995,73.29721099999995],[-83.61389199999996,73.29609700000015],[-83.60055499999993,73.29748500000005],[-83.59306299999997,73.30137599999995],[-83.59083599999991,73.30720499999995],[-83.59110999999996,73.313309],[-83.59416199999998,73.32527200000004],[-83.62499999999994,73.41526800000003],[-83.63333099999994,73.42886400000003],[-83.64250199999998,73.43969699999997],[-83.65249599999999,73.44525099999998],[-83.66389500000002,73.4497070000001],[-83.67971799999992,73.45387299999999],[-83.69694500000003,73.45721400000002],[-83.754456,73.46331800000007],[-83.81054699999993,73.47053499999998],[-83.95472699999993,73.49275200000005],[-83.97860699999995,73.49664300000012],[-83.993607,73.50027500000004],[-84.00418099999996,73.50416600000011],[-84.00695799999994,73.50972000000013],[-83.99694799999997,73.51388500000013],[-83.979172,73.51805100000001],[-83.74082899999996,73.56776399999995],[-83.57749899999999,73.59637500000008],[-83.445267,73.615814],[-83.21916199999987,73.65664700000008],[-83.08528099999995,73.65776100000005],[-83.01834099999991,73.66609199999994],[-82.931107,73.69053600000007],[-82.90222199999994,73.70027200000004],[-82.88999899999999,73.70526100000001],[-82.87277199999988,73.71554600000013],[-82.86972000000003,73.72109999999998],[-82.86332699999997,73.72608900000012],[-82.85278299999993,73.73027000000002],[-82.84083599999997,73.73275799999999],[-82.82084699999996,73.73359700000015],[-82.63612399999994,73.72776799999991],[-82.52999899999992,73.72221400000012],[-82.47500600000001,73.71998599999995],[-82.41389499999997,73.71887199999998],[-82.36749299999991,73.71914700000002],[-82.21945199999999,73.72526600000003],[-81.99082899999996,73.73136899999997],[-81.61805700000002,73.72109999999998],[-81.57250999999997,73.71971100000013],[-81.55387899999994,73.71720900000008],[-81.53666699999985,73.71388200000013],[-81.47610500000002,73.69802900000008],[-81.45722999999998,73.6910860000001],[-81.28250099999997,73.58027600000014],[-81.23971599999987,73.54693600000007],[-81.228882,73.53553800000009],[-81.21945199999999,73.52137800000014],[-81.19749499999995,73.47720300000015],[-81.18832399999991,73.38970900000004],[-81.21166999999997,73.326096],[-81.21610999999996,73.31469700000008],[-81.21583599999997,73.30386399999992],[-81.21417200000002,73.29193100000009],[-81.20944199999991,73.2727660000001],[-81.20472699999999,73.266663],[-81.19249000000002,73.26054399999998],[-81.17749000000003,73.25637800000004],[-81.10166899999996,73.23831200000006],[-81.07444800000002,73.23220800000007],[-80.90028399999994,73.209427],[-80.71278399999994,73.18026700000013],[-80.66471899999993,73.17109700000009],[-80.64083900000003,73.16554300000013],[-80.61721799999998,73.157761],[-80.59638999999999,73.14804100000009],[-80.55776999999995,73.11137400000007],[-80.54750100000001,73.09803799999992],[-80.54777499999994,73.09136999999998],[-80.54943799999995,73.08194000000009],[-80.59333799999996,73.02581800000007],[-80.61749299999997,73.00555400000013],[-80.641388,72.99609400000008],[-80.64750700000002,72.99054000000007],[-80.65222199999994,72.97470099999998],[-80.65083300000003,72.96914699999996],[-80.63389599999994,72.94053600000007],[-80.64250199999998,72.93553200000008],[-80.64277599999997,72.92886400000009],[-80.63833599999998,72.9227600000001],[-80.537216,72.851089],[-80.51390100000003,72.83888200000001],[-80.48777799999999,72.828598],[-80.44055200000003,72.818604],[-80.40556300000003,72.81330900000012],[-80.34916699999997,72.80636600000014],[-80.33332799999994,72.80304000000007],[-80.31945799999994,72.799149],[-80.29998799999998,72.78804000000014],[-80.283615,72.77748100000008],[-80.24749800000001,72.73054500000006],[-80.2580569999999,72.724426],[-80.33222999999992,72.71249400000005],[-80.36166400000002,72.70609999999999],[-80.44499199999996,72.67359900000008],[-80.46472199999994,72.66526800000003],[-80.541382,72.62886000000015],[-80.55610699999994,72.6202550000001],[-80.55638099999987,72.60720800000007],[-80.64862099999999,72.55497700000001],[-80.67639199999996,72.54721100000012],[-80.765289,72.5169370000001],[-80.94248999999996,72.45526100000012],[-80.95388799999995,72.45054600000009],[-80.98832700000003,72.42970300000002],[-81.186935,72.29914900000011],[-81.19249000000002,72.29359400000004],[-81.19972200000001,72.289154],[-81.22250400000001,72.2816620000001],[-81.23916600000001,72.27777100000003],[-81.30471799999998,72.26832600000012],[-81.37943999999999,72.24165299999993],[-81.36527999999998,72.24165299999993],[-81.30139200000002,72.24609400000003],[-81.28582799999992,72.24720800000006],[-81.25306699999999,72.25193800000005],[-81.24194299999999,72.25443999999993],[-81.22972099999993,72.25860600000004],[-81.16416900000002,72.2872010000001],[-81.03750600000001,72.35108900000012],[-80.92944299999994,72.40026899999998],[-80.82167099999998,72.43914800000005],[-80.715012,72.47303799999997],[-80.60055499999999,72.50665300000003],[-80.58029199999993,72.509995],[-80.55444299999999,72.51249700000005],[-80.53944399999995,72.51165800000007],[-80.52555799999999,72.50804099999993],[-80.51640299999991,72.50387599999993],[-80.508896,72.49664300000012],[-80.50306699999999,72.48498500000011],[-80.49527,72.46415700000006],[-80.49276700000001,72.45304900000002],[-80.493607,72.44720500000005],[-80.51417499999997,72.37970000000001],[-80.52500900000001,72.37414600000005],[-80.54222099999987,72.37052900000009],[-80.56443799999994,72.36665300000004],[-80.60305800000003,72.36303700000013],[-80.65556299999997,72.35192899999998],[-80.66915899999998,72.34721400000012],[-80.68055699999996,72.34220900000008],[-80.78332499999999,72.29026799999997],[-80.79415899999992,72.28471400000001],[-80.80833399999995,72.27415500000012],[-80.854172,72.23553500000003],[-80.89695699999993,72.19442700000008],[-80.90556300000003,72.180542],[-80.816666,72.15054299999997],[-80.769455,72.14166300000011],[-80.75389099999995,72.14054899999996],[-80.70973200000003,72.13192700000013],[-80.58084099999996,72.09443700000008],[-80.569458,72.08831800000007],[-80.56723,72.07720899999998],[-80.56723,72.07276899999994],[-80.57417299999992,72.06832900000012],[-80.58833300000003,72.06414800000005],[-80.63055400000002,72.06219500000009],[-80.646118,72.06330900000006],[-80.68666100000002,72.07304399999998],[-80.74194299999994,72.09414700000008],[-80.94110099999995,72.0874940000001],[-81.08029199999993,72.05165100000005],[-81.08666999999997,72.04664600000001],[-81.08332799999994,72.04553200000004],[-81.06500199999994,72.04165599999993],[-81.04666099999997,72.03997800000002],[-80.99055499999997,72.03776600000015],[-80.92721599999999,72.03776600000015],[-80.906387,72.03997800000002],[-80.89222699999999,72.04414400000013],[-80.88639799999999,72.04971300000011],[-80.87943999999999,72.05415299999993],[-80.86665299999999,72.0577550000001],[-80.84722899999997,72.05664100000013],[-80.79277000000002,72.02777100000003],[-80.79415899999992,72.022491],[-80.82139599999988,71.95637499999998],[-80.833328,71.94581599999998],[-80.84944199999995,71.93470799999994],[-80.88612399999994,71.92082199999999],[-80.93331899999993,71.90887500000002],[-80.97500599999995,71.895828],[-80.98083499999996,71.89027399999998],[-80.983612,71.88638300000014],[-80.97166400000003,71.88165300000009],[-80.950287,71.88108800000003],[-80.92639200000002,71.88275099999998],[-80.90361000000001,71.88526899999994],[-80.86805699999996,71.89305100000007],[-80.76722699999999,71.92942800000009],[-80.75611900000001,71.93414300000012],[-80.75029,71.93969700000008],[-80.74694799999997,71.9452510000001],[-80.74472000000003,71.95193499999999],[-80.745834,71.95748899999995],[-80.75556899999998,71.97109999999992],[-80.75834699999996,71.97776800000008],[-80.74694799999997,71.98248300000012],[-80.65916400000003,72.00305200000008],[-80.63944999999995,72.00637799999993],[-80.620544,72.006104],[-80.53527799999995,72.01609800000006],[-80.44888300000002,72.02916000000005],[-80.410553,72.0394290000001],[-80.38500999999997,72.04832500000003],[-80.35055499999993,72.06915300000009],[-80.34777799999995,72.0752720000001],[-80.34666399999998,72.08110000000005],[-80.34722899999991,72.08831800000007],[-80.35249299999998,72.09553499999998],[-80.358612,72.10137900000001],[-80.37026999999995,72.10803199999998],[-80.38305699999995,72.11331200000001],[-80.410278,72.12136800000007],[-80.43388400000003,72.1327510000001],[-80.44554099999999,72.1397090000001],[-80.45527599999997,72.14665200000007],[-80.47860700000001,72.16859399999998],[-80.48332199999999,72.17526199999992],[-80.48693800000001,72.18304400000005],[-80.48666400000002,72.18942300000015],[-80.46806299999997,72.19192500000003],[-80.42694099999989,72.19108600000004],[-80.40861499999988,72.1891480000001],[-80.39361600000001,72.17720000000008],[-80.37666300000001,72.17442299999999],[-80.35555999999991,72.17442299999999],[-80.33139,72.17608600000011],[-80.2411039999999,72.19775400000003],[-80.23527499999994,72.20332300000001],[-80.24444599999993,72.20971700000007],[-80.27305599999994,72.21914700000013],[-80.27972399999993,72.22554000000008],[-80.30166599999995,72.24859600000013],[-80.30638099999999,72.25526400000012],[-80.29554699999994,72.27442900000005],[-80.28971899999993,72.27998400000013],[-80.27223199999997,72.29026799999997],[-80.26083399999999,72.294983],[-80.24221799999998,72.29748500000011],[-80.22444200000001,72.29637100000014],[-80.19415300000003,72.28776600000009],[-80.15583800000002,72.27360500000009],[-80.13473499999992,72.26277199999993],[-80.11305199999998,72.24414100000013],[-80.08555599999994,72.22665400000005],[-80.02139299999999,72.18969700000008],[-79.99166899999989,72.1766510000001],[-79.962784,72.16886899999997],[-79.94722000000002,72.16526799999991],[-79.89973399999997,72.15554800000001],[-79.84028599999994,72.145264],[-79.79055799999998,72.13777200000004],[-79.761124,72.13415500000008],[-79.68554699999993,72.12637299999994],[-79.67443799999995,72.12664799999999],[-79.67250100000001,72.12970000000007],[-79.691666,72.14166300000011],[-79.71916199999993,72.1483310000001],[-79.78999299999998,72.15582300000005],[-79.81111099999998,72.16026300000004],[-79.85499599999997,72.17109700000015],[-79.92388900000003,72.19053600000001],[-79.941101,72.1958160000001],[-80.045547,72.24247700000012],[-80.15194699999995,72.31053199999997],[-80.16639699999996,72.32222000000013],[-80.16444399999995,72.32748400000014],[-80.15556299999992,72.336929],[-80.13362099999995,72.349716],[-80.11527999999993,72.35942100000011],[-80.07640099999998,72.37885999999997],[-80.06471299999998,72.3836060000001],[-80.05221599999999,72.38777199999998],[-79.99194299999999,72.40277100000009],[-79.95722999999992,72.40832500000005],[-79.87443499999995,72.47053499999998],[-79.870834,72.483047],[-79.86332699999997,72.48969999999997],[-79.8369449999999,72.49859600000008],[-79.82084700000001,72.50138900000007],[-79.79916400000002,72.50138900000007],[-79.78056299999997,72.49942000000004],[-79.77084400000001,72.49664300000012],[-79.73416099999992,72.484421],[-79.70056199999999,72.47248800000011],[-79.69221500000003,72.46693399999992],[-79.7686389999999,72.411766],[-79.68786599999999,72.3843920000001],[-79.59555099999994,72.33471700000013],[-79.63890100000003,72.289154],[-79.66805999999991,72.28082300000011],[-79.70556599999998,72.27360500000009],[-79.72000099999997,72.26944000000009],[-79.731674,72.26470899999998],[-79.75973499999992,72.25054900000009],[-79.76861600000001,72.2452550000001],[-79.77471899999989,72.23970000000003],[-79.775284,72.23332200000004],[-79.76972999999992,72.22581500000013],[-79.75,72.21554600000007],[-79.73277300000001,72.21220399999999],[-79.712784,72.21110499999998],[-79.70111099999997,72.21582000000001],[-79.56582599999996,72.2752690000001],[-79.48500100000001,72.32554599999997],[-79.35555999999991,72.39915500000001],[-79.34249899999998,72.40026899999998],[-79.32972699999999,72.39721700000007],[-79.24333199999995,72.37441999999999],[-79.18249500000002,72.3583220000001],[-79.14666699999998,72.3458250000001],[-79.11332700000003,72.33109999999999],[-79.08222999999992,72.313873],[-79.012787,72.27388000000013],[-78.94554099999993,72.199997],[-78.943604,72.193039],[-78.94694500000003,72.18691999999999],[-79.03639199999998,72.06944300000009],[-79.13612399999994,72.00749200000013],[-79.14500399999997,72.00248700000009],[-79.15666199999998,71.99775700000004],[-79.20638999999994,71.98664900000006],[-79.22999600000003,71.98027000000002],[-79.23306300000002,71.97637900000012],[-79.20306399999998,71.961929],[-79.19027699999998,71.95832800000011],[-79.17639200000002,71.95582600000006],[-79.16111799999993,71.95443700000004],[-79.13861099999991,71.95526100000001],[-79.12304699999993,71.9580380000001],[-79.09973099999996,71.96720900000008],[-79.09083599999985,71.97248800000006],[-79.07223499999992,71.97499099999999],[-79.06111099999993,71.97526600000003],[-79.02667199999996,71.9705350000001],[-78.81806899999998,71.93525700000009],[-78.76889,71.92692599999998],[-78.7225039999999,71.91886900000003],[-78.68388400000003,71.90971400000001],[-78.65306099999998,71.89387500000004],[-78.639725,71.88443000000001],[-78.62582399999985,71.8791500000001],[-78.585556,71.865814],[-78.57139599999988,71.86276200000003],[-78.55139200000002,71.86109899999997],[-78.52917499999995,71.861649],[-78.511124,71.86469999999997],[-78.50361599999997,71.86886600000008],[-78.5083469999999,71.876373],[-78.595551,71.93331899999998],[-78.60749800000002,71.93858300000011],[-78.62222299999996,71.94220000000007],[-78.69137599999999,71.94970700000005],[-78.74055499999997,71.9580380000001],[-78.85555999999985,71.97970600000002],[-78.914444,72.00776700000011],[-78.92361499999998,72.01499900000005],[-78.92443800000001,72.02053800000004],[-78.87748699999997,72.15332000000006],[-78.86944599999993,72.16665600000005],[-78.866104,72.1705320000001],[-78.85444599999994,72.17303500000008],[-78.843613,72.17109700000015],[-78.55444299999999,72.11137400000007],[-78.51222199999995,72.101089],[-78.48777799999993,72.09248400000013],[-78.47610500000002,72.0872040000001],[-78.46083099999993,72.07331800000009],[-78.43277,72.03804000000008],[-78.39527899999996,71.98248300000012],[-78.38999899999999,71.96943700000003],[-78.39277599999997,71.94999700000005],[-78.39167800000001,71.94358799999998],[-78.38667299999997,71.93331899999998],[-78.38194299999992,71.92804000000001],[-78.36527999999993,71.91748000000001],[-78.31777999999997,71.88832100000008],[-78.22666900000002,71.83305400000012],[-78.21083099999998,71.82582100000013],[-78.18499799999995,71.81749000000002],[-78.15760799999998,71.81057700000002],[-78.12304699999993,71.80636600000014],[-78.09056099999992,71.80081200000012],[-78.05972300000002,71.79414399999996],[-77.92443799999995,71.7647090000001],[-77.90777599999996,71.76638800000012],[-77.90444899999994,71.76805100000001],[-77.90695199999999,71.7705380000001],[-77.91416900000002,71.77360500000003],[-77.96665999999993,71.78665200000006],[-77.99749800000001,71.79332],[-78.02972399999993,71.79887400000001],[-78.08583099999998,71.81330900000012],[-78.10722399999992,71.81915300000014],[-78.13999899999993,71.83055100000013],[-78.178879,71.84860200000014],[-78.30888400000003,71.92109699999997],[-78.316666,71.92942800000009],[-78.321396,71.93692000000004],[-78.31500199999999,71.942474],[-78.3052669999999,71.94693000000012],[-78.27917500000001,71.95359800000011],[-78.258896,71.95665000000002],[-78.178879,71.96720900000008],[-78.15695199999993,71.96832300000005],[-78.14167799999996,71.96415700000011],[-78.01861600000001,71.89082300000013],[-77.974716,71.85998499999994],[-77.785553,71.78749099999999],[-77.80776999999995,71.82304400000004],[-77.96000699999996,71.88165300000009],[-78.09695399999998,71.96804800000001],[-78.10722399999992,71.97415200000006],[-78.11639399999996,71.97692899999998],[-78.14973399999997,71.980545],[-78.156387,71.980545],[-78.19610599999993,71.97859200000005],[-78.26222200000001,71.97276300000004],[-78.281387,71.97387700000002],[-78.29861499999998,71.97747800000008],[-78.32250999999991,71.98580900000002],[-78.33416699999992,71.99136400000009],[-78.34111000000001,71.99859600000002],[-78.34249899999992,72.01277199999998],[-78.34167499999995,72.01914999999997],[-78.34167499999995,72.03193699999997],[-78.35694899999993,72.05831900000004],[-78.37554899999998,72.08581500000008],[-78.38667299999997,72.09553499999998],[-78.40222199999994,72.10498000000007],[-78.42443799999995,72.11360200000007],[-78.436935,72.11747700000001],[-78.468887,72.12414600000011],[-78.51501499999995,72.13136300000002],[-78.59999099999999,72.145264],[-78.69665499999996,72.16360500000002],[-78.80999800000001,72.19720500000005],[-78.84249899999992,72.20915200000002],[-78.85472099999998,72.2144320000001],[-78.870834,72.22665400000005],[-78.86915599999992,72.22970600000002],[-78.73472599999997,72.32859800000011],[-78.61582900000002,72.35914600000007],[-78.604172,72.35942100000011],[-78.58056599999992,72.35415600000005],[-78.51583900000003,72.33055100000007],[-78.5125119999999,72.324432],[-78.51916499999999,72.31915300000003],[-78.52833599999991,72.313873],[-78.53332499999999,72.30914300000012],[-78.53694200000001,72.30331400000011],[-78.537781,72.25471500000015],[-78.53138699999994,72.24026500000002],[-78.52917499999995,72.23553500000003],[-78.52084399999995,72.22915599999999],[-78.42193599999996,72.1708220000001],[-78.40834000000001,72.16638200000011],[-78.39973399999997,72.16720600000008],[-78.39083900000003,72.16998299999995],[-78.386124,72.17248500000005],[-78.38417099999998,72.17553700000013],[-78.41111799999999,72.21666000000005],[-78.41471899999993,72.22053500000004],[-78.422775,72.224152],[-78.45973200000003,72.23387100000002],[-78.47277799999995,72.24247700000012],[-78.46833799999996,72.31498699999997],[-78.46278399999994,72.31887800000004],[-78.45111099999991,72.32415800000007],[-78.439438,72.32666],[-78.40834000000001,72.32582100000002],[-78.3052669999999,72.313309],[-78.01251200000002,72.2749940000001],[-77.89361599999995,72.25943000000001],[-77.82749899999999,72.24859600000013],[-77.79388399999999,72.24220299999996],[-77.66528299999987,72.20471200000003],[-77.65527299999997,72.20138500000007],[-77.64862099999999,72.19413799999995],[-77.644455,72.18664600000005],[-77.54083300000002,72.17692599999998],[-77.381104,72.18498200000005],[-77.32417299999986,72.18609600000002],[-77.289444,72.1833190000001],[-77.23998999999998,72.17442299999999],[-77.11582899999996,72.1483310000001],[-77.03944399999995,72.13165300000003],[-77.02333099999998,72.12886000000003],[-77.00611899999996,72.12747200000013],[-76.99722300000002,72.12803600000007],[-76.99583399999995,72.12886000000003],[-76.99471999999997,72.13053900000006],[-77.00500499999998,72.13443000000012],[-77.06861900000001,72.15220600000009],[-77.25167799999991,72.19331399999999],[-77.27806099999998,72.19693000000007],[-77.30694599999993,72.19802900000002],[-77.39723200000003,72.19274899999999],[-77.45584099999996,72.19081100000005],[-77.476944,72.19136000000015],[-77.51417500000002,72.19386299999996],[-77.54998799999998,72.19802900000002],[-77.578888,72.20416300000005],[-77.604172,72.21192900000011],[-77.62388599999991,72.22110000000009],[-77.658615,72.23165899999992],[-77.76083399999993,72.25721700000003],[-77.82305899999994,72.271927],[-77.866104,72.28109700000005],[-77.94999699999988,72.29609700000003],[-78.07250999999997,72.31248500000004],[-78.12138400000003,72.31971699999997],[-78.15472399999999,72.32554599999997],[-78.22000100000002,72.33776900000004],[-78.32695000000001,72.35914600000007],[-78.37388599999997,72.36943100000002],[-78.38917500000002,72.37303200000008],[-78.47332799999998,72.39498900000012],[-78.49916100000002,72.40470900000003],[-78.52084399999995,72.41499300000004],[-78.55915800000002,72.43803400000007],[-78.56111099999993,72.44497700000005],[-78.55665599999992,72.5044400000001],[-78.44305399999996,72.58193999999997],[-78.43055699999996,72.58665500000001],[-78.17027300000001,72.653595],[-78.156387,72.65693700000008],[-78.00167799999991,72.68248000000006],[-77.8699949999999,72.6974790000001],[-77.84500100000002,72.69886800000006],[-77.78083799999996,72.70694000000003],[-77.76861600000001,72.70942700000012],[-77.70140100000003,72.72470100000004],[-77.67027300000001,72.73220800000013],[-77.65695199999988,72.73609900000002],[-77.63999899999999,72.74386599999997],[-77.62748699999997,72.74859600000002],[-77.61389200000002,72.75166300000012],[-77.57640100000003,72.75555400000002],[-77.53222699999992,72.75694300000004],[-77.51362599999999,72.75471500000003],[-77.41305499999987,72.75221299999998],[-77.25973499999998,72.75166300000012],[-77.05581699999999,72.75286100000011],[-77.00250199999999,72.74941999999999],[-76.9472199999999,72.74386599999997],[-76.79972800000002,72.72747800000013],[-76.75306699999999,72.72053499999993],[-76.69305399999996,72.694702],[-76.6849979999999,72.69108599999993],[-76.6625059999999,72.67858899999999],[-76.65360999999996,72.67082199999999],[-76.65527299999997,72.66442900000004],[-76.65972899999997,72.65832499999999],[-76.646118,72.63970899999998],[-76.58473200000003,72.62858599999998],[-76.42832899999996,72.61415100000005],[-76.32833900000003,72.60748300000012],[-76.28832999999992,72.60498000000013],[-76.21528599999994,72.59610000000009],[-76.18221999999997,72.58998100000008],[-76.166946,72.58638000000002],[-76.15556299999992,72.580826],[-76.150284,72.57415800000001],[-76.15472399999993,72.56248500000004],[-76.16055299999994,72.54942299999999],[-76.16583300000002,72.53831500000001],[-76.16250600000001,72.526093],[-76.15611299999995,72.51805100000007],[-76.12165799999991,72.47831700000012],[-76.10777300000001,72.47303799999997],[-76.087784,72.47164899999996],[-76.069458,72.4749910000001],[-76.04638699999987,72.48359700000003],[-76.0369419999999,72.48942600000004],[-76.03778099999994,72.49636800000013],[-76.05221599999999,72.51138300000008],[-76.06861900000001,72.52581800000002],[-76.07722499999994,72.53637700000007],[-76.07417299999992,72.54165600000005],[-76.06471299999987,72.54998800000004],[-76.01889,72.57443199999994],[-76.00584399999997,72.57916300000011],[-75.98860199999996,72.580826],[-75.93194599999993,72.5836030000001],[-75.88528400000001,72.58415200000007],[-75.84194899999994,72.58305399999995],[-75.79888899999997,72.58193999999997],[-75.75917099999998,72.57916300000011],[-75.56806899999998,72.55747999999994],[-75.55332899999996,72.5535890000001],[-75.54722600000002,72.5455320000001],[-75.53778099999994,72.53970300000009],[-75.52111799999989,72.53610200000003],[-75.47222899999991,72.52748099999997],[-75.435272,72.52249100000006],[-75.37943999999993,72.51638800000012],[-75.36000100000001,72.51554899999996],[-75.30166600000001,72.50972000000013],[-75.231674,72.50054900000003],[-75.21528599999988,72.4974820000001],[-75.19249000000002,72.49192800000009],[-75.18666100000002,72.4874880000001],[-75.18916300000001,72.47831700000012],[-75.19915800000001,72.46693399999992],[-75.200287,72.46192900000005],[-75.16027799999995,72.42109700000009],[-75.13249200000001,72.3936000000001],[-75.054169,72.3288730000001],[-75.03416400000003,72.31749000000013],[-75,72.29836999999998],[-74.98055999999991,72.28831500000007],[-74.95083599999998,72.26998900000007],[-74.943604,72.26332100000008],[-74.94249000000002,72.25582900000012],[-74.94749499999995,72.2497100000001],[-75.04499799999996,72.18830899999995],[-75.06806899999992,72.17915299999999],[-75.225281,72.1224820000001],[-75.23832699999991,72.1183170000001],[-75.25306699999993,72.11637899999994],[-75.27166699999998,72.11720300000007],[-75.29138199999989,72.11943100000008],[-75.32362399999994,72.12553400000002],[-75.3875119999999,72.13443000000012],[-75.44055200000003,72.14109800000011],[-75.47778299999999,72.14471400000014],[-75.52000399999997,72.14610299999998],[-75.60749800000002,72.14332600000006],[-75.71000699999996,72.13665800000007],[-75.73332199999993,72.13415500000008],[-75.81388900000002,72.1224820000001],[-75.86665299999999,72.113876],[-76.015015,72.08665500000012],[-76.03332499999993,72.08110000000005],[-76.05471799999987,72.07304399999998],[-76.07806399999998,72.059418],[-76.08416699999992,72.04971300000011],[-76.09973100000002,72.02887000000004],[-76.11193800000001,72.01805099999996],[-76.12805200000003,72.00416600000005],[-76.14222699999993,71.99331699999999],[-76.15638699999988,71.98526000000004],[-76.17361499999998,71.97554000000014],[-76.19249000000002,71.967758],[-76.23472600000002,71.95748899999995],[-76.2625119999999,71.94970700000005],[-76.27444500000001,71.94442700000013],[-76.30166599999995,71.93054200000006],[-76.31834400000002,71.919983],[-76.34805299999988,71.891663],[-76.31082200000003,71.88472000000002],[-76.08972199999994,71.9788670000001],[-76.07305899999994,71.98942599999992],[-76.06332399999997,72],[-76.0497279999999,72.01776100000012],[-76.04750100000001,72.02360499999998],[-76.04360999999994,72.03027299999997],[-76.02944899999994,72.04109199999999],[-76.01972999999998,72.04609700000003],[-75.99861099999998,72.05415299999993],[-75.95611599999995,72.06721500000015],[-75.89445499999988,72.08221400000002],[-75.82833899999997,72.09693900000013],[-75.79666099999992,72.10359199999994],[-75.710556,72.11331200000001],[-75.63055400000002,72.11970500000001],[-75.58612099999999,72.12164300000012],[-75.52833599999997,72.12081899999998],[-75.48805199999993,72.11886600000003],[-75.43306000000001,72.11276199999998],[-75.23332199999993,72.08415200000013],[-75.22610500000002,72.08027600000008],[-75.21945199999988,72.07443200000006],[-75.218887,72.07026700000006],[-75.221115,72.06469699999997],[-75.22888199999994,72.059143],[-75.25527999999991,72.04609700000003],[-75.28167699999989,72.03858900000006],[-75.31750499999993,72.03166199999993],[-75.33833299999998,72.02887000000004],[-75.40417499999995,72.02554300000008],[-75.449432,72.02526899999998],[-75.49415599999998,72.02137800000008],[-75.515015,72.018326],[-75.54804999999999,72.01110799999998],[-75.57417299999992,72.00360100000006],[-75.58667000000003,71.99914600000005],[-75.60638399999993,71.98942599999992],[-75.61389200000002,71.98387100000002],[-75.61888099999999,71.97859200000005],[-75.68666100000002,71.88304099999999],[-75.697495,71.85832200000004],[-75.69137599999988,71.85026600000015],[-75.68804899999992,71.84275800000012],[-75.6875,71.83915700000006],[-75.69221500000003,71.83332800000005],[-75.80249000000003,71.75054899999998],[-75.83000199999998,71.73664900000011],[-75.8722229999999,71.72137500000002],[-75.89834599999995,71.71443200000004],[-75.93415799999997,71.71110500000009],[-75.95361299999996,71.7102660000001],[-75.9974979999999,71.70915200000013],[-76.04028299999993,71.70942699999995],[-76.06750499999987,71.70665000000008],[-76.07917799999996,71.7044370000001],[-76.09083599999991,71.70220899999998],[-76.096115,71.6974790000001],[-76.09583999999995,71.69386300000008],[-76.08528100000001,71.69192499999991],[-75.90167199999996,71.70109600000006],[-75.88027999999997,71.70248400000014],[-75.84695399999998,71.70860299999998],[-75.81945799999994,71.7169340000001],[-75.79499800000002,71.72581500000001],[-75.78721599999994,71.73054500000006],[-75.675003,71.81053200000002],[-75.65499899999998,71.82609600000012],[-75.58000199999987,71.90609700000005],[-75.57028199999996,71.91748000000001],[-75.56582599999996,71.92970300000007],[-75.56722999999994,71.93748500000004],[-75.57028199999996,71.94136000000003],[-75.57444799999996,71.95304899999996],[-75.57194499999997,71.95887800000014],[-75.56916799999999,71.96388200000013],[-75.558334,71.97665400000011],[-75.53860500000002,71.98637400000001],[-75.51333599999992,71.99525499999999],[-75.49804699999993,71.99914600000005],[-75.47666900000002,72.00082399999997],[-75.414444,71.99971],[-75.3719329999999,71.99775700000004],[-75.3494419999999,71.99803200000002],[-75.32778899999994,71.99941999999999],[-75.24888599999997,72.01277199999998],[-75.19776899999994,72.02331500000014],[-75.17443799999995,72.03193699999997],[-75.15861499999994,72.04165599999993],[-75.15028399999994,72.0577550000001],[-75.13500999999997,72.08055100000007],[-75.12999000000002,72.08638000000013],[-75.11915599999986,72.09637500000002],[-75.10916099999986,72.101089],[-75.093613,72.10803199999998],[-75.08138999999994,72.11303700000002],[-75.05139200000002,72.12191799999994],[-75.03582799999992,72.125809],[-75.01251199999996,72.12831100000011],[-75,72.12852500000002],[-74.98443599999996,72.12747200000013],[-74.95167500000002,72.12330600000007],[-74.83500699999996,72.10386699999998],[-74.80139199999996,72.09832799999998],[-74.76444999999995,72.09471100000002],[-74.65943900000002,72.09109499999994],[-74.62554899999992,72.09136999999998],[-74.535278,72.08970599999998],[-74.31639099999995,72.08221400000002],[-74.29722600000002,72.08082600000012],[-74.26000999999997,72.07609600000006],[-74.24415599999986,72.07304399999998],[-74.23332199999999,72.06748999999996],[-74.21806299999997,72.05802900000003],[-74.17748999999992,72.03193699999997],[-74.12222299999996,71.98359700000009],[-74.11776699999996,71.96998599999995],[-74.11944599999998,71.95582600000006],[-74.16610700000001,71.87469500000009],[-74.17111199999994,71.86859100000004],[-74.18499800000001,71.85581999999994],[-74.22999600000003,71.822769],[-74.24305699999996,71.818604],[-74.26333599999998,71.815811],[-74.40306099999992,71.80386400000009],[-74.43998699999986,71.80192599999992],[-74.460556,71.80276500000008],[-74.47778299999993,71.80497700000012],[-74.50140399999998,71.80970800000006],[-74.51362599999987,71.81805399999996],[-74.57055700000001,71.80941800000005],[-74.60499600000003,71.78471400000012],[-74.67832899999996,71.74525499999999],[-74.69610599999993,71.73858600000011],[-74.71362299999987,71.7352600000001],[-74.88500999999991,71.70860299999998],[-75,71.71191400000004],[-75.04666099999992,71.71609500000011],[-75.09056099999992,71.71804800000007],[-75.13667299999997,71.7169340000001],[-75.158051,71.71527100000014],[-75.34277299999991,71.69581599999998],[-75.36389200000002,71.69136000000009],[-75.37860099999995,71.68692000000004],[-75.38999899999999,71.68109100000004],[-75.39388999999994,71.67747500000002],[-75.391953,71.67469800000009],[-75.38500999999991,71.6744230000001],[-75.24194299999988,71.68609600000008],[-75.17832900000002,71.69413800000007],[-75.08500700000002,71.70082100000008],[-75.04361,71.69970700000005],[-75.02500899999995,71.69802900000013],[-75.00917099999992,71.69497700000005],[-74.941101,71.67469800000009],[-74.93415800000002,71.67082200000004],[-74.93360899999999,71.66387900000001],[-74.93638599999997,71.65803500000004],[-74.94554099999993,71.65248100000002],[-74.95611599999995,71.64833100000004],[-75.008896,71.63192700000008],[-75.05555700000002,71.62248199999999],[-75.11416600000001,71.61109899999997],[-75.19415299999997,71.5955350000001],[-75.206955,71.59193400000004],[-75.39834599999995,71.5252690000001],[-75.40972899999997,71.51971400000002],[-75.40833999999995,71.51470899999998],[-75.40638699999994,71.51220700000005],[-75.40222199999994,71.51249700000005],[-75.20527600000003,71.54637100000008],[-75,71.60723899999999],[-74.86111499999993,71.64942900000011],[-74.85166899999996,71.65498400000001],[-74.79943799999995,71.67886399999998],[-74.78416399999998,71.68275500000004],[-74.7183379999999,71.69358800000003],[-74.69776899999994,71.69636500000013],[-74.68666100000002,71.69636500000013],[-74.67277499999994,71.69247400000006],[-74.63194299999998,71.6624910000001],[-74.62971499999992,71.65277100000003],[-74.63194299999998,71.64637800000008],[-74.64639299999999,71.63192700000008],[-74.6744379999999,71.6083220000001],[-74.68971299999998,71.59803800000003],[-74.70472699999993,71.58804299999997],[-74.71305799999993,71.58387800000014],[-74.73388699999998,71.57554600000014],[-74.81193499999995,71.5477600000001],[-74.86972000000003,71.54165600000005],[-74.9225009999999,71.53776600000009],[-74.94027699999987,71.53804000000002],[-74.97084000000001,71.53720100000004],[-74.99027999999998,71.53665200000012],[-75,71.53558300000009],[-75.027222,71.532486],[-75.03666699999997,71.53054800000007],[-75.08138999999994,71.51527399999998],[-75.10777300000001,71.50305200000003],[-75.12470999999994,71.49247700000006],[-75.15194699999995,71.47164900000001],[-75.152222,71.466095],[-75.14611799999994,71.46360800000008],[-75.12777699999998,71.46582000000001],[-75.11555499999997,71.46998600000006],[-75.10611,71.48193400000008],[-75.09388699999994,71.49275200000011],[-75.08473199999997,71.49832200000014],[-75.06138599999997,71.50637800000004],[-75.05082699999997,71.50972000000002],[-75.03332499999993,71.51304600000003],[-75,71.51789900000011],[-74.99305699999991,71.51887500000004],[-74.94415300000003,71.52165200000013],[-74.87748699999997,71.52415500000012],[-74.85722399999997,71.52360500000009],[-74.83833299999992,71.52192699999995],[-74.82833899999997,71.51721199999992],[-74.71665999999999,71.41914400000013],[-74.69943199999994,71.39082300000007],[-74.70056199999993,71.38665800000007],[-74.70556599999998,71.38081400000004],[-74.71528599999999,71.375809],[-74.88833599999998,71.2872010000001],[-75.07501200000002,71.20443700000004],[-75.08138999999994,71.17942800000003],[-75.06500199999999,71.18081700000005],[-75,71.19934100000006],[-74.987503,71.2038730000001],[-74.87416099999996,71.24775699999998],[-74.86444099999994,71.25248700000003],[-74.67166099999997,71.35998500000005],[-74.65444899999994,71.37025499999999],[-74.63751199999996,71.380539],[-74.63221699999997,71.38581800000003],[-74.62805199999997,71.39248700000007],[-74.62582399999985,71.39888000000002],[-74.62609899999995,71.405823],[-74.631104,71.41943399999997],[-74.63806199999999,71.4266510000001],[-74.64695699999993,71.43304400000005],[-74.65722700000003,71.43858300000005],[-74.71972699999998,71.4624940000001],[-74.726944,71.466095],[-74.73554999999999,71.47248799999994],[-74.73638899999997,71.47665400000005],[-74.74305700000002,71.51193200000006],[-74.73611499999987,71.53054800000007],[-74.72389199999998,71.54193100000009],[-74.71417200000002,71.54664600000012],[-74.70167500000002,71.55108600000011],[-74.68638599999991,71.55497700000001],[-74.66389500000002,71.55720499999995],[-74.62887599999993,71.55470300000007],[-74.61999500000002,71.55802900000009],[-74.583618,71.58581500000003],[-74.57640100000003,71.5913700000001],[-74.54388399999999,71.63136299999996],[-74.38194299999992,71.67719999999997],[-74.34555099999994,71.68942300000003],[-74.335556,71.69413800000007],[-74.31777999999997,71.7044370000001],[-74.30943299999996,71.71220400000004],[-74.30694599999998,71.71775800000006],[-74.29943799999995,71.72387700000007],[-74.2886049999999,71.72747800000013],[-74.26834100000002,71.73027000000002],[-74.14695699999993,71.73887599999995],[-74.12470999999988,71.73887599999995],[-74.10916099999997,71.73580900000002],[-74.10305800000003,71.73332199999999],[-74.09777799999995,71.72886699999998],[-74.12388599999991,71.6808170000001],[-74.12887599999988,71.67164600000001],[-74.14222699999999,71.661652],[-74.15055799999999,71.65748600000006],[-74.17304999999999,71.65109300000012],[-74.202789,71.64582800000005],[-74.22027600000001,71.64166300000005],[-74.23277300000001,71.63749699999994],[-74.239441,71.63415500000002],[-74.24888599999997,71.62164300000006],[-74.25306699999999,71.611649],[-74.25445599999995,71.60664399999996],[-74.25473,71.6038670000001],[-74.252228,71.58998100000008],[-74.24916100000002,71.58248900000012],[-74.24305699999996,71.56971699999997],[-74.21888699999994,71.55664100000001],[-74.18028299999997,71.53831500000001],[-74.16833499999996,71.53332499999999],[-74.156387,71.53221100000002],[-74.15028399999989,71.53332499999999],[-74.14862099999993,71.53749100000005],[-74.15167199999996,71.544983],[-74.165009,71.55525200000005],[-74.146118,71.63749699999994],[-74.03971899999993,71.72221399999995],[-74.01916499999999,71.73803700000002],[-74.01472499999994,71.7410890000001],[-73.99694799999997,71.75138900000002],[-73.97778299999993,71.75972000000013],[-73.964447,71.76332100000002],[-73.92832900000002,71.76915000000002],[-73.74804699999993,71.77693199999999],[-73.71888699999994,71.77693199999999],[-73.61610399999995,71.77331500000003],[-73.604172,71.77221700000013],[-73.593887,71.76998899999995],[-73.589722,71.76332100000002],[-73.58999599999999,71.75694300000004],[-73.59167500000001,71.751938],[-73.598343,71.73831200000001],[-73.612503,71.72221399999995],[-73.61999500000002,71.71609500000011],[-73.63806199999999,71.70637500000004],[-73.66332999999992,71.697205],[-73.69444299999992,71.69026200000002],[-73.73277299999995,71.68386800000013],[-73.77111799999994,71.67082200000004],[-73.791382,71.66110200000014],[-73.89083900000003,71.60942100000005],[-73.98554999999999,71.53414900000013],[-73.99027999999993,71.52748099999997],[-74.01083399999999,71.49136399999998],[-74.09527599999996,71.46276899999998],[-74.16999799999996,71.44581600000004],[-74.303879,71.41943399999997],[-74.31582600000002,71.4144290000001],[-74.31916799999988,71.40942400000006],[-74.31221,71.40554800000001],[-74.29722600000002,71.405823],[-74.191666,71.42553700000013],[-74.15916399999992,71.4327550000001],[-74.12138400000003,71.43858300000005],[-74.08361799999994,71.44108600000004],[-74.04583699999995,71.440811],[-74.02861000000001,71.43775900000009],[-74.06388900000002,71.33692900000005],[-74.09167500000001,71.28553799999997],[-74.10638399999988,71.2747040000001],[-74.137787,71.25582899999995],[-74.152222,71.24803200000002],[-74.18777499999993,71.22943099999998],[-74.20750399999986,71.21971100000007],[-74.21722399999993,71.21499600000004],[-74.22666900000002,71.21220399999999],[-74.23832700000003,71.2038730000001],[-74.24082900000002,71.20082100000013],[-74.2350009999999,71.19831799999997],[-74.22888199999994,71.19941699999998],[-74.21777299999997,71.20220900000004],[-74.19082599999996,71.21110499999998],[-74.15833999999995,71.22387700000002],[-74.148056,71.22859200000005],[-74.11833200000001,71.24331699999999],[-74.039444,71.30219999999997],[-74.00944499999997,71.36080900000002],[-74.006958,71.36720300000007],[-73.97332799999992,71.41360500000013],[-73.96861299999989,71.41943399999997],[-73.86776700000001,71.52581800000002],[-73.86221299999994,71.53109699999999],[-73.76167299999997,71.58082600000006],[-73.74694799999997,71.58526600000005],[-73.73277299999995,71.586929],[-73.68916299999995,71.58804299999997],[-73.65361000000001,71.58749399999999],[-73.63972499999994,71.58638000000002],[-73.62193299999996,71.58332800000011],[-73.59500099999997,71.57527200000004],[-73.58860800000002,71.57222000000013],[-73.56500199999994,71.55192599999998],[-73.56666599999994,71.54414400000002],[-73.598343,71.52832000000012],[-73.61555499999992,71.52026400000005],[-73.61944599999998,71.51582300000013],[-73.63027999999997,71.45664999999991],[-73.63500999999991,71.35942100000011],[-73.62249800000001,71.35664400000002],[-73.61332699999997,71.35582000000005],[-73.59472700000003,71.35775799999999],[-73.54038999999995,71.37286400000005],[-73.51888999999994,71.37915000000004],[-73.51722699999993,71.379974],[-73.51611299999996,71.38581800000003],[-73.51556399999993,71.39888000000002],[-73.51333599999998,71.41304000000014],[-73.50306699999993,71.42469800000015],[-73.49694799999992,71.42858900000004],[-73.47749299999992,71.43637100000001],[-73.44694500000003,71.44026200000008],[-73.428879,71.43580600000013],[-73.38444500000003,71.39193700000004],[-73.38027999999991,71.38526900000005],[-73.38500999999997,71.38192700000013],[-73.50089999999994,71.33721200000002],[-73.59028599999994,71.30497700000006],[-73.61555499999992,71.29637100000014],[-73.62304699999987,71.29109199999999],[-73.63555899999994,71.27970900000014],[-73.66305499999999,71.25416600000005],[-73.678879,71.23803700000008],[-73.712784,71.17776500000014],[-73.71777299999997,71.1649930000001],[-73.71888699999994,71.15942400000012],[-73.71639999999996,71.14498900000001],[-73.71362299999998,71.13749700000005],[-73.71362299999998,71.13053900000006],[-73.71665999999999,71.1183170000001],[-73.72860699999995,71.09860200000008],[-73.73582499999998,71.09332300000011],[-73.74583399999989,71.08859300000012],[-73.76083399999993,71.08471700000001],[-73.77806099999998,71.0816650000001],[-73.79777499999994,71.07887299999999],[-73.84249899999992,71.07443200000012],[-73.87388599999997,71.06971700000008],[-73.890289,71.06498700000003],[-73.898346,71.05748000000011],[-73.89500399999997,71.05220000000003],[-73.88667299999997,71.049149],[-73.87943999999987,71.04775999999998],[-73.872772,71.047485],[-73.85055499999999,71.05998199999999],[-73.84222399999999,71.06414800000005],[-73.75306699999999,71.065811],[-73.73277299999995,71.06776400000012],[-73.71583599999985,71.07165500000002],[-73.69276400000001,71.07943699999998],[-73.67443800000001,71.08831800000007],[-73.66722099999998,71.09359700000005],[-73.660553,71.10386699999998],[-73.65833999999995,71.1249850000001],[-73.66250599999995,71.134995],[-73.66665599999988,71.141663],[-73.67361499999993,71.16303999999997],[-73.66888399999999,71.17303500000008],[-73.62361099999998,71.22554000000014],[-73.61582900000002,71.23027000000013],[-73.54916400000002,71.26998900000007],[-73.45472699999999,71.30026200000003],[-73.43388400000003,71.30859400000003],[-73.42860399999995,71.31442300000003],[-73.42777999999998,71.32720899999993],[-73.43527199999994,71.33221400000002],[-73.43777499999999,71.33638000000008],[-73.43611099999998,71.34054599999996],[-73.43028299999997,71.34165999999999],[-73.38221699999997,71.345261],[-73.36305199999998,71.34582499999999],[-73.34973099999996,71.345261],[-73.32084700000001,71.34082000000012],[-73.08361799999994,71.28581200000008],[-73.06111099999998,71.27748100000002],[-73.04943799999995,71.26832599999994],[-73.05387899999994,71.26165800000001],[-73.06500199999994,71.25833100000006],[-73.15556299999997,71.246643],[-73.214722,71.240814],[-73.23083500000001,71.23831200000012],[-73.24943499999995,71.23387100000002],[-73.26611300000002,71.22499099999999],[-73.27194199999985,71.22053500000004],[-73.26306199999999,71.205826],[-73.25250199999994,71.1952510000001],[-73.24444599999998,71.18887300000011],[-73.23500100000001,71.17330900000002],[-73.23500100000001,71.16220100000004],[-73.23832700000003,71.15721099999996],[-73.247772,71.14415000000002],[-73.25695799999988,71.13388100000003],[-73.29444899999993,71.09248399999996],[-73.31111099999993,71.08082600000012],[-73.327789,71.072769],[-73.37943999999999,71.05831900000004],[-73.42639199999991,71.04775999999998],[-73.44610599999999,71.04109200000005],[-73.45083599999992,71.03526300000004],[-73.45195000000001,71.02943399999998],[-73.44694500000003,71.02499399999999],[-73.37748699999992,70.980545],[-73.36999500000002,70.98580900000002],[-73.17361499999987,71.15693700000003],[-73.16861,71.1705320000001],[-73.17749000000003,71.18525700000004],[-73.18306000000001,71.19136000000003],[-73.18804899999998,71.19914199999994],[-73.185272,71.205826],[-73.18028300000003,71.21165500000001],[-73.17222600000002,71.21638500000006],[-73.14222699999993,71.22442599999994],[-73.11555499999992,71.23027000000013],[-73.10139500000002,71.23165899999998],[-73.07972699999999,71.23165899999998],[-73.06777999999986,71.23027000000013],[-73.04554699999989,71.22554000000014],[-73.02722199999988,71.22720300000003],[-73.01194799999996,71.23442100000005],[-73.00445599999995,71.23970000000003],[-72.99499499999996,71.24999999999994],[-72.98167399999994,71.26748700000002],[-72.952789,71.31109600000008],[-72.95140099999998,71.31608599999998],[-72.95973199999997,71.35582000000005],[-72.96362299999993,71.36248800000004],[-72.97000100000002,71.36998],[-72.9783329999999,71.37637300000011],[-72.989441,71.39166300000011],[-72.99305700000002,71.39776600000005],[-72.99333199999995,71.40193199999993],[-72.98889200000002,71.40554800000001],[-72.97582999999992,71.40914900000007],[-72.89723200000003,71.41665599999999],[-72.85804699999994,71.41331500000013],[-72.83639499999992,71.41331500000013],[-72.76583900000003,71.42387400000001],[-72.75917099999992,71.4269260000001],[-72.75750700000003,71.43193100000013],[-72.758621,71.43748499999998],[-72.76472499999994,71.45166000000006],[-72.76916499999993,71.45915200000002],[-72.67999299999991,71.52470400000004],[-72.64973399999997,71.53692600000005],[-72.61860699999994,71.55941800000011],[-72.61332699999997,71.56553600000007],[-72.61027499999989,71.57193000000012],[-72.608337,71.58387800000014],[-72.61082499999992,71.5955350000001],[-72.608337,71.60664399999996],[-72.593887,71.64248700000002],[-72.58332799999988,71.65138200000007],[-72.58029199999993,71.653595],[-72.57333399999993,71.65664700000013],[-72.55749500000002,71.66026299999999],[-72.53805499999993,71.66081200000013],[-72.52362099999999,71.65887500000008],[-72.50306699999987,71.65026899999998],[-72.47471599999994,71.64276100000012],[-72.44444299999998,71.63610799999998],[-72.30110200000001,71.61219800000015],[-72.15222199999994,71.58998100000008],[-71.84777799999995,71.54664600000012],[-71.689438,71.52442900000005],[-71.670547,71.52221699999996],[-71.635559,71.51776100000006],[-71.58555599999994,71.509995],[-71.554169,71.50387599999999],[-71.45527599999991,71.47303799999997],[-71.44444299999992,71.46859700000005],[-71.435272,71.46360800000008],[-71.29554699999994,71.38472000000013],[-71.241379,71.349426],[-71.12332200000003,71.27165200000002],[-71.11971999999997,71.26416000000006],[-71.122772,71.25721700000008],[-71.128601,71.25138900000013],[-71.14778099999995,71.24192799999997],[-71.16944899999999,71.23332200000004],[-71.20611600000001,71.22053500000004],[-71.22138999999999,71.21693400000004],[-71.23472600000002,71.21276900000004],[-71.32472200000001,71.17776500000014],[-71.34056099999987,71.1705320000001],[-71.34277299999991,71.16638200000011],[-71.34611499999994,71.15582300000005],[-71.3494419999999,71.149429],[-71.4158329999999,71.09332300000011],[-71.452225,71.06805400000013],[-71.46444699999995,71.06248499999998],[-71.47027599999996,71.06137099999995],[-71.48971599999993,71.0619200000001],[-71.55110200000001,71.06469700000002],[-71.60833699999995,71.068604],[-71.64083900000003,71.07388300000014],[-71.714447,71.08804300000008],[-71.81249999999994,71.1041560000001],[-71.84889199999992,71.10832199999999],[-71.86888099999987,71.109421],[-71.89028899999988,71.109421],[-71.91082799999992,71.10775800000005],[-72.069458,71.07527199999998],[-72.08555599999994,71.07026700000011],[-72.09973100000002,71.06387300000006],[-72.110275,71.05220000000003],[-72.11389200000002,71.04721100000006],[-72.114441,71.0435940000001],[-72.11332699999991,71.03749099999999],[-72.10722399999997,71.03027299999997],[-72.09973100000002,71.02026399999994],[-72.101944,71.01609800000006],[-72.16555799999992,70.96804800000007],[-72.17971799999992,70.96220400000004],[-72.20028699999995,70.96110500000003],[-72.23500100000001,70.961929],[-72.261124,70.95915200000013],[-72.27806099999998,70.95526100000006],[-72.29055799999998,70.95109600000006],[-72.29722600000002,70.947205],[-72.31750499999998,70.93026700000007],[-72.319458,70.92581200000006],[-72.31750499999998,70.91832000000011],[-72.31138599999997,70.91110200000008],[-72.31388900000002,70.89971900000006],[-72.32055700000001,70.88832100000008],[-72.32556199999988,70.88247700000005],[-72.33416699999998,70.87858599999998],[-72.514725,70.84443699999997],[-72.5344389999999,70.84193399999998],[-72.65360999999996,70.82777400000009],[-72.6541749999999,70.82083100000011],[-72.51139799999987,70.82720900000004],[-72.476944,70.83332800000005],[-72.40110800000002,70.84971600000011],[-72.35611,70.86053500000003],[-72.30277999999993,70.86720300000002],[-72.26417500000002,70.86665299999999],[-72.25,70.86387600000006],[-72.18472299999996,70.84471100000007],[-72.17222599999997,70.84054600000007],[-72.16361999999998,70.83638000000002],[-72.16221599999989,70.82998700000002],[-72.36332700000003,70.68609600000013],[-72.38194299999998,70.67720000000003],[-72.45944199999997,70.65387000000004],[-72.47582999999992,70.64942900000011],[-72.499435,70.64665200000002],[-72.54249600000003,70.64471400000008],[-72.57806399999998,70.64137300000004],[-72.597778,70.63859599999995],[-72.60916099999997,70.63665800000001],[-72.61582899999996,70.63333100000006],[-72.62332199999997,70.62803600000001],[-72.56945799999988,70.60998500000005],[-72.55166600000001,70.6080320000001],[-72.50306699999987,70.62997399999995],[-72.49055499999997,70.63415500000002],[-72.37193299999996,70.65498400000001],[-72.34222399999993,70.66220099999992],[-72.32611099999991,70.66720600000002],[-72.30638099999999,70.67747500000002],[-72.27749599999987,70.69802899999996],[-72.26472499999994,70.70915199999996],[-72.24861099999998,70.726654],[-72.245834,70.733047],[-72.2369379999999,70.74386600000003],[-72.229172,70.74942000000004],[-72.210556,70.75804099999993],[-72.18554699999993,70.76638800000012],[-72.15583800000002,70.77360500000003],[-72.136124,70.776093],[-72.00473,70.786926],[-71.89695699999993,70.80693100000002],[-71.818893,70.82304400000004],[-71.68916300000001,70.85026600000015],[-71.54388399999999,70.87248199999999],[-71.35444599999994,70.88275099999998],[-71.28750600000001,70.90609700000005],[-71.28916900000002,70.90887500000002],[-71.289444,70.91360500000008],[-71.20834399999995,71.00499000000008],[-71.18554699999987,71.01943999999997],[-71.162216,71.02832000000001],[-70.89555399999995,71.09971600000006],[-70.83612099999993,71.11442600000004],[-70.79972799999996,71.11886600000003],[-70.77166699999998,71.11804200000006],[-70.75556899999992,71.11554000000001],[-70.72471599999994,71.10443099999992],[-70.635559,71.07222000000002],[-70.61389199999996,71.06219499999992],[-70.60472099999993,71.05636600000008],[-70.60166900000002,71.05386400000003],[-70.591949,71.04248000000013],[-70.51472499999994,70.94053600000007],[-70.51251199999996,70.926086],[-70.51445000000001,70.92109700000003],[-70.51972999999998,70.91387900000001],[-70.553604,70.89498900000007],[-70.58944699999995,70.87608300000005],[-70.678879,70.84054600000007],[-70.7408289999999,70.75471500000009],[-70.74694799999992,70.74552900000015],[-70.77333099999998,70.734421],[-70.79888899999992,70.72554000000002],[-70.87249800000001,70.70387299999999],[-70.89111299999996,70.69886800000012],[-70.96583599999997,70.684143],[-71.02444500000001,70.67498799999993],[-71.05526700000001,70.66914400000013],[-71.08277899999996,70.661652],[-71.10055499999993,70.65498400000001],[-71.108612,70.64999399999999],[-71.11805699999996,70.63888500000007],[-71.12805199999997,70.62052900000009],[-71.12943999999999,70.6141510000001],[-71.13444500000003,70.60276799999991],[-71.13999899999993,70.59637499999997],[-71.14778099999995,70.59109500000011],[-71.16027799999995,70.586929],[-71.17527799999999,70.58360299999998],[-71.191666,70.58248900000001],[-71.22471599999994,70.58221400000014],[-71.28167699999989,70.58415200000007],[-71.31249999999994,70.58720400000004],[-71.34584000000001,70.5916600000001],[-71.38972499999994,70.60054000000014],[-71.40750100000002,70.60304300000013],[-71.422775,70.60498000000001],[-71.46194499999996,70.60775799999999],[-71.55860899999993,70.60942100000011],[-71.59277299999997,70.60693400000002],[-71.59555099999994,70.6038670000001],[-71.59583999999995,70.60054000000014],[-71.59249899999992,70.58970600000009],[-71.58667000000003,70.58166500000004],[-71.58389299999993,70.576096],[-71.58029199999999,70.56469700000014],[-71.581955,70.551376],[-71.583618,70.54637100000014],[-71.58805799999993,70.54275500000006],[-71.74360699999994,70.46693399999998],[-71.80305499999997,70.42831400000006],[-71.76306199999993,70.42720000000008],[-71.74804699999999,70.42581199999995],[-71.73638900000003,70.42303500000008],[-71.72721899999999,70.41747999999995],[-71.72805800000003,70.41053800000009],[-71.731674,70.39721700000013],[-71.74638400000003,70.3477630000001],[-71.75556899999998,70.329163],[-71.76306199999993,70.32331800000009],[-71.78306599999996,70.313873],[-71.81666599999994,70.30304000000007],[-71.84416199999998,70.29664600000001],[-71.8497309999999,70.290817],[-71.83694499999996,70.28997800000002],[-71.80694599999987,70.29582200000004],[-71.74804699999999,70.309708],[-71.73361199999994,70.313873],[-71.68638599999991,70.35582000000011],[-71.674713,70.36970500000001],[-71.64167800000001,70.44497700000011],[-71.640289,70.45054600000009],[-71.54333500000001,70.51470899999998],[-71.52528399999994,70.5247040000001],[-71.51000999999997,70.53581200000008],[-71.50250199999994,70.54609699999997],[-71.50167799999997,70.55304000000001],[-71.50334199999998,70.56053199999991],[-71.50750699999998,70.56915300000003],[-71.51167299999997,70.57331800000003],[-71.50695799999994,70.57638500000013],[-71.49554399999994,70.5788730000001],[-71.435272,70.57859800000011],[-71.42027300000001,70.57748400000014],[-71.39778100000001,70.574432],[-71.25306699999993,70.54971300000005],[-71.18499800000001,70.53804000000002],[-71.17582699999997,70.53581200000008],[-71.17027299999995,70.53332499999999],[-71.1677699999999,70.53193700000008],[-71.16250600000001,70.5252690000001],[-71.162216,70.52053799999999],[-71.26055899999989,70.37776200000013],[-71.32250999999997,70.31275900000003],[-71.32167099999998,70.30664100000007],[-71.31834399999997,70.2999880000001],[-71.30110199999996,70.284988],[-71.28889499999997,70.280823],[-71.27999899999998,70.27499399999994],[-71.276947,70.268326],[-71.27833599999985,70.26277199999998],[-71.285278,70.25138899999996],[-71.28916900000002,70.24609400000008],[-71.31695599999995,70.21859699999999],[-71.36305199999987,70.18220499999995],[-71.43472300000002,70.12692300000003],[-71.485275,70.08831800000007],[-71.49804699999993,70.08055100000013],[-71.523056,70.05220000000003],[-71.53277600000001,70.03858900000006],[-71.53916899999996,70.02638200000013],[-71.54110700000001,70.02221700000013],[-71.53582799999992,70.01971400000014],[-71.52806099999998,70.020264],[-71.51806599999998,70.02499399999999],[-71.50029,70.03831500000013],[-71.493607,70.05053700000013],[-71.47582999999997,70.06805400000013],[-71.43804899999998,70.08665500000001],[-71.39361600000001,70.10443099999998],[-71.36665299999999,70.1119230000001],[-71.33168,70.12858599999998],[-71.210556,70.26220699999993],[-71.20889299999999,70.26776100000012],[-71.21305799999999,70.272491],[-71.218887,70.27638200000007],[-71.22972099999998,70.2810970000001],[-71.23194899999993,70.29498300000006],[-71.17166099999997,70.36804200000006],[-71.13583399999993,70.41053800000009],[-71.09306299999997,70.46054100000003],[-71.03056300000003,70.54054300000001],[-71.04998799999993,70.54637100000014],[-71.05305499999997,70.55304000000001],[-71.04943800000001,70.55886800000007],[-71.00584399999997,70.61692800000003],[-70.99722299999996,70.62580899999995],[-70.968887,70.63220200000012],[-70.91305499999999,70.63777199999998],[-70.77111799999994,70.66886900000009],[-70.61193799999995,70.72360200000008],[-70.42166099999986,70.77221700000013],[-70.39695699999999,70.77832000000006],[-70.36527999999993,70.782486],[-70.32472199999995,70.78581200000002],[-70.25500499999998,70.79386899999997],[-70.22888199999994,70.79721100000012],[-70.07501200000002,70.83027600000014],[-69.98805199999998,70.85359200000005],[-69.91583300000002,70.87747200000001],[-69.90472399999993,70.88136300000008],[-69.89277599999991,70.88333100000006],[-69.87388599999997,70.88333100000006],[-69.86527999999993,70.88247700000005],[-69.833618,70.87692300000009],[-69.78443900000002,70.86470000000003],[-69.77111799999994,70.85748300000012],[-69.770554,70.8560940000001],[-69.77250699999996,70.85054000000008],[-69.795837,70.82054100000005],[-69.80888400000003,70.81109600000002],[-69.87943999999993,70.76805100000007],[-69.91555799999992,70.74914600000011],[-69.96528599999994,70.72776799999997],[-70.07389799999993,70.68748499999992],[-70.08473200000003,70.68359400000003],[-70.12165800000002,70.67164600000001],[-70.21055599999994,70.6461030000001],[-70.22555499999993,70.64193699999998],[-70.24499500000002,70.63832100000013],[-70.277222,70.63610799999998],[-70.33805799999999,70.637497],[-70.35333299999996,70.63888500000007],[-70.40777599999996,70.63888500000007],[-70.42332499999998,70.63693200000012],[-70.45472699999999,70.62776200000008],[-70.473053,70.61720300000002],[-70.47694399999995,70.61219799999998],[-70.478882,70.60664400000002],[-70.460556,70.57415800000007],[-70.44276400000001,70.56192000000004],[-70.42416400000002,70.55192600000004],[-70.41139199999998,70.54220599999991],[-70.40472399999993,70.53637700000007],[-70.400284,70.53027300000008],[-70.39750700000002,70.52415500000012],[-70.40167200000002,70.51915000000008],[-70.40777599999996,70.51416],[-70.42332499999998,70.50694300000009],[-70.46722399999999,70.49386600000008],[-70.48222399999992,70.49054000000007],[-70.49082900000002,70.486649],[-70.49444599999998,70.484985],[-70.49610899999999,70.47943099999998],[-70.48889200000002,70.4769290000001],[-70.47778299999999,70.47554000000008],[-70.45916699999998,70.47554000000008],[-70.44137599999993,70.47720300000003],[-70.30972299999996,70.49803199999997],[-70.316666,70.52859499999994],[-70.32000700000003,70.53692600000005],[-70.33167999999995,70.54859900000008],[-70.34861799999993,70.55970799999994],[-70.37110899999993,70.57360800000004],[-70.34445199999993,70.61303700000013],[-70.15833999999995,70.61554000000012],[-70.09249899999998,70.61219799999998],[-70.02333099999998,70.61053500000008],[-69.99221799999998,70.64582800000005],[-69.98777799999993,70.64999399999999],[-69.97860700000001,70.65332000000001],[-69.87582399999991,70.67720000000003],[-69.77583299999998,70.68220500000007],[-69.65139799999997,70.72554000000002],[-69.64916999999991,70.73109400000004],[-69.64472999999998,70.74108899999993],[-69.63861099999997,70.74693300000013],[-69.61999500000002,70.75804099999993],[-69.56916799999993,70.77192700000012],[-69.53832999999986,70.77859500000011],[-69.46972700000003,70.79054300000013],[-69.45140100000003,70.79193100000003],[-69.24276699999996,70.782486],[-69.22694399999995,70.77998400000007],[-69.215012,70.776093],[-69.19055200000003,70.76693700000004],[-69.13194299999998,70.7374880000001],[-68.95805399999995,70.688583],[-68.92832900000002,70.68165600000009],[-68.664444,70.62692300000015],[-68.61860699999994,70.62052900000009],[-68.58250399999997,70.617752],[-68.54972799999996,70.61360200000001],[-68.515289,70.60914600000007],[-68.48472600000002,70.60415600000005],[-68.39056399999998,70.58221400000014],[-68.32556199999993,70.56666599999994],[-68.31388900000002,70.56303400000002],[-68.29361,70.551376],[-68.28416400000003,70.54054300000001],[-68.27917499999995,70.53109700000005],[-68.279449,70.51944000000009],[-68.28138699999994,70.51249700000011],[-68.28971899999999,70.50000000000011],[-68.296112,70.49414100000013],[-68.31361400000003,70.48471100000006],[-68.33168,70.47637900000007],[-68.37193299999996,70.455826],[-68.44665499999996,70.41304000000014],[-68.45140099999998,70.40942400000012],[-68.45361300000002,70.4038700000001],[-68.45195000000001,70.39221200000009],[-68.44915800000001,70.38415500000008],[-68.44860799999998,70.37525900000014],[-68.45167500000002,70.37248200000005],[-68.458618,70.36943100000008],[-68.48500099999995,70.36775200000005],[-68.49527,70.36859099999998],[-68.506393,70.37109399999997],[-68.519455,70.37414600000011],[-68.56138599999991,70.3897090000001],[-68.571121,70.39332600000006],[-68.57583599999992,70.39610299999998],[-68.58084099999996,70.4041600000001],[-68.58056599999998,70.41581700000006],[-68.56973299999999,70.42637600000012],[-68.556107,70.43525700000004],[-68.54998799999998,70.44081100000005],[-68.54804999999993,70.44775400000003],[-68.55694599999998,70.46192900000011],[-68.56471299999993,70.46638500000006],[-68.58250399999997,70.4644320000001],[-68.62165799999997,70.45277400000009],[-68.65083300000003,70.44192500000003],[-68.6541749999999,70.4391480000001],[-68.66166699999991,70.43109099999992],[-68.66665599999999,70.42221100000012],[-68.67027300000001,70.40887499999997],[-68.67083699999995,70.4041600000001],[-68.664444,70.38499499999995],[-68.65722699999998,70.375809],[-68.651947,70.35942099999994],[-68.65055799999993,70.34999100000005],[-68.65110799999997,70.34582499999999],[-68.65388499999995,70.34136999999998],[-68.65695199999999,70.33859300000006],[-68.66416900000002,70.33554100000015],[-68.68249500000002,70.3294370000001],[-68.73554999999988,70.31776400000007],[-68.78416400000003,70.31025699999998],[-68.90695199999993,70.29386900000009],[-68.94137599999999,70.29304500000012],[-69.07194500000003,70.28804000000008],[-69.23500100000001,70.27026400000011],[-69.28388999999999,70.26470900000004],[-69.47389199999998,70.23887600000006],[-69.63999899999988,70.20471200000009],[-69.66805999999997,70.19859300000002],[-69.82389799999999,70.15582300000011],[-69.829453,70.15415999999999],[-69.83612099999999,70.15054300000003],[-69.83972199999994,70.14415000000008],[-69.84083599999991,70.1419370000001],[-69.83972199999994,70.13443000000001],[-69.84306299999997,70.121918],[-69.84889199999998,70.11608899999999],[-69.85694899999993,70.11080900000007],[-69.87582399999991,70.10192900000004],[-69.91776999999996,70.08554100000003],[-69.94665500000002,70.07638500000007],[-69.96833799999996,70.07470699999993],[-69.99027999999993,70.07443200000012],[-70.037781,70.07222000000007],[-70.073059,70.06915300000014],[-70.08612099999999,70.06666600000005],[-70.09695399999998,70.06330900000012],[-70.14138799999995,70.04332],[-70.17443800000001,70.034988],[-70.18276999999989,70.03109699999993],[-70.18554699999999,70.02804600000013],[-70.18276999999989,70.02137800000014],[-70.16999799999996,70.01443499999999],[-70.15449499999994,70.0151600000001],[-70.14750699999996,70.01548800000006],[-70.13950299999993,70.0171590000001],[-70.11332700000003,70.02388000000002],[-70.10305800000003,70.02859500000005],[-70.08999599999999,70.03610200000003],[-70.08889799999992,70.03831500000013],[-70.07749899999999,70.049713],[-70.06695599999995,70.05358900000004],[-70.04998799999987,70.05720500000007],[-70.02861000000001,70.05886800000002],[-70.02027900000002,70.05859400000008],[-69.90110799999997,70.04832500000003],[-69.89222699999993,70.0458220000001],[-69.88473499999992,70.042755],[-69.85360700000001,70.02970900000003],[-69.83555599999994,70.020264],[-69.82749899999999,70.01443499999999],[-69.82084699999996,70.0080410000001],[-69.81304899999992,69.99859600000002],[-69.81221,69.9910890000001],[-69.81555200000003,69.98471100000012],[-69.82250999999991,69.98165900000004],[-69.83750899999995,69.97831700000012],[-69.85139500000002,69.97831700000012],[-69.89750700000002,69.98304700000011],[-69.93638599999997,69.98942599999998],[-69.96333299999998,69.99165300000004],[-69.98138399999999,69.99165300000004],[-70.00306699999993,69.98970000000008],[-70.0574949999999,69.98109399999998],[-70.09889199999992,69.97360200000008],[-70.16444399999989,69.96165500000012],[-70.21888699999994,69.9416500000001],[-70.22332799999998,69.93803400000002],[-70.22389199999998,69.92970300000013],[-70.21806299999997,69.92526200000003],[-70.21611000000001,69.92053199999998],[-70.22027600000001,69.91554300000001],[-70.22860700000001,69.91165199999995],[-70.291382,69.8894350000001],[-70.38417099999998,69.86053500000003],[-70.40139799999997,69.85914600000007],[-70.42222599999997,69.86080900000013],[-70.43249500000002,69.86248799999998],[-70.44387799999993,69.86053500000003],[-70.45056199999999,69.85720800000007],[-70.46722399999999,69.84471100000013],[-70.46861299999995,69.842758],[-70.46028099999995,69.8416600000001],[-70.436935,69.83943199999993],[-70.41221599999994,69.83776900000004],[-70.396118,69.83720399999999],[-70.38417099999998,69.83720399999999],[-70.37277199999988,69.83831800000013],[-70.35583499999996,69.8413700000001],[-70.343613,69.84526099999994],[-70.25527999999991,69.87914999999998],[-70.19276400000001,69.90776100000011],[-70.13694800000002,69.93331899999998],[-70.12609899999995,69.94053600000012],[-70.09861799999999,69.95304900000002],[-70.07667500000002,69.95803799999999],[-70.05943300000001,69.95971699999996],[-69.97860700000001,69.964157],[-69.94193999999999,69.96304300000003],[-69.925003,69.96110500000009],[-69.89695699999999,69.95610000000005],[-69.86805700000002,69.95332300000013],[-69.83750899999995,69.95277399999998],[-69.81311,69.9554290000001],[-69.777222,69.96360800000002],[-69.75083899999993,69.97248800000006],[-69.74554399999994,69.97470100000004],[-69.73805199999993,69.98136900000003],[-69.73554999999993,69.98553500000008],[-69.735275,69.99053999999995],[-69.739441,70.00138900000002],[-69.74415599999998,70.0080410000001],[-69.76000999999997,70.01748700000007],[-69.76945499999994,70.02137800000014],[-69.78111299999995,70.02499399999999],[-69.795547,70.03166199999998],[-69.80471799999987,70.03887900000007],[-69.80888400000003,70.049713],[-69.80694599999998,70.055252],[-69.79277000000002,70.080826],[-69.79028299999993,70.084991],[-69.78388999999999,70.0894320000001],[-69.74082900000002,70.11415100000005],[-69.67582699999991,70.13970899999998],[-69.65333599999991,70.14498900000001],[-69.42610199999996,70.17608600000011],[-69.40417500000001,70.17776500000014],[-69.21945199999999,70.188309],[-69.18249499999996,70.18719500000003],[-69.16999799999991,70.18609600000002],[-69.15472399999999,70.18331899999998],[-69.011124,70.17831400000011],[-68.93693499999995,70.19303900000006],[-68.85916099999986,70.20304899999996],[-68.83917200000002,70.20359800000006],[-68.69722000000002,70.2038730000001],[-68.68277,70.20359800000006],[-68.67832900000002,70.20248400000008],[-68.67639199999996,70.20166000000012],[-68.64750700000002,70.15832499999999],[-68.64250199999998,70.14942900000005],[-68.64500399999991,70.14526400000005],[-68.741379,70.06526200000008],[-68.74665800000002,70.06248499999998],[-68.78306600000002,70.04443399999997],[-68.80055199999998,70.03749099999999],[-68.81332399999997,70.032761],[-68.86805699999996,70.01693700000004],[-68.90028399999994,70.01165800000007],[-68.954453,70.00471500000009],[-69.08860800000002,69.97499100000005],[-69.15306099999998,69.95304900000002],[-69.31310999999994,69.88229400000006],[-69.346115,69.855545],[-69.37054399999994,69.83998100000008],[-69.398056,69.82859800000006],[-69.42694099999994,69.81971699999997],[-69.43971299999993,69.8163760000001],[-69.460556,69.813309],[-69.474716,69.81359900000001],[-69.516953,69.81999200000013],[-69.54333500000001,69.82693499999993],[-69.56582600000002,69.83415200000007],[-69.58084100000002,69.836929],[-69.68388400000003,69.83998100000008],[-69.71389799999997,69.83998100000008],[-69.74499500000002,69.83776900000004],[-69.76000999999997,69.834991],[-69.77084400000001,69.83194000000003],[-69.80583200000001,69.81999200000013],[-69.827789,69.80941800000011],[-69.84416199999993,69.80026199999998],[-69.85583499999996,69.79359399999998],[-69.87249799999995,69.78109699999999],[-69.99804699999999,69.66998300000012],[-70,69.66415400000011],[-70.00083899999998,69.6560970000001],[-70.00140399999998,69.62275700000004],[-69.99888599999991,69.6160890000001],[-69.99055499999992,69.61499000000009],[-69.94444299999998,69.649719],[-69.816956,69.72442600000005],[-69.81082199999997,69.72886699999998],[-69.808334,69.733047],[-69.808334,69.73803700000002],[-69.81471299999987,69.75471500000009],[-69.81500199999999,69.76026900000011],[-69.81416300000001,69.76388499999996],[-69.80555700000002,69.77249100000006],[-69.78306600000002,69.78581200000002],[-69.764725,69.79553199999992],[-69.75445599999995,69.799713],[-69.74194299999999,69.8035890000001],[-69.73083500000001,69.80609099999998],[-69.71333300000003,69.80748],[-69.64306599999998,69.81080600000001],[-69.60278299999999,69.80970800000011],[-69.5727839999999,69.80442800000003],[-69.56111099999998,69.79998800000004],[-69.54527300000001,69.79443400000002],[-69.48998999999992,69.77970900000008],[-69.45666499999993,69.77581800000002],[-69.44665500000002,69.77554300000003],[-69.40916399999998,69.77638199999996],[-69.39584400000001,69.77777100000014],[-69.38473499999992,69.78082300000005],[-69.37805199999997,69.78387500000002],[-69.31388900000002,69.8163760000001],[-69.291382,69.83109999999994],[-69.27944899999994,69.84248400000007],[-69.26916499999993,69.85276800000008],[-69.25306699999999,69.86219800000015],[-69.20056199999988,69.88360600000004],[-69.18804899999998,69.88777199999998],[-69.10194399999995,69.91609199999999],[-69.07667499999997,69.92387400000013],[-68.94554099999999,69.94999700000005],[-68.93388400000003,69.95109600000006],[-68.87027,69.95304900000002],[-68.80194099999989,69.95220899999998],[-68.76666299999988,69.94886800000012],[-68.75195300000001,69.94663999999995],[-68.62281799999994,69.98240699999991],[-68.47166400000003,70.04664600000007],[-68.33833300000003,70.0641480000001],[-68.241379,70.09582500000005],[-68.22138999999999,70.10276800000003],[-68.20722999999998,70.109421],[-68.19638099999997,70.11943100000008],[-68.193604,70.12359600000008],[-68.20333899999997,70.12886000000009],[-68.22944599999994,70.13526900000011],[-68.26861600000001,70.13749700000011],[-68.2908329999999,70.13720700000005],[-68.30833399999995,70.13526900000011],[-68.32055700000001,70.13554399999998],[-68.333618,70.13916],[-68.34916699999985,70.16804500000006],[-68.34861799999999,70.1727600000001],[-68.34527599999996,70.18803400000002],[-68.31861899999996,70.21859699999999],[-68.31361400000003,70.22221400000012],[-68.16000400000001,70.28276100000011],[-68.03944399999995,70.301376],[-67.80804399999994,70.262497],[-67.79472399999997,70.25888100000009],[-67.77417000000003,70.25054900000009],[-67.76806599999998,70.24386600000014],[-67.76000999999991,70.22970600000002],[-67.74055499999986,70.21887200000015],[-67.69721999999996,70.2022090000001],[-67.67443799999995,70.19358799999998],[-67.648056,70.18609600000002],[-67.59167499999995,70.16526799999997],[-67.57556199999993,70.15832499999999],[-67.55694599999998,70.14915500000012],[-67.52833599999997,70.13388100000003],[-67.41221599999994,70.0688780000001],[-67.40472399999999,70.06442300000009],[-67.37805200000003,70.04803500000003],[-67.24249299999997,69.958328],[-67.222778,69.94386300000008],[-67.216949,69.93775900000003],[-67.15249599999999,69.81776400000001],[-67.14862099999999,69.81025700000009],[-67.12777699999987,69.72692900000004],[-67.193604,69.721924],[-67.37138400000003,69.71443200000004],[-67.39111300000002,69.71388200000001],[-67.40695199999988,69.71470599999998],[-67.43611099999993,69.71914700000008],[-67.49999999999994,69.73183399999999],[-67.60249299999992,69.7502750000001],[-67.761124,69.77859500000011],[-67.77305599999994,69.7794340000001],[-67.81082200000003,69.77886999999993],[-67.99610899999999,69.77442900000005],[-68.01306199999999,69.77192700000012],[-68.087784,69.75610400000011],[-68.208054,69.71554600000002],[-68.21665999999993,69.71026599999999],[-68.22277799999995,69.70471199999997],[-68.2286069999999,69.69136000000015],[-68.23028599999998,69.68441800000005],[-68.24110399999995,69.67498799999998],[-68.31138599999997,69.63333100000011],[-68.323624,69.62886000000003],[-68.329453,69.62776200000013],[-68.35278299999999,69.62692300000015],[-68.49638399999998,69.625809],[-68.51806599999992,69.62608300000011],[-68.62026999999989,69.63720699999999],[-68.64527899999996,69.64109800000006],[-68.83999599999999,69.6160890000001],[-68.98083499999996,69.589157],[-69.18859900000001,69.54193099999992],[-69.20111099999991,69.53804000000002],[-69.22000100000002,69.53581200000008],[-69.32501200000002,69.53248600000006],[-69.34277299999997,69.53248600000006],[-69.36416599999995,69.53776600000009],[-69.41027799999995,69.54609700000003],[-69.42694099999994,69.54803500000014],[-69.54943800000001,69.56053199999997],[-69.630829,69.56721500000009],[-69.68888900000002,69.56944300000009],[-69.73777799999999,69.56832900000006],[-69.75111400000003,69.56721500000009],[-69.83860800000002,69.55886800000013],[-70.0308379999999,69.53610200000008],[-70.02861000000001,69.53082300000011],[-70.025284,69.52748100000002],[-70.011124,69.52110300000004],[-69.995544,69.51721199999997],[-69.964722,69.51388500000002],[-69.89944499999996,69.50721700000008],[-69.88583399999999,69.50721700000008],[-69.86694299999988,69.50943000000001],[-69.84416199999993,69.51748700000002],[-69.82444800000002,69.52720599999998],[-69.81582600000002,69.53054800000012],[-69.803879,69.53498800000011],[-69.78944399999995,69.538589],[-69.73277300000001,69.54525800000005],[-69.69860799999992,69.54832499999998],[-69.68499799999995,69.54887400000013],[-69.66332999999992,69.54832499999998],[-69.61389199999991,69.54304500000012],[-69.506958,69.52943399999992],[-69.44999699999988,69.5188750000001],[-69.37582399999991,69.50972000000002],[-69.34306299999997,69.50582899999995],[-69.32333399999999,69.50526400000012],[-69.29998799999993,69.506104],[-69.20666499999999,69.51499899999999],[-69.1516719999999,69.52026400000005],[-69.00584400000002,69.53581200000008],[-68.99527,69.53970300000015],[-68.98222399999997,69.547211],[-68.97138999999999,69.5558170000001],[-68.95722999999998,69.56053199999997],[-68.9261019999999,69.566666],[-68.76945499999988,69.58749400000005],[-68.75250199999988,69.58943199999999],[-68.6683349999999,69.59082000000006],[-68.61193800000001,69.58749400000005],[-68.54472399999992,69.57998700000013],[-68.52806099999992,69.57720899999993],[-68.31722999999988,69.53027300000008],[-68.29333499999996,69.52360499999992],[-68.18194599999998,69.49832200000003],[-68.02555799999999,69.46609500000005],[-67.98222399999997,69.45748900000012],[-67.94610599999993,69.45471200000003],[-67.92639200000002,69.45416300000011],[-67.89334099999996,69.45443700000004],[-67.87416100000002,69.45664999999997],[-67.86193799999995,69.46026600000005],[-67.84083599999997,69.46943699999997],[-67.81945799999994,69.4769290000001],[-67.80694599999987,69.48082],[-67.79222099999998,69.48414600000001],[-67.60499600000003,69.47804300000007],[-67.56221,69.47192400000006],[-67.51167299999997,69.46609500000005],[-67.47582999999997,69.46304299999991],[-67.43277,69.46331800000013],[-67.30526699999996,69.46720900000003],[-67.25834700000001,69.46748400000001],[-67.21000699999996,69.46138000000002],[-67.18083200000001,69.45471200000003],[-66.921112,69.3791500000001],[-66.79554699999989,69.341095],[-66.78527799999995,69.3372040000001],[-66.77444499999996,69.33194000000009],[-66.76722699999993,69.32748400000003],[-66.69499200000001,69.28166199999998],[-66.68276999999995,69.27026400000011],[-66.65028399999994,69.23637400000001],[-66.64584400000001,69.22499100000005],[-66.64666699999998,69.20359800000011],[-66.65861499999994,69.188309],[-66.66833500000001,69.17831400000011],[-66.68943799999994,69.16192600000005],[-66.72000100000002,69.14415000000008],[-66.73055999999997,69.13888500000002],[-66.75306699999993,69.12942499999997],[-66.75862099999995,69.12803600000012],[-66.77610799999997,69.12886000000009],[-66.837219,69.13581800000009],[-66.84944200000001,69.13832100000008],[-66.912781,69.15498400000013],[-66.9283289999999,69.164154],[-66.95333900000003,69.172211],[-66.96528599999999,69.17442300000005],[-66.99694799999997,69.17776499999997],[-67.132767,69.18248],[-67.37193299999996,69.18441799999994],[-67.38555899999994,69.18386800000013],[-67.41471899999999,69.17831400000011],[-67.42721599999999,69.17442300000005],[-67.45889299999993,69.1624910000001],[-67.46610999999996,69.16081200000008],[-67.50556899999998,69.15748600000006],[-67.52111799999994,69.15776100000005],[-67.64862099999999,69.16693100000009],[-67.67639199999996,69.16943400000008],[-67.86416600000001,69.22192400000012],[-68.18447900000001,69.30801400000001],[-68.20973200000003,69.31137099999995],[-68.22166399999998,69.31219499999992],[-68.23277299999995,69.31137099999995],[-68.25195300000001,69.30970800000006],[-68.285278,69.30442800000014],[-68.31082200000003,69.29859899999997],[-68.32749899999999,69.29609700000009],[-68.34416199999998,69.29470800000007],[-68.35583500000001,69.29414400000013],[-68.37554899999992,69.29470800000007],[-68.46472199999994,69.30165100000005],[-68.67527799999999,69.32222000000002],[-68.74027999999998,69.33055100000013],[-68.811935,69.34193399999992],[-68.84445199999999,69.34610000000004],[-68.94471699999991,69.35498000000007],[-68.962784,69.35636900000003],[-68.98443600000002,69.35693400000008],[-69.015015,69.35498000000007],[-69.04028299999999,69.34971600000006],[-69.17666599999995,69.31080600000013],[-69.20306399999993,69.30304000000007],[-69.24137899999988,69.28414900000001],[-69.25389099999995,69.27526899999998],[-69.25778200000002,69.27026400000011],[-69.25167799999997,69.26361099999997],[-69.24694799999997,69.26110799999998],[-69.23500100000001,69.25972000000007],[-69.22193899999996,69.26165800000001],[-69.21305799999993,69.26470900000004],[-69.20333900000003,69.26998900000012],[-69.197769,69.27554299999991],[-69.17639200000002,69.28749099999999],[-69.15638699999994,69.297485],[-69.146118,69.30053700000008],[-69.133331,69.303314],[-69.01333599999998,69.32748400000003],[-68.95666499999987,69.33194000000009],[-68.94110099999995,69.33248900000007],[-68.92138699999987,69.33194000000009],[-68.6583399999999,69.30026200000009],[-68.537216,69.28526299999999],[-68.50473,69.28027299999997],[-68.33056599999992,69.27526899999998],[-68.25195300000001,69.27748100000008],[-68.23083500000001,69.27777100000009],[-68.19860799999998,69.27470399999999],[-68.17222599999997,69.26971400000008],[-68.15943899999996,69.26609800000006],[-68.14834599999989,69.26165800000001],[-68.13972499999988,69.25776699999994],[-68.08860800000002,69.2288670000001],[-68.083618,69.22554000000014],[-68.07749899999988,69.21748400000007],[-68.08167999999995,69.211929],[-68.09138499999995,69.20555100000007],[-68.103882,69.2022090000001],[-68.12971500000003,69.19775400000009],[-68.16305499999993,69.19999700000005],[-68.26306199999999,69.21138000000008],[-68.41082799999992,69.22137499999997],[-68.54998799999998,69.22692899999998],[-68.64361600000001,69.22943100000003],[-68.664444,69.22804300000013],[-68.68998699999992,69.22360200000003],[-68.83972199999994,69.21470600000009],[-68.92304999999999,69.2208250000001],[-68.96777299999997,69.22109999999998],[-68.94833399999987,69.21415699999994],[-68.93971299999987,69.211929],[-68.91305499999999,69.20748900000001],[-68.86277799999999,69.20193499999999],[-68.80749499999996,69.19886800000006],[-68.78805499999999,69.19831800000003],[-68.76722699999999,69.19970700000005],[-68.73777799999999,69.20359800000011],[-68.70472699999999,69.20915200000007],[-68.65695199999999,69.21054100000009],[-68.61805700000002,69.20915200000007],[-68.515015,69.20248400000014],[-68.50250199999999,69.19859300000007],[-68.50527999999991,69.19581599999998],[-68.51390100000003,69.19192500000008],[-68.69055199999997,69.141098],[-68.70722999999992,69.13832100000008],[-68.872772,69.12052900000003],[-68.99804699999999,69.10359199999999],[-68.96167000000003,69.10386700000004],[-68.92971799999992,69.10026600000015],[-68.92694099999994,69.09832800000004],[-68.92666600000001,69.07998700000002],[-68.95777900000002,69.00526400000001],[-68.95889299999999,69.00305200000014],[-68.96916199999993,68.99359100000004],[-68.99415599999992,68.982483],[-69.00611899999996,68.97831700000012],[-69.01888999999989,68.97581500000007],[-69.028885,68.97137500000002],[-69.02583300000003,68.96859700000005],[-69.01750199999998,68.966385],[-69.00556899999992,68.96470599999998],[-68.99804699999999,68.96499599999999],[-68.973053,68.97082499999999],[-68.962784,68.97470100000004],[-68.94638099999992,68.982483],[-68.93055700000002,68.99275200000005],[-68.92027299999995,69.00277699999998],[-68.89416499999993,69.04498299999995],[-68.89416499999993,69.05053700000013],[-68.89222699999999,69.06219499999997],[-68.889725,69.06637600000005],[-68.88194299999986,69.07777400000009],[-68.87916599999994,69.08137499999992],[-68.8724979999999,69.084991],[-68.85833699999989,69.08831800000013],[-68.75361599999997,69.10971100000006],[-68.471115,69.166382],[-68.41278099999994,69.17692600000004],[-68.38137799999993,69.17526200000003],[-68.35139499999997,69.17164600000012],[-68.17832900000002,69.14665199999996],[-68.089447,69.126083],[-67.72528099999994,69.03221100000013],[-67.715012,69.0291600000001],[-67.708054,69.02470400000004],[-67.70584099999996,69.01638800000012],[-67.72111499999994,69.00972000000013],[-67.97471599999994,68.9727630000001],[-68.02944899999994,68.97137500000002],[-68.05888400000003,68.97360200000008],[-68.21112099999993,68.99192800000009],[-68.241379,68.99693300000013],[-68.26806599999998,69.00277699999998],[-68.31416299999995,69.0105440000001],[-68.33500700000002,69.00915500000008],[-68.53555299999988,68.98414600000012],[-68.54861499999998,68.98220800000001],[-68.55277999999998,68.97720300000015],[-68.55471799999992,68.97110000000004],[-68.556107,68.964157],[-68.54527299999995,68.95971700000001],[-68.44055200000003,68.9727630000001],[-68.33750900000001,68.98580900000007],[-68.32028199999996,68.98637400000007],[-68.30305499999997,68.98580900000007],[-68.29055799999998,68.98220800000001],[-68.285278,68.97747800000013],[-68.28443900000002,68.97470100000004],[-68.26417500000002,68.96470599999998],[-68.19694500000003,68.94999700000011],[-68.18666100000002,68.94775400000015],[-68.16944899999999,68.94693000000001],[-68.15222199999994,68.94693000000001],[-68.116104,68.94747899999993],[-68.08167999999995,68.94747899999993],[-68.06416300000001,68.94609100000002],[-68.04834,68.94386300000008],[-68.03999299999998,68.94136000000009],[-67.97471599999994,68.86526500000008],[-67.972778,68.85914600000007],[-67.97749299999998,68.855545],[-67.98693800000001,68.85443100000003],[-68.0061189999999,68.85497999999995],[-68.08222999999998,68.86248799999998],[-68.129166,68.867752],[-68.18360899999999,68.87858600000004],[-68.24221799999987,68.88998400000003],[-68.25611900000001,68.89221200000003],[-68.289444,68.89498900000012],[-68.37388599999997,68.89721700000007],[-68.475281,68.89942900000011],[-68.48999000000003,68.897491],[-68.49166899999994,68.89665200000002],[-68.48889200000002,68.893326],[-68.48582499999992,68.89027400000009],[-68.47721899999993,68.88693200000012],[-68.46333300000003,68.88554400000004],[-68.43249499999996,68.88333100000006],[-68.37304699999993,68.88220200000012],[-68.35360699999995,68.88108799999992],[-68.29305999999997,68.87498499999998],[-68.266663,68.86998000000011],[-68.17971799999992,68.85192899999998],[-68.13389599999994,68.83720399999999],[-68.00834700000001,68.81666600000011],[-67.972778,68.81192000000004],[-67.95556599999998,68.81025700000009],[-67.91694599999994,68.80831899999998],[-67.88667299999992,68.80886800000007],[-67.86138900000003,68.80554200000006],[-67.77833599999991,68.78610200000008],[-67.77194199999997,68.78276100000005],[-67.77139299999993,68.78137200000003],[-67.77471899999995,68.77915999999999],[-67.80332900000002,68.77415500000012],[-67.82000699999998,68.7727660000001],[-67.85777299999995,68.77137800000003],[-67.872772,68.77165200000013],[-67.915009,68.77415500000012],[-67.94444299999992,68.77804600000002],[-68.07611099999997,68.80192599999998],[-68.17083699999989,68.81469700000008],[-68.35221899999993,68.83248899999995],[-68.42639200000002,68.83915700000011],[-68.54666099999997,68.84664900000007],[-68.56555199999997,68.84721400000012],[-68.58805799999999,68.84637499999997],[-68.60610999999989,68.842758],[-68.61054999999999,68.83915700000011],[-68.61166399999996,68.83581500000003],[-68.60444599999994,68.83137499999998],[-68.593887,68.82748400000008],[-68.55776999999995,68.82138099999997],[-68.52694699999995,68.79525800000005],[-68.60249299999992,68.794983],[-68.67887899999994,68.79664600000012],[-68.79527300000001,68.79942300000005],[-68.80722000000003,68.80026199999998],[-68.90028399999994,68.80720500000001],[-68.96749899999992,68.81469700000008],[-68.99527,68.81915300000003],[-69.00389100000001,68.82222000000013],[-69.015015,68.8272090000001],[-69.10583500000001,68.84860200000003],[-69.25111400000003,68.87248199999999],[-69.28083799999996,68.87580900000012],[-69.32305899999994,68.8766480000001],[-69.36193800000001,68.87414600000005],[-69.37805199999997,68.87136800000002],[-69.38999899999999,68.86747699999995],[-69.398056,68.86219800000015],[-69.394455,68.85775799999999],[-69.37999000000002,68.85497999999995],[-69.36082499999992,68.85443100000003],[-69.33167999999995,68.85693400000002],[-69.27944899999994,68.855255],[-69.24554399999988,68.85137900000012],[-69.18554699999999,68.84220900000008],[-69.171112,68.83888200000013],[-69.16221599999994,68.83581500000003],[-69.15222199999994,68.82804899999996],[-69.15388499999995,68.8272090000001],[-69.16305499999999,68.826096],[-69.22999600000003,68.8272090000001],[-69.29415899999992,68.83194000000003],[-69.31500199999999,68.83166499999999],[-69.35777300000001,68.82916300000011],[-69.368607,68.8272090000001],[-69.37554899999998,68.82499700000005],[-69.382767,68.81915300000003],[-69.383896,68.8163760000001],[-69.38137799999998,68.81498699999992],[-69.37110899999999,68.81275900000014],[-69.193604,68.80415300000004],[-68.971115,68.79193100000009],[-68.95916699999992,68.78970300000015],[-68.94499200000001,68.78692600000005],[-68.94249000000002,68.78498800000011],[-68.19638099999997,68.70694000000015],[-68.04943799999995,68.68165599999998],[-68.04499800000002,68.67831400000006],[-68.04611199999994,68.67637600000006],[-68.08750899999995,68.62942500000008],[-68.09445199999993,68.62776200000013],[-68.34445199999999,68.6285860000001],[-68.56220999999988,68.65193199999999],[-68.62193300000001,68.65582300000005],[-68.65777600000001,68.65637200000015],[-68.68028300000003,68.65554800000001],[-68.74777199999994,68.64915500000006],[-68.77778599999994,68.64305100000001],[-68.89416499999993,68.60720800000001],[-68.90249599999999,68.6035920000001],[-68.90028399999994,68.60304300000001],[-68.83583099999998,68.589157],[-68.804169,68.58998099999997],[-68.75767499999995,68.60064699999998],[-68.74934399999995,68.60265400000014],[-68.73500100000001,68.60731499999997],[-68.71116599999999,68.62114700000012],[-68.67999299999991,68.63081400000004],[-68.64750700000002,68.6355440000001],[-68.62860099999989,68.6355440000001],[-68.59416199999993,68.63360599999999],[-68.56304899999992,68.62942500000008],[-68.53332499999999,68.62498500000004],[-68.48138399999993,68.61499000000015],[-68.475281,68.61303700000002],[-68.47027600000001,68.60914600000012],[-68.46945199999999,68.60636900000003],[-68.48332199999999,68.59693900000013],[-68.50389100000001,68.58998099999997],[-68.519455,68.58581500000008],[-68.53388999999993,68.58387800000003],[-68.60583499999996,68.57887299999999],[-68.64834599999995,68.57777399999998],[-68.66000400000001,68.57887299999999],[-68.68288399999994,68.57521100000002],[-68.69506100000001,68.57437900000014],[-68.70705399999997,68.57337200000012],[-68.71238700000004,68.572044],[-68.71606400000002,68.56938200000002],[-68.71672799999993,68.56804700000004],[-68.70705399999997,68.5660400000001],[-68.69672400000002,68.56520799999998],[-68.656113,68.559708],[-68.46000700000002,68.56219500000009],[-68.44722000000002,68.56359900000007],[-68.43527199999994,68.56749000000013],[-68.42721599999999,68.57193000000001],[-68.42277499999994,68.57609600000006],[-68.4202729999999,68.57971199999992],[-68.41999799999996,68.5852660000001],[-68.41639700000002,68.59136999999998],[-68.39611799999994,68.59304800000007],[-68.337784,68.59332300000011],[-68.24444599999998,68.58804300000003],[-68.21556099999987,68.58554100000015],[-68.13667299999997,68.57222000000002],[-68.06534599999992,68.54582200000004],[-67.92027300000001,68.534424],[-67.86694299999999,68.50972000000007],[-67.80915800000002,68.5310970000001],[-67.67304999999993,68.56109600000008],[-67.66416900000002,68.56275900000003],[-67.64361599999995,68.56275900000003],[-67.53944399999995,68.55081200000006],[-67.52555799999999,68.54859899999991],[-67.50083899999993,68.53831500000007],[-67.49221799999992,68.52720600000004],[-67.49305699999996,68.52360499999998],[-67.502228,68.51499900000005],[-67.510559,68.51138299999997],[-67.51916499999993,68.50915500000002],[-67.54305999999991,68.506104],[-67.60777300000001,68.50387600000005],[-67.62165800000002,68.5],[-67.62805200000003,68.49636800000002],[-67.63473499999992,68.486649],[-67.62138399999998,68.38442999999995],[-67.618607,68.38108800000003],[-67.61250299999995,68.37942499999991],[-67.6033329999999,68.37886000000009],[-67.59445199999999,68.38136300000008],[-67.55110200000001,68.41442899999998],[-67.54834,68.44026200000013],[-67.5494379999999,68.44386300000002],[-67.55583200000001,68.45526100000001],[-67.51112399999994,68.4833220000001],[-67.42610200000001,68.49443099999996],[-67.335556,68.49693300000007],[-67.31639100000001,68.49609400000008],[-67.23249799999996,68.480545],[-67.22416699999997,68.47665400000011],[-67.21749899999992,68.47192400000006],[-67.21362299999993,68.44081100000005],[-67.223053,68.42608600000011],[-67.30777,68.42330900000002],[-67.32583599999998,68.42137100000008],[-67.33277900000002,68.41886900000003],[-67.33583099999998,68.4160920000001],[-67.33860800000002,68.41192600000005],[-67.33805799999999,68.40998800000006],[-67.32444800000002,68.40776100000005],[-67.15695199999999,68.40637200000003],[-67.11193800000001,68.41192600000005],[-67.10499600000003,68.414154],[-67.10055499999993,68.41832000000005],[-67.09722899999997,68.45138500000013],[-67.100281,68.45721400000014],[-67.10665899999987,68.46054100000009],[-67.11665299999999,68.46360799999997],[-67.12721299999998,68.46804800000001],[-67.12999000000002,68.47276300000004],[-67.126938,68.47554000000014],[-67.11277799999999,68.4788670000001],[-66.90805099999994,68.4538730000001],[-66.821396,68.46527100000009],[-66.80305499999997,68.46720900000003],[-66.78750600000001,68.4649960000001],[-66.706955,68.44470200000012],[-66.69776899999994,68.42803999999995],[-66.72416699999991,68.42915300000004],[-66.78277599999996,68.42608600000011],[-66.90499899999992,68.41638200000011],[-66.92054699999994,68.41110200000008],[-66.92166099999992,68.40832499999999],[-66.9141689999999,68.39888000000008],[-66.91305499999999,68.39498900000001],[-66.914444,68.3919370000001],[-66.93638599999997,68.37442000000004],[-66.94665499999991,68.36998000000006],[-66.95500199999998,68.36747700000006],[-67.00584399999997,68.35443099999998],[-67.01112399999994,68.35359199999999],[-67.02416999999997,68.35386699999998],[-67.04888900000003,68.35582000000011],[-67.07556199999993,68.36053500000014],[-67.11138899999997,68.37025500000004],[-67.13027999999991,68.37970000000013],[-67.14222699999999,68.38275099999998],[-67.23055999999997,68.39498900000001],[-67.245544,68.395828],[-67.28639199999998,68.395828],[-67.37971500000003,68.39082300000013],[-67.41111799999993,68.38275099999998],[-67.41555799999998,68.37803600000012],[-67.41888399999999,68.376373],[-67.45556599999992,68.36775200000011],[-67.49471999999997,68.36080900000007],[-67.59527600000001,68.34776299999999],[-67.63166799999999,68.34526100000011],[-67.64611799999994,68.34471100000007],[-67.74388099999999,68.34332299999994],[-67.78138699999994,68.3372040000001],[-67.81054699999999,68.328598],[-67.83222999999992,68.32026700000011],[-67.84973099999996,68.30998199999999],[-67.86582900000002,68.29971299999994],[-67.87110899999999,68.292755],[-67.87832600000002,68.26527400000009],[-67.86972000000003,68.25999500000012],[-67.86000100000001,68.25833100000011],[-67.845551,68.25888099999997],[-67.83332799999994,68.26138300000002],[-67.82667500000002,68.26443499999993],[-67.8202819999999,68.26859999999994],[-67.81806899999992,68.27415500000006],[-67.82112099999995,68.284988],[-67.82055700000001,68.28970300000003],[-67.81555199999997,68.29220600000002],[-67.75250199999999,68.3188780000001],[-67.74526999999989,68.32054100000005],[-67.597778,68.32304400000004],[-67.58306900000002,68.30802900000003],[-67.57223499999998,68.27331499999997],[-67.57667500000002,68.26859999999994],[-67.583328,68.26554899999996],[-67.59167499999995,68.26304600000014],[-67.61639400000001,68.25833100000011],[-67.64666699999998,68.25360100000006],[-67.662781,68.25248700000009],[-67.689438,68.24803200000008],[-67.695267,68.24247700000001],[-67.69499200000001,68.2410890000001],[-67.69082600000002,68.23970000000008],[-67.67971799999992,68.23887600000012],[-67.666946,68.23997500000013],[-67.57972699999993,68.25138900000002],[-67.5708469999999,68.25305200000014],[-67.55166600000001,68.25833100000011],[-67.54695099999998,68.2605440000001],[-67.53916900000002,68.26582300000007],[-67.53306600000002,68.27137800000014],[-67.53111299999995,68.27832000000006],[-67.53500400000001,68.28553800000003],[-67.541382,68.28887900000007],[-67.54611199999994,68.29414400000013],[-67.54499799999996,68.29637100000002],[-67.54028299999993,68.29971299999994],[-67.52389499999998,68.30859400000008],[-67.49415599999998,68.32193000000001],[-67.401947,68.35247800000002],[-67.39472999999998,68.3541560000001],[-67.38555899999994,68.35443099999998],[-67.24388099999999,68.35832200000004],[-67.23249799999996,68.35748300000006],[-67.18249500000002,68.34942600000011],[-67.13027999999991,68.34082000000001],[-67.07806399999993,68.3311000000001],[-67.01611300000002,68.318604],[-67.01167299999992,68.31608600000004],[-67.01834099999996,68.311646],[-67.03250099999997,68.309143],[-67.152222,68.29998799999998],[-67.23500099999995,68.29165599999999],[-67.30387899999994,68.25888099999997],[-67.31973299999999,68.24971],[-67.32778899999994,68.24359099999998],[-67.33361799999994,68.23776199999998],[-67.33750900000001,68.232483],[-67.33889799999992,68.22776799999997],[-67.33944699999995,68.22164900000013],[-67.33944699999995,68.20555100000007],[-67.33500700000002,68.20082100000002],[-67.32749899999993,68.18664600000011],[-67.32778899999994,68.18109100000004],[-67.33860800000002,68.17109700000003],[-67.34584000000001,68.16609199999999],[-67.37110899999999,68.15386999999998],[-67.387787,68.14637800000008],[-67.39862099999988,68.1438750000001],[-67.41250599999995,68.14305100000013],[-67.43028300000003,68.14471400000008],[-67.456955,68.14942900000011],[-67.47778299999999,68.15498400000001],[-67.51390100000003,68.1624910000001],[-67.528885,68.16526800000003],[-67.56777999999997,68.16914400000007],[-67.58111600000001,68.16886900000009],[-67.59889199999998,68.16499299999998],[-67.59834299999994,68.16276600000015],[-67.57556199999993,68.15498400000001],[-67.54472399999992,68.14776599999999],[-67.48028599999998,68.13472000000002],[-67.466949,68.13220200000006],[-67.43804899999998,68.12803600000001],[-67.40805099999994,68.12498499999998],[-67.39695699999993,68.12469499999997],[-67.37416100000002,68.12747200000001],[-67.353882,68.135269],[-67.30777,68.15554800000012],[-67.30416899999994,68.15860000000004],[-67.27389499999992,68.19081100000011],[-67.27278100000001,68.19552599999997],[-67.27471899999989,68.20054600000003],[-67.27917500000001,68.20526100000006],[-67.283615,68.21192900000005],[-67.28889499999997,68.22637900000012],[-67.289444,68.23082000000005],[-67.289444,68.23637400000007],[-67.27471899999989,68.24414100000001],[-67.178879,68.26998900000012],[-67.139725,68.27998400000007],[-67.05776999999989,68.29109200000005],[-67.01139799999999,68.29498300000012],[-66.99833699999994,68.29248000000013],[-66.99110399999995,68.28887900000007],[-66.98611499999998,68.28553800000003],[-66.98416099999997,68.28054800000001],[-66.97361799999999,68.27388000000002],[-66.964722,68.270264],[-66.93057299999992,68.26248200000003],[-66.86582899999996,68.25],[-66.83583099999993,68.24636800000007],[-66.791672,68.24470500000012],[-66.77749599999999,68.24331700000005],[-66.76972999999992,68.2410890000001],[-66.76583900000003,68.23858600000011],[-66.78028899999998,68.20776400000005],[-66.85221899999999,68.11526500000008],[-66.88890099999998,68.092758],[-66.89666699999987,68.0894320000001],[-66.91389499999997,68.08415200000007],[-66.94583099999994,68.076096],[-66.95445299999994,68.07193000000007],[-66.96556099999992,68.06387300000011],[-66.971115,68.05331400000006],[-66.97277799999995,68.04859900000002],[-66.97332799999998,68.03942899999998],[-66.96972700000003,68.03414900000013],[-66.96112099999999,68.02499400000005],[-66.95361299999996,68.01721200000009],[-66.94665499999991,68.01361100000003],[-66.92805499999997,68.042755],[-66.92166099999992,68.04914900000006],[-66.83612099999993,68.09553500000004],[-66.74804699999999,68.13165300000014],[-66.70916699999992,68.141098],[-66.69444299999998,68.14305100000013],[-66.68276999999995,68.14137300000004],[-66.678879,68.13888500000002],[-66.670837,68.12886000000015],[-66.67027299999995,68.1141510000001],[-66.67805499999992,68.04332000000005],[-66.68055700000002,68.036926],[-66.6930539999999,68.02221700000013],[-66.70638999999994,68.01165800000012],[-66.72083999999995,68.00166300000001],[-66.73500099999995,67.98220800000001],[-66.73277300000001,67.98193400000008],[-66.71472199999994,67.98359700000003],[-66.6972199999999,67.9874880000001],[-66.64723200000003,68.01554899999996],[-66.63473499999986,68.06414799999993],[-66.63194299999998,68.07582100000013],[-66.62554899999998,68.103317],[-66.62027,68.12580900000012],[-66.61555499999997,68.13247700000011],[-66.61054999999993,68.13693200000012],[-66.59472699999992,68.14305100000013],[-66.56138599999997,68.14749099999995],[-66.54194599999988,68.14833099999998],[-66.51362599999993,68.14833099999998],[-66.32888799999995,68.13220200000006],[-66.31527699999998,68.13026400000012],[-66.30943299999996,68.12747200000001],[-66.31054699999993,68.1185910000001],[-66.31500199999988,68.11248799999998],[-66.321121,68.10693400000014],[-66.35028099999994,68.09027100000009],[-66.36639400000001,68.08332800000011],[-66.37165799999997,68.08166499999999],[-66.38861099999997,68.08137499999998],[-66.41361999999998,68.08610499999998],[-66.42777999999998,68.08749399999999],[-66.45056199999999,68.08692899999994],[-66.46861299999995,68.083054],[-66.4761049999999,68.08055100000001],[-66.47860699999995,68.07720900000004],[-66.47222899999991,68.07304400000004],[-66.460556,68.0705410000001],[-66.43804899999998,68.06805400000002],[-66.38999899999999,68.06944300000004],[-66.36944599999993,68.07165500000008],[-66.32611099999997,68.07916300000011],[-66.303879,68.08387800000014],[-66.29666099999997,68.08610499999998],[-66.27278099999995,68.08776900000004],[-66.25917099999998,68.08581499999997],[-66.25083899999998,68.08221400000014],[-66.24027999999987,68.07331799999997],[-66.18415799999997,68.01887500000004],[-66.18443300000001,68.01332100000002],[-66.18638599999991,68.01081800000003],[-66.19276400000001,68.00721700000003],[-66.2041779999999,68.00471500000009],[-66.25306699999987,68.00221300000004],[-66.26417500000002,67.99971000000005],[-66.29444899999999,67.9916530000001],[-66.30972299999996,67.98609900000008],[-66.32084699999996,67.97886699999998],[-66.34445199999993,67.95665000000008],[-66.40583800000002,67.89804100000003],[-66.40139799999997,67.888596],[-66.52223200000003,67.86080900000002],[-66.535278,67.86360200000001],[-66.59416199999998,67.87248200000005],[-66.628601,67.8766480000001],[-66.67250100000001,67.88026400000001],[-66.729446,67.87885999999997],[-66.73971599999999,67.87776200000008],[-66.74694799999992,67.87525900000014],[-66.74499499999996,67.87275700000004],[-66.73222399999997,67.86720300000007],[-66.70306399999998,67.86360200000001],[-66.68693499999995,67.86276199999998],[-66.653885,67.85942100000011],[-66.56138599999997,67.84304800000007],[-66.40139799999997,67.81109600000008],[-66.35665899999992,67.82138100000003],[-66.34638999999999,67.86109900000002],[-66.33277900000002,67.88777200000004],[-66.31945799999988,67.91110200000014],[-66.295837,67.93830900000012],[-66.27667200000002,67.95443699999998],[-66.26861599999995,67.95803799999999],[-66.25195299999996,67.9624940000001],[-66.24055499999997,67.96276899999992],[-66.22749299999987,67.95999100000012],[-66.21389799999997,67.96081500000008],[-66.13694800000002,67.976089],[-66.11999500000002,67.98136900000009],[-66.00321999999989,68.02049299999999],[-65.98872399999988,68.02614599999998],[-65.98138399999999,68.02998400000013],[-65.943604,68.04609700000015],[-65.94860799999998,68.09248400000007],[-65.95861799999994,68.12942499999997],[-65.96194500000001,68.13749700000011],[-65.960556,68.14444000000015],[-65.94749499999989,68.15416000000005],[-65.94166599999994,68.15721100000002],[-65.92832900000002,68.1622010000001],[-65.920837,68.16192600000005],[-65.91194199999995,68.15887500000008],[-65.86749299999991,68.12469499999997],[-65.86389200000002,68.11943100000013],[-65.85777300000001,68.11026000000004],[-65.85360700000001,68.07804899999991],[-65.85360700000001,68.07331799999997],[-65.85777300000001,68.06721500000003],[-65.93383799999992,68.01226800000012],[-65.96032699999995,67.99642900000003],[-65.98083500000001,67.98726700000009],[-65.99433099999999,67.97976700000004],[-66.03222699999998,67.95248400000003],[-65.98582499999998,67.91665599999999],[-65.96722399999999,67.85331700000006],[-65.98083500000001,67.842758],[-66.00500499999987,67.81498699999997],[-66.00973499999998,67.80331400000011],[-66.02888499999995,67.72442600000011],[-66.02888499999995,67.71943699999997],[-66.02194199999997,67.65026900000004],[-66.02000399999991,67.63526900000011],[-66.01306199999993,67.62692300000003],[-66.008621,67.62553400000002],[-65.9997249999999,67.62747200000013],[-65.98666399999996,67.63526900000011],[-65.96139499999998,67.68969700000008],[-65.95028699999995,67.722488],[-65.936935,67.76554900000002],[-65.93859899999995,67.77609300000006],[-65.94249000000002,67.78082300000011],[-65.953888,67.79832499999998],[-65.95666499999993,67.81192000000004],[-65.95584099999996,67.81832900000006],[-65.95333899999997,67.82138100000003],[-65.94610599999999,67.82638500000013],[-65.92639199999996,67.832764],[-65.86915599999992,67.84414700000002],[-65.83167999999995,67.85443100000003],[-65.804169,67.86360200000001],[-65.79527299999995,67.868042],[-65.76362599999993,67.909988],[-65.76222200000001,67.91470300000003],[-65.76390100000003,67.91970800000007],[-65.76722699999999,67.92303500000003],[-65.79888900000003,67.93830900000012],[-65.81973299999999,67.95555100000013],[-65.823624,67.96276899999992],[-65.81777999999997,67.96804800000012],[-65.80776999999995,67.97110000000004],[-65.68443300000001,67.99247700000006],[-65.46305799999999,67.99636800000013],[-65.44860799999998,67.99552900000015],[-65.443604,67.99220300000013],[-65.44193999999999,67.98692300000005],[-65.44249000000002,67.98136900000009],[-65.45750399999997,67.93719499999992],[-65.464447,67.92082200000004],[-65.52027899999996,67.84304800000007],[-65.52583300000003,67.83776900000004],[-65.54527300000001,67.82222000000013],[-65.55860899999999,67.81442300000003],[-65.57362399999994,67.80693100000008],[-65.603882,67.79693599999996],[-65.61054999999988,67.79275500000006],[-65.61582900000002,67.78610200000008],[-65.61389199999991,67.78082300000011],[-65.61000100000001,67.77638200000001],[-65.59194899999994,67.76304600000009],[-65.57250999999997,67.75166300000006],[-65.55694599999987,67.7452550000001],[-65.51750199999998,67.73304700000006],[-65.47361799999993,67.71971100000007],[-65.45472699999999,67.71276899999998],[-65.43971299999993,67.70555100000001],[-65.42639199999996,67.69636500000001],[-65.41361999999998,67.68359399999991],[-65.40695199999999,67.67498800000004],[-65.40360999999996,67.66470300000009],[-65.40028399999994,67.65443400000004],[-65.39639299999988,67.64498900000001],[-65.38473499999992,67.625809],[-65.36389200000002,67.59748800000011],[-65.35665899999992,67.59471100000002],[-65.34638999999999,67.59332300000011],[-65.33528100000001,67.59359700000005],[-65.32278400000001,67.59498600000006],[-65.31834400000002,67.601089],[-65.36915599999992,67.70277400000009],[-65.37916599999994,67.71165500000001],[-65.40264899999994,67.72322100000008],[-65.46250899999995,67.74192800000014],[-65.49249299999997,67.75166300000006],[-65.51083399999999,67.75915500000002],[-65.54444899999999,67.77415500000012],[-65.55055199999998,67.77832000000012],[-65.55444299999999,67.78305100000006],[-65.55444299999999,67.78804000000002],[-65.42361499999998,67.89804100000003],[-65.29249599999997,67.934143],[-65.235275,67.94470200000006],[-65.20140100000003,67.95443699999998],[-65.17166099999992,67.966095],[-65.15638699999994,67.97360200000008],[-65.14416499999987,67.98414599999995],[-65.14138799999995,67.99026500000002],[-65.14555399999995,67.997208],[-65.17582700000003,68.00888100000003],[-65.18083199999995,68.01220700000005],[-65.181107,68.016663],[-65.17666599999995,68.02249100000006],[-65.16915899999992,68.02720600000009],[-65.047775,68.04942299999999],[-65.00111399999992,68.055542],[-64.973053,68.05026199999998],[-64.73416099999997,67.99386600000003],[-64.72361799999999,67.99054000000001],[-64.71749899999998,67.98637400000013],[-64.71362299999998,67.98165900000009],[-64.71806300000003,67.97665400000005],[-64.72555499999993,67.97164899999996],[-64.74333200000001,67.96581999999995],[-64.84722899999997,67.93498199999999],[-64.94249000000002,67.91249099999999],[-65.015289,67.86248800000004],[-65.01777599999997,67.820831],[-65.00834700000001,67.78526299999993],[-65.01417500000002,67.78027300000008],[-65.05110199999996,67.75443999999999],[-65.06054699999993,67.7522130000001],[-65.0852809999999,67.749146],[-65.112213,67.74803200000002],[-65.12443499999995,67.74636800000002],[-65.136124,67.7435910000001],[-65.14555399999995,67.73887600000006],[-65.15833999999995,67.72970600000002],[-65.17999299999991,67.71360800000014],[-65.19248999999996,67.70220900000004],[-65.19638099999997,67.69720500000011],[-65.19860799999992,67.69164999999998],[-65.20500199999998,67.65914900000007],[-65.20556599999992,67.65359500000011],[-65.20417800000001,67.6483310000001],[-65.20028699999995,67.64387500000004],[-65.17832899999996,67.63360599999999],[-65.17250099999995,67.63360599999999],[-65.16722099999998,67.63581800000003],[-65.162781,67.63888500000013],[-65.150284,67.67221100000012],[-65.14973399999997,67.67776500000008],[-65.150284,67.68193100000002],[-65.15417499999995,67.68664600000005],[-65.15333599999991,67.69220000000001],[-65.14889499999998,67.69831799999997],[-65.12971500000003,67.71582000000001],[-65.12416100000002,67.71804799999995],[-64.92971799999992,67.78776600000009],[-64.91972399999992,67.79081700000012],[-64.90722700000003,67.79220599999996],[-64.82722499999994,67.78471400000001],[-64.81639100000001,67.78137200000009],[-64.81054699999999,67.77720599999998],[-64.80888400000003,67.771927],[-64.80749499999996,67.74275200000011],[-64.81610099999989,67.71054100000003],[-64.82583599999998,67.70304900000008],[-64.83750900000001,67.70027199999998],[-64.86277799999999,67.69164999999998],[-64.86250299999995,67.68748499999998],[-64.84944200000001,67.68719499999997],[-64.82055700000001,67.68830899999995],[-64.79972800000002,67.69081100000005],[-64.77944899999989,67.69775400000003],[-64.773056,67.70359800000006],[-64.76861600000001,67.70942700000006],[-64.76222199999995,67.76249700000011],[-64.75584399999997,67.81776400000007],[-64.75,67.82276900000011],[-64.74082900000002,67.82470700000005],[-64.65306099999998,67.82887299999993],[-64.61193800000001,67.82638500000013],[-64.56806899999998,67.81999200000001],[-64.506958,67.80720500000001],[-64.36888099999993,67.76416000000006],[-64.36332700000003,67.75943000000001],[-64.36389199999996,67.75443999999999],[-64.39611799999994,67.71192900000011],[-64.40139799999992,67.70776400000011],[-64.41471899999999,67.70721400000008],[-64.43138099999999,67.70971700000007],[-64.44526699999994,67.71138000000002],[-64.4600069999999,67.71165500000001],[-64.47250399999996,67.71026600000005],[-64.57833899999997,67.69693000000007],[-64.59722899999986,67.68969700000008],[-64.61721799999998,67.67858900000004],[-64.6372219999999,67.66526799999991],[-64.63917500000002,67.66053800000009],[-64.62638900000002,67.65971400000012],[-64.61833200000001,67.66304000000014],[-64.58139,67.67442299999999],[-64.51583900000003,67.68609600000002],[-64.45417799999996,67.69331400000004],[-64.38082899999989,67.69802900000008],[-64.36250299999989,67.70248400000008],[-64.34722899999997,67.709991],[-64.33138999999989,67.72720300000003],[-64.32640099999992,67.7310940000001],[-64.31806899999992,67.73414600000001],[-64.30555700000002,67.73359700000009],[-64.29527300000001,67.73027000000013],[-64.07278400000001,67.6102600000001],[-64.06777999999997,67.60247799999996],[-64.03971899999999,67.53360000000009],[-64.0386049999999,67.52859500000005],[-64.03889500000002,67.52581800000013],[-64.04499800000002,67.52082800000005],[-64.05305499999992,67.51748700000002],[-64.13473499999992,67.49026500000008],[-64.14472999999992,67.48719799999998],[-64.16528299999999,67.48248299999995],[-64.2386019999999,67.46748400000007],[-64.25083899999987,67.46609500000011],[-64.27194199999997,67.4649960000001],[-64.281113,67.46554600000013],[-64.34388699999994,67.46998599999995],[-64.38694800000002,67.474426],[-64.412216,67.47747800000008],[-64.42304999999999,67.47804300000013],[-64.43554699999999,67.47859200000005],[-64.44055200000003,67.47499100000005],[-64.43222000000003,67.47109999999998],[-64.41000400000001,67.46415699999994],[-64.38473499999998,67.45832800000011],[-64.35694899999999,67.4538730000001],[-64.29666099999992,67.44802900000008],[-64.283615,67.44802900000008],[-64.20445299999994,67.4522090000001],[-64.19055199999997,67.45332300000007],[-64.166946,67.45694000000003],[-64.14500399999986,67.46165500000006],[-64.12332199999992,67.46527100000014],[-64.11111499999993,67.4666600000001],[-64.08639499999998,67.46748400000007],[-64.04804999999988,67.46415699999994],[-64.01083399999999,67.45971700000013],[-64.00111400000003,67.45582600000006],[-63.99265300000002,67.44862400000011],[-63.95111099999997,67.40998800000011],[-63.90416699999997,67.30581699999999],[-63.90416699999997,67.3016510000001],[-63.90582999999992,67.299713],[-63.912773000000016,67.2955320000001],[-63.92388900000003,67.29332000000005],[-63.93721800000003,67.292755],[-64.02278099999995,67.30802900000009],[-64.05526699999996,67.31137100000001],[-64.08473200000003,67.31330900000012],[-64.18167099999994,67.31219499999997],[-64.21749899999998,67.31359899999995],[-64.33999599999999,67.31944299999998],[-64.53056299999992,67.33776899999998],[-64.74027999999998,67.35693400000014],[-64.75750700000003,67.35832200000004],[-64.78832999999992,67.35914600000001],[-64.79750099999995,67.35664400000013],[-64.80082699999997,67.35276800000003],[-64.79888900000003,67.35026600000015],[-64.78860500000002,67.34693900000002],[-64.73443599999996,67.3336030000001],[-64.72138999999993,67.33137499999992],[-64.68777499999999,67.32748400000003],[-64.441666,67.30304000000012],[-64.402222,67.29914900000006],[-64.37249800000001,67.29721100000012],[-64.34472699999992,67.29748500000005],[-64.283615,67.29998799999998],[-64.258621,67.29914900000006],[-64.24610899999999,67.29859900000002],[-64.23832699999997,67.29693600000007],[-64.23194899999999,67.29332000000005],[-64.23388699999987,67.28858900000012],[-64.24833699999999,67.27943400000004],[-64.30638099999999,67.26220700000005],[-64.32501200000002,67.25721699999997],[-64.35611,67.25027500000004],[-64.39222699999999,67.24664300000012],[-64.41944899999993,67.24720799999994],[-64.50917099999998,67.25499000000008],[-64.53694199999995,67.25665300000003],[-64.55027799999999,67.25610400000005],[-64.66861,67.23858599999994],[-64.72416699999997,67.22886699999998],[-64.77917499999995,67.21887200000003],[-64.79028299999993,67.21665999999999],[-64.79998799999993,67.21360800000008],[-64.80972300000002,67.2102660000001],[-64.81610099999989,67.20694000000009],[-64.81304899999998,67.20138500000002],[-64.808044,67.19802900000013],[-64.80139200000002,67.19525099999998],[-64.78332499999993,67.19026200000002],[-64.77278100000001,67.18969699999997],[-64.758896,67.19081099999994],[-64.71665999999999,67.2002720000001],[-64.65583800000002,67.21720900000014],[-64.46665999999999,67.22915600000005],[-64.42527799999993,67.22804300000001],[-64.35078399999998,67.2347640000001],[-64.28744499999999,67.23825799999997],[-64.267113,67.24142500000005],[-64.23277299999995,67.25143400000002],[-64.16944899999999,67.26081800000003],[-64.15888999999993,67.26249700000005],[-64.11471599999999,67.26721200000009],[-64.010559,67.27526900000004],[-63.976944,67.27777100000009],[-63.969993999999986,67.27748100000008],[-63.965836000000024,67.27554299999997],[-63.96277599999996,67.27249100000006],[-63.96277599999996,67.270264],[-63.97582999999992,67.251938],[-63.993056999999965,67.22831700000012],[-63.998336999999935,67.22164900000013],[-64.01333599999998,67.21220400000004],[-64.02139299999999,67.20887800000003],[-64.04527299999995,67.20471199999997],[-64.05610699999994,67.2044370000001],[-64.08860800000002,67.20776400000005],[-64.22022200000004,67.20171400000004],[-64.46749899999992,67.16748000000007],[-64.50140399999992,67.161652],[-64.54527299999995,67.15248100000002],[-64.57501199999996,67.14471400000008],[-64.58416699999992,67.14221200000003],[-64.61193800000001,67.13247700000011],[-64.65805099999994,67.11303700000013],[-64.68083199999995,67.09304800000001],[-64.686935,67.08749399999999],[-64.68998699999992,67.08360299999993],[-64.69249000000002,67.07804899999996],[-64.70056199999999,67.01805100000007],[-64.70111099999991,67.01220700000005],[-64.70056199999999,67.00804099999999],[-64.69694500000003,67.00332600000013],[-64.69193999999999,67.00054900000003],[-64.68306000000001,67.0002750000001],[-64.660278,67.00387599999999],[-64.63861099999997,67.00860600000004],[-64.62832599999996,67.01220700000005],[-64.62388599999991,67.01805100000007],[-64.61972000000003,67.02832000000012],[-64.61805700000002,67.03942899999998],[-64.61805700000002,67.04443400000008],[-64.61972000000003,67.04971300000005],[-64.61888099999999,67.05525200000005],[-64.61527999999993,67.06694000000005],[-64.60916099999997,67.08194000000003],[-64.604172,67.08831799999996],[-64.59777799999989,67.09387200000015],[-64.58361799999989,67.10304300000013],[-64.54750100000001,67.11859099999992],[-64.52722199999988,67.124146],[-64.506393,67.12942500000003],[-64.47471599999994,67.13499500000006],[-64.22999599999997,67.16415400000005],[-64.08721899999995,67.17970300000013],[-64.008896,67.17886400000003],[-63.995551999999975,67.17942800000014],[-63.97138199999995,67.18220500000007],[-63.96055599999994,67.184418],[-63.92972600000002,67.1927490000001],[-63.91916699999996,67.19636500000013],[-63.912216,67.20054600000003],[-63.86222099999992,67.22581500000001],[-63.80750299999994,67.23915099999999],[-63.797500999999954,67.24026500000014],[-63.561942999999985,67.23692300000005],[-63.54639400000002,67.23580900000007],[-63.46944399999995,67.22831700000012],[-63.45833600000003,67.22608899999994],[-63.45055400000001,67.22248800000011],[-63.449164999999994,67.21943700000008],[-63.449164999999994,67.21499599999999],[-63.45083599999998,67.17970300000013],[-63.453888000000006,67.16943400000014],[-63.52944200000002,67.10443100000003],[-63.53833800000001,67.10054000000014],[-63.604720999999984,67.07527200000004],[-63.61389200000002,67.07276900000005],[-63.64805599999988,67.06694000000005],[-63.672775,67.06359900000001],[-63.71277600000002,67.05497700000001],[-63.72277100000002,67.05192599999998],[-63.73138399999999,67.04803500000008],[-63.74444599999998,67.0410920000001],[-63.77972399999999,67.01748700000013],[-63.79583699999995,67.00665300000009],[-63.806389000000024,66.99581900000004],[-63.80721999999997,66.98803700000008],[-63.80139200000002,66.97970599999996],[-63.78138699999994,66.96360800000014],[-63.77249899999987,66.95887800000008],[-63.769447000000014,66.97137500000008],[-63.76888999999994,66.97692900000004],[-63.77111100000002,66.98081999999994],[-63.77249899999987,66.98609899999991],[-63.77361300000001,66.99108899999999],[-63.773330999999985,66.99609400000003],[-63.77083600000003,67.00138900000007],[-63.76721999999995,67.00610400000011],[-63.75695000000002,67.01416],[-63.750557000000015,67.01748700000013],[-63.73444399999994,67.02415500000012],[-63.69860799999998,67.03887899999995],[-63.68000000000001,67.04582199999999],[-63.65083299999998,67.05247500000013],[-63.63833599999998,67.05442800000009],[-63.60083799999995,67.05748],[-63.565552000000025,67.06248500000004],[-63.53527799999995,67.07083100000011],[-63.49722299999996,67.08526600000005],[-63.40277900000001,67.14444000000015],[-63.39639299999999,67.15220600000004],[-63.39416499999993,67.15693699999997],[-63.39388999999994,67.161652],[-63.398056,67.165817],[-63.41694599999988,67.18026700000007],[-63.419997999999964,67.18580600000007],[-63.42194399999988,67.194702],[-63.42083699999995,67.2002720000001],[-63.417778,67.20610000000005],[-63.40916399999992,67.21665999999999],[-63.351669000000015,67.26805100000001],[-63.340553,67.27665700000011],[-63.33250399999997,67.28193700000003],[-63.298888999999974,67.29776000000004],[-63.28055599999993,67.30636600000014],[-63.27249899999998,67.30941800000005],[-63.16027799999995,67.32832300000001],[-63.13722200000001,67.3311000000001],[-63.11028299999987,67.32998700000002],[-63.03972599999986,67.30609099999992],[-63.022498999999925,67.29803500000008],[-63.01500699999997,67.29359399999998],[-62.99777999999998,67.28137200000015],[-62.992774999999995,67.27638200000013],[-62.97388499999988,67.23553500000014],[-62.97083299999997,67.22581500000001],[-62.97083299999997,67.22137500000002],[-63.023056,67.17942800000014],[-63.03583499999996,67.17109700000003],[-63.04472399999986,67.16720599999996],[-63.075561999999934,67.15887500000008],[-63.100554999999986,67.15554800000012],[-63.13417099999998,67.15277100000003],[-63.17027999999999,67.14721700000007],[-63.19027699999998,67.143326],[-63.232497999999964,67.13220200000006],[-63.24250000000001,67.12914999999998],[-63.26888999999994,67.11747700000012],[-63.27583299999998,67.11331200000012],[-63.284447,67.105255],[-63.285278000000005,67.099716],[-63.283615,67.09498600000012],[-63.27805299999994,67.09082000000006],[-63.26860799999997,67.08248899999995],[-63.26083399999999,67.07415800000007],[-63.25389100000001,67.06469700000008],[-63.224716,67.02470400000004],[-63.22027600000001,67.0169370000001],[-63.22027600000001,67.00610400000011],[-63.22083299999997,66.98969999999997],[-63.22138199999995,66.98498499999994],[-63.223884999999996,66.97943099999998],[-63.227776000000006,66.97276299999999],[-63.240837,66.96165500000001],[-63.27777900000001,66.94970699999993],[-63.32055700000001,66.94026200000008],[-63.356109999999944,66.93470800000006],[-63.36860699999994,66.93470800000006],[-63.43638599999997,66.92553700000013],[-63.469993999999986,66.9205320000001],[-63.514725,66.91249099999999],[-63.526138,66.90927100000005],[-63.545554999999865,66.90359500000005],[-63.554442999999935,66.899719],[-63.565552000000025,66.89248700000007],[-63.565552000000025,66.88804600000014],[-63.56361399999997,66.88360599999993],[-63.557503,66.875809],[-63.554717999999866,66.87025499999999],[-63.55139200000002,66.86053500000008],[-63.55555700000002,66.84887700000007],[-63.57194499999997,66.83749400000005],[-63.59332999999992,66.83166500000004],[-63.615005,66.82720899999998],[-63.63889299999988,66.82443200000006],[-63.65222199999988,66.82388300000008],[-63.69860799999998,66.822495],[-63.725273000000016,66.82304399999998],[-63.77583299999992,66.82582100000002],[-63.77138499999995,66.81109600000008],[-63.653053,66.80247500000002],[-63.62444299999993,66.80192600000004],[-63.598334999999906,66.80304000000001],[-63.58777600000002,66.80442800000014],[-63.54888900000003,66.8124850000001],[-63.539443999999946,66.81469700000014],[-63.53527799999995,66.81581100000011],[-63.488891999999964,66.82832300000013],[-63.47888199999994,66.83581500000008],[-63.47638699999993,66.839157],[-63.47527299999996,66.84248400000013],[-63.476944,66.84693900000013],[-63.48722099999998,66.85887100000008],[-63.49471999999997,66.86553999999995],[-63.49694799999986,66.88081400000004],[-63.48722099999998,66.89694200000008],[-63.48082699999998,66.90248100000008],[-63.474441999999954,66.90609699999993],[-63.45610799999997,66.91081199999996],[-63.441666,66.9083250000001],[-63.427223000000026,66.90138200000013],[-63.407219,66.81442300000003],[-63.40777600000001,66.809708],[-63.410278000000005,66.7999880000001],[-63.41471899999999,66.78332500000005],[-63.417778,66.77304099999998],[-63.436110999999926,66.72804300000007],[-63.449439999999925,66.71609500000005],[-63.453056000000004,66.71165500000006],[-63.45194199999992,66.70637499999998],[-63.44193999999993,66.70304899999996],[-63.420279999999934,66.69886800000006],[-63.415276000000006,66.70054600000014],[-63.408332999999914,66.70443700000004],[-63.40277900000001,66.70887800000014],[-63.37666300000001,66.73414600000007],[-63.32028200000002,66.81414800000005],[-63.31945000000002,66.81999200000001],[-63.224716,66.899429],[-62.97388499999988,66.96110499999998],[-62.96250199999997,66.96388200000007],[-62.93999499999995,66.96666000000005],[-62.87222300000002,66.9644320000001],[-62.84694699999994,66.96192900000011],[-62.83777600000002,66.95776400000011],[-62.82111400000002,66.83027600000008],[-62.82055700000001,66.81359900000007],[-62.82749899999993,66.78804000000008],[-62.82972699999999,66.78332500000005],[-62.83750199999997,66.771927],[-62.84332999999998,66.76914999999991],[-62.86444899999998,66.74609400000008],[-62.86999500000002,66.73970000000003],[-62.87305500000002,66.73359700000009],[-62.91194200000001,66.65277100000014],[-62.914444,66.64721699999996],[-62.90805099999994,66.63998400000014],[-62.90305299999994,66.63720700000005],[-62.899726999999984,66.63665800000012],[-62.85916900000001,66.65304599999996],[-62.85028099999994,66.65693700000003],[-62.83527400000003,66.66638200000011],[-62.819999999999936,66.68441800000011],[-62.73416899999995,66.79081699999995],[-62.73583199999996,66.80165100000005],[-62.74333199999995,66.8099820000001],[-62.751113999999916,66.81805400000007],[-62.76805899999994,66.83055100000007],[-62.77417000000003,66.84054600000002],[-62.768332999999984,66.907761],[-62.764449999999954,66.92526200000009],[-62.76111599999996,66.92915299999999],[-62.74305700000002,66.94192499999997],[-62.725273000000016,66.94747899999999],[-62.63417099999998,66.95138500000007],[-62.60777999999999,66.95220900000004],[-62.59222399999993,66.95082100000013],[-62.57861299999996,66.94775400000003],[-62.56889299999989,66.94413800000012],[-62.54999499999997,66.93165599999998],[-62.51999699999993,66.91110200000003],[-62.40277900000001,66.809418],[-62.401389999999935,66.80497700000006],[-62.40193899999997,66.78915400000005],[-62.39861300000001,66.78027299999991],[-62.393332999999984,66.77581800000007],[-62.32695000000001,66.73027000000013],[-62.31945000000002,66.72637900000007],[-62.313332,66.7269290000001],[-62.299171,66.73304700000006],[-62.291388999999924,66.7563780000001],[-62.292778,66.76165800000001],[-62.295837000000006,66.766388],[-62.36222099999998,66.81832900000012],[-62.419448999999986,66.84332300000005],[-62.42472099999998,66.84748800000006],[-62.426948999999865,66.85137899999995],[-62.436942999999985,66.88443000000012],[-62.42722299999997,66.92109700000009],[-62.41889199999997,66.9266510000001],[-62.407501000000025,66.92942800000003],[-62.394721999999945,66.92915299999999],[-62.346946999999886,66.93359400000008],[-62.28472899999991,66.94609100000008],[-62.27166699999998,66.96081500000014],[-62.27972399999993,66.9791560000001],[-62.291388999999924,67.00582900000012],[-62.294448999999986,67.02137800000003],[-62.29361699999998,67.02638200000001],[-62.29028299999999,67.032486],[-62.28527799999995,67.03610200000008],[-62.27860999999996,67.03942899999998],[-62.262504999999976,67.04525800000005],[-62.10139499999997,67.05470300000007],[-62.05444299999988,67.04914900000011],[-62.03194400000001,67.04525800000005],[-62.019721999999945,67.04220600000008],[-62.00556199999994,67.0352630000001],[-62.00695000000002,67.03193700000008],[-62.04999499999991,66.98719800000009],[-62.10611,66.91720600000002],[-62.102225999999916,66.91304000000014],[-62.072227,66.90748600000012],[-62.02972399999999,66.90165700000011],[-62.01888999999994,66.90165700000011],[-62.01860799999997,66.9080350000001],[-62.01500699999991,66.91415400000011],[-61.95666499999993,66.96388200000007],[-61.94972200000001,66.96720899999997],[-61.93860599999999,66.96943699999997],[-61.91332999999997,66.97082500000005],[-61.86555499999997,66.97082500000005],[-61.851395000000025,66.97053500000004],[-61.83805099999995,66.9685970000001],[-61.74972500000001,66.94802900000002],[-61.73722099999998,66.94108600000004],[-61.731941000000006,66.93691999999993],[-61.72888199999994,66.93220500000007],[-61.73082699999986,66.92387400000001],[-61.61277799999999,66.87081899999993],[-61.31416300000001,66.68719500000003],[-61.29472399999992,66.67442299999999],[-61.289443999999946,66.669983],[-61.281386999999995,66.66110200000003],[-61.262504999999976,66.62942500000008],[-61.26666299999994,66.62275699999992],[-61.300277999999935,66.59359700000005],[-61.34166700000003,66.57193000000001],[-61.348052999999936,66.57054100000005],[-61.35666699999996,66.57110600000004],[-61.38833599999998,66.578598],[-61.40027599999996,66.57720899999998],[-61.409720999999934,66.572769],[-61.425003000000004,66.55970800000006],[-61.447776999999974,66.53831500000013],[-61.46166999999997,66.54332],[-61.54861499999987,66.547485],[-61.584723999999994,66.54776000000004],[-61.59860999999995,66.55026200000009],[-61.618056999999965,66.55720500000007],[-61.623885999999914,66.56693999999999],[-61.63194299999998,66.58665499999995],[-61.63861099999997,66.59553499999998],[-61.64389,66.5999910000001],[-61.66916699999996,66.616379],[-61.69138299999997,66.62831100000011],[-61.72582999999986,66.64305100000007],[-61.734443999999996,66.645828],[-61.95055400000001,66.67692599999998],[-62.01555599999995,66.67137100000008],[-62.12388599999997,66.626373],[-62.05055199999998,66.6249850000001],[-62.01860799999997,66.64082300000013],[-61.990837,66.64804100000009],[-61.97999599999997,66.64804100000009],[-61.95055400000001,66.64610299999998],[-61.830284000000006,66.62136800000013],[-61.79695099999998,66.61192300000005],[-61.788895000000025,66.60859700000003],[-61.75389100000001,66.58859300000012],[-61.576667999999984,66.48719800000003],[-61.57527900000002,66.48275799999999],[-61.576392999999996,66.47720300000009],[-61.58332799999994,66.47164900000013],[-61.59194199999996,66.46775800000006],[-61.61416600000001,66.46304300000003],[-61.63500199999993,66.45999100000006],[-61.731383999999935,66.45109600000006],[-61.844161999999926,66.44609100000002],[-61.857779999999934,66.447205],[-61.86972000000003,66.44581599999998],[-61.956947000000014,66.42414900000011],[-61.976943999999946,66.41748000000007],[-61.985832000000016,66.41360500000008],[-61.98694599999993,66.41026299999999],[-61.978049999999996,66.40386999999998],[-61.96416499999998,66.40138200000001],[-61.93416599999989,66.40081800000007],[-61.75500499999998,66.40748600000006],[-61.578612999999905,66.41526800000003],[-61.569449999999904,66.41554300000001],[-61.55726600000003,66.413681],[-61.54527999999999,66.40998800000011],[-61.46694200000002,66.37191800000005],[-61.46250199999997,66.36914100000013],[-61.46361499999989,66.365814],[-61.665276000000006,66.324997],[-61.87749499999995,66.28332499999993],[-61.92888599999998,66.28387499999997],[-62.19888300000002,66.3141480000001],[-62.207503999999915,66.31666600000011],[-62.21221899999995,66.31944299999998],[-62.21805599999993,66.33193999999997],[-62.231941000000006,66.36608900000004],[-62.23221599999994,66.36970500000007],[-62.22943900000001,66.37525900000009],[-62.22499800000003,66.38026400000012],[-62.21860499999997,66.39248700000002],[-62.21832999999987,66.39665200000002],[-62.22361000000001,66.40109300000012],[-62.22999600000003,66.40415999999999],[-62.255279999999914,66.40832499999999],[-62.26889,66.409424],[-62.41861,66.42109700000003],[-62.456107999999915,66.42387400000013],[-62.565833999999995,66.42804000000001],[-62.626662999999894,66.426086],[-62.69888300000002,66.41276600000009],[-62.709723999999994,66.41053799999997],[-62.716110000000015,66.40721100000002],[-62.71028100000001,66.403595],[-62.673614999999984,66.39360000000005],[-62.629996999999946,66.38777199999998],[-62.478049999999996,66.36998000000011],[-62.33750199999997,66.31581100000005],[-62.32028200000002,66.3083190000001],[-62.31610899999998,66.30497700000001],[-62.32055699999995,66.299713],[-62.323616000000015,66.29803500000008],[-62.38889299999994,66.276093],[-62.398338000000024,66.27304100000009],[-62.62194099999999,66.22137500000002],[-62.64361599999995,66.21693399999992],[-62.66694599999994,66.21443200000004],[-62.68083200000001,66.21693399999992],[-62.75194499999992,66.24108899999993],[-62.757225000000005,66.24525500000004],[-62.78055599999993,66.27777100000014],[-62.782218999999884,66.282486],[-62.782218999999884,66.28887900000012],[-62.773330999999985,66.29693600000007],[-62.77417000000003,66.30276500000014],[-62.77944199999996,66.30720500000012],[-62.79722599999997,66.31387300000011],[-62.81666599999994,66.32083100000011],[-62.82611099999991,66.32415800000001],[-62.85889400000002,66.33415200000007],[-62.86805700000002,66.33610499999998],[-62.881110999999976,66.33581500000014],[-62.88999899999999,66.33332800000011],[-62.895003999999915,66.32971200000003],[-62.80944099999999,66.24081400000011],[-62.801391999999964,66.23525999999993],[-62.71500399999991,66.20166000000006],[-62.70610799999997,66.1997070000001],[-62.681389000000024,66.19693000000001],[-62.647223999999994,66.1997070000001],[-62.60361499999999,66.20526100000012],[-62.488051999999925,66.20027199999993],[-62.366660999999965,66.17498799999998],[-62.18055700000002,66.14860499999998],[-62.03750599999995,66.10081500000001],[-61.9611129999999,66.03387500000002],[-61.95500199999998,66.02415500000012],[-61.95444500000002,66.01915000000008],[-61.95583299999993,66.01499899999999],[-61.960280999999895,66.01193200000006],[-61.975554999999986,66.01054399999998],[-62.088889999999935,66.00027499999993],[-62.13361400000002,66.00000000000011],[-62.148056,66.00138900000013],[-62.16638899999998,66.00749200000007],[-62.17250100000001,66.01054399999998],[-62.18888900000002,66.0122070000001],[-62.196663,66.01110800000009],[-62.291672000000005,65.98027000000013],[-62.30777699999999,65.97387699999996],[-62.39166999999986,66.01138300000014],[-62.404715999999894,66.01470899999998],[-62.52527600000002,66.03414900000013],[-62.54138899999998,66.03553799999997],[-62.69554900000003,66.04220599999996],[-62.74111199999993,66.03831500000007],[-62.759726999999884,66.03305100000006],[-62.778885,66.03332499999999],[-62.799995000000024,66.03970300000015],[-62.80916599999989,66.04386900000003],[-62.83167299999997,66.05554200000006],[-62.84222399999999,66.06414799999999],[-62.84694699999994,66.06915300000003],[-62.85500300000001,66.083054],[-62.856667000000016,66.08749400000005],[-62.86000100000001,66.10304300000013],[-62.8663939999999,66.11276199999998],[-62.87332900000001,66.12136800000007],[-62.88417099999987,66.12997399999995],[-62.90555599999999,66.14082300000001],[-62.93055700000002,66.14694200000008],[-62.94694500000003,66.14860499999998],[-62.95944199999991,66.14888000000002],[-62.970551,66.14804100000003],[-63.01361800000001,66.13888500000007],[-63.041672000000005,66.13026400000001],[-63.06194299999993,66.1208190000001],[-63.06027999999998,66.11637900000011],[-63.03944399999989,66.11331200000001],[-63.006393,66.11692800000003],[-62.892226999999934,66.07666],[-62.88999899999999,66.06637599999993],[-62.88583399999999,66.05636600000003],[-62.875,66.0477600000001],[-62.86222099999986,66.03942900000004],[-62.84194200000002,66.02748099999997],[-62.82666799999993,66.02026400000005],[-62.81583399999994,66.016098],[-62.79361699999998,66.01081800000009],[-62.778885,66.00972000000002],[-62.768332999999984,66.00972000000002],[-62.755561999999884,66.00999500000006],[-62.743889000000024,66.01138300000014],[-62.67472099999992,66.01554900000002],[-62.523056,66.0022130000001],[-62.51721999999995,66.00054900000009],[-62.4183349999999,65.97053500000004],[-62.40555599999993,65.96304300000008],[-62.395003999999915,65.949997],[-62.386664999999994,65.93664600000005],[-62.32111400000002,65.83110000000005],[-62.317222999999956,65.80802900000003],[-62.44166599999994,65.7935940000001],[-62.478882,65.790817],[-62.50527999999997,65.790817],[-62.52138499999995,65.79248000000013],[-62.60417199999989,65.801086],[-62.61999500000002,65.80304000000007],[-62.684440999999936,65.81637599999999],[-62.71777300000002,65.8252720000001],[-62.72721899999999,65.828598],[-62.72999600000003,65.83194000000009],[-62.75278499999996,65.85359199999994],[-62.80750299999994,65.88998400000014],[-62.82944500000002,65.89999400000005],[-62.857506,65.91110200000003],[-62.86416600000001,65.91110200000003],[-62.87055199999992,65.90554800000001],[-62.871940999999936,65.90138200000013],[-62.87471800000003,65.88749700000005],[-62.87471800000003,65.8830410000001],[-62.760001999999986,65.816666],[-62.74639100000002,65.809708],[-62.73694599999993,65.80831900000004],[-62.71999399999993,65.809708],[-62.658889999999985,65.79193099999998],[-62.597778000000005,65.77192700000006],[-62.58222199999989,65.76554900000008],[-62.575004999999976,65.76165800000001],[-62.56944999999996,65.75749200000013],[-62.56861099999992,65.75221299999993],[-62.569725000000005,65.74664300000006],[-62.579444999999964,65.72831700000006],[-62.58361099999996,65.72331200000002],[-62.58777599999996,65.720261],[-62.59027900000001,65.71914700000002],[-62.59944200000001,65.71887200000015],[-62.61277799999999,65.72164900000007],[-62.62194099999999,65.72554000000014],[-62.67472099999992,65.73580900000002],[-62.823891,65.76138300000002],[-62.833442999999875,65.75299100000001],[-62.83377799999988,65.74999200000002],[-62.82878099999988,65.7444920000001],[-62.79917099999989,65.711929],[-62.78805499999993,65.70832800000011],[-62.72638699999999,65.71138000000002],[-62.69888300000002,65.71026600000005],[-62.681670999999994,65.7080380000001],[-62.6627729999999,65.701096],[-62.59944200000001,65.67581200000001],[-62.59194199999996,65.67192099999994],[-62.58972199999994,65.66859400000004],[-62.59583299999986,65.65220599999998],[-62.60222599999997,65.64027399999998],[-62.611670999999944,65.62414599999994],[-62.61749999999989,65.61499000000003],[-62.62805199999997,65.6019290000001],[-62.645279000000016,65.58720399999993],[-62.653053,65.58610499999998],[-62.751113999999916,65.58526599999999],[-62.76722000000001,65.58749399999994],[-62.78472899999997,65.59137000000004],[-62.80305499999997,65.59887700000013],[-62.85972600000002,65.63472000000002],[-62.86138900000003,65.63916],[-62.85861199999994,65.65525800000006],[-62.862503000000004,65.68525700000009],[-62.882998999999984,65.72415200000006],[-62.885001999999986,65.72697399999993],[-62.88799999999986,65.72965200000004],[-62.90416700000003,65.74636800000002],[-62.922500999999954,65.75221299999993],[-62.936110999999926,65.75499000000002],[-62.949439999999925,65.75526399999995],[-62.95944199999991,65.75387600000005],[-62.962219000000005,65.74832200000009],[-62.94361099999992,65.743042],[-62.93472300000002,65.73887600000012],[-62.92527799999999,65.73109399999998],[-62.91666399999991,65.72221400000012],[-62.914444,65.71832300000005],[-62.892226999999934,65.6419370000001],[-62.89166999999992,65.63832100000008],[-62.89583600000003,65.63304099999999],[-62.901389999999935,65.62803600000012],[-62.95333099999999,65.58692900000011],[-62.96167000000003,65.58305400000012],[-62.972220999999934,65.580826],[-63.005004999999926,65.6249850000001],[-63.01611300000002,65.63275099999998],[-63.02749599999993,65.63581800000009],[-63.04028299999993,65.63749700000011],[-63.13777900000002,65.64415000000008],[-63.16249800000003,65.63247700000005],[-63.16240699999997,65.62886800000007],[-63.164443999999946,65.62553400000007],[-63.17861199999999,65.62747200000001],[-63.20027900000002,65.633331],[-63.211945000000014,65.64054900000002],[-63.29389199999997,65.70887800000014],[-63.43638599999997,65.84526100000005],[-63.44305400000002,65.85470599999991],[-63.47416700000002,65.83305400000006],[-63.379166,65.720261],[-63.36833200000001,65.69386300000002],[-63.36833200000001,65.66943400000008],[-63.399726999999984,65.67637599999995],[-63.412215999999944,65.67804000000001],[-63.44860799999992,65.68081700000005],[-63.46194499999996,65.68109099999998],[-63.70472000000001,65.68220500000001],[-63.71721600000001,65.68165600000003],[-63.723609999999894,65.68026700000001],[-63.72860700000001,65.67581200000001],[-63.728882,65.67303500000014],[-63.723609999999894,65.66886900000003],[-63.700553999999954,65.65582300000011],[-63.68360899999999,65.65081800000007],[-63.67166900000001,65.64833099999998],[-63.50472300000001,65.6308140000001],[-63.45333099999999,65.62970000000013],[-63.432503,65.63192700000002],[-63.399726999999984,65.63415500000013],[-63.375,65.632202],[-63.36860699999994,65.6291500000001],[-63.351669000000015,65.61775200000011],[-63.326667999999984,65.60081500000007],[-63.319999999999936,65.593323],[-63.33666199999993,65.55693099999996],[-63.34332999999998,65.54832500000009],[-63.35500300000001,65.53776600000003],[-63.35972600000002,65.53610200000003],[-63.37361099999998,65.53387499999997],[-63.46333299999998,65.52276600000005],[-63.47471599999989,65.52360500000003],[-63.48221599999994,65.52526900000004],[-63.488609,65.52832000000006],[-63.501396,65.53637700000002],[-63.523056,65.55081200000012],[-63.5327759999999,65.55859400000008],[-63.541114999999934,65.57026700000011],[-63.54138899999987,65.57415800000001],[-63.54666900000001,65.5811000000001],[-63.561278999999956,65.58537299999995],[-63.567943999999954,65.5900420000001],[-63.572449000000006,65.59120900000005],[-63.58127999999999,65.59187300000008],[-63.589943000000005,65.59120900000005],[-63.59577899999999,65.58903500000008],[-63.60889400000002,65.58998100000002],[-63.61833199999995,65.54193100000003],[-63.61666099999991,65.53749099999999],[-63.61277799999988,65.5333250000001],[-63.601395000000025,65.53027300000002],[-63.530280999999945,65.51220699999999],[-63.43277699999993,65.48442100000011],[-63.39194500000002,65.47248800000011],[-63.362503000000004,65.46331800000002],[-63.30916599999995,65.44552599999997],[-63.3016659999999,65.4416500000001],[-63.29527999999999,65.43637100000012],[-63.290839999999946,65.43165600000009],[-63.292778,65.42886399999998],[-63.39388999999994,65.42526200000003],[-63.40999599999992,65.42665100000005],[-63.46888699999994,65.43969700000014],[-63.49527699999999,65.4502720000001],[-63.50278500000002,65.454163],[-63.52166699999998,65.46110500000009],[-63.5327759999999,65.46470599999998],[-63.55332900000002,65.46887200000003],[-63.568892999999946,65.47164900000013],[-63.583327999999995,65.4727630000001],[-63.64305899999988,65.47360200000008],[-63.65444199999996,65.47221399999995],[-63.65555599999993,65.47082499999999],[-63.65471600000001,65.46499599999999],[-63.62749499999995,65.45582600000012],[-63.56361399999997,65.43580600000007],[-63.483611999999994,65.40498400000001],[-63.335556,65.30053700000002],[-63.335830999999985,65.29553199999992],[-63.42472099999998,65.22943099999998],[-63.472220999999934,65.19636500000001],[-63.41889200000003,65.145264],[-63.37694499999998,65.11080900000002],[-63.42444599999993,65.04914900000011],[-63.46472199999994,65.01805100000013],[-63.527221999999995,64.97192400000006],[-63.52833599999997,64.967758],[-63.54695099999998,64.88720700000005],[-63.653885,64.91165200000006],[-63.659720999999934,64.93969700000008],[-63.74777999999998,64.96220399999999],[-63.82417299999997,64.98471100000006],[-63.82833900000003,65.01081799999992],[-63.82556199999988,65.01277199999998],[-63.72027600000001,65.03082300000011],[-63.66972399999992,65.03498800000011],[-63.65999599999998,65.03637700000013],[-63.655272999999966,65.03804000000008],[-63.658051,65.04109199999999],[-63.664718999999934,65.04359400000004],[-63.685554999999965,65.04775999999998],[-63.697776999999974,65.04942300000005],[-63.732215999999994,65.04887400000013],[-63.75194499999998,65.04525800000005],[-63.78221899999994,65.03414900000001],[-63.801941,65.03027300000008],[-63.82444799999996,65.02748100000002],[-63.849723999999924,65.03027300000008],[-63.861114999999984,65.03332500000005],[-63.87055199999992,65.04081699999995],[-63.873885999999914,65.04553199999998],[-63.87555699999996,65.05026200000003],[-63.885559,65.07998700000013],[-63.886116000000015,65.08581500000003],[-63.881667999999934,65.09693900000013],[-63.94860799999998,65.10054000000002],[-64.12110899999993,65.04386900000009],[-64.13249199999996,65.04443400000008],[-64.14083900000003,65.047211],[-64.26722699999999,65.09414700000002],[-64.27583300000003,65.09887700000007],[-64.271118,65.10331700000006],[-64.22193900000002,65.14694200000008],[-64.20889299999999,65.155258],[-64.18582200000003,65.16387900000007],[-64.16722099999993,65.17053200000004],[-64.13110399999994,65.18248000000011],[-64.12971500000003,65.19358800000009],[-64.20361300000002,65.1997070000001],[-64.2119449999999,65.19999699999994],[-64.23138399999999,65.19693000000001],[-64.301941,65.16304000000014],[-64.30999799999995,65.15914900000007],[-64.31471299999998,65.15248100000008],[-64.33917200000002,65.16137700000002],[-64.37332200000003,65.17720000000003],[-64.38082899999989,65.1810910000001],[-64.39584400000001,65.20721400000008],[-64.40722700000003,65.27581800000002],[-64.40527299999991,65.28553799999992],[-64.40278599999994,65.2910920000001],[-64.39862099999993,65.29693600000013],[-64.389725,65.30442800000009],[-64.35583500000001,65.324997],[-64.333328,65.33720399999999],[-64.30999799999995,65.34999099999999],[-64.30055199999998,65.35582],[-64.25556899999998,65.38638299999997],[-64.25083899999987,65.39082300000001],[-64.23638900000003,65.421921],[-64.23416099999997,65.42719999999997],[-64.237213,65.42997700000006],[-64.24888599999991,65.43054200000012],[-64.27278100000001,65.42858899999999],[-64.29110700000001,65.42248499999994],[-64.43138099999999,65.32693499999999],[-64.46167000000003,65.294983],[-64.47166400000003,65.28332499999999],[-64.47471599999994,65.27249100000012],[-64.46888699999994,65.26388500000002],[-64.46389799999997,65.25888100000003],[-64.456955,65.24942000000004],[-64.45249899999999,65.2416530000001],[-64.45556599999998,65.20721400000008],[-64.46221899999995,65.190811],[-64.4683379999999,65.18026700000013],[-64.50973499999992,65.12052900000009],[-64.52111799999994,65.10914600000012],[-64.53500400000001,65.09721400000012],[-64.54998799999998,65.09275800000006],[-64.55555699999996,65.09220900000008],[-64.56193499999995,65.094986],[-64.56750499999993,65.11581400000006],[-64.56750499999993,65.11998],[-64.56945799999994,65.12441999999999],[-64.58000199999992,65.12886000000003],[-64.61138900000003,65.14193700000004],[-64.64111299999996,65.14999399999999],[-64.65527299999997,65.16609200000005],[-64.71833800000002,65.22248799999994],[-64.76028400000001,65.25221300000004],[-64.76501499999995,65.24775699999998],[-64.77833599999997,65.238586],[-64.78832999999992,65.23414600000001],[-64.80110200000001,65.23082000000011],[-64.81471299999998,65.23525999999998],[-64.864441,65.25665300000009],[-64.883896,65.26527399999998],[-64.89111300000002,65.26915000000008],[-64.89666699999998,65.27331500000008],[-64.898346,65.27581800000002],[-64.910553,65.29942299999999],[-64.91082799999998,65.3035890000001],[-64.91000400000001,65.30497700000001],[-64.85588799999994,65.31454500000012],[-64.83422899999994,65.31904600000001],[-64.82338700000003,65.31821400000013],[-64.79611199999994,65.31860400000005],[-64.79388399999999,65.31469700000008],[-64.78639199999998,65.31080600000001],[-64.777222,65.30914300000012],[-64.75717199999991,65.31309500000003],[-64.75217399999991,65.31425500000012],[-64.69610599999987,65.32971200000003],[-64.691101,65.33194000000003],[-64.68720999999994,65.33499100000006],[-64.685272,65.33749399999999],[-64.68443300000001,65.34109500000005],[-64.68916299999995,65.3416600000001],[-64.79972800000002,65.34693900000008],[-64.81361399999997,65.34721400000006],[-64.86805699999996,65.33970600000009],[-64.89778099999995,65.33415200000007],[-64.90916399999998,65.33471700000013],[-64.912216,65.33804299999997],[-64.910553,65.33998100000008],[-64.90472399999999,65.34359699999993],[-64.60916099999997,65.426376],[-64.59111000000001,65.42970300000013],[-64.58389299999999,65.43026700000007],[-64.50834700000001,65.42581200000006],[-64.47721899999999,65.42109700000003],[-64.46640000000002,65.41748000000007],[-64.45834399999995,65.4166560000001],[-64.44860799999998,65.41831999999994],[-64.44193999999993,65.4202580000001],[-64.43360899999993,65.4291530000001],[-64.42999299999997,65.434418],[-64.40943900000002,65.47387700000007],[-64.41278099999994,65.4785920000001],[-64.41833500000001,65.48275800000005],[-64.4344329999999,65.48414600000012],[-64.551941,65.45776400000005],[-64.695267,65.42776500000002],[-64.79527300000001,65.41526800000003],[-64.80665599999992,65.41387900000001],[-64.82417299999986,65.41331500000007],[-64.833618,65.41442900000004],[-64.84388699999994,65.41720599999996],[-64.84555099999994,65.41943400000014],[-64.85499600000003,65.42275999999998],[-64.86389199999996,65.42469800000009],[-64.86971999999997,65.42387400000013],[-64.97416699999997,65.40470899999997],[-64.98111,65.4019320000001],[-64.98750299999995,65.39776599999999],[-64.99027999999993,65.3938750000001],[-64.98860200000001,65.37942499999997],[-64.98582499999992,65.37136800000002],[-64.98971599999999,65.36831699999999],[-65.00111399999992,65.36665299999999],[-65.01611299999996,65.36720300000002],[-65.05888399999998,65.3766480000001],[-65.07501200000002,65.38304100000005],[-65.136124,65.42248499999994],[-65.14416499999987,65.42776500000002],[-65.14999399999999,65.434143],[-65.16888399999999,65.48275800000005],[-65.16805999999997,65.48387100000008],[-65.16000399999996,65.48803700000002],[-65.14944500000001,65.49304200000006],[-65.14250199999992,65.49581899999998],[-65.12999000000002,65.49859600000002],[-65.11027499999994,65.49748200000005],[-65.08250399999997,65.50054899999998],[-64.92971799999992,65.52470399999999],[-64.854446,65.5836030000001],[-64.83694499999996,65.60581999999994],[-64.76722699999999,65.63998399999997],[-64.741669,65.641663],[-64.723053,65.64360000000005],[-64.71194499999996,65.64721700000001],[-64.70944199999991,65.65054300000003],[-64.71000700000002,65.65220599999998],[-64.71444699999995,65.65332000000012],[-64.76834099999996,65.65998800000011],[-64.79472399999997,65.66192600000005],[-64.81861899999996,65.66192600000005],[-64.82806399999993,65.66110200000008],[-64.84388699999994,65.65803499999998],[-64.85333300000002,65.65470900000014],[-64.87222299999996,65.64498900000001],[-64.88890100000003,65.6291500000001],[-64.89999399999994,65.616379],[-64.95249899999988,65.56442300000009],[-64.97416699999997,65.55137600000006],[-64.99360699999988,65.54803500000003],[-65.11027499999994,65.54109200000005],[-65.15306099999998,65.53915400000011],[-65.31111099999998,65.54887400000001],[-65.31834400000002,65.55053700000013],[-65.32640099999998,65.55636600000014],[-65.333328,65.56359900000012],[-65.33860799999997,65.57554600000009],[-65.308334,65.62109400000003],[-65.30332899999996,65.62831099999994],[-65.29998799999993,65.6308140000001],[-65.295837,65.63165300000009],[-65.27528399999994,65.63136300000008],[-65.252228,65.62997400000006],[-65.21777299999997,65.62997400000006],[-65.18859900000001,65.62997400000006],[-65.15388499999995,65.63026400000007],[-65.12582399999997,65.633331],[-65.112503,65.6372070000001],[-65.10583500000001,65.63943500000005],[-65.103882,65.64248700000013],[-65.103882,65.65193200000004],[-65.10943600000002,65.65887500000002],[-65.10694899999999,65.66720599999991],[-65.10583500000001,65.66859400000004],[-65.09973100000002,65.67192099999994],[-64.99444599999993,65.70138500000013],[-64.98138399999999,65.70471200000009],[-64.96972699999998,65.70665000000002],[-64.94221500000003,65.70915200000007],[-64.92250100000001,65.70942700000012],[-64.90249599999999,65.70860299999998],[-64.81471299999998,65.71276900000004],[-64.80332899999996,65.71415700000011],[-64.79834,65.71638500000012],[-64.79360999999989,65.71998599999995],[-64.791382,65.72331200000002],[-64.79499799999996,65.72804300000013],[-64.80194099999989,65.73027000000002],[-64.81555200000003,65.730545],[-64.90695199999999,65.7288670000001],[-64.973053,65.72360200000003],[-64.99694799999992,65.72137499999997],[-65.024719,65.71693400000004],[-65.05721999999997,65.71026600000005],[-65.07611099999991,65.70555100000001],[-65.10305800000003,65.69442700000013],[-65.11610399999995,65.68525700000009],[-65.13861099999997,65.67109699999997],[-65.144455,65.66748000000001],[-65.16416899999996,65.65693700000008],[-65.16833499999996,65.65609700000005],[-65.3699949999999,65.66110200000008],[-65.43138099999993,65.66914400000007],[-65.44166599999988,65.67164600000012],[-65.44999699999988,65.67498800000004],[-65.45445299999989,65.67831400000011],[-65.45695499999994,65.68220500000001],[-65.45639,65.68553199999991],[-65.45249899999993,65.69081100000011],[-65.447769,65.6952510000001],[-65.46028100000001,65.74136400000009],[-65.49027999999993,65.73580900000002],[-65.49777199999994,65.73748799999998],[-65.50556899999998,65.74331699999999],[-65.50500499999998,65.75166300000012],[-65.49888599999986,65.76304600000009],[-65.45527600000003,65.83248900000007],[-65.44915800000001,65.84109499999994],[-65.439438,65.8477630000001],[-65.35722399999997,65.90248099999991],[-65.15222199999994,65.95776400000011],[-65.137787,65.96110499999998],[-65.05027799999999,65.98054500000012],[-64.96389799999997,65.99859600000013],[-64.94610599999999,66.00138900000013],[-64.9347229999999,66.0022130000001],[-64.92304999999999,66.00138900000013],[-64.898346,65.99693300000001],[-64.88082899999995,65.98997500000002],[-64.85110499999996,65.98054500000012],[-64.84222399999993,65.97804300000007],[-64.80139200000002,65.96943699999997],[-64.77250699999996,65.96609500000005],[-64.75500499999993,65.96609500000005],[-64.74333200000001,65.96748400000001],[-64.73500100000001,65.96943699999997],[-64.73388699999992,65.97554000000008],[-64.73860199999996,65.97886700000004],[-64.76501499999995,65.98803700000008],[-64.82167099999998,66.04470800000001],[-64.75083899999993,66.18553200000002],[-64.72166399999998,66.21748399999996],[-64.712219,66.22360200000008],[-64.60583499999996,66.25915500000013],[-64.48055999999997,66.29637100000008],[-64.45195000000001,66.3035890000001],[-64.40556300000003,66.31581100000005],[-64.38861099999991,66.32165500000008],[-64.37554899999992,66.32720900000004],[-64.36582900000002,66.33305399999995],[-64.35638399999993,66.34054600000007],[-64.354172,66.34803800000003],[-64.35638399999993,66.34971599999994],[-64.366104,66.35081500000013],[-64.37748699999997,66.34999099999999],[-64.44387799999998,66.34471100000007],[-64.46472199999994,66.34304800000001],[-64.71444699999995,66.27499400000005],[-64.718887,66.27331500000003],[-64.78916899999996,66.23637400000013],[-64.79611199999994,66.23165900000009],[-64.83999599999999,66.19331399999999],[-64.85804699999994,66.14999399999999],[-64.85665899999998,66.13998400000008],[-64.851944,66.12498499999998],[-64.84973099999996,66.12052900000009],[-64.85417199999995,66.10971100000012],[-64.85888699999998,66.10609399999998],[-64.93388400000003,66.08027600000003],[-64.94860799999998,66.07693499999999],[-65.12609899999995,66.03776600000009],[-65.38194299999992,65.97581500000013],[-65.398056,65.97470099999992],[-65.827789,65.95304900000008],[-65.87638900000002,65.94802900000002],[-65.91610699999995,65.95109599999995],[-65.92805499999997,65.95387300000004],[-65.93554699999993,65.95832800000005],[-65.93971299999993,65.96249399999999],[-65.96305799999999,66.034424],[-65.96389799999992,66.04386900000003],[-65.91888399999993,66.08610500000003],[-65.91166699999985,66.0916600000001],[-65.90417500000001,66.09443700000003],[-65.78611799999999,66.12637300000011],[-65.674713,66.15748600000012],[-65.65055799999999,66.1644290000001],[-65.64083899999991,66.16832],[-65.63417099999992,66.172485],[-65.56416299999995,66.22692900000004],[-65.54554699999994,66.2433170000001],[-65.47111499999994,66.34248400000001],[-65.47166399999992,66.38360600000004],[-65.47361799999993,66.38581799999992],[-65.47582999999997,66.38777199999998],[-65.479172,66.38804600000009],[-65.48277300000001,66.38777199999998],[-65.48971599999999,66.38581799999992],[-65.50167799999991,66.37637300000006],[-65.55387899999994,66.32777400000009],[-65.55583199999995,66.32527200000004],[-65.55943300000001,66.3205410000001],[-65.5616609999999,66.31442300000015],[-65.564438,66.29359399999998],[-65.56277499999999,66.28831500000001],[-65.56277499999999,66.28332499999993],[-65.57167099999998,66.26832600000006],[-65.59889199999992,66.24498],[-65.61054999999988,66.23580900000007],[-65.69694499999997,66.18054200000012],[-65.70249899999999,66.17747500000002],[-65.84416199999993,66.13581799999997],[-65.926941,66.11470000000008],[-65.95195000000001,66.10887100000008],[-65.96833799999996,66.1080320000001],[-66.073624,66.12052900000009],[-66.13917499999997,66.13136299999996],[-66.14500399999997,66.1336060000001],[-66.14723200000003,66.13526900000005],[-66.20083599999998,66.19497700000005],[-66.19110099999995,66.23997499999996],[-66.25111400000003,66.24220300000013],[-66.37138400000003,66.22526600000009],[-66.401947,66.20082100000008],[-66.47833300000002,66.20166000000006],[-66.48971599999987,66.20277400000003],[-66.49694799999997,66.20498699999996],[-66.50500499999993,66.20887800000003],[-66.52444500000001,66.22415200000012],[-66.52999899999992,66.2291560000001],[-66.53416400000003,66.233047],[-66.54083299999996,66.2416530000001],[-66.54277000000002,66.24664300000012],[-66.57749899999999,66.35443099999998],[-66.57611099999997,66.35914600000001],[-66.57000700000003,66.36554000000007],[-66.56416299999995,66.36914100000013],[-66.53694200000001,66.37803599999995],[-66.500565,66.38804600000009],[-66.45472699999999,66.39804100000015],[-66.445267,66.40138200000001],[-66.43832399999991,66.40415999999999],[-66.43443300000001,66.40721100000002],[-66.43720999999994,66.41331500000007],[-66.44193999999999,66.41442900000004],[-66.4661099999999,66.41499299999998],[-66.47361799999999,66.41442900000004],[-66.48138399999999,66.41304000000002],[-66.597778,66.38693200000012],[-66.60499600000003,66.37637300000006],[-66.61000100000001,66.37136800000002],[-66.61749299999991,66.3685910000001],[-66.62999000000002,66.36775200000011],[-66.71389799999997,66.36886600000008],[-66.72416699999991,66.36943100000013],[-66.73083499999996,66.36998000000011],[-66.74305700000002,66.37275699999998],[-66.76777599999991,66.38053900000011],[-66.82167099999992,66.45803799999993],[-66.82167099999992,66.46081500000003],[-66.80638099999993,66.53193699999997],[-66.85194399999995,66.58332800000005],[-66.97222899999991,66.62886000000009],[-66.99972499999996,66.63832100000002],[-67.023056,66.64332600000006],[-67.03611799999993,66.64471400000002],[-67.04888900000003,66.64471400000002],[-67.05888400000003,66.64276100000006],[-67.06054699999999,66.64027399999998],[-67.05610699999994,66.63360599999999],[-67.04333499999996,66.62580900000006],[-67.01666299999994,66.61526500000002],[-66.95056199999988,66.59220900000014],[-66.90833999999995,66.57804900000008],[-66.8875119999999,66.56944299999998],[-66.88417099999987,66.56608600000004],[-66.88945000000001,66.56109600000013],[-67.10555999999997,66.48580900000002],[-67.11833199999995,66.48498500000005],[-67.13362099999995,66.48580900000002],[-67.17694099999994,66.48970000000008],[-67.18971299999993,66.49165300000004],[-67.19860799999998,66.49414100000001],[-67.202225,66.49720800000011],[-67.20388799999995,66.50526400000001],[-67.19221500000003,66.51527400000009],[-67.18611099999998,66.52442899999994],[-67.19027699999998,66.5291600000001],[-67.327225,66.59582500000005],[-67.33833299999998,66.59776299999999],[-67.34584000000001,66.59721400000001],[-67.39862099999988,66.58915700000006],[-67.41000399999996,66.58554099999998],[-67.46362299999998,66.57887300000004],[-67.515015,66.57360799999998],[-67.58111600000001,66.57527199999998],[-67.639725,66.58055100000013],[-67.72694399999989,66.57666000000006],[-67.737213,66.57415800000001],[-67.74082899999996,66.57110600000004],[-67.74276700000001,66.56832899999995],[-67.74194299999994,66.56414800000005],[-67.73500100000001,66.56137100000001],[-67.72277799999989,66.55802900000003],[-67.70111099999986,66.55581699999999],[-67.49999999999994,66.54483800000003],[-67.42610200000001,66.54136700000004],[-67.40777600000001,66.54220600000002],[-67.39584399999995,66.54470800000007],[-67.3805539999999,66.54582200000004],[-67.37388599999991,66.54582200000004],[-67.36582900000002,66.54443400000014],[-67.29638699999992,66.526093],[-67.28167699999995,66.51887499999998],[-67.14862099999999,66.44386300000002],[-67.14389,66.43775900000003],[-67.14361599999995,66.43553199999997],[-67.13806199999999,66.38220200000006],[-67.139725,66.37664800000005],[-67.16082799999998,66.36554000000007],[-67.17250100000001,66.36387600000006],[-67.18527199999994,66.36360200000013],[-67.197769,66.365814],[-67.29167199999989,66.39942900000005],[-67.33750900000001,66.41886900000009],[-67.33898899999991,66.42285200000009],[-67.34306300000003,66.42665099999999],[-67.35028099999994,66.42886399999998],[-67.36582900000002,66.42970300000013],[-67.38972499999994,66.4308170000001],[-67.406387,66.42970300000013],[-67.410553,66.42526200000003],[-67.41000399999996,66.42082199999999],[-67.383331,66.40193200000004],[-67.37832600000002,66.39860499999992],[-67.36860699999994,66.39471400000002],[-67.31361400000003,66.37637300000006],[-67.28860499999996,66.36886600000008],[-67.24082899999996,66.35887100000002],[-67.195831,66.35498000000013],[-67.18859899999995,66.35220300000003],[-67.13305700000001,66.31387300000011],[-67.12527499999999,66.30693100000002],[-67.12609900000001,66.305542],[-67.12916599999994,66.3035890000001],[-67.13944999999995,66.30137600000012],[-67.162216,66.29887400000007],[-67.18388400000003,66.29748500000005],[-67.19415300000003,66.29776000000004],[-67.208618,66.29998800000004],[-67.226944,66.30415300000004],[-67.24082899999996,66.30415300000004],[-67.25418100000002,66.30276500000014],[-67.26167299999997,66.29914900000006],[-67.28222699999998,66.27526900000004],[-67.29750100000001,66.276093],[-67.39917000000003,66.29248000000001],[-67.41389500000002,66.29664600000007],[-67.450287,66.31666600000011],[-67.45306399999993,66.3205410000001],[-67.45333900000003,66.32249500000012],[-67.49471999999997,66.35693400000014],[-67.52610800000002,66.38220200000006],[-67.5625,66.40748600000006],[-67.566666,66.409424],[-67.60305799999998,66.41859400000004],[-67.63417099999998,66.42469800000009],[-67.69082600000002,66.43525699999992],[-67.71305799999999,66.43609600000008],[-67.73028599999998,66.43997199999995],[-67.81249999999994,66.46304300000003],[-67.82528699999995,66.46775800000006],[-67.8286129999999,66.47082499999993],[-67.83473200000003,66.48332199999993],[-67.83860799999991,66.49165300000004],[-67.92361499999993,66.51609800000006],[-67.95249899999999,66.51470900000004],[-67.98582499999986,66.50972000000007],[-67.99276700000001,66.50694300000004],[-67.99276700000001,66.5038760000001],[-67.94471699999986,66.4788670000001],[-67.929169,66.47303800000009],[-67.906113,66.46804800000007],[-67.88694800000002,66.461929],[-67.87026999999995,66.45471200000009],[-67.76055899999994,66.35803200000004],[-67.75639299999995,66.353317],[-67.71112099999993,66.29693600000007],[-67.70140100000003,66.28471400000012],[-67.70167499999997,66.27832000000006],[-67.70556599999998,66.27526900000004],[-67.724716,66.26081800000003],[-67.67222599999997,66.22831700000012],[-67.57055699999995,66.184143],[-67.454453,66.14471400000008],[-67.39999399999999,66.12637300000011],[-67.28138699999994,66.083054],[-67.165009,66.03692600000005],[-67.16250600000001,66.03526299999993],[-67.24352299999993,65.97830199999999],[-67.17304999999988,65.91859399999998],[-67.18582199999997,65.91220099999998],[-67.19444299999998,65.90971400000012],[-67.20167499999997,65.90914900000007],[-67.42999299999991,65.90554800000001],[-67.74055499999986,65.89415000000002],[-67.79527300000001,65.87719700000014],[-67.82417299999997,65.88081400000004],[-67.86471599999993,65.88777200000004],[-67.914444,65.89915500000006],[-67.93859900000001,65.9080350000001],[-68.02694699999995,65.99275200000011],[-68.03056300000003,65.99803200000002],[-68.031387,66.0022130000001],[-68.027222,66.06080600000007],[-68.02583299999998,66.06581100000011],[-68.13082899999995,66.1266480000001],[-68.24472000000003,66.1827550000001],[-68.34028599999999,66.19693000000001],[-68.53805499999993,66.20082100000008],[-68.71278399999994,66.19859300000013],[-68.808334,66.19581600000004],[-68.84249899999998,66.19331399999999],[-68.85139499999997,66.18997200000001],[-68.84638999999993,66.186646],[-68.83528100000001,66.18498199999999],[-68.66861,66.17886400000003],[-68.56834399999997,66.17858899999999],[-68.41471899999999,66.15942400000006],[-68.40361000000001,66.14637800000008],[-68.39111300000002,66.13526900000005],[-68.38333099999994,66.13108799999998],[-68.30027799999988,66.092758],[-68.27806099999998,66.08360299999998],[-68.24415599999998,66.07110599999999],[-68.23777799999993,66.06999200000001],[-68.22555499999999,66.06999200000001],[-68.220551,66.0730440000001],[-68.218887,66.08137500000004],[-68.22193900000002,66.0852660000001],[-68.22972099999998,66.09220900000008],[-68.24415599999998,66.09999100000005],[-68.24694799999997,66.11276199999998],[-68.22000099999997,66.12858600000004],[-68.20249899999993,66.12885999999997],[-68.19471699999997,66.12747200000007],[-68.15750100000002,66.11747700000001],[-68.13417099999998,66.10998500000005],[-68.11888099999999,66.1035920000001],[-68.04722600000002,66.06498699999997],[-68.04888900000003,66.00749200000007],[-68.05194099999994,65.996643],[-68.05360399999995,65.99108899999999],[-68.06443799999994,65.98442100000005],[-68.12388599999997,65.96304300000008],[-68.13417099999998,65.96331800000013],[-68.17361499999998,65.96943699999997],[-68.19694500000003,65.97387699999996],[-68.210556,65.97943099999998],[-68.27806099999998,66.01416000000006],[-68.30444299999988,66.02804600000002],[-68.32389799999993,66.00387599999999],[-68.333618,65.93193100000002],[-68.33222999999992,65.92886400000009],[-68.32583599999998,65.91638200000011],[-68.32167099999998,65.911926],[-68.30474899999996,65.90866100000005],[-68.287781,65.907761],[-68.26000999999991,65.91137700000002],[-68.19415300000003,65.92109700000015],[-68.156113,65.92970300000002],[-68.150284,65.930542],[-68.14277599999997,65.92915299999999],[-68.13999899999999,65.92747500000007],[-68.136124,65.92276000000004],[-68.13473499999992,65.91360500000002],[-68.13290399999994,65.83488500000004],[-68.13917500000002,65.81721500000015],[-68.14723199999997,65.79832500000003],[-68.03332499999993,65.77638200000007],[-68.02389499999987,65.77526899999998],[-68.00306699999999,65.77832000000001],[-67.92361499999993,65.79386900000009],[-67.88612399999988,65.80497700000006],[-67.82112099999995,65.76805099999996],[-67.87026999999995,65.68942299999998],[-67.94248999999996,65.61804200000012],[-67.9891659999999,65.61914100000007],[-68.05888400000003,65.56805399999996],[-68.027222,65.5583190000001],[-68.01251200000002,65.55775499999993],[-68.01167299999997,65.55886800000002],[-67.99861099999998,65.56693999999999],[-67.98721299999994,65.57138100000009],[-67.971115,65.57527199999998],[-67.95666499999999,65.57165500000002],[-67.95167500000002,65.568329],[-67.95306399999993,65.55720500000012],[-67.95500199999998,65.55386400000009],[-68.02084400000001,65.49803200000008],[-68.02778599999994,65.49165300000004],[-68.03028899999998,65.48776199999998],[-68.03056300000003,65.48442100000011],[-68.02583299999998,65.48109399999998],[-68.02250700000002,65.48054500000006],[-68.00778200000002,65.48553500000008],[-67.94193999999993,65.52526900000004],[-67.92250099999995,65.53804000000014],[-67.86027499999994,65.58442700000006],[-67.73028599999998,65.63638300000014],[-67.712219,65.64082300000013],[-67.65249599999999,65.65138200000001],[-67.46610999999996,65.67414900000011],[-67.428604,65.67665099999999],[-67.40249599999993,65.67747500000013],[-67.396118,65.67665099999999],[-67.38221699999991,65.67387400000007],[-67.32806399999998,65.66249100000005],[-67.31945799999994,65.65942399999994],[-67.28056299999997,65.64248700000013],[-67.275284,65.6377720000001],[-67.25666799999999,65.61526500000002],[-67.25389100000001,65.611649],[-67.25167799999986,65.60693400000014],[-67.25334199999998,65.60165400000005],[-67.25666799999999,65.599152],[-67.27278100000001,65.59526100000011],[-67.32055700000001,65.58692900000011],[-67.33332799999994,65.58248900000007],[-67.33612099999993,65.580826],[-67.45666499999999,65.501938],[-67.45889299999993,65.49803200000008],[-67.45140099999992,65.49359099999998],[-67.34750400000001,65.45860299999998],[-67.22138999999999,65.45637500000004],[-67.18998699999997,65.45803799999999],[-67.18083200000001,65.45915200000013],[-67.16915899999998,65.46138000000008],[-67.15556300000003,65.4669340000001],[-67.14222699999999,65.46914700000008],[-67.08167999999995,65.46249400000005],[-67.06555200000003,65.45860299999998],[-67.05860899999993,65.45359799999994],[-67.058044,65.45138500000002],[-67.058334,65.42665100000005],[-67.06277499999993,65.41748000000007],[-67.07833900000003,65.39221199999997],[-67.11111499999998,65.36470000000003],[-67.11805699999996,65.36192299999993],[-67.12388599999997,65.36053500000003],[-67.13444500000003,65.35971100000006],[-67.21806300000003,65.35859700000009],[-67.25556899999992,65.36053500000003],[-67.316101,65.35859700000009],[-67.40083300000003,65.35026600000003],[-67.40888999999999,65.3483280000001],[-67.41361999999992,65.3458250000001],[-67.41777000000002,65.34220900000003],[-67.41610700000001,65.33915700000011],[-67.40943900000002,65.33332800000011],[-67.39999399999999,65.32971200000003],[-67.39111300000002,65.3272090000001],[-67.33666999999997,65.31721500000009],[-67.32667499999997,65.31694000000005],[-67.31916799999993,65.31805400000002],[-67.31582600000002,65.3205410000001],[-67.30665599999986,65.33027600000003],[-67.306107,65.33360299999993],[-67.30694599999998,65.33804299999997],[-67.30387899999994,65.34248400000007],[-67.29750100000001,65.347488],[-67.29138199999994,65.349716],[-67.283615,65.35108900000006],[-67.26916499999999,65.35220300000003],[-67.12554899999998,65.31191999999999],[-67.11999500000002,65.30998200000005],[-67.077789,65.2502750000001],[-67.06388900000002,65.21832299999994],[-66.93472300000002,65.23387100000014],[-66.93306000000001,65.23359700000003],[-66.92887899999994,65.22970599999996],[-66.94888300000002,65.12525900000014],[-66.95083599999998,65.11692800000003],[-66.95333900000003,65.11303699999996],[-66.95916699999998,65.10664400000002],[-66.96749899999998,65.10386699999992],[-67.02528399999989,65.10832199999993],[-67.04415899999992,65.107483],[-67.05555700000002,65.10525500000006],[-67.066666,65.10081500000001],[-67.07223499999998,65.09721400000012],[-67.10611,65.06414799999999],[-67.108612,65.06025699999992],[-67.10777300000001,65.05886800000013],[-67.096115,65.05609100000004],[-67.08583099999998,65.05636600000008],[-67.07501200000002,65.05802900000015],[-66.89056399999998,65.10331700000006],[-66.835556,65.13720699999999],[-66.756393,65.17720000000003],[-66.74749799999995,65.180542],[-66.73028599999992,65.18136600000014],[-66.72610500000002,65.18026700000013],[-66.72555499999999,65.17804000000007],[-66.75334199999998,65.11331200000001],[-66.80166600000001,65.06080600000007],[-66.76750199999998,65.02442900000011],[-66.74305700000002,64.96304299999997],[-66.726944,64.91387900000012],[-66.72749299999992,64.90525800000006],[-66.72805799999998,64.901657],[-66.73306300000002,64.88832100000002],[-66.73916599999995,64.85998500000011],[-66.73500099999995,64.8247070000001],[-66.73416099999992,64.82054100000005],[-66.69804399999987,64.76193199999994],[-66.69471699999991,64.76138300000002],[-66.68777499999999,64.76220699999999],[-66.65417500000001,64.7711030000001],[-66.64111300000002,64.77581800000013],[-66.63249200000001,64.78137200000015],[-66.63806199999999,64.78553800000003],[-66.6761019999999,64.876083],[-66.69694499999997,65.03276100000005],[-66.69415299999997,65.0372010000001],[-66.68866000000003,65.03877299999994],[-66.67332499999998,65.038589],[-66.66082799999998,65.0372010000001],[-66.61805699999996,65.03027300000008],[-66.535278,65.01081799999992],[-66.53056300000003,65.00749200000007],[-66.49610899999999,64.98304700000006],[-66.48889199999991,64.95748900000012],[-66.49665800000002,64.94552600000009],[-66.495544,64.93887300000011],[-66.491379,64.93498200000005],[-66.48666400000002,64.93220500000012],[-66.47860699999995,64.92915300000004],[-66.38861099999997,64.91331500000001],[-66.379166,64.91220100000004],[-66.36805700000002,64.91360500000002],[-66.36389200000002,64.91748000000001],[-66.36193800000001,64.92359900000002],[-66.36361699999992,64.9285890000001],[-66.33473200000003,64.93470800000011],[-66.17777999999993,64.88026400000007],[-66.148346,64.86886600000003],[-66.17721599999999,64.79637100000002],[-66.18472300000002,64.78442400000006],[-66.19193999999993,64.77887000000004],[-66.19943199999994,64.77499399999999],[-66.20333900000003,64.77388000000002],[-66.21333300000003,64.75610400000005],[-66.21916199999998,64.72608900000012],[-66.21888699999994,64.69081100000011],[-66.21221899999995,64.68553199999997],[-66.18472300000002,64.68165600000003],[-66.16694599999994,64.68109100000004],[-66.16111799999993,64.68248],[-66.15834000000001,64.68414300000012],[-66.151947,64.68914799999999],[-66.14778100000001,64.69581599999998],[-66.14723200000003,64.70138500000013],[-66.14723200000003,64.70416299999994],[-66.15028399999994,64.71748400000007],[-66.14973399999991,64.73359700000015],[-66.145554,64.74026500000014],[-66.13639799999999,64.75416600000011],[-66.11694299999999,64.78137200000015],[-66.09167500000001,64.80970800000006],[-66.08084100000002,64.81915300000009],[-66.05833399999995,64.83276400000005],[-66.03721599999994,64.84498600000006],[-66.02084399999995,64.84971600000006],[-66.01139799999999,64.84832799999998],[-66.011124,64.84637500000002],[-66.008621,64.78915400000011],[-66.00917099999987,64.77804600000007],[-66.0125119999999,64.69941700000004],[-65.89999399999999,64.67330900000007],[-65.84666400000003,64.676086],[-65.85221899999999,64.68026700000007],[-65.86138900000003,64.68914799999999],[-65.88944999999995,64.71971100000013],[-65.89917000000003,64.73275799999999],[-65.95861799999994,64.87776199999996],[-65.95666499999993,64.88610800000009],[-65.95333899999997,64.88832100000002],[-65.94193999999999,64.89054899999996],[-65.93138099999993,64.89137299999993],[-65.92471299999994,64.89137299999993],[-65.83860800000002,64.882477],[-65.72721899999993,64.84359700000005],[-65.71777299999997,64.84027100000003],[-65.67443800000001,64.81805400000013],[-65.66416899999996,64.80831900000004],[-65.66166699999997,64.80442800000014],[-65.660278,64.799149],[-65.665009,64.79693600000002],[-65.68331899999993,64.79220600000002],[-65.69833399999999,64.78471400000006],[-65.72027599999996,64.76666300000011],[-65.73611499999998,64.75027500000004],[-65.74249299999991,64.7410890000001],[-65.74276699999996,64.73526000000004],[-65.73693800000001,64.72608900000012],[-65.726944,64.71138000000008],[-65.71083099999998,64.69303900000006],[-65.70472699999993,64.6874850000001],[-65.70306399999993,64.69220000000013],[-65.70944199999997,64.71276900000004],[-65.71055599999994,64.71859699999999],[-65.71000700000002,64.73220800000013],[-65.708618,64.73609900000002],[-65.68415799999997,64.76110799999998],[-65.67610200000001,64.76554899999991],[-65.66528299999993,64.77137800000014],[-65.648056,64.77499399999999],[-65.64277600000003,64.77499399999999],[-65.62721299999993,64.7711030000001],[-65.59889199999992,64.75637799999998],[-65.56639100000001,64.73748800000004],[-65.56111099999987,64.73304700000011],[-65.55749500000002,64.72831700000006],[-65.55583199999995,64.72331200000002],[-65.55638099999993,64.717758],[-65.57223499999992,64.664154],[-65.57667500000002,64.65248100000002],[-65.58332799999994,64.64276100000012],[-65.58639499999992,64.64027400000003],[-65.65472399999999,64.60247800000002],[-65.66250599999995,64.59832800000004],[-65.71417200000002,64.57054100000005],[-65.73083500000001,64.51776100000001],[-65.73222399999997,64.50804099999993],[-65.72555499999993,64.49803199999997],[-65.72166400000003,64.49414100000007],[-65.70834400000001,64.48664900000011],[-65.69554099999999,64.48580900000007],[-65.665009,64.49220300000013],[-65.64334099999996,64.49498],[-65.57333399999999,64.49859600000008],[-65.52471899999995,64.49971000000005],[-65.51806599999998,64.49971000000005],[-65.50639299999995,64.4974820000001],[-65.50418100000002,64.49581899999998],[-65.50556899999998,64.46887200000003],[-65.39611799999994,64.52137799999997],[-65.38417099999998,64.52415500000006],[-65.3658289999999,64.52693199999999],[-65.21055599999988,64.53610200000003],[-65.203888,64.53387499999997],[-65.144455,64.51138300000008],[-65.08500699999996,64.47970599999996],[-65.07778899999994,64.47581500000007],[-65.07583599999998,64.47137500000002],[-65.07417299999997,64.46192900000005],[-65.07167099999998,64.440811],[-65.07194500000003,64.43081699999999],[-65.07362399999994,64.42608600000005],[-65.19499199999996,64.31025700000009],[-65.20249899999999,64.30636600000003],[-65.21083099999998,64.30386399999998],[-65.28472899999991,64.2916560000001],[-65.2952729999999,64.29026799999997],[-65.30943300000001,64.29136699999998],[-65.3433379999999,64.294983],[-65.37721299999998,64.30331400000011],[-65.38639799999993,64.30664100000007],[-65.40888999999993,64.31248500000004],[-65.45167499999997,64.31999200000001],[-65.49888599999986,64.32276900000011],[-65.5250089999999,64.32331800000003],[-65.55416899999994,64.32331800000003],[-65.56332399999991,64.32249499999995],[-65.65583799999996,64.30886800000007],[-65.66166699999997,64.30748],[-65.65833999999995,64.30276500000014],[-65.654449,64.30081200000001],[-65.61860699999994,64.29304500000006],[-65.60194399999995,64.29359400000004],[-65.59194899999994,64.29609699999997],[-65.57223499999992,64.29859900000008],[-65.50584400000002,64.30247500000013],[-65.46583599999997,64.30304000000001],[-65.43415800000002,64.29914900000011],[-65.42277499999994,64.29637100000014],[-65.250565,64.20832800000005],[-65.24610899999999,64.20498700000002],[-65.24276699999996,64.20027199999998],[-65.265015,64.17886400000009],[-65.16194200000001,64.13804600000014],[-65.04943800000001,64.07222000000002],[-65.05387899999994,64.06776400000007],[-65.06054699999993,64.06498699999997],[-65.093887,64.05219999999997],[-65.103882,64.049149],[-65.13667299999992,64.04136700000004],[-65.15833999999995,64.03831500000007],[-65.19610599999993,64.04026800000003],[-65.20611599999995,64.04026800000003],[-65.21665999999999,64.038589],[-65.22138999999993,64.03637700000013],[-65.22555499999993,64.03276100000011],[-65.22193899999996,64.028595],[-65.21417200000002,64.02554300000008],[-65.18998699999992,64.02026400000011],[-65.09666399999998,64.00915500000002],[-65.08805799999999,64.00943000000007],[-64.94915800000001,64.01499900000005],[-64.80055199999998,64.02777100000003],[-64.68638599999997,64.03915400000005],[-64.676941,64.036652],[-64.66805999999997,64.03305100000011],[-64.66111799999999,64.028595],[-64.63055400000002,63.978324999999984],[-64.63137799999998,63.97470900000013],[-64.63276699999994,63.97276300000004],[-64.63833599999998,63.96915400000006],[-64.64805599999994,63.96693400000004],[-64.65888999999999,63.96554600000013],[-64.66999800000002,63.96638500000006],[-64.689438,63.96610300000003],[-64.70056199999999,63.963882000000126],[-64.81750499999998,63.923607000000004],[-64.87527499999999,63.9011000000001],[-64.88890100000003,63.89499699999999],[-64.97471599999994,63.85193600000014],[-64.98500099999995,63.82916300000005],[-64.98750299999995,63.82305100000008],[-64.98416099999992,63.81388100000004],[-64.95417799999996,63.776382000000126],[-64.94888299999991,63.77443700000009],[-64.77806099999998,63.747772000000055],[-64.68360899999999,63.74638399999998],[-64.58444199999985,63.704711999999915],[-64.55943299999996,63.694153000000085],[-64.54028299999999,63.68443300000001],[-64.52749599999999,63.676941000000056],[-64.52250700000002,63.672768000000076],[-64.50834700000001,63.65082600000005],[-64.50666799999999,63.63694000000004],[-64.50750699999998,63.630821000000026],[-64.515015,63.62027000000012],[-64.52194199999991,63.61193800000012],[-64.53666699999997,63.581108000000086],[-64.529449,63.534996000000035],[-64.52250700000002,63.514717000000076],[-64.50167799999997,63.4438780000001],[-64.49888599999997,63.42916100000008],[-64.49554399999994,63.32777399999998],[-64.51083399999999,63.30777000000006],[-64.58889799999986,63.3219380000001],[-64.608337,63.32388300000008],[-64.61999499999996,63.32332600000001],[-64.62222300000002,63.32221999999996],[-64.62471,63.318054000000075],[-64.61999499999996,63.31332400000002],[-64.61471599999999,63.30971500000004],[-64.58778399999994,63.299721000000034],[-64.577225,63.29666099999997],[-64.56639099999995,63.29388400000005],[-64.52555799999993,63.29055000000005],[-64.50083899999998,63.28999299999998],[-64.48889200000002,63.28833000000009],[-64.48277300000001,63.28582799999998],[-64.48194899999987,63.28221100000002],[-64.53111299999995,63.24971800000009],[-64.53805499999993,63.24832900000007],[-64.65833999999995,63.249161000000015],[-64.76750199999992,63.32388300000008],[-64.82695000000001,63.45249199999995],[-64.85055499999993,63.51082600000001],[-64.94249000000002,63.63221000000004],[-64.95500199999992,63.64027400000003],[-64.973053,63.646942000000024],[-64.99499499999996,63.652488999999946],[-65.04638699999992,63.662209000000075],[-65.06361400000003,63.66805300000004],[-65.07084700000001,63.67193600000002],[-65.166946,63.747772000000055],[-65.16639700000002,63.77332300000012],[-65.15333599999991,63.771102999999925],[-65.15083300000003,63.772217000000126],[-65.15417499999995,63.77693900000003],[-65.15943900000002,63.78110500000008],[-65.20472699999993,63.80332199999998],[-65.29360999999994,63.812767000000065],[-65.29861499999993,63.81249200000002],[-65.30139200000002,63.81082200000003],[-65.303879,63.806938],[-65.30027799999993,63.799995000000024],[-65.281677,63.788887000000045],[-65.21556099999992,63.75471500000009],[-65.15566999999993,63.72532699999999],[-65.13528400000001,63.71527100000014],[-65.05305499999997,63.63804600000009],[-65.03916900000002,63.57416500000011],[-65.06973299999999,63.568886000000134],[-65.08583099999993,63.563881000000094],[-65.09194899999994,63.55971499999998],[-65.09999099999993,63.54721799999999],[-65.10221899999999,63.541664000000026],[-65.10221899999999,63.53665899999993],[-65.0994419999999,63.526381999999955],[-65.026947,63.3991620000001],[-64.96501199999994,63.36943800000006],[-64.95249899999988,63.362213],[-64.94249000000002,63.353049999999996],[-64.90916399999998,63.280548000000124],[-64.90110800000002,63.237495000000024],[-64.90861499999994,63.235550000000046],[-64.92138699999992,63.235825000000034],[-65.04638699999992,63.24832900000007],[-65.068893,63.25249499999995],[-65.08250399999997,63.260826000000066],[-65.10333299999996,63.27777100000003],[-65.11416600000001,63.28499600000009],[-65.12332199999997,63.28833000000009],[-65.136124,63.29083300000002],[-65.141953,63.28943600000008],[-65.14862099999999,63.286110000000065],[-65.14695699999987,63.28138000000001],[-65.08332799999994,63.20388000000014],[-65.05777,63.174713],[-65.05499299999991,63.17221799999999],[-65.046112,63.171104000000014],[-65.01652499999994,63.171516],[-64.99861099999993,63.176102000000014],[-64.94471699999991,63.18332700000008],[-64.92027299999995,63.18415800000008],[-64.91139199999992,63.18082400000009],[-64.81166099999996,63.13749700000005],[-64.79750099999995,63.130547000000035],[-64.78388999999999,63.12221500000004],[-64.75500499999993,63.099158999999986],[-64.75334199999992,63.09665700000011],[-64.76251199999996,63.0472180000001],[-64.77139299999999,62.98333000000008],[-64.70333899999997,62.95332300000007],[-64.69610599999987,62.952217000000076],[-64.67639200000002,62.94165800000002],[-64.64555399999995,62.92166099999997],[-64.63444499999997,62.9124910000001],[-64.62721299999998,62.90415999999999],[-64.62693799999994,62.899994000000106],[-64.62998999999996,62.897491000000116],[-64.63833599999998,62.89444000000009],[-64.733612,62.87887599999999],[-64.76945499999994,62.86221300000011],[-64.85526999999996,62.865273],[-64.88194299999986,62.867493000000024],[-64.903885,62.872490000000084],[-64.92332499999998,62.87887599999999],[-65.00500499999998,62.90776800000009],[-65.16221599999994,62.943047000000035],[-65.225281,62.95499399999994],[-65.23611499999998,62.95777100000004],[-65.24305699999996,62.9616620000001],[-65.24833699999994,62.965828000000045],[-65.25140399999998,62.97054300000008],[-65.25500499999993,62.97971300000012],[-65.25473,62.98526800000002],[-65.26916499999993,62.95999100000006],[-65.19444299999992,62.87887599999999],[-65.19027699999992,62.87526700000001],[-65.17500299999995,62.862495000000024],[-65.15388499999995,62.84693900000002],[-65.14805599999994,62.843323],[-65.129166,62.83638000000002],[-65.11527999999998,62.82888000000008],[-64.98472600000002,62.714157],[-64.97833299999996,62.70471199999997],[-64.94888299999991,62.648604999999975],[-64.964722,62.6336060000001],[-64.98083499999996,62.623604000000114],[-65.06277499999999,62.58749400000005],[-65.07112099999995,62.58443500000004],[-65.087219,62.57888000000014],[-65.11471599999999,62.57166300000006],[-65.14500399999991,62.56582600000007],[-65.18749999999994,62.56221000000005],[-65.19776899999988,62.56304899999998],[-65.20500199999998,62.56610100000012],[-65.212219,62.56999200000001],[-65.22084000000001,62.57833100000005],[-65.28860500000002,62.659988],[-65.29499799999996,62.669441000000006],[-65.29666099999997,62.67416399999996],[-65.29055800000003,62.678878999999995],[-65.27389499999998,62.68526500000013],[-65.26777600000003,62.69026900000006],[-65.26695299999994,62.694435],[-65.27917500000001,62.696654999999964],[-65.321121,62.694435],[-65.32749899999999,62.691658000000075],[-65.32972699999993,62.685546999999985],[-65.32806399999998,62.66610000000014],[-65.33721899999995,62.66666400000008],[-65.34695399999987,62.67582700000008],[-65.35388199999994,62.68443300000001],[-65.35665899999992,62.69499200000007],[-65.33972199999994,62.83749399999999],[-65.39195299999994,62.843605000000025],[-65.43666100000002,62.81944299999998],[-65.56666599999994,62.811661000000015],[-65.57917800000001,62.81193499999995],[-65.60194399999995,62.817772000000105],[-65.60943599999996,62.820831000000055],[-65.61610399999995,62.82471500000008],[-65.74694799999986,62.917770000000075],[-65.90943899999996,62.92582700000003],[-65.93331899999998,62.95582600000006],[-65.910278,62.96776599999998],[-65.839722,63.02082800000005],[-65.83473199999997,63.02638200000007],[-65.833328,63.03138000000007],[-65.83833300000003,63.03333300000003],[-65.84973100000002,63.032767999999976],[-65.86639400000001,63.028602999999976],[-65.92610199999996,63.00833100000011],[-65.94972200000001,62.997772000000055],[-65.95500199999998,62.994155999999975],[-65.95556599999986,62.990829000000076],[-65.94638099999997,62.98304700000011],[-65.94583099999994,62.97887400000013],[-65.95056199999999,62.97582200000005],[-65.96083099999993,62.974433999999974],[-65.97389199999986,62.97387700000007],[-65.987213,62.97470900000013],[-66.01445000000001,62.97887400000013],[-66.03138699999994,62.98471799999999],[-66.03971899999999,62.988602000000014],[-66.05221599999999,62.99665800000008],[-66.14973399999991,63.059990000000084],[-66.15556300000003,63.08138300000002],[-66.16278099999994,63.08998900000012],[-66.17443800000001,63.09638200000006],[-66.26695299999994,63.13082099999997],[-66.27583299999998,63.13388100000003],[-66.28250100000002,63.133331],[-66.287781,63.12971500000009],[-66.291946,63.12526700000012],[-66.29333500000001,63.120543999999995],[-66.291382,63.11610400000012],[-66.206955,63.04083300000008],[-66.19665499999996,63.03166199999998],[-66.18276999999989,63.023604999999975],[-66.12165800000002,63.00110600000005],[-66.10555999999997,62.99388099999999],[-66.098343,62.99027300000006],[-66.091385,62.983604000000014],[-66.08972199999988,62.97860000000003],[-66.09777799999995,62.95249200000006],[-66.10305800000003,62.946655000000135],[-66.10777299999995,62.94387800000004],[-66.11610399999995,62.940544000000045],[-66.13583399999993,62.93665299999998],[-66.14723200000003,62.936104],[-66.15916399999998,62.93665299999998],[-66.16888399999999,62.938881000000094],[-66.19221500000003,62.95443700000004],[-66.22083999999995,62.96943700000003],[-66.28472899999991,62.99027300000006],[-66.29388399999988,62.992767000000015],[-66.34500099999997,62.999161000000015],[-66.35166899999996,62.99860399999994],[-66.366104,62.99249300000008],[-66.37860099999989,62.99249300000008],[-66.39277599999997,62.99499500000013],[-66.40888999999993,63.00193800000011],[-66.44444299999986,63.020546000000024],[-66.46444699999995,63.032211000000075],[-66.51834099999996,63.06526900000006],[-66.525284,63.074715000000026],[-66.551941,63.17943600000001],[-66.62638899999996,63.252220000000136],[-66.64666699999998,63.32638499999996],[-66.63833599999998,63.34027100000014],[-66.63751200000002,63.349998000000085],[-66.63694800000002,63.35833000000008],[-66.63778699999995,63.36277000000007],[-66.64277600000003,63.37248999999997],[-66.65083299999998,63.37499200000008],[-66.65750099999997,63.374435000000005],[-66.66416900000002,63.37165800000008],[-66.73554999999999,63.299438000000066],[-66.73860200000001,63.29415900000009],[-66.74082899999996,63.288048],[-66.74027999999993,63.283607000000075],[-66.73111,63.27471200000002],[-66.72055099999994,63.266388000000006],[-66.68554699999999,63.248046999999985],[-66.67138699999987,63.24276700000013],[-66.64695699999993,63.23915900000003],[-66.63917499999997,63.23610700000012],[-66.60749800000002,63.21027400000014],[-66.60249299999998,63.2052690000001],[-66.600281,63.20082900000011],[-66.558334,63.08721200000002],[-66.53778099999988,62.99804700000004],[-66.54028299999993,62.994155999999975],[-66.54666099999992,62.99137900000011],[-66.55722000000003,62.99193600000001],[-66.67304999999999,63.023048000000074],[-66.68222000000003,63.02638200000007],[-66.76306199999993,63.08305400000006],[-66.76806599999992,63.08776899999992],[-66.77389499999992,63.09638200000006],[-66.77444499999996,63.100548],[-66.778885,63.14360799999997],[-66.78916900000002,63.21138000000002],[-66.80665599999998,63.272491000000116],[-66.80749500000002,63.27332300000006],[-66.81166100000002,63.274437000000034],[-66.82028200000002,63.27332300000006],[-66.82917799999996,63.27166000000011],[-66.83778399999994,63.267769000000044],[-66.84695399999993,63.25750000000005],[-66.84916699999997,63.25138900000013],[-66.84916699999997,63.24554400000005],[-66.84611499999994,63.22971300000006],[-66.84472700000003,63.22665400000011],[-66.837219,63.21804800000001],[-66.82833899999997,63.20916],[-66.81945799999994,63.20027200000004],[-66.81388899999996,63.196098000000006],[-66.80387899999994,63.186378000000104],[-66.80139199999996,63.18249500000013],[-66.79972799999996,63.17749000000009],[-66.79943799999995,63.172492999999974],[-66.80166600000001,63.16638200000011],[-66.80665599999998,63.16054500000013],[-66.81834399999997,63.15415999999993],[-66.835556,63.14916199999993],[-66.84416199999993,63.147217000000126],[-66.85527000000002,63.147217000000126],[-66.86833200000001,63.14888000000008],[-66.87777699999998,63.15193199999999],[-67.01834099999996,63.238883999999985],[-67.02389499999998,63.243050000000096],[-67.02500899999995,63.246658000000025],[-67.02444500000001,63.25027499999999],[-67.023056,63.25277700000004],[-67.006393,63.26221500000008],[-66.971115,63.38971700000002],[-66.97277799999995,63.3949970000001],[-66.97778299999999,63.399719000000005],[-66.98889199999996,63.402489],[-67.01112399999994,63.39999399999999],[-67.01722699999999,63.39721700000007],[-67.04083299999996,63.33554799999996],[-67.03916899999996,63.33055100000007],[-67.03582799999992,63.3252720000001],[-67.02500899999995,63.31110400000006],[-67.01611300000002,63.29666099999997],[-67.01417499999997,63.28638500000005],[-67.01722699999999,63.281105000000025],[-67.03332499999993,63.27526899999992],[-67.05194099999994,63.27332300000006],[-67.171112,63.27388000000013],[-67.17971799999992,63.27555100000001],[-67.20388799999995,63.28527100000008],[-67.431671,63.412765999999976],[-67.49999999999994,63.442764000000125],[-67.62165800000002,63.54888199999999],[-67.68331899999998,63.619438],[-67.83889799999992,63.72971300000012],[-67.89750699999996,63.75305200000014],[-67.91471899999999,63.759438000000046],[-67.92332499999992,63.761108000000036],[-67.92610200000001,63.75916300000006],[-67.92527799999993,63.75471500000009],[-67.92138699999998,63.74443800000006],[-67.91805999999985,63.739159000000086],[-67.82000699999998,63.596382000000006],[-67.710556,63.45860300000004],[-67.68331899999998,63.43166400000007],[-67.675003,63.4180530000001],[-67.67193599999996,63.41249099999999],[-67.66776999999996,63.403046000000074],[-67.66639699999996,63.394439999999975],[-67.66665599999999,63.388046000000145],[-67.67832900000002,63.3730470000001],[-67.685272,63.36888099999999],[-67.69444299999998,63.36638599999998],[-67.71665999999993,63.3638840000001],[-67.72416699999997,63.364159000000086],[-67.737213,63.36638599999998],[-67.74638400000003,63.36943800000006],[-67.82055700000001,63.40026900000004],[-67.827225,63.4052660000001],[-67.83750900000001,63.42416400000002],[-67.854446,63.45277400000003],[-67.858047,63.457497000000046],[-67.87165800000002,63.46471400000013],[-67.95083599999998,63.506660000000124],[-68.02528399999994,63.540832999999964],[-68.03332499999993,63.54388399999999],[-68.041382,63.546104000000014],[-68.05305499999992,63.54527300000001],[-68.06166100000002,63.54332700000009],[-68.07556199999999,63.544159000000036],[-68.36582900000002,63.64527099999998],[-68.38861099999986,63.655548000000124],[-68.40028399999994,63.66387900000001],[-68.40556300000003,63.66860200000002],[-68.42832899999996,63.69638100000003],[-68.54276999999996,63.732490999999925],[-68.6458439999999,63.74749000000003],[-68.71362299999998,63.74249300000008],[-68.70973200000003,63.73804500000011],[-68.71139499999992,63.73471799999999],[-68.71610999999996,63.73220799999996],[-68.72361799999999,63.72971300000012],[-68.795547,63.728600000000085],[-68.80444299999994,63.73027000000002],[-68.87609900000001,63.744713000000104],[-68.91583300000002,63.75721699999997],[-68.92443799999995,63.75888800000001],[-68.96250899999995,63.75916300000006],[-68.99472000000003,63.75555400000002],[-68.99694799999992,63.75360900000004],[-68.99833699999999,63.745270000000005],[-68.99527,63.74137900000011],[-68.98971599999999,63.73749500000008],[-68.97778299999993,63.72971300000012],[-68.93305999999995,63.71193699999998],[-68.91944899999999,63.704994],[-68.82472200000001,63.64388300000007],[-68.81304899999998,63.63555100000008],[-68.80943300000001,63.630821000000026],[-68.80722000000003,63.62582400000014],[-68.80943300000001,63.621658000000025],[-68.79333499999996,63.589157000000114],[-68.76611300000002,63.55665600000003],[-68.75473,63.548607000000004],[-68.71777299999991,63.52860300000009],[-68.55776999999995,63.45249199999995],[-68.49583399999995,63.421378999999945],[-68.35943599999996,63.34471099999996],[-68.28860500000002,63.298332000000016],[-68.27055399999995,63.28499600000009],[-68.20639,63.22721100000001],[-68.20249899999993,63.21693399999998],[-68.20639,63.21249399999999],[-68.18638599999997,63.18832400000014],[-68.156113,63.158324999999934],[-68.146118,63.15026900000004],[-68.13917500000002,63.14860500000003],[-68.128601,63.14804800000013],[-68.11555499999997,63.15248900000006],[-68.08277900000002,63.16360500000002],[-68.06388899999996,63.16360500000002],[-67.95222499999994,63.14554600000008],[-67.92639200000002,63.141106000000036],[-67.91749599999997,63.13721499999997],[-67.91665599999993,63.133049000000085],[-67.92332499999992,63.12943300000006],[-67.91278099999994,63.083327999999995],[-67.64611799999994,63.10027299999996],[-67.632767,63.09887700000013],[-67.610275,63.09415400000012],[-67.60499600000003,63.08998900000012],[-67.59999099999999,63.08443499999993],[-67.59999099999999,63.07888000000003],[-67.601944,63.073326000000066],[-67.61500499999994,63.06360599999999],[-67.62416099999996,63.06110400000006],[-67.636124,63.0597150000001],[-67.68221999999992,63.05777000000012],[-67.68971299999993,63.05804400000005],[-67.70916699999992,63.05665599999992],[-67.71945199999993,63.054993000000024],[-67.72749299999992,63.05165900000003],[-67.77305599999994,63.02582600000005],[-67.77250700000002,62.962212000000136],[-67.76972999999998,62.95832799999994],[-67.76362599999999,62.95555100000007],[-67.74804699999999,62.953049000000135],[-67.73860200000001,62.95332300000007],[-67.72805800000003,62.95499399999994],[-67.72183199999995,62.96265800000009],[-67.718842,62.96449300000006],[-67.71816999999999,62.96732700000007],[-67.71932999999996,62.9704900000001],[-67.72444200000001,62.984161000000086],[-67.72999599999997,62.98832700000014],[-67.73693800000001,62.99554400000011],[-67.73388699999998,63.000832000000116],[-67.69804399999992,63.02082800000005],[-67.68693499999995,63.026657000000114],[-67.65943899999996,63.03416400000003],[-67.56527699999998,63.04943800000012],[-67.55305499999992,63.04860700000012],[-67.52999899999998,63.03694200000001],[-67.510559,63.02471200000008],[-67.49999999999994,63.01554900000008],[-67.49972499999996,63.00777399999998],[-67.50917099999992,63.00193800000011],[-67.531387,62.99526999999995],[-67.55055199999998,62.99193600000001],[-67.57333399999999,62.99027300000006],[-67.593613,62.98749500000008],[-67.63082899999995,62.97637900000012],[-67.65139799999992,62.96749099999994],[-67.670998,62.944323999999995],[-67.671829,62.94132200000013],[-67.67266799999999,62.937996000000055],[-67.672775,62.92332499999998],[-67.66583300000002,62.91888400000005],[-67.65916400000003,62.916664000000026],[-67.654922,62.917282],[-67.64889499999992,62.92110400000007],[-67.64666699999998,62.925270000000125],[-67.63833599999998,62.931938000000116],[-67.57250999999991,62.963882000000126],[-67.566956,62.96554600000013],[-67.47027599999996,62.98526800000002],[-67.462784,62.98526800000002],[-67.39805599999994,62.96720900000008],[-67.19471699999991,62.87027000000006],[-67.04834,62.77137800000014],[-67.01222199999995,62.73443600000013],[-66.95777899999996,62.681107],[-66.91332999999992,62.66999100000004],[-66.82472200000001,62.67916100000008],[-66.81332399999985,62.67999299999997],[-66.741104,62.673882000000106],[-66.73306300000002,62.67166100000003],[-66.726944,62.66860200000002],[-66.72888199999994,62.66610000000014],[-66.735275,62.66249099999993],[-66.74444599999993,62.66027100000014],[-66.752792,62.65693699999997],[-66.760559,62.653602999999976],[-66.76806599999992,62.64887999999996],[-66.77305599999988,62.64305099999996],[-66.77500900000001,62.636940000000095],[-66.77305599999988,62.63249200000013],[-66.60694899999999,62.604996000000085],[-66.42500299999995,62.445267000000115],[-66.35943600000002,62.44748700000014],[-66.35166899999996,62.44499200000013],[-66.34916699999997,62.44137600000005],[-66.32749899999993,62.384438000000046],[-66.33056599999998,62.37915800000002],[-66.33778399999989,62.37499200000008],[-66.42639199999996,62.349433999999974],[-66.43554699999993,62.349158999999986],[-66.45861799999994,62.35193600000008],[-66.46916199999998,62.35193600000008],[-66.47582999999997,62.348602000000085],[-66.478882,62.34332300000011],[-66.478882,62.338325999999995],[-66.47694399999995,62.335823000000005],[-66.47000099999997,62.33221400000002],[-66.37471,62.286110000000065],[-66.32917799999996,62.267494000000056],[-66.31861900000001,62.26471700000013],[-66.35583499999996,62.30777000000006],[-66.35916099999997,62.312492000000134],[-66.36389200000002,62.32305100000002],[-66.36138900000003,62.32694200000009],[-66.35555999999985,62.33194000000009],[-66.351944,62.334991000000116],[-66.33277900000002,62.341934000000094],[-66.3125,62.344993999999986],[-66.29415899999998,62.34471100000002],[-66.285553,62.34360500000014],[-66.2083439999999,62.33221400000002],[-66.16528299999993,62.291382],[-66.16027799999989,62.271378000000084],[-66.16722099999998,62.25443999999999],[-66.20195000000001,62.26055100000008],[-66.25666799999999,62.26610599999998],[-66.26139799999987,62.26305400000007],[-66.25723299999987,62.25972000000007],[-66.241104,62.253326000000015],[-66.2125089999999,62.24527000000012],[-66.16639700000002,62.23526799999996],[-66.08168,62.226379000000065],[-66.05860899999988,62.2241590000001],[-66.051941,62.22470900000013],[-66.04583699999995,62.227486],[-66.04361,62.23360400000013],[-66.03889500000002,62.23943299999996],[-66.03388999999999,62.24499500000013],[-66.02861000000001,62.248604000000114],[-66.02500899999995,62.24971800000009],[-66.01501499999995,62.25138900000013],[-66,62.247772],[-65.99305700000002,62.244155999999975],[-65.939438,62.208602999999925],[-65.93305999999995,62.20416300000011],[-65.92916899999989,62.198044000000095],[-65.93055699999996,62.19332100000008],[-65.93443299999996,62.19165799999996],[-65.95278899999994,62.18915600000008],[-65.96333299999998,62.186935000000005],[-65.96916199999993,62.18471499999998],[-66.04361,62.151657],[-66.05082700000003,62.147774000000084],[-66.13249200000001,62.089432000000045],[-66.11000100000001,62.01749400000011],[-66.041946,61.95804600000008],[-66.03582799999992,61.95277399999998],[-66.03306600000002,61.95249200000012],[-66.019455,61.954994],[-66.00306699999999,61.96221200000002],[-65.99943499999995,61.96305100000012],[-65.99221799999987,61.962769000000094],[-65.98860200000001,61.958885000000066],[-65.949432,61.9124910000001],[-65.94665500000002,61.906936999999914],[-65.94665500000002,61.89916200000005],[-65.94888299999997,61.89527099999998],[-65.95500199999998,61.89027400000003],[-65.96194500000001,61.88638300000014],[-65.97084000000001,61.88388100000009],[-66.05777,61.86971300000005],[-66.066101,61.868599000000074],[-66.27583299999998,61.858330000000024],[-66.287781,61.858330000000024],[-66.39500399999986,61.87082700000002],[-66.404449,61.87276500000013],[-66.52166699999992,61.896942000000024],[-66.54333499999996,61.89888000000013],[-66.55555700000002,61.90138200000001],[-66.62609900000001,61.917213000000004],[-66.632767,61.91888400000005],[-66.65916399999998,61.93360100000007],[-66.66528299999993,61.94137599999999],[-66.662216,61.946655000000135],[-66.74694799999992,62.00777400000004],[-66.75556899999992,62.011108000000036],[-66.78138699999988,62.015549000000135],[-66.80332900000002,62.01693700000004],[-66.81277499999999,62.01666300000011],[-66.82583599999992,62.011940000000095],[-67.091949,62.030823],[-67.10472099999998,62.03221100000013],[-67.25472999999994,62.07804900000008],[-67.3452759999999,62.119437999999946],[-67.46305799999993,62.13943500000005],[-67.49999999999994,62.13865700000014],[-67.73165899999992,62.158356000000026],[-67.75723299999993,62.160544999999956],[-67.79833999999994,62.166100000000085],[-68.00306699999999,62.213882000000126],[-68.11389200000002,62.21610300000003],[-68.2330629999999,62.21971100000013],[-68.256958,62.220825000000104],[-68.26916499999987,62.22304500000013],[-68.29943800000001,62.23220800000013],[-68.32528699999995,62.234993000000145],[-68.40167199999996,62.23943299999996],[-68.46945199999999,62.24276700000013],[-68.51972999999992,62.24471300000005],[-68.54804999999993,62.248604000000114],[-68.56471299999993,62.25193800000011],[-68.61582899999996,62.26388500000007],[-68.72222899999991,62.302216000000044],[-68.72555499999987,62.30471],[-68.72694399999995,62.30777000000006],[-68.75917099999992,62.32804900000002],[-68.88221699999997,62.3605500000001],[-68.92250100000001,62.36554700000005],[-68.99583399999995,62.37332200000009],[-69.03900099999998,62.38135500000004],[-69.12138400000003,62.410820000000115],[-69.16000399999996,62.42527000000007],[-69.19305400000002,62.43804200000005],[-69.23167399999988,62.4552690000001],[-69.270554,62.4783250000001],[-69.36082499999992,62.53638500000005],[-69.40834000000001,62.56999200000001],[-69.43055699999996,62.584160000000054],[-69.42666600000001,62.55443600000001],[-69.42832900000002,62.548332000000016],[-69.44221500000003,62.54749300000003],[-69.44972199999995,62.551102000000014],[-69.51916499999999,62.602493000000095],[-69.58389299999999,62.6519320000001],[-69.59722899999991,62.66249099999993],[-69.59750400000001,62.665268000000026],[-69.56555199999997,62.71804800000007],[-69.55721999999997,62.72637900000001],[-69.54333500000001,62.732765000000086],[-69.52555799999993,62.73804499999994],[-69.50389100000001,62.74137899999994],[-69.48249799999996,62.763611000000026],[-69.72749299999998,62.77999100000011],[-69.90638699999988,62.76859999999999],[-70.12193299999996,62.748878000000104],[-70.21749899999986,62.74777200000011],[-70.22917199999995,62.748878000000104],[-70.24027999999998,62.751389000000074],[-70.35499599999991,62.78832999999997],[-70.36000099999995,62.79027600000006],[-70.36776700000001,62.79388399999999],[-70.47778299999999,62.84832800000004],[-70.49943499999995,62.864441000000056],[-70.50805699999995,62.86582899999996],[-70.66555800000003,62.88054700000009],[-70.83029199999993,62.89666000000011],[-70.85333299999996,62.899994000000106],[-70.88555899999994,62.90721100000002],[-70.896118,62.91443600000008],[-70.89306599999998,62.917770000000075],[-70.88583399999999,62.920547],[-70.87138400000003,62.924713000000054],[-70.86361699999998,62.92555200000004],[-70.848343,62.924713000000054],[-70.84777799999989,62.947212000000036],[-70.97483799999998,62.98943700000001],[-70.97734100000002,62.983768000000055],[-71.01306199999999,62.98999000000009],[-71.06027199999994,62.98110200000008],[-71.07167099999998,62.979431000000034],[-71.12083399999995,62.979431000000034],[-71.13583399999993,62.98082000000005],[-71.152222,62.98526800000002],[-71.15666199999998,62.989159000000086],[-71.15666199999998,62.99943499999995],[-71.13667299999997,63.028602999999976],[-71.11810300000002,63.032219000000055],[-71.09138499999995,63.02999100000005],[-71.02088899999995,63.0442700000001],[-71.01372499999997,63.04360200000002],[-71.00738499999994,63.04343799999998],[-71.00321999999994,63.044768999999974],[-70.86389200000002,63.112213000000054],[-70.85638399999999,63.13943499999999],[-70.90888999999999,63.17083000000008],[-70.92054699999994,63.16888399999999],[-70.95249899999999,63.16276600000003],[-70.97138999999993,63.158882000000006],[-70.97694399999995,63.15665400000006],[-70.99027999999998,63.14804800000013],[-70.99749800000001,63.14166299999994],[-71.00195300000001,63.128044000000045],[-71.002792,63.123322000000144],[-71.00140399999998,63.118881000000044],[-70.99333200000001,63.112770000000125],[-70.99082900000002,63.10833000000014],[-70.98998999999998,63.10249299999998],[-70.993607,63.09804500000001],[-71.02972399999999,63.07193799999999],[-71.041672,63.06944299999992],[-71.12721299999998,63.071663000000115],[-71.13861099999991,63.073326000000066],[-71.19526699999994,63.03166199999998],[-71.195831,63.026657000000114],[-71.19860799999998,63.01998900000012],[-71.208618,63.01166500000005],[-71.23277300000001,63.00193800000011],[-71.24388099999999,63.00110600000005],[-71.25584400000002,63.00193800000011],[-71.26251200000002,63.00416600000011],[-71.40055799999999,63.05165900000003],[-71.40833999999995,63.05526700000013],[-71.41389500000002,63.060546999999985],[-71.42138699999998,63.071663000000115],[-71.45472699999993,63.10193600000008],[-71.465012,63.1033250000001],[-71.60583499999996,63.134995],[-71.62499999999994,63.14083100000005],[-71.70666499999993,63.17499500000008],[-71.71389799999997,63.179161000000136],[-71.77000399999991,63.25638600000002],[-71.79499800000002,63.326660000000004],[-71.79554699999994,63.38472000000007],[-71.80583199999995,63.382767],[-72.00917099999998,63.391106000000036],[-72.06304899999992,63.39638500000001],[-72.07640099999998,63.398048000000074],[-72.08306900000002,63.40054299999997],[-72.14167800000001,63.436104000000114],[-72.146118,63.43998700000003],[-72.145554,63.44609800000012],[-72.12666299999995,63.450271999999984],[-72.023056,63.44804399999998],[-71.93331899999993,63.443321000000026],[-71.82583599999998,63.43526500000013],[-71.785278,63.431938],[-71.74804699999999,63.428047000000106],[-71.71112099999993,63.42276800000013],[-71.68305999999995,63.41971600000005],[-71.63473499999992,63.41971600000005],[-71.61500499999994,63.422493000000145],[-71.59944200000001,63.42582700000014],[-71.41166699999991,63.48582499999998],[-71.31695599999995,63.530823000000055],[-71.22749299999992,63.598877000000016],[-71.22972099999998,63.60471300000006],[-71.23472600000002,63.608047000000056],[-71.24562099999997,63.61093900000009],[-71.261124,63.612495000000024],[-71.29527300000001,63.612495000000024],[-71.30694599999998,63.611381999999935],[-71.32362399999994,63.60527000000013],[-71.32806399999998,63.602218999999934],[-71.33168,63.59832800000004],[-71.33306900000002,63.583603000000096],[-71.33250399999997,63.58166499999999],[-71.32806399999998,63.57694200000003],[-71.32556199999999,63.571938000000046],[-71.32611099999991,63.57054900000003],[-71.33168,63.56554399999999],[-71.3352809999999,63.564437999999996],[-71.37999000000002,63.56554399999999],[-71.40750100000002,63.567771999999934],[-71.41416899999996,63.57054900000003],[-71.41639700000002,63.57276900000005],[-71.37805200000003,63.59526800000003],[-71.36749299999997,63.60193599999997],[-71.36361699999998,63.60721600000005],[-71.362503,63.61332700000014],[-71.37748699999997,63.632767000000115],[-71.39666699999992,63.635826000000066],[-71.40777600000001,63.63555100000008],[-71.41139199999998,63.63443799999999],[-71.41805999999997,63.62999000000002],[-71.45249899999999,63.60443900000013],[-71.441101,63.59082799999999],[-71.439438,63.58804299999997],[-71.44694499999991,63.580826],[-71.45584100000002,63.57888000000014],[-71.47027599999996,63.578049000000135],[-71.56166100000002,63.58027599999997],[-71.57695000000001,63.58166499999999],[-71.58056599999998,63.58387800000014],[-71.58138999999994,63.59304800000001],[-71.583618,63.64971900000012],[-71.569458,63.67555200000004],[-71.56221,63.685546999999985],[-71.58111600000001,63.714995999999985],[-71.58500700000002,63.71665999999999],[-71.6158289999999,63.72221399999995],[-71.62916599999994,63.72387700000007],[-71.63806199999988,63.72109999999998],[-71.66000400000001,63.70694000000009],[-71.66471899999988,63.70304900000002],[-71.66722099999993,63.697212000000036],[-71.70056199999999,63.69638100000003],[-71.82389799999987,63.78054800000001],[-71.83000199999998,63.78443900000008],[-71.89111300000002,63.80832700000002],[-71.904449,63.80998999999997],[-71.91555800000003,63.810272],[-71.93859900000001,63.80804400000005],[-71.95834400000001,63.802490000000034],[-71.97055099999994,63.795830000000024],[-71.98554999999993,63.78193700000003],[-72.000565,63.76138300000002],[-72.00418100000002,63.752776999999924],[-71.99972500000001,63.748328999999956],[-71.991104,63.74610100000001],[-71.972778,63.7480470000001],[-71.966949,63.75110600000005],[-71.95472699999993,63.76527400000009],[-71.94665499999996,63.77027100000004],[-71.93916299999995,63.77249100000006],[-71.93443300000001,63.77276600000005],[-71.853882,63.76138300000002],[-71.84861799999999,63.759438000000046],[-71.843887,63.75555400000002],[-71.87943999999999,63.681937999999946],[-71.88276699999994,63.67804700000005],[-71.92027300000001,63.655548000000124],[-71.93388400000003,63.649437000000034],[-71.96362299999998,63.64916200000005],[-72.05194099999994,63.67860399999995],[-72.15417500000001,63.7355500000001],[-72.16944899999999,63.748604],[-72.21305799999999,63.68387600000011],[-72.21278399999994,63.68055000000004],[-72.21389799999992,63.677772999999945],[-72.218887,63.67388200000005],[-72.22389199999986,63.67221800000004],[-72.23416099999997,63.670273000000066],[-72.24526999999995,63.669715999999994],[-72.28694200000001,63.67166099999997],[-72.31750499999998,63.67416400000013],[-72.32417299999997,63.67665899999997],[-72.32749899999999,63.67971799999998],[-72.36389199999996,63.749435000000005],[-72.36361699999998,63.754440000000045],[-72.35777299999995,63.76138300000002],[-72.35278299999999,63.76527400000009],[-72.34249899999998,63.77137800000014],[-72.32472200000001,63.77693900000003],[-72.31777999999991,63.77777100000009],[-72.30277999999993,63.776657000000114],[-72.29138199999994,63.77360500000003],[-72.27000399999991,63.787216],[-72.215012,63.86776700000007],[-72.20973200000003,63.89305100000007],[-72.223053,63.92943600000001],[-72.2327729999999,63.94832599999995],[-72.23889200000002,63.95249200000006],[-72.24638400000003,63.95027200000004],[-72.25056499999994,63.94776900000005],[-72.36471599999993,63.845543000000134],[-72.38305699999995,63.81554399999993],[-72.37638899999996,63.812209999999936],[-72.37165800000002,63.809158000000025],[-72.36694299999999,63.80471000000006],[-72.36555499999992,63.80027000000007],[-72.36305199999993,63.79110700000007],[-72.36805699999996,63.7824940000001],[-72.372772,63.77860300000003],[-72.43611099999993,63.78166199999998],[-72.51583899999997,63.786384999999996],[-72.52639799999992,63.78777300000007],[-72.531387,63.79110700000007],[-72.53222700000003,63.79666100000003],[-72.531387,63.79943800000012],[-72.51972999999992,63.80471000000006],[-72.49665800000002,63.803604000000064],[-72.47416699999991,63.80471000000006],[-72.46389799999997,63.806655999999975],[-72.45973199999997,63.809158000000025],[-72.45611600000001,63.81443800000011],[-72.456955,63.815826000000015],[-72.46501199999994,63.81916000000001],[-72.52111799999994,63.84027100000003],[-72.537216,63.844154],[-72.585556,63.852776000000006],[-72.63473499999998,63.85249300000004],[-72.63751200000002,63.87360400000006],[-72.64111299999996,63.904434000000094],[-72.61166399999996,63.94304699999998],[-72.59277299999985,64.01805100000013],[-72.59277299999985,64.02221700000007],[-72.6583399999999,64.07666],[-72.66471899999993,64.08055100000007],[-72.67471299999994,64.083328],[-72.68249500000002,64.07971199999997],[-72.68554699999993,64.07638500000002],[-72.68804899999998,64.07054099999999],[-72.70472699999999,64.01554900000008],[-72.70584100000002,64.00915500000002],[-72.70249899999993,64.00555399999996],[-72.69694500000003,64.00305200000008],[-72.66833500000001,63.996101000000124],[-72.66000400000001,63.992493000000024],[-72.658615,63.98777000000007],[-72.66639699999996,63.980545000000006],[-72.67887899999994,63.972488000000055],[-72.69249000000002,63.966660000000104],[-72.69972200000001,63.96443900000003],[-72.72000099999997,63.96110500000003],[-72.75334199999992,64.00027499999999],[-72.75834699999996,64.00416600000005],[-72.779449,64.01054400000004],[-72.83612099999999,64.01971400000008],[-72.93138099999999,64.05247500000002],[-72.94027699999998,64.05859400000003],[-72.94137599999999,64.06359900000007],[-72.93971299999987,64.06776400000007],[-72.93331899999998,64.07638500000002],[-72.92555199999987,64.08415200000013],[-72.91972399999992,64.08692900000005],[-72.91111799999993,64.08859300000006],[-72.88806199999999,64.08610500000009],[-72.87832600000002,64.08665500000012],[-72.874435,64.08859300000006],[-72.87083399999995,64.09387200000003],[-72.86888099999993,64.09915200000012],[-72.86833200000001,64.10832199999999],[-72.89723200000003,64.15693700000003],[-72.90527299999991,64.1649930000001],[-72.91166699999997,64.16886899999997],[-73.22389199999992,64.31164600000011],[-73.27111799999989,64.28387500000002],[-73.26722699999999,64.27388000000013],[-73.27000399999997,64.26582300000013],[-73.273056,64.26249700000011],[-73.27917499999995,64.25860600000004],[-73.33972199999994,64.25804099999999],[-73.36582900000002,64.26193200000006],[-73.38055400000002,64.26860000000005],[-73.38417099999998,64.27249100000012],[-73.3869479999999,64.27748099999997],[-73.4177699999999,64.37109399999991],[-73.41555800000003,64.44581600000004],[-73.32695000000001,64.476089],[-73.16777000000002,64.57666000000012],[-73.16471899999993,64.57971200000003],[-73.16471899999993,64.60554499999995],[-73.16555799999998,64.60748300000012],[-73.16944899999987,64.609985],[-73.29695099999992,64.65693700000008],[-73.30277999999993,64.65887500000002],[-73.30943300000001,64.65860000000004],[-73.34222399999993,64.64415000000008],[-73.34666400000003,64.641098],[-73.34750400000001,64.63499500000006],[-73.34111000000001,64.62608300000005],[-73.32611099999997,64.609985],[-73.31443799999994,64.59803800000003],[-73.308044,64.593323],[-73.30221599999999,64.58387800000008],[-73.29861499999993,64.55941800000011],[-73.29916399999996,64.54498299999995],[-73.30332899999996,64.53831500000001],[-73.30749499999996,64.53581200000002],[-73.31527699999992,64.53221100000013],[-73.32417299999986,64.52998400000007],[-73.42416400000002,64.509995],[-73.46333300000003,64.50248699999997],[-73.47222899999997,64.5044400000001],[-73.47582999999992,64.50804099999993],[-73.47721899999999,64.51220700000005],[-73.473053,64.55358900000004],[-73.44871499999994,64.56542200000001],[-73.46722399999999,64.61276200000009],[-73.59500099999997,64.62969999999996],[-73.65556300000003,64.63165300000009],[-73.65556300000003,64.62359600000013],[-73.66749600000003,64.57720900000004],[-73.7502899999999,64.53637700000007],[-73.75389100000001,64.53526300000004],[-73.76445000000001,64.53749100000005],[-73.78778099999994,64.54803500000008],[-73.80305499999992,64.555252],[-73.821121,64.56749000000008],[-73.837784,64.57971200000003],[-73.84944200000001,64.58749399999999],[-73.86138899999997,64.59443699999997],[-73.87666299999995,64.60081500000013],[-73.88694799999996,64.60359200000005],[-73.91027799999995,64.60582],[-73.92027299999995,64.60525500000011],[-73.92944299999999,64.60220300000003],[-73.93249500000002,64.5935970000001],[-73.931107,64.58387800000008],[-73.84472699999998,64.501938],[-73.92555199999993,64.46026599999993],[-73.97277799999989,64.43026700000013],[-73.99943499999989,64.32804899999996],[-74.06277499999999,64.33442700000012],[-74.10221899999988,64.36747699999995],[-74.12805199999991,64.533051],[-74.12748699999997,64.53442400000012],[-74.10583500000001,64.53581200000002],[-74.08222999999992,64.53498800000006],[-74.06527699999992,64.533051],[-74.05555700000002,64.61053500000003],[-74.05055199999998,64.72499100000005],[-74.05387899999994,64.7285920000001],[-74.06054699999999,64.7333220000001],[-74.089722,64.75109900000001],[-74.09611499999994,64.75138900000002],[-74.11444099999994,64.7458190000001],[-74.120544,64.74192800000003],[-74.19526699999989,64.66304000000002],[-74.20889299999993,64.61415100000005],[-74.212784,64.60276800000008],[-74.22471599999994,64.59248400000001],[-74.24027999999998,64.58027600000014],[-74.38194299999992,64.56999200000013],[-74.390289,64.56971699999991],[-74.39750700000002,64.57222000000007],[-74.535278,64.62220800000006],[-74.65750099999997,64.7002720000001],[-74.70167500000002,64.732483],[-74.7041779999999,64.73553500000008],[-74.70083599999987,64.74026500000014],[-74.68331899999993,64.75833100000011],[-74.56750499999998,64.83276400000005],[-74.50111399999997,64.83360300000004],[-74.48777799999993,64.83415200000002],[-74.478882,64.83581500000008],[-74.47639500000002,64.83888200000001],[-74.47694399999995,64.84165999999999],[-74.54055799999998,64.88916],[-74.54583699999995,64.89221200000009],[-74.56111099999993,64.89610299999998],[-74.62193299999996,64.90386999999993],[-74.63999899999993,64.90359500000011],[-74.64862099999993,64.90138200000013],[-74.66027799999989,64.89637800000003],[-74.73277300000001,64.85470599999996],[-74.74137899999994,64.84748800000011],[-74.74305700000002,64.84220900000014],[-74.74194299999999,64.83581500000008],[-74.73889200000002,64.8313750000001],[-74.72222899999997,64.82222000000002],[-74.71472199999994,64.81553599999995],[-74.71000700000002,64.81053200000002],[-74.70666499999999,64.80053700000008],[-74.70666499999999,64.79498300000012],[-74.71083099999998,64.78276100000011],[-74.71888699999994,64.77360499999998],[-74.72639499999997,64.77082800000011],[-74.837219,64.77859500000005],[-74.86833200000001,64.78193699999997],[-74.89334100000002,64.78471400000006],[-74.90222199999994,64.78804000000008],[-74.90916400000003,64.79136700000004],[-74.91583300000002,64.79582200000004],[-74.92443800000001,64.799149],[-74.94415300000003,64.80358900000004],[-74.95500199999998,64.80442800000014],[-74.97555499999987,64.80137600000006],[-74.98527499999994,64.79582200000004],[-74.98554999999988,64.79026800000008],[-74.98249800000002,64.78526300000004],[-74.978882,64.78137200000015],[-74.96333299999998,64.77360499999998],[-74.83473200000003,64.71638500000012],[-74.73332199999999,64.68553199999997],[-74.69444299999998,64.676376],[-74.67555199999998,64.67025800000005],[-74.66000399999996,64.66387900000001],[-74.61305199999993,64.64027400000003],[-74.54527300000001,64.60220300000003],[-74.512787,64.5836030000001],[-74.47528099999994,64.56137100000001],[-74.47000099999997,64.55747999999994],[-74.47084000000001,64.555542],[-74.51362599999987,64.5333250000001],[-74.52027900000002,64.53221100000013],[-74.58583099999998,64.48027000000008],[-74.68554699999999,64.39193699999998],[-74.68582199999997,64.37109399999991],[-74.79777499999994,64.38081399999999],[-74.974716,64.41609199999999],[-74.98527499999994,64.41886900000009],[-75.01055899999994,64.42997700000012],[-75.05638099999999,64.45220899999998],[-75.14250199999998,64.48332199999999],[-75.174713,64.49275200000005],[-75.18276999999995,64.49247700000006],[-75.18859899999995,64.48942600000004],[-75.1888889999999,64.48332199999999],[-75.18721,64.47360200000008],[-75.18249500000002,64.46832300000011],[-75.17721599999999,64.46470599999998],[-75.15139799999992,64.46026599999993],[-75.14611799999994,64.45721400000002],[-75.14416499999993,64.45304900000002],[-75.15055799999999,64.447205],[-75.15444899999994,64.44470200000006],[-75.19972199999995,64.42804000000007],[-75.20777900000002,64.42776500000002],[-75.21556099999998,64.42886400000003],[-75.22416699999991,64.43220500000007],[-75.29527299999995,64.46665999999999],[-75.32389799999999,64.48193400000008],[-75.33250399999997,64.49081400000011],[-75.34416199999993,64.49914600000011],[-75.34973100000002,64.50221300000004],[-75.38166799999999,64.51361100000003],[-75.40916400000003,64.5227660000001],[-75.47972099999993,64.53915399999994],[-75.49082900000002,64.53970300000009],[-75.56610099999995,64.54998800000004],[-75.66639699999996,64.56387300000011],[-75.693329,64.56999200000013],[-75.70388799999995,64.57276900000005],[-75.72138999999999,64.57916300000005],[-75.73693800000001,64.58610499999998],[-75.74722300000002,64.59443699999997],[-75.76362599999999,64.60498000000013],[-75.77389499999992,64.60832200000004],[-75.79695100000004,64.61219800000015],[-75.82417299999997,64.611649],[-75.84306300000003,64.6077580000001],[-75.84722899999991,64.60443099999998],[-75.837219,64.56137100000001],[-75.82362399999994,64.53581200000002],[-75.818893,64.53082300000005],[-75.80749500000002,64.52526900000004],[-75.729172,64.50305199999997],[-75.64472999999992,64.46887200000003],[-75.63944999999995,64.46527100000003],[-75.63055400000002,64.45721400000002],[-75.63166799999999,64.453598],[-75.63612399999994,64.44914200000005],[-75.641388,64.44802899999996],[-75.69665500000002,64.43942300000009],[-75.70834399999995,64.43775900000003],[-75.72778299999993,64.44247400000006],[-75.74694799999997,64.45304900000002],[-75.76583900000003,64.46527100000003],[-75.77305599999994,64.46748400000013],[-75.87471,64.48692300000005],[-75.89527900000002,64.48803700000002],[-75.90833999999995,64.48719800000003],[-75.92027300000001,64.484421],[-75.92250099999995,64.48109400000004],[-75.910553,64.47831700000012],[-75.87527499999999,64.47387700000013],[-75.85777299999995,64.46804800000007],[-75.72083999999995,64.38333100000006],[-75.71722399999999,64.37970000000001],[-75.718887,64.37441999999999],[-75.72332799999992,64.36970500000012],[-75.726944,64.36720300000002],[-75.83805799999999,64.36914100000001],[-75.86166400000002,64.37109399999991],[-75.95056199999993,64.39915500000001],[-76.04388399999999,64.36831700000005],[-76.25361599999997,64.35775799999999],[-76.26445000000001,64.31915300000003],[-76.214722,64.31498699999997],[-76.20556599999998,64.313309],[-76.19665500000002,64.31080600000007],[-76.18832399999985,64.30693100000008],[-76.18971299999993,64.301376],[-76.19721999999996,64.29693600000013],[-76.20584099999996,64.29470800000001],[-76.30055199999998,64.27886999999998],[-76.48472599999997,64.266663],[-76.493607,64.26860000000005],[-76.50306699999999,64.2752690000001],[-76.50695799999994,64.284424],[-76.50556899999992,64.289154],[-76.50361599999991,64.29109199999994],[-76.50250199999994,64.29525800000005],[-76.50666799999993,64.29748500000011],[-76.541382,64.30470300000007],[-76.591949,64.31053199999991],[-76.70584099999996,64.30081200000001],[-76.71945199999993,64.29664600000012],[-76.73388699999987,64.29054300000001],[-76.73666400000002,64.28581200000008],[-76.73889200000002,64.27638200000001],[-76.72166399999998,64.23831200000006],[-76.714722,64.23387099999997],[-76.70611599999995,64.23136900000009],[-76.68472299999996,64.22776800000003],[-76.67443800000001,64.22499099999993],[-76.66722099999993,64.22192400000006],[-76.660278,64.218323],[-76.65472399999993,64.20915200000002],[-76.65472399999993,64.19664000000006],[-76.65834000000001,64.18997200000007],[-76.66221599999994,64.18664600000005],[-76.67054699999994,64.18414300000006],[-76.84722899999997,64.23054500000012],[-76.9683379999999,64.25972000000002],[-77.13833599999998,64.28942900000004],[-77.27610800000002,64.2563780000001],[-77.29611199999994,64.25193800000005],[-77.32749899999999,64.24636799999996],[-77.351944,64.24386600000008],[-77.366104,64.24386600000008],[-77.37999000000002,64.2452550000001],[-77.38137799999998,64.246643],[-77.38221699999997,64.2494200000001],[-77.38137799999998,64.253601],[-77.37887599999993,64.25694300000009],[-77.43415800000002,64.320267],[-77.58833299999998,64.36831700000005],[-77.65222199999994,64.38804600000009],[-77.660278,64.38638300000002],[-77.664444,64.3836060000001],[-77.6658329999999,64.37692300000015],[-77.66471899999999,64.37414600000005],[-77.65888999999999,64.36499000000009],[-77.67971799999998,64.32110599999999],[-77.74722299999996,64.33776900000004],[-77.83138999999994,64.41249099999999],[-77.97027600000001,64.45443699999993],[-78.17805499999997,64.56749000000008],[-78.18331899999993,64.57249500000012],[-78.16857899999997,64.62619799999993],[-78.160553,64.69053600000007],[-78.18443300000001,64.73109399999998],[-78.07362399999994,64.81359900000012],[-78.064438,64.84942600000005],[-78.06527699999987,64.85359199999999],[-78.06639100000001,64.85582000000011],[-78.07362399999994,64.859421],[-78.10249299999998,64.86886600000003],[-78.11721799999992,64.876083],[-78.120834,64.88108800000003],[-78.12971500000003,64.89387500000004],[-78.146118,64.938309],[-78.148056,64.94386299999996],[-78.14973399999997,64.95220900000004],[-78.14527900000002,64.95748900000012],[-77.973053,65.04136699999998],[-77.67971799999998,65.12330600000001],[-77.54361,65.1397090000001],[-77.50306699999993,65.138596],[-77.48832699999991,65.13943499999993],[-77.47972099999998,65.14109800000006],[-77.34472699999998,65.17330900000013],[-77.32861299999996,65.17886400000003],[-77.32278399999996,65.18331900000004],[-77.31582599999996,65.19053600000001],[-77.31304899999998,65.19581600000004],[-77.31555200000003,65.1994170000001],[-77.3824919999999,65.2474820000001],[-77.39723200000003,65.25499000000013],[-77.42277499999994,65.26443500000005],[-77.44471699999991,65.27554300000003],[-77.49804699999999,65.30664100000001],[-77.51306199999993,65.31887799999998],[-77.515015,65.32582099999996],[-77.51222200000001,65.33055100000001],[-77.471115,65.37136800000002],[-77.466949,65.37525900000009],[-77.46112099999988,65.37914999999998],[-77.45249899999988,65.38081399999999],[-77.43804899999992,65.37970000000001],[-77.41361999999998,65.37164300000006],[-77.40249599999999,65.36914100000013],[-77.3458399999999,65.35859700000009],[-77.337784,65.35748300000012],[-77.32305899999994,65.35775799999993],[-77.30610699999994,65.35971100000006],[-77.295547,65.36192299999993],[-77.29194599999994,65.36387600000006],[-77.28750599999995,65.367752],[-77.287216,65.37525900000009],[-77.28999299999992,65.37886000000015],[-77.29527300000001,65.38333100000006],[-77.319458,65.393326],[-77.32695000000001,65.39553800000004],[-77.341949,65.40165700000006],[-77.36749299999991,65.4124910000001],[-77.39862099999993,65.42665100000005],[-77.42027299999995,65.43997200000001],[-77.42832900000002,65.44775400000015],[-77.43443299999996,65.45694000000009],[-77.43055699999991,65.45887800000003],[-77.42166099999997,65.46138000000008],[-77.385559,65.46804800000007],[-77.33667000000003,65.47137500000002],[-77.26528899999988,65.47192399999994],[-77.23805199999993,65.46943700000008],[-77.154449,65.44581599999998],[-77.13473499999998,65.43942300000003],[-77.12443499999989,65.434143],[-77.11582899999996,65.42970300000013],[-77.11166399999996,65.426086],[-77.11111499999993,65.42137100000014],[-77.10638399999999,65.41360500000008],[-77.09944200000001,65.40914900000001],[-77.08666999999997,65.40721100000007],[-76.962784,65.40721100000007],[-76.956955,65.41053799999997],[-76.95249899999999,65.41499300000004],[-76.95611600000001,65.42137100000014],[-76.95556599999998,65.42275999999998],[-76.95167500000002,65.42526200000003],[-76.94444299999998,65.42776500000002],[-76.920837,65.42942800000014],[-76.84999099999999,65.42831399999994],[-76.82472200000001,65.42526200000003],[-76.62693799999994,65.39888000000013],[-76.36193799999995,65.34220900000003],[-76.23500100000001,65.31275900000014],[-76.164444,65.29609700000015],[-76.07250999999991,65.27720599999992],[-75.96665999999999,65.25582900000012],[-75.953888,65.25526400000007],[-75.92527799999993,65.25721700000003],[-75.92027300000001,65.258331],[-75.91221599999994,65.25721700000003],[-75.89834599999995,65.25387599999999],[-75.80555699999996,65.22970599999996],[-75.78555299999994,65.22442600000011],[-75.76916499999999,65.21887200000009],[-75.76501499999989,65.21666000000005],[-75.76000999999991,65.21081500000014],[-75.741379,65.17387400000001],[-75.73998999999992,65.16832],[-75.57084700000001,65.12081899999993],[-75.52861000000001,65.10887100000008],[-75.47500600000001,65.08610500000009],[-75.46665999999999,65.08221400000002],[-75.45722999999992,65.07470700000005],[-75.44694500000003,65.06581100000011],[-75.42805499999997,65.04832499999998],[-75.42443800000001,65.04386900000009],[-75.41055299999994,65.0247040000001],[-75.41555799999998,64.97747800000008],[-75.42027300000001,64.97221400000006],[-75.42805499999997,64.968323],[-75.49694799999997,64.94053600000007],[-75.50723299999999,64.938309],[-75.51916499999993,64.93691999999999],[-75.53361499999994,64.93691999999999],[-75.55722000000003,64.94026200000013],[-75.63473499999992,64.94720500000011],[-75.65444899999994,64.94636500000007],[-75.66305499999993,64.9452510000001],[-75.66749600000003,64.94081100000005],[-75.601944,64.86775200000005],[-75.59416199999998,64.86025999999993],[-75.5875089999999,64.85664400000007],[-75.56806899999998,64.85054000000002],[-75.55555700000002,64.84860200000008],[-75.46139499999992,64.811646],[-75.38917500000002,64.73609900000002],[-75.37304699999999,64.7149960000001],[-75.31666599999994,64.71943700000003],[-75.30833399999989,64.72109999999998],[-75.29818699999998,64.72576900000013],[-75.29472399999997,64.72804300000013],[-75.29138199999989,64.73387100000008],[-75.289444,64.73997500000007],[-75.29138199999989,64.74443100000002],[-75.30221599999993,64.75109900000001],[-75.31054699999993,64.75499000000008],[-75.32972699999999,64.76110799999998],[-75.33389299999999,64.76332100000013],[-75.34416199999993,64.77221700000007],[-75.37388599999991,64.83305400000012],[-75.35722399999992,64.8977660000001],[-75.422775,64.89027399999998],[-75.45167500000002,64.87525900000003],[-75.46083099999998,64.87164300000012],[-75.46972700000003,64.86943100000008],[-75.55749499999996,64.87414600000011],[-75.56332399999997,64.87719700000014],[-75.56555200000003,64.87942500000008],[-75.56750499999998,64.88360599999999],[-75.56527699999998,64.88693200000006],[-75.47389199999992,64.93580600000001],[-75.390289,64.97943099999998],[-75.38473499999998,64.98193400000014],[-75.3760989999999,64.98332200000004],[-75.36305199999998,64.98414600000001],[-75.35333299999996,64.98359700000009],[-75.34416199999993,64.9810940000001],[-75.335556,64.97776800000008],[-75.26417500000002,64.96609500000005],[-75.19610599999999,65.06860400000011],[-75.18916300000001,65.07971200000009],[-75.18554699999987,65.09136999999993],[-75.18693499999995,65.101654],[-75.19249000000002,65.10554500000006],[-75.19665500000002,65.10720799999996],[-75.21250899999995,65.10942100000011],[-75.22555499999999,65.10942100000011],[-75.24082899999996,65.10832199999993],[-75.25917099999998,65.10220300000009],[-75.26362599999999,65.0977630000001],[-75.26556399999993,65.09165999999999],[-75.26251200000002,65.08055100000007],[-75.26000999999985,65.07276900000011],[-75.261124,65.05914299999995],[-75.26306199999993,65.05219999999997],[-75.27999899999998,65.03526299999999],[-75.29972799999996,65.0247040000001],[-75.34861799999993,65.00387600000005],[-75.36000100000001,65.00387600000005],[-75.36749299999997,65.0063780000001],[-75.37304699999999,65.00943000000001],[-75.37887599999999,65.01666300000005],[-75.379166,65.02137800000008],[-75.38110399999994,65.02581800000007],[-75.40249599999987,65.0558170000001],[-75.41000399999996,65.063873],[-75.42555199999998,65.07720899999993],[-75.44137599999999,65.089157],[-75.44804399999998,65.09414700000002],[-75.51640299999985,65.138596],[-75.72805800000003,65.22415199999995],[-75.76194799999996,65.23776200000003],[-75.78167699999995,65.24304200000012],[-75.835556,65.25526400000007],[-75.86416600000001,65.258331],[-75.89056399999998,65.26915000000008],[-75.93971299999998,65.29248000000001],[-75.94387799999998,65.29525799999999],[-75.95083599999998,65.3163760000001],[-75.950287,65.31832900000006],[-75.941101,65.32138099999997],[-75.93110699999988,65.32222000000013],[-75.904449,65.32222000000013],[-75.87388599999991,65.3205410000001],[-75.85777299999995,65.31915300000003],[-75.60305799999998,65.29553199999992],[-75.59222399999993,65.28720100000004],[-75.57556199999993,65.27804600000002],[-75.5663909999999,65.27499400000005],[-75.55526700000001,65.27360500000009],[-75.495834,65.26915000000008],[-75.48443599999996,65.26832600000012],[-75.21194500000001,65.25054900000003],[-75.18666100000002,65.25193800000005],[-75.153885,65.25694300000009],[-75.114441,65.26638799999995],[-75.10166900000002,65.27137800000003],[-75.09388699999994,65.27499400000005],[-75.083618,65.28610200000008],[-75.08167999999989,65.29220600000008],[-75.07084700000001,65.33027600000003],[-75.09083599999991,65.355545],[-75.10916099999986,65.37997400000012],[-75.11082499999998,65.38472000000007],[-75.11111499999998,65.38888500000007],[-75.11054999999993,65.391098],[-75.10804699999994,65.39305100000013],[-75.097778,65.39498900000007],[-75.08277899999996,65.39498900000007],[-74.82362399999994,65.37747200000007],[-74.660553,65.34637499999997],[-74.64584400000001,65.3413700000001],[-74.63500999999997,65.338593],[-74.62416100000002,65.33665500000006],[-74.58944699999995,65.33248900000012],[-74.54666099999992,65.33137499999998],[-74.52444500000001,65.33332800000011],[-74.508621,65.33665500000006],[-74.49694799999997,65.34082000000006],[-74.35777300000001,65.39860499999998],[-74.34783899999996,65.40718100000004],[-74.32389799999999,65.43775900000003],[-74.31889299999995,65.447205],[-74.31527699999998,65.45803799999999],[-74.31138599999991,65.46388200000001],[-74.18277,65.52526900000004],[-74.10583500000001,65.53498800000006],[-73.84527600000001,65.53221100000013],[-73.791382,65.524429],[-73.76777600000003,65.52082800000011],[-73.74722299999996,65.51748700000007],[-73.73693799999995,65.5147090000001],[-73.73277299999995,65.511932],[-73.73138399999993,65.50694300000004],[-73.73083500000001,65.50416600000011],[-73.73500100000001,65.50166299999995],[-73.74027999999998,65.49693300000013],[-73.74082900000002,65.49081400000011],[-73.73693799999995,65.48776199999998],[-73.71167000000003,65.47109999999998],[-73.70306399999993,65.4669340000001],[-73.69415299999991,65.46443200000004],[-73.66389500000002,65.45694000000009],[-73.65139799999997,65.45471199999992],[-73.64111300000002,65.45526100000006],[-73.5599979999999,65.46249400000005],[-73.50056499999994,65.47442600000005],[-73.56361400000003,65.56219499999997],[-73.61833200000001,65.61970500000007],[-73.66221599999994,65.65859999999998],[-73.68415799999991,65.71527100000009],[-73.68499799999995,65.730545],[-73.70472699999993,65.75804100000005],[-73.70973199999992,65.762497],[-73.72055099999989,65.76944000000015],[-73.81082199999997,65.81109600000013],[-73.84111000000001,65.81999200000007],[-73.88417099999998,65.82193000000001],[-73.886124,65.82138100000003],[-73.92361499999998,65.82443200000006],[-73.93167099999994,65.82554600000003],[-73.94249000000002,65.82832300000013],[-74.01194799999996,65.85470599999991],[-74.02917499999995,65.86192300000005],[-74.05804399999994,65.87553400000002],[-74.12943999999999,65.92469799999998],[-74.258896,66.00166300000006],[-74.29695099999998,66.01832600000012],[-74.337784,66.03665200000012],[-74.37388599999997,66.05386399999998],[-74.38806199999993,66.06164600000011],[-74.42555199999993,66.08471700000013],[-74.44499200000001,66.09693900000008],[-74.45556599999986,66.10582000000005],[-74.47138999999999,66.12719700000008],[-74.47277799999995,66.13304100000005],[-74.47250400000001,66.13916000000012],[-74.47000099999997,66.14582800000005],[-74.46611000000001,66.1519320000001],[-74.44665500000002,66.1685940000001],[-74.43443299999996,66.178314],[-74.406113,66.19581600000004],[-74.36665299999993,66.21415700000006],[-74.34222399999999,66.22526600000009],[-74.31639099999995,66.23525999999993],[-74.30665599999998,66.238876],[-74.18721,66.26971399999996],[-74.07778899999994,66.30081200000001],[-73.86082499999992,66.38832100000008],[-73.74499500000002,66.43775900000003],[-73.66610700000001,66.47192400000012],[-73.60665899999998,66.49525499999999],[-73.52999899999998,66.52276600000005],[-73.460556,66.54443400000014],[-73.44415300000003,66.55108600000005],[-73.43055699999991,66.55831900000004],[-73.42027299999995,66.57165500000002],[-73.41833500000001,66.57971199999997],[-73.41833500000001,66.58471700000001],[-73.41639699999996,66.58998100000002],[-73.40028399999994,66.61164900000011],[-73.39695699999999,66.61554000000001],[-73.37971499999998,66.63247700000005],[-73.351944,66.64999400000005],[-73.32833900000003,66.6602630000001],[-73.29638699999998,66.66581700000006],[-73.26722699999999,66.6727600000001],[-73.10861199999994,66.72331199999996],[-73.00111400000003,66.81553600000012],[-72.87388599999997,66.93193099999996],[-72.85249299999998,66.9685970000001],[-72.837784,66.99803199999997],[-72.83138999999989,67.01332100000008],[-72.83111599999995,67.01832600000012],[-72.82806399999993,67.02499400000005],[-72.82417299999997,67.0294340000001],[-72.80665599999992,67.03720100000004],[-72.79167199999995,67.04332000000005],[-72.73889199999991,67.06303400000002],[-72.71665999999993,67.06860400000005],[-72.68499799999995,67.076096],[-72.62609900000001,67.08471700000013],[-72.55082700000003,67.082764],[-72.52583299999998,67.08332800000011],[-72.46417200000002,67.08998100000008],[-72.43110699999994,67.09609999999992],[-72.39944500000001,67.10359200000005],[-72.368607,67.11248799999998],[-72.35139499999997,67.11970500000012],[-72.337784,67.12637300000006],[-72.31555200000003,67.1394350000001],[-72.28250100000002,67.16110200000014],[-72.27610800000002,67.16693099999998],[-72.2583469999999,67.24803199999991],[-72.28694200000001,67.29081700000006],[-72.36361699999998,67.353317],[-72.43638599999991,67.47221400000012],[-72.48111,67.609711],[-72.48582499999992,67.62303199999997],[-72.49082900000002,67.62831100000011],[-72.49749799999995,67.63304099999993],[-72.508896,67.63638300000008],[-72.597778,67.6397090000001],[-72.66639699999996,67.68414300000006],[-72.67639199999996,67.69386299999996],[-72.67777999999998,67.69941699999998],[-72.67500299999995,67.70526099999995],[-72.66888399999993,67.71054100000003],[-72.66166699999991,67.71470600000004],[-72.61389200000002,67.73525999999998],[-72.59695399999993,67.740814],[-72.59194899999989,67.74331699999999],[-72.58332799999988,67.75027499999999],[-72.60888699999998,67.78581200000008],[-72.612503,67.79026800000003],[-72.61944599999993,67.79470800000001],[-72.73500100000001,67.84165999999993],[-72.82000700000003,67.85108900000012],[-72.833328,67.84999100000005],[-72.84388699999994,67.85081500000001],[-72.84805299999994,67.8535920000001],[-72.94221500000003,67.92526200000009],[-72.94444299999998,67.92804000000007],[-72.94499200000001,67.93081699999999],[-72.94387799999987,67.93775900000009],[-72.94249000000002,67.94108599999998],[-72.92999299999997,67.94886799999995],[-72.92277499999994,67.95277400000003],[-72.90417500000001,67.95971700000001],[-72.90249599999993,67.96388200000001],[-72.89611799999994,68.01416],[-72.910553,68.05415300000004],[-72.91389500000002,68.06080600000001],[-72.94110099999995,68.07832300000007],[-72.956955,68.09498600000012],[-72.98111,68.13916000000006],[-72.99276700000001,68.19859300000007],[-72.99388099999999,68.21220400000004],[-73.16111799999999,68.22886699999992],[-73.19027699999992,68.24887100000007],[-73.189438,68.25471500000003],[-73.18998699999992,68.25943000000007],[-73.19471699999997,68.26527400000009],[-73.20083599999998,68.26971400000014],[-73.21556099999992,68.27276600000005],[-73.27111799999989,68.28193699999997],[-73.30332899999996,68.27843499999994],[-73.31449900000001,68.27843499999994],[-73.33667000000003,68.27560400000004],[-73.355186,68.26783],[-73.395554,68.25860599999993],[-73.49610899999993,68.27554299999997],[-73.41000400000001,68.31080600000013],[-73.39916999999997,68.31498700000003],[-73.35467499999993,68.32921599999997]],[[-124.43055699999996,73.8785860000001],[-124.45028699999995,73.8785860000001],[-124.46721600000001,73.8808140000001],[-124.515289,73.89498900000001],[-124.53666699999991,73.90248099999991],[-124.546112,73.90664700000002],[-124.55055199999998,73.91220100000004],[-124.55277999999993,73.91693100000003],[-124.53056299999997,73.91748000000001],[-124.5133439999999,73.91665600000005],[-124.43250299999994,73.91276600000003],[-124.42027300000001,73.90914900000007],[-124.41583300000002,73.90498400000007],[-124.40888999999993,73.90026900000004],[-124.40943899999996,73.89332600000006],[-124.42027300000001,73.882477],[-124.43055699999996,73.8785860000001]],[[-99.80455799999993,73.8890990000001],[-99.73277300000001,73.8499910000001],[-99.71362299999987,73.84637500000002],[-99.58972199999988,73.8377690000001],[-99.53138699999994,73.83194000000009],[-99.49388099999999,73.82582100000008],[-99.48028599999998,73.82193000000001],[-99.2350009999999,73.73776199999992],[-99.115005,73.74859600000002],[-98.97193900000002,73.75054899999992],[-98.82917799999996,73.75166300000012],[-98.756393,73.75610400000005],[-98.71665999999999,73.76666300000005],[-98.68832399999997,73.77201800000012],[-98.641953,73.77720600000004],[-98.51444999999995,73.78749099999999],[-98.42443799999995,73.7935940000001],[-98.29083299999996,73.80165100000005],[-98.20722999999992,73.80525200000011],[-98.19055200000003,73.80358899999999],[-98.17999299999991,73.80415299999993],[-98.13417099999987,73.80970800000006],[-98.09500099999997,73.81553600000012],[-98.07167099999992,73.81944300000009],[-97.976944,73.84275800000006],[-97.96028100000001,73.84693899999996],[-97.94833399999999,73.851654],[-97.9430539999999,73.85693400000008],[-97.94276399999995,73.86276200000003],[-97.94137599999999,73.86804200000006],[-97.93638599999991,73.87831100000011],[-97.91833500000001,73.89027399999998],[-97.90834000000001,73.89471400000014],[-97.88751200000002,73.899429],[-97.80526700000001,73.91110200000003],[-97.78805499999999,73.91276600000003],[-97.76194800000002,73.911926],[-97.58195499999994,73.89387500000004],[-97.56277499999999,73.89082300000007],[-97.54472399999992,73.88610800000004],[-97.52917500000001,73.87970000000007],[-97.52084400000001,73.87387100000007],[-97.51417500000002,73.86775200000005],[-97.50028999999995,73.86192300000005],[-97.47138999999999,73.85775800000005],[-97.456955,73.85775800000005],[-97.39973399999991,73.85887100000014],[-97.35777299999995,73.8624880000001],[-97.34584000000001,73.86499000000015],[-97.32749899999999,73.86581400000011],[-97.26028400000001,73.8602600000001],[-97.22361799999993,73.85636900000003],[-96.97250400000001,73.74414100000001],[-96.96221899999989,73.73858600000011],[-96.95584100000002,73.73248299999995],[-96.93721,73.70359800000011],[-96.93277,73.69220000000007],[-96.93472300000002,73.68692000000004],[-96.96389799999997,73.63998399999997],[-96.968613,73.633331],[-96.98889199999996,73.62469500000009],[-97.00195300000001,73.6202550000001],[-97.18499800000001,73.56219499999997],[-97.20249899999993,73.55720500000012],[-97.43611099999993,73.52554299999997],[-97.62388599999986,73.53887900000012],[-97.63806199999993,73.53858900000012],[-97.64111299999996,73.53359999999992],[-97.66833500000001,73.48332199999999],[-97.66749600000003,73.47943100000009],[-97.66305499999993,73.4727630000001],[-97.65472399999993,73.4669340000001],[-97.63833599999998,73.4602660000001],[-97.62332199999997,73.45637500000004],[-97.60722399999997,73.45471199999997],[-97.579453,73.45498700000013],[-97.56277499999999,73.45915200000013],[-97.53416399999998,73.47387700000007],[-97.52223200000003,73.4785920000001],[-97.50389100000001,73.48304699999994],[-97.43721,73.49192800000009],[-97.41722099999998,73.49331700000005],[-97.401947,73.49304200000006],[-97.23222399999992,73.47442600000005],[-97.19721999999996,73.46971100000002],[-97.18305999999995,73.46499599999999],[-97.17222599999997,73.4602660000001],[-97.16610699999995,73.454163],[-97.15722699999992,73.39553800000004],[-97.150284,73.38998400000003],[-97.16944899999999,73.35664399999996],[-97.17193599999996,73.35276800000008],[-97.18388399999992,73.35054000000014],[-97.20750399999997,73.3483280000001],[-97.2369379999999,73.34860200000003],[-97.24305700000002,73.35470600000002],[-97.37554899999992,73.34721400000012],[-97.64500399999986,73.31805400000002],[-97.660278,73.3160860000001],[-97.70861799999994,73.30470300000007],[-97.84138499999989,73.27331500000008],[-97.84445199999999,73.26832600000012],[-97.84805299999994,73.2544400000001],[-97.847778,73.24942000000004],[-97.84861799999999,73.24498000000006],[-97.86250299999989,73.23387100000014],[-97.983612,73.1810910000001],[-98.02917500000001,73.16526800000008],[-98.07667499999997,73.15138200000013],[-98.112503,73.14248700000007],[-98.15167200000002,73.13108799999998],[-98.202789,73.11053500000008],[-98.22277799999995,73.09999100000005],[-98.22999600000003,73.09082000000012],[-98.23138399999988,73.08554100000015],[-98.23500100000001,73.07971199999992],[-98.24082900000002,73.0752720000001],[-98.319458,73.05053700000008],[-98.36582900000002,73.03776600000015],[-98.450287,73.02026400000011],[-98.45916699999992,72.99331699999999],[-98.45361300000002,72.89860500000009],[-98.45056199999999,72.8749850000001],[-98.445831,72.86581400000011],[-98.43859899999995,72.86053500000014],[-98.42805499999992,72.85609400000004],[-98.41999800000002,72.85859700000003],[-98.41332999999997,72.86415100000005],[-98.40333599999997,72.88136300000002],[-98.40333599999997,72.88720700000005],[-98.40583800000002,72.891663],[-98.402222,72.89749100000006],[-98.39778099999995,72.90277100000014],[-98.38806199999999,72.90803499999993],[-98.26640299999985,72.97276300000004],[-98.25500499999993,72.97747800000008],[-98.22721899999988,72.98748799999998],[-98.176941,72.99859600000013],[-97.99499499999996,73.0374910000001],[-97.98055999999997,73.03970299999997],[-97.86416600000001,73.04748500000011],[-97.84695399999998,73.04859899999991],[-97.68443300000001,73.03305100000011],[-97.66833500000001,73.03137200000009],[-97.52749599999999,73.01138300000014],[-97.44248999999996,72.999146],[-97.29972800000002,72.96971100000013],[-97.28332499999999,72.96388200000007],[-97.22972099999998,72.943039],[-97.22500600000001,72.93997200000013],[-97.25805699999995,72.88360599999999],[-97.26640299999997,72.87858599999998],[-97.265289,72.84887700000013],[-97.20361300000002,72.82582100000008],[-97.08167999999995,72.77998400000007],[-97.03028899999998,72.74136400000009],[-97.023056,72.73220800000013],[-97.023056,72.72720300000009],[-97.02972399999999,72.71665999999993],[-97.079453,72.70193499999999],[-97.10583499999996,72.69636500000013],[-97.13444499999991,72.68830900000006],[-97.16111799999999,72.67804000000001],[-97.17054699999989,72.67359900000008],[-97.17944299999999,72.66748000000007],[-97.18305999999995,72.66192600000005],[-97.19027699999998,72.64054900000002],[-97.19833399999993,72.609985],[-97.19665500000002,72.60443099999998],[-97.185272,72.6019290000001],[-97.16555799999992,72.60165400000011],[-97.09056099999998,72.60525499999994],[-97.08100899999994,72.60592700000012],[-97.07028200000002,72.60859700000009],[-97.04277000000002,72.62330600000013],[-97.03582799999998,72.62886000000015],[-97.00556899999987,72.64471400000002],[-96.98222399999997,72.65525800000012],[-96.96888699999994,72.66026299999999],[-96.91555800000003,72.67858899999999],[-96.61193800000001,72.74693300000007],[-96.51750199999992,72.71470600000009],[-96.52194199999991,72.67442300000005],[-96.45973199999992,72.6077580000001],[-96.40527299999997,72.55941800000011],[-96.37471,72.53442400000012],[-96.33694500000001,72.50082400000002],[-96.32556199999999,72.48831200000006],[-96.30221599999993,72.43386800000002],[-96.29750100000001,72.42164600000001],[-96.29833999999994,72.415817],[-96.53860500000002,72.34332300000005],[-96.66833500000001,72.309708],[-96.69694500000003,72.31053199999997],[-96.73889200000002,72.32110599999999],[-96.77639799999997,72.32331800000003],[-96.83139,72.32360800000004],[-96.86833200000001,72.32193000000012],[-96.87193299999996,72.32110599999999],[-96.86444099999994,72.31776400000007],[-96.771118,72.29887400000007],[-96.66888399999988,72.27915999999999],[-96.57833900000003,72.278595],[-96.56111099999998,72.27554300000003],[-96.554169,72.26388500000002],[-96.48721299999988,72.13610800000004],[-96.48500100000001,72.129974],[-96.48306299999996,72.11303700000002],[-96.487503,72.101654],[-96.49833699999994,72.09027099999997],[-96.50834699999996,72.08499100000012],[-96.52111799999994,72.07998700000013],[-96.537216,72.07499700000011],[-96.55722000000003,72.07193000000001],[-96.72166399999992,72.05276500000002],[-96.77305599999994,72.05304000000007],[-96.789444,72.05220000000003],[-96.86694299999999,72.04109199999999],[-96.853882,72.03637699999996],[-96.828888,72.030823],[-96.67250100000001,72.01277199999998],[-96.63500999999997,72.01388500000007],[-96.61805700000002,72.018326],[-96.60916099999992,72.02415500000001],[-96.60055499999999,72.02777100000003],[-96.56777999999997,72.03360000000009],[-96.52111799999994,72.03887900000007],[-96.50195300000001,72.03858900000006],[-96.48860199999996,72.034988],[-96.48999000000003,72.018326],[-96.49082900000002,72.01220699999999],[-96.49305699999996,72.00109899999995],[-96.502228,71.97554000000014],[-96.50584399999997,71.96971100000013],[-96.51278699999989,71.96443199999999],[-96.52250699999996,71.95915200000007],[-96.55444299999994,71.949142],[-96.56555200000003,71.94693000000012],[-96.57389799999999,71.94831800000003],[-96.589447,71.95443700000004],[-96.60278299999999,71.9580380000001],[-96.61749299999991,71.95999100000006],[-96.63833599999998,71.95748899999995],[-96.73332199999993,71.92886399999998],[-96.74916099999996,71.92387400000007],[-96.76194799999996,71.91859400000004],[-96.76445000000001,71.91499299999998],[-96.76139799999993,71.90971400000001],[-96.74972500000001,71.90304600000002],[-96.73638900000003,71.89942900000005],[-96.72416699999997,71.89860500000009],[-96.70083599999992,71.8999940000001],[-96.64527899999996,71.91748000000001],[-96.60722399999997,71.92692599999998],[-96.56555200000003,71.93220500000001],[-96.52278100000001,71.93441800000011],[-96.50917099999992,71.93304400000011],[-96.50389099999995,71.93165600000003],[-96.49166899999989,71.92608599999994],[-96.49110399999995,71.91943400000008],[-96.49305699999996,71.914154],[-96.52583299999998,71.86886600000008],[-96.55776999999995,71.82943699999998],[-96.5708469999999,71.81944299999998],[-96.57972699999993,71.81498700000003],[-96.591949,71.81080599999996],[-96.61332700000003,71.80720500000012],[-96.72666899999996,71.79359399999993],[-96.74472000000003,71.79220600000002],[-96.73805199999998,71.824997],[-96.79138199999994,71.82777400000003],[-96.983612,71.77581799999996],[-97.01306199999999,71.74914600000005],[-97.08416699999992,71.7002720000001],[-97.16500899999994,71.67553700000008],[-97.21000699999996,71.66360500000008],[-97.43443300000001,71.617752],[-97.47055099999994,71.61248799999998],[-97.50500499999998,71.611649],[-97.65638699999994,71.61470000000003],[-97.69665500000002,71.61970500000007],[-97.71333299999998,71.62387100000001],[-97.72639500000002,71.628311],[-97.78721599999994,71.64414999999997],[-97.97471599999994,71.66081200000013],[-97.98805199999998,71.66192600000011],[-98.03527799999995,71.65332000000001],[-98.05332900000002,71.64833100000004],[-98.07278400000001,71.64166300000005],[-98.11277799999993,71.63693200000012],[-98.13110399999994,71.63804600000009],[-98.17887899999994,71.64166300000005],[-98.19665499999991,71.6436000000001],[-98.20750399999997,71.64610300000004],[-98.21806300000003,71.64971900000012],[-98.24082900000002,71.65971400000001],[-98.25279199999989,71.66609199999999],[-98.33111600000001,71.708328],[-98.34916699999991,71.71859700000005],[-98.3558349999999,71.7227630000001],[-98.35972599999997,71.72804300000001],[-98.35943600000002,71.73387100000008],[-98.333328,71.78749099999999],[-98.32556199999993,71.79832500000009],[-98.32139599999994,71.80331400000006],[-98.31527699999992,71.80914300000006],[-98.27917499999995,71.83471700000007],[-98.25917099999992,71.84471100000007],[-98.228882,71.86219800000009],[-98.21194499999996,71.87858599999998],[-98.20861799999994,71.88443000000001],[-98.20916699999998,71.88916],[-98.22193899999996,71.89498900000001],[-98.25527999999997,71.90248099999997],[-98.26722699999999,71.90415999999999],[-98.28277600000001,71.89915500000012],[-98.291382,71.89471400000002],[-98.45056199999999,71.79414399999996],[-98.46250899999995,71.78387499999997],[-98.47778299999993,71.76721200000009],[-98.48889200000002,71.74941999999999],[-98.49749799999995,71.73332199999999],[-98.49749799999995,71.72164900000013],[-98.49388099999999,71.71388200000001],[-98.38137799999998,71.653595],[-98.36749299999991,71.647491],[-98.17999299999991,71.57193000000012],[-98.04138199999989,71.53082300000005],[-98.03750600000001,71.526657],[-98.120544,71.46054099999998],[-98.18083199999995,71.42359899999997],[-98.19804399999998,71.41470300000003],[-98.46611000000001,71.31330900000006],[-98.50556899999992,71.29914900000011],[-98.54138199999994,71.28942900000004],[-98.55471799999998,71.2872010000001],[-98.70167500000002,71.271927],[-98.72084000000001,71.26998900000007],[-98.72972099999993,71.27053800000004],[-98.75111400000003,71.27415499999995],[-98.81639099999995,71.28915400000005],[-98.829453,71.29386900000009],[-98.84472699999998,71.30554200000012],[-98.88221699999997,71.33387800000003],[-98.93832399999985,71.36914100000001],[-98.96028100000001,71.379974],[-98.978882,71.382477],[-98.995544,71.3827510000001],[-99.01472499999994,71.38165300000003],[-99.03443899999996,71.37886000000003],[-99.04277000000002,71.37441999999999],[-99.04554699999994,71.36859099999998],[-99.05139200000002,71.36303699999996],[-99.05972300000002,71.35859700000015],[-99.07749899999999,71.3535920000001],[-99.11582900000002,71.35054000000002],[-99.2208399999999,71.34220900000008],[-99.23805199999998,71.344986],[-99.28805499999987,71.40277100000009],[-99.31332399999997,71.43942300000009],[-99.46278399999994,71.59304800000001],[-99.52972399999999,71.605255],[-99.55860899999988,71.61303700000013],[-99.57417299999997,71.61970500000007],[-99.578888,71.62275700000004],[-99.59167500000001,71.635269],[-99.67639200000002,71.72526600000009],[-99.67777999999993,71.72915600000005],[-99.67721599999999,71.73692300000005],[-99.6744379999999,71.74275200000005],[-99.67304999999999,71.74914600000005],[-99.67388900000003,71.7538760000001],[-99.67639200000002,71.75860599999999],[-99.67832899999996,71.7605440000001],[-99.84222399999999,71.834991],[-99.95916699999998,71.85415599999993],[-99.97721899999999,71.85581999999994],[-100.05110200000001,71.865814],[-100.067497,71.87052900000003],[-100.10193599999997,71.88472000000002],[-100.31471299999993,71.97997999999995],[-100.3219529999999,71.98498500000005],[-100.33222999999998,71.99720800000006],[-100.33583099999993,72.00665300000014],[-100.579453,72.15443400000004],[-100.63445299999995,72.18553200000008],[-100.64417300000002,72.18830899999995],[-100.72000099999997,72.20166000000012],[-100.88527699999997,72.20776400000011],[-100.88999899999988,72.20748900000012],[-100.92388900000003,72.19941699999998],[-100.95140099999992,72.17109700000015],[-100.96777299999997,72.17414900000006],[-101.01334399999996,72.19108600000004],[-101.02084400000001,72.19636500000001],[-101.054169,72.23165899999992],[-101.05555700000002,72.236649],[-101.11776700000001,72.284424],[-101.19444299999998,72.324432],[-101.20861799999994,72.32971200000009],[-101.220551,72.33221400000014],[-101.23889200000002,72.33387799999997],[-101.27667200000002,72.32832300000007],[-101.32528699999995,72.31498699999997],[-101.395554,72.28692600000005],[-101.40416699999997,72.28137200000003],[-101.40972899999986,72.27554300000003],[-101.46945199999999,72.26554900000002],[-101.50917099999998,72.28305100000006],[-101.58556399999998,72.301376],[-101.63474299999996,72.30693100000008],[-101.65638699999994,72.30525200000005],[-101.66416900000002,72.30165099999999],[-101.672234,72.29275500000006],[-101.6849979999999,72.28776600000009],[-101.69444299999986,72.28804000000002],[-101.776947,72.29971300000005],[-101.83056599999992,72.31915300000003],[-101.84472699999992,72.324432],[-101.88834399999996,72.35859700000015],[-101.94167299999987,72.45193500000005],[-101.98131599999999,72.47811100000013],[-102.08033799999993,72.51600600000012],[-102.22222899999991,72.54220600000008],[-102.258621,72.54914900000006],[-102.37721299999998,72.57748400000008],[-102.46584299999995,72.60470600000002],[-102.6219329999999,72.66470300000015],[-102.73638899999992,72.719986],[-102.74166899999989,72.72415200000006],[-102.75583599999993,72.76138300000002],[-102.76471699999996,72.784988],[-102.76306199999999,72.790817],[-102.75306699999999,72.81109600000013],[-102.74944299999999,72.81721499999998],[-102.74305699999996,72.82249500000006],[-102.73500100000001,72.82609600000012],[-102.69860799999992,72.83665499999995],[-102.66361999999992,72.85331699999995],[-102.64666699999992,72.86442600000004],[-102.61277799999993,72.89665200000013],[-102.59722899999991,72.91360500000002],[-102.59361299999995,72.919983],[-102.59166699999997,72.92553699999996],[-102.59306300000003,72.93165600000003],[-102.59416199999998,72.94274899999999],[-102.593887,72.949142],[-102.59166699999997,72.95498700000007],[-102.576683,72.97970600000002],[-102.56304899999998,72.99108900000004],[-102.51306199999993,73.02609300000012],[-102.50110599999994,73.03054800000012],[-102.38806199999999,73.06275900000003],[-102.36805699999996,73.06749000000013],[-102.27610800000002,73.08248900000001],[-102.24694799999997,73.08387800000003],[-102.1372219999999,73.08692900000005],[-102.08444199999985,73.08415200000013],[-102.014183,73.07971199999992],[-101.97083999999995,73.07054099999999],[-101.88417099999992,73.0247040000001],[-101.81777999999991,72.9666600000001],[-101.810272,72.96054100000003],[-101.75527999999997,72.93054200000006],[-101.74109599999991,72.92414900000006],[-101.67527799999999,72.90971400000012],[-101.59528399999994,72.90220599999992],[-101.52166699999998,72.87831100000011],[-101.50974299999996,72.87164299999995],[-101.40444899999989,72.78248600000012],[-101.41332999999997,72.74832200000009],[-101.37249800000001,72.72720300000009],[-101.36665299999999,72.72526600000003],[-101.29750099999995,72.70999100000006],[-101.03333299999997,72.68969700000014],[-100.91583299999996,72.68803400000002],[-100.88221699999991,72.68969700000014],[-100.82778899999994,72.70582600000006],[-100.81945799999994,72.7102660000001],[-100.81220999999994,72.71554599999996],[-100.81194299999999,72.71971099999996],[-100.79833999999994,72.74359099999998],[-100.70722999999998,72.755829],[-100.53307299999994,72.75138900000002],[-100.50917099999992,72.74914600000005],[-100.49833699999994,72.74803200000008],[-100.47582999999997,72.742752],[-100.44803599999995,72.73553500000008],[-100.43443300000001,72.73692299999999],[-100.41221599999994,72.74192800000003],[-100.34973100000002,72.7705380000001],[-100.340843,72.77499399999999],[-100.33168,72.78054800000001],[-100.314438,72.79637100000002],[-100.31555199999997,72.80137600000006],[-100.35077699999994,72.85132600000009],[-100.35160799999994,72.85366099999999],[-100.35711699999996,72.8591540000001],[-100.46916199999998,72.95027200000004],[-100.48638899999992,72.949142],[-100.49889399999995,72.95054600000014],[-100.49973299999999,72.95637499999998],[-100.46305799999993,73.01470900000004],[-100.45194999999995,73.02053800000004],[-100.421944,73.03498799999994],[-100.36776700000001,73.04693600000002],[-100.35637700000001,73.04942300000005],[-100.34221600000001,73.04414400000007],[-100.31667299999992,73.03414900000001],[-100.30943299999996,73.02804600000007],[-100.31555199999997,73.02249099999995],[-100.34306300000003,73.01388500000007],[-100.3577729999999,73.01054400000004],[-100.38137799999998,72.949142],[-100.3289949999999,72.89137299999999],[-100.31732899999992,72.88887],[-100.285278,72.87359600000008],[-100.21721599999995,72.87664799999999],[-100.196663,72.87776200000002],[-100.09638999999993,72.88638300000008],[-100.06722999999994,72.90220599999992],[-100.031387,72.93498200000005],[-100.04750099999995,72.95721400000014],[-100.11277799999999,73.02581800000007],[-100.16972399999992,73.07859800000011],[-100.23222399999997,73.13443000000012],[-100.24445299999996,73.136932],[-100.25446299999999,73.13720699999999],[-100.28888699999993,73.13581800000003],[-100.32362399999994,73.13333100000011],[-100.345551,73.13026400000001],[-100.38249200000001,73.12275700000009],[-100.39138799999995,73.11831700000005],[-100.41443600000002,73.10470600000008],[-100.44275699999997,73.08720400000004],[-100.51862299999993,73.0977630000001],[-100.58667000000003,73.1327510000001],[-100.60193599999997,73.14082300000007],[-100.60777300000001,73.14637800000014],[-100.58612099999999,73.16748000000013],[-100.58000199999987,73.17303500000003],[-100.49082900000002,73.23081999999994],[-100.40666199999987,73.28027300000008],[-100.39778100000001,73.28471399999995],[-100.37832600000002,73.28997800000013],[-100.36110699999995,73.29026799999997],[-100.28138699999994,73.27915999999999],[-100.1347429999999,73.22110000000004],[-100.05332899999996,73.18637100000001],[-100.03751399999999,73.18386800000002],[-100.021118,73.18304400000005],[-100.00418099999996,73.1833190000001],[-99.84111000000001,73.19136000000015],[-99.80166600000001,73.19552600000003],[-99.77166699999998,73.20109600000012],[-99.77027899999996,73.20387300000004],[-99.77166699999998,73.20803800000004],[-99.78639199999992,73.21249399999994],[-99.81193499999995,73.21554600000007],[-99.84944200000001,73.21527100000003],[-99.886124,73.21331800000007],[-99.92582700000003,73.21499600000004],[-99.945267,73.21666000000005],[-99.96444699999995,73.21943699999997],[-100.07749899999999,73.25138900000007],[-100.09500100000002,73.25721700000003],[-100.15915699999994,73.28942899999998],[-100.19943199999994,73.31860400000005],[-100.27223199999992,73.35859700000009],[-100.32362399999994,73.3836060000001],[-100.33332799999994,73.38832100000013],[-100.358047,73.393326],[-100.37389399999995,73.39582800000005],[-100.38417099999987,73.39637800000008],[-100.38806199999993,73.39553800000004],[-100.4058379999999,73.36137400000001],[-100.387787,73.338593],[-100.56166099999996,73.28665200000012],[-100.583618,73.28359999999998],[-100.823059,73.26081800000009],[-100.84056099999992,73.25972000000002],[-100.88945000000001,73.26443500000005],[-100.97749299999998,73.28027300000008],[-101.30499299999991,73.36164900000006],[-101.31276700000001,73.37109400000008],[-101.311394,73.38275100000004],[-101.31054699999999,73.39248700000002],[-101.311394,73.39833100000004],[-101.31723,73.40165700000006],[-101.47055099999994,73.43609600000013],[-101.55832700000002,73.44664],[-101.58084099999996,73.4502720000001],[-101.61665299999993,73.4852600000001],[-101.62138400000003,73.49026500000014],[-101.44055200000003,73.54914900000006],[-101.42748999999992,73.55220000000008],[-101.40083299999992,73.55358900000004],[-101.31582599999996,73.55081199999995],[-101.2808379999999,73.55247500000007],[-101.26888999999994,73.55609099999992],[-101.25974300000001,73.56164600000005],[-101.25527999999997,73.56776399999995],[-101.25222799999995,73.57887300000004],[-101.25306699999993,73.584991],[-101.25110599999994,73.58970600000004],[-101.24194299999994,73.59526100000011],[-101.23082699999998,73.60026600000015],[-101.21721600000001,73.60415599999993],[-101.199432,73.60554500000012],[-100.92639200000002,73.60026600000015],[-100.90943900000002,73.59971600000011],[-100.890289,73.59610000000009],[-100.87748699999997,73.59027100000003],[-100.77084400000001,73.53997800000008],[-100.71749899999992,73.50915500000008],[-100.70667299999997,73.49942000000004],[-100.70221699999996,73.49443100000008],[-100.70140100000003,73.48858599999994],[-100.69721999999996,73.482483],[-100.69110099999995,73.47692900000004],[-100.67278299999998,73.46443200000004],[-100.51834099999996,73.41693099999998],[-100.49973299999999,73.41249099999993],[-100.46472199999988,73.40721100000007],[-100.44444299999992,73.40637200000009],[-100.43055700000002,73.40693699999997],[-100.41722099999998,73.41331500000007],[-100.41500899999994,73.41804500000012],[-100.42971799999998,73.43026700000007],[-100.45500199999998,73.44192499999997],[-100.484734,73.45193500000005],[-100.50279199999989,73.45748900000001],[-100.531387,73.46609499999994],[-100.58389299999993,73.48220800000001],[-100.59221599999995,73.48637400000007],[-100.59861799999999,73.4910890000001],[-100.60611,73.49720799999994],[-100.61000099999995,73.50305200000014],[-100.610817,73.50915500000008],[-100.60804699999994,73.5149990000001],[-100.60388199999994,73.52110299999998],[-100.55915799999997,73.54609700000009],[-100.54387700000001,73.55636600000014],[-100.541382,73.56219499999997],[-100.54277000000002,73.57388300000002],[-100.54998799999993,73.59471100000007],[-100.55166600000001,73.59887699999996],[-100.573624,73.59664900000001],[-100.628601,73.593323],[-100.76750199999998,73.60386700000004],[-100.89167799999996,73.61998000000006],[-100.91139199999998,73.62275699999998],[-100.91194200000001,73.62525900000003],[-100.91139199999998,73.63053900000011],[-100.87943999999999,73.63581800000009],[-100.86472300000003,73.641663],[-100.86110699999995,73.645828],[-100.85360699999995,73.66220100000004],[-100.858047,73.66720599999991],[-100.97444199999995,73.67915300000004],[-100.99194299999999,73.67886399999998],[-101.03333299999997,73.67137100000014],[-101.04695099999998,73.67303500000014],[-101.057503,73.67665099999999],[-101.11833199999995,73.72331200000002],[-101.120003,73.72720300000009],[-101.01390100000003,73.79721100000006],[-100.9974979999999,73.80247500000002],[-100.98222399999997,73.80581699999999],[-100.95973199999997,73.809143],[-100.93804899999998,73.81025699999998],[-100.82861300000002,73.81553600000012],[-100.79527300000001,73.81248499999992],[-100.77583300000003,73.81219500000009],[-100.754997,73.81248499999992],[-100.73416099999997,73.81526200000002],[-100.714447,73.82026700000006],[-100.69915800000001,73.82609600000006],[-100.66416900000002,73.84498600000006],[-100.64835399999993,73.84832799999998],[-100.554169,73.85470599999996],[-100.52999899999998,73.85359199999994],[-100.41777000000002,73.84553499999998],[-100.39555399999995,73.84082000000012],[-100.38945000000001,73.83859300000006],[-100.370003,73.82804900000002],[-100.34999099999993,73.818604],[-100.33612099999993,73.81469700000002],[-100.06304899999998,73.76499900000005],[-99.86582899999996,73.8377690000001],[-99.85777300000001,73.84275800000006],[-99.87010999999995,73.86154199999999],[-99.86910999999992,73.86737099999999],[-99.86978099999993,73.87020100000001],[-99.87710599999991,73.87654100000003],[-99.88677199999995,73.8822100000001],[-99.89244099999996,73.88353699999993],[-99.96194499999996,73.87330600000007],[-99.97166399999998,73.86804200000006],[-99.98805199999993,73.85693400000008],[-99.99082900000002,73.851089],[-99.99749800000001,73.84553499999998],[-100.00834699999996,73.84136999999998],[-100.02639799999997,73.83692900000005],[-100.04943800000001,73.83276400000005],[-100.13667299999997,73.82748400000003],[-100.175003,73.82804900000002],[-100.24944299999993,73.83387800000003],[-100.26139799999993,73.83831800000007],[-100.29972799999996,73.8602600000001],[-100.29695100000004,73.86581400000011],[-100.29222099999993,73.872208],[-100.27860999999996,73.888596],[-100.26583900000003,73.89999400000005],[-100.252792,73.905258],[-100.24305700000002,73.907486],[-100.14306599999992,73.92997700000001],[-100.12721299999993,73.9333190000001],[-100.104446,73.93637100000001],[-100.03751399999999,73.94247399999995],[-99.98110999999994,73.9458160000001],[-99.93859900000001,73.94609100000008],[-99.89695699999999,73.94413800000001],[-99.85610999999989,73.94081100000005],[-99.81610099999995,73.93609600000002],[-99.80082700000003,73.93165599999998],[-99.80055199999993,73.92581200000001],[-99.81332399999997,73.92137100000008],[-99.80622099999994,73.90210000000002],[-99.81005899999997,73.89876600000002],[-99.81088999999997,73.8949280000001],[-99.80822799999999,73.89193700000004],[-99.80455799999993,73.8890990000001]],[[-89.98889200000002,73.98831200000012],[-90.00778199999996,73.984985],[-90.05804399999994,73.99247700000012],[-90.158615,74.00138900000013],[-90.21777299999997,74.00443999999999],[-90.25029,74.00999500000006],[-90.265015,74.01470899999998],[-90.28111299999989,74.02165199999996],[-90.28472899999991,74.0249940000001],[-90.28500399999996,74.02970900000014],[-90.27639799999986,74.038589],[-90.27111799999994,74.04332000000011],[-90.24055499999997,74.05386399999998],[-90.20611599999995,74.05775500000004],[-89.99194299999994,74.066666],[-89.97193900000002,74.06469700000014],[-89.94137599999999,74.05748],[-89.91444399999995,74.04748500000011],[-89.90194699999995,74.03776600000009],[-89.903885,74.03137200000009],[-89.91860999999994,74.01054399999998],[-89.92832900000002,74.00555400000013],[-89.98889200000002,73.98831200000012]],[[-98.91861,73.8060910000001],[-98.96166999999997,73.80525200000011],[-99.104172,73.81442300000009],[-99.14083899999991,73.81805400000013],[-99.36361699999992,73.86442600000004],[-99.38194299999992,73.86914100000007],[-99.42971799999992,73.89166299999994],[-99.43749999999994,73.89694199999991],[-99.43638599999997,73.90220600000009],[-99.42971799999992,73.9080350000001],[-99.42250100000001,73.91110200000003],[-99.406113,73.91526799999991],[-99.28250099999997,73.93691999999999],[-99.22389199999998,73.94026200000008],[-99.09277299999991,73.95220900000004],[-99.02027900000002,73.97970600000002],[-98.93804899999992,73.99859600000013],[-98.80166600000001,74.01805100000013],[-98.66194200000001,74.03137200000009],[-98.57583599999998,74.03137200000009],[-98.53250100000002,74.03221100000002],[-98.49194299999994,74.03414899999996],[-98.42527799999999,74.04386900000003],[-98.3558349999999,74.05748],[-98.27583299999992,74.07388300000008],[-98.25500499999993,74.07859800000011],[-98.23028599999998,74.08332799999994],[-98.17083699999995,74.09248400000007],[-98.03999299999998,74.10582000000005],[-97.99444599999993,74.10942100000011],[-97.80610699999988,74.11943100000002],[-97.75834699999996,74.11859099999998],[-97.737213,74.11747700000001],[-97.70361300000002,74.11387600000012],[-97.69082600000002,74.11137400000007],[-97.65360999999996,74.09999100000005],[-97.64805599999994,74.0977630000001],[-97.64222699999993,74.08720400000004],[-97.637787,74.07554600000003],[-97.63833599999998,74.063873],[-97.64944499999996,74.05247499999996],[-97.65666199999998,74.04693599999996],[-97.67332499999986,74.03553799999997],[-97.71722399999999,74.00972000000002],[-97.72805800000003,74.00416600000005],[-97.76362599999993,73.98831200000012],[-97.82305899999989,73.9685970000001],[-98.12416100000002,73.8785860000001],[-98.14500399999991,73.87359600000008],[-98.16833499999996,73.87081899999998],[-98.39277600000003,73.84526100000005],[-98.478882,73.8374940000001],[-98.777222,73.81359900000012],[-98.91861,73.8060910000001]],[[-92.63806199999988,74.10304300000013],[-92.36860699999994,74.04109199999999],[-92.35694899999999,74.03804000000002],[-92.33444199999991,74.03137200000009],[-92.31138599999997,74.02165199999996],[-92.29695100000004,74.01443500000005],[-92.289444,74.00915500000002],[-92.28277599999996,74.00332599999996],[-92.27362099999999,73.99054000000007],[-92.27278100000001,73.98442100000005],[-92.28195199999999,73.97499099999999],[-92.29110700000001,73.96971100000007],[-92.31054699999993,73.96110499999998],[-92.32778899999994,73.95138500000007],[-92.33000199999998,73.94552600000009],[-92.32972699999999,73.94247399999995],[-92.30943300000001,73.94081100000005],[-92.1324919999999,73.94636500000001],[-92.118607,73.94914200000011],[-92.11665299999999,73.95109599999995],[-92.11332700000003,73.95637499999998],[-92.1100009999999,73.96470600000004],[-92.11305199999998,73.97442600000011],[-92.114441,73.97665400000005],[-92.11305199999998,73.98136899999992],[-92.10777300000001,73.98471100000006],[-92.09416199999998,73.98915100000005],[-91.92555199999998,74.01277199999993],[-91.87721299999998,74.01693699999993],[-91.83833299999998,74.0188750000001],[-91.57084700000001,74.02581800000007],[-91.52833599999991,74.02442900000005],[-91.13999899999993,74.00999500000006],[-91.09750400000001,74.00833100000006],[-91.06500199999999,74.006104],[-91.04695100000004,74.00416600000005],[-90.73554999999993,73.968323],[-90.66000399999996,73.95387300000004],[-90.63305699999995,73.94831799999997],[-90.44137599999993,73.91970800000013],[-90.40666199999998,73.91470300000009],[-90.364441,73.91165200000006],[-90.35472099999998,73.91220100000004],[-90.34495500000003,73.91436800000008],[-90.34167499999995,73.91720600000008],[-90.33972199999994,73.9205320000001],[-90.34111000000001,73.92414900000006],[-90.33555599999994,73.92581200000001],[-90.31777999999997,73.92526199999998],[-90.22500600000001,73.90859999999998],[-90.195831,73.90193199999999],[-90.19444299999992,73.899719],[-90.20417800000001,73.88832100000002],[-90.23028599999998,73.86219800000003],[-90.24194299999999,73.85192900000004],[-90.25140399999998,73.84664900000013],[-90.26445000000001,73.84165999999999],[-90.27528399999994,73.83859300000006],[-90.28306600000002,73.83831800000007],[-90.36000099999995,73.80081200000012],[-90.474716,73.72164900000007],[-90.58139,73.65776100000005],[-90.72471599999994,73.58305400000012],[-90.84973100000002,73.54026800000008],[-90.92138699999992,73.49525500000004],[-90.93028300000003,73.48387100000008],[-90.93221999999997,73.48193400000008],[-91.08917200000002,73.38415500000002],[-91.152222,73.36109900000002],[-91.17138699999998,73.35108900000006],[-91.18055700000002,73.3458250000001],[-91.18638599999991,73.34027100000009],[-91.23860200000001,73.27998400000013],[-91.25306699999987,73.26915000000008],[-91.26222200000001,73.26388500000002],[-91.36776700000001,73.20082100000013],[-91.569458,73.06330900000006],[-91.64277600000003,73.02110300000004],[-91.64750699999996,73.01666300000005],[-91.64500399999997,72.99803200000002],[-91.77084400000001,72.91304000000002],[-91.79972799999996,72.89721699999996],[-91.80833399999989,72.8919370000001],[-91.81277499999999,72.88581800000009],[-91.81304899999992,72.88026400000007],[-91.81138599999997,72.86804200000012],[-91.818893,72.86219800000009],[-91.84973100000002,72.84610000000004],[-92.06610099999989,72.75248700000009],[-92.0958399999999,72.743042],[-92.12748699999992,72.73442100000011],[-92.16639699999996,72.72553999999997],[-92.23222399999997,72.71304300000003],[-92.27471899999989,72.70748900000001],[-92.314438,72.70498700000013],[-92.33528099999995,72.7044370000001],[-92.39334099999991,72.70721399999996],[-92.431107,72.71054100000009],[-92.524719,72.72053499999993],[-92.74526999999989,72.73997500000013],[-92.898346,72.75027500000004],[-93.07749899999988,72.76943999999997],[-93.24888599999991,72.78970300000003],[-93.337784,72.8077550000001],[-93.34916699999985,72.80247500000007],[-93.36665299999999,72.79776000000004],[-93.39195299999994,72.79414400000013],[-93.412216,72.79220600000002],[-93.58000199999992,72.77804600000007],[-93.67999299999991,72.77970900000003],[-93.7261049999999,72.7810970000001],[-93.76445000000001,72.78137200000015],[-93.93276999999995,72.77415500000001],[-94.03860499999996,72.76638800000006],[-94.09916699999997,72.76416000000012],[-94.13249200000001,72.76470900000004],[-94.17054699999994,72.76748700000007],[-94.18249499999996,72.76943999999997],[-94.24610899999999,72.77388000000002],[-94.26278699999989,72.77415500000001],[-94.29804999999999,72.77026399999994],[-94.31555200000003,72.76304600000014],[-94.32194499999997,72.75943000000007],[-94.32749899999999,72.75444000000005],[-94.33444199999997,72.73803699999996],[-94.33277900000002,72.73193400000002],[-94.32749899999999,72.72164900000013],[-94.319458,72.71748400000013],[-94.3125,72.71554599999996],[-94.29750100000001,72.71331800000002],[-94.26916499999993,72.71914700000002],[-94.26528899999994,72.72387700000007],[-94.26390100000003,72.72998000000001],[-94.25834699999996,72.732483],[-94.23638899999992,72.73498500000005],[-94.160278,72.72943100000003],[-94.1036069999999,72.71859699999999],[-94.09333799999996,72.71499599999993],[-94.00140399999992,72.704163],[-93.98500099999995,72.70387299999993],[-93.88667299999997,72.70471200000009],[-93.839447,72.71720900000008],[-93.79834,72.70220899999993],[-93.82305899999989,72.65304600000002],[-93.81722999999994,72.64221199999997],[-93.80166599999995,72.63443000000001],[-93.78611799999993,72.62914999999998],[-93.76945499999988,72.62498499999998],[-93.75778200000002,72.62303200000002],[-93.6866609999999,72.62220800000006],[-93.67443800000001,72.61886600000008],[-93.589722,72.58137499999998],[-93.56861900000001,72.57083100000011],[-93.49888599999997,72.52192700000012],[-93.46333300000003,72.4622040000001],[-93.46611000000001,72.45138500000002],[-93.46945199999999,72.43969700000002],[-93.62805200000003,72.34193400000004],[-93.64527899999996,72.33720400000004],[-93.66639700000002,72.33360299999998],[-93.68832399999991,72.33109999999999],[-93.74861099999998,72.32971200000009],[-93.76722699999999,72.3272090000001],[-93.787216,72.32276900000011],[-93.80139200000002,72.31776400000007],[-93.81973299999993,72.30720500000001],[-93.82749899999999,72.30192600000004],[-93.91332999999997,72.24165299999993],[-93.92527799999993,72.23304700000006],[-94.01417500000002,72.16387900000012],[-94.03666699999985,72.14221200000009],[-94.04028299999999,72.13749700000005],[-94.04361,72.13136300000002],[-94.04554699999989,72.12692299999998],[-94.04472399999997,72.11581400000011],[-94.04222099999993,72.10664400000007],[-94.04388399999993,72.09693900000013],[-94.04833999999994,72.09109499999994],[-94.05471799999992,72.08526599999993],[-94.06666599999994,72.07666],[-94.08084099999996,72.06693999999993],[-94.09167500000001,72.061646],[-94.12768599999993,72.05636600000008],[-94.14334100000002,72.05748000000006],[-94.17250099999995,72.0577550000001],[-94.18666099999996,72.05581699999993],[-94.19888300000002,72.05276500000002],[-94.18872099999999,72.0452580000001],[-94.19505300000003,72.04209100000008],[-94.19838700000003,72.03910100000013],[-94.199547,72.03643800000003],[-94.196053,72.03243299999997],[-94.18838499999998,72.03093000000013],[-94.17204299999992,72.02959400000009],[-94.14988699999992,72.02943399999998],[-94.13738299999989,72.03176900000011],[-94.13055400000002,72.03310400000004],[-94.12521400000003,72.03509500000013],[-94.091385,72.03776600000015],[-94.06082200000003,72.03526299999999],[-94.02972399999993,71.99941999999999],[-94.06304899999992,71.97831700000006],[-94.08222999999998,71.97608900000012],[-94.19171900000003,71.99431600000008],[-94.35388199999994,72.01805099999996],[-94.37193300000001,72.01944000000015],[-94.41805999999991,72.02276599999999],[-94.44972199999995,72.02331500000014],[-94.74388099999993,72.01138300000002],[-94.78028899999998,72.006104],[-94.82556199999999,71.99748199999999],[-94.90222199999988,71.9891510000001],[-95.12193299999996,71.96609500000005],[-95.16111799999993,71.96470600000009],[-95.17582699999997,71.96693400000004],[-95.20777899999996,71.98887600000012],[-95.21333300000003,71.99443100000002],[-95.20666499999999,72.09748800000011],[-95.204453,72.10276799999997],[-95.19665499999996,72.10664400000007],[-95.039444,72.13136300000002],[-94.981674,72.13943499999999],[-94.92971799999992,72.14359999999999],[-94.89999399999999,72.14444000000003],[-94.86805700000002,72.1455380000001],[-94.752228,72.15332000000006],[-94.76083399999993,72.15498400000007],[-94.80610699999994,72.15914900000007],[-94.8391719999999,72.15859999999998],[-94.96139499999998,72.155258],[-95.02749599999999,72.14498900000001],[-95.12110899999999,72.13665800000007],[-95.13999899999993,72.1355440000001],[-95.15888999999999,72.13581800000003],[-95.17111199999994,72.13915999999995],[-95.20666499999999,72.18081700000005],[-95.21167000000003,72.18719499999997],[-95.21362299999998,72.19331399999999],[-95.21472199999994,72.20027199999998],[-95.21472199999994,72.20526099999995],[-95.20388799999989,72.22192400000006],[-95.19137599999999,72.2452550000001],[-95.17111199999994,72.28332499999999],[-95.13333099999988,72.46026599999999],[-95.200287,72.524429],[-95.22639499999997,72.53166200000004],[-95.2830659999999,72.53553800000009],[-95.31610099999995,72.53970300000009],[-95.321396,72.54609700000015],[-95.34445199999993,72.58137499999998],[-95.34666400000003,72.58749399999999],[-95.345551,72.593323],[-95.33167999999995,72.59832800000004],[-95.31332399999997,72.60108900000006],[-95.31582600000002,72.60636899999992],[-95.35555999999997,72.63777199999998],[-95.36444099999989,72.64332600000012],[-95.45861799999994,72.68220500000001],[-95.47555499999999,72.68637100000012],[-95.4927669999999,72.68803400000002],[-95.50556899999998,72.68637100000012],[-95.52555799999999,72.68165600000009],[-95.53582799999992,72.68136600000003],[-95.54861499999993,72.68220500000001],[-95.57611099999997,72.68997199999995],[-95.59056099999992,72.69552599999997],[-95.60221899999993,72.70220899999993],[-95.6661069999999,72.80137600000006],[-95.67361499999998,72.81387300000006],[-95.67555199999998,72.82499700000011],[-95.67527799999993,72.841095],[-95.67193600000002,72.85247800000002],[-95.653885,72.87692300000003],[-95.64584400000001,72.91276600000009],[-95.65556300000003,73.01998900000007],[-95.68331899999998,73.07582100000002],[-95.58250399999997,73.12776200000013],[-95.57501200000002,73.1649930000001],[-95.60054000000002,73.283905],[-95.65083299999998,73.32527200000004],[-95.64666699999998,73.33082600000006],[-95.61361699999998,73.342758],[-95.62361099999998,73.36109900000002],[-95.65361000000001,73.41249099999993],[-95.681671,73.44413800000007],[-95.68388400000003,73.4502720000001],[-95.700287,73.55386400000009],[-95.66836499999994,73.58178700000008],[-95.61256399999996,73.61097699999999],[-95.65605900000003,73.63186600000012],[-95.676086,73.66506199999998],[-95.68194599999998,73.711929],[-95.67304999999999,73.72331200000002],[-95.65888999999999,73.73248299999995],[-95.64584400000001,73.73553500000008],[-95.45083599999998,73.7711030000001],[-95.42832900000002,73.77276599999999],[-95.29972799999996,73.7711030000001],[-95.28361499999994,73.76914999999997],[-95.26640299999991,73.76416000000012],[-95.23693800000001,73.75221299999998],[-95.160278,73.71304299999997],[-95.15472399999999,73.70694000000003],[-95.13833599999992,73.70082100000002],[-95.10694899999999,73.69192500000008],[-95.07640100000003,73.68331899999998],[-95.02417000000003,73.67164600000012],[-94.95666499999993,73.65914900000013],[-94.89056399999993,73.64915500000012],[-94.84555099999994,73.64415000000008],[-94.82861300000002,73.64305100000007],[-94.81221,73.64332600000012],[-94.652222,73.64860500000009],[-94.63417099999992,73.64942900000005],[-94.61805699999991,73.65138200000001],[-94.61915599999998,73.6544340000001],[-94.63806199999999,73.66581700000012],[-94.64944500000001,73.67082199999999],[-94.67639200000002,73.67665099999999],[-94.73277300000001,73.68136600000003],[-94.773056,73.67997700000001],[-94.81471299999987,73.6808170000001],[-94.866104,73.68719500000003],[-94.883331,73.69220000000007],[-95.07556199999988,73.77331500000014],[-95.08917200000002,73.78332500000005],[-95.11193799999995,73.80108600000005],[-95.11610399999995,73.80664100000013],[-95.108047,73.81219500000009],[-95.07084700000001,73.822769],[-95.03666699999991,73.82943699999993],[-95.00556899999998,73.83248900000007],[-94.97666899999996,73.83110000000005],[-94.958054,73.83194000000009],[-94.96333299999998,73.83831800000007],[-94.98249799999996,73.84553499999998],[-95.00500499999998,73.85276799999997],[-95.02444500000001,73.85525500000006],[-95.04554699999994,73.85554500000006],[-95.07667500000002,73.85247799999996],[-95.10916099999997,73.84359700000005],[-95.11639399999996,73.839157],[-95.12721299999993,73.82582100000008],[-95.13612399999994,73.82360800000009],[-95.15417499999995,73.82360800000009],[-95.26306199999999,73.86276200000003],[-95.304169,73.8808140000001],[-95.31138599999991,73.88526900000011],[-95.32333399999993,73.89694199999991],[-95.32778899999988,73.90914900000007],[-95.32972699999999,73.91998299999995],[-95.32611099999997,73.94413800000001],[-95.32472199999995,73.95248400000008],[-95.31916799999988,73.96415700000011],[-95.29834,73.98082],[-95.24527,74.010269],[-95.22778299999999,74.01416000000006],[-95.22000100000002,74.01470899999998],[-95.19248999999996,74.00888100000009],[-95.17443800000001,74.00888100000009],[-95.04083300000002,74.02638200000001],[-94.90695199999999,74.04748500000011],[-94.850281,74.05886800000013],[-94.80610699999994,74.06805400000007],[-94.78750600000001,74.07276900000011],[-94.75527999999991,74.08720400000004],[-94.74583399999995,74.09220900000008],[-94.73222399999997,74.095261],[-94.61833200000001,74.09027100000014],[-94.46028100000001,74.09443700000003],[-94.43693499999995,74.09582499999993],[-94.42721599999993,74.10081500000001],[-94.421112,74.10582000000005],[-94.412781,74.11526500000014],[-94.40611299999995,74.11886599999997],[-94.39222699999999,74.12191800000011],[-94.21749899999998,74.13165299999997],[-94.17777999999993,74.1336060000001],[-94.09306300000003,74.13638300000002],[-93.99249299999991,74.138596],[-93.95195000000001,74.13888500000007],[-93.91416900000002,74.13610799999998],[-93.90194699999995,74.13333100000011],[-93.75834699999996,74.09693900000013],[-93.76139799999999,74.12915000000004],[-93.75944500000003,74.13916000000012],[-93.754456,74.14471400000008],[-93.73083500000001,74.15416000000005],[-93.69055199999997,74.16220099999998],[-93.64111299999996,74.16775499999994],[-93.58361799999989,74.17082200000004],[-93.515015,74.17303500000003],[-93.431671,74.17221100000006],[-93.32749899999999,74.16998300000012],[-93.24388099999999,74.16499300000004],[-93.028885,74.14999399999999],[-92.979446,74.14582800000011],[-92.79638699999998,74.12498500000004],[-92.63806199999988,74.10304300000013]],[[-98.65722699999998,74.29942299999999],[-98.74694799999997,74.29803500000008],[-98.81027199999994,74.29832500000009],[-98.83167999999995,74.29914900000006],[-98.85943600000002,74.30137600000012],[-98.86221299999994,74.30247500000013],[-98.86471599999999,74.30470300000007],[-98.86305199999998,74.30748],[-98.85722399999997,74.31137100000007],[-98.75250199999994,74.33415200000007],[-98.71833800000002,74.33665500000001],[-98.630829,74.34248400000007],[-98.61665299999999,74.34193400000004],[-98.58583099999998,74.338593],[-98.57362399999994,74.334991],[-98.535278,74.3288730000001],[-98.52166699999998,74.32470699999999],[-98.511124,74.318329],[-98.51556399999993,74.31414799999993],[-98.52500900000001,74.31053200000008],[-98.5686189999999,74.30470300000007],[-98.65722699999998,74.29942299999999]],[[-120.14998600000001,74.27249100000006],[-119.86472300000003,74.23776200000003],[-119.84528399999999,74.23580900000007],[-119.79527299999995,74.234421],[-119.72501399999993,74.23387100000014],[-119.60916099999997,74.23332199999999],[-119.63971699999996,74.19303900000011],[-119.65139799999997,74.18165599999992],[-119.67250099999995,74.165817],[-119.69082599999996,74.15693699999997],[-119.70249899999999,74.15304600000007],[-119.72305299999994,74.14471400000008],[-119.79415899999998,74.11526500000014],[-119.80332900000002,74.11053500000008],[-119.82417299999992,74.09471100000013],[-119.833618,74.082764],[-119.83612099999999,74.07582100000002],[-119.83277900000002,74.06414799999999],[-119.8272169999999,74.05914300000012],[-119.77916699999997,74.03387500000002],[-119.76806599999986,74.03027300000008],[-119.74481199999997,74.02551300000005],[-119.72860699999995,74.02915999999999],[-119.72609699999992,74.03581200000008],[-119.72638699999993,74.04193100000009],[-119.73777799999999,74.05802900000015],[-119.650284,74.11859099999998],[-119.51000999999991,74.20915200000002],[-119.50083899999998,74.21388200000001],[-119.48916599999995,74.21748399999996],[-119.46528599999994,74.22110000000004],[-119.44972199999995,74.221924],[-119.25723299999999,74.21832300000011],[-119.18472300000002,74.21693399999992],[-119.16528299999987,74.21499599999999],[-119.14862099999999,74.2122040000001],[-119.137787,74.20860300000004],[-119.12110899999993,74.1997070000001],[-119.11554699999999,74.19497700000005],[-119.10193600000002,74.17942800000014],[-119.09638999999999,74.16832],[-119.090843,74.15693699999997],[-119.07055700000001,74.11470000000008],[-119.06527699999998,74.10331700000006],[-119.07084699999996,74.08998099999997],[-119.08084099999996,74.07777399999998],[-119.08805799999999,74.07276900000011],[-119.10166900000002,74.06971699999997],[-119.11972000000003,74.06805400000007],[-119.14723199999997,74.06219500000003],[-119.15222199999994,74.05609100000004],[-119.18721,73.99414100000013],[-119.18721,73.98776200000009],[-119.16750299999995,73.98719800000015],[-118.98889200000002,73.99803200000002],[-118.973053,74.00027499999999],[-118.96362299999993,74.00499000000002],[-118.80777,74.09054600000013],[-118.80055199999998,74.09582499999993],[-118.79028299999993,74.10775799999999],[-118.78751399999999,74.11470000000008],[-118.79277000000002,74.125809],[-118.79804999999999,74.13081400000004],[-118.80695299999996,74.13388099999997],[-118.82333399999999,74.13638300000002],[-118.83693699999992,74.1394350000001],[-118.84805299999994,74.143326],[-118.86721799999998,74.15138200000007],[-118.88333099999994,74.16638200000006],[-118.88612399999994,74.17192100000005],[-118.881104,74.17804000000007],[-118.84388699999994,74.18830900000012],[-118.72000100000002,74.21276899999992],[-118.67388899999997,74.21998600000006],[-118.60722399999997,74.22831700000012],[-118.50583599999999,74.23997499999996],[-118.17999299999991,74.27221700000013],[-118.12249799999995,74.27581800000002],[-118.10193600000002,74.27638200000013],[-118.031387,74.2752690000001],[-117.97361799999999,74.26915000000002],[-117.91860999999989,74.26220700000005],[-117.62832599999996,74.24498000000006],[-117.51251199999996,74.238586],[-117.43859900000001,74.22943099999992],[-117.422234,74.22692900000004],[-117.37609899999995,74.21832300000011],[-117.28943599999997,74.1997070000001],[-117.15722700000003,74.16775499999994],[-116.82833899999997,74.072495],[-116.78500400000001,74.059708],[-116.735817,74.03970300000015],[-116.6224979999999,73.990814],[-116.52806099999998,73.94970699999999],[-116.441101,73.91360500000002],[-116.348053,73.87553400000002],[-116.33805799999999,73.87164300000012],[-116.32778899999988,73.86775200000005],[-116.31471299999993,73.86442600000004],[-116.29888900000003,73.86164900000011],[-116.20805399999995,73.83831800000007],[-116.05583199999995,73.79275500000011],[-116.00556899999998,73.77331500000014],[-115.97638699999999,73.75555400000002],[-115.91443599999997,73.72637900000012],[-115.89444699999996,73.71859699999999],[-115.817497,73.69831800000003],[-115.603882,73.65220599999998],[-115.402222,73.568329],[-115.36694299999999,73.5458220000001],[-115.34889199999998,73.53193700000003],[-115.33194700000001,73.51165800000007],[-115.31500199999999,73.47970599999991],[-115.32305899999994,73.47442600000005],[-115.449432,73.42665100000005],[-115.46140300000002,73.42303499999997],[-115.69943199999989,73.36886600000014],[-115.83473199999997,73.33998100000008],[-115.862213,73.33442700000012],[-116.26750199999998,73.27304100000015],[-116.33556399999998,73.26721199999992],[-116.37249800000001,73.26554900000002],[-116.42500299999995,73.26165800000012],[-116.45612299999993,73.25749200000001],[-116.46945199999999,73.25471500000015],[-116.69304699999992,73.20387300000004],[-116.80943299999996,73.168045],[-116.94803599999995,73.12498500000004],[-117.02639799999997,73.10693400000002],[-117.16915899999998,73.08194000000009],[-117.39388999999994,73.04859899999991],[-117.42639200000002,73.04498300000006],[-117.46610999999996,73.03637700000013],[-117.708054,72.97776800000008],[-117.83667000000003,72.93858300000011],[-117.891953,72.919983],[-117.925003,72.90887500000002],[-117.97501399999993,72.89637800000003],[-118.01611300000002,72.88832100000002],[-118.11527999999993,72.87081899999998],[-118.21806300000003,72.85470599999996],[-118.27362099999999,72.84443699999991],[-118.314438,72.83610499999992],[-118.36609599999997,72.82443200000012],[-118.38999899999993,72.81776400000012],[-118.44444299999998,72.79887400000001],[-118.45333900000003,72.79443400000014],[-118.46000700000002,72.78915400000011],[-118.46472199999994,72.7833250000001],[-118.48528299999992,72.76748700000007],[-118.49610899999999,72.76361099999997],[-118.53472899999991,72.75471500000003],[-118.54943799999995,72.75248700000009],[-118.58528100000001,72.75027500000004],[-118.65805099999994,72.74803200000008],[-118.70861799999994,72.74359099999998],[-118.75306699999999,72.73692299999999],[-118.77861000000001,72.73109399999998],[-119.11444099999994,72.63943500000005],[-119.1375119999999,72.63247700000005],[-119.15888999999999,72.62498499999998],[-119.16750299999995,72.62052900000003],[-119.30943300000001,72.43887300000006],[-119.3163909999999,72.42581200000012],[-119.33000199999987,72.39414999999997],[-119.33249699999999,72.38720699999999],[-119.33000199999987,72.38165300000014],[-119.32501200000002,72.3766480000001],[-119.30999800000001,72.368042],[-119.30277999999993,72.36303700000013],[-119.30248999999998,72.35664400000002],[-119.31111099999993,72.35220300000009],[-119.40444899999994,72.32554599999997],[-119.429169,72.31971699999997],[-119.51555599999989,72.3058170000001],[-119.62666300000001,72.27832000000012],[-119.65750099999991,72.26721199999997],[-119.67804699999999,72.25943000000001],[-119.760559,72.22886700000004],[-119.80139200000002,72.22137500000008],[-119.837784,72.21971100000007],[-119.97250399999996,72.22110000000009],[-120.12372599999998,72.23259700000011],[-120.13405599999999,72.23375699999997],[-120.13871799999998,72.23642000000007],[-120.13621499999994,72.23992900000013],[-120.12888299999992,72.24192800000014],[-120.14362299999993,72.2494200000001],[-120.12943999999999,72.25166300000006],[-120.12721299999993,72.25860600000004],[-120.12999000000002,72.26416000000006],[-120.13999899999993,72.26776100000006],[-120.15750099999997,72.26971400000002],[-120.17582699999997,72.2688750000001],[-120.24109599999997,72.26249700000011],[-120.251106,72.25860600000004],[-120.25945299999995,72.246643],[-120.26139799999987,72.23970000000003],[-120.25862099999995,72.23414600000001],[-120.23144500000001,72.21481299999999],[-120.225281,72.21247900000014],[-120.21028899999999,72.20881700000001],[-120.19810499999994,72.20432299999999],[-120.18894999999998,72.19915000000009],[-120.18578299999996,72.19615199999998],[-120.14527900000002,72.14999400000005],[-120.14499699999993,72.14359999999999],[-120.17582699999997,72.09443700000008],[-120.19415299999997,72.07832300000013],[-120.30526699999996,72.01304600000009],[-120.329453,71.99914600000005],[-120.34750399999996,71.99081400000006],[-120.383621,71.98165899999998],[-120.41332999999986,71.97137499999997],[-120.423317,71.96748400000007],[-120.4391629999999,71.95832800000011],[-120.445267,71.95304899999996],[-120.4491579999999,71.94693000000012],[-120.45278899999994,71.93470799999994],[-120.45249899999993,71.92776500000014],[-120.44972200000001,71.92221099999995],[-120.439438,71.91220100000004],[-120.43167099999994,71.90803499999998],[-120.391953,71.89305100000007],[-120.38445300000001,71.88888500000002],[-120.37917299999998,71.88388100000003],[-120.380829,71.87831099999994],[-120.41500899999994,71.77638200000013],[-120.42278299999998,71.76416000000012],[-120.42471299999994,71.75721699999997],[-120.42639199999996,71.74443100000002],[-120.423607,71.73887599999995],[-120.41332999999986,71.72886699999998],[-120.40805099999994,71.72387700000007],[-120.40055799999993,71.71943700000008],[-120.37998999999996,71.69970700000005],[-120.37748699999992,71.69413800000007],[-120.37693799999994,71.68803400000007],[-120.380829,71.68193100000008],[-120.43611099999998,71.61192299999993],[-120.473053,71.56553600000007],[-120.49665799999997,71.54414400000002],[-120.54332699999992,71.516663],[-120.60166900000002,71.49359100000004],[-120.63639799999999,71.48553500000014],[-120.78028899999998,71.45721400000008],[-120.80750299999988,71.45248400000003],[-120.87721299999998,71.44136000000015],[-120.921944,71.43553200000002],[-121.13333099999994,71.40942400000006],[-121.33249699999993,71.386932],[-121.39444700000001,71.38026400000001],[-121.42916899999994,71.37831100000005],[-121.44833399999999,71.37942500000003],[-121.59056099999998,71.39637800000014],[-121.60305799999998,71.399429],[-121.59137699999991,71.40277100000009],[-121.57611099999997,71.40443400000004],[-121.54915599999993,71.40914900000007],[-121.53751399999999,71.41249099999999],[-121.53195199999993,71.417755],[-121.52861000000001,71.42387400000001],[-121.531677,71.42942799999997],[-121.53694200000001,71.43441800000005],[-121.54998799999993,71.44358800000009],[-121.56973299999999,71.45166000000006],[-121.59638999999999,71.45694000000015],[-121.63027999999991,71.46054099999998],[-121.66860999999994,71.46276899999998],[-121.70361300000002,71.46081500000014],[-121.74388099999999,71.45332300000001],[-121.75556899999998,71.45027199999998],[-121.77639799999997,71.44303899999994],[-121.81220999999994,71.4266510000001],[-121.82917800000001,71.41832],[-121.84612299999998,71.40971400000006],[-121.901947,71.3785860000001],[-121.96528599999999,71.34275800000006],[-122.07501199999996,71.28692600000005],[-122.12165799999991,71.26721199999997],[-122.14417300000002,71.26081799999992],[-122.21056399999986,71.24832200000003],[-122.25446299999999,71.24247700000012],[-122.29833999999994,71.23637400000001],[-122.35526999999996,71.22776800000008],[-122.43028299999997,71.21415700000011],[-122.50556899999992,71.19775400000003],[-122.593887,71.17804000000012],[-122.60500299999995,71.17498800000004],[-122.61638600000003,71.17164600000007],[-122.64584400000001,71.16053800000009],[-122.66221599999994,71.15193199999999],[-122.67832900000002,71.14332600000006],[-122.7069469999999,71.12442000000004],[-122.74249299999997,71.101089],[-122.76999699999988,71.08915700000006],[-122.781113,71.08610499999992],[-122.79611199999988,71.08415200000002],[-122.84944199999995,71.0816650000001],[-123.07611099999986,71.07916300000005],[-123.09500099999997,71.07998700000002],[-123.1260989999999,71.08387800000008],[-123.162781,71.09275800000012],[-123.22332799999998,71.11415099999999],[-123.25945300000001,71.12970000000013],[-123.29305999999985,71.14610299999998],[-123.31696299999999,71.15859999999998],[-123.37027,71.18887300000011],[-123.3952789999999,71.20776399999994],[-123.42999299999997,71.2369230000001],[-123.44860799999998,71.25776700000011],[-123.46640000000002,71.28553799999997],[-123.51390099999998,71.34915200000006],[-123.56696299999993,71.40609699999993],[-123.63417099999992,71.47248799999994],[-123.66583299999996,71.49636800000013],[-123.67971799999998,71.50526400000007],[-123.84388699999994,71.58332800000011],[-123.88722200000001,71.62359599999996],[-123.89917000000003,71.63304100000005],[-123.94888299999997,71.65832500000005],[-123.97582999999997,71.6702580000001],[-124.01334400000002,71.68580600000007],[-124.02390300000002,71.68914800000005],[-124.07055700000001,71.70193500000005],[-124.11138900000003,71.70999100000012],[-124.13694800000002,71.71443200000004],[-124.38474299999996,71.75471500000009],[-124.458054,71.76638800000012],[-124.609734,71.78804000000014],[-124.65278599999994,71.79525799999999],[-124.678879,71.80081200000012],[-124.700287,71.80636600000014],[-124.83194700000001,71.84082000000001],[-124.86665299999993,71.85054000000008],[-125.07694999999995,71.90914900000013],[-125.16000400000001,71.92468300000007],[-125.23638900000003,71.94191000000006],[-125.24722300000002,71.94551100000012],[-125.25361599999997,71.95025599999997],[-125.24472000000003,71.95442200000008],[-125.04804999999999,71.95553600000005],[-124.98029300000002,71.94358799999998],[-124.96945199999999,71.93997200000013],[-124.953888,71.93803400000002],[-124.94275699999997,71.93997200000013],[-124.93804899999998,71.94552599999992],[-124.93554699999999,71.95165999999995],[-124.93971299999998,71.95694000000003],[-124.94833399999999,71.96110500000003],[-124.98777799999999,71.96971100000013],[-125.02278100000001,71.97250400000013],[-125.23277300000001,71.97552499999995],[-125.35221899999999,71.97468600000002],[-125.41639700000002,71.97413599999999],[-125.47833300000002,71.97276300000004],[-125.59111000000001,71.96638500000012],[-125.62666299999995,71.96360800000002],[-125.68639399999995,71.95498700000007],[-125.72165699999994,71.9522090000001],[-125.76139799999993,71.95082100000002],[-125.80139199999996,71.9522090000001],[-125.93582199999992,71.95860299999998],[-125.97361799999999,71.96054100000009],[-125.984444,71.96388200000013],[-125.99333200000001,71.96804800000001],[-125.997772,71.97360200000003],[-125.99333200000001,71.9788670000001],[-125.97778299999999,71.97970600000002],[-125.966949,71.97637900000012],[-125.90055799999999,71.96249400000005],[-125.88054699999992,71.96331800000002],[-125.8497309999999,71.96720900000008],[-125.80999799999995,71.97554000000014],[-125.787781,71.98220800000013],[-125.77887699999991,71.98637400000001],[-125.765289,71.99609400000008],[-125.75418100000002,72.006104],[-125.74082899999996,72.02275100000003],[-125.73388699999998,72.034134],[-125.724716,72.0519260000001],[-125.71777299999985,72.07054099999999],[-125.71528599999994,72.08360300000004],[-125.71528599999994,72.09027099999997],[-125.71749899999992,72.09637500000002],[-125.72165699999994,72.10192900000004],[-125.72833299999996,72.10664400000007],[-125.73944099999989,72.1102600000001],[-125.714447,72.15748599999995],[-125.57389799999993,72.24746700000014],[-125.51445000000001,72.29107699999997],[-125.46777299999997,72.3510740000001],[-125.43221999999997,72.40358000000003],[-125.43666099999996,72.40913400000005],[-125.30055199999993,72.48330700000002],[-125.29110699999995,72.48718300000007],[-125.27971600000001,72.49052400000011],[-125.25787399999996,72.49512500000014],[-125.247772,72.49523899999997],[-125.17194399999994,72.51359600000006],[-125.1394499999999,72.52413899999999],[-125.02806099999998,72.56607100000008],[-125,72.60525499999994],[-124.94055199999997,72.70248400000014],[-124.9719389999999,72.755829],[-125.02610800000002,72.82109100000008],[-124.95916699999998,72.85636900000009],[-124.89334100000002,72.87387100000012],[-124.87917299999998,72.876373],[-124.801941,72.88749700000005],[-124.76695299999994,72.89082300000013],[-124.72749299999987,72.88859600000006],[-124.68804899999986,72.88749700000005],[-124.66944899999993,72.88888499999996],[-124.63667299999997,72.89276100000006],[-124.60611,72.89721699999996],[-124.591949,72.89999400000005],[-124.49722300000002,72.91970799999996],[-124.48554999999999,72.92303500000008],[-124.47582999999997,72.92720000000008],[-124.473053,72.93331899999993],[-124.49305700000002,72.97164900000007],[-124.49722300000002,72.97720300000003],[-124.62138399999992,73.00138900000013],[-124.71250899999995,73.00387600000005],[-124.72609699999998,73.00665300000014],[-124.73777799999999,73.010269],[-124.76972999999992,73.02137800000008],[-124.82417299999992,73.04609700000003],[-124.83332799999994,73.05026200000003],[-124.84916699999997,73.059418],[-124.862503,73.06887800000004],[-124.86694299999994,73.07443200000006],[-124.86888099999999,73.08055100000007],[-124.86389200000002,73.08610500000009],[-124.79472399999992,73.13472000000013],[-124.78500400000001,73.13888500000013],[-124.71362299999987,73.149429],[-124.59916699999985,73.22776800000003],[-124.58640299999996,73.23803700000008],[-124.57389799999993,73.24832199999997],[-124.56360599999988,73.25915500000013],[-124.50805699999995,73.32638500000013],[-124.44583099999994,73.41110200000014],[-124.44055199999997,73.41665599999993],[-124.43306000000001,73.42137099999997],[-124.40556299999997,73.434143],[-124.30555699999991,73.4785920000001],[-124.29332699999998,73.48165900000004],[-124.252228,73.48359699999997],[-124.22833300000002,73.48332199999999],[-124.20916699999998,73.48165900000004],[-124.18998699999997,73.48165900000004],[-124.17304999999999,73.48359699999997],[-124.160553,73.48692300000005],[-124.07000699999998,73.54609700000009],[-124.041946,73.58221400000008],[-124.03888699999993,73.58692900000011],[-124.07167099999998,73.61775200000011],[-124.0786129999999,73.62275699999998],[-124.07611099999991,73.64305100000007],[-124.073059,73.64915500000012],[-124.06777999999991,73.65470900000014],[-124.05526700000001,73.65803499999998],[-123.94554099999993,73.68165600000003],[-123.86138899999997,73.69581599999998],[-123.83389299999999,73.70027200000004],[-123.774719,73.7644350000001],[-123.80471799999987,73.79693600000002],[-123.83833300000003,73.82110600000004],[-123.847778,73.82527199999993],[-123.93639399999995,73.84054600000002],[-123.95834399999995,73.84136999999998],[-123.98055999999991,73.84082000000012],[-124.01999699999999,73.83831800000007],[-124.06639100000001,73.83943200000004],[-124.08583099999998,73.841095],[-124.13417099999992,73.84832799999998],[-124.16306299999985,73.8541560000001],[-124.19860799999992,73.86469999999997],[-124.21749899999986,73.87275700000009],[-124.36860699999988,74.01443500000005],[-124.41166699999991,74.05636600000003],[-124.42666600000001,74.10971100000012],[-124.43415800000002,74.13443000000007],[-124.600281,74.26832600000006],[-124.61805699999996,74.26638800000012],[-124.66082799999992,74.26470899999993],[-124.68083200000001,74.26609800000011],[-124.69304699999986,74.26944000000003],[-124.77500900000001,74.31915299999997],[-124.784157,74.32998700000007],[-124.781387,74.33610499999998],[-124.77084400000001,74.34027100000009],[-124.75556899999992,74.342758],[-124.69722000000002,74.34721400000006],[-124.40471600000001,74.36914100000013],[-124.108612,74.39276100000012],[-123.89527899999996,74.39637800000008],[-123.85694899999987,74.39942900000011],[-123.676941,74.41832000000011],[-123.63834399999996,74.42137100000014],[-123.57444800000002,74.42414900000011],[-123.41887700000001,74.42831400000011],[-123.20584100000002,74.44303900000006],[-123.02250700000002,74.444702],[-122.68998699999992,74.45387299999999],[-122.43804899999998,74.46499599999993],[-122.33750900000001,74.47109999999998],[-122.118607,74.49192800000003],[-122.06610099999995,74.49803200000008],[-121.93859900000001,74.518326],[-121.766663,74.53970300000003],[-121.73000299999995,74.54332],[-121.65194699999995,74.54859899999997],[-121.61028299999992,74.55053700000013],[-121.56416300000001,74.55108600000005],[-121.51862299999993,74.54887400000001],[-121.31082200000003,74.53166199999998],[-121.25361599999997,74.52581800000013],[-121.13612399999994,74.50694300000004],[-121.08389299999993,74.49359099999998],[-121.05777,74.48664900000006],[-121.01112399999988,74.47221400000012],[-121.00222799999995,74.46775800000006],[-120.98998999999998,74.45803799999999],[-120.98055999999991,74.4474790000001],[-120.97693599999991,74.44192500000008],[-120.97556299999991,74.42970300000013],[-120.90638699999994,74.41526800000003],[-120.70584100000002,74.37359600000013],[-120.48166700000002,74.32998700000007],[-120.2172159999999,74.282486],[-120.14998600000001,74.27249100000006]],[[-97.65278599999999,74.45582600000006],[-97.67555199999998,74.45498700000013],[-97.69193999999999,74.45526100000006],[-97.70889299999999,74.45721400000002],[-97.777222,74.47637900000012],[-97.789444,74.47998000000001],[-97.79249599999991,74.48580900000002],[-97.781387,74.49720800000011],[-97.76861600000001,74.5080410000001],[-97.76167299999992,74.512497],[-97.75389099999995,74.51554899999996],[-97.61805700000002,74.55220000000003],[-97.53222700000003,74.60636900000009],[-97.51362599999999,74.61137400000013],[-97.47000100000002,74.62109400000003],[-97.445831,74.626083],[-97.42277499999994,74.62942499999991],[-97.40695199999993,74.62831100000011],[-97.389725,74.626373],[-97.36805699999996,74.62275699999998],[-97.35777299999995,74.62136800000013],[-97.29138199999994,74.60525500000011],[-97.26722699999993,74.59721400000001],[-97.26167299999992,74.59471100000007],[-97.256958,74.59054600000007],[-97.26194800000002,74.58387800000008],[-97.29998799999987,74.55137600000006],[-97.37609899999995,74.51165800000007],[-97.38751199999996,74.50637799999998],[-97.60638399999999,74.46192900000005],[-97.65278599999999,74.45582600000006]],[[-95.31111099999998,74.49775700000009],[-95.33139,74.49609399999997],[-95.35333299999996,74.49636800000007],[-95.45889299999999,74.49859600000002],[-95.48055999999991,74.5],[-95.52278100000001,74.50499000000008],[-95.60305799999992,74.51554899999996],[-95.66166699999997,74.52360500000003],[-95.69776899999994,74.52970900000003],[-95.71665999999999,74.53387499999997],[-95.80943299999996,74.55442799999997],[-95.84500099999997,74.56387300000006],[-95.862213,74.56999200000007],[-95.86639400000001,74.57415800000001],[-95.86054999999999,74.57916300000005],[-95.85749799999996,74.58055100000013],[-95.68249500000002,74.634995],[-95.653885,74.64221199999992],[-95.63806199999999,74.64332600000012],[-95.62416100000002,74.641663],[-95.628601,74.64082300000013],[-95.51750199999992,74.63026400000007],[-95.49749800000001,74.62719700000014],[-95.441101,74.613876],[-95.40360999999996,74.60331699999995],[-95.33444199999997,74.58082599999994],[-95.31777999999997,74.57388300000014],[-95.29194599999994,74.56025700000004],[-95.26028399999996,74.54054300000007],[-95.25111400000003,74.53414900000007],[-95.24499500000002,74.52777100000009],[-95.24638399999998,74.52165200000007],[-95.25111400000003,74.51609800000006],[-95.25917099999998,74.5105440000001],[-95.27111799999994,74.50555400000002],[-95.28944399999995,74.50138900000002],[-95.31111099999998,74.49775700000009]],[[-97.17582700000003,75.24414100000007],[-97.19444299999998,75.24275200000005],[-97.21611000000001,75.24470500000001],[-97.22500600000001,75.24803199999991],[-97.23194899999993,75.25444000000005],[-97.27806099999998,75.3435970000001],[-97.275284,75.347488],[-97.25805699999995,75.34942600000011],[-97.20861799999994,75.34220900000003],[-97.19055199999997,75.33526599999999],[-97.16166699999985,75.32222000000007],[-97.15306099999992,75.31526200000008],[-97.14889499999992,75.29776000000004],[-97.14695699999999,75.27998400000007],[-97.14750700000002,75.27388000000008],[-97.15583800000002,75.25526400000001],[-97.16166699999985,75.25000000000006],[-97.17582700000003,75.24414100000007]],[[-103.9175029999999,75.05497700000001],[-104.22917199999995,75.01805100000007],[-104.261124,75.01832600000012],[-104.45944199999991,75.02886999999998],[-104.662216,75.06248500000004],[-104.84722899999991,75.10914600000007],[-104.85722399999992,75.16470300000003],[-104.82000699999998,75.17776500000002],[-104.79998799999998,75.18942300000003],[-104.79305999999997,75.19470200000006],[-104.74472000000003,75.24609399999997],[-104.76862299999999,75.28193700000003],[-104.71083099999993,75.32222000000007],[-104.68222000000003,75.33776899999998],[-104.67360699999995,75.34166000000005],[-104.49722299999996,75.40637200000003],[-104.42804699999994,75.42082199999999],[-104.37777699999998,75.42804000000001],[-104.33000199999992,75.43304399999994],[-104.18222000000003,75.43553199999997],[-104.15177900000003,75.4345550000001],[-104.11416600000001,75.43026700000007],[-103.97112299999998,75.4044340000001],[-103.953056,75.3999940000001],[-103.935272,75.39498900000007],[-103.848053,75.36499000000003],[-103.81054699999993,75.34860200000014],[-103.74166899999994,75.28610200000003],[-103.587219,75.16998300000006],[-103.58306899999997,75.16470300000003],[-103.59028599999999,75.15942400000006],[-103.60888699999992,75.14915500000001],[-103.7302929999999,75.09999099999999],[-103.76390100000003,75.08888200000013],[-103.79943799999995,75.07748400000008],[-103.81777999999997,75.07249499999995],[-103.88999899999999,75.05831899999998],[-103.9175029999999,75.05497700000001]],[[-100.17223399999995,75.60137900000001],[-100.15722700000003,75.58943200000004],[-100.15778399999994,75.58499100000012],[-100.17639200000002,75.57998699999996],[-100.23332199999993,75.56915300000009],[-100.383331,75.55358899999999],[-100.45417800000001,75.54637100000002],[-100.47972099999993,75.54582200000004],[-100.47556299999997,75.54998799999998],[-100.45749699999999,75.55415299999999],[-100.43195299999991,75.55831900000004],[-100.40666199999987,75.56137099999995],[-100.36110699999995,75.56553599999995],[-100.31777999999986,75.57304399999998],[-100.30332900000002,75.57748400000003],[-100.29361,75.584427],[-100.30332900000002,75.58859300000006],[-100.31973299999999,75.59082000000012],[-100.33917199999996,75.59136999999998],[-100.36332699999997,75.59027100000003],[-100.52778599999994,75.57720899999998],[-100.74973299999994,75.55802900000003],[-100.86527999999998,75.54721100000006],[-100.88555899999994,75.54582200000004],[-100.90862300000003,75.54637100000002],[-100.950287,75.54971300000011],[-100.99445300000002,75.55497700000012],[-101.02333099999993,75.55998199999999],[-101.03333299999997,75.56303400000007],[-101.03943600000002,75.56721500000015],[-101.02583299999998,75.57054099999999],[-100.84277299999991,75.58692900000005],[-100.70249899999993,75.58888200000001],[-100.68055699999996,75.58943200000004],[-100.65583800000002,75.59165999999999],[-100.64167800000001,75.59610000000004],[-100.62027,75.60609400000004],[-100.59861799999999,75.61025999999993],[-100.51112399999994,75.61914100000007],[-100.39444700000001,75.62303199999997],[-100.27639799999997,75.62303199999997],[-100.23500099999995,75.62303199999997],[-100.21777299999997,75.621918],[-100.204453,75.61747700000006],[-100.19499200000001,75.61331200000006],[-100.17223399999995,75.60137900000001]],[[-94.36389200000002,75.59082000000012],[-94.32695000000001,75.57971199999997],[-94.24388099999993,75.54971300000011],[-94.20527599999991,75.52970900000003],[-94.01028399999996,75.44220000000007],[-93.98971599999999,75.4349820000001],[-93.83972199999994,75.38804600000003],[-93.74249299999997,75.3644260000001],[-93.49916099999996,75.2647090000001],[-93.48750299999995,75.25665300000003],[-93.49333199999995,75.24720799999994],[-93.52917500000001,75.17637600000006],[-93.48889200000002,75.07249499999995],[-93.43415799999997,74.966385],[-93.406387,74.88360599999999],[-93.45805399999995,74.7149960000001],[-93.46250899999995,74.70860299999993],[-93.46777299999997,74.70304899999996],[-93.48472600000002,74.68775900000014],[-93.49610899999999,74.68193100000002],[-93.53056300000003,74.66775500000006],[-93.56332399999997,74.65942400000012],[-93.69166599999994,74.63998400000014],[-93.71722399999987,74.63693200000006],[-93.741379,74.63554399999998],[-94.04028299999999,74.64082300000013],[-94.24999999999989,74.64637800000003],[-94.38806199999999,74.63526900000011],[-94.47111499999988,74.62664800000005],[-94.51194799999996,74.62330600000007],[-94.5475009999999,74.62136800000013],[-94.64334099999996,74.62359600000008],[-94.68777499999993,74.62831100000011],[-95.02471899999995,74.67303500000008],[-95.08000199999998,74.68081700000005],[-95.08583099999998,74.68719500000003],[-95.07694999999995,74.69747900000004],[-95.07278399999996,74.7022090000001],[-95.104446,74.74414100000013],[-95.26640299999991,74.79331999999994],[-95.28332499999999,74.79803499999997],[-95.29834,74.80026200000003],[-95.40333599999991,74.80386399999998],[-95.43415800000002,74.801376],[-95.45750399999997,74.79832499999998],[-95.479172,74.78804000000008],[-95.4830629999999,74.78332500000005],[-95.48277299999995,74.77943399999998],[-95.47555499999999,74.76998900000007],[-95.462219,74.75665300000014],[-95.54722600000002,74.76110799999998],[-95.62582399999991,74.80748000000006],[-95.70556599999998,74.82998700000013],[-95.7408289999999,74.82388300000008],[-95.77139299999993,74.82360800000009],[-95.86416600000001,74.82609600000006],[-95.959473,74.85636900000003],[-96.00250199999988,74.87275700000009],[-96.00666799999993,74.87692300000015],[-96.07722499999994,74.90277100000009],[-96.1352839999999,74.95109600000012],[-96.14167800000001,74.95721400000008],[-96.13694800000002,74.96304300000008],[-96.12470999999994,74.97581500000007],[-96.09472699999998,74.99136400000003],[-96.07084700000001,75.00193800000005],[-96.05638099999999,75.01026899999994],[-96.05555700000002,75.01609799999994],[-96.06054699999999,75.01944000000009],[-96.07417299999986,75.02360500000009],[-96.08306899999997,75.02442900000005],[-96.14222699999999,75.01776100000006],[-96.14750700000002,75.01361100000008],[-96.20083599999992,74.95471200000003],[-96.20333900000003,74.95166000000006],[-96.20666499999993,74.943039],[-96.20388799999995,74.93691999999993],[-96.20584099999996,74.92025799999999],[-96.20973200000003,74.91554300000013],[-96.22138999999999,74.91026300000004],[-96.24777199999988,74.90554800000001],[-96.26834100000002,74.9038700000001],[-96.31527699999998,74.90248100000008],[-96.337219,74.90359500000005],[-96.35749799999996,74.90664700000002],[-96.37361099999998,74.91026300000004],[-96.38722199999995,74.91470300000009],[-96.39666699999992,74.91970800000013],[-96.40306099999998,74.92581200000012],[-96.386124,74.97387700000013],[-96.35749799999996,74.97137500000008],[-96.341385,74.972488],[-96.32806399999998,74.9747010000001],[-96.32055700000001,74.97943099999998],[-96.31834399999997,74.98220800000007],[-96.32223499999986,75.00138900000007],[-96.3311159999999,75.00471500000015],[-96.47666900000002,75.0044400000001],[-96.50083899999993,75.00277700000004],[-96.523056,74.99914599999994],[-96.53388999999999,74.99470500000007],[-96.55972300000002,74.98609899999997],[-96.58029199999999,74.98414600000001],[-96.59999099999999,74.98332200000004],[-96.61416599999995,74.98498499999994],[-96.61694299999999,74.99108899999999],[-96.60472099999998,75.063309],[-96.57139599999994,75.10108900000012],[-96.46305799999993,75.19331399999993],[-96.45639,75.19693000000001],[-96.37860099999995,75.21665999999999],[-96.077789,75.27249100000006],[-95.94804399999998,75.2833250000001],[-95.92250099999995,75.28610200000003],[-95.90333599999991,75.28997800000008],[-95.91055299999994,75.29525799999999],[-95.93443300000001,75.29721100000012],[-95.97805800000003,75.29887400000001],[-96.02667199999996,75.29914900000006],[-96.04998799999993,75.29693600000007],[-96.061935,75.31526200000008],[-96.00361599999997,75.34304799999995],[-95.9324949999999,75.35304300000007],[-95.93471499999998,75.35017399999998],[-95.93472300000002,75.34776299999999],[-95.91999800000002,75.34693900000002],[-95.890289,75.349152],[-95.88744399999996,75.36026800000013],[-95.83677699999987,75.36992600000002],[-95.83078,75.37142900000003],[-95.82978100000003,75.37258900000012],[-95.83061199999986,75.37442800000002],[-95.83278699999994,75.37592300000011],[-95.848274,75.37843299999997],[-95.90677599999998,75.38742800000006],[-95.92777999999987,75.39804100000015],[-96.03332499999993,75.40109300000006],[-96.05526700000001,75.40081800000007],[-96.07888799999989,75.39610300000004],[-96.07917800000001,75.391098],[-96.083618,75.38554399999998],[-96.09973099999996,75.38026400000012],[-96.12609900000001,75.37692300000009],[-96.15110800000002,75.37498499999992],[-96.17527799999999,75.37942499999997],[-96.178879,75.38443000000001],[-96.16194199999995,75.39553799999999],[-96.14973399999991,75.40081800000007],[-96.13500999999997,75.40637200000003],[-96.0958399999999,75.41775500000006],[-96.0625,75.4249880000001],[-95.97416699999997,75.43609600000008],[-95.95834400000001,75.43637100000007],[-95.93638599999997,75.43414300000012],[-95.87416099999996,75.42387400000007],[-95.83104699999996,75.41531400000008],[-95.83254999999997,75.41365100000013],[-95.83322099999998,75.40998800000011],[-95.83104699999996,75.40698200000008],[-95.82588199999998,75.40332000000012],[-95.81438399999996,75.40032200000007],[-95.76955399999986,75.40032200000007],[-95.69110099999995,75.40525800000006],[-95.68249500000002,75.40832499999999],[-95.67610200000001,75.41581700000012],[-95.67832899999996,75.421921],[-95.68472300000002,75.42831400000011],[-95.691666,75.42970300000013],[-95.71583599999991,75.4291530000001],[-95.73416099999992,75.426086],[-95.75862099999995,75.42553700000002],[-95.781677,75.42804000000001],[-95.80055199999993,75.43165600000003],[-95.82501199999996,75.43997200000013],[-95.83000199999992,75.4433140000001],[-95.83694500000001,75.45359800000011],[-95.83805799999999,75.45915200000007],[-95.835556,75.46443199999999],[-95.83222999999998,75.4705350000001],[-95.82417299999997,75.47776799999991],[-95.80055199999993,75.49136400000009],[-95.76222200000001,75.50804100000005],[-95.74972500000001,75.51332100000013],[-95.47000099999997,75.56693999999999],[-95.27528399999994,75.59942600000005],[-95.26417500000002,75.59387200000009],[-95.23443600000002,75.58471700000001],[-95.212784,75.58248900000007],[-95.178604,75.584427],[-95.12470999999988,75.59526100000005],[-95.104172,75.60026600000009],[-95.09333800000002,75.60359199999999],[-95.08583099999998,75.60720800000001],[-95.08416699999998,75.60914600000012],[-95.07528699999995,75.61442600000004],[-95.06332399999991,75.61886600000003],[-95.04444899999987,75.62164300000012],[-94.91776999999996,75.63720700000005],[-94.90167200000002,75.63749700000005],[-94.74137899999994,75.62414600000011],[-94.55972299999996,75.6124880000001],[-94.511124,75.61109900000008],[-94.46556099999998,75.60832199999999],[-94.40417500000001,75.59915200000012],[-94.36389200000002,75.59082000000012]],[[-95.9100039999999,75.56025699999998],[-95.91111799999999,75.55415299999999],[-95.93472300000002,75.54054300000007],[-96.170837,75.4580380000001],[-96.22027600000001,75.45555100000007],[-96.23889200000002,75.45665000000002],[-96.25500499999998,75.46138000000008],[-96.39917000000003,75.51638800000006],[-96.41722099999998,75.52331500000014],[-96.42471299999994,75.52859500000005],[-96.45099599999998,75.52999100000005],[-96.44116199999996,75.53598799999997],[-96.4158329999999,75.54364800000013],[-96.41265900000002,75.54615000000001],[-96.41166699999991,75.54881999999998],[-96.41799200000003,75.55265800000006],[-96.43116799999996,75.55548900000002],[-96.44183299999997,75.55566400000009],[-96.45099599999998,75.55315400000006],[-96.50383799999992,75.53515600000003],[-96.50799599999993,75.53298200000012],[-96.51816599999995,75.526321],[-96.52516199999991,75.51932500000004],[-96.5536039999999,75.50888099999992],[-96.55221599999999,75.50332600000002],[-96.5494379999999,75.49720800000011],[-96.545547,75.49220300000007],[-96.54110700000001,75.48803700000013],[-96.53332499999993,75.48275799999999],[-96.51750199999992,75.47804300000013],[-96.50334199999998,75.47137499999997],[-96.500565,75.4649960000001],[-96.50418099999996,75.4602660000001],[-96.51194800000002,75.45582600000006],[-96.65834000000001,75.38859600000006],[-96.83361799999994,75.35247800000002],[-96.8511049999999,75.35026600000015],[-96.862213,75.35081500000013],[-96.87609899999995,75.35359199999999],[-96.93249499999996,75.376083],[-97.03083800000002,75.45443700000004],[-97.05305499999992,75.49220300000007],[-97.05305499999992,75.49720800000011],[-97.00695799999994,75.50833100000011],[-96.94082599999996,75.52165200000002],[-96.91361999999992,75.52638200000007],[-96.89167799999996,75.52916000000005],[-96.666946,75.55276500000002],[-96.469383,75.58842500000003],[-96.46655299999992,75.59193399999992],[-96.46772799999991,75.59909100000004],[-96.47005499999989,75.60226400000005],[-96.42250099999995,75.62359600000008],[-96.42443800000001,75.6355440000001],[-96.41500899999994,75.64694199999997],[-96.39639299999999,75.64999400000005],[-96.37971500000003,75.651093],[-96.34722899999991,75.65138200000013],[-96.335556,75.65081800000002],[-96.314438,75.6477660000001],[-96.241104,75.62997400000006],[-96.13333099999994,75.60664400000007],[-96.11582900000002,75.60386699999998],[-96.101944,75.60359199999999],[-96.02543600000001,75.60284400000006],[-95.95777899999996,75.58360300000004],[-95.93888900000002,75.57748400000003],[-95.92388899999997,75.57165500000002],[-95.91639700000002,75.56637599999999],[-95.9100039999999,75.56025699999998]],[[-96.954453,75.59553499999998],[-96.9750059999999,75.59471100000002],[-96.99665800000002,75.59776299999993],[-97.00500499999998,75.60443100000009],[-97.00195300000001,75.61080900000007],[-96.98860199999996,75.61804200000006],[-96.97860700000001,75.62303199999997],[-96.96083099999998,75.62747200000013],[-96.779449,75.6602630000001],[-96.75195299999996,75.66470300000009],[-96.72972099999998,75.66526799999997],[-96.720551,75.66415399999994],[-96.71583599999997,75.65998800000006],[-96.718887,75.6538700000001],[-96.722305,75.65295400000002],[-96.74027999999993,75.64694199999997],[-96.84916699999997,75.61331200000006],[-96.954453,75.59553499999998]],[[-96.5791779999999,75.7369230000001],[-96.69665500000002,75.73082],[-96.710556,75.73359700000009],[-96.71722399999999,75.73970000000003],[-96.67860399999995,75.77748100000002],[-96.666946,75.78665200000012],[-96.66082799999998,75.78942900000004],[-96.54110700000001,75.82221999999996],[-96.52528399999994,75.82638499999996],[-96.50750699999998,75.82832300000013],[-96.48443599999996,75.82720899999993],[-96.46806299999992,75.822495],[-96.45584100000002,75.81776400000007],[-96.45750399999997,75.801086],[-96.45916699999998,75.78942900000004],[-96.53971899999999,75.74331699999999],[-96.5536039999999,75.73858600000005],[-96.5791779999999,75.7369230000001]],[[-111.79998799999998,75.839157],[-111.823624,75.83859300000006],[-111.86582899999996,75.84054599999996],[-111.900284,75.84359699999999],[-111.91722099999993,75.84693900000013],[-111.92250100000001,75.85276799999997],[-111.91972399999997,75.85775799999999],[-111.90139799999997,75.86387600000012],[-111.85665899999992,75.867752],[-111.79972799999996,75.87109399999997],[-111.61305199999993,75.88192700000013],[-111.59528399999999,75.8827510000001],[-111.58306899999991,75.88192700000013],[-111.5786129999999,75.879974],[-111.58194699999996,75.87608300000011],[-111.59306300000003,75.87303200000008],[-111.62917299999992,75.85693400000002],[-111.64806399999998,75.85192899999998],[-111.75695799999994,75.84165999999993],[-111.79998799999998,75.839157]],[[-122.340843,75.86276199999998],[-122.36277799999999,75.8580320000001],[-122.39862099999993,75.85942100000011],[-122.66471899999993,75.89387499999998],[-122.69167299999998,75.90026900000004],[-122.693604,75.90220600000004],[-122.69554099999993,75.90803500000004],[-122.68277,75.911652],[-122.633331,75.91970800000007],[-122.58222999999998,75.92192100000005],[-122.53751399999993,75.922485],[-122.37917299999992,75.915817],[-122.35305800000003,75.9144290000001],[-122.337784,75.91137700000002],[-122.32833900000003,75.905823],[-122.32417299999997,75.899719],[-122.33473200000003,75.86914100000001],[-122.340843,75.86276199999998]],[[-121.09306299999997,75.72608900000006],[-121.1100009999999,75.72470099999998],[-121.14306599999992,75.72581500000013],[-121.27555799999993,75.74748199999999],[-121.28832999999997,75.75277700000004],[-121.28582799999998,75.75888100000009],[-121.27194199999997,75.77053799999999],[-121.26306199999993,75.77415499999995],[-121.11694299999999,75.79582199999999],[-121.04332699999992,75.80886800000013],[-121.02944899999989,75.81137100000012],[-121.01917299999997,75.81805400000007],[-121.01500699999997,75.82470700000005],[-121.00083899999993,75.85664400000002],[-120.99833699999988,75.867752],[-121.00695799999988,75.87970000000007],[-121.01363399999997,75.88472000000007],[-121.04222099999998,75.89414999999997],[-121.04750099999995,75.89999399999999],[-121.04250299999995,75.90554800000001],[-121.03859699999998,75.9083250000001],[-120.997772,75.92637600000006],[-120.98000300000001,75.92942799999997],[-120.87777699999998,75.93609600000013],[-120.86776700000001,75.92469800000015],[-120.86776700000001,75.91331500000013],[-120.86972000000003,75.88108799999998],[-120.87110899999993,75.87553400000013],[-120.88474300000001,75.844986],[-120.89835399999998,75.82582100000002],[-120.921112,75.80331400000011],[-120.93804899999998,75.79054300000001],[-120.99388099999993,75.75776700000011],[-121.01862299999993,75.74443100000013],[-121.03278399999994,75.73776200000009],[-121.05248999999992,75.7327580000001],[-121.09306299999997,75.72608900000006]],[[-95.79276999999996,75.899719],[-95.80943299999996,75.89471400000014],[-95.818893,75.90721100000007],[-95.82556199999999,75.91331500000013],[-95.84777799999989,75.92942799999997],[-95.862503,75.93609600000013],[-95.88249200000001,75.94108600000004],[-95.89695699999999,75.94775399999997],[-95.89999399999999,75.95387300000004],[-95.89083900000003,75.959427],[-95.86000100000001,75.96666000000005],[-95.79666099999997,75.97331200000008],[-95.770554,75.9749910000001],[-95.74694799999992,75.97387700000013],[-95.73582499999992,75.96832300000011],[-95.73693800000001,75.9624940000001],[-95.75195299999996,75.92747500000007],[-95.76194799999996,75.91609200000005],[-95.77972399999993,75.90498400000007],[-95.79276999999996,75.899719]],[[-94.40556300000003,75.75082400000008],[-94.5827789999999,75.74581900000004],[-94.629166,75.74609400000008],[-94.67610200000001,75.74775699999998],[-94.72084000000001,75.75387600000005],[-94.739441,75.75749200000007],[-94.77749599999993,75.76860000000005],[-94.79527299999995,75.77581800000007],[-94.80915799999997,75.78248600000006],[-94.82223499999998,75.79414400000007],[-94.89889499999992,75.91276599999998],[-94.90278599999999,75.91943400000014],[-94.90527299999997,75.92553700000008],[-94.90611299999995,75.93081699999999],[-94.904449,75.9369200000001],[-94.89527899999996,75.94220000000001],[-94.87998999999996,75.94552600000003],[-94.86555499999997,75.94747899999999],[-94.81361399999997,75.95054600000009],[-94.73777799999999,75.95220899999998],[-94.69972200000001,75.95555100000013],[-94.53832999999986,75.98609900000008],[-94.48194899999993,75.97442600000005],[-94.46694899999989,75.96859700000005],[-94.45333899999991,75.96192900000011],[-94.44972199999995,75.95526100000012],[-94.443604,75.93830900000012],[-94.42027299999995,75.86859099999998],[-94.41027799999995,75.86192299999999],[-94.37083399999995,75.84220900000008],[-94.32223499999998,75.81498699999997],[-94.30555700000002,75.80304000000001],[-94.28778099999994,75.78387500000002],[-94.28805499999999,75.77748100000002],[-94.291382,75.77221700000001],[-94.29695099999998,75.766388],[-94.31027199999994,75.76138300000014],[-94.32640099999998,75.75721700000008],[-94.35388199999994,75.75387600000005],[-94.40556300000003,75.75082400000008]],[[-103.137787,75.74275200000011],[-103.20667300000002,75.74275200000011],[-103.3011019999999,75.74470500000007],[-103.32389799999999,75.74720800000006],[-103.36888099999999,75.75387600000005],[-103.38082899999995,75.75943000000001],[-103.382767,75.76554900000002],[-103.31139399999995,75.80525200000005],[-103.07749899999999,75.89082300000007],[-103.05943300000001,75.89637800000014],[-103.03751399999993,75.90165700000011],[-103.01194799999996,75.9060970000001],[-102.98693800000001,75.90942400000006],[-102.69611399999997,75.94664],[-102.59889199999986,75.953598],[-102.52278099999995,75.95803800000004],[-102.43360899999999,75.96415700000006],[-102.291382,75.97720300000015],[-102.21749899999998,75.98553500000014],[-102.19138299999997,75.98969999999997],[-102.16471899999993,75.99054000000001],[-102.07861300000002,75.97137500000008],[-101.98916599999995,75.95082100000008],[-101.98332199999987,75.94581600000004],[-101.98860200000001,75.93441800000005],[-102.020554,75.92553700000008],[-102.09472700000003,75.911652],[-102.14639299999993,75.90332000000001],[-102.19638099999997,75.899719],[-102.29638699999998,75.89498900000012],[-102.31916799999999,75.89305100000001],[-102.346657,75.88943499999993],[-102.39417299999997,75.88081400000004],[-102.43055699999991,75.86998],[-102.44082600000002,75.86442599999998],[-102.44943199999994,75.85832199999993],[-102.45584099999996,75.85247800000013],[-102.46000699999996,75.84721400000012],[-102.47165699999988,75.81832900000006],[-102.48277300000001,75.80636600000003],[-102.49694799999992,75.79553199999998],[-102.50917099999998,75.78942900000004],[-102.54527300000001,75.77970900000014],[-102.59028599999994,75.77053799999999],[-102.61165599999998,75.76721199999997],[-102.636124,75.76470899999998],[-102.86638599999998,75.753601],[-103.015289,75.74720800000006],[-103.137787,75.74275200000011]],[[-122.81916799999999,76.06053200000008],[-122.78056300000003,76.05720500000012],[-122.68776700000001,76.05998200000005],[-122.66194200000001,76.05693100000002],[-122.64277599999997,76.05247500000013],[-122.630829,76.04664600000012],[-122.72501399999987,76.02360500000009],[-122.88194299999998,76.01110800000009],[-122.89250199999998,76.01361100000003],[-122.89611799999994,76.02693199999999],[-122.89222699999999,76.03109699999999],[-122.85082999999997,76.05720500000012],[-122.81916799999999,76.06053200000008]],[[-102.38999899999993,76.0836030000001],[-102.37554899999998,76.07916300000011],[-102.37138399999998,76.07916300000011],[-102.36805699999996,76.0772090000001],[-102.3563769999999,76.07582099999996],[-102.35333300000002,76.07388300000002],[-102.33889799999997,76.06944300000004],[-102.33249699999999,76.06553600000007],[-102.32167099999998,76.0535890000001],[-102.31639100000001,76.036926],[-102.31889299999989,76.03109699999999],[-102.319458,76.02470400000004],[-102.32972699999993,76.01582300000013],[-102.34388699999994,76.01026900000011],[-102.36582900000002,76.00582900000012],[-102.41665599999999,76.0002750000001],[-102.51722699999993,75.99108899999999],[-102.56777999999991,75.98553500000014],[-102.695267,75.97331200000008],[-102.71472199999988,75.97026100000005],[-102.73972299999997,75.96804800000012],[-102.79055800000003,75.96138000000013],[-102.81139399999995,75.95999099999995],[-102.93611099999998,75.94802900000002],[-103.01027699999997,75.94303899999994],[-103.08528099999995,75.93580600000013],[-103.15695199999993,75.92581200000012],[-103.21888699999994,75.9202580000001],[-103.26500699999997,75.9144290000001],[-103.28943600000002,75.91304000000014],[-103.339447,75.90803500000004],[-103.37998999999996,75.9060970000001],[-103.39639299999993,75.90443400000004],[-103.43305999999995,75.90332000000001],[-103.45333899999997,75.90165700000011],[-103.52443699999998,75.89888000000002],[-103.59277299999997,75.89721700000007],[-103.61332700000003,75.8955380000001],[-103.63474300000001,75.89109800000006],[-103.65556300000003,75.888596],[-103.6997219999999,75.887497],[-103.72332799999987,75.88916000000012],[-103.77111799999994,75.89637800000014],[-103.81166100000002,75.89942899999994],[-103.88806199999993,75.89804100000003],[-103.901947,75.89860499999998],[-103.91471899999993,75.90248100000008],[-103.91500899999994,75.90776099999994],[-103.91722099999993,75.91360500000013],[-103.92555199999998,75.91914400000013],[-103.93611099999998,75.924149],[-103.964722,75.93441800000005],[-103.97165699999994,75.93830900000012],[-103.94220699999994,75.9427490000001],[-103.901947,75.94386299999991],[-103.82556199999999,75.95082100000008],[-103.80248999999998,75.95387300000004],[-103.78527799999995,75.95748900000007],[-103.77139299999988,75.96304300000008],[-103.75834700000001,75.96666000000005],[-103.7083439999999,75.97248800000011],[-103.6877669999999,75.97387700000013],[-103.598343,75.97720300000015],[-103.57444799999996,75.97665400000005],[-103.55471799999998,75.97526600000015],[-103.5225069999999,75.97554000000008],[-103.49694799999997,75.97998000000007],[-103.474716,75.98525999999998],[-103.45694700000001,75.99081400000011],[-103.41306299999997,76.00166300000001],[-103.391388,76.00610400000011],[-103.36582899999996,76.00942999999995],[-103.34028599999988,76.01388499999996],[-103.31500199999999,76.01721200000009],[-103.29028299999999,76.01859999999999],[-103.26363399999997,76.01944000000009],[-103.22138999999993,76.01915000000002],[-103.196663,76.02053799999999],[-103.178879,76.02499400000005],[-103.15666199999993,76.03665200000006],[-103.13667299999992,76.04165600000005],[-103.120003,76.04332000000005],[-103.05110200000001,76.04359399999998],[-103.00639299999995,76.04470799999996],[-102.98110999999989,76.04693600000013],[-102.95556599999998,76.05026199999998],[-102.91555800000003,76.06025700000009],[-102.88971700000002,76.06442300000015],[-102.86833199999995,76.06694000000005],[-102.86028299999992,76.06666600000011],[-102.85582699999992,76.06776400000001],[-102.75666799999993,76.0730440000001],[-102.708618,76.07748400000008],[-102.68138099999999,76.07916300000011],[-102.65805099999994,76.08221400000014],[-102.60777299999995,76.08581499999997],[-102.53138699999994,76.08943199999993],[-102.46806300000003,76.09027100000009],[-102.42804699999999,76.08943199999993],[-102.40416699999997,76.08776900000004],[-102.39639299999999,76.08665500000006],[-102.38999899999993,76.0836030000001]],[[-118.31639100000001,75.57249500000006],[-118.35472099999993,75.55886800000002],[-118.58306900000002,75.49941999999999],[-118.60472099999998,75.49636800000007],[-118.7036129999999,75.50305200000008],[-118.72250400000001,75.50444000000005],[-118.82749899999999,75.53276100000011],[-118.87361099999998,75.547485],[-118.87777699999998,75.553314],[-118.92804699999999,75.56275900000009],[-118.95305599999995,75.56469700000002],[-119.08194700000001,75.56776400000012],[-119.130829,75.56693999999999],[-119.19695299999995,75.56248499999992],[-119.22250400000001,75.56526200000002],[-119.34028599999999,75.57943699999993],[-119.36749299999991,75.58415199999996],[-119.38333099999994,75.58915700000006],[-119.39527899999996,75.59471100000002],[-119.40583800000002,75.60054000000002],[-119.408051,75.60582000000011],[-119.40471600000001,75.61192300000005],[-119.39750700000002,75.6183170000001],[-119.37554899999998,75.63108800000003],[-119.27528399999994,75.67469800000003],[-119.18831599999987,75.70248400000008],[-119.11389200000002,75.72053500000004],[-118.95472699999999,75.778595],[-118.78888699999999,75.84304800000007],[-118.762787,75.85693400000002],[-118.75834699999996,75.86219800000003],[-118.75334199999992,75.86637900000011],[-118.71694899999994,75.8827510000001],[-118.61916399999996,75.91554300000007],[-118.58139,75.92498799999998],[-118.56388899999996,75.92858900000004],[-118.40444899999994,75.96081500000008],[-118.36776699999996,75.966385],[-118.34028599999999,75.96748400000001],[-118.19415300000003,75.96748400000001],[-118.16832699999998,75.96832300000011],[-118.15222199999994,75.97137500000008],[-118.13751200000002,75.97970599999996],[-118.13137799999998,75.98553500000014],[-118.13137799999998,75.99136399999998],[-118.12748699999992,75.9974820000001],[-118.10500299999995,76.02388000000008],[-118.08860800000002,76.0294340000001],[-118.07140400000003,76.03414900000013],[-118.03751399999987,76.03831500000001],[-117.99804699999993,76.03997800000013],[-117.95722999999992,76.04304500000006],[-117.93360899999993,76.04748500000005],[-117.89972699999998,76.05748],[-117.88971699999996,76.06080600000001],[-117.88500999999997,76.0660860000001],[-117.89138799999995,76.07222000000013],[-117.89277600000003,76.07748400000008],[-117.88612399999988,76.07971200000003],[-117.77887699999991,76.10859700000009],[-117.72609699999998,76.11554000000007],[-117.70694700000001,76.11720300000002],[-117.662216,76.11775199999994],[-117.64111299999996,76.11665299999999],[-117.62304699999999,76.1144260000001],[-117.51944700000001,76.099716],[-117.49166899999989,76.09498600000012],[-117.47138999999993,76.08888200000007],[-117.46389799999997,76.083054],[-117.48916600000001,76.04693600000013],[-117.57305899999994,75.98193400000008],[-117.681107,75.92109700000009],[-117.70445299999989,75.91693099999998],[-117.74694799999997,75.91081200000013],[-117.77555799999993,75.89888000000002],[-117.83833299999998,75.85998500000005],[-117.93721,75.78526299999999],[-117.94499199999996,75.77915999999999],[-117.95221700000002,75.771927],[-117.95638999999994,75.76582299999995],[-117.95638999999994,75.75999500000006],[-117.97138999999993,75.72886700000004],[-118.01583899999997,75.69941699999998],[-118.06221,75.68580600000001],[-118.096947,75.6785890000001],[-118.11389200000002,75.67387400000007],[-118.14277599999997,75.66387900000012],[-118.22193900000002,75.63388100000003],[-118.26363400000002,75.61692800000009],[-118.2675089999999,75.61285399999997],[-118.266953,75.60998500000011],[-118.26834099999991,75.59165999999999],[-118.31639100000001,75.57249500000006]],[[-78.92639199999996,75.875809],[-78.91416900000002,75.87303200000008],[-78.9041749999999,75.86720300000007],[-78.88137799999998,75.85331700000006],[-78.87666300000001,75.84915200000006],[-78.87943999999993,75.84414700000002],[-78.89778100000001,75.83970600000009],[-78.921112,75.83749400000005],[-79.04888900000003,75.836929],[-79.06777999999997,75.84027100000014],[-79.07278399999996,75.84443700000003],[-79.06861899999996,75.8483280000001],[-79.05749499999996,75.85331700000006],[-79.04249599999991,75.8580320000001],[-79.02166699999992,75.86747700000001],[-79.03167699999995,75.8708190000001],[-79.05471799999998,75.87275700000004],[-79.26889,75.87525900000014],[-79.31945799999994,75.87359600000002],[-79.34306300000003,75.87109399999997],[-79.36138900000003,75.86692800000003],[-79.40833999999995,75.85276799999997],[-79.42027300000001,75.84803800000009],[-79.42805499999997,75.84248400000013],[-79.45861799999994,75.81080600000007],[-79.59805299999994,75.86137400000007],[-79.62027,75.86276199999998],[-79.70584099999996,75.86053500000008],[-79.726944,75.86109900000002],[-79.73999000000003,75.86442599999998],[-79.75222799999989,75.8785860000001],[-79.58000199999998,75.94525100000004],[-79.56750499999998,75.94914200000011],[-79.39695699999999,76.00193800000005],[-79.375,76.00555400000007],[-79.27278099999995,76.02804599999996],[-79.13778699999995,76.0772090000001],[-79.12971499999998,76.082764],[-79.12193299999996,76.088593],[-79.11305199999993,76.10054000000014],[-79.09138499999989,76.1144260000001],[-79.081955,76.11637900000005],[-78.92388899999997,76.12109400000008],[-78.9041749999999,76.11970500000007],[-78.89306599999998,76.11554000000007],[-78.82167099999992,76.09832800000004],[-78.80583200000001,76.09304800000001],[-78.79804999999988,76.08638000000002],[-78.79916400000002,76.07998700000007],[-78.82583599999992,76.05802900000009],[-78.83389299999999,76.05247500000013],[-78.845551,76.04748500000005],[-78.86138900000003,76.04332000000005],[-78.92166099999992,76.03193700000003],[-78.99861099999998,76.01499899999999],[-79.06973299999993,75.99832200000014],[-79.08500700000002,75.99386600000008],[-79.14472999999998,75.97526600000015],[-79.15611299999995,75.96998600000006],[-79.16665599999993,75.96415700000006],[-79.17193600000002,75.95887800000008],[-79.17639200000002,75.95277400000003],[-79.17694099999994,75.94636500000001],[-79.17443799999995,75.93942300000009],[-79.16833500000001,75.93193100000013],[-79.14028899999994,75.91886899999997],[-79.11193800000001,75.91026300000004],[-79.029449,75.88832100000013],[-79.01028400000001,75.88472000000007],[-78.98944099999994,75.88192700000013],[-78.943604,75.87803600000007],[-78.92639199999996,75.875809]],[[-94.843613,76.12220800000006],[-94.83111600000001,76.09664900000007],[-94.87027,76.06887799999998],[-94.88917500000002,76.05802900000009],[-94.90556299999992,76.05386400000009],[-94.92860399999995,76.05108600000011],[-95.00666799999999,76.04748500000005],[-95.02722199999994,76.0477600000001],[-95.04888899999997,76.05081200000001],[-95.06249999999994,76.05609099999998],[-95.08639499999992,76.06805400000002],[-95.10194399999995,76.07777400000009],[-95.139725,76.10775799999993],[-95.14416499999993,76.11192299999993],[-95.14723200000003,76.11692799999997],[-95.14639299999999,76.118042],[-95.12110899999999,76.1185910000001],[-95.09445199999999,76.11360200000013],[-95.07694999999995,76.1083220000001],[-95.06054699999999,76.10582],[-95.03056299999997,76.10470600000002],[-95.01306199999993,76.10582],[-94.99276700000001,76.10942100000005],[-94.854446,76.13665800000001],[-94.843613,76.12220800000006]],[[-81.327789,76.14721700000001],[-81.33860799999997,76.14637800000008],[-81.45249899999988,76.15582299999994],[-81.46250899999995,76.15887500000008],[-81.456955,76.16360500000008],[-81.41583300000002,76.17692600000004],[-81.37805199999997,76.184418],[-81.34889199999998,76.1874850000001],[-81.29444899999993,76.18775900000003],[-81.26722699999999,76.18775900000003],[-81.22166399999998,76.18553199999997],[-81.20333899999997,76.18109100000004],[-81.20140100000003,76.17776500000002],[-81.20861799999994,76.172211],[-81.30610699999988,76.15109300000012],[-81.327789,76.14721700000001]],[[-102.53083800000002,76.22331200000002],[-102.52722199999994,76.2169340000001],[-102.53138699999994,76.21165500000012],[-102.58056599999986,76.15248100000002],[-102.636124,76.12553400000007],[-102.65055799999999,76.11998000000011],[-102.67138699999998,76.1141510000001],[-102.73665599999998,76.09860199999997],[-102.78056300000003,76.08970600000004],[-102.80638099999999,76.08554100000003],[-102.85777300000001,76.0788730000001],[-102.93360899999999,76.07083100000011],[-103.34221599999995,76.03665200000006],[-103.36472300000003,76.03581200000002],[-103.67999299999997,76.03414900000013],[-103.82000700000003,76.03137200000003],[-103.86638600000003,76.03082300000005],[-103.91443599999997,76.03166200000004],[-103.962219,76.03471400000012],[-103.97277799999995,76.03970300000009],[-103.92388899999997,76.04081700000006],[-103.87832599999996,76.04386900000003],[-103.86945299999996,76.04748500000005],[-103.88861099999997,76.049713],[-103.98332199999999,76.05720500000012],[-104.06054699999999,76.06219500000003],[-104.08677699999998,76.06053200000008],[-104.08743999999996,76.05819699999995],[-104.13082899999989,76.05636600000003],[-104.39111300000002,76.07832300000007],[-104.40833999999995,76.08221400000014],[-104.47833300000002,76.13581799999997],[-104.48277299999995,76.14221199999997],[-104.46389799999992,76.15887500000008],[-104.45417800000001,76.16442900000004],[-104.31582600000002,76.20803799999999],[-104.29804999999993,76.21249400000005],[-104.27250700000002,76.21609500000011],[-104.24722300000002,76.21859699999999],[-104.17223399999995,76.22415200000012],[-104.14806399999986,76.2227630000001],[-104.07472200000001,76.22221399999995],[-103.9569469999999,76.23304700000011],[-103.91805999999997,76.23997500000013],[-103.85138699999999,76.25000000000006],[-103.59445199999999,76.26527400000009],[-103.33693699999998,76.27998400000007],[-103.13137799999993,76.30304000000007],[-103.11000100000001,76.30470300000002],[-103.05999799999995,76.30636600000014],[-102.86472299999997,76.31109599999996],[-102.81696299999999,76.31219499999997],[-102.765556,76.311646],[-102.72693599999997,76.30581699999999],[-102.66915899999992,76.2958220000001],[-102.66555799999998,76.29470800000013],[-102.65222199999994,76.28776600000003],[-102.64277599999997,76.26998900000012],[-102.633621,76.25749199999996],[-102.62554899999992,76.251938],[-102.6036069999999,76.24552900000009],[-102.55832700000002,76.23580900000002],[-102.54055799999998,76.22943100000009],[-102.53083800000002,76.22331200000002]],[[-89.39889499999998,76.43553200000008],[-89.425003,76.43553200000008],[-89.59916699999997,76.44026200000013],[-89.61361699999998,76.44081100000005],[-89.62554899999998,76.444977],[-89.615005,76.449142],[-89.55915800000002,76.4705350000001],[-89.53306599999996,76.47665400000011],[-89.49499499999996,76.47248800000006],[-89.48832700000003,76.46804800000001],[-89.46583599999991,76.46220399999999],[-89.44638099999992,76.457764],[-89.40834000000001,76.45054600000014],[-89.38612399999994,76.44775400000009],[-89.37805199999997,76.44413800000001],[-89.38055399999996,76.43914799999999],[-89.39889499999998,76.43553200000008]],[[-83.962784,76.42637599999995],[-83.98611499999998,76.42330900000002],[-84.00917099999992,76.42581200000001],[-84.10943600000002,76.44442700000013],[-84.12388599999997,76.451096],[-84.13944999999995,76.50721700000008],[-84.12805200000003,76.50999500000006],[-84.0975039999999,76.50665300000014],[-84.01362599999993,76.49803200000002],[-83.99249299999985,76.49498000000011],[-83.976944,76.49108900000004],[-83.91833499999996,76.46943700000003],[-83.90805099999994,76.4649960000001],[-83.962784,76.42637599999995]],[[-104.053879,76.56303400000007],[-104.03388999999999,76.559708],[-103.87888299999997,76.57360800000009],[-103.86860699999994,76.579163],[-103.86665299999993,76.58499100000012],[-103.87138400000003,76.59664900000013],[-103.86721799999998,76.60304300000001],[-103.85944399999994,76.60720800000001],[-103.82640100000003,76.61831700000005],[-103.804169,76.62191800000011],[-103.78751399999993,76.62052900000015],[-103.58194699999996,76.54775999999998],[-103.58805799999993,76.54193099999998],[-103.59249899999998,76.53581200000013],[-103.59166700000003,76.53137200000009],[-103.587784,76.52499399999994],[-103.57028199999996,76.5211030000001],[-103.404449,76.49470500000012],[-103.38445299999995,76.49220300000002],[-103.321121,76.49498000000011],[-103.24500299999994,76.48553500000003],[-103.05777,76.457764],[-103.03666699999991,76.4538730000001],[-103.01418299999995,76.44775400000009],[-103.0080569999999,76.44165000000004],[-103.00446299999999,76.43525700000009],[-103.00446299999999,76.42997700000001],[-103.011124,76.42330900000002],[-103.01917300000002,76.41804500000006],[-103.0297159999999,76.41249100000005],[-103.0425029999999,76.40637200000003],[-103.098343,76.38472000000002],[-103.17250099999995,76.36276200000003],[-103.20472699999993,76.35470599999996],[-103.281387,76.33692900000011],[-103.37805200000003,76.32554600000009],[-103.55444299999999,76.31025700000004],[-103.70056199999993,76.30415299999999],[-103.75195299999996,76.30358900000004],[-103.848343,76.31025700000004],[-104.06194299999993,76.31749000000002],[-104.11165599999998,76.31637600000005],[-104.33500699999996,76.318604],[-104.37888299999992,76.32331799999997],[-104.396118,76.32777400000003],[-104.40471599999995,76.33332800000005],[-104.404449,76.334427],[-104.38971700000002,76.34275800000012],[-104.37581599999993,76.34832800000004],[-104.362213,76.35220299999997],[-104.34333799999996,76.3541560000001],[-104.32972699999999,76.35803200000004],[-104.328056,76.363876],[-104.39111300000002,76.46110500000003],[-104.43388399999998,76.484985],[-104.44888300000002,76.49108900000004],[-104.47332799999998,76.49331699999999],[-104.48249800000002,76.49054000000012],[-104.483612,76.48580899999996],[-104.49749800000001,76.48109399999993],[-104.52278100000001,76.480545],[-104.56388900000002,76.48220800000013],[-104.65888999999987,76.54582200000004],[-104.66583300000002,76.55165100000005],[-104.63722200000001,76.60331700000012],[-104.56304899999998,76.61276199999998],[-104.53666699999997,76.61720300000007],[-104.445267,76.63581800000003],[-104.40666199999987,76.6455380000001],[-104.37416100000002,76.65582300000005],[-104.35193600000002,76.66026300000004],[-104.31500199999994,76.66387900000012],[-104.26750199999998,76.66720600000002],[-104.21665999999999,76.66832000000005],[-104.13417099999998,76.66943400000002],[-104.05332899999996,76.66470300000009],[-104.031113,76.66165200000006],[-103.96333299999998,76.64999400000005],[-103.93971299999998,76.64471400000014],[-103.926941,76.63804600000014],[-103.9225009999999,76.63360599999999],[-103.92610200000001,76.62191800000011],[-103.93831599999999,76.61053500000014],[-103.95861799999994,76.59915200000012],[-104.02778599999988,76.579163],[-104.051941,76.56887800000004],[-104.053879,76.56303400000007]],[[-98.41805999999991,76.66832000000005],[-98.403885,76.66137700000002],[-98.41393999999991,76.64749100000006],[-98.42360699999995,76.64148699999993],[-98.42578099999997,76.63848900000005],[-98.42527799999999,76.63564300000013],[-98.429169,76.62692299999998],[-98.41972399999992,76.62248200000005],[-98.37609900000001,76.61192300000005],[-98.35777300000001,76.60832199999999],[-98.281387,76.60220300000015],[-98.18055700000002,76.58692900000005],[-98.18971299999998,76.58027600000008],[-98.24276699999996,76.57165500000013],[-98.258621,76.57331800000009],[-98.27833599999997,76.58110000000005],[-98.29834,76.5852660000001],[-98.319458,76.58859300000006],[-98.36250299999995,76.59332300000011],[-98.395554,76.59443700000008],[-98.40194699999995,76.5919340000001],[-98.39889499999992,76.58137500000004],[-98.37805199999997,76.57222000000002],[-98.35777300000001,76.56553600000012],[-98.32278400000001,76.56109600000013],[-98.08056599999998,76.5310970000001],[-97.94444299999998,76.51805100000013],[-97.8977809999999,76.51582300000001],[-97.80777,76.5144350000001],[-97.76445000000001,76.51054400000004],[-97.75029,76.50694299999998],[-97.69332899999995,76.48776200000009],[-97.68472299999996,76.47164900000007],[-97.66221599999994,76.42526199999998],[-97.6625059999999,76.41943400000008],[-97.67027300000001,76.41499299999998],[-97.70695499999994,76.40554800000007],[-97.718887,76.40109300000006],[-97.72721899999999,76.39553799999999],[-97.731674,76.38998400000014],[-97.76139799999999,76.334991],[-97.728882,76.282761],[-97.7261049999999,76.27832000000006],[-97.699432,76.26666300000011],[-97.64805599999994,76.25027500000004],[-97.61054999999999,76.24220300000007],[-97.59167499999995,76.23692299999999],[-97.57556199999999,76.23136900000003],[-97.523056,76.20582600000012],[-97.51695299999994,76.19999700000005],[-97.50917099999998,76.188873],[-97.4949949999999,76.14888000000013],[-97.49444599999987,76.13888500000007],[-97.50306699999987,76.12747200000007],[-97.51777600000003,76.11914100000013],[-97.54249600000003,76.1083220000001],[-97.56332399999997,76.097488],[-97.58833300000003,76.080826],[-97.65638699999994,75.97276299999999],[-97.64750700000002,75.94442700000008],[-97.64555399999989,75.93887300000006],[-97.64222699999993,75.9327550000001],[-97.612503,75.9019320000001],[-97.597778,75.88943499999993],[-97.597778,75.84693900000013],[-97.6541749999999,75.79832499999998],[-97.66416900000002,75.79332000000011],[-97.693604,75.78581200000008],[-97.70750399999997,75.78332499999999],[-97.837219,75.76554900000002],[-97.91332999999997,75.75166300000006],[-97.93055700000002,75.74693300000001],[-97.93859899999995,75.74136400000003],[-97.87054399999994,75.73054499999995],[-97.82722499999988,75.7269290000001],[-97.69027699999987,75.72053500000004],[-97.42555199999998,75.69220000000007],[-97.40444899999994,75.68803400000013],[-97.38667299999997,75.68275499999999],[-97.37582399999985,75.67637600000012],[-97.36999500000002,75.6708220000001],[-97.368607,75.65942400000012],[-97.36915599999998,75.65332000000006],[-97.38473499999998,75.64332600000006],[-97.39445499999994,75.63832100000002],[-97.41000399999996,75.62081899999998],[-97.41194200000001,75.61554000000001],[-97.42388900000003,75.52859500000005],[-97.42250100000001,75.50637799999998],[-97.41749599999997,75.49470500000012],[-97.40139799999986,75.45860299999998],[-97.398056,75.45248400000014],[-97.37832600000002,75.43414300000012],[-97.34973099999996,75.419983],[-97.33056599999992,75.414154],[-97.29388399999999,75.40554800000007],[-97.28500399999996,75.40220599999998],[-97.2808379999999,75.39694199999997],[-97.29333499999996,75.39082300000013],[-97.30555700000002,75.39027400000003],[-97.32055700000001,75.391098],[-97.34167500000001,75.3938750000001],[-97.441666,75.41499299999998],[-97.46916199999998,75.4227600000001],[-97.48416099999992,75.42942800000009],[-97.49610899999999,75.44220000000007],[-97.49888599999997,75.469986],[-97.49665800000002,75.4785920000001],[-97.57362399999988,75.51304600000014],[-97.7119449999999,75.56666600000005],[-97.728882,75.57026700000006],[-97.74415599999998,75.57110600000004],[-97.76251199999996,75.56805400000013],[-97.81806199999988,75.54898100000014],[-97.82755299999991,75.545815],[-97.82705699999991,75.53981799999997],[-97.82172400000002,75.53732300000013],[-97.81156199999992,75.53515600000003],[-97.802055,75.53532400000006],[-97.801941,75.52442900000011],[-97.78999299999992,75.51887499999998],[-97.77416999999991,75.50833100000011],[-97.758896,75.49664300000006],[-97.74804699999987,75.48442100000011],[-97.74472000000003,75.47831700000006],[-97.74333200000001,75.47192400000012],[-97.74526999999995,75.4666600000001],[-97.75639299999995,75.46220400000004],[-97.78332499999988,75.45748900000001],[-97.80749499999996,75.45665000000002],[-97.83583099999998,75.46081500000003],[-97.84083599999985,75.4649960000001],[-97.84500100000002,75.469986],[-97.8556749999999,75.48448200000001],[-97.85600299999993,75.48748800000004],[-97.85800199999989,75.49464400000005],[-97.85916900000001,75.49798599999997],[-97.86983499999991,75.50116000000008],[-97.88233899999994,75.5034940000001],[-97.90834000000001,75.51332100000013],[-97.93249500000002,75.512497],[-97.95195000000001,75.50749200000013],[-98.041672,75.4833220000001],[-98.04333500000001,75.48136899999997],[-97.98554999999999,75.45721400000014],[-97.95750399999991,75.44720499999994],[-97.93331899999998,75.44802900000013],[-97.91111799999993,75.44609099999997],[-97.78277600000001,75.42831400000011],[-97.77471899999995,75.42303500000014],[-97.79361,75.41304000000002],[-97.80860899999993,75.40887500000002],[-97.9344329999999,75.40748600000006],[-97.98472600000002,75.40887500000002],[-98.00472999999988,75.41360500000008],[-98.02806099999992,75.41387900000001],[-98.01989000000003,75.40704299999999],[-98.0287249999999,75.40454100000011],[-98.03238699999991,75.40087900000015],[-98.02955600000001,75.39837599999998],[-98.02122500000002,75.39521000000002],[-97.96055599999994,75.38472000000002],[-97.92027299999995,75.38081399999993],[-97.90139799999992,75.37997400000006],[-97.88444500000003,75.37637300000006],[-97.872772,75.37081900000004],[-97.8766629999999,75.36499000000003],[-97.88778699999995,75.36053500000003],[-97.91027799999995,75.35664400000013],[-97.92639200000002,75.35554500000012],[-97.99055499999997,75.35582],[-98.04276999999996,75.35914600000001],[-98.07010700000001,75.36470000000003],[-98.07076999999998,75.36708800000008],[-98.07411200000001,75.36903399999994],[-98.08277900000002,75.37003300000003],[-98.1077729999999,75.371918],[-98.12471,75.36720299999996],[-98.13639799999999,75.3619230000001],[-98.141953,75.35664400000013],[-98.15361000000001,75.34553500000004],[-98.16528299999999,75.33415200000002],[-98.16471899999993,75.32916300000005],[-98.129166,75.30192599999998],[-98.120544,75.29776000000004],[-98.10139500000002,75.29193100000003],[-98.06471299999993,75.28581200000002],[-97.91305499999999,75.26415999999995],[-97.87388599999997,75.270264],[-97.75584399999991,75.22943100000009],[-97.74360699999994,75.2249910000001],[-97.73500100000001,75.20721400000002],[-97.73693799999995,75.2044370000001],[-97.75973499999998,75.188583],[-97.676941,75.16415400000005],[-97.62860099999989,75.15109300000012],[-97.60249299999992,75.14721700000007],[-97.59750399999996,75.14915500000001],[-97.60583499999996,75.15832500000005],[-97.61444099999989,75.16276600000015],[-97.61305199999998,75.16470300000003],[-97.597778,75.16470300000003],[-97.57861300000002,75.15887500000008],[-97.56777999999997,75.15248100000002],[-97.56750499999993,75.147491],[-97.58250399999991,75.137497],[-97.61944599999993,75.11859099999992],[-97.63999899999999,75.11637900000005],[-97.74694799999997,75.11164900000006],[-97.84388699999994,75.11026000000004],[-97.86250299999989,75.11109900000002],[-97.88137799999993,75.11692800000003],[-98.024719,75.16249099999993],[-98.033615,75.17164600000001],[-98.03443899999996,75.18165600000009],[-98.02694699999995,75.18719500000009],[-98.02027899999996,75.19664],[-98.01916499999999,75.20109600000006],[-98.02583300000003,75.21081500000008],[-98.04138199999989,75.216385],[-98.06166100000002,75.22026100000005],[-98.08528100000001,75.2227630000001],[-98.09861799999993,75.2227630000001],[-98.14666699999987,75.18081699999993],[-98.14666699999987,75.16387900000007],[-98.14555399999995,75.159988],[-98.136124,75.15416000000005],[-98.12138400000003,75.147491],[-98.08139,75.130539],[-98.03916900000002,75.11637900000005],[-98.02555799999993,75.11360199999996],[-98.00306699999993,75.11276199999992],[-97.98167399999994,75.11080900000002],[-97.966949,75.10415599999999],[-97.9472199999999,75.07998700000007],[-97.9388889999999,75.06971699999997],[-97.93859899999995,75.06498699999992],[-97.945831,75.026657],[-97.949997,75.02110300000004],[-97.9600069999999,75.01748700000013],[-97.98249799999991,75.01527399999998],[-98.00306699999993,75.01554900000002],[-98.02027899999996,75.01832600000012],[-98.10888699999998,75.02249100000012],[-98.25917099999992,75.0227660000001],[-98.276947,75.02221700000001],[-98.30027799999993,75.02110300000004],[-98.36971999999997,75.01443500000005],[-98.44444299999998,75.00499000000013],[-98.46833799999996,75.00305200000003],[-98.63473499999998,74.99247700000006],[-98.72389199999992,74.98942600000004],[-98.78500400000001,74.99498000000006],[-98.98500100000001,75.00000000000011],[-99.06695599999995,74.99636800000013],[-99.35444599999988,74.984421],[-99.37666299999995,74.98553499999997],[-99.39416499999999,74.98803700000008],[-99.406113,74.99331699999993],[-99.39361599999995,75.02720599999998],[-99.38751200000002,75.03776600000009],[-99.335556,75.0705410000001],[-99.29943799999995,75.092758],[-99.28195199999999,75.10276800000008],[-99.27694699999995,75.1080320000001],[-99.27223200000003,75.11581400000006],[-99.281387,75.12248199999999],[-99.308044,75.12248199999999],[-99.32583599999992,75.11831699999999],[-99.34056099999998,75.11303700000013],[-99.44554099999993,75.05831899999998],[-99.48249799999996,75.03776600000009],[-99.49665799999997,75.02638200000001],[-99.5,75.02053799999999],[-99.49610899999993,75.01470899999998],[-99.48028599999998,75.00915500000013],[-99.44554099999993,75.00387599999999],[-99.43249500000002,75.0002750000001],[-99.42721599999993,74.99636800000013],[-99.42639199999996,74.99136400000003],[-99.53860500000002,74.974152],[-99.56249999999994,74.97221400000006],[-99.60278299999999,74.97110000000004],[-99.61971999999997,74.97137500000008],[-99.70167500000002,74.97360200000014],[-99.99055499999992,74.984421],[-100.05722000000003,74.9869230000001],[-100.14584400000001,74.99108899999999],[-100.21056399999998,74.997208],[-100.25306699999993,75.00277700000004],[-100.34777799999995,75.0169370000001],[-100.36389200000002,75.02137800000003],[-100.38945000000001,75.03109700000005],[-100.39388999999994,75.03720100000004],[-100.396118,75.04359400000004],[-100.3975069999999,75.05554200000006],[-100.39723199999997,75.06666600000011],[-100.39472999999998,75.07832300000007],[-100.38583399999999,75.0955350000001],[-100.38054699999986,75.10192899999998],[-100.37805200000003,75.11331199999995],[-100.39806399999998,75.15860000000009],[-100.41221599999994,75.16804500000012],[-100.43250299999994,75.17359899999997],[-100.45333900000003,75.17720000000003],[-100.47693599999997,75.17942800000014],[-100.51112399999994,75.184143],[-100.528343,75.18775900000003],[-100.54444899999993,75.19303900000011],[-100.54695099999998,75.1994170000001],[-100.53859699999998,75.20471199999997],[-100.46333299999998,75.22360200000008],[-100.43859900000001,75.226654],[-100.41722099999998,75.22747800000013],[-100.32528699999995,75.23054500000006],[-100.30222299999997,75.23082000000011],[-100.27999899999998,75.22886699999998],[-100.24833699999999,75.22387700000007],[-100.22556299999997,75.22303799999997],[-100.031387,75.22692900000004],[-100.00778200000002,75.22804300000001],[-99.99055499999992,75.23136900000003],[-99.98777799999999,75.23609900000008],[-99.99526999999995,75.23997500000013],[-100.00945300000001,75.24220300000007],[-100.11945300000002,75.24859600000008],[-100.20333900000003,75.25332600000007],[-100.22609699999998,75.25416599999994],[-100.314438,75.25082400000002],[-100.354172,75.25166300000001],[-100.37554899999986,75.25526400000001],[-100.39388999999994,75.26026900000011],[-100.406113,75.26666300000011],[-100.40278599999999,75.27249100000006],[-100.33444199999991,75.274429],[-100.31166100000002,75.27720600000009],[-100.29387700000001,75.28137199999998],[-100.279449,75.28665200000006],[-100.25805700000001,75.29776000000004],[-100.24445299999996,75.30886800000002],[-100.25723299999993,75.31330899999995],[-100.28222699999992,75.31025700000004],[-100.33277900000002,75.30220000000008],[-100.35944399999994,75.299713],[-100.49999999999989,75.29248000000001],[-100.52306399999998,75.293045],[-100.60888699999998,75.30581700000005],[-100.62249799999995,75.30914300000006],[-100.76555599999989,75.34637500000008],[-100.77887699999991,75.35054000000008],[-100.76888999999994,75.35525500000011],[-100.67639199999996,75.37664800000005],[-100.652222,75.37858599999998],[-100.63305700000001,75.37803600000012],[-100.61805700000002,75.37664800000005],[-100.60221899999993,75.37359600000013],[-100.61833199999995,75.36886600000008],[-100.64389,75.36470000000003],[-100.67999299999997,75.3619230000001],[-100.69833399999993,75.35664400000013],[-100.68222000000003,75.35026600000015],[-100.63806199999999,75.34582500000005],[-100.61472299999997,75.34610000000009],[-100.59472699999998,75.347488],[-100.44748699999991,75.36998000000006],[-100.43277,75.37525900000003],[-100.4283289999999,75.38053900000011],[-100.44055200000003,75.38665800000012],[-100.56527699999998,75.422211],[-100.58444199999997,75.426376],[-100.60694899999999,75.42804000000001],[-100.67555199999993,75.42692600000004],[-100.71694899999989,75.4291530000001],[-100.723053,75.43248],[-100.697769,75.43637100000007],[-100.67331699999994,75.43858299999994],[-100.43388399999998,75.44581599999998],[-100.339722,75.4474790000001],[-100.27084400000001,75.44859300000007],[-100.17666600000001,75.449142],[-100.11138899999997,75.451096],[-100.06276700000001,75.45443700000004],[-100.01194800000002,75.46138000000008],[-100.00917099999992,75.46609500000011],[-100.01944700000001,75.46859699999999],[-100.10056299999997,75.4705350000001],[-100.19193999999999,75.467758],[-100.21528599999988,75.467758],[-100.30695300000002,75.47164900000007],[-100.30555699999996,75.47360200000003],[-100.12999000000002,75.52581800000013],[-100.03415699999988,75.52943399999998],[-99.96694899999994,75.53332500000005],[-99.84500099999997,75.540817],[-99.83139,75.54414400000013],[-99.83222999999998,75.54553200000004],[-99.84500099999997,75.547485],[-99.85638399999999,75.54803500000003],[-99.89999399999999,75.547485],[-99.94665500000002,75.54470800000007],[-99.99027999999998,75.54443400000014],[-100.03859699999998,75.549149],[-100.03943600000002,75.55415299999999],[-100.02806099999998,75.55720500000007],[-99.82362399999994,75.58415199999996],[-99.80055199999993,75.58665500000012],[-99.756393,75.58804300000003],[-99.73693800000001,75.5872040000001],[-99.71250899999995,75.58915700000006],[-99.67277499999994,75.60609400000004],[-99.66777000000002,75.61109900000008],[-99.68582199999997,75.613876],[-99.79083300000002,75.6166530000001],[-99.84056099999998,75.6124880000001],[-99.86305199999998,75.61442600000004],[-99.862503,75.61886600000003],[-99.82362399999994,75.651657],[-99.81750499999993,75.655258],[-99.78805499999993,75.65832499999993],[-99.45861799999994,75.67248500000005],[-99.22666900000002,75.67553700000013],[-99.20249899999999,75.67553700000013],[-99.08361799999994,75.67581200000001],[-99.03306600000002,75.67720000000008],[-98.98277300000001,75.68109099999998],[-98.92971799999992,75.68637100000001],[-98.90556299999992,75.68997200000007],[-98.88999899999999,75.69525100000004],[-98.891388,75.69914199999994],[-98.90777599999996,75.70471200000003],[-98.92582700000003,75.70748900000012],[-98.95028699999989,75.709991],[-98.97193900000002,75.71026600000005],[-99.329453,75.69525100000004],[-99.55749499999996,75.69192500000003],[-99.61999500000002,75.69413800000001],[-99.64389,75.69413800000001],[-99.7408289999999,75.69081100000005],[-99.84973100000002,75.67747500000007],[-100.031677,75.66442899999998],[-100.256393,75.651657],[-100.37332199999997,75.65470900000008],[-100.39723199999997,75.65443400000004],[-100.54028299999993,75.64553799999993],[-100.62888299999997,75.63472000000013],[-100.65416699999997,75.63165300000003],[-100.80471799999998,75.61499000000015],[-100.82972699999999,75.61303700000002],[-101.22556299999991,75.5874940000001],[-101.24916100000002,75.5872040000001],[-101.30638099999999,75.591095],[-101.37721299999993,75.59887700000013],[-101.38806199999999,75.60026600000009],[-101.471657,75.60220300000015],[-101.4955369999999,75.60192900000004],[-101.74944299999999,75.57443200000006],[-101.89835399999998,75.5560910000001],[-101.97250399999996,75.54832500000003],[-101.99638399999998,75.54721100000006],[-102.06723,75.54609700000009],[-102.13639799999993,75.553314],[-102.159157,75.55497700000012],[-102.20667300000002,75.553314],[-102.35193599999997,75.54220600000002],[-102.39916999999997,75.53720099999998],[-102.44860799999998,75.53054799999995],[-102.49916099999996,75.5211030000001],[-102.534157,75.51138300000002],[-102.67304999999999,75.51470900000004],[-102.86694299999999,75.601089],[-102.87805200000003,75.60775800000005],[-102.88194299999992,75.61331200000006],[-102.88390400000003,75.61914100000007],[-102.87777699999992,75.62469500000003],[-102.86054999999999,75.62831100000011],[-102.8125,75.63108800000003],[-102.79305999999991,75.63053900000006],[-102.70140100000003,75.62886000000003],[-102.68916299999995,75.6705320000001],[-102.58168,75.71276899999998],[-102.563606,75.718323],[-102.53888699999993,75.72137499999991],[-102.37748699999992,75.72915599999999],[-102.35193599999997,75.72915599999999],[-102.311394,75.72665400000011],[-102.26390100000003,75.72192400000006],[-102.16832699999992,75.70915200000007],[-102.15416700000003,75.7061000000001],[-102.07861300000002,75.688309],[-102.05776999999995,75.69081100000005],[-102.03666699999997,75.69413800000001],[-102.01862299999999,75.69941699999998],[-102.00917099999998,75.70304899999991],[-102.00805700000001,75.70498700000007],[-102.09166699999997,75.72192400000006],[-102.120003,75.77638200000001],[-102.10185200000001,75.78424799999999],[-102.09361299999989,75.79109199999999],[-102.112213,75.79359400000004],[-102.23277299999995,75.78665200000012],[-102.28222700000003,75.78193700000008],[-102.32668299999995,75.77998399999996],[-102.34388699999994,75.78193700000008],[-102.36609599999997,75.78997800000002],[-102.37165800000002,75.79582199999999],[-102.37332200000003,75.80165099999999],[-102.37082700000002,75.80748000000006],[-102.36250299999995,75.81805400000007],[-102.339447,75.83499100000006],[-102.31667299999998,75.84664900000013],[-102.29028299999993,75.85720800000013],[-102.26640299999997,75.86192299999999],[-102.16306299999997,75.87886000000003],[-102.13806199999993,75.88108799999998],[-101.864441,75.90220600000004],[-101.82640099999992,75.89833100000004],[-101.80526700000001,75.89193700000004],[-101.79943800000001,75.88665800000007],[-101.77194199999997,75.86859099999998],[-101.74833699999999,75.85914600000007],[-101.74109599999991,75.85693400000002],[-101.55638099999987,75.82110599999999],[-101.47028399999999,75.77221700000001],[-101.46888699999994,75.766388],[-101.45973199999997,75.76110799999992],[-101.43859900000001,75.75555400000013],[-101.41416899999996,75.75248700000003],[-101.301941,75.74609400000008],[-101.254997,75.74470500000007],[-101.24416400000001,75.74693300000001],[-101.23388699999998,75.75138900000013],[-101.20249899999993,75.76721199999997],[-101.18221999999997,75.77970900000014],[-101.23110999999994,75.77720599999998],[-101.328056,75.77442900000005],[-101.34777799999995,75.7749940000001],[-101.35555999999991,75.77943399999992],[-101.358612,75.78498800000011],[-101.35193599999991,75.79054300000001],[-101.34137699999997,75.79609700000003],[-101.326683,75.80165099999999],[-101.323624,75.80748000000006],[-101.32501200000002,75.81330900000006],[-101.33500700000002,75.8252720000001],[-101.34056099999992,75.83027600000003],[-101.35637700000001,75.84304800000007],[-101.36389199999996,75.8477630000001],[-101.37805199999997,75.85192899999998],[-101.39277600000003,75.85443100000003],[-101.40833999999995,75.85582000000005],[-101.42388900000003,75.85636900000003],[-101.48889199999996,75.85415600000005],[-101.52694699999995,75.85832199999993],[-101.537216,75.86137400000007],[-101.54638699999992,75.86747700000001],[-101.57917799999996,75.90860000000009],[-101.56500199999988,75.92970300000002],[-101.49665800000002,75.95498700000002],[-101.47778299999999,75.96026599999999],[-101.45221700000002,75.96360800000008],[-101.39417299999997,75.97554000000008],[-101.30915800000002,76.008331],[-101.30277999999987,76.01304600000003],[-101.31582599999996,76.01915000000002],[-101.33556399999992,76.020828],[-101.36971999999992,76.0169370000001],[-101.38249200000001,76.01081800000009],[-101.39195299999989,76.00054900000003],[-101.40833999999995,75.99552900000015],[-101.61721799999998,75.98082000000011],[-101.641953,75.97970599999996],[-101.67832900000002,75.97970599999996],[-101.68388399999998,75.98027000000008],[-101.728882,75.9874880000001],[-101.80638099999999,76.00749200000001],[-101.83249699999999,76.016663],[-101.84889199999992,76.02470400000004],[-101.89362299999993,76.06025700000009],[-101.90055799999999,76.06666600000011],[-101.90722700000003,76.07859800000006],[-101.90862299999998,76.08442700000006],[-101.90750099999997,76.09610000000009],[-101.902222,76.10775799999993],[-101.88861099999991,76.11914100000013],[-101.761124,76.17414899999994],[-101.71140300000002,76.184708],[-101.685272,76.18775900000003],[-101.60833699999995,76.19442700000002],[-101.53362299999998,76.20526100000006],[-101.48860200000001,76.21360800000002],[-101.46556099999998,76.21887200000003],[-101.39611799999989,76.24331700000005],[-101.38500999999997,76.24887100000007],[-101.387787,76.251938],[-101.44193999999993,76.24165300000004],[-101.49694799999992,76.23387100000008],[-101.69888299999997,76.21943700000008],[-101.74973299999999,76.21582000000012],[-101.77471899999995,76.21554600000002],[-102.051941,76.21360800000002],[-102.11444099999994,76.21554600000002],[-102.1330569999999,76.219986],[-102.14835399999998,76.226654],[-102.16583300000002,76.23831200000001],[-102.15972899999997,76.24304200000006],[-102.133621,76.24636800000007],[-102.08222999999998,76.25082400000002],[-102.06388899999996,76.25526400000001],[-102.05803700000001,76.25915500000008],[-102.001106,76.35276800000003],[-102.029449,76.3808140000001],[-102.051941,76.38638300000008],[-102.05332900000002,76.39221199999992],[-102.05082700000003,76.39804100000015],[-102.03999299999998,76.40359500000011],[-102.01862299999999,76.40942399999994],[-101.88583399999993,76.444977],[-101.86221299999994,76.45027200000004],[-101.80832699999996,76.45416300000011],[-101.78333299999991,76.45443700000004],[-101.671112,76.449142],[-101.45667300000002,76.43637100000007],[-101.43472300000002,76.43441800000011],[-101.41166699999997,76.43081700000005],[-101.31582599999996,76.41442899999998],[-101.30249000000003,76.40832499999999],[-101.29138199999994,76.401657],[-101.28362300000003,76.39610299999998],[-101.27667200000002,76.38943500000005],[-101.24027999999993,76.371643],[-101.22805800000003,76.36692800000014],[-101.20612299999993,76.36137400000013],[-101.13694799999996,76.35081500000007],[-101.06806899999998,76.33194000000015],[-101.05832700000002,76.3269350000001],[-101.09388699999994,76.283051],[-101.00446299999993,76.23776199999998],[-100.98111,76.2352600000001],[-100.92832899999996,76.22581500000001],[-100.91000399999996,76.22221399999995],[-100.86582900000002,76.21220400000004],[-100.783073,76.19108599999998],[-100.75110599999994,76.18220500000001],[-100.71056399999998,76.166382],[-100.63027999999991,76.13333100000006],[-100.43998699999992,76.105255],[-100.31582600000002,76.05137600000012],[-100.30943299999996,76.04803500000008],[-100.13166799999993,75.95248400000003],[-100.047234,75.91387900000007],[-99.98249800000002,75.89054899999991],[-99.88833599999998,75.88638300000002],[-99.75361599999991,75.90637200000015],[-99.73083499999996,75.91053800000003],[-99.71556099999998,75.91609200000005],[-99.67832899999996,75.93136600000014],[-99.587784,75.94999700000011],[-99.508621,75.95748900000007],[-99.48361199999994,75.95860300000004],[-99.45750399999997,75.96138000000013],[-99.44249000000002,75.96581999999995],[-99.439438,75.97053499999998],[-99.45461999999992,75.97480800000005],[-99.49444599999998,75.97360200000008],[-99.65777600000001,75.96138000000013],[-99.78527799999995,75.95138500000002],[-99.81111099999998,75.94831799999992],[-99.85943600000002,75.93525699999998],[-99.86332699999997,75.93553200000002],[-99.89862099999999,75.95027199999998],[-100.07749899999999,76.03887900000012],[-100.08249699999999,76.04386900000003],[-100.09221600000001,76.05497700000001],[-100.14222699999999,76.11219800000015],[-100.15278599999994,76.13247700000011],[-100.12499999999994,76.14888000000013],[-100.10388199999994,76.15332000000001],[-100.07167099999998,76.15582299999994],[-100.031113,76.15554800000012],[-100.01139799999999,76.15387000000004],[-99.86833200000001,76.13998400000003],[-99.73083499999996,76.11747700000012],[-99.68083200000001,76.1185910000001],[-99.65083299999998,76.12747200000007],[-99.60916099999997,76.13581799999997],[-99.556107,76.14166300000005],[-99.50222799999995,76.14610300000004],[-99.4830629999999,76.14694200000002],[-99.42971799999992,76.15387000000004],[-99.414444,76.15832500000005],[-99.42138699999992,76.16026299999999],[-99.445267,76.16137700000013],[-99.49888599999991,76.15776100000011],[-99.54888899999997,76.15332000000001],[-99.66805999999991,76.13970900000004],[-99.69305400000002,76.13859600000012],[-99.716949,76.13970900000004],[-99.87443499999989,76.17053199999998],[-99.91583300000002,76.18026700000007],[-99.94888299999997,76.18969700000014],[-100.15028399999994,76.1933140000001],[-100.17832900000002,76.19081100000011],[-100.20140099999998,76.18997200000001],[-100.22556299999997,76.19081100000011],[-100.43888900000002,76.21249400000005],[-100.47222899999991,76.22637899999995],[-100.49861099999998,76.23776199999998],[-100.51278699999989,76.24914600000005],[-100.514183,76.25416600000011],[-100.51112399999994,76.25972000000013],[-100.49944299999999,76.26527400000009],[-100.465012,76.27499399999999],[-100.43804899999998,76.2788700000001],[-100.41665599999999,76.28027299999997],[-100.36638600000003,76.28166199999998],[-100.26917300000002,76.27859500000005],[-100.18276999999995,76.27082800000011],[-100.111107,76.26638800000006],[-99.89555399999995,76.27470399999999],[-99.86999499999996,76.27581799999996],[-99.84472700000003,76.28027299999997],[-99.84861799999993,76.28387499999997],[-100.03859699999998,76.3188780000001],[-100.27722199999994,76.37858599999998],[-100.30166600000001,76.38275099999998],[-100.32362399999994,76.38415500000013],[-100.35056299999991,76.38443000000001],[-100.37444299999999,76.38275099999998],[-100.48137700000001,76.37387100000012],[-100.55332899999996,76.37109400000003],[-100.67360699999995,76.371918],[-100.69444299999998,76.3749850000001],[-100.95249899999999,76.47470099999998],[-100.97222899999997,76.48526000000004],[-100.98388699999992,76.49443099999996],[-100.98554999999993,76.499146],[-100.98249800000002,76.50499000000002],[-100.962784,76.510269],[-100.93943799999988,76.5144350000001],[-100.89277600000003,76.51944000000015],[-100.82972699999999,76.51971400000008],[-100.80526700000001,76.52221700000007],[-100.737213,76.5310970000001],[-100.72083999999995,76.54609700000003],[-100.72341899999998,76.55109400000015],[-100.72332799999992,76.55609100000004],[-100.71250899999995,76.56053199999997],[-100.65306099999992,76.57638500000002],[-100.45861799999994,76.61360200000001],[-100.383827,76.6275020000001],[-100.36389200000002,76.63108799999998],[-100.318893,76.6355440000001],[-100.21665999999988,76.64305100000001],[-100.19193999999999,76.64221200000009],[-100.05222300000003,76.63136300000002],[-99.981674,76.62220799999994],[-99.91111799999999,76.61303700000002],[-99.88500999999991,76.61053500000014],[-99.83778399999989,76.60859699999997],[-99.81138599999991,76.60971099999995],[-99.796112,76.61387599999995],[-99.79527299999995,76.61831700000005],[-99.770554,76.62776200000013],[-99.74194299999999,76.6327510000001],[-99.72582999999992,76.63472000000013],[-99.68443300000001,76.63333100000011],[-99.58833300000003,76.62387100000007],[-99.569458,76.62052900000015],[-99.36694299999994,76.52638200000007],[-99.25695799999994,76.4705350000001],[-99.260559,76.46470600000009],[-99.25527999999991,76.45359800000006],[-99.18443300000001,76.41581700000012],[-99.16361999999992,76.40914900000013],[-99.12332200000003,76.40081800000002],[-99.09999099999999,76.39804100000015],[-99.07972699999999,76.39721700000001],[-99.066101,76.39860500000009],[-99.06639100000001,76.4044340000001],[-99.08361799999994,76.4160920000001],[-99.11000100000001,76.42665099999999],[-99.11833200000001,76.43304400000011],[-99.13722199999995,76.45193499999999],[-99.133896,76.45665000000002],[-99.12249800000001,76.46110500000003],[-98.99415599999998,76.47109999999992],[-98.98083499999996,76.47164900000007],[-98.95527600000003,76.46914700000002],[-98.94694500000003,76.46304299999997],[-98.94804399999992,76.45277399999992],[-98.95028699999989,76.44636500000007],[-98.943604,76.44081100000005],[-98.92582700000003,76.43609600000002],[-98.90638699999988,76.43331899999998],[-98.882767,76.43136600000003],[-98.85777300000001,76.43136600000003],[-98.846115,76.43609600000002],[-98.85611,76.46388200000013],[-98.86527999999993,76.46914700000002],[-98.89862099999999,76.48109399999993],[-98.953888,76.499146],[-99.03805499999999,76.52970899999997],[-99.05055199999998,76.53610200000014],[-99.051941,76.53997800000002],[-99.02722199999994,76.60108899999994],[-98.99916099999996,76.60498000000001],[-98.97166399999998,76.60775800000005],[-98.86082499999992,76.61442599999998],[-98.71472199999994,76.61415099999999],[-98.61111499999998,76.6102600000001],[-98.58917200000002,76.61137400000007],[-98.56639100000001,76.61360200000001],[-98.53889499999997,76.61637900000011],[-98.51806599999998,76.62136800000007],[-98.511124,76.62525900000014],[-98.489731,76.6447070000001],[-98.48832699999997,76.65081800000002],[-98.54695100000004,76.6580350000001],[-98.5911099999999,76.66165200000006],[-98.59500099999997,76.65942400000012],[-98.59249899999998,76.6538700000001],[-98.59861799999999,76.651093],[-98.62304699999987,76.64721700000013],[-98.67443800000001,76.64387499999998],[-98.74444599999998,76.64387499999998],[-98.81416300000001,76.65359500000005],[-98.85110500000002,76.66165200000006],[-98.85777300000001,76.66387900000012],[-98.85583499999996,76.67025799999999],[-98.85249299999992,76.67164600000007],[-98.82139599999994,76.67692599999992],[-98.733612,76.68275499999999],[-98.71250900000001,76.68304400000005],[-98.50472999999994,76.68109099999992],[-98.48028599999992,76.67915299999999],[-98.43998699999997,76.67303500000008],[-98.41805999999991,76.66832000000005]],[[-99.99694799999997,76.734421],[-99.97639500000002,76.73359700000003],[-99.86999499999996,76.73637400000013],[-99.81945799999988,76.73831200000006],[-99.74833699999999,76.74275200000011],[-99.72083999999995,76.74581900000004],[-99.69387799999998,76.74775699999998],[-99.64639299999999,76.74803199999997],[-99.62249800000001,76.7452550000001],[-99.52888499999995,76.72554000000008],[-99.447769,76.7061000000001],[-99.43055699999996,76.69941699999993],[-99.43388399999998,76.69470200000012],[-99.52806099999998,76.67442299999999],[-99.556107,76.6705320000001],[-99.58168,76.67025799999999],[-99.626938,76.67303500000008],[-99.65777600000001,76.67776500000008],[-99.73332199999999,76.70248400000003],[-99.8883899999999,76.71865100000014],[-99.90022299999993,76.72015399999998],[-99.91555799999998,76.72015399999998],[-100.01112399999988,76.71914700000013],[-100.02999899999992,76.71582000000001],[-100.05139200000002,76.71554600000007],[-100.09750400000001,76.71720900000003],[-100.12138399999998,76.71971100000007],[-100.128601,76.72192400000006],[-100.12805199999997,76.72303800000003],[-100.10193599999997,76.74470500000007],[-100.08277899999996,76.74803199999997],[-100.05526700000001,76.75082400000008],[-100.03778099999988,76.75138900000013],[-99.99943499999995,76.75109900000007],[-99.97222899999991,76.747208],[-99.97500600000001,76.74247700000006],[-99.99415599999998,76.73915100000005],[-100.004997,76.73553500000003],[-99.99694799999997,76.734421]],[[-120.883621,76.73970000000003],[-120.886124,76.72859199999999],[-120.90334299999995,76.72387699999996],[-120.94499199999996,76.71775800000012],[-120.97000100000002,76.71666000000005],[-121.0908429999999,76.71887200000009],[-121.11749299999991,76.71971100000007],[-121.16000400000001,76.72331200000013],[-121.18110699999994,76.72720300000003],[-121.1847229999999,76.7310940000001],[-121.181671,76.73220800000007],[-121.15666199999998,76.73359700000003],[-121.12832600000002,76.73082],[-121.083618,76.72915599999993],[-121.05972300000002,76.73136900000009],[-121.05638099999999,76.73248300000006],[-121.01806599999998,76.75138900000013],[-120.99082900000002,76.75471500000015],[-120.97833300000002,76.75526400000007],[-120.91443599999997,76.754166],[-120.89083900000003,76.7497100000001],[-120.88474300000001,76.74552900000003],[-120.883621,76.73970000000003]],[[-101.38054699999992,76.55358899999999],[-101.40416699999997,76.55276500000002],[-101.45388799999989,76.5541530000001],[-101.54083300000002,76.56080600000007],[-101.56471299999993,76.56359900000007],[-101.62332199999992,76.57276899999994],[-101.68831599999999,76.58638000000008],[-101.57556199999999,76.61415099999999],[-101.52194199999991,76.62387100000007],[-101.38583399999993,76.64248700000007],[-101.31777999999991,76.64276100000001],[-101.21362299999993,76.65193199999999],[-101.05999800000001,76.68580599999996],[-101.04250300000001,76.69053600000001],[-101.03943600000002,76.69636500000001],[-101.04028299999993,76.70220900000004],[-101.03307299999994,76.70803800000004],[-101.00583599999993,76.71887200000009],[-100.983612,76.72470099999992],[-100.95749699999999,76.72915599999993],[-100.90249599999993,76.73637400000013],[-100.74388099999999,76.75332600000013],[-100.69193999999999,76.75471500000015],[-100.53443900000002,76.75721700000003],[-100.50917099999992,76.7563780000001],[-100.484734,76.75471500000015],[-100.26888999999989,76.73719800000009],[-100.248894,76.73471100000006],[-100.25917099999998,76.72859199999999],[-100.266663,76.72637900000007],[-100.29305999999997,76.72192400000006],[-100.297234,76.72192400000006],[-100.31723,76.71666000000005],[-100.48721299999988,76.68441800000005],[-100.761124,76.63581800000003],[-100.92304999999999,76.6102600000001],[-101.19275699999997,76.57138100000003],[-101.27390300000002,76.56080600000007],[-101.326683,76.55636600000008],[-101.38054699999992,76.55358899999999]],[[-89.93443299999996,76.47665400000011],[-89.978882,76.46971100000013],[-89.99972500000001,76.470261],[-90.04083300000002,76.47692899999993],[-90.08168,76.484985],[-90.15110800000002,76.50443999999999],[-90.18443300000001,76.51527400000003],[-90.21444699999995,76.528595],[-90.22666900000002,76.53553800000003],[-90.412216,76.63610800000004],[-90.47805800000003,76.66220099999998],[-90.504456,76.67526199999992],[-90.56361400000003,76.709991],[-90.57333399999999,76.71582000000001],[-90.59445199999999,76.72970599999996],[-90.60028099999994,76.734985],[-90.60082999999997,76.74108899999999],[-90.59999099999999,76.746643],[-90.59777799999995,76.75000000000011],[-90.58666999999997,76.76138300000014],[-90.57917800000001,76.7669370000001],[-90.57028200000002,76.771927],[-90.54444899999999,76.78305100000006],[-90.51028400000001,76.79332000000011],[-90.474716,76.79971300000005],[-90.23055999999997,76.82804899999996],[-90.10305800000003,76.83610500000003],[-90.025284,76.83915699999994],[-89.98306300000002,76.836929],[-89.92777999999998,76.8288730000001],[-89.86527999999998,76.8160860000001],[-89.82583599999998,76.80609100000004],[-89.77944899999989,76.7852630000001],[-89.67388899999997,76.73748799999993],[-89.67388899999997,76.73136900000009],[-89.68777499999999,76.70887800000008],[-89.702225,76.68969700000002],[-89.729446,76.67330900000002],[-89.74415599999998,76.66943400000002],[-89.76806599999998,76.668045],[-89.81973299999993,76.66720600000002],[-89.83721899999989,76.66304000000014],[-89.84083599999991,76.65721100000013],[-89.86277799999999,76.60386699999998],[-89.86250299999995,76.59748800000011],[-89.85833699999995,76.59109499999994],[-89.81750499999998,76.54693600000002],[-89.79444899999993,76.53332500000005],[-89.75611900000001,76.52470399999993],[-89.72166399999998,76.51971400000008],[-89.69915799999995,76.51693699999998],[-89.68443300000001,76.51165800000001],[-89.67138699999998,76.50416600000005],[-89.67388899999997,76.50221299999993],[-89.75750700000003,76.48609900000002],[-89.78361499999988,76.48304700000006],[-89.93443299999996,76.47665400000011]],[[-108.65110800000002,76.81359900000001],[-108.65110800000002,76.80886800000007],[-108.65527299999991,76.80386399999998],[-108.67804699999999,76.78498800000011],[-108.68443299999996,76.78054800000007],[-108.69055200000003,76.77442900000005],[-108.69249000000002,76.76998900000007],[-108.68831599999999,76.766098],[-108.67971799999992,76.76332100000008],[-108.66278099999994,76.76138300000014],[-108.596947,76.76081800000009],[-108.55248999999992,76.76138300000014],[-108.527222,76.76026899999994],[-108.50389099999995,76.75610399999994],[-108.48889199999996,76.75166300000006],[-108.46333299999998,76.73915100000005],[-108.45500199999998,76.73332200000004],[-108.44638099999997,76.72360200000014],[-108.44220699999994,76.71775800000012],[-108.43804899999998,76.70803800000004],[-108.44193999999999,76.69636500000001],[-108.45889299999988,76.68470800000006],[-108.54472399999997,76.64637800000014],[-108.56555200000003,76.64166300000011],[-108.58667000000003,76.64166300000011],[-108.60749800000002,76.64248700000007],[-108.628601,76.645264],[-108.65387699999997,76.64721700000013],[-108.68110699999994,76.64776600000005],[-108.70417799999996,76.64637800000014],[-108.72083999999995,76.64248700000007],[-108.72721899999999,76.63804600000014],[-108.72693600000002,76.63415500000008],[-108.69915800000001,76.60554500000006],[-108.69055200000003,76.60054000000002],[-108.62721299999998,76.57554600000003],[-108.61054999999993,76.56971700000003],[-108.58389299999993,76.47747800000008],[-108.58112299999999,76.43914799999999],[-108.55803699999996,76.40859999999998],[-108.475281,76.40693700000008],[-108.36389200000002,76.39999400000005],[-108.328888,76.39665200000013],[-108.31861900000001,76.39415000000008],[-108.28971899999993,76.38443000000001],[-108.26917300000002,76.3749850000001],[-108.07749899999999,76.28054800000001],[-108.11472299999997,76.26138300000002],[-108.252228,76.19692999999995],[-108.33139,76.18193100000008],[-108.38027999999997,76.16526800000003],[-108.39222699999993,76.159424],[-108.40862300000003,76.14776599999999],[-108.396118,76.04609700000015],[-108.35193600000002,76.04887400000007],[-108.02555799999999,76.06219500000003],[-108.00140399999998,76.06303399999996],[-107.916946,76.06303399999996],[-107.83833300000003,76.06137100000007],[-107.81221,76.05609099999998],[-107.73665599999998,76.03942899999998],[-107.72471599999994,76.03553800000009],[-107.63834399999996,75.99636800000013],[-107.63249200000001,75.99108899999999],[-107.63305699999995,75.98136900000009],[-107.639183,75.976089],[-107.65139799999997,75.97026100000005],[-107.785553,75.91998300000012],[-107.84221599999995,75.89999399999999],[-107.901947,75.8961030000001],[-107.91805999999997,75.8913730000001],[-107.93028300000003,75.88554400000004],[-108.031113,75.822495],[-108.04361,75.80219999999997],[-108.02417000000003,75.78387500000002],[-108.02027900000002,75.78082300000011],[-108.00639299999995,75.77943399999992],[-107.9569469999999,75.78471400000001],[-107.91332999999986,75.78942900000004],[-107.87361099999993,75.79803500000014],[-107.82084699999996,75.829163],[-107.778343,75.85470600000008],[-107.75974299999996,75.86970500000012],[-107.75974299999996,75.87441999999999],[-107.739441,75.87915000000004],[-107.51555599999995,75.89999399999999],[-107.36945299999996,75.911652],[-107.33750899999995,75.91137700000002],[-107.18666099999996,75.90387000000004],[-107.08000199999998,75.89276100000001],[-107.08583099999998,75.87248200000005],[-107.09028599999994,75.86747700000001],[-107.10500300000001,75.83471700000013],[-107.098053,75.82304399999992],[-107.03167699999995,75.77110300000004],[-106.96362299999993,75.73858600000005],[-106.89666699999998,75.72026100000011],[-106.88027999999991,75.76582299999995],[-106.83056599999998,75.78581200000008],[-106.79444899999993,75.7916560000001],[-106.74471999999992,75.79553199999998],[-106.72277799999995,75.79582199999999],[-106.67944299999999,75.79359400000004],[-106.6558379999999,75.79359400000004],[-106.636124,75.79443400000008],[-106.61582899999996,75.797211],[-106.62110899999993,75.80331400000011],[-106.6383439999999,75.80693100000008],[-106.67944299999999,75.8124850000001],[-106.72666900000002,75.813873],[-106.78611799999993,75.81330900000006],[-106.829453,75.816666],[-106.85082999999992,75.81999200000001],[-106.87000299999994,75.82499700000005],[-106.88890100000003,75.83471700000013],[-106.89584400000001,75.84443700000003],[-106.89666699999998,75.93525699999998],[-106.89611799999994,75.94108600000004],[-106.89334100000002,75.94747899999999],[-106.86971999999997,75.96415700000006],[-106.63890099999998,76.05304000000012],[-106.60610999999994,76.05775499999999],[-106.58583099999993,76.05859399999997],[-106.368607,76.05581700000005],[-106.33667000000003,76.05470300000007],[-106.30082699999997,76.05137600000012],[-106.01611299999996,76.01971400000002],[-105.93721,76.01026900000011],[-105.89998600000001,76.00555400000007],[-105.837219,75.99693299999996],[-105.73500100000001,75.9749910000001],[-105.66832699999998,75.95555100000013],[-105.61945299999996,75.93942300000009],[-105.60637699999995,75.93470800000006],[-105.59528399999988,75.92970300000002],[-105.47888199999994,75.86303699999996],[-105.46528599999999,75.85192899999998],[-105.45333900000003,75.84165999999993],[-105.445831,75.83055100000007],[-105.40028399999989,75.69442700000008],[-105.38834399999996,75.65637200000003],[-105.391953,75.63888500000013],[-105.48750299999995,75.56080600000013],[-105.49638399999998,75.55525200000011],[-105.51666299999994,75.55053700000008],[-105.54083300000002,75.54693600000002],[-105.60444599999988,75.53997800000002],[-105.63667299999997,75.53360000000009],[-105.68582200000003,75.51944000000015],[-105.74082900000002,75.49497999999994],[-105.75140399999998,75.48970000000008],[-105.74804699999999,75.48580900000002],[-105.73693799999995,75.48275799999999],[-105.68666100000002,75.48304700000011],[-105.67166099999986,75.48109399999998],[-105.61138900000003,75.47164900000007],[-105.59277299999997,75.46748400000007],[-105.593613,75.46276900000004],[-105.64639299999993,75.36526500000002],[-105.65110799999997,75.35942100000005],[-105.66055299999994,75.34971600000011],[-105.72666900000002,75.31303400000013],[-105.7386019999999,75.30941800000005],[-105.76251199999996,75.30497699999995],[-105.79361,75.30220000000008],[-105.81304899999998,75.29942299999999],[-105.82140399999992,75.2958220000001],[-105.86694299999999,75.27581800000002],[-105.87526699999995,75.27110299999998],[-105.9377669999999,75.21443200000004],[-105.93888900000002,75.20860300000004],[-105.93582199999997,75.20277400000003],[-105.929169,75.19775400000015],[-105.89222699999999,75.190811],[-105.87249800000001,75.171921],[-105.876938,75.14582800000005],[-105.88527699999997,75.14027400000009],[-105.90499899999998,75.13638300000002],[-105.92582699999997,75.135269],[-106.00361599999991,75.13554400000004],[-106.01889,75.13388100000009],[-106.07028200000002,75.10664400000002],[-106.07945299999989,75.09693900000008],[-106.07333399999993,75.08720399999999],[-106.01862299999999,75.07415800000007],[-106.00446299999999,75.06805400000002],[-105.99416399999996,75.06219500000003],[-105.99333199999995,75.05581700000005],[-106.011124,75.05081200000001],[-106.23528299999998,75.02137800000003],[-106.26000999999997,75.01915000000008],[-106.45500199999992,75.00582900000012],[-106.54554699999989,75.00166300000001],[-106.564438,75.00082400000008],[-106.66332999999992,75.004166],[-106.72556299999997,75.00221300000004],[-106.77111799999989,74.996643],[-106.78639199999998,74.99192800000014],[-106.78307299999994,74.98997500000002],[-106.78333299999997,74.98609899999997],[-106.78582799999992,74.98054500000012],[-106.79194599999994,74.97526600000015],[-106.807503,74.96971100000007],[-106.93055699999996,74.93359400000008],[-106.97222899999997,74.92608600000005],[-107.01000999999991,74.922485],[-107.05110200000001,74.92164600000007],[-107.07362399999994,74.91998300000012],[-107.16000399999996,74.91053800000009],[-107.19722000000002,74.91081200000002],[-107.215843,74.911926],[-107.46417199999996,74.93441800000005],[-107.506958,74.93997200000007],[-107.630829,74.96110499999998],[-107.66251399999999,74.96666000000005],[-107.68804899999998,74.97637900000007],[-107.69554099999999,74.98220800000007],[-107.72389199999998,75.016388],[-107.72389199999998,75.02026400000005],[-107.71972699999998,75.02609300000006],[-107.704453,75.03082300000011],[-107.68138099999999,75.04248000000001],[-107.67944299999994,75.04859900000008],[-107.68110699999994,75.05304000000001],[-107.69499199999996,75.07527200000004],[-107.70584100000002,75.08610500000003],[-107.716949,75.09082000000006],[-107.739441,75.0958250000001],[-107.75834700000001,75.09693900000008],[-107.77333099999998,75.09609999999992],[-107.78307299999994,75.09359699999999],[-107.77999899999998,75.07222000000013],[-107.77084400000001,75.06581100000011],[-107.75778200000002,75.06053199999991],[-107.74500299999994,75.05415300000004],[-107.739441,75.04887400000007],[-107.73972299999997,75.04304500000006],[-107.74388099999993,75.03720100000004],[-107.77778599999999,75.0294340000001],[-107.89499699999999,75.003601],[-107.94193999999999,74.93081699999999],[-107.95527600000003,74.92858900000004],[-107.97749299999998,74.92747500000007],[-108.02417000000003,74.92915299999999],[-108.13417099999992,74.92776500000008],[-108.21083099999987,74.92359900000002],[-108.37304699999999,74.91053800000009],[-108.3916779999999,74.91137700000002],[-108.436394,74.91526800000008],[-108.45500199999998,74.91832],[-108.52971599999995,74.936646],[-108.54110700000001,74.94053600000001],[-108.548607,74.94636500000001],[-108.547958,74.95165300000002],[-108.55055199999998,74.9563750000001],[-108.55999800000001,74.96081500000014],[-108.67971799999992,74.97026100000011],[-108.781113,74.97998000000007],[-108.80721999999997,74.98359700000003],[-108.80721999999997,74.984711],[-108.796112,74.98580900000013],[-108.74553699999996,74.984421],[-108.63890100000003,74.9810940000001],[-108.614441,74.97970599999996],[-108.55999800000001,74.97637900000007],[-108.53028899999993,74.97331200000013],[-108.51139799999999,74.97554000000008],[-108.52667199999996,75.00166300000001],[-108.53056300000003,75.00555400000007],[-108.53806299999985,75.00943000000001],[-108.628601,75.04609699999997],[-108.65139799999992,75.05386399999998],[-108.79472399999997,75.06915300000003],[-108.83249699999993,75.06999200000001],[-108.92777999999993,75.05192599999998],[-108.94972200000001,75.04026799999997],[-109.001106,75.00499000000013],[-109.11971999999997,74.97943099999998],[-109.34584000000001,74.94470200000006],[-109.36416600000001,74.93969700000002],[-109.39998600000001,74.91832],[-109.40722700000003,74.91249099999999],[-109.40695199999993,74.90859999999992],[-109.420547,74.89305100000001],[-109.50805700000001,74.86637900000011],[-109.52278099999995,74.86331200000001],[-109.56861900000001,74.85775800000005],[-109.58721899999995,74.85664400000002],[-109.66139199999992,74.85636900000003],[-109.76944700000001,74.85942100000011],[-109.79750099999995,74.86360200000001],[-109.81111099999993,74.86804200000006],[-109.83361799999994,74.86970499999995],[-109.87249800000001,74.86914100000001],[-109.93472300000002,74.86080900000002],[-109.95500199999987,74.85720800000001],[-109.99471999999997,74.84832799999998],[-110.01640299999991,74.84220900000008],[-110.13971700000002,74.83305400000006],[-110.30444299999994,74.84637500000002],[-110.32501200000002,74.84748800000011],[-110.34555099999989,74.84693900000013],[-110.36000100000001,74.84387200000003],[-110.37053700000001,74.83998099999997],[-110.40416699999997,74.82666],[-110.39620999999994,74.81368999999995],[-110.39666699999998,74.7994230000001],[-110.43666100000002,74.79331999999994],[-110.58999599999993,74.77804600000007],[-110.59137699999997,74.72415200000006],[-110.75666799999993,74.68525700000009],[-110.77250699999996,74.68081700000005],[-110.78639199999998,74.67469800000003],[-110.79638699999998,74.66886900000003],[-110.807503,74.657486],[-110.83389299999993,74.65193199999999],[-110.98111,74.62136800000013],[-111.28056300000003,74.56776400000012],[-111.38722200000001,74.56303400000007],[-111.409157,74.56275900000009],[-111.43055699999996,74.56053200000002],[-111.55888399999998,74.52748100000008],[-111.64250199999992,74.50138900000002],[-111.67722300000003,74.49331700000005],[-111.700287,74.49136400000009],[-111.82389799999999,74.48332199999993],[-111.94554099999993,74.474426],[-111.98416099999997,74.46887200000003],[-112.087219,74.45220899999993],[-112.29305999999991,74.42776500000002],[-112.37053699999996,74.41859400000004],[-112.43831599999999,74.41442900000004],[-112.54194599999988,74.409424],[-112.75306699999993,74.40138200000001],[-112.85694899999993,74.39833099999998],[-112.91999799999991,74.39749099999995],[-113.00890400000003,74.39804099999998],[-113.25723299999993,74.40525800000012],[-113.406113,74.41331500000007],[-113.42832899999996,74.41470300000015],[-113.47168699999997,74.41891499999997],[-113.64083900000003,74.4374850000001],[-113.69638099999997,74.44609100000002],[-113.84221600000001,74.47970600000008],[-113.94167299999998,74.50360100000006],[-114.053879,74.530823],[-114.12110899999993,74.54998799999998],[-114.29834,74.60276800000003],[-114.34861799999999,74.61886600000008],[-114.37470999999994,74.6291500000001],[-114.39695699999993,74.63916],[-114.43804899999986,74.65942400000012],[-114.44360399999994,74.664154],[-114.44776899999994,74.67469800000003],[-114.42859599999991,74.69192500000003],[-114.41972399999992,74.69802900000008],[-114.40750099999997,74.70416300000011],[-114.39444700000001,74.70832800000011],[-114.21444699999995,74.75555400000013],[-114.10166899999996,74.77665700000006],[-114.01027699999992,74.79054300000007],[-113.73166699999996,74.82720899999998],[-113.71000699999996,74.82971199999992],[-113.55695300000002,74.839157],[-113.41861,74.84275800000006],[-113.28278399999999,74.84860200000008],[-113.25334199999998,74.87359600000002],[-113.22269399999988,74.89646900000002],[-113.15194699999995,74.92498799999998],[-113.1205369999999,74.93248000000011],[-113.00750699999992,74.95416300000005],[-112.91111799999987,74.97082500000005],[-112.86749299999997,74.97554000000008],[-112.84528399999994,74.9769290000001],[-112.57224299999996,74.99275200000011],[-112.52416999999991,74.99552900000003],[-112.5,74.99601000000001],[-112.453056,74.99693300000001],[-112.37444299999993,74.99832199999997],[-112.01500699999991,75.00248699999997],[-111.962219,75.00138900000007],[-111.935272,74.99887100000012],[-111.89890299999996,74.99498000000006],[-111.86527999999993,74.98831200000006],[-111.84056099999998,74.98637400000013],[-111.76444999999995,74.98165900000009],[-111.75334199999998,74.98165900000009],[-111.718613,74.986649],[-111.62666300000001,75.00387599999999],[-111.589722,75.00637800000004],[-111.55139200000002,75.01138300000014],[-111.535278,75.01499899999999],[-111.28971899999999,75.08610500000003],[-111.02916700000003,75.17109700000003],[-110.920547,75.22360200000008],[-110.91361999999998,75.22859199999994],[-110.91278099999994,75.23387100000014],[-110.91750300000001,75.23969999999997],[-111.05249000000003,75.270264],[-111.06806899999987,75.27192700000012],[-111.23082699999998,75.26415999999995],[-111.248894,75.25915500000008],[-111.25195300000001,75.25416599999994],[-111.25083899999993,75.24859600000008],[-111.25167799999997,75.24304200000006],[-111.25611900000001,75.23664900000011],[-111.26112399999994,75.23220800000001],[-111.27778599999994,75.22053499999998],[-111.33416699999992,75.19747899999993],[-111.39167800000001,75.1810910000001],[-111.47501399999999,75.161652],[-111.56082200000003,75.1461030000001],[-111.57721700000002,75.1436000000001],[-111.59612299999998,75.143326],[-111.69526699999989,75.14582800000005],[-111.70584100000002,75.15109300000012],[-111.787216,75.16665599999993],[-111.958054,75.13499500000006],[-112.22833300000002,75.12469499999997],[-112.39055599999995,75.12303200000002],[-112.40972899999997,75.12359600000002],[-112.42916899999994,75.12525900000009],[-112.439438,75.12858600000004],[-112.44833399999999,75.13304100000005],[-112.47084000000001,75.14637800000008],[-112.46833800000002,75.15138200000007],[-112.46166999999997,75.15443399999998],[-112.45249899999999,75.155823],[-112.41197199999993,75.15901200000008],[-112.36860699999994,75.16914400000013],[-112.358337,75.17303500000003],[-112.29472399999992,75.19802899999996],[-112.295837,75.20277400000003],[-112.339447,75.22360200000008],[-112.39750700000002,75.2410890000001],[-112.40888999999993,75.24081400000011],[-112.4366609999999,75.23054500000006],[-112.46193700000003,75.21887200000003],[-112.46417200000002,75.21304300000003],[-112.46305799999999,75.208328],[-112.45056199999999,75.20471199999997],[-112.43749999999994,75.19886800000012],[-112.43221999999997,75.19331399999993],[-112.43250299999994,75.1869200000001],[-112.44471699999997,75.18331900000004],[-112.46665999999999,75.17997700000006],[-112.56111099999993,75.178314],[-112.59249899999998,75.18165600000009],[-112.60888699999992,75.18525699999998],[-112.62554899999998,75.190811],[-112.6347429999999,75.19636500000013],[-112.63722200000001,75.20498700000013],[-112.63694800000002,75.21054100000015],[-112.632767,75.21582000000012],[-112.61609599999997,75.22387700000007],[-112.59472699999998,75.23027000000008],[-112.58583099999998,75.23915099999999],[-112.59472699999998,75.25000000000006],[-112.61277799999999,75.25943000000012],[-112.65167200000002,75.27526900000004],[-112.66583300000002,75.27859500000011],[-112.679169,75.27777100000014],[-112.71305799999999,75.25610400000011],[-112.718887,75.25027500000004],[-112.735817,75.20332300000013],[-112.73416099999992,75.19747899999993],[-112.72888199999994,75.1927490000001],[-112.71584299999995,75.18719500000009],[-112.698036,75.17776500000002],[-112.68859899999995,75.171921],[-112.699997,75.13832100000013],[-112.80695300000002,75.11581400000006],[-112.89417300000002,75.10331700000006],[-112.95667300000002,75.09721400000012],[-113.25446299999999,75.076096],[-113.29888899999997,75.0730440000001],[-113.343887,75.07222000000013],[-113.610817,75.06275900000014],[-113.68083200000001,75.05192599999998],[-113.699432,75.05137599999995],[-113.89417299999997,75.05219999999991],[-113.91750299999995,75.0535890000001],[-113.94138299999986,75.05693100000008],[-113.950287,75.06053199999991],[-113.96888699999994,75.07527200000004],[-113.97305299999994,75.08665500000006],[-113.97305299999994,75.09637499999997],[-113.93138099999999,75.18914800000005],[-113.82055700000001,75.31442300000015],[-113.80583199999995,75.32666000000012],[-113.78278399999999,75.33776899999998],[-113.72805800000003,75.34582500000005],[-113.66055299999994,75.35137900000007],[-113.64222699999993,75.35359199999999],[-113.573624,75.36692800000014],[-113.34056099999992,75.41331500000007],[-113.381104,75.41832000000011],[-113.47112300000003,75.42776499999997],[-113.577789,75.41165200000012],[-113.66027799999995,75.39860500000009],[-113.74445299999996,75.38581800000009],[-113.83389299999988,75.37692300000009],[-113.87138400000003,75.374146],[-113.902222,75.3744200000001],[-113.91139199999998,75.37803600000012],[-113.92111199999994,75.38388100000003],[-113.958618,75.41110200000008],[-113.98166700000002,75.43109100000004],[-113.98416099999992,75.43775899999997],[-113.99221799999998,75.44831800000003],[-114.02416999999997,75.46110500000003],[-114.04083300000002,75.46388200000013],[-114.06500199999988,75.46609500000011],[-114.08389299999999,75.46470600000009],[-114.08693699999998,75.46249400000005],[-114.08917199999996,75.45860299999998],[-114.093887,75.41081200000008],[-114.09166699999992,75.40498400000013],[-114.08583099999993,75.4002690000001],[-114.07778899999988,75.39415000000008],[-114.06610099999995,75.38916000000006],[-114.05638099999987,75.383331],[-114.04472399999992,75.37303200000002],[-114.04055800000003,75.36775200000011],[-114.04055800000003,75.36219800000009],[-114.04750100000001,75.35054000000008],[-114.13751200000002,75.24498],[-114.15805099999994,75.23332199999999],[-114.17083699999989,75.22692900000004],[-114.18666100000002,75.22331200000008],[-114.203056,75.22137500000002],[-114.22277799999995,75.2227630000001],[-114.26363399999991,75.22970599999991],[-114.28472899999997,75.23498500000011],[-114.319458,75.24470500000001],[-114.34638999999993,75.25471500000009],[-114.35082999999997,75.26638800000012],[-114.34916699999985,75.27137800000014],[-114.35109699999992,75.276093],[-114.35888699999992,75.28137199999998],[-114.49999999999994,75.31219499999997],[-114.51278699999995,75.31469700000008],[-114.52806099999992,75.31442300000015],[-114.54276999999996,75.31303400000013],[-114.60973399999995,75.27998400000007],[-114.61527999999993,75.27499400000005],[-114.61138900000003,75.26527399999998],[-114.598343,75.26165800000007],[-114.57972699999999,75.26332100000002],[-114.57250999999997,75.26443499999999],[-114.54666099999997,75.26693700000004],[-114.49638399999998,75.26554899999996],[-114.46806299999997,75.26220700000005],[-114.44304699999986,75.25721699999997],[-114.41278099999994,75.24803199999991],[-114.39723200000003,75.238876],[-114.30249000000003,75.1827550000001],[-114.297234,75.17915299999993],[-114.29472399999997,75.17330900000013],[-114.29804999999999,75.16665599999993],[-114.30860899999993,75.15470900000003],[-114.32112099999995,75.143326],[-114.33528099999995,75.13108799999992],[-114.34944199999995,75.11914099999996],[-114.36749299999985,75.10693400000002],[-114.39499699999993,75.09054600000013],[-114.42971799999987,75.0730440000001],[-114.46640000000002,75.06053199999991],[-114.48332199999987,75.05609099999998],[-114.51889,75.05026199999998],[-114.60082999999997,75.03831500000001],[-114.72416699999997,75.01193200000006],[-114.76342799999998,75.00247200000001],[-114.825287,74.98803700000008],[-114.88861099999991,74.97747800000002],[-114.94915800000001,74.96998600000006],[-115.03222699999992,74.96165500000001],[-115.05082700000003,74.96110499999998],[-115.066101,74.96165500000001],[-115.160553,74.97943099999998],[-115.18582200000003,74.98525999999998],[-115.195267,74.98997500000002],[-115.22609699999992,75.04971300000005],[-115.22638699999993,75.05831899999998],[-115.225281,75.06414799999999],[-115.21861299999995,75.07083100000011],[-115.21167000000003,75.07638500000013],[-115.199432,75.082764],[-115.18331899999993,75.08888200000013],[-115.17415599999993,75.09414700000002],[-115.17304999999999,75.09999099999999],[-115.17278299999992,75.10775799999999],[-115.17832899999996,75.11581400000006],[-115.216949,75.16748000000013],[-115.23554999999993,75.17469800000009],[-115.24861099999998,75.178314],[-115.25695799999994,75.17997700000006],[-115.26083399999993,75.17997700000006],[-115.25611900000001,75.17804000000007],[-115.252228,75.17387400000013],[-115.25361599999991,75.1644290000001],[-115.256393,75.15803500000004],[-115.26139799999999,75.1519320000001],[-115.27916699999997,75.14082300000001],[-115.291382,75.13443000000007],[-115.33640300000002,75.11665299999999],[-115.35305799999998,75.11109900000002],[-115.37304699999999,75.10582000000005],[-115.38694799999996,75.10220300000009],[-115.40416700000003,75.09887700000002],[-115.42666600000001,75.09803800000009],[-115.451683,75.09887700000002],[-115.48361199999994,75.10609399999998],[-115.51944700000001,75.117752],[-115.62389399999995,75.12136800000002],[-115.60472099999993,75.10859700000009],[-115.54888899999997,75.05581700000005],[-115.53971899999993,75.04443400000008],[-115.53751399999993,75.03942900000004],[-115.53751399999993,75.02720599999998],[-115.54527300000001,75.01582300000013],[-115.5516659999999,75.00915500000013],[-115.57472200000001,74.99832199999997],[-115.60249299999998,74.98553499999997],[-115.61833200000001,74.97915599999993],[-115.658051,74.96720899999997],[-115.67194399999988,74.96470600000004],[-115.69055200000003,74.96415700000006],[-115.73500100000001,74.96720899999997],[-115.75723299999999,74.96998600000006],[-115.847778,74.98553499999997],[-116.16306299999991,75.04026799999997],[-116.27916699999997,75.099426],[-116.28639199999992,75.13108799999992],[-116.27694699999995,75.135269],[-116.26889,75.14137300000004],[-116.2455369999999,75.16276600000015],[-116.24109599999997,75.16886900000009],[-116.23860200000001,75.19693000000001],[-116.23916599999995,75.20138500000002],[-116.24694799999992,75.20526100000006],[-116.26834100000002,75.20610000000005],[-116.287216,75.20555100000007],[-116.527222,75.184708],[-116.56054699999999,75.17915299999993],[-116.58084100000002,75.1744230000001],[-116.59388699999994,75.1702580000001],[-116.60249299999998,75.16499300000004],[-116.618607,75.15248100000002],[-116.66332999999997,75.12248199999999],[-116.679169,75.11720300000002],[-116.69415299999997,75.11665299999999],[-116.71721599999995,75.11665299999999],[-117.16860999999994,75.15748600000006],[-117.38417099999992,75.17858899999999],[-117.41915899999992,75.18248000000006],[-117.45777899999996,75.188873],[-117.47501399999993,75.19220000000013],[-117.66361999999998,75.23915099999999],[-117.67832900000002,75.24443100000008],[-117.68305999999995,75.24859600000008],[-117.68388400000003,75.25305200000014],[-117.67166099999997,75.28887900000012],[-117.666946,75.29414400000002],[-117.66194199999995,75.29803500000008],[-117.53666699999997,75.361649],[-117.45527599999997,75.4002690000001],[-117.42054699999994,75.41331500000007],[-117.35360699999995,75.43748500000004],[-117.32112099999995,75.44859300000007],[-117.26139799999993,75.46887199999998],[-117.24054699999999,75.47360200000003],[-117.218887,75.47637900000012],[-117.14666699999998,75.48027000000002],[-117.10305799999998,75.48220800000013],[-117.041382,75.48359700000015],[-116.89778100000001,75.48248299999995],[-116.87748699999997,75.48136899999997],[-116.75334199999998,75.47943100000003],[-116.13474300000001,75.47637900000012],[-116.11554699999994,75.47692899999998],[-116.02194199999997,75.48498500000005],[-115.97332799999998,75.492752],[-115.92250100000001,75.50387600000005],[-115.81833599999987,75.52970900000003],[-115.68888900000002,75.56442300000009],[-115.64639299999999,75.57360799999992],[-115.61972000000003,75.57887299999999],[-115.56527699999987,75.58387800000003],[-115.53056299999997,75.58499100000012],[-115.50611900000001,75.5872040000001],[-115.46305799999999,75.59193399999992],[-115.36609599999997,75.60276800000003],[-115.28832999999997,75.62052900000015],[-115.28611799999993,75.62442000000004],[-115.277222,75.63053900000006],[-115.26777600000003,75.63581800000003],[-115.20333900000003,75.65721100000013],[-115.18611099999993,75.66276600000003],[-115.09665699999994,75.68719499999997],[-115.08194700000001,75.68942300000015],[-115.07028200000002,75.68997200000007],[-115.04250300000001,75.68969700000008],[-114.99973299999994,75.69081100000005],[-114.99804699999999,75.6958160000001],[-115.00556899999992,75.698868],[-115.028343,75.70166000000012],[-115.05277999999998,75.70304899999991],[-115.07611099999991,75.70248400000008],[-115.10305800000003,75.70082100000013],[-115.14555399999995,75.69413800000001],[-115.21721600000001,75.67932100000007],[-115.27916699999997,75.667755],[-115.32472199999995,75.65998800000006],[-115.38305700000001,75.6538700000001],[-115.40194699999995,75.65248099999997],[-115.47193900000002,75.65026900000004],[-115.51888999999994,75.64999400000005],[-115.60637700000001,75.651093],[-115.66750299999995,75.64721700000013],[-115.714447,75.64248700000013],[-115.889183,75.61442600000004],[-116.09166700000003,75.58055100000013],[-116.108047,75.57415799999995],[-116.11916400000001,75.572769],[-116.34750399999996,75.559143],[-116.38971700000002,75.5577550000001],[-116.46028099999995,75.55748000000006],[-116.48610699999995,75.5577550000001],[-116.84361299999989,75.56498700000003],[-117.19499200000001,75.57360799999992],[-117.21556099999998,75.5747070000001],[-117.23277300000001,75.57693500000005],[-117.24276700000001,75.58055100000013],[-117.25,75.58610500000009],[-117.25110599999994,75.59748800000011],[-117.24833699999999,75.60304300000001],[-117.23999000000003,75.61499000000015],[-117.23361199999994,75.62052900000015],[-117.21362299999993,75.633331],[-117.07805599999995,75.70721400000008],[-117.06443799999994,75.71415700000011],[-117.03971899999999,75.72581500000013],[-117.02362099999993,75.73248300000012],[-117.01666299999994,75.73719800000015],[-116.95556599999992,75.76193200000012],[-116.923317,75.7747040000001],[-116.88667299999992,75.78692600000005],[-116.86888099999999,75.79054300000001],[-116.85056299999991,75.79304500000012],[-116.81639099999995,75.79637100000014],[-116.76278699999995,75.7999880000001],[-116.71972699999998,75.80165099999999],[-116.58860799999997,75.80331400000011],[-116.53056300000003,75.80276500000002],[-116.32417299999992,75.80470300000013],[-116.10582699999998,75.80693100000008],[-116.03721599999994,75.809708],[-115.82305899999994,75.82720899999993],[-115.80444299999994,75.82998700000013],[-115.79444899999999,75.83415200000013],[-115.78415699999994,75.845261],[-115.77971600000001,75.85220300000009],[-115.76500699999997,75.85443100000003],[-115.74944299999999,75.85498000000001],[-115.73693800000001,75.85443100000003],[-115.72638699999993,75.85331700000006],[-115.69193999999993,75.8483280000001],[-115.67388900000003,75.84414700000002],[-115.65943900000002,75.83970600000009],[-115.62277199999994,75.83442700000012],[-115.59445199999999,75.833328],[-115.50723299999993,75.83499100000006],[-115.40499899999998,75.83804300000003],[-115.38194299999992,75.83970600000009],[-115.36416599999995,75.84414700000002],[-115.35193599999997,75.85220300000009],[-115.31360599999994,75.855255],[-115.13945000000001,75.85942100000011],[-115.07277699999986,75.85775799999999],[-115.04998799999998,75.85582000000005],[-115.00083899999998,75.85331700000006],[-114.98082699999992,75.85304300000013],[-114.932503,75.85664400000002],[-114.91194199999995,75.85971100000012],[-114.83860799999997,75.87441999999999],[-114.817497,75.88081400000004],[-114.80444299999994,75.886932],[-114.798607,75.89221200000003],[-114.80999800000001,75.89942899999994],[-114.82417299999986,75.9041600000001],[-114.83667000000003,75.905823],[-114.88166799999993,75.90748600000012],[-114.90722700000003,75.90637200000015],[-115.01806599999992,75.89888000000002],[-115.0641629999999,75.89471400000014],[-115.10527000000002,75.888596],[-115.221657,75.88026400000001],[-115.29277000000002,75.87831100000005],[-115.39472999999992,75.87776200000013],[-115.54055799999998,75.88136299999996],[-115.68222000000003,75.88832100000013],[-115.74694799999986,75.88943499999993],[-115.83029199999993,75.88777200000004],[-115.86888099999999,75.88443000000007],[-116.00472999999994,75.86859099999998],[-116.0533289999999,75.86554000000012],[-116.10665899999998,75.86415099999994],[-116.13474300000001,75.86442599999998],[-116.15083299999992,75.86470000000008],[-116.48277299999995,75.87387100000007],[-116.623894,75.88192700000013],[-116.64972699999998,75.88499500000012],[-116.67666600000001,75.88970900000004],[-116.69972199999995,75.89498900000012],[-116.71501199999994,75.90026900000004],[-116.72444200000001,75.90637200000015],[-116.73416099999992,75.922485],[-116.733612,75.92858900000004],[-116.73137699999995,75.94525100000004],[-116.72666899999996,75.95138500000002],[-116.71389799999997,75.95664999999991],[-116.69972199999995,75.95999099999995],[-116.67748999999998,75.96388200000001],[-116.63221699999997,75.96914700000008],[-116.58528099999995,75.971924],[-116.561394,75.97276299999999],[-116.53721599999994,75.97248800000011],[-116.51611300000002,75.97110000000004],[-116.48528299999998,75.966385],[-116.470551,75.96887200000009],[-116.46193700000003,75.9749910000001],[-116.46833800000002,75.98637400000013],[-116.52834299999995,76.02748099999997],[-116.60221899999993,76.02221699999996],[-116.645554,76.02304100000009],[-116.66944899999999,76.02581800000002],[-116.6875,76.02915999999999],[-116.69888300000002,76.03442400000012],[-116.70556599999998,76.039154],[-116.708618,76.04386900000003],[-116.70777900000002,76.04998800000004],[-116.70612299999999,76.05386400000009],[-116.70168299999995,76.05998200000005],[-116.69638099999992,76.06498700000009],[-116.641388,76.11331200000012],[-116.53388999999999,76.15332000000001],[-116.51611300000002,76.15776100000011],[-116.34221599999995,76.183044],[-116.296112,76.188583],[-116.21362299999998,76.19497700000005],[-116.16361999999992,76.197205],[-116.08416699999998,76.19831800000009],[-116.05943300000001,76.19802900000013],[-115.95889299999999,76.19413800000007],[-115.90862300000003,76.19192499999991],[-115.86554699999999,76.18830900000006],[-115.81582600000002,76.18692000000004],[-115.64334099999996,76.18609600000008],[-115.59500100000002,76.18775900000003],[-115.44721999999996,76.18692000000004],[-115.32749899999999,76.184708],[-115.27306399999998,76.18220500000001],[-115.154449,76.16943400000008],[-115.13027999999997,76.16581699999995],[-115.02166699999998,76.15637200000009],[-114.87554899999998,76.14971900000012],[-114.85109699999992,76.14942900000011],[-114.790771,76.15107700000004],[-114.72833300000002,76.15304600000007],[-114.68499799999995,76.15609700000005],[-114.66972399999997,76.15832500000005],[-114.66251399999999,76.16053799999997],[-114.662781,76.16165199999995],[-114.68083199999995,76.16499299999998],[-114.70639,76.16720599999996],[-114.80082699999997,76.16859400000004],[-114.85056299999997,76.17025800000005],[-114.89862099999993,76.17248500000011],[-114.94499200000001,76.176086],[-114.99305700000002,76.18248000000006],[-115.00974299999996,76.1874850000001],[-115.01444999999995,76.19274900000005],[-115.02250700000002,76.19692999999995],[-115.04527300000001,76.20220899999998],[-115.08944699999995,76.20887800000003],[-115.15972899999997,76.21859699999999],[-115.27223200000003,76.23027000000002],[-115.37304699999999,76.23082000000005],[-115.54943800000001,76.23054500000006],[-115.75666799999993,76.23414600000012],[-115.78195199999993,76.2352600000001],[-115.8272169999999,76.23942599999998],[-115.847778,76.24304200000006],[-115.86665299999993,76.24748200000005],[-115.88194299999992,76.25277699999992],[-115.91471899999993,76.27526900000004],[-115.92166099999997,76.28109699999993],[-115.92500299999989,76.28665200000006],[-115.90943899999996,76.34553500000004],[-115.90139799999997,76.3499910000001],[-115.86054999999999,76.3624880000001],[-115.64835399999998,76.42025800000005],[-115.62638899999996,76.42581200000001],[-115.51471700000002,76.45138500000013],[-115.49973299999994,76.45471200000009],[-115.46665999999993,76.45582600000006],[-115.26944700000001,76.46110500000003],[-115.02139299999993,76.47470099999998],[-115.00167799999997,76.47720300000009],[-114.978882,76.48165899999998],[-114.95638999999994,76.48719800000015],[-114.94638099999992,76.49247700000012],[-114.93360899999999,76.50499000000002],[-114.92999299999997,76.510269],[-114.91944899999999,76.5144350000001],[-114.89972699999987,76.51693699999998],[-114.74054699999988,76.51721200000003],[-114.71112099999999,76.51693699999998],[-114.70194999999995,76.51527400000003],[-114.69611399999991,76.51138299999997],[-114.69833399999999,76.50749200000013],[-114.720551,76.50109900000012],[-114.70694699999996,76.48970000000003],[-114.61028299999992,76.48831200000012],[-114.45140099999998,76.49693300000007],[-114.29361,76.48026999999996],[-114.25167799999991,76.47499099999999],[-114.20722999999987,76.46804800000001],[-114.17471299999994,76.46026600000005],[-114.14806399999998,76.45138500000013],[-114.13555899999989,76.44636500000007],[-114.11833199999995,76.43525700000009],[-114.11193800000001,76.42942800000009],[-114.10333299999996,76.41886900000003],[-114.096947,76.40359500000011],[-114.09111000000001,76.38888500000002],[-114.10611,76.35554500000012],[-114.11749299999997,76.353317],[-114.12943999999993,76.31191999999993],[-114.05972299999996,76.21775800000006],[-113.99665800000002,76.19274900000005],[-113.98332199999999,76.19026200000002],[-113.9583439999999,76.188873],[-113.94833399999999,76.18942300000003],[-113.70889299999999,76.20359800000011],[-113.685272,76.20610000000005],[-113.63890100000003,76.2127690000001],[-113.61609599999997,76.21832300000005],[-113.52443700000003,76.23580900000002],[-113.36501299999992,76.25860599999993],[-113.32333399999993,76.26277200000004],[-113.26055899999994,76.26443499999999],[-112.99916100000002,76.26748700000007],[-112.95667300000002,76.26361100000003],[-112.90972899999997,76.25749199999996],[-112.89222699999993,76.2538760000001],[-112.86860699999994,76.24470499999995],[-112.85888699999998,76.23997500000013],[-112.85305800000003,76.23414600000012],[-112.75055700000001,76.20054600000003],[-112.71721599999995,76.19831800000009],[-112.62138399999998,76.19831800000009],[-112.59028599999999,76.19663999999995],[-112.48194899999999,76.18136600000008],[-112.46278399999994,76.17831399999994],[-112.453888,76.176376],[-112.42500299999995,76.16775500000011],[-112.43138099999993,76.16192600000011],[-112.43859900000001,76.15887500000008],[-112.47721899999999,76.15138200000001],[-112.49416400000001,76.14665200000002],[-112.50389099999995,76.13859600000012],[-112.52610800000002,76.11053500000003],[-112.52806099999998,76.10386700000004],[-112.52278100000001,76.099152],[-112.42278299999987,76.04721100000012],[-112.41332999999992,76.04248000000001],[-112.38555899999994,76.03665200000006],[-112.29888900000003,76.0294340000001],[-112.15416699999997,76.01499899999999],[-112.06861899999996,76.00332600000013],[-112.04332699999992,75.99887100000012],[-111.9786069999999,75.98136900000009],[-111.78443900000002,75.9497070000001],[-111.76390100000003,75.94693000000001],[-111.75279199999994,75.9427490000001],[-111.72778299999999,75.92164600000001],[-111.72666900000002,75.915817],[-111.729446,75.91110199999997],[-111.736107,75.90498400000007],[-111.77749599999999,75.89471400000014],[-111.87138400000003,75.887497],[-111.94444299999998,75.88499500000012],[-112.00945300000001,75.88165299999997],[-112.03472899999997,75.879974],[-112.05222300000003,75.87803600000007],[-112.07501200000002,75.87387100000007],[-112.165009,75.85192899999998],[-112.17971799999998,75.84803800000009],[-112.18694299999993,75.844986],[-112.22556299999997,75.81109600000008],[-112.218613,75.80802900000015],[-112.20834399999995,75.80664100000007],[-112.19248999999996,75.8058170000001],[-112.02834299999995,75.81526199999996],[-111.85861199999988,75.82693499999999],[-111.69082599999996,75.82276900000011],[-111.64499699999993,75.82165500000013],[-111.604446,75.82666],[-111.53971899999993,75.83831800000002],[-111.49638400000003,75.83970600000009],[-111.47638699999999,75.839157],[-111.45195000000001,75.83665500000006],[-111.44499200000001,75.83221399999996],[-111.35527000000002,75.72442600000011],[-111.35388199999994,75.7185970000001],[-111.35500299999995,75.7144320000001],[-111.38971700000002,75.66303999999997],[-111.40834000000001,75.62081899999998],[-111.40722700000003,75.61499000000015],[-111.35360700000001,75.57249500000006],[-111.31861900000001,75.5452580000001],[-111.27139299999999,75.522491],[-111.24722299999996,75.51805100000001],[-111.221657,75.51693699999998],[-110.995003,75.52916000000005],[-110.97222899999997,75.53248600000012],[-110.89943700000003,75.55026200000009],[-110.79499799999996,75.56526200000002],[-110.77166699999992,75.56666600000005],[-110.54222099999993,75.5688780000001],[-110.49553699999996,75.56915300000009],[-110.47582999999992,75.56832900000012],[-110.45612299999999,75.56553599999995],[-110.43110699999994,75.55415299999999],[-110.42443799999995,75.54887399999996],[-110.42223399999995,75.54553200000004],[-110.33389299999993,75.53915400000005],[-110.19583099999994,75.53970300000003],[-110.06777999999997,75.54054300000007],[-109.97416699999991,75.53749099999999],[-109.75,75.52970900000003],[-109.55304699999999,75.52165200000002],[-109.30444299999999,75.51499900000005],[-109.25389100000001,75.51416000000012],[-109.18360899999999,75.5086060000001],[-109.07472199999995,75.49832200000009],[-108.936394,75.47665399999994],[-108.89943699999998,75.47637900000012],[-108.89584399999995,75.47720300000009],[-108.891953,75.48027000000002],[-108.91639700000002,75.51332100000013],[-108.92443800000001,75.52388000000002],[-108.83612099999993,75.61276200000003],[-108.8269499999999,75.68664600000005],[-108.84277299999991,75.69135999999997],[-108.88194299999998,75.69220000000007],[-108.91332999999992,75.69108600000004],[-108.94499199999996,75.69497699999994],[-109.05832699999996,75.72804300000007],[-109.05860899999993,75.73304700000006],[-109.0627669999999,75.73776200000009],[-109.12638900000002,75.7494200000001],[-109.21000699999996,75.76277199999998],[-109.26555599999995,75.77026400000005],[-109.30526700000001,75.77110300000004],[-109.45221700000002,75.78305100000006],[-109.62943999999993,75.7999880000001],[-109.63751200000002,75.82276900000011],[-109.62805200000003,75.829163],[-109.62638900000002,75.83248900000001],[-109.65722699999992,75.86637900000011],[-109.66361999999998,75.8708190000001],[-109.72972099999998,75.87664799999993],[-109.737503,75.87664799999993],[-109.845551,75.86303699999996],[-109.85722399999992,75.86080900000002],[-109.88390400000003,75.84999100000005],[-109.90778399999994,75.84999100000005],[-109.9363939999999,75.85664400000002],[-110.05555699999996,75.89054899999991],[-110.05583200000001,75.89443999999997],[-110.04055800000003,75.89860499999998],[-109.92610200000001,75.92776500000008],[-109.826683,75.93054199999995],[-109.697769,75.94026200000008],[-109.672234,75.94386299999991],[-109.65666199999998,75.94802900000002],[-109.42138699999998,76.03581200000002],[-109.30499299999991,76.10054000000014],[-109.30943300000001,76.1060940000001],[-109.313606,76.10914600000007],[-109.396118,76.13304100000005],[-109.69999699999994,76.21887200000003],[-109.72250400000001,76.22221399999995],[-109.80943300000001,76.23442100000011],[-109.83416699999998,76.23609900000002],[-109.858612,76.23580900000002],[-109.882767,76.23387100000008],[-109.89666699999992,76.23027000000002],[-109.902222,76.22608900000012],[-109.90167199999996,76.22109999999998],[-109.88305699999995,76.19886800000012],[-109.88667299999997,76.19497700000005],[-109.89666699999992,76.19358800000003],[-109.91944899999993,76.19663999999995],[-109.94055200000003,76.20248400000014],[-110.01471700000002,76.22970600000008],[-110.06833599999993,76.25000000000006],[-110.08528100000001,76.25582900000006],[-110.12332199999997,76.26609800000006],[-110.15306099999998,76.27388000000002],[-110.201683,76.28553800000003],[-110.24109599999991,76.29054300000013],[-110.26583900000003,76.2913670000001],[-110.33138999999989,76.29081700000006],[-110.35804699999994,76.29220600000002],[-110.372772,76.29443399999997],[-110.38362099999995,76.29776000000004],[-110.39306599999986,76.3919370000001],[-110.38527699999986,76.42303500000008],[-110.38390400000003,76.42747500000013],[-110.28943600000002,76.43304400000011],[-110.095551,76.45416300000011],[-109.80721999999997,76.49054000000012],[-109.74638400000003,76.50555399999996],[-109.71833799999996,76.51527400000003],[-109.70639,76.5211030000001],[-109.70694700000001,76.52609300000012],[-109.71140300000002,76.52998400000001],[-109.72416699999997,76.5316620000001],[-109.74916100000002,76.5316620000001],[-109.81111099999993,76.52720600000004],[-109.83222999999992,76.52916000000005],[-109.84722899999991,76.53248600000006],[-109.83750900000001,76.53887900000007],[-109.75527999999997,76.57276899999994],[-109.70667299999997,76.5874940000001],[-109.64666699999998,76.59332300000011],[-109.56082199999997,76.64082300000007],[-109.5097429999999,76.70832800000005],[-109.30277999999998,76.79693600000013],[-109.222778,76.80802900000015],[-109.12777699999992,76.81944300000004],[-109.02583299999998,76.82276900000011],[-108.97444199999995,76.8160860000001],[-108.95084400000002,76.81164600000011],[-108.93582200000003,76.80941799999994],[-108.91887699999995,76.80941799999994],[-108.88945000000001,76.81414799999999],[-108.84500099999997,76.82360800000004],[-108.8219529999999,76.82998700000007],[-108.81331599999999,76.83387800000014],[-108.813606,76.83776900000004],[-108.81582600000002,76.84304800000001],[-108.81388899999996,76.84748800000006],[-108.78859699999992,76.85720800000013],[-108.77362099999999,76.85775799999999],[-108.74804699999999,76.85582000000005],[-108.65556300000003,76.81749000000008],[-108.65110800000002,76.81359900000001]],[[-97.04527299999995,76.7977600000001],[-97.075287,76.79332000000011],[-97.093887,76.79693600000013],[-97.18859899999995,76.82276900000011],[-97.20056199999999,76.82943700000004],[-97.20083599999992,76.83415200000007],[-97.20083599999992,76.85748299999995],[-97.18749999999994,76.86026000000004],[-97.14917000000003,76.85971100000012],[-97.12887599999999,76.85775799999999],[-97.08694500000001,76.85108900000012],[-97.00500499999998,76.81971699999997],[-96.99722299999996,76.813309],[-97.00917099999998,76.80748],[-97.02639799999992,76.80247500000013],[-97.04527299999995,76.7977600000001]],[[-113.46610999999996,76.766388],[-113.61361699999992,76.71304300000008],[-113.628601,76.70803800000004],[-113.65249599999999,76.70443699999998],[-113.67999299999985,76.70443699999998],[-113.70417799999996,76.70637499999992],[-113.78472899999997,76.71720900000003],[-113.83667000000003,76.71998600000006],[-113.889183,76.7185970000001],[-114.05471799999992,76.70359800000006],[-114.16194200000001,76.71693399999998],[-114.21444699999995,76.72053500000004],[-114.501106,76.73414600000001],[-114.73416099999997,76.746643],[-114.78694200000001,76.75027499999993],[-114.82501200000002,76.753601],[-114.85888699999998,76.75804099999999],[-114.87304699999993,76.76081800000009],[-114.87526700000001,76.76554900000002],[-114.87581599999999,76.770828],[-114.85526999999996,76.79443400000008],[-114.83721899999989,76.80165099999999],[-114.80444299999994,76.813309],[-114.76666299999988,76.82388300000008],[-114.62416099999996,76.86192299999999],[-114.60637700000001,76.86581400000006],[-114.58583099999993,76.86747699999995],[-114.33693700000003,76.87719700000008],[-114.13834400000002,76.88443000000007],[-113.96221899999995,76.88998400000008],[-113.885559,76.89166300000005],[-113.80750299999994,76.8894350000001],[-113.7625119999999,76.88443000000007],[-113.73444399999994,76.87914999999998],[-113.49804699999993,76.83332800000011],[-113.48750299999989,76.82777399999998],[-113.44915799999995,76.77720599999998],[-113.453888,76.77276599999993],[-113.46610999999996,76.766388]],[[-109.06610099999995,76.90054300000008],[-109.07444800000002,76.89471400000008],[-109.12581599999987,76.89860499999998],[-109.229172,76.90693699999997],[-109.254997,76.91081200000013],[-109.29888899999997,76.92221100000006],[-109.30777,76.92804000000007],[-109.30387899999994,76.93386799999996],[-109.28278399999999,76.93775900000003],[-109.256958,76.93887300000006],[-109.20527600000003,76.93525699999998],[-109.17944299999999,76.93248000000006],[-109.12721299999998,76.92387399999996],[-109.09249899999992,76.91220099999992],[-109.07695000000001,76.9060970000001],[-109.06610099999995,76.90054300000008]],[[-97.25639299999995,76.96748400000013],[-97.28416400000003,76.96582000000012],[-97.33500700000002,76.96804800000007],[-97.40943900000002,76.97303799999997],[-97.458618,76.97720300000015],[-97.47305299999994,76.98054500000006],[-97.42388900000003,77.00582900000006],[-97.37470999999994,77.02249100000006],[-97.28611799999987,77.0333250000001],[-97.24305700000002,77.03749100000005],[-97.19915800000001,77.03776600000003],[-97.15472399999993,77.03027300000002],[-97.13667299999997,77.02554299999997],[-97.09222399999999,77.01081800000003],[-97.09306300000003,77.00499000000013],[-97.23110999999994,76.97137500000002],[-97.25639299999995,76.96748400000013]],[[-95.65972899999991,77.05886800000007],[-95.58555599999988,77.05331400000006],[-95.56082200000003,77.05358900000004],[-95.46528599999994,77.0583190000001],[-95.41776999999996,77.05693100000002],[-95.38667299999997,77.05247500000007],[-95.36833199999995,77.04859900000002],[-95.33721899999995,77.03997800000008],[-95.28805499999987,77.02249100000006],[-95.22471599999994,77.00637800000004],[-95.18194599999993,76.99636800000013],[-95.16833499999996,76.99414100000007],[-95.11582900000002,76.99581899999998],[-95,76.99054000000001],[-94.90638699999988,76.976089],[-94.8138889999999,76.97137500000002],[-94.72860699999995,76.97276299999993],[-94.71417200000002,76.97387700000013],[-94.68859900000001,76.97526600000009],[-94.636124,76.97692900000004],[-94.59306300000003,76.97554000000002],[-94.52639799999997,76.96943700000008],[-94.51000999999991,76.966095],[-94.49415599999992,76.96026599999993],[-94.48971599999999,76.95610000000005],[-94.40194699999995,76.91832],[-94.25778200000002,76.89637800000008],[-94.25473,76.89137300000004],[-94.23889199999996,76.8894350000001],[-94.20722999999992,76.88804600000009],[-94.15972899999997,76.887497],[-94.09638999999999,76.88888500000007],[-94.08168,76.89027400000009],[-94.05499299999985,76.89471400000008],[-94.03222699999992,76.90332000000001],[-94.02610799999997,76.90914900000001],[-94.010559,76.91914400000013],[-94.00111399999992,76.92359899999997],[-93.98666399999996,76.92886400000003],[-93.964722,76.93248000000006],[-93.94360399999994,76.93386799999996],[-93.89999399999994,76.93331900000004],[-93.75500499999993,76.922485],[-93.73916600000001,76.92082200000004],[-93.6583399999999,76.909988],[-93.64944500000001,76.90803500000004],[-93.641953,76.90525800000012],[-93.63583399999999,76.89888000000002],[-93.48860200000001,76.83970600000009],[-93.30139200000002,76.76860000000005],[-93.208054,76.74693300000001],[-93.20278899999994,76.74748199999993],[-93.19221499999998,76.747208],[-93.18749999999994,76.74552900000003],[-93.17971799999992,76.74108899999999],[-93.16972399999997,76.68691999999999],[-93.17443800000001,76.67498799999998],[-93.18638599999997,76.66081200000002],[-93.30027799999988,76.55219999999997],[-93.30665599999992,76.54664600000001],[-93.46139499999998,76.49832200000003],[-93.59527600000001,76.46249399999999],[-93.62998999999996,76.45193499999999],[-93.641953,76.44720500000011],[-93.651947,76.44165000000004],[-93.65222199999994,76.43775900000014],[-93.650284,76.43553200000008],[-93.54833999999988,76.38610800000009],[-93.52860999999996,76.38472000000002],[-93.50944500000003,76.38665800000012],[-93.49833699999999,76.38888500000002],[-93.46362299999987,76.39942900000005],[-93.456955,76.40359500000011],[-93.4674,76.40792799999997],[-93.48055999999997,76.40992700000004],[-93.50083899999998,76.4102630000001],[-93.508896,76.40664700000008],[-93.520554,76.40582300000011],[-93.537781,76.407486],[-93.55499299999997,76.41137700000007],[-93.57084699999996,76.41638200000011],[-93.58056599999998,76.42303500000008],[-93.57640100000003,76.42665099999999],[-93.53306599999996,76.44303900000006],[-93.51889,76.44831800000003],[-93.50140399999992,76.4522090000001],[-93.476562,76.45477299999993],[-93.45422399999995,76.45643600000005],[-93.42222600000002,76.45832800000011],[-93.39277600000003,76.46165500000006],[-93.37027,76.46638500000006],[-93.35722399999992,76.4705350000001],[-93.12361099999993,76.57304399999998],[-93.11111499999993,76.58027600000008],[-93.09527600000001,76.59054600000002],[-93.09695399999993,76.59664900000013],[-93.09973100000002,76.601654],[-93.04638699999992,76.6160890000001],[-92.945831,76.62248200000005],[-92.90306099999998,76.62191800000011],[-92.88027999999997,76.62081899999998],[-92.85722399999992,76.61831700000005],[-92.78971899999993,76.60914600000012],[-92.70527600000003,76.59443700000008],[-92.68360899999999,76.59248400000013],[-92.65499899999998,76.59471100000002],[-92.64250199999998,76.59803799999997],[-92.632767,76.60247800000013],[-92.61805700000002,76.607483],[-92.60583499999996,76.61053500000014],[-92.56443799999994,76.6160890000001],[-92.5411069999999,76.61775200000005],[-92.506393,76.61747700000001],[-92.46833800000002,76.61303700000002],[-92.44082599999996,76.60331700000012],[-92.42111199999988,76.59803799999997],[-92.40055799999999,76.594986],[-92.38694800000002,76.59387200000003],[-92.36860699999994,76.59443700000008],[-92.33084099999996,76.59721400000001],[-92.18331899999998,76.61469999999991],[-92.07749899999999,76.63720700000005],[-92.04360999999989,76.64694200000008],[-92.00433299999992,76.65789799999993],[-91.99194299999999,76.66081200000002],[-91.97000100000002,76.66442899999998],[-91.93859900000001,76.66832000000005],[-91.9100039999999,76.6705320000001],[-91.77555799999993,76.67970300000002],[-91.66860999999994,76.68470800000006],[-91.53582799999992,76.68887300000006],[-91.41055299999994,76.6891480000001],[-91.38528399999996,76.68830900000012],[-91.132767,76.66442899999998],[-91.00889599999994,76.65165700000011],[-90.98611499999998,76.64915500000006],[-90.88389599999994,76.62664799999999],[-90.87138399999998,76.62275700000009],[-90.85472099999998,76.61554000000001],[-90.84999099999987,76.60914600000012],[-90.84416199999993,76.6035920000001],[-90.83721899999995,76.59915200000012],[-90.81777999999997,76.59359700000005],[-90.77999899999998,76.58581500000008],[-90.741104,76.58055100000007],[-90.67443800000001,76.57331800000009],[-90.62638899999996,76.56999200000007],[-90.58250399999997,76.56526200000002],[-90.56361400000003,76.559708],[-90.50306699999993,76.53137200000009],[-90.49861099999993,76.52499399999994],[-90.468613,76.47915599999999],[-90.46806300000003,76.47303800000009],[-90.48332199999993,76.46804800000001],[-90.51083399999999,76.46388200000013],[-90.53805499999993,76.46138000000002],[-90.61610399999995,76.45637499999998],[-90.63833599999992,76.45582600000006],[-90.77917500000001,76.46110500000003],[-90.82640099999998,76.46304299999997],[-91.09056099999992,76.47804300000013],[-91.304169,76.50416600000005],[-91.34973100000002,76.50943000000007],[-91.37388599999986,76.51110799999998],[-91.41471899999993,76.51277199999998],[-91.441101,76.51277199999998],[-91.56416299999995,76.50082399999997],[-91.566666,76.49887100000001],[-91.41639699999996,76.46026600000005],[-91.40249599999999,76.45748899999995],[-91.27111799999994,76.4538730000001],[-91.14750699999996,76.45082100000002],[-91.05721999999997,76.45054600000014],[-90.99110399999995,76.44775400000009],[-90.97416699999997,76.44609100000014],[-90.79777499999994,76.42692599999998],[-90.64222699999999,76.41053799999992],[-90.41444399999995,76.40304600000002],[-90.36833199999995,76.39999400000005],[-90.31722999999994,76.39471400000002],[-90.281387,76.38916],[-90.06361400000003,76.36164899999994],[-89.83138999999994,76.34027100000003],[-89.54388399999993,76.31693999999999],[-89.36776699999996,76.30415299999999],[-89.30555700000002,76.299149],[-89.29249600000003,76.29609700000009],[-89.23055999999991,76.27276600000005],[-89.21777299999991,76.26666300000011],[-89.20861799999994,76.26081800000003],[-89.20111099999991,76.25416600000011],[-89.19221499999998,76.24220300000007],[-89.19249000000002,76.23609900000002],[-89.19860799999987,76.22526600000009],[-89.20916699999998,76.22109999999998],[-89.29554699999994,76.19775400000015],[-89.32640099999992,76.18942300000003],[-89.34973099999996,76.18359400000003],[-89.37805199999997,76.18026700000007],[-89.58833299999992,76.16581699999995],[-89.831955,76.16081200000008],[-89.88861099999991,76.16609199999999],[-89.90417500000001,76.16886900000009],[-89.97610500000002,76.17387400000013],[-90.37332200000003,76.18136600000008],[-90.39778099999995,76.18054200000012],[-90.416946,76.17886399999998],[-90.43859899999995,76.17553700000008],[-90.45361300000002,76.17053199999998],[-90.45584099999996,76.16720599999996],[-90.45556599999998,76.16554300000001],[-90.43859899999995,76.1622010000001],[-90.41444399999995,76.15998799999994],[-90.25695799999994,76.14694200000002],[-90.22222899999997,76.14444000000015],[-90.1516719999999,76.14166300000005],[-90.0641629999999,76.13693200000012],[-90.04861499999998,76.13275100000004],[-90.06361400000003,76.12776200000008],[-90.0852809999999,76.1244200000001],[-90.11082499999998,76.124146],[-90.30888400000003,76.13832100000008],[-90.44860799999998,76.15498400000001],[-90.66639700000002,76.16693099999998],[-90.78611799999999,76.17137100000014],[-90.93720999999994,76.1808170000001],[-91.11221299999988,76.19192499999991],[-91.20472699999993,76.2127690000001],[-91.21972699999998,76.21832300000005],[-91.25695799999994,76.22720300000009],[-91.27444499999996,76.23027000000002],[-91.42361499999998,76.2538760000001],[-91.44583099999994,76.25665300000003],[-91.57139599999994,76.26527400000009],[-91.59722899999997,76.2649990000001],[-91.61361699999998,76.26220699999999],[-91.59973099999996,76.25610400000005],[-91.579453,76.25166300000012],[-91.41665599999999,76.22526600000009],[-91.33277900000002,76.214157],[-91.33666999999997,76.17858899999999],[-91.27194199999991,76.15582299999994],[-91.22027600000001,76.16165199999995],[-91.20333900000003,76.16137700000013],[-91.16332999999997,76.15971400000001],[-91.11665299999999,76.15637200000009],[-90.88249199999996,76.1372070000001],[-90.700287,76.11943100000013],[-90.67971799999998,76.11720300000002],[-90.665009,76.11219800000015],[-90.75750699999998,76.07638500000013],[-90.78527799999995,76.07276900000005],[-90.80943299999996,76.07193000000007],[-90.833618,76.07276900000005],[-90.85527000000002,76.07222000000013],[-90.86250299999995,76.06999200000013],[-90.866104,76.06721500000003],[-90.86471599999999,76.06498700000009],[-90.84889199999998,76.06080600000001],[-90.71578199999999,76.06343099999998],[-90.70360599999992,76.06492600000001],[-90.66394000000003,76.07426500000003],[-90.66094199999986,76.07643100000001],[-90.61166400000002,76.08471700000007],[-90.59916699999997,76.08804299999997],[-90.57501200000002,76.09027100000009],[-90.54833999999994,76.0913700000001],[-90.47416699999997,76.08970600000004],[-90.42944299999999,76.08831800000013],[-90.408615,76.08638000000002],[-90.19444299999992,76.06275900000014],[-90.19055200000003,76.06109600000002],[-90.19387799999998,76.055252],[-90.20249899999999,76.05026199999998],[-90.215012,76.04582199999993],[-90.23388699999992,76.0410920000001],[-90.27416999999997,76.03442400000012],[-90.30166600000001,76.032486],[-90.32861300000002,76.03137200000003],[-90.40472399999993,76.03109699999999],[-90.63594799999998,76.02815200000003],[-90.71845200000001,76.02265899999998],[-90.90417500000001,76.01554900000002],[-90.92916899999989,76.01554900000002],[-91.00527999999997,76.02499400000005],[-91.14472999999998,76.02110299999998],[-91.16082799999992,76.01805100000007],[-91.15527299999991,76.01416],[-91.06973299999993,75.99026500000002],[-90.95028699999995,75.9622040000001],[-90.94193999999999,75.95555100000013],[-90.93859899999995,75.95138500000002],[-90.94193999999999,75.94552600000003],[-90.94888299999997,75.93997200000001],[-90.96806300000003,75.9310910000001],[-91.016953,75.92553700000008],[-91.07055700000001,75.922485],[-91.100281,75.9185940000001],[-91.11888099999993,75.91387900000007],[-91.12943999999999,75.90860000000009],[-91.14334099999996,75.89721700000007],[-91.12582399999985,75.857483],[-91.13249200000001,75.85192899999998],[-91.13583399999993,75.84609999999998],[-91.13417099999992,75.84248400000013],[-91.12999000000002,75.839157],[-91.10749800000002,75.84054599999996],[-91.09167500000001,75.84332300000005],[-91.07945299999994,75.84803800000009],[-91.0533289999999,75.88108799999998],[-90.93998699999997,75.91526800000008],[-90.90306099999992,75.92469800000015],[-90.89584400000001,75.92720000000003],[-90.886124,75.93165599999998],[-90.847778,75.95220899999998],[-90.833618,75.96026599999999],[-90.827789,75.966385],[-90.80555700000002,75.98553500000014],[-90.79388399999999,75.99470500000001],[-90.77749599999999,75.99609400000003],[-90.75584399999997,75.99498000000006],[-90.71722399999993,75.98915100000005],[-90.56945799999994,75.97998000000007],[-90.48332199999993,75.98027000000008],[-90.464447,75.97859199999999],[-90.44471699999997,75.97415199999995],[-90.43331899999998,75.97026100000005],[-90.42944299999999,75.96832300000011],[-90.43415800000002,75.96331800000007],[-90.44249000000002,75.95971700000001],[-90.49221799999998,75.94581600000004],[-90.51916499999999,75.93609600000013],[-90.52610799999997,75.93054199999995],[-90.52833599999991,75.92553700000008],[-90.53138699999994,75.91360500000013],[-90.53167699999995,75.90359500000005],[-90.52999899999986,75.89833100000004],[-90.521118,75.8955380000001],[-90.50472999999994,75.89526399999994],[-90.49694799999997,75.89776600000005],[-90.34722899999997,75.9494170000001],[-90.34222399999999,75.95304900000008],[-90.337784,75.96304300000008],[-90.339447,75.96832300000011],[-90.25695799999994,75.96693399999998],[-90.11805700000002,75.94192499999997],[-90.11444099999994,75.94775399999997],[-90.10249299999998,75.96165499999995],[-90.07250999999997,75.99552900000015],[-90.060272,76.00471500000009],[-90.05277999999998,76.00721700000003],[-90.03750600000001,76.00915500000013],[-90.015015,76.01026900000011],[-89.96665999999988,76.00860599999999],[-89.947495,76.00721700000003],[-89.92971799999992,76.00471500000009],[-89.92443799999995,76.00221300000004],[-89.90916399999998,75.96499599999999],[-89.82501200000002,75.94303899999994],[-89.68749999999994,75.89999399999999],[-89.68998699999992,75.89498900000012],[-89.702225,75.87970000000007],[-89.70944199999991,75.87414600000005],[-89.72444199999995,75.86303699999996],[-89.75029,75.84664900000013],[-89.77278100000001,75.83638000000008],[-89.778885,75.83166500000004],[-89.78222700000003,75.82582100000002],[-89.77639799999997,75.79275500000006],[-89.77500899999995,75.7874910000001],[-89.76501499999995,75.78581200000008],[-89.73889199999996,75.78665200000012],[-89.69249000000002,75.79637100000014],[-89.68638599999997,75.80247499999996],[-89.68804899999998,75.80442800000009],[-89.68916299999995,75.809708],[-89.68554699999999,75.81414799999999],[-89.61999499999996,75.8535920000001],[-89.61111499999993,75.85720800000013],[-89.58750899999995,75.85914600000007],[-89.558334,75.857483],[-89.43916300000001,75.845261],[-89.42277499999994,75.8419340000001],[-89.41027799999995,75.82971200000009],[-89.39250199999998,75.82110599999999],[-89.37777699999998,75.816666],[-89.32000700000003,75.80386399999998],[-89.27749599999993,75.79832499999998],[-89.20140100000003,75.78692600000005],[-89.172775,75.78054800000012],[-89.16416900000002,75.7747040000001],[-89.160278,75.76805100000013],[-89.16055299999994,75.75582899999995],[-89.166946,75.7452550000001],[-89.25389099999995,75.63108800000003],[-89.262787,75.62776199999996],[-89.27500899999995,75.62776199999996],[-89.33667000000003,75.62776199999996],[-89.54305999999997,75.61053500000014],[-89.64917000000003,75.61554000000001],[-89.76306199999999,75.57748400000003],[-89.76528899999988,75.57554600000009],[-89.73944099999994,75.57360799999992],[-89.72250400000001,75.57415799999995],[-89.68194599999987,75.57998699999996],[-89.64999399999999,75.5872040000001],[-89.60555999999991,75.58970599999998],[-89.58833299999992,75.58859300000006],[-89.550995,75.57971199999997],[-89.54249600000003,75.57054099999999],[-89.54861499999998,75.56608599999998],[-89.56806899999998,75.5619200000001],[-89.62832599999996,75.56137099999995],[-89.67639200000002,75.56219499999992],[-89.69249000000002,75.56109600000013],[-89.706955,75.55748000000006],[-89.70083599999998,75.55304000000007],[-89.64555399999995,75.54832500000003],[-89.57667499999997,75.54775999999998],[-89.55082700000003,75.54887399999996],[-89.52639799999992,75.5519260000001],[-89.515015,75.55415299999999],[-89.500565,75.55886800000002],[-89.49194299999999,75.56553599999995],[-89.47361799999987,75.5747070000001],[-89.458618,75.57943699999993],[-89.441666,75.583328],[-89.431671,75.584427],[-89.40333599999997,75.5872040000001],[-89.35166900000002,75.58915700000006],[-89.30221599999999,75.58915700000006],[-89.23582499999998,75.58665500000012],[-89.21722399999999,75.58499100000012],[-89.18277,75.57720899999998],[-89.17443800000001,75.572769],[-89.16833500000001,75.56666600000005],[-89.15638699999994,75.54971300000011],[-89.15499899999998,75.54443400000014],[-89.14917000000003,75.53221100000007],[-89.14306599999998,75.52442900000011],[-89.09973100000002,75.48414600000007],[-88.96389799999997,75.43193100000008],[-88.95056199999993,75.42970300000013],[-88.92138699999998,75.42719999999997],[-88.87110899999999,75.43414300000012],[-88.84167500000001,75.43637100000007],[-88.81861899999996,75.43692000000004],[-88.79695100000004,75.4349820000001],[-88.77972399999999,75.43248],[-88.76888999999994,75.434708],[-88.74777199999994,75.4708250000001],[-88.75,75.47499100000005],[-88.80139200000002,75.53137200000015],[-88.86582900000002,75.58610500000009],[-88.75500499999998,75.67665099999994],[-88.73889200000002,75.67942800000003],[-88.72277799999989,75.67915300000004],[-88.67832900000002,75.67526199999998],[-88.63166799999999,75.66720600000008],[-88.60082999999992,75.65942400000012],[-88.57417299999992,75.64888000000008],[-88.54277000000002,75.63581800000003],[-88.50778200000002,75.61943100000008],[-88.44888300000002,75.59526100000005],[-88.39944500000001,75.579163],[-88.36416600000001,75.5688780000001],[-88.31582600000002,75.55636600000008],[-88.228882,75.5394290000001],[-88.20361300000002,75.5310970000001],[-88.19888299999997,75.52859500000005],[-88.19694500000003,75.52276600000005],[-88.19860799999998,75.51721200000003],[-88.20140100000003,75.51220699999999],[-88.21749899999992,75.50972000000007],[-88.24082899999996,75.50915500000008],[-88.29083300000002,75.49693300000007],[-88.3058319999999,75.49220300000007],[-88.30139199999996,75.48803700000013],[-88.29527300000001,75.48498500000005],[-88.26306199999993,75.47608900000012],[-88.228882,75.47109999999998],[-88.21305799999999,75.4705350000001],[-88.20083599999992,75.47192400000012],[-88.148056,75.48887600000012],[-88.12249799999995,75.50109900000001],[-88.06806899999998,75.52192700000006],[-87.958054,75.54414400000013],[-87.75140399999992,75.57666000000006],[-87.71611000000001,75.57527199999993],[-87.69776899999994,75.57360799999992],[-87.66139199999992,75.56721500000015],[-87.648346,75.5619200000001],[-87.495544,75.48580900000002],[-87.49499500000002,75.48387100000008],[-87.49888599999991,75.47804300000013],[-87.50473,75.474426],[-87.52999899999992,75.46527100000014],[-87.56388900000002,75.45915200000007],[-87.58860799999997,75.45637500000004],[-87.60139499999997,75.45332300000007],[-87.60638399999993,75.44970700000005],[-87.59472699999998,75.44636500000007],[-87.58277899999996,75.444702],[-87.56834400000002,75.44358800000003],[-87.54861499999993,75.44442700000013],[-87.53361499999988,75.44609099999997],[-87.5,75.4522090000001],[-87.45973200000003,75.46138000000008],[-87.44583099999994,75.46527100000014],[-87.43443300000001,75.46887199999998],[-87.4183349999999,75.47970600000008],[-87.41639700000002,75.48526000000004],[-87.43028300000003,75.50109900000001],[-87.43777499999999,75.5086060000001],[-87.44444299999992,75.51388500000007],[-87.46665999999999,75.5211030000001],[-87.46278399999994,75.56303400000007],[-87.39306599999998,75.6041560000001],[-87.38110399999994,75.609421],[-87.35472099999998,75.61303700000002],[-87.28555299999988,75.62025500000004],[-87.26333599999998,75.62109400000003],[-87.25111400000003,75.62109400000003],[-87.23416099999992,75.6183170000001],[-87.08805799999993,75.57998699999996],[-87.07917800000001,75.56666600000005],[-87.07278399999996,75.55998199999999],[-87.05526700000001,75.54693600000002],[-87.01194800000002,75.53137200000015],[-86.96749899999998,75.518326],[-86.931107,75.50804100000005],[-86.914444,75.50387600000005],[-86.86277799999993,75.49165300000004],[-86.80749500000002,75.47915600000005],[-86.77111799999994,75.47554000000014],[-86.72222899999997,75.47499100000005],[-86.64334099999996,75.47804300000013],[-86.631104,75.47776799999991],[-86.60194399999995,75.47637900000012],[-86.58389299999988,75.47470100000004],[-86.56750499999998,75.47221400000012],[-86.48332199999993,75.45665000000002],[-86.464722,75.45277399999998],[-86.37554899999998,75.42747500000013],[-86.36555499999997,75.42330900000007],[-86.36888099999999,75.41832000000011],[-86.38917500000002,75.40776100000005],[-86.400284,75.40220599999998],[-86.41528299999999,75.39888000000013],[-86.50639299999995,75.38804600000003],[-86.55387899999994,75.38136300000008],[-86.57667500000002,75.37719700000002],[-86.61111499999998,75.36831699999999],[-86.61527999999998,75.36554000000007],[-86.59666399999998,75.361649],[-86.54472399999997,75.35914600000001],[-86.52027900000002,75.36025999999998],[-86.49194299999994,75.36276200000009],[-86.37609900000001,75.37637300000006],[-86.35833699999995,75.37969999999996],[-86.24527,75.40193200000004],[-86.19860799999992,75.41609199999994],[-86.16999799999996,75.41859400000004],[-86.08250399999997,75.42137100000014],[-86.03138699999994,75.42248500000011],[-85.833618,75.41609199999994],[-85.68055700000002,75.40803499999998],[-85.67443800000001,75.41832000000011],[-85.90861499999994,75.4602660000001],[-86.00639299999989,75.47221400000012],[-86.10972600000002,75.48193400000002],[-86.12471,75.48553500000008],[-86.13833599999992,75.48997500000007],[-86.14944500000001,75.49636800000007],[-86.154449,75.50082399999997],[-86.14306599999998,75.50804100000005],[-86.11332699999997,75.51499900000005],[-86.09695399999998,75.51776099999995],[-86.00389100000001,75.53137200000015],[-85.90861499999994,75.54386899999992],[-85.86555499999997,75.54470800000007],[-85.76306199999999,75.54609700000009],[-85.44387799999987,75.56025699999998],[-85.32917800000001,75.56109600000013],[-85.30332899999996,75.5688780000001],[-85.18998699999992,75.61192300000005],[-85.07417299999992,75.65193199999999],[-85.05444299999999,75.65609699999999],[-85.03916900000002,75.657761],[-84.92694099999994,75.65887499999997],[-84.87916599999988,75.65693700000003],[-84.79722600000002,75.65277100000014],[-84.76306199999993,75.65026900000004],[-84.71833799999996,75.64276100000006],[-84.68388399999992,75.63443000000012],[-84.62249799999995,75.62803600000007],[-84.59973100000002,75.62664799999999],[-84.57223499999998,75.626373],[-84.524719,75.62803600000007],[-84.4974979999999,75.63165300000003],[-84.50306699999999,75.633331],[-84.51945499999994,75.63610800000004],[-84.53999299999998,75.6377720000001],[-84.55722000000003,75.63888500000013],[-84.60777300000001,75.63916],[-84.63110399999988,75.64054899999996],[-84.65110799999997,75.64359999999999],[-84.65722699999992,75.64749100000006],[-84.66361999999998,75.68609600000002],[-84.644455,75.68719499999997],[-84.48277300000001,75.69442700000008],[-84.35055499999987,75.69775400000003],[-84.32278399999996,75.69914199999994],[-84.29916400000002,75.70277400000009],[-84.07055699999995,75.76193200000012],[-83.92944299999988,75.81080600000007],[-83.87815099999995,75.81896200000006],[-83.76722699999993,75.82415800000012],[-83.74055499999997,75.82443200000006],[-83.72250399999996,75.822495],[-83.70388799999995,75.81832900000006],[-83.69804399999992,75.81442300000003],[-83.70638999999994,75.81219500000009],[-83.72193900000002,75.81080600000007],[-83.74888599999997,75.80664100000007],[-83.752228,75.801376],[-83.73693800000001,75.79525800000005],[-83.69860799999998,75.79026800000003],[-83.67277499999994,75.78887900000001],[-83.61999500000002,75.78942900000004],[-83.56610099999989,75.7916560000001],[-83.51528899999988,75.78970300000015],[-83.49526999999995,75.78637700000013],[-83.47972099999993,75.78221100000002],[-83.464722,75.77609300000012],[-83.45834400000001,75.77026400000005],[-83.447769,75.75582899999995],[-83.43360899999999,75.75027499999999],[-83.41915899999987,75.74887099999995],[-83.29222099999993,75.73776200000009],[-83.12361099999998,75.73442100000005],[-83.06527699999992,75.73915100000005],[-82.96000700000002,75.756104],[-82.82028200000002,75.78193700000008],[-82.79943799999995,75.78610200000008],[-82.66471899999999,75.81137100000012],[-82.46640000000002,75.82804899999996],[-82.32722499999994,75.836929],[-82.27917500000001,75.83665500000006],[-82.13999899999988,75.82693499999999],[-81.95666499999993,75.81526199999996],[-81.885559,75.81109600000008],[-81.66082799999992,75.81137100000012],[-81.53694199999995,75.809418],[-81.45056199999999,75.80081200000006],[-81.21250900000001,75.77137800000008],[-81.22084000000001,75.70471200000003],[-81.27667199999996,75.66832000000005],[-81.281677,75.66360500000002],[-81.285278,75.657486],[-81.271118,75.65138200000013],[-81.256958,75.649719],[-81.01000999999997,75.633331],[-80.98388699999998,75.633331],[-80.85777299999995,75.634995],[-80.77999899999992,75.6377720000001],[-80.54722600000002,75.65081800000002],[-80.50250199999994,75.65220600000009],[-80.48055999999997,75.651093],[-80.46665999999999,75.649429],[-80.31695599999995,75.63053900000006],[-80.275284,75.6249850000001],[-80.25611900000001,75.62164300000012],[-80.19915800000001,75.60887100000014],[-80.101944,75.58692900000005],[-80.06834400000002,75.57887299999999],[-79.95361299999996,75.54026800000008],[-79.94860799999992,75.53414900000001],[-79.95611599999995,75.530823],[-80.0850069999999,75.50776699999994],[-80.19166599999988,75.48997500000007],[-80.25250199999999,75.48580900000002],[-80.35526999999996,75.47387700000007],[-80.37193299999996,75.46887199999998],[-80.37304699999993,75.46304299999997],[-80.358337,75.45860299999998],[-80.33860799999991,75.45637500000004],[-80.30665599999992,75.45609999999999],[-80.10804699999994,75.46914700000002],[-80.0002899999999,75.47692899999998],[-79.92916899999994,75.47970600000008],[-79.73332199999993,75.47192400000012],[-79.714722,75.4705350000001],[-79.64416499999999,75.46249400000005],[-79.58639499999998,75.45471200000009],[-79.5747219999999,75.44999700000005],[-79.581955,75.44636500000007],[-79.635559,75.44581599999998],[-79.656387,75.44413800000007],[-79.67555199999993,75.44136000000003],[-79.68305999999995,75.43580600000007],[-79.68249500000002,75.4308170000001],[-79.62222300000002,75.40248099999997],[-79.60555999999997,75.39804100000015],[-79.56166099999996,75.39498900000007],[-79.52000399999997,75.391098],[-79.50306699999999,75.38859600000006],[-79.48805199999993,75.383331],[-79.48693799999995,75.37997400000006],[-79.48860199999996,75.36248799999993],[-79.51000999999997,75.33804300000008],[-79.52749599999993,75.32222000000007],[-79.53944399999989,75.31776399999995],[-79.56332399999997,75.31860400000005],[-79.59666400000003,75.31608600000004],[-79.6100009999999,75.31080600000001],[-79.61471599999993,75.305542],[-79.61193800000001,75.29832500000009],[-79.5875089999999,75.28749100000005],[-79.57084700000001,75.283051],[-79.54888900000003,75.28109699999999],[-79.443085,75.28019000000006],[-79.50695799999988,75.22998000000007],[-79.571121,75.19914200000005],[-79.62943999999999,75.17498799999993],[-79.65167200000002,75.172485],[-79.73194899999993,75.16470300000003],[-79.77417000000003,75.16720599999996],[-79.835556,75.16026299999999],[-79.92944299999988,75.14054900000008],[-79.94415299999991,75.13638300000002],[-79.95472699999993,75.12692300000009],[-79.95584100000002,75.11387600000012],[-79.95527599999997,75.10664400000002],[-79.95584100000002,75.10026600000003],[-79.96055599999988,75.09471100000013],[-79.97416699999985,75.08998100000008],[-80.12887599999999,75.06805400000002],[-80.15083299999998,75.06553600000007],[-80.215012,75.063309],[-80.296112,75.05886800000007],[-80.44055200000003,75.03804000000002],[-80.42748999999992,75.02998400000013],[-80.40249599999993,75.02110300000004],[-80.32749899999999,74.99859600000013],[-80.31054699999999,74.99636800000013],[-80.29722599999997,74.996643],[-80.23889200000002,74.99443100000013],[-80.19444299999998,74.98997500000002],[-80.18221999999992,74.986649],[-80.17388899999992,74.98248300000006],[-80.18415800000002,74.97943099999998],[-80.21611000000001,74.976089],[-80.24305700000002,74.97303800000003],[-80.25834700000001,74.96971100000007],[-80.27194199999997,74.96499600000004],[-80.27888499999995,74.95942700000006],[-80.27888499999995,74.95721400000008],[-80.27417000000003,74.95109600000012],[-80.26611299999996,74.94664000000006],[-80.24082899999996,74.94664000000006],[-80.03361499999994,74.97442600000011],[-80.0269469999999,74.97998000000007],[-80.01306199999999,74.9869230000001],[-79.975281,74.9994200000001],[-79.94276400000001,75.00694300000009],[-79.91915899999992,75.01054399999998],[-79.79527300000001,75.02748099999997],[-79.776947,75.02832000000012],[-79.71640000000002,75.02886999999998],[-79.69276399999995,75.02804600000002],[-79.61389199999996,75.01998900000001],[-79.59722899999997,75.01748700000013],[-79.58250399999991,75.01443500000005],[-79.50500499999993,74.99832199999997],[-79.50195300000001,74.99581900000004],[-79.50723299999999,74.99304200000012],[-79.53582799999992,74.9916530000001],[-79.55555700000002,74.98719800000009],[-79.55194099999994,74.98165900000009],[-79.464722,74.9333190000001],[-79.4424899999999,74.92164600000007],[-79.42639200000002,74.91720600000002],[-79.391953,74.91110200000003],[-79.35722399999986,74.90748600000012],[-79.33860800000002,74.90332000000006],[-79.33473200000003,74.89999399999999],[-79.33361799999994,74.89637800000014],[-79.33361799999994,74.89444000000003],[-79.33583099999993,74.88916000000012],[-79.370544,74.87637300000011],[-79.39083900000003,74.87248200000005],[-79.50195300000001,74.85942100000011],[-79.53028899999993,74.85775800000005],[-79.58000199999998,74.85832199999999],[-79.73277300000001,74.83665500000012],[-79.85194399999995,74.81887800000004],[-79.86054999999999,74.81469700000014],[-79.8805539999999,74.81303400000007],[-79.93055700000002,74.81330900000006],[-80.06806899999998,74.83638000000008],[-80.25306699999993,74.87081899999998],[-80.27417000000003,74.88108799999998],[-80.28195199999999,74.88998400000008],[-80.29388399999993,74.91998300000012],[-80.29361,74.92637600000006],[-80.29695100000004,74.93109099999992],[-80.30638099999999,74.9391480000001],[-80.32167099999998,74.93775900000009],[-80.33528099999995,74.93304400000005],[-80.362213,74.92359900000002],[-80.38612399999988,74.91360499999996],[-80.396118,74.90859999999992],[-80.41305499999999,74.89776600000005],[-80.41665599999993,74.89387499999998],[-80.41610700000001,74.88888500000013],[-80.36111499999998,74.86886600000003],[-80.34777799999995,74.86499000000015],[-80.32972699999999,74.86137400000007],[-80.29695100000004,74.85693400000008],[-80.261124,74.85276799999997],[-80.22416699999997,74.84942600000005],[-80.18638599999997,74.84332300000011],[-80.15360999999996,74.83665500000012],[-80.108612,74.82443200000006],[-80.097778,74.82026700000006],[-80.10166899999996,74.78915400000005],[-80.15916400000003,74.73026999999996],[-80.19137599999993,74.69802900000008],[-80.15611299999995,74.63693200000006],[-80.14889499999992,74.63108800000003],[-80.14666699999998,74.62692300000003],[-80.14944499999996,74.6224820000001],[-80.16139199999992,74.61219800000009],[-80.231674,74.57804900000008],[-80.24804699999999,74.57609600000012],[-80.253716,74.57605000000007],[-80.33999599999999,74.58055100000013],[-80.38500999999997,74.5816650000001],[-80.454453,74.58082599999994],[-80.46888699999994,74.57943699999998],[-80.48889199999996,74.57554600000009],[-80.59167499999995,74.56442300000009],[-80.75306699999999,74.56330900000012],[-80.84416199999998,74.56275900000009],[-80.95195000000001,74.56608600000004],[-80.97471599999994,74.56693999999999],[-80.99415599999992,74.56971700000008],[-81.02999899999998,74.57666000000006],[-81.04972799999996,74.57916300000005],[-81.06945799999988,74.57971199999997],[-81.21916199999998,74.57138100000009],[-81.26972999999998,74.56608600000004],[-81.28750599999995,74.56303400000007],[-81.51083399999999,74.51443499999993],[-81.67083699999995,74.4785920000001],[-81.75917099999992,74.46110500000009],[-81.78500399999996,74.45776400000005],[-81.81082199999997,74.45694000000009],[-81.85472099999998,74.45942700000012],[-82.06054699999993,74.47554000000002],[-82.08168,74.47720300000009],[-82.10139500000002,74.47970600000008],[-82.32749899999999,74.5105440000001],[-82.511124,74.52720600000004],[-82.55721999999997,74.5147090000001],[-82.57472200000001,74.51165800000007],[-82.59249899999998,74.5105440000001],[-82.61527999999998,74.51110800000004],[-82.74749799999995,74.51805100000001],[-82.78361499999994,74.520264],[-82.87193300000001,74.53858900000006],[-82.91416900000002,74.549149],[-82.95361300000002,74.565811],[-83.01834099999991,74.59443699999991],[-83.05638099999999,74.61554000000001],[-83.07972699999993,74.63026400000007],[-83.08860799999997,74.63665800000012],[-83.09249899999998,74.64137299999999],[-83.10221899999993,74.65415999999999],[-83.12388599999997,74.68498200000005],[-83.12805199999997,74.69192500000003],[-83.13194299999998,74.70832800000011],[-83.12805199999997,74.71748400000007],[-83.10777299999995,74.74803200000002],[-83.09083599999985,74.75776700000011],[-83.07501200000002,74.76220699999993],[-83.04138199999994,74.76998900000007],[-83.02888499999995,74.77499399999994],[-83.02305599999994,74.78054800000012],[-83.02417000000003,74.78332500000005],[-83.08168,74.81805400000007],[-83.09584000000001,74.82388300000008],[-83.10526999999996,74.82666],[-83.116104,74.82859799999994],[-83.15583799999996,74.82693500000005],[-83.20306399999998,74.820831],[-83.22778299999987,74.82054099999999],[-83.24888599999997,74.82360800000009],[-83.29972799999996,74.83554100000015],[-83.33666999999997,74.84942600000005],[-83.380829,74.86637900000011],[-83.40222199999994,74.87525900000014],[-83.47555499999993,74.89665200000007],[-83.51139799999999,74.90165700000011],[-83.52806099999998,74.90165700000011],[-83.54750099999995,74.89749100000006],[-83.55972300000002,74.89248700000007],[-83.56054699999999,74.88720699999999],[-83.55943300000001,74.88081400000004],[-83.55694599999993,74.87525900000014],[-83.527222,74.84526100000005],[-83.51861600000001,74.83943200000004],[-83.47250400000001,74.81526200000002],[-83.45861799999994,74.80802899999998],[-83.42999299999991,74.79748499999994],[-83.39416499999999,74.79026800000003],[-83.37527499999993,74.78692600000011],[-83.35499599999997,74.784424],[-83.32749899999993,74.77916000000005],[-83.318893,74.77499399999994],[-83.32417299999997,74.75526400000012],[-83.32749899999993,74.75],[-83.45472699999999,74.591095],[-83.47444199999995,74.57971199999997],[-83.48416099999997,74.57499699999994],[-83.59889199999998,74.5435940000001],[-83.61166400000002,74.540817],[-83.72083999999995,74.54553200000004],[-83.78555299999994,74.54859899999997],[-83.80555699999996,74.55081200000012],[-83.83084099999996,74.55137600000006],[-83.85527000000002,74.55081200000012],[-83.90750100000002,74.54693600000007],[-84.03778099999994,74.53414900000007],[-84.06332399999997,74.530823],[-84.10749800000002,74.52331499999997],[-84.14584400000001,74.51554899999996],[-84.21640000000002,74.50721699999997],[-84.23889200000002,74.50555400000002],[-84.28555299999994,74.50360100000006],[-84.3327789999999,74.5038760000001],[-84.35583500000001,74.50444000000005],[-84.396118,74.50749200000013],[-84.64167800000001,74.50694300000004],[-84.850281,74.50221299999998],[-84.87138400000003,74.50138900000002],[-84.88945000000001,74.50221299999998],[-84.89944500000001,74.50332600000007],[-84.91194200000001,74.5080410000001],[-84.91665599999993,74.51110800000004],[-84.98306300000002,74.57054100000005],[-84.985275,74.57916300000005],[-84.97471599999994,74.61747700000006],[-84.96028100000001,74.65693700000008],[-84.95500199999987,74.66276600000009],[-84.95083599999998,74.66886900000003],[-84.95083599999998,74.6727600000001],[-84.95249899999999,74.67915300000004],[-84.95556599999998,74.68470800000011],[-84.96417200000002,74.69192500000003],[-84.97332799999987,74.69609100000014],[-84.99055499999997,74.69802900000008],[-85.00334199999998,74.69747900000004],[-85.06388899999996,74.651657],[-85.07250999999997,74.64109800000011],[-85.04472399999992,74.61219800000009],[-85.03750600000001,74.54109200000005],[-85.03694199999995,74.53526300000004],[-85.03860499999996,74.5288700000001],[-85.04360999999994,74.52331499999997],[-85.07417299999992,74.50888099999997],[-85.08778399999989,74.50499000000008],[-85.10472099999998,74.50166300000012],[-85.12527499999993,74.49859600000002],[-85.21444699999995,74.49192800000003],[-85.25944500000003,74.49054000000012],[-85.35305799999998,74.49859600000002],[-85.36361699999998,74.501938],[-85.36999500000002,74.50943000000007],[-85.36389199999996,74.53749099999999],[-85.36555499999997,74.54414400000013],[-85.37027,74.55247500000007],[-85.468613,74.65887500000002],[-85.47416699999991,74.66442899999998],[-85.48277300000001,74.67164600000012],[-85.49499499999996,74.67915300000004],[-85.50445599999995,74.68331899999993],[-85.520554,74.68803399999996],[-85.52722199999988,74.68887300000011],[-85.54333500000001,74.68637100000007],[-85.54998799999998,74.68193100000002],[-85.52417000000003,74.59860200000014],[-85.52084400000001,74.59304800000012],[-85.50917099999998,74.57998700000002],[-85.48693800000001,74.56109600000013],[-85.48194899999993,74.55415299999999],[-85.47999600000003,74.54776000000004],[-85.47917199999995,74.54165599999999],[-85.48028599999992,74.53720099999998],[-85.50389100000001,74.5205380000001],[-85.52722199999988,74.51026900000005],[-85.54222099999993,74.50555400000002],[-85.56054699999993,74.50138900000002],[-85.58084099999996,74.49832200000009],[-85.604172,74.49581899999993],[-86.01333599999998,74.47943100000009],[-86.05943300000001,74.4785920000001],[-86.08250399999997,74.47915600000005],[-86.120834,74.48220799999996],[-86.12304699999987,74.48332199999993],[-86.12277199999994,74.48997500000013],[-86.10110500000002,74.51138300000002],[-86.085556,74.52943400000004],[-86.07917800000001,74.53915400000011],[-86.07778899999994,74.54525799999993],[-86.08277900000002,74.55525199999994],[-86.15361000000001,74.60914600000001],[-86.17777999999993,74.61526500000002],[-86.19749499999995,74.61526500000002],[-86.21583599999985,74.61080900000007],[-86.22444199999995,74.60775800000005],[-86.23500100000001,74.60192900000004],[-86.24055499999997,74.59693900000002],[-86.24276699999996,74.59137000000004],[-86.23443599999996,74.5811000000001],[-86.22749299999998,74.57527199999998],[-86.22305299999994,74.56219499999997],[-86.23222399999997,74.54026800000008],[-86.235275,74.53526300000004],[-86.24471999999997,74.52388000000002],[-86.278885,74.50860599999993],[-86.33277900000002,74.49026500000014],[-86.39917000000003,74.47943100000009],[-86.42332499999998,74.47886699999992],[-86.443604,74.48109399999998],[-86.46250899999995,74.48553500000008],[-86.633331,74.526093],[-86.66416899999996,74.53471400000006],[-86.69110099999989,74.54414400000013],[-86.708618,74.55108600000005],[-86.7208399999999,74.55859400000008],[-86.75917099999998,74.58638000000013],[-86.76278699999995,74.59193399999998],[-86.76167299999997,74.59803799999997],[-86.75140399999987,74.60386699999998],[-86.74610899999999,74.60887100000014],[-86.75111400000003,74.61360200000007],[-86.76695299999994,74.61608899999999],[-86.78527799999995,74.61692800000014],[-86.79943799999995,74.61526500000002],[-86.80110199999996,74.61137400000013],[-86.80055199999993,74.55220000000003],[-86.79722600000002,74.5435940000001],[-86.79444899999999,74.53997800000008],[-86.70556599999998,74.50027500000004],[-86.69360399999994,74.46804800000007],[-86.90583800000002,74.46054100000009],[-87.22582999999992,74.4669340000001],[-87.27027899999996,74.46832300000005],[-87.304169,74.47164900000013],[-87.32084699999996,74.476654],[-87.35278299999993,74.49525499999999],[-87.47444199999995,74.47581500000001],[-87.508621,74.46775800000006],[-87.527222,74.46554599999996],[-87.57472200000001,74.46192900000005],[-87.66999800000002,74.45999100000006],[-87.71083099999993,74.46081500000003],[-87.73222399999997,74.46638500000012],[-87.75500499999998,74.47943100000009],[-87.848053,74.47608900000012],[-87.90361000000001,74.47221400000012],[-88.03611799999993,74.47692899999998],[-88.26362599999999,74.48359700000015],[-88.35610999999994,74.48915099999999],[-88.49694799999986,74.49775700000009],[-88.51722699999999,74.49971],[-88.52972399999999,74.501938],[-88.53527799999995,74.50360100000006],[-88.53999299999998,74.50610400000005],[-88.571121,74.54998799999998],[-88.57084699999996,74.5560910000001],[-88.56082199999997,74.59304800000012],[-88.54222099999998,74.61608899999999],[-88.406387,74.73609899999997],[-88.34750400000001,74.78471400000001],[-88.48472599999997,74.85775800000005],[-88.52806099999987,74.90193199999999],[-88.537216,74.90693700000003],[-88.54777499999994,74.907761],[-88.55722000000003,74.90664700000002],[-88.56806899999998,74.90138200000013],[-88.66471899999993,74.844986],[-88.67582700000003,74.83692900000005],[-88.74360699999994,74.78387500000008],[-88.7497249999999,74.77777100000003],[-88.75250199999999,74.768326],[-88.75306699999993,74.756104],[-88.7497249999999,74.74970999999994],[-88.74888599999991,74.74136400000003],[-88.74943499999995,74.72608900000006],[-88.75334199999992,74.71415700000011],[-88.811935,74.67221100000012],[-88.821396,74.66638200000011],[-88.835556,74.66137700000007],[-88.848343,74.65914900000013],[-88.862213,74.65887500000002],[-88.87388599999991,74.6602630000001],[-88.88305699999995,74.66526799999997],[-88.889725,74.67053199999992],[-88.91722099999998,74.71971100000013],[-88.91805999999985,74.73248300000012],[-88.91416899999996,74.749146],[-88.910278,74.75499000000002],[-88.90556300000003,74.75999500000006],[-88.90417499999995,74.76554900000008],[-88.906387,74.77304100000003],[-88.90972899999986,74.77777100000003],[-88.92694099999994,74.78387500000008],[-89.07362399999988,74.83387800000003],[-89.08860800000002,74.83720400000004],[-89.097778,74.83610500000009],[-89.09916699999997,74.8352660000001],[-89.05999800000001,74.79748499999994],[-89.05332900000002,74.79359400000004],[-89.0427699999999,74.78970299999997],[-89.01112399999994,74.78082299999994],[-89.01028399999996,74.77554300000008],[-89.01278699999995,74.77053800000004],[-89.041382,74.73026999999996],[-89.04750100000001,74.722488],[-89.05583200000001,74.71914699999996],[-89.07778899999988,74.71720900000003],[-89.10221899999999,74.71943700000003],[-89.17887899999994,74.73220800000013],[-89.17887899999994,74.73526000000004],[-89.181107,74.73970000000003],[-89.19055199999997,74.74443099999996],[-89.223053,74.75248700000003],[-89.24305700000002,74.75526400000012],[-89.26501499999995,74.7563780000001],[-89.271118,74.75471500000003],[-89.21640000000002,74.72110000000009],[-89.20249899999993,74.71388200000013],[-89.18971299999993,74.70860299999993],[-89.14111299999996,74.69802900000008],[-89.12249799999995,74.69609100000014],[-89.10527000000002,74.69303900000006],[-89.09583999999995,74.68803399999996],[-89.09583999999995,74.68193100000002],[-89.125,74.61692800000014],[-89.13194299999992,74.61137400000013],[-89.15055799999993,74.59971600000011],[-89.185272,74.5874940000001],[-89.19694500000003,74.584427],[-89.43888900000002,74.55081200000012],[-89.45500199999992,74.54859899999997],[-89.48971599999999,74.54553200000004],[-89.58056599999998,74.54026800000008],[-89.92860399999995,74.530823],[-89.94610599999999,74.53221100000013],[-90.10665899999998,74.54942299999993],[-90.22389199999992,74.56359900000012],[-90.24499500000002,74.56693999999999],[-90.26333599999992,74.57054100000005],[-90.36305199999998,74.59471100000007],[-90.45666499999993,74.60081500000007],[-90.49638400000003,74.60165400000005],[-90.52999899999986,74.60525500000011],[-90.589722,74.61331200000006],[-90.60722399999992,74.616379],[-90.61999500000002,74.61998000000006],[-90.70805399999989,74.64804100000015],[-90.73167399999994,74.664154],[-90.73693800000001,74.66943400000002],[-90.739441,74.67387400000007],[-90.747772,74.70304899999996],[-90.75111400000003,74.71638500000006],[-90.86749299999991,74.70248400000008],[-90.87582399999997,74.69192500000003],[-90.885559,74.68359399999997],[-90.89561499999996,74.68113700000009],[-91.01362599999999,74.69886800000006],[-91.02471899999995,74.70277400000009],[-91.02362099999999,74.70694000000003],[-91.01222199999995,74.71720900000003],[-90.97833299999996,74.73970000000003],[-90.965012,74.74775700000004],[-90.94583099999994,74.75138900000013],[-90.93859899999995,74.75082399999997],[-90.92610199999996,74.75166300000006],[-90.896118,74.75749200000007],[-90.88389599999994,74.76165800000001],[-90.85139500000002,74.77609300000012],[-90.75805700000001,74.83110000000005],[-90.75279199999994,74.83581500000008],[-90.74082900000002,74.84748800000011],[-90.74249299999991,74.85276799999997],[-90.74665800000002,74.86053500000008],[-90.75778200000002,74.88081400000004],[-90.77223200000003,74.88499500000012],[-90.816956,74.88360599999999],[-90.84111000000001,74.87942500000008],[-90.85388199999994,74.87525900000014],[-90.86389200000002,74.86998],[-90.87027,74.86442599999998],[-90.874435,74.85914600000012],[-90.87388599999997,74.85304300000001],[-90.883331,74.84165999999999],[-90.97500600000001,74.7994230000001],[-91,74.78970299999997],[-91.07528699999995,74.76110799999998],[-91.10194399999995,74.75109900000012],[-91.132767,74.74443099999996],[-91.14472999999998,74.74748199999999],[-91.14416499999993,74.75138900000013],[-91.14666699999992,74.75555400000013],[-91.17166099999997,74.75749200000007],[-91.18859900000001,74.75277700000004],[-91.21611000000001,74.73887600000006],[-91.22582999999992,74.73359700000009],[-91.22888199999994,74.72776800000008],[-91.226944,74.722488],[-91.18527199999994,74.68470800000011],[-91.17748999999998,74.67803999999995],[-91.15499899999998,74.66554299999996],[-91.11471599999993,74.645828],[-91.10583500000001,74.63998400000014],[-91.09805299999988,74.633331],[-91.09973099999996,74.62831100000011],[-91.10665899999998,74.62580900000006],[-91.13305699999995,74.62442000000004],[-91.256393,74.62858599999998],[-91.45584100000002,74.63970899999998],[-91.53999299999992,74.64637800000003],[-91.55332899999996,74.64833099999998],[-91.6761019999999,74.67192100000011],[-91.68499800000001,74.67776500000014],[-91.67166099999997,74.68969700000008],[-91.66416900000002,74.69331400000004],[-91.63417099999998,74.69609100000014],[-91.62193299999996,74.70027200000004],[-91.62027,74.70498700000007],[-91.624435,74.70999100000006],[-91.63583399999993,74.71527100000009],[-91.65167199999996,74.71998600000012],[-91.708618,74.72747800000008],[-91.75418100000002,74.72776800000008],[-91.779449,74.72581500000013],[-91.79888899999992,74.72221400000006],[-91.81111099999998,74.71804800000001],[-91.81249999999989,74.71304299999997],[-91.80296299999992,74.70618400000001],[-91.79888899999992,74.69941699999998],[-91.81555199999997,74.69470200000012],[-91.83306900000002,74.69609100000014],[-91.85110500000002,74.69886800000006],[-91.86665299999993,74.7022090000001],[-91.87666300000001,74.70694000000003],[-91.87527499999993,74.711929],[-91.85916099999997,74.72110000000009],[-91.89222699999993,74.75082399999997],[-91.96194499999996,74.76416000000006],[-91.99861099999998,74.77304100000003],[-92.01583899999997,74.77832000000001],[-92.045547,74.78970299999997],[-92.05749499999996,74.79664600000001],[-92.06361399999997,74.80358899999999],[-92.06527699999992,74.80720500000001],[-92.06639100000001,74.81330900000006],[-92.05749499999996,74.82499700000011],[-92.05166599999995,74.83055100000007],[-92.04333499999996,74.83638000000008],[-92.01916499999993,74.84609999999998],[-92.01306199999999,74.85192899999998],[-92.00805699999995,74.86360200000001],[-92.006393,74.88804600000014],[-92.01333599999992,74.9083250000001],[-92.01528899999994,74.91360499999996],[-92.04333499999996,74.9519350000001],[-92.04804999999999,74.95832800000005],[-92.06332399999997,74.96388200000007],[-92.0916749999999,74.97164900000001],[-92.1058349999999,74.97665400000005],[-92.16416900000002,74.99803199999997],[-92.20973200000003,75.03858899999994],[-92.228882,75.07110599999999],[-92.22582999999992,75.07388300000008],[-92.21556099999998,75.07638500000013],[-92.18638599999991,75.08137499999998],[-92.15249599999999,75.08387800000014],[-92.11166400000002,75.08194000000003],[-92.04618800000003,75.08496100000008],[-92.02999899999992,75.08638000000002],[-92.01251199999996,75.095261],[-92.01000999999997,75.10108900000012],[-92.05139200000002,75.14694200000002],[-92.05555700000002,75.15026899999998],[-92.0705569999999,75.15304600000007],[-92.083618,75.15332000000001],[-92.10526999999996,75.1519320000001],[-92.193329,75.143326],[-92.32556199999999,75.15165700000006],[-92.49082900000002,75.21360800000008],[-92.46888699999994,75.28471400000012],[-92.428604,75.39444000000009],[-92.38833599999992,75.44192500000008],[-92.32806399999998,75.4891510000001],[-92.22027600000001,75.54609700000009],[-92.21028100000001,75.55137600000006],[-92.19943199999994,75.55386400000003],[-92.15583800000002,75.55664100000013],[-92.100281,75.56275900000009],[-92.08583099999998,75.56498700000003],[-92.069458,75.5688780000001],[-92.05665599999998,75.57304399999998],[-92.01390100000003,75.58915700000006],[-92.00500499999993,75.59498600000006],[-92.00834699999996,75.66137700000007],[-92.04360999999989,75.68553200000008],[-92.05749499999996,75.69135999999997],[-92.08999599999999,75.70027200000004],[-92.13751200000002,75.72110000000009],[-92.15666199999998,75.7310940000001],[-92.17443799999995,75.74443100000013],[-92.17555199999993,75.75054900000009],[-92.139725,75.77831999999995],[-92.11915599999992,75.78915400000005],[-92.11277799999999,75.79470800000001],[-92.10472099999998,75.80525200000005],[-92.10055499999993,75.82304399999992],[-92.10388199999994,75.84136999999993],[-92.10526999999996,75.84748800000006],[-92.108612,75.85887100000008],[-92.11332700000003,75.86360200000001],[-92.12971499999998,75.87637300000011],[-92.13806199999999,75.879974],[-92.15110800000002,75.8830410000001],[-92.17277499999994,75.88554400000004],[-92.215012,75.88832100000013],[-92.23832699999997,75.8913730000001],[-92.31777999999991,75.90498400000007],[-92.33639499999987,75.90860000000009],[-92.408615,75.92858900000004],[-92.43306000000001,75.93637100000001],[-92.44444299999992,75.94108600000004],[-92.583618,76.00888100000003],[-92.63583399999999,76.10415599999999],[-92.63583399999999,76.10971100000006],[-92.63722200000001,76.115814],[-92.79388399999993,76.20748900000001],[-92.80943300000001,76.21249400000005],[-92.94665499999996,76.24581899999993],[-93.066956,76.299149],[-93.07667499999991,76.31693999999999],[-93.05722000000003,76.32666000000006],[-93.05499299999997,76.33248900000007],[-93.05638099999987,76.33859300000012],[-93.05915800000002,76.34387200000009],[-93.07194500000003,76.353317],[-93.083618,76.35803200000004],[-93.11527999999993,76.363876],[-93.13806199999993,76.366379],[-93.186935,76.3683170000001],[-93.21278399999994,76.36804200000012],[-93.23998999999998,76.3666530000001],[-93.31527699999992,76.36025999999998],[-93.34527599999996,76.35609400000004],[-93.38137799999993,76.34637500000008],[-93.449997,76.32638500000007],[-93.56193499999995,76.29721100000006],[-93.58778399999989,76.292755],[-93.61749299999997,76.29109200000005],[-93.63583399999999,76.29165599999999],[-93.6583399999999,76.29386899999997],[-93.66639700000002,76.29859899999997],[-93.65333599999991,76.30276500000008],[-93.62443499999989,76.30581699999999],[-93.62361099999993,76.31080600000013],[-93.636124,76.32666000000006],[-93.6541749999999,76.32582100000013],[-93.67887899999994,76.32222000000007],[-93.718887,76.31248499999998],[-93.73138399999999,76.30693099999996],[-93.76390100000003,76.28637700000002],[-93.76390100000003,76.28221100000013],[-93.76194800000002,76.28027299999997],[-93.75389099999995,76.27581799999996],[-93.74110399999995,76.27192700000006],[-93.720551,76.26776100000001],[-93.69722000000002,76.26388500000013],[-93.78443900000002,76.25305200000014],[-93.954453,76.257767],[-93.95611600000001,76.257767],[-93.95834399999995,76.257767],[-94.09750400000001,76.25943000000012],[-94.11888099999999,76.26138300000002],[-94.13417099999987,76.2647090000001],[-94.14138799999995,76.26998900000012],[-94.1516719999999,76.27415500000006],[-94.16861,76.27832000000006],[-94.21250900000001,76.280823],[-94.47083999999995,76.28109699999993],[-94.64167799999996,76.29332],[-94.78028899999998,76.28887900000007],[-94.78999299999998,76.28360000000009],[-94.80332900000002,76.27832000000006],[-94.83860800000002,76.26832600000006],[-95.02917499999995,76.23609900000002],[-95.35499599999991,76.23414600000012],[-95.37609900000001,76.23442100000011],[-95.38694799999996,76.23580900000002],[-95.38806199999993,76.28360000000009],[-95.374435,76.29776000000004],[-95.36694299999994,76.30137600000006],[-95.35722399999997,76.30276500000008],[-95.34306300000003,76.30026200000009],[-95.31806899999998,76.29081700000006],[-95.27917500000001,76.28137200000015],[-95.258896,76.282761],[-95.11833200000001,76.29803500000003],[-95.09277299999991,76.30276500000008],[-95.07556199999988,76.30775499999993],[-95.06973299999993,76.31330900000012],[-95.06655899999998,76.319862],[-95.05888399999998,76.32470699999993],[-95.01055899999994,76.3311000000001],[-94.98388699999998,76.33248900000007],[-94.95889299999999,76.33221400000008],[-94.91500899999988,76.32971199999997],[-94.86639400000001,76.32554600000009],[-94.84973100000002,76.32331799999997],[-94.84056099999998,76.31971700000008],[-94.84999099999987,76.31442300000009],[-94.86277799999988,76.30998199999999],[-94.86166399999996,76.30693099999996],[-94.843613,76.30386400000003],[-94.82861300000002,76.3060910000001],[-94.80860899999993,76.31137100000001],[-94.80248999999998,76.31553600000001],[-94.80082699999997,76.32165500000002],[-94.81416300000001,76.32916300000005],[-94.83444199999997,76.334427],[-94.89472999999992,76.34166000000005],[-94.965012,76.34748799999994],[-95.132767,76.36137400000013],[-95.274719,76.372208],[-95.29943799999995,76.3724820000001],[-95.32640100000003,76.37081900000004],[-95.33167999999995,76.36526500000002],[-95.34138499999995,76.359711],[-95.38890099999998,76.35192900000004],[-95.39999399999999,76.353317],[-95.44722000000002,76.36581399999994],[-95.64527900000002,76.38415500000013],[-95.66833500000001,76.38610800000009],[-95.71583599999991,76.39221199999992],[-95.73750299999995,76.39387500000004],[-95.85110500000002,76.40109300000006],[-95.995834,76.43691999999999],[-96.08167999999989,76.47804300000013],[-96.10694899999999,76.49443099999996],[-96.10417199999995,76.5],[-96.09916699999991,76.50555399999996],[-96.09056099999998,76.510269],[-96.06555200000003,76.52137800000008],[-96.05248999999992,76.52415500000001],[-95.99722299999996,76.51944000000015],[-95.94499199999996,76.518326],[-95.80638099999993,76.51638800000006],[-95.77860999999996,76.5188750000001],[-95.69415299999997,76.5452580000001],[-95.68055700000002,76.55053700000008],[-95.65777600000001,76.56137100000012],[-95.59388699999994,76.59304800000007],[-95.58416699999998,76.59832799999998],[-95.587784,76.6035920000001],[-95.59944199999995,76.60525500000006],[-95.61971999999997,76.60609400000004],[-95.63890100000003,76.60415600000005],[-95.66027799999995,76.59942600000005],[-95.69610599999999,76.58415200000013],[-95.69554099999999,76.58027600000008],[-95.69665499999996,76.57443200000006],[-95.712784,76.56860399999994],[-95.75917099999998,76.55358899999999],[-95.78056299999992,76.54887400000013],[-95.99249299999997,76.54803499999997],[-96.016953,76.549149],[-96.15861499999994,76.583328],[-96.17860399999995,76.59414700000008],[-96.22528099999988,76.625809],[-96.27027899999996,76.6327510000001],[-96.33944699999995,76.63220199999995],[-96.35583500000001,76.6330410000001],[-96.38137799999987,76.63581800000003],[-96.40333599999991,76.6397090000001],[-96.42138699999998,76.64610299999998],[-96.445831,76.65721100000013],[-96.45417800000001,76.66249099999999],[-96.46139499999992,76.66859399999998],[-96.46112099999999,76.67359900000002],[-96.46444699999995,76.67970300000002],[-96.47027599999996,76.68553200000002],[-96.52778599999994,76.693039],[-96.61193800000001,76.70248400000003],[-96.636124,76.70443699999998],[-96.66166699999997,76.70471200000003],[-96.73693800000001,76.69720500000005],[-96.76417500000002,76.69552600000009],[-96.78971899999993,76.6958160000001],[-96.81639100000001,76.69747899999999],[-96.85777299999995,76.7019350000001],[-96.87999000000002,76.705826],[-96.91583299999996,76.7144320000001],[-96.94665499999996,76.72360200000014],[-96.95916699999998,76.72915599999993],[-96.964447,76.73332200000004],[-96.900284,76.79525800000005],[-96.88722199999995,76.80554200000006],[-96.87388599999991,76.81080600000007],[-96.85499599999997,76.81303400000002],[-96.839722,76.81025700000009],[-96.724716,76.78332499999999],[-96.67971799999992,76.77026400000005],[-96.59249899999992,76.75888100000003],[-96.42610200000001,76.74470500000007],[-96.33029199999993,76.75027499999993],[-96.311935,76.75138900000013],[-96.30555699999996,76.75387599999999],[-96.31555199999997,76.80247500000013],[-96.32055700000001,76.80664100000007],[-96.36694299999994,76.81275899999997],[-96.45361299999996,76.81526200000013],[-96.50111400000003,76.81805400000007],[-96.54722600000002,76.82276900000011],[-96.7975009999999,76.86137400000001],[-96.81361400000003,76.868042],[-96.84889199999992,76.887497],[-96.86582900000002,76.89804100000003],[-96.86915599999998,76.90416000000005],[-96.86944599999998,76.91387900000007],[-96.86416600000001,76.91970800000007],[-96.85777299999995,76.92498799999993],[-96.83361799999994,76.9327550000001],[-96.79638699999998,76.93748499999992],[-96.77194199999997,76.93775900000003],[-96.761124,76.93775900000003],[-96.72389199999998,76.93525699999998],[-96.708054,76.93331900000004],[-96.69860799999998,76.934143],[-96.66082799999998,76.947205],[-96.65916399999998,76.94914200000005],[-96.66776999999996,76.95443699999993],[-96.67777999999998,76.95776400000005],[-96.69694500000003,76.96054100000015],[-96.718887,76.96304300000003],[-96.765289,76.96527100000003],[-96.80833399999995,76.966095],[-96.8244479999999,76.96775800000006],[-96.82778899999994,76.96887200000003],[-96.82556199999999,76.97442600000005],[-96.810272,76.9791560000001],[-96.77203400000002,76.98101800000012],[-96.74203499999999,76.98220800000001],[-96.67332499999998,76.98220800000001],[-96.622772,76.97998000000007],[-96.483612,76.97110000000004],[-96.353882,76.99304200000006],[-96.39111300000002,77.02693199999999],[-96.387787,77.03054800000001],[-96.37332199999997,77.03193700000003],[-96.28472899999997,77.03942899999998],[-96.27305599999994,77.04026799999991],[-96.24499499999996,77.04193100000003],[-96.22610500000002,77.043045],[-96.10305799999998,77.04470800000013],[-95.96665999999999,77.05304000000012],[-95.88806199999993,77.06109600000002],[-95.75250199999999,77.06860400000005],[-95.73472600000002,77.06860400000005],[-95.70750399999991,77.06694000000005],[-95.65972899999991,77.05886800000007]],[[-113.328888,77.07998700000002],[-113.353882,77.07748400000008],[-113.40888999999999,77.07887300000004],[-113.45140099999992,77.08166499999999],[-113.49194299999999,77.08554100000003],[-113.4974979999999,77.08831800000013],[-113.49027999999998,77.09248400000001],[-113.34472700000003,77.12776200000002],[-113.33528099999995,77.12608300000005],[-113.31471299999998,77.11775200000011],[-113.29332699999986,77.10748300000012],[-113.28694200000001,77.09637500000008],[-113.29110700000001,77.08998100000008],[-113.30471799999998,77.08526600000005],[-113.328888,77.07998700000002]],[[-113.77861000000001,77.10415599999999],[-113.80695299999991,77.10415599999999],[-113.85333300000002,77.10554499999995],[-113.88054699999992,77.10803200000004],[-113.90888999999999,77.11303700000008],[-113.92443800000001,77.1185910000001],[-113.93138099999999,77.1244200000001],[-113.93138099999999,77.12969999999996],[-113.92722300000003,77.135269],[-113.920837,77.141098],[-113.90110800000002,77.14637800000003],[-113.880829,77.14971900000006],[-113.859444,77.15138200000001],[-113.798607,77.15248100000002],[-113.77417000000003,77.15165700000006],[-113.72250399999996,77.14804100000015],[-113.69915800000001,77.14471400000002],[-113.67555199999993,77.14027400000003],[-113.66443599999997,77.13472000000002],[-113.65778399999999,77.12914999999992],[-113.66416900000002,77.12303200000002],[-113.67916899999989,77.11692800000014],[-113.703056,77.111649],[-113.72778299999993,77.10803200000004],[-113.75306699999993,77.10554499999995],[-113.77861000000001,77.10415599999999]],[[-104.25250199999999,77.07276900000005],[-104.30277999999998,77.07222000000007],[-104.354172,77.07388300000002],[-104.37721299999998,77.07666000000012],[-104.40222199999994,77.0811000000001],[-104.421944,77.08720399999999],[-104.43167099999994,77.09887700000002],[-104.42639200000002,77.11637900000005],[-104.42027300000001,77.12220800000006],[-104.40556299999997,77.12776200000002],[-104.31973299999999,77.15165700000006],[-104.30082700000003,77.15525800000006],[-104.27333099999998,77.15971400000001],[-104.18360899999993,77.16720599999996],[-104.11389199999996,77.16609199999999],[-104.07140399999997,77.16137700000013],[-104.061394,77.15887500000002],[-104.031113,77.15109300000006],[-104.01972999999998,77.14610300000004],[-104.001106,77.13581800000009],[-103.99889399999995,77.12387099999995],[-104.00945300000001,77.11804200000012],[-104.02416999999991,77.11248799999998],[-104.04778299999992,77.10693400000014],[-104.15028399999994,77.08638000000002],[-104.196663,77.07748400000008],[-104.25250199999999,77.07276900000005]],[[-95.22444200000001,77.16720599999996],[-95.24527,77.164154],[-95.291382,77.16499299999998],[-95.314438,77.1666560000001],[-95.36277799999993,77.171921],[-95.41999800000002,77.18193100000008],[-95.57250999999985,77.21304299999997],[-95.61305199999993,77.22192400000012],[-95.63417099999992,77.22804300000013],[-95.63890100000003,77.23220800000013],[-95.63999899999993,77.23776199999998],[-95.63667299999997,77.23915099999994],[-95.63137799999993,77.23970000000008],[-95.60804699999989,77.24081400000006],[-95.511124,77.243042],[-95.43804899999998,77.24443100000002],[-95.38751200000002,77.24081400000006],[-95.37222300000002,77.23803700000013],[-95.35611,77.23637400000007],[-95.31361400000003,77.22915600000005],[-95.24415599999992,77.21388200000013],[-95.21639999999996,77.20166],[-95.20666499999999,77.18914799999999],[-95.206955,77.17776499999997],[-95.214447,77.17248500000011],[-95.22444200000001,77.16720599999996]],[[-90.93305999999995,77.25444000000005],[-90.90916400000003,77.25166300000012],[-90.81500199999999,77.24026500000014],[-90.77223200000003,77.23136899999997],[-90.73638899999997,77.22082499999993],[-90.71833800000002,77.20721399999996],[-90.71362299999998,77.20082100000002],[-90.72416699999991,77.18331899999998],[-90.73194899999999,77.17776499999997],[-90.77917500000001,77.15664700000008],[-90.81138599999991,77.14665199999996],[-90.83555599999994,77.14221199999997],[-90.86833199999995,77.13832100000008],[-90.89999399999999,77.13693200000006],[-90.9786069999999,77.13777199999993],[-91.04972800000002,77.14553799999999],[-91.18472300000002,77.16360500000008],[-91.22166400000003,77.17025800000005],[-91.23889200000002,77.17442300000005],[-91.26251200000002,77.18414300000012],[-91.28639199999992,77.19664000000012],[-91.295547,77.20332300000007],[-91.29750100000001,77.20721399999996],[-91.29916400000002,77.217758],[-91.277222,77.22747800000013],[-91.24749799999995,77.23580900000002],[-91.18971299999998,77.24803200000008],[-91.162216,77.25138900000002],[-91.10722399999992,77.25471500000003],[-91.08473200000003,77.25444000000005],[-91.07223499999992,77.25332600000007],[-91.05721999999997,77.25444000000005],[-90.987503,77.25499000000008],[-90.93305999999995,77.25444000000005]],[[-116.35109699999998,77.53915400000005],[-116.20333900000003,77.51998900000007],[-116.09056099999992,77.49108900000004],[-116.073624,77.48553500000003],[-115.88027999999991,77.4333190000001],[-115.52055399999995,77.36442600000004],[-115.49526999999989,77.359421],[-115.458054,77.34860200000008],[-115.44611399999985,77.34304800000012],[-115.389183,77.31219499999992],[-115.390289,77.30636600000008],[-115.54332699999986,77.26554899999991],[-115.59110999999996,77.25999500000012],[-115.61694299999999,77.25833100000011],[-115.66915899999992,77.25694299999998],[-115.69499199999996,77.25526400000001],[-115.77250700000002,77.24775700000004],[-115.81973299999999,77.23748800000004],[-115.83084099999991,77.2333220000001],[-115.85888699999998,77.22082499999993],[-115.87777699999992,77.21527100000014],[-115.9469529999999,77.20887799999997],[-116.112503,77.19386300000002],[-116.13806199999999,77.19220000000013],[-116.19055200000003,77.1916500000001],[-116.21777299999997,77.19274900000005],[-116.26917300000002,77.19026199999996],[-116.28056300000003,77.18359400000003],[-116.31416300000001,77.14444000000009],[-116.31973299999999,77.11775200000011],[-116.28028899999998,77.06721500000003],[-116.26917300000002,77.05581700000005],[-116.24249299999991,77.04414400000002],[-116.17360699999989,77.02720600000009],[-116.06388900000002,77.00749200000001],[-116.00583599999999,76.9974820000001],[-115.95028699999995,76.99136399999998],[-115.860817,76.9791560000001],[-115.75499699999995,76.96081500000008],[-115.73889199999996,76.95526100000006],[-115.73137700000001,76.9497070000001],[-115.72833300000002,76.94386300000008],[-115.729446,76.93803400000007],[-115.73222399999997,76.93165600000009],[-115.74610899999999,76.92526200000009],[-115.80695300000002,76.90637200000009],[-115.829453,76.90081800000013],[-115.85333299999996,76.89721700000007],[-115.903343,76.89387499999992],[-115.92859599999997,76.89305099999996],[-115.98194899999993,76.89553800000004],[-116.06388900000002,76.90277100000009],[-116.11501299999992,76.90914900000001],[-116.25389100000001,76.93248000000006],[-116.306107,76.93609600000013],[-116.32721699999996,76.93553200000002],[-116.35166899999996,76.9327550000001],[-116.36527999999993,76.92637600000006],[-116.36721799999998,76.91554300000007],[-116.36332699999997,76.90887500000008],[-116.35555999999985,76.90332000000001],[-116.34612299999992,76.89833100000004],[-116.32972699999999,76.89276099999995],[-116.18360899999993,76.8458250000001],[-116.16388699999999,76.8416600000001],[-116.10749800000002,76.83360299999998],[-116.031113,76.820267],[-116.00029,76.81137100000007],[-115.89472999999992,76.70332300000001],[-115.891388,76.69747899999999],[-115.89666699999998,76.69164999999998],[-116.07140400000003,76.625809],[-116.09306299999992,76.61914100000001],[-116.11582900000002,76.61442599999998],[-116.160553,76.61109900000008],[-116.23194899999999,76.60304300000001],[-116.25446299999999,76.59860200000008],[-116.32250999999997,76.58110000000005],[-116.37351999999993,76.58180200000004],[-116.73277300000001,76.572495],[-116.75890399999992,76.56999200000007],[-116.97112299999998,76.54859899999997],[-116.99471999999992,76.54582200000004],[-117.01750199999992,76.54220599999996],[-117.03999299999992,76.53749099999993],[-117.053879,76.53305100000011],[-117.06861900000001,76.52609300000012],[-117.07556199999993,76.52053800000004],[-117.07749899999999,76.51416000000006],[-117.07640099999998,76.50888100000009],[-117.07277699999997,76.50305200000008],[-117.05695299999996,76.49165299999999],[-117.04360999999989,76.48692299999999],[-117.01750199999992,76.48248300000012],[-117.00389099999995,76.47747800000008],[-116.983612,76.45498700000007],[-116.94082599999996,76.38693200000006],[-116.93916299999995,76.38053900000011],[-116.93582200000003,76.35192900000004],[-116.93859900000001,76.34637500000008],[-117.09555099999994,76.29525799999993],[-117.13971700000002,76.286926],[-117.31973299999999,76.257767],[-117.345551,76.25637799999998],[-117.36888099999999,76.25694300000004],[-117.52390300000002,76.26361100000003],[-117.5750119999999,76.26887499999998],[-117.60305799999998,76.27388000000002],[-117.62304699999999,76.2788700000001],[-117.639183,76.28414900000007],[-117.65778399999999,76.29332],[-117.64917000000003,76.305542],[-117.64890299999996,76.31137100000001],[-117.65527299999997,76.31749000000002],[-117.67304999999993,76.32222000000007],[-117.69915800000001,76.32415800000001],[-117.72416699999997,76.32443200000012],[-117.87777699999998,76.34193399999998],[-117.889183,76.35581999999994],[-117.90139799999997,76.36720300000013],[-117.90695199999993,76.372208],[-117.99722299999996,76.39694199999997],[-118.02139299999999,76.40193200000004],[-118.04444899999999,76.40498400000013],[-118.05999800000001,76.40914900000013],[-118.04750100000001,76.44165000000004],[-118.02749599999999,76.48471100000006],[-117.97332799999998,76.59637500000002],[-117.92832899999996,76.6766510000001],[-117.91915899999992,76.68803400000013],[-117.90666199999993,76.69413799999995],[-117.883331,76.70054600000009],[-117.86444099999994,76.70416300000005],[-117.848053,76.70832800000005],[-117.81331599999999,76.71943699999997],[-117.79638699999998,76.72581500000013],[-117.78806299999997,76.73220800000007],[-117.73889200000002,76.77221700000001],[-117.73444399999994,76.77832000000012],[-117.73860200000001,76.78414900000013],[-117.79888899999997,76.81776400000001],[-117.81667299999998,76.82138099999997],[-117.84221600000001,76.82388300000008],[-117.86665299999999,76.82222000000013],[-117.88806199999999,76.81887800000004],[-117.90499899999992,76.81219500000003],[-117.91777000000002,76.79998800000004],[-117.92610200000001,76.78804000000002],[-117.96056399999998,76.76998900000007],[-118.00583599999993,76.76138300000014],[-118.02971600000001,76.75860600000004],[-118.08222999999998,76.75694300000009],[-118.10611,76.75749200000007],[-118.15695199999999,76.76249700000011],[-118.21362299999998,76.76915000000008],[-118.29361,76.77304100000015],[-118.319458,76.77304100000015],[-118.33750900000001,76.76832600000012],[-118.49500299999994,76.71220399999993],[-118.47471599999994,76.67970300000002],[-118.45973199999997,76.67387400000001],[-118.428879,76.66387900000012],[-118.40306099999998,76.657761],[-118.35804699999989,76.64888000000002],[-118.34137699999997,76.64359999999999],[-118.33473199999992,76.63749700000005],[-118.316101,76.5747070000001],[-118.50279199999994,76.50972000000007],[-118.52390299999996,76.50387600000005],[-118.546112,76.5],[-118.57084699999996,76.499146],[-118.59694699999989,76.5],[-118.62361099999993,76.50193800000011],[-118.65167200000002,76.50555399999996],[-118.67804699999994,76.50999500000006],[-118.70916699999998,76.51998900000007],[-118.71333299999998,76.52581800000013],[-118.71362299999998,76.5316620000001],[-118.72222899999991,76.5372010000001],[-118.73473399999995,76.54248000000007],[-118.76139799999999,76.54693600000002],[-118.81471299999998,76.55304000000007],[-118.84166700000003,76.55497700000006],[-118.94415299999997,76.51805100000013],[-118.96806300000003,76.50526400000012],[-118.97582999999992,76.49887100000001],[-118.97609699999998,76.49636800000002],[-118.97250399999996,76.49165299999999],[-118.96777299999997,76.48831200000012],[-118.95527600000003,76.48304700000006],[-118.93110699999994,76.47915599999999],[-118.82195300000001,76.47137499999997],[-118.68195300000002,76.4452510000001],[-118.64862099999999,76.42886399999992],[-118.612503,76.4002690000001],[-118.59416199999993,76.38388100000003],[-118.56610099999995,76.34304800000012],[-118.567497,76.33665500000001],[-118.58168,76.32470699999993],[-118.62554899999998,76.29443399999997],[-118.63751200000002,76.28804000000014],[-118.65556299999997,76.28414900000007],[-118.67916899999994,76.28221100000013],[-118.70556599999992,76.28166199999998],[-118.78083799999996,76.28248600000012],[-118.82833900000003,76.28193700000003],[-118.8766629999999,76.27748100000008],[-118.89584400000001,76.27221700000013],[-118.91139199999992,76.26554899999996],[-118.91915899999998,76.25943000000012],[-118.92443799999995,76.25277699999992],[-118.942207,76.21054100000015],[-118.93776699999995,76.20471199999992],[-118.92331699999994,76.19413800000007],[-118.91278099999994,76.18803400000002],[-118.90471600000001,76.16914400000007],[-118.95527600000003,76.13247700000011],[-118.96501199999994,76.1266480000001],[-119.07584399999996,76.08332800000011],[-119.10109699999998,76.08415200000007],[-119.12471,76.08804299999997],[-119.22972099999993,76.10720800000007],[-119.24526999999995,76.11137400000001],[-119.26000999999997,76.11720300000002],[-119.28250099999997,76.12747200000007],[-119.29943800000001,76.13859600000012],[-119.30832699999996,76.1499940000001],[-119.31054699999999,76.15525800000012],[-119.30583200000001,76.16775500000011],[-119.30082699999997,76.17442300000005],[-119.29499799999996,76.18026700000007],[-119.29527300000001,76.18609600000008],[-119.30166600000001,76.19136000000009],[-119.36916399999996,76.22970600000008],[-119.54915599999998,76.32415800000001],[-119.5864029999999,76.318604],[-119.65499899999992,76.30304000000007],[-119.67527799999993,76.26416000000012],[-119.67500299999995,76.24581899999993],[-119.64555399999995,76.23054500000006],[-119.59445199999999,76.20304900000002],[-119.58583099999998,76.1974790000001],[-119.57277699999992,76.18637100000012],[-119.56806899999987,76.18054200000012],[-119.56582600000002,76.17526200000003],[-119.56696299999999,76.16886900000009],[-119.57277699999992,76.16304000000008],[-119.64334099999996,76.11248799999998],[-119.74527,76.11665299999999],[-119.76999699999993,76.11637900000005],[-119.79305999999991,76.1144260000001],[-119.80499299999997,76.10887100000002],[-119.79723399999995,76.10415599999999],[-119.7727809999999,76.09942599999994],[-119.74416400000001,76.097488],[-119.64723200000003,76.08166499999999],[-119.62666300000001,76.07666000000012],[-119.50389100000001,76.04081700000006],[-119.491379,76.03553800000009],[-119.47833299999996,76.02415500000012],[-119.47389199999998,76.01859999999999],[-119.47222899999997,76.00082400000002],[-119.47609699999998,75.98248300000006],[-119.48110999999989,75.97082500000005],[-119.48916599999995,75.96554600000002],[-119.50974299999996,75.96054099999998],[-119.53555299999994,75.9624940000001],[-119.54638699999998,75.96832300000011],[-119.56111099999998,75.97886699999998],[-119.57195299999995,75.98498500000011],[-119.58583099999998,75.98969999999997],[-119.612503,75.99247700000006],[-119.63694800000002,75.99220300000013],[-119.64890300000002,75.98664900000011],[-119.699997,75.94859300000013],[-119.70333900000003,75.9427490000001],[-119.6875,75.93830900000012],[-119.612503,75.91026300000004],[-119.81082199999997,75.86943100000002],[-119.870003,75.857483],[-119.93554699999993,75.8483280000001],[-119.98000300000001,75.84332300000005],[-120.02583300000003,75.83998099999997],[-120.04915599999987,75.83888200000013],[-120.07640100000003,75.86720300000007],[-120.08500700000002,75.87275700000004],[-120.11416600000001,75.88832100000013],[-120.12805199999997,75.89305100000001],[-120.14916999999997,75.89637800000014],[-120.16639700000002,75.89248700000007],[-120.18028299999997,75.879974],[-120.18331899999993,75.87387100000007],[-120.19722000000002,75.86137400000007],[-120.21501199999994,75.84860200000003],[-120.22582999999992,75.84220900000008],[-120.26972999999992,75.82193000000012],[-120.28888699999987,75.81608599999993],[-120.30915800000002,75.81109600000008],[-120.33222999999998,75.80748000000006],[-120.35555999999997,75.80636600000003],[-120.37805200000003,75.80664100000007],[-120.40387699999991,75.80831899999998],[-120.43028300000003,75.81109600000008],[-120.45445299999994,75.81581100000011],[-120.46694899999994,75.82110599999999],[-120.47582999999997,75.82666],[-120.48528299999998,75.8377690000001],[-120.4886019999999,75.84414700000002],[-120.48972300000003,75.84999100000005],[-120.48832699999997,75.85554500000006],[-120.46305799999999,75.91638200000006],[-120.46000700000002,75.922485],[-120.44860799999987,75.93553200000002],[-120.406113,75.95498700000002],[-120.40583800000002,75.97137500000008],[-120.4349979999999,76.00305200000003],[-120.45889299999999,76.01165800000012],[-120.46749899999998,76.01220700000005],[-120.53333299999991,76.00305200000003],[-120.56054699999999,75.9916530000001],[-120.56331599999993,75.98553500000014],[-120.57417299999997,75.9791560000001],[-120.59388699999994,75.97804300000001],[-120.61361699999998,75.98193400000008],[-120.64306599999986,75.99247700000006],[-120.696663,76.01388499999996],[-120.70722999999998,76.01887500000004],[-120.71611000000001,76.02442900000005],[-120.729446,76.03942899999998],[-120.75167799999997,76.09942599999994],[-120.751106,76.10582],[-120.74833699999999,76.11192299999993],[-120.74305700000002,76.11775199999994],[-120.73222399999997,76.124146],[-120.71193699999998,76.12914999999998],[-120.72749299999992,76.15860000000004],[-120.85722399999986,76.19663999999995],[-120.883621,76.19831800000009],[-120.90249599999999,76.19636500000013],[-120.95639,76.17776500000002],[-120.96806300000003,76.172211],[-121.00890400000003,76.14414999999991],[-121.01251199999996,76.13916000000006],[-121.016953,76.12109400000008],[-121.02528399999989,76.07331800000003],[-121.02278100000001,76.05914300000006],[-120.99328600000001,76.02681700000011],[-120.97961399999997,76.01965300000012],[-120.970123,76.0134890000001],[-120.93195300000002,75.95999099999995],[-120.93306000000001,75.95694000000015],[-120.94583099999994,75.94859300000013],[-120.98082699999998,75.94164999999998],[-120.99944299999999,75.93969700000002],[-121.01445000000001,75.9427490000001],[-121.01722699999999,75.94802900000002],[-121.01112399999988,75.97082500000005],[-121.00055699999996,75.97720300000015],[-120.98610699999995,75.98414599999995],[-121.00761399999999,75.98898299999996],[-121.01527399999998,75.9921490000001],[-121.030441,75.99247700000006],[-121.09277299999997,75.9933170000001],[-121.11389199999996,75.9916530000001],[-121.25945299999995,75.96443200000004],[-121.26583900000003,75.95832800000005],[-121.271118,75.94609100000008],[-121.27887699999985,75.92776500000008],[-121.34861799999993,75.92804000000007],[-121.423317,75.93386800000002],[-121.436394,75.93914800000005],[-121.422775,75.9464650000001],[-121.41665599999988,75.95304900000008],[-121.42415599999993,75.95664999999991],[-121.479446,75.97637900000001],[-121.58306899999997,76.00360100000012],[-121.59500100000002,76.00555400000007],[-121.83473200000003,76.03442400000012],[-122.13417099999998,76.03637700000007],[-122.14499699999999,76.03082300000005],[-122.14472999999992,75.99693299999996],[-122.16944899999999,75.97804300000001],[-122.33583099999998,75.94247400000012],[-122.37666300000001,75.93386800000002],[-122.41639700000002,75.92858900000004],[-122.442207,75.92747500000007],[-122.48916599999995,75.92720000000003],[-122.51666299999994,75.928314],[-122.563606,75.93193100000013],[-122.67610200000001,75.95166000000006],[-122.69638099999997,75.95555100000013],[-122.72250400000001,75.96887200000009],[-122.728882,75.97303799999997],[-122.66915899999998,75.97692900000004],[-122.64943699999998,75.98220800000001],[-122.59111000000001,76.00166300000001],[-122.57640100000003,76.00749200000001],[-122.5625,76.01443499999999],[-122.47556299999997,76.10443100000003],[-122.47112300000003,76.11026000000004],[-122.47193899999996,76.11499000000003],[-122.48554999999993,76.1202550000001],[-122.49833699999994,76.12052900000003],[-122.60134900000003,76.11509700000005],[-122.62222300000002,76.11137400000001],[-122.67832900000002,76.11137400000001],[-122.69999699999994,76.11219800000015],[-122.70445299999994,76.1144260000001],[-122.69554099999993,76.11775199999994],[-122.58721899999995,76.13415500000002],[-122.50195299999996,76.13638300000014],[-122.48999000000003,76.141098],[-122.57417299999992,76.16609199999999],[-122.595551,76.17082200000004],[-122.62027,76.17442300000005],[-122.64666699999998,76.17581200000006],[-122.67027300000001,76.17442300000005],[-122.693604,76.17053199999998],[-122.73361199999994,76.1624910000001],[-122.84277299999997,76.13108800000009],[-122.885559,76.10443100000003],[-122.90194699999995,76.09803800000003],[-122.92138699999987,76.092758],[-123.01139799999993,76.08332800000011],[-123.037781,76.08471700000007],[-122.97917199999995,76.12580900000012],[-122.84861799999999,76.20887800000003],[-122.72112299999998,76.23136900000003],[-122.636124,76.2647090000001],[-122.63166799999999,76.2705380000001],[-122.63751200000002,76.28804000000014],[-122.64527899999996,76.299713],[-122.63249199999996,76.32998700000002],[-122.62638900000002,76.33638000000013],[-122.61776700000001,76.34220899999997],[-122.59889199999998,76.34832800000004],[-122.57861300000002,76.35359199999999],[-122.39890300000002,76.39694199999997],[-122.30943300000001,76.40887500000002],[-122.01471699999996,76.43248],[-121.826683,76.4227600000001],[-121.78195199999999,76.42025800000005],[-121.73805199999998,76.42109700000015],[-121.54998799999993,76.43470800000011],[-121.53307299999994,76.43719500000003],[-121.51445000000001,76.44413800000001],[-121.421944,76.49359099999992],[-121.31220999999994,76.572495],[-121.30695300000002,76.57832300000013],[-121.31388899999996,76.58970599999998],[-121.30915800000002,76.59387200000003],[-121.21250899999995,76.649719],[-121.118607,76.67330900000002],[-121.10109699999992,76.66832000000005],[-121.079453,76.66832000000005],[-121.05666399999996,76.67137100000002],[-120.923317,76.68997200000007],[-120.900284,76.69331399999999],[-120.88417099999998,76.698868],[-120.86193800000001,76.71192900000011],[-120.84777799999989,76.72470099999992],[-120.83249699999993,76.73136900000009],[-120.81220999999994,76.73719800000009],[-120.76611299999996,76.7435910000001],[-120.66915899999998,76.75109900000007],[-120.64083899999997,76.74859600000013],[-120.62581599999999,76.74636799999996],[-120.604172,76.74636799999996],[-120.58112299999999,76.7494200000001],[-120.40167200000002,76.797211],[-120.38194299999992,76.80415300000004],[-120.36776700000001,76.81025700000009],[-120.36609599999997,76.813309],[-120.36527999999993,76.83610500000003],[-120.09137699999997,77.00305199999997],[-120.06916799999999,77.00804099999993],[-120.03888699999999,77.01332100000002],[-120.02278100000001,77.01527399999998],[-119.99722300000002,77.01638800000012],[-119.97693600000002,77.01332100000002],[-119.96112099999993,77.009995],[-119.94999699999994,77.01249700000005],[-119.92027299999995,77.02360500000003],[-119.839447,77.05693100000002],[-119.83167999999995,77.06303400000013],[-119.83249699999999,77.06915300000014],[-119.83583099999987,77.07527199999998],[-119.83721899999995,77.07971200000003],[-119.83556399999998,77.08526600000005],[-119.825287,77.09109500000005],[-119.8125,77.09664900000001],[-119.77639799999992,77.1060940000001],[-119.60056299999991,77.145828],[-119.43331899999998,77.17359900000008],[-119.41082799999998,77.17858899999993],[-119.389183,77.184418],[-119.360817,77.20332300000007],[-119.354446,77.20915200000013],[-119.346947,77.22137499999997],[-119.34583999999995,77.22776799999997],[-119.33389299999993,77.23997500000007],[-119.31582599999996,77.2580410000001],[-119.295837,77.27665700000011],[-119.26834099999996,77.28915400000011],[-119.25306699999999,77.2952580000001],[-119.22222899999991,77.30636600000008],[-119.20111099999991,77.31303400000007],[-119.15334299999995,77.32582100000008],[-119.11444099999994,77.32748400000003],[-119.08666999999997,77.32666000000006],[-119.00110599999988,77.32110600000004],[-118.94138299999992,77.31971700000008],[-118.91694599999994,77.32249500000006],[-118.89389,77.32748400000003],[-118.87000299999994,77.33387800000008],[-118.75723299999999,77.35247800000002],[-118.73249800000002,77.35554500000012],[-118.65110799999997,77.36053500000014],[-118.44972199999995,77.35887100000014],[-118.224716,77.35609400000004],[-118.19721999999996,77.35498000000007],[-118.16583300000002,77.35525500000006],[-118.14111299999996,77.35803199999998],[-118.12805200000003,77.36442600000004],[-118.12721299999998,77.36943100000008],[-118.125,77.3724820000001],[-118.10694899999993,77.37803600000012],[-118.08750899999995,77.3791500000001],[-117.91111799999993,77.38693200000006],[-117.86721799999992,77.38859600000006],[-117.85056299999991,77.38443000000012],[-117.781113,77.36303700000002],[-117.76806599999998,77.35775800000005],[-117.756958,77.35165400000005],[-117.75083899999998,77.34664899999996],[-117.73860200000001,77.34193399999992],[-117.72444200000001,77.33804300000008],[-117.61193800000001,77.32777400000003],[-117.45084400000002,77.31219499999992],[-117.27639799999997,77.28915400000011],[-117.02306399999998,77.290817],[-117.01478600000002,77.29670000000004],[-117.01711999999992,77.30020899999994],[-117.02749599999993,77.31025699999998],[-117.06082199999997,77.32666000000006],[-117.10555999999997,77.33998100000002],[-117.11582900000002,77.34165999999999],[-117.11805699999996,77.33859300000012],[-117.1324919999999,77.33332800000005],[-117.15416699999997,77.33248900000007],[-117.16999800000002,77.33581500000008],[-117.18195300000002,77.34027100000003],[-117.181671,77.34637500000002],[-117.17666600000001,77.35220300000015],[-117.15888999999987,77.35887100000014],[-117.14277600000003,77.36137400000013],[-117.11945300000002,77.35998500000011],[-117.06082199999997,77.35331700000012],[-117.00749999999994,77.34303999999997],[-116.94666299999994,77.32943699999998],[-116.87638900000002,77.31805400000013],[-116.848343,77.315811],[-116.795837,77.31749000000002],[-116.77887699999997,77.31915300000009],[-116.65167199999996,77.37776199999996],[-116.64835399999998,77.383331],[-116.65167199999996,77.38804600000003],[-116.66278099999994,77.391663],[-116.741379,77.395264],[-116.87082699999996,77.40081800000002],[-116.89917000000003,77.399429],[-116.97582999999997,77.39332600000006],[-116.99471999999992,77.39444000000003],[-117.01112399999994,77.39888000000008],[-117.15306099999992,77.45166000000012],[-117.14998599999996,77.45721400000014],[-117.13890100000003,77.46054100000003],[-117.08306899999997,77.47442599999994],[-117.06667299999998,77.4769290000001],[-117.0613939999999,77.47608900000006],[-117.03833799999995,77.47100100000006],[-116.991669,77.4666600000001],[-116.91972399999997,77.47053500000004],[-116.89444700000001,77.47331200000013],[-116.78527799999995,77.499146],[-116.75723299999993,77.51165800000001],[-116.76944699999996,77.516388],[-116.85109699999998,77.51666300000005],[-116.87917299999987,77.51776100000012],[-116.9058379999999,77.52026400000011],[-116.926941,77.5247040000001],[-116.92054699999994,77.528595],[-116.900284,77.53221100000002],[-116.875,77.53498800000011],[-116.83306900000002,77.53360000000004],[-116.75418100000002,77.534424],[-116.64750699999996,77.53776600000015],[-116.58583099999998,77.54054300000001],[-116.53611799999993,77.54443400000008],[-116.48777799999999,77.55026200000003],[-116.35109699999998,77.53915400000005]],[[-85.285278,77.58749400000005],[-85.25973499999998,77.58665500000012],[-85.23527499999994,77.58665500000012],[-85.10722399999997,77.58109999999999],[-85.01112399999994,77.57388300000008],[-84.99527,77.56944300000009],[-84.82250999999997,77.50526400000012],[-84.81388900000002,77.49720800000006],[-84.82444799999996,77.49192799999997],[-84.84306299999992,77.48719800000015],[-84.93443300000001,77.47026099999994],[-84.96083099999998,77.46638500000006],[-85.027222,77.45971700000007],[-85.095551,77.45443700000004],[-85.12693799999994,77.45304899999991],[-85.15360999999996,77.45443700000004],[-85.16833500000001,77.45693999999997],[-85.178604,77.46415700000011],[-85.1725009999999,77.47360199999997],[-85.15916400000003,77.48414600000001],[-85.14472999999992,77.4894260000001],[-85.13861099999997,77.49498000000011],[-85.14083900000003,77.50166300000006],[-85.15278599999999,77.50776700000011],[-85.17027300000001,77.51165800000001],[-85.24888599999991,77.52748100000002],[-85.27084399999995,77.52998400000001],[-85.31973299999993,77.53221100000002],[-85.34416199999998,77.53221100000002],[-85.39916999999997,77.53387500000008],[-85.53832999999997,77.53997800000002],[-85.53555299999994,77.54386900000009],[-85.35221899999993,77.58276400000005],[-85.31138599999997,77.58665500000012],[-85.285278,77.58749400000005]],[[-90.60305800000003,77.62831100000005],[-90.521118,77.62608300000011],[-90.49249299999997,77.62608300000011],[-90.43859899999995,77.630539],[-90.41444399999995,77.63108799999998],[-90.38806199999988,77.62942500000003],[-90.33917200000002,77.62387100000007],[-90.24249299999985,77.61248800000004],[-90.21916199999998,77.60887100000008],[-90.20889299999993,77.60304299999996],[-90.21000700000002,77.59748800000006],[-90.20666499999999,77.59165999999999],[-90.19665499999996,77.58720400000004],[-90.17777999999993,77.58248900000001],[-90.05972299999996,77.56637599999999],[-89.93721,77.53276100000005],[-89.91722099999987,77.52720599999998],[-89.84110999999996,77.50416600000005],[-89.80665599999992,77.49247700000012],[-89.75361599999997,77.47303800000003],[-89.71916199999998,77.45832800000011],[-89.636124,77.33915700000006],[-89.640289,77.33332800000005],[-89.67471299999994,77.31025699999998],[-89.70777899999996,77.29414400000013],[-89.84973099999996,77.25],[-89.882767,77.23997500000007],[-89.91999800000002,77.23027000000002],[-90,77.21381400000001],[-90.00917099999998,77.211929],[-90.08889799999992,77.19970700000005],[-90.11805700000002,77.19859300000007],[-90.129166,77.20054600000003],[-90.25917099999992,77.20109600000006],[-90.36694299999999,77.19775400000009],[-90.41665599999999,77.21304299999997],[-90.68331899999993,77.27192700000006],[-90.70472699999993,77.27638200000007],[-90.72721899999993,77.27998400000001],[-90.84306300000003,77.29275499999994],[-90.90972899999997,77.30304000000007],[-90.94665500000002,77.30941800000005],[-91.14666699999992,77.36219800000009],[-91.18249499999996,77.38693200000006],[-91.18721,77.39027399999998],[-91.20889299999993,77.4149930000001],[-91.206955,77.56860400000011],[-91.18443300000001,77.60859700000015],[-91.17361499999993,77.61303699999996],[-91.15834000000001,77.61720300000007],[-91.10943599999996,77.62498500000004],[-90.90638699999994,77.65304600000013],[-90.88082899999995,77.65443400000004],[-90.82640099999998,77.65443400000004],[-90.80166600000001,77.65165700000011],[-90.72749299999998,77.64221200000003],[-90.68360899999993,77.63333100000011],[-90.60305800000003,77.62831100000005]],[[-105.01027699999986,77.40803499999993],[-104.98665599999998,77.4044340000001],[-104.96193700000003,77.4044340000001],[-104.90805099999994,77.40693700000003],[-104.82584400000002,77.41360500000002],[-104.77166699999998,77.41665600000005],[-104.74109599999997,77.41442899999998],[-104.73277300000001,77.41137700000007],[-104.53832999999997,77.33831800000007],[-104.48889199999996,77.318604],[-104.39555399999995,77.27638200000007],[-104.38834400000002,77.27137800000014],[-104.38137799999998,77.2644350000001],[-104.37998999999996,77.26193199999994],[-104.36554699999999,77.23027000000002],[-104.36749299999997,77.224426],[-104.40499899999992,77.17248500000011],[-104.416946,77.16192600000005],[-104.43804899999998,77.15054300000003],[-104.47250400000001,77.13749700000011],[-104.5,77.13304099999999],[-104.52250699999996,77.13053900000011],[-104.74027999999993,77.10859700000009],[-104.79028299999999,77.10887100000002],[-104.83249699999993,77.11331200000012],[-104.85333300000002,77.11747700000012],[-104.86916400000001,77.12359600000013],[-104.883331,77.13554399999998],[-104.89250199999992,77.14193699999993],[-104.906387,77.14749100000012],[-104.92250099999995,77.15248100000002],[-104.945267,77.15721100000002],[-104.993607,77.16499299999998],[-105.04444899999993,77.17137100000014],[-105.09583999999995,77.176086],[-105.11971999999997,77.17665099999999],[-105.13751200000002,77.176086],[-105.15167200000002,77.17137100000014],[-105.24694799999997,77.19386300000002],[-105.40888999999999,77.28166199999998],[-105.41722099999998,77.28471400000006],[-105.45527599999997,77.29193099999998],[-105.48111,77.29498300000012],[-105.50666799999993,77.299149],[-105.531677,77.30525200000011],[-105.55027799999999,77.311646],[-105.57195300000001,77.32331799999992],[-105.67916899999994,77.44747900000004],[-105.691101,77.49720800000006],[-105.83444199999997,77.6102600000001],[-105.858337,77.62692300000015],[-105.878601,77.6397090000001],[-105.88890100000003,77.645264],[-105.93083200000001,77.66304000000014],[-105.94776899999994,77.66886899999997],[-105.98000299999995,77.67942799999997],[-106.01471700000002,77.68858300000005],[-106.08361799999989,77.71026599999999],[-106.09166699999997,77.71527100000003],[-106.09472700000003,77.72415199999995],[-106.08917199999996,77.72886699999998],[-106.07945299999989,77.73275800000005],[-106.04055800000003,77.74498000000006],[-106.01222200000001,77.75054900000003],[-105.94167299999987,77.75972000000002],[-105.91388699999999,77.76249700000005],[-105.70056199999999,77.75360099999995],[-105.64890299999996,77.74859600000008],[-105.55248999999998,77.72943099999998],[-105.50666799999993,77.71971100000007],[-105.47028399999999,77.70915200000002],[-105.38971699999996,77.68386800000002],[-105.17360699999995,77.61219800000003],[-105.15695199999999,77.60609399999998],[-105.03971899999999,77.55219999999997],[-105.02778599999994,77.54637100000014],[-104.968613,77.51443500000005],[-104.95916699999998,77.50804100000005],[-104.94888300000002,77.49609400000008],[-104.94499199999996,77.484985],[-104.946663,77.47915599999999],[-104.95249899999999,77.47442599999994],[-104.96749899999998,77.46887200000015],[-105.01027699999986,77.4586030000001],[-105.01194800000002,77.45277400000009],[-105.01806599999986,77.411926],[-105.01027699999986,77.40803499999993]],[[-95.40583800000002,77.76388500000002],[-95.40888999999993,77.75221300000004],[-95.406113,77.74609400000003],[-95.38972499999994,77.73942600000004],[-95.36389200000002,77.73719800000009],[-95.343887,77.73803700000008],[-95.118607,77.74971000000005],[-95.08778399999994,77.75221300000004],[-95.05943300000001,77.75665300000009],[-95.02917499999995,77.76721199999992],[-95.01083399999999,77.77777100000014],[-94.981674,77.78082300000005],[-94.95167499999997,77.782486],[-94.752228,77.78858900000012],[-94.72888199999994,77.78831500000001],[-94.62332199999997,77.78359999999998],[-94.5727839999999,77.78054800000007],[-94.54222099999993,77.77388000000008],[-94.521118,77.76776100000006],[-94.47749299999992,77.76470899999998],[-94.44860799999998,77.76527399999998],[-94.35665899999987,77.76748700000013],[-94.25250199999994,77.77221699999996],[-94.08999599999993,77.76582300000013],[-94.03028899999998,77.76054399999998],[-93.95111099999997,77.73553500000014],[-93.93582199999997,77.73248300000006],[-93.93138099999999,77.73248300000006],[-93.82667500000002,77.73942600000004],[-93.82000700000003,77.74498000000006],[-93.81777999999997,77.75082400000008],[-93.80665599999992,77.75637800000004],[-93.78666699999997,77.76110800000009],[-93.68638599999997,77.77388000000008],[-93.65695199999999,77.776657],[-93.62943999999993,77.77609300000006],[-93.546112,77.770828],[-93.241669,77.73387100000014],[-93.23388699999987,77.73248300000006],[-93.17471299999994,77.70416300000005],[-93.101944,77.66249099999999],[-93.10665899999992,77.66026300000004],[-93.14834599999989,77.6455380000001],[-93.16416900000002,77.64027400000009],[-93.19638099999997,77.63720699999999],[-93.22250400000001,77.638596],[-93.24916100000002,77.64166300000011],[-93.27722199999994,77.64359999999994],[-93.30305499999997,77.64359999999994],[-93.35943599999996,77.63581800000003],[-93.37943999999999,77.63081400000004],[-93.39028899999994,77.62553399999996],[-93.39723200000003,77.61998],[-93.48638899999997,77.54553199999998],[-93.50250199999999,77.50305200000008],[-93.47778299999999,77.49247700000012],[-93.47471599999994,77.48748799999998],[-93.47416699999991,77.47637900000007],[-93.475281,77.47137499999991],[-93.48083499999996,77.4666600000001],[-93.537781,77.4458160000001],[-93.55305499999992,77.44081100000005],[-93.57055699999995,77.43775900000014],[-93.90666199999998,77.4333190000001],[-93.93388400000003,77.43359399999997],[-94.25167799999997,77.45526100000001],[-94.319458,77.4685970000001],[-94.34500100000002,77.472488],[-94.468887,77.4769290000001],[-94.8011019999999,77.48027000000013],[-95.03222699999998,77.46998600000012],[-95.12361099999998,77.46388200000007],[-95.204453,77.46081499999997],[-95.25279199999994,77.46081499999997],[-95.29499800000002,77.46638500000006],[-95.34638999999999,77.46998600000012],[-95.47749299999998,77.47387700000002],[-95.53277600000001,77.47360199999997],[-95.72610500000002,77.47026099999994],[-95.82362399999994,77.46638500000006],[-95.83889799999986,77.46249399999999],[-95.86416600000001,77.46220399999999],[-95.88945000000001,77.4644320000001],[-96,77.47998000000013],[-96.06138599999986,77.49165299999999],[-96.083328,77.49775699999998],[-96.09973099999996,77.50443999999999],[-96.25917099999998,77.57192999999995],[-96.31834399999997,77.59887700000007],[-96.328888,77.60498000000001],[-96.25556899999992,77.68969700000002],[-96.241104,77.69497700000011],[-96.19444299999998,77.70498700000002],[-96.07722499999994,77.72692900000004],[-95.93443300000001,77.75305200000003],[-95.91805999999997,77.75555400000007],[-95.89723199999997,77.75749200000001],[-95.86944599999993,77.75721700000003],[-95.848053,77.75526400000007],[-95.74276700000001,77.76220700000005],[-95.63055399999996,77.77110299999998],[-95.58389299999993,77.77970900000008],[-95.57000700000003,77.78414900000013],[-95.566101,77.78776600000009],[-95.56555200000003,77.79275500000006],[-95.55277999999993,77.79609700000015],[-95.52888499999995,77.80108600000011],[-95.49610899999999,77.80554200000006],[-95.46528599999994,77.80802900000009],[-95.42777999999998,77.80331400000006],[-95.41833500000001,77.79887400000007],[-95.41082799999998,77.79248000000001],[-95.40695199999999,77.78720100000004],[-95.404449,77.77638199999996],[-95.40583800000002,77.76388500000002]],[[-77.851944,77.77442900000005],[-77.87527499999987,77.77442900000005],[-77.88806199999988,77.78137200000003],[-77.93055699999996,77.80886800000007],[-77.95500199999992,77.83027600000003],[-77.952225,77.833054],[-77.93638599999991,77.83915700000011],[-77.906387,77.84443700000003],[-77.88027999999991,77.84803800000003],[-77.821121,77.85443100000003],[-77.71777299999997,77.86303700000013],[-77.67610200000001,77.86470000000003],[-77.62277199999994,77.86276200000009],[-77.59638999999999,77.86080899999996],[-77.58277900000002,77.8580320000001],[-77.57528699999995,77.85498000000013],[-77.56861900000001,77.849716],[-77.57556199999999,77.82360800000004],[-77.57917800000001,77.81860400000005],[-77.59277299999991,77.813309],[-77.62805200000003,77.80415300000004],[-77.65888999999999,77.79693600000013],[-77.68055700000002,77.79275500000006],[-77.851944,77.77442900000005]],[[-101.71140300000002,77.90165700000006],[-101.671944,77.893326],[-101.62082699999996,77.88443000000007],[-101.52443700000003,77.86998000000011],[-101.450287,77.86109899999997],[-101.36833200000001,77.8538670000001],[-101.26555599999995,77.842758],[-101.23777799999993,77.83888200000013],[-101.19138299999997,77.83082600000006],[-101.16139199999992,77.82276900000005],[-100.96056399999992,77.75915500000013],[-100.92639200000002,77.7433170000001],[-100.92555199999998,77.73719800000009],[-100.928879,77.73136900000009],[-100.94055200000003,77.72692900000004],[-100.96472199999994,77.72554000000008],[-101.096947,77.71943699999991],[-101.21694899999994,77.721924],[-101.26777599999997,77.72581500000007],[-101.31806899999992,77.726089],[-101.50695799999994,77.7249910000001],[-101.53527799999995,77.72360200000014],[-101.56471299999993,77.72053500000004],[-101.58583099999993,77.71527100000003],[-101.593613,77.709427],[-101.60582699999992,77.70387300000004],[-101.62249799999995,77.69859300000013],[-101.65222199999994,77.69442700000008],[-101.79888900000003,77.67637600000006],[-101.82640099999992,77.67608600000005],[-102.01695299999994,77.67970300000002],[-102.06777999999997,77.68220500000007],[-102.1416779999999,77.690811],[-102.43639399999995,77.72970599999996],[-102.44444299999998,77.73193400000008],[-102.51083399999999,77.78610200000008],[-102.52971600000001,77.83415200000007],[-102.51806599999992,77.84414699999996],[-102.498894,77.855545],[-102.45889299999999,77.87109400000008],[-102.44249000000002,77.8766480000001],[-102.41665599999999,77.88192700000008],[-102.38778699999995,77.88415500000002],[-102.13999899999999,77.89637800000008],[-102.08389299999999,77.89721700000007],[-102.04915599999998,77.89694200000002],[-101.91583299999996,77.8938750000001],[-101.83194699999996,77.8938750000001],[-101.779449,77.89637800000008],[-101.74973299999999,77.89971900000012],[-101.71140300000002,77.90165700000006]],[[-114.07305899999994,77.98165900000004],[-113.9813769999999,77.9349820000001],[-113.97501399999993,77.93109100000004],[-113.97222899999997,77.92526200000003],[-113.97222899999997,77.91998300000006],[-113.9583439999999,77.91499300000004],[-113.92388900000003,77.91081200000013],[-113.89499699999993,77.90832500000005],[-113.84028599999999,77.9060970000001],[-113.72666899999996,77.89610300000004],[-113.70639,77.89166300000005],[-113.58556399999998,77.82582099999996],[-113.57861300000002,77.81999199999996],[-113.57611099999997,77.81414799999999],[-113.58750899999995,77.80802900000009],[-113.61916399999996,77.79582199999999],[-113.65972899999997,77.78332499999999],[-113.78832999999992,77.74525500000004],[-113.90833999999995,77.72637900000001],[-113.93472300000002,77.72387700000013],[-114.11444099999989,77.70664999999991],[-114.19304699999998,77.69802900000002],[-114.223053,77.698868],[-114.277222,77.70220900000004],[-114.33112299999999,77.70971700000001],[-114.415009,77.73136900000009],[-114.514183,77.76527399999998],[-114.66251399999999,77.80386399999992],[-114.70916699999998,77.81359900000001],[-114.73029300000002,77.81887799999998],[-114.84834299999994,77.85470600000002],[-115.07721699999996,77.938583],[-115.11138900000003,77.95387299999999],[-115.11501299999992,77.95637500000004],[-115.11609599999991,77.958328],[-115.108337,77.96138000000008],[-115.090843,77.96360800000008],[-115.06054699999993,77.96388200000001],[-115.03388999999993,77.96220400000004],[-114.93028299999997,77.96054100000015],[-114.81973299999993,77.97303799999992],[-114.79778299999992,77.97554000000002],[-114.77749599999993,77.98165900000004],[-114.74027999999998,78.00000000000006],[-114.60582699999998,78.03054800000001],[-114.40083299999998,78.06749000000002],[-114.35500300000001,78.07054100000005],[-114.32694999999995,78.0711060000001],[-114.30332899999996,78.07054100000005],[-114.28694200000001,78.06608600000004],[-114.07305899999994,77.98165900000004]],[[-109.58805799999999,78.06469700000002],[-109.58056599999998,78.0583190000001],[-109.58112299999988,78.0413670000001],[-109.58528100000001,78.03553800000009],[-109.66972399999997,77.97164900000013],[-109.68305999999995,77.96582000000012],[-109.70556599999986,77.95999100000012],[-109.76027699999997,77.95109600000006],[-109.81527699999992,77.9427490000001],[-109.84249899999998,77.938873],[-109.89750699999996,77.93275500000004],[-110.00723299999987,77.92137100000014],[-110.14499699999999,77.91192600000011],[-110.162781,77.90693699999997],[-110.16665599999999,77.90109300000012],[-110.19611399999991,77.89665200000002],[-110.22112299999998,77.8938750000001],[-110.24889399999995,77.8938750000001],[-110.48999000000003,77.88388100000009],[-110.62666300000001,77.87303200000002],[-110.65416700000003,77.87191800000005],[-110.79250299999995,77.8708190000001],[-110.846947,77.86637900000005],[-110.873894,77.86219800000015],[-110.89584400000001,77.85609399999993],[-110.90139799999992,77.849716],[-110.90471600000001,77.84387200000015],[-110.90360999999996,77.83804299999997],[-110.90028399999994,77.832764],[-110.89444699999996,77.82693499999999],[-110.88639799999987,77.82083100000011],[-110.74388099999993,77.77360500000009],[-110.71556099999992,77.76887500000004],[-110.65888999999999,77.75972000000002],[-110.63110399999994,77.75804099999999],[-110.60138699999999,77.75888100000003],[-110.51972999999992,77.76332100000002],[-110.41583299999996,77.770828],[-110.39306599999986,77.77304100000015],[-110.368607,77.77638199999996],[-110.28916899999996,77.782486],[-110.16111799999999,77.78414900000013],[-110.13305700000001,77.78054800000007],[-110.10500299999995,77.77499400000005],[-110.09028599999994,77.76915000000008],[-110.08029199999993,77.76332100000002],[-110.04055800000003,77.637497],[-110.08029199999993,77.56359900000007],[-110.08416699999992,77.55775500000004],[-110.09221599999995,77.55192600000004],[-110.11749299999997,77.53997800000002],[-110.20333899999997,77.51138300000014],[-110.22501399999987,77.50526400000012],[-110.27055399999995,77.49581900000004],[-110.29695100000004,77.49165299999999],[-110.502228,77.46026600000005],[-110.81500199999999,77.42498800000004],[-110.82749899999999,77.41914400000002],[-110.85082999999992,77.41442899999998],[-110.87721299999998,77.41137700000007],[-110.95639,77.407486],[-111.00974299999996,77.40609699999999],[-111.06527699999998,77.40609699999999],[-111.11721799999992,77.40887499999997],[-111.172234,77.4160920000001],[-111.29998799999993,77.41914400000002],[-111.46305799999999,77.39305100000007],[-111.61833200000001,77.37387100000012],[-111.82501199999996,77.34887700000013],[-112.031113,77.3247070000001],[-112.05722000000003,77.32331799999992],[-112.083618,77.32304399999998],[-112.13694800000002,77.32331799999992],[-112.16639700000002,77.32527199999998],[-112.41306299999997,77.35609400000004],[-112.43888900000002,77.36109900000008],[-112.48222399999992,77.37109400000003],[-112.5,77.37823500000002],[-112.50778200000002,77.38136300000002],[-112.52139299999999,77.38943499999999],[-112.52333099999993,77.395264],[-112.526947,77.39971900000006],[-112.545547,77.41581700000006],[-112.587784,77.44914199999994],[-112.60109699999992,77.45526100000001],[-112.626938,77.45942700000006],[-112.65387699999997,77.45887800000014],[-112.68222000000003,77.45693999999997],[-112.69721999999996,77.45526100000001],[-112.73889200000002,77.4458160000001],[-112.764183,77.44165000000004],[-112.79083300000002,77.4410860000001],[-112.80249000000003,77.442474],[-112.92887899999994,77.46415700000011],[-112.95777899999996,77.46943699999997],[-112.96389799999992,77.474152],[-112.96806299999992,77.48580900000013],[-112.96806299999992,77.49220300000002],[-112.97028399999999,77.49803200000002],[-112.978882,77.50332600000002],[-112.99445300000002,77.50888100000009],[-113.01167299999997,77.51277199999998],[-113.03751399999999,77.51582300000001],[-113.06500199999999,77.51721199999997],[-113.14611799999994,77.51776100000012],[-113.17388900000003,77.51944000000015],[-113.198036,77.52388000000013],[-113.20472699999999,77.52943399999998],[-113.23805199999998,77.58137500000004],[-113.24027999999993,77.58720400000004],[-113.16251399999993,77.60914600000012],[-113.1875,77.73942600000004],[-113.20556599999998,77.74443100000008],[-113.26251200000002,77.75555400000007],[-113.283073,77.76110800000009],[-113.29444899999999,77.766663],[-113.30387899999994,77.77304100000015],[-113.31054699999993,77.77859500000011],[-113.31500199999994,77.78387500000002],[-113.31973299999999,77.79553199999992],[-113.31973299999999,77.80720499999995],[-113.31749699999995,77.81303399999996],[-113.30638099999993,77.83720399999999],[-113.23473399999989,77.90165700000006],[-113.23082699999992,77.903595],[-113.20973200000003,77.90887500000008],[-113.12721299999998,77.9122010000001],[-113.09973100000002,77.91276600000015],[-113.07167099999998,77.9122010000001],[-113.04666099999997,77.90776100000011],[-113.03971899999999,77.9019320000001],[-112.943604,77.91192600000011],[-112.80499299999985,77.933044],[-112.78333299999997,77.93719500000009],[-112.766663,77.94247400000006],[-112.74194299999988,77.95166],[-112.57444799999996,77.97943100000009],[-112.46694899999994,77.99247700000001],[-112.29499800000002,78.0105440000001],[-112.12526699999995,78.00610400000005],[-111.97944599999994,78.01859999999999],[-111.787216,78.03359999999992],[-111.77610800000002,78.02804600000013],[-111.756393,78.024429],[-111.73055999999997,78.02415500000006],[-111.70556599999998,78.02693199999999],[-111.63221699999991,78.04081700000006],[-111.34583999999995,78.0769350000001],[-111.31833599999999,78.08027600000014],[-111.28832999999997,78.08194000000015],[-111.09333800000002,78.09248400000001],[-111.048607,78.0935970000001],[-111.02749599999999,78.093323],[-110.99861099999993,78.09054600000007],[-110.99749799999995,78.08471700000007],[-111.00110599999994,78.07998700000002],[-110.995003,78.07415800000001],[-110.903343,78.06219499999997],[-110.861107,78.061646],[-110.83306899999997,78.06303400000013],[-110.80555700000002,78.06526200000008],[-110.78778099999994,78.0711060000001],[-110.77500899999995,78.0769350000001],[-110.77139299999999,78.08276400000011],[-110.76334399999996,78.08888200000007],[-110.74553700000001,78.09471100000007],[-110.72721899999988,78.09776299999999],[-110.67051700000002,78.101089],[-110.54998799999998,78.1060940000001],[-110.46584299999995,78.10859700000003],[-110.23777799999999,78.11080900000013],[-110.10082999999992,78.10859700000003],[-109.95916699999987,78.10470599999996],[-109.78916899999996,78.09971600000011],[-109.67777999999998,78.09193399999998],[-109.65387699999985,78.08831800000013],[-109.60527000000002,78.0711060000001],[-109.58805799999999,78.06469700000002]],[[-101.65139799999997,78.14471400000002],[-101.67527799999999,78.14444000000009],[-101.859444,78.15525800000006],[-101.87917299999992,78.15832499999999],[-101.88194299999998,78.16220100000004],[-101.77610800000002,78.21638500000012],[-101.75334199999992,78.22720300000009],[-101.73137700000001,78.23248300000012],[-101.70722999999987,78.23275799999999],[-101.68472299999996,78.230545],[-101.68167099999994,78.22747800000008],[-101.67250100000001,78.22608900000012],[-101.633621,78.21081500000003],[-101.62277199999988,78.20471200000009],[-101.61582899999996,78.19941699999998],[-101.60360700000001,78.18748500000004],[-101.59999099999993,78.18109099999998],[-101.59861799999993,78.17526199999998],[-101.59973100000002,78.16442900000004],[-101.60527000000002,78.15914900000013],[-101.61305199999998,78.15359499999994],[-101.62581599999993,78.14804100000015],[-101.65139799999997,78.14471400000002]],[[-103.05695300000002,78.11970500000007],[-103.11444099999994,78.11775200000011],[-103.19444299999992,78.11914100000007],[-103.212784,78.12052900000003],[-103.23029300000002,78.12387100000012],[-103.25862099999995,78.134995],[-103.27027900000002,78.14109799999994],[-103.277222,78.14694199999997],[-103.28222700000003,78.15776100000005],[-103.27971600000001,78.16360500000008],[-103.274719,78.169983],[-103.26750199999998,78.17553700000002],[-103.23916600000001,78.19220000000007],[-103.22721899999993,78.19775400000009],[-103.17027300000001,78.21998599999995],[-103.12471,78.23664900000006],[-103.06276700000001,78.25804100000005],[-103.04138199999994,78.26361099999997],[-102.98693800000001,78.27276599999999],[-102.93415800000002,78.27276599999999],[-102.89750700000002,78.26914999999997],[-102.82556199999993,78.25888100000009],[-102.8125,78.255829],[-102.79860699999995,78.25027499999999],[-102.78916899999996,78.24443100000002],[-102.78222700000003,78.23858600000005],[-102.78028899999993,78.23275799999999],[-102.77639799999986,78.21554600000013],[-102.77639799999986,78.21026600000005],[-102.781387,78.20498700000007],[-102.79332699999998,78.19941699999998],[-102.85527000000002,78.18887299999994],[-102.89806399999992,78.17804000000001],[-102.93195300000002,78.16693100000009],[-102.97721899999999,78.1502690000001],[-103.01777599999997,78.13360600000004],[-103.04167199999995,78.122208],[-103.05695300000002,78.11970500000007]],[[-94.36665299999999,78.15914900000013],[-94.37805199999997,78.15776100000005],[-94.40444899999994,78.15998800000011],[-94.50611899999996,78.1727600000001],[-94.52000399999986,78.17747500000013],[-94.67111199999988,78.24081400000006],[-94.68306000000001,78.24720800000006],[-94.69415299999991,78.2586060000001],[-94.69221500000003,78.26470900000004],[-94.68110699999988,78.27415500000001],[-94.66082799999992,78.27916000000005],[-94.63555899999994,78.28387500000008],[-94.60221899999999,78.28720099999992],[-94.57223499999992,78.28776600000015],[-94.54638699999998,78.28442400000006],[-94.51501499999989,78.27804600000007],[-94.48194899999993,78.268326],[-94.36111499999987,78.22164900000007],[-94.34472699999998,78.21470600000009],[-94.316666,78.19747900000004],[-94.30943300000001,78.1910860000001],[-94.30694599999993,78.18498200000005],[-94.30915799999997,78.17915300000004],[-94.36665299999999,78.15914900000013]],[[-88.28721599999994,78.24331699999999],[-88.36000100000001,78.23776199999992],[-88.38194299999998,78.24247699999995],[-88.39361600000001,78.24887100000001],[-88.40472399999999,78.25999500000006],[-88.40750099999991,78.2644350000001],[-88.41111799999993,78.27387999999996],[-88.40972899999997,78.29220599999996],[-88.404449,78.29803500000003],[-88.23527499999989,78.42692599999998],[-88.11305199999998,78.45526099999995],[-88.09445199999999,78.45694000000015],[-88.07028199999996,78.45471200000003],[-88.06138599999991,78.45248400000008],[-88.05277999999993,78.44552600000009],[-88.04972800000002,78.44442700000008],[-88.04333499999996,78.43664600000005],[-88.04444899999993,78.42442299999999],[-88.04499799999996,78.42137100000008],[-88.04666099999997,78.41886899999997],[-88.05722000000003,78.40748599999995],[-88.16639699999996,78.30802900000003],[-88.18777499999999,78.29165599999993],[-88.245544,78.2527770000001],[-88.25500499999998,78.24720800000006],[-88.28721599999994,78.24331699999999]],[[-109.64806399999992,78.58804299999997],[-109.569458,78.58638000000008],[-109.54998799999998,78.58665500000006],[-109.50055700000001,78.582764],[-109.40527299999997,78.55693100000008],[-109.33416699999998,78.52415500000012],[-109.26055899999994,78.48719800000009],[-109.25556899999998,78.48248300000006],[-109.254997,78.47859199999999],[-109.26055899999994,78.455826],[-109.31806899999992,78.35803199999998],[-109.32721700000002,78.35220300000015],[-109.40499899999992,78.30636600000008],[-109.42859599999997,78.303314],[-109.59583999999995,78.30276500000002],[-109.766953,78.29414400000013],[-109.82444799999996,78.29386900000009],[-109.85333300000002,78.29664600000001],[-109.882767,78.30137600000006],[-109.89306599999998,78.30720500000007],[-109.89835399999998,78.3119200000001],[-109.90862299999998,78.31776400000007],[-109.92610200000001,78.32304399999998],[-109.95527599999997,78.32582100000008],[-109.98388699999998,78.32554600000003],[-110.01251200000002,78.32360800000009],[-110.19638099999997,78.30386400000003],[-110.22444199999995,78.29998799999993],[-110.25250199999999,78.29582200000004],[-110.279449,78.284988],[-110.29778299999992,78.2810970000001],[-110.354446,78.27665700000006],[-110.4119419999999,78.27720600000004],[-110.484734,78.28442400000006],[-110.57167099999992,78.28970300000003],[-110.65833999999995,78.29304500000012],[-110.71556099999992,78.29248000000013],[-110.78778099999994,78.30693100000013],[-110.85665899999987,78.32720899999998],[-110.85888699999998,78.3377690000001],[-110.97501399999999,78.363876],[-111.00250199999999,78.36804200000006],[-111.14138799999995,78.38610800000004],[-111.16999799999996,78.38415500000008],[-111.27778599999994,78.37220799999994],[-111.27139299999999,78.34610000000004],[-111.30610699999994,78.32110600000004],[-111.41000400000001,78.27720600000004],[-111.42304999999993,78.27221700000007],[-111.43888899999996,78.2686000000001],[-111.46250899999995,78.26748700000002],[-111.50527999999997,78.26693699999998],[-111.57556199999999,78.27053800000004],[-111.65249599999993,78.27276599999999],[-111.73832700000003,78.27276599999999],[-111.76666299999994,78.27137800000008],[-111.79527299999995,78.2711030000001],[-111.82000700000003,78.27360499999998],[-111.86472300000003,78.29637099999997],[-111.88221699999997,78.30693100000013],[-111.88861099999997,78.3124850000001],[-111.89277599999997,78.31805400000013],[-111.89167800000001,78.32222000000002],[-111.91861,78.33276400000005],[-111.939438,78.33831800000007],[-112.13305700000001,78.36554000000001],[-112.21501199999994,78.36526500000014],[-112.43776700000001,78.35443100000009],[-112.58306899999997,78.34359700000005],[-112.68443299999996,78.33137500000004],[-112.73916599999995,78.32304399999998],[-112.78721599999989,78.31053199999997],[-112.89083900000003,78.29248000000013],[-112.94499199999996,78.28387500000008],[-113.026947,78.27276599999999],[-113.05499299999997,78.27137800000008],[-113.14222699999999,78.268326],[-113.16860999999994,78.2686000000001],[-113.18831599999999,78.26998900000012],[-113.21777299999985,78.27777100000003],[-113.27333099999998,78.29637099999997],[-113.28195199999999,78.29971300000011],[-113.287781,78.30247500000002],[-113.33249699999993,78.32887299999999],[-113.33416699999998,78.33276400000005],[-113.21611000000001,78.38526900000011],[-113.1241609999999,78.4208220000001],[-113.11527999999987,78.42303500000008],[-113.03832999999997,78.43691999999999],[-112.71167000000003,78.48471100000006],[-112.60749800000002,78.4994200000001],[-112.36305199999998,78.53332499999999],[-112.31166100000002,78.53997799999996],[-112.23805199999998,78.547211],[-112.12970699999994,78.55192600000004],[-111.98805199999987,78.55276499999997],[-111.90360999999996,78.54887400000007],[-111.87304699999999,78.54443400000008],[-111.85305800000003,78.54275500000006],[-111.8097229999999,78.54525800000005],[-111.75250199999994,78.55053700000002],[-111.67777999999993,78.56303400000002],[-111.641953,78.57415800000007],[-111.60082999999997,78.5852660000001],[-111.57224299999996,78.588593],[-111.45556599999998,78.592758],[-111.39195299999994,78.61192299999999],[-111.378601,78.617752],[-111.3799899999999,78.62275700000004],[-111.36305199999998,78.64276099999995],[-111.160553,78.69164999999992],[-110.95612299999993,78.71832300000011],[-110.79110700000001,78.73525999999993],[-110.6375119999999,78.74859600000008],[-110.46028100000001,78.75749200000001],[-110.43055700000002,78.75860599999999],[-110.410553,78.757767],[-110.39527900000002,78.75610400000011],[-110.3844529999999,78.75138900000007],[-110.271118,78.72776800000003],[-110.16416900000002,78.70915199999996],[-110.07778899999988,78.69497700000005],[-109.99722300000002,78.68386800000002],[-109.86165599999998,78.66693099999998],[-109.85582699999998,78.66026299999999],[-109.86000100000001,78.65443399999998],[-109.86165599999998,78.64915500000001],[-109.86110699999995,78.643326],[-109.85526999999996,78.637497],[-109.67054699999989,78.5913700000001],[-109.64806399999992,78.58804299999997]],[[-74.30694599999998,78.67665100000005],[-74.33416699999992,78.67526200000009],[-74.36721799999998,78.67608600000005],[-74.41944899999999,78.68165599999992],[-74.61416600000001,78.70277400000003],[-74.70472699999993,78.72276299999993],[-74.71000700000002,78.72747799999996],[-74.71028100000001,78.73109400000004],[-74.70666499999999,78.7374880000001],[-74.64500399999997,78.77249100000006],[-74.63221699999997,78.77720600000009],[-74.61582900000002,78.77859500000011],[-74.59110999999996,78.7788700000001],[-74.55555700000002,78.776093],[-74.35694899999993,78.75582900000006],[-74.31204200000002,78.75000000000006],[-74.28195199999999,78.74609400000003],[-74.19248999999996,78.72970599999996],[-74.16777000000002,78.71998600000006],[-74.16361999999992,78.716095],[-74.17277499999989,78.71138000000013],[-74.23638899999997,78.68719499999992],[-74.25666799999993,78.6827550000001],[-74.28443900000002,78.67886400000003],[-74.30694599999998,78.67665100000005]],[[-96.76806599999998,78.684143],[-96.70889299999999,78.6827550000001],[-96.64500399999997,78.68609600000013],[-96.61305199999998,78.68553200000002],[-96.58500700000002,78.68331900000004],[-96.53361499999994,78.6769260000001],[-96.510559,78.672485],[-96.46639999999996,78.66192600000011],[-96.39527900000002,78.64054900000008],[-96.379166,78.63443000000007],[-96.35610999999994,78.62776200000008],[-96.31582600000002,78.618042],[-96.29388399999993,78.61526500000008],[-96.265015,78.61886600000014],[-96.23554999999999,78.62776200000008],[-96.20249899999988,78.63026400000001],[-96.18443299999996,78.62858600000004],[-96.16749599999997,78.62330600000001],[-96.15888999999987,78.61720300000007],[-96.15249599999999,78.61137400000001],[-96.21640000000002,78.56053199999997],[-96.17805499999992,78.5188750000001],[-96.00944500000003,78.49247700000012],[-95.85777300000001,78.49498000000006],[-95.82000699999992,78.5022130000001],[-95.74665800000002,78.51499899999999],[-95.71665999999999,78.51971400000002],[-95.68472300000002,78.52110300000004],[-95.652222,78.52137800000003],[-95.601944,78.51971400000002],[-95.53721599999994,78.51470899999998],[-95.481674,78.50888100000003],[-95.40777599999996,78.49720800000006],[-95.20638999999994,78.46165500000001],[-95.08694499999996,78.43775900000009],[-94.89500399999997,78.39582800000011],[-94.87777699999992,78.3913730000001],[-94.86082499999992,78.38472000000013],[-94.83167999999995,78.36469999999997],[-94.82917799999996,78.35887100000014],[-94.83084099999991,78.35276799999997],[-94.83750899999995,78.34721400000001],[-94.8533329999999,78.3419340000001],[-94.94193999999999,78.31637599999999],[-94.96694899999994,78.31137100000012],[-95.09638999999993,78.29026800000003],[-95.36361699999992,78.24136400000009],[-95.38806199999993,78.23637400000001],[-95.39917000000003,78.23109399999998],[-95.39862099999999,78.22692899999998],[-95.38890099999998,78.22248800000006],[-95.36888099999999,78.21859699999999],[-95.34583999999995,78.217758],[-95.25527999999991,78.21804800000001],[-95.22749299999998,78.2166600000001],[-95.130829,78.19413800000001],[-95.11305199999993,78.18858300000011],[-95.10694899999999,78.18525700000009],[-95.108612,78.17942800000009],[-95.11193799999995,78.17414900000011],[-95.11193799999995,78.16748000000001],[-95.10610999999994,78.16192600000005],[-95.089722,78.15498400000013],[-95.06806899999992,78.14804100000015],[-94.98332199999993,78.13304099999999],[-94.90695199999999,78.11720300000013],[-94.88999899999999,78.10887099999997],[-94.88694799999996,78.10276800000003],[-94.91166699999985,78.055252],[-95.01139799999999,77.99136399999992],[-95.04388399999993,77.97499100000005],[-95.0574949999999,77.96914700000008],[-95.08528099999995,77.95887800000003],[-95.10055499999993,77.95359799999994],[-95.112503,77.95138500000002],[-95.13751199999996,77.95054600000003],[-95.16250600000001,77.95359799999994],[-95.18638599999986,77.95776400000005],[-95.21167000000003,77.96110500000009],[-95.23693800000001,77.964157],[-95.26583899999997,77.96609500000011],[-95.321396,77.96775800000006],[-95.37998999999996,77.96638499999995],[-95.400284,77.9627690000001],[-95.41332999999986,77.95942699999995],[-95.42555199999993,77.94802900000013],[-95.44972200000001,77.9433140000001],[-95.54972800000002,77.934143],[-95.75805700000001,77.91192600000011],[-95.83084099999996,77.89888000000013],[-95.93859900000001,77.88581799999997],[-96.18943799999994,77.86608900000004],[-96.28555299999994,77.85942100000005],[-96.31750499999993,77.8583220000001],[-96.345551,77.85859700000009],[-96.36527999999998,77.859985],[-96.386124,77.86276200000009],[-96.40417499999995,77.8685910000001],[-96.41194200000001,77.87498499999998],[-96.41082799999992,77.88081399999999],[-96.40527299999997,77.88638299999997],[-96.410553,77.89054900000008],[-96.416946,77.8938750000001],[-96.43582200000003,77.89860499999998],[-96.45666499999999,77.90165700000006],[-96.54110700000001,77.89721700000007],[-96.73443600000002,77.87275700000004],[-96.73500099999995,77.86692800000003],[-96.710556,77.855545],[-96.69638099999992,77.85081500000013],[-96.66722099999993,77.84915200000006],[-96.58500700000002,77.85636899999997],[-96.55888400000003,77.85942100000005],[-96.53971899999999,77.8644260000001],[-96.51611300000002,77.86943099999996],[-96.49166899999989,77.87025499999993],[-96.51556399999998,77.8455350000001],[-96.54277000000002,77.84193400000004],[-96.62832599999996,77.84054600000013],[-96.68720999999988,77.84054600000013],[-96.71166999999997,77.83970600000009],[-96.73416099999997,77.83554100000009],[-96.74861099999993,77.83027600000003],[-96.82945299999994,77.789154],[-96.84999099999999,77.78720100000004],[-96.88055399999996,77.78692600000005],[-96.900284,77.78831500000001],[-96.90777600000001,77.79054299999996],[-96.912216,77.79304500000006],[-96.93388400000003,77.79748500000005],[-97.01417499999997,77.80415300000004],[-97.05749500000002,77.80554200000006],[-97.07250999999991,77.80415300000004],[-97.09695399999993,77.80331400000006],[-97.10221899999999,77.80748],[-97.11972000000003,77.86526500000008],[-97.11999499999996,77.87025499999993],[-97.10749799999996,77.87637300000006],[-97.08138999999994,77.88665800000001],[-97.01556399999998,77.90416000000005],[-97.002228,77.90860000000004],[-96.99221799999998,77.91415400000005],[-96.99249299999991,77.91886900000009],[-96.99499500000002,77.92109700000003],[-97.14277599999997,77.9349820000001],[-97.28167699999995,77.94831800000009],[-97.30999799999995,77.95109600000006],[-97.354446,77.96220400000004],[-97.38027999999997,77.969986],[-97.431671,77.98692300000005],[-97.45472699999993,77.99275200000005],[-97.50306699999987,78.00248699999992],[-97.57223499999998,78.01249700000005],[-97.60278299999993,78.01554899999996],[-97.67361499999998,78.02137800000014],[-97.75556899999998,78.02554299999997],[-97.766953,78.0288700000001],[-97.77555799999999,78.03498800000006],[-97.666946,78.08804300000008],[-97.64778100000001,78.09082000000001],[-97.61833199999995,78.09166000000005],[-97.56750499999993,78.08970600000004],[-97.51306199999999,78.08665500000001],[-97.43249499999996,78.08055100000013],[-97.323624,78.0769350000001],[-97.297775,78.07638500000007],[-97.0244449999999,78.07470699999993],[-96.997772,78.07527199999998],[-96.910278,78.07916300000005],[-96.88751199999996,78.08305400000012],[-96.85555999999991,78.10415599999993],[-96.85638399999999,78.10803200000004],[-96.870544,78.133331],[-96.88555899999994,78.13804600000003],[-96.98388699999992,78.15081800000007],[-97.05915799999997,78.15776100000005],[-97.13806199999993,78.16581700000012],[-97.164444,78.16886900000003],[-97.18472299999996,78.17248500000011],[-97.19499200000001,78.17692599999998],[-97.20083599999992,78.18359399999997],[-97.21250900000001,78.18942299999998],[-97.29943800000001,78.20471200000009],[-97.32112099999995,78.20748899999995],[-97.34916699999997,78.20860299999998],[-97.40777600000001,78.207764],[-97.63555899999994,78.20665000000002],[-97.829453,78.21914700000002],[-97.84944199999995,78.23471100000012],[-97.81750499999998,78.23275799999999],[-97.773056,78.23887600000012],[-97.76333599999992,78.24443100000002],[-97.77778599999988,78.25],[-97.86776699999996,78.27970900000003],[-97.881104,78.28360000000009],[-97.90417500000001,78.28804000000008],[-97.93055700000002,78.290817],[-98.01278699999995,78.29693600000002],[-98.05471799999992,78.30165100000005],[-98.06834399999997,78.30802900000003],[-98.07084699999996,78.31359900000007],[-98.04361,78.38943499999999],[-98.14834599999995,78.4038700000001],[-98.17222600000002,78.40498400000007],[-98.19833399999999,78.40859999999998],[-98.347778,78.443039],[-98.36665299999999,78.44941699999998],[-98.38806199999999,78.46748400000001],[-98.410553,78.49026500000002],[-98.41139199999992,78.4952550000001],[-98.41027799999995,78.50804099999999],[-98.30888400000003,78.53387500000002],[-98.17138699999998,78.52970900000014],[-98.05444299999999,78.53360000000004],[-98.02223199999992,78.53637700000013],[-98.01916499999999,78.54275500000006],[-98.02806099999992,78.563309],[-98.04222099999993,78.56971699999997],[-98.08000199999992,78.582764],[-98.115005,78.59387199999998],[-98.13999899999999,78.599426],[-98.16915899999992,78.60304300000013],[-98.23500100000001,78.61914100000001],[-98.31527699999992,78.64387499999998],[-98.32695000000001,78.65054299999991],[-98.32806399999993,78.65220600000004],[-98.37165800000002,78.71998600000006],[-98.366104,78.76361100000003],[-98.36471599999993,78.76805100000007],[-98.17332499999992,78.81275900000014],[-98.144455,78.81666600000011],[-98.06138599999997,78.81887799999998],[-97.77778599999988,78.81526200000008],[-97.65695199999999,78.81137100000001],[-97.59973100000002,78.80747999999994],[-97.48860200000001,78.79664600000007],[-97.46194500000001,78.792755],[-97.43693499999989,78.786926],[-97.385559,78.77693199999999],[-97.35916099999997,78.77304100000009],[-97.27362099999999,78.76443499999999],[-97.160278,78.75888100000003],[-97.07806399999998,78.74971000000005],[-97.02528399999994,78.74192800000009],[-96.99972500000001,78.73692300000005],[-96.95472699999993,78.72637900000001],[-96.92250099999995,78.71331800000007],[-96.91389500000002,78.70694000000009],[-96.90388499999995,78.70166000000006],[-96.88639799999999,78.69664],[-96.76806599999998,78.684143]],[[-86.319458,78.88360600000004],[-86.38806199999988,78.88304100000005],[-86.41471899999993,78.88443000000001],[-86.44444299999998,78.8872070000001],[-86.46916199999993,78.88970899999998],[-86.48443600000002,78.89276100000012],[-86.47694399999989,78.89637800000008],[-86.43638599999997,78.91110200000008],[-86.38667299999997,78.9249880000001],[-86.366104,78.92970300000013],[-86.346115,78.93969700000014],[-86.32861300000002,78.95082100000002],[-86.29277000000002,78.98304700000011],[-86.28527799999995,78.99331700000005],[-86.28361499999994,78.99803200000008],[-86.04695100000004,79.03858900000006],[-85.99082899999996,79.04693600000007],[-85.92443799999995,79.05386400000003],[-85.89611799999994,79.05693100000013],[-85.82000700000003,79.06137100000001],[-85.71250900000001,79.06414800000005],[-85.646118,79.06442300000009],[-85.32139599999994,79.05386400000003],[-85.26333599999992,79.04887400000001],[-85.2161099999999,79.04136700000004],[-85.19972200000001,79.03749099999999],[-85.18249500000002,79.03137200000015],[-85.16722099999993,79.02082800000011],[-85.16944899999999,79.01470900000004],[-85.17639199999996,79.00888099999997],[-85.18666100000002,79.0027770000001],[-85.20944199999991,78.99359099999998],[-85.22582999999997,78.98858600000011],[-85.24694799999997,78.98414600000007],[-85.30139200000002,78.97526600000003],[-85.46611000000001,78.958328],[-85.54666099999997,78.95248400000014],[-85.76556399999998,78.93414300000012],[-86.026947,78.91026299999999],[-86.21389799999997,78.89166300000005],[-86.24499500000002,78.88832100000008],[-86.28416399999998,78.885269],[-86.319458,78.88360600000004]],[[-103.59388699999988,79.32582100000002],[-103.39835399999993,79.2999880000001],[-103.33556399999998,79.2999880000001],[-103.26251200000002,79.2999880000001],[-103.13999899999993,79.28776600000015],[-103.09777799999995,79.28248600000006],[-103.08361799999994,79.27943399999998],[-103.06806899999992,79.27388000000013],[-102.921112,79.21748400000007],[-102.92666600000001,79.21110500000003],[-102.92639199999996,79.20664999999997],[-102.921944,79.20027200000004],[-102.90194699999995,79.17221100000012],[-102.89167800000001,79.16665600000005],[-102.87444299999987,79.16499299999992],[-102.76862299999993,79.13888499999996],[-102.620003,79.09721400000001],[-102.61165599999998,79.09304800000012],[-102.60582699999998,79.07443200000012],[-102.60637700000001,79.06805400000013],[-102.612213,79.05664100000013],[-102.654449,78.99414100000001],[-102.66555799999998,78.98275799999999],[-102.67582700000003,78.97747800000013],[-102.69860799999992,78.97192400000012],[-102.72084000000001,78.93830900000006],[-102.59500099999997,78.87664800000005],[-102.57945299999994,78.87303200000002],[-102.56082200000003,78.86970500000007],[-102.55082700000003,78.86943100000013],[-102.52887699999985,78.87303200000002],[-102.39195299999994,78.93165600000009],[-102.37638900000002,78.94636500000013],[-102.38054699999998,78.9627690000001],[-102.39806399999992,78.98719800000003],[-102.36305199999998,79.0149990000001],[-102.27944899999989,79.01805100000001],[-102.09361299999989,79.04414400000013],[-102.04943799999995,79.05442799999997],[-102.01500699999997,79.06498700000003],[-101.99333199999995,79.07609600000012],[-101.975281,79.08082599999994],[-101.942207,79.08471700000001],[-101.90249599999993,79.08638000000013],[-101.88194299999998,79.08610499999992],[-101.64890299999996,79.07582100000008],[-101.62805200000003,79.07193000000001],[-101.54194599999994,79.04470800000007],[-101.5202789999999,79.03831500000013],[-101.30803699999996,78.97581500000001],[-101.23166699999996,78.95942700000012],[-101.20472699999999,78.954163],[-101.17666600000001,78.95387299999993],[-101.15222199999988,78.95665000000002],[-101.14334100000002,78.96249400000005],[-101.14472999999992,78.96832300000005],[-101.14083900000003,78.97415200000006],[-101.09388699999994,78.96360800000002],[-101.00556899999998,78.94303900000006],[-100.98665599999998,78.93719500000009],[-100.98528299999998,78.93136600000003],[-101.11694299999988,78.85693400000014],[-101.15278599999999,78.83998100000008],[-101.19304699999992,78.82443199999994],[-101.20056199999999,78.82083100000011],[-101.20333899999997,78.81581100000005],[-101.20084399999996,78.81191999999999],[-101.186394,78.80276500000014],[-101.17278299999998,78.80053700000013],[-100.99194299999999,78.78887900000012],[-100.86389199999991,78.78137200000003],[-100.83056599999992,78.78970300000009],[-100.80055199999998,78.79332000000005],[-100.70556599999998,78.799713],[-100.61389200000002,78.79803500000008],[-100.587784,78.79914900000006],[-100.55915799999997,78.80442800000003],[-100.55027799999993,78.80998200000005],[-100.53639199999998,78.81553600000001],[-100.52443700000003,78.81805400000002],[-100.35109699999998,78.82832300000001],[-100.34445199999993,78.82666000000012],[-100.32389799999999,78.80220000000008],[-100.32250999999997,78.79721100000012],[-100.33249699999993,78.782761],[-100.32333399999993,78.77804600000013],[-100.283073,78.76776100000006],[-100.22778299999993,78.7605440000001],[-100.14334099999996,78.75221300000004],[-100.12416100000002,78.75000000000006],[-100.03250099999997,78.73942600000004],[-100.004997,78.73580900000007],[-99.95249899999999,78.72554000000002],[-99.93638599999997,78.71998600000006],[-99.89639299999993,78.69581600000004],[-99.89388999999994,78.69303900000011],[-99.89306599999998,78.6869200000001],[-99.91332999999992,78.67970300000002],[-99.97277799999995,78.659988],[-100.0625,78.63888500000007],[-100.0625,78.63554400000004],[-100.01666299999988,78.61665300000004],[-99.98889199999991,78.61387600000012],[-99.96305799999999,78.61499000000009],[-99.90972899999997,78.62387100000001],[-99.85333299999996,78.63304100000005],[-99.81750499999993,78.630539],[-99.573624,78.5955350000001],[-99.55027799999988,78.59027100000014],[-99.53332499999999,78.58360299999998],[-99.52972399999999,78.57804899999996],[-99.53416400000003,78.57222000000013],[-99.66111799999993,78.48553500000003],[-99.6702729999999,78.47970600000002],[-99.68415799999997,78.47442600000011],[-99.71250899999995,78.46943699999997],[-99.777222,78.46138000000002],[-99.83139,78.45082100000013],[-99.85943600000002,78.44220000000001],[-99.86776700000001,78.43748499999998],[-99.865005,78.43441800000005],[-99.821396,78.42747500000007],[-99.80139199999996,78.4208220000001],[-99.78666699999997,78.41470300000009],[-99.77667200000002,78.40859999999998],[-99.761124,78.39637800000014],[-99.75361599999991,78.3897090000001],[-99.74833699999999,78.38360599999999],[-99.74916099999996,78.3724820000001],[-99.77860999999996,78.33221400000002],[-99.79777499999994,78.30859400000003],[-99.79943799999995,78.303314],[-99.79388399999988,78.29721100000006],[-99.77583299999998,78.29248000000013],[-99.74137899999994,78.28997800000002],[-99.67304999999999,78.290817],[-99.62054399999994,78.29026800000003],[-99.55110200000001,78.28610200000014],[-99.529449,78.28248600000006],[-99.51445000000001,78.27720600000004],[-99.47972099999998,78.24914600000005],[-99.447769,78.22415200000006],[-99.42832900000002,78.21165500000006],[-99.41389499999997,78.20526100000001],[-99.39862099999999,78.19999700000005],[-99.18859900000001,78.13304099999999],[-98.98916600000001,78.07304400000004],[-98.96916199999993,78.068329],[-98.94583099999988,78.061646],[-98.94583099999988,78.05581699999999],[-98.96278399999994,78.00915500000008],[-98.97166399999998,77.99775700000009],[-98.98083499999996,77.99220300000007],[-98.99888599999991,77.98692300000005],[-99.02166699999987,77.98165900000004],[-99.08111599999995,77.97192399999994],[-99.09472700000003,77.96638499999995],[-99.09916699999997,77.96081500000008],[-99.09889199999992,77.95498700000013],[-99.0786129999999,77.92553700000008],[-99.06916799999999,77.91360500000008],[-99.04138199999994,77.90081800000007],[-99.02278100000001,77.89444000000015],[-99.01333599999998,77.88832100000013],[-99.02223199999997,77.88247700000011],[-99.23805199999998,77.83776900000004],[-99.39666699999998,77.82415800000007],[-99.525284,77.81359900000001],[-99.54943800000001,77.81248500000004],[-99.71305799999993,77.81080600000001],[-99.853882,77.79220600000008],[-99.85943600000002,77.78692600000005],[-99.87693799999994,77.78137200000003],[-99.90695199999999,77.77859500000011],[-100.21000699999996,77.80998200000005],[-100.32972699999999,77.82527200000004],[-100.49889399999995,77.85165400000011],[-100.60637699999995,77.87997400000012],[-100.75527999999997,77.95555100000007],[-100.78611799999999,77.97415200000012],[-100.81749699999995,77.99914600000005],[-100.82389799999999,78.00444000000005],[-100.83833299999998,78.02276600000005],[-100.83778399999994,78.03498800000006],[-100.83693700000003,78.04026800000008],[-100.83444199999991,78.04414399999996],[-100.82694999999995,78.04887400000001],[-100.853882,78.09664900000001],[-100.87581599999999,78.09999099999993],[-100.99861099999998,78.13165300000009],[-101.00974300000001,78.13665800000012],[-101.02194199999991,78.1477660000001],[-101.01889,78.15693700000008],[-101.01528899999994,78.16276600000009],[-101.01363399999997,78.17359900000008],[-101.01390100000003,78.18470799999994],[-101.02027900000002,78.18969700000008],[-101.035553,78.19609100000014],[-101.06276699999995,78.19859300000002],[-101.089447,78.19802900000008],[-101.23137700000001,78.18386800000007],[-101.28943599999997,78.18248],[-101.31667299999998,78.18498200000005],[-101.34249899999998,78.18942299999998],[-101.41722099999998,78.20887800000014],[-101.432503,78.21527100000009],[-101.43138099999999,78.22137499999997],[-101.43276999999989,78.22747800000008],[-101.45638999999994,78.23220800000013],[-101.47416699999991,78.23471100000012],[-101.49665800000002,78.23719800000015],[-101.833328,78.26499900000005],[-102.1330569999999,78.28276100000011],[-102.15750100000002,78.28248600000006],[-102.18221999999997,78.2810970000001],[-102.29888900000003,78.27331500000014],[-102.34722899999997,78.26776100000012],[-102.38890100000003,78.26081799999997],[-102.47138999999999,78.24887100000001],[-102.50167799999997,78.2458190000001],[-102.561394,78.24108900000004],[-102.59056099999987,78.23970000000008],[-102.61860699999994,78.24136400000009],[-102.64527900000002,78.24552900000009],[-102.73222399999992,78.26388500000007],[-102.781387,78.27609300000012],[-102.79778299999998,78.28221100000007],[-102.80943300000001,78.28831500000013],[-102.8163909999999,78.29443400000014],[-102.81833599999999,78.30026200000003],[-102.81360599999994,78.31080600000013],[-102.80803700000001,78.31693999999993],[-102.74999999999989,78.33831800000007],[-102.736107,78.34248400000013],[-102.686394,78.35054000000002],[-102.6658329999999,78.35859699999997],[-102.67083699999995,78.36303700000002],[-102.69499199999996,78.36775200000005],[-102.72250400000001,78.37136800000007],[-102.77778599999994,78.37637299999994],[-102.80610699999994,78.37776200000013],[-102.83583099999998,78.37637299999994],[-102.88999899999999,78.36914100000007],[-102.92027299999995,78.36581400000011],[-102.93804899999992,78.36469999999997],[-102.96694899999989,78.36415099999999],[-103.02443699999998,78.36526500000014],[-103.13390400000003,78.36914100000007],[-103.16388699999999,78.36692800000009],[-103.21417200000002,78.35664400000007],[-103.23832700000003,78.35054000000002],[-103.26471699999996,78.34526100000005],[-103.38110399999988,78.3316650000001],[-103.41111799999999,78.3294370000001],[-103.49804699999999,78.32777400000003],[-103.52749599999987,78.32638500000002],[-103.58473200000003,78.32193000000001],[-103.67999299999997,78.3119200000001],[-103.751106,78.30137600000006],[-103.78195199999999,78.29609700000003],[-103.80803700000001,78.29054300000007],[-103.829453,78.284988],[-103.87721299999998,78.27221700000007],[-103.89417300000002,78.25221299999993],[-103.89890299999996,78.2458190000001],[-103.910278,78.24108900000004],[-103.93331899999998,78.23719800000015],[-103.96305799999999,78.23359700000009],[-103.99194299999999,78.23304700000006],[-104.02250699999996,78.23414600000007],[-104.04277000000002,78.23692299999999],[-104.06984699999987,78.24217199999998],[-104.08306899999997,78.24414099999996],[-104.110817,78.24664300000006],[-104.19027699999998,78.25166300000012],[-104.30471799999992,78.25221299999993],[-104.36361699999998,78.25443999999999],[-104.41251399999999,78.25776700000011],[-104.46749899999998,78.26527400000009],[-104.49445300000002,78.27053800000004],[-104.82055700000001,78.35582000000011],[-104.99194299999999,78.43775900000009],[-104.99999999999994,78.44386299999996],[-105.05055199999998,78.48803700000008],[-105.05139200000002,78.49443100000013],[-105.04305999999991,78.50582900000012],[-105.01194800000002,78.52165199999996],[-104.95361299999996,78.5374910000001],[-104.86860699999994,78.56053199999997],[-104.83139,78.56999200000001],[-104.806107,78.572495],[-104.69638099999992,78.5788730000001],[-104.66665599999999,78.57971200000009],[-104.39778100000001,78.56999200000001],[-104.35500300000001,78.56637599999993],[-104.287781,78.55525200000005],[-104.26278699999995,78.54942300000005],[-104.21221899999995,78.53997799999996],[-104.1661069999999,78.53276100000005],[-104.14277600000003,78.5294340000001],[-104.08833300000003,78.52415500000012],[-104.03388999999999,78.51998900000007],[-103.93055699999996,78.516098],[-103.87110899999993,78.51805100000013],[-103.78250100000002,78.51971400000002],[-103.7225039999999,78.51721199999997],[-103.66583299999996,78.51249700000011],[-103.58860799999997,78.50387599999999],[-103.53333299999991,78.49636799999996],[-103.52362099999999,78.49609400000003],[-103.51834100000002,78.49693300000001],[-103.465843,78.51748699999996],[-103.37805200000003,78.58610500000003],[-103.39998599999996,78.61554000000012],[-103.44666299999994,78.62136800000007],[-103.50611900000001,78.62136800000007],[-103.74082900000002,78.61970500000012],[-103.98554999999999,78.61692800000003],[-104.01000999999991,78.61720300000007],[-104.04215999999991,78.62068199999993],[-104.04222099999998,78.62997399999995],[-104.03278399999988,78.63526900000005],[-103.98916600000001,78.6461030000001],[-103.85193600000002,78.66943400000014],[-103.82611099999997,78.67192100000005],[-103.77223200000003,78.67109700000009],[-103.65834000000001,78.66499300000004],[-103.62888299999992,78.6644290000001],[-103.53943600000002,78.66499300000004],[-103.50917099999987,78.66638200000006],[-103.48361199999994,78.66914400000013],[-103.49082899999996,78.67498799999998],[-103.50306699999999,78.6810910000001],[-103.51306199999993,78.68748499999992],[-103.52778599999999,78.6994170000001],[-103.525284,78.70526100000012],[-103.51806599999998,78.71081500000008],[-103.48860200000001,78.71582000000012],[-103.439438,78.72026100000005],[-103.41221599999989,78.72026100000005],[-103.38861099999997,78.71693399999992],[-103.35804699999994,78.71859700000005],[-103.33389299999999,78.72248800000011],[-103.31916799999999,78.72859199999999],[-103.31639099999995,78.734421],[-103.31889299999995,78.74026499999997],[-103.41665599999999,78.7788700000001],[-103.43916300000001,78.78498800000006],[-103.46806300000003,78.78749100000005],[-103.63971699999996,78.76527399999998],[-103.66915899999992,78.7605440000001],[-103.71056399999998,78.75000000000006],[-103.796112,78.73580900000007],[-103.70249899999999,78.78831500000001],[-103.69526699999994,78.79386899999997],[-103.698036,78.799713],[-103.72693599999997,78.80220000000008],[-103.86054999999999,78.80609099999998],[-103.87053699999996,78.80636599999997],[-103.886124,78.80442800000003],[-103.9083399999999,78.79914900000006],[-103.90556299999997,78.79414400000002],[-103.89639299999993,78.78471400000012],[-103.89083900000003,78.78027300000002],[-103.89527899999996,78.77499400000005],[-103.90527299999997,78.76887500000004],[-103.92916899999994,78.76499899999993],[-103.96056399999992,78.76138300000008],[-103.99109599999991,78.75888100000003],[-104.02166699999992,78.75749200000001],[-104.04943800000001,78.75637800000004],[-104.07389799999993,78.757767],[-104.170547,78.76582300000007],[-104.19888300000002,78.770264],[-104.21167000000003,78.776093],[-104.21972699999998,78.78221100000013],[-104.21528599999999,78.79359399999998],[-104.16722099999998,78.8163760000001],[-104.13305700000001,78.82748400000008],[-104.04834,78.83888200000007],[-103.98665599999998,78.85026599999998],[-103.86054999999999,78.87664800000005],[-103.83139,78.88693200000012],[-103.82389799999999,78.89248700000002],[-103.82167099999992,78.89833099999998],[-103.82472199999995,78.90331999999995],[-103.86749299999997,78.91609199999999],[-103.96305799999999,78.92997700000006],[-103.98998999999998,78.93275500000004],[-104.00639299999995,78.93553199999997],[-104.029449,78.9416500000001],[-104.04750099999995,78.94775400000009],[-104.05332899999996,78.95220899999993],[-104.053879,78.95748900000001],[-104.05222300000003,78.96138000000008],[-104.04778299999992,78.96665999999993],[-104.048607,78.97109999999998],[-104.05777,78.97415200000006],[-104.08112299999999,78.97943100000003],[-104.12943999999999,78.98580900000002],[-104.17859599999991,78.99026500000014],[-104.20361300000002,78.99165300000004],[-104.23388699999998,78.99192800000003],[-104.265556,78.98858600000011],[-104.45500199999998,78.95609999999999],[-104.47193899999996,78.95054600000003],[-104.51112399999994,78.91026299999999],[-104.53832999999997,78.88192700000002],[-104.56416300000001,78.86470000000003],[-104.57888799999989,78.85859700000009],[-104.78582799999998,78.80664100000001],[-104.81749699999995,78.80220000000008],[-104.87860099999995,78.79803500000008],[-104.909157,78.79664600000007],[-104.96888699999994,78.79721100000012],[-104.98832700000003,78.79832500000009],[-105.01194800000002,78.8035890000001],[-105.02250699999996,78.80998200000005],[-105.02861000000001,78.81526200000008],[-105.02916699999997,78.82165500000008],[-105.028343,78.83276399999994],[-105.01222200000001,78.84471100000007],[-104.83389299999999,78.92665099999999],[-104.68859899999995,78.99359099999998],[-104.678879,78.99971],[-104.674713,79.00499000000008],[-104.68110699999994,79.01666300000011],[-104.69415300000003,79.02276600000005],[-104.70805399999995,79.02777100000009],[-104.737213,79.03193699999997],[-104.90249599999993,79.04971299999994],[-104.98638899999997,79.043045],[-105.01334399999996,79.03831500000013],[-105.09916699999991,79.02388000000002],[-105.12526700000001,79.0211030000001],[-105.15638699999988,79.01943999999997],[-105.39527900000002,79.01165800000007],[-105.42610200000001,79.01110800000004],[-105.48388699999998,79.01304600000014],[-105.51363399999997,79.01609800000006],[-105.54332699999998,79.02026399999994],[-105.5625,79.02442899999994],[-105.58138999999994,79.03054800000001],[-105.59084299999995,79.03442400000006],[-105.59944200000001,79.04026800000008],[-105.60665899999992,79.0519260000001],[-105.628601,79.16137700000007],[-105.62053699999996,79.1727600000001],[-105.48277300000001,79.30636600000008],[-105.45973199999997,79.32415800000012],[-105.43998699999997,79.329163],[-105.40862299999992,79.32887299999999],[-105.38305699999995,79.32693500000005],[-105.33277899999996,79.31944300000009],[-105.19721999999996,79.29971300000011],[-105.16111799999999,79.29748500000011],[-105.12721299999998,79.29748500000011],[-105.108612,79.29887400000013],[-105.01611300000002,79.31053199999997],[-104.95472699999993,79.31526200000002],[-104.85916099999997,79.31915300000009],[-104.74276700000001,79.322495],[-104.583328,79.3294370000001],[-104.54860699999989,79.33137500000004],[-104.49082900000002,79.339157],[-104.46083099999998,79.34220900000008],[-104.181671,79.35887100000008],[-104.00723299999999,79.36775200000005],[-103.97778299999999,79.36886600000003],[-103.9491579999999,79.36804200000006],[-103.83500699999996,79.36442599999998],[-103.7225039999999,79.35693400000002],[-103.69526699999994,79.35220300000009],[-103.62053700000001,79.33055100000007],[-103.59388699999988,79.32582100000002]],[[-99.47166399999998,80.109711],[-99.43666100000002,80.10720800000001],[-99.40472399999993,80.10803199999998],[-99.29804999999999,80.11886600000003],[-99.13667299999992,80.13304099999993],[-99.11054999999988,80.13053900000006],[-99.08168,80.12469500000003],[-98.86888099999999,80.07777400000003],[-98.85665899999992,80.07249500000006],[-98.774719,80.01527400000009],[-98.70584100000002,79.96582000000006],[-98.64416499999987,79.80026199999992],[-98.64416499999987,79.79414400000002],[-98.64862099999988,79.78359999999992],[-98.67304999999999,79.77192700000012],[-98.77917500000001,79.70220899999998],[-98.83000199999992,79.6644290000001],[-98.86805700000002,79.70082100000008],[-98.93611099999998,79.71971100000002],[-98.96777299999991,79.72415200000012],[-99.13999899999993,79.74081400000011],[-99.24305699999996,79.74859600000008],[-99.27362099999993,79.75138900000002],[-99.30139199999991,79.75471500000009],[-99.31723,79.75860599999999],[-99.32444800000002,79.76249700000005],[-99.32556199999999,79.76748700000007],[-99.32250999999991,79.77137800000014],[-99.31304899999992,79.776093],[-99.30471799999992,79.78221100000013],[-99.30277999999998,79.78749099999999],[-99.29750100000001,79.81275900000009],[-99.295837,79.83332800000005],[-99.29638699999992,79.83915700000006],[-99.30221599999987,79.84526100000011],[-99.31582600000002,79.84860200000014],[-99.36888099999999,79.8577580000001],[-99.55665599999992,79.88888500000002],[-99.58444199999997,79.8919370000001],[-99.61416600000001,79.89332600000012],[-99.64778100000001,79.89305100000007],[-99.67971799999998,79.88804600000003],[-99.70083599999987,79.88275099999998],[-99.73222399999997,79.87886000000009],[-99.80082700000003,79.87664800000005],[-100.00556899999998,79.8744200000001],[-100.03582799999992,79.87469500000009],[-100.07028199999996,79.87692300000003],[-100.097778,79.88108800000003],[-100.12110899999999,79.88665800000012],[-100.14389,79.89305100000007],[-100.15862299999998,79.89860500000009],[-100.17748999999998,79.90998800000011],[-100.17832900000002,79.91581700000012],[-100.193329,80.03387500000008],[-100.08167999999989,80.084427],[-100.06555200000003,80.08998099999997],[-100.02362099999993,80.09971600000006],[-99.827225,80.14359999999999],[-99.79527299999995,80.1477660000001],[-99.75917099999998,80.149719],[-99.726944,80.15054299999997],[-99.62554899999992,80.14888000000008],[-99.59999099999999,80.145264],[-99.59388699999988,80.13916],[-99.57112099999995,80.1327510000001],[-99.47166399999998,80.109711]],[[-99.15556300000003,80.17469799999998],[-99.12721299999993,80.168045],[-99.11389199999996,80.16387900000012],[-99.13806199999999,80.16249100000005],[-99.160553,80.16304000000014],[-99.18499800000001,80.167755],[-99.2519529999999,80.17303500000008],[-99.27749599999999,80.17303500000008],[-99.31361399999997,80.17109700000015],[-99.34138499999995,80.1660920000001],[-99.33306900000002,80.15942400000012],[-99.30360399999995,80.1538700000001],[-99.30555699999991,80.1483310000001],[-99.34249899999992,80.1455380000001],[-99.37527499999993,80.14721700000013],[-99.40055799999993,80.15081800000002],[-99.41805999999997,80.15721100000013],[-99.41833500000001,80.16304000000014],[-99.41332999999997,80.16886899999997],[-99.38694799999996,80.17886400000009],[-99.36694299999994,80.18220500000012],[-99.2391659999999,80.18386800000007],[-99.21194499999996,80.18220500000012],[-99.15556300000003,80.17469799999998]],[[-95.0308379999999,80.67025800000005],[-94.96945199999993,80.64027400000003],[-94.970551,80.635269],[-94.98138399999999,80.63192700000008],[-95.006958,80.62664800000005],[-95.19027699999992,80.60887100000002],[-95.22610499999996,80.60914600000001],[-95.45361300000002,80.62942499999997],[-95.61111499999998,80.64804099999998],[-95.67694099999994,80.65331999999995],[-95.71194500000001,80.65443399999998],[-95.74916099999996,80.65386999999998],[-95.78805499999993,80.65220599999998],[-95.82362399999994,80.64860499999992],[-95.86332699999997,80.64582800000005],[-96.061935,80.65664700000008],[-96.11805699999996,80.66053799999997],[-96.14916999999997,80.66470300000015],[-96.13944999999995,80.66970800000001],[-96.07667500000002,80.683044],[-96.02833599999997,80.68719500000009],[-96.00611900000001,80.68803400000002],[-95.491379,80.69999700000005],[-95.42443800000001,80.69970700000005],[-95.20056199999993,80.6974790000001],[-95.16694599999994,80.69525099999998],[-95.12887599999993,80.69192500000008],[-95.09666399999998,80.688583],[-95.06249999999994,80.68248000000006],[-95.06527699999992,80.68054200000012],[-95.04583699999995,80.67692600000004],[-95.0308379999999,80.67025800000005]],[[-92.72778299999993,81.30554200000006],[-92.53028899999998,81.28498800000011],[-92.21305799999999,81.24552900000003],[-92.148056,81.23637400000013],[-92.12470999999994,81.2327580000001],[-92.05248999999992,81.2185970000001],[-91.95584100000002,81.19636500000001],[-91.858047,81.167755],[-91.781677,81.09027100000014],[-91.78388999999993,81.08360299999998],[-91.79750100000001,81.08166500000004],[-91.83250399999997,81.08027600000008],[-91.88806199999993,81.08194000000009],[-91.914444,81.07804900000002],[-91.91389499999997,81.07499700000011],[-91.908615,81.07054099999999],[-91.89334100000002,81.06498699999997],[-91.86582899999996,81.05859400000003],[-91.76722699999993,81.04914899999994],[-91.72222899999997,81.04220599999996],[-91.53889500000002,80.98165899999998],[-91.52555799999999,80.97499099999999],[-91.52278100000001,80.96276900000004],[-91.53167699999995,80.951096],[-91.527222,80.93969700000008],[-91.51777600000003,80.93275499999999],[-91.481674,80.91943400000002],[-91.321121,80.88275099999998],[-91.306107,80.87553400000002],[-91.152222,80.78553800000003],[-91.15499899999998,80.78054800000001],[-91.14916999999997,80.770264],[-91.14056399999998,80.7647090000001],[-91.12165800000002,80.75471500000003],[-91.09944199999995,80.74803200000008],[-91.03472899999997,80.73748800000004],[-90.97277799999995,80.73027000000002],[-90.90527299999997,80.724426],[-90.777222,80.71775800000006],[-90.75418100000002,80.71499599999993],[-90.712784,80.70555100000007],[-90.66471899999999,80.684708],[-90.65249599999993,80.67804000000001],[-90.603882,80.65138200000001],[-90.59361299999995,80.64526400000011],[-90.59306300000003,80.64082300000001],[-90.60194399999995,80.63610799999998],[-90.61582900000002,80.63026400000012],[-90.67805499999997,80.61554000000007],[-90.71583599999991,80.605545],[-90.74249299999991,80.59471100000007],[-90.76306199999999,80.5836030000001],[-90.77166699999998,80.57748400000008],[-90.77278099999995,80.57193000000007],[-90.76640299999991,80.56553600000007],[-90.74137899999994,80.56219500000003],[-90.70611600000001,80.56137100000007],[-90.60722399999992,80.56137100000007],[-90.58306900000002,80.56137100000007],[-90.41805999999991,80.55220000000008],[-90.23889199999996,80.55053699999996],[-90.20333900000003,80.549713],[-90.17721599999999,80.54887400000007],[-90.04638699999992,80.54165600000005],[-90.01640299999997,80.53803999999997],[-90,80.53459199999998],[-89.98999000000003,80.532486],[-89.96139499999998,80.520264],[-89.95556599999998,80.51554899999996],[-89.93859899999995,80.508331],[-89.84056099999998,80.48136900000009],[-89.81639100000001,80.4749910000001],[-89.79028299999993,80.46943700000008],[-89.76251199999996,80.46499599999999],[-89.75111400000003,80.46443200000004],[-89.78416399999992,80.50082400000002],[-89.74833699999988,80.532761],[-89.58694500000001,80.5455320000001],[-89.546112,80.54748500000005],[-89.48277300000001,80.544983],[-89.4472199999999,80.54248000000001],[-89.354172,80.53498800000006],[-89.32640099999992,80.53193700000003],[-89.27278100000001,80.52331500000003],[-89.24499500000002,80.51721200000009],[-89.05915800000002,80.46138000000013],[-89.08750899999995,80.43858300000005],[-89.11527999999993,80.43386800000002],[-89.17610199999996,80.42665100000005],[-89.19833399999993,80.42164600000001],[-89.20944199999991,80.41775499999994],[-89.23500100000001,80.40803500000004],[-89.25,80.40220600000004],[-89.25723299999999,80.39694200000008],[-89.25361599999997,80.39276100000001],[-89.237213,80.388596],[-89.21694899999994,80.38970900000004],[-89.18971299999993,80.39414999999997],[-89.16749600000003,80.39915500000001],[-89.136124,80.40248100000008],[-89.09973100000002,80.40248100000008],[-89.08332799999988,80.39833100000004],[-89.07583599999992,80.39305100000001],[-89.10499599999991,80.33943199999999],[-89.11416599999995,80.33332799999994],[-89.12527499999993,80.32777399999998],[-89.14361600000001,80.32331800000003],[-89.16915899999998,80.31805400000007],[-89.2202759999999,80.30914300000012],[-89.24194299999994,80.3041530000001],[-89.25666799999999,80.29859900000008],[-89.26390099999998,80.29332000000011],[-89.26222199999995,80.28665200000012],[-89.25140399999998,80.27832000000012],[-89.180496,80.23817400000007],[-89.11389200000002,80.20803800000004],[-89.09222399999999,80.20082100000013],[-89.07278400000001,80.19552600000009],[-88.77667200000002,80.13136300000002],[-88.75,80.12664799999999],[-88.53472899999991,80.09887700000013],[-88.49888599999997,80.09887700000013],[-88.44193999999993,80.10054000000002],[-88.41471899999999,80.10498000000007],[-88.414444,80.10803199999998],[-88.36305199999993,80.12442000000004],[-88.23527499999989,80.10247799999996],[-88.16194199999995,80.09165999999999],[-88.145554,80.09387200000003],[-88.148346,80.09803799999997],[-88.26139799999993,80.18803400000013],[-88.27305599999994,80.19552600000009],[-88.29415899999998,80.20138500000007],[-88.35082999999997,80.20887800000008],[-88.422775,80.21054100000003],[-88.47999600000003,80.21360800000014],[-88.50695799999994,80.218323],[-88.59527600000001,80.2369230000001],[-88.61805700000002,80.24331699999999],[-88.63027999999991,80.249146],[-88.66139199999992,80.27249100000012],[-88.68443299999996,80.35859700000015],[-88.68582200000003,80.36554000000012],[-88.685272,80.37164300000006],[-88.68305999999995,80.37692300000015],[-88.67721599999993,80.38275100000004],[-88.64889499999992,80.3936000000001],[-88.61527999999993,80.40387000000004],[-88.51028400000001,80.42886400000003],[-88.48777799999999,80.43386800000002],[-88.46333300000003,80.43803400000007],[-88.420547,80.44220000000001],[-88.383896,80.44358800000009],[-88.30833399999995,80.4427490000001],[-88.11054999999993,80.4327550000001],[-87.91888399999999,80.42109700000009],[-87.718613,80.41110200000014],[-87.68388400000003,80.41026300000004],[-87.6663969999999,80.40387000000004],[-87.63612399999994,80.36692800000003],[-87.60749800000002,80.32415800000007],[-87.56388900000002,80.23332200000004],[-87.561935,80.18359399999991],[-87.56277499999993,80.17915300000004],[-87.57223499999992,80.17608600000011],[-87.67805499999992,80.15637199999998],[-87.72138999999999,80.15304600000013],[-87.93916299999995,80.14387500000004],[-87.96665999999999,80.13943499999999],[-88.04888900000003,80.125809],[-88.06555200000003,80.12081899999998],[-88.06054699999999,80.11747700000006],[-87.95666499999999,80.06971700000003],[-87.93804899999998,80.06442300000009],[-87.89138799999995,80.05554200000012],[-87.86000100000001,80.05358899999999],[-87.83612099999993,80.0577550000001],[-87.823059,80.06248499999992],[-87.76306199999993,80.07110600000004],[-87.72000099999991,80.0747070000001],[-87.68055700000002,80.07638500000002],[-87.64167800000001,80.07638500000002],[-87.365005,80.072769],[-87.29998799999998,80.06944300000009],[-87.27555799999988,80.06693999999993],[-87.25862099999995,80.06387300000006],[-87.23332199999999,80.05748000000006],[-87.21528599999999,80.05053700000008],[-87.04333499999996,79.9649960000001],[-87.09361299999995,79.92942800000009],[-87.314438,79.86608899999999],[-87.33612099999993,79.86137400000013],[-87.36833200000001,79.85720800000007],[-87.44665500000002,79.8560940000001],[-87.4719389999999,79.85247800000002],[-87.48306299999996,79.84721400000006],[-87.48944099999994,79.84137000000004],[-87.48554999999988,79.834991],[-87.46362299999998,79.83137499999992],[-87.43916299999995,79.83194000000015],[-87.412781,79.83332800000005],[-87.33860800000002,79.84082000000001],[-87.19082600000002,79.86608899999999],[-87.16555800000003,79.87109400000003],[-87.14695699999993,79.87553400000007],[-87.07972699999993,79.89610300000004],[-87.05139200000002,79.90664700000008],[-87.02471899999995,79.91609199999994],[-87.00306699999999,79.91775500000006],[-86.98582499999998,79.91775500000006],[-86.97389199999986,79.91638199999994],[-86.96139499999998,79.90998800000011],[-86.95777900000002,79.90359499999994],[-86.960556,79.89137299999999],[-87.05555700000002,79.73193400000008],[-87.13417099999992,79.64526400000011],[-87.14416499999993,79.63777199999998],[-87.15499899999998,79.6336060000001],[-87.17304999999999,79.62914999999998],[-87.25862099999995,79.61026000000004],[-87.34445199999993,79.59637499999997],[-87.42555199999998,79.57916300000011],[-87.44166599999994,79.57388300000002],[-87.44804399999998,79.56832900000006],[-87.46250900000001,79.53471399999995],[-87.44193999999999,79.52638200000001],[-87.40666199999998,79.51582300000013],[-87.39056399999993,79.51110800000009],[-87.36639400000001,79.50637800000004],[-87.34527600000001,79.50305200000003],[-87.30999800000001,79.50221300000004],[-87.28056300000003,79.50694300000009],[-87.26278699999995,79.51138300000008],[-87.24833699999999,79.5169370000001],[-87.19055200000003,79.54359399999998],[-87.18276999999995,79.54887400000007],[-87.17999299999997,79.55415300000004],[-87.16888399999999,79.5663760000001],[-87.16111799999993,79.57165500000008],[-87.07667500000002,79.58749399999999],[-87.02555799999999,79.5955350000001],[-87.00111399999997,79.59887700000002],[-86.96665999999993,79.60165400000011],[-86.93249500000002,79.60165400000011],[-86.84138499999995,79.59304800000001],[-86.823624,79.58776900000004],[-86.81973299999999,79.576096],[-86.82389799999999,79.5660860000001],[-86.839722,79.55581700000005],[-86.84638999999999,79.54998800000004],[-86.837784,79.54332000000005],[-86.816666,79.53970300000015],[-86.78999299999998,79.53887899999995],[-86.777222,79.54220600000008],[-86.69499199999996,79.56749000000008],[-86.693329,79.57360800000004],[-86.71055599999994,79.58720399999999],[-86.72389199999998,79.59443700000003],[-86.74638399999998,79.59999099999999],[-86.80248999999998,79.60609399999993],[-86.81304899999992,79.61192299999999],[-86.80638099999987,79.617752],[-86.79527299999995,79.62164300000006],[-86.77694699999995,79.62747200000007],[-86.76222200000001,79.63165300000014],[-86.68721,79.64526400000011],[-86.64083899999991,79.65332000000001],[-86.61305199999993,79.655823],[-86.57501200000002,79.65721100000007],[-86.547775,79.65637200000009],[-86.33416699999992,79.64553800000004],[-86.30277999999998,79.64276100000012],[-86.27944899999994,79.64027400000003],[-86.258896,79.63499500000006],[-86.10916099999997,79.595261],[-86.046112,79.56887799999998],[-86.04222099999993,79.56553600000007],[-86.02806099999992,79.4747010000001],[-86.05471799999998,79.47053500000004],[-86.160553,79.46360800000014],[-86.16749600000003,79.45776400000011],[-86.136124,79.44470200000006],[-86.120834,79.43997200000007],[-86.09889199999992,79.43580600000013],[-86.07084700000001,79.43414300000006],[-86.03500400000001,79.43637100000001],[-86.01194799999996,79.44026200000008],[-85.99055499999997,79.44497700000011],[-85.97582999999992,79.44914200000011],[-85.96417199999996,79.45443699999998],[-85.90110800000002,79.49359100000004],[-85.88722200000001,79.50526400000007],[-85.88528399999996,79.51138300000008],[-85.89334100000002,79.52331500000008],[-85.89916999999997,79.53637700000007],[-85.89666699999998,79.54914900000011],[-85.89334100000002,79.55470300000007],[-85.88778699999995,79.56109600000002],[-85.84750400000001,79.59637499999997],[-85.84028599999999,79.60192899999993],[-85.82833900000003,79.60748300000012],[-85.781387,79.61554000000012],[-85.743607,79.61692800000003],[-85.68194599999993,79.61331200000012],[-85.63917500000002,79.60415599999999],[-85.62388599999991,79.59915200000006],[-85.591385,79.58526600000005],[-85.53111299999995,79.55941800000011],[-85.48500099999995,79.51860000000005],[-85.402222,79.47360200000014],[-85.30665599999992,79.428314],[-85.27806099999998,79.41554300000013],[-85.15055799999993,79.38220200000012],[-85.13027999999997,79.3785860000001],[-85.03971899999988,79.35081500000001],[-84.93249499999996,79.30026200000003],[-84.92027300000001,79.29332000000011],[-84.90417500000001,79.27665700000006],[-84.90417500000001,79.26776100000012],[-84.90972899999986,79.26304600000009],[-84.93110699999994,79.25833100000006],[-85.09999099999993,79.2394260000001],[-85.15888999999993,79.23193399999997],[-85.21139499999987,79.22331199999996],[-85.23277299999995,79.21887200000015],[-85.24804699999987,79.21304299999997],[-85.26000999999991,79.207764],[-85.27194199999997,79.19720500000011],[-85.28056300000003,79.19220000000007],[-85.29722600000002,79.18719500000003],[-85.591385,79.15415999999999],[-85.77999899999992,79.13108800000003],[-85.87721299999998,79.12164299999995],[-86.00389100000001,79.11137400000013],[-86.15888999999999,79.10331699999995],[-86.27139299999999,79.09553499999998],[-86.34167499999995,79.08831800000007],[-86.42250100000001,79.07554600000009],[-86.48554999999999,79.06330900000012],[-86.55082700000003,79.04887400000001],[-86.55999799999995,79.04443400000014],[-86.55555700000002,79.04248000000013],[-86.55082700000003,79.03553800000003],[-86.55249000000003,79.02943400000004],[-86.55999799999995,79.01220699999999],[-86.58778399999994,78.98359700000015],[-86.59889199999992,78.97831700000006],[-86.61444099999994,78.97331200000002],[-86.67694099999989,78.95971700000013],[-86.70222499999994,78.95526100000006],[-86.74137899999994,78.95193499999999],[-86.765015,78.95359800000011],[-86.78500400000001,78.95721399999996],[-86.808334,78.96720900000008],[-86.90333599999985,79.00943000000007],[-86.91639699999996,79.01666300000011],[-86.92639199999996,79.03581200000013],[-86.93055699999996,79.04776000000004],[-86.94055199999997,79.05358900000004],[-86.94915800000001,79.05720500000007],[-86.96528599999994,79.05748000000011],[-86.98332199999993,79.05664100000013],[-86.98998999999998,79.04776000000004],[-87.004456,78.98719800000003],[-87.00250199999999,78.98136900000003],[-86.98693799999995,78.94970700000005],[-86.97999599999997,78.9433140000001],[-86.96694899999994,78.93637100000012],[-86.95083599999998,78.92942800000009],[-86.94276400000001,78.92248500000011],[-86.93777499999999,78.91693099999992],[-86.95249899999993,78.90664700000008],[-86.97084000000001,78.89610300000004],[-86.99749800000001,78.88247700000005],[-87.02166699999992,78.87303200000002],[-87.05249000000003,78.86276200000009],[-87.17944299999994,78.83055100000001],[-87.28277599999996,78.81025700000004],[-87.32806399999998,78.79470800000013],[-87.353882,78.78414900000007],[-87.52999899999992,78.6869200000001],[-87.53277600000001,78.66998300000012],[-87.54305999999997,78.66470300000003],[-87.57278399999996,78.65443399999998],[-87.591949,78.64971899999995],[-87.61582900000002,78.64526400000011],[-87.66305499999999,78.64248700000002],[-87.68443299999996,78.64498900000012],[-87.87277199999994,78.69497700000005],[-87.93777499999987,78.73831200000006],[-87.95361299999996,78.74971000000005],[-87.95916699999998,78.75526400000007],[-87.99388099999993,78.79525799999999],[-88.00334199999992,78.80720500000012],[-88.00140399999998,78.82415800000001],[-87.985275,78.95721399999996],[-87.98167399999988,78.96054100000009],[-87.96833800000002,78.96638500000012],[-87.89416499999999,78.97970600000008],[-87.83361799999994,78.99220300000007],[-87.81361400000003,78.99693300000007],[-87.79444899999999,79.00694300000004],[-87.72888199999994,79.06944299999998],[-87.72471599999994,79.07582100000008],[-87.73388699999998,79.08110000000005],[-87.74610899999993,79.08610499999992],[-87.752792,79.08554099999998],[-87.77278099999995,79.08082599999994],[-87.80638099999993,79.06999200000007],[-87.84916699999997,79.05497700000012],[-87.87277199999994,79.0452580000001],[-87.883331,79.03997800000008],[-87.894455,79.02832000000001],[-87.890289,79.02165200000007],[-87.89999399999999,79.01110800000004],[-87.92944299999999,79.00694300000004],[-88.000565,79.00360100000006],[-88.03277600000001,79.0038760000001],[-88.06138599999991,79.005829],[-88.09388699999994,79.00444000000005],[-88.16250600000001,78.99054000000012],[-88.20249899999993,78.97637900000012],[-88.21305799999999,78.96609500000011],[-88.21528599999994,78.96081500000003],[-88.21665999999993,78.94831800000003],[-88.22972099999998,78.80220000000008],[-88.224716,78.78915399999994],[-88.22222899999997,78.78332499999993],[-88.21806300000003,78.77693199999999],[-88.20111099999997,78.75721699999997],[-88.13221699999997,78.68081699999999],[-88.04415899999992,78.65860000000009],[-88.02416999999997,78.65664700000013],[-88.01083399999993,78.65277100000009],[-87.99305699999996,78.64526400000011],[-87.98277299999995,78.6394350000001],[-87.908615,78.59693900000008],[-87.89472999999998,78.58471700000013],[-87.89083900000003,78.57832300000007],[-87.89695699999987,78.56637599999993],[-87.90833999999995,78.54859900000008],[-87.98472599999997,78.49220299999996],[-88.01194800000002,78.48136900000009],[-88.05583200000001,78.47276299999999],[-88.20527600000003,78.45248400000008],[-88.23416099999997,78.45359800000006],[-88.24916099999996,78.45664999999997],[-88.38945000000001,78.52137800000003],[-88.5594329999999,78.60415600000005],[-88.57472199999995,78.60720800000013],[-88.723053,78.61581400000006],[-88.78860500000002,78.61276199999998],[-88.80416899999994,78.60971100000012],[-88.74610899999993,78.53581200000008],[-88.72500600000001,78.52415500000012],[-88.65916400000003,78.49108899999999],[-88.59527600000001,78.459991],[-88.5625,78.44470200000012],[-88.55221599999999,78.43748499999998],[-88.54388399999999,78.42608600000011],[-88.535553,78.41304000000014],[-88.53611799999993,78.40693700000003],[-88.53805499999999,78.40138200000013],[-88.541382,78.39665200000007],[-88.55305499999992,78.3855440000001],[-88.56111099999998,78.37942500000008],[-88.57055699999995,78.37387100000007],[-88.61471599999999,78.34832799999998],[-88.66332999999997,78.32138100000003],[-88.67250100000001,78.31608599999998],[-88.70417799999996,78.2711030000001],[-88.710556,78.26110799999998],[-88.71389799999986,78.25471500000003],[-88.71556099999998,78.24914600000005],[-88.71611000000001,78.243042],[-88.72111499999994,78.23109399999998],[-88.72610500000002,78.22526600000003],[-88.75140399999998,78.19693000000012],[-88.77667200000002,78.17608599999994],[-88.78443900000002,78.169983],[-88.79333499999996,78.16442900000004],[-88.81777999999991,78.1544340000001],[-88.84777799999995,78.15138200000001],[-88.97888199999994,78.16581700000012],[-89.00279199999994,78.16943400000008],[-89.06500199999988,78.18441800000011],[-89.07972699999999,78.18914799999999],[-89.11582899999996,78.20082100000002],[-89.22749299999998,78.24525499999999],[-89.25917099999992,78.26277199999998],[-89.26501499999995,78.268326],[-89.275284,78.28193699999997],[-89.35388199999989,78.33970599999998],[-89.364441,78.34414700000008],[-89.381104,78.3477630000001],[-89.51834100000002,78.39221200000009],[-89.67666599999995,78.44747899999999],[-89.803879,78.49443100000013],[-89.819458,78.50054900000009],[-89.89111300000002,78.55276499999997],[-89.92166099999997,78.57804899999996],[-89.945831,78.599426],[-89.95695499999988,78.605255],[-89.98055999999997,78.60971100000012],[-90.01472499999988,78.60942100000011],[-90.05139199999996,78.60582000000005],[-90.08833299999998,78.5958250000001],[-90.09249899999998,78.58998099999991],[-90.09973100000002,78.55525200000005],[-90.10082999999997,78.54971300000005],[-90.06471299999993,78.51332100000008],[-89.98500099999995,78.43609600000002],[-89.960556,78.43248000000011],[-89.93611099999998,78.43026700000001],[-89.91000400000001,78.42608600000011],[-89.86999500000002,78.417755],[-89.80972300000002,78.40470900000008],[-89.785278,78.39804100000009],[-89.77444500000001,78.39387499999998],[-89.74804699999993,78.38026400000001],[-89.61555499999986,78.30026200000003],[-89.60610999999994,78.29332],[-89.46167000000003,78.17553700000002],[-89.45584100000002,78.169983],[-89.45249899999999,78.16249100000005],[-89.46167000000003,78.15859999999998],[-89.47666899999996,78.15386999999998],[-89.50778199999996,78.1499940000001],[-89.53028899999998,78.14833099999998],[-89.54943799999995,78.14860500000009],[-89.56304899999992,78.14971900000006],[-89.59584000000001,78.15693700000008],[-89.61860699999994,78.16304000000002],[-89.63194299999998,78.16859400000004],[-89.63972499999994,78.17330900000007],[-89.64416499999999,78.17970300000007],[-89.646118,78.18470799999994],[-89.646118,78.19720500000011],[-89.64805599999994,78.2022090000001],[-89.65417499999995,78.20942700000012],[-89.65722699999998,78.21220399999999],[-89.67388899999997,78.21720900000008],[-89.70083599999998,78.21914700000002],[-89.74888599999991,78.21720900000008],[-89.78332499999993,78.21443199999999],[-89.847778,78.21304299999997],[-89.88694800000002,78.21527100000009],[-89.91111799999999,78.21887200000015],[-89.929169,78.22303800000009],[-89.95527600000003,78.2333220000001],[-89.96028100000001,78.23831199999995],[-89.96194500000001,78.24359099999992],[-89.95944199999997,78.25443999999999],[-89.95500199999992,78.26054400000004],[-89.98028599999992,78.27777100000003],[-90.02333099999998,78.29803500000003],[-90.060272,78.30802900000003],[-90.17250099999995,78.33110000000005],[-90.18611099999993,78.333328],[-90.21362299999998,78.33526599999993],[-90.24249299999985,78.33610500000009],[-90.27416999999997,78.33499100000012],[-90.34056099999998,78.33110000000005],[-90.41139199999992,78.32443200000006],[-90.478882,78.32110600000004],[-90.50778199999996,78.32054099999999],[-90.59445199999999,78.32276899999994],[-90.62026999999995,78.32554600000003],[-90.66777000000002,78.32748399999997],[-90.729446,78.32609600000006],[-90.74444599999998,78.32304399999998],[-90.74861099999998,78.32026700000006],[-90.73721299999994,78.31442300000003],[-90.71556099999992,78.309143],[-90.62277199999994,78.29109199999999],[-90.598343,78.28749099999993],[-90.54499800000002,78.28305100000011],[-90.46166999999997,78.27887000000004],[-90.41027799999995,78.27665700000006],[-90.36332700000003,78.25694299999998],[-90.27389499999998,78.19220000000007],[-90.26750199999992,78.18664600000011],[-90.26889,78.18275500000004],[-90.27278100000001,78.17692599999998],[-90.29388399999999,78.15998800000011],[-90.30110200000001,78.15525800000006],[-90.33029199999999,78.14610300000004],[-90.35388199999994,78.14332600000012],[-90.43388400000003,78.13638300000014],[-90.465012,78.13526899999994],[-90.49777199999994,78.134995],[-90.62443499999995,78.13443000000001],[-90.71112099999999,78.13581800000009],[-90.96722399999999,78.14276100000006],[-91.02139299999999,78.14610300000004],[-91.03971899999999,78.1502690000001],[-91.23838799999999,78.16659499999997],[-91.32667499999997,78.16859400000004],[-91.48971599999987,78.17692599999998],[-91.53999299999992,78.18136600000003],[-91.61389199999996,78.19192500000008],[-91.6619419999999,78.19970700000005],[-91.70722999999998,78.20942700000012],[-91.72471599999994,78.21470600000009],[-91.80777,78.23275799999999],[-91.83139,78.23692299999999],[-91.85749799999996,78.23970000000008],[-91.8875119999999,78.23942599999992],[-91.92027300000001,78.23719800000015],[-91.94638099999997,78.23275799999999],[-91.96333299999998,78.22776800000008],[-91.97444199999995,78.22331200000002],[-91.98611499999998,78.21470600000009],[-92.00306699999999,78.20971700000013],[-92.031113,78.20748899999995],[-92.058334,78.20887800000014],[-92.083328,78.21249400000005],[-92.10555999999997,78.217758],[-92.30833399999995,78.278595],[-92.537216,78.31053199999997],[-92.55665599999998,78.31469699999997],[-92.589447,78.32360800000009],[-92.94943199999989,78.43193100000002],[-92.96665999999999,78.44358799999992],[-92.98249800000002,78.45443699999998],[-92.98721299999994,78.46026599999999],[-92.98750299999995,78.46554600000007],[-92.97888199999994,78.48332200000004],[-92.96665999999999,78.48858600000005],[-92.86389199999996,78.50526400000012],[-92.84861799999999,78.50555400000013],[-92.69055199999997,78.49581900000004],[-92.64639299999993,78.48748799999993],[-92.62193300000001,78.48719800000009],[-92.60055499999999,78.48803700000008],[-92.57667500000002,78.49054000000007],[-92.52027900000002,78.49859600000013],[-92.493607,78.50332599999996],[-92.48721299999994,78.50776700000006],[-92.48777799999999,78.50943000000001],[-92.497772,78.51304600000003],[-92.56332399999997,78.52053799999999],[-92.52944899999994,78.52137800000003],[-92.24722300000002,78.52777100000003],[-92.21665999999993,78.52804600000002],[-92.07084700000001,78.52554300000003],[-92.01112399999994,78.526657],[-91.94999699999994,78.53027300000008],[-91.91861,78.534424],[-91.72639500000002,78.53054800000007],[-91.68249500000002,78.52609300000006],[-91.66082799999998,78.52693200000004],[-91.64611799999994,78.52998400000013],[-91.63612399999994,78.53360000000004],[-91.63249200000001,78.53942900000004],[-91.63528400000001,78.54609700000003],[-91.64750699999996,78.56025700000009],[-91.65750099999997,78.563873],[-91.67027299999995,78.56581100000011],[-91.945267,78.57222000000013],[-92.15139799999992,78.57943700000004],[-92.35194399999995,78.586929],[-92.55722000000003,78.59471100000013],[-92.58555599999994,78.59609999999998],[-92.60472099999998,78.59860200000003],[-92.697769,78.6141510000001],[-92.73306300000002,78.62359600000002],[-92.75778199999996,78.62803600000001],[-92.806107,78.6336060000001],[-92.828888,78.63192700000008],[-92.90722700000003,78.62303200000008],[-92.93554699999999,78.61886600000014],[-92.93582199999997,78.61499000000009],[-92.941666,78.60859700000015],[-92.95584100000002,78.6038670000001],[-92.99166899999994,78.599716],[-93.176941,78.58638000000008],[-93.210556,78.58415200000007],[-93.24249299999997,78.582764],[-93.271118,78.58415200000007],[-93.28443900000002,78.58749400000005],[-93.43415799999997,78.6336060000001],[-93.77139299999999,78.75054900000003],[-93.81361399999997,78.76582300000007],[-93.80277999999993,78.770264],[-93.68415800000002,78.782486],[-93.650284,78.78471400000012],[-93.589722,78.78359999999998],[-93.53443899999996,78.7788700000001],[-93.429169,78.76721200000009],[-93.37638899999996,78.7605440000001],[-93.35139499999997,78.75610400000011],[-93.29972800000002,78.74859600000008],[-93.24722300000002,78.74192800000009],[-93.19055199999997,78.73637400000013],[-93.16332999999997,78.73553500000014],[-93.09973100000002,78.73719800000009],[-93.05499299999997,78.73997499999996],[-93.04222099999987,78.74525500000004],[-93.039963,78.75000000000006],[-93.03944399999995,78.75109900000007],[-93.03527799999995,78.761932],[-93.03778099999994,78.76582300000007],[-93.11888099999999,78.77249100000006],[-93.17027300000001,78.77998400000007],[-93.27194199999997,78.79609700000015],[-93.34638999999993,78.80998200000005],[-93.36915599999998,78.81608600000004],[-93.391388,78.82083100000011],[-93.41639700000002,78.824997],[-93.56054699999993,78.83332800000011],[-93.589722,78.83471700000007],[-93.650284,78.83554100000003],[-93.74694799999997,78.834991],[-93.77972399999999,78.8336030000001],[-93.84277299999997,78.83248900000012],[-93.87470999999994,78.8336030000001],[-93.89250199999998,78.83804299999991],[-93.902222,78.84248400000001],[-93.906387,78.849152],[-93.91749599999997,78.86053500000003],[-93.93943799999994,78.871643],[-93.95944199999997,78.878311],[-94.05249000000003,78.90248100000002],[-94.09584000000001,78.91110200000008],[-94.25306699999999,78.95694000000003],[-94.26972999999998,78.96220400000004],[-94.28222700000003,78.96887200000003],[-94.28750600000001,78.98109399999998],[-94.28860500000002,78.98637400000007],[-94.24137899999988,78.99664300000006],[-94.00527999999991,79.02970900000003],[-93.91027799999995,79.04193099999998],[-93.87805199999997,79.04248000000013],[-93.85472099999993,79.04054300000007],[-93.81388900000002,79.03553800000003],[-93.78416400000003,79.03804000000014],[-93.60194399999989,79.06832899999995],[-93.472778,79.10887100000014],[-93.45556599999998,79.11970500000001],[-93.45249899999999,79.12553400000002],[-93.45666499999999,79.132202],[-93.46333300000003,79.13693200000006],[-93.46055599999994,79.14276100000006],[-93.44305400000002,79.14804100000009],[-93.36610399999995,79.16137700000007],[-93.32972699999993,79.16442899999998],[-93.29499799999991,79.16693100000009],[-93.25917099999992,79.16748000000001],[-93.22778299999993,79.16693100000009],[-93.00306699999999,79.1544340000001],[-92.89555399999995,79.14387500000004],[-92.86972000000003,79.13970899999993],[-92.84110999999996,79.14109800000011],[-92.816101,79.14553799999999],[-92.80139200000002,79.1502690000001],[-92.7933349999999,79.15582300000005],[-92.78028899999987,79.16110200000003],[-92.74694799999997,79.164154],[-92.50695799999994,79.15832499999999],[-92.47860699999995,79.15582300000005],[-92.40750099999991,79.14610299999998],[-92.30943300000001,79.14526400000005],[-92.24305700000002,79.14694199999997],[-91.89805599999994,79.16137700000007],[-91.69193999999999,79.17330900000002],[-91.43916299999995,79.18359399999997],[-91.20527599999997,79.19192500000003],[-91.00917099999987,79.20304899999996],[-90.81193499999995,79.2080380000001],[-90.60166900000002,79.21415700000011],[-90.56416299999995,79.21554600000013],[-90.52833599999991,79.21748400000007],[-90.49276700000001,79.2208250000001],[-90.39083900000003,79.23637400000001],[-90.36833199999995,79.243042],[-90.36326600000001,79.2468110000001],[-90.38221699999997,79.2494200000001],[-90.40556300000003,79.25193800000011],[-90.472778,79.25082399999991],[-90.50222799999995,79.2494200000001],[-90.73222399999997,79.23831200000012],[-90.88583399999999,79.24414100000013],[-91.13999899999993,79.24443100000013],[-91.19888300000002,79.24136400000003],[-91.47084000000001,79.22886700000004],[-91.86111499999993,79.21527100000009],[-92.02639799999997,79.20748900000012],[-92.053604,79.20526100000001],[-92.087784,79.20416300000011],[-92.18083200000001,79.20304899999996],[-92.21389799999997,79.20416300000011],[-92.23889200000002,79.20555100000001],[-92.51028400000001,79.23275799999993],[-92.62193300000001,79.24443100000013],[-92.67666600000001,79.25138900000013],[-92.69471699999997,79.25721700000008],[-92.69305399999996,79.2622070000001],[-92.62554899999998,79.29525800000005],[-92.60388199999994,79.30081200000006],[-92.57194499999997,79.3041530000001],[-92.52333099999993,79.30775500000004],[-92.454453,79.30859400000003],[-92.39472999999998,79.30859400000003],[-92.30332900000002,79.30636600000008],[-92.25500499999998,79.30442800000014],[-92.13137799999998,79.2999880000001],[-91.99499500000002,79.29525800000005],[-91.96194499999996,79.29553199999998],[-91.9324949999999,79.297211],[-91.89416499999999,79.301086],[-91.86527999999993,79.30554200000012],[-91.82945299999994,79.31469700000014],[-91.79554699999989,79.31915300000009],[-91.72749299999992,79.32609600000006],[-91.65888999999999,79.32998700000013],[-91.58972199999994,79.33221400000002],[-91.52888499999995,79.33305400000006],[-91.49388099999987,79.33248900000001],[-91.46749899999998,79.33360299999998],[-91.26777600000003,79.34582499999999],[-91.23167399999994,79.34803799999992],[-91.15834000000001,79.35609399999998],[-91.11999500000002,79.38638300000002],[-91.12916599999988,79.39082300000007],[-91.156387,79.39444000000003],[-91.19110099999995,79.39332600000006],[-91.23055999999997,79.38943499999999],[-91.42222599999997,79.37414600000005],[-91.508621,79.37330600000001],[-91.58084100000002,79.36914100000001],[-91.70222499999994,79.36137400000007],[-91.72972099999998,79.35942100000011],[-91.766663,79.35331700000012],[-91.78832999999997,79.34637500000002],[-91.83528100000001,79.34082000000012],[-91.86471599999999,79.33943199999999],[-91.89778100000001,79.339157],[-92.15083299999998,79.34443700000008],[-92.18110699999994,79.34582499999999],[-92.21000699999996,79.34832799999992],[-92.29083300000002,79.35803199999992],[-92.35194399999995,79.36276199999998],[-92.41194200000001,79.36442599999998],[-92.51000999999997,79.36415099999999],[-92.56193499999995,79.36581400000006],[-92.57167099999987,79.37052900000009],[-92.57749899999999,79.37915000000004],[-92.56750499999987,79.38415500000008],[-92.47999600000003,79.40443400000004],[-92.46250900000001,79.40693700000003],[-92.41194200000001,79.41165200000006],[-92.31361400000003,79.41859399999993],[-92.24388099999999,79.4266510000001],[-92.22860700000001,79.43136600000014],[-92.22778299999993,79.43525700000004],[-92.228882,79.43830900000012],[-92.23472600000002,79.44164999999998],[-92.24194299999994,79.44413800000012],[-92.25917099999998,79.44693000000007],[-92.28332499999999,79.44914200000011],[-92.33805799999999,79.45304900000008],[-92.41972399999997,79.45721400000008],[-92.58084100000002,79.45220900000004],[-92.60527000000002,79.45054600000009],[-92.63417099999998,79.44581600000004],[-92.67999299999997,79.43719499999997],[-92.77417000000003,79.417755],[-92.80305499999997,79.41304000000014],[-92.854446,79.407761],[-92.87609899999995,79.407761],[-92.90167199999996,79.40887499999997],[-92.92944299999994,79.41249099999999],[-92.95083599999998,79.41638200000006],[-92.97332799999998,79.42359899999997],[-93.02917500000001,79.46026599999999],[-93.03277599999996,79.46554600000007],[-93.03472899999991,79.47164900000001],[-93.04472399999992,79.476089],[-93.06304899999992,79.48054500000012],[-93.09056099999998,79.48220800000007],[-93.10722399999997,79.48220800000007],[-93.12666299999995,79.47998000000007],[-93.14388999999989,79.47581500000007],[-93.14666699999998,79.46998600000006],[-93.144455,79.46388200000007],[-93.125,79.45082100000013],[-93.10583499999996,79.43942300000009],[-93.08138999999994,79.42637600000006],[-93.06111099999998,79.41581700000006],[-93.03361499999994,79.40443400000004],[-93.01889,79.399719],[-93.00917099999998,79.395264],[-93.00695799999994,79.38916000000012],[-93.00834700000001,79.38804600000014],[-93.00944500000003,79.38720699999999],[-93.02139299999999,79.3827510000001],[-93.125,79.35971100000012],[-93.26417500000002,79.3535920000001],[-93.31249999999994,79.37275700000009],[-93.25111399999997,79.40498400000007],[-93.23611499999998,79.41526800000008],[-93.22972099999998,79.42553700000013],[-93.23138399999999,79.42997700000012],[-93.23500100000001,79.43525700000004],[-93.25250199999999,79.44192499999997],[-93.27583300000003,79.44664],[-93.29333499999996,79.44802900000002],[-93.32000700000003,79.44831799999997],[-93.33805799999993,79.44720500000005],[-93.354446,79.44136000000015],[-93.4244379999999,79.405258],[-93.4330599999999,79.387497],[-93.485275,79.35415600000005],[-93.64138799999989,79.31164600000011],[-93.75750700000003,79.28360000000004],[-93.80194099999989,79.2747040000001],[-93.86999500000002,79.26388500000007],[-93.90666199999998,79.26054400000004],[-93.96972699999998,79.25749200000007],[-93.99722300000002,79.25694299999998],[-94.04722599999997,79.25749200000007],[-94.206955,79.27249099999995],[-94.212219,79.27665700000006],[-94.162781,79.32222000000002],[-94.14805599999994,79.33360299999998],[-94.11972000000003,79.34471100000002],[-94.08860800000002,79.3535920000001],[-94.05638099999993,79.37970000000007],[-94.245834,79.4041600000001],[-94.36665299999999,79.41970800000013],[-94.38612399999994,79.42137100000002],[-94.49472000000003,79.42137100000002],[-94.50917099999998,79.41638200000006],[-94.5,79.37970000000007],[-94.48306300000002,79.375809],[-94.46305799999999,79.37915000000004],[-94.454453,79.3855440000001],[-94.43276999999995,79.3855440000001],[-94.398056,79.37525900000014],[-94.38999899999999,79.36886600000003],[-94.50666799999999,79.33720400000004],[-94.53805499999993,79.33360299999998],[-94.57362399999994,79.33110000000005],[-94.63890099999998,79.33248900000001],[-94.66999799999996,79.33137500000004],[-94.697495,79.32666],[-94.72000100000002,79.32165500000013],[-94.765015,79.31164600000011],[-94.95249899999993,79.28997800000002],[-94.97000099999997,79.28471400000001],[-94.97277799999989,79.27388000000013],[-94.97721899999999,79.27026400000011],[-94.98582499999998,79.26748700000002],[-95.01861600000001,79.26693699999998],[-95.08755500000001,79.27075200000013],[-95.16166699999997,79.28109700000005],[-95.30499299999997,79.32582100000002],[-95.31861900000001,79.33221400000002],[-95.32028200000002,79.3352660000001],[-95.29444899999999,79.33665500000012],[-95.28500400000001,79.35304299999996],[-95.295837,79.37942500000003],[-95.39416499999999,79.387497],[-95.47721899999999,79.38081400000004],[-95.65556300000003,79.39166300000011],[-95.75334199999998,79.40443400000004],[-95.77166699999998,79.40971400000006],[-95.77860999999996,79.41304000000014],[-95.779449,79.42581200000012],[-95.73638899999997,79.53749100000005],[-95.65750099999997,79.55331400000011],[-95.63612399999994,79.55748],[-95.56555200000003,79.55914300000012],[-95.30972299999996,79.56915300000003],[-95.17027300000001,79.57527200000004],[-95.05166599999995,79.58221400000014],[-94.83999599999987,79.59721400000012],[-94.80248999999998,79.60054000000014],[-94.699432,79.61219800000015],[-94.40695199999999,79.66775500000011],[-94.360275,79.67776500000002],[-94.329453,79.68830900000006],[-94.28277600000001,79.75749200000001],[-94.28694200000001,79.76277200000004],[-94.29834,79.76887499999998],[-94.31834400000002,79.77859500000005],[-94.33528100000001,79.78082300000005],[-94.36166400000002,79.78193700000003],[-94.38417099999998,79.77804600000013],[-94.57749899999993,79.73580900000007],[-94.59249899999998,79.73109400000004],[-94.59666399999998,79.72581500000001],[-94.60139500000002,79.71388200000001],[-94.60888699999992,79.708328],[-94.74833699999994,79.678314],[-94.77667199999996,79.67359899999997],[-94.81443799999994,79.6702580000001],[-94.87832599999996,79.66804500000012],[-94.94638099999997,79.66693099999998],[-94.98500100000001,79.66499300000004],[-95.09167500000001,79.65693699999997],[-95.15361000000001,79.647491],[-95.19082599999996,79.64414999999997],[-95.35555999999997,79.63832100000013],[-95.41999800000002,79.637497],[-95.48527499999994,79.63804600000009],[-95.7408289999999,79.64137300000004],[-95.79943799999995,79.64248700000002],[-95.85333299999996,79.6461030000001],[-95.90110799999997,79.65443399999998],[-95.93306000000001,79.6644290000001],[-95.95472699999999,79.671921],[-95.98083500000001,79.6827550000001],[-96.03222700000003,79.70694000000009],[-96.28250100000002,79.79887400000001],[-96.335556,79.81553600000001],[-96.36082499999998,79.82249500000006],[-96.38417099999992,79.82638500000007],[-96.49055499999997,79.83610499999998],[-96.57556199999993,79.84999099999993],[-96.589447,79.85247800000002],[-96.61054999999999,79.87776200000002],[-96.61500499999994,79.88388100000003],[-96.60943600000002,79.88859600000006],[-96.573624,79.9002690000001],[-96.458618,79.91442900000004],[-96.422775,79.91609199999994],[-96.39138799999995,79.91387900000001],[-96.38500999999991,79.90971400000001],[-96.37777699999998,79.89915500000012],[-96.19471699999991,79.90138200000001],[-96.15888999999987,79.90304600000002],[-96.13806199999999,79.90637200000003],[-96.14778099999995,79.9124910000001],[-96.16471899999999,79.91720599999991],[-96.23332199999993,79.93304399999994],[-96.26251200000002,79.93692000000004],[-96.32556199999999,79.94136000000003],[-96.39917000000003,79.9410860000001],[-96.49276699999996,79.94331400000004],[-96.52416999999997,79.9452510000001],[-96.55665599999998,79.94886800000006],[-96.58056599999998,79.95277399999998],[-96.59583999999995,79.95694000000003],[-96.60665899999992,79.96220400000004],[-96.675003,80.00833100000006],[-96.67944299999999,80.0144350000001],[-96.66194199999995,80.01998900000012],[-96.62805200000003,80.02442900000011],[-96.48277299999995,80.04109199999999],[-96.41915899999992,80.04193099999998],[-96.39416499999987,80.04386900000009],[-96.39167799999996,80.04582200000004],[-96.40583799999996,80.04832500000003],[-96.428879,80.05053700000008],[-96.479172,80.05386400000003],[-96.51222200000001,80.05497700000012],[-96.54861499999993,80.053314],[-96.58250399999991,80.04859899999997],[-96.59916699999991,80.04443400000014],[-96.62777699999992,80.0394290000001],[-96.67610199999996,80.04193099999998],[-96.69888299999997,80.04693600000002],[-96.737503,80.05802900000003],[-96.78167699999995,80.07666000000006],[-96.80139199999996,80.08692900000005],[-96.80277999999998,80.09082000000012],[-96.74888599999986,80.13472000000013],[-96.73443600000002,80.1397090000001],[-96.71112099999993,80.14498900000001],[-96.67582700000003,80.1455380000001],[-96.41000399999996,80.13888500000013],[-96.38110399999994,80.13638300000008],[-96.35139500000002,80.132477],[-96.32278400000001,80.12747200000013],[-96.16305499999987,80.09304800000007],[-96.077789,80.07804900000002],[-96.01777600000003,80.070831],[-95.84777799999989,80.053314],[-95.54583699999995,80.04054300000007],[-95.41888399999993,80.036652],[-95.32501199999996,80.03387500000008],[-95.19387799999998,80.03137200000009],[-95.06361400000003,80.02998400000001],[-95.03805499999999,80.03193699999997],[-95.01167299999992,80.03887900000007],[-94.98889200000002,80.04304500000012],[-94.95111099999986,80.04553200000004],[-94.92138699999992,80.04637100000002],[-94.88751200000002,80.04582200000004],[-94.85278299999987,80.04414400000013],[-94.82583599999992,80.04054300000007],[-94.71777299999997,80.02082800000005],[-94.60749800000002,80.0027770000001],[-94.56945799999994,79.99720800000011],[-94.416946,79.9788670000001],[-94.38362099999995,79.98248299999995],[-94.38778699999995,79.98776199999992],[-94.41389499999991,79.99775700000004],[-94.45167499999997,80.00972000000007],[-94.52555799999993,80.02276599999999],[-94.62110899999999,80.04304500000012],[-94.67111199999988,80.05693100000013],[-94.74888599999997,80.07998699999996],[-94.72888199999994,80.10554500000006],[-94.63276699999994,80.13108800000003],[-94.61193799999995,80.1355440000001],[-94.51055899999994,80.15443400000004],[-94.48055999999985,80.15914900000007],[-94.41639699999996,80.16360500000002],[-94.38722200000001,80.16331500000001],[-94.28582799999992,80.1649930000001],[-94.12110899999993,80.17025799999999],[-94.09167500000001,80.17248500000005],[-94.08389299999999,80.17553700000013],[-94.09638999999999,80.17915300000004],[-94.11999500000002,80.18304400000011],[-94.18443300000001,80.18664600000005],[-94.21777299999997,80.18803400000013],[-94.35417199999995,80.19081100000005],[-94.48500099999995,80.209991],[-94.64222699999999,80.199997],[-94.64999399999988,80.19442700000008],[-94.704453,80.17804000000012],[-94.74833699999994,80.16943400000002],[-94.816956,80.15971400000012],[-95.03332499999999,80.134995],[-95.10499600000003,80.12886000000003],[-95.26362599999999,80.1183170000001],[-95.333618,80.11804200000006],[-95.36776700000001,80.1183170000001],[-95.42027300000001,80.1224820000001],[-95.65888999999999,80.16859399999998],[-95.68388400000003,80.17387400000001],[-95.695831,80.17831400000006],[-95.69221500000003,80.18109099999998],[-95.67388900000003,80.18637100000001],[-95.62165800000002,80.19525100000004],[-95.58084100000002,80.19970699999999],[-95.54277000000002,80.20220900000004],[-95.47111499999994,80.20359800000006],[-95.40417500000001,80.20359800000006],[-95.370544,80.20471200000003],[-95.32778899999988,80.2086030000001],[-95.295837,80.21276899999998],[-95.26834100000002,80.21804799999995],[-95.25445599999995,80.22221400000006],[-95.2350009999999,80.23220800000007],[-95.22999600000003,80.23609899999997],[-95.2350009999999,80.24108899999999],[-95.24333199999995,80.2435910000001],[-95.258896,80.24498000000006],[-95.27806099999992,80.24386600000008],[-95.287216,80.24108899999999],[-95.32556199999999,80.23220800000007],[-95.39834599999989,80.22360200000014],[-95.46139499999987,80.21998600000012],[-95.49694799999997,80.21943699999997],[-95.54834,80.22026100000011],[-95.56695599999995,80.224152],[-95.57749899999999,80.22943099999998],[-95.58138999999989,80.23553500000003],[-95.58639499999992,80.24054000000007],[-95.601944,80.24220300000002],[-95.64584400000001,80.23970000000003],[-95.69027699999998,80.23248300000012],[-95.71055599999994,80.22776800000008],[-95.88417099999998,80.19914200000011],[-95.92250099999995,80.19413800000001],[-95.93360899999999,80.19442700000008],[-95.98443599999996,80.20027199999998],[-96.21665999999988,80.23580900000013],[-96.43499799999995,80.26971400000002],[-96.46444699999995,80.31303400000002],[-96.61389200000002,80.32998700000013],[-96.64584400000001,80.333054],[-96.67027299999995,80.336929],[-96.68167099999988,80.34220900000008],[-96.67610199999996,80.34693900000013],[-96.658051,80.35220300000009],[-96.63417099999998,80.35720800000013],[-96.60472099999998,80.36219800000003],[-96.59222399999999,80.36276199999998],[-96.44055200000003,80.35664400000002],[-96.40888999999999,80.3535920000001],[-96.36389200000002,80.34220900000008],[-96.25472999999994,80.33554100000009],[-96.23222399999997,80.33471700000013],[-96.21640000000002,80.33804299999997],[-96.22166400000003,80.34332300000005],[-96.25500499999998,80.35415600000005],[-96.27722199999994,80.35998500000005],[-96.28083800000002,80.36192299999999],[-96.26806599999992,80.36747700000001],[-96.24055499999997,80.37303200000008],[-96.08084100000002,80.38720699999999],[-96.04777499999989,80.38998400000008],[-95.97860699999995,80.388596],[-95.73249799999991,80.37275700000004],[-95.697495,80.36997999999994],[-95.63694800000002,80.36415099999994],[-95.61221299999994,80.36026000000004],[-95.56695599999995,80.35220300000009],[-95.54277000000002,80.34582499999993],[-95.51390099999998,80.34082000000006],[-95.48832699999997,80.33804299999997],[-95.46028099999995,80.336929],[-95.44082600000002,80.33831800000002],[-95.436935,80.34109500000011],[-95.45333899999997,80.37330600000001],[-95.45861799999994,80.37858600000004],[-95.46806300000003,80.38220200000012],[-95.49861099999998,80.38388099999997],[-95.56416299999995,80.38581799999997],[-95.62499999999994,80.39166300000011],[-95.653885,80.39665200000007],[-95.69499200000001,80.4060970000001],[-95.72166400000003,80.41276599999998],[-95.85221899999999,80.45416300000005],[-95.95722999999992,80.50499000000013],[-96.02055399999995,80.56749000000008],[-96.027222,80.57415800000007],[-96.02444500000001,80.57832300000007],[-96.00695799999988,80.58276399999994],[-95.97999600000003,80.58471700000007],[-95.94166599999994,80.58638000000002],[-95.67166099999997,80.58471700000007],[-95.53639199999998,80.59082000000001],[-95.49804699999987,80.59248400000007],[-95.42361499999998,80.5935970000001],[-95.31834399999991,80.59082000000001],[-95.24665800000002,80.58998100000008],[-95.17222600000002,80.59137000000004],[-95.13221699999997,80.59387200000015],[-95.06723,80.60137900000007],[-95.0308379999999,80.603317],[-94.99499499999996,80.60304300000007],[-94.96278399999994,80.59971599999994],[-94.90249599999999,80.58665500000001],[-94.84695399999993,80.57470699999999],[-94.823624,80.56971699999997],[-94.77194199999991,80.56137100000007],[-94.75279199999994,80.55998200000005],[-94.69665499999996,80.55693100000002],[-94.658615,80.55581700000005],[-94.55499299999991,80.55442800000003],[-94.37499999999994,80.55720500000012],[-94.23083500000001,80.55636599999997],[-94.010559,80.54942299999999],[-93.968887,80.54081700000006],[-93.968887,80.536926],[-93.96611000000001,80.53082300000005],[-93.95834399999995,80.52609300000006],[-93.89916999999997,80.51915000000002],[-93.86694299999999,80.51832600000006],[-93.839447,80.51859999999999],[-93.78639199999998,80.52554300000003],[-93.78306600000002,80.52970900000008],[-93.79083299999996,80.53442400000012],[-93.81054699999999,80.5413670000001],[-93.89472999999987,80.56581100000005],[-93.94915800000001,80.57804899999991],[-93.97361799999993,80.58193999999997],[-94.00500499999998,80.58526600000005],[-94.09361299999995,80.593323],[-94.308334,80.60636899999997],[-94.43777499999999,80.605545],[-94.45750399999991,80.60026599999998],[-94.48472600000002,80.59832800000004],[-94.52417000000003,80.59832800000004],[-94.54333500000001,80.59971599999994],[-94.561935,80.60582],[-94.660278,80.65138200000001],[-94.66944899999993,80.65776100000005],[-94.672775,80.66387900000001],[-94.67027300000001,80.66970800000001],[-94.66221599999994,80.67526200000003],[-94.650284,80.68136600000008],[-94.62832600000002,80.68580600000007],[-94.59695399999998,80.69053600000012],[-94.553604,80.69497700000005],[-94.51472499999994,80.69636500000013],[-94.43916300000001,80.6974790000001],[-94.33111600000001,80.69386300000002],[-94.23167399999988,80.69220000000013],[-94.19972200000001,80.69303900000006],[-94.11749299999997,80.69859300000007],[-94.08833299999998,80.70166],[-94.07556199999999,80.70609999999999],[-94.07695000000001,80.70915200000013],[-94.08639499999998,80.71304300000003],[-94.108337,80.71887200000003],[-94.140289,80.72192400000012],[-94.30444299999994,80.73387100000008],[-94.42304999999988,80.73498500000005],[-94.44915800000001,80.73027000000002],[-94.491104,80.72692899999998],[-94.54943800000001,80.72499100000005],[-94.65972899999997,80.72526600000009],[-94.69471699999997,80.726654],[-94.722778,80.7285920000001],[-94.895554,80.74775700000009],[-95.03582799999987,80.768326],[-95.03750599999995,80.77137800000014],[-95.03694200000001,80.776093],[-95.03388999999999,80.77804600000013],[-95.025284,80.8016510000001],[-95.24305699999996,80.78776600000003],[-95.28250100000002,80.78610199999997],[-95.33416699999992,80.78887900000007],[-95.44276400000001,80.79971299999994],[-95.47555499999999,80.80304000000007],[-95.50111399999997,80.80693100000013],[-95.52417000000003,80.81248499999998],[-95.53416400000003,80.8188780000001],[-95.52639799999997,80.83332800000005],[-95.50083899999987,80.83831800000007],[-95.44027699999998,80.84610000000004],[-95.37138400000003,80.85331699999995],[-95.212784,80.8683170000001],[-95.170837,80.87580900000006],[-95.15083299999992,80.88108800000003],[-95.14666699999992,80.88388100000003],[-95.170547,80.88472000000002],[-95.30082700000003,80.88526900000011],[-95.41332999999986,80.88526900000011],[-95.468887,80.89027399999998],[-95.48138399999999,80.89471400000002],[-95.48472600000002,80.89915500000012],[-95.47416699999997,80.9044340000001],[-95.46028099999995,80.90971399999995],[-95.422775,80.92082199999999],[-95.33416699999992,80.93470800000011],[-95.31193499999995,80.93914799999999],[-95.28361499999994,80.949997],[-95.26750199999998,80.96138000000002],[-95.25973499999992,80.97360200000003],[-95.25750699999998,80.97943100000003],[-95.25917099999998,80.984985],[-95.25500499999998,80.99664300000006],[-95.241104,81.006104],[-95.2208399999999,81.01138299999997],[-95.18306000000001,81.01971400000008],[-94.943329,81.04887400000013],[-94.81416300000001,81.0541530000001],[-94.66305499999999,81.04859899999991],[-94.5727839999999,81.03887900000001],[-94.546112,81.03332500000005],[-94.49388099999999,81.01748700000002],[-94.495544,80.9958190000001],[-94.50418100000002,80.99026500000008],[-94.50917099999998,80.98471100000006],[-94.50805700000001,80.97943100000003],[-94.49276700000001,80.97276300000004],[-94.472778,80.96914699999996],[-94.43415800000002,80.96554600000013],[-94.40861499999994,80.96554600000013],[-94.36555499999997,80.96887200000015],[-94.34472699999998,80.97415200000006],[-94.33000199999987,80.97970600000002],[-94.14361600000001,81.01582300000001],[-94.07167099999992,81.02499399999994],[-93.908051,81.03942900000004],[-93.906387,81.04054300000007],[-94.01333599999998,81.05358899999999],[-94.04222099999993,81.05554200000012],[-94.18249499999996,81.06805400000007],[-94.32861299999996,81.08943200000004],[-94.35749800000002,81.09526100000005],[-94.36221299999994,81.10054000000002],[-94.35360700000001,81.10609399999998],[-94.34555099999994,81.10942100000011],[-94.31304899999998,81.11553999999995],[-94.27833599999997,81.11720300000007],[-94.25527999999997,81.11553999999995],[-94.23083500000001,81.11053500000008],[-94.21472199999988,81.10636900000003],[-94.19583099999994,81.10026600000009],[-94.15472399999999,81.09387200000003],[-94.13027999999997,81.09275800000006],[-93.98971599999999,81.09248400000013],[-93.96083099999993,81.09414700000008],[-93.93527199999994,81.09832799999998],[-93.90722700000003,81.101654],[-93.86639400000001,81.10304300000001],[-93.79527300000001,81.09942600000005],[-93.689438,81.09304800000007],[-93.51722699999988,81.08442699999995],[-93.29998799999993,81.07971199999992],[-93.25584400000002,81.08276400000005],[-93.16305499999993,81.0919340000001],[-93.15222199999994,81.09471100000002],[-93.12332199999992,81.11526500000014],[-93.09555099999994,81.1541600000001],[-93.09167499999995,81.15998800000006],[-93.09583999999995,81.16526800000008],[-93.12110899999993,81.18275499999993],[-93.25973499999998,81.21220399999993],[-93.41944899999993,81.21998600000006],[-93.514725,81.21775800000012],[-93.68749999999994,81.21026599999999],[-93.72833300000002,81.20721400000008],[-93.85221899999993,81.20304900000008],[-93.928879,81.20387300000004],[-94.03138699999994,81.20887800000008],[-94.16639700000002,81.21804800000012],[-94.20056199999988,81.22110000000004],[-94.28222700000003,81.2310940000001],[-94.30248999999998,81.23498499999994],[-94.38166799999999,81.25082400000008],[-94.38806199999999,81.25499000000013],[-94.391388,81.26110800000009],[-94.38612399999994,81.2727660000001],[-94.37027,81.28471400000001],[-94.27861000000001,81.34193400000004],[-94.26861600000001,81.34609999999992],[-94.24082900000002,81.35081499999995],[-94.20056199999988,81.355545],[-94.15388499999995,81.35971100000012],[-94.06806899999998,81.36331199999995],[-94.035278,81.36331199999995],[-93.789444,81.34803800000009],[-93.75500499999993,81.34471100000013],[-93.69444299999992,81.33749400000005],[-93.66583300000002,81.332764],[-93.63890099999998,81.3272090000001],[-93.62193300000001,81.32165500000008],[-93.61138900000003,81.3163760000001],[-93.59445199999993,81.31053199999991],[-93.55332900000002,81.30554200000006],[-93.515289,81.31053199999991],[-93.4949949999999,81.31469700000008],[-93.48306300000002,81.31971699999997],[-93.483612,81.32527200000004],[-93.48805199999998,81.33055100000001],[-93.53332499999999,81.34860200000003],[-93.56054699999993,81.367752],[-93.56471299999993,81.3766480000001],[-93.55055199999993,81.38108799999992],[-93.51750199999998,81.38499500000006],[-93.34028599999999,81.37220800000006],[-93.17749000000003,81.35859700000009],[-93.01556399999987,81.3413700000001],[-92.92805499999997,81.33082600000006],[-92.83168,81.31776400000001],[-92.72778299999993,81.30554200000006]],[[-91.71833799999996,81.54914900000006],[-91.76167299999997,81.54803500000008],[-91.80139199999996,81.54859900000002],[-91.83750900000001,81.55108600000011],[-91.86361699999998,81.555252],[-91.95111099999991,81.58415200000002],[-91.95861799999994,81.58888200000007],[-91.960556,81.59498600000012],[-91.95611599999995,81.60081500000013],[-91.9324949999999,81.60582],[-91.90388499999995,81.60832200000004],[-91.86833200000001,81.60859700000009],[-91.82389799999999,81.60693400000014],[-91.789444,81.603317],[-91.72471599999994,81.59610000000009],[-91.597778,81.58055099999996],[-91.58222999999992,81.57804900000008],[-91.61999500000002,81.56248499999998],[-91.6436159999999,81.55748000000011],[-91.67361499999998,81.55276500000008],[-91.71833799999996,81.54914900000006]],[[-78.36582899999996,82.88360599999999],[-78.383331,82.88360599999999],[-78.41944899999999,82.89915500000006],[-78.41722099999993,82.93553200000002],[-78.41471899999993,82.94192500000003],[-78.40583800000002,82.94775400000003],[-78.38972499999988,82.95332300000001],[-78.36166399999996,82.9586030000001],[-78.32333399999987,82.96192900000011],[-78.27389499999987,82.96304300000008],[-78.22361799999999,82.96110499999998],[-78.14527900000002,82.95471200000003],[-78.11972000000003,82.94859299999996],[-78.11694299999999,82.94220000000001],[-78.12249800000001,82.93719499999997],[-78.15083300000003,82.92692599999992],[-78.212784,82.91137700000002],[-78.33639499999998,82.88804600000014],[-78.36582899999996,82.88360599999999]],[[-70.11193799999995,83.10942100000011],[-70.00140399999998,83.10775799999999],[-69.81221,83.11219799999998],[-69.74888599999997,83.11192299999999],[-69.70167500000002,83.11053500000008],[-69.665009,83.1083220000001],[-69.65916400000003,83.10304300000013],[-69.66221599999994,83.07415800000007],[-69.66416899999996,83.07083099999994],[-69.68055700000002,83.06498699999997],[-69.71610999999996,83.06109600000008],[-69.75750699999998,83.05775500000004],[-69.77389499999998,83.05192600000004],[-69.77528399999994,83.0477600000001],[-69.74444599999998,83.04553199999998],[-69.67193600000002,83.04109199999994],[-69.636124,83.03970300000015],[-69.47138999999999,83.03887900000001],[-69.45111099999997,83.03581200000008],[-69.51333599999998,83.01971400000002],[-69.53611799999999,83.01443500000005],[-69.56500199999994,83.009995],[-69.55972299999996,82.99414100000013],[-69.23306299999996,83.01026899999994],[-69.15638699999994,83.01748700000013],[-69.120544,83.02165200000013],[-69.09777799999995,83.026657],[-69.06361400000003,83.03804000000002],[-69.01556399999993,83.04081700000012],[-68.98306300000002,83.03665200000012],[-68.975281,83.02832000000012],[-68.97389199999998,83.01554900000002],[-68.97721899999999,83.00166300000006],[-68.90278599999994,82.98831200000006],[-68.70834400000001,82.97804300000007],[-68.66500899999994,82.98027000000013],[-68.630829,82.98525999999998],[-68.62666300000001,82.9869230000001],[-68.57972699999999,82.99693300000001],[-68.55055199999993,83.00166300000006],[-68.514725,83.00555400000013],[-68.46665999999999,83.00804099999999],[-68.40472399999999,83.008331],[-68.35804699999989,83.00610399999994],[-68.316101,83.00332600000013],[-68.19082600000002,82.99470500000007],[-68.15417500000001,82.99108899999999],[-68.14222699999993,82.98359700000003],[-68.15527299999997,82.972488],[-68.17777999999998,82.959991],[-68.18859900000001,82.94609100000008],[-68.17639199999996,82.93887300000006],[-68.145554,82.93498199999999],[-68.09973100000002,82.93359400000008],[-68.06806899999998,82.93525700000004],[-68.054169,82.93887300000006],[-67.88166799999993,82.95887800000008],[-67.666946,82.96971100000007],[-67.61082499999992,82.96887200000009],[-67.54415899999998,82.96220399999993],[-67.50140399999998,82.95721400000008],[-67.49999999999994,82.95701600000007],[-67.47610499999996,82.95359800000006],[-67.41000399999996,82.94664000000006],[-67.32778899999994,82.94081100000005],[-67.241669,82.93691999999999],[-67.19665500000002,82.93609600000002],[-67.13612399999994,82.93664600000005],[-67.11694299999999,82.94108600000004],[-67.122772,82.94914200000011],[-67.12165800000002,82.95526100000012],[-67.11332700000003,82.95942700000006],[-67.09222399999993,82.96110499999998],[-67.04110700000001,82.95971700000007],[-66.964722,82.95416300000005],[-66.93998699999992,82.95054600000009],[-66.93832399999991,82.94775400000003],[-66.818893,82.93525700000004],[-66.65306099999987,82.93637100000001],[-66.33000199999992,82.93386800000002],[-66.30139199999996,82.93193100000002],[-66.29943799999995,82.92942800000003],[-66.34750399999996,82.89804100000009],[-66.36915599999992,82.88832100000002],[-66.81138599999997,82.81526200000002],[-66.84111000000001,82.81080600000007],[-66.87666300000001,82.80720500000007],[-66.95973200000003,82.80081200000006],[-67.13833599999998,82.78387500000008],[-67.31527699999998,82.76470900000004],[-67.386124,82.75776700000011],[-67.45777899999996,82.75221299999993],[-67.49999999999994,82.74961100000013],[-67.597778,82.74359099999992],[-67.64472999999992,82.74165299999999],[-67.79916400000002,82.73165899999998],[-67.91416899999996,82.71998600000012],[-68.041382,82.7038730000001],[-68.08167999999995,82.70082100000002],[-68.13417099999998,82.69859300000002],[-68.23472600000002,82.69664000000012],[-68.27610800000002,82.69470199999995],[-68.35665899999998,82.68803400000002],[-68.4244379999999,82.67970300000007],[-68.633621,82.64860500000009],[-68.65583800000002,82.64360000000005],[-68.67222599999997,82.6377720000001],[-68.66722099999998,82.63247700000005],[-68.64250199999998,82.62858599999998],[-68.57362399999994,82.62886000000009],[-68.46501199999994,82.63943500000005],[-68.4244379999999,82.6419370000001],[-68.32583599999998,82.64553799999999],[-67.93499800000001,82.65832499999999],[-67.81277499999999,82.65914900000013],[-67.60665899999992,82.65554800000007],[-67.51806599999986,82.65109300000006],[-67.47084000000001,82.65220599999998],[-67.43055700000002,82.65554800000007],[-67.38194299999998,82.66276600000009],[-67.32806399999998,82.67719999999991],[-67.275284,82.68609600000002],[-67.245834,82.68969700000008],[-67.21083099999993,82.69358799999998],[-66.997772,82.71220399999999],[-66.900284,82.71943700000003],[-66.670837,82.74026500000008],[-66.65722700000003,82.74443099999996],[-66.63833599999998,82.74887100000001],[-66.122772,82.81303400000007],[-66.08667000000003,82.816666],[-65.81027199999994,82.84082000000012],[-65.76777600000003,82.84304800000007],[-65.72416699999991,82.84359700000005],[-65.54666099999992,82.83804300000003],[-65.46777299999985,82.833328],[-65.45472699999999,82.829163],[-65.481674,82.816666],[-65.495834,82.8119200000001],[-65.52722199999994,82.79748499999994],[-65.51806599999998,82.78997800000002],[-65.511124,82.786652],[-65.45861799999989,82.77943399999998],[-65.43083200000001,82.77748100000002],[-65.19749499999995,82.76416000000006],[-65.164444,82.76304600000009],[-65.15472399999999,82.76527400000003],[-65.16749600000003,82.76998900000007],[-65.25917099999992,82.7816620000001],[-65.32749899999999,82.78915400000005],[-65.33972199999994,82.79193099999998],[-65.35305799999998,82.797211],[-65.34445199999999,82.80192600000004],[-65.22193899999996,82.83276400000005],[-65.10278299999993,82.84803799999997],[-65.11000100000001,82.85276799999997],[-65.12805200000003,82.85609400000004],[-65.172775,82.85832199999999],[-65.27278100000001,82.86109900000008],[-65.30749499999996,82.86554000000001],[-65.28916899999996,82.87330600000001],[-65.25805700000001,82.87747200000013],[-65.10472099999998,82.89166300000011],[-64.98222399999997,82.901093],[-64.88473499999992,82.90582300000005],[-64.83555599999994,82.90693700000003],[-64.72972099999993,82.9041600000001],[-64.68472300000002,82.90165700000011],[-64.65556299999997,82.89694200000008],[-64.6641689999999,82.89027399999992],[-64.678604,82.88472000000013],[-64.71389799999992,82.87637299999994],[-64.75195300000001,82.87525900000014],[-64.79055800000003,82.875809],[-64.82972699999993,82.87776200000013],[-64.89028899999994,82.87803600000007],[-64.92250100000001,82.87637299999994],[-64.93693499999995,82.87136800000007],[-64.92361499999998,82.86469999999991],[-64.883896,82.86164900000011],[-64.83999599999999,82.86192300000005],[-64.74638400000003,82.86053500000014],[-64.723053,82.85636900000003],[-64.710556,82.85247800000013],[-64.71389799999992,82.84637500000002],[-64.72277799999995,82.84082000000012],[-64.74221799999992,82.834427],[-64.75083899999993,82.82832300000013],[-64.73777799999999,82.82222000000002],[-64.706955,82.81303400000007],[-64.64805599999994,82.79971300000011],[-64.47860700000001,82.7644350000001],[-64.44526699999994,82.76193200000012],[-64.41805999999991,82.76138299999997],[-64.41278099999994,82.76220699999993],[-64.398056,82.76693699999998],[-64.328888,82.7872010000001],[-64.18638599999997,82.81915300000009],[-64.13999899999999,82.82804900000002],[-64.10305800000003,82.83166500000004],[-64.05972299999996,82.833328],[-63.972770999999966,82.83499100000012],[-63.672775,82.83471700000001],[-63.623610999999926,82.83360300000004],[-63.52972399999999,82.82832300000013],[-63.49083699999994,82.8252720000001],[-63.43472300000002,82.816666],[-63.38916799999993,82.80497700000006],[-63.38249999999999,82.79832500000003],[-63.38221699999991,82.76776100000012],[-63.397223999999994,82.76138299999997],[-63.479163999999855,82.73942599999992],[-63.51028400000001,82.73248300000012],[-63.52583299999998,82.730545],[-63.590836000000024,82.73304700000006],[-63.666106999999954,82.73136899999997],[-63.81944999999996,82.72137499999997],[-63.83499899999998,82.71914700000002],[-63.850280999999995,82.71582000000006],[-63.76445000000001,82.71527100000009],[-63.67888599999992,82.717758],[-63.65166499999998,82.7149960000001],[-63.54000100000002,82.69442700000013],[-63.502040999999906,82.68276200000008],[-63.42222600000002,82.66554300000001],[-63.28694899999999,82.6544340000001],[-63.25444799999997,82.6502690000001],[-63.232215999999994,82.64498900000001],[-63.22610500000002,82.64027399999998],[-63.235557999999855,82.633331],[-63.25583599999999,82.62719700000014],[-63.28722399999998,82.6249850000001],[-63.339721999999995,82.62359600000008],[-63.37638899999996,82.61998000000006],[-63.380829000000006,82.61526500000002],[-63.36944599999998,82.61053499999997],[-63.34749599999998,82.60498000000007],[-63.315001999999936,82.601089],[-63.27222399999994,82.59860200000014],[-63.229720999999984,82.59721400000001],[-63.11361699999992,82.59748799999994],[-63.071113999999966,82.59637500000008],[-63.03361499999994,82.59443699999997],[-62.99639099999996,82.59027100000003],[-62.96416499999998,82.58554100000003],[-62.942496999999946,82.5816650000001],[-62.926109,82.57609600000012],[-62.93055700000002,82.56999200000007],[-62.960556,82.55775499999993],[-63.059440999999936,82.511932],[-63.08943899999997,82.46638500000012],[-63.1199949999999,82.46360800000002],[-63.243889000000024,82.45776400000005],[-63.285004000000015,82.45498700000013],[-63.346106999999904,82.44914200000005],[-63.36611199999999,82.44497700000005],[-63.36999500000002,82.438873],[-63.32861300000002,82.43775900000003],[-63.27722199999994,82.43914800000005],[-63.148888,82.44692999999995],[-63.07167099999998,82.45193500000005],[-63.01583899999997,82.45971699999996],[-62.990836999999885,82.46720900000008],[-62.92083699999995,82.4910890000001],[-62.823616000000015,82.50444000000005],[-62.678337,82.51609800000006],[-62.55332899999996,82.524429],[-62.50666799999988,82.52665700000011],[-62.28694899999999,82.52804600000013],[-62.24500299999994,82.52804600000013],[-62.17166900000001,82.52554299999997],[-62.17138699999998,82.52137800000014],[-62.322776999999974,82.51110800000004],[-62.33306099999999,82.50416600000011],[-62.353057999999976,82.48637400000007],[-62.35278299999993,82.48109399999998],[-62.300835000000006,82.482483],[-62.264449999999954,82.48580900000002],[-62.21566799999988,82.49192800000009],[-62.21249799999987,82.495766],[-62.098052999999936,82.50221299999998],[-61.88417099999998,82.49275200000005],[-61.691666,82.48803700000002],[-61.58250399999997,82.482483],[-61.53082999999987,82.47831700000012],[-61.5,82.47415200000012],[-61.44860799999998,82.46443199999999],[-61.32611099999997,82.43969700000014],[-61.28556100000003,82.43026700000007],[-61.17027999999988,82.39526400000011],[-61.14111300000002,82.38304100000005],[-61.13138599999991,82.37747200000007],[-61.11222099999992,82.36387600000006],[-61.09860999999995,82.35026600000003],[-61.076392999999996,82.32083100000011],[-61.07861300000002,82.30108600000011],[-61.084723999999994,82.29359399999998],[-61.107779999999934,82.26776100000006],[-61.130359999999996,82.25293700000009],[-61.135558999999944,82.2474820000001],[-61.15694400000001,82.23525999999998],[-61.19332899999995,82.22360200000008],[-61.28111299999995,82.20277400000003],[-61.306389000000024,82.19720500000005],[-61.38805400000001,82.18331900000004],[-61.43332700000002,82.17637600000006],[-61.46361499999989,82.172485],[-61.5341719999999,82.16554300000007],[-61.599441999999954,82.16081200000013],[-61.80444299999999,82.14665200000007],[-61.86999499999996,82.10664400000002],[-61.885001999999986,82.10053999999997],[-62.07778199999996,82.05358899999999],[-62.12694499999998,82.04386900000009],[-62.25417299999998,82.01998900000007],[-62.278885,82.01582299999995],[-62.31305699999996,82.01249700000011],[-62.35694899999993,82.010269],[-62.51361800000001,82.00471500000015],[-62.57028199999996,81.97608900000006],[-62.94499999999999,81.92221100000012],[-63.040557999999976,81.90971400000012],[-63.2925029999999,81.87776199999996],[-63.38722199999995,81.86775200000005],[-63.65610499999997,81.8374940000001],[-63.715003999999965,81.82083100000006],[-63.761116000000015,81.811646],[-63.81722300000001,81.80470300000002],[-63.849723999999924,81.80108600000005],[-63.925003000000004,81.7952580000001],[-63.96277599999996,81.79248000000013],[-64.01000999999997,81.79026800000008],[-64.05305499999992,81.78997800000002],[-64.08694500000001,81.79193099999998],[-64.11166399999996,81.79498300000012],[-64.13166799999999,81.799149],[-64.14222699999993,81.80304000000007],[-64.17777999999998,81.81053200000002],[-64.20750399999997,81.81442300000009],[-64.27166699999992,81.82165500000002],[-64.30139200000002,81.82415799999995],[-64.325287,81.8247070000001],[-64.323624,81.81915300000009],[-64.308044,81.81469700000002],[-64.25306699999999,81.8060910000001],[-64.23277299999995,81.80053700000008],[-64.12388599999997,81.768326],[-64.11805700000002,81.7644350000001],[-64.13473499999992,81.75471500000003],[-64.20777900000002,81.74192800000003],[-64.35526999999996,81.72637900000012],[-64.47250399999996,81.72137499999997],[-64.62943999999993,81.72248800000006],[-64.72000100000002,81.72387700000007],[-64.76777600000003,81.72581500000001],[-64.80166599999995,81.72831700000006],[-64.81221,81.73082000000005],[-64.83389299999993,81.73887600000012],[-64.83972199999994,81.74220300000007],[-64.885559,81.75082399999997],[-64.91000400000001,81.7527770000001],[-64.96221899999995,81.75221299999998],[-65.21665999999999,81.74552900000009],[-65.33750899999995,81.73776199999998],[-65.40972899999991,81.72831700000006],[-65.63137799999993,81.70248400000014],[-65.66833499999996,81.70082100000002],[-65.72555499999993,81.70166],[-65.77333099999998,81.70277399999998],[-65.92443799999995,81.70138500000013],[-66.01222199999995,81.69693000000012],[-66.03860500000002,81.692474],[-66.04222099999998,81.69053600000007],[-66.03028899999993,81.6849820000001],[-65.991379,81.68275500000004],[-65.82194499999997,81.68441799999994],[-65.612503,81.6808170000001],[-65.48777799999993,81.68748500000004],[-65.40417500000001,81.69081100000011],[-65.35249299999987,81.69192500000008],[-65.33667000000003,81.68803400000002],[-65.37083399999995,81.67886399999998],[-65.402222,81.67442300000005],[-65.52362099999999,81.65971400000001],[-65.61805699999991,81.64860500000009],[-65.78944399999995,81.63220200000006],[-65.87165799999991,81.62719700000002],[-65.910278,81.62969999999996],[-65.92639199999996,81.63415499999996],[-65.92721599999993,81.63554399999998],[-65.92443799999995,81.63970899999998],[-65.92721599999993,81.645828],[-65.94332899999989,81.65054300000003],[-65.98222399999992,81.65277100000003],[-66.02471899999995,81.65304600000002],[-66.04277000000002,81.651657],[-66.06471299999998,81.64776599999993],[-66.085556,81.64276100000006],[-66.10194399999995,81.6372070000001],[-66.14083899999997,81.62052900000003],[-66.17250100000001,81.61804200000012],[-66.21888699999994,81.61692800000014],[-66.35527000000002,81.61747700000012],[-66.39388999999994,81.61970500000007],[-66.43971299999998,81.62692300000009],[-66.47833300000002,81.62858599999998],[-66.57556199999993,81.626083],[-66.72749299999992,81.6202550000001],[-66.80499299999985,81.615814],[-66.89639299999993,81.6119230000001],[-67.15695199999999,81.60803200000004],[-67.50917099999992,81.60054000000008],[-67.55972300000002,81.599152],[-67.766663,81.59304799999995],[-67.79277000000002,81.58970600000004],[-68.11138900000003,81.56303400000013],[-68.15666199999998,81.56109600000002],[-68.23138399999999,81.56137100000001],[-68.27471899999995,81.56275900000009],[-68.30943300000001,81.56553600000001],[-68.33056599999992,81.56860400000005],[-68.35249299999998,81.57304400000004],[-68.41027799999989,81.58804300000008],[-68.45973199999997,81.597488],[-68.66139199999998,81.633331],[-68.71528599999999,81.64221199999997],[-68.976944,81.68441799999994],[-69.05888399999992,81.6974790000001],[-69.13999899999999,81.70887799999997],[-69.17639200000002,81.71249400000005],[-69.24722299999996,81.71748400000007],[-69.291382,81.71887199999998],[-69.29943800000001,81.71720900000008],[-69.30665599999998,81.71443199999999],[-69.291382,81.707764],[-69.26806599999998,81.70248400000014],[-69.21417200000002,81.6952510000001],[-69.12361099999998,81.68386800000013],[-69.00527999999991,81.66748000000007],[-68.902222,81.65138200000001],[-68.62471,81.60443099999998],[-68.44915800000001,81.57083100000006],[-68.37083399999989,81.55358900000004],[-68.35777299999995,81.54832500000009],[-68.35249299999998,81.54165600000005],[-68.37332200000003,81.53776600000003],[-68.40750099999997,81.53387499999997],[-68.50445599999995,81.53221100000013],[-68.55139199999996,81.532761],[-68.63751200000002,81.53553800000009],[-68.71528599999999,81.53970300000009],[-68.81082199999992,81.54859900000002],[-68.84889199999998,81.54914900000006],[-68.85694899999999,81.54776000000004],[-68.851944,81.54165600000005],[-68.83917200000002,81.536926],[-68.81304899999998,81.5333250000001],[-68.77749599999993,81.52970900000008],[-68.57945299999989,81.51443499999999],[-68.53666699999997,81.51332100000002],[-68.44665499999996,81.51748700000007],[-68.37609899999995,81.52276600000005],[-68.28582799999992,81.52693199999999],[-68.091949,81.5291600000001],[-68.05110199999996,81.53054800000001],[-68.01112399999994,81.533051],[-67.91000399999996,81.54220600000008],[-67.81973299999987,81.54693600000007],[-67.724716,81.55108600000011],[-67.38365199999998,81.56088299999999],[-67.18249500000002,81.56469700000008],[-67.15028399999994,81.56498700000009],[-67.10777300000001,81.56498700000009],[-67.06471299999998,81.56275900000009],[-66.85972600000002,81.54664600000007],[-66.79138199999989,81.54081700000006],[-66.76611299999996,81.53749100000005],[-66.62999000000002,81.51805100000001],[-66.608612,81.51277200000004],[-66.62388599999997,81.50637800000004],[-66.741104,81.49192800000009],[-66.887787,81.48054500000006],[-66.96278399999994,81.4749910000001],[-67.04333499999996,81.46971100000002],[-67.24833699999999,81.44999700000011],[-67.45750399999997,81.42303500000003],[-67.7538909999999,81.39166300000005],[-67.81834400000002,81.385269],[-67.99471999999997,81.368042],[-68.24472000000003,81.33998100000008],[-68.35583500000001,81.32388300000008],[-68.429169,81.31164600000011],[-68.48693800000001,81.30386399999998],[-68.61805700000002,81.29054300000001],[-68.79695100000004,81.2752690000001],[-69.02860999999996,81.25860600000004],[-69.319458,81.26026899999994],[-69.34056099999998,81.26388500000002],[-69.35777300000001,81.26832600000012],[-69.36277799999999,81.26887500000004],[-69.391388,81.27053799999999],[-69.42694099999994,81.26998900000001],[-69.45556599999998,81.26582300000013],[-69.468887,81.259995],[-69.46305799999999,81.25332600000013],[-69.43693499999995,81.24914599999994],[-69.36665299999999,81.24636800000013],[-69.319458,81.24359100000004],[-69.31221,81.24054000000007],[-69.32389799999993,81.23803700000008],[-69.54167199999995,81.21249399999994],[-69.91194199999995,81.18248000000011],[-69.99943499999995,81.17997700000012],[-70.15833999999995,81.18136600000014],[-70.20638999999994,81.17970300000002],[-70.21000700000002,81.17387400000001],[-70.12609899999995,81.16554300000013],[-70.05055199999998,81.16165200000006],[-69.96028100000001,81.16053800000009],[-69.90722700000003,81.16165200000006],[-69.864441,81.16415400000011],[-69.76000999999997,81.17303500000003],[-69.63806199999999,81.17747500000007],[-69.64750699999996,81.172485],[-69.831955,81.13720699999999],[-69.88778699999995,81.12915000000004],[-69.95306399999998,81.12220800000011],[-69.97694399999995,81.11886600000003],[-70.01306199999993,81.10914600000012],[-70.025284,81.10276799999997],[-70.02333099999998,81.10081500000001],[-69.99526999999995,81.09942600000005],[-69.95556599999998,81.09942600000005],[-69.92222599999997,81.10220300000015],[-69.83222999999998,81.11164900000011],[-69.63249200000001,81.13916000000012],[-69.60972600000002,81.14387499999998],[-69.59167500000001,81.14888000000002],[-69.54167199999995,81.16442899999993],[-69.52833599999991,81.16943400000002],[-69.46333300000003,81.18304400000005],[-69.43055699999996,81.18719499999997],[-69.35943600000002,81.19331399999999],[-68.87609900000001,81.2310940000001],[-68.76083399999993,81.23942600000004],[-68.37388599999997,81.266663],[-68.24694799999997,81.2727660000001],[-68.11665299999993,81.28027300000008],[-68.05277999999998,81.28610200000008],[-67.88722199999995,81.30304000000001],[-67.82362399999994,81.31025700000009],[-67.79110700000001,81.31553600000007],[-67.69082600000002,81.32943700000004],[-67.59306299999997,81.34027100000009],[-67.35665899999998,81.36360199999996],[-67.24749799999995,81.37191800000005],[-67.1241609999999,81.37970000000001],[-66.99055499999992,81.38554400000004],[-66.62138399999998,81.41387900000007],[-66.36582899999996,81.434708],[-66.29028299999999,81.44026200000002],[-66.16972399999986,81.44775400000015],[-66.13417099999992,81.45082100000008],[-66.05082700000003,81.45915200000013],[-65.98554999999999,81.46804800000007],[-65.83167999999995,81.484711],[-65.72471599999994,81.49386600000003],[-65.64361600000001,81.49887100000007],[-65.55749500000002,81.50305200000014],[-65.46640000000002,81.50637800000004],[-65.25279199999994,81.51721200000009],[-65.002792,81.53082300000005],[-64.612503,81.54498299999995],[-64.56639099999995,81.5455320000001],[-64.537781,81.54359399999998],[-64.52806099999992,81.54165600000005],[-64.51750199999998,81.53749100000005],[-64.44415299999997,81.49081400000011],[-64.43638599999991,81.47943100000009],[-64.45111099999997,81.4669340000001],[-64.49194299999999,81.44886800000012],[-64.50862099999995,81.44192499999997],[-64.52084400000001,81.4369200000001],[-64.554169,81.42581200000006],[-64.61665299999993,81.40498400000001],[-64.65888999999999,81.39305099999996],[-64.73527499999994,81.37414600000005],[-64.80860899999993,81.36053500000008],[-64.85583500000001,81.35276800000008],[-64.99499499999996,81.33332800000011],[-65.060272,81.326096],[-65.16805999999997,81.30998200000005],[-65.28639199999998,81.28720100000004],[-65.323624,81.27804600000002],[-65.44137599999993,81.25637800000004],[-65.49305700000002,81.25054900000003],[-65.52778599999999,81.24748199999993],[-65.57167099999998,81.24498000000006],[-65.747772,81.23580900000013],[-65.941101,81.22637900000007],[-65.98055999999991,81.22387700000013],[-66.01028400000001,81.22026100000011],[-66.1997219999999,81.18386800000002],[-66.24444599999987,81.17442299999999],[-66.26444999999995,81.16943400000002],[-66.41833500000001,81.12886000000003],[-66.43804899999998,81.12359600000002],[-66.48277299999995,81.10693400000008],[-66.50418099999996,81.09553499999998],[-66.50944500000003,81.08859300000006],[-66.52972399999999,81.07609600000006],[-66.54472399999997,81.07054099999999],[-66.60333300000002,81.05525200000011],[-66.68582199999997,81.03581200000013],[-66.75334199999998,81.021927],[-66.921112,80.99108900000004],[-67.16444399999995,80.94859300000002],[-67.208618,80.94192500000003],[-67.27917500000001,80.93553200000008],[-67.30915800000002,80.93441800000011],[-67.34944199999995,80.93637100000007],[-67.44082599999996,80.93664600000005],[-67.56221,80.93553200000008],[-67.59138499999995,80.93304400000011],[-67.60665899999992,80.92997700000001],[-67.60360700000001,80.92442299999999],[-67.58833300000003,80.91387899999995],[-67.56777999999997,80.90859999999998],[-67.54333500000001,80.90415999999999],[-67.53083799999996,80.89749100000012],[-67.53999299999998,80.89109800000011],[-67.583618,80.87664800000005],[-67.63444500000003,80.86080900000007],[-67.65360999999996,80.85636900000009],[-67.86389199999996,80.83415200000002],[-67.910278,80.8119200000001],[-67.96583599999991,80.797485],[-68.01139799999999,80.78831500000013],[-68.06555200000003,80.7791600000001],[-68.089447,80.776093],[-68.13833599999998,80.772491],[-68.20278899999994,80.76582300000007],[-68.22528099999994,80.76138300000002],[-68.6725009999999,80.66693099999992],[-68.73889199999991,80.64721700000001],[-68.81471299999998,80.62858600000004],[-68.95249899999988,80.60304300000007],[-69.14666699999992,80.52970900000008],[-69.171112,80.51748700000013],[-69.273056,80.46388200000001],[-69.28916899999996,80.45166000000006],[-69.291382,80.44413800000012],[-69.29055800000003,80.43719499999992],[-69.29777499999994,80.42469800000015],[-69.30555700000002,80.41832],[-69.31750499999998,80.41249099999999],[-69.33389299999993,80.40664700000013],[-69.38473499999992,80.39193700000004],[-69.42748999999998,80.38275100000004],[-69.47972099999998,80.37553400000013],[-69.55110200000001,80.36637900000011],[-69.59638999999987,80.36109900000002],[-69.72972099999993,80.35276799999997],[-69.9827729999999,80.344986],[-70.07278399999996,80.34443700000003],[-70.21888699999994,80.34637499999997],[-70.2844389999999,80.35108900000012],[-70.30526699999996,80.35609399999998],[-70.31082199999997,80.36303700000013],[-70.28582799999998,80.37248200000005],[-70.256393,80.38136299999996],[-70.24415599999992,80.38665800000001],[-70.22778299999999,80.40138200000007],[-70.22000100000002,80.41693099999998],[-70.2350009999999,80.42970300000002],[-70.27528399999994,80.44802900000002],[-70.31416300000001,80.46443200000004],[-70.49943499999995,80.51388499999996],[-70.53999299999992,80.52192700000012],[-70.68110699999994,80.54803500000008],[-70.70611600000001,80.55247500000013],[-70.75473,80.55941800000011],[-70.78306599999996,80.56303400000013],[-70.81249999999989,80.56275900000014],[-70.82528699999989,80.55859399999997],[-70.82749899999993,80.55137600000012],[-70.81304899999992,80.544983],[-70.796112,80.54054300000013],[-70.765289,80.53442400000012],[-70.74166899999994,80.53137200000003],[-70.670837,80.51805100000007],[-70.63778699999995,80.50915500000013],[-70.531387,80.47442600000005],[-70.49055499999992,80.46081500000008],[-70.47666900000002,80.45443699999998],[-70.42332499999998,80.42164600000001],[-70.43472299999996,80.39166300000011],[-70.45056199999999,80.38581799999997],[-70.45889299999999,80.38136299999996],[-70.47222899999991,80.368042],[-70.47138999999999,80.36248800000004],[-70.46916199999998,80.35498000000001],[-70.462219,80.34693900000013],[-70.44415300000003,80.34027100000014],[-70.42416400000002,80.33610500000003],[-70.35249299999992,80.32470700000005],[-70.30999800000001,80.31805400000007],[-70.25279199999994,80.31330900000006],[-70.15055799999999,80.29914900000011],[-70.035278,80.27832000000012],[-69.9911039999999,80.2688750000001],[-69.97416699999997,80.26304600000009],[-69.960556,80.2563780000001],[-69.96528599999994,80.2522130000001],[-69.99082899999996,80.24331699999999],[-70.12832600000002,80.19720500000011],[-70.145554,80.19358799999998],[-70.178604,80.1891480000001],[-70.21665999999999,80.18637100000001],[-70.24888599999997,80.18609600000002],[-70.31500199999988,80.18748499999998],[-70.61138899999997,80.19720500000011],[-70.645554,80.19914200000011],[-70.821121,80.19552600000009],[-71.12083399999995,80.17248500000005],[-71.18055699999991,80.16665600000005],[-71.23832699999991,80.15887499999997],[-71.38194299999998,80.13916],[-71.41861,80.13108800000003],[-71.44610599999993,80.12136800000013],[-71.46305799999993,80.11804200000006],[-71.50111400000003,80.11554000000001],[-71.65444899999994,80.11137400000007],[-71.69444299999998,80.11080900000007],[-71.73194899999993,80.11192300000005],[-71.762787,80.11442600000004],[-71.78999299999998,80.11775200000005],[-71.8116609999999,80.12359600000008],[-71.83612099999999,80.13192700000013],[-71.848053,80.14387500000004],[-71.87860099999995,80.16249100000005],[-71.90777600000001,80.17137100000008],[-71.95333900000003,80.180542],[-72.006393,80.18858300000011],[-72.05722000000003,80.19470200000012],[-72.08111600000001,80.19413800000001],[-72.09999099999987,80.19274899999999],[-72.12777699999992,80.18775900000014],[-72.16528299999999,80.18887300000011],[-72.18916300000001,80.19220000000001],[-72.22332799999998,80.20166000000012],[-72.241379,80.20748900000012],[-72.25639299999995,80.21388200000007],[-72.27444500000001,80.21971100000007],[-72.29444899999987,80.22331200000013],[-72.32972699999988,80.22554000000008],[-72.35888699999992,80.22608900000006],[-72.37805199999997,80.22470099999998],[-72.39111300000002,80.22164900000001],[-72.40028399999994,80.2185970000001],[-72.420837,80.21110499999998],[-72.41250600000001,80.20721400000008],[-72.18859899999995,80.16387900000012],[-72.14083900000003,80.15693700000003],[-72.08277900000002,80.15165699999994],[-72.05248999999998,80.149719],[-71.99694799999986,80.14305100000007],[-71.97721899999993,80.13943499999999],[-71.89695699999993,80.11554000000001],[-71.89555399999995,80.11415099999999],[-71.898056,80.10859700000003],[-71.90527299999997,80.10359199999994],[-71.92610200000001,80.0999910000001],[-71.95472699999993,80.09637500000002],[-72.11555499999997,80.0874940000001],[-72.25056499999994,80.08554100000015],[-72.39167799999996,80.08554100000015],[-72.39222699999999,80.08194000000009],[-72.358337,80.06498700000003],[-72.34056099999992,80.059143],[-72.30638099999999,80.05748000000006],[-72.17027299999995,80.05386400000003],[-72.137787,80.05358899999999],[-72.05305499999992,80.05748000000006],[-71.92083699999995,80.06637599999999],[-71.88583399999993,80.06721500000015],[-71.8497309999999,80.06776400000012],[-71.70195000000001,80.06414800000005],[-71.61805700000002,80.06442300000009],[-71.48916600000001,80.0688780000001],[-71.37609899999995,80.07693500000005],[-71.31666599999994,80.08194000000009],[-71.18638599999991,80.09387200000003],[-70.96806300000003,80.11499000000015],[-70.85472099999998,80.12831100000011],[-70.821121,80.13108800000003],[-70.76251200000002,80.13333099999994],[-70.65167199999996,80.13136300000002],[-70.62666300000001,80.13053900000006],[-70.50778200000002,80.09971600000006],[-70.50222799999995,80.09304800000007],[-70.49749800000001,80.08276400000005],[-70.48832699999997,80.05720500000007],[-70.49499500000002,80.05081200000012],[-70.50834699999996,80.04775999999998],[-70.56806899999992,80.04275500000011],[-70.59722899999997,80.0394290000001],[-70.64666699999998,80.03193699999997],[-70.662216,80.02665700000006],[-70.67304999999999,80.02082800000005],[-70.67971799999987,80.0144350000001],[-70.67277499999994,80.00637799999998],[-70.67250100000001,80.00138900000002],[-70.68971299999998,79.99331700000005],[-70.71945199999999,79.98637400000001],[-70.76722699999988,79.98165899999998],[-70.91610700000001,79.974426],[-70.95417800000001,79.97276300000004],[-71.08555599999994,79.96859699999999],[-71.241669,79.96081500000003],[-71.27027899999996,79.95721400000014],[-71.40110800000002,79.93553199999991],[-71.41639700000002,79.93026700000007],[-71.45361299999996,79.90637200000003],[-71.46055599999988,79.90138200000001],[-71.45889299999993,79.89498900000007],[-71.43859900000001,79.88998399999997],[-71.4158329999999,79.88665800000012],[-71.394455,79.884995],[-71.35278299999993,79.88693200000006],[-71.33860800000002,79.88859600000006],[-71.16833500000001,79.914154],[-71.10972599999997,79.91526799999997],[-71.06304899999998,79.91165200000012],[-70.94471699999997,79.89415000000008],[-70.92582700000003,79.89027400000003],[-70.910278,79.88581800000009],[-70.91639700000002,79.87942499999997],[-71.00584399999997,79.81971700000008],[-71.11665299999999,79.78970300000009],[-71.13612399999994,79.78498800000006],[-71.18388400000003,79.77748100000008],[-71.212784,79.774429],[-71.34361299999995,79.76388500000013],[-71.37609899999995,79.76081800000003],[-71.400284,79.75749200000001],[-71.44444299999992,79.74165300000004],[-71.46333300000003,79.73692300000005],[-71.49110399999995,79.73332199999999],[-71.69915800000001,79.70999100000012],[-71.73944099999994,79.70721400000002],[-71.781113,79.70610000000005],[-71.81750499999998,79.70359799999994],[-71.92250099999995,79.69552599999997],[-71.99027999999998,79.68914800000005],[-72.09666400000003,79.6749880000001],[-72.21777299999991,79.659988],[-72.26722699999993,79.65914900000001],[-72.28721599999994,79.659988],[-72.31777999999991,79.66720599999996],[-72.33084100000002,79.67248499999994],[-72.34805299999988,79.67804000000007],[-72.36721799999992,79.68165600000009],[-72.39222699999999,79.68359400000003],[-72.425003,79.68553199999997],[-72.46722399999993,79.684708],[-72.57417299999992,79.6791530000001],[-72.61944599999993,79.67776500000002],[-72.66139199999998,79.67719999999997],[-72.69722000000002,79.67804000000007],[-72.72999599999997,79.67970300000013],[-72.75611900000001,79.68220500000007],[-72.91278099999994,79.70220899999998],[-72.93276999999995,79.70637500000004],[-72.94444299999998,79.7102660000001],[-73.06277499999999,79.79942299999999],[-73.06111099999998,79.805252],[-73.04861499999998,79.8083190000001],[-73.02749599999999,79.80693100000002],[-73.01722699999993,79.80470300000002],[-73.00334199999998,79.80304000000012],[-72.97917199999995,79.80220000000008],[-72.945831,79.80415299999999],[-72.92443799999995,79.80636600000014],[-72.912216,79.80941800000005],[-72.90249599999993,79.81526200000008],[-72.92639200000002,79.81944299999998],[-73.05915800000002,79.82554600000009],[-73.09167500000001,79.82638500000007],[-73.1783289999999,79.822769],[-73.21806300000003,79.822769],[-73.28500399999996,79.82609600000012],[-73.34861799999999,79.83027600000014],[-73.37138399999998,79.83305400000012],[-73.39695699999999,79.834991],[-73.43360899999999,79.83581500000014],[-73.57640100000003,79.83276400000011],[-73.66777000000002,79.82971200000003],[-73.74527,79.82832300000001],[-73.78028899999998,79.82777400000009],[-73.8533329999999,79.82916300000005],[-73.86694299999999,79.830826],[-73.86471599999999,79.83581500000014],[-73.85360700000001,79.83970600000004],[-73.80166600000001,79.84637500000008],[-73.74554399999994,79.849152],[-73.74249299999985,79.84999099999993],[-73.74694799999997,79.85415599999993],[-73.7686159999999,79.85887099999997],[-73.89083900000003,79.87525900000003],[-73.94583099999988,79.88165300000009],[-74.01028400000001,79.88581800000009],[-74.11749299999997,79.88888500000002],[-74.15695199999993,79.88888500000002],[-74.23889199999996,79.8872070000001],[-74.28361499999994,79.88136300000008],[-74.30610699999994,79.87692300000003],[-74.383621,79.8685910000001],[-74.41528299999999,79.86526500000002],[-74.57640100000003,79.85693400000014],[-74.66749599999997,79.85359199999999],[-74.79527299999995,79.85081500000013],[-74.83306900000002,79.849152],[-74.84638999999999,79.84721400000006],[-74.84611499999994,79.84387200000009],[-74.71665999999999,79.79693600000007],[-74.69943199999994,79.792755],[-74.68388400000003,79.78997800000008],[-74.65499899999998,79.78887900000012],[-74.48889200000002,79.79165599999999],[-74.44499200000001,79.79470800000013],[-74.39222699999993,79.80026199999992],[-74.35166899999996,79.80247500000007],[-74.30943299999996,79.80331400000006],[-74.23638899999997,79.80192599999992],[-74.10638399999988,79.7955320000001],[-73.95140100000003,79.78442400000012],[-73.71472199999994,79.76638800000012],[-73.51083399999999,79.75637799999998],[-73.38473499999992,79.74887100000007],[-73.36665299999999,79.71804800000007],[-73.36082499999986,79.7127690000001],[-73.295547,79.688583],[-73.25695799999988,79.67804000000007],[-73.20666499999999,79.66360500000013],[-73.18888900000002,79.65803500000004],[-73.17443800000001,79.65165700000006],[-73.16833499999996,79.6461030000001],[-73.1260989999999,79.56944300000004],[-73.12582399999997,79.55831899999998],[-73.12887599999999,79.55415300000004],[-73.13583399999999,79.54971300000005],[-73.14862099999999,79.54359399999998],[-73.16305499999999,79.53887899999995],[-73.18083199999995,79.53414900000013],[-73.24722299999996,79.520828],[-73.29611199999994,79.5127720000001],[-73.35388199999994,79.50582900000012],[-73.44638099999992,79.49914599999994],[-73.65777600000001,79.49636800000013],[-73.69305400000002,79.49693300000001],[-73.729172,79.49859600000008],[-73.75805700000001,79.5002750000001],[-73.77999899999998,79.50305200000003],[-73.79194599999994,79.50665300000009],[-73.81722999999994,79.51554900000002],[-73.837784,79.52748099999997],[-73.86389200000002,79.54026799999997],[-73.87666299999995,79.54470800000001],[-73.91610699999995,79.55247500000013],[-73.95028699999989,79.55525200000005],[-73.965012,79.55470300000007],[-73.98889200000002,79.55192599999998],[-74.00111399999997,79.54582199999999],[-74.00029,79.54165600000005],[-73.99694799999997,79.53553799999992],[-73.98944099999994,79.52859500000011],[-73.96861299999989,79.5169370000001],[-73.95916699999992,79.50888100000003],[-73.94999699999994,79.49386600000008],[-73.94972199999995,79.47998000000007],[-73.95306399999998,79.47276299999999],[-73.96194500000001,79.46693399999998],[-73.98332199999993,79.45555100000013],[-73.99804699999999,79.45138500000007],[-74.02362099999999,79.44693000000007],[-74.08139,79.44053600000001],[-74.11610399999995,79.43803400000013],[-74.160278,79.43637100000001],[-74.19833399999999,79.43609599999996],[-74.54415899999992,79.43803400000013],[-74.61749299999985,79.43858300000005],[-74.67361499999993,79.44413800000012],[-74.6885989999999,79.44693000000007],[-74.93167099999994,79.49887100000012],[-74.93241099999989,79.50479899999999],[-74.94193999999999,79.51054399999998],[-74.96444699999995,79.51304600000003],[-74.987503,79.509995],[-75.04333499999996,79.49581900000004],[-75.06027199999988,79.49081399999994],[-75.05943300000001,79.48387100000014],[-74.99526999999995,79.453598],[-74.98306299999996,79.44970699999993],[-74.94888299999997,79.440811],[-74.91221599999994,79.42970300000002],[-74.89723199999997,79.42330899999996],[-74.88444499999997,79.41609200000005],[-74.8830569999999,79.4083250000001],[-74.91111799999999,79.39387499999998],[-74.93499799999995,79.38526900000005],[-74.95194999999995,79.38026400000001],[-75,79.37548800000008],[-75.016953,79.37414600000005],[-75.058334,79.37387100000007],[-75.21389799999997,79.37637300000011],[-75.31361400000003,79.379974],[-75.410278,79.38415500000008],[-75.531387,79.39248700000007],[-75.69526699999994,79.409988],[-75.79972800000002,79.43136600000014],[-75.90777600000001,79.42608600000005],[-75.93138099999999,79.42359899999997],[-75.95750399999997,79.42608600000005],[-75.985275,79.42970300000002],[-76.031387,79.43830900000012],[-76.04916400000002,79.443039],[-76.09750399999996,79.46192900000011],[-76.10916099999992,79.46775800000012],[-76.11527999999993,79.47248799999994],[-76.12416099999996,79.47637900000001],[-76.13861099999991,79.48136900000009],[-76.17582700000003,79.488876],[-76.203888,79.49247700000006],[-76.261124,79.49775699999998],[-76.3202819999999,79.50138900000007],[-76.636124,79.51944000000009],[-76.66528299999999,79.520828],[-76.71833800000002,79.51998900000001],[-76.79527300000001,79.51138300000008],[-76.83444199999997,79.50888100000003],[-76.872772,79.50860600000004],[-76.90583799999996,79.50972000000002],[-77.05027799999999,79.51860000000005],[-77.06973299999999,79.52388000000008],[-77.09277299999991,79.53970300000015],[-77.112213,79.54525800000005],[-77.14250199999987,79.54748500000005],[-77.16055299999994,79.54359399999998],[-77.19137599999993,79.51110800000009],[-77.18443300000001,79.50360099999995],[-77.178604,79.4997100000001],[-77.13444499999997,79.49026500000002],[-77.07167099999992,79.4869230000001],[-76.895554,79.48054500000012],[-76.86721799999992,79.47970599999996],[-76.612503,79.4747010000001],[-76.406387,79.47360200000014],[-76.20472699999999,79.46138000000013],[-76.17916899999989,79.45971700000007],[-76.15943899999996,79.4563750000001],[-76.14334100000002,79.44999699999994],[-76.13806199999993,79.44331399999999],[-76.13890100000003,79.44108600000004],[-76.14999399999999,79.43775900000009],[-76.15916400000003,79.43609599999996],[-76.18998699999997,79.4333190000001],[-76.208054,79.42970300000002],[-76.20556599999998,79.42469800000015],[-76.16749600000003,79.39610299999993],[-76.15750100000002,79.39166300000011],[-76.11721799999998,79.38443000000012],[-76.083328,79.37886000000003],[-76.05915799999997,79.37498500000004],[-75.902222,79.35720799999996],[-75.88194299999998,79.35331700000012],[-75.879166,79.35137899999995],[-75.88999899999988,79.34803799999992],[-75.90278599999988,79.34609999999998],[-76.08667000000003,79.33221400000002],[-76.12332200000003,79.33110000000005],[-76.35110499999996,79.3419340000001],[-76.68277,79.35276799999997],[-76.71777299999991,79.35331700000012],[-76.79055799999998,79.35331700000012],[-76.82917800000001,79.35081500000001],[-76.86971999999997,79.34942600000005],[-76.89416499999993,79.35331700000012],[-76.95944199999997,79.36720300000007],[-77.01889,79.38192700000013],[-77.07640100000003,79.3983310000001],[-77.09028599999994,79.40554800000001],[-77.10555999999991,79.41609200000005],[-77.108337,79.4208220000001],[-77.21250900000001,79.44775400000003],[-77.32640099999998,79.45416300000005],[-77.35916099999992,79.45555100000013],[-77.38612399999994,79.45277400000003],[-77.39750700000002,79.44720500000005],[-77.39500399999997,79.44026200000008],[-77.38444500000003,79.43304400000005],[-77.26222199999995,79.37248200000005],[-77.17250099999995,79.33638000000008],[-77.158615,79.329163],[-77.16389499999997,79.32470700000005],[-77.18777499999999,79.32276900000011],[-77.22805800000003,79.32165500000013],[-77.260559,79.32276900000011],[-77.31722999999994,79.32777399999998],[-77.36721799999998,79.33610500000009],[-77.38639799999999,79.33859300000006],[-77.41361999999998,79.34165999999999],[-77.46611000000001,79.34609999999998],[-77.47778299999993,79.34609999999998],[-77.59611499999994,79.34582499999999],[-77.63417099999992,79.34553499999998],[-77.70750399999997,79.34332300000005],[-77.73999000000003,79.34443700000008],[-77.76972999999998,79.34637500000002],[-77.81973299999999,79.351654],[-77.90527299999991,79.36526500000014],[-77.92250100000001,79.36637900000011],[-77.95722999999998,79.36387600000012],[-78.05139199999996,79.35470600000008],[-78.05888399999998,79.34942600000005],[-78.04361,79.34443700000008],[-78.02139299999993,79.33998099999997],[-77.90333599999997,79.322495],[-77.87609900000001,79.31971700000003],[-77.846115,79.31776400000007],[-77.80999800000001,79.316666],[-77.76000999999997,79.31637599999999],[-77.726944,79.31749000000013],[-77.65083300000003,79.31776400000007],[-77.62443499999995,79.31553600000012],[-77.52917500000001,79.30525200000011],[-77.47860700000001,79.29664600000001],[-77.32223499999998,79.26748700000002],[-77.32917800000001,79.26138300000014],[-77.34138499999995,79.25943000000001],[-77.35804699999994,79.25776700000011],[-77.42222600000002,79.25471499999998],[-77.45306399999998,79.25248700000003],[-77.48222399999997,79.24887100000001],[-77.49694799999992,79.24581900000004],[-77.48805199999998,79.24498000000011],[-77.424713,79.24609400000008],[-77.35833699999995,79.24999999999994],[-77.19193999999999,79.26388500000007],[-76.99972500000001,79.27331500000014],[-76.67138699999992,79.27748100000002],[-76.23777799999993,79.27110300000004],[-76.16805999999997,79.26998900000007],[-76.136124,79.2686000000001],[-76.10583499999996,79.26582300000001],[-76.06861900000001,79.25749200000007],[-76.05277999999998,79.25109900000012],[-76.03443900000002,79.24581900000004],[-75.99194299999999,79.23637400000001],[-75.93888900000002,79.23027000000013],[-75.80749500000002,79.22776800000008],[-75.77722199999994,79.22747800000008],[-75.73443600000002,79.22943100000003],[-75.67527799999999,79.23637400000001],[-75.63778699999995,79.2394260000001],[-75.60833699999995,79.23997500000007],[-75.465012,79.23997500000007],[-75.4058379999999,79.23748799999998],[-75.08306899999997,79.23526000000004],[-74.87609900000001,79.23803700000013],[-74.80027799999999,79.24054000000007],[-74.777222,79.24026500000008],[-74.52555799999999,79.22720300000003],[-74.49694799999997,79.22499099999999],[-74.47084000000001,79.22164900000007],[-74.464722,79.21998600000012],[-74.46722399999999,79.21554600000013],[-74.47416699999997,79.211929],[-74.52027900000002,79.20304899999996],[-74.57194499999991,79.19609100000014],[-74.601944,79.19274899999999],[-74.75805700000001,79.18553200000008],[-74.791946,79.18275499999999],[-74.81750499999993,79.17886400000009],[-74.82695000000001,79.17414900000006],[-74.81916799999993,79.16775500000006],[-74.795547,79.16360500000002],[-74.76695299999994,79.16137700000007],[-74.67250100000001,79.15693700000003],[-74.61749299999985,79.15138199999996],[-74.44583099999994,79.065811],[-74.43666100000002,79.0577550000001],[-74.44305399999996,79.04693600000007],[-74.45527600000003,79.04165599999999],[-74.47193900000002,79.036652],[-74.51445000000001,79.02859500000005],[-74.54388399999999,79.02526900000004],[-74.57833900000003,79.02331499999997],[-74.65417500000001,79.02221700000007],[-74.72500599999995,79.02276600000005],[-74.96000700000002,79.02832000000001],[-75.116104,79.03581200000013],[-75.24305700000002,79.043045],[-75.62666299999995,79.06608600000004],[-75.65556300000003,79.06832899999995],[-75.76333599999998,79.08055100000013],[-75.88528400000001,79.09748800000011],[-75.89138799999995,79.10220300000015],[-75.88722199999995,79.12831100000011],[-75.880829,79.134995],[-75.85665899999998,79.13970899999993],[-75.84861799999999,79.14498900000001],[-75.85777299999995,79.15220599999992],[-75.94444299999992,79.17303500000008],[-76.04777499999994,79.19220000000007],[-76.07167099999992,79.19609100000014],[-76.098053,79.199142],[-76.132767,79.19970699999999],[-76.30943300000001,79.19081100000005],[-76.51916499999999,79.19026200000013],[-76.85916099999997,79.18525700000009],[-76.97332799999992,79.18331899999993],[-77.04499800000002,79.18331899999993],[-77.08306900000002,79.18359399999997],[-77.11166399999996,79.18498200000005],[-77.16749600000003,79.18997200000013],[-77.20500199999998,79.1952510000001],[-77.250565,79.19802900000008],[-77.38890100000003,79.19970699999999],[-77.51083399999999,79.194977],[-77.54804999999993,79.19442700000013],[-77.64250199999992,79.19970699999999],[-77.695267,79.20471200000003],[-77.74999999999989,79.20832800000011],[-77.77749599999993,79.20887800000014],[-77.81750499999998,79.207764],[-78.15888999999999,79.18997200000013],[-78.21362299999998,79.18359399999997],[-78.23332199999999,79.17886400000009],[-78.24583399999995,79.17469800000003],[-78.25389100000001,79.169983],[-78.25306699999999,79.16442899999998],[-78.22860700000001,79.16053800000009],[-78.181671,79.15942400000012],[-78.08473200000003,79.16804500000006],[-78.056107,79.17192100000011],[-78.02639799999997,79.17469800000003],[-77.98889200000002,79.17747500000013],[-77.912216,79.17942800000003],[-77.84277299999997,79.1785890000001],[-77.47193900000002,79.16775500000006],[-77.23777799999999,79.15693700000003],[-77.20861799999994,79.15470900000008],[-77.181107,79.15386999999993],[-77.01861599999995,79.15359500000011],[-76.841949,79.15359500000011],[-76.70611599999995,79.15304599999996],[-76.63999899999999,79.15109300000006],[-76.61082499999992,79.14915500000012],[-76.48472599999997,79.13610800000009],[-76.43055700000002,79.132202],[-76.31973299999993,79.12469500000009],[-76.26000999999991,79.121918],[-76.23361199999994,79.12164299999995],[-76.19137599999993,79.12359600000008],[-76.15972899999997,79.122208],[-76.13667299999997,79.11914100000007],[-76.081955,79.09971600000011],[-76.0850069999999,79.09332300000011],[-76.09999099999987,79.08776899999998],[-76.11665299999993,79.08332800000005],[-76.14666699999998,79.07777400000003],[-76.17054699999989,79.07582100000008],[-76.21000699999996,79.0747070000001],[-76.26501499999995,79.07443200000012],[-76.36000100000001,79.07832300000001],[-76.515015,79.08581500000008],[-76.57556199999999,79.08943200000004],[-76.63722200000001,79.09054600000002],[-76.67639199999996,79.08943200000004],[-76.82833900000003,79.08276400000011],[-76.99638399999998,79.0747070000001],[-77.07333399999993,79.07083100000006],[-77.15278599999999,79.06608600000004],[-77.223053,79.06053200000002],[-77.32695000000001,79.0516510000001],[-77.35555999999997,79.04832500000003],[-77.42971799999992,79.03720099999998],[-77.44943199999994,79.03276099999994],[-77.464722,79.02777100000009],[-77.49499499999996,79.01776100000001],[-77.52917500000001,79.01805100000001],[-77.69305400000002,79.03360000000009],[-77.71972700000003,79.036652],[-77.74221799999992,79.04193099999998],[-77.78306600000002,79.06248499999998],[-77.79998799999993,79.06666600000005],[-77.84973100000002,79.06971700000008],[-77.91972399999992,79.0688780000001],[-78.03500400000001,79.06553600000001],[-78.10333300000002,79.06608600000004],[-78.13500999999997,79.06749000000002],[-78.16528299999993,79.06999200000007],[-78.214447,79.07527199999998],[-78.23416099999986,79.07832300000001],[-78.28999299999998,79.08332800000005],[-78.35110500000002,79.08638000000013],[-78.42527799999999,79.08305400000012],[-78.67138699999998,79.07193000000001],[-78.81834399999997,79.06944299999998],[-78.86000099999995,79.06721499999998],[-78.89138799999989,79.06330900000012],[-78.87943999999993,79.06025699999998],[-78.69248999999996,79.05859400000008],[-78.58833299999998,79.059143],[-78.40527299999997,79.06498700000003],[-78.28388999999999,79.06666600000005],[-78.23638899999997,79.06498700000003],[-78.15972899999997,79.05108600000005],[-78.108337,79.04664600000001],[-78.07055700000001,79.04664600000001],[-77.96611000000001,79.049149],[-77.86111499999987,79.049149],[-77.829453,79.04803500000003],[-77.7994379999999,79.0452580000001],[-77.785553,79.04109200000005],[-77.70834400000001,79.01304600000014],[-77.70333900000003,79.00694300000004],[-77.71665999999999,79.00332600000007],[-77.79611199999994,78.98858600000011],[-77.83500700000002,78.97943100000003],[-77.94694500000003,78.95166],[-77.94638099999992,78.94581599999998],[-77.95249899999993,78.93969700000014],[-78.04028299999999,78.90609700000005],[-78.14750699999996,78.86526500000008],[-78.28222700000003,78.80386400000009],[-78.28999299999998,78.79914900000006],[-78.29722600000002,78.78887900000012],[-78.29611199999994,78.783051],[-78.285553,78.77581800000002],[-78.26945499999994,78.77249100000006],[-78.24804699999993,78.770264],[-78.21556099999992,78.77053799999993],[-78.19610599999993,78.77221700000013],[-78.16833499999996,78.78082300000005],[-78.15972899999997,78.78498800000006],[-78.15943900000002,78.78997800000013],[-78.14584399999995,78.80081200000001],[-78.12943999999999,78.81219499999997],[-78.1052699999999,78.82859800000006],[-78.04276999999996,78.861649],[-78.0291749999999,78.86747700000012],[-77.902222,78.91276600000009],[-77.88722200000001,78.91775500000006],[-77.75167799999997,78.95748900000001],[-77.71194499999996,78.96609500000011],[-77.689438,78.96859699999999],[-77.52639799999997,78.97915600000005],[-77.37027,78.98442100000011],[-77.25834699999996,78.98637400000007],[-77.17749000000003,78.98970000000008],[-77.10749799999996,78.99552900000009],[-77.078888,78.99887100000007],[-77.02610799999997,79.00665299999997],[-76.96028100000001,79.01277200000004],[-76.75418099999996,79.02777100000009],[-76.710556,79.02832000000001],[-76.68331899999998,79.02777100000009],[-76.42416399999996,79.022491],[-76.36138900000003,79.01971400000014],[-75.98971599999993,78.99552900000009],[-75.73222399999997,78.96914700000002],[-75.72027600000001,78.96554599999996],[-75.769455,78.93997199999995],[-75.781113,78.934708],[-75.79695100000004,78.92970300000013],[-75.82556199999999,78.926086],[-75.85861199999994,78.92330900000007],[-75.896118,78.92082199999999],[-76.09527600000001,78.91026299999999],[-76.25,78.90220599999998],[-76.28721599999994,78.89971900000012],[-76.31555200000003,78.89610300000004],[-76.335556,78.89166300000005],[-76.37554899999992,78.88275099999998],[-76.415009,78.87387099999995],[-76.44610599999993,78.86387600000006],[-76.45638999999994,78.8577580000001],[-76.46000700000002,78.8519290000001],[-76.4583439999999,78.84498600000012],[-76.44027699999992,78.8394320000001],[-76.41194200000001,78.83720399999999],[-76.39445499999994,78.84082000000001],[-76.39111300000002,78.84387200000015],[-76.37470999999988,78.85108900000006],[-76.34472700000003,78.85887100000002],[-76.33000199999998,78.861649],[-76.231674,78.87914999999998],[-76.20472699999999,78.88108800000009],[-76.17832900000002,78.88026400000012],[-76.15834000000001,78.87914999999998],[-76.133331,78.87664800000005],[-76.07749899999999,78.87303200000002],[-75.97500600000001,78.87275699999998],[-75.79167199999995,78.88415500000002],[-75.46112099999999,78.89137299999999],[-75.316101,78.89221199999997],[-75.29222099999993,78.89027400000003],[-75.18055700000002,78.87914999999998],[-74.964722,78.8560940000001],[-74.77500900000001,78.82998700000007],[-74.760559,78.82360799999998],[-74.75279199999994,78.81694000000005],[-74.71972699999998,78.70748900000007],[-74.72721899999993,78.70138500000002],[-74.75584400000002,78.69802900000002],[-74.823059,78.69747899999999],[-74.84333799999996,78.69303900000011],[-74.86999499999996,78.67581200000012],[-74.86944599999993,78.6685940000001],[-74.85777300000001,78.63610799999998],[-74.81945799999988,78.62747200000007],[-74.78999299999998,78.5913700000001],[-74.862213,78.56721500000009],[-74.87805200000003,78.56248500000004],[-75.02416999999991,78.53193700000008],[-75.04804999999999,78.52804600000002],[-75.07250999999991,78.52777100000003],[-75.079453,78.53387500000002],[-75.10139499999997,78.53776600000009],[-75.13137799999993,78.539154],[-75.16722099999987,78.53970300000015],[-75.200287,78.5374910000001],[-75.21972699999998,78.53305100000006],[-75.235275,78.52804600000002],[-75.26167299999997,78.52331500000008],[-75.29055799999992,78.52053799999999],[-75.479446,78.50999500000006],[-75.83000199999998,78.50471500000015],[-75.88833599999992,78.506104],[-75.96501199999989,78.51081800000009],[-75.98999000000003,78.51388500000002],[-76.03056300000003,78.52110300000004],[-76.07305899999994,78.52970900000014],[-76.09555099999994,78.53360000000004],[-76.12027,78.53665200000012],[-76.15110799999997,78.538589],[-76.40444899999989,78.54803500000014],[-76.43721,78.54859900000008],[-76.46888699999994,78.54553199999998],[-76.64277599999997,78.52832000000012],[-76.68443300000001,78.52221700000001],[-76.691101,78.5188750000001],[-76.69276400000001,78.51470899999998],[-76.693604,78.50972000000002],[-76.6849979999999,78.50582900000012],[-76.66833500000001,78.50387599999999],[-76.64584400000001,78.50277700000004],[-76.53999299999998,78.50332599999996],[-76.46833800000002,78.50526400000012],[-76.36471599999993,78.51332100000008],[-76.32472200000001,78.51527400000003],[-76.289444,78.51554900000002],[-76.26194800000002,78.51361100000008],[-76.24305700000002,78.5122070000001],[-76.12499999999994,78.49414100000013],[-76.11416599999995,78.48831200000012],[-76.11277799999988,78.4810940000001],[-76.10888699999998,78.47499099999999],[-76.10055499999999,78.468323],[-76.08167999999995,78.4644320000001],[-76.05749500000002,78.46192900000011],[-75.761124,78.44386299999996],[-75.61721799999998,78.43803400000013],[-75.49888599999997,78.43304400000005],[-75.443604,78.430542],[-75.41082799999992,78.4266510000001],[-75.26972999999992,78.4041600000001],[-75.08999599999999,78.36886600000003],[-75.031387,78.33137500000004],[-75.03832999999992,78.32554600000003],[-75.05194099999989,78.315811],[-75.0625,78.309708],[-75.08667000000003,78.30636600000008],[-75.18998699999997,78.29971300000011],[-75.22193900000002,78.30026200000003],[-75.24610899999993,78.303314],[-75.27305599999988,78.30554200000012],[-75.30749500000002,78.30554200000012],[-75.35861199999994,78.30165100000005],[-75.37721299999998,78.29664600000001],[-75.38500999999991,78.29136700000004],[-75.39222699999993,78.28526299999999],[-75.39805599999994,78.272491],[-75.479172,78.22221400000012],[-75.49415599999998,78.21720900000008],[-75.51333599999992,78.21276900000004],[-75.58250399999991,78.201096],[-75.61361699999992,78.19802900000008],[-75.65028399999994,78.19693000000012],[-75.67944299999999,78.19831800000003],[-75.77639799999997,78.21054100000009],[-75.90249599999993,78.22415200000006],[-75.98554999999993,78.22997999999995],[-76.15722700000003,78.24054000000012],[-76.18888899999996,78.24108900000004],[-76.22582999999997,78.23997500000007],[-76.291946,78.23442100000005],[-76.32444799999996,78.23275799999999],[-76.36138900000003,78.23165899999998],[-76.39306599999998,78.23220800000013],[-76.47471599999994,78.23942599999992],[-76.5202789999999,78.24552900000009],[-76.54804999999988,78.24832200000009],[-76.57417299999992,78.24971],[-76.60833699999995,78.24941999999999],[-76.63055400000002,78.24775700000004],[-76.83168,78.23082000000005],[-76.85526999999996,78.22747800000008],[-76.88806199999999,78.21804800000001],[-76.89862099999993,78.21249400000005],[-76.912216,78.201096],[-76.90834000000001,78.19552599999992],[-76.88333099999994,78.19192500000008],[-76.68859900000001,78.16886900000003],[-76.664444,78.1660920000001],[-76.64167800000001,78.16442900000004],[-76.53778099999994,78.15832499999999],[-76.02139299999999,78.13804600000003],[-75.76390099999998,78.13165300000009],[-75.73554999999999,78.1308140000001],[-75.62193300000001,78.1244200000001],[-75.59722899999997,78.12081900000004],[-75.58138999999994,78.115814],[-75.57556199999993,78.1077580000001],[-75.575287,78.10137900000007],[-75.58889799999997,78.0894320000001],[-75.59916699999991,78.08332800000005],[-75.69276399999995,78.03997800000008],[-75.70750399999991,78.03498800000006],[-75.723053,78.03082300000005],[-75.761124,78.02249100000006],[-75.80943300000001,78.00833100000011],[-75.83860800000002,77.99832200000009],[-75.922775,77.95665000000008],[-75.96501199999989,77.97303799999992],[-75.98416099999986,77.97747800000013],[-76.15722700000003,78.01249700000005],[-76.214722,78.01527399999992],[-76.24610899999993,78.01582300000007],[-76.27667200000002,78.01277200000004],[-76.30305499999997,78.00943000000012],[-76.44471699999991,77.98858600000011],[-76.466949,77.98471099999995],[-76.48138399999993,77.97970600000008],[-76.49194299999999,77.96859700000005],[-76.49972500000001,77.958328],[-76.52610800000002,77.94914200000005],[-76.54834,77.94497700000005],[-76.59583999999995,77.93969700000014],[-76.66999800000002,77.93637100000012],[-76.69444299999986,77.93719500000009],[-76.73055999999991,77.93609600000008],[-76.75723299999999,77.93331900000004],[-76.78028899999993,77.92997700000006],[-76.80249000000003,77.9202580000001],[-76.80555700000002,77.91720599999996],[-76.80694599999993,77.91304000000008],[-76.825287,77.90832500000005],[-76.86221299999994,77.90277100000003],[-76.93110699999994,77.90138200000007],[-76.95973199999997,77.90248100000002],[-76.98611499999993,77.90470899999997],[-77.03639199999992,77.90971400000001],[-77.07778899999994,77.915817],[-77.08917199999996,77.91970800000007],[-77.09527600000001,77.92719999999997],[-77.104172,77.934418],[-77.12026999999989,77.93914800000005],[-77.1600039999999,77.94609100000002],[-77.21083099999998,77.94914200000005],[-77.24444599999998,77.94859300000007],[-77.27223200000003,77.94636500000013],[-77.29834,77.9427490000001],[-77.33612099999999,77.94081099999994],[-77.83889799999997,77.9427490000001],[-77.99749800000001,77.95721400000002],[-78.03694200000001,77.96638499999995],[-78.14083899999991,77.9852600000001],[-78.162216,77.98831200000001],[-78.23750299999995,77.99581899999998],[-78.26083399999993,77.99525499999999],[-78.41139199999992,77.91775500000011],[-78.420837,77.9124910000001],[-78.42639199999996,77.90637200000009],[-78.41972399999997,77.89888000000013],[-78.41055299999994,77.89221199999997],[-78.33084099999991,77.8685910000001],[-78.31710799999996,77.865814],[-78.28250099999997,77.86276200000009],[-78.2602839999999,77.86137400000001],[-78.17388900000003,77.859985],[-78.13945000000001,77.85720800000013],[-77.97193900000002,77.80720499999995],[-77.95861799999989,77.80220000000008],[-77.947769,77.79637100000008],[-77.94082600000002,77.76554900000002],[-77.94055199999997,77.759995],[-77.98110999999989,77.70138500000007],[-77.92027299999995,77.66998300000012],[-77.882767,77.661652],[-77.86277799999999,77.65637200000015],[-77.74276699999996,77.62220800000011],[-77.724716,77.61331200000001],[-77.71861299999995,77.60582000000005],[-77.72305299999994,77.59915200000006],[-77.73083500000001,77.59721400000012],[-77.87222300000002,77.56832900000012],[-77.952225,77.5558170000001],[-77.95834399999995,77.52970900000014],[-77.94444299999998,77.51138300000014],[-77.94610599999999,77.50471499999998],[-77.94860799999998,77.50193800000011],[-77.981674,77.48637400000001],[-77.99499499999996,77.4810940000001],[-78.25666799999993,77.38192699999996],[-78.303879,77.37330600000007],[-78.69055200000003,77.31553599999995],[-78.741104,77.30941800000005],[-78.777222,77.30720500000007],[-78.80665599999998,77.30720500000007],[-78.83416699999992,77.30831900000004],[-78.839722,77.31025699999998],[-78.83306900000002,77.31498700000003],[-78.78611799999999,77.33581500000008],[-78.73388699999998,77.36276200000003],[-78.726944,77.36747700000006],[-78.725281,77.37109400000003],[-78.72778299999999,77.37525900000003],[-78.76444999999995,77.3808140000001],[-78.7844389999999,77.3808140000001],[-78.816666,77.37803600000012],[-78.84111000000001,77.37442000000004],[-78.86166399999996,77.37025500000004],[-78.89805599999994,77.36080900000007],[-78.92027300000001,77.35081500000007],[-78.93998699999992,77.33888200000001],[-78.94804399999998,77.33248900000007],[-78.95556599999992,77.32832299999995],[-78.96833800000002,77.32331799999992],[-79.00418099999996,77.31387300000006],[-79.083328,77.29998799999998],[-79.139725,77.2935940000001],[-79.17138699999987,77.290817],[-79.20722999999998,77.28831500000013],[-79.270554,77.28692600000011],[-79.32167099999992,77.28858900000006],[-79.37332199999997,77.29304499999995],[-79.49333200000001,77.30442800000014],[-79.63137799999998,77.31666600000005],[-79.653885,77.318604],[-79.71221899999995,77.31832899999995],[-79.83666999999997,77.30693100000013],[-79.86082499999998,77.303314],[-79.88194299999998,77.29971300000011],[-79.896118,77.29582200000004],[-79.92332499999992,77.28526300000004],[-79.96055599999988,77.2769320000001],[-79.98832700000003,77.27360499999998],[-80.01916499999993,77.27221700000007],[-80.04249599999997,77.27276600000005],[-80.45611600000001,77.29609700000009],[-80.75334199999992,77.33055100000013],[-80.77583300000003,77.334427],[-80.87971499999992,77.35304300000001],[-81.00556899999992,77.37719700000014],[-81.015289,77.38136300000002],[-81.019455,77.39276100000006],[-81.027222,77.39804100000009],[-81.03527799999995,77.40109300000006],[-81.09527600000001,77.411926],[-81.12110899999993,77.41360500000002],[-81.15083300000003,77.41360500000002],[-81.2077789999999,77.41581700000006],[-81.25473,77.4205320000001],[-81.27749599999993,77.42442299999999],[-81.29444899999993,77.42915300000004],[-81.31054699999999,77.43498200000005],[-81.316666,77.43887300000011],[-81.321121,77.45027200000004],[-81.325287,77.45498700000007],[-81.33750900000001,77.46276900000004],[-81.35166900000002,77.46971100000007],[-81.37054399999994,77.47554000000014],[-81.38890100000003,77.48082],[-81.44221500000003,77.49136400000003],[-81.53388999999993,77.50694299999998],[-81.57362399999994,77.51277199999998],[-81.58778399999994,77.51748700000002],[-81.589722,77.52082800000005],[-81.608337,77.55358899999999],[-81.61054999999999,77.57609600000006],[-81.82028199999996,77.62191800000011],[-81.83972199999994,77.625809],[-81.84500100000002,77.62886000000003],[-81.84861799999999,77.63943499999993],[-81.847778,77.643326],[-81.83667000000003,77.65498400000007],[-81.8475039999999,77.665817],[-81.86000099999995,77.67137100000002],[-81.87666299999995,77.67747500000007],[-81.89527899999996,77.68248000000011],[-81.91389499999991,77.68553200000002],[-81.92832900000002,77.68580600000013],[-81.93028300000003,77.68498199999999],[-81.93554699999993,77.67804000000007],[-81.94915800000001,77.655258],[-81.94943199999994,77.64498900000012],[-81.91139199999992,77.60942100000011],[-81.89584400000001,77.60415600000005],[-81.85722399999997,77.59887700000007],[-81.81027199999994,77.595261],[-81.79804999999999,77.59165999999999],[-81.78750600000001,77.58749400000005],[-81.67805499999997,77.53831500000007],[-81.67054699999994,77.5316620000001],[-81.66722099999998,77.52526899999998],[-81.666946,77.5022130000001],[-81.67083699999995,77.49609400000008],[-81.69027699999992,77.48526000000004],[-81.710556,77.47499099999999],[-81.71945199999999,77.46998600000012],[-81.74804699999993,77.44802900000008],[-81.743607,77.4410860000001],[-81.739441,77.43637100000007],[-81.728882,77.42997700000001],[-81.70056199999988,77.4227600000001],[-81.52362099999999,77.37803600000012],[-81.48472600000002,77.372208],[-81.43222000000003,77.36804200000006],[-81.33667000000003,77.36859100000004],[-81.25140399999998,77.36914100000007],[-81.203888,77.37052900000015],[-81.18998699999992,77.36804200000006],[-81.17805499999997,77.36025999999993],[-81.172775,77.35470599999996],[-81.16776999999996,77.34275800000012],[-81.16583300000002,77.3372040000001],[-81.16583300000002,77.33276400000005],[-81.16944899999999,77.32249500000006],[-81.28388999999999,77.31526200000002],[-81.425003,77.30636600000008],[-81.53832999999997,77.30276500000008],[-81.87499999999994,77.29248000000013],[-81.95388799999995,77.30220000000003],[-82.09194899999994,77.31637600000005],[-82.15139799999997,77.30386400000003],[-82.16610700000001,77.29248000000013],[-82.08168,77.27276600000005],[-82.04333500000001,77.26554899999991],[-81.978882,77.25833100000011],[-81.90695199999999,77.19831800000003],[-81.90657799999997,77.1933140000001],[-81.902222,77.18719500000003],[-81.87609900000001,77.17469800000009],[-81.86805700000002,77.17164600000012],[-81.83416699999987,77.1624910000001],[-81.79666099999997,77.15748600000006],[-81.78694200000001,77.15748600000006],[-81.71583599999997,77.17692600000004],[-81.69665499999991,77.18136600000003],[-81.63444499999997,77.19386300000002],[-81.60749799999996,77.1974790000001],[-81.39500399999997,77.23165900000004],[-81.14917000000003,77.27470399999999],[-80.96028100000001,77.27137800000014],[-80.59277299999997,77.24247700000001],[-80.52639799999992,77.23498500000005],[-80.28028899999987,77.21360800000002],[-80.258621,77.21220400000004],[-80.20584099999996,77.20942700000012],[-80.15499899999998,77.20803799999993],[-80.13583399999999,77.20582600000006],[-80.116104,77.20138500000013],[-80.11471599999999,77.19552599999997],[-80.13694799999996,77.18609600000008],[-80.15278599999999,77.18165600000003],[-80.25500499999998,77.15332000000012],[-80.40167199999996,77.08665500000001],[-80.40972899999997,77.0811000000001],[-80.40972899999997,77.07666000000012],[-80.39445499999994,77.07276900000005],[-80.37304699999993,77.07138099999992],[-80.34584000000001,77.074997],[-80.32806399999993,77.07832300000001],[-80.20695499999994,77.10859700000009],[-80.15943899999996,77.12275699999998],[-80.13500999999997,77.13943500000005],[-80.118607,77.15081800000007],[-80.09472699999998,77.16110200000008],[-80.07250999999991,77.17053199999998],[-80.01333599999992,77.19053600000007],[-79.93582200000003,77.20665000000002],[-79.785278,77.23136899999997],[-79.72582999999992,77.23997500000007],[-79.66027799999995,77.24443100000002],[-79.63305700000001,77.24331700000005],[-79.44554099999999,77.23442100000011],[-79.4241639999999,77.23304700000011],[-79.25500499999998,77.21859699999999],[-79.216949,77.20971700000013],[-79.04194599999988,77.16110200000008],[-79.03306600000002,77.15664700000008],[-79.02806099999998,77.15054300000003],[-79.00389099999995,77.10359200000005],[-79.00500499999993,77.09693900000002],[-79.01333599999992,77.09137000000004],[-79.02972399999999,77.08692900000011],[-79.13249200000001,77.05358900000004],[-79.328888,76.97859199999994],[-79.36555499999992,76.96331800000007],[-79.37666300000001,76.95748900000007],[-79.39138799999995,76.947205],[-79.39500399999991,76.94053600000012],[-79.39306599999998,76.934143],[-79.38694800000002,76.92747500000002],[-79.37222300000002,76.92330900000013],[-79.34584000000001,76.91804500000012],[-79.31750499999993,76.91775500000011],[-79.24444599999993,76.92498799999993],[-79.1930539999999,76.92915299999993],[-79.00584399999991,76.93609600000013],[-78.98083500000001,76.93637100000012],[-78.95417800000001,76.93525699999998],[-78.886124,76.9269260000001],[-78.870834,76.92221100000006],[-78.86639400000001,76.91886900000009],[-78.91000400000001,76.88665800000001],[-78.91528299999999,76.83970600000009],[-78.74833699999994,76.82249499999995],[-78.72193899999996,76.82138099999997],[-78.71221899999995,76.82331800000003],[-78.70805399999995,76.82499700000005],[-78.56361400000003,76.90664700000013],[-78.566101,76.91360500000013],[-78.56750499999998,76.92720000000003],[-78.56277499999987,76.933044],[-78.55387899999994,76.938583],[-78.547775,76.94136000000009],[-78.38444499999991,76.99971000000005],[-78.34416199999993,77.007767],[-78.32028200000002,77.01165800000007],[-78.29277000000002,77.0147090000001],[-78.19694499999997,77.01944000000003],[-78.14083899999991,77.01998900000001],[-78.087219,77.01776100000001],[-78.07028200000002,77.01443499999999],[-77.89666699999998,76.95555100000013],[-77.88694799999996,76.94775400000015],[-77.881104,76.94026200000002],[-77.77944899999994,76.79136699999998],[-77.78944399999995,76.78166200000004],[-77.81332399999997,76.69274899999999],[-77.81361399999997,76.68775900000009],[-77.81304899999986,76.68193100000002],[-77.80499299999997,76.67526199999992],[-77.76945499999994,76.6583250000001],[-77.78443900000002,76.65026900000004],[-77.81027199999994,76.64082300000007],[-77.84111000000001,76.63333100000011],[-77.8616639999999,76.62970000000007],[-77.91833500000001,76.62831100000011],[-77.94721999999996,76.62942500000008],[-77.98500099999995,76.632477],[-78.01362599999999,76.63081400000004],[-78.02749599999999,76.62692299999998],[-78.089722,76.60942099999994],[-78.09777799999995,76.60609400000004],[-78.17832899999996,76.56608599999998],[-78.18611099999993,76.559708],[-78.20610799999997,76.53914600000013],[-78.25666799999993,76.50665300000014],[-78.364441,76.46249399999999],[-78.37748699999992,76.4580380000001],[-78.43510399999997,76.45317100000011],[-78.44332899999989,76.4522090000001],[-78.473053,76.45166000000012],[-78.51916499999999,76.45694000000003],[-78.55249000000003,76.46415700000011],[-78.60777299999995,76.48664900000006],[-78.61471599999993,76.48997500000007],[-78.61944599999998,76.49609400000008],[-78.61694299999999,76.49887100000001],[-78.61500499999988,76.5],[-78.61138899999992,76.49941999999993],[-78.59722899999991,76.50526400000012],[-78.591949,76.5086060000001],[-78.58833299999998,76.51304600000009],[-78.61332700000003,76.54775999999998],[-78.62721299999993,76.563873],[-78.75111400000003,76.57222000000002],[-78.77333099999998,76.57276899999994],[-78.79055800000003,76.57165500000013],[-78.86833199999995,76.5211030000001],[-78.88694799999996,76.49720800000006],[-78.90083300000003,76.4788670000001],[-78.93777499999999,76.44999700000005],[-78.94665500000002,76.444977],[-78.96945199999999,76.43414300000012],[-78.99415599999998,76.42442300000005],[-79.01306199999999,76.42025800000005],[-79.06138599999997,76.41276600000009],[-79.09028599999999,76.41137700000007],[-79.13917499999997,76.41165200000012],[-79.170837,76.40998800000011],[-79.18971299999987,76.40582300000011],[-79.19804399999987,76.4002690000001],[-79.261124,76.35220299999997],[-79.26556399999993,76.34610000000004],[-79.26640299999997,76.3394320000001],[-79.26278699999995,76.33194000000015],[-79.25418100000002,76.32026700000011],[-79.25306699999993,76.31469700000002],[-79.261124,76.30914300000006],[-79.27278099999995,76.30415299999999],[-79.31277499999999,76.297485],[-79.33860800000002,76.29637100000002],[-79.36582899999996,76.29664600000007],[-79.4141689999999,76.30108600000005],[-79.44554099999999,76.30664100000013],[-79.50083899999993,76.3141480000001],[-79.52528399999989,76.31442300000009],[-79.573624,76.311646],[-79.59666400000003,76.30859400000008],[-79.80555699999996,76.27832000000006],[-79.92443800000001,76.25360100000006],[-80.06138599999991,76.22692899999998],[-80.08721899999995,76.22360200000008],[-80.10722399999997,76.2227630000001],[-80.12165800000002,76.22442600000005],[-80.136124,76.22831700000012],[-80.15638699999988,76.23692299999999],[-80.17832900000002,76.23970000000008],[-80.20361300000002,76.24053999999995],[-80.23028599999998,76.23997500000013],[-80.261124,76.23831200000001],[-80.2933349999999,76.2352600000001],[-80.33833299999998,76.22831700000012],[-80.36694299999999,76.21804800000007],[-80.37554899999992,76.21304300000003],[-80.38305699999995,76.20748900000001],[-80.39666699999992,76.20220899999998],[-80.412216,76.19802900000013],[-80.42694099999989,76.19552599999997],[-80.50695799999994,76.19636500000013],[-80.60638399999999,76.1916500000001],[-80.62748699999992,76.18719500000009],[-80.637787,76.17053199999998],[-80.63972499999988,76.16748000000007],[-80.65417500000001,76.1624910000001],[-80.67250100000001,76.15832500000005],[-80.70333899999997,76.15664700000008],[-80.949997,76.14498900000007],[-81.05332900000002,76.12803600000001],[-81.07583599999992,76.12914999999998],[-81.08583099999993,76.13415500000002],[-81.09028599999994,76.13749699999994],[-81.095551,76.21220400000004],[-81.04750100000001,76.24941999999999],[-81.04110699999995,76.25360100000006],[-81.02639799999992,76.25833100000011],[-80.903885,76.31219499999997],[-80.783615,76.3749850000001],[-80.769455,76.38472000000002],[-80.761124,76.39415000000008],[-80.76000999999991,76.40415999999999],[-80.76362599999987,76.41110200000008],[-80.77166699999992,76.41914400000002],[-80.78472899999997,76.42387400000007],[-80.99166899999994,76.48304700000006],[-81.18888900000002,76.5188750000001],[-81.27500899999995,76.53332500000005],[-81.304169,76.51054400000004],[-81.33721899999989,76.49498000000011],[-81.351944,76.49026500000008],[-81.38890100000003,76.48136899999997],[-81.41111799999999,76.47747800000008],[-81.46083099999993,76.47137499999997],[-81.49249299999991,76.46943700000003],[-81.52194199999997,76.46859699999999],[-81.63694800000002,76.46887200000015],[-81.71665999999999,76.470261],[-81.78860500000002,76.47470099999998],[-81.87999000000002,76.48387100000002],[-82.03971899999993,76.50943000000007],[-82.05860899999999,76.51361099999997],[-82.07583599999998,76.5186000000001],[-82.08361799999994,76.52387999999996],[-82.03195199999999,76.55358899999999],[-81.98500099999995,76.57859799999994],[-81.98194899999993,76.58471700000001],[-81.99333199999995,76.59027099999997],[-82.04527300000001,76.6035920000001],[-82.05665599999986,76.60914600000012],[-82.04943800000001,76.61248800000004],[-81.95333899999991,76.63192700000013],[-81.87361099999987,76.64582800000011],[-81.85139499999997,76.649719],[-81.81416300000001,76.65859999999992],[-81.79028299999993,76.667755],[-81.78222700000003,76.67276000000004],[-81.776947,76.67747500000007],[-81.778885,76.68109099999992],[-81.78582799999992,76.68553200000002],[-81.79916399999996,76.68580599999996],[-81.819458,76.68275499999999],[-81.83805799999993,76.67831400000006],[-81.85278299999999,76.67359900000002],[-81.86193800000001,76.66914400000002],[-81.89334100000002,76.66081200000002],[-82.08111599999995,76.63108799999998],[-82.11555499999992,76.62886000000003],[-82.14555399999995,76.62803600000007],[-82.199997,76.6285860000001],[-82.27333099999993,76.63333100000011],[-82.29249599999997,76.6355440000001],[-82.32695000000001,76.6413730000001],[-82.346115,76.6455380000001],[-82.37748699999992,76.65748599999995],[-82.44249000000002,76.68498199999999],[-82.47027600000001,76.698868],[-82.47666899999996,76.70471200000003],[-82.487213,76.71775800000012],[-82.58029199999999,76.77638200000001],[-82.596115,76.782486],[-82.69860799999998,76.81248500000004],[-82.72500599999995,76.81915300000003],[-82.74972500000001,76.81860400000011],[-82.76722699999999,76.813309],[-82.76972999999992,76.81109600000008],[-82.76556399999987,76.80831899999998],[-82.74610899999999,76.80415300000004],[-82.72833300000002,76.79914900000011],[-82.69860799999998,76.788589],[-82.64056399999998,76.766388],[-82.556107,76.72303800000003],[-82.55833399999995,76.718323],[-82.56666599999994,76.70748900000012],[-82.56945799999994,76.70138500000007],[-82.56249999999994,76.68887300000006],[-82.54554699999994,76.67414900000006],[-82.53332499999999,76.66638200000006],[-82.460556,76.63610800000004],[-82.435272,76.62803600000007],[-82.41500899999988,76.62303199999991],[-82.30888400000003,76.60942099999994],[-82.208054,76.59304800000007],[-82.11389199999991,76.57222000000002],[-82.10221899999999,76.56887800000004],[-82.08111599999995,76.56109600000013],[-82.093887,76.55720500000007],[-82.17500299999995,76.54693600000002],[-82.19694499999997,76.54275500000011],[-82.21139499999992,76.53804000000008],[-82.22222899999997,76.53276100000011],[-82.225281,76.52665700000006],[-82.22471599999989,76.52026400000011],[-82.22250400000001,76.5144350000001],[-82.21639999999996,76.5086060000001],[-82.18943799999988,76.48664900000006],[-82.15805099999994,76.46609500000005],[-82.14723200000003,76.46110500000003],[-82.13555899999994,76.45332300000007],[-82.13137799999993,76.44859300000002],[-82.12721299999993,76.44165000000004],[-82.13221699999991,76.43691999999999],[-82.16250599999995,76.42192100000011],[-82.17971799999998,76.41693100000009],[-82.20944199999997,76.40998800000011],[-82.26028400000001,76.39860500000009],[-82.29333500000001,76.395828],[-82.34834299999994,76.39553799999999],[-82.48306300000002,76.39637800000003],[-82.704453,76.38693200000006],[-82.83332799999988,76.3977660000001],[-82.99055499999992,76.42665099999999],[-83.00361599999997,76.42915300000004],[-83.0625,76.45027200000004],[-83.09973099999996,76.46388200000013],[-83.10249299999998,76.46943700000003],[-83.09695399999998,76.47581499999995],[-83.08944699999995,76.48082],[-83.06500199999999,76.49108900000004],[-83.061935,76.49720800000006],[-83.07501200000002,76.53276100000011],[-83.08444199999997,76.54637099999997],[-83.11000100000001,76.57998700000013],[-83.11665299999999,76.58610500000009],[-83.19860799999998,76.61943100000008],[-83.33889799999986,76.66415400000011],[-83.38417099999998,76.73082],[-83.36527999999993,76.74054000000007],[-83.35861199999994,76.74609400000003],[-83.35583499999996,76.7522130000001],[-83.362213,76.75610399999994],[-83.37998999999996,76.75888100000003],[-83.40083300000003,76.759995],[-83.4100039999999,76.75776700000006],[-83.49749800000001,76.72387699999996],[-83.51834099999996,76.71331800000013],[-83.52362099999993,76.70664999999997],[-83.52333099999993,76.70082100000013],[-83.52055399999995,76.69525100000004],[-83.51501499999995,76.68997200000007],[-83.49916100000002,76.6766510000001],[-83.35221899999999,76.61248800000004],[-83.33111600000001,76.60331700000012],[-83.316101,76.59803799999997],[-83.29861499999998,76.59304800000007],[-83.27806099999992,76.58831800000007],[-83.25418100000002,76.5794370000001],[-83.24638399999998,76.57276899999994],[-83.20750399999991,76.50555399999996],[-83.1844329999999,76.42498800000004],[-83.18832399999997,76.41943400000008],[-83.20222499999994,76.41442899999998],[-83.22361799999987,76.41053799999992],[-83.25666799999999,76.407486],[-83.28582799999998,76.40637200000003],[-83.43998699999992,76.41110200000008],[-83.61999500000002,76.42359900000008],[-83.69110099999995,76.42886399999992],[-83.710556,76.43304400000011],[-83.73500099999995,76.44413800000001],[-83.73416099999992,76.449142],[-83.735275,76.45582600000006],[-83.74055499999997,76.46276900000004],[-83.75666799999999,76.46859699999999],[-83.89361600000001,76.50166300000006],[-83.98500100000001,76.52053800000004],[-84.01861600000001,76.52943399999998],[-84.03361499999994,76.53471400000006],[-84.04666099999997,76.54220599999996],[-84.058334,76.55304000000007],[-84.05888400000003,76.55886800000013],[-84.06166100000002,76.5852660000001],[-84.0708469999999,76.61665300000004],[-84.08667000000003,76.62414600000011],[-84.101944,76.62942500000008],[-84.11888099999999,76.63388099999997],[-84.13861099999991,76.63777200000004],[-84.261124,76.65554800000001],[-84.28443899999996,76.657761],[-84.31082200000003,76.6583250000001],[-84.31973299999987,76.65609699999999],[-84.32472200000001,76.65332000000006],[-84.33084100000002,76.64749100000006],[-84.31332399999991,76.64109800000011],[-84.25666799999999,76.6285860000001],[-84.220551,76.62220799999994],[-84.20249899999993,76.61720300000007],[-84.19305399999996,76.60998500000011],[-84.19444299999998,76.60693400000008],[-84.21694899999989,76.57165500000013],[-84.24972500000001,76.53692600000011],[-84.24833699999999,76.53054800000012],[-84.24499499999996,76.52499399999994],[-84.22111499999994,76.51081799999997],[-84.20861799999989,76.50526400000012],[-84.19249000000002,76.49941999999993],[-84.17971799999992,76.49192800000003],[-84.18083200000001,76.484985],[-84.19554099999993,76.45637499999998],[-84.20556599999998,76.451096],[-84.21583599999997,76.44802900000008],[-84.23693800000001,76.44358799999998],[-84.48916600000001,76.42915300000004],[-84.51861599999995,76.42776500000014],[-84.57084699999996,76.42886399999992],[-84.61972000000003,76.43165600000003],[-84.63694799999996,76.43441800000011],[-84.65278599999999,76.43803400000002],[-84.78388999999999,76.46998600000012],[-84.79277000000002,76.47499099999999],[-84.785278,76.48526000000004],[-84.78388999999999,76.48997500000007],[-84.79527300000001,76.50387600000005],[-84.84889199999992,76.53637700000013],[-84.86000100000001,76.54275500000011],[-84.95056199999993,76.57777399999998],[-84.97055099999994,76.58194000000009],[-84.99137899999994,76.58276400000005],[-85.01640299999991,76.57887299999999],[-85.02833599999997,76.57499700000011],[-85.03416399999998,76.56915300000009],[-85.05139199999996,76.51416000000006],[-85.02250700000002,76.45609999999999],[-84.97027600000001,76.42608600000011],[-84.96028100000001,76.42053199999998],[-84.94444299999998,76.41693100000009],[-84.90417500000001,76.41192600000005],[-84.72805800000003,76.39027399999998],[-84.43638599999997,76.33859300000012],[-84.39750699999996,76.33055100000013],[-84.38137799999993,76.32470699999993],[-84.37609899999995,76.31776400000012],[-84.38194299999998,76.31191999999993],[-84.39389,76.30802900000003],[-84.41305499999999,76.30470300000002],[-84.429169,76.30304000000007],[-84.53361499999994,76.30581699999999],[-84.71665999999993,76.30693099999996],[-84.77639799999997,76.303314],[-84.898056,76.28858900000006],[-84.92832899999996,76.28637700000002],[-85.17443800000001,76.28027299999997],[-85.23222399999992,76.29525799999993],[-85.36221299999994,76.303314],[-85.50500499999998,76.32193000000007],[-85.52305599999988,76.32666000000006],[-85.54444899999999,76.32998700000002],[-85.69833399999999,76.34887700000013],[-85.95249899999993,76.36859100000004],[-85.97805800000003,76.37052899999998],[-86.00418100000002,76.37081900000004],[-86.11027499999994,76.3683170000001],[-86.13473499999998,76.36943100000008],[-86.281677,76.37692300000003],[-86.33056599999998,76.3808140000001],[-86.37222300000002,76.38638300000008],[-86.412216,76.40776100000005],[-86.41500899999988,76.41276600000009],[-86.42138699999992,76.45694000000003],[-86.41861,76.46914700000002],[-86.40972899999991,76.47470099999998],[-86.398056,76.4788670000001],[-86.37887599999999,76.48387100000002],[-86.36082499999992,76.48776200000009],[-86.30776999999995,76.49552900000009],[-86.27778599999994,76.5],[-86.25611900000001,76.50387600000005],[-86.22222899999997,76.51332100000013],[-86.21305799999993,76.5186000000001],[-86.20777899999996,76.52442900000011],[-86.21194499999996,76.53526299999999],[-86.22610499999996,76.54275500000011],[-86.53277600000001,76.62330600000001],[-86.59416199999998,76.63499499999995],[-86.63034099999993,76.63513200000011],[-86.62582399999997,76.62942500000008],[-86.60110499999996,76.61998],[-86.51251200000002,76.58692900000005],[-86.36221299999994,76.54165599999993],[-86.34222399999999,76.51220699999993],[-86.5080569999999,76.48776200000009],[-86.64916999999997,76.45887800000014],[-86.66471899999999,76.41970800000001],[-86.71112099999999,76.34803799999997],[-86.71665999999999,76.34610000000004],[-86.770554,76.35081500000007],[-87.083328,76.37942499999991],[-87.130829,76.38415500000013],[-87.148346,76.38832100000008],[-87.15499899999998,76.39498900000001],[-87.15417500000001,76.40109300000006],[-87.225281,76.44802900000008],[-87.4266659999999,76.46859699999999],[-87.46278399999994,76.58692900000005],[-87.468887,76.59165999999999],[-87.52027900000002,76.61248800000004],[-87.53694200000001,76.61747700000001],[-87.56361399999997,76.61637900000011],[-87.58000199999998,76.61137400000007],[-87.583618,76.60498000000001],[-87.59861799999999,76.540817],[-87.59555099999994,76.53414900000001],[-87.553604,76.451096],[-87.54527300000001,76.44358799999998],[-87.53694200000001,76.43914799999999],[-87.516953,76.43248],[-87.50029,76.42886399999992],[-87.45527600000003,76.42387400000007],[-87.42999299999991,76.41775500000006],[-87.40249599999999,76.35276800000003],[-87.41639700000002,76.34803799999997],[-87.59138499999989,76.341095],[-87.64889499999987,76.33804300000008],[-87.71972699999998,76.34304800000012],[-87.74276700000001,76.34637500000008],[-87.760559,76.35220299999997],[-87.78860499999996,76.366379],[-87.81723,76.39054900000002],[-87.86416600000001,76.38998400000014],[-87.90083300000003,76.36303700000008],[-87.916946,76.359711],[-87.94833399999999,76.3577580000001],[-87.997772,76.35832200000004],[-88.3511049999999,76.384995],[-88.38999899999988,76.38970899999998],[-88.42971799999998,76.39804100000015],[-88.43443300000001,76.40220599999998],[-88.391953,76.45416300000011],[-88.37193299999996,76.47608900000006],[-88.35583500000001,76.48109399999993],[-88.34861799999999,76.48719800000015],[-88.34944199999995,76.5144350000001],[-88.35665899999998,76.5211030000001],[-88.44276400000001,76.59165999999999],[-88.51528899999994,76.63610800000004],[-88.50917099999998,76.69747899999999],[-88.48860199999996,76.76527400000003],[-88.47972099999993,76.77693200000004],[-88.47666900000002,76.78332499999999],[-88.47471599999989,76.78887900000001],[-88.47471599999989,76.794983],[-88.47778299999999,76.80775500000004],[-88.485275,76.81442299999998],[-88.49471999999997,76.81721500000009],[-88.51889,76.8160860000001],[-88.54194599999994,76.81275899999997],[-88.55444299999994,76.80748],[-88.55722000000003,76.8058170000001],[-88.70195000000001,76.70748900000012],[-88.68331899999998,76.7019350000001],[-88.64973399999997,76.68414300000006],[-88.591949,76.64276100000001],[-88.58444199999997,76.63581800000003],[-88.49554399999994,76.55219999999997],[-88.489441,76.50332600000002],[-88.49638399999998,76.49720800000006],[-88.57167099999992,76.47360200000003],[-88.59355899999997,76.45593300000002],[-88.60321799999997,76.44926500000003],[-88.60821499999997,76.44226100000014],[-88.60772700000001,76.43909500000001],[-88.608612,76.4160920000001],[-88.59973100000002,76.40998800000011],[-88.59750399999996,76.40582300000011],[-88.60804699999994,76.39999400000005],[-88.63194299999992,76.39721700000001],[-88.65638699999988,76.39833099999998],[-88.67721599999993,76.40193200000004],[-88.68998699999997,76.40832499999999],[-88.693604,76.41470300000015],[-88.693329,76.42082199999999],[-88.68499800000001,76.43248],[-88.67805499999997,76.44165000000004],[-88.65950800000002,76.4787060000001],[-88.64650699999999,76.48921200000001],[-88.640289,76.55859400000003],[-88.64416499999999,76.56526200000002],[-88.65167200000002,76.57193000000001],[-88.66027799999995,76.57777399999998],[-88.68888899999996,76.59136999999998],[-88.71000699999996,76.594986],[-88.73361199999994,76.59387200000003],[-88.74082899999996,76.5877690000001],[-88.79138199999994,76.51332100000013],[-88.79527300000001,76.47943100000003],[-88.78666699999991,76.47360200000003],[-88.78138699999994,76.46638500000006],[-88.78332499999999,76.46081500000003],[-88.79943800000001,76.44999700000005],[-88.90167199999996,76.40832499999999],[-88.92111199999994,76.40525800000006],[-88.94722000000002,76.40525800000006],[-88.99415599999992,76.40914900000013],[-89.16639699999996,76.42442300000005],[-89.21333299999998,76.42970300000007],[-89.231674,76.43359399999997],[-89.35333300000002,76.47997999999995],[-89.40722700000003,76.51582300000001],[-89.49027999999993,76.55748000000006],[-89.499435,76.54664600000001],[-89.515015,76.54165599999993],[-89.541382,76.54165599999993],[-89.66722099999998,76.56442300000003],[-89.67666599999995,76.56721500000015],[-89.67944299999999,76.57165500000013],[-89.61416600000001,76.6160890000001],[-89.60360700000001,76.62191800000011],[-89.57194500000003,76.63165300000003],[-89.52833599999997,76.64082300000007],[-89.48055999999997,76.649429],[-89.443329,76.6583250000001],[-89.43138099999999,76.66360500000002],[-89.41555800000003,76.67442299999999],[-89.41166699999997,76.68026699999996],[-89.4344329999999,76.72442600000011],[-89.47222899999997,76.78471400000001],[-89.49694799999992,76.820267],[-89.51444999999995,76.83581500000003],[-89.52917500000001,76.84721400000012],[-89.53332499999999,76.85359200000005],[-89.52139299999993,76.85887100000008],[-89.41777000000002,76.88665800000001],[-89.279449,76.90693699999997],[-89.23889200000002,76.91609199999999],[-89.14805599999994,76.92553700000008],[-88.98693800000001,76.95443699999993],[-88.97610499999996,76.95999100000012],[-88.89889499999998,76.98553500000014],[-88.76916499999999,76.99887100000007],[-88.74027999999993,77.00277699999998],[-88.71945199999993,77.00749200000001],[-88.70278899999994,77.01220700000005],[-88.50111400000003,77.07165500000008],[-88.47332799999998,77.09664900000001],[-88.54472399999992,77.09803800000003],[-88.545837,77.10026600000015],[-88.42639200000002,77.12081900000004],[-88.30721999999997,77.12886000000009],[-88.27833599999991,77.12969999999996],[-88.17250100000001,77.12803599999995],[-88.15417500000001,77.11608899999999],[-87.96722399999993,77.12747200000001],[-87.69055200000003,77.135269],[-87.67027299999995,77.13360600000004],[-87.65695199999993,77.13026400000012],[-87.64250199999998,77.12498499999992],[-87.626938,77.11747700000012],[-87.61971999999997,77.11080900000013],[-87.56889299999989,77.09942600000011],[-87.45584100000002,77.1019290000001],[-87.34916699999997,77.1060940000001],[-87.33778399999989,77.11025999999998],[-87.35360700000001,77.11470000000003],[-87.37222300000002,77.11720300000002],[-87.45140100000003,77.12275699999998],[-87.460556,77.12553400000007],[-87.45666499999999,77.13192700000002],[-87.452225,77.13638300000014],[-87.43221999999997,77.14971900000006],[-87.41610700000001,77.15664700000008],[-87.4041749999999,77.16081200000008],[-87.35638399999999,77.17553700000002],[-87.33666999999997,77.1791530000001],[-87.31277499999999,77.1808170000001],[-87.06916799999999,77.18275500000004],[-87.04444899999993,77.18054200000006],[-86.95916699999998,77.16192600000005],[-86.95167499999997,77.15832499999999],[-86.94694500000003,77.15443399999992],[-86.9519499999999,77.1499940000001],[-86.95140100000003,77.14471400000002],[-86.94249000000002,77.14193699999993],[-86.87527499999993,77.13220200000006],[-86.82917799999996,77.12776200000002],[-86.80444299999999,77.12719700000002],[-86.791382,77.13081399999999],[-86.73999000000003,77.17414900000011],[-86.77362099999993,77.18580600000007],[-86.96000699999996,77.19581599999998],[-87.15055799999999,77.19941700000004],[-87.148056,77.19802900000013],[-87.14695699999993,77.19581599999998],[-87.16111799999993,77.19442699999996],[-87.18276999999995,77.19693000000012],[-87.19610599999993,77.19999700000005],[-87.21055599999994,77.20526100000006],[-87.1744379999999,77.22943100000003],[-87.16694599999994,77.23387100000008],[-87.141388,77.23803700000013],[-87.00723299999999,77.255829],[-86.97666900000002,77.25749200000013],[-86.94888299999997,77.25555400000002],[-86.92832900000002,77.25526400000001],[-86.91055299999994,77.26026900000005],[-86.91915899999998,77.26609800000006],[-86.94749499999995,77.27165200000007],[-86.98443600000002,77.27470399999999],[-87.01222199999995,77.27499399999999],[-87.07806399999993,77.27360499999998],[-87.10611,77.27221700000007],[-87.13667299999997,77.27221700000007],[-87.18388400000003,77.27360499999998],[-87.197495,77.27526899999998],[-87.22917199999995,77.28553800000003],[-87.24527,77.29832500000003],[-87.24888599999997,77.303314],[-87.108612,77.33831800000007],[-87.09584000000001,77.34027100000003],[-87.06861899999996,77.34220900000014],[-87.037781,77.34220900000014],[-86.96278399999994,77.33915700000006],[-86.93472299999996,77.33888200000001],[-86.900284,77.34220900000014],[-86.84583999999995,77.34915200000012],[-86.82972699999999,77.35304300000001],[-86.83860800000002,77.35748300000006],[-86.851944,77.36053500000014],[-86.96333299999998,77.366379],[-87.06416299999995,77.36692800000009],[-87.09110999999996,77.366379],[-87.24137899999994,77.35609400000004],[-87.26306199999988,77.35165400000005],[-87.28083800000002,77.34693900000002],[-87.29415899999998,77.34165999999999],[-87.32611099999997,77.33387800000008],[-87.35888699999998,77.3313750000001],[-87.39111299999996,77.33055100000013],[-87.41639700000002,77.33082600000012],[-87.695831,77.35554500000012],[-87.71194500000001,77.35998500000011],[-87.71583599999991,77.36331200000006],[-87.775284,77.41554300000013],[-87.78028899999998,77.42109700000015],[-87.78472899999997,77.42970300000007],[-87.77500900000001,77.44136000000003],[-87.74833699999999,77.45166000000012],[-87.73083499999996,77.45637499999998],[-87.66953999999998,77.46923800000002],[-87.65194699999995,77.47499099999999],[-87.64250199999998,77.48027000000013],[-87.64611799999994,77.4869230000001],[-87.69444299999998,77.5372010000001],[-87.71112099999988,77.5416560000001],[-87.86888099999999,77.57859800000011],[-88.06304899999998,77.61886600000003],[-88.162216,77.62692300000015],[-88.18055699999996,77.63192700000013],[-88.20083599999992,77.64276100000001],[-88.214722,77.65054299999997],[-88.22361799999993,77.66249099999999],[-88.223053,77.66720600000002],[-88.22111499999988,77.67276000000004],[-88.162781,77.758331],[-88.06806899999998,77.820267],[-87.83583099999993,77.84027100000009],[-87.64056399999998,77.86248799999998],[-87.29472399999992,77.89804100000003],[-87.23138399999993,77.89888000000013],[-87.174713,77.897491],[-86.87609900000001,77.8836060000001],[-86.82417299999992,77.87942499999997],[-86.65167199999996,77.86026000000004],[-86.46166999999997,77.83610500000003],[-86.42222599999997,77.83082600000006],[-86.37748699999992,77.82276900000005],[-86.222778,77.79443400000002],[-86.19888300000002,77.78610200000008],[-85.98693800000001,77.71138000000013],[-85.97528099999988,77.70582599999994],[-85.88444500000003,77.6327510000001],[-85.718887,77.47221400000006],[-85.71583599999997,77.46720900000003],[-85.71722399999993,77.46249399999999],[-85.72721899999988,77.45193499999993],[-85.74861099999998,77.44693000000007],[-85.76916499999993,77.44358799999998],[-85.77583299999992,77.43997200000007],[-85.795837,77.42387400000007],[-85.79444899999993,77.41970800000013],[-85.776947,77.42137100000008],[-85.55139199999996,77.45832800000011],[-85.53056299999992,77.46192899999994],[-85.49333199999995,77.43026700000001],[-85.43638599999991,77.40415999999993],[-85.39973399999991,77.395828],[-85.3766629999999,77.39248700000013],[-85.29943800000001,77.3877720000001],[-85.27000399999991,77.38665800000012],[-85.15583800000002,77.38749700000005],[-84.97332799999987,77.37719700000014],[-84.95472699999993,77.37442000000004],[-84.9375,77.37081899999998],[-84.87527499999999,77.35165400000005],[-84.82528699999995,77.33415200000002],[-84.75917099999987,77.31832899999995],[-84.71972700000003,77.311646],[-84.64944499999996,77.30442800000014],[-84.601944,77.30053700000008],[-84.52917500000001,77.29582200000004],[-84.479446,77.29443400000014],[-84.46639999999996,77.29637100000002],[-84.46333300000003,77.30026200000009],[-84.47444200000001,77.3119200000001],[-84.48194899999999,77.31776400000012],[-84.49471999999997,77.32110600000004],[-84.52027900000002,77.32415799999995],[-84.553879,77.3313750000001],[-84.56916799999999,77.33970599999998],[-84.615005,77.38304099999999],[-84.61277799999988,77.38916],[-84.60388199999994,77.39359999999999],[-84.58555599999994,77.39804100000009],[-84.55027799999993,77.40138200000013],[-84.52084400000001,77.401657],[-84.49610899999999,77.399429],[-84.47055099999994,77.39637800000003],[-84.42944299999994,77.38888499999996],[-84.38639799999999,77.38388100000003],[-84.33444199999991,77.38304099999999],[-84.27027899999996,77.384995],[-84.15360999999996,77.39498900000001],[-84.06166100000002,77.39860500000003],[-84.00584399999997,77.39749100000006],[-83.985275,77.39553799999993],[-83.949997,77.38888499999996],[-83.86805700000002,77.37692300000003],[-83.79361,77.36914100000007],[-83.53195199999993,77.34637500000002],[-83.50584399999997,77.34471100000002],[-83.47805800000003,77.34414700000008],[-83.464722,77.34832799999998],[-83.46305799999988,77.34915200000012],[-83.46444699999995,77.35554500000012],[-83.47250400000001,77.38720700000005],[-83.55305499999997,77.39305100000007],[-83.65499899999998,77.39553799999993],[-83.71166999999991,77.40470900000008],[-83.72860700000001,77.40832499999993],[-83.77860999999996,77.42330900000002],[-83.82250999999997,77.442474],[-83.83389299999999,77.448868],[-83.835556,77.45526100000001],[-83.82472200000001,77.46054100000003],[-83.80139199999996,77.46470600000004],[-83.76806599999992,77.46693400000004],[-83.68222000000003,77.46804800000001],[-83.62083399999995,77.47192400000006],[-83.59388699999994,77.47554000000014],[-83.42610200000001,77.4997100000001],[-83.38945000000001,77.50776700000011],[-83.36332699999997,77.51805100000013],[-83.21611000000001,77.57777399999998],[-83.011124,77.665817],[-82.89500399999986,77.71748400000001],[-82.67443800000001,77.836929],[-82.65527299999985,77.84776300000004],[-82.54167199999995,77.92053200000004],[-82.52610799999997,77.96192900000005],[-82.577225,78.00332600000007],[-82.59083599999997,78.01110800000004],[-82.59167500000001,78.01748700000007],[-82.57972699999988,78.02276600000005],[-82.56361400000003,78.02777100000009],[-82.53805499999999,78.03109699999999],[-82.49749800000001,78.03414900000007],[-82.470551,78.03471400000012],[-82.40972899999997,78.03414900000007],[-82.37748699999992,78.03581200000002],[-82.36944599999993,78.03942899999993],[-82.32611099999997,78.06526200000008],[-82.31861900000001,78.07083100000006],[-82.32000700000003,78.07582100000013],[-82.33612099999999,78.07887300000004],[-82.51834100000002,78.07415800000001],[-82.54943800000001,78.07193000000007],[-82.652222,78.05609099999992],[-82.67250099999995,78.0516510000001],[-82.69248999999996,78.04498300000012],[-82.78028899999998,78.0149990000001],[-82.79028299999999,78.0105440000001],[-82.7927699999999,78.00582900000006],[-82.79415899999998,77.99498],[-82.78527799999995,77.969986],[-82.77528399999994,77.964157],[-82.735275,77.9474790000001],[-82.72888199999994,77.93997200000001],[-82.72860700000001,77.92970300000013],[-82.73611499999998,77.92414899999994],[-82.76916499999999,77.91499300000004],[-82.85221899999999,77.89694200000002],[-82.9491579999999,77.87469499999997],[-83.12304699999993,77.78054800000007],[-83.15666199999993,77.74498000000006],[-83.18554699999999,77.716385],[-83.19248999999996,77.71054099999998],[-83.20083599999987,77.70555100000013],[-83.38667299999992,77.61665300000004],[-83.42721599999999,77.60081500000001],[-83.52778599999994,77.57276900000011],[-83.648056,77.54081699999995],[-83.73500099999995,77.5188750000001],[-83.87304699999999,77.49331699999999],[-83.89834599999995,77.49054000000007],[-83.92054699999994,77.49165299999999],[-84.14389,77.50943000000001],[-84.19249000000002,77.51554900000008],[-84.22999599999997,77.52137800000008],[-84.38667299999992,77.528595],[-84.41999799999996,77.52777100000003],[-84.45222499999994,77.5249940000001],[-84.48332199999999,77.52165200000002],[-84.500565,77.51805100000013],[-84.55555700000002,77.51249700000011],[-84.57972699999999,77.51249700000011],[-84.76055899999994,77.51971400000008],[-84.77917499999995,77.52249099999995],[-84.85888699999992,77.54275500000011],[-84.86915599999998,77.56275900000003],[-84.87110899999999,77.56915300000009],[-84.86639399999996,77.57415800000012],[-84.837219,77.58387800000003],[-84.81555200000003,77.58888199999996],[-84.77362099999999,77.5977630000001],[-84.70722999999998,77.60998500000005],[-84.66528299999999,77.61886600000003],[-84.62748699999992,77.62803600000007],[-84.52000399999997,77.66470300000003],[-84.44193999999993,77.7061000000001],[-84.42999299999997,77.71832299999994],[-84.42832899999996,77.72276299999999],[-84.43110699999988,77.72637900000001],[-84.44305400000002,77.73637400000013],[-84.48693800000001,77.7502750000001],[-84.49527,77.75109900000007],[-84.50306699999999,77.74971000000005],[-84.48971599999993,77.74636800000013],[-84.48306299999996,77.74470500000001],[-84.475281,77.738876],[-84.47666900000002,77.72831699999995],[-84.48638899999997,77.71138000000013],[-84.49916100000002,77.6997070000001],[-84.52084400000001,77.6891480000001],[-84.53388999999999,77.68498199999999],[-84.54722600000002,77.68081699999999],[-84.715012,77.6397090000001],[-84.92250100000001,77.601654],[-84.95249899999999,77.60137900000012],[-84.9725039999999,77.60636900000003],[-85.1583399999999,77.64166300000011],[-85.29888900000003,77.66053800000003],[-85.31054699999999,77.66470300000003],[-85.34889199999992,77.72886699999998],[-85.34889199999992,77.73387100000014],[-85.33583099999998,77.73803700000008],[-85.19027699999987,77.77998400000013],[-85.05499299999997,77.79693600000013],[-85.05360399999995,77.83055100000001],[-85.14416499999999,77.81749000000008],[-85.297775,77.79721100000012],[-85.32806399999993,77.79832499999992],[-85.38194299999998,77.80775499999999],[-85.40028399999994,77.813309],[-85.40249599999993,77.81999199999996],[-85.40028399999994,77.83638000000002],[-85.389725,77.84193400000004],[-85.35333300000002,77.855545],[-85.32501200000002,77.86608900000004],[-85.281387,77.87441999999993],[-85.23194899999999,77.88165300000014],[-85.2077789999999,77.88388100000009],[-84.92555199999998,77.891098],[-84.837219,77.88749699999994],[-84.69249000000002,77.89860499999998],[-84.664444,77.90220600000004],[-84.61111499999993,77.90387000000004],[-84.498154,77.90011600000008],[-84.428879,77.89694200000002],[-84.38583399999993,77.891098],[-84.36805699999991,77.88720699999993],[-84.34277299999991,77.88499500000006],[-84.31861899999996,77.88693200000012],[-84.31361400000003,77.89193699999998],[-84.32501200000002,77.89610300000004],[-84.37971500000003,77.90637200000009],[-84.40167199999996,77.91026299999999],[-84.55943299999996,77.92303499999997],[-84.57556199999999,77.92387400000013],[-84.63444499999991,77.92692600000004],[-84.66305499999993,77.92526200000003],[-84.81666599999994,77.911652],[-84.84722899999991,77.90887500000008],[-85.05694599999998,77.90054300000008],[-85.16639699999996,77.90220600000004],[-85.20056199999999,77.90165700000006],[-85.26750199999992,77.89804100000003],[-85.303604,77.89471400000008],[-85.33168,77.89082300000001],[-85.37805199999997,77.88220200000006],[-85.42304999999999,77.87469499999997],[-85.47471599999994,77.8685910000001],[-85.515289,77.8836060000001],[-85.67887899999994,77.92942800000014],[-85.67971799999998,77.93664599999994],[-85.67527799999999,77.9416500000001],[-85.660278,77.94663999999995],[-85.45056199999999,77.9910890000001],[-85.28694200000001,78.02165200000007],[-85.06555199999991,78.05636600000014],[-85.03889499999991,78.05720500000012],[-85.00973499999992,78.055252],[-84.96305799999993,78.04414399999996],[-84.88417099999992,78.033051],[-84.81695599999995,78.02638200000013],[-84.78805499999999,78.02415500000006],[-84.76167299999992,78.02360500000003],[-84.72694399999995,78.02581799999996],[-84.70889299999999,78.02943400000004],[-84.69554099999993,78.03359999999992],[-84.68888899999996,78.03915400000011],[-84.67388899999997,78.04414399999996],[-84.65417500000001,78.04887400000001],[-84.57556199999999,78.06721500000003],[-84.54750100000001,78.0711060000001],[-84.5244449999999,78.07222000000007],[-84.36000100000001,78.07026700000011],[-84.3286129999999,78.07054100000005],[-84.30721999999997,78.07249500000006],[-84.28805499999993,78.07554600000009],[-84.29276999999996,78.07804900000008],[-84.29943800000001,78.07971200000003],[-84.32362399999994,78.08276400000011],[-84.41000399999996,78.08692900000011],[-84.5327759999999,78.08554100000003],[-84.55722000000003,78.0836030000001],[-84.62304699999999,78.07138100000009],[-84.67361499999998,78.0641480000001],[-84.7369379999999,78.0583190000001],[-84.76556399999998,78.05636600000014],[-84.79888899999997,78.055252],[-84.85583500000001,78.05693099999996],[-84.88194299999998,78.05914300000006],[-84.99388099999999,78.07415800000001],[-85.07749899999993,78.09082000000001],[-85.09445199999993,78.097488],[-85.08778399999989,78.103317],[-84.9949949999999,78.16304000000002],[-84.901947,78.17082199999999],[-84.82945299999994,78.16886900000003],[-84.79388399999999,78.17109699999997],[-84.761124,78.17442300000005],[-84.70861799999994,78.18248],[-84.68859899999995,78.18719500000003],[-84.65777599999996,78.19720500000011],[-84.63110399999988,78.19999700000005],[-84.54943799999995,78.19720500000011],[-84.43055700000002,78.18637100000007],[-84.31555199999997,78.17359900000008],[-84.28416400000003,78.16638199999994],[-84.222778,78.15887500000002],[-84.20111099999997,78.15693700000008],[-84.17388900000003,78.15776100000005],[-84.12777699999992,78.17109699999997],[-84.12666299999995,78.17997700000001],[-84.45361299999996,78.21470600000009],[-84.47972099999993,78.21693400000004],[-84.50666799999993,78.217758],[-84.693604,78.21720900000008],[-84.72250400000001,78.21693400000004],[-84.77749599999987,78.21026600000005],[-84.87721299999993,78.19303900000006],[-84.90972899999986,78.1910860000001],[-84.93777499999993,78.192474],[-84.95140099999998,78.19552599999992],[-84.968613,78.20248400000008],[-84.97389199999998,78.20860299999998],[-84.97027600000001,78.21415700000011],[-84.96722399999993,78.21804800000001],[-84.95611600000001,78.23220800000013],[-84.94276400000001,78.24386600000014],[-84.83444199999991,78.31498700000003],[-84.81527699999992,78.32165499999996],[-84.79249600000003,78.32499700000011],[-84.73138399999999,78.32554600000003],[-84.658615,78.3294370000001],[-84.62971500000003,78.333328],[-84.60527000000002,78.3374940000001],[-84.58528100000001,78.3419340000001],[-84.57556199999999,78.34637500000002],[-84.57278400000001,78.35054000000002],[-84.57194499999997,78.35554500000006],[-84.57583599999992,78.36137400000007],[-84.58167999999995,78.3660890000001],[-84.601944,78.36886600000003],[-84.63082899999995,78.36499000000015],[-84.66776999999996,78.34860200000008],[-84.68472299999996,78.34414700000008],[-84.70722999999998,78.34109499999994],[-84.73500100000001,78.34027099999997],[-84.77223199999997,78.34220900000014],[-84.81555200000003,78.34915200000012],[-84.86694299999999,78.36914100000007],[-84.86582900000002,78.37220799999994],[-84.785278,78.50166300000006],[-84.78250100000002,78.50582900000012],[-84.77471899999995,78.50915499999996],[-84.75917099999987,78.51416000000006],[-84.73860200000001,78.5188750000001],[-84.72416699999997,78.52442900000005],[-84.70445299999994,78.53498800000011],[-84.62582399999997,78.58415200000007],[-84.61944599999993,78.58831800000002],[-84.61999499999996,78.59054600000013],[-84.63861099999997,78.59414700000002],[-84.66111799999999,78.59248400000007],[-84.67527799999999,78.58831800000002],[-84.83833299999998,78.516663],[-84.84638999999993,78.51165800000012],[-84.97833300000002,78.4149930000001],[-84.97471599999994,78.35887100000014],[-84.97055099999994,78.35331700000012],[-84.96472199999994,78.34860200000008],[-84.96194500000001,78.34359700000005],[-84.96665999999999,78.33888200000001],[-85.04333500000001,78.299149],[-85.18804899999998,78.22831700000006],[-85.41833500000001,78.11886600000008],[-85.43331899999998,78.113876],[-85.45083599999992,78.10998499999994],[-85.48611499999993,78.10247800000002],[-85.50805700000001,78.099152],[-85.52305599999988,78.09942600000011],[-85.52806099999992,78.1019290000001],[-85.60888699999998,78.10081500000007],[-85.74082900000002,78.09304800000012],[-85.80471799999998,78.08888200000007],[-85.87666299999995,78.08166499999993],[-85.89416499999999,78.07804900000008],[-86.01028399999996,78.06608600000004],[-86.11999500000002,78.05636600000014],[-86.14834599999995,78.05470300000002],[-86.17805499999997,78.05497700000012],[-86.22332799999998,78.05748000000011],[-86.26722699999999,78.06637600000005],[-86.28222700000003,78.07165500000002],[-86.28832999999997,78.07638500000007],[-86.291382,78.0813750000001],[-86.29055800000003,78.08581500000014],[-86.25140399999998,78.15664700000008],[-86.23416099999997,78.16053799999997],[-86.13555899999994,78.16554300000001],[-86.11305199999987,78.17053199999998],[-86.098053,78.17553700000002],[-85.949997,78.22831700000006],[-85.93110699999994,78.23664900000006],[-85.83999599999999,78.32582100000008],[-85.83528100000001,78.33221400000002],[-85.82722499999994,78.34414700000008],[-85.82556199999993,78.34860200000008],[-85.83306899999997,78.379974],[-85.85333300000002,78.37915000000004],[-85.87805199999997,78.37692299999998],[-86.05277999999998,78.297485],[-86.060272,78.29248000000013],[-86.06054699999993,78.28054800000012],[-86.06527699999998,78.26361099999997],[-86.07362399999994,78.24859600000002],[-86.25917099999992,78.19636500000007],[-86.28527799999995,78.19331400000004],[-86.31111099999998,78.19331400000004],[-86.45361300000002,78.211929],[-86.47666899999996,78.21582000000006],[-86.49777199999994,78.21554600000013],[-86.51501499999995,78.21165500000006],[-86.53721599999994,78.19470199999995],[-86.54888899999997,78.18304400000011],[-86.56945799999994,78.17221099999995],[-86.71972699999998,78.121918],[-86.73693800000001,78.11804200000012],[-86.76306199999999,78.11499000000003],[-87.07972699999993,78.10276800000003],[-87.10943599999996,78.10304300000007],[-87.19665499999996,78.1060940000001],[-87.43971299999998,78.121643],[-87.50584399999991,78.12831099999994],[-87.52917499999995,78.132202],[-87.53860500000002,78.13804600000003],[-87.53500399999996,78.14305100000007],[-87.52667199999996,78.14915500000012],[-87.48388699999992,78.16442900000004],[-87.43055699999996,78.17831400000011],[-87.40750100000002,78.18304400000011],[-87.35221899999999,78.1910860000001],[-87.31416300000001,78.19386300000002],[-87.28999299999998,78.19470199999995],[-87.16694599999994,78.19552599999992],[-87.10499600000003,78.199142],[-87.08944699999995,78.20193499999999],[-87.087219,78.20609999999999],[-87.10583500000001,78.20942700000012],[-87.26222200000001,78.22665400000011],[-87.29360999999994,78.22608900000012],[-87.36389200000002,78.22109999999992],[-87.37165799999997,78.21943700000003],[-87.396118,78.21720900000008],[-87.42304999999993,78.21609500000005],[-87.47555499999987,78.21638500000012],[-87.49777199999994,78.21971100000013],[-87.51333599999992,78.22499099999999],[-87.51861600000001,78.230545],[-87.516953,78.24136400000009],[-87.51611300000002,78.2458190000001],[-87.49444599999998,78.29859899999997],[-87.50250199999988,78.30525200000011],[-87.51306199999999,78.31637599999999],[-87.51640299999997,78.32276899999994],[-87.52555799999999,78.41026300000004],[-87.52471899999995,78.41638200000011],[-87.51722699999999,78.42637600000012],[-87.50306699999999,78.43664600000005],[-87.47694399999995,78.44802900000002],[-87.31138599999991,78.50915499999996],[-87.29222099999993,78.51388500000002],[-87.15834000000001,78.54637100000014],[-87.14056399999998,78.55026200000003],[-87.01306199999999,78.5541530000001],[-86.89111299999996,78.54553199999998],[-86.86639400000001,78.54637100000014],[-86.85833699999995,78.5477600000001],[-86.85583499999996,78.55165099999999],[-86.85888699999998,78.56637599999993],[-86.864441,78.56887800000004],[-86.87777699999992,78.5730440000001],[-86.89862099999999,78.57582100000002],[-86.95777900000002,78.57499700000005],[-87.03167699999995,78.56915300000003],[-87.066101,78.56749000000013],[-87.09527599999996,78.56860400000011],[-87.11305199999993,78.5730440000001],[-87.12165800000002,78.57693499999999],[-87.12388599999997,78.58109999999999],[-87.12249800000001,78.58720400000004],[-86.94471699999997,78.70471199999997],[-86.93443299999996,78.70999100000012],[-86.92250100000001,78.71470599999998],[-86.85694899999993,78.73498500000011],[-86.63890100000003,78.79942299999999],[-86.61582900000002,78.80304000000012],[-86.37721299999998,78.80998200000005],[-86.13806199999999,78.81666600000011],[-86.06750499999998,78.81971699999991],[-86.03721599999994,78.82138099999997],[-85.64666699999987,78.84860200000014],[-85.60749799999996,78.85165400000011],[-85.57749899999993,78.85582],[-85.350281,78.88749700000011],[-85.32972699999993,78.89221199999997],[-85.29750099999995,78.90220599999998],[-85.25750700000003,78.91053799999997],[-85.09973100000002,78.91775500000006],[-85.06416300000001,78.91914400000007],[-85.03611799999999,78.91693099999992],[-85.008896,78.91331500000007],[-84.84584000000001,78.88888500000002],[-84.78832999999992,78.87803599999995],[-84.76640299999997,78.87303200000002],[-84.74055499999992,78.86998000000011],[-84.71278399999994,78.86775200000011],[-84.56332399999997,78.859985],[-84.412216,78.85554499999995],[-84.21278399999989,78.85693400000014],[-84.14500399999997,78.85554499999995],[-83.85082999999997,78.84526100000011],[-83.74694799999992,78.83692899999994],[-83.69444299999998,78.82971200000003],[-83.67443799999995,78.82554600000014],[-83.66000400000001,78.81999200000013],[-83.64056399999987,78.81387300000011],[-83.601944,78.80220000000008],[-83.57972699999993,78.79637100000008],[-83.53832999999992,78.78720100000004],[-83.51306199999999,78.78387499999997],[-83.48582499999998,78.78137200000003],[-83.428604,78.77915999999993],[-83.39416499999999,78.7788700000001],[-83.34584000000001,78.77360500000003],[-83.32749899999993,78.76971399999996],[-83.308334,78.76388500000013],[-83.29361,78.75610400000011],[-83.28492699999993,78.75000000000006],[-83.23693800000001,78.74054000000001],[-83.10139499999997,78.71443200000004],[-82.99472000000003,78.6997070000001],[-82.94193999999999,78.69552600000003],[-82.91082799999998,78.69470200000006],[-82.84500099999997,78.69747899999999],[-82.82250999999997,78.69525099999998],[-82.68971299999998,78.66415400000005],[-82.69638099999986,78.65776100000011],[-82.704453,78.6519320000001],[-82.69554099999999,78.64526400000011],[-82.61054999999993,78.61137400000001],[-82.506958,78.59109500000011],[-82.41722099999993,78.57415800000007],[-82.37388599999997,78.56860400000011],[-82.35749799999991,78.56749000000013],[-82.337784,78.56666599999994],[-82.308334,78.56887800000004],[-82.26222200000001,78.57804899999996],[-82.23693800000001,78.58831800000002],[-82.23554999999993,78.5958250000001],[-82.24471999999997,78.59887700000007],[-82.31027199999994,78.61665300000004],[-82.41665599999999,78.64276099999995],[-82.49638400000003,78.66192600000011],[-82.516953,78.66693099999998],[-82.535278,78.67275999999998],[-82.55943300000001,78.68220500000007],[-82.56555200000003,78.68525699999998],[-82.58473200000003,78.69552600000003],[-82.59445199999999,78.70304900000002],[-82.581955,78.708328],[-82.56916799999999,78.71138000000013],[-82.45666499999993,78.73082000000011],[-82.43554699999993,78.73165900000009],[-82.40777599999996,78.73082000000011],[-82.35055499999999,78.726089],[-82.27972399999999,78.71775800000006],[-82.25527999999991,78.71665999999999],[-82.23083500000001,78.71775800000006],[-82.22332799999998,78.71971100000002],[-82.21501199999989,78.72303799999997],[-82.22055099999989,78.73220800000001],[-82.23194899999999,78.73637400000013],[-82.25473,78.74081400000011],[-82.27917500000001,78.74414100000007],[-82.31082199999997,78.74693300000013],[-82.39639299999993,78.74914600000011],[-82.45666499999993,78.74914600000011],[-82.48083500000001,78.74832200000014],[-82.50611900000001,78.74581899999998],[-82.52555799999993,78.74220300000013],[-82.54277000000002,78.73719800000009],[-82.564438,78.73275800000005],[-82.61915599999998,78.72804300000001],[-82.66361999999992,78.72804300000001],[-82.75250199999994,78.72970599999996],[-82.781387,78.73109400000004],[-82.80972299999996,78.73414600000012],[-82.82695000000001,78.7374880000001],[-82.84333799999996,78.74220300000013],[-82.91166699999991,78.76638800000012],[-83.06973299999993,78.79220600000008],[-83.108612,78.79664600000007],[-83.21055599999994,78.79887400000007],[-83.22860700000001,78.80415300000004],[-83.25584400000002,78.82998700000007],[-83.25473,78.834991],[-83.24444599999993,78.8394320000001],[-83.2183379999999,78.8435970000001],[-83.1875,78.84721400000006],[-83.08583099999998,78.85554499999995],[-83.05694599999993,78.8560940000001],[-82.991669,78.85554499999995],[-82.81111099999998,78.84803800000003],[-82.67582699999997,78.84220900000003],[-82.65055799999999,78.83888200000007],[-82.62138400000003,78.83749399999999],[-82.46278399999994,78.83332800000011],[-82.42944299999999,78.83332800000011],[-82.28971899999999,78.83720399999999],[-82.25445599999995,78.84054600000007],[-82.11277799999999,78.85748300000012],[-82.07945299999994,78.85971100000006],[-81.947495,78.865814],[-81.91389499999991,78.865814],[-81.76417499999997,78.859985],[-81.74943499999995,78.85803200000004],[-81.74055499999992,78.85525499999994],[-81.76722699999999,78.853317],[-81.82444799999996,78.85386700000004],[-81.83860799999997,78.85137900000007],[-81.833618,78.84664900000001],[-81.82028199999996,78.84526100000011],[-81.74137899999988,78.83915700000011],[-81.71250900000001,78.83970600000004],[-81.69915799999995,78.84275799999995],[-81.66082799999992,78.87776200000002],[-81.65666199999987,78.88388100000009],[-81.65695199999999,78.88832100000008],[-81.66639700000002,78.89553799999999],[-81.68249499999996,78.90026899999992],[-81.73472599999997,78.90637200000009],[-81.75306699999999,78.9122010000001],[-81.75584399999997,78.91804500000012],[-81.69860799999992,78.97387700000007],[-81.69082599999996,78.98027000000002],[-81.68306000000001,78.98442100000011],[-81.553604,79.02415500000001],[-81.48611499999993,79.04165599999999],[-81.47721899999999,79.04721100000006],[-81.48666399999996,79.05247500000007],[-81.50306699999993,79.059143],[-81.521118,79.06109600000013],[-81.54861499999998,79.06135599999999],[-81.61776700000001,79.05108600000005],[-81.86582900000002,79.01361099999997],[-81.91027799999995,79.00499000000008],[-81.92832900000002,79],[-81.96112099999993,78.98692299999999],[-81.97222899999997,78.982483],[-81.97416699999997,78.97943100000003],[-81.99972500000001,78.9602660000001],[-82.09277299999991,78.91832000000011],[-82.11027499999994,78.91360500000008],[-82.34722899999997,78.89444000000009],[-82.50306699999993,78.88275099999998],[-82.55943300000001,78.88472000000002],[-82.68138099999999,78.90331999999995],[-82.81388899999996,78.92303500000014],[-82.839447,78.926376],[-82.92443800000001,78.9349820000001],[-83.06304899999998,78.93969700000014],[-83.12666300000001,78.94108599999993],[-83.26417500000002,78.93914799999999],[-83.51417499999997,78.93054200000006],[-83.57055700000001,78.92997700000006],[-83.63751200000002,78.9308170000001],[-83.69471699999991,78.934708],[-83.78721599999989,78.94247400000006],[-83.81277499999999,78.94581599999998],[-84.03416399999998,78.95665000000002],[-84.16555800000003,78.95694000000003],[-84.20056199999999,78.95721399999996],[-84.25917099999998,78.95942700000012],[-84.328888,78.96527100000014],[-84.36749299999997,78.97248800000006],[-84.38612399999988,78.97776799999997],[-84.42999299999997,78.98776199999998],[-84.47305299999994,78.99552900000009],[-84.57333399999987,79.00999500000012],[-84.65139799999997,79.01943999999997],[-84.67944299999999,79.02165200000007],[-84.72694399999995,79.02777100000009],[-84.74804699999999,79.03193699999997],[-84.766953,79.03720099999998],[-84.77917499999995,79.04664600000001],[-84.78971899999999,79.06414800000005],[-84.78916899999996,79.06944299999998],[-84.78388999999999,79.07443200000012],[-84.65167200000002,79.11469999999997],[-84.54415899999998,79.14137299999999],[-84.5286099999999,79.14332600000006],[-84.50361599999991,79.14444000000009],[-84.47305299999994,79.14305100000007],[-84.16389499999991,79.12414600000011],[-84.135559,79.121918],[-84.07556199999993,79.10443099999992],[-84.0625,79.09054600000002],[-84.04055800000003,79.07544700000005],[-83.99027999999998,79.0516510000001],[-83.95056199999993,79.0435940000001],[-83.89639299999999,79.03804000000014],[-83.74472000000003,79.02804600000007],[-83.60055499999993,79.02526900000004],[-83.504456,79.02360499999998],[-83.474716,79.02415500000001],[-83.45472699999999,79.02554299999997],[-83.386124,79.0394290000001],[-83.36860699999994,79.04443400000014],[-83.35861199999994,79.05081200000012],[-83.37361099999993,79.05636600000014],[-83.39944500000001,79.05970800000006],[-83.41555799999998,79.05998199999999],[-83.43083199999995,79.05831900000004],[-83.46167000000003,79.05220000000003],[-83.49388099999993,79.04332],[-83.521118,79.04136700000004],[-83.54611199999994,79.04248000000013],[-83.70666499999993,79.07777400000003],[-83.97639499999997,79.14109800000011],[-84.00361599999991,79.14860500000009],[-84.02999899999998,79.151657],[-84.02917500000001,79.15693700000003],[-84.01889,79.16137700000007],[-84.00500499999993,79.1660920000001],[-83.95249899999999,79.18026700000001],[-83.93998699999992,79.18553200000008],[-83.93331899999993,79.19192500000003],[-83.941101,79.21638500000006],[-83.95666499999999,79.22192400000006],[-83.97972099999993,79.22164900000007],[-84.01695299999994,79.21304299999997],[-84.04305999999991,79.20304899999996],[-84.05194099999994,79.19802900000008],[-84.06750499999998,79.192474],[-84.08612099999999,79.18803399999996],[-84.12193300000001,79.18470800000011],[-84.15850799999998,79.18330400000013],[-84.193329,79.18304400000011],[-84.30332900000002,79.18664600000005],[-84.32694999999995,79.18858300000011],[-84.32389799999987,79.19470200000012],[-84.31666599999994,79.20054600000014],[-84.31361400000003,79.20664999999997],[-84.335556,79.2522130000001],[-84.34445199999999,79.25804100000005],[-84.36277799999999,79.26499900000005],[-84.40110800000002,79.27526899999998],[-84.428879,79.29026800000003],[-84.452789,79.32887299999999],[-84.45222499999994,79.34165999999999],[-84.44665499999996,79.35386699999992],[-84.44610599999993,79.35887100000008],[-84.48472599999997,79.40637200000015],[-84.50334199999998,79.41304000000014],[-84.58111600000001,79.43386800000002],[-84.60611,79.43803400000013],[-84.660278,79.44413800000012],[-84.70916699999998,79.45166000000006],[-84.82112099999995,79.47303799999997],[-84.88249200000001,79.48609899999991],[-84.89695699999993,79.49247700000006],[-84.96945199999999,79.53749100000005],[-84.9725039999999,79.54220600000008],[-85.02223200000003,79.61109900000002],[-85.028885,79.61581400000006],[-85.05027799999999,79.62164300000006],[-85.06889299999995,79.62608300000005],[-85.25418099999996,79.66720599999996],[-85.3724979999999,79.684418],[-85.49333199999995,79.70054600000003],[-85.55139199999996,79.70582600000012],[-85.61582899999996,79.708328],[-85.68443300000001,79.70915200000013],[-85.76306199999999,79.70555100000007],[-85.94888299999991,79.708328],[-86.20333900000003,79.73580900000007],[-86.38751200000002,79.74748200000005],[-86.41583300000002,79.75054899999998],[-86.44583099999988,79.75416600000011],[-86.47193900000002,79.75972000000013],[-86.48638900000003,79.76361100000003],[-86.49360699999994,79.76832600000006],[-86.50222799999995,79.77526900000004],[-86.47193900000002,79.89054900000002],[-86.46028100000001,79.91970800000001],[-86.45028699999989,79.93109100000004],[-86.43638599999997,79.942474],[-86.42443799999995,79.94802900000008],[-86.389725,79.9580380000001],[-86.36721799999998,79.96276900000004],[-86.30027799999993,79.96859699999999],[-86.26333599999992,79.96914700000002],[-86.23028599999998,79.96804800000001],[-86.08389299999999,79.95748900000001],[-85.88583399999999,79.9410860000001],[-85.81973299999993,79.93858299999994],[-85.78500399999996,79.93803400000002],[-85.71139499999992,79.93748500000004],[-85.65695199999999,79.93803400000002],[-85.519455,79.92498800000004],[-85.4600069999999,79.91081200000008],[-85.41639700000002,79.90138200000001],[-85.38999899999993,79.89749100000012],[-85.36582900000002,79.89637800000003],[-85.308334,79.90054300000003],[-85.28916899999996,79.90498400000013],[-85.27500899999995,79.909424],[-85.26251199999996,79.91499299999998],[-85.25500499999993,79.92082199999999],[-85.271118,79.92387400000007],[-85.44082600000002,79.938309],[-85.64083900000003,79.96276900000004],[-86.19055200000003,80],[-86.30194099999994,79.99832200000009],[-86.34138499999995,79.99693300000007],[-86.41332999999997,79.99803200000008],[-86.44276399999995,79.99971],[-86.46640000000002,80.00387600000005],[-86.48277300000001,80.0086060000001],[-86.56555199999997,80.03581200000013],[-86.57945299999994,80.04304500000012],[-86.64250199999992,80.09803799999997],[-86.65861499999988,80.11775200000005],[-86.65943900000002,80.12803600000007],[-86.65583799999996,80.13526900000011],[-86.51472499999994,80.29914900000011],[-86.49305700000002,80.30442800000009],[-86.46833799999996,80.30859400000003],[-86.43443299999996,80.3124850000001],[-86.34500100000002,80.31915300000003],[-86.11610399999995,80.33360299999998],[-86.07611099999991,80.33360299999998],[-85.89750700000002,80.333054],[-85.74526999999995,80.320267],[-85.71749899999998,80.31637599999993],[-85.67193600000002,80.30693100000008],[-85.61665299999993,80.29887400000013],[-85.50917099999998,80.28581200000008],[-85.47917199999995,80.28276100000005],[-85.35417199999989,80.27304100000015],[-85.29083299999996,80.26860000000005],[-85.256958,80.26721199999997],[-85.09583999999995,80.2622070000001],[-84.9375,80.26721199999997],[-84.898346,80.26944000000009],[-84.77917499999995,80.27249100000012],[-84.70249899999993,80.27331500000008],[-84.589722,80.27360500000009],[-84.19665500000002,80.27137800000003],[-84.0494379999999,80.26776100000012],[-83.989441,80.26443500000005],[-83.92639200000002,80.25972000000002],[-83.81111099999998,80.249146],[-83.78195199999999,80.24581900000004],[-83.71611000000001,80.23387100000002],[-83.62638900000002,80.21360800000014],[-83.56082199999997,80.1958160000001],[-83.54638699999998,80.18942300000015],[-83.47805800000003,80.16442899999998],[-83.46139499999992,80.15914900000007],[-83.42471299999994,80.1483310000001],[-83.40306099999998,80.14221200000009],[-83.24499499999996,80.10359199999994],[-83.13890100000003,80.07832300000013],[-83.02972399999999,80.053314],[-82.89805599999994,80.02526899999998],[-82.80332900000002,80.00637799999998],[-82.73611499999998,79.99247699999995],[-82.60583500000001,79.96443199999999],[-82.28388999999999,79.89305100000007],[-82.15306099999998,79.85887099999997],[-82.10194399999995,79.83970600000004],[-82.09167500000001,79.83471700000007],[-82.06249999999994,79.81608600000004],[-82.04638699999998,79.8016510000001],[-81.976944,79.73580900000007],[-81.981674,79.72387700000007],[-81.978882,79.71832300000011],[-81.91665599999999,79.70332300000013],[-81.85305799999998,79.69358800000003],[-81.79943800000001,79.68664599999994],[-81.76750199999992,79.68498199999993],[-81.73388699999992,79.68637100000012],[-81.68472300000002,79.67581200000006],[-81.6163939999999,79.62330599999996],[-81.61860699999994,79.61831699999999],[-81.62805200000003,79.61470000000003],[-81.6516719999999,79.61026000000004],[-81.67805499999997,79.60720800000013],[-81.68777499999987,79.6080320000001],[-81.69471699999997,79.60971100000006],[-81.70973200000003,79.61554000000012],[-81.73416099999997,79.61970500000012],[-81.74861099999998,79.62109400000008],[-81.76750199999992,79.62052900000009],[-81.777222,79.61914099999996],[-81.78527799999989,79.61499000000009],[-81.78611799999993,79.60914600000007],[-81.78222700000003,79.60497999999995],[-81.76861600000001,79.60026600000003],[-81.75029,79.59471100000013],[-81.72833300000002,79.58970600000009],[-81.70666499999999,79.58665500000006],[-81.67527799999999,79.58499100000006],[-81.63945000000001,79.58499100000006],[-81.60583500000001,79.588593],[-81.57861300000002,79.59304800000001],[-81.56361400000003,79.59776300000004],[-81.54499800000002,79.60914600000007],[-81.50944499999991,79.624146],[-81.49527,79.62942500000003],[-81.47639500000002,79.63415500000002],[-81.45722999999998,79.63693200000012],[-81.424713,79.63665800000001],[-81.36805699999996,79.63443000000007],[-81.27999899999992,79.628311],[-81.25361599999997,79.62469499999997],[-81.01306199999988,79.59887700000002],[-80.69027699999998,79.56860400000005],[-80.63055400000002,79.56414799999999],[-80.598053,79.5660860000001],[-80.589722,79.56805400000002],[-80.591949,79.57360800000004],[-80.60861199999988,79.576096],[-80.62527499999993,79.58082600000006],[-80.641953,79.58804299999997],[-80.63417099999998,79.592758],[-80.61860699999988,79.59721400000012],[-80.598053,79.60137900000012],[-80.56916799999988,79.605255],[-80.50167799999997,79.61192299999999],[-80.100281,79.64444000000015],[-80.05665599999998,79.64694200000002],[-80.02528399999994,79.64721700000007],[-79.972778,79.64444000000015],[-79.93638599999997,79.64444000000015],[-79.90472399999999,79.64694200000002],[-79.89250199999992,79.64915500000001],[-79.76194799999996,79.69581600000004],[-79.75140399999992,79.70138500000002],[-79.76861600000001,79.70193500000005],[-80.041382,79.6974790000001],[-80.35665899999998,79.68525699999998],[-80.389725,79.68331900000004],[-80.43222000000003,79.67776500000002],[-80.47361799999999,79.66970800000007],[-80.51611300000002,79.6644290000001],[-80.61805700000002,79.65416000000005],[-80.65888999999993,79.65248100000002],[-80.79527300000001,79.64804100000003],[-80.82749899999999,79.64833100000004],[-80.910553,79.6519320000001],[-80.94221500000003,79.653595],[-80.95527599999997,79.65860000000004],[-80.95889299999993,79.66499300000004],[-80.97083999999995,79.67137099999997],[-80.97833300000002,79.67303499999997],[-81.07611099999997,79.688873],[-81.17193600000002,79.70332300000013],[-81.22778299999999,79.709427],[-81.29194599999988,79.71360800000008],[-81.385559,79.71360800000008],[-81.42443799999995,79.7127690000001],[-81.51972999999992,79.73082000000011],[-81.56945799999994,79.81971700000008],[-81.58277900000002,79.83692900000011],[-81.58778399999994,79.84166000000005],[-81.59973100000002,79.8519290000001],[-81.608337,79.85859700000003],[-81.63137799999998,79.872208],[-81.651947,79.88275099999998],[-81.65972899999997,79.88859600000006],[-81.66500899999994,79.89776599999993],[-81.66305499999999,79.90304600000002],[-81.64361600000001,79.90998800000011],[-81.54055799999992,79.9227600000001],[-81.51583900000003,79.92498800000004],[-81.41694599999994,79.92719999999997],[-81.402222,79.93248],[-81.40028399999994,79.93775899999997],[-81.42027299999995,79.94358799999998],[-81.55749500000002,79.96081500000003],[-81.589722,79.96249400000005],[-81.63945000000001,79.96220400000004],[-81.64334100000002,79.96220400000004],[-81.710556,79.96470600000009],[-81.74305699999996,79.96638500000012],[-81.83306899999997,79.97387700000002],[-82.00500499999998,79.993042],[-82.16833499999996,80.01361099999997],[-82.191101,80.0186000000001],[-82.28582799999998,80.04609700000009],[-82.34333799999996,80.06387300000006],[-82.35916099999992,80.06915300000009],[-82.61915599999998,80.15054299999997],[-82.94804399999998,80.24748199999999],[-83.12110899999999,80.29275500000006],[-83.16665599999993,80.301376],[-83.18693499999995,80.30664100000007],[-83.20140099999998,80.31330900000006],[-83.20388799999995,80.31805400000007],[-83.19665499999996,80.320831],[-83.16694599999994,80.32693499999999],[-83.13194299999998,80.33055100000007],[-82.94276400000001,80.3455350000001],[-82.85472099999998,80.35081500000001],[-82.78778099999994,80.35220300000009],[-82.70666499999999,80.35276799999997],[-82.57972699999988,80.3583220000001],[-82.27333099999993,80.37747200000007],[-82.03138699999994,80.39833100000004],[-81.987213,80.40026899999998],[-81.89917000000003,80.40165700000011],[-81.88221699999997,80.4019320000001],[-81.67388899999997,80.4060970000001],[-81.33444199999997,80.42053200000004],[-81.20472699999999,80.42720000000003],[-81.07972699999999,80.43609600000013],[-80.98611499999987,80.44358800000009],[-80.83500700000002,80.45277400000003],[-80.66000400000001,80.46081500000008],[-80.48111,80.4624940000001],[-80.412216,80.46054100000015],[-80.36776699999996,80.4622040000001],[-80.33612099999999,80.46581999999995],[-80.318893,80.47053499999998],[-80.30665599999992,80.47526600000009],[-80.29415899999987,80.48664900000011],[-80.297775,80.488876],[-80.31220999999994,80.4916530000001],[-80.34333800000002,80.49414100000007],[-80.35499600000003,80.49803199999997],[-80.35722399999992,80.50138900000007],[-80.22749299999992,80.51971399999996],[-80.19554099999993,80.52360500000003],[-80.15333599999997,80.52638200000013],[-80.11639400000001,80.52777100000014],[-80.05860899999993,80.52720600000009],[-79.94027699999992,80.52886999999993],[-79.558044,80.53637700000007],[-79.49055499999992,80.53970300000009],[-79.33999599999993,80.54998800000004],[-79.23277300000001,80.55331400000006],[-79.19055200000003,80.55386400000009],[-79.011124,80.55331400000006],[-78.81555199999991,80.55581700000005],[-78.59277299999997,80.56219500000003],[-78.46556099999998,80.56387300000011],[-78.34527600000001,80.56442300000015],[-78.09889199999992,80.56248500000004],[-78.06388900000002,80.56469700000008],[-78.03805499999993,80.56721500000003],[-78.01501499999995,80.58665500000001],[-78.01362599999999,80.59109500000005],[-78.01916499999999,80.59443699999997],[-78.03083800000002,80.59610000000009],[-78.08860800000002,80.59693900000008],[-78.35777300000001,80.60165400000011],[-78.74137899999994,80.60914600000001],[-78.851944,80.61248799999998],[-78.92527799999999,80.61665299999999],[-78.98110999999994,80.61608900000004],[-79.114441,80.61248799999998],[-79.25500499999998,80.60582],[-79.34722899999991,80.60108900000006],[-79.39222699999993,80.59971599999994],[-79.56527699999992,80.59610000000009],[-79.63417099999998,80.59553500000004],[-79.86332699999997,80.60304300000007],[-79.93443300000001,80.6060940000001],[-79.96055599999988,80.60803200000004],[-79.96028099999995,80.61470000000003],[-79.90722699999998,80.62387100000001],[-79.84777799999995,80.63192700000008],[-79.55943300000001,80.66998300000006],[-79.35360700000001,80.69664000000012],[-79.291946,80.70387299999999],[-79.17250100000001,80.71304300000003],[-78.99082900000002,80.72970600000008],[-78.80943299999996,80.74693300000013],[-78.62388599999997,80.76914999999997],[-78.58528099999995,80.77221700000007],[-78.50556899999998,80.77748100000008],[-78.23666400000002,80.79332],[-77.894455,80.81330900000012],[-77.80583200000001,80.818604],[-77.73306299999996,80.82554600000009],[-77.63917500000002,80.83027600000014],[-77.28778099999994,80.83526599999999],[-76.92639200000002,80.84193399999998],[-76.84500100000002,80.841095],[-76.729172,80.83804300000008],[-76.68138099999993,80.83859300000012],[-76.59083599999997,80.84275800000012],[-76.55665599999998,80.84637500000008],[-76.51167299999997,80.85443099999998],[-76.48472599999997,80.86554000000001],[-76.4850009999999,80.87109400000003],[-76.49082900000002,80.8749850000001],[-76.52667200000002,80.88638300000008],[-76.62110899999993,80.90081800000002],[-76.65666199999998,80.89804100000015],[-76.699432,80.89137299999999],[-76.73889200000002,80.88832100000002],[-76.79750099999995,80.88610800000009],[-76.84167500000001,80.88554399999998],[-77.16888399999993,80.88693200000006],[-77.20167500000002,80.8877720000001],[-77.30888400000003,80.89305100000007],[-77.42832900000002,80.90304600000002],[-77.45472699999999,80.90525800000006],[-77.5811159999999,80.91137700000007],[-77.76611300000002,80.90693700000008],[-77.98028599999992,80.90109300000006],[-78.421112,80.87942499999991],[-78.83639499999998,80.85386699999998],[-78.86944599999993,80.85220299999997],[-78.88528399999996,80.85359199999999],[-78.896118,80.85470599999996],[-78.908615,80.85887100000014],[-78.92222599999997,80.86608899999999],[-78.93499799999995,80.87553400000002],[-78.93638599999997,80.88136300000008],[-78.93055699999996,80.98193399999997],[-78.928604,80.99054000000007],[-78.839722,81.016098],[-78.79998799999998,81.02638200000007],[-78.7577819999999,81.03553799999997],[-78.63667299999997,81.05859400000003],[-78.52888499999995,81.08194000000009],[-78.50111399999997,81.09165999999999],[-78.45750399999997,81.10775800000005],[-78.42610199999996,81.12081899999998],[-78.41639699999996,81.12525900000014],[-78.39723199999992,81.13749700000005],[-78.39306599999992,81.14276100000001],[-78.40638699999994,81.14498899999995],[-78.46194500000001,81.14749100000006],[-78.47528099999994,81.149719],[-78.47582999999997,81.15248100000008],[-78.47277799999995,81.1583250000001],[-78.46362299999993,81.16081200000002],[-78.43859899999995,81.16470300000009],[-78.41139199999992,81.16747999999995],[-78.29083300000002,81.17469800000015],[-78.25473,81.17776500000008],[-78.2250059999999,81.18193099999996],[-78.15943900000002,81.19386299999996],[-78.05110200000001,81.2185970000001],[-78.03694200000001,81.22331200000013],[-78.016663,81.2327580000001],[-78.00917099999998,81.238586],[-77.97694399999989,81.24914599999994],[-77.87527499999987,81.2727660000001],[-77.85082999999992,81.27720599999998],[-77.612503,81.31887799999998],[-77.5769499999999,81.32249499999995],[-77.50306699999993,81.32832300000007],[-77.36639400000001,81.33610500000003],[-77.233612,81.35108900000012],[-77.11694299999994,81.367752],[-76.95527599999997,81.39387499999992],[-76.76501499999995,81.42858899999999],[-76.74861099999998,81.4327550000001],[-76.74526999999995,81.43914800000005],[-76.761124,81.4427490000001],[-76.77778599999988,81.44442700000002],[-76.80332899999996,81.44552600000003],[-76.85583500000001,81.44552600000003],[-76.95111099999997,81.44053600000012],[-77.02860999999996,81.43331900000004],[-77.20861799999994,81.40942400000006],[-77.26445000000001,81.40081800000013],[-77.41722099999987,81.380539],[-77.571396,81.36665299999999],[-77.60972600000002,81.36442599999992],[-77.8291779999999,81.34248400000007],[-77.89611799999994,81.33554100000009],[-78.17416399999996,81.30053700000002],[-78.22833300000002,81.29165600000005],[-78.27362099999993,81.28359999999998],[-78.29222099999987,81.27832000000012],[-78.30555700000002,81.2727660000001],[-78.32583599999992,81.26138300000014],[-78.351944,81.2502750000001],[-78.37027,81.2452550000001],[-78.41000400000001,81.23637400000013],[-78.43388399999992,81.23193400000014],[-78.487213,81.22303800000003],[-78.60499600000003,81.2063750000001],[-78.65249599999993,81.19720500000005],[-78.67527799999993,81.19192500000003],[-78.70195000000001,81.18165599999998],[-78.721115,81.17221100000006],[-78.72833300000002,81.16638200000006],[-78.75111400000003,81.14166300000011],[-78.75418100000002,81.13581800000003],[-78.74583399999995,81.12915000000004],[-78.71665999999999,81.12330600000001],[-78.69055200000003,81.12164300000012],[-78.69082599999996,81.11943100000002],[-78.81750499999993,81.10609399999998],[-78.89501999999993,81.09899900000005],[-78.916946,81.09803799999992],[-78.94137599999993,81.10108899999994],[-78.96362299999998,81.10775800000005],[-79.01501499999995,81.11553999999995],[-79.075287,81.12275700000009],[-79.16278099999994,81.13220199999995],[-79.21806299999997,81.136932],[-79.24276700000001,81.13998400000008],[-79.39917000000003,81.17469800000015],[-79.46362299999998,81.19331399999999],[-79.48611499999998,81.19497700000011],[-79.50167799999997,81.19358800000009],[-79.49943499999995,81.18997200000007],[-79.491669,81.18609599999996],[-79.47582999999997,81.180542],[-79.275284,81.12359600000002],[-79.21888699999994,81.11109900000008],[-79.17250100000001,81.10386699999998],[-79.08883700000001,81.09475700000007],[-79.073624,81.09082000000012],[-79.06361399999992,81.08554100000015],[-79.07278399999996,81.08082600000012],[-79.087784,81.07666],[-79.14222699999999,81.06915300000009],[-79.226944,81.06303400000007],[-79.25527999999991,81.05886800000013],[-79.30526699999996,81.02998400000001],[-79.31582600000002,81.02388000000013],[-79.32362399999994,81.018326],[-79.33666999999997,81.0086060000001],[-79.343887,80.99832200000003],[-79.33694500000001,80.99220300000002],[-79.32112099999989,80.98858600000005],[-79.29138199999989,80.984985],[-79.25834700000001,80.98442100000005],[-79.20527599999997,80.98776200000009],[-79.18472300000002,80.98637400000001],[-79.16471899999999,80.98304700000006],[-79.15888999999999,80.97776800000008],[-79.15834000000001,80.97276300000004],[-79.16528299999993,80.9666600000001],[-79.265289,80.92414900000006],[-79.60082999999992,80.82443200000012],[-79.61805699999996,80.81944299999998],[-79.883621,80.7833250000001],[-80.06555200000003,80.75972000000013],[-80.24749800000001,80.73692299999999],[-80.51112399999994,80.70582600000006],[-80.651947,80.69192500000008],[-80.720551,80.68414299999995],[-80.85555999999997,80.66331500000007],[-80.91944899999993,80.65554800000012],[-80.95666499999999,80.65193200000004],[-81.33639499999992,80.62330600000013],[-81.53332499999999,80.60720800000007],[-81.57556199999999,80.60415599999999],[-81.80888400000003,80.59304800000001],[-81.96611000000001,80.57971200000003],[-82.35388199999994,80.55636599999997],[-82.43499800000001,80.55304000000012],[-82.79888900000003,80.53942899999998],[-82.88110399999994,80.53665200000006],[-82.95639,80.53637700000007],[-83.02749599999993,80.53858900000012],[-83.09666400000003,80.54165600000005],[-83.1519469999999,80.54637100000008],[-83.165009,80.55192599999998],[-83.1702729999999,80.56414799999993],[-83.16805999999991,80.57666000000012],[-83.16528299999993,80.5894320000001],[-83.16139199999986,80.60108900000006],[-83.15611299999995,80.60664400000013],[-83.14666699999998,80.61219800000015],[-83.09695399999998,80.63943500000005],[-83.07806399999993,80.64498900000007],[-83.05638099999999,80.64915499999995],[-82.773056,80.68664600000011],[-82.52749599999999,80.70332300000013],[-82.43194599999998,80.70887800000003],[-82.25083899999993,80.71638500000012],[-82.21639999999996,80.71914700000002],[-82.13583399999987,80.72943100000009],[-82.02500900000001,80.74664300000006],[-81.94833399999993,80.75915500000008],[-81.90861499999994,80.76776100000001],[-81.76278699999989,80.81080600000013],[-81.758896,80.81303400000007],[-81.76750199999992,80.82138100000009],[-81.943604,80.83305400000012],[-81.96112099999993,80.83305400000012],[-81.99610899999993,80.83027600000014],[-82.05221599999993,80.822769],[-82.0997309999999,80.81359900000012],[-82.146118,80.80358900000004],[-82.19387799999998,80.79664600000007],[-82.33222999999998,80.78137200000015],[-82.51306199999993,80.76304600000014],[-82.52610799999997,80.7527770000001],[-82.53582799999987,80.74720800000011],[-82.54333499999996,80.74443100000002],[-82.56723,80.74081400000006],[-82.60166900000002,80.73803699999996],[-82.94055199999997,80.71443199999999],[-83.31193499999995,80.68775900000003],[-83.35694899999993,80.68553199999997],[-83.51611300000002,80.70138499999996],[-83.54110700000001,80.704163],[-83.54722600000002,80.70694000000009],[-83.569458,80.73915099999999],[-83.5625,80.74386600000003],[-83.52972399999999,80.74748200000005],[-83.45666499999999,80.75109900000001],[-83.42250099999995,80.7538760000001],[-83.39138799999995,80.7580410000001],[-83.26194799999996,80.78637700000002],[-83.13305700000001,80.8188780000001],[-83.12027,80.82331799999997],[-83.13249200000001,80.828598],[-83.158051,80.83360300000004],[-83.19110099999995,80.83581500000014],[-83.256958,80.83859300000012],[-83.29722599999997,80.83610499999998],[-83.32333399999993,80.8316650000001],[-83.32917799999996,80.82832300000001],[-83.33195499999994,80.82388300000014],[-83.353882,80.81359900000012],[-83.38137799999998,80.80386400000003],[-83.40722699999998,80.79942299999993],[-83.49333200000001,80.78776600000003],[-83.58721899999989,80.77526900000004],[-83.61054999999993,80.77165200000007],[-83.63082899999995,80.76693700000004],[-83.645554,80.76165800000007],[-83.64916999999997,80.75555400000002],[-83.65888999999987,80.751938],[-83.6677699999999,80.75],[-83.69665500000002,80.74664300000006],[-83.712784,80.74775700000009],[-83.82749899999993,80.76138300000002],[-83.85916099999997,80.75915500000008],[-83.86389200000002,80.75749200000013],[-83.83639499999998,80.71971099999996],[-83.82167099999998,80.70582600000006],[-83.81249999999994,80.69831800000009],[-83.80139199999996,80.69192500000008],[-83.78306599999996,80.68414299999995],[-83.75723299999993,80.66970800000001],[-83.73443600000002,80.65416000000005],[-83.72332799999992,80.6438750000001],[-83.72000099999991,80.63665800000001],[-83.71972699999998,80.63081399999999],[-83.73582499999992,80.61303700000008],[-83.77917500000001,80.57083100000011],[-83.79472399999997,80.56025700000004],[-83.82112099999995,80.55053699999996],[-83.84056099999987,80.5455320000001],[-83.87110899999993,80.5413670000001],[-83.93472300000002,80.53442400000012],[-83.97332799999998,80.53193700000003],[-84.31332399999991,80.51361100000003],[-84.381104,80.51220700000005],[-84.48971599999993,80.51443499999999],[-84.55139200000002,80.51776100000006],[-84.689438,80.52499400000005],[-84.76362599999999,80.52581800000002],[-84.84666400000003,80.52331500000003],[-84.89056399999998,80.52110299999998],[-84.964447,80.51443499999999],[-85.027222,80.50721700000003],[-85.066956,80.50526400000007],[-85.23277299999995,80.50888100000003],[-85.33473199999997,80.51361100000003],[-85.36665299999999,80.51748700000013],[-85.42582699999997,80.52304100000009],[-85.46221899999995,80.52499400000005],[-85.59472700000003,80.52915999999993],[-85.80943300000001,80.53193700000003],[-85.8641659999999,80.53553800000009],[-85.86582900000002,80.5413670000001],[-85.81277499999993,80.55914300000006],[-85.70584100000002,80.58970600000004],[-85.68916299999995,80.59387200000015],[-85.66500899999994,80.59860199999997],[-85.61305199999998,80.60636899999997],[-85.57194500000003,80.61526500000008],[-85.56471299999993,80.61943100000013],[-85.59445199999993,80.6202550000001],[-85.63639799999999,80.61914100000013],[-85.69471699999997,80.61360200000013],[-85.74471999999992,80.60636899999997],[-85.79305999999985,80.59693900000008],[-85.85472099999998,80.58221400000014],[-85.889725,80.57304400000004],[-85.92527799999999,80.56248500000004],[-85.95060699999999,80.55294799999996],[-85.95666499999993,80.54832500000009],[-85.98277300000001,80.53749100000005],[-86.01194799999996,80.53332499999993],[-86.03721599999994,80.53082300000005],[-86.08084099999996,80.52832000000006],[-86.14834599999995,80.53166200000004],[-86.17749000000003,80.53414900000013],[-86.42832900000002,80.56025700000004],[-86.63999899999993,80.583054],[-86.71806299999997,80.59304800000001],[-86.7391659999999,80.597488],[-86.74499500000002,80.60304300000007],[-86.73249800000002,80.61526500000008],[-86.68028299999997,80.65498400000001],[-86.66000399999996,80.66609199999999],[-86.63806199999999,80.67665100000005],[-86.51472499999994,80.72943100000009],[-86.49777199999994,80.7352600000001],[-86.46611000000001,80.74552900000009],[-86.41000400000001,80.76081800000003],[-86.33833300000003,80.77554299999997],[-86.24471999999997,80.79414400000013],[-86.22555499999993,80.799149],[-86.17443800000001,80.81442300000009],[-86.05027799999999,80.85664400000007],[-85.96417199999996,80.88693200000006],[-85.846115,80.9285890000001],[-85.82833900000003,80.93414300000012],[-85.77416999999997,80.94886800000006],[-85.69860799999992,80.96276900000004],[-85.60583500000001,80.97581500000013],[-85.556107,80.98193399999997],[-85.00306699999987,81.02832000000001],[-84.928879,81.03082299999994],[-84.72666900000002,81.0310970000001],[-84.40499899999992,81.04386900000009],[-84.36833200000001,81.04609700000003],[-84.20666499999993,81.06053199999997],[-84.1199949999999,81.06749000000013],[-84.02500900000001,81.070831],[-83.90805099999994,81.07138100000003],[-83.82362399999994,81.07360800000009],[-83.52999899999992,81.09027100000014],[-83.31138599999997,81.10331700000012],[-83.15055799999999,81.12052900000015],[-83.12332200000003,81.12303200000008],[-83.05332899999996,81.12330600000001],[-82.943604,81.12081899999998],[-82.86944599999993,81.12136800000007],[-82.82640100000003,81.12303200000008],[-82.78500400000001,81.12553400000002],[-82.76028399999996,81.12915000000004],[-82.73889199999996,81.13388099999997],[-82.70722999999998,81.14444000000003],[-82.68832399999997,81.1483310000001],[-82.64416499999993,81.15165700000011],[-82.59916699999997,81.15277100000009],[-82.53138699999994,81.14999399999999],[-82.50306699999993,81.14776600000005],[-82.46665999999993,81.1483310000001],[-82.37222300000002,81.17469800000015],[-82.364441,81.17942800000003],[-82.38999899999999,81.18026699999996],[-82.420837,81.17942800000003],[-82.48416099999997,81.16998300000012],[-82.52305599999994,81.16638200000006],[-82.56527699999992,81.16609200000005],[-82.665009,81.17442299999999],[-82.82806399999998,81.17330899999996],[-82.86665299999993,81.16970800000013],[-82.89416499999999,81.16526800000008],[-82.926941,81.16110200000003],[-82.96278399999994,81.1583250000001],[-83.14973399999991,81.15138200000013],[-83.45333899999997,81.13220199999995],[-83.75750700000003,81.11331200000001],[-84.116104,81.0977630000001],[-84.37277199999994,81.09220900000008],[-84.58555599999994,81.08638000000008],[-84.79750099999995,81.07832300000013],[-85.06555199999991,81.06637599999999],[-85.2119449999999,81.05693100000008],[-85.25,81.05525200000011],[-85.291382,81.05470300000013],[-85.40444899999994,81.05775500000004],[-85.48277300000001,81.05859400000003],[-85.57250999999997,81.05664100000007],[-85.68167099999994,81.0494230000001],[-85.75556899999998,81.04136700000004],[-85.81777999999997,81.03276100000011],[-85.98860200000001,81.00665300000014],[-86.14334099999991,80.97831700000006],[-86.30972300000002,80.94081100000005],[-86.351944,80.93054200000006],[-87.061935,80.72747800000013],[-87.07640100000003,80.7227630000001],[-87.083618,80.7169340000001],[-87.07907899999998,80.7070240000001],[-87.08029199999999,80.69914200000005],[-87.12138399999992,80.67747500000002],[-87.18055700000002,80.64915499999995],[-87.21501199999994,80.63832100000008],[-87.24055499999997,80.63415500000002],[-87.273056,80.63081399999999],[-87.31500199999994,80.62942499999997],[-87.458054,80.62776200000008],[-87.48971599999987,80.62747200000001],[-87.55943300000001,80.62747200000001],[-87.59472699999998,80.62858600000004],[-87.62805199999997,80.63220200000006],[-87.77722199999994,80.64888000000013],[-87.86416600000001,80.659424],[-87.95472699999988,80.67164599999995],[-88.139725,80.68525699999992],[-88.17721599999993,80.68692000000004],[-88.19610599999999,80.688583],[-88.22222899999997,80.69108599999998],[-88.34889199999992,80.70860299999998],[-88.40666199999993,80.7169340000001],[-88.48860199999996,80.73193400000002],[-88.566956,80.74859600000002],[-88.70611600000001,80.77276600000005],[-88.96749899999986,80.80859400000008],[-89.03416399999998,80.81637600000005],[-89.12582399999997,80.82582100000008],[-89.29055799999998,80.84942600000011],[-89.33473199999992,80.85748300000006],[-89.38249200000001,80.86970500000001],[-89.398056,80.876083],[-89.45056199999993,80.90332000000012],[-89.46221899999995,80.90998800000006],[-89.46611000000001,80.914154],[-89.46221899999995,80.91914400000002],[-89.4427639999999,80.92359900000002],[-89.38082899999989,80.93304400000011],[-89.23527499999994,80.94831800000003],[-89.18638599999997,80.95304899999996],[-88.90556300000003,80.97776800000008],[-88.858612,80.98136899999997],[-88.766861,80.98680100000001],[-88.59028599999999,80.99636800000002],[-88.51390100000003,80.99832200000003],[-88.28332499999999,81.0022130000001],[-88.08972199999994,81.003601],[-88.01139799999999,81.00332600000002],[-87.82667499999997,80.99803200000002],[-87.75500499999998,80.99498000000011],[-87.68943799999994,80.990814],[-87.62805199999997,80.98471100000006],[-87.59750400000001,80.98082],[-87.52416999999991,80.97720300000003],[-87.44638099999997,80.97692899999993],[-87.27944899999994,80.98193399999997],[-87.15943900000002,80.98692299999993],[-87.11971999999997,80.98970000000003],[-87.08917200000002,80.99414100000013],[-87.06471299999998,80.99887100000001],[-87.03056299999997,81.00193800000011],[-86.9830629999999,81.00387600000005],[-86.94610599999999,81.00416600000005],[-86.75500499999998,81.00109900000012],[-86.71167000000003,81.00248700000003],[-86.67193600000002,81.00526400000012],[-86.635559,81.00943000000007],[-86.541946,81.02026400000011],[-86.41944899999999,81.03610200000014],[-86.06111099999998,81.08276400000005],[-85.91639699999996,81.10498000000001],[-85.91639699999996,81.1102600000001],[-85.90722700000003,81.11387599999995],[-85.88751200000002,81.11886600000003],[-85.56277499999999,81.17942800000003],[-85.48306300000002,81.19274899999999],[-85.42527799999993,81.20166000000006],[-85.29750099999995,81.2185970000001],[-85.22193900000002,81.22637900000007],[-85.02027899999996,81.24498000000006],[-84.97639499999997,81.24859600000013],[-84.87638899999996,81.25471500000015],[-84.83250399999997,81.258331],[-84.80249000000003,81.26165800000012],[-84.77610800000002,81.26609799999994],[-84.73388699999998,81.28109700000005],[-84.73554999999999,81.28553799999997],[-84.745834,81.28942900000004],[-84.89999399999994,81.30497700000001],[-84.93666099999996,81.30775500000004],[-84.97555499999999,81.30748],[-85.02917500000001,81.30581700000005],[-85.27917499999995,81.28997800000013],[-85.36138899999997,81.28276100000005],[-85.76834099999996,81.24470500000007],[-85.95056199999999,81.2247010000001],[-86.01834100000002,81.21582000000001],[-86.07749899999993,81.20748900000007],[-86.15417499999995,81.19331399999999],[-86.22500600000001,81.17387400000001],[-86.24082900000002,81.16914399999996],[-86.25695799999994,81.16276600000003],[-86.2994379999999,81.14860500000003],[-86.33833300000003,81.138596],[-86.40499899999998,81.12970000000007],[-86.43804899999992,81.12608300000011],[-86.47277799999989,81.12275700000009],[-86.521118,81.11970499999995],[-86.65083300000003,81.11581400000011],[-86.95639,81.09942600000005],[-87.11138899999992,81.0877690000001],[-87.29722599999997,81.07693500000005],[-87.63751200000002,81.059418],[-87.678879,81.05859400000003],[-87.72000099999991,81.059418],[-87.841385,81.06275900000003],[-88.0625,81.06999200000001],[-88.21777299999985,81.07138100000003],[-88.33999599999999,81.06971700000003],[-88.43499799999995,81.06414800000005],[-88.57167099999992,81.05470300000013],[-88.65834000000001,81.051376],[-88.74082899999996,81.04971300000011],[-88.88999899999993,81.05192600000004],[-88.96472199999994,81.0494230000001],[-89.041672,81.04109199999999],[-89.210556,81.02665700000006],[-89.25556899999998,81.02388000000013],[-89.34167500000001,81.02026400000011],[-89.629166,81.00915500000002],[-89.74665800000002,81.00888100000009],[-89.78750599999995,81.00972000000007],[-89.82084700000001,81.01081799999997],[-89.87388599999997,81.016388],[-90.01194799999996,81.03305100000011],[-90.06361400000003,81.03970299999997],[-90.0952759999999,81.04470800000007],[-90.14917000000003,81.05497700000006],[-90.19776899999988,81.06971700000003],[-90.21000700000002,81.07499700000011],[-90.33805799999993,81.15165700000011],[-90.351944,81.16747999999995],[-90.32556199999993,81.18193099999996],[-90.277222,81.19720500000005],[-90.10221899999999,81.23027000000013],[-90.04305999999997,81.23942600000004],[-90.011124,81.24192800000014],[-89.972778,81.24275200000011],[-89.87054399999994,81.24220300000013],[-89.74610899999999,81.236649],[-89.66915899999987,81.21804800000012],[-89.63500999999991,81.21220399999993],[-89.573059,81.20694000000015],[-89.53500400000001,81.2061000000001],[-89.491104,81.2063750000001],[-89.4472199999999,81.20832800000005],[-89.35722399999997,81.2144320000001],[-89.281387,81.22164900000001],[-89.13667299999997,81.238876],[-89.08833300000003,81.24247700000006],[-89.04444899999999,81.24275200000011],[-88.98222399999997,81.24192800000014],[-88.95417800000001,81.24275200000011],[-88.94415299999997,81.24414100000007],[-88.93582199999997,81.24775699999998],[-88.9497219999999,81.253601],[-88.979446,81.258331],[-89.16221599999994,81.25582900000012],[-89.19860799999987,81.25332600000013],[-89.26501499999995,81.24443100000013],[-89.30722000000003,81.24054000000007],[-89.33528099999995,81.24275200000011],[-89.44360399999994,81.26054399999998],[-89.68777499999999,81.28997800000013],[-89.77500899999995,81.29637100000008],[-89.86805699999996,81.30609099999998],[-89.89862099999993,81.31053199999991],[-89.91722099999987,81.31442299999998],[-89.950287,81.32415800000007],[-89.95249899999988,81.32943700000004],[-89.94055200000003,81.33332800000011],[-89.9163969999999,81.336929],[-89.88221699999997,81.34027100000009],[-89.702225,81.35026600000003],[-89.62721299999998,81.35664400000002],[-89.24249299999997,81.42303500000003],[-89.05915800000002,81.45555100000007],[-88.92832899999996,81.48553500000014],[-88.90943900000002,81.49081400000011],[-88.84695399999998,81.49971000000005],[-88.71583599999997,81.51304599999997],[-88.54527299999995,81.52526900000004],[-88.49499500000002,81.52720600000009],[-88.406113,81.52832000000006],[-88.37110899999999,81.52693199999999],[-88.16139199999992,81.53027300000002],[-88.02999899999998,81.53581200000002],[-87.98416099999997,81.53581200000002],[-87.95973200000003,81.53471400000012],[-87.939438,81.53166199999998],[-87.89369999999997,81.52471200000014],[-87.80139199999996,81.51554899999996],[-87.67944299999994,81.51388500000013],[-87.49027999999998,81.50888099999997],[-87.43138099999993,81.50471500000009],[-87.39889499999998,81.50082400000002],[-87.34306300000003,81.49275200000005],[-87.31111099999998,81.488876],[-87.27667200000002,81.48580900000007],[-87.25140399999992,81.48748800000004],[-87.24471999999997,81.49026500000014],[-87.28639199999992,81.50555400000007],[-87.28832999999997,81.50610400000011],[-87.31555199999997,81.51332100000002],[-87.37860099999989,81.51721200000009],[-87.48916600000001,81.52331500000003],[-87.64584400000001,81.52748099999991],[-87.72166400000003,81.53221100000013],[-87.75195299999996,81.53526300000004],[-87.91500899999994,81.55276500000008],[-88.279449,81.57943699999998],[-88.30638099999993,81.58137499999992],[-88.35221899999999,81.57971200000003],[-88.39222699999999,81.57777400000009],[-88.44694499999997,81.57222000000007],[-88.55221599999999,81.55886800000002],[-88.64222699999993,81.5516510000001],[-88.66944899999999,81.55053700000013],[-88.76916499999999,81.55108600000011],[-88.84999099999999,81.55053700000013],[-88.90028399999989,81.54832500000009],[-88.99804699999999,81.54054300000013],[-89.07305899999994,81.53221100000013],[-89.14584400000001,81.52304100000009],[-89.28250099999991,81.50526400000001],[-89.54833999999988,81.47720300000015],[-89.585556,81.47303799999997],[-89.71028099999995,81.45526100000006],[-90.01139799999993,81.41693099999998],[-90.37083399999995,81.37525900000009],[-90.44305399999996,81.36665299999999],[-90.46749899999992,81.367752],[-90.50056499999994,81.37136800000002],[-90.53582799999998,81.37692300000009],[-90.55332900000002,81.38499500000006],[-90.525284,81.38859600000012],[-90.51722699999993,81.38916000000006],[-90.478882,81.39444000000015],[-90.48138399999999,81.39665200000002],[-90.48777799999993,81.39860499999998],[-90.516953,81.40248100000002],[-90.64361600000001,81.416382],[-90.67832899999996,81.41748000000013],[-90.74665800000002,81.42221100000006],[-90.77999899999998,81.42553700000008],[-90.81138599999991,81.42997700000006],[-90.84111000000001,81.43553199999997],[-90.85417199999995,81.44053600000012],[-90.85665899999992,81.44413800000007],[-90.85388199999994,81.45082100000008],[-90.84834299999994,81.45498700000013],[-90.80082699999997,81.46499599999999],[-90.770554,81.46971100000002],[-90.58306900000002,81.4974820000001],[-90.54028299999999,81.50166300000001],[-90.31221,81.53137199999998],[-90.1305539999999,81.56442300000015],[-89.87470999999994,81.599152],[-89.79750099999995,81.60247800000002],[-89.67443800000001,81.60165400000005],[-89.63249200000001,81.60470600000002],[-89.59750399999996,81.61415100000005],[-89.58500699999996,81.61970500000007],[-89.58500699999996,81.62580900000006],[-89.60194399999989,81.62776200000002],[-89.79888900000003,81.62997400000006],[-89.86805699999996,81.63026400000012],[-89.91416900000002,81.628311],[-89.96221899999995,81.62553400000007],[-90.06945799999994,81.63360600000004],[-90.11158,81.65674600000011],[-90.20472699999993,81.68637100000007],[-90.27139299999999,81.6974790000001],[-90.29695099999998,81.69859300000007],[-90.33029199999999,81.69609099999997],[-90.35305799999998,81.69053600000007],[-90.36082499999992,81.68525700000009],[-90.35527000000002,81.67359900000008],[-90.33721899999995,81.6624910000001],[-90.35472099999998,81.65138200000001],[-90.511124,81.65776100000005],[-90.60472099999993,81.66470300000015],[-90.63890100000003,81.66804500000006],[-90.678879,81.66886900000003],[-90.71888699999994,81.6666560000001],[-90.73472599999997,81.66081200000008],[-90.74221799999998,81.65554800000007],[-90.76362599999993,81.64553799999999],[-90.77972399999999,81.641098],[-90.803879,81.63610800000009],[-90.83473199999997,81.63136300000008],[-90.87805200000003,81.62747200000001],[-90.92388899999997,81.62525900000003],[-90.96694899999994,81.62109400000003],[-90.99110399999995,81.61608899999999],[-91.006958,81.59887699999996],[-91.00334199999992,81.59220900000003],[-90.98860200000001,81.57943699999998],[-90.98860200000001,81.55775499999999],[-91.07167099999998,81.53720099999998],[-91.091949,81.53387499999997],[-91.104446,81.53442400000012],[-91.11389199999996,81.53997800000008],[-91.23693800000001,81.54332000000005],[-91.31388899999996,81.53414900000007],[-91.40139799999997,81.52638200000013],[-91.44638099999997,81.524429],[-91.46333299999998,81.526093],[-91.46777299999991,81.52720600000009],[-91.45249899999993,81.53166199999998],[-91.428604,81.53665200000006],[-91.41111799999999,81.54193100000003],[-91.40638699999994,81.54776000000004],[-91.44415300000003,81.5836030000001],[-91.47444199999995,81.58888200000007],[-91.65417500000001,81.60582],[-91.74722300000002,81.60914600000001],[-91.85722399999986,81.61276200000009],[-91.87832600000002,81.61415100000005],[-91.900284,81.61692800000014],[-91.93859900000001,81.62553400000007],[-91.94860799999992,81.63108800000009],[-91.95666499999999,81.65860000000004],[-91.949432,81.6622010000001],[-91.926941,81.66499299999998],[-91.90222199999994,81.66693100000009],[-91.86776700000001,81.66331500000007],[-91.83889799999986,81.65860000000004],[-91.80110199999996,81.65860000000004],[-91.77084400000001,81.66331500000007],[-91.73721299999994,81.68692000000004],[-91.72582999999992,81.70665000000002],[-91.72361799999987,81.72164900000007],[-91.48554999999999,81.76998900000012],[-91.386124,81.77388000000002],[-91.35139500000002,81.77026400000011],[-91.28750600000001,81.76193199999994],[-91.25500499999998,81.75915500000008],[-91.2125089999999,81.75943000000007],[-91.0533289999999,81.76165800000001],[-91.03443900000002,81.76388500000007],[-91.03332499999999,81.76776099999995],[-91.05749499999996,81.77276600000005],[-91.09056099999992,81.77720600000004],[-91.11776699999996,81.78442400000006],[-91.14056399999998,81.79193099999998],[-91.15249599999993,81.79803500000003],[-91.14723200000003,81.80386400000003],[-91.13751199999996,81.80859400000008],[-91.10110499999996,81.8188780000001],[-91.05166599999995,81.82887299999999],[-91.00111399999997,81.83276400000005],[-90.85221899999999,81.84248399999996],[-90.72749299999998,81.841095],[-90.70417800000001,81.84359700000005],[-90.68998699999992,81.84860200000008],[-90.68637799999999,81.85396600000001],[-90.67832899999996,81.85859700000003],[-90.63500999999997,81.86886600000003],[-90.61000100000001,81.87387100000007],[-90.56527699999987,81.87803600000007],[-90.43666100000002,81.88749700000005],[-90.33805799999993,81.89305100000007],[-90.24527,81.89610299999998],[-90.154449,81.89665200000013],[-89.99082899999996,81.90554800000007],[-89.78332499999993,81.91720600000008],[-89.73582499999998,81.91748000000001],[-89.70083599999998,81.91554300000013],[-89.676941,81.9102630000001],[-89.68305199999998,81.89943700000015],[-89.6824949999999,81.883331],[-89.64944500000001,81.86331200000006],[-89.62998999999996,81.85636900000003],[-89.46139499999998,81.81805400000013],[-89.425003,81.81526200000002],[-89.35638399999993,81.81109600000013],[-89.24472000000003,81.84637500000002],[-89.22721899999999,81.85220300000015],[-89.20322399999998,81.87803600000007],[-89.19923399999999,81.88153799999992],[-89.19905900000003,81.88520800000003],[-89.21321899999998,81.88838200000009],[-89.32806399999993,81.90220600000009],[-89.36721799999992,81.90554800000007],[-89.39750699999996,81.90942400000012],[-89.41915899999998,81.91554300000013],[-89.41694599999994,81.92581200000001],[-89.3977809999999,81.93081700000005],[-89.37165800000002,81.93580600000001],[-89.33889799999997,81.94026200000008],[-89.28889500000002,81.943039],[-89.24972499999996,81.94108600000004],[-89.15739399999995,81.92836800000009],[-89.15621899999991,81.92520100000007],[-89.15255699999994,81.92137100000008],[-89.13305700000001,81.91853300000008],[-89.07472199999995,81.91165200000006],[-89.03332499999999,81.91220100000004],[-89.00723299999987,81.91554300000013],[-88.98971599999993,81.92109700000015],[-88.98638899999997,81.94497699999994],[-88.99276700000001,81.95138500000007],[-89.0119479999999,81.9586030000001],[-89.04834,81.97804300000007],[-89.05444299999999,81.98748799999998],[-89.04110699999995,81.99304199999995],[-89.02111799999994,81.99803200000002],[-88.96389799999997,82.00804100000005],[-88.77305599999994,82.03942900000004],[-88.62554899999998,82.06275900000003],[-88.58972199999994,82.066666],[-88.54305999999991,82.07054099999999],[-88.44305400000002,82.07499700000005],[-88.29666099999992,82.08027600000003],[-88.25,82.08082600000006],[-88.14500399999997,82.086929],[-88.11361699999992,82.09054599999996],[-88.09973100000002,82.09304800000007],[-88.09500100000002,82.09637499999997],[-88.08528100000001,82.10137900000012],[-88.07556199999993,82.10498000000001],[-88.03832999999997,82.1038670000001],[-87.91194200000001,82.09082000000006],[-87.71833799999996,82.08387800000003],[-87.70222499999994,82.086929],[-87.6663969999999,82.08943199999999],[-87.64195299999994,82.09027100000014],[-87.59973099999996,82.089157],[-87.50140399999998,82.08415200000013],[-87.40222199999994,82.07388300000008],[-87.35278299999993,82.06721500000009],[-87.33361799999989,82.06330900000006],[-87.27166699999998,82.04775999999993],[-87.23055999999997,82.03692600000005],[-87.195831,82.02638200000001],[-87.18360899999993,82.02249100000012],[-87.1744379999999,82.01470899999998],[-87.17332499999998,82.01110799999992],[-87.1786039999999,82.00776700000011],[-87.19776899999994,82.0022130000001],[-87.23277300000001,81.99331699999999],[-87.25805700000001,81.9894260000001],[-87.29998799999998,81.97915599999999],[-87.314438,81.97387700000002],[-87.30943299999996,81.96748400000001],[-87.26583900000003,81.95887800000014],[-87.16915899999998,81.94552600000009],[-87.10166900000002,81.93775900000014],[-87.06332399999991,81.93441800000011],[-86.939438,81.91886899999997],[-86.87721299999998,81.90942400000012],[-86.82888799999995,81.89749100000006],[-86.804169,81.89305100000007],[-86.76834100000002,81.89027399999998],[-86.72666900000002,81.8919370000001],[-86.726944,81.89721700000013],[-86.73416099999992,81.90277100000014],[-86.74583399999995,81.90664700000002],[-86.83473200000003,81.92776500000014],[-86.86361699999992,81.93359399999997],[-86.91944899999999,81.94274899999999],[-87.066101,81.95498700000007],[-87.09805299999994,81.95832800000011],[-87.12721299999993,81.96388200000007],[-87.13027999999986,81.968323],[-87.00140399999998,82.03610200000008],[-86.987213,82.03997800000002],[-86.93167099999994,82.04942300000005],[-86.89250199999998,82.0541530000001],[-86.84333799999996,82.05720500000001],[-86.79194599999994,82.05802900000015],[-86.58361799999994,82.05386399999998],[-86.35638399999999,82.05358899999999],[-86.27806099999998,82.05081200000006],[-86.23916600000001,82.04859900000008],[-86.202789,82.04553199999998],[-86.16915899999992,82.0416560000001],[-86.01611299999996,82.01666300000005],[-85.960556,82.00749200000007],[-85.91444399999995,81.99748199999999],[-85.81500199999999,81.97387700000002],[-85.76750199999992,81.96192899999994],[-85.73138399999988,81.949997],[-85.62887599999999,81.9160920000001],[-85.46722399999999,81.86720300000013],[-85.42250100000001,81.85748300000006],[-85.37943999999999,81.85693400000008],[-85.37165800000002,81.859711],[-85.37388599999997,81.863876],[-85.38583399999993,81.8749850000001],[-85.398056,81.88108800000003],[-85.44193999999999,81.89387500000004],[-85.46945199999988,81.899719],[-85.566101,81.92498800000004],[-85.65472399999999,81.95082100000013],[-85.73194899999999,81.98332200000004],[-85.72999600000003,81.98776200000009],[-85.72694399999995,81.99026500000008],[-85.69387799999998,81.99498000000011],[-85.65055799999993,81.99832200000003],[-85.55943299999996,82.00166300000006],[-85.258621,81.99693300000001],[-85.21749899999998,81.99552900000003],[-85.18832399999991,81.99275200000011],[-85.16583300000002,81.98525999999998],[-85.16000400000001,81.97970600000002],[-85.14056399999993,81.96609500000005],[-85.09638999999999,81.9458160000001],[-85.01889,81.91943400000002],[-84.98416099999992,81.91110200000003],[-84.87943999999999,81.88749700000005],[-84.83889799999992,81.882477],[-84.81688700000001,81.88536799999991],[-84.82188400000001,81.88821400000006],[-84.84422299999989,81.89488200000005],[-84.86389199999996,81.90026900000004],[-84.915009,81.918045],[-84.99471999999997,81.94859300000002],[-85.02528399999994,81.96081500000014],[-85.037216,81.96693399999998],[-85.04888900000003,81.97442600000011],[-85.06610099999995,81.98748799999998],[-85.05555699999996,81.990814],[-85.03832999999997,81.99414100000013],[-85.00111400000003,81.99414100000013],[-84.929169,81.99304199999995],[-84.88917499999997,81.99026500000008],[-84.85888699999992,81.98525999999998],[-84.83168,81.97943099999998],[-84.81666599999994,81.97082500000005],[-84.814438,81.96638500000006],[-84.81527699999992,81.96110499999998],[-84.82194500000003,81.94914199999994],[-84.79760699999997,81.93087000000014],[-84.78926799999999,81.92469800000003],[-84.75144199999994,81.91053800000009],[-84.74227899999994,81.90837899999997],[-84.68859899999995,81.8919370000001],[-84.656113,81.8877720000001],[-84.63528399999996,81.88610800000004],[-84.62193300000001,81.886932],[-84.60499600000003,81.88998400000014],[-84.714722,81.96998600000012],[-84.72972099999998,81.97720300000003],[-84.75167799999991,81.98471100000006],[-84.81527699999992,82.00082400000008],[-84.84083599999997,82.006104],[-84.89973399999991,82.01527400000003],[-84.93249499999996,82.01944000000009],[-85.03999299999998,82.028595],[-85.11694299999994,82.03305100000006],[-85.40583800000002,82.04220599999996],[-85.6783289999999,82.05442800000009],[-85.75584399999997,82.05886800000013],[-85.85166900000002,82.06721500000009],[-85.91583300000002,82.07748400000014],[-85.99972500000001,82.09414700000002],[-86.06220999999994,82.1038670000001],[-86.0911099999999,82.10443100000003],[-86.278885,82.10720800000013],[-86.48500100000001,82.11415099999994],[-86.56555199999997,82.11886599999997],[-86.63751199999996,82.12441999999999],[-86.70611600000001,82.13192700000013],[-86.73138399999993,82.13638300000002],[-86.752228,82.14109800000006],[-86.85665899999992,82.18470800000006],[-86.86915599999992,82.19525100000004],[-86.87609900000001,82.20220899999998],[-86.87193300000001,82.20776400000011],[-86.843613,82.2124940000001],[-86.76417499999997,82.22164900000001],[-86.66944899999993,82.22831699999995],[-86.61944599999998,82.22970599999996],[-86.57167099999998,82.23027000000008],[-86.52000399999991,82.22970599999996],[-86.316666,82.2247010000001],[-86.22888199999989,82.2247010000001],[-86.181107,82.22526600000015],[-86.137787,82.22692900000004],[-85.98443600000002,82.2374880000001],[-85.93415800000002,82.238876],[-85.84138499999995,82.23915100000005],[-85.79888900000003,82.23776200000003],[-85.75389099999995,82.2374880000001],[-85.70611599999995,82.23803700000002],[-85.66221599999994,82.23969999999997],[-85.61999499999996,82.24359100000004],[-85.603882,82.24914600000011],[-85.59889199999998,82.2544400000001],[-85.58056599999998,82.26443499999999],[-85.55777,82.26944000000009],[-85.50834700000001,82.27304100000009],[-85.41389500000002,82.27609300000006],[-85.37083399999995,82.27998400000013],[-85.35055499999993,82.28387500000002],[-85.34722899999997,82.28637700000007],[-85.36749299999991,82.2910920000001],[-85.39639299999999,82.29693600000013],[-85.45722999999998,82.30748],[-85.48167399999994,82.31359900000001],[-85.48999000000003,82.31971699999997],[-85.515015,82.343323],[-85.531677,82.36970500000007],[-85.50167799999997,82.3936000000001],[-85.50140399999992,82.39888000000013],[-85.515289,82.40332000000001],[-85.53416400000003,82.40748600000006],[-85.66944899999987,82.409424],[-85.86694299999999,82.421921],[-85.90499899999998,82.4249880000001],[-85.921112,82.42997700000006],[-85.91194199999995,82.43580600000007],[-85.81973299999993,82.4544370000001],[-85.79472399999997,82.45860299999998],[-85.74694799999997,82.46138000000008],[-85.70861799999994,82.46360800000002],[-85.50250199999999,82.47109999999998],[-85.29861499999993,82.47804299999996],[-85.04695099999998,82.48193400000002],[-85.00306699999987,82.48082000000005],[-84.69387799999993,82.47137500000002],[-84.662781,82.46859699999999],[-84.64167800000001,82.46554600000002],[-84.62222300000002,82.45915200000013],[-84.61639400000001,82.45359800000011],[-84.61332699999991,82.447205],[-84.61332699999991,82.4433140000001],[-84.63137799999998,82.44026200000002],[-84.787781,82.4349820000001],[-84.89527900000002,82.43359400000003],[-84.94055200000003,82.43193100000008],[-84.94387799999998,82.42581200000006],[-84.91665599999993,82.42053199999998],[-84.88861099999986,82.41693099999998],[-84.714722,82.40582299999994],[-84.5597229999999,82.39498900000007],[-84.48249800000002,82.3894350000001],[-84.449997,82.38610799999998],[-84.41833499999996,82.38108800000009],[-84.38806199999999,82.37109400000008],[-84.38417099999992,82.36608900000004],[-84.38722199999995,82.361649],[-84.37860099999995,82.35693399999997],[-84.34445199999999,82.35276800000008],[-84.30332900000002,82.35582],[-84.228882,82.36387600000006],[-84.18055699999996,82.368042],[-84.14695699999999,82.36970500000007],[-84.09555099999994,82.37109400000008],[-84.04722600000002,82.37136800000002],[-83.96139499999992,82.3685910000001],[-83.87693799999994,82.3641510000001],[-83.84194899999994,82.36137400000001],[-83.76750199999998,82.35304300000007],[-83.60638399999993,82.33137499999998],[-83.51640299999997,82.31694000000005],[-83.38473499999998,82.28221099999996],[-83.36860699999994,82.27638199999996],[-83.36000100000001,82.26944000000009],[-83.36000100000001,82.26361100000003],[-83.36915599999998,82.25166300000001],[-83.37193300000001,82.24470500000001],[-83.37193300000001,82.23915100000005],[-83.34445199999993,82.22720300000015],[-83.308334,82.21832300000011],[-83.24221799999998,82.20416300000005],[-83.18415799999997,82.19470200000006],[-83.13055399999996,82.18498199999999],[-83.08389299999993,82.17581200000012],[-83.02278100000001,82.15942400000006],[-83,82.151093],[-82.97666900000002,82.13832100000013],[-82.95306399999998,82.11998],[-82.95666499999993,82.10971100000012],[-82.95861799999994,82.10443100000003],[-82.96833800000002,82.09803800000009],[-82.97805800000003,82.09387200000003],[-83.00195300000001,82.089157],[-83.0625,82.08027600000003],[-83.12609899999995,82.072495],[-83.12805199999997,82.06721500000009],[-83.11193799999995,82.06526199999996],[-83.07640099999992,82.06192000000004],[-82.97416699999997,82.06498699999997],[-82.88833599999998,82.072495],[-82.79750100000001,82.07777399999998],[-82.75805700000001,82.07693499999999],[-82.67443800000001,82.07304399999992],[-82.63639799999999,82.07054099999999],[-82.42166099999997,82.0669400000001],[-82.28416399999998,82.06637599999999],[-82.199432,82.06414799999999],[-82.1222229999999,82.05859400000003],[-82.05555699999996,82.05081200000006],[-81.96362299999993,82.0372010000001],[-81.92610199999996,82.03471400000001],[-81.88999899999999,82.03498800000011],[-81.87805199999997,82.03637700000013],[-81.88473499999992,82.04109199999999],[-81.92416400000002,82.05886800000013],[-81.96611000000001,82.07110599999999],[-82.02084400000001,82.08221399999996],[-82.05860899999999,82.08471700000013],[-82.10249299999998,82.08554100000009],[-82.24305699999996,82.08499100000006],[-82.41749600000003,82.08720400000004],[-82.54638699999998,82.09027100000014],[-82.58444199999991,82.09275800000006],[-82.61971999999992,82.09609999999998],[-82.651947,82.10026600000003],[-82.67694099999994,82.10775799999999],[-82.68388400000003,82.11831700000005],[-82.68859900000001,82.12608300000011],[-82.697495,82.13136299999996],[-82.71722399999993,82.14276100000001],[-82.73138399999993,82.14999399999999],[-82.77223200000003,82.16331500000013],[-82.860275,82.18775900000009],[-82.88694799999996,82.19386299999991],[-82.94027699999998,82.203598],[-82.987503,82.21499599999999],[-83.01139799999999,82.22164900000001],[-83.02778599999988,82.23525999999998],[-83.02888499999995,82.26499899999999],[-83.02888499999995,82.276657],[-83.02555799999999,82.28332499999999],[-83.01916499999987,82.28887900000012],[-82.99082900000002,82.29248000000001],[-82.73554999999993,82.28610200000003],[-82.69360399999994,82.28471400000012],[-82.65444899999989,82.28221099999996],[-82.62165800000002,82.27804599999996],[-82.50889599999994,82.25804099999999],[-82.45278899999994,82.24942000000004],[-82.28666699999997,82.2291560000001],[-82.26306199999999,82.22221400000001],[-82.21112099999999,82.20471199999997],[-82.160278,82.19331399999999],[-82.10194399999995,82.18304400000005],[-82.011124,82.1685940000001],[-81.91805999999991,82.15498400000007],[-81.60888699999998,82.11859099999998],[-81.42527799999993,82.0977630000001],[-81.35305799999998,82.09165999999993],[-81.24916100000002,82.08137500000004],[-81.150284,82.06887800000004],[-81.09111000000001,82.059418],[-80.86833200000001,82.03137200000009],[-80.640289,82.01832600000012],[-80.43249499999996,81.99748199999999],[-80.22582999999997,81.98609899999997],[-80.15360999999996,81.98136899999992],[-80.0850069999999,81.97360200000014],[-80.03527799999995,81.96304299999991],[-79.88305699999995,81.92469800000003],[-79.6100009999999,81.851089],[-79.58972199999994,81.84414700000008],[-79.587784,81.83831800000007],[-79.57722499999994,81.82887299999999],[-79.56416300000001,81.82527199999993],[-79.53443900000002,81.82083100000006],[-79.49221799999992,81.81971700000003],[-79.24444599999993,81.81608599999998],[-79.22917199999995,81.81608599999998],[-79.452225,81.88998400000014],[-79.48998999999998,81.90026900000004],[-79.52111799999989,81.90554800000007],[-79.57972699999993,81.91360500000002],[-79.670837,81.92747500000007],[-79.84445199999993,81.97137499999991],[-79.83778399999994,82.00721700000008],[-79.83222999999987,82.01388500000002],[-79.85333300000002,82.0188750000001],[-79.880829,82.021927],[-79.91639700000002,82.02388000000013],[-80.21389799999986,82.03221100000002],[-80.33168,82.038589],[-80.368607,82.04109199999999],[-80.624435,82.06192000000004],[-80.65722699999992,82.06469700000014],[-80.72555499999999,82.07165500000013],[-80.79110700000001,82.0794370000001],[-80.82223499999992,82.08387800000003],[-80.87832600000002,82.09414700000002],[-80.92222600000002,82.1035920000001],[-80.94860799999998,82.1102600000001],[-80.962784,82.11637900000011],[-80.97555499999999,82.12359600000002],[-80.97555499999999,82.12776200000013],[-80.95666499999999,82.13720699999999],[-80.93138099999999,82.14221200000003],[-80.89973399999991,82.14637800000014],[-80.874435,82.151093],[-80.86805699999996,82.15498400000007],[-80.90916399999998,82.15664700000013],[-81.05139199999996,82.15470900000003],[-81.171112,82.15637200000015],[-81.25334199999992,82.15971400000006],[-81.32472200000001,82.16499300000004],[-81.42332499999998,82.1769260000001],[-81.79972800000002,82.22276299999999],[-81.82556199999993,82.22665400000005],[-81.88778699999995,82.23803700000002],[-82.170547,82.28665200000006],[-82.45472699999999,82.32804899999996],[-82.51306199999993,82.33776900000004],[-82.62554899999992,82.35914600000007],[-82.67999299999997,82.37081900000004],[-82.71167000000003,82.38247700000011],[-82.722778,82.38832100000008],[-82.7308349999999,82.39526400000011],[-82.73222399999997,82.40165700000006],[-82.72888199999994,82.40832500000005],[-82.71028100000001,82.41943400000008],[-82.69833399999999,82.4249880000001],[-82.539444,82.49720800000011],[-82.52055399999995,82.50248700000009],[-82.49833699999999,82.50637799999998],[-82.45889299999999,82.50833100000011],[-82.40638699999988,82.50915500000008],[-82.316956,82.50694300000004],[-82.09167500000001,82.50138900000002],[-81.66999799999991,82.49247700000001],[-81.541672,82.49609399999997],[-81.54222099999993,82.50499000000008],[-81.71333299999998,82.51527400000009],[-81.75140399999998,82.51693700000004],[-81.84722899999997,82.51554899999996],[-81.88055400000002,82.51776100000001],[-81.92748999999998,82.52276600000005],[-81.96640000000002,82.5288700000001],[-82.26390100000003,82.57666000000006],[-82.321121,82.58915700000006],[-82.34388699999994,82.59526100000011],[-82.390289,82.6119230000001],[-82.39472999999992,82.61747700000006],[-82.39222699999993,82.62275699999998],[-82.38110399999988,82.63472000000002],[-82.37193300000001,82.63970899999998],[-82.354446,82.64553799999999],[-82.33528100000001,82.65054300000003],[-82.28805499999999,82.65998800000011],[-82.25500499999993,82.66442899999998],[-82.21528599999999,82.66859399999998],[-82.15499899999992,82.67109700000015],[-82.060272,82.66970800000001],[-81.97222899999997,82.66638200000011],[-81.93138099999993,82.66387899999995],[-81.54333500000001,82.63720700000005],[-81.43249500000002,82.6291500000001],[-81.35972599999997,82.62081900000004],[-81.30082699999997,82.61109899999991],[-81.136124,82.57804900000008],[-80.989441,82.54721100000006],[-80.94972199999995,82.53804000000014],[-80.89195299999994,82.532761],[-80.58167999999995,82.543045],[-80.57806399999998,82.54609700000009],[-80.59916699999997,82.55442800000003],[-80.87388599999997,82.62970000000013],[-80.99444599999993,82.6502690000001],[-81.04998799999998,82.66081200000008],[-81.077225,82.66693100000009],[-81.09750399999996,82.67248500000005],[-81.12471,82.68691999999999],[-81.22361799999999,82.71582000000006],[-81.30583199999995,82.73387100000002],[-81.449997,82.75555399999996],[-81.50862099999995,82.76470900000004],[-81.57362399999994,82.78831500000007],[-81.58444199999991,82.79443400000014],[-81.58500699999996,82.80081200000006],[-81.57167099999992,82.80636600000008],[-81.55665599999998,82.81137100000012],[-81.53639199999992,82.816666],[-81.51417500000002,82.82110600000004],[-81.473053,82.82499700000011],[-81.41139199999992,82.82777399999998],[-81.35972599999997,82.82777399999998],[-81.02223200000003,82.82193000000001],[-80.97721899999993,82.82026700000006],[-80.801941,82.8124850000001],[-80.500565,82.79748499999994],[-80.41833499999996,82.79220599999996],[-80.381104,82.78887900000007],[-80.31861899999996,82.77998400000001],[-80.2933349999999,82.77442900000011],[-80.15834000000001,82.72776800000008],[-80.13890100000003,82.71998600000012],[-80.13944999999995,82.71582000000006],[-80.17832900000002,82.69999700000005],[-80.18249500000002,82.69470199999995],[-80.18138099999993,82.68775900000014],[-80.16027799999995,82.68136600000003],[-80.0708469999999,82.66554300000001],[-80.00306699999999,82.65637200000003],[-79.941666,82.64942900000005],[-79.86166400000002,82.64415000000008],[-79.81777999999991,82.64444000000009],[-79.80082700000003,82.64665200000013],[-79.803604,82.64999400000005],[-79.82250999999997,82.65776100000005],[-79.84861799999999,82.66387899999995],[-79.966949,82.68470800000011],[-79.98332199999999,82.68914799999999],[-79.97749299999998,82.69581599999992],[-79.96139499999992,82.70082100000002],[-79.928604,82.70555100000001],[-79.88583399999987,82.70860299999993],[-79.82972699999999,82.70887800000014],[-79.7875059999999,82.707764],[-79.74749799999995,82.70498700000007],[-79.68415800000002,82.69970699999999],[-79.61749299999991,82.69303900000006],[-79.46833800000002,82.67747500000013],[-79.38473499999998,82.6727600000001],[-79.14999399999994,82.66775500000006],[-78.843613,82.66499299999998],[-78.56555200000003,82.67469800000003],[-78.521118,82.67692599999998],[-78.502792,82.68109099999998],[-78.53195199999999,82.68441800000011],[-78.57667500000002,82.68691999999999],[-78.84083599999997,82.68081700000005],[-78.89500399999986,82.68026700000001],[-78.93194599999998,82.68165600000003],[-79.24305700000002,82.6952510000001],[-79.33168,82.69970699999999],[-79.40306099999998,82.70637499999998],[-79.62304699999999,82.72776800000008],[-79.8369449999999,82.75054900000009],[-79.88694800000002,82.75943000000007],[-79.91332999999992,82.76527400000003],[-79.93638599999997,82.77221700000007],[-79.99694799999997,82.803314],[-79.97582999999997,82.80859400000003],[-79.94248999999996,82.81137100000012],[-79.69221500000003,82.81805400000007],[-79.67443799999995,82.82026700000006],[-79.67222599999991,82.82388300000014],[-79.67388900000003,82.8247070000001],[-79.84777799999995,82.83499100000012],[-79.896118,82.83581500000008],[-80.00666799999993,82.834427],[-80.11000099999995,82.83471700000001],[-80.15834000000001,82.83554100000015],[-80.19415300000003,82.83831800000007],[-80.21972700000003,82.84165999999999],[-80.27722199999994,82.85081500000001],[-80.39306599999998,82.87553400000002],[-80.43028299999997,82.88749700000005],[-80.42971799999998,82.89415000000002],[-80.398056,82.899719],[-80.09583999999995,82.93719499999997],[-79.90472399999999,82.95109600000012],[-79.79333500000001,82.95748900000012],[-79.45834400000001,82.974152],[-79.414444,82.97526600000015],[-79.370544,82.974152],[-79.17748999999998,82.9519350000001],[-79.07333399999999,82.90193199999999],[-79.06443799999988,82.89582800000011],[-79.066101,82.88943499999999],[-78.92805499999997,82.89860500000003],[-78.825287,82.92804000000012],[-78.78028899999998,82.93803400000013],[-78.75611899999996,82.94247400000012],[-78.71972699999998,82.94664000000006],[-78.67111199999994,82.94552600000009],[-78.63194299999998,82.94136000000015],[-78.546112,82.9266510000001],[-78.52166699999992,82.92109700000009],[-78.50334199999992,82.91331499999995],[-78.50195300000001,82.907761],[-78.5041809999999,82.901093],[-78.52194199999997,82.88915999999995],[-78.53860500000002,82.87664799999999],[-78.55777,82.86053500000014],[-78.5533289999999,82.8535920000001],[-78.53443900000002,82.8477630000001],[-78.50056499999994,82.84553499999998],[-78.34167499999995,82.85054000000002],[-78.17555199999998,82.82720899999998],[-78.14416499999993,82.82331800000009],[-78.10916099999997,82.8252720000001],[-78.10665899999998,82.83194000000009],[-78.12887599999988,82.83665500000012],[-78.19444299999992,82.84582499999999],[-78.22361799999999,82.85108899999994],[-78.24137899999994,82.85887100000008],[-78.23889199999996,82.86526500000014],[-78.108337,82.89332600000006],[-78.08029199999999,82.8983310000001],[-77.98666399999996,82.90998800000006],[-77.94999699999988,82.91415400000011],[-77.86332700000003,82.92137100000002],[-77.81304899999986,82.92442299999999],[-77.76834099999996,82.92248500000005],[-77.70834400000001,82.91609200000005],[-77.68888900000002,82.91249099999999],[-77.61665299999999,82.90277100000009],[-77.52806099999992,82.89109800000011],[-77.46722399999999,82.88388099999997],[-77.40527299999991,82.87886000000003],[-77.319458,82.87330600000001],[-77.12832599999996,82.86331200000001],[-77.108047,82.85914600000012],[-77.08917199999996,82.85276799999997],[-76.96665999999999,82.80470300000013],[-76.95916699999992,82.77415500000001],[-76.941666,82.768326],[-76.898346,82.766098],[-76.85110499999996,82.76499900000005],[-76.81555200000003,82.76110799999998],[-76.78916899999996,82.75637799999993],[-76.766663,82.75082399999997],[-76.70861799999994,82.73304700000006],[-76.67443800000001,82.72137499999997],[-76.64416499999999,82.70915200000007],[-76.612503,82.69609100000014],[-76.598053,82.68887300000011],[-76.57055699999995,82.66665600000005],[-76.53832999999997,82.664154],[-76.38722199999995,82.65138200000001],[-76.09333799999996,82.62081900000004],[-76.05888400000003,82.61692800000014],[-75.91389500000002,82.59748799999994],[-75.89222699999999,82.59193399999998],[-75.89639299999999,82.58831800000007],[-75.91861,82.57998700000002],[-75.93832399999997,82.57582100000013],[-75.972778,82.57138100000009],[-76.03889500000002,82.55720500000007],[-76.19471699999997,82.51110800000004],[-76.20750399999997,82.50637799999998],[-76.21777299999991,82.50054899999998],[-76.25527999999997,82.47192400000012],[-76.26100200000002,82.46655299999998],[-76.2369379999999,82.44525099999998],[-76.23083500000001,82.444702],[-76.18415800000002,82.45387299999999],[-76.10278299999987,82.47053499999998],[-76.03778099999994,82.48442100000011],[-75.97500600000001,82.49971],[-75.88722199999995,82.52221700000013],[-75.80277999999998,82.54637100000002],[-75.77389499999992,82.55720500000007],[-75.67138699999992,82.58692900000011],[-75.648056,82.59166000000005],[-75.60638399999993,82.59582500000005],[-75.50083899999993,82.60026600000015],[-75.45167500000002,82.603317],[-75.42027300000001,82.60693400000014],[-75.396118,82.61469999999997],[-75.40972899999997,82.61914100000007],[-75.43472300000002,82.62387100000012],[-75.46888699999988,82.62776200000002],[-75.50361599999985,82.62886000000009],[-75.55749499999996,82.62858599999998],[-75.62554899999998,82.63304099999999],[-75.670547,82.64276100000006],[-75.80749500000002,82.65470900000008],[-76.10305799999998,82.68609600000002],[-76.23582499999998,82.71220399999999],[-76.25639299999995,82.71720900000003],[-76.27555799999993,82.724426],[-76.29998799999987,82.73970000000003],[-76.30665599999992,82.7458190000001],[-76.30915800000002,82.7527770000001],[-76.269455,82.76081799999997],[-76.22639500000002,82.7644350000001],[-76.17639199999996,82.76721200000003],[-76.05694599999998,82.77165200000002],[-76.014725,82.77581800000013],[-75.989441,82.77998400000001],[-75.97610499999996,82.78471400000006],[-75.99833699999994,82.78749099999993],[-76.18638599999997,82.78387500000008],[-76.241379,82.78360000000004],[-76.28860500000002,82.78471400000006],[-76.37527499999999,82.78915400000005],[-76.447495,82.79748499999994],[-76.50167799999997,82.8077550000001],[-76.52528399999994,82.813873],[-76.54527299999995,82.82110600000004],[-76.58639499999998,82.83859300000006],[-76.629166,82.85971099999995],[-76.66665599999999,82.87248200000005],[-76.71083099999998,82.88581800000003],[-76.752792,82.89498899999995],[-76.84416199999998,82.90914900000007],[-76.88194299999998,82.91360500000002],[-77.02583299999998,82.92776500000008],[-77.06639099999995,82.93081699999999],[-77.13166799999999,82.93997200000007],[-77.34472699999998,82.972488],[-77.3852839999999,82.983047],[-77.38137799999998,82.99443100000013],[-77.364441,83.00000000000011],[-77.341949,83.00555400000013],[-77.27610800000002,83.02026400000005],[-77.25222799999995,83.0252690000001],[-77.22277799999995,83.03054800000007],[-77.18388399999998,83.03387500000002],[-77.13473499999998,83.032486],[-77.1372219999999,83.02832000000012],[-77.17138699999998,83.01721199999997],[-77.16972399999997,83.01388500000002],[-77.13555899999994,83.01138300000014],[-76.86305199999993,83.01081800000009],[-76.55943299999996,83.01193200000006],[-76.36027499999994,83.02137800000003],[-76.266663,83.02915999999999],[-76.20666499999993,83.03665200000012],[-76.11332700000003,83.05053700000002],[-76.07917799999996,83.0535890000001],[-76.02861000000001,83.05442800000009],[-75.97972099999993,83.05304000000001],[-75.94860799999992,83.05192600000004],[-75.58084100000002,83.03804000000002],[-75.31332399999991,83.02748099999997],[-75.04695100000004,83.0416560000001],[-75,83.04388400000005],[-74.95639,83.04553199999998],[-74.79750100000001,83.04359400000004],[-74.70666499999999,83.04109199999994],[-74.43582200000003,83.02720599999998],[-74.40805099999989,83.0247040000001],[-74.27917500000001,83.009995],[-74.17277499999989,82.99108899999999],[-74.08416699999998,82.972488],[-74.01806599999998,82.95694000000015],[-73.87943999999987,82.89721700000013],[-73.85166899999996,82.86665300000004],[-73.81777999999997,82.85276799999997],[-73.60777299999995,82.81581099999994],[-73.54833999999994,82.80609100000004],[-73.28195199999993,82.76638800000006],[-73.24722299999996,82.76165800000001],[-73.160278,82.75138899999996],[-73.07501199999996,82.7458190000001],[-72.94972199999995,82.73887600000006],[-72.90666199999998,82.73580899999996],[-72.83583099999998,82.72859200000005],[-72.75,82.71470600000009],[-72.70083599999998,82.70332300000007],[-72.67222599999997,82.69859300000002],[-72.63389599999994,82.69442700000013],[-72.60333299999996,82.69581599999992],[-72.59472700000003,82.69747900000004],[-72.49888599999997,82.71832300000005],[-72.50250199999994,82.724426],[-72.64889499999992,82.74664300000006],[-72.71665999999993,82.75555399999996],[-72.912216,82.77665700000006],[-72.98388699999998,82.78387500000008],[-73.02722199999988,82.78692600000011],[-73.21139499999992,82.813873],[-73.25750699999992,82.82582100000008],[-73.40139799999992,82.87498500000004],[-73.42027299999995,82.89054899999996],[-73.43055699999991,82.89359999999999],[-73.46083099999993,82.89860500000003],[-73.49499499999996,82.90248100000008],[-73.577225,82.9080350000001],[-73.60749800000002,82.91304000000014],[-73.633331,82.91859399999998],[-73.65055799999999,82.92581199999995],[-73.64416499999987,82.93220500000012],[-73.63444499999997,82.93664600000005],[-73.61915599999998,82.94108600000004],[-73.26194800000002,83.00776700000006],[-73.03388999999993,83.03665200000012],[-72.94860799999998,83.05525200000005],[-72.92748999999998,83.06749000000008],[-72.65055799999993,83.09637499999997],[-72.59973100000002,83.09693900000008],[-72.57028200000002,83.092758],[-72.56861900000001,83.08776900000004],[-72.55665599999998,83.07971200000009],[-72.52389499999992,83.07693499999999],[-72.47749299999987,83.07665999999995],[-72.42416399999996,83.07916300000011],[-72.40777600000001,83.08360299999998],[-72.39361600000001,83.08943199999999],[-72.36582900000002,83.09414700000002],[-72.33639499999992,83.09776300000004],[-72.22694399999995,83.10137900000012],[-72.11193800000001,83.10108900000012],[-72.00556899999987,83.09915200000006],[-71.83168,83.09776300000004],[-71.71278399999989,83.09887700000002],[-71.6116639999999,83.09609999999998],[-71.58167999999995,83.09109500000011],[-71.59695399999987,83.08526600000005],[-71.65444899999994,83.06887800000004],[-71.69638099999992,83.05775500000004],[-71.75,83.04304500000006],[-71.7750089999999,83.03221100000002],[-71.7933349999999,83.02053799999999],[-71.79499800000002,83.01361100000008],[-71.79222099999998,83.00749200000007],[-71.77833599999991,83.00166300000006],[-71.56722999999994,82.94108600000004],[-71.493607,82.93220500000012],[-71.33666999999997,82.91470300000009],[-71.21972699999998,82.9149930000001],[-71.14416499999999,82.9083250000001],[-71.08416699999998,82.90054299999997],[-71.01834099999996,82.89193700000004],[-70.952225,82.88360599999999],[-70.87138400000003,82.88108799999998],[-70.83500699999996,82.8830410000001],[-70.84333799999996,82.88998400000008],[-70.85777300000001,82.89721700000013],[-70.90417499999995,82.9080350000001],[-70.96194499999996,82.91859399999998],[-71.08084100000002,82.93748499999998],[-71.30638099999993,82.98220800000007],[-71.47277799999995,83.00166300000006],[-71.49749800000001,83.00721700000003],[-71.48999000000003,83.01443500000005],[-71.47416699999985,83.01944000000009],[-71.42500299999995,83.0294340000001],[-71.12527499999999,83.08749400000005],[-70.8872219999999,83.09803800000009],[-70.69415299999997,83.10359200000005],[-70.58528099999995,83.10331700000006],[-70.47000099999997,83.10748299999995],[-70.37388599999997,83.11331199999995],[-70.26000999999997,83.11387600000012],[-70.16000399999996,83.11137400000001],[-70.11193799999995,83.10942100000011]]]}}]}python-msgspec-0.19.0/examples/geojson/msgspec_geojson.py000066400000000000000000000026701473355726200236250ustar00rootroot00000000000000from __future__ import annotations import msgspec Position = tuple[float, float] # Define the 7 standard Geometry types. # All types set `tag=True`, meaning that they'll make use of a `type` field to # disambiguate between types when decoding. class Point(msgspec.Struct, tag=True): coordinates: Position class MultiPoint(msgspec.Struct, tag=True): coordinates: list[Position] class LineString(msgspec.Struct, tag=True): coordinates: list[Position] class MultiLineString(msgspec.Struct, tag=True): coordinates: list[list[Position]] class Polygon(msgspec.Struct, tag=True): coordinates: list[list[Position]] class MultiPolygon(msgspec.Struct, tag=True): coordinates: list[list[list[Position]]] class GeometryCollection(msgspec.Struct, tag=True): geometries: list[Geometry] Geometry = ( Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon | GeometryCollection ) # Define the two Feature types class Feature(msgspec.Struct, tag=True): geometry: Geometry | None = None properties: dict | None = None id: str | int | None = None class FeatureCollection(msgspec.Struct, tag=True): features: list[Feature] # A union of all 9 GeoJSON types GeoJSON = Geometry | Feature | FeatureCollection # Create a decoder and an encoder to use for decoding & encoding GeoJSON types loads = msgspec.json.Decoder(GeoJSON).decode dumps = msgspec.json.Encoder().encode python-msgspec-0.19.0/examples/pyproject-toml/000077500000000000000000000000001473355726200214055ustar00rootroot00000000000000python-msgspec-0.19.0/examples/pyproject-toml/pyproject.py000066400000000000000000000042751473355726200240060ustar00rootroot00000000000000from typing import Any import msgspec class Base( msgspec.Struct, omit_defaults=True, forbid_unknown_fields=True, rename="kebab", ): """A base class holding some common settings. - We set ``omit_defaults = True`` to omit any fields containing only their default value from the output when encoding. - We set ``forbid_unknown_fields = True`` to error nicely if an unknown field is present in the input TOML. This helps catch typo errors early, and is also required per PEP 621. - We set ``rename = "kebab"`` to rename all fields to use kebab case when encoding/decoding, as this is the convention used in pyproject.toml. For example, this will rename ``requires_python`` to ``requires-python``. """ pass class BuildSystem(Base): requires: list[str] = [] build_backend: str | None = None backend_path: list[str] = [] class Readme(Base): file: str | None = None text: str | None = None content_type: str | None = None class License(Base): file: str | None = None text: str | None = None class Contributor(Base): name: str | None = None email: str | None = None class Project(Base): name: str | None = None version: str | None = None description: str | None = None readme: str | Readme | None = None license: str | License | None = None authors: list[Contributor] = [] maintainers: list[Contributor] = [] keywords: list[str] = [] classifiers: list[str] = [] urls: dict[str, str] = {} requires_python: str | None = None dependencies: list[str] = [] optional_dependencies: dict[str, list[str]] = {} scripts: dict[str, str] = {} gui_scripts: dict[str, str] = {} entry_points: dict[str, dict[str, str]] = {} dynamic: list[str] = [] class PyProject(Base): build_system: BuildSystem | None = None project: Project | None = None tool: dict[str, dict[str, Any]] = {} def decode(data: bytes | str) -> PyProject: """Decode a ``pyproject.toml`` file from TOML""" return msgspec.toml.decode(data, type=PyProject) def encode(msg: PyProject) -> bytes: """Encode a ``PyProject`` object to TOML""" return msgspec.toml.encode(msg) python-msgspec-0.19.0/msgspec/000077500000000000000000000000001473355726200162405ustar00rootroot00000000000000python-msgspec-0.19.0/msgspec/__init__.py000066400000000000000000000011751473355726200203550ustar00rootroot00000000000000from ._core import ( DecodeError, EncodeError, Field as _Field, Meta, MsgspecError, Raw, Struct, UnsetType, UNSET, NODEFAULT, ValidationError, defstruct, convert, to_builtins, ) def field(*, default=NODEFAULT, default_factory=NODEFAULT, name=None): return _Field(default=default, default_factory=default_factory, name=name) field.__doc__ = _Field.__doc__ from . import msgpack from . import json from . import yaml from . import toml from . import inspect from . import structs from ._version import get_versions __version__ = get_versions()["version"] del get_versions python-msgspec-0.19.0/msgspec/__init__.pyi000066400000000000000000000126761473355726200205360ustar00rootroot00000000000000import enum from typing import ( Any, Callable, ClassVar, Dict, Final, Iterable, Literal, Mapping, Optional, Tuple, Type, TypeVar, Union, overload, ) from typing_extensions import dataclass_transform, Buffer from . import inspect, json, msgpack, structs, toml, yaml T = TypeVar("T") class UnsetType(enum.Enum): UNSET = "UNSET" UNSET = UnsetType.UNSET class _NoDefault(enum.Enum): NODEFAULT = "NODEFAULT" NODEFAULT = _NoDefault.NODEFAULT @overload def field(*, default: T, name: Optional[str] = None) -> T: ... @overload def field(*, default_factory: Callable[[], T], name: Optional[str] = None) -> T: ... @overload def field(*, name: Optional[str] = None) -> Any: ... @dataclass_transform(field_specifiers=(field,)) class Struct: __struct_fields__: ClassVar[Tuple[str, ...]] __struct_config__: ClassVar[structs.StructConfig] __match_args__: ClassVar[Tuple[str, ...]] # A default __init__ so that Structs with unknown field types (say # constructed by `defstruct`) won't error on every call to `__init__` def __init__(self, *args: Any, **kwargs: Any) -> None: ... def __init_subclass__( cls, tag: Union[None, bool, str, int, Callable[[str], Union[str, int]]] = None, tag_field: Union[None, str] = None, rename: Union[ None, Literal["lower", "upper", "camel", "pascal", "kebab"], Callable[[str], Optional[str]], Mapping[str, str], ] = None, omit_defaults: bool = False, forbid_unknown_fields: bool = False, frozen: bool = False, eq: bool = True, order: bool = False, kw_only: bool = False, repr_omit_defaults: bool = False, array_like: bool = False, gc: bool = True, weakref: bool = False, dict: bool = False, cache_hash: bool = False, ) -> None: ... def __rich_repr__( self, ) -> Iterable[Union[Any, Tuple[Any], Tuple[str, Any], Tuple[str, Any, Any]]]: ... def defstruct( name: str, fields: Iterable[Union[str, Tuple[str, type], Tuple[str, type, Any]]], *, bases: Optional[Tuple[Type[Struct], ...]] = None, module: Optional[str] = None, namespace: Optional[Dict[str, Any]] = None, tag: Union[None, bool, str, int, Callable[[str], Union[str, int]]] = None, tag_field: Union[None, str] = None, rename: Union[ None, Literal["lower", "upper", "camel", "pascal", "kebab"], Callable[[str], Optional[str]], Mapping[str, str], ] = None, omit_defaults: bool = False, forbid_unknown_fields: bool = False, frozen: bool = False, eq: bool = True, order: bool = False, kw_only: bool = False, repr_omit_defaults: bool = False, array_like: bool = False, gc: bool = True, weakref: bool = False, dict: bool = False, cache_hash: bool = False, ) -> Type[Struct]: ... # Lie and say `Raw` is a subclass of `bytes`, so mypy will accept it in most # places where an object that implements the buffer protocol is valid class Raw(bytes): @overload def __new__(cls) -> "Raw": ... @overload def __new__(cls, msg: Union[Buffer, str]) -> "Raw": ... def copy(self) -> "Raw": ... class Meta: def __init__( self, *, gt: Union[int, float, None] = None, ge: Union[int, float, None] = None, lt: Union[int, float, None] = None, le: Union[int, float, None] = None, multiple_of: Union[int, float, None] = None, pattern: Union[str, None] = None, min_length: Union[int, None] = None, max_length: Union[int, None] = None, tz: Union[bool, None] = None, title: Union[str, None] = None, description: Union[str, None] = None, examples: Union[list, None] = None, extra_json_schema: Union[dict, None] = None, extra: Union[dict, None] = None, ): ... gt: Final[Union[int, float, None]] ge: Final[Union[int, float, None]] lt: Final[Union[int, float, None]] le: Final[Union[int, float, None]] multiple_of: Final[Union[int, float, None]] pattern: Final[Union[str, None]] min_length: Final[Union[int, None]] max_length: Final[Union[int, None]] tz: Final[Union[int, None]] title: Final[Union[str, None]] description: Final[Union[str, None]] examples: Final[Union[list, None]] extra_json_schema: Final[Union[dict, None]] extra: Final[Union[dict, None]] def __rich_repr__(self) -> Iterable[Tuple[str, Any]]: ... def to_builtins( obj: Any, *, str_keys: bool = False, builtin_types: Union[Iterable[type], None] = None, enc_hook: Optional[Callable[[Any], Any]] = None, order: Literal[None, "deterministic", "sorted"] = None, ) -> Any: ... @overload def convert( obj: Any, type: Type[T], *, strict: bool = True, from_attributes: bool = False, dec_hook: Optional[Callable[[type, Any], Any]] = None, builtin_types: Union[Iterable[type], None] = None, str_keys: bool = False, ) -> T: ... @overload def convert( obj: Any, type: Any, *, strict: bool = True, from_attributes: bool = False, dec_hook: Optional[Callable[[type, Any], Any]] = None, builtin_types: Union[Iterable[type], None] = None, str_keys: bool = False, ) -> Any: ... class MsgspecError(Exception): ... class EncodeError(MsgspecError): ... class DecodeError(MsgspecError): ... class ValidationError(DecodeError): ... __version__: str python-msgspec-0.19.0/msgspec/_core.c000066400000000000000000025364741473355726200175200ustar00rootroot00000000000000#include #include #include #include #include #include #define PY_SSIZE_T_CLEAN #include "Python.h" #include "datetime.h" #include "structmember.h" #include "common.h" #include "itoa.h" #include "ryu.h" #include "atof.h" /* Python version checks */ #define PY310_PLUS (PY_VERSION_HEX >= 0x030a0000) #define PY311_PLUS (PY_VERSION_HEX >= 0x030b0000) #define PY312_PLUS (PY_VERSION_HEX >= 0x030c0000) #define PY313_PLUS (PY_VERSION_HEX >= 0x030d0000) #define PY314_PLUS (PY_VERSION_HEX >= 0x030e0000) /* Hint to the compiler not to store `x` in a register since it is likely to * change. Results in much higher performance on GCC, with smaller benefits on * clang */ #if defined(__GNUC__) #define OPT_FORCE_RELOAD(x) __asm volatile("":"=m"(x)::); #else #define OPT_FORCE_RELOAD(x) #endif #ifdef __GNUC__ #define ms_popcount(i) __builtin_popcountll(i) #else static int ms_popcount(uint64_t i) { \ i = i - ((i >> 1) & 0x5555555555555555); // pairs i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333); // quads i = (i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F; // groups of 8 return (uint64_t)(i * 0x0101010101010101) >> 56; // sum bytes } #endif /* In Python 3.12+, tp_dict is NULL for some core types, PyType_GetDict returns * a borrowed reference to the interpreter or cls mapping */ #if PY312_PLUS #define MS_GET_TYPE_DICT(a) PyType_GetDict(a) #else #define MS_GET_TYPE_DICT(a) ((a)->tp_dict) #endif #if PY313_PLUS #define MS_UNICODE_EQ(a, b) (PyUnicode_Compare(a, b) == 0) #else #define MS_UNICODE_EQ(a, b) _PyUnicode_EQ(a, b) #endif #if PY314_PLUS #define MS_IMMORTAL_INITIAL_REFCNT _Py_IMMORTAL_INITIAL_REFCNT #else #define MS_IMMORTAL_INITIAL_REFCNT _Py_IMMORTAL_REFCNT #endif #define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) /* These macros are used to manually unroll some loops */ #define repeat8(x) { x(0) x(1) x(2) x(3) x(4) x(5) x(6) x(7) } #define is_digit(c) (c >= '0' && c <= '9') /* Easy access to NoneType object */ #define NONE_TYPE ((PyObject *)(Py_TYPE(Py_None))) /* Capacity of a list */ #define LIST_CAPACITY(x) (((PyListObject *)x)->allocated) /* Get the raw items pointer for a list and tuple */ #define LIST_ITEMS(x) (((PyListObject *)(x))->ob_item) #define TUPLE_ITEMS(x) (((PyTupleObject *)(x))->ob_item) /* Fast shrink of bytes & bytearray objects. This doesn't do any memory * allocations, it just shrinks the size of the view presented to Python. Since * outputs of `encode` should be short lived (immediately written to a * socket/file then dropped), this shouldn't result in increased application * memory usage. */ # define FAST_BYTES_SHRINK(obj, size) \ do { \ Py_SET_SIZE(obj, size); \ PyBytes_AS_STRING(obj)[size] = '\0'; \ } while (0); # define FAST_BYTEARRAY_SHRINK(obj, size) \ do { \ Py_SET_SIZE(obj, size); \ PyByteArray_AS_STRING(obj)[size] = '\0'; \ } while (0); /* XXX: Optimized `PyUnicode_AsUTF8AndSize` for strs that we know have * a cached unicode representation. */ static inline const char * unicode_str_and_size_nocheck(PyObject *str, Py_ssize_t *size) { if (MS_LIKELY(PyUnicode_IS_COMPACT_ASCII(str))) { *size = ((PyASCIIObject *)str)->length; return (char *)(((PyASCIIObject *)str) + 1); } *size = ((PyCompactUnicodeObject *)str)->utf8_length; return ((PyCompactUnicodeObject *)str)->utf8; } /* XXX: Optimized `PyUnicode_AsUTF8AndSize` */ static inline const char * unicode_str_and_size(PyObject *str, Py_ssize_t *size) { const char *out = unicode_str_and_size_nocheck(str, size); if (MS_LIKELY(out != NULL)) return out; return PyUnicode_AsUTF8AndSize(str, size); } static MS_INLINE char * ascii_get_buffer(PyObject *str) { return (char *)(((PyASCIIObject *)str) + 1); } /* Fill in view.buf & view.len from either a Unicode or buffer-compatible * object. */ static int ms_get_buffer(PyObject *obj, Py_buffer *view) { if (MS_UNLIKELY(PyUnicode_CheckExact(obj))) { view->buf = (void *)unicode_str_and_size(obj, &(view->len)); if (view->buf == NULL) return -1; Py_INCREF(obj); view->obj = obj; return 0; } return PyObject_GetBuffer(obj, view, PyBUF_CONTIG_RO); } static void ms_release_buffer(Py_buffer *view) { if (MS_LIKELY(!PyUnicode_CheckExact(view->obj))) { PyBuffer_Release(view); } else { Py_CLEAR(view->obj); } } /* Hash algorithm borrowed from cpython 3.10's hashing algorithm for tuples. * See https://github.com/python/cpython/blob/4bcef2bb48b3fd82011a89c1c716421b789f1442/Objects/tupleobject.c#L386-L424 */ #if SIZEOF_PY_UHASH_T > 4 #define MS_HASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL) #define MS_HASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL) #define MS_HASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL) #define MS_HASH_XXROTATE(x) ((x << 31) | (x >> 33)) /* Rotate left 31 bits */ #else #define MS_HASH_XXPRIME_1 ((Py_uhash_t)2654435761UL) #define MS_HASH_XXPRIME_2 ((Py_uhash_t)2246822519UL) #define MS_HASH_XXPRIME_5 ((Py_uhash_t)374761393UL) #define MS_HASH_XXROTATE(x) ((x << 13) | (x >> 19)) /* Rotate left 13 bits */ #endif /* Optimized version of PyLong_AsLongLongAndOverflow/PyLong_AsUnsignedLongLong. * * Returns True if sign * scale won't fit in an `int64` or a `uint64`. */ static inline bool fast_long_extract_parts(PyObject *vv, bool *neg, uint64_t *scale) { PyLongObject *v = (PyLongObject *)vv; uint64_t prev, x = 0; bool negative; #if PY312_PLUS /* CPython 3.12 changed int internal representation */ int sign = 1 - (v->long_value.lv_tag & _PyLong_SIGN_MASK); negative = sign == -1; if (_PyLong_IsCompact(v)) { x = v->long_value.ob_digit[0]; } else { Py_ssize_t i = v->long_value.lv_tag >> _PyLong_NON_SIZE_BITS; while (--i >= 0) { prev = x; x = (x << PyLong_SHIFT) + v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { return true; } } if (negative && x > (1ull << 63)) { return true; } } #else Py_ssize_t i = Py_SIZE(v); negative = false; if (MS_LIKELY(i == 1)) { x = v->ob_digit[0]; } else if (i != 0) { negative = i < 0; if (MS_UNLIKELY(negative)) { i = -i; } while (--i >= 0) { prev = x; x = (x << PyLong_SHIFT) + v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { return true; } } if (negative && x > (1ull << 63)) { return true; } } #endif *neg = negative; *scale = x; return false; } /* Access macro to the members which are floating "behind" the object */ #define MS_PyHeapType_GET_MEMBERS(etype) \ ((PyMemberDef *)(((char *)(etype)) + Py_TYPE(etype)->tp_basicsize)) #define MS_GET_FIRST_SLOT(obj) \ *((PyObject **)((char *)(obj) + sizeof(PyObject))) \ #define MS_SET_FIRST_SLOT(obj, val) \ MS_GET_FIRST_SLOT(obj) = (val) /************************************************************************* * Lookup Tables * *************************************************************************/ static const char hex_encode_table[] = "0123456789abcdef"; static const char base64_encode_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /************************************************************************* * GC Utilities * *************************************************************************/ /* Mirrored from pycore_gc.h in cpython */ typedef struct { uintptr_t _gc_next; uintptr_t _gc_prev; } MS_PyGC_Head; #define MS_AS_GC(o) ((MS_PyGC_Head *)(o)-1) #define MS_TYPE_IS_GC(t) (((PyTypeObject *)(t))->tp_flags & Py_TPFLAGS_HAVE_GC) #define MS_OBJECT_IS_GC(obj) MS_TYPE_IS_GC(Py_TYPE(obj)) #define MS_IS_TRACKED(o) (MS_AS_GC(o)->_gc_next != 0) /* Is this object something that is/could be GC tracked? True if * - the value supports GC * - the value isn't a tuple or the object is tracked (skip tracked checks for non-tuples) */ #define MS_MAYBE_TRACKED(x) \ (MS_TYPE_IS_GC(Py_TYPE(x)) && \ (!PyTuple_CheckExact(x) || MS_IS_TRACKED(x))) /************************************************************************* * Murmurhash2 * *************************************************************************/ static inline uint32_t unaligned_load(const unsigned char *p) { uint32_t out; memcpy(&out, p, sizeof(out)); return out; } static inline uint32_t murmur2(const char *p, Py_ssize_t len) { const unsigned char *buf = (unsigned char *)p; const size_t m = 0x5bd1e995; uint32_t hash = (uint32_t)len; while(len >= 4) { uint32_t k = unaligned_load(buf); k *= m; k ^= k >> 24; k *= m; hash *= m; hash ^= k; buf += 4; len -= 4; } switch(len) { case 3: hash ^= buf[2] << 16; case 2: hash ^= buf[1] << 8; case 1: hash ^= buf[0]; hash *= m; }; hash ^= hash >> 13; hash *= m; hash ^= hash >> 15; return hash; } /************************************************************************* * String Cache * *************************************************************************/ #ifndef STRING_CACHE_SIZE #define STRING_CACHE_SIZE 512 #endif #ifndef STRING_CACHE_MAX_STRING_LENGTH #define STRING_CACHE_MAX_STRING_LENGTH 32 #endif static PyObject *string_cache[STRING_CACHE_SIZE]; static void string_cache_clear(void) { /* Traverse the string cache, deleting any string with a reference count of * only 1 */ for (Py_ssize_t i = 0; i < STRING_CACHE_SIZE; i++) { PyObject *obj = string_cache[i]; if (obj != NULL) { if (Py_REFCNT(obj) == 1) { Py_DECREF(obj); string_cache[i] = NULL; } } } } /************************************************************************* * Endian handling macros * *************************************************************************/ #define _msgspec_store16(to, x) do { \ ((uint8_t*)to)[0] = (uint8_t)((x >> 8) & 0xff); \ ((uint8_t*)to)[1] = (uint8_t)(x & 0xff); \ } while (0); #define _msgspec_store32(to, x) do { \ ((uint8_t*)to)[0] = (uint8_t)((x >> 24) & 0xff); \ ((uint8_t*)to)[1] = (uint8_t)((x >> 16) & 0xff); \ ((uint8_t*)to)[2] = (uint8_t)((x >> 8) & 0xff); \ ((uint8_t*)to)[3] = (uint8_t)(x & 0xff); \ } while (0); #define _msgspec_store64(to, x) do { \ ((uint8_t*)to)[0] = (uint8_t)((x >> 56) & 0xff); \ ((uint8_t*)to)[1] = (uint8_t)((x >> 48) & 0xff); \ ((uint8_t*)to)[2] = (uint8_t)((x >> 40) & 0xff); \ ((uint8_t*)to)[3] = (uint8_t)((x >> 32) & 0xff); \ ((uint8_t*)to)[4] = (uint8_t)((x >> 24) & 0xff); \ ((uint8_t*)to)[5] = (uint8_t)((x >> 16) & 0xff); \ ((uint8_t*)to)[6] = (uint8_t)((x >> 8) & 0xff); \ ((uint8_t*)to)[7] = (uint8_t)(x & 0xff); \ } while (0); #define _msgspec_load16(cast, from) ((cast)( \ (((uint16_t)((uint8_t*)from)[0]) << 8) | \ (((uint16_t)((uint8_t*)from)[1]) ) )) #define _msgspec_load32(cast, from) ((cast)( \ (((uint32_t)((uint8_t*)from)[0]) << 24) | \ (((uint32_t)((uint8_t*)from)[1]) << 16) | \ (((uint32_t)((uint8_t*)from)[2]) << 8) | \ (((uint32_t)((uint8_t*)from)[3]) ) )) #define _msgspec_load64(cast, from) ((cast)( \ (((uint64_t)((uint8_t*)from)[0]) << 56) | \ (((uint64_t)((uint8_t*)from)[1]) << 48) | \ (((uint64_t)((uint8_t*)from)[2]) << 40) | \ (((uint64_t)((uint8_t*)from)[3]) << 32) | \ (((uint64_t)((uint8_t*)from)[4]) << 24) | \ (((uint64_t)((uint8_t*)from)[5]) << 16) | \ (((uint64_t)((uint8_t*)from)[6]) << 8) | \ (((uint64_t)((uint8_t*)from)[7]) ) )) /************************************************************************* * Module level state * *************************************************************************/ /* State of the msgspec module */ typedef struct { PyObject *MsgspecError; PyObject *EncodeError; PyObject *DecodeError; PyObject *ValidationError; PyObject *StructType; PyTypeObject *EnumMetaType; PyObject *struct_lookup_cache; PyObject *str___weakref__; PyObject *str___dict__; PyObject *str___msgspec_cached_hash__; PyObject *str__value2member_map_; PyObject *str___msgspec_cache__; PyObject *str__value_; PyObject *str__missing_; PyObject *str_type; PyObject *str_enc_hook; PyObject *str_dec_hook; PyObject *str_ext_hook; PyObject *str_strict; PyObject *str_order; PyObject *str_utcoffset; PyObject *str___origin__; PyObject *str___args__; PyObject *str___metadata__; PyObject *str___total__; PyObject *str___required_keys__; PyObject *str__fields; PyObject *str__field_defaults; PyObject *str___post_init__; PyObject *str___dataclass_fields__; PyObject *str___attrs_attrs__; PyObject *str___supertype__; #if PY312_PLUS PyObject *str___value__; #endif PyObject *str___bound__; PyObject *str___constraints__; PyObject *str_int; PyObject *str_is_safe; PyObject *UUIDType; PyObject *uuid_safeuuid_unknown; PyObject *DecimalType; PyObject *typing_union; PyObject *typing_any; PyObject *typing_literal; PyObject *typing_classvar; PyObject *typing_typevar; PyObject *typing_final; PyObject *typing_generic; PyObject *typing_generic_alias; PyObject *typing_annotated_alias; PyObject *concrete_types; PyObject *get_type_hints; PyObject *get_class_annotations; PyObject *get_typeddict_info; PyObject *get_dataclass_info; PyObject *rebuild; #if PY310_PLUS PyObject *types_uniontype; #endif #if PY312_PLUS PyObject *typing_typealiastype; #endif PyObject *astimezone; PyObject *re_compile; uint8_t gc_cycle; } MsgspecState; /* Forward declaration of the msgspec module definition. */ static struct PyModuleDef msgspecmodule; /* Given a module object, get its per-module state. */ static MsgspecState * msgspec_get_state(PyObject *module) { return (MsgspecState *)PyModule_GetState(module); } /* Find the module instance imported in the currently running sub-interpreter and get its state. */ static MsgspecState * msgspec_get_global_state(void) { PyObject *module = PyState_FindModule(&msgspecmodule); return module == NULL ? NULL : msgspec_get_state(module); } static int ms_err_truncated(void) { PyErr_SetString(msgspec_get_global_state()->DecodeError, "Input data was truncated"); return -1; } /************************************************************************* * Utilities * *************************************************************************/ static PyObject* find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key) { Py_ssize_t i, nkwargs; nkwargs = PyTuple_GET_SIZE(kwnames); for (i = 0; i < nkwargs; i++) { PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); /* kwname == key will normally find a match in since keyword keys should be interned strings; if not retry below in a new loop. */ if (kwname == key) { return kwstack[i]; } } for (i = 0; i < nkwargs; i++) { PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); assert(PyUnicode_Check(kwname)); if (MS_UNICODE_EQ(kwname, key)) { return kwstack[i]; } } return NULL; } static int check_positional_nargs(Py_ssize_t nargs, Py_ssize_t min, Py_ssize_t max) { if (nargs > max) { PyErr_SetString( PyExc_TypeError, "Extra positional arguments provided" ); return 0; } else if (nargs < min) { PyErr_Format( PyExc_TypeError, "Missing %zd required arguments", min - nargs ); return 0; } return 1; } /* A utility incrementally building strings */ typedef struct strbuilder { char *sep; Py_ssize_t sep_size; char *buffer; Py_ssize_t size; /* How many bytes have been written */ Py_ssize_t capacity; /* How many bytes can be written */ } strbuilder; #define strbuilder_extend_literal(self, str) strbuilder_extend(self, str, sizeof(str) - 1) static bool strbuilder_extend(strbuilder *self, const char *buf, Py_ssize_t nbytes) { bool is_first_write = self->size == 0; Py_ssize_t required = self->size + nbytes + self->sep_size; if (required > self->capacity) { self->capacity = required * 1.5; char *new_buf = PyMem_Realloc(self->buffer, self->capacity); if (new_buf == NULL) { PyMem_Free(self->buffer); self->buffer = NULL; return false; } self->buffer = new_buf; } if (self->sep_size && !is_first_write) { memcpy(self->buffer + self->size, self->sep, self->sep_size); self->size += self->sep_size; } memcpy(self->buffer + self->size, buf, nbytes); self->size += nbytes; return true; } static bool strbuilder_extend_unicode(strbuilder *self, PyObject *obj) { Py_ssize_t size; const char* buf = unicode_str_and_size(obj, &size); if (buf == NULL) return false; return strbuilder_extend(self, buf, size); } static void strbuilder_reset(strbuilder *self) { if (self->capacity != 0 && self->buffer != NULL) { PyMem_Free(self->buffer); } self->buffer = NULL; self->size = 0; self->capacity = 0; } static PyObject * strbuilder_build(strbuilder *self) { PyObject *out = PyUnicode_FromStringAndSize(self->buffer, self->size); strbuilder_reset(self); return out; } /************************************************************************* * PathNode * *************************************************************************/ #define PATH_ELLIPSIS -1 #define PATH_STR -2 #define PATH_KEY -3 typedef struct PathNode { struct PathNode *parent; Py_ssize_t index; PyObject *object; } PathNode; /* reverse the parent pointers in the path linked list */ static PathNode * pathnode_reverse(PathNode *path) { PathNode *current = path, *prev = NULL, *next = NULL; while (current != NULL) { next = current->parent; current->parent = prev; prev = current; current = next; } return prev; } static PyObject* StructMeta_get_field_name(PyObject*, Py_ssize_t); static PyObject * PathNode_ErrSuffix(PathNode *path) { strbuilder parts = {0}; PathNode *path_orig; PyObject *out = NULL, *path_repr = NULL, *groups = NULL, *group = NULL; if (path == NULL) { return PyUnicode_FromString(""); } /* Reverse the parent pointers for easier printing */ path = pathnode_reverse(path); /* Cache the original path to reset the parent pointers later */ path_orig = path; /* Start with the root element */ if (!strbuilder_extend_literal(&parts, "`$")) goto cleanup; while (path != NULL) { if (path->object != NULL) { PyObject *name; if (path->index == PATH_STR) { name = path->object; } else { name = StructMeta_get_field_name(path->object, path->index); } if (!strbuilder_extend_literal(&parts, ".")) goto cleanup; if (!strbuilder_extend_unicode(&parts, name)) goto cleanup; } else if (path->index == PATH_ELLIPSIS) { if (!strbuilder_extend_literal(&parts, "[...]")) goto cleanup; } else if (path->index == PATH_KEY) { if (groups == NULL) { groups = PyList_New(0); if (groups == NULL) goto cleanup; } if (!strbuilder_extend_literal(&parts, "`")) goto cleanup; group = strbuilder_build(&parts); if (group == NULL) goto cleanup; if (PyList_Append(groups, group) < 0) goto cleanup; Py_CLEAR(group); strbuilder_extend_literal(&parts, "`key"); } else { char buf[20]; char *p = &buf[20]; Py_ssize_t x = path->index; if (!strbuilder_extend_literal(&parts, "[")) goto cleanup; while (x >= 100) { const int64_t old = x; p -= 2; x /= 100; memcpy(p, DIGIT_TABLE + ((old - (x * 100)) << 1), 2); } if (x >= 10) { p -= 2; memcpy(p, DIGIT_TABLE + (x << 1), 2); } else { *--p = x + '0'; } if (!strbuilder_extend(&parts, p, &buf[20] - p)) goto cleanup; if (!strbuilder_extend_literal(&parts, "]")) goto cleanup; } path = path->parent; } if (!strbuilder_extend_literal(&parts, "`")) goto cleanup; if (groups == NULL) { path_repr = strbuilder_build(&parts); } else { group = strbuilder_build(&parts); if (group == NULL) goto cleanup; if (PyList_Append(groups, group) < 0) goto cleanup; PyObject *sep = PyUnicode_FromString(" in "); if (sep == NULL) goto cleanup; if (PyList_Reverse(groups) < 0) goto cleanup; path_repr = PyUnicode_Join(sep, groups); Py_DECREF(sep); } out = PyUnicode_FromFormat(" - at %U", path_repr); cleanup: Py_XDECREF(path_repr); Py_XDECREF(group); Py_XDECREF(groups); pathnode_reverse(path_orig); strbuilder_reset(&parts); return out; } /************************************************************************* * Lookup Tables for ints & strings * *************************************************************************/ typedef struct Lookup { PyObject_VAR_HEAD PyObject *tag_field; /* used for struct lookup table only */ PyObject *cls; /* Used for enum lookup table only */ bool array_like; } Lookup; static PyTypeObject IntLookup_Type; static PyTypeObject StrLookup_Type; typedef struct IntLookup { Lookup common; bool compact; } IntLookup; typedef struct IntLookupEntry { int64_t key; PyObject *value; } IntLookupEntry; typedef struct IntLookupHashmap { IntLookup base; IntLookupEntry table[]; } IntLookupHashmap; typedef struct IntLookupCompact { IntLookup base; int64_t offset; PyObject* table[]; } IntLookupCompact; typedef struct StrLookupEntry { PyObject *key; PyObject *value; } StrLookupEntry; typedef struct StrLookup { Lookup common; StrLookupEntry table[]; } StrLookup; #define Lookup_array_like(obj) ((Lookup *)(obj))->array_like #define Lookup_tag_field(obj) ((Lookup *)(obj))->tag_field #define Lookup_IsStrLookup(obj) (Py_TYPE(obj) == &StrLookup_Type) #define Lookup_IsIntLookup(obj) (Py_TYPE(obj) == &IntLookup_Type) /* Handles Enum._missing_ calls. Returns a new reference, or NULL on error. * Will decref val if non-null. */ static PyObject * _Lookup_OnMissing(Lookup *lookup, PyObject *val, PathNode *path) { if (val == NULL) return NULL; MsgspecState *mod = msgspec_get_global_state(); if (lookup->cls != NULL) { PyObject *out = PyObject_CallMethodOneArg(lookup->cls, mod->str__missing_, val); if (out == NULL) { PyErr_Clear(); } else if (out == Py_None) { Py_DECREF(out); } else { Py_DECREF(val); return out; } } PyObject *suffix = PathNode_ErrSuffix(path); if (suffix != NULL) { PyErr_Format(mod->ValidationError, "Invalid enum value %R%U", val, suffix); Py_DECREF(suffix); } Py_DECREF(val); return NULL; } static IntLookupEntry * _IntLookupHashmap_lookup(IntLookupHashmap *self, int64_t key) { IntLookupEntry *table = self->table; size_t mask = Py_SIZE(self) - 1; size_t i = key & mask; while (true) { IntLookupEntry *entry = &table[i]; if (MS_LIKELY(entry->key == key)) return entry; if (entry->value == NULL) return entry; i = (i + 1) & mask; } /* Unreachable */ return NULL; } static void _IntLookupHashmap_Set(IntLookupHashmap *self, int64_t key, PyObject *value) { IntLookupEntry *entry = _IntLookupHashmap_lookup(self, key); Py_XDECREF(entry->value); Py_INCREF(value); entry->key = key; entry->value = value; } static PyObject * IntLookup_New(PyObject *arg, PyObject *tag_field, PyObject *cls, bool array_like) { Py_ssize_t nitems; PyObject *item, *items = NULL; IntLookup *self = NULL; int64_t imin = LLONG_MAX, imax = LLONG_MIN; if (PyDict_CheckExact(arg)) { nitems = PyDict_GET_SIZE(arg); } else { items = PySequence_Tuple(arg); if (items == NULL) return NULL; nitems = PyTuple_GET_SIZE(items); } /* Must have at least one item */ if (nitems == 0) { PyErr_Format( PyExc_TypeError, "Enum types must have at least one item, %R is invalid", arg ); goto cleanup; } /* Find the min/max of items, and error if any item isn't an integer or is * out of range */ #define handle(key) \ do { \ int overflow = 0; \ int64_t ival = PyLong_AsLongLongAndOverflow(key, &overflow); \ if (overflow) { \ PyErr_SetString( \ PyExc_NotImplementedError, \ "Integer values > (2**63 - 1) are not currently supported for " \ "Enum/Literal/integer tags. If you need this feature, please " \ "open an issue on GitHub." \ ); \ goto cleanup; \ } \ if (ival == -1 && PyErr_Occurred()) goto cleanup; \ if (ival < imin) { \ imin = ival; \ } \ if (ival > imax) { \ imax = ival; \ } \ } while (false) if (PyDict_CheckExact(arg)) { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(arg, &pos, &key, &val)) { handle(key); } } else { for (Py_ssize_t i = 0; i < nitems; i++) { handle(PyTuple_GET_ITEM(items, i)); } } #undef handle /* Calculate range without overflow */ uint64_t range; if (imax > 0) { range = imax; range -= imin; } else { range = imax - imin; } if (range < 1.4 * nitems) { /* Use compact representation */ size_t size = range + 1; /* XXX: In Python 3.11+ there's not an easy way to allocate an untyped * block of memory that is also tracked by the GC. To hack around this * we set `tp_itemsize = 1` for `IntLookup_Type`, and manually calculate * the size of trailing parts. It's gross, but it works. */ size_t nextra = ( sizeof(IntLookupCompact) + (size * sizeof(PyObject *)) - sizeof(IntLookup) ); IntLookupCompact *out = PyObject_GC_NewVar( IntLookupCompact, &IntLookup_Type, nextra ); if (out == NULL) goto cleanup; /* XXX: overwrite `ob_size`, since we lied above */ Py_SET_SIZE(out, size); out->offset = imin; for (size_t i = 0; i < size; i++) { out->table[i] = NULL; } #define setitem(key, val) \ do { \ int64_t ikey = PyLong_AsLongLong(key); \ out->table[ikey - imin] = val; \ Py_INCREF(val); \ } while (false) if (PyDict_CheckExact(arg)) { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(arg, &pos, &key, &val)) { setitem(key, val); } } else { for (Py_ssize_t i = 0; i < nitems; i++) { item = PyTuple_GET_ITEM(items, i); setitem(item, item); } } #undef setitem self = (IntLookup *)out; self->compact = true; } else { /* Use hashtable */ size_t needed = nitems * 4 / 3; size_t size = 4; while (size < (size_t)needed) { size <<= 1; } /* XXX: This is hacky, see comment above allocating IntLookupCompact */ size_t nextra = ( sizeof(IntLookupHashmap) + (size * sizeof(IntLookupEntry)) - sizeof(IntLookup) ); IntLookupHashmap *out = PyObject_GC_NewVar( IntLookupHashmap, &IntLookup_Type, nextra ); if (out == NULL) goto cleanup; /* XXX: overwrite `ob_size`, since we lied above */ Py_SET_SIZE(out, size); for (size_t i = 0; i < size; i++) { out->table[i].key = 0; out->table[i].value = NULL; } if (PyDict_CheckExact(arg)) { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(arg, &pos, &key, &val)) { int64_t ival = PyLong_AsLongLong(key); _IntLookupHashmap_Set(out, ival, val); } } else { for (Py_ssize_t i = 0; i < nitems; i++) { PyObject *val = PyTuple_GET_ITEM(items, i); int64_t ival = PyLong_AsLongLong(val); _IntLookupHashmap_Set(out, ival, val); } } self = (IntLookup *)out; self->compact = false; } /* Store extra metadata (struct lookup only) */ Py_XINCREF(tag_field); self->common.tag_field = tag_field; Py_XINCREF(cls); self->common.cls = cls; self->common.array_like = array_like; cleanup: Py_XDECREF(items); if (self != NULL) { PyObject_GC_Track(self); } return (PyObject *)self; } static int IntLookup_traverse(IntLookup *self, visitproc visit, void *arg) { Py_VISIT(self->common.cls); if (self->compact) { IntLookupCompact *lk = (IntLookupCompact *)self; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { Py_VISIT(lk->table[i]); } } else { IntLookupHashmap *lk = (IntLookupHashmap *)self; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { Py_VISIT(lk->table[i].value); } } return 0; } static int IntLookup_clear(IntLookup *self) { if (self->compact) { IntLookupCompact *lk = (IntLookupCompact *)self; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { Py_CLEAR(lk->table[i]); } } else { IntLookupHashmap *lk = (IntLookupHashmap *)self; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { Py_CLEAR(lk->table[i].value); } } Py_CLEAR(self->common.cls); Py_CLEAR(self->common.tag_field); return 0; } static void IntLookup_dealloc(IntLookup *self) { PyObject_GC_UnTrack(self); IntLookup_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * IntLookup_GetInt64(IntLookup *self, int64_t key) { if (MS_LIKELY(self->compact)) { IntLookupCompact *lk = (IntLookupCompact *)self; Py_ssize_t index = key - lk->offset; if (index >= 0 && index < Py_SIZE(lk)) { return lk->table[index]; } return NULL; } return _IntLookupHashmap_lookup((IntLookupHashmap *)self, key)->value; } static PyObject * IntLookup_GetInt64OrError(IntLookup *self, int64_t key, PathNode *path) { PyObject *out = IntLookup_GetInt64(self, key); if (out != NULL) { Py_INCREF(out); return out; } return _Lookup_OnMissing((Lookup *)self, PyLong_FromLongLong(key), path); } static PyObject * IntLookup_GetUInt64(IntLookup *self, uint64_t key) { if (key > LLONG_MAX) return NULL; return IntLookup_GetInt64(self, key); } static PyObject * IntLookup_GetUInt64OrError(IntLookup *self, uint64_t key, PathNode *path) { PyObject *out = IntLookup_GetUInt64(self, key); if (out != NULL) { Py_INCREF(out); return out; } return _Lookup_OnMissing( (Lookup *)self, PyLong_FromUnsignedLongLong(key), path ); } static PyObject * IntLookup_GetPyIntOrError(IntLookup *self, PyObject *key, PathNode *path) { uint64_t x; bool neg, overflow; PyObject *out = NULL; overflow = fast_long_extract_parts(key, &neg, &x); if (!overflow) { if (neg) { out = IntLookup_GetInt64(self, -(int64_t)x); } else { out = IntLookup_GetUInt64(self, x); } } if (out != NULL) { Py_INCREF(out); return out; } /* PyNumber_Long call ensures input is actual int */ return _Lookup_OnMissing((Lookup *)self, PyNumber_Long(key), path); } static PyTypeObject IntLookup_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.IntLookup", .tp_basicsize = sizeof(IntLookup), .tp_itemsize = 1, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_dealloc = (destructor)IntLookup_dealloc, .tp_clear = (inquiry)IntLookup_clear, .tp_traverse = (traverseproc)IntLookup_traverse, }; static StrLookupEntry * _StrLookup_lookup(StrLookup *self, const char *key, Py_ssize_t size) { StrLookupEntry *table = self->table; size_t hash = murmur2(key, size); size_t perturb = hash; size_t mask = Py_SIZE(self) - 1; size_t i = hash & mask; while (true) { StrLookupEntry *entry = &table[i]; if (entry->value == NULL) return entry; Py_ssize_t entry_size; const char *entry_key = unicode_str_and_size_nocheck(entry->key, &entry_size); if (entry_size == size && memcmp(entry_key, key, size) == 0) return entry; /* Collision, perturb and try again */ perturb >>= 5; i = mask & (i*5 + perturb + 1); } /* Unreachable */ return NULL; } static int StrLookup_Set(StrLookup *self, PyObject *key, PyObject *value) { Py_ssize_t key_size; const char *key_str = unicode_str_and_size(key, &key_size); if (key_str == NULL) return -1; StrLookupEntry *entry = _StrLookup_lookup(self, key_str, key_size); entry->key = key; Py_INCREF(key); entry->value = value; Py_INCREF(value); return 0; } static PyObject * StrLookup_New(PyObject *arg, PyObject *tag_field, PyObject *cls, bool array_like) { Py_ssize_t nitems; PyObject *item, *items = NULL; StrLookup *self = NULL; if (PyDict_CheckExact(arg)) { nitems = PyDict_GET_SIZE(arg); } else { items = PySequence_Tuple(arg); if (items == NULL) return NULL; nitems = PyTuple_GET_SIZE(items); } /* Must have at least one item */ if (nitems == 0) { PyErr_Format( PyExc_TypeError, "Enum types must have at least one item, %R is invalid", arg ); goto cleanup; } size_t needed = nitems * 4 / 3; size_t size = 4; while (size < (size_t)needed) { size <<= 1; } self = PyObject_GC_NewVar(StrLookup, &StrLookup_Type, size); if (self == NULL) goto cleanup; /* Zero out memory */ self->common.cls = NULL; self->common.tag_field = NULL; for (size_t i = 0; i < size; i++) { self->table[i].key = NULL; self->table[i].value = NULL; } if (PyDict_CheckExact(arg)) { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(arg, &pos, &key, &val)) { if (!PyUnicode_CheckExact(key)) { PyErr_SetString(PyExc_RuntimeError, "Enum values must be strings"); Py_CLEAR(self); goto cleanup; } if (StrLookup_Set(self, key, val) < 0) { Py_CLEAR(self); goto cleanup; } } } else { for (Py_ssize_t i = 0; i < nitems; i++) { item = PyTuple_GET_ITEM(items, i); if (!PyUnicode_CheckExact(item)) { PyErr_SetString(PyExc_RuntimeError, "Enum values must be strings"); Py_CLEAR(self); goto cleanup; } if (StrLookup_Set(self, item, item) < 0) { Py_CLEAR(self); goto cleanup; } } } Py_XINCREF(cls); self->common.cls = cls; Py_XINCREF(tag_field); self->common.tag_field = tag_field; self->common.array_like = array_like; cleanup: Py_XDECREF(items); if (self != NULL) { PyObject_GC_Track(self); } return (PyObject *)self; } static int StrLookup_traverse(StrLookup *self, visitproc visit, void *arg) { Py_VISIT(self->common.cls); for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { Py_VISIT(self->table[i].key); Py_VISIT(self->table[i].value); } return 0; } static int StrLookup_clear(StrLookup *self) { for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { Py_CLEAR(self->table[i].key); Py_CLEAR(self->table[i].value); } Py_CLEAR(self->common.cls); Py_CLEAR(self->common.tag_field); return 0; } static void StrLookup_dealloc(StrLookup *self) { PyObject_GC_UnTrack(self); StrLookup_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * StrLookup_Get(StrLookup *self, const char *key, Py_ssize_t size) { StrLookupEntry *entry = _StrLookup_lookup(self, key, size); return entry->value; } static PyObject * StrLookup_GetOrError( StrLookup *self, const char *key, Py_ssize_t size, PathNode *path ) { PyObject *out = StrLookup_Get(self, key, size); if (out != NULL) { Py_INCREF(out); return out; } return _Lookup_OnMissing( (Lookup *)self, PyUnicode_FromStringAndSize(key, size), path ); } static PyTypeObject StrLookup_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.StrLookup", .tp_basicsize = sizeof(StrLookup), .tp_itemsize = sizeof(StrLookupEntry), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_dealloc = (destructor) StrLookup_dealloc, .tp_clear = (inquiry)StrLookup_clear, .tp_traverse = (traverseproc) StrLookup_traverse, }; /************************************************************************* * Raw * *************************************************************************/ static PyTypeObject Raw_Type; typedef struct Raw { PyObject_HEAD PyObject *base; char *buf; Py_ssize_t len; bool is_view; } Raw; static PyObject * Raw_New(PyObject *msg) { Raw *out = (Raw *)Raw_Type.tp_alloc(&Raw_Type, 0); if (out == NULL) return NULL; if (PyBytes_CheckExact(msg)) { Py_INCREF(msg); out->base = msg; out->buf = PyBytes_AS_STRING(msg); out->len = PyBytes_GET_SIZE(msg); out->is_view = false; } else if (PyUnicode_CheckExact(msg)) { out->base = msg; out->buf = (char *)unicode_str_and_size(msg, &out->len); if (out->buf == NULL) return NULL; Py_INCREF(msg); out->is_view = false; } else { Py_buffer buffer; if (PyObject_GetBuffer(msg, &buffer, PyBUF_CONTIG_RO) < 0) { Py_DECREF(out); return NULL; } out->base = buffer.obj; out->buf = buffer.buf; out->len = buffer.len; out->is_view = true; } return (PyObject *)out; } PyDoc_STRVAR(Raw__doc__, "Raw(msg="", /)\n" "--\n" "\n" "A buffer containing an encoded message.\n" "\n" "Raw objects have two common uses:\n" "\n" "- During decoding. Fields annotated with the ``Raw`` type won't be decoded\n" " immediately, but will instead return a ``Raw`` object with a view into the\n" " original message where that field is encoded. This is useful for decoding\n" " fields whose type may only be inferred after decoding other fields.\n" "- During encoding. Raw objects wrap pre-encoded messages. These can be added\n" " as components of larger messages without having to pay the cost of decoding\n" " and re-encoding them.\n" "\n" "Parameters\n" "----------\n" "msg: bytes, bytearray, memoryview, or str, optional\n" " A buffer containing an encoded message. One of bytes, bytearray, memoryview,\n" " str, or any object that implements the buffer protocol. If not present,\n" " defaults to an empty buffer." ); static PyObject * Raw_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *msg; Py_ssize_t nargs, nkwargs; nargs = PyTuple_GET_SIZE(args); nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs); if (nkwargs != 0) { PyErr_SetString( PyExc_TypeError, "Raw takes no keyword arguments" ); return NULL; } else if (nargs == 0) { msg = PyBytes_FromStringAndSize(NULL, 0); if (msg == NULL) return NULL; /* This looks weird, but is safe since the empty bytes object is an * immortal singleton */ Py_DECREF(msg); } else if (nargs == 1) { msg = PyTuple_GET_ITEM(args, 0); } else { PyErr_Format( PyExc_TypeError, "Raw expected at most 1 arguments, got %zd", nargs ); return NULL; } return Raw_New(msg); } static void Raw_dealloc(Raw *self) { if (self->base != NULL) { if (!self->is_view) { Py_DECREF(self->base); } else { Py_buffer buffer; buffer.obj = self->base; buffer.len = self->len; buffer.buf = self->buf; ms_release_buffer(&buffer); } } Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * Raw_FromView(PyObject *buffer_obj, char *data, Py_ssize_t len) { Raw *out = (Raw *)Raw_Type.tp_alloc(&Raw_Type, 0); if (out == NULL) return NULL; Py_buffer buffer; if (ms_get_buffer(buffer_obj, &buffer) < 0) { Py_DECREF(out); return NULL; } out->base = buffer.obj; out->buf = data; out->len = len; out->is_view = true; return (PyObject *)out; } static PyObject * Raw_richcompare(Raw *self, PyObject *other, int op) { if (Py_TYPE(other) != &Raw_Type) { Py_RETURN_NOTIMPLEMENTED; } if (op != Py_EQ && op != Py_NE) { Py_RETURN_NOTIMPLEMENTED; } Raw *raw_other = (Raw *)other; bool equal = ( self == raw_other || ( (self->len == raw_other->len) && (memcmp(self->buf, raw_other->buf, self->len) == 0) ) ); bool result = (op == Py_EQ) ? equal : !equal; if (result) { Py_RETURN_TRUE; } Py_RETURN_FALSE; } static int Raw_buffer_getbuffer(Raw *self, Py_buffer *view, int flags) { return PyBuffer_FillInfo(view, (PyObject *)self, self->buf, self->len, 1, flags); } static PyBufferProcs Raw_as_buffer = { .bf_getbuffer = (getbufferproc)Raw_buffer_getbuffer }; static Py_ssize_t Raw_length(Raw *self) { return self->len; } static PySequenceMethods Raw_as_sequence = { .sq_length = (lenfunc)Raw_length }; static PyObject * Raw_reduce(Raw *self, PyObject *unused) { if (!self->is_view) { return Py_BuildValue("O(O)", &Raw_Type, self->base); } return Py_BuildValue("O(y#)", &Raw_Type, self->buf, self->len); } PyDoc_STRVAR(Raw_copy__doc__, "copy(self)\n" "--\n" "\n" "Copy a Raw object.\n" "\n" "If the raw message is backed by a memoryview into a larger buffer (as happens\n" "during decoding), the message is copied and the reference to the larger buffer\n" "released. This may be useful to reduce memory usage if a Raw object created\n" "during decoding will be kept in memory for a while rather than immediately\n" "decoded and dropped." ); static PyObject * Raw_copy(Raw *self, PyObject *unused) { if (!self->is_view) { Py_INCREF(self); return (PyObject *)self; } PyObject *buf = PyBytes_FromStringAndSize(self->buf, self->len); if (buf == NULL) return NULL; PyObject *out = Raw_New(buf); Py_DECREF(buf); return out; } static PyMethodDef Raw_methods[] = { {"__reduce__", (PyCFunction)Raw_reduce, METH_NOARGS}, {"copy", (PyCFunction)Raw_copy, METH_NOARGS, Raw_copy__doc__}, {NULL, NULL}, }; static PyTypeObject Raw_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.Raw", .tp_doc = Raw__doc__, .tp_basicsize = sizeof(Raw), .tp_itemsize = sizeof(char), .tp_flags = Py_TPFLAGS_DEFAULT, .tp_new = Raw_new, .tp_dealloc = (destructor) Raw_dealloc, .tp_as_buffer = &Raw_as_buffer, .tp_as_sequence = &Raw_as_sequence, .tp_methods = Raw_methods, .tp_richcompare = (richcmpfunc) Raw_richcompare, }; /************************************************************************* * Meta * *************************************************************************/ static PyTypeObject Meta_Type; typedef struct Meta { PyObject_HEAD PyObject *gt; PyObject *ge; PyObject *lt; PyObject *le; PyObject *multiple_of; PyObject *pattern; PyObject *regex; PyObject *min_length; PyObject *max_length; PyObject *tz; PyObject *title; PyObject *description; PyObject *examples; PyObject *extra_json_schema; PyObject *extra; } Meta; static bool ensure_is_string(PyObject *val, const char *param) { if (PyUnicode_CheckExact(val)) return true; PyErr_Format( PyExc_TypeError, "`%s` must be a str, got %.200s", param, Py_TYPE(val)->tp_name ); return false; } static bool ensure_is_bool(PyObject *val, const char *param) { if (val == Py_True || val == Py_False) return true; PyErr_Format( PyExc_TypeError, "`%s` must be a bool, got %.200s", param, Py_TYPE(val)->tp_name ); return false; } static bool ensure_is_nonnegative_integer(PyObject *val, const char *param) { if (!PyLong_CheckExact(val)) { PyErr_Format( PyExc_TypeError, "`%s` must be an int, got %.200s", param, Py_TYPE(val)->tp_name ); return false; } Py_ssize_t x = PyLong_AsSsize_t(val); if (x >= 0) return true; PyErr_Format(PyExc_ValueError, "`%s` must be >= 0, got %R", param, val); return false; } static bool ensure_is_finite_numeric(PyObject *val, const char *param, bool positive) { double x; if (PyLong_CheckExact(val)) { x = PyLong_AsDouble(val); } else if (PyFloat_CheckExact(val)) { x = PyFloat_AS_DOUBLE(val); if (!isfinite(x)) { PyErr_Format( PyExc_ValueError, "`%s` must be finite, %R is not supported", param, val ); return false; } } else { PyErr_Format( PyExc_TypeError, "`%s` must be an int or float, got %.200s", param, Py_TYPE(val)->tp_name ); return false; } if (positive && x <= 0) { PyErr_Format(PyExc_ValueError, "`%s` must be > 0", param); return false; } return true; } PyDoc_STRVAR(Meta__doc__, "Meta(*, gt=None, ge=None, lt=None, le=None, multiple_of=None, pattern=None, " "min_length=None, max_length=None, tz=None, title=None, description=None, " "examples=None, extra_json_schema=None, extra=None)\n" "--\n" "\n" "Extra metadata and constraints for a type or field.\n" "\n" "Parameters\n" "----------\n" "gt : int or float, optional\n" " The annotated value must be greater than ``gt``.\n" "ge : int or float, optional\n" " The annotated value must be greater than or equal to ``ge``.\n" "lt : int or float, optional\n" " The annotated value must be less than ``lt``.\n" "le : int or float, optional\n" " The annotated value must be less than or equal to ``le``.\n" "multiple_of : int or float, optional\n" " The annotated value must be a multiple of ``multiple_of``.\n" "pattern : str, optional\n" " A regex pattern that the annotated value must match against. Note that\n" " the pattern is treated as **unanchored**, meaning the ``re.search``\n" " method is used when matching.\n" "min_length: int, optional\n" " The annotated value must have a length greater than or equal to\n" " ``min_length``.\n" "max_length: int, optional\n" " The annotated value must have a length less than or equal to\n" " ``max_length``.\n" "tz: bool, optional\n" " Configures the timezone-requirements for annotated ``datetime``/``time``\n" " types. Set to ``True`` to require timezone-aware values, or ``False`` to\n" " require timezone-naive values. The default is ``None``, which accepts\n" " either timezone-aware or timezone-naive values.\n" "title: str, optional\n" " The title to use for the annotated value when generating a json-schema.\n" "description: str, optional\n" " The description to use for the annotated value when generating a\n" " json-schema.\n" "examples: list, optional\n" " A list of examples to use for the annotated value when generating a\n" " json-schema.\n" "extra_json_schema: dict, optional\n" " A dict of extra fields to set for the annotated value when generating\n" " a json-schema. This dict is recursively merged with the generated schema,\n" " with ``extra_json_schema`` overriding any conflicting autogenerated fields.\n" "extra: dict, optional\n" " Any additional user-defined metadata.\n" "\n" "Examples\n" "--------\n" "Here we use ``Meta`` to add constraints on two different types. The first\n" "defines a new type alias ``NonNegativeInt``, which is an integer that must be\n" "``>= 0``. This type alias can be reused in multiple locations. The second uses\n" "``Meta`` inline in a struct definition to restrict the ``name`` string field\n" "to a maximum length of 32 characters.\n" "\n" ">>> import msgspec\n" ">>> from typing import Annotated\n" ">>> from msgspec import Struct, Meta\n" ">>> NonNegativeInt = Annotated[int, Meta(ge=0)]\n" ">>> class User(Struct):\n" "... name: Annotated[str, Meta(max_length=32)]\n" "... age: NonNegativeInt\n" "...\n" ">>> msgspec.json.decode(b'{\"name\": \"alice\", \"age\": 25}', type=User)\n" "User(name='alice', age=25)\n" ); static PyObject * Meta_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { char *kwlist[] = { "gt", "ge", "lt", "le", "multiple_of", "pattern", "min_length", "max_length", "tz", "title", "description", "examples", "extra_json_schema", "extra", NULL }; PyObject *gt = NULL, *ge = NULL, *lt = NULL, *le = NULL, *multiple_of = NULL; PyObject *pattern = NULL, *min_length = NULL, *max_length = NULL, *tz = NULL; PyObject *title = NULL, *description = NULL, *examples = NULL; PyObject *extra_json_schema = NULL, *extra = NULL; PyObject *regex = NULL; if (!PyArg_ParseTupleAndKeywords( args, kwargs, "|$OOOOOOOOOOOOOO:Meta.__new__", kwlist, >, &ge, <, &le, &multiple_of, &pattern, &min_length, &max_length, &tz, &title, &description, &examples, &extra_json_schema, &extra ) ) return NULL; #define NONE_TO_NULL(x) do { if (x == Py_None) {x = NULL;} } while(0) NONE_TO_NULL(gt); NONE_TO_NULL(ge); NONE_TO_NULL(lt); NONE_TO_NULL(le); NONE_TO_NULL(multiple_of); NONE_TO_NULL(pattern); NONE_TO_NULL(min_length); NONE_TO_NULL(max_length); NONE_TO_NULL(tz); NONE_TO_NULL(title); NONE_TO_NULL(description); NONE_TO_NULL(examples); NONE_TO_NULL(extra_json_schema); NONE_TO_NULL(extra); #undef NONE_TO_NULL /* Check parameter types/values */ if (gt != NULL && !ensure_is_finite_numeric(gt, "gt", false)) return NULL; if (ge != NULL && !ensure_is_finite_numeric(ge, "ge", false)) return NULL; if (lt != NULL && !ensure_is_finite_numeric(lt, "lt", false)) return NULL; if (le != NULL && !ensure_is_finite_numeric(le, "le", false)) return NULL; if (multiple_of != NULL && !ensure_is_finite_numeric(multiple_of, "multiple_of", true)) return NULL; if (pattern != NULL && !ensure_is_string(pattern, "pattern")) return NULL; if (min_length != NULL && !ensure_is_nonnegative_integer(min_length, "min_length")) return NULL; if (max_length != NULL && !ensure_is_nonnegative_integer(max_length, "max_length")) return NULL; if (tz != NULL && !ensure_is_bool(tz, "tz")) return NULL; /* Check multiple constraint restrictions */ if (gt != NULL && ge != NULL) { PyErr_SetString(PyExc_ValueError, "Cannot specify both `gt` and `ge`"); return NULL; } if (lt != NULL && le != NULL) { PyErr_SetString(PyExc_ValueError, "Cannot specify both `lt` and `le`"); return NULL; } bool numeric = (gt != NULL || ge != NULL || lt != NULL || le != NULL || multiple_of != NULL); bool other = (pattern != NULL || min_length != NULL || max_length != NULL || tz != NULL); if (numeric && other) { PyErr_SetString( PyExc_ValueError, "Cannot mix numeric constraints (gt, lt, ...) with non-numeric " "constraints (pattern, min_length, max_length, tz)" ); return NULL; } /* Check types/values of extra metadata */ if (title != NULL && !ensure_is_string(title, "title")) return NULL; if (description != NULL && !ensure_is_string(description, "description")) return NULL; if (examples != NULL && !PyList_CheckExact(examples)) { PyErr_Format( PyExc_TypeError, "`examples` must be a list, got %.200s", Py_TYPE(examples)->tp_name ); return NULL; } if (extra_json_schema != NULL && !PyDict_CheckExact(extra_json_schema)) { PyErr_Format( PyExc_TypeError, "`extra_json_schema` must be a dict, got %.200s", Py_TYPE(extra_json_schema)->tp_name ); return NULL; } if (extra != NULL && !PyDict_CheckExact(extra)) { PyErr_Format( PyExc_TypeError, "`extra` must be a dict, got %.200s", Py_TYPE(extra)->tp_name ); return NULL; } /* regex compile pattern if provided */ if (pattern != NULL) { MsgspecState *mod = msgspec_get_global_state(); regex = PyObject_CallOneArg(mod->re_compile, pattern); if (regex == NULL) return NULL; } Meta *out = (Meta *)Meta_Type.tp_alloc(&Meta_Type, 0); if (out == NULL) return NULL; #define SET_FIELD(x) do { Py_XINCREF(x); out->x = x; } while(0) SET_FIELD(gt); SET_FIELD(ge); SET_FIELD(lt); SET_FIELD(le); SET_FIELD(multiple_of); SET_FIELD(pattern); SET_FIELD(regex); SET_FIELD(min_length); SET_FIELD(max_length); SET_FIELD(tz); SET_FIELD(title); SET_FIELD(description); SET_FIELD(examples); SET_FIELD(extra_json_schema); SET_FIELD(extra); #undef SET_FIELD return (PyObject *)out; } static int Meta_traverse(Meta *self, visitproc visit, void *arg) { Py_VISIT(self->regex); Py_VISIT(self->examples); Py_VISIT(self->extra_json_schema); Py_VISIT(self->extra); return 0; } static int Meta_clear(Meta *self) { Py_CLEAR(self->gt); Py_CLEAR(self->ge); Py_CLEAR(self->lt); Py_CLEAR(self->le); Py_CLEAR(self->multiple_of); Py_CLEAR(self->pattern); Py_CLEAR(self->regex); Py_CLEAR(self->min_length); Py_CLEAR(self->max_length); Py_CLEAR(self->tz); Py_CLEAR(self->title); Py_CLEAR(self->description); Py_CLEAR(self->examples); Py_CLEAR(self->extra_json_schema); Py_CLEAR(self->extra); return 0; } static void Meta_dealloc(Meta *self) { PyObject_GC_UnTrack(self); Meta_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static bool _meta_repr_part(strbuilder *builder, const char *prefix, Py_ssize_t prefix_size, PyObject *field, bool *first) { if (*first) { *first = false; } else { if (!strbuilder_extend_literal(builder, ", ")) return false; } if (!strbuilder_extend(builder, prefix, prefix_size)) return false; PyObject *repr = PyObject_Repr(field); if (repr == NULL) return false; bool ok = strbuilder_extend_unicode(builder, repr); Py_DECREF(repr); return ok; } static PyObject * Meta_repr(Meta *self) { strbuilder builder = {0}; bool first = true; if (!strbuilder_extend_literal(&builder, "msgspec.Meta(")) return NULL; /* sizeof(#field) is the length of the field name + 1 (null terminator). We * want the length of field name + 1 (for the `=`). */ #define DO_REPR(field) do { \ if (self->field != NULL) { \ if (!_meta_repr_part(&builder, #field "=", sizeof(#field), self->field, &first)) { \ goto error; \ } \ } \ } while(0) DO_REPR(gt); DO_REPR(ge); DO_REPR(lt); DO_REPR(le); DO_REPR(multiple_of); DO_REPR(pattern); DO_REPR(min_length); DO_REPR(max_length); DO_REPR(tz); DO_REPR(title); DO_REPR(description); DO_REPR(examples); DO_REPR(extra_json_schema); DO_REPR(extra); #undef DO_REPR if (!strbuilder_extend_literal(&builder, ")")) goto error; return strbuilder_build(&builder); error: strbuilder_reset(&builder); return NULL; } static PyObject * Meta_rich_repr(PyObject *py_self, PyObject *args) { Meta *self = (Meta *)py_self; PyObject *out = PyList_New(0); if (out == NULL) goto error; #define DO_REPR(field) do { \ if (self->field != NULL) { \ PyObject *part = Py_BuildValue("(UO)", #field, self->field); \ if (part == NULL || (PyList_Append(out, part) < 0)) goto error;\ } } while(0) DO_REPR(gt); DO_REPR(ge); DO_REPR(lt); DO_REPR(le); DO_REPR(multiple_of); DO_REPR(pattern); DO_REPR(min_length); DO_REPR(max_length); DO_REPR(tz); DO_REPR(title); DO_REPR(description); DO_REPR(examples); DO_REPR(extra_json_schema); DO_REPR(extra); #undef DO_REPR return out; error: Py_XDECREF(out); return NULL; } static int _meta_richcompare_part(PyObject *left, PyObject *right) { if ((left == NULL) != (right == NULL)) { return 0; } if (left != NULL) { return PyObject_RichCompareBool(left, right, Py_EQ); } else { return 1; } } static PyObject * Meta_richcompare(Meta *self, PyObject *py_other, int op) { int equal = 1; PyObject *out; if (Py_TYPE(py_other) != &Meta_Type) { Py_RETURN_NOTIMPLEMENTED; } if (!(op == Py_EQ || op == Py_NE)) { Py_RETURN_NOTIMPLEMENTED; } Meta *other = (Meta *)py_other; /* Only need to loop if self is not other` */ if (MS_LIKELY(self != other)) { #define DO_COMPARE(field) do { \ equal = _meta_richcompare_part(self->field, other->field); \ if (equal < 0) return NULL; \ if (!equal) goto done; \ } while (0) DO_COMPARE(gt); DO_COMPARE(ge); DO_COMPARE(lt); DO_COMPARE(le); DO_COMPARE(multiple_of); DO_COMPARE(pattern); DO_COMPARE(min_length); DO_COMPARE(max_length); DO_COMPARE(tz); DO_COMPARE(title); DO_COMPARE(description); DO_COMPARE(examples); DO_COMPARE(extra_json_schema); DO_COMPARE(extra); } #undef DO_COMPARE done: if (op == Py_EQ) { out = equal ? Py_True : Py_False; } else { out = (!equal) ? Py_True : Py_False; } Py_INCREF(out); return out; } static Py_hash_t Meta_hash(Meta *self) { Py_ssize_t nfields = 0; Py_uhash_t acc = MS_HASH_XXPRIME_5; #define DO_HASH(field) \ if (self->field != NULL) { \ Py_uhash_t lane = PyObject_Hash(self->field); \ if (lane == (Py_uhash_t)-1) return -1; \ acc += lane * MS_HASH_XXPRIME_2; \ acc = MS_HASH_XXROTATE(acc); \ acc *= MS_HASH_XXPRIME_1; \ nfields += 1; \ } DO_HASH(gt); DO_HASH(ge); DO_HASH(lt); DO_HASH(le); DO_HASH(multiple_of); DO_HASH(pattern); DO_HASH(min_length); DO_HASH(max_length); DO_HASH(tz); DO_HASH(title); DO_HASH(description); /* Leave out examples & description, since they could be unhashable */ #undef DO_HASH acc += nfields ^ (MS_HASH_XXPRIME_5 ^ 3527539UL); return (acc == (Py_uhash_t)-1) ? 1546275796 : acc; } static PyMethodDef Meta_methods[] = { {"__rich_repr__", Meta_rich_repr, METH_NOARGS, "rich repr"}, {NULL, NULL}, }; static PyMemberDef Meta_members[] = { {"gt", T_OBJECT, offsetof(Meta, gt), READONLY, NULL}, {"ge", T_OBJECT, offsetof(Meta, ge), READONLY, NULL}, {"lt", T_OBJECT, offsetof(Meta, lt), READONLY, NULL}, {"le", T_OBJECT, offsetof(Meta, le), READONLY, NULL}, {"multiple_of", T_OBJECT, offsetof(Meta, multiple_of), READONLY, NULL}, {"pattern", T_OBJECT, offsetof(Meta, pattern), READONLY, NULL}, {"min_length", T_OBJECT, offsetof(Meta, min_length), READONLY, NULL}, {"max_length", T_OBJECT, offsetof(Meta, max_length), READONLY, NULL}, {"tz", T_OBJECT, offsetof(Meta, tz), READONLY, NULL}, {"title", T_OBJECT, offsetof(Meta, title), READONLY, NULL}, {"description", T_OBJECT, offsetof(Meta, description), READONLY, NULL}, {"examples", T_OBJECT, offsetof(Meta, examples), READONLY, NULL}, {"extra_json_schema", T_OBJECT, offsetof(Meta, extra_json_schema), READONLY, NULL}, {"extra", T_OBJECT, offsetof(Meta, extra), READONLY, NULL}, {NULL}, }; static PyTypeObject Meta_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.Meta", .tp_doc = Meta__doc__, .tp_basicsize = sizeof(Meta), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_new = Meta_new, .tp_traverse = (traverseproc) Meta_traverse, .tp_clear = (inquiry) Meta_clear, .tp_dealloc = (destructor) Meta_dealloc, .tp_methods = Meta_methods, .tp_members = Meta_members, .tp_repr = (reprfunc) Meta_repr, .tp_richcompare = (richcmpfunc) Meta_richcompare, .tp_hash = (hashfunc) Meta_hash }; /************************************************************************* * NODEFAULT singleton * *************************************************************************/ PyObject _NoDefault_Object; #define NODEFAULT &_NoDefault_Object PyDoc_STRVAR(nodefault__doc__, "NoDefaultType()\n" "--\n" "\n" "A singleton indicating no default value is configured." ); static PyObject * nodefault_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) { PyErr_SetString(PyExc_TypeError, "NoDefaultType takes no arguments"); return NULL; } Py_INCREF(NODEFAULT); return NODEFAULT; } static PyObject * nodefault_repr(PyObject *op) { return PyUnicode_FromString("NODEFAULT"); } static PyObject * nodefault_reduce(PyObject *op, PyObject *args) { return PyUnicode_FromString("NODEFAULT"); } static PyMethodDef nodefault_methods[] = { {"__reduce__", nodefault_reduce, METH_NOARGS, NULL}, {NULL, NULL} }; PyTypeObject NoDefault_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.NoDefaultType", .tp_doc = nodefault__doc__, .tp_repr = nodefault_repr, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_methods = nodefault_methods, .tp_new = nodefault_new, .tp_dealloc = 0, .tp_itemsize = 0, .tp_basicsize = 0 }; #if PY312_PLUS PyObject _NoDefault_Object = { _PyObject_EXTRA_INIT { MS_IMMORTAL_INITIAL_REFCNT }, &NoDefault_Type }; #else PyObject _NoDefault_Object = {1, &NoDefault_Type}; #endif /************************************************************************* * UNSET singleton * *************************************************************************/ PyObject _Unset_Object; #define UNSET &_Unset_Object PyDoc_STRVAR(unset__doc__, "UnsetType()\n" "--\n" "\n" "A singleton indicating a field value is unset.\n" "\n" "This may be useful for working with message schemas where an unset field\n" "in an object needs to be treated differently than one containing an explicit\n" "``None`` value. In this case, you may use ``UNSET`` as the default value,\n" "rather than ``None`` when defining object schemas. This feature is supported\n" "for any `msgspec.Struct`, `dataclasses` or `attrs` types.\n" "\n" "Examples\n" "--------\n" ">>> from msgspec import Struct, UnsetType, UNSET, json\n" ">>> class Example(Struct):\n" "... x: int\n" "... y: int | None | UnsetType = UNSET\n" "\n" "During encoding, any field containing ``UNSET`` is omitted from the message.\n" "\n" ">>> json.encode(Example(1))\n" "b'{\"x\":1}'\n" ">>> json.encode(Example(1, 2))\n" "b'{\"x\":1,\"y\":2}'\n" "\n" "During decoding, if a field isn't explicitly set in the message, the default\n" "value of ``UNSET`` will be set instead. This lets downstream consumers\n" "determine whether a field was left unset, or explicitly set to ``None``\n" "\n" ">>> json.decode(b'{\"x\": 1}', type=Example) # unset\n" "Example(x=1, y=UNSET)\n" ">>> json.decode(b'{\"x\": 1, \"y\": null}', type=Example) # explicit null\n" "Example(x=1, y=None)\n" ">>> json.decode(b'{\"x\": 1, \"y\": 2}', type=Example) # explicit value\n" "Example(x=1, y=2)" ); static PyObject * unset_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { if (PyTuple_GET_SIZE(args) || (kwargs && PyDict_GET_SIZE(kwargs))) { PyErr_SetString(PyExc_TypeError, "UnsetType takes no arguments"); return NULL; } Py_INCREF(UNSET); return UNSET; } static PyObject * unset_repr(PyObject *op) { return PyUnicode_FromString("UNSET"); } static PyObject * unset_reduce(PyObject *op, PyObject *args) { return PyUnicode_FromString("UNSET"); } static PyMethodDef unset_methods[] = { {"__reduce__", unset_reduce, METH_NOARGS, NULL}, {NULL, NULL} }; static int unset_bool(PyObject *obj) { return 0; }; static PyNumberMethods unset_as_number = { .nb_bool = unset_bool, }; PyTypeObject Unset_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.UnsetType", .tp_doc = unset__doc__, .tp_repr = unset_repr, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_methods = unset_methods, .tp_as_number = &unset_as_number, .tp_new = unset_new, .tp_dealloc = 0, .tp_itemsize = 0, .tp_basicsize = 0 }; #if PY312_PLUS PyObject _Unset_Object = { _PyObject_EXTRA_INIT { MS_IMMORTAL_INITIAL_REFCNT }, &Unset_Type }; #else PyObject _Unset_Object = {1, &Unset_Type}; #endif /************************************************************************* * Factory * *************************************************************************/ static PyTypeObject Factory_Type; typedef struct { PyObject_HEAD PyObject *factory; } Factory; static PyObject * Factory_New(PyObject *factory) { if (!PyCallable_Check(factory)) { PyErr_SetString(PyExc_TypeError, "default_factory must be callable"); return NULL; } Factory *out = (Factory *)Factory_Type.tp_alloc(&Factory_Type, 0); if (out == NULL) return NULL; Py_INCREF(factory); out->factory = factory; return (PyObject *)out; } static PyObject * Factory_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { Py_ssize_t nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs); Py_ssize_t nargs = PyTuple_GET_SIZE(args); if (nkwargs != 0) { PyErr_SetString(PyExc_TypeError, "Factory takes no keyword arguments"); return NULL; } else if (nargs != 1) { PyErr_Format( PyExc_TypeError, "Factory expected 1 argument, got %zd", nargs ); return NULL; } else { return Factory_New(PyTuple_GET_ITEM(args, 0)); } } static PyObject * Factory_Call(PyObject *self) { PyObject *factory = ((Factory *)(self))->factory; /* Inline two common factory types */ if (factory == (PyObject *)(&PyList_Type)) { return PyList_New(0); } else if (factory == (PyObject *)(&PyDict_Type)) { return PyDict_New(); } return PyObject_CallNoArgs(factory); } static PyObject * Factory_repr(PyObject *op) { return PyUnicode_FromString(""); } static int Factory_traverse(Factory *self, visitproc visit, void *arg) { Py_VISIT(self->factory); return 0; } static int Factory_clear(Factory *self) { Py_CLEAR(self->factory); return 0; } static void Factory_dealloc(Factory *self) { PyObject_GC_UnTrack(self); Factory_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyMemberDef Factory_members[] = { {"factory", T_OBJECT_EX, offsetof(Factory, factory), READONLY, "The factory function"}, {NULL}, }; static PyTypeObject Factory_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.Factory", .tp_basicsize = sizeof(Factory), .tp_itemsize = 0, .tp_new = Factory_new, .tp_repr = Factory_repr, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)Factory_clear, .tp_traverse = (traverseproc)Factory_traverse, .tp_dealloc = (destructor) Factory_dealloc, .tp_members = Factory_members, }; /************************************************************************* * Field * *************************************************************************/ static PyTypeObject Field_Type; typedef struct { PyObject_HEAD PyObject *default_value; PyObject *default_factory; PyObject *name; } Field; PyDoc_STRVAR(Field__doc__, "Configuration for a Struct field.\n" "\n" "Parameters\n" "----------\n" "default : Any, optional\n" " A default value to use for this field.\n" "default_factory : callable, optional\n" " A zero-argument function called to generate a new default value\n" " per-instance, rather than using a constant value as in ``default``.\n" "name : str, optional\n" " The name to use when encoding/decoding this field. If present, this\n" " will override any struct-level configuration using the ``rename``\n" " option for this field." ); static PyObject * Field_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { char *kwlist[] = {"default", "default_factory", "name", NULL}; PyObject *default_value = NODEFAULT, *default_factory = NODEFAULT; PyObject *name = Py_None; if ( !PyArg_ParseTupleAndKeywords( args, kwargs, "|$OOO", kwlist, &default_value, &default_factory, &name ) ) { return NULL; } if (default_value != NODEFAULT && default_factory != NODEFAULT) { PyErr_SetString( PyExc_TypeError, "Cannot set both `default` and `default_factory`" ); return NULL; } if (default_factory != NODEFAULT) { if (!PyCallable_Check(default_factory)) { PyErr_SetString(PyExc_TypeError, "default_factory must be callable"); return NULL; } } if (name == Py_None) { name = NULL; } else if (!PyUnicode_CheckExact(name)) { PyErr_SetString(PyExc_TypeError, "name must be a str or None"); return NULL; } Field *self = (Field *)Field_Type.tp_alloc(&Field_Type, 0); if (self == NULL) return NULL; Py_INCREF(default_value); self->default_value = default_value; Py_INCREF(default_factory); self->default_factory = default_factory; Py_XINCREF(name); self->name = name; return (PyObject *)self; } static int Field_traverse(Field *self, visitproc visit, void *arg) { Py_VISIT(self->default_value); Py_VISIT(self->default_factory); Py_VISIT(self->name); return 0; } static int Field_clear(Field *self) { Py_CLEAR(self->default_value); Py_CLEAR(self->default_factory); Py_CLEAR(self->name); return 0; } static void Field_dealloc(Field *self) { PyObject_GC_UnTrack(self); Field_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyMemberDef Field_members[] = { { "default", T_OBJECT_EX, offsetof(Field, default_value), READONLY, "The default value, or NODEFAULT if no default" }, { "default_factory", T_OBJECT_EX, offsetof(Field, default_factory), READONLY, "The default_factory, or NODEFAULT if no default" }, { "name", T_OBJECT, offsetof(Field, name), READONLY, "An alternative name to use when encoding/decoding this field" }, {NULL}, }; static PyTypeObject Field_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.Field", .tp_doc = Field__doc__, .tp_basicsize = sizeof(Field), .tp_itemsize = 0, .tp_new = Field_new, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)Field_clear, .tp_traverse = (traverseproc)Field_traverse, .tp_dealloc = (destructor) Field_dealloc, .tp_members = Field_members, }; /************************************************************************* * AssocList & order handling * *************************************************************************/ enum order_mode { ORDER_SORTED = -1, ORDER_DEFAULT = 0, ORDER_DETERMINISTIC = 1, ORDER_INVALID = 2, }; static enum order_mode parse_order_arg(PyObject *order) { if (order == NULL || order == Py_None) { return ORDER_DEFAULT; } else if (PyUnicode_CheckExact(order)) { if (PyUnicode_CompareWithASCIIString(order, "deterministic") == 0) { return ORDER_DETERMINISTIC; } else if (PyUnicode_CompareWithASCIIString(order, "sorted") == 0) { return ORDER_SORTED; } } PyErr_Format( PyExc_ValueError, "`order` must be one of `{None, 'deterministic', 'sorted'}`, got %R", order ); return ORDER_INVALID; } #define ASSOCLIST_SORT_CUTOFF 16 typedef struct { const char *key; Py_ssize_t key_size; PyObject *val; } AssocItem; typedef struct { Py_ssize_t size; AssocItem items[]; } AssocList; static AssocList * AssocList_New(Py_ssize_t capacity) { AssocList *out = PyMem_Malloc(sizeof(AssocList) + capacity * sizeof(AssocItem)); if (out == NULL) { PyErr_NoMemory(); return NULL; } out->size = 0; return out; } static void AssocList_Free(AssocList *list) { PyMem_Free(list); } static void AssocList_AppendCStr(AssocList *list, const char *key, PyObject *val) { list->items[list->size].key = key; list->items[list->size].key_size = strlen(key); list->items[list->size].val = val; list->size++; } static int AssocList_Append(AssocList *list, PyObject *key, PyObject *val) { Py_ssize_t key_size; const char* key_buf = unicode_str_and_size(key, &key_size); if (key_buf == NULL) return -1; list->items[list->size].key = key_buf; list->items[list->size].key_size = key_size; list->items[list->size].val = val; list->size++; return 0; } static AssocList * AssocList_FromDict(PyObject *dict) { Py_ssize_t len = PyDict_GET_SIZE(dict); AssocList *out = AssocList_New(len); PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(dict, &pos, &key, &val)) { if (!PyUnicode_Check(key)) { PyErr_SetString( PyExc_TypeError, "Only dicts with str keys are supported when `order` is not `None`" ); goto error; } if (AssocList_Append(out, key, val) < 0) goto error; } return out; error: AssocList_Free(out); return NULL; } static inline int _AssocItem_lt(AssocItem *left, AssocItem *right) { int left_shorter = left->key_size < right->key_size; int cmp = memcmp( left->key, right->key, (left_shorter) ? left->key_size : right->key_size ); return (cmp < 0) || ((cmp == 0) & left_shorter); } static Py_ssize_t _AssocList_sort_partition( AssocList* list, Py_ssize_t lo, Py_ssize_t hi, AssocItem *pivot ) { Py_ssize_t i = lo - 1; Py_ssize_t j = hi + 1; while (true) { while (_AssocItem_lt(pivot, &(list->items[--j]))); while (_AssocItem_lt(&(list->items[++i]), pivot)); if (i < j) { AssocItem tmp = list->items[i]; list->items[i] = list->items[j]; list->items[j] = tmp; } else { return j; } } } static void _AssocList_sort_inner(AssocList* list, Py_ssize_t lo, Py_ssize_t hi) { while (lo + ASSOCLIST_SORT_CUTOFF < hi) { AssocItem *v1 = &(list->items[lo]); AssocItem *v2 = &(list->items[hi]); AssocItem *v3 = &(list->items[(lo + hi)/2]); AssocItem pivot; if (_AssocItem_lt(v1, v2)) { if (_AssocItem_lt(v3, v1)) { pivot = *v1; } else if (_AssocItem_lt(v2, v3)) { pivot = *v2; } else { pivot = *v3; } } else { if (_AssocItem_lt(v3, v2)) { pivot = *v2; } else if (_AssocItem_lt(v1, v3)) { pivot = *v1; } else { pivot = *v3; } } Py_ssize_t partition = _AssocList_sort_partition(list, lo, hi, &pivot); _AssocList_sort_inner(list, lo, partition); lo = partition + 1; } } static void AssocList_Sort(AssocList* list) { if (list->size > ASSOCLIST_SORT_CUTOFF) { _AssocList_sort_inner(list, 0, list->size - 1); } for (Py_ssize_t i = 1; i < list->size; i++) { AssocItem val = list->items[i]; Py_ssize_t j = i; while (j > 0 && _AssocItem_lt(&val, &(list->items[j - 1]))) { list->items[j] = list->items[j - 1]; --j; } list->items[j] = val; } } /************************************************************************* * Struct, PathNode, and TypeNode Types * *************************************************************************/ /* Types */ #define MS_TYPE_ANY (1ull << 0) #define MS_TYPE_NONE (1ull << 1) #define MS_TYPE_BOOL (1ull << 2) #define MS_TYPE_INT (1ull << 3) #define MS_TYPE_FLOAT (1ull << 4) #define MS_TYPE_STR (1ull << 5) #define MS_TYPE_BYTES (1ull << 6) #define MS_TYPE_BYTEARRAY (1ull << 7) #define MS_TYPE_MEMORYVIEW (1ull << 8) #define MS_TYPE_DATETIME (1ull << 9) #define MS_TYPE_DATE (1ull << 10) #define MS_TYPE_TIME (1ull << 11) #define MS_TYPE_TIMEDELTA (1ull << 12) #define MS_TYPE_UUID (1ull << 13) #define MS_TYPE_DECIMAL (1ull << 14) #define MS_TYPE_EXT (1ull << 15) #define MS_TYPE_STRUCT (1ull << 16) #define MS_TYPE_STRUCT_ARRAY (1ull << 17) #define MS_TYPE_STRUCT_UNION (1ull << 18) #define MS_TYPE_STRUCT_ARRAY_UNION (1ull << 19) #define MS_TYPE_ENUM (1ull << 20) #define MS_TYPE_INTENUM (1ull << 21) #define MS_TYPE_CUSTOM (1ull << 22) #define MS_TYPE_CUSTOM_GENERIC (1ull << 23) #define MS_TYPE_DICT ((1ull << 24) | (1ull << 25)) #define MS_TYPE_LIST (1ull << 26) #define MS_TYPE_SET (1ull << 27) #define MS_TYPE_FROZENSET (1ull << 28) #define MS_TYPE_VARTUPLE (1ull << 29) #define MS_TYPE_FIXTUPLE (1ull << 30) #define MS_TYPE_INTLITERAL (1ull << 31) #define MS_TYPE_STRLITERAL (1ull << 32) #define MS_TYPE_TYPEDDICT (1ull << 33) #define MS_TYPE_DATACLASS (1ull << 34) #define MS_TYPE_NAMEDTUPLE (1ull << 35) /* Constraints */ #define MS_CONSTR_INT_MIN (1ull << 42) #define MS_CONSTR_INT_MAX (1ull << 43) #define MS_CONSTR_INT_MULTIPLE_OF (1ull << 44) #define MS_CONSTR_FLOAT_GT (1ull << 45) #define MS_CONSTR_FLOAT_GE (1ull << 46) #define MS_CONSTR_FLOAT_LT (1ull << 47) #define MS_CONSTR_FLOAT_LE (1ull << 48) #define MS_CONSTR_FLOAT_MULTIPLE_OF (1ull << 49) #define MS_CONSTR_STR_REGEX (1ull << 50) #define MS_CONSTR_STR_MIN_LENGTH (1ull << 51) #define MS_CONSTR_STR_MAX_LENGTH (1ull << 52) #define MS_CONSTR_BYTES_MIN_LENGTH (1ull << 53) #define MS_CONSTR_BYTES_MAX_LENGTH (1ull << 54) #define MS_CONSTR_ARRAY_MIN_LENGTH (1ull << 55) #define MS_CONSTR_ARRAY_MAX_LENGTH (1ull << 56) #define MS_CONSTR_MAP_MIN_LENGTH (1ull << 57) #define MS_CONSTR_MAP_MAX_LENGTH (1ull << 58) #define MS_CONSTR_TZ_AWARE (1ull << 59) #define MS_CONSTR_TZ_NAIVE (1ull << 60) /* Extra flag bit, used by TypedDict/dataclass implementations */ #define MS_EXTRA_FLAG (1ull << 63) /* A TypeNode encodes information about all types at the same hierarchy in the * type tree. They can encode both single types (`int`) and unions of types * (`int | float | list[int]`). The encoding is optimized for the common case * of simple scalar types (or unions of these types) with no constraints - * these values only require a single uint64_t. More complicated types require * extra *details* (`TypeDetail` objects) stored in a variable length array. * * The encoding is *compressed* - only fields that are set are stored. To know * which fields are set, a bitmask of `types` is used, masking both the types * and constraints set on the node. * * The order these details are stored is consistent, allowing the offset of a * field to be computed using an efficient bitmask and popcount. * * The order is documented below: * * O | STRUCT | STRUCT_ARRAY | STRUCT_UNION | STRUCT_ARRAY_UNION | CUSTOM | * O | INTENUM | INTLITERAL | * O | ENUM | STRLITERAL | * O | TYPEDDICT | DATACLASS | * O | NAMEDTUPLE | * O | STR_REGEX | * T | DICT [key, value] | * T | LIST | SET | FROZENSET | VARTUPLE | * I | INT_MIN | * I | INT_MAX | * I | INT_MULTIPLE_OF | * F | FLOAT_GT | FLOAT_GE | * F | FLOAT_LT | FLOAT_LE | * F | FLOAT_MULTIPLE_OF | * S | STR_MIN_LENGTH | * S | STR_MAX_LENGTH | * S | BYTES_MIN_LENGTH | * S | BYTES_MAX_LENGTH | * S | ARRAY_MIN_LENGTH | * S | ARRAY_MAX_LENGTH | * S | MAP_MIN_LENGTH | * S | MAP_MAX_LENGTH | * T | FIXTUPLE [size, types ...] | * */ #define SLOT_00 ( \ MS_TYPE_STRUCT | MS_TYPE_STRUCT_ARRAY | \ MS_TYPE_STRUCT_UNION | MS_TYPE_STRUCT_ARRAY_UNION | \ MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC \ ) #define SLOT_01 (MS_TYPE_INTENUM | MS_TYPE_INTLITERAL) #define SLOT_02 (MS_TYPE_ENUM | MS_TYPE_STRLITERAL) #define SLOT_03 (MS_TYPE_TYPEDDICT | MS_TYPE_DATACLASS) #define SLOT_04 MS_TYPE_NAMEDTUPLE #define SLOT_05 MS_CONSTR_STR_REGEX #define SLOT_06 MS_TYPE_DICT #define SLOT_07 (MS_TYPE_LIST | MS_TYPE_VARTUPLE | MS_TYPE_SET | MS_TYPE_FROZENSET) #define SLOT_08 MS_CONSTR_INT_MIN #define SLOT_09 MS_CONSTR_INT_MAX #define SLOT_10 MS_CONSTR_INT_MULTIPLE_OF #define SLOT_11 (MS_CONSTR_FLOAT_GE | MS_CONSTR_FLOAT_GT) #define SLOT_12 (MS_CONSTR_FLOAT_LE | MS_CONSTR_FLOAT_LT) #define SLOT_13 MS_CONSTR_FLOAT_MULTIPLE_OF #define SLOT_14 MS_CONSTR_STR_MIN_LENGTH #define SLOT_15 MS_CONSTR_STR_MAX_LENGTH #define SLOT_16 MS_CONSTR_BYTES_MIN_LENGTH #define SLOT_17 MS_CONSTR_BYTES_MAX_LENGTH #define SLOT_18 MS_CONSTR_ARRAY_MIN_LENGTH #define SLOT_19 MS_CONSTR_ARRAY_MAX_LENGTH #define SLOT_20 MS_CONSTR_MAP_MIN_LENGTH #define SLOT_21 MS_CONSTR_MAP_MAX_LENGTH /* Common groups */ #define MS_INT_CONSTRS (SLOT_08 | SLOT_09 | SLOT_10) #define MS_FLOAT_CONSTRS (SLOT_11 | SLOT_12 | SLOT_13) #define MS_STR_CONSTRS (SLOT_05 | SLOT_14 | SLOT_15) #define MS_BYTES_CONSTRS (SLOT_16 | SLOT_17) #define MS_ARRAY_CONSTRS (SLOT_18 | SLOT_19) #define MS_MAP_CONSTRS (SLOT_20 | SLOT_21) #define MS_TIME_CONSTRS (MS_CONSTR_TZ_AWARE | MS_CONSTR_TZ_NAIVE) typedef union TypeDetail { int64_t i64; double f64; Py_ssize_t py_ssize_t; void *pointer; } TypeDetail; typedef struct TypeNode { uint64_t types; TypeDetail details[]; } TypeNode; /* A simple extension of TypeNode to allow for static allocation */ typedef struct { uint64_t types; TypeDetail details[1]; } TypeNodeSimple; typedef struct { PyObject_HEAD PyObject *int_lookup; PyObject *str_lookup; bool literal_none; } LiteralInfo; typedef struct { PyObject *key; TypeNode *type; } TypedDictField; typedef struct { PyObject_VAR_HEAD Py_ssize_t nrequired; TypedDictField fields[]; } TypedDictInfo; typedef struct { PyObject *key; TypeNode *type; } DataclassField; typedef struct { PyObject_VAR_HEAD PyObject *class; PyObject *pre_init; PyObject *post_init; PyObject *defaults; DataclassField fields[]; } DataclassInfo; typedef struct { PyObject_VAR_HEAD PyObject *class; PyObject *defaults; TypeNode *types[]; } NamedTupleInfo; struct StructInfo; typedef struct { PyHeapTypeObject base; PyObject *struct_fields; PyObject *struct_defaults; Py_ssize_t *struct_offsets; PyObject *struct_encode_fields; struct StructInfo *struct_info; Py_ssize_t nkwonly; Py_ssize_t n_trailing_defaults; PyObject *struct_tag_field; /* str or NULL */ PyObject *struct_tag_value; /* str or NULL */ PyObject *struct_tag; /* True, str, or NULL */ PyObject *match_args; PyObject *rename; PyObject *post_init; Py_ssize_t hash_offset; /* 0 for no caching, otherwise offset */ int8_t frozen; int8_t order; int8_t eq; int8_t repr_omit_defaults; int8_t array_like; int8_t gc; int8_t omit_defaults; int8_t forbid_unknown_fields; } StructMetaObject; typedef struct StructInfo { PyObject_VAR_HEAD StructMetaObject *class; TypeNode *types[]; } StructInfo; typedef struct { PyObject_HEAD StructMetaObject *st_type; } StructConfig; static PyTypeObject LiteralInfo_Type; static PyTypeObject TypedDictInfo_Type; static PyTypeObject DataclassInfo_Type; static PyTypeObject NamedTupleInfo_Type; static PyTypeObject StructInfo_Type; static PyTypeObject StructMetaType; static PyTypeObject Ext_Type; static TypeNode* TypeNode_Convert(PyObject *type); static PyObject* StructInfo_Convert(PyObject*); static PyObject* TypedDictInfo_Convert(PyObject*); static PyObject* DataclassInfo_Convert(PyObject*); static PyObject* NamedTupleInfo_Convert(PyObject*); #define StructMeta_GET_FIELDS(s) (((StructMetaObject *)(s))->struct_fields) #define StructMeta_GET_NFIELDS(s) (PyTuple_GET_SIZE((((StructMetaObject *)(s))->struct_fields))) #define StructMeta_GET_DEFAULTS(s) (((StructMetaObject *)(s))->struct_defaults) #define StructMeta_GET_OFFSETS(s) (((StructMetaObject *)(s))->struct_offsets) #define OPT_UNSET -1 #define OPT_FALSE 0 #define OPT_TRUE 1 #define STRUCT_MERGE_OPTIONS(opt1, opt2) (((opt2) != OPT_UNSET) ? (opt2) : (opt1)) static MS_INLINE StructInfo * TypeNode_get_struct_info(TypeNode *type) { /* Struct types are always first */ return type->details[0].pointer; } static MS_INLINE Lookup * TypeNode_get_struct_union(TypeNode *type) { /* Struct union types are always first */ return type->details[0].pointer; } static MS_INLINE PyObject * TypeNode_get_custom(TypeNode *type) { /* Custom types can't be mixed with anything */ return type->details[0].pointer; } static MS_INLINE IntLookup * TypeNode_get_int_enum_or_literal(TypeNode *type) { Py_ssize_t i = ms_popcount(type->types & SLOT_00); return type->details[i].pointer; } static MS_INLINE StrLookup * TypeNode_get_str_enum_or_literal(TypeNode *type) { Py_ssize_t i = ms_popcount(type->types & (SLOT_00 | SLOT_01)); return type->details[i].pointer; } static MS_INLINE TypedDictInfo * TypeNode_get_typeddict_info(TypeNode *type) { Py_ssize_t i = ms_popcount(type->types & (SLOT_00 | SLOT_01 | SLOT_02)); return type->details[i].pointer; } static MS_INLINE DataclassInfo * TypeNode_get_dataclass_info(TypeNode *type) { Py_ssize_t i = ms_popcount(type->types & (SLOT_00 | SLOT_01 | SLOT_02)); return type->details[i].pointer; } static MS_INLINE NamedTupleInfo * TypeNode_get_namedtuple_info(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 ) ); return type->details[i].pointer; } static MS_INLINE PyObject * TypeNode_get_constr_str_regex(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 ) ); return type->details[i].pointer; } static MS_INLINE void TypeNode_get_dict(TypeNode *type, TypeNode **key, TypeNode **val) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 ) ); *key = type->details[i].pointer; *val = type->details[i + 1].pointer; } static MS_INLINE TypeNode * TypeNode_get_array(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 ) ); return type->details[i].pointer; } static MS_INLINE int64_t TypeNode_get_constr_int_min(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 ) ); return type->details[i].i64; } static MS_INLINE int64_t TypeNode_get_constr_int_max(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 ) ); return type->details[i].i64; } static MS_INLINE int64_t TypeNode_get_constr_int_multiple_of(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 ) ); return type->details[i].i64; } static MS_INLINE double TypeNode_get_constr_float_min(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 ) ); return type->details[i].f64; } static MS_INLINE double TypeNode_get_constr_float_max(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 ) ); return type->details[i].f64; } static MS_INLINE double TypeNode_get_constr_float_multiple_of(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 ) ); return type->details[i].f64; } static MS_INLINE Py_ssize_t TypeNode_get_constr_str_min_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_str_max_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_bytes_min_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_bytes_max_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_array_min_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 | SLOT_17 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_array_max_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 | SLOT_17 | SLOT_18 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_map_min_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 | SLOT_17 | SLOT_18 | SLOT_19 ) ); return type->details[i].py_ssize_t; } static MS_INLINE Py_ssize_t TypeNode_get_constr_map_max_length(TypeNode *type) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 | SLOT_17 | SLOT_18 | SLOT_19 | SLOT_20 ) ); return type->details[i].py_ssize_t; } static MS_INLINE void TypeNode_get_fixtuple(TypeNode *type, Py_ssize_t *offset, Py_ssize_t *size) { Py_ssize_t i = ms_popcount( type->types & ( SLOT_00 | SLOT_01 | SLOT_02 | SLOT_03 | SLOT_04 | SLOT_05 | SLOT_06 | SLOT_07 | SLOT_08 | SLOT_09 | SLOT_10 | SLOT_11 | SLOT_12 | SLOT_13 | SLOT_14 | SLOT_15 | SLOT_16 | SLOT_17 | SLOT_18 | SLOT_19 | SLOT_20 | SLOT_21 ) ); *size = type->details[i].py_ssize_t; *offset = i + 1; } static void TypeNode_get_traverse_ranges( TypeNode *type, Py_ssize_t *n_objects, Py_ssize_t *n_typenode, Py_ssize_t *fixtuple_offset, Py_ssize_t *fixtuple_size ) { Py_ssize_t n_obj = 0, n_type = 0, ft_offset = 0, ft_size = 0; /* Custom types cannot share a union with anything except `None` */ if (type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC)) { n_obj = 1; } else if (!(type->types & MS_TYPE_ANY)) { /* Number of pyobject details */ n_obj = ms_popcount( type->types & ( MS_TYPE_STRUCT | MS_TYPE_STRUCT_UNION | MS_TYPE_STRUCT_ARRAY | MS_TYPE_STRUCT_ARRAY_UNION | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL | MS_TYPE_ENUM | MS_TYPE_STRLITERAL | MS_TYPE_TYPEDDICT | MS_TYPE_DATACLASS | MS_TYPE_NAMEDTUPLE ) ); /* Number of typenode details */ n_type = ms_popcount( type->types & ( MS_TYPE_DICT | MS_TYPE_LIST | MS_TYPE_SET | MS_TYPE_FROZENSET | MS_TYPE_VARTUPLE ) ); if (type->types & MS_TYPE_FIXTUPLE) { TypeNode_get_fixtuple(type, &ft_offset, &ft_size); } } *n_objects = n_obj; *n_typenode = n_type; *fixtuple_offset = ft_offset; *fixtuple_size = ft_size; } static void TypeNode_Free(TypeNode *self) { if (self == NULL) return; Py_ssize_t n_obj, n_typenode, fixtuple_offset, fixtuple_size, i; TypeNode_get_traverse_ranges(self, &n_obj, &n_typenode, &fixtuple_offset, &fixtuple_size); for (i = 0; i < n_obj; i++) { PyObject *obj = (PyObject *)(self->details[i].pointer); Py_XDECREF(obj); } for (i = n_obj; i < (n_obj + n_typenode); i++) { TypeNode *node = (TypeNode *)(self->details[i].pointer); TypeNode_Free(node); } for (i = 0; i < fixtuple_size; i++) { TypeNode *node = (TypeNode *)(self->details[i + fixtuple_offset].pointer); TypeNode_Free(node); } PyMem_Free(self); } static int TypeNode_traverse(TypeNode *self, visitproc visit, void *arg) { if (self == NULL) return 0; Py_ssize_t n_obj, n_typenode, fixtuple_offset, fixtuple_size, i; TypeNode_get_traverse_ranges(self, &n_obj, &n_typenode, &fixtuple_offset, &fixtuple_size); for (i = 0; i < n_obj; i++) { PyObject *obj = (PyObject *)(self->details[i].pointer); Py_VISIT(obj); } for (i = n_obj; i < (n_obj + n_typenode); i++) { int out; TypeNode *node = (TypeNode *)(self->details[i].pointer); if ((out = TypeNode_traverse(node, visit, arg)) != 0) return out; } for (i = 0; i < fixtuple_size; i++) { int out; TypeNode *node = (TypeNode *)(self->details[i + fixtuple_offset].pointer); if ((out = TypeNode_traverse(node, visit, arg)) != 0) return out; } return 0; } static PyObject * typenode_simple_repr(TypeNode *self) { strbuilder builder = {" | ", 3}; if (self->types & (MS_TYPE_ANY | MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC) || self->types == 0) { return PyUnicode_FromString("any"); } if (self->types & MS_TYPE_BOOL) { if (!strbuilder_extend_literal(&builder, "bool")) return NULL; } if (self->types & (MS_TYPE_INT | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL)) { if (!strbuilder_extend_literal(&builder, "int")) return NULL; } if (self->types & MS_TYPE_FLOAT) { if (!strbuilder_extend_literal(&builder, "float")) return NULL; } if (self->types & (MS_TYPE_STR | MS_TYPE_ENUM | MS_TYPE_STRLITERAL)) { if (!strbuilder_extend_literal(&builder, "str")) return NULL; } if (self->types & (MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW)) { if (!strbuilder_extend_literal(&builder, "bytes")) return NULL; } if (self->types & MS_TYPE_DATETIME) { if (!strbuilder_extend_literal(&builder, "datetime")) return NULL; } if (self->types & MS_TYPE_DATE) { if (!strbuilder_extend_literal(&builder, "date")) return NULL; } if (self->types & MS_TYPE_TIME) { if (!strbuilder_extend_literal(&builder, "time")) return NULL; } if (self->types & MS_TYPE_TIMEDELTA) { if (!strbuilder_extend_literal(&builder, "duration")) return NULL; } if (self->types & MS_TYPE_UUID) { if (!strbuilder_extend_literal(&builder, "uuid")) return NULL; } if (self->types & MS_TYPE_DECIMAL) { if (!strbuilder_extend_literal(&builder, "decimal")) return NULL; } if (self->types & MS_TYPE_EXT) { if (!strbuilder_extend_literal(&builder, "ext")) return NULL; } if (self->types & ( MS_TYPE_STRUCT | MS_TYPE_STRUCT_UNION | MS_TYPE_TYPEDDICT | MS_TYPE_DATACLASS | MS_TYPE_DICT ) ) { if (!strbuilder_extend_literal(&builder, "object")) return NULL; } if ( self->types & ( MS_TYPE_STRUCT_ARRAY | MS_TYPE_STRUCT_ARRAY_UNION | MS_TYPE_LIST | MS_TYPE_SET | MS_TYPE_FROZENSET | MS_TYPE_VARTUPLE | MS_TYPE_FIXTUPLE | MS_TYPE_NAMEDTUPLE ) ) { if (!strbuilder_extend_literal(&builder, "array")) return NULL; } if (self->types & MS_TYPE_NONE) { if (!strbuilder_extend_literal(&builder, "null")) return NULL; } return strbuilder_build(&builder); } typedef struct { PyObject *gt; PyObject *ge; PyObject *lt; PyObject *le; PyObject *multiple_of; PyObject *regex; PyObject *min_length; PyObject *max_length; PyObject *tz; } Constraints; typedef struct { MsgspecState *mod; PyObject *context; uint64_t types; PyObject *struct_obj; PyObject *struct_info; PyObject *structs_set; PyObject *structs_lookup; PyObject *intenum_obj; PyObject *enum_obj; PyObject *custom_obj; PyObject *array_el_obj; PyObject *dict_key_obj; PyObject *dict_val_obj; PyObject *typeddict_obj; PyObject *dataclass_obj; PyObject *namedtuple_obj; PyObject *literals; PyObject *literal_int_values; PyObject *literal_int_lookup; PyObject *literal_str_values; PyObject *literal_str_lookup; bool literal_none; /* Constraints */ int64_t c_int_min; int64_t c_int_max; int64_t c_int_multiple_of; double c_float_min; double c_float_max; double c_float_multiple_of; PyObject *c_str_regex; Py_ssize_t c_str_min_length; Py_ssize_t c_str_max_length; Py_ssize_t c_bytes_min_length; Py_ssize_t c_bytes_max_length; Py_ssize_t c_array_min_length; Py_ssize_t c_array_max_length; Py_ssize_t c_map_min_length; Py_ssize_t c_map_max_length; } TypeNodeCollectState; static MS_INLINE bool constraints_is_empty(Constraints *self) { return ( self->gt == NULL && self->ge == NULL && self->lt == NULL && self->le == NULL && self->multiple_of == NULL && self->regex == NULL && self->min_length == NULL && self->max_length == NULL && self->tz == NULL ); } static int _set_constraint(PyObject *source, PyObject **target, const char *name, PyObject *type) { if (source == NULL) return 0; if (*target == NULL) { *target = source; return 0; } PyErr_Format( PyExc_TypeError, "Multiple `Meta` annotations setting `%s` found, " "type `%R` is invalid", name, type ); return -1; } static int constraints_update(Constraints *self, Meta *meta, PyObject *type) { #define set_constraint(field) do { \ if (_set_constraint(meta->field, &(self->field), #field, type) < 0) return -1; \ } while (0) set_constraint(gt); set_constraint(ge); set_constraint(lt); set_constraint(le); set_constraint(multiple_of); set_constraint(regex); set_constraint(min_length); set_constraint(max_length); set_constraint(tz); if (self->gt != NULL && self->ge != NULL) { PyErr_Format( PyExc_TypeError, "Cannot set both `gt` and `ge` on the same annotated type, " "type `%R` is invalid", type ); return -1; } if (self->lt != NULL && self->le != NULL) { PyErr_Format( PyExc_TypeError, "Cannot set both `lt` and `le` on the same annotated type, " "type `%R` is invalid", type ); return -1; } return 0; #undef set_constraint } enum constraint_kind { CK_INT = 0, CK_FLOAT = 1, CK_STR = 2, CK_BYTES = 3, CK_TIME = 4, CK_ARRAY = 5, CK_MAP = 6, CK_OTHER = 7, }; static int err_invalid_constraint(const char *name, const char *kind, PyObject *obj) { PyErr_Format( PyExc_TypeError, "Can only set `%s` on a %s type - type `%R` is invalid", name, kind, obj ); return -1; } static bool _constr_as_i64(PyObject *obj, int64_t *target, int offset) { int overflow; int64_t x = PyLong_AsLongLongAndOverflow(obj, &overflow); if (overflow != 0) { PyErr_SetString( PyExc_ValueError, "Integer bounds constraints (`ge`, `le`, ...) that don't fit in an " "int64 are currently not supported. If you need this feature, please " "open an issue on GitHub" ); return false; } else if (x == -1 && PyErr_Occurred()) { return false; } /* Do offsets for lt/gt */ if (offset == -1) { if (x == (-1LL << 63)) { PyErr_SetString(PyExc_ValueError, "lt <= -2**63 is not supported"); return false; } x -= 1; } else if (offset == 1) { if (x == ((1ULL << 63) - 1)) { PyErr_SetString(PyExc_ValueError, "gt >= 2**63 - 1 is not supported"); return false; } x += 1; } *target = x; return true; } static bool _constr_as_f64(PyObject *obj, double *target, int offset) { /* Use PyFloat_AsDouble to also handle integers */ double x = PyFloat_AsDouble(obj); /* Should never be hit, types already checked */ if (x == -1.0 && PyErr_Occurred()) return false; if (offset == 1) { x = nextafter(x, DBL_MAX); } else if (offset == -1) { x = nextafter(x, -DBL_MAX); } *target = x; return true; } static bool _constr_as_py_ssize_t(PyObject *obj, Py_ssize_t *target) { Py_ssize_t x = PyLong_AsSsize_t(obj); /* Should never be hit, types already checked */ if (x == -1 && PyErr_Occurred()) return false; *target = x; return true; } static int typenode_collect_constraints( TypeNodeCollectState *state, Constraints *constraints, enum constraint_kind kind, PyObject *obj ) { /* If no constraints, do nothing */ if (constraints == NULL) return 0; if (constraints_is_empty(constraints)) return 0; /* Check that the constraints are valid for the corresponding type */ if (kind != CK_INT && kind != CK_FLOAT) { if (constraints->gt != NULL) return err_invalid_constraint("gt", "numeric", obj); if (constraints->ge != NULL) return err_invalid_constraint("ge", "numeric", obj); if (constraints->lt != NULL) return err_invalid_constraint("lt", "numeric", obj); if (constraints->le != NULL) return err_invalid_constraint("le", "numeric", obj); if (constraints->multiple_of != NULL) return err_invalid_constraint("multiple_of", "numeric", obj); } if (kind != CK_STR) { if (constraints->regex != NULL) return err_invalid_constraint("pattern", "str", obj); } if (kind != CK_STR && kind != CK_BYTES && kind != CK_ARRAY && kind != CK_MAP) { if (constraints->min_length != NULL) return err_invalid_constraint("min_length", "str, bytes, or collection", obj); if (constraints->max_length != NULL) return err_invalid_constraint("max_length", "str, bytes, or collection", obj); } if (kind != CK_TIME) { if (constraints->tz != NULL) return err_invalid_constraint("tz", "datetime or time", obj); } /* Next attempt to fill in the state. */ if (kind == CK_INT) { if (constraints->gt != NULL) { state->types |= MS_CONSTR_INT_MIN; if (!_constr_as_i64(constraints->gt, &(state->c_int_min), 1)) return -1; } else if (constraints->ge != NULL) { state->types |= MS_CONSTR_INT_MIN; if (!_constr_as_i64(constraints->ge, &(state->c_int_min), 0)) return -1; } if (constraints->lt != NULL) { state->types |= MS_CONSTR_INT_MAX; if (!_constr_as_i64(constraints->lt, &(state->c_int_max), -1)) return -1; } else if (constraints->le != NULL) { state->types |= MS_CONSTR_INT_MAX; if (!_constr_as_i64(constraints->le, &(state->c_int_max), 0)) return -1; } if (constraints->multiple_of != NULL) { state->types |= MS_CONSTR_INT_MULTIPLE_OF; if (!_constr_as_i64(constraints->multiple_of, &(state->c_int_multiple_of), 0)) return -1; } } else if (kind == CK_FLOAT) { if (constraints->gt != NULL) { state->types |= MS_CONSTR_FLOAT_GT; if (!_constr_as_f64(constraints->gt, &(state->c_float_min), 1)) return -1; } else if (constraints->ge != NULL) { state->types |= MS_CONSTR_FLOAT_GE; if (!_constr_as_f64(constraints->ge, &(state->c_float_min), 0)) return -1; } if (constraints->lt != NULL) { state->types |= MS_CONSTR_FLOAT_LT; if (!_constr_as_f64(constraints->lt, &(state->c_float_max), -1)) return -1; } else if (constraints->le != NULL) { state->types |= MS_CONSTR_FLOAT_LE; if (!_constr_as_f64(constraints->le, &(state->c_float_max), 0)) return -1; } if (constraints->multiple_of != NULL) { state->types |= MS_CONSTR_FLOAT_MULTIPLE_OF; if (!_constr_as_f64(constraints->multiple_of, &(state->c_float_multiple_of), 0)) return -1; } } else if (kind == CK_STR) { if (constraints->regex != NULL) { state->types |= MS_CONSTR_STR_REGEX; Py_INCREF(constraints->regex); state->c_str_regex = constraints->regex; } if (constraints->min_length != NULL) { state->types |= MS_CONSTR_STR_MIN_LENGTH; if (!_constr_as_py_ssize_t(constraints->min_length, &(state->c_str_min_length))) return -1; } if (constraints->max_length != NULL) { state->types |= MS_CONSTR_STR_MAX_LENGTH; if (!_constr_as_py_ssize_t(constraints->max_length, &(state->c_str_max_length))) return -1; } } else if (kind == CK_BYTES) { if (constraints->min_length != NULL) { state->types |= MS_CONSTR_BYTES_MIN_LENGTH; if (!_constr_as_py_ssize_t(constraints->min_length, &(state->c_bytes_min_length))) return -1; } if (constraints->max_length != NULL) { state->types |= MS_CONSTR_BYTES_MAX_LENGTH; if (!_constr_as_py_ssize_t(constraints->max_length, &(state->c_bytes_max_length))) return -1; } } else if (kind == CK_TIME) { if (constraints->tz != NULL) { if (constraints->tz == Py_True) { state->types |= MS_CONSTR_TZ_AWARE; } else { state->types |= MS_CONSTR_TZ_NAIVE; } } } else if (kind == CK_ARRAY) { if (constraints->min_length != NULL) { state->types |= MS_CONSTR_ARRAY_MIN_LENGTH; if (!_constr_as_py_ssize_t(constraints->min_length, &(state->c_array_min_length))) return -1; } if (constraints->max_length != NULL) { state->types |= MS_CONSTR_ARRAY_MAX_LENGTH; if (!_constr_as_py_ssize_t(constraints->max_length, &(state->c_array_max_length))) return -1; } } else if (kind == CK_MAP) { if (constraints->min_length != NULL) { state->types |= MS_CONSTR_MAP_MIN_LENGTH; if (!_constr_as_py_ssize_t(constraints->min_length, &(state->c_map_min_length))) return -1; } if (constraints->max_length != NULL) { state->types |= MS_CONSTR_MAP_MAX_LENGTH; if (!_constr_as_py_ssize_t(constraints->max_length, &(state->c_map_max_length))) return -1; } } return 0; } static int typenode_collect_type(TypeNodeCollectState*, PyObject*); static TypeNode * typenode_from_collect_state(TypeNodeCollectState *state) { Py_ssize_t e_ind, n_extra = 0, fixtuple_size = 0; bool has_fixtuple = false; n_extra = ms_popcount( state->types & ( MS_TYPE_STRUCT | MS_TYPE_STRUCT_ARRAY | MS_TYPE_STRUCT_UNION | MS_TYPE_STRUCT_ARRAY_UNION | MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL | MS_TYPE_ENUM | MS_TYPE_STRLITERAL | MS_TYPE_TYPEDDICT | MS_TYPE_DATACLASS | MS_TYPE_NAMEDTUPLE | MS_CONSTR_STR_REGEX | MS_TYPE_DICT | MS_TYPE_LIST | MS_TYPE_SET | MS_TYPE_FROZENSET | MS_TYPE_VARTUPLE | MS_CONSTR_INT_MIN | MS_CONSTR_INT_MAX | MS_CONSTR_INT_MULTIPLE_OF | MS_CONSTR_FLOAT_GT | MS_CONSTR_FLOAT_GE | MS_CONSTR_FLOAT_LT | MS_CONSTR_FLOAT_LE | MS_CONSTR_FLOAT_MULTIPLE_OF | MS_CONSTR_STR_MIN_LENGTH | MS_CONSTR_STR_MAX_LENGTH | MS_CONSTR_BYTES_MIN_LENGTH | MS_CONSTR_BYTES_MAX_LENGTH | MS_CONSTR_ARRAY_MIN_LENGTH | MS_CONSTR_ARRAY_MAX_LENGTH | MS_CONSTR_MAP_MIN_LENGTH | MS_CONSTR_MAP_MAX_LENGTH ) ); if (state->types & MS_TYPE_FIXTUPLE) { has_fixtuple = true; fixtuple_size = PyTuple_GET_SIZE(state->array_el_obj); n_extra += fixtuple_size + 1; } if (n_extra == 0) { TypeNode *out = (TypeNode *)PyMem_Malloc(sizeof(TypeNode)); if (out == NULL) { PyErr_NoMemory(); return NULL; } out->types = state->types; return out; } /* Use calloc so that `out->details` is initialized, easing cleanup on error */ TypeNode *out = (TypeNode *)PyMem_Calloc( 1, sizeof(TypeNode) + n_extra * sizeof(TypeDetail) ); if (out == NULL) { PyErr_NoMemory(); return NULL; } out->types = state->types; /* Populate `details` fields in order */ e_ind = 0; if (state->custom_obj != NULL) { Py_INCREF(state->custom_obj); /* Add `Any` to the type node, so the individual decode functions can * check for `Any` alone, and only have to handle custom types in one * location (e.g. `mpack_decode`). */ out->types |= MS_TYPE_ANY; out->details[e_ind++].pointer = state->custom_obj; } if (state->struct_info != NULL) { Py_INCREF(state->struct_info); out->details[e_ind++].pointer = state->struct_info; } if (state->structs_lookup != NULL) { Py_INCREF(state->structs_lookup); out->details[e_ind++].pointer = state->structs_lookup; } if (state->intenum_obj != NULL) { PyObject *lookup = PyObject_GetAttr(state->intenum_obj, state->mod->str___msgspec_cache__); if (lookup == NULL) { /* IntLookup isn't created yet, create and store on enum class */ PyErr_Clear(); PyObject *member_map = PyObject_GetAttr(state->intenum_obj, state->mod->str__value2member_map_); if (member_map == NULL) goto error; lookup = IntLookup_New(member_map, NULL, state->intenum_obj, false); Py_DECREF(member_map); if (lookup == NULL) goto error; if (PyObject_SetAttr(state->intenum_obj, state->mod->str___msgspec_cache__, lookup) < 0) { Py_DECREF(lookup); goto error; } } else if (!Lookup_IsIntLookup(lookup)) { /* the lookup attribute has been overwritten, error */ Py_DECREF(lookup); PyErr_Format( PyExc_RuntimeError, "%R.__msgspec_cache__ has been overwritten", state->intenum_obj ); goto error; } out->details[e_ind++].pointer = lookup; } if (state->literal_int_lookup != NULL) { Py_INCREF(state->literal_int_lookup); out->details[e_ind++].pointer = state->literal_int_lookup; } if (state->enum_obj != NULL) { PyObject *lookup = PyObject_GetAttr(state->enum_obj, state->mod->str___msgspec_cache__); if (lookup == NULL) { /* StrLookup isn't created yet, create and store on enum class */ PyErr_Clear(); PyObject *member_map = PyObject_GetAttr(state->enum_obj, state->mod->str__value2member_map_); if (member_map == NULL) goto error; lookup = StrLookup_New(member_map, NULL, state->enum_obj, false); Py_DECREF(member_map); if (lookup == NULL) goto error; if (PyObject_SetAttr(state->enum_obj, state->mod->str___msgspec_cache__, lookup) < 0) { Py_DECREF(lookup); goto error; } } else if (Py_TYPE(lookup) != &StrLookup_Type) { /* the lookup attribute has been overwritten, error */ Py_DECREF(lookup); PyErr_Format( PyExc_RuntimeError, "%R.__msgspec_cache__ has been overwritten", state->enum_obj ); goto error; } out->details[e_ind++].pointer = lookup; } if (state->literal_str_lookup != NULL) { Py_INCREF(state->literal_str_lookup); out->details[e_ind++].pointer = state->literal_str_lookup; } if (state->typeddict_obj != NULL) { PyObject *info = TypedDictInfo_Convert(state->typeddict_obj); if (info == NULL) goto error; out->details[e_ind++].pointer = info; } if (state->dataclass_obj != NULL) { PyObject *info = DataclassInfo_Convert(state->dataclass_obj); if (info == NULL) goto error; out->details[e_ind++].pointer = info; } if (state->namedtuple_obj != NULL) { PyObject *info = NamedTupleInfo_Convert(state->namedtuple_obj); if (info == NULL) goto error; out->details[e_ind++].pointer = info; } if (state->types & MS_CONSTR_STR_REGEX) { Py_INCREF(state->c_str_regex); out->details[e_ind++].pointer = state->c_str_regex; } if (state->dict_key_obj != NULL) { TypeNode *temp = TypeNode_Convert(state->dict_key_obj); if (temp == NULL) goto error; out->details[e_ind++].pointer = temp; temp = TypeNode_Convert(state->dict_val_obj); if (temp == NULL) goto error; out->details[e_ind++].pointer = temp; } if (state->array_el_obj != NULL) { if (has_fixtuple) { out->details[e_ind++].py_ssize_t = fixtuple_size; for (Py_ssize_t i = 0; i < fixtuple_size; i++) { TypeNode *temp = TypeNode_Convert( PyTuple_GET_ITEM(state->array_el_obj, i) ); if (temp == NULL) goto error; out->details[e_ind++].pointer = temp; } } else { TypeNode *temp = TypeNode_Convert(state->array_el_obj); if (temp == NULL) goto error; out->details[e_ind++].pointer = temp; } } if (state->types & MS_CONSTR_INT_MIN) { out->details[e_ind++].i64 = state->c_int_min; } if (state->types & MS_CONSTR_INT_MAX) { out->details[e_ind++].i64 = state->c_int_max; } if (state->types & MS_CONSTR_INT_MULTIPLE_OF) { out->details[e_ind++].i64 = state->c_int_multiple_of; } if (state->types & (MS_CONSTR_FLOAT_GT | MS_CONSTR_FLOAT_GE)) { out->details[e_ind++].f64 = state->c_float_min; } if (state->types & (MS_CONSTR_FLOAT_LT | MS_CONSTR_FLOAT_LE)) { out->details[e_ind++].f64 = state->c_float_max; } if (state->types & MS_CONSTR_FLOAT_MULTIPLE_OF) { out->details[e_ind++].f64 = state->c_float_multiple_of; } if (state->types & MS_CONSTR_STR_MIN_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_str_min_length; } if (state->types & MS_CONSTR_STR_MAX_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_str_max_length; } if (state->types & MS_CONSTR_BYTES_MIN_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_bytes_min_length; } if (state->types & MS_CONSTR_BYTES_MAX_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_bytes_max_length; } if (state->types & MS_CONSTR_ARRAY_MIN_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_array_min_length; } if (state->types & MS_CONSTR_ARRAY_MAX_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_array_max_length; } if (state->types & MS_CONSTR_MAP_MIN_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_map_min_length; } if (state->types & MS_CONSTR_MAP_MAX_LENGTH) { out->details[e_ind++].py_ssize_t = state->c_map_max_length; } return (TypeNode *)out; error: TypeNode_Free((TypeNode *)out); return NULL; } static bool get_msgspec_cache(MsgspecState *mod, PyObject *obj, PyTypeObject *type, PyObject **out) { PyObject *cached = PyObject_GenericGetAttr(obj, mod->str___msgspec_cache__); if (cached != NULL) { if (Py_TYPE(cached) != type) { Py_DECREF(cached); PyErr_Format( PyExc_RuntimeError, "%R.__msgspec_cache__ has been overwritten", obj ); } else { *out = cached; } return true; } PyErr_Clear(); return false; } static int typenode_collect_err_unique(TypeNodeCollectState *state, const char *kind) { PyErr_Format( PyExc_TypeError, "Type unions may not contain more than one %s type - " "type `%R` is not supported", kind, state->context ); return -1; } static int typenode_collect_check_invariants(TypeNodeCollectState *state) { /* If a custom type is used, this node may only contain that type and `None */ if ( state->custom_obj != NULL && state->types & ~(MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC | MS_TYPE_NONE) ) { PyErr_Format( PyExc_TypeError, "Type unions containing a custom type may not contain any " "additional types other than `None` - type `%R` is not supported", state->context ); return -1; } /* Ensure at most one array-like type in the union */ if (ms_popcount( state->types & ( MS_TYPE_STRUCT_ARRAY | MS_TYPE_STRUCT_ARRAY_UNION | MS_TYPE_LIST | MS_TYPE_SET | MS_TYPE_FROZENSET | MS_TYPE_VARTUPLE | MS_TYPE_FIXTUPLE | MS_TYPE_NAMEDTUPLE ) ) > 1 ) { PyErr_Format( PyExc_TypeError, "Type unions may not contain more than one array-like type " "(`Struct(array_like=True)`, `list`, `set`, `frozenset`, `tuple`, " "`NamedTuple`) - type `%R` is not supported", state->context ); return -1; } /* Ensure at most one dict-like type in the union */ int ndictlike = ms_popcount( state->types & ( MS_TYPE_STRUCT | MS_TYPE_STRUCT_UNION | MS_TYPE_TYPEDDICT | MS_TYPE_DATACLASS ) ); if (state->types & MS_TYPE_DICT) { ndictlike++; } if (ndictlike > 1) { PyErr_Format( PyExc_TypeError, "Type unions may not contain more than one dict-like type " "(`Struct`, `dict`, `TypedDict`, `dataclass`) - type `%R` " "is not supported", state->context ); return -1; } /* If int & int literals are both present, drop literals */ if (state->types & MS_TYPE_INT && state->literal_int_lookup) { state->types &= ~MS_TYPE_INTLITERAL; Py_CLEAR(state->literal_int_lookup); } /* If str & str literals are both present, drop literals */ if (state->types & MS_TYPE_STR && state->literal_str_lookup) { state->types &= ~MS_TYPE_STRLITERAL; Py_CLEAR(state->literal_str_lookup); } /* Ensure int-like types don't conflict */ if (ms_popcount(state->types & (MS_TYPE_INT | MS_TYPE_INTLITERAL | MS_TYPE_INTENUM)) > 1) { PyErr_Format( PyExc_TypeError, "Type unions may not contain more than one int-like type (`int`, " "`Enum`, `Literal[int values]`) - type `%R` is not supported", state->context ); return -1; } /* Ensure str-like types don't conflict */ if (ms_popcount( state->types & ( MS_TYPE_STR | MS_TYPE_STRLITERAL | MS_TYPE_ENUM | MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW | MS_TYPE_DATETIME | MS_TYPE_DATE | MS_TYPE_TIME | MS_TYPE_TIMEDELTA | MS_TYPE_UUID | MS_TYPE_DECIMAL ) ) > 1 ) { PyErr_Format( PyExc_TypeError, "Type unions may not contain more than one str-like type (`str`, " "`Enum`, `Literal[str values]`, `datetime`, `date`, `time`, `timedelta`, " "`uuid`, `decimal`, `bytes`, `bytearray`) - type `%R` is not supported", state->context ); return -1; } return 0; } static int typenode_collect_enum(TypeNodeCollectState *state, PyObject *obj) { bool is_intenum; if (PyType_IsSubtype((PyTypeObject *)obj, &PyLong_Type)) { is_intenum = true; } else if (PyType_IsSubtype((PyTypeObject *)obj, &PyUnicode_Type)) { is_intenum = false; } else { PyObject *members = PyObject_GetAttr(obj, state->mod->str__value2member_map_); if (members == NULL) return -1; if (!PyDict_Check(members)) { Py_DECREF(members); PyErr_SetString( PyExc_RuntimeError, "Expected _value2member_map_ to be a dict" ); return -1; } /* Traverse _value2member_map_ to determine key type */ Py_ssize_t pos = 0; PyObject *key; bool all_ints = true; bool all_strs = true; while (PyDict_Next(members, &pos, &key, NULL)) { all_ints &= PyLong_CheckExact(key); all_strs &= PyUnicode_CheckExact(key); } Py_CLEAR(members); if (all_ints) { is_intenum = true; } else if (all_strs) { is_intenum = false; } else { PyErr_Format( PyExc_TypeError, "Enums must contain either all str or all int values - " "type `%R` is not supported", state->context ); return -1; } } if (is_intenum) { if (state->intenum_obj != NULL) { return typenode_collect_err_unique(state, "int enum"); } state->types |= MS_TYPE_INTENUM; Py_INCREF(obj); state->intenum_obj = obj; } else { if (state->enum_obj != NULL) { return typenode_collect_err_unique(state, "str enum"); } state->types |= MS_TYPE_ENUM; Py_INCREF(obj); state->enum_obj = obj; } return 0; } static int typenode_collect_dict(TypeNodeCollectState *state, PyObject *key, PyObject *val) { if (state->dict_key_obj != NULL) { return typenode_collect_err_unique(state, "dict"); } state->types |= MS_TYPE_DICT; Py_INCREF(key); state->dict_key_obj = key; Py_INCREF(val); state->dict_val_obj = val; return 0; } static int typenode_collect_array(TypeNodeCollectState *state, uint64_t type, PyObject *obj) { if (state->array_el_obj != NULL) { return typenode_collect_err_unique( state, "array-like (list, set, tuple)" ); } state->types |= type; Py_INCREF(obj); state->array_el_obj = obj; return 0; } static int typenode_collect_custom(TypeNodeCollectState *state, uint64_t type, PyObject *obj) { if (state->custom_obj != NULL) { return typenode_collect_err_unique(state, "custom"); } state->types |= type; Py_INCREF(obj); state->custom_obj = obj; return 0; } static int typenode_collect_typevar(TypeNodeCollectState *state, PyObject *obj) { int out; PyObject *bound = PyObject_GetAttr(obj, state->mod->str___bound__); if (bound == NULL) return -1; if (bound == Py_None) { Py_DECREF(bound); /* No `bound`, check for constraints */ PyObject *constraints = PyObject_GetAttr(obj, state->mod->str___constraints__); if (constraints == NULL) return -1; if ( !( (constraints == Py_None) || (PyTuple_CheckExact(constraints) && (PyTuple_GET_SIZE(constraints) == 0)) ) ) { PyErr_Format( PyExc_TypeError, "Unbound TypeVar `%R` has constraints `%R` - constraints are " "currently unsupported. If possible, either explicitly bind " "the parameter, or use `bound` instead of constraints.", obj, constraints ); Py_DECREF(constraints); return -1; } Py_DECREF(constraints); /* No constraints either, use `Any` */ out = typenode_collect_type(state, state->mod->typing_any); } else { /* Bound, substitute in the bound type */ out = typenode_collect_type(state, bound); Py_DECREF(bound); } return out; } static int typenode_collect_struct(TypeNodeCollectState *state, PyObject *obj) { if (state->struct_obj == NULL && state->structs_set == NULL) { /* First struct found, store it directly */ Py_INCREF(obj); state->struct_obj = obj; } else { if (state->structs_set == NULL) { /* Second struct found, create a set and move the existing struct there */ state->structs_set = PyFrozenSet_New(NULL); if (state->structs_set == NULL) return -1; if (PySet_Add(state->structs_set, state->struct_obj) < 0) return -1; Py_CLEAR(state->struct_obj); } if (PySet_Add(state->structs_set, obj) < 0) return -1; } return 0; } static int typenode_collect_typeddict(TypeNodeCollectState *state, PyObject *obj) { if (state->typeddict_obj != NULL) { return typenode_collect_err_unique(state, "TypedDict"); } state->types |= MS_TYPE_TYPEDDICT; Py_INCREF(obj); state->typeddict_obj = obj; return 0; } static int typenode_collect_dataclass(TypeNodeCollectState *state, PyObject *obj) { if (state->dataclass_obj != NULL) { return typenode_collect_err_unique(state, "dataclass or attrs"); } state->types |= MS_TYPE_DATACLASS; Py_INCREF(obj); state->dataclass_obj = obj; return 0; } static int typenode_collect_namedtuple(TypeNodeCollectState *state, PyObject *obj) { if (state->namedtuple_obj != NULL) { return typenode_collect_err_unique(state, "NamedTuple"); } state->types |= MS_TYPE_NAMEDTUPLE; Py_INCREF(obj); state->namedtuple_obj = obj; return 0; } static int typenode_collect_literal(TypeNodeCollectState *state, PyObject *literal) { PyObject *args = PyObject_GetAttr(literal, state->mod->str___args__); /* This should never happen, since we know this is a `Literal` object */ if (args == NULL) return -1; Py_ssize_t size = PyTuple_GET_SIZE(args); if (size < 0) return -1; if (size == 0) { PyErr_Format( PyExc_TypeError, "Literal types must have at least one item, %R is invalid", literal ); return -1; } for (Py_ssize_t i = 0; i < size; i++) { PyObject *obj = PyTuple_GET_ITEM(args, i); PyTypeObject *type = Py_TYPE(obj); if (obj == Py_None || obj == NONE_TYPE) { state->literal_none = true; } else if (type == &PyLong_Type) { if (state->literal_int_values == NULL) { state->literal_int_values = PySet_New(NULL); if (state->literal_int_values == NULL) goto error; } if (PySet_Add(state->literal_int_values, obj) < 0) goto error; } else if (type == &PyUnicode_Type) { if (state->literal_str_values == NULL) { state->literal_str_values = PySet_New(NULL); if (state->literal_str_values == NULL) goto error; } if (PySet_Add(state->literal_str_values, obj) < 0) goto error; } else { /* Check for nested Literal */ PyObject *origin = PyObject_GetAttr(obj, state->mod->str___origin__); if (origin == NULL) { PyErr_Clear(); goto invalid; } else if (origin != state->mod->typing_literal) { Py_DECREF(origin); goto invalid; } Py_DECREF(origin); if (typenode_collect_literal(state, obj) < 0) goto error; } } Py_DECREF(args); return 0; invalid: PyErr_Format( PyExc_TypeError, "Literal may only contain None/integers/strings - %R is not supported", literal ); error: Py_DECREF(args); return -1; } static int typenode_collect_convert_literals(TypeNodeCollectState *state) { if (state->literals == NULL) { /* Nothing to do */ return 0; } Py_ssize_t n = PyList_GET_SIZE(state->literals); if (n == 1) { PyObject *literal = PyList_GET_ITEM(state->literals, 0); PyObject *cached = NULL; if (get_msgspec_cache(state->mod, literal, &LiteralInfo_Type, &cached)) { if (cached == NULL) return -1; LiteralInfo *info = (LiteralInfo *)cached; if (info->int_lookup != NULL) { state->types |= MS_TYPE_INTLITERAL; Py_INCREF(info->int_lookup); state->literal_int_lookup = info->int_lookup; } if (info->str_lookup != NULL) { state->types |= MS_TYPE_STRLITERAL; Py_INCREF(info->str_lookup); state->literal_str_lookup = info->str_lookup; } if (info->literal_none) { state->types |= MS_TYPE_NONE; } Py_DECREF(cached); return 0; } } /* Collect all values in all literals */ for (Py_ssize_t i = 0; i < n; i++) { PyObject *literal = PyList_GET_ITEM(state->literals, i); if (typenode_collect_literal(state, literal) < 0) return -1; } /* Convert values to lookup objects (if values exist for each type) */ if (state->literal_int_values != NULL) { state->types |= MS_TYPE_INTLITERAL; state->literal_int_lookup = IntLookup_New( state->literal_int_values, NULL, NULL, false ); if (state->literal_int_lookup == NULL) return -1; } if (state->literal_str_values != NULL) { state->types |= MS_TYPE_STRLITERAL; state->literal_str_lookup = StrLookup_New( state->literal_str_values, NULL, NULL, false ); if (state->literal_str_lookup == NULL) return -1; } if (state->literal_none) { state->types |= MS_TYPE_NONE; } if (n == 1) { /* A single `Literal` object, cache the lookups on it */ LiteralInfo *info = PyObject_GC_New(LiteralInfo, &LiteralInfo_Type); if (info == NULL) return -1; Py_XINCREF(state->literal_int_lookup); info->int_lookup = state->literal_int_lookup; Py_XINCREF(state->literal_str_lookup); info->str_lookup = state->literal_str_lookup; info->literal_none = state->literal_none; PyObject_GC_Track(info); PyObject *literal = PyList_GET_ITEM(state->literals, 0); int status = PyObject_SetAttr( literal, state->mod->str___msgspec_cache__, (PyObject *)info ); Py_DECREF(info); return status; } return 0; } static int typenode_collect_convert_structs(TypeNodeCollectState *state) { if (state->struct_obj == NULL && state->structs_set == NULL) { return 0; } else if (state->struct_obj != NULL) { /* Single struct */ state->struct_info = StructInfo_Convert(state->struct_obj); if (state->struct_info == NULL) return -1; if (((StructInfo *)state->struct_info)->class->array_like == OPT_TRUE) { state->types |= MS_TYPE_STRUCT_ARRAY; } else { state->types |= MS_TYPE_STRUCT; } return 0; } /* Multiple structs. * * Try looking the structs_set up in the cache first, to avoid building a * new one below. */ PyObject *lookup = PyDict_GetItem( state->mod->struct_lookup_cache, state->structs_set ); if (lookup != NULL) { /* Lookup was in the cache, update the state and return */ Py_INCREF(lookup); state->structs_lookup = lookup; if (Lookup_array_like(lookup)) { state->types |= MS_TYPE_STRUCT_ARRAY_UNION; } else { state->types |= MS_TYPE_STRUCT_UNION; } return 0; } /* Here we check a number of restrictions before building a lookup table * from struct tags to their matching classes. * * Validation checks: * - All structs in the set are tagged. * - All structs in the set have the same `array_like` status * - All structs in the set have the same `tag_field` * - All structs in the set have a unique `tag_value` * * If any of these checks fails, an appropriate error is returned. */ PyObject *tag_mapping = NULL, *tag_field = NULL, *set_iter = NULL, *set_item = NULL; PyObject *struct_info = NULL; bool array_like = false; bool tags_are_strings = true; int status = -1; tag_mapping = PyDict_New(); if (tag_mapping == NULL) goto cleanup; set_iter = PyObject_GetIter(state->structs_set); while ((set_item = PyIter_Next(set_iter))) { struct_info = StructInfo_Convert(set_item); if (struct_info == NULL) goto cleanup; StructMetaObject *struct_type = ((StructInfo *)struct_info)->class; PyObject *item_tag_field = struct_type->struct_tag_field; PyObject *item_tag_value = struct_type->struct_tag_value; bool item_array_like = struct_type->array_like == OPT_TRUE; if (item_tag_value == NULL) { PyErr_Format( PyExc_TypeError, "If a type union contains multiple Struct types, all Struct " "types must be tagged (via `tag` or `tag_field` kwarg) - type " "`%R` is not supported", state->context ); goto cleanup; } if (tag_field == NULL) { array_like = struct_type->array_like == OPT_TRUE; tag_field = struct_type->struct_tag_field; tags_are_strings = PyUnicode_CheckExact(item_tag_value); } else { if (array_like != item_array_like) { PyErr_Format( PyExc_TypeError, "Type unions may not contain Struct types with `array_like=True` " "and `array_like=False` - type `%R` is not supported", state->context ); goto cleanup; } if (tags_are_strings != PyUnicode_CheckExact(item_tag_value)) { PyErr_Format( PyExc_TypeError, "Type unions may not contain Struct types with both `int` " "and `str` tags - type `%R` is not supported", state->context ); goto cleanup; } int compare = PyUnicode_Compare(item_tag_field, tag_field); if (compare == -1 && PyErr_Occurred()) goto cleanup; if (compare != 0) { PyErr_Format( PyExc_TypeError, "If a type union contains multiple Struct types, all Struct types " "must have the same `tag_field` - type `%R` is not supported", state->context ); goto cleanup; } } if (PyDict_GetItem(tag_mapping, item_tag_value) != NULL) { PyErr_Format( PyExc_TypeError, "If a type union contains multiple Struct types, all Struct types " "must have unique `tag` values - type `%R` is not supported", state->context ); goto cleanup; } int ok = PyDict_SetItem(tag_mapping, item_tag_value, struct_info) == 0; Py_CLEAR(struct_info); if (!ok) goto cleanup; } /* Build a lookup from tag_value -> struct_info */ if (tags_are_strings) { lookup = StrLookup_New(tag_mapping, tag_field, NULL, array_like); } else { lookup = IntLookup_New(tag_mapping, tag_field, NULL, array_like); } if (lookup == NULL) goto cleanup; state->structs_lookup = lookup; /* Check if the cache is full, if so clear the oldest item */ if (PyDict_GET_SIZE(state->mod->struct_lookup_cache) == 64) { PyObject *key; Py_ssize_t pos = 0; if (PyDict_Next(state->mod->struct_lookup_cache, &pos, &key, NULL)) { if (PyDict_DelItem(state->mod->struct_lookup_cache, key) < 0) { goto cleanup; } } } /* Add the new lookup to the cache */ if (PyDict_SetItem(state->mod->struct_lookup_cache, state->structs_set, lookup) < 0) { goto cleanup; } /* Update the `types` */ if (array_like) { state->types |= MS_TYPE_STRUCT_ARRAY_UNION; } else { state->types |= MS_TYPE_STRUCT_UNION; } status = 0; cleanup: Py_XDECREF(set_iter); Py_XDECREF(tag_mapping); Py_XDECREF(struct_info); return status; } static void typenode_collect_clear_state(TypeNodeCollectState *state) { Py_CLEAR(state->struct_obj); Py_CLEAR(state->struct_info); Py_CLEAR(state->structs_set); Py_CLEAR(state->structs_lookup); Py_CLEAR(state->intenum_obj); Py_CLEAR(state->enum_obj); Py_CLEAR(state->custom_obj); Py_CLEAR(state->array_el_obj); Py_CLEAR(state->dict_key_obj); Py_CLEAR(state->dict_val_obj); Py_CLEAR(state->typeddict_obj); Py_CLEAR(state->dataclass_obj); Py_CLEAR(state->namedtuple_obj); Py_CLEAR(state->literals); Py_CLEAR(state->literal_int_values); Py_CLEAR(state->literal_int_lookup); Py_CLEAR(state->literal_str_values); Py_CLEAR(state->literal_str_lookup); Py_CLEAR(state->c_str_regex); } /* This decomposes an input type `obj`, stripping out any "wrapper" types * (Annotated/NewType). It returns the following components: * * - `t` (return value): the first "concrete" type found in the type tree. * - `origin`: `__origin__` on `t` (if present), with a few normalizations * applied to work around differences in type spelling (List vs list) and * python version. * - `args`: `__args__` on `t` (if present) * - `constraints`: Any constraints from `Meta` objects annotated on the type */ static PyObject * typenode_origin_args_metadata( TypeNodeCollectState *state, PyObject *obj, PyObject **out_origin, PyObject **out_args, Constraints *constraints ) { PyObject *origin = NULL, *args = NULL; PyObject *t = obj; Py_INCREF(t); /* First strip out meta "wrapper" types (Annotated, NewType, Final) */ while (true) { assert(t != NULL && origin == NULL && args == NULL); /* Before inspecting attributes, try looking up the object in the * abstract -> concrete mapping. If present, this is an unparametrized * collection of some form. This helps avoid compatibility issues in * Python 3.8, where unparametrized collections still have __args__. */ origin = PyDict_GetItemWithError(state->mod->concrete_types, t); if (origin != NULL) { Py_INCREF(origin); break; } else { /* Ignore all errors in this initial check */ PyErr_Clear(); } /* If `t` is a type instance, no need to inspect further */ if (PyType_CheckExact(t)) { /* t is a concrete type object. */ break; } origin = PyObject_GetAttr(t, state->mod->str___origin__); if (origin != NULL) { if (Py_TYPE(t) == (PyTypeObject *)(state->mod->typing_annotated_alias)) { /* Handle typing.Annotated[...] */ PyObject *metadata = PyObject_GetAttr(t, state->mod->str___metadata__); if (metadata == NULL) goto error; for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(metadata); i++) { PyObject *annot = PyTuple_GET_ITEM(metadata, i); if (Py_TYPE(annot) == &Meta_Type) { if (constraints_update(constraints, (Meta *)annot, obj) < 0) { Py_DECREF(metadata); goto error; } } } Py_DECREF(metadata); Py_DECREF(t); t = origin; origin = NULL; continue; } else { args = PyObject_GetAttr(t, state->mod->str___args__); if (args != NULL) { if (!PyTuple_Check(args)) { PyErr_SetString(PyExc_TypeError, "__args__ must be a tuple"); goto error; } if (origin == state->mod->typing_final) { /* Handle typing.Final[...] */ PyObject *temp = PyTuple_GetItem(args, 0); if (temp == NULL) goto error; Py_CLEAR(args); Py_CLEAR(origin); Py_DECREF(t); Py_INCREF(temp); t = temp; continue; } /* Check for parametrized TypeAliasType if Python 3.12+ */ #if PY312_PLUS if (Py_TYPE(origin) == (PyTypeObject *)(state->mod->typing_typealiastype)) { PyObject *value = PyObject_GetAttr(origin, state->mod->str___value__); if (value == NULL) goto error; PyObject *temp = PyObject_GetItem(value, args); Py_DECREF(value); if (temp == NULL) goto error; Py_CLEAR(args); Py_CLEAR(origin); Py_DECREF(t); t = temp; continue; } #endif } else { /* Custom non-parametrized generics won't have __args__ * set. Ignore __args__ error */ PyErr_Clear(); } /* Lookup __origin__ in the mapping, in case it's a supported * abstract type. Equal to `origin = mapping.get(origin, origin)` */ PyObject *temp = PyDict_GetItem(state->mod->concrete_types, origin); if (temp != NULL) { Py_DECREF(origin); Py_INCREF(temp); origin = temp; } break; } } else { PyErr_Clear(); /* Check for NewType */ PyObject *supertype = PyObject_GetAttr(t, state->mod->str___supertype__); if (supertype != NULL) { /* It's a newtype, use the wrapped type and loop again */ Py_DECREF(t); t = supertype; continue; } PyErr_Clear(); /* Check for TypeAliasType if Python 3.12+ */ #if PY312_PLUS if (Py_TYPE(t) == (PyTypeObject *)(state->mod->typing_typealiastype)) { PyObject *value = PyObject_GetAttr(t, state->mod->str___value__); if (value == NULL) goto error; Py_DECREF(t); t = value; continue; } #endif break; } } #if PY310_PLUS if (Py_TYPE(t) == (PyTypeObject *)(state->mod->types_uniontype)) { /* Handle types.UnionType unions (`int | float | ...`) */ args = PyObject_GetAttr(t, state->mod->str___args__); if (args == NULL) goto error; origin = state->mod->typing_union; Py_INCREF(origin); } #endif *out_origin = origin; *out_args = args; return t; error: Py_XDECREF(t); Py_XDECREF(origin); Py_XDECREF(args); return NULL; } static bool is_namedtuple_class(TypeNodeCollectState *state, PyObject *t) { return ( PyType_Check(t) && PyType_IsSubtype((PyTypeObject *)t, &PyTuple_Type) && PyObject_HasAttr(t, state->mod->str__fields) ); } static bool is_typeddict_class(TypeNodeCollectState *state, PyObject *t) { return ( PyType_Check(t) && PyType_IsSubtype((PyTypeObject *)t, &PyDict_Type) && PyObject_HasAttr(t, state->mod->str___total__) ); } static bool is_dataclass_or_attrs_class(TypeNodeCollectState *state, PyObject *t) { return ( PyType_Check(t) && ( PyObject_HasAttr(t, state->mod->str___dataclass_fields__) || PyObject_HasAttr(t, state->mod->str___attrs_attrs__) ) ); } static int typenode_collect_type(TypeNodeCollectState *state, PyObject *obj) { int out = 0; PyObject *t = NULL, *origin = NULL, *args = NULL; Constraints constraints = {0}; enum constraint_kind kind = CK_OTHER; /* If `Any` type already encountered, nothing to do */ if (state->types & MS_TYPE_ANY) return 0; t = typenode_origin_args_metadata(state, obj, &origin, &args, &constraints); if (t == NULL) return -1; if (t == state->mod->typing_any) { /* Any takes precedence, drop all existing and update type flags */ typenode_collect_clear_state(state); state->types = MS_TYPE_ANY; } else if (t == Py_None || t == NONE_TYPE) { state->types |= MS_TYPE_NONE; } else if (t == (PyObject *)(&PyBool_Type)) { state->types |= MS_TYPE_BOOL; } else if (t == (PyObject *)(&PyLong_Type)) { state->types |= MS_TYPE_INT; kind = CK_INT; } else if (t == (PyObject *)(&PyFloat_Type)) { state->types |= MS_TYPE_FLOAT; kind = CK_FLOAT; } else if (t == (PyObject *)(&PyUnicode_Type)) { state->types |= MS_TYPE_STR; kind = CK_STR; } else if (t == (PyObject *)(&PyBytes_Type)) { state->types |= MS_TYPE_BYTES; kind = CK_BYTES; } else if (t == (PyObject *)(&PyByteArray_Type)) { state->types |= MS_TYPE_BYTEARRAY; kind = CK_BYTES; } else if (t == (PyObject *)(&PyMemoryView_Type)) { state->types |= MS_TYPE_MEMORYVIEW; kind = CK_BYTES; } else if (t == (PyObject *)(PyDateTimeAPI->DateTimeType)) { state->types |= MS_TYPE_DATETIME; kind = CK_TIME; } else if (t == (PyObject *)(PyDateTimeAPI->DateType)) { state->types |= MS_TYPE_DATE; } else if (t == (PyObject *)(PyDateTimeAPI->TimeType)) { state->types |= MS_TYPE_TIME; kind = CK_TIME; } else if (t == (PyObject *)(PyDateTimeAPI->DeltaType)) { state->types |= MS_TYPE_TIMEDELTA; } else if (t == state->mod->UUIDType) { state->types |= MS_TYPE_UUID; } else if (t == state->mod->DecimalType) { state->types |= MS_TYPE_DECIMAL; } else if (t == (PyObject *)(&Ext_Type)) { state->types |= MS_TYPE_EXT; } else if (t == (PyObject *)(&Raw_Type)) { /* Raw is marked with a typecode of 0, nothing to do */ } else if (Py_TYPE(t) == (PyTypeObject *)(state->mod->typing_typevar)) { out = typenode_collect_typevar(state, t); } else if ( Py_TYPE(t) == &StructMetaType || (origin != NULL && Py_TYPE(origin) == &StructMetaType) ) { out = typenode_collect_struct(state, t); } else if (Py_TYPE(t) == state->mod->EnumMetaType) { out = typenode_collect_enum(state, t); } else if (origin == (PyObject*)(&PyDict_Type)) { kind = CK_MAP; if (args != NULL && PyTuple_GET_SIZE(args) != 2) goto invalid; out = typenode_collect_dict( state, (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 0), (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 1) ); } else if (origin == (PyObject*)(&PyList_Type)) { kind = CK_ARRAY; if (args != NULL && PyTuple_GET_SIZE(args) != 1) goto invalid; out = typenode_collect_array( state, MS_TYPE_LIST, (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 0) ); } else if (origin == (PyObject*)(&PySet_Type)) { kind = CK_ARRAY; if (args != NULL && PyTuple_GET_SIZE(args) != 1) goto invalid; out = typenode_collect_array( state, MS_TYPE_SET, (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 0) ); } else if (origin == (PyObject*)(&PyFrozenSet_Type)) { kind = CK_ARRAY; if (args != NULL && PyTuple_GET_SIZE(args) != 1) goto invalid; out = typenode_collect_array( state, MS_TYPE_FROZENSET, (args == NULL) ? state->mod->typing_any : PyTuple_GET_ITEM(args, 0) ); } else if (origin == (PyObject*)(&PyTuple_Type)) { if (args == NULL) { kind = CK_ARRAY; out = typenode_collect_array( state, MS_TYPE_VARTUPLE, state->mod->typing_any ); } else if (PyTuple_GET_SIZE(args) == 2 && PyTuple_GET_ITEM(args, 1) == Py_Ellipsis) { kind = CK_ARRAY; out = typenode_collect_array( state, MS_TYPE_VARTUPLE, PyTuple_GET_ITEM(args, 0) ); } else if ( PyTuple_GET_SIZE(args) == 1 && PyTuple_CheckExact(PyTuple_GET_ITEM(args, 0)) && PyTuple_GET_SIZE(PyTuple_GET_ITEM(args, 0)) == 0 ) { /* XXX: this case handles a weird compatibility issue: * - Tuple[()].__args__ == ((),) * - tuple[()].__args__ == () */ out = typenode_collect_array( state, MS_TYPE_FIXTUPLE, PyTuple_GET_ITEM(args, 0) ); } else { out = typenode_collect_array(state, MS_TYPE_FIXTUPLE, args); } } else if (origin == state->mod->typing_union) { if (Py_EnterRecursiveCall(" while analyzing a type")) { out = -1; goto done; } for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(args); i++) { PyObject *arg = PyTuple_GET_ITEM(args, i); /* Ignore UnsetType in unions */ if (arg == (PyObject *)(&Unset_Type)) continue; out = typenode_collect_type(state, arg); if (out < 0) break; } Py_LeaveRecursiveCall(); } else if (origin == state->mod->typing_literal) { if (state->literals == NULL) { state->literals = PyList_New(0); if (state->literals == NULL) goto done; } out = PyList_Append(state->literals, t); } else if ( is_typeddict_class(state, t) || (origin != NULL && is_typeddict_class(state, origin)) ) { out = typenode_collect_typeddict(state, t); } else if ( is_namedtuple_class(state, t) || (origin != NULL && is_namedtuple_class(state, origin)) ) { out = typenode_collect_namedtuple(state, t); } else if ( is_dataclass_or_attrs_class(state, t) || (origin != NULL && is_dataclass_or_attrs_class(state, origin)) ) { out = typenode_collect_dataclass(state, t); } else { if (origin != NULL) { if (!PyType_Check(origin)) goto invalid; } else { if (!PyType_Check(t)) goto invalid; } out = typenode_collect_custom( state, (origin != NULL) ? MS_TYPE_CUSTOM_GENERIC : MS_TYPE_CUSTOM, t ); } done: Py_XDECREF(t); Py_XDECREF(origin); Py_XDECREF(args); if (out == 0) { out = typenode_collect_constraints(state, &constraints, kind, obj); } return out; invalid: PyErr_Format(PyExc_TypeError, "Type '%R' is not supported", t); out = -1; goto done; } static TypeNode * TypeNode_Convert(PyObject *obj) { TypeNode *out = NULL; TypeNodeCollectState state = {0}; state.mod = msgspec_get_global_state(); state.context = obj; if (Py_EnterRecursiveCall(" while analyzing a type")) return NULL; /* Traverse `obj` to collect all type annotations at this level */ if (typenode_collect_type(&state, obj) < 0) goto done; /* Handle structs in a second pass */ if (typenode_collect_convert_structs(&state) < 0) goto done; /* Handle literals in a second pass */ if (typenode_collect_convert_literals(&state) < 0) goto done; /* Check type invariants to ensure Union types are valid */ if (typenode_collect_check_invariants(&state) < 0) goto done; /* Populate a new TypeNode, recursing into subtypes as needed */ out = typenode_from_collect_state(&state); done: typenode_collect_clear_state(&state); Py_LeaveRecursiveCall(); return out; } #define ms_raise_validation_error(path, format, ...) \ do { \ MsgspecState *st = msgspec_get_global_state(); \ PyObject *suffix = PathNode_ErrSuffix(path); \ if (suffix != NULL) { \ PyErr_Format(st->ValidationError, format, __VA_ARGS__, suffix); \ Py_DECREF(suffix); \ } \ } while (0) static MS_NOINLINE PyObject * ms_validation_error(const char *got, TypeNode *type, PathNode *path) { PyObject *type_repr = typenode_simple_repr(type); if (type_repr != NULL) { ms_raise_validation_error(path, "Expected `%U`, got `%s`%U", type_repr, got); Py_DECREF(type_repr); } return NULL; } static void ms_missing_required_field(PyObject *field, PathNode *path) { ms_raise_validation_error( path, "Object missing required field `%U`%U", field ); } static PyObject * ms_invalid_cstr_value(const char *cstr, Py_ssize_t size, PathNode *path) { PyObject *str = PyUnicode_DecodeUTF8(cstr, size, NULL); if (str == NULL) return NULL; ms_raise_validation_error(path, "Invalid value '%U'%U", str); Py_DECREF(str); return NULL; } static PyObject * ms_invalid_cint_value(int64_t val, PathNode *path) { ms_raise_validation_error(path, "Invalid value %lld%U", val); return NULL; } static PyObject * ms_invalid_cuint_value(uint64_t val, PathNode *path) { ms_raise_validation_error(path, "Invalid value %llu%U", val); return NULL; } static MS_NOINLINE PyObject * ms_error_unknown_field(const char *key, Py_ssize_t key_size, PathNode *path) { PyObject *field = PyUnicode_FromStringAndSize(key, key_size); if (field == NULL) return NULL; ms_raise_validation_error( path, "Object contains unknown field `%U`%U", field ); Py_DECREF(field); return NULL; } /* Same as ms_raise_validation_error, except doesn't require any format arguments. */ static PyObject * ms_error_with_path(const char *msg, PathNode *path) { MsgspecState *st = msgspec_get_global_state(); PyObject *suffix = PathNode_ErrSuffix(path); if (suffix != NULL) { PyErr_Format(st->ValidationError, msg, suffix); Py_DECREF(suffix); } return NULL; } static MS_NOINLINE void ms_maybe_wrap_validation_error(PathNode *path) { PyObject *exc_type, *exc, *tb; /* Fetch the exception state */ PyErr_Fetch(&exc_type, &exc, &tb); /* If null, some other c-extension has borked, just return */ if (exc_type == NULL) return; /* If it's a TypeError or ValueError, wrap it in a ValidationError. * Otherwise we reraise the original error below */ if ( PyType_IsSubtype( (PyTypeObject *)exc_type, (PyTypeObject *)PyExc_ValueError ) || PyType_IsSubtype( (PyTypeObject *)exc_type, (PyTypeObject *)PyExc_TypeError ) ) { PyObject *exc_type2, *exc2, *tb2; /* Normalize the original exception */ PyErr_NormalizeException(&exc_type, &exc, &tb); if (tb != NULL) { PyException_SetTraceback(exc, tb); Py_DECREF(tb); } Py_DECREF(exc_type); /* Raise a new validation error with context based on the * original exception */ ms_raise_validation_error(path, "%S%U", exc); /* Fetch the new exception */ PyErr_Fetch(&exc_type2, &exc2, &tb2); /* Normalize the new exception */ PyErr_NormalizeException(&exc_type2, &exc2, &tb2); /* Set the original exception as the cause and context */ Py_INCREF(exc); PyException_SetCause(exc2, exc); PyException_SetContext(exc2, exc); /* At this point the original exc_type/exc/tb are all dropped, * replace them with the new values */ exc_type = exc_type2; exc = exc2; tb = tb2; } /* Restore the new exception state */ PyErr_Restore(exc_type, exc, tb); } static PyTypeObject StructMixinType; /* Note this always allocates an UNTRACKED object */ static PyObject * Struct_alloc(PyTypeObject *type) { PyObject *obj; bool is_gc = MS_TYPE_IS_GC(type); if (is_gc) { obj = PyObject_GC_New(PyObject, type); } else { obj = PyObject_New(PyObject, type); } if (obj == NULL) return NULL; /* Zero out slot fields */ memset((char *)obj + sizeof(PyObject), '\0', type->tp_basicsize - sizeof(PyObject)); return obj; } /* Mirrored from cpython Objects/typeobject.c */ static void clear_slots(PyTypeObject *type, PyObject *self) { Py_ssize_t i, n; PyMemberDef *mp; n = Py_SIZE(type); mp = MS_PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (i = 0; i < n; i++, mp++) { if (mp->type == T_OBJECT_EX && !(mp->flags & READONLY)) { char *addr = (char *)self + mp->offset; PyObject *obj = *(PyObject **)addr; if (obj != NULL) { *(PyObject **)addr = NULL; Py_DECREF(obj); } } } } static void Struct_dealloc_nogc(PyObject *self) { PyTypeObject *type = Py_TYPE(self); /* Maybe call a finalizer */ if (type->tp_finalize) { /* If resurrected, exit early */ if (PyObject_CallFinalizerFromDealloc(self) < 0) return; } /* Maybe clear weakrefs */ if (type->tp_weaklistoffset) { PyObject_ClearWeakRefs(self); } /* Clear all slots */ PyTypeObject *base = type; while (base != NULL) { if (Py_SIZE(base)) { clear_slots(base, self); } base = base->tp_base; } type->tp_free(self); /* Decref the object type immediately */ Py_DECREF(type); } static PyObject * StructMeta_get_field_name(PyObject *self, Py_ssize_t field_index) { return PyTuple_GET_ITEM( ((StructMetaObject *)self)->struct_encode_fields, field_index ); } static MS_INLINE Py_ssize_t StructMeta_get_field_index( StructMetaObject *self, const char * key, Py_ssize_t key_size, Py_ssize_t *pos ) { const char *field; Py_ssize_t nfields, field_size, i, offset = *pos; nfields = PyTuple_GET_SIZE(self->struct_encode_fields); for (i = offset; i < nfields; i++) { field = unicode_str_and_size_nocheck( PyTuple_GET_ITEM(self->struct_encode_fields, i), &field_size ); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i < (nfields - 1) ? (i + 1) : 0; return i; } } for (i = 0; i < offset; i++) { field = unicode_str_and_size_nocheck( PyTuple_GET_ITEM(self->struct_encode_fields, i), &field_size ); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i + 1; return i; } } /* Not a field, check if it matches the tag field (if present) */ if (MS_UNLIKELY(self->struct_tag_field != NULL)) { Py_ssize_t tag_field_size; const char *tag_field; tag_field = unicode_str_and_size_nocheck(self->struct_tag_field, &tag_field_size); if (key_size == tag_field_size && memcmp(key, tag_field, key_size) == 0) { return -2; } } return -1; } static int dict_discard(PyObject *dict, PyObject *key) { int status = PyDict_Contains(dict, key); if (status < 0) return status; return (status == 1) ? PyDict_DelItem(dict, key) : 0; } static PyObject * Struct_vectorcall(PyTypeObject *cls, PyObject *const *args, size_t nargsf, PyObject *kwnames); /* setattr for frozen=True types */ static int Struct_setattro_frozen(PyObject *self, PyObject *key, PyObject *value) { PyErr_Format( PyExc_AttributeError, "immutable type: '%s'", Py_TYPE(self)->tp_name ); return -1; } /* setattr for frozen=False types */ static int Struct_setattro_default(PyObject *self, PyObject *key, PyObject *value) { if (PyObject_GenericSetAttr(self, key, value) < 0) return -1; if ( value != NULL && MS_OBJECT_IS_GC(self) && !MS_IS_TRACKED(self) && MS_MAYBE_TRACKED(value) ) PyObject_GC_Track(self); return 0; } static PyObject* rename_lower(PyObject *rename, PyObject *field) { return PyObject_CallMethod(field, "lower", NULL); } static PyObject* rename_upper(PyObject *rename, PyObject *field) { return PyObject_CallMethod(field, "upper", NULL); } static PyObject* rename_kebab(PyObject *rename, PyObject *field) { PyObject *underscore = NULL, *dash = NULL, *temp = NULL, *out = NULL; underscore = PyUnicode_FromStringAndSize("_", 1); if (underscore == NULL) goto error; dash = PyUnicode_FromStringAndSize("-", 1); if (dash == NULL) goto error; temp = PyObject_CallMethod(field, "strip", "s", "_"); if (temp == NULL) goto error; out = PyUnicode_Replace(temp, underscore, dash, -1); error: Py_XDECREF(underscore); Py_XDECREF(dash); Py_XDECREF(temp); return out; } static PyObject* rename_camel_inner(PyObject *field, bool cap_first) { PyObject *parts = NULL, *out = NULL, *empty = NULL; PyObject *underscore = PyUnicode_FromStringAndSize("_", 1); if (underscore == NULL) return NULL; parts = PyUnicode_Split(field, underscore, -1); if (parts == NULL) goto cleanup; if (PyList_GET_SIZE(parts) == 1 && !cap_first) { Py_INCREF(field); out = field; goto cleanup; } bool first = true; for (Py_ssize_t i = 0; i < PyList_GET_SIZE(parts); i++) { PyObject *part = PyList_GET_ITEM(parts, i); if (first && (PyUnicode_GET_LENGTH(part) == 0)) { /* Preserve leading underscores */ Py_INCREF(underscore); Py_DECREF(part); PyList_SET_ITEM(parts, i, underscore); } else { if (!first || cap_first) { /* convert part to title case, inplace in the list */ PyObject *part_title = PyObject_CallMethod(part, "title", NULL); if (part_title == NULL) goto cleanup; Py_DECREF(part); PyList_SET_ITEM(parts, i, part_title); } first = false; } } empty = PyUnicode_FromStringAndSize("", 0); if (empty == NULL) goto cleanup; out = PyUnicode_Join(empty, parts); cleanup: Py_XDECREF(empty); Py_XDECREF(underscore); Py_XDECREF(parts); return out; } static PyObject* rename_camel(PyObject *rename, PyObject *field) { return rename_camel_inner(field, false); } static PyObject* rename_pascal(PyObject *rename, PyObject *field) { return rename_camel_inner(field, true); } static PyObject* rename_callable(PyObject *rename, PyObject *field) { PyObject *temp = PyObject_CallOneArg(rename, field); if (temp == NULL) return NULL; if (PyUnicode_CheckExact(temp)) return temp; if (temp == Py_None) { Py_DECREF(temp); Py_INCREF(field); return field; } PyErr_Format( PyExc_TypeError, "Expected calling `rename` to return a `str` or `None`, got `%.200s`", Py_TYPE(temp)->tp_name ); Py_DECREF(temp); return NULL; } static PyObject* rename_mapping(PyObject *rename, PyObject *field) { PyObject *temp = PyObject_GetItem(rename, field); if (temp == NULL) { PyErr_Clear(); Py_INCREF(field); return field; } else if (temp == Py_None) { Py_DECREF(temp); Py_INCREF(field); return field; } else if (PyUnicode_CheckExact(temp)) { return temp; } PyErr_Format( PyExc_TypeError, "Expected `rename[field]` to return a `str` or `None`, got `%.200s`", Py_TYPE(temp)->tp_name ); Py_DECREF(temp); return NULL; } typedef struct { /* Temporary state. All owned references. */ PyObject *defaults_lk; PyObject *offsets_lk; PyObject *kwonly_fields; PyObject *slots; PyObject *namespace; PyObject *renamed_fields; /* Output values. All owned references. */ PyObject *fields; PyObject *encode_fields; PyObject *defaults; PyObject *match_args; PyObject *tag; PyObject *tag_field; PyObject *tag_value; Py_ssize_t *offsets; Py_ssize_t nkwonly; Py_ssize_t n_trailing_defaults; /* Configuration values. All borrowed references. */ PyObject *name; PyObject *temp_tag_field; PyObject *temp_tag; PyObject *rename; int omit_defaults; int forbid_unknown_fields; int frozen; int eq; int order; int repr_omit_defaults; int array_like; int gc; int weakref; bool already_has_weakref; int dict; bool already_has_dict; int cache_hash; Py_ssize_t hash_offset; bool has_non_slots_bases; } StructMetaInfo; static int structmeta_check_namespace(PyObject *namespace) { static const char *attrs[] = {"__init__", "__new__", "__slots__"}; Py_ssize_t nattrs = 3; for (Py_ssize_t i = 0; i < nattrs; i++) { if (PyDict_GetItemString(namespace, attrs[i]) != NULL) { PyErr_Format(PyExc_TypeError, "Struct types cannot define %s", attrs[i]); return -1; } } return 0; } static PyObject * structmeta_get_module_ns(MsgspecState *mod, StructMetaInfo *info) { PyObject *name = PyDict_GetItemString(info->namespace, "__module__"); if (name == NULL) return NULL; PyObject *modules = PySys_GetObject("modules"); if (modules == NULL) return NULL; PyObject *module = PyDict_GetItem(modules, name); if (mod == NULL) return NULL; return PyObject_GetAttr(module, mod->str___dict__); } static int structmeta_collect_base(StructMetaInfo *info, MsgspecState *mod, PyObject *base) { if ((PyTypeObject *)base == &StructMixinType) return 0; if (((PyTypeObject *)base)->tp_weaklistoffset) { info->already_has_weakref = true; } if (((PyTypeObject *)base)->tp_dictoffset) { info->already_has_dict = true; } if (!PyType_Check(base)) { /* CPython's metaclass conflict check will catch this issue earlier on, * but it's still good to have this check in place in case that's ever * removed */ PyErr_SetString(PyExc_TypeError, "All base classes must be types"); return -1; } if (Py_TYPE(base) != &StructMetaType) { if (((PyTypeObject *)base)->tp_dictoffset) { info->has_non_slots_bases = true; } static const char *attrs[] = {"__init__", "__new__"}; Py_ssize_t nattrs = 2; PyObject *tp_dict = MS_GET_TYPE_DICT((PyTypeObject *)base); for (Py_ssize_t i = 0; i < nattrs; i++) { if (PyDict_GetItemString(tp_dict, attrs[i]) != NULL) { PyErr_Format(PyExc_TypeError, "Struct base classes cannot define %s", attrs[i]); return -1; } } return 0; } StructMetaObject *st_type = (StructMetaObject *)base; /* Check if a hash_cache slot already exists */ if (st_type->hash_offset != 0) { info->hash_offset = st_type->hash_offset; } /* Inherit config fields */ if (st_type->struct_tag_field != NULL) { info->temp_tag_field = st_type->struct_tag_field; } if (st_type->struct_tag != NULL) { info->temp_tag = st_type->struct_tag; } if (st_type->rename != NULL) { info->rename = st_type->rename; } info->frozen = STRUCT_MERGE_OPTIONS(info->frozen, st_type->frozen); info->eq = STRUCT_MERGE_OPTIONS(info->eq, st_type->eq); info->order = STRUCT_MERGE_OPTIONS(info->order, st_type->order); info->array_like = STRUCT_MERGE_OPTIONS(info->array_like, st_type->array_like); info->gc = STRUCT_MERGE_OPTIONS(info->gc, st_type->gc); info->omit_defaults = STRUCT_MERGE_OPTIONS(info->omit_defaults, st_type->omit_defaults); info->repr_omit_defaults = STRUCT_MERGE_OPTIONS( info->repr_omit_defaults, st_type->repr_omit_defaults ); info->forbid_unknown_fields = STRUCT_MERGE_OPTIONS( info->forbid_unknown_fields, st_type->forbid_unknown_fields ); PyObject *fields = st_type->struct_fields; PyObject *encode_fields = st_type->struct_encode_fields; PyObject *defaults = st_type->struct_defaults; Py_ssize_t *offsets = st_type->struct_offsets; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); Py_ssize_t nkwonly = st_type->nkwonly; Py_ssize_t ndefaults = PyTuple_GET_SIZE(defaults); Py_ssize_t defaults_offset = nfields - ndefaults; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(fields, i); PyObject *encode_field = PyTuple_GET_ITEM(encode_fields, i); PyObject *default_val = NODEFAULT; if (i >= defaults_offset) { default_val = PyTuple_GET_ITEM(defaults, i - defaults_offset); } if (PyDict_SetItem(info->defaults_lk, field, default_val) < 0) return -1; /* Mark the field as kwonly or not */ if (i >= (nfields - nkwonly)) { if (PySet_Add(info->kwonly_fields, field) < 0) return -1; } else { if (PySet_Discard(info->kwonly_fields, field) < 0) return -1; } /* Propagate any renamed fields */ if (field != encode_field) { if (PyDict_SetItem(info->renamed_fields, field, encode_field) < 0) return -1; } PyObject *offset = PyLong_FromSsize_t(offsets[i]); if (offset == NULL) return -1; bool errored = PyDict_SetItem(info->offsets_lk, field, offset) < 0; Py_DECREF(offset); if (errored) return -1; } return 0; } static int structmeta_process_rename( StructMetaInfo *info, PyObject *name, PyObject *default_value ) { if ( default_value != NULL && Py_TYPE(default_value) == &Field_Type && ((Field *)default_value)->name != NULL ) { Field *field = (Field *)default_value; if (PyUnicode_Compare(name, field->name) == 0) return 0; return PyDict_SetItem(info->renamed_fields, name, field->name); } if (info->rename == NULL) return 0; PyObject* (*method)(PyObject *, PyObject *); if (PyUnicode_CheckExact(info->rename)) { if (PyUnicode_CompareWithASCIIString(info->rename, "lower") == 0) { method = &rename_lower; } else if (PyUnicode_CompareWithASCIIString(info->rename, "upper") == 0) { method = &rename_upper; } else if (PyUnicode_CompareWithASCIIString(info->rename, "camel") == 0) { method = &rename_camel; } else if (PyUnicode_CompareWithASCIIString(info->rename, "pascal") == 0) { method = &rename_pascal; } else if (PyUnicode_CompareWithASCIIString(info->rename, "kebab") == 0) { method = &rename_kebab; } else { PyErr_Format(PyExc_ValueError, "rename='%U' is unsupported", info->rename); return -1; } } else if (PyCallable_Check(info->rename)) { method = &rename_callable; } else if (PyMapping_Check(info->rename)) { method = &rename_mapping; } else { PyErr_SetString(PyExc_TypeError, "`rename` must be a str, callable, or mapping"); return -1; } PyObject *temp = method(info->rename, name); if (temp == NULL) return -1; int out = 0; if (PyUnicode_Compare(name, temp) != 0) { out = PyDict_SetItem(info->renamed_fields, name, temp); } Py_DECREF(temp); return out; } static int structmeta_process_default(StructMetaInfo *info, PyObject *name) { PyObject *obj = PyDict_GetItem(info->namespace, name); if (structmeta_process_rename(info, name, obj) < 0) return -1; if (obj == NULL) { return PyDict_SetItem(info->defaults_lk, name, NODEFAULT); } PyObject* default_val = NULL; PyTypeObject *type = Py_TYPE(obj); if (type == &Field_Type) { Field *f = (Field *)obj; /* Extract default or default_factory */ if (f->default_value != NODEFAULT) { obj = f->default_value; type = Py_TYPE(obj); } else if (f->default_factory != NODEFAULT) { if (f->default_factory == (PyObject *)&PyTuple_Type) { default_val = PyTuple_New(0); } else if (f->default_factory == (PyObject *)&PyFrozenSet_Type) { default_val = PyFrozenSet_New(NULL); } else { default_val = Factory_New(f->default_factory); } if (default_val == NULL) return -1; goto done; } else { default_val = NODEFAULT; Py_INCREF(default_val); goto done; } } if (type == &PyDict_Type) { if (PyDict_GET_SIZE(obj) != 0) goto error_nonempty; default_val = Factory_New((PyObject*)(&PyDict_Type)); if (default_val == NULL) return -1; } else if (type == &PyList_Type) { if (PyList_GET_SIZE(obj) != 0) goto error_nonempty; default_val = Factory_New((PyObject*)(&PyList_Type)); if (default_val == NULL) return -1; } else if (type == &PySet_Type) { if (PySet_GET_SIZE(obj) != 0) goto error_nonempty; default_val = Factory_New((PyObject*)(&PySet_Type)); if (default_val == NULL) return -1; } else if (type == &PyByteArray_Type) { if (PyByteArray_GET_SIZE(obj) != 0) goto error_nonempty; default_val = Factory_New((PyObject*)(&PyByteArray_Type)); if (default_val == NULL) return -1; } else if ( (Py_TYPE(type) == &StructMetaType) && ((StructMetaObject *)type)->frozen != OPT_TRUE ) { goto error_mutable_struct; } else { Py_INCREF(obj); default_val = obj; } done: if (dict_discard(info->namespace, name) < 0) { Py_DECREF(default_val); return -1; } int status = PyDict_SetItem(info->defaults_lk, name, default_val); Py_DECREF(default_val); return status; error_nonempty: PyErr_Format( PyExc_TypeError, "Using a non-empty mutable collection (%R) as a default value is unsafe. " "Instead configure a `default_factory` for this field.", obj ); return -1; error_mutable_struct: PyErr_Format( PyExc_TypeError, "Using a mutable struct object (%R) as a default value is unsafe. " "Either configure a `default_factory` for this field, or set " "`frozen=True` on `%.200s`", obj, type->tp_name ); return -1; } static int structmeta_is_classvar( StructMetaInfo *info, MsgspecState *mod, PyObject *ann, PyObject **module_ns ) { PyTypeObject *ann_type = Py_TYPE(ann); if (ann_type == &PyUnicode_Type) { Py_ssize_t ann_len; const char *ann_buf = unicode_str_and_size(ann, &ann_len); if (ann_len < 8) return 0; if (memcmp(ann_buf, "ClassVar", 8) == 0) { if (ann_len != 8 && ann_buf[8] != '[') return 0; if (*module_ns == NULL) { *module_ns = structmeta_get_module_ns(mod, info); } if (*module_ns == NULL) return 0; PyObject *temp = PyDict_GetItemString(*module_ns, "ClassVar"); return temp == mod->typing_classvar; } if (ann_len < 15) return 0; if (memcmp(ann_buf, "typing.ClassVar", 15) == 0) { if (ann_len != 15 && ann_buf[15] != '[') return 0; if (*module_ns == NULL) { *module_ns = structmeta_get_module_ns(mod, info); } if (*module_ns == NULL) return 0; PyObject *temp = PyDict_GetItemString(*module_ns, "typing"); if (temp == NULL) return 0; temp = PyObject_GetAttrString(temp, "ClassVar"); int status = temp == mod->typing_classvar; Py_DECREF(temp); return status; } } else { if (ann == mod->typing_classvar) { return 1; } else if ((PyObject *)ann_type == mod->typing_generic_alias) { PyObject *temp = PyObject_GetAttr(ann, mod->str___origin__); if (temp == NULL) return -1; int status = temp == mod->typing_classvar; Py_DECREF(temp); return status; } return 0; } return 0; } static int structmeta_collect_fields(StructMetaInfo *info, MsgspecState *mod, bool kwonly) { PyObject *annotations = PyDict_GetItemString( info->namespace, "__annotations__" ); if (annotations == NULL) return 0; if (!PyDict_Check(annotations)) { PyErr_SetString(PyExc_TypeError, "__annotations__ must be a dict"); return -1; } PyObject *module_ns = NULL; PyObject *field, *value; Py_ssize_t i = 0; while (PyDict_Next(annotations, &i, &field, &value)) { if (!PyUnicode_CheckExact(field)) { PyErr_SetString( PyExc_TypeError, "__annotations__ keys must be strings" ); goto error; } PyObject *invalid_field_names[] = { mod->str___weakref__, mod->str___dict__, mod->str___msgspec_cached_hash__ }; for (int i = 0; i < 3; i++) { if (PyUnicode_Compare(field, invalid_field_names[i]) == 0) { PyErr_Format( PyExc_TypeError, "Cannot have a struct field named %R", field ); goto error; } } int status = structmeta_is_classvar(info, mod, value, &module_ns); if (status == 1) continue; if (status == -1) goto error; /* If the field is new, add it to slots */ if (PyDict_GetItem(info->defaults_lk, field) == NULL) { if (PyList_Append(info->slots, field) < 0) goto error; } if (kwonly) { if (PySet_Add(info->kwonly_fields, field) < 0) goto error; } else { if (PySet_Discard(info->kwonly_fields, field) < 0) goto error; } if (structmeta_process_default(info, field) < 0) goto error; } return 0; error: Py_XDECREF(module_ns); return -1; } static int structmeta_construct_fields(StructMetaInfo *info, MsgspecState *mod) { Py_ssize_t nfields = PyDict_GET_SIZE(info->defaults_lk); Py_ssize_t nkwonly = PySet_GET_SIZE(info->kwonly_fields); Py_ssize_t field_index = 0; info->fields = PyTuple_New(nfields); if (info->fields == NULL) return -1; info->defaults = PyList_New(0); /* First pass - handle all non-kwonly fields. */ PyObject *field, *default_val; Py_ssize_t pos = 0; while (PyDict_Next(info->defaults_lk, &pos, &field, &default_val)) { int kwonly = PySet_Contains(info->kwonly_fields, field); if (kwonly < 0) return -1; if (kwonly) continue; Py_INCREF(field); PyTuple_SET_ITEM(info->fields, field_index, field); if (default_val == NODEFAULT) { if (PyList_GET_SIZE(info->defaults)) { PyErr_Format( PyExc_TypeError, "Required field '%U' cannot follow optional fields. Either " "reorder the struct fields, or set `kw_only=True` in the " "struct definition.", field ); return -1; } } else { if (PyList_Append(info->defaults, default_val) < 0) return -1; } field_index++; } /* Next handle any kw_only fields */ if (nkwonly) { PyObject *field, *default_val; Py_ssize_t pos = 0; while (PyDict_Next(info->defaults_lk, &pos, &field, &default_val)) { int kwonly = PySet_Contains(info->kwonly_fields, field); if (kwonly < 0) return -1; if (!kwonly) continue; Py_INCREF(field); PyTuple_SET_ITEM(info->fields, field_index, field); if (PyList_GET_SIZE(info->defaults) || default_val != NODEFAULT) { if (PyList_Append(info->defaults, default_val) < 0) return -1; } field_index++; } } /* Convert defaults list to tuple */ PyObject *temp_defaults = PyList_AsTuple(info->defaults); Py_DECREF(info->defaults); info->defaults = temp_defaults; if (info->defaults == NULL) return -1; /* Compute n_trailing_defaults */ info->nkwonly = nkwonly; info->n_trailing_defaults = 0; for (Py_ssize_t i = PyTuple_GET_SIZE(info->defaults) - 1; i >= 0; i--) { if (PyTuple_GET_ITEM(info->defaults, i) == NODEFAULT) break; info->n_trailing_defaults++; } /* Construct __match_args__ */ info->match_args = PyTuple_GetSlice(info->fields, 0, nfields - nkwonly); if (info->match_args == NULL) return -1; /* Construct __slots__ */ if (info->weakref == OPT_TRUE && !info->already_has_weakref) { if (PyList_Append(info->slots, mod->str___weakref__) < 0) return -1; } else if (info->weakref == OPT_FALSE && info->already_has_weakref) { PyErr_SetString( PyExc_ValueError, "Cannot set `weakref=False` if base class already has `weakref=True`" ); return -1; } if (info->dict == OPT_TRUE && !info->already_has_dict) { if (PyList_Append(info->slots, mod->str___dict__) < 0) return -1; } else if (info->dict == OPT_FALSE && info->already_has_dict) { PyErr_SetString( PyExc_ValueError, "Cannot set `dict=False` if base class already has `dict=True`" ); return -1; } if (info->cache_hash == OPT_TRUE && !info->hash_offset) { if (PyList_Append(info->slots, mod->str___msgspec_cached_hash__) < 0) return -1; } else if (info->cache_hash == OPT_FALSE && info->hash_offset) { PyErr_SetString( PyExc_ValueError, "Cannot set `cache_hash=False` if base class already has `cache_hash=True`" ); return -1; } if (PyList_Sort(info->slots) < 0) return -1; PyObject *slots = PyList_AsTuple(info->slots); if (slots == NULL) return -1; int out = PyDict_SetItemString(info->namespace, "__slots__", slots); Py_DECREF(slots); return out; } static int json_str_requires_escaping(PyObject *); static int structmeta_construct_encode_fields(StructMetaInfo *info) { if (PyDict_GET_SIZE(info->renamed_fields) == 0) { /* Nothing to do, use original field tuple */ Py_INCREF(info->fields); info->encode_fields = info->fields; return 0; } info->encode_fields = PyTuple_New(PyTuple_GET_SIZE(info->fields)); if (info->encode_fields == NULL) return -1; for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(info->fields); i++) { PyObject *name = PyTuple_GET_ITEM(info->fields, i); PyObject *temp = PyDict_GetItem(info->renamed_fields, name); if (temp == NULL) { temp = name; } Py_INCREF(temp); PyTuple_SET_ITEM(info->encode_fields, i, temp); } /* Ensure that renamed fields don't collide */ PyObject *fields_set = PySet_New(info->encode_fields); if (fields_set == NULL) return -1; bool unique = PySet_GET_SIZE(fields_set) == PyTuple_GET_SIZE(info->encode_fields); Py_DECREF(fields_set); if (!unique) { PyErr_SetString( PyExc_ValueError, "Multiple fields rename to the same name, field names " "must be unique" ); return -1; } /* Ensure all renamed fields contain characters that don't require quoting * in JSON. This isn't strictly required, but usage of such characters is * extremely unlikely, and forbidding this allows us to optimize encoding */ for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(info->encode_fields); i++) { PyObject *field = PyTuple_GET_ITEM(info->encode_fields, i); Py_ssize_t status = json_str_requires_escaping(field); if (status == -1) return -1; if (status == 1) { PyErr_Format( PyExc_ValueError, "Renamed field names must not contain '\\', '\"', or control characters " "('\\u0000' to '\\u001F') - '%U' is invalid", field ); return -1; } } return 0; } /* Extracts the qualname for a class, and strips off any leading bits from a * function namespace. Examples: * * - `Foo` -> `Foo` * - `Foo.Bar` -> `Foo.Bar` * - `fizz..Foo.Bar` -> `Foo.Bar` * * This means that (nested) classes dynamically defined within functions should * work the same as (nested) classes defined at the top level. */ static PyObject *simple_qualname(PyObject *cls) { PyObject *qualname = NULL, *dotlocalsdot = NULL, *rsplits = NULL, *out = NULL; qualname = PyObject_GetAttrString(cls, "__qualname__"); if (qualname == NULL) goto cleanup; dotlocalsdot = PyUnicode_FromString(".."); if (dotlocalsdot == NULL) goto cleanup; rsplits = PyUnicode_RSplit(qualname, dotlocalsdot, 1); if (rsplits == NULL) goto cleanup; Py_ssize_t end = PyList_GET_SIZE(rsplits) - 1; out = PyList_GET_ITEM(rsplits, end); Py_INCREF(out); cleanup: Py_XDECREF(qualname); Py_XDECREF(dotlocalsdot); Py_XDECREF(rsplits); return out; } static int structmeta_construct_tag(StructMetaInfo *info, MsgspecState *mod, PyObject *cls) { if (info->temp_tag == Py_False) return 0; if (info->temp_tag == NULL && info->temp_tag_field == NULL) return 0; Py_XINCREF(info->temp_tag); info->tag = info->temp_tag; /* Determine the tag value */ if (info->temp_tag == NULL || info->temp_tag == Py_True) { info->tag_value = simple_qualname(cls); if (info->tag_value == NULL) return -1; } else { if (PyCallable_Check(info->temp_tag)) { PyObject *qualname = simple_qualname(cls); if (qualname == NULL) return -1; info->tag_value = PyObject_CallOneArg(info->temp_tag, qualname); Py_DECREF(qualname); if (info->tag_value == NULL) return -1; } else { Py_INCREF(info->temp_tag); info->tag_value = info->temp_tag; } if (PyLong_CheckExact(info->tag_value)) { int64_t val = PyLong_AsLongLong(info->tag_value); if (val == -1 && PyErr_Occurred()) { PyErr_SetString( PyExc_ValueError, "Integer `tag` values must be within [-2**63, 2**63 - 1]" ); return -1; } } else if (!PyUnicode_CheckExact(info->tag_value)) { PyErr_SetString(PyExc_TypeError, "`tag` must be a `str` or an `int`"); return -1; } } /* Next determine the tag_field to use. */ if (info->temp_tag_field == NULL) { info->tag_field = mod->str_type; Py_INCREF(info->tag_field); } else if (PyUnicode_CheckExact(info->temp_tag_field)) { info->tag_field = info->temp_tag_field; Py_INCREF(info->tag_field); } else { PyErr_SetString(PyExc_TypeError, "`tag_field` must be a `str`"); return -1; } int contains = PySequence_Contains(info->encode_fields, info->tag_field); if (contains < 0) return -1; if (contains) { PyErr_Format( PyExc_ValueError, "`tag_field='%U' conflicts with an existing field of that name", info->tag_field ); return -1; } return 0; } static int structmeta_construct_offsets( StructMetaInfo *info, MsgspecState *mod, StructMetaObject *cls ) { PyMemberDef *mp = MS_PyHeapType_GET_MEMBERS(cls); for (Py_ssize_t i = 0; i < Py_SIZE(cls); i++, mp++) { PyObject *offset = PyLong_FromSsize_t(mp->offset); if (offset == NULL) return -1; bool errored = PyDict_SetItemString(info->offsets_lk, mp->name, offset) < 0; Py_DECREF(offset); if (errored) return -1; } info->offsets = PyMem_New(Py_ssize_t, PyTuple_GET_SIZE(info->fields)); if (info->offsets == NULL) return -1; for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(info->fields); i++) { PyObject *field = PyTuple_GET_ITEM(info->fields, i); PyObject *offset = PyDict_GetItem(info->offsets_lk, field); if (offset == NULL) { PyErr_Format(PyExc_RuntimeError, "Failed to get offset for %R", field); return -1; } info->offsets[i] = PyLong_AsSsize_t(offset); } if (info->cache_hash == OPT_TRUE && info->hash_offset == 0) { PyObject *offset = PyDict_GetItem( info->offsets_lk, mod->str___msgspec_cached_hash__ ); if (offset == NULL) { PyErr_Format( PyExc_RuntimeError, "Failed to get offset for %R", mod->str___msgspec_cached_hash__ ); return -1; } info->hash_offset = PyLong_AsSsize_t(offset); } return 0; } static PyObject * StructMeta_new_inner( PyTypeObject *type, PyObject *name, PyObject *bases, PyObject *namespace, PyObject *arg_tag_field, PyObject *arg_tag, PyObject *arg_rename, int arg_omit_defaults, int arg_forbid_unknown_fields, int arg_frozen, int arg_eq, int arg_order, bool arg_kw_only, int arg_repr_omit_defaults, int arg_array_like, int arg_gc, int arg_weakref, int arg_dict, int arg_cache_hash ) { StructMetaObject *cls = NULL; MsgspecState *mod = msgspec_get_global_state(); bool ok = false; if (structmeta_check_namespace(namespace) < 0) return NULL; StructMetaInfo info = { .defaults_lk = NULL, .offsets_lk = NULL, .kwonly_fields = NULL, .slots = NULL, .namespace = NULL, .renamed_fields = NULL, .fields = NULL, .encode_fields = NULL, .defaults = NULL, .match_args = NULL, .tag = NULL, .tag_field = NULL, .tag_value = NULL, .offsets = NULL, .nkwonly = 0, .n_trailing_defaults = 0, .name = name, .temp_tag_field = NULL, .temp_tag = NULL, .rename = NULL, .omit_defaults = -1, .forbid_unknown_fields = -1, .frozen = -1, .eq = -1, .order = -1, .repr_omit_defaults = -1, .array_like = -1, .gc = -1, .weakref = arg_weakref, .already_has_weakref = false, .dict = arg_dict, .already_has_dict = false, .cache_hash = arg_cache_hash, .hash_offset = 0, .has_non_slots_bases = false, }; info.defaults_lk = PyDict_New(); if (info.defaults_lk == NULL) goto cleanup; info.offsets_lk = PyDict_New(); if (info.offsets_lk == NULL) goto cleanup; info.kwonly_fields = PySet_New(NULL); if (info.kwonly_fields == NULL) goto cleanup; info.namespace = PyDict_Copy(namespace); if (info.namespace == NULL) goto cleanup; info.renamed_fields = PyDict_New(); if (info.renamed_fields == NULL) goto cleanup; info.slots = PyList_New(0); if (info.slots == NULL) goto cleanup; /* Extract info from base classes in reverse MRO order */ for (Py_ssize_t i = PyTuple_GET_SIZE(bases) - 1; i >= 0; i--) { PyObject *base = PyTuple_GET_ITEM(bases, i); if (structmeta_collect_base(&info, mod, base) < 0) goto cleanup; } /* Process configuration options */ if (arg_tag != NULL && arg_tag != Py_None) { info.temp_tag = arg_tag; } if (arg_tag_field != NULL && arg_tag_field != Py_None) { info.temp_tag_field = arg_tag_field; } if (arg_rename != NULL) { info.rename = arg_rename == Py_None ? NULL : arg_rename; } info.frozen = STRUCT_MERGE_OPTIONS(info.frozen, arg_frozen); info.eq = STRUCT_MERGE_OPTIONS(info.eq, arg_eq); info.order = STRUCT_MERGE_OPTIONS(info.order, arg_order); info.repr_omit_defaults = STRUCT_MERGE_OPTIONS(info.repr_omit_defaults, arg_repr_omit_defaults); info.array_like = STRUCT_MERGE_OPTIONS(info.array_like, arg_array_like); info.gc = STRUCT_MERGE_OPTIONS(info.gc, arg_gc); info.omit_defaults = STRUCT_MERGE_OPTIONS(info.omit_defaults, arg_omit_defaults); info.forbid_unknown_fields = STRUCT_MERGE_OPTIONS(info.forbid_unknown_fields, arg_forbid_unknown_fields); if (info.eq == OPT_FALSE && info.order == OPT_TRUE) { PyErr_SetString(PyExc_ValueError, "Cannot set eq=False and order=True"); goto cleanup; } if (info.cache_hash == OPT_TRUE && info.frozen != OPT_TRUE) { PyErr_SetString(PyExc_ValueError, "Cannot set cache_hash=True without frozen=True"); goto cleanup; } if (info.gc == OPT_FALSE) { if (info.has_non_slots_bases) { PyErr_SetString( PyExc_ValueError, "Cannot set gc=False when inheriting from non-struct types with a __dict__" ); goto cleanup; } else if (info.dict == OPT_TRUE || info.already_has_dict) { PyErr_SetString(PyExc_ValueError, "Cannot set gc=False and dict=True"); goto cleanup; } } /* Collect new fields and defaults */ if (structmeta_collect_fields(&info, mod, arg_kw_only) < 0) goto cleanup; /* Construct fields and defaults */ if (structmeta_construct_fields(&info, mod) < 0) goto cleanup; /* Construct encode_fields */ if (structmeta_construct_encode_fields(&info) < 0) goto cleanup; /* Construct type */ PyObject *args = Py_BuildValue("(OOO)", name, bases, info.namespace); if (args == NULL) goto cleanup; cls = (StructMetaObject *) PyType_Type.tp_new(type, args, NULL); Py_CLEAR(args); if (cls == NULL) goto cleanup; /* Fill in type methods */ ((PyTypeObject *)cls)->tp_vectorcall = (vectorcallfunc)Struct_vectorcall; if (info.gc == OPT_FALSE) { ((PyTypeObject *)cls)->tp_flags &= ~Py_TPFLAGS_HAVE_GC; ((PyTypeObject *)cls)->tp_dealloc = &Struct_dealloc_nogc; ((PyTypeObject *)cls)->tp_free = &PyObject_Free; } else { ((PyTypeObject *)cls)->tp_flags |= Py_TPFLAGS_HAVE_GC; ((PyTypeObject *)cls)->tp_free = &PyObject_GC_Del; } if (info.frozen == OPT_TRUE) { /* Frozen structs always override __setattr__ */ ((PyTypeObject *)cls)->tp_setattro = &Struct_setattro_frozen; } else if ( ((PyTypeObject *)cls)->tp_setattro == Struct_setattro_frozen || ((PyTypeObject *)cls)->tp_setattro == PyObject_GenericSetAttr ) { /* Only set non-frozen __setattr__ if it hasn't been defined by the * user. All structs will inherit `Struct_setattro_default` from the * base Struct class, so proper use of `super()` should still result in * this being called. */ ((PyTypeObject *)cls)->tp_setattro = &Struct_setattro_default; } /* Construct tag, tag_field, & tag_value */ if (structmeta_construct_tag(&info, mod, (PyObject *)cls) < 0) goto cleanup; /* Fill in struct offsets */ if (structmeta_construct_offsets(&info, mod, cls) < 0) goto cleanup; /* Cache access to __post_init__ (if defined). */ cls->post_init = PyObject_GetAttr((PyObject *)cls, mod->str___post_init__); if (cls->post_init == NULL) { PyErr_Clear(); } cls->nkwonly = info.nkwonly; cls->n_trailing_defaults = info.n_trailing_defaults; cls->struct_offsets = info.offsets; Py_INCREF(info.fields); cls->struct_fields = info.fields; Py_INCREF(info.defaults); cls->struct_defaults = info.defaults; Py_INCREF(info.encode_fields); cls->struct_encode_fields = info.encode_fields; Py_INCREF(info.match_args); cls->match_args = info.match_args; Py_XINCREF(info.tag); cls->struct_tag = info.tag; Py_XINCREF(info.tag_field); cls->struct_tag_field = info.tag_field; Py_XINCREF(info.tag_value); cls->struct_tag_value = info.tag_value; Py_XINCREF(info.rename); cls->rename = info.rename; cls->hash_offset = info.hash_offset; cls->frozen = info.frozen; cls->eq = info.eq; cls->order = info.order; cls->repr_omit_defaults = info.repr_omit_defaults; cls->array_like = info.array_like; cls->gc = info.gc; cls->omit_defaults = info.omit_defaults; cls->forbid_unknown_fields = info.forbid_unknown_fields; ok = true; cleanup: /* Temporary structures */ Py_XDECREF(info.defaults_lk); Py_XDECREF(info.offsets_lk); Py_XDECREF(info.kwonly_fields); Py_XDECREF(info.slots); Py_XDECREF(info.namespace); Py_XDECREF(info.renamed_fields); /* Constructed outputs */ Py_XDECREF(info.fields); Py_XDECREF(info.encode_fields); Py_XDECREF(info.defaults); Py_XDECREF(info.match_args); Py_XDECREF(info.tag); Py_XDECREF(info.tag_field); Py_XDECREF(info.tag_value); if (!ok) { if (info.offsets != NULL) { PyMem_Free(info.offsets); } Py_XDECREF(cls); return NULL; } return (PyObject *) cls; } static PyObject * StructMeta_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *name = NULL, *bases = NULL, *namespace = NULL; PyObject *arg_tag_field = NULL, *arg_tag = NULL, *arg_rename = NULL; int arg_omit_defaults = -1, arg_forbid_unknown_fields = -1; int arg_frozen = -1, arg_eq = -1, arg_order = -1, arg_repr_omit_defaults = -1; int arg_array_like = -1, arg_gc = -1, arg_weakref = -1, arg_dict = -1; int arg_kw_only = 0, arg_cache_hash = -1; char *kwlist[] = { "name", "bases", "dict", "tag_field", "tag", "rename", "omit_defaults", "forbid_unknown_fields", "frozen", "eq", "order", "kw_only", "repr_omit_defaults", "array_like", "gc", "weakref", "dict", "cache_hash", NULL }; /* Parse arguments: (name, bases, dict) */ if (!PyArg_ParseTupleAndKeywords( args, kwargs, "UO!O!|$OOOpppppppppppp:StructMeta.__new__", kwlist, &name, &PyTuple_Type, &bases, &PyDict_Type, &namespace, &arg_tag_field, &arg_tag, &arg_rename, &arg_omit_defaults, &arg_forbid_unknown_fields, &arg_frozen, &arg_eq, &arg_order, &arg_kw_only, &arg_repr_omit_defaults, &arg_array_like, &arg_gc, &arg_weakref, &arg_dict, &arg_cache_hash ) ) return NULL; return StructMeta_new_inner( type, name, bases, namespace, arg_tag_field, arg_tag, arg_rename, arg_omit_defaults, arg_forbid_unknown_fields, arg_frozen, arg_eq, arg_order, arg_kw_only, arg_repr_omit_defaults, arg_array_like, arg_gc, arg_weakref, arg_dict, arg_cache_hash ); } PyDoc_STRVAR(msgspec_defstruct__doc__, "defstruct(name, fields, *, bases=None, module=None, namespace=None, " "tag_field=None, tag=None, rename=None, omit_defaults=False, " "forbid_unknown_fields=False, frozen=False, eq=True, order=False, " "kw_only=False, repr_omit_defaults=False, array_like=False, gc=True, " "weakref=False, dict=False, cache_hash=False)\n" "--\n" "\n" "Dynamically define a new Struct class.\n" "\n" "Parameters\n" "----------\n" "name : str\n" " The name of the new Struct class.\n" "fields : iterable\n" " An iterable of fields in the new class. Elements may be either ``name``,\n" " tuples of ``(name, type)``, ``(name, type, default)``, or \n" " ``(name, type, msgspec.field)``. Fields without a specified type will \n" " default to ``typing.Any``.\n" "bases : tuple, optional\n" " A tuple of any Struct base classes to use when defining the new class.\n" "module : str, optional\n" " The module name to use for the new class. If not provided, will be inferred\n" " from the caller's stack frame.\n" "namespace : dict, optional\n" " If provided, will be used as the base namespace for the new class. This may\n" " be used to add additional methods to the class definition.\n" "**kwargs :\n" " Additional Struct configuration options. See the ``Struct`` docs for more\n" " information.\n" "\n" "Examples\n" "--------\n" ">>> from msgspec import defstruct, field\n" ">>> User = defstruct(\n" "... 'User',\n" "... [\n" "... ('name', str),\n" "... ('email', str | None, None),\n" "... ('groups', set[str], field(default_factory=set)),\n" "... ],\n" "... )\n" ">>> User('alice')\n" "User(name='alice', email=None, groups=set())\n" "\n" "See Also\n" "--------\n" "Struct" ); static PyObject * msgspec_defstruct(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *name = NULL, *fields = NULL, *bases = NULL, *module = NULL, *namespace = NULL; PyObject *arg_tag_field = NULL, *arg_tag = NULL, *arg_rename = NULL; PyObject *new_bases = NULL, *annotations = NULL, *fields_fast = NULL, *out = NULL; int arg_omit_defaults = -1, arg_forbid_unknown_fields = -1; int arg_frozen = -1, arg_eq = -1, arg_order = -1, arg_kw_only = 0; int arg_repr_omit_defaults = -1, arg_array_like = -1; int arg_gc = -1, arg_weakref = -1, arg_dict = -1, arg_cache_hash = -1; char *kwlist[] = { "name", "fields", "bases", "module", "namespace", "tag_field", "tag", "rename", "omit_defaults", "forbid_unknown_fields", "frozen", "eq", "order", "kw_only", "repr_omit_defaults", "array_like", "gc", "weakref", "dict", "cache_hash", NULL }; /* Parse arguments: (name, bases, dict) */ if (!PyArg_ParseTupleAndKeywords( args, kwargs, "UO|$OOOOOOpppppppppppp:defstruct", kwlist, &name, &fields, &bases, &module, &namespace, &arg_tag_field, &arg_tag, &arg_rename, &arg_omit_defaults, &arg_forbid_unknown_fields, &arg_frozen, &arg_eq, &arg_order, &arg_kw_only, &arg_repr_omit_defaults, &arg_array_like, &arg_gc, &arg_weakref, &arg_dict, &arg_cache_hash) ) return NULL; MsgspecState *mod = msgspec_get_state(self); /* Handle namespace */ if (namespace == NULL || namespace == Py_None) { namespace = PyDict_New(); } else { if (!PyDict_Check(namespace)) { PyErr_SetString(PyExc_TypeError, "namespace must be a dict or None"); return NULL; } namespace = PyDict_Copy(namespace); } if (namespace == NULL) return NULL; /* Handle module */ if (module != NULL && module != Py_None) { if (!PyUnicode_CheckExact(module)) { PyErr_SetString(PyExc_TypeError, "module must be a str or None"); goto cleanup; } if (PyDict_SetItemString(namespace, "__module__", module) < 0) goto cleanup; } /* Handle bases */ if (bases == NULL || bases == Py_None) { new_bases = PyTuple_New(1); if (new_bases == NULL) goto cleanup; Py_INCREF(mod->StructType); PyTuple_SET_ITEM(new_bases, 0, mod->StructType); bases = new_bases; } else if (!PyTuple_CheckExact(bases)) { PyErr_SetString(PyExc_TypeError, "bases must be a tuple or None"); goto cleanup; } annotations = PyDict_New(); if (annotations == NULL) goto cleanup; fields_fast = PySequence_Fast(fields, "`fields` must be an iterable"); if (fields_fast == NULL) goto cleanup; Py_ssize_t nfields = PySequence_Fast_GET_SIZE(fields_fast); for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *name = NULL, *type = NULL, *default_val = NULL; PyObject *field = PySequence_Fast_GET_ITEM(fields_fast, i); if (PyUnicode_Check(field)) { name = field; type = mod->typing_any; } else if (PyTuple_Check(field)) { Py_ssize_t len = PyTuple_GET_SIZE(field); if (len == 2) { name = PyTuple_GET_ITEM(field, 0); type = PyTuple_GET_ITEM(field, 1); } else if (len == 3) { name = PyTuple_GET_ITEM(field, 0); type = PyTuple_GET_ITEM(field, 1); default_val = PyTuple_GET_ITEM(field, 2); } } if (name == NULL || !PyUnicode_Check(name)) { PyErr_SetString( PyExc_TypeError, "items in `fields` must be one of `str`, `tuple[str, type]`, or `tuple[str, type, Any]`" ); goto cleanup; } if (PyDict_SetItem(annotations, name, type) < 0) goto cleanup; if (default_val != NULL) { if (PyDict_SetItem(namespace, name, default_val) < 0) goto cleanup; } } if (PyDict_SetItemString(namespace, "__annotations__", annotations) < 0) goto cleanup; out = StructMeta_new_inner( &StructMetaType, name, bases, namespace, arg_tag_field, arg_tag, arg_rename, arg_omit_defaults, arg_forbid_unknown_fields, arg_frozen, arg_eq, arg_order, arg_kw_only, arg_repr_omit_defaults, arg_array_like, arg_gc, arg_weakref, arg_dict, arg_cache_hash ); cleanup: Py_XDECREF(namespace); Py_XDECREF(new_bases); Py_XDECREF(annotations); Py_XDECREF(fields_fast); return out; } static int StructInfo_traverse(StructInfo *self, visitproc visit, void *arg) { Py_VISIT(self->class); for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { int out = TypeNode_traverse(self->types[i], visit, arg); if (out != 0) return out; } return 0; } static int StructInfo_clear(StructInfo *self) { Py_CLEAR(self->class); for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { TypeNode_Free(self->types[i]); self->types[i] = NULL; } return 0; } static void StructInfo_dealloc(StructInfo *self) { PyObject_GC_UnTrack(self); StructInfo_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyTypeObject StructInfo_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.StructInfo", .tp_basicsize = sizeof(StructInfo), .tp_itemsize = sizeof(TypeNode *), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)StructInfo_clear, .tp_traverse = (traverseproc)StructInfo_traverse, .tp_dealloc = (destructor)StructInfo_dealloc, }; static PyObject * StructInfo_Convert(PyObject *obj) { MsgspecState *mod = msgspec_get_global_state(); StructMetaObject *class; PyObject *annotations = NULL; StructInfo *info = NULL; bool cache_set = false; bool is_struct = Py_TYPE(obj) == &StructMetaType; /* Check for a cached StructInfo, and return if one exists */ if (MS_LIKELY(is_struct)) { class = (StructMetaObject *)obj; if (class->struct_info != NULL) { Py_INCREF(class->struct_info); return (PyObject *)(class->struct_info); } Py_INCREF(class); } else { PyObject *cached = NULL; if (get_msgspec_cache(mod, obj, &StructInfo_Type, &cached)) { return cached; } PyObject *origin = PyObject_GetAttr(obj, mod->str___origin__); if (origin == NULL) return NULL; if (Py_TYPE(origin) != &StructMetaType) { Py_DECREF(origin); PyErr_SetString( PyExc_RuntimeError, "Expected __origin__ to be a Struct type" ); return NULL; } class = (StructMetaObject *)origin; } /* At this point `class` is a StructMetaObject, and `obj` is a * StructMetaObject or Generic. `class` has already been incref'd */ /* Ensure the StructMetaObject is fully initialized */ if (MS_UNLIKELY(class->struct_fields == NULL)) { PyErr_Format( PyExc_ValueError, "Type `%R` isn't fully defined, and can't be used in any " "`Decoder`/`decode` operations. This commonly happens when " "trying to use the struct type within an `__init_subclass__` " "method. If you believe what you're trying to do should work, " "please raise an issue on GitHub.", (PyObject *)class ); goto error; } /* Extract annotations from the original type object */ annotations = PyObject_CallOneArg(mod->get_class_annotations, obj); if (annotations == NULL) goto error; /* Allocate and zero-out a new StructInfo */ Py_ssize_t nfields = PyTuple_GET_SIZE(class->struct_fields); info = PyObject_GC_NewVar(StructInfo, &StructInfo_Type, nfields); if (info == NULL) goto error; for (Py_ssize_t i = 0; i < nfields; i++) { info->types[i] = NULL; } Py_INCREF(class); info->class = class; /* Cache the new StuctInfo on the original type annotation */ if (is_struct) { Py_INCREF(info); class->struct_info = info; } else { if (PyObject_SetAttr(obj, mod->str___msgspec_cache__, (PyObject *)info) < 0) goto error; } cache_set = true; /* Process all the struct fields */ for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(class->struct_fields, i); PyObject *field_type = PyDict_GetItem(annotations, field); if (field_type == NULL) goto error; TypeNode *type = TypeNode_Convert(field_type); if (type == NULL) goto error; info->types[i] = type; } Py_DECREF(class); Py_DECREF(annotations); PyObject_GC_Track(info); return (PyObject *)info; error: if (cache_set) { /* An error occurred after the cache was created and set on the object. * We need to delete the cached value. */ if (is_struct) { Py_CLEAR(class->struct_info); } else { /* Fetch and restore the original exception to avoid DelAttr * silently clearing it on rare occasions. */ PyObject *err_type, *err_value, *err_tb; PyErr_Fetch(&err_type, &err_value, &err_tb); PyObject_DelAttr(obj, mod->str___msgspec_cache__); PyErr_Restore(err_type, err_value, err_tb); } } Py_DECREF(class); Py_XDECREF(annotations); Py_XDECREF(info); return NULL; } static int StructMeta_traverse(StructMetaObject *self, visitproc visit, void *arg) { Py_VISIT(self->struct_fields); Py_VISIT(self->struct_defaults); Py_VISIT(self->struct_encode_fields); Py_VISIT(self->struct_tag); /* May be a function */ Py_VISIT(self->rename); /* May be a function */ Py_VISIT(self->post_init); Py_VISIT(self->struct_info); return PyType_Type.tp_traverse((PyObject *)self, visit, arg); } static int StructMeta_clear(StructMetaObject *self) { /* skip if clear already invoked */ if (self->struct_fields == NULL) return 0; Py_CLEAR(self->struct_fields); Py_CLEAR(self->struct_defaults); Py_CLEAR(self->struct_encode_fields); Py_CLEAR(self->struct_tag_field); Py_CLEAR(self->struct_tag_value); Py_CLEAR(self->struct_tag); Py_CLEAR(self->rename); Py_CLEAR(self->post_init); Py_CLEAR(self->struct_info); Py_CLEAR(self->match_args); if (self->struct_offsets != NULL) { PyMem_Free(self->struct_offsets); self->struct_offsets = NULL; } return PyType_Type.tp_clear((PyObject *)self); } static void StructMeta_dealloc(StructMetaObject *self) { /* The GC invariants require dealloc immediately untrack to avoid double * deallocation. However, PyType_Type.tp_dealloc assumes the type is * currently tracked. Hence the unfortunate untrack/retrack below. */ PyObject_GC_UnTrack(self); StructMeta_clear(self); PyObject_GC_Track(self); PyType_Type.tp_dealloc((PyObject *)self); } static PyObject* StructMeta_signature(StructMetaObject *self, void *closure) { Py_ssize_t nfields, ndefaults, npos, nkwonly, i; MsgspecState *st; PyObject *res = NULL; PyObject *inspect = NULL; PyObject *parameter_cls = NULL; PyObject *parameter_empty = NULL; PyObject *kind_positional = NULL; PyObject *kind_kw_only = NULL; PyObject *signature_cls = NULL; PyObject *annotations = NULL; PyObject *parameters = NULL; PyObject *temp_args = NULL, *temp_kwargs = NULL; PyObject *field, *kind, *default_val, *parameter, *annotation; st = msgspec_get_global_state(); nfields = PyTuple_GET_SIZE(self->struct_fields); ndefaults = PyTuple_GET_SIZE(self->struct_defaults); npos = nfields - ndefaults; nkwonly = self->nkwonly; inspect = PyImport_ImportModule("inspect"); if (inspect == NULL) goto cleanup; parameter_cls = PyObject_GetAttrString(inspect, "Parameter"); if (parameter_cls == NULL) goto cleanup; parameter_empty = PyObject_GetAttrString(parameter_cls, "empty"); if (parameter_empty == NULL) goto cleanup; kind_positional = PyObject_GetAttrString(parameter_cls, "POSITIONAL_OR_KEYWORD"); if (kind_positional == NULL) goto cleanup; kind_kw_only = PyObject_GetAttrString(parameter_cls, "KEYWORD_ONLY"); if (kind_kw_only == NULL) goto cleanup; signature_cls = PyObject_GetAttrString(inspect, "Signature"); if (signature_cls == NULL) goto cleanup; annotations = PyObject_CallOneArg(st->get_type_hints, (PyObject *)self); if (annotations == NULL) goto cleanup; parameters = PyList_New(nfields); if (parameters == NULL) return NULL; temp_args = PyTuple_New(0); if (temp_args == NULL) goto cleanup; temp_kwargs = PyDict_New(); if (temp_kwargs == NULL) goto cleanup; for (i = 0; i < nfields; i++) { field = PyTuple_GET_ITEM(self->struct_fields, i); if (i < npos) { default_val = parameter_empty; } else { default_val = PyTuple_GET_ITEM(self->struct_defaults, i - npos); if (default_val == NODEFAULT) { default_val = parameter_empty; } } if (i < (nfields - nkwonly)) { kind = kind_positional; } else { kind = kind_kw_only; } annotation = PyDict_GetItem(annotations, field); if (annotation == NULL) { annotation = parameter_empty; } if (PyDict_SetItemString(temp_kwargs, "name", field) < 0) goto cleanup; if (PyDict_SetItemString(temp_kwargs, "kind", kind) < 0) goto cleanup; if (PyDict_SetItemString(temp_kwargs, "default", default_val) < 0) goto cleanup; if (PyDict_SetItemString(temp_kwargs, "annotation", annotation) < 0) goto cleanup; parameter = PyObject_Call(parameter_cls, temp_args, temp_kwargs); if (parameter == NULL) goto cleanup; PyList_SET_ITEM(parameters, i, parameter); } res = PyObject_CallOneArg(signature_cls, parameters); cleanup: Py_XDECREF(inspect); Py_XDECREF(parameter_cls); Py_XDECREF(parameter_empty); Py_XDECREF(kind_positional); Py_XDECREF(kind_kw_only); Py_XDECREF(signature_cls); Py_XDECREF(annotations); Py_XDECREF(parameters); Py_XDECREF(temp_args); Py_XDECREF(temp_kwargs); return res; } static PyObject* StructConfig_frozen(StructConfig *self, void *closure) { if (self->st_type->frozen == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_eq(StructConfig *self, void *closure) { if (self->st_type->eq == OPT_FALSE) { Py_RETURN_FALSE; } else { Py_RETURN_TRUE; } } static PyObject* StructConfig_order(StructConfig *self, void *closure) { if (self->st_type->order == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_array_like(StructConfig *self, void *closure) { if (self->st_type->array_like == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_gc(StructConfig *self, void *closure) { if (self->st_type->gc == OPT_FALSE) { Py_RETURN_FALSE; } else { Py_RETURN_TRUE; } } static PyObject* StructConfig_weakref(StructConfig *self, void *closure) { PyTypeObject *type = (PyTypeObject *)(self->st_type); if (type->tp_weaklistoffset) { Py_RETURN_TRUE; } Py_RETURN_FALSE; } static PyObject* StructConfig_dict(StructConfig *self, void *closure) { PyTypeObject *type = (PyTypeObject *)(self->st_type); if (type->tp_dictoffset) { Py_RETURN_TRUE; } Py_RETURN_FALSE; } static PyObject* StructConfig_cache_hash(StructConfig *self, void *closure) { StructMetaObject *type = (StructMetaObject *)(self->st_type); if (type->hash_offset != 0) { Py_RETURN_TRUE; } Py_RETURN_FALSE; } static PyObject* StructConfig_repr_omit_defaults(StructConfig *self, void *closure) { if (self->st_type->repr_omit_defaults == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_omit_defaults(StructConfig *self, void *closure) { if (self->st_type->omit_defaults == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_forbid_unknown_fields(StructConfig *self, void *closure) { if (self->st_type->forbid_unknown_fields == OPT_TRUE) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* StructConfig_tag_field(StructConfig *self, void *closure) { PyObject *out = self->st_type->struct_tag_field; if (out == NULL) Py_RETURN_NONE; Py_INCREF(out); return out; } static PyObject* StructConfig_tag(StructConfig *self, void *closure) { PyObject *out = self->st_type->struct_tag_value; if (out == NULL) Py_RETURN_NONE; Py_INCREF(out); return out; } static PyGetSetDef StructConfig_getset[] = { {"frozen", (getter) StructConfig_frozen, NULL, NULL, NULL}, {"eq", (getter) StructConfig_eq, NULL, NULL, NULL}, {"order", (getter) StructConfig_order, NULL, NULL, NULL}, {"repr_omit_defaults", (getter) StructConfig_repr_omit_defaults, NULL, NULL, NULL}, {"array_like", (getter) StructConfig_array_like, NULL, NULL, NULL}, {"gc", (getter) StructConfig_gc, NULL, NULL, NULL}, {"weakref", (getter) StructConfig_weakref, NULL, NULL, NULL}, {"dict", (getter) StructConfig_dict, NULL, NULL, NULL}, {"cache_hash", (getter) StructConfig_cache_hash, NULL, NULL, NULL}, {"omit_defaults", (getter) StructConfig_omit_defaults, NULL, NULL, NULL}, {"forbid_unknown_fields", (getter) StructConfig_forbid_unknown_fields, NULL, NULL, NULL}, {"tag", (getter) StructConfig_tag, NULL, NULL, NULL}, {"tag_field", (getter) StructConfig_tag_field, NULL, NULL, NULL}, {NULL}, }; static int StructConfig_traverse(StructConfig *self, visitproc visit, void *arg) { Py_VISIT(self->st_type); return 0; } static int StructConfig_clear(StructConfig *self) { Py_CLEAR(self->st_type); return 0; } static void StructConfig_dealloc(StructConfig *self) { PyObject_GC_UnTrack(self); StructConfig_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } PyDoc_STRVAR(StructConfig__doc__, "StructConfig()\n" "--\n" "\n" "Configuration settings for a given Struct type.\n" "\n" "This object is accessible through the ``__struct_config__`` field on a struct\n" "type or instance. It exposes the following attributes, matching the Struct\n" "configuration parameters of the same name. See the `Struct` docstring for\n" "details.\n" "\n" "Configuration\n" "-------------\n" "frozen: bool\n" "eq: bool\n" "order: bool\n" "array_like: bool\n" "gc: bool\n" "repr_omit_defaults: bool\n" "omit_defaults: bool\n" "forbid_unknown_fields: bool\n" "weakref: bool\n" "dict: bool\n" "cache_hash: bool\n" "tag_field: str | None\n" "tag: str | int | None" ); static PyTypeObject StructConfig_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.structs.StructConfig", .tp_doc = StructConfig__doc__, .tp_basicsize = sizeof(StructConfig), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_new = NULL, .tp_dealloc = (destructor) StructConfig_dealloc, .tp_clear = (inquiry) StructConfig_clear, .tp_traverse = (traverseproc) StructConfig_traverse, .tp_getset = StructConfig_getset, }; static PyObject* StructConfig_New(StructMetaObject *st_type) { StructConfig *out = (StructConfig *)StructConfig_Type.tp_alloc(&StructConfig_Type, 0); if (out == NULL) return NULL; out->st_type = st_type; Py_INCREF(st_type); return (PyObject *)out; } static PyObject* StructMeta_config(StructMetaObject *self, void *closure) { return StructConfig_New(self); } static PyMemberDef StructMeta_members[] = { {"__struct_fields__", T_OBJECT_EX, offsetof(StructMetaObject, struct_fields), READONLY, "Struct fields"}, {"__struct_defaults__", T_OBJECT_EX, offsetof(StructMetaObject, struct_defaults), READONLY, "Struct defaults"}, {"__struct_encode_fields__", T_OBJECT_EX, offsetof(StructMetaObject, struct_encode_fields), READONLY, "Struct encoded field names"}, {"__match_args__", T_OBJECT_EX, offsetof(StructMetaObject, match_args), READONLY, "Positional match args"}, {NULL}, }; static PyGetSetDef StructMeta_getset[] = { {"__signature__", (getter) StructMeta_signature, NULL, NULL, NULL}, {"__struct_config__", (getter) StructMeta_config, NULL, "Struct configuration", NULL}, {NULL}, }; static PyTypeObject StructMetaType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.StructMeta", .tp_basicsize = sizeof(StructMetaObject), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_TYPE_SUBCLASS | Py_TPFLAGS_HAVE_GC | _Py_TPFLAGS_HAVE_VECTORCALL, .tp_new = StructMeta_new, .tp_dealloc = (destructor) StructMeta_dealloc, .tp_clear = (inquiry) StructMeta_clear, .tp_traverse = (traverseproc) StructMeta_traverse, .tp_members = StructMeta_members, .tp_getset = StructMeta_getset, .tp_call = PyVectorcall_Call, .tp_vectorcall_offset = offsetof(PyTypeObject, tp_vectorcall), }; static PyObject * get_default(PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (type == &Factory_Type) { return Factory_Call(obj); } Py_INCREF(obj); return obj; } static MS_INLINE bool is_default(PyObject *x, PyObject *d) { if (x == d) return true; if (Py_TYPE(d) == &Factory_Type) { PyTypeObject *factory = (PyTypeObject *)(((Factory *)d)->factory); if (Py_TYPE(x) != factory) return false; if (factory == &PyList_Type && PyList_GET_SIZE(x) == 0) return true; if (factory == &PyDict_Type && PyDict_GET_SIZE(x) == 0) return true; if (factory == &PySet_Type && PySet_GET_SIZE(x) == 0) return true; } return false; } /* Set field #index on obj. Steals a reference to val */ static inline void Struct_set_index(PyObject *obj, Py_ssize_t index, PyObject *val) { StructMetaObject *cls; char *addr; PyObject *old; cls = (StructMetaObject *)Py_TYPE(obj); addr = (char *)obj + cls->struct_offsets[index]; old = *(PyObject **)addr; Py_XDECREF(old); *(PyObject **)addr = val; } /* Get field #index or NULL on obj. Returns a borrowed reference */ static inline PyObject* Struct_get_index_noerror(PyObject *obj, Py_ssize_t index) { StructMetaObject *cls = (StructMetaObject *)Py_TYPE(obj); char *addr = (char *)obj + cls->struct_offsets[index]; return *(PyObject **)addr; } /* Get field #index on obj. Returns a borrowed reference */ static inline PyObject* Struct_get_index(PyObject *obj, Py_ssize_t index) { PyObject *val = Struct_get_index_noerror(obj, index); if (val == NULL) { StructMetaObject *cls = (StructMetaObject *)Py_TYPE(obj); PyErr_Format(PyExc_AttributeError, "Struct field %R is unset", PyTuple_GET_ITEM(cls->struct_fields, index)); } return val; } static MS_INLINE int Struct_post_init(StructMetaObject *st_type, PyObject *obj) { if (st_type->post_init != NULL) { PyObject *res = PyObject_CallOneArg(st_type->post_init, obj); if (res == NULL) return -1; Py_DECREF(res); } return 0; } static MS_INLINE int Struct_decode_post_init(StructMetaObject *st_type, PyObject *obj, PathNode *path) { if (MS_UNLIKELY(Struct_post_init(st_type, obj) < 0)) { ms_maybe_wrap_validation_error(path); return -1; } return 0; } /* ASSUMPTION - obj is untracked and allocated via Struct_alloc */ static int Struct_fill_in_defaults(StructMetaObject *st_type, PyObject *obj, PathNode *path) { Py_ssize_t nfields, ndefaults, i; bool is_gc, should_untrack; nfields = PyTuple_GET_SIZE(st_type->struct_encode_fields); ndefaults = PyTuple_GET_SIZE(st_type->struct_defaults); is_gc = MS_TYPE_IS_GC(st_type); should_untrack = is_gc; for (i = 0; i < nfields; i++) { PyObject *val = Struct_get_index_noerror(obj, i); if (val == NULL) { if (MS_UNLIKELY(i < (nfields - ndefaults))) goto missing_required; val = PyTuple_GET_ITEM( st_type->struct_defaults, i - (nfields - ndefaults) ); if (MS_UNLIKELY(val == NODEFAULT)) goto missing_required; val = get_default(val); if (MS_UNLIKELY(val == NULL)) return -1; Struct_set_index(obj, i, val); } if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } if (is_gc && !should_untrack) PyObject_GC_Track(obj); if (Struct_decode_post_init(st_type, obj, path) < 0) return -1; return 0; missing_required: ms_missing_required_field( PyTuple_GET_ITEM(st_type->struct_encode_fields, i), path ); return -1; } static PyObject * Struct_vectorcall(PyTypeObject *cls, PyObject *const *args, size_t nargsf, PyObject *kwnames) { Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); StructMetaObject *st_type = (StructMetaObject *)cls; PyObject *fields = st_type->struct_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); PyObject *defaults = st_type->struct_defaults; Py_ssize_t ndefaults = PyTuple_GET_SIZE(defaults); Py_ssize_t nkwonly = st_type->nkwonly; Py_ssize_t npos = nfields - ndefaults; if (MS_UNLIKELY(nargs > (nfields - nkwonly))) { PyErr_SetString(PyExc_TypeError, "Extra positional arguments provided"); return NULL; } bool is_gc = MS_TYPE_IS_GC(cls); bool should_untrack = is_gc; PyObject *self = Struct_alloc(cls); if (self == NULL) return NULL; /* First, process all positional arguments */ for (Py_ssize_t i = 0; i < nargs; i++) { PyObject *val = args[i]; char *addr = (char *)self + st_type->struct_offsets[i]; Py_INCREF(val); *(PyObject **)addr = val; if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } /* Next, process all kwargs */ for (Py_ssize_t i = 0; i < nkwargs; i++) { char *addr; PyObject *val; Py_ssize_t field_index; PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); /* Since keyword names are interned, first loop with pointer * comparisons only. */ for (field_index = nargs; field_index < nfields; field_index++) { PyObject *field = PyTuple_GET_ITEM(fields, field_index); if (MS_LIKELY(kwname == field)) goto kw_found; } /* Fast path failed. It's more likely that this is an invalid kwarg * than that the kwname wasn't interned. Loop from 0 this time to also * check for parameters passed both as arg and kwarg */ for (field_index = 0; field_index < nfields; field_index++) { PyObject *field = PyTuple_GET_ITEM(fields, field_index); if (MS_UNICODE_EQ(kwname, field)) { if (MS_UNLIKELY(field_index < nargs)) { PyErr_Format( PyExc_TypeError, "Argument '%U' given by name and position", kwname ); goto error; } goto kw_found; } } /* Unknown keyword */ PyErr_Format(PyExc_TypeError, "Unexpected keyword argument '%U'", kwname); goto error; kw_found: val = args[i + nargs]; addr = (char *)self + st_type->struct_offsets[field_index]; Py_INCREF(val); *(PyObject **)addr = val; if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } /* Finally, fill in missing defaults */ if (nargs + nkwargs < nfields) { for (Py_ssize_t field_index = nargs; field_index < nfields; field_index++) { char *addr = (char *)self + st_type->struct_offsets[field_index]; if (MS_LIKELY(*(PyObject **)addr == NULL)) { if (MS_LIKELY(field_index >= npos)) { PyObject *val = PyTuple_GET_ITEM(defaults, field_index - npos); if (MS_LIKELY(val != NODEFAULT)) { val = get_default(val); if (MS_UNLIKELY(val == NULL)) goto error; *(PyObject **)addr = val; if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } continue; } } PyErr_Format( PyExc_TypeError, "Missing required argument '%U'", PyTuple_GET_ITEM(fields, field_index) ); goto error; } } } if (is_gc && !should_untrack) PyObject_GC_Track(self); if (Struct_post_init(st_type, self) < 0) goto error; return self; error: Py_DECREF(self); return NULL; } static PyObject * Struct_repr(PyObject *self) { StructMetaObject *st_type = (StructMetaObject *)(Py_TYPE(self)); bool omit_defaults = st_type->repr_omit_defaults == OPT_TRUE; PyObject *fields = st_type->struct_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); PyObject *defaults = NULL; Py_ssize_t nunchecked = nfields; if (omit_defaults) { defaults = st_type->struct_defaults; nunchecked = nfields - PyTuple_GET_SIZE(defaults); } int recursive = Py_ReprEnter(self); if (recursive != 0) { return (recursive < 0) ? NULL : PyUnicode_FromString("..."); /* cpylint-ignore */ } strbuilder builder = {0}; bool first = true; const char *name = Py_TYPE(self)->tp_name; if (!strbuilder_extend(&builder, name, strlen(name))) goto error; if (!strbuilder_extend_literal(&builder, "(")) goto error; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(self, i); if (val == NULL) goto error; if (i >= nunchecked) { PyObject *default_val = PyTuple_GET_ITEM(defaults, i - nunchecked); if (is_default(val, default_val)) continue; } if (first) { first = false; } else { if (!strbuilder_extend_literal(&builder, ", ")) goto error; } if (!strbuilder_extend_unicode(&builder, field)) goto error; if (!strbuilder_extend_literal(&builder, "=")) goto error; PyObject *repr = PyObject_Repr(val); if (repr == NULL) goto error; bool ok = strbuilder_extend_unicode(&builder, repr); Py_DECREF(repr); if (!ok) goto error; } if (!strbuilder_extend_literal(&builder, ")")) goto error; PyObject *out = strbuilder_build(&builder); Py_ReprLeave(self); return out; error: strbuilder_reset(&builder); Py_ReprLeave(self); return NULL; } static Py_hash_t Struct_hash(PyObject *self) { PyObject *val; Py_ssize_t i, nfields; Py_uhash_t acc = MS_HASH_XXPRIME_5; StructMetaObject *st_type = (StructMetaObject *)Py_TYPE(self); if (MS_UNLIKELY(st_type->eq == OPT_FALSE)) { /* If `__eq__` isn't implemented, then the default pointer-based * `__hash__` should be used */ return PyBaseObject_Type.tp_hash(self); } if (MS_UNLIKELY(st_type->frozen != OPT_TRUE)) { /* If `__eq__` is implemented, only frozen types can be hashed */ return PyObject_HashNotImplemented(self); } if (MS_UNLIKELY(st_type->hash_offset != 0)) { PyObject *cached_hash = *(PyObject **)((char *)self + st_type->hash_offset); if (cached_hash != NULL) { /* Use the cached hash */ return PyLong_AsSsize_t(cached_hash); } } /* First hash the type by its pointer */ size_t type_id = (size_t)((void *)st_type); /* The lower bits are likely to be 0; rotate by 4 */ type_id = (type_id >> 4) | (type_id << (8 * sizeof(void *) - 4)); acc += type_id * MS_HASH_XXPRIME_2; acc = MS_HASH_XXROTATE(acc); acc *= MS_HASH_XXPRIME_1; /* Then hash all the fields */ nfields = StructMeta_GET_NFIELDS(Py_TYPE(self)); for (i = 0; i < nfields; i++) { val = Struct_get_index(self, i); if (val == NULL) return -1; Py_uhash_t item_hash = PyObject_Hash(val); if (item_hash == (Py_uhash_t)-1) return -1; acc += item_hash * MS_HASH_XXPRIME_2; acc = MS_HASH_XXROTATE(acc); acc *= MS_HASH_XXPRIME_1; } acc += (1 + nfields) ^ (MS_HASH_XXPRIME_5 ^ 3527539UL); Py_uhash_t hash = (acc == (Py_uhash_t)-1) ? 1546275796 : acc; if (MS_UNLIKELY(st_type->hash_offset != 0)) { /* Cache the hash */ char *addr = (char *)self + st_type->hash_offset; PyObject *cached_hash = PyLong_FromSsize_t(hash); if (cached_hash == NULL) return -1; *(PyObject **)addr = cached_hash; } return hash; } static PyObject * Struct_richcompare(PyObject *self, PyObject *other, int op) { if (Py_TYPE(self) != Py_TYPE(other)) { Py_RETURN_NOTIMPLEMENTED; } StructMetaObject *st_type = (StructMetaObject *)(Py_TYPE(self)); if (op == Py_EQ || op == Py_NE) { if (MS_UNLIKELY(st_type->eq == OPT_FALSE)) { Py_RETURN_NOTIMPLEMENTED; } } else if (st_type->order != OPT_TRUE) { Py_RETURN_NOTIMPLEMENTED; } if ( MS_UNLIKELY(op == Py_NE && (Py_TYPE(self)->tp_richcompare != Struct_richcompare)) ) { /* This case is hit when a subclass has manually defined `__eq__` but * not `__ne__`. In this case we want to dispatch to `__eq__` and invert * the result, rather than relying on the default `__ne__` implementation. */ PyObject *out = Py_TYPE(self)->tp_richcompare(self, other, Py_EQ); if (out != NULL && out != Py_NotImplemented) { int is_true = PyObject_IsTrue(out); Py_DECREF(out); if (is_true < 0) { out = NULL; } else { out = is_true ? Py_False : Py_True; Py_INCREF(out); } } return out; } int equal = 1; PyObject *left = NULL, *right = NULL; /* Only need to loop if self is not other` */ if (MS_LIKELY(self != other)) { Py_ssize_t nfields = StructMeta_GET_NFIELDS(st_type); for (Py_ssize_t i = 0; i < nfields; i++) { left = Struct_get_index(self, i); if (left == NULL) return NULL; right = Struct_get_index(other, i); if (right == NULL) return NULL; equal = PyObject_RichCompareBool(left, right, Py_EQ); if (equal < 0) return NULL; if (equal == 0) break; } } if (equal) { if (op == Py_EQ || op == Py_GE || op == Py_LE) { Py_RETURN_TRUE; } else if (op == Py_NE) { Py_RETURN_FALSE; } else if (left == NULL) { /* < or > on two 0-field or identical structs */ Py_RETURN_FALSE; } } else if (op == Py_EQ) { Py_RETURN_FALSE; } else if (op == Py_NE) { Py_RETURN_TRUE; } /* Need to compare final element again to determine proper result */ return PyObject_RichCompare(left, right, op); } static PyObject * Struct_copy(PyObject *self, PyObject *args) { Py_ssize_t i, nfields; PyObject *val, *res = NULL; res = Struct_alloc(Py_TYPE(self)); if (res == NULL) return NULL; nfields = StructMeta_GET_NFIELDS(Py_TYPE(self)); for (i = 0; i < nfields; i++) { val = Struct_get_index(self, i); if (val == NULL) goto error; Py_INCREF(val); Struct_set_index(res, i, val); } /* If self is tracked, then copy is tracked */ if (MS_OBJECT_IS_GC(self) && MS_IS_TRACKED(self)) PyObject_GC_Track(res); return res; error: Py_DECREF(res); return NULL; } static PyObject * Struct_replace( PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames ) { Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); if (!check_positional_nargs(nargs, 0, 0)) return NULL; StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(self); PyObject *fields = struct_type->struct_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); bool is_gc = MS_TYPE_IS_GC(struct_type); bool should_untrack = is_gc; PyObject *out = Struct_alloc((PyTypeObject *)struct_type); if (out == NULL) return NULL; for (Py_ssize_t i = 0; i < nkwargs; i++) { PyObject *val; Py_ssize_t field_index; PyObject *kwname = PyTuple_GET_ITEM(kwnames, i); /* Since keyword names are interned, first loop with pointer * comparisons only. */ for (field_index = 0; field_index < nfields; field_index++) { PyObject *field = PyTuple_GET_ITEM(fields, field_index); if (MS_LIKELY(kwname == field)) goto kw_found; } for (field_index = 0; field_index < nfields; field_index++) { PyObject *field = PyTuple_GET_ITEM(fields, field_index); if (MS_UNICODE_EQ(kwname, field)) goto kw_found; } /* Unknown keyword */ PyErr_Format( PyExc_TypeError, "`%.200s` has no field '%U'", ((PyTypeObject *)struct_type)->tp_name, kwname ); goto error; kw_found: val = args[i]; Py_INCREF(val); Struct_set_index(out, field_index, val); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } for (Py_ssize_t i = 0; i < nfields; i++) { if (Struct_get_index_noerror(out, i) == NULL) { PyObject *val = Struct_get_index(self, i); if (val == NULL) goto error; if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } Py_INCREF(val); Struct_set_index(out, i, val); } } if (is_gc && !should_untrack) { PyObject_GC_Track(out); } return out; error: Py_DECREF(out); return NULL; } static AssocList * AssocList_FromStruct(PyObject *obj) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; bool ok = false; StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); PyObject *tag_field = struct_type->struct_tag_field; PyObject *tag_value = struct_type->struct_tag_value; PyObject *fields = struct_type->struct_encode_fields; PyObject *defaults = struct_type->struct_defaults; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); Py_ssize_t npos = nfields - PyTuple_GET_SIZE(defaults); bool omit_defaults = struct_type->omit_defaults == OPT_TRUE; AssocList *out = AssocList_New(nfields + (tag_value != NULL)); if (out == NULL) goto cleanup; if (tag_value != NULL) { if (AssocList_Append(out, tag_field, tag_value) < 0) goto cleanup; } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *key = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(obj, i); if (MS_UNLIKELY(val == NULL)) goto cleanup; if (MS_UNLIKELY(val == UNSET)) continue; if ( !omit_defaults || i < npos || !is_default(val, PyTuple_GET_ITEM(defaults, i - npos)) ) { if (AssocList_Append(out, key, val) < 0) goto cleanup; } } ok = true; cleanup: Py_LeaveRecursiveCall(); if (!ok) { AssocList_Free(out); } return out; } PyDoc_STRVAR(struct_replace__doc__, "replace(struct, / **changes)\n" "--\n" "\n" "Create a new struct instance of the same type as ``struct``, replacing fields\n" "with values from ``**changes``.\n" "\n" "Parameters\n" "----------\n" "struct: Struct\n" " The original struct instance.\n" "**changes:\n" " Fields and values that should be replaced in the new struct instance.\n" "\n" "Returns\n" "-------\n" "new_struct: Struct\n" " A new struct instance of the same type as ``struct``.\n" "\n" "Examples\n" "--------\n" ">>> class Point(msgspec.Struct):\n" "... x: int\n" "... y: int\n" ">>> obj = Point(x=1, y=2)\n" ">>> msgspec.structs.replace(obj, x=3)\n" "Point(x=3, y=2)\n" "\n" "See Also\n" "--------\n" "copy.replace\n" "dataclasses.replace" ); static PyObject* struct_replace(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { if (!check_positional_nargs(nargs, 1, 1)) return NULL; PyObject *obj = args[0]; if (Py_TYPE(Py_TYPE(obj)) != &StructMetaType) { PyErr_SetString(PyExc_TypeError, "`struct` must be a `msgspec.Struct`"); return NULL; } return Struct_replace(obj, args + 1, 0, kwnames); } PyDoc_STRVAR(struct_asdict__doc__, "asdict(struct)\n" "--\n" "\n" "Convert a struct to a dict.\n" "\n" "Parameters\n" "----------\n" "struct: Struct\n" " The struct instance.\n" "\n" "Returns\n" "-------\n" "dict\n" "\n" "Examples\n" "--------\n" ">>> class Point(msgspec.Struct):\n" "... x: int\n" "... y: int\n" ">>> obj = Point(x=1, y=2)\n" ">>> msgspec.structs.asdict(obj)\n" "{'x': 1, 'y': 2}\n" "\n" "See Also\n" "--------\n" "msgspec.structs.astuple\n" "msgspec.to_builtins" ); static PyObject* struct_asdict(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) return NULL; PyObject *obj = args[0]; if (Py_TYPE(Py_TYPE(obj)) != &StructMetaType) { PyErr_SetString(PyExc_TypeError, "`struct` must be a `msgspec.Struct`"); return NULL; } StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); PyObject *fields = struct_type->struct_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); PyObject *out = PyDict_New(); if (out == NULL) return NULL; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *key = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(obj, i); if (val == NULL) goto error; if (PyDict_SetItem(out, key, val) < 0) goto error; } return out; error: Py_DECREF(out); return NULL; } PyDoc_STRVAR(struct_astuple__doc__, "astuple(struct)\n" "--\n" "\n" "Convert a struct to a tuple.\n" "\n" "Parameters\n" "----------\n" "struct: Struct\n" " The struct instance.\n" "\n" "Returns\n" "-------\n" "tuple\n" "\n" "Examples\n" "--------\n" ">>> class Point(msgspec.Struct):\n" "... x: int\n" "... y: int\n" ">>> obj = Point(x=1, y=2)\n" ">>> msgspec.structs.astuple(obj)\n" "(1, 2)\n" "\n" "See Also\n" "--------\n" "msgspec.structs.asdict\n" "msgspec.to_builtins" ); static PyObject* struct_astuple(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) return NULL; PyObject *obj = args[0]; if (Py_TYPE(Py_TYPE(obj)) != &StructMetaType) { PyErr_SetString(PyExc_TypeError, "`struct` must be a `msgspec.Struct`"); return NULL; } StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); Py_ssize_t nfields = PyTuple_GET_SIZE(struct_type->struct_fields); PyObject *out = PyTuple_New(nfields); if (out == NULL) return NULL; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val = Struct_get_index(obj, i); if (val == NULL) goto error; Py_INCREF(val); PyTuple_SET_ITEM(out, i, val); } return out; error: Py_DECREF(out); return NULL; } PyDoc_STRVAR(struct_force_setattr__doc__, "force_setattr(struct, name, value)\n" "--\n" "\n" "Set an attribute on a struct, even if the struct is frozen.\n" "\n" "The main use case for this is modifying a frozen struct in a ``__post_init__``\n" "method before returning.\n" "\n" ".. warning::\n\n" " This function violates the guarantees of a frozen struct, and is potentially\n" " unsafe. Only use it if you know what you're doing!\n" "\n" "Parameters\n" "----------\n" "struct: Struct\n" " The struct instance.\n" "name: str\n" " The attribute name.\n" "value: Any\n" " The attribute value." ); static PyObject* struct_force_setattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 3, 3)) return NULL; PyObject *obj = args[0]; PyObject *name = args[1]; PyObject *value = args[2]; if (Py_TYPE(Py_TYPE(obj)) != &StructMetaType) { PyErr_SetString(PyExc_TypeError, "`struct` must be a `msgspec.Struct`"); return NULL; } if (PyObject_GenericSetAttr(obj, name, value) < 0) { return NULL; } Py_RETURN_NONE; } static PyObject * Struct_reduce(PyObject *self, PyObject *args) { PyObject *values = NULL, *out = NULL; StructMetaObject *st_type = (StructMetaObject *)(Py_TYPE(self)); Py_ssize_t nfields = PyTuple_GET_SIZE(st_type->struct_fields); if (st_type->nkwonly) { MsgspecState *mod = msgspec_get_global_state(); values = PyDict_New(); if (values == NULL) return NULL; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(st_type->struct_fields, i); PyObject *val = Struct_get_index(self, i); if (val == NULL) goto cleanup; if (PyDict_SetItem(values, field, val) < 0) goto cleanup; } out = Py_BuildValue("O(OO)", mod->rebuild, Py_TYPE(self), values); } else { values = PyTuple_New(nfields); if (values == NULL) return NULL; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val = Struct_get_index(self, i); if (val == NULL) goto cleanup; Py_INCREF(val); PyTuple_SET_ITEM(values, i, val); } out = PyTuple_Pack(2, Py_TYPE(self), values); } cleanup: Py_DECREF(values); return out; } static PyObject * Struct_rich_repr(PyObject *self, PyObject *args) { StructMetaObject *st_type = (StructMetaObject *)(Py_TYPE(self)); bool omit_defaults = st_type->repr_omit_defaults == OPT_TRUE; PyObject *fields = st_type->struct_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); PyObject *defaults = NULL; Py_ssize_t nunchecked = nfields; if (omit_defaults) { defaults = st_type->struct_defaults; nunchecked = nfields - PyTuple_GET_SIZE(defaults); } PyObject *out = PyList_New(0); if (out == NULL) return NULL; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(self, i); if (i >= nunchecked) { PyObject *default_val = PyTuple_GET_ITEM(defaults, i - nunchecked); if (is_default(val, default_val)) continue; } if (val == NULL) goto error; PyObject *part = PyTuple_Pack(2, field, val); if (part == NULL) goto error; int status = PyList_Append(out, part); Py_DECREF(part); if (status < 0) goto error; } return out; error: Py_DECREF(out); return NULL; } static PyObject * StructMixin_fields(PyObject *self, void *closure) { PyObject *out = ((StructMetaObject *)Py_TYPE(self))->struct_fields; Py_INCREF(out); return out; } static PyObject * StructMixin_encode_fields(PyObject *self, void *closure) { PyObject *out = ((StructMetaObject *)Py_TYPE(self))->struct_encode_fields; Py_INCREF(out); return out; } static PyObject * StructMixin_defaults(PyObject *self, void *closure) { PyObject *out = ((StructMetaObject *)Py_TYPE(self))->struct_defaults; Py_INCREF(out); return out; } static PyObject* StructMixin_config(StructMetaObject *self, void *closure) { return StructConfig_New((StructMetaObject *)Py_TYPE(self)); } static PyMethodDef Struct_methods[] = { {"__copy__", Struct_copy, METH_NOARGS, "copy a struct"}, {"__replace__", (PyCFunction) Struct_replace, METH_FASTCALL | METH_KEYWORDS, "create a new struct with replacements" }, {"__reduce__", Struct_reduce, METH_NOARGS, "reduce a struct"}, {"__rich_repr__", Struct_rich_repr, METH_NOARGS, "rich repr"}, {NULL, NULL}, }; static PyGetSetDef StructMixin_getset[] = { {"__struct_fields__", (getter) StructMixin_fields, NULL, "Struct fields", NULL}, {"__struct_encode_fields__", (getter) StructMixin_encode_fields, NULL, "Struct encoded field names", NULL}, {"__struct_defaults__", (getter) StructMixin_defaults, NULL, "Struct defaults", NULL}, {"__struct_config__", (getter) StructMixin_config, NULL, "Struct configuration", NULL}, {NULL}, }; static PyTypeObject StructMixinType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core._StructMixin", .tp_basicsize = 0, .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_setattro = Struct_setattro_default, .tp_repr = Struct_repr, .tp_richcompare = Struct_richcompare, .tp_hash = Struct_hash, .tp_methods = Struct_methods, .tp_getset = StructMixin_getset, }; PyDoc_STRVAR(Struct__doc__, "A base class for defining efficient serializable objects.\n" "\n" "Fields are defined using type annotations. Fields may optionally have\n" "default values, which result in keyword parameters to the constructor.\n" "\n" "Structs automatically define ``__init__``, ``__eq__``, ``__repr__``, and\n" "``__copy__`` methods. Additional methods can be defined on the class as\n" "needed. Note that ``__init__``/``__new__`` cannot be overridden, but other\n" "methods can. A tuple of the field names is available on the class via the\n" "``__struct_fields__`` attribute if needed.\n" "\n" "Additional class options can be enabled by passing keywords to the class\n" "definition (see example below). These configuration options may also be\n" "inspected at runtime through the ``__struct_config__`` attribute.\n" "\n" "Configuration\n" "-------------\n" "frozen: bool, default False\n" " Whether instances of this type are pseudo-immutable. If true, attribute\n" " assignment is disabled and a corresponding ``__hash__`` is defined.\n" "order: bool, default False\n" " If True, ``__lt__``, `__le__``, ``__gt__``, and ``__ge__`` methods\n" " will be generated for this type.\n" "eq: bool, default True\n" " If True (the default), an ``__eq__`` method will be generated for this\n" " type. Set to False to compare based on instance identity alone.\n" "kw_only: bool, default False\n" " If True, all fields will be treated as keyword-only arguments in the\n" " generated ``__init__`` method. Default is False.\n" "omit_defaults: bool, default False\n" " Whether fields should be omitted from encoding if the corresponding value\n" " is the default for that field. Enabling this may reduce message size, and\n" " often also improve encoding & decoding performance.\n" "forbid_unknown_fields: bool, default False\n" " If True, an error is raised if an unknown field is encountered while\n" " decoding structs of this type. If False (the default), no error is raised\n" " and the unknown field is skipped.\n" "tag: str, int, bool, callable, or None, default None\n" " Used along with ``tag_field`` for configuring tagged union support. If\n" " either are non-None, then the struct is considered \"tagged\". In this case,\n" " an extra field (the ``tag_field``) and value (the ``tag``) are added to the\n" " encoded message, which can be used to differentiate message types during\n" " decoding.\n" "\n" " Set ``tag=True`` to enable the default tagged configuration (``tag_field``\n" " is ``\"type\"``, ``tag`` is the class name). Alternatively, you can provide\n" " a string (or less commonly int) value directly to be used as the tag\n" " (e.g. ``tag=\"my-tag-value\"``).``tag`` can also be passed a callable that\n" " takes the class qualname and returns a valid tag value (e.g.\n" " ``tag=str.lower``). See the docs for more information.\n" "tag_field: str or None, default None\n" " The field name to use for tagged union support. If ``tag`` is non-None,\n" " then this defaults to ``\"type\"``. See the ``tag`` docs above for more\n" " information.\n" "rename: str, mapping, callable, or None, default None\n" " Controls renaming the field names used when encoding/decoding the struct.\n" " May be one of ``\"lower\"``, ``\"upper\"``, ``\"camel\"``, ``\"pascal\"``, or\n" " ``\"kebab\"`` to rename in lowercase, UPPERCASE, camelCase, PascalCase,\n" " or kebab-case respectively. May also be a mapping from field names to the\n" " renamed names (missing fields are not renamed). Alternatively, may be a\n" " callable that takes the field name and returns a new name or ``None`` to\n" " not rename that field. Default is ``None`` for no field renaming.\n" "repr_omit_defaults: bool, default False\n" " Whether fields should be omitted from the generated repr if the\n" " corresponding value is the default for that field.\n" "array_like: bool, default False\n" " If True, this struct type will be treated as an array-like type during\n" " encoding/decoding, rather than a dict-like type (the default). This may\n" " improve performance, at the cost of a more inscrutable message encoding.\n" "gc: bool, default True\n" " Whether garbage collection is enabled for this type. Disabling this *may*\n" " help reduce GC pressure, but will prevent reference cycles composed of only\n" " ``gc=False`` from being collected. It is the user's responsibility to ensure\n" " that reference cycles don't occur when setting ``gc=False``.\n" "weakref: bool, default False\n" " Whether instances of this type support weak references. Defaults to False.\n" "dict: bool, default False\n" " Whether instances of this type will include a ``__dict__``. Setting this to\n" " True will allow adding additional undeclared attributes to a struct instance,\n" " which may be useful for holding private runtime state. Defaults to False.\n" "cache_hash: bool, default False\n" " If enabled, the hash of a frozen struct instance will be computed at most\n" " once, and then cached on the instance for further reuse. For expensive\n" " hash values this can improve performance at the cost of a small amount of\n" " memory usage.\n" "\n" "Examples\n" "--------\n" "Here we define a new `Struct` type for describing a dog. It has three fields;\n" "two required and one optional.\n" "\n" ">>> class Dog(Struct):\n" "... name: str\n" "... breed: str\n" "... is_good_boy: bool = True\n" "...\n" ">>> Dog('snickers', breed='corgi')\n" "Dog(name='snickers', breed='corgi', is_good_boy=True)\n" "\n" "Additional struct options can be set as part of the class definition. Here\n" "we define a new `Struct` type for a frozen `Point` object.\n" "\n" ">>> class Point(Struct, frozen=True):\n" "... x: float\n" "... y: float\n" "...\n" ">>> {Point(1.5, 2.0): 1} # frozen structs are hashable\n" "{Point(x=1.5, y=2.0): 1}" ); static int LiteralInfo_traverse(LiteralInfo *self, visitproc visit, void *arg) { Py_VISIT(self->str_lookup); Py_VISIT(self->int_lookup); return 0; } static int LiteralInfo_clear(LiteralInfo *self) { Py_CLEAR(self->str_lookup); Py_CLEAR(self->int_lookup); return 0; } static void LiteralInfo_dealloc(LiteralInfo *self) { PyObject_GC_UnTrack(self); LiteralInfo_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyTypeObject LiteralInfo_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.LiteralInfo", .tp_basicsize = sizeof(LiteralInfo), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)LiteralInfo_clear, .tp_traverse = (traverseproc)LiteralInfo_traverse, .tp_dealloc = (destructor)LiteralInfo_dealloc, }; static PyObject * TypedDictInfo_Convert(PyObject *obj) { PyObject *annotations = NULL, *required = NULL; TypedDictInfo *info = NULL; MsgspecState *mod = msgspec_get_global_state(); bool cache_set = false, succeeded = false; PyObject *cached = NULL; if (get_msgspec_cache(mod, obj, &TypedDictInfo_Type, &cached)) { return cached; } /* Not cached, extract fields from TypedDict object */ PyObject *temp = PyObject_CallOneArg(mod->get_typeddict_info, obj); if (temp == NULL) return NULL; annotations = PyTuple_GET_ITEM(temp, 0); Py_INCREF(annotations); required = PyTuple_GET_ITEM(temp, 1); Py_INCREF(required); Py_DECREF(temp); /* Allocate and zero-out a new TypedDictInfo object */ Py_ssize_t nfields = PyDict_GET_SIZE(annotations); info = PyObject_GC_NewVar(TypedDictInfo, &TypedDictInfo_Type, nfields); if (info == NULL) goto cleanup; for (Py_ssize_t i = 0; i < nfields; i++) { info->fields[i].key = NULL; info->fields[i].type = NULL; } /* Initialize nrequired to -1 as a flag in case of a recursive TypedDict * definition. */ info->nrequired = -1; /* If not already cached, then cache on TypedDict object _before_ * traversing fields. This is to ensure self-referential TypedDicts work. */ if (PyObject_SetAttr(obj, mod->str___msgspec_cache__, (PyObject *)info) < 0) { goto cleanup; } cache_set = true; /* Traverse fields and initialize TypedDictInfo */ Py_ssize_t pos = 0, i = 0; PyObject *key, *val; while (PyDict_Next(annotations, &pos, &key, &val)) { TypeNode *type = TypeNode_Convert(val); if (type == NULL) goto cleanup; Py_INCREF(key); info->fields[i].key = key; info->fields[i].type = type; int contains = PySet_Contains(required, key); if (contains == -1) goto cleanup; if (contains) { type->types |= MS_EXTRA_FLAG; } i++; } info->nrequired = PySet_GET_SIZE(required); PyObject_GC_Track(info); succeeded = true; cleanup: if (!succeeded) { Py_CLEAR(info); if (cache_set) { /* An error occurred after the cache was created and set on the * TypedDict. We need to delete the attribute. Fetch and restore the * original exception to avoid DelAttr silently clearing it on rare * occasions. */ PyObject *err_type, *err_value, *err_tb; PyErr_Fetch(&err_type, &err_value, &err_tb); PyObject_DelAttr(obj, mod->str___msgspec_cache__); PyErr_Restore(err_type, err_value, err_tb); } } Py_XDECREF(annotations); Py_XDECREF(required); return (PyObject *)info; } static MS_INLINE PyObject * TypedDictInfo_lookup_key( TypedDictInfo *self, const char * key, Py_ssize_t key_size, TypeNode **type, Py_ssize_t *pos ) { const char *field; Py_ssize_t nfields, field_size, i, offset = *pos; nfields = Py_SIZE(self); for (i = offset; i < nfields; i++) { field = unicode_str_and_size_nocheck(self->fields[i].key, &field_size); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i < (nfields - 1) ? (i + 1) : 0; *type = self->fields[i].type; return self->fields[i].key; } } for (i = 0; i < offset; i++) { field = unicode_str_and_size_nocheck(self->fields[i].key, &field_size); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i + 1; *type = self->fields[i].type; return self->fields[i].key; } } return NULL; } static void TypedDictInfo_error_missing(TypedDictInfo *self, PyObject *dict, PathNode *path) { Py_ssize_t nfields = Py_SIZE(self); for (Py_ssize_t i = 0; i < nfields; i++) { if (self->fields[i].type->types & MS_EXTRA_FLAG) { PyObject *field = self->fields[i].key; int contains = PyDict_Contains(dict, field); if (contains < 0) return; if (contains == 0) { ms_missing_required_field(field, path); return; } } } } static int TypedDictInfo_traverse(TypedDictInfo *self, visitproc visit, void *arg) { for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { TypedDictField *field = &(self->fields[i]); if (field->key != NULL) { int out = TypeNode_traverse(field->type, visit, arg); if (out != 0) return out; } } return 0; } static int TypedDictInfo_clear(TypedDictInfo *self) { for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { Py_CLEAR(self->fields[i].key); TypeNode_Free(self->fields[i].type); self->fields[i].type = NULL; } return 0; } static void TypedDictInfo_dealloc(TypedDictInfo *self) { PyObject_GC_UnTrack(self); TypedDictInfo_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyTypeObject TypedDictInfo_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.TypedDictInfo", .tp_basicsize = sizeof(TypedDictInfo), .tp_itemsize = sizeof(TypedDictField), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)TypedDictInfo_clear, .tp_traverse = (traverseproc)TypedDictInfo_traverse, .tp_dealloc = (destructor)TypedDictInfo_dealloc, }; static PyObject * DataclassInfo_Convert(PyObject *obj) { PyObject *cls = NULL, *fields = NULL, *field_defaults = NULL; PyObject *pre_init = NULL, *post_init = NULL; DataclassInfo *info = NULL; MsgspecState *mod = msgspec_get_global_state(); bool cache_set = false, succeeded = false; PyObject *cached = NULL; if (get_msgspec_cache(mod, obj, &DataclassInfo_Type, &cached)) { return cached; } /* Not cached, extract fields from Dataclass object */ PyObject *temp = PyObject_CallOneArg(mod->get_dataclass_info, obj); if (temp == NULL) return NULL; cls = PyTuple_GET_ITEM(temp, 0); Py_INCREF(cls); fields = PyTuple_GET_ITEM(temp, 1); Py_INCREF(fields); field_defaults = PyTuple_GET_ITEM(temp, 2); Py_INCREF(field_defaults); pre_init = PyTuple_GET_ITEM(temp, 3); Py_INCREF(pre_init); post_init = PyTuple_GET_ITEM(temp, 4); Py_INCREF(post_init); Py_DECREF(temp); /* Allocate and zero-out a new DataclassInfo object */ Py_ssize_t nfields = PyTuple_GET_SIZE(fields); info = PyObject_GC_NewVar(DataclassInfo, &DataclassInfo_Type, nfields); if (info == NULL) goto cleanup; for (Py_ssize_t i = 0; i < nfields; i++) { info->fields[i].key = NULL; info->fields[i].type = NULL; } Py_INCREF(field_defaults); info->defaults = field_defaults; Py_INCREF(cls); info->class = cls; if (pre_init == Py_None) { info->pre_init = NULL; } else { Py_INCREF(pre_init); info->pre_init = pre_init; } if (post_init == Py_None) { info->post_init = NULL; } else { Py_INCREF(post_init); info->post_init = post_init; } /* If not already cached, then cache on Dataclass object _before_ * traversing fields. This is to ensure self-referential Dataclasses work. */ if (PyObject_SetAttr(obj, mod->str___msgspec_cache__, (PyObject *)info) < 0) { goto cleanup; } cache_set = true; /* Traverse fields and initialize DataclassInfo */ for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(fields, i); TypeNode *type = TypeNode_Convert(PyTuple_GET_ITEM(field, 1)); if (type == NULL) goto cleanup; /* If field has a default factory, set extra flag bit */ if (PyObject_IsTrue(PyTuple_GET_ITEM(field, 2))) { type->types |= MS_EXTRA_FLAG; } info->fields[i].type = type; info->fields[i].key = PyTuple_GET_ITEM(field, 0); Py_INCREF(info->fields[i].key); } PyObject_GC_Track(info); succeeded = true; cleanup: if (!succeeded) { Py_CLEAR(info); if (cache_set) { /* An error occurred after the cache was created and set on the * Dataclass. We need to delete the attribute. Fetch and restore the * original exception to avoid DelAttr silently clearing it on rare * occasions. */ PyObject *err_type, *err_value, *err_tb; PyErr_Fetch(&err_type, &err_value, &err_tb); PyObject_DelAttr(obj, mod->str___msgspec_cache__); PyErr_Restore(err_type, err_value, err_tb); } } Py_XDECREF(cls); Py_XDECREF(fields); Py_XDECREF(field_defaults); Py_XDECREF(pre_init); Py_XDECREF(post_init); return (PyObject *)info; } static MS_INLINE PyObject * DataclassInfo_lookup_key( DataclassInfo *self, const char * key, Py_ssize_t key_size, TypeNode **type, Py_ssize_t *pos ) { const char *field; Py_ssize_t nfields, field_size, i, offset = *pos; nfields = Py_SIZE(self); for (i = offset; i < nfields; i++) { field = unicode_str_and_size_nocheck(self->fields[i].key, &field_size); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i < (nfields - 1) ? (i + 1) : 0; *type = self->fields[i].type; return self->fields[i].key; } } for (i = 0; i < offset; i++) { field = unicode_str_and_size_nocheck(self->fields[i].key, &field_size); if (key_size == field_size && memcmp(key, field, key_size) == 0) { *pos = i + 1; *type = self->fields[i].type; return self->fields[i].key; } } return NULL; } static int DataclassInfo_post_decode(DataclassInfo *self, PyObject *obj, PathNode *path) { Py_ssize_t nfields = Py_SIZE(self); Py_ssize_t ndefaults = PyTuple_GET_SIZE(self->defaults); for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *name = self->fields[i].key; if (!PyObject_HasAttr(obj, name)) { if (i < (nfields - ndefaults)) { ms_missing_required_field(name, path); return -1; } else { PyObject *default_value = PyTuple_GET_ITEM( self->defaults, i - (nfields - ndefaults) ); bool is_factory = self->fields[i].type->types & MS_EXTRA_FLAG; if (is_factory) { default_value = PyObject_CallNoArgs(default_value); if (default_value == NULL) return -1; } int status = PyObject_GenericSetAttr(obj, name, default_value); if (is_factory) { Py_DECREF(default_value); } if (status < 0) return -1; } } } if (self->post_init != NULL) { PyObject *res = PyObject_CallOneArg(self->post_init, obj); if (res == NULL) { ms_maybe_wrap_validation_error(path); return -1; } Py_DECREF(res); } return 0; } static int DataclassInfo_traverse(DataclassInfo *self, visitproc visit, void *arg) { for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { DataclassField *field = &(self->fields[i]); if (field->key != NULL) { int out = TypeNode_traverse(field->type, visit, arg); if (out != 0) return out; } } Py_VISIT(self->defaults); Py_VISIT(self->class); Py_VISIT(self->pre_init); Py_VISIT(self->post_init); return 0; } static int DataclassInfo_clear(DataclassInfo *self) { for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { Py_CLEAR(self->fields[i].key); TypeNode_Free(self->fields[i].type); self->fields[i].type = NULL; } Py_CLEAR(self->defaults); Py_CLEAR(self->class); Py_CLEAR(self->pre_init); Py_CLEAR(self->post_init); return 0; } static void DataclassInfo_dealloc(DataclassInfo *self) { PyObject_GC_UnTrack(self); DataclassInfo_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyTypeObject DataclassInfo_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.DataclassInfo", .tp_basicsize = sizeof(DataclassInfo), .tp_itemsize = sizeof(DataclassField), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)DataclassInfo_clear, .tp_traverse = (traverseproc)DataclassInfo_traverse, .tp_dealloc = (destructor)DataclassInfo_dealloc, }; static PyObject * NamedTupleInfo_Convert(PyObject *obj) { MsgspecState *mod = msgspec_get_global_state(); NamedTupleInfo *info = NULL; PyObject *annotations = NULL, *cls = NULL, *fields = NULL; PyObject *defaults = NULL, *defaults_list = NULL; bool cache_set = false, succeeded = false; PyObject *cached = NULL; if (get_msgspec_cache(mod, obj, &NamedTupleInfo_Type, &cached)) { return cached; } /* Not cached, extract fields from NamedTuple object */ annotations = PyObject_CallOneArg(mod->get_class_annotations, obj); if (annotations == NULL) goto cleanup; if (PyType_Check(obj)) { Py_INCREF(obj); cls = obj; } else { cls = PyObject_GetAttr(obj, mod->str___origin__); if (cls == NULL) goto cleanup; } fields = PyObject_GetAttr(cls, mod->str__fields); if (fields == NULL) goto cleanup; defaults = PyObject_GetAttr(cls, mod->str__field_defaults); if (defaults == NULL) goto cleanup; /* Allocate and zero-out a new NamedTupleInfo object */ Py_ssize_t nfields = PyTuple_GET_SIZE(fields); info = PyObject_GC_NewVar(NamedTupleInfo, &NamedTupleInfo_Type, nfields); if (info == NULL) goto cleanup; info->class = NULL; info->defaults = NULL; for (Py_ssize_t i = 0; i < nfields; i++) { info->types[i] = NULL; } /* If not already cached, then cache on NamedTuple object _before_ * traversing fields. This is to ensure self-referential NamedTuple work. */ if (PyObject_SetAttr(obj, mod->str___msgspec_cache__, (PyObject *)info) < 0) { goto cleanup; } cache_set = true; /* Traverse fields and initialize NamedTupleInfo */ defaults_list = PyList_New(0); if (defaults_list == NULL) goto cleanup; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = PyTuple_GET_ITEM(fields, i); /* Get the field type, defaulting to Any */ PyObject *type_obj = PyDict_GetItem(annotations, field); if (type_obj == NULL) { type_obj = mod->typing_any; } /* Convert the type to a TypeNode */ TypeNode *type = TypeNode_Convert(type_obj); if (type == NULL) goto cleanup; info->types[i] = type; /* Get the field default (if any), and append it to the list */ PyObject *default_obj = PyDict_GetItem(defaults, field); if (default_obj != NULL) { if (PyList_Append(defaults_list, default_obj) < 0) goto cleanup; } } Py_INCREF(cls); info->class = cls; info->defaults = PyList_AsTuple(defaults_list); if (info->defaults == NULL) goto cleanup; PyObject_GC_Track(info); succeeded = true; cleanup: if (!succeeded) { Py_CLEAR(info); if (cache_set) { /* An error occurred after the cache was created and set on the * NamedTuple. We need to delete the attribute. Fetch and restore * the original exception to avoid DelAttr silently clearing it * on rare occasions. */ PyObject *err_type, *err_value, *err_tb; PyErr_Fetch(&err_type, &err_value, &err_tb); PyObject_DelAttr(obj, mod->str___msgspec_cache__); PyErr_Restore(err_type, err_value, err_tb); } } Py_XDECREF(cls); Py_XDECREF(annotations); Py_XDECREF(fields); Py_XDECREF(defaults); Py_XDECREF(defaults_list); return (PyObject *)info; } static int NamedTupleInfo_traverse(NamedTupleInfo *self, visitproc visit, void *arg) { Py_VISIT(self->class); Py_VISIT(self->defaults); for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { int out = TypeNode_traverse(self->types[i], visit, arg); if (out != 0) return out; } return 0; } static int NamedTupleInfo_clear(NamedTupleInfo *self) { Py_CLEAR(self->class); Py_CLEAR(self->defaults); for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { TypeNode_Free(self->types[i]); self->types[i] = NULL; } return 0; } static void NamedTupleInfo_dealloc(NamedTupleInfo *self) { PyObject_GC_UnTrack(self); NamedTupleInfo_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } static PyTypeObject NamedTupleInfo_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec._core.NamedTupleInfo", .tp_basicsize = sizeof(NamedTupleInfo), .tp_itemsize = sizeof(TypeNode *), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_clear = (inquiry)NamedTupleInfo_clear, .tp_traverse = (traverseproc)NamedTupleInfo_traverse, .tp_dealloc = (destructor)NamedTupleInfo_dealloc, }; /************************************************************************* * Ext * *************************************************************************/ typedef struct Ext { PyObject_HEAD long code; PyObject *data; } Ext; static PyObject * Ext_New(long code, PyObject *data) { Ext *out = (Ext *)Ext_Type.tp_alloc(&Ext_Type, 0); if (out == NULL) return NULL; out->code = code; Py_INCREF(data); out->data = data; return (PyObject *)out; } PyDoc_STRVAR(Ext__doc__, "Ext(code, data)\n" "--\n" "\n" "A record representing a MessagePack Extension Type.\n" "\n" "Parameters\n" "----------\n" "code : int\n" " The integer type code for this extension. Must be between -128 and 127.\n" "data : bytes, bytearray, or memoryview\n" " The byte buffer for this extension. One of bytes, bytearray, memoryview,\n" " or any object that implements the buffer protocol." ); static PyObject * Ext_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *pycode, *data; long code; Py_ssize_t nargs, nkwargs; nargs = PyTuple_GET_SIZE(args); nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs); if (nkwargs != 0) { PyErr_SetString( PyExc_TypeError, "Ext takes no keyword arguments" ); return NULL; } else if (nargs != 2) { PyErr_Format( PyExc_TypeError, "Ext expected 2 arguments, got %zd", nargs ); return NULL; } pycode = PyTuple_GET_ITEM(args, 0); data = PyTuple_GET_ITEM(args, 1); if (PyLong_CheckExact(pycode)) { code = PyLong_AsLong(pycode); if ((code == -1 && PyErr_Occurred()) || code > 127 || code < -128) { PyErr_SetString( PyExc_ValueError, "code must be an int between -128 and 127" ); return NULL; } } else { PyErr_Format( PyExc_TypeError, "code must be an int, got %.200s", Py_TYPE(pycode)->tp_name ); return NULL; } if (!(PyBytes_CheckExact(data) || PyByteArray_CheckExact(data) || PyObject_CheckBuffer(data))) { PyErr_Format( PyExc_TypeError, "data must be a bytes, bytearray, or buffer-like object, got %.200s", Py_TYPE(data)->tp_name ); return NULL; } return Ext_New(code, data); } static void Ext_dealloc(Ext *self) { Py_XDECREF(self->data); Py_TYPE(self)->tp_free((PyObject *)self); } static PyMemberDef Ext_members[] = { {"code", T_INT, offsetof(Ext, code), READONLY, "The extension type code"}, {"data", T_OBJECT_EX, offsetof(Ext, data), READONLY, "The extension data payload"}, {NULL}, }; static PyObject * Ext_reduce(PyObject *self, PyObject *unused) { return Py_BuildValue("O(bO)", Py_TYPE(self), ((Ext*)self)->code, ((Ext*)self)->data); } static PyObject * Ext_richcompare(PyObject *self, PyObject *other, int op) { int status; PyObject *out; Ext *ex_self, *ex_other; if (Py_TYPE(other) != &Ext_Type) { Py_RETURN_NOTIMPLEMENTED; } if (op != Py_EQ && op != Py_NE) { Py_RETURN_NOTIMPLEMENTED; } ex_self = (Ext *)self; ex_other = (Ext *)other; status = ex_self->code == ex_other->code; if (!status) { out = (op == Py_EQ) ? Py_False : Py_True; } else { status = PyObject_RichCompareBool(ex_self->data, ex_other->data, op); if (status == -1) return NULL; out = status ? Py_True : Py_False; } Py_INCREF(out); return out; } static PyMethodDef Ext_methods[] = { {"__reduce__", Ext_reduce, METH_NOARGS, "reduce an Ext"}, {NULL, NULL}, }; static PyTypeObject Ext_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.msgpack.Ext", .tp_doc = Ext__doc__, .tp_basicsize = sizeof(Ext), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_new = Ext_new, .tp_dealloc = (destructor) Ext_dealloc, .tp_richcompare = Ext_richcompare, .tp_members = Ext_members, .tp_methods = Ext_methods }; /************************************************************************* * Dataclass Utilities * *************************************************************************/ typedef struct { PyObject *obj; PyObject *fields; PyObject *dict; Py_ssize_t fields_pos; Py_ssize_t dict_pos; bool fastpath; bool standard_getattr; } DataclassIter; static bool dataclass_iter_setup(DataclassIter *iter, PyObject *obj, PyObject *fields) { iter->dict = NULL; if (MS_UNLIKELY(!PyDict_CheckExact(fields))) { PyErr_Format(PyExc_RuntimeError, "%R.__dataclass_fields__ is not a dict", obj); return false; } iter->obj = obj; iter->fields = fields; iter->fields_pos = 0; iter->dict_pos = 0; iter->fastpath = false; iter->standard_getattr = ( Py_TYPE(obj)->tp_getattro == PyObject_GenericGetAttr ); if (iter->standard_getattr) { iter->dict = PyObject_GenericGetDict(obj, NULL); if (iter->dict == NULL) { PyErr_Clear(); } else if (PyDict_GET_SIZE(fields) == PyDict_GET_SIZE(iter->dict)) { iter->fastpath = true; } } return true; } static void dataclass_iter_cleanup(DataclassIter *iter) { Py_XDECREF(iter->dict); } static MS_INLINE bool dataclass_iter_next( DataclassIter *iter, PyObject **field_name, PyObject **field_val ) { PyObject *name, *key, *val; next_field: if (!PyDict_Next(iter->fields, &(iter->fields_pos), &name, NULL)) { return false; } if (MS_UNLIKELY(!PyUnicode_CheckExact(name))) goto next_field; if (MS_LIKELY(iter->fastpath)) { if ( PyDict_Next(iter->dict, &(iter->dict_pos), &key, &val) && (key == name) ) { Py_INCREF(val); goto found_val; } else { iter->fastpath = false; } } PyTypeObject *type = Py_TYPE(iter->obj); if (MS_LIKELY(iter->standard_getattr)) { if (iter->dict != NULL) { /* We know it's already hashed, it came from a dict */ Py_hash_t hash = ((PyASCIIObject *)name)->hash; val = _PyDict_GetItem_KnownHash(iter->dict, name, hash); if (val != NULL) { Py_INCREF(val); goto found_val; } } PyObject *descr = _PyType_Lookup(type, name); if (descr != NULL) { descrgetfunc get = Py_TYPE(descr)->tp_descr_get; descrsetfunc set = Py_TYPE(descr)->tp_descr_set; if (get != NULL && set != NULL) { Py_INCREF(descr); val = get(descr, iter->obj, (PyObject *)type); Py_DECREF(descr); if (val != NULL) goto found_val; PyErr_Clear(); } } goto next_field; } else { val = type->tp_getattro(iter->obj, name); if (val == NULL) { PyErr_Clear(); goto next_field; } goto found_val; } found_val: if (MS_UNLIKELY(val == UNSET)) { Py_DECREF(val); goto next_field; } *field_name = name; *field_val = val; return true; } static AssocList * AssocList_FromDataclass(PyObject *obj, PyObject *fields) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; bool ok = false; AssocList *out = NULL; DataclassIter iter; if (!dataclass_iter_setup(&iter, obj, fields)) goto cleanup; out = AssocList_New(PyDict_GET_SIZE(fields)); if (out == NULL) goto cleanup; PyObject *field, *val; while (dataclass_iter_next(&iter, &field, &val)) { int status = AssocList_Append(out, field, val); Py_DECREF(val); if (status < 0) goto cleanup; } ok = true; cleanup: Py_LeaveRecursiveCall(); dataclass_iter_cleanup(&iter); if (!ok) { AssocList_Free(out); return NULL; } return out; } /************************************************************************* * Object Utilities * *************************************************************************/ static AssocList * AssocList_FromObject(PyObject *obj) { bool ok = false; PyObject *dict = NULL; AssocList *out = NULL; if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; dict = PyObject_GenericGetDict(obj, NULL); if (MS_UNLIKELY(dict == NULL)) { PyErr_Clear(); } /* Determine max size of AssocList needed */ Py_ssize_t max_size = (dict == NULL) ? 0 : PyDict_GET_SIZE(dict); PyTypeObject *type = Py_TYPE(obj); while (type != NULL) { max_size += Py_SIZE(type); type = type->tp_base; } out = AssocList_New(max_size); if (out == NULL) goto cleanup; /* Append everything in `__dict__` */ if (dict != NULL) { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(dict, &pos, &key, &val)) { if (MS_LIKELY(PyUnicode_CheckExact(key))) { Py_ssize_t key_len; if (MS_UNLIKELY(val == UNSET)) continue; const char* key_buf = unicode_str_and_size(key, &key_len); if (MS_UNLIKELY(key_buf == NULL)) goto cleanup; if (MS_UNLIKELY(*key_buf == '_')) continue; if (MS_UNLIKELY(AssocList_Append(out, key, val) < 0)) goto cleanup; } } } /* Then append everything in slots */ type = Py_TYPE(obj); while (type != NULL) { Py_ssize_t n = Py_SIZE(type); if (n) { PyMemberDef *mp = MS_PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (Py_ssize_t i = 0; i < n; i++, mp++) { if (MS_LIKELY(mp->type == T_OBJECT_EX && !(mp->flags & READONLY))) { char *addr = (char *)obj + mp->offset; PyObject *val = *(PyObject **)addr; if (MS_UNLIKELY(val == UNSET)) continue; if (MS_UNLIKELY(val == NULL)) continue; if (MS_UNLIKELY(*mp->name == '_')) continue; AssocList_AppendCStr(out, mp->name, val); } } } type = type->tp_base; } ok = true; cleanup: Py_XDECREF(dict); Py_LeaveRecursiveCall(); if (!ok) { AssocList_Free(out); return NULL; } return out; } /************************************************************************* * Shared Encoder structs/methods * *************************************************************************/ #define ENC_INIT_BUFSIZE 32 #define ENC_LINES_INIT_BUFSIZE 1024 enum decimal_format { DECIMAL_FORMAT_STRING = 0, DECIMAL_FORMAT_NUMBER = 1, }; enum uuid_format { UUID_FORMAT_CANONICAL = 0, UUID_FORMAT_HEX = 1, UUID_FORMAT_BYTES = 2, }; typedef struct EncoderState { MsgspecState *mod; /* module reference */ PyObject *enc_hook; /* `enc_hook` callback */ enum decimal_format decimal_format; enum uuid_format uuid_format; enum order_mode order; char* (*resize_buffer)(PyObject**, Py_ssize_t); /* callback for resizing buffer */ char *output_buffer_raw; /* raw pointer to output_buffer internal buffer */ Py_ssize_t output_len; /* Length of output_buffer */ Py_ssize_t max_output_len; /* Allocation size of output_buffer */ PyObject *output_buffer; /* bytes or bytearray storing the output */ } EncoderState; typedef struct Encoder { PyObject_HEAD PyObject *enc_hook; MsgspecState *mod; enum decimal_format decimal_format; enum uuid_format uuid_format; enum order_mode order; } Encoder; static PyTypeObject Encoder_Type; static char* ms_resize_bytes(PyObject** output_buffer, Py_ssize_t size) { int status = _PyBytes_Resize(output_buffer, size); if (status < 0) return NULL; return PyBytes_AS_STRING(*output_buffer); } static char* ms_resize_bytearray(PyObject** output_buffer, Py_ssize_t size) { int status = PyByteArray_Resize(*output_buffer, size); if (status < 0) return NULL; return PyByteArray_AS_STRING(*output_buffer); } static MS_NOINLINE int ms_resize(EncoderState *self, Py_ssize_t size) { self->max_output_len = Py_MAX(8, 1.5 * size); char *new_buf = self->resize_buffer(&self->output_buffer, self->max_output_len); if (new_buf == NULL) return -1; self->output_buffer_raw = new_buf; return 0; } static MS_INLINE int ms_ensure_space(EncoderState *self, Py_ssize_t size) { Py_ssize_t required = self->output_len + size; if (MS_UNLIKELY(required > self->max_output_len)) { return ms_resize(self, required); } return 0; } static MS_INLINE int ms_write(EncoderState *self, const char *s, Py_ssize_t n) { Py_ssize_t required = self->output_len + n; if (MS_UNLIKELY(required > self->max_output_len)) { if (ms_resize(self, required) < 0) return -1; } memcpy(self->output_buffer_raw + self->output_len, s, n); self->output_len += n; return 0; } static int Encoder_init(Encoder *self, PyObject *args, PyObject *kwds) { char *kwlist[] = {"enc_hook", "decimal_format", "uuid_format", "order", NULL}; PyObject *enc_hook = NULL, *decimal_format = NULL, *uuid_format = NULL, *order = NULL; if ( !PyArg_ParseTupleAndKeywords( args, kwds, "|$OOOO", kwlist, &enc_hook, &decimal_format, &uuid_format, &order ) ) { return -1; } if (enc_hook == Py_None) { enc_hook = NULL; } if (enc_hook != NULL) { if (!PyCallable_Check(enc_hook)) { PyErr_SetString(PyExc_TypeError, "enc_hook must be callable"); return -1; } Py_INCREF(enc_hook); } /* Process decimal format */ if (decimal_format == NULL) { self->decimal_format = DECIMAL_FORMAT_STRING; } else { bool ok = false; if (PyUnicode_CheckExact(decimal_format)) { if (PyUnicode_CompareWithASCIIString(decimal_format, "string") == 0) { self->decimal_format = DECIMAL_FORMAT_STRING; ok = true; } else if (PyUnicode_CompareWithASCIIString(decimal_format, "number") == 0) { self->decimal_format = DECIMAL_FORMAT_NUMBER; ok = true; } } if (!ok) { PyErr_Format( PyExc_ValueError, "`decimal_format` must be 'string' or 'number', got %R", decimal_format ); return -1; } } /* Process uuid format */ if (uuid_format == NULL) { self->uuid_format = UUID_FORMAT_CANONICAL; } else { bool is_msgpack = Py_TYPE(self) == &Encoder_Type; bool ok = false; if (PyUnicode_CheckExact(uuid_format)) { if (PyUnicode_CompareWithASCIIString(uuid_format, "canonical") == 0) { self->uuid_format = UUID_FORMAT_CANONICAL; ok = true; } else if (PyUnicode_CompareWithASCIIString(uuid_format, "hex") == 0) { self->uuid_format = UUID_FORMAT_HEX; ok = true; } else if (is_msgpack && PyUnicode_CompareWithASCIIString(uuid_format, "bytes") == 0) { self->uuid_format = UUID_FORMAT_BYTES; ok = true; } } if (!ok) { const char *errmsg = ( is_msgpack ? "`uuid_format` must be 'canonical', 'hex', or 'bytes', got %R" : "`uuid_format` must be 'canonical' or 'hex', got %R" ); PyErr_Format(PyExc_ValueError, errmsg, uuid_format); return -1; } } /* Process order */ self->order = parse_order_arg(order); if (self->order == ORDER_INVALID) return -1; self->mod = msgspec_get_global_state(); self->enc_hook = enc_hook; return 0; } static int Encoder_traverse(Encoder *self, visitproc visit, void *arg) { Py_VISIT(self->enc_hook); return 0; } static int Encoder_clear(Encoder *self) { Py_CLEAR(self->enc_hook); return 0; } static void Encoder_dealloc(Encoder *self) { PyObject_GC_UnTrack(self); Encoder_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } PyDoc_STRVAR(Encoder_encode_into__doc__, "encode_into(self, obj, buffer, offset=0, /)\n" "--\n" "\n" "Serialize an object into an existing bytearray buffer.\n" "\n" "Upon success, the buffer will be truncated to the end of the serialized\n" "message. Note that the underlying memory buffer *won't* be truncated,\n" "allowing for efficiently appending additional bytes later.\n" "\n" "Parameters\n" "----------\n" "obj : Any\n" " The object to serialize.\n" "buffer : bytearray\n" " The buffer to serialize into.\n" "offset : int, optional\n" " The offset into the buffer to start writing at. Defaults to 0. Set to -1\n" " to start writing at the end of the buffer.\n" "\n" "Returns\n" "-------\n" "None" ); static PyObject* encoder_encode_into_common( Encoder *self, PyObject *const *args, Py_ssize_t nargs, int(*encode)(EncoderState*, PyObject*) ) { if (!check_positional_nargs(nargs, 2, 3)) return NULL; PyObject *obj = args[0]; PyObject *buf = args[1]; if (!PyByteArray_CheckExact(buf)) { PyErr_SetString(PyExc_TypeError, "buffer must be a `bytearray`"); return NULL; } Py_ssize_t buf_size = PyByteArray_GET_SIZE(buf); Py_ssize_t offset = 0; if (nargs == 3) { offset = PyLong_AsSsize_t(args[2]); if (offset == -1) { if (PyErr_Occurred()) return NULL; offset = buf_size; } if (offset < 0) { PyErr_SetString(PyExc_ValueError, "offset must be >= -1"); return NULL; } if (offset < buf_size) { buf_size = Py_MAX(8, 1.5 * offset); if (PyByteArray_Resize(buf, buf_size) < 0) return NULL; } } /* Setup buffer */ EncoderState state = { .mod = self->mod, .enc_hook = self->enc_hook, .decimal_format = self->decimal_format, .uuid_format = self->uuid_format, .order = self->order, .output_buffer = buf, .output_buffer_raw = PyByteArray_AS_STRING(buf), .output_len = offset, .max_output_len = buf_size, .resize_buffer = ms_resize_bytearray }; if (encode(&state, obj) < 0) { return NULL; } FAST_BYTEARRAY_SHRINK(buf, state.output_len); Py_RETURN_NONE; } PyDoc_STRVAR(Encoder_encode__doc__, "encode(self, obj)\n" "--\n" "\n" "Serialize an object to bytes.\n" "\n" "Parameters\n" "----------\n" "obj : Any\n" " The object to serialize.\n" "\n" "Returns\n" "-------\n" "data : bytes\n" " The serialized object.\n" ); static PyObject* encoder_encode_common( Encoder *self, PyObject *const *args, Py_ssize_t nargs, int(*encode)(EncoderState*, PyObject*) ) { if (!check_positional_nargs(nargs, 1, 1)) return NULL; EncoderState state = { .mod = self->mod, .enc_hook = self->enc_hook, .decimal_format = self->decimal_format, .uuid_format = self->uuid_format, .order = self->order, .output_len = 0, .max_output_len = ENC_INIT_BUFSIZE, .resize_buffer = &ms_resize_bytes }; state.output_buffer = PyBytes_FromStringAndSize(NULL, state.max_output_len); if (state.output_buffer == NULL) return NULL; state.output_buffer_raw = PyBytes_AS_STRING(state.output_buffer); if (encode(&state, args[0]) < 0) { Py_DECREF(state.output_buffer); return NULL; } FAST_BYTES_SHRINK(state.output_buffer, state.output_len); return state.output_buffer; } static PyObject* encode_common( PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames, int(*encode)(EncoderState*, PyObject*) ) { PyObject *enc_hook = NULL, *order = NULL; MsgspecState *mod = msgspec_get_state(module); /* Parse arguments */ if (!check_positional_nargs(nargs, 1, 1)) return NULL; if (kwnames != NULL) { Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames); if ((enc_hook = find_keyword(kwnames, args + nargs, mod->str_enc_hook)) != NULL) nkwargs--; if ((order = find_keyword(kwnames, args + nargs, mod->str_order)) != NULL) nkwargs--; if (nkwargs > 0) { PyErr_SetString( PyExc_TypeError, "Extra keyword arguments provided" ); return NULL; } } if (enc_hook == Py_None) { enc_hook = NULL; } if (enc_hook != NULL && !PyCallable_Check(enc_hook)) { PyErr_SetString(PyExc_TypeError, "enc_hook must be callable"); return NULL; } EncoderState state = { .mod = mod, .enc_hook = enc_hook, .decimal_format = DECIMAL_FORMAT_STRING, .uuid_format = UUID_FORMAT_CANONICAL, .output_len = 0, .max_output_len = ENC_INIT_BUFSIZE, .resize_buffer = &ms_resize_bytes }; state.order = parse_order_arg(order); if (state.order == ORDER_INVALID) return NULL; state.output_buffer = PyBytes_FromStringAndSize(NULL, state.max_output_len); if (state.output_buffer == NULL) return NULL; state.output_buffer_raw = PyBytes_AS_STRING(state.output_buffer); if (encode(&state, args[0]) < 0) { Py_DECREF(state.output_buffer); return NULL; } FAST_BYTES_SHRINK(state.output_buffer, state.output_len); return state.output_buffer; } static PyMemberDef Encoder_members[] = { {"enc_hook", T_OBJECT, offsetof(Encoder, enc_hook), READONLY, NULL}, {NULL}, }; static PyObject* Encoder_decimal_format(Encoder *self, void *closure) { if (self->decimal_format == DECIMAL_FORMAT_STRING) { return PyUnicode_InternFromString("string"); } return PyUnicode_InternFromString("number"); } static PyObject* Encoder_uuid_format(Encoder *self, void *closure) { if (self->uuid_format == UUID_FORMAT_CANONICAL) { return PyUnicode_InternFromString("canonical"); } else if (self->uuid_format == UUID_FORMAT_HEX) { return PyUnicode_InternFromString("hex"); } else { return PyUnicode_InternFromString("bytes"); } } static PyObject* Encoder_order(Encoder *self, void *closure) { if (self->order == ORDER_DEFAULT) { Py_RETURN_NONE; } else if (self->order == ORDER_DETERMINISTIC) { return PyUnicode_InternFromString("deterministic"); } else { return PyUnicode_InternFromString("sorted"); } } static PyGetSetDef Encoder_getset[] = { {"decimal_format", (getter) Encoder_decimal_format, NULL, NULL, NULL}, {"uuid_format", (getter) Encoder_uuid_format, NULL, NULL, NULL}, {"order", (getter) Encoder_order, NULL, NULL, NULL}, {NULL}, }; /************************************************************************* * Shared Decoding Utilities * *************************************************************************/ static PyObject * ms_maybe_decode_bool_from_uint64(uint64_t x) { if (x == 0) { Py_RETURN_FALSE; } else if (x == 1) { Py_RETURN_TRUE; } return NULL; } static PyObject * ms_maybe_decode_bool_from_int64(int64_t x) { if (x == 0) { Py_RETURN_FALSE; } else if (x == 1) { Py_RETURN_TRUE; } return NULL; } static PyObject * ms_decode_str_enum_or_literal(const char *name, Py_ssize_t size, TypeNode *type, PathNode *path) { StrLookup *lookup = TypeNode_get_str_enum_or_literal(type); return StrLookup_GetOrError(lookup, name, size, path); } static PyObject * ms_decode_int_enum_or_literal_int64(int64_t val, TypeNode *type, PathNode *path) { IntLookup *lookup = TypeNode_get_int_enum_or_literal(type); return IntLookup_GetInt64OrError(lookup, val, path); } static PyObject * ms_decode_int_enum_or_literal_uint64(uint64_t val, TypeNode *type, PathNode *path) { IntLookup *lookup = TypeNode_get_int_enum_or_literal(type); return IntLookup_GetUInt64OrError(lookup, val, path); } static PyObject * ms_decode_int_enum_or_literal_pyint(PyObject *val, TypeNode *type, PathNode *path) { IntLookup *lookup = TypeNode_get_int_enum_or_literal(type); return IntLookup_GetPyIntOrError(lookup, val, path); } static MS_NOINLINE PyObject * ms_decode_custom(PyObject *obj, PyObject *dec_hook, TypeNode* type, PathNode *path) { PyObject *custom_cls = NULL, *custom_obj, *out = NULL; int status; bool generic = type->types & MS_TYPE_CUSTOM_GENERIC; if (obj == NULL) return NULL; if (obj == Py_None && type->types & MS_TYPE_NONE) return obj; custom_obj = TypeNode_get_custom(type); if (dec_hook != NULL) { out = PyObject_CallFunctionObjArgs(dec_hook, custom_obj, obj, NULL); Py_DECREF(obj); if (out == NULL) { ms_maybe_wrap_validation_error(path); return NULL; } } else { out = obj; } /* Generic classes must be checked based on __origin__ */ if (generic) { MsgspecState *st = msgspec_get_global_state(); custom_cls = PyObject_GetAttr(custom_obj, st->str___origin__); if (custom_cls == NULL) { Py_DECREF(out); return NULL; } } else { custom_cls = custom_obj; } /* Check that the decoded value matches the expected type */ status = PyObject_IsInstance(out, custom_cls); if (status == 0) { ms_raise_validation_error( path, "Expected `%s`, got `%s`%U", ((PyTypeObject *)custom_cls)->tp_name, Py_TYPE(out)->tp_name ); Py_CLEAR(out); } else if (status == -1) { Py_CLEAR(out); } if (generic) { Py_DECREF(custom_cls); } return out; } static MS_NOINLINE PyObject * _err_int_constraint(const char *msg, int64_t c, PathNode *path) { ms_raise_validation_error(path, msg, c); return NULL; } static MS_NOINLINE PyObject * ms_decode_constr_int(int64_t x, TypeNode *type, PathNode *path) { if (type->types & MS_CONSTR_INT_MIN) { int64_t c = TypeNode_get_constr_int_min(type); bool ok = x >= c; if (MS_UNLIKELY(!ok)) { return _err_int_constraint("Expected `int` >= %lld%U", c, path); } } if (type->types & MS_CONSTR_INT_MAX) { int64_t c = TypeNode_get_constr_int_max(type); bool ok = x <= c; if (MS_UNLIKELY(!ok)) { return _err_int_constraint("Expected `int` <= %lld%U", c, path); } } if (MS_UNLIKELY(type->types & MS_CONSTR_INT_MULTIPLE_OF)) { int64_t c = TypeNode_get_constr_int_multiple_of(type); bool ok = (x % c) == 0; if (MS_UNLIKELY(!ok)) { return _err_int_constraint( "Expected `int` that's a multiple of %lld%U", c, path ); } } return PyLong_FromLongLong(x); } static MS_INLINE PyObject * ms_decode_int(int64_t x, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_INT_CONSTRS)) { return ms_decode_constr_int(x, type, path); } return PyLong_FromLongLong(x); } static MS_NOINLINE PyObject * ms_decode_constr_uint(uint64_t x, TypeNode *type, PathNode *path) { if (type->types & MS_CONSTR_INT_MAX) { int64_t c = TypeNode_get_constr_int_max(type); return _err_int_constraint("Expected `int` <= %lld%U", c, path); } if (MS_UNLIKELY(type->types & MS_CONSTR_INT_MULTIPLE_OF)) { int64_t c = TypeNode_get_constr_int_multiple_of(type); bool ok = (x % c) == 0; if (MS_UNLIKELY(!ok)) { return _err_int_constraint( "Expected `int` that's a multiple of %lld%U", c, path ); } } return PyLong_FromUnsignedLongLong(x); } static MS_INLINE PyObject * ms_decode_uint(uint64_t x, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_INT_CONSTRS)) { if (MS_LIKELY(x <= LLONG_MAX)) { return ms_decode_int(x, type, path); } return ms_decode_constr_uint(x, type, path); } return PyLong_FromUnsignedLongLong(x); } static MS_NOINLINE bool ms_passes_int_constraints(uint64_t ux, bool neg, TypeNode *type, PathNode *path) { if (type->types & MS_CONSTR_INT_MIN) { int64_t c = TypeNode_get_constr_int_min(type); bool ok = ( neg ? ((-(int64_t)ux) >= c) : ((c < 0) || (ux >= (uint64_t)c)) ); if (MS_UNLIKELY(!ok)) { _err_int_constraint("Expected `int` >= %lld%U", c, path); return false; } } if (type->types & MS_CONSTR_INT_MAX) { int64_t c = TypeNode_get_constr_int_max(type); bool ok = ( neg ? ((-(int64_t)ux) <= c) : ((c >= 0) && (ux <= (uint64_t)c)) ); if (MS_UNLIKELY(!ok)) { _err_int_constraint("Expected `int` <= %lld%U", c, path); return false; } } if (MS_UNLIKELY(type->types & MS_CONSTR_INT_MULTIPLE_OF)) { int64_t c = TypeNode_get_constr_int_multiple_of(type); bool ok = (ux % c) == 0; if (MS_UNLIKELY(!ok)) { _err_int_constraint( "Expected `int` that's a multiple of %lld%U", c, path ); return false; } } return true; } /* Constraint checks for a PyLong that is known not to fit into a uint64/int64 */ static bool ms_passes_big_int_constraints(PyObject *obj, TypeNode *type, PathNode *path) { bool neg = _PyLong_Sign(obj) < 0; if (type->types & MS_CONSTR_INT_MIN) { if (neg) { int64_t c = TypeNode_get_constr_int_min(type); _err_int_constraint("Expected `int` >= %lld%U", c, path); return false; } } if (type->types & MS_CONSTR_INT_MAX) { if (!neg) { int64_t c = TypeNode_get_constr_int_max(type); _err_int_constraint("Expected `int` <= %lld%U", c, path); return false; } } if (MS_UNLIKELY(type->types & MS_CONSTR_INT_MULTIPLE_OF)) { int64_t c = TypeNode_get_constr_int_multiple_of(type); PyObject *base = PyLong_FromLongLong(c); if (base == NULL) return false; PyObject *remainder = PyNumber_Remainder(obj, base); Py_DECREF(base); if (remainder == NULL) return false; long iremainder = PyLong_AsLong(remainder); if (iremainder != 0) { _err_int_constraint( "Expected `int` that's a multiple of %lld%U", c, path ); return false; } } return true; } static MS_NOINLINE PyObject * ms_decode_big_pyint(PyObject *obj, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_INT_CONSTRS)) { if (!ms_passes_big_int_constraints(obj, type, path)) return NULL; } if (MS_LIKELY(PyLong_CheckExact(obj))) { Py_INCREF(obj); return obj; } else { return PyNumber_Long(obj); } } static MS_INLINE PyObject * ms_decode_pyint(PyObject *obj, TypeNode *type, PathNode *path) { uint64_t ux; bool neg, overflow; overflow = fast_long_extract_parts(obj, &neg, &ux); if (MS_UNLIKELY(overflow)) { return ms_decode_big_pyint(obj, type, path); } if (MS_UNLIKELY(type->types & MS_INT_CONSTRS)) { if (!ms_passes_int_constraints(ux, neg, type, path)) return NULL; } if (MS_LIKELY(PyLong_CheckExact(obj))) { Py_INCREF(obj); return obj; } if (!neg) { return PyLong_FromUnsignedLongLong(ux); } return PyLong_FromLongLong(-(int64_t)ux); } static MS_NOINLINE PyObject * ms_decode_bigint(const char *buf, Py_ssize_t size, TypeNode *type, PathNode *path) { if (size > 4300) goto out_of_range; /* CPython int parsing routine requires NULL terminated buffer */ char *temp = (char *)PyMem_Malloc(size + 1); if (temp == NULL) return NULL; memcpy(temp, buf, size); temp[size] = '\0'; PyObject *out = PyLong_FromString(temp, NULL, 10); PyMem_Free(temp); /* We already know the int is a valid integer string. An error here is * either a ValueError due to the int being too big (to prevent DDOS * issues), or some issue in the VM. We convert the former to out-of-range * errors for uniformity, and raise the latter directly. */ if (MS_UNLIKELY(out == NULL)) { PyObject *exc_type, *exc, *tb; /* Fetch the exception state */ PyErr_Fetch(&exc_type, &exc, &tb); if (exc_type == NULL) { /* Some other c-extension has borked, just return */ return NULL; } else if (exc_type == PyExc_ValueError) { goto out_of_range; } else { /* Restore the exception state */ PyErr_Restore(exc_type, exc, tb); } } if (MS_UNLIKELY(type->types & MS_INT_CONSTRS)) { if (!ms_passes_big_int_constraints(out, type, path)) { Py_CLEAR(out); } } return out; out_of_range: return ms_error_with_path("Integer value out of range%U", path); } static MS_NOINLINE PyObject * _err_float_constraint( const char *msg, int offset, double c, PathNode *path ) { if (offset == 1) { c = nextafter(c, DBL_MAX); } else if (offset == -1) { c = nextafter(c, -DBL_MAX); } PyObject *py_c = PyFloat_FromDouble(c); if (py_c != NULL) { ms_raise_validation_error(path, "Expected `float` %s %R%U", msg, py_c); Py_DECREF(py_c); } return NULL; } static MS_INLINE bool ms_passes_float_constraints_inline(double x, TypeNode *type, PathNode *path) { if (type->types & (MS_CONSTR_FLOAT_GE | MS_CONSTR_FLOAT_GT)) { double c = TypeNode_get_constr_float_min(type); bool ok = x >= c; if (MS_UNLIKELY(!ok)) { bool eq = type->types & MS_CONSTR_FLOAT_GE; _err_float_constraint( eq ? ">=" : ">", eq ? 0 : -1, c, path ); return false; } } if (type->types & (MS_CONSTR_FLOAT_LE | MS_CONSTR_FLOAT_LT)) { double c = TypeNode_get_constr_float_max(type); bool ok = x <= c; if (MS_UNLIKELY(!ok)) { bool eq = type->types & MS_CONSTR_FLOAT_LE; _err_float_constraint( eq ? "<=" : "<", eq ? 0 : 1, c, path ); return false; } } if (MS_UNLIKELY(type->types & MS_CONSTR_FLOAT_MULTIPLE_OF)) { double c = TypeNode_get_constr_float_multiple_of(type); bool ok = x == 0 || fmod(x, c) == 0.0; if (MS_UNLIKELY(!ok)) { _err_float_constraint( "that's a multiple of", 0, c, path ); return false; } } return true; } static MS_NOINLINE PyObject * ms_decode_constr_float(double x, TypeNode *type, PathNode *path) { if (!ms_passes_float_constraints_inline(x, type, path)) return NULL; return PyFloat_FromDouble(x); } static MS_INLINE PyObject * ms_decode_float(double x, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_FLOAT_CONSTRS)) { return ms_decode_constr_float(x, type, path); } return PyFloat_FromDouble(x); } static MS_NOINLINE PyObject * _ms_check_float_constraints(PyObject *obj, TypeNode *type, PathNode *path) { double x = PyFloat_AS_DOUBLE(obj); if (ms_passes_float_constraints_inline(x, type, path)) return obj; Py_DECREF(obj); return NULL; } static MS_INLINE PyObject * ms_check_float_constraints(PyObject *obj, TypeNode *type, PathNode *path) { if (MS_LIKELY(!(type->types & MS_FLOAT_CONSTRS))) return obj; return _ms_check_float_constraints(obj, type, path); } static MS_NOINLINE bool _err_py_ssize_t_constraint(const char *msg, Py_ssize_t c, PathNode *path) { ms_raise_validation_error(path, msg, c); return false; } static MS_NOINLINE PyObject * _ms_check_str_constraints(PyObject *obj, TypeNode *type, PathNode *path) { if (obj == NULL) return NULL; Py_ssize_t len = PyUnicode_GET_LENGTH(obj); if (type->types & MS_CONSTR_STR_MIN_LENGTH) { Py_ssize_t c = TypeNode_get_constr_str_min_length(type); if (len < c) { _err_py_ssize_t_constraint( "Expected `str` of length >= %zd%U", c, path ); goto error; } } if (type->types & MS_CONSTR_STR_MAX_LENGTH) { Py_ssize_t c = TypeNode_get_constr_str_max_length(type); if (len > c) { _err_py_ssize_t_constraint( "Expected `str` of length <= %zd%U", c, path ); goto error; } } if (type->types & MS_CONSTR_STR_REGEX) { PyObject *regex = TypeNode_get_constr_str_regex(type); PyObject *res = PyObject_CallMethod(regex, "search", "O", obj); if (res == NULL) goto error; bool ok = (res != Py_None); Py_DECREF(res); if (!ok) { PyObject *pattern = PyObject_GetAttrString(regex, "pattern"); if (pattern == NULL) goto error; ms_raise_validation_error( path, "Expected `str` matching regex %R%U", pattern ); Py_DECREF(pattern); goto error; } } return obj; error: Py_DECREF(obj); return NULL; } static MS_INLINE PyObject * ms_check_str_constraints(PyObject *obj, TypeNode *type, PathNode *path) { if (MS_LIKELY(!(type->types & MS_STR_CONSTRS))) return obj; return _ms_check_str_constraints(obj, type, path); } static bool ms_passes_bytes_constraints(Py_ssize_t size, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_CONSTR_BYTES_MIN_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_bytes_min_length(type); if (size < c) { return _err_py_ssize_t_constraint( "Expected `bytes` of length >= %zd%U", c, path ); } } if (MS_UNLIKELY(type->types & MS_CONSTR_BYTES_MAX_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_bytes_max_length(type); if (size > c) { return _err_py_ssize_t_constraint( "Expected `bytes` of length <= %zd%U", c, path ); } } return true; } static MS_NOINLINE bool _ms_passes_array_constraints(Py_ssize_t size, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_CONSTR_ARRAY_MIN_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_array_min_length(type); if (size < c) { return _err_py_ssize_t_constraint( "Expected `array` of length >= %zd%U", c, path ); } } if (MS_UNLIKELY(type->types & MS_CONSTR_ARRAY_MAX_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_array_max_length(type); if (size > c) { return _err_py_ssize_t_constraint( "Expected `array` of length <= %zd%U", c, path ); } } return true; } static MS_INLINE bool ms_passes_array_constraints(Py_ssize_t size, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_ARRAY_CONSTRS)) { return _ms_passes_array_constraints(size, type, path); } return true; } static MS_NOINLINE bool _ms_passes_map_constraints(Py_ssize_t size, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_CONSTR_MAP_MIN_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_map_min_length(type); if (size < c) { return _err_py_ssize_t_constraint( "Expected `object` of length >= %zd%U", c, path ); } } if (MS_UNLIKELY(type->types & MS_CONSTR_MAP_MAX_LENGTH)) { Py_ssize_t c = TypeNode_get_constr_map_max_length(type); if (size > c) { return _err_py_ssize_t_constraint( "Expected `object` of length <= %zd%U", c, path ); } } return true; } static MS_INLINE bool ms_passes_map_constraints(Py_ssize_t size, TypeNode *type, PathNode *path) { if (MS_UNLIKELY(type->types & MS_MAP_CONSTRS)) { return _ms_passes_map_constraints(size, type, path); } return true; } static bool ms_passes_tz_constraint( PyObject *tz, TypeNode *type, PathNode *path ) { char *err, *type_str; if (tz == Py_None) { if (type->types & MS_CONSTR_TZ_AWARE) { err = "Expected `%s` with a timezone component%U"; goto error; } } else if (type->types & MS_CONSTR_TZ_NAIVE) { err = "Expected `%s` with no timezone component%U"; goto error; } return true; error: if (type->types & MS_TYPE_TIME) { type_str = "time"; } else { type_str = "datetime"; } ms_raise_validation_error(path, err, type_str); return false; } static int ms_encode_err_type_unsupported(PyTypeObject *type) { PyErr_Format( PyExc_TypeError, "Encoding objects of type %.200s is unsupported", type->tp_name ); return -1; } /************************************************************************* * Datetime utilities * *************************************************************************/ #define MS_HAS_TZINFO(o) (((_PyDateTime_BaseTZInfo *)(o))->hastzinfo) #if PY310_PLUS #define MS_DATE_GET_TZINFO(o) PyDateTime_DATE_GET_TZINFO(o) #define MS_TIME_GET_TZINFO(o) PyDateTime_TIME_GET_TZINFO(o) #else #define MS_DATE_GET_TZINFO(o) (MS_HAS_TZINFO(o) ? \ ((PyDateTime_DateTime *)(o))->tzinfo : Py_None) #define MS_TIME_GET_TZINFO(o) (MS_HAS_TZINFO(o) ? \ ((PyDateTime_Time *)(o))->tzinfo : Py_None) #endif #ifndef TIMEZONE_CACHE_SIZE #define TIMEZONE_CACHE_SIZE 512 #endif typedef struct { int32_t offset; PyObject *tz; } TimezoneCacheItem; static TimezoneCacheItem timezone_cache[TIMEZONE_CACHE_SIZE]; static void timezone_cache_clear(void) { /* Traverse the timezone cache, deleting any string with a reference count * of only 1 */ for (Py_ssize_t i = 0; i < TIMEZONE_CACHE_SIZE; i++) { PyObject *tz = timezone_cache[i].tz; if (tz != NULL && Py_REFCNT(tz) == 1) { timezone_cache[i].offset = 0; timezone_cache[i].tz = NULL; Py_DECREF(tz); } } } /* Returns a new reference */ static PyObject* timezone_from_offset(int32_t offset) { uint32_t index = ((uint32_t)offset) % TIMEZONE_CACHE_SIZE; if (timezone_cache[index].offset == offset) { PyObject *tz = timezone_cache[index].tz; Py_INCREF(tz); return tz; } PyObject *delta = PyDelta_FromDSU(0, offset * 60, 0); if (delta == NULL) return NULL; PyObject *tz = PyTimeZone_FromOffset(delta); Py_DECREF(delta); if (tz == NULL) return NULL; Py_XDECREF(timezone_cache[index].tz); timezone_cache[index].offset = offset; Py_INCREF(tz); timezone_cache[index].tz = tz; return tz; } static bool is_leap_year(int year) { unsigned int y = (unsigned int)year; return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0); } static int days_in_month(int year, int month) { static const uint8_t ndays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (month == 2 && is_leap_year(year)) return 29; else return ndays[month - 1]; } static MS_NOINLINE int datetime_round_up_micros( int *year, int *month, int *day, int *hour, int *minute, int *second, int *microsecond ) { ++*microsecond; if (*microsecond == 1000000) { *microsecond = 0; ++*second; if (*second == 60) { *second = 0; ++*minute; if (*minute == 60) { *minute = 0; ++*hour; if (*hour == 24) { *hour = 0; ++*day; if (*day == days_in_month(*year, *month) + 1) { ++*month; *day = 1; if (*month > 12) { *month = 1; ++*year; if (*year > 9999) return -1; } } } } } } return 0; } static MS_NOINLINE void time_round_up_micros( int *hour, int *minute, int *second, int *microsecond ) { ++*microsecond; if (*microsecond == 1000000) { *microsecond = 0; ++*second; if (*second == 60) { *second = 0; ++*minute; if (*minute == 60) { *minute = 0; ++*hour; if (*hour == 24) { *hour = 0; } } } } } /* Days since 0001-01-01, the min value for python's datetime objects */ static int days_since_min_datetime(int year, int month, int day) { int out = day; static const int _days_before_month[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; out += _days_before_month[month - 1]; if (month > 2 && is_leap_year(year)) out++; year--; /* makes math easier */ out += year*365 + year/4 - year/100 + year/400; return out; } static void datetime_to_epoch(PyObject *obj, int64_t *seconds, int32_t *nanoseconds) { int64_t d = days_since_min_datetime( PyDateTime_GET_YEAR(obj), PyDateTime_GET_MONTH(obj), PyDateTime_GET_DAY(obj) ) - 719163; /* days_since_min_datetime(1970, 1, 1) */ int64_t s = ( PyDateTime_DATE_GET_HOUR(obj) * 3600 + PyDateTime_DATE_GET_MINUTE(obj) * 60 + PyDateTime_DATE_GET_SECOND(obj) ); int64_t us = PyDateTime_DATE_GET_MICROSECOND(obj); *seconds = 86400 * d + s; *nanoseconds = us * 1000; } /* Python datetimes bounded between (inclusive) * [0001-01-01T00:00:00.000000, 9999-12-31T23:59:59.999999] UTC */ #define MS_EPOCH_SECS_MAX 253402300800 #define MS_EPOCH_SECS_MIN -62135596800 #define MS_DAYS_PER_400Y (365*400 + 97) #define MS_DAYS_PER_100Y (365*100 + 24) #define MS_DAYS_PER_4Y (365*4 + 1) /* Epoch -> datetime conversion borrowed and modified from the implementation * in musl, found at * http://git.musl-libc.org/cgit/musl/tree/src/time/__secs_to_tm.c. musl is * copyright Rich Felker et. al, and is licensed under the standard MIT * license. */ static PyObject * datetime_from_epoch( int64_t epoch_secs, uint32_t epoch_nanos, TypeNode *type, PathNode *path ) { /* Error on out-of-bounds datetimes. This leaves ample space in an int, so * no need to check for overflow later. */ if (epoch_secs < MS_EPOCH_SECS_MIN || epoch_secs > MS_EPOCH_SECS_MAX) { return ms_error_with_path("Timestamp is out of range %U", path); } int64_t years, days, secs; int micros, months, remdays, remsecs, remyears; int qc_cycles, c_cycles, q_cycles; /* Round nanos to nearest microsecond, adjusting seconds as needed */ micros = DIV_ROUND_CLOSEST(epoch_nanos, 1000); if (micros == 1000000) { micros = 0; epoch_secs++; } /* Start in Mar not Jan, so leap day is on end */ static const char days_in_month[] = {31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29}; /* Offset to 2000-03-01, a mod 400 year, immediately after feb 29 */ secs = epoch_secs - (946684800LL + 86400 * (31 + 29)); days = secs / 86400; remsecs = secs % 86400; if (remsecs < 0) { remsecs += 86400; days--; } qc_cycles = days / MS_DAYS_PER_400Y; remdays = days % MS_DAYS_PER_400Y; if (remdays < 0) { remdays += MS_DAYS_PER_400Y; qc_cycles--; } c_cycles = remdays / MS_DAYS_PER_100Y; if (c_cycles == 4) c_cycles--; remdays -= c_cycles * MS_DAYS_PER_100Y; q_cycles = remdays / MS_DAYS_PER_4Y; if (q_cycles == 25) q_cycles--; remdays -= q_cycles * MS_DAYS_PER_4Y; remyears = remdays / 365; if (remyears == 4) remyears--; remdays -= remyears * 365; years = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles; for (months = 0; days_in_month[months] <= remdays; months++) remdays -= days_in_month[months]; if (months >= 10) { months -= 12; years++; } if (!ms_passes_tz_constraint(PyDateTime_TimeZone_UTC, type, path)) return NULL; return PyDateTimeAPI->DateTime_FromDateAndTime( years + 2000, months + 3, remdays + 1, remsecs / 3600, remsecs / 60 % 60, remsecs % 60, micros, PyDateTime_TimeZone_UTC, PyDateTimeAPI->DateTimeType ); } static inline const char * ms_read_fixint(const char *buf, int width, int *out) { int x = 0; for (int i = 0; i < width; i++) { char c = *buf++; if (!is_digit(c)) return NULL; x = x * 10 + (c - '0'); } *out = x; return buf; } /* Requires 10 bytes of scratch space */ static void ms_encode_date(PyObject *obj, char *out) { uint32_t year = PyDateTime_GET_YEAR(obj); uint8_t month = PyDateTime_GET_MONTH(obj); uint8_t day = PyDateTime_GET_DAY(obj); write_u32_4_digits(year, out); *(out + 4) = '-'; write_u32_2_digits(month, out + 5); *(out + 7) = '-'; write_u32_2_digits(day, out + 8); } /* Requires 21 bytes of scratch space */ static int ms_encode_time_parts( MsgspecState *mod, PyObject *datetime_or_none, uint8_t hour, uint8_t minute, uint8_t second, uint32_t microsecond, PyObject *tzinfo, char *out, int out_offset ) { char *p = out + out_offset; write_u32_2_digits(hour, p); p += 2; *p++ = ':'; write_u32_2_digits(minute, p); p += 2; *p++ = ':'; write_u32_2_digits(second, p); p += 2; if (microsecond) { *p++ = '.'; write_u32_6_digits(microsecond, p); p += 6; } if (tzinfo != Py_None) { int32_t offset_days = 0, offset_secs = 0; if (tzinfo != PyDateTime_TimeZone_UTC) { PyObject *offset = PyObject_CallMethodOneArg( tzinfo, mod->str_utcoffset, datetime_or_none ); if (offset == NULL) { return -1; } else if (PyDelta_Check(offset)) { offset_days = PyDateTime_DELTA_GET_DAYS(offset); offset_secs = PyDateTime_DELTA_GET_SECONDS(offset); Py_DECREF(offset); } else if (offset == Py_None) { Py_DECREF(offset); goto done; } else if (offset != Py_None) { PyErr_SetString( PyExc_TypeError, "tzinfo.utcoffset returned a non-timedelta object" ); Py_DECREF(offset); return -1; } } if (MS_LIKELY(offset_secs == 0)) { *p++ = 'Z'; } else { char sign = '+'; if (offset_days == -1) { sign = '-'; offset_secs = 86400 - offset_secs; } uint8_t offset_hour = offset_secs / 3600; uint8_t offset_min = (offset_secs / 60) % 60; /* If the offset isn't an even number of minutes, RFC 3339 * indicates that the offset should be rounded to the nearest * possible hour:min pair */ bool round_up = (offset_secs - (offset_hour * 3600 + offset_min * 60)) > 30; if (MS_UNLIKELY(round_up)) { offset_min++; if (offset_min == 60) { offset_min = 0; offset_hour++; if (offset_hour == 24) { offset_hour = 0; } } } if (offset_hour == 0 && offset_min == 0) { *p++ = 'Z'; } else { *p++ = sign; write_u32_2_digits(offset_hour, p); p += 2; *p++ = ':'; write_u32_2_digits(offset_min, p); p += 2; } } } done: return p - out; } /* Requires 21 bytes of scratch space max. * * Returns +nbytes if successful, -1 on failure */ static int ms_encode_time(MsgspecState *mod, PyObject *obj, char *out) { uint8_t hour = PyDateTime_TIME_GET_HOUR(obj); uint8_t minute = PyDateTime_TIME_GET_MINUTE(obj); uint8_t second = PyDateTime_TIME_GET_SECOND(obj); uint32_t microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); PyObject *tzinfo = MS_TIME_GET_TZINFO(obj); return ms_encode_time_parts( mod, Py_None, hour, minute, second, microsecond, tzinfo, out, 0 ); } /* Requires 32 bytes of scratch space max. * * Returns +nbytes if successful, -1 on failure */ static int ms_encode_datetime(MsgspecState *mod, PyObject *obj, char *out) { uint8_t hour = PyDateTime_DATE_GET_HOUR(obj); uint8_t minute = PyDateTime_DATE_GET_MINUTE(obj); uint8_t second = PyDateTime_DATE_GET_SECOND(obj); uint32_t microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); PyObject *tzinfo = MS_DATE_GET_TZINFO(obj); ms_encode_date(obj, out); out[10] = 'T'; return ms_encode_time_parts( mod, obj, hour, minute, second, microsecond, tzinfo, out, 11 ); } static PyObject * ms_decode_date(const char *buf, Py_ssize_t size, PathNode *path) { int year, month, day; /* A valid date is 10 characters in length */ if (size != 10) goto invalid; /* Parse date */ if ((buf = ms_read_fixint(buf, 4, &year)) == NULL) goto invalid; if (*buf++ != '-') goto invalid; if ((buf = ms_read_fixint(buf, 2, &month)) == NULL) goto invalid; if (*buf++ != '-') goto invalid; if ((buf = ms_read_fixint(buf, 2, &day)) == NULL) goto invalid; /* Ensure all numbers are valid */ if (year == 0) goto invalid; if (month == 0 || month > 12) goto invalid; if (day == 0 || day > days_in_month(year, month)) goto invalid; return PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType); invalid: return ms_error_with_path("Invalid RFC3339 encoded date%U", path); } static PyObject * ms_decode_time(const char *buf, Py_ssize_t size, TypeNode *type, PathNode *path) { int hour, minute, second, microsecond = 0; const char *buf_end = buf + size; bool round_up_micros = false; PyObject *tz = NULL; char c; /* A valid time is at least 8 characters in length */ if (size < 8) goto invalid; /* Parse time */ if ((buf = ms_read_fixint(buf, 2, &hour)) == NULL) goto invalid; if (*buf++ != ':') goto invalid; if ((buf = ms_read_fixint(buf, 2, &minute)) == NULL) goto invalid; if (*buf++ != ':') goto invalid; if ((buf = ms_read_fixint(buf, 2, &second)) == NULL) goto invalid; /* Remaining reads require bounds check */ #define next_or_null() (buf == buf_end) ? '\0' : *buf++ c = next_or_null(); if (c == '.') { int ndigits = 0; while (ndigits < 6) { c = next_or_null(); if (!is_digit(c)) goto end_decimal; ndigits++; microsecond = microsecond * 10 + (c - '0'); } c = next_or_null(); if (is_digit(c)) { /* This timestamp has higher precision than microseconds; parse * the next digit to support rounding, then skip all remaining * digits */ if ((c - '0') >= 5) { round_up_micros = true; } while (true) { c = next_or_null(); if (!is_digit(c)) break; } } end_decimal: /* Error if no digits after decimal */ if (ndigits == 0) goto invalid; int pow10[6] = {100000, 10000, 1000, 100, 10, 1}; /* Scale microseconds appropriately */ microsecond *= pow10[ndigits - 1]; } #undef next_or_null if (c != '\0') { /* Parse timezone */ int offset = 0; if (c == 'Z' || c == 'z') { /* Check for trailing characters */ if (buf != buf_end) goto invalid; } else { int offset_hour, offset_min; if (c == '-') { offset = -1; } else if (c == '+') { offset = 1; } else { goto invalid; } if (buf_end - buf < 3) goto invalid; if ((buf = ms_read_fixint(buf, 2, &offset_hour)) == NULL) goto invalid; /* RFC3339 requires a ':' separator, ISO8601 doesn't. We support * either */ if (*buf == ':') buf++; if (buf_end - buf != 2) goto invalid; if ((buf = ms_read_fixint(buf, 2, &offset_min)) == NULL) goto invalid; if (offset_hour > 23 || offset_min > 59) goto invalid; offset *= (offset_hour * 60 + offset_min); } if (offset == 0) { tz = PyDateTime_TimeZone_UTC; Py_INCREF(tz); } else { tz = timezone_from_offset(offset); if (tz == NULL) goto error; } } else { tz = Py_None; Py_INCREF(tz); } /* Ensure all numbers are valid */ if (hour > 23) goto invalid; if (minute > 59) goto invalid; if (second > 59) goto invalid; if (MS_UNLIKELY(round_up_micros)) { time_round_up_micros(&hour, &minute, &second, µsecond); } if (!ms_passes_tz_constraint(tz, type, path)) goto error; PyObject *out = PyDateTimeAPI->Time_FromTime( hour, minute, second, microsecond, tz, PyDateTimeAPI->TimeType ); Py_XDECREF(tz); return out; invalid: ms_error_with_path("Invalid RFC3339 encoded time%U", path); error: Py_XDECREF(tz); return NULL; } static PyObject * ms_decode_datetime_from_int64( int64_t timestamp, TypeNode *type, PathNode *path ) { return datetime_from_epoch(timestamp, 0, type, path); } static PyObject * ms_decode_datetime_from_uint64( uint64_t timestamp, TypeNode *type, PathNode *path ) { if (timestamp > LLONG_MAX) { timestamp = LLONG_MAX; /* will raise out of range error later */ } return datetime_from_epoch((int64_t)timestamp, 0, type, path); } static PyObject * ms_decode_datetime_from_float( double timestamp, TypeNode *type, PathNode *path ) { if (MS_UNLIKELY(!isfinite(timestamp))) { return ms_error_with_path("Invalid epoch timestamp%U", path); } int64_t secs = trunc(timestamp); int32_t nanos = 1000000000 * (timestamp - secs); if (nanos && timestamp < 0) { secs--; nanos += 1000000000; } return datetime_from_epoch(secs, nanos, type, path); } static PyObject * ms_decode_datetime_from_str( const char *buf, Py_ssize_t size, TypeNode *type, PathNode *path ) { int year, month, day, hour, minute, second, microsecond = 0; const char *buf_end = buf + size; bool round_up_micros = false; PyObject *tz = NULL; char c; /* A valid datetime is at least 19 characters in length */ if (size < 19) goto invalid; /* Parse date */ if ((buf = ms_read_fixint(buf, 4, &year)) == NULL) goto invalid; if (*buf++ != '-') goto invalid; if ((buf = ms_read_fixint(buf, 2, &month)) == NULL) goto invalid; if (*buf++ != '-') goto invalid; if ((buf = ms_read_fixint(buf, 2, &day)) == NULL) goto invalid; /* RFC3339 date/time separator can be T or t. We also support ' ', which is * ISO8601 compatible. */ c = *buf++; if (!(c == 'T' || c == 't' || c == ' ')) goto invalid; /* Parse time */ if ((buf = ms_read_fixint(buf, 2, &hour)) == NULL) goto invalid; if (*buf++ != ':') goto invalid; if ((buf = ms_read_fixint(buf, 2, &minute)) == NULL) goto invalid; if (*buf++ != ':') goto invalid; if ((buf = ms_read_fixint(buf, 2, &second)) == NULL) goto invalid; /* Remaining reads require bounds check */ #define next_or_null() (buf == buf_end) ? '\0' : *buf++ c = next_or_null(); /* Parse decimal if present. * * Python datetime's only supports microsecond precision, but RFC3339 * doesn't specify a decimal precision limit. To work around this we * support infinite decimal digits, but round to the closest microsecond. * This means that nanosecond timestamps won't properly roundtrip through * datetime objects, but there's not much we can do about that. Other * systems commonly accept 3 or 6 digits, support for/usage of nanosecond * precision is rare. */ if (c == '.') { int ndigits = 0; while (ndigits < 6) { c = next_or_null(); if (!is_digit(c)) goto end_decimal; ndigits++; microsecond = microsecond * 10 + (c - '0'); } c = next_or_null(); if (is_digit(c)) { /* This timestamp has higher precision than microseconds; parse * the next digit to support rounding, then skip all remaining * digits */ if ((c - '0') >= 5) { round_up_micros = true; } while (true) { c = next_or_null(); if (!is_digit(c)) break; } } end_decimal: /* Error if no digits after decimal */ if (ndigits == 0) goto invalid; int pow10[6] = {100000, 10000, 1000, 100, 10, 1}; /* Scale microseconds appropriately */ microsecond *= pow10[ndigits - 1]; } #undef next_or_null if (c != '\0') { /* Parse timezone */ int offset = 0; if (c == 'Z' || c == 'z') { /* Check for trailing characters */ if (buf != buf_end) goto invalid; } else { int offset_hour, offset_min; if (c == '-') { offset = -1; } else if (c == '+') { offset = 1; } else { goto invalid; } if (buf_end - buf < 3) goto invalid; if ((buf = ms_read_fixint(buf, 2, &offset_hour)) == NULL) goto invalid; /* RFC3339 requires a ':' separator, ISO8601 doesn't. We support * either */ if (*buf == ':') buf++; if (buf_end - buf != 2) goto invalid; if ((buf = ms_read_fixint(buf, 2, &offset_min)) == NULL) goto invalid; if (offset_hour > 23 || offset_min > 59) goto invalid; offset *= (offset_hour * 60 + offset_min); } if (offset == 0) { tz = PyDateTime_TimeZone_UTC; Py_INCREF(tz); } else { tz = timezone_from_offset(offset); if (tz == NULL) goto error; } } else { tz = Py_None; Py_INCREF(tz); } /* Ensure all numbers are valid */ if (year == 0) goto invalid; if (month == 0 || month > 12) goto invalid; if (day == 0 || day > days_in_month(year, month)) goto invalid; if (hour > 23) goto invalid; if (minute > 59) goto invalid; if (second > 59) goto invalid; if (MS_UNLIKELY(round_up_micros)) { if ( datetime_round_up_micros( &year, &month, &day, &hour, &minute, &second, µsecond ) < 0 ) goto invalid; } if (!ms_passes_tz_constraint(tz, type, path)) goto error; PyObject *out = PyDateTimeAPI->DateTime_FromDateAndTime( year, month, day, hour, minute, second, microsecond, tz, PyDateTimeAPI->DateTimeType ); Py_XDECREF(tz); return out; invalid: ms_error_with_path("Invalid RFC3339 encoded datetime%U", path); error: Py_XDECREF(tz); return NULL; } /* Requires 26 bytes of scratch space */ static int ms_encode_timedelta(PyObject *obj, char *out) { const char *start = out; int days = PyDateTime_DELTA_GET_DAYS(obj); int secs = PyDateTime_DELTA_GET_SECONDS(obj); int micros = PyDateTime_DELTA_GET_MICROSECONDS(obj); if (days < 0) { *out++ = '-'; days = -days; if (secs != 0 || micros != 0) { days--; if (micros != 0) { micros = 1000000 - micros; secs += 1; } secs = 86400 - secs; } } *out++ = 'P'; if (days != 0) { out = write_u64(days, out); *out++ = 'D'; } if (secs != 0 || micros != 0) { *out++ = 'T'; out = write_u64(secs, out); if (micros != 0) { *out++ = '.'; write_u32_6_digits(micros, out); out += 6; while (*(out - 1) == '0') { out--; } } *out++ = 'S'; } else if (days == 0) { *out++ = '0'; *out++ = 'D'; } return out - start; } #define MS_TIMEDELTA_MAX_SECONDS (86399999999999LL) #define MS_TIMEDELTA_MIN_SECONDS (-86399999913600LL) static PyObject * ms_timedelta_from_parts(int64_t secs, int micros) { int64_t days = secs / (24 * 60 * 60); secs -= days * (24 * 60 * 60); return PyDelta_FromDSU(days, secs, micros); } static PyObject * ms_decode_timedelta_from_uint64(uint64_t x, PathNode *path) { if (x > (uint64_t)MS_TIMEDELTA_MAX_SECONDS) { return ms_error_with_path("Duration is out of range%U", path); } return ms_timedelta_from_parts((int64_t)x, 0); } static PyObject * ms_decode_timedelta_from_int64(int64_t x, PathNode *path) { if ((x > MS_TIMEDELTA_MAX_SECONDS) || (x < MS_TIMEDELTA_MIN_SECONDS)) { return ms_error_with_path("Duration is out of range%U", path); } return ms_timedelta_from_parts(x, 0); } static PyObject * ms_decode_timedelta_from_float(double x, PathNode *path) { if ( (!isfinite(x)) || (x > (double)MS_TIMEDELTA_MAX_SECONDS) || (x < (double)MS_TIMEDELTA_MIN_SECONDS) ) { return ms_error_with_path("Duration is out of range%U", path); } int64_t secs = trunc(x); long micros = lround(1000000 * (x - secs)); return ms_timedelta_from_parts(secs, micros); } enum timedelta_parse_state { TIMEDELTA_START = 0, TIMEDELTA_D = 1, TIMEDELTA_T = 2, TIMEDELTA_H = 3, TIMEDELTA_M = 4, TIMEDELTA_S = 5, }; /* Parses a timedelta from an extended ISO8601 Duration. We try to follow the * ISO8601-2 spec as closely as possible, extrapolating as needed when the spec * is vague. We've also limited support for some units/ranges as needed to fit * python's timedelta model. * * Values parsed here are compatible with Java's `Time.Duration.parse`, as well * as the proposed javascript `Temporal.Duration.from` API. * * We accept the following format: [-/+]P#DT#H#M#S * * where # is a number with optional decimal component. Characters are case * insensitive. * * Additional restrictions, mostly taken from the ISO spec. Extrapolations or * self-imposed restrictions are noted. * * - The units D (days), H (hours), M (minutes) and S (seconds) may be omitted * if their value is 0. * * - At least one value must be present (`P0D` is a valid 0 duration, but `P` * is not). * * - If present, the values must be in the proper unit order (D, H, M, S). * * - If a unit value contains a fractional number, it must be the last unit. * `PT1H1.5S` and `PT1.5H` are valid but `PT1.5H1S` is not. * * - Unlike JSON numbers, leading 0s are fine. `P001D` and `P1D` are * equivalent. * * - If `T` is present, there must be at least one time component after it. * This isn't explicitly said in the spec, but is enforced by both Java and * Temporal APIs. * * - A leading `-` or `+` may be used to indicate a negative or positive * duration. This is part of the extended spec in ISO8601-2, and is supported * by both Java and Temporal apis. * * - We don't support relative duration units (Y (year), M (month), W (week)). * Python's timedeltas are absolute deltas composed of fixed-length days, * seconds, and microseconds. There's no way to accurately store a relative * quantity like "months". Java's Duration implementation has the same * restriction. * * - This implementation will error for durations that exceed python's * timedelta range limits. The ISO spec provides no restrictions on duration * range. */ static PyObject * ms_decode_timedelta( const char *p, Py_ssize_t size, TypeNode *type, PathNode *path ) { bool neg = false; const char *end = p + size; if (p == end) goto invalid; if (*p == '-') { neg = true; p++; if (p == end) goto invalid; } else if (*p == '+') { p++; if (p == end) goto invalid; } if (*p != 'P' && *p != 'p') goto invalid; p++; if (p == end) goto invalid; int64_t seconds = 0; int micros = 0; enum timedelta_parse_state parse_state = TIMEDELTA_START; while (true) { if (p == end) goto invalid; /* Missing segment */ if (*p == 'T' || *p == 't') { if (parse_state >= TIMEDELTA_T) goto invalid; parse_state = TIMEDELTA_T; p++; continue; } uint32_t scale; bool has_frac = false; uint64_t x = 0, frac_num = 0, frac_den = 10; /* Read integral part */ if (!is_digit(*p)) goto invalid; x = *p - '0'; p++; while (true) { if (p == end) goto invalid; /* missing unit */ if (!is_digit(*p)) break; x = x * 10 + (uint64_t)(*p - '0'); if (x > (1ULL << 47)) goto out_of_range; p++; } if (*p == '.') { /* Read fractional part */ has_frac = true; p++; if (p == end) goto invalid; if (!is_digit(*p)) goto invalid; frac_num = *p - '0'; p++; /* Parse up to 10 more decimal digits. * * Since the largest unit we support is days, and python's * timedelta has microsecond precision, only 11 decimal digits need * to be read. Any further precision will have no effect on the * output. */ for (int i = 0; i < 10; i++) { if (p == end) goto invalid; /* missing unit */ if (!is_digit(*p)) goto parse_unit; frac_num = frac_num * 10 + (uint64_t)(*p - '0'); frac_den *= 10; p++; } /* Remaining digits won't have any effect on output, skip them */ while (true) { if (p == end) goto invalid; /* missing unit */ if (!is_digit(*p)) goto parse_unit; p++; } } parse_unit: switch (*p++) { case 'D': case 'd': { if (parse_state >= TIMEDELTA_D) goto invalid; parse_state = TIMEDELTA_D; scale = 24 * 60 * 60; break; }; case 'H': case 'h': { if (parse_state < TIMEDELTA_T || parse_state >= TIMEDELTA_H) goto invalid; parse_state = TIMEDELTA_H; scale = 60 * 60; break; } case 'M': case 'm': { if (parse_state < TIMEDELTA_T) goto unsupported; if (parse_state >= TIMEDELTA_M) goto invalid; parse_state = TIMEDELTA_M; scale = 60; break; }; case 'S': case 's': { if (parse_state < TIMEDELTA_T || parse_state >= TIMEDELTA_S) goto invalid; parse_state = TIMEDELTA_S; scale = 1; break; }; case 'W': case 'w': case 'Y': case 'y': goto unsupported; default: goto invalid; } /* Apply integral part */ seconds += scale * x; if (has_frac) { /* Apply fractional part */ frac_num *= scale; int64_t extra_secs = frac_num / frac_den; int extra_micros = DIV_ROUND_CLOSEST(1000000 * (frac_num - (extra_secs * frac_den)), frac_den); micros += extra_micros; if (micros >= 1000000) { extra_secs++; micros -= 1000000; } seconds += extra_secs; } /* Ensure seconds are still in-bounds */ if (seconds > MS_TIMEDELTA_MAX_SECONDS) goto out_of_range; if (p == end) { break; } else if (has_frac) { goto invalid; /* decimal segment must be last */ } } if (neg) { seconds = -seconds; if (micros) { micros = 1000000 - micros; seconds -= 1; } /* abs(lower_limit) < upper_limit, so we need to recheck it here */ if (seconds < MS_TIMEDELTA_MIN_SECONDS) goto out_of_range; } int64_t days = seconds / (24 * 60 * 60); seconds -= days * (24 * 60 * 60); return PyDelta_FromDSU(days, seconds, micros); invalid: return ms_error_with_path("Invalid ISO8601 duration%U", path); out_of_range: return ms_error_with_path("Duration is out of range%U", path); unsupported: return ms_error_with_path( "Only units 'D', 'H', 'M', and 'S' are supported when parsing ISO8601 durations%U", path ); } /************************************************************************* * Base64 Encoder * *************************************************************************/ static Py_ssize_t ms_encode_base64_size(MsgspecState *mod, Py_ssize_t input_size) { if (input_size >= (1LL << 32)) { PyErr_SetString( mod->EncodeError, "Can't encode bytes-like objects longer than 2**32 - 1" ); return -1; } /* ceil(4/3 * input_size) */ return 4 * ((input_size + 2) / 3); } static void ms_encode_base64(const char *input, Py_ssize_t input_size, char *out) { int nbits = 0; unsigned int charbuf = 0; for (; input_size > 0; input_size--, input++) { charbuf = (charbuf << 8) | (unsigned char)(*input); nbits += 8; while (nbits >= 6) { unsigned char ind = (charbuf >> (nbits - 6)) & 0x3f; nbits -= 6; *out++ = base64_encode_table[ind]; } } if (nbits == 2) { *out++ = base64_encode_table[(charbuf & 3) << 4]; *out++ = '='; *out++ = '='; } else if (nbits == 4) { *out++ = base64_encode_table[(charbuf & 0xf) << 2]; *out++ = '='; } } /************************************************************************* * UUID Utilities * *************************************************************************/ static int ms_uuid_to_16_bytes(MsgspecState *mod, PyObject *obj, unsigned char *buf) { PyObject *int128 = PyObject_GetAttr(obj, mod->str_int); if (int128 == NULL) return -1; if (MS_UNLIKELY(!PyLong_CheckExact(int128))) { PyErr_SetString(PyExc_TypeError, "uuid.int must be an int"); return -1; } #if PY313_PLUS int out = (int)PyLong_AsNativeBytes( int128, buf, 16, Py_ASNATIVEBYTES_BIG_ENDIAN | Py_ASNATIVEBYTES_UNSIGNED_BUFFER ); #else int out = _PyLong_AsByteArray((PyLongObject *)int128, buf, 16, 0, 0); #endif Py_DECREF(int128); return out; } static PyObject * ms_uuid_from_16_bytes(const unsigned char *buf) { PyObject *int128 = _PyLong_FromByteArray(buf, 16, 0, 0); if (int128 == NULL) return NULL; MsgspecState *mod = msgspec_get_global_state(); PyTypeObject *uuid_type = (PyTypeObject *)(mod->UUIDType); PyObject *out = uuid_type->tp_alloc(uuid_type, 0); if (out == NULL) goto error; /* UUID objects are immutable, use GenericSetAttr instead of SetAttr */ if (PyObject_GenericSetAttr(out, mod->str_int, int128) < 0) goto error; if (PyObject_GenericSetAttr(out, mod->str_is_safe, mod->uuid_safeuuid_unknown) < 0) goto error; Py_DECREF(int128); return out; error: Py_DECREF(int128); Py_XDECREF(out); return NULL; } /* Requires up to 36 bytes of space */ static int ms_encode_uuid(MsgspecState *mod, PyObject *obj, char *out, bool canonical) { unsigned char scratch[16]; unsigned char *buf = scratch; if (ms_uuid_to_16_bytes(mod, obj, scratch) < 0) return -1; for (int i = 0; i < 4; i++) { unsigned char c = *buf++; *out++ = hex_encode_table[c >> 4]; *out++ = hex_encode_table[c & 0xF]; } if (canonical) *out++ = '-'; for (int j = 0; j < 3; j++) { for (int i = 0; i < 2; i++) { unsigned char c = *buf++; *out++ = hex_encode_table[c >> 4]; *out++ = hex_encode_table[c & 0xF]; } if (canonical) *out++ = '-'; } for (int i = 0; i < 6; i++) { unsigned char c = *buf++; *out++ = hex_encode_table[c >> 4]; *out++ = hex_encode_table[c & 0xF]; } return 0; } static PyObject * ms_decode_uuid_from_str(const char *buf, Py_ssize_t size, PathNode *path) { unsigned char scratch[16]; unsigned char *decoded = scratch; int segments[] = {4, 2, 2, 2, 6}; /* A valid uuid is 32 or 36 characters in length */ if (size != 32 && size != 36) goto invalid; bool has_hyphens = size == 36; for (int i = 0; i < 5; i++) { for (int j = 0; j < segments[i]; j++) { char hi = *buf++; if (hi >= '0' && hi <= '9') { hi -= '0'; } else if (hi >= 'a' && hi <= 'f') { hi = hi - 'a' + 10; } else if (hi >= 'A' && hi <= 'F') { hi = hi - 'A' + 10; } else { goto invalid; } char lo = *buf++; if (lo >= '0' && lo <= '9') { lo -= '0'; } else if (lo >= 'a' && lo <= 'f') { lo = lo - 'a' + 10; } else if (lo >= 'A' && lo <= 'F') { lo = lo - 'A' + 10; } else { goto invalid; } *decoded++ = ((unsigned char)hi << 4) + (unsigned char)lo; } if (has_hyphens && i < 4 && *buf++ != '-') goto invalid; } return ms_uuid_from_16_bytes(scratch); invalid: return ms_error_with_path("Invalid UUID%U", path); } static PyObject * ms_decode_uuid_from_bytes(const char *buf, Py_ssize_t size, PathNode *path) { if (size == 16) { return ms_uuid_from_16_bytes((unsigned char *)buf); } return ms_error_with_path("Invalid UUID bytes%U", path); } /************************************************************************* * Decimal Utilities * *************************************************************************/ static PyObject * ms_decode_decimal_from_pyobj(PyObject *str, PathNode *path, MsgspecState *mod) { if (mod == NULL) { mod = msgspec_get_global_state(); } return PyObject_CallOneArg(mod->DecimalType, str); } static PyObject * ms_decode_decimal_from_pystr(PyObject *str, PathNode *path, MsgspecState *mod) { PyObject *out = ms_decode_decimal_from_pyobj(str, path, mod); if (out == NULL) { ms_error_with_path("Invalid decimal string%U", path); } return out; } static PyObject * ms_decode_decimal( const char *view, Py_ssize_t size, bool is_ascii, PathNode *path, MsgspecState *mod ) { PyObject *str; if (MS_LIKELY(is_ascii)) { str = PyUnicode_New(size, 127); if (str == NULL) return NULL; memcpy(ascii_get_buffer(str), view, size); } else { str = PyUnicode_DecodeUTF8(view, size, NULL); if (str == NULL) return NULL; } PyObject *out = ms_decode_decimal_from_pystr(str, path, mod); Py_DECREF(str); return out; } static PyObject * ms_decode_decimal_from_int64(int64_t x, PathNode *path) { PyObject *temp = PyLong_FromLongLong(x); if (temp == NULL) return NULL; PyObject *out = ms_decode_decimal_from_pyobj(temp, path, NULL); Py_DECREF(temp); return out; } static PyObject * ms_decode_decimal_from_uint64(uint64_t x, PathNode *path) { PyObject *temp = PyLong_FromUnsignedLongLong(x); if (temp == NULL) return NULL; PyObject *out = ms_decode_decimal_from_pyobj(temp, path, NULL); Py_DECREF(temp); return out; } static PyObject * ms_decode_decimal_from_float(double val, PathNode *path, MsgspecState *mod) { if (MS_LIKELY(isfinite(val))) { /* For finite values, render as the nearest IEEE754 double in string * form, then call decimal.Decimal to parse */ char buf[24]; int n = write_f64(val, buf, false); return ms_decode_decimal(buf, n, true, path, mod); } else { /* For nonfinite values, convert to float obj and go through python */ PyObject *temp = PyFloat_FromDouble(val); if (temp == NULL) return NULL; PyObject *out = ms_decode_decimal_from_pyobj(temp, path, mod); Py_DECREF(temp); return out; } } /************************************************************************* * strict=False Utilities * *************************************************************************/ static bool maybe_parse_number( const char *, Py_ssize_t, TypeNode *, PathNode *, bool, PyObject ** ); static PyObject * ms_decode_str_lax( const char *view, Py_ssize_t size, TypeNode *type, PathNode *path, bool *invalid ) { if (type->types & ( MS_TYPE_INT | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL | MS_TYPE_BOOL | MS_TYPE_FLOAT | MS_TYPE_DECIMAL | MS_TYPE_DATETIME | MS_TYPE_TIMEDELTA ) ) { PyObject *out; if (maybe_parse_number(view, size, type, path, false, &out)) { return out; } } if (type->types & MS_TYPE_BOOL) { if (size == 4) { if ( (view[0] == 't' || view[0] == 'T') && (view[1] == 'r' || view[1] == 'R') && (view[2] == 'u' || view[2] == 'U') && (view[3] == 'e' || view[3] == 'E') ) { Py_RETURN_TRUE; } } else if (size == 5) { if ( (view[0] == 'f' || view[0] == 'F') && (view[1] == 'a' || view[1] == 'A') && (view[2] == 'l' || view[2] == 'L') && (view[3] == 's' || view[3] == 'S') && (view[4] == 'e' || view[4] == 'E') ) { Py_RETURN_FALSE; } } } if (type->types & MS_TYPE_NONE) { if (size == 4 && (view[0] == 'n' || view[0] == 'N') && (view[1] == 'u' || view[1] == 'U') && (view[2] == 'l' || view[2] == 'L') && (view[3] == 'l' || view[3] == 'L') ) { Py_RETURN_NONE; } } *invalid = true; return NULL; } /************************************************************************* * Shared Post-Decode Handlers * *************************************************************************/ static PyObject * ms_post_decode_int64( int64_t x, TypeNode *type, PathNode *path, bool strict, bool from_str ) { if (MS_LIKELY(type->types & (MS_TYPE_ANY | MS_TYPE_INT))) { return ms_decode_int(x, type, path); } else if (type->types & (MS_TYPE_INTENUM | MS_TYPE_INTLITERAL)) { return ms_decode_int_enum_or_literal_int64(x, type, path); } else if (type->types & MS_TYPE_FLOAT) { return ms_decode_float(x, type, path); } else if (type->types & MS_TYPE_DECIMAL) { return ms_decode_decimal_from_int64(x, path); } else if (!strict) { if (type->types & MS_TYPE_BOOL) { PyObject *out = ms_maybe_decode_bool_from_int64(x); if (out != NULL) return out; } if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_int64(x, type, path); } if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta_from_int64(x, path); } } return ms_validation_error(from_str ? "str" : "int", type, path); } static PyObject * ms_post_decode_uint64( uint64_t x, TypeNode *type, PathNode *path, bool strict, bool from_str ) { if (MS_LIKELY(type->types & (MS_TYPE_ANY | MS_TYPE_INT))) { return ms_decode_uint(x, type, path); } else if (type->types & (MS_TYPE_INTENUM | MS_TYPE_INTLITERAL)) { return ms_decode_int_enum_or_literal_uint64(x, type, path); } else if (type->types & MS_TYPE_FLOAT) { return ms_decode_float(x, type, path); } else if (type->types & MS_TYPE_DECIMAL) { return ms_decode_decimal_from_uint64(x, path); } else if (!strict) { if (type->types & MS_TYPE_BOOL) { PyObject *out = ms_maybe_decode_bool_from_uint64(x); if (out != NULL) return out; } if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_uint64(x, type, path); } if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta_from_uint64(x, path); } } return ms_validation_error(from_str ? "str" : "int", type, path); } static bool double_as_int64(double x, int64_t *out) { if (fmod(x, 1.0) != 0.0) return false; if (x > (1LL << 53)) return false; if (x < (-1LL << 53)) return false; *out = (int64_t)x; return true; } static PyObject * ms_post_decode_float( double x, TypeNode *type, PathNode *path, bool strict, bool from_str ) { if (type->types & (MS_TYPE_ANY | MS_TYPE_FLOAT)) { return ms_decode_float(x, type, path); } else if (!strict) { if (type->types & MS_TYPE_INT) { int64_t out; if (double_as_int64(x, &out)) { return ms_post_decode_int64(out, type, path, strict, from_str); } } if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_float(x, type, path); } if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta_from_float(x, path); } } return ms_validation_error(from_str ? "str" : "float", type, path); } /************************************************************************* * Number Parser * *************************************************************************/ #define ONE_E18 1000000000000000000ULL #define ONE_E19_MINUS_ONE 9999999999999999999ULL static MS_NOINLINE PyObject * parse_number_fallback( const unsigned char* integer_start, const unsigned char* integer_end, const unsigned char* fraction_start, const unsigned char* fraction_end, int32_t exp_part, bool is_negative, TypeNode *type, PathNode *path, bool strict, bool from_str ) { uint32_t nd = 0; int32_t dp = 0; ms_hpd dec; dec.num_digits = 0; dec.decimal_point = 0; dec.negative = is_negative; dec.truncated = false; /* Parse integer */ const unsigned char *p = integer_start; if (*p != '0') { while (p < integer_end) { if (MS_LIKELY(nd < MS_HPD_MAX_DIGITS)) { dec.digits[nd++] = (uint8_t)(*p - '0'); } else if (*p != '0') { dec.truncated = true; } dp++; p++; } } p = fraction_start; while (p < fraction_end) { if (*p == '0') { if (nd == 0) { /* Track leading zeros implicitly */ dp--; } else if (nd < MS_HPD_MAX_DIGITS) { dec.digits[nd++] = (uint8_t)(*p - '0'); } } else if ('1' <= *p && *p <= '9') { if (nd < MS_HPD_MAX_DIGITS) { dec.digits[nd++] = (uint8_t)(*p - '0'); } else { dec.truncated = true; } } p++; } dp += exp_part; dec.num_digits = nd; if (dp < -MS_HPD_DP_RANGE) { dec.decimal_point = -(MS_HPD_DP_RANGE + 1); } else if (dp > MS_HPD_DP_RANGE) { dec.decimal_point = (MS_HPD_DP_RANGE + 1); } else { dec.decimal_point = dp; } ms_hpd_trim(&dec); double res = ms_hpd_to_double(&dec); if (Py_IS_INFINITY(res)) { return ms_error_with_path("Number out of range%U", path); } return ms_post_decode_float(res, type, path, strict, from_str); } static MS_NOINLINE PyObject * parse_number_nonfinite( const unsigned char *start, bool is_negative, const unsigned char *p, const unsigned char *pend, const char **errmsg, TypeNode *type, PathNode *path, bool strict ) { size_t size = pend - p; double val; if (size == 3) { if ( (p[0] == 'n' || p[0] == 'N') && (p[1] == 'a' || p[1] == 'A') && (p[2] == 'n' || p[2] == 'N') ) { val = NAN; goto done; } else if ( (p[0] == 'i' || p[0] == 'I') && (p[1] == 'n' || p[1] == 'N') && (p[2] == 'f' || p[2] == 'F') ) { val = INFINITY; goto done; } } else if (size == 8) { if ( (p[0] == 'i' || p[0] == 'I') && (p[1] == 'n' || p[1] == 'N') && (p[2] == 'f' || p[2] == 'F') && (p[3] == 'i' || p[3] == 'I') && (p[4] == 'n' || p[4] == 'N') && (p[5] == 'i' || p[5] == 'I') && (p[6] == 't' || p[6] == 'T') && (p[7] == 'y' || p[7] == 'Y') ) { val = INFINITY; goto done; } } *errmsg = "invalid number"; return NULL; done: if ( MS_UNLIKELY( !(type->types & (MS_TYPE_ANY | MS_TYPE_FLOAT)) && type->types & MS_TYPE_DECIMAL ) ) { return ms_decode_decimal( (char *)start, pend - start, true, path, NULL ); } if (is_negative) { val = -val; } return ms_post_decode_float(val, type, path, strict, true); } static MS_NOINLINE PyObject * json_float_hook( const char *buf, Py_ssize_t size, PathNode *path, PyObject *float_hook ) { PyObject *str = PyUnicode_New(size, 127); if (str == NULL) return NULL; memcpy(ascii_get_buffer(str), buf, size); PyObject *out = PyObject_CallOneArg(float_hook, str); Py_DECREF(str); if (out == NULL) { ms_maybe_wrap_validation_error(path); return NULL; } return out; } static MS_INLINE PyObject * parse_number_inline( const unsigned char *p, const unsigned char *pend, const unsigned char **pout, const char **errmsg, TypeNode *type, PathNode *path, bool strict, PyObject *float_hook, bool from_str ) { uint64_t mantissa = 0; int64_t exponent = 0; int32_t exp_part = 0; bool is_negative = false; bool is_float = false; bool is_truncated = false; const unsigned char *start = p; /* We know there is at least one byte available when this function is * called */ if (*p == '-') { /* Parse minus sign */ p++; if (p == pend) goto invalid_number; is_negative = true; } const unsigned char *integer_start = p; /* Parse integer */ if (MS_UNLIKELY(*p == '0')) { p++; if (MS_UNLIKELY(p != pend && is_digit(*p))) goto invalid_number; } else { unsigned char c = *p; while (MS_LIKELY(is_digit(c))) { mantissa = mantissa * 10 + (uint8_t)(c - '0'); p++; if (MS_UNLIKELY(p == pend)) break; c = *p; } /* There must be at least one digit */ if (MS_UNLIKELY(integer_start == p)) { if (MS_UNLIKELY(from_str)) { return parse_number_nonfinite( start, is_negative, p, pend, errmsg, type, path, strict ); } else { goto invalid_character; } } } const unsigned char *integer_end = p; int64_t digit_count = integer_end - integer_start; const unsigned char *fraction_start = NULL; const unsigned char *fraction_end = NULL; if (MS_UNLIKELY(p == pend)) goto end_parsing; if (*p == '.') { is_float = true; p++; /* Parse fraction */ fraction_start = p; while (MS_LIKELY(p != pend && is_digit(*p))) { mantissa = mantissa * 10 + (uint8_t)(*p - '0'); p++; } /* Error if no digits after decimal */ if (MS_UNLIKELY(fraction_start == p)) goto invalid_number; fraction_end = p; exponent = fraction_start - p; digit_count -= exponent; if (MS_UNLIKELY(p == pend)) goto end_parsing; } if (*p == 'e' || *p == 'E') { is_float = true; int32_t exp_sign = 1; p++; if (p == pend) goto invalid_number; /* Parse exponent sign (if any) */ if (*p == '+') { p++; } else if (*p == '-') { p++; exp_sign = -1; } /* Parse exponent digits */ const unsigned char *start_exponent = p; while (p != pend && is_digit(*p)) { if (MS_LIKELY(exp_part < 10000)) { exp_part = exp_part * 10 + (uint8_t)(*p - '0'); } p++; } /* Error if no digits in exponent */ if (MS_UNLIKELY(start_exponent == p)) goto invalid_number; exp_part *= exp_sign; exponent += exp_part; } if (MS_UNLIKELY(from_str)) { if (MS_UNLIKELY(p != pend)) goto invalid_number; } end_parsing: /* Check for overflow and maybe reparse if needed */ if (MS_UNLIKELY(digit_count > 19)) { const unsigned char *cur = integer_start; while ((cur != pend) && (*cur == '0' || *cur == '.')) { if (*cur == '0') { digit_count--; } cur++; } if ( (digit_count > 19) && ( (is_float) || ((integer_end - integer_start) != 20) || (*integer_start != '1') || (mantissa <= ONE_E19_MINUS_ONE) ) ) { /* We overflowed. Redo parsing, truncating at 19 digits */ is_truncated = true; const unsigned char *cur = integer_start; mantissa = 0; while ((mantissa < ONE_E18) && (cur != integer_end)) { mantissa = mantissa * 10 + (uint64_t)(*cur - '0'); cur++; } if (mantissa >= ONE_E18) { exponent = integer_end - cur + exp_part; } else { cur = fraction_start; while ((mantissa < ONE_E18) && (cur != fraction_end)) { mantissa = mantissa * 10 + (uint64_t)(*cur - '0'); cur++; } exponent = fraction_start - cur + exp_part; } } } /* Forward output position */ *pout = p; if (!is_float) { if (is_negative) { is_truncated |= (mantissa > (1ull << 63)); } if (MS_UNLIKELY(is_truncated)) { if (type->types & (MS_TYPE_ANY | MS_TYPE_INT)) { return ms_decode_bigint((char *)start, p - start, type, path); } } else { if (is_negative) { return ms_post_decode_int64( -1 * (int64_t)(mantissa), type, path, strict, from_str ); } else { return ms_post_decode_uint64(mantissa, type, path, strict, from_str); } } } if ( MS_UNLIKELY( !(type->types & (MS_TYPE_ANY | MS_TYPE_FLOAT)) && type->types & MS_TYPE_DECIMAL ) ) { return ms_decode_decimal( (char *)start, p - start, true, path, NULL ); } else if (MS_UNLIKELY(float_hook != NULL && type->types & MS_TYPE_ANY)) { return json_float_hook((char *)start, p - start, path, float_hook); } else { if (MS_UNLIKELY(exponent > 288 || exponent < -307)) { /* Exponent is out of bounds */ goto fallback; } double val; if (MS_LIKELY((-22 <= exponent) && (exponent <= 22) && ((mantissa >> 53) == 0))) { /* If both `mantissa` and `10 ** exponent` can be exactly * represented as a double, we can take a fast path */ val = (double)(mantissa); if (exponent >= 0) { val *= ms_atof_f64_powers_of_10[exponent]; } else { val /= ms_atof_f64_powers_of_10[-exponent]; } } else if (MS_UNLIKELY(mantissa == 0)) { /* Special case 0 handling. This is only hit if the mantissa is 0 * and the exponent is out of bounds above (i.e. rarely) */ val = 0.0; } else { int64_t r1 = eisel_lemire(mantissa, exponent); if (MS_UNLIKELY(r1 < 0)) goto fallback; if (MS_UNLIKELY(is_truncated)) { int64_t r2 = eisel_lemire(mantissa + 1, exponent); if (r1 != r2) goto fallback; } uint64_t bits = ((uint64_t)r1); memcpy(&val, &bits, sizeof(double)); } if (is_negative) { val = -val; } return ms_post_decode_float(val, type, path, strict, from_str); } fallback: return parse_number_fallback( integer_start, integer_end, fraction_start, fraction_end, exp_part, is_negative, type, path, strict, from_str ); invalid_number: if (pout != NULL) *pout = p; *errmsg = "invalid number"; return NULL; invalid_character: if (pout != NULL) *pout = p; *errmsg = "invalid character"; return NULL; } static MS_NOINLINE bool maybe_parse_number( const char *view, Py_ssize_t size, TypeNode *type, PathNode *path, bool strict, PyObject **out ) { const char *errmsg = NULL; const unsigned char *pout; *out = parse_number_inline( (const unsigned char *)view, (const unsigned char *)(view + size), &pout, &errmsg, type, path, strict, NULL, true ); return (*out != NULL || errmsg == NULL); } /************************************************************************* * MessagePack Encoder * *************************************************************************/ PyDoc_STRVAR(Encoder__doc__, "Encoder(*, enc_hook=None, decimal_format='string', uuid_format='canonical', order=None)\n" "--\n" "\n" "A MessagePack encoder.\n" "\n" "Parameters\n" "----------\n" "enc_hook : callable, optional\n" " A callable to call for objects that aren't supported msgspec types. Takes\n" " the unsupported object and should return a supported object, or raise a\n" " ``NotImplementedError`` if unsupported.\n" "decimal_format : {'string', 'number'}, optional\n" " The format to use for encoding `decimal.Decimal` objects. If 'string'\n" " they're encoded as strings, if 'number', they're encoded as floats.\n" " Defaults to 'string', which is the recommended value since 'number'\n" " may result in precision loss when decoding.\n" "uuid_format : {'canonical', 'hex', 'bytes'}, optional\n" " The format to use for encoding `uuid.UUID` objects. The 'canonical'\n" " and 'hex' formats encode them as strings with and without hyphens\n" " respectively. The 'bytes' format encodes them as big-endian binary\n" " representations of the corresponding 128-bit integers. Defaults to\n" " 'canonical'.\n" "order : {None, 'deterministic', 'sorted'}, optional\n" " The ordering to use when encoding unordered compound types.\n" "\n" " - ``None``: All objects are encoded in the most efficient manner matching\n" " their in-memory representations. The default.\n" " - `'deterministic'`: Unordered collections (sets, dicts) are sorted to\n" " ensure a consistent output between runs. Useful when comparison/hashing\n" " of the encoded binary output is necessary.\n" " - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs,\n" " dataclasses, ...) are also sorted by field name before encoding. This is\n" " slower than `'deterministic'`, but may produce more human-readable output." ); enum mpack_code { MP_NIL = '\xc0', MP_FALSE = '\xc2', MP_TRUE = '\xc3', MP_FLOAT32 = '\xca', MP_FLOAT64 = '\xcb', MP_UINT8 = '\xcc', MP_UINT16 = '\xcd', MP_UINT32 = '\xce', MP_UINT64 = '\xcf', MP_INT8 = '\xd0', MP_INT16 = '\xd1', MP_INT32 = '\xd2', MP_INT64 = '\xd3', MP_FIXSTR = '\xa0', MP_STR8 = '\xd9', MP_STR16 = '\xda', MP_STR32 = '\xdb', MP_BIN8 = '\xc4', MP_BIN16 = '\xc5', MP_BIN32 = '\xc6', MP_FIXARRAY = '\x90', MP_ARRAY16 = '\xdc', MP_ARRAY32 = '\xdd', MP_FIXMAP = '\x80', MP_MAP16 = '\xde', MP_MAP32 = '\xdf', MP_FIXEXT1 = '\xd4', MP_FIXEXT2 = '\xd5', MP_FIXEXT4 = '\xd6', MP_FIXEXT8 = '\xd7', MP_FIXEXT16 = '\xd8', MP_EXT8 = '\xc7', MP_EXT16 = '\xc8', MP_EXT32 = '\xc9', }; static int mpack_encode_inline(EncoderState *self, PyObject *obj); static int mpack_encode_dict_key_inline(EncoderState *self, PyObject *obj); static int mpack_encode(EncoderState *self, PyObject *obj); static int mpack_encode_none(EncoderState *self) { const char op = MP_NIL; return ms_write(self, &op, 1); } static int mpack_encode_bool(EncoderState *self, PyObject *obj) { const char op = (obj == Py_True) ? MP_TRUE : MP_FALSE; return ms_write(self, &op, 1); } static MS_NOINLINE int mpack_encode_long(EncoderState *self, PyObject *obj) { bool overflow, neg; uint64_t ux; overflow = fast_long_extract_parts(obj, &neg, &ux); if (MS_UNLIKELY(overflow)) { PyErr_SetString( PyExc_OverflowError, "can't serialize ints < -2**63 or > 2**64 - 1" ); return -1; } if (MS_UNLIKELY(neg)) { int64_t x = -ux; if(x < -(1LL<<5)) { if(x < -(1LL<<15)) { if(x < -(1LL<<31)) { char buf[9]; buf[0] = MP_INT64; _msgspec_store64(&buf[1], x); return ms_write(self, buf, 9); } else { char buf[5]; buf[0] = MP_INT32; _msgspec_store32(&buf[1], (int32_t)x); return ms_write(self, buf, 5); } } else { if(x < -(1<<7)) { char buf[3]; buf[0] = MP_INT16; _msgspec_store16(&buf[1], (int16_t)x); return ms_write(self, buf, 3); } else { char buf[2] = {MP_INT8, (x & 0xff)}; return ms_write(self, buf, 2); } } } else { char buf[1] = {(x & 0xff)}; return ms_write(self, buf, 1); } } else { if (ux < (1<<7)) { char buf[1] = {(ux & 0xff)}; return ms_write(self, buf, 1); } else { if(ux < (1<<16)) { if(ux < (1<<8)) { char buf[2] = {MP_UINT8, (ux & 0xff)}; return ms_write(self, buf, 2); } else { char buf[3]; buf[0] = MP_UINT16; _msgspec_store16(&buf[1], (uint16_t)ux); return ms_write(self, buf, 3); } } else { if(ux < (1LL<<32)) { char buf[5]; buf[0] = MP_UINT32; _msgspec_store32(&buf[1], (uint32_t)ux); return ms_write(self, buf, 5); } else { char buf[9]; buf[0] = MP_UINT64; _msgspec_store64(&buf[1], ux); return ms_write(self, buf, 9); } } } } } static MS_NOINLINE int mpack_encode_float(EncoderState *self, PyObject *obj) { char buf[9]; double x = PyFloat_AS_DOUBLE(obj); uint64_t ux = 0; memcpy(&ux, &x, sizeof(double)); buf[0] = MP_FLOAT64; _msgspec_store64(&buf[1], ux); return ms_write(self, buf, 9); } static MS_NOINLINE int mpack_encode_cstr(EncoderState *self, const char *buf, Py_ssize_t len) { if (buf == NULL) { return -1; } if (len < 32) { char header[1] = {MP_FIXSTR | (uint8_t)len}; if (ms_write(self, header, 1) < 0) return -1; } else if (len < (1 << 8)) { char header[2] = {MP_STR8, (uint8_t)len}; if (ms_write(self, header, 2) < 0) return -1; } else if (len < (1 << 16)) { char header[3]; header[0] = MP_STR16; _msgspec_store16(&header[1], (uint16_t)len); if (ms_write(self, header, 3) < 0) return -1; } else if (len < (1LL << 32)) { char header[5]; header[0] = MP_STR32; _msgspec_store32(&header[1], (uint32_t)len); if (ms_write(self, header, 5) < 0) return -1; } else { PyErr_SetString( self->mod->EncodeError, "Can't encode strings longer than 2**32 - 1" ); return -1; } return len > 0 ? ms_write(self, buf, len) : 0; } static MS_INLINE int mpack_encode_str(EncoderState *self, PyObject *obj) { Py_ssize_t len; const char* buf = unicode_str_and_size(obj, &len); if (buf == NULL) return -1; return mpack_encode_cstr(self, buf, len); } static int mpack_encode_bin(EncoderState *self, const char* buf, Py_ssize_t len) { if (buf == NULL) { return -1; } if (len < (1 << 8)) { char header[2] = {MP_BIN8, (uint8_t)len}; if (ms_write(self, header, 2) < 0) return -1; } else if (len < (1 << 16)) { char header[3]; header[0] = MP_BIN16; _msgspec_store16(&header[1], (uint16_t)len); if (ms_write(self, header, 3) < 0) return -1; } else if (len < (1LL << 32)) { char header[5]; header[0] = MP_BIN32; _msgspec_store32(&header[1], (uint32_t)len); if (ms_write(self, header, 5) < 0) return -1; } else { PyErr_SetString( self->mod->EncodeError, "Can't encode bytes-like objects longer than 2**32 - 1" ); return -1; } return len > 0 ? ms_write(self, buf, len) : 0; } static int mpack_encode_bytes(EncoderState *self, PyObject *obj) { Py_ssize_t len = PyBytes_GET_SIZE(obj); const char* buf = PyBytes_AS_STRING(obj); return mpack_encode_bin(self, buf, len); } static int mpack_encode_bytearray(EncoderState *self, PyObject *obj) { Py_ssize_t len = PyByteArray_GET_SIZE(obj); const char* buf = PyByteArray_AS_STRING(obj); return mpack_encode_bin(self, buf, len); } static int mpack_encode_memoryview(EncoderState *self, PyObject *obj) { int out; Py_buffer buffer; if (PyObject_GetBuffer(obj, &buffer, PyBUF_CONTIG_RO) < 0) return -1; out = mpack_encode_bin(self, buffer.buf, buffer.len); PyBuffer_Release(&buffer); return out; } static int mpack_encode_raw(EncoderState *self, PyObject *obj) { Raw *raw = (Raw *)obj; return ms_write(self, raw->buf, raw->len); } static int mpack_encode_array_header(EncoderState *self, Py_ssize_t len, const char* typname) { if (len < 16) { char header[1] = {MP_FIXARRAY | len}; if (ms_write(self, header, 1) < 0) return -1; } else if (len < (1 << 16)) { char header[3]; header[0] = MP_ARRAY16; _msgspec_store16(&header[1], (uint16_t)len); if (ms_write(self, header, 3) < 0) return -1; } else if (len < (1LL << 32)) { char header[5]; header[0] = MP_ARRAY32; _msgspec_store32(&header[1], (uint32_t)len); if (ms_write(self, header, 5) < 0) return -1; } else { PyErr_Format( self->mod->EncodeError, "Can't encode %s longer than 2**32 - 1", typname ); return -1; } return 0; } static MS_INLINE int mpack_encode_empty_array(EncoderState *self) { char header[1] = {MP_FIXARRAY}; return ms_write(self, header, 1); } static MS_NOINLINE int mpack_encode_list(EncoderState *self, PyObject *obj) { Py_ssize_t i, len; int status = 0; len = PyList_GET_SIZE(obj); if (len == 0) return mpack_encode_empty_array(self); if (mpack_encode_array_header(self, len, "list") < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; for (i = 0; i < len; i++) { if (mpack_encode_inline(self, PyList_GET_ITEM(obj, i)) < 0) { status = -1; break; } } Py_LeaveRecursiveCall(); return status; } static int mpack_encode_set(EncoderState *self, PyObject *obj) { Py_ssize_t len = 0; PyObject *item; int status = -1; len = PySet_GET_SIZE(obj); if (len == 0) return mpack_encode_empty_array(self); if (MS_UNLIKELY(self->order != ORDER_DEFAULT)) { PyObject *temp = PySequence_List(obj); if (temp == NULL) return -1; if (PyList_Sort(temp) == 0) { status = mpack_encode_list(self, temp); } Py_DECREF(temp); return status; } if (mpack_encode_array_header(self, len, "set") < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; PyObject *iter = PyObject_GetIter(obj); if (iter == NULL) goto cleanup; while ((item = PyIter_Next(iter))) { if (mpack_encode_inline(self, item) < 0) goto cleanup; } status = 0; cleanup: Py_LeaveRecursiveCall(); Py_XDECREF(iter); return status; } static int mpack_encode_tuple(EncoderState *self, PyObject *obj) { Py_ssize_t i, len; int status = 0; len = PyTuple_GET_SIZE(obj); if (len == 0) return mpack_encode_empty_array(self); if (mpack_encode_array_header(self, len, "tuples") < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; for (i = 0; i < len; i++) { if (mpack_encode_inline(self, PyTuple_GET_ITEM(obj, i)) < 0) { status = -1; break; } } Py_LeaveRecursiveCall(); return status; } static int mpack_encode_map_header(EncoderState *self, Py_ssize_t len, const char* typname) { if (len < 16) { char header[1] = {MP_FIXMAP | len}; if (ms_write(self, header, 1) < 0) return -1; } else if (len < (1 << 16)) { char header[3]; header[0] = MP_MAP16; _msgspec_store16(&header[1], (uint16_t)len); if (ms_write(self, header, 3) < 0) return -1; } else if (len < (1LL << 32)) { char header[5]; header[0] = MP_MAP32; _msgspec_store32(&header[1], (uint32_t)len); if (ms_write(self, header, 5) < 0) return -1; } else { PyErr_Format( self->mod->EncodeError, "Can't encode %s longer than 2**32 - 1", typname ); return -1; } return 0; } static int mpack_encode_and_free_assoclist(EncoderState *self, AssocList *list) { if (list == NULL) return -1; int status = -1; AssocList_Sort(list); if (mpack_encode_map_header(self, list->size, "dicts") < 0) goto cleanup2; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; for (Py_ssize_t i = 0; i < list->size; i++) { AssocItem *item = &(list->items[i]); if (mpack_encode_cstr(self, item->key, item->key_size) < 0) goto cleanup; if (mpack_encode_inline(self, item->val) < 0) goto cleanup; } status = 0; cleanup: Py_LeaveRecursiveCall(); cleanup2: AssocList_Free(list); return status; } static MS_NOINLINE int mpack_encode_dict(EncoderState *self, PyObject *obj) { PyObject *key, *val; Py_ssize_t pos = 0; int status = -1; Py_ssize_t len = PyDict_GET_SIZE(obj); if (MS_UNLIKELY(len == 0)) { char header[1] = {MP_FIXMAP}; return ms_write(self, header, 1); } if (MS_UNLIKELY(self->order != ORDER_DEFAULT)) { return mpack_encode_and_free_assoclist(self, AssocList_FromDict(obj)); } if (mpack_encode_map_header(self, len, "dicts") < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; while (PyDict_Next(obj, &pos, &key, &val)) { if (mpack_encode_dict_key_inline(self, key) < 0) goto cleanup; if (mpack_encode_inline(self, val) < 0) goto cleanup; } status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static int mpack_encode_dataclass(EncoderState *self, PyObject *obj, PyObject *fields) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return mpack_encode_and_free_assoclist(self, AssocList_FromDataclass(obj, fields)); } if (Py_EnterRecursiveCall(" while serializing an object")) return -1; int status = -1; DataclassIter iter; if (!dataclass_iter_setup(&iter, obj, fields)) goto cleanup; /* Cache header offset in case we need to adjust the header after writing */ Py_ssize_t header_offset = self->output_len; Py_ssize_t max_size = PyDict_GET_SIZE(fields); if (mpack_encode_map_header(self, max_size, "objects") < 0) goto cleanup; Py_ssize_t size = 0; PyObject *field, *val; while (dataclass_iter_next(&iter, &field, &val)) { size++; Py_ssize_t field_len; const char* field_buf = unicode_str_and_size(field, &field_len); bool errored = ( (field_buf == NULL) || (mpack_encode_cstr(self, field_buf, field_len) < 0) || (mpack_encode(self, val) < 0) ); Py_DECREF(val); if (errored) goto cleanup; } if (MS_UNLIKELY(size != max_size)) { /* Some fields were skipped, need to adjust header. We write the header * using the width type of `max_size`, but the value of `size`. */ char *header_loc = self->output_buffer_raw + header_offset; if (max_size < 16) { *header_loc = MP_FIXMAP | size; } else if (max_size < (1 << 16)) { *header_loc++ = MP_MAP16; _msgspec_store16(header_loc, (uint16_t)size); } else { *header_loc++ = MP_MAP32; _msgspec_store32(header_loc, (uint32_t)size); } } status = 0; cleanup: Py_LeaveRecursiveCall(); dataclass_iter_cleanup(&iter); return status; } /* This method encodes an object as a map, with fields taken from `__dict__`, * followed by all `__slots__` in the class hierarchy. Any unset slots are * ignored, and `__weakref__` is not included. */ static int mpack_encode_object(EncoderState *self, PyObject *obj) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return mpack_encode_and_free_assoclist(self, AssocList_FromObject(obj)); } int status = -1; Py_ssize_t size = 0, max_size; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; /* Calculate the maximum number of fields that could be part of this object. * This is roughly equal to: * max_size = size = len(getattr(obj, '__dict__', {})) * max_size += sum(len(getattr(c, '__slots__', ())) for c in type(obj).mro()) */ PyObject *dict = PyObject_GenericGetDict(obj, NULL); if (MS_UNLIKELY(dict == NULL)) { PyErr_Clear(); max_size = 0; } else { max_size = PyDict_GET_SIZE(dict); } PyTypeObject *type = Py_TYPE(obj); while (type != NULL) { max_size += Py_SIZE(type); type = type->tp_base; } /* Cache header offset in case we need to adjust the header after writing */ Py_ssize_t header_offset = self->output_len; if (mpack_encode_map_header(self, max_size, "objects") < 0) goto cleanup; /* First encode everything in `__dict__` */ if (dict != NULL) { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(dict, &pos, &key, &val)) { if (MS_LIKELY(PyUnicode_CheckExact(key))) { Py_ssize_t key_len; if (MS_UNLIKELY(val == UNSET)) continue; const char* key_buf = unicode_str_and_size(key, &key_len); if (MS_UNLIKELY(key_buf == NULL)) goto cleanup; if (MS_UNLIKELY(*key_buf == '_')) continue; if (MS_UNLIKELY(mpack_encode_cstr(self, key_buf, key_len) < 0)) goto cleanup; if (MS_UNLIKELY(mpack_encode(self, val) < 0)) goto cleanup; size++; } } } /* Then encode everything in slots */ type = Py_TYPE(obj); while (type != NULL) { Py_ssize_t n = Py_SIZE(type); if (n) { PyMemberDef *mp = MS_PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (Py_ssize_t i = 0; i < n; i++, mp++) { if (MS_LIKELY(mp->type == T_OBJECT_EX && !(mp->flags & READONLY))) { char *addr = (char *)obj + mp->offset; PyObject *val = *(PyObject **)addr; if (MS_UNLIKELY(val == UNSET)) continue; if (MS_UNLIKELY(val == NULL)) continue; if (MS_UNLIKELY(*mp->name == '_')) continue; if (MS_UNLIKELY(mpack_encode_cstr(self, mp->name, strlen(mp->name)) < 0)) goto cleanup; if (MS_UNLIKELY(mpack_encode(self, val) < 0)) goto cleanup; size++; } } } type = type->tp_base; } if (MS_UNLIKELY(size != max_size)) { /* Some fields were NULL, need to adjust header. We write the header * using the width type of `max_size`, but the value of `size`. */ char *header_loc = self->output_buffer_raw + header_offset; if (max_size < 16) { *header_loc = MP_FIXMAP | size; } else if (max_size < (1 << 16)) { *header_loc++ = MP_MAP16; _msgspec_store16(header_loc, (uint16_t)size); } else { *header_loc++ = MP_MAP32; _msgspec_store32(header_loc, (uint32_t)size); } } status = 0; cleanup: Py_XDECREF(dict); Py_LeaveRecursiveCall(); return status; } static int mpack_encode_struct_array( EncoderState *self, StructMetaObject *struct_type, PyObject *obj ) { int status = -1; PyObject *tag_value = struct_type->struct_tag_value; int tagged = tag_value != NULL; PyObject *fields = struct_type->struct_encode_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); Py_ssize_t len = nfields + tagged; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; if (mpack_encode_array_header(self, len, "structs") < 0) goto cleanup; if (tagged) { if (mpack_encode(self, tag_value) < 0) goto cleanup; } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val = Struct_get_index(obj, i); if (val == NULL || mpack_encode(self, val) < 0) goto cleanup; } status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static int mpack_encode_struct_object( EncoderState *self, StructMetaObject *struct_type, PyObject *obj ) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return mpack_encode_and_free_assoclist(self, AssocList_FromStruct(obj)); } int status = -1; PyObject *tag_field = struct_type->struct_tag_field; PyObject *tag_value = struct_type->struct_tag_value; int tagged = tag_value != NULL; PyObject *fields = struct_type->struct_encode_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); Py_ssize_t len = nfields + tagged; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; Py_ssize_t header_offset = self->output_len; if (mpack_encode_map_header(self, len, "structs") < 0) goto cleanup; if (tagged) { if (mpack_encode_str(self, tag_field) < 0) goto cleanup; if (mpack_encode(self, tag_value) < 0) goto cleanup; } Py_ssize_t nunchecked = nfields, actual_len = len; if (struct_type->omit_defaults == OPT_TRUE) { nunchecked -= PyTuple_GET_SIZE(struct_type->struct_defaults); } for (Py_ssize_t i = 0; i < nunchecked; i++) { PyObject *key = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(obj, i); if (MS_UNLIKELY(val == NULL)) goto cleanup; if (MS_UNLIKELY(val == UNSET)) { actual_len--; } else { if (mpack_encode_str(self, key) < 0) goto cleanup; if (mpack_encode(self, val) < 0) goto cleanup; } } for (Py_ssize_t i = nunchecked; i < nfields; i++) { PyObject *key = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(obj, i); if (val == NULL) goto cleanup; PyObject *default_val = PyTuple_GET_ITEM( struct_type->struct_defaults, i - nunchecked ); if (val == UNSET || is_default(val, default_val)) { actual_len--; } else { if (mpack_encode_str(self, key) < 0) goto cleanup; if (mpack_encode(self, val) < 0) goto cleanup; } } if (MS_UNLIKELY(actual_len != len)) { /* Fixup the header length after we know how many fields were * actually written */ char *header_loc = self->output_buffer_raw + header_offset; if (len < 16) { *header_loc = MP_FIXMAP | actual_len; } else if (len < (1 << 16)) { *header_loc++ = MP_MAP16; _msgspec_store16(header_loc, (uint16_t)actual_len); } else { *header_loc++ = MP_MAP32; _msgspec_store32(header_loc, (uint32_t)actual_len); } } status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static int mpack_encode_struct(EncoderState *self, PyObject *obj) { StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); if (struct_type->array_like == OPT_TRUE) { return mpack_encode_struct_array(self, struct_type, obj); } return mpack_encode_struct_object(self, struct_type, obj); } static int mpack_encode_ext(EncoderState *self, PyObject *obj) { Ext *ex = (Ext *)obj; Py_ssize_t len; int status = -1, header_len = 2; char header[6]; const char* data; Py_buffer buffer; buffer.buf = NULL; if (PyBytes_CheckExact(ex->data)) { len = PyBytes_GET_SIZE(ex->data); data = PyBytes_AS_STRING(ex->data); } else if (PyByteArray_CheckExact(ex->data)) { len = PyByteArray_GET_SIZE(ex->data); data = PyByteArray_AS_STRING(ex->data); } else { if (PyObject_GetBuffer(ex->data, &buffer, PyBUF_CONTIG_RO) < 0) return -1; len = buffer.len; data = buffer.buf; } if (len == 1) { header[0] = MP_FIXEXT1; header[1] = ex->code; } else if (len == 2) { header[0] = MP_FIXEXT2; header[1] = ex->code; } else if (len == 4) { header[0] = MP_FIXEXT4; header[1] = ex->code; } else if (len == 8) { header[0] = MP_FIXEXT8; header[1] = ex->code; } else if (len == 16) { header[0] = MP_FIXEXT16; header[1] = ex->code; } else if (len < (1<<8)) { header[0] = MP_EXT8; header[1] = len; header[2] = ex->code; header_len = 3; } else if (len < (1<<16)) { header[0] = MP_EXT16; _msgspec_store16(&header[1], (uint16_t)len); header[3] = ex->code; header_len = 4; } else if (len < (1LL<<32)) { header[0] = MP_EXT32; _msgspec_store32(&header[1], (uint32_t)len); header[5] = ex->code; header_len = 6; } else { PyErr_SetString( self->mod->EncodeError, "Can't encode Ext objects with data longer than 2**32 - 1" ); goto done; } if (ms_write(self, header, header_len) < 0) goto done; status = len > 0 ? ms_write(self, data, len) : 0; done: if (buffer.buf != NULL) PyBuffer_Release(&buffer); return status; } static int mpack_encode_enum(EncoderState *self, PyObject *obj) { if (PyLong_Check(obj)) return mpack_encode_long(self, obj); if (PyUnicode_Check(obj)) return mpack_encode_str(self, obj); PyObject *value = PyObject_GetAttr(obj, self->mod->str__value_); if (value == NULL) return -1; int status = mpack_encode(self, value); Py_DECREF(value); return status; } static int mpack_encode_uuid(EncoderState *self, PyObject *obj) { char buf[36]; if (MS_UNLIKELY(self->uuid_format == UUID_FORMAT_BYTES)) { if (ms_uuid_to_16_bytes(self->mod, obj, (unsigned char *)buf) < 0) return -1; return mpack_encode_bin(self, buf, 16); } bool canonical = self->uuid_format == UUID_FORMAT_CANONICAL; if (ms_encode_uuid(self->mod, obj, buf, canonical) < 0) return -1; return mpack_encode_cstr(self, buf, canonical ? 36 : 32); } static int mpack_encode_decimal(EncoderState *self, PyObject *obj) { PyObject *temp; int out; if (MS_LIKELY(self->decimal_format == DECIMAL_FORMAT_STRING)) { temp = PyObject_Str(obj); if (temp == NULL) return -1; out = mpack_encode_str(self, temp); } else { temp = PyNumber_Float(obj); if (temp == NULL) return -1; out = mpack_encode_float(self, temp); } Py_DECREF(temp); return out; } static int mpack_encode_date(EncoderState *self, PyObject *obj) { char buf[10]; ms_encode_date(obj, buf); return mpack_encode_cstr(self, buf, 10); } static int mpack_encode_time(EncoderState *self, PyObject *obj) { char buf[21]; int size = ms_encode_time(self->mod, obj, buf); if (size < 0) return -1; return mpack_encode_cstr(self, buf, size); } static int mpack_encode_timedelta(EncoderState *self, PyObject *obj) { char buf[26]; int size = ms_encode_timedelta(obj, buf); return mpack_encode_cstr(self, buf, size); } static int mpack_encode_datetime(EncoderState *self, PyObject *obj) { int64_t seconds; int32_t nanoseconds; PyObject *tzinfo = MS_DATE_GET_TZINFO(obj); if (tzinfo == Py_None) { char buf[32]; int size = ms_encode_datetime(self->mod, obj, buf); if (size < 0) return -1; return mpack_encode_cstr(self, buf, size); } if (tzinfo == PyDateTime_TimeZone_UTC) { datetime_to_epoch(obj, &seconds, &nanoseconds); } else { PyObject *temp = PyObject_CallFunctionObjArgs( self->mod->astimezone, obj, PyDateTime_TimeZone_UTC, NULL ); if (temp == NULL) return -1; datetime_to_epoch(temp, &seconds, &nanoseconds); Py_DECREF(temp); } if ((seconds >> 34) == 0) { uint64_t data64 = ((uint64_t)nanoseconds << 34) | (uint64_t)seconds; if ((data64 & 0xffffffff00000000L) == 0) { /* timestamp 32 */ char buf[6]; buf[0] = MP_FIXEXT4; buf[1] = -1; uint32_t data32 = (uint32_t)data64; _msgspec_store32(&buf[2], data32); if (ms_write(self, buf, 6) < 0) return -1; } else { /* timestamp 64 */ char buf[10]; buf[0] = MP_FIXEXT8; buf[1] = -1; _msgspec_store64(&buf[2], data64); if (ms_write(self, buf, 10) < 0) return -1; } } else { /* timestamp 96 */ char buf[15]; buf[0] = MP_EXT8; buf[1] = 12; buf[2] = -1; _msgspec_store32(&buf[3], nanoseconds); _msgspec_store64(&buf[7], seconds); if (ms_write(self, buf, 15) < 0) return -1; } return 0; } static MS_NOINLINE int mpack_encode_uncommon(EncoderState *self, PyTypeObject *type, PyObject *obj) { if (obj == Py_None) { return mpack_encode_none(self); } else if (type == &PyBool_Type) { return mpack_encode_bool(self, obj); } else if (Py_TYPE(type) == &StructMetaType) { return mpack_encode_struct(self, obj); } else if (type == &PyBytes_Type) { return mpack_encode_bytes(self, obj); } else if (type == &PyByteArray_Type) { return mpack_encode_bytearray(self, obj); } else if (type == &PyMemoryView_Type) { return mpack_encode_memoryview(self, obj); } else if (PyTuple_Check(obj)) { return mpack_encode_tuple(self, obj); } else if (type == PyDateTimeAPI->DateTimeType) { return mpack_encode_datetime(self, obj); } else if (type == PyDateTimeAPI->DateType) { return mpack_encode_date(self, obj); } else if (type == PyDateTimeAPI->TimeType) { return mpack_encode_time(self, obj); } else if (type == PyDateTimeAPI->DeltaType) { return mpack_encode_timedelta(self, obj); } else if (type == &Ext_Type) { return mpack_encode_ext(self, obj); } else if (type == &Raw_Type) { return mpack_encode_raw(self, obj); } else if (Py_TYPE(type) == self->mod->EnumMetaType) { return mpack_encode_enum(self, obj); } else if (type == (PyTypeObject *)(self->mod->DecimalType)) { return mpack_encode_decimal(self, obj); } else if (PyType_IsSubtype(type, (PyTypeObject *)(self->mod->UUIDType))) { return mpack_encode_uuid(self, obj); } else if (PyAnySet_Check(obj)) { return mpack_encode_set(self, obj); } else if (!PyType_Check(obj) && type->tp_dict != NULL) { PyObject *fields = PyObject_GetAttr(obj, self->mod->str___dataclass_fields__); if (fields != NULL) { int status = mpack_encode_dataclass(self, obj, fields); Py_DECREF(fields); return status; } else { PyErr_Clear(); } if (PyDict_Contains(type->tp_dict, self->mod->str___attrs_attrs__)) { return mpack_encode_object(self, obj); } } if (self->enc_hook != NULL) { int status = -1; PyObject *temp; temp = PyObject_CallOneArg(self->enc_hook, obj); if (temp == NULL) return -1; if (!Py_EnterRecursiveCall(" while serializing an object")) { status = mpack_encode(self, temp); Py_LeaveRecursiveCall(); } Py_DECREF(temp); return status; } return ms_encode_err_type_unsupported(type); } static MS_INLINE int mpack_encode_inline(EncoderState *self, PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (type == &PyUnicode_Type) { return mpack_encode_str(self, obj); } else if (type == &PyLong_Type) { return mpack_encode_long(self, obj); } else if (type == &PyFloat_Type) { return mpack_encode_float(self, obj); } else if (PyList_Check(obj)) { return mpack_encode_list(self, obj); } else if (PyDict_Check(obj)) { return mpack_encode_dict(self, obj); } else { return mpack_encode_uncommon(self, type, obj); } } static MS_INLINE int mpack_encode_dict_key_inline(EncoderState *self, PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (PyUnicode_Check(obj)) { return mpack_encode_str(self, obj); } else if (type == &PyLong_Type) { return mpack_encode_long(self, obj); } else if (type == &PyFloat_Type) { return mpack_encode_float(self, obj); } else if (PyList_Check(obj)) { return mpack_encode_list(self, obj); } else if (PyDict_Check(obj)) { return mpack_encode_dict(self, obj); } else { return mpack_encode_uncommon(self, type, obj); } } static int mpack_encode(EncoderState *self, PyObject *obj) { return mpack_encode_inline(self, obj); } static PyObject* Encoder_encode_into(Encoder *self, PyObject *const *args, Py_ssize_t nargs) { return encoder_encode_into_common(self, args, nargs, &mpack_encode); } static PyObject* Encoder_encode(Encoder *self, PyObject *const *args, Py_ssize_t nargs) { return encoder_encode_common(self, args, nargs, &mpack_encode); } static struct PyMethodDef Encoder_methods[] = { { "encode", (PyCFunction) Encoder_encode, METH_FASTCALL, Encoder_encode__doc__, }, { "encode_into", (PyCFunction) Encoder_encode_into, METH_FASTCALL, Encoder_encode_into__doc__, }, {NULL, NULL} /* sentinel */ }; static PyTypeObject Encoder_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.msgpack.Encoder", .tp_doc = Encoder__doc__, .tp_basicsize = sizeof(Encoder), .tp_dealloc = (destructor)Encoder_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_traverse = (traverseproc)Encoder_traverse, .tp_clear = (inquiry)Encoder_clear, .tp_new = PyType_GenericNew, .tp_init = (initproc)Encoder_init, .tp_methods = Encoder_methods, .tp_members = Encoder_members, .tp_getset = Encoder_getset, }; PyDoc_STRVAR(msgspec_msgpack_encode__doc__, "msgpack_encode(obj, *, enc_hook=None, order=None)\n" "--\n" "\n" "Serialize an object as MessagePack.\n" "\n" "Parameters\n" "----------\n" "obj : Any\n" " The object to serialize.\n" "enc_hook : callable, optional\n" " A callable to call for objects that aren't supported msgspec types. Takes\n" " the unsupported object and should return a supported object, or raise a\n" " ``NotImplementedError`` if unsupported.\n" "order : {None, 'deterministic', 'sorted'}, optional\n" " The ordering to use when encoding unordered compound types.\n" "\n" " - ``None``: All objects are encoded in the most efficient manner matching\n" " their in-memory representations. The default.\n" " - `'deterministic'`: Unordered collections (sets, dicts) are sorted to\n" " ensure a consistent output between runs. Useful when comparison/hashing\n" " of the encoded binary output is necessary.\n" " - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs,\n" " dataclasses, ...) are also sorted by field name before encoding. This is\n" " slower than `'deterministic'`, but may produce more human-readable output.\n" "\n" "Returns\n" "-------\n" "data : bytes\n" " The serialized object.\n" "\n" "See Also\n" "--------\n" "Encoder.encode" ); static PyObject* msgspec_msgpack_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { return encode_common(self, args, nargs, kwnames, &mpack_encode); } /************************************************************************* * JSON Encoder * *************************************************************************/ PyDoc_STRVAR(JSONEncoder__doc__, "Encoder(*, enc_hook=None, decimal_format='string', uuid_format='canonical', order=None)\n" "--\n" "\n" "A JSON encoder.\n" "\n" "Parameters\n" "----------\n" "enc_hook : callable, optional\n" " A callable to call for objects that aren't supported msgspec types. Takes\n" " the unsupported object and should return a supported object, or raise a\n" " ``NotImplementedError`` if unsupported.\n" "decimal_format : {'string', 'number'}, optional\n" " The format to use for encoding `decimal.Decimal` objects. If 'string'\n" " they're encoded as strings, if 'number', they're encoded as floats.\n" " Defaults to 'string', which is the recommended value since 'number'\n" " may result in precision loss when decoding for some JSON library\n" " implementations.\n" "uuid_format : {'canonical', 'hex'}, optional\n" " The format to use for encoding `uuid.UUID` objects. The 'canonical'\n" " and 'hex' formats encode them as strings with and without hyphens\n" " respectively. Defaults to 'canonical'.\n" "order : {None, 'deterministic', 'sorted'}, optional\n" " The ordering to use when encoding unordered compound types.\n" "\n" " - ``None``: All objects are encoded in the most efficient manner matching\n" " their in-memory representations. The default.\n" " - `'deterministic'`: Unordered collections (sets, dicts) are sorted to\n" " ensure a consistent output between runs. Useful when comparison/hashing\n" " of the encoded binary output is necessary.\n" " - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs,\n" " dataclasses, ...) are also sorted by field name before encoding. This is\n" " slower than `'deterministic'`, but may produce more human-readable output." ); static int json_encode_inline(EncoderState*, PyObject*); static int json_encode(EncoderState*, PyObject*); static MS_NOINLINE int json_encode_long_fallback(EncoderState *self, PyObject *obj) { int out = -1; PyObject *encoded = PyLong_Type.tp_repr(obj); if (MS_LIKELY(encoded != NULL)) { Py_ssize_t len; const char* buf = unicode_str_and_size(encoded, &len); if (MS_LIKELY(buf != NULL)) { out = ms_write(self, buf, len); } Py_DECREF(encoded); } return out; } static MS_NOINLINE int json_encode_long(EncoderState *self, PyObject *obj) { uint64_t x; bool neg, overflow; overflow = fast_long_extract_parts(obj, &neg, &x); if (MS_UNLIKELY(overflow)) { return json_encode_long_fallback(self, obj); } if (ms_ensure_space(self, 20) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; if (neg) { *p++ = '-'; } self->output_len = write_u64(x, p) - self->output_buffer_raw; return 0; } static int json_encode_long_as_str(EncoderState *self, PyObject *obj) { if (ms_write(self, "\"", 1) < 0) return -1; if (json_encode_long(self, obj) < 0) return -1; return ms_write(self, "\"", 1); } static MS_NOINLINE int json_encode_float(EncoderState *self, PyObject *obj) { double x = PyFloat_AS_DOUBLE(obj); if (ms_ensure_space(self, 24) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; self->output_len += write_f64(x, p, false); return 0; } static MS_NOINLINE int json_encode_float_as_str(EncoderState *self, PyObject *obj) { double x = PyFloat_AS_DOUBLE(obj); if (ms_ensure_space(self, 26) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p = '"'; int n = write_f64(x, p + 1, true); *(p + 1 + n) = '"'; self->output_len += n + 2; return 0; } /* A table of escape characters to use for each byte (0 if no escape needed) */ static const char escape_table[256] = { 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\\', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static int json_str_requires_escaping(PyObject *obj) { Py_ssize_t i, len; const char* buf = unicode_str_and_size(obj, &len); if (buf == NULL) return -1; for (i = 0; i < len; i++) { char escape = escape_table[(uint8_t)buf[i]]; if (escape != 0) { return 1; } } return 0; } static MS_INLINE int json_encode_cstr_inline(EncoderState *self, const char *src, Py_ssize_t len) { const char* src_end = src + len; if (ms_ensure_space(self, len + 2) < 0) return -1; char *out = self->output_buffer_raw + self->output_len; char *out_end = self->output_buffer_raw + self->max_output_len; *out++ = '"'; noescape: #define write_ascii_pre(i) \ if (MS_UNLIKELY(escape_table[(uint8_t)src[i]])) goto write_ascii_##i; #define write_ascii_post(i) \ write_ascii_##i: \ memcpy(out, src, i); \ out += i; \ src += i; \ goto escape; while (src_end - src >= 8) { repeat8(write_ascii_pre); memcpy(out, src, 8); out += 8; src += 8; } while (MS_LIKELY(src_end > src)) { write_ascii_pre(0); *out++ = *src++; } *out++ = '"'; self->output_len = out - self->output_buffer_raw; return 0; repeat8(write_ascii_post); escape: { char c = *src++; char escape = escape_table[(uint8_t)c]; /* Ensure enough space for the escape, final quote, and any remaining characters */ Py_ssize_t remaining = 7 + src_end - src; if (MS_UNLIKELY(remaining > out_end - out)) { Py_ssize_t output_len = out - self->output_buffer_raw; if (MS_UNLIKELY(ms_resize(self, remaining + output_len) < 0)) return -1; out = self->output_buffer_raw + output_len; out_end = self->output_buffer_raw + self->max_output_len; } /* Write the escaped character */ char escaped[6] = {'\\', escape, '0', '0'}; if (MS_UNLIKELY(escape == 'u')) { escaped[4] = hex_encode_table[c >> 4]; escaped[5] = hex_encode_table[c & 0xF]; memcpy(out, escaped, 6); out += 6; } else { memcpy(out, escaped, 2); out += 2; } goto noescape; } } static int json_encode_cstr(EncoderState *self, const char *src, Py_ssize_t len) { return json_encode_cstr_inline(self, src, len); } static MS_NOINLINE int json_encode_str(EncoderState *self, PyObject *obj) { Py_ssize_t len; const char* buf = unicode_str_and_size(obj, &len); if (buf == NULL) return -1; return json_encode_cstr_inline(self, buf, len); } static MS_INLINE int json_encode_cstr_noescape(EncoderState *self, const char *str, Py_ssize_t size) { if (ms_ensure_space(self, size + 2) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p++ = '"'; memcpy(p, str, size); *(p + size) = '"'; self->output_len += size + 2; return 0; } static inline int json_encode_str_noescape(EncoderState *self, PyObject *obj) { Py_ssize_t len; const char* buf = unicode_str_and_size_nocheck(obj, &len); return json_encode_cstr_noescape(self, buf, len); } static int json_encode_bin(EncoderState *self, const char* buf, Py_ssize_t len) { /* Preallocate the buffer (ceil(4/3 * len) + 2) */ Py_ssize_t encoded_len = ms_encode_base64_size(self->mod, len); if (encoded_len < 0) return -1; if (ms_ensure_space(self, encoded_len + 2) < 0) return -1; /* Write to the buffer directly */ char *out = self->output_buffer_raw + self->output_len; *out++ = '"'; ms_encode_base64(buf, len, out); out += encoded_len; *out++ = '"'; self->output_len += encoded_len + 2; return 0; } static int json_encode_bytes(EncoderState *self, PyObject *obj) { Py_ssize_t len = PyBytes_GET_SIZE(obj); const char* buf = PyBytes_AS_STRING(obj); return json_encode_bin(self, buf, len); } static int json_encode_bytearray(EncoderState *self, PyObject *obj) { Py_ssize_t len = PyByteArray_GET_SIZE(obj); const char* buf = PyByteArray_AS_STRING(obj); return json_encode_bin(self, buf, len); } static int json_encode_memoryview(EncoderState *self, PyObject *obj) { int out; Py_buffer buffer; if (PyObject_GetBuffer(obj, &buffer, PyBUF_CONTIG_RO) < 0) return -1; out = json_encode_bin(self, buffer.buf, buffer.len); PyBuffer_Release(&buffer); return out; } static int json_encode_raw(EncoderState *self, PyObject *obj) { Raw *raw = (Raw *)obj; return ms_write(self, raw->buf, raw->len); } static int json_encode_dict_key_noinline(EncoderState *, PyObject *); static int json_encode_enum(EncoderState *self, PyObject *obj, bool is_key) { if (PyLong_Check(obj)) { return is_key ? json_encode_long_as_str(self, obj) : json_encode_long(self, obj); } if (PyUnicode_Check(obj)) { return json_encode_str(self, obj); } PyObject *value = PyObject_GetAttr(obj, self->mod->str__value_); if (value == NULL) return -1; int status = ( is_key ? json_encode_dict_key_noinline(self, value) : json_encode(self, value) ); Py_DECREF(value); return status; } static int json_encode_uuid(EncoderState *self, PyObject *obj) { char buf[38]; buf[0] = '"'; bool canonical = self->uuid_format == UUID_FORMAT_CANONICAL; if (ms_encode_uuid(self->mod, obj, buf + 1, canonical) < 0) return -1; int size = canonical ? 36 : 32; buf[size + 1] = '"'; return ms_write(self, buf, size + 2); } static int json_encode_decimal(EncoderState *self, PyObject *obj) { PyObject *temp = PyObject_Str(obj); if (temp == NULL) return -1; Py_ssize_t size; const char* buf = unicode_str_and_size_nocheck(temp, &size); bool decimal_as_string = (self->decimal_format == DECIMAL_FORMAT_STRING); Py_ssize_t required = size + (2 * decimal_as_string); if (ms_ensure_space(self, size + 2) < 0) { Py_DECREF(temp); return -1; } char *p = self->output_buffer_raw + self->output_len; if (MS_LIKELY(decimal_as_string)) *p++ = '"'; memcpy(p, buf, size); if (MS_LIKELY(decimal_as_string)) *(p + size) = '"'; self->output_len += required; Py_DECREF(temp); return 0; } static int json_encode_date(EncoderState *self, PyObject *obj) { if (ms_ensure_space(self, 12) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p = '"'; ms_encode_date(obj, p + 1); *(p + 11) = '"'; self->output_len += 12; return 0; } static int json_encode_time(EncoderState *self, PyObject *obj) { if (ms_ensure_space(self, 23) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p = '"'; int size = ms_encode_time(self->mod, obj, p + 1); if (size < 0) return -1; *(p + size + 1) = '"'; self->output_len += (size + 2); return 0; } static int json_encode_datetime(EncoderState *self, PyObject *obj) { if (ms_ensure_space(self, 34) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p = '"'; int size = ms_encode_datetime(self->mod, obj, p + 1); if (size < 0) return -1; *(p + size + 1) = '"'; self->output_len += (size + 2); return 0; } static int json_encode_timedelta(EncoderState *self, PyObject *obj) { char buf[28]; buf[0] = '"'; int n = ms_encode_timedelta(obj, buf + 1); buf[1 + n] = '"'; return ms_write(self, buf, 2 + n); } static MS_INLINE int json_encode_sequence(EncoderState *self, Py_ssize_t size, PyObject **arr) { int status = -1; if (size == 0) return ms_write(self, "[]", 2); if (ms_write(self, "[", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; for (Py_ssize_t i = 0; i < size; i++) { if (json_encode_inline(self, *(arr + i)) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } /* Overwrite trailing comma with ] */ *(self->output_buffer_raw + self->output_len - 1) = ']'; status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static MS_NOINLINE int json_encode_list(EncoderState *self, PyObject *obj) { return json_encode_sequence( self, PyList_GET_SIZE(obj), ((PyListObject *)obj)->ob_item ); } static MS_NOINLINE int json_encode_tuple(EncoderState *self, PyObject *obj) { return json_encode_sequence( self, PyTuple_GET_SIZE(obj), ((PyTupleObject *)obj)->ob_item ); } static int json_encode_set(EncoderState *self, PyObject *obj) { Py_ssize_t len = 0; PyObject *item; int status = -1; len = PySet_GET_SIZE(obj); if (len == 0) return ms_write(self, "[]", 2); if (MS_UNLIKELY(self->order != ORDER_DEFAULT)) { PyObject *temp = PySequence_List(obj); if (temp == NULL) return -1; if (PyList_Sort(temp) == 0) { status = json_encode_list(self, temp); } Py_DECREF(temp); return status; } if (ms_write(self, "[", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; PyObject *iter = PyObject_GetIter(obj); if (iter == NULL) goto cleanup; while ((item = PyIter_Next(iter))) { if (json_encode_inline(self, item) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } /* Overwrite trailing comma with ] */ *(self->output_buffer_raw + self->output_len - 1) = ']'; status = 0; cleanup: Py_LeaveRecursiveCall(); Py_XDECREF(iter); return status; } static MS_INLINE int json_encode_dict_key(EncoderState *self, PyObject *key) { if (MS_LIKELY(PyUnicode_Check(key))) { return json_encode_str(self, key); } return json_encode_dict_key_noinline(self, key); } static MS_NOINLINE int json_encode_dict_key_noinline(EncoderState *self, PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (type == &PyLong_Type) { return json_encode_long_as_str(self, obj); } else if (type == &PyFloat_Type) { return json_encode_float_as_str(self, obj); } else if (Py_TYPE(type) == self->mod->EnumMetaType) { return json_encode_enum(self, obj, true); } else if (type == PyDateTimeAPI->DateTimeType) { return json_encode_datetime(self, obj); } else if (type == PyDateTimeAPI->DateType) { return json_encode_date(self, obj); } else if (type == PyDateTimeAPI->TimeType) { return json_encode_time(self, obj); } else if (type == PyDateTimeAPI->DeltaType) { return json_encode_timedelta(self, obj); } else if (type == &PyBytes_Type) { return json_encode_bytes(self, obj); } else if (type == (PyTypeObject *)(self->mod->DecimalType)) { return json_encode_decimal(self, obj); } else if (PyType_IsSubtype(type, (PyTypeObject *)(self->mod->UUIDType))) { return json_encode_uuid(self, obj); } else if (self->enc_hook != NULL) { int status = -1; PyObject *temp; temp = PyObject_CallOneArg(self->enc_hook, obj); if (temp == NULL) return -1; if (!Py_EnterRecursiveCall(" while serializing an object")) { status = json_encode_dict_key(self, temp); Py_LeaveRecursiveCall(); } Py_DECREF(temp); return status; } else { PyErr_SetString( PyExc_TypeError, "Only dicts with str-like or number-like keys are supported" ); return -1; } } static int json_encode_and_free_assoclist(EncoderState *self, AssocList *list, bool escape) { if (list == NULL) return -1; int status = -1; AssocList_Sort(list); if (Py_EnterRecursiveCall(" while serializing an object")) goto cleanup2; if (ms_write(self, "{", 1) < 0) goto cleanup; Py_ssize_t start_len = self->output_len; if (escape) { for (Py_ssize_t i = 0; i < list->size; i++) { AssocItem *item = &(list->items[i]); if (json_encode_cstr(self, item->key, item->key_size) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode_inline(self, item->val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } } else { for (Py_ssize_t i = 0; i < list->size; i++) { AssocItem *item = &(list->items[i]); if (json_encode_cstr_noescape(self, item->key, item->key_size) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode_inline(self, item->val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } } if (MS_UNLIKELY(start_len == self->output_len)) { /* Empty, append "}" */ if (ms_write(self, "}", 1) < 0) goto cleanup; } else { /* Overwrite trailing comma with } */ *(self->output_buffer_raw + self->output_len - 1) = '}'; } status = 0; cleanup: Py_LeaveRecursiveCall(); cleanup2: AssocList_Free(list); return status; } static MS_NOINLINE int json_encode_dict(EncoderState *self, PyObject *obj) { PyObject *key, *val; Py_ssize_t len, pos = 0; int status = -1; len = PyDict_GET_SIZE(obj); if (len == 0) return ms_write(self, "{}", 2); if (MS_UNLIKELY(self->order != ORDER_DEFAULT)) { return json_encode_and_free_assoclist(self, AssocList_FromDict(obj), true); } if (ms_write(self, "{", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; while (PyDict_Next(obj, &pos, &key, &val)) { if (json_encode_dict_key(self, key) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode_inline(self, val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } /* Overwrite trailing comma with } */ *(self->output_buffer_raw + self->output_len - 1) = '}'; status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static int json_encode_dataclass(EncoderState *self, PyObject *obj, PyObject *fields) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return json_encode_and_free_assoclist( self, AssocList_FromDataclass(obj, fields), false ); } if (Py_EnterRecursiveCall(" while serializing an object")) return -1; int status = -1; DataclassIter iter; if (!dataclass_iter_setup(&iter, obj, fields)) goto cleanup; if (ms_write(self, "{", 1) < 0) goto cleanup; Py_ssize_t start_offset = self->output_len; PyObject *field, *val; while (dataclass_iter_next(&iter, &field, &val)) { Py_ssize_t field_len; const char* field_buf = unicode_str_and_size(field, &field_len); bool errored = ( (field_buf == NULL) || (json_encode_cstr_noescape(self, field_buf, field_len) < 0) || (ms_write(self, ":", 1) < 0) || (json_encode(self, val) < 0) || (ms_write(self, ",", 1) < 0) ); Py_DECREF(val); if (errored) goto cleanup; } /* If any fields written, overwrite trailing comma with }, otherwise append } */ if (MS_LIKELY(self->output_len != start_offset)) { *(self->output_buffer_raw + self->output_len - 1) = '}'; status = 0; } else { status = ms_write(self, "}", 1); } cleanup: Py_LeaveRecursiveCall(); dataclass_iter_cleanup(&iter); return status; } /* This method encodes an object as a map, with fields taken from `__dict__`, * followed by all `__slots__` in the class hierarchy. Any unset slots are * ignored, and `__weakref__` is not included. */ static int json_encode_object(EncoderState *self, PyObject *obj) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return json_encode_and_free_assoclist(self, AssocList_FromObject(obj), false); } int status = -1; if (ms_write(self, "{", 1) < 0) return -1; Py_ssize_t start_offset = self->output_len; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; /* First encode everything in `__dict__` */ PyObject *dict = PyObject_GenericGetDict(obj, NULL); if (MS_UNLIKELY(dict == NULL)) { PyErr_Clear(); } else { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(dict, &pos, &key, &val)) { if (MS_LIKELY(PyUnicode_CheckExact(key))) { Py_ssize_t key_len; const char* key_buf = unicode_str_and_size(key, &key_len); if (MS_UNLIKELY(val == UNSET)) continue; if (MS_UNLIKELY(key_buf == NULL)) goto cleanup; if (MS_UNLIKELY(*key_buf == '_')) continue; if (MS_UNLIKELY(json_encode_cstr_noescape(self, key_buf, key_len) < 0)) goto cleanup; if (MS_UNLIKELY(ms_write(self, ":", 1) < 0)) goto cleanup; if (MS_UNLIKELY(json_encode(self, val) < 0)) goto cleanup; if (MS_UNLIKELY(ms_write(self, ",", 1) < 0)) goto cleanup; } } } /* Then encode everything in slots */ PyTypeObject *type = Py_TYPE(obj); while (type != NULL) { Py_ssize_t n = Py_SIZE(type); if (n) { PyMemberDef *mp = MS_PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (Py_ssize_t i = 0; i < n; i++, mp++) { if (MS_LIKELY(mp->type == T_OBJECT_EX && !(mp->flags & READONLY))) { char *addr = (char *)obj + mp->offset; PyObject *val = *(PyObject **)addr; if (MS_UNLIKELY(val == NULL)) continue; if (MS_UNLIKELY(val == UNSET)) continue; if (MS_UNLIKELY(*mp->name == '_')) continue; if (MS_UNLIKELY(json_encode_cstr_noescape(self, mp->name, strlen(mp->name)) < 0)) goto cleanup; if (MS_UNLIKELY(ms_write(self, ":", 1) < 0)) goto cleanup; if (MS_UNLIKELY(json_encode(self, val) < 0)) goto cleanup; if (MS_UNLIKELY(ms_write(self, ",", 1) < 0)) goto cleanup; } } } type = type->tp_base; } /* If any fields written, overwrite trailing comma with }, otherwise append } */ if (MS_LIKELY(self->output_len != start_offset)) { *(self->output_buffer_raw + self->output_len - 1) = '}'; status = 0; } else { status = ms_write(self, "}", 1); } cleanup: Py_XDECREF(dict); Py_LeaveRecursiveCall(); return status; } static int json_encode_struct_tag(EncoderState *self, PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (type == &PyUnicode_Type) { return json_encode_str(self, obj); } else { return json_encode_long(self, obj); } } static int json_encode_struct_object( EncoderState *self, StructMetaObject *struct_type, PyObject *obj ) { if (MS_UNLIKELY(self->order == ORDER_SORTED)) { return json_encode_and_free_assoclist(self, AssocList_FromStruct(obj), false); } PyObject *key, *val, *fields, *defaults, *tag_field, *tag_value; Py_ssize_t i, nfields, nunchecked; int status = -1; tag_field = struct_type->struct_tag_field; tag_value = struct_type->struct_tag_value; fields = struct_type->struct_encode_fields; defaults = struct_type->struct_defaults; nfields = PyTuple_GET_SIZE(fields); nunchecked = nfields; if (struct_type->omit_defaults == OPT_TRUE) { nunchecked -= PyTuple_GET_SIZE(defaults); } if (ms_write(self, "{", 1) < 0) return -1; Py_ssize_t start_len = self->output_len; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; if (tag_value != NULL) { if (json_encode_str(self, tag_field) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode_struct_tag(self, tag_value) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } for (i = 0; i < nunchecked; i++) { key = PyTuple_GET_ITEM(fields, i); val = Struct_get_index(obj, i); if (MS_UNLIKELY(val == NULL)) goto cleanup; if (MS_UNLIKELY(val == UNSET)) continue; if (json_encode_str_noescape(self, key) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode(self, val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } for (i = nunchecked; i < nfields; i++) { key = PyTuple_GET_ITEM(fields, i); val = Struct_get_index(obj, i); if (MS_UNLIKELY(val == NULL)) goto cleanup; if (MS_UNLIKELY(val == UNSET)) continue; PyObject *default_val = PyTuple_GET_ITEM(defaults, i - nunchecked); if (!is_default(val, default_val)) { if (json_encode_str_noescape(self, key) < 0) goto cleanup; if (ms_write(self, ":", 1) < 0) goto cleanup; if (json_encode(self, val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } } if (MS_UNLIKELY(start_len == self->output_len)) { /* Empty struct, append "}" */ if (ms_write(self, "}", 1) < 0) goto cleanup; } else { /* Overwrite trailing comma with } */ *(self->output_buffer_raw + self->output_len - 1) = '}'; } status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static int json_encode_struct_array( EncoderState *self, StructMetaObject *struct_type, PyObject *obj ) { int status = -1; PyObject *tag_value = struct_type->struct_tag_value; PyObject *fields = struct_type->struct_encode_fields; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); if (nfields == 0 && tag_value == NULL) return ms_write(self, "[]", 2); if (ms_write(self, "[", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while serializing an object")) return -1; if (tag_value != NULL) { if (json_encode_struct_tag(self, tag_value) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val = Struct_get_index(obj, i); if (val == NULL) goto cleanup; if (json_encode(self, val) < 0) goto cleanup; if (ms_write(self, ",", 1) < 0) goto cleanup; } /* Overwrite trailing comma with ] */ *(self->output_buffer_raw + self->output_len - 1) = ']'; status = 0; cleanup: Py_LeaveRecursiveCall(); return status; } static int json_encode_struct(EncoderState *self, PyObject *obj) { StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); if (struct_type->array_like == OPT_TRUE) { return json_encode_struct_array(self, struct_type, obj); } return json_encode_struct_object(self, struct_type, obj); } static MS_NOINLINE int json_encode_uncommon(EncoderState *self, PyTypeObject *type, PyObject *obj) { if (obj == Py_None) { return ms_write(self, "null", 4); } else if (obj == Py_True) { return ms_write(self, "true", 4); } else if (obj == Py_False) { return ms_write(self, "false", 5); } else if (Py_TYPE(type) == &StructMetaType) { return json_encode_struct(self, obj); } else if (PyTuple_Check(obj)) { return json_encode_tuple(self, obj); } else if (type == PyDateTimeAPI->DateTimeType) { return json_encode_datetime(self, obj); } else if (type == PyDateTimeAPI->DateType) { return json_encode_date(self, obj); } else if (type == PyDateTimeAPI->TimeType) { return json_encode_time(self, obj); } else if (type == PyDateTimeAPI->DeltaType) { return json_encode_timedelta(self, obj); } else if (type == &PyBytes_Type) { return json_encode_bytes(self, obj); } else if (type == &PyByteArray_Type) { return json_encode_bytearray(self, obj); } else if (type == &PyMemoryView_Type) { return json_encode_memoryview(self, obj); } else if (type == &Raw_Type) { return json_encode_raw(self, obj); } else if (Py_TYPE(type) == self->mod->EnumMetaType) { return json_encode_enum(self, obj, false); } else if (PyType_IsSubtype(type, (PyTypeObject *)(self->mod->UUIDType))) { return json_encode_uuid(self, obj); } else if (type == (PyTypeObject *)(self->mod->DecimalType)) { return json_encode_decimal(self, obj); } else if (PyAnySet_Check(obj)) { return json_encode_set(self, obj); } else if (!PyType_Check(obj) && type->tp_dict != NULL) { PyObject *fields = PyObject_GetAttr(obj, self->mod->str___dataclass_fields__); if (fields != NULL) { int status = json_encode_dataclass(self, obj, fields); Py_DECREF(fields); return status; } else { PyErr_Clear(); } if (PyDict_Contains(type->tp_dict, self->mod->str___attrs_attrs__)) { return json_encode_object(self, obj); } } if (self->enc_hook != NULL) { int status = -1; PyObject *temp; temp = PyObject_CallOneArg(self->enc_hook, obj); if (temp == NULL) return -1; if (!Py_EnterRecursiveCall(" while serializing an object")) { status = json_encode(self, temp); Py_LeaveRecursiveCall(); } Py_DECREF(temp); return status; } return ms_encode_err_type_unsupported(type); } static MS_INLINE int json_encode_inline(EncoderState *self, PyObject *obj) { PyTypeObject *type = Py_TYPE(obj); if (type == &PyUnicode_Type) { return json_encode_str(self, obj); } else if (type == &PyLong_Type) { return json_encode_long(self, obj); } else if (type == &PyFloat_Type) { return json_encode_float(self, obj); } else if (PyList_Check(obj)) { return json_encode_list(self, obj); } else if (PyDict_Check(obj)) { return json_encode_dict(self, obj); } else { return json_encode_uncommon(self, type, obj); } } static int json_encode(EncoderState *self, PyObject *obj) { return json_encode_inline(self, obj); } static PyObject* JSONEncoder_encode_into(Encoder *self, PyObject *const *args, Py_ssize_t nargs) { return encoder_encode_into_common(self, args, nargs, &json_encode); } static PyObject* JSONEncoder_encode(Encoder *self, PyObject *const *args, Py_ssize_t nargs) { return encoder_encode_common(self, args, nargs, &json_encode); } PyDoc_STRVAR(JSONEncoder_encode_lines__doc__, "encode_lines(self, items)\n" "--\n" "\n" "Encode an iterable of items as newline-delimited JSON, one item per line.\n" "\n" "Parameters\n" "----------\n" "items : iterable\n" " An iterable of items to encode.\n" "\n" "Returns\n" "-------\n" "data : bytes\n" " The items encoded as newline-delimited JSON, one item per line.\n" "\n" "Examples\n" "--------\n" ">>> import msgspec\n" ">>> items = [{\"name\": \"alice\"}, {\"name\": \"ben\"}]\n" ">>> encoder = msgspec.json.Encoder()\n" ">>> encoder.encode_lines(items)\n" "b'{\"name\":\"alice\"}\\n{\"name\":\"ben\"}\\n'" ); static PyObject * JSONEncoder_encode_lines(Encoder *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) return NULL; EncoderState state = { .mod = self->mod, .enc_hook = self->enc_hook, .decimal_format = self->decimal_format, .uuid_format = self->uuid_format, .order = self->order, .output_len = 0, .max_output_len = ENC_LINES_INIT_BUFSIZE, .resize_buffer = &ms_resize_bytes }; state.output_buffer = PyBytes_FromStringAndSize(NULL, state.max_output_len); if (state.output_buffer == NULL) return NULL; state.output_buffer_raw = PyBytes_AS_STRING(state.output_buffer); PyObject *input = args[0]; if (MS_LIKELY(PyList_Check(input))) { for (Py_ssize_t i = 0; i < PyList_GET_SIZE(input); i++) { if (json_encode(&state, PyList_GET_ITEM(input, i)) < 0) goto error; if (ms_write(&state, "\n", 1) < 0) goto error; } } else { PyObject *iter = PyObject_GetIter(input); if (iter == NULL) goto error; PyObject *item; while ((item = PyIter_Next(iter))) { if (json_encode(&state, item) < 0) goto error; if (ms_write(&state, "\n", 1) < 0) goto error; } if (PyErr_Occurred()) goto error; } FAST_BYTES_SHRINK(state.output_buffer, state.output_len); return state.output_buffer; error: Py_DECREF(state.output_buffer); return NULL; } static struct PyMethodDef JSONEncoder_methods[] = { { "encode", (PyCFunction) JSONEncoder_encode, METH_FASTCALL, Encoder_encode__doc__, }, { "encode_into", (PyCFunction) JSONEncoder_encode_into, METH_FASTCALL, Encoder_encode_into__doc__, }, { "encode_lines", (PyCFunction) JSONEncoder_encode_lines, METH_FASTCALL, JSONEncoder_encode_lines__doc__, }, {NULL, NULL} /* sentinel */ }; static PyTypeObject JSONEncoder_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.json.Encoder", .tp_doc = JSONEncoder__doc__, .tp_basicsize = sizeof(Encoder), .tp_dealloc = (destructor)Encoder_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_traverse = (traverseproc)Encoder_traverse, .tp_clear = (inquiry)Encoder_clear, .tp_new = PyType_GenericNew, .tp_init = (initproc)Encoder_init, .tp_methods = JSONEncoder_methods, .tp_members = Encoder_members, .tp_getset = Encoder_getset, }; PyDoc_STRVAR(msgspec_json_encode__doc__, "json_encode(obj, *, enc_hook=None, order=None)\n" "--\n" "\n" "Serialize an object as JSON.\n" "\n" "Parameters\n" "----------\n" "obj : Any\n" " The object to serialize.\n" "enc_hook : callable, optional\n" " A callable to call for objects that aren't supported msgspec types. Takes\n" " the unsupported object and should return a supported object, or raise a\n" " ``NotImplementedError`` if unsupported.\n" "order : {None, 'deterministic', 'sorted'}, optional\n" " The ordering to use when encoding unordered compound types.\n" "\n" " - ``None``: All objects are encoded in the most efficient manner matching\n" " their in-memory representations. The default.\n" " - `'deterministic'`: Unordered collections (sets, dicts) are sorted to\n" " ensure a consistent output between runs. Useful when comparison/hashing\n" " of the encoded binary output is necessary.\n" " - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs,\n" " dataclasses, ...) are also sorted by field name before encoding. This is\n" " slower than `'deterministic'`, but may produce more human-readable output.\n" "\n" "Returns\n" "-------\n" "data : bytes\n" " The serialized object.\n" "\n" "See Also\n" "--------\n" "Encoder.encode" ); static PyObject* msgspec_json_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { return encode_common(self, args, nargs, kwnames, &json_encode); } /************************************************************************* * MessagePack Decoder * *************************************************************************/ typedef struct DecoderState { /* Configuration */ TypeNode *type; PyObject *dec_hook; PyObject *ext_hook; bool strict; /* Per-message attributes */ PyObject *buffer_obj; char *input_start; char *input_pos; char *input_end; } DecoderState; typedef struct Decoder { PyObject_HEAD PyObject *orig_type; /* Configuration */ TypeNode *type; char strict; PyObject *dec_hook; PyObject *ext_hook; } Decoder; PyDoc_STRVAR(Decoder__doc__, "Decoder(type='Any', *, strict=True, dec_hook=None, ext_hook=None)\n" "--\n" "\n" "A MessagePack decoder.\n" "\n" "Parameters\n" "----------\n" "type : type, optional\n" " A Python type (in type annotation form) to decode the object as. If\n" " provided, the message will be type checked and decoded as the specified\n" " type. Defaults to `Any`, in which case the message will be decoded using\n" " the default MessagePack types.\n" "strict : bool, optional\n" " Whether type coercion rules should be strict. Setting to False enables a\n" " wider set of coercion rules from string to non-string types for all values.\n" " Default is True.\n" "dec_hook : callable, optional\n" " An optional callback for handling decoding custom types. Should have the\n" " signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the\n" " expected message type, and ``obj`` is the decoded representation composed\n" " of only basic MessagePack types. This hook should transform ``obj`` into\n" " type ``type``, or raise a ``NotImplementedError`` if unsupported.\n" "ext_hook : callable, optional\n" " An optional callback for decoding MessagePack extensions. Should have the\n" " signature ``ext_hook(code: int, data: memoryview) -> Any``. If provided,\n" " this will be called to deserialize all extension types found in the\n" " message. Note that ``data`` is a memoryview into the larger message\n" " buffer - any references created to the underlying buffer without copying\n" " the data out will cause the full message buffer to persist in memory.\n" " If not provided, extension types will decode as ``msgspec.Ext`` objects." ); static int Decoder_init(Decoder *self, PyObject *args, PyObject *kwds) { char *kwlist[] = {"type", "strict", "dec_hook", "ext_hook", NULL}; MsgspecState *st = msgspec_get_global_state(); PyObject *type = st->typing_any; PyObject *ext_hook = NULL; PyObject *dec_hook = NULL; int strict = 1; if (!PyArg_ParseTupleAndKeywords( args, kwds, "|O$pOO", kwlist, &type, &strict, &dec_hook, &ext_hook )) { return -1; } /* Handle strict */ self->strict = strict; /* Handle dec_hook */ if (dec_hook == Py_None) { dec_hook = NULL; } if (dec_hook != NULL) { if (!PyCallable_Check(dec_hook)) { PyErr_SetString(PyExc_TypeError, "dec_hook must be callable"); return -1; } Py_INCREF(dec_hook); } self->dec_hook = dec_hook; /* Handle ext_hook */ if (ext_hook == Py_None) { ext_hook = NULL; } if (ext_hook != NULL) { if (!PyCallable_Check(ext_hook)) { PyErr_SetString(PyExc_TypeError, "ext_hook must be callable"); return -1; } Py_INCREF(ext_hook); } self->ext_hook = ext_hook; /* Handle type */ self->type = TypeNode_Convert(type); if (self->type == NULL) { return -1; } Py_INCREF(type); self->orig_type = type; return 0; } static int Decoder_traverse(Decoder *self, visitproc visit, void *arg) { int out = TypeNode_traverse(self->type, visit, arg); if (out != 0) return out; Py_VISIT(self->orig_type); Py_VISIT(self->dec_hook); Py_VISIT(self->ext_hook); return 0; } static void Decoder_dealloc(Decoder *self) { PyObject_GC_UnTrack(self); TypeNode_Free(self->type); Py_XDECREF(self->orig_type); Py_XDECREF(self->dec_hook); Py_XDECREF(self->ext_hook); Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * Decoder_repr(Decoder *self) { int recursive; PyObject *typstr, *out = NULL; recursive = Py_ReprEnter((PyObject *)self); if (recursive != 0) { return (recursive < 0) ? NULL : PyUnicode_FromString("..."); /* cpylint-ignore */ } typstr = PyObject_Repr(self->orig_type); if (typstr != NULL) { out = PyUnicode_FromFormat("msgspec.msgpack.Decoder(%U)", typstr); } Py_XDECREF(typstr); Py_ReprLeave((PyObject *)self); return out; } static MS_INLINE int mpack_read1(DecoderState *self, char *s) { if (MS_UNLIKELY(self->input_pos == self->input_end)) { return ms_err_truncated(); } *s = *self->input_pos++; return 0; } static MS_INLINE int mpack_read(DecoderState *self, char **s, Py_ssize_t n) { if (MS_LIKELY(n <= self->input_end - self->input_pos)) { *s = self->input_pos; self->input_pos += n; return 0; } return ms_err_truncated(); } static MS_INLINE bool mpack_has_trailing_characters(DecoderState *self) { if (self->input_pos != self->input_end) { PyErr_Format( msgspec_get_global_state()->DecodeError, "MessagePack data is malformed: trailing characters (byte %zd)", (Py_ssize_t)(self->input_pos - self->input_start) ); return true; } return false; } static MS_INLINE Py_ssize_t mpack_decode_size1(DecoderState *self) { char s = 0; if (mpack_read1(self, &s) < 0) return -1; return (Py_ssize_t)((unsigned char)s); } static MS_INLINE Py_ssize_t mpack_decode_size2(DecoderState *self) { char *s = NULL; if (mpack_read(self, &s, 2) < 0) return -1; return (Py_ssize_t)(_msgspec_load16(uint16_t, s)); } static MS_INLINE Py_ssize_t mpack_decode_size4(DecoderState *self) { char *s = NULL; if (mpack_read(self, &s, 4) < 0) return -1; return (Py_ssize_t)(_msgspec_load32(uint32_t, s)); } static PyObject * mpack_error_expected(char op, char *expected, PathNode *path) { char *got; if (('\x00' <= op && op <= '\x7f') || ('\xe0' <= op && op <= '\xff')) { got = "int"; } else if ('\xa0' <= op && op <= '\xbf') { got = "str"; } else if ('\x90' <= op && op <= '\x9f') { got = "array"; } else if ('\x80' <= op && op <= '\x8f') { got = "object"; } else { switch ((enum mpack_code)op) { case MP_NIL: got = "null"; break; case MP_TRUE: case MP_FALSE: got = "bool"; break; case MP_UINT8: case MP_UINT16: case MP_UINT32: case MP_UINT64: case MP_INT8: case MP_INT16: case MP_INT32: case MP_INT64: got = "int"; break; case MP_FLOAT32: case MP_FLOAT64: got = "float"; break; case MP_STR8: case MP_STR16: case MP_STR32: got = "str"; break; case MP_BIN8: case MP_BIN16: case MP_BIN32: got = "bytes"; break; case MP_ARRAY16: case MP_ARRAY32: got = "array"; break; case MP_MAP16: case MP_MAP32: got = "object"; break; case MP_FIXEXT1: case MP_FIXEXT2: case MP_FIXEXT4: case MP_FIXEXT8: case MP_FIXEXT16: case MP_EXT8: case MP_EXT16: case MP_EXT32: got = "ext"; break; default: got = "unknown"; break; } } ms_raise_validation_error(path, "Expected `%s`, got `%s`%U", expected, got); return NULL; } static MS_INLINE Py_ssize_t mpack_decode_cstr(DecoderState *self, char ** out, PathNode *path) { char op = 0; Py_ssize_t size; if (mpack_read1(self, &op) < 0) return -1; if ('\xa0' <= op && op <= '\xbf') { size = op & 0x1f; } else if (op == MP_STR8) { size = mpack_decode_size1(self); } else if (op == MP_STR16) { size = mpack_decode_size2(self); } else if (op == MP_STR32) { size = mpack_decode_size4(self); } else { mpack_error_expected(op, "str", path); return -1; } if (mpack_read(self, out, size) < 0) return -1; return size; } /* Decode an integer. If the value fits in an int64_t, it will be stored in * `out`, otherwise it will be stored in `uout`. A return value of -1 indicates * an error. */ static int mpack_decode_cint(DecoderState *self, int64_t *out, uint64_t *uout, PathNode *path) { char op = 0; char *s = NULL; if (mpack_read1(self, &op) < 0) return -1; if (('\x00' <= op && op <= '\x7f') || ('\xe0' <= op && op <= '\xff')) { *out = *((int8_t *)(&op)); } else if (op == MP_UINT8) { if (MS_UNLIKELY(mpack_read(self, &s, 1) < 0)) return -1; *out = *(uint8_t *)s; } else if (op == MP_UINT16) { if (MS_UNLIKELY(mpack_read(self, &s, 2) < 0)) return -1; *out = _msgspec_load16(uint16_t, s); } else if (op == MP_UINT32) { if (MS_UNLIKELY(mpack_read(self, &s, 4) < 0)) return -1; *out = _msgspec_load32(uint32_t, s); } else if (op == MP_UINT64) { if (MS_UNLIKELY(mpack_read(self, &s, 8) < 0)) return -1; uint64_t ux = _msgspec_load64(uint64_t, s); if (ux > LLONG_MAX) { *uout = ux; } else { *out = ux; } } else if (op == MP_INT8) { if (MS_UNLIKELY(mpack_read(self, &s, 1) < 0)) return -1; *out = *(int8_t *)s; } else if (op == MP_INT16) { if (MS_UNLIKELY(mpack_read(self, &s, 2) < 0)) return -1; *out = _msgspec_load16(int16_t, s); } else if (op == MP_INT32) { if (MS_UNLIKELY(mpack_read(self, &s, 4) < 0)) return -1; *out = _msgspec_load32(int32_t, s); } else if (op == MP_INT64) { if (MS_UNLIKELY(mpack_read(self, &s, 8) < 0)) return -1; *out = _msgspec_load64(int64_t, s); } else { mpack_error_expected(op, "int", path); return -1; } return 0; } static PyObject * mpack_decode_datetime( DecoderState *self, const char *data_buf, Py_ssize_t size, TypeNode *type, PathNode *path ) { uint64_t data64; uint32_t nanoseconds; int64_t seconds; switch (size) { case 4: seconds = _msgspec_load32(uint32_t, data_buf); nanoseconds = 0; break; case 8: data64 = _msgspec_load64(uint64_t, data_buf); seconds = data64 & 0x00000003ffffffffL; nanoseconds = data64 >> 34; break; case 12: nanoseconds = _msgspec_load32(uint32_t, data_buf); seconds = _msgspec_load64(uint64_t, data_buf + 4); break; default: return ms_error_with_path( "Invalid MessagePack timestamp%U", path ); } if (nanoseconds > 999999999) { return ms_error_with_path( "Invalid MessagePack timestamp: nanoseconds out of range%U", path ); } return datetime_from_epoch(seconds, nanoseconds, type, path); } static int mpack_skip(DecoderState *self); static int mpack_skip_array(DecoderState *self, Py_ssize_t size) { int status = -1; Py_ssize_t i; if (size < 0) return -1; if (size == 0) return 0; if (Py_EnterRecursiveCall(" while deserializing an object")) return -1; for (i = 0; i < size; i++) { if (mpack_skip(self) < 0) goto done; } status = 0; done: Py_LeaveRecursiveCall(); return status; } static int mpack_skip_map(DecoderState *self, Py_ssize_t size) { return mpack_skip_array(self, size * 2); } static int mpack_skip_ext(DecoderState *self, Py_ssize_t size) { char *s; if (size < 0) return -1; return mpack_read(self, &s, size + 1); } static int mpack_skip(DecoderState *self) { char *s = NULL; char op = 0; Py_ssize_t size; if (mpack_read1(self, &op) < 0) return -1; if (('\x00' <= op && op <= '\x7f') || ('\xe0' <= op && op <= '\xff')) { return 0; } else if ('\xa0' <= op && op <= '\xbf') { return mpack_read(self, &s, op & 0x1f); } else if ('\x90' <= op && op <= '\x9f') { return mpack_skip_array(self, op & 0x0f); } else if ('\x80' <= op && op <= '\x8f') { return mpack_skip_map(self, op & 0x0f); } switch ((enum mpack_code)op) { case MP_NIL: case MP_TRUE: case MP_FALSE: return 0; case MP_UINT8: case MP_INT8: return mpack_read1(self, &op); case MP_UINT16: case MP_INT16: return mpack_read(self, &s, 2); case MP_UINT32: case MP_INT32: case MP_FLOAT32: return mpack_read(self, &s, 4); case MP_UINT64: case MP_INT64: case MP_FLOAT64: return mpack_read(self, &s, 8); case MP_STR8: case MP_BIN8: if ((size = mpack_decode_size1(self)) < 0) return -1; return mpack_read(self, &s, size); case MP_STR16: case MP_BIN16: if ((size = mpack_decode_size2(self)) < 0) return -1; return mpack_read(self, &s, size); case MP_STR32: case MP_BIN32: if ((size = mpack_decode_size4(self)) < 0) return -1; return mpack_read(self, &s, size); case MP_ARRAY16: return mpack_skip_array(self, mpack_decode_size2(self)); case MP_ARRAY32: return mpack_skip_array(self, mpack_decode_size4(self)); case MP_MAP16: return mpack_skip_map(self, mpack_decode_size2(self)); case MP_MAP32: return mpack_skip_map(self, mpack_decode_size4(self)); case MP_FIXEXT1: return mpack_skip_ext(self, 1); case MP_FIXEXT2: return mpack_skip_ext(self, 2); case MP_FIXEXT4: return mpack_skip_ext(self, 4); case MP_FIXEXT8: return mpack_skip_ext(self, 8); case MP_FIXEXT16: return mpack_skip_ext(self, 16); case MP_EXT8: return mpack_skip_ext(self, mpack_decode_size1(self)); case MP_EXT16: return mpack_skip_ext(self, mpack_decode_size2(self)); case MP_EXT32: return mpack_skip_ext(self, mpack_decode_size4(self)); default: PyErr_Format( msgspec_get_global_state()->DecodeError, "MessagePack data is malformed: invalid opcode '\\x%02x' (byte %zd)", (unsigned char)op, (Py_ssize_t)(self->input_pos - self->input_start - 1) ); return -1; } } static PyObject * mpack_decode( DecoderState *self, TypeNode *type, PathNode *path, bool is_key ); static PyObject * mpack_decode_none(DecoderState *self, TypeNode *type, PathNode *path) { if (type->types & (MS_TYPE_ANY | MS_TYPE_NONE)) { Py_INCREF(Py_None); return Py_None; } return ms_validation_error("None", type, path); } static PyObject * mpack_decode_bool(DecoderState *self, PyObject *val, TypeNode *type, PathNode *path) { if (type->types & (MS_TYPE_ANY | MS_TYPE_BOOL)) { Py_INCREF(val); return val; } return ms_validation_error("bool", type, path); } static PyObject * mpack_decode_float(DecoderState *self, double x, TypeNode *type, PathNode *path) { if (MS_LIKELY(type->types & (MS_TYPE_ANY | MS_TYPE_FLOAT))) { return ms_decode_float(x, type, path); } else if (type->types & MS_TYPE_DECIMAL) { return ms_decode_decimal_from_float(x, path, NULL); } else if (!self->strict) { if (type->types & MS_TYPE_INT) { int64_t out; if (double_as_int64(x, &out)) { return ms_post_decode_int64(out, type, path, self->strict, false); } } if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_float(x, type, path); } if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta_from_float(x, path); } } return ms_validation_error("float", type, path); } static PyObject * mpack_decode_str(DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path) { char *s = NULL; if (MS_UNLIKELY(mpack_read(self, &s, size) < 0)) return NULL; if (MS_LIKELY(type->types & (MS_TYPE_STR | MS_TYPE_ANY))) { return ms_check_str_constraints( PyUnicode_DecodeUTF8(s, size, NULL), type, path ); } else if (MS_UNLIKELY(!self->strict)) { bool invalid = false; PyObject *out = ms_decode_str_lax(s, size, type, path, &invalid); if (!invalid) return out; } if (MS_UNLIKELY(type->types & (MS_TYPE_ENUM | MS_TYPE_STRLITERAL))) { return ms_decode_str_enum_or_literal(s, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_DATETIME)) { return ms_decode_datetime_from_str(s, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_DATE)) { return ms_decode_date(s, size, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_TIME)) { return ms_decode_time(s, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_TIMEDELTA)) { return ms_decode_timedelta(s, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_UUID)) { return ms_decode_uuid_from_str(s, size, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_DECIMAL)) { return ms_decode_decimal(s, size, false, path, NULL); } return ms_validation_error("str", type, path); } static PyObject * mpack_decode_bin( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path ) { if (MS_UNLIKELY(size < 0)) return NULL; if (MS_UNLIKELY(!ms_passes_bytes_constraints(size, type, path))) return NULL; char *s = NULL; if (MS_UNLIKELY(mpack_read(self, &s, size) < 0)) return NULL; if (type->types & (MS_TYPE_ANY | MS_TYPE_BYTES)) { return PyBytes_FromStringAndSize(s, size); } else if (type->types & MS_TYPE_BYTEARRAY) { return PyByteArray_FromStringAndSize(s, size); } else if (type->types & MS_TYPE_UUID) { return ms_decode_uuid_from_bytes(s, size, path); } else if (type->types & MS_TYPE_MEMORYVIEW) { PyObject *view = PyMemoryView_GetContiguous( self->buffer_obj, PyBUF_READ, 'C' ); if (view == NULL) return NULL; Py_buffer *buffer = PyMemoryView_GET_BUFFER(view); buffer->buf = s; buffer->len = size; return view; } return ms_validation_error("bytes", type, path); } static PyObject * mpack_decode_list( DecoderState *self, Py_ssize_t size, TypeNode *el_type, PathNode *path ) { Py_ssize_t i; PyObject *res, *item; /* XXX: Preallocate all elements for lists <= 16 elements in length. * * This minimizes the ability of malicious messages to cause a massive * overallocation, while not penalizing decoding speed for small lists. * With this restriction, a malicious message can preallocate at most: * * sys.getsizeof(list(range(16))) * sys.getrecursionlimit() * * bytes, which should be low enough to not matter (500 KiB on my machine). * Dropping this optimization (resulting in the same allocation pattern as * the JSON decoder would reduce this to * * sys.getsizeof([]) * sys.getrecursionlimit() * * which is roughly 1/3 the size. This reduction is deemed not worth it. */ res = PyList_New(Py_MIN(16, size)); if (res == NULL) return NULL; Py_SET_SIZE(res, 0); if (size == 0) return res; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(res); return NULL; /* cpylint-ignore */ } for (i = 0; i < size; i++) { PathNode el_path = {path, i}; item = mpack_decode(self, el_type, &el_path, false); if (MS_UNLIKELY(item == NULL)) { Py_CLEAR(res); break; } /* Append item to list */ if (MS_LIKELY((LIST_CAPACITY(res) > Py_SIZE(res)))) { PyList_SET_ITEM(res, Py_SIZE(res), item); Py_SET_SIZE(res, Py_SIZE(res) + 1); } else { int status = PyList_Append(res, item); Py_DECREF(item); if (MS_UNLIKELY(status < 0)) { Py_CLEAR(res); break; } } } Py_LeaveRecursiveCall(); return res; } static PyObject * mpack_decode_set( DecoderState *self, bool mutable, Py_ssize_t size, TypeNode *el_type, PathNode *path ) { Py_ssize_t i; PyObject *res, *item; res = mutable ? PySet_New(NULL) : PyFrozenSet_New(NULL); if (res == NULL) return NULL; if (size == 0) return res; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(res); return NULL; /* cpylint-ignore */ } for (i = 0; i < size; i++) { PathNode el_path = {path, i}; item = mpack_decode(self, el_type, &el_path, true); if (MS_UNLIKELY(item == NULL || PySet_Add(res, item) < 0)) { Py_XDECREF(item); Py_CLEAR(res); break; } Py_DECREF(item); } Py_LeaveRecursiveCall(); return res; } static PyObject * mpack_decode_vartuple( DecoderState *self, Py_ssize_t size, TypeNode *el_type, PathNode *path, bool is_key ) { if (MS_UNLIKELY(size > 16)) { /* For variadic tuples of length > 16, we fallback to decoding into a * list, then converting to a tuple. This lets us avoid pre-allocating * extremely large tuples. See the comment in `mpack_decode_list` for * more info. */ PyObject *temp = mpack_decode_list(self, size, el_type, path); if (temp == NULL) return NULL; PyObject *res = PyList_AsTuple(temp); Py_DECREF(temp); return res; } PyObject *res = PyTuple_New(size); if (res == NULL) return NULL; if (size == 0) return res; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(res); return NULL; /* cpylint-ignore */ } for (Py_ssize_t i = 0; i < size; i++) { PathNode el_path = {path, i}; PyObject *item = mpack_decode(self, el_type, &el_path, is_key); if (MS_UNLIKELY(item == NULL)) { Py_CLEAR(res); break; } PyTuple_SET_ITEM(res, i, item); } Py_LeaveRecursiveCall(); return res; } static PyObject * mpack_decode_fixtuple( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { PyObject *res, *item; Py_ssize_t i, fixtuple_size, offset; TypeNode_get_fixtuple(type, &offset, &fixtuple_size); if (size != fixtuple_size) { /* tuple is the incorrect size, raise and return */ ms_raise_validation_error( path, "Expected `array` of length %zd, got %zd%U", fixtuple_size, size ); return NULL; } res = PyTuple_New(size); if (res == NULL) return NULL; if (size == 0) return res; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(res); return NULL; /* cpylint-ignore */ } for (i = 0; i < fixtuple_size; i++) { PathNode el_path = {path, i}; item = mpack_decode(self, type->details[offset + i].pointer, &el_path, is_key); if (MS_UNLIKELY(item == NULL)) { Py_CLEAR(res); break; } PyTuple_SET_ITEM(res, i, item); } Py_LeaveRecursiveCall(); return res; } static PyObject * mpack_decode_namedtuple( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { NamedTupleInfo *info = TypeNode_get_namedtuple_info(type); Py_ssize_t nfields = Py_SIZE(info); Py_ssize_t ndefaults = info->defaults == NULL ? 0 : PyTuple_GET_SIZE(info->defaults); Py_ssize_t nrequired = nfields - ndefaults; if (size < nrequired || nfields < size) { /* tuple is the incorrect size, raise and return */ if (ndefaults == 0) { ms_raise_validation_error( path, "Expected `array` of length %zd, got %zd%U", nfields, size ); } else { ms_raise_validation_error( path, "Expected `array` of length %zd to %zd, got %zd%U", nrequired, nfields, size ); } return NULL; } if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyTypeObject *nt_type = (PyTypeObject *)(info->class); PyObject *res = nt_type->tp_alloc(nt_type, nfields); if (res == NULL) goto error; for (Py_ssize_t i = 0; i < nfields; i++) { PyTuple_SET_ITEM(res, i, NULL); } for (Py_ssize_t i = 0; i < size; i++) { PathNode el_path = {path, i}; PyObject *item = mpack_decode(self, info->types[i], &el_path, is_key); if (MS_UNLIKELY(item == NULL)) goto error; PyTuple_SET_ITEM(res, i, item); } for (Py_ssize_t i = size; i < nfields; i++) { PyObject *item = PyTuple_GET_ITEM(info->defaults, i - nrequired); Py_INCREF(item); PyTuple_SET_ITEM(res, i, item); } Py_LeaveRecursiveCall(); return res; error: Py_LeaveRecursiveCall(); Py_CLEAR(res); return NULL; } static int mpack_ensure_tag_matches( DecoderState *self, PathNode *path, PyObject *expected_tag ) { if (PyUnicode_CheckExact(expected_tag)) { char *tag = NULL; Py_ssize_t tag_size; tag_size = mpack_decode_cstr(self, &tag, path); if (tag_size < 0) return -1; /* Check that tag matches expected tag value */ Py_ssize_t expected_size; const char *expected_str = unicode_str_and_size_nocheck( expected_tag, &expected_size ); if (tag_size != expected_size || memcmp(tag, expected_str, expected_size) != 0) { /* Tag doesn't match the expected value, error nicely */ ms_invalid_cstr_value(tag, tag_size, path); return -1; } } else { int64_t tag = 0; uint64_t utag = 0; if (mpack_decode_cint(self, &tag, &utag, path) < 0) return -1; int64_t expected = PyLong_AsLongLong(expected_tag); /* Tags must be int64s, if utag != 0 then we know the tags don't match. * We parse the full uint64 value only to validate the message and * raise a nice error */ if (utag != 0) { ms_invalid_cuint_value(utag, path); return -1; } if (tag != expected) { ms_invalid_cint_value(tag, path); return -1; } } return 0; } static StructInfo * mpack_decode_tag_and_lookup_type( DecoderState *self, Lookup *lookup, PathNode *path ) { StructInfo *out = NULL; if (Lookup_IsStrLookup(lookup)) { Py_ssize_t tag_size; char *tag = NULL; tag_size = mpack_decode_cstr(self, &tag, path); if (tag_size < 0) return NULL; out = (StructInfo *)StrLookup_Get((StrLookup *)lookup, tag, tag_size); if (out == NULL) { ms_invalid_cstr_value(tag, tag_size, path); } } else { int64_t tag = 0; uint64_t utag = 0; if (mpack_decode_cint(self, &tag, &utag, path) < 0) return NULL; if (utag == 0) { out = (StructInfo *)IntLookup_GetInt64((IntLookup *)lookup, tag); if (out == NULL) { ms_invalid_cint_value(tag, path); } } else { out = (StructInfo *)IntLookup_GetUInt64((IntLookup *)lookup, utag); if (out == NULL) { ms_invalid_cuint_value(utag, path); } } } return out; } static PyObject * mpack_decode_struct_array_inner( DecoderState *self, Py_ssize_t size, bool tag_already_read, StructInfo *info, PathNode *path, bool is_key ) { Py_ssize_t i, nfields, ndefaults, nrequired, npos; PyObject *res, *val = NULL; StructMetaObject *st_type = info->class; bool is_gc, should_untrack; bool tagged = st_type->struct_tag_value != NULL; PathNode item_path = {path, 0}; nfields = PyTuple_GET_SIZE(st_type->struct_encode_fields); ndefaults = PyTuple_GET_SIZE(st_type->struct_defaults); nrequired = tagged + nfields - st_type->n_trailing_defaults; npos = nfields - ndefaults; if (size < nrequired) { ms_raise_validation_error( path, "Expected `array` of at least length %zd, got %zd%U", nrequired, size ); return NULL; } if (tagged) { if (!tag_already_read) { if (mpack_ensure_tag_matches(self, &item_path, st_type->struct_tag_value) < 0) { return NULL; } } size--; item_path.index++; } if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; res = Struct_alloc((PyTypeObject *)(st_type)); if (res == NULL) goto error; is_gc = MS_TYPE_IS_GC(st_type); should_untrack = is_gc; for (i = 0; i < nfields; i++) { if (size > 0) { val = mpack_decode(self, info->types[i], &item_path, is_key); if (MS_UNLIKELY(val == NULL)) goto error; size--; item_path.index++; } else { val = get_default( PyTuple_GET_ITEM(st_type->struct_defaults, i - npos) ); if (val == NULL) goto error; } Struct_set_index(res, i, val); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } if (MS_UNLIKELY(size > 0)) { if (MS_UNLIKELY(st_type->forbid_unknown_fields == OPT_TRUE)) { ms_raise_validation_error( path, "Expected `array` of at most length %zd, got %zd%U", nfields, nfields + size ); goto error; } else { /* Ignore all trailing fields */ while (size > 0) { if (mpack_skip(self) < 0) goto error; size--; } } } if (Struct_decode_post_init(st_type, res, path) < 0) goto error; Py_LeaveRecursiveCall(); if (is_gc && !should_untrack) PyObject_GC_Track(res); return res; error: Py_LeaveRecursiveCall(); Py_XDECREF(res); return NULL; } static PyObject * mpack_decode_struct_array( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { StructInfo *info = TypeNode_get_struct_info(type); return mpack_decode_struct_array_inner(self, size, false, info, path, is_key); } static PyObject * mpack_decode_struct_array_union( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { Lookup *lookup = TypeNode_get_struct_union(type); if (size == 0) { return ms_error_with_path( "Expected `array` of at least length 1, got 0%U", path ); } /* Decode and lookup tag */ PathNode tag_path = {path, 0}; StructInfo *info = mpack_decode_tag_and_lookup_type(self, lookup, &tag_path); if (info == NULL) return NULL; /* Finish decoding the rest of the struct */ return mpack_decode_struct_array_inner(self, size, true, info, path, is_key); } static PyObject * mpack_decode_array( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { if (MS_UNLIKELY(!ms_passes_array_constraints(size, type, path))) return NULL; if (type->types & MS_TYPE_ANY) { TypeNode type_any = {MS_TYPE_ANY}; if (is_key) { return mpack_decode_vartuple(self, size, &type_any, path, is_key); } else { return mpack_decode_list(self, size, &type_any, path); } } else if (type->types & MS_TYPE_LIST) { return mpack_decode_list(self, size, TypeNode_get_array(type), path); } else if (type->types & (MS_TYPE_SET | MS_TYPE_FROZENSET)) { return mpack_decode_set( self, type->types & MS_TYPE_SET, size, TypeNode_get_array(type), path ); } else if (type->types & MS_TYPE_VARTUPLE) { return mpack_decode_vartuple(self, size, TypeNode_get_array(type), path, is_key); } else if (type->types & MS_TYPE_FIXTUPLE) { return mpack_decode_fixtuple(self, size, type, path, is_key); } else if (type->types & MS_TYPE_NAMEDTUPLE) { return mpack_decode_namedtuple(self, size, type, path, is_key); } else if (type->types & MS_TYPE_STRUCT_ARRAY) { return mpack_decode_struct_array(self, size, type, path, is_key); } else if (type->types & MS_TYPE_STRUCT_ARRAY_UNION) { return mpack_decode_struct_array_union(self, size, type, path, is_key); } return ms_validation_error("array", type, path); } /* Specialized mpack_decode for dict keys, handling caching of short string keys */ static PyObject * mpack_decode_key(DecoderState *self, TypeNode *type, PathNode *path) { char op; if (MS_UNLIKELY(self->input_pos == self->input_end)) { ms_err_truncated(); return NULL; } /* Peek at the next op */ op = *self->input_pos; bool is_str = type->types == MS_TYPE_ANY || type->types == MS_TYPE_STR; if (MS_LIKELY(is_str && '\xa0' <= op && op <= '\xbf')) { /* A short (<= 31 byte) unicode str */ self->input_pos++; /* consume op */ Py_ssize_t size = op & 0x1f; /* Don't cache the empty string */ if (MS_UNLIKELY(size == 0)) return PyUnicode_New(0, 127); /* Read in the string buffer */ char *str; if (MS_UNLIKELY(mpack_read(self, &str, size) < 0)) return NULL; /* Attempt a cache lookup. We don't know if it's ascii yet, but * checking if it's ascii is more expensive than just doing a lookup, * and most dict key strings are ascii */ uint32_t hash = murmur2(str, size); uint32_t index = hash % STRING_CACHE_SIZE; PyObject *existing = string_cache[index]; if (MS_LIKELY(existing != NULL)) { Py_ssize_t e_size = ((PyASCIIObject *)existing)->length; char *e_str = ascii_get_buffer(existing); if (MS_LIKELY(size == e_size && memcmp(str, e_str, size) == 0)) { Py_INCREF(existing); return existing; } } /* Cache miss, create a new string */ PyObject *new = PyUnicode_DecodeUTF8(str, size, NULL); if (new == NULL) return NULL; /* If ascii, add it to the cache */ if (PyUnicode_IS_COMPACT_ASCII(new)) { Py_XDECREF(existing); Py_INCREF(new); string_cache[index] = new; } return new; } /* Fallback to standard decode */ return mpack_decode(self, type, path, true); } static PyObject * mpack_decode_dict( DecoderState *self, Py_ssize_t size, TypeNode *key_type, TypeNode *val_type, PathNode *path ) { Py_ssize_t i; PyObject *res, *key = NULL, *val = NULL; PathNode key_path = {path, PATH_KEY, NULL}; PathNode val_path = {path, PATH_ELLIPSIS, NULL}; res = PyDict_New(); if (res == NULL) return NULL; if (size == 0) return res; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(res); return NULL; /* cpylint-ignore */ } for (i = 0; i < size; i++) { key = mpack_decode_key(self, key_type, &key_path); if (MS_UNLIKELY(key == NULL)) goto error; val = mpack_decode(self, val_type, &val_path, false); if (MS_UNLIKELY(val == NULL)) goto error; if (MS_UNLIKELY(PyDict_SetItem(res, key, val) < 0)) goto error; Py_CLEAR(key); Py_CLEAR(val); } Py_LeaveRecursiveCall(); return res; error: Py_LeaveRecursiveCall(); Py_XDECREF(key); Py_XDECREF(val); Py_DECREF(res); return NULL; } static PyObject * mpack_decode_typeddict( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path ) { if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyObject *res = PyDict_New(); if (res == NULL) goto error; TypedDictInfo *info = TypeNode_get_typeddict_info(type); Py_ssize_t nrequired = 0, pos = 0; for (Py_ssize_t i = 0; i < size; i++) { char *key; PathNode key_path = {path, PATH_KEY, NULL}; Py_ssize_t key_size = mpack_decode_cstr(self, &key, &key_path); if (MS_UNLIKELY(key_size < 0)) goto error; TypeNode *field_type; PyObject *field = TypedDictInfo_lookup_key(info, key, key_size, &field_type, &pos); if (field != NULL) { PathNode field_path = {path, PATH_STR, field}; PyObject *val = mpack_decode(self, field_type, &field_path, false); if (val == NULL) goto error; /* We want to keep a count of required fields we've decoded. Since * duplicates can occur, we stash the current dict size, then only * increment if the dict size has changed _and_ the field is * required. */ Py_ssize_t cur_size = PyDict_GET_SIZE(res); int status = PyDict_SetItem(res, field, val); /* Always decref value, no need to decref key since it's a borrowed * reference. */ Py_DECREF(val); if (status < 0) goto error; if ((PyDict_GET_SIZE(res) != cur_size) && (field_type->types & MS_EXTRA_FLAG)) { nrequired++; } } else { /* Unknown field, skip */ if (mpack_skip(self) < 0) goto error; } } if (nrequired < info->nrequired) { /* A required field is missing, determine which one and raise */ TypedDictInfo_error_missing(info, res, path); goto error; } Py_LeaveRecursiveCall(); return res; error: Py_LeaveRecursiveCall(); Py_XDECREF(res); return NULL; } static PyObject * mpack_decode_dataclass( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path ) { if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; DataclassInfo *info = TypeNode_get_dataclass_info(type); PyTypeObject *dataclass_type = (PyTypeObject *)(info->class); PyObject *out = dataclass_type->tp_alloc(dataclass_type, 0); if (out == NULL) goto error; if (info->pre_init != NULL) { PyObject *res = PyObject_CallOneArg(info->pre_init, out); if (res == NULL) goto error; Py_DECREF(res); } Py_ssize_t pos = 0; for (Py_ssize_t i = 0; i < size; i++) { char *key; PathNode key_path = {path, PATH_KEY, NULL}; Py_ssize_t key_size = mpack_decode_cstr(self, &key, &key_path); if (MS_UNLIKELY(key_size < 0)) goto error; TypeNode *field_type; PyObject *field = DataclassInfo_lookup_key(info, key, key_size, &field_type, &pos); if (field != NULL) { PathNode field_path = {path, PATH_STR, field}; PyObject *val = mpack_decode(self, field_type, &field_path, false); if (val == NULL) goto error; int status = PyObject_GenericSetAttr(out, field, val); Py_DECREF(val); if (status < 0) goto error; } else { /* Unknown field, skip */ if (mpack_skip(self) < 0) goto error; } } if (DataclassInfo_post_decode(info, out, path) < 0) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * mpack_decode_struct_map( DecoderState *self, Py_ssize_t size, StructInfo *info, PathNode *path, bool is_key ) { StructMetaObject *st_type = info->class; Py_ssize_t i, key_size, field_index, pos = 0; char *key = NULL; PyObject *res, *val = NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; res = Struct_alloc((PyTypeObject *)(st_type)); if (res == NULL) goto error; for (i = 0; i < size; i++) { PathNode key_path = {path, PATH_KEY, NULL}; key_size = mpack_decode_cstr(self, &key, &key_path); if (MS_UNLIKELY(key_size < 0)) goto error; field_index = StructMeta_get_field_index(st_type, key, key_size, &pos); if (field_index < 0) { if (MS_UNLIKELY(field_index == -2)) { PathNode tag_path = {path, PATH_STR, st_type->struct_tag_field}; if (mpack_ensure_tag_matches(self, &tag_path, st_type->struct_tag_value) < 0) { goto error; } } else { /* Unknown field */ if (MS_UNLIKELY(st_type->forbid_unknown_fields == OPT_TRUE)) { ms_error_unknown_field(key, key_size, path); goto error; } else { if (mpack_skip(self) < 0) goto error; } } } else { PathNode field_path = {path, field_index, (PyObject *)st_type}; val = mpack_decode(self, info->types[field_index], &field_path, is_key); if (val == NULL) goto error; Struct_set_index(res, field_index, val); } } if (Struct_fill_in_defaults(st_type, res, path) < 0) goto error; Py_LeaveRecursiveCall(); return res; error: Py_LeaveRecursiveCall(); Py_XDECREF(res); return NULL; } static PyObject * mpack_decode_struct_union( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { Lookup *lookup = TypeNode_get_struct_union(type); PathNode key_path = {path, PATH_KEY, NULL}; Py_ssize_t tag_field_size; const char *tag_field = unicode_str_and_size_nocheck( Lookup_tag_field(lookup), &tag_field_size ); /* Cache the current input position in case we need to reset it once the * tag is found */ char *orig_input_pos = self->input_pos; for (Py_ssize_t i = 0; i < size; i++) { Py_ssize_t key_size; char *key = NULL; key_size = mpack_decode_cstr(self, &key, &key_path); if (key_size < 0) return NULL; if (key_size == tag_field_size && memcmp(key, tag_field, key_size) == 0) { /* Decode and lookup tag */ PathNode tag_path = {path, PATH_STR, Lookup_tag_field(lookup)}; StructInfo *info = mpack_decode_tag_and_lookup_type(self, lookup, &tag_path); if (info == NULL) return NULL; if (i == 0) { /* Common case, tag is first field. No need to reset, just mark * that the first field has been read. */ size--; } else { self->input_pos = orig_input_pos; } return mpack_decode_struct_map(self, size, info, path, is_key); } else { /* Not the tag field, skip the value and try again */ if (mpack_skip(self) < 0) return NULL; } } ms_missing_required_field(Lookup_tag_field(lookup), path); return NULL; } static PyObject * mpack_decode_map( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path, bool is_key ) { if (type->types & MS_TYPE_STRUCT) { StructInfo *info = TypeNode_get_struct_info(type); return mpack_decode_struct_map(self, size, info, path, is_key); } else if (type->types & MS_TYPE_TYPEDDICT) { return mpack_decode_typeddict(self, size, type, path); } else if (type->types & MS_TYPE_DATACLASS) { return mpack_decode_dataclass(self, size, type, path); } else if (type->types & (MS_TYPE_DICT | MS_TYPE_ANY)) { if (MS_UNLIKELY(!ms_passes_map_constraints(size, type, path))) { return NULL; } TypeNode *key, *val; TypeNode type_any = {MS_TYPE_ANY}; if (type->types & MS_TYPE_ANY) { key = &type_any; val = &type_any; } else { TypeNode_get_dict(type, &key, &val); } return mpack_decode_dict(self, size, key, val, path); } else if (type->types & MS_TYPE_STRUCT_UNION) { return mpack_decode_struct_union(self, size, type, path, is_key); } return ms_validation_error("object", type, path); } static PyObject * mpack_decode_ext( DecoderState *self, Py_ssize_t size, TypeNode *type, PathNode *path ) { Py_buffer *buffer; char c_code = 0, *data_buf = NULL; long code; PyObject *data, *pycode = NULL, *view = NULL, *out = NULL; if (size < 0) return NULL; if (mpack_read1(self, &c_code) < 0) return NULL; code = *((int8_t *)(&c_code)); if (mpack_read(self, &data_buf, size) < 0) return NULL; if (type->types & MS_TYPE_DATETIME && code == -1) { return mpack_decode_datetime(self, data_buf, size, type, path); } else if (type->types & MS_TYPE_EXT) { data = PyBytes_FromStringAndSize(data_buf, size); if (data == NULL) return NULL; return Ext_New(code, data); } else if (!(type->types & MS_TYPE_ANY)) { return ms_validation_error("ext", type, path); } /* Decode Any. * - datetime if code == -1 * - call ext_hook if available * - otherwise return Ext object * */ if (code == -1) { return mpack_decode_datetime(self, data_buf, size, type, path); } else if (self->ext_hook == NULL) { data = PyBytes_FromStringAndSize(data_buf, size); if (data == NULL) return NULL; return Ext_New(code, data); } else { pycode = PyLong_FromLong(code); if (pycode == NULL) goto done; } view = PyMemoryView_GetContiguous(self->buffer_obj, PyBUF_READ, 'C'); if (view == NULL) goto done; buffer = PyMemoryView_GET_BUFFER(view); buffer->buf = data_buf; buffer->len = size; out = PyObject_CallFunctionObjArgs(self->ext_hook, pycode, view, NULL); done: Py_XDECREF(pycode); Py_XDECREF(view); return out; } static MS_NOINLINE PyObject * mpack_decode_raw(DecoderState *self) { char *start = self->input_pos; if (mpack_skip(self) < 0) return NULL; Py_ssize_t size = self->input_pos - start; return Raw_FromView(self->buffer_obj, start, size); } static MS_INLINE PyObject * mpack_decode_nocustom( DecoderState *self, TypeNode *type, PathNode *path, bool is_key ) { char op = 0; char *s = NULL; if (mpack_read1(self, &op) < 0) { return NULL; } if (('\x00' <= op && op <= '\x7f') || ('\xe0' <= op && op <= '\xff')) { return ms_post_decode_int64(*((int8_t *)(&op)), type, path, self->strict, false); } else if ('\xa0' <= op && op <= '\xbf') { return mpack_decode_str(self, op & 0x1f, type, path); } else if ('\x90' <= op && op <= '\x9f') { return mpack_decode_array(self, op & 0x0f, type, path, is_key); } else if ('\x80' <= op && op <= '\x8f') { return mpack_decode_map(self, op & 0x0f, type, path, is_key); } switch ((enum mpack_code)op) { case MP_NIL: return mpack_decode_none(self, type, path); case MP_TRUE: return mpack_decode_bool(self, Py_True, type, path); case MP_FALSE: return mpack_decode_bool(self, Py_False, type, path); case MP_UINT8: if (MS_UNLIKELY(mpack_read(self, &s, 1) < 0)) return NULL; return ms_post_decode_uint64(*(uint8_t *)s, type, path, self->strict, false); case MP_UINT16: if (MS_UNLIKELY(mpack_read(self, &s, 2) < 0)) return NULL; return ms_post_decode_uint64(_msgspec_load16(uint16_t, s), type, path, self->strict, false); case MP_UINT32: if (MS_UNLIKELY(mpack_read(self, &s, 4) < 0)) return NULL; return ms_post_decode_uint64(_msgspec_load32(uint32_t, s), type, path, self->strict, false); case MP_UINT64: if (MS_UNLIKELY(mpack_read(self, &s, 8) < 0)) return NULL; return ms_post_decode_uint64(_msgspec_load64(uint64_t, s), type, path, self->strict, false); case MP_INT8: if (MS_UNLIKELY(mpack_read(self, &s, 1) < 0)) return NULL; return ms_post_decode_int64(*(int8_t *)s, type, path, self->strict, false); case MP_INT16: if (MS_UNLIKELY(mpack_read(self, &s, 2) < 0)) return NULL; return ms_post_decode_int64(_msgspec_load16(int16_t, s), type, path, self->strict, false); case MP_INT32: if (MS_UNLIKELY(mpack_read(self, &s, 4) < 0)) return NULL; return ms_post_decode_int64(_msgspec_load32(int32_t, s), type, path, self->strict, false); case MP_INT64: if (MS_UNLIKELY(mpack_read(self, &s, 8) < 0)) return NULL; return ms_post_decode_int64(_msgspec_load64(int64_t, s), type, path, self->strict, false); case MP_FLOAT32: { float f = 0; uint32_t uf; if (mpack_read(self, &s, 4) < 0) return NULL; uf = _msgspec_load32(uint32_t, s); memcpy(&f, &uf, 4); return mpack_decode_float(self, f, type, path); } case MP_FLOAT64: { double f = 0; uint64_t uf; if (mpack_read(self, &s, 8) < 0) return NULL; uf = _msgspec_load64(uint64_t, s); memcpy(&f, &uf, 8); return mpack_decode_float(self, f, type, path); } case MP_STR8: { Py_ssize_t size = mpack_decode_size1(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_str(self, size, type, path); } case MP_STR16: { Py_ssize_t size = mpack_decode_size2(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_str(self, size, type, path); } case MP_STR32: { Py_ssize_t size = mpack_decode_size4(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_str(self, size, type, path); } case MP_BIN8: return mpack_decode_bin(self, mpack_decode_size1(self), type, path); case MP_BIN16: return mpack_decode_bin(self, mpack_decode_size2(self), type, path); case MP_BIN32: return mpack_decode_bin(self, mpack_decode_size4(self), type, path); case MP_ARRAY16: { Py_ssize_t size = mpack_decode_size2(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_array(self, size, type, path, is_key); } case MP_ARRAY32: { Py_ssize_t size = mpack_decode_size4(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_array(self, size, type, path, is_key); } case MP_MAP16: { Py_ssize_t size = mpack_decode_size2(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_map(self, size, type, path, is_key); } case MP_MAP32: { Py_ssize_t size = mpack_decode_size4(self); if (MS_UNLIKELY(size < 0)) return NULL; return mpack_decode_map(self, size, type, path, is_key); } case MP_FIXEXT1: return mpack_decode_ext(self, 1, type, path); case MP_FIXEXT2: return mpack_decode_ext(self, 2, type, path); case MP_FIXEXT4: return mpack_decode_ext(self, 4, type, path); case MP_FIXEXT8: return mpack_decode_ext(self, 8, type, path); case MP_FIXEXT16: return mpack_decode_ext(self, 16, type, path); case MP_EXT8: return mpack_decode_ext(self, mpack_decode_size1(self), type, path); case MP_EXT16: return mpack_decode_ext(self, mpack_decode_size2(self), type, path); case MP_EXT32: return mpack_decode_ext(self, mpack_decode_size4(self), type, path); default: PyErr_Format( msgspec_get_global_state()->DecodeError, "MessagePack data is malformed: invalid opcode '\\x%02x' (byte %zd)", (unsigned char)op, (Py_ssize_t)(self->input_pos - self->input_start - 1) ); return NULL; } } static PyObject * mpack_decode( DecoderState *self, TypeNode *type, PathNode *path, bool is_key ) { if (MS_UNLIKELY(type->types == 0)) { return mpack_decode_raw(self); } PyObject *obj = mpack_decode_nocustom(self, type, path, is_key); if (MS_UNLIKELY(type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC))) { return ms_decode_custom(obj, self->dec_hook, type, path); } return obj; } PyDoc_STRVAR(Decoder_decode__doc__, "decode(self, buf)\n" "--\n" "\n" "Deserialize an object from MessagePack.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like\n" " The message to decode.\n" "\n" "Returns\n" "-------\n" "obj : Any\n" " The deserialized object.\n" ); static PyObject* Decoder_decode(Decoder *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) { return NULL; } DecoderState state = { .type = self->type, .strict = self->strict, .dec_hook = self->dec_hook, .ext_hook = self->ext_hook }; Py_buffer buffer; buffer.buf = NULL; if (PyObject_GetBuffer(args[0], &buffer, PyBUF_CONTIG_RO) >= 0) { state.buffer_obj = args[0]; state.input_start = buffer.buf; state.input_pos = buffer.buf; state.input_end = state.input_pos + buffer.len; PyObject *res = mpack_decode(&state, state.type, NULL, false); if (res != NULL && mpack_has_trailing_characters(&state)) { Py_CLEAR(res); } PyBuffer_Release(&buffer); return res; } return NULL; } static struct PyMethodDef Decoder_methods[] = { { "decode", (PyCFunction) Decoder_decode, METH_FASTCALL, Decoder_decode__doc__, }, {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS}, {NULL, NULL} /* sentinel */ }; static PyMemberDef Decoder_members[] = { {"type", T_OBJECT_EX, offsetof(Decoder, orig_type), READONLY, "The Decoder type"}, {"strict", T_BOOL, offsetof(Decoder, strict), READONLY, "The Decoder strict setting"}, {"dec_hook", T_OBJECT, offsetof(Decoder, dec_hook), READONLY, "The Decoder dec_hook"}, {"ext_hook", T_OBJECT, offsetof(Decoder, ext_hook), READONLY, "The Decoder ext_hook"}, {NULL}, }; static PyTypeObject Decoder_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.msgpack.Decoder", .tp_doc = Decoder__doc__, .tp_basicsize = sizeof(Decoder), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_new = PyType_GenericNew, .tp_init = (initproc)Decoder_init, .tp_traverse = (traverseproc)Decoder_traverse, .tp_dealloc = (destructor)Decoder_dealloc, .tp_repr = (reprfunc)Decoder_repr, .tp_methods = Decoder_methods, .tp_members = Decoder_members, }; PyDoc_STRVAR(msgspec_msgpack_decode__doc__, "msgpack_decode(buf, *, type='Any', strict=True, dec_hook=None, ext_hook=None)\n" "--\n" "\n" "Deserialize an object from MessagePack.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like\n" " The message to decode.\n" "type : type, optional\n" " A Python type (in type annotation form) to decode the object as. If\n" " provided, the message will be type checked and decoded as the specified\n" " type. Defaults to `Any`, in which case the message will be decoded using\n" " the default MessagePack types.\n" "strict : bool, optional\n" " Whether type coercion rules should be strict. Setting to False enables a\n" " wider set of coercion rules from string to non-string types for all values.\n" " Default is True.\n" "dec_hook : callable, optional\n" " An optional callback for handling decoding custom types. Should have the\n" " signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the\n" " expected message type, and ``obj`` is the decoded representation composed\n" " of only basic MessagePack types. This hook should transform ``obj`` into\n" " type ``type``, or raise a ``NotImplementedError`` if unsupported.\n" "ext_hook : callable, optional\n" " An optional callback for decoding MessagePack extensions. Should have the\n" " signature ``ext_hook(code: int, data: memoryview) -> Any``. If provided,\n" " this will be called to deserialize all extension types found in the\n" " message. Note that ``data`` is a memoryview into the larger message\n" " buffer - any references created to the underlying buffer without copying\n" " the data out will cause the full message buffer to persist in memory.\n" " If not provided, extension types will decode as ``msgspec.Ext`` objects.\n" "\n" "Returns\n" "-------\n" "obj : Any\n" " The deserialized object.\n" "\n" "See Also\n" "--------\n" "Decoder.decode" ); static PyObject* msgspec_msgpack_decode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *res = NULL, *buf = NULL, *type = NULL, *strict_obj = NULL; PyObject *dec_hook = NULL, *ext_hook = NULL; MsgspecState *mod = msgspec_get_state(self); int strict = 1; /* Parse arguments */ if (!check_positional_nargs(nargs, 1, 1)) return NULL; buf = args[0]; if (kwnames != NULL) { Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames); if ((type = find_keyword(kwnames, args + nargs, mod->str_type)) != NULL) nkwargs--; if ((strict_obj = find_keyword(kwnames, args + nargs, mod->str_strict)) != NULL) nkwargs--; if ((dec_hook = find_keyword(kwnames, args + nargs, mod->str_dec_hook)) != NULL) nkwargs--; if ((ext_hook = find_keyword(kwnames, args + nargs, mod->str_ext_hook)) != NULL) nkwargs--; if (nkwargs > 0) { PyErr_SetString( PyExc_TypeError, "Extra keyword arguments provided" ); return NULL; } } /* Handle strict */ if (strict_obj != NULL) { strict = PyObject_IsTrue(strict_obj); if (strict < 0) return NULL; } /* Handle dec_hook */ if (dec_hook == Py_None) { dec_hook = NULL; } if (dec_hook != NULL) { if (!PyCallable_Check(dec_hook)) { PyErr_SetString(PyExc_TypeError, "dec_hook must be callable"); return NULL; } } /* Handle ext_hook */ if (ext_hook == Py_None) { ext_hook = NULL; } if (ext_hook != NULL) { if (!PyCallable_Check(ext_hook)) { PyErr_SetString(PyExc_TypeError, "ext_hook must be callable"); return NULL; } } DecoderState state = { .strict = strict, .dec_hook = dec_hook, .ext_hook = ext_hook }; /* Allocate Any & Struct type nodes (simple, common cases) on the stack, * everything else on the heap */ TypeNode typenode_any = {MS_TYPE_ANY}; TypeNodeSimple typenode_struct; if (type == NULL || type == mod->typing_any) { state.type = &typenode_any; } else if (Py_TYPE(type) == &StructMetaType) { PyObject *info = StructInfo_Convert(type); if (info == NULL) return NULL; bool array_like = ((StructMetaObject *)type)->array_like == OPT_TRUE; typenode_struct.types = array_like ? MS_TYPE_STRUCT_ARRAY : MS_TYPE_STRUCT; typenode_struct.details[0].pointer = info; state.type = (TypeNode *)(&typenode_struct); } else { state.type = TypeNode_Convert(type); if (state.type == NULL) return NULL; } Py_buffer buffer; buffer.buf = NULL; if (PyObject_GetBuffer(buf, &buffer, PyBUF_CONTIG_RO) >= 0) { state.buffer_obj = buf; state.input_start = buffer.buf; state.input_pos = buffer.buf; state.input_end = state.input_pos + buffer.len; res = mpack_decode(&state, state.type, NULL, false); PyBuffer_Release(&buffer); if (res != NULL && mpack_has_trailing_characters(&state)) { Py_CLEAR(res); } } if (state.type == (TypeNode *)&typenode_struct) { Py_DECREF(typenode_struct.details[0].pointer); } else if (state.type != &typenode_any) { TypeNode_Free(state.type); } return res; } /************************************************************************* * JSON Decoder * *************************************************************************/ typedef struct JSONDecoderState { /* Configuration */ TypeNode *type; PyObject *dec_hook; PyObject *float_hook; bool strict; /* Temporary scratch space */ unsigned char *scratch; Py_ssize_t scratch_capacity; Py_ssize_t scratch_len; /* Per-message attributes */ PyObject *buffer_obj; unsigned char *input_start; unsigned char *input_pos; unsigned char *input_end; } JSONDecoderState; typedef struct JSONDecoder { PyObject_HEAD PyObject *orig_type; /* Configuration */ TypeNode *type; char strict; PyObject *dec_hook; PyObject *float_hook; } JSONDecoder; PyDoc_STRVAR(JSONDecoder__doc__, "Decoder(type='Any', *, strict=True, dec_hook=None, float_hook=None)\n" "--\n" "\n" "A JSON decoder.\n" "\n" "Parameters\n" "----------\n" "type : type, optional\n" " A Python type (in type annotation form) to decode the object as. If\n" " provided, the message will be type checked and decoded as the specified\n" " type. Defaults to `Any`, in which case the message will be decoded using\n" " the default JSON types.\n" "strict : bool, optional\n" " Whether type coercion rules should be strict. Setting to False enables a\n" " wider set of coercion rules from string to non-string types for all values.\n" " Default is True.\n" "dec_hook : callable, optional\n" " An optional callback for handling decoding custom types. Should have the\n" " signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the\n" " expected message type, and ``obj`` is the decoded representation composed\n" " of only basic JSON types. This hook should transform ``obj`` into type\n" " ``type``, or raise a ``NotImplementedError`` if unsupported.\n" "float_hook : callable, optional\n" " An optional callback for handling decoding untyped float literals. Should\n" " have the signature ``float_hook(val: str) -> Any``, where ``val`` is the\n" " raw string value of the JSON float. This hook is called to decode any\n" " \"untyped\" float value (e.g. ``typing.Any`` typed). The default is\n" " equivalent to ``float_hook=float``, where all untyped JSON floats are\n" " decoded as python floats. Specifying ``float_hook=decimal.Decimal``\n" " will decode all untyped JSON floats as decimals instead." ); static int JSONDecoder_init(JSONDecoder *self, PyObject *args, PyObject *kwds) { char *kwlist[] = {"type", "strict", "dec_hook", "float_hook", NULL}; MsgspecState *st = msgspec_get_global_state(); PyObject *type = st->typing_any; PyObject *dec_hook = NULL; PyObject *float_hook = NULL; int strict = 1; if (!PyArg_ParseTupleAndKeywords( args, kwds, "|O$pOO", kwlist, &type, &strict, &dec_hook, &float_hook) ) { return -1; } /* Handle dec_hook */ if (dec_hook == Py_None) { dec_hook = NULL; } if (dec_hook != NULL) { if (!PyCallable_Check(dec_hook)) { PyErr_SetString(PyExc_TypeError, "dec_hook must be callable"); return -1; } Py_INCREF(dec_hook); } self->dec_hook = dec_hook; /* Handle float_hook */ if (float_hook == Py_None) { float_hook = NULL; } if (float_hook != NULL) { if (!PyCallable_Check(float_hook)) { PyErr_SetString(PyExc_TypeError, "float_hook must be callable"); return -1; } Py_INCREF(float_hook); } self->float_hook = float_hook; /* Handle strict */ self->strict = strict; /* Handle type */ self->type = TypeNode_Convert(type); if (self->type == NULL) return -1; Py_INCREF(type); self->orig_type = type; return 0; } static int JSONDecoder_traverse(JSONDecoder *self, visitproc visit, void *arg) { int out = TypeNode_traverse(self->type, visit, arg); if (out != 0) return out; Py_VISIT(self->orig_type); Py_VISIT(self->dec_hook); Py_VISIT(self->float_hook); return 0; } static void JSONDecoder_dealloc(JSONDecoder *self) { PyObject_GC_UnTrack(self); TypeNode_Free(self->type); Py_XDECREF(self->orig_type); Py_XDECREF(self->dec_hook); Py_XDECREF(self->float_hook); Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * JSONDecoder_repr(JSONDecoder *self) { int recursive; PyObject *typstr, *out = NULL; recursive = Py_ReprEnter((PyObject *)self); if (recursive != 0) { return (recursive < 0) ? NULL : PyUnicode_FromString("..."); /* cpylint-ignore */ } typstr = PyObject_Repr(self->orig_type); if (typstr != NULL) { out = PyUnicode_FromFormat("msgspec.json.Decoder(%U)", typstr); } Py_XDECREF(typstr); Py_ReprLeave((PyObject *)self); return out; } static MS_INLINE bool json_read1(JSONDecoderState *self, unsigned char *c) { if (MS_UNLIKELY(self->input_pos == self->input_end)) { ms_err_truncated(); return false; } *c = *self->input_pos; self->input_pos += 1; return true; } static MS_INLINE char json_peek_or_null(JSONDecoderState *self) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return '\0'; return *self->input_pos; } static MS_INLINE bool json_peek_skip_ws(JSONDecoderState *self, unsigned char *s) { while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) { ms_err_truncated(); return false; } unsigned char c = *self->input_pos; if (MS_LIKELY(c != ' ' && c != '\n' && c != '\r' && c != '\t')) { *s = c; return true; } self->input_pos++; } } static MS_INLINE bool json_remaining(JSONDecoderState *self, ptrdiff_t remaining) { return self->input_end - self->input_pos >= remaining; } static PyObject * json_err_invalid(JSONDecoderState *self, const char *msg) { PyErr_Format( msgspec_get_global_state()->DecodeError, "JSON is malformed: %s (byte %zd)", msg, (Py_ssize_t)(self->input_pos - self->input_start) ); return NULL; } static MS_INLINE bool json_has_trailing_characters(JSONDecoderState *self) { while (self->input_pos != self->input_end) { unsigned char c = *self->input_pos++; if (MS_UNLIKELY(!(c == ' ' || c == '\n' || c == '\t' || c == '\r'))) { json_err_invalid(self, "trailing characters"); return true; } } return false; } static int json_skip(JSONDecoderState *self); static PyObject * json_decode( JSONDecoderState *self, TypeNode *type, PathNode *path ); static PyObject * json_decode_none(JSONDecoderState *self, TypeNode *type, PathNode *path) { self->input_pos++; /* Already checked as 'n' */ if (MS_UNLIKELY(!json_remaining(self, 3))) { ms_err_truncated(); return NULL; } unsigned char c1 = *self->input_pos++; unsigned char c2 = *self->input_pos++; unsigned char c3 = *self->input_pos++; if (MS_UNLIKELY(c1 != 'u' || c2 != 'l' || c3 != 'l')) { return json_err_invalid(self, "invalid character"); } if (type->types & (MS_TYPE_ANY | MS_TYPE_NONE)) { Py_INCREF(Py_None); return Py_None; } return ms_validation_error("null", type, path); } static PyObject * json_decode_true(JSONDecoderState *self, TypeNode *type, PathNode *path) { self->input_pos++; /* Already checked as 't' */ if (MS_UNLIKELY(!json_remaining(self, 3))) { ms_err_truncated(); return NULL; } unsigned char c1 = *self->input_pos++; unsigned char c2 = *self->input_pos++; unsigned char c3 = *self->input_pos++; if (MS_UNLIKELY(c1 != 'r' || c2 != 'u' || c3 != 'e')) { return json_err_invalid(self, "invalid character"); } if (type->types & (MS_TYPE_ANY | MS_TYPE_BOOL)) { Py_INCREF(Py_True); return Py_True; } return ms_validation_error("bool", type, path); } static PyObject * json_decode_false(JSONDecoderState *self, TypeNode *type, PathNode *path) { self->input_pos++; /* Already checked as 'f' */ if (MS_UNLIKELY(!json_remaining(self, 4))) { ms_err_truncated(); return NULL; } unsigned char c1 = *self->input_pos++; unsigned char c2 = *self->input_pos++; unsigned char c3 = *self->input_pos++; unsigned char c4 = *self->input_pos++; if (MS_UNLIKELY(c1 != 'a' || c2 != 'l' || c3 != 's' || c4 != 'e')) { return json_err_invalid(self, "invalid character"); } if (type->types & (MS_TYPE_ANY | MS_TYPE_BOOL)) { Py_INCREF(Py_False); return Py_False; } return ms_validation_error("bool", type, path); } #define JS_SCRATCH_MAX_SIZE 1024 static int json_scratch_resize(JSONDecoderState *state, Py_ssize_t size) { unsigned char *temp = PyMem_Realloc(state->scratch, size); if (MS_UNLIKELY(temp == NULL)) { PyErr_NoMemory(); return -1; } state->scratch = temp; state->scratch_capacity = size; return 0; } static MS_NOINLINE int json_scratch_expand(JSONDecoderState *state, Py_ssize_t required) { size_t new_size = Py_MAX(8, 1.5 * required); return json_scratch_resize(state, new_size); } static int json_scratch_extend(JSONDecoderState *state, const void *buf, Py_ssize_t size) { Py_ssize_t required = state->scratch_len + size; if (MS_UNLIKELY(required >= state->scratch_capacity)) { if (MS_UNLIKELY(json_scratch_expand(state, required) < 0)) return -1; } memcpy(state->scratch + state->scratch_len, buf, size); state->scratch_len += size; return 0; } /* -1: '\', '"', and forbidden characters * 0: ascii * 1: non-ascii */ static const int8_t char_types[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; /* Is char `"`, `\`, or nonascii? */ static MS_INLINE bool char_is_special_or_nonascii(unsigned char c) { return char_types[c] != 0; } /* Is char `"` or `\`? */ static MS_INLINE bool char_is_special(unsigned char c) { return char_types[c] < 0; } static int json_read_codepoint(JSONDecoderState *self, unsigned int *out) { unsigned char c; unsigned int cp = 0; if (!json_remaining(self, 4)) return ms_err_truncated(); for (int i = 0; i < 4; i++) { c = *self->input_pos++; if (c >= '0' && c <= '9') { c -= '0'; } else if (c >= 'a' && c <= 'f') { c = c - 'a' + 10; } else if (c >= 'A' && c <= 'F') { c = c - 'A' + 10; } else { json_err_invalid(self, "invalid character in unicode escape"); return -1; } cp = (cp << 4) + c; } *out = cp; return 0; } static MS_NOINLINE int json_handle_unicode_escape(JSONDecoderState *self) { unsigned int cp; if (json_read_codepoint(self, &cp) < 0) return -1; if (0xDC00 <= cp && cp <= 0xDFFF) { json_err_invalid(self, "invalid utf-16 surrogate pair"); return -1; } else if (0xD800 <= cp && cp <= 0xDBFF) { /* utf-16 pair, parse 2nd pair */ unsigned int cp2; if (!json_remaining(self, 6)) return ms_err_truncated(); if (self->input_pos[0] != '\\' || self->input_pos[1] != 'u') { json_err_invalid(self, "unexpected end of escaped utf-16 surrogate pair"); return -1; } self->input_pos += 2; if (json_read_codepoint(self, &cp2) < 0) return -1; if (cp2 < 0xDC00 || cp2 > 0xDFFF) { json_err_invalid(self, "invalid utf-16 surrogate pair"); return -1; } cp = 0x10000 + (((cp - 0xD800) << 10) | (cp2 - 0xDC00)); } /* Encode the codepoint as utf-8 */ unsigned char *p = self->scratch + self->scratch_len; if (cp < 0x80) { *p++ = cp; self->scratch_len += 1; } else if (cp < 0x800) { *p++ = 0xC0 | (cp >> 6); *p++ = 0x80 | (cp & 0x3F); self->scratch_len += 2; } else if (cp < 0x10000) { *p++ = 0xE0 | (cp >> 12); *p++ = 0x80 | ((cp >> 6) & 0x3F); *p++ = 0x80 | (cp & 0x3F); self->scratch_len += 3; } else { *p++ = 0xF0 | (cp >> 18); *p++ = 0x80 | ((cp >> 12) & 0x3F); *p++ = 0x80 | ((cp >> 6) & 0x3F); *p++ = 0x80 | (cp & 0x3F); self->scratch_len += 4; } return 0; } #define parse_ascii_pre(i) \ if (MS_UNLIKELY(char_is_special_or_nonascii(self->input_pos[i]))) goto parse_ascii_##i; #define parse_ascii_post(i) \ parse_ascii_##i: \ self->input_pos += i; \ goto parse_ascii_end; #define parse_unicode_pre(i) \ if (MS_UNLIKELY(char_is_special(self->input_pos[i]))) goto parse_unicode_##i; #define parse_unicode_post(i) \ parse_unicode_##i: \ self->input_pos += i; \ goto parse_unicode_end; static MS_NOINLINE Py_ssize_t json_decode_string_view_copy( JSONDecoderState *self, char **out, bool *is_ascii, unsigned char *start ) { unsigned char c; self->scratch_len = 0; top: OPT_FORCE_RELOAD(*self->input_pos); c = *self->input_pos; if (c == '\\') { /* Write the current block to scratch */ Py_ssize_t block_size = self->input_pos - start; /* An escape string requires at most 4 bytes to decode */ Py_ssize_t required = self->scratch_len + block_size + 4; if (MS_UNLIKELY(required >= self->scratch_capacity)) { if (MS_UNLIKELY(json_scratch_expand(self, required) < 0)) return -1; } memcpy(self->scratch + self->scratch_len, start, block_size); self->scratch_len += block_size; self->input_pos++; if (!json_read1(self, &c)) return -1; switch (c) { case 'n': { *(self->scratch + self->scratch_len) = '\n'; self->scratch_len++; break; } case '"': { *(self->scratch + self->scratch_len) = '"'; self->scratch_len++; break; } case 't': { *(self->scratch + self->scratch_len) = '\t'; self->scratch_len++; break; } case 'r': { *(self->scratch + self->scratch_len) = '\r'; self->scratch_len++; break; } case '\\': { *(self->scratch + self->scratch_len) = '\\'; self->scratch_len++; break; } case '/': { *(self->scratch + self->scratch_len) = '/'; self->scratch_len++; break; } case 'b': { *(self->scratch + self->scratch_len) = '\b'; self->scratch_len++; break; } case 'f': { *(self->scratch + self->scratch_len) = '\f'; self->scratch_len++; break; } case 'u': { *is_ascii = false; if (json_handle_unicode_escape(self) < 0) return -1; break; } default: json_err_invalid(self, "invalid escape character in string"); return -1; } start = self->input_pos; } else if (c == '"') { if (json_scratch_extend(self, start, self->input_pos - start) < 0) return -1; self->input_pos++; *out = (char *)(self->scratch); return self->scratch_len; } else { json_err_invalid(self, "invalid character"); return -1; } /* Loop until `"`, `\`, or a non-ascii character */ while (self->input_end - self->input_pos >= 8) { repeat8(parse_ascii_pre); self->input_pos += 8; continue; repeat8(parse_ascii_post); } while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); if (MS_UNLIKELY(char_is_special_or_nonascii(*self->input_pos))) break; self->input_pos++; } parse_ascii_end: OPT_FORCE_RELOAD(*self->input_pos); if (MS_UNLIKELY(*self->input_pos & 0x80)) { *is_ascii = false; /* Loop until `"` or `\` */ while (self->input_end - self->input_pos >= 8) { repeat8(parse_unicode_pre); self->input_pos += 8; continue; repeat8(parse_unicode_post); } while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); if (MS_UNLIKELY(char_is_special(*self->input_pos))) break; self->input_pos++; } } parse_unicode_end: goto top; } static Py_ssize_t json_decode_string_view(JSONDecoderState *self, char **out, bool *is_ascii) { self->input_pos++; /* Skip '"' */ unsigned char *start = self->input_pos; /* Loop until `"`, `\`, or a non-ascii character */ while (self->input_end - self->input_pos >= 8) { repeat8(parse_ascii_pre); self->input_pos += 8; continue; repeat8(parse_ascii_post); } while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); if (MS_UNLIKELY(char_is_special_or_nonascii(*self->input_pos))) break; self->input_pos++; } parse_ascii_end: OPT_FORCE_RELOAD(*self->input_pos); if (MS_LIKELY(*self->input_pos == '"')) { Py_ssize_t size = self->input_pos - start; self->input_pos++; *out = (char *)start; return size; } if (MS_UNLIKELY(*self->input_pos & 0x80)) { *is_ascii = false; /* Loop until `"` or `\` */ while (self->input_end - self->input_pos >= 8) { repeat8(parse_unicode_pre); self->input_pos += 8; continue; repeat8(parse_unicode_post); } while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); if (MS_UNLIKELY(char_is_special(*self->input_pos))) break; self->input_pos++; } } parse_unicode_end: OPT_FORCE_RELOAD(*self->input_pos); if (MS_LIKELY(*self->input_pos == '"')) { Py_ssize_t size = self->input_pos - start; self->input_pos++; *out = (char *)start; return size; } return json_decode_string_view_copy(self, out, is_ascii, start); } static int json_skip_string(JSONDecoderState *self) { self->input_pos++; /* Skip '"' */ parse_unicode: /* Loop until `"` or `\` */ while (self->input_end - self->input_pos >= 8) { repeat8(parse_unicode_pre); self->input_pos += 8; continue; repeat8(parse_unicode_post); } while (true) { if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); if (MS_UNLIKELY(char_is_special(*self->input_pos))) break; self->input_pos++; } parse_unicode_end: OPT_FORCE_RELOAD(*self->input_pos); if (MS_LIKELY(*self->input_pos == '"')) { self->input_pos++; return 0; } else if (*self->input_pos == '\\') { self->input_pos++; if (MS_UNLIKELY(self->input_pos == self->input_end)) return ms_err_truncated(); switch (*self->input_pos) { case '"': case '\\': case '/': case 'b': case 'f': case 'n': case 'r': case 't': self->input_pos++; break; case 'u': { self->input_pos++; unsigned int cp; if (json_read_codepoint(self, &cp) < 0) return -1; if (0xDC00 <= cp && cp <= 0xDFFF) { json_err_invalid(self, "invalid utf-16 surrogate pair"); return -1; } else if (0xD800 <= cp && cp <= 0xDBFF) { /* utf-16 pair, parse 2nd pair */ unsigned int cp2; if (!json_remaining(self, 6)) return ms_err_truncated(); if (self->input_pos[0] != '\\' || self->input_pos[1] != 'u') { json_err_invalid(self, "unexpected end of hex escape"); return -1; } self->input_pos += 2; if (json_read_codepoint(self, &cp2) < 0) return -1; if (cp2 < 0xDC00 || cp2 > 0xDFFF) { json_err_invalid(self, "invalid utf-16 surrogate pair"); return -1; } cp = 0x10000 + (((cp - 0xD800) << 10) | (cp2 - 0xDC00)); } break; } default: { json_err_invalid(self, "invalid escaped character"); return -1; } } goto parse_unicode; } else { json_err_invalid(self, "invalid character"); return -1; } } #undef parse_ascii_pre #undef parse_ascii_post #undef parse_unicode_pre #undef parse_unicode_post /* A table of the corresponding base64 value for each character, or -1 if an * invalid character in the base64 alphabet (note the padding char '=' is * handled elsewhere, so is marked as invalid here as well) */ static const uint8_t base64_decode_table[] = { -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, }; static PyObject * json_decode_binary( const char *buffer, Py_ssize_t size, TypeNode *type, PathNode *path ) { PyObject *out = NULL; char *bin_buffer; Py_ssize_t bin_size, i; if (size % 4 != 0) goto invalid; int npad = 0; if (size > 0 && buffer[size - 1] == '=') npad++; if (size > 1 && buffer[size - 2] == '=') npad++; bin_size = (size / 4) * 3 - npad; if (!ms_passes_bytes_constraints(bin_size, type, path)) return NULL; if (type->types & MS_TYPE_BYTES) { out = PyBytes_FromStringAndSize(NULL, bin_size); if (out == NULL) return NULL; bin_buffer = PyBytes_AS_STRING(out); } else if (type->types & MS_TYPE_BYTEARRAY) { out = PyByteArray_FromStringAndSize(NULL, bin_size); if (out == NULL) return NULL; bin_buffer = PyByteArray_AS_STRING(out); } else { PyObject *temp = PyBytes_FromStringAndSize(NULL, bin_size); if (temp == NULL) return NULL; bin_buffer = PyBytes_AS_STRING(temp); out = PyMemoryView_FromObject(temp); Py_DECREF(temp); if (out == NULL) return NULL; } int quad = 0; uint8_t left_c = 0; for (i = 0; i < size - npad; i++) { uint8_t c = base64_decode_table[(uint8_t)(buffer[i])]; if (c >= 64) goto invalid; switch (quad) { case 0: quad = 1; left_c = c; break; case 1: quad = 2; *bin_buffer++ = (left_c << 2) | (c >> 4); left_c = c & 0x0f; break; case 2: quad = 3; *bin_buffer++ = (left_c << 4) | (c >> 2); left_c = c & 0x03; break; case 3: quad = 0; *bin_buffer++ = (left_c << 6) | c; left_c = 0; break; } } return out; invalid: Py_XDECREF(out); return ms_error_with_path("Invalid base64 encoded string%U", path); } static PyObject * json_decode_string(JSONDecoderState *self, TypeNode *type, PathNode *path) { char *view = NULL; bool is_ascii = true; Py_ssize_t size = json_decode_string_view(self, &view, &is_ascii); if (size < 0) return NULL; if (MS_LIKELY(type->types & (MS_TYPE_STR | MS_TYPE_ANY))) { PyObject *out; if (MS_LIKELY(is_ascii)) { out = PyUnicode_New(size, 127); memcpy(ascii_get_buffer(out), view, size); } else { out = PyUnicode_DecodeUTF8(view, size, NULL); } return ms_check_str_constraints(out, type, path); } else if (MS_UNLIKELY(!self->strict)) { bool invalid = false; PyObject *out = ms_decode_str_lax(view, size, type, path, &invalid); if (!invalid) return out; } if (MS_UNLIKELY(type->types & MS_TYPE_DATETIME)) { return ms_decode_datetime_from_str(view, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_DATE)) { return ms_decode_date(view, size, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_TIME)) { return ms_decode_time(view, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_TIMEDELTA)) { return ms_decode_timedelta(view, size, type, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_UUID)) { return ms_decode_uuid_from_str(view, size, path); } else if (MS_UNLIKELY(type->types & MS_TYPE_DECIMAL)) { return ms_decode_decimal(view, size, is_ascii, path, NULL); } else if ( MS_UNLIKELY(type->types & (MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW) ) ) { return json_decode_binary(view, size, type, path); } else if (MS_UNLIKELY(type->types & (MS_TYPE_ENUM | MS_TYPE_STRLITERAL))) { return ms_decode_str_enum_or_literal(view, size, type, path); } return ms_validation_error("str", type, path); } static PyObject * json_decode_dict_key_fallback( JSONDecoderState *self, const char *view, Py_ssize_t size, bool is_ascii, TypeNode *type, PathNode *path ) { if (type->types & (MS_TYPE_STR | MS_TYPE_ANY)) { PyObject *out; if (is_ascii) { out = PyUnicode_New(size, 127); if (MS_UNLIKELY(out == NULL)) return NULL; memcpy(ascii_get_buffer(out), view, size); } else { out = PyUnicode_DecodeUTF8(view, size, NULL); } if (MS_UNLIKELY(type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC))) { return ms_decode_custom(out, self->dec_hook, type, path); } return ms_check_str_constraints(out, type, path); } if (type->types & ( MS_TYPE_INT | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL | MS_TYPE_FLOAT | MS_TYPE_DECIMAL | ((!self->strict) * (MS_TYPE_DATETIME | MS_TYPE_TIMEDELTA)) ) ) { PyObject *out; if (maybe_parse_number(view, size, type, path, self->strict, &out)) { return out; } } if (type->types & (MS_TYPE_ENUM | MS_TYPE_STRLITERAL)) { return ms_decode_str_enum_or_literal(view, size, type, path); } else if (type->types & MS_TYPE_UUID) { return ms_decode_uuid_from_str(view, size, path); } else if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_str(view, size, type, path); } else if (type->types & MS_TYPE_DATE) { return ms_decode_date(view, size, path); } else if (type->types & MS_TYPE_TIME) { return ms_decode_time(view, size, type, path); } else if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta(view, size, type, path); } else if (type->types & (MS_TYPE_BYTES | MS_TYPE_MEMORYVIEW)) { return json_decode_binary(view, size, type, path); } else { return ms_validation_error("str", type, path); } } static PyObject * json_decode_dict_key(JSONDecoderState *self, TypeNode *type, PathNode *path) { bool is_ascii = true; char *view = NULL; Py_ssize_t size; bool is_str = type->types == MS_TYPE_ANY || type->types == MS_TYPE_STR; size = json_decode_string_view(self, &view, &is_ascii); if (size < 0) return NULL; bool cacheable = is_str && is_ascii && size > 0 && size <= STRING_CACHE_MAX_STRING_LENGTH; if (MS_UNLIKELY(!cacheable)) { return json_decode_dict_key_fallback(self, view, size, is_ascii, type, path); } uint32_t hash = murmur2(view, size); uint32_t index = hash % STRING_CACHE_SIZE; PyObject *existing = string_cache[index]; if (MS_LIKELY(existing != NULL)) { Py_ssize_t e_size = ((PyASCIIObject *)existing)->length; char *e_str = ascii_get_buffer(existing); if (MS_LIKELY(size == e_size && memcmp(view, e_str, size) == 0)) { Py_INCREF(existing); return existing; } } /* Create a new ASCII str object */ PyObject *new = PyUnicode_New(size, 127); if (MS_UNLIKELY(new == NULL)) return NULL; memcpy(ascii_get_buffer(new), view, size); /* Swap out the str in the cache */ Py_XDECREF(existing); Py_INCREF(new); string_cache[index] = new; return new; } static PyObject * json_decode_list(JSONDecoderState *self, TypeNode *type, TypeNode *el_type, PathNode *path) { unsigned char c; bool first = true; PathNode el_path = {path, 0, NULL}; self->input_pos++; /* Skip '[' */ PyObject *out = PyList_New(0); if (out == NULL) return NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; /* Parse ']' or ',', then peek the next character */ if (c == ']') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or ']'"); goto error; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); goto error; } /* Parse item */ PyObject *item = json_decode(self, el_type, &el_path); if (item == NULL) goto error; el_path.index++; /* Append item to list */ if (MS_LIKELY((LIST_CAPACITY(out) > Py_SIZE(out)))) { PyList_SET_ITEM(out, Py_SIZE(out), item); Py_SET_SIZE(out, Py_SIZE(out) + 1); } else { int status = PyList_Append(out, item); Py_DECREF(item); if (MS_UNLIKELY(status < 0)) goto error; } } if (MS_UNLIKELY(!ms_passes_array_constraints(PyList_GET_SIZE(out), type, path))) { goto error; } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static PyObject * json_decode_set( JSONDecoderState *self, TypeNode *type, TypeNode *el_type, PathNode *path ) { PyObject *out, *item = NULL; unsigned char c; bool first = true; PathNode el_path = {path, 0, NULL}; self->input_pos++; /* Skip '[' */ out = (type->types & MS_TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL); if (out == NULL) return NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; /* Parse ']' or ',', then peek the next character */ if (c == ']') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or ']'"); goto error; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); goto error; } /* Parse item */ item = json_decode(self, el_type, &el_path); if (item == NULL) goto error; el_path.index++; /* Append item to set */ if (PySet_Add(out, item) < 0) goto error; Py_CLEAR(item); } if (MS_UNLIKELY(!ms_passes_array_constraints(PySet_GET_SIZE(out), type, path))) { goto error; } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); Py_XDECREF(item); return NULL; } static PyObject * json_decode_vartuple(JSONDecoderState *self, TypeNode *type, TypeNode *el_type, PathNode *path) { PyObject *list, *item, *out = NULL; Py_ssize_t size, i; list = json_decode_list(self, type, el_type, path); if (list == NULL) return NULL; size = PyList_GET_SIZE(list); out = PyTuple_New(size); if (out != NULL) { for (i = 0; i < size; i++) { item = PyList_GET_ITEM(list, i); PyTuple_SET_ITEM(out, i, item); PyList_SET_ITEM(list, i, NULL); /* Drop reference in old list */ } } Py_DECREF(list); return out; } static PyObject * json_decode_fixtuple(JSONDecoderState *self, TypeNode *type, PathNode *path) { PyObject *out, *item; unsigned char c; bool first = true; PathNode el_path = {path, 0, NULL}; Py_ssize_t i = 0, offset, fixtuple_size; TypeNode_get_fixtuple(type, &offset, &fixtuple_size); self->input_pos++; /* Skip '[' */ out = PyTuple_New(fixtuple_size); if (out == NULL) return NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; /* Parse ']' or ',', then peek the next character */ if (c == ']') { self->input_pos++; if (MS_UNLIKELY(i < fixtuple_size)) goto size_error; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or ']'"); goto error; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); goto error; } /* Check we don't have too many elements */ if (MS_UNLIKELY(i >= fixtuple_size)) goto size_error; /* Parse item */ item = json_decode(self, type->details[offset + i].pointer, &el_path); if (item == NULL) goto error; el_path.index++; /* Add item to tuple */ PyTuple_SET_ITEM(out, i, item); i++; } Py_LeaveRecursiveCall(); return out; size_error: ms_raise_validation_error( path, "Expected `array` of length %zd%U", fixtuple_size ); error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static PyObject * json_decode_namedtuple(JSONDecoderState *self, TypeNode *type, PathNode *path) { unsigned char c; bool first = true; Py_ssize_t nfields, ndefaults, nrequired; NamedTupleInfo *info = TypeNode_get_namedtuple_info(type); nfields = Py_SIZE(info); ndefaults = info->defaults == NULL ? 0 : PyTuple_GET_SIZE(info->defaults); nrequired = nfields - ndefaults; self->input_pos++; /* Skip '[' */ if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyTypeObject *nt_type = (PyTypeObject *)(info->class); PyObject *out = nt_type->tp_alloc(nt_type, nfields); if (out == NULL) goto error; for (Py_ssize_t i = 0; i < nfields; i++) { PyTuple_SET_ITEM(out, i, NULL); } Py_ssize_t i = 0; while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; /* Parse ']' or ',', then peek the next character */ if (c == ']') { self->input_pos++; if (MS_UNLIKELY(i < nrequired)) goto size_error; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or ']'"); goto error; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); goto error; } /* Check we don't have too many elements */ if (MS_UNLIKELY(i >= nfields)) goto size_error; /* Parse item */ PathNode el_path = {path, i, NULL}; PyObject *item = json_decode(self, info->types[i], &el_path); if (item == NULL) goto error; /* Add item to tuple */ PyTuple_SET_ITEM(out, i, item); i++; } Py_LeaveRecursiveCall(); /* Fill in defaults */ for (; i < nfields; i++) { PyObject *item = PyTuple_GET_ITEM(info->defaults, i - nrequired); Py_INCREF(item); PyTuple_SET_ITEM(out, i, item); } return out; size_error: if (ndefaults == 0) { ms_raise_validation_error( path, "Expected `array` of length %zd%U", nfields ); } else { ms_raise_validation_error( path, "Expected `array` of length %zd to %zd%U", nrequired, nfields ); } error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static PyObject * json_decode_struct_array_inner( JSONDecoderState *self, StructInfo *info, PathNode *path, Py_ssize_t starting_index ) { Py_ssize_t nfields, ndefaults, nrequired, npos, i = 0; PyObject *out, *item = NULL; unsigned char c; bool is_gc, should_untrack; bool first = starting_index == 0; StructMetaObject *st_type = info->class; PathNode item_path = {path, starting_index}; out = Struct_alloc((PyTypeObject *)(st_type)); if (out == NULL) return NULL; nfields = PyTuple_GET_SIZE(st_type->struct_encode_fields); ndefaults = PyTuple_GET_SIZE(st_type->struct_defaults); nrequired = nfields - st_type->n_trailing_defaults; npos = nfields - ndefaults; is_gc = MS_TYPE_IS_GC(st_type); should_untrack = is_gc; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; /* Parse ']' or ',', then peek the next character */ if (c == ']') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or ']'"); goto error; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); goto error; } if (MS_LIKELY(i < nfields)) { /* Parse item */ item = json_decode(self, info->types[i], &item_path); if (MS_UNLIKELY(item == NULL)) goto error; Struct_set_index(out, i, item); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(item); } i++; item_path.index++; } else { if (MS_UNLIKELY(st_type->forbid_unknown_fields == OPT_TRUE)) { ms_raise_validation_error( path, "Expected `array` of at most length %zd", nfields ); goto error; } else { /* Skip trailing fields */ if (json_skip(self) < 0) goto error; } } } /* Check for missing required fields */ if (i < nrequired) { ms_raise_validation_error( path, "Expected `array` of at least length %zd, got %zd%U", nrequired + starting_index, i + starting_index ); goto error; } /* Fill in missing fields with defaults */ for (; i < nfields; i++) { item = get_default( PyTuple_GET_ITEM(st_type->struct_defaults, i - npos) ); if (item == NULL) goto error; Struct_set_index(out, i, item); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(item); } } if (Struct_decode_post_init(st_type, out, path) < 0) goto error; Py_LeaveRecursiveCall(); if (is_gc && !should_untrack) PyObject_GC_Track(out); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } /* Decode an integer. If the value fits in an int64_t, it will be stored in * `out`, otherwise it will be stored in `uout`. A return value of -1 indicates * an error. */ static int json_decode_cint(JSONDecoderState *self, int64_t *out, uint64_t *uout, PathNode *path) { uint64_t mantissa = 0; bool is_negative = false; unsigned char c; unsigned char *orig_input_pos = self->input_pos; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return -1; /* Parse minus sign (if present) */ if (c == '-') { self->input_pos++; c = json_peek_or_null(self); is_negative = true; } /* Parse integer */ if (MS_UNLIKELY(c == '0')) { /* Ensure at most one leading zero */ self->input_pos++; c = json_peek_or_null(self); if (MS_UNLIKELY(is_digit(c))) { json_err_invalid(self, "invalid number"); return -1; } } else { /* Parse the integer part of the number. * * We can read the first 19 digits safely into a uint64 without * checking for overflow. Removing overflow checks from the loop gives * a measurable performance boost. */ size_t remaining = self->input_end - self->input_pos; size_t n_safe = Py_MIN(19, remaining); while (n_safe) { c = *self->input_pos; if (!is_digit(c)) goto end_integer; self->input_pos++; n_safe--; mantissa = mantissa * 10 + (uint64_t)(c - '0'); } if (MS_UNLIKELY(remaining > 19)) { /* Reading a 20th digit may or may not cause overflow. Any * additional digits definitely will. Read the 20th digit (and * check for a 21st), taking the slow path upon overflow. */ c = *self->input_pos; if (MS_UNLIKELY(is_digit(c))) { self->input_pos++; uint64_t mantissa2 = mantissa * 10 + (uint64_t)(c - '0'); bool overflowed = (mantissa2 < mantissa) || ((mantissa2 - (uint64_t)(c - '0')) / 10) != mantissa; if (MS_UNLIKELY(overflowed || is_digit(json_peek_or_null(self)))) { goto error_not_int; } mantissa = mantissa2; c = json_peek_or_null(self); } } end_integer: /* There must be at least one digit */ if (MS_UNLIKELY(mantissa == 0)) goto error_not_int; } if (c == '.' || c == 'e' || c == 'E') goto error_not_int; if (is_negative) { if (mantissa > 1ull << 63) goto error_not_int; *out = -1 * (int64_t)mantissa; } else { if (mantissa > LLONG_MAX) { *uout = mantissa; } else { *out = mantissa; } } return 0; error_not_int: /* Use skip to catch malformed JSON */ self->input_pos = orig_input_pos; if (json_skip(self) < 0) return -1; ms_error_with_path("Expected `int`%U", path); return -1; } static Py_ssize_t json_decode_cstr(JSONDecoderState *self, char **out, PathNode *path) { unsigned char c; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return -1; if (c != '"') { /* Use skip to catch malformed JSON */ if (json_skip(self) < 0) return -1; /* JSON is valid but the wrong type */ ms_error_with_path("Expected `str`%U", path); return -1; } bool is_ascii = true; return json_decode_string_view(self, out, &is_ascii); } static int json_ensure_array_nonempty( JSONDecoderState *self, StructMetaObject *st_type, PathNode *path ) { unsigned char c; /* Check for an early end to the array */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return -1; if (c == ']') { Py_ssize_t expected_size; if (st_type == NULL) { /* If we don't know the type, the most we know is that the minimum * size is 1 */ expected_size = 1; } else { /* n_fields - n_optional_fields + 1 tag */ expected_size = PyTuple_GET_SIZE(st_type->struct_encode_fields) - PyTuple_GET_SIZE(st_type->struct_defaults) + 1; } ms_raise_validation_error( path, "Expected `array` of at least length %zd, got 0%U", expected_size ); return -1; } return 0; } static int json_ensure_tag_matches( JSONDecoderState *self, PathNode *path, PyObject *expected_tag ) { if (PyUnicode_CheckExact(expected_tag)) { char *tag = NULL; Py_ssize_t tag_size; tag_size = json_decode_cstr(self, &tag, path); if (tag_size < 0) return -1; /* Check that tag matches expected tag value */ Py_ssize_t expected_size; const char *expected_str = unicode_str_and_size_nocheck( expected_tag, &expected_size ); if (tag_size != expected_size || memcmp(tag, expected_str, expected_size) != 0) { /* Tag doesn't match the expected value, error nicely */ ms_invalid_cstr_value(tag, tag_size, path); return -1; } } else { int64_t tag = 0; uint64_t utag = 0; if (json_decode_cint(self, &tag, &utag, path) < 0) return -1; int64_t expected = PyLong_AsLongLong(expected_tag); /* Tags must be int64s, if utag != 0 then we know the tags don't match. * We parse the full uint64 value only to validate the message and * raise a nice error */ if (utag != 0) { ms_invalid_cuint_value(utag, path); return -1; } if (tag != expected) { ms_invalid_cint_value(tag, path); return -1; } } return 0; } static StructInfo * json_decode_tag_and_lookup_type( JSONDecoderState *self, Lookup *lookup, PathNode *path ) { StructInfo *out = NULL; if (Lookup_IsStrLookup(lookup)) { Py_ssize_t tag_size; char *tag = NULL; tag_size = json_decode_cstr(self, &tag, path); if (tag_size < 0) return NULL; out = (StructInfo *)StrLookup_Get((StrLookup *)lookup, tag, tag_size); if (out == NULL) { ms_invalid_cstr_value(tag, tag_size, path); } } else { int64_t tag = 0; uint64_t utag = 0; if (json_decode_cint(self, &tag, &utag, path) < 0) return NULL; if (utag == 0) { out = (StructInfo *)IntLookup_GetInt64((IntLookup *)lookup, tag); if (out == NULL) { ms_invalid_cint_value(tag, path); } } else { /* tags can't be uint64 values, we only decode to give a nice error */ ms_invalid_cuint_value(utag, path); } } return out; } static PyObject * json_decode_struct_array( JSONDecoderState *self, TypeNode *type, PathNode *path ) { Py_ssize_t starting_index = 0; StructInfo *info = TypeNode_get_struct_info(type); self->input_pos++; /* Skip '[' */ /* If this is a tagged struct, first read and validate the tag */ if (info->class->struct_tag_value != NULL) { PathNode tag_path = {path, 0}; if (json_ensure_array_nonempty(self, info->class, path) < 0) return NULL; if (json_ensure_tag_matches(self, &tag_path, info->class->struct_tag_value) < 0) return NULL; starting_index = 1; } /* Decode the rest of the struct */ return json_decode_struct_array_inner(self, info, path, starting_index); } static PyObject * json_decode_struct_array_union( JSONDecoderState *self, TypeNode *type, PathNode *path ) { PathNode tag_path = {path, 0}; Lookup *lookup = TypeNode_get_struct_union(type); self->input_pos++; /* Skip '[' */ /* Decode & lookup struct type from tag */ if (json_ensure_array_nonempty(self, NULL, path) < 0) return NULL; StructInfo *info = json_decode_tag_and_lookup_type(self, lookup, &tag_path); if (info == NULL) return NULL; /* Finish decoding the rest of the struct */ return json_decode_struct_array_inner(self, info, path, 1); } static PyObject * json_decode_array( JSONDecoderState *self, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_ANY) { TypeNode type_any = {MS_TYPE_ANY}; return json_decode_list(self, type, &type_any, path); } else if (type->types & MS_TYPE_LIST) { return json_decode_list(self, type, TypeNode_get_array(type), path); } else if (type->types & (MS_TYPE_SET | MS_TYPE_FROZENSET)) { return json_decode_set(self, type, TypeNode_get_array(type), path); } else if (type->types & MS_TYPE_VARTUPLE) { return json_decode_vartuple(self, type, TypeNode_get_array(type), path); } else if (type->types & MS_TYPE_FIXTUPLE) { return json_decode_fixtuple(self, type, path); } else if (type->types & MS_TYPE_NAMEDTUPLE) { return json_decode_namedtuple(self, type, path); } else if (type->types & MS_TYPE_STRUCT_ARRAY) { return json_decode_struct_array(self, type, path); } else if (type->types & MS_TYPE_STRUCT_ARRAY_UNION) { return json_decode_struct_array_union(self, type, path); } return ms_validation_error("array", type, path); } static PyObject * json_decode_dict( JSONDecoderState *self, TypeNode *type, TypeNode *key_type, TypeNode *val_type, PathNode *path ) { PyObject *out, *key = NULL, *val = NULL; unsigned char c; bool first = true; PathNode key_path = {path, PATH_KEY, NULL}; PathNode val_path = {path, PATH_ELLIPSIS, NULL}; self->input_pos++; /* Skip '{' */ out = PyDict_New(); if (out == NULL) return NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { /* Parse '}' or ',', then peek the next character */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c == '}') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or '}'"); goto error; } /* Parse a string key */ if (c == '"') { key = json_decode_dict_key(self, key_type, &key_path); if (key == NULL) goto error; } else if (c == '}') { json_err_invalid(self, "trailing comma in object"); goto error; } else { json_err_invalid(self, "object keys must be strings"); goto error; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c != ':') { json_err_invalid(self, "expected ':'"); goto error; } self->input_pos++; /* Parse value */ val = json_decode(self, val_type, &val_path); if (val == NULL) goto error; /* Add item to dict */ if (MS_UNLIKELY(PyDict_SetItem(out, key, val) < 0)) goto error; Py_CLEAR(key); Py_CLEAR(val); } if (MS_UNLIKELY(!ms_passes_map_constraints(PyDict_GET_SIZE(out), type, path))) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(key); Py_XDECREF(val); Py_DECREF(out); return NULL; } static PyObject * json_decode_typeddict( JSONDecoderState *self, TypeNode *type, PathNode *path ) { PyObject *out; unsigned char c; char *key = NULL; bool first = true; Py_ssize_t key_size, nrequired = 0, pos = 0; TypedDictInfo *info = TypeNode_get_typeddict_info(type); self->input_pos++; /* Skip '{' */ if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; out = PyDict_New(); if (out == NULL) goto error; while (true) { /* Parse '}' or ',', then peek the next character */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c == '}') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or '}'"); goto error; } /* Parse a string key */ if (c == '"') { bool is_ascii = true; key_size = json_decode_string_view(self, &key, &is_ascii); if (key_size < 0) goto error; } else if (c == '}') { json_err_invalid(self, "trailing comma in object"); goto error; } else { json_err_invalid(self, "object keys must be strings"); goto error; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c != ':') { json_err_invalid(self, "expected ':'"); goto error; } self->input_pos++; /* Parse value */ TypeNode *field_type; PyObject *field = TypedDictInfo_lookup_key(info, key, key_size, &field_type, &pos); if (field != NULL) { PathNode field_path = {path, PATH_STR, field}; PyObject *val = json_decode(self, field_type, &field_path); if (val == NULL) goto error; /* We want to keep a count of required fields we've decoded. Since * duplicates can occur, we stash the current dict size, then only * increment if the dict size has changed _and_ the field is * required. */ Py_ssize_t cur_size = PyDict_GET_SIZE(out); int status = PyDict_SetItem(out, field, val); /* Always decref value, no need to decref key since it's a borrowed * reference. */ Py_DECREF(val); if (status < 0) goto error; if ((PyDict_GET_SIZE(out) != cur_size) && (field_type->types & MS_EXTRA_FLAG)) { nrequired++; } } else { /* Skip unknown fields */ if (json_skip(self) < 0) goto error; } } if (nrequired < info->nrequired) { /* A required field is missing, determine which one and raise */ TypedDictInfo_error_missing(info, out, path); goto error; } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static PyObject * json_decode_dataclass( JSONDecoderState *self, TypeNode *type, PathNode *path ) { PyObject *out; unsigned char c; char *key = NULL; bool first = true; Py_ssize_t key_size, pos = 0; DataclassInfo *info = TypeNode_get_dataclass_info(type); if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyTypeObject *dataclass_type = (PyTypeObject *)(info->class); out = dataclass_type->tp_alloc(dataclass_type, 0); if (out == NULL) goto error; if (info->pre_init != NULL) { PyObject *res = PyObject_CallOneArg(info->pre_init, out); if (res == NULL) goto error; Py_DECREF(res); } self->input_pos++; /* Skip '{' */ while (true) { /* Parse '}' or ',', then peek the next character */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c == '}') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or '}'"); goto error; } /* Parse a string key */ if (c == '"') { bool is_ascii = true; key_size = json_decode_string_view(self, &key, &is_ascii); if (key_size < 0) goto error; } else if (c == '}') { json_err_invalid(self, "trailing comma in object"); goto error; } else { json_err_invalid(self, "object keys must be strings"); goto error; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c != ':') { json_err_invalid(self, "expected ':'"); goto error; } self->input_pos++; /* Parse value */ TypeNode *field_type; PyObject *field = DataclassInfo_lookup_key(info, key, key_size, &field_type, &pos); if (field != NULL) { PathNode field_path = {path, PATH_STR, field}; PyObject *val = json_decode(self, field_type, &field_path); if (val == NULL) goto error; int status = PyObject_GenericSetAttr(out, field, val); Py_DECREF(val); if (status < 0) goto error; } else { /* Skip unknown fields */ if (json_skip(self) < 0) goto error; } } if (DataclassInfo_post_decode(info, out, path) < 0) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * json_decode_struct_map_inner( JSONDecoderState *self, StructInfo *info, PathNode *path, Py_ssize_t starting_index ) { PyObject *out, *val = NULL; Py_ssize_t key_size, field_index, pos = 0; unsigned char c; char *key = NULL; bool first = starting_index == 0; StructMetaObject *st_type = info->class; PathNode field_path = {path, 0, (PyObject *)st_type}; out = Struct_alloc((PyTypeObject *)(st_type)); if (out == NULL) return NULL; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } while (true) { /* Parse '}' or ',', then peek the next character */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c == '}') { self->input_pos++; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; } else if (first) { /* Only the first item doesn't need a comma delimiter */ first = false; } else { json_err_invalid(self, "expected ',' or '}'"); goto error; } /* Parse a string key */ if (c == '"') { bool is_ascii = true; key_size = json_decode_string_view(self, &key, &is_ascii); if (key_size < 0) goto error; } else if (c == '}') { json_err_invalid(self, "trailing comma in object"); goto error; } else { json_err_invalid(self, "object keys must be strings"); goto error; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) goto error; if (c != ':') { json_err_invalid(self, "expected ':'"); goto error; } self->input_pos++; /* Parse value */ field_index = StructMeta_get_field_index(st_type, key, key_size, &pos); if (MS_LIKELY(field_index >= 0)) { field_path.index = field_index; TypeNode *type = info->types[field_index]; val = json_decode(self, type, &field_path); if (val == NULL) goto error; Struct_set_index(out, field_index, val); } else if (MS_UNLIKELY(field_index == -2)) { /* Decode and check that the tag value matches the expected value */ PathNode tag_path = {path, PATH_STR, st_type->struct_tag_field}; if (json_ensure_tag_matches(self, &tag_path, st_type->struct_tag_value) < 0) { goto error; } } else { /* Unknown field */ if (MS_UNLIKELY(st_type->forbid_unknown_fields == OPT_TRUE)) { ms_error_unknown_field(key, key_size, path); goto error; } else { if (json_skip(self) < 0) goto error; } } } if (Struct_fill_in_defaults(st_type, out, path) < 0) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static PyObject * json_decode_struct_map( JSONDecoderState *self, TypeNode *type, PathNode *path ) { StructInfo *info = TypeNode_get_struct_info(type); self->input_pos++; /* Skip '{' */ return json_decode_struct_map_inner(self, info, path, 0); } static PyObject * json_decode_struct_union( JSONDecoderState *self, TypeNode *type, PathNode *path ) { Lookup *lookup = TypeNode_get_struct_union(type); PathNode tag_path = {path, PATH_STR, Lookup_tag_field(lookup)}; Py_ssize_t tag_field_size; const char *tag_field = unicode_str_and_size_nocheck( Lookup_tag_field(lookup), &tag_field_size ); self->input_pos++; /* Skip '{' */ /* Cache the current input position in case we need to reset it once the * tag is found */ unsigned char *orig_input_pos = self->input_pos; for (Py_ssize_t i = 0; ; i++) { unsigned char c; /* Parse '}' or ',', then peek the next character */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return NULL; if (c == '}') { self->input_pos++; break; } else if (c == ',' && (i != 0)) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return NULL; } else if (i != 0) { return json_err_invalid(self, "expected ',' or '}'"); } /* Parse a string key */ Py_ssize_t key_size; char *key = NULL; if (c == '"') { bool is_ascii = true; key_size = json_decode_string_view(self, &key, &is_ascii); if (key_size < 0) return NULL; } else if (c == '}') { return json_err_invalid(self, "trailing comma in object"); } else { return json_err_invalid(self, "object keys must be strings"); } /* Check if key matches tag_field */ bool tag_found = false; if (key_size == tag_field_size && memcmp(key, tag_field, key_size) == 0) { tag_found = true; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return NULL; if (c != ':') { return json_err_invalid(self, "expected ':'"); } self->input_pos++; /* Parse value */ if (tag_found) { /* Decode & lookup struct type from tag */ StructInfo *info = json_decode_tag_and_lookup_type(self, lookup, &tag_path); if (info == NULL) return NULL; if (i != 0) { /* tag wasn't first field, reset decoder position */ self->input_pos = orig_input_pos; } return json_decode_struct_map_inner(self, info, path, i == 0 ? 1 : 0); } else { if (json_skip(self) < 0) return NULL; } } ms_missing_required_field(Lookup_tag_field(lookup), path); return NULL; } static PyObject * json_decode_object( JSONDecoderState *self, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_ANY) { TypeNode type_any = {MS_TYPE_ANY}; return json_decode_dict(self, type, &type_any, &type_any, path); } else if (type->types & MS_TYPE_DICT) { TypeNode *key, *val; TypeNode_get_dict(type, &key, &val); return json_decode_dict(self, type, key, val, path); } else if (type->types & MS_TYPE_TYPEDDICT) { return json_decode_typeddict(self, type, path); } else if (type->types & MS_TYPE_DATACLASS) { return json_decode_dataclass(self, type, path); } else if (type->types & MS_TYPE_STRUCT) { return json_decode_struct_map(self, type, path); } else if (type->types & MS_TYPE_STRUCT_UNION) { return json_decode_struct_union(self, type, path); } return ms_validation_error("object", type, path); } static PyObject * json_maybe_decode_number(JSONDecoderState *self, TypeNode *type, PathNode *path) { const char *errmsg = NULL; const unsigned char *pout; PyObject *out = parse_number_inline( self->input_pos, self->input_end, &pout, &errmsg, type, path, self->strict, self->float_hook, false ); self->input_pos = (unsigned char *)pout; if (MS_UNLIKELY(out == NULL)) { if (errmsg != NULL) { json_err_invalid(self, errmsg); } } return out; } static MS_NOINLINE PyObject * json_decode_raw(JSONDecoderState *self) { unsigned char c; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return NULL; const unsigned char *start = self->input_pos; if (json_skip(self) < 0) return NULL; Py_ssize_t size = self->input_pos - start; return Raw_FromView(self->buffer_obj, (char *)start, size); } static MS_INLINE PyObject * json_decode_nocustom( JSONDecoderState *self, TypeNode *type, PathNode *path ) { unsigned char c; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return NULL; switch (c) { case 'n': return json_decode_none(self, type, path); case 't': return json_decode_true(self, type, path); case 'f': return json_decode_false(self, type, path); case '[': return json_decode_array(self, type, path); case '{': return json_decode_object(self, type, path); case '"': return json_decode_string(self, type, path); default: return json_maybe_decode_number(self, type, path); } } static PyObject * json_decode( JSONDecoderState *self, TypeNode *type, PathNode *path ) { if (MS_UNLIKELY(type->types == 0)) { return json_decode_raw(self); } PyObject *obj = json_decode_nocustom(self, type, path); if (MS_UNLIKELY(type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC))) { return ms_decode_custom(obj, self->dec_hook, type, path); } return obj; } static int json_skip_ident(JSONDecoderState *self, const char *ident, size_t len) { self->input_pos++; /* Already checked first char */ if (MS_UNLIKELY(!json_remaining(self, len))) return ms_err_truncated(); if (memcmp(self->input_pos, ident, len) != 0) { json_err_invalid(self, "invalid character"); return -1; } self->input_pos += len; return 0; } static int json_skip_array(JSONDecoderState *self) { unsigned char c; bool first = true; int out = -1; self->input_pos++; /* Skip '[' */ if (Py_EnterRecursiveCall(" while deserializing an object")) return -1; while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) break; if (c == ']') { self->input_pos++; out = 0; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) break; } else if (first) { first = false; } else { json_err_invalid(self, "expected ',' or ']'"); break; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(self, "trailing comma in array"); break; } if (json_skip(self) < 0) break; } Py_LeaveRecursiveCall(); return out; } static int json_skip_object(JSONDecoderState *self) { unsigned char c; bool first = true; int out = -1; self->input_pos++; /* Skip '{' */ if (Py_EnterRecursiveCall(" while deserializing an object")) return -1; while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) break; if (c == '}') { self->input_pos++; out = 0; break; } else if (c == ',' && !first) { self->input_pos++; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) break; } else if (first) { first = false; } else { json_err_invalid(self, "expected ',' or '}'"); break; } /* Skip key */ if (c == '"') { if (json_skip_string(self) < 0) break; } else if (c == '}') { json_err_invalid(self, "trailing comma in object"); break; } else { json_err_invalid(self, "expected '\"'"); break; } /* Parse colon */ if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) break; if (c != ':') { json_err_invalid(self, "expected ':'"); break; } self->input_pos++; /* Skip value */ if (json_skip(self) < 0) break; } Py_LeaveRecursiveCall(); return out; } static int json_maybe_skip_number(JSONDecoderState *self) { /* We know there is at least one byte available when this function is * called */ char c = *self->input_pos; /* Parse minus sign (if present) */ if (c == '-') { self->input_pos++; c = json_peek_or_null(self); } /* Parse integer */ if (MS_UNLIKELY(c == '0')) { /* Ensure at most one leading zero */ self->input_pos++; c = json_peek_or_null(self); if (MS_UNLIKELY(is_digit(c))) { json_err_invalid(self, "invalid number"); return -1; } } else { /* Skip the integer part of the number. */ unsigned char *cur_pos = self->input_pos; while (self->input_pos < self->input_end && is_digit(*self->input_pos)) { self->input_pos++; } /* There must be at least one digit */ if (MS_UNLIKELY(cur_pos == self->input_pos)) { json_err_invalid(self, "invalid character"); return -1; } } c = json_peek_or_null(self); if (c == '.') { self->input_pos++; /* Skip remaining digits until invalid/unknown character */ unsigned char *cur_pos = self->input_pos; while (self->input_pos < self->input_end && is_digit(*self->input_pos)) { self->input_pos++; } /* Error if no digits after decimal */ if (MS_UNLIKELY(cur_pos == self->input_pos)) { json_err_invalid(self, "invalid number"); return -1; } c = json_peek_or_null(self); } if (c == 'e' || c == 'E') { self->input_pos++; /* Parse exponent sign (if any) */ c = json_peek_or_null(self); if (c == '+' || c == '-') { self->input_pos++; } /* Parse exponent digits */ unsigned char *cur_pos = self->input_pos; while (self->input_pos < self->input_end && is_digit(*self->input_pos)) { self->input_pos++; } /* Error if no digits in exponent */ if (MS_UNLIKELY(cur_pos == self->input_pos)) { json_err_invalid(self, "invalid number"); return -1; } } return 0; } static int json_skip(JSONDecoderState *self) { unsigned char c; if (MS_UNLIKELY(!json_peek_skip_ws(self, &c))) return -1; switch (c) { case 'n': return json_skip_ident(self, "ull", 3); case 't': return json_skip_ident(self, "rue", 3); case 'f': return json_skip_ident(self, "alse", 4); case '"': return json_skip_string(self); case '[': return json_skip_array(self); case '{': return json_skip_object(self); default: return json_maybe_skip_number(self); } } static int json_format( JSONDecoderState *, EncoderState *, Py_ssize_t indent, Py_ssize_t cur_indent ); static int json_write_indent(EncoderState *self, Py_ssize_t indent, Py_ssize_t cur_indent) { if (indent <= 0) return 0; if (ms_ensure_space(self, cur_indent + 1) < 0) return -1; char *p = self->output_buffer_raw + self->output_len; *p++ = '\n'; for (Py_ssize_t i = 0; i < cur_indent; i++) { *p++ = ' '; } self->output_len += cur_indent + 1; return 0; } static int json_format_array( JSONDecoderState *dec, EncoderState *enc, Py_ssize_t indent, Py_ssize_t cur_indent ) { unsigned char c; bool first = true; int out = -1; Py_ssize_t el_indent = cur_indent + indent; dec->input_pos++; /* Skip '[' */ if (ms_write(enc, "[", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while deserializing an object")) return -1; while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) break; if (c == ']') { dec->input_pos++; if (!first) { if (MS_UNLIKELY(json_write_indent(enc, indent, cur_indent) < 0)) break; } out = ms_write(enc, "]", 1); break; } else if (c == ',' && !first) { dec->input_pos++; if (indent == 0) { if (MS_UNLIKELY(ms_write(enc, ", ", 2) < 0)) break; } else { if (MS_UNLIKELY(ms_write(enc, ",", 1) < 0)) break; } if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) break; } else if (first) { first = false; } else { json_err_invalid(dec, "expected ',' or ']'"); break; } if (MS_UNLIKELY(c == ']')) { json_err_invalid(dec, "trailing comma in array"); break; } if (json_write_indent(enc, indent, el_indent) < 0) break; if (json_format(dec, enc, indent, el_indent) < 0) break; } Py_LeaveRecursiveCall(); return out; } static int json_format_object( JSONDecoderState *dec, EncoderState *enc, Py_ssize_t indent, Py_ssize_t cur_indent ) { unsigned char c; bool first = true; int out = -1; Py_ssize_t el_indent = cur_indent + indent; dec->input_pos++; /* Skip '{' */ if (ms_write(enc, "{", 1) < 0) return -1; if (Py_EnterRecursiveCall(" while deserializing an object")) return -1; while (true) { if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) break; if (c == '}') { dec->input_pos++; if (!first) { if (MS_UNLIKELY(json_write_indent(enc, indent, cur_indent) < 0)) break; } out = ms_write(enc, "}", 1); break; } else if (c == ',' && !first) { dec->input_pos++; if (indent == 0) { if (MS_UNLIKELY(ms_write(enc, ", ", 2) < 0)) break; } else { if (MS_UNLIKELY(ms_write(enc, ",", 1) < 0)) break; } if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) break; } else if (first) { first = false; } else { json_err_invalid(dec, "expected ',' or '}'"); break; } if (c == '"') { if (json_write_indent(enc, indent, el_indent) < 0) break; if (json_format(dec, enc, indent, el_indent) < 0) break; } else if (c == '}') { json_err_invalid(dec, "trailing comma in object"); break; } else { json_err_invalid(dec, "expected '\"'"); break; } if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) break; if (c != ':') { json_err_invalid(dec, "expected ':'"); break; } dec->input_pos++; if (indent >= 0) { if (ms_write(enc, ": ", 2) < 0) break; } else { if (ms_write(enc, ":", 1) < 0) break; } if (json_format(dec, enc, indent, el_indent) < 0) break; } Py_LeaveRecursiveCall(); return out; } static int json_format( JSONDecoderState *dec, EncoderState *enc, Py_ssize_t indent, Py_ssize_t cur_indent ) { unsigned char c; if (MS_UNLIKELY(!json_peek_skip_ws(dec, &c))) return -1; if (c == '[') { return json_format_array(dec, enc, indent, cur_indent); } else if (c == '{') { return json_format_object(dec, enc, indent, cur_indent); } else { unsigned char *start = dec->input_pos; if (json_skip(dec) < 0) return -1; unsigned char *end = dec->input_pos; return ms_write(enc, (char *)start, end - start); } } PyDoc_STRVAR(msgspec_json_format__doc__, "json_format(buf, *, indent=2)\n" "--\n" "\n" "Format an existing JSON message, usually to be more human readable.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like or str\n" " The JSON message to format.\n" "indent : int, optional\n" " How many spaces to indent for a single indentation level. Defaults to 2.\n" " Set to 0 to format the message as a single line, with spaces added between\n" " items for readability. Set to a negative number to strip all unnecessary\n" " whitespace, minimizing the message size.\n" "\n" "Returns\n" "-------\n" "output : bytes or str\n" " The formatted JSON message. Returns a str if input is a str, bytes otherwise." ); static PyObject* msgspec_json_format(PyObject *self, PyObject *args, PyObject *kwargs) { int status; Py_buffer buffer; PyObject *out = NULL, *buf = NULL; char *kwlist[] = {"buf", "indent", NULL}; Py_ssize_t indent = 2; /* Parse arguments */ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|$n", kwlist, &buf, &indent)) return NULL; if (indent < 0) { indent = -1; } buffer.buf = NULL; if (ms_get_buffer(buf, &buffer) >= 0) { JSONDecoderState dec; EncoderState enc; /* Init decoder */ dec.dec_hook = NULL; dec.float_hook = NULL; dec.type = NULL; dec.scratch = NULL; dec.scratch_capacity = 0; dec.scratch_len = 0; dec.buffer_obj = buf; dec.input_start = buffer.buf; dec.input_pos = buffer.buf; dec.input_end = dec.input_pos + buffer.len; /* Init encoder */ enc.mod = msgspec_get_state(self); enc.enc_hook = NULL; /* Assume pretty-printing will take at least as much space as the * input. This is true unless there's existing whitespace. */ enc.max_output_len = (indent >= 0) ? buffer.len : ENC_INIT_BUFSIZE; enc.output_len = 0; enc.output_buffer = PyBytes_FromStringAndSize(NULL, enc.max_output_len); if (enc.output_buffer != NULL) { enc.output_buffer_raw = PyBytes_AS_STRING(enc.output_buffer); enc.resize_buffer = &ms_resize_bytes; status = json_format(&dec, &enc, indent, 0); if (status == 0 && json_has_trailing_characters(&dec)) { status = -1; } if (status == 0) { if (PyUnicode_CheckExact(buf)) { /* str input, str output */ out = PyUnicode_FromStringAndSize( enc.output_buffer_raw, enc.output_len ); Py_CLEAR(enc.output_buffer); } else { /* Trim output to length */ out = enc.output_buffer; FAST_BYTES_SHRINK(out, enc.output_len); } } else { /* Error, drop buffer */ Py_CLEAR(enc.output_buffer); } } ms_release_buffer(&buffer); } return out; } PyDoc_STRVAR(JSONDecoder_decode__doc__, "decode(self, buf)\n" "--\n" "\n" "Deserialize an object from JSON.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like or str\n" " The message to decode.\n" "\n" "Returns\n" "-------\n" "obj : Any\n" " The deserialized object.\n" ); static PyObject* JSONDecoder_decode(JSONDecoder *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) { return NULL; } JSONDecoderState state = { .type = self->type, .strict = self->strict, .dec_hook = self->dec_hook, .float_hook = self->float_hook, .scratch = NULL, .scratch_capacity = 0, .scratch_len = 0 }; Py_buffer buffer; buffer.buf = NULL; if (ms_get_buffer(args[0], &buffer) >= 0) { state.buffer_obj = args[0]; state.input_start = buffer.buf; state.input_pos = buffer.buf; state.input_end = state.input_pos + buffer.len; PyObject *res = json_decode(&state, state.type, NULL); if (res != NULL && json_has_trailing_characters(&state)) { Py_CLEAR(res); } ms_release_buffer(&buffer); PyMem_Free(state.scratch); return res; } return NULL; } PyDoc_STRVAR(JSONDecoder_decode_lines__doc__, "decode_lines(self, buf)\n" "--\n" "\n" "Decode a list of items from newline-delimited JSON.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like or str\n" " The message to decode.\n" "\n" "Returns\n" "-------\n" "items : list\n" " A list of decoded objects.\n" "Examples\n" "--------\n" ">>> import msgspec\n" ">>> msg = \"\"\"\n" "... {\"x\": 1, \"y\": 2}\n" "... {\"x\": 3, \"y\": 4}\n" "... \"\"\"\n" ">>> dec = msgspec.json.Decoder()\n" ">>> dec.decode_lines(msg)\n" "[{'x': 1, 'y': 2}, {'x': 3, 'y': 4}]" ); static PyObject* JSONDecoder_decode_lines(JSONDecoder *self, PyObject *const *args, Py_ssize_t nargs) { if (!check_positional_nargs(nargs, 1, 1)) { return NULL; } JSONDecoderState state = { .type = self->type, .strict = self->strict, .dec_hook = self->dec_hook, .float_hook = self->float_hook, .scratch = NULL, .scratch_capacity = 0, .scratch_len = 0 }; Py_buffer buffer; buffer.buf = NULL; if (ms_get_buffer(args[0], &buffer) >= 0) { state.buffer_obj = args[0]; state.input_start = buffer.buf; state.input_pos = buffer.buf; state.input_end = state.input_pos + buffer.len; PathNode path = {NULL, 0, NULL}; PyObject *out = PyList_New(0); if (out == NULL) return NULL; while (true) { /* Skip until first non-whitespace character, or return if buffer * exhausted */ while (true) { if (state.input_pos == state.input_end) { goto done; } unsigned char c = *state.input_pos; if (MS_LIKELY(c != ' ' && c != '\n' && c != '\r' && c != '\t')) { break; } state.input_pos++; } /* Read and append next item */ PyObject *item = json_decode(&state, state.type, &path); path.index++; if (item == NULL) { Py_CLEAR(out); goto done; } int status = PyList_Append(out, item); Py_DECREF(item); if (status < 0) { Py_CLEAR(out); goto done; } } done: ms_release_buffer(&buffer); PyMem_Free(state.scratch); return out; } return NULL; } static struct PyMethodDef JSONDecoder_methods[] = { { "decode", (PyCFunction) JSONDecoder_decode, METH_FASTCALL, JSONDecoder_decode__doc__, }, { "decode_lines", (PyCFunction) JSONDecoder_decode_lines, METH_FASTCALL, JSONDecoder_decode_lines__doc__, }, {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS}, {NULL, NULL} /* sentinel */ }; static PyMemberDef JSONDecoder_members[] = { {"type", T_OBJECT_EX, offsetof(JSONDecoder, orig_type), READONLY, "The Decoder type"}, {"strict", T_BOOL, offsetof(JSONDecoder, strict), READONLY, "The Decoder strict setting"}, {"dec_hook", T_OBJECT, offsetof(JSONDecoder, dec_hook), READONLY, "The Decoder dec_hook"}, {"float_hook", T_OBJECT, offsetof(JSONDecoder, float_hook), READONLY, "The Decoder float_hook"}, {NULL}, }; static PyTypeObject JSONDecoder_Type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "msgspec.json.Decoder", .tp_doc = JSONDecoder__doc__, .tp_basicsize = sizeof(JSONDecoder), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, .tp_new = PyType_GenericNew, .tp_init = (initproc)JSONDecoder_init, .tp_traverse = (traverseproc)JSONDecoder_traverse, .tp_dealloc = (destructor)JSONDecoder_dealloc, .tp_repr = (reprfunc)JSONDecoder_repr, .tp_methods = JSONDecoder_methods, .tp_members = JSONDecoder_members, }; PyDoc_STRVAR(msgspec_json_decode__doc__, "json_decode(buf, *, type='Any', strict=True, dec_hook=None)\n" "--\n" "\n" "Deserialize an object from JSON.\n" "\n" "Parameters\n" "----------\n" "buf : bytes-like or str\n" " The message to decode.\n" "type : type, optional\n" " A Python type (in type annotation form) to decode the object as. If\n" " provided, the message will be type checked and decoded as the specified\n" " type. Defaults to `Any`, in which case the message will be decoded using\n" " the default JSON types.\n" "strict : bool, optional\n" " Whether type coercion rules should be strict. Setting to False enables a\n" " wider set of coercion rules from string to non-string types for all values.\n" " Default is True.\n" "dec_hook : callable, optional\n" " An optional callback for handling decoding custom types. Should have the\n" " signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the\n" " expected message type, and ``obj`` is the decoded representation composed\n" " of only basic JSON types. This hook should transform ``obj`` into type\n" " ``type``, or raise a ``TypeError`` if unsupported.\n" "\n" "Returns\n" "-------\n" "obj : Any\n" " The deserialized object.\n" "\n" "See Also\n" "--------\n" "Decoder.decode" ); static PyObject* msgspec_json_decode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *res = NULL, *buf = NULL, *type = NULL, *dec_hook = NULL, *strict_obj = NULL; int strict = 1; MsgspecState *mod = msgspec_get_state(self); /* Parse arguments */ if (!check_positional_nargs(nargs, 1, 1)) return NULL; buf = args[0]; if (kwnames != NULL) { Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames); if ((type = find_keyword(kwnames, args + nargs, mod->str_type)) != NULL) nkwargs--; if ((strict_obj = find_keyword(kwnames, args + nargs, mod->str_strict)) != NULL) nkwargs--; if ((dec_hook = find_keyword(kwnames, args + nargs, mod->str_dec_hook)) != NULL) nkwargs--; if (nkwargs > 0) { PyErr_SetString( PyExc_TypeError, "Extra keyword arguments provided" ); return NULL; } } /* Handle dec_hook */ if (dec_hook == Py_None) { dec_hook = NULL; } if (dec_hook != NULL) { if (!PyCallable_Check(dec_hook)) { PyErr_SetString(PyExc_TypeError, "dec_hook must be callable"); return NULL; } } /* Handle strict */ if (strict_obj != NULL) { strict = PyObject_IsTrue(strict_obj); if (strict < 0) return NULL; } JSONDecoderState state = { .strict = strict, .dec_hook = dec_hook, .float_hook = NULL, .scratch = NULL, .scratch_capacity = 0, .scratch_len = 0 }; /* Allocate Any & Struct type nodes (simple, common cases) on the stack, * everything else on the heap */ TypeNode typenode_any = {MS_TYPE_ANY}; TypeNodeSimple typenode_struct; if (type == NULL || type == mod->typing_any) { state.type = &typenode_any; } else if (Py_TYPE(type) == &StructMetaType) { PyObject *info = StructInfo_Convert(type); if (info == NULL) return NULL; bool array_like = ((StructMetaObject *)type)->array_like == OPT_TRUE; typenode_struct.types = array_like ? MS_TYPE_STRUCT_ARRAY : MS_TYPE_STRUCT; typenode_struct.details[0].pointer = info; state.type = (TypeNode *)(&typenode_struct); } else { state.type = TypeNode_Convert(type); if (state.type == NULL) return NULL; } Py_buffer buffer; buffer.buf = NULL; if (ms_get_buffer(buf, &buffer) >= 0) { state.buffer_obj = buf; state.input_start = buffer.buf; state.input_pos = buffer.buf; state.input_end = state.input_pos + buffer.len; res = json_decode(&state, state.type, NULL); if (res != NULL && json_has_trailing_characters(&state)) { Py_CLEAR(res); } ms_release_buffer(&buffer); } PyMem_Free(state.scratch); if (state.type == (TypeNode *)&typenode_struct) { Py_DECREF(typenode_struct.details[0].pointer); } else if (state.type != &typenode_any) { TypeNode_Free(state.type); } return res; } /************************************************************************* * to_builtins * *************************************************************************/ #define MS_BUILTIN_BYTES (1ull << 0) #define MS_BUILTIN_BYTEARRAY (1ull << 1) #define MS_BUILTIN_MEMORYVIEW (1ull << 2) #define MS_BUILTIN_DATETIME (1ull << 3) #define MS_BUILTIN_DATE (1ull << 4) #define MS_BUILTIN_TIME (1ull << 5) #define MS_BUILTIN_UUID (1ull << 6) #define MS_BUILTIN_DECIMAL (1ull << 7) #define MS_BUILTIN_TIMEDELTA (1ull << 8) typedef struct { MsgspecState *mod; PyObject *enc_hook; bool str_keys; enum order_mode order; uint32_t builtin_types; PyObject *builtin_types_seq; } ToBuiltinsState; static PyObject * to_builtins(ToBuiltinsState *, PyObject *, bool); static PyObject * to_builtins_enum(ToBuiltinsState *self, PyObject *obj) { return PyObject_GetAttr(obj, self->mod->str__value_); } static PyObject * to_builtins_binary(ToBuiltinsState *self, const char *buf, Py_ssize_t size) { Py_ssize_t output_size = ms_encode_base64_size(self->mod, size); if (output_size < 0) return NULL; PyObject *out = PyUnicode_New(output_size, 127); if (out == NULL) return NULL; ms_encode_base64(buf, size, ascii_get_buffer(out)); return out; } static PyObject * to_builtins_datetime(ToBuiltinsState *self, PyObject *obj) { char buf[32]; int size = ms_encode_datetime(self->mod, obj, buf); if (size < 0) return NULL; PyObject *out = PyUnicode_New(size, 127); memcpy(ascii_get_buffer(out), buf, size); return out; } static PyObject * to_builtins_date(ToBuiltinsState *self, PyObject *obj) { PyObject *out = PyUnicode_New(10, 127); if (out == NULL) return NULL; ms_encode_date(obj, ascii_get_buffer(out)); return out; } static PyObject * to_builtins_time(ToBuiltinsState *self, PyObject *obj) { char buf[21]; int size = ms_encode_time(self->mod, obj, buf); if (size < 0) return NULL; PyObject *out = PyUnicode_New(size, 127); memcpy(ascii_get_buffer(out), buf, size); return out; } static PyObject * to_builtins_timedelta(ToBuiltinsState *self, PyObject *obj) { char buf[26]; int size = ms_encode_timedelta(obj, buf); PyObject *out = PyUnicode_New(size, 127); memcpy(ascii_get_buffer(out), buf, size); return out; } static PyObject * to_builtins_uuid(ToBuiltinsState *self, PyObject *obj) { PyObject *out = PyUnicode_New(36, 127); if (out == NULL) return NULL; if (ms_encode_uuid(self->mod, obj, ascii_get_buffer(out), true) < 0) { Py_CLEAR(out); } return out; } static PyObject * to_builtins_decimal(ToBuiltinsState *self, PyObject *obj) { return PyObject_Str(obj); } static PyObject * to_builtins_list(ToBuiltinsState *self, PyObject *obj) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; Py_ssize_t size = PyList_GET_SIZE(obj); PyObject *out = PyList_New(size); if (out == NULL) goto cleanup; for (Py_ssize_t i = 0; i < size; i++) { PyObject *item = PyList_GET_ITEM(obj, i); PyObject *new = to_builtins(self, item, false); if (new == NULL) { Py_CLEAR(out); goto cleanup; } PyList_SET_ITEM(out, i, new); } cleanup: Py_LeaveRecursiveCall(); return out; } static PyObject * to_builtins_tuple(ToBuiltinsState *self, PyObject *obj, bool is_key) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; Py_ssize_t size = PyTuple_GET_SIZE(obj); PyObject *out = PyTuple_New(size); if (out == NULL) goto cleanup; for (Py_ssize_t i = 0; i < size; i++) { PyObject *item = PyTuple_GET_ITEM(obj, i); PyObject *new = to_builtins(self, item, is_key); if (new == NULL) { Py_CLEAR(out); goto cleanup; } PyTuple_SET_ITEM(out, i, new); } cleanup: Py_LeaveRecursiveCall(); return out; } static PyObject * to_builtins_set(ToBuiltinsState *self, PyObject *obj, bool is_key) { PyObject *out = NULL; if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; PyObject *list = PySequence_List(obj); if (list == NULL) goto cleanup; if (self->order != ORDER_DEFAULT) { if (PyList_Sort(list) < 0) goto cleanup; } Py_ssize_t size = PyList_GET_SIZE(list); for (Py_ssize_t i = 0; i < size; i++) { PyObject *orig_item = PyList_GET_ITEM(list, i); PyObject *new_item = to_builtins(self, orig_item, is_key); if (new_item == NULL) goto cleanup; PyList_SET_ITEM(list, i, new_item); Py_DECREF(orig_item); } if (is_key) { out = PyList_AsTuple(list); } else { Py_INCREF(list); out = list; } cleanup: Py_LeaveRecursiveCall(); Py_XDECREF(list); return out; } static void sort_dict_inplace(PyObject **dict) { PyObject *out = NULL, *new = NULL, *keys = NULL; new = PyDict_New(); if (new == NULL) goto error; keys = PyDict_Keys(*dict); if (keys == NULL) goto error; if (PyList_Sort(keys) < 0) goto error; Py_ssize_t size = PyList_GET_SIZE(keys); for (Py_ssize_t i = 0; i < size; i++) { PyObject *key = PyList_GET_ITEM(keys, i); PyObject *val = PyDict_GetItem(*dict, key); if (val == NULL) goto error; if (PyDict_SetItem(new, key, val) < 0) goto error; } Py_INCREF(new); out = new; error: Py_XDECREF(new); Py_XDECREF(keys); Py_XDECREF(*dict); *dict = out; } static PyObject * to_builtins_dict(ToBuiltinsState *self, PyObject *obj) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; PyObject *new_key = NULL, *new_val = NULL, *key, *val; bool ok = false; PyObject *out = PyDict_New(); if (out == NULL) goto cleanup; Py_ssize_t pos = 0; while (PyDict_Next(obj, &pos, &key, &val)) { new_key = to_builtins(self, key, true); if (new_key == NULL) goto cleanup; if (self->str_keys) { if (PyLong_CheckExact(new_key) || PyFloat_CheckExact(new_key)) { PyObject *temp = PyObject_Str(new_key); if (temp == NULL) goto cleanup; Py_DECREF(new_key); new_key = temp; } else if (!PyUnicode_CheckExact(new_key)) { PyErr_SetString( PyExc_TypeError, "Only dicts with str-like or number-like keys are supported" ); goto cleanup; } } new_val = to_builtins(self, val, false); if (new_val == NULL) goto cleanup; if (PyDict_SetItem(out, new_key, new_val) < 0) goto cleanup; Py_CLEAR(new_key); Py_CLEAR(new_val); } if (MS_UNLIKELY(self->order != ORDER_DEFAULT)) { sort_dict_inplace(&out); } ok = true; cleanup: Py_LeaveRecursiveCall(); if (!ok) { Py_CLEAR(out); Py_XDECREF(new_key); Py_XDECREF(new_val); } return out; } static PyObject * to_builtins_struct(ToBuiltinsState *self, PyObject *obj, bool is_key) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; bool ok = false; PyObject *out = NULL; StructMetaObject *struct_type = (StructMetaObject *)Py_TYPE(obj); PyObject *tag_field = struct_type->struct_tag_field; PyObject *tag_value = struct_type->struct_tag_value; PyObject *fields = struct_type->struct_encode_fields; PyObject *defaults = struct_type->struct_defaults; Py_ssize_t nfields = PyTuple_GET_SIZE(fields); Py_ssize_t npos = nfields - PyTuple_GET_SIZE(defaults); bool omit_defaults = struct_type->omit_defaults == OPT_TRUE; if (struct_type->array_like == OPT_TRUE) { Py_ssize_t tagged = (tag_value != NULL); Py_ssize_t size = nfields + tagged; if (is_key) { out = PyTuple_New(size); } else { out = PyList_New(size); } if (out == NULL) goto cleanup; if (tagged) { Py_INCREF(tag_value); if (is_key) { PyTuple_SET_ITEM(out, 0, tag_value); } else { PyList_SET_ITEM(out, 0, tag_value); } } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val = Struct_get_index(obj, i); if (val == NULL) goto cleanup; PyObject *val2 = to_builtins(self, val, is_key); if (val2 == NULL) goto cleanup; Py_INCREF(val2); if (is_key) { PyTuple_SET_ITEM(out, i + tagged, val2); } else { PyList_SET_ITEM(out, i + tagged, val2); } } } else { out = PyDict_New(); if (out == NULL) goto cleanup; if (tag_value != NULL) { if (PyDict_SetItem(out, tag_field, tag_value) < 0) goto cleanup; } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *key = PyTuple_GET_ITEM(fields, i); PyObject *val = Struct_get_index(obj, i); if (MS_UNLIKELY(val == NULL)) goto cleanup; if (MS_UNLIKELY(val == UNSET)) continue; if ( !omit_defaults || i < npos || !is_default(val, PyTuple_GET_ITEM(defaults, i - npos)) ) { PyObject *val2 = to_builtins(self, val, false); if (val2 == NULL) goto cleanup; int status = PyDict_SetItem(out, key, val2); Py_DECREF(val2); if (status < 0) goto cleanup; } } if (MS_UNLIKELY(self->order == ORDER_SORTED)) { sort_dict_inplace(&out); } } ok = true; cleanup: Py_LeaveRecursiveCall(); if (!ok) { Py_CLEAR(out); } return out; } static PyObject * to_builtins_dataclass(ToBuiltinsState *self, PyObject *obj, PyObject *fields) { if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; bool ok = false; PyObject *out = NULL; DataclassIter iter; if (!dataclass_iter_setup(&iter, obj, fields)) goto cleanup; out = PyDict_New(); if (out == NULL) goto cleanup; PyObject *field, *val; while (dataclass_iter_next(&iter, &field, &val)) { PyObject *val2 = to_builtins(self, val, false); int status = ( (val2 == NULL) ? -1 : PyDict_SetItem(out, field, val2) ); Py_DECREF(val); Py_XDECREF(val2); if (status < 0) goto cleanup; } if (MS_UNLIKELY(self->order == ORDER_SORTED)) { sort_dict_inplace(&out); } ok = true; cleanup: Py_LeaveRecursiveCall(); dataclass_iter_cleanup(&iter); if (!ok) { Py_CLEAR(out); } return out; } static PyObject* to_builtins_object(ToBuiltinsState *self, PyObject *obj) { bool ok = false; PyObject *dict = NULL, *out = NULL; if (Py_EnterRecursiveCall(" while serializing an object")) return NULL; out = PyDict_New(); if (out == NULL) goto cleanup; /* First encode everything in `__dict__` */ dict = PyObject_GenericGetDict(obj, NULL); if (MS_UNLIKELY(dict == NULL)) { PyErr_Clear(); } else { PyObject *key, *val; Py_ssize_t pos = 0; while (PyDict_Next(dict, &pos, &key, &val)) { if (MS_LIKELY(PyUnicode_CheckExact(key))) { Py_ssize_t key_len; if (MS_UNLIKELY(val == UNSET)) continue; const char* key_buf = unicode_str_and_size(key, &key_len); if (MS_UNLIKELY(key_buf == NULL)) goto cleanup; if (MS_UNLIKELY(*key_buf == '_')) continue; PyObject *val2 = to_builtins(self, val, false); if (val2 == NULL) goto cleanup; int status = PyDict_SetItem(out, key, val2); Py_DECREF(val2); if (status < 0) goto cleanup; } } } /* Then encode everything in slots */ PyTypeObject *type = Py_TYPE(obj); while (type != NULL) { Py_ssize_t n = Py_SIZE(type); if (n) { PyMemberDef *mp = MS_PyHeapType_GET_MEMBERS((PyHeapTypeObject *)type); for (Py_ssize_t i = 0; i < n; i++, mp++) { if (MS_LIKELY(mp->type == T_OBJECT_EX && !(mp->flags & READONLY))) { char *addr = (char *)obj + mp->offset; PyObject *val = *(PyObject **)addr; if (MS_UNLIKELY(val == UNSET)) continue; if (MS_UNLIKELY(val == NULL)) continue; if (MS_UNLIKELY(*mp->name == '_')) continue; PyObject *key = PyUnicode_InternFromString(mp->name); if (key == NULL) goto cleanup; int status = -1; PyObject *val2 = to_builtins(self, val, false); if (val2 != NULL) { status = PyDict_SetItem(out, key, val2); Py_DECREF(val2); } Py_DECREF(key); if (status < 0) goto cleanup; } } } type = type->tp_base; } if (MS_UNLIKELY(self->order == ORDER_SORTED)) { sort_dict_inplace(&out); } ok = true; cleanup: Py_XDECREF(dict); Py_LeaveRecursiveCall(); if (!ok) { Py_CLEAR(out); } return out; } static PyObject * to_builtins(ToBuiltinsState *self, PyObject *obj, bool is_key) { PyTypeObject *type = Py_TYPE(obj); if ( obj == Py_None || type == &PyBool_Type || type == &PyLong_Type || type == &PyFloat_Type || type == &PyUnicode_Type ) { goto builtin; } else if (type == &PyBytes_Type) { if (self->builtin_types & MS_BUILTIN_BYTES) goto builtin; return to_builtins_binary( self, PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj) ); } else if (type == &PyByteArray_Type) { if (self->builtin_types & MS_BUILTIN_BYTEARRAY) goto builtin; return to_builtins_binary( self, PyByteArray_AS_STRING(obj), PyByteArray_GET_SIZE(obj) ); } else if (type == &PyMemoryView_Type) { if (self->builtin_types & MS_BUILTIN_MEMORYVIEW) goto builtin; PyObject *out; Py_buffer buffer; if (PyObject_GetBuffer(obj, &buffer, PyBUF_CONTIG_RO) < 0) return NULL; out = to_builtins_binary(self, buffer.buf, buffer.len); PyBuffer_Release(&buffer); return out; } else if (type == PyDateTimeAPI->DateTimeType) { if (self->builtin_types & MS_BUILTIN_DATETIME) goto builtin; return to_builtins_datetime(self, obj); } else if (type == PyDateTimeAPI->DateType) { if (self->builtin_types & MS_BUILTIN_DATE) goto builtin; return to_builtins_date(self, obj); } else if (type == PyDateTimeAPI->TimeType) { if (self->builtin_types & MS_BUILTIN_TIME) goto builtin; return to_builtins_time(self, obj); } else if (type == PyDateTimeAPI->DeltaType) { if (self->builtin_types & MS_BUILTIN_TIMEDELTA) goto builtin; return to_builtins_timedelta(self, obj); } else if (type == (PyTypeObject *)(self->mod->DecimalType)) { if (self->builtin_types & MS_BUILTIN_DECIMAL) goto builtin; return to_builtins_decimal(self, obj); } else if (PyList_Check(obj)) { return to_builtins_list(self, obj); } else if (PyTuple_Check(obj)) { return to_builtins_tuple(self, obj, is_key); } else if (PyDict_Check(obj)) { return to_builtins_dict(self, obj); } else if (Py_TYPE(type) == &StructMetaType) { return to_builtins_struct(self, obj, is_key); } else if (Py_TYPE(type) == self->mod->EnumMetaType) { return to_builtins_enum(self, obj); } else if (is_key & PyUnicode_Check(obj)) { return PyObject_Str(obj); } else if (PyType_IsSubtype(type, (PyTypeObject *)(self->mod->UUIDType))) { if (self->builtin_types & MS_BUILTIN_UUID) goto builtin; return to_builtins_uuid(self, obj); } else if (PyAnySet_Check(obj)) { return to_builtins_set(self, obj, is_key); } else if (!PyType_Check(obj) && type->tp_dict != NULL) { PyObject *fields = PyObject_GetAttr(obj, self->mod->str___dataclass_fields__); if (fields != NULL) { PyObject *out = to_builtins_dataclass(self, obj, fields); Py_DECREF(fields); return out; } else { PyErr_Clear(); } if (PyDict_Contains(type->tp_dict, self->mod->str___attrs_attrs__)) { return to_builtins_object(self, obj); } } if (self->builtin_types_seq != NULL) { PyObject **items = PySequence_Fast_ITEMS(self->builtin_types_seq); Py_ssize_t size = PySequence_Fast_GET_SIZE(self->builtin_types_seq); for (Py_ssize_t i = 0; i < size; i++) { if (((PyObject *)type) == *(items + i)) goto builtin; } } if (self->enc_hook != NULL) { PyObject *out = NULL; PyObject *temp; temp = PyObject_CallOneArg(self->enc_hook, obj); if (temp == NULL) return NULL; if (!Py_EnterRecursiveCall(" while serializing an object")) { out = to_builtins(self, temp, is_key); Py_LeaveRecursiveCall(); } Py_DECREF(temp); return out; } else { ms_encode_err_type_unsupported(type); return NULL; } builtin: Py_INCREF(obj); return obj; } static int ms_process_builtin_types( MsgspecState *mod, PyObject *builtin_types, uint32_t *mask, PyObject **custom_types ) { if (builtin_types == NULL || builtin_types == Py_None) return 0; bool forward_builtins_seq = false; const char *invalid_type_err = "builtin_types must be an iterable of types"; PyObject *seq = PySequence_Fast(builtin_types, invalid_type_err); if (seq == NULL) return -1; Py_ssize_t size = PySequence_Fast_GET_SIZE(seq); PyObject **items = PySequence_Fast_ITEMS(seq); for (Py_ssize_t i = 0; i < size; i++) { PyObject *type = *(items + i); if (type == (PyObject *)(&PyBytes_Type)) { *mask |= MS_BUILTIN_BYTES; } else if (type == (PyObject *)(&PyByteArray_Type)) { *mask |= MS_BUILTIN_BYTEARRAY; } else if (type == (PyObject *)(&PyMemoryView_Type)) { *mask |= MS_BUILTIN_MEMORYVIEW; } else if (type == (PyObject *)(PyDateTimeAPI->DateTimeType)) { *mask |= MS_BUILTIN_DATETIME; } else if (type == (PyObject *)(PyDateTimeAPI->DateType)) { *mask |= MS_BUILTIN_DATE; } else if (type == (PyObject *)(PyDateTimeAPI->TimeType)) { *mask |= MS_BUILTIN_TIME; } else if (type == (PyObject *)(PyDateTimeAPI->DeltaType)) { *mask |= MS_BUILTIN_TIMEDELTA; } else if (type == mod->UUIDType) { *mask |= MS_BUILTIN_UUID; } else if (type == mod->DecimalType) { *mask |= MS_BUILTIN_DECIMAL; } else if (!PyType_Check(type)) { PyErr_SetString(PyExc_TypeError, invalid_type_err); goto error; } else if (custom_types != NULL) { forward_builtins_seq = true; } else { PyErr_Format(PyExc_TypeError, "Cannot treat %R as a builtin type", type); goto error; } } if (forward_builtins_seq) { *custom_types = seq; } else { Py_DECREF(seq); } return 0; error: Py_DECREF(seq); return -1; } PyDoc_STRVAR(msgspec_to_builtins__doc__, "to_builtins(obj, *, str_keys=False, builtin_types=None, enc_hook=None, order=None)\n" "--\n" "\n" "Convert a complex object to one composed only of simpler builtin types\n" "commonly supported by Python serialization libraries.\n" "\n" "This is mainly useful for adding msgspec support for other protocols.\n" "\n" "Parameters\n" "----------\n" "obj: Any\n" " The object to convert.\n" "builtin_types: Iterable[type], optional\n" " An iterable of types to treat as additional builtin types. These types will\n" " be passed through ``to_builtins`` unchanged. Currently supports `bytes`,\n" " `bytearray`, `memoryview`, `datetime.datetime`, `datetime.time`,\n" " `datetime.date`, `datetime.timedelta`, `uuid.UUID`, `decimal.Decimal`,\n" " and custom types.\n" "str_keys: bool, optional\n" " Whether to convert all object keys to strings. Default is False.\n" "enc_hook : callable, optional\n" " A callable to call for objects that aren't supported msgspec types. Takes\n" " the unsupported object and should return a supported object, or raise a\n" " ``NotImplementedError`` if unsupported.\n" "order : {None, 'deterministic', 'sorted'}, optional\n" " The ordering to use when converting unordered compound types.\n" "\n" " - ``None``: All objects are converted in the most efficient manner matching\n" " their in-memory representations. The default.\n" " - `'deterministic'`: Unordered collections (sets, dicts) are sorted to\n" " ensure a consistent output between runs. Useful when comparison/hashing\n" " of the converted output is necessary.\n" " - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs,\n" " dataclasses, ...) are also sorted by field name before encoding. This is\n" " slower than `'deterministic'`, but may produce more human-readable output.\n" "\n" "Returns\n" "-------\n" "Any\n" " The converted object.\n" "\n" "Examples\n" "--------\n" ">>> import msgspec\n" ">>> class Example(msgspec.Struct):\n" "... x: set[int]\n" "... y: bytes\n" ">>> msg = Example({1, 2, 3}, b'\\x01\\x02')\n" "\n" "Convert the message to a simpler set of builtin types. Note that by default\n" "all bytes-like objects are base64-encoded and converted to strings.\n" "\n" ">>> msgspec.to_builtins(msg)\n" "{'x': [1, 2, 3], 'y': 'AQI='}\n" "\n" "If the downstream code supports binary objects natively, you can\n" "disable conversion by passing in the types to ``builtin_types``.\n" "\n" ">>> msgspec.to_builtins(msg, builtin_types=(bytes, bytearray, memoryview))\n" "{'x': [1, 2, 3], 'y': b'\\x01\\x02'}\n" "\n" "See Also\n" "--------\n" "msgspec.convert\n" "msgspec.structs.asdict\n" "msgspec.structs.astuple" ); static PyObject* msgspec_to_builtins(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *obj = NULL, *builtin_types = NULL, *enc_hook = NULL, *order = NULL; int str_keys = 0; ToBuiltinsState state; char *kwlist[] = {"obj", "builtin_types", "str_keys", "enc_hook", "order", NULL}; /* Parse arguments */ if (!PyArg_ParseTupleAndKeywords( args, kwargs, "O|$OpOO", kwlist, &obj, &builtin_types, &str_keys, &enc_hook, &order )) { return NULL; } state.mod = msgspec_get_state(self); state.str_keys = str_keys; state.builtin_types = 0; state.builtin_types_seq = NULL; state.order = parse_order_arg(order); if (state.order == ORDER_INVALID) return NULL; if (enc_hook == Py_None) { enc_hook = NULL; } else if (enc_hook != NULL && !PyCallable_Check(enc_hook)) { PyErr_SetString(PyExc_TypeError, "enc_hook must be callable"); return NULL; } state.enc_hook = enc_hook; if ( ms_process_builtin_types( state.mod, builtin_types, &(state.builtin_types), &(state.builtin_types_seq) ) < 0 ) { return NULL; } PyObject *out = to_builtins(&state, obj, false); Py_XDECREF(state.builtin_types_seq); return out; } /************************************************************************* * convert * *************************************************************************/ typedef struct ConvertState { MsgspecState *mod; PyObject *dec_hook; uint32_t builtin_types; bool str_keys; bool from_attributes; bool strict; } ConvertState; static PyObject * convert(ConvertState *, PyObject *, TypeNode *, PathNode *); static PyObject * convert_int_uncommon( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (!self->strict) { uint64_t ux; bool neg, overflow; overflow = fast_long_extract_parts(obj, &neg, &ux); if ((type->types & MS_TYPE_BOOL) && !overflow && !neg) { if (ux == 0) { Py_RETURN_FALSE; } else if (ux == 1) { Py_RETURN_TRUE; } } if (type->types & (MS_TYPE_DATETIME | MS_TYPE_TIMEDELTA)) { int64_t seconds; if (overflow || ux > LLONG_MAX) { seconds = LLONG_MAX; } else { seconds = ux; if (neg) { seconds *= -1; } } if (type->types & MS_TYPE_DATETIME) { return datetime_from_epoch(seconds, 0, type, path); } return ms_decode_timedelta_from_int64(seconds, path); } } return ms_validation_error("int", type, path); } static PyObject * convert_int( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (MS_LIKELY(type->types & MS_TYPE_INT)) { return ms_decode_pyint(obj, type, path); } else if (type->types & (MS_TYPE_INTENUM | MS_TYPE_INTLITERAL)) { return ms_decode_int_enum_or_literal_pyint(obj, type, path); } else if (type->types & MS_TYPE_FLOAT) { return ms_decode_float(PyLong_AsDouble(obj), type, path); } else if ( type->types & MS_TYPE_DECIMAL && !(self->builtin_types & MS_BUILTIN_DECIMAL) ) { return ms_decode_decimal_from_pyobj(obj, path, self->mod); } return convert_int_uncommon(self, obj, type, path); } static PyObject * convert_float( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_FLOAT) { Py_INCREF(obj); return ms_check_float_constraints(obj, type, path); } else if ( type->types & MS_TYPE_DECIMAL && !(self->builtin_types & MS_BUILTIN_DECIMAL) ) { return ms_decode_decimal_from_float( PyFloat_AS_DOUBLE(obj), path, self->mod ); } else if (!self->strict) { double val = PyFloat_AS_DOUBLE(obj); if (type->types & MS_TYPE_INT) { int64_t out; if (double_as_int64(val, &out)) { return ms_post_decode_int64(out, type, path, self->strict, false); } } if (type->types & MS_TYPE_DATETIME) { return ms_decode_datetime_from_float(val, type, path); } else if (type->types & MS_TYPE_TIMEDELTA) { return ms_decode_timedelta_from_float(val, path); } } return ms_validation_error("float", type, path); } static PyObject * convert_bool( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_BOOL) { Py_INCREF(obj); return obj; } return ms_validation_error("bool", type, path); } static PyObject * convert_none( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_NONE) { Py_INCREF(obj); return obj; } return ms_validation_error("null", type, path); } static PyObject * convert_str_uncommon( ConvertState *self, PyObject *obj, const char *view, Py_ssize_t size, bool is_key, TypeNode *type, PathNode *path ) { if (is_key && self->str_keys && ( type->types & ( MS_TYPE_INT | MS_TYPE_INTENUM | MS_TYPE_INTLITERAL | MS_TYPE_FLOAT | MS_TYPE_DECIMAL | ((!self->strict) * (MS_TYPE_DATETIME | MS_TYPE_TIMEDELTA)) ) ) ) { PyObject *out; if (maybe_parse_number(view, size, type, path, self->strict, &out)) { return out; } } if (type->types & (MS_TYPE_ENUM | MS_TYPE_STRLITERAL)) { return ms_decode_str_enum_or_literal(view, size, type, path); } else if ( (type->types & MS_TYPE_DATETIME) && !(self->builtin_types & MS_BUILTIN_DATETIME) ) { return ms_decode_datetime_from_str(view, size, type, path); } else if ( (type->types & MS_TYPE_DATE) && !(self->builtin_types & MS_BUILTIN_DATE) ) { return ms_decode_date(view, size, path); } else if ( (type->types & MS_TYPE_TIME) && !(self->builtin_types & MS_BUILTIN_TIME) ) { return ms_decode_time(view, size, type, path); } else if ( (type->types & MS_TYPE_TIMEDELTA) && !(self->builtin_types & MS_BUILTIN_TIMEDELTA) ) { return ms_decode_timedelta(view, size, type, path); } else if ( (type->types & MS_TYPE_UUID) && !(self->builtin_types & MS_BUILTIN_UUID) ) { return ms_decode_uuid_from_str(view, size, path); } else if ( (type->types & MS_TYPE_DECIMAL) && !(self->builtin_types & MS_BUILTIN_DECIMAL) ) { return ms_decode_decimal_from_pystr(obj, path, self->mod); } else if ( (type->types & MS_TYPE_BYTES) && !(self->builtin_types & MS_BUILTIN_BYTES) ) { return json_decode_binary(view, size, type, path); } else if ( (type->types & MS_TYPE_BYTEARRAY) && !(self->builtin_types & MS_BUILTIN_BYTEARRAY) ) { return json_decode_binary(view, size, type, path); } else if ( (type->types & MS_TYPE_MEMORYVIEW) && !(self->builtin_types & MS_BUILTIN_MEMORYVIEW) ) { return json_decode_binary(view, size, type, path); } return ms_validation_error("str", type, path); } static PyObject * convert_str( ConvertState *self, PyObject *obj, bool is_key, TypeNode *type, PathNode *path ) { if (type->types & (MS_TYPE_ANY | MS_TYPE_STR)) { Py_INCREF(obj); return ms_check_str_constraints(obj, type, path); } Py_ssize_t size; const char* view = unicode_str_and_size(obj, &size); if (view == NULL) return NULL; if (MS_UNLIKELY(!self->strict)) { bool invalid = false; PyObject *out = ms_decode_str_lax(view, size, type, path, &invalid); if (!invalid) return out; } return convert_str_uncommon(self, obj, view, size, is_key, type, path); } static PyObject * convert_bytes( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & (MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW)) { if (!ms_passes_bytes_constraints(PyBytes_GET_SIZE(obj), type, path)) { return NULL; } if (type->types & MS_TYPE_BYTES) { return PyBytes_FromObject(obj); } else if (type->types & MS_TYPE_BYTEARRAY) { return PyByteArray_FromObject(obj); } else { return PyMemoryView_FromObject(obj); } } if ( (type->types & MS_TYPE_UUID) && !(self->builtin_types & MS_BUILTIN_UUID) ) { return ms_decode_uuid_from_bytes( PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj), path ); } return ms_validation_error("bytes", type, path); } static PyObject * convert_bytearray( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & (MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW)) { if (!ms_passes_bytes_constraints(PyByteArray_GET_SIZE(obj), type, path)) { return NULL; } if (type->types & MS_TYPE_BYTEARRAY) { Py_INCREF(obj); return obj; } else if (type->types & MS_TYPE_BYTES) { return PyBytes_FromObject(obj); } else { return PyMemoryView_FromObject(obj); } } if ( (type->types & MS_TYPE_UUID) && !(self->builtin_types & MS_BUILTIN_UUID) ) { return ms_decode_uuid_from_bytes( PyByteArray_AS_STRING(obj), PyByteArray_GET_SIZE(obj), path ); } return ms_validation_error("bytes", type, path); } static PyObject * convert_memoryview( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & (MS_TYPE_BYTES | MS_TYPE_BYTEARRAY | MS_TYPE_MEMORYVIEW)) { Py_ssize_t len = PyMemoryView_GET_BUFFER(obj)->len; if (!ms_passes_bytes_constraints(len, type, path)) return NULL; if (type->types & MS_TYPE_MEMORYVIEW) { Py_INCREF(obj); return obj; } else if (type->types & MS_TYPE_BYTES) { return PyBytes_FromObject(obj); } else { return PyByteArray_FromObject(obj); } } if ( (type->types & MS_TYPE_UUID) && !(self->builtin_types & MS_BUILTIN_UUID) ) { Py_buffer buffer; if (PyObject_GetBuffer(obj, &buffer, PyBUF_CONTIG_RO) < 0) return NULL; PyObject *out = ms_decode_uuid_from_bytes( buffer.buf, buffer.len, path ); PyBuffer_Release(&buffer); return out; } return ms_validation_error("bytes", type, path); } static PyObject * convert_datetime( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_DATETIME) { PyObject *tz = MS_DATE_GET_TZINFO(obj); if (!ms_passes_tz_constraint(tz, type, path)) return NULL; Py_INCREF(obj); return obj; } return ms_validation_error("datetime", type, path); } static PyObject * convert_time( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_TIME) { PyObject *tz = MS_TIME_GET_TZINFO(obj); if (!ms_passes_tz_constraint(tz, type, path)) return NULL; Py_INCREF(obj); return obj; } return ms_validation_error("time", type, path); } static PyObject * convert_enum( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_ENUM) { StrLookup *lookup = TypeNode_get_str_enum_or_literal(type); /* Check that the type matches. Note that enums that are also int or * str subclasses will be handled by `convert_int`/`convert_str`, not * here */ if (lookup->common.cls != NULL && Py_TYPE(obj) == (PyTypeObject *)(lookup->common.cls)) { Py_INCREF(obj); return obj; } } return ms_validation_error(Py_TYPE(obj)->tp_name, type, path); } static PyObject * convert_decimal( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_DECIMAL) { Py_INCREF(obj); return obj; } else if (type->types & MS_TYPE_FLOAT) { PyObject *temp = PyNumber_Float(obj); if (temp == NULL) return NULL; PyObject *out = convert_float(self, temp, type, path); Py_DECREF(temp); return out; } return ms_validation_error("decimal", type, path); } static PyObject * convert_immutable( ConvertState *self, uint64_t mask, const char *expected, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & mask) { Py_INCREF(obj); return obj; } return ms_validation_error(expected, type, path); } static PyObject * convert_raw( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types == 0) { Py_INCREF(obj); return obj; } return ms_validation_error("raw", type, path); } static PyObject * convert_seq_to_list( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *item_type, PathNode *path ) { PyObject *out = PyList_New(size); if (out == NULL) return NULL; if (size == 0) return out; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } for (Py_ssize_t i = 0; i < size; i++) { PathNode item_path = {path, i}; PyObject *val = convert(self, items[i], item_type, &item_path); if (val == NULL) { Py_CLEAR(out); break; } PyList_SET_ITEM(out, i, val); } Py_LeaveRecursiveCall(); return out; } static PyObject * convert_seq_to_set( ConvertState *self, PyObject **items, Py_ssize_t size, bool mutable, TypeNode *item_type, PathNode *path ) { PyObject *out = mutable ? PySet_New(NULL) : PyFrozenSet_New(NULL); if (out == NULL) return NULL; if (size == 0) return out; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } for (Py_ssize_t i = 0; i < size; i++) { PathNode item_path = {path, i}; PyObject *val = convert(self, items[i], item_type, &item_path); if (MS_UNLIKELY(val == NULL || PySet_Add(out, val) < 0)) { Py_XDECREF(val); Py_CLEAR(out); break; } Py_DECREF(val); } Py_LeaveRecursiveCall(); return out; } static PyObject * convert_seq_to_vartuple( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *item_type, PathNode *path ) { PyObject *out = PyTuple_New(size); if (out == NULL) return NULL; if (size == 0) return out; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } for (Py_ssize_t i = 0; i < size; i++) { PathNode item_path = {path, i}; PyObject *val = convert(self, items[i], item_type, &item_path); if (val == NULL) { Py_CLEAR(out); break; } PyTuple_SET_ITEM(out, i, val); } Py_LeaveRecursiveCall(); return out; } static PyObject * convert_seq_to_fixtuple( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *type, PathNode *path ) { Py_ssize_t fixtuple_size, offset; TypeNode_get_fixtuple(type, &offset, &fixtuple_size); if (size != fixtuple_size) { /* tuple is the incorrect size, raise and return */ ms_raise_validation_error( path, "Expected `array` of length %zd, got %zd%U", fixtuple_size, size ); return NULL; } PyObject *out = PyTuple_New(size); if (out == NULL) return NULL; if (size == 0) return out; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } for (Py_ssize_t i = 0; i < fixtuple_size; i++) { PathNode item_path = {path, i}; PyObject *val = convert( self, items[i], type->details[offset + i].pointer, &item_path ); if (MS_UNLIKELY(val == NULL)) { Py_CLEAR(out); break; } PyTuple_SET_ITEM(out, i, val); } Py_LeaveRecursiveCall(); return out; } static PyObject * convert_seq_to_namedtuple( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *type, PathNode *path ) { NamedTupleInfo *info = TypeNode_get_namedtuple_info(type); Py_ssize_t nfields = Py_SIZE(info); Py_ssize_t ndefaults = info->defaults == NULL ? 0 : PyTuple_GET_SIZE(info->defaults); Py_ssize_t nrequired = nfields - ndefaults; if (size < nrequired || nfields < size) { /* tuple is the incorrect size, raise and return */ if (ndefaults == 0) { ms_raise_validation_error( path, "Expected `array` of length %zd, got %zd%U", nfields, size ); } else { ms_raise_validation_error( path, "Expected `array` of length %zd to %zd, got %zd%U", nrequired, nfields, size ); } return NULL; } if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyTypeObject *nt_type = (PyTypeObject *)(info->class); PyObject *out = nt_type->tp_alloc(nt_type, nfields); if (out == NULL) goto error; for (Py_ssize_t i = 0; i < nfields; i++) { PyTuple_SET_ITEM(out, i, NULL); } for (Py_ssize_t i = 0; i < size; i++) { PathNode item_path = {path, i}; PyObject *item = convert(self, items[i], info->types[i], &item_path); if (MS_UNLIKELY(item == NULL)) goto error; PyTuple_SET_ITEM(out, i, item); } for (Py_ssize_t i = size; i < nfields; i++) { PyObject *item = PyTuple_GET_ITEM(info->defaults, i - nrequired); Py_INCREF(item); PyTuple_SET_ITEM(out, i, item); } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static bool convert_tag_matches( ConvertState *self, PyObject *tag, PyObject *expected_tag, PathNode *path ) { if (PyUnicode_CheckExact(expected_tag)) { if (!PyUnicode_CheckExact(tag)) goto wrong_type; } else if (!PyLong_CheckExact(tag)) { goto wrong_type; } int status = PyObject_RichCompareBool(tag, expected_tag, Py_EQ); if (status == 1) return true; if (status == 0) { ms_raise_validation_error(path, "Invalid value %R%U", tag); } return false; wrong_type: ms_raise_validation_error( path, "Expected `%s`, got `%s`%U", (PyUnicode_CheckExact(expected_tag) ? "str" : "int"), Py_TYPE(tag)->tp_name ); return false; } static StructInfo * convert_lookup_tag( ConvertState *self, Lookup *lookup, PyObject *tag, PathNode *path ) { StructInfo *out = NULL; if (Lookup_IsStrLookup(lookup)) { if (!PyUnicode_CheckExact(tag)) goto wrong_type; Py_ssize_t size; const char *buf = unicode_str_and_size(tag, &size); if (buf == NULL) return NULL; out = (StructInfo *)StrLookup_Get((StrLookup *)lookup, buf, size); } else { if (!PyLong_CheckExact(tag)) goto wrong_type; uint64_t ux; bool neg, overflow; overflow = fast_long_extract_parts(tag, &neg, &ux); if (overflow) goto invalid_value; if (neg) { out = (StructInfo *)IntLookup_GetInt64((IntLookup *)lookup, -(int64_t)ux); } else { out = (StructInfo *)IntLookup_GetUInt64((IntLookup *)lookup, ux); } } if (out != NULL) return out; invalid_value: ms_raise_validation_error(path, "Invalid value %R%U", tag); return NULL; wrong_type: ms_raise_validation_error( path, "Expected `%s`, got `%s`%U", (Lookup_IsStrLookup(lookup) ? "str" : "int"), Py_TYPE(tag)->tp_name ); return NULL; } static PyObject * convert_seq_to_struct_array_inner( ConvertState *self, PyObject **items, Py_ssize_t size, bool tag_already_read, StructInfo *info, PathNode *path ) { StructMetaObject *st_type = info->class; PathNode item_path = {path, 0}; bool tagged = st_type->struct_tag_value != NULL; Py_ssize_t nfields = PyTuple_GET_SIZE(st_type->struct_encode_fields); Py_ssize_t ndefaults = PyTuple_GET_SIZE(st_type->struct_defaults); Py_ssize_t nrequired = tagged + nfields - st_type->n_trailing_defaults; Py_ssize_t npos = nfields - ndefaults; if (size < nrequired) { ms_raise_validation_error( path, "Expected `array` of at least length %zd, got %zd%U", nrequired, size ); return NULL; } if (tagged) { if (!tag_already_read) { if ( !convert_tag_matches( self, items[item_path.index], st_type->struct_tag_value, &item_path ) ) { return NULL; } } size--; item_path.index++; } if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyObject *out = Struct_alloc((PyTypeObject *)(st_type)); if (out == NULL) goto error; bool is_gc = MS_TYPE_IS_GC(st_type); bool should_untrack = is_gc; for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *val; if (size > 0) { val = convert( self, items[item_path.index], info->types[i], &item_path ); if (MS_UNLIKELY(val == NULL)) goto error; size--; item_path.index++; } else { val = get_default( PyTuple_GET_ITEM(st_type->struct_defaults, i - npos) ); if (val == NULL) goto error; } Struct_set_index(out, i, val); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } if (MS_UNLIKELY(size > 0)) { if (MS_UNLIKELY(st_type->forbid_unknown_fields == OPT_TRUE)) { ms_raise_validation_error( path, "Expected `array` of at most length %zd, got %zd%U", nfields, nfields + size ); goto error; } } if (Struct_decode_post_init(st_type, out, path) < 0) goto error; Py_LeaveRecursiveCall(); if (is_gc && !should_untrack) PyObject_GC_Track(out); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * convert_seq_to_struct_array( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *type, PathNode *path ) { return convert_seq_to_struct_array_inner( self, items, size, false, TypeNode_get_struct_info(type), path ); } static PyObject * convert_seq_to_struct_array_union( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *type, PathNode *path ) { Lookup *lookup = TypeNode_get_struct_union(type); if (size == 0) { return ms_error_with_path( "Expected `array` of at least length 1, got 0%U", path ); } PathNode tag_path = {path, 0}; StructInfo *info = convert_lookup_tag(self, lookup, items[0], &tag_path); if (info == NULL) return NULL; return convert_seq_to_struct_array_inner(self, items, size, true, info, path); } static PyObject * convert_seq( ConvertState *self, PyObject **items, Py_ssize_t size, TypeNode *type, PathNode *path ) { if (!ms_passes_array_constraints(size, type, path)) return NULL; if (type->types & MS_TYPE_LIST) { return convert_seq_to_list( self, items, size, TypeNode_get_array(type), path ); } else if (type->types & (MS_TYPE_SET | MS_TYPE_FROZENSET)) { return convert_seq_to_set( self, items, size, (type->types & MS_TYPE_SET), TypeNode_get_array(type), path ); } else if (type->types & MS_TYPE_VARTUPLE) { return convert_seq_to_vartuple( self, items, size, TypeNode_get_array(type), path ); } else if (type->types & MS_TYPE_FIXTUPLE) { return convert_seq_to_fixtuple(self, items, size, type, path); } else if (type->types & MS_TYPE_NAMEDTUPLE) { return convert_seq_to_namedtuple(self, items, size, type, path); } else if (type->types & MS_TYPE_STRUCT_ARRAY) { return convert_seq_to_struct_array(self, items, size, type, path); } else if (type->types & MS_TYPE_STRUCT_ARRAY_UNION) { return convert_seq_to_struct_array_union(self, items, size, type, path); } return ms_validation_error("array", type, path); } static PyObject * convert_any_set( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { PyObject *seq = PySequence_Tuple(obj); if (seq == NULL) return NULL; PyObject **items = PySequence_Fast_ITEMS(seq); Py_ssize_t size = PySequence_Fast_GET_SIZE(seq); PyObject *out = NULL; if (!ms_passes_array_constraints(size, type, path)) goto done; if (type->types & MS_TYPE_LIST) { out = convert_seq_to_list( self, items, size, TypeNode_get_array(type), path ); } else if (type->types & (MS_TYPE_SET | MS_TYPE_FROZENSET)) { out = convert_seq_to_set( self, items, size, (type->types & MS_TYPE_SET), TypeNode_get_array(type), path ); } else if (type->types & MS_TYPE_VARTUPLE) { out = convert_seq_to_vartuple( self, items, size, TypeNode_get_array(type), path ); } else { ms_validation_error("set", type, path); } done: Py_DECREF(seq); return out; } static PyObject * convert_dict_to_dict( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { Py_ssize_t size = PyDict_GET_SIZE(obj); if (!ms_passes_map_constraints(size, type, path)) return NULL; TypeNode *key_type, *val_type; TypeNode_get_dict(type, &key_type, &val_type); PathNode key_path = {path, PATH_KEY, NULL}; PathNode val_path = {path, PATH_ELLIPSIS, NULL}; PyObject *out = PyDict_New(); if (out == NULL) return NULL; if (PyDict_GET_SIZE(obj) == 0) return out; if (Py_EnterRecursiveCall(" while deserializing an object")) { Py_DECREF(out); return NULL; /* cpylint-ignore */ } PyObject *key_obj = NULL, *val_obj = NULL; Py_ssize_t pos = 0; while (PyDict_Next(obj, &pos, &key_obj, &val_obj)) { PyObject *key; if (PyUnicode_CheckExact(key_obj)) { key = convert_str(self, key_obj, true, key_type, &key_path); } else { key = convert(self, key_obj, key_type, &key_path); } if (MS_UNLIKELY(key == NULL)) goto error; PyObject *val = convert(self, val_obj, val_type, &val_path); if (MS_UNLIKELY(val == NULL)) { Py_DECREF(key); goto error; } int status = PyDict_SetItem(out, key, val); Py_DECREF(key); Py_DECREF(val); if (status < 0) goto error; } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_DECREF(out); return NULL; } static PyObject * convert_mapping_to_dict( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { PyObject *out = NULL; PyObject *temp = PyDict_New(); if (temp == NULL) return NULL; if (PyDict_Merge(temp, obj, 1) == 0) { out = convert_dict_to_dict(self, temp, type, path); } Py_DECREF(temp); return out; } static bool convert_is_str_key(PyObject *key, PathNode *path) { if (PyUnicode_CheckExact(key)) return true; PathNode key_path = {path, PATH_KEY, NULL}; ms_error_with_path("Expected `str`%U", &key_path); return false; } static PyObject * convert_dict_to_struct( ConvertState *self, PyObject *obj, StructInfo *info, PathNode *path, bool tag_already_read ) { StructMetaObject *struct_type = info->class; if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyObject *out = Struct_alloc((PyTypeObject *)(struct_type)); if (out == NULL) goto error; Py_ssize_t pos = 0, pos_obj = 0; PyObject *key_obj, *val_obj; while (PyDict_Next(obj, &pos_obj, &key_obj, &val_obj)) { if (!convert_is_str_key(key_obj, path)) goto error; Py_ssize_t key_size; const char *key = unicode_str_and_size(key_obj, &key_size); if (key == NULL) goto error; Py_ssize_t field_index = StructMeta_get_field_index(struct_type, key, key_size, &pos); if (field_index < 0) { if (MS_UNLIKELY(field_index == -2)) { if (tag_already_read) continue; PathNode tag_path = {path, PATH_STR, struct_type->struct_tag_field}; if ( !convert_tag_matches( self, val_obj, struct_type->struct_tag_value, &tag_path ) ) { goto error; } } else { /* Unknown field */ if (MS_UNLIKELY(struct_type->forbid_unknown_fields == OPT_TRUE)) { ms_error_unknown_field(key, key_size, path); goto error; } } } else { PathNode field_path = {path, field_index, (PyObject *)struct_type}; PyObject *val = convert( self, val_obj, info->types[field_index], &field_path ); if (val == NULL) goto error; Struct_set_index(out, field_index, val); } } if (Struct_fill_in_defaults(struct_type, out, path) < 0) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * convert_dict_to_struct_union( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { Lookup *lookup = TypeNode_get_struct_union(type); PyObject *tag_field = Lookup_tag_field(lookup); PyObject *value = PyDict_GetItem(obj, tag_field); if (value != NULL) { PathNode tag_path = {path, PATH_STR, tag_field}; StructInfo *info = convert_lookup_tag( self, lookup, value, &tag_path ); if (info == NULL) return NULL; return convert_dict_to_struct(self, obj, info, path, true); } ms_missing_required_field(tag_field, path); return NULL; } static PyObject * convert_dict_to_typeddict( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyObject *out = PyDict_New(); if (out == NULL) goto error; TypedDictInfo *info = TypeNode_get_typeddict_info(type); Py_ssize_t nrequired = 0, pos = 0, pos_obj = 0; PyObject *key_obj, *val_obj; while (PyDict_Next(obj, &pos_obj, &key_obj, &val_obj)) { if (!convert_is_str_key(key_obj, path)) goto error; Py_ssize_t key_size; const char *key = unicode_str_and_size(key_obj, &key_size); if (key == NULL) goto error; TypeNode *field_type; PyObject *field = TypedDictInfo_lookup_key( info, key, key_size, &field_type, &pos ); if (field != NULL) { if (field_type->types & MS_EXTRA_FLAG) nrequired++; PathNode field_path = {path, PATH_STR, field}; PyObject *val = convert(self, val_obj, field_type, &field_path); if (val == NULL) goto error; int status = PyDict_SetItem(out, field, val); Py_DECREF(val); if (status < 0) goto error; } } if (nrequired < info->nrequired) { /* A required field is missing, determine which one and raise */ TypedDictInfo_error_missing(info, out, path); goto error; } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * convert_dict_to_dataclass( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; DataclassInfo *info = TypeNode_get_dataclass_info(type); PyTypeObject *dataclass_type = (PyTypeObject *)(info->class); PyObject *out = dataclass_type->tp_alloc(dataclass_type, 0); if (out == NULL) goto error; if (info->pre_init != NULL) { PyObject *res = PyObject_CallOneArg(info->pre_init, out); if (res == NULL) goto error; Py_DECREF(res); } Py_ssize_t pos = 0, pos_obj = 0; PyObject *key_obj = NULL, *val_obj = NULL; while (PyDict_Next(obj, &pos_obj, &key_obj, &val_obj)) { if (!convert_is_str_key(key_obj, path)) goto error; Py_ssize_t key_size; const char *key = unicode_str_and_size(key_obj, &key_size); if (MS_UNLIKELY(key == NULL)) goto error; TypeNode *field_type; PyObject *field = DataclassInfo_lookup_key( info, key, key_size, &field_type, &pos ); if (field != NULL) { PathNode field_path = {path, PATH_STR, field}; PyObject *val = convert(self, val_obj, field_type, &field_path); if (val == NULL) goto error; int status = PyObject_GenericSetAttr(out, field, val); Py_DECREF(val); if (status < 0) goto error; } } if (DataclassInfo_post_decode(info, out, path) < 0) goto error; Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * convert_dict( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (type->types & MS_TYPE_DICT) { return convert_dict_to_dict(self, obj, type, path); } else if (type->types & MS_TYPE_STRUCT) { StructInfo *info = TypeNode_get_struct_info(type); return convert_dict_to_struct(self, obj, info, path, false); } else if (type->types & MS_TYPE_STRUCT_UNION) { return convert_dict_to_struct_union(self, obj, type, path); } else if (type->types & MS_TYPE_TYPEDDICT) { return convert_dict_to_typeddict(self, obj, type, path); } else if (type->types & MS_TYPE_DATACLASS) { return convert_dict_to_dataclass(self, obj, type, path); } return ms_validation_error("object", type, path); } static PyObject * convert_object_to_struct( ConvertState *self, PyObject *obj, StructInfo *info, PathNode *path, PyObject* (*getter)(PyObject *, PyObject *), bool tag_already_read ) { StructMetaObject *struct_type = info->class; Py_ssize_t nfields = PyTuple_GET_SIZE(struct_type->struct_encode_fields); Py_ssize_t ndefaults = PyTuple_GET_SIZE(struct_type->struct_defaults); if (struct_type->struct_tag_value != NULL && !tag_already_read) { PyObject *attr = getter(obj, struct_type->struct_tag_field); if (attr != NULL) { PathNode tag_path = {path, PATH_STR, struct_type->struct_tag_field}; bool ok = convert_tag_matches( self, attr, struct_type->struct_tag_value, &tag_path ); Py_DECREF(attr); if (!ok) return NULL; } else { /* Tag not present, ignore and continue */ PyErr_Clear(); } } if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyObject *out = Struct_alloc((PyTypeObject *)(struct_type)); if (out == NULL) goto error; bool is_gc = MS_TYPE_IS_GC(struct_type); bool should_untrack = is_gc; /* If no fields are renamed we only have one fields tuple to choose from */ PyObject *fields = NULL; if (struct_type->struct_fields == struct_type->struct_encode_fields) { fields = struct_type->struct_fields; } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field, *attr, *val; if (MS_LIKELY(fields != NULL)) { /* fields tuple already determined, just get the next field name */ field = PyTuple_GET_ITEM(fields, i); attr = getter(obj, field); } else { /* fields tuple undetermined. Try the attribute name first */ PyObject *encode_field; field = PyTuple_GET_ITEM(struct_type->struct_fields, i); encode_field = PyTuple_GET_ITEM(struct_type->struct_encode_fields, i); attr = getter(obj, field); if (field != encode_field) { /* The field _was_ renamed */ if (attr != NULL) { /* Got a match, lock-in using attribute names */ fields = struct_type->struct_fields; } else { /* No match. Try using the renamed name */ PyErr_Clear(); attr = getter(obj, encode_field); if (attr != NULL) { /* Got a match, lock-in using renamed names */ field = encode_field; fields = struct_type->struct_encode_fields; } } } } if (attr != NULL) { PathNode field_path = {path, PATH_STR, field}; val = convert(self, attr, info->types[i], &field_path); Py_DECREF(attr); } else { PyErr_Clear(); PyObject *default_val = NULL; if (MS_LIKELY(i >= (nfields - ndefaults))) { default_val = PyTuple_GET_ITEM( struct_type->struct_defaults, i - (nfields - ndefaults) ); if (MS_UNLIKELY(default_val == NODEFAULT)) { default_val = NULL; } } if (default_val == NULL) { ms_missing_required_field(field, path); goto error; } val = get_default(default_val); } if (val == NULL) goto error; Struct_set_index(out, i, val); if (should_untrack) { should_untrack = !MS_MAYBE_TRACKED(val); } } if (Struct_decode_post_init(struct_type, out, path) < 0) goto error; Py_LeaveRecursiveCall(); if (is_gc && !should_untrack) PyObject_GC_Track(out); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static PyObject * convert_object_to_struct_union( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path, PyObject* (*getter)(PyObject *, PyObject *) ) { Lookup *lookup = TypeNode_get_struct_union(type); PyObject *tag_field = Lookup_tag_field(lookup); PyObject *value = getter(obj, tag_field); if (value != NULL) { PathNode tag_path = {path, PATH_STR, tag_field}; StructInfo *info = convert_lookup_tag( self, lookup, value, &tag_path ); Py_DECREF(value); if (info == NULL) return NULL; return convert_object_to_struct(self, obj, info, path, getter, true); } ms_missing_required_field(tag_field, path); return NULL; } static PyObject * convert_object_to_dataclass( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path, PyObject* (*getter)(PyObject *, PyObject *) ) { DataclassInfo *info = TypeNode_get_dataclass_info(type); Py_ssize_t nfields = Py_SIZE(info); Py_ssize_t ndefaults = PyTuple_GET_SIZE(info->defaults); if (Py_EnterRecursiveCall(" while deserializing an object")) return NULL; PyTypeObject *dataclass_type = (PyTypeObject *)(info->class); PyObject *out = dataclass_type->tp_alloc(dataclass_type, 0); if (out == NULL) goto error; if (info->pre_init != NULL) { PyObject *res = PyObject_CallOneArg(info->pre_init, out); if (res == NULL) goto error; Py_DECREF(res); } for (Py_ssize_t i = 0; i < nfields; i++) { PyObject *field = info->fields[i].key; PyObject *attr = getter(obj, field); PyObject *val; if (attr == NULL) { PyErr_Clear(); if (MS_LIKELY(i >= (nfields - ndefaults))) { PyObject *default_val = PyTuple_GET_ITEM( info->defaults, i - (nfields - ndefaults) ); bool is_factory = info->fields[i].type->types & MS_EXTRA_FLAG; if (is_factory) { val = PyObject_CallNoArgs(default_val); } else { Py_INCREF(default_val); val = default_val; } } else { ms_missing_required_field(field, path); goto error; } } else { PathNode field_path = {path, PATH_STR, field}; val = convert(self, attr, info->fields[i].type, &field_path); Py_DECREF(attr); } if (val == NULL) goto error; int status = PyObject_GenericSetAttr(out, field, val); Py_DECREF(val); if (status < 0) goto error; } if (info->post_init != NULL) { PyObject *res = PyObject_CallOneArg(info->post_init, out); if (res == NULL) { ms_maybe_wrap_validation_error(path); goto error; } Py_DECREF(res); } Py_LeaveRecursiveCall(); return out; error: Py_LeaveRecursiveCall(); Py_XDECREF(out); return NULL; } static bool Lookup_union_contains_type(Lookup *lookup, PyTypeObject *cls) { if (Lookup_IsStrLookup(lookup)) { StrLookup *lk = (StrLookup *)lookup; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { StructInfo *info = (StructInfo *)(lk->table[i].value); if (info != NULL && ((PyTypeObject *)(info->class) == cls)) { return true; } } } else { if (((IntLookup *)lookup)->compact) { IntLookupCompact *lk = (IntLookupCompact *)lookup; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { StructInfo *info = (StructInfo *)(lk->table[i]); if (info != NULL && ((PyTypeObject *)(info->class) == cls)) { return true; } } } else { IntLookupHashmap *lk = (IntLookupHashmap *)lookup; for (Py_ssize_t i = 0; i < Py_SIZE(lk); i++) { StructInfo *info = (StructInfo *)(lk->table[i].value); if (info != NULL && ((PyTypeObject *)(info->class) == cls)) { return true; } } } } return false; } static PyObject * getattr_then_getitem(PyObject *obj, PyObject *key) { PyObject *out = PyObject_GetAttr(obj, key); if (out == NULL) { PyErr_Clear(); out = PyObject_GetItem(obj, key); } return out; } static PyObject * convert_other( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { PyTypeObject *pytype = Py_TYPE(obj); /* First check if instance matches requested type for builtin user-defined * collection types. */ if (type->types & (MS_TYPE_STRUCT | MS_TYPE_STRUCT_ARRAY)) { StructInfo *info = TypeNode_get_struct_info(type); if (pytype == (PyTypeObject *)(info->class)) { Py_INCREF(obj); return obj; } } else if (type->types & (MS_TYPE_STRUCT_UNION | MS_TYPE_STRUCT_ARRAY_UNION)) { Lookup *lookup = TypeNode_get_struct_union(type); if (Lookup_union_contains_type(lookup, pytype)) { Py_INCREF(obj); return obj; } } else if (type->types & MS_TYPE_DATACLASS) { DataclassInfo *info = TypeNode_get_dataclass_info(type); if (pytype == (PyTypeObject *)(info->class)) { Py_INCREF(obj); return obj; } } else if (type->types & MS_TYPE_NAMEDTUPLE) { NamedTupleInfo *info = TypeNode_get_namedtuple_info(type); if (pytype == (PyTypeObject *)(info->class)) { Py_INCREF(obj); return obj; } } /* No luck. Next check if it's a tuple subclass (standard tuples are * handled earlier), and if so try converting it as a sequence */ if (PyTuple_Check(obj)) { return convert_seq(self, TUPLE_ITEMS(obj), PyTuple_GET_SIZE(obj), type, path); } /* Next try converting from a mapping or by attribute */ bool is_mapping = PyMapping_Check(obj); if (is_mapping && type->types & MS_TYPE_DICT) { return convert_mapping_to_dict(self, obj, type, path); } if (is_mapping || self->from_attributes) { PyObject* (*getter)(PyObject *, PyObject *); /* We want to exclude array_like structs when converting from a * mapping, but include them when converting by attribute */ bool matches_struct, matches_struct_union; if (self->from_attributes) { getter = (is_mapping) ? getattr_then_getitem : PyObject_GetAttr; matches_struct = type->types & (MS_TYPE_STRUCT | MS_TYPE_STRUCT_ARRAY); matches_struct_union = type->types & (MS_TYPE_STRUCT_UNION | MS_TYPE_STRUCT_ARRAY_UNION); } else { getter = getattr_then_getitem; matches_struct = type->types & MS_TYPE_STRUCT; matches_struct_union = type->types & MS_TYPE_STRUCT_UNION; } if (matches_struct) { StructInfo *info = TypeNode_get_struct_info(type); return convert_object_to_struct(self, obj, info, path, getter, false); } else if (matches_struct_union) { return convert_object_to_struct_union(self, obj, type, path, getter); } else if (type->types & MS_TYPE_DATACLASS) { return convert_object_to_dataclass(self, obj, type, path, getter); } } return ms_validation_error(Py_TYPE(obj)->tp_name, type, path); } static PyObject * convert( ConvertState *self, PyObject *obj, TypeNode *type, PathNode *path ) { if (MS_UNLIKELY(type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC | MS_TYPE_ANY))) { Py_INCREF(obj); if (MS_UNLIKELY(type->types & (MS_TYPE_CUSTOM | MS_TYPE_CUSTOM_GENERIC))) { return ms_decode_custom(obj, self->dec_hook, type, path); } return obj; } PyTypeObject *pytype = Py_TYPE(obj); if (PyUnicode_Check(obj)) { return convert_str(self, obj, false, type, path); } else if (pytype == &PyBool_Type) { return convert_bool(self, obj, type, path); } else if (PyLong_Check(obj)) { return convert_int(self, obj, type, path); } else if (pytype == &PyFloat_Type) { return convert_float(self, obj, type, path); } else if (PyList_Check(obj)) { return convert_seq(self, LIST_ITEMS(obj), PyList_GET_SIZE(obj), type, path); } else if (pytype == &PyTuple_Type) { /* Tuple subclasses are handled later on */ return convert_seq(self, TUPLE_ITEMS(obj), PyTuple_GET_SIZE(obj), type, path); } else if (PyDict_Check(obj)) { return convert_dict(self, obj, type, path); } else if (obj == Py_None) { return convert_none(self, obj, type, path); } else if (PyBytes_Check(obj)) { return convert_bytes(self, obj, type, path); } else if (pytype == &PyByteArray_Type) { return convert_bytearray(self, obj, type, path); } else if (pytype == &PyMemoryView_Type) { return convert_memoryview(self, obj, type, path); } else if (pytype == PyDateTimeAPI->DateTimeType) { return convert_datetime(self, obj, type, path); } else if (pytype == PyDateTimeAPI->TimeType) { return convert_time(self, obj, type, path); } else if (pytype == PyDateTimeAPI->DateType) { return convert_immutable(self, MS_TYPE_DATE, "date", obj, type, path); } else if (pytype == PyDateTimeAPI->DeltaType) { return convert_immutable(self, MS_TYPE_TIMEDELTA, "duration", obj, type, path); } else if (PyType_IsSubtype(pytype, (PyTypeObject *)(self->mod->UUIDType))) { return convert_immutable(self, MS_TYPE_UUID, "uuid", obj, type, path); } else if (pytype == (PyTypeObject *)self->mod->DecimalType) { return convert_decimal(self, obj, type, path); } else if (Py_TYPE(pytype) == self->mod->EnumMetaType) { return convert_enum(self, obj, type, path); } else if (pytype == &Ext_Type) { return convert_immutable(self, MS_TYPE_EXT, "ext", obj, type, path); } else if (pytype == &Raw_Type) { return convert_raw(self, obj, type, path); } else if (PyAnySet_Check(obj)) { return convert_any_set(self, obj, type, path); } else { return convert_other(self, obj, type, path); } } PyDoc_STRVAR(msgspec_convert__doc__, "convert(obj, type, *, strict=True, from_attributes=False, dec_hook=None, str_keys=False, builtin_types=None)\n" "--\n" "\n" "Convert the input object to the specified type, or error accordingly.\n" "\n" "Parameters\n" "----------\n" "obj: Any\n" " The object to convert.\n" "type: Type\n" " A Python type (in type annotation form) to convert the object to.\n" "strict: bool, optional\n" " Whether type coercion rules should be strict. Setting to False enables a\n" " wider set of coercion rules from string to non-string types for all values.\n" " Setting ``strict=False`` implies ``str_keys=True, builtin_types=None``.\n" " Default is True.\n" "from_attributes: bool, optional\n" " If True, input objects may be coerced to ``Struct``/``dataclass``/``attrs``\n" " types by extracting attributes from the input matching fields in the output\n" " type. One use case is converting database query results (ORM or otherwise)\n" " to msgspec structured types. Default is False.\n" "dec_hook: callable, optional\n" " An optional callback for handling decoding custom types. Should have the\n" " signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the\n" " expected message type, and ``obj`` is the decoded representation composed\n" " of only basic MessagePack types. This hook should transform ``obj`` into\n" " type ``type``, or raise a ``NotImplementedError`` if unsupported.\n" "builtin_types: Iterable[type], optional\n" " Useful for wrapping other serialization protocols. An iterable of types to\n" " treat as additional builtin types. Passing a type here indicates that the\n" " wrapped protocol natively supports that type, disabling any coercion to\n" " that type provided by `convert`. For example, passing\n" " ``builtin_types=(datetime,)`` disables the default ``str`` to ``datetime``\n" " conversion; the wrapped protocol must provide a ``datetime`` object\n" " directly. Currently supports `bytes`, `bytearray`, `datetime.datetime`,\n" " `datetime.time`, `datetime.date`, `datetime.timedelta`, `uuid.UUID`, and\n" " `decimal.Decimal`.\n" "str_keys: bool, optional\n" " Useful for wrapping other serialization protocols. Indicates whether the\n" " wrapped protocol only supports string keys. Setting to True enables a wider\n" " set of coercion rules from string to non-string types for dict keys.\n" " Default is False.\n" "\n" "Returns\n" "-------\n" "Any\n" " The converted object of the specified ``type``.\n" "\n" "Examples\n" "--------\n" ">>> import msgspec\n" ">>> class Example(msgspec.Struct):\n" "... x: set[int]\n" "... y: bytes\n" ">>> msg = {'x': [1, 2, 3], 'y': 'AQI='}\n" "\n" "Construct the message from a simpler set of builtin types.\n" "\n" ">>> msgspec.convert(msg, Example)\n" "Example({1, 2, 3}, b'\\x01\\x02')\n" "\n" "See Also\n" "--------\n" "to_builtins" ); static PyObject* msgspec_convert(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *obj = NULL, *pytype = NULL, *builtin_types = NULL, *dec_hook = NULL; int str_keys = false, strict = true, from_attributes = false; ConvertState state; char *kwlist[] = { "obj", "type", "strict", "from_attributes", "dec_hook", "builtin_types", "str_keys", NULL }; /* Parse arguments */ if (!PyArg_ParseTupleAndKeywords( args, kwargs, "OO|$ppOOp", kwlist, &obj, &pytype, &strict, &from_attributes, &dec_hook, &builtin_types, &str_keys )) { return NULL; } state.mod = msgspec_get_state(self); state.builtin_types = 0; state.from_attributes = from_attributes; state.strict = strict; if (strict) { state.str_keys = str_keys; if (ms_process_builtin_types(state.mod, builtin_types, &(state.builtin_types), NULL) < 0) { return NULL; } } else { state.str_keys = true; } if (dec_hook == Py_None) { dec_hook = NULL; } else if (dec_hook != NULL && !PyCallable_Check(dec_hook)) { PyErr_SetString(PyExc_TypeError, "dec_hook must be callable"); return NULL; } state.dec_hook = dec_hook; /* Avoid allocating a new TypeNode for struct types */ if (Py_TYPE(pytype) == &StructMetaType) { PyObject *info = StructInfo_Convert(pytype); if (info == NULL) return NULL; bool array_like = ((StructMetaObject *)pytype)->array_like == OPT_TRUE; TypeNodeSimple type; type.types = array_like ? MS_TYPE_STRUCT_ARRAY : MS_TYPE_STRUCT; type.details[0].pointer = info; PyObject *out = convert(&state, obj, (TypeNode *)(&type), NULL); Py_DECREF(info); return out; } TypeNode *type = TypeNode_Convert(pytype); if (type == NULL) return NULL; PyObject *out = convert(&state, obj, type, NULL); TypeNode_Free(type); return out; } /************************************************************************* * Module Setup * *************************************************************************/ static struct PyMethodDef msgspec_methods[] = { { "replace", (PyCFunction) struct_replace, METH_FASTCALL | METH_KEYWORDS, struct_replace__doc__, }, { "asdict", (PyCFunction) struct_asdict, METH_FASTCALL, struct_asdict__doc__, }, { "astuple", (PyCFunction) struct_astuple, METH_FASTCALL, struct_astuple__doc__, }, { "defstruct", (PyCFunction) msgspec_defstruct, METH_VARARGS | METH_KEYWORDS, msgspec_defstruct__doc__, }, { "force_setattr", (PyCFunction) struct_force_setattr, METH_FASTCALL, struct_force_setattr__doc__, }, { "msgpack_encode", (PyCFunction) msgspec_msgpack_encode, METH_FASTCALL | METH_KEYWORDS, msgspec_msgpack_encode__doc__, }, { "msgpack_decode", (PyCFunction) msgspec_msgpack_decode, METH_FASTCALL | METH_KEYWORDS, msgspec_msgpack_decode__doc__, }, { "json_encode", (PyCFunction) msgspec_json_encode, METH_FASTCALL | METH_KEYWORDS, msgspec_json_encode__doc__, }, { "json_decode", (PyCFunction) msgspec_json_decode, METH_FASTCALL | METH_KEYWORDS, msgspec_json_decode__doc__, }, { "json_format", (PyCFunction) msgspec_json_format, METH_VARARGS | METH_KEYWORDS, msgspec_json_format__doc__, }, { "to_builtins", (PyCFunction) msgspec_to_builtins, METH_VARARGS | METH_KEYWORDS, msgspec_to_builtins__doc__, }, { "convert", (PyCFunction) msgspec_convert, METH_VARARGS | METH_KEYWORDS, msgspec_convert__doc__, }, {NULL, NULL} /* sentinel */ }; static int msgspec_clear(PyObject *m) { MsgspecState *st = msgspec_get_state(m); Py_CLEAR(st->MsgspecError); Py_CLEAR(st->EncodeError); Py_CLEAR(st->DecodeError); Py_CLEAR(st->StructType); Py_CLEAR(st->EnumMetaType); Py_CLEAR(st->struct_lookup_cache); Py_CLEAR(st->str___weakref__); Py_CLEAR(st->str___dict__); Py_CLEAR(st->str___msgspec_cached_hash__); Py_CLEAR(st->str__value2member_map_); Py_CLEAR(st->str___msgspec_cache__); Py_CLEAR(st->str__value_); Py_CLEAR(st->str__missing_); Py_CLEAR(st->str_type); Py_CLEAR(st->str_enc_hook); Py_CLEAR(st->str_dec_hook); Py_CLEAR(st->str_ext_hook); Py_CLEAR(st->str_strict); Py_CLEAR(st->str_order); Py_CLEAR(st->str_utcoffset); Py_CLEAR(st->str___origin__); Py_CLEAR(st->str___args__); Py_CLEAR(st->str___metadata__); Py_CLEAR(st->str___total__); Py_CLEAR(st->str___required_keys__); Py_CLEAR(st->str__fields); Py_CLEAR(st->str__field_defaults); Py_CLEAR(st->str___post_init__); Py_CLEAR(st->str___dataclass_fields__); Py_CLEAR(st->str___attrs_attrs__); Py_CLEAR(st->str___supertype__); #if PY312_PLUS Py_CLEAR(st->str___value__); #endif Py_CLEAR(st->str___bound__); Py_CLEAR(st->str___constraints__); Py_CLEAR(st->str_int); Py_CLEAR(st->str_is_safe); Py_CLEAR(st->UUIDType); Py_CLEAR(st->uuid_safeuuid_unknown); Py_CLEAR(st->DecimalType); Py_CLEAR(st->typing_union); Py_CLEAR(st->typing_any); Py_CLEAR(st->typing_literal); Py_CLEAR(st->typing_classvar); Py_CLEAR(st->typing_typevar); Py_CLEAR(st->typing_final); Py_CLEAR(st->typing_generic); Py_CLEAR(st->typing_generic_alias); Py_CLEAR(st->typing_annotated_alias); Py_CLEAR(st->concrete_types); Py_CLEAR(st->get_type_hints); Py_CLEAR(st->get_class_annotations); Py_CLEAR(st->get_typeddict_info); Py_CLEAR(st->get_dataclass_info); Py_CLEAR(st->rebuild); #if PY310_PLUS Py_CLEAR(st->types_uniontype); #endif #if PY312_PLUS Py_CLEAR(st->typing_typealiastype); #endif Py_CLEAR(st->astimezone); Py_CLEAR(st->re_compile); return 0; } static void msgspec_free(PyObject *m) { msgspec_clear(m); } static int msgspec_traverse(PyObject *m, visitproc visit, void *arg) { MsgspecState *st = msgspec_get_state(m); /* Clear the string cache every 10 major GC passes. * * The string cache can help improve performance in 2 different situations: * * - Calling untyped `json.decode` on a large message, where many keys are * repeated within the same message. * - Calling untyped `json.decode` in a hot loop on many messages that * share the same structure. * * In both cases, the string cache helps because common keys are more * likely to remain in cache. We do want to periodically clear the cache so * the allocator can free up old pages and reduce fragmentation, but we * want to do so as infrequently as possible. I've arbitrarily picked 10 * major GC passes here as a heuristic. * * With the current configuration, the string cache may consume up to 20 * KiB at a time, but that's with 100% of slots filled (unlikely due to * collisions). 50% filled is more likely, so 12 KiB max is a reasonable * estimate. */ st->gc_cycle++; if (st->gc_cycle == 10) { st->gc_cycle = 0; string_cache_clear(); timezone_cache_clear(); } Py_VISIT(st->MsgspecError); Py_VISIT(st->EncodeError); Py_VISIT(st->DecodeError); Py_VISIT(st->StructType); Py_VISIT(st->EnumMetaType); Py_VISIT(st->struct_lookup_cache); Py_VISIT(st->typing_union); Py_VISIT(st->typing_any); Py_VISIT(st->typing_literal); Py_VISIT(st->typing_classvar); Py_VISIT(st->typing_typevar); Py_VISIT(st->typing_final); Py_VISIT(st->typing_generic); Py_VISIT(st->typing_generic_alias); Py_VISIT(st->typing_annotated_alias); Py_VISIT(st->concrete_types); Py_VISIT(st->get_type_hints); Py_VISIT(st->get_class_annotations); Py_VISIT(st->get_typeddict_info); Py_VISIT(st->get_dataclass_info); Py_VISIT(st->rebuild); #if PY310_PLUS Py_VISIT(st->types_uniontype); #endif #if PY312_PLUS Py_VISIT(st->typing_typealiastype); #endif Py_VISIT(st->astimezone); Py_VISIT(st->re_compile); return 0; } static struct PyModuleDef msgspecmodule = { PyModuleDef_HEAD_INIT, .m_name = "msgspec._core", .m_size = sizeof(MsgspecState), .m_methods = msgspec_methods, .m_traverse = msgspec_traverse, .m_clear = msgspec_clear, .m_free =(freefunc)msgspec_free }; PyMODINIT_FUNC PyInit__core(void) { PyObject *m, *temp_module, *temp_obj; MsgspecState *st; PyDateTime_IMPORT; m = PyState_FindModule(&msgspecmodule); if (m) { Py_INCREF(m); return m; } StructMetaType.tp_base = &PyType_Type; if (PyType_Ready(&NoDefault_Type) < 0) return NULL; if (PyType_Ready(&Unset_Type) < 0) return NULL; if (PyType_Ready(&Factory_Type) < 0) return NULL; if (PyType_Ready(&Field_Type) < 0) return NULL; if (PyType_Ready(&IntLookup_Type) < 0) return NULL; if (PyType_Ready(&StrLookup_Type) < 0) return NULL; if (PyType_Ready(&LiteralInfo_Type) < 0) return NULL; if (PyType_Ready(&TypedDictInfo_Type) < 0) return NULL; if (PyType_Ready(&DataclassInfo_Type) < 0) return NULL; if (PyType_Ready(&NamedTupleInfo_Type) < 0) return NULL; if (PyType_Ready(&StructInfo_Type) < 0) return NULL; if (PyType_Ready(&Meta_Type) < 0) return NULL; if (PyType_Ready(&StructMetaType) < 0) return NULL; if (PyType_Ready(&StructMixinType) < 0) return NULL; if (PyType_Ready(&StructConfig_Type) < 0) return NULL; if (PyType_Ready(&Encoder_Type) < 0) return NULL; if (PyType_Ready(&Decoder_Type) < 0) return NULL; if (PyType_Ready(&Ext_Type) < 0) return NULL; if (PyType_Ready(&Raw_Type) < 0) return NULL; if (PyType_Ready(&JSONEncoder_Type) < 0) return NULL; if (PyType_Ready(&JSONDecoder_Type) < 0) return NULL; /* Create the module */ m = PyModule_Create(&msgspecmodule); if (m == NULL) return NULL; /* Add types */ Py_INCREF(&Factory_Type); if (PyModule_AddObject(m, "Factory", (PyObject *)&Factory_Type) < 0) return NULL; if (PyModule_AddObject(m, "Field", (PyObject *)&Field_Type) < 0) return NULL; Py_INCREF(&Meta_Type); if (PyModule_AddObject(m, "Meta", (PyObject *)&Meta_Type) < 0) return NULL; Py_INCREF(&StructConfig_Type); if (PyModule_AddObject(m, "StructConfig", (PyObject *)&StructConfig_Type) < 0) return NULL; Py_INCREF(&Ext_Type); if (PyModule_AddObject(m, "Ext", (PyObject *)&Ext_Type) < 0) return NULL; Py_INCREF(&Raw_Type); if (PyModule_AddObject(m, "Raw", (PyObject *)&Raw_Type) < 0) return NULL; Py_INCREF(&Encoder_Type); if (PyModule_AddObject(m, "MsgpackEncoder", (PyObject *)&Encoder_Type) < 0) return NULL; Py_INCREF(&Decoder_Type); if (PyModule_AddObject(m, "MsgpackDecoder", (PyObject *)&Decoder_Type) < 0) return NULL; Py_INCREF(&JSONEncoder_Type); if (PyModule_AddObject(m, "JSONEncoder", (PyObject *)&JSONEncoder_Type) < 0) return NULL; Py_INCREF(&JSONDecoder_Type); if (PyModule_AddObject(m, "JSONDecoder", (PyObject *)&JSONDecoder_Type) < 0) return NULL; Py_INCREF(&Unset_Type); if (PyModule_AddObject(m, "UnsetType", (PyObject *)&Unset_Type) < 0) return NULL; st = msgspec_get_state(m); /* Initialize GC counter */ st->gc_cycle = 0; /* Add NODEFAULT singleton */ Py_INCREF(NODEFAULT); if (PyModule_AddObject(m, "NODEFAULT", NODEFAULT) < 0) return NULL; /* Add UNSET singleton */ Py_INCREF(UNSET); if (PyModule_AddObject(m, "UNSET", UNSET) < 0) return NULL; /* Initialize the exceptions. */ st->MsgspecError = PyErr_NewExceptionWithDoc( "msgspec.MsgspecError", "Base class for all Msgspec exceptions", NULL, NULL ); if (st->MsgspecError == NULL) return NULL; st->EncodeError = PyErr_NewExceptionWithDoc( "msgspec.EncodeError", "An error occurred while encoding an object", st->MsgspecError, NULL ); if (st->EncodeError == NULL) return NULL; st->DecodeError = PyErr_NewExceptionWithDoc( "msgspec.DecodeError", "An error occurred while decoding an object", st->MsgspecError, NULL ); if (st->DecodeError == NULL) return NULL; st->ValidationError = PyErr_NewExceptionWithDoc( "msgspec.ValidationError", "The message didn't match the expected schema", st->DecodeError, NULL ); if (st->ValidationError == NULL) return NULL; Py_INCREF(st->MsgspecError); if (PyModule_AddObject(m, "MsgspecError", st->MsgspecError) < 0) return NULL; Py_INCREF(st->EncodeError); if (PyModule_AddObject(m, "EncodeError", st->EncodeError) < 0) return NULL; Py_INCREF(st->DecodeError); if (PyModule_AddObject(m, "DecodeError", st->DecodeError) < 0) return NULL; Py_INCREF(st->ValidationError); if (PyModule_AddObject(m, "ValidationError", st->ValidationError) < 0) return NULL; /* Initialize the struct_lookup_cache */ st->struct_lookup_cache = PyDict_New(); if (st->struct_lookup_cache == NULL) return NULL; Py_INCREF(st->struct_lookup_cache); if (PyModule_AddObject(m, "_struct_lookup_cache", st->struct_lookup_cache) < 0) return NULL; #define SET_REF(attr, name) \ do { \ st->attr = PyObject_GetAttrString(temp_module, name); \ if (st->attr == NULL) return NULL; \ } while (0) /* Get all imports from the typing module */ temp_module = PyImport_ImportModule("typing"); if (temp_module == NULL) return NULL; SET_REF(typing_union, "Union"); SET_REF(typing_any, "Any"); SET_REF(typing_literal, "Literal"); SET_REF(typing_classvar, "ClassVar"); SET_REF(typing_typevar, "TypeVar"); SET_REF(typing_final, "Final"); SET_REF(typing_generic, "Generic"); SET_REF(typing_generic_alias, "_GenericAlias"); #if PY312_PLUS SET_REF(typing_typealiastype, "TypeAliasType"); #endif Py_DECREF(temp_module); temp_module = PyImport_ImportModule("msgspec._utils"); if (temp_module == NULL) return NULL; SET_REF(concrete_types, "_CONCRETE_TYPES"); SET_REF(get_type_hints, "get_type_hints"); SET_REF(get_class_annotations, "get_class_annotations"); SET_REF(get_typeddict_info, "get_typeddict_info"); SET_REF(get_dataclass_info, "get_dataclass_info"); SET_REF(typing_annotated_alias, "_AnnotatedAlias"); SET_REF(rebuild, "rebuild"); Py_DECREF(temp_module); #if PY310_PLUS temp_module = PyImport_ImportModule("types"); if (temp_module == NULL) return NULL; SET_REF(types_uniontype, "UnionType"); Py_DECREF(temp_module); #endif /* Get the EnumMeta type */ temp_module = PyImport_ImportModule("enum"); if (temp_module == NULL) return NULL; temp_obj = PyObject_GetAttrString(temp_module, "EnumMeta"); Py_DECREF(temp_module); if (temp_obj == NULL) return NULL; if (!PyType_Check(temp_obj)) { Py_DECREF(temp_obj); PyErr_SetString(PyExc_TypeError, "enum.EnumMeta should be a type"); return NULL; } st->EnumMetaType = (PyTypeObject *)temp_obj; /* Get the datetime.datetime.astimezone method */ temp_module = PyImport_ImportModule("datetime"); if (temp_module == NULL) return NULL; temp_obj = PyObject_GetAttrString(temp_module, "datetime"); Py_DECREF(temp_module); if (temp_obj == NULL) return NULL; st->astimezone = PyObject_GetAttrString(temp_obj, "astimezone"); Py_DECREF(temp_obj); if (st->astimezone == NULL) return NULL; /* uuid module imports */ temp_module = PyImport_ImportModule("uuid"); if (temp_module == NULL) return NULL; st->UUIDType = PyObject_GetAttrString(temp_module, "UUID"); if (st->UUIDType == NULL) return NULL; temp_obj = PyObject_GetAttrString(temp_module, "SafeUUID"); if (temp_obj == NULL) return NULL; st->uuid_safeuuid_unknown = PyObject_GetAttrString(temp_obj, "unknown"); Py_DECREF(temp_obj); if (st->uuid_safeuuid_unknown == NULL) return NULL; /* decimal module imports */ temp_module = PyImport_ImportModule("decimal"); if (temp_module == NULL) return NULL; st->DecimalType = PyObject_GetAttrString(temp_module, "Decimal"); if (st->DecimalType == NULL) return NULL; /* Get the re.compile function */ temp_module = PyImport_ImportModule("re"); if (temp_module == NULL) return NULL; st->re_compile = PyObject_GetAttrString(temp_module, "compile"); Py_DECREF(temp_module); if (st->re_compile == NULL) return NULL; /* Initialize cached constant strings */ #define CACHED_STRING(attr, str) \ if ((st->attr = PyUnicode_InternFromString(str)) == NULL) return NULL CACHED_STRING(str___weakref__, "__weakref__"); CACHED_STRING(str___dict__, "__dict__"); CACHED_STRING(str___msgspec_cached_hash__, "__msgspec_cached_hash__"); CACHED_STRING(str__value2member_map_, "_value2member_map_"); CACHED_STRING(str___msgspec_cache__, "__msgspec_cache__"); CACHED_STRING(str__value_, "_value_"); CACHED_STRING(str__missing_, "_missing_"); CACHED_STRING(str_type, "type"); CACHED_STRING(str_enc_hook, "enc_hook"); CACHED_STRING(str_dec_hook, "dec_hook"); CACHED_STRING(str_ext_hook, "ext_hook"); CACHED_STRING(str_strict, "strict"); CACHED_STRING(str_order, "order"); CACHED_STRING(str_utcoffset, "utcoffset"); CACHED_STRING(str___origin__, "__origin__"); CACHED_STRING(str___args__, "__args__"); CACHED_STRING(str___metadata__, "__metadata__"); CACHED_STRING(str___total__, "__total__"); CACHED_STRING(str___required_keys__, "__required_keys__"); CACHED_STRING(str__fields, "_fields"); CACHED_STRING(str__field_defaults, "_field_defaults"); CACHED_STRING(str___post_init__, "__post_init__"); CACHED_STRING(str___dataclass_fields__, "__dataclass_fields__"); CACHED_STRING(str___attrs_attrs__, "__attrs_attrs__"); CACHED_STRING(str___supertype__, "__supertype__"); #if PY312_PLUS CACHED_STRING(str___value__, "__value__"); #endif CACHED_STRING(str___bound__, "__bound__"); CACHED_STRING(str___constraints__, "__constraints__"); CACHED_STRING(str_int, "int"); CACHED_STRING(str_is_safe, "is_safe"); /* Initialize the Struct Type */ PyState_AddModule(m, &msgspecmodule); st->StructType = PyObject_CallFunction( (PyObject *)&StructMetaType, "s(O){ssss}", "Struct", &StructMixinType, "__module__", "msgspec", "__doc__", Struct__doc__ ); if (st->StructType == NULL) return NULL; Py_INCREF(st->StructType); if (PyModule_AddObject(m, "Struct", st->StructType) < 0) return NULL; return m; } python-msgspec-0.19.0/msgspec/_json_schema.py000066400000000000000000000404221473355726200212440ustar00rootroot00000000000000from __future__ import annotations import re import textwrap from collections.abc import Iterable from typing import Any, Optional, Callable from . import inspect as mi, to_builtins __all__ = ("schema", "schema_components") def schema( type: Any, *, schema_hook: Optional[Callable[[type], dict[str, Any]]] = None ) -> dict[str, Any]: """Generate a JSON Schema for a given type. Any schemas for (potentially) shared components are extracted and stored in a top-level ``"$defs"`` field. If you want to generate schemas for multiple types, or to have more control over the generated schema you may want to use ``schema_components`` instead. Parameters ---------- type : type The type to generate the schema for. schema_hook : callable, optional An optional callback to use for generating JSON schemas of custom types. Will be called with the custom type, and should return a dict representation of the JSON schema for that type. Returns ------- schema : dict The generated JSON Schema. See Also -------- schema_components """ (out,), components = schema_components((type,), schema_hook=schema_hook) if components: out["$defs"] = components return out def schema_components( types: Iterable[Any], *, schema_hook: Optional[Callable[[type], dict[str, Any]]] = None, ref_template: str = "#/$defs/{name}", ) -> tuple[tuple[dict[str, Any], ...], dict[str, Any]]: """Generate JSON Schemas for one or more types. Any schemas for (potentially) shared components are extracted and returned in a separate ``components`` dict. Parameters ---------- types : Iterable[type] An iterable of one or more types to generate schemas for. schema_hook : callable, optional An optional callback to use for generating JSON schemas of custom types. Will be called with the custom type, and should return a dict representation of the JSON schema for that type. ref_template : str, optional A template to use when generating ``"$ref"`` fields. This template is formatted with the type name as ``template.format(name=name)``. This can be useful if you intend to store the ``components`` mapping somewhere other than a top-level ``"$defs"`` field. For example, you might use ``ref_template="#/components/{name}"`` if generating an OpenAPI schema. Returns ------- schemas : tuple[dict] A tuple of JSON Schemas, one for each type in ``types``. components : dict A mapping of name to schema for any shared components used by ``schemas``. See Also -------- schema """ type_infos = mi.multi_type_info(types) component_types = _collect_component_types(type_infos) name_map = _build_name_map(component_types) gen = _SchemaGenerator(name_map, schema_hook, ref_template) schemas = tuple(gen.to_schema(t) for t in type_infos) components = { name_map[cls]: gen.to_schema(t, False) for cls, t in component_types.items() } return schemas, components def _collect_component_types(type_infos: Iterable[mi.Type]) -> dict[Any, mi.Type]: """Find all types in the type tree that are "nameable" and worthy of being extracted out into a shared top-level components mapping. Currently this looks for Struct, Dataclass, NamedTuple, TypedDict, and Enum types. """ components = {} def collect(t): if isinstance( t, (mi.StructType, mi.TypedDictType, mi.DataclassType, mi.NamedTupleType) ): if t.cls not in components: components[t.cls] = t for f in t.fields: collect(f.type) elif isinstance(t, mi.EnumType): components[t.cls] = t elif isinstance(t, mi.Metadata): collect(t.type) elif isinstance(t, mi.CollectionType): collect(t.item_type) elif isinstance(t, mi.TupleType): for st in t.item_types: collect(st) elif isinstance(t, mi.DictType): collect(t.key_type) collect(t.value_type) elif isinstance(t, mi.UnionType): for st in t.types: collect(st) for t in type_infos: collect(t) return components def _type_repr(obj): return obj.__name__ if isinstance(obj, type) else repr(obj) def _get_class_name(cls: Any) -> str: if hasattr(cls, "__origin__"): name = cls.__origin__.__name__ args = ", ".join(_type_repr(a) for a in cls.__args__) return f"{name}[{args}]" return cls.__name__ def _get_doc(t: mi.Type) -> str: assert hasattr(t, "cls") cls = getattr(t.cls, "__origin__", t.cls) doc = getattr(cls, "__doc__", "") if not doc: return "" doc = textwrap.dedent(doc).strip("\r\n") if isinstance(t, mi.EnumType): if doc == "An enumeration.": return "" elif isinstance(t, (mi.NamedTupleType, mi.DataclassType)): if doc.startswith(f"{cls.__name__}(") and doc.endswith(")"): return "" return doc def _build_name_map(component_types: dict[Any, mi.Type]) -> dict[Any, str]: """A mapping from nameable subcomponents to a generated name. The generated name is usually a normalized version of the class name. In the case of conflicts, the name will be expanded to also include the full import path. """ def normalize(name): return re.sub(r"[^a-zA-Z0-9.\-_]", "_", name) def fullname(cls): return normalize(f"{cls.__module__}.{cls.__qualname__}") conflicts = set() names: dict[str, Any] = {} for cls in component_types: name = normalize(_get_class_name(cls)) if name in names: old = names.pop(name) conflicts.add(name) names[fullname(old)] = old if name in conflicts: names[fullname(cls)] = cls else: names[name] = cls return {v: k for k, v in names.items()} class _SchemaGenerator: def __init__( self, name_map: dict[Any, str], schema_hook: Optional[Callable[[type], dict[str, Any]]] = None, ref_template: str = "#/$defs/{name}", ): self.name_map = name_map self.schema_hook = schema_hook self.ref_template = ref_template def to_schema(self, t: mi.Type, check_ref: bool = True) -> dict[str, Any]: """Converts a Type to a json-schema.""" schema: dict[str, Any] = {} while isinstance(t, mi.Metadata): schema = mi._merge_json(schema, t.extra_json_schema) t = t.type if check_ref and hasattr(t, "cls"): if name := self.name_map.get(t.cls): schema["$ref"] = self.ref_template.format(name=name) return schema if isinstance(t, (mi.AnyType, mi.RawType)): pass elif isinstance(t, mi.NoneType): schema["type"] = "null" elif isinstance(t, mi.BoolType): schema["type"] = "boolean" elif isinstance(t, (mi.IntType, mi.FloatType)): schema["type"] = "integer" if isinstance(t, mi.IntType) else "number" if t.ge is not None: schema["minimum"] = t.ge if t.gt is not None: schema["exclusiveMinimum"] = t.gt if t.le is not None: schema["maximum"] = t.le if t.lt is not None: schema["exclusiveMaximum"] = t.lt if t.multiple_of is not None: schema["multipleOf"] = t.multiple_of elif isinstance(t, mi.StrType): schema["type"] = "string" if t.max_length is not None: schema["maxLength"] = t.max_length if t.min_length is not None: schema["minLength"] = t.min_length if t.pattern is not None: schema["pattern"] = t.pattern elif isinstance(t, (mi.BytesType, mi.ByteArrayType, mi.MemoryViewType)): schema["type"] = "string" schema["contentEncoding"] = "base64" if t.max_length is not None: schema["maxLength"] = 4 * ((t.max_length + 2) // 3) if t.min_length is not None: schema["minLength"] = 4 * ((t.min_length + 2) // 3) elif isinstance(t, mi.DateTimeType): schema["type"] = "string" if t.tz is True: schema["format"] = "date-time" elif isinstance(t, mi.TimeType): schema["type"] = "string" if t.tz is True: schema["format"] = "time" elif t.tz is False: schema["format"] = "partial-time" elif isinstance(t, mi.DateType): schema["type"] = "string" schema["format"] = "date" elif isinstance(t, mi.TimeDeltaType): schema["type"] = "string" schema["format"] = "duration" elif isinstance(t, mi.UUIDType): schema["type"] = "string" schema["format"] = "uuid" elif isinstance(t, mi.DecimalType): schema["type"] = "string" schema["format"] = "decimal" elif isinstance(t, mi.CollectionType): schema["type"] = "array" if not isinstance(t.item_type, mi.AnyType): schema["items"] = self.to_schema(t.item_type) if t.max_length is not None: schema["maxItems"] = t.max_length if t.min_length is not None: schema["minItems"] = t.min_length elif isinstance(t, mi.TupleType): schema["type"] = "array" schema["minItems"] = schema["maxItems"] = len(t.item_types) if t.item_types: schema["prefixItems"] = [self.to_schema(i) for i in t.item_types] schema["items"] = False elif isinstance(t, mi.DictType): schema["type"] = "object" # If there are restrictions on the keys, specify them as propertyNames if isinstance(key_type := t.key_type, mi.StrType): property_names: dict[str, Any] = {} if key_type.min_length is not None: property_names["minLength"] = key_type.min_length if key_type.max_length is not None: property_names["maxLength"] = key_type.max_length if key_type.pattern is not None: property_names["pattern"] = key_type.pattern if property_names: schema["propertyNames"] = property_names if not isinstance(t.value_type, mi.AnyType): schema["additionalProperties"] = self.to_schema(t.value_type) if t.max_length is not None: schema["maxProperties"] = t.max_length if t.min_length is not None: schema["minProperties"] = t.min_length elif isinstance(t, mi.UnionType): structs = {} other = [] tag_field = None for subtype in t.types: real_type = subtype while isinstance(real_type, mi.Metadata): real_type = real_type.type if isinstance(real_type, mi.StructType) and not real_type.array_like: tag_field = real_type.tag_field structs[real_type.tag] = real_type else: other.append(subtype) options = [self.to_schema(a) for a in other] if len(structs) >= 2: mapping = { k: self.ref_template.format(name=self.name_map[v.cls]) for k, v in structs.items() } struct_schema = { "anyOf": [self.to_schema(v) for v in structs.values()], "discriminator": {"propertyName": tag_field, "mapping": mapping}, } if options: options.append(struct_schema) schema["anyOf"] = options else: schema.update(struct_schema) elif len(structs) == 1: _, subtype = structs.popitem() options.append(self.to_schema(subtype)) schema["anyOf"] = options else: schema["anyOf"] = options elif isinstance(t, mi.LiteralType): schema["enum"] = sorted(t.values) elif isinstance(t, mi.EnumType): schema.setdefault("title", t.cls.__name__) if doc := _get_doc(t): schema.setdefault("description", doc) schema["enum"] = sorted(e.value for e in t.cls) elif isinstance(t, mi.StructType): schema.setdefault("title", _get_class_name(t.cls)) if doc := _get_doc(t): schema.setdefault("description", doc) required = [] names = [] fields = [] if t.tag_field is not None: required.append(t.tag_field) names.append(t.tag_field) fields.append({"enum": [t.tag]}) for field in t.fields: field_schema = self.to_schema(field.type) if field.required: required.append(field.encode_name) elif field.default is not mi.NODEFAULT: field_schema["default"] = to_builtins(field.default, str_keys=True) elif field.default_factory in (list, dict, set, bytearray): field_schema["default"] = field.default_factory() names.append(field.encode_name) fields.append(field_schema) if t.array_like: n_trailing_defaults = 0 for n_trailing_defaults, f in enumerate(reversed(t.fields)): if f.required: break schema["type"] = "array" schema["prefixItems"] = fields schema["minItems"] = len(fields) - n_trailing_defaults if t.forbid_unknown_fields: schema["maxItems"] = len(fields) else: schema["type"] = "object" schema["properties"] = dict(zip(names, fields)) schema["required"] = required if t.forbid_unknown_fields: schema["additionalProperties"] = False elif isinstance(t, (mi.TypedDictType, mi.DataclassType, mi.NamedTupleType)): schema.setdefault("title", _get_class_name(t.cls)) if doc := _get_doc(t): schema.setdefault("description", doc) names = [] fields = [] required = [] for field in t.fields: field_schema = self.to_schema(field.type) if field.required: required.append(field.encode_name) elif field.default is not mi.NODEFAULT: field_schema["default"] = to_builtins(field.default, str_keys=True) names.append(field.encode_name) fields.append(field_schema) if isinstance(t, mi.NamedTupleType): schema["type"] = "array" schema["prefixItems"] = fields schema["minItems"] = len(required) schema["maxItems"] = len(fields) else: schema["type"] = "object" schema["properties"] = dict(zip(names, fields)) schema["required"] = required elif isinstance(t, mi.ExtType): raise TypeError("json-schema doesn't support msgpack Ext types") elif isinstance(t, mi.CustomType): if self.schema_hook: try: schema = mi._merge_json(self.schema_hook(t.cls), schema) except NotImplementedError: pass if not schema: raise TypeError( "Generating JSON schema for custom types requires either:\n" "- specifying a `schema_hook`\n" "- annotating the type with `Meta(extra_json_schema=...)`\n" "\n" f"type {t.cls!r} is not supported" ) else: # This should be unreachable raise TypeError(f"json-schema doesn't support type {t!r}") return schema python-msgspec-0.19.0/msgspec/_utils.py000066400000000000000000000235651473355726200201240ustar00rootroot00000000000000# type: ignore import collections import sys import typing from typing import _AnnotatedAlias # noqa: F401 try: from typing_extensions import get_type_hints as _get_type_hints except Exception: from typing import get_type_hints as _get_type_hints try: from typing_extensions import NotRequired, Required except Exception: try: from typing import NotRequired, Required except Exception: Required = NotRequired = None def get_type_hints(obj): return _get_type_hints(obj, include_extras=True) # The `is_class` argument was new in 3.11, but was backported to 3.9 and 3.10. # It's _likely_ to be available for 3.9/3.10, but may not be. Easiest way to # check is to try it and see. This check can be removed when we drop support # for Python 3.10. try: typing.ForwardRef("Foo", is_class=True) except TypeError: def _forward_ref(value): return typing.ForwardRef(value, is_argument=False) else: def _forward_ref(value): return typing.ForwardRef(value, is_argument=False, is_class=True) # Python 3.13 adds a new mandatory type_params kwarg to _eval_type if sys.version_info >= (3, 13): def _eval_type(t, globalns, localns): return typing._eval_type(t, globalns, localns, ()) elif sys.version_info < (3, 10): def _eval_type(t, globalns, localns): try: return typing._eval_type(t, globalns, localns) except TypeError as e: try: from eval_type_backport import eval_type_backport except ImportError: raise TypeError( f"Unable to evaluate type annotation {t.__forward_arg__!r}. If you are making use " "of the new typing syntax (unions using `|` since Python 3.10 or builtins subscripting " "since Python 3.9), you should either replace the use of new syntax with the existing " "`typing` constructs or install the `eval_type_backport` package." ) from e return eval_type_backport( t, globalns, localns, try_default=False, ) else: _eval_type = typing._eval_type def _apply_params(obj, mapping): if isinstance(obj, typing.TypeVar): return mapping.get(obj, obj) try: parameters = tuple(obj.__parameters__) except Exception: # Not parameterized or __parameters__ is invalid, ignore return obj if not parameters: # Not parametrized return obj # Parametrized args = tuple(mapping.get(p, p) for p in parameters) return obj[args] def _get_class_mro_and_typevar_mappings(obj): mapping = {} if isinstance(obj, type): cls = obj else: cls = obj.__origin__ def inner(c, scope): if isinstance(c, type): cls = c new_scope = {} else: cls = getattr(c, "__origin__", None) if cls in (None, object, typing.Generic) or cls in mapping: return params = cls.__parameters__ args = tuple(_apply_params(a, scope) for a in c.__args__) assert len(params) == len(args) mapping[cls] = new_scope = dict(zip(params, args)) if issubclass(cls, typing.Generic): bases = getattr(cls, "__orig_bases__", cls.__bases__) for b in bases: inner(b, new_scope) inner(obj, {}) return cls.__mro__, mapping def get_class_annotations(obj): """Get the annotations for a class. This is similar to ``typing.get_type_hints``, except: - We maintain it - It leaves extras like ``Annotated``/``ClassVar`` alone - It resolves any parametrized generics in the class mro. The returned mapping may still include ``TypeVar`` values, but those should be treated as their unparametrized variants (i.e. equal to ``Any`` for the common case). Note that this function doesn't check that Generic types are being used properly - invalid uses of `Generic` may slip through without complaint. The assumption here is that the user is making use of a static analysis tool like ``mypy``/``pyright`` already, which would catch misuse of these APIs. """ hints = {} mro, typevar_mappings = _get_class_mro_and_typevar_mappings(obj) for cls in mro: if cls in (typing.Generic, object): continue mapping = typevar_mappings.get(cls) cls_locals = dict(vars(cls)) cls_globals = getattr(sys.modules.get(cls.__module__, None), "__dict__", {}) ann = cls.__dict__.get("__annotations__", {}) for name, value in ann.items(): if name in hints: continue if value is None: value = type(None) elif isinstance(value, str): value = _forward_ref(value) value = _eval_type(value, cls_locals, cls_globals) if mapping is not None: value = _apply_params(value, mapping) hints[name] = value return hints # A mapping from a type annotation (or annotation __origin__) to the concrete # python type that msgspec will use when decoding. THIS IS PRIVATE FOR A # REASON. DON'T MUCK WITH THIS. _CONCRETE_TYPES = { list: list, tuple: tuple, set: set, frozenset: frozenset, dict: dict, typing.List: list, typing.Tuple: tuple, typing.Set: set, typing.FrozenSet: frozenset, typing.Dict: dict, typing.Collection: list, typing.MutableSequence: list, typing.Sequence: list, typing.MutableMapping: dict, typing.Mapping: dict, typing.MutableSet: set, typing.AbstractSet: set, collections.abc.Collection: list, collections.abc.MutableSequence: list, collections.abc.Sequence: list, collections.abc.MutableSet: set, collections.abc.Set: set, collections.abc.MutableMapping: dict, collections.abc.Mapping: dict, } def get_typeddict_info(obj): if isinstance(obj, type): cls = obj else: cls = obj.__origin__ raw_hints = get_class_annotations(obj) if hasattr(cls, "__required_keys__"): required = set(cls.__required_keys__) elif cls.__total__: required = set(raw_hints) else: required = set() # Both `typing.TypedDict` and `typing_extensions.TypedDict` have a bug # where `Required`/`NotRequired` aren't properly detected at runtime when # `__future__.annotations` is enabled, meaning the `__required_keys__` # isn't correct. This code block works around this issue by amending the # set of required keys as needed, while also stripping off any # `Required`/`NotRequired` wrappers. hints = {} for k, v in raw_hints.items(): origin = getattr(v, "__origin__", False) if origin is Required: required.add(k) hints[k] = v.__args__[0] elif origin is NotRequired: required.discard(k) hints[k] = v.__args__[0] else: hints[k] = v return hints, required def get_dataclass_info(obj): if isinstance(obj, type): cls = obj else: cls = obj.__origin__ hints = get_class_annotations(obj) required = [] optional = [] defaults = [] if hasattr(cls, "__dataclass_fields__"): from dataclasses import _FIELD, _FIELD_INITVAR, MISSING for field in cls.__dataclass_fields__.values(): if field._field_type is not _FIELD: if field._field_type is _FIELD_INITVAR: raise TypeError( "dataclasses with `InitVar` fields are not supported" ) continue name = field.name typ = hints[name] if field.default is not MISSING: defaults.append(field.default) optional.append((name, typ, False)) elif field.default_factory is not MISSING: defaults.append(field.default_factory) optional.append((name, typ, True)) else: required.append((name, typ, False)) required.extend(optional) pre_init = None post_init = getattr(cls, "__post_init__", None) else: from attrs import NOTHING, Factory fields_with_validators = [] for field in cls.__attrs_attrs__: name = field.name typ = hints[name] default = field.default if default is not NOTHING: if isinstance(default, Factory): if default.takes_self: raise NotImplementedError( "Support for default factories with `takes_self=True` " "is not implemented. File a GitHub issue if you need " "this feature!" ) defaults.append(default.factory) optional.append((name, typ, True)) else: defaults.append(default) optional.append((name, typ, False)) else: required.append((name, typ, False)) if field.validator is not None: fields_with_validators.append(field) required.extend(optional) pre_init = getattr(cls, "__attrs_pre_init__", None) post_init = getattr(cls, "__attrs_post_init__", None) if fields_with_validators: post_init = _wrap_attrs_validators(fields_with_validators, post_init) return cls, tuple(required), tuple(defaults), pre_init, post_init def _wrap_attrs_validators(fields, post_init): def inner(obj): for field in fields: field.validator(obj, field, getattr(obj, field.name)) if post_init is not None: post_init(obj) return inner def rebuild(cls, kwargs): """Used to unpickle Structs with keyword-only fields""" return cls(**kwargs) python-msgspec-0.19.0/msgspec/_version.py000066400000000000000000000445111473355726200204430ustar00rootroot00000000000000# type: ignore # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build # directories (produced by setup.py build) will contain a much shorter file # that just contains the computed version number. # This file is released into the public domain. Generated by # versioneer-0.19 (https://github.com/python-versioneer/python-versioneer) """Git implementation of _version.py.""" import errno import os import re import subprocess import sys def get_keywords(): """Get the keywords needed to look up the version information.""" # these strings will be replaced by git during git-archive. # setup.py/versioneer.py will grep for the variable names, so they must # each be defined on a line of their own. _version.py will just call # get_keywords(). git_refnames = " (grafted, HEAD, tag: 0.19.0)" git_full = "dd965dce22e5278d4935bea923441ecde31b5325" git_date = "2024-12-27 11:06:58 -0600" keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} return keywords class VersioneerConfig: """Container for Versioneer configuration parameters.""" def get_config(): """Create, populate and return the VersioneerConfig() object.""" # these strings are filled in when 'setup.py versioneer' creates # _version.py cfg = VersioneerConfig() cfg.VCS = "git" cfg.style = "pep440" cfg.tag_prefix = "" cfg.parentdir_prefix = "msgspec-" cfg.versionfile_source = "msgspec/_version.py" cfg.verbose = False return cfg class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" LONG_VERSION_PY = {} HANDLERS = {} def register_vcs_handler(vcs, method): # decorator """Create decorator to mark a method as the handler of a VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: HANDLERS[vcs] = {} HANDLERS[vcs][method] = f return f return decorate def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) p = None for c in commands: try: dispcmd = str([c] + args) # remember shell=False, so use git.cmd on windows, not just git p = subprocess.Popen( [c] + args, cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=(subprocess.PIPE if hide_stderr else None), ) break except EnvironmentError: e = sys.exc_info()[1] if e.errno == errno.ENOENT: continue if verbose: print("unable to run %s" % dispcmd) print(e) return None, None else: if verbose: print("unable to find command, tried %s" % (commands,)) return None, None stdout = p.communicate()[0].strip().decode() if p.returncode != 0: if verbose: print("unable to run %s (error)" % dispcmd) print("stdout was %s" % stdout) return None, p.returncode return stdout, p.returncode def versions_from_parentdir(parentdir_prefix, root, verbose): """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both the project name and a version string. We will also support searching up two directory levels for an appropriately named parent directory """ rootdirs = [] for i in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): return { "version": dirname[len(parentdir_prefix) :], "full-revisionid": None, "dirty": False, "error": None, "date": None, } else: rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: print( "Tried directories %s but none started with prefix %s" % (str(rootdirs), parentdir_prefix) ) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @register_vcs_handler("git", "get_keywords") def git_get_keywords(versionfile_abs): """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. keywords = {} try: f = open(versionfile_abs, "r") for line in f.readlines(): if line.strip().startswith("git_refnames ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["refnames"] = mo.group(1) if line.strip().startswith("git_full ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["full"] = mo.group(1) if line.strip().startswith("git_date ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["date"] = mo.group(1) f.close() except EnvironmentError: pass return keywords @register_vcs_handler("git", "keywords") def git_versions_from_keywords(keywords, tag_prefix, verbose): """Get version information from git keywords.""" if not keywords: raise NotThisMethod("no keywords at all, weird") date = keywords.get("date") if date is not None: # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because # it's been around since git-1.5.3, and it's too difficult to # discover which version we're using, or to work around using an # older one. date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) refnames = keywords["refnames"].strip() if refnames.startswith("$Format"): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") refs = set([r.strip() for r in refnames.strip("()").split(",")]) # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " tags = set([r[len(TAG) :] for r in refs if r.startswith(TAG)]) if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d # expansion behaves like git log --decorate=short and strips out the # refs/heads/ and refs/tags/ prefixes that would let us distinguish # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". tags = set([r for r in refs if re.search(r"\d", r)]) if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: print("likely tags: %s" % ",".join(sorted(tags))) for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): r = ref[len(tag_prefix) :] if verbose: print("picking %s" % r) return { "version": r, "full-revisionid": keywords["full"].strip(), "dirty": False, "error": None, "date": date, } # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") return { "version": "0+unknown", "full-revisionid": keywords["full"].strip(), "dirty": False, "error": "no suitable tags", "date": None, } @register_vcs_handler("git", "pieces_from_vcs") def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* expanded, and _version.py hasn't already been rewritten with a short version string, meaning we're inside a checked out source tree. """ GITS = ["git"] if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) if rc != 0: if verbose: print("Directory %s not under git control" % root) raise NotThisMethod("'git rev-parse --git-dir' returned error") # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) describe_out, rc = run_command( GITS, [ "describe", "--tags", "--dirty", "--always", "--long", "--match", "%s*" % tag_prefix, ], cwd=root, ) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() pieces = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out # look for -dirty suffix dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: git_describe = git_describe[: git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) if not mo: # unparseable. Maybe git-describe is misbehaving? pieces["error"] = "unable to parse git-describe output: '%s'" % describe_out return pieces # tag full_tag = mo.group(1) if not full_tag.startswith(tag_prefix): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( full_tag, tag_prefix, ) return pieces pieces["closest-tag"] = full_tag[len(tag_prefix) :] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) # commit: short hex revision ID pieces["short"] = mo.group(3) else: # HEX: no tags pieces["closest-tag"] = None count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], cwd=root) pieces["distance"] = int(count_out) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[ 0 ].strip() # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces def plus_or_dot(pieces): """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" def render_pep440(pieces): """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty Exceptions: 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += plus_or_dot(pieces) rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_pre(pieces): """TAG[.post0.devDISTANCE] -- No -dirty. Exceptions: 1: no tags. 0.post0.devDISTANCE """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += ".post0.dev%d" % pieces["distance"] else: # exception #1 rendered = "0.post0.dev%d" % pieces["distance"] return rendered def render_pep440_post(pieces): """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards (a dirty tree will appear "older" than the corresponding clean one), but you shouldn't be releasing software with -dirty anyways. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%s" % pieces["short"] else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += "+g%s" % pieces["short"] return rendered def render_pep440_old(pieces): """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" return rendered def render_git_describe(pieces): """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render_git_describe_long(pieces): """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. The distance/hash is unconditional. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: return { "version": "unknown", "full-revisionid": pieces.get("long"), "dirty": None, "error": pieces["error"], "date": None, } if not style or style == "default": style = "pep440" # the default if style == "pep440": rendered = render_pep440(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": rendered = render_git_describe(pieces) elif style == "git-describe-long": rendered = render_git_describe_long(pieces) else: raise ValueError("unknown style '%s'" % style) return { "version": rendered, "full-revisionid": pieces["long"], "dirty": pieces["dirty"], "error": None, "date": pieces.get("date"), } def get_versions(): """Get version information or return default if unable to do so.""" # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have # __file__, we can work backwards from there to the root. Some # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which # case we can only use expanded keywords. cfg = get_config() verbose = cfg.verbose try: return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, verbose) except NotThisMethod: pass try: root = os.path.realpath(__file__) # versionfile_source is the relative path from the top of the source # tree (where the .git directory might live) to this file. Invert # this to find the root from __file__. for i in cfg.versionfile_source.split("/"): root = os.path.dirname(root) except NameError: return { "version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to find root of source tree", "date": None, } try: pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) return render(pieces, cfg.style) except NotThisMethod: pass try: if cfg.parentdir_prefix: return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) except NotThisMethod: pass return { "version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to compute version", "date": None, } python-msgspec-0.19.0/msgspec/atof.h000066400000000000000000000265671473355726200173620ustar00rootroot00000000000000/* This file implements the core float parsing routines used in msgspec. * * It contains an implementation of the Eisel-Lemire algorithm, as described in * https://nigeltao.github.io/blog/2020/eisel-lemire.html. Much of the * implementation is based on the one available in Wuffs * (https://github.com/google/wuffs/blob/c104ae296c3557f946e4bd5ee8b85511f12c141c/internal/cgen/base/floatconv-submodule-code.c#L989). * * It also contains a fallback implementation using a High Precision Double * (HPD). This method is based on the following blogpost by Nigel Tao ( * https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html), as well * as the implementation in Wuffs * (https://github.com/google/wuffs/blob/c104ae296c3557f946e4bd5ee8b85511f12c141c/internal/cgen/base/floatconv-submodule-code.c#L1307-L1308). * * The Wuffs license is copied below: * * """ Copyright 2020 The Wuffs Authors. * * 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 * * https://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. """ * * */ #ifndef MS_ATOF_H #define MS_ATOF_H #include #include #if defined(_MSC_VER) #include #endif #include "atof_consts.h" typedef struct ms_uint128 { uint64_t lo; uint64_t hi; } ms_uint128; static inline ms_uint128 ms_mulu64(uint64_t x, uint64_t y) { #if defined(__SIZEOF_INT128__) ms_uint128 out; __uint128_t z = ((__uint128_t)x) * ((__uint128_t)y); out.lo = (uint64_t)z; out.hi = (uint64_t)(z >> 64); return out; #else ms_uint128 out; uint64_t x0 = x & 0xFFFFFFFF; uint64_t x1 = x >> 32; uint64_t y0 = y & 0xFFFFFFFF; uint64_t y1 = y >> 32; uint64_t w0 = x0 * y0; uint64_t t = (x1 * y0) + (w0 >> 32); uint64_t w1 = t & 0xFFFFFFFF; uint64_t w2 = t >> 32; w1 += x0 * y1; out.lo = x * y; out.hi = (x1 * y1) + w2 + (w1 >> 32); return out; #endif } static inline uint32_t ms_clzll(uint64_t x) { #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_ARM64) || defined(_M_IA64)) uint32_t index = 0; _BitScanReverse64(&index, x); return (int)(63 - index); #elif defined(__GNUC__) return (uint32_t)__builtin_clzll(x); #else uint32_t out; if ((x >> 32) == 0) { out |= 32; x <<= 32; } if ((x >> 48) == 0) { out |= 16; x <<= 16; } if ((x >> 56) == 0) { out |= 8; x <<= 8; } if ((x >> 60) == 0) { out |= 4; x <<= 4; } if ((x >> 62) == 0) { out |= 2; x <<= 2; } if ((x >> 63) == 0) { out |= 1; x <<= 1; } return out; #endif } static inline int64_t eisel_lemire(uint64_t man, int32_t exp) { /* The short comment headers below correspond to section titles in Nigel * Tao's blogpost. See * https://nigeltao.github.io/blog/2020/eisel-lemire.html for a more * in-depth description of the algorithm */ /* Normalization */ const uint64_t* po10 = ms_atof_powers_of_10[exp + 307]; uint32_t clz = ms_clzll(man); man <<= clz; uint64_t ret_exp2 = ((uint64_t)(((217706 * exp) >> 16) + 1087)) - ((uint64_t)clz); /* Multiplication */ ms_uint128 x = ms_mulu64(man, po10[1]); uint64_t x_hi = x.hi; uint64_t x_lo = x.lo; /* Apply a wider Approximation if needed */ if (((x_hi & 0x1FF) == 0x1FF) && ((x_lo + man) < man)) { ms_uint128 y = ms_mulu64(man, po10[0]); uint64_t y_hi = y.hi; uint64_t y_lo = y.lo; uint64_t merged_hi = x_hi; uint64_t merged_lo = x_lo + y_hi; if (merged_lo < x_lo) { merged_hi++; } /* If the result is still ambiguous at this approximation, abort */ if (((merged_hi & 0x1FF) == 0x1FF) && ((merged_lo + 1) == 0) && (y_lo + man < man)) { return -1; } x_hi = merged_hi; x_lo = merged_lo; } /* Shift to 54 bits */ uint64_t msb = x_hi >> 63; uint64_t ret_mantissa = x_hi >> (msb + 9); ret_exp2 -= 1 ^ msb; /* Check for a half-way ambiguity, and abort if present */ if ((x_lo == 0) && ((x_hi & 0x1FF) == 0) && ((ret_mantissa & 3) == 1)) { return -1; } /* From 54 to 53 bits */ ret_mantissa += ret_mantissa & 1; ret_mantissa >>= 1; if ((ret_mantissa >> 53) > 0) { ret_mantissa >>= 1; ret_exp2++; } /* Construct final output */ ret_mantissa &= 0x000FFFFFFFFFFFFF; return ((int64_t)(ret_mantissa | (ret_exp2 << 52))); } /* Fallback parsing method using a High Precision Double (HPD) */ #define MS_HPD_MAX_DIGITS 800 #define MS_HPD_DP_RANGE 2047 #define MS_HPD_MAX_SHIFT 60 typedef struct ms_hpd { uint32_t num_digits; int32_t decimal_point; bool negative; bool truncated; uint8_t digits[800]; } ms_hpd; static inline void ms_hpd_trim(ms_hpd *dec) { while ((dec->num_digits > 0) && (dec->digits[dec->num_digits - 1] == 0)) { dec->num_digits--; } if (dec->num_digits == 0) { dec->decimal_point = 0; } } static uint32_t ms_hpd_lshift_num_new_digits(ms_hpd *hpd, uint32_t shift) { shift &= 63; uint32_t x_a = ms_atof_left_shift[shift]; uint32_t x_b = ms_atof_left_shift[shift + 1]; uint32_t num_new_digits = x_a >> 11; uint32_t pow5_a = 0x7FF & x_a; uint32_t pow5_b = 0x7FF & x_b; const uint8_t* pow5 = &ms_atof_powers_of_5[pow5_a]; uint32_t i = 0; uint32_t n = pow5_b - pow5_a; for (; i < n; i++) { if (i >= hpd->num_digits) { return num_new_digits - 1; } else if (hpd->digits[i] == pow5[i]) { continue; } else if (hpd->digits[i] < pow5[i]) { return num_new_digits - 1; } else { return num_new_digits; } } return num_new_digits; } static uint64_t ms_hpd_rounded_integer(ms_hpd *hpd) { if ((hpd->num_digits == 0) || (hpd->decimal_point < 0)) { return 0; } else if (hpd->decimal_point > 18) { return UINT64_MAX; } uint32_t dp = (uint32_t)(hpd->decimal_point); uint64_t n = 0; uint32_t i = 0; for (; i < dp; i++) { n = (10 * n) + ((i < hpd->num_digits) ? hpd->digits[i] : 0); } bool round_up = false; if (dp < hpd->num_digits) { round_up = hpd->digits[dp] >= 5; if ((hpd->digits[dp] == 5) && (dp + 1 == hpd->num_digits)) { round_up = hpd->truncated || ((dp > 0) && (1 & hpd->digits[dp - 1])); } } if (round_up) { n++; } return n; } static void ms_hpd_small_lshift(ms_hpd *hpd, uint32_t shift) { if (hpd->num_digits == 0) { return; } uint32_t num_new_digits = ms_hpd_lshift_num_new_digits(hpd, shift); uint32_t rx = hpd->num_digits - 1; // Read index. uint32_t wx = hpd->num_digits - 1 + num_new_digits; // Write index. uint64_t n = 0; while (((int32_t)rx) >= 0) { n += ((uint64_t)(hpd->digits[rx])) << shift; uint64_t quo = n / 10; uint64_t rem = n - (10 * quo); if (wx < MS_HPD_MAX_DIGITS) { hpd->digits[wx] = (uint8_t)rem; } else if (rem > 0) { hpd->truncated = true; } n = quo; wx--; rx--; } while (n > 0) { uint64_t quo = n / 10; uint64_t rem = n - (10 * quo); if (wx < MS_HPD_MAX_DIGITS) { hpd->digits[wx] = (uint8_t)rem; } else if (rem > 0) { hpd->truncated = true; } n = quo; wx--; } hpd->num_digits += num_new_digits; if (hpd->num_digits > MS_HPD_MAX_DIGITS) { hpd->num_digits = MS_HPD_MAX_DIGITS; } hpd->decimal_point += (int32_t)num_new_digits; ms_hpd_trim(hpd); } static void ms_hpd_small_rshift(ms_hpd *hpd, uint32_t shift) { uint32_t rx = 0; uint32_t wx = 0; uint64_t n = 0; while ((n >> shift) == 0) { if (rx < hpd->num_digits) { n = (10 * n) + hpd->digits[rx++]; } else if (n == 0) { return; } else { while ((n >> shift) == 0) { n = 10 * n; rx++; } break; } } hpd->decimal_point -= ((int32_t)(rx - 1)); if (hpd->decimal_point < -MS_HPD_DP_RANGE) { hpd->num_digits = 0; hpd->decimal_point = 0; hpd->truncated = false; return; } uint64_t mask = (((uint64_t)(1)) << shift) - 1; while (rx < hpd->num_digits) { uint8_t new_digit = ((uint8_t)(n >> shift)); n = (10 * (n & mask)) + hpd->digits[rx++]; hpd->digits[wx++] = new_digit; } while (n > 0) { uint8_t new_digit = ((uint8_t)(n >> shift)); n = 10 * (n & mask); if (wx < MS_HPD_MAX_DIGITS) { hpd->digits[wx++] = new_digit; } else if (new_digit > 0) { hpd->truncated = true; } } hpd->num_digits = wx; ms_hpd_trim(hpd); } static double ms_hpd_to_double(ms_hpd *hpd) { static const uint32_t num_powers = 19; static const uint8_t powers[19] = { 0, 3, 6, 9, 13, 16, 19, 23, 26, 29, 33, 36, 39, 43, 46, 49, 53, 56, 59, }; if ((hpd->num_digits == 0) || (hpd->decimal_point < -326)) { goto zero; } else if (hpd->decimal_point > 310) { goto infinity; } const int32_t f64_bias = -1023; int32_t exp2 = 0; while (hpd->decimal_point > 0) { uint32_t n = (uint32_t)(+hpd->decimal_point); uint32_t shift = (n < num_powers) ? powers[n] : MS_HPD_MAX_SHIFT; ms_hpd_small_rshift(hpd, shift); if (hpd->decimal_point < -MS_HPD_DP_RANGE) { goto zero; } exp2 += (int32_t)shift; } while (hpd->decimal_point <= 0) { uint32_t shift; if (hpd->decimal_point == 0) { if (hpd->digits[0] >= 5) { break; } shift = (hpd->digits[0] < 2) ? 2 : 1; } else { uint32_t n = (uint32_t)(-hpd->decimal_point); shift = (n < num_powers) ? powers[n] : MS_HPD_MAX_SHIFT; } ms_hpd_small_lshift(hpd, shift); if (hpd->decimal_point > +MS_HPD_DP_RANGE) { goto infinity; } exp2 -= (int32_t)shift; } exp2--; while ((f64_bias + 1) > exp2) { uint32_t n = (uint32_t)((f64_bias + 1) - exp2); if (n > MS_HPD_MAX_SHIFT) { n = MS_HPD_MAX_SHIFT; } ms_hpd_small_rshift(hpd, n); exp2 += (int32_t)n; } if ((exp2 - f64_bias) >= 0x07FF) { goto infinity; } ms_hpd_small_lshift(hpd, 53); uint64_t man2 = ms_hpd_rounded_integer(hpd); if ((man2 >> 53) != 0) { man2 >>= 1; exp2++; if ((exp2 - f64_bias) >= 0x07FF) { goto infinity; } } if ((man2 >> 52) == 0) { exp2 = f64_bias; } uint64_t exp2_bits = (uint64_t)((exp2 - f64_bias) & 0x07FF); uint64_t bits = ( (man2 & 0x000FFFFFFFFFFFFF) | (exp2_bits << 52) | (hpd->negative ? 0x8000000000000000 : 0) ); double ret; memcpy(&ret, &bits, sizeof(double)); return ret; zero: return hpd->negative ? -0.0 : 0.0; infinity: return hpd->negative ? -INFINITY : INFINITY; } #endif python-msgspec-0.19.0/msgspec/atof_consts.h000066400000000000000000001072431473355726200207420ustar00rootroot00000000000000/* DO NOT EDIT - generated by scripts/generate_atof_consts.py */ #ifndef MSGSPEC_ATOF_CONSTS_H #define MSGSPEC_ATOF_CONSTS_H static const uint64_t ms_atof_powers_of_10[596][2] = { {0xa5d3b6d479f8e056, 0x8fd0c16206306bab}, // 1e-307 {0x8f48a4899877186c, 0xb3c4f1ba87bc8696}, // 1e-306 {0x331acdabfe94de87, 0xe0b62e2929aba83c}, // 1e-305 {0x9ff0c08b7f1d0b14, 0x8c71dcd9ba0b4925}, // 1e-304 {0x07ecf0ae5ee44dd9, 0xaf8e5410288e1b6f}, // 1e-303 {0xc9e82cd9f69d6150, 0xdb71e91432b1a24a}, // 1e-302 {0xbe311c083a225cd2, 0x892731ac9faf056e}, // 1e-301 {0x6dbd630a48aaf406, 0xab70fe17c79ac6ca}, // 1e-300 {0x092cbbccdad5b108, 0xd64d3d9db981787d}, // 1e-299 {0x25bbf56008c58ea5, 0x85f0468293f0eb4e}, // 1e-298 {0xaf2af2b80af6f24e, 0xa76c582338ed2621}, // 1e-297 {0x1af5af660db4aee1, 0xd1476e2c07286faa}, // 1e-296 {0x50d98d9fc890ed4d, 0x82cca4db847945ca}, // 1e-295 {0xe50ff107bab528a0, 0xa37fce126597973c}, // 1e-294 {0x1e53ed49a96272c8, 0xcc5fc196fefd7d0c}, // 1e-293 {0x25e8e89c13bb0f7a, 0xff77b1fcbebcdc4f}, // 1e-292 {0x77b191618c54e9ac, 0x9faacf3df73609b1}, // 1e-291 {0xd59df5b9ef6a2417, 0xc795830d75038c1d}, // 1e-290 {0x4b0573286b44ad1d, 0xf97ae3d0d2446f25}, // 1e-289 {0x4ee367f9430aec32, 0x9becce62836ac577}, // 1e-288 {0x229c41f793cda73f, 0xc2e801fb244576d5}, // 1e-287 {0x6b43527578c1110f, 0xf3a20279ed56d48a}, // 1e-286 {0x830a13896b78aaa9, 0x9845418c345644d6}, // 1e-285 {0x23cc986bc656d553, 0xbe5691ef416bd60c}, // 1e-284 {0x2cbfbe86b7ec8aa8, 0xedec366b11c6cb8f}, // 1e-283 {0x7bf7d71432f3d6a9, 0x94b3a202eb1c3f39}, // 1e-282 {0xdaf5ccd93fb0cc53, 0xb9e08a83a5e34f07}, // 1e-281 {0xd1b3400f8f9cff68, 0xe858ad248f5c22c9}, // 1e-280 {0x23100809b9c21fa1, 0x91376c36d99995be}, // 1e-279 {0xabd40a0c2832a78a, 0xb58547448ffffb2d}, // 1e-278 {0x16c90c8f323f516c, 0xe2e69915b3fff9f9}, // 1e-277 {0xae3da7d97f6792e3, 0x8dd01fad907ffc3b}, // 1e-276 {0x99cd11cfdf41779c, 0xb1442798f49ffb4a}, // 1e-275 {0x40405643d711d583, 0xdd95317f31c7fa1d}, // 1e-274 {0x482835ea666b2572, 0x8a7d3eef7f1cfc52}, // 1e-273 {0xda3243650005eecf, 0xad1c8eab5ee43b66}, // 1e-272 {0x90bed43e40076a82, 0xd863b256369d4a40}, // 1e-271 {0x5a7744a6e804a291, 0x873e4f75e2224e68}, // 1e-270 {0x711515d0a205cb36, 0xa90de3535aaae202}, // 1e-269 {0x0d5a5b44ca873e03, 0xd3515c2831559a83}, // 1e-268 {0xe858790afe9486c2, 0x8412d9991ed58091}, // 1e-267 {0x626e974dbe39a872, 0xa5178fff668ae0b6}, // 1e-266 {0xfb0a3d212dc8128f, 0xce5d73ff402d98e3}, // 1e-265 {0x7ce66634bc9d0b99, 0x80fa687f881c7f8e}, // 1e-264 {0x1c1fffc1ebc44e80, 0xa139029f6a239f72}, // 1e-263 {0xa327ffb266b56220, 0xc987434744ac874e}, // 1e-262 {0x4bf1ff9f0062baa8, 0xfbe9141915d7a922}, // 1e-261 {0x6f773fc3603db4a9, 0x9d71ac8fada6c9b5}, // 1e-260 {0xcb550fb4384d21d3, 0xc4ce17b399107c22}, // 1e-259 {0x7e2a53a146606a48, 0xf6019da07f549b2b}, // 1e-258 {0x2eda7444cbfc426d, 0x99c102844f94e0fb}, // 1e-257 {0xfa911155fefb5308, 0xc0314325637a1939}, // 1e-256 {0x793555ab7eba27ca, 0xf03d93eebc589f88}, // 1e-255 {0x4bc1558b2f3458de, 0x96267c7535b763b5}, // 1e-254 {0x9eb1aaedfb016f16, 0xbbb01b9283253ca2}, // 1e-253 {0x465e15a979c1cadc, 0xea9c227723ee8bcb}, // 1e-252 {0x0bfacd89ec191ec9, 0x92a1958a7675175f}, // 1e-251 {0xcef980ec671f667b, 0xb749faed14125d36}, // 1e-250 {0x82b7e12780e7401a, 0xe51c79a85916f484}, // 1e-249 {0xd1b2ecb8b0908810, 0x8f31cc0937ae58d2}, // 1e-248 {0x861fa7e6dcb4aa15, 0xb2fe3f0b8599ef07}, // 1e-247 {0x67a791e093e1d49a, 0xdfbdcece67006ac9}, // 1e-246 {0xe0c8bb2c5c6d24e0, 0x8bd6a141006042bd}, // 1e-245 {0x58fae9f773886e18, 0xaecc49914078536d}, // 1e-244 {0xaf39a475506a899e, 0xda7f5bf590966848}, // 1e-243 {0x6d8406c952429603, 0x888f99797a5e012d}, // 1e-242 {0xc8e5087ba6d33b83, 0xaab37fd7d8f58178}, // 1e-241 {0xfb1e4a9a90880a64, 0xd5605fcdcf32e1d6}, // 1e-240 {0x5cf2eea09a55067f, 0x855c3be0a17fcd26}, // 1e-239 {0xf42faa48c0ea481e, 0xa6b34ad8c9dfc06f}, // 1e-238 {0xf13b94daf124da26, 0xd0601d8efc57b08b}, // 1e-237 {0x76c53d08d6b70858, 0x823c12795db6ce57}, // 1e-236 {0x54768c4b0c64ca6e, 0xa2cb1717b52481ed}, // 1e-235 {0xa9942f5dcf7dfd09, 0xcb7ddcdda26da268}, // 1e-234 {0xd3f93b35435d7c4c, 0xfe5d54150b090b02}, // 1e-233 {0xc47bc5014a1a6daf, 0x9efa548d26e5a6e1}, // 1e-232 {0x359ab6419ca1091b, 0xc6b8e9b0709f109a}, // 1e-231 {0xc30163d203c94b62, 0xf867241c8cc6d4c0}, // 1e-230 {0x79e0de63425dcf1d, 0x9b407691d7fc44f8}, // 1e-229 {0x985915fc12f542e4, 0xc21094364dfb5636}, // 1e-228 {0x3e6f5b7b17b2939d, 0xf294b943e17a2bc4}, // 1e-227 {0xa705992ceecf9c42, 0x979cf3ca6cec5b5a}, // 1e-226 {0x50c6ff782a838353, 0xbd8430bd08277231}, // 1e-225 {0xa4f8bf5635246428, 0xece53cec4a314ebd}, // 1e-224 {0x871b7795e136be99, 0x940f4613ae5ed136}, // 1e-223 {0x28e2557b59846e3f, 0xb913179899f68584}, // 1e-222 {0x331aeada2fe589cf, 0xe757dd7ec07426e5}, // 1e-221 {0x3ff0d2c85def7621, 0x9096ea6f3848984f}, // 1e-220 {0x0fed077a756b53a9, 0xb4bca50b065abe63}, // 1e-219 {0xd3e8495912c62894, 0xe1ebce4dc7f16dfb}, // 1e-218 {0x64712dd7abbbd95c, 0x8d3360f09cf6e4bd}, // 1e-217 {0xbd8d794d96aacfb3, 0xb080392cc4349dec}, // 1e-216 {0xecf0d7a0fc5583a0, 0xdca04777f541c567}, // 1e-215 {0xf41686c49db57244, 0x89e42caaf9491b60}, // 1e-214 {0x311c2875c522ced5, 0xac5d37d5b79b6239}, // 1e-213 {0x7d633293366b828b, 0xd77485cb25823ac7}, // 1e-212 {0xae5dff9c02033197, 0x86a8d39ef77164bc}, // 1e-211 {0xd9f57f830283fdfc, 0xa8530886b54dbdeb}, // 1e-210 {0xd072df63c324fd7b, 0xd267caa862a12d66}, // 1e-209 {0x4247cb9e59f71e6d, 0x8380dea93da4bc60}, // 1e-208 {0x52d9be85f074e608, 0xa46116538d0deb78}, // 1e-207 {0x67902e276c921f8b, 0xcd795be870516656}, // 1e-206 {0x00ba1cd8a3db53b6, 0x806bd9714632dff6}, // 1e-205 {0x80e8a40eccd228a4, 0xa086cfcd97bf97f3}, // 1e-204 {0x6122cd128006b2cd, 0xc8a883c0fdaf7df0}, // 1e-203 {0x796b805720085f81, 0xfad2a4b13d1b5d6c}, // 1e-202 {0xcbe3303674053bb0, 0x9cc3a6eec6311a63}, // 1e-201 {0xbedbfc4411068a9c, 0xc3f490aa77bd60fc}, // 1e-200 {0xee92fb5515482d44, 0xf4f1b4d515acb93b}, // 1e-199 {0x751bdd152d4d1c4a, 0x991711052d8bf3c5}, // 1e-198 {0xd262d45a78a0635d, 0xbf5cd54678eef0b6}, // 1e-197 {0x86fb897116c87c34, 0xef340a98172aace4}, // 1e-196 {0xd45d35e6ae3d4da0, 0x9580869f0e7aac0e}, // 1e-195 {0x8974836059cca109, 0xbae0a846d2195712}, // 1e-194 {0x2bd1a438703fc94b, 0xe998d258869facd7}, // 1e-193 {0x7b6306a34627ddcf, 0x91ff83775423cc06}, // 1e-192 {0x1a3bc84c17b1d542, 0xb67f6455292cbf08}, // 1e-191 {0x20caba5f1d9e4a93, 0xe41f3d6a7377eeca}, // 1e-190 {0x547eb47b7282ee9c, 0x8e938662882af53e}, // 1e-189 {0xe99e619a4f23aa43, 0xb23867fb2a35b28d}, // 1e-188 {0x6405fa00e2ec94d4, 0xdec681f9f4c31f31}, // 1e-187 {0xde83bc408dd3dd04, 0x8b3c113c38f9f37e}, // 1e-186 {0x9624ab50b148d445, 0xae0b158b4738705e}, // 1e-185 {0x3badd624dd9b0957, 0xd98ddaee19068c76}, // 1e-184 {0xe54ca5d70a80e5d6, 0x87f8a8d4cfa417c9}, // 1e-183 {0x5e9fcf4ccd211f4c, 0xa9f6d30a038d1dbc}, // 1e-182 {0x7647c3200069671f, 0xd47487cc8470652b}, // 1e-181 {0x29ecd9f40041e073, 0x84c8d4dfd2c63f3b}, // 1e-180 {0xf468107100525890, 0xa5fb0a17c777cf09}, // 1e-179 {0x7182148d4066eeb4, 0xcf79cc9db955c2cc}, // 1e-178 {0xc6f14cd848405530, 0x81ac1fe293d599bf}, // 1e-177 {0xb8ada00e5a506a7c, 0xa21727db38cb002f}, // 1e-176 {0xa6d90811f0e4851c, 0xca9cf1d206fdc03b}, // 1e-175 {0x908f4a166d1da663, 0xfd442e4688bd304a}, // 1e-174 {0x9a598e4e043287fe, 0x9e4a9cec15763e2e}, // 1e-173 {0x40eff1e1853f29fd, 0xc5dd44271ad3cdba}, // 1e-172 {0xd12bee59e68ef47c, 0xf7549530e188c128}, // 1e-171 {0x82bb74f8301958ce, 0x9a94dd3e8cf578b9}, // 1e-170 {0xe36a52363c1faf01, 0xc13a148e3032d6e7}, // 1e-169 {0xdc44e6c3cb279ac1, 0xf18899b1bc3f8ca1}, // 1e-168 {0x29ab103a5ef8c0b9, 0x96f5600f15a7b7e5}, // 1e-167 {0x7415d448f6b6f0e7, 0xbcb2b812db11a5de}, // 1e-166 {0x111b495b3464ad21, 0xebdf661791d60f56}, // 1e-165 {0xcab10dd900beec34, 0x936b9fcebb25c995}, // 1e-164 {0x3d5d514f40eea742, 0xb84687c269ef3bfb}, // 1e-163 {0x0cb4a5a3112a5112, 0xe65829b3046b0afa}, // 1e-162 {0x47f0e785eaba72ab, 0x8ff71a0fe2c2e6dc}, // 1e-161 {0x59ed216765690f56, 0xb3f4e093db73a093}, // 1e-160 {0x306869c13ec3532c, 0xe0f218b8d25088b8}, // 1e-159 {0x1e414218c73a13fb, 0x8c974f7383725573}, // 1e-158 {0xe5d1929ef90898fa, 0xafbd2350644eeacf}, // 1e-157 {0xdf45f746b74abf39, 0xdbac6c247d62a583}, // 1e-156 {0x6b8bba8c328eb783, 0x894bc396ce5da772}, // 1e-155 {0x066ea92f3f326564, 0xab9eb47c81f5114f}, // 1e-154 {0xc80a537b0efefebd, 0xd686619ba27255a2}, // 1e-153 {0xbd06742ce95f5f36, 0x8613fd0145877585}, // 1e-152 {0x2c48113823b73704, 0xa798fc4196e952e7}, // 1e-151 {0xf75a15862ca504c5, 0xd17f3b51fca3a7a0}, // 1e-150 {0x9a984d73dbe722fb, 0x82ef85133de648c4}, // 1e-149 {0xc13e60d0d2e0ebba, 0xa3ab66580d5fdaf5}, // 1e-148 {0x318df905079926a8, 0xcc963fee10b7d1b3}, // 1e-147 {0xfdf17746497f7052, 0xffbbcfe994e5c61f}, // 1e-146 {0xfeb6ea8bedefa633, 0x9fd561f1fd0f9bd3}, // 1e-145 {0xfe64a52ee96b8fc0, 0xc7caba6e7c5382c8}, // 1e-144 {0x3dfdce7aa3c673b0, 0xf9bd690a1b68637b}, // 1e-143 {0x06bea10ca65c084e, 0x9c1661a651213e2d}, // 1e-142 {0x486e494fcff30a62, 0xc31bfa0fe5698db8}, // 1e-141 {0x5a89dba3c3efccfa, 0xf3e2f893dec3f126}, // 1e-140 {0xf89629465a75e01c, 0x986ddb5c6b3a76b7}, // 1e-139 {0xf6bbb397f1135823, 0xbe89523386091465}, // 1e-138 {0x746aa07ded582e2c, 0xee2ba6c0678b597f}, // 1e-137 {0xa8c2a44eb4571cdc, 0x94db483840b717ef}, // 1e-136 {0x92f34d62616ce413, 0xba121a4650e4ddeb}, // 1e-135 {0x77b020baf9c81d17, 0xe896a0d7e51e1566}, // 1e-134 {0x0ace1474dc1d122e, 0x915e2486ef32cd60}, // 1e-133 {0x0d819992132456ba, 0xb5b5ada8aaff80b8}, // 1e-132 {0x10e1fff697ed6c69, 0xe3231912d5bf60e6}, // 1e-131 {0xca8d3ffa1ef463c1, 0x8df5efabc5979c8f}, // 1e-130 {0xbd308ff8a6b17cb2, 0xb1736b96b6fd83b3}, // 1e-129 {0xac7cb3f6d05ddbde, 0xddd0467c64bce4a0}, // 1e-128 {0x6bcdf07a423aa96b, 0x8aa22c0dbef60ee4}, // 1e-127 {0x86c16c98d2c953c6, 0xad4ab7112eb3929d}, // 1e-126 {0xe871c7bf077ba8b7, 0xd89d64d57a607744}, // 1e-125 {0x11471cd764ad4972, 0x87625f056c7c4a8b}, // 1e-124 {0xd598e40d3dd89bcf, 0xa93af6c6c79b5d2d}, // 1e-123 {0x4aff1d108d4ec2c3, 0xd389b47879823479}, // 1e-122 {0xcedf722a585139ba, 0x843610cb4bf160cb}, // 1e-121 {0xc2974eb4ee658828, 0xa54394fe1eedb8fe}, // 1e-120 {0x733d226229feea32, 0xce947a3da6a9273e}, // 1e-119 {0x0806357d5a3f525f, 0x811ccc668829b887}, // 1e-118 {0xca07c2dcb0cf26f7, 0xa163ff802a3426a8}, // 1e-117 {0xfc89b393dd02f0b5, 0xc9bcff6034c13052}, // 1e-116 {0xbbac2078d443ace2, 0xfc2c3f3841f17c67}, // 1e-115 {0xd54b944b84aa4c0d, 0x9d9ba7832936edc0}, // 1e-114 {0x0a9e795e65d4df11, 0xc5029163f384a931}, // 1e-113 {0x4d4617b5ff4a16d5, 0xf64335bcf065d37d}, // 1e-112 {0x504bced1bf8e4e45, 0x99ea0196163fa42e}, // 1e-111 {0xe45ec2862f71e1d6, 0xc06481fb9bcf8d39}, // 1e-110 {0x5d767327bb4e5a4c, 0xf07da27a82c37088}, // 1e-109 {0x3a6a07f8d510f86f, 0x964e858c91ba2655}, // 1e-108 {0x890489f70a55368b, 0xbbe226efb628afea}, // 1e-107 {0x2b45ac74ccea842e, 0xeadab0aba3b2dbe5}, // 1e-106 {0x3b0b8bc90012929d, 0x92c8ae6b464fc96f}, // 1e-105 {0x09ce6ebb40173744, 0xb77ada0617e3bbcb}, // 1e-104 {0xcc420a6a101d0515, 0xe55990879ddcaabd}, // 1e-103 {0x9fa946824a12232d, 0x8f57fa54c2a9eab6}, // 1e-102 {0x47939822dc96abf9, 0xb32df8e9f3546564}, // 1e-101 {0x59787e2b93bc56f7, 0xdff9772470297ebd}, // 1e-100 {0x57eb4edb3c55b65a, 0x8bfbea76c619ef36}, // 1e-99 {0xede622920b6b23f1, 0xaefae51477a06b03}, // 1e-98 {0xe95fab368e45eced, 0xdab99e59958885c4}, // 1e-97 {0x11dbcb0218ebb414, 0x88b402f7fd75539b}, // 1e-96 {0xd652bdc29f26a119, 0xaae103b5fcd2a881}, // 1e-95 {0x4be76d3346f0495f, 0xd59944a37c0752a2}, // 1e-94 {0x6f70a4400c562ddb, 0x857fcae62d8493a5}, // 1e-93 {0xcb4ccd500f6bb952, 0xa6dfbd9fb8e5b88e}, // 1e-92 {0x7e2000a41346a7a7, 0xd097ad07a71f26b2}, // 1e-91 {0x8ed400668c0c28c8, 0x825ecc24c873782f}, // 1e-90 {0x728900802f0f32fa, 0xa2f67f2dfa90563b}, // 1e-89 {0x4f2b40a03ad2ffb9, 0xcbb41ef979346bca}, // 1e-88 {0xe2f610c84987bfa8, 0xfea126b7d78186bc}, // 1e-87 {0x0dd9ca7d2df4d7c9, 0x9f24b832e6b0f436}, // 1e-86 {0x91503d1c79720dbb, 0xc6ede63fa05d3143}, // 1e-85 {0x75a44c6397ce912a, 0xf8a95fcf88747d94}, // 1e-84 {0xc986afbe3ee11aba, 0x9b69dbe1b548ce7c}, // 1e-83 {0xfbe85badce996168, 0xc24452da229b021b}, // 1e-82 {0xfae27299423fb9c3, 0xf2d56790ab41c2a2}, // 1e-81 {0xdccd879fc967d41a, 0x97c560ba6b0919a5}, // 1e-80 {0x5400e987bbc1c920, 0xbdb6b8e905cb600f}, // 1e-79 {0x290123e9aab23b68, 0xed246723473e3813}, // 1e-78 {0xf9a0b6720aaf6521, 0x9436c0760c86e30b}, // 1e-77 {0xf808e40e8d5b3e69, 0xb94470938fa89bce}, // 1e-76 {0xb60b1d1230b20e04, 0xe7958cb87392c2c2}, // 1e-75 {0xb1c6f22b5e6f48c2, 0x90bd77f3483bb9b9}, // 1e-74 {0x1e38aeb6360b1af3, 0xb4ecd5f01a4aa828}, // 1e-73 {0x25c6da63c38de1b0, 0xe2280b6c20dd5232}, // 1e-72 {0x579c487e5a38ad0e, 0x8d590723948a535f}, // 1e-71 {0x2d835a9df0c6d851, 0xb0af48ec79ace837}, // 1e-70 {0xf8e431456cf88e65, 0xdcdb1b2798182244}, // 1e-69 {0x1b8e9ecb641b58ff, 0x8a08f0f8bf0f156b}, // 1e-68 {0xe272467e3d222f3f, 0xac8b2d36eed2dac5}, // 1e-67 {0x5b0ed81dcc6abb0f, 0xd7adf884aa879177}, // 1e-66 {0x98e947129fc2b4e9, 0x86ccbb52ea94baea}, // 1e-65 {0x3f2398d747b36224, 0xa87fea27a539e9a5}, // 1e-64 {0x8eec7f0d19a03aad, 0xd29fe4b18e88640e}, // 1e-63 {0x1953cf68300424ac, 0x83a3eeeef9153e89}, // 1e-62 {0x5fa8c3423c052dd7, 0xa48ceaaab75a8e2b}, // 1e-61 {0x3792f412cb06794d, 0xcdb02555653131b6}, // 1e-60 {0xe2bbd88bbee40bd0, 0x808e17555f3ebf11}, // 1e-59 {0x5b6aceaeae9d0ec4, 0xa0b19d2ab70e6ed6}, // 1e-58 {0xf245825a5a445275, 0xc8de047564d20a8b}, // 1e-57 {0xeed6e2f0f0d56712, 0xfb158592be068d2e}, // 1e-56 {0x55464dd69685606b, 0x9ced737bb6c4183d}, // 1e-55 {0xaa97e14c3c26b886, 0xc428d05aa4751e4c}, // 1e-54 {0xd53dd99f4b3066a8, 0xf53304714d9265df}, // 1e-53 {0xe546a8038efe4029, 0x993fe2c6d07b7fab}, // 1e-52 {0xde98520472bdd033, 0xbf8fdb78849a5f96}, // 1e-51 {0x963e66858f6d4440, 0xef73d256a5c0f77c}, // 1e-50 {0xdde7001379a44aa8, 0x95a8637627989aad}, // 1e-49 {0x5560c018580d5d52, 0xbb127c53b17ec159}, // 1e-48 {0xaab8f01e6e10b4a6, 0xe9d71b689dde71af}, // 1e-47 {0xcab3961304ca70e8, 0x9226712162ab070d}, // 1e-46 {0x3d607b97c5fd0d22, 0xb6b00d69bb55c8d1}, // 1e-45 {0x8cb89a7db77c506a, 0xe45c10c42a2b3b05}, // 1e-44 {0x77f3608e92adb242, 0x8eb98a7a9a5b04e3}, // 1e-43 {0x55f038b237591ed3, 0xb267ed1940f1c61c}, // 1e-42 {0x6b6c46dec52f6688, 0xdf01e85f912e37a3}, // 1e-41 {0x2323ac4b3b3da015, 0x8b61313bbabce2c6}, // 1e-40 {0xabec975e0a0d081a, 0xae397d8aa96c1b77}, // 1e-39 {0x96e7bd358c904a21, 0xd9c7dced53c72255}, // 1e-38 {0x7e50d64177da2e54, 0x881cea14545c7575}, // 1e-37 {0xdde50bd1d5d0b9e9, 0xaa242499697392d2}, // 1e-36 {0x955e4ec64b44e864, 0xd4ad2dbfc3d07787}, // 1e-35 {0xbd5af13bef0b113e, 0x84ec3c97da624ab4}, // 1e-34 {0xecb1ad8aeacdd58e, 0xa6274bbdd0fadd61}, // 1e-33 {0x67de18eda5814af2, 0xcfb11ead453994ba}, // 1e-32 {0x80eacf948770ced7, 0x81ceb32c4b43fcf4}, // 1e-31 {0xa1258379a94d028d, 0xa2425ff75e14fc31}, // 1e-30 {0x096ee45813a04330, 0xcad2f7f5359a3b3e}, // 1e-29 {0x8bca9d6e188853fc, 0xfd87b5f28300ca0d}, // 1e-28 {0x775ea264cf55347d, 0x9e74d1b791e07e48}, // 1e-27 {0x95364afe032a819d, 0xc612062576589dda}, // 1e-26 {0x3a83ddbd83f52204, 0xf79687aed3eec551}, // 1e-25 {0xc4926a9672793542, 0x9abe14cd44753b52}, // 1e-24 {0x75b7053c0f178293, 0xc16d9a0095928a27}, // 1e-23 {0x5324c68b12dd6338, 0xf1c90080baf72cb1}, // 1e-22 {0xd3f6fc16ebca5e03, 0x971da05074da7bee}, // 1e-21 {0x88f4bb1ca6bcf584, 0xbce5086492111aea}, // 1e-20 {0x2b31e9e3d06c32e5, 0xec1e4a7db69561a5}, // 1e-19 {0x3aff322e62439fcf, 0x9392ee8e921d5d07}, // 1e-18 {0x09befeb9fad487c2, 0xb877aa3236a4b449}, // 1e-17 {0x4c2ebe687989a9b3, 0xe69594bec44de15b}, // 1e-16 {0x0f9d37014bf60a10, 0x901d7cf73ab0acd9}, // 1e-15 {0x538484c19ef38c94, 0xb424dc35095cd80f}, // 1e-14 {0x2865a5f206b06fb9, 0xe12e13424bb40e13}, // 1e-13 {0xf93f87b7442e45d3, 0x8cbccc096f5088cb}, // 1e-12 {0xf78f69a51539d748, 0xafebff0bcb24aafe}, // 1e-11 {0xb573440e5a884d1b, 0xdbe6fecebdedd5be}, // 1e-10 {0x31680a88f8953030, 0x89705f4136b4a597}, // 1e-9 {0xfdc20d2b36ba7c3d, 0xabcc77118461cefc}, // 1e-8 {0x3d32907604691b4c, 0xd6bf94d5e57a42bc}, // 1e-7 {0xa63f9a49c2c1b10f, 0x8637bd05af6c69b5}, // 1e-6 {0x0fcf80dc33721d53, 0xa7c5ac471b478423}, // 1e-5 {0xd3c36113404ea4a8, 0xd1b71758e219652b}, // 1e-4 {0x645a1cac083126e9, 0x83126e978d4fdf3b}, // 1e-3 {0x3d70a3d70a3d70a3, 0xa3d70a3d70a3d70a}, // 1e-2 {0xcccccccccccccccc, 0xcccccccccccccccc}, // 1e-1 {0x0000000000000000, 0x8000000000000000}, // 1e0 {0x0000000000000000, 0xa000000000000000}, // 1e1 {0x0000000000000000, 0xc800000000000000}, // 1e2 {0x0000000000000000, 0xfa00000000000000}, // 1e3 {0x0000000000000000, 0x9c40000000000000}, // 1e4 {0x0000000000000000, 0xc350000000000000}, // 1e5 {0x0000000000000000, 0xf424000000000000}, // 1e6 {0x0000000000000000, 0x9896800000000000}, // 1e7 {0x0000000000000000, 0xbebc200000000000}, // 1e8 {0x0000000000000000, 0xee6b280000000000}, // 1e9 {0x0000000000000000, 0x9502f90000000000}, // 1e10 {0x0000000000000000, 0xba43b74000000000}, // 1e11 {0x0000000000000000, 0xe8d4a51000000000}, // 1e12 {0x0000000000000000, 0x9184e72a00000000}, // 1e13 {0x0000000000000000, 0xb5e620f480000000}, // 1e14 {0x0000000000000000, 0xe35fa931a0000000}, // 1e15 {0x0000000000000000, 0x8e1bc9bf04000000}, // 1e16 {0x0000000000000000, 0xb1a2bc2ec5000000}, // 1e17 {0x0000000000000000, 0xde0b6b3a76400000}, // 1e18 {0x0000000000000000, 0x8ac7230489e80000}, // 1e19 {0x0000000000000000, 0xad78ebc5ac620000}, // 1e20 {0x0000000000000000, 0xd8d726b7177a8000}, // 1e21 {0x0000000000000000, 0x878678326eac9000}, // 1e22 {0x0000000000000000, 0xa968163f0a57b400}, // 1e23 {0x0000000000000000, 0xd3c21bcecceda100}, // 1e24 {0x0000000000000000, 0x84595161401484a0}, // 1e25 {0x0000000000000000, 0xa56fa5b99019a5c8}, // 1e26 {0x0000000000000000, 0xcecb8f27f4200f3a}, // 1e27 {0x4000000000000000, 0x813f3978f8940984}, // 1e28 {0x5000000000000000, 0xa18f07d736b90be5}, // 1e29 {0xa400000000000000, 0xc9f2c9cd04674ede}, // 1e30 {0x4d00000000000000, 0xfc6f7c4045812296}, // 1e31 {0xf020000000000000, 0x9dc5ada82b70b59d}, // 1e32 {0x6c28000000000000, 0xc5371912364ce305}, // 1e33 {0xc732000000000000, 0xf684df56c3e01bc6}, // 1e34 {0x3c7f400000000000, 0x9a130b963a6c115c}, // 1e35 {0x4b9f100000000000, 0xc097ce7bc90715b3}, // 1e36 {0x1e86d40000000000, 0xf0bdc21abb48db20}, // 1e37 {0x1314448000000000, 0x96769950b50d88f4}, // 1e38 {0x17d955a000000000, 0xbc143fa4e250eb31}, // 1e39 {0x5dcfab0800000000, 0xeb194f8e1ae525fd}, // 1e40 {0x5aa1cae500000000, 0x92efd1b8d0cf37be}, // 1e41 {0xf14a3d9e40000000, 0xb7abc627050305ad}, // 1e42 {0x6d9ccd05d0000000, 0xe596b7b0c643c719}, // 1e43 {0xe4820023a2000000, 0x8f7e32ce7bea5c6f}, // 1e44 {0xdda2802c8a800000, 0xb35dbf821ae4f38b}, // 1e45 {0xd50b2037ad200000, 0xe0352f62a19e306e}, // 1e46 {0x4526f422cc340000, 0x8c213d9da502de45}, // 1e47 {0x9670b12b7f410000, 0xaf298d050e4395d6}, // 1e48 {0x3c0cdd765f114000, 0xdaf3f04651d47b4c}, // 1e49 {0xa5880a69fb6ac800, 0x88d8762bf324cd0f}, // 1e50 {0x8eea0d047a457a00, 0xab0e93b6efee0053}, // 1e51 {0x72a4904598d6d880, 0xd5d238a4abe98068}, // 1e52 {0x47a6da2b7f864750, 0x85a36366eb71f041}, // 1e53 {0x999090b65f67d924, 0xa70c3c40a64e6c51}, // 1e54 {0xfff4b4e3f741cf6d, 0xd0cf4b50cfe20765}, // 1e55 {0xbff8f10e7a8921a4, 0x82818f1281ed449f}, // 1e56 {0xaff72d52192b6a0d, 0xa321f2d7226895c7}, // 1e57 {0x9bf4f8a69f764490, 0xcbea6f8ceb02bb39}, // 1e58 {0x02f236d04753d5b4, 0xfee50b7025c36a08}, // 1e59 {0x01d762422c946590, 0x9f4f2726179a2245}, // 1e60 {0x424d3ad2b7b97ef5, 0xc722f0ef9d80aad6}, // 1e61 {0xd2e0898765a7deb2, 0xf8ebad2b84e0d58b}, // 1e62 {0x63cc55f49f88eb2f, 0x9b934c3b330c8577}, // 1e63 {0x3cbf6b71c76b25fb, 0xc2781f49ffcfa6d5}, // 1e64 {0x8bef464e3945ef7a, 0xf316271c7fc3908a}, // 1e65 {0x97758bf0e3cbb5ac, 0x97edd871cfda3a56}, // 1e66 {0x3d52eeed1cbea317, 0xbde94e8e43d0c8ec}, // 1e67 {0x4ca7aaa863ee4bdd, 0xed63a231d4c4fb27}, // 1e68 {0x8fe8caa93e74ef6a, 0x945e455f24fb1cf8}, // 1e69 {0xb3e2fd538e122b44, 0xb975d6b6ee39e436}, // 1e70 {0x60dbbca87196b616, 0xe7d34c64a9c85d44}, // 1e71 {0xbc8955e946fe31cd, 0x90e40fbeea1d3a4a}, // 1e72 {0x6babab6398bdbe41, 0xb51d13aea4a488dd}, // 1e73 {0xc696963c7eed2dd1, 0xe264589a4dcdab14}, // 1e74 {0xfc1e1de5cf543ca2, 0x8d7eb76070a08aec}, // 1e75 {0x3b25a55f43294bcb, 0xb0de65388cc8ada8}, // 1e76 {0x49ef0eb713f39ebe, 0xdd15fe86affad912}, // 1e77 {0x6e3569326c784337, 0x8a2dbf142dfcc7ab}, // 1e78 {0x49c2c37f07965404, 0xacb92ed9397bf996}, // 1e79 {0xdc33745ec97be906, 0xd7e77a8f87daf7fb}, // 1e80 {0x69a028bb3ded71a3, 0x86f0ac99b4e8dafd}, // 1e81 {0xc40832ea0d68ce0c, 0xa8acd7c0222311bc}, // 1e82 {0xf50a3fa490c30190, 0xd2d80db02aabd62b}, // 1e83 {0x792667c6da79e0fa, 0x83c7088e1aab65db}, // 1e84 {0x577001b891185938, 0xa4b8cab1a1563f52}, // 1e85 {0xed4c0226b55e6f86, 0xcde6fd5e09abcf26}, // 1e86 {0x544f8158315b05b4, 0x80b05e5ac60b6178}, // 1e87 {0x696361ae3db1c721, 0xa0dc75f1778e39d6}, // 1e88 {0x03bc3a19cd1e38e9, 0xc913936dd571c84c}, // 1e89 {0x04ab48a04065c723, 0xfb5878494ace3a5f}, // 1e90 {0x62eb0d64283f9c76, 0x9d174b2dcec0e47b}, // 1e91 {0x3ba5d0bd324f8394, 0xc45d1df942711d9a}, // 1e92 {0xca8f44ec7ee36479, 0xf5746577930d6500}, // 1e93 {0x7e998b13cf4e1ecb, 0x9968bf6abbe85f20}, // 1e94 {0x9e3fedd8c321a67e, 0xbfc2ef456ae276e8}, // 1e95 {0xc5cfe94ef3ea101e, 0xefb3ab16c59b14a2}, // 1e96 {0xbba1f1d158724a12, 0x95d04aee3b80ece5}, // 1e97 {0x2a8a6e45ae8edc97, 0xbb445da9ca61281f}, // 1e98 {0xf52d09d71a3293bd, 0xea1575143cf97226}, // 1e99 {0x593c2626705f9c56, 0x924d692ca61be758}, // 1e100 {0x6f8b2fb00c77836c, 0xb6e0c377cfa2e12e}, // 1e101 {0x0b6dfb9c0f956447, 0xe498f455c38b997a}, // 1e102 {0x4724bd4189bd5eac, 0x8edf98b59a373fec}, // 1e103 {0x58edec91ec2cb657, 0xb2977ee300c50fe7}, // 1e104 {0x2f2967b66737e3ed, 0xdf3d5e9bc0f653e1}, // 1e105 {0xbd79e0d20082ee74, 0x8b865b215899f46c}, // 1e106 {0xecd8590680a3aa11, 0xae67f1e9aec07187}, // 1e107 {0xe80e6f4820cc9495, 0xda01ee641a708de9}, // 1e108 {0x3109058d147fdcdd, 0x884134fe908658b2}, // 1e109 {0xbd4b46f0599fd415, 0xaa51823e34a7eede}, // 1e110 {0x6c9e18ac7007c91a, 0xd4e5e2cdc1d1ea96}, // 1e111 {0x03e2cf6bc604ddb0, 0x850fadc09923329e}, // 1e112 {0x84db8346b786151c, 0xa6539930bf6bff45}, // 1e113 {0xe612641865679a63, 0xcfe87f7cef46ff16}, // 1e114 {0x4fcb7e8f3f60c07e, 0x81f14fae158c5f6e}, // 1e115 {0xe3be5e330f38f09d, 0xa26da3999aef7749}, // 1e116 {0x5cadf5bfd3072cc5, 0xcb090c8001ab551c}, // 1e117 {0x73d9732fc7c8f7f6, 0xfdcb4fa002162a63}, // 1e118 {0x2867e7fddcdd9afa, 0x9e9f11c4014dda7e}, // 1e119 {0xb281e1fd541501b8, 0xc646d63501a1511d}, // 1e120 {0x1f225a7ca91a4226, 0xf7d88bc24209a565}, // 1e121 {0x3375788de9b06958, 0x9ae757596946075f}, // 1e122 {0x0052d6b1641c83ae, 0xc1a12d2fc3978937}, // 1e123 {0xc0678c5dbd23a49a, 0xf209787bb47d6b84}, // 1e124 {0xf840b7ba963646e0, 0x9745eb4d50ce6332}, // 1e125 {0xb650e5a93bc3d898, 0xbd176620a501fbff}, // 1e126 {0xa3e51f138ab4cebe, 0xec5d3fa8ce427aff}, // 1e127 {0xc66f336c36b10137, 0x93ba47c980e98cdf}, // 1e128 {0xb80b0047445d4184, 0xb8a8d9bbe123f017}, // 1e129 {0xa60dc059157491e5, 0xe6d3102ad96cec1d}, // 1e130 {0x87c89837ad68db2f, 0x9043ea1ac7e41392}, // 1e131 {0x29babe4598c311fb, 0xb454e4a179dd1877}, // 1e132 {0xf4296dd6fef3d67a, 0xe16a1dc9d8545e94}, // 1e133 {0x1899e4a65f58660c, 0x8ce2529e2734bb1d}, // 1e134 {0x5ec05dcff72e7f8f, 0xb01ae745b101e9e4}, // 1e135 {0x76707543f4fa1f73, 0xdc21a1171d42645d}, // 1e136 {0x6a06494a791c53a8, 0x899504ae72497eba}, // 1e137 {0x0487db9d17636892, 0xabfa45da0edbde69}, // 1e138 {0x45a9d2845d3c42b6, 0xd6f8d7509292d603}, // 1e139 {0x0b8a2392ba45a9b2, 0x865b86925b9bc5c2}, // 1e140 {0x8e6cac7768d7141e, 0xa7f26836f282b732}, // 1e141 {0x3207d795430cd926, 0xd1ef0244af2364ff}, // 1e142 {0x7f44e6bd49e807b8, 0x8335616aed761f1f}, // 1e143 {0x5f16206c9c6209a6, 0xa402b9c5a8d3a6e7}, // 1e144 {0x36dba887c37a8c0f, 0xcd036837130890a1}, // 1e145 {0xc2494954da2c9789, 0x802221226be55a64}, // 1e146 {0xf2db9baa10b7bd6c, 0xa02aa96b06deb0fd}, // 1e147 {0x6f92829494e5acc7, 0xc83553c5c8965d3d}, // 1e148 {0xcb772339ba1f17f9, 0xfa42a8b73abbf48c}, // 1e149 {0xff2a760414536efb, 0x9c69a97284b578d7}, // 1e150 {0xfef5138519684aba, 0xc38413cf25e2d70d}, // 1e151 {0x7eb258665fc25d69, 0xf46518c2ef5b8cd1}, // 1e152 {0xef2f773ffbd97a61, 0x98bf2f79d5993802}, // 1e153 {0xaafb550ffacfd8fa, 0xbeeefb584aff8603}, // 1e154 {0x95ba2a53f983cf38, 0xeeaaba2e5dbf6784}, // 1e155 {0xdd945a747bf26183, 0x952ab45cfa97a0b2}, // 1e156 {0x94f971119aeef9e4, 0xba756174393d88df}, // 1e157 {0x7a37cd5601aab85d, 0xe912b9d1478ceb17}, // 1e158 {0xac62e055c10ab33a, 0x91abb422ccb812ee}, // 1e159 {0x577b986b314d6009, 0xb616a12b7fe617aa}, // 1e160 {0xed5a7e85fda0b80b, 0xe39c49765fdf9d94}, // 1e161 {0x14588f13be847307, 0x8e41ade9fbebc27d}, // 1e162 {0x596eb2d8ae258fc8, 0xb1d219647ae6b31c}, // 1e163 {0x6fca5f8ed9aef3bb, 0xde469fbd99a05fe3}, // 1e164 {0x25de7bb9480d5854, 0x8aec23d680043bee}, // 1e165 {0xaf561aa79a10ae6a, 0xada72ccc20054ae9}, // 1e166 {0x1b2ba1518094da04, 0xd910f7ff28069da4}, // 1e167 {0x90fb44d2f05d0842, 0x87aa9aff79042286}, // 1e168 {0x353a1607ac744a53, 0xa99541bf57452b28}, // 1e169 {0x42889b8997915ce8, 0xd3fa922f2d1675f2}, // 1e170 {0x69956135febada11, 0x847c9b5d7c2e09b7}, // 1e171 {0x43fab9837e699095, 0xa59bc234db398c25}, // 1e172 {0x94f967e45e03f4bb, 0xcf02b2c21207ef2e}, // 1e173 {0x1d1be0eebac278f5, 0x8161afb94b44f57d}, // 1e174 {0x6462d92a69731732, 0xa1ba1ba79e1632dc}, // 1e175 {0x7d7b8f7503cfdcfe, 0xca28a291859bbf93}, // 1e176 {0x5cda735244c3d43e, 0xfcb2cb35e702af78}, // 1e177 {0x3a0888136afa64a7, 0x9defbf01b061adab}, // 1e178 {0x088aaa1845b8fdd0, 0xc56baec21c7a1916}, // 1e179 {0x8aad549e57273d45, 0xf6c69a72a3989f5b}, // 1e180 {0x36ac54e2f678864b, 0x9a3c2087a63f6399}, // 1e181 {0x84576a1bb416a7dd, 0xc0cb28a98fcf3c7f}, // 1e182 {0x656d44a2a11c51d5, 0xf0fdf2d3f3c30b9f}, // 1e183 {0x9f644ae5a4b1b325, 0x969eb7c47859e743}, // 1e184 {0x873d5d9f0dde1fee, 0xbc4665b596706114}, // 1e185 {0xa90cb506d155a7ea, 0xeb57ff22fc0c7959}, // 1e186 {0x09a7f12442d588f2, 0x9316ff75dd87cbd8}, // 1e187 {0x0c11ed6d538aeb2f, 0xb7dcbf5354e9bece}, // 1e188 {0x8f1668c8a86da5fa, 0xe5d3ef282a242e81}, // 1e189 {0xf96e017d694487bc, 0x8fa475791a569d10}, // 1e190 {0x37c981dcc395a9ac, 0xb38d92d760ec4455}, // 1e191 {0x85bbe253f47b1417, 0xe070f78d3927556a}, // 1e192 {0x93956d7478ccec8e, 0x8c469ab843b89562}, // 1e193 {0x387ac8d1970027b2, 0xaf58416654a6babb}, // 1e194 {0x06997b05fcc0319e, 0xdb2e51bfe9d0696a}, // 1e195 {0x441fece3bdf81f03, 0x88fcf317f22241e2}, // 1e196 {0xd527e81cad7626c3, 0xab3c2fddeeaad25a}, // 1e197 {0x8a71e223d8d3b074, 0xd60b3bd56a5586f1}, // 1e198 {0xf6872d5667844e49, 0x85c7056562757456}, // 1e199 {0xb428f8ac016561db, 0xa738c6bebb12d16c}, // 1e200 {0xe13336d701beba52, 0xd106f86e69d785c7}, // 1e201 {0xecc0024661173473, 0x82a45b450226b39c}, // 1e202 {0x27f002d7f95d0190, 0xa34d721642b06084}, // 1e203 {0x31ec038df7b441f4, 0xcc20ce9bd35c78a5}, // 1e204 {0x7e67047175a15271, 0xff290242c83396ce}, // 1e205 {0x0f0062c6e984d386, 0x9f79a169bd203e41}, // 1e206 {0x52c07b78a3e60868, 0xc75809c42c684dd1}, // 1e207 {0xa7709a56ccdf8a82, 0xf92e0c3537826145}, // 1e208 {0x88a66076400bb691, 0x9bbcc7a142b17ccb}, // 1e209 {0x6acff893d00ea435, 0xc2abf989935ddbfe}, // 1e210 {0x0583f6b8c4124d43, 0xf356f7ebf83552fe}, // 1e211 {0xc3727a337a8b704a, 0x98165af37b2153de}, // 1e212 {0x744f18c0592e4c5c, 0xbe1bf1b059e9a8d6}, // 1e213 {0x1162def06f79df73, 0xeda2ee1c7064130c}, // 1e214 {0x8addcb5645ac2ba8, 0x9485d4d1c63e8be7}, // 1e215 {0x6d953e2bd7173692, 0xb9a74a0637ce2ee1}, // 1e216 {0xc8fa8db6ccdd0437, 0xe8111c87c5c1ba99}, // 1e217 {0x1d9c9892400a22a2, 0x910ab1d4db9914a0}, // 1e218 {0x2503beb6d00cab4b, 0xb54d5e4a127f59c8}, // 1e219 {0x2e44ae64840fd61d, 0xe2a0b5dc971f303a}, // 1e220 {0x5ceaecfed289e5d2, 0x8da471a9de737e24}, // 1e221 {0x7425a83e872c5f47, 0xb10d8e1456105dad}, // 1e222 {0xd12f124e28f77719, 0xdd50f1996b947518}, // 1e223 {0x82bd6b70d99aaa6f, 0x8a5296ffe33cc92f}, // 1e224 {0x636cc64d1001550b, 0xace73cbfdc0bfb7b}, // 1e225 {0x3c47f7e05401aa4e, 0xd8210befd30efa5a}, // 1e226 {0x65acfaec34810a71, 0x8714a775e3e95c78}, // 1e227 {0x7f1839a741a14d0d, 0xa8d9d1535ce3b396}, // 1e228 {0x1ede48111209a050, 0xd31045a8341ca07c}, // 1e229 {0x934aed0aab460432, 0x83ea2b892091e44d}, // 1e230 {0xf81da84d5617853f, 0xa4e4b66b68b65d60}, // 1e231 {0x36251260ab9d668e, 0xce1de40642e3f4b9}, // 1e232 {0xc1d72b7c6b426019, 0x80d2ae83e9ce78f3}, // 1e233 {0xb24cf65b8612f81f, 0xa1075a24e4421730}, // 1e234 {0xdee033f26797b627, 0xc94930ae1d529cfc}, // 1e235 {0x169840ef017da3b1, 0xfb9b7cd9a4a7443c}, // 1e236 {0x8e1f289560ee864e, 0x9d412e0806e88aa5}, // 1e237 {0xf1a6f2bab92a27e2, 0xc491798a08a2ad4e}, // 1e238 {0xae10af696774b1db, 0xf5b5d7ec8acb58a2}, // 1e239 {0xacca6da1e0a8ef29, 0x9991a6f3d6bf1765}, // 1e240 {0x17fd090a58d32af3, 0xbff610b0cc6edd3f}, // 1e241 {0xddfc4b4cef07f5b0, 0xeff394dcff8a948e}, // 1e242 {0x4abdaf101564f98e, 0x95f83d0a1fb69cd9}, // 1e243 {0x9d6d1ad41abe37f1, 0xbb764c4ca7a4440f}, // 1e244 {0x84c86189216dc5ed, 0xea53df5fd18d5513}, // 1e245 {0x32fd3cf5b4e49bb4, 0x92746b9be2f8552c}, // 1e246 {0x3fbc8c33221dc2a1, 0xb7118682dbb66a77}, // 1e247 {0x0fabaf3feaa5334a, 0xe4d5e82392a40515}, // 1e248 {0x29cb4d87f2a7400e, 0x8f05b1163ba6832d}, // 1e249 {0x743e20e9ef511012, 0xb2c71d5bca9023f8}, // 1e250 {0x914da9246b255416, 0xdf78e4b2bd342cf6}, // 1e251 {0x1ad089b6c2f7548e, 0x8bab8eefb6409c1a}, // 1e252 {0xa184ac2473b529b1, 0xae9672aba3d0c320}, // 1e253 {0xc9e5d72d90a2741e, 0xda3c0f568cc4f3e8}, // 1e254 {0x7e2fa67c7a658892, 0x8865899617fb1871}, // 1e255 {0xddbb901b98feeab7, 0xaa7eebfb9df9de8d}, // 1e256 {0x552a74227f3ea565, 0xd51ea6fa85785631}, // 1e257 {0xd53a88958f87275f, 0x8533285c936b35de}, // 1e258 {0x8a892abaf368f137, 0xa67ff273b8460356}, // 1e259 {0x2d2b7569b0432d85, 0xd01fef10a657842c}, // 1e260 {0x9c3b29620e29fc73, 0x8213f56a67f6b29b}, // 1e261 {0x8349f3ba91b47b8f, 0xa298f2c501f45f42}, // 1e262 {0x241c70a936219a73, 0xcb3f2f7642717713}, // 1e263 {0xed238cd383aa0110, 0xfe0efb53d30dd4d7}, // 1e264 {0xf4363804324a40aa, 0x9ec95d1463e8a506}, // 1e265 {0xb143c6053edcd0d5, 0xc67bb4597ce2ce48}, // 1e266 {0xdd94b7868e94050a, 0xf81aa16fdc1b81da}, // 1e267 {0xca7cf2b4191c8326, 0x9b10a4e5e9913128}, // 1e268 {0xfd1c2f611f63a3f0, 0xc1d4ce1f63f57d72}, // 1e269 {0xbc633b39673c8cec, 0xf24a01a73cf2dccf}, // 1e270 {0xd5be0503e085d813, 0x976e41088617ca01}, // 1e271 {0x4b2d8644d8a74e18, 0xbd49d14aa79dbc82}, // 1e272 {0xddf8e7d60ed1219e, 0xec9c459d51852ba2}, // 1e273 {0xcabb90e5c942b503, 0x93e1ab8252f33b45}, // 1e274 {0x3d6a751f3b936243, 0xb8da1662e7b00a17}, // 1e275 {0x0cc512670a783ad4, 0xe7109bfba19c0c9d}, // 1e276 {0x27fb2b80668b24c5, 0x906a617d450187e2}, // 1e277 {0xb1f9f660802dedf6, 0xb484f9dc9641e9da}, // 1e278 {0x5e7873f8a0396973, 0xe1a63853bbd26451}, // 1e279 {0xdb0b487b6423e1e8, 0x8d07e33455637eb2}, // 1e280 {0x91ce1a9a3d2cda62, 0xb049dc016abc5e5f}, // 1e281 {0x7641a140cc7810fb, 0xdc5c5301c56b75f7}, // 1e282 {0xa9e904c87fcb0a9d, 0x89b9b3e11b6329ba}, // 1e283 {0x546345fa9fbdcd44, 0xac2820d9623bf429}, // 1e284 {0xa97c177947ad4095, 0xd732290fbacaf133}, // 1e285 {0x49ed8eabcccc485d, 0x867f59a9d4bed6c0}, // 1e286 {0x5c68f256bfff5a74, 0xa81f301449ee8c70}, // 1e287 {0x73832eec6fff3111, 0xd226fc195c6a2f8c}, // 1e288 }; static const double ms_atof_f64_powers_of_10[23] = { 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22 }; static const uint16_t ms_atof_left_shift[65] = { 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817, 0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067, 0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF, 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0, 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA, 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC, 0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C, 0x051C, 0x051C }; static const uint8_t ms_atof_powers_of_5[1308] = { 5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, 3, 9, 0, 6, 2, 5, 1, 9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, 2, 8, 1, 2, 5, 2, 4, 4, 1, 4, 0, 6, 2, 5, 1, 2, 2, 0, 7, 0, 3, 1, 2, 5, 6, 1, 0, 3, 5, 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2, 5, 1, 5, 2, 5, 8, 7, 8, 9, 0, 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, 3, 8, 1, 4, 6, 9, 7, 2, 6, 5, 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, 8, 1, 2, 5, 9, 5, 3, 6, 7, 4, 3, 1, 6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, 7, 1, 5, 8, 2, 0, 3, 1, 2, 5, 2, 3, 8, 4, 1, 8, 5, 7, 9, 1, 0, 1, 5, 6, 2, 5, 1, 1, 9, 2, 0, 9, 2, 8, 9, 5, 5, 0, 7, 8, 1, 2, 5, 5, 9, 6, 0, 4, 6, 4, 4, 7, 7, 5, 3, 9, 0, 6, 2, 5, 2, 9, 8, 0, 2, 3, 2, 2, 3, 8, 7, 6, 9, 5, 3, 1, 2, 5, 1, 4, 9, 0, 1, 1, 6, 1, 1, 9, 3, 8, 4, 7, 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8, 0, 5, 9, 6, 9, 2, 3, 8, 2, 8, 1, 2, 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4, 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, 6, 2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5, 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, 2, 2, 5, 7, 4, 6, 1, 5, 4, 7, 8, 5, 1, 5, 6, 2, 5, 4, 6, 5, 6, 6, 1, 2, 8, 7, 3, 0, 7, 7, 3, 9, 2, 5, 7, 8, 1, 2, 5, 2, 3, 2, 8, 3, 0, 6, 4, 3, 6, 5, 3, 8, 6, 9, 6, 2, 8, 9, 0, 6, 2, 5, 1, 1, 6, 4, 1, 5, 3, 2, 1, 8, 2, 6, 9, 3, 4, 8, 1, 4, 4, 5, 3, 1, 2, 5, 5, 8, 2, 0, 7, 6, 6, 0, 9, 1, 3, 4, 6, 7, 4, 0, 7, 2, 2, 6, 5, 6, 2, 5, 2, 9, 1, 0, 3, 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6, 1, 3, 2, 8, 1, 2, 5, 1, 4, 5, 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8, 0, 6, 6, 4, 0, 6, 2, 5, 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9, 0, 3, 3, 2, 0, 3, 1, 2, 5, 3, 6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2, 9, 5, 1, 6, 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8, 9, 8, 9, 4, 0, 3, 5, 4, 5, 8, 5, 6, 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4, 7, 0, 1, 7, 7, 2, 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, 3, 5, 0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, 2, 2, 7, 3, 7, 3, 6, 7, 5, 4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, 9, 7, 6, 5, 6, 2, 5, 1, 1, 3, 6, 8, 6, 8, 3, 7, 7, 2, 1, 6, 1, 6, 0, 2, 9, 7, 3, 9, 3, 7, 9, 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8, 8, 6, 0, 8, 0, 8, 0, 1, 4, 8, 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, 2, 8, 4, 2, 1, 7, 0, 9, 4, 3, 0, 4, 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, 9, 7, 0, 7, 0, 3, 1, 2, 5, 1, 4, 2, 1, 0, 8, 5, 4, 7, 1, 5, 2, 0, 2, 0, 0, 3, 7, 1, 7, 4, 2, 2, 4, 8, 5, 3, 5, 1, 5, 6, 2, 5, 7, 1, 0, 5, 4, 2, 7, 3, 5, 7, 6, 0, 1, 0, 0, 1, 8, 5, 8, 7, 1, 1, 2, 4, 2, 6, 7, 5, 7, 8, 1, 2, 5, 3, 5, 5, 2, 7, 1, 3, 6, 7, 8, 8, 0, 0, 5, 0, 0, 9, 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8, 9, 0, 6, 2, 5, 1, 7, 7, 6, 3, 5, 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4, 6, 7, 7, 8, 1, 0, 6, 6, 8, 9, 4, 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1, 9, 7, 0, 0, 1, 2, 5, 2, 3, 2, 3, 3, 8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5, 6, 2, 5, 4, 4, 4, 0, 8, 9, 2, 0, 9, 8, 5, 0, 0, 6, 2, 6, 1, 6, 1, 6, 9, 4, 5, 2, 6, 6, 7, 2, 3, 6, 3, 2, 8, 1, 2, 5, 2, 2, 2, 0, 4, 4, 6, 0, 4, 9, 2, 5, 0, 3, 1, 3, 0, 8, 0, 8, 4, 7, 2, 6, 3, 3, 3, 6, 1, 8, 1, 6, 4, 0, 6, 2, 5, 1, 1, 1, 0, 2, 2, 3, 0, 2, 4, 6, 2, 5, 1, 5, 6, 5, 4, 0, 4, 2, 3, 6, 3, 1, 6, 6, 8, 0, 9, 0, 8, 2, 0, 3, 1, 2, 5, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5, 8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5, 6, 2, 8, 9, 1, 3, 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8, 1, 2, 5, 1, 3, 8, 7, 7, 7, 8, 7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9, 5, 3, 9, 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0, 6, 2, 5, 6, 9, 3, 8, 8, 9, 3, 9, 0, 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2, 5, 5, 6, 7, 6, 2, 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, 6, 1, 4, 1, 8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, 6, 5, 6, 2, 5, 1, 7, 3, 4, 7, 2, 3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, 4, 4, 1, 1, 9, 2, 4, 4, 8, 1, 3, 9, 1, 9, 0, 6, 7, 3, 8, 2, 8, 1, 2, 5, 8, 6, 7, 3, 6, 1, 7, 3, 7, 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, 6, 2, 2, 4, 0, 6, 9, 5, 9, 5, 3, 3, 6, 9, 1, 4, 0, 6, 2, 5 }; #endif python-msgspec-0.19.0/msgspec/common.h000066400000000000000000000010161473355726200176770ustar00rootroot00000000000000#ifndef MS_COMMON_H #define MS_COMMON_H #ifdef __GNUC__ #define MS_LIKELY(pred) __builtin_expect(!!(pred), 1) #define MS_UNLIKELY(pred) __builtin_expect(!!(pred), 0) #else #define MS_LIKELY(pred) (pred) #define MS_UNLIKELY(pred) (pred) #endif #ifdef __GNUC__ #define MS_INLINE __attribute__((always_inline)) inline #define MS_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) #define MS_INLINE __forceinline #define MS_NOINLINE __declspec(noinline) #else #define MS_INLINE inline #define MS_NOINLINE #endif #endif python-msgspec-0.19.0/msgspec/inspect.py000066400000000000000000000703401473355726200202630ustar00rootroot00000000000000from __future__ import annotations import datetime import decimal import enum import uuid from collections.abc import Iterable from typing import ( Any, Final, Literal, Tuple, Type as typing_Type, TypeVar, Union, ) try: from types import UnionType as _types_UnionType # type: ignore except Exception: _types_UnionType = type("UnionType", (), {}) # type: ignore try: from typing import TypeAliasType as _TypeAliasType # type: ignore except Exception: _TypeAliasType = type("TypeAliasType", (), {}) # type: ignore import msgspec from msgspec import NODEFAULT, UNSET, UnsetType as _UnsetType from ._core import ( # type: ignore Factory as _Factory, to_builtins as _to_builtins, ) from ._utils import ( # type: ignore _CONCRETE_TYPES, _AnnotatedAlias, get_class_annotations as _get_class_annotations, get_dataclass_info as _get_dataclass_info, get_typeddict_info as _get_typeddict_info, ) __all__ = ( "type_info", "multi_type_info", "Type", "Metadata", "AnyType", "NoneType", "BoolType", "IntType", "FloatType", "StrType", "BytesType", "ByteArrayType", "MemoryViewType", "DateTimeType", "TimeType", "DateType", "TimeDeltaType", "UUIDType", "DecimalType", "ExtType", "RawType", "EnumType", "LiteralType", "CustomType", "UnionType", "CollectionType", "ListType", "SetType", "FrozenSetType", "VarTupleType", "TupleType", "DictType", "Field", "TypedDictType", "NamedTupleType", "DataclassType", "StructType", ) def __dir__(): return __all__ class Type(msgspec.Struct): """The base Type.""" class Metadata(Type): """A type wrapping a subtype with additional metadata. Parameters ---------- type: Type The subtype. extra_json_schema: dict, optional A dict of extra fields to set for the subtype when generating a json-schema. extra: dict, optional A dict of extra user-defined metadata attached to the subtype. """ type: Type extra_json_schema: Union[dict, None] = None extra: Union[dict, None] = None class AnyType(Type): """A type corresponding to `typing.Any`.""" class NoneType(Type): """A type corresponding to `None`.""" class BoolType(Type): """A type corresponding to `bool`.""" class IntType(Type): """A type corresponding to `int`. Parameters ---------- gt: int, optional If set, an instance of this type must be greater than ``gt``. ge: int, optional If set, an instance of this type must be greater than or equal to ``ge``. lt: int, optional If set, an instance of this type must be less than to ``lt``. le: int, optional If set, an instance of this type must be less than or equal to ``le``. multiple_of: int, optional If set, an instance of this type must be a multiple of ``multiple_of``. """ gt: Union[int, None] = None ge: Union[int, None] = None lt: Union[int, None] = None le: Union[int, None] = None multiple_of: Union[int, None] = None class FloatType(Type): """A type corresponding to `float`. Parameters ---------- gt: float, optional If set, an instance of this type must be greater than ``gt``. ge: float, optional If set, an instance of this type must be greater than or equal to ``ge``. lt: float, optional If set, an instance of this type must be less than to ``lt``. le: float, optional If set, an instance of this type must be less than or equal to ``le``. multiple_of: float, optional If set, an instance of this type must be a multiple of ``multiple_of``. """ gt: Union[float, None] = None ge: Union[float, None] = None lt: Union[float, None] = None le: Union[float, None] = None multiple_of: Union[float, None] = None class StrType(Type): """A type corresponding to `str`. Parameters ---------- min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. pattern: str, optional If set, an instance of this type must match against this regex pattern. Note that the pattern is treated as **unanchored**. """ min_length: Union[int, None] = None max_length: Union[int, None] = None pattern: Union[str, None] = None class BytesType(Type): """A type corresponding to `bytes`. Parameters ---------- min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ min_length: Union[int, None] = None max_length: Union[int, None] = None class ByteArrayType(Type): """A type corresponding to `bytearray`. Parameters ---------- min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ min_length: Union[int, None] = None max_length: Union[int, None] = None class MemoryViewType(Type): """A type corresponding to `memoryview`. Parameters ---------- min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ min_length: Union[int, None] = None max_length: Union[int, None] = None class DateTimeType(Type): """A type corresponding to `datetime.datetime`. Parameters ---------- tz: bool The timezone-requirements for an instance of this type. ``True`` indicates a timezone-aware value is required, ``False`` indicates a timezone-aware value is required. The default is ``None``, which accepts either timezone-aware or timezone-naive values. """ tz: Union[bool, None] = None class TimeType(Type): """A type corresponding to `datetime.time`. Parameters ---------- tz: bool The timezone-requirements for an instance of this type. ``True`` indicates a timezone-aware value is required, ``False`` indicates a timezone-aware value is required. The default is ``None``, which accepts either timezone-aware or timezone-naive values. """ tz: Union[bool, None] = None class DateType(Type): """A type corresponding to `datetime.date`.""" class TimeDeltaType(Type): """A type corresponding to `datetime.timedelta`.""" class UUIDType(Type): """A type corresponding to `uuid.UUID`.""" class DecimalType(Type): """A type corresponding to `decimal.Decimal`.""" class ExtType(Type): """A type corresponding to `msgspec.msgpack.Ext`.""" class RawType(Type): """A type corresponding to `msgspec.Raw`.""" class EnumType(Type): """A type corresponding to an `enum.Enum` type. Parameters ---------- cls: type The corresponding `enum.Enum` type. """ cls: typing_Type[enum.Enum] class LiteralType(Type): """A type corresponding to a `typing.Literal` type. Parameters ---------- values: tuple A tuple of possible values for this literal instance. Only `str` or `int` literals are supported. """ values: Union[Tuple[str, ...], Tuple[int, ...]] class CustomType(Type): """A custom type. Parameters ---------- cls: type The corresponding custom type. """ cls: type class UnionType(Type): """A union type. Parameters ---------- types: Tuple[Type, ...] A tuple of possible types for this union. """ types: Tuple[Type, ...] @property def includes_none(self) -> bool: """A helper for checking whether ``None`` is included in this union.""" return any(isinstance(t, NoneType) for t in self.types) class CollectionType(Type): """A collection type. This is the base type shared by collection types like `ListType`, `SetType`, etc. Parameters ---------- item_type: Type The item type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ item_type: Type min_length: Union[int, None] = None max_length: Union[int, None] = None class ListType(CollectionType): """A type corresponding to a `list`. Parameters ---------- item_type: Type The item type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ class VarTupleType(CollectionType): """A type corresponding to a variadic `tuple`. Parameters ---------- item_type: Type The item type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ class SetType(CollectionType): """A type corresponding to a `set`. Parameters ---------- item_type: Type The item type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ class FrozenSetType(CollectionType): """A type corresponding to a `frozenset`. Parameters ---------- item_type: Type The item type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ class TupleType(Type): """A type corresponding to `tuple`. Parameters ---------- item_types: Tuple[Type, ...] A tuple of types for each element in the tuple. """ item_types: Tuple[Type, ...] class DictType(Type): """A type corresponding to `dict`. Parameters ---------- key_type: Type The key type. value_type: Type The value type. min_length: int, optional If set, an instance of this type must have length greater than or equal to ``min_length``. max_length: int, optional If set, an instance of this type must have length less than or equal to ``max_length``. """ key_type: Type value_type: Type min_length: Union[int, None] = None max_length: Union[int, None] = None class Field(msgspec.Struct): """A record describing a field in an object-like type. Parameters ---------- name: str The field name as seen by Python code (e.g. ``field_one``). encode_name: str The name used when encoding/decoding the field. This may differ if the field is renamed (e.g. ``fieldOne``). type: Type The field type. required: bool, optional Whether the field is required. Note that if `required` is False doesn't necessarily mean that `default` or `default_factory` will be set - optional fields may exist with no default value. default: Any, optional A default value for the field. Will be `NODEFAULT` if no default value is set. default_factory: Any, optional A callable that creates a default value for the field. Will be `NODEFAULT` if no ``default_factory`` is set. """ name: str encode_name: str type: Type required: bool = True default: Any = msgspec.field(default_factory=lambda: NODEFAULT) default_factory: Any = msgspec.field(default_factory=lambda: NODEFAULT) class TypedDictType(Type): """A type corresponding to a `typing.TypedDict` type. Parameters ---------- cls: type The corresponding TypedDict type. fields: Tuple[Field, ...] A tuple of fields in the TypedDict. """ cls: type fields: Tuple[Field, ...] class NamedTupleType(Type): """A type corresponding to a `typing.NamedTuple` type. Parameters ---------- cls: type The corresponding NamedTuple type. fields: Tuple[Field, ...] A tuple of fields in the NamedTuple. """ cls: type fields: Tuple[Field, ...] class DataclassType(Type): """A type corresponding to a `dataclasses` or `attrs` type. Parameters ---------- cls: type The corresponding dataclass type. fields: Tuple[Field, ...] A tuple of fields in the dataclass. """ cls: type fields: Tuple[Field, ...] class StructType(Type): """A type corresponding to a `msgspec.Struct` type. Parameters ---------- cls: type The corresponding Struct type. fields: Tuple[Field, ...] A tuple of fields in the Struct. tag_field: str or None, optional If set, the field name used for the tag in a tagged union. tag: str, int, or None, optional If set, the value used for the tag in a tagged union. array_like: bool, optional Whether the struct is encoded as an array rather than an object. forbid_unknown_fields: bool, optional If ``False`` (the default) unknown fields are ignored when decoding. If ``True`` any unknown fields will result in an error. """ cls: typing_Type[msgspec.Struct] fields: Tuple[Field, ...] tag_field: Union[str, None] = None tag: Union[str, int, None] = None array_like: bool = False forbid_unknown_fields: bool = False def multi_type_info(types: Iterable[Any]) -> tuple[Type, ...]: """Get information about multiple msgspec-compatible types. Parameters ---------- types: an iterable of types The types to get info about. Returns ------- tuple[Type, ...] Examples -------- >>> msgspec.inspect.multi_type_info([int, float, list[str]]) # doctest: +NORMALIZE_WHITESPACE (IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None), FloatType(gt=None, ge=None, lt=None, le=None, multiple_of=None), ListType(item_type=StrType(min_length=None, max_length=None, pattern=None), min_length=None, max_length=None)) """ return _Translator(types).run() def type_info(type: Any) -> Type: """Get information about a msgspec-compatible type. Note that if you need to inspect multiple types it's more efficient to call `multi_type_info` once with a sequence of types than calling `type_info` multiple times. Parameters ---------- type: type The type to get info about. Returns ------- Type Examples -------- >>> msgspec.inspect.type_info(bool) BoolType() >>> msgspec.inspect.type_info(int) IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None) >>> msgspec.inspect.type_info(list[int]) # doctest: +NORMALIZE_WHITESPACE ListType(item_type=IntType(gt=None, ge=None, lt=None, le=None, multiple_of=None), min_length=None, max_length=None) """ return multi_type_info([type])[0] # Implementation details def _origin_args_metadata(t): # Strip wrappers (Annotated, NewType, Final) until we hit a concrete type metadata = [] while True: try: origin = _CONCRETE_TYPES.get(t) except TypeError: # t is not hashable origin = None if origin is not None: args = None break origin = getattr(t, "__origin__", None) if origin is not None: if type(t) is _AnnotatedAlias: metadata.extend(m for m in t.__metadata__ if type(m) is msgspec.Meta) t = origin elif origin == Final: t = t.__args__[0] elif type(origin) is _TypeAliasType: t = origin.__value__[t.__args__] else: args = getattr(t, "__args__", None) origin = _CONCRETE_TYPES.get(origin, origin) break else: supertype = getattr(t, "__supertype__", None) if supertype is not None: t = supertype elif type(t) is _TypeAliasType: t = t.__value__ else: origin = t args = None break if type(origin) is _types_UnionType: args = origin.__args__ origin = Union return origin, args, tuple(metadata) def _is_struct(t): return type(t) is type(msgspec.Struct) def _is_enum(t): return type(t) is enum.EnumMeta def _is_dataclass(t): return hasattr(t, "__dataclass_fields__") def _is_attrs(t): return hasattr(t, "__attrs_attrs__") def _is_typeddict(t): try: return issubclass(t, dict) and hasattr(t, "__total__") except TypeError: return False def _is_namedtuple(t): try: return issubclass(t, tuple) and hasattr(t, "_fields") except TypeError: return False def _merge_json(a, b): if b: a = a.copy() for key, b_val in b.items(): if key in a: a_val = a[key] if isinstance(a_val, dict) and isinstance(b_val, dict): a[key] = _merge_json(a_val, b_val) elif isinstance(a_val, (list, tuple)) and isinstance( b_val, (list, tuple) ): a[key] = list(a_val) + list(b_val) else: a[key] = b_val else: a[key] = b_val return a class _Translator: def __init__(self, types): self.types = tuple(types) self.type_hints = {} self.cache = {} def _get_class_annotations(self, t): """A cached version of `get_class_annotations`""" try: return self.type_hints[t] except KeyError: out = self.type_hints[t] = _get_class_annotations(t) return out def run(self): # First construct a decoder to validate the types are valid from ._core import MsgpackDecoder MsgpackDecoder(Tuple[self.types]) return tuple(self.translate(t) for t in self.types) def translate(self, typ): t, args, metadata = _origin_args_metadata(typ) # Extract and merge components of any `Meta` annotations constrs = {} extra_json_schema = {} extra = {} for meta in metadata: for attr in ( "ge", "gt", "le", "lt", "multiple_of", "pattern", "min_length", "max_length", "tz", ): if (val := getattr(meta, attr)) is not None: constrs[attr] = val for attr in ("title", "description", "examples"): if (val := getattr(meta, attr)) is not None: extra_json_schema[attr] = val if meta.extra_json_schema is not None: extra_json_schema = _merge_json( extra_json_schema, _to_builtins(meta.extra_json_schema, str_keys=True), ) if meta.extra is not None: extra.update(meta.extra) out = self._translate_inner(t, args, **constrs) if extra_json_schema or extra: # If extra metadata is present, wrap the output type in a Metadata # wrapper object return Metadata( out, extra_json_schema=extra_json_schema or None, extra=extra or None ) return out def _translate_inner( self, t, args, ge=None, gt=None, le=None, lt=None, multiple_of=None, pattern=None, min_length=None, max_length=None, tz=None, ): if t is Any: return AnyType() elif isinstance(t, TypeVar): if t.__bound__ is not None: return self.translate(t.__bound__) return AnyType() elif t is None or t is type(None): return NoneType() elif t is bool: return BoolType() elif t is int: return IntType(ge=ge, gt=gt, le=le, lt=lt, multiple_of=multiple_of) elif t is float: return FloatType(ge=ge, gt=gt, le=le, lt=lt, multiple_of=multiple_of) elif t is str: return StrType( min_length=min_length, max_length=max_length, pattern=pattern ) elif t is bytes: return BytesType(min_length=min_length, max_length=max_length) elif t is bytearray: return ByteArrayType(min_length=min_length, max_length=max_length) elif t is memoryview: return MemoryViewType(min_length=min_length, max_length=max_length) elif t is datetime.datetime: return DateTimeType(tz=tz) elif t is datetime.time: return TimeType(tz=tz) elif t is datetime.date: return DateType() elif t is datetime.timedelta: return TimeDeltaType() elif t is uuid.UUID: return UUIDType() elif t is decimal.Decimal: return DecimalType() elif t is msgspec.Raw: return RawType() elif t is msgspec.msgpack.Ext: return ExtType() elif t is list: return ListType( self.translate(args[0]) if args else AnyType(), min_length=min_length, max_length=max_length, ) elif t is set: return SetType( self.translate(args[0]) if args else AnyType(), min_length=min_length, max_length=max_length, ) elif t is frozenset: return FrozenSetType( self.translate(args[0]) if args else AnyType(), min_length=min_length, max_length=max_length, ) elif t is tuple: # Handle an annoying compatibility issue: # - Tuple[()] has args == ((),) # - tuple[()] has args == () if args == ((),): args = () if args is None: return VarTupleType( AnyType(), min_length=min_length, max_length=max_length ) elif len(args) == 2 and args[-1] is ...: return VarTupleType( self.translate(args[0]), min_length=min_length, max_length=max_length, ) else: return TupleType(tuple(self.translate(a) for a in args)) elif t is dict: return DictType( self.translate(args[0]) if args else AnyType(), self.translate(args[1]) if args else AnyType(), min_length=min_length, max_length=max_length, ) elif t is Union: args = tuple(self.translate(a) for a in args if a is not _UnsetType) return args[0] if len(args) == 1 else UnionType(args) elif t is Literal: return LiteralType(tuple(sorted(args))) elif _is_enum(t): return EnumType(t) elif _is_struct(t): cls = t[args] if args else t if cls in self.cache: return self.cache[cls] config = t.__struct_config__ self.cache[cls] = out = StructType( cls, (), tag_field=config.tag_field, tag=config.tag, array_like=config.array_like, forbid_unknown_fields=config.forbid_unknown_fields, ) hints = self._get_class_annotations(cls) npos = len(t.__struct_fields__) - len(t.__struct_defaults__) fields = [] for name, encode_name, default_obj in zip( t.__struct_fields__, t.__struct_encode_fields__, (NODEFAULT,) * npos + t.__struct_defaults__, ): if default_obj is NODEFAULT: required = True default = default_factory = NODEFAULT elif isinstance(default_obj, _Factory): required = False default = NODEFAULT default_factory = default_obj.factory else: required = False default = NODEFAULT if default_obj is UNSET else default_obj default_factory = NODEFAULT field = Field( name=name, encode_name=encode_name, type=self.translate(hints[name]), required=required, default=default, default_factory=default_factory, ) fields.append(field) out.fields = tuple(fields) return out elif _is_typeddict(t): cls = t[args] if args else t if cls in self.cache: return self.cache[cls] self.cache[cls] = out = TypedDictType(cls, ()) hints, required = _get_typeddict_info(cls) out.fields = tuple( Field( name=name, encode_name=name, type=self.translate(field_type), required=name in required, ) for name, field_type in sorted(hints.items()) ) return out elif _is_dataclass(t) or _is_attrs(t): cls = t[args] if args else t if cls in self.cache: return self.cache[cls] self.cache[cls] = out = DataclassType(cls, ()) _, info, defaults, _, _ = _get_dataclass_info(cls) defaults = ((NODEFAULT,) * (len(info) - len(defaults))) + defaults fields = [] for (name, typ, is_factory), default_obj in zip(info, defaults): if default_obj is NODEFAULT: required = True default = default_factory = NODEFAULT elif is_factory: required = False default = NODEFAULT default_factory = default_obj else: required = False default = NODEFAULT if default_obj is UNSET else default_obj default_factory = NODEFAULT fields.append( Field( name=name, encode_name=name, type=self.translate(typ), required=required, default=default, default_factory=default_factory, ) ) out.fields = tuple(fields) return out elif _is_namedtuple(t): cls = t[args] if args else t if cls in self.cache: return self.cache[cls] self.cache[cls] = out = NamedTupleType(cls, ()) hints = self._get_class_annotations(cls) out.fields = tuple( Field( name=name, encode_name=name, type=self.translate(hints.get(name, Any)), required=name not in t._field_defaults, default=t._field_defaults.get(name, NODEFAULT), ) for name in t._fields ) return out else: return CustomType(t) python-msgspec-0.19.0/msgspec/itoa.h000066400000000000000000000210251473355726200173450ustar00rootroot00000000000000/* This code is a modified and condensed version of the int -> str routines * found in yyjson (https://github.com/ibireme/yyjson). The yyjson license * is copied below: * * Copyright (c) 2020 YaoYuan * 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. */ #ifndef MS_ITOA_H #define MS_ITOA_H #include #include "common.h" static const char DIGIT_TABLE[200] = { '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' }; static MS_INLINE void write_u32_8_digits(uint32_t x, char *buf) { uint32_t aabb, ccdd, aa, bb, cc, dd; aabb = (uint32_t)(((uint64_t)x * 109951163) >> 40); /* (x / 10000) */ ccdd = x - aabb * 10000; /* (x % 10000) */ aa = (aabb * 5243) >> 19; /* (aabb / 100) */ bb = aabb - aa * 100; /* (aabb % 100) */ cc = (ccdd * 5243) >> 19; /* (ccdd / 100) */ dd = ccdd - cc * 100; /* (ccdd % 100) */ memcpy(buf + 0, DIGIT_TABLE + aa * 2, 2); memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); memcpy(buf + 6, DIGIT_TABLE + dd * 2, 2); } static MS_INLINE void write_u32_6_digits(uint32_t x, char *buf) { uint32_t aa, bbcc, bb, cc; aa = (uint32_t)(((uint64_t)x * 109951163) >> 40); /* (x / 10000) */ bbcc = x - aa * 10000; /* (x % 10000) */ bb = (bbcc * 5243) >> 19; /* (bbcc / 100) */ cc = bbcc - bb * 100; /* (bbcc % 100) */ memcpy(buf + 0, DIGIT_TABLE + aa * 2, 2); memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); } static MS_INLINE void write_u32_4_digits(uint32_t x, char *buf) { uint32_t aa, bb; aa = (x * 5243) >> 19; /* (x / 100) */ bb = x - aa * 100; /* (x % 100) */ memcpy(buf + 0, DIGIT_TABLE + aa * 2, 2); memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); } static MS_INLINE void write_u32_2_digits(uint32_t x, char *buf) { memcpy(buf, DIGIT_TABLE + x * 2, 2); } static MS_INLINE char * write_u32_1_to_8_digits(uint32_t x, char *buf) { uint32_t aa, bb, cc, dd, aabb, bbcc, ccdd, lz; if (x < 100) { /* 1-2 digits */ lz = x < 10; memcpy(buf + 0, DIGIT_TABLE + x * 2 + lz, 2); buf -= lz; return buf + 2; } else if (x < 10000) { /* 3-4 digits */ aa = (x * 5243) >> 19; /* (x / 100) */ bb = x - aa * 100; /* (x % 100) */ lz = aa < 10; memcpy(buf + 0, DIGIT_TABLE + aa * 2 + lz, 2); buf -= lz; memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); return buf + 4; } else if (x < 1000000) { /* 5-6 digits */ aa = (uint32_t)(((uint64_t)x * 429497) >> 32); /* (x / 10000) */ bbcc = x - aa * 10000; /* (x % 10000) */ bb = (bbcc * 5243) >> 19; /* (bbcc / 100) */ cc = bbcc - bb * 100; /* (bbcc % 100) */ lz = aa < 10; memcpy(buf + 0, DIGIT_TABLE + aa * 2 + lz, 2); buf -= lz; memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); return buf + 6; } else { /* 7-8 digits */ aabb = (uint32_t)(((uint64_t)x * 109951163) >> 40); /* (x / 10000) */ ccdd = x - aabb * 10000; /* (x % 10000) */ aa = (aabb * 5243) >> 19; /* (aabb / 100) */ bb = aabb - aa * 100; /* (aabb % 100) */ cc = (ccdd * 5243) >> 19; /* (ccdd / 100) */ dd = ccdd - cc * 100; /* (ccdd % 100) */ lz = aa < 10; memcpy(buf + 0, DIGIT_TABLE + aa * 2 + lz, 2); buf -= lz; memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); memcpy(buf + 6, DIGIT_TABLE + dd * 2, 2); return buf + 8; } } static MS_INLINE char * write_u64_5_to_8_digits(uint32_t x, char *buf) { uint32_t aa, bb, cc, dd, aabb, bbcc, ccdd, lz; if (x < 1000000) { /* 5-6 digits */ aa = (uint32_t)(((uint64_t)x * 429497) >> 32); /* (x / 10000) */ bbcc = x - aa * 10000; /* (x % 10000) */ bb = (bbcc * 5243) >> 19; /* (bbcc / 100) */ cc = bbcc - bb * 100; /* (bbcc % 100) */ lz = aa < 10; memcpy(buf + 0, DIGIT_TABLE + aa * 2 + lz, 2); buf -= lz; memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); return buf + 6; } else { /* 7-8 digits */ aabb = (uint32_t)(((uint64_t)x * 109951163) >> 40); /* (x / 10000) */ ccdd = x - aabb * 10000; /* (x % 10000) */ aa = (aabb * 5243) >> 19; /* (aabb / 100) */ bb = aabb - aa * 100; /* (aabb % 100) */ cc = (ccdd * 5243) >> 19; /* (ccdd / 100) */ dd = ccdd - cc * 100; /* (ccdd % 100) */ lz = aa < 10; memcpy(buf + 0, DIGIT_TABLE + aa * 2 + lz, 2); buf -= lz; memcpy(buf + 2, DIGIT_TABLE + bb * 2, 2); memcpy(buf + 4, DIGIT_TABLE + cc * 2, 2); memcpy(buf + 6, DIGIT_TABLE + dd * 2, 2); return buf + 8; } } /* Write a uint64 to buf, requires 20 bytes of space */ static inline char * write_u64(uint64_t x, char *buf) { uint64_t tmp, hgh; uint32_t mid, low; if (x < 100000000) { /* 1-8 digits */ return write_u32_1_to_8_digits((uint32_t)x, buf); } else if (x < (uint64_t)100000000 * 100000000) { /* 9-16 digits */ hgh = x / 100000000; /* (x / 100000000) */ low = (uint32_t)(x - hgh * 100000000); /* (x % 100000000) */ char *cur = write_u32_1_to_8_digits((uint32_t)hgh, buf); write_u32_8_digits(low, cur); return cur + 8; } else { /* 17-20 digits */ tmp = x / 100000000; /* (x / 100000000) */ low = (uint32_t)(x - tmp * 100000000); /* (x % 100000000) */ hgh = (uint32_t)(tmp / 10000); /* (tmp / 10000) */ mid = (uint32_t)(tmp - hgh * 10000); /* (tmp % 10000) */ char *cur = write_u64_5_to_8_digits((uint32_t)hgh, buf); write_u32_4_digits(mid, cur); write_u32_8_digits(low, cur + 4); return cur + 12; } } #endif // MS_ITOA_H python-msgspec-0.19.0/msgspec/json.py000066400000000000000000000003241473355726200175620ustar00rootroot00000000000000from ._core import ( JSONDecoder as Decoder, JSONEncoder as Encoder, json_decode as decode, json_encode as encode, json_format as format, ) from ._json_schema import schema, schema_components python-msgspec-0.19.0/msgspec/json.pyi000066400000000000000000000060121473355726200177330ustar00rootroot00000000000000from collections.abc import Iterable from typing import ( Any, Callable, Dict, Generic, Iterable, Literal, Optional, Tuple, Type, TypeVar, Union, overload, ) from typing_extensions import Buffer T = TypeVar("T") enc_hook_sig = Optional[Callable[[Any], Any]] dec_hook_sig = Optional[Callable[[type, Any], Any]] float_hook_sig = Optional[Callable[[str], Any]] schema_hook_sig = Optional[Callable[[type], dict[str, Any]]] class Encoder: enc_hook: enc_hook_sig decimal_format: Literal["string", "number"] uuid_format: Literal["canonical", "hex"] order: Literal[None, "deterministic", "sorted"] def __init__( self, *, enc_hook: enc_hook_sig = None, decimal_format: Literal["string", "number"] = "string", uuid_format: Literal["canonical", "hex"] = "canonical", order: Literal[None, "deterministic", "sorted"] = None, ): ... def encode(self, obj: Any, /) -> bytes: ... def encode_lines(self, items: Iterable, /) -> bytes: ... def encode_into( self, obj: Any, buffer: bytearray, offset: Optional[int] = 0, / ) -> None: ... class Decoder(Generic[T]): type: Type[T] strict: bool dec_hook: dec_hook_sig float_hook: float_hook_sig @overload def __init__( self: Decoder[Any], *, strict: bool = True, dec_hook: dec_hook_sig = None, float_hook: float_hook_sig = None, ) -> None: ... @overload def __init__( self: Decoder[T], type: Type[T] = ..., *, strict: bool = True, dec_hook: dec_hook_sig = None, float_hook: float_hook_sig = None, ) -> None: ... @overload def __init__( self: Decoder[Any], type: Any = ..., *, strict: bool = True, dec_hook: dec_hook_sig = None, float_hook: float_hook_sig = None, ) -> None: ... def decode(self, buf: Union[Buffer, str], /) -> T: ... def decode_lines(self, buf: Union[Buffer, str], /) -> list[T]: ... @overload def decode( buf: Union[Buffer, str], /, *, strict: bool = True, dec_hook: dec_hook_sig = None, ) -> Any: ... @overload def decode( buf: Union[Buffer, str], /, *, type: Type[T] = ..., strict: bool = True, dec_hook: dec_hook_sig = None, ) -> T: ... @overload def decode( buf: Union[Buffer, str], /, *, type: Any = ..., strict: bool = True, dec_hook: dec_hook_sig = None, ) -> Any: ... def encode(obj: Any, /, *, enc_hook: enc_hook_sig = None, order: Literal[None, "deterministic", "sorted"] = None) -> bytes: ... def schema(type: Any, *, schema_hook: schema_hook_sig = None) -> Dict[str, Any]: ... def schema_components( types: Iterable[Any], *, schema_hook: schema_hook_sig = None, ref_template: str = "#/$defs/{name}" ) -> Tuple[Tuple[Dict[str, Any], ...], Dict[str, Any]]: ... @overload def format(buf: str, /, *, indent: int = 2) -> str: ... @overload def format(buf: Buffer, /, *, indent: int = 2) -> bytes: ... python-msgspec-0.19.0/msgspec/msgpack.py000066400000000000000000000002321473355726200202340ustar00rootroot00000000000000from ._core import ( Ext, MsgpackDecoder as Decoder, MsgpackEncoder as Encoder, msgpack_decode as decode, msgpack_encode as encode, ) python-msgspec-0.19.0/msgspec/msgpack.pyi000066400000000000000000000051211473355726200204070ustar00rootroot00000000000000from typing import ( Any, Callable, Generic, Literal, Optional, Type, TypeVar, Union, overload, ) from typing_extensions import Buffer T = TypeVar("T") enc_hook_sig = Optional[Callable[[Any], Any]] ext_hook_sig = Optional[Callable[[int, memoryview], Any]] dec_hook_sig = Optional[Callable[[type, Any], Any]] class Ext: code: int data: Union[bytes, bytearray, memoryview] def __init__( self, code: int, data: Union[bytes, bytearray, memoryview] ) -> None: ... class Decoder(Generic[T]): type: Type[T] strict: bool dec_hook: dec_hook_sig ext_hook: ext_hook_sig @overload def __init__( self: Decoder[Any], *, strict: bool = True, dec_hook: dec_hook_sig = None, ext_hook: ext_hook_sig = None, ) -> None: ... @overload def __init__( self: Decoder[T], type: Type[T] = ..., *, strict: bool = True, dec_hook: dec_hook_sig = None, ext_hook: ext_hook_sig = None, ) -> None: ... @overload def __init__( self: Decoder[Any], type: Any = ..., *, strict: bool = True, dec_hook: dec_hook_sig = None, ext_hook: ext_hook_sig = None, ) -> None: ... def decode(self, buf: Buffer, /) -> T: ... class Encoder: enc_hook: enc_hook_sig decimal_format: Literal["string", "number"] uuid_format: Literal["canonical", "hex", "bytes"] order: Literal[None, "deterministic", "sorted"] def __init__( self, *, enc_hook: enc_hook_sig = None, decimal_format: Literal["string", "number"] = "string", uuid_format: Literal["canonical", "hex", "bytes"] = "canonical", order: Literal[None, "deterministic", "sorted"] = None, ): ... def encode(self, obj: Any, /) -> bytes: ... def encode_into( self, obj: Any, buffer: bytearray, offset: Optional[int] = 0, / ) -> None: ... @overload def decode( buf: Buffer, /, *, strict: bool = True, dec_hook: dec_hook_sig = None, ext_hook: ext_hook_sig = None, ) -> Any: ... @overload def decode( buf: Buffer, /, *, type: Type[T] = ..., strict: bool = True, dec_hook: dec_hook_sig = None, ext_hook: ext_hook_sig = None, ) -> T: ... @overload def decode( buf: Buffer, /, *, type: Any = ..., strict: bool = True, dec_hook: dec_hook_sig = None, ext_hook: ext_hook_sig = None, ) -> Any: ... def encode(obj: Any, /, *, enc_hook: enc_hook_sig = None, order: Literal[None, "deterministic", "sorted"] = None) -> bytes: ... python-msgspec-0.19.0/msgspec/py.typed000066400000000000000000000000001473355726200177250ustar00rootroot00000000000000python-msgspec-0.19.0/msgspec/ryu.h000066400000000000000000001566541473355726200172510ustar00rootroot00000000000000/* This code is a modified and condensed version of the ryu library, found at * https://github.com/ulfjack/ryu. The formatting routine also mirrors some * ideas taken from https://github.com/dtolnay/ryu, which was direct rust * translation of the above (and has the same license as the above). That * license is copied below. * * Copyright 2018 Ulf Adams * * The contents of this file may be used under the terms of the Apache License, * Version 2.0. * * (See accompanying file LICENSE-Apache or copy at * http://www.apache.org/licenses/LICENSE-2.0) * * Alternatively, the contents of this file may be used under the terms of * the Boost Software License, Version 1.0. * (See accompanying file LICENSE-Boost or copy at * https://www.boost.org/LICENSE_1_0.txt) * * Unless required by applicable law or agreed to in writing, this software * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. */ #ifndef RYU_H #define RYU_H #include #include #include #include #include #include "common.h" #include "itoa.h" #define DOUBLE_MANTISSA_BITS 52 #define DOUBLE_EXPONENT_BITS 11 #define DOUBLE_BIAS 1023 #define DOUBLE_POW5_INV_BITCOUNT 125 #define DOUBLE_POW5_BITCOUNT 125 #define DOUBLE_POW5_INV_TABLE_SIZE 342 #define DOUBLE_POW5_TABLE_SIZE 326 static const uint64_t DOUBLE_POW5_INV_SPLIT[DOUBLE_POW5_INV_TABLE_SIZE][2] = { { 1u, 2305843009213693952u }, { 11068046444225730970u, 1844674407370955161u }, { 5165088340638674453u, 1475739525896764129u }, { 7821419487252849886u, 1180591620717411303u }, { 8824922364862649494u, 1888946593147858085u }, { 7059937891890119595u, 1511157274518286468u }, { 13026647942995916322u, 1208925819614629174u }, { 9774590264567735146u, 1934281311383406679u }, { 11509021026396098440u, 1547425049106725343u }, { 16585914450600699399u, 1237940039285380274u }, { 15469416676735388068u, 1980704062856608439u }, { 16064882156130220778u, 1584563250285286751u }, { 9162556910162266299u, 1267650600228229401u }, { 7281393426775805432u, 2028240960365167042u }, { 16893161185646375315u, 1622592768292133633u }, { 2446482504291369283u, 1298074214633706907u }, { 7603720821608101175u, 2076918743413931051u }, { 2393627842544570617u, 1661534994731144841u }, { 16672297533003297786u, 1329227995784915872u }, { 11918280793837635165u, 2126764793255865396u }, { 5845275820328197809u, 1701411834604692317u }, { 15744267100488289217u, 1361129467683753853u }, { 3054734472329800808u, 2177807148294006166u }, { 17201182836831481939u, 1742245718635204932u }, { 6382248639981364905u, 1393796574908163946u }, { 2832900194486363201u, 2230074519853062314u }, { 5955668970331000884u, 1784059615882449851u }, { 1075186361522890384u, 1427247692705959881u }, { 12788344622662355584u, 2283596308329535809u }, { 13920024512871794791u, 1826877046663628647u }, { 3757321980813615186u, 1461501637330902918u }, { 10384555214134712795u, 1169201309864722334u }, { 5547241898389809503u, 1870722095783555735u }, { 4437793518711847602u, 1496577676626844588u }, { 10928932444453298728u, 1197262141301475670u }, { 17486291911125277965u, 1915619426082361072u }, { 6610335899416401726u, 1532495540865888858u }, { 12666966349016942027u, 1225996432692711086u }, { 12888448528943286597u, 1961594292308337738u }, { 17689456452638449924u, 1569275433846670190u }, { 14151565162110759939u, 1255420347077336152u }, { 7885109000409574610u, 2008672555323737844u }, { 9997436015069570011u, 1606938044258990275u }, { 7997948812055656009u, 1285550435407192220u }, { 12796718099289049614u, 2056880696651507552u }, { 2858676849947419045u, 1645504557321206042u }, { 13354987924183666206u, 1316403645856964833u }, { 17678631863951955605u, 2106245833371143733u }, { 3074859046935833515u, 1684996666696914987u }, { 13527933681774397782u, 1347997333357531989u }, { 10576647446613305481u, 2156795733372051183u }, { 15840015586774465031u, 1725436586697640946u }, { 8982663654677661702u, 1380349269358112757u }, { 18061610662226169046u, 2208558830972980411u }, { 10759939715039024913u, 1766847064778384329u }, { 12297300586773130254u, 1413477651822707463u }, { 15986332124095098083u, 2261564242916331941u }, { 9099716884534168143u, 1809251394333065553u }, { 14658471137111155161u, 1447401115466452442u }, { 4348079280205103483u, 1157920892373161954u }, { 14335624477811986218u, 1852673427797059126u }, { 7779150767507678651u, 1482138742237647301u }, { 2533971799264232598u, 1185710993790117841u }, { 15122401323048503126u, 1897137590064188545u }, { 12097921058438802501u, 1517710072051350836u }, { 5988988032009131678u, 1214168057641080669u }, { 16961078480698431330u, 1942668892225729070u }, { 13568862784558745064u, 1554135113780583256u }, { 7165741412905085728u, 1243308091024466605u }, { 11465186260648137165u, 1989292945639146568u }, { 16550846638002330379u, 1591434356511317254u }, { 16930026125143774626u, 1273147485209053803u }, { 4951948911778577463u, 2037035976334486086u }, { 272210314680951647u, 1629628781067588869u }, { 3907117066486671641u, 1303703024854071095u }, { 6251387306378674625u, 2085924839766513752u }, { 16069156289328670670u, 1668739871813211001u }, { 9165976216721026213u, 1334991897450568801u }, { 7286864317269821294u, 2135987035920910082u }, { 16897537898041588005u, 1708789628736728065u }, { 13518030318433270404u, 1367031702989382452u }, { 6871453250525591353u, 2187250724783011924u }, { 9186511415162383406u, 1749800579826409539u }, { 11038557946871817048u, 1399840463861127631u }, { 10282995085511086630u, 2239744742177804210u }, { 8226396068408869304u, 1791795793742243368u }, { 13959814484210916090u, 1433436634993794694u }, { 11267656730511734774u, 2293498615990071511u }, { 5324776569667477496u, 1834798892792057209u }, { 7949170070475892320u, 1467839114233645767u }, { 17427382500606444826u, 1174271291386916613u }, { 5747719112518849781u, 1878834066219066582u }, { 15666221734240810795u, 1503067252975253265u }, { 12532977387392648636u, 1202453802380202612u }, { 5295368560860596524u, 1923926083808324180u }, { 4236294848688477220u, 1539140867046659344u }, { 7078384693692692099u, 1231312693637327475u }, { 11325415509908307358u, 1970100309819723960u }, { 9060332407926645887u, 1576080247855779168u }, { 14626963555825137356u, 1260864198284623334u }, { 12335095245094488799u, 2017382717255397335u }, { 9868076196075591040u, 1613906173804317868u }, { 15273158586344293478u, 1291124939043454294u }, { 13369007293925138595u, 2065799902469526871u }, { 7005857020398200553u, 1652639921975621497u }, { 16672732060544291412u, 1322111937580497197u }, { 11918976037903224966u, 2115379100128795516u }, { 5845832015580669650u, 1692303280103036413u }, { 12055363241948356366u, 1353842624082429130u }, { 841837113407818570u, 2166148198531886609u }, { 4362818505468165179u, 1732918558825509287u }, { 14558301248600263113u, 1386334847060407429u }, { 12225235553534690011u, 2218135755296651887u }, { 2401490813343931363u, 1774508604237321510u }, { 1921192650675145090u, 1419606883389857208u }, { 17831303500047873437u, 2271371013423771532u }, { 6886345170554478103u, 1817096810739017226u }, { 1819727321701672159u, 1453677448591213781u }, { 16213177116328979020u, 1162941958872971024u }, { 14873036941900635463u, 1860707134196753639u }, { 15587778368262418694u, 1488565707357402911u }, { 8780873879868024632u, 1190852565885922329u }, { 2981351763563108441u, 1905364105417475727u }, { 13453127855076217722u, 1524291284333980581u }, { 7073153469319063855u, 1219433027467184465u }, { 11317045550910502167u, 1951092843947495144u }, { 12742985255470312057u, 1560874275157996115u }, { 10194388204376249646u, 1248699420126396892u }, { 1553625868034358140u, 1997919072202235028u }, { 8621598323911307159u, 1598335257761788022u }, { 17965325103354776697u, 1278668206209430417u }, { 13987124906400001422u, 2045869129935088668u }, { 121653480894270168u, 1636695303948070935u }, { 97322784715416134u, 1309356243158456748u }, { 14913111714512307107u, 2094969989053530796u }, { 8241140556867935363u, 1675975991242824637u }, { 17660958889720079260u, 1340780792994259709u }, { 17189487779326395846u, 2145249268790815535u }, { 13751590223461116677u, 1716199415032652428u }, { 18379969808252713988u, 1372959532026121942u }, { 14650556434236701088u, 2196735251241795108u }, { 652398703163629901u, 1757388200993436087u }, { 11589965406756634890u, 1405910560794748869u }, { 7475898206584884855u, 2249456897271598191u }, { 2291369750525997561u, 1799565517817278553u }, { 9211793429904618695u, 1439652414253822842u }, { 18428218302589300235u, 2303443862806116547u }, { 7363877012587619542u, 1842755090244893238u }, { 13269799239553916280u, 1474204072195914590u }, { 10615839391643133024u, 1179363257756731672u }, { 2227947767661371545u, 1886981212410770676u }, { 16539753473096738529u, 1509584969928616540u }, { 13231802778477390823u, 1207667975942893232u }, { 6413489186596184024u, 1932268761508629172u }, { 16198837793502678189u, 1545815009206903337u }, { 5580372605318321905u, 1236652007365522670u }, { 8928596168509315048u, 1978643211784836272u }, { 18210923379033183008u, 1582914569427869017u }, { 7190041073742725760u, 1266331655542295214u }, { 436019273762630246u, 2026130648867672343u }, { 7727513048493924843u, 1620904519094137874u }, { 9871359253537050198u, 1296723615275310299u }, { 4726128361433549347u, 2074757784440496479u }, { 7470251503888749801u, 1659806227552397183u }, { 13354898832594820487u, 1327844982041917746u }, { 13989140502667892133u, 2124551971267068394u }, { 14880661216876224029u, 1699641577013654715u }, { 11904528973500979224u, 1359713261610923772u }, { 4289851098633925465u, 2175541218577478036u }, { 18189276137874781665u, 1740432974861982428u }, { 3483374466074094362u, 1392346379889585943u }, { 1884050330976640656u, 2227754207823337509u }, { 5196589079523222848u, 1782203366258670007u }, { 15225317707844309248u, 1425762693006936005u }, { 5913764258841343181u, 2281220308811097609u }, { 8420360221814984868u, 1824976247048878087u }, { 17804334621677718864u, 1459980997639102469u }, { 17932816512084085415u, 1167984798111281975u }, { 10245762345624985047u, 1868775676978051161u }, { 4507261061758077715u, 1495020541582440929u }, { 7295157664148372495u, 1196016433265952743u }, { 7982903447895485668u, 1913626293225524389u }, { 10075671573058298858u, 1530901034580419511u }, { 4371188443704728763u, 1224720827664335609u }, { 14372599139411386667u, 1959553324262936974u }, { 15187428126271019657u, 1567642659410349579u }, { 15839291315758726049u, 1254114127528279663u }, { 3206773216762499739u, 2006582604045247462u }, { 13633465017635730761u, 1605266083236197969u }, { 14596120828850494932u, 1284212866588958375u }, { 4907049252451240275u, 2054740586542333401u }, { 236290587219081897u, 1643792469233866721u }, { 14946427728742906810u, 1315033975387093376u }, { 16535586736504830250u, 2104054360619349402u }, { 5849771759720043554u, 1683243488495479522u }, { 15747863852001765813u, 1346594790796383617u }, { 10439186904235184007u, 2154551665274213788u }, { 15730047152871967852u, 1723641332219371030u }, { 12584037722297574282u, 1378913065775496824u }, { 9066413911450387881u, 2206260905240794919u }, { 10942479943902220628u, 1765008724192635935u }, { 8753983955121776503u, 1412006979354108748u }, { 10317025513452932081u, 2259211166966573997u }, { 874922781278525018u, 1807368933573259198u }, { 8078635854506640661u, 1445895146858607358u }, { 13841606313089133175u, 1156716117486885886u }, { 14767872471458792434u, 1850745787979017418u }, { 746251532941302978u, 1480596630383213935u }, { 597001226353042382u, 1184477304306571148u }, { 15712597221132509104u, 1895163686890513836u }, { 8880728962164096960u, 1516130949512411069u }, { 10793931984473187891u, 1212904759609928855u }, { 17270291175157100626u, 1940647615375886168u }, { 2748186495899949531u, 1552518092300708935u }, { 2198549196719959625u, 1242014473840567148u }, { 18275073973719576693u, 1987223158144907436u }, { 10930710364233751031u, 1589778526515925949u }, { 12433917106128911148u, 1271822821212740759u }, { 8826220925580526867u, 2034916513940385215u }, { 7060976740464421494u, 1627933211152308172u }, { 16716827836597268165u, 1302346568921846537u }, { 11989529279587987770u, 2083754510274954460u }, { 9591623423670390216u, 1667003608219963568u }, { 15051996368420132820u, 1333602886575970854u }, { 13015147745246481542u, 2133764618521553367u }, { 3033420566713364587u, 1707011694817242694u }, { 6116085268112601993u, 1365609355853794155u }, { 9785736428980163188u, 2184974969366070648u }, { 15207286772667951197u, 1747979975492856518u }, { 1097782973908629988u, 1398383980394285215u }, { 1756452758253807981u, 2237414368630856344u }, { 5094511021344956708u, 1789931494904685075u }, { 4075608817075965366u, 1431945195923748060u }, { 6520974107321544586u, 2291112313477996896u }, { 1527430471115325346u, 1832889850782397517u }, { 12289990821117991246u, 1466311880625918013u }, { 17210690286378213644u, 1173049504500734410u }, { 9090360384495590213u, 1876879207201175057u }, { 18340334751822203140u, 1501503365760940045u }, { 14672267801457762512u, 1201202692608752036u }, { 16096930852848599373u, 1921924308174003258u }, { 1809498238053148529u, 1537539446539202607u }, { 12515645034668249793u, 1230031557231362085u }, { 1578287981759648052u, 1968050491570179337u }, { 12330676829633449412u, 1574440393256143469u }, { 13553890278448669853u, 1259552314604914775u }, { 3239480371808320148u, 2015283703367863641u }, { 17348979556414297411u, 1612226962694290912u }, { 6500486015647617283u, 1289781570155432730u }, { 10400777625036187652u, 2063650512248692368u }, { 15699319729512770768u, 1650920409798953894u }, { 16248804598352126938u, 1320736327839163115u }, { 7551343283653851484u, 2113178124542660985u }, { 6041074626923081187u, 1690542499634128788u }, { 12211557331022285596u, 1352433999707303030u }, { 1091747655926105338u, 2163894399531684849u }, { 4562746939482794594u, 1731115519625347879u }, { 7339546366328145998u, 1384892415700278303u }, { 8053925371383123274u, 2215827865120445285u }, { 6443140297106498619u, 1772662292096356228u }, { 12533209867169019542u, 1418129833677084982u }, { 5295740528502789974u, 2269007733883335972u }, { 15304638867027962949u, 1815206187106668777u }, { 4865013464138549713u, 1452164949685335022u }, { 14960057215536570740u, 1161731959748268017u }, { 9178696285890871890u, 1858771135597228828u }, { 14721654658196518159u, 1487016908477783062u }, { 4398626097073393881u, 1189613526782226450u }, { 7037801755317430209u, 1903381642851562320u }, { 5630241404253944167u, 1522705314281249856u }, { 814844308661245011u, 1218164251424999885u }, { 1303750893857992017u, 1949062802279999816u }, { 15800395974054034906u, 1559250241823999852u }, { 5261619149759407279u, 1247400193459199882u }, { 12107939454356961969u, 1995840309534719811u }, { 5997002748743659252u, 1596672247627775849u }, { 8486951013736837725u, 1277337798102220679u }, { 2511075177753209390u, 2043740476963553087u }, { 13076906586428298482u, 1634992381570842469u }, { 14150874083884549109u, 1307993905256673975u }, { 4194654460505726958u, 2092790248410678361u }, { 18113118827372222859u, 1674232198728542688u }, { 3422448617672047318u, 1339385758982834151u }, { 16543964232501006678u, 2143017214372534641u }, { 9545822571258895019u, 1714413771498027713u }, { 15015355686490936662u, 1371531017198422170u }, { 5577825024675947042u, 2194449627517475473u }, { 11840957649224578280u, 1755559702013980378u }, { 16851463748863483271u, 1404447761611184302u }, { 12204946739213931940u, 2247116418577894884u }, { 13453306206113055875u, 1797693134862315907u }, { 3383947335406624054u, 1438154507889852726u }, { 16482362180876329456u, 2301047212623764361u }, { 9496540929959153242u, 1840837770099011489u }, { 11286581558709232917u, 1472670216079209191u }, { 5339916432225476010u, 1178136172863367353u }, { 4854517476818851293u, 1885017876581387765u }, { 3883613981455081034u, 1508014301265110212u }, { 14174937629389795797u, 1206411441012088169u }, { 11611853762797942306u, 1930258305619341071u }, { 5600134195496443521u, 1544206644495472857u }, { 15548153800622885787u, 1235365315596378285u }, { 6430302007287065643u, 1976584504954205257u }, { 16212288050055383484u, 1581267603963364205u }, { 12969830440044306787u, 1265014083170691364u }, { 9683682259845159889u, 2024022533073106183u }, { 15125643437359948558u, 1619218026458484946u }, { 8411165935146048523u, 1295374421166787957u }, { 17147214310975587960u, 2072599073866860731u }, { 10028422634038560045u, 1658079259093488585u }, { 8022738107230848036u, 1326463407274790868u }, { 9147032156827446534u, 2122341451639665389u }, { 11006974540203867551u, 1697873161311732311u }, { 5116230817421183718u, 1358298529049385849u }, { 15564666937357714594u, 2173277646479017358u }, { 1383687105660440706u, 1738622117183213887u }, { 12174996128754083534u, 1390897693746571109u }, { 8411947361780802685u, 2225436309994513775u }, { 6729557889424642148u, 1780349047995611020u }, { 5383646311539713719u, 1424279238396488816u }, { 1235136468979721303u, 2278846781434382106u }, { 15745504434151418335u, 1823077425147505684u }, { 16285752362063044992u, 1458461940118004547u }, { 5649904260166615347u, 1166769552094403638u }, { 5350498001524674232u, 1866831283351045821u }, { 591049586477829062u, 1493465026680836657u }, { 11540886113407994219u, 1194772021344669325u }, { 18673707743239135u, 1911635234151470921u }, { 14772334225162232601u, 1529308187321176736u }, { 8128518565387875758u, 1223446549856941389u }, { 1937583260394870242u, 1957514479771106223u }, { 8928764237799716840u, 1566011583816884978u }, { 14521709019723594119u, 1252809267053507982u }, { 8477339172590109297u, 2004494827285612772u }, { 17849917782297818407u, 1603595861828490217u }, { 6901236596354434079u, 1282876689462792174u }, { 18420676183650915173u, 2052602703140467478u }, { 3668494502695001169u, 1642082162512373983u }, { 10313493231639821582u, 1313665730009899186u }, { 9122891541139893884u, 2101865168015838698u }, { 14677010862395735754u, 1681492134412670958u }, { 673562245690857633u, 1345193707530136767u } }; static const uint64_t DOUBLE_POW5_SPLIT[DOUBLE_POW5_TABLE_SIZE][2] = { { 0u, 1152921504606846976u }, { 0u, 1441151880758558720u }, { 0u, 1801439850948198400u }, { 0u, 2251799813685248000u }, { 0u, 1407374883553280000u }, { 0u, 1759218604441600000u }, { 0u, 2199023255552000000u }, { 0u, 1374389534720000000u }, { 0u, 1717986918400000000u }, { 0u, 2147483648000000000u }, { 0u, 1342177280000000000u }, { 0u, 1677721600000000000u }, { 0u, 2097152000000000000u }, { 0u, 1310720000000000000u }, { 0u, 1638400000000000000u }, { 0u, 2048000000000000000u }, { 0u, 1280000000000000000u }, { 0u, 1600000000000000000u }, { 0u, 2000000000000000000u }, { 0u, 1250000000000000000u }, { 0u, 1562500000000000000u }, { 0u, 1953125000000000000u }, { 0u, 1220703125000000000u }, { 0u, 1525878906250000000u }, { 0u, 1907348632812500000u }, { 0u, 1192092895507812500u }, { 0u, 1490116119384765625u }, { 4611686018427387904u, 1862645149230957031u }, { 9799832789158199296u, 1164153218269348144u }, { 12249790986447749120u, 1455191522836685180u }, { 15312238733059686400u, 1818989403545856475u }, { 14528612397897220096u, 2273736754432320594u }, { 13692068767113150464u, 1421085471520200371u }, { 12503399940464050176u, 1776356839400250464u }, { 15629249925580062720u, 2220446049250313080u }, { 9768281203487539200u, 1387778780781445675u }, { 7598665485932036096u, 1734723475976807094u }, { 274959820560269312u, 2168404344971008868u }, { 9395221924704944128u, 1355252715606880542u }, { 2520655369026404352u, 1694065894508600678u }, { 12374191248137781248u, 2117582368135750847u }, { 14651398557727195136u, 1323488980084844279u }, { 13702562178731606016u, 1654361225106055349u }, { 3293144668132343808u, 2067951531382569187u }, { 18199116482078572544u, 1292469707114105741u }, { 8913837547316051968u, 1615587133892632177u }, { 15753982952572452864u, 2019483917365790221u }, { 12152082354571476992u, 1262177448353618888u }, { 15190102943214346240u, 1577721810442023610u }, { 9764256642163156992u, 1972152263052529513u }, { 17631875447420442880u, 1232595164407830945u }, { 8204786253993389888u, 1540743955509788682u }, { 1032610780636961552u, 1925929944387235853u }, { 2951224747111794922u, 1203706215242022408u }, { 3689030933889743652u, 1504632769052528010u }, { 13834660704216955373u, 1880790961315660012u }, { 17870034976990372916u, 1175494350822287507u }, { 17725857702810578241u, 1469367938527859384u }, { 3710578054803671186u, 1836709923159824231u }, { 26536550077201078u, 2295887403949780289u }, { 11545800389866720434u, 1434929627468612680u }, { 14432250487333400542u, 1793662034335765850u }, { 8816941072311974870u, 2242077542919707313u }, { 17039803216263454053u, 1401298464324817070u }, { 12076381983474541759u, 1751623080406021338u }, { 5872105442488401391u, 2189528850507526673u }, { 15199280947623720629u, 1368455531567204170u }, { 9775729147674874978u, 1710569414459005213u }, { 16831347453020981627u, 2138211768073756516u }, { 1296220121283337709u, 1336382355046097823u }, { 15455333206886335848u, 1670477943807622278u }, { 10095794471753144002u, 2088097429759527848u }, { 6309871544845715001u, 1305060893599704905u }, { 12499025449484531656u, 1631326116999631131u }, { 11012095793428276666u, 2039157646249538914u }, { 11494245889320060820u, 1274473528905961821u }, { 532749306367912313u, 1593091911132452277u }, { 5277622651387278295u, 1991364888915565346u }, { 7910200175544436838u, 1244603055572228341u }, { 14499436237857933952u, 1555753819465285426u }, { 8900923260467641632u, 1944692274331606783u }, { 12480606065433357876u, 1215432671457254239u }, { 10989071563364309441u, 1519290839321567799u }, { 9124653435777998898u, 1899113549151959749u }, { 8008751406574943263u, 1186945968219974843u }, { 5399253239791291175u, 1483682460274968554u }, { 15972438586593889776u, 1854603075343710692u }, { 759402079766405302u, 1159126922089819183u }, { 14784310654990170340u, 1448908652612273978u }, { 9257016281882937117u, 1811135815765342473u }, { 16182956370781059300u, 2263919769706678091u }, { 7808504722524468110u, 1414949856066673807u }, { 5148944884728197234u, 1768687320083342259u }, { 1824495087482858639u, 2210859150104177824u }, { 1140309429676786649u, 1381786968815111140u }, { 1425386787095983311u, 1727233711018888925u }, { 6393419502297367043u, 2159042138773611156u }, { 13219259225790630210u, 1349401336733506972u }, { 16524074032238287762u, 1686751670916883715u }, { 16043406521870471799u, 2108439588646104644u }, { 803757039314269066u, 1317774742903815403u }, { 14839754354425000045u, 1647218428629769253u }, { 4714634887749086344u, 2059023035787211567u }, { 9864175832484260821u, 1286889397367007229u }, { 16941905809032713930u, 1608611746708759036u }, { 2730638187581340797u, 2010764683385948796u }, { 10930020904093113806u, 1256727927116217997u }, { 18274212148543780162u, 1570909908895272496u }, { 4396021111970173586u, 1963637386119090621u }, { 5053356204195052443u, 1227273366324431638u }, { 15540067292098591362u, 1534091707905539547u }, { 14813398096695851299u, 1917614634881924434u }, { 13870059828862294966u, 1198509146801202771u }, { 12725888767650480803u, 1498136433501503464u }, { 15907360959563101004u, 1872670541876879330u }, { 14553786618154326031u, 1170419088673049581u }, { 4357175217410743827u, 1463023860841311977u }, { 10058155040190817688u, 1828779826051639971u }, { 7961007781811134206u, 2285974782564549964u }, { 14199001900486734687u, 1428734239102843727u }, { 13137066357181030455u, 1785917798878554659u }, { 11809646928048900164u, 2232397248598193324u }, { 16604401366885338411u, 1395248280373870827u }, { 16143815690179285109u, 1744060350467338534u }, { 10956397575869330579u, 2180075438084173168u }, { 6847748484918331612u, 1362547148802608230u }, { 17783057643002690323u, 1703183936003260287u }, { 17617136035325974999u, 2128979920004075359u }, { 17928239049719816230u, 1330612450002547099u }, { 17798612793722382384u, 1663265562503183874u }, { 13024893955298202172u, 2079081953128979843u }, { 5834715712847682405u, 1299426220705612402u }, { 16516766677914378815u, 1624282775882015502u }, { 11422586310538197711u, 2030353469852519378u }, { 11750802462513761473u, 1268970918657824611u }, { 10076817059714813937u, 1586213648322280764u }, { 12596021324643517422u, 1982767060402850955u }, { 5566670318688504437u, 1239229412751781847u }, { 2346651879933242642u, 1549036765939727309u }, { 7545000868343941206u, 1936295957424659136u }, { 4715625542714963254u, 1210184973390411960u }, { 5894531928393704067u, 1512731216738014950u }, { 16591536947346905892u, 1890914020922518687u }, { 17287239619732898039u, 1181821263076574179u }, { 16997363506238734644u, 1477276578845717724u }, { 2799960309088866689u, 1846595723557147156u }, { 10973347230035317489u, 1154122327223216972u }, { 13716684037544146861u, 1442652909029021215u }, { 12534169028502795672u, 1803316136286276519u }, { 11056025267201106687u, 2254145170357845649u }, { 18439230838069161439u, 1408840731473653530u }, { 13825666510731675991u, 1761050914342066913u }, { 3447025083132431277u, 2201313642927583642u }, { 6766076695385157452u, 1375821026829739776u }, { 8457595869231446815u, 1719776283537174720u }, { 10571994836539308519u, 2149720354421468400u }, { 6607496772837067824u, 1343575221513417750u }, { 17482743002901110588u, 1679469026891772187u }, { 17241742735199000331u, 2099336283614715234u }, { 15387775227926763111u, 1312085177259197021u }, { 5399660979626290177u, 1640106471573996277u }, { 11361262242960250625u, 2050133089467495346u }, { 11712474920277544544u, 1281333180917184591u }, { 10028907631919542777u, 1601666476146480739u }, { 7924448521472040567u, 2002083095183100924u }, { 14176152362774801162u, 1251301934489438077u }, { 3885132398186337741u, 1564127418111797597u }, { 9468101516160310080u, 1955159272639746996u }, { 15140935484454969608u, 1221974545399841872u }, { 479425281859160394u, 1527468181749802341u }, { 5210967620751338397u, 1909335227187252926u }, { 17091912818251750210u, 1193334516992033078u }, { 12141518985959911954u, 1491668146240041348u }, { 15176898732449889943u, 1864585182800051685u }, { 11791404716994875166u, 1165365739250032303u }, { 10127569877816206054u, 1456707174062540379u }, { 8047776328842869663u, 1820883967578175474u }, { 836348374198811271u, 2276104959472719343u }, { 7440246761515338900u, 1422565599670449589u }, { 13911994470321561530u, 1778206999588061986u }, { 8166621051047176104u, 2222758749485077483u }, { 2798295147690791113u, 1389224218428173427u }, { 17332926989895652603u, 1736530273035216783u }, { 17054472718942177850u, 2170662841294020979u }, { 8353202440125167204u, 1356664275808763112u }, { 10441503050156459005u, 1695830344760953890u }, { 3828506775840797949u, 2119787930951192363u }, { 86973725686804766u, 1324867456844495227u }, { 13943775212390669669u, 1656084321055619033u }, { 3594660960206173375u, 2070105401319523792u }, { 2246663100128858359u, 1293815875824702370u }, { 12031700912015848757u, 1617269844780877962u }, { 5816254103165035138u, 2021587305976097453u }, { 5941001823691840913u, 1263492066235060908u }, { 7426252279614801142u, 1579365082793826135u }, { 4671129331091113523u, 1974206353492282669u }, { 5225298841145639904u, 1233878970932676668u }, { 6531623551432049880u, 1542348713665845835u }, { 3552843420862674446u, 1927935892082307294u }, { 16055585193321335241u, 1204959932551442058u }, { 10846109454796893243u, 1506199915689302573u }, { 18169322836923504458u, 1882749894611628216u }, { 11355826773077190286u, 1176718684132267635u }, { 9583097447919099954u, 1470898355165334544u }, { 11978871809898874942u, 1838622943956668180u }, { 14973589762373593678u, 2298278679945835225u }, { 2440964573842414192u, 1436424174966147016u }, { 3051205717303017741u, 1795530218707683770u }, { 13037379183483547984u, 2244412773384604712u }, { 8148361989677217490u, 1402757983365377945u }, { 14797138505523909766u, 1753447479206722431u }, { 13884737113477499304u, 2191809349008403039u }, { 15595489723564518921u, 1369880843130251899u }, { 14882676136028260747u, 1712351053912814874u }, { 9379973133180550126u, 2140438817391018593u }, { 17391698254306313589u, 1337774260869386620u }, { 3292878744173340370u, 1672217826086733276u }, { 4116098430216675462u, 2090272282608416595u }, { 266718509671728212u, 1306420176630260372u }, { 333398137089660265u, 1633025220787825465u }, { 5028433689789463235u, 2041281525984781831u }, { 10060300083759496378u, 1275800953740488644u }, { 12575375104699370472u, 1594751192175610805u }, { 1884160825592049379u, 1993438990219513507u }, { 17318501580490888525u, 1245899368887195941u }, { 7813068920331446945u, 1557374211108994927u }, { 5154650131986920777u, 1946717763886243659u }, { 915813323278131534u, 1216698602428902287u }, { 14979824709379828129u, 1520873253036127858u }, { 9501408849870009354u, 1901091566295159823u }, { 12855909558809837702u, 1188182228934474889u }, { 2234828893230133415u, 1485227786168093612u }, { 2793536116537666769u, 1856534732710117015u }, { 8663489100477123587u, 1160334207943823134u }, { 1605989338741628675u, 1450417759929778918u }, { 11230858710281811652u, 1813022199912223647u }, { 9426887369424876662u, 2266277749890279559u }, { 12809333633531629769u, 1416423593681424724u }, { 16011667041914537212u, 1770529492101780905u }, { 6179525747111007803u, 2213161865127226132u }, { 13085575628799155685u, 1383226165704516332u }, { 16356969535998944606u, 1729032707130645415u }, { 15834525901571292854u, 2161290883913306769u }, { 2979049660840976177u, 1350806802445816731u }, { 17558870131333383934u, 1688508503057270913u }, { 8113529608884566205u, 2110635628821588642u }, { 9682642023980241782u, 1319147268013492901u }, { 16714988548402690132u, 1648934085016866126u }, { 11670363648648586857u, 2061167606271082658u }, { 11905663298832754689u, 1288229753919426661u }, { 1047021068258779650u, 1610287192399283327u }, { 15143834390605638274u, 2012858990499104158u }, { 4853210475701136017u, 1258036869061940099u }, { 1454827076199032118u, 1572546086327425124u }, { 1818533845248790147u, 1965682607909281405u }, { 3442426662494187794u, 1228551629943300878u }, { 13526405364972510550u, 1535689537429126097u }, { 3072948650933474476u, 1919611921786407622u }, { 15755650962115585259u, 1199757451116504763u }, { 15082877684217093670u, 1499696813895630954u }, { 9630225068416591280u, 1874621017369538693u }, { 8324733676974063502u, 1171638135855961683u }, { 5794231077790191473u, 1464547669819952104u }, { 7242788847237739342u, 1830684587274940130u }, { 18276858095901949986u, 2288355734093675162u }, { 16034722328366106645u, 1430222333808546976u }, { 1596658836748081690u, 1787777917260683721u }, { 6607509564362490017u, 2234722396575854651u }, { 1823850468512862308u, 1396701497859909157u }, { 6891499104068465790u, 1745876872324886446u }, { 17837745916940358045u, 2182346090406108057u }, { 4231062170446641922u, 1363966306503817536u }, { 5288827713058302403u, 1704957883129771920u }, { 6611034641322878003u, 2131197353912214900u }, { 13355268687681574560u, 1331998346195134312u }, { 16694085859601968200u, 1664997932743917890u }, { 11644235287647684442u, 2081247415929897363u }, { 4971804045566108824u, 1300779634956185852u }, { 6214755056957636030u, 1625974543695232315u }, { 3156757802769657134u, 2032468179619040394u }, { 6584659645158423613u, 1270292612261900246u }, { 17454196593302805324u, 1587865765327375307u }, { 17206059723201118751u, 1984832206659219134u }, { 6142101308573311315u, 1240520129162011959u }, { 3065940617289251240u, 1550650161452514949u }, { 8444111790038951954u, 1938312701815643686u }, { 665883850346957067u, 1211445438634777304u }, { 832354812933696334u, 1514306798293471630u }, { 10263815553021896226u, 1892883497866839537u }, { 17944099766707154901u, 1183052186166774710u }, { 13206752671529167818u, 1478815232708468388u }, { 16508440839411459773u, 1848519040885585485u }, { 12623618533845856310u, 1155324400553490928u }, { 15779523167307320387u, 1444155500691863660u }, { 1277659885424598868u, 1805194375864829576u }, { 1597074856780748586u, 2256492969831036970u }, { 5609857803915355770u, 1410308106144398106u }, { 16235694291748970521u, 1762885132680497632u }, { 1847873790976661535u, 2203606415850622041u }, { 12684136165428883219u, 1377254009906638775u }, { 11243484188358716120u, 1721567512383298469u }, { 219297180166231438u, 2151959390479123087u }, { 7054589765244976505u, 1344974619049451929u }, { 13429923224983608535u, 1681218273811814911u }, { 12175718012802122765u, 2101522842264768639u }, { 14527352785642408584u, 1313451776415480399u }, { 13547504963625622826u, 1641814720519350499u }, { 12322695186104640628u, 2052268400649188124u }, { 16925056528170176201u, 1282667750405742577u }, { 7321262604930556539u, 1603334688007178222u }, { 18374950293017971482u, 2004168360008972777u }, { 4566814905495150320u, 1252605225005607986u }, { 14931890668723713708u, 1565756531257009982u }, { 9441491299049866327u, 1957195664071262478u }, { 1289246043478778550u, 1223247290044539049u }, { 6223243572775861092u, 1529059112555673811u }, { 3167368447542438461u, 1911323890694592264u }, { 1979605279714024038u, 1194577431684120165u }, { 7086192618069917952u, 1493221789605150206u }, { 18081112809442173248u, 1866527237006437757u }, { 13606538515115052232u, 1166579523129023598u }, { 7784801107039039482u, 1458224403911279498u }, { 507629346944023544u, 1822780504889099373u }, { 5246222702107417334u, 2278475631111374216u }, { 3278889188817135834u, 1424047269444608885u }, { 8710297504448807696u, 1780059086805761106u } }; #if defined(_M_IX86) || defined(_M_ARM) #define RYU_32_BIT_PLATFORM #endif #if defined(__SIZEOF_INT128__) && !defined(_MSC_VER) && !defined(RYU_ONLY_64_BIT_OPS) #define HAS_UINT128 #elif defined(_MSC_VER) && !defined(RYU_ONLY_64_BIT_OPS) && defined(_M_X64) #define HAS_64_BIT_INTRINSICS #endif #if defined(HAS_UINT128) typedef __uint128_t uint128_t; #endif #if defined(HAS_64_BIT_INTRINSICS) #include static inline uint64_t umul128(const uint64_t a, const uint64_t b, uint64_t* const productHi) { return _umul128(a, b, productHi); } // Returns the lower 64 bits of (hi*2^64 + lo) >> dist, with 0 < dist < 64. static inline uint64_t shiftright128(const uint64_t lo, const uint64_t hi, const uint32_t dist) { // For the __shiftright128 intrinsic, the shift value is always // modulo 64. // In the current implementation of the double-precision version // of Ryu, the shift value is always < 64. (In the case // RYU_OPTIMIZE_SIZE == 0, the shift value is in the range [49, 58]. // Otherwise in the range [2, 59].) // However, this function is now also called by s2d, which requires supporting // the larger shift range (TODO: what is the actual range?). // Check this here in case a future change requires larger shift // values. In this case this function needs to be adjusted. assert(dist < 64); return __shiftright128(lo, hi, (unsigned char) dist); } #else // defined(HAS_64_BIT_INTRINSICS) static inline uint64_t umul128(const uint64_t a, const uint64_t b, uint64_t* const productHi) { // The casts here help MSVC to avoid calls to the __allmul library function. const uint32_t aLo = (uint32_t)a; const uint32_t aHi = (uint32_t)(a >> 32); const uint32_t bLo = (uint32_t)b; const uint32_t bHi = (uint32_t)(b >> 32); const uint64_t b00 = (uint64_t)aLo * bLo; const uint64_t b01 = (uint64_t)aLo * bHi; const uint64_t b10 = (uint64_t)aHi * bLo; const uint64_t b11 = (uint64_t)aHi * bHi; const uint32_t b00Lo = (uint32_t)b00; const uint32_t b00Hi = (uint32_t)(b00 >> 32); const uint64_t mid1 = b10 + b00Hi; const uint32_t mid1Lo = (uint32_t)(mid1); const uint32_t mid1Hi = (uint32_t)(mid1 >> 32); const uint64_t mid2 = b01 + mid1Lo; const uint32_t mid2Lo = (uint32_t)(mid2); const uint32_t mid2Hi = (uint32_t)(mid2 >> 32); const uint64_t pHi = b11 + mid1Hi + mid2Hi; const uint64_t pLo = ((uint64_t)mid2Lo << 32) | b00Lo; *productHi = pHi; return pLo; } static inline uint64_t shiftright128(const uint64_t lo, const uint64_t hi, const uint32_t dist) { // We don't need to handle the case dist >= 64 here (see above). assert(dist < 64); assert(dist > 0); return (hi << (64 - dist)) | (lo >> dist); } #endif // defined(HAS_64_BIT_INTRINSICS) #if defined(RYU_32_BIT_PLATFORM) // Returns the high 64 bits of the 128-bit product of a and b. static inline uint64_t umulh(const uint64_t a, const uint64_t b) { // Reuse the umul128 implementation. // Optimizers will likely eliminate the instructions used to compute the // low part of the product. uint64_t hi; umul128(a, b, &hi); return hi; } // On 32-bit platforms, compilers typically generate calls to library // functions for 64-bit divisions, even if the divisor is a constant. // // E.g.: // https://bugs.llvm.org/show_bug.cgi?id=37932 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17958 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37443 // // The functions here perform division-by-constant using multiplications // in the same way as 64-bit compilers would do. // // NB: // The multipliers and shift values are the ones generated by clang x64 // for expressions like x/5, x/10, etc. static inline uint64_t div5(const uint64_t x) { return umulh(x, 0xCCCCCCCCCCCCCCCDu) >> 2; } static inline uint64_t div10(const uint64_t x) { return umulh(x, 0xCCCCCCCCCCCCCCCDu) >> 3; } static inline uint64_t div100(const uint64_t x) { return umulh(x >> 2, 0x28F5C28F5C28F5C3u) >> 2; } #else // defined(RYU_32_BIT_PLATFORM) static inline uint64_t div5(const uint64_t x) { return x / 5; } static inline uint64_t div10(const uint64_t x) { return x / 10; } static inline uint64_t div100(const uint64_t x) { return x / 100; } #endif // defined(RYU_32_BIT_PLATFORM) static inline uint32_t pow5Factor(uint64_t value) { const uint64_t m_inv_5 = 14757395258967641293u; // 5 * m_inv_5 = 1 (mod 2^64) const uint64_t n_div_5 = 3689348814741910323u; // #{ n | n = 0 (mod 2^64) } = 2^64 / 5 uint32_t count = 0; for (;;) { assert(value != 0); value *= m_inv_5; if (value > n_div_5) break; ++count; } return count; } // Returns true if value is divisible by 5^p. static inline bool multipleOfPowerOf5(const uint64_t value, const uint32_t p) { // I tried a case distinction on p, but there was no performance difference. return pow5Factor(value) >= p; } // Returns true if value is divisible by 2^p. static inline bool multipleOfPowerOf2(const uint64_t value, const uint32_t p) { assert(value != 0); assert(p < 64); // __builtin_ctzll doesn't appear to be faster here. return (value & ((1ull << p) - 1)) == 0; } // We need a 64x128-bit multiplication and a subsequent 128-bit shift. // Multiplication: // The 64-bit factor is variable and passed in, the 128-bit factor comes // from a lookup table. We know that the 64-bit factor only has 55 // significant bits (i.e., the 9 topmost bits are zeros). The 128-bit // factor only has 124 significant bits (i.e., the 4 topmost bits are // zeros). // Shift: // In principle, the multiplication result requires 55 + 124 = 179 bits to // represent. However, we then shift this value to the right by j, which is // at least j >= 115, so the result is guaranteed to fit into 179 - 115 = 64 // bits. This means that we only need the topmost 64 significant bits of // the 64x128-bit multiplication. // // There are several ways to do this: // 1. Best case: the compiler exposes a 128-bit type. // We perform two 64x64-bit multiplications, add the higher 64 bits of the // lower result to the higher result, and shift by j - 64 bits. // // We explicitly cast from 64-bit to 128-bit, so the compiler can tell // that these are only 64-bit inputs, and can map these to the best // possible sequence of assembly instructions. // x64 machines happen to have matching assembly instructions for // 64x64-bit multiplications and 128-bit shifts. // // 2. Second best case: the compiler exposes intrinsics for the x64 assembly // instructions mentioned in 1. // // 3. We only have 64x64 bit instructions that return the lower 64 bits of // the result, i.e., we have to use plain C. // Our inputs are less than the full width, so we have three options: // a. Ignore this fact and just implement the intrinsics manually. // b. Split both into 31-bit pieces, which guarantees no internal overflow, // but requires extra work upfront (unless we change the lookup table). // c. Split only the first factor into 31-bit pieces, which also guarantees // no internal overflow, but requires extra work since the intermediate // results are not perfectly aligned. #if defined(HAS_UINT128) // Best case: use 128-bit type. static inline uint64_t mulShift64(const uint64_t m, const uint64_t* const mul, const int32_t j) { const uint128_t b0 = ((uint128_t) m) * mul[0]; const uint128_t b2 = ((uint128_t) m) * mul[1]; return (uint64_t) (((b0 >> 64) + b2) >> (j - 64)); } static inline uint64_t mulShiftAll64(const uint64_t m, const uint64_t* const mul, const int32_t j, uint64_t* const vp, uint64_t* const vm, const uint32_t mmShift) { // m <<= 2; // uint128_t b0 = ((uint128_t) m) * mul[0]; // 0 // uint128_t b2 = ((uint128_t) m) * mul[1]; // 64 // // uint128_t hi = (b0 >> 64) + b2; // uint128_t lo = b0 & 0xffffffffffffffffull; // uint128_t factor = (((uint128_t) mul[1]) << 64) + mul[0]; // uint128_t vpLo = lo + (factor << 1); // *vp = (uint64_t) ((hi + (vpLo >> 64)) >> (j - 64)); // uint128_t vmLo = lo - (factor << mmShift); // *vm = (uint64_t) ((hi + (vmLo >> 64) - (((uint128_t) 1ull) << 64)) >> (j - 64)); // return (uint64_t) (hi >> (j - 64)); *vp = mulShift64(4 * m + 2, mul, j); *vm = mulShift64(4 * m - 1 - mmShift, mul, j); return mulShift64(4 * m, mul, j); } #elif defined(HAS_64_BIT_INTRINSICS) static inline uint64_t mulShift64(const uint64_t m, const uint64_t* const mul, const int32_t j) { // m is maximum 55 bits uint64_t high1; // 128 const uint64_t low1 = umul128(m, mul[1], &high1); // 64 uint64_t high0; // 64 umul128(m, mul[0], &high0); // 0 const uint64_t sum = high0 + low1; if (sum < high0) { ++high1; // overflow into high1 } return shiftright128(sum, high1, j - 64); } static inline uint64_t mulShiftAll64(const uint64_t m, const uint64_t* const mul, const int32_t j, uint64_t* const vp, uint64_t* const vm, const uint32_t mmShift) { *vp = mulShift64(4 * m + 2, mul, j); *vm = mulShift64(4 * m - 1 - mmShift, mul, j); return mulShift64(4 * m, mul, j); } #else // !defined(HAS_UINT128) && !defined(HAS_64_BIT_INTRINSICS) static inline uint64_t mulShift64(const uint64_t m, const uint64_t* const mul, const int32_t j) { // m is maximum 55 bits uint64_t high1; // 128 const uint64_t low1 = umul128(m, mul[1], &high1); // 64 uint64_t high0; // 64 umul128(m, mul[0], &high0); // 0 const uint64_t sum = high0 + low1; if (sum < high0) { ++high1; // overflow into high1 } return shiftright128(sum, high1, j - 64); } // This is faster if we don't have a 64x64->128-bit multiplication. static inline uint64_t mulShiftAll64(uint64_t m, const uint64_t* const mul, const int32_t j, uint64_t* const vp, uint64_t* const vm, const uint32_t mmShift) { m <<= 1; // m is maximum 55 bits uint64_t tmp; const uint64_t lo = umul128(m, mul[0], &tmp); uint64_t hi; const uint64_t mid = tmp + umul128(m, mul[1], &hi); hi += mid < tmp; // overflow into hi const uint64_t lo2 = lo + mul[0]; const uint64_t mid2 = mid + mul[1] + (lo2 < lo); const uint64_t hi2 = hi + (mid2 < mid); *vp = shiftright128(mid2, hi2, (uint32_t) (j - 64 - 1)); if (mmShift == 1) { const uint64_t lo3 = lo - mul[0]; const uint64_t mid3 = mid - mul[1] - (lo3 > lo); const uint64_t hi3 = hi - (mid3 > mid); *vm = shiftright128(mid3, hi3, (uint32_t) (j - 64 - 1)); } else { const uint64_t lo3 = lo + lo; const uint64_t mid3 = mid + mid + (lo3 < lo); const uint64_t hi3 = hi + hi + (mid3 < mid); const uint64_t lo4 = lo3 - mul[0]; const uint64_t mid4 = mid3 - mul[1] - (lo4 > lo3); const uint64_t hi4 = hi3 - (mid4 > mid3); *vm = shiftright128(mid4, hi4, (uint32_t) (j - 64)); } return shiftright128(mid, hi, (uint32_t) (j - 64 - 1)); } #endif // Returns e == 0 ? 1 : ceil(log_2(5^e)); requires 0 <= e <= 3528. static inline int32_t pow5bits(const int32_t e) { // This approximation works up to the point that the multiplication overflows at e = 3529. // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater // than 2^9297. assert(e >= 0); assert(e <= 3528); return (int32_t) (((((uint32_t) e) * 1217359) >> 19) + 1); } // Returns floor(log_10(2^e)); requires 0 <= e <= 1650. static inline uint32_t log10Pow2(const int32_t e) { // The first value this approximation fails for is 2^1651 which is just greater than 10^297. assert(e >= 0); assert(e <= 1650); return (((uint32_t) e) * 78913) >> 18; } // Returns floor(log_10(5^e)); requires 0 <= e <= 2620. static inline uint32_t log10Pow5(const int32_t e) { // The first value this approximation fails for is 5^2621 which is just greater than 10^1832. assert(e >= 0); assert(e <= 2620); return (((uint32_t) e) * 732923) >> 20; } static inline uint64_t double_to_bits(const double d) { uint64_t bits = 0; memcpy(&bits, &d, sizeof(double)); return bits; } // A floating decimal representing m * 10^e. typedef struct floating_decimal_64 { uint64_t mantissa; // Decimal exponent's range is -324 to 308 // inclusive, and can fit in a short if needed. int32_t exponent; } floating_decimal_64; static inline floating_decimal_64 d2d(const uint64_t ieeeMantissa, const uint32_t ieeeExponent) { int32_t e2; uint64_t m2; if (ieeeExponent == 0) { // We subtract 2 so that the bounds computation has 2 additional bits. e2 = 1 - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2; m2 = ieeeMantissa; } else { e2 = (int32_t) ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2; m2 = (1ull << DOUBLE_MANTISSA_BITS) | ieeeMantissa; } const bool even = (m2 & 1) == 0; const bool acceptBounds = even; // Step 2: Determine the interval of valid decimal representations. const uint64_t mv = 4 * m2; // Implicit bool -> int conversion. True is 1, false is 0. const uint32_t mmShift = ieeeMantissa != 0 || ieeeExponent <= 1; // We would compute mp and mm like this: // uint64_t mp = 4 * m2 + 2; // uint64_t mm = mv - 1 - mmShift; // Step 3: Convert to a decimal power base using 128-bit arithmetic. uint64_t vr, vp, vm; int32_t e10; bool vmIsTrailingZeros = false; bool vrIsTrailingZeros = false; if (e2 >= 0) { // I tried special-casing q == 0, but there was no effect on performance. // This expression is slightly faster than max(0, log10Pow2(e2) - 1). const uint32_t q = log10Pow2(e2) - (e2 > 3); e10 = (int32_t) q; const int32_t k = DOUBLE_POW5_INV_BITCOUNT + pow5bits((int32_t) q) - 1; const int32_t i = -e2 + (int32_t) q + k; vr = mulShiftAll64(m2, DOUBLE_POW5_INV_SPLIT[q], i, &vp, &vm, mmShift); if (q <= 21) { // This should use q <= 22, but I think 21 is also safe. Smaller values // may still be safe, but it's more difficult to reason about them. // Only one of mp, mv, and mm can be a multiple of 5, if any. const uint32_t mvMod5 = ((uint32_t) mv) - 5 * ((uint32_t) div5(mv)); if (mvMod5 == 0) { vrIsTrailingZeros = multipleOfPowerOf5(mv, q); } else if (acceptBounds) { // Same as min(e2 + (~mm & 1), pow5Factor(mm)) >= q // <=> e2 + (~mm & 1) >= q && pow5Factor(mm) >= q // <=> true && pow5Factor(mm) >= q, since e2 >= q. vmIsTrailingZeros = multipleOfPowerOf5(mv - 1 - mmShift, q); } else { // Same as min(e2 + 1, pow5Factor(mp)) >= q. vp -= multipleOfPowerOf5(mv + 2, q); } } } else { // This expression is slightly faster than max(0, log10Pow5(-e2) - 1). const uint32_t q = log10Pow5(-e2) - (-e2 > 1); e10 = (int32_t) q + e2; const int32_t i = -e2 - (int32_t) q; const int32_t k = pow5bits(i) - DOUBLE_POW5_BITCOUNT; const int32_t j = (int32_t) q - k; vr = mulShiftAll64(m2, DOUBLE_POW5_SPLIT[i], j, &vp, &vm, mmShift); if (q <= 1) { // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits. // mv = 4 * m2, so it always has at least two trailing 0 bits. vrIsTrailingZeros = true; if (acceptBounds) { // mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff mmShift == 1. vmIsTrailingZeros = mmShift == 1; } else { // mp = mv + 2, so it always has at least one trailing 0 bit. --vp; } } else if (q < 63) { // TODO(ulfjack): Use a tighter bound here. // We want to know if the full product has at least q trailing zeros. // We need to compute min(p2(mv), p5(mv) - e2) >= q // <=> p2(mv) >= q && p5(mv) - e2 >= q // <=> p2(mv) >= q (because -e2 >= q) vrIsTrailingZeros = multipleOfPowerOf2(mv, q); } } // Step 4: Find the shortest decimal representation in the interval of valid representations. int32_t removed = 0; uint8_t lastRemovedDigit = 0; uint64_t output; // On average, we remove ~2 digits. if (vmIsTrailingZeros || vrIsTrailingZeros) { // General case, which happens rarely (~0.7%). for (;;) { const uint64_t vpDiv10 = div10(vp); const uint64_t vmDiv10 = div10(vm); if (vpDiv10 <= vmDiv10) { break; } const uint32_t vmMod10 = ((uint32_t) vm) - 10 * ((uint32_t) vmDiv10); const uint64_t vrDiv10 = div10(vr); const uint32_t vrMod10 = ((uint32_t) vr) - 10 * ((uint32_t) vrDiv10); vmIsTrailingZeros &= vmMod10 == 0; vrIsTrailingZeros &= lastRemovedDigit == 0; lastRemovedDigit = (uint8_t) vrMod10; vr = vrDiv10; vp = vpDiv10; vm = vmDiv10; ++removed; } if (vmIsTrailingZeros) { for (;;) { const uint64_t vmDiv10 = div10(vm); const uint32_t vmMod10 = ((uint32_t) vm) - 10 * ((uint32_t) vmDiv10); if (vmMod10 != 0) { break; } const uint64_t vpDiv10 = div10(vp); const uint64_t vrDiv10 = div10(vr); const uint32_t vrMod10 = ((uint32_t) vr) - 10 * ((uint32_t) vrDiv10); vrIsTrailingZeros &= lastRemovedDigit == 0; lastRemovedDigit = (uint8_t) vrMod10; vr = vrDiv10; vp = vpDiv10; vm = vmDiv10; ++removed; } } if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) { // Round even if the exact number is .....50..0. lastRemovedDigit = 4; } // We need to take vr + 1 if vr is outside bounds or we need to round up. output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5); } else { // Specialized for the common case (~99.3%). Percentages below are relative to this. bool roundUp = false; const uint64_t vpDiv100 = div100(vp); const uint64_t vmDiv100 = div100(vm); if (vpDiv100 > vmDiv100) { // Optimization: remove two digits at a time (~86.2%). const uint64_t vrDiv100 = div100(vr); const uint32_t vrMod100 = ((uint32_t) vr) - 100 * ((uint32_t) vrDiv100); roundUp = vrMod100 >= 50; vr = vrDiv100; vp = vpDiv100; vm = vmDiv100; removed += 2; } // Loop iterations below (approximately), without optimization above: // 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, 6+: 0.02% // Loop iterations below (approximately), with optimization above: // 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02% for (;;) { const uint64_t vpDiv10 = div10(vp); const uint64_t vmDiv10 = div10(vm); if (vpDiv10 <= vmDiv10) { break; } const uint64_t vrDiv10 = div10(vr); const uint32_t vrMod10 = ((uint32_t) vr) - 10 * ((uint32_t) vrDiv10); roundUp = vrMod10 >= 5; vr = vrDiv10; vp = vpDiv10; vm = vmDiv10; ++removed; } // We need to take vr + 1 if vr is outside bounds or we need to round up. output = vr + (vr == vm || roundUp); } const int32_t exp = e10 + removed; floating_decimal_64 fd; fd.exponent = exp; fd.mantissa = output; return fd; } static inline int write_exponent(int32_t k, char* buf) { int sign = k < 0; if (sign) { *buf++ = '-'; k = -k; } if (k >= 100) { *buf++ = '0' + (k / 100); k %= 100; memcpy(buf, DIGIT_TABLE + (k * 2), 2); return sign + 3; } else if (k >= 10) { memcpy(buf, DIGIT_TABLE + (k * 2), 2); return sign + 2; } else { *buf = '0' + k; return sign + 1; } } /* Write a double to buf, requires 24 bytes of space */ static inline int write_f64(double f, char* buf, bool allow_nonfinite) { const uint64_t bits = double_to_bits(f); const int sign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0; const uint64_t ieee_mantissa = bits & ((1ull << DOUBLE_MANTISSA_BITS) - 1); const uint32_t ieee_exponent = (uint32_t) ((bits >> DOUBLE_MANTISSA_BITS) & ((1u << DOUBLE_EXPONENT_BITS) - 1)); /* Serialize all non-finite numbers as null */ if (MS_UNLIKELY(ieee_exponent == ((1 << DOUBLE_EXPONENT_BITS) - 1))) { if (MS_LIKELY(!allow_nonfinite)) { memcpy(buf, "null", 4); return 4; } else { if (ieee_mantissa == 0) { if (sign) { memcpy(buf, "-inf", 4); return 4; } memcpy(buf, "inf", 3); return 3; } memcpy(buf, "nan", 3); return 3; } } if (sign) { *buf++ = '-'; } if (ieee_exponent == 0 && ieee_mantissa == 0) { memcpy(buf, "0.0", 3); return sign + 3; } floating_decimal_64 v = d2d(ieee_mantissa, ieee_exponent); int length = write_u64(v.mantissa, buf) - buf; int32_t k = v.exponent; int32_t kk = length + k; if (0 <= k && kk <= 16) { /* XYZ00.0 */ memset(buf + length, '0', k + 2); *(buf + kk) = '.'; return sign + kk + 2; } else if (0 < kk && kk <= 16) { /* XY.Z */ memmove(buf + kk + 1, buf + kk, length - kk); *(buf + kk) = '.'; return sign + length + 1; } else if (-5 < kk && kk <= 0) { /* 0.0XYZ */ int offset = 2 - kk; memmove(buf + offset, buf, length); memset(buf, '0', offset); *(buf + 1) = '.'; return sign + length + offset; } else { /* X.YZe123 if length > 1 else Xe123 */ int offset = 0; if (length > 1) { offset = length; memmove(buf + 2, buf + 1, length - 1); *(buf + 1) = '.'; } *(buf + offset + 1) = 'e'; return sign + offset + 2 + write_exponent(kk - 1, buf + offset + 2); } } #endif // RYU_H python-msgspec-0.19.0/msgspec/structs.py000066400000000000000000000055761473355726200203360ustar00rootroot00000000000000from __future__ import annotations from typing import Any from . import NODEFAULT, Struct, field from ._core import ( # noqa Factory as _Factory, StructConfig, asdict, astuple, replace, force_setattr, ) from ._utils import get_class_annotations as _get_class_annotations __all__ = ( "FieldInfo", "StructConfig", "asdict", "astuple", "fields", "force_setattr", "replace", ) def __dir__(): return __all__ class FieldInfo(Struct): """A record describing a field in a struct type. Parameters ---------- name: str The field name as seen by Python code (e.g. ``field_one``). encode_name: str The name used when encoding/decoding the field. This may differ if the field is renamed (e.g. ``fieldOne``). type: Any The full field type annotation. default: Any, optional A default value for the field. Will be `NODEFAULT` if no default value is set. default_factory: Any, optional A callable that creates a default value for the field. Will be `NODEFAULT` if no ``default_factory`` is set. """ name: str encode_name: str type: Any default: Any = field(default_factory=lambda: NODEFAULT) default_factory: Any = field(default_factory=lambda: NODEFAULT) @property def required(self) -> bool: """A helper for checking whether a field is required""" return self.default is NODEFAULT and self.default_factory is NODEFAULT def fields(type_or_instance: Struct | type[Struct]) -> tuple[FieldInfo]: """Get information about the fields in a Struct. Parameters ---------- type_or_instance: A struct type or instance. Returns ------- tuple[FieldInfo] """ if isinstance(type_or_instance, Struct): annotated_cls = cls = type(type_or_instance) else: annotated_cls = type_or_instance cls = getattr(type_or_instance, "__origin__", type_or_instance) if not (isinstance(cls, type) and issubclass(cls, Struct)): raise TypeError("Must be called with a struct type or instance") hints = _get_class_annotations(annotated_cls) npos = len(cls.__struct_fields__) - len(cls.__struct_defaults__) fields = [] for name, encode_name, default_obj in zip( cls.__struct_fields__, cls.__struct_encode_fields__, (NODEFAULT,) * npos + cls.__struct_defaults__, ): default = default_factory = NODEFAULT if isinstance(default_obj, _Factory): default_factory = default_obj.factory elif default_obj is not NODEFAULT: default = default_obj field = FieldInfo( name=name, encode_name=encode_name, type=hints[name], default=default, default_factory=default_factory, ) fields.append(field) return tuple(fields) python-msgspec-0.19.0/msgspec/structs.pyi000066400000000000000000000016061473355726200204750ustar00rootroot00000000000000from typing import Any, TypeVar, Union from . import NODEFAULT, Struct S = TypeVar("S", bound=Struct) def replace(struct: S, /, **changes: Any) -> S: ... def asdict(struct: Struct) -> dict[str, Any]: ... def astuple(struct: Struct) -> tuple[Any, ...]: ... def force_setattr(struct: Struct, name: str, value: Any) -> None: ... class StructConfig: frozen: bool eq: bool order: bool array_like: bool gc: bool repr_omit_defaults: bool omit_defaults: bool forbid_unknown_fields: bool weakref: bool dict: bool cache_hash: bool tag: Union[str, int, None] tag_field: Union[str, None] class FieldInfo(Struct): name: str encode_name: str type: Any default: Any = NODEFAULT default_factory: Any = NODEFAULT @property def required(self) -> bool: ... def fields(type_or_instance: Struct | type[Struct]) -> tuple[FieldInfo]: ... python-msgspec-0.19.0/msgspec/toml.py000066400000000000000000000126261473355726200175740ustar00rootroot00000000000000from __future__ import annotations import datetime as _datetime from typing import TYPE_CHECKING, overload, TypeVar, Any from . import ( DecodeError as _DecodeError, convert as _convert, to_builtins as _to_builtins, ) if TYPE_CHECKING: from typing import Callable, Optional, Type, Union, Literal from typing_extensions import Buffer __all__ = ("encode", "decode") def __dir__(): return __all__ def _import_tomllib(): try: import tomllib # type: ignore return tomllib except ImportError: pass try: import tomli # type: ignore return tomli except ImportError: raise ImportError( "`msgspec.toml.decode` requires `tomli` be installed.\n\n" "Please either `pip` or `conda` install it as follows:\n\n" " $ python -m pip install tomli # using pip\n" " $ conda install tomli # or using conda" ) from None def _import_tomli_w(): try: import tomli_w # type: ignore return tomli_w except ImportError: raise ImportError( "`msgspec.toml.encode` requires `tomli_w` be installed.\n\n" "Please either `pip` or `conda` install it as follows:\n\n" " $ python -m pip install tomli_w # using pip\n" " $ conda install tomli_w # or using conda" ) from None def encode( obj: Any, *, enc_hook: Optional[Callable[[Any], Any]] = None, order: Literal[None, "deterministic", "sorted"] = None, ) -> bytes: """Serialize an object as TOML. Parameters ---------- obj : Any The object to serialize. enc_hook : callable, optional A callable to call for objects that aren't supported msgspec types. Takes the unsupported object and should return a supported object, or raise a ``NotImplementedError`` if unsupported. order : {None, 'deterministic', 'sorted'}, optional The ordering to use when encoding unordered compound types. - ``None``: All objects are encoded in the most efficient manner matching their in-memory representations. The default. - `'deterministic'`: Unordered collections (sets, dicts) are sorted to ensure a consistent output between runs. Useful when comparison/hashing of the encoded binary output is necessary. - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs, dataclasses, ...) are also sorted by field name before encoding. This is slower than `'deterministic'`, but may produce more human-readable output. Returns ------- data : bytes The serialized object. See Also -------- decode """ toml = _import_tomli_w() msg = _to_builtins( obj, builtin_types=(_datetime.datetime, _datetime.date, _datetime.time), str_keys=True, enc_hook=enc_hook, order=order, ) return toml.dumps(msg).encode("utf-8") T = TypeVar("T") @overload def decode( buf: Union[Buffer, str], *, strict: bool = True, dec_hook: Optional[Callable[[type, Any], Any]] = None, ) -> Any: pass @overload def decode( buf: Union[Buffer, str], *, type: Type[T] = ..., strict: bool = True, dec_hook: Optional[Callable[[type, Any], Any]] = None, ) -> T: pass @overload def decode( buf: Union[Buffer, str], *, type: Any = ..., strict: bool = True, dec_hook: Optional[Callable[[type, Any], Any]] = None, ) -> Any: pass def decode(buf, *, type=Any, strict=True, dec_hook=None): """Deserialize an object from TOML. Parameters ---------- buf : bytes-like or str The message to decode. type : type, optional A Python type (in type annotation form) to decode the object as. If provided, the message will be type checked and decoded as the specified type. Defaults to `Any`, in which case the message will be decoded using the default TOML types. strict : bool, optional Whether type coercion rules should be strict. Setting to False enables a wider set of coercion rules from string to non-string types for all values. Default is True. dec_hook : callable, optional An optional callback for handling decoding custom types. Should have the signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the expected message type, and ``obj`` is the decoded representation composed of only basic TOML types. This hook should transform ``obj`` into type ``type``, or raise a ``NotImplementedError`` if unsupported. Returns ------- obj : Any The deserialized object. See Also -------- encode """ toml = _import_tomllib() if isinstance(buf, str): str_buf = buf elif isinstance(buf, (bytes, bytearray)): str_buf = buf.decode("utf-8") else: # call `memoryview` first, since `bytes(1)` is actually valid str_buf = bytes(memoryview(buf)).decode("utf-8") try: obj = toml.loads(str_buf) except toml.TOMLDecodeError as exc: raise _DecodeError(str(exc)) from None if type is Any: return obj return _convert( obj, type, builtin_types=(_datetime.datetime, _datetime.date, _datetime.time), str_keys=True, strict=strict, dec_hook=dec_hook, ) python-msgspec-0.19.0/msgspec/yaml.py000066400000000000000000000124231473355726200175560ustar00rootroot00000000000000from __future__ import annotations import datetime as _datetime from typing import TYPE_CHECKING, overload, TypeVar, Any from . import ( DecodeError as _DecodeError, convert as _convert, to_builtins as _to_builtins, ) if TYPE_CHECKING: from typing import Callable, Optional, Type, Union, Literal from typing_extensions import Buffer __all__ = ("encode", "decode") def __dir__(): return __all__ def _import_pyyaml(name): try: import yaml # type: ignore except ImportError: raise ImportError( f"`msgspec.yaml.{name}` requires PyYAML be installed.\n\n" "Please either `pip` or `conda` install it as follows:\n\n" " $ python -m pip install pyyaml # using pip\n" " $ conda install pyyaml # or using conda" ) from None else: return yaml def encode( obj: Any, *, enc_hook: Optional[Callable[[Any], Any]] = None, order: Literal[None, "deterministic", "sorted"] = None, ) -> bytes: """Serialize an object as YAML. Parameters ---------- obj : Any The object to serialize. enc_hook : callable, optional A callable to call for objects that aren't supported msgspec types. Takes the unsupported object and should return a supported object, or raise a ``NotImplementedError`` if unsupported. order : {None, 'deterministic', 'sorted'}, optional The ordering to use when encoding unordered compound types. - ``None``: All objects are encoded in the most efficient manner matching their in-memory representations. The default. - `'deterministic'`: Unordered collections (sets, dicts) are sorted to ensure a consistent output between runs. Useful when comparison/hashing of the encoded binary output is necessary. - `'sorted'`: Like `'deterministic'`, but *all* object-like types (structs, dataclasses, ...) are also sorted by field name before encoding. This is slower than `'deterministic'`, but may produce more human-readable output. Returns ------- data : bytes The serialized object. Notes ----- This function requires that the third-party `PyYAML library `_ is installed. See Also -------- decode """ yaml = _import_pyyaml("encode") # Use the C extension if available Dumper = getattr(yaml, "CSafeDumper", yaml.SafeDumper) return yaml.dump_all( [ _to_builtins( obj, builtin_types=(_datetime.datetime, _datetime.date), enc_hook=enc_hook, order=order, ) ], encoding="utf-8", Dumper=Dumper, allow_unicode=True, sort_keys=False, ) T = TypeVar("T") @overload def decode( buf: Union[Buffer, str], *, strict: bool = True, dec_hook: Optional[Callable[[type, Any], Any]] = None, ) -> Any: pass @overload def decode( buf: Union[bytes, str], *, type: Type[T] = ..., strict: bool = True, dec_hook: Optional[Callable[[type, Any], Any]] = None, ) -> T: pass @overload def decode( buf: Union[bytes, str], *, type: Any = ..., strict: bool = True, dec_hook: Optional[Callable[[type, Any], Any]] = None, ) -> Any: pass def decode(buf, *, type=Any, strict=True, dec_hook=None): """Deserialize an object from YAML. Parameters ---------- buf : bytes-like or str The message to decode. type : type, optional A Python type (in type annotation form) to decode the object as. If provided, the message will be type checked and decoded as the specified type. Defaults to `Any`, in which case the message will be decoded using the default YAML types. strict : bool, optional Whether type coercion rules should be strict. Setting to False enables a wider set of coercion rules from string to non-string types for all values. Default is True. dec_hook : callable, optional An optional callback for handling decoding custom types. Should have the signature ``dec_hook(type: Type, obj: Any) -> Any``, where ``type`` is the expected message type, and ``obj`` is the decoded representation composed of only basic YAML types. This hook should transform ``obj`` into type ``type``, or raise a ``NotImplementedError`` if unsupported. Returns ------- obj : Any The deserialized object. Notes ----- This function requires that the third-party `PyYAML library `_ is installed. See Also -------- encode """ yaml = _import_pyyaml("decode") # Use the C extension if available Loader = getattr(yaml, "CSafeLoader", yaml.SafeLoader) if not isinstance(buf, (str, bytes)): # call `memoryview` first, since `bytes(1)` is actually valid buf = bytes(memoryview(buf)) try: obj = yaml.load(buf, Loader) except yaml.YAMLError as exc: raise _DecodeError(str(exc)) from None if type is Any: return obj return _convert( obj, type, builtin_types=(_datetime.datetime, _datetime.date), strict=strict, dec_hook=dec_hook, ) python-msgspec-0.19.0/pyproject.toml000066400000000000000000000010571473355726200175160ustar00rootroot00000000000000[tool.ruff] exclude = [ "*.pyi", "__init__.py", "_version.py", "versioneer.py", "basic_typing_examples.py", "json.py", "msgpack.py", "test_JSONTestSuite.py", "conf.py", ] line-length = 88 [tool.ruff.lint] ignore = [ "E721", # Comparing types instead of isinstance "E741", # Ambiguous variable names "E501", # Conflicts with ruff format "W191", # Conflicts with ruff format ] select = [ "E", # PEP8 Errors "F", # Pyflakes "W", # PEP8 Warnings ] [tool.ruff.lint.isort] combine-as-imports = true python-msgspec-0.19.0/scripts/000077500000000000000000000000001473355726200162665ustar00rootroot00000000000000python-msgspec-0.19.0/scripts/generate_atof_consts.py000066400000000000000000000043141473355726200230360ustar00rootroot00000000000000"""This script generates msgspec/atof_consts.h""" import math import os import textwrap def gen_hpd_tables(): log2log10 = math.log(2) / math.log(10) shifts = ["0x0000"] powers = [] for i in range(1, 61): offset = len(powers) assert offset <= 0x07FF num_new_digits = int(log2log10 * float(i)) + 1 assert num_new_digits <= 31 code = (num_new_digits << 11) | offset p = str(5**i) powers.extend(p) shifts.append("0x%04X" % code) for i in range(61, 65): shifts.append("0x%04X" % len(powers)) n_shifts = len(shifts) n_powers = len(powers) assert n_powers <= 0x07FF shifts_str = "\n".join(textwrap.wrap(", ".join(shifts), width=78)) powers_str = "\n".join(textwrap.wrap(", ".join(powers), width=78)) return n_shifts, shifts_str, n_powers, powers_str def gen_row(e): z = 1 << 2048 if e >= 0: exp = 10**e z = z * exp else: exp = 10 ** (-e) z = z // exp n = -2048 while z >= (1 << 128): z = z >> 1 n += 1 h = hex(z)[2:] assert len(h) == 32 approx_n = ((217706 * e) >> 16) + 1087 biased_n = 1214 + n assert approx_n == biased_n return "{0x%s, 0x%s}, // 1e%-04d" % (h[16:], h[:16], e) table_rows = [gen_row(e) for e in range(-307, 289)] f64_powers = [f"1e{i}" for i in range(23)] n_shifts, shifts, n_powers, powers = gen_hpd_tables() text = """\ /* DO NOT EDIT - generated by scripts/generate_atof_consts.py */ #ifndef MSGSPEC_ATOF_CONSTS_H #define MSGSPEC_ATOF_CONSTS_H static const uint64_t ms_atof_powers_of_10[%d][2] = { %s }; static const double ms_atof_f64_powers_of_10[%d] = { %s }; static const uint16_t ms_atof_left_shift[%d] = { %s }; static const uint8_t ms_atof_powers_of_5[%d] = { %s }; #endif """ % ( len(table_rows), "\n".join(table_rows), len(f64_powers), "\n".join(textwrap.wrap(", ".join(f64_powers), width=78)), n_shifts, shifts, n_powers, powers, ) if __name__ == "__main__": repo = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) path = os.path.join(repo, "msgspec", "atof_consts.h") with open(path, "wb") as f: f.write(text.encode("utf-8")) python-msgspec-0.19.0/setup.cfg000066400000000000000000000006131473355726200164200ustar00rootroot00000000000000[codespell] skip=*.py,*.c,*.h [coverage:run] omit = msgspec/_version.py tests/basic_typing_examples.py tests/test_mypy.py tests/test_pyright.py [tool:pytest] markers = mypy pyright filterwarnings = error [versioneer] VCS = git style = pep440 versionfile_source = msgspec/_version.py versionfile_build = msgspec/_version.py tag_prefix = parentdir_prefix = msgspec- python-msgspec-0.19.0/setup.py000066400000000000000000000066151473355726200163210ustar00rootroot00000000000000import sys import os from setuptools import setup from setuptools.extension import Extension import versioneer # Check for 32-bit windows builds, which currently aren't supported. We can't # rely on `platform.architecture` here since users can still run 32-bit python # builds on 64 bit architectures. if sys.platform == "win32" and sys.maxsize == (2**31 - 1): import textwrap error = """ ==================================================================== `msgspec` currently doesn't support 32-bit Python windows builds. If this is important for your use case, please open an issue on GitHub: https://github.com/jcrist/msgspec/issues ==================================================================== """ print(textwrap.dedent(error)) exit(1) SANITIZE = os.environ.get("MSGSPEC_SANITIZE", False) COVERAGE = os.environ.get("MSGSPEC_COVERAGE", False) DEBUG = os.environ.get("MSGSPEC_DEBUG", SANITIZE or COVERAGE) extra_compile_args = [] extra_link_args = [] if SANITIZE: extra_compile_args.extend(["-fsanitize=address", "-fsanitize=undefined"]) extra_link_args.extend(["-lasan", "-lubsan"]) if COVERAGE: extra_compile_args.append("--coverage") extra_link_args.append("-lgcov") if DEBUG: extra_compile_args.extend(["-O0", "-g", "-UNDEBUG"]) ext_modules = [ Extension( "msgspec._core", [os.path.join("msgspec", "_core.c")], extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, ) ] yaml_deps = ["pyyaml"] toml_deps = ['tomli ; python_version < "3.11"', "tomli_w"] doc_deps = ["sphinx", "furo", "sphinx-copybutton", "sphinx-design", "ipython"] test_deps = [ "pytest", "msgpack", "attrs", 'eval-type-backport ; python_version < "3.10"', *yaml_deps, *toml_deps, ] dev_deps = ["pre-commit", "coverage", "mypy", "pyright", *doc_deps, *test_deps] extras_require = { "yaml": yaml_deps, "toml": toml_deps, "doc": doc_deps, "test": test_deps, "dev": dev_deps, } setup( name="msgspec", version=versioneer.get_version(), cmdclass=versioneer.get_cmdclass(), maintainer="Jim Crist-Harif", maintainer_email="jcristharif@gmail.com", url="https://jcristharif.com/msgspec/", project_urls={ "Documentation": "https://jcristharif.com/msgspec/", "Source": "https://github.com/jcrist/msgspec/", "Issue Tracker": "https://github.com/jcrist/msgspec/issues", }, description=( "A fast serialization and validation library, with builtin support for " "JSON, MessagePack, YAML, and TOML." ), keywords="JSON msgpack MessagePack TOML YAML serialization validation schema", classifiers=[ "License :: OSI Approved :: BSD License", "Development Status :: 4 - Beta", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", ], extras_require=extras_require, license="BSD", packages=["msgspec"], package_data={"msgspec": ["py.typed", "*.pyi"]}, ext_modules=ext_modules, long_description=( open("README.md", encoding="utf-8").read() if os.path.exists("README.md") else "" ), long_description_content_type="text/markdown", python_requires=">=3.9", zip_safe=False, ) python-msgspec-0.19.0/tests/000077500000000000000000000000001473355726200157415ustar00rootroot00000000000000python-msgspec-0.19.0/tests/basic_typing_examples.py000066400000000000000000001003171473355726200226660ustar00rootroot00000000000000# fmt: off from __future__ import annotations import datetime import decimal import pickle from typing import Any, Dict, Final, List, Type, Union import msgspec def check___version__() -> None: reveal_type(msgspec.__version__) # assert "str" in typ def check_exceptions() -> None: reveal_type(msgspec.MsgspecError) # assert "Any" not in typ reveal_type(msgspec.EncodeError) # assert "Any" not in typ reveal_type(msgspec.DecodeError) # assert "Any" not in typ reveal_type(msgspec.ValidationError) # assert "Any" not in typ def check_unset() -> None: reveal_type(msgspec.UNSET) # assert "UnsetType" in typ if isinstance(msgspec.UNSET, msgspec.UnsetType): print("True") str(msgspec.UNSET) pickle.dumps(msgspec.UNSET) def check_unset_type_lowering(x: int | msgspec.UnsetType) -> None: if x is msgspec.UNSET: reveal_type(x) # assert "int" not in typ.lower() else: reveal_type(x) # assert "unset" not in typ.lower() def check_nodefault() -> None: reveal_type(msgspec.NODEFAULT) # assert "Any" not in typ str(msgspec.NODEFAULT) pickle.dumps(msgspec.NODEFAULT) ########################################################## # Structs # ########################################################## def check_struct() -> None: class Test(msgspec.Struct): x: int y: str t = Test(1, "foo") reveal_type(t) # assert "Test" in typ reveal_type(t.x) # assert "int" in typ reveal_type(t.y) # assert "str" in typ def check_struct_field() -> None: class Test(msgspec.Struct): a: int b: int = msgspec.field(name="b_field") x: int = msgspec.field(default=1) y: List[int] = msgspec.field(default_factory=lambda: [1, 2, 3]) x2: int = msgspec.field(default=1, name="x2_field") y2: List[int] = msgspec.field(default_factory=lambda: [1, 2, 3], name="y2_field") Test(1, 2) Test(1, 2, 3) Test(1, 2, 3, [4]) Test(1, 2, 3, [4], 5) Test(1, 2, 3, [4], 5, [6]) def check_struct_kw_only() -> None: class Test(msgspec.Struct, kw_only=True): x: int y: str t = Test(y="foo", x=1) def check_struct_kw_only_base_class() -> None: class Base(msgspec.Struct, kw_only=True): d: bytes c: str = "default" class Test(Base): a: int b: list[int] = [] Test(1, d=b"foo") Test(1, [1, 2, 3], d=b"foo", c="test") def check_struct_kw_only_subclass() -> None: class Base(msgspec.Struct): d: bytes c: str = "default" class Test(Base, kw_only=True): a: int b: list[int] = [] Test(b"foo", a=1) Test(b"foo", "test", a=1, b=[1, 2, 3]) def check_struct_final_fields() -> None: """Test that type checkers support `Final` fields for dataclass_transform""" class Test(msgspec.Struct): x: Final[int] = 0 t = Test() t2 = Test(x=1) reveal_type(t.x) # assert "int" in typ reveal_type(t2.x) # assert "int" in typ def check_struct_repr_omit_defaults() -> None: class Test(msgspec.Struct, repr_omit_defaults=True): x: int y: str t = Test(1, "foo") reveal_type(t.x) # assert "int" in typ def check_struct_omit_defaults() -> None: class Test(msgspec.Struct, omit_defaults=True): x: int y: str t = Test(1, "foo") reveal_type(t) # assert "Test" in typ reveal_type(t.x) # assert "int" in typ reveal_type(t.y) # assert "str" in typ def check_struct_forbid_unknown_fields() -> None: class Test(msgspec.Struct, forbid_unknown_fields=True): x: int y: str t = Test(1, "foo") reveal_type(t) # assert "Test" in typ reveal_type(t.x) # assert "int" in typ reveal_type(t.y) # assert "str" in typ def check_struct_rename() -> None: class TestLower(msgspec.Struct, rename="lower"): x: int class TestUpper(msgspec.Struct, rename="upper"): x: int class TestCamel(msgspec.Struct, rename="camel"): x: int class TestPascal(msgspec.Struct, rename="pascal"): x: int class TestKebab(msgspec.Struct, rename="kebab"): x: int class TestCallable(msgspec.Struct, rename=lambda x: x.title()): x: int class TestCallableNone(msgspec.Struct, rename=lambda x: None): x: int class TestMapping(msgspec.Struct, rename={"x": "X"}): x: int class TestNone(msgspec.Struct, rename=None): x: int o = sum( [ TestLower(1).x, TestUpper(2).x, TestCamel(3).x, TestPascal(4).x, TestCallable(5).x, TestNone(6).x, ] ) reveal_type(o) # assert "int" in typ def check_struct_array_like() -> None: class Test(msgspec.Struct, array_like=True): x: int y: str t = Test(1, "foo") reveal_type(t) # assert "Test" in typ reveal_type(t.x) # assert "int" in typ reveal_type(t.y) # assert "str" in typ def check_struct_frozen() -> None: class Test(msgspec.Struct, frozen=True): x: int y: str t = Test(1, "foo") reveal_type(t) # assert "Test" in typ reveal_type(t.x) # assert "int" in typ reveal_type(t.y) # assert "str" in typ def check_struct_eq() -> None: class Test(msgspec.Struct, eq=False): x: int y: str t = Test(1, "foo") t2 = Test(1, "foo") if t == t2: print("Here") reveal_type(t) # assert "Test" in typ reveal_type(t.x) # assert "int" in typ reveal_type(t.y) # assert "str" in typ def check_struct_order() -> None: class Test(msgspec.Struct, order=True): x: int y: str t = Test(1, "foo") reveal_type(t) # assert "Test" in typ reveal_type(t.x) # assert "int" in typ reveal_type(t.y) # assert "str" in typ def check_struct_gc() -> None: class Test(msgspec.Struct, gc=False): x: int y: str t = Test(1, "foo") reveal_type(t) # assert "Test" in typ reveal_type(t.x) # assert "int" in typ reveal_type(t.y) # assert "str" in typ def check_struct_weakref() -> None: class Test(msgspec.Struct, weakref=True): x: int y: str t = Test(1, "foo") reveal_type(t) # assert "Test" in typ reveal_type(t.x) # assert "int" in typ reveal_type(t.y) # assert "str" in typ def check_struct_dict() -> None: class Test(msgspec.Struct, dict=True): x: int y: str t = Test(1, "foo") reveal_type(t) # assert "Test" in typ def check_struct_cache_hash() -> None: class Test(msgspec.Struct, cache_hash=True): x: int y: str t = Test(1, "foo") reveal_type(t) # assert "Test" in typ def check_struct_tag_tag_field() -> None: class Test1(msgspec.Struct, tag=None): pass class Test2(msgspec.Struct, tag=True): pass class Test3(msgspec.Struct, tag=False): pass class Test4(msgspec.Struct, tag="mytag"): pass class Test5(msgspec.Struct, tag=123): pass class Test6(msgspec.Struct, tag=str.lower): pass class Test7(msgspec.Struct, tag=lambda n: len(n)): pass class Test8(msgspec.Struct, tag_field=None): pass class Test9(msgspec.Struct, tag_field="type"): pass def check_struct_methods() -> None: class Point(msgspec.Struct): x: int y: int a = Point(1, 2) b = Point(3, 4) if a == b: print("equal") a.x = a.x + b.y repr(a) for item in a.__rich_repr__(): assert isinstance(item, tuple) assert len(item) == 2 name, val = item print(f"{name} = {val}") def check_struct_attributes() -> None: class Point(msgspec.Struct): x: int y: int for field in Point.__struct_fields__: reveal_type(field) # assert "str" in typ for field in Point.__match_args__: reveal_type(field) # assert "any" not in typ.lower() p = Point(1, 2) for field in p.__struct_fields__: reveal_type(field) # assert "str" in typ def check_struct_config() -> None: class Point(msgspec.Struct): x: int y: int config = Point.__struct_config__ reveal_type(config) # assert "StructConfig" in typ reveal_type(config.frozen) # assert "bool" in typ reveal_type(config.eq) # assert "bool" in typ reveal_type(config.order) # assert "bool" in typ reveal_type(config.array_like) # assert "bool" in typ reveal_type(config.gc) # assert "bool" in typ reveal_type(config.repr_omit_defaults) # assert "bool" in typ reveal_type(config.omit_defaults) # assert "bool" in typ reveal_type(config.forbid_unknown_fields) # assert "bool" in typ reveal_type(config.weakref) # assert "bool" in typ reveal_type(config.dict) # assert "bool" in typ reveal_type(config.cache_hash) # assert "bool" in typ reveal_type(config.tag) # assert "str" in typ and "int" in typ reveal_type(config.tag_field) # assert "str" in typ ########################################################## # defstruct # ########################################################## def check_defstruct() -> None: Test = msgspec.defstruct("Test", ["x", "y"]) for field in Test.__struct_fields__: reveal_type(field) # assert "str" in typ Test(1, y=2) def check_defstruct_field_types() -> None: Test = msgspec.defstruct( "Test", ("x", ("y", int), ("z", str, "default")) ) def check_defstruct_bases() -> None: class Base(msgspec.Struct): pass msgspec.defstruct("Test", ["x", "y"], bases=(Base,)) msgspec.defstruct("Test2", ["x", "y"], bases=None) def check_defstruct_namespace() -> None: msgspec.defstruct("Test", ["x", "y"], namespace={"classval": 1}) msgspec.defstruct("Test2", ["x", "y"], namespace=None) def check_defstruct_module() -> None: msgspec.defstruct("Test", ["x", "y"], module="mymod") msgspec.defstruct("Test2", ["x", "y"], module=None) def check_defstruct_config_options() -> None: Test = msgspec.defstruct( "Test", ("x", "y"), omit_defaults=True, forbid_unknown_fields=True, frozen=True, order=True, eq=True, kw_only=True, repr_omit_defaults=True, array_like=True, dict=True, weakref=True, cache_hash=True, gc=False, tag="mytag", tag_field="mytagfield", rename="lower" ) ########################################################## # msgspec.structs # ########################################################## def check_replace() -> None: class Test(msgspec.Struct): x: int y: int struct: int struct = Test(1, 2, 3) reveal_type(msgspec.structs.replace(struct)) # assert "Test" in typ reveal_type(msgspec.structs.replace(struct, x=1)) # assert "Test" in typ reveal_type(msgspec.structs.replace(struct, struct=1)) # assert "Test" in typ def check_asdict() -> None: class Test(msgspec.Struct): x: int y: int x = Test(1, 2) o = msgspec.structs.asdict(x) reveal_type(o) # assert "dict" in typ reveal_type(o["foo"]) # assert "Any" in typ def check_astuple() -> None: class Test(msgspec.Struct): x: int y: int x = Test(1, 2) o = msgspec.structs.astuple(x) reveal_type(o) # assert "tuple" in typ reveal_type(o[0]) # assert "Any" in typ def check_force_setattr() -> None: class Point(msgspec.Struct, frozen=True): x: int y: int obj = Point(1, 2) msgspec.structs.force_setattr(obj, "x", 3) def check_fields() -> None: class Test(msgspec.Struct): x: int y: int x = Test(1, 2) res1 = msgspec.structs.fields(x) reveal_type(res1) # assert "tuple" in typ.lower() and "FieldInfo" in typ res2 = msgspec.structs.fields(Test) reveal_type(res2) # assert "tuple" in typ.lower() and "FieldInfo" in typ for field in res1: reveal_type(field) # assert "FieldInfo" in typ reveal_type(field.required) # assert "bool" in typ reveal_type(field.name) # assert "str" in typ ########################################################## # Meta # ########################################################## def check_meta_constructor() -> None: msgspec.Meta() for val in [1, 1.5, None]: msgspec.Meta(gt=val) msgspec.Meta(ge=val) msgspec.Meta(lt=val) msgspec.Meta(le=val) msgspec.Meta(multiple_of=val) for val2 in ["string", None]: msgspec.Meta(pattern=val2) msgspec.Meta(title=val2) msgspec.Meta(description=val2) for val3 in [1, None]: msgspec.Meta(min_length=val3) msgspec.Meta(max_length=val3) for val4 in [True, False, None]: msgspec.Meta(tz=val4) for val5 in [[1, 2, 3], None]: msgspec.Meta(examples=val5) for val6 in [{"foo": "bar"}, None]: msgspec.Meta(extra_json_schema=val6) msgspec.Meta(extra=val6) def check_meta_attributes() -> None: c = msgspec.Meta() print(c.gt) print(c.ge) print(c.lt) print(c.le) print(c.multiple_of) print(c.pattern) print(c.min_length) print(c.max_length) print(c.tz) print(c.title) print(c.description) print(c.examples) print(c.extra_json_schema) print(c.extra) def check_meta_equal() -> None: c1 = msgspec.Meta() c2 = msgspec.Meta() if c1 == c2: print("ok") def check_meta_methods() -> None: c = msgspec.Meta() for name, val in c.__rich_repr__(): print(f"{name} = {val}") ########################################################## # Raw # ########################################################## def check_raw_constructor() -> None: r = msgspec.Raw() r2 = msgspec.Raw(b"test") r3 = msgspec.Raw(bytearray(b"test")) r4 = msgspec.Raw(memoryview(b"test")) r2 = msgspec.Raw("test") def check_raw_copy() -> None: r = msgspec.Raw() r2 = r.copy() reveal_type(r2) # assert "Raw" in typ def check_raw_methods() -> None: r1 = msgspec.Raw(b"a") r2 = msgspec.Raw(b"b") if r1 == r2: print(r1) m = memoryview(r1) # buffer protocol def check_raw_pass_to_decode() -> None: r = msgspec.Raw() res = msgspec.json.decode(r) res2 = msgspec.msgpack.decode(r) ########################################################## # MessagePack # ########################################################## def check_msgpack_Encoder_encode() -> None: enc = msgspec.msgpack.Encoder() b = enc.encode([1, 2, 3]) reveal_type(b) # assert "bytes" in typ def check_msgpack_Encoder_encode_into() -> None: enc = msgspec.msgpack.Encoder() buf = bytearray(48) enc.encode_into([1, 2, 3], buf) enc.encode_into([1, 2, 3], buf, 2) def check_msgpack_encode() -> None: b = msgspec.msgpack.encode([1, 2, 3]) reveal_type(b) # assert "bytes" in typ def check_msgpack_Decoder_decode_any() -> None: dec = msgspec.msgpack.Decoder() b = msgspec.msgpack.encode([1, 2, 3]) o = dec.decode(b) reveal_type(dec) # assert "Decoder" in typ and "Any" in typ reveal_type(o) # assert "Any" in typ def check_msgpack_Decoder_decode_typed() -> None: dec = msgspec.msgpack.Decoder(List[int]) b = msgspec.msgpack.encode([1, 2, 3]) o = dec.decode(b) reveal_type(dec) # assert "Decoder" in typ and ("List" in typ or "list" in typ) and "int" in typ reveal_type(o) # assert ("List" in typ or "list" in typ) and "int" in typ def check_msgpack_Decoder_decode_union() -> None: # Pyright doesn't require the annotation, but mypy does until TypeForm # is supported. This is mostly checking that no error happens here. dec: msgspec.msgpack.Decoder[Union[int, str]] = msgspec.msgpack.Decoder(Union[int, str]) o = dec.decode(b'') reveal_type(o) # assert ("int" in typ and "str" in typ) def check_msgpack_Decoder_decode_type_comment() -> None: dec = msgspec.msgpack.Decoder() # type: msgspec.msgpack.Decoder[List[int]] b = msgspec.msgpack.encode([1, 2, 3]) o = dec.decode(b) reveal_type(dec) # assert "Decoder" in typ and ("List" in typ or "list" in typ) and "int" in typ reveal_type(o) # assert ("List" in typ or "list" in typ) and "int" in typ def check_msgpack_decode_any() -> None: b = msgspec.msgpack.encode([1, 2, 3]) o = msgspec.msgpack.decode(b) reveal_type(o) # assert "Any" in typ def check_msgpack_decode_typed() -> None: b = msgspec.msgpack.encode([1, 2, 3]) o = msgspec.msgpack.decode(b, type=List[int]) reveal_type(o) # assert ("List" in typ or "list" in typ) and "int" in typ def check_msgpack_decode_from_buffer() -> None: msg = msgspec.msgpack.encode([1, 2, 3]) msgspec.toml.decode(memoryview(msg)) def check_msgpack_decode_typed_union() -> None: o: Union[int, str] = msgspec.msgpack.decode(b"", type=Union[int, str]) reveal_type(o) # assert "int" in typ and "str" in typ def check_msgpack_encode_enc_hook() -> None: msgspec.msgpack.encode(object(), enc_hook=lambda x: None) def check_msgpack_Encoder_enc_hook() -> None: msgspec.msgpack.Encoder(enc_hook=lambda x: None) def check_msgpack_order() -> None: enc = msgspec.msgpack.Encoder(order=None) msgspec.msgpack.Encoder(order='deterministic') msgspec.msgpack.Encoder(order='sorted') reveal_type(enc.order) # assert "deterministic" in typ msgspec.msgpack.encode({"a": 1}, order=None) msgspec.msgpack.encode({"a": 1}, order='deterministic') msgspec.msgpack.encode({"a": 1}, order='sorted') def check_msgpack_Encoder_decimal_format() -> None: enc = msgspec.msgpack.Encoder(decimal_format="string") msgspec.msgpack.Encoder(decimal_format="number") reveal_type(enc.decimal_format) # assert "string" in typ.lower() and "number" in typ.lower() def check_msgpack_Encoder_uuid_format() -> None: enc = msgspec.msgpack.Encoder(uuid_format="canonical") msgspec.msgpack.Encoder(uuid_format="hex") msgspec.msgpack.Encoder(uuid_format="bytes") reveal_type(enc.uuid_format) # assert all(s in typ.lower() for s in ("canonical", "hex", "bytes")) def check_msgpack_decode_dec_hook() -> None: def dec_hook(typ: Type, obj: Any) -> Any: return typ(obj) msgspec.msgpack.decode(b"test", dec_hook=dec_hook) msgspec.msgpack.Decoder(dec_hook=dec_hook) def check_msgpack_decode_ext_hook() -> None: def ext_hook(code: int, data: memoryview) -> Any: return pickle.loads(data) msgspec.msgpack.decode(b"test", ext_hook=ext_hook) msgspec.msgpack.Decoder(ext_hook=ext_hook) def check_msgpack_Decoder_strict() -> None: dec = msgspec.msgpack.Decoder(List[int], strict=False) reveal_type(dec.strict) # assert "bool" in typ def check_msgpack_decode_strict() -> None: out = msgspec.msgpack.decode(b'', type=List[int], strict=False) reveal_type(out) # assert "list" in typ.lower() def check_msgpack_Ext() -> None: ext = msgspec.msgpack.Ext(1, b"test") reveal_type(ext.code) # assert "int" in typ reveal_type(ext.data) # assert "bytes" in typ ########################################################## # JSON # ########################################################## def check_json_Encoder_encode() -> None: enc = msgspec.json.Encoder() b = enc.encode([1, 2, 3]) reveal_type(b) # assert "bytes" in typ def check_json_Encoder_encode_lines() -> None: enc = msgspec.json.Encoder() items = [{"x": 1}, 2] b = enc.encode_lines(items) b2 = enc.encode_lines((i for i in items)) reveal_type(b) # assert "bytes" in typ reveal_type(b2) # assert "bytes" in typ def check_json_Encoder_encode_into() -> None: enc = msgspec.json.Encoder() buf = bytearray(48) enc.encode_into([1, 2, 3], buf) enc.encode_into([1, 2, 3], buf, 2) def check_json_encode() -> None: b = msgspec.json.encode([1, 2, 3]) reveal_type(b) # assert "bytes" in typ def check_json_Decoder_decode_any() -> None: dec = msgspec.json.Decoder() b = msgspec.json.encode([1, 2, 3]) o = dec.decode(b) reveal_type(dec) # assert "Decoder" in typ and "Any" in typ reveal_type(o) # assert "Any" in typ def check_json_Decoder_decode_typed() -> None: dec = msgspec.json.Decoder(List[int]) b = msgspec.json.encode([1, 2, 3]) o = dec.decode(b) reveal_type(dec) # assert "Decoder" in typ and ("List" in typ or "list" in typ) and "int" in typ reveal_type(o) # assert ("List" in typ or "list" in typ) and "int" in typ def check_json_Decoder_decode_type_comment() -> None: dec = msgspec.json.Decoder() # type: msgspec.json.Decoder[List[int]] b = msgspec.json.encode([1, 2, 3]) o = dec.decode(b) reveal_type(dec) # assert "Decoder" in typ and ("List" in typ or "list" in typ) and "int" in typ reveal_type(o) # assert ("List" in typ or "list" in typ) and "int" in typ def check_json_Decoder_decode_union() -> None: dec: msgspec.json.Decoder[Union[int, str]] = msgspec.json.Decoder(Union[int, str]) o = dec.decode(b'') reveal_type(o) # assert ("int" in typ and "str" in typ) def check_json_Decoder_decode_from_str() -> None: dec = msgspec.json.Decoder(List[int]) o = dec.decode("[1, 2, 3]") reveal_type(o) # assert ("List" in typ or "list" in typ) and "int" in typ def check_json_Decoder_decode_lines_any() -> None: dec = msgspec.json.Decoder() o = dec.decode_lines(b'1\n2\n3') reveal_type(o) # assert "list" in typ.lower() and "any" in typ.lower() def check_json_Decoder_decode_lines_typed() -> None: dec = msgspec.json.Decoder(int) o = dec.decode_lines(b'1\n2\n3') reveal_type(o) # assert "list" in typ.lower() and "int" in typ.lower() def check_json_decode_any() -> None: b = msgspec.json.encode([1, 2, 3]) o = msgspec.json.decode(b) reveal_type(o) # assert "Any" in typ def check_json_decode_typed() -> None: b = msgspec.json.encode([1, 2, 3]) o = msgspec.json.decode(b, type=List[int]) reveal_type(o) # assert ("List" in typ or "list" in typ) and "int" in typ def check_json_decode_typed_union() -> None: o: Union[int, str] = msgspec.json.decode(b"", type=Union[int, str]) reveal_type(o) # assert "int" in typ and "str" in typ def check_json_decode_from_str() -> None: msgspec.json.decode("[1, 2, 3]") o = msgspec.json.decode("[1, 2, 3]", type=List[int]) reveal_type(o) # assert ("List" in typ or "list" in typ) and "int" in typ def check_json_decode_from_buffer() -> None: msgspec.json.decode(memoryview(b"[1, 2, 3]")) def check_json_encode_enc_hook() -> None: msgspec.json.encode(object(), enc_hook=lambda x: None) def check_json_Encoder_enc_hook() -> None: msgspec.json.Encoder(enc_hook=lambda x: None) def check_json_order() -> None: enc = msgspec.json.Encoder(order=None) msgspec.json.Encoder(order='deterministic') msgspec.json.Encoder(order='sorted') reveal_type(enc.order) # assert "deterministic" in typ msgspec.json.encode({"a": 1}, order=None) msgspec.json.encode({"a": 1}, order='deterministic') msgspec.json.encode({"a": 1}, order='sorted') def check_json_Encoder_decimal_format() -> None: enc = msgspec.json.Encoder(decimal_format="string") msgspec.json.Encoder(decimal_format="number") reveal_type(enc.decimal_format) # assert "string" in typ.lower() and "number" in typ.lower() def check_json_Encoder_uuid_format() -> None: enc = msgspec.json.Encoder(uuid_format="canonical") msgspec.json.Encoder(uuid_format="hex") reveal_type(enc.uuid_format) # assert all(s in typ.lower() for s in ("canonical", "hex")) def check_json_decode_dec_hook() -> None: def dec_hook(typ: Type, obj: Any) -> Any: return typ(obj) msgspec.json.decode(b"test", dec_hook=dec_hook) msgspec.json.Decoder(dec_hook=dec_hook) def check_json_Decoder_float_hook() -> None: msgspec.json.Decoder(float_hook=None) msgspec.json.Decoder(float_hook=float) dec = msgspec.json.Decoder(float_hook=decimal.Decimal) if dec.float_hook is not None: dec.float_hook("1.5") def check_json_Decoder_strict() -> None: dec = msgspec.json.Decoder(List[int], strict=False) reveal_type(dec.strict) # assert "bool" in typ def check_json_decode_strict() -> None: out = msgspec.json.decode(b'', type=List[int], strict=False) reveal_type(out) # assert "list" in typ.lower() def check_json_format() -> None: reveal_type(msgspec.json.format(b"test")) # assert "bytes" in typ reveal_type(msgspec.json.format(b"test", indent=4)) # assert "bytes" in typ reveal_type(msgspec.json.format("test")) # assert "str" in typ reveal_type(msgspec.json.format("test", indent=4)) # assert "str" in typ ########################################################## # YAML # ########################################################## def check_yaml_encode() -> None: b = msgspec.yaml.encode([1, 2, 3]) reveal_type(b) # assert "bytes" in typ def check_yaml_decode_any() -> None: o = msgspec.yaml.decode(b"[1, 2, 3]") reveal_type(o) # assert "Any" in typ def check_yaml_decode_typed() -> None: o = msgspec.yaml.decode(b"[1, 2, 3]", type=List[int]) reveal_type(o) # assert "list" in typ.lower() and "int" in typ def check_yaml_decode_typed_union() -> None: o: Union[int, str] = msgspec.yaml.decode(b"1", type=Union[int, str]) reveal_type(o) # assert "int" in typ and "str" in typ def check_yaml_decode_from_str() -> None: msgspec.yaml.decode("[1, 2, 3]") o = msgspec.yaml.decode("[1, 2, 3]", type=List[int]) reveal_type(o) # assert "list" in typ.lower() and "int" in typ def check_yaml_decode_from_buffer() -> None: msgspec.yaml.decode(memoryview(b"[1, 2, 3]")) def check_yaml_encode_enc_hook() -> None: msgspec.yaml.encode(object(), enc_hook=lambda x: None) def check_yaml_encode_order() -> None: msgspec.yaml.encode(object(), order=None) msgspec.yaml.encode(object(), order="deterministic") msgspec.yaml.encode(object(), order="sorted") def check_yaml_decode_dec_hook() -> None: def dec_hook(typ: Type, obj: Any) -> Any: return typ(obj) msgspec.yaml.decode(b"test", dec_hook=dec_hook) def check_yaml_decode_strict() -> None: out = msgspec.yaml.decode(b'', type=List[int], strict=False) reveal_type(out) # assert "list" in typ.lower() ########################################################## # TOML # ########################################################## def check_toml_encode() -> None: b = msgspec.toml.encode({"a": 1}) reveal_type(b) # assert "bytes" in typ def check_toml_decode_any() -> None: o = msgspec.toml.decode(b"a = 1") reveal_type(o) # assert "Any" in typ def check_toml_decode_typed() -> None: o = msgspec.toml.decode(b"a = 1", type=Dict[str, int]) reveal_type(o) # assert "dict" in typ.lower() and "int" in typ def check_toml_decode_from_str() -> None: msgspec.toml.decode("a = 1") o = msgspec.toml.decode("a = 1", type=Dict[str, int]) reveal_type(o) # assert "dict" in typ.lower() and "int" in typ def check_toml_decode_from_buffer() -> None: msgspec.toml.decode(memoryview(b"a = 1")) def check_toml_encode_enc_hook() -> None: msgspec.toml.encode(object(), enc_hook=lambda x: None) def check_toml_encode_order() -> None: msgspec.toml.encode(object(), order=None) msgspec.toml.encode(object(), order="deterministic") msgspec.toml.encode(object(), order="sorted") def check_toml_decode_dec_hook() -> None: def dec_hook(typ: Type, obj: Any) -> Any: return typ(obj) msgspec.toml.decode(b"a = 1", dec_hook=dec_hook) def check_toml_decode_strict() -> None: out = msgspec.toml.decode(b'', type=List[int], strict=False) reveal_type(out) # assert "list" in typ.lower() ########################################################## # msgspec.inspect # ########################################################## def check_inspect_type_info() -> None: o = msgspec.inspect.type_info(List[int]) reveal_type(o) # assert "Type" in typ msgspec.inspect.type_info(int) msgspec.inspect.type_info(int) msgspec.inspect.type_info(int) def check_inspect_multi_type_info() -> None: o = msgspec.inspect.multi_type_info([int, float]) reveal_type(o) # assert "Type" in typ and "tuple" in typ.lower() o2 = msgspec.inspect.multi_type_info((int, float)) reveal_type(o2) # assert "Type" in typ and "tuple" in typ.lower() msgspec.inspect.multi_type_info([int]) msgspec.inspect.multi_type_info([int]) msgspec.inspect.multi_type_info([int]) def max_depth(t: msgspec.inspect.Type, depth: int = 0) -> int: # This isn't actually a complete max_depth implementation if isinstance(t, msgspec.inspect.CollectionType): reveal_type(t.item_type) # assert "Type" in typ return max_depth(t.item_type, depth + 1) elif isinstance(t, msgspec.inspect.DictType): reveal_type(t.key_type) # assert "Type" in typ return max( max_depth(t.key_type, depth + 1), max_depth(t.value_type, depth + 1) ) elif isinstance(t, msgspec.inspect.TupleType): reveal_type(t.item_types) # assert "Type" in typ and "tuple" in typ.lower() return max(max_depth(a, depth + 1) for a in t.item_types) else: return depth def check_consume_inspect_types() -> None: t = msgspec.inspect.type_info(List[int]) o = max_depth(t) reveal_type(o) # assert "int" in typ.lower() t = msgspec.inspect.UnionType( (msgspec.inspect.IntType(), msgspec.inspect.NoneType()) ) reveal_type(t.includes_none) # assert "bool" in typ.lower() ########################################################## # JSON Schema # ########################################################## def check_json_schema() -> None: o1 = msgspec.json.schema(List[int]) reveal_type(o1) # assert ("Dict" in typ or "dict" in typ) o2 = msgspec.json.schema(List[int], schema_hook=lambda t: {"type": "object"}) reveal_type(o2) # assert ("Dict" in typ or "dict" in typ) def check_json_schema_components() -> None: s1, c1 = msgspec.json.schema_components([List[int]]) reveal_type(s1) # assert ("dict" in typ.lower()) and ("tuple" in typ.lower()) reveal_type(c1) # assert ("dict" in typ.lower()) s2, c2 = msgspec.json.schema_components([List[int]], ref_template="#/definitions/{name}") reveal_type(s2) # assert ("dict" in typ.lower()) and ("tuple" in typ.lower()) reveal_type(c2) # assert ("dict" in typ.lower()) s3, c3 = msgspec.json.schema_components( [List[int]], schema_hook=lambda t: {"type": "object"} ) reveal_type(s3) # assert ("dict" in typ.lower()) and ("tuple" in typ.lower()) reveal_type(c3) # assert ("dict" in typ.lower()) ########################################################## # Converters # ########################################################## def check_to_builtins() -> None: msgspec.to_builtins(1) msgspec.to_builtins({1: 2}, str_keys=False) msgspec.to_builtins(b"test", builtin_types=(bytes, bytearray, memoryview)) msgspec.to_builtins([1, 2, 3], enc_hook=lambda x: None) msgspec.to_builtins([1, 2, 3], order=None) msgspec.to_builtins([1, 2, 3], order="deterministic") msgspec.to_builtins([1, 2, 3], order="sorted") def check_convert() -> None: o1 = msgspec.convert(1, int) reveal_type(o1) # assert "int" in typ.lower() o2 = msgspec.convert([1, 2], List[float]) reveal_type(o2) # assert "list" in typ.lower() o3 = msgspec.convert(1, int, strict=False) reveal_type(o3) # assert "int" in typ.lower() o4 = msgspec.convert(1, int, from_attributes=True) reveal_type(o4) # assert "int" in typ.lower() o5 = msgspec.convert(1, int, dec_hook=lambda typ, x: None) reveal_type(o5) # assert "int" in typ.lower() o6 = msgspec.convert(1, int, builtin_types=(bytes, bytearray, memoryview)) reveal_type(o6) # assert "int" in typ.lower() o7 = msgspec.convert("1", int, str_keys=True) reveal_type(o7) # assert "int" in typ.lower() python-msgspec-0.19.0/tests/conftest.py000066400000000000000000000022361473355726200201430ustar00rootroot00000000000000import math import random import string import struct import pytest class Rand: """Random source, pulled out into fixture with repr so the seed is displayed on failing tests""" def __init__(self, seed=0): self.seed = seed or random.randint(0, 2**32 - 1) self.rand = random.Random(self.seed) def __repr__(self): return f"Rand({self.seed})" def str(self, n, m=0): """ str(n) -> random string of length `n`. str(n, m) -> random string between lengths `n` & `m` """ if m: n = self.rand.randint(n, m) return "".join(self.rand.choices(string.ascii_letters, k=n)) def bytes(self, n): """random bytes of length `n`""" return self.rand.getrandbits(8 * n).to_bytes(n, "little") def float(self): """random finite float""" while True: dbytes = self.rand.getrandbits(64).to_bytes(8, "big") x = struct.unpack("!d", dbytes)[0] if math.isfinite(x): return x def shuffle(self, obj): """random shuffle""" self.rand.shuffle(obj) @pytest.fixture def rand(): yield Rand() python-msgspec-0.19.0/tests/test_JSONTestSuite.py000066400000000000000000012673021473355726200220100ustar00rootroot00000000000000"""These test cases are from https://github.com/nst/JSONTestSuite. They don't check the correctness of the parsing, only whether a JSON message is accepted/rejected appropriately.""" import itertools import pytest import msgspec valid_cases = [ b"[1e-2]", b'["\\uD834\\uDd1e"]', b'["\xe2\x80\xa8"]', b'["\\u0061\\u30af\\u30EA\\u30b9"]', b'["\\""]', b"[1,null,null,null,2]", b'["\xe2\x82\xac\xf0\x9d\x84\x9e"]', b"[null]", b"[1E-2]", b'{"a":"b","a":"c"}', b"[1E+2]", b'{"a":[]}', b"[ 4]", b" [1]", b"[-1]", b'["\xe2\x80\xa9"]', b'{"foo\\u0000bar": 42}', b" [] ", b'["\\u2064"]', b'["\xcf\x80"]', b'["new\\u000Aline"]', b'["\\u002c"]', b'["\\uD83F\\uDFFE"]', b'["\\u0123"]', b"[1\n]", b"[20e1]", b'["\\u0022"]', b"[true]", b'["\\u0821"]', b'["\\uD801\\udc37"]', b'["\x7f"]', b"[123e65]", b'{"":0}', b'""', b'["\\uDBFF\\uDFFF"]', b"[-0]", b'["\\\\a"]', b"true", b"[123.456789]", b'["\\uFFFE"]', b'{"asd":"sdf"}', b"[]", b'["a"]', b"[-123]", b'["\\\\n"]', b"[1E22]", b'["\\u0012"]', b'["asd "]', b'["\\ud83d\\ude39\\ud83d\\udc8d"]', b'["\\u0060\\u012a\\u12AB"]', b'["\\"\\\\\\/\\b\\f\\n\\r\\t"]', b'["\\uA66D"]', b'"asd"', b"[0e+1]", b'{\n"a": "b"\n}', b'["\\\\u0000"]', b"[false]", b'[ "asd"]', b'["\\u200B"]', b'["new\\u00A0line"]', b"{}", b'["\xf0\x9b\xbf\xbf"]', b'["\xe2\x8d\x82\xe3\x88\xb4\xe2\x8d\x82"]', b"[1e+2]", b'{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}', b'["\\u005C"]', b"-0.1", b'["a\x7fa"]', b"[123.456e78]", b'["\xef\xbf\xbf"]', b'["asd"]', b'[null, 1, "1", {}]', b'["a"]\n', b"[123e45]", b"[123]", b'["\\uFFFF"]', b'["\xf4\x8f\xbf\xbf"]', b'[""]', b"42", b'["\\uFDD0"]', b'" "', b'["\\uDBFF\\uDFFE"]', b'{"asd":"sdf", "dfg":"fgh"}', b"null", b"[-0]", b'{ "min": -1.0e+28, "max": 1.0e+28 }', b'["a/*b*/c/*d//e"]', b'["\\u0000"]', b'{"a":"b","a":"b"}', b'{"title":"\\u041f\\u043e\\u043b\\u0442\\u043e\\u0440\\u0430 \\u0417\\u0435\\u043c\\u043b\\u0435\\u043a\\u043e\\u043f\\u0430" }', b"[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]\n", b"[0e1]", b"[[] ]", b"false", b"[2] ", ] invalid_cases = [ b"['single quote']", b'{"":', b'["\\\\\\"]', b"[1e\xe5]", b"[Infinity]", b"[1,]", b"[0.1.2]", b"{,", b"[++1234]", b"[-]", b"[1", b"[-01]", b'["\\uqqqq"]', b"[9.e+]", b"[-foo]", b'["a",\n4\n,1,', b'[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":\n', b'["\\uD800\\u1"]', b'{"x", null}', b"<.>", b"[+1]", b"[1.2a-3]", b"[-123.123foo]", b"[0x42]", b'[\\u0020"asd"]', b"{'a':0}", b"{]", b'{"a" "b"}', b'{[: "x"}\n', b"[tru]", b"[ false, tru", b'{"a":"b"}/**//', b"[nul]", b'{"a"', b"]", b"[\xe2\x81\xa0]", b"[\xff]", b"[1ea]", b'{"a":"b"}/**/', b"[0\xe5]\n", b"[1.0e]", b'["",]', b'["\\\t"]', b"{'a'", b'["\\\x00"]', b'{"a":"a', b'{"a":"a" 123}', b" ", b"{null:null,null:null}", b"[1.0e+]", b"[\xe2\x81\xa0]", b'["a', b"\xe5", b'["a\x00a"]', b'[""', b'{"a": true} "x"', b"", b"\xe9", b"[.2e-3]", b'["\\uD800\\uD800\\x"]', b'["\\x00"]', b"[012]", b"[0.e1]", b"[1.0e-]", b'["\\a"]', b"[1,\n1\n,1", b"[{}", b"[0x1]", b'{"a":"b"}//', b"[", b"[1 000.0]", b"[-1x]", b"1]", b'{"a" b}', b'["\\uD800\\u"]', b'{"a":"b"}#{}', b'{"x": true,', b"[0E+]", b"{}}", b"2@", b'"', b'{"a":"b"}#', b"[-2.]", b"[- 1]", b'"\\UA66D"', b'{"a":"b"}/', b"[1+2]", b"[a\xe5]", b'["\\uD834\\uDd"]', b"[.-1]", b'["\\uD800\\u1x"]', b'["new\nline"]', b"\xc3\xa5", b"[,1]", b"[\x00]", b"['", b"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[", b"[1,", b'["": 1]', b'["\\{["\\{["\\{["\\{', b"\xef\xbb{}", b'["\x0ba"\\f]', b"[.123]", b'["\\"]', b"[x", b"[2.e+3]", b"[+Inf]", b"[1,,]", b"[0E]", b"[ true, fals", b"{key: 'value'}", b'{"a', b"\xef\xbb\xbf", b"a\xc3\xa5", b"[1:2]", b"[-1.0.]", b'{"a":/*comment*/"b"}', b"[-Infinity]", b"[1eE2]", b"[ false, nul", b"[\\n]", b"[,", b"{[", b"[-NaN]", b"[NaN]", b'["a"', b"{", b'["x"', b'{"x"::"b"}', b"[][]", b'["\\\xe5"]', b'["x"]]', b'[ , ""]', b"[2.e3]", b"[0e+-1]", b"[,]", b'{"\xb9":"0",}', b'["\\u\xe5"]', b"[0e+]", b"[{", b"[1.8011670033376514H-308]", b'{"id":0,,,,,}', b'{ "foo" : "bar", "a" }', b"[0e]", b"[1]]", b'{"asd":"asd"', b'["\t"]', b"[fals]", b"[1 true]", b"{9999E9999:1}", b'["\\', b"[Inf]", b'["\\\xf0\x9f\x8c\x80"]', b"[1,,2]", b"[123\xe5]", b"[True]", b'{:"b"}', b"[-012]", b"[0.3e+]", b"abc", b'[""],', b'["asd]', b"[*]", b'{a: "b"}', b'[\\u000A""]', b'["\\u00A"]', b"*", b'["x", truth]', b"[\xef\xbc\x91]", b"[]", b"{1:1}", b"[0.3e]", b'{"id":0,}', b"[1]x", b"{\xf0\x9f\x87\xa8\xf0\x9f\x87\xad}", b"[1e1\xe5]", b"[2.e-3]", b"[\x0c]", b'["\\uD800\\"]', b'{"a":"b",,"c":"d"}', b"[1.]", b'""x', b"[-.123]", b"[\xc3\xa9]", b"123\x00", b"[3[4]]", b'["x",,]', b'{"a":', ] @pytest.mark.parametrize("case", valid_cases, ids=itertools.count()) def test_valid(case): msgspec.json.decode(case) @pytest.mark.parametrize("case", invalid_cases, ids=itertools.count()) def test_invalid(case): expected_errors = (msgspec.DecodeError, UnicodeDecodeError, RecursionError) with pytest.raises(expected_errors): msgspec.json.decode(case) python-msgspec-0.19.0/tests/test_common.py000066400000000000000000004316171473355726200206560ustar00rootroot00000000000000from __future__ import annotations import base64 import collections import datetime import decimal import enum import gc import sys import typing import uuid import weakref from collections import namedtuple from dataclasses import dataclass, field, make_dataclass from datetime import timedelta from typing import ( Annotated, ClassVar, Deque, Dict, Final, Generic, List, Literal, NamedTuple, NewType, Optional, Tuple, TypedDict, TypeVar, Union, ) import pytest from utils import temp_module, max_call_depth try: import attrs except ImportError: attrs = None import msgspec from msgspec import Meta, Struct, ValidationError, UNSET, UnsetType UTC = datetime.timezone.utc PY310 = sys.version_info[:2] >= (3, 10) PY311 = sys.version_info[:2] >= (3, 11) PY312 = sys.version_info[:2] >= (3, 12) py310_plus = pytest.mark.skipif(not PY310, reason="3.10+ only") py311_plus = pytest.mark.skipif(not PY311, reason="3.11+ only") py312_plus = pytest.mark.skipif(not PY312, reason="3.12+ only") T = TypeVar("T") def assert_eq(x, y): assert x == y assert type(x) is type(y) @pytest.fixture(params=["json", "msgpack"]) def proto(request): if request.param == "json": return msgspec.json elif request.param == "msgpack": return msgspec.msgpack try: from enum import StrEnum except ImportError: class StrEnum(str, enum.Enum): pass class FruitInt(enum.IntEnum): APPLE = 1 BANANA = 2 class FruitStr(enum.Enum): APPLE = "apple" BANANA = "banana" class VeggieInt(enum.IntEnum): CARROT = 1 LETTUCE = 2 class VeggieStr(enum.Enum): CARROT = "carrot" LETTUCE = "banana" class Person(Struct): first: str last: str age: int class PersonArray(Struct, array_like=True): first: str last: str age: int class PersonDict(TypedDict): first: str last: str age: int @dataclass class PersonDataclass: first: str last: str age: int class PersonTuple(NamedTuple): first: str last: str age: int class Custom: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, other): return self.x == other.x and self.y == other.y class TestEncodeSubclasses: def test_encode_dict_subclass(self, proto): class subclass(dict): pass for msg in [{}, {"a": 1, "b": 2}]: assert proto.encode(subclass(msg)) == proto.encode(msg) @pytest.mark.parametrize("cls", [list, tuple, set, frozenset]) def test_encode_sequence_subclass(self, cls, proto): class subclass(cls): pass for msg in [[], [1, 2]]: assert proto.encode(subclass(msg)) == proto.encode(cls(msg)) class TestDecoder: def test_decoder_runtime_type_parameters(self, proto): dec = proto.Decoder[int](int) assert isinstance(dec, proto.Decoder) msg = proto.encode(2) assert dec.decode(msg) == 2 def test_decoder_dec_hook_attribute(self, proto): def dec_hook(typ, obj): pass dec = proto.Decoder() assert dec.dec_hook is None dec = proto.Decoder(dec_hook=None) assert dec.dec_hook is None dec = proto.Decoder(dec_hook=dec_hook) assert dec.dec_hook is dec_hook def test_decoder_dec_hook_not_callable(self, proto): with pytest.raises(TypeError): proto.Decoder(dec_hook=1) def test_decode_dec_hook(self, proto): def dec_hook(typ, obj): assert typ is Custom return typ(*obj) msg = proto.encode([1, 2]) res = proto.decode(msg, type=Custom, dec_hook=dec_hook) assert res == Custom(1, 2) assert isinstance(res, Custom) def test_decoder_dec_hook(self, proto): called = False def dec_hook(typ, obj): nonlocal called called = True assert typ is Custom return Custom(*obj) dec = proto.Decoder(type=List[Custom], dec_hook=dec_hook) buf = proto.encode([[1, 2], [3, 4], [5, 6]]) msg = dec.decode(buf) assert called assert msg == [Custom(1, 2), Custom(3, 4), Custom(5, 6)] assert isinstance(msg[0], Custom) def test_decoder_dec_hook_optional_custom_type(self, proto): called = False def dec_hook(typ, obj): nonlocal called called = True dec = proto.Decoder(type=Optional[Custom], dec_hook=dec_hook) msg = dec.decode(proto.encode(None)) assert not called assert msg is None @pytest.mark.parametrize("err_cls", [TypeError, ValueError]) def test_decode_dec_hook_errors_wrapped(self, err_cls, proto): def dec_hook(typ, obj): assert obj == "some string" raise err_cls("Oh no!") msg = proto.encode("some string") with pytest.raises(msgspec.ValidationError, match="Oh no!") as rec: proto.decode(msg, type=Custom, dec_hook=dec_hook) assert rec.value.__cause__ is rec.value.__context__ assert type(rec.value.__cause__) is err_cls msg = proto.encode(["some string"]) with pytest.raises(msgspec.ValidationError, match=r"Oh no! - at `\$\[0\]`"): proto.decode(msg, type=List[Custom], dec_hook=dec_hook) def test_decode_dec_hook_errors_passthrough(self, proto): def dec_hook(typ, obj): assert obj == "some string" raise NotImplementedError("Oh no!") msg = proto.encode("some string") with pytest.raises(NotImplementedError, match="Oh no!"): proto.decode(msg, type=Custom, dec_hook=dec_hook) msg = proto.encode(["some string"]) with pytest.raises(NotImplementedError, match=r"Oh no!"): proto.decode(msg, type=List[Custom], dec_hook=dec_hook) def test_decode_dec_hook_wrong_type(self, proto): dec = proto.Decoder(type=Custom, dec_hook=lambda t, o: o) msg = proto.encode([1, 2]) with pytest.raises( msgspec.ValidationError, match="Expected `Custom`, got `list`", ): dec.decode(msg) def test_decode_dec_hook_wrong_type_in_struct(self, proto): class Test(Struct): point: Custom other: int dec = proto.Decoder(type=Test, dec_hook=lambda t, o: o) msg = proto.encode({"point": [1, 2], "other": 3}) with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msg) assert "Expected `Custom`, got `list` - at `$.point`" == str(rec.value) def test_decode_dec_hook_wrong_type_generic(self, proto): dec = proto.Decoder(type=Deque[int], dec_hook=lambda t, o: o) msg = proto.encode([1, 2, 3]) with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msg) assert "Expected `collections.deque`, got `list`" == str(rec.value) def test_decode_dec_hook_isinstance_errors(self, proto): class Metaclass(type): def __instancecheck__(self, obj): raise TypeError("Oh no!") class Custom(metaclass=Metaclass): pass dec = proto.Decoder(type=Custom) msg = proto.encode(1) with pytest.raises(TypeError, match="Oh no!"): dec.decode(msg) @pytest.mark.skipif( PY312, reason=( "Python 3.12 harcodes the C recursion limit, making this " "behavior harder to test in CI" ), ) class TestRecursion: @staticmethod def nested(n, is_array): if is_array: obj = [] for _ in range(n): obj = [obj] else: obj = {} for _ in range(n): obj = {"": obj} return obj @pytest.mark.parametrize("is_array", [True, False]) def test_encode_highly_recursive_msg_errors(self, is_array, proto): N = 200 obj = self.nested(N, is_array) # Errors if above the recursion limit with max_call_depth(N // 2): with pytest.raises(RecursionError): proto.encode(obj) # Works if below the recursion limit with max_call_depth(N * 2): proto.encode(obj) @pytest.mark.parametrize("is_array", [True, False]) def test_decode_highly_recursive_msg_errors(self, is_array, proto): """Ensure recursion is properly handled when decoding. Test case seen in https://github.com/ijl/orjson/issues/458.""" N = 200 obj = self.nested(N, is_array) with max_call_depth(N * 2): msg = proto.encode(obj) # Errors if above the recursion limit with max_call_depth(N // 2): with pytest.raises(RecursionError): proto.decode(msg) # Works if below the recursion limit with max_call_depth(N * 2): obj2 = proto.decode(msg) assert obj2 class TestThreadSafe: def test_encode_threadsafe(self, proto): class Nested: def __init__(self, x): self.x = x def enc_hook(obj): return base64.b64encode(enc.encode(obj.x)).decode("utf-8") enc = proto.Encoder(enc_hook=enc_hook) res = enc.encode({"x": Nested(1)}) sol = proto.encode({"x": base64.b64encode(proto.encode(1)).decode("utf-8")}) assert res == sol def test_decode_threadsafe(self, proto): class Custom: def __init__(self, node): self.node = node def __eq__(self, other): return type(other) is Custom and self.node == other.node def dec_hook(typ, obj): msg = base64.b64decode(obj) return Custom(dec.decode(msg)) dec = proto.Decoder(Tuple[Union[Custom, None], int], dec_hook=dec_hook) msg = proto.encode( (base64.b64encode(proto.encode((None, 1))).decode("utf-8"), 2) ) sol = (Custom((None, 1)), 2) res = dec.decode(msg) assert res == sol class TestIntEnum: def test_empty_errors(self, proto): class Empty(enum.IntEnum): pass with pytest.raises(TypeError, match="Enum types must have at least one item"): proto.Decoder(Empty) @pytest.mark.parametrize("base_cls", [enum.IntEnum, enum.Enum]) def test_encode(self, proto, base_cls): class Test(base_cls): A = 1 B = 2 assert proto.encode(Test.A) == proto.encode(1) @pytest.mark.parametrize("base_cls", [enum.IntEnum, enum.Enum]) def test_decode(self, proto, base_cls): class Test(base_cls): A = 1 B = 2 dec = proto.Decoder(Test) assert dec.decode(proto.encode(1)) is Test.A assert dec.decode(proto.encode(2)) is Test.B with pytest.raises(ValidationError, match="Invalid enum value 3"): dec.decode(proto.encode(3)) def test_decode_nested(self, proto): class Test(Struct): fruit: FruitInt dec = proto.Decoder(Test) dec.decode(proto.encode({"fruit": 1})) == Test(FruitInt.APPLE) with pytest.raises( ValidationError, match=r"Invalid enum value 3 - at `\$.fruit`" ): dec.decode(proto.encode({"fruit": 3})) def test_intenum_missing(self, proto): class Ex(enum.IntEnum): A = 1 B = 2 @classmethod def _missing_(cls, val): if val == 3: return cls.A elif val == -4: return cls.B elif val == 5: raise ValueError("oh no!") else: return None dec = proto.Decoder(Ex) def roundtrip(msg): return dec.decode(proto.encode(msg)) assert roundtrip(1) is Ex.A assert roundtrip(3) is Ex.A assert roundtrip(-4) is Ex.B with pytest.raises(ValidationError, match="Invalid enum value 5"): roundtrip(5) with pytest.raises(ValidationError, match="Invalid enum value 6"): roundtrip(6) def test_intflag(self, proto): class Ex(enum.IntFlag): A = 0b001 B = 0b010 C = 0b100 obj = Ex.A | Ex.C msg = proto.encode(obj) assert msg == proto.encode(int(obj)) assert proto.decode(msg, type=Ex) == obj def test_int_lookup_reused(self): class Test(enum.IntEnum): A = 1 B = 2 dec = msgspec.msgpack.Decoder(Test) # noqa count = sys.getrefcount(Test.__msgspec_cache__) dec2 = msgspec.msgpack.Decoder(Test) count2 = sys.getrefcount(Test.__msgspec_cache__) assert count2 == count + 1 # Reference count decreases when decoder is dropped del dec2 gc.collect() count3 = sys.getrefcount(Test.__msgspec_cache__) assert count == count3 def test_int_lookup_gc(self): class Test(enum.IntEnum): A = 1 B = 2 dec = msgspec.msgpack.Decoder(Test) assert gc.is_tracked(Test.__msgspec_cache__) # Deleting all references and running GC cleans up cycle ref = weakref.ref(Test) del Test del dec gc.collect() assert ref() is None @pytest.mark.parametrize( "values", [ [0, 1, 2, -(2**63) - 1], [0, 1, 2, 2**63], ], ) def test_int_lookup_values_out_of_range(self, values): myenum = enum.IntEnum("myenum", [(f"x{i}", v) for i, v in enumerate(values)]) with pytest.raises(NotImplementedError): msgspec.msgpack.Decoder(myenum) def test_msgspec_cache_overwritten(self): class Test(enum.IntEnum): A = 1 Test.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): msgspec.msgpack.Decoder(Test) @pytest.mark.parametrize( "values", [ [0], [1], [-1], [3, 4, 5, 2, 1], [4, 3, 1, 2, 7], [-4, -3, -2, -1, 0, 1, 2, 3, 4], [-4, -3, -1, -2, -7], [-4, -3, 1, 0, -2, -1], [2**63 - 1, 2**63 - 2, 2**63 - 3], [-(2**63) + 1, -(2**63) + 2, -(2**63) + 3], ], ) def test_compact(self, values): myenum = enum.IntEnum("myenum", [(f"x{i}", v) for i, v in enumerate(values)]) dec = msgspec.msgpack.Decoder(myenum) assert hasattr(myenum, "__msgspec_cache__") for val in myenum: msg = msgspec.msgpack.encode(val) val2 = dec.decode(msg) assert val == val2 for bad in [-1000, min(values) - 1, max(values) + 1, 1000]: with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(bad)) @pytest.mark.parametrize( "values", [ [-(2**63), 2**63 - 1, 0], [2**63 - 2, 2**63 - 3, 2**63 - 1], [2**63 - 2, 2**63 - 3, 2**63 - 1, 0, 2, 3, 4, 5, 6], ], ) def test_hashtable(self, values): myenum = enum.IntEnum("myenum", [(f"x{i}", v) for i, v in enumerate(values)]) dec = msgspec.msgpack.Decoder(myenum) assert hasattr(myenum, "__msgspec_cache__") for val in myenum: msg = msgspec.msgpack.encode(val) val2 = dec.decode(msg) assert val == val2 for bad in [-2000, -1, 1, 2000]: with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(bad)) @pytest.mark.parametrize( "values", [ [8, 16, 24, 32, 40, 48], [-8, -16, -24, -32, -40, -48], ], ) def test_hashtable_collisions(self, values): myenum = enum.IntEnum("myenum", [(f"x{i}", v) for i, v in enumerate(values)]) dec = msgspec.msgpack.Decoder(myenum) for val in myenum: msg = msgspec.msgpack.encode(val) val2 = dec.decode(msg) assert val == val2 for bad in [0, 7, 9, 56, -min(values), -max(values), 2**64 - 1, -(2**63)]: with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(bad)) class TestEnum: def test_empty_errors(self, proto): class Empty(enum.Enum): pass with pytest.raises(TypeError, match="Enum types must have at least one item"): proto.Decoder(Empty) def test_encode_complex(self, proto): class Complex(enum.Enum): A = 1.5 res = proto.encode(Complex.A) sol = proto.encode(1.5) assert res == sol res = proto.encode({Complex.A: 1}) sol = proto.encode({1.5: 1}) assert res == sol def test_decode_complex_errors(self, proto): class Complex(enum.Enum): A = 1.5 with pytest.raises(TypeError) as rec: proto.Decoder(Complex) assert "Enums must contain either all str or all int values" in str(rec.value) assert repr(Complex) in str(rec.value) @pytest.mark.parametrize( "values", [ [("A", 1), ("B", 2), ("C", "c")], [("A", "a"), ("B", "b"), ("C", 3)], ], ) def test_mixed_value_types_errors(self, values, proto): Bad = enum.Enum("Bad", values) with pytest.raises(TypeError) as rec: proto.Decoder(Bad) assert "Enums must contain either all str or all int values" in str(rec.value) assert repr(Bad) in str(rec.value) @pytest.mark.parametrize("base_cls", [StrEnum, enum.Enum]) def test_encode(self, proto, base_cls): class Test(base_cls): A = "apple" B = "banana" assert proto.encode(Test.A) == proto.encode("apple") @pytest.mark.parametrize("base_cls", [StrEnum, enum.Enum]) def test_decode(self, proto, base_cls): class Test(base_cls): A = "apple" B = "banana" dec = proto.Decoder(Test) assert dec.decode(proto.encode("apple")) is Test.A assert dec.decode(proto.encode("banana")) is Test.B with pytest.raises(ValidationError, match="Invalid enum value 'cherry'"): dec.decode(proto.encode("cherry")) def test_decode_nested(self, proto): class Test(Struct): fruit: FruitStr dec = proto.Decoder(Test) dec.decode(proto.encode({"fruit": "apple"})) == Test(FruitStr.APPLE) with pytest.raises( ValidationError, match=r"Invalid enum value 'cherry' - at `\$.fruit`", ): dec.decode(proto.encode({"fruit": "cherry"})) def test_str_lookup_reused(self): class Test(enum.Enum): A = "a" B = "b" dec = msgspec.msgpack.Decoder(Test) # noqa count = sys.getrefcount(Test.__msgspec_cache__) dec2 = msgspec.msgpack.Decoder(Test) count2 = sys.getrefcount(Test.__msgspec_cache__) assert count2 == count + 1 # Reference count decreases when decoder is dropped del dec2 gc.collect() count3 = sys.getrefcount(Test.__msgspec_cache__) assert count == count3 def test_str_lookup_gc(self): class Test(enum.Enum): A = "a" B = "b" dec = msgspec.msgpack.Decoder(Test) assert gc.is_tracked(Test.__msgspec_cache__) # Deleting all references and running GC cleans up cycle ref = weakref.ref(Test) del Test del dec gc.collect() assert ref() is None def test_msgspec_cache_overwritten(self): class Test(enum.Enum): A = 1 Test.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): msgspec.msgpack.Decoder(Test) @pytest.mark.parametrize("length", [2, 8, 16]) @pytest.mark.parametrize("nitems", [1, 3, 6, 12, 24, 48]) def test_random_enum_same_lengths(self, rand, length, nitems): def strgen(length): """Yields unique random fixed-length strings""" seen = set() while True: x = rand.str(length) if x in seen: continue seen.add(x) yield x unique_str = strgen(length).__next__ myenum = enum.Enum( "myenum", [(unique_str(), unique_str()) for _ in range(nitems)] ) dec = msgspec.msgpack.Decoder(myenum) for val in myenum: msg = msgspec.msgpack.encode(val.value) val2 = dec.decode(msg) assert val == val2 for _ in range(10): key = unique_str() with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(key)) # Try bad of different lengths for bad_length in [1, 7, 15, 30]: assert bad_length != length key = rand.str(bad_length) with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(key)) @pytest.mark.parametrize("nitems", [1, 3, 6, 12, 24, 48]) def test_random_enum_different_lengths(self, rand, nitems): def strgen(): """Yields unique random strings""" seen = set() while True: x = rand.str(1, 32) if x in seen: continue seen.add(x) yield x unique_str = strgen().__next__ myenum = enum.Enum( "myenum", [(unique_str(), unique_str()) for _ in range(nitems)] ) dec = msgspec.msgpack.Decoder(myenum) for val in myenum: msg = msgspec.msgpack.encode(val.value) val2 = dec.decode(msg) assert val == val2 for _ in range(10): key = unique_str() with pytest.raises(ValidationError): dec.decode(msgspec.msgpack.encode(key)) def test_enum_missing(self, proto): class Ex(enum.Enum): A = "a" B = "b" @classmethod def _missing_(cls, val): if val == "return-A": return cls.A elif val == "return-B": return cls.B elif val == "error": raise ValueError("oh no!") else: return None dec = proto.Decoder(Ex) def roundtrip(msg): return dec.decode(proto.encode(msg)) assert roundtrip("a") is Ex.A assert roundtrip("return-A") is Ex.A assert roundtrip("return-B") is Ex.B with pytest.raises(ValidationError, match="Invalid enum value 'error'"): roundtrip("error") with pytest.raises(ValidationError, match="Invalid enum value 'other'"): roundtrip("other") class TestLiterals: def test_empty_errors(self): with pytest.raises( TypeError, match="Literal types must have at least one item" ): msgspec.msgpack.Decoder(Literal[()]) @pytest.mark.parametrize( "values", [ [0, 1, 2, 2**63], [0, 1, 2, -(2**63) - 1], ], ) def test_int_literal_values_out_of_range(self, values): literal = Literal[tuple(values)] with pytest.raises(NotImplementedError): msgspec.msgpack.Decoder(literal) @pytest.mark.parametrize( "typ", [ Literal[1, False], Literal["ok", b"bad"], Literal[1, object()], Union[Literal[1, 2], Literal[3, False]], Union[Literal["one", "two"], Literal[3, False]], Literal[Literal[1, 2], Literal[3, False]], Literal[Literal["one", "two"], Literal[3, False]], Literal[1, 2, List[int]], Literal[1, 2, List], ], ) def test_invalid_values(self, typ): with pytest.raises(TypeError, match="not supported"): msgspec.msgpack.Decoder(typ) def test_decode_literal_int_str_and_none_uncached_and_cached(self): values = (45987, "an_unlikely_string", None) literal = Literal[values] assert not hasattr(literal, "__msgspec_cache__") uncached = msgspec.msgpack.Decoder(literal) assert hasattr(literal, "__msgspec_cache__") cached = msgspec.msgpack.Decoder(literal) for val in values: assert uncached.decode(msgspec.msgpack.encode(val)) == val assert cached.decode(msgspec.msgpack.encode(val)) == val def test_cache_refcounts(self): literal = Literal[1, 2, "three", "four"] dec = msgspec.msgpack.Decoder(literal) # noqa cache = literal.__msgspec_cache__ count = sys.getrefcount(cache) dec2 = msgspec.msgpack.Decoder(literal) assert sys.getrefcount(cache) == count del dec2 gc.collect() assert sys.getrefcount(cache) == count @pytest.mark.parametrize("val", [None, (), (1,), (1, 2), (1, 2, 3)]) def test_msgspec_cache_overwritten(self, val): literal = Literal["a", "highly", "improbable", "set", "of", "strings"] literal.__msgspec_cache__ = val with pytest.raises(RuntimeError, match="__msgspec_cache__"): msgspec.msgpack.Decoder(literal) def test_multiple_literals(self): integers = Literal[-1, -2, -3] strings = Literal["apple", "banana"] both = Union[integers, strings] dec = msgspec.msgpack.Decoder(both) assert not hasattr(both, "__msgspec_cache__") for val in [-1, -2, -3, "apple", "banana"]: assert dec.decode(msgspec.msgpack.encode(val)) == val with pytest.raises(ValidationError, match="Invalid enum value 4"): dec.decode(msgspec.msgpack.encode(4)) with pytest.raises(ValidationError, match="Invalid enum value 'carrot'"): dec.decode(msgspec.msgpack.encode("carrot")) def test_nested_literals(self): integers = Literal[-1, -2, -3] strings = Literal["apple", "banana"] both = Literal[integers, strings] dec = msgspec.msgpack.Decoder(both) assert hasattr(both, "__msgspec_cache__") for val in [-1, -2, -3, "apple", "banana"]: assert dec.decode(msgspec.msgpack.encode(val)) == val with pytest.raises(ValidationError, match="Invalid enum value 4"): dec.decode(msgspec.msgpack.encode(4)) with pytest.raises(ValidationError, match="Invalid enum value 'carrot'"): dec.decode(msgspec.msgpack.encode("carrot")) def test_mix_int_and_int_literal(self): dec = msgspec.msgpack.Decoder(Union[Literal[-1, 1], int]) for x in [-1, 1, 10]: assert dec.decode(msgspec.msgpack.encode(x)) == x def test_mix_str_and_str_literal(self): dec = msgspec.msgpack.Decoder(Union[Literal["a", "b"], str]) for x in ["a", "b", "c"]: assert dec.decode(msgspec.msgpack.encode(x)) == x class TestUnionTypeErrors: def test_decoder_unsupported_type(self, proto): with pytest.raises(TypeError): proto.Decoder(1) def test_decoder_validates_struct_definition_unsupported_types(self, proto): """Struct definitions aren't validated until first use""" class Test(Struct): a: 1 with pytest.raises(TypeError): proto.Decoder(Test) @pytest.mark.parametrize("typ", [Union[int, Deque], Union[Deque, int]]) def test_err_union_with_custom_type(self, typ, proto): with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "custom type" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize( "typ", [ Union[dict, Person], Union[Person, dict], Union[PersonDict, dict], Union[PersonDataclass, dict], Union[Person, PersonDict], ], ) def test_err_union_with_multiple_dict_like_types(self, typ, proto): with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "more than one dict-like type" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize( "typ", [ Union[PersonArray, list], Union[tuple, PersonArray], Union[PersonArray, PersonTuple], Union[PersonTuple, frozenset], ], ) def test_err_union_with_struct_array_like_and_array(self, typ, proto): with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "more than one array-like type" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize("types", [(FruitInt, int), (FruitInt, Literal[1, 2])]) def test_err_union_with_multiple_int_like_types(self, types, proto): typ = Union[types] with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "int-like" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize( "typ", [ str, Literal["one", "two"], datetime.datetime, datetime.date, datetime.time, uuid.UUID, ], ) def test_err_union_with_multiple_str_like_types(self, typ, proto): union = Union[FruitStr, typ] with pytest.raises(TypeError) as rec: proto.Decoder(union) assert "str-like" in str(rec.value) assert repr(union) in str(rec.value) @pytest.mark.parametrize( "typ,kind", [ (Union[FruitInt, VeggieInt], "int enum"), (Union[FruitStr, VeggieStr], "str enum"), (Union[Dict[int, float], dict], "dict"), (Union[List[int], List[float]], "array-like"), (Union[List[int], tuple], "array-like"), (Union[set, tuple], "array-like"), (Union[Tuple[int, ...], list], "array-like"), (Union[Tuple[int, float, str], set], "array-like"), (Union[Deque, int, Custom], "custom"), ], ) def test_err_union_conflicts(self, typ, kind, proto): with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert f"more than one {kind}" in str(rec.value) assert repr(typ) in str(rec.value) @py310_plus def test_310_union_types(self, proto): dec = proto.Decoder(int | str | None) for msg in [1, "abc", None]: assert dec.decode(proto.encode(msg)) == msg with pytest.raises(ValidationError): assert dec.decode(proto.encode(1.5)) class TestStructUnion: def test_err_union_struct_mix_array_like(self, proto): class Test1(Struct, tag=True, array_like=True): x: int class Test2(Struct, tag=True, array_like=False): x: int typ = Union[Test1, Test2] with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) assert "array_like" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) @pytest.mark.parametrize("tag1", [False, True]) def test_err_union_struct_not_tagged(self, array_like, tag1, proto): class Test1(Struct, tag=tag1, array_like=array_like): x: int class Test2(Struct, array_like=array_like): x: int typ = Union[Test1, Test2] with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) assert "must be tagged" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_err_union_conflict_with_basic_type(self, array_like, proto): class Test1(Struct, tag=True, array_like=array_like): x: int class Test2(Struct, tag=True, array_like=array_like): x: int other = list if array_like else dict typ = Union[Test1, Test2, other] with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) if array_like: assert "more than one array-like type" in str(rec.value) else: assert "more than one dict-like type" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_err_union_struct_different_fields(self, proto, array_like): class Test1(Struct, tag_field="foo", array_like=array_like): x: int class Test2(Struct, tag_field="bar", array_like=array_like): x: int typ = Union[Test1, Test2] with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) assert "the same `tag_field`" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_err_union_struct_mix_int_str_tags(self, proto, array_like): class Test1(Struct, tag=1, array_like=array_like): x: int class Test2(Struct, tag="two", array_like=array_like): x: int typ = Union[Test1, Test2] with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) assert "both `int` and `str` tags" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) @pytest.mark.parametrize( "tags", [ ("a", "b", "b"), ("a", "a", "b"), ("a", "b", "a"), (1, 2, 2), (1, 1, 2), (1, 2, 1), ], ) def test_err_union_struct_non_unique_tag_values(self, proto, array_like, tags): class Test1(Struct, tag=tags[0], array_like=array_like): x: int class Test2(Struct, tag=tags[1], array_like=array_like): x: int class Test3(Struct, tag=tags[2], array_like=array_like): x: int typ = Union[Test1, Test2, Test3] with pytest.raises(TypeError) as rec: proto.Decoder(typ) assert "not supported" in str(rec.value) assert "unique `tag`" in str(rec.value) assert repr(typ) in str(rec.value) @pytest.mark.parametrize( "tag1, tag2, unknown", [ ("Test1", "Test2", "Test3"), (0, 1, 2), (123, -123, 0), ], ) def test_decode_struct_union(self, proto, tag1, tag2, unknown): class Test1(Struct, tag=tag1): a: int b: int c: int = 0 class Test2(Struct, tag=tag2): x: int y: int dec = proto.Decoder(Union[Test1, Test2]) enc = proto.Encoder() # Tag can be in any position assert dec.decode(enc.encode({"type": tag1, "a": 1, "b": 2})) == Test1(1, 2) assert dec.decode(enc.encode({"a": 1, "type": tag1, "b": 2})) == Test1(1, 2) assert dec.decode(enc.encode({"x": 1, "y": 2, "type": tag2})) == Test2(1, 2) # Optional fields still work assert dec.decode(enc.encode({"type": tag1, "a": 1, "b": 2, "c": 3})) == Test1( 1, 2, 3 ) assert dec.decode(enc.encode({"a": 1, "b": 2, "c": 3, "type": tag1})) == Test1( 1, 2, 3 ) # Extra fields still ignored assert dec.decode(enc.encode({"a": 1, "b": 2, "d": 4, "type": tag1})) == Test1( 1, 2 ) # Tag missing with pytest.raises(ValidationError) as rec: dec.decode(enc.encode({"a": 1, "b": 2})) assert "missing required field `type`" in str(rec.value) # Tag wrong type with pytest.raises(ValidationError) as rec: dec.decode(enc.encode({"type": 123.456, "a": 1, "b": 2})) assert f"Expected `{type(tag1).__name__}`" in str(rec.value) assert "`$.type`" in str(rec.value) # Tag unknown with pytest.raises(ValidationError) as rec: dec.decode(enc.encode({"type": unknown, "a": 1, "b": 2})) assert f"Invalid value {unknown!r} - at `$.type`" == str(rec.value) @pytest.mark.parametrize( "tag1, tag2, tag3, unknown", [ ("Test1", "Test2", "Test3", "Test4"), (0, 1, 2, 3), (123, -123, 0, -1), ], ) def test_decode_struct_array_union(self, proto, tag1, tag2, tag3, unknown): class Test1(Struct, tag=tag1, array_like=True): a: int b: int c: int = 0 class Test2(Struct, tag=tag2, array_like=True): x: int y: int class Test3(Struct, tag=tag3, array_like=True): pass dec = proto.Decoder(Union[Test1, Test2, Test3]) enc = proto.Encoder() # Decoding works assert dec.decode(enc.encode([tag1, 1, 2])) == Test1(1, 2) assert dec.decode(enc.encode([tag2, 3, 4])) == Test2(3, 4) assert dec.decode(enc.encode([tag3])) == Test3() # Optional & Extra fields still respected assert dec.decode(enc.encode([tag1, 1, 2, 3])) == Test1(1, 2, 3) assert dec.decode(enc.encode([tag1, 1, 2, 3, 4])) == Test1(1, 2, 3) # Missing required field with pytest.raises(ValidationError) as rec: dec.decode(enc.encode([tag1, 1])) assert "Expected `array` of at least length 3, got 2" in str(rec.value) # Type error has correct field index with pytest.raises(ValidationError) as rec: dec.decode(enc.encode([tag1, 1, "bad", 2])) assert "Expected `int`, got `str` - at `$[2]`" == str(rec.value) # Tag missing with pytest.raises(ValidationError) as rec: dec.decode(enc.encode([])) assert "Expected `array` of at least length 1, got 0" == str(rec.value) # Tag wrong type with pytest.raises(ValidationError) as rec: dec.decode(enc.encode([123.456, 2, 3, 4])) assert f"Expected `{type(tag1).__name__}`" in str(rec.value) assert "`$[0]`" in str(rec.value) # Tag unknown with pytest.raises(ValidationError) as rec: dec.decode(enc.encode([unknown, 1, 2, 3])) assert f"Invalid value {unknown!r} - at `$[0]`" == str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_decode_struct_union_with_non_struct_types(self, array_like, proto): class Test1(Struct, tag=True, array_like=array_like): a: int b: int class Test2(Struct, tag=True, array_like=array_like): x: int y: int dec = proto.Decoder(Union[Test1, Test2, None, int, str]) enc = proto.Encoder() for msg in [Test1(1, 2), Test2(3, 4), None, 5, 6]: assert dec.decode(enc.encode(msg)) == msg with pytest.raises(ValidationError) as rec: dec.decode(enc.encode(True)) typ = "array" if array_like else "object" assert f"Expected `int | str | {typ} | null`, got `bool`" == str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_struct_union_cached(self, array_like, proto): from msgspec._core import _struct_lookup_cache as cache cache.clear() class Test1(Struct, tag=True, array_like=array_like): a: int b: int class Test2(Struct, tag=True, array_like=array_like): x: int y: int typ1 = Union[Test2, Test1] typ2 = Union[Test1, Test2] typ3 = Union[Test1, Test2, int, None] for typ in [typ1, typ2, typ3]: for msg in [Test1(1, 2), Test2(3, 4)]: assert proto.decode(proto.encode(msg), type=typ) == msg assert len(cache) == 1 assert frozenset((Test1, Test2)) in cache def test_struct_union_cache_evicted(self, proto): from msgspec._core import _struct_lookup_cache as cache MAX_CACHE_SIZE = 64 # XXX: update if hardcoded value in `_core.c` changes cache.clear() def call_with_new_types(): class Test1(Struct, tag=True): a: int class Test2(Struct, tag=True): x: int typ = (Test1, Test2) proto.decode(proto.encode(Test1(1)), type=Union[typ]) return frozenset(typ) first = call_with_new_types() assert first in cache # Fill up the cache for _ in range(MAX_CACHE_SIZE - 1): call_with_new_types() # Check that first item is still in cache and is first in order assert len(cache) == MAX_CACHE_SIZE assert first in cache assert first == list(cache.keys())[0] # Add a new item, causing an item to be popped from the cache new = call_with_new_types() assert len(cache) == MAX_CACHE_SIZE assert first not in cache assert frozenset(new) in cache class TestGenericStruct: def test_generic_struct_info_cached(self, proto): class Ex(Struct, Generic[T]): x: T typ = Ex[int] assert Ex[int] is typ dec = proto.Decoder(typ) info = typ.__msgspec_cache__ assert info is not None assert sys.getrefcount(info) == 4 # info + attr + decoder + func call dec2 = proto.Decoder(typ) assert typ.__msgspec_cache__ is info assert sys.getrefcount(info) == 5 del dec del dec2 assert sys.getrefcount(info) == 3 def test_generic_struct_invalid_types_not_cached(self, proto): class Ex(Struct, Generic[T]): x: Union[List[T], Tuple[float]] for typ in [Ex, Ex[int]]: for _ in range(2): with pytest.raises(TypeError, match="not supported"): proto.Decoder(typ) assert not hasattr(typ, "__msgspec_cache__") def test_msgspec_cache_overwritten(self, proto): class Ex(Struct, Generic[T]): x: T typ = Ex[int] typ.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): proto.Decoder(typ) @pytest.mark.parametrize("array_like", [False, True]) def test_generic_struct(self, proto, array_like): class Ex(Struct, Generic[T], array_like=array_like): x: T y: List[T] sol = Ex(1, [1, 2]) msg = proto.encode(sol) res = proto.decode(msg, type=Ex) assert res == sol res = proto.decode(msg, type=Ex[int]) assert res == sol res = proto.decode(msg, type=Ex[Union[int, str]]) assert res == sol res = proto.decode(msg, type=Ex[float]) assert type(res.x) is float with pytest.raises(ValidationError, match="Expected `str`, got `int`"): proto.decode(msg, type=Ex[str]) @pytest.mark.parametrize("array_like", [False, True]) def test_recursive_generic_struct(self, proto, array_like): source = f""" from __future__ import annotations from typing import Union, Generic, TypeVar from msgspec import Struct T = TypeVar("T") class Ex(Struct, Generic[T], array_like={array_like}): a: T b: Union[Ex[T], None] """ with temp_module(source) as mod: msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) msg2 = mod.Ex(a=1, b=mod.Ex(a="bad", b=None)) assert proto.decode(proto.encode(msg), type=mod.Ex) == msg assert proto.decode(proto.encode(msg2), type=mod.Ex) == msg2 assert proto.decode(proto.encode(msg), type=mod.Ex[int]) == msg with pytest.raises(ValidationError) as rec: proto.decode(proto.encode(msg2), type=mod.Ex[int]) if array_like: assert "`$[1][0]`" in str(rec.value) else: assert "`$.b.a`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) @pytest.mark.parametrize("array_like", [False, True]) def test_generic_struct_union(self, proto, array_like): class Test1(Struct, Generic[T], tag=True, array_like=array_like): a: Union[T, None] b: int class Test2(Struct, Generic[T], tag=True, array_like=array_like): x: T y: int typ = Union[Test1[T], Test2[T]] msg1 = Test1(1, 2) s1 = proto.encode(msg1) msg2 = Test2("three", 4) s2 = proto.encode(msg2) msg3 = Test1(None, 4) s3 = proto.encode(msg3) assert proto.decode(s1, type=typ) == msg1 assert proto.decode(s2, type=typ) == msg2 assert proto.decode(s3, type=typ) == msg3 assert proto.decode(s1, type=typ[int]) == msg1 assert proto.decode(s3, type=typ[int]) == msg3 assert proto.decode(s2, type=typ[str]) == msg2 assert proto.decode(s3, type=typ[str]) == msg3 with pytest.raises(ValidationError) as rec: proto.decode(s1, type=typ[str]) assert "Expected `str | null`, got `int`" in str(rec.value) loc = "$[1]" if array_like else "$.a" assert loc in str(rec.value) with pytest.raises(ValidationError) as rec: proto.decode(s2, type=typ[int]) assert "Expected `int`, got `str`" in str(rec.value) loc = "$[1]" if array_like else "$.x" assert loc in str(rec.value) def test_unbound_typevars_use_bound_if_set(self, proto): T = TypeVar("T", bound=Union[int, str]) dec = proto.Decoder(List[T]) sol = [1, "two", 3, "four"] msg = proto.encode(sol) assert dec.decode(msg) == sol bad = proto.encode([1, {}]) with pytest.raises( ValidationError, match=r"Expected `int \| str`, got `object` - at `\$\[1\]`", ): dec.decode(bad) def test_unbound_typevars_with_constraints_unsupported(self, proto): T = TypeVar("T", int, str) with pytest.raises(TypeError) as rec: proto.Decoder(List[T]) assert "Unbound TypeVar `~T` has constraints" in str(rec.value) class TestStructPostInit: @pytest.mark.parametrize("array_like", [False, True]) @pytest.mark.parametrize("union", [False, True]) def test_struct_post_init(self, array_like, union, proto): count = 0 singleton = object() class Ex(Struct, array_like=array_like, tag=union): x: int def __post_init__(self): nonlocal count count += 1 return singleton if union: class Ex2(Struct, array_like=array_like, tag=True): pass typ = Union[Ex, Ex2] else: typ = Ex msg = Ex(1) buf = proto.encode(msg) res = proto.decode(buf, type=typ) assert res == msg assert count == 2 # 1 for Ex(), 1 for decode assert sys.getrefcount(singleton) == 2 # 1 for ref, 1 for call @pytest.mark.parametrize("array_like", [False, True]) @pytest.mark.parametrize("union", [False, True]) @pytest.mark.parametrize("exc_class", [ValueError, TypeError, OSError]) def test_struct_post_init_errors(self, array_like, union, exc_class, proto): error = False class Ex(Struct, array_like=array_like, tag=union): x: int def __post_init__(self): if error: raise exc_class("Oh no!") if union: class Ex2(Struct, array_like=array_like, tag=True): pass typ = Union[Ex, Ex2] else: typ = Ex msg = proto.encode([Ex(1)]) error = True if exc_class in (ValueError, TypeError): expected = ValidationError else: expected = exc_class with pytest.raises(expected, match="Oh no!") as rec: proto.decode(msg, type=List[typ]) if expected is ValidationError: assert "- at `$[0]`" in str(rec.value) @pytest.fixture(params=["dataclass", "attrs"]) def decorator(request): if request.param == "dataclass": return dataclass elif request.param == "attrs": if attrs is None: pytest.skip(reason="attrs not installed") return attrs.define class TestGenericDataclassOrAttrs: def test_generic_info_cached(self, decorator, proto): @decorator class Ex(Generic[T]): x: T typ = Ex[int] assert Ex[int] is typ dec = proto.Decoder(typ) info = typ.__msgspec_cache__ assert info is not None assert sys.getrefcount(info) == 4 # info + attr + decoder + func call dec2 = proto.Decoder(typ) assert typ.__msgspec_cache__ is info assert sys.getrefcount(info) == 5 del dec del dec2 assert sys.getrefcount(info) == 3 def test_generic_invalid_types_not_cached(self, decorator, proto): @decorator class Ex(Generic[T]): x: Union[List[T], Tuple[float]] for typ in [Ex, Ex[int]]: for _ in range(2): with pytest.raises(TypeError, match="not supported"): proto.Decoder(typ) assert not hasattr(typ, "__msgspec_cache__") def test_msgspec_cache_overwritten(self, decorator, proto): @decorator class Ex(Generic[T]): x: T typ = Ex[int] typ.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): proto.Decoder(typ) def test_generic_dataclass(self, decorator, proto): @decorator class Ex(Generic[T]): x: T y: List[T] sol = Ex(1, [1, 2]) msg = proto.encode(sol) res = proto.decode(msg, type=Ex) assert res == sol res = proto.decode(msg, type=Ex[int]) assert res == sol res = proto.decode(msg, type=Ex[Union[int, str]]) assert res == sol res = proto.decode(msg, type=Ex[float]) assert type(res.x) is float with pytest.raises(ValidationError, match="Expected `str`, got `int`"): proto.decode(msg, type=Ex[str]) @pytest.mark.parametrize("module", ["dataclasses", "attrs"]) def test_recursive_generic(self, module, proto): pytest.importorskip(module) if module == "dataclasses": import_ = "from dataclasses import dataclass as decorator" else: import_ = "from attrs import define as decorator" source = f""" from __future__ import annotations from typing import Union, Generic, TypeVar from msgspec import Struct {import_} T = TypeVar("T") @decorator class Ex(Generic[T]): a: T b: Union[Ex[T], None] """ with temp_module(source) as mod: msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) msg2 = mod.Ex(a=1, b=mod.Ex(a="bad", b=None)) assert proto.decode(proto.encode(msg), type=mod.Ex) == msg assert proto.decode(proto.encode(msg2), type=mod.Ex) == msg2 assert proto.decode(proto.encode(msg), type=mod.Ex[int]) == msg with pytest.raises(ValidationError) as rec: proto.decode(proto.encode(msg2), type=mod.Ex[int]) assert "`$.b.a`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) def test_unbound_typevars_use_bound_if_set(self, proto): T = TypeVar("T", bound=Union[int, str]) dec = proto.Decoder(List[T]) sol = [1, "two", 3, "four"] msg = proto.encode(sol) assert dec.decode(msg) == sol bad = proto.encode([1, {}]) with pytest.raises( ValidationError, match=r"Expected `int \| str`, got `object` - at `\$\[1\]`", ): dec.decode(bad) def test_unbound_typevars_with_constraints_unsupported(self, proto): T = TypeVar("T", int, str) with pytest.raises(TypeError) as rec: proto.Decoder(List[T]) assert "Unbound TypeVar `~T` has constraints" in str(rec.value) class TestStructOmitDefaults: def test_omit_defaults(self, proto): class Test(Struct, omit_defaults=True): a: int = 0 b: bool = False c: Optional[str] = None d: list = [] e: Union[list, set] = set() f: dict = {} cases = [ (Test(), {}), (Test(1), {"a": 1}), (Test(1, False), {"a": 1}), (Test(1, True), {"a": 1, "b": True}), (Test(1, c=None), {"a": 1}), (Test(1, c="test"), {"a": 1, "c": "test"}), (Test(1, d=[1]), {"a": 1, "d": [1]}), (Test(1, e={1}), {"a": 1, "e": [1]}), (Test(1, e=[]), {"a": 1, "e": []}), (Test(1, f={"a": 1}), {"a": 1, "f": {"a": 1}}), ] for obj, sol in cases: res = proto.decode(proto.encode(obj)) assert res == sol @pytest.mark.parametrize("typ", [tuple, list, set, frozenset, dict]) def test_omit_defaults_collections(self, proto, typ): """Check that using empty collections as default values are detected regardless if they're specified by value or as a default_factory.""" class Test(Struct, omit_defaults=True): a: typ = msgspec.field(default_factory=typ) b: typ = msgspec.field(default=typ()) c: typ = typ() ex = {"x": 1} if typ is dict else [1] assert proto.encode(Test()) == proto.encode({}) for n in ["a", "b", "c"]: assert proto.encode(Test(**{n: typ(ex)})) == proto.encode({n: ex}) def test_omit_defaults_positional(self, proto): class Test(Struct, omit_defaults=True): a: int b: bool = False cases = [ (Test(1), {"a": 1}), (Test(1, False), {"a": 1}), (Test(1, True), {"a": 1, "b": True}), ] for obj, sol in cases: res = proto.decode(proto.encode(obj)) assert res == sol def test_omit_defaults_tagged(self, proto): class Test(Struct, omit_defaults=True, tag=True): a: int b: bool = False cases = [ (Test(1), {"type": "Test", "a": 1}), (Test(1, False), {"type": "Test", "a": 1}), (Test(1, True), {"type": "Test", "a": 1, "b": True}), ] for obj, sol in cases: res = proto.decode(proto.encode(obj)) assert res == sol def test_omit_defaults_ignored_for_array_like(self, proto): class Test(Struct, omit_defaults=True, array_like=True): a: int b: bool = False cases = [ (Test(1), [1, False]), (Test(1, False), [1, False]), (Test(1, True), [1, True]), ] for obj, sol in cases: res = proto.decode(proto.encode(obj)) assert res == sol class TestStructForbidUnknownFields: def test_forbid_unknown_fields(self, proto): class Test(Struct, forbid_unknown_fields=True): x: int y: int good = Test(1, 2) assert proto.decode(proto.encode(good), type=Test) == good bad = proto.encode({"x": 1, "y": 2, "z": 3}) with pytest.raises(ValidationError, match="Object contains unknown field `z`"): proto.decode(bad, type=Test) def test_forbid_unknown_fields_array_like(self, proto): class Test(Struct, forbid_unknown_fields=True, array_like=True): x: int y: int good = Test(1, 2) assert proto.decode(proto.encode(good), type=Test) == good bad = proto.encode([1, 2, 3]) with pytest.raises( ValidationError, match="Expected `array` of at most length 2" ): proto.decode(bad, type=Test) class PointUpper(Struct, rename="upper"): x: int y: int class TestStructRename: def test_rename_encode_struct(self, proto): res = proto.encode(PointUpper(1, 2)) exp = proto.encode({"X": 1, "Y": 2}) assert res == exp def test_rename_decode_struct(self, proto): msg = proto.encode({"X": 1, "Y": 2}) res = proto.decode(msg, type=PointUpper) assert res == PointUpper(1, 2) def test_rename_decode_struct_wrong_type(self, proto): msg = proto.encode({"X": 1, "Y": "bad"}) with pytest.raises(ValidationError) as rec: proto.decode(msg, type=PointUpper) assert "Expected `int`, got `str` - at `$.Y`" == str(rec.value) def test_rename_decode_struct_missing_field(self, proto): msg = proto.encode({"X": 1}) with pytest.raises(ValidationError) as rec: proto.decode(msg, type=PointUpper) assert "Object missing required field `Y`" == str(rec.value) class TestStructKeywordOnly: def test_keyword_only_object(self, proto): class Test(Struct, kw_only=True): a: int b: int = 2 c: int d: int = 4 sol = Test(a=1, b=2, c=3, d=4) msg = proto.encode({"a": 1, "b": 2, "c": 3, "d": 4}) res = proto.decode(msg, type=Test) assert res == sol msg = proto.encode({"a": 1, "c": 3}) res = proto.decode(msg, type=Test) assert res == sol sol = Test(a=1, b=3, c=5) msg = proto.encode({"a": 1, "b": 3, "c": 5}) res = proto.decode(msg, type=Test) assert res == sol msg = proto.encode({"a": 1, "b": 2}) with pytest.raises( ValidationError, match="missing required field `c`", ): proto.decode(msg, type=Test) msg = proto.encode({"c": 1, "b": 2}) with pytest.raises( ValidationError, match="missing required field `a`", ): proto.decode(msg, type=Test) def test_keyword_only_array(self, proto): class Test(Struct, kw_only=True, array_like=True): a: int b: int = 2 c: int d: int = 4 msg = proto.encode([5, 6, 7, 8]) res = proto.decode(msg, type=Test) assert res == Test(a=5, b=6, c=7, d=8) msg = proto.encode([5, 6, 7]) res = proto.decode(msg, type=Test) assert res == Test(a=5, b=6, c=7, d=4) msg = proto.encode([5, 6]) with pytest.raises( ValidationError, match="Expected `array` of at least length 3, got 2", ): proto.decode(msg, type=Test) msg = proto.encode([]) with pytest.raises( ValidationError, match="Expected `array` of at least length 3, got 0", ): proto.decode(msg, type=Test) class TestStructDefaults: def test_struct_defaults(self, proto): class Test(Struct): a: int = 1 b: list = [] c: int = msgspec.field(default=2) d: dict = msgspec.field(default_factory=dict) sol = Test() res = proto.decode(proto.encode(sol), type=Test) assert res == sol res = proto.decode(proto.encode({}), type=Test) assert res == sol def test_struct_default_factory_errors(self, proto): def bad(): raise ValueError("Oh no!") class Test(Struct): a: int = msgspec.field(default_factory=bad) msg = proto.encode({}) with pytest.raises(Exception, match="Oh no!"): proto.decode(msg, type=Test) class TestTypedDict: def test_type_cached(self, proto): class Ex(TypedDict): a: int b: str msg = {"a": 1, "b": "two"} dec = proto.Decoder(Ex) info = Ex.__msgspec_cache__ assert info is not None dec2 = proto.Decoder(Ex) assert Ex.__msgspec_cache__ is info assert dec.decode(proto.encode(msg)) == msg assert dec2.decode(proto.encode(msg)) == msg def test_msgspec_cache_overwritten(self, proto): class Ex(TypedDict): x: int Ex.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): proto.Decoder(Ex) def test_multiple_typeddict_errors(self, proto): class Ex1(TypedDict): a: int class Ex2(TypedDict): b: int with pytest.raises(TypeError, match="may not contain more than one TypedDict"): proto.Decoder(Union[Ex1, Ex2]) def test_subtype_error(self, proto): class Ex(TypedDict): a: int b: Union[list, tuple] with pytest.raises(TypeError, match="may not contain more than one array-like"): proto.Decoder(Ex) assert not hasattr(Ex, "__msgspec_cache__") def test_recursive_type(self, proto): source = """ from __future__ import annotations from typing import TypedDict, Union class Ex(TypedDict): a: int b: Union[Ex, None] """ with temp_module(source) as mod: msg = {"a": 1, "b": {"a": 2, "b": None}} dec = proto.Decoder(mod.Ex) assert dec.decode(proto.encode(msg)) == msg with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"a": 1, "b": {"a": "bad"}})) assert "`$.b.a`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) def test_total_true(self, proto): class Ex(TypedDict): a: int b: str dec = proto.Decoder(Ex) x = {"a": 1, "b": "two"} assert dec.decode(proto.encode(x)) == x x2 = {"a": 1, "b": "two", "c": "extra"} assert dec.decode(proto.encode(x2)) == x with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"b": "two"})) assert "Object missing required field `a`" == str(rec.value) with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"a": 1, "b": 2})) assert "Expected `str`, got `int` - at `$.b`" == str(rec.value) def test_duplicate_keys(self, proto): """Validating if all required keys are present is done with a count. We need to ensure that duplicate required keys don't increment the count, masking a missing field.""" class Ex(TypedDict): a: int b: str dec = proto.Decoder(Ex) temp = proto.encode({"a": 1, "b": "two", "x": 2}) msg = temp.replace(b"x", b"a") assert dec.decode(msg) == {"a": 2, "b": "two"} msg = temp.replace(b"x", b"a").replace(b"b", b"c") with pytest.raises(ValidationError) as rec: dec.decode(msg) assert "Object missing required field `b`" == str(rec.value) def test_total_false(self, proto): class Ex(TypedDict, total=False): a: int b: str dec = proto.Decoder(Ex) x = {"a": 1, "b": "two"} assert dec.decode(proto.encode(x)) == x x2 = {"a": 1, "b": "two", "c": "extra"} assert dec.decode(proto.encode(x2)) == x x3 = {"b": "two"} assert dec.decode(proto.encode(x3)) == x3 x4 = {} assert dec.decode(proto.encode(x4)) == x4 @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_total_partially_optional(self, proto, use_typing_extensions): if use_typing_extensions: tex = pytest.importorskip("typing_extensions") cls = tex.TypedDict else: cls = TypedDict class Base(cls): a: int b: str class Ex(Base, total=False): c: str dec = proto.Decoder(Ex) x = {"a": 1, "b": "two", "c": "extra"} assert dec.decode(proto.encode(x)) == x x2 = {"a": 1, "b": "two"} assert dec.decode(proto.encode(x2)) == x2 with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"b": "two"})) assert "Object missing required field `a`" == str(rec.value) @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_required_and_notrequired(self, proto, use_typing_extensions): if use_typing_extensions: module = "typing_extensions" else: module = "typing" ns = pytest.importorskip(module) if not hasattr(ns, "Required"): pytest.skip(f"{module}.Required is not available") source = f""" from __future__ import annotations from {module} import TypedDict, Required, NotRequired class Base(TypedDict): a: int b: NotRequired[str] class Ex(Base, total=False): c: str d: Required[bool] """ with temp_module(source) as mod: dec = proto.Decoder(mod.Ex) x = {"a": 1, "b": "two", "c": "extra", "d": False} assert dec.decode(proto.encode(x)) == x x2 = {"a": 1, "d": False} assert dec.decode(proto.encode(x2)) == x2 with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"d": False})) assert "Object missing required field `a`" == str(rec.value) with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"a": 2})) assert "Object missing required field `d`" == str(rec.value) def test_keys_are_their_interned_values(self, proto): """Ensure that we're not allocating new keys here, but reusing the existing keys on the TypedDict schema""" class Ex(TypedDict): key_name_1: int key_name_2: int dec = proto.Decoder(Ex) msg = dec.decode(proto.encode({"key_name_1": 1, "key_name_2": 2})) for k1, k2 in zip(sorted(Ex.__annotations__), sorted(msg)): assert k1 is k2 def test_generic_typeddict_info_cached(self, proto): TypedDict = pytest.importorskip("typing_extensions").TypedDict class Ex(TypedDict, Generic[T]): x: T typ = Ex[int] assert Ex[int] is typ dec = proto.Decoder(typ) info = typ.__msgspec_cache__ assert info is not None assert sys.getrefcount(info) == 4 # info + attr + decoder + func call dec2 = proto.Decoder(typ) assert typ.__msgspec_cache__ is info assert sys.getrefcount(info) == 5 del dec del dec2 assert sys.getrefcount(info) == 3 def test_generic_typeddict_invalid_types_not_cached(self, proto): TypedDict = pytest.importorskip("typing_extensions").TypedDict class Ex(TypedDict, Generic[T]): x: Union[List[T], Tuple[float]] for typ in [Ex, Ex[int]]: for _ in range(2): with pytest.raises(TypeError, match="not supported"): proto.Decoder(typ) assert not hasattr(typ, "__msgspec_cache__") def test_generic_typeddict(self, proto): TypedDict = pytest.importorskip("typing_extensions").TypedDict class Ex(TypedDict, Generic[T]): x: T y: List[T] sol = Ex(x=1, y=[1, 2]) msg = proto.encode(sol) res = proto.decode(msg, type=Ex) assert res == sol res = proto.decode(msg, type=Ex[int]) assert res == sol res = proto.decode(msg, type=Ex[Union[int, str]]) assert res == sol res = proto.decode(msg, type=Ex[float]) assert type(res["x"]) is float with pytest.raises(ValidationError, match="Expected `str`, got `int`"): proto.decode(msg, type=Ex[str]) def test_recursive_generic_typeddict(self, proto): pytest.importorskip("typing_extensions") source = """ from __future__ import annotations from typing import Union, Generic, TypeVar from typing_extensions import TypedDict T = TypeVar("T") class Ex(TypedDict, Generic[T]): a: T b: Union[Ex[T], None] """ with temp_module(source) as mod: msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) msg2 = mod.Ex(a=1, b=mod.Ex(a="bad", b=None)) assert proto.decode(proto.encode(msg), type=mod.Ex) == msg assert proto.decode(proto.encode(msg2), type=mod.Ex) == msg2 assert proto.decode(proto.encode(msg), type=mod.Ex[int]) == msg with pytest.raises(ValidationError) as rec: proto.decode(proto.encode(msg2), type=mod.Ex[int]) assert "`$.b.a`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) class TestNamedTuple: def test_type_cached(self, proto): class Ex(NamedTuple): a: int b: str msg = (1, "two") dec = proto.Decoder(Ex) info = Ex.__msgspec_cache__ assert info is not None dec2 = proto.Decoder(Ex) assert Ex.__msgspec_cache__ is info assert dec.decode(proto.encode(msg)) == msg assert dec2.decode(proto.encode(msg)) == msg def test_msgspec_cache_overwritten(self, proto): class Ex(NamedTuple): x: int Ex.__msgspec_cache__ = 1 with pytest.raises(RuntimeError, match="__msgspec_cache__"): proto.Decoder(Ex) def test_multiple_namedtuple_errors(self, proto): class Ex1(NamedTuple): a: int class Ex2(NamedTuple): b: int with pytest.raises(TypeError, match="may not contain more than one NamedTuple"): proto.Decoder(Union[Ex1, Ex2]) def test_subtype_error(self, proto): class Ex(NamedTuple): a: int b: Union[list, tuple] with pytest.raises(TypeError, match="may not contain more than one array-like"): proto.Decoder(Ex) assert not hasattr(Ex, "__msgspec_cache__") def test_recursive_type(self, proto): source = """ from __future__ import annotations from typing import NamedTuple, Union class Ex(NamedTuple): a: int b: Union[Ex, None] """ with temp_module(source) as mod: msg = mod.Ex(1, mod.Ex(2, None)) dec = proto.Decoder(mod.Ex) assert dec.decode(proto.encode(msg)) == msg with pytest.raises(ValidationError) as rec: dec.decode(proto.encode(mod.Ex(1, ("bad", "two")))) assert "`$[1][0]`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) @pytest.mark.parametrize("use_typing", [True, False]) def test_decode_namedtuple_no_defaults(self, proto, use_typing): if use_typing: class Example(NamedTuple): a: int b: int c: int else: Example = namedtuple("Example", "a b c") dec = proto.Decoder(Example) msg = Example(1, 2, 3) res = dec.decode(proto.encode(msg)) assert res == msg suffix = ", got 1" if proto is msgspec.msgpack else "" with pytest.raises(ValidationError, match=f"length 3{suffix}"): dec.decode(proto.encode((1,))) suffix = ", got 6" if proto is msgspec.msgpack else "" with pytest.raises(ValidationError, match=f"length 3{suffix}"): dec.decode(proto.encode((1, 2, 3, 4, 5, 6))) @pytest.mark.parametrize("use_typing", [True, False]) def test_decode_namedtuple_with_defaults(self, proto, use_typing): if use_typing: class Example(NamedTuple): a: int b: int c: int = -3 d: int = -4 e: int = -5 else: Example = namedtuple("Example", "a b c d e", defaults=(-3, -4, -5)) dec = proto.Decoder(Example) for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: msg = Example(*args) res = dec.decode(proto.encode(msg)) assert res == msg suffix = ", got 1" if proto is msgspec.msgpack else "" with pytest.raises(ValidationError, match=f"length 2 to 5{suffix}"): dec.decode(proto.encode((1,))) suffix = ", got 6" if proto is msgspec.msgpack else "" with pytest.raises(ValidationError, match=f"length 2 to 5{suffix}"): dec.decode(proto.encode((1, 2, 3, 4, 5, 6))) def test_decode_namedtuple_field_wrong_type(self, proto): dec = proto.Decoder(PersonTuple) msg = proto.encode((1, "bad", 2)) with pytest.raises( ValidationError, match=r"Expected `str`, got `int` - at `\$\[0\]`" ): dec.decode(msg) def test_decode_namedtuple_not_array(self, proto): dec = proto.Decoder(PersonTuple) msg = proto.encode({}) with pytest.raises(ValidationError, match="Expected `array`, got `object`"): dec.decode(msg) def test_generic_namedtuple_info_cached(self, proto): NamedTuple = pytest.importorskip("typing_extensions").NamedTuple class Ex(NamedTuple, Generic[T]): x: T typ = Ex[int] assert Ex[int] is typ dec = proto.Decoder(typ) info = typ.__msgspec_cache__ assert info is not None assert sys.getrefcount(info) == 4 # info + attr + decoder + func call dec2 = proto.Decoder(typ) assert typ.__msgspec_cache__ is info assert sys.getrefcount(info) == 5 del dec del dec2 assert sys.getrefcount(info) == 3 def test_generic_namedtuple_invalid_types_not_cached(self, proto): NamedTuple = pytest.importorskip("typing_extensions").NamedTuple class Ex(NamedTuple, Generic[T]): x: Union[List[T], Tuple[float]] for typ in [Ex, Ex[int]]: for _ in range(2): with pytest.raises(TypeError, match="not supported"): proto.Decoder(typ) assert not hasattr(typ, "__msgspec_cache__") def test_generic_namedtuple(self, proto): NamedTuple = pytest.importorskip("typing_extensions").NamedTuple class Ex(NamedTuple, Generic[T]): x: T y: List[T] sol = Ex(1, [1, 2]) msg = proto.encode(sol) res = proto.decode(msg, type=Ex) assert res == sol res = proto.decode(msg, type=Ex[int]) assert res == sol res = proto.decode(msg, type=Ex[Union[int, str]]) assert res == sol res = proto.decode(msg, type=Ex[float]) assert type(res.x) is float with pytest.raises(ValidationError, match="Expected `str`, got `int`"): proto.decode(msg, type=Ex[str]) def test_recursive_generic_namedtuple(self, proto): pytest.importorskip("typing_extensions") source = """ from __future__ import annotations from typing import Union, Generic, TypeVar from typing_extensions import NamedTuple T = TypeVar("T") class Ex(NamedTuple, Generic[T]): a: T b: Union[Ex[T], None] """ with temp_module(source) as mod: msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) msg2 = mod.Ex(a=1, b=mod.Ex(a="bad", b=None)) assert proto.decode(proto.encode(msg), type=mod.Ex) == msg assert proto.decode(proto.encode(msg2), type=mod.Ex) == msg2 assert proto.decode(proto.encode(msg), type=mod.Ex[int]) == msg with pytest.raises(ValidationError) as rec: proto.decode(proto.encode(msg2), type=mod.Ex[int]) assert "`$[1][0]`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) class TestDataclass: def test_encode_dataclass_err_invalid_dataclass_fields(self, proto): @dataclass class Ex: x: int Ex.__dataclass_fields__ = () with pytest.raises(RuntimeError, match="is not a dict"): proto.encode(Ex(1)) def test_encode_dataclass_class_errors(self, proto): @dataclass class Ex: x: int with pytest.raises(TypeError, match="Encoding objects of type type"): proto.encode(Ex) def test_encode_dataclass_no_slots(self, proto): @dataclass class Test: x: int y: int x = Test(1, 2) res = proto.encode(x) sol = proto.encode({"x": 1, "y": 2}) assert res == sol @py310_plus def test_encode_dataclass_slots(self, proto): @dataclass(slots=True) class Test: x: int y: int x = Test(1, 2) res = proto.encode(x) sol = proto.encode({"x": 1, "y": 2}) assert res == sol @py310_plus @pytest.mark.parametrize("slots", [True, False]) def test_encode_dataclass_missing_fields(self, proto, slots): @dataclass(slots=slots) class Test: x: int y: int z: int x = Test(1, 2, 3) sol = {"x": 1, "y": 2, "z": 3} for key in "xyz": delattr(x, key) del sol[key] res = proto.decode(proto.encode(x)) assert res == sol @py310_plus @pytest.mark.parametrize("slots_base", [True, False]) @pytest.mark.parametrize("slots", [True, False]) def test_encode_dataclass_subclasses(self, proto, slots_base, slots): @dataclass(slots=slots_base) class Base: x: int y: int @dataclass(slots=slots) class Test(Base): y: int z: int x = Test(1, 2, 3) res = proto.decode(proto.encode(x)) assert res == {"x": 1, "y": 2, "z": 3} # Missing attribute ignored del x.y res = proto.decode(proto.encode(x)) assert res == {"x": 1, "z": 3} @py311_plus def test_encode_dataclass_weakref_slot(self, proto): @dataclass(slots=True, weakref_slot=True) class Test: x: int y: int x = Test(1, 2) ref = weakref.ref(x) # noqa res = proto.decode(proto.encode(x)) assert res == {"x": 1, "y": 2} def test_encode_dataclass_classvars_ignored(self, proto): @dataclass class Ex: a: int b: ClassVar[int] = 2 msg = proto.encode(Ex(a=1)) assert msg == proto.encode({"a": 1}) def test_encode_dataclass_extra_fields_ignored(self, proto): @dataclass class Ex: a: int b: int x = Ex(1, 2) x.c = 3 msg = proto.encode(Ex(1, 2)) assert msg == proto.encode({"a": 1, "b": 2}) @pytest.mark.parametrize("order", ["acb", "bca", "cba"]) def test_encode_dataclass_dict_reordered(self, proto, order): @dataclass class Ex: a: int b: int c: int x = Ex(1, 2, 3) x.__dict__.clear() x.__dict__.update(dict(zip(order, range(3)))) res = proto.encode(x) sol = proto.encode(dict(sorted(zip(order, range(3))))) assert res == sol @pytest.mark.parametrize("present", ["ab", "a", "b", ""]) def test_encode_dataclass_ducktyped(self, proto, present): """edgedb.Object looks like a dataclass, but the implementation doesn't match the one from dataclasses. This ducktyped implementation tries to mirror the one in edgedb for testing purposes.""" @dataclass class Ex: a: int b: int msg = {k: v for k, v in zip("ab", range(2)) if k in present} class Ex2: def __getattr__(self, key): return msg[key] __dataclass_fields__ = {} x = Ex2() x.__dataclass_fields__ = Ex.__dataclass_fields__ res = proto.encode(x) sol = proto.encode(msg) assert res == sol @pytest.mark.parametrize("field", "xyz") def test_encode_dataclass_invalid_field_errors(self, proto, field): @dataclass class Test: x: int y: int z: int x = Test(1, 2, 3) setattr(x, field, object()) with pytest.raises(TypeError, match="unsupported"): proto.encode(x) def test_type_cached(self, proto): @dataclass class Ex: a: int b: str msg = Ex(a=1, b="two") dec = proto.Decoder(Ex) info = Ex.__msgspec_cache__ assert info is not None dec2 = proto.Decoder(Ex) assert Ex.__msgspec_cache__ is info assert dec.decode(proto.encode(msg)) == msg assert dec2.decode(proto.encode(msg)) == msg def test_decode_dataclass_subclasses(self, proto): @dataclass class Base: x: int @dataclass class Sub(Base): y: int msg = proto.encode({"x": 1, "y": 2}) assert proto.decode(msg, type=Base) == Base(1) assert proto.decode(msg, type=Sub) == Sub(1, 2) def test_multiple_dataclasses_errors(self, proto): @dataclass class Ex1: a: int @dataclass class Ex2: b: int with pytest.raises(TypeError, match="may not contain more than one dataclass"): proto.Decoder(Union[Ex1, Ex2]) def test_subtype_error(self, proto): @dataclass class Ex: a: int b: Union[list, tuple] with pytest.raises(TypeError, match="may not contain more than one array-like"): proto.Decoder(Ex) assert not hasattr(Ex, "__msgspec_cache__") def test_recursive_type(self, proto): source = """ from __future__ import annotations from typing import Union from dataclasses import dataclass @dataclass class Ex: a: int b: Union[Ex, None] """ with temp_module(source) as mod: msg = mod.Ex(a=1, b=mod.Ex(a=2, b=None)) dec = proto.Decoder(mod.Ex) assert dec.decode(proto.encode(msg)) == msg with pytest.raises(ValidationError) as rec: dec.decode(proto.encode({"a": 1, "b": {"a": "bad"}})) assert "`$.b.a`" in str(rec.value) assert "Expected `int`, got `str`" in str(rec.value) def test_classvars_ignored(self, proto): source = """ from __future__ import annotations from typing import ClassVar from dataclasses import dataclass @dataclass class Ex: a: int other: ClassVar[int] """ with temp_module(source) as mod: msg = mod.Ex(a=1) dec = proto.Decoder(mod.Ex) res = dec.decode(proto.encode({"a": 1, "other": 2})) assert res == msg assert not hasattr(res, "other") def test_initvars_forbidden(self, proto): source = """ from dataclasses import dataclass, InitVar @dataclass class Ex: a: int other: InitVar[int] """ with temp_module(source) as mod: with pytest.raises(TypeError, match="`InitVar` fields are not supported"): proto.Decoder(mod.Ex) @pytest.mark.parametrize("slots", [False, True]) def test_decode_dataclass(self, proto, slots): if slots: if not PY310: pytest.skip(reason="Python 3.10+ required") kws = {"slots": True} else: kws = {} @dataclass(**kws) class Example: a: int b: int c: int dec = proto.Decoder(Example) msg = Example(1, 2, 3) res = dec.decode(proto.encode(msg)) assert res == msg # Extra fields ignored res = dec.decode( proto.encode({"x": -1, "a": 1, "y": -2, "b": 2, "z": -3, "c": 3, "": -4}) ) assert res == msg # Missing fields error with pytest.raises(ValidationError, match="missing required field `b`"): dec.decode(proto.encode({"a": 1})) # Incorrect field types error with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.a`" ): dec.decode(proto.encode({"a": "bad"})) @pytest.mark.parametrize("frozen", [False, True]) @pytest.mark.parametrize("slots", [False, True]) def test_decode_dataclass_defaults(self, proto, frozen, slots): if slots: if not PY310: pytest.skip(reason="Python 3.10+ required") kws = {"slots": True} else: kws = {} @dataclass(frozen=frozen, **kws) class Example: a: int b: int c: int = -3 d: int = -4 e: int = field(default_factory=lambda: -1000) dec = proto.Decoder(Example) for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: sol = Example(*args) msg = dict(zip("abcde", args)) res = dec.decode(proto.encode(msg)) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `a`"): dec.decode(proto.encode({"c": 1, "d": 2, "e": 3})) def test_decode_dataclass_default_factory_errors(self, proto): def bad(): raise ValueError("Oh no!") @dataclass class Example: a: int = field(default_factory=bad) with pytest.raises(ValueError, match="Oh no!"): proto.decode(proto.encode({}), type=Example) def test_decode_dataclass_frozen(self, proto): @dataclass(frozen=True) class Point: x: int y: int msg = proto.encode(Point(1, 2)) res = proto.decode(msg, type=Point) assert res == Point(1, 2) def test_decode_dataclass_post_init(self, proto): called = False @dataclass class Example: a: int def __post_init__(self): nonlocal called called = True res = proto.decode(proto.encode({"a": 1}), type=Example) assert res.a == 1 assert called @pytest.mark.parametrize("exc_class", [ValueError, TypeError, OSError]) def test_decode_dataclass_post_init_errors(self, proto, exc_class): @dataclass class Example: a: int def __post_init__(self): raise exc_class("Oh no!") expected = ( ValidationError if exc_class in (ValueError, TypeError) else exc_class ) with pytest.raises(expected, match="Oh no!") as rec: proto.decode(proto.encode([{"a": 1}]), type=List[Example]) if expected is ValidationError: assert "- at `$[0]`" in str(rec.value) def test_decode_dataclass_not_object(self, proto): @dataclass class Example: a: int b: int dec = proto.Decoder(Example) msg = proto.encode([]) with pytest.raises(ValidationError, match="Expected `object`, got `array`"): dec.decode(msg) @pytest.mark.skipif(attrs is None, reason="attrs not installed") class TestAttrs: def test_factory_takes_self_not_implemented(self, proto): """This feature is doable, but not yet implemented""" @attrs.define class Test: x: int = attrs.Factory(lambda self: 0, takes_self=True) with pytest.raises(NotImplementedError): proto.Decoder(Test) @pytest.mark.parametrize("slots", [True, False]) def test_encode_attrs(self, proto, slots): @attrs.define(slots=slots) class Test: x: int y: int x = Test(1, 2) res = proto.encode(x) sol = proto.encode({"x": 1, "y": 2}) assert res == sol @pytest.mark.parametrize("slots", [True, False]) def test_encode_attrs_missing_fields(self, proto, slots): @attrs.define(slots=slots) class Test: x: int y: int z: int x = Test(1, 2, 3) sol = {"x": 1, "y": 2, "z": 3} for key in "xyz": delattr(x, key) del sol[key] res = proto.decode(proto.encode(x)) assert res == sol @pytest.mark.parametrize("slots_base", [True, False]) @pytest.mark.parametrize("slots", [True, False]) def test_encode_attrs_subclasses(self, proto, slots_base, slots): @attrs.define(slots=slots_base) class Base: x: int y: int @attrs.define(slots=slots) class Test(Base): y: int z: int x = Test(1, 2, 3) res = proto.decode(proto.encode(x)) assert res == {"x": 1, "y": 2, "z": 3} # Missing attribute ignored del x.y res = proto.decode(proto.encode(x)) assert res == {"x": 1, "z": 3} def test_encode_attrs_weakref_slot(self, proto): @attrs.define(slots=True, weakref_slot=True) class Test: x: int y: int x = Test(1, 2) ref = weakref.ref(x) # noqa res = proto.decode(proto.encode(x)) assert res == {"x": 1, "y": 2} @pytest.mark.parametrize("slots", [True, False]) def test_encode_attrs_skip_leading_underscore(self, proto, slots): @attrs.define(slots=slots) class Test: x: int y: int _z: int x = Test(1, 2, 3) res = proto.encode(x) sol = proto.encode({"x": 1, "y": 2}) assert res == sol @pytest.mark.parametrize("slots", [False, True]) def test_decode_attrs(self, proto, slots): @attrs.define(slots=slots) class Example: a: int b: int c: int dec = proto.Decoder(Example) msg = Example(1, 2, 3) res = dec.decode(proto.encode(msg)) assert res == msg # Extra fields ignored res = dec.decode( proto.encode({"x": -1, "a": 1, "y": -2, "b": 2, "z": -3, "c": 3, "": -4}) ) assert res == msg # Missing fields error with pytest.raises(ValidationError, match="missing required field `b`"): dec.decode(proto.encode({"a": 1})) # Incorrect field types error with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.a`" ): dec.decode(proto.encode({"a": "bad"})) @pytest.mark.parametrize("frozen", [False, True]) @pytest.mark.parametrize("slots", [False, True]) def test_decode_attrs_defaults(self, proto, frozen, slots): @attrs.define(frozen=frozen, slots=slots) class Example: a: int b: int c: int = -3 d: int = -4 e: int = attrs.field(factory=lambda: -1000) dec = proto.Decoder(Example) for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: sol = Example(*args) msg = dict(zip("abcde", args)) res = dec.decode(proto.encode(msg)) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `a`"): dec.decode(proto.encode({"c": 1, "d": 2, "e": 3})) def test_decode_attrs_default_factory_errors(self, proto): def bad(): raise ValueError("Oh no!") @attrs.define class Example: a: int = attrs.field(factory=bad) with pytest.raises(ValueError, match="Oh no!"): proto.decode(proto.encode({}), type=Example) def test_decode_attrs_frozen(self, proto): @attrs.define(frozen=True) class Example: x: int y: int msg = Example(1, 2) res = proto.decode(proto.encode(msg), type=Example) assert res == Example(1, 2) def test_decode_attrs_post_init(self, proto): called = False @attrs.define class Example: a: int def __attrs_post_init__(self): nonlocal called called = True res = proto.decode(proto.encode({"a": 1}), type=Example) assert res.a == 1 assert called @pytest.mark.parametrize("exc_class", [ValueError, TypeError, OSError]) def test_decode_attrs_post_init_errors(self, proto, exc_class): @attrs.define class Example: a: int def __attrs_post_init__(self): raise exc_class("Oh no!") expected = ( ValidationError if exc_class in (ValueError, TypeError) else exc_class ) with pytest.raises(expected, match="Oh no!") as rec: proto.decode(proto.encode([{"a": 1}]), type=List[Example]) if expected is ValidationError: assert "- at `$[0]`" in str(rec.value) def test_decode_attrs_pre_init(self, proto): called = False @attrs.define class Example: a: int def __attrs_pre_init__(self): nonlocal called called = True res = proto.decode(proto.encode({"a": 1}), type=Example) assert res.a == 1 assert called def test_decode_attrs_pre_init_errors(self, proto): @attrs.define class Example: a: int def __attrs_pre_init__(self): raise ValueError("Oh no!") with pytest.raises(ValueError, match="Oh no!"): proto.decode(proto.encode({"a": 1}), type=Example) def test_decode_attrs_validators(self, proto): def not2(self, attr, value): if value == 2: raise ValueError("Oh no!") @attrs.define class Example: a: int = attrs.field(validator=[attrs.validators.gt(0), not2]) res = proto.decode(proto.encode({"a": 1}), type=Example) assert res.a == 1 with pytest.raises(ValidationError): res = proto.decode(proto.encode({"a": -1}), type=Example) with pytest.raises(ValidationError, match="Oh no!"): res = proto.decode(proto.encode({"a": 2}), type=Example) def test_decode_attrs_not_object(self, proto): @attrs.define class Example: a: int b: int dec = proto.Decoder(Example) msg = proto.encode([]) with pytest.raises(ValidationError, match="Expected `object`, got `array`"): dec.decode(msg) class TestDate: def test_encode_date(self, proto): # All fields, zero padded x = datetime.date(1, 2, 3) s = proto.decode(proto.encode(x)) assert s == "0001-02-03" # All fields, no zeros x = datetime.date(1234, 12, 31) s = proto.decode(proto.encode(x)) assert s == "1234-12-31" @pytest.mark.parametrize( "s", [ "0001-01-01", "9999-12-31", "0001-02-03", "2020-02-29", ], ) def test_decode_date(self, proto, s): sol = datetime.date.fromisoformat(s) res = proto.decode(proto.encode(s), type=datetime.date) assert type(res) is datetime.date assert res == sol def test_decode_date_wrong_type(self, proto): msg = proto.encode([]) with pytest.raises(ValidationError, match="Expected `date`, got `array`"): proto.decode(msg, type=datetime.date) @pytest.mark.parametrize( "s", [ # Incorrect field lengths "001-02-03", "0001-2-03", "0001-02-3", # Trailing data "0001-02-0300", # Truncated "0001-02-", # Invalid characters "000a-02-03", "0001-0a-03", "0001-02-0a", # Year out of range "0000-02-03", # Month out of range "0001-00-03", "0001-13-03", # Day out of range for month "0001-02-00", "0001-02-29", "2000-02-30", ], ) def test_decode_date_malformed(self, proto, s): msg = proto.encode(s) with pytest.raises(ValidationError, match="Invalid RFC3339"): proto.decode(msg, type=datetime.date) class TestTime: @staticmethod def parse(t_str): t_str = t_str.replace("Z", "+00:00") return datetime.time.fromisoformat(t_str) @pytest.mark.parametrize( "t", [ "00:00:00", "01:02:03", "01:02:03.000004", "12:34:56.789000", "23:59:59.999999", ], ) def test_encode_time_naive(self, proto, t): res = proto.encode(self.parse(t)) sol = proto.encode(t) assert res == sol @pytest.mark.parametrize( "t", [ "00:00:00", "01:02:03", "01:02:03.000004", "12:34:56.789000", "23:59:59.999999", ], ) def test_decode_time_naive(self, proto, t): sol = self.parse(t) res = proto.decode(proto.encode(t), type=datetime.time) assert type(res) is datetime.time assert res == sol def test_decode_time_wrong_type(self, proto): msg = proto.encode([]) with pytest.raises(ValidationError, match="Expected `time`, got `array`"): proto.decode(msg, type=datetime.time) @pytest.mark.parametrize( "offset", [ datetime.timedelta(0), datetime.timedelta(days=1, microseconds=-1), datetime.timedelta(days=-1, microseconds=1), datetime.timedelta(days=1, seconds=-29), datetime.timedelta(days=-1, seconds=29), datetime.timedelta(days=0, seconds=30), datetime.timedelta(days=0, seconds=-30), ], ) def test_encode_time_offset_is_appx_equal_to_utc(self, proto, offset): x = datetime.time(14, 56, 27, 123456, datetime.timezone(offset)) res = proto.encode(x) sol = proto.encode("14:56:27.123456Z") assert res == sol @pytest.mark.parametrize( "offset, t_str", [ ( datetime.timedelta(days=1, seconds=-30), "14:56:27.123456+23:59", ), ( datetime.timedelta(days=-1, seconds=30), "14:56:27.123456-23:59", ), ( datetime.timedelta(minutes=19, seconds=32, microseconds=130000), "14:56:27.123456+00:20", ), ], ) def test_encode_time_offset_rounds_to_nearest_minute(self, proto, offset, t_str): x = datetime.time(14, 56, 27, 123456, datetime.timezone(offset)) res = proto.encode(x) sol = proto.encode(t_str) assert res == sol def test_encode_time_zoneinfo(self): import zoneinfo try: x = datetime.time(1, 2, 3, 456789, zoneinfo.ZoneInfo("America/Chicago")) except zoneinfo.ZoneInfoNotFoundError: pytest.skip(reason="Failed to load timezone") sol = msgspec.json.encode(x.isoformat()) res = msgspec.json.encode(x) assert res == sol @pytest.mark.parametrize( "dt", [ "04:05:06.000007", "04:05:06.007", "04:05:06", "21:19:22.123456", ], ) @pytest.mark.parametrize("suffix", ["", "Z", "+00:00", "-00:00"]) def test_decode_time_utc(self, proto, dt, suffix): dt += suffix sol = self.parse(dt) msg = proto.encode(sol) res = proto.decode(msg, type=datetime.time) assert res == sol @pytest.mark.parametrize("t", ["00:00:01", "12:01:01"]) @pytest.mark.parametrize("sign", ["-", "+"]) @pytest.mark.parametrize("hour", [0, 8, 12, 16, 23]) @pytest.mark.parametrize("minute", [0, 30]) def test_decode_time_with_timezone(self, proto, t, sign, hour, minute): s = f"{t}{sign}{hour:02}:{minute:02}" msg = proto.encode(s) res = proto.decode(msg, type=datetime.time) sol = self.parse(s) assert res == sol @pytest.mark.parametrize("z", ["Z", "z"]) def test_decode_time_not_case_sensitive(self, proto, z): """Z can be upper/lowercase""" sol = datetime.time(4, 5, 6, 7, UTC) res = proto.decode(proto.encode(f"04:05:06.000007{z}"), type=datetime.time) assert res == sol @pytest.mark.parametrize( "lax, strict", [ ("03:04:05+0102", "03:04:05+01:02"), ("03:04:05-0102", "03:04:05-01:02"), ], ) def test_decode_time_rfc3339_relaxed(self, lax, strict, proto): """msgspec supports a few relaxations of the RFC3339 format.""" sol = datetime.time.fromisoformat(strict) msg = proto.encode(lax) res = proto.decode(msg, type=datetime.time) assert res == sol @pytest.mark.parametrize( "t, sol", [ ( "03:04:05.1234564Z", datetime.time(3, 4, 5, 123456, UTC), ), ( "03:04:05.1234565Z", datetime.time(3, 4, 5, 123457, UTC), ), ( "03:04:05.12345650000000000001Z", datetime.time(3, 4, 5, 123457, UTC), ), ( "03:04:05.9999995Z", datetime.time(3, 4, 6, 0, UTC), ), ( "03:04:59.9999995Z", datetime.time(3, 5, 0, 0, UTC), ), ( "03:59:59.9999995Z", datetime.time(4, 0, 0, 0, UTC), ), ( "23:59:59.9999995Z", datetime.time(0, 0, 0, 0, UTC), ), ], ) def test_decode_time_nanos(self, proto, t, sol): msg = proto.encode(t) res = proto.decode(msg, type=datetime.time) assert res == sol @pytest.mark.parametrize( "s", [ # Incorrect field lengths "1:02:03.0000004Z", "01:2:03.0000004Z", "01:02:3.0000004Z", "01:02:03.0000004+5:06", "01:02:03.0000004+05:6", "01:02:03.0000004+056", "01:02:03.0000004+05600", # Trailing data "01:02:030", "01:02:03a", "01:02:03.a", "01:02:03.0a", "01:02:03.0000004a", "01:02:03.0000004+00:000", "01:02:03.0000004+00000", "01:02:03.0000004Z0", # Truncated "01:02:3", # Missing +/- "01:02:0300:00", # Missing digits after decimal "01:02:03.", "01:02:03.Z", # Invalid characters "0a:02:03.004+05:06", "01:0a:03.004+05:06", "01:02:0a.004+05:06", "01:02:03.00a+05:06", "01:02:03.004+0a:06", "01:02:03.004+05:0a", "01:02:03.004+0a06", "01:02:03.004+050a", # Hour out of range "24:02:03.004", # Minute out of range "01:60:03.004", # Second out of range "01:02:60.004", # Timezone hour out of range "01:02:03.004+24:00", "01:02:03.004-24:00", # Timezone minute out of range "01:02:03.004+00:60", "01:02:03.004-00:60", ], ) def test_decode_time_malformed(self, proto, s): msg = proto.encode(s) with pytest.raises(ValidationError, match="Invalid RFC3339"): proto.decode(msg, type=datetime.time) class TestTimeDelta: @pytest.mark.parametrize("neg", [False, True]) @pytest.mark.parametrize( "td, msg", [ (timedelta(), "P0D"), (timedelta(1), "P1D"), (timedelta(10), "P10D"), (timedelta(123456789), "P123456789D"), (timedelta(0, 1), "PT1S"), (timedelta(0, 10), "PT10S"), (timedelta(0, 12345), "PT12345S"), (timedelta(0, 0, 1), "PT0.000001S"), (timedelta(0, 0, 10), "PT0.00001S"), (timedelta(0, 0, 100), "PT0.0001S"), (timedelta(0, 0, 1000), "PT0.001S"), (timedelta(0, 0, 10000), "PT0.01S"), (timedelta(0, 0, 100000), "PT0.1S"), (timedelta(123456789, 54321, 123456), "P123456789DT54321.123456S"), (timedelta(0, 86399, 999999), "PT86399.999999S"), ], ) def test_roundtrip_timedelta(self, proto, td, msg, neg): if neg and td: td = -td msg = "-" + msg buf = proto.encode(td) res = proto.decode(buf) assert res == msg td2 = proto.decode(buf, type=timedelta) assert td2 == td @pytest.mark.parametrize( "msg, sol", [ ("PT0S", timedelta()), ("+P1DT2S", timedelta(1, 2)), ("-P1DT2S", -timedelta(1, 2)), ("P000DT000.000S", timedelta()), ("-P000DT000.000S", timedelta()), ("P00012DT0045.670000000S", timedelta(12, 45, 670000)), ("P123456789.12345678912D", timedelta(123456789, 10666, 666580)), ("P123456789.12345678912999D", timedelta(123456789, 10666, 666580)), ("P123456789.12345678913D", timedelta(123456789, 10666, 666581)), ("PT0123H", timedelta(0, 123 * 60 * 60)), ("PT0123.456H", timedelta(0, 123.456 * 60 * 60)), ("PT0123M", timedelta(0, 123 * 60)), ("PT0123.456M", timedelta(0, 123.456 * 60)), ], ) def test_decode_timedelta(self, proto, msg, sol): buf = proto.encode(msg) res = proto.decode(buf, type=timedelta) assert res == sol def test_decode_timedelta_case_insensitive(self, proto): buf = proto.encode("p1dt2h3m4s") res = proto.decode(buf, type=timedelta) assert res == timedelta(1, 2 * 60 * 60 + 3 * 60 + 4) @pytest.mark.parametrize( "msg", [ "P999999999DT86399.999999S", "P999999998DT24H86399.999999S", "P999999999DT86399.9999994S", ], ) def test_decode_timedelta_max(self, proto, msg): buf = proto.encode(msg) res = proto.decode(buf, type=timedelta) assert res == timedelta.max @pytest.mark.parametrize( "msg", [ "-P999999999D", "-P999999998DT24H", "-P999999998DT23H3600S", "-P999999998DT86399.9999995S", ], ) def test_decode_timedelta_min(self, proto, msg): buf = proto.encode(msg) res = proto.decode(buf, type=timedelta) assert res == timedelta.min def test_decode_timedelta_wrong_type(self, proto): bad = proto.encode([]) with pytest.raises(ValidationError, match="Expected `duration`, got `array`"): proto.decode(bad, type=timedelta) @pytest.mark.parametrize( "msg", [ # No P "", "-", "+", # Just P "P", "-P", "+P", # Missing Number "PD", "P.0D", # Missing digit after decimal place "P123.", "P123.D", # Missing Unit "P0", "P0.0", "P0.00", "P0.000000000000123", # Trailing T "PT", "P0DT", # Missing T "P1D2H", "P1D2S", # Repeat T "PTT0S", # Repeat Units "P1D2D", "PT1H2H", "PT1M2M", "PT1S2S", # Units in wrong order "PT1H1D", "PT1M1H", "PT1S1M", # Non-fractional after fractional "PT1.2H1M", "P1.2DT1H", "PT1.2H0S", # Invalid characters "1P1D", "P-1D", "P1.-D", "P1.0-D", "P1.000000000000123-D", "P1D-", ], ) def test_decode_timedelta_malformed(self, proto, msg): encoded = proto.encode(msg) with pytest.raises(ValidationError, match="Invalid ISO8601 duration"): proto.decode(encoded, type=timedelta) @pytest.mark.parametrize( "msg", [ "P1000000000D", "PT140737488355329S", "P999999999DT86399.9999995S", "-P999999999DT0.0000005S", "P999999998DT48H", "-P999999998DT24H01S", ], ) def test_decode_timedelta_out_of_range(self, proto, msg): encoded = proto.encode(msg) with pytest.raises(ValidationError, match="Duration is out of range"): proto.decode(encoded, type=timedelta) @pytest.mark.parametrize("unit", ["Y", "M", "W"]) def test_decode_timedelta_unsupported_unit(self, proto, unit): upper = f"P1{unit}" for msg in [upper, upper.lower()]: encoded = proto.encode(msg) with pytest.raises(ValidationError, match="Only units 'D'"): proto.decode(encoded, type=timedelta) class TestUUID: def test_encoder_uuid_format(self, proto): assert proto.Encoder().uuid_format == "canonical" assert proto.Encoder(uuid_format="canonical").uuid_format == "canonical" assert proto.Encoder(uuid_format="hex").uuid_format == "hex" if proto is msgspec.msgpack: assert proto.Encoder(uuid_format="bytes").uuid_format == "bytes" else: with pytest.raises( ValueError, match="`uuid_format` must be 'canonical' or 'hex', got 'bytes'", ): proto.Encoder(uuid_format="bytes") def test_encoder_invalid_uuid_format(self, proto): if proto is msgspec.json: msg = "`uuid_format` must be 'canonical' or 'hex', got {!r}" else: msg = "`uuid_format` must be 'canonical', 'hex', or 'bytes', got {!r}" for bad in ["bad", 1]: with pytest.raises(ValueError, match=msg.format(bad)): proto.Encoder(uuid_format=bad) @pytest.mark.parametrize("format", ["canonical", "hex"]) def test_encode_uuid(self, format, proto): u = uuid.uuid4() enc = proto.Encoder(uuid_format=format) res = enc.encode(u) if format == "canonical": sol = enc.encode(str(u)) else: sol = enc.encode(u.hex) assert res == sol def test_encode_uuid_bytes(self): u = uuid.uuid4() enc = msgspec.msgpack.Encoder(uuid_format="bytes") res = enc.encode(u) sol = enc.encode(u.bytes) assert res == sol def test_encode_uuid_subclass(self, proto): class Ex(uuid.UUID): pass s = "4184defa-4d1a-4497-a140-fd1ec0b22383" assert proto.encode(Ex(s)) == proto.encode(s) def test_encode_uuid_malformed_internals(self, proto): """Ensure that if some other code mutates the uuid object, we error nicely rather than segfaulting""" u = uuid.uuid4() object.__delattr__(u, "int") with pytest.raises(AttributeError): proto.encode(u) u = uuid.uuid4() object.__setattr__(u, "int", "oops") with pytest.raises(TypeError): proto.encode(u) @pytest.mark.parametrize("upper", [False, True]) @pytest.mark.parametrize("hyphens", [False, True]) def test_decode_uuid(self, proto, upper, hyphens): u = uuid.uuid4() s = str(u) if hyphens else u.hex if upper: s = s.upper() msg = proto.encode(s) res = proto.decode(msg, type=uuid.UUID) assert res == u assert res.is_safe == u.is_safe def test_decode_uuid_from_bytes(self): sol = uuid.uuid4() msg = msgspec.msgpack.encode(sol.bytes) res = msgspec.msgpack.decode(msg, type=uuid.UUID) assert res == sol bad_msg = msgspec.msgpack.encode(b"x" * 8) with pytest.raises(msgspec.ValidationError, match="Invalid UUID bytes"): msgspec.msgpack.decode(bad_msg, type=uuid.UUID) @pytest.mark.parametrize( "uuid_str", [ # Truncated "12345678-1234-1234-1234-1234567890a", "123456781234123412341234567890a", # Truncated segments "1234567-1234-1234-1234-1234567890abc", "12345678-123-1234-1234-1234567890abc", "12345678-1234-123-1234-1234567890abc", "12345678-1234-1234-123-1234567890abc", "12345678-1234-1234-1234-1234567890a-", # Invalid character "123456x81234123412341234567890ab", "123456x8-1234-1234-1234-1234567890ab", "1234567x-1234-1234-1234-1234567890ab", "12345678-123x-1234-1234-1234567890ab", "12345678-1234-123x-1234-1234567890ab", "12345678-1234-1234-123x-1234567890ab", "12345678-1234-1234-1234-1234567890ax", # Invalid dash "12345678.1234-1234-1234-1234567890ab", "12345678-1234.1234-1234-1234567890ab", "12345678-1234-1234.1234-1234567890ab", "12345678-1234-1234-1234.1234567890ab", # Trailing data "12345678-1234-1234-1234-1234567890ab-", "12345678-1234-1234-1234-1234567890abc", ], ) def test_decode_uuid_malformed(self, proto, uuid_str): msg = proto.encode(uuid_str) with pytest.raises(ValidationError, match="Invalid UUID"): proto.decode(msg, type=uuid.UUID) class TestNewType: def test_decode_newtype(self, proto): UserId = NewType("UserId", int) assert proto.decode(proto.encode(1), type=UserId) == 1 with pytest.raises(ValidationError): proto.decode(proto.encode("bad"), type=UserId) # Nested NewId works UserId2 = NewType("UserId2", UserId) assert proto.decode(proto.encode(1), type=UserId2) == 1 with pytest.raises(ValidationError): proto.decode(proto.encode("bad"), type=UserId2) def test_decode_annotated_newtype(self, proto): UserId = NewType("UserId", int) dec = proto.Decoder(Annotated[UserId, msgspec.Meta(ge=0)]) assert dec.decode(proto.encode(1)) == 1 with pytest.raises(ValidationError): dec.decode(proto.encode(-1)) def test_decode_newtype_annotated(self, proto): UserId = NewType("UserId", Annotated[int, msgspec.Meta(ge=0)]) dec = proto.Decoder(UserId) assert dec.decode(proto.encode(1)) == 1 with pytest.raises(ValidationError): dec.decode(proto.encode(-1)) def test_decode_annotated_newtype_annotated(self, proto): UserId = Annotated[ NewType("UserId", Annotated[int, msgspec.Meta(ge=0)]), msgspec.Meta(le=10) ] dec = proto.Decoder(UserId) assert dec.decode(proto.encode(1)) == 1 for bad in [-1, 11]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) class TestTypeAlias: @py312_plus def test_simple(self, proto): with temp_module("type Ex = str | None") as mod: dec = proto.Decoder(mod.Ex) assert dec.decode(proto.encode("test")) == "test" assert dec.decode(proto.encode(None)) is None with pytest.raises(ValidationError): dec.decode(proto.encode(1)) @py312_plus def test_generic(self, proto): with temp_module("type Pair[T] = tuple[T, T]") as mod: dec = proto.Decoder(mod.Pair) assert dec.decode(proto.encode((1, 2))) == (1, 2) for bad in [1, [1, 2, 3]]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) @py312_plus def test_parametrized_generic(self, proto): with temp_module("type Pair[T] = tuple[T, T]") as mod: dec = proto.Decoder(mod.Pair[int]) assert dec.decode(proto.encode((1, 2))) == (1, 2) for bad in [1, [1, 2, 3], [1, "a"]]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) @py312_plus def test_typealias_wrapping_typealias(self, proto): src = """ type Pair[T] = tuple[T, T] type Pairs[T] = list[Pair[T]] """ with temp_module(src) as mod: dec = proto.Decoder(mod.Pairs) for good in [[], [(1, 2), (3, 4)]]: assert dec.decode(proto.encode(good)) == good for bad in [1, [1], [(1, 2, 3)]]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) dec = proto.Decoder(mod.Pairs[int]) for good in [[], [(1, 2)], [(1, 2), (3, 4)]]: assert dec.decode(proto.encode(good)) == good for bad in [1, [1], [(1, "a")]]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) @py312_plus def test_typealias_with_constraints(self, proto): src = """ import msgspec from typing import Annotated type Key = Annotated[str, msgspec.Meta(max_length=4)] """ with temp_module(src) as mod: dec = proto.Decoder(mod.Key) for good in ["", "abc", "abcd"]: assert dec.decode(proto.encode(good)) == good for bad in [1, "abcde"]: with pytest.raises(ValidationError): dec.decode(proto.encode(bad)) @py312_plus def test_typealias_parametrized_generic_too_many_parameters(self): with temp_module("type Pair[T] = tuple[T, T]") as mod: with pytest.raises(TypeError): msgspec.json.Decoder(mod.Pair[int, int]) @py312_plus @pytest.mark.parametrize( "src", [ "type Ex = Ex | None", "type Ex = tuple[Ex, int]", "type Ex[T] = tuple[T, Ex[T]]", "type Temp[T] = tuple[T, Temp[T]]; Ex = Temp[int]", "type Temp[T] = tuple[T, Ex[T]]; type Ex[T] = tuple[Temp[T], T];", ], ) def test_recursive_typealias_errors(self, src): """Eventually we should support this, but for now just test that it errors cleanly""" with temp_module(src) as mod: with pytest.raises(RecursionError): msgspec.json.Decoder(mod.Ex) @py312_plus def test_typealias_invalid_type(self): with temp_module("type Ex = int | complex") as mod: with pytest.raises(TypeError): msgspec.json.Decoder(mod.Ex) class TestDecimal: def test_encoder_decimal_format(self, proto): assert proto.Encoder().decimal_format == "string" assert proto.Encoder(decimal_format="string").decimal_format == "string" assert proto.Encoder(decimal_format="number").decimal_format == "number" def test_encoder_invalid_decimal_format(self, proto): with pytest.raises(ValueError, match="must be 'string' or 'number', got 'bad'"): proto.Encoder(decimal_format="bad") with pytest.raises(ValueError, match="must be 'string' or 'number', got 1"): proto.Encoder(decimal_format=1) def test_encoder_encode_decimal(self, proto): enc = proto.Encoder() d = decimal.Decimal("1.5") s = str(d) assert enc.encode(d) == enc.encode(s) def test_Encoder_encode_decimal_string(self, proto): enc = proto.Encoder(decimal_format="string") d = decimal.Decimal("1.5") sol = enc.encode(str(d)) assert enc.encode(d) == sol buf = bytearray() enc.encode_into(d, buf) assert buf == sol def test_Encoder_encode_decimal_number(self, proto): enc = proto.Encoder(decimal_format="number") d = decimal.Decimal("1.5") sol = enc.encode(float(d)) assert enc.encode(d) == sol buf = bytearray() enc.encode_into(d, buf) assert buf == sol def test_encode_decimal(self, proto): d = decimal.Decimal("1.5") s = str(d) assert proto.encode(d) == proto.encode(s) @pytest.mark.parametrize( "val", ["1.5", "InF", "-iNf", "iNfInItY", "-InFiNiTy", "NaN"] ) def test_decode_decimal_str(self, val, proto): sol = decimal.Decimal(val) msg = proto.encode(sol) res = proto.decode(msg, type=decimal.Decimal) assert str(res) == str(sol) assert type(res) is decimal.Decimal def test_decode_decimal_str_invalid(self, proto): msg = proto.encode("1..5") with pytest.raises(ValidationError, match="Invalid decimal string"): proto.decode(msg, type=decimal.Decimal) @pytest.mark.parametrize("val", [-1, -1234, 1, 1234]) def test_decode_decimal_int(self, val, proto): msg = proto.encode(val) sol = decimal.Decimal(str(val)) res = proto.decode(msg, type=decimal.Decimal) assert type(res) is decimal.Decimal assert res == sol @pytest.mark.parametrize( "val", [0.0, 1.3, float("nan"), float("inf"), float("-inf")] ) def test_decode_decimal_float(self, val, proto): msg = proto.encode(val) if msg == b"null": pytest.skip("nonfinite values not supported") sol = decimal.Decimal(str(val)) res = proto.decode(msg, type=decimal.Decimal) assert str(res) == str(sol) assert type(res) is decimal.Decimal class TestAbstractTypes: @pytest.mark.parametrize( "typ", [ typing.Collection, typing.MutableSequence, typing.Sequence, collections.abc.Collection, collections.abc.MutableSequence, collections.abc.Sequence, typing.MutableSet, typing.AbstractSet, collections.abc.MutableSet, collections.abc.Set, ], ) def test_abstract_sequence(self, proto, typ): # Hacky, but it works if "Set" in str(typ): sol = {1, 2} else: sol = [1, 2] msg = proto.encode(sol) assert proto.decode(msg, type=typ) == sol with pytest.raises(ValidationError, match="Expected `array`, got `str`"): proto.decode(proto.encode("a"), type=typ) assert proto.decode(msg, type=typ[int]) == sol with pytest.raises(ValidationError, match="Expected `int`, got `str`"): proto.decode(proto.encode(["a"]), type=typ[int]) @pytest.mark.parametrize( "typ", [ typing.MutableMapping, typing.Mapping, collections.abc.MutableMapping, collections.abc.Mapping, ], ) def test_abstract_mapping(self, proto, typ): sol = {"x": 1, "y": 2} msg = proto.encode(sol) assert proto.decode(msg, type=typ) == sol with pytest.raises(ValidationError, match="Expected `object`, got `str`"): proto.decode(proto.encode("a"), type=typ) assert proto.decode(msg, type=typ[str, int]) == sol with pytest.raises(ValidationError, match="Expected `int`, got `str`"): proto.decode(proto.encode({"a": "b"}), type=typ[str, int]) class TestUnset: def test_unset_type_annotation_ignored(self, proto): class Ex(Struct): x: Union[int, UnsetType] dec = proto.Decoder(Ex) msg = proto.encode({"x": 1}) assert dec.decode(msg) == Ex(1) def test_encode_unset_errors_other_contexts(self, proto): with pytest.raises(TypeError): proto.encode(UNSET) @pytest.mark.parametrize("kind", ["struct", "dataclass", "attrs"]) def test_unset_encode(self, kind, proto): if kind == "struct": class Ex(Struct): x: Union[int, UnsetType] y: Union[int, UnsetType] elif kind == "dataclass": @dataclass class Ex: x: Union[int, UnsetType] y: Union[int, UnsetType] elif kind == "attrs": attrs = pytest.importorskip("attrs") @attrs.define class Ex: x: Union[int, UnsetType] y: Union[int, UnsetType] res = proto.encode(Ex(1, UNSET)) sol = proto.encode({"x": 1}) assert res == sol res = proto.encode(Ex(UNSET, 2)) sol = proto.encode({"y": 2}) assert res == sol res = proto.encode(Ex(UNSET, UNSET)) sol = proto.encode({}) assert res == sol def test_unset_encode_struct_omit_defaults(self, proto): class Ex(Struct, omit_defaults=True): x: Union[int, UnsetType] = UNSET y: Union[int, UnsetType] = UNSET z: int = 0 for x, y in [(Ex(), {}), (Ex(y=2), {"y": 2}), (Ex(z=1), {"z": 1})]: res = proto.encode(x) sol = proto.encode(y) assert res == sol class TestOrder: def test_encoder_order_attribute(self, proto): enc = proto.Encoder() assert enc.order is None enc = proto.Encoder(order=None) assert enc.order is None enc = proto.Encoder(order="deterministic") assert enc.order == "deterministic" enc = proto.Encoder(order="sorted") assert enc.order == "sorted" def test_order_invalid(self, proto): with pytest.raises(ValueError, match="`order` must be one of"): proto.Encoder(order="bad") with pytest.raises(ValueError, match="`order` must be one of"): proto.encode(1, order="bad") @pytest.mark.parametrize("msg", [{}, {"y": 1, "x": 2, "z": 3}]) @pytest.mark.parametrize("order", [None, "deterministic", "sorted"]) @pytest.mark.parametrize("use_encoder", [False, True]) def test_order_dict(self, msg, order, use_encoder, proto): if use_encoder: res = proto.Encoder(order=order).encode(msg) else: res = proto.encode(msg, order=order) if order is not None: sol = proto.encode(dict(sorted(msg.items()))) else: sol = proto.encode(msg) assert res == sol def test_order_dict_non_str_errors(self, proto): with pytest.raises(TypeError, match="Only dicts with str keys"): proto.encode({"b": 2, 1: "a"}, order="deterministic") def test_order_dict_unsortable(self, proto): with pytest.raises(TypeError): proto.encode({"x": 1, 1: 2}, order="deterministic") @pytest.mark.parametrize("typ", [set, frozenset]) @pytest.mark.parametrize("order", ["deterministic", "sorted"]) def test_order_set(self, typ, proto, rand, order): assert proto.encode(typ(), order=order) == proto.encode([]) msg = typ(rand.str(10) for _ in range(20)) res = proto.encode(msg, order=order) sol = proto.encode(list(sorted(msg))) assert res == sol res = proto.encode(msg) sol = proto.encode(list(msg)) assert res == sol def test_order_set_unsortable(self, proto): with pytest.raises(TypeError): proto.encode({"x", 1}, order="deterministic") @pytest.mark.parametrize("n", [0, 1, 2]) @pytest.mark.parametrize( "kind", [ "struct", "dataclass", "attrs", "attrs-dict", ], ) def test_order_object(self, kind, n, proto): fields = [f"x{i}" for i in range(n)] fields.reverse() if kind == "struct": cls = msgspec.defstruct("Test", fields) elif kind == "dataclass": cls = make_dataclass("Test", fields) else: attrs = pytest.importorskip("attrs") cls = attrs.make_class("Test", fields, slots=(kind == "attrs")) msg = cls(*range(n)) if kind in ("struct", "dataclass"): # we currently don't guarantee field order with attrs types sol = proto.encode(dict(zip(fields, range(n)))) res = proto.encode(msg) assert res == sol res = proto.encode(msg, order="deterministic") assert res == sol res = proto.encode(msg, order="sorted") sol = proto.encode(dict(sorted(zip(fields, range(n))))) assert res == sol @pytest.mark.parametrize("kind", ["struct", "dataclass", "attrs", "attrs-dict"]) def test_order_unset(self, kind, proto): if kind == "struct": class Ex(Struct): z: Union[int, UnsetType] = UNSET x: Union[int, UnsetType] = UNSET elif kind == "dataclass": @dataclass class Ex: z: Union[int, UnsetType] = UNSET x: Union[int, UnsetType] = UNSET else: attrs = pytest.importorskip("attrs") @attrs.define(slots=(kind == "attrs")) class Ex: z: Union[int, UnsetType] = UNSET x: Union[int, UnsetType] = UNSET res = proto.encode(Ex(), order="sorted") sol = proto.encode({}) assert res == sol res = proto.encode(Ex(z=10), order="sorted") sol = proto.encode({"z": 10}) assert res == sol res = proto.encode(Ex(z=10, x=-1), order="sorted") sol = proto.encode({"x": -1, "z": 10}) assert res == sol def test_order_struct_omit_defaults(self, proto): class Ex(Struct, omit_defaults=True): z: int = 0 x: int = 1 y: int = 2 res = proto.encode(Ex(), order="sorted") sol = proto.encode({}) assert res == sol res = proto.encode(Ex(z=10), order="sorted") sol = proto.encode({"z": 10}) assert res == sol res = proto.encode(Ex(z=10, x=-1), order="sorted") sol = proto.encode({"x": -1, "z": 10}) assert res == sol def test_order_struct_tag(self, proto): class Ex(Struct, tag_field="y", tag=2): z: int x: int res = proto.encode(Ex(0, 1), order="sorted") sol = proto.encode({"x": 1, "y": 2, "z": 0}) assert res == sol @pytest.mark.parametrize("n", [0, 2, 3, 7, 15, 16, 17, 32, 100, 500, 1000, 10000]) def test_order_sort_implementation(self, rand, n): keys = [f"x_{i}" for i in range(n)] rand.shuffle(keys) msg = dict(zip(keys, range(n))) res = msgspec.json.encode(msg, order="deterministic") sol = msgspec.json.encode(dict(sorted(msg.items()))) assert res == sol class TestFinal: def test_decode_final(self, proto): dec = proto.Decoder(Final[int]) assert dec.decode(proto.encode(1)) == 1 with pytest.raises(ValidationError): dec.decode(proto.encode("bad")) def test_decode_final_annotated(self, proto): dec = proto.Decoder(Final[Annotated[int, msgspec.Meta(ge=0)]]) assert dec.decode(proto.encode(1)) == 1 with pytest.raises(ValidationError): dec.decode(proto.encode(-1)) def test_decode_final_newtype(self, proto): UserId = NewType("UserId", int) dec = proto.Decoder(Final[UserId]) assert dec.decode(proto.encode(1)) == 1 with pytest.raises(ValidationError): dec.decode(proto.encode("bad")) class TestLax: @pytest.mark.parametrize("strict", [True, False]) def test_strict_lax_decoder(self, proto, strict): dec = proto.Decoder(List[int], strict=strict) assert dec.strict is strict msg = proto.encode(["1", "2"]) if strict: with pytest.raises(ValidationError): dec.decode(msg) else: assert dec.decode(msg) == [1, 2] def test_lax_none(self, proto): for x in ["null", "Null", "nUll", "nuLl", "nulL"]: msg = proto.encode(x) assert proto.decode(msg, type=None, strict=False) is None for x in ["xull", "nxll", "nuxl", "nulx"]: msg = proto.encode(x) with pytest.raises(ValidationError, match="Expected `null`, got `str`"): proto.decode(msg, type=None, strict=False) def test_lax_bool_true(self, proto): for x in [1, "1", "true", "True", "tRue", "trUe", "truE"]: msg = proto.encode(x) assert proto.decode(msg, type=bool, strict=False) is True for x in [-1, 3, "x", "xx", "xrue", "txue", "trxe", "trux"]: msg = proto.encode(x) typ = type(x).__name__ with pytest.raises(ValidationError, match=f"Expected `bool`, got `{typ}`"): assert proto.decode(msg, type=bool, strict=False) def test_lax_bool_false(self, proto): for x in [0, "0", "false", "False", "fAlse", "faLse", "falSe", "falsE"]: msg = proto.encode(x) assert proto.decode(msg, type=bool, strict=False) is False for x in [-1, 3, "x", "xx", "xalse", "fxlse", "faxse", "falxe", "falsx"]: msg = proto.encode(x) typ = type(x).__name__ with pytest.raises(ValidationError, match=f"Expected `bool`, got `{typ}`"): assert proto.decode(msg, type=bool, strict=False) def test_lax_int(self, proto): for x in ["1", "-1", "123456"]: msg = proto.encode(x) assert proto.decode(msg, type=int, strict=False) == int(x) for x in ["a", "1a", "1.5", "1..", "nan", "inf"]: msg = proto.encode(x) with pytest.raises(ValidationError, match="Expected `int`, got `str`"): proto.decode(msg, type=int, strict=False) def test_lax_int_from_float(self, proto): bound = float(1 << 53) for x in [-bound, -1.0, -0.0, 0.0, 1.0, bound]: msg = proto.encode(x) assert proto.decode(msg, type=int, strict=False) == int(x) for x in [-bound - 2, -1.5, 0.001, 1.5, bound + 2]: msg = proto.encode(x) with pytest.raises(ValidationError, match="Expected `int`, got `float`"): proto.decode(msg, type=int, strict=False) def test_lax_int_constr(self, proto): typ = Annotated[int, Meta(ge=0)] msg = proto.encode("1") assert proto.decode(msg, type=typ, strict=False) == 1 msg = proto.encode("-1") with pytest.raises(ValidationError): proto.decode(msg, type=typ, strict=False) def test_lax_int_enum(self, proto): class Ex(enum.IntEnum): x = 1 y = -2 def roundtrip(msg): return proto.decode(proto.encode(msg), type=Ex, strict=False) assert roundtrip("1") is Ex.x assert roundtrip("-2") is Ex.y with pytest.raises(ValidationError, match="Invalid enum value 3"): roundtrip("3") with pytest.raises(ValidationError, match="Expected `int`, got `str`"): roundtrip("A") def test_lax_int_literal(self, proto): typ = Literal[1, -2] def roundtrip(msg): return proto.decode(proto.encode(msg), type=typ, strict=False) assert roundtrip("1") == 1 assert roundtrip("-2") == -2 with pytest.raises(ValidationError, match="Invalid enum value 3"): roundtrip("3") with pytest.raises(ValidationError, match="Expected `int`, got `str`"): roundtrip("A") def test_lax_float(self, proto): for x in ["1", "-1", "123456", "1.5", "-1.5", "inf"]: msg = proto.encode(x) assert proto.decode(msg, type=float, strict=False) == float(x) for x in ["a", "1a", "1.0.0", "1.."]: msg = proto.encode(x) with pytest.raises(ValidationError, match="Expected `float`, got `str`"): proto.decode(msg, type=float, strict=False) def test_lax_float_constr(self, proto): msg = proto.encode("1.5") assert proto.decode(msg, type=Annotated[float, Meta(ge=0)], strict=False) == 1.5 msg = proto.encode("-1.0") with pytest.raises(ValidationError): proto.decode(msg, type=Annotated[float, Meta(ge=0)], strict=False) def test_lax_str(self, proto): for x in ["1", "1.5", "false", "null"]: msg = proto.encode(x) assert proto.decode(msg, type=str, strict=False) == x def test_lax_str_constr(self, proto): typ = Annotated[str, Meta(max_length=10)] msg = proto.encode("xxx") assert proto.decode(msg, type=typ, strict=False) == "xxx" msg = proto.encode("x" * 20) with pytest.raises(ValidationError): proto.decode(msg, type=typ, strict=False) @pytest.mark.parametrize( "x", [ 1234.0000004, 1234.0000006, 1234.000567, 1234.567, 1234.0, 0.123, 0.0, 1234, 0, ], ) @pytest.mark.parametrize("sign", [-1, 1]) @pytest.mark.parametrize("transform", [None, str]) def test_lax_datetime(self, x, sign, transform, proto): timestamp = x * sign msg = proto.encode(transform(timestamp) if transform else timestamp) sol = datetime.datetime.fromtimestamp(timestamp, UTC) res = proto.decode(msg, type=datetime.datetime, strict=False) assert res == sol def test_lax_datetime_nonfinite_values(self, proto): values = ["nan", "-inf", "inf"] if proto is msgspec.msgpack: values.extend([float(v) for v in values]) for val in values: msg = proto.encode(val) with pytest.raises(ValidationError, match="Invalid epoch timestamp"): proto.decode(msg, type=datetime.datetime, strict=False) @pytest.mark.parametrize("val", [-62135596801, 253402300801]) @pytest.mark.parametrize("type", [int, float, str]) def test_lax_datetime_out_of_range(self, val, type, proto): msg = proto.encode(type(val)) with pytest.raises(ValidationError, match="out of range"): proto.decode(msg, type=datetime.datetime, strict=False) def test_lax_datetime_invalid_numeric_str(self, proto): for bad in ["", "12e", "1234a", "1234-1", "1234.a"]: msg = proto.encode(bad) with pytest.raises(ValidationError, match="Invalid"): proto.decode(msg, type=datetime.datetime, strict=False) @pytest.mark.parametrize("val", [123, -123, 123.456, "123.456"]) def test_lax_datetime_naive_required(self, val, proto): msg = proto.encode(val) with pytest.raises(ValidationError, match="no timezone component"): proto.decode( msg, type=Annotated[datetime.datetime, Meta(tz=False)], strict=False ) @pytest.mark.parametrize( "x", [ 1234.0000004, 1234.0000006, 1234.000567, 1234.567, 1234.0, 0.123, 0.0, 1234, 0, ], ) @pytest.mark.parametrize("sign", [-1, 1]) @pytest.mark.parametrize("transform", [None, str]) def test_lax_timedelta(self, x, sign, transform, proto): timestamp = x * sign msg = proto.encode(transform(timestamp) if transform else timestamp) sol = datetime.timedelta(seconds=timestamp) res = proto.decode(msg, type=datetime.timedelta, strict=False) assert res == sol def test_lax_timedelta_nonfinite_values(self, proto): values = ["nan", "-inf", "inf"] if proto is msgspec.msgpack: values.extend([float(v) for v in values]) for val in values: msg = proto.encode(val) with pytest.raises(ValidationError, match="out of range"): proto.decode(msg, type=datetime.timedelta, strict=False) @pytest.mark.parametrize("val", [86400000000001, -86399999913601]) @pytest.mark.parametrize("type", [int, float, str]) def test_lax_timedelta_out_of_range(self, val, type, proto): msg = proto.encode(type(val)) with pytest.raises(ValidationError, match="out of range"): proto.decode(msg, type=datetime.timedelta, strict=False) def test_lax_timedelta_invalid_numeric_str(self, proto): for bad in ["", "12e", "1234a", "1234-1", "1234.a"]: msg = proto.encode(bad) with pytest.raises(ValidationError, match="Invalid"): proto.decode(msg, type=datetime.timedelta, strict=False) @pytest.mark.parametrize( "x, sol", [ ("1", 1), ("0", 0), ("-1", -1), ("12.5", 12.5), ("inf", float("inf")), ("true", True), ("false", False), ("null", None), ], ) def test_lax_union_valid(self, x, sol, proto): typ = Union[int, float, bool, None] msg = proto.encode(x) assert_eq(proto.decode(msg, type=typ, strict=False), sol) @pytest.mark.parametrize("x", ["1a", "1.5a", "falsx", "trux", "nulx"]) def test_lax_union_invalid(self, x, proto): typ = Union[int, float, bool, None] msg = proto.encode(x) with pytest.raises( ValidationError, match="Expected `int | float | bool | null`" ): proto.decode(msg, type=typ, strict=False) @pytest.mark.parametrize( "x, err", [ ("-1", "`int` >= 0"), ("2000", "`int` <= 1000"), ("18446744073709551616", "`int` <= 1000"), ("-9223372036854775809", "`int` >= 0"), ("100.5", "`float` <= 100.0"), ], ) def test_lax_union_invalid_constr(self, x, err, proto): """Ensure that values that parse properly but don't meet the specified constraints error with a specific constraint error""" msg = proto.encode(x) typ = Union[ Annotated[int, Meta(ge=0), Meta(le=1000)], Annotated[float, Meta(le=100)], ] with pytest.raises(ValidationError, match=err): proto.decode(msg, type=typ, strict=False) @pytest.mark.parametrize( "x, sol", [ ("1", 1), ("1.5", 1.5), ("false", False), ("true", True), ("null", None), ("2022-05-02", datetime.date(2022, 5, 2)), ], ) def test_lax_union_extended(self, proto, x, sol): typ = Union[int, float, bool, None, datetime.date] msg = proto.encode(x) assert_eq(proto.decode(msg, type=typ, strict=False), sol) python-msgspec-0.19.0/tests/test_constraints.py000066400000000000000000000646251473355726200217360ustar00rootroot00000000000000import datetime import math import re from typing import Dict, List, Union, Annotated import pytest import msgspec from msgspec import Meta @pytest.fixture(params=["json", "msgpack"]) def proto(request): if request.param == "json": return msgspec.json elif request.param == "msgpack": return msgspec.msgpack FIELDS = { "gt": 0, "ge": 0, "lt": 10, "le": 10, "multiple_of": 1, "pattern": "^foo$", "min_length": 0, "max_length": 10, "tz": True, "title": "example title", "description": "example description", "examples": ["example 1", "example 2"], "extra_json_schema": {"foo": "bar"}, "extra": {"fizz": "buzz"}, } def assert_eq(a, b): assert a == b assert not a != b def assert_ne(a, b): assert a != b assert not a == b class TestMetaObject: def test_init_nokwargs(self): c = Meta() for f in FIELDS: assert getattr(c, f) is None @pytest.mark.parametrize("field", FIELDS) def test_init_explicit_none(self, field): c = Meta(**{field: None}) for f in FIELDS: assert getattr(c, f) is None @pytest.mark.parametrize("field", FIELDS) def test_init(self, field): c = Meta(**{field: FIELDS[field]}) for f in FIELDS: sol = FIELDS[field] if f == field else None assert getattr(c, f) == sol def test_repr_empty(self): assert repr(Meta()) == "msgspec.Meta()" for field in FIELDS: c = Meta(**{field: None}) assert repr(c) == "msgspec.Meta()" def test_repr_error(self): class Oops: def __repr__(self): raise ValueError("Oh no!") m = Meta(extra_json_schema={"oops": Oops()}) with pytest.raises(ValueError, match="Oh no!"): repr(m) @pytest.mark.parametrize("field", FIELDS) def test_repr_one_field(self, field): c = Meta(**{field: FIELDS[field]}) assert repr(c) == f"msgspec.Meta({field}={FIELDS[field]!r})" def test_repr_multiple_fields(self): c = Meta(gt=0, lt=1) assert repr(c) == "msgspec.Meta(gt=0, lt=1)" def test_rich_repr_empty(self): assert Meta().__rich_repr__() == [] @pytest.mark.parametrize("field", FIELDS) def test_rich_repr_one_field(self, field): m = Meta(**{field: FIELDS[field]}) assert m.__rich_repr__() == [(field, FIELDS[field])] def test_rich_repr_multiple_fields(self): m = Meta(gt=0, lt=1) assert m.__rich_repr__() == [("gt", 0), ("lt", 1)] def test_equality(self): assert_eq(Meta(), Meta()) assert_ne(Meta(), None) with pytest.raises(TypeError): Meta() > Meta() with pytest.raises(TypeError): Meta() > None def test_hash(self): def samples(): return [ Meta(), Meta(ge=0), Meta(ge=1, le=2), Meta(ge=1, le=2, examples=["stuff"]), ] lk = {k: k for k in samples()} for key in samples(): assert lk[key] == key @pytest.mark.parametrize("field", FIELDS) def test_field_equality(self, field): val = FIELDS[field] if isinstance(val, dict): val2 = {} elif isinstance(val, list): val2 = [] elif isinstance(val, bool): val2 = not val elif isinstance(val, int): val2 = val + 25 else: val2 = "foobar" c = Meta(**{field: val}) c2 = Meta(**{field: val}) c3 = Meta(**{field: val2}) c4 = Meta() assert_eq(c, c) assert_eq(c, c2) assert_ne(c, c3) assert_ne(c, c4) assert_ne(c4, c) @pytest.mark.parametrize("field", ["gt", "ge", "lt", "le", "multiple_of"]) def test_numeric_fields(self, field): Meta(**{field: 1}) Meta(**{field: 2.5}) with pytest.raises( TypeError, match=f"`{field}` must be an int or float, got str" ): Meta(**{field: "bad"}) with pytest.raises(ValueError, match=f"`{field}` must be finite"): Meta(**{field: float("inf")}) @pytest.mark.parametrize("val", [0, 0.0]) def test_multiple_of_bounds(self, val): with pytest.raises(ValueError, match=r"`multiple_of` must be > 0"): Meta(multiple_of=val) @pytest.mark.parametrize("field", ["min_length", "max_length"]) def test_nonnegative_integer_fields(self, field): Meta(**{field: 0}) Meta(**{field: 10}) with pytest.raises(TypeError, match=f"`{field}` must be an int, got float"): Meta(**{field: 1.5}) with pytest.raises(ValueError, match=f"{field}` must be >= 0, got -10"): Meta(**{field: -10}) @pytest.mark.parametrize("field", ["pattern", "title", "description"]) def test_string_fields(self, field): Meta(**{field: "good"}) with pytest.raises(TypeError, match=f"`{field}` must be a str, got bytes"): Meta(**{field: b"bad"}) @pytest.mark.parametrize("field", ["tz"]) def test_bool_fields(self, field): Meta(**{field: True}) Meta(**{field: False}) with pytest.raises(TypeError, match=f"`{field}` must be a bool, got float"): Meta(**{field: 1.5}) @pytest.mark.parametrize("field", ["examples"]) def test_list_fields(self, field): Meta(**{field: ["good", "stuff"]}) with pytest.raises(TypeError, match=f"`{field}` must be a list, got str"): Meta(**{field: "bad"}) @pytest.mark.parametrize("field", ["extra_json_schema", "extra"]) def test_dict_fields(self, field): Meta(**{field: {"good": "stuff"}}) with pytest.raises(TypeError, match=f"`{field}` must be a dict, got str"): Meta(**{field: "bad"}) def test_invalid_pattern_errors(self): with pytest.raises(re.error): Meta(pattern="[abc") def test_conflicting_bounds_errors(self): with pytest.raises(ValueError, match="both `gt` and `ge`"): Meta(gt=0, ge=1) with pytest.raises(ValueError, match="both `lt` and `le`"): Meta(lt=0, le=1) def test_mixing_numeric_and_nonnumeric_constraints_errors(self): with pytest.raises(ValueError, match="Cannot mix numeric constraints"): Meta(gt=0, pattern="foo") class TestInvalidConstraintAnnotations: """Constraint validity is applied in two places: - Type checks on constraint values in the `Meta` constructor - Type checks on type & constraint annotations in Decoder constructors The tests here check the latter. """ @pytest.mark.parametrize("name", ["ge", "gt", "le", "lt", "multiple_of"]) def test_invalid_numeric_constraints(self, name): with pytest.raises(TypeError, match=f"Can only set `{name}` on a numeric type"): msgspec.json.Decoder(Annotated[str, Meta(**{name: 1})]) def test_invalid_pattern_constraint(self): with pytest.raises(TypeError, match="Can only set `pattern` on a str type"): msgspec.json.Decoder(Annotated[int, Meta(pattern="ok")]) @pytest.mark.parametrize("name", ["min_length", "max_length"]) def test_invalid_length_constraint(self, name): with pytest.raises( TypeError, match=f"Can only set `{name}` on a str, bytes, or collection type", ): msgspec.json.Decoder(Annotated[int, Meta(**{name: 1})]) def test_invalid_tz_constraint(self): with pytest.raises( TypeError, match="Can only set `tz` on a datetime or time type", ): msgspec.json.Decoder(Annotated[int, Meta(tz=True)]) @pytest.mark.parametrize( "name, val", [("ge", 2**63), ("gt", 2**63 - 1), ("le", 2**63), ("lt", -(2**63))], ) def test_invalid_integer_bounds(self, name, val): with pytest.raises(ValueError) as rec: msgspec.json.Decoder(Annotated[int, Meta(**{name: val})]) assert name in str(rec.value) assert "not supported" in str(rec.value) def test_invalid_multiple_meta_annotations_conflict(self): with pytest.raises(TypeError, match="Multiple `Meta` annotations"): msgspec.json.Decoder(Annotated[int, Meta(ge=1), Meta(ge=2)]) def test_invalid_gt_and_ge_conflict(self): with pytest.raises(TypeError, match="Cannot set both `gt` and `ge`"): msgspec.json.Decoder(Annotated[int, Meta(gt=1), Meta(ge=2)]) def test_invalid_lt_and_le_conflict(self): with pytest.raises(TypeError, match="Cannot set both `lt` and `le`"): msgspec.json.Decoder(Annotated[int, Meta(lt=2), Meta(le=1)]) class TestIntConstraints: @pytest.mark.parametrize( "name, bound, good, bad", [ ("ge", -1, [-1, 2**63, 2**65], [-(2**64), -2]), ("gt", -1, [0, 2**63, 2**65], [-(2**64), -1]), ("le", -1, [-(2**64), -1], [0, 2**63, 2**65]), ("lt", -1, [-(2**64), -2], [-1, 2**63, 2**65]), ], ) def test_bounds(self, proto, name, bound, good, bad): if proto is msgspec.msgpack: # msgpack only supports int64/uint64 values good = [i for i in good if -(2**63) - 1 <= i <= 2**64] bad = [i for i in bad if -(2**63) - 1 <= i <= 2**64] class Ex(msgspec.Struct): x: Annotated[int, Meta(**{name: bound})] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x op = ">=" if name.startswith("g") else "<=" offset = {"lt": -1, "gt": 1}.get(name, 0) err_msg = rf"Expected `int` {op} {bound + offset} - at `\$.x`" for x in bad: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) def test_multiple_of(self, proto): good = [-(2**64), -2, 0, 2, 40, 2**63 + 2, 2**65] bad = [1, -1, 2**63 + 1, 2**65 + 1] if proto is msgspec.msgpack: # msgpack only supports int64/uint64 values good = [i for i in good if -(2**63) - 1 <= i <= 2**64] bad = [i for i in bad if -(2**63) - 1 <= i <= 2**64] class Ex(msgspec.Struct): x: Annotated[int, Meta(multiple_of=2)] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `int` that's a multiple of 2 - at `\$.x`" for x in bad: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize( "meta, good, bad", [ (Meta(ge=0, le=10, multiple_of=2), [0, 2, 10], [-1, 1, 11]), (Meta(ge=0, multiple_of=2), [0, 2**63 + 2], [-2, 2**63 + 1]), (Meta(le=0, multiple_of=2), [0, -(2**63)], [-1, 2, 2**63]), (Meta(ge=0, le=10), [0, 10], [-1, 11]), (Meta(gt=0, lt=10), [1, 2, 9], [-1, 0, 10]), ], ) def test_combinations(self, proto, meta, good, bad): class Ex(msgspec.Struct): x: Annotated[int, meta] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x for x in bad: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) class TestFloatConstraints: @pytest.mark.parametrize("name", ["ge", "gt", "le", "lt"]) def test_bound_constraint_uint64_valid_for_floats(self, name): typ = Annotated[float, Meta(**{name: 2**63})] msgspec.json.Decoder(typ) def get_bounds_cases(self, name, bound): def ceilp1(x): return int(math.ceil(x + 1)) def floorm1(x): return int(math.floor(x - 1)) if name.startswith("g"): good_dir = math.inf good_round = ceilp1 bad_round = floorm1 else: good_dir = -math.inf good_round = floorm1 bad_round = ceilp1 if name.endswith("e"): good = bound bad = math.nextafter(bound, -good_dir) else: good = math.nextafter(bound, good_dir) bad = bound good_cases = [good, good_round(good), float(good_round(good))] bad_cases = [bad, bad_round(bad), float(bad_round(bad))] op = ">" if name.startswith("g") else "<" if name.endswith("e"): op += "=" return good_cases, bad_cases, op @pytest.mark.parametrize("name", ["ge", "gt", "le", "lt"]) @pytest.mark.parametrize("bound", [1.5, -1.5, 10.0]) def test_bounds(self, proto, name, bound): class Ex(msgspec.Struct): x: Annotated[float, Meta(**{name: bound})] dec = proto.Decoder(Ex) good, bad, op = self.get_bounds_cases(name, bound) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = rf"Expected `float` {op} {bound} - at `\$.x`" for x in bad: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) def test_multiple_of(self, proto): """multipleOf for floats will always have precisions issues. This check just ensures that _some_ cases work. See https://github.com/json-schema-org/json-schema-spec/issues/312 for more info.""" class Ex(msgspec.Struct): x: Annotated[float, Meta(multiple_of=0.1)] dec = proto.Decoder(Ex) for x in [0, 0.0, 0.1, -0.1, 0.2, -0.2]: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `float` that's a multiple of 0.1 - at `\$.x`" for x in [0.01, -0.15]: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize( "meta, good, bad", [ (Meta(ge=0.0, le=10.0, multiple_of=2.0), [0, 2.0, 10], [-2, 11, 3]), (Meta(ge=0.0, multiple_of=2.0), [0, 2, 10.0], [-2, 3]), (Meta(le=10.0, multiple_of=2.0), [-2.0, 10.0], [11.0, 3.0]), (Meta(ge=0.0, le=10.0), [0.0, 2.0, 10.0], [-1.0, 11.5, 11]), ], ) def test_combinations(self, proto, meta, good, bad): class Ex(msgspec.Struct): x: Annotated[float, meta] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x for x in bad: with pytest.raises(msgspec.ValidationError): assert dec.decode(proto.encode(Ex(x))) class TestStrConstraints: def test_min_length(self, proto): class Ex(msgspec.Struct): x: Annotated[str, Meta(min_length=2)] dec = proto.Decoder(Ex) for x in ["xx", "xxx", "𝄞x"]: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `str` of length >= 2 - at `\$.x`" for x in ["x", "𝄞", ""]: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) def test_max_length(self, proto): class Ex(msgspec.Struct): x: Annotated[str, Meta(max_length=2)] dec = proto.Decoder(Ex) for x in ["", "xx", "𝄞x"]: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `str` of length <= 2 - at `\$.x`" for x in ["xxx", "𝄞xx"]: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize( "pattern, good, bad", [ ("", ["", "test"], []), ("as", ["as", "ease", "ast", "pass"], ["", "nope"]), ("^pre[123]*$", ["pre1", "pre123"], ["apre1", "pre1two"]), ], ) def test_pattern(self, proto, pattern, good, bad): class Ex(msgspec.Struct): x: Annotated[str, Meta(pattern=pattern)] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x err_msg = f"Expected `str` matching regex {pattern!r} - at `$.x`" for x in bad: with pytest.raises(msgspec.ValidationError) as rec: dec.decode(proto.encode(Ex(x))) assert str(rec.value) == err_msg @pytest.mark.parametrize( "meta, good, bad", [ ( Meta(min_length=2, max_length=3, pattern="x"), ["xy", "xyz"], ["x", "yy", "wxyz"], ), (Meta(min_length=2, max_length=4), ["xx", "xxxx"], ["x", "xxxxx"]), (Meta(min_length=2, pattern="x"), ["xy", "wxyz"], ["x", "bad"]), (Meta(max_length=3, pattern="x"), ["xy", "xyz"], ["y", "wxyz"]), ], ) def test_combinations(self, proto, meta, good, bad): class Ex(msgspec.Struct): x: Annotated[str, meta] dec = proto.Decoder(Ex) for x in good: assert dec.decode(proto.encode(Ex(x))).x == x for x in bad: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize( "meta, good, bad", [ (Meta(min_length=2), ["xy", "𝄞xy"], ["", "𝄞"]), (Meta(pattern="as"), ["as", "pass", "𝄞as"], ["", "nope", "𝄞"]), ], ) def test_str_constraints_on_dict_keys(self, proto, meta, good, bad): dec = proto.Decoder(Dict[Annotated[str, meta], int]) for x in good: assert dec.decode(proto.encode({x: 1})) == {x: 1} for x in bad: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode({x: 1})) class TestDateTimeConstraints: @staticmethod def roundtrip(proto, cls, aware, as_str): dt = datetime.datetime.now(datetime.timezone.utc if aware else None) if as_str: s = proto.encode(cls(dt.isoformat())) else: s = proto.encode(cls(dt)) res = proto.decode(s, type=cls) assert res.x == dt @pytest.mark.parametrize("as_str", [True, False]) def test_tz_none(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.datetime, Meta(tz=None)] self.roundtrip(proto, Ex, True, as_str) self.roundtrip(proto, Ex, False, as_str) @pytest.mark.parametrize("as_str", [True, False]) def test_tz_false(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.datetime, Meta(tz=False)] self.roundtrip(proto, Ex, False, as_str) err_msg = r"Expected `datetime` with no timezone component - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): self.roundtrip(proto, Ex, True, as_str) @pytest.mark.parametrize("as_str", [True, False]) def test_tz_true(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.datetime, Meta(tz=True)] self.roundtrip(proto, Ex, True, as_str) err_msg = r"Expected `datetime` with a timezone component - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): self.roundtrip(proto, Ex, False, as_str) class TestTimeConstraints: @staticmethod def roundtrip(proto, cls, aware, as_str): dt = datetime.datetime.now(datetime.timezone.utc if aware else None).timetz() if as_str: s = proto.encode(cls(dt.isoformat())) else: s = proto.encode(cls(dt)) res = proto.decode(s, type=cls) assert res.x == dt @pytest.mark.parametrize("as_str", [True, False]) def test_tz_none(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.time, Meta(tz=None)] self.roundtrip(proto, Ex, True, as_str) self.roundtrip(proto, Ex, False, as_str) @pytest.mark.parametrize("as_str", [True, False]) def test_tz_false(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.time, Meta(tz=False)] self.roundtrip(proto, Ex, False, as_str) err_msg = r"Expected `time` with no timezone component - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): self.roundtrip(proto, Ex, True, as_str) @pytest.mark.parametrize("as_str", [True, False]) def test_tz_true(self, proto, as_str): class Ex(msgspec.Struct): x: Annotated[datetime.time, Meta(tz=True)] self.roundtrip(proto, Ex, True, as_str) err_msg = r"Expected `time` with a timezone component - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): self.roundtrip(proto, Ex, False, as_str) class TestBytesConstraints: @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_min_length(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(min_length=2)] dec = proto.Decoder(Ex) for x in [b"xx", b"xxx"]: assert bytes(dec.decode(proto.encode(Ex(x))).x) == x err_msg = r"Expected `bytes` of length >= 2 - at `\$.x`" for x in [b"", b"x"]: with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_max_length(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(max_length=2)] dec = proto.Decoder(Ex) for x in [b"", b"xx"]: assert bytes(dec.decode(proto.encode(Ex(x))).x) == x err_msg = r"Expected `bytes` of length <= 2 - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(b"xxx"))) @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_combinations(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(min_length=2, max_length=4)] dec = proto.Decoder(Ex) for x in [b"xx", b"xxx", b"xxxx"]: assert bytes(dec.decode(proto.encode(Ex(x))).x) == x for x in [b"x", b"xxxxx"]: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) class TestArrayConstraints: @pytest.mark.parametrize("typ", [list, tuple, set, frozenset]) def test_min_length(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(min_length=2)] dec = proto.Decoder(Ex) for n in [2, 3]: x = typ(range(n)) assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `array` of length >= 2 - at `\$.x`" for n in [0, 1]: x = typ(range(n)) with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) @pytest.mark.parametrize("typ", [list, tuple, set, frozenset]) def test_max_length(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(max_length=2)] dec = proto.Decoder(Ex) for n in [0, 2]: x = typ(range(n)) assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `array` of length <= 2 - at `\$.x`" with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(typ(range(3))))) @pytest.mark.parametrize("typ", [list, tuple, set, frozenset]) def test_combinations(self, proto, typ): class Ex(msgspec.Struct): x: Annotated[typ, Meta(min_length=2, max_length=4)] dec = proto.Decoder(Ex) for n in [2, 3, 4]: x = typ(range(n)) assert dec.decode(proto.encode(Ex(x))).x == x for n in [1, 5]: x = typ(range(n)) with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) class TestMapConstraints: def test_min_length(self, proto): class Ex(msgspec.Struct): x: Annotated[Dict[str, int], Meta(min_length=2)] dec = proto.Decoder(Ex) for n in [2, 3]: x = {str(i): i for i in range(n)} assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `object` of length >= 2 - at `\$.x`" for n in [0, 1]: x = {str(i): i for i in range(n)} with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) def test_max_length(self, proto): class Ex(msgspec.Struct): x: Annotated[Dict[str, int], Meta(max_length=2)] dec = proto.Decoder(Ex) for n in [0, 2]: x = {str(i): i for i in range(n)} assert dec.decode(proto.encode(Ex(x))).x == x err_msg = r"Expected `object` of length <= 2 - at `\$.x`" x = {"1": 1, "2": 2, "3": 3} with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(proto.encode(Ex(x))) def test_combinations(self, proto): class Ex(msgspec.Struct): x: Annotated[Dict[str, int], Meta(min_length=2, max_length=4)] dec = proto.Decoder(Ex) for n in [2, 3, 4]: x = {str(i): i for i in range(n)} assert dec.decode(proto.encode(Ex(x))).x == x for n in [1, 5]: x = {str(i): i for i in range(n)} with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) class TestUnionConstraints: def test_mix_float_and_int(self, proto): class Ex(msgspec.Struct): x: Union[ Annotated[int, Meta(ge=0, le=10)], Annotated[float, Meta(ge=1000, le=2000)], ] dec = proto.Decoder(Ex) for x in [0, 5, 10, 1000.0, 1234.5, 2000.0]: assert dec.decode(proto.encode(Ex(x))).x == x for x in [0.0, 10.0, 1000, 2000]: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) def test_mix_length_constraints(self, proto): class Ex(msgspec.Struct): x: Union[ Annotated[Dict[str, int], Meta(min_length=1, max_length=2)], Annotated[List[int], Meta(min_length=3, max_length=4)], Annotated[str, Meta(min_length=5, max_length=6)], ] dec = proto.Decoder(Ex) for x in [{"x": 1}, [1, 2, 3], "xxxxx"]: assert dec.decode(proto.encode(Ex(x))).x == x for x in [{}, [1], "x"]: with pytest.raises(msgspec.ValidationError): dec.decode(proto.encode(Ex(x))) python-msgspec-0.19.0/tests/test_convert.py000066400000000000000000002422351473355726200210420ustar00rootroot00000000000000import datetime import decimal import enum import gc import math import sys import uuid from base64 import b64encode from collections.abc import MutableMapping from dataclasses import dataclass, field from typing import ( Annotated, Any, Dict, FrozenSet, Generic, List, Literal, NamedTuple, Set, Tuple, TypeVar, TypedDict, Union, ) import pytest from utils import temp_module, max_call_depth import msgspec from msgspec import Meta, Struct, ValidationError, convert, to_builtins try: import attrs except ImportError: attrs = None PY310 = sys.version_info[:2] >= (3, 10) PY311 = sys.version_info[:2] >= (3, 11) PY312 = sys.version_info[:2] >= (3, 12) UTC = datetime.timezone.utc T = TypeVar("T") class GetAttrObj: def __init__(self, _data=None, **kwargs): self._data = _data or {} self._data.update(kwargs) def __getattr__(self, key): try: return self._data[key] except KeyError: raise AttributeError(key) from None class GetItemObj(MutableMapping): def __init__(self, _data=None, **kwargs): self._data = _data or {} self._data.update(kwargs) def __getitem__(self, key): return self._data[key] def __setitem__(self, key, val): self._data[key] = val def __delitem__(self, key): del self._data[key] def __iter__(self): return iter(self._data) def __len__(self): return len(self._data) class GetAttrOrItemObj: def __init__(self, _data=None, **kwargs): self._attrs = _data or {} self._attrs.update(kwargs) self._items = {} if self._attrs: k, v = self._attrs.popitem() self._items[k] = v def __getitem__(self, key): return self._items[key] def __getattr__(self, key): try: return self._attrs[key] except KeyError: raise AttributeError(key) from None def KWList(**kwargs): return list(kwargs.values()) class SubList(list): pass class SubTuple(tuple): pass class SubSet(set): pass class SubFrozenSet(frozenset): pass class SubDict(dict): pass mapcls_and_from_attributes = pytest.mark.parametrize( "mapcls, from_attributes", [ (dict, False), (SubDict, False), (GetAttrObj, True), (GetAttrOrItemObj, True), (GetItemObj, False), ], ) mapcls_from_attributes_and_array_like = pytest.mark.parametrize( "mapcls, from_attributes, array_like", [ (dict, False, False), (SubDict, False, False), (KWList, False, True), (GetAttrObj, True, True), (GetAttrObj, True, False), (GetAttrOrItemObj, True, True), (GetAttrOrItemObj, True, False), (GetAttrOrItemObj, False, False), (GetItemObj, False, False), ], ) seq_in_type = pytest.mark.parametrize( "in_type", [ list, tuple, set, frozenset, SubList, SubTuple, SubSet, SubFrozenSet, ], ) @pytest.fixture(params=["dict", "subclass", "mapping"]) def dictcls(request): if request.param == "dict": return dict elif request.param == "subclass": return SubDict else: return GetItemObj def assert_eq(x, y): assert type(x) is type(y) if type(x) is float and math.isnan(x): return math.isnan(y) assert x == y def roundtrip(obj, typ): return convert(to_builtins(obj), typ) class TestConvert: def test_bad_calls(self): with pytest.raises(TypeError): convert() with pytest.raises(TypeError): convert(1) with pytest.raises( TypeError, match="builtin_types must be an iterable of types" ): convert(1, int, builtin_types=1) with pytest.raises(TypeError) as rec: convert(1, int, builtin_types=(int,)) assert "Cannot treat" in str(rec.value) assert "int" in str(rec.value) with pytest.raises(TypeError, match="dec_hook must be callable"): convert(1, int, dec_hook=1) def test_dec_hook_explicit_none(self): assert convert(1, int, dec_hook=None) == 1 def test_custom_input_type(self): class Custom: pass with pytest.raises(ValidationError, match="Expected `int`, got `Custom`"): convert(Custom(), int) def test_custom_input_type_works_with_any(self): class Custom: pass x = Custom() res = convert(x, Any) assert res is x assert sys.getrefcount(x) == 3 # x + res + 1 def test_custom_input_type_works_with_custom(self): class Custom: pass x = Custom() res = convert(x, Custom) assert res is x assert sys.getrefcount(x) == 3 # x + res + 1 def test_custom_input_type_works_with_dec_hook(self): class Custom: pass class Custom2: pass def dec_hook(typ, x): if typ is Custom2: assert isinstance(x, Custom) return Custom2() raise TypeError x = Custom() res = convert(x, Custom2, dec_hook=dec_hook) assert isinstance(res, Custom2) assert sys.getrefcount(res) == 2 # res + 1 assert sys.getrefcount(x) == 2 # x + 1 def test_unsupported_output_type(self): with pytest.raises(TypeError, match="more than one array-like"): convert({}, Union[List[int], Tuple[str, ...]]) @pytest.mark.parametrize( "val, got", [ (None, "null"), (True, "bool"), (1, "int"), (1.5, "float"), ("a", "str"), (b"b", "bytes"), (bytearray(b"c"), "bytes"), (datetime.datetime(2022, 1, 2), "datetime"), (datetime.time(12, 34), "time"), (datetime.date(2022, 1, 2), "date"), (uuid.uuid4(), "uuid"), (decimal.Decimal("1.5"), "decimal"), ([1], "array"), ((1,), "array"), ({"a": 1}, "object"), ], ) def test_wrong_type(self, val, got): # An arbitrary wrong type, if isinstance(val, int): typ = str expected = "str" else: typ = int expected = "int" msg = f"Expected `{expected}`, got `{got}`" with pytest.raises(ValidationError, match=msg): convert(val, typ) class TestAny: @pytest.mark.parametrize("msg", [(1, 2), {"a": 1}, object(), {1, 2}]) def test_any_passthrough(self, msg): assert convert(msg, Any) is msg class TestNone: def test_none(self): assert convert(None, Any) is None assert convert(None, None) is None with pytest.raises(ValidationError, match="Expected `null`, got `int`"): convert(1, None) class TestBool: @pytest.mark.parametrize("val", [True, False]) def test_bool(self, val): assert convert(val, Any) is val assert convert(val, bool) is val def test_bool_invalid(self): with pytest.raises(ValidationError, match="Expected `bool`, got `int`"): convert(1, bool) with pytest.raises(ValidationError, match="Expected `bool`, got `str`"): convert("true", bool) class TestInt: def test_int(self): assert convert(1, Any) == 1 assert convert(1, int) == 1 with pytest.raises(ValidationError, match="Expected `int`, got `float`"): convert(1.5, int) @pytest.mark.parametrize("val", [2**64, -(2**63) - 1]) def test_convert_big_ints(self, val): class myint(int): pass assert_eq(convert(val, int), val) assert_eq(convert(myint(val), int), val) @pytest.mark.parametrize( "name, bound, good, bad", [ ("ge", -1, [-1, 2**63, 2**65], [-(2**64), -2]), ("gt", -1, [0, 2**63, 2**65], [-(2**64), -1]), ("le", -1, [-(2**64), -1], [0, 2**63, 2**65]), ("lt", -1, [-(2**64), -2], [-1, 2**63, 2**65]), ], ) def test_int_constr_bounds(self, name, bound, good, bad): class Ex(Struct): x: Annotated[int, Meta(**{name: bound})] for x in good: assert convert({"x": x}, Ex).x == x op = ">=" if name.startswith("g") else "<=" offset = {"lt": -1, "gt": 1}.get(name, 0) err_msg = rf"Expected `int` {op} {bound + offset} - at `\$.x`" for x in bad: with pytest.raises(ValidationError, match=err_msg): convert({"x": x}, Ex) def test_int_constr_multiple_of(self): class Ex(Struct): x: Annotated[int, Meta(multiple_of=2)] for x in [-(2**64), -2, 0, 2, 40, 2**63 + 2, 2**65]: assert convert({"x": x}, Ex).x == x err_msg = r"Expected `int` that's a multiple of 2 - at `\$.x`" for x in [1, -(2**64) + 1, -1, 2**63 + 1, 2**65 + 1]: with pytest.raises(ValidationError, match=err_msg): convert({"x": x}, Ex) @pytest.mark.parametrize( "meta, good, bad", [ (Meta(ge=0, le=10, multiple_of=2), [0, 2, 10], [-1, 1, 11]), (Meta(ge=0, multiple_of=2), [0, 2**63 + 2], [-2, 2**63 + 1]), (Meta(le=0, multiple_of=2), [0, -(2**63)], [-1, 2, 2**63]), (Meta(ge=0, le=10), [0, 10], [-1, 11]), ], ) def test_int_constrs(self, meta, good, bad): class Ex(Struct): x: Annotated[int, meta] for x in good: assert convert({"x": x}, Ex).x == x for x in bad: with pytest.raises(ValidationError): convert({"x": x}, Ex) def test_int_subclass(self): class MyInt(int): pass for val in [10, 0, -10]: sol = convert(MyInt(val), int) assert type(sol) is int assert sol == val x = MyInt(100) sol = convert(x, MyInt) assert sol is x assert sys.getrefcount(x) == 3 # x + sol + 1 class TestFloat: def test_float(self): assert convert(1.5, Any) == 1.5 assert convert(1.5, float) == 1.5 res = convert(1, float) assert res == 1.0 assert isinstance(res, float) with pytest.raises(ValidationError, match="Expected `float`, got `null`"): convert(None, float) @pytest.mark.parametrize( "meta, good, bad", [ (Meta(ge=0.0, le=10.0, multiple_of=2.0), [0, 2.0, 10], [-2, 11, 3]), (Meta(ge=0.0, multiple_of=2.0), [0, 2, 10.0], [-2, 3]), (Meta(le=10.0, multiple_of=2.0), [-2.0, 10.0], [11.0, 3.0]), (Meta(ge=0.0, le=10.0), [0.0, 2.0, 10.0], [-1.0, 11.5, 11]), ], ) def test_float_constrs(self, meta, good, bad): class Ex(Struct): x: Annotated[float, meta] for x in good: assert convert({"x": x}, Ex).x == x for x in bad: with pytest.raises(ValidationError): convert({"x": x}, Ex) def test_float_from_decimal(self): res = convert(decimal.Decimal("1.5"), float) assert res == 1.5 assert type(res) is float def test_constr_float_from_decimal(self): typ = Annotated[float, Meta(ge=0)] res = convert(decimal.Decimal("1.5"), typ) assert res == 1.5 assert type(res) is float with pytest.raises(ValidationError, match="Expected `float` >= 0.0"): convert(decimal.Decimal("-1.5"), typ) class TestStr: def test_str(self): assert convert("test", Any) == "test" assert convert("test", str) == "test" with pytest.raises(ValidationError, match="Expected `str`, got `bytes`"): convert(b"test", str) @pytest.mark.parametrize( "meta, good, bad", [ ( Meta(min_length=2, max_length=3, pattern="x"), ["xy", "xyz"], ["x", "yy", "wxyz"], ), (Meta(min_length=2, max_length=4), ["xx", "xxxx"], ["x", "xxxxx"]), (Meta(min_length=2, pattern="x"), ["xy", "wxyz"], ["x", "bad"]), (Meta(max_length=3, pattern="x"), ["xy", "xyz"], ["y", "wxyz"]), ], ) def test_str_constrs(self, meta, good, bad): class Ex(Struct): x: Annotated[str, meta] for x in good: assert convert({"x": x}, Ex).x == x for x in bad: with pytest.raises(ValidationError): convert({"x": x}, Ex) class TestBinary: @pytest.mark.parametrize("out_type", [bytes, bytearray, memoryview]) def test_binary_wrong_type(self, out_type): with pytest.raises(ValidationError, match="Expected `bytes`, got `int`"): convert(1, out_type) @pytest.mark.parametrize("in_type", [bytes, bytearray, memoryview]) @pytest.mark.parametrize("out_type", [bytes, bytearray, memoryview]) def test_binary_builtin(self, in_type, out_type): res = convert(in_type(b"test"), out_type) assert res == b"test" assert isinstance(res, out_type) @pytest.mark.parametrize("out_type", [bytes, bytearray, memoryview]) def test_binary_base64(self, out_type): res = convert("AQI=", out_type) assert res == b"\x01\x02" assert isinstance(res, out_type) @pytest.mark.parametrize("out_type", [bytes, bytearray, memoryview]) def test_binary_base64_disabled(self, out_type): with pytest.raises(ValidationError, match="Expected `bytes`, got `str`"): convert("AQI=", out_type, builtin_types=(bytes, bytearray, memoryview)) @pytest.mark.parametrize("in_type", [bytes, bytearray, memoryview, str]) @pytest.mark.parametrize("out_type", [bytes, bytearray, memoryview]) def test_binary_constraints(self, in_type, out_type): class Ex(Struct): x: Annotated[out_type, Meta(min_length=2, max_length=4)] for x in [b"xx", b"xxx", b"xxxx"]: if in_type is str: msg = {"x": b64encode(x).decode("utf-8")} else: msg = {"x": in_type(x)} assert convert(msg, Ex).x == x for x in [b"x", b"xxxxx"]: if in_type is str: msg = {"x": b64encode(x).decode("utf-8")} else: msg = {"x": in_type(x)} with pytest.raises(ValidationError): convert(msg, Ex) def test_bytes_subclass(self): class MyBytes(bytes): pass msg = MyBytes(b"abc") for typ in [bytes, bytearray, memoryview]: sol = convert(msg, typ) assert type(sol) is typ assert sol == b"abc" del sol assert sys.getrefcount(msg) == 2 # msg + 1 sol = convert(msg, MyBytes) assert sol is msg assert sys.getrefcount(msg) == 3 # msg + sol + 1 class TestDateTime: def test_datetime_wrong_type(self): with pytest.raises(ValidationError, match="Expected `datetime`, got `int`"): convert(1, datetime.datetime) @pytest.mark.parametrize("tz", [False, True]) def test_datetime_builtin(self, tz): dt = datetime.datetime.now(UTC if tz else None) assert convert(dt, datetime.datetime) is dt @pytest.mark.parametrize("tz", [False, True]) def test_datetime_str(self, tz): sol = datetime.datetime(1, 2, 3, 4, 5, 6, 7, UTC if tz else None) msg = "0001-02-03T04:05:06.000007" + ("Z" if tz else "") res = convert(msg, datetime.datetime) assert res == sol def test_datetime_str_disabled(self): with pytest.raises(ValidationError, match="Expected `datetime`, got `str`"): convert( "0001-02-03T04:05:06.000007Z", datetime.datetime, builtin_types=(datetime.datetime,), ) @pytest.mark.parametrize("as_str", [False, True]) def test_datetime_constrs(self, as_str): class Ex(Struct): x: Annotated[datetime.datetime, Meta(tz=True)] builtin_types = None if as_str else (datetime.datetime,) aware = Ex(datetime.datetime(1, 2, 3, 4, 5, 6, 7, UTC)) aware_msg = to_builtins(aware, builtin_types=builtin_types) naive = Ex(datetime.datetime(1, 2, 3, 4, 5, 6, 7)) naive_msg = to_builtins(naive, builtin_types=builtin_types) assert convert(aware_msg, Ex) == aware with pytest.raises(ValidationError): convert(naive_msg, Ex) class TestTime: def test_time_wrong_type(self): with pytest.raises(ValidationError, match="Expected `time`, got `int`"): convert(1, datetime.time) @pytest.mark.parametrize("tz", [False, True]) def test_time_builtin(self, tz): t = datetime.time(12, 34, tzinfo=(UTC if tz else None)) assert convert(t, datetime.time) is t @pytest.mark.parametrize("tz", [False, True]) def test_time_str(self, tz): sol = datetime.time(12, 34, tzinfo=(UTC if tz else None)) msg = "12:34:00" + ("Z" if tz else "") res = convert(msg, datetime.time) assert res == sol def test_time_str_disabled(self): with pytest.raises(ValidationError, match="Expected `time`, got `str`"): convert("12:34:00Z", datetime.time, builtin_types=(datetime.time,)) @pytest.mark.parametrize("as_str", [False, True]) def test_time_constrs(self, as_str): class Ex(Struct): x: Annotated[datetime.time, Meta(tz=True)] builtin_types = None if as_str else (datetime.time,) aware = Ex(datetime.time(12, 34, tzinfo=UTC)) aware_msg = to_builtins(aware, builtin_types=builtin_types) naive = Ex(datetime.time(12, 34)) naive_msg = to_builtins(naive, builtin_types=builtin_types) assert convert(aware_msg, Ex) == aware with pytest.raises(ValidationError): convert(naive_msg, Ex) class TestDate: def test_date_wrong_type(self): with pytest.raises(ValidationError, match="Expected `date`, got `int`"): convert(1, datetime.date) def test_date_builtin(self): dt = datetime.date.today() assert convert(dt, datetime.date) is dt def test_date_str(self): sol = datetime.date.today() res = convert(sol.isoformat(), datetime.date) assert res == sol def test_date_str_disabled(self): with pytest.raises(ValidationError, match="Expected `date`, got `str`"): convert("2022-01-02", datetime.date, builtin_types=(datetime.date,)) class TestTimeDelta: def test_timedelta_wrong_type(self): with pytest.raises(ValidationError, match="Expected `duration`, got `array`"): convert([], datetime.timedelta) def test_timedelta_builtin(self): td = datetime.timedelta(1) assert convert(td, datetime.timedelta) is td def test_timedelta_str(self): sol = datetime.timedelta(1, 2) res = convert("P1DT2S", datetime.timedelta) assert res == sol def test_timedelta_str_disabled(self): with pytest.raises(ValidationError, match="Expected `duration`, got `str`"): convert("P1DT2S", datetime.timedelta, builtin_types=(datetime.timedelta,)) class TestUUID: def test_uuid_wrong_type(self): with pytest.raises(ValidationError, match="Expected `uuid`, got `int`"): convert(1, uuid.UUID) def test_uuid_builtin(self): x = uuid.uuid4() assert convert(x, uuid.UUID) is x def test_uuid_str(self): sol = uuid.uuid4() res = convert(str(sol), uuid.UUID) assert res == sol @pytest.mark.parametrize("input_type", [bytes, bytearray, memoryview]) def test_uuid_bytes(self, input_type): sol = uuid.uuid4() msg = input_type(sol.bytes) res = convert(msg, uuid.UUID) assert res == sol bad_msg = input_type(b"x" * 8) with pytest.raises(msgspec.ValidationError, match="Invalid UUID bytes"): convert(bad_msg, type=uuid.UUID) def test_uuid_disabled(self): u = uuid.uuid4() with pytest.raises(ValidationError, match="Expected `uuid`, got `str`"): convert(str(u), uuid.UUID, builtin_types=(uuid.UUID,)) for typ in [bytes, bytearray]: with pytest.raises(ValidationError, match="Expected `uuid`, got `bytes`"): convert(typ(u.bytes), uuid.UUID, builtin_types=(uuid.UUID,)) def test_convert_uuid_subclass(self): class UUID2(uuid.UUID): ... u1 = uuid.uuid4() u2 = UUID2(str(u1)) assert convert(u2, uuid.UUID) is u2 class TestDecimal: def test_decimal_wrong_type(self): with pytest.raises(ValidationError, match="Expected `decimal`, got `array`"): convert([], decimal.Decimal) def test_decimal_builtin(self): x = decimal.Decimal("1.5") assert convert(x, decimal.Decimal) is x def test_decimal_str(self): sol = decimal.Decimal("1.5") res = convert("1.5", decimal.Decimal) assert res == sol assert type(res) is decimal.Decimal @pytest.mark.parametrize("val", [1.3, float("nan"), float("inf"), float("-inf")]) def test_decimal_float(self, val): sol = decimal.Decimal(str(val)) res = convert(val, decimal.Decimal) assert str(res) == str(sol) # compare strs to support NaN assert type(res) is decimal.Decimal @pytest.mark.parametrize("val", [0, 1234, -1234]) def test_decimal_int(self, val): sol = decimal.Decimal(val) res = convert(val, decimal.Decimal) assert res == sol assert type(res) is decimal.Decimal @pytest.mark.parametrize("val, typ", [("1.5", "str"), (123, "int"), (1.3, "float")]) def test_decimal_conversion_disabled(self, val, typ): with pytest.raises(ValidationError, match=f"Expected `decimal`, got `{typ}`"): convert(val, decimal.Decimal, builtin_types=(decimal.Decimal,)) class TestExt: def test_ext(self): x = msgspec.msgpack.Ext(1, b"123") assert convert(x, msgspec.msgpack.Ext) is x def test_ext_errors(self): with pytest.raises(ValidationError, match="Expected `ext`, got `int`"): convert(1, msgspec.msgpack.Ext) with pytest.raises(ValidationError, match="Expected `int`, got `ext`"): convert(msgspec.msgpack.Ext(1, b"123"), int) class TestEnum: def test_enum(self): class Ex(enum.Enum): x = "A" y = "B" class Ex2(enum.Enum): x = "A" assert convert(Ex.x, Ex) is Ex.x assert convert("A", Ex) is Ex.x assert convert("B", Ex) is Ex.y with pytest.raises(ValidationError, match="Invalid enum value 'C'"): convert("C", Ex) with pytest.raises(ValidationError, match="Expected `str`, got `int`"): convert(1, Ex) with pytest.raises(ValidationError, match="got `Ex2`"): convert(Ex2.x, Ex) def test_int_enum(self): class Ex(enum.IntEnum): x = 1 y = 2 class Ex2(enum.IntEnum): a = 1 b = 3 assert convert(Ex.x, Ex) is Ex.x assert convert(1, Ex) is Ex.x assert convert(2, Ex) is Ex.y assert convert(Ex2.a, Ex) is Ex.x with pytest.raises(ValidationError, match="Invalid enum value 3"): convert(3, Ex) with pytest.raises(ValidationError, match="Invalid enum value 3"): convert(Ex2.b, Ex) with pytest.raises(ValidationError, match="Expected `int`, got `str`"): convert("A", Ex) def test_str_enum(self): if not hasattr(enum, "StrEnum"): pytest.skip(reason="StrEnum not available") class Ex(enum.StrEnum): x = "A" y = "B" class Ex2(enum.StrEnum): a = "A" b = "C" assert convert(Ex.x, Ex) is Ex.x assert convert("A", Ex) is Ex.x assert convert("B", Ex) is Ex.y assert convert(Ex2.a, Ex) is Ex.x with pytest.raises(ValidationError, match="Invalid enum value 'C'"): convert("C", Ex) with pytest.raises(ValidationError, match="Invalid enum value 'C'"): convert(Ex2.b, Ex) with pytest.raises(ValidationError, match="Expected `str`, got `int`"): convert(3, Ex) def test_int_enum_int_subclass(self): class MyInt(int): pass class Ex(enum.IntEnum): x = 1 y = 2 msg = MyInt(1) assert convert(msg, Ex) is Ex.x assert sys.getrefcount(msg) == 2 # msg + 1 assert convert(MyInt(2), Ex) is Ex.y def test_enum_missing(self): class Ex(enum.Enum): A = "a" B = "b" @classmethod def _missing_(cls, val): if val == "return-A": return cls.A elif val == "return-B": return cls.B elif val == "error": raise ValueError("oh no!") else: return None assert msgspec.convert("a", Ex) is Ex.A assert msgspec.convert("return-A", Ex) is Ex.A assert msgspec.convert("return-B", Ex) is Ex.B with pytest.raises(ValidationError, match="Invalid enum value 'error'"): msgspec.convert("error", Ex) with pytest.raises(ValidationError, match="Invalid enum value 'other'"): msgspec.convert("other", Ex) def test_intenum_missing(self): class Ex(enum.IntEnum): A = 1 B = 2 @classmethod def _missing_(cls, val): if val == 3: return cls.A elif val == -4: return cls.B elif val == 5: raise ValueError("oh no!") else: return None assert msgspec.convert(1, Ex) is Ex.A assert msgspec.convert(3, Ex) is Ex.A assert msgspec.convert(-4, Ex) is Ex.B with pytest.raises(ValidationError, match="Invalid enum value 5"): msgspec.convert(5, Ex) with pytest.raises(ValidationError, match="Invalid enum value 6"): msgspec.convert(6, Ex) class TestLiteral: def test_str_literal(self): typ = Literal["A", "B"] assert convert("A", typ) == "A" assert convert("B", typ) == "B" with pytest.raises(ValidationError, match="Invalid enum value 'C'"): convert("C", typ) with pytest.raises(ValidationError, match="Expected `str`, got `int`"): convert(1, typ) def test_int_literal(self): typ = Literal[1, -2] assert convert(1, typ) == 1 assert convert(-2, typ) == -2 with pytest.raises(ValidationError, match="Invalid enum value 3"): convert(3, typ) with pytest.raises(ValidationError, match="Invalid enum value -3"): convert(-3, typ) with pytest.raises(ValidationError, match="Expected `int`, got `str`"): convert("A", typ) class TestSequences: def test_any_sequence(self): msg = (1, 2, 3) assert convert(msg, Any) is msg @seq_in_type @pytest.mark.parametrize("out_type", [list, tuple, set, frozenset]) def test_empty_sequence(self, in_type, out_type): assert convert(in_type(), out_type) == out_type() @seq_in_type @pytest.mark.parametrize( "out_type_annot", [(list, List), (tuple, Tuple), (set, Set), (frozenset, FrozenSet)], ) @pytest.mark.parametrize("item_annot", [None, int]) def test_sequence(self, in_type, out_type_annot, item_annot): out_type, out_annot = out_type_annot if item_annot is not None: if out_annot is Tuple: out_annot = out_annot[item_annot, ...] else: out_annot = out_annot[item_annot] res = convert(in_type([1, 2]), out_annot) sol = out_type([1, 2]) assert res == sol assert isinstance(res, out_type) @seq_in_type @pytest.mark.parametrize( "out_annot", [List[int], Tuple[int, ...], Set[int], FrozenSet[int]] ) def test_sequence_wrong_item_type(self, in_type, out_annot): with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$\[0\]`" ): assert convert(in_type(["bad"]), out_annot) @pytest.mark.parametrize("out_type", [list, tuple, set, frozenset]) def test_sequence_wrong_type(self, out_type): with pytest.raises(ValidationError, match=r"Expected `array`, got `int`"): assert convert(1, out_type) @pytest.mark.parametrize("kind", ["list", "tuple", "fixtuple", "set"]) @pytest.mark.skipif( PY312, reason="CPython 3.12 internal changes prevent testing for recursion issues this way", ) def test_sequence_cyclic_recursion(self, kind): depth = 50 if kind == "list": typ = List[int] for _ in range(depth): typ = List[typ] elif kind == "tuple": typ = Tuple[int, ...] for _ in range(depth): typ = Tuple[typ, ...] elif kind == "fixtuple": typ = Tuple[int] for _ in range(depth): typ = Tuple[typ] elif kind == "set": typ = FrozenSet[int] for _ in range(depth): typ = FrozenSet[typ] class Cache(Struct): value: typ msgspec.json.Decoder(Cache) arr = [] arr.append(arr) msg = {"value": arr} with pytest.raises(RecursionError): with max_call_depth(5): convert(msg, Cache) @pytest.mark.parametrize("out_type", [list, tuple, set, frozenset]) def test_sequence_constrs(self, out_type): class Ex(Struct): x: Annotated[out_type, Meta(min_length=2, max_length=4)] for n in [2, 4]: x = out_type(range(n)) assert convert({"x": list(range(n))}, Ex).x == x for n in [1, 5]: x = out_type(range(n)) with pytest.raises(ValidationError): convert({"x": list(range(n))}, Ex) def test_fixtuple_any(self): typ = Tuple[Any, Any, Any] sol = (1, "two", False) res = convert([1, "two", False], typ) assert res == sol with pytest.raises(ValidationError, match="Expected `array`, got `int`"): convert(1, typ) with pytest.raises(ValidationError, match="Expected `array`, got `set`"): convert({1, 2, 3}, typ) with pytest.raises(ValidationError, match="Expected `array` of length 3"): convert((1, "two"), typ) def test_fixtuple_typed(self): typ = Tuple[int, str, bool] sol = (1, "two", False) res = convert([1, "two", False], typ) assert res == sol with pytest.raises(ValidationError, match="Expected `bool`"): convert([1, "two", "three"], typ) with pytest.raises(ValidationError, match="Expected `array`, got `set`"): convert({1, 2, 3}, typ) with pytest.raises(ValidationError, match="Expected `array` of length 3"): convert((1, "two"), typ) class TestNamedTuple: def test_namedtuple_no_defaults(self): class Example(NamedTuple): a: int b: int c: int msg = Example(1, 2, 3) res = convert([1, 2, 3], Example) assert res == msg with pytest.raises(ValidationError, match="length 3, got 1"): convert([1], Example) with pytest.raises(ValidationError, match="length 3, got 6"): convert([1, 2, 3, 4, 5, 6], Example) def test_namedtuple_with_defaults(self): class Example(NamedTuple): a: int b: int c: int = -3 d: int = -4 e: int = -5 for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: msg = Example(*args) res = convert(args, Example) assert res == msg with pytest.raises(ValidationError, match="length 2 to 5, got 1"): convert([1], Example) with pytest.raises(ValidationError, match="length 2 to 5, got 6"): convert([1, 2, 3, 4, 5, 6], Example) def test_namedtuple_field_wrong_type(self): class Example(NamedTuple): a: int b: str with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$\[0\]`" ): convert(("bad", 1), Example) def test_namedtuple_not_array(self): class Example(NamedTuple): a: int b: str with pytest.raises(ValidationError, match="Expected `array`, got `object`"): convert({"a": 1, "b": "two"}, Example) def test_namedtuple_cyclic_recursion(self): source = """ from __future__ import annotations from typing import NamedTuple, Union, Dict class Ex(NamedTuple): a: int b: Union[Ex, None] """ with temp_module(source) as mod: msg = [1] msg.append(msg) with pytest.raises(RecursionError): assert convert(msg, mod.Ex) def test_namedtuple_to_namedtuple(self): class Ex1(NamedTuple): x: int class Ex2(NamedTuple): x: int class Ex3(NamedTuple): x: str msg = Ex1(1) assert convert(msg, Ex1) is msg assert convert(msg, Ex2) == Ex2(1) with pytest.raises(ValidationError, match="Expected `str`, got `int`"): convert(msg, Ex3) class TestDict: def test_any_dict(self, dictcls): assert convert(dictcls({"one": 1, 2: "two"}), Any) == {"one": 1, 2: "two"} def test_empty_dict(self, dictcls): assert convert(dictcls({}), dict) == {} assert convert(dictcls({}), Dict[int, int]) == {} def test_typed_dict(self, dictcls): res = convert(dictcls({"x": 1, "y": 2}), Dict[str, float]) assert res == {"x": 1.0, "y": 2.0} assert all(type(v) is float for v in res.values()) with pytest.raises( ValidationError, match=r"Expected `str`, got `int` - at `\$\[\.\.\.\]`" ): convert(dictcls({"x": 1}), Dict[str, str]) with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `key` in `\$`" ): convert(dictcls({"x": 1}), Dict[int, str]) def test_dict_wrong_type(self): with pytest.raises(ValidationError, match=r"Expected `object`, got `int`"): assert convert(1, dict) def test_str_formatted_keys(self): msg = {uuid.uuid4(): 1, uuid.uuid4(): 2} res = convert(to_builtins(msg), Dict[uuid.UUID, int]) assert res == msg @pytest.mark.parametrize("key_type", ["int", "enum", "literal"]) def test_int_keys(self, dictcls, key_type): msg = dictcls({1: "A", 2: "B"}) if key_type == "enum": Key = enum.IntEnum("Key", ["one", "two"]) sol = {Key.one: "A", Key.two: "B"} elif key_type == "literal": Key = Literal[1, 2] sol = msg else: Key = int sol = msg res = convert(msg, Dict[Key, str]) assert res == sol res = convert(msg, Dict[Key, str], str_keys=True) assert res == sol str_msg = dictcls(to_builtins(dict(msg), str_keys=True)) res = convert(str_msg, Dict[Key, str], str_keys=True) assert res == sol with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `key` in `\$`" ): convert(str_msg, Dict[Key, str]) def test_non_str_keys(self, dictcls): convert(dictcls({1.5: 1}), Dict[float, int]) == {1.5: 1} with pytest.raises(ValidationError): convert(dictcls({"x": 1}), Dict[Tuple[int, int], int], str_keys=True) @pytest.mark.skipif( PY312, reason="CPython 3.12 internal changes prevent testing for recursion issues this way", ) def test_dict_cyclic_recursion(self, dictcls): depth = 50 typ = Dict[str, int] for _ in range(depth): typ = Dict[str, typ] class Cache(Struct): value: typ msgspec.json.Decoder(Cache) map = dictcls() map["x"] = map msg = {"value": map} with pytest.raises(RecursionError): with max_call_depth(5): convert(msg, Cache) def test_dict_constrs(self, dictcls): class Ex(Struct): x: Annotated[dict, Meta(min_length=2, max_length=4)] for n in [2, 4]: x = dictcls({str(i): i for i in range(n)}) assert convert(dictcls({"x": x}), Ex).x == x for n in [1, 5]: x = {str(i): i for i in range(n)} with pytest.raises(ValidationError): convert(dictcls({"x": x}), Ex) class TestTypedDict: def test_typeddict_total_true(self): class Ex(TypedDict): a: int b: str x = {"a": 1, "b": "two"} assert convert(x, Ex) == x x2 = {"a": 1, "b": "two", "c": "extra"} assert convert(x2, Ex) == x with pytest.raises(ValidationError) as rec: convert({"b": "two"}, Ex) assert "Object missing required field `a`" == str(rec.value) with pytest.raises(ValidationError) as rec: convert({"a": 1, "b": 2}, Ex) assert "Expected `str`, got `int` - at `$.b`" == str(rec.value) with pytest.raises(ValidationError) as rec: convert({"a": 1, 1: 2}, Ex) assert "Expected `str` - at `key` in `$`" == str(rec.value) def test_typeddict_total_false(self): class Ex(TypedDict, total=False): a: int b: str x = {"a": 1, "b": "two"} assert convert(x, Ex) == x x2 = {"a": 1, "b": "two", "c": "extra"} assert convert(x2, Ex) == x x3 = {"b": "two"} assert convert(x3, Ex) == x3 x4 = {} assert convert(x4, Ex) == x4 def test_typeddict_total_partially_optional(self): class Base(TypedDict): a: int b: str class Ex(Base, total=False): c: str x = {"a": 1, "b": "two", "c": "extra"} assert convert(x, Ex) == x x2 = {"a": 1, "b": "two"} assert convert(x2, Ex) == x2 with pytest.raises(ValidationError) as rec: convert({"b": "two"}, Ex) assert "Object missing required field `a`" == str(rec.value) class TestDataclass: @pytest.mark.parametrize("slots", [False, True]) @mapcls_and_from_attributes def test_dataclass(self, slots, mapcls, from_attributes): if slots: if not PY310: pytest.skip(reason="Python 3.10+ required") kws = {"slots": True} else: kws = {} @dataclass(**kws) class Example: a: int b: int c: int sol = Example(1, 2, 3) msg = mapcls(a=1, b=2, c=3) res = convert(msg, Example, from_attributes=from_attributes) assert res == sol # Extra fields ignored res = convert( mapcls({"x": -1, "a": 1, "y": -2, "b": 2, "z": -3, "c": 3, "": -4}), Example, from_attributes=from_attributes, ) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `b`"): convert(mapcls(a=1), Example, from_attributes=from_attributes) # Incorrect field types error with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.a`" ): convert(mapcls(a="bad"), Example, from_attributes=from_attributes) def test_dict_to_dataclass_errors(self): @dataclass class Example: a: int with pytest.raises(ValidationError, match=r"Expected `str` - at `key` in `\$`"): convert({"a": 1, 1: 2}, Example) def test_from_attributes_option_disables_attribute_coercion(self): class Bad: def __init__(self): self.x = 1 msg = Bad() @dataclass class Ex: x: int with pytest.raises(ValidationError, match="Expected `object`, got `Bad`"): convert(msg, Ex) assert convert(msg, Ex, from_attributes=True) == Ex(1) @pytest.mark.parametrize("frozen", [False, True]) @pytest.mark.parametrize("slots", [False, True]) @mapcls_and_from_attributes def test_dataclass_defaults(self, frozen, slots, mapcls, from_attributes): if slots: if not PY310: pytest.skip(reason="Python 3.10+ required") kws = {"slots": True} else: kws = {} @dataclass(frozen=frozen, **kws) class Example: a: int b: int c: int = -3 d: int = -4 e: int = field(default_factory=lambda: -1000) for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: sol = Example(*args) msg = mapcls(dict(zip("abcde", args))) res = convert(msg, Example, from_attributes=from_attributes) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `a`"): convert(mapcls(c=1, d=2, e=3), Example, from_attributes=from_attributes) @mapcls_and_from_attributes def test_dataclass_default_factory_errors(self, mapcls, from_attributes): def bad(): raise ValueError("Oh no!") @dataclass class Example: a: int = field(default_factory=bad) msg = mapcls() with pytest.raises(ValueError, match="Oh no!"): convert(msg, Example, from_attributes=from_attributes) @mapcls_and_from_attributes def test_dataclass_post_init(self, mapcls, from_attributes): called = False @dataclass class Example: a: int def __post_init__(self): nonlocal called called = True msg = mapcls(a=1) res = convert(msg, Example, from_attributes=from_attributes) assert res.a == 1 assert called @mapcls_and_from_attributes def test_dataclass_post_init_errors(self, mapcls, from_attributes): @dataclass class Example: a: int def __post_init__(self): raise ValueError("Oh no!") msg = mapcls(a=1) with pytest.raises(ValidationError, match="Oh no!"): convert(msg, Example, from_attributes=from_attributes) @mapcls_and_from_attributes def test_dataclass_not_object(self, mapcls, from_attributes): @dataclass class Example: a: int b: int with pytest.raises(ValidationError, match="Expected `object`, got `array`"): convert([], Example, from_attributes=from_attributes) def test_dataclass_to_dataclass(self): @dataclass class Ex1: x: int @dataclass class Ex2: x: int msg = Ex1(1) assert convert(msg, Ex1) is msg with pytest.raises(ValidationError, match="got `Ex1`"): convert(msg, Ex2) assert convert(msg, Ex2, from_attributes=True) == Ex2(1) def test_struct_to_dataclass(self): @dataclass class Ex1: x: int class Ex2(Struct): x: int assert convert(Ex1(1), Ex2, from_attributes=True) == Ex2(1) @pytest.mark.skipif(attrs is None, reason="attrs is not installed") class TestAttrs: @pytest.mark.parametrize("slots", [False, True]) @mapcls_and_from_attributes def test_attrs(self, slots, mapcls, from_attributes): @attrs.define(slots=slots) class Example: a: int b: int c: int sol = Example(1, 2, 3) msg = mapcls(a=1, b=2, c=3) res = convert(msg, Example, from_attributes=from_attributes) assert res == sol # Extra fields ignored res = convert( mapcls({"x": -1, "a": 1, "y": -2, "b": 2, "z": -3, "c": 3, "": -4}), Example, from_attributes=from_attributes, ) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `b`"): convert(mapcls(a=1), Example, from_attributes=from_attributes) # Incorrect field types error with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.a`" ): convert({"a": "bad"}, Example, from_attributes=from_attributes) def test_dict_to_attrs_errors(self): @attrs.define class Example: a: int with pytest.raises(ValidationError, match=r"Expected `str` - at `key` in `\$`"): convert({"a": 1, 1: 2}, Example) def test_from_attributes_option_disables_attribute_coercion(self): class Bad: def __init__(self): self.x = 1 msg = Bad() @attrs.define class Ex: x: int with pytest.raises(ValidationError, match="Expected `object`, got `Bad`"): convert(msg, Ex) assert convert(msg, Ex, from_attributes=True) == Ex(1) @pytest.mark.parametrize("frozen", [False, True]) @pytest.mark.parametrize("slots", [False, True]) @mapcls_and_from_attributes def test_attrs_defaults(self, frozen, slots, mapcls, from_attributes): @attrs.define(frozen=frozen, slots=slots) class Example: a: int b: int c: int = -3 d: int = -4 e: int = attrs.field(factory=lambda: -1000) for args in [(1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5)]: sol = Example(*args) msg = mapcls(dict(zip("abcde", args))) res = convert(msg, Example, from_attributes=from_attributes) assert res == sol # Missing fields error with pytest.raises(ValidationError, match="missing required field `a`"): convert(mapcls(c=1, d=2, e=3), Example, from_attributes=from_attributes) @mapcls_and_from_attributes def test_attrs_frozen(self, mapcls, from_attributes): @attrs.define(frozen=True) class Example: x: int y: int sol = Example(1, 2) msg = mapcls(x=1, y=2) res = convert(msg, Example, from_attributes=from_attributes) assert res == sol @mapcls_and_from_attributes def test_attrs_pre_init(self, mapcls, from_attributes): called = False @attrs.define class Example: a: int def __attrs_pre_init__(self): nonlocal called called = True res = convert(mapcls(a=1), Example, from_attributes=from_attributes) assert res.a == 1 assert called @mapcls_and_from_attributes def test_attrs_pre_init_errors(self, mapcls, from_attributes): @attrs.define class Example: a: int def __attrs_pre_init__(self): raise ValueError("Oh no!") with pytest.raises(ValueError, match="Oh no!"): convert(mapcls(a=1), Example, from_attributes=from_attributes) @mapcls_and_from_attributes def test_attrs_post_init(self, mapcls, from_attributes): called = False @attrs.define class Example: a: int def __attrs_post_init__(self): nonlocal called called = True res = convert(mapcls(a=1), Example, from_attributes=from_attributes) assert res.a == 1 assert called @mapcls_and_from_attributes def test_attrs_post_init_errors(self, mapcls, from_attributes): @attrs.define class Example: a: int def __attrs_post_init__(self): raise ValueError("Oh no!") with pytest.raises(ValidationError, match="Oh no!"): convert(mapcls(a=1), Example, from_attributes=from_attributes) def test_attrs_to_attrs(self): @attrs.define class Ex1: x: int @attrs.define class Ex2: x: int msg = Ex1(1) assert convert(msg, Ex1) is msg with pytest.raises(ValidationError, match="got `Ex1`"): convert(msg, Ex2) assert convert(msg, Ex2, from_attributes=True) == Ex2(1) def test_struct_to_attrs(self): @attrs.define class Ex1: x: int class Ex2(Struct): x: int assert convert(Ex1(1), Ex2, from_attributes=True) == Ex2(1) class TestStruct: class Account(Struct, kw_only=True): first: str last: str verified: bool = False age: int @mapcls_and_from_attributes def test_struct(self, mapcls, from_attributes): msg = mapcls(first="alice", last="munro", age=91, verified=True) sol = self.Account(first="alice", last="munro", verified=True, age=91) res = convert(msg, self.Account, from_attributes=from_attributes) assert res == sol with pytest.raises(ValidationError, match="Expected `object`, got `array`"): convert([], self.Account, from_attributes=from_attributes) with pytest.raises( ValidationError, match=r"Expected `str`, got `int` - at `\$.last`" ): convert( mapcls(first="alice", last=1), self.Account, from_attributes=from_attributes, ) with pytest.raises( ValidationError, match="Object missing required field `age`" ): convert( mapcls(first="alice", last="munro"), self.Account, from_attributes=from_attributes, ) def test_dict_to_struct_errors(self): with pytest.raises(ValidationError, match=r"Expected `str` - at `key` in `\$`"): convert({"age": 1, 1: 2}, self.Account) def test_from_attributes_option_disables_attribute_coercion(self): class Bad: def __init__(self): self.x = 1 msg = Bad() class Ex(Struct): x: int with pytest.raises(ValidationError, match="Expected `object`, got `Bad`"): convert(msg, Ex) assert convert(msg, Ex, from_attributes=True) == Ex(1) @pytest.mark.parametrize("mapcls", [GetAttrObj, GetItemObj]) def test_object_to_struct_with_renamed_fields(self, mapcls): class Ex(Struct, rename="camel"): fa: int f_b: int fc: int f_d: int sol = Ex(1, 2, 3, 4) # Use attribute names msg = mapcls(fa=1, f_b=2, fc=3, f_d=4) assert convert(msg, Ex, from_attributes=True) == sol # Use renamed names msg = mapcls(fa=1, fB=2, fc=3, fD=4) assert convert(msg, Ex, from_attributes=True) == sol # Priority to attribute names msg = mapcls(fa=1, f_b=2, fB=100, fc=3, f_d=4, fD=100) assert convert(msg, Ex, from_attributes=True) == sol # Don't allow renamed names if determined to be attributes msg = mapcls(fa=1, f_b=2, fc=3, fD=4) with pytest.raises(ValidationError, match="missing required field `f_d`"): convert(msg, Ex, from_attributes=True) # Don't allow attributes if determined to be renamed names msg = mapcls(fa=1, fB=2, fc=3, f_d=4) with pytest.raises(ValidationError, match="missing required field `fD`"): convert(msg, Ex, from_attributes=True) # Errors use attribute name if using attributes msg = mapcls(fa=1, f_b=2, fc=3, f_d="bad") with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.f_d`" ): convert(msg, Ex, from_attributes=True) # Errors use renamed name if using renamed names msg = mapcls(fa=1, fB=2, fc=3, fD="bad") with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.fD`" ): convert(msg, Ex, from_attributes=True) # Errors use attribute name if undecided msg = mapcls(fa="bad") with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$.fa`" ): convert(msg, Ex, from_attributes=True) @pytest.mark.parametrize("forbid_unknown_fields", [False, True]) @mapcls_and_from_attributes def test_struct_extra_fields(self, forbid_unknown_fields, mapcls, from_attributes): class Ex(Struct, forbid_unknown_fields=forbid_unknown_fields): a: int b: int msg = mapcls(x=1, a=2, y=3, b=4, z=5) if forbid_unknown_fields and issubclass(mapcls, dict): with pytest.raises(ValidationError, match="unknown field `x`"): convert(msg, Ex, from_attributes=from_attributes) else: res = convert(msg, Ex, from_attributes=from_attributes) assert res == Ex(2, 4) @mapcls_and_from_attributes def test_struct_defaults_missing_fields(self, mapcls, from_attributes): msg = mapcls(first="alice", last="munro", age=91) res = convert(msg, self.Account, from_attributes=from_attributes) assert res == self.Account(first="alice", last="munro", age=91) @mapcls_from_attributes_and_array_like def test_struct_gc_maybe_untracked_on_decode( self, mapcls, from_attributes, array_like ): class Test(Struct, array_like=array_like): x: Any y: Any z: Tuple = () ts = [ mapcls(x=1, y=2), mapcls(x=3, y="hello"), mapcls(x=[], y=[]), mapcls(x={}, y={}), mapcls(x=None, y=None, z=()), ] a, b, c, d, e = convert(ts, List[Test], from_attributes=from_attributes) assert not gc.is_tracked(a) assert not gc.is_tracked(b) assert gc.is_tracked(c) assert gc.is_tracked(d) assert not gc.is_tracked(e) @mapcls_from_attributes_and_array_like def test_struct_gc_false_always_untracked_on_decode( self, mapcls, from_attributes, array_like ): class Test(Struct, array_like=array_like, gc=False): x: Any y: Any ts = [ mapcls(x=1, y=2), mapcls(x=[], y=[]), mapcls(x={}, y={}), ] for obj in convert(ts, List[Test], from_attributes=from_attributes): assert not gc.is_tracked(obj) @pytest.mark.parametrize("tag", ["Test", 123, -123]) @mapcls_and_from_attributes def test_tagged_struct(self, tag, mapcls, from_attributes): class Test(Struct, tag=tag): a: int b: int # Test with and without tag for msg in [ mapcls(a=1, b=2), mapcls(type=tag, a=1, b=2), mapcls(a=1, type=tag, b=2), ]: res = convert(msg, Test, from_attributes=from_attributes) assert res == Test(1, 2) # Tag incorrect type with pytest.raises(ValidationError) as rec: convert(mapcls(type=123.456), Test, from_attributes=from_attributes) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$.type`" in str(rec.value) # Tag incorrect value bad = -3 if isinstance(tag, int) else "bad" with pytest.raises(ValidationError) as rec: convert(mapcls(type=bad), Test, from_attributes=from_attributes) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize("tag_val", [2**64 - 1, 2**64, -(2**63) - 1]) @mapcls_and_from_attributes def test_tagged_struct_int_tag_not_int64_always_invalid( self, tag_val, mapcls, from_attributes ): """Tag values that don't fit in an int64 are currently unsupported, but we still want to raise a good error message.""" class Test(Struct, tag=123): pass with pytest.raises(ValidationError) as rec: convert(mapcls(type=tag_val), Test, from_attributes=from_attributes) assert f"Invalid value {tag_val}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123, -123]) @mapcls_and_from_attributes def test_tagged_empty_struct(self, tag, mapcls, from_attributes): class Test(Struct, tag=tag): pass # Tag missing res = convert(mapcls(), Test, from_attributes=from_attributes) assert res == Test() # Tag present res = convert(mapcls(type=tag), Test, from_attributes=from_attributes) assert res == Test() @pytest.mark.parametrize("array_like", [False, True]) def test_struct_to_struct(self, array_like): class Ex1(Struct, array_like=array_like): x: int class Ex2(Struct, array_like=array_like): x: int msg = Ex1(1) assert convert(msg, Ex1) is msg with pytest.raises(ValidationError, match="got `Ex1`"): convert(msg, Ex2) assert convert(msg, Ex2, from_attributes=True) == Ex2(1) @pytest.mark.parametrize("array_like", [False, True]) def test_dataclass_to_struct(self, array_like): @dataclass class Ex1: x: int class Ex2(Struct, array_like=array_like): x: int assert convert(Ex1(1), Ex2, from_attributes=True) == Ex2(1) class TestStructArray: class Account(Struct, array_like=True): first: str last: str age: int verified: bool = False def test_struct_array_like(self): msg = self.Account("alice", "munro", 91, True) res = roundtrip(msg, self.Account) assert res == msg with pytest.raises(ValidationError, match="Expected `array`, got `int`"): roundtrip(1, self.Account) # Wrong field type with pytest.raises( ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`" ): roundtrip(("alice", "munro", "bad"), self.Account) # Missing fields with pytest.raises( ValidationError, match="Expected `array` of at least length 3, got 2", ): roundtrip(("alice", "munro"), self.Account) with pytest.raises( ValidationError, match="Expected `array` of at least length 3, got 0", ): roundtrip((), self.Account) @pytest.mark.parametrize("forbid_unknown_fields", [False, True]) def test_struct_extra_fields(self, forbid_unknown_fields): class Ex(Struct, array_like=True, forbid_unknown_fields=forbid_unknown_fields): a: int b: int msg = (1, 2, 3, 4) if forbid_unknown_fields: with pytest.raises( ValidationError, match="Expected `array` of at most length 2, got 4" ): roundtrip(msg, Ex) else: res = roundtrip(msg, Ex) assert res == Ex(1, 2) def test_struct_defaults_missing_fields(self): res = roundtrip(("alice", "munro", 91), self.Account) assert res == self.Account("alice", "munro", 91) @pytest.mark.parametrize("tag", ["Test", -123, 123]) def test_tagged_struct(self, tag): class Test(Struct, tag=tag, array_like=True): a: int b: int c: int = 0 # Decode with tag res = roundtrip((tag, 1, 2), Test) assert res == Test(1, 2) res = roundtrip((tag, 1, 2, 3), Test) assert res == Test(1, 2, 3) # Trailing fields ignored res = roundtrip((tag, 1, 2, 3, 4), Test) assert res == Test(1, 2, 3) # Missing required field errors with pytest.raises(ValidationError) as rec: roundtrip((tag, 1), Test) assert "Expected `array` of at least length 3, got 2" in str(rec.value) # Tag missing with pytest.raises(ValidationError) as rec: roundtrip((), Test) assert "Expected `array` of at least length 3, got 0" in str(rec.value) # Tag incorrect type with pytest.raises(ValidationError) as rec: roundtrip((123.456, 2, 3), Test) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$[0]`" in str(rec.value) # Tag incorrect value bad = -3 if isinstance(tag, int) else "bad" with pytest.raises(ValidationError) as rec: roundtrip((bad, 1, 2), Test) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$[0]`" in str(rec.value) # Field incorrect type correct index with pytest.raises(ValidationError) as rec: roundtrip((tag, "a", 2), Test) assert "Expected `int`, got `str`" in str(rec.value) assert "`$[1]`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123, -123]) def test_tagged_empty_struct(self, tag): class Test(Struct, tag=tag, array_like=True): pass # Decode with tag res = roundtrip((tag, 1, 2), Test) assert res == Test() # Tag missing with pytest.raises(ValidationError) as rec: roundtrip((), Test) assert "Expected `array` of at least length 1, got 0" in str(rec.value) class TestStructUnion: @pytest.mark.parametrize( "tag1, tag2, unknown", [ ("Test1", "Test2", "Test3"), (0, 1, 2), (123, -123, 0), ], ) @mapcls_and_from_attributes def test_struct_union(self, tag1, tag2, unknown, mapcls, from_attributes): def decode(msg): return convert( mapcls(msg), Union[Test1, Test2], from_attributes=from_attributes ) class Test1(Struct, tag=tag1): a: int b: int c: int = 0 class Test2(Struct, tag=tag2): x: int y: int # Tag can be in any position assert decode({"type": tag1, "a": 1, "b": 2}) == Test1(1, 2) assert decode({"a": 1, "type": tag1, "b": 2}) == Test1(1, 2) assert decode({"x": 1, "y": 2, "type": tag2}) == Test2(1, 2) # Optional fields still work assert decode({"type": tag1, "a": 1, "b": 2, "c": 3}) == Test1(1, 2, 3) assert decode({"a": 1, "b": 2, "c": 3, "type": tag1}) == Test1(1, 2, 3) # Extra fields still ignored assert decode({"a": 1, "b": 2, "d": 4, "type": tag1}) == Test1(1, 2) # Tag missing with pytest.raises(ValidationError) as rec: decode({"a": 1, "b": 2}) assert "missing required field `type`" in str(rec.value) # Tag wrong type with pytest.raises(ValidationError) as rec: decode({"type": 123.456, "a": 1, "b": 2}) assert f"Expected `{type(tag1).__name__}`" in str(rec.value) assert "`$.type`" in str(rec.value) # Tag unknown with pytest.raises(ValidationError) as rec: decode({"type": unknown, "a": 1, "b": 2}) assert f"Invalid value {unknown!r} - at `$.type`" == str(rec.value) @pytest.mark.parametrize( "tag1, tag2, tag3, unknown", [ ("Test1", "Test2", "Test3", "Test4"), (0, 1, 2, 3), (123, -123, 0, -1), ], ) def test_struct_array_union(self, tag1, tag2, tag3, unknown): class Test1(Struct, tag=tag1, array_like=True): a: int b: int c: int = 0 class Test2(Struct, tag=tag2, array_like=True): x: int y: int class Test3(Struct, tag=tag3, array_like=True): pass typ = Union[Test1, Test2, Test3] # Decoding works assert roundtrip([tag1, 1, 2], typ) == Test1(1, 2) assert roundtrip([tag2, 3, 4], typ) == Test2(3, 4) assert roundtrip([tag3], typ) == Test3() # Optional & Extra fields still respected assert roundtrip([tag1, 1, 2, 3], typ) == Test1(1, 2, 3) assert roundtrip([tag1, 1, 2, 3, 4], typ) == Test1(1, 2, 3) # Missing required field with pytest.raises(ValidationError) as rec: roundtrip([tag1, 1], typ) assert "Expected `array` of at least length 3, got 2" in str(rec.value) # Type error has correct field index with pytest.raises(ValidationError) as rec: roundtrip([tag1, 1, "bad", 2], typ) assert "Expected `int`, got `str` - at `$[2]`" == str(rec.value) # Tag missing with pytest.raises(ValidationError) as rec: roundtrip([], typ) assert "Expected `array` of at least length 1, got 0" == str(rec.value) # Tag wrong type with pytest.raises(ValidationError) as rec: roundtrip([123.456, 2, 3, 4], typ) assert f"Expected `{type(tag1).__name__}`" in str(rec.value) assert "`$[0]`" in str(rec.value) # Tag unknown with pytest.raises(ValidationError) as rec: roundtrip([unknown, 1, 2, 3], typ) assert f"Invalid value {unknown!r} - at `$[0]`" == str(rec.value) @pytest.mark.parametrize("tags", [(1, 2), (-10000, 10000), ("A", "B")]) @pytest.mark.parametrize("array_like", [False, True]) def test_struct_to_struct_union(self, tags, array_like): class Ex1(Struct, array_like=array_like, tag=tags[0]): x: int class Ex2(Struct, array_like=array_like, tag=tags[1]): x: int class Ex3(Struct, array_like=array_like): x: int typ = Union[Ex1, Ex2] msg = Ex1(1) assert convert(msg, typ) is msg with pytest.raises(ValidationError, match="got `Ex3`"): convert(Ex3(1), typ) class TestGenericStruct: @mapcls_from_attributes_and_array_like def test_generic_struct(self, mapcls, from_attributes, array_like): class Ex(Struct, Generic[T], array_like=array_like): x: T y: List[T] sol = Ex(1, [1, 2]) msg = mapcls(x=1, y=[1, 2]) res = convert(msg, Ex, from_attributes=from_attributes) assert res == sol res = convert(msg, Ex[int], from_attributes=from_attributes) assert res == sol res = convert(msg, Ex[Union[int, str]], from_attributes=from_attributes) assert res == sol res = convert(msg, Ex[float], from_attributes=from_attributes) assert type(res.x) is float with pytest.raises(ValidationError, match="Expected `str`, got `int`"): convert(msg, Ex[str], from_attributes=from_attributes) @mapcls_from_attributes_and_array_like def test_generic_struct_union(self, mapcls, from_attributes, array_like): class Test1(Struct, Generic[T], tag=True, array_like=array_like): a: Union[T, None] b: int class Test2(Struct, Generic[T], tag=True, array_like=array_like): x: T y: int typ = Union[Test1[T], Test2[T]] msg1 = Test1(1, 2) s1 = mapcls(type="Test1", a=1, b=2) msg2 = Test2("three", 4) s2 = mapcls(type="Test2", x="three", y=4) msg3 = Test1(None, 4) s3 = mapcls(type="Test1", a=None, b=4) assert convert(s1, typ, from_attributes=from_attributes) == msg1 assert convert(s2, typ, from_attributes=from_attributes) == msg2 assert convert(s3, typ, from_attributes=from_attributes) == msg3 assert convert(s1, typ[int], from_attributes=from_attributes) == msg1 assert convert(s3, typ[int], from_attributes=from_attributes) == msg3 assert convert(s2, typ[str], from_attributes=from_attributes) == msg2 assert convert(s3, typ[str], from_attributes=from_attributes) == msg3 with pytest.raises(ValidationError) as rec: convert(s1, typ[str], from_attributes=from_attributes) assert "Expected `str | null`, got `int`" in str(rec.value) loc = "$[1]" if array_like and not from_attributes else "$.a" assert loc in str(rec.value) with pytest.raises(ValidationError) as rec: convert(s2, typ[int], from_attributes=from_attributes) assert "Expected `int`, got `str`" in str(rec.value) loc = "$[1]" if array_like and not from_attributes else "$.x" assert loc in str(rec.value) class TestStructPostInit: @pytest.mark.parametrize("union", [False, True]) @mapcls_from_attributes_and_array_like def test_struct_post_init(self, union, mapcls, from_attributes, array_like): called = False singleton = object() class Ex(Struct, array_like=array_like, tag=union): x: int def __post_init__(self): nonlocal called called = True return singleton if union: class Ex2(Struct, array_like=array_like, tag=True): pass typ = Union[Ex, Ex2] else: typ = Ex msg = mapcls(type="Ex", x=1) if union else mapcls(x=1) res = convert(msg, type=typ, from_attributes=from_attributes) assert type(res) is Ex assert called assert sys.getrefcount(singleton) == 2 # 1 for ref, 1 for call @pytest.mark.parametrize("union", [False, True]) @pytest.mark.parametrize("exc_class", [ValueError, TypeError, OSError]) @mapcls_from_attributes_and_array_like def test_struct_post_init_errors( self, union, exc_class, mapcls, from_attributes, array_like ): class Ex(Struct, array_like=array_like, tag=union): x: int def __post_init__(self): raise exc_class("Oh no!") if union: class Ex2(Struct, array_like=array_like, tag=True): pass typ = Union[Ex, Ex2] else: typ = Ex msg = [mapcls(type="Ex", x=1) if union else mapcls(x=1)] if exc_class in (ValueError, TypeError): expected = ValidationError else: expected = exc_class with pytest.raises(expected, match="Oh no!") as rec: convert(msg, type=List[typ], from_attributes=from_attributes) if expected is ValidationError: assert "- at `$[0]`" in str(rec.value) class TestLax: def test_lax_none(self): for x in ["null", "Null", "nUll", "nuLl", "nulL"]: assert convert(x, None, strict=False) is None for x in ["xull", "nxll", "nuxl", "nulx"]: with pytest.raises(ValidationError, match="Expected `null`, got `str`"): convert(x, None, strict=False) def test_lax_bool_true(self): for x in [1, "1", "true", "True", "tRue", "trUe", "truE"]: assert convert(x, bool, strict=False) is True def test_lax_bool_false(self): for x in [0, "0", "false", "False", "fAlse", "faLse", "falSe", "falsE"]: assert convert(x, bool, strict=False) is False def test_lax_bool_true_invalid(self): for x in [-1, 3, "x", "xx", "xrue", "txue", "trxe", "trux"]: typ = type(x).__name__ with pytest.raises(ValidationError, match=f"Expected `bool`, got `{typ}`"): assert convert(x, bool, strict=False) def test_lax_bool_false_invalid(self): for x in [-1, 3, "x", "xx", "xalse", "fxlse", "faxse", "falxe", "falsx"]: typ = type(x).__name__ with pytest.raises(ValidationError, match=f"Expected `bool`, got `{typ}`"): assert convert(x, bool, strict=False) def test_lax_int_from_str(self): for x in ["1", "-1", "123456", "1.0"]: assert convert(x, int, strict=False) == int(float(x)) for x in ["a", "1a", "1.5", "1..", "nan", "inf"]: with pytest.raises(ValidationError, match="Expected `int`, got `str`"): convert(x, int, strict=False) def test_lax_int_from_float(self): bound = float(1 << 53) for x in [-bound, -1.0, -0.0, 0.0, 1.0, bound]: assert convert(x, int, strict=False) == int(x) for x in [-bound - 2, -1.5, 0.001, 1.5, bound + 2, float("inf"), float("nan")]: with pytest.raises(ValidationError, match="Expected `int`, got `float`"): convert(x, int, strict=False) def test_lax_int_constr(self): typ = Annotated[int, Meta(ge=0)] assert convert("1", typ, strict=False) == 1 with pytest.raises(ValidationError): convert("-1", typ, strict=False) def test_lax_int_enum(self): class Ex(enum.IntEnum): x = 1 y = -2 assert convert("1", Ex, strict=False) is Ex.x assert convert("-2", Ex, strict=False) is Ex.y with pytest.raises(ValidationError, match="Invalid enum value 3"): convert("3", Ex, strict=False) with pytest.raises(ValidationError, match="Expected `int`, got `str`"): convert("A", Ex, strict=False) def test_lax_int_literal(self): typ = Literal[1, -2] assert convert("1", typ, strict=False) == 1 assert convert("-2", typ, strict=False) == -2 with pytest.raises(ValidationError, match="Invalid enum value 3"): convert("3", typ, strict=False) with pytest.raises(ValidationError, match="Expected `int`, got `str`"): convert("A", typ, strict=False) def test_lax_float(self): for x in ["1", "-1", "123456", "1.5", "-1.5", "inf"]: assert convert(x, float, strict=False) == float(x) for x in ["a", "1a", "1.0.0", "1.."]: with pytest.raises(ValidationError, match="Expected `float`, got `str`"): convert(x, float, strict=False) @pytest.mark.parametrize("str_value", ["nan", "infinity"]) @pytest.mark.parametrize("negative", [False, True]) def test_lax_float_nonfinite(self, str_value, negative): prefix = "-" if negative else "" for i in range(len(str_value)): msg = prefix + str_value[:i] + str_value[i].upper() + str_value[i + 1 :] sol = float(msg) res = convert(msg, float, strict=False) assert_eq(res, sol) def test_lax_float_nonfinite_invalid(self): for bad in ["abcd", "-abcd", "inx", "-inx", "infinitx", "-infinitx", "nax"]: for msg in [bad, bad.upper()]: with pytest.raises( ValidationError, match="Expected `float`, got `str`" ): convert(msg, float, strict=False) def test_lax_float_constr(self): assert convert("1.5", Annotated[float, Meta(ge=0)], strict=False) == 1.5 with pytest.raises(ValidationError): convert("-1.0", Annotated[float, Meta(ge=0)], strict=False) def test_lax_str(self): for x in ["1", "1.5", "false", "null"]: assert convert(x, str, strict=False) == x def test_lax_str_constr(self): typ = Annotated[str, Meta(max_length=10)] assert convert("xxx", typ, strict=False) == "xxx" with pytest.raises(ValidationError): convert("x" * 20, typ, strict=False) @pytest.mark.parametrize( "x", [ 1234.0000004, 1234.0000006, 1234.000567, 1234.567, 1234.0, 0.123, 0.0, 1234, 0, ], ) @pytest.mark.parametrize("sign", [-1, 1]) @pytest.mark.parametrize("transform", [None, str]) def test_lax_datetime(self, x, sign, transform): timestamp = x * sign msg = transform(timestamp) if transform else timestamp sol = datetime.datetime.fromtimestamp(timestamp, UTC) res = convert(msg, type=datetime.datetime, strict=False) assert res == sol def test_lax_datetime_nonfinite_values(self): for msg in ["nan", "-inf", "inf", float("nan"), float("inf"), float("-inf")]: with pytest.raises(ValidationError, match="Invalid epoch timestamp"): convert(msg, type=datetime.datetime, strict=False) @pytest.mark.parametrize("val", [-62135596801, 253402300801]) @pytest.mark.parametrize("type", [int, float, str]) def test_lax_datetime_out_of_range(self, val, type): msg = type(val) with pytest.raises(ValidationError, match="out of range"): convert(msg, type=datetime.datetime, strict=False) def test_lax_datetime_invalid_numeric_str(self): for msg in ["", "12e", "1234a", "1234-1", "1234.a"]: with pytest.raises(ValidationError, match="Invalid"): convert(msg, type=datetime.datetime, strict=False) @pytest.mark.parametrize("msg", [123, -123, 123.456, "123.456"]) def test_lax_datetime_naive_required(self, msg): with pytest.raises(ValidationError, match="no timezone component"): convert( msg, type=Annotated[datetime.datetime, Meta(tz=False)], strict=False ) @pytest.mark.parametrize( "x", [ 1234.0000004, 1234.0000006, 1234.000567, 1234.567, 1234.0, 0.123, 0.0, 1234, 0, ], ) @pytest.mark.parametrize("sign", [-1, 1]) @pytest.mark.parametrize("transform", [None, str]) def test_lax_timedelta(self, x, sign, transform): timestamp = x * sign msg = transform(timestamp) if transform else timestamp sol = datetime.timedelta(seconds=timestamp) res = convert(msg, type=datetime.timedelta, strict=False) assert res == sol def test_lax_timedelta_nonfinite_values(self): for msg in ["nan", "-inf", "inf", float("nan"), float("inf"), float("-inf")]: with pytest.raises(ValidationError, match="Duration is out of range"): convert(msg, type=datetime.timedelta, strict=False) @pytest.mark.parametrize("val", [86400000000001, -86399999913601]) @pytest.mark.parametrize("type", [int, float, str]) def test_lax_timedelta_out_of_range(self, val, type): msg = type(val) with pytest.raises(ValidationError, match="out of range"): convert(msg, type=datetime.timedelta, strict=False) def test_lax_timedelta_invalid_numeric_str(self): for msg in ["", "12e", "1234a", "1234-1", "1234.a"]: with pytest.raises(ValidationError, match="Invalid"): convert(msg, type=datetime.timedelta, strict=False) @pytest.mark.parametrize( "msg, sol", [ ("1", 1), ("0", 0), ("-1", -1), ("12.5", 12.5), ("inf", float("inf")), ("true", True), ("false", False), ("null", None), ], ) def test_lax_union_valid(self, msg, sol): typ = Union[int, float, bool, None] assert_eq(convert(msg, typ, strict=False), sol) @pytest.mark.parametrize("msg", ["1a", "1.5a", "falsx", "trux", "nulx"]) def test_lax_union_invalid(self, msg): typ = Union[int, float, bool, None] with pytest.raises( ValidationError, match="Expected `int | float | bool | null`" ): convert(msg, typ, strict=False) @pytest.mark.parametrize( "msg, err", [ ("-1", "`int` >= 0"), ("2000", "`int` <= 1000"), ("18446744073709551616", "`int` <= 1000"), ("-9223372036854775809", "`int` >= 0"), ("100.5", "`float` <= 100.0"), ], ) def test_lax_union_invalid_constr(self, msg, err): """Ensure that values that parse properly but don't meet the specified constraints error with a specific constraint error""" typ = Union[ Annotated[int, Meta(ge=0), Meta(le=1000)], Annotated[float, Meta(le=100)], ] with pytest.raises(ValidationError, match=err): convert(msg, typ, strict=False) def test_lax_union_extended(self): typ = Union[int, float, bool, None, datetime.datetime] dt = datetime.datetime.now() assert_eq(convert("1", typ, strict=False), 1) assert_eq(convert("1.5", typ, strict=False), 1.5) assert_eq(convert("false", typ, strict=False), False) assert_eq(convert("null", typ, strict=False), None) assert_eq(convert(dt.isoformat(), typ, strict=False), dt) def test_lax_implies_str_keys(self): res = convert({"1": False}, Dict[int, bool], strict=False) assert res == {1: False} def test_lax_implies_no_builtin_types(self): sol = uuid.uuid4() msg = str(sol) res = convert(msg, uuid.UUID, strict=False, builtin_types=(uuid.UUID,)) assert res == sol class TestCustom: def test_custom(self): def dec_hook(typ, x): assert typ is complex return complex(*x) msg = {"x": (1, 2)} sol = {"x": complex(1, 2)} res = convert(msg, Dict[str, complex], dec_hook=dec_hook) assert res == sol def test_custom_no_dec_hook(self): with pytest.raises(ValidationError, match="Expected `complex`, got `str`"): convert({"x": "oh no"}, Dict[str, complex]) def test_custom_dec_hook_errors(self): def dec_hook(typ, x): raise TypeError("Oops!") with pytest.raises(ValidationError, match="Oops!") as rec: convert({"x": (1, 2)}, Dict[str, complex], dec_hook=dec_hook) assert rec.value.__cause__ is rec.value.__context__ assert type(rec.value.__cause__) is TypeError class TestRaw: def test_raw(self): raw = msgspec.Raw(b"123") class Ex(Struct): x: msgspec.Raw sol = Ex(x=raw) assert convert({"x": raw}, type=Ex) == sol python-msgspec-0.19.0/tests/test_cpylint.py000066400000000000000000000032171473355726200210370ustar00rootroot00000000000000"""This file contains some simple linters for catching some common but easy to catch cpython capi bugs. These are naive string-munging checks, if you write some code that _is_ correct but is failing, add `/* cpylint-ignore */` on the failing source line and it will be ignored.""" import os import pytest MSGSPEC_CORE_PATH = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "msgspec", "_core.c" ) @pytest.fixture def source(): with open(MSGSPEC_CORE_PATH, "r") as f: return f.read().splitlines() def test_recursive_call_blocks(source): """Ensure all code that calls `Py_EnterRecursiveCall` doesn't return without calling `Py_LeaveRecursiveCall`""" in_block = False for lineno, line in enumerate(source, 1): if "cpylint-ignore" in line: continue if "Py_EnterRecursiveCall" in line: in_block = True elif "return " in line and in_block: raise ValueError( f"return without calling Py_LeaveRecursiveCall on line {lineno}" ) elif "Py_LeaveRecursiveCall" in line: in_block = False def test_recursive_repr_blocks(source): """Ensure all code that calls `Py_ReprEnter` doesn't return without calling `Py_ReprLeave`""" in_block = False for lineno, line in enumerate(source, 1): if "cpylint-ignore" in line: continue if "Py_ReprEnter" in line: in_block = True elif "return " in line and in_block: raise ValueError(f"return without calling Py_ReprLeave on line {lineno}") elif "Py_ReprLeave" in line: in_block = False python-msgspec-0.19.0/tests/test_inspect.py000066400000000000000000000454471473355726200210350ustar00rootroot00000000000000import collections import datetime import decimal import enum import sys import typing import uuid from collections import namedtuple from copy import deepcopy from dataclasses import dataclass, field from typing import ( Annotated, Any, Dict, Final, FrozenSet, Generic, List, Literal, NamedTuple, NewType, Set, Tuple, TypedDict, TypeVar, Union, ) import pytest from utils import temp_module import msgspec import msgspec.inspect as mi from msgspec import Meta PY312 = sys.version_info[:2] >= (3, 12) py312_plus = pytest.mark.skipif(not PY312, reason="3.12+ only") T = TypeVar("T") @pytest.mark.parametrize( "a,b,sol", [ ( {"a": {"b": {"c": 1}}}, {"a": {"b": {"d": 2}}}, {"a": {"b": {"c": 1, "d": 2}}}, ), ({"a": {"b": {"c": 1}}}, {"a": {"b": 2}}, {"a": {"b": 2}}), ({"a": [1, 2]}, {"a": [3, 4]}, {"a": [1, 2, 3, 4]}), ({"a": {"b": 1}}, {"a2": 3}, {"a": {"b": 1}, "a2": 3}), ({"a": 1}, {}, {"a": 1}), ], ) def test_merge_json(a, b, sol): a_orig = deepcopy(a) b_orig = deepcopy(b) res = mi._merge_json(a, b) assert res == sol assert a == a_orig assert b == b_orig def test_inspect_module_dir(): assert mi.__dir__() == mi.__all__ def test_any(): assert mi.type_info(Any) == mi.AnyType() def test_typevar(): assert mi.type_info(T) == mi.AnyType() def test_bound_typevar(): T = TypeVar("T", bound=Union[int, str]) assert mi.type_info(T) == mi.UnionType((mi.IntType(), mi.StrType())) def test_none(): assert mi.type_info(None) == mi.NoneType() def test_bool(): assert mi.type_info(bool) == mi.BoolType() @pytest.mark.parametrize( "kw", [{}, dict(ge=2), dict(gt=2), dict(le=2), dict(lt=2), dict(multiple_of=2)] ) @pytest.mark.parametrize("typ, info_type", [(int, mi.IntType), (float, mi.FloatType)]) def test_numeric(kw, typ, info_type): if kw: typ = Annotated[typ, Meta(**kw)] assert mi.type_info(typ) == info_type(**kw) @pytest.mark.parametrize( "kw", [{}, dict(pattern="[a-z]*"), dict(min_length=0), dict(max_length=3)], ) def test_string(kw): typ = str if kw: typ = Annotated[typ, Meta(**kw)] assert mi.type_info(typ) == mi.StrType(**kw) @pytest.mark.parametrize( "kw", [{}, dict(min_length=0), dict(max_length=3)], ) @pytest.mark.parametrize( "typ, info_type", [ (bytes, mi.BytesType), (bytearray, mi.ByteArrayType), (memoryview, mi.MemoryViewType), ], ) def test_binary(kw, typ, info_type): if kw: typ = Annotated[typ, Meta(**kw)] assert mi.type_info(typ) == info_type(**kw) @pytest.mark.parametrize( "kw", [{}, dict(tz=None), dict(tz=True), dict(tz=False)], ) def test_datetime(kw): typ = datetime.datetime if kw: typ = Annotated[typ, Meta(**kw)] assert mi.type_info(typ) == mi.DateTimeType(**kw) @pytest.mark.parametrize( "kw", [{}, dict(tz=None), dict(tz=True), dict(tz=False)], ) def test_time(kw): typ = datetime.time if kw: typ = Annotated[typ, Meta(**kw)] assert mi.type_info(typ) == mi.TimeType(**kw) def test_date(): assert mi.type_info(datetime.date) == mi.DateType() def test_timedelta(): assert mi.type_info(datetime.timedelta) == mi.TimeDeltaType() def test_uuid(): assert mi.type_info(uuid.UUID) == mi.UUIDType() def test_decimal(): assert mi.type_info(decimal.Decimal) == mi.DecimalType() def test_raw(): assert mi.type_info(msgspec.Raw) == mi.RawType() def test_msgpack_ext(): assert mi.type_info(msgspec.msgpack.Ext) == mi.ExtType() def test_newtype(): UserId = NewType("UserId", str) assert mi.type_info(UserId) == mi.StrType() assert mi.type_info(Annotated[UserId, Meta(max_length=10)]) == mi.StrType( max_length=10 ) # Annotated in NewType UserId = NewType("UserId", Annotated[str, Meta(max_length=10)]) assert mi.type_info(UserId) == mi.StrType(max_length=10) assert mi.type_info(Annotated[UserId, Meta(min_length=2)]) == mi.StrType( min_length=2, max_length=10 ) # NewType in NewType UserId2 = NewType("UserId2", UserId) assert mi.type_info(UserId2) == mi.StrType(max_length=10) assert mi.type_info(Annotated[UserId2, Meta(min_length=2)]) == mi.StrType( min_length=2, max_length=10 ) @py312_plus @pytest.mark.parametrize( "src, typ", [ ("type Ex = str | None", Union[str, None]), ("type Ex[T] = tuple[T, int]", Tuple[Any, int]), ("type Temp[T] = tuple[T, int]; Ex = Temp[str]", Tuple[str, int]), ], ) def test_typealias(src, typ): with temp_module(src) as mod: assert mi.type_info(mod.Ex) == mi.type_info(typ) def test_final(): cases = [ (int, mi.IntType()), (Annotated[int, Meta(ge=0)], mi.IntType(ge=0)), (NewType("UserId", Annotated[int, Meta(ge=0)]), mi.IntType(ge=0)), ] for typ, sol in cases: class Ex(msgspec.Struct): x: Final[typ] info = mi.type_info(Ex) assert info.fields[0].type == sol def test_custom(): assert mi.type_info(complex) == mi.CustomType(complex) @pytest.mark.parametrize( "kw", [{}, dict(min_length=0), dict(max_length=3)], ) @pytest.mark.parametrize( "typ, info_type", [ (list, mi.ListType), (tuple, mi.VarTupleType), (set, mi.SetType), (frozenset, mi.FrozenSetType), (List, mi.ListType), (Tuple, mi.VarTupleType), (Set, mi.SetType), (FrozenSet, mi.FrozenSetType), ], ) @pytest.mark.parametrize("has_item_type", [False, True]) def test_sequence(kw, typ, info_type, has_item_type): if has_item_type: item_type = mi.IntType() if info_type is mi.VarTupleType: typ = typ[int, ...] else: typ = typ[int] else: item_type = mi.AnyType() if kw: typ = Annotated[typ, Meta(**kw)] sol = info_type(item_type=item_type, **kw) assert mi.type_info(typ) == sol @pytest.mark.parametrize("typ", [Tuple, tuple]) def test_tuple(typ): assert mi.type_info(typ[()]) == mi.TupleType(()) assert mi.type_info(typ[int]) == mi.TupleType((mi.IntType(),)) assert mi.type_info(typ[int, float]) == mi.TupleType((mi.IntType(), mi.FloatType())) @pytest.mark.parametrize("typ", [Dict, dict]) @pytest.mark.parametrize("kw", [{}, dict(min_length=0), dict(max_length=3)]) @pytest.mark.parametrize("has_args", [False, True]) def test_dict(typ, kw, has_args): if has_args: typ = typ[int, float] key = mi.IntType() val = mi.FloatType() else: key = val = mi.AnyType() if kw: typ = Annotated[typ, Meta(**kw)] sol = mi.DictType(key_type=key, value_type=val, **kw) assert mi.type_info(typ) == sol @pytest.mark.parametrize( "typ", [ typing.Collection, typing.MutableSequence, typing.Sequence, collections.abc.Collection, collections.abc.MutableSequence, collections.abc.Sequence, typing.MutableSet, typing.AbstractSet, collections.abc.MutableSet, collections.abc.Set, ], ) def test_abstract_sequence(typ): if "Set" in str(typ): col_type = mi.SetType else: col_type = mi.ListType assert mi.type_info(typ) == col_type(mi.AnyType()) assert mi.type_info(typ[int]) == col_type(mi.IntType()) @pytest.mark.parametrize( "typ", [ typing.MutableMapping, typing.Mapping, collections.abc.MutableMapping, collections.abc.Mapping, ], ) def test_abstract_mapping(typ): assert mi.type_info(typ) == mi.DictType(mi.AnyType(), mi.AnyType()) assert mi.type_info(typ[str, int]) == mi.DictType(mi.StrType(), mi.IntType()) @pytest.mark.parametrize("use_union_operator", [False, True]) def test_union(use_union_operator): if use_union_operator: try: typ = int | str except TypeError: pytest.skip("Union operator not supported") else: typ = Union[int, str] sol = mi.UnionType((mi.IntType(), mi.StrType())) assert mi.type_info(typ) == sol assert not sol.includes_none assert mi.type_info(Union[int, None]).includes_none def test_int_literal(): assert mi.type_info(Literal[3, 1, 2]) == mi.LiteralType((1, 2, 3)) def test_str_literal(): assert mi.type_info(Literal["c", "a", "b"]) == mi.LiteralType(("a", "b", "c")) def test_int_enum(): class Example(enum.IntEnum): B = 3 A = 2 assert mi.type_info(Example) == mi.EnumType(Example) def test_enum(): class Example(enum.Enum): B = "z" A = "y" assert mi.type_info(Example) == mi.EnumType(Example) @pytest.mark.parametrize( "kw", [ {}, {"array_like": True}, {"forbid_unknown_fields": True}, {"tag": "Example", "tag_field": "type"}, ], ) def test_struct(kw): def factory(): return "foo" class Example(msgspec.Struct, **kw): x: int y: int = 0 z: int = msgspec.field(default_factory=factory) sol = mi.StructType( cls=Example, fields=( mi.Field(name="x", encode_name="x", type=mi.IntType()), mi.Field( name="y", encode_name="y", type=mi.IntType(), required=False, default=0 ), mi.Field( name="z", encode_name="z", type=mi.IntType(), required=False, default_factory=factory, ), ), **kw, ) assert mi.type_info(Example) == sol def test_struct_no_fields(): class Example(msgspec.Struct): pass sol = mi.StructType(Example, fields=()) assert mi.type_info(Example) == sol def test_struct_keyword_only(): class Example(msgspec.Struct, kw_only=True): a: int b: int = 1 c: int d: int = 2 sol = mi.StructType( Example, fields=( mi.Field("a", "a", mi.IntType()), mi.Field("b", "b", mi.IntType(), required=False, default=1), mi.Field("c", "c", mi.IntType()), mi.Field("d", "d", mi.IntType(), required=False, default=2), ), ) assert mi.type_info(Example) == sol def test_struct_encode_name(): class Example(msgspec.Struct, rename="camel"): field_one: int field_two: int sol = mi.StructType( Example, fields=( mi.Field("field_one", "fieldOne", mi.IntType()), mi.Field("field_two", "fieldTwo", mi.IntType()), ), ) assert mi.type_info(Example) == sol def test_generic_struct(): class Example(msgspec.Struct, Generic[T]): a: T b: List[T] sol = mi.StructType( Example, fields=( mi.Field("a", "a", mi.AnyType()), mi.Field("b", "b", mi.ListType(mi.AnyType())), ), ) assert mi.type_info(Example) == sol sol = mi.StructType( Example[int], fields=( mi.Field("a", "a", mi.IntType()), mi.Field("b", "b", mi.ListType(mi.IntType())), ), ) assert mi.type_info(Example[int]) == sol def test_typing_namedtuple(): class Example(NamedTuple): a: str b: bool c: int = 0 sol = mi.NamedTupleType( Example, fields=( mi.Field("a", "a", mi.StrType()), mi.Field("b", "b", mi.BoolType()), mi.Field("c", "c", mi.IntType(), required=False, default=0), ), ) assert mi.type_info(Example) == sol def test_collections_namedtuple(): Example = namedtuple("Example", ["a", "b", "c"], defaults=(0,)) sol = mi.NamedTupleType( Example, fields=( mi.Field("a", "a", mi.AnyType()), mi.Field("b", "b", mi.AnyType()), mi.Field("c", "c", mi.AnyType(), required=False, default=0), ), ) assert mi.type_info(Example) == sol def test_generic_namedtuple(): NamedTuple = pytest.importorskip("typing_extensions").NamedTuple class Example(NamedTuple, Generic[T]): a: T b: List[T] sol = mi.NamedTupleType( Example, fields=( mi.Field("a", "a", mi.AnyType()), mi.Field("b", "b", mi.ListType(mi.AnyType())), ), ) assert mi.type_info(Example) == sol sol = mi.NamedTupleType( Example[int], fields=( mi.Field("a", "a", mi.IntType()), mi.Field("b", "b", mi.ListType(mi.IntType())), ), ) assert mi.type_info(Example[int]) == sol @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_typeddict(use_typing_extensions): if use_typing_extensions: tex = pytest.importorskip("typing_extensions") cls = tex.TypedDict else: cls = TypedDict class Example(cls): a: str b: bool c: int sol = mi.TypedDictType( Example, fields=( mi.Field("a", "a", mi.StrType()), mi.Field("b", "b", mi.BoolType()), mi.Field("c", "c", mi.IntType()), ), ) assert mi.type_info(Example) == sol @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_typeddict_optional(use_typing_extensions): if use_typing_extensions: tex = pytest.importorskip("typing_extensions") cls = tex.TypedDict else: cls = TypedDict class Base(cls): a: str b: bool class Example(Base, total=False): c: int sol = mi.TypedDictType( Example, fields=( mi.Field("a", "a", mi.StrType()), mi.Field("b", "b", mi.BoolType()), mi.Field("c", "c", mi.IntType(), required=False), ), ) assert mi.type_info(Example) == sol def test_generic_typeddict(): TypedDict = pytest.importorskip("typing_extensions").TypedDict class Example(TypedDict, Generic[T]): a: T b: List[T] sol = mi.TypedDictType( Example, fields=( mi.Field("a", "a", mi.AnyType()), mi.Field("b", "b", mi.ListType(mi.AnyType())), ), ) assert mi.type_info(Example) == sol sol = mi.TypedDictType( Example[int], fields=( mi.Field("a", "a", mi.IntType()), mi.Field("b", "b", mi.ListType(mi.IntType())), ), ) assert mi.type_info(Example[int]) == sol def test_dataclass(): @dataclass class Example: x: int y: int = 0 z: str = field(default_factory=str) sol = mi.DataclassType( Example, fields=( mi.Field("x", "x", mi.IntType()), mi.Field("y", "y", mi.IntType(), required=False, default=0), mi.Field("z", "z", mi.StrType(), required=False, default_factory=str), ), ) assert mi.type_info(Example) == sol def test_attrs(): attrs = pytest.importorskip("attrs") @attrs.define class Example: x: int y: int = 0 z: str = attrs.field(factory=str) sol = mi.DataclassType( Example, fields=( mi.Field("x", "x", mi.IntType()), mi.Field("y", "y", mi.IntType(), required=False, default=0), mi.Field("z", "z", mi.StrType(), required=False, default_factory=str), ), ) assert mi.type_info(Example) == sol @pytest.mark.parametrize("module", ["dataclasses", "attrs"]) def test_generic_dataclass_or_attrs(module): m = pytest.importorskip(module) decorator = m.define if module == "attrs" else m.dataclass @decorator class Example(Generic[T]): a: T b: List[T] sol = mi.DataclassType( Example, fields=( mi.Field("a", "a", mi.AnyType()), mi.Field("b", "b", mi.ListType(mi.AnyType())), ), ) assert mi.type_info(Example) == sol sol = mi.DataclassType( Example[int], fields=( mi.Field("a", "a", mi.IntType()), mi.Field("b", "b", mi.ListType(mi.IntType())), ), ) assert mi.type_info(Example[int]) == sol @pytest.mark.parametrize("kind", ["struct", "dataclass", "attrs"]) def test_unset_fields(kind): if kind == "struct": class Ex(msgspec.Struct): x: Union[int, msgspec.UnsetType] = msgspec.UNSET elif kind == "dataclass": @dataclass class Ex: x: Union[int, msgspec.UnsetType] = msgspec.UNSET elif kind == "attrs": attrs = pytest.importorskip("attrs") @attrs.define class Ex: x: Union[int, msgspec.UnsetType] = msgspec.UNSET res = mi.type_info(Ex) assert res.fields == (mi.Field("x", "x", mi.IntType(), required=False),) @pytest.mark.parametrize("kind", ["struct", "namedtuple", "typeddict", "dataclass"]) def test_self_referential_objects(kind): if kind == "struct": code = """ import msgspec class Node(msgspec.Struct): child: "Node" """ elif kind == "namedtuple": code = """ from typing import NamedTuple class Node(NamedTuple): child: "Node" """ elif kind == "typeddict": code = """ from typing import TypedDict class Node(TypedDict): child: "Node" """ elif kind == "dataclass": code = """ from dataclasses import dataclass @dataclass class Node: child: "Node" """ with temp_module(code) as mod: res = mi.type_info(mod.Node) assert res.cls is mod.Node assert res.fields[0].name == "child" assert res.fields[0].type is res def test_metadata(): typ = Annotated[int, Meta(gt=1, title="a"), Meta(description="b")] assert mi.type_info(typ) == mi.Metadata( mi.IntType(gt=1), {"title": "a", "description": "b"} ) typ = Annotated[ int, Meta(extra_json_schema={"title": "a", "description": "b"}), Meta(extra_json_schema={"title": "c", "examples": [1, 2]}), ] assert mi.type_info(typ) == mi.Metadata( mi.IntType(), {"title": "c", "description": "b", "examples": [1, 2]} ) typ = Annotated[ int, Meta(extra={"a": 1, "b": 2}), Meta(extra={"a": 3, "c": 4}), ] assert mi.type_info(typ) == mi.Metadata( mi.IntType(), extra={"a": 3, "b": 2, "c": 4} ) def test_inspect_with_unhashable_metadata(): typ = Annotated[int, {"unhashable"}] assert mi.type_info(typ) == mi.IntType() def test_multi_type_info(): class Example(msgspec.Struct): x: int y: int ex_type = mi.StructType( Example, fields=( mi.Field("x", "x", mi.IntType()), mi.Field("y", "y", mi.IntType()), ), ) assert mi.multi_type_info([]) == () res = mi.multi_type_info([Example, List[Example]]) assert res == (ex_type, mi.ListType(ex_type)) assert res[0] is res[1].item_type python-msgspec-0.19.0/tests/test_integration.py000066400000000000000000000016221473355726200216760ustar00rootroot00000000000000import datetime import sys import pytest import msgspec @pytest.fixture(params=["json", "msgpack"]) def proto(request): if request.param == "json": return msgspec.json elif request.param == "msgpack": return msgspec.msgpack def test_decode_naive_datetime(proto): """See https://github.com/jcrist/msgspec/issues/408""" dt = datetime.datetime(2001, 2, 3, 4, 5, 6, 7) msg = proto.encode(dt) start = sys.getrefcount(None) for _ in range(1000): proto.decode(msg, type=datetime.datetime) end = sys.getrefcount(None) assert start == end def test_decode_naive_time(proto): """See https://github.com/jcrist/msgspec/issues/408""" dt = datetime.time(12, 20) msg = proto.encode(dt) start = sys.getrefcount(None) for _ in range(1000): proto.decode(msg, type=datetime.time) end = sys.getrefcount(None) assert start == end python-msgspec-0.19.0/tests/test_json.py000066400000000000000000003267611473355726200203420ustar00rootroot00000000000000from __future__ import annotations import base64 import datetime import decimal import enum import gc import itertools import json import math import string import sys import uuid from dataclasses import dataclass from decimal import Decimal from typing import ( Annotated, Any, Dict, FrozenSet, List, Literal, NamedTuple, Optional, Set, Tuple, TypedDict, Union, ) import pytest import msgspec UTC = datetime.timezone.utc class FruitInt(enum.IntEnum): APPLE = -1 BANANA = 2 class FruitStr(enum.Enum): APPLE = "apple" BANANA = "banana" class Person(msgspec.Struct): first: str last: str age: int prefect: bool = False class PersonArray(msgspec.Struct, array_like=True): first: str last: str age: int prefect: bool = False class Node(msgspec.Struct): left: Optional[Node] = None right: Optional[Node] = None class Custom: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, other): return self.x == other.x and self.y == other.y class TestInvalidJSONTypes: def test_invalid_type_union(self): literal = Literal["a", "b"] types = [ FruitStr, literal, str, datetime.datetime, datetime.date, bytes, bytearray, ] for length in [2, 3, 4]: for types in itertools.combinations(types, length): if set(types) in ({bytes, bytearray}, {str, literal}): continue with pytest.raises(TypeError, match="not supported"): msgspec.json.Decoder(Union[types]) def test_invalid_dict_key_type_errors_at_runtime(self): # We used to check this statically at TypeNode build time, but this was # a pain. We now just ensure invalid types error at runtime. with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `str`" ): msgspec.json.decode(b'{"x": 1}', type=Dict[Tuple[int, int], int]) class TestEncodeFunction: def test_encode(self): assert msgspec.json.encode(1) == b"1" def test_encode_error(self): with pytest.raises(TypeError): msgspec.json.encode(object()) def test_encode_large_object(self): """Check that buffer resize works""" data = "x" * 4097 assert msgspec.json.encode(data) == f'"{data}"'.encode("utf-8") def test_encode_no_enc_hook(self): class Foo: pass with pytest.raises( TypeError, match="Encoding objects of type Foo is unsupported" ): msgspec.json.encode(Foo()) def test_encode_enc_hook(self): unsupported = object() def enc_hook(x): assert x is unsupported return "hello" orig_refcount = sys.getrefcount(enc_hook) res = msgspec.json.encode(unsupported, enc_hook=enc_hook) assert msgspec.json.encode("hello") == res assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_enc_hook_errors(self): def enc_hook(x): raise TypeError("bad") orig_refcount = sys.getrefcount(enc_hook) with pytest.raises(TypeError, match="bad"): msgspec.json.encode(object(), enc_hook=enc_hook) assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_parse_arguments_errors(self): with pytest.raises(TypeError, match="Missing 1 required argument"): msgspec.json.encode() with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.json.encode(1, lambda x: None) with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.json.encode(1, 2, 3) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.json.encode(1, bad=1) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.json.encode(1, enc_hook=lambda x: None, extra="extra") class TestEncoderMisc: def rec_obj1(self): o = [] o.append(o) return o def rec_obj2(self): o = ([],) o[0].append(o) return o def rec_obj3(self): o = {} o["a"] = o return o def rec_obj4(self): class Box(msgspec.Struct): a: "Box" o = Box(None) o.a = o return o @pytest.mark.parametrize("case", [1, 2, 3, 4]) def test_encode_infinite_recursive_object_errors(self, case): enc = msgspec.json.Encoder() o = getattr(self, "rec_obj%d" % case)() with pytest.raises(RecursionError): enc.encode(o) def test_encode_no_enc_hook(self): class Foo: pass enc = msgspec.json.Encoder() assert enc.enc_hook is None with pytest.raises( TypeError, match="Encoding objects of type Foo is unsupported" ): enc.encode(Foo()) def test_encode_enc_hook(self): unsupported = object() def enc_hook(x): assert x is unsupported return "hello" orig_refcount = sys.getrefcount(enc_hook) enc = msgspec.json.Encoder(enc_hook=enc_hook) assert enc.enc_hook is enc_hook assert sys.getrefcount(enc.enc_hook) == orig_refcount + 2 assert sys.getrefcount(enc_hook) == orig_refcount + 1 res = enc.encode(unsupported) assert enc.encode("hello") == res del enc assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_enc_hook_errors(self): def enc_hook(x): raise TypeError("bad") enc = msgspec.json.Encoder(enc_hook=enc_hook) with pytest.raises(TypeError, match="bad"): enc.encode(object()) def test_encode_enc_hook_recurses(self): class Node: def __init__(self, a): self.a = a def enc_hook(x): return {"type": "Node", "a": x.a} enc = msgspec.json.Encoder(enc_hook=enc_hook) msg = enc.encode(Node(Node(1))) res = json.loads(msg) assert res == {"type": "Node", "a": {"type": "Node", "a": 1}} def test_encode_enc_hook_recursion_error(self): enc = msgspec.json.Encoder(enc_hook=lambda x: x) with pytest.raises(RecursionError): enc.encode(object()) def test_encode_into_bad_arguments(self): enc = msgspec.json.Encoder() with pytest.raises(TypeError, match="bytearray"): enc.encode_into(1, b"test") with pytest.raises(TypeError): enc.encode_into(1, bytearray(), "bad") with pytest.raises(ValueError, match="offset"): enc.encode_into(1, bytearray(), -2) @pytest.mark.parametrize("buf_size", [0, 1, 16, 55, 60]) def test_encode_into(self, buf_size): enc = msgspec.json.Encoder() msg = {"key": "x" * 48} encoded = msgspec.json.encode(msg) buf = bytearray(buf_size) out = enc.encode_into(msg, buf) assert out is None assert buf == encoded def test_encode_into_offset(self): enc = msgspec.json.Encoder() msg = {"key": "value"} encoded = enc.encode(msg) # Offset 0 is default buf = bytearray() enc.encode_into(msg, buf, 0) assert buf == encoded # Offset in bounds uses the provided offset buf = bytearray(b"01234") enc.encode_into(msg, buf, 2) assert buf == b"01" + encoded # Offset out of bounds extends buf = bytearray(b"01234") enc.encode_into(msg, buf, 10) assert buf[:5] == b"01234" assert buf[10:] == encoded # Offset -1 means append at end buf = bytearray(b"01234") enc.encode_into(msg, buf, -1) assert buf == b"01234" + encoded def test_encode_into_handles_errors_properly(self): enc = msgspec.json.Encoder() out1 = enc.encode([1, 2, 3]) msg = [1, 2, object()] buf = bytearray() with pytest.raises(TypeError): enc.encode_into(msg, buf) assert buf # buffer isn't reset upon error # Encoder still works out2 = enc.encode([1, 2, 3]) assert out1 == out2 @pytest.mark.parametrize("n", range(3)) @pytest.mark.parametrize("iterable", [False, True]) def test_encode_lines(self, n, iterable): class custom: def __init__(self, x): self.x = x def __str__(self): return f"<{self.x}>" enc = msgspec.json.Encoder(enc_hook=str) items = [{"x": i, "y": custom(i)} for i in range(n)] sol = b"".join(enc.encode(i) + b"\n" for i in items) if iterable: items = (i for i in items) res = enc.encode_lines(items) assert res == sol @pytest.mark.parametrize("iterable", [False, True]) def test_encode_lines_iterable_unsupported_item_errors(self, iterable): enc = msgspec.json.Encoder() def gen(): yield 1 yield object() items = gen() if iterable else list(gen()) with pytest.raises(TypeError): enc.encode_lines(items) def test_encode_lines_iterable_iter_error(self): enc = msgspec.json.Encoder() class noiter: def __iter__(self): raise ValueError("Oh no!") with pytest.raises(ValueError, match="Oh no!"): enc.encode_lines(noiter()) def test_encode_lines_iterable_next_error(self): enc = msgspec.json.Encoder() def gen(): yield 1 raise ValueError("Oh no!") with pytest.raises(ValueError, match="Oh no!"): enc.encode_lines(gen()) class TestDecodeFunction: def test_decode(self): assert msgspec.json.decode(b"[1, 2, 3]") == [1, 2, 3] def test_decode_from_str(self): assert msgspec.json.decode("[1, 2, 3]") == [1, 2, 3] with pytest.raises(msgspec.DecodeError, match="truncated"): assert msgspec.json.decode("[1, 2, 3") def test_decode_type_keyword(self): assert msgspec.json.decode(b"[1, 2, 3]", type=Set[int]) == {1, 2, 3} with pytest.raises(msgspec.ValidationError): assert msgspec.json.decode(b"[1, 2, 3]", type=Set[str]) def test_decode_type_any(self): assert msgspec.json.decode(b"[1, 2, 3]", type=Any) == [1, 2, 3] @pytest.mark.parametrize("array_like", [False, True]) def test_decode_type_struct(self, array_like): class Point(msgspec.Struct, array_like=array_like): x: int y: int msg = msgspec.json.encode(Point(1, 2)) for _ in range(2): assert msgspec.json.decode(msg, type=Point) == Point(1, 2) def test_decode_type_struct_invalid_type(self): class Test(msgspec.Struct): x: 1 with pytest.raises(TypeError): msgspec.json.decode(b"{}", type=Test) def test_decode_invalid_type(self): with pytest.raises(TypeError, match="Type '1' is not supported"): msgspec.json.decode(b"[]", type=1) def test_decode_invalid_buf(self): with pytest.raises(TypeError): msgspec.json.decode(1) def test_decode_parse_arguments_errors(self): buf = b"[1, 2, 3]" with pytest.raises(TypeError, match="Missing 1 required argument"): msgspec.json.decode() with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.json.decode(buf, List[int]) with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.json.decode(buf, 2, 3) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.json.decode(buf, bad=1) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.json.decode(buf, type=List[int], extra=1) def test_decode_with_trailing_characters_errors(self): with pytest.raises(msgspec.DecodeError): msgspec.json.decode(b'[1, 2, 3]"trailing"') class TestDecoderMisc: def test_decode_from_str(self): dec = msgspec.json.Decoder() assert dec.decode("[1, 2, 3]") == [1, 2, 3] with pytest.raises(msgspec.DecodeError, match="truncated"): assert dec.decode("[1, 2, 3") def test_decoder_type_attribute(self): dec = msgspec.json.Decoder() assert dec.type is Any dec = msgspec.json.Decoder(int) assert dec.type is int def test_decoder_repr(self): typ = List[Dict[str, float]] dec = msgspec.json.Decoder(typ) assert repr(dec) == f"msgspec.json.Decoder({typ!r})" dec = msgspec.json.Decoder() assert repr(dec) == f"msgspec.json.Decoder({Any!r})" def test_decode_with_trailing_characters_errors(self): dec = msgspec.json.Decoder() with pytest.raises(msgspec.DecodeError): dec.decode(b'[1, 2, 3]"trailing"') @pytest.mark.parametrize( "msg", ["", "\n", "1", " 1", "1\t\r\n", "1\n\r\t 2", "1\n2\n", "1\n2\n3\n"], ) def test_decode_lines(self, msg): dec = msgspec.json.Decoder() sol = [] for part in msg.splitlines(): if part := part.strip(): sol.append(dec.decode(part)) res = dec.decode_lines(msg) assert res == sol def test_decode_lines_typed(self): class Ex(msgspec.Struct): x: int sol = [Ex(1), Ex(2)] buf = msgspec.json.Encoder().encode_lines(sol) res = msgspec.json.Decoder(Ex).decode_lines(buf) assert res == sol def test_decode_lines_typed_error(self): class Ex(msgspec.Struct): x: int buf = b'{"x": 1}\n{"x": "bad"}\n' dec = msgspec.json.Decoder(Ex) with pytest.raises(msgspec.ValidationError) as rec: dec.decode_lines(buf) assert "Expected `int`, got `str`" in str(rec.value) assert "`$[1].x" in str(rec.value) def test_decode_lines_malformed(self): buf = b'{"x": 1}\n{"x": efg' dec = msgspec.json.Decoder() with pytest.raises(msgspec.DecodeError, match="malformed"): dec.decode_lines(buf) def test_decode_lines_bad_call(self): dec = msgspec.json.Decoder() with pytest.raises(TypeError): dec.decode() with pytest.raises(TypeError): dec.decode("{}", 2) with pytest.raises(TypeError): dec.decode(1) def test_decoder_init_float_hook(self): dec = msgspec.json.Decoder() assert dec.float_hook is None dec = msgspec.json.Decoder(float_hook=None) assert dec.float_hook is None dec = msgspec.json.Decoder(float_hook=decimal.Decimal) assert dec.float_hook is decimal.Decimal with pytest.raises(TypeError): dec = msgspec.json.Decoder(float_hook=1) class TestBoolAndNone: def test_encode_none(self): assert msgspec.json.encode(None) == b"null" def test_decode_none(self): assert msgspec.json.decode(b"null") is None assert msgspec.json.decode(b" null ") is None @pytest.mark.parametrize("s", [b"nul", b"nulll", b"nuul", b"nulp"]) def test_decode_none_malformed(self, s): with pytest.raises(msgspec.DecodeError): msgspec.json.decode(s) def test_decode_none_typed(self): with pytest.raises( msgspec.ValidationError, match="Expected `int | null`, got `str`" ): msgspec.json.decode(b'"test"', type=Union[int, None]) def test_encode_true(self): assert msgspec.json.encode(True) == b"true" def test_decode_true(self): assert msgspec.json.decode(b"true") is True assert msgspec.json.decode(b" true ") is True @pytest.mark.parametrize("s", [b"tru", b"truee", b"trru", b"trup"]) def test_decode_true_malformed(self, s): with pytest.raises(msgspec.DecodeError): msgspec.json.decode(s) def test_encode_false(self): assert msgspec.json.encode(False) == b"false" def test_decode_false(self): assert msgspec.json.decode(b"false") is False assert msgspec.json.decode(b" false ") is False @pytest.mark.parametrize("s", [b"fals", b"falsee", b"faase", b"falsp"]) def test_decode_false_malformed(self, s): with pytest.raises(msgspec.DecodeError): msgspec.json.decode(s) def test_decode_bool_typed(self): with pytest.raises(msgspec.ValidationError, match="Expected `bool`, got `str`"): msgspec.json.decode(b'"test"', type=bool) class TestStrings: STRINGS = [ ("", b'""'), ("a", b'"a"'), (" a b c d", b'" a b c d"'), ("123 á 456", b'"123 \xc3\xa1 456"'), ("á 456", b'"\xc3\xa1 456"'), ("123 á", b'"123 \xc3\xa1"'), ("123 𝄞 456", b'"123 \xf0\x9d\x84\x9e 456"'), ("𝄞 456", b'"\xf0\x9d\x84\x9e 456"'), ("123 𝄞", b'"123 \xf0\x9d\x84\x9e"'), ('123 \b\n\f\r\t"\\ 456', b'"123 \\b\\n\\f\\r\\t\\"\\\\ 456"'), ('\b\n\f\r\t"\\ 456', b'"\\b\\n\\f\\r\\t\\"\\\\ 456"'), ('123 \b\n\f\r\t"\\', b'"123 \\b\\n\\f\\r\\t\\"\\\\"'), ("123 \x01\x02\x03 456", b'"123 \\u0001\\u0002\\u0003 456"'), ("\x01\x02\x03 456", b'"\\u0001\\u0002\\u0003 456"'), ("123 \x01\x02\x03", b'"123 \\u0001\\u0002\\u0003"'), ] @pytest.mark.parametrize("decoded, encoded", STRINGS) def test_encode_str(self, decoded, encoded): assert msgspec.json.encode(decoded) == encoded @pytest.mark.parametrize("length", [*range(1, 17), 25, 33, 63, 255]) @pytest.mark.parametrize("esc1", ["\n", "\x01"]) @pytest.mark.parametrize("esc2", ["\n", "\x01"]) @pytest.mark.parametrize("adjacent", [False, True]) def test_encode_str_unroll_escapes(self, length, esc1, esc2, adjacent): """Exercise all the branches in the unrolled loops in the JSON str encoding functions""" base = list(itertools.islice(itertools.cycle(string.ascii_letters), length)) if adjacent: def gen(): for i in range(length - 1): s = base.copy() s[i] = esc1 s[i + 1] = esc2 yield "".join(s) else: def gen(): for i in range(length): s = base.copy() s[i] = esc1 if i + 2 < length: s[i + 2] = esc2 else: s[0] = esc2 yield "".join(s) for s in gen(): sol = json.dumps(s, ensure_ascii=False).encode("utf-8") res = msgspec.json.encode(s) assert res == sol @pytest.mark.parametrize("decoded, encoded", STRINGS) def test_decode_str(self, decoded, encoded): assert msgspec.json.decode(encoded) == decoded @pytest.mark.parametrize( "decoded, encoded", [ ("123 Á 456", b'"123 \\u00C1 456"'), ("Á 456", b'"\\u00C1 456"'), ("123 Á", b'"123 \\u00C1"'), ("123 𝄞 456", b'"123 \\ud834\\udd1e 456"'), ("𝄞 456", b'"\\ud834\\udd1e 456"'), ("123 𝄞", b'"123 \\ud834\\udd1e"'), ("123 𝄞 456", b'"123 \\uD834\\uDD1E 456"'), ], ) def test_decode_str_unicode_escapes(self, decoded, encoded): assert msgspec.json.decode(encoded) == decoded @pytest.mark.parametrize( "s, error", [ (b'"\\u00cz 123"', "invalid character in unicode escape"), (b'"\\ud834\\uddz0 123"', "invalid character in unicode escape"), (b'"\\ud834"', "truncated"), (b'"\\ud834 1234567"', "unexpected end of escaped utf-16 surrogate pair"), (b'"\\udc00"', "invalid utf-16 surrogate pair"), (b'"\\udfff"', "invalid utf-16 surrogate pair"), (b'"\\ud834\\udb99"', "invalid utf-16 surrogate pair"), (b'"\\ud834\\ue000"', "invalid utf-16 surrogate pair"), (b'"\\v"', "invalid escape character in string"), ], ) def test_decode_str_malformed_escapes(self, s, error): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s) def test_decode_str_invalid_byte(self): with pytest.raises(msgspec.DecodeError, match="invalid character"): msgspec.json.decode(b'"123 \x00 456"') with pytest.raises(msgspec.DecodeError, match="invalid character"): msgspec.json.decode(b'"123 \x01 456"') def test_decode_str_missing_closing_quote(self): with pytest.raises(msgspec.DecodeError, match="truncated"): msgspec.json.decode(b'"test') @pytest.mark.parametrize("length", range(10)) @pytest.mark.parametrize("in_list", [False, True]) @pytest.mark.parametrize("unicode", [False, True]) @pytest.mark.parametrize("escape", [False, True]) def test_decode_str_lengths(self, length, in_list, unicode, escape): """A test designed to get full coverage of the unrolled loops in the string parsing routine""" if unicode: prefix = "𝄞\nÁ\t\n𝄞Á" if escape else "𝄞Á" else: prefix = "a\nb\t\ncd" if escape else "" s = prefix + string.ascii_letters[:length] sol = [s, 1] if in_list else s buf = msgspec.json.encode(sol) res = msgspec.json.decode(buf) assert res == sol left, _, right = buf.rpartition(b'"') buf2 = left + b'\x01"' + right with pytest.raises(msgspec.DecodeError, match="invalid character"): msgspec.json.decode(buf2) # Test str skipping class Test(msgspec.Struct): x: int buf3 = msgspec.json.encode({"y": sol, "x": 1}) msgspec.json.decode(buf3, type=Test) class TestBinary: @pytest.mark.parametrize( "x", [b"", b"a", b"ab", b"abc", b"abcd", b"abcde", b"abcdef", b"\x00\xff"] ) @pytest.mark.parametrize("type", [bytes, bytearray, memoryview]) def test_encode_binary(self, x, type): x = type(x) s = msgspec.json.encode(x) expected = b'"' + base64.b64encode(x) + b'"' assert s == expected @pytest.mark.parametrize( "x", [b"", b"a", b"ab", b"abc", b"abcd", b"abcde", b"abcdef", b"\x00\xff"] ) @pytest.mark.parametrize("type", [bytes, bytearray, memoryview]) def test_decode_binary(self, x, type): s = b'"' + base64.b64encode(x) + b'"' res = msgspec.json.decode(s, type=type) assert res == bytes(x) assert isinstance(res, type) @pytest.mark.parametrize("n", [1023, 1024, 1025]) def test_roundtrip_random(self, n, rand): for _ in range(10): x = rand.bytes(n) s = msgspec.json.encode(x) x2 = msgspec.json.decode(s, type=bytes) assert x == x2 @pytest.mark.parametrize( "s", [b'"Y"', b'"YQ"', b'"YQ="', b'"YQI"', b'"YQI=="', b'"YQJj="', b'"AB*D"'] ) def test_malformed_base64_encoding(self, s): with pytest.raises( msgspec.ValidationError, match="Invalid base64 encoded string" ): msgspec.json.decode(s, type=bytes) class TestDatetime: def test_encode_datetime(self): # All fields, zero padded x = datetime.datetime(1, 2, 3, 4, 5, 6, 7, UTC) s = msgspec.json.encode(x) assert s == b'"0001-02-03T04:05:06.000007Z"' # All fields, no zeros x = datetime.datetime(1234, 12, 31, 14, 56, 27, 123456, UTC) s = msgspec.json.encode(x) assert s == b'"1234-12-31T14:56:27.123456Z"' def test_encode_datetime_no_microsecond(self): x = datetime.datetime(1234, 12, 31, 14, 56, 27, 0, UTC) s = msgspec.json.encode(x) assert s == b'"1234-12-31T14:56:27Z"' @pytest.mark.parametrize( "dt, sol", [ (datetime.datetime(1, 2, 3, 4, 5, 6), b'"0001-02-03T04:05:06"'), (datetime.datetime(1234, 12, 31, 14, 56, 27, 0), b'"1234-12-31T14:56:27"'), ( datetime.datetime(1234, 12, 31, 14, 56, 27, 7), b'"1234-12-31T14:56:27.000007"', ), ( datetime.datetime(1234, 12, 31, 14, 56, 27, 123456), b'"1234-12-31T14:56:27.123456"', ), ], ) def test_encode_datetime_naive(self, dt, sol): res = msgspec.json.encode(dt) assert res == sol @pytest.mark.parametrize( "offset", [ datetime.timedelta(0), datetime.timedelta(days=1, microseconds=-1), datetime.timedelta(days=-1, microseconds=1), datetime.timedelta(days=1, seconds=-29), datetime.timedelta(days=-1, seconds=29), datetime.timedelta(days=0, seconds=30), datetime.timedelta(days=0, seconds=-30), ], ) def test_encode_datetime_offset_is_appx_equal_to_utc(self, offset): tz = datetime.timezone(offset) x = datetime.datetime(1234, 12, 31, 14, 56, 27, 123456, tz) s = msgspec.json.encode(x) assert s == b'"1234-12-31T14:56:27.123456Z"' @pytest.mark.parametrize( "offset, expected", [ ( datetime.timedelta(days=1, seconds=-30), b'"1234-12-31T14:56:27.123456+23:59"', ), ( datetime.timedelta(days=-1, seconds=30), b'"1234-12-31T14:56:27.123456-23:59"', ), ( datetime.timedelta(minutes=19, seconds=32, microseconds=130000), b'"1234-12-31T14:56:27.123456+00:20"', ), ], ) def test_encode_datetime_offset_rounds_to_nearest_minute(self, offset, expected): tz = datetime.timezone(offset) x = datetime.datetime(1234, 12, 31, 14, 56, 27, 123456, tz) s = msgspec.json.encode(x) assert s == expected def test_encode_datetime_zoneinfo(self): import zoneinfo try: x = datetime.datetime( 2023, 1, 2, 3, 4, 5, 678, zoneinfo.ZoneInfo("America/Chicago") ) except zoneinfo.ZoneInfoNotFoundError: pytest.skip(reason="Failed to load timezone") sol = msgspec.json.encode(x.isoformat()) res = msgspec.json.encode(x) assert res == sol @pytest.mark.parametrize( "dt", [ "0001-02-03T04:05:06.000007", "0001-02-03T04:05:06.007", "0001-02-03T04:05:06", "2021-12-11T21:19:22.123456", ], ) @pytest.mark.parametrize("suffix", ["Z", "+00:00", "-00:00"]) def test_decode_datetime_utc(self, dt, suffix): dt += suffix exp = datetime.datetime.fromisoformat(dt.replace("Z", "+00:00")) s = f'"{dt}"'.encode("utf-8") res = msgspec.json.decode(s, type=datetime.datetime) assert res == exp @pytest.mark.parametrize( "dt", [ "2000-12-31T12:00:01", "2000-01-01T00:00:01", "2000-01-31T12:01:01", "2000-02-01T12:01:01", "2000-02-28T12:01:01", "2000-02-29T12:01:01", "2000-03-01T12:01:01", ], ) @pytest.mark.parametrize("sign", ["-", "+"]) @pytest.mark.parametrize("hour", [0, 8, 12, 16, 23]) @pytest.mark.parametrize("minute", [0, 30]) def test_decode_datetime_with_timezone(self, dt, sign, hour, minute): s = f"{dt}{sign}{hour:02}:{minute:02}" json_s = f'"{s}"'.encode("utf-8") exp = datetime.datetime.fromisoformat(s) res = msgspec.json.decode(json_s, type=datetime.datetime) assert res == exp def test_decode_timezone_cache(self): msg = b'"2000-01-01T00:00:01+03:02"' tz = msgspec.json.decode(msg, type=datetime.datetime).tzinfo tz2 = msgspec.json.decode(msg, type=datetime.datetime).tzinfo assert tz is tz2 del tz2 assert sys.getrefcount(tz) == 3 # 1 tz, 1 cache, 1 func call for _ in range(10): gc.collect() # cache is cleared every 10 full collections # Since tz still has refcnt > 1, shouldn't be cleared tz2 = msgspec.json.decode(msg, type=datetime.datetime).tzinfo assert tz is tz2 @pytest.mark.parametrize( "s", [ "1234-01-02T03:04:05", "1234-01-02T03:04:05.123", "1234-01-02T03:04:05.123456", ], ) def test_decode_datetime_naive(self, s): sol = datetime.datetime.fromisoformat(s) msg = f'"{s}"'.encode("utf-8") res = msgspec.json.decode(msg, type=datetime.datetime) assert sol == res @pytest.mark.parametrize("t", ["T", "t"]) @pytest.mark.parametrize("z", ["Z", "z"]) def test_decode_datetime_not_case_sensitive(self, t, z): """Both T & Z can be upper/lowercase""" s = f'"0001-02-03{t}04:05:06.000007{z}"'.encode("utf-8") exp = datetime.datetime(1, 2, 3, 4, 5, 6, 7, UTC) res = msgspec.json.decode(s, type=datetime.datetime) assert res == exp def test_decode_min_datetime(self): res = msgspec.json.decode(b'"0001-01-01T00:00:00Z"', type=datetime.datetime) exp = datetime.datetime.min.replace(tzinfo=UTC) assert res == exp def test_decode_max_datetime(self): res = msgspec.json.decode( b'"9999-12-31T23:59:59.999999Z"', type=datetime.datetime ) exp = datetime.datetime.max.replace(tzinfo=UTC) assert res == exp @pytest.mark.parametrize( "msg, sol", [ ( b'"2022-01-02T03:04:05.1234564Z"', datetime.datetime(2022, 1, 2, 3, 4, 5, 123456, UTC), ), ( b'"2022-01-02T03:04:05.1234565Z"', datetime.datetime(2022, 1, 2, 3, 4, 5, 123457, UTC), ), ( b'"2022-01-02T03:04:05.12345650000000000001Z"', datetime.datetime(2022, 1, 2, 3, 4, 5, 123457, UTC), ), ( b'"2022-01-02T03:04:05.9999995Z"', datetime.datetime(2022, 1, 2, 3, 4, 6, 0, UTC), ), ( b'"2022-01-02T03:04:59.9999995Z"', datetime.datetime(2022, 1, 2, 3, 5, 0, 0, UTC), ), ( b'"2022-01-02T03:59:59.9999995Z"', datetime.datetime(2022, 1, 2, 4, 0, 0, 0, UTC), ), ( b'"2022-01-02T23:59:59.9999995Z"', datetime.datetime(2022, 1, 3, 0, 0, 0, 0, UTC), ), ( b'"2022-02-28T23:59:59.9999995Z"', datetime.datetime(2022, 3, 1, 0, 0, 0, 0, UTC), ), ], ) def test_decode_datetime_nanos(self, msg, sol): res = msgspec.json.decode(msg, type=datetime.datetime) assert res == sol @pytest.mark.parametrize( "lax, strict", [ ("2022-01-02T03:04:05+0102", "2022-01-02T03:04:05+01:02"), ("2022-01-02T03:04:05-0102", "2022-01-02T03:04:05-01:02"), ("2022-01-02 03:04:05", "2022-01-02T03:04:05"), ], ) def test_decode_datetime_rfc3339_relaxed(self, lax, strict): """msgspec supports a few relaxations of the RFC3339 format.""" sol = datetime.datetime.fromisoformat(strict) msg = msgspec.json.encode(lax) res = msgspec.json.decode(msg, type=datetime.datetime) assert res == sol @pytest.mark.parametrize( "s", [ # Incorrect field lengths b'"001-02-03T04:05:06.000007Z"', b'"0001-2-03T04:05:06.000007Z"', b'"0001-02-3T04:05:06.000007Z"', b'"0001-02-03T4:05:06.000007Z"', b'"0001-02-03T04:5:06.000007Z"', b'"0001-02-03T04:05:6.000007Z"', b'"0001-02-03T04:05:06.000007+0:00"', b'"0001-02-03T04:05:06.000007+00:0"', b'"0001-02-03T04:05:06.000007+000"', # Trailing data b'"0001-02-03T04:05:06.000007+00:000"', b'"0001-02-03T04:05:06.000007+00000"', b'"0001-02-03T04:05:06.000007Z0"', b'"0001-02-03T04:05:06a"', b'"0001-02-03T04:05:06.000007a"', # Truncated b'"0001-02-03T04:05:"', # Missing +/- b'"0001-02-03T04:05:06.00000700:00"', # Missing digits after decimal b'"0001-02-03T04:05:06."', b'"0001-02-03T04:05:06.Z"', # Invalid characters b'"000a-02-03T04:05:06.000007Z"', b'"0001-0a-03T04:05:06.000007Z"', b'"0001-02-0aT04:05:06.000007Z"', b'"0001-02-03T0a:05:06.000007Z"', b'"0001-02-03T04:0a:06.000007Z"', b'"0001-02-03T04:05:0a.000007Z"', b'"0001-02-03T04:05:06.00000aZ"', b'"0001-02-03T04:05:06.000007a"', b'"0001-02-03T04:05:06.000007+0a:00"', b'"0001-02-03T04:05:06.000007+00:0a"', b'"0001-02-03T04:05:06.000007+0a00"', b'"0001-02-03T04:05:06.000007+000a"', # Year out of range b'"0000-02-03T04:05:06.000007Z"', # Month out of range b'"0001-00-03T04:05:06.000007Z"', b'"0001-13-03T04:05:06.000007Z"', # Day out of range for month b'"0001-02-00T01:05:06.000007Z"', b'"0001-02-29T01:05:06.000007Z"', b'"2000-02-30T01:05:06.000007Z"', # Hour out of range b'"0001-02-03T24:05:06.000007Z"', # Minute out of range b'"0001-02-03T04:60:06.000007Z"', # Second out of range b'"0001-02-03T04:05:60.000007Z"', # Timezone hour out of range b'"0001-02-03T04:05:06.000007+24:00"', b'"0001-02-03T04:05:06.000007-24:00"', # Timezone minute out of range b'"0001-02-03T04:05:06.000007+00:60"', b'"0001-02-03T04:05:06.000007-00:60"', ], ) def test_decode_datetime_malformed(self, s): with pytest.raises(msgspec.ValidationError, match="Invalid RFC3339"): msgspec.json.decode(s, type=datetime.datetime) class TestIntegers: @pytest.mark.parametrize("ndigits", range(21)) def test_encode_int(self, ndigits): if ndigits == 0: s = b"0" else: s = "".join( itertools.islice(itertools.cycle("123456789"), ndigits) ).encode() x = int(s) assert msgspec.json.encode(x) == s if 0 < ndigits < 20: assert msgspec.json.encode(-x) == b"-" + s @pytest.mark.parametrize("x", [-(2**63 + 1), -(2**63), 2**64 - 1, 2**64]) def test_encode_big_integers(self, x): assert msgspec.json.encode(x) == str(x).encode() @pytest.mark.parametrize("ndigits", range(21)) def test_decode_int(self, ndigits): if ndigits == 0: s = b"0" else: s = "".join( itertools.islice(itertools.cycle("123456789"), ndigits) ).encode() x = int(s) assert msgspec.json.decode(s) == x if 0 < ndigits < 20: assert msgspec.json.decode(b"-" + s) == -x @pytest.mark.parametrize("x", [2**63 - 1, 2**63, 2**63 + 1]) def test_decode_int_19_digit_overflow_boundary(self, x): s = str(x).encode("utf-8") # Add extra trailing 0 to ensure no out-of-bounds reads buffer = memoryview(s + b"0")[:-1] assert msgspec.json.decode(buffer) == x @pytest.mark.parametrize("x", [-(2**63), 2**64 - 1]) def test_decode_int_boundaries(self, x): s = str(x).encode() x2 = msgspec.json.decode(s) assert isinstance(x2, int) assert x2 == x @pytest.mark.parametrize( "x", [ -(2**63) - 1, 2**64, 2**64 + 10**18, 2**64 + 10**18 + 1, 19999999999999999999, 20000000000000000000, 2**64 + 10**19, # mantissa overflows to 20 digits 2**64 + 10**19 - 1, -(2**64), -(2**64) + 10**18, -(2**64) + 10**18 + 1, -19999999999999999999, -20000000000000000000, -(2**64 + 10**19), -(2**64 + 10**19 - 1), ], ) @pytest.mark.parametrize("type", [Any, int]) def test_decode_big_int(self, x, type): s = str(x).encode() x2 = msgspec.json.decode(s, type=type) assert isinstance(x2, int) assert x2 == x @pytest.mark.parametrize("max_length", [None, 1000]) def test_decode_big_int_max_length(self, max_length): if max_length is not None: try: orig = sys.get_int_max_str_digits() sys.set_int_max_str_digits(max_length) except AttributeError: pytest.skip(reason="sys.set_int_max_str_digits is not available") def cleanup(): sys.set_int_max_str_digits(orig) s = "1" * (max_length + 1) else: cleanup = None s = "1" * 4301 try: with pytest.raises( msgspec.ValidationError, match="Integer value out of range" ): msgspec.json.decode(s, type=int) finally: if cleanup: cleanup() @pytest.mark.parametrize("s", [b" 123 ", b" -123 "]) def test_decode_int_whitespace(self, s): assert msgspec.json.decode(s) == int(s) @pytest.mark.parametrize("s", [b"- 123", b"-n123", b"1 2", b"12n3", b"123n"]) def test_decode_int_malformed(self, s): with pytest.raises(msgspec.DecodeError): msgspec.json.decode(s) def test_decode_int_converts_to_float_if_requested(self): x = msgspec.json.decode(b"123", type=float) assert isinstance(x, float) assert x == 123.0 x = msgspec.json.decode(b"-123", type=float) assert isinstance(x, float) assert x == -123.0 def test_decode_int_type_error(self): with pytest.raises(msgspec.ValidationError, match="Expected `str`, got `int`"): msgspec.json.decode(b"123", type=str) class TestLiteral: @pytest.mark.parametrize( "values", [ (1, 2, 3), ("one", "two", "three"), (1, 2, "three", "four"), (1, None), ("one", None), ], ) def test_literal(self, values): literal = Literal[values] dec = msgspec.json.Decoder(literal) for val in values: assert dec.decode(msgspec.json.encode(val)) == val for bad in ["bad", 1234]: with pytest.raises(msgspec.ValidationError): dec.decode(msgspec.json.encode(bad)) def test_int_literal_errors(self): dec = msgspec.json.Decoder(Literal[1, 2, 3]) with pytest.raises(msgspec.ValidationError, match="Invalid enum value 4"): dec.decode(b"4") with pytest.raises(msgspec.ValidationError, match="Expected `int`, got `str`"): dec.decode(b'"bad"') def test_str_literal_errors(self): dec = msgspec.json.Decoder(Literal["one", "two", "three"]) with pytest.raises(msgspec.ValidationError, match="Expected `str`, got `int`"): dec.decode(b"4") with pytest.raises(msgspec.ValidationError, match="Invalid enum value 'bad'"): dec.decode(b'"bad"') class TestFloat: @pytest.mark.parametrize( "x", [ 0.1 + 0.2, -0.1 - 0.2, 1.0, -1.0, sys.float_info.min, sys.float_info.max, 1.0 / 3, 2.0**-24, 2.0**-14, 2.0**-149, 2.0**-126, sys.float_info.min / 2, sys.float_info.min / 10, sys.float_info.min / 1000, sys.float_info.min / 100000, 5e-324, 2.9802322387695312e-8, 2.109808898695963e16, 4.940656e-318, 1.18575755e-316, 2.989102097996e-312, 9.0608011534336e15, 4.708356024711512e18, 9.409340012568248e18, 1.2345678, 5.764607523034235e39, 1.152921504606847e40, 2.305843009213694e40, 4.294967294, 4.294967295, 4.294967296, 4.294967297, 4.294967298, 1.7800590868057611e-307, 2.8480945388892175e-306, 2.446494580089078e-296, 4.8929891601781557e-296, 1.8014398509481984e16, 3.6028797018963964e16, 2.900835519859558e-216, 5.801671039719115e-216, 3.196104012172126e-27, 9.007199254740991e15, 9.007199254740992e15, 3.1462737709539517e18, ], ) def test_roundtrip_float_tricky_cases(self, x): """Tricky float values, many taken from https://github.com/ulfjack/ryu/blob/master/ryu/tests/d2s_test.cc""" s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 @pytest.mark.parametrize("x", [-0.0, 0.0]) def test_roundtrip_signed_zero(self, x): s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 assert math.copysign(1.0, x) == math.copysign(1.0, x2) @pytest.mark.parametrize("n", range(-15, 15)) def test_roundtrip_float_powers_10(self, n): x = 10.0**n s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 @pytest.mark.parametrize("n", range(-15, 14)) def test_roundtrip_float_lots_of_middle_zeros(self, n): x = 1e15 + 10.0**n s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 @pytest.mark.parametrize("n", range(1, 17)) def test_roundtrip_float_integers(self, n): x = float("".join(itertools.islice(itertools.cycle("123456789"), n))) s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 @pytest.mark.parametrize("scale", [0.0001, 1, 1000]) @pytest.mark.parametrize("n", range(54)) def test_roundtrip_float_powers_of_2(self, n, scale): x = (2.0**n) * scale s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 def test_roundtrip_float_random_checks(self, rand): for _ in range(1000): x = rand.float() s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 @pytest.mark.parametrize( "s", [ str(2**64 - 1).encode(), # 20 digits, no overflow str(2**64).encode(), # 20 digits, overflow str(2**64 + 1).encode(), # 20 digits, overflow str(2**68).encode(), # 21 digits ], ) @pytest.mark.parametrize("i", [-5, 0, 5]) def test_decode_float_long_mantissa(self, s, i): if i > 0: s = s[:i] + b"." + s[i:] elif i == 0: s += b".0" else: s = b"0." + b"0" * (-i) + s x = msgspec.json.decode(s) x2 = msgspec.json.decode(s, type=float) assert float(s) == x == x2 with pytest.raises( msgspec.ValidationError, match="Expected `int`, got `float`" ): msgspec.json.decode(s, type=int) @pytest.mark.parametrize("n", [5, 20, 300, 500]) def test_decode_float_lots_of_leading_zeros(self, n): s = b"0." + b"0" * n + b"123" x = msgspec.json.decode(s) x2 = msgspec.json.decode(s, type=float) assert x == x2 == float(s) @pytest.mark.parametrize("n", [5, 20, 300, 500]) def test_decode_float_lots_of_middle_leading_zeros(self, n): s = b"1." + b"0" * n + b"123" x = msgspec.json.decode(s) x2 = msgspec.json.decode(s, type=float) assert x == x2 == float(s) @pytest.mark.parametrize("prefix", [b"0", b"0.0", b"0.0001", b"123", b"123.000"]) @pytest.mark.parametrize("e", [b"e", b"E"]) @pytest.mark.parametrize("sign", [b"+", b"-", b""]) @pytest.mark.parametrize("exp", [b"0", b"000", b"12", b"300"]) def test_decode_float_with_exponent(self, prefix, e, sign, exp): s = prefix + e + sign + exp x = msgspec.json.decode(s) x2 = msgspec.json.decode(s, type=float) assert x == x2 == float(s) def test_decode_float_long_decimal_large_exponent(self): s = b"0." + b"0" * 500 + b"123e500" x = msgspec.json.decode(s) assert x == float(s) @pytest.mark.parametrize("s", [b"123e308", b"-123e308", b"123e50000", b"123e50000"]) def test_decode_float_boundaries_errors(self, s): with pytest.raises(msgspec.ValidationError, match="Number out of range"): msgspec.json.decode(s) @pytest.mark.parametrize( "s", [ "-2.2222222222223e-322", "9007199254740993.0", "860228122.6654514319E+90", "10000000000000000000", "10000000000000000000000000000001000000000000", "10000000000000000000000000000000000000000001", "1.1920928955078125e-07", ( "9355950000000000000.0000000000000000000000000000000000184467440737095516160000" "018446744073709551616184467440737095516140737095516161844674407370955161600018" "446744073709551616600000184467440737095516161844674407370955161407370955161618" "446744073709551616000184467440737095516160184467440737095567445161618446744073" "709551614073709551616184467440737095516160001844674407370955161601844674407370" "955161161600018446744073709500184467440737095516160018446744073709551616001844" "674407370955116816446744073709551616000184407370955161601844674407370955161618" "446744073709551616000184467440753691075160161161600018446744073709500184467440" "737095516160018446744073709551616001844674407370955161618446744073709551616000" "1844955161618446744073709551616000184467440753691075160018446744073709" ), ( "2.2250738585072021241887014792022203290724052827943903781430313383743510731924" "419468675440643256388185138218821850243806999994773301300564988410779192874134" "192929720097048195199306799329096904278406473168204156592672863293363047467012" "331685298342215274451726083585965456631928283524478778779989431077978383369915" "928859455521371418112845825114558431922307989750439508685941245723089173894616" "936837232119137365897797772328669884035639025104444303545739673370658398105542" "045669382465841374760715598117657387762674766591238719993190400631733470900301" "279018817520344719025002806127777791679839109057858400646471594381051148915428" "277504117468219413395246668250343130618158782937900420539237507208336669324158" "0002758391118854188641513168478436313080237596295773983001708984375e-308" ), "1.0000000000000006661338147750939242541790008544921875", "1090544144181609348835077142190", "2.2250738585072013e-308", "-92666518056446206563E3", "-92666518056446206563E3", "-42823146028335318693e-128", "90054602635948575728E72", ( "1.0000000000000018855892087022346387017456602069175351539464355066307055836837" "3221972569761144603605635692374830246134201063722058e-309" ), "0e9999999999999999999999999999", "-2402844368454405395.2", "2402844368454405395.2", "7.0420557077594588669468784357561207962098443483187940792729600000e+59", "7.0420557077594588669468784357561207962098443483187940792729600000e+59", "-1.7339253062092163730578609458683877051596800000000000000000000000e+42", "-2.0972622234386619214559824785284023792871122537545728000000000000e+52", "-1.0001803374372191849407179462120053338028379051879898808320000000e+57", "-1.8607245283054342363818436991534856973992070520151142825984000000e+58", "-1.9189205311132686907264385602245237137907390376574976000000000000e+52", "-2.8184483231688951563253238886553506793085187889855201280000000000e+54", "-1.7664960224650106892054063261344555646357024359107788800000000000e+53", "-2.1470977154320536489471030463761883783915110400000000000000000000e+45", "-4.4900312744003159009338275160799498340862630046359789166919680000e+61", "1.797693134862315700000000000000001e308", "1.00000006e+09", "4.9406564584124653e-324", "4.9406564584124654e-324", "2.2250738585072009e-308", "2.2250738585072014e-308", "1.7976931348623157e308", "1.7976931348623158e308", "4503599627370496.5", "4503599627475352.5", "4503599627475353.5", "2251799813685248.25", "1125899906842624.125", "1125899906842901.875", "2251799813685803.75", "4503599627370497.5", "45035996.273704995", "45035996.273704985", ( "0.0000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000445" "014771701440227211481959341826395186963909270329129604685221944964444404215389" "103305904781627017582829831782607924221374017287738918929105531441481564124348" "675997628212653465850710457376274429802596224490290377969811444461457051026631" "151003182879495279596682360399864792509657803421416370138126133331198987655154" "514403152612538132666529513060001849177663286607555958373922409899478075565940" "981010216121988146052587425791790000716759993441450860872056815779154359230189" "103349648694206140521828924314457976051636509036065141403772174422625615902446" "685257673724464300755133324500796506867194913776884780053099639677097589658441" "378944337966219939673169362804570848666132067970177289160800206986794085513437" "28867675409720757232455434770912461317493580281734466552734375" ), ( "0.0000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000000000000000000222" "507385850720088902458687608585988765042311224095946549352480256244000922823569" "517877588880375915526423097809504343120858773871583572918219930202943792242235" "598198275012420417889695713117910822610439719796040004548973919380791989360815" "256131133761498420432717510336273915497827315941438281362751138386040942494649" "422863166954291050802018159266421349966065178030950759130587198464239060686371" "020051087232827846788436319445158661350412234790147923695852083215976210663754" "016137365830441936037147783553066828345356340050740730401356029680463759185831" "631242245215992625464943008368518617194224176464551371354201322170313704965832" "101546540680353974179060225895030235019375197730309457631732108525072993050897" "61582519159720757232455434770912461317493580281734466552734375" ), ( "143845666314139027352611820764223558118322784524633123116263665379036815209139" "419693036582863468763794815794077659918279138752713535303473835713411031060945" "569390082419354977279201654318268051974058035436546798544018359870131225762454" "556233139701832992861319612559027418772007391481806253083031653315809862498411" "888929828137181228878953731059903752911341543873895489475212472498306724110876" "448834645437669901867307840475112141480493722424080599312381693232622368309077" "056159757045779393298582616260425588452913412639628220212652625338938342180672" "795458852559611437980126909409632980505480308929973699687095125857301087740440" "745195384669860919821392688269207855703322826525930548119852605981316446918758" "669325733577952202040764549868426333992190522755661669812996741289128223168550" "466067127792719829000982468018631975097866573457668378425580226970891736171946" "604317520115884909788137047711185017157986905601606166617302905958843377601564" "443970505037755427769614392827809345379280384625271596601673322264644238289212" "394005244134682242972159388437821255870100435692424303005951748934664657772462" "249891975259738209522250031112418182351225107135618176937657765139002829779615" "620881537508915912839494571051586133448626710179749711112590927250519479287088" "961717975870344260801614334326215999814970060659779253557445756042922697427344" "363032381874773077131676339857211087495998192373246307688452867739265415001026" "982223940199342748237651323138921235358357356637691557265091686655361236618737" "895955498356671276709337290603018897622016905802535497362221166650454931695827" "188097569714354656446980679135870731887307570838334500409015197406832583817753" "126695417740666139222980134999469594150993565535565298572378215357008408956013" "9142231.7384750423625968754491545523922995489471381620816941686753406778438076" "131297804493233637590270129724669873709218168131626587547265451210905455072402" "670004565947865409496052607224619378706306348749917293982080264676981318986918" "30012167897399682179601734569071423681e-1500" ), "-2240084132271013504.131248280843119943687942846658579428", ], ids=itertools.count(), ) def test_decode_float_cases_from_fastfloat(self, s): """Some tricky test cases from https://github.com/fastfloat/fast_float/blob/main/tests/basictest.cpp""" x = msgspec.json.decode(s.encode(), type=float) assert x == float(s) @pytest.mark.parametrize("negative", [True, False]) def test_decode_long_float_rounds_to_zero(self, negative): s = b"0." + b"0" * 400 + b"1" if negative: s = b"-" + s x = msgspec.json.decode(s) assert x == 0.0 assert (math.copysign(1.0, x) < 0) == negative @pytest.mark.parametrize( "s", [ "0." + "0" * 900 + "123451e875", "0." + "0" * 900 + "12345" * 40 + "1e875", "0." + "0" * 900 + "12345" * 400 + "1e875", "1" * 30000 + "e-30000", ], ids=itertools.count(), ) def test_decode_long_float_truncated_but_exp_brings_back_in_bounds(self, s): """The digits part of these would put them over the limit to inf, but the exponent bit brings them back in range""" x = msgspec.json.decode(s.encode()) assert x == float(s) @pytest.mark.parametrize( "s, error", [ (b"1.", "invalid number"), (b"1..", "invalid number"), (b"1.2.", "trailing characters"), (b".123", "invalid character"), (b"001.2", "invalid number"), (b"00.2", "invalid number"), (b"1a2", "trailing characters"), (b"1.e2", "invalid number"), (b"1.2e", "invalid number"), (b"1.2e+", "invalid number"), (b"1.2e-", "invalid number"), (b"1.2ea", "invalid number"), (b"1.2e1a", "trailing characters"), (b"1.2e1-2", "trailing characters"), (b"123 456", "trailing characters"), (b"123. 456", "invalid number"), (b"123.456 e2", "trailing characters"), (b"123.456e 2", "invalid number"), ], ) def test_decode_float_malformed(self, s, error): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s) @pytest.mark.parametrize( "s, error", [ (b"1" * 25 + b".", "invalid number"), (b"1" * 25 + b".2.", "trailing characters"), (b"1" * 25 + b".e", "invalid number"), (b"1" * 25 + b".e2", "invalid number"), (b"1" * 25 + b".2e", "invalid number"), (b"1" * 25 + b".2e-", "invalid number"), (b"1" * 25 + b".2e+", "invalid number"), (b"1" * 25 + b".2ea", "invalid number"), ], ids=itertools.count(), ) def test_decode_long_float_malformed(self, s, error): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s) @pytest.mark.parametrize( "s", [ b"1e500", b"-1e500", b"123456789e301", b"-123456789e301", b"0.01e311", b"-0.01e311", b"1" * 3000 + b"e-2600", b"-" + b"1" * 3000 + b"e-2600", ], ids=itertools.count(), ) def test_decode_float_out_of_bounds(self, s): with pytest.raises(msgspec.ValidationError, match="out of range"): msgspec.json.decode(s) @pytest.mark.parametrize("s", [b"1.23e3", b"1.2", b"1e2"]) def test_decode_float_err_expected_int(self, s): with pytest.raises( msgspec.ValidationError, match="Expected `int`, got `float`" ): msgspec.json.decode(s, type=int) def test_float_hook_untyped(self): dec = msgspec.json.Decoder(float_hook=decimal.Decimal) res = dec.decode(b"1.33") assert res == decimal.Decimal("1.33") assert type(res) is decimal.Decimal def test_float_hook_typed(self): class Ex(msgspec.Struct): a: float b: decimal.Decimal c: Any d: Any class MyFloat(NamedTuple): x: str dec = msgspec.json.Decoder(Ex, float_hook=MyFloat) res = dec.decode(b'{"a": 1.5, "b": 1.3, "c": 1.3, "d": 123}') sol = Ex(1.5, decimal.Decimal("1.3"), MyFloat("1.3"), 123) assert res == sol def test_float_hook_error(self): def float_hook(val): raise ValueError("Oh no!") class Ex(msgspec.Struct): a: float b: Any dec = msgspec.json.Decoder(Ex, float_hook=float_hook) assert dec.decode(b'{"a": 1.5, "b": 2}') == Ex(a=1.5, b=2) with pytest.raises(msgspec.ValidationError) as rec: dec.decode(b'{"a": 1.5, "b": 2.5}') assert "Oh no!" in str(rec.value) assert "at `$.b`" in str(rec.value) class TestDecimal: """Most decimal tests are in test_common.py, the ones here are for json specific behaviors""" def test_decimal_to_number_keeps_precision(self): enc = msgspec.json.Encoder(decimal_format="number") msg = enc.encode(Decimal("1.3000")) assert msg == b"1.3000" @pytest.mark.parametrize( "msg", [ "123", "-123", "1e3", "-1e3", "1.0100", "-1.0100", "0.123456789123456789123456789", "-0.123456789123456789123456789", "123456789123456789123456789", "-123456789123456789123456789", ], ) def test_decimal_from_number_keeps_precision(self, msg): res = msgspec.json.decode(msg, type=Decimal) sol = Decimal(msg) assert res == sol assert str(res) == str(sol) # check trailing 0s @pytest.mark.parametrize( "msg", [ "123_", "123_45", "123._", "123.", "123.45_", "123.45_6", "123456789123456789123456789_", "123456789123456789123456789.", "0.123456789123456789123456789_", ], ) def test_decimal_from_number_still_errors_on_invalid_number(self, msg): """Check that decimal strings that `decimal.Decimal` will happily parse but aren't valid JSON still error as invalid JSON""" Decimal(msg) with pytest.raises(msgspec.DecodeError) as rec: msgspec.json.decode(msg) # not ValidationError, a subclass assert type(rec.value) is msgspec.DecodeError assert "JSON is malformed" in str(rec.value) def test_decimal_from_number_priority(self): posint = "123" negint = "-123" bigint = "123456789" * 3 double = "123.45" extdouble = "123." + ("123456789" * 3) cases = [ (posint, Decimal, Decimal), (negint, Decimal, Decimal), (bigint, Decimal, Decimal), (double, Decimal, Decimal), (extdouble, Decimal, Decimal), (posint, Union[Decimal, int], int), (negint, Union[Decimal, int], int), (bigint, Union[Decimal, int], int), (double, Union[Decimal, int], Decimal), (extdouble, Union[Decimal, int], Decimal), (posint, Union[Decimal, float], float), (negint, Union[Decimal, float], float), (bigint, Union[Decimal, float], float), (double, Union[Decimal, float], float), (extdouble, Union[Decimal, float], float), (posint, Union[Decimal, int, float], int), (negint, Union[Decimal, int, float], int), (bigint, Union[Decimal, int, float], int), (double, Union[Decimal, int, float], float), (extdouble, Union[Decimal, int, float], float), ] for msg, request_type, out_type in cases: out = msgspec.json.decode(msg, type=request_type) assert type(out) is out_type class TestSequences: @pytest.mark.parametrize("x", [[], [1], [1, "two", False]]) @pytest.mark.parametrize("type", [list, set, frozenset, tuple]) def test_roundtrip_sequence(self, x, type): x = type(x) s = msgspec.json.encode(x) x2 = msgspec.json.decode(s, type=type) assert x == x2 assert isinstance(x2, type) @pytest.mark.parametrize( "s, x", [ (b"[\t\n\r ]", []), (b"[\t\n 1\r ]", [1]), (b"[ 1\n ,\t 2\r ]", [1, 2]), (b" \t [\n 1 , 2 \t ]\r ", [1, 2]), ], ) @pytest.mark.parametrize("type", [list, set, frozenset, tuple]) def test_decode_sequence_ignores_whitespace(self, s, x, type): x2 = msgspec.json.decode(s, type=type) assert isinstance(x2, type) assert type(x) == type(x2) def test_decode_typed_list(self): dec = msgspec.json.Decoder(List[int]) assert dec.decode(b"[]") == [] assert dec.decode(b"[1]") == [1] assert dec.decode(b"[1,2]") == [1, 2] def test_decode_typed_set(self): dec = msgspec.json.Decoder(Set[int]) assert dec.decode(b"[]") == set() assert dec.decode(b"[1]") == {1} assert dec.decode(b"[1,2]") == {1, 2} def test_decode_typed_frozenset(self): dec = msgspec.json.Decoder(FrozenSet[int]) assert dec.decode(b"[]") == frozenset() assert dec.decode(b"[1]") == frozenset({1}) assert dec.decode(b"[1,2]") == frozenset({1, 2}) def test_decode_typed_vartuple(self): dec = msgspec.json.Decoder(Tuple[int, ...]) assert dec.decode(b"[]") == () assert dec.decode(b"[1]") == (1,) assert dec.decode(b"[1,2]") == ( 1, 2, ) @pytest.mark.parametrize("type", [List[int], Set[int], Tuple[int, ...]]) @pytest.mark.parametrize("bad_index", [0, 9, 10, 91, 1234]) def test_decode_typed_list_wrong_element_type(self, type, bad_index): dec = msgspec.json.Decoder(type) data = [1] * (bad_index + 1) data[bad_index] = "oops" msg = msgspec.json.encode(data) err_msg = rf"Expected `int`, got `str` - at `\$\[{bad_index}\]`" with pytest.raises(msgspec.ValidationError, match=err_msg): dec.decode(msg) @pytest.mark.parametrize( "s, error", [ (b"[", "truncated"), (b"[1", "truncated"), (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[1, ]", "trailing comma in array"), (b"[1, 2 3]", r"expected ',' or ']'"), ], ) @pytest.mark.parametrize("type", [list, set, tuple, Tuple[int, int, int]]) def test_decode_sequence_malformed(self, s, error, type): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=type) def test_decode_fixtuple_any(self): dec = msgspec.json.Decoder(Tuple[Any, Any, Any]) x = (1, "two", False) res = dec.decode(b'[1, "two", false]') assert res == x with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `int`" ): dec.decode(b"1") with pytest.raises( msgspec.ValidationError, match="Expected `array` of length 3" ): dec.decode(b'[1, "two"]') def test_decode_fixtuple_typed(self): dec = msgspec.json.Decoder(Tuple[int, str, bool]) x = (1, "two", False) res = dec.decode(b'[1, "two", false]') assert res == x with pytest.raises(msgspec.ValidationError, match="Expected `bool`"): dec.decode(b'[1, "two", "three"]') with pytest.raises( msgspec.ValidationError, match="Expected `array` of length 3" ): dec.decode(b'[1, "two"]') class TestNamedTuple: """Most tests are in `test_common`, this just tests some JSON peculiarities""" @pytest.mark.parametrize( "s, x", [(b"[\t\n\r ]", ()), (b" [ 1 , 2 ] ", (1, 2))], ) def test_decode_namedtuple_ignores_whitespace(self, s, x): class Test(NamedTuple): a: int = 0 b: int = 1 x2 = msgspec.json.decode(s, type=Test) assert x2 == Test(*x) @pytest.mark.parametrize( "s, error", [ (b"[", "truncated"), (b"[1", "truncated"), (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[1, ]", "trailing comma in array"), (b"[1, 2 3]", r"expected ',' or ']'"), ], ) def test_decode_namedtuple_malformed(self, s, error): class Test(NamedTuple): a: int b: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test) class TestDict: def test_encode_dict_raises_non_string_or_numeric_keys(self): with pytest.raises( TypeError, match="Only dicts with str-like or number-like keys are supported", ): msgspec.json.encode({"a": 1, (1, 2): "bad"}) @pytest.mark.parametrize("x", [{}, {"a": 1}, {"a": 1, "b": 2}]) def test_roundtrip_dict(self, x): s = msgspec.json.encode(x) x2 = msgspec.json.decode(s) assert x == x2 assert json.loads(s) == x def test_decode_any_dict(self): x = msgspec.json.decode(b'{"a": 1, "b": "two", "c": false}') assert x == {"a": 1, "b": "two", "c": False} @pytest.mark.parametrize( "s, x", [ (b"{\t\n\r }", {}), (b'{\t\n\r "a" : 1}', {"a": 1}), (b'{ "a"\t : 1 \n, "b": \r 2 }', {"a": 1, "b": 2}), (b' { "a"\t : 1 \n, "b": \r 2 } ', {"a": 1, "b": 2}), ], ) def test_decode_dict_ignores_whitespace(self, s, x): x2 = msgspec.json.decode(s) assert x == x2 def test_decode_dict_wrong_element_type(self): dec = msgspec.json.Decoder(Dict[str, int]) with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[...\]`" ): dec.decode(b'{"a": "bad"}') def test_decode_dict_literal_key(self): dec = msgspec.json.Decoder(Dict[Literal["a", "b"], int]) assert dec.decode(b'{"a": 1, "b": 2}') == {"a": 1, "b": 2} with pytest.raises(msgspec.ValidationError, match="Invalid enum value 'c'"): dec.decode(b'{"a": 1, "c": 2}') def test_decode_dict_enum_key(self): dec = msgspec.json.Decoder(Dict[FruitStr, int]) assert dec.decode(b'{"apple": 1, "banana": 2}') == { FruitStr.APPLE: 1, FruitStr.BANANA: 2, } with pytest.raises( msgspec.ValidationError, match="Invalid enum value 'carrot'" ): dec.decode(b'{"apple": 1, "carrot": 2}') def test_decode_dict_str_key_constraints(self): dec = msgspec.json.Decoder( Dict[Annotated[str, msgspec.Meta(min_length=3)], int] ) assert dec.decode(b'{"abc": 1, "def": 2}') == {"abc": 1, "def": 2} with pytest.raises( msgspec.ValidationError, match="Expected `str` of length >= 3" ): dec.decode(b'{"a": 1}') @pytest.mark.parametrize("length", [3, 32, 33]) def test_decode_dict_string_cache(self, length): key = "x" * length msg = [{key: 1}, {key: 2}, {key: 3}] res = msgspec.json.decode(msgspec.json.encode(msg)) assert msg == res ids = {id(k) for d in res for k in d.keys()} if length > 32: assert len(ids) == 3 else: assert len(ids) == 1 def test_decode_dict_string_cache_ascii_only(self): """Short non-ascii strings aren't cached""" s = "123 á 456" msg = [{s: 1}, {s: 2}, {s: 3}] res = msgspec.json.decode(msgspec.json.encode(msg)) ids = {id(k) for d in res for k in d.keys()} assert len(ids) == 3 @pytest.mark.parametrize( "key", [ 1, 1.5, FruitInt.APPLE, uuid.uuid4(), datetime.datetime.now(), datetime.date.today(), datetime.datetime.now().time(), datetime.timedelta(1.5), b"test", Decimal("1.5"), ], ) def test_roundtrip_dict_key_types(self, key): msg = {key: 100} sol = msgspec.json.encode(msgspec.to_builtins(msg, str_keys=True)) res = msgspec.json.encode(msg) assert res == sol msg2 = msgspec.json.decode(sol, type=Dict[type(key), int]) assert msg == msg2 def test_decode_dict_int_enum_key(self): dec = msgspec.json.Decoder(Dict[FruitInt, int]) assert dec.decode(b'{"-1": 10, "2": 20}') == { FruitInt.APPLE: 10, FruitInt.BANANA: 20, } with pytest.raises(msgspec.ValidationError, match="Invalid enum value 3"): dec.decode(b'{"-1": 1, "3": 2}') @pytest.mark.parametrize("x", [-(2**63), 2**64 - 1]) def test_encode_dict_int_key(self, x): msg = {-(2**63): "a", 0: "b", 2**64 - 1: "c"} s = msgspec.json.encode(msg) assert s == b'{"-9223372036854775808":"a","0":"b","18446744073709551615":"c"}' for x in [-(2**63) - 1, 2**64]: s = msgspec.json.encode({x: "a"}) assert s == f'{{"{x}":"a"}}'.encode("utf-8") def test_decode_dict_int_key(self): msg = {-(2**63): "a", 0: "b", 2**64 - 1: "c"} buf = msgspec.json.encode(msg) res = msgspec.json.decode(buf, type=Dict[int, str]) assert res == msg @pytest.mark.parametrize("s", ['""', '"-"', '"a"', '"-a"', '"01"', '"1a"']) def test_decode_dict_int_key_malformed(self, s): bad = ("{%s: 1}" % s).encode("utf-8") with pytest.raises(msgspec.ValidationError, match="Expected `int`, got `str`"): msgspec.json.decode(bad, type=Dict[int, int]) @pytest.mark.parametrize("x", [-(2**63) - 1, 2**64, 2**65]) def test_decode_dict_big_int(self, x): msg = {str(x): 1} buf = msgspec.json.encode(msg) res = msgspec.json.decode(buf, type=Dict[int, int]) assert res == {x: 1} assert type(list(res)[0]) is int def test_decode_dict_int_key_constraints(self): dec = msgspec.json.Decoder(Dict[Annotated[int, msgspec.Meta(ge=3)], int]) assert dec.decode(b'{"4": 1, "5": 2}') == {4: 1, 5: 2} with pytest.raises(msgspec.ValidationError, match="Expected `int` >= 3"): dec.decode(b'{"2": 1}') def test_decode_dict_int_literal_key(self): dec = msgspec.json.Decoder(Dict[Literal[-1, 2], int]) assert dec.decode(b'{"-1": 10, "2": 20}') == {-1: 10, 2: 20} with pytest.raises(msgspec.ValidationError, match="Invalid enum value 3"): dec.decode(b'{"-1": 10, "3": 20}') def test_encode_dict_float_key(self): msg = { 1.5: 1, -1.5: 2, 0.0: 3, float("-inf"): 4, float("inf"): 5, float("nan"): 6, } sol = msgspec.json.encode({str(k): v for k, v in msg.items()}) res = msgspec.json.encode(msg) assert res == sol def test_decode_dict_float_key(self): msg = {"1.5": 1, "inf": 2, "-inf": 3, "0": 4, "-1.5e12": 5, "123": 6} buf = msgspec.json.encode(msg) sol = {float(k): v for k, v in msg.items()} res = msgspec.json.decode(buf, type=Dict[float, int]) assert res == sol def test_decode_dict_int_or_float_key(self): buf = b'{"1.5": "a", "123": "b"}' sol = {1.5: "a", 123: "b"} res = msgspec.json.decode(buf, type=Dict[Union[int, float], str]) assert res == sol assert type(list(res.keys())[-1]) is int def test_encode_dict_str_subclass_key(self): class mystr(str): pass msg = msgspec.json.encode({mystr("test"): 1}) assert msg == b'{"test":1}' def test_encode_dict_custom_key(self): class Custom: def __init__(self, value): self.value = value msg = msgspec.json.encode( {Custom("a"): 1, Custom("b"): 2}, enc_hook=lambda x: x.value ) assert msg == b'{"a":1,"b":2}' def enc_hook(x): raise TypeError("Oh no!") with pytest.raises(TypeError): msgspec.json.encode({Custom("x"): 1}, enc_hook=enc_hook) with pytest.raises(RecursionError): msgspec.json.encode({Custom("x"): 1}, enc_hook=lambda x: x) def test_decode_dict_custom_key(self): class Custom: def __init__(self, value): self.value = value def __hash__(self): return hash(self.value) def __eq__(self, other): return self.value == other.value def dec_hook(typ, obj): if typ == Custom: return Custom(obj) raise NotImplementedError msg = b'{"a":1,"b":2}' obj = msgspec.json.decode(msg, type=Dict[Custom, int], dec_hook=dec_hook) assert obj == {Custom("a"): 1, Custom("b"): 2} @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"a"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 2}', "expected ':'"), (b'{"a": 1, "b": 2 "c"}', r"expected ',' or '}'"), ], ) @pytest.mark.parametrize("type", [dict, Any]) def test_decode_dict_malformed(self, s, error, type): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=type) def test_encode_dict_order_escape(self): msg = {"test\nkey": 1, "another\t\rkey": 2} res = msgspec.json.encode(msg, order="deterministic") sol = b'{"another\\t\\rkey":2,"test\\nkey":1}' assert res == sol class TestTypedDict: """Most tests are in `test_common`, this just tests some JSON peculiarities""" @pytest.mark.parametrize( "s, x", [ (b"{\t\n\r }", {}), (b'{\t\n\r "a" : 1}', {"a": 1}), (b'{ "a"\t : 1 \n, "b": \r 2 }', {"a": 1, "b": 2}), (b' { "a"\t : 1 \n, "b": \r 2 } ', {"a": 1, "b": 2}), ], ) def test_decode_typeddict_ignores_whitespace(self, s, x): class Test(TypedDict, total=False): a: int b: int x2 = msgspec.json.decode(s, type=Test) assert x == x2 @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"a"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 2}', "expected ':'"), (b'{"a": 1, "b": 2 "c"}', r"expected ',' or '}'"), ], ) def test_decode_typeddict_malformed(self, s, error): class Test(TypedDict, total=False): a: int b: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test) class TestDataclass: """Most tests are in `test_common`, this just tests some JSON peculiarities""" @pytest.mark.parametrize( "s, x", [ (b"{\t\n\r }", {}), (b'{\t\n\r "a" : 1}', {"a": 1}), (b'{ "a"\t : 1 \n, "b": \r 2 }', {"a": 1, "b": 2}), (b' { "a"\t : 1 \n, "b": \r 2 } ', {"a": 1, "b": 2}), ], ) def test_decode_dataclass_ignores_whitespace(self, s, x): @dataclass class Test: a: int = -1 b: int = -2 x2 = msgspec.json.decode(s, type=Test) assert x2 == Test(**x) @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"a"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 2}', "expected ':'"), (b'{"a": 1, "b": 2 "c"}', r"expected ',' or '}'"), ], ) def test_decode_typeddict_malformed(self, s, error): @dataclass class Test: a: int b: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test) class TestStruct: @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag): pass s = msgspec.json.encode(Test()) if tag: expected = msgspec.json.encode({"type": tag}) assert s == expected else: assert s == b"{}" @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_one_field_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int s = msgspec.json.encode(Test(a=1)) if tag: expected = msgspec.json.encode({"type": tag, "a": 1}) assert s == expected else: assert s == b'{"a":1}' @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_two_field_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int b: str s = msgspec.json.encode(Test(a=1, b="two")) if tag: expected = msgspec.json.encode({"type": tag, "a": 1, "b": "two"}) assert s == expected else: assert s == b'{"a":1,"b":"two"}' def test_decode_struct(self): dec = msgspec.json.Decoder(Person) msg = b'{"first": "harry", "last": "potter", "age": 13, "prefect": false}' x = dec.decode(msg) assert x == Person("harry", "potter", 13, False) # one for struct, one for output of getattr, and one for getrefcount assert sys.getrefcount(x.first) == 3 with pytest.raises( msgspec.ValidationError, match="Expected `object`, got `int`" ): dec.decode(b"1") def test_decode_struct_field_wrong_type(self): dec = msgspec.json.Decoder(Person) msg = b'{"first": "harry", "last": "potter", "age": "bad"}' with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$.age`" ): dec.decode(msg) def test_decode_struct_missing_fields(self): bad = b'{"first": "harry", "last": "potter"}' with pytest.raises( msgspec.ValidationError, match="Object missing required field `age`" ): msgspec.json.decode(bad, type=Person) bad = b"{}" with pytest.raises( msgspec.ValidationError, match="Object missing required field `first`" ): msgspec.json.decode(bad, type=Person) bad = b'[{"first": "harry", "last": "potter"}]' with pytest.raises( msgspec.ValidationError, match=r"Object missing required field `age` - at `\$\[0\]`", ): msgspec.json.decode(bad, type=List[Person]) def test_decode_struct_fields_mixed_order(self): class Test(msgspec.Struct): a: int b: int c: int d: int sol = Test(0, 1, 2, 3) dec = msgspec.json.Decoder(Test) pairs = list(zip("abcdef", range(6))) for data in itertools.permutations(pairs): msg = msgspec.json.encode(dict(data)) res = dec.decode(msg) assert res == sol @pytest.mark.parametrize( "extra", [ None, False, True, 1, 2.0, "three", [1, 2], {"a": 1}, ], ) def test_decode_struct_ignore_extra_fields(self, extra): dec = msgspec.json.Decoder(Person) a = msgspec.json.encode( { "extra1": extra, "first": "harry", "extra2": extra, "last": "potter", "age": 13, "extra3": extra, } ) res = dec.decode(a) assert res == Person("harry", "potter", 13) def test_decode_struct_defaults_missing_fields(self): dec = msgspec.json.Decoder(Person) a = b'{"first": "harry", "last": "potter", "age": 13}' res = dec.decode(a) assert res == Person("harry", "potter", 13) assert res.prefect is False @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"first"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"age": 13, }', "trailing comma in object"), (b'{"age": 13, "first" "harry"}', "expected ':'"), (b'{"age": 13, "first": "harry" "c"}', r"expected ',' or '}'"), ], ) def test_decode_struct_malformed(self, s, error): with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Person) @pytest.mark.parametrize("array_like", [False, True]) def test_struct_gc_maybe_untracked_on_decode(self, array_like): class Test(msgspec.Struct, array_like=array_like): x: Any y: Any z: Tuple = () enc = msgspec.json.Encoder() dec = msgspec.json.Decoder(List[Test]) ts = [ Test(1, 2), Test(3, "hello"), Test([], []), Test({}, {}), Test(None, None, ()), ] a, b, c, d, e = dec.decode(enc.encode(ts)) assert not gc.is_tracked(a) assert not gc.is_tracked(b) assert gc.is_tracked(c) assert gc.is_tracked(d) assert not gc.is_tracked(e) @pytest.mark.parametrize("array_like", [False, True]) def test_struct_gc_false_always_untracked_on_decode(self, array_like): class Test(msgspec.Struct, array_like=array_like, gc=False): x: Any y: Any dec = msgspec.json.Decoder(List[Test]) ts = [ Test(1, 2), Test([], []), Test({}, {}), ] for obj in dec.decode(msgspec.json.encode(ts)): assert not gc.is_tracked(obj) def test_struct_recursive_definition(self): enc = msgspec.json.Encoder() dec = msgspec.json.Decoder(Node) x = Node(Node(Node(), Node(Node()))) s = enc.encode(x) res = dec.decode(s) assert res == x @pytest.mark.parametrize("tag", ["Test", 0, 2**63 - 1, -(2**63)]) def test_decode_tagged_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int b: int dec = msgspec.json.Decoder(Test) # Test decode with and without tag for msg in [ {"a": 1, "b": 2}, {"type": tag, "a": 1, "b": 2}, {"a": 1, "type": tag, "b": 2}, ]: res = dec.decode(msgspec.json.encode(msg)) assert res == Test(1, 2) # Tag incorrect type for bad in [False, 123.456]: with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode({"type": bad})) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$.type`" in str(rec.value) # Tag incorrect value bad = -3 if isinstance(tag, int) else "bad" with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode({"type": bad})) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123, -123]) def test_decode_tagged_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag): pass dec = msgspec.json.Decoder(Test) # Tag missing res = dec.decode(msgspec.json.encode({})) assert res == Test() # Tag present res = dec.decode(msgspec.json.encode({"type": tag})) assert res == Test() @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"type"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"type": "Test1", }', "trailing comma in object"), (b'{"type": "Test1", "a" 1}', "expected ':'"), (b'{"type": "Test1", "a": 1 "b"}', r"expected ',' or '}'"), (b'{"type": nulp}', r"invalid character"), (b'{"type": "nulp}', r"truncated"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 1}', "expected ':'"), (b'{"a": 1 "b"}', r"expected ',' or '}'"), ], ) def test_decode_struct_tag_malformed(self, s, error): class Test1(msgspec.Struct, tag=True): a: int b: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test1) @pytest.mark.parametrize("ndigits", range(19)) @pytest.mark.parametrize("negative", [False, True]) def test_decode_tagged_struct_int_tag(self, ndigits, negative): if ndigits == 0: s = b"0" else: s = "".join( itertools.islice(itertools.cycle("123456789"), ndigits) ).encode() tag = int(s) if negative: tag = -tag class Test(msgspec.Struct, tag=tag): x: int t = Test(1) msg = msgspec.json.encode(t) assert msgspec.json.decode(msg, type=Test) == t def test_decode_tagged_struct_int_tag_uint64_always_invalid(self): """Uint64 values aren't currently valid tag values, but we still want to raise a good error message.""" class Test(msgspec.Struct, tag=123): pass with pytest.raises(msgspec.ValidationError) as rec: msgspec.json.decode(msgspec.json.encode({"type": 2**64 - 1}), type=Test) assert f"Invalid value {2**64 - 1}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize( "s, error", [ (b'{"type": 00}', "invalid number"), (b'{"type": -n123}', "invalid character"), (b'{"type": 123n}', "expected ',' or '}'"), (b'{"type": 123.}', "invalid number"), (b'{"type": 123.n}', "invalid number"), (b'{"type": 123e}', "invalid number"), (b'{"type": 123en}', "invalid number"), (b'{"type": 123, }', "trailing comma in object"), (b'{"type": 123, "a" 1}', "expected ':'"), (b'{"type": 123, "a": 1 "b"}', "expected ',' or '}'"), (b'{"type": nulp}', "invalid character"), (b'{"type": "bad}', "truncated"), (b'{"type": bad}', "invalid character"), ], ) def test_decode_struct_int_tag_malformed(self, s, error): class Test1(msgspec.Struct, tag=123): a: int b: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Test1) class TestStructUnion: """Most functionality is tested in `test_common.py:TestStructUnion`, this only checks for malformed inputs and whitespace handling""" @pytest.mark.parametrize( "s, error", [ (b"{", "truncated"), (b'{"type"', "truncated"), (b"{,}", "object keys must be strings"), (b"{:}", "object keys must be strings"), (b"{1: 2}", "object keys must be strings"), (b'{"type": "Test1", }', "trailing comma in object"), (b'{"type": "Test1", "a" 1}', "expected ':'"), (b'{"type": "Test1", "a": 1 "b"}', r"expected ',' or '}'"), (b'{"type": nulp}', r"invalid character"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 1}', "expected ':'"), (b'{"a": 1 "b"}', r"expected ',' or '}'"), ], ) def test_decode_struct_union_malformed(self, s, error): class Test1(msgspec.Struct, tag=True): a: int b: int class Test2(msgspec.Struct, tag=True): pass with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Union[Test1, Test2]) @pytest.mark.parametrize( "s, error", [ (b'{"type": 00}', "invalid number"), (b'{"type": -n123}', "invalid character"), (b'{"type": 123n}', "expected ',' or '}'"), (b'{"type": 123.}', "invalid number"), (b'{"type": 123.n}', "invalid number"), (b'{"type": 123e}', "invalid number"), (b'{"type": 123en}', "invalid number"), (b'{"type": 123, }', "trailing comma in object"), (b'{"type": 123, "a" 1}', "expected ':'"), (b'{"type": 123, "a": 1 "b"}', "expected ',' or '}'"), (b'{"type": nulp}', "invalid character"), (b'{"type": "bad}', "truncated"), (b'{"type": bad}', "invalid character"), ], ) def test_decode_struct_union_int_tag_malformed(self, s, error): class Test1(msgspec.Struct, tag=-123): a: int b: int class Test2(msgspec.Struct, tag=123): pass with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Union[Test1, Test2]) @pytest.mark.parametrize( "s", [ b' { "type" : "Test1" , "a" : 1 , "b" : 2 } ', b' { "a" : 1 , "type" : "Test1" , "b" : 2 } ', b' { "a" : 1 , "b" : 2 , "type" : "Test1" } ', ], ) def test_decode_struct_union_ignores_whitespace(self, s): class Test1(msgspec.Struct, tag=True): a: int b: int class Test2(msgspec.Struct, tag=True): pass res = msgspec.json.decode(s, type=Union[Test1, Test2]) assert res == Test1(1, 2) @pytest.mark.parametrize( "s", [ b' { "type" : -123 , "a" : 1 , "b" : 2 } ', b' { "a" : 1 , "type" : -123 , "b" : 2 } ', b' { "a" : 1 , "b" : 2 , "type" : -123 } ', ], ) def test_decode_struct_union_int_tag_ignores_whitespace(self, s): class Test1(msgspec.Struct, tag=-123): a: int b: int class Test2(msgspec.Struct, tag=123): pass res = msgspec.json.decode(s, type=Union[Test1, Test2]) assert res == Test1(1, 2) class TestStructArray: @pytest.mark.parametrize("tag", [False, True]) def test_encode_empty_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): pass s = msgspec.json.encode(Test()) if tag: assert s == b'["Test"]' else: assert s == b"[]" @pytest.mark.parametrize("tag", [False, True]) def test_encode_one_field_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): a: int s = msgspec.json.encode(Test(a=1)) if tag: assert s == b'["Test",1]' else: assert s == b"[1]" @pytest.mark.parametrize("tag", [False, True]) def test_encode_two_field_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): a: int b: str s = msgspec.json.encode(Test(a=1, b="two")) if tag: assert s == b'["Test",1,"two"]' else: assert s == b'[1,"two"]' def test_struct_array_like(self): dec = msgspec.json.Decoder(PersonArray) x = PersonArray(first="harry", last="potter", age=13) a = msgspec.json.encode(x) assert msgspec.json.encode(("harry", "potter", 13, False)) == a assert dec.decode(a) == x with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `int`" ): dec.decode(b"1") # Wrong field type bad = msgspec.json.encode(("harry", "potter", "thirteen")) with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`" ): dec.decode(bad) # Missing fields bad = msgspec.json.encode(("harry", "potter")) with pytest.raises( msgspec.ValidationError, match="Expected `array` of at least length 3, got 2", ): dec.decode(bad) bad = msgspec.json.encode(()) with pytest.raises( msgspec.ValidationError, match="Expected `array` of at least length 3, got 0", ): dec.decode(bad) # Extra fields ignored dec2 = msgspec.json.Decoder(List[PersonArray]) msg = msgspec.json.encode( [ ("harry", "potter", 13, False, 1, 2, 3, 4), ("ron", "weasley", 13, False, 5, 6), ] ) res = dec2.decode(msg) assert res == [ PersonArray("harry", "potter", 13), PersonArray("ron", "weasley", 13), ] # Defaults applied res = dec.decode(msgspec.json.encode(("harry", "potter", 13))) assert res == PersonArray("harry", "potter", 13) assert res.prefect is False def test_struct_map_and_array_like_messages_cant_mix(self): array_msg = msgspec.json.encode(("harry", "potter", 13)) map_msg = msgspec.json.encode({"first": "harry", "last": "potter", "age": 13}) sol = Person("harry", "potter", 13) array_sol = PersonArray("harry", "potter", 13) dec = msgspec.json.Decoder(Person) array_dec = msgspec.json.Decoder(PersonArray) assert array_dec.decode(array_msg) == array_sol assert dec.decode(map_msg) == sol with pytest.raises( msgspec.ValidationError, match="Expected `object`, got `array`" ): dec.decode(array_msg) with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `object`" ): array_dec.decode(map_msg) @pytest.mark.parametrize( "s, error", [ (b"[", "truncated"), (b"[1", "truncated"), (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[1, ]", "trailing comma in array"), (b"[1, 2 3]", r"expected ',' or ']'"), ], ) def test_decode_struct_array_like_malformed(self, s, error): class Point(msgspec.Struct, array_like=True): x: int y: int z: int with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Point) @pytest.mark.parametrize("tag", ["Test", 123]) def test_decode_tagged_struct(self, tag): class Test(msgspec.Struct, tag=tag, array_like=True): a: int b: int c: int = 0 dec = msgspec.json.Decoder(Test) # Decode with tag res = dec.decode(msgspec.json.encode([tag, 1, 2])) assert res == Test(1, 2) res = dec.decode(msgspec.json.encode([tag, 1, 2, 3])) assert res == Test(1, 2, 3) # Trailing fields ignored res = dec.decode(msgspec.json.encode([tag, 1, 2, 3, 4])) assert res == Test(1, 2, 3) # Missing required field errors with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([tag, 1])) assert "Expected `array` of at least length 3, got 2" in str(rec.value) # Tag missing with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([])) assert "Expected `array` of at least length 3, got 0" in str(rec.value) # Tag incorrect type with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([123.456, 2, 3])) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$[0]`" in str(rec.value) # Tag incorrect value bad = 0 if isinstance(tag, int) else "bad" with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([bad, 1, 2])) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$[0]`" in str(rec.value) # Field incorrect type correct index with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([tag, "a", 2])) assert "Expected `int`, got `str`" in str(rec.value) assert "`$[1]`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123]) def test_decode_tagged_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag, array_like=True): pass dec = msgspec.json.Decoder(Test) # Decode with tag res = dec.decode(msgspec.json.encode([tag, 1, 2])) assert res == Test() # Tag missing with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.json.encode([])) assert "Expected `array` of at least length 1, got 0" in str(rec.value) class TestStructArrayUnion: """Most functionality is tested in `test_common.py:TestStructUnion`, this only checks for malformed inputs and whitespace handling""" @pytest.mark.parametrize( "s, error", [ (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[nulp]", "invalid character"), (b'["Test1", nulp]', "invalid character"), (b"[", "truncated"), (b'["Test1', "truncated"), (b'["Test1"', "truncated"), (b'["Test1",', "truncated"), (b'["Test1]', "truncated"), (b'["Test1", ]', "trailing comma in array"), (b'["Test1" g', r"expected ',' or ']'"), (b'["Test1", 1 g', r"expected ',' or ']'"), (b'["Test1", 2 3]', r"expected ',' or ']'"), ], ) def test_decode_struct_array_like_union_malformed(self, s, error): class Test1(msgspec.Struct, tag=True, array_like=True): x: int y: int z: int class Test2(msgspec.Struct, tag=True, array_like=True): pass with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Union[Test1, Test2]) @pytest.mark.parametrize( "s, error", [ (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[nulp]", "invalid character"), (b"[123, nulp]", "invalid character"), (b"[", "truncated"), (b"[123.n,", "invalid number"), (b"[123en,", "invalid number"), (b"[123", "truncated"), (b"[123,", "truncated"), (b"[123, ]", "trailing comma in array"), (b"[123 g", r"expected ',' or ']'"), (b"[123, 1 g", r"expected ',' or ']'"), ], ) def test_decode_struct_array_like_union_int_tag_malformed(self, s, error): class Test1(msgspec.Struct, tag=123, array_like=True): x: int y: int z: int class Test2(msgspec.Struct, tag=-123, array_like=True): pass with pytest.raises(msgspec.DecodeError, match=error): msgspec.json.decode(s, type=Union[Test1, Test2]) def test_decode_struct_array_union_ignores_whitespace(self): s = b' [ "Test1" , 1 , 2 ] ' class Test1(msgspec.Struct, tag=True, array_like=True): a: int b: int class Test2(msgspec.Struct, tag=True, array_like=True): pass res = msgspec.json.decode(s, type=Union[Test1, Test2]) assert res == Test1(1, 2) def test_decode_struct_array_union_int_tag_ignores_whitespace(self): s = b" [ 123 , 1 , 2 ] " class Test1(msgspec.Struct, tag=123, array_like=True): a: int b: int class Test2(msgspec.Struct, tag=-123, array_like=True): pass res = msgspec.json.decode(s, type=Union[Test1, Test2]) assert res == Test1(1, 2) class TestRaw: def test_encode_raw(self): b = b'{"x":1}' r = msgspec.Raw(b) assert msgspec.json.encode(r) == b assert msgspec.json.encode({"y": r}) == b'{"y":{"x":1}}' def test_decode_raw_field(self): class Test(msgspec.Struct): x: int y: msgspec.Raw s = b'{"x": 1, "y": [1, 2, 3] }' res = msgspec.json.decode(s, type=Test) assert res.x == 1 assert bytes(res.y) == b"[1, 2, 3]" def test_decode_raw_optional_field(self): default = msgspec.Raw() class Test(msgspec.Struct): x: int y: msgspec.Raw = default s = b'{"x": 1, "y": [1, 2, 3] }' res = msgspec.json.decode(s, type=Test) assert res.x == 1 assert bytes(res.y) == b"[1, 2, 3]" s = b'{"x": 1}' res = msgspec.json.decode(s, type=Test) assert res.x == 1 assert res.y is default def test_decode_raw_malformed_data(self): class Test(msgspec.Struct): x: int y: msgspec.Raw s = b'{"x": 1, "y": [1, 2,]}' with pytest.raises(msgspec.DecodeError, match="malformed"): msgspec.json.decode(s, type=Test) def test_decode_raw_is_view(self): s = b' {"x": 1} ' r = msgspec.json.decode(s, type=msgspec.Raw) assert bytes(r) == b'{"x": 1}' assert r.copy() is not r # actual copy indicates a view @pytest.mark.parametrize("wrap", [False, True]) def test_decode_raw_from_str(self, wrap): msg = '[{"x": 1}]' if wrap else '{"x": 1}' c = sys.getrefcount(msg) if wrap: [r] = msgspec.json.decode(msg, type=List[msgspec.Raw]) else: r = msgspec.json.decode(msg, type=msgspec.Raw) assert bytes(r) == b'{"x": 1}' # Raw holds a ref to the original str assert sys.getrefcount(msg) == c + 1 del r assert sys.getrefcount(msg) == c def test_raw_in_union_works_but_doesnt_change_anything(self): class Test(msgspec.Struct): x: Union[int, str, msgspec.Raw] r = msgspec.json.decode(b'{"x": 1}', type=Test) assert r == Test(1) def test_raw_can_be_mixed_with_custom_type(self): class Test(msgspec.Struct): x: Union[Custom, msgspec.Raw] def dec_hook(typ, obj): assert typ is Custom return typ(*obj) res = msgspec.json.decode(b'{"x": [1, 2]}', type=Test, dec_hook=dec_hook) assert res == Test(Custom(1, 2)) class TestFormat: @pytest.mark.parametrize( "msg", [ b"null", b"false", b"true", b" true \n", b"1", b" \n1\t\r", b"1.5", b'"abc"', b' \t"abc" \n\t', b"[]", b"[ \t ]", b"[1]", b"[1, 2]", b"{}", b"{ }", b'{"a": 1}', b'{"a": 1, "b": 2}', b'{"a": {"x": 1, "y": [1, false]}, "b": ["foo", []]}', b'\n{ "a" : \t[ 1, \t\n\r 2]\n} ', ], ) @pytest.mark.parametrize("indent", [-1, 0, 2, 4]) def test_format(self, msg, indent): if indent > 0: kwargs = {"separators": None, "indent": indent} elif indent == 0: kwargs = {"separators": None, "indent": None} elif indent < 0: kwargs = {"separators": (",", ":"), "indent": None} sol = json.dumps(json.loads(msg), **kwargs).encode() res = msgspec.json.format(msg, indent=indent) assert res == sol def test_format_str(self): assert msgspec.json.format("[1, 2]", indent=0) == "[1, 2]" def test_format_bad_calls(self): with pytest.raises(TypeError): msgspec.json.format(1) with pytest.raises(TypeError): msgspec.json.format(b"[]", indent=None) with pytest.raises(TypeError): msgspec.json.format(b"[]", 2) with pytest.raises(TypeError): msgspec.json.format(b"[]", bad=2) @pytest.mark.parametrize( "msg, err", [ (b"nulx", "invalid character"), (b"trux", "invalid character"), (b"falsx", "invalid character"), (b"x1", "invalid character"), (b"1.", "invalid number"), (b"1x", "trailing characters"), (b'"abc', "truncated"), (b'"\\u00cz 123"', "invalid character in unicode escape"), (b"[", "truncated"), (b"[1", "truncated"), (b"[,]", "invalid character"), (b"[, 1]", "invalid character"), (b"[1, ]", "trailing comma in array"), (b"[1, 2 3]", r"expected ',' or ']'"), (b"{", "truncated"), (b'{"a"', "truncated"), (b"{,}", "expected '\"'"), (b"{:}", "expected '\"'"), (b"{1: 2}", "expected '\"'"), (b'{"a": 1, }', "trailing comma in object"), (b'{"a": 1, "b" 2}', "expected ':'"), (b'{"a": 1, "b": 2 "c"}', r"expected ',' or '}'"), ], ) def test_format_malformed(self, msg, err): with pytest.raises(msgspec.DecodeError, match=err): msgspec.json.format(msg) python-msgspec-0.19.0/tests/test_msgpack.py000066400000000000000000001755541473355726200210200ustar00rootroot00000000000000from __future__ import annotations import datetime import enum import gc import itertools import math import pickle import struct import sys from typing import ( Any, Dict, FrozenSet, List, Literal, Optional, Set, Tuple, Union, ) import pytest import msgspec UTC = datetime.timezone.utc class FruitInt(enum.IntEnum): APPLE = 1 BANANA = 2 class FruitStr(enum.Enum): APPLE = "apple" BANANA = "banana" class Person(msgspec.Struct): first: str last: str age: int prefect: bool = False class PersonArray(msgspec.Struct, array_like=True): first: str last: str age: int prefect: bool = False PERSON = Person("harry", "potter", 13) PERSON_AA = PersonArray("harry", "potter", 13) class Node(msgspec.Struct): left: Optional[Node] = None right: Optional[Node] = None class Custom: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, other): return self.x == other.x and self.y == other.y INTS = [ -(2**63), -(2**31 + 1), -(2**31), -(2**15 + 1), -(2**15), -(2**7 + 1), -(2**7), -(2**5 + 1), -(2**5), -1, 0, 1, 2**7 - 1, 2**7, 2**8 - 1, 2**8, 2**16 - 1, 2**16, 2**32 - 1, 2**32, 2**63 - 1, 2**64 - 1, ] FLOATS = [ -1.5, 0.0, 1.5, -float("inf"), float("inf"), float("nan"), sys.float_info.max, sys.float_info.min, -sys.float_info.max, -sys.float_info.min, ] SIZES = [0, 1, 31, 32, 2**8 - 1, 2**8, 2**16 - 1, 2**16] def assert_eq(x, y): if isinstance(x, float) and math.isnan(x): assert math.isnan(y) else: assert x == y class TestEncodeFunction: def test_encode(self): dec = msgspec.msgpack.Decoder() assert dec.decode(msgspec.msgpack.encode(1)) == 1 def test_encode_bad_arguments(self): with pytest.raises(TypeError, match="Missing 1 required arguments"): msgspec.msgpack.encode() with pytest.raises(TypeError, match="Extra positional"): msgspec.msgpack.encode(1, 2) with pytest.raises(TypeError, match="enc_hook must be callable"): msgspec.msgpack.encode(1, enc_hook="bad") def test_encode_error(self): with pytest.raises(TypeError): msgspec.msgpack.encode(object()) def test_encode_large_object(self): """Check that buffer resize works""" data = b"x" * 4097 dec = msgspec.msgpack.Decoder() assert dec.decode(msgspec.msgpack.encode(data)) == data def test_encode_no_enc_hook(self): class Foo: pass with pytest.raises( TypeError, match="Encoding objects of type Foo is unsupported" ): msgspec.msgpack.encode(Foo()) with pytest.raises( TypeError, match="Encoding objects of type Foo is unsupported" ): msgspec.msgpack.encode(Foo(), enc_hook=None) def test_encode_enc_hook(self): unsupported = object() def enc_hook(x): assert x is unsupported return "hello" orig_refcount = sys.getrefcount(enc_hook) res = msgspec.msgpack.encode(unsupported, enc_hook=enc_hook) assert msgspec.msgpack.encode("hello") == res assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_enc_hook_errors(self): def enc_hook(x): raise TypeError("bad") orig_refcount = sys.getrefcount(enc_hook) with pytest.raises(TypeError, match="bad"): msgspec.msgpack.encode(object(), enc_hook=enc_hook) assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_parse_arguments_errors(self): with pytest.raises(TypeError, match="Missing 1 required argument"): msgspec.msgpack.encode() with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.msgpack.encode(1, lambda x: None) with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.msgpack.encode(1, 2, 3) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.msgpack.encode(1, bad=1) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.msgpack.encode(1, enc_hook=lambda x: None, extra="extra") class TestDecodeFunction: def setup_method(self): self.buf = msgspec.msgpack.encode([1, 2, 3]) def test_decode(self): assert msgspec.msgpack.decode(self.buf) == [1, 2, 3] def test_decode_type_keyword(self): assert msgspec.msgpack.decode(self.buf, type=List[int]) == [1, 2, 3] with pytest.raises(msgspec.ValidationError): assert msgspec.msgpack.decode(self.buf, type=List[str]) def test_decode_type_any(self): assert msgspec.msgpack.decode(self.buf, type=Any) == [1, 2, 3] @pytest.mark.parametrize("array_like", [False, True]) def test_decode_type_struct(self, array_like): class Point(msgspec.Struct, array_like=array_like): x: int y: int msg = msgspec.msgpack.encode(Point(1, 2)) for _ in range(2): assert msgspec.msgpack.decode(msg, type=Point) == Point(1, 2) def test_decode_type_struct_not_json_compatible(self): class Test(msgspec.Struct): x: Dict[int, str] msg = msgspec.msgpack.encode(Test({1: "two"})) msgspec.msgpack.decode(msg, type=Test) == Test({1, "two"}) def test_decode_type_struct_invalid_type(self): class Test(msgspec.Struct): x: 1 with pytest.raises(TypeError): msgspec.msgpack.decode(b"{}", type=Test) def test_decode_invalid_type(self): with pytest.raises(TypeError, match="Type '1' is not supported"): msgspec.msgpack.decode(self.buf, type=1) def test_decode_invalid_buf(self): with pytest.raises(TypeError): msgspec.msgpack.decode(1) def test_decode_parse_arguments_errors(self): with pytest.raises(TypeError, match="Missing 1 required argument"): msgspec.msgpack.decode() with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.msgpack.decode(self.buf, List[int]) with pytest.raises(TypeError, match="Extra positional arguments"): msgspec.msgpack.decode(self.buf, 2, 3) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.msgpack.decode(self.buf, bad=1) with pytest.raises(TypeError, match="Extra keyword arguments"): msgspec.msgpack.decode(self.buf, type=List[int], extra=1) def test_decode_with_trailing_characters_errors(self): msg = msgspec.msgpack.encode([1, 2, 3]) + b"trailing" with pytest.raises(msgspec.DecodeError): msgspec.msgpack.decode(msg) class TestEncoderMisc: def test_encoder_init_errors(self): with pytest.raises(TypeError): msgspec.msgpack.Encoder(bad=1) with pytest.raises(TypeError, match="enc_hook must be callable"): msgspec.msgpack.Encoder(enc_hook=1) @pytest.mark.parametrize("x", [-(2**63) - 1, 2**64]) def test_encode_integer_limits(self, x): enc = msgspec.msgpack.Encoder() with pytest.raises(OverflowError): enc.encode(x) def rec_obj1(self): o = [] o.append(o) return o def rec_obj2(self): o = ([],) o[0].append(o) return o def rec_obj3(self): o = {} o["a"] = o return o def rec_obj4(self): class Box(msgspec.Struct): a: "Box" o = Box(None) o.a = o return o @pytest.mark.parametrize("case", [1, 2, 3, 4]) def test_encode_infinite_recursive_object_errors(self, case): enc = msgspec.msgpack.Encoder() o = getattr(self, "rec_obj%d" % case)() with pytest.raises(RecursionError): enc.encode(o) def test_encode_no_enc_hook(self): class Foo: pass enc = msgspec.msgpack.Encoder() assert enc.enc_hook is None enc = msgspec.msgpack.Encoder(enc_hook=None) assert enc.enc_hook is None with pytest.raises( TypeError, match="Encoding objects of type Foo is unsupported" ): enc.encode(Foo()) def test_encode_enc_hook(self): unsupported = object() def enc_hook(x): assert x is unsupported return "hello" orig_refcount = sys.getrefcount(enc_hook) enc = msgspec.msgpack.Encoder(enc_hook=enc_hook) assert enc.enc_hook is enc_hook assert sys.getrefcount(enc.enc_hook) == orig_refcount + 2 assert sys.getrefcount(enc_hook) == orig_refcount + 1 res = enc.encode(unsupported) assert enc.encode("hello") == res del enc assert sys.getrefcount(enc_hook) == orig_refcount def test_encode_enc_hook_errors(self): def enc_hook(x): raise TypeError("bad") enc = msgspec.msgpack.Encoder(enc_hook=enc_hook) with pytest.raises(TypeError, match="bad"): enc.encode(object()) def test_encode_enc_hook_recurses(self): class Node: def __init__(self, a): self.a = a def enc_hook(x): return {"type": "Node", "a": x.a} enc = msgspec.msgpack.Encoder(enc_hook=enc_hook) msg = enc.encode(Node(Node(1))) res = msgspec.msgpack.decode(msg) assert res == {"type": "Node", "a": {"type": "Node", "a": 1}} def test_encode_enc_hook_recursion_error(self): enc = msgspec.msgpack.Encoder(enc_hook=lambda x: x) with pytest.raises(RecursionError): enc.encode(object()) def test_encode_bad_arguments(self): enc = msgspec.msgpack.Encoder() with pytest.raises(TypeError, match="Missing 1 required arguments"): enc.encode() with pytest.raises(TypeError, match="Extra positional"): enc.encode(1, 2) def test_encode_into_bad_arguments(self): enc = msgspec.msgpack.Encoder() with pytest.raises(TypeError, match="bytearray"): enc.encode_into(1, b"test") with pytest.raises(TypeError): enc.encode_into(1, bytearray(), "bad") with pytest.raises(ValueError, match="offset"): enc.encode_into(1, bytearray(), -2) with pytest.raises(TypeError, match="Missing 1 required arguments"): enc.encode_into(1) with pytest.raises(TypeError, match="Extra positional"): enc.encode_into(1, bytearray(), 2, 3) @pytest.mark.parametrize("buf_size", [0, 1, 16, 55, 60]) def test_encode_into(self, buf_size): enc = msgspec.msgpack.Encoder() msg = {"key": "x" * 48} encoded = msgspec.msgpack.encode(msg) buf = bytearray(buf_size) out = enc.encode_into(msg, buf) assert out is None assert buf == encoded def test_encode_into_offset(self): enc = msgspec.msgpack.Encoder() msg = {"key": "value"} encoded = enc.encode(msg) # Offset 0 is default buf = bytearray() enc.encode_into(msg, buf, 0) assert buf == encoded # Offset in bounds uses the provided offset buf = bytearray(b"01234") enc.encode_into(msg, buf, 2) assert buf == b"01" + encoded # Offset out of bounds extends buf = bytearray(b"01234") enc.encode_into(msg, buf, 10) assert buf[:5] == b"01234" assert buf[10:] == encoded # Offset -1 means append at end buf = bytearray(b"01234") enc.encode_into(msg, buf, -1) assert buf == b"01234" + encoded def test_encode_into_handles_errors_properly(self): enc = msgspec.msgpack.Encoder() out1 = enc.encode([1, 2, 3]) msg = [1, 2, object()] buf = bytearray() with pytest.raises(TypeError): enc.encode_into(msg, buf) assert buf # buffer isn't reset upon error # Encoder still works out2 = enc.encode([1, 2, 3]) assert out1 == out2 @pytest.mark.parametrize( "dt, dt_str", [ (datetime.datetime(1, 2, 3, 4, 5, 6), "0001-02-03T04:05:06"), ( datetime.datetime(1234, 12, 31, 14, 56, 27, 123456), "1234-12-31T14:56:27.123456", ), ], ) def test_encode_datetime_naive(self, dt, dt_str): res = msgspec.msgpack.encode(dt) sol = msgspec.msgpack.encode(dt_str) assert res == sol def test_encode_datetime_non_utc_tzinfo(self): tzinfo = datetime.timezone(datetime.timedelta(hours=1)) x = datetime.datetime.now(tzinfo) x2 = x.astimezone(datetime.timezone.utc) res = msgspec.msgpack.encode(x) sol = msgspec.msgpack.encode(x2) assert res == sol class TestDecoderMisc: def test_decoder_type_attribute(self): dec = msgspec.msgpack.Decoder() assert dec.type is Any dec = msgspec.msgpack.Decoder(int) assert dec.type is int def test_decoder_ext_hook_attribute(self): def ext_hook(code, buf): pass dec = msgspec.msgpack.Decoder() assert dec.ext_hook is None dec = msgspec.msgpack.Decoder(ext_hook=None) assert dec.ext_hook is None dec = msgspec.msgpack.Decoder(ext_hook=ext_hook) assert dec.ext_hook is ext_hook def test_decoder_bad_args(self): with pytest.raises(TypeError): msgspec.msgpack.Decoder(bad=1) def test_decoder_ext_hook_not_callable(self): with pytest.raises(TypeError): msgspec.msgpack.Decoder(ext_hook=1) def test_decoder_repr(self): typ = List[Dict[int, float]] dec = msgspec.msgpack.Decoder(typ) assert repr(dec) == f"msgspec.msgpack.Decoder({typ!r})" dec = msgspec.msgpack.Decoder() assert repr(dec) == f"msgspec.msgpack.Decoder({Any!r})" def test_decode_with_trailing_characters_errors(self): dec = msgspec.msgpack.Decoder() msg = msgspec.msgpack.encode([1, 2, 3]) + b"trailing" with pytest.raises(msgspec.DecodeError): dec.decode(msg) def test_decode_invalid_opcode_error(self): with pytest.raises(msgspec.DecodeError, match="invalid opcode '\\\\xc1'"): msgspec.msgpack.decode(b"\xc1abc") def test_decode_skip_invalid_submessage_raises(self): """Ensure errors in submessage skipping are raised""" class Test(msgspec.Struct): x: int msg = msgspec.msgpack.encode({"x": 1, "y": ["one", "two", "three"]}) # Break the message msg = msg.replace(b"three", b"tree") with pytest.raises(msgspec.DecodeError, match="truncated"): msgspec.msgpack.decode(msg, type=Test) @pytest.mark.parametrize("length", [3, 31, 33]) @pytest.mark.parametrize("typed", [False, True]) def test_decode_dict_string_cache(self, length, typed): key = "x" * length msg = [{key: 1}, {key: 2}, {key: 3}] if typed: dec = msgspec.msgpack.Decoder(List[Dict[str, int]]) else: dec = msgspec.msgpack.Decoder() res = dec.decode(msgspec.msgpack.encode(msg)) assert msg == res ids = {id(k) for d in res for k in d.keys()} if length > 32: assert len(ids) == 3 else: assert len(ids) == 1 def test_decode_dict_string_cache_ascii_only(self): """Short non-ascii strings aren't cached""" s = "123 á 456" msg = [{s: 1}, {s: 2}, {s: 3}] res = msgspec.msgpack.decode(msgspec.msgpack.encode(msg)) ids = {id(k) for d in res for k in d.keys()} assert len(ids) == 3 @pytest.mark.parametrize("type", [None, list, tuple, set]) def test_decoding_large_arrays_doesnt_preallocate(self, type): # b = b"\xdd\xff\xff\xff\xff" with pytest.raises(msgspec.DecodeError, match="truncated"): if type is None: msgspec.msgpack.decode(b) else: msgspec.msgpack.decode(b, type=type) def test_decoding_large_arrays_as_keys_doesnt_preallocate(self): # {"x": } b = b"\x81\xa1x\xdd\xff\xff\xff\xff" with pytest.raises(msgspec.DecodeError, match="truncated"): msgspec.msgpack.decode(b) class TestTypedDecoder: def check_unexpected_type(self, dec_type, val, msg): dec = msgspec.msgpack.Decoder(dec_type) s = msgspec.msgpack.Encoder().encode(val) with pytest.raises(msgspec.ValidationError, match=msg): dec.decode(s) def test_any(self): dec = msgspec.msgpack.Decoder(Any) assert dec.decode(msgspec.msgpack.encode([1, 2, 3])) == [1, 2, 3] # A union that includes `Any` is just `Any` dec = msgspec.msgpack.Decoder(Union[Any, float, int, None]) assert dec.decode(msgspec.msgpack.encode([1, 2, 3])) == [1, 2, 3] def test_none(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(None) assert dec.decode(enc.encode(None)) is None with pytest.raises(msgspec.ValidationError, match="Expected `null`"): assert dec.decode(enc.encode(1)) @pytest.mark.parametrize("x", [False, True]) def test_bool(self, x): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(bool) assert dec.decode(enc.encode(x)) is x def test_bool_unexpected_type(self): self.check_unexpected_type(bool, "a", "Expected `bool`") @pytest.mark.parametrize("x", INTS) def test_int(self, x): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(int) assert dec.decode(enc.encode(x)) == x def test_int_unexpected_type(self): self.check_unexpected_type(int, "a", "Expected `int`") @pytest.mark.parametrize("x", FLOATS + INTS) def test_float(self, x): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(float) res = dec.decode(enc.encode(x)) sol = float(x) if math.isnan(sol): assert math.isnan(res) else: assert res == sol def test_float_unexpected_type(self): self.check_unexpected_type(float, "a", "Expected `float`") def test_decode_float4(self): x = 1.2 packed = struct.pack(">f", x) # Loss of resolution in float32 leads to some rounding error x4 = struct.unpack(">f", packed)[0] msg = b"\xca" + packed assert msgspec.msgpack.decode(msg) == x4 assert msgspec.msgpack.decode(msg, type=float) == x4 @pytest.mark.parametrize("size", SIZES) def test_str(self, size): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(str) x = "a" * size res = dec.decode(enc.encode(x)) assert res == x def test_str_unexpected_type(self): self.check_unexpected_type(str, 1, "Expected `str`") @pytest.mark.parametrize("size", SIZES) @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_binary(self, size, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) sol = b"a" * size res = dec.decode(enc.encode(typ(sol))) assert isinstance(res, typ) assert bytes(res) == sol @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_binary_unexpected_type(self, typ): self.check_unexpected_type(typ, 1, "Expected `bytes`") @pytest.mark.parametrize("input_type", [bytes, bytearray, memoryview]) def test_decode_memoryview_zerocopy(self, input_type): msg = msgspec.msgpack.encode(b"abcde") ref = msg if input_type is memoryview else None msg = input_type(msg) res = msgspec.msgpack.decode(msg, type=memoryview) assert isinstance(res, memoryview) assert bytes(res) == b"abcde" if input_type is memoryview: assert sys.getrefcount(ref) == 3 del msg assert sys.getrefcount(ref) == 3 del res assert sys.getrefcount(ref) == 2 elif input_type is bytes: assert sys.getrefcount(msg) == 3 def test_datetime_aware_ext(self): dec = msgspec.msgpack.Decoder(datetime.datetime) x = datetime.datetime.now(UTC) res = dec.decode(msgspec.msgpack.encode(x)) assert x == res @pytest.mark.parametrize( "s", [ "1234-01-02T03:04:05Z", "1234-01-02T03:04:05.123Z", "1234-01-02T03:04:05.123+00:00", ], ) def test_decode_datetime_aware_str(self, s): sol = datetime.datetime.fromisoformat(s.replace("Z", "+00:00")) msg = msgspec.msgpack.encode(s) res = msgspec.msgpack.decode(msg, type=datetime.datetime) assert sol == res @pytest.mark.parametrize( "s", [ "1234-01-02T03:04:05", "1234-01-02T03:04:05.123", "1234-01-02T03:04:05.123456", ], ) def test_decode_datetime_naive(self, s): sol = datetime.datetime.fromisoformat(s) msg = msgspec.msgpack.encode(s) res = msgspec.msgpack.decode(msg, type=datetime.datetime) assert sol == res def test_datetime_unexpected_type(self): self.check_unexpected_type(datetime.datetime, 1, "Expected `datetime`") self.check_unexpected_type( datetime.datetime, msgspec.msgpack.Ext(1, b"test"), "Expected `datetime`" ) def test_datetime_invalid(self): msg = msgspec.msgpack.encode(msgspec.msgpack.Ext(-1, b"\x01\x02\x03")) with pytest.raises( msgspec.ValidationError, match="Invalid MessagePack timestamp" ): msgspec.msgpack.decode(msg, type=datetime.datetime) @pytest.mark.parametrize("size", SIZES) def test_list_lengths(self, size): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(list) x = list(range(size)) res = dec.decode(enc.encode(x)) assert res == x @pytest.mark.parametrize("typ", [list, List, List[Any]]) def test_list_any(self, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) x = [1, "two", b"three"] res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.ValidationError, match="Expected `array`"): dec.decode(enc.encode(1)) def test_list_typed(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(List[int]) x = [1, 2, 3] res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`", ): dec.decode(enc.encode([1, 2, "three"])) @pytest.mark.parametrize("size", SIZES) @pytest.mark.parametrize("typ", [set, frozenset]) def test_set_lengths(self, size, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) x = typ(range(size)) res = dec.decode(enc.encode(x)) assert res == x assert isinstance(res, typ) @pytest.mark.parametrize( "typ", [set, Set, Set[Any], frozenset, FrozenSet, FrozenSet[Any]] ) def test_set_any(self, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) real_type = getattr(typ, "__origin__", typ) x = {1, "two", b"three"} res = dec.decode(enc.encode(x)) assert res == x assert type(res) is real_type with pytest.raises(msgspec.ValidationError, match="Expected `array`"): dec.decode(enc.encode(1)) @pytest.mark.parametrize("typ", [Set, FrozenSet]) def test_set_typed(self, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ[int]) x = {1, 2, 3} res = dec.decode(enc.encode(x)) assert res == x assert type(res) is typ.__origin__ with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`", ): dec.decode(enc.encode([1, 2, "three"])) @pytest.mark.parametrize("size", SIZES) def test_vartuple_lengths(self, size): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(tuple) x = tuple(f"x{i}x" for i in range(size)) res = dec.decode(enc.encode(x)) assert res == x if res: assert sys.getrefcount(res[0]) == 3 # 1 tuple, 1 index, 1 func call @pytest.mark.parametrize("typ", [tuple, Tuple, Tuple[Any, ...]]) def test_vartuple_any(self, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) x = (1, "two", b"three") res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `int`" ): dec.decode(enc.encode(1)) def test_vartuple_typed(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Tuple[int, ...]) x = (1, 2, 3) res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`", ): dec.decode(enc.encode((1, 2, "three"))) def test_fixtuple_any(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Tuple[Any, Any, Any]) x = (1, "two", b"three") res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `int`" ): dec.decode(enc.encode(1)) with pytest.raises( msgspec.ValidationError, match="Expected `array` of length 3, got 2" ): dec.decode(enc.encode((1, 2))) def test_fixtuple_typed(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Tuple[int, str, bytes]) x = (1, "two", b"three") res = dec.decode(enc.encode(x)) assert res == x with pytest.raises(msgspec.ValidationError, match="Expected `bytes`"): dec.decode(enc.encode((1, "two", "three"))) with pytest.raises( msgspec.ValidationError, match="Expected `array` of length 3, got 2" ): dec.decode(enc.encode((1, 2))) @pytest.mark.parametrize("size", SIZES) def test_dict_lengths(self, size): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(dict) x = {i: i for i in range(size)} res = dec.decode(enc.encode(x)) assert res == x @pytest.mark.parametrize("typ", [dict, Dict, Dict[Any, Any]]) def test_dict_any_any(self, typ): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) x = {1: "one", "two": 2, b"three": 3.0} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `object`, got `int`" ): dec.decode(enc.encode(1)) def test_dict_any_val(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Dict[str, Any]) x = {"a": 1, "b": "two", "c": b"three"} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `str`, got `int` - at `key` in `\$`", ): dec.decode(enc.encode({1: 2})) def test_dict_any_key(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Dict[Any, str]) x = {1: "a", "two": "b", b"three": "c"} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `str`, got `int` - at `\$\[...\]`" ): dec.decode(enc.encode({1: 2})) def test_dict_str_subclass_key(self): class mystr(str): pass msg1 = msgspec.msgpack.encode({mystr("test"): 1}) msg2 = msgspec.msgpack.encode({"test": 1}) assert msg1 == msg2 def test_dict_typed(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Dict[str, int]) x = {"a": 1, "b": 2} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `str`, got `int` - at `key` in `\$`", ): dec.decode(enc.encode({1: 2})) with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[...\]`" ): dec.decode(enc.encode({"a": "two"})) def test_dict_typed_non_str_key(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Dict[int, int]) x = {0: 1, 2: 3} res = dec.decode(enc.encode(x)) assert res == x with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `key` in `\$`", ): dec.decode(enc.encode({"bad": 2})) def test_enum(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(FruitStr) a = enc.encode(FruitStr.APPLE) assert enc.encode("apple") == a assert dec.decode(a) == FruitStr.APPLE with pytest.raises(msgspec.DecodeError, match="truncated"): dec.decode(a[:-2]) with pytest.raises( msgspec.ValidationError, match="Invalid enum value 'MISSING'" ): dec.decode(enc.encode("MISSING")) with pytest.raises( msgspec.ValidationError, match=r"Invalid enum value 'MISSING' - at `\$\[0\]`", ): msgspec.msgpack.decode(enc.encode(["MISSING"]), type=List[FruitStr]) with pytest.raises(msgspec.ValidationError): dec.decode(enc.encode(1)) def test_int_enum(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(FruitInt) a = enc.encode(FruitInt.APPLE) assert enc.encode(1) == a assert dec.decode(a) == FruitInt.APPLE with pytest.raises(msgspec.DecodeError, match="truncated"): dec.decode(a[:-2]) with pytest.raises(msgspec.ValidationError, match="Invalid enum value 1000"): dec.decode(enc.encode(1000)) with pytest.raises( msgspec.ValidationError, match=r"Invalid enum value 1000 - at `\$\[0\]`" ): msgspec.msgpack.decode(enc.encode([1000]), type=List[FruitInt]) with pytest.raises(msgspec.ValidationError): dec.decode(enc.encode("INVALID")) def test_str_literal(self): literal = Literal["one", "two"] enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(literal) assert dec.decode(enc.encode("one")) == "one" with pytest.raises( msgspec.ValidationError, match="Invalid enum value 'MISSING'" ): dec.decode(enc.encode("MISSING")) with pytest.raises( msgspec.ValidationError, match=r"Invalid enum value 'MISSING' - at `\$\[0\]`", ): msgspec.msgpack.decode(enc.encode(["MISSING"]), type=List[literal]) def test_int_literal(self): literal = Literal[1, 2, 3] enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(literal) assert dec.decode(enc.encode(1)) == 1 with pytest.raises(msgspec.ValidationError, match="Invalid enum value 1000"): dec.decode(enc.encode(1000)) with pytest.raises( msgspec.ValidationError, match=r"Invalid enum value 1000 - at `\$\[0\]`" ): msgspec.msgpack.decode(enc.encode([1000]), type=List[literal]) @pytest.mark.parametrize( "typ, value", [ (bool, False), (bool, True), (int, 1), (float, 2.5), (str, "a"), (bytes, b"a"), (bytearray, bytearray(b"a")), (FruitInt, FruitInt.APPLE), (FruitStr, FruitStr.APPLE), (Person, Person("harry", "potter", 13)), (list, [1]), (set, {1}), (tuple, (1, 2)), (Tuple[int, int], (1, 2)), (dict, {1: 2}), (datetime.datetime, datetime.datetime.now(UTC)), ], ) def test_optional(self, typ, value): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Optional[typ]) s = enc.encode(value) s2 = enc.encode(None) assert dec.decode(s) == value assert dec.decode(s2) is None dec = msgspec.msgpack.Decoder(typ) with pytest.raises(msgspec.ValidationError): dec.decode(s2) @pytest.mark.parametrize( "typ, value", [ (List[Optional[int]], [1, None]), (Tuple[Optional[int], int], (None, 1)), (Set[Optional[int]], {1, None}), (FrozenSet[Optional[int]], frozenset({1, None})), (Dict[str, Optional[int]], {"a": 1, "b": None}), (Dict[Optional[str], int], {"a": 1, None: 2}), ], ) def test_optional_nested(self, typ, value): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(typ) s = enc.encode(value) assert dec.decode(s) == value @pytest.mark.parametrize( "types, vals", [ ([int, float], [1, 2.5]), ( [float, msgspec.msgpack.Ext, int, str], [1.5, msgspec.msgpack.Ext(1, b"two"), 1, "two"], ), ([bool, None, float, str], [True, None, 1.5, "test"]), ], ) def test_union(self, types, vals): dec = msgspec.msgpack.Decoder(List[Union[tuple(types)]]) s = msgspec.msgpack.encode(vals) res = dec.decode(s) assert res == vals for t, v in zip(types, res): if t is not None: t = getattr(t, "__origin__", t) assert type(v) == t @pytest.mark.parametrize( "types, vals", [ ( [PersonArray, FruitInt, FruitStr, Dict[int, str]], [PERSON_AA, FruitInt.APPLE, FruitStr.BANANA, {1: "two"}], ), ( [Person, FruitInt, FruitStr, Tuple[int, ...]], [PERSON, FruitInt.APPLE, FruitStr.BANANA, (1, 2, 3)], ), ( [Person, FruitInt, FruitStr, List[int]], [PERSON, FruitInt.APPLE, FruitStr.BANANA, [1, 2, 3]], ), ( [Person, FruitInt, FruitStr, Set[int]], [PERSON, FruitInt.APPLE, FruitStr.BANANA, {1, 2, 3}], ), ( [Person, FruitInt, FruitStr, Tuple[int, str, float]], [PERSON, FruitInt.APPLE, FruitStr.BANANA, (1, "two", 3.5)], ), ( [Dict[int, str], FruitInt, FruitStr, Tuple[int, ...]], [{1: "two"}, FruitInt.APPLE, FruitStr.BANANA, (1, 2, 3)], ), ( [Dict[int, str], FruitInt, FruitStr, List[int]], [{1: "two"}, FruitInt.APPLE, FruitStr.BANANA, [1, 2, 3]], ), ( [Dict[int, str], FruitInt, FruitStr, Set[int]], [{1: "two"}, FruitInt.APPLE, FruitStr.BANANA, {1, 2, 3}], ), ( [Dict[int, str], FruitInt, FruitStr, Tuple[int, str, float]], [{1: "two"}, FruitInt.APPLE, FruitStr.BANANA, (1, "two", 3.5)], ), ], ) def test_compound_type_unions(self, types, vals): typ_vals = list(zip(types, vals)) for N in range(2, len(typ_vals)): for typ_vals_subset in itertools.combinations(typ_vals, N): types, vals = zip(*typ_vals_subset) vals = list(vals) dec = msgspec.msgpack.Decoder(List[Union[types]]) s = msgspec.msgpack.encode(vals) res = dec.decode(s) assert res == vals for t, v in zip(types, res): t = getattr(t, "__origin__", t) assert type(v) == t def test_union_error(self): msg = msgspec.msgpack.encode(1) with pytest.raises( msgspec.ValidationError, match="Expected `bool | string`, got `int`" ): msgspec.msgpack.decode(msg, type=Union[bool, str]) def test_decoding_error_no_struct_toplevel(self): b = msgspec.msgpack.Encoder().encode([{"a": 1}]) dec = msgspec.msgpack.Decoder(List[Dict[str, str]]) with pytest.raises( msgspec.ValidationError, match=r"Expected `str`, got `int` - at `\$\[0\]\[...\]`", ): dec.decode(b) class TestExt: @pytest.mark.parametrize("data", [b"test", bytearray(b"test"), memoryview(b"test")]) def test_init(self, data): x = msgspec.msgpack.Ext(1, data) assert x.code == 1 assert x.data == data def test_init_bad_arguments(self): with pytest.raises(TypeError, match="Ext takes no keyword arguments"): msgspec.msgpack.Ext(code=1, data=b"two") with pytest.raises(TypeError, match="expected 2 arguments, got 3"): msgspec.msgpack.Ext(1, b"two", 3) with pytest.raises(TypeError, match="expected 2 arguments, got 0"): msgspec.msgpack.Ext() def test_compare(self): x = msgspec.msgpack.Ext(1, b"two") x2 = msgspec.msgpack.Ext(1, b"two") x3 = msgspec.msgpack.Ext(1, b"three") x4 = msgspec.msgpack.Ext(2, b"two") assert x == x2 assert not (x != x2) assert x != x3 assert not (x == x3) assert x != x4 assert not (x == x4) assert not (x == 1) assert x != 1 with pytest.raises(TypeError): x >= x2 @pytest.mark.parametrize("code", [-128, -2, 0, 2, 127]) def test_code_roundtrip(self, code): ext = msgspec.msgpack.Ext(code, b"") assert ext.code == code ext2 = msgspec.msgpack.decode(msgspec.msgpack.encode(ext)) assert ext2.code == code @pytest.mark.parametrize("code", [-129, 128, 2**65]) def test_code_out_of_range(self, code): with pytest.raises(ValueError): msgspec.msgpack.Ext(code, b"bad") def test_data_wrong_type(self): with pytest.raises(TypeError): msgspec.msgpack.Ext(1, 2) def test_code_wrong_type(self): with pytest.raises(TypeError): msgspec.msgpack.Ext(b"bad", b"bad") def test_immutable(self): x = msgspec.msgpack.Ext(1, b"two") with pytest.raises(AttributeError): x.code = 2 def test_pickleable(self): x = msgspec.msgpack.Ext(1, b"two") x2 = pickle.loads(pickle.dumps(x)) assert x2.code == 1 assert x2.data == b"two" @pytest.mark.parametrize("size", sorted({0, 1, 2, 4, 8, 16, *SIZES})) def test_serialize_compatibility(self, size): msgpack = pytest.importorskip("msgpack") data = b"x" * size code = 5 msgspec_bytes = msgspec.msgpack.encode(msgspec.msgpack.Ext(code, data)) msgpack_bytes = msgpack.dumps(msgpack.ExtType(code, data)) assert msgspec_bytes == msgpack_bytes @pytest.mark.parametrize("typ", [bytearray, memoryview]) def test_serialize_other_types(self, typ): buf = b"test" a = msgspec.msgpack.encode(msgspec.msgpack.Ext(1, buf)) b = msgspec.msgpack.encode(msgspec.msgpack.Ext(1, typ(buf))) assert a == b @pytest.mark.parametrize("size", sorted({0, 1, 2, 4, 8, 16, *SIZES})) def test_roundtrip(self, size): data = b"x" * size code = 5 buf = msgspec.msgpack.encode(msgspec.msgpack.Ext(code, data)) out = msgspec.msgpack.decode(buf) assert out.code == code assert out.data == data @pytest.mark.parametrize("size", sorted({0, 1, 2, 4, 8, 16, *SIZES})) def test_roundtrip_typed_decoder(self, size): dec = msgspec.msgpack.Decoder(msgspec.msgpack.Ext) ext = msgspec.msgpack.Ext(5, b"x" * size) buf = msgspec.msgpack.encode(ext) out = dec.decode(buf) assert out == ext def test_typed_decoder_skips_ext_hook(self): def ext_hook(code, data): assert False, "shouldn't ever get called" msg = [None, msgspec.msgpack.Ext(1, b"test")] dec = msgspec.msgpack.Decoder(List[Optional[msgspec.msgpack.Ext]]) buf = msgspec.msgpack.encode(msg) out = dec.decode(buf) assert out == msg def test_ext_typed_decoder_error(self): dec = msgspec.msgpack.Decoder(msgspec.msgpack.Ext) with pytest.raises(msgspec.ValidationError, match="Expected `ext`, got `int`"): assert dec.decode(msgspec.msgpack.encode(1)) @pytest.mark.parametrize("use_function", [True, False]) def test_decoder_ext_hook(self, use_function): obj = {"x": range(10)} exp_buf = pickle.dumps(range(10)) def enc_hook(x): return msgspec.msgpack.Ext(5, pickle.dumps(x)) def ext_hook(code, buf): assert isinstance(buf, memoryview) assert bytes(buf) == exp_buf assert code == 5 return pickle.loads(buf) msg = msgspec.msgpack.encode(obj, enc_hook=enc_hook) if use_function: out = msgspec.msgpack.decode(msg, ext_hook=ext_hook) else: dec = msgspec.msgpack.Decoder(ext_hook=ext_hook) out = dec.decode(msg) assert out == obj def test_decoder_ext_hook_bad_signature(self): msg = msgspec.msgpack.encode( range(5), enc_hook=lambda x: msgspec.msgpack.Ext(1, b"test") ) with pytest.raises(TypeError): msgspec.msgpack.decode(msg, ext_hook=lambda: None) def test_decoder_ext_hook_raises(self): class CustomError(Exception): pass def ext_hook(code, buf): raise CustomError msg = msgspec.msgpack.encode( range(5), enc_hook=lambda x: msgspec.msgpack.Ext(1, b"test") ) with pytest.raises(CustomError): msgspec.msgpack.decode(msg, ext_hook=ext_hook) class TestTimestampExt: def check(self, dt, msg): assert msgspec.msgpack.encode(dt) == msg assert msgspec.msgpack.decode(msg) == dt def test_timestamp32_lower(self): dt = datetime.datetime.fromtimestamp(0, UTC) msg = b"\xd6\xff\x00\x00\x00\x00" self.check(dt, msg) def test_timestamp32_upper(self): dt = datetime.datetime.fromtimestamp(2**32 - 1, UTC) msg = b"\xd6\xff\xff\xff\xff\xff" self.check(dt, msg) def test_timestamp64_lower(self): dt = datetime.datetime.fromtimestamp(1e-6, UTC) msg = b"\xd7\xff\x00\x00\x0f\xa0\x00\x00\x00\x00" self.check(dt, msg) def test_timestamp64_upper(self): dt = datetime.datetime.fromtimestamp(2**34, UTC) - datetime.timedelta( microseconds=1 ) msg = b"\xd7\xff\xeek\x18c\xff\xff\xff\xff" self.check(dt, msg) def test_timestamp96_lower(self): dt = datetime.datetime.fromtimestamp(-1e-6, UTC) msg = b"\xc7\x0c\xff;\x9a\xc6\x18\xff\xff\xff\xff\xff\xff\xff\xff" self.check(dt, msg) def test_timestamp96_upper(self): dt = datetime.datetime.fromtimestamp(2**34, UTC) msg = b"\xc7\x0c\xff\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00" self.check(dt, msg) @pytest.mark.parametrize( "msg, secs, micros", [ (b"\xd7\xff\x00\x00\x07\xd0\x00\x00\x00\x00", 0, 1), (b"\xd7\xff\x00\x00\x07\xcc\x00\x00\x00\x00", 0, 0), (b"\xd7\xff\xeek 0\x00\x00\x00\x00", 1, 0), (b"\xd7\xff\xeek ,\x00\x00\x00\x00", 0, 999999), ], ) def test_timestamp_rounds_nanos(self, msg, secs, micros): res = msgspec.msgpack.decode(msg) assert res.second == secs assert res.microsecond == micros class CommonTypeTestBase: """Test msgspec untyped encode/decode""" def test_none(self): self.check(None) @pytest.mark.parametrize("x", [False, True]) def test_bool(self, x): self.check(x) @pytest.mark.parametrize("x", INTS) def test_int(self, x): self.check(x) @pytest.mark.parametrize("x", FLOATS) def test_float(self, x): self.check(x) @pytest.mark.parametrize("size", SIZES) def test_str(self, size): self.check(" " * size) @pytest.mark.parametrize("size", SIZES) def test_bytes(self, size): self.check(b" " * size) @pytest.mark.parametrize("size", SIZES) def test_dict(self, size): self.check({str(i): i for i in range(size)}) @pytest.mark.parametrize("size", SIZES) def test_list(self, size): self.check(list(range(size))) class TestDecodeArrayTypeUsesTupleIfHashableRequired: def test_decode_tuple_dict_keys_as_tuples(self): orig = {(1, 2): [1, 2, [3, 4]], (1, (2, 3)): [4, 5, 6], tuple(range(32)): []} data = msgspec.msgpack.encode(orig) out = msgspec.msgpack.decode(data) assert orig == out @pytest.mark.parametrize( "typ", [ Dict[Tuple[int, Tuple[int, int]], List[int]], Dict[Tuple[int, Tuple[int, ...]], Any], Dict[Tuple, List[int]], Dict[Tuple[Any, ...], Any], Dict[Tuple[Any, Any], Any], ], ) def test_decode_dict_key_status_forwarded_through_typed_tuples(self, typ): orig = {(1, (2, 3)): [1, 2, 3]} data = msgspec.msgpack.encode(orig) out = msgspec.msgpack.Decoder(typ).decode(data) assert orig == out def test_decode_tuple_set_keys_as_tuples(self): orig = {(1, 2), (3, (4, 5)), 6} data = msgspec.msgpack.encode(orig) out = msgspec.msgpack.decode(data, type=set) assert orig == out def test_decode_hashable_struct_in_key(self): class Test(msgspec.Struct): data: List[int] def __hash__(self): return hash(tuple(self.data)) orig = {(1, Test([1, 2])): [1, 2]} data = msgspec.msgpack.encode(orig) out = msgspec.msgpack.Decoder(Dict[Tuple[int, Test], List[int]]).decode(data) assert orig == out class TestUntypedDecoder(CommonTypeTestBase): """Check the untyped deserializer works for common types""" def check(self, x): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder() assert_eq(dec.decode(enc.encode(x)), x) class TestCompatibility(CommonTypeTestBase): """Test compatibility with the existing python msgpack library""" def check(self, x): msgpack = pytest.importorskip("msgpack") enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder() assert_eq(dec.decode(msgpack.dumps(x)), x) assert_eq(msgpack.loads(enc.encode(x)), x) class TestStruct: @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag): pass if tag: msg = {"type": tag} else: msg = {} s = msgspec.msgpack.encode(Test()) s2 = msgspec.msgpack.encode(msg) assert s == s2 @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_one_field_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int if tag: msg = {"type": tag, "a": 1} else: msg = {"a": 1} s = msgspec.msgpack.encode(Test(a=1)) s2 = msgspec.msgpack.encode(msg) assert s == s2 @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_two_field_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int b: str if tag: msg = {"type": tag, "a": 1, "b": "two"} else: msg = {"a": 1, "b": "two"} s = msgspec.msgpack.encode(Test(a=1, b="two")) s2 = msgspec.msgpack.encode(msg) assert s == s2 def test_decode_struct(self): dec = msgspec.msgpack.Decoder(Person) msg = msgspec.msgpack.encode( {"first": "harry", "last": "potter", "age": 13, "prefect": False} ) x = dec.decode(msg) assert x == Person("harry", "potter", 13, False) with pytest.raises( msgspec.ValidationError, match="Expected `object`, got `int`" ): dec.decode(msgspec.msgpack.encode(1)) def test_decode_struct_field_wrong_type(self): dec = msgspec.msgpack.Decoder(Person) msg = msgspec.msgpack.encode({"first": "harry", "last": "potter", "age": "bad"}) with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$.age`" ): dec.decode(msg) def test_decode_struct_missing_fields(self): bad = msgspec.msgpack.encode({"first": "harry", "last": "potter"}) with pytest.raises( msgspec.ValidationError, match="Object missing required field `age`" ): msgspec.msgpack.decode(bad, type=Person) bad = msgspec.msgpack.encode({}) with pytest.raises( msgspec.ValidationError, match="Object missing required field `first`" ): msgspec.msgpack.decode(bad, type=Person) bad = msgspec.msgpack.encode([{"first": "harry", "last": "potter"}]) with pytest.raises( msgspec.ValidationError, match=r"Object missing required field `age` - at `\$\[0\]`", ): msgspec.msgpack.decode(bad, type=List[Person]) @pytest.mark.parametrize( "extra", [ None, False, True, 1, 2.0, "three", b"four", [1, 2], {3: 4}, msgspec.msgpack.Ext(1, b"12345"), msgspec.msgpack.Ext(1, b""), ], ) def test_decode_struct_ignore_extra_fields(self, extra): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Person) a = enc.encode( { "extra1": extra, "first": "harry", "extra2": extra, "last": "potter", "age": 13, "extra3": extra, } ) res = dec.decode(a) assert res == Person("harry", "potter", 13) def test_decode_struct_defaults_missing_fields(self): dec = msgspec.msgpack.Decoder(Person) a = msgspec.msgpack.encode({"first": "harry", "last": "potter", "age": 13}) res = dec.decode(a) assert res == Person("harry", "potter", 13) assert res.prefect is False @pytest.mark.parametrize("array_like", [False, True]) def test_struct_gc_maybe_untracked_on_decode(self, array_like): class Test(msgspec.Struct, array_like=array_like): x: Any y: Any z: Tuple = () enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(List[Test]) ts = [ Test(1, 2), Test(3, "hello"), Test([], []), Test({}, {}), Test(None, None, ()), ] a, b, c, d, e = dec.decode(enc.encode(ts)) assert not gc.is_tracked(a) assert not gc.is_tracked(b) assert gc.is_tracked(c) assert gc.is_tracked(d) assert not gc.is_tracked(e) @pytest.mark.parametrize("array_like", [False, True]) def test_struct_gc_false_always_untracked_on_decode(self, array_like): class Test(msgspec.Struct, array_like=array_like, gc=False): x: Any y: Any dec = msgspec.msgpack.Decoder(List[Test]) ts = [ Test(1, 2), Test([], []), Test({}, {}), ] for obj in dec.decode(msgspec.msgpack.encode(ts)): assert not gc.is_tracked(obj) def test_struct_recursive_definition(self): enc = msgspec.msgpack.Encoder() dec = msgspec.msgpack.Decoder(Node) x = Node(Node(Node(), Node(Node()))) s = enc.encode(x) res = dec.decode(s) assert res == x @pytest.mark.parametrize("tag", ["Test", 123, -123]) def test_decode_tagged_struct(self, tag): class Test(msgspec.Struct, tag=tag): a: int b: int dec = msgspec.msgpack.Decoder(Test) # Test decode with and without tag for msg in [ {"a": 1, "b": 2}, {"type": tag, "a": 1, "b": 2}, {"a": 1, "type": tag, "b": 2}, ]: res = dec.decode(msgspec.msgpack.encode(msg)) assert res == Test(1, 2) # Tag incorrect type with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode({"type": 123.456})) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$.type`" in str(rec.value) # Tag incorrect value bad = -3 if isinstance(tag, int) else "bad" with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode({"type": bad})) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize("tag", [i for i in INTS if -(2**63) <= i < 2**63]) def test_decode_tagged_struct_int_ranges(self, tag): class Test(msgspec.Struct, tag=tag): a: int b: int dec = msgspec.msgpack.Decoder(Test) t = Test(1, 2) assert dec.decode(msgspec.msgpack.encode(t)) def test_decode_tagged_struct_int_tag_uint64_always_invalid(self): """Uint64 values aren't currently valid tag values, but we still want to raise a good error message.""" class Test(msgspec.Struct, tag=123): pass with pytest.raises(msgspec.ValidationError) as rec: msgspec.msgpack.decode( msgspec.msgpack.encode({"type": 2**64 - 1}), type=Test ) assert f"Invalid value {2**64 - 1}" in str(rec.value) assert "`$.type`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123, -123]) def test_decode_tagged_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag): pass dec = msgspec.msgpack.Decoder(Test) # Tag missing res = dec.decode(msgspec.msgpack.encode({})) assert res == Test() # Tag present res = dec.decode(msgspec.msgpack.encode({"type": tag})) assert res == Test() class TestStructArray: @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_empty_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): pass s = msgspec.msgpack.encode(Test()) if tag: msg = [tag] else: msg = [] s2 = msgspec.msgpack.encode(msg) assert s == s2 @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_one_field_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): a: int s = msgspec.msgpack.encode(Test(a=1)) if tag: msg = [tag, 1] else: msg = [1] s2 = msgspec.msgpack.encode(msg) assert s == s2 @pytest.mark.parametrize("tag", [False, "Test", 123]) def test_encode_two_field_struct(self, tag): class Test(msgspec.Struct, array_like=True, tag=tag): a: int b: str s = msgspec.msgpack.encode(Test(a=1, b="two")) if tag: msg = [tag, 1, "two"] else: msg = [1, "two"] s2 = msgspec.msgpack.encode(msg) assert s == s2 def test_struct_array_like(self): dec = msgspec.msgpack.Decoder(PersonArray) x = PersonArray(first="harry", last="potter", age=13) a = msgspec.msgpack.encode(x) assert msgspec.msgpack.encode(("harry", "potter", 13, False)) == a assert dec.decode(a) == x with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `int`" ): dec.decode(b"1") # Wrong field type bad = msgspec.msgpack.encode(("harry", "potter", "thirteen")) with pytest.raises( msgspec.ValidationError, match=r"Expected `int`, got `str` - at `\$\[2\]`" ): dec.decode(bad) # Missing fields bad = msgspec.msgpack.encode(("harry", "potter")) with pytest.raises( msgspec.ValidationError, match="Expected `array` of at least length 3, got 2", ): dec.decode(bad) bad = msgspec.msgpack.encode(()) with pytest.raises( msgspec.ValidationError, match="Expected `array` of at least length 3, got 0", ): dec.decode(bad) # Extra fields ignored dec2 = msgspec.msgpack.Decoder(List[PersonArray]) msg = msgspec.msgpack.encode( [ ("harry", "potter", 13, False, 1, 2, 3, 4), ("ron", "weasley", 13, False, 5, 6), ] ) res = dec2.decode(msg) assert res == [ PersonArray("harry", "potter", 13), PersonArray("ron", "weasley", 13), ] # Defaults applied res = dec.decode(msgspec.msgpack.encode(("harry", "potter", 13))) assert res == PersonArray("harry", "potter", 13) assert res.prefect is False def test_struct_map_and_array_like_messages_cant_mix(self): array_msg = msgspec.msgpack.encode(("harry", "potter", 13)) map_msg = msgspec.msgpack.encode( {"first": "harry", "last": "potter", "age": 13} ) sol = Person("harry", "potter", 13) array_sol = PersonArray("harry", "potter", 13) dec = msgspec.msgpack.Decoder(Person) array_dec = msgspec.msgpack.Decoder(PersonArray) assert array_dec.decode(array_msg) == array_sol assert dec.decode(map_msg) == sol with pytest.raises( msgspec.ValidationError, match="Expected `object`, got `array`" ): dec.decode(array_msg) with pytest.raises( msgspec.ValidationError, match="Expected `array`, got `object`" ): array_dec.decode(map_msg) @pytest.mark.parametrize("tag", ["Test", -123, 123]) def test_decode_tagged_struct(self, tag): class Test(msgspec.Struct, tag=tag, array_like=True): a: int b: int c: int = 0 dec = msgspec.msgpack.Decoder(Test) # Decode with tag res = dec.decode(msgspec.msgpack.encode([tag, 1, 2])) assert res == Test(1, 2) res = dec.decode(msgspec.msgpack.encode([tag, 1, 2, 3])) assert res == Test(1, 2, 3) # Trailing fields ignored res = dec.decode(msgspec.msgpack.encode([tag, 1, 2, 3, 4])) assert res == Test(1, 2, 3) # Missing required field errors with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([tag, 1])) assert "Expected `array` of at least length 3, got 2" in str(rec.value) # Tag missing with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([])) assert "Expected `array` of at least length 3, got 0" in str(rec.value) # Tag incorrect type with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([123.456, 2, 3])) assert f"Expected `{type(tag).__name__}`" in str(rec.value) assert "`$[0]`" in str(rec.value) # Tag incorrect value bad = -3 if isinstance(tag, int) else "bad" with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([bad, 1, 2])) assert f"Invalid value {bad!r}" in str(rec.value) assert "`$[0]`" in str(rec.value) # Field incorrect type correct index with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([tag, "a", 2])) assert "Expected `int`, got `str`" in str(rec.value) assert "`$[1]`" in str(rec.value) @pytest.mark.parametrize("tag", ["Test", 123, -123]) def test_decode_tagged_empty_struct(self, tag): class Test(msgspec.Struct, tag=tag, array_like=True): pass dec = msgspec.msgpack.Decoder(Test) # Decode with tag res = dec.decode(msgspec.msgpack.encode([tag, 1, 2])) assert res == Test() # Tag missing with pytest.raises(msgspec.ValidationError) as rec: dec.decode(msgspec.msgpack.encode([])) assert "Expected `array` of at least length 1, got 0" in str(rec.value) class TestRaw: def test_encode_raw(self): b = msgspec.msgpack.encode({"x": 1}) r = msgspec.Raw(b) assert msgspec.msgpack.encode(r) == b assert msgspec.msgpack.encode({"y": r}) == msgspec.msgpack.encode( {"y": {"x": 1}} ) def test_decode_raw_field(self): class Test(msgspec.Struct): x: int y: msgspec.Raw s = msgspec.msgpack.encode({"x": 1, "y": [1, 2, 3]}) res = msgspec.msgpack.decode(s, type=Test) assert res.x == 1 assert bytes(res.y) == msgspec.msgpack.encode([1, 2, 3]) def test_decode_raw_optional_field(self): default = msgspec.Raw() class Test(msgspec.Struct): x: int y: msgspec.Raw = default s = msgspec.msgpack.encode({"x": 1, "y": [1, 2, 3]}) res = msgspec.msgpack.decode(s, type=Test) assert res.x == 1 assert bytes(res.y) == msgspec.msgpack.encode([1, 2, 3]) s = msgspec.msgpack.encode({"x": 1}) res = msgspec.msgpack.decode(s, type=Test) assert res.x == 1 assert res.y is default def test_decode_raw_malformed_data(self): class Test(msgspec.Struct): x: int y: msgspec.Raw s = msgspec.msgpack.encode({"x": 1, "y": [1, 2]})[:3] with pytest.raises(msgspec.DecodeError): msgspec.msgpack.decode(s, type=Test) def test_decode_raw_is_view(self): s = msgspec.msgpack.encode({"x": 1}) r = msgspec.msgpack.decode(s, type=msgspec.Raw) assert bytes(r) == s assert r.copy() is not r # actual copy indicates a view def test_raw_in_union_works_but_doesnt_change_anything(self): class Test(msgspec.Struct): x: Union[int, str, msgspec.Raw] s = msgspec.msgpack.encode({"x": 1}) r = msgspec.msgpack.decode(s, type=Test) assert r == Test(1) def test_raw_can_be_mixed_with_custom_type(self): class Test(msgspec.Struct): x: Union[Custom, msgspec.Raw] def dec_hook(typ, obj): assert typ is Custom return typ(*obj) s = msgspec.msgpack.encode({"x": [1, 2]}) res = msgspec.msgpack.decode(s, type=Test, dec_hook=dec_hook) assert res == Test(Custom(1, 2)) python-msgspec-0.19.0/tests/test_mypy.py000066400000000000000000000020371473355726200203520ustar00rootroot00000000000000import os import re import pytest pytestmark = pytest.mark.mypy api = pytest.importorskip("mypy.api") PATH = os.path.join(os.path.dirname(__file__), "basic_typing_examples.py") def get_lineno_type(line): assert "revealed type" in line.lower() _, lineno, msg = line.split(":", 2) lineno = int(lineno) pat = re.search("[\"'](.*)[\"']", msg) typ = pat.groups()[0] return lineno, typ def test_mypy(): with open(PATH, "r") as fil: ex_lines = fil.readlines() stdout, stderr, code = api.run([PATH]) lines = stdout.splitlines() for line in lines: if "revealed type" in line.lower(): lineno, typ = get_lineno_type(line) check = ex_lines[lineno - 1].split("#")[1].strip() try: exec(check, {"typ": typ}) except Exception: assert ( False ), f"Failed check at {PATH}:{lineno}: {check!r}, where 'typ' is {typ!r}" elif "success" not in line.lower(): assert False, line python-msgspec-0.19.0/tests/test_performance.py000066400000000000000000000021711473355726200216540ustar00rootroot00000000000000import textwrap import msgspec from utils import temp_module def test_process_large_recursive_union(): """ A recursive schema processing perf test from https://github.com/pydantic/pydantic/issues/8499 This test is mostly to ensure that processing deeply recursive schemas with unions succeeds. """ def gen_code(): yield "from __future__ import annotations" yield "from msgspec import Struct" yield "from typing import Union" for i in range(50): yield textwrap.dedent( f""" class Node{i}(Struct, tag='node{i}'): data: Union[Node, None] """ ) yield "Node = Union[" for i in range(50): yield f" Node{i}," yield "]" code = "\n".join(gen_code()) with temp_module(code) as mod: dec = msgspec.json.Decoder(mod.Node) msg = b""" { "type": "node25", "data": { "type": "node13", "data": null } } """ sol = mod.Node25(mod.Node13(None)) assert dec.decode(msg) == sol python-msgspec-0.19.0/tests/test_pyright.py000066400000000000000000000017311473355726200210420ustar00rootroot00000000000000import os import re import subprocess import pytest pytestmark = pytest.mark.pyright pyright = pytest.importorskip("pyright") PATH = os.path.join(os.path.dirname(__file__), "basic_typing_examples.py") def test_pyright(): with open(PATH, "r") as fil: ex_lines = fil.readlines() result = pyright.run(PATH, stdout=subprocess.PIPE) if result.returncode != 0: assert False, f"Unexpected pyright error:\n{result.stdout}" for line in result.stdout.decode().splitlines(): try: _, lineno, _, msg = line.split(":", 3) except ValueError: continue lineno = int(lineno) pat = re.search("[\"'](.*)[\"']", msg) typ = pat.groups()[0] check = ex_lines[lineno - 1].split("#")[1].strip() try: exec(check, {"typ": typ}) except Exception: assert ( False ), f"Failed check at {PATH}:{lineno}: {check!r}, where 'typ' is {typ!r}" python-msgspec-0.19.0/tests/test_raw.py000066400000000000000000000062211473355726200201440ustar00rootroot00000000000000import operator import subprocess import sys import textwrap import weakref import pytest import msgspec def test_raw_noargs(): r = msgspec.Raw() assert bytes(r) == b"" assert len(r) == 0 assert not r @pytest.mark.parametrize("type", [bytes, bytearray, memoryview, str]) def test_raw_constructor(type): msg = "test" if type is str else type(b"test") r = msgspec.Raw(msg) assert bytes(r) == b"test" assert len(r) == 4 assert r def test_raw_constructor_errors(): with pytest.raises(TypeError): msgspec.Raw(1) with pytest.raises(TypeError): msgspec.Raw(msg=b"test") with pytest.raises(TypeError): msgspec.Raw(b"test", b"extra") def test_raw_from_view(): r = msgspec.Raw(memoryview(b"123456")[:3]) assert bytes(r) == b"123" assert len(r) == 3 assert r def test_raw_copy(): r = msgspec.Raw(b"test") c1 = sys.getrefcount(r) r2 = r.copy() c2 = sys.getrefcount(r) assert c1 + 1 == c2 assert r2 is r r = msgspec.Raw() assert r.copy() is r m = memoryview(b"test") ref = weakref.ref(m) r = msgspec.Raw(m) del m # Raw holds a ref assert ref() is not None r2 = r.copy() # Actually copied assert r2 is not r assert bytes(r2) == b"test" # Copy doesn't accidentally release buffer assert ref() is not None del r # Copy doesn't hold a reference to original view assert ref() is None def test_raw_copy_doesnt_leak(): """See https://github.com/jcrist/msgspec/pull/709""" script = textwrap.dedent( """ import msgspec import tracemalloc tracemalloc.start() raw = msgspec.Raw(bytearray(1000)) for _ in range(10000): raw.copy() _, peak = tracemalloc.get_traced_memory() print(peak) """ ) output = subprocess.check_output([sys.executable, "-c", script]) peak = int(output.decode().strip()) assert peak < 10_000 # should really be ~2000 def test_raw_pickle_bytes(): orig_buffer = b"test" r = msgspec.Raw(orig_buffer) o = r.__reduce__() assert o == (msgspec.Raw, (b"test",)) assert o[1][0] is orig_buffer def test_raw_pickle_str(): orig_buffer = "test" r = msgspec.Raw(orig_buffer) o = r.__reduce__() assert o == (msgspec.Raw, ("test",)) assert o[1][0] is orig_buffer def test_raw_pickle_view(): r = msgspec.Raw(memoryview(b"test")[:3]) o = r.__reduce__() assert o == (msgspec.Raw, (b"tes",)) def test_raw_comparison(): r = msgspec.Raw() assert r == r assert not r != r assert msgspec.Raw() == msgspec.Raw() assert msgspec.Raw(b"") == msgspec.Raw() assert not msgspec.Raw(b"") == msgspec.Raw(b"other") assert msgspec.Raw(b"test") == msgspec.Raw(memoryview(b"testy")[:4]) assert msgspec.Raw(b"test") != msgspec.Raw(b"tesp") assert msgspec.Raw(b"test") != msgspec.Raw(b"") assert msgspec.Raw(b"") != msgspec.Raw(b"test") assert msgspec.Raw() != 1 assert 1 != msgspec.Raw() for op in [operator.lt, operator.gt, operator.le, operator.ge]: with pytest.raises(TypeError): op(msgspec.Raw(), msgspec.Raw()) python-msgspec-0.19.0/tests/test_schema.py000066400000000000000000001032101473355726200206070ustar00rootroot00000000000000import datetime import decimal import enum import typing import uuid from base64 import b64encode from collections import namedtuple from dataclasses import dataclass from typing import ( Annotated, Any, Dict, FrozenSet, Generic, List, Literal, NamedTuple, NewType, Set, Tuple, TypedDict, TypeVar, Union, ) import pytest from utils import temp_module import msgspec from msgspec import Meta T = TypeVar("T") def test_any(): assert msgspec.json.schema(Any) == {} def test_raw(): assert msgspec.json.schema(msgspec.Raw) == {} def test_msgpack_ext(): with pytest.raises(TypeError): assert msgspec.json.schema(msgspec.msgpack.Ext) def test_custom(): with pytest.raises(TypeError, match="Generating JSON schema for custom types"): assert msgspec.json.schema(complex) schema = {"type": "string", "format": "complex"} assert ( msgspec.json.schema(Annotated[complex, Meta(extra_json_schema=schema)]) == schema ) def test_custom_schema_hook(): schema = {"type": "string", "format": "complex"} def schema_hook(cls): if cls is complex: return schema raise NotImplementedError assert msgspec.json.schema(complex, schema_hook=schema_hook) == schema assert msgspec.json.schema( Annotated[complex, Meta(extra_json_schema={"title": "A complex field"})], schema_hook=schema_hook, ) == {**schema, "title": "A complex field"} with pytest.raises(TypeError, match="Generating JSON schema for custom types"): msgspec.json.schema(slice, schema_hook=schema_hook) def test_none(): assert msgspec.json.schema(None) == {"type": "null"} def test_bool(): assert msgspec.json.schema(bool) == {"type": "boolean"} def test_int(): assert msgspec.json.schema(int) == {"type": "integer"} def test_float(): assert msgspec.json.schema(float) == {"type": "number"} def test_string(): assert msgspec.json.schema(str) == {"type": "string"} @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_binary(typ): assert msgspec.json.schema(typ) == { "type": "string", "contentEncoding": "base64", } @pytest.mark.parametrize( "annot, extra", [ (None, {}), (Meta(tz=None), {}), (Meta(tz=True), {"format": "date-time"}), (Meta(tz=False), {}), ], ) def test_datetime(annot, extra): typ = datetime.datetime if annot is not None: typ = Annotated[typ, annot] assert msgspec.json.schema(typ) == {"type": "string", **extra} @pytest.mark.parametrize( "annot, extra", [ (None, {}), (Meta(tz=None), {}), (Meta(tz=True), {"format": "time"}), (Meta(tz=False), {"format": "partial-time"}), ], ) def test_time(annot, extra): typ = datetime.time if annot is not None: typ = Annotated[typ, annot] assert msgspec.json.schema(typ) == {"type": "string", **extra} def test_date(): assert msgspec.json.schema(datetime.date) == { "type": "string", "format": "date", } def test_timedelta(): assert msgspec.json.schema(datetime.timedelta) == { "type": "string", "format": "duration", } def test_uuid(): assert msgspec.json.schema(uuid.UUID) == { "type": "string", "format": "uuid", } def test_decimal(): assert msgspec.json.schema(decimal.Decimal) == { "type": "string", "format": "decimal", } def test_newtype(): UserId = NewType("UserId", str) assert msgspec.json.schema(UserId) == {"type": "string"} assert msgspec.json.schema(Annotated[UserId, Meta(max_length=10)]) == { "type": "string", "maxLength": 10, } @pytest.mark.parametrize( "typ", [list, tuple, set, frozenset, List, Tuple, Set, FrozenSet] ) def test_sequence_any(typ): assert msgspec.json.schema(typ) == {"type": "array"} @pytest.mark.parametrize( "cls", [list, tuple, set, frozenset, List, Tuple, Set, FrozenSet] ) def test_sequence_typed(cls): args = (int, ...) if cls in (tuple, Tuple) else int typ = cls[args] assert msgspec.json.schema(typ) == {"type": "array", "items": {"type": "integer"}} @pytest.mark.parametrize("cls", [tuple, Tuple]) def test_tuple(cls): typ = cls[int, float, str] assert msgspec.json.schema(typ) == { "type": "array", "minItems": 3, "maxItems": 3, "items": False, "prefixItems": [ {"type": "integer"}, {"type": "number"}, {"type": "string"}, ], } @pytest.mark.parametrize("cls", [tuple, Tuple]) def test_empty_tuple(cls): typ = cls[()] assert msgspec.json.schema(typ) == { "type": "array", "minItems": 0, "maxItems": 0, } @pytest.mark.parametrize("typ", [dict, Dict]) def test_dict_any(typ): assert msgspec.json.schema(typ) == {"type": "object"} @pytest.mark.parametrize("cls", [dict, Dict]) def test_dict_typed(cls): typ = cls[str, int] assert msgspec.json.schema(typ) == { "type": "object", "additionalProperties": {"type": "integer"}, } def test_abstract_sequence(): # Only testing one here, the main tests are in `test_inspect` typ = typing.Sequence[int] assert msgspec.json.schema(typ) == {"type": "array", "items": {"type": "integer"}} def test_abstract_mapping(): # Only testing one here, the main tests are in `test_inspect` typ = typing.MutableMapping[str, int] assert msgspec.json.schema(typ) == { "type": "object", "additionalProperties": {"type": "integer"}, } def test_int_enum(): class Example(enum.IntEnum): C = 1 B = 3 A = 2 assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": {"Example": {"title": "Example", "enum": [1, 2, 3]}}, } def test_enum(): class Example(enum.Enum): """A docstring""" C = "x" B = "z" A = "y" assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "description": "A docstring", "enum": ["x", "y", "z"], } }, } def test_int_literal(): assert msgspec.json.schema(Literal[3, 1, 2]) == {"enum": [1, 2, 3]} def test_str_literal(): assert msgspec.json.schema(Literal["c", "a", "b"]) == {"enum": ["a", "b", "c"]} def test_struct_object(): class Point(msgspec.Struct, forbid_unknown_fields=True): x: int y: int class Polygon(msgspec.Struct): """An example docstring""" vertices: List[Point] name: Union[str, None] = None metadata: Dict[str, str] = {} assert msgspec.json.schema(Polygon) == { "$ref": "#/$defs/Polygon", "$defs": { "Polygon": { "title": "Polygon", "description": "An example docstring", "type": "object", "properties": { "vertices": { "type": "array", "items": {"$ref": "#/$defs/Point"}, }, "name": { "anyOf": [{"type": "string"}, {"type": "null"}], "default": None, }, "metadata": { "type": "object", "additionalProperties": {"type": "string"}, "default": {}, }, }, "required": ["vertices"], }, "Point": { "title": "Point", "type": "object", "properties": { "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["x", "y"], "additionalProperties": False, }, }, } @pytest.mark.parametrize("forbid_unknown_fields", [False, True]) def test_struct_array_like(forbid_unknown_fields): class Example( msgspec.Struct, array_like=True, forbid_unknown_fields=forbid_unknown_fields ): """An example docstring""" a: int b: str c: List[int] = [] d: Dict[str, int] = {} sol = { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "description": "An example docstring", "type": "array", "prefixItems": [ {"type": "integer"}, {"type": "string"}, {"type": "array", "items": {"type": "integer"}, "default": []}, { "type": "object", "additionalProperties": {"type": "integer"}, "default": {}, }, ], "minItems": 2, } }, } if forbid_unknown_fields: sol["$defs"]["Example"]["maxItems"] = 4 assert msgspec.json.schema(Example) == sol def test_struct_no_fields(): class Example(msgspec.Struct): pass assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "type": "object", "properties": {}, "required": [], } }, } def test_struct_object_tagged(): class Point(msgspec.Struct, tag=True): x: int y: int assert msgspec.json.schema(Point) == { "$ref": "#/$defs/Point", "$defs": { "Point": { "title": "Point", "type": "object", "properties": { "type": {"enum": ["Point"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["type", "x", "y"], } }, } def test_struct_array_tagged(): class Point(msgspec.Struct, tag=True, array_like=True): x: int y: int assert msgspec.json.schema(Point) == { "$ref": "#/$defs/Point", "$defs": { "Point": { "title": "Point", "type": "array", "prefixItems": [ {"enum": ["Point"]}, {"type": "integer"}, {"type": "integer"}, ], "minItems": 3, } }, } def test_struct_keyword_only(): class Base(msgspec.Struct, kw_only=True): x: int = 1 y: int z: int = 2 class Test(Base): a: int b: int = 0 assert msgspec.json.schema(Test) == { "$ref": "#/$defs/Test", "$defs": { "Test": { "title": "Test", "type": "object", "properties": { "a": {"type": "integer"}, "b": {"type": "integer", "default": 0}, "x": {"type": "integer", "default": 1}, "y": {"type": "integer"}, "z": {"type": "integer", "default": 2}, }, "required": ["a", "y"], } }, } def test_struct_array_keyword_only(): class Base(msgspec.Struct, kw_only=True, array_like=True): x: int = 1 y: int z: int = 2 class Test(Base): a: int b: int = 0 assert msgspec.json.schema(Test) == { "$ref": "#/$defs/Test", "$defs": { "Test": { "title": "Test", "type": "array", "prefixItems": [ {"type": "integer"}, {"type": "integer", "default": 0}, {"type": "integer", "default": 1}, {"type": "integer"}, {"type": "integer", "default": 2}, ], "minItems": 4, } }, } def test_typing_namedtuple(): class Example(NamedTuple): """An example docstring""" a: str b: bool c: int = 0 assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "description": "An example docstring", "type": "array", "prefixItems": [ {"type": "string"}, {"type": "boolean"}, {"type": "integer", "default": 0}, ], "minItems": 2, "maxItems": 3, } }, } def test_collections_namedtuple(): Example = namedtuple("Example", ["a", "b", "c"], defaults=(0,)) assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "type": "array", "prefixItems": [{}, {}, {"default": 0}], "minItems": 2, "maxItems": 3, } }, } def test_generic_namedtuple(): NamedTuple = pytest.importorskip("typing_extensions").NamedTuple class Ex(NamedTuple, Generic[T]): """An example docstring""" x: T y: List[T] assert msgspec.json.schema(Ex) == { "$ref": "#/$defs/Ex", "$defs": { "Ex": { "title": "Ex", "description": "An example docstring", "type": "array", "prefixItems": [{}, {"type": "array"}], "minItems": 2, "maxItems": 2, }, }, } assert msgspec.json.schema(Ex[int]) == { "$ref": "#/$defs/Ex_int_", "$defs": { "Ex_int_": { "title": "Ex[int]", "description": "An example docstring", "type": "array", "prefixItems": [ {"type": "integer"}, {"type": "array", "items": {"type": "integer"}}, ], "minItems": 2, "maxItems": 2, }, }, } @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_typeddict(use_typing_extensions): if use_typing_extensions: tex = pytest.importorskip("typing_extensions") cls = tex.TypedDict else: cls = TypedDict class Example(cls): """An example docstring""" a: str b: bool c: int assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "description": "An example docstring", "type": "object", "properties": { "a": {"type": "string"}, "b": {"type": "boolean"}, "c": {"type": "integer"}, }, "required": ["a", "b", "c"], } }, } @pytest.mark.parametrize("use_typing_extensions", [False, True]) def test_typeddict_optional(use_typing_extensions): if use_typing_extensions: tex = pytest.importorskip("typing_extensions") cls = tex.TypedDict else: cls = TypedDict class Base(cls): a: str b: bool class Example(Base, total=False): """An example docstring""" c: int assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "title": "Example", "description": "An example docstring", "type": "object", "properties": { "a": {"type": "string"}, "b": {"type": "boolean"}, "c": {"type": "integer"}, }, "required": ["a", "b"], } }, } def test_generic_typeddict(): TypedDict = pytest.importorskip("typing_extensions").TypedDict class Ex(TypedDict, Generic[T]): """An example docstring""" x: T y: List[T] assert msgspec.json.schema(Ex) == { "$ref": "#/$defs/Ex", "$defs": { "Ex": { "title": "Ex", "description": "An example docstring", "type": "object", "properties": { "x": {}, "y": {"type": "array"}, }, "required": ["x", "y"], }, }, } assert msgspec.json.schema(Ex[int]) == { "$ref": "#/$defs/Ex_int_", "$defs": { "Ex_int_": { "title": "Ex[int]", "description": "An example docstring", "type": "object", "properties": { "x": {"type": "integer"}, "y": {"type": "array", "items": {"type": "integer"}}, }, "required": ["x", "y"], }, }, } @pytest.mark.parametrize("module", ["dataclasses", "attrs"]) def test_dataclass_or_attrs(module): m = pytest.importorskip(module) if module == "attrs": decorator = m.define factory_default = m.field(factory=dict) else: decorator = m.dataclass factory_default = m.field(default_factory=dict) @decorator class Point: x: int y: int @decorator class Polygon: """An example docstring""" vertices: List[Point] name: Union[str, None] = None metadata: Dict[str, str] = factory_default assert msgspec.json.schema(Polygon) == { "$ref": "#/$defs/Polygon", "$defs": { "Polygon": { "title": "Polygon", "description": "An example docstring", "type": "object", "properties": { "vertices": { "type": "array", "items": {"$ref": "#/$defs/Point"}, }, "name": { "anyOf": [{"type": "string"}, {"type": "null"}], "default": None, }, "metadata": { "type": "object", "additionalProperties": {"type": "string"}, }, }, "required": ["vertices"], }, "Point": { "title": "Point", "type": "object", "properties": { "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["x", "y"], }, }, } @pytest.mark.parametrize("module", ["dataclasses", "attrs"]) def test_generic_dataclass_or_attrs(module): m = pytest.importorskip(module) decorator = m.define if module == "attrs" else m.dataclass @decorator class Ex(Generic[T]): """An example docstring""" x: T y: List[T] assert msgspec.json.schema(Ex) == { "$ref": "#/$defs/Ex", "$defs": { "Ex": { "title": "Ex", "description": "An example docstring", "type": "object", "properties": { "x": {}, "y": {"type": "array"}, }, "required": ["x", "y"], }, }, } assert msgspec.json.schema(Ex[int]) == { "$ref": "#/$defs/Ex_int_", "$defs": { "Ex_int_": { "title": "Ex[int]", "description": "An example docstring", "type": "object", "properties": { "x": {"type": "integer"}, "y": {"type": "array", "items": {"type": "integer"}}, }, "required": ["x", "y"], }, }, } @pytest.mark.parametrize("use_union_operator", [False, True]) def test_union(use_union_operator): class Example(msgspec.Struct): x: int y: int if use_union_operator: try: typ = int | str | Example except TypeError: pytest.skip("Union operator not supported") else: typ = Union[int, str, Example] assert msgspec.json.schema(typ) == { "anyOf": [ {"type": "integer"}, {"type": "string"}, {"$ref": "#/$defs/Example"}, ], "$defs": { "Example": { "title": "Example", "type": "object", "properties": {"x": {"type": "integer"}, "y": {"type": "integer"}}, "required": ["x", "y"], } }, } def test_struct_tagged_union(): class Point(msgspec.Struct, tag=True): x: int y: int class Point3D(Point): z: int assert msgspec.json.schema(Union[Point, Point3D]) == { "anyOf": [{"$ref": "#/$defs/Point"}, {"$ref": "#/$defs/Point3D"}], "discriminator": { "mapping": {"Point": "#/$defs/Point", "Point3D": "#/$defs/Point3D"}, "propertyName": "type", }, "$defs": { "Point": { "properties": { "type": {"enum": ["Point"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["type", "x", "y"], "title": "Point", "type": "object", }, "Point3D": { "properties": { "type": {"enum": ["Point3D"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, "z": {"type": "integer"}, }, "required": ["type", "x", "y", "z"], "title": "Point3D", "type": "object", }, }, } def test_struct_tagged_union_mixed_types(): class Point(msgspec.Struct, tag=True): x: int y: int class Point3D(Point): z: int assert msgspec.json.schema(Union[Point, Point3D, int, float]) == { "anyOf": [ {"type": "integer"}, {"type": "number"}, { "anyOf": [{"$ref": "#/$defs/Point"}, {"$ref": "#/$defs/Point3D"}], "discriminator": { "mapping": {"Point": "#/$defs/Point", "Point3D": "#/$defs/Point3D"}, "propertyName": "type", }, }, ], "$defs": { "Point": { "properties": { "type": {"enum": ["Point"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["type", "x", "y"], "title": "Point", "type": "object", }, "Point3D": { "properties": { "type": {"enum": ["Point3D"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, "z": {"type": "integer"}, }, "required": ["type", "x", "y", "z"], "title": "Point3D", "type": "object", }, }, } def test_struct_array_union(): class Point(msgspec.Struct, array_like=True, tag=True): x: int y: int class Point3D(Point): z: int assert msgspec.json.schema(Union[Point, Point3D]) == { "anyOf": [{"$ref": "#/$defs/Point"}, {"$ref": "#/$defs/Point3D"}], "$defs": { "Point": { "minItems": 3, "prefixItems": [ {"enum": ["Point"]}, {"type": "integer"}, {"type": "integer"}, ], "title": "Point", "type": "array", }, "Point3D": { "minItems": 4, "prefixItems": [ {"enum": ["Point3D"]}, {"type": "integer"}, {"type": "integer"}, {"type": "integer"}, ], "title": "Point3D", "type": "array", }, }, } def test_struct_unset_fields(): class Ex(msgspec.Struct): x: Union[int, msgspec.UnsetType] = msgspec.UNSET assert msgspec.json.schema(Ex) == { "$ref": "#/$defs/Ex", "$defs": { "Ex": { "properties": {"x": {"type": "integer"}}, "required": [], "title": "Ex", "type": "object", } }, } def test_generic_struct(): class Ex(msgspec.Struct, Generic[T]): """An example docstring""" x: T y: List[T] assert msgspec.json.schema(Ex) == { "$ref": "#/$defs/Ex", "$defs": { "Ex": { "title": "Ex", "description": "An example docstring", "type": "object", "properties": { "x": {}, "y": {"type": "array"}, }, "required": ["x", "y"], }, }, } assert msgspec.json.schema(Ex[int]) == { "$ref": "#/$defs/Ex_int_", "$defs": { "Ex_int_": { "title": "Ex[int]", "description": "An example docstring", "type": "object", "properties": { "x": {"type": "integer"}, "y": {"type": "array", "items": {"type": "integer"}}, }, "required": ["x", "y"], }, }, } def test_generic_struct_tagged_union(): class Point(msgspec.Struct, Generic[T], tag=True): x: T y: T class Point3D(Point[T]): z: T sol = { "anyOf": [{"$ref": "#/$defs/Point_int_"}, {"$ref": "#/$defs/Point3D_int_"}], "discriminator": { "mapping": { "Point": "#/$defs/Point_int_", "Point3D": "#/$defs/Point3D_int_", }, "propertyName": "type", }, "$defs": { "Point_int_": { "properties": { "type": {"enum": ["Point"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, }, "required": ["type", "x", "y"], "title": "Point[int]", "type": "object", }, "Point3D_int_": { "properties": { "type": {"enum": ["Point3D"]}, "x": {"type": "integer"}, "y": {"type": "integer"}, "z": {"type": "integer"}, }, "required": ["type", "x", "y", "z"], "title": "Point3D[int]", "type": "object", }, }, } res = msgspec.json.schema(Union[Point[int], Point3D[int]]) assert res == sol @pytest.mark.parametrize( "field, constraint", [ ("ge", "minimum"), ("gt", "exclusiveMinimum"), ("le", "maximum"), ("lt", "exclusiveMaximum"), ("multiple_of", "multipleOf"), ], ) def test_numeric_metadata(field, constraint): typ = Annotated[int, Meta(**{field: 2})] assert msgspec.json.schema(typ) == {"type": "integer", constraint: 2} @pytest.mark.parametrize( "field, val, constraint", [ ("pattern", "[a-z]*", "pattern"), ("min_length", 0, "minLength"), ("max_length", 3, "maxLength"), ], ) def test_string_metadata(field, val, constraint): typ = Annotated[str, Meta(**{field: val})] assert msgspec.json.schema(typ) == {"type": "string", constraint: val} @pytest.mark.parametrize( "field, val, constraint", [ ("pattern", "[a-z]*", "pattern"), ("min_length", 0, "minLength"), ("max_length", 3, "maxLength"), ], ) def test_dict_key_metadata(field, val, constraint): typ = Annotated[str, Meta(**{field: val})] assert msgspec.json.schema(Dict[typ, int]) == { "type": "object", "additionalProperties": {"type": "integer"}, "propertyNames": {constraint: val}, } @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) @pytest.mark.parametrize( "field, n, constraint", [("min_length", 2, "minLength"), ("max_length", 7, "maxLength")], ) def test_binary_metadata(typ, field, n, constraint): n2 = len(b64encode(b"x" * n)) typ = Annotated[typ, Meta(**{field: n})] assert msgspec.json.schema(typ) == { "type": "string", constraint: n2, "contentEncoding": "base64", } @pytest.mark.parametrize("typ", [list, tuple, set, frozenset]) @pytest.mark.parametrize( "field, constraint", [("min_length", "minItems"), ("max_length", "maxItems")], ) def test_array_metadata(typ, field, constraint): typ = Annotated[typ, Meta(**{field: 2})] assert msgspec.json.schema(typ) == {"type": "array", constraint: 2} @pytest.mark.parametrize( "field, constraint", [("min_length", "minProperties"), ("max_length", "maxProperties")], ) def test_object_metadata(field, constraint): typ = Annotated[dict, Meta(**{field: 2})] assert msgspec.json.schema(typ) == {"type": "object", constraint: 2} def test_generic_metadata(): typ = Annotated[ int, Meta( title="the title", description="the description", examples=[1, 2, 3], extra_json_schema={"title": "an override", "default": 1}, ), ] assert msgspec.json.schema(typ) == { "type": "integer", "title": "an override", "description": "the description", "examples": [1, 2, 3], "default": 1, } def test_component_names_collide(): s1 = """ import msgspec Ex = msgspec.defstruct("Ex", [("x", int), ("y", int)]) """ s2 = """ import msgspec Ex = msgspec.defstruct("Ex", [("a", str), ("b", str)]) """ with temp_module(s1) as m1, temp_module(s2) as m2: (r1, r2), components = msgspec.json.schema_components([m1.Ex, m2.Ex]) assert r1 == {"$ref": f"#/$defs/{m1.__name__}.Ex"} assert r2 == {"$ref": f"#/$defs/{m2.__name__}.Ex"} assert components == { f"{m1.__name__}.Ex": { "properties": {"x": {"type": "integer"}, "y": {"type": "integer"}}, "required": ["x", "y"], "title": "Ex", "type": "object", }, f"{m2.__name__}.Ex": { "properties": {"a": {"type": "string"}, "b": {"type": "string"}}, "required": ["a", "b"], "title": "Ex", "type": "object", }, } def test_schema_components_collects_subtypes(): class ExEnum(enum.Enum): A = 1 class ExStruct(msgspec.Struct): b: Union[Set[FrozenSet[ExEnum]], int] class ExDict(TypedDict): c: Tuple[ExStruct, ...] class ExTuple(NamedTuple): d: List[ExDict] @dataclass class ExDataclass: e: List[ExTuple] (s,), components = msgspec.json.schema_components([Dict[str, ExDataclass]]) r1 = {"$ref": "#/$defs/ExEnum"} r2 = {"$ref": "#/$defs/ExStruct"} r3 = {"$ref": "#/$defs/ExDict"} r4 = {"$ref": "#/$defs/ExTuple"} r5 = {"$ref": "#/$defs/ExDataclass"} assert s == {"type": "object", "additionalProperties": r5} assert components == { "ExEnum": {"enum": [1], "title": "ExEnum"}, "ExStruct": { "type": "object", "title": "ExStruct", "properties": { "b": { "anyOf": [ {"items": {"items": r1, "type": "array"}, "type": "array"}, {"type": "integer"}, ] } }, "required": ["b"], }, "ExDict": { "title": "ExDict", "type": "object", "properties": {"c": {"items": r2, "type": "array"}}, "required": ["c"], }, "ExTuple": { "title": "ExTuple", "type": "array", "prefixItems": [{"items": r3, "type": "array"}], "maxItems": 1, "minItems": 1, }, "ExDataclass": { "title": "ExDataclass", "type": "object", "properties": {"e": {"items": r4, "type": "array"}}, "required": ["e"], }, } def test_ref_template(): class Ex1(msgspec.Struct): a: int class Ex2(msgspec.Struct): b: Ex1 (s1, s2), components = msgspec.json.schema_components( [Ex1, Ex2], ref_template="#/definitions/{name}" ) assert s1 == {"$ref": "#/definitions/Ex1"} assert s2 == {"$ref": "#/definitions/Ex2"} assert components == { "Ex1": { "title": "Ex1", "type": "object", "properties": {"a": {"type": "integer"}}, "required": ["a"], }, "Ex2": { "title": "Ex2", "type": "object", "properties": {"b": s1}, "required": ["b"], }, } def test_multiline_docstring(): class Example(msgspec.Struct): """ indented first line last line. """ pass assert msgspec.json.schema(Example) == { "$ref": "#/$defs/Example", "$defs": { "Example": { "description": " indented first line\n\nlast line.", "title": "Example", "type": "object", "properties": {}, "required": [], } }, } python-msgspec-0.19.0/tests/test_struct.py000066400000000000000000002164151473355726200207070ustar00rootroot00000000000000import copy import datetime import enum import gc import operator import pickle import sys import weakref from contextlib import contextmanager from inspect import Parameter, Signature from typing import Any, List, Optional, Generic, TypeVar import pytest from utils import temp_module import msgspec from msgspec import NODEFAULT, UNSET, Struct, defstruct, field from msgspec.structs import StructConfig if hasattr(copy, "replace"): # Added in Python 3.13 copy_replace = copy.replace else: def copy_replace(s, **changes): return s.__replace__(**changes) @contextmanager def nogc(): """Temporarily disable GC""" try: gc.disable() yield finally: gc.enable() class Fruit(enum.IntEnum): APPLE = 1 BANANA = 2 def as_tuple(x): return tuple(getattr(x, f) for f in x.__struct_fields__) @pytest.mark.parametrize("obj, str_obj", [(UNSET, "UNSET"), (NODEFAULT, "NODEFAULT")]) def test_singletons(obj, str_obj): assert str(obj) == str_obj assert pickle.loads(pickle.dumps(obj)) is obj cls = type(obj) assert cls() is obj with pytest.raises(TypeError): cls(1) with pytest.raises(TypeError): cls(foo=1) if obj is UNSET: assert bool(obj) is False else: assert bool(obj) is True def test_field(): f1 = msgspec.field() assert f1.default is NODEFAULT assert f1.default_factory is NODEFAULT assert f1.name is None f2 = msgspec.field(default=1) assert f2.default == 1 assert f2.default_factory is NODEFAULT assert f2.name is None f3 = msgspec.field(default_factory=int) assert f3.default is NODEFAULT assert f3.default_factory is int assert f3.name is None f4 = msgspec.field(name="foo") assert f4.name == "foo" f5 = msgspec.field(name=None) assert f5.name is None with pytest.raises(TypeError, match="Cannot set both"): msgspec.field(default=1, default_factory=int) with pytest.raises(TypeError, match="must be callable"): msgspec.field(default_factory=1) with pytest.raises(TypeError, match="must be a str or None"): msgspec.field(name=b"bad") def test_struct_class_attributes(): assert Struct.__struct_fields__ == () assert Struct.__struct_encode_fields__ == () assert Struct.__struct_defaults__ == () assert Struct.__match_args__ == () assert Struct.__slots__ == () assert Struct.__module__ == "msgspec" assert isinstance(Struct.__struct_config__, StructConfig) def test_struct_class_and_instance_dir(): expected = {"__struct_fields__", "__struct_config__"} assert expected.issubset(dir(Struct)) assert expected.issubset(dir(Struct())) def test_struct_instance_attributes(): class Test(Struct): c: int b: float a: str = "hello" x = Test(1, 2.0, a="goodbye") assert x.__struct_fields__ == ("c", "b", "a") assert x.__struct_encode_fields__ == ("c", "b", "a") assert x.__struct_fields__ is x.__struct_encode_fields__ assert x.__struct_defaults__ == ("hello",) assert x.__slots__ == ("a", "b", "c") assert isinstance(x.__struct_config__, StructConfig) assert x.c == 1 assert x.b == 2.0 assert x.a == "goodbye" def test_struct_subclass_forbids_init_new_slots(): with pytest.raises(TypeError, match="__init__"): class Test1(Struct): a: int def __init__(self, a): pass with pytest.raises(TypeError, match="__new__"): class Test2(Struct): a: int def __new__(self, a): pass with pytest.raises(TypeError, match="__slots__"): class Test3(Struct): __slots__ = ("a",) a: int def test_struct_subclass_forbidden_field_names(): with pytest.raises( TypeError, match="Cannot have a struct field named '__weakref__'" ): class Test1(Struct): __weakref__: int with pytest.raises(TypeError, match="Cannot have a struct field named '__dict__'"): class Test2(Struct): __dict__: int with pytest.raises( TypeError, match="Cannot have a struct field named '__msgspec_cached_hash__'" ): class Test3(Struct): __msgspec_cached_hash__: int class TestMixins: def test_mixin_no_slots(self): class Mixin(object): def method(self): pass class Test1(Struct, Mixin): pass assert issubclass(Test1, Mixin) assert Test1.__dictoffset__ != 0 assert Test1.__weakrefoffset__ != 0 class Test2(Struct, Mixin, dict=True, weakref=True): pass assert Test2.__dictoffset__ != 0 assert Test2.__weakrefoffset__ != 0 def test_mixin_slots(self): class Mixin(object): __slots__ = () def method(self): pass class Test1(Struct, Mixin): pass assert issubclass(Test1, Mixin) assert Test1.__dictoffset__ == 0 assert Test1.__weakrefoffset__ == 0 class Test2(Struct, Mixin, dict=True, weakref=True): pass assert Test2.__dictoffset__ != 0 assert Test2.__weakrefoffset__ != 0 def test_mixin_nonempty_slots(self): class Mixin(object): __slots__ = "_state" def method(self): try: return self._state except AttributeError: self._state = self.x + 1 return self._state class Test(Struct, Mixin): x: int assert Test.__dictoffset__ == 0 t = Test(1) assert t.method() == 2 assert t.method() == 2 def test_mixin_forbids_init(self): class Mixin(object): def __init__(self): pass with pytest.raises(TypeError, match="cannot define __init__"): class Test(Struct, Mixin): pass def test_mixin_forbids_new(self): class Mixin(object): def __new__(self): pass with pytest.raises(TypeError, match="cannot define __new__"): class Test(Struct, Mixin): pass def test_mixin_builtin_type_errors(self): with pytest.raises(TypeError): class Test(Struct, Exception): pass def test_struct_subclass_forbids_non_types(): # Currently this failcase is handled by CPython's internals, but it's good # to make sure this user error actually errors. class Foo: pass with pytest.raises(TypeError): class Test(msgspec.Struct, Foo()): pass def test_struct_subclass_forbids_mixed_layouts(): class A(Struct): a: int b: int class B(Struct): c: int d: int # This error is raised by cpython with pytest.raises(TypeError, match="lay-out conflict"): class C(A, B): pass def test_struct_errors_nicely_if_used_in_init_subclass(): ran = False class Test(Struct): def __init_subclass__(cls): # Class attributes aren't yet defined, error nicely for attr in [ "__struct_fields__", "__struct_encode_fields__", "__match_args__", "__struct_defaults__", ]: with pytest.raises(AttributeError): getattr(cls, attr) # Init doesn't work with pytest.raises(Exception): cls() # Decoder/decode doesn't work for proto in [msgspec.json, msgspec.msgpack]: with pytest.raises(ValueError, match="isn't fully defined"): proto.Decoder(cls) with pytest.raises(ValueError, match="isn't fully defined"): proto.decode(b"", type=cls) nonlocal ran ran = True class Subclass(Test): x: int assert ran class TestStructParameterOrdering: """Tests for parsing parameter types & defaults from one or more class definitions.""" def test_no_args(self): class Test(Struct): pass assert Test.__struct_fields__ == () assert Test.__struct_defaults__ == () assert Test.__match_args__ == () assert Test.__slots__ == () def test_all_positional(self): class Test(Struct): y: float x: int assert Test.__struct_fields__ == ("y", "x") assert Test.__struct_defaults__ == () assert Test.__match_args__ == ("y", "x") assert Test.__slots__ == ("x", "y") def test_all_positional_with_defaults(self): class Test(Struct): y: int = 1 x: float = 2.0 assert Test.__struct_fields__ == ("y", "x") assert Test.__struct_defaults__ == (1, 2.0) assert Test.__match_args__ == ("y", "x") assert Test.__slots__ == ("x", "y") def test_subclass_no_change(self): class Test(Struct): y: float x: int class Test2(Test): pass assert Test2.__struct_fields__ == ("y", "x") assert Test2.__struct_defaults__ == () assert Test2.__match_args__ == ("y", "x") assert Test2.__slots__ == () def test_subclass_extends(self): class Test(Struct): c: int b: float d: int = 1 a: float = 2.0 class Test2(Test): e: str = "3.0" f: float = 4.0 assert Test2.__struct_fields__ == ("c", "b", "d", "a", "e", "f") assert Test2.__struct_defaults__ == (1, 2.0, "3.0", 4.0) assert Test2.__match_args__ == ("c", "b", "d", "a", "e", "f") assert Test2.__slots__ == ("e", "f") def test_subclass_overrides(self): class Test(Struct): c: int b: int d: int = 1 a: float = 2.0 class Test2(Test): b: float = 3 # switch to keyword, change type d: int = 4 # change default e: float = 5.0 # new assert Test2.__struct_fields__ == ("c", "b", "d", "a", "e") assert Test2.__struct_defaults__ == (3, 4, 2.0, 5.0) assert Test2.__match_args__ == ("c", "b", "d", "a", "e") assert Test2.__slots__ == ("e",) def test_subclass_with_mixin(self): class A(Struct): b: int a: float = 1.0 class Mixin(Struct): pass class B(A, Mixin): a: float = 2.0 assert B.__struct_fields__ == ("b", "a") assert B.__struct_defaults__ == (2.0,) assert B.__match_args__ == ("b", "a") assert B.__slots__ == () def test_positional_after_keyword_errors(self): with pytest.raises(TypeError) as rec: class Test(Struct): a: int b: int = 1 c: float assert "Required field 'c' cannot follow optional fields" in str(rec.value) def test_positional_after_keyword_subclass_errors(self): class Base(Struct): a: int b: int = 1 with pytest.raises(TypeError) as rec: class Test(Base): c: float assert "Required field 'c' cannot follow optional fields" in str(rec.value) def test_kw_only_positional(self): class Test(Struct, kw_only=True): b: int a: int assert Test.__struct_fields__ == ("b", "a") assert Test.__struct_defaults__ == () assert Test.__match_args__ == () assert Test.__slots__ == ("a", "b") def test_kw_only_mixed(self): class Test(Struct, kw_only=True): b: int a: int = 0 c: int d: int = 1 assert Test.__struct_fields__ == ("b", "a", "c", "d") assert Test.__struct_defaults__ == (0, NODEFAULT, 1) assert Test.__match_args__ == () assert Test.__slots__ == ("a", "b", "c", "d") def test_kw_only_positional_base_class(self): class Base(Struct, kw_only=True): b: int a: int class S1(Base): d: int c: int class S2(Base): d: int c: int = 1 assert S1.__struct_fields__ == ("d", "c", "b", "a") assert S1.__struct_defaults__ == () assert S1.__match_args__ == ("d", "c") assert S1.__slots__ == ("c", "d") assert S2.__struct_fields__ == ("d", "c", "b", "a") assert S2.__struct_defaults__ == (1, NODEFAULT, NODEFAULT) assert S2.__match_args__ == ("d", "c") assert S2.__slots__ == ("c", "d") def test_kw_only_base_class(self): class Base(Struct, kw_only=True): b: int = 1 a: int class S1(Base): d: int c: int = 2 assert S1.__struct_fields__ == ("d", "c", "b", "a") assert S1.__struct_defaults__ == (2, 1, NODEFAULT) assert S1.__match_args__ == ("d", "c") assert S1.__slots__ == ("c", "d") def test_kw_only_subclass(self): class Base(Struct): b: int a: int class S1(Base, kw_only=True): d: int c: int assert S1.__struct_fields__ == ("b", "a", "d", "c") assert S1.__struct_defaults__ == () assert S1.__match_args__ == ("b", "a") assert S1.__slots__ == ("c", "d") def test_kw_only_defaults_subclass(self): class Base(Struct): b: int a: int = 0 class S1(Base, kw_only=True): d: int c: int = 1 assert S1.__struct_fields__ == ("b", "a", "d", "c") assert S1.__struct_defaults__ == (0, NODEFAULT, 1) assert S1.__match_args__ == ("b", "a") assert S1.__slots__ == ("c", "d") def test_kw_only_overrides(self): class Base(Struct): b: int a: int = 2 class S1(Base, kw_only=True): b: int c: int = 3 assert S1.__struct_fields__ == ("a", "b", "c") assert S1.__struct_defaults__ == (2, NODEFAULT, 3) assert S1.__match_args__ == ("a",) assert S1.__slots__ == ("c",) def test_kw_only_overridden(self): class Base(Struct, kw_only=True): b: int a: int = 2 class S1(Base): b: int c: int = 3 assert S1.__struct_fields__ == ("b", "c", "a") assert S1.__struct_defaults__ == (3, 2) assert S1.__match_args__ == ("b", "c") assert S1.__slots__ == ("c",) class TestStructInit: def test_init_positional(self): class Test(Struct): a: int b: float c: int = 3 d: float = 4.0 assert as_tuple(Test(1, 2.0)) == (1, 2.0, 3, 4.0) assert as_tuple(Test(1, b=2.0)) == (1, 2.0, 3, 4.0) assert as_tuple(Test(a=1, b=2.0)) == (1, 2.0, 3, 4.0) assert as_tuple(Test(1, b=2.0, c=5)) == (1, 2.0, 5, 4.0) assert as_tuple(Test(1, b=2.0, d=5.0)) == (1, 2.0, 3, 5.0) assert as_tuple(Test(1, 2.0, 5)) == (1, 2.0, 5, 4.0) assert as_tuple(Test(1, 2.0, 5, 6.0)) == (1, 2.0, 5, 6.0) with pytest.raises(TypeError, match="Missing required argument 'a'"): Test() with pytest.raises(TypeError, match="Missing required argument 'b'"): Test(1) with pytest.raises(TypeError, match="Extra positional arguments provided"): Test(1, 2, 3, 4, 5) with pytest.raises(TypeError, match="Argument 'a' given by name and position"): Test(1, 2, a=3) with pytest.raises(TypeError, match="Unexpected keyword argument 'e'"): Test(1, 2, e=5) def test_init_kw_only(self): class Test(Struct, kw_only=True): a: int b: float = 2.0 c: int = 3 assert as_tuple(Test(a=1)) == (1, 2.0, 3) assert as_tuple(Test(a=1, b=4.0)) == (1, 4.0, 3) assert as_tuple(Test(a=1, c=4)) == (1, 2.0, 4) assert as_tuple(Test(a=1, b=4.0, c=5)) == (1, 4.0, 5) with pytest.raises(TypeError, match="Missing required argument 'a'"): Test() with pytest.raises(TypeError, match="Extra positional arguments provided"): Test(1) with pytest.raises(TypeError, match="Unexpected keyword argument 'e'"): Test(a=1, e=5) def test_init_kw_only_mixed(self): class Base(Struct, kw_only=True): c: int = 3 d: float = 4.0 class Test(Base): a: int b: float = 2.0 assert as_tuple(Test(1)) == (1, 2.0, 3, 4.0) assert as_tuple(Test(1, 5.0)) == (1, 5.0, 3, 4.0) assert as_tuple(Test(a=1)) == (1, 2.0, 3, 4.0) assert as_tuple(Test(a=1, b=5.0)) == (1, 5.0, 3, 4.0) assert as_tuple(Test(1, c=5)) == (1, 2.0, 5, 4.0) with pytest.raises(TypeError, match="Missing required argument 'a'"): Test() with pytest.raises(TypeError, match="Argument 'a' given by name and position"): Test(1, b=3.0, c=4, a=3) with pytest.raises(TypeError, match="Extra positional arguments provided"): Test(1, 5.0, 3) with pytest.raises(TypeError, match="Unexpected keyword argument 'e'"): Test(1, e=5) class TestSignature: def test_signature_no_args(self): class Test(Struct): pass sig = Signature(parameters=[]) assert Test.__signature__ == sig def test_signature_positional(self): class Test(Struct): b: float a: int = 1 sig = Signature( parameters=[ Parameter("b", Parameter.POSITIONAL_OR_KEYWORD, annotation=float), Parameter( "a", Parameter.POSITIONAL_OR_KEYWORD, default=1, annotation=int, ), ] ) assert Test.__signature__ == sig def test_signature_kw_only(self): class Base(Struct, kw_only=True): c: float d: int = 2 class Test(Base): b: float a: int = 1 sig = Signature( parameters=[ Parameter("b", Parameter.POSITIONAL_OR_KEYWORD, annotation=float), Parameter( "a", Parameter.POSITIONAL_OR_KEYWORD, default=1, annotation=int, ), Parameter("c", Parameter.KEYWORD_ONLY, annotation=float), Parameter("d", Parameter.KEYWORD_ONLY, default=2, annotation=int), ] ) assert Test.__signature__ == sig class TestRepr: def test_repr_base(self): x = Struct() assert repr(x) == "Struct()" assert x.__rich_repr__() == [] def test_repr_empty(self): class Test(Struct): pass x = Test() assert repr(x) == "Test()" assert x.__rich_repr__() == [] def test_repr_one_field(self): class Test(Struct): a: int x = Test(1) assert repr(x) == "Test(a=1)" assert x.__rich_repr__() == [("a", 1)] def test_repr_two_fields(self): class Test(Struct): a: int b: str x = Test(1, "y") assert repr(x) == "Test(a=1, b='y')" assert x.__rich_repr__() == [("a", 1), ("b", "y")] def test_repr_omit_defaults_empty(self): class Test(Struct, repr_omit_defaults=True): pass x = Test() assert repr(x) == "Test()" assert x.__rich_repr__() == [] def test_repr_omit_defaults_one_field(self): class Test(Struct, repr_omit_defaults=True): a: int = 0 x = Test(0) assert repr(x) == "Test()" assert x.__rich_repr__() == [] x = Test(1) assert repr(x) == "Test(a=1)" assert x.__rich_repr__() == [("a", 1)] def test_repr_omit_defaults_multiple_fields(self): class Test(Struct, repr_omit_defaults=True): a: int b: int = 0 c: str = "" x = Test(0) assert repr(x) == "Test(a=0)" assert x.__rich_repr__() == [("a", 0)] x = Test(0, b=1) assert repr(x) == "Test(a=0, b=1)" assert x.__rich_repr__() == [("a", 0), ("b", 1)] x = Test(0, c="two") assert repr(x) == "Test(a=0, c='two')" assert x.__rich_repr__() == [("a", 0), ("c", "two")] x = Test(0, b=1, c="two") assert repr(x) == "Test(a=0, b=1, c='two')" assert x.__rich_repr__() == [("a", 0), ("b", 1), ("c", "two")] def test_repr_recursive(self): class Test(Struct): a: int b: Any t = Test(1, Test(2, None)) t.b.b = t assert repr(t) == "Test(a=1, b=Test(a=2, b=...))" def test_repr_missing_attr_errors(self): class Test(Struct): a: int b: str t = Test(1, "hello") del t.b with pytest.raises(AttributeError): repr(t) with pytest.raises(AttributeError): t.__rich_repr__() def test_repr_errors(self): msg = "Oh no!" class Bad: def __repr__(self): raise ValueError(msg) class Test(Struct): a: object b: object t = Test(1, Bad()) with pytest.raises(ValueError, match=msg): repr(t) def test_struct_copy(): x = copy.copy(Struct()) assert type(x) is Struct class Test(Struct): b: int a: int x = copy.copy(Test(1, 2)) assert type(x) is Test assert x.b == 1 assert x.a == 2 class FrozenPoint(Struct, frozen=True): x: int y: int @pytest.mark.parametrize( "default", [ None, False, True, 1, 2.0, 1.5 + 2.32j, b"test", "test", (), frozenset(), frozenset((1, (2, 3, 4), 5)), Fruit.APPLE, datetime.time(1), datetime.date.today(), datetime.timedelta(seconds=2), datetime.datetime.now(), FrozenPoint(1, 2), ], ) def test_struct_immutable_defaults_use_instance(default): class Test(Struct): value: object = default t = Test() assert t.value is default @pytest.mark.parametrize("default", [[], {}, set()]) def test_struct_empty_mutable_defaults_fast_copy(default): class Test(Struct): value: object = default t = Test() assert t.value == default assert t.value is not default class Point(Struct): x: int y: int class PointKWOnly(Struct, kw_only=True): x: int y: int @pytest.mark.parametrize("default", [[], {}, set(), bytearray()]) def test_struct_empty_mutable_defaults_work(default): class Test(Struct): value: object = default x = Test().value x == default assert x is not default @pytest.mark.parametrize( "default", [Point(1, 2), [1], {"a": "b"}, {1, 2}, bytearray(b"test")], ) def test_struct_nonempty_mutable_defaults_error(default): with pytest.raises(TypeError) as rec: class Test(Struct): value: object = default assert "as a default value is unsafe" in str(rec.value) assert repr(default) in str(rec.value) def test_struct_defaults_from_field(): default = [] class Test(Struct): req: int = field() x: int = field(default=1) y: int = field(default_factory=lambda: 2) z: List[int] = field(default=default) t = Test(100) assert t.req == 100 assert t.x == 1 assert t.y == 2 assert t.z == [] assert t.z is not default def test_struct_default_factory_errors(): def bad(): raise ValueError("Oh no") class Test(Struct): x: int = field(default_factory=bad) with pytest.raises(ValueError): Test() def test_struct_reference_counting(): """Test that struct operations that access fields properly decref""" class Test(Struct): value: list data = [1, 2, 3] t = Test(data) assert sys.getrefcount(data) == 3 repr(t) assert sys.getrefcount(data) == 3 t2 = t.__copy__() assert sys.getrefcount(data) == 4 assert t == t2 assert sys.getrefcount(data) == 4 def test_struct_gc_not_added_if_not_needed(): """Structs aren't tracked by GC until/unless they reference a container type""" class Test(Struct): x: object y: object assert not gc.is_tracked(Test(1, 2)) assert not gc.is_tracked(Test("hello", "world")) assert gc.is_tracked(Test([1, 2, 3], 1)) assert gc.is_tracked(Test(1, [1, 2, 3])) # Tuples are all tracked on creation, but through GC passes eventually # become untracked if they don't contain tracked types untracked_tuple = (1, 2, 3) for i in range(5): gc.collect() if not gc.is_tracked(untracked_tuple): break else: assert False, "something has changed with Python's GC, investigate" assert not gc.is_tracked(Test(1, untracked_tuple)) tracked_tuple = ([],) assert gc.is_tracked(Test(1, tracked_tuple)) # On mutation, if a tracked objected is stored on a struct, an untracked # struct will become tracked t = Test(1, 2) assert not gc.is_tracked(t) t.x = 3 assert not gc.is_tracked(t) t.x = untracked_tuple assert not gc.is_tracked(t) t.x = [] assert gc.is_tracked(t) # An error in setattr doesn't change tracked status t = Test(1, 2) assert not gc.is_tracked(t) with pytest.raises(AttributeError): t.z = [] assert not gc.is_tracked(t) class TestStructGC: def test_memory_layout(self): sizes = {} for has_gc in [False, True]: class Test(Struct, gc=has_gc): x: object y: object sizes[has_gc] = sys.getsizeof(Test(1, 2)) # Currently gc=False structs are 16 bytes smaller than gc=True structs, # but that's a cpython implementation detail. This test is mainly to # check that the smaller layout is being actually used. assert sizes[False] < sizes[True] def test_init(self): class Test(Struct, gc=False): x: object y: object assert not gc.is_tracked(Test(1, 2)) assert not gc.is_tracked(Test([1, 2, 3], 1)) assert not gc.is_tracked(Test(1, [1, 2, 3])) def test_setattr(self): class Test(Struct, gc=False): x: object y: object # Tracked status doesn't change on mutation t = Test(1, 2) assert not gc.is_tracked(t) t.x = [] assert not gc.is_tracked(t) def test_gc_false_inherit_from_gc_true(self): class HasGC(Struct): x: object class NoGC(HasGC, gc=False): y: object assert gc.is_tracked(HasGC([])) assert not gc.is_tracked(NoGC(1, 2)) assert not gc.is_tracked(NoGC(1, [])) x = NoGC([], 2) assert not gc.is_tracked(x) x.y = [] assert not gc.is_tracked(x) def test_gc_true_inherit_from_gc_false(self): class NoGC(Struct, gc=False): y: object class HasGC(NoGC, gc=True): x: object assert gc.is_tracked(HasGC(1, [])) assert gc.is_tracked(HasGC([], 1)) x = HasGC(1, 2) assert not gc.is_tracked(x) x.x = [] assert gc.is_tracked(x) @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_gc_set_on_copy(self, has_gc): """Copying doesn't go through the struct constructor""" class Test(Struct, gc=has_gc): x: object y: object assert not gc.is_tracked(copy.copy(Test(1, 2))) assert not gc.is_tracked(copy.copy(Test(1, ()))) assert gc.is_tracked(copy.copy(Test(1, []))) == has_gc def test_struct_gc_false_cannot_inherit_from_non_slots_classes(self): class Base: pass with pytest.raises( ValueError, match="Cannot set gc=False when inheriting from non-struct types with a __dict__", ): class Test(Struct, Base, gc=False): pass def test_struct_gc_false_can_inherit_from_slots_class_mixin(self): class Base: __slots__ = () class Test(Struct, Base, gc=False): x: int t = Test(1) assert not gc.is_tracked(t) @pytest.mark.parametrize("case", ["base-dict", "base-nogc", "nobase"]) def test_struct_gc_false_forbids_dict_true(self, case): if case == "base-dict": class Base(Struct, dict=True): pass opts = {"gc": False} elif case == "base-nogc": class Base(Struct, gc=False): pass opts = {"dict": True} elif case == "nobase": Base = Struct opts = {"gc": False, "dict": True} with pytest.raises(ValueError, match="Cannot set gc=False and dict=True"): class Test(Base, **opts): pass class TestStructDealloc: @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_decrefs_type(self, has_gc): class Test1(Struct, gc=has_gc): x: int y: int class Test2(Struct, gc=has_gc): x: int y: int with nogc(): orig_1 = sys.getrefcount(Test1) orig_2 = sys.getrefcount(Test2) t = Test1(1, 2) assert sys.getrefcount(Test1) == orig_1 + 1 del t assert sys.getrefcount(Test1) == orig_1 t = Test2(1, 2) assert sys.getrefcount(Test1) == orig_1 assert sys.getrefcount(Test2) == orig_2 + 1 del t assert sys.getrefcount(Test1) == orig_1 assert sys.getrefcount(Test2) == orig_2 gc.collect() assert sys.getrefcount(Test1) == orig_1 assert sys.getrefcount(Test2) == orig_2 @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_calls_finalizer(self, has_gc): for _ in range(3): called = False class Test(Struct, gc=has_gc): x: int y: int def __del__(self): nonlocal called called = True t = Test(1, 2) if hasattr(gc, "is_finalized"): assert not gc.is_finalized(t) del t assert called @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_supports_finalizer_resurrection(self, has_gc): for _ in range(3): called = False new_ref = None class Test(Struct, gc=has_gc): x: int y: int def __del__(self): # XXX: Python will only run `__del__` once, even if it's # resurrected FOR GC TYPES ONLY. If gc=False, cpython will # happily run `__del__` every time the refcount drops to 0 nonlocal called nonlocal new_ref if not called: called = True new_ref = self t = Test(1, 2) del t assert called assert new_ref is not None del new_ref @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_trashcan(self, has_gc): N = 100 called = set() class Node(Struct, gc=has_gc): child: "Optional[Node]" = None def __del__(self): called.add(id(self)) node = None for _ in range(N): node = Node(node) del node assert len(called) == N @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_decrefs_fields(self, has_gc): class Test(Struct, gc=has_gc): x: Any x = object() t = Test(x) count = sys.getrefcount(x) del t assert sys.getrefcount(x) == count - 1 @pytest.mark.parametrize("has_gc", [False, True]) def test_struct_dealloc_works_with_missing_fields(self, has_gc): class Test(Struct, gc=has_gc): x: Any y: Any x = object() t = Test(x, None) del t.y count = sys.getrefcount(x) del t assert sys.getrefcount(x) == count - 1 def test_struct_dealloc_dict(self): class Test(Struct, dict=True): x: int called = False class Flag: def __del__(self): nonlocal called called = True t = Test(1) t.flag = Flag() del t assert called def test_struct_dealloc_weakref(self): class Test(Struct, weakref=True): x: int t = Test(1) # smoketest dealloc weakrefable struct doesn't crash del t t = Test(1) ref = weakref.ref(t) assert ref() is not None del t assert ref() is None def test_struct_dealloc_in_gc_properly_handles_type_decref(self): def inner(): class Box(msgspec.Struct): a: Any gc.collect() o = Box(None) o.a = o for _ in range(5): inner() gc.collect() @pytest.mark.parametrize("kw_only", [False, True]) def test_struct_pickle(kw_only): cls = PointKWOnly if kw_only else Point a = cls(x=1, y=2) b = cls(x=3, y=4) assert pickle.loads(pickle.dumps(a)) == a assert pickle.loads(pickle.dumps(b)) == b del a.x with pytest.raises(AttributeError, match="Struct field 'x' is unset"): pickle.dumps(a) def test_struct_handles_missing_attributes(): """If an attribute is unset, raise an AttributeError appropriately""" class MyStruct(Struct): x: int y: int z: str = "default" t = MyStruct(1, 2) del t.y t2 = MyStruct(1, 2) match = "Struct field 'y' is unset" with pytest.raises(AttributeError, match=match): repr(t) with pytest.raises(AttributeError, match=match): copy.copy(t) with pytest.raises(AttributeError, match=match): t == t2 with pytest.raises(AttributeError, match=match): t2 == t @pytest.mark.parametrize( "option, default", [ ("frozen", False), ("order", False), ("eq", True), ("repr_omit_defaults", False), ("array_like", False), ("gc", True), ("omit_defaults", False), ("forbid_unknown_fields", False), ], ) def test_struct_option_precedence(option, default): def get(cls): return getattr(cls.__struct_config__, option) class Default(Struct): pass assert get(Default) is default class Enabled(Struct, **{option: True}): pass assert get(Enabled) is True class Disabled(Struct, **{option: False}): pass assert get(Disabled) is False class T(Enabled): pass assert get(T) is True class T(Enabled, **{option: False}): pass assert get(T) is False class T(Enabled, Default): pass assert get(T) is True class T(Default, Enabled): pass assert get(T) is True class T(Default, Disabled, Enabled): pass assert get(T) is False def test_weakref_option(): class Default(Struct): pass assert Default.__weakrefoffset__ == 0 class Enabled(Struct, weakref=True): pass assert Enabled.__weakrefoffset__ != 0 assert Enabled.__struct_config__.weakref class Disabled(Struct, weakref=False): pass assert Disabled.__weakrefoffset__ == 0 assert not Disabled.__struct_config__.weakref class T(Enabled): pass assert T.__weakrefoffset__ != 0 assert T.__struct_config__.weakref class T(Enabled, Default): pass assert T.__weakrefoffset__ != 0 assert T.__struct_config__.weakref class T(Default, Disabled, Enabled): pass assert T.__weakrefoffset__ != 0 assert T.__struct_config__.weakref with pytest.raises(ValueError, match="Cannot set `weakref=False`"): class T(Enabled, weakref=False): pass def test_dict_option(): class Default(Struct): pass assert Default.__dictoffset__ == 0 class Enabled(Struct, dict=True): pass assert Enabled.__dictoffset__ != 0 assert Enabled.__struct_config__.dict class Disabled(Struct, dict=False): pass assert Disabled.__dictoffset__ == 0 assert not Disabled.__struct_config__.dict class T(Enabled): pass assert T.__dictoffset__ != 0 assert T.__struct_config__.dict class T(Enabled, Default): pass assert T.__dictoffset__ != 0 assert T.__struct_config__.dict class T(Default, Disabled, Enabled): pass assert T.__dictoffset__ != 0 assert T.__struct_config__.dict with pytest.raises(ValueError, match="Cannot set `dict=False`"): class T(Enabled, dict=False): pass def test_cache_hash_option(): with pytest.raises( ValueError, match="Cannot set cache_hash=True without frozen=True" ): class Invalid(Struct, cache_hash=True): pass class Default(Struct, frozen=True): pass assert "__msgspec_cached_hash__" not in Default.__slots__ assert not Default.__struct_config__.cache_hash class Enabled(Struct, cache_hash=True, frozen=True): pass assert "__msgspec_cached_hash__" in Enabled.__slots__ assert Enabled.__struct_config__.cache_hash class Disabled(Struct, cache_hash=False, frozen=True): pass assert "__msgspec_cached_hash__" not in Disabled.__slots__ assert not Disabled.__struct_config__.cache_hash class T(Enabled): pass assert "__msgspec_cached_hash__" not in T.__slots__ assert T.__struct_config__.cache_hash class T(Enabled, Default): pass assert "__msgspec_cached_hash__" not in T.__slots__ assert T.__struct_config__.cache_hash class T(Default, Disabled, Enabled): pass assert "__msgspec_cached_hash__" not in T.__slots__ assert T.__struct_config__.cache_hash with pytest.raises(ValueError, match="Cannot set `cache_hash=False`"): class T(Enabled, cache_hash=False): pass def test_invalid_option_raises(): with pytest.raises(TypeError): class Foo(Struct, invalid=True): pass class FrozenPoint(Struct, frozen=True): x: int y: int class TestHash: def test_frozen_objects_hashable(self): p1 = FrozenPoint(1, 2) p2 = FrozenPoint(1, 2) p3 = FrozenPoint(1, 3) assert hash(p1) == hash(p2) assert hash(p1) != hash(p3) assert p1 == p2 assert p1 != p3 def test_frozen_objects_hash_errors_if_field_unhashable(self): p = FrozenPoint(1, [2]) with pytest.raises(TypeError): hash(p) def test_frozen_hash_mutable_objects_hash_errors(self): p = Point(1, 2) with pytest.raises(TypeError, match="unhashable type"): hash(p) def test_hash_includes_type(self): Ex1 = defstruct("Ex1", ["x"], frozen=True) Ex2 = defstruct("Ex2", ["x"], frozen=True) Ex3 = defstruct("Ex3", [], frozen=True) Ex4 = defstruct("Ex4", [], frozen=True) assert hash(Ex1(1)) == hash(Ex1(1)) assert hash(Ex1(1)) != hash(Ex2(1)) assert hash(Ex3()) == hash(Ex3()) assert hash(Ex3()) != hash(Ex4()) def test_cache_hash(self): class Inner: def __init__(self): self.hash_calls = 0 def __hash__(self): self.hash_calls += 1 return 123 class Cached(Struct, frozen=True, cache_hash=True): x: int y: Inner assert "__msgspec_cached_hash__" in Cached.__slots__ obj = Cached(1, Inner()) assert not hasattr(obj, "__msgspec_cached_hash__") assert hash(obj) == hash(obj) assert obj.__msgspec_cached_hash__ == hash(obj) assert obj.y.hash_calls == 1 class TestSetAttr: def test_frozen_objects_no_setattr(self): p = FrozenPoint(1, 2) with pytest.raises(AttributeError, match="immutable type: 'FrozenPoint'"): p.x = 3 @pytest.mark.parametrize("base_gc", [True, None, False]) @pytest.mark.parametrize("base_frozen", [True, False]) @pytest.mark.parametrize("has_gc", [True, None, False]) def test_override_setattr(self, has_gc, base_gc, base_frozen): called = False class Base(Struct, gc=base_gc, frozen=base_frozen): pass class Test(Struct, gc=has_gc, frozen=False): x: Any def __setattr__(self, name, value): nonlocal called called = True super().__setattr__(name, value) t = Test(1) assert not called t.x = 2 assert called if has_gc: assert not gc.is_tracked(t) t.x = [1] assert gc.is_tracked(t) @pytest.mark.parametrize("base_gc", [True, None, False]) @pytest.mark.parametrize("has_gc", [True, None, False]) def test_override_setattr_inherit(self, base_gc, has_gc): called = False class Base(Struct, gc=base_gc): x: Any def __setattr__(self, name, value): nonlocal called called = True super().__setattr__(name, value) class Test(Base, gc=has_gc): pass t = Test(1) assert not called t.x = 2 assert called if has_gc: assert not gc.is_tracked(t) t.x = [1] assert gc.is_tracked(t) def test_force_setattr(self): class Ex(Struct, frozen=True): x: Any obj = Ex(1) res = msgspec.structs.force_setattr(obj, "x", 2) assert res is None assert obj.x == 2 with pytest.raises(AttributeError): msgspec.structs.force_setattr(obj, "oops", 3) with pytest.raises(TypeError): msgspec.structs.force_setattr(1, "oops", 3) class TestOrderAndEq: @staticmethod def assert_eq(a, b): assert a == b assert not a != b @staticmethod def assert_neq(a, b): assert a != b assert not a == b def test_order_no_eq_errors(self): with pytest.raises(ValueError, match="Cannot set eq=False and order=True"): class Test(Struct, order=True, eq=False): pass def test_struct_eq_false(self): class Point(Struct, eq=False): x: int y: int p = Point(1, 2) # identity based equality self.assert_eq(p, p) self.assert_neq(p, Point(1, 2)) # identity based hash assert hash(p) == hash(p) assert hash(p) != hash(Point(1, 2)) def test_struct_eq(self): class Test(Struct): a: int b: int class Test2(Test): pass x = Struct() self.assert_eq(x, Struct()) self.assert_neq(x, None) x = Test(1, 2) self.assert_eq(x, Test(1, 2)) self.assert_neq(x, None) self.assert_neq(x, Test(1, 3)) self.assert_neq(x, Test(2, 2)) self.assert_neq(x, Test2(1, 2)) def test_struct_override_eq(self): class Ex(Struct): a: int b: int def __eq__(self, other): return self.a == other.a x = Ex(1, 2) y = Ex(1, 3) z = Ex(2, 3) self.assert_eq(x, y) self.assert_neq(x, z) def test_struct_eq_identity_fastpath(self): class Bad: def __eq__(self, other): raise ValueError("Oh no!") class Test(Struct): a: int b: Bad t = Test(1, Bad()) self.assert_eq(t, t) @pytest.mark.parametrize("op", ["le", "lt", "ge", "gt"]) def test_struct_order(self, op): func = getattr(operator, op) class Point(Struct, order=True): x: int y: int origin = Point(0, 0) for x in [-1, 0, 1]: for y in [-1, 0, 1]: sol = func((0, 0), (x, y)) res = func(origin, Point(x, y)) assert res == sol assert func(origin, origin) == func(1, 1) @pytest.mark.parametrize("eq, order", [(False, False), (True, False), (True, True)]) def test_struct_compare_returns_notimplemented(self, eq, order): class Test(Struct, eq=eq, order=order): x: int t1 = Test(1) t2 = Test(2) assert t1.__eq__(t2) is (False if eq else NotImplemented) assert t1.__lt__(t2) is (True if order else NotImplemented) assert t1.__eq__(None) is NotImplemented assert t1.__lt__(None) is NotImplemented @pytest.mark.parametrize("op", ["eq", "ne", "le", "lt", "ge", "gt"]) def test_struct_compare_errors(self, op): func = getattr(operator, op) class Bad: def __eq__(self, other): raise ValueError("Oh no!") class Test(Struct, order=True): a: object b: object t = Test(1, Bad()) t2 = Test(1, 2) with pytest.raises(ValueError, match="Oh no!"): func(t, t2) with pytest.raises(ValueError, match="Oh no!"): func(t2, t) class TestTagAndTagField: @pytest.mark.parametrize( "opts, tag_field, tag", [ # Default & explicit NULL ({}, None, None), ({"tag": None, "tag_field": None}, None, None), # tag=True ({"tag": True}, "type", "Test"), ({"tag": True, "tag_field": "test"}, "test", "Test"), # tag=False ({"tag": False}, None, None), ({"tag": False, "tag_field": "kind"}, None, None), # tag str ({"tag": "test"}, "type", "test"), (dict(tag="test", tag_field="kind"), "kind", "test"), # tag int ({"tag": 1}, "type", 1), (dict(tag=1, tag_field="kind"), "kind", 1), # tag callable (dict(tag=lambda n: n.lower()), "type", "test"), (dict(tag=lambda n: n.lower(), tag_field="kind"), "kind", "test"), # tag_field alone (dict(tag_field="kind"), "kind", "Test"), ], ) def test_config(self, opts, tag_field, tag): class Test(Struct, **opts): x: int y: int assert Test.__struct_config__.tag_field == tag_field assert Test.__struct_config__.tag == tag @pytest.mark.parametrize( "opts1, opts2, tag_field, tag", [ # tag=True ({"tag": True}, {}, "type", "S2"), ({"tag": True}, {"tag": None}, "type", "S2"), ({"tag": True}, {"tag": False}, None, None), ({"tag": True}, {"tag_field": "foo"}, "foo", "S2"), # tag str ({"tag": "test"}, {}, "type", "test"), ({"tag": "test"}, {"tag": "test2"}, "type", "test2"), ({"tag": "test"}, {"tag": None}, "type", "test"), ({"tag": "test"}, {"tag_field": "foo"}, "foo", "test"), # tag int ({"tag": 1}, {}, "type", 1), ({"tag": 1}, {"tag": "test2"}, "type", "test2"), ({"tag": 1}, {"tag": None}, "type", 1), ({"tag": 1}, {"tag_field": "foo"}, "foo", 1), # tag callable ({"tag": lambda n: n.lower()}, {}, "type", "s2"), ({"tag": lambda n: n.lower()}, {"tag": False}, None, None), ({"tag": lambda n: n.lower()}, {"tag": None}, "type", "s2"), ({"tag": lambda n: n.lower()}, {"tag_field": "foo"}, "foo", "s2"), ], ) def test_inheritance(self, opts1, opts2, tag_field, tag): class S1(Struct, **opts1): pass class S2(S1, **opts2): pass assert S2.__struct_config__.tag_field == tag_field assert S2.__struct_config__.tag == tag def test_tag_uses_simple_qualname(self): class S1(Struct, tag=True): class S2(Struct, tag=True): pass assert S1.__struct_config__.tag == "S1" assert S1.S2.__struct_config__.tag == "S1.S2" class S1(Struct, tag=str.lower): class S2(Struct, tag=str.lower): pass assert S1.__struct_config__.tag == "s1" assert S1.S2.__struct_config__.tag == "s1.s2" @pytest.mark.parametrize("tag", [b"bad", lambda n: b"bad"]) def test_tag_wrong_type(self, tag): with pytest.raises(TypeError, match="`tag` must be a `str` or an `int`"): class Test(Struct, tag=tag): pass @pytest.mark.parametrize("tag", [-(2**63) - 1, 2**63]) def test_tag_integer_out_of_range(self, tag): with pytest.raises(ValueError, match="Integer `tag` values must be"): class Test(Struct, tag=tag): pass def test_tag_field_wrong_type(self): with pytest.raises(TypeError, match="`tag_field` must be a `str`"): class Test(Struct, tag_field=b"bad"): pass def test_tag_field_collision(self): with pytest.raises(ValueError, match="tag_field='y'"): class Test(Struct, tag_field="y"): x: int y: int def test_tag_field_inheritance_collision(self): # Inherit the tag field class Base(Struct, tag_field="y"): pass with pytest.raises(ValueError, match="tag_field='y'"): class Test(Base): x: int y: int # Inherit the field class Base(Struct): x: int y: int with pytest.raises(ValueError, match="tag_field='y'"): class Test(Base, tag_field="y"): # noqa pass class TestRename: def test_field_name(self): class Test(Struct): x: int = field(name="field_x") assert Test.__struct_encode_fields__ == ("field_x",) def test_rename_mixed_with_field_name(self): class Test(Struct, rename="upper"): x: int = field(name="field_x") y: int assert Test.__struct_encode_fields__ == ("field_x", "Y") def test_rename_no_change(self): class Test(Struct, rename="lower"): x: int assert Test.__struct_fields__ is Test.__struct_encode_fields__ def test_field_name_no_change(self): class Test(Struct): x: int = field(name="x") assert Test.__struct_fields__ is Test.__struct_encode_fields__ def test_field_name_none(self): class Test(Struct): x: int = field(name=None) assert Test.__struct_fields__ is Test.__struct_encode_fields__ class Test(Struct, rename="upper"): x: int = field(name=None) assert Test.__struct_encode_fields__ == ("X",) def test_rename_explicit_none(self): class Test(Struct, rename=None): field_one: int field_two: str assert Test.__struct_encode_fields__ == ("field_one", "field_two") assert Test.__struct_fields__ is Test.__struct_encode_fields__ def test_rename_lower(self): class Test(Struct, rename="lower"): field_One: int field_Two: str assert Test.__struct_encode_fields__ == ("field_one", "field_two") def test_rename_upper(self): class Test(Struct, rename="upper"): field_one: int field_two: str assert Test.__struct_encode_fields__ == ("FIELD_ONE", "FIELD_TWO") def test_rename_kebab(self): class Test(Struct, rename="kebab"): field_one: int field_two_with_suffix: str __field_three__: bool field4: float _field_five: int assert Test.__struct_encode_fields__ == ( "field-one", "field-two-with-suffix", "field-three", "field4", "field-five", ) def test_rename_camel(self): class Test(Struct, rename="camel"): field_one: int field_two_with_suffix: str __field__three__: bool field4: float _field_five: int assert Test.__struct_encode_fields__ == ( "fieldOne", "fieldTwoWithSuffix", "__fieldThree", "field4", "_fieldFive", ) def test_rename_pascal(self): class Test(Struct, rename="pascal"): field_one: int field_two_with_suffix: str __field__three__: bool field4: float _field_five: int assert Test.__struct_encode_fields__ == ( "FieldOne", "FieldTwoWithSuffix", "__FieldThree", "Field4", "_FieldFive", ) def test_rename_callable(self): class Test(Struct, rename=str.title): field_one: int field_two: str assert Test.__struct_encode_fields__ == ("Field_One", "Field_Two") def test_rename_callable_returns_none(self): class Test(Struct, rename={"from_": "from"}.get): from_: str to: str assert Test.__struct_encode_fields__ == ("from", "to") def test_rename_callable_returns_non_string(self): with pytest.raises( TypeError, match="Expected calling `rename` to return a `str` or `None`, got `int`", ): class Test(Struct, rename=lambda x: 1): aa1: int aa2: int ab1: int def test_rename_mapping(self): class Test(Struct, rename={"from_": "from"}): from_: str to: str assert Test.__struct_encode_fields__ == ("from", "to") def test_rename_bad_value(self): with pytest.raises(ValueError, match="rename='invalid' is unsupported"): class Test(Struct, rename="invalid"): x: int def test_rename_bad_type(self): with pytest.raises(TypeError, match="str, callable, or mapping"): class Test(Struct, rename=1): x: int def test_rename_fields_collide(self): with pytest.raises(ValueError, match="Multiple fields rename to the same name"): class Test(Struct, rename=lambda x: x[:2]): aa1: int aa2: int ab1: int @pytest.mark.parametrize("field", ["foo\\bar", 'foo"bar', "foo\tbar"]) def test_rename_field_invalid_characters(self, field): with pytest.raises(ValueError) as rec: class Test(Struct, rename=lambda x: field): x: int assert field in str(rec.value) assert "must not contain" in str(rec.value) def test_rename_inherit(self): class Base(Struct, rename="upper"): pass class Test1(Base): x: int assert Test1.__struct_encode_fields__ == ("X",) class Test2(Base, rename="camel"): my_field: int assert Test2.__struct_encode_fields__ == ("myField",) class Test3(Test2, rename="kebab"): my_other_field: int assert Test3.__struct_encode_fields__ == ("myField", "my-other-field") class Test4(Base, rename=None): my_field: int assert Test4.__struct_encode_fields__ == ("my_field",) def test_rename_fields_only_used_for_encode_and_decode(self): """Check that the renamed fields don't show up elsewhere""" class Test(Struct, rename="upper"): one: int two: str t = Test(one=1, two="test") assert t.one == 1 assert t.two == "test" assert repr(t) == "Test(one=1, two='test')" with pytest.raises(TypeError, match="Missing required argument 'two'"): Test(one=1) class TestDefStruct: def test_defstruct_simple(self): Point = defstruct("Point", ["x", "y"]) assert issubclass(Point, Struct) assert as_tuple(Point(1, 2)) == (1, 2) assert Point.__module__ == "test_struct" def test_defstruct_empty(self): Empty = defstruct("Empty", []) assert as_tuple(Empty()) == () def test_defstruct_fields(self): Test = defstruct("Point", ["x", ("y", int), ("z", int, 0)]) assert Test.__struct_fields__ == ("x", "y", "z") assert Test.__struct_defaults__ == (0,) assert Test.__annotations__ == {"x": Any, "y": int, "z": int} assert as_tuple(Test(1, 2)) == (1, 2, 0) assert as_tuple(Test(1, 2, 3)) == (1, 2, 3) def test_defstruct_fields_iterable(self): Test = defstruct("Point", ((n, int) for n in "xyz")) assert Test.__struct_fields__ == ("x", "y", "z") assert Test.__annotations__ == {"x": int, "y": int, "z": int} def test_defstruct_errors(self): with pytest.raises(TypeError, match="must be str, not int"): defstruct(1) with pytest.raises(TypeError, match="`fields` must be an iterable"): defstruct("Test", 1) with pytest.raises(TypeError, match="items in `fields` must be one of"): defstruct("Test", ["x", 1]) with pytest.raises(TypeError, match="items in `fields` must be one of"): defstruct("Test", ["x", (1, 2)]) with pytest.raises(TypeError, match="must be a tuple or None"): defstruct("Test", [], bases=[]) with pytest.raises(TypeError, match="must be a str or None"): defstruct("Test", [], module=1) with pytest.raises(TypeError, match="must be a dict or None"): defstruct("Test", [], namespace=1) def test_defstruct_bases(self): class Base(Struct): z: int Point = defstruct("Point", ["x", "y"], bases=(Base,)) assert issubclass(Point, Base) assert issubclass(Point, Struct) assert as_tuple(Point(1, 2, 0)) == (1, 2, 0) assert as_tuple(Point(1, 2, 3)) == (1, 2, 3) def test_defstruct_bases_none(self): Point = defstruct("Point", ["x", "y"], bases=None) assert Point.mro() == [Point, *Struct.mro()] assert Point(1, 2) == Point(1, 2) def test_defstruct_module(self): Test = defstruct("Test", [], module="testmod") assert Test.__module__ == "testmod" def test_defstruct_module_none(self): Test = defstruct("Test", [], module=None) assert Test.__module__ == "test_struct" def test_defstruct_namespace(self): Test = defstruct( "Test", ["x", "y"], namespace={"add": lambda self: self.x + self.y} ) t = Test(1, 2) assert t.add() == 3 def test_defstruct_namespace_none(self): Test = defstruct("Test", [], namespace=None) assert Test() == Test() # smoketest def test_defstruct_kw_only(self): Test = defstruct("Test", ["x", "y"], kw_only=True) t = Test(x=1, y=2) assert t.x == 1 and t.y == 2 with pytest.raises(TypeError, match="Extra positional arguments"): Test(1, 2) @pytest.mark.parametrize( "option, default", [ ("repr_omit_defaults", False), ("omit_defaults", False), ("forbid_unknown_fields", False), ("frozen", False), ("order", False), ("eq", True), ("array_like", False), ("gc", True), ], ) def test_defstruct_bool_options(self, option, default): Test = defstruct("Test", [], **{option: True}) assert getattr(Test.__struct_config__, option) is True Test = defstruct("Test", [], **{option: False}) assert getattr(Test.__struct_config__, option) is False Test = defstruct("Test", []) assert getattr(Test.__struct_config__, option) is default def test_defstruct_weakref(self): Test = defstruct("Test", []) assert Test.__weakrefoffset__ == 0 assert not Test.__struct_config__.weakref Test = defstruct("Test", [], weakref=False) assert Test.__weakrefoffset__ == 0 assert not Test.__struct_config__.weakref Test = defstruct("Test", [], weakref=True) assert Test.__weakrefoffset__ != 0 assert Test.__struct_config__.weakref def test_defstruct_dict(self): Test = defstruct("Test", []) assert not hasattr(Test(), "__dict__") assert not Test.__struct_config__.dict Test = defstruct("Test", [], dict=False) assert not hasattr(Test(), "__dict__") assert not Test.__struct_config__.dict Test = defstruct("Test", [], dict=True) assert hasattr(Test(), "__dict__") assert Test.__struct_config__.dict def test_defstruct_cache_hash(self): Test = defstruct("Test", [], frozen=True) assert not Test.__struct_config__.cache_hash Test = defstruct("Test", [], frozen=True, cache_hash=False) assert not Test.__struct_config__.cache_hash Test = defstruct("Test", [], frozen=True, cache_hash=True) assert Test.__struct_config__.cache_hash def test_defstruct_tag_and_tag_field(self): Test = defstruct("Test", [], tag=True) assert Test.__struct_config__.tag == "Test" Test = defstruct("Test", [], namespace={"__qualname__": "Foo.Test"}, tag=True) assert Test.__struct_config__.tag == "Foo.Test" Test = defstruct("Test", [], tag="mytag", tag_field="mytagfield") config = Test.__struct_config__ assert config.tag_field == "mytagfield" assert config.tag == "mytag" def test_defstruct_rename(self): Test = defstruct("Test", ["my_field"], rename="camel") assert Test.__struct_fields__ == ("my_field",) assert Test.__struct_encode_fields__ == ("myField",) @pytest.fixture(params=["structs.replace", "copy.replace"]) def replace(request): if request.param == "structs.replace": return msgspec.structs.replace else: return copy_replace class TestReplace: def test_replace_not_a_struct(self): with pytest.raises(TypeError, match="`struct` must be a `msgspec.Struct`"): msgspec.structs.replace(1, x=2) def test_replace_no_kwargs(self, replace): p = Point(1, 2) assert replace(p) == p def test_replace_kwargs(self, replace): p = Point(1, 2) assert replace(p, x=3) == Point(3, 2) assert replace(p, y=4) == Point(1, 4) assert replace(p, x=3, y=4) == Point(3, 4) def test_replace_unknown_field(self, replace): p = Point(1, 2) with pytest.raises(TypeError, match="`Point` has no field 'oops'"): replace(p, oops=3) def test_replace_errors_unset_fields(self, replace): p = Point(1, 2) del p.x with pytest.raises(AttributeError, match="Struct field 'x' is unset"): replace(p) with pytest.raises(AttributeError, match="Struct field 'x' is unset"): replace(p, y=1) assert replace(p, x=3) == Point(3, 2) def test_replace_frozen(self, replace): class Test(msgspec.Struct, frozen=True): x: int y: int assert replace(Test(1, 2), x=3) == Test(3, 2) def test_replace_gc_delayed_tracking(self, replace): class Test(msgspec.Struct): x: int y: Optional[List[int]] obj = Test(1, None) assert not gc.is_tracked(replace(obj)) assert not gc.is_tracked(replace(obj, x=10)) assert not gc.is_tracked(replace(obj, y=None)) assert gc.is_tracked(replace(obj, y=[1, 2, 3])) obj = Test(1, [1, 2, 3]) assert gc.is_tracked(replace(obj)) assert gc.is_tracked(replace(obj, x=1)) assert not gc.is_tracked(replace(obj, y=None)) def test_replace_gc_false(self, replace): class Test(msgspec.Struct, gc=False): x: int y: List[int] res = replace(Test(1, [1, 2]), x=3) assert res == Test(3, [1, 2]) assert not gc.is_tracked(res) def test_replace_reference_counts(self, replace): class Test(msgspec.Struct): x: Any y: int x = object() t = Test(x, 1) x_count = sys.getrefcount(x) t2 = replace(t) assert sys.getrefcount(x) == x_count + 1 del t2 t2 = replace(t, x=None) assert sys.getrefcount(x) == x_count del t2 t2 = replace(t, y=2) assert sys.getrefcount(x) == x_count + 1 del t2 x2 = object() x2_count = sys.getrefcount(x2) t2 = replace(t, x=x2) assert sys.getrefcount(x) == x_count assert sys.getrefcount(x2) == x2_count + 1 del t2 class TestAsDictAndAsTuple: def test_asdict(self): x = Point(1, 2) assert msgspec.structs.asdict(x) == {"x": 1, "y": 2} def test_astuple(self): x = Point(1, 2) assert msgspec.structs.astuple(x) == (1, 2) @pytest.mark.parametrize("func", [msgspec.structs.asdict, msgspec.structs.astuple]) def test_errors(self, func): with pytest.raises(TypeError): func(1) x = Point(1, 2) del x.y with pytest.raises(AttributeError): func(x) class TestInspectFields: def test_fields_bad_arg(self): T = TypeVar("T") class Bad(Generic[T]): x: T for val in [1, int, Bad, Bad[int]]: with pytest.raises(TypeError, match="struct type or instance"): msgspec.structs.fields(val) def test_fields_no_fields(self): assert msgspec.structs.fields(msgspec.Struct) == () @pytest.mark.parametrize("instance", [False, True]) def test_fields(self, instance): def factory(): return 1 class Example(msgspec.Struct): x: int y: int = 0 z: int = msgspec.field(default_factory=factory) arg = Example(1, 2, 3) if instance else Example fields = msgspec.structs.fields(arg) x_field, y_field, z_field = fields assert x_field.required assert x_field.default is NODEFAULT assert x_field.default_factory is NODEFAULT assert not y_field.required assert y_field.default == 0 assert y_field.default_factory is NODEFAULT assert not z_field.required assert z_field.default is NODEFAULT assert z_field.default_factory is factory def test_fields_keyword_only(self): class Example(msgspec.Struct, kw_only=True): a: int b: int = 1 c: int d: int = 2 sol = ( msgspec.structs.FieldInfo("a", "a", int), msgspec.structs.FieldInfo("b", "b", int, default=1), msgspec.structs.FieldInfo("c", "c", int), msgspec.structs.FieldInfo("d", "d", int, default=2), ) assert msgspec.structs.fields(Example) == sol def test_fields_encode_name(self): class Example(msgspec.Struct, rename="camel"): field_one: int field_two: int sol = ( msgspec.structs.FieldInfo("field_one", "fieldOne", int), msgspec.structs.FieldInfo("field_two", "fieldTwo", int), ) assert msgspec.structs.fields(Example) == sol def test_fields_generic(self): T = TypeVar("T") class Example(msgspec.Struct, Generic[T]): x: T y: int sol = ( msgspec.structs.FieldInfo("x", "x", T), msgspec.structs.FieldInfo("y", "y", int), ) assert msgspec.structs.fields(Example) == sol assert msgspec.structs.fields(Example(1, 2)) == sol sol = ( msgspec.structs.FieldInfo("x", "x", str), msgspec.structs.FieldInfo("y", "y", int), ) assert msgspec.structs.fields(Example[str]) class TestClassVar: def case1(self): return """ from typing import ClassVar from msgspec import Struct class Ex(Struct): a: int cv1: ClassVar b: int cv2: ClassVar[int] = 1 """ def case2(self): return """ import typing from msgspec import Struct class Ex(Struct): a: int cv1: typing.ClassVar b: int cv2: typing.ClassVar[int] = 1 """ def case3(self): return """ import typing from msgspec import Struct ClassVar = typing.List class Ex(Struct): a: ClassVar b: ClassVar[int] cv2: typing.ClassVar[int] = 1 """ def case4(self): return """ from typing import ClassVar, List from msgspec import Struct class typing: ClassVar = List class Ex(Struct): a: typing.ClassVar b: typing.ClassVar[int] cv2: ClassVar[int] = 1 """ def case5(self): """Annotations that start with `ClassVar`/`typing.ClassVar` but don't end there aren't treated as false-positives""" return """ from typing import ClassVar, List from msgspec import Struct ClassVariable = List class typing: ClassVariable = List class Ex(Struct): a: typing.ClassVariable b: ClassVariable[int] cv2: ClassVar[int] = 1 """ @pytest.mark.parametrize("case", [1, 2, 3, 4, 5]) @pytest.mark.parametrize("future_annotations", [True, False]) def test_classvar(self, case, future_annotations): source = getattr(self, f"case{case}")() if future_annotations: source = " from __future__ import annotations\n" + source with temp_module(source) as mod: assert mod.Ex.__struct_fields__ == ("a", "b") assert mod.Ex.cv2 == 1 class TestPostInit: def test_post_init(self): called = False singleton = object() class Ex(Struct): x: int def __post_init__(self): nonlocal called called = True return singleton Ex(1) assert called # Return value is decref'd assert sys.getrefcount(singleton) == 2 # 1 for ref, 1 for call def test_post_init_errors(self): class Ex(Struct): x: int def __post_init__(self): raise ValueError("Oh no!") with pytest.raises(ValueError, match="Oh no!"): Ex(1) def test_post_init_invalid(self): class Bad1(Struct): __post_init__ = 1 class Bad2(Struct): def __post_init__(self, other): pass with pytest.raises(TypeError): Bad1() with pytest.raises(TypeError): Bad2() def test_post_init_inheritance(self): called = False class Base: def __post_init__(self): nonlocal called called = True class Ex(Struct, Base): x: int Ex(1) assert called def test_post_init_not_called_on_copy(self): count = 0 class Ex(Struct): def __post_init__(self): nonlocal count count += 1 x1 = Ex() assert count == 1 x2 = x1.__copy__() assert x1 == x2 assert count == 1 def test_post_init_not_called_on_replace(self): count = 0 class Ex(Struct): def __post_init__(self): nonlocal count count += 1 x1 = Ex() assert count == 1 x2 = msgspec.structs.replace(x1) assert x1 == x2 assert count == 1 python-msgspec-0.19.0/tests/test_to_builtins.py000066400000000000000000000461601473355726200217140ustar00rootroot00000000000000import base64 import datetime import decimal import enum import os import sys import uuid import weakref from dataclasses import dataclass, make_dataclass from typing import Any, NamedTuple, Union import pytest from msgspec import UNSET, Struct, UnsetType, to_builtins, defstruct PY310 = sys.version_info[:2] >= (3, 10) PY311 = sys.version_info[:2] >= (3, 11) py310_plus = pytest.mark.skipif(not PY310, reason="3.10+ only") py311_plus = pytest.mark.skipif(not PY311, reason="3.11+ only") slots_params = [False, pytest.param(True, marks=[py310_plus])] class FruitInt(enum.IntEnum): APPLE = -1 BANANA = 2 def __eq__(self, other): assert type(other) is type(self) return super().__eq__(other) def __hash__(self): return super().__hash__() class FruitStr(enum.Enum): APPLE = "apple" BANANA = "banana" def __eq__(self, other): assert type(other) is type(self) return super().__eq__(other) def __hash__(self): return super().__hash__() class Bad: """A type that msgspec doesn't natively handle""" class TestToBuiltins: def test_to_builtins_bad_calls(self): with pytest.raises(TypeError): to_builtins() with pytest.raises( TypeError, match="builtin_types must be an iterable of types" ): to_builtins([1], builtin_types=1) with pytest.raises( TypeError, match="builtin_types must be an iterable of types" ): to_builtins([1], builtin_types=(1,)) with pytest.raises(TypeError, match="enc_hook must be callable"): to_builtins([1], enc_hook=1) def test_to_builtins_builtin_types_explicit_none(self): assert to_builtins(1, builtin_types=None) == 1 def test_to_builtins_enc_hook_explicit_none(self): assert to_builtins(1, enc_hook=None) == 1 @pytest.mark.parametrize("case", [1, 2, 3, 4, 5]) def test_to_builtins_recursive(self, case): if case == 1: o = [] o.append(o) elif case == 2: o = ([],) o[0].append(o) elif case == 3: o = {} o["a"] = o elif case == 4: class Box(Struct): a: "Box" o = Box(None) o.a = o elif case == 5: @dataclass class Box: a: "Box" o = Box(None) o.a = o with pytest.raises(RecursionError): to_builtins(o) def test_none(self): assert to_builtins(None) is None def test_bool(self): assert to_builtins(False) is False assert to_builtins(True) is True def test_int(self): assert to_builtins(1) == 1 def test_float(self): assert to_builtins(1.5) == 1.5 def test_str(self): assert to_builtins("abc") == "abc" @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) @pytest.mark.parametrize("size", range(5)) def test_binary(self, typ, size): msg = typ(os.urandom(size)) res = to_builtins(msg) sol = base64.b64encode(msg).decode("utf-8") assert res == sol @pytest.mark.parametrize("typ", [bytes, bytearray, memoryview]) def test_binary_builtin_types(self, typ): msg = typ(b"\x01\x02\x03") res = to_builtins(msg, builtin_types=(typ,)) assert res is msg @pytest.mark.parametrize("tzinfo", [None, datetime.timezone.utc]) @pytest.mark.parametrize("microsecond", [123456, 123, 0]) def test_datetime(self, tzinfo, microsecond): msg = datetime.datetime.now(tzinfo).replace(microsecond=microsecond) res = to_builtins(msg) sol = msg.isoformat().replace("+00:00", "Z") assert res == sol def test_datetime_builtin_types(self): msg = datetime.datetime.now() res = to_builtins(msg, builtin_types=(datetime.datetime,)) assert res is msg def test_date(self): msg = datetime.date.today() res = to_builtins(msg) sol = msg.isoformat() assert res == sol def test_date_builtin_types(self): msg = datetime.date.today() res = to_builtins(msg, builtin_types=(datetime.date,)) assert res is msg @pytest.mark.parametrize("tzinfo", [None, datetime.timezone.utc]) @pytest.mark.parametrize("microsecond", [123456, 123, 0]) def test_time(self, tzinfo, microsecond): msg = datetime.datetime.now(tzinfo).replace(microsecond=microsecond).timetz() res = to_builtins(msg) sol = msg.isoformat().replace("+00:00", "Z") assert res == sol def test_time_builtin_types(self): msg = datetime.datetime.now().time() res = to_builtins(msg, builtin_types=(datetime.time,)) assert res is msg def test_timedelta(self): msg = datetime.timedelta(1, 2, 300) res = to_builtins(msg) assert res == "P1DT2.0003S" def test_timedelta_builtin_types(self): msg = datetime.timedelta(1, 2, 300) res = to_builtins(msg, builtin_types=(datetime.timedelta,)) assert res is msg def test_uuid(self): msg = uuid.uuid4() assert to_builtins(msg) == str(msg) def test_uuid_subclass(self): class Ex(uuid.UUID): pass s = "4184defa-4d1a-4497-a140-fd1ec0b22383" assert to_builtins(Ex(s)) == s def test_uuid_builtin_types(self): msg = uuid.uuid4() res = to_builtins(msg, builtin_types=(uuid.UUID,)) assert res is msg def test_decimal(self): msg = decimal.Decimal("1.5") assert to_builtins(msg) == str(msg) def test_decimal_builtin_types(self): msg = decimal.Decimal("1.5") res = to_builtins(msg, builtin_types=(decimal.Decimal,)) assert res is msg def test_intenum(self): res = to_builtins(FruitInt.APPLE) assert res == -1 assert type(res) is int def test_enum(self): res = to_builtins(FruitStr.APPLE) assert res == "apple" assert type(res) is str def test_enum_complex(self): class Complex(enum.Enum): x = (1, 2) res = to_builtins(Complex.x) assert res is Complex.x.value @pytest.mark.parametrize( "in_type, out_type", [(list, list), (tuple, tuple), (set, list), (frozenset, list)], ) @pytest.mark.parametrize("subclass", [False, True]) def test_sequence(self, in_type, out_type, subclass): if subclass: class in_type(in_type): pass msg = in_type([1, FruitInt.APPLE]) res = to_builtins(msg) assert res == out_type([1, -1]) assert res is not msg res = to_builtins(in_type()) assert res == out_type() @pytest.mark.parametrize("in_type", [list, tuple, set, frozenset]) def test_sequence_unsupported_item(self, in_type): msg = in_type([1, Bad(), 3]) with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) def test_namedtuple(self): class Point(NamedTuple): x: int y: FruitInt assert to_builtins(Point(1, FruitInt.APPLE)) == (1, -1) @pytest.mark.parametrize("subclass", [False, True]) def test_dict(self, subclass): if subclass: class in_type(dict): pass else: in_type = dict msg = in_type({FruitStr.BANANA: 1, "b": [FruitInt.APPLE], 3: "three"}) sol = {"banana": 1, "b": [-1], 3: "three"} res = to_builtins(msg) assert res == sol assert res is not msg res = to_builtins(in_type()) assert res == {} def test_dict_str_subclass_key(self): class mystr(str): pass msg = to_builtins({mystr("test"): 1}) assert msg == {"test": 1} assert type(list(msg.keys())[0]) is str def test_dict_unsupported_key(self): msg = {Bad(): 1} with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) def test_dict_unsupported_value(self): msg = {"x": Bad()} with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) def test_dict_str_keys(self): assert to_builtins({FruitStr.BANANA: 1}, str_keys=True) == {"banana": 1} assert to_builtins({"banana": 1}, str_keys=True) == {"banana": 1} assert to_builtins({FruitInt.BANANA: 1}, str_keys=True) == {"2": 1} assert to_builtins({2: 1}, str_keys=True) == {"2": 1} def test_dict_sequence_keys(self): msg = {frozenset([1, 2]): 1} assert to_builtins(msg) == {(1, 2): 1} with pytest.raises( TypeError, match="Only dicts with str-like or number-like keys are supported", ): to_builtins(msg, str_keys=True) @pytest.mark.parametrize("tagged", [False, True]) def test_struct_object(self, tagged): class Ex(Struct, tag=tagged): x: int y: FruitInt sol = {"type": "Ex", "x": 1, "y": -1} if tagged else {"x": 1, "y": -1} assert to_builtins(Ex(1, FruitInt.APPLE)) == sol def test_struct_object_omit_defaults(self): class Ex(Struct, omit_defaults=True): x: int a: list = [] b: FruitStr = FruitStr.BANANA c: FruitInt = FruitInt.APPLE assert to_builtins(Ex(1)) == {"x": 1} assert to_builtins(Ex(1, a=[2])) == {"x": 1, "a": [2]} assert to_builtins(Ex(1, b=FruitStr.APPLE)) == {"x": 1, "b": "apple"} @pytest.mark.parametrize("tagged", [False, True]) def test_struct_array(self, tagged): class Ex(Struct, array_like=True, tag=tagged): x: int y: FruitInt sol = ["Ex", 1, -1] if tagged else [1, -1] assert to_builtins(Ex(1, FruitInt.APPLE)) == sol @pytest.mark.parametrize("tagged", [False, True]) def test_struct_array_keys(self, tagged): class Ex(Struct, array_like=True, tag=tagged, frozen=True): x: int y: FruitInt msg = {Ex(1, FruitInt.APPLE): "abc"} sol = {("Ex", 1, -1) if tagged else (1, -1): "abc"} assert to_builtins(msg) == sol @pytest.mark.parametrize("array_like", [False, True]) def test_struct_unsupported_value(self, array_like): class Ex(Struct): a: Any b: Any msg = Ex(1, Bad()) with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) @pytest.mark.parametrize("slots", slots_params) def test_dataclass(self, slots): @dataclass(**({"slots": True} if slots else {})) class Ex: x: int y: FruitInt msg = Ex(1, FruitInt.APPLE) assert to_builtins(msg) == {"x": 1, "y": -1} @pytest.mark.parametrize("slots", slots_params) def test_dataclass_missing_fields(self, slots): @dataclass(**({"slots": True} if slots else {})) class Ex: x: int y: int z: int x = Ex(1, 2, 3) sol = {"x": 1, "y": 2, "z": 3} for key in "xyz": delattr(x, key) del sol[key] assert to_builtins(x) == sol @pytest.mark.parametrize("slots_base", slots_params) @pytest.mark.parametrize("slots", slots_params) def test_dataclass_subclasses(self, slots_base, slots): @dataclass(**({"slots": True} if slots_base else {})) class Base: x: int y: int @dataclass(**({"slots": True} if slots else {})) class Ex(Base): y: int z: int x = Ex(1, 2, 3) res = to_builtins(x) assert res == {"x": 1, "y": 2, "z": 3} # Missing attribute ignored del x.y res = to_builtins(x) assert res == {"x": 1, "z": 3} @py311_plus def test_dataclass_weakref_slot(self): @dataclass(slots=True, weakref_slot=True) class Ex: x: int y: int x = Ex(1, 2) ref = weakref.ref(x) # noqa res = to_builtins(x) assert res == {"x": 1, "y": 2} @pytest.mark.parametrize("slots", slots_params) def test_dataclass_unsupported_value(self, slots): @dataclass(**({"slots": True} if slots else {})) class Ex: x: Any y: Any msg = Ex(1, Bad()) with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(msg) def test_dataclass_class_errors(self): @dataclass class Ex: x: int with pytest.raises(TypeError, match="Encoding objects of type type"): to_builtins(Ex) @pytest.mark.parametrize("slots", [True, False]) def test_attrs(self, slots): attrs = pytest.importorskip("attrs") @attrs.define(slots=slots) class Ex: x: int y: FruitInt msg = Ex(1, FruitInt.APPLE) assert to_builtins(msg) == {"x": 1, "y": -1} @pytest.mark.parametrize("slots", [True, False]) def test_attrs_skip_leading_underscore(self, slots): attrs = pytest.importorskip("attrs") @attrs.define(slots=slots) class Ex: x: int y: int _z: int x = Ex(1, 2, 3) res = to_builtins(x) assert res == {"x": 1, "y": 2} @pytest.mark.parametrize("kind", ["struct", "dataclass", "attrs"]) def test_unset_fields(self, kind): if kind == "struct": class Ex(Struct): x: Union[int, UnsetType] y: Union[int, UnsetType] elif kind == "dataclass": @dataclass class Ex: x: Union[int, UnsetType] y: Union[int, UnsetType] elif kind == "attrs": attrs = pytest.importorskip("attrs") @attrs.define class Ex: x: Union[int, UnsetType] y: Union[int, UnsetType] res = to_builtins(Ex(1, UNSET)) assert res == {"x": 1} res = to_builtins(Ex(UNSET, 2)) assert res == {"y": 2} res = to_builtins(Ex(UNSET, UNSET)) assert res == {} def test_unset_errors_in_other_contexts(self): with pytest.raises(TypeError): to_builtins(UNSET) def test_custom(self): with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(Bad()) assert to_builtins(Bad(), enc_hook=lambda x: "bad") == "bad" @pytest.mark.parametrize("col_type", [tuple, list, set]) def test_custom_builtin_types(self, col_type): class C1: pass class C2: pass builtins = col_type([C1, bytes, C2]) count = sys.getrefcount(builtins) for msg in [C1(), C2(), b"test"]: assert to_builtins(msg, builtin_types=builtins) is msg with pytest.raises(TypeError, match="Encoding objects of type Bad"): to_builtins(Bad(), builtin_types=builtins) assert sys.getrefcount(builtins) == count class TestOrder: def test_order_invalid(self): with pytest.raises(ValueError, match="`order` must be one of"): to_builtins(1, order="bad") @staticmethod def assert_eq(left, right): assert left == right if isinstance(left, dict): assert list(left) == list(right) @pytest.mark.parametrize("msg", [{}, {"y": 1, "x": 2, "z": 3}]) @pytest.mark.parametrize("order", [None, "deterministic", "sorted"]) def test_order_dict(self, msg, order): res = to_builtins(msg, order=order) sol = dict(sorted(msg.items())) if order else msg self.assert_eq(res, sol) def test_order_dict_non_str_errors(self): with pytest.raises(TypeError): to_builtins({"b": 2, 1: "a"}, order="deterministic") def test_order_dict_unsortable(self): with pytest.raises(TypeError): to_builtins({"x": 1, 1: 2}, order="deterministic") @pytest.mark.parametrize("typ", [set, frozenset]) @pytest.mark.parametrize("order", ["deterministic", "sorted"]) def test_order_set(self, typ, rand, order): assert to_builtins(typ(), order=order) == [] msg = typ(rand.str(10) for _ in range(20)) res = to_builtins(msg, order=order) self.assert_eq(res, sorted(msg)) res = to_builtins(msg) self.assert_eq(res, list(msg)) def test_order_set_unsortable(self): with pytest.raises(TypeError): to_builtins({"x", 1}, order="deterministic") @pytest.mark.parametrize("n", [0, 1, 2]) @pytest.mark.parametrize( "kind", [ "struct", "dataclass", "attrs", "attrs-dict", ], ) def test_order_object(self, kind, n): fields = [f"x{i}" for i in range(n)] fields.reverse() if kind == "struct": cls = defstruct("Test", fields) elif kind == "dataclass": cls = make_dataclass("Test", fields) else: attrs = pytest.importorskip("attrs") cls = attrs.make_class("Test", fields, slots=(kind == "attrs")) msg = cls(*range(n)) if kind in ("struct", "dataclass"): # we currently don't guarantee field order with attrs types res = to_builtins(msg) sol = dict(zip(fields, range(n))) self.assert_eq(res, sol) res = to_builtins(msg, order="deterministic") self.assert_eq(res, sol) res = to_builtins(msg, order="sorted") sol = dict(sorted(zip(fields, range(n)))) self.assert_eq(res, sol) @pytest.mark.parametrize("kind", ["struct", "dataclass", "attrs", "attrs-dict"]) def test_order_unset(self, kind): if kind == "struct": class Ex(Struct): z: Union[int, UnsetType] = UNSET x: Union[int, UnsetType] = UNSET elif kind == "dataclass": @dataclass class Ex: z: Union[int, UnsetType] = UNSET x: Union[int, UnsetType] = UNSET else: attrs = pytest.importorskip("attrs") @attrs.define(slots=(kind == "attrs")) class Ex: z: Union[int, UnsetType] = UNSET x: Union[int, UnsetType] = UNSET res = to_builtins(Ex(), order="sorted") self.assert_eq(res, {}) res = to_builtins(Ex(z=10), order="sorted") self.assert_eq(res, {"z": 10}) res = to_builtins(Ex(z=10, x=-1), order="sorted") self.assert_eq(res, {"x": -1, "z": 10}) def test_order_struct_omit_defaults(self): class Ex(Struct, omit_defaults=True): z: int = 0 x: int = 1 y: int = 2 res = to_builtins(Ex(), order="sorted") self.assert_eq(res, {}) res = to_builtins(Ex(z=10), order="sorted") self.assert_eq(res, {"z": 10}) res = to_builtins(Ex(z=10, x=-1), order="sorted") self.assert_eq(res, {"x": -1, "z": 10}) def test_order_struct_tag(self): class Ex(Struct, tag_field="y", tag=2): z: int x: int res = to_builtins(Ex(0, 1), order="sorted") self.assert_eq(res, {"x": 1, "y": 2, "z": 0}) python-msgspec-0.19.0/tests/test_toml.py000066400000000000000000000124401473355726200203260ustar00rootroot00000000000000import dataclasses import datetime import enum import sys import uuid from decimal import Decimal from typing import Dict, FrozenSet, List, Set, Tuple import pytest import msgspec try: import tomllib except ImportError: try: import tomli as tomllib except ImportError: tomllib = None try: import tomli_w except ImportError: tomli_w = None needs_decode = pytest.mark.skipif( tomllib is None, reason="Neither tomllib or tomli are installed" ) needs_encode = pytest.mark.skipif(tomli_w is None, reason="tomli_w is not installed") PY311 = sys.version_info[:2] >= (3, 11) UTC = datetime.timezone.utc class ExStruct(msgspec.Struct): x: int y: str @dataclasses.dataclass class ExDataclass: x: int y: str class ExEnum(enum.Enum): one = "one" two = "two" class ExIntEnum(enum.IntEnum): one = 1 two = 2 def test_module_dir(): assert set(dir(msgspec.toml)) == {"encode", "decode"} @pytest.mark.skipif(PY311, reason="tomllib is builtin in 3.11+") def test_tomli_not_installed_error(monkeypatch): monkeypatch.setitem(sys.modules, "tomli", None) with pytest.raises(ImportError, match="conda install"): msgspec.toml.decode("a = 1", type=int) def test_tomli_w_not_installed_error(monkeypatch): monkeypatch.setitem(sys.modules, "tomli_w", None) with pytest.raises(ImportError, match="conda install"): msgspec.toml.encode({"a": 1}) @pytest.mark.parametrize( "val", [ True, False, 1, 1.5, "fizz", datetime.datetime(2022, 1, 2, 3, 4, 5, 6), datetime.datetime(2022, 1, 2, 3, 4, 5, 6, UTC), datetime.date(2022, 1, 2), datetime.time(12, 34), [1, 2], {"one": 2}, ], ) @needs_encode @needs_decode def test_roundtrip_any(val): msg = msgspec.toml.encode({"x": val}) res = msgspec.toml.decode(msg)["x"] assert res == val @pytest.mark.parametrize( "val, type", [ (True, bool), (False, bool), (1, int), (1.5, float), ("fizz", str), (b"fizz", bytes), (b"fizz", bytearray), (datetime.datetime(2022, 1, 2, 3, 4, 5, 6), datetime.datetime), (datetime.datetime(2022, 1, 2, 3, 4, 5, 6, UTC), datetime.datetime), (datetime.date(2022, 1, 2), datetime.date), (datetime.time(12, 34), datetime.time), (uuid.uuid4(), uuid.UUID), (ExEnum.one, ExEnum), (ExIntEnum.one, ExIntEnum), ([1, 2], List[int]), ((1, 2), Tuple[int, ...]), ({1, 2}, Set[int]), (frozenset({1, 2}), FrozenSet[int]), (("one", 2), Tuple[str, int]), ({"one": 2}, Dict[str, int]), ({1: "two"}, Dict[int, str]), (ExStruct(1, "two"), ExStruct), (ExDataclass(1, "two"), ExDataclass), ], ) @needs_encode @needs_decode def test_roundtrip_typed(val, type): msg = msgspec.toml.encode({"x": val}) res = msgspec.toml.decode(msg, type=Dict[str, type])["x"] assert res == val @needs_encode def test_encode_output_type(): msg = msgspec.toml.encode({"x": 1}) assert isinstance(msg, bytes) @needs_encode def test_encode_error(): class Oops: pass with pytest.raises(TypeError, match="Encoding objects of type Oops is unsupported"): msgspec.toml.encode({"x": Oops()}) @needs_encode @needs_decode def test_encode_enc_hook(): msg = msgspec.toml.encode({"x": Decimal(1.5)}, enc_hook=str) assert msgspec.toml.decode(msg) == {"x": "1.5"} @needs_encode @pytest.mark.parametrize("order", [None, "deterministic"]) def test_encode_order(order): msg = {"y": 1, "x": ({"n": 1, "m": 2},), "z": [{"b": 1, "a": 2}]} res = msgspec.toml.encode(msg, order=order) if order: sol_msg = {"x": ({"m": 2, "n": 1},), "y": 1, "z": [{"a": 2, "b": 1}]} else: sol_msg = msg sol = tomli_w.dumps(sol_msg).encode("utf-8") assert res == sol @needs_decode def test_decode_str_or_bytes_like(): assert msgspec.toml.decode("a = 1") == {"a": 1} assert msgspec.toml.decode(b"a = 1") == {"a": 1} assert msgspec.toml.decode(bytearray(b"a = 1")) == {"a": 1} assert msgspec.toml.decode(memoryview(b"a = 1")) == {"a": 1} with pytest.raises(TypeError): msgspec.toml.decode(1) @needs_decode @pytest.mark.parametrize("msg", [b"{{", b"!!binary 123"]) def test_decode_parse_error(msg): with pytest.raises(msgspec.DecodeError): msgspec.toml.decode(msg) @needs_decode def test_decode_validation_error(): with pytest.raises(msgspec.ValidationError, match="Expected `str`"): msgspec.toml.decode(b"a = [1, 2, 3]", type=Dict[str, List[str]]) @needs_decode @pytest.mark.parametrize("strict", [True, False]) def test_decode_strict_or_lax(strict): msg = b"a = ['1', '2']" typ = Dict[str, List[int]] if strict: with pytest.raises(msgspec.ValidationError, match="Expected `int`"): msgspec.toml.decode(msg, type=typ, strict=strict) else: res = msgspec.toml.decode(msg, type=typ, strict=strict) assert res == {"a": [1, 2]} @needs_decode def test_decode_dec_hook(): def dec_hook(typ, val): if typ is Decimal: return Decimal(val) raise TypeError res = msgspec.toml.decode("a = '1.5'", type=Dict[str, Decimal], dec_hook=dec_hook) assert res == {"a": Decimal("1.5")} python-msgspec-0.19.0/tests/test_utils.py000066400000000000000000000137011473355726200205140ustar00rootroot00000000000000from __future__ import annotations import sys from typing import Generic, List, Optional, Set, TypeVar import pytest from utils import temp_module, package_not_installed from msgspec._utils import get_class_annotations PY310 = sys.version_info[:2] >= (3, 10) T = TypeVar("T") S = TypeVar("S") U = TypeVar("U") class Base(Generic[T]): x: T class Base2(Generic[T, S]): a: T b: S class TestGetClassAnnotations: @pytest.mark.parametrize("future_annotations", [False, True]) def test_eval_scopes(self, future_annotations): header = "from __future__ import annotations" if future_annotations else "" source = f""" {header} STR = str class Ex: LOCAL = float x: int y: LOCAL z: STR """ with temp_module(source) as mod: assert get_class_annotations(mod.Ex) == {"x": int, "y": float, "z": str} def test_none_to_nonetype(self): class Ex: x: None assert get_class_annotations(Ex) == {"x": type(None)} def test_subclass(self): class Base: x: int y: str class Sub(Base): x: float z: list class Base2: a: int class Sub2(Sub, Base2): b: float y: list assert get_class_annotations(Base) == {"x": int, "y": str} assert get_class_annotations(Sub) == {"x": float, "y": str, "z": list} assert get_class_annotations(Sub2) == { "x": float, "y": list, "z": list, "a": int, "b": float, } def test_simple_generic(self): class Test(Generic[T]): x: T y: List[T] z: int assert get_class_annotations(Test) == {"x": T, "y": List[T], "z": int} assert get_class_annotations(Test[int]) == {"x": int, "y": List[int], "z": int} assert get_class_annotations(Test[Set[T]]) == { "x": Set[T], "y": List[Set[T]], "z": int, } def test_generic_sub1(self): class Sub(Base): y: int assert get_class_annotations(Sub) == {"x": T, "y": int} def test_generic_sub2(self): class Sub(Base, Generic[T]): y: List[T] assert get_class_annotations(Sub) == {"x": T, "y": List[T]} assert get_class_annotations(Sub[int]) == {"x": T, "y": List[int]} def test_generic_sub3(self): class Sub(Base[int], Generic[T]): y: List[T] assert get_class_annotations(Sub) == {"x": int, "y": List[T]} assert get_class_annotations(Sub[float]) == {"x": int, "y": List[float]} def test_generic_sub4(self): class Sub(Base[T]): y: List[T] assert get_class_annotations(Sub) == {"x": T, "y": List[T]} assert get_class_annotations(Sub[int]) == {"x": int, "y": List[int]} def test_generic_sub5(self): class Sub(Base[T], Generic[T]): y: List[T] assert get_class_annotations(Sub) == {"x": T, "y": List[T]} assert get_class_annotations(Sub[int]) == {"x": int, "y": List[int]} def test_generic_sub6(self): class Sub(Base[S]): y: List[S] assert get_class_annotations(Sub) == {"x": S, "y": List[S]} assert get_class_annotations(Sub[int]) == {"x": int, "y": List[int]} def test_generic_sub7(self): class Sub(Base[List[T]]): y: Set[T] assert get_class_annotations(Sub) == {"x": List[T], "y": Set[T]} assert get_class_annotations(Sub[int]) == {"x": List[int], "y": Set[int]} def test_generic_sub8(self): class Sub(Base[int], Base2[float, str]): pass assert get_class_annotations(Sub) == {"x": int, "a": float, "b": str} def test_generic_sub9(self): class Sub(Base[U], Base2[List[U], U]): y: str assert get_class_annotations(Sub) == {"y": str, "x": U, "a": List[U], "b": U} assert get_class_annotations(Sub[int]) == { "y": str, "x": int, "a": List[int], "b": int, } class Sub2(Sub[int]): x: list assert get_class_annotations(Sub2) == { "x": list, "y": str, "a": List[int], "b": int, } def test_generic_sub10(self): class Sub(Base[U], Base2[List[U], U]): y: str class Sub3(Sub[List[T]]): c: T assert get_class_annotations(Sub3) == { "c": T, "y": str, "x": List[T], "a": List[List[T]], "b": List[T], } assert get_class_annotations(Sub3[int]) == { "c": int, "y": str, "x": List[int], "a": List[List[int]], "b": List[int], } def test_generic_sub11(self): class Sub(Base[int]): y: float class Sub2(Sub, Base[int]): z: str assert get_class_annotations(Sub2) == {"x": int, "y": float, "z": str} def test_generic_invalid_parameters(self): class Invalid: @property def __parameters__(self): pass class Sub(Base[Invalid]): pass assert get_class_annotations(Sub) == {"x": Invalid} @pytest.mark.skipif(PY310, reason="<3.10 only") def test_union_backport_not_installed(self): class Ex: x: int | None = None with package_not_installed("eval_type_backport"): with pytest.raises( TypeError, match=r"or install the `eval_type_backport` package." ): get_class_annotations(Ex) @pytest.mark.skipif(PY310, reason="<3.10 only") def test_union_backport_installed(self): class Ex: x: int | None = None pytest.importorskip("eval_type_backport") assert get_class_annotations(Ex) == {"x": Optional[int]} python-msgspec-0.19.0/tests/test_yaml.py000066400000000000000000000104371473355726200203210ustar00rootroot00000000000000import dataclasses import datetime import enum import sys import uuid from decimal import Decimal from typing import Dict, FrozenSet, List, Set, Tuple import pytest import msgspec try: import yaml # noqa except ImportError: pytestmark = pytest.mark.skip(reason="PyYAML is not installed") UTC = datetime.timezone.utc class ExStruct(msgspec.Struct): x: int y: str @dataclasses.dataclass class ExDataclass: x: int y: str class ExEnum(enum.Enum): one = "one" two = "two" class ExIntEnum(enum.IntEnum): one = 1 two = 2 def test_module_dir(): assert set(dir(msgspec.yaml)) == {"encode", "decode"} def test_pyyaml_not_installed_error(monkeypatch): monkeypatch.setitem(sys.modules, "yaml", None) with pytest.raises(ImportError, match="PyYAML"): msgspec.yaml.encode(1) with pytest.raises(ImportError, match="PyYAML"): msgspec.yaml.decode("1", type=int) @pytest.mark.parametrize( "val", [ None, True, False, 1, 1.5, "fizz", datetime.datetime(2022, 1, 2, 3, 4, 5, 6), datetime.datetime(2022, 1, 2, 3, 4, 5, 6, UTC), datetime.date(2022, 1, 2), [1, 2], {"one": 2}, {1: "two"}, ], ) def test_roundtrip_any(val): msg = msgspec.yaml.encode(val) res = msgspec.yaml.decode(msg) assert res == val @pytest.mark.parametrize( "val, type", [ (None, None), (True, bool), (False, bool), (1, int), (1.5, float), ("fizz", str), (b"fizz", bytes), (b"fizz", bytearray), (datetime.datetime(2022, 1, 2, 3, 4, 5, 6), datetime.datetime), (datetime.datetime(2022, 1, 2, 3, 4, 5, 6, UTC), datetime.datetime), (datetime.date(2022, 1, 2), datetime.date), (datetime.time(12, 34), datetime.time), (uuid.uuid4(), uuid.UUID), (ExEnum.one, ExEnum), (ExIntEnum.one, ExIntEnum), ([1, 2], List[int]), ((1, 2), Tuple[int, ...]), ({1, 2}, Set[int]), (frozenset({1, 2}), FrozenSet[int]), (("one", 2), Tuple[str, int]), ({"one": 2}, Dict[str, int]), ({1: "two"}, Dict[int, str]), (ExStruct(1, "two"), ExStruct), (ExDataclass(1, "two"), ExDataclass), ], ) def test_roundtrip_typed(val, type): msg = msgspec.yaml.encode(val) res = msgspec.yaml.decode(msg, type=type) assert res == val def test_encode_error(): class Oops: pass with pytest.raises(TypeError, match="Encoding objects of type Oops is unsupported"): msgspec.yaml.encode(Oops()) def test_encode_enc_hook(): msg = msgspec.yaml.encode(Decimal(1.5), enc_hook=str) assert msgspec.yaml.decode(msg) == "1.5" @pytest.mark.parametrize("order", [None, "deterministic"]) def test_encode_order(order): msg = {"y": 1, "x": 2, "z": 3} res = msgspec.yaml.encode(msg, order=order) sol = yaml.safe_dump(msg, sort_keys=bool(order)).encode("utf-8") assert res == sol def test_decode_str_or_bytes_like(): assert msgspec.yaml.decode("[1, 2]") == [1, 2] assert msgspec.yaml.decode(b"[1, 2]") == [1, 2] assert msgspec.yaml.decode(bytearray(b"[1, 2]")) == [1, 2] assert msgspec.yaml.decode(memoryview(b"[1, 2]")) == [1, 2] with pytest.raises(TypeError): msgspec.yaml.decode(1) @pytest.mark.parametrize("msg", [b"{{", b"!!binary 123"]) def test_decode_parse_error(msg): with pytest.raises(msgspec.DecodeError): msgspec.yaml.decode(msg) def test_decode_validation_error(): with pytest.raises(msgspec.ValidationError, match="Expected `str`"): msgspec.yaml.decode(b"[1, 2, 3]", type=List[str]) @pytest.mark.parametrize("strict", [True, False]) def test_decode_strict_or_lax(strict): msg = b"a: ['1', '2']" typ = Dict[str, List[int]] if strict: with pytest.raises(msgspec.ValidationError, match="Expected `int`"): msgspec.yaml.decode(msg, type=typ, strict=strict) else: res = msgspec.yaml.decode(msg, type=typ, strict=strict) assert res == {"a": [1, 2]} def test_decode_dec_hook(): def dec_hook(typ, val): if typ is Decimal: return Decimal(val) raise TypeError res = msgspec.yaml.decode("'1.5'", type=Decimal, dec_hook=dec_hook) assert res == Decimal("1.5") python-msgspec-0.19.0/tests/utils.py000066400000000000000000000032711473355726200174560ustar00rootroot00000000000000import sys import inspect import textwrap import types import uuid from contextlib import contextmanager @contextmanager def temp_module(code): """Mutually recursive struct types defined inside functions don't work (and probably never will). To avoid populating a bunch of test structs in the top level of this module, we instead create a temporary module per test to exec whatever is needed for that test""" code = textwrap.dedent(code) name = f"temp_{uuid.uuid4().hex}" mod = types.ModuleType(name) sys.modules[name] = mod try: exec(code, mod.__dict__) yield mod finally: sys.modules.pop(name, None) @contextmanager def max_call_depth(n): cur_depth = len(inspect.stack(0)) orig = sys.getrecursionlimit() try: # Our measure of the current stack depth can be off by a bit. Trying to # set a recursionlimit < the current depth will raise a RecursionError. # We just try again with a slightly higher limit, bailing after an # unreasonable amount of adjustments. for i in range(64): try: sys.setrecursionlimit(cur_depth + i + n) break except RecursionError: pass else: raise ValueError( "Failed to set low recursion limit, something is wrong here" ) yield finally: sys.setrecursionlimit(orig) @contextmanager def package_not_installed(name): try: orig = sys.modules.get(name) sys.modules[name] = None yield finally: if orig is not None: sys.modules[name] = orig else: del sys.modules[name] python-msgspec-0.19.0/versioneer.py000066400000000000000000002111341473355726200173340ustar00rootroot00000000000000# Version: 0.19 """The Versioneer - like a rocketeer, but for versions. The Versioneer ============== * like a rocketeer, but for versions! * https://github.com/python-versioneer/python-versioneer * Brian Warner * License: Public Domain * Compatible with: Python 3.6, 3.7, 3.8, 3.9 and pypy3 * [![Latest Version][pypi-image]][pypi-url] * [![Build Status][travis-image]][travis-url] This is a tool for managing a recorded version number in distutils-based python projects. The goal is to remove the tedious and error-prone "update the embedded version string" step from your release process. Making a new release should be as easy as recording a new tag in your version-control system, and maybe making new tarballs. ## Quick Install * `pip install versioneer` to somewhere in your $PATH * add a `[versioneer]` section to your setup.cfg (see [Install](INSTALL.md)) * run `versioneer install` in your source tree, commit the results * Verify version information with `python setup.py version` ## Version Identifiers Source trees come from a variety of places: * a version-control system checkout (mostly used by developers) * a nightly tarball, produced by build automation * a snapshot tarball, produced by a web-based VCS browser, like github's "tarball from tag" feature * a release tarball, produced by "setup.py sdist", distributed through PyPI Within each source tree, the version identifier (either a string or a number, this tool is format-agnostic) can come from a variety of places: * ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows about recent "tags" and an absolute revision-id * the name of the directory into which the tarball was unpacked * an expanded VCS keyword ($Id$, etc) * a `_version.py` created by some earlier build step For released software, the version identifier is closely related to a VCS tag. Some projects use tag names that include more than just the version string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool needs to strip the tag prefix to extract the version identifier. For unreleased software (between tags), the version identifier should provide enough information to help developers recreate the same tree, while also giving them an idea of roughly how old the tree is (after version 1.2, before version 1.3). Many VCS systems can report a description that captures this, for example `git describe --tags --dirty --always` reports things like "0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the 0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has uncommitted changes). The version identifier is used for multiple purposes: * to allow the module to self-identify its version: `myproject.__version__` * to choose a name and prefix for a 'setup.py sdist' tarball ## Theory of Operation Versioneer works by adding a special `_version.py` file into your source tree, where your `__init__.py` can import it. This `_version.py` knows how to dynamically ask the VCS tool for version information at import time. `_version.py` also contains `$Revision$` markers, and the installation process marks `_version.py` to have this marker rewritten with a tag name during the `git archive` command. As a result, generated tarballs will contain enough information to get the proper version. To allow `setup.py` to compute a version too, a `versioneer.py` is added to the top level of your source tree, next to `setup.py` and the `setup.cfg` that configures it. This overrides several distutils/setuptools commands to compute the version when invoked, and changes `setup.py build` and `setup.py sdist` to replace `_version.py` with a small static file that contains just the generated version data. ## Installation See [INSTALL.md](./INSTALL.md) for detailed installation instructions. ## Version-String Flavors Code which uses Versioneer can learn about its version string at runtime by importing `_version` from your main `__init__.py` file and running the `get_versions()` function. From the "outside" (e.g. in `setup.py`), you can import the top-level `versioneer.py` and run `get_versions()`. Both functions return a dictionary with different flavors of version information: * `['version']`: A condensed version string, rendered using the selected style. This is the most commonly used value for the project's version string. The default "pep440" style yields strings like `0.11`, `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section below for alternative styles. * `['full-revisionid']`: detailed revision identifier. For Git, this is the full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac". * `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the commit date in ISO 8601 format. This will be None if the date is not available. * `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that this is only accurate if run in a VCS checkout, otherwise it is likely to be False or None * `['error']`: if the version string could not be computed, this will be set to a string describing the problem, otherwise it will be None. It may be useful to throw an exception in setup.py if this is set, to avoid e.g. creating tarballs with a version string of "unknown". Some variants are more useful than others. Including `full-revisionid` in a bug report should allow developers to reconstruct the exact code being tested (or indicate the presence of local changes that should be shared with the developers). `version` is suitable for display in an "about" box or a CLI `--version` output: it can be easily compared against release notes and lists of bugs fixed in various releases. The installer adds the following text to your `__init__.py` to place a basic version in `YOURPROJECT.__version__`: from ._version import get_versions __version__ = get_versions()['version'] del get_versions ## Styles The setup.cfg `style=` configuration controls how the VCS information is rendered into a version string. The default style, "pep440", produces a PEP440-compliant string, equal to the un-prefixed tag name for actual releases, and containing an additional "local version" section with more detail for in-between builds. For Git, this is TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags --dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and that this commit is two revisions ("+2") beyond the "0.11" tag. For released software (exactly equal to a known tag), the identifier will only contain the stripped tag, e.g. "0.11". Other styles are available. See [details.md](details.md) in the Versioneer source tree for descriptions. ## Debugging Versioneer tries to avoid fatal errors: if something goes wrong, it will tend to return a version of "0+unknown". To investigate the problem, run `setup.py version`, which will run the version-lookup code in a verbose mode, and will display the full contents of `get_versions()` (including the `error` string, which may help identify what went wrong). ## Known Limitations Some situations are known to cause problems for Versioneer. This details the most significant ones. More can be found on Github [issues page](https://github.com/python-versioneer/python-versioneer/issues). ### Subprojects Versioneer has limited support for source trees in which `setup.py` is not in the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are two common reasons why `setup.py` might not be in the root: * Source trees which contain multiple subprojects, such as [Buildbot](https://github.com/buildbot/buildbot), which contains both "master" and "slave" subprojects, each with their own `setup.py`, `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI distributions (and upload multiple independently-installable tarballs). * Source trees whose main purpose is to contain a C library, but which also provide bindings to Python (and perhaps other languages) in subdirectories. Versioneer will look for `.git` in parent directories, and most operations should get the right version string. However `pip` and `setuptools` have bugs and implementation details which frequently cause `pip install .` from a subproject directory to fail to find a correct version string (so it usually defaults to `0+unknown`). `pip install --editable .` should work correctly. `setup.py install` might work too. Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in some later version. [Bug #38](https://github.com/python-versioneer/python-versioneer/issues/38) is tracking this issue. The discussion in [PR #61](https://github.com/python-versioneer/python-versioneer/pull/61) describes the issue from the Versioneer side in more detail. [pip PR#3176](https://github.com/pypa/pip/pull/3176) and [pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve pip to let Versioneer work correctly. Versioneer-0.16 and earlier only looked for a `.git` directory next to the `setup.cfg`, so subprojects were completely unsupported with those releases. ### Editable installs with setuptools <= 18.5 `setup.py develop` and `pip install --editable .` allow you to install a project into a virtualenv once, then continue editing the source code (and test) without re-installing after every change. "Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a convenient way to specify executable scripts that should be installed along with the python package. These both work as expected when using modern setuptools. When using setuptools-18.5 or earlier, however, certain operations will cause `pkg_resources.DistributionNotFound` errors when running the entrypoint script, which must be resolved by re-installing the package. This happens when the install happens with one version, then the egg_info data is regenerated while a different version is checked out. Many setup.py commands cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into a different virtualenv), so this can be surprising. [Bug #83](https://github.com/python-versioneer/python-versioneer/issues/83) describes this one, but upgrading to a newer version of setuptools should probably resolve it. ## Updating Versioneer To upgrade your project to a new release of Versioneer, do the following: * install the new Versioneer (`pip install -U versioneer` or equivalent) * edit `setup.cfg`, if necessary, to include any new configuration settings indicated by the release notes. See [UPGRADING](./UPGRADING.md) for details. * re-run `versioneer install` in your source tree, to replace `SRC/_version.py` * commit any changed files ## Future Directions This tool is designed to make it easily extended to other version-control systems: all VCS-specific components are in separate directories like src/git/ . The top-level `versioneer.py` script is assembled from these components by running make-versioneer.py . In the future, make-versioneer.py will take a VCS name as an argument, and will construct a version of `versioneer.py` that is specific to the given VCS. It might also take the configuration arguments that are currently provided manually during installation by editing setup.py . Alternatively, it might go the other direction and include code from all supported VCS systems, reducing the number of intermediate scripts. ## Similar projects * [setuptools_scm](https://github.com/pypa/setuptools_scm/) - a non-vendored build-time dependency * [minver](https://github.com/jbweston/miniver) - a lightweight reimplementation of versioneer ## License To make Versioneer easier to embed, all its code is dedicated to the public domain. The `_version.py` that it creates is also in the public domain. Specifically, both are released under the Creative Commons "Public Domain Dedication" license (CC0-1.0), as described in https://creativecommons.org/publicdomain/zero/1.0/ . [pypi-image]: https://img.shields.io/pypi/v/versioneer.svg [pypi-url]: https://pypi.python.org/pypi/versioneer/ [travis-image]: https://img.shields.io/travis/com/python-versioneer/python-versioneer.svg [travis-url]: https://travis-ci.com/github/python-versioneer/python-versioneer """ import configparser import errno import json import os import re import subprocess import sys class VersioneerConfig: """Container for Versioneer configuration parameters.""" def get_root(): """Get the project root directory. We require that all commands are run from the project root, i.e. the directory that contains setup.py, setup.cfg, and versioneer.py . """ root = os.path.realpath(os.path.abspath(os.getcwd())) setup_py = os.path.join(root, "setup.py") versioneer_py = os.path.join(root, "versioneer.py") if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): # allow 'python path/to/setup.py COMMAND' root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0]))) setup_py = os.path.join(root, "setup.py") versioneer_py = os.path.join(root, "versioneer.py") if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): err = ( "Versioneer was unable to run the project root directory. " "Versioneer requires setup.py to be executed from " "its immediate directory (like 'python setup.py COMMAND'), " "or in a way that lets it use sys.argv[0] to find the root " "(like 'python path/to/setup.py COMMAND')." ) raise VersioneerBadRootError(err) try: # Certain runtime workflows (setup.py install/develop in a setuptools # tree) execute all dependencies in a single python process, so # "versioneer" may be imported multiple times, and python's shared # module-import table will cache the first one. So we can't use # os.path.dirname(__file__), as that will find whichever # versioneer.py was first imported, even in later projects. me = os.path.realpath(os.path.abspath(__file__)) me_dir = os.path.normcase(os.path.splitext(me)[0]) vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) if me_dir != vsr_dir: print( "Warning: build in %s is using versioneer.py from %s" % (os.path.dirname(me), versioneer_py) ) except NameError: pass return root def get_config_from_root(root): """Read the project setup.cfg file to determine Versioneer config.""" # This might raise EnvironmentError (if setup.cfg is missing), or # configparser.NoSectionError (if it lacks a [versioneer] section), or # configparser.NoOptionError (if it lacks "VCS="). See the docstring at # the top of versioneer.py for instructions on writing your setup.cfg . setup_cfg = os.path.join(root, "setup.cfg") parser = configparser.ConfigParser() with open(setup_cfg, "r") as f: parser.read_file(f) VCS = parser.get("versioneer", "VCS") # mandatory def get(parser, name): if parser.has_option("versioneer", name): return parser.get("versioneer", name) return None cfg = VersioneerConfig() cfg.VCS = VCS cfg.style = get(parser, "style") or "" cfg.versionfile_source = get(parser, "versionfile_source") cfg.versionfile_build = get(parser, "versionfile_build") cfg.tag_prefix = get(parser, "tag_prefix") if cfg.tag_prefix in ("''", '""'): cfg.tag_prefix = "" cfg.parentdir_prefix = get(parser, "parentdir_prefix") cfg.verbose = get(parser, "verbose") return cfg class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" # these dictionaries contain VCS-specific tools LONG_VERSION_PY = {} HANDLERS = {} def register_vcs_handler(vcs, method): # decorator """Create decorator to mark a method as the handler of a VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: HANDLERS[vcs] = {} HANDLERS[vcs][method] = f return f return decorate def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) p = None for c in commands: try: dispcmd = str([c] + args) # remember shell=False, so use git.cmd on windows, not just git p = subprocess.Popen( [c] + args, cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=(subprocess.PIPE if hide_stderr else None), ) break except EnvironmentError: e = sys.exc_info()[1] if e.errno == errno.ENOENT: continue if verbose: print("unable to run %s" % dispcmd) print(e) return None, None else: if verbose: print("unable to find command, tried %s" % (commands,)) return None, None stdout = p.communicate()[0].strip().decode() if p.returncode != 0: if verbose: print("unable to run %s (error)" % dispcmd) print("stdout was %s" % stdout) return None, p.returncode return stdout, p.returncode LONG_VERSION_PY[ "git" ] = r''' # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build # directories (produced by setup.py build) will contain a much shorter file # that just contains the computed version number. # This file is released into the public domain. Generated by # versioneer-0.19 (https://github.com/python-versioneer/python-versioneer) """Git implementation of _version.py.""" import errno import os import re import subprocess import sys def get_keywords(): """Get the keywords needed to look up the version information.""" # these strings will be replaced by git during git-archive. # setup.py/versioneer.py will grep for the variable names, so they must # each be defined on a line of their own. _version.py will just call # get_keywords(). git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s" git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s" git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s" keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} return keywords class VersioneerConfig: """Container for Versioneer configuration parameters.""" def get_config(): """Create, populate and return the VersioneerConfig() object.""" # these strings are filled in when 'setup.py versioneer' creates # _version.py cfg = VersioneerConfig() cfg.VCS = "git" cfg.style = "%(STYLE)s" cfg.tag_prefix = "%(TAG_PREFIX)s" cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s" cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s" cfg.verbose = False return cfg class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" LONG_VERSION_PY = {} HANDLERS = {} def register_vcs_handler(vcs, method): # decorator """Create decorator to mark a method as the handler of a VCS.""" def decorate(f): """Store f in HANDLERS[vcs][method].""" if vcs not in HANDLERS: HANDLERS[vcs] = {} HANDLERS[vcs][method] = f return f return decorate def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) p = None for c in commands: try: dispcmd = str([c] + args) # remember shell=False, so use git.cmd on windows, not just git p = subprocess.Popen([c] + args, cwd=cwd, env=env, stdout=subprocess.PIPE, stderr=(subprocess.PIPE if hide_stderr else None)) break except EnvironmentError: e = sys.exc_info()[1] if e.errno == errno.ENOENT: continue if verbose: print("unable to run %%s" %% dispcmd) print(e) return None, None else: if verbose: print("unable to find command, tried %%s" %% (commands,)) return None, None stdout = p.communicate()[0].strip().decode() if p.returncode != 0: if verbose: print("unable to run %%s (error)" %% dispcmd) print("stdout was %%s" %% stdout) return None, p.returncode return stdout, p.returncode def versions_from_parentdir(parentdir_prefix, root, verbose): """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both the project name and a version string. We will also support searching up two directory levels for an appropriately named parent directory """ rootdirs = [] for i in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): return {"version": dirname[len(parentdir_prefix):], "full-revisionid": None, "dirty": False, "error": None, "date": None} else: rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: print("Tried directories %%s but none started with prefix %%s" %% (str(rootdirs), parentdir_prefix)) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @register_vcs_handler("git", "get_keywords") def git_get_keywords(versionfile_abs): """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. keywords = {} try: f = open(versionfile_abs, "r") for line in f.readlines(): if line.strip().startswith("git_refnames ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["refnames"] = mo.group(1) if line.strip().startswith("git_full ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["full"] = mo.group(1) if line.strip().startswith("git_date ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["date"] = mo.group(1) f.close() except EnvironmentError: pass return keywords @register_vcs_handler("git", "keywords") def git_versions_from_keywords(keywords, tag_prefix, verbose): """Get version information from git keywords.""" if not keywords: raise NotThisMethod("no keywords at all, weird") date = keywords.get("date") if date is not None: # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because # it's been around since git-1.5.3, and it's too difficult to # discover which version we're using, or to work around using an # older one. date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) refnames = keywords["refnames"].strip() if refnames.startswith("$Format"): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") refs = set([r.strip() for r in refnames.strip("()").split(",")]) # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %%d # expansion behaves like git log --decorate=short and strips out the # refs/heads/ and refs/tags/ prefixes that would let us distinguish # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". tags = set([r for r in refs if re.search(r'\d', r)]) if verbose: print("discarding '%%s', no digits" %% ",".join(refs - tags)) if verbose: print("likely tags: %%s" %% ",".join(sorted(tags))) for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): r = ref[len(tag_prefix):] if verbose: print("picking %%s" %% r) return {"version": r, "full-revisionid": keywords["full"].strip(), "dirty": False, "error": None, "date": date} # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") return {"version": "0+unknown", "full-revisionid": keywords["full"].strip(), "dirty": False, "error": "no suitable tags", "date": None} @register_vcs_handler("git", "pieces_from_vcs") def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* expanded, and _version.py hasn't already been rewritten with a short version string, meaning we're inside a checked out source tree. """ GITS = ["git"] if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) if rc != 0: if verbose: print("Directory %%s not under git control" %% root) raise NotThisMethod("'git rev-parse --git-dir' returned error") # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty", "--always", "--long", "--match", "%%s*" %% tag_prefix], cwd=root) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() pieces = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out # look for -dirty suffix dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: git_describe = git_describe[:git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) if not mo: # unparsable. Maybe git-describe is misbehaving? pieces["error"] = ("unable to parse git-describe output: '%%s'" %% describe_out) return pieces # tag full_tag = mo.group(1) if not full_tag.startswith(tag_prefix): if verbose: fmt = "tag '%%s' doesn't start with prefix '%%s'" print(fmt %% (full_tag, tag_prefix)) pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'" %% (full_tag, tag_prefix)) return pieces pieces["closest-tag"] = full_tag[len(tag_prefix):] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) # commit: short hex revision ID pieces["short"] = mo.group(3) else: # HEX: no tags pieces["closest-tag"] = None count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], cwd=root) pieces["distance"] = int(count_out) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() date = run_command(GITS, ["show", "-s", "--format=%%ci", "HEAD"], cwd=root)[0].strip() # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces def plus_or_dot(pieces): """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" def render_pep440(pieces): """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty Exceptions: 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += plus_or_dot(pieces) rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_pre(pieces): """TAG[.post0.devDISTANCE] -- No -dirty. Exceptions: 1: no tags. 0.post0.devDISTANCE """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += ".post0.dev%%d" %% pieces["distance"] else: # exception #1 rendered = "0.post0.dev%%d" %% pieces["distance"] return rendered def render_pep440_post(pieces): """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards (a dirty tree will appear "older" than the corresponding clean one), but you shouldn't be releasing software with -dirty anyways. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%%s" %% pieces["short"] else: # exception #1 rendered = "0.post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += "+g%%s" %% pieces["short"] return rendered def render_pep440_old(pieces): """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" else: # exception #1 rendered = "0.post%%d" %% pieces["distance"] if pieces["dirty"]: rendered += ".dev0" return rendered def render_git_describe(pieces): """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render_git_describe_long(pieces): """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. The distance/hash is unconditional. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: return {"version": "unknown", "full-revisionid": pieces.get("long"), "dirty": None, "error": pieces["error"], "date": None} if not style or style == "default": style = "pep440" # the default if style == "pep440": rendered = render_pep440(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": rendered = render_git_describe(pieces) elif style == "git-describe-long": rendered = render_git_describe_long(pieces) else: raise ValueError("unknown style '%%s'" %% style) return {"version": rendered, "full-revisionid": pieces["long"], "dirty": pieces["dirty"], "error": None, "date": pieces.get("date")} def get_versions(): """Get version information or return default if unable to do so.""" # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have # __file__, we can work backwards from there to the root. Some # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which # case we can only use expanded keywords. cfg = get_config() verbose = cfg.verbose try: return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, verbose) except NotThisMethod: pass try: root = os.path.realpath(__file__) # versionfile_source is the relative path from the top of the source # tree (where the .git directory might live) to this file. Invert # this to find the root from __file__. for i in cfg.versionfile_source.split('/'): root = os.path.dirname(root) except NameError: return {"version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to find root of source tree", "date": None} try: pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) return render(pieces, cfg.style) except NotThisMethod: pass try: if cfg.parentdir_prefix: return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) except NotThisMethod: pass return {"version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to compute version", "date": None} ''' @register_vcs_handler("git", "get_keywords") def git_get_keywords(versionfile_abs): """Extract version information from the given file.""" # the code embedded in _version.py can just fetch the value of these # keywords. When used from setup.py, we don't want to import _version.py, # so we do it with a regexp instead. This function is not used from # _version.py. keywords = {} try: f = open(versionfile_abs, "r") for line in f.readlines(): if line.strip().startswith("git_refnames ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["refnames"] = mo.group(1) if line.strip().startswith("git_full ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["full"] = mo.group(1) if line.strip().startswith("git_date ="): mo = re.search(r'=\s*"(.*)"', line) if mo: keywords["date"] = mo.group(1) f.close() except EnvironmentError: pass return keywords @register_vcs_handler("git", "keywords") def git_versions_from_keywords(keywords, tag_prefix, verbose): """Get version information from git keywords.""" if not keywords: raise NotThisMethod("no keywords at all, weird") date = keywords.get("date") if date is not None: # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 # -like" string, which we must then edit to make compliant), because # it's been around since git-1.5.3, and it's too difficult to # discover which version we're using, or to work around using an # older one. date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) refnames = keywords["refnames"].strip() if refnames.startswith("$Format"): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") refs = set([r.strip() for r in refnames.strip("()").split(",")]) # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " tags = set([r[len(TAG) :] for r in refs if r.startswith(TAG)]) if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d # expansion behaves like git log --decorate=short and strips out the # refs/heads/ and refs/tags/ prefixes that would let us distinguish # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". tags = set([r for r in refs if re.search(r"\d", r)]) if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: print("likely tags: %s" % ",".join(sorted(tags))) for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): r = ref[len(tag_prefix) :] if verbose: print("picking %s" % r) return { "version": r, "full-revisionid": keywords["full"].strip(), "dirty": False, "error": None, "date": date, } # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") return { "version": "0+unknown", "full-revisionid": keywords["full"].strip(), "dirty": False, "error": "no suitable tags", "date": None, } @register_vcs_handler("git", "pieces_from_vcs") def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): """Get version from 'git describe' in the root of the source tree. This only gets called if the git-archive 'subst' keywords were *not* expanded, and _version.py hasn't already been rewritten with a short version string, meaning we're inside a checked out source tree. """ GITS = ["git"] if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) if rc != 0: if verbose: print("Directory %s not under git control" % root) raise NotThisMethod("'git rev-parse --git-dir' returned error") # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) describe_out, rc = run_command( GITS, [ "describe", "--tags", "--dirty", "--always", "--long", "--match", "%s*" % tag_prefix, ], cwd=root, ) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") describe_out = describe_out.strip() full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) if full_out is None: raise NotThisMethod("'git rev-parse' failed") full_out = full_out.strip() pieces = {} pieces["long"] = full_out pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] # TAG might have hyphens. git_describe = describe_out # look for -dirty suffix dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: git_describe = git_describe[: git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) if not mo: # unparsable. Maybe git-describe is misbehaving? pieces["error"] = "unable to parse git-describe output: '%s'" % describe_out return pieces # tag full_tag = mo.group(1) if not full_tag.startswith(tag_prefix): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( full_tag, tag_prefix, ) return pieces pieces["closest-tag"] = full_tag[len(tag_prefix) :] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) # commit: short hex revision ID pieces["short"] = mo.group(3) else: # HEX: no tags pieces["closest-tag"] = None count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], cwd=root) pieces["distance"] = int(count_out) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[ 0 ].strip() # Use only the last line. Previous lines may contain GPG signature # information. date = date.splitlines()[-1] pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) return pieces def do_vcs_install(manifest_in, versionfile_source, ipy): """Git-specific installation logic for Versioneer. For Git, this means creating/changing .gitattributes to mark _version.py for export-subst keyword substitution. """ GITS = ["git"] if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] files = [manifest_in, versionfile_source] if ipy: files.append(ipy) try: me = __file__ if me.endswith(".pyc") or me.endswith(".pyo"): me = os.path.splitext(me)[0] + ".py" versioneer_file = os.path.relpath(me) except NameError: versioneer_file = "versioneer.py" files.append(versioneer_file) present = False try: f = open(".gitattributes", "r") for line in f.readlines(): if line.strip().startswith(versionfile_source): if "export-subst" in line.strip().split()[1:]: present = True f.close() except EnvironmentError: pass if not present: f = open(".gitattributes", "a+") f.write("%s export-subst\n" % versionfile_source) f.close() files.append(".gitattributes") run_command(GITS, ["add", "--"] + files) def versions_from_parentdir(parentdir_prefix, root, verbose): """Try to determine the version from the parent directory name. Source tarballs conventionally unpack into a directory that includes both the project name and a version string. We will also support searching up two directory levels for an appropriately named parent directory """ rootdirs = [] for i in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): return { "version": dirname[len(parentdir_prefix) :], "full-revisionid": None, "dirty": False, "error": None, "date": None, } else: rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: print( "Tried directories %s but none started with prefix %s" % (str(rootdirs), parentdir_prefix) ) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") SHORT_VERSION_PY = """ # This file was generated by 'versioneer.py' (0.19) from # revision-control system data, or from the parent directory name of an # unpacked source archive. Distribution tarballs contain a pre-generated copy # of this file. import json version_json = ''' %s ''' # END VERSION_JSON def get_versions(): return json.loads(version_json) """ def versions_from_file(filename): """Try to determine the version from _version.py if present.""" try: with open(filename) as f: contents = f.read() except EnvironmentError: raise NotThisMethod("unable to read _version.py") mo = re.search( r"version_json = '''\n(.*)''' # END VERSION_JSON", contents, re.M | re.S ) if not mo: mo = re.search( r"version_json = '''\r\n(.*)''' # END VERSION_JSON", contents, re.M | re.S ) if not mo: raise NotThisMethod("no version_json in _version.py") return json.loads(mo.group(1)) def write_to_version_file(filename, versions): """Write the given version number to the given _version.py file.""" os.unlink(filename) contents = json.dumps(versions, sort_keys=True, indent=1, separators=(",", ": ")) with open(filename, "w") as f: f.write(SHORT_VERSION_PY % contents) print("set %s to '%s'" % (filename, versions["version"])) def plus_or_dot(pieces): """Return a + if we don't already have one, else return a .""" if "+" in pieces.get("closest-tag", ""): return "." return "+" def render_pep440(pieces): """Build up version string, with post-release "local version identifier". Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty Exceptions: 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += plus_or_dot(pieces) rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" else: # exception #1 rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered def render_pep440_pre(pieces): """TAG[.post0.devDISTANCE] -- No -dirty. Exceptions: 1: no tags. 0.post0.devDISTANCE """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += ".post0.dev%d" % pieces["distance"] else: # exception #1 rendered = "0.post0.dev%d" % pieces["distance"] return rendered def render_pep440_post(pieces): """TAG[.postDISTANCE[.dev0]+gHEX] . The ".dev0" means dirty. Note that .dev0 sorts backwards (a dirty tree will appear "older" than the corresponding clean one), but you shouldn't be releasing software with -dirty anyways. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += plus_or_dot(pieces) rendered += "g%s" % pieces["short"] else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" rendered += "+g%s" % pieces["short"] return rendered def render_pep440_old(pieces): """TAG[.postDISTANCE[.dev0]] . The ".dev0" means dirty. Exceptions: 1: no tags. 0.postDISTANCE[.dev0] """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"] or pieces["dirty"]: rendered += ".post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" else: # exception #1 rendered = "0.post%d" % pieces["distance"] if pieces["dirty"]: rendered += ".dev0" return rendered def render_git_describe(pieces): """TAG[-DISTANCE-gHEX][-dirty]. Like 'git describe --tags --dirty --always'. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] if pieces["distance"]: rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render_git_describe_long(pieces): """TAG-DISTANCE-gHEX[-dirty]. Like 'git describe --tags --dirty --always -long'. The distance/hash is unconditional. Exceptions: 1: no tags. HEX[-dirty] (note: no 'g' prefix) """ if pieces["closest-tag"]: rendered = pieces["closest-tag"] rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) else: # exception #1 rendered = pieces["short"] if pieces["dirty"]: rendered += "-dirty" return rendered def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: return { "version": "unknown", "full-revisionid": pieces.get("long"), "dirty": None, "error": pieces["error"], "date": None, } if not style or style == "default": style = "pep440" # the default if style == "pep440": rendered = render_pep440(pieces) elif style == "pep440-pre": rendered = render_pep440_pre(pieces) elif style == "pep440-post": rendered = render_pep440_post(pieces) elif style == "pep440-old": rendered = render_pep440_old(pieces) elif style == "git-describe": rendered = render_git_describe(pieces) elif style == "git-describe-long": rendered = render_git_describe_long(pieces) else: raise ValueError("unknown style '%s'" % style) return { "version": rendered, "full-revisionid": pieces["long"], "dirty": pieces["dirty"], "error": None, "date": pieces.get("date"), } class VersioneerBadRootError(Exception): """The project root directory is unknown or missing key files.""" def get_versions(verbose=False): """Get the project version from whatever source is available. Returns dict with two keys: 'version' and 'full'. """ if "versioneer" in sys.modules: # see the discussion in cmdclass.py:get_cmdclass() del sys.modules["versioneer"] root = get_root() cfg = get_config_from_root(root) assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg" handlers = HANDLERS.get(cfg.VCS) assert handlers, "unrecognized VCS '%s'" % cfg.VCS verbose = verbose or cfg.verbose assert ( cfg.versionfile_source is not None ), "please set versioneer.versionfile_source" assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" versionfile_abs = os.path.join(root, cfg.versionfile_source) # extract version from first of: _version.py, VCS command (e.g. 'git # describe'), parentdir. This is meant to work for developers using a # source checkout, for users of a tarball created by 'setup.py sdist', # and for users of a tarball/zipball created by 'git archive' or github's # download-from-tag feature or the equivalent in other VCSes. get_keywords_f = handlers.get("get_keywords") from_keywords_f = handlers.get("keywords") if get_keywords_f and from_keywords_f: try: keywords = get_keywords_f(versionfile_abs) ver = from_keywords_f(keywords, cfg.tag_prefix, verbose) if verbose: print("got version from expanded keyword %s" % ver) return ver except NotThisMethod: pass try: ver = versions_from_file(versionfile_abs) if verbose: print("got version from file %s %s" % (versionfile_abs, ver)) return ver except NotThisMethod: pass from_vcs_f = handlers.get("pieces_from_vcs") if from_vcs_f: try: pieces = from_vcs_f(cfg.tag_prefix, root, verbose) ver = render(pieces, cfg.style) if verbose: print("got version from VCS %s" % ver) return ver except NotThisMethod: pass try: if cfg.parentdir_prefix: ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose) if verbose: print("got version from parentdir %s" % ver) return ver except NotThisMethod: pass if verbose: print("unable to compute version") return { "version": "0+unknown", "full-revisionid": None, "dirty": None, "error": "unable to compute version", "date": None, } def get_version(): """Get the short version string for this project.""" return get_versions()["version"] def get_cmdclass(cmdclass=None): """Get the custom setuptools/distutils subclasses used by Versioneer. If the package uses a different cmdclass (e.g. one from numpy), it should be provide as an argument. """ if "versioneer" in sys.modules: del sys.modules["versioneer"] # this fixes the "python setup.py develop" case (also 'install' and # 'easy_install .'), in which subdependencies of the main project are # built (using setup.py bdist_egg) in the same python process. Assume # a main project A and a dependency B, which use different versions # of Versioneer. A's setup.py imports A's Versioneer, leaving it in # sys.modules by the time B's setup.py is executed, causing B to run # with the wrong versioneer. Setuptools wraps the sub-dep builds in a # sandbox that restores sys.modules to it's pre-build state, so the # parent is protected against the child's "import versioneer". By # removing ourselves from sys.modules here, before the child build # happens, we protect the child from the parent's versioneer too. # Also see https://github.com/python-versioneer/python-versioneer/issues/52 cmds = {} if cmdclass is None else cmdclass.copy() # we add "version" to both distutils and setuptools from distutils.core import Command class cmd_version(Command): description = "report generated version string" user_options = [] boolean_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): vers = get_versions(verbose=True) print("Version: %s" % vers["version"]) print(" full-revisionid: %s" % vers.get("full-revisionid")) print(" dirty: %s" % vers.get("dirty")) print(" date: %s" % vers.get("date")) if vers["error"]: print(" error: %s" % vers["error"]) cmds["version"] = cmd_version # we override "build_py" in both distutils and setuptools # # most invocation pathways end up running build_py: # distutils/build -> build_py # distutils/install -> distutils/build ->.. # setuptools/bdist_wheel -> distutils/install ->.. # setuptools/bdist_egg -> distutils/install_lib -> build_py # setuptools/install -> bdist_egg ->.. # setuptools/develop -> ? # pip install: # copies source tree to a tempdir before running egg_info/etc # if .git isn't copied too, 'git describe' will fail # then does setup.py bdist_wheel, or sometimes setup.py install # setup.py egg_info -> ? # we override different "build_py" commands for both environments if "build_py" in cmds: _build_py = cmds["build_py"] elif "setuptools" in sys.modules: from setuptools.command.build_py import build_py as _build_py else: from distutils.command.build_py import build_py as _build_py class cmd_build_py(_build_py): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() _build_py.run(self) # now locate _version.py in the new build/ directory and replace # it with an updated value if cfg.versionfile_build: target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) cmds["build_py"] = cmd_build_py if "setuptools" in sys.modules: from setuptools.command.build_ext import build_ext as _build_ext else: from distutils.command.build_ext import build_ext as _build_ext class cmd_build_ext(_build_ext): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() _build_ext.run(self) if self.inplace: # build_ext --inplace will only build extensions in # build/lib<..> dir with no _version.py to write to. # As in place builds will already have a _version.py # in the module dir, we do not need to write one. return # now locate _version.py in the new build/ directory and replace # it with an updated value target_versionfile = os.path.join(self.build_lib, cfg.versionfile_source) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) cmds["build_ext"] = cmd_build_ext if "cx_Freeze" in sys.modules: # cx_freeze enabled? from cx_Freeze.dist import build_exe as _build_exe # nczeczulin reports that py2exe won't like the pep440-style string # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. # setup(console=[{ # "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION # "product_version": versioneer.get_version(), # ... class cmd_build_exe(_build_exe): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() target_versionfile = cfg.versionfile_source print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) _build_exe.run(self) os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] f.write( LONG % { "DOLLAR": "$", "STYLE": cfg.style, "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, } ) cmds["build_exe"] = cmd_build_exe del cmds["build_py"] if "py2exe" in sys.modules: # py2exe enabled? from py2exe.distutils_buildexe import py2exe as _py2exe class cmd_py2exe(_py2exe): def run(self): root = get_root() cfg = get_config_from_root(root) versions = get_versions() target_versionfile = cfg.versionfile_source print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) _py2exe.run(self) os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] f.write( LONG % { "DOLLAR": "$", "STYLE": cfg.style, "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, } ) cmds["py2exe"] = cmd_py2exe # we override different "sdist" commands for both environments if "sdist" in cmds: _sdist = cmds["sdist"] elif "setuptools" in sys.modules: from setuptools.command.sdist import sdist as _sdist else: from distutils.command.sdist import sdist as _sdist class cmd_sdist(_sdist): def run(self): versions = get_versions() self._versioneer_generated_versions = versions # unless we update this, the command will keep using the old # version self.distribution.metadata.version = versions["version"] return _sdist.run(self) def make_release_tree(self, base_dir, files): root = get_root() cfg = get_config_from_root(root) _sdist.make_release_tree(self, base_dir, files) # now locate _version.py in the new base_dir directory # (remembering that it may be a hardlink) and replace it with an # updated value target_versionfile = os.path.join(base_dir, cfg.versionfile_source) print("UPDATING %s" % target_versionfile) write_to_version_file( target_versionfile, self._versioneer_generated_versions ) cmds["sdist"] = cmd_sdist return cmds CONFIG_ERROR = """ setup.cfg is missing the necessary Versioneer configuration. You need a section like: [versioneer] VCS = git style = pep440 versionfile_source = src/myproject/_version.py versionfile_build = myproject/_version.py tag_prefix = parentdir_prefix = myproject- You will also need to edit your setup.py to use the results: import versioneer setup(version=versioneer.get_version(), cmdclass=versioneer.get_cmdclass(), ...) Please read the docstring in ./versioneer.py for configuration instructions, edit setup.cfg, and re-run the installer or 'python versioneer.py setup'. """ SAMPLE_CONFIG = """ # See the docstring in versioneer.py for instructions. Note that you must # re-run 'versioneer.py setup' after changing this section, and commit the # resulting files. [versioneer] #VCS = git #style = pep440 #versionfile_source = #versionfile_build = #tag_prefix = #parentdir_prefix = """ INIT_PY_SNIPPET = """ from ._version import get_versions __version__ = get_versions()['version'] del get_versions """ def do_setup(): """Do main VCS-independent setup function for installing Versioneer.""" root = get_root() try: cfg = get_config_from_root(root) except ( EnvironmentError, configparser.NoSectionError, configparser.NoOptionError, ) as e: if isinstance(e, (EnvironmentError, configparser.NoSectionError)): print("Adding sample versioneer config to setup.cfg", file=sys.stderr) with open(os.path.join(root, "setup.cfg"), "a") as f: f.write(SAMPLE_CONFIG) print(CONFIG_ERROR, file=sys.stderr) return 1 print(" creating %s" % cfg.versionfile_source) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] f.write( LONG % { "DOLLAR": "$", "STYLE": cfg.style, "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, } ) ipy = os.path.join(os.path.dirname(cfg.versionfile_source), "__init__.py") if os.path.exists(ipy): try: with open(ipy, "r") as f: old = f.read() except EnvironmentError: old = "" if INIT_PY_SNIPPET not in old: print(" appending to %s" % ipy) with open(ipy, "a") as f: f.write(INIT_PY_SNIPPET) else: print(" %s unmodified" % ipy) else: print(" %s doesn't exist, ok" % ipy) ipy = None # Make sure both the top-level "versioneer.py" and versionfile_source # (PKG/_version.py, used by runtime code) are in MANIFEST.in, so # they'll be copied into source distributions. Pip won't be able to # install the package without this. manifest_in = os.path.join(root, "MANIFEST.in") simple_includes = set() try: with open(manifest_in, "r") as f: for line in f: if line.startswith("include "): for include in line.split()[1:]: simple_includes.add(include) except EnvironmentError: pass # That doesn't cover everything MANIFEST.in can do # (http://docs.python.org/2/distutils/sourcedist.html#commands), so # it might give some false negatives. Appending redundant 'include' # lines is safe, though. if "versioneer.py" not in simple_includes: print(" appending 'versioneer.py' to MANIFEST.in") with open(manifest_in, "a") as f: f.write("include versioneer.py\n") else: print(" 'versioneer.py' already in MANIFEST.in") if cfg.versionfile_source not in simple_includes: print( " appending versionfile_source ('%s') to MANIFEST.in" % cfg.versionfile_source ) with open(manifest_in, "a") as f: f.write("include %s\n" % cfg.versionfile_source) else: print(" versionfile_source already in MANIFEST.in") # Make VCS-specific changes. For git, this means creating/changing # .gitattributes to mark _version.py for export-subst keyword # substitution. do_vcs_install(manifest_in, cfg.versionfile_source, ipy) return 0 def scan_setup_py(): """Validate the contents of setup.py against Versioneer's expectations.""" found = set() setters = False errors = 0 with open("setup.py", "r") as f: for line in f.readlines(): if "import versioneer" in line: found.add("import") if "versioneer.get_cmdclass()" in line: found.add("cmdclass") if "versioneer.get_version()" in line: found.add("get_version") if "versioneer.VCS" in line: setters = True if "versioneer.versionfile_source" in line: setters = True if len(found) != 3: print("") print("Your setup.py appears to be missing some important items") print("(but I might be wrong). Please make sure it has something") print("roughly like the following:") print("") print(" import versioneer") print(" setup( version=versioneer.get_version(),") print(" cmdclass=versioneer.get_cmdclass(), ...)") print("") errors += 1 if setters: print("You should remove lines like 'versioneer.VCS = ' and") print("'versioneer.versionfile_source = ' . This configuration") print("now lives in setup.cfg, and should be removed from setup.py") print("") errors += 1 return errors if __name__ == "__main__": cmd = sys.argv[1] if cmd == "setup": errors = do_setup() errors += scan_setup_py() if errors: sys.exit(1)